Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go/cmd/ocitool/desc_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func loadManifestForImage(ctx context.Context, allLocalProviders content.Provide
OS: os,
Architecture: arch,
}
targetPlatformMatch := platforms.Only(targetPlatform)
targetPlatformMatch := platforms.OnlyStrict(targetPlatform)

// Resolve the unknown descriptor into an image manifest, if an index
// match the requested platform.
Expand Down
26 changes: 24 additions & 2 deletions go/pkg/layer/rebase.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/DataDog/rules_oci/go/pkg/ociutil"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/images/converter"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)

Expand Down Expand Up @@ -38,9 +39,30 @@ func RebaseImage(ctx context.Context, store content.Store, originalImageDesc oci
}
}

// Get the original image's layers after the old base image to append to the new base image.
// Get the original image's layers after the old base image to append to the new base image and add the original image
// as the OCI base image annotations to that layer, as is done for the layers from the base image in AppendLayers.
var layersToAppend []ocispec.Descriptor
layersToAppend = append(layersToAppend, originalManifest.Layers[len(oldBaseManifest.Layers):]...)
origRef := originalImageDesc.Annotations[ocispec.AnnotationRefName]

for _, origImgLayer := range originalManifest.Layers[len(oldBaseManifest.Layers):] {
// If we have an original image ref, set the OCI base image annotations on the original image layers. This allows
// ociutil.CopyContent to determine whether to copy the layer into the target repo via an OCI mount request.
if origRef != "" {
if origImgLayer.Annotations == nil {
origImgLayer.Annotations = make(map[string]string)
}
if _, ok := origImgLayer.Annotations[ocispec.AnnotationBaseImageName]; !ok {
origImgLayer.Annotations[ocispec.AnnotationBaseImageName] = origRef
}

if _, ok := origImgLayer.Annotations[ocispec.AnnotationBaseImageDigest]; !ok {
origImgLayer.Annotations[ocispec.AnnotationBaseImageDigest] = originalImageDesc.Digest.String()
}
}

origImgLayer.MediaType = converter.ConvertDockerMediaTypeToOCI(origImgLayer.MediaType)
layersToAppend = append(layersToAppend, origImgLayer)
}

rebasedManifest, rebasedConfig, err := AppendLayers(ctx, store, newBaseImageDesc, layersToAppend, nil, originalImageConfig.Config.Labels, createdTimestamp, originalImageConfig.Config.Entrypoint)
if err != nil {
Expand Down
14 changes: 13 additions & 1 deletion go/pkg/ociutil/bazel.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ func GenerateBuildFilesHandler(handler images.HandlerFunc, layoutRoot string, pr
// TODO Currently only supporting SHA256
blobBuildFiles[digest.SHA256] = rule.EmptyFile(algoBUILDPath(layoutRoot, digest.SHA256), "")

insertedBlobRules := make(map[digest.Algorithm]map[string]bool)
insertedBlobRules[digest.SHA256] = make(map[string]bool)

// Add load statements for all of the oci_* rules
ldBlob := rule.NewLoad("@com_github_datadog_rules_oci//oci:blob.bzl")
ldBlob.Add("oci_blob")
Expand Down Expand Up @@ -65,7 +68,16 @@ func GenerateBuildFilesHandler(handler images.HandlerFunc, layoutRoot string, pr
return nil, fmt.Errorf("no build file for algo '%v'", algo)
}

// Insert a rule for each blob
if _, ok := insertedBlobRules[algo]; !ok {
return nil, fmt.Errorf("no inserted blob rules map for algo '%v'", algo)
}
// If we've already inserted this descriptor's blob rule, skip it and its children.
if _, ok := insertedBlobRules[algo][dgstToLabelName(desc.Digest)]; ok {
return nil, nil
}
insertedBlobRules[algo][dgstToLabelName(desc.Digest)] = true

// Insert a rule for each blob.
blobRuleFromDescriptor(desc).Insert(f)

// if the manifest is an manifest or index, add an additional rule to
Expand Down
10 changes: 5 additions & 5 deletions tests/go-multiarch-image/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ oci_push(

oci_rebase_image(
name = "rebase",
arch = "arm64",
new_base = "@ubuntu_jammy//image",
old_base = "@ubuntu_focal//image",
original = ":image",
arch = "amd64",
new_base = "@new-base-for-rebase//image",
old_base = "@old-base-for-rebase//image",
original = "@tekton-45//image",
os = "linux",
visibility = ["//visibility:public"],
)
Expand All @@ -48,7 +48,7 @@ oci_push(
name = "push-rebase",
manifest = ":rebase",
registry = "ghcr.io",
repository = "datadog/rules_oci/hello-world-rebase",
repository = "datadog/rules_oci/tekton-rebase",
)

bzl_library(
Expand Down
24 changes: 19 additions & 5 deletions tests/test_images.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,25 @@ def pull_test_images():
digest = "sha256:9d6a8699fb5c9c39cf08a0871bd6219f0400981c570894cd8cbea30d3424a31f",
)

# TODO(abayer): Temporarily using a public image I pushed to my own gcr.io repo.
oci_pull(
name = "ubuntu_jammy",
name = "tekton-45",
registry = "gcr.io",
repository = "abayer-jclouds-test1/rules_oci/ubuntu",
# Latest at "jammy" tag
digest = "sha256:99f98de8a0a27a7e1b3979238d17422ae3359573bda3beed0906da7e2d42e8c3",
repository = "tekton-releases/github.com/tektoncd/pipeline/cmd/controller",
# Latest at "v0.45.0" tag
digest = "sha256:8a302dab54484bbb83d46ff9455b077ea51c1c189641dcda12575f8301bfb257",
shallow = False,
)

oci_pull(
name = "old-base-for-rebase",
registry = "cgr.dev",
repository = "chainguard/static",
digest = "sha256:d9dd790fb308621ac4a5d648a852fbc455cda12f487eb30fb775a479c4f90703",
)

oci_pull(
name = "new-base-for-rebase",
registry = "cgr.dev",
repository = "chainguard/static",
digest = "sha256:76bde0b3719bbb65c1b39cd6c0f75fbbe0e24c115a40040ac50361cd8774d913",
)