Skip to content

Commit

Permalink
set base-image annotations
Browse files Browse the repository at this point in the history
Since opencontainers/image-spec/pull/822/ the OCI spec supports two new
annotations to set the fully-qualified name and the digest of the base
image.

Signed-off-by: Valentin Rothberg <[email protected]>
  • Loading branch information
vrothberg committed Aug 3, 2021
1 parent 6329b98 commit d97694b
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 25 deletions.
10 changes: 9 additions & 1 deletion config.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,15 @@ func (b *Builder) initConfig(ctx context.Context, img types.Image) error {
if err := json.Unmarshal(b.Manifest, &v1Manifest); err != nil {
return errors.Wrapf(err, "error parsing OCI manifest %q", string(b.Manifest))
}
b.ImageAnnotations = v1Manifest.Annotations
for k, v := range v1Manifest.Annotations {
// NOTE: do not override annotations that are
// already set. Otherwise, we may erase
// annotations such as the digest of the base
// image.
if value := b.ImageAnnotations[k]; value == "" {
b.ImageAnnotations[k] = v
}
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ require (
github.com/onsi/ginkgo v1.16.4
github.com/onsi/gomega v1.14.0
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6
github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7
github.com/opencontainers/runc v1.0.1
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
github.com/opencontainers/runtime-tools v0.9.0
Expand Down
3 changes: 2 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -627,8 +627,9 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 h1:yN8BPXVwMBAm3Cuvh1L5XE8XpvYRMdsVLd82ILprhUU=
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7 h1:axgApq2XShTLwQii2zAnIkMPlhGVHbAXHUcHezu5G/k=
github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
Expand Down
13 changes: 12 additions & 1 deletion new.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ import (
"github.com/containers/common/pkg/config"
"github.com/containers/image/v5/image"
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/pkg/shortnames"
"github.com/containers/image/v5/transports"
"github.com/containers/image/v5/types"
"github.com/containers/storage"
digest "github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/openshift/imagebuilder"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -248,6 +250,15 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions
namespaceOptions := defaultNamespaceOptions
namespaceOptions.AddOrReplace(options.NamespaceOptions...)

// Set the base-image annotations as suggested by the OCI image spec.
imageAnnotations := map[string]string{}
imageAnnotations[v1.AnnotationBaseImageDigest] = imageDigest
if !shortnames.IsShortName(imageSpec) {
// If the base image could be resolved to a fully-qualified
// image name, let's set it.
imageAnnotations[v1.AnnotationBaseImageName] = imageSpec
}

builder := &Builder{
store: store,
Type: containerType,
Expand All @@ -256,7 +267,7 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions
FromImageDigest: imageDigest,
Container: name,
ContainerID: container.ID,
ImageAnnotations: map[string]string{},
ImageAnnotations: imageAnnotations,
ImageCreatedBy: "",
ProcessLabel: container.ProcessLabel(),
MountLabel: container.MountLabel(),
Expand Down
51 changes: 47 additions & 4 deletions tests/bud.bats
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,30 @@ symlink(subdir)"

@test "bud with --layers and single and two line Dockerfiles" {
_prefetch alpine
run_buildah inspect --format "{{.FromImageDigest}}" alpine
fromDigest="$output"

run_buildah bud --signature-policy ${TESTSDIR}/policy.json --layers -t test -f Dockerfile.5 ${TESTSDIR}/bud/use-layers
run_buildah images -a
expect_line_count 3

# Also check for base-image annotations.
run_buildah inspect --format '{{index .ImageAnnotations "org.opencontainers.image.base.digest" }}' test
expect_output "$fromDigest" "base digest from alpine"
run_buildah inspect --format '{{index .ImageAnnotations "org.opencontainers.image.base.name" }}' test
expect_output "docker.io/library/alpine:latest" "base name from alpine"

run_buildah bud --signature-policy ${TESTSDIR}/policy.json --layers -t test1 -f Dockerfile.6 ${TESTSDIR}/bud/use-layers
run_buildah images -a
expect_line_count 4

# Note that the base-image annotations are empty here since a Container with
# a single FROM line is effectively just a tag and it does not create a new
# image.
run_buildah inspect --format '{{index .ImageAnnotations "org.opencontainers.image.base.digest" }}' test1
expect_output "" "base digest from alpine"
run_buildah inspect --format '{{index .ImageAnnotations "org.opencontainers.image.base.name" }}' test1
expect_output "" "base name from alpine"
}

@test "bud with --layers, multistage, and COPY with --from" {
Expand Down Expand Up @@ -258,8 +275,18 @@ symlink(subdir)"

@test "bud-multistage-reused" {
_prefetch alpine busybox
run_buildah inspect --format "{{.FromImageDigest}}" busybox
fromDigest="$output"

target=foo
run_buildah bud --signature-policy ${TESTSDIR}/policy.json -t ${target} -f ${TESTSDIR}/bud/multi-stage-builds/Dockerfile.reused ${TESTSDIR}/bud/multi-stage-builds

# Also check for base-image annotations.
run_buildah inspect --format '{{index .ImageAnnotations "org.opencontainers.image.base.digest" }}' ${target}
expect_output "$fromDigest" "base digest from busybox"
run_buildah inspect --format '{{index .ImageAnnotations "org.opencontainers.image.base.name" }}' ${target}
expect_output "docker.io/library/busybox:latest" "base name from busybox"

run_buildah from --signature-policy ${TESTSDIR}/policy.json ${target}
run_buildah rmi -f ${target}
run_buildah bud --signature-policy ${TESTSDIR}/policy.json -t ${target} --layers -f ${TESTSDIR}/bud/multi-stage-builds/Dockerfile.reused ${TESTSDIR}/bud/multi-stage-builds
Expand Down Expand Up @@ -403,6 +430,22 @@ symlink(subdir)"
expect_output "${target}-working-container"
}

@test "bud-from-scratch-untagged" {
run_buildah bud --iidfile ${TESTDIR}/output.iid --signature-policy ${TESTSDIR}/policy.json ${TESTSDIR}/bud/from-scratch
iid=$(cat ${TESTDIR}/output.iid)
expect_output --substring --from="$iid" '^sha256:[0-9a-f]{64}$'
run_buildah from ${iid}
buildctr="$output"
run_buildah commit $buildctr new-image

run_buildah inspect --format "{{.FromImageDigest}}" $iid
fromDigest="$output"
run_buildah inspect --format '{{index .ImageAnnotations "org.opencontainers.image.base.digest" }}' new-image
expect_output "$fromDigest" "digest for untagged base image"
run_buildah inspect --format '{{index .ImageAnnotations "org.opencontainers.image.base.name" }}' new-image
expect_output "" "no base name for untagged base image"
}

@test "bud with --tag " {
target=scratch-image
run_buildah bud --quiet=false --tag test1 --signature-policy ${TESTSDIR}/policy.json -t ${target} ${TESTSDIR}/bud/from-scratch
Expand Down Expand Up @@ -458,8 +501,8 @@ symlink(subdir)"
@test "bud-from-scratch-annotation" {
target=scratch-image
run_buildah bud --annotation "test=annotation1,annotation2=z" --signature-policy ${TESTSDIR}/policy.json -t ${target} ${TESTSDIR}/bud/from-scratch
run_buildah inspect --format '{{printf "%q" .ImageAnnotations}}' ${target}
expect_output 'map["test":"annotation1,annotation2=z"]'
run_buildah inspect --format '{{index .ImageAnnotations "test"}}' ${target}
expect_output "annotation1,annotation2=z"
}

@test "bud-from-scratch-layers" {
Expand Down Expand Up @@ -2029,8 +2072,8 @@ _EOF
_prefetch alpine
target=no-change-image
run_buildah bud --annotation "test=annotation" --signature-policy ${TESTSDIR}/policy.json -t ${target} ${TESTSDIR}/bud/no-change
run_buildah inspect --format '{{printf "%q" .ImageAnnotations}}' ${target}
expect_output 'map["test":"annotation"]'
run_buildah inspect --format '{{index .ImageAnnotations "test"}}' ${target}
expect_output "annotation"
}

@test "bud-squash-layers" {
Expand Down
32 changes: 16 additions & 16 deletions tests/config.bats
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,10 @@ function check_matrix() {
run_buildah commit --format docker --signature-policy ${TESTSDIR}/policy.json $cid scratch-image-docker
run_buildah commit --format oci --signature-policy ${TESTSDIR}/policy.json $cid scratch-image-oci

run_buildah inspect --type=image --format '{{.ImageAnnotations}}' scratch-image-oci
expect_output "map[ANNOTATION:VALUE1,VALUE2]"
run_buildah inspect --format '{{.ImageAnnotations}}' $cid
expect_output "map[ANNOTATION:VALUE1,VALUE2]"
run_buildah inspect --type=image --format '{{index .ImageAnnotations "ANNOTATION"}}' scratch-image-oci
expect_output "VALUE1,VALUE2"
run_buildah inspect --format '{{index .ImageAnnotations "ANNOTATION"}}' $cid
expect_output "VALUE1,VALUE2"
check_matrix 'Config.ExposedPorts' 'map[12345:{}]'
check_matrix 'Config.Env' '[VARIABLE=VALUE1,VALUE2]'
check_matrix 'Config.Labels.LABEL' 'VALUE'
Expand Down Expand Up @@ -253,10 +253,10 @@ function check_matrix() {
expect_output "PROBABLY-EMPTY"

# The following aren't part of the Docker v2 spec, so they're discarded when we save to Docker format.
run_buildah inspect --type=image --format '{{.ImageAnnotations}}' scratch-image-oci
expect_output "map[ANNOTATION:VALUE1,VALUE2]"
run_buildah inspect --format '{{.ImageAnnotations}}' $cid
expect_output "map[ANNOTATION:VALUE1,VALUE2]"
run_buildah inspect --type=image --format '{{index .ImageAnnotations "ANNOTATION"}}' scratch-image-oci
expect_output "VALUE1,VALUE2"
run_buildah inspect --format '{{index .ImageAnnotations "ANNOTATION"}}' $cid
expect_output "VALUE1,VALUE2"
run_buildah inspect --type=image --format '{{.Docker.Comment}}' scratch-image-docker
expect_output "INFORMATIVE"
run_buildah inspect --type=image --format '{{.Docker.Config.Domainname}}' scratch-image-docker
Expand Down Expand Up @@ -348,10 +348,10 @@ function check_matrix() {
check_matrix 'Config.Env' '[VARIABLE=VALUE1,VALUE2]'
check_matrix 'Config.Labels.LABEL' 'VALUE'
check_matrix 'Config.ExposedPorts' 'map[12345:{}]'
run_buildah inspect --type=image --format '{{.ImageAnnotations}}' scratch-image-oci
expect_output "map[ANNOTATION:VALUE1,VALUE2]"
run_buildah inspect --format '{{.ImageAnnotations}}' $cid
expect_output "map[ANNOTATION:VALUE1,VALUE2]"
run_buildah inspect --type=image --format '{{index .ImageAnnotations "ANNOTATION"}}' scratch-image-oci
expect_output "VALUE1,VALUE2"
run_buildah inspect --format '{{index .ImageAnnotations "ANNOTATION"}}' $cid
expect_output "VALUE1,VALUE2"

run_buildah config \
--created-by COINCIDENCE \
Expand All @@ -370,10 +370,10 @@ function check_matrix() {
check_matrix 'Config.Env' '[]'
check_matrix 'Config.Labels.LABEL' '<no value>'
check_matrix 'Config.ExposedPorts' 'map[]'
run_buildah inspect --type=image --format '{{.ImageAnnotations}}' scratch-image-oci
expect_output "map[]"
run_buildah inspect --format '{{.ImageAnnotations}}' $cid
expect_output "map[]"
run_buildah inspect --type=image --format '{{index .ImageAnnotations "ANNOTATION"}}' scratch-image-oci
expect_output ""
run_buildah inspect --format '{{index .ImageAnnotations "ANNOTATION"}}' $cid
expect_output ""

run_buildah config \
--created-by COINCIDENCE \
Expand Down
13 changes: 13 additions & 0 deletions tests/from.bats
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ load helpers
run_buildah from --pull=false --signature-policy ${TESTSDIR}/policy.json scratch
cid=$output
run_buildah commit --signature-policy ${TESTSDIR}/policy.json "$cid" scratch2
# Also check for base-image annotations.
run_buildah inspect --format '{{index .ImageAnnotations "org.opencontainers.image.base.digest" }}' scratch2
expect_output "" "no base digest for scratch"
run_buildah inspect --format '{{index .ImageAnnotations "org.opencontainers.image.base.name" }}' scratch2
expect_output "" "no base name for scratch"
run_buildah rm $cid
run_buildah tag scratch2 scratch3
# Set --pull=false to prevent looking for a newer scratch3 image.
Expand Down Expand Up @@ -379,11 +384,19 @@ load helpers

@test "from --pull-always: emits 'Getting' even if image is cached" {
_prefetch docker.io/busybox
run_buildah inspect --format "{{.FromImageDigest}}" docker.io/busybox
fromDigest="$output"
run buildah pull --signature-policy ${TESTSDIR}/policy.json docker.io/busybox
run_buildah from --signature-policy ${TESTSDIR}/policy.json --name busyboxc --pull-always docker.io/busybox
expect_output --substring "Getting"
run_buildah commit --signature-policy ${TESTSDIR}/policy.json busyboxc fakename-img
run_buildah 125 from --signature-policy ${TESTSDIR}/policy.json --pull-always fakename-img

# Also check for base-image annotations.
run_buildah inspect --format '{{index .ImageAnnotations "org.opencontainers.image.base.digest" }}' fakename-img
expect_output "$fromDigest" "base digest from busybox"
run_buildah inspect --format '{{index .ImageAnnotations "org.opencontainers.image.base.name" }}' fakename-img
expect_output "docker.io/library/busybox:latest" "base name from busybox"
}

@test "from --quiet: should not emit progress messages" {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion vendor/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ github.com/onsi/gomega/matchers/support/goraph/util
github.com/onsi/gomega/types
# github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/go-digest
# github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6
# github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7
github.com/opencontainers/image-spec/specs-go
github.com/opencontainers/image-spec/specs-go/v1
# github.com/opencontainers/runc v1.0.1
Expand Down

0 comments on commit d97694b

Please sign in to comment.