Skip to content

Commit 5642b2c

Browse files
committed
wip: Move digest fetching into package version filtering
1 parent d0ff4c5 commit 5642b2c

File tree

4 files changed

+119
-35
lines changed

4 files changed

+119
-35
lines changed

src/client/builder.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use tracing::debug;
1313
use crate::cli::models::{Account, Token};
1414
use crate::client::client::PackagesClient;
1515
use crate::client::urls::Urls;
16-
use base64::prelude::*;
1716
pub type RateLimitedService = Arc<Mutex<ConcurrencyLimit<RateLimit<Client>>>>;
1817

1918
#[derive(Debug)]

src/client/client.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use chrono::{DateTime, Utc};
66
use color_eyre::eyre::{eyre, Result};
77
use reqwest::header::HeaderMap;
88
use reqwest::{Client, Method, Request, StatusCode};
9-
use serde_json::Value;
109
use tokio::time::sleep;
1110
use tower::{Service, ServiceExt};
1211
use tracing::{debug, error, info, Span};
@@ -481,7 +480,11 @@ impl PackagesClient {
481480
))
482481
}
483482

484-
pub async fn fetch_image_manifest(&self, tag: &str) -> Result<Vec<String>> {
483+
pub async fn fetch_image_manifest(
484+
&self,
485+
package_name: String,
486+
tag: String,
487+
) -> Result<(String, String, Vec<String>)> {
485488
debug!(tag = tag, "Retrieving image manifest");
486489

487490
let url = format!("https://ghcr.io/v2/snok%2Fcontainer-retention-policy/manifests/{tag}");
@@ -494,16 +497,21 @@ impl PackagesClient {
494497
Ok(t) => t,
495498
Err(e) => {
496499
println!("{}", raw_json);
497-
return Ok(vec![]);
500+
return Err(eyre!(
501+
"Failed to fetch image manifest for \x1b[34m{package_name}\x1b[0m:\x1b[32m{tag}\x1b[0m: {e}"
502+
));
498503
}
499504
};
500505

501-
Ok(resp
502-
.manifests
503-
.unwrap_or(vec![])
504-
.iter()
505-
.map(|manifest| manifest.digest.to_string())
506-
.collect())
506+
Ok((
507+
package_name,
508+
tag,
509+
resp.manifests
510+
.unwrap_or(vec![])
511+
.iter()
512+
.map(|manifest| manifest.digest.to_string())
513+
.collect(),
514+
))
507515
}
508516
}
509517

src/core/select_package_versions.rs

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use chrono::Utc;
88
use color_eyre::Result;
99
use humantime::Duration as HumantimeDuration;
1010
use indicatif::ProgressStyle;
11-
use std::collections::HashMap;
11+
use std::collections::{HashMap, HashSet};
1212
use std::sync::Arc;
1313
use std::time::Duration;
1414
use tokio::task::JoinSet;
@@ -287,16 +287,104 @@ pub async fn select_package_versions(
287287
);
288288
}
289289

290-
let mut package_version_map = HashMap::new();
290+
let mut all_package_versions = vec![];
291+
let mut fetch_digest_set = JoinSet::new();
291292

292293
debug!("Fetching package versions");
294+
293295
while let Some(r) = set.join_next().await {
294296
// Get all the package versions for a package
295297
let (package_name, mut package_versions) = r??;
296298

299+
// Queue fetching of digests for each tag
300+
for package_version in &package_versions.tagged {
301+
for tag in &package_version.metadata.container.tags {
302+
fetch_digest_set.spawn(client.fetch_image_manifest(package_name.clone(), tag.clone()));
303+
}
304+
}
305+
306+
all_package_versions.push((package_name, package_versions));
307+
}
308+
309+
debug!("Fetching package versions");
310+
let mut digests = HashSet::new();
311+
let mut digest_tag = HashMap::new();
312+
313+
while let Some(r) = fetch_digest_set.join_next().await {
314+
// Get all the digests for the package
315+
let (package_name, tag, package_digests) = r??;
316+
317+
if package_digests.is_empty() {
318+
debug!(
319+
package_name = package_name,
320+
"Found {} associated digests for \x1b[34m{package_name}\x1b[0m:\x1b[32m{tag}\x1b[0m",
321+
package_digests.len()
322+
);
323+
} else {
324+
info!(
325+
package_name = package_name,
326+
"Found {} associated digests for \x1b[34m{package_name}\x1b[0m:\x1b[32m{tag}\x1b[0m",
327+
package_digests.len()
328+
);
329+
}
330+
331+
digests.extend(package_digests.clone());
332+
for digest in package_digests.into_iter() {
333+
digest_tag.insert(digest, format!("\x1b[34m{package_name}\x1b[0m:\x1b[32m{tag}\x1b[0m"));
334+
}
335+
}
336+
337+
let mut package_version_map = HashMap::new();
338+
339+
for (package_name, mut package_versions) in all_package_versions {
340+
package_versions.untagged = package_versions
341+
.untagged
342+
.into_iter()
343+
.filter_map(|package_version| {
344+
if digests.contains(&package_version.name) {
345+
let x: String = package_version.name.clone();
346+
let association: &String = digest_tag.get(&x as &str).unwrap();
347+
debug!(
348+
"Skipping deletion of {} because it's associated with {association}",
349+
package_version.name
350+
);
351+
None
352+
} else {
353+
Some(package_version)
354+
}
355+
})
356+
.collect();
357+
let count_before = package_versions.tagged.len();
358+
package_versions.tagged = package_versions
359+
.tagged
360+
.into_iter()
361+
.filter(|package_version| {
362+
if digests.contains(&package_version.name) {
363+
let association = digest_tag.get(&*(package_version.name)).unwrap();
364+
debug!(
365+
"Skipping deletion of {} because it's associated with {association}",
366+
package_version.name
367+
);
368+
false
369+
} else {
370+
true
371+
}
372+
})
373+
.collect();
374+
375+
let adjusted_keep_n_most_recent =
376+
if keep_n_most_recent as i64 - (count_before as i64 - package_versions.tagged.len() as i64) < 0 {
377+
0
378+
} else {
379+
keep_n_most_recent as i64 - (count_before as i64 - package_versions.tagged.len() as i64)
380+
};
381+
297382
// Keep n package versions per package, if specified
298-
package_versions.tagged =
299-
handle_keep_n_most_recent(package_versions.tagged, keep_n_most_recent, timestamp_to_use);
383+
package_versions.tagged = handle_keep_n_most_recent(
384+
package_versions.tagged,
385+
adjusted_keep_n_most_recent as u32,
386+
timestamp_to_use,
387+
);
300388

301389
info!(
302390
package_name = package_name,

src/main.rs

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::sync::Arc;
44

55
use color_eyre::eyre::Result;
66
use tokio::sync::RwLock;
7-
use tracing::{debug, error, info, info_span, trace, Instrument};
7+
use tracing::{debug, error, info_span, trace, Instrument};
88
use tracing_indicatif::IndicatifLayer;
99
use tracing_subscriber::layer::SubscriberExt;
1010
use tracing_subscriber::util::SubscriberInitExt;
@@ -143,27 +143,16 @@ async fn main() -> Result<()> {
143143
*counts.remaining_requests.read().await
144144
);
145145

146-
for (package, package_versions) in package_version_map.iter() {
147-
info!("Print package {package}");
148-
for package_version in &package_versions.tagged {
149-
for tag in &package_version.metadata.container.tags {
150-
info!("Print tag {tag}");
151-
let digests = client.fetch_image_manifest(tag).await.unwrap();
146+
let (deleted_packages, failed_packages) =
147+
delete_package_versions(package_version_map, client, counts.clone(), input.dry_run)
148+
.instrument(info_span!("deleting package versions"))
149+
.await;
152150

153-
println!("digests: {digests:?}");
154-
}
155-
}
156-
}
157-
// let (deleted_packages, failed_packages) =
158-
// delete_package_versions(package_version_map, client, counts.clone(), input.dry_run)
159-
// .instrument(info_span!("deleting package versions"))
160-
// .await;
161-
//
162-
// let mut github_output = env::var("GITHUB_OUTPUT").unwrap_or_default();
163-
//
164-
// github_output.push_str(&format!("deleted={}", deleted_packages.join(",")));
165-
// github_output.push_str(&format!("failed={}", failed_packages.join(",")));
166-
// env::set_var("GITHUB_OUTPUT", github_output);
151+
let mut github_output = env::var("GITHUB_OUTPUT").unwrap_or_default();
152+
153+
github_output.push_str(&format!("deleted={}", deleted_packages.join(",")));
154+
github_output.push_str(&format!("failed={}", failed_packages.join(",")));
155+
env::set_var("GITHUB_OUTPUT", github_output);
167156

168157
Ok(())
169158
}

0 commit comments

Comments
 (0)