Skip to content

Commit b6935e3

Browse files
committed
gc: merge container-prune into cloud-prune
Merged the code of the container gc into the cloud one, and update builds.json. Go through the tags in base-oscontainer data in meta.json and prune every tag except the stream-name itself which are moving tags.
1 parent 48fba72 commit b6935e3

File tree

3 files changed

+72
-128
lines changed

3 files changed

+72
-128
lines changed

cmd/coreos-assembler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ var buildCommands = []string{"init", "fetch", "build", "run", "prune", "clean",
1616
var advancedBuildCommands = []string{"buildfetch", "buildupload", "oc-adm-release", "push-container"}
1717
var buildextendCommands = []string{"aliyun", "applehv", "aws", "azure", "digitalocean", "exoscale", "extensions-container", "gcp", "hashlist-experimental", "hyperv", "ibmcloud", "kubevirt", "live", "metal", "metal4k", "nutanix", "openstack", "qemu", "secex", "virtualbox", "vmware", "vultr"}
1818

19-
var utilityCommands = []string{"aws-replicate", "cloud-prune", "compress", "container-prune", "copy-container", "koji-upload", "kola", "push-container-manifest", "remote-build-container", "remote-session", "sign", "tag", "update-variant"}
19+
var utilityCommands = []string{"aws-replicate", "cloud-prune", "compress", "copy-container", "koji-upload", "kola", "push-container-manifest", "remote-build-container", "remote-session", "sign", "tag", "update-variant"}
2020
var otherCommands = []string{"shell", "meta"}
2121

2222
func init() {

src/cmd-cloud-prune

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@
3434

3535
import argparse
3636
import json
37+
import subprocess
3738
from urllib.parse import urlparse
3839
import pytz
40+
import requests
3941
import yaml
4042
import collections
4143
import datetime
@@ -59,7 +61,8 @@ CACHE_MAX_AGE_METADATA = 60 * 5
5961
# is up to date.
6062
SUPPORTED = ["amis", "gcp"]
6163
UNSUPPORTED = ["aliyun", "azure", "ibmcloud", "powervs"]
62-
64+
# list of known streams with containers
65+
STREAMS = {"next", "testing", "stable", "next-devel", "testing-devel", "rawhide", "branched"}
6366

6467
def parse_args():
6568
parser = argparse.ArgumentParser(prog="coreos-assembler cloud-prune")
@@ -70,6 +73,9 @@ def parse_args():
7073
parser.add_argument("--gcp-json-key", help="GCP Service Account JSON Auth", default=os.environ.get("GCP_JSON_AUTH"))
7174
parser.add_argument("--acl", help="ACL for objects", action='store', default='private')
7275
parser.add_argument("--aws-config-file", default=os.environ.get("AWS_CONFIG_FILE"), help="Path to AWS config file")
76+
parser.add_argument("--repository-url", help="container images URL")
77+
parser.add_argument("--registry-auth-file", default=os.environ.get("REGISTRY_AUTH_FILE"),
78+
help="Path to docker registry auth file. Directly passed to skopeo.")
7379
return parser.parse_args()
7480

7581

@@ -125,7 +131,7 @@ def main():
125131
current_build = Build(id=build_id, images=images, arch=arch, meta_json=meta_json)
126132

127133
# Iterate over actions (policy types) to apply pruning
128-
for action in ['cloud-uploads', 'images', 'build']:
134+
for action in ['cloud-uploads', 'images', 'build', 'containers']:
129135
if action not in policy[stream]:
130136
continue
131137
action_duration = convert_duration_to_days(policy[stream][action])
@@ -162,6 +168,19 @@ def main():
162168
case "build":
163169
prune_build(s3_client, bucket, prefix, build_id, args.dry_run)
164170
pruned_build_ids.append(build_id)
171+
case "containers":
172+
container_tags = get_container_tags(meta_json, stream)
173+
if container_tags:
174+
containers_config = {
175+
"container_tags": container_tags,
176+
"dry_run" : args.dry_run,
177+
"repository_url": args.repository_url,
178+
"registry_auth_file": args.registry_auth_file,
179+
"stream": stream
180+
}
181+
prune_containers(containers_config)
182+
else:
183+
print(f"No container tags to prune for build {build_id} on architecture {arch}.")
165184

166185
# Update policy-cleanup after pruning actions for the architecture
167186
policy_cleanup = build.setdefault("policy-cleanup", {})
@@ -174,6 +193,9 @@ def main():
174193
if "images" not in policy_cleanup:
175194
policy_cleanup["images"] = True
176195
policy_cleanup["images-kept"] = images_to_keep
196+
case "containers":
197+
if "containers" not in policy_cleanup:
198+
policy_cleanup["containers"] = True
177199

178200
if pruned_build_ids:
179201
if "tombstone-builds" not in builds_json_data:
@@ -414,5 +436,52 @@ def prune_build(s3_client, bucket, prefix, build_id, dry_run):
414436
raise Exception(f"Error pruning {build_id}: {e.response['Error']['Message']}")
415437

416438

439+
def get_container_tags(meta_json, stream):
440+
container_tags = []
441+
base_oscontainer = meta_json.get("base-oscontainer")
442+
if base_oscontainer:
443+
tags = base_oscontainer.get("tags", [])
444+
# Only include tags that do not match the stream i.e. moving tags
445+
filtered_tags = [tag for tag in tags if tag != stream]
446+
if filtered_tags:
447+
container_tags = filtered_tags
448+
return container_tags
449+
450+
451+
def prune_containers(containers_config):
452+
barrier_releases = set()
453+
# Get the update graph for stable streams
454+
if containers_config.stream in ['stable', 'testing', 'next']:
455+
update_graph = get_update_graph(containers_config.stream)['releases']
456+
# Keep only the barrier releases
457+
barrier_releases = set([release["version"] for release in update_graph if "barrier" in release])
458+
459+
for tag in containers_config.container_tags:
460+
if tag in STREAMS:
461+
continue
462+
if tag in barrier_releases:
463+
print(f"Release {tag} is a barrier release, keeping.")
464+
continue
465+
if containers_config.dry_run:
466+
print(f"Would prune image {containers_config.repository_url}:{tag}")
467+
else:
468+
skopeo_delete(containers_config.repository_url, tag, containers_config.registry_auth_file)
469+
470+
471+
def get_update_graph(stream):
472+
url = f"https://builds.coreos.fedoraproject.org/updates/{stream}.json"
473+
r = requests.get(url, timeout=5)
474+
if r.status_code != 200:
475+
raise Exception(f"Could not download update graph for {stream}. HTTP {r.status_code}")
476+
return r.json()
477+
478+
479+
def skopeo_delete(repo, image, auth):
480+
skopeo_args = ["skopeo", "delete", f"docker://{repo}:{image}"]
481+
if auth is not None:
482+
skopeo_args.append(f"--authfile {auth}")
483+
subprocess.check_output(skopeo_args)
484+
485+
417486
if __name__ == "__main__":
418487
main()

src/cmd-container-prune

Lines changed: 0 additions & 125 deletions
This file was deleted.

0 commit comments

Comments
 (0)