Skip to content
This repository has been archived by the owner on Jun 7, 2024. It is now read-only.

Commit

Permalink
Add purge task to clean leftover docker entities
Browse files Browse the repository at this point in the history
  • Loading branch information
pvdrz committed May 28, 2024
1 parent 568c75e commit 45980a2
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[alias]
purge = "run --package purge --"
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions packages/purge/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "purge"
version = "0.1.0"
edition = "2021"

[dependencies]
94 changes: 94 additions & 0 deletions packages/purge/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
use std::{
error::Error,
io::{self, Write},
process::{exit, Command, Output},
};

fn main() {
if let Err(err) = run() {
eprintln!("{err}");
exit(1)
}
}

fn run() -> io::Result<()> {
let args: Vec<_> = std::env::args().skip(1).collect();

let mut clean_network = false;
let mut clean_container = false;

match args.first().map(String::as_str) {
Some("network") => {
clean_network = true;
}
Some("container") => {
clean_container = true;
}
None => {
clean_network = true;
clean_container = true;
}
Some(unexpected) => {
return Err(io_error(format!("Unexpected argument `{unexpected}`")));
}
}

if clean_container {
let hashes = filter_command_output(Command::new("docker").arg("ps"))?;

if hashes.is_empty() {
println!("No containers to be removed");
} else {
let output = run_command(Command::new("docker").args(["rm", "-f"]).args(hashes))?;

println!("Removed containers:");
io::stdout().write_all(&output.stdout)?;
}
}

if clean_network {
let hashes = filter_command_output(Command::new("docker").args(["network", "ls"]))?;

if hashes.is_empty() {
println!("No networks to be removed");
} else {
let output = run_command(Command::new("docker").args(["network", "rm"]).args(hashes))?;

println!("Removed networks:");
io::stdout().write_all(&output.stdout)?;
}
}

Ok(())
}

fn run_command(command: &mut Command) -> io::Result<Output> {
let output = command.output()?;

if !output.status.success() {
return Err(io_error(format!(
"command {:?} exited with status-code {:?}, stderr:\n{}",
command.get_program(),
output.status,
String::from_utf8_lossy(&output.stderr),
)));
}

Ok(output)
}

fn filter_command_output(command: &mut Command) -> io::Result<Vec<String>> {
String::from_utf8(run_command(command)?.stdout)
.map_err(io_error)
.map(|stdout| {
stdout
.lines()
.filter(|&line| line.contains("dns-test"))
.map(|line| line[..12].to_owned())
.collect()
})
}

fn io_error(msg: impl Into<Box<dyn Error + Sync + Send + 'static>>) -> io::Error {
io::Error::new(io::ErrorKind::Other, msg.into())
}

0 comments on commit 45980a2

Please sign in to comment.