use super::{docker_compose, DockerCommand}; use anyhow::{Context, Result}; use std::{ fs::File, path::{Path, PathBuf}, process::Stdio, }; fn get_containers() -> Result<[String; 2]> { // get db container // FIX: we assume we are running db in service named "postgresbd" let db_container = DockerCommand::docker_compose() .args("ps -q postgresdb") .stdout()? .trim() .to_string(); // get all containers and filter out db container let app_containers = DockerCommand::docker_compose() .args("ps -q") .stdout()? .split_whitespace() .filter(|x| x != &db_container) .collect::>() .join(" "); Ok([db_container, app_containers]) } pub fn import(file: &Path) -> Result<()> { let [db_container, app_containers] = get_containers()?; let dump_file = file.to_string_lossy(); println!("stopping all containers"); docker_compose::stop()?; println!("starting db container"); docker_compose::start(Some(&db_container))?; println!("restoring database"); let commands = [ format!("cp {dump_file} {db_container}:/tmp/dbdump"), format!("exec {db_container} dropdb -U db db"), format!("exec {db_container} createdb -U db -E utf8 -T template0 db"), format!("exec {db_container} pg_restore -U db --dbname=db /tmp/dbdump"), ]; for command in commands { DockerCommand::docker().args(&command).spawn_wait()?; } println!("restarting containers"); docker_compose::stop()?; docker_compose::up()?; Ok(()) } pub fn dump(file: &PathBuf) -> Result<()> { let [db_container, _] = get_containers()?; println!("dumping to local file {}", file.to_string_lossy()); let file = File::create(file)?; let stdout = Stdio::from(file); let command = format!("exec {db_container} pg_dump -U db --format=c db"); DockerCommand::docker() .args(&command) .write_stdout(stdout)?; Ok(()) }