use std::path::PathBuf; use std::process::Command; use serde::{Deserialize, Serialize}; use serde_json::Value as JValue; #[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)] pub struct Container { pub service: String, pub name: String, pub image: String, } pub struct DockerCompose { base_dir: PathBuf, } impl DockerCompose { pub fn new(base_dir: PathBuf) -> Self { Self { base_dir } } pub fn version() -> String { let version = Command::new("docker-compose") .arg("--version") .output() .expect("unable to obtain DockerCompose version"); let x = String::from_utf8(version.stdout).unwrap(); let x: Vec<&str> = x.split("Docker Compose version ").collect(); x.get(1).unwrap().trim().to_string() } pub fn services(&self) -> Vec { let ps = Command::new("docker-compose") .current_dir(&self.base_dir) .args(["ps", "--format", "json"]) .output() .expect("unable to obtain DockerCompose version"); let ps = String::from_utf8(ps.stdout).unwrap(); let x: serde_json::Value = serde_json::from_str(&ps).unwrap(); if let JValue::Array(val) = x { let mut containers = Vec::with_capacity(val.len()); for item in val.iter() { if let JValue::Object(val) = item { containers.push(Container { name: val["Name"].as_str().unwrap().to_string(), service: val["Service"].as_str().unwrap().to_string(), image: val["Image"].as_str().unwrap().to_string(), }) } } return containers; } return Vec::default(); } pub fn up(&self) { let mut child = Command::new("docker-compose") .current_dir(&self.base_dir) .args(["up", "--detach", "--remove-orphans"]) .spawn() .expect("unable to run DockerCompose"); child.wait().unwrap(); } pub fn logs(&self, service: &str) -> String { let output = Command::new("docker-compose") .current_dir(&self.base_dir) .args(["logs", service]) .output() .expect("unable to get logs"); String::from_utf8(output.stdout).unwrap() } pub fn down(&self, remove_orphans: bool, volumes: bool) { let mut opts = vec!["down"]; if remove_orphans { opts.push("--remove-orphans"); } if volumes { opts.push("--volumes"); } Command::new("docker-compose") .current_dir(&self.base_dir) .args(opts) .spawn() .expect(&format!("unable to remove")); } }