96 lines
2.6 KiB
Rust
96 lines
2.6 KiB
Rust
use anyhow::{anyhow, Context, Result};
|
|
use std::{
|
|
fs::File,
|
|
path::{Path, PathBuf},
|
|
process::Stdio,
|
|
thread,
|
|
time::Duration,
|
|
};
|
|
|
|
use super::docker_compose;
|
|
use crate::{command_builder::CommandBuilder, debug_eprintln};
|
|
|
|
fn get_containers(container: &str) -> Result<[String; 2]> {
|
|
// get db container
|
|
let db_container = CommandBuilder::docker_compose()
|
|
.args("ps -q")
|
|
.args(container)
|
|
.exec_get_stdout()?
|
|
.trim()
|
|
.to_string();
|
|
|
|
let no_result = db_container.is_empty();
|
|
if no_result {
|
|
return Err(anyhow!("no container"));
|
|
}
|
|
|
|
// get all containers and filter out db container
|
|
let app_containers = CommandBuilder::docker_compose()
|
|
.args("ps -q")
|
|
.exec_get_stdout()?
|
|
.split_whitespace()
|
|
.filter(|x| x != &db_container)
|
|
.collect::<Vec<&str>>()
|
|
.join(" ");
|
|
|
|
Ok([db_container, app_containers])
|
|
}
|
|
|
|
pub fn import(container: &str, file: &Path) -> Result<()> {
|
|
let [db_container, app_containers] = get_containers(container)?;
|
|
let dump_file = file.to_string_lossy();
|
|
|
|
eprintln!("stopping all containers");
|
|
docker_compose::stop()?;
|
|
|
|
eprintln!("starting db container");
|
|
docker_compose::start(Some(container))?;
|
|
|
|
eprintln!("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 {
|
|
debug_eprintln!("waiting until pg_isready");
|
|
while !CommandBuilder::docker()
|
|
.args(&format!(
|
|
"exec {db_container} pg_isready -h {container} -p 5432 -U db",
|
|
))
|
|
.build()?
|
|
.stdout(Stdio::null())
|
|
.spawn()?
|
|
.wait()?
|
|
.success()
|
|
{
|
|
thread::sleep(Duration::from_secs(1));
|
|
}
|
|
CommandBuilder::docker().args(&command).exec()?;
|
|
}
|
|
|
|
eprintln!("restarting containers");
|
|
docker_compose::stop()?;
|
|
docker_compose::up()?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn dump(container: &str, file: &PathBuf) -> Result<()> {
|
|
let [db_container, _] = get_containers(container)?;
|
|
|
|
eprintln!("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");
|
|
CommandBuilder::docker()
|
|
.args(&command)
|
|
.exec_redirect_stdout(stdout)?;
|
|
|
|
Ok(())
|
|
}
|