-
Notifications
You must be signed in to change notification settings - Fork 171
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor zoci push to support new package layout
Signed-off-by: Philip Laine <[email protected]>
- Loading branch information
1 parent
9a0874a
commit 169f944
Showing
4 changed files
with
201 additions
and
8 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// SPDX-FileCopyrightText: 2021-Present The Zarf Authors | ||
|
||
package layout | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"log/slog" | ||
|
||
"github.com/defenseunicorns/pkg/oci" | ||
ocispec "github.com/opencontainers/image-spec/specs-go/v1" | ||
"oras.land/oras-go/v2" | ||
"oras.land/oras-go/v2/content/file" | ||
|
||
"github.com/zarf-dev/zarf/src/api/v1alpha1" | ||
"github.com/zarf-dev/zarf/src/config" | ||
"github.com/zarf-dev/zarf/src/pkg/logger" | ||
"github.com/zarf-dev/zarf/src/pkg/message" | ||
) | ||
|
||
const ( | ||
// ZarfConfigMediaType is the media type for the manifest config | ||
ZarfConfigMediaType = "application/vnd.zarf.config.v1+json" | ||
// ZarfLayerMediaTypeBlob is the media type for all Zarf layers due to the range of possible content | ||
ZarfLayerMediaTypeBlob = "application/vnd.zarf.layer.v1.blob" | ||
) | ||
|
||
// Remote is a wrapper around the Oras remote repository with zarf specific functions | ||
type Remote struct { | ||
orasRemote *oci.OrasRemote | ||
} | ||
|
||
// NewRemote returns an oras remote repository client and context for the given url with zarf opination embedded. | ||
func NewRemote(ctx context.Context, url string, platform ocispec.Platform, mods ...oci.Modifier) (*Remote, error) { | ||
l := slog.New(message.ZarfHandler{}) | ||
if logger.Enabled(ctx) { | ||
l = logger.From(ctx) | ||
} | ||
modifiers := append([]oci.Modifier{ | ||
oci.WithPlainHTTP(config.CommonOptions.PlainHTTP), | ||
oci.WithInsecureSkipVerify(config.CommonOptions.InsecureSkipTLSVerify), | ||
oci.WithLogger(l), | ||
oci.WithUserAgent("zarf/" + config.CLIVersion), | ||
}, mods...) | ||
remote, err := oci.NewOrasRemote(url, platform, modifiers...) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &Remote{orasRemote: remote}, nil | ||
} | ||
|
||
// Push pushes the given package layout to the remote registry. | ||
func (r *Remote) Push(ctx context.Context, pkgLayout PackageLayout, concurrency int) (err error) { | ||
src, err := file.New("") | ||
if err != nil { | ||
return err | ||
} | ||
defer func(src *file.Store) { | ||
err2 := src.Close() | ||
err = errors.Join(err, err2) | ||
}(src) | ||
|
||
descs := []ocispec.Descriptor{} | ||
files, err := pkgLayout.Files() | ||
if err != nil { | ||
return err | ||
} | ||
for path, name := range files { | ||
desc, err := src.Add(ctx, name, ZarfLayerMediaTypeBlob, path) | ||
if err != nil { | ||
return err | ||
} | ||
descs = append(descs, desc) | ||
} | ||
|
||
annotations := annotationsFromMetadata(pkgLayout.Pkg.Metadata) | ||
manifestConfigDesc, err := r.orasRemote.CreateAndPushManifestConfig(ctx, annotations, ZarfConfigMediaType) | ||
if err != nil { | ||
return err | ||
} | ||
root, err := r.orasRemote.PackAndTagManifest(ctx, src, descs, manifestConfigDesc, annotations) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
copyOpts := r.orasRemote.GetDefaultCopyOpts() | ||
copyOpts.Concurrency = concurrency | ||
publishedDesc, err := oras.Copy(ctx, src, root.Digest.String(), r.orasRemote.Repo(), "", copyOpts) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = r.orasRemote.UpdateIndex(ctx, r.orasRemote.Repo().Reference.Reference, publishedDesc) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func annotationsFromMetadata(metadata v1alpha1.ZarfMetadata) map[string]string { | ||
annotations := map[string]string{ | ||
ocispec.AnnotationTitle: metadata.Name, | ||
ocispec.AnnotationDescription: metadata.Description, | ||
} | ||
if url := metadata.URL; url != "" { | ||
annotations[ocispec.AnnotationURL] = url | ||
} | ||
if authors := metadata.Authors; authors != "" { | ||
annotations[ocispec.AnnotationAuthors] = authors | ||
} | ||
if documentation := metadata.Documentation; documentation != "" { | ||
annotations[ocispec.AnnotationDocumentation] = documentation | ||
} | ||
if source := metadata.Source; source != "" { | ||
annotations[ocispec.AnnotationSource] = source | ||
} | ||
if vendor := metadata.Vendor; vendor != "" { | ||
annotations[ocispec.AnnotationVendor] = vendor | ||
} | ||
return annotations | ||
} |
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,36 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// SPDX-FileCopyrightText: 2021-Present The Zarf Authors | ||
|
||
package layout | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
"github.com/zarf-dev/zarf/src/api/v1alpha1" | ||
) | ||
|
||
func TestAnnotationsFromMetadata(t *testing.T) { | ||
t.Parallel() | ||
|
||
metadata := v1alpha1.ZarfMetadata{ | ||
Name: "foo", | ||
Description: "bar", | ||
URL: "https://example.com", | ||
Authors: "Zarf", | ||
Documentation: "documentation", | ||
Source: "source", | ||
Vendor: "vendor", | ||
} | ||
annotations := annotationsFromMetadata(metadata) | ||
expectedAnnotations := map[string]string{ | ||
"org.opencontainers.image.title": "foo", | ||
"org.opencontainers.image.description": "bar", | ||
"org.opencontainers.image.url": "https://example.com", | ||
"org.opencontainers.image.authors": "Zarf", | ||
"org.opencontainers.image.documentation": "documentation", | ||
"org.opencontainers.image.source": "source", | ||
"org.opencontainers.image.vendor": "vendor", | ||
} | ||
require.Equal(t, expectedAnnotations, annotations) | ||
} |
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