From 22d6c6b6c8b67c5c0f3ebcc8adbf8fefe1084c99 Mon Sep 17 00:00:00 2001 From: folex <0xdxdy@gmail.com> Date: Tue, 18 Aug 2020 22:58:41 +0300 Subject: [PATCH] Do not throw error if service_base_dir already exists (#18) --- fluence-app-service/src/errors.rs | 24 +++++++++++-------- fluence-app-service/src/service.rs | 38 ++++++++++++++++++------------ fluence-faas/src/misc/config.rs | 1 + 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/fluence-app-service/src/errors.rs b/fluence-app-service/src/errors.rs index 6ca8d0dd..d6b5dcbd 100644 --- a/fluence-app-service/src/errors.rs +++ b/fluence-app-service/src/errors.rs @@ -18,17 +18,22 @@ use fluence_faas::FaaSError; use std::io::Error as IOError; use std::error::Error; +use std::path::PathBuf; #[derive(Debug)] pub enum AppServiceError { /// An error related to config parsing. InvalidConfig(String), - /// Various errors related to file i/o. - IOError(String), - /// FaaS errors. FaaSError(FaaSError), + + /// Directory creation failed + CreateDir { err: IOError, path: PathBuf }, + + /// Base service dir wasn't specified in config + /// TODO: do we need that dir to be optional? + MissingServiceDir, } impl Error for AppServiceError {} @@ -37,18 +42,17 @@ impl std::fmt::Display for AppServiceError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { match self { AppServiceError::InvalidConfig(err_msg) => write!(f, "{}", err_msg), - AppServiceError::IOError(err_msg) => write!(f, "{}", err_msg), AppServiceError::FaaSError(err) => write!(f, "{}", err), + AppServiceError::CreateDir { err, path } => { + write!(f, "Failed to create dir {:?}: {:?}", path, err) + } + AppServiceError::MissingServiceDir => { + write!(f, "service base dir should be specified in config") + } } } } -impl From for AppServiceError { - fn from(err: IOError) -> Self { - AppServiceError::IOError(format!("{}", err)) - } -} - impl From for AppServiceError { fn from(err: FaaSError) -> Self { AppServiceError::FaaSError(err) diff --git a/fluence-app-service/src/service.rs b/fluence-app-service/src/service.rs index 2fbce14a..20247d0c 100644 --- a/fluence-app-service/src/service.rs +++ b/fluence-app-service/src/service.rs @@ -22,6 +22,8 @@ use fluence_faas::FluenceFaaS; use fluence_faas::ModulesConfig; use std::convert::TryInto; +use std::path::{Path, PathBuf}; +use std::io::ErrorKind; const SERVICE_ID_ENV_NAME: &str = "service_id"; const SERVICE_LOCAL_DIR_NAME: &str = "local"; @@ -81,26 +83,32 @@ impl AppService { service_id: &str, mut envs: Vec, ) -> Result { - let base_dir = match config.service_base_dir.as_ref() { - Some(base_dir) => base_dir, - _ => { - return Err(AppServiceError::IOError(String::from( - "service_base_dir should be specified", - ))) - } + let base_dir: &Path = config + .service_base_dir + .as_ref() + .ok_or(AppServiceError::MissingServiceDir)? + .as_ref(); + + let create = |dir: &PathBuf| match std::fs::create_dir(dir) { + Err(e) if e.kind() == ErrorKind::AlreadyExists => Ok(()), + Err(err) => Err(AppServiceError::CreateDir { + err, + path: dir.clone(), + }), + _ => Ok(()), }; - let service_dir_path = std::path::Path::new(base_dir).join(service_id); - std::fs::create_dir(service_dir_path.clone())?; // will return an error if dir is already exists + let service_dir = base_dir.join(service_id); + create(&service_dir)?; - let local_dir_path = service_dir_path.join(SERVICE_LOCAL_DIR_NAME); - std::fs::create_dir(local_dir_path.clone())?; // will return an error if dir is already exists + let local_dir = service_dir.join(SERVICE_LOCAL_DIR_NAME); + create(&local_dir)?; - let tmp_dir_path = service_dir_path.join(SERVICE_TMP_DIR_NAME); - std::fs::create_dir(tmp_dir_path.clone())?; // will return an error if dir is already exists + let tmp_dir = service_dir.join(SERVICE_TMP_DIR_NAME); + create(&tmp_dir)?; - let local_dir: String = local_dir_path.to_string_lossy().into(); - let tmp_dir: String = tmp_dir_path.to_string_lossy().into(); + let local_dir = local_dir.to_string_lossy().to_string(); + let tmp_dir = tmp_dir.to_string_lossy().to_string(); let preopened_files = vec![local_dir.clone(), tmp_dir.clone()]; let mapped_dirs = vec![ diff --git a/fluence-faas/src/misc/config.rs b/fluence-faas/src/misc/config.rs index f9c6dcb8..457a5202 100644 --- a/fluence-faas/src/misc/config.rs +++ b/fluence-faas/src/misc/config.rs @@ -133,6 +133,7 @@ pub struct RawWASIConfig { #[derive(Debug, Clone, Default)] pub struct ModulesConfig { /// Used for preparing filesystem on the service initialization stage. + /// TODO: do we need that dir to be optional? We require it on creation anyways pub service_base_dir: Option, /// Path to a dir where compiled Wasm modules are located.