use std::fs;
use std::path::{Path, PathBuf};
use brane_cfg::info::Info as _;
use brane_cfg::node::{NodeConfig, NodeKind};
use log::{debug, info};
pub use crate::errors::UnpackError as Error;
use crate::spec::ResolvableNodeKind;
pub fn compose(kind: ResolvableNodeKind, fix_dirs: bool, path: impl AsRef<Path>, node_config_path: impl AsRef<Path>) -> Result<(), Error> {
let path: &Path = path.as_ref();
let node_config_path: &Path = node_config_path.as_ref();
info!("Extracting Docker Compose file for '{}' to '{}'", kind, path.display());
let kind: NodeKind = match kind.0 {
Some(kind) => kind,
None => {
debug!("Resolving node kind using '{}'...", node_config_path.display());
let node_config: NodeConfig = match NodeConfig::from_path(node_config_path) {
Ok(config) => config,
Err(err) => {
return Err(Error::NodeConfigError { err });
},
};
node_config.node.kind()
},
};
let path: PathBuf = path.to_string_lossy().replace("$NODE", &kind.to_string()).into();
if let Some(parent) = path.parent() {
debug!("Asserting target directory '{}' exists...", parent.display());
if !parent.exists() {
if fix_dirs {
if let Err(err) = fs::create_dir_all(parent) {
return Err(Error::TargetDirCreateError { path: parent.into(), err });
}
} else {
return Err(Error::TargetDirNotFound { path: parent.into() });
}
}
if !parent.is_dir() {
return Err(Error::TargetDirNotADir { path: parent.into() });
}
}
let compose: &str = match kind {
NodeKind::Central => include_str!("../../docker-compose-central.yml"),
NodeKind::Worker => include_str!("../../docker-compose-worker.yml"),
NodeKind::Proxy => include_str!("../../docker-compose-proxy.yml"),
};
debug!("Writing file to '{}'...", path.display());
if let Err(err) = fs::write(&path, compose) {
return Err(Error::FileWriteError { what: "Docker Compose", path, err });
}
Ok(())
}