Skip to content

Commit 3522faf

Browse files
committed
Added cleanup routines / Cosign update
1 parent c1e576d commit 3522faf

File tree

2 files changed

+109
-15
lines changed

2 files changed

+109
-15
lines changed

tools/monitor-oci-artifacts/Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ ARG RELEASE="1"
88
# Update image
99
RUN microdnf install -y yum \
1010
&& yum -y update-minimal --security --sec-severity=Important --sec-severity=Critical \
11-
&& curl -L -O https://github.com/sigstore/cosign/releases/download/v2.1.1/cosign-2.1.1.x86_64.rpm \
12-
&& rpm -ivh cosign-2.1.1.x86_64.rpm \
11+
&& curl -L -O https://github.com/sigstore/cosign/releases/download/v2.2.3/cosign-2.2.3-1.x86_64.rpm \
12+
&& rpm -ivh cosign-2.2.3-1.x86_64.rpm \
1313
&& yum clean all \
1414
&& microdnf clean all
1515

tools/monitor-oci-artifacts/src/main.rs

Lines changed: 107 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,24 @@ impl std::ops::Deref for TagList {
4343
}
4444
}
4545

46+
#[derive(Deserialize, Debug)]
47+
struct ArtifactReference {
48+
child_digest: String,
49+
}
4650
#[derive(Deserialize, Debug)]
4751
struct Artifact {
4852
digest: String,
4953
manifest_media_type: String,
5054
media_type: String,
5155
tags: Option<TagList>,
56+
references: Option<Vec<ArtifactReference>>,
5257
}
5358

5459
#[tokio::main]
5560
async fn main() -> Result<(), Box<dyn std::error::Error>> {
5661
let registry_hostname = "oci.stackable.tech";
5762
let base_url = format!("https://{}/api/v2.0", registry_hostname);
58-
let page_size = 10;
63+
let page_size = 20;
5964
let mut page = 1;
6065
let attestation_tag_regex = Regex::new(r"^sha256-[0-9a-f]{64}.att$").unwrap();
6166

@@ -70,18 +75,38 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
7075

7176
for repository in &repositories {
7277
let (project_name, repository_name) = repository.name.split_once('/').unwrap();
73-
if project_name == "sandbox" {
78+
if project_name == "sandbox"
79+
&& (repository_name != "git-sync" && repository_name != "ubi8-rust-builder")
80+
{
7481
continue;
7582
}
76-
let artifacts: Vec<Artifact> = reqwest::get(format!(
77-
"{}/projects/{}/repositories/{}/artifacts",
78-
base_url,
79-
encode(project_name),
80-
encode(repository_name)
81-
))
82-
.await?
83-
.json()
84-
.await?;
83+
84+
let mut attestations: Vec<String> = Vec::with_capacity(32);
85+
let mut potentially_attested_artifacts: Vec<&str> = Vec::with_capacity(32);
86+
let mut artifacts: Vec<Artifact> = Vec::with_capacity(64);
87+
let mut page = 1;
88+
let page_size = 20;
89+
loop {
90+
let artifacts_page: Vec<Artifact> = reqwest::get(format!(
91+
"{}/projects/{}/repositories/{}/artifacts?page_size={}&page={}",
92+
base_url,
93+
encode(project_name),
94+
encode(repository_name),
95+
page_size,
96+
page
97+
))
98+
.await?
99+
.json()
100+
.await?;
101+
102+
let number_of_returned_artifacts = artifacts_page.len();
103+
artifacts.extend(artifacts_page);
104+
if number_of_returned_artifacts < page_size {
105+
break;
106+
}
107+
page += 1;
108+
}
109+
85110
for artifact in &artifacts {
86111
if artifact
87112
.tags
@@ -99,15 +124,20 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
99124
{
100125
// it's an attestation, attestations artifacts themselves are not signed
101126
println!(
102-
"skipping attestation {}{} ({})",
127+
"skipping attestation {} {} ({})",
103128
repository_name,
104129
artifact.digest,
105130
artifact.tags.as_ref().unwrap()
106131
);
132+
attestations.push(artifact.tags.as_ref().unwrap()[0].name.clone());
107133
continue;
134+
} else {
135+
potentially_attested_artifacts.push(&artifact.digest[7..71]);
108136
}
109137

110-
if project_name == "sdp" && (repository_name != "git-sync" && repository_name != "ubi8-rust-builder") {
138+
if project_name == "sdp"
139+
&& (repository_name != "git-sync" && repository_name != "ubi8-rust-builder")
140+
{
111141
if artifact.manifest_media_type
112142
!= "application/vnd.docker.distribution.manifest.v2+json"
113143
{
@@ -159,6 +189,24 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
159189
exit(cmd_output.status.code().unwrap_or(1));
160190
}
161191
}
192+
193+
// remove dangling attestations
194+
for attestation in attestations {
195+
if !potentially_attested_artifacts.contains(&&attestation[7..71]) {
196+
println!("removing dangling attestation {}", attestation);
197+
reqwest::Client::new()
198+
.delete(format!(
199+
"{}/projects/{}/repositories/{}/artifacts/{}",
200+
base_url,
201+
encode(project_name),
202+
encode(repository_name),
203+
attestation
204+
))
205+
.basic_auth("robot$stackable-cleanup", Some("XX"))
206+
.send()
207+
.await?;
208+
}
209+
}
162210
}
163211

164212
if repositories.len() < page_size {
@@ -168,5 +216,51 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
168216
page += 1;
169217
}
170218

219+
let latest_rust_builder_artifact: Artifact = reqwest::Client::new()
220+
.get(format!(
221+
"{}/projects/sdp/repositories/ubi8-rust-builder/artifacts/latest",
222+
base_url,
223+
))
224+
.send()
225+
.await?
226+
.json()
227+
.await?;
228+
229+
let referenced_digests = latest_rust_builder_artifact
230+
.references
231+
.unwrap()
232+
.into_iter()
233+
.map(|reference| reference.child_digest)
234+
.collect::<Vec<String>>();
235+
236+
let rust_builder_artifacts: Vec<Artifact> = reqwest::get(format!(
237+
"{}/projects/sdp/repositories/ubi8-rust-builder/artifacts?page_size=100",
238+
base_url
239+
))
240+
.await?
241+
.json()
242+
.await?;
243+
244+
// keep "latest" and its referenced artifacts
245+
for artifact in rust_builder_artifacts {
246+
if artifact.digest != latest_rust_builder_artifact.digest
247+
&& !referenced_digests.contains(&artifact.digest)
248+
{
249+
println!(
250+
"removing dangling rust builder artifact {}",
251+
artifact.digest
252+
);
253+
reqwest::Client::new()
254+
.delete(format!(
255+
"{}/projects/sdp/repositories/ubi8-rust-builder/artifacts/{}",
256+
base_url, artifact.digest
257+
))
258+
.basic_auth("robot$stackable-cleanup", Some("XX"))
259+
.send()
260+
.await?;
261+
}
262+
}
263+
171264
Ok(())
172265
}
266+
// cachebust

0 commit comments

Comments
 (0)