registry-cleaner/src/main.rs

170 lines
3.7 KiB
Rust

#[allow(dead_code)]
extern crate args;
extern crate getopts;
use args::{Args, ArgsError};
// use args::validations::{Order,OrderValidation};
use getopts::Occur;
use tokio::runtime::Runtime;
mod api;
#[allow(unused)]
struct Opts {
registry: String,
image: String,
exclude: Vec<String>,
keep: i32,
}
fn main() {
let mut rt = Runtime::new().unwrap();
let input_args = std::env::args().collect::<Vec<String>>();
let _parsed = parse(&input_args).unwrap();
rt.block_on(async {
let registry = api::registry::Registry {
url: _parsed.registry.as_str(),
};
let res = registry.get_repositories().await.unwrap();
if res.repositories.len() == 0 {
return;
}
// println!("response :::: {:?}", res);
let mut proc_images: Vec<String> = Vec::new();
if _parsed.image.len() > 0 {
if !res.repositories.contains(&_parsed.image) {
eprintln!("image not in registry");
std::process::exit(1);
}
proc_images.push(_parsed.image);
} else {
proc_images = res.repositories.to_owned();
}
// println!("proc images ::: {:?}", proc_images);
for img in proc_images.into_iter() {
println!("ProcImage: {}", img);
let _repo_tags = registry.get_repository_tags(img.as_str()).await.unwrap();
let mut tags: Vec<api::registry::RepositoryTagManifest> = Vec::new();
match _repo_tags.tags {
Some(s) => {
for x in s.iter() {
if _parsed.exclude.contains(x) {
continue;
}
let manifests = registry.get_repository_tag_manifest(img.as_str(), x).await;
match manifests {
Err(_) => continue,
Ok(v) => tags.push(v),
};
}
}
_ => continue,
};
tags.sort_by(|a, b| b.ts.partial_cmp(&a.ts).unwrap());
// println!("{:?}", tags);
let del_count: usize = if tags.len() > _parsed.keep as usize {
_parsed.keep as usize
} else {
tags.len()
};
tags.drain(0..del_count);
println!("delete tag number : {}", tags.len());
for x in tags.iter() {
if x.digest.len() == 0 {
continue;
}
match registry
.delete_repository_tag(img.as_str(), x.digest.as_str())
.await
{
Ok(_) => println!("delete {} success", x.tag),
Err(_) => println!("delete {} fail", x.tag),
};
}
}
});
}
fn parse(input: &Vec<String>) -> Result<Opts, ArgsError> {
let mut arg = Args::new("Registry Cleaner", "clean registry images");
arg.flag("h", "help", "print usage");
arg.option(
"i",
"image",
"image name empty is all",
"IMAGE",
Occur::Optional,
Some(String::from("")),
);
arg.option(
"e",
"exclude",
"exclude tag no delete",
"EXCLUDE",
Occur::Optional,
None,
);
arg.option(
"r",
"registry",
"registry url",
"REGISTRY",
Occur::Optional,
None,
);
arg.option(
"k",
"keep",
"keep tags number",
"KEEP",
Occur::Optional,
None,
);
arg.parse(input).unwrap();
let help: bool = arg.value_of("help").unwrap();
if help {
let str = arg.full_usage();
eprintln!("{}", str);
std::process::exit(1);
}
let exclude: Vec<String> = match arg.values_of("exclude") {
Ok(strs) => strs,
Err(_) => vec![],
};
let image: String = match arg.value_of("image") {
Ok(v) => v,
Err(_) => String::from(""),
};
let url: String = arg.value_of("registry").unwrap();
let keep: i32 = match arg.value_of("keep") {
Ok(v) => v,
Err(_) => 10,
};
let opts = Opts {
image: image.clone(),
exclude: exclude.clone(),
registry: url,
keep,
};
Ok(opts)
}