"""Remove only the retired distroless tag, after a successful latest publication.""" import json import os from urllib.error import HTTPError from urllib.request import Request, urlopen repo = os.environ['DOCKER_REPOSITORY'] if repo not in {'k2patel/rtorrent', 'k2patel/floodui'}: raise SystemExit('Unexpected repository') base = 'https://hub.docker.com/v2/repositories/' + repo + '/tags/' def request(url, method='GET', data=None, token=None): headers = {'Content-Type': 'application/json'} if token: headers['Authorization'] = 'Bearer ' + token req = Request(url, method=method, headers=headers, data=json.dumps(data).encode() if data is not None else None) with urlopen(req, timeout=30) as response: body = response.read() return json.loads(body) if body else None try: latest = request(base + 'latest/') try: old = request(base + 'distroless/') except HTTPError as error: if error.code == 404: print(repo + ': only latest remains; no legacy tag to retire') raise SystemExit(0) raise if not latest.get('digest'): raise SystemExit('Refusing cleanup without a published latest digest') auth = request('https://hub.docker.com/v2/users/login', method='POST', data={ 'username': os.environ['DOCKER_USERNAME'], 'password': os.environ['DOCKER_TOKEN']}) token = auth['token'] request(base + 'distroless/', method='DELETE', token=token) # Verify the latest image remained unchanged. if request(base + 'latest/')['digest'] != latest['digest']: raise SystemExit('latest changed during tag retirement; inspect the registry') print(repo + ': retired distroless tag; latest retained at ' + latest['digest']) except HTTPError as error: # Never print an authentication response or token. raise SystemExit(f'Docker Hub tag retirement failed: HTTP {error.code}. Token needs delete permission.')