From a8fae241f06b90695ff069f19af47bee6a0db800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jake=20Buchholz=20G=C3=B6kt=C3=BCrk?= Date: Tue, 30 Nov 2021 16:11:32 +0000 Subject: [PATCH] Authoritative EOL / Publish Updates Tags & Description Implement alpine lib as a class * get versions/releases/EOLs from authoritative source * methods to build appropriate URLs * fallback to old method of determining release for RC versions * compute edge & RC EOLs here instead of elsewhere Remove end_of_life from configs, and don't return it from imported images. Always update image tags and descriptions when re/publishing images. Fix image description URL... :P --- alpine.py | 112 ++++++++++++++++++++++++++++++-------- build | 13 ++--- clouds/aws.py | 23 ++++---- configs/alpine.conf | 2 +- configs/version/3.11.conf | 2 - configs/version/3.12.conf | 4 +- configs/version/3.13.conf | 4 +- configs/version/3.14.conf | 4 +- configs/version/3.15.conf | 2 - image_configs.py | 23 +++----- 10 files changed, 120 insertions(+), 69 deletions(-) diff --git a/alpine.py b/alpine.py index 46b10f1..09f393d 100644 --- a/alpine.py +++ b/alpine.py @@ -1,35 +1,103 @@ # vim: ts=4 et: +import json import re +from datetime import datetime, timedelta from urllib.request import urlopen -# constants and vars -CDN_URL = 'https://dl-cdn.alpinelinux.org/alpine' +class Alpine(): + DEFAULT_RELEASES_URL = 'https://alpinelinux.org/releases.json' + DEFAULT_CDN_URL = 'https://dl-cdn.alpinelinux.org/alpine' -# TODO: also get EOL from authoritative source + def __init__(self, releases_url=None, cdn_url=None): + self.now = datetime.utcnow() + self.release_today = self.now.strftime('%Y%m%d') + self.eol_tomorrow = (self.now + timedelta(days=1)).strftime('%F') + self.latest = None + self.versions = {} + self.releases_url = releases_url or self.DEFAULT_RELEASES_URL + self.cdn_url = cdn_url or self.DEFAULT_CDN_URL -def get_version_release(alpine_version): - apk_ver = get_apk_version(alpine_version, 'main', 'x86_64', 'alpine-base') - release = apk_ver.split('-')[0] - version = '.'.join(release.split('.')[:2]) - return {'version': version, 'release': release} + # get all Alpine versions, and their EOL and latest release + res = urlopen(self.releases_url) + r = json.load(res) + branches = sorted( + r['release_branches'], reverse=True, + key=lambda x: x.get('branch_date', '0000-00-00') + ) + for b in branches: + ver = b['rel_branch'].lstrip('v') + if not self.latest: + self.latest = ver + rel = None + if releases := b.get('releases', None): + rel = sorted( + releases, reverse=True, key=lambda x: x['date'] + )[0]['version'] + elif ver == 'edge': + # edge "releases" is today's YYYYMMDD + rel = self.release_today -# TODO? maybe download and parse APKINDEX instead? -# also check out https://dl-cdn.alpinelinux.org/alpine/v3.15/releases/x86_64/latest-releases.yaml -def get_apk_version(alpine_version, repo, arch, apk): - repo_url = f"{CDN_URL}/{alpine_version}/{repo}/{arch}" - apks_re = re.compile(f'"{apk}-(\\d.*)\\.apk"') - res = urlopen(repo_url) - for line in map(lambda x: x.decode('utf8'), res): - if not line.startswith('