From b47933135affb3a7160cec4fbf447539ad0cd77e Mon Sep 17 00:00:00 2001 From: unclegedd Date: Tue, 2 Apr 2024 12:22:09 -0500 Subject: [PATCH 1/2] fix: ensure we are pulling all components --- src/pkg/bundler/fetcher/fetcher.go | 1 + src/pkg/bundler/fetcher/remote.go | 2 +- src/pkg/bundler/pusher/remote.go | 2 +- src/pkg/utils/oci.go | 21 +++++++++++---------- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/pkg/bundler/fetcher/fetcher.go b/src/pkg/bundler/fetcher/fetcher.go index cf24efbd..56e871cd 100644 --- a/src/pkg/bundler/fetcher/fetcher.go +++ b/src/pkg/bundler/fetcher/fetcher.go @@ -52,6 +52,7 @@ func NewPkgFetcher(pkg types.Package, fetcherConfig Config) (Fetcher, error) { if err != nil { return nil, err } + fetcher = &remoteFetcher{ pkg: pkg, cfg: fetcherConfig, diff --git a/src/pkg/bundler/fetcher/remote.go b/src/pkg/bundler/fetcher/remote.go index c9ad92c4..5870a970 100644 --- a/src/pkg/bundler/fetcher/remote.go +++ b/src/pkg/bundler/fetcher/remote.go @@ -101,7 +101,7 @@ func (f *remoteFetcher) Fetch() ([]ocispec.Descriptor, error) { func (f *remoteFetcher) layersToLocalBundle(spinner *message.Spinner, currentPackageIter int, totalPackages int) ([]ocispec.Descriptor, error) { spinner.Updatef("Fetching %s package layer metadata (package %d of %d)", f.pkg.Name, currentPackageIter, totalPackages) // get only the layers that are required by the components - layersToCopy, err := utils.GetZarfLayers(*f.remote, f.pkgRootManifest) + layersToCopy, err := utils.GetZarfLayers(*f.remote, f.pkgRootManifest, f.pkg.OptionalComponents) if err != nil { return nil, err } diff --git a/src/pkg/bundler/pusher/remote.go b/src/pkg/bundler/pusher/remote.go index fa846f26..68313305 100644 --- a/src/pkg/bundler/pusher/remote.go +++ b/src/pkg/bundler/pusher/remote.go @@ -88,7 +88,7 @@ func (p *RemotePusher) PushManifest() (ocispec.Descriptor, error) { func (p *RemotePusher) LayersToRemoteBundle(spinner *message.Spinner, currentPackageIter int, totalPackages int) ([]ocispec.Descriptor, error) { spinner.Updatef("Fetching %s package layer metadata (package %d of %d)", p.pkg.Name, currentPackageIter, totalPackages) // get only the layers that are required by the components - layersToCopy, err := utils.GetZarfLayers(p.cfg.RemoteSrc, p.cfg.PkgRootManifest) + layersToCopy, err := utils.GetZarfLayers(p.cfg.RemoteSrc, p.cfg.PkgRootManifest, p.pkg.OptionalComponents) if err != nil { return nil, err } diff --git a/src/pkg/utils/oci.go b/src/pkg/utils/oci.go index 0a2b2118..cac7bc82 100644 --- a/src/pkg/utils/oci.go +++ b/src/pkg/utils/oci.go @@ -261,24 +261,25 @@ func EnsureOCIPrefix(source string) string { } // GetZarfLayers grabs the necessary Zarf pkg layers from a remote OCI registry -func GetZarfLayers(remote zoci.Remote, pkgRootManifest *oci.Manifest) ([]ocispec.Descriptor, error) { - // todo: ensure we are only pulling non-optional components +func GetZarfLayers(remote zoci.Remote, pkgRootManifest *oci.Manifest, optionalComponents []string) ([]ocispec.Descriptor, error) { ctx := context.TODO() + zarfPkg, err := remote.FetchZarfYAML(ctx) + if err != nil { + return nil, err + } + + // ensure we're only pulling required components and optional components var components []zarfTypes.ZarfComponent - for _, layer := range pkgRootManifest.Layers { - // infer component name from layer title annotation - titleAnnotation := layer.Annotations[ocispec.AnnotationTitle] - isComponent := strings.HasPrefix(titleAnnotation, "components/") && strings.HasSuffix(titleAnnotation, ".tar") - if isComponent { - afterComponents := strings.Split(titleAnnotation, "components/")[1] - componentName := strings.Split(afterComponents, ".tar")[0] - components = append(components, zarfTypes.ZarfComponent{Name: componentName}) + for _, c := range zarfPkg.Components { + if c.Required != nil || slices.Contains(optionalComponents, c.Name) { + components = append(components, c) } } layersFromComponents, err := remote.LayersFromRequestedComponents(ctx, components) if err != nil { return nil, err } + // get the layers that are always pulled var metadataLayers []ocispec.Descriptor for _, path := range zoci.PackageAlwaysPull { From 59d501230fdb5c71d17281e8d5843513e9d1833f Mon Sep 17 00:00:00 2001 From: unclegedd Date: Tue, 2 Apr 2024 13:51:14 -0500 Subject: [PATCH 2/2] adds test --- .../13-composable-component/uds-bundle.yaml | 14 +++++++++++++ src/test/e2e/bundle_test.go | 16 ++++++++++++++ src/test/packages/prometheus/images/zarf.yaml | 13 ++++++++++++ src/test/packages/prometheus/zarf.yaml | 21 +++++++++++++++++++ 4 files changed, 64 insertions(+) create mode 100644 src/test/bundles/13-composable-component/uds-bundle.yaml create mode 100644 src/test/packages/prometheus/images/zarf.yaml create mode 100644 src/test/packages/prometheus/zarf.yaml diff --git a/src/test/bundles/13-composable-component/uds-bundle.yaml b/src/test/bundles/13-composable-component/uds-bundle.yaml new file mode 100644 index 00000000..a4182f81 --- /dev/null +++ b/src/test/bundles/13-composable-component/uds-bundle.yaml @@ -0,0 +1,14 @@ +kind: UDSBundle +metadata: + name: with-composed + description: | + test bundle with a remote pkg with a: + - docker distribution manifest media type (quay images) + - composed component with only images + version: 0.0.1 + +packages: + - name: prometheus + # remote pkg ensures we're testing pulling composed components from OCI + repository: localhost:888/prometheus + ref: 0.0.1 diff --git a/src/test/e2e/bundle_test.go b/src/test/e2e/bundle_test.go index d17c94c3..7618a18b 100644 --- a/src/test/e2e/bundle_test.go +++ b/src/test/e2e/bundle_test.go @@ -481,6 +481,22 @@ func validateMultiArchIndex(t *testing.T, index ocispec.Index) { require.True(t, checkedARM) } +func TestBundleWithComposedPkgComponent(t *testing.T) { + e2e.SetupDockerRegistry(t, 888) + defer e2e.TeardownRegistry(t, 888) + zarfPkgPath := "src/test/packages/prometheus" + pkg := filepath.Join(zarfPkgPath, fmt.Sprintf("zarf-package-prometheus-%s-0.0.1.tar.zst", e2e.Arch)) + e2e.CreateZarfPkg(t, zarfPkgPath, false) + zarfPublish(t, pkg, "localhost:888") + + bundleDir := "src/test/bundles/13-composable-component" + bundleName := "with-composed" + bundlePath := filepath.Join(bundleDir, fmt.Sprintf("uds-bundle-%s-%s-0.0.1.tar.zst", bundleName, e2e.Arch)) + createLocal(t, bundleDir, e2e.Arch) + deploy(t, bundlePath) + remove(t, bundlePath) +} + func TestBundleTmpDir(t *testing.T) { deployZarfInit(t) e2e.CreateZarfPkg(t, "src/test/packages/podinfo", false) diff --git a/src/test/packages/prometheus/images/zarf.yaml b/src/test/packages/prometheus/images/zarf.yaml new file mode 100644 index 00000000..9ebc9f90 --- /dev/null +++ b/src/test/packages/prometheus/images/zarf.yaml @@ -0,0 +1,13 @@ +kind: ZarfPackageConfig +metadata: + name: prometheus-images + description: | + testing pkg component composition + version: 0.0.1 + +components: + - name: upload + required: true + description: Push quay image to the zarf registry + images: + - quay.io/prometheus/node-exporter:v1.7.0 diff --git a/src/test/packages/prometheus/zarf.yaml b/src/test/packages/prometheus/zarf.yaml new file mode 100644 index 00000000..ca6af08c --- /dev/null +++ b/src/test/packages/prometheus/zarf.yaml @@ -0,0 +1,21 @@ +kind: ZarfPackageConfig +metadata: + name: prometheus + description: | + test pkg with a docker distribution manifest media type (quay images) and a component with only images + version: 0.0.1 + +components: + - name: upload-image + required: true + description: test composition + import: + path: images + name: upload + - name: deploy + required: true + charts: + - name: prometheus-node-exporter + url: https://prometheus-community.github.io/helm-charts + version: 4.32.0 + namespace: prometheus