Skip to content

Commit

Permalink
WIP from Austin meetup
Browse files Browse the repository at this point in the history
  • Loading branch information
Austin Abro committed Jan 22, 2024
1 parent ea8b271 commit f845fcf
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 98 deletions.
2 changes: 1 addition & 1 deletion src/cmd/initialize.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ func downloadInitPackage(cacheDirectory string) (string, error) {

// If the user wants to download the init-package, download it
if confirmDownload {
remote, err := oci.NewOrasRemote(url, oci.WithArch(config.GetArch()))
remote, err := oci.NewOrasRemote(url, oci.WithArch(config.GetArch()), oci.WithInsecure(zarfconfig.CommonOptions.Insecure))
if err != nil {
return "", err
}
Expand Down
16 changes: 16 additions & 0 deletions src/pkg/packager/oci/manifest.go
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")
)
100 changes: 100 additions & 0 deletions src/pkg/packager/oci/pull.go
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
}
97 changes: 0 additions & 97 deletions src/pkg/utils/transport.go

This file was deleted.

0 comments on commit f845fcf

Please sign in to comment.