-
Notifications
You must be signed in to change notification settings - Fork 174
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Austin Abro
committed
Jan 22, 2024
1 parent
ea8b271
commit f845fcf
Showing
4 changed files
with
117 additions
and
98 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// SPDX-FileCopyrightText: 2021-Present The Zarf Authors | ||
|
||
// Package oci contains functions for interacting with Zarf packages stored in OCI registries. | ||
package oci | ||
|
||
import "path/filepath" | ||
|
||
var ( | ||
// ZarfPackageIndexPath is the path to the index.json file in the OCI package. | ||
ZarfPackageIndexPath = filepath.Join("images", "index.json") | ||
// ZarfPackageLayoutPath is the path to the oci-layout file in the OCI package. | ||
ZarfPackageLayoutPath = filepath.Join("images", "oci-layout") | ||
// ZarfPackageImagesBlobsDir is the path to the directory containing the image blobs in the OCI package. | ||
ZarfPackageImagesBlobsDir = filepath.Join("images", "blobs", "sha256") | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// SPDX-FileCopyrightText: 2021-Present The Zarf Authors | ||
|
||
// Package oci contains functions for interacting with Zarf packages stored in OCI registries. | ||
package oci | ||
|
||
import ( | ||
"fmt" | ||
"path/filepath" | ||
"slices" | ||
|
||
"github.com/defenseunicorns/pkg/oci" | ||
"github.com/defenseunicorns/zarf/src/pkg/layout" | ||
"github.com/defenseunicorns/zarf/src/pkg/transform" | ||
"github.com/defenseunicorns/zarf/src/pkg/utils/helpers" | ||
"github.com/defenseunicorns/zarf/src/types" | ||
ocispec "github.com/opencontainers/image-spec/specs-go/v1" | ||
) | ||
|
||
// LayersFromRequestedComponents returns the descriptors for the given components from the root manifest. | ||
// It also retrieves the descriptors for all image layers that are required by the components. | ||
// | ||
// It also respects the `required` flag on components, and will retrieve all necessary layers for required components. | ||
func LayersFromRequestedComponents(o *oci.OrasRemote, requestedComponents []string) (layers []ocispec.Descriptor, err error) { | ||
root, err := o.FetchRoot() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
pkg, err := o.FetchZarfYAML() | ||
if err != nil { | ||
return nil, err | ||
} | ||
images := map[string]bool{} | ||
tarballFormat := "%s.tar" | ||
for _, name := range requestedComponents { | ||
component := helpers.Find(pkg.Components, func(component types.ZarfComponent) bool { | ||
return component.Name == name | ||
}) | ||
if component.Name == "" { | ||
return nil, fmt.Errorf("component %s does not exist in this package", name) | ||
} | ||
} | ||
for _, component := range pkg.Components { | ||
// If we requested this component, or it is required, we need to pull its images and tarball | ||
if slices.Contains(requestedComponents, component.Name) || component.Required { | ||
for _, image := range component.Images { | ||
images[image] = true | ||
} | ||
layers = append(layers, root.Locate(filepath.Join(layout.ComponentsDir, fmt.Sprintf(tarballFormat, component.Name)))) | ||
} | ||
} | ||
// Append the sboms.tar layer if it exists | ||
// | ||
// Since sboms.tar is not a heavy addition 99% of the time, we'll just always pull it | ||
sbomsDescriptor := root.Locate(layout.SBOMTar) | ||
if !oci.IsEmptyDescriptor(sbomsDescriptor) { | ||
layers = append(layers, sbomsDescriptor) | ||
} | ||
if len(images) > 0 { | ||
// Add the image index and the oci-layout layers | ||
layers = append(layers, root.Locate(ZarfPackageIndexPath), root.Locate(ZarfPackageLayoutPath)) | ||
index, err := o.FetchImagesIndex() | ||
if err != nil { | ||
return nil, err | ||
} | ||
for image := range images { | ||
// use docker's transform lib to parse the image ref | ||
// this properly mirrors the logic within create | ||
refInfo, err := transform.ParseImageRef(image) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to parse image ref %q: %w", image, err) | ||
} | ||
|
||
manifestDescriptor := helpers.Find(index.Manifests, func(layer ocispec.Descriptor) bool { | ||
return layer.Annotations[ocispec.AnnotationBaseImageName] == refInfo.Reference || | ||
// A backwards compatibility shim for older Zarf versions that would leave docker.io off of image annotations | ||
(layer.Annotations[ocispec.AnnotationBaseImageName] == refInfo.Path+refInfo.TagOrDigest && refInfo.Host == "docker.io") | ||
}) | ||
|
||
// even though these are technically image manifests, we store them as Zarf blobs | ||
manifestDescriptor.MediaType = ZarfLayerMediaTypeBlob | ||
|
||
manifest, err := o.FetchManifest(manifestDescriptor) | ||
if err != nil { | ||
return nil, err | ||
} | ||
// Add the manifest and the manifest config layers | ||
layers = append(layers, root.Locate(filepath.Join(ZarfPackageImagesBlobsDir, manifestDescriptor.Digest.Encoded()))) | ||
layers = append(layers, root.Locate(filepath.Join(ZarfPackageImagesBlobsDir, manifest.Config.Digest.Encoded()))) | ||
|
||
// Add all the layers from the manifest | ||
for _, layer := range manifest.Layers { | ||
layerPath := filepath.Join(ZarfPackageImagesBlobsDir, layer.Digest.Encoded()) | ||
layers = append(layers, root.Locate(layerPath)) | ||
} | ||
} | ||
} | ||
return layers, nil | ||
} |
This file was deleted.
Oops, something went wrong.