use super::DockerError;
const MAX_COLLISION_ATTEMPTS: u32 = 64;
pub fn old_name_for(original: &str, ts_unix: i64) -> String {
format!("{original}-old-{ts_unix}")
}
pub fn next_available_old_name(
original: &str,
ts_unix: i64,
exists: impl Fn(&str) -> bool,
) -> String {
let base = old_name_for(original, ts_unix);
if !exists(&base) {
return base;
}
for n in 1..=MAX_COLLISION_ATTEMPTS {
let candidate = format!("{base}-{n}");
if !exists(&candidate) {
return candidate;
}
}
format!("{base}-{MAX_COLLISION_ATTEMPTS}")
}
impl super::Docker {
pub async fn rename_to_old(&self, original: &str, ts_unix: i64) -> Result<String, DockerError> {
let new_name = {
let docker = self.0.clone();
next_available_old_name_async(original, ts_unix, |candidate| {
let docker = docker.clone();
let candidate = candidate.to_owned();
async move { docker.inspect_container(&candidate, None).await.is_ok() }
})
.await
};
let opts = bollard::query_parameters::RenameContainerOptionsBuilder::new()
.name(&new_name)
.build();
self.0.rename_container(original, opts).await?;
Ok(new_name)
}
}
async fn next_available_old_name_async<F, Fut>(original: &str, ts_unix: i64, exists: F) -> String
where
F: Fn(&str) -> Fut,
Fut: std::future::Future<Output = bool>,
{
let base = old_name_for(original, ts_unix);
if !exists(&base).await {
return base;
}
for n in 1..=MAX_COLLISION_ATTEMPTS {
let candidate = format!("{base}-{n}");
if !exists(&candidate).await {
return candidate;
}
}
format!("{base}-{MAX_COLLISION_ATTEMPTS}")
}