Skip to content

Commit

Permalink
createrepo. Limit the number of versions
Browse files Browse the repository at this point in the history
Repository can have hundreds of image tags, limit them to the bare
minimum:

- at most one stable tag
- if a testing tag is available, consider it only if greater than the
  stable tag

Also

- Bump to Python 3.11
- Package imghdr deprecation
- Produce more output
  • Loading branch information
DavidePrincipi committed Apr 17, 2024
1 parent 2e79a32 commit ee035a6
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 30 deletions.
87 changes: 63 additions & 24 deletions createrepo.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,19 @@
import sys
import copy
import json
import imghdr
import filetype
import semver
import subprocess
import glob
import urllib.request

def is_pngfile(file_path):
kind = filetype.guess(file_path)
if kind is None:
return False

return kind.extension == 'png'

path = '.'
index = []
defaults = {
Expand Down Expand Up @@ -104,39 +111,71 @@
except:
pass

if os.path.isfile(logo) and imghdr.what(logo) == "png":
if os.path.isfile(logo) and is_pngfile(logo):
metadata["logo"] = "logo.png"

# add screenshots if pngs are available inside the screenshots directory
screenshot_dirs = os.path.join(entry_name, "screenshots")
if os.path.isdir(screenshot_dirs):
with os.scandir(screenshot_dirs) as sdir:
for screenshot in sdir:
if imghdr.what(screenshot) == "png":
if is_pngfile(screenshot.path):
metadata["screenshots"].append(os.path.join("screenshots",screenshot.name))

print("Inspect " + metadata["source"])
print("Inspect " + metadata["source"], file=sys.stderr)
metadata["versions"] = []
# Parse the image info from remote registry to retrieve tags
with subprocess.Popen(["skopeo", "inspect", f'docker://{metadata["source"]}'], stdout=subprocess.PIPE, stderr=sys.stderr) as proc:
info = json.load(proc.stdout)
metadata["versions"] = []
versions = []
for tag in info["RepoTags"]:
try:
versions.append(semver.VersionInfo.parse(tag))
# Retrieve labels for each valid version
p = subprocess.Popen(["skopeo", "inspect", f'docker://{metadata["source"]}:{tag}'], stdout=subprocess.PIPE, stderr=sys.stderr)
info_tags = json.load(p.stdout)
version_labels[tag] = info_tags['Labels']
except:
# skip invalid semantic versions
pass

# Sort by most recent
for v in sorted(versions, reverse=True):
metadata["versions"].append({"tag": f"{v}", "testing": (not v.prerelease is None), "labels": version_labels[f"{v}"]})

index.append(metadata)
try:
with subprocess.Popen(["skopeo", "inspect", 'docker://' + metadata["source"]], stdout=subprocess.PIPE, stderr=sys.stderr) as proc:
repo_inspect = json.load(proc.stdout)

# Filter out non-semver tags and reverse-sort remaining tags from
# younger to older:
semver_tags = list(sorted(filter(semver.VersionInfo.is_valid, repo_inspect["RepoTags"]),
key=semver.parse_version_info,
reverse=True,
))

except Exception as ex:
print(f'[ERROR] cannot inspect {metadata["source"]}', ex, file=sys.stderr)
continue

testing_found = False # record if a testing release was found
for tag in semver_tags:
semver_tag = semver.parse_version_info(tag)

if testing_found and semver_tag.prerelease is not None:
# skip older testing releases, we do not need them
continue

try:
# Fetch the image labels
with subprocess.Popen(["skopeo", "inspect", f'docker://{metadata["source"]}:{tag}'], stdout=subprocess.PIPE, stderr=sys.stderr) as proc:
image_inspect = json.load(proc.stdout)
image_labels = image_inspect['Labels']
except Exception as ex:
print(f'[ERROR] cannot inspect {metadata["source"]}:{tag}', ex, file=sys.stderr)
continue

image_version = {
"tag": tag,
"testing": semver_tag.prerelease is not None,
"labels": image_labels,
}
print("* Add version", tag)
metadata["versions"].append(image_version)

if semver_tag.prerelease is None:
# Only the last stable tag is actually needed: stop here
break
else:
testing_found = True


if metadata["versions"]:
index.append(metadata)
else:
print("[ERROR] no versions found for", metadata["source"], file=sys.stderr)

with open (os.path.join(path, 'repodata.json'), 'w') as outfile:
json.dump(index, outfile, separators=(',', ':'))
10 changes: 4 additions & 6 deletions createrepo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,12 @@ set -e

if ! buildah containers --format "{{.ContainerName}}" | grep -q repomd-builder; then
echo "Pulling Python runtime and Skopeo..."
buildah from --name repomd-builder -v "${PWD}:/usr/src:Z" docker.io/library/python:3.9-alpine
buildah from --name repomd-builder -v "${PWD}:/usr/src:Z" docker.io/library/python:3.11-alpine
buildah run repomd-builder sh <<EOF
cd /usr/src
python -mvenv /opt/pyenv --upgrade-deps
source /opt/pyenv/bin/activate
pip install semver
python3 -mvenv /opt/pyenv --upgrade-deps
/opt/pyenv/bin/pip3 install semver==3.0.1 filetype
apk add skopeo
EOF
fi

buildah run repomd-builder sh -c "cd /usr/src ; . /opt/pyenv/bin/activate ; python createrepo.py"
buildah run --workingdir /usr/src repomd-builder /opt/pyenv/bin/python3 createrepo.py

0 comments on commit ee035a6

Please sign in to comment.