44 lines
1.9 KiB
Python
44 lines
1.9 KiB
Python
"""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.')
|