forked from docker-library/meta-scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
deploy.jq
76 lines (72 loc) · 3 KB
/
deploy.jq
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
75
76
include "oci";
# input: array of "build" objects (with "buildId" top level keys)
# output: map of { "tag": [ list of OCI descriptors ], ... }
def tagged_manifests(builds_selector; tags_extractor):
reduce (.[] | select(.build.resolved and builds_selector)) as $i ({};
.[
$i
| tags_extractor
| ..|strings # no matter what "tags_extractor" gives us, this will flatten us to a stream of strings
] += [
# as an extra protection against cross-architecture "bleeding" ("riscv64" infra pushing "amd64" images, for example), filter the list of manifests to those whose architecture matches the architecture it is supposed to be for
# to be explicitly clear, this filtering is *also* done as part of our "builds.json" generation, so this is an added layer of best-effort protection that will be especially important to preserve and/or replicate if/when we solve the "not built yet so include the previous contents of the tag" portion of the problem at this layer instead of in the currently-separate put-shared process
$i.build.resolved.manifests[]
| select(.annotations["com.docker.official-images.bashbrew.arch"] // "" == $i.build.arch) # this assumes "registry.SynthesizeIndex" created this list of manifests (because it sets this annotation), but it would be reasonable for us to reimplement that conversion of "OCI platform object" to "bashbrew architecture" in pure jq if it was prudent or necessary to do so
]
)
;
def arch_tagged_manifests($arch):
tagged_manifests(.build.arch == $arch; .source.arches[.build.arch].archTags)
;
# input: output of tagged_manifests (map of tag -> list of OCI descriptors)
# output: array of input objects for "cmd/deploy" ({ "type": "manifest", "refs": [ ... ], "data": { ... } })
def deploy_objects:
reduce to_entries[] as $in ({};
$in.key as $ref
| (
$in.value
| map(normalize_descriptor) # normalized platforms *and* normalized field ordering
| sort_manifests
) as $manifests
| ([ $manifests[].digest ] | join("\n")) as $key
| .[$key] |= (
if . then
.refs += [ $ref ]
else
{
type: "manifest",
refs: [ $ref ],
# add appropriate "lookup" values for copying child objects properly
lookup: (
$manifests
| map({
key: .digest,
value: (
.digest as $dig
| .annotations["org.opencontainers.image.ref.name"]
| rtrimstr("@" + $dig)
),
})
| from_entries
),
# convert the list of "manifests" into a full (canonical!) index/manifest list for deploying
data: {
schemaVersion: 2,
mediaType: (
if $manifests[0]?.mediaType == "application/vnd.docker.distribution.manifest.v2+json" then
"application/vnd.docker.distribution.manifest.list.v2+json"
else
"application/vnd.oci.image.index.v1+json"
end
),
manifests: (
$manifests
| del(.[].annotations["org.opencontainers.image.ref.name"])
),
},
}
end
)
)
| [ .[] ] # strip off our synthetic map keys to avoid leaking our implementation detail
;