mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-02 21:00:55 +00:00
hypha: convert to using anyhow for error handling
This commit is contained in:
parent
a1081ea79c
commit
eec213c712
@ -13,6 +13,7 @@ resolver = "2"
|
|||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
|
anyhow = "1.0"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
log = "0.4.20"
|
log = "0.4.20"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
|
@ -5,6 +5,7 @@ edition = "2021"
|
|||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
anyhow = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
env_logger = { workspace = true }
|
env_logger = { workspace = true }
|
||||||
zstd = { workspace = true }
|
zstd = { workspace = true }
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
use anyhow::Result;
|
||||||
use hypha::container::init::ContainerInit;
|
use hypha::container::init::ContainerInit;
|
||||||
use hypha::error::Result;
|
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
use anyhow::{anyhow, Result};
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use hypha::ctl::Controller;
|
use hypha::ctl::Controller;
|
||||||
use hypha::error::{HyphaError, Result};
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
@ -48,8 +48,7 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
let args = ControllerArgs::parse();
|
let args = ControllerArgs::parse();
|
||||||
let store_path = if args.store == "auto" {
|
let store_path = if args.store == "auto" {
|
||||||
default_store_path()
|
default_store_path().ok_or_else(|| anyhow!("unable to determine default store path"))
|
||||||
.ok_or_else(|| HyphaError::new("unable to determine default store path"))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(PathBuf::from(args.store))
|
Ok(PathBuf::from(args.store))
|
||||||
}?;
|
}?;
|
||||||
@ -57,7 +56,7 @@ fn main() -> Result<()> {
|
|||||||
let store_path = store_path
|
let store_path = store_path
|
||||||
.to_str()
|
.to_str()
|
||||||
.map(|x| x.to_string())
|
.map(|x| x.to_string())
|
||||||
.ok_or_else(|| HyphaError::new("unable to convert store path to string"))?;
|
.ok_or_else(|| anyhow!("unable to convert store path to string"))?;
|
||||||
|
|
||||||
let mut controller = Controller::new(store_path.clone())?;
|
let mut controller = Controller::new(store_path.clone())?;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::error::{HyphaError, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use loopdev::{LoopControl, LoopDevice};
|
use loopdev::{LoopControl, LoopDevice};
|
||||||
use xenclient::BlockDeviceRef;
|
use xenclient::BlockDeviceRef;
|
||||||
|
|
||||||
@ -16,11 +16,9 @@ impl AutoLoop {
|
|||||||
device.with().read_only(true).attach(file)?;
|
device.with().read_only(true).attach(file)?;
|
||||||
let path = device
|
let path = device
|
||||||
.path()
|
.path()
|
||||||
.ok_or(HyphaError::new("unable to get loop device path"))?
|
.ok_or(anyhow!("unable to get loop device path"))?
|
||||||
.to_str()
|
.to_str()
|
||||||
.ok_or(HyphaError::new(
|
.ok_or(anyhow!("unable to convert loop device path to string",))?
|
||||||
"unable to convert loop device path to string",
|
|
||||||
))?
|
|
||||||
.to_string();
|
.to_string();
|
||||||
let major = device.major()?;
|
let major = device.major()?;
|
||||||
let minor = device.minor()?;
|
let minor = device.minor()?;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use crate::error::Result;
|
|
||||||
use crate::hypha_err;
|
|
||||||
use crate::shared::LaunchInfo;
|
use crate::shared::LaunchInfo;
|
||||||
|
use anyhow::{anyhow, Result};
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use nix::libc::dup2;
|
use nix::libc::dup2;
|
||||||
use nix::unistd::execve;
|
use nix::unistd::execve;
|
||||||
@ -69,7 +68,9 @@ impl ContainerInit {
|
|||||||
if let Some(cfg) = config.config() {
|
if let Some(cfg) = config.config() {
|
||||||
self.run(cfg, &launch)?;
|
self.run(cfg, &launch)?;
|
||||||
} else {
|
} else {
|
||||||
return hypha_err!("unable to determine what to execute, image config doesn't tell us");
|
return Err(anyhow!(
|
||||||
|
"unable to determine what to execute, image config doesn't tell us"
|
||||||
|
));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::error::Result;
|
|
||||||
use crate::image::ImageInfo;
|
use crate::image::ImageInfo;
|
||||||
use crate::shared::LaunchInfo;
|
use crate::shared::LaunchInfo;
|
||||||
|
use anyhow::Result;
|
||||||
use backhand::{FilesystemWriter, NodeHeader};
|
use backhand::{FilesystemWriter, NodeHeader};
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
@ -2,11 +2,11 @@ pub mod cfgblk;
|
|||||||
|
|
||||||
use crate::autoloop::AutoLoop;
|
use crate::autoloop::AutoLoop;
|
||||||
use crate::ctl::cfgblk::ConfigBlock;
|
use crate::ctl::cfgblk::ConfigBlock;
|
||||||
use crate::error::{HyphaError, Result};
|
|
||||||
use crate::image::cache::ImageCache;
|
use crate::image::cache::ImageCache;
|
||||||
use crate::image::name::ImageName;
|
use crate::image::name::ImageName;
|
||||||
use crate::image::{ImageCompiler, ImageInfo};
|
use crate::image::{ImageCompiler, ImageInfo};
|
||||||
use crate::shared::LaunchInfo;
|
use crate::shared::LaunchInfo;
|
||||||
|
use anyhow::{anyhow, Result};
|
||||||
use loopdev::LoopControl;
|
use loopdev::LoopControl;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@ -82,16 +82,16 @@ impl Controller {
|
|||||||
let image_squashfs_path = image_info
|
let image_squashfs_path = image_info
|
||||||
.image_squashfs
|
.image_squashfs
|
||||||
.to_str()
|
.to_str()
|
||||||
.ok_or_else(|| HyphaError::new("failed to convert image squashfs path to string"))?;
|
.ok_or_else(|| anyhow!("failed to convert image squashfs path to string"))?;
|
||||||
|
|
||||||
let cfgblk_dir_path = cfgblk
|
let cfgblk_dir_path = cfgblk
|
||||||
.dir
|
.dir
|
||||||
.to_str()
|
.to_str()
|
||||||
.ok_or_else(|| HyphaError::new("failed to convert cfgblk directory path to string"))?;
|
.ok_or_else(|| anyhow!("failed to convert cfgblk directory path to string"))?;
|
||||||
let cfgblk_squashfs_path = cfgblk
|
let cfgblk_squashfs_path = cfgblk
|
||||||
.file
|
.file
|
||||||
.to_str()
|
.to_str()
|
||||||
.ok_or_else(|| HyphaError::new("failed to convert cfgblk squashfs path to string"))?;
|
.ok_or_else(|| anyhow!("failed to convert cfgblk squashfs path to string"))?;
|
||||||
|
|
||||||
let image_squashfs_loop = self.autoloop.loopify(image_squashfs_path)?;
|
let image_squashfs_loop = self.autoloop.loopify(image_squashfs_path)?;
|
||||||
let cfgblk_squashfs_loop = self.autoloop.loopify(cfgblk_squashfs_path)?;
|
let cfgblk_squashfs_loop = self.autoloop.loopify(cfgblk_squashfs_path)?;
|
||||||
@ -149,17 +149,15 @@ impl Controller {
|
|||||||
let dom_path = store.get_domain_path(domid)?;
|
let dom_path = store.get_domain_path(domid)?;
|
||||||
let uuid = match store.read_string_optional(format!("{}/hypha/uuid", dom_path).as_str())? {
|
let uuid = match store.read_string_optional(format!("{}/hypha/uuid", dom_path).as_str())? {
|
||||||
None => {
|
None => {
|
||||||
return Err(HyphaError::new(&format!(
|
return Err(anyhow!(
|
||||||
"domain {} was not found or not created by hypha",
|
"domain {} was not found or not created by hypha",
|
||||||
domid
|
domid
|
||||||
)))
|
))
|
||||||
}
|
}
|
||||||
Some(value) => value,
|
Some(value) => value,
|
||||||
};
|
};
|
||||||
if uuid.is_empty() {
|
if uuid.is_empty() {
|
||||||
return Err(HyphaError::new(
|
return Err(anyhow!("unable to find hypha uuid based on the domain",));
|
||||||
"unable to find hypha uuid based on the domain",
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
let uuid = Uuid::parse_str(&uuid)?;
|
let uuid = Uuid::parse_str(&uuid)?;
|
||||||
let loops = store.read_string(format!("{}/hypha/loops", dom_path).as_str())?;
|
let loops = store.read_string(format!("{}/hypha/loops", dom_path).as_str())?;
|
||||||
@ -235,8 +233,8 @@ impl Controller {
|
|||||||
None => continue,
|
None => continue,
|
||||||
Some(value) => value,
|
Some(value) => value,
|
||||||
};
|
};
|
||||||
let domid = u32::from_str(&domid_candidate)
|
let domid =
|
||||||
.map_err(|_| HyphaError::new("failed to parse domid"))?;
|
u32::from_str(&domid_candidate).map_err(|_| anyhow!("failed to parse domid"))?;
|
||||||
let uuid = Uuid::from_str(&uuid_string)?;
|
let uuid = Uuid::from_str(&uuid_string)?;
|
||||||
let image = self
|
let image = self
|
||||||
.client
|
.client
|
||||||
|
@ -1,141 +0,0 @@
|
|||||||
use backhand::BackhandError;
|
|
||||||
use cli_tables::TableError;
|
|
||||||
use oci_spec::OciSpecError;
|
|
||||||
use std::error::Error;
|
|
||||||
use std::ffi::NulError;
|
|
||||||
use std::fmt::{Display, Formatter};
|
|
||||||
use std::num::ParseIntError;
|
|
||||||
use std::path::StripPrefixError;
|
|
||||||
use xenclient::XenClientError;
|
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, HyphaError>;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct HyphaError {
|
|
||||||
message: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HyphaError {
|
|
||||||
pub fn new(msg: &str) -> HyphaError {
|
|
||||||
HyphaError {
|
|
||||||
message: msg.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for HyphaError {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "{}", self.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Error for HyphaError {
|
|
||||||
fn description(&self) -> &str {
|
|
||||||
&self.message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! hypha_err {
|
|
||||||
($($arg:tt)*) => {{
|
|
||||||
use $crate::error::HyphaError;
|
|
||||||
let text = std::fmt::format(format_args!($($arg)*));
|
|
||||||
Err(HyphaError::new(text.as_str()))
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<std::io::Error> for HyphaError {
|
|
||||||
fn from(value: std::io::Error) -> Self {
|
|
||||||
HyphaError::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<XenClientError> for HyphaError {
|
|
||||||
fn from(value: XenClientError) -> Self {
|
|
||||||
HyphaError::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<walkdir::Error> for HyphaError {
|
|
||||||
fn from(value: walkdir::Error) -> Self {
|
|
||||||
HyphaError::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<StripPrefixError> for HyphaError {
|
|
||||||
fn from(value: StripPrefixError) -> Self {
|
|
||||||
HyphaError::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<BackhandError> for HyphaError {
|
|
||||||
fn from(value: BackhandError) -> Self {
|
|
||||||
HyphaError::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<serde_json::Error> for HyphaError {
|
|
||||||
fn from(value: serde_json::Error) -> Self {
|
|
||||||
HyphaError::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ureq::Error> for HyphaError {
|
|
||||||
fn from(value: ureq::Error) -> Self {
|
|
||||||
HyphaError::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ParseIntError> for HyphaError {
|
|
||||||
fn from(value: ParseIntError) -> Self {
|
|
||||||
HyphaError::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<OciSpecError> for HyphaError {
|
|
||||||
fn from(value: OciSpecError) -> Self {
|
|
||||||
HyphaError::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<url::ParseError> for HyphaError {
|
|
||||||
fn from(value: url::ParseError) -> Self {
|
|
||||||
HyphaError::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<std::fmt::Error> for HyphaError {
|
|
||||||
fn from(value: std::fmt::Error) -> Self {
|
|
||||||
HyphaError::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<uuid::Error> for HyphaError {
|
|
||||||
fn from(value: uuid::Error) -> Self {
|
|
||||||
HyphaError::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<xenstore::error::Error> for HyphaError {
|
|
||||||
fn from(value: xenstore::error::Error) -> Self {
|
|
||||||
HyphaError::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<TableError> for HyphaError {
|
|
||||||
fn from(value: TableError) -> Self {
|
|
||||||
HyphaError::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<NulError> for HyphaError {
|
|
||||||
fn from(value: NulError) -> Self {
|
|
||||||
HyphaError::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<nix::Error> for HyphaError {
|
|
||||||
fn from(value: nix::Error) -> Self {
|
|
||||||
HyphaError::new(value.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
use crate::error::{HyphaError, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use oci_spec::image::{Arch, Descriptor, ImageIndex, ImageManifest, MediaType, Os, ToDockerV2S2};
|
use oci_spec::image::{Arch, Descriptor, ImageIndex, ImageManifest, MediaType, Os, ToDockerV2S2};
|
||||||
use std::io::copy;
|
use std::io::copy;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
@ -63,21 +63,21 @@ impl RegistryClient {
|
|||||||
MediaType::ImageIndex.to_docker_v2s2()?,
|
MediaType::ImageIndex.to_docker_v2s2()?,
|
||||||
);
|
);
|
||||||
let response = self.call(self.agent.get(url.as_str()).set("Accept", &accept))?;
|
let response = self.call(self.agent.get(url.as_str()).set("Accept", &accept))?;
|
||||||
let content_type = response.header("Content-Type").ok_or_else(|| {
|
let content_type = response
|
||||||
HyphaError::new("registry response did not have a Content-Type header")
|
.header("Content-Type")
|
||||||
})?;
|
.ok_or_else(|| anyhow!("registry response did not have a Content-Type header"))?;
|
||||||
if content_type == MediaType::ImageIndex.to_string()
|
if content_type == MediaType::ImageIndex.to_string()
|
||||||
|| content_type == MediaType::ImageIndex.to_docker_v2s2()?
|
|| content_type == MediaType::ImageIndex.to_docker_v2s2()?
|
||||||
{
|
{
|
||||||
let index = ImageIndex::from_reader(response.into_reader())?;
|
let index = ImageIndex::from_reader(response.into_reader())?;
|
||||||
let descriptor = self
|
let descriptor = self
|
||||||
.pick_manifest(index)
|
.pick_manifest(index)
|
||||||
.ok_or_else(|| HyphaError::new("unable to pick manifest from index"))?;
|
.ok_or_else(|| anyhow!("unable to pick manifest from index"))?;
|
||||||
return self.get_manifest_with_digest(name, descriptor.digest());
|
return self.get_manifest_with_digest(name, descriptor.digest());
|
||||||
}
|
}
|
||||||
let digest = response
|
let digest = response
|
||||||
.header("Docker-Content-Digest")
|
.header("Docker-Content-Digest")
|
||||||
.ok_or_else(|| HyphaError::new("fetching manifest did not yield a content digest"))?
|
.ok_or_else(|| anyhow!("fetching manifest did not yield a content digest"))?
|
||||||
.to_string();
|
.to_string();
|
||||||
let manifest = ImageManifest::from_reader(response.into_reader())?;
|
let manifest = ImageManifest::from_reader(response.into_reader())?;
|
||||||
Ok((manifest, digest))
|
Ok((manifest, digest))
|
||||||
|
@ -2,10 +2,10 @@ pub mod cache;
|
|||||||
pub mod fetch;
|
pub mod fetch;
|
||||||
pub mod name;
|
pub mod name;
|
||||||
|
|
||||||
use crate::error::{HyphaError, Result};
|
|
||||||
use crate::image::cache::ImageCache;
|
use crate::image::cache::ImageCache;
|
||||||
use crate::image::fetch::RegistryClient;
|
use crate::image::fetch::RegistryClient;
|
||||||
use crate::image::name::ImageName;
|
use crate::image::name::ImageName;
|
||||||
|
use anyhow::{anyhow, Result};
|
||||||
use backhand::compression::Compressor;
|
use backhand::compression::Compressor;
|
||||||
use backhand::{FilesystemCompressor, FilesystemWriter, NodeHeader};
|
use backhand::{FilesystemCompressor, FilesystemWriter, NodeHeader};
|
||||||
use flate2::read::GzDecoder;
|
use flate2::read::GzDecoder;
|
||||||
@ -160,10 +160,10 @@ impl ImageCompiler<'_> {
|
|||||||
let mut entry = entry?;
|
let mut entry = entry?;
|
||||||
let path = entry.path()?;
|
let path = entry.path()?;
|
||||||
let Some(name) = path.file_name() else {
|
let Some(name) = path.file_name() else {
|
||||||
return Err(HyphaError::new("unable to get file name"));
|
return Err(anyhow!("unable to get file name"));
|
||||||
};
|
};
|
||||||
let Some(name) = name.to_str() else {
|
let Some(name) = name.to_str() else {
|
||||||
return Err(HyphaError::new("unable to get file name as string"));
|
return Err(anyhow!("unable to get file name as string"));
|
||||||
};
|
};
|
||||||
|
|
||||||
if name.starts_with(".wh.") {
|
if name.starts_with(".wh.") {
|
||||||
@ -214,7 +214,7 @@ impl ImageCompiler<'_> {
|
|||||||
} else if path.is_dir() {
|
} else if path.is_dir() {
|
||||||
fs::remove_dir_all(&path)?;
|
fs::remove_dir_all(&path)?;
|
||||||
} else {
|
} else {
|
||||||
return Err(HyphaError::new("opaque whiteout entry did not exist"));
|
return Err(anyhow!("opaque whiteout entry did not exist"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -280,7 +280,7 @@ impl ImageCompiler<'_> {
|
|||||||
fn check_safe_path(&self, dst: &PathBuf, image_dir: &PathBuf) -> Result<()> {
|
fn check_safe_path(&self, dst: &PathBuf, image_dir: &PathBuf) -> Result<()> {
|
||||||
let resolved = path_clean::clean(dst);
|
let resolved = path_clean::clean(dst);
|
||||||
if !resolved.starts_with(image_dir) {
|
if !resolved.starts_with(image_dir) {
|
||||||
return Err(HyphaError::new("layer attempts to work outside image dir"));
|
return Err(anyhow!("layer attempts to work outside image dir"));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -306,7 +306,7 @@ impl ImageCompiler<'_> {
|
|||||||
let mut file = File::create(&layer_path)?;
|
let mut file = File::create(&layer_path)?;
|
||||||
let size = client.write_blob(&image.name, layer, &mut file)?;
|
let size = client.write_blob(&image.name, layer, &mut file)?;
|
||||||
if layer.size() as u64 != size {
|
if layer.size() as u64 != size {
|
||||||
return Err(HyphaError::new(
|
return Err(anyhow!(
|
||||||
"downloaded layer size differs from size in manifest",
|
"downloaded layer size differs from size in manifest",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -323,11 +323,7 @@ impl ImageCompiler<'_> {
|
|||||||
MediaType::ImageLayer => LayerCompressionType::None,
|
MediaType::ImageLayer => LayerCompressionType::None,
|
||||||
MediaType::ImageLayerGzip => LayerCompressionType::Gzip,
|
MediaType::ImageLayerGzip => LayerCompressionType::Gzip,
|
||||||
MediaType::ImageLayerZstd => LayerCompressionType::Zstd,
|
MediaType::ImageLayerZstd => LayerCompressionType::Zstd,
|
||||||
other => {
|
other => return Err(anyhow!("found layer with unknown media type: {}", other)),
|
||||||
return Err(HyphaError::new(
|
|
||||||
format!("found layer with unknown media type: {}", other).as_str(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
Ok(LayerFile {
|
Ok(LayerFile {
|
||||||
digest: layer.digest().clone(),
|
digest: layer.digest().clone(),
|
||||||
@ -346,7 +342,7 @@ impl ImageCompiler<'_> {
|
|||||||
.path()
|
.path()
|
||||||
.strip_prefix(image_dir)?
|
.strip_prefix(image_dir)?
|
||||||
.to_str()
|
.to_str()
|
||||||
.ok_or_else(|| HyphaError::new("failed to strip prefix of tmpdir"))?;
|
.ok_or_else(|| anyhow!("failed to strip prefix of tmpdir"))?;
|
||||||
let rel = format!("/{}", rel);
|
let rel = format!("/{}", rel);
|
||||||
trace!("ImageCompiler squash write {}", rel);
|
trace!("ImageCompiler squash write {}", rel);
|
||||||
let typ = entry.file_type();
|
let typ = entry.file_type();
|
||||||
@ -373,7 +369,7 @@ impl ImageCompiler<'_> {
|
|||||||
let symlink = fs::read_link(entry.path())?;
|
let symlink = fs::read_link(entry.path())?;
|
||||||
let symlink = symlink
|
let symlink = symlink
|
||||||
.to_str()
|
.to_str()
|
||||||
.ok_or_else(|| HyphaError::new("failed to read symlink"))?;
|
.ok_or_else(|| anyhow!("failed to read symlink"))?;
|
||||||
writer.push_symlink(symlink, rel, header)?;
|
writer.push_symlink(symlink, rel, header)?;
|
||||||
} else if typ.is_dir() {
|
} else if typ.is_dir() {
|
||||||
writer.push_dir(rel, header)?;
|
writer.push_dir(rel, header)?;
|
||||||
@ -393,7 +389,7 @@ impl ImageCompiler<'_> {
|
|||||||
let device = metadata.dev();
|
let device = metadata.dev();
|
||||||
writer.push_char_device(device as u32, rel, header)?;
|
writer.push_char_device(device as u32, rel, header)?;
|
||||||
} else {
|
} else {
|
||||||
return Err(HyphaError::new("invalid file type"));
|
return Err(anyhow!("invalid file type"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,7 +397,7 @@ impl ImageCompiler<'_> {
|
|||||||
|
|
||||||
let squash_file_path = squash_file
|
let squash_file_path = squash_file
|
||||||
.to_str()
|
.to_str()
|
||||||
.ok_or_else(|| HyphaError::new("failed to convert squashfs string"))?;
|
.ok_or_else(|| anyhow!("failed to convert squashfs string"))?;
|
||||||
|
|
||||||
let mut file = File::create(squash_file)?;
|
let mut file = File::create(squash_file)?;
|
||||||
trace!("ImageCompiler squash generate: {}", squash_file_path);
|
trace!("ImageCompiler squash generate: {}", squash_file_path);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::error::Result;
|
use anyhow::Result;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
pub mod autoloop;
|
pub mod autoloop;
|
||||||
pub mod container;
|
pub mod container;
|
||||||
pub mod ctl;
|
pub mod ctl;
|
||||||
pub mod error;
|
|
||||||
pub mod image;
|
pub mod image;
|
||||||
mod shared;
|
pub mod shared;
|
||||||
|
Loading…
Reference in New Issue
Block a user