mirror of
				https://github.com/edera-dev/krata.git
				synced 2025-11-03 07:19:37 +00:00 
			
		
		
		
	hypha: convert to using anyhow for error handling
This commit is contained in:
		@ -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;
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user