Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move versionary script here #2859

Merged
merged 1 commit into from
Feb 20, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 173 additions & 0 deletions versionary
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
#!/usr/bin/python3 -u

# This file originally lived in
# https://github.com/coreos/fedora-coreos-releng-automation. See that repo for
# archeological git research.

'''
Implements the Fedora CoreOS versioning scheme as per:
https://github.com/coreos/fedora-coreos-tracker/issues/81
https://github.com/coreos/fedora-coreos-tracker/issues/211
'''

import argparse
import json
import os
import re
import subprocess
import sys
import time
import yaml

from datetime import datetime

# streams which don't use lockfiles
UNLOCKED_STREAMS = [
'rawhide',
'branched',
'bodhi-updates-testing',
'bodhi-updates',
]

# https://github.com/coreos/fedora-coreos-tracker/issues/211#issuecomment-543547587
STREAM_TO_NUM = {
'next': 1,
'testing': 2,
'stable': 3,
'next-devel': 10,
'testing-devel': 20,
'rawhide': 91,
'branched': 92,
'bodhi-updates-testing': 93,
'bodhi-updates': 94,
}


def main():
args = parse_args()
if args.workdir is not None:
os.chdir(args.workdir)
assert os.path.isdir('builds'), 'Missing builds/ dir'

manifest = get_flattened_manifest()
x, y, z = (get_x(manifest), get_y(manifest), get_z(manifest))
n = get_next_iteration(x, y, z)
new_version = f'{x}.{y}.{z}.{n}'

# sanity check the new version by trying to re-parse it
assert parse_version(new_version) is not None
print(new_version)


def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument('--workdir', help="path to cosa workdir")
return parser.parse_args()


def get_x(manifest):
"""
X is the Fedora release version on which we're based.
"""
releasever = manifest['releasever']
eprint(f"x: {releasever} (from manifest)")
return int(releasever)


def get_y(manifest):
"""
Y is the base snapshot date in YYYYMMDD format of Fedora. We derive
this using the timestamp in the base lockfile.
"""

stream = manifest['add-commit-metadata']['fedora-coreos.stream']

# XXX: should sanity check that the lockfiles for all the basearches have
# matching timestamps
exts = ['json', 'yaml']
for ext in exts:
try:
with open(f"src/config/manifest-lock.x86_64.{ext}") as f:
lockfile = yaml.safe_load(f)
generated = lockfile.get('metadata', {}).get('generated')
if not generated:
raise Exception("Missing 'metadata.generated' key "
f"from {lockfile}")
dt = datetime.strptime(generated, '%Y-%m-%dT%H:%M:%SZ')
assert stream not in UNLOCKED_STREAMS
msg_src = "from lockfile"
break
except FileNotFoundError:
continue
else:
# must be an unlocked stream
assert stream in UNLOCKED_STREAMS
msg_src = "unlocked stream"
dt = datetime.now()

ymd = dt.strftime('%Y%m%d')
eprint(f"y: {ymd} ({msg_src})")
return int(ymd)


def get_z(manifest):
"""
Z is the stream indicator.
"""
stream = manifest['add-commit-metadata']['fedora-coreos.stream']
assert stream in STREAM_TO_NUM, f"Unknown stream: {stream}"
mapped = STREAM_TO_NUM[stream]
eprint(f"z: {mapped} (mapped from stream {stream})")
return mapped


def get_next_iteration(x, y, z):
try:
with open('builds/builds.json') as f:
builds = json.load(f)
except FileNotFoundError:
builds = {'builds': []}

if len(builds['builds']) == 0:
eprint("n: 0 (no previous builds)")
return 0

last_buildid = builds['builds'][0]['id']
last_version = parse_version(last_buildid)
if not last_version:
eprint(f"n: 0 (previous version {last_buildid} does not match scheme)")
return 0

if (x, y, z) != last_version[:3]:
eprint(f"n: 0 (previous version {last_buildid} x.y.z does not match)")
return 0

n = last_version[3] + 1
eprint(f"n: {n} (incremented from previous version {last_buildid})")
return n


def get_flattened_manifest():
return yaml.safe_load(
subprocess.check_output(['rpm-ostree', 'compose', 'tree',
'--print-only', 'src/config/manifest.yaml']))


def parse_version(version):
m = re.match(r'^([0-9]{2})\.([0-9]{8})\.([0-9]+)\.([0-9]+)$', version)
if m is None:
return None
# sanity-check date
try:
time.strptime(m.group(2), '%Y%m%d')
except ValueError:
return None
return tuple(map(int, m.groups()))


def eprint(*args):
print(*args, file=sys.stderr)


if __name__ == "__main__":
sys.exit(main())
Loading