aboutsummaryrefslogtreecommitdiff
path: root/releng/docker.xsh
blob: 20fb30cd3ed71b5f384ca5c6ecc5fdab817443d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import json
import logging
from pathlib import Path
import tempfile

import requests

from .environment import DockerTarget, RelengEnvironment
from .version import VERSION, MAJOR
from . import gitutils
from .docker_assemble import Registry, OCIIndex, OCIIndexItem
from . import docker_assemble

log = logging.getLogger(__name__)
log.setLevel(logging.INFO)

def check_all_logins(env: RelengEnvironment):
    for target in env.docker_targets:
        check_login(target)

def check_login(target: DockerTarget):
    skopeo login @(target.registry_name())

def upload_docker_images(target: DockerTarget, paths: list[Path]):
    if not paths: return

    sess = requests.Session()
    sess.headers['User-Agent'] = 'lix-releng'

    tag_names = [DockerTarget.resolve(tag, version=VERSION, major=MAJOR) for tag in target.tags]

    # latest only gets tagged for the current release branch of Lix
    if not gitutils.is_maintenance_branch('HEAD'):
        tag_names.append('latest')

    meta = {}

    reg = docker_assemble.Registry(sess)
    manifests = []

    with tempfile.TemporaryDirectory() as tmp:
        tmp = Path(tmp)

        for path in paths:
            digest_file = tmp / (path.name + '.digest')
            inspection = json.loads($(skopeo inspect docker-archive:@(path)))

            docker_arch = inspection['Architecture']
            docker_os = inspection['Os']
            meta = inspection['Labels']

            log.info('Pushing image %s for %s to %s', path, docker_arch, target.registry_path)

            # insecure-policy: we don't have any signature policy, we are just uploading an image
            # We upload to a junk tag, because otherwise it will upload to `latest`, which is undesirable
            skopeo --insecure-policy copy --format oci --digestfile @(digest_file) docker-archive:@(path) docker://@(target.registry_path):temp

            digest = digest_file.read_text().strip()

            # skopeo doesn't give us the manifest size directly, so we just ask the registry
            metadata = reg.image_info(target.registry_path, digest)

            manifests.append(OCIIndexItem(metadata=metadata, architecture=docker_arch, os=docker_os))
    # delete the temp tag, which we only have to create because of skopeo
    # limitations anyhow (it seems to not have a way to say "don't tag it, find
    # your checksum and put it there")
    # FIXME: this is not possible because GitHub only has a proprietary API for it. amazing. 11/10.
    # reg.delete_tag(target.registry_path, 'temp')

    log.info('Pushed images to %r, building a bigger and more menacing manifest from %r with metadata %r', target, manifests, meta)
    # send the multiarch manifest to each tag
    index = OCIIndex(manifests=manifests, annotations=meta)
    for tag in tag_names:
        reg.upload_index(target.registry_path, tag, index)