blob: 5f9341bdace52571591c3c9e3daf9e5e5f8b523a [file] [log] [blame]
Mohammed Naser8613c862023-04-24 17:26:51 -04001#!/usr/bin/env python3
2
3import argparse
4import functools
5
6from docker_image import reference
7from oslo_config import cfg
8from oslo_log import log as logging
9from ruyaml import YAML
10import requests
11
12LOG = logging.getLogger(__name__)
13CONF = cfg.CONF
14
15
16@functools.cache
17def get_pinned_image(image_src):
18 image_ref = reference.Reference.parse(image_src)
19
20 if image_ref.domain() == "quay.io":
21 r = requests.get(
22 f"https://quay.io/api/v1/repository/{image_ref.path()}/tag/",
23 params={"specificTag": image_ref["tag"]},
24 )
25 r.raise_for_status()
26 digest = r.json()["tags"][0]["manifest_digest"]
27
Mohammed Naser49e66372023-07-10 14:57:00 -040028 if image_ref.domain() == "docker.io":
29 # Get token for docker.io
30 r = requests.get(
31 "https://auth.docker.io/token",
Mohammed Naser16baaab2023-07-10 15:07:11 -040032 params={
33 "service": "registry.docker.io",
34 "scope": f"repository:{image_ref.path()}:pull",
35 },
Mohammed Naser49e66372023-07-10 14:57:00 -040036 )
37 r.raise_for_status()
38 token = r.json()["token"]
39
40 r = requests.get(
41 f"https://registry-1.docker.io/v2/{image_ref.path()}/manifests/{image_ref['tag']}",
Mohammed Naser16baaab2023-07-10 15:07:11 -040042 headers={
43 "Accept": "application/vnd.docker.distribution.manifest.v2+json",
44 "Authorization": f"Bearer {token}",
45 },
Mohammed Naser49e66372023-07-10 14:57:00 -040046 )
47 r.raise_for_status()
48 digest = r.headers["Docker-Content-Digest"]
49
Mohammed Naser8613c862023-04-24 17:26:51 -040050 return f"{image_ref.domain()}/{image_ref.path()}@{digest}"
51
52
53def main():
54 logging.register_options(CONF)
55 logging.setup(CONF, "atmosphere-bump-images")
56
57 parser = argparse.ArgumentParser("bump-images")
58 parser.add_argument(
59 "src", help="Path for default values file", type=argparse.FileType("r")
60 )
61 parser.add_argument("dst", help="Path for output file", type=argparse.FileType("w"))
62
63 args = parser.parse_args()
64
65 yaml = YAML(typ="rt")
66 data = yaml.load(args.src)
67
ricolinb8ab0172023-06-01 15:41:02 +080068 for image in data["_atmosphere_images"].ca.items:
69 token = data["_atmosphere_images"].ca.get(image, 2).value
Mohammed Naser8613c862023-04-24 17:26:51 -040070 if not token.startswith("# image-source: "):
71 LOG.info("Skipping image %s", image)
72 continue
73
74 image_src = token.replace("# image-source: ", "").strip()
75 pinned_image = get_pinned_image(image_src)
76
77 LOG.info("Pinning image %s from %s to %s", image, image_src, pinned_image)
ricolinb8ab0172023-06-01 15:41:02 +080078 data["_atmosphere_images"][image] = pinned_image
Mohammed Naser8613c862023-04-24 17:26:51 -040079
80 yaml.dump(data, args.dst)
81
82
83if __name__ == "__main__":
84 main()