diff --git a/Cargo.toml b/Cargo.toml index 952e033..4fcc45d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ resolver = "2" version = "0.0.1" [workspace.dependencies] +anyhow = "1.0" thiserror = "1.0" log = "0.4.20" libc = "0.2" diff --git a/hypha/Cargo.toml b/hypha/Cargo.toml index 4faa3db..d4f3cdc 100644 --- a/hypha/Cargo.toml +++ b/hypha/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" resolver = "2" [dependencies] +anyhow = { workspace = true } log = { workspace = true } env_logger = { workspace = true } zstd = { workspace = true } diff --git a/hypha/bin/container.rs b/hypha/bin/container.rs index a7e29a6..b854377 100644 --- a/hypha/bin/container.rs +++ b/hypha/bin/container.rs @@ -1,5 +1,5 @@ +use anyhow::Result; use hypha::container::init::ContainerInit; -use hypha::error::Result; fn main() -> Result<()> { env_logger::init(); diff --git a/hypha/bin/controller.rs b/hypha/bin/controller.rs index b646d8c..39043bb 100644 --- a/hypha/bin/controller.rs +++ b/hypha/bin/controller.rs @@ -1,6 +1,6 @@ +use anyhow::{anyhow, Result}; use clap::{Parser, Subcommand}; use hypha::ctl::Controller; -use hypha::error::{HyphaError, Result}; use std::path::PathBuf; #[derive(Parser, Debug)] @@ -48,8 +48,7 @@ fn main() -> Result<()> { let args = ControllerArgs::parse(); let store_path = if args.store == "auto" { - default_store_path() - .ok_or_else(|| HyphaError::new("unable to determine default store path")) + default_store_path().ok_or_else(|| anyhow!("unable to determine default store path")) } else { Ok(PathBuf::from(args.store)) }?; @@ -57,7 +56,7 @@ fn main() -> Result<()> { let store_path = store_path .to_str() .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())?; diff --git a/hypha/src/autoloop.rs b/hypha/src/autoloop.rs index f849aa5..4dc881d 100644 --- a/hypha/src/autoloop.rs +++ b/hypha/src/autoloop.rs @@ -1,4 +1,4 @@ -use crate::error::{HyphaError, Result}; +use anyhow::{anyhow, Result}; use loopdev::{LoopControl, LoopDevice}; use xenclient::BlockDeviceRef; @@ -16,11 +16,9 @@ impl AutoLoop { device.with().read_only(true).attach(file)?; let path = device .path() - .ok_or(HyphaError::new("unable to get loop device path"))? + .ok_or(anyhow!("unable to get loop device path"))? .to_str() - .ok_or(HyphaError::new( - "unable to convert loop device path to string", - ))? + .ok_or(anyhow!("unable to convert loop device path to string",))? .to_string(); let major = device.major()?; let minor = device.minor()?; diff --git a/hypha/src/container/init.rs b/hypha/src/container/init.rs index c7ccd75..6755c0f 100644 --- a/hypha/src/container/init.rs +++ b/hypha/src/container/init.rs @@ -1,6 +1,5 @@ -use crate::error::Result; -use crate::hypha_err; use crate::shared::LaunchInfo; +use anyhow::{anyhow, Result}; use log::trace; use nix::libc::dup2; use nix::unistd::execve; @@ -69,7 +68,9 @@ impl ContainerInit { if let Some(cfg) = config.config() { self.run(cfg, &launch)?; } 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(()) } diff --git a/hypha/src/ctl/cfgblk.rs b/hypha/src/ctl/cfgblk.rs index dd6fd2a..ae310c1 100644 --- a/hypha/src/ctl/cfgblk.rs +++ b/hypha/src/ctl/cfgblk.rs @@ -1,6 +1,6 @@ -use crate::error::Result; use crate::image::ImageInfo; use crate::shared::LaunchInfo; +use anyhow::Result; use backhand::{FilesystemWriter, NodeHeader}; use log::trace; use std::fs; diff --git a/hypha/src/ctl/mod.rs b/hypha/src/ctl/mod.rs index 9565268..4c0368d 100644 --- a/hypha/src/ctl/mod.rs +++ b/hypha/src/ctl/mod.rs @@ -2,11 +2,11 @@ pub mod cfgblk; use crate::autoloop::AutoLoop; use crate::ctl::cfgblk::ConfigBlock; -use crate::error::{HyphaError, Result}; use crate::image::cache::ImageCache; use crate::image::name::ImageName; use crate::image::{ImageCompiler, ImageInfo}; use crate::shared::LaunchInfo; +use anyhow::{anyhow, Result}; use loopdev::LoopControl; use std::io::{Read, Write}; use std::path::PathBuf; @@ -82,16 +82,16 @@ impl Controller { let image_squashfs_path = image_info .image_squashfs .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 .dir .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 .file .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 cfgblk_squashfs_loop = self.autoloop.loopify(cfgblk_squashfs_path)?; @@ -149,17 +149,15 @@ impl Controller { let dom_path = store.get_domain_path(domid)?; let uuid = match store.read_string_optional(format!("{}/hypha/uuid", dom_path).as_str())? { None => { - return Err(HyphaError::new(&format!( + return Err(anyhow!( "domain {} was not found or not created by hypha", domid - ))) + )) } Some(value) => value, }; if uuid.is_empty() { - return Err(HyphaError::new( - "unable to find hypha uuid based on the domain", - )); + return Err(anyhow!("unable to find hypha uuid based on the domain",)); } let uuid = Uuid::parse_str(&uuid)?; let loops = store.read_string(format!("{}/hypha/loops", dom_path).as_str())?; @@ -235,8 +233,8 @@ impl Controller { None => continue, Some(value) => value, }; - let domid = u32::from_str(&domid_candidate) - .map_err(|_| HyphaError::new("failed to parse domid"))?; + let domid = + u32::from_str(&domid_candidate).map_err(|_| anyhow!("failed to parse domid"))?; let uuid = Uuid::from_str(&uuid_string)?; let image = self .client diff --git a/hypha/src/error.rs b/hypha/src/error.rs deleted file mode 100644 index 5609a45..0000000 --- a/hypha/src/error.rs +++ /dev/null @@ -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 = std::result::Result; - -#[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 for HyphaError { - fn from(value: std::io::Error) -> Self { - HyphaError::new(value.to_string().as_str()) - } -} - -impl From for HyphaError { - fn from(value: XenClientError) -> Self { - HyphaError::new(value.to_string().as_str()) - } -} - -impl From for HyphaError { - fn from(value: walkdir::Error) -> Self { - HyphaError::new(value.to_string().as_str()) - } -} - -impl From for HyphaError { - fn from(value: StripPrefixError) -> Self { - HyphaError::new(value.to_string().as_str()) - } -} - -impl From for HyphaError { - fn from(value: BackhandError) -> Self { - HyphaError::new(value.to_string().as_str()) - } -} - -impl From for HyphaError { - fn from(value: serde_json::Error) -> Self { - HyphaError::new(value.to_string().as_str()) - } -} - -impl From for HyphaError { - fn from(value: ureq::Error) -> Self { - HyphaError::new(value.to_string().as_str()) - } -} - -impl From for HyphaError { - fn from(value: ParseIntError) -> Self { - HyphaError::new(value.to_string().as_str()) - } -} - -impl From for HyphaError { - fn from(value: OciSpecError) -> Self { - HyphaError::new(value.to_string().as_str()) - } -} - -impl From for HyphaError { - fn from(value: url::ParseError) -> Self { - HyphaError::new(value.to_string().as_str()) - } -} - -impl From for HyphaError { - fn from(value: std::fmt::Error) -> Self { - HyphaError::new(value.to_string().as_str()) - } -} - -impl From for HyphaError { - fn from(value: uuid::Error) -> Self { - HyphaError::new(value.to_string().as_str()) - } -} - -impl From for HyphaError { - fn from(value: xenstore::error::Error) -> Self { - HyphaError::new(value.to_string().as_str()) - } -} - -impl From for HyphaError { - fn from(value: TableError) -> Self { - HyphaError::new(value.to_string().as_str()) - } -} - -impl From for HyphaError { - fn from(value: NulError) -> Self { - HyphaError::new(value.to_string().as_str()) - } -} - -impl From for HyphaError { - fn from(value: nix::Error) -> Self { - HyphaError::new(value.to_string().as_str()) - } -} diff --git a/hypha/src/image/fetch.rs b/hypha/src/image/fetch.rs index e08c805..dadce06 100644 --- a/hypha/src/image/fetch.rs +++ b/hypha/src/image/fetch.rs @@ -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 std::io::copy; use std::io::{Read, Write}; @@ -63,21 +63,21 @@ impl RegistryClient { MediaType::ImageIndex.to_docker_v2s2()?, ); let response = self.call(self.agent.get(url.as_str()).set("Accept", &accept))?; - let content_type = response.header("Content-Type").ok_or_else(|| { - HyphaError::new("registry response did not have a Content-Type header") - })?; + let content_type = response + .header("Content-Type") + .ok_or_else(|| anyhow!("registry response did not have a Content-Type header"))?; if content_type == MediaType::ImageIndex.to_string() || content_type == MediaType::ImageIndex.to_docker_v2s2()? { let index = ImageIndex::from_reader(response.into_reader())?; let descriptor = self .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()); } let digest = response .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(); let manifest = ImageManifest::from_reader(response.into_reader())?; Ok((manifest, digest)) diff --git a/hypha/src/image/mod.rs b/hypha/src/image/mod.rs index 5ca34bd..0a482a0 100644 --- a/hypha/src/image/mod.rs +++ b/hypha/src/image/mod.rs @@ -2,10 +2,10 @@ pub mod cache; pub mod fetch; pub mod name; -use crate::error::{HyphaError, Result}; use crate::image::cache::ImageCache; use crate::image::fetch::RegistryClient; use crate::image::name::ImageName; +use anyhow::{anyhow, Result}; use backhand::compression::Compressor; use backhand::{FilesystemCompressor, FilesystemWriter, NodeHeader}; use flate2::read::GzDecoder; @@ -160,10 +160,10 @@ impl ImageCompiler<'_> { let mut entry = entry?; let path = entry.path()?; 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 { - 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.") { @@ -214,7 +214,7 @@ impl ImageCompiler<'_> { } else if path.is_dir() { fs::remove_dir_all(&path)?; } else { - return Err(HyphaError::new("opaque whiteout entry did not exist")); + return Err(anyhow!("opaque whiteout entry did not exist")); } } } else { @@ -280,7 +280,7 @@ impl ImageCompiler<'_> { fn check_safe_path(&self, dst: &PathBuf, image_dir: &PathBuf) -> Result<()> { let resolved = path_clean::clean(dst); 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(()) } @@ -306,7 +306,7 @@ impl ImageCompiler<'_> { let mut file = File::create(&layer_path)?; let size = client.write_blob(&image.name, layer, &mut file)?; if layer.size() as u64 != size { - return Err(HyphaError::new( + return Err(anyhow!( "downloaded layer size differs from size in manifest", )); } @@ -323,11 +323,7 @@ impl ImageCompiler<'_> { MediaType::ImageLayer => LayerCompressionType::None, MediaType::ImageLayerGzip => LayerCompressionType::Gzip, MediaType::ImageLayerZstd => LayerCompressionType::Zstd, - other => { - return Err(HyphaError::new( - format!("found layer with unknown media type: {}", other).as_str(), - )) - } + other => return Err(anyhow!("found layer with unknown media type: {}", other)), }; Ok(LayerFile { digest: layer.digest().clone(), @@ -346,7 +342,7 @@ impl ImageCompiler<'_> { .path() .strip_prefix(image_dir)? .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); trace!("ImageCompiler squash write {}", rel); let typ = entry.file_type(); @@ -373,7 +369,7 @@ impl ImageCompiler<'_> { let symlink = fs::read_link(entry.path())?; let symlink = symlink .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)?; } else if typ.is_dir() { writer.push_dir(rel, header)?; @@ -393,7 +389,7 @@ impl ImageCompiler<'_> { let device = metadata.dev(); writer.push_char_device(device as u32, rel, header)?; } 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 .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)?; trace!("ImageCompiler squash generate: {}", squash_file_path); diff --git a/hypha/src/image/name.rs b/hypha/src/image/name.rs index e145575..dd1cc83 100644 --- a/hypha/src/image/name.rs +++ b/hypha/src/image/name.rs @@ -1,4 +1,4 @@ -use crate::error::Result; +use anyhow::Result; use std::fmt; use url::Url; diff --git a/hypha/src/lib.rs b/hypha/src/lib.rs index b295648..5d1be80 100644 --- a/hypha/src/lib.rs +++ b/hypha/src/lib.rs @@ -1,6 +1,5 @@ pub mod autoloop; pub mod container; pub mod ctl; -pub mod error; pub mod image; -mod shared; +pub mod shared;