mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-01 21:13:09 +00:00
add system images to os build process (#620)
* update compat build and add to os build process * copy to explicit file * fix paths and loading input * temp save docker images output * add docker config file to suppress warning * notes and first attempt of load image script * pr fixes * run as root, fix executable path * wip fixes * fix pool name and stop docker before umount * start docker again * reset docker fs * remove mkdir * load system images during embassy-init * add utils to make build * fix utils source * create system-images dir as root * cleanup * make loading docker images datadir agnostic * address PR feedback * rework load images * create shutdown channel on failed embassy-init run * pr feedback * fix import
This commit is contained in:
@@ -1,23 +1,11 @@
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::ffi::OsStr;
|
||||
use std::io::SeekFrom;
|
||||
use std::path::Path;
|
||||
use std::process::Stdio;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::sync::Arc;
|
||||
|
||||
use color_eyre::eyre::{self, eyre};
|
||||
use emver::VersionRange;
|
||||
use futures::TryStreamExt;
|
||||
use http::StatusCode;
|
||||
use patch_db::{DbHandle, LockType};
|
||||
use reqwest::Response;
|
||||
use rpc_toolkit::command;
|
||||
use tokio::fs::{File, OpenOptions};
|
||||
use tokio::io::{AsyncRead, AsyncSeek, AsyncSeekExt};
|
||||
use tokio::process::Command;
|
||||
use tokio_stream::wrappers::ReadDirStream;
|
||||
use tracing::instrument;
|
||||
|
||||
use self::cleanup::cleanup_failed;
|
||||
use crate::context::RpcContext;
|
||||
use crate::db::model::{
|
||||
@@ -38,6 +26,19 @@ use crate::util::io::copy_and_shutdown;
|
||||
use crate::util::{display_none, display_serializable, AsyncFileExt, Version};
|
||||
use crate::volume::asset_dir;
|
||||
use crate::{Error, ResultExt};
|
||||
use color_eyre::eyre::{self, eyre};
|
||||
use emver::VersionRange;
|
||||
use futures::future::BoxFuture;
|
||||
use futures::{FutureExt, StreamExt, TryStreamExt};
|
||||
use http::StatusCode;
|
||||
use patch_db::{DbHandle, LockType};
|
||||
use reqwest::Response;
|
||||
use rpc_toolkit::command;
|
||||
use tokio::fs::{DirEntry, File, OpenOptions};
|
||||
use tokio::io::{AsyncRead, AsyncSeek, AsyncSeekExt};
|
||||
use tokio::process::Command;
|
||||
use tokio_stream::wrappers::ReadDirStream;
|
||||
use tracing::instrument;
|
||||
|
||||
pub mod cleanup;
|
||||
pub mod progress;
|
||||
@@ -766,58 +767,62 @@ async fn handle_recovered_package(
|
||||
}
|
||||
|
||||
#[instrument(skip(datadir))]
|
||||
pub async fn load_images<P: AsRef<Path>>(datadir: P) -> Result<(), Error> {
|
||||
let docker_dir = datadir.as_ref().join(PKG_DOCKER_DIR);
|
||||
if tokio::fs::metadata(&docker_dir).await.is_ok() {
|
||||
ReadDirStream::new(tokio::fs::read_dir(&docker_dir).await?)
|
||||
.map_err(|e| {
|
||||
Error::new(
|
||||
eyre::Report::from(e).wrap_err(format!("{:?}", &docker_dir)),
|
||||
crate::ErrorKind::Filesystem,
|
||||
)
|
||||
})
|
||||
.try_for_each_concurrent(None, |pkg_id| async move {
|
||||
ReadDirStream::new(tokio::fs::read_dir(pkg_id.path()).await?)
|
||||
.map_err(|e| {
|
||||
Error::new(
|
||||
eyre::Report::from(e).wrap_err(pkg_id.path().display().to_string()),
|
||||
crate::ErrorKind::Filesystem,
|
||||
)
|
||||
})
|
||||
.try_for_each_concurrent(None, |version| async move {
|
||||
let mut load = Command::new("docker")
|
||||
.arg("load")
|
||||
.stdin(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()?;
|
||||
let load_in = load.stdin.take().ok_or_else(|| {
|
||||
Error::new(
|
||||
eyre!("Could not write to stdin of docker load"),
|
||||
crate::ErrorKind::Docker,
|
||||
)
|
||||
})?;
|
||||
let mut docker_rdr = File::open(version.path().join("image.tar")).await?;
|
||||
copy_and_shutdown(&mut docker_rdr, load_in).await?;
|
||||
let res = load.wait_with_output().await?;
|
||||
if !res.status.success() {
|
||||
Err(Error::new(
|
||||
eyre!(
|
||||
"{}",
|
||||
String::from_utf8(res.stderr).unwrap_or_else(|e| format!(
|
||||
"Could not parse stderr: {}",
|
||||
e
|
||||
))
|
||||
),
|
||||
crate::ErrorKind::Docker,
|
||||
))
|
||||
pub fn load_images<'a, P: AsRef<Path> + 'a + Send + Sync>(
|
||||
datadir: P,
|
||||
) -> BoxFuture<'a, Result<(), Error>> {
|
||||
async move {
|
||||
let docker_dir = datadir.as_ref();
|
||||
if tokio::fs::metadata(&docker_dir).await.is_ok() {
|
||||
ReadDirStream::new(tokio::fs::read_dir(&docker_dir).await?)
|
||||
.map(|r| {
|
||||
r.with_ctx(|_| (crate::ErrorKind::Filesystem, format!("{:?}", &docker_dir)))
|
||||
})
|
||||
.try_for_each(|entry| async move {
|
||||
let m = entry.metadata().await?;
|
||||
if m.is_file() {
|
||||
if entry.path().extension().and_then(|ext| ext.to_str()) == Some("tar") {
|
||||
let mut load = Command::new("docker")
|
||||
.arg("load")
|
||||
.stdin(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()?;
|
||||
let load_in = load.stdin.take().ok_or_else(|| {
|
||||
Error::new(
|
||||
eyre!("Could not write to stdin of docker load"),
|
||||
crate::ErrorKind::Docker,
|
||||
)
|
||||
})?;
|
||||
let mut docker_rdr = File::open(&entry.path()).await?;
|
||||
copy_and_shutdown(&mut docker_rdr, load_in).await?;
|
||||
let res = load.wait_with_output().await?;
|
||||
if !res.status.success() {
|
||||
Err(Error::new(
|
||||
eyre!(
|
||||
"{}",
|
||||
String::from_utf8(res.stderr).unwrap_or_else(|e| format!(
|
||||
"Could not parse stderr: {}",
|
||||
e
|
||||
))
|
||||
),
|
||||
crate::ErrorKind::Docker,
|
||||
))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
})
|
||||
.await
|
||||
})
|
||||
.await
|
||||
} else {
|
||||
Ok(())
|
||||
} else if m.is_dir() {
|
||||
load_images(entry.path()).await?;
|
||||
Ok(())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
})
|
||||
.await
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user