diff options
Diffstat (limited to 'zoned')
-rw-r--r-- | zoned/Cargo.toml | 2 | ||||
-rw-r--r-- | zoned/src/api.rs | 18 | ||||
-rw-r--r-- | zoned/src/lib.rs | 52 |
3 files changed, 64 insertions, 8 deletions
diff --git a/zoned/Cargo.toml b/zoned/Cargo.toml index 4983d03..28d1650 100644 --- a/zoned/Cargo.toml +++ b/zoned/Cargo.toml @@ -12,11 +12,13 @@ description = "daemon for managing containers using systemd-nspawn and ZFS" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +anyhow = "1.0.53" figment = "0.10.6" lazy_static = "1.4.0" rocket = { version = "0.5.0-rc.1", default-features = false, features = ["json"] } rocket_okapi = { version = "0.8.0-rc.1", features = ["rapidoc", "swagger"] } serde = "1.0.136" +thiserror = "1.0.30" zone_core = { version = "0.1.0", path = "../zone_core" } zone_nspawn = { version = "0.1.0", path = "../zone_nspawn" } zone_zfs = { version = "0.1.0", path = "../zone_zfs" } diff --git a/zoned/src/api.rs b/zoned/src/api.rs index d36d2e2..fa98562 100644 --- a/zoned/src/api.rs +++ b/zoned/src/api.rs @@ -7,6 +7,8 @@ use rocket_okapi::{ }; use zone_core::{Container, PartialEqOrDefault}; +use crate::{Error, Result}; + /// # Test endpoint /// /// Returns a list of containers based on the query. @@ -34,22 +36,22 @@ pub fn container_list(container: Container) -> Json<Vec<Container>> { } /// Create container +/// +/// Creates a new container volume from the provided container json data #[openapi(tag = "Container")] #[post("/container", data = "<container>")] fn create_container( container: Json<Container>, zfs_config: &State<zone_zfs::Config>, -) -> Json<Container> { - let container = zone_zfs::create_file_system( +) -> Result<Json<Container>> { + zone_zfs::create_file_system( container.template.clone(), format!("{}-{}", container.user, container.id), zfs_config, - ); - - match container { - Ok(f) => Json(Container::try_from(f).expect("failed to convert")), - Err(_err) => todo!("Respond with error message"), - } + )? + .try_into() + .map_err(Error::from) + .map(Container::into) } pub fn build_rocket(config: crate::Config) -> Rocket<Build> { diff --git a/zoned/src/lib.rs b/zoned/src/lib.rs index f17530f..4784ff5 100644 --- a/zoned/src/lib.rs +++ b/zoned/src/lib.rs @@ -1,4 +1,56 @@ +use rocket::{ + http::Status, + response::{self, Responder}, + Request, +}; +use rocket_okapi::{ + gen::OpenApiGenerator, okapi::openapi3::Responses, response::OpenApiResponderInner, + util::ensure_status_code_exists, +}; use serde::{Deserialize, Serialize}; +use thiserror::Error; +use zone_core::Container; + +type Result<T> = std::result::Result<T, Error>; + +#[derive(Error, Debug)] +pub enum Error { + #[error("Container Error {0:?}")] + Container(Container), + + #[error("ZFS Error {source:?}")] + ZFS { + #[from] + source: zone_zfs::Error, + }, + + #[error("NSpawn Error {source:?}")] + Nspawn { + #[from] + source: zone_nspawn::Error, + }, + + #[error(transparent)] + Other(#[from] anyhow::Error), +} + +impl<'r, 'o: 'r> Responder<'r, 'o> for Error { + fn respond_to(self, req: &'r Request<'_>) -> response::Result<'o> { + // https://stuarth.github.io/rocket-error-handling/ + // match self { + // _ => Status::InternalServerError.respond_to(req), + // } + Status::InternalServerError.respond_to(req) + } +} + +impl OpenApiResponderInner for Error { + fn responses(_gen: &mut OpenApiGenerator) -> rocket_okapi::Result<Responses> { + let mut responses = Responses::default(); + ensure_status_code_exists(&mut responses, 500); + Ok(responses) + } +} #[derive(Default, Serialize, Deserialize)] pub struct Config { |