Skip to content

Commit

Permalink
feat: enables duplicate pkgs
Browse files Browse the repository at this point in the history
  • Loading branch information
UncleGedd committed Apr 1, 2024
1 parent e333eac commit cf502b6
Show file tree
Hide file tree
Showing 14 changed files with 71 additions and 119 deletions.
6 changes: 0 additions & 6 deletions src/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,6 @@ const (
// EnvVarPrefix is the prefix for environment variables to override bundle helm variables
EnvVarPrefix = "UDS_"

// ZarfPackageNameAnnotation is the annotation key for the value that specifies the zarf package name
ZarfPackageNameAnnotation = "zarf.package.name"

// UDSPackageNameAnnotation is the annotation key for the value that specifies the name given to a zarf package in the uds-bundle.yaml
UDSPackageNameAnnotation = "uds.package.name"

// CachedLogs is a file containing cached logs
CachedLogs = "recent-logs"
)
Expand Down
8 changes: 1 addition & 7 deletions src/pkg/bundle/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func deployPackages(packages []types.Package, resume bool, b *Bundle) error {
// Automatically confirm the package deployment
zarfConfig.CommonOptions.Confirm = true

source, err := sources.New(b.cfg.DeployOpts.Source, b.cfg.DeployOpts.ZarfPackageNameMap[pkg.Name], opts, sha, nsOverrides)
source, err := sources.New(b.cfg.DeployOpts.Source, pkg.Name, opts, sha, nsOverrides)
if err != nil {
return err
}
Expand Down Expand Up @@ -328,12 +328,6 @@ func (b *Bundle) PreDeployValidation() (string, string, string, error) {
return "", "", "", err
}

// Maps name given to zarf package in the bundle to the actual name of the zarf package
zarfPackageNameMap, err := provider.ZarfPackageNameMap()
if err != nil {
return "", "", "", err
}
b.cfg.DeployOpts.ZarfPackageNameMap = zarfPackageNameMap
bundleName := b.bundle.Metadata.Name
return bundleName, string(bundleYAML), source, err
}
Expand Down
3 changes: 0 additions & 3 deletions src/pkg/bundle/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ type Provider interface {

// getBundleManifest gets the bundle's root manifest
getBundleManifest() (*oci.Manifest, error)

// ZarfPackageNameMap returns a map of the zarf package name specified in the uds-bundle.yaml to the actual zarf package name
ZarfPackageNameMap() (map[string]string, error)
}

// NewBundleProvider returns a new bundler Provider based on the source type
Expand Down
32 changes: 0 additions & 32 deletions src/pkg/bundle/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
zarfUtils "github.com/defenseunicorns/zarf/src/pkg/utils"
"github.com/defenseunicorns/zarf/src/pkg/utils/helpers"
"github.com/defenseunicorns/zarf/src/pkg/zoci"
goyaml "github.com/goccy/go-yaml"
"github.com/mholt/archiver/v4"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras-go/v2"
Expand Down Expand Up @@ -335,34 +334,3 @@ func CheckOCISourcePath(source string) (string, error) {
}
return source, nil
}

// ZarfPackageNameMap returns the uds bundle zarf package name to actual zarf package name mappings from the oci provider
func (op *ociProvider) ZarfPackageNameMap() (map[string]string, error) {
rootManifest, err := op.getBundleManifest()
if err != nil {
return nil, err
}

loaded, err := op.LoadBundleMetadata()
if err != nil {
return nil, err
}

b, err := os.ReadFile(loaded[config.BundleYAML])
if err != nil {
return nil, err
}

var bundle types.UDSBundle
if err := goyaml.Unmarshal(b, &bundle); err != nil {
return nil, err
}

nameMap := make(map[string]string)
for _, pkg := range bundle.Packages {
sha := strings.Split(pkg.Ref, "@sha256:")[1] // this is where we use the SHA appended to the Zarf pkg inside the bundle
manifestDesc := rootManifest.Locate(sha)
nameMap[manifestDesc.Annotations[config.UDSPackageNameAnnotation]] = manifestDesc.Annotations[config.ZarfPackageNameAnnotation]
}
return nameMap, nil
}
21 changes: 5 additions & 16 deletions src/pkg/bundle/remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,6 @@ func (b *Bundle) Remove() error {
return err
}

// Maps name given to zarf package in the bundle to the actual name of the zarf package
zarfPackageNameMap, err := provider.ZarfPackageNameMap()
if err != nil {
return err
}

// Check if --packages flag is set and zarf packages have been specified
var packagesToRemove []types.Package

Expand All @@ -73,25 +67,20 @@ func (b *Bundle) Remove() error {
if len(userSpecifiedPackages) != len(packagesToRemove) {
return fmt.Errorf("invalid zarf packages specified by --packages")
}
return removePackages(packagesToRemove, b, zarfPackageNameMap)
return removePackages(packagesToRemove, b)
}
return removePackages(b.bundle.Packages, b, zarfPackageNameMap)
return removePackages(b.bundle.Packages, b)
}

func removePackages(packagesToRemove []types.Package, b *Bundle, zarfPackageNameMap map[string]string) error {
func removePackages(packagesToRemove []types.Package, b *Bundle) error {
// Get deployed packages
deployedPackageNames := GetDeployedPackageNames()

for i := len(packagesToRemove) - 1; i >= 0; i-- {

pkg := packagesToRemove[i]
zarfPackageName := pkg.Name
// use the name map if it has been set (remote pkgs where the pkg name isn't consistent)
if _, ok := zarfPackageNameMap[pkg.Name]; ok {
zarfPackageName = zarfPackageNameMap[pkg.Name]
}

if slices.Contains(deployedPackageNames, zarfPackageName) {
if slices.Contains(deployedPackageNames, pkg.Name) {
opts := zarfTypes.ZarfPackageOptions{
PackageSource: b.cfg.RemoveOpts.Source,
}
Expand All @@ -104,7 +93,7 @@ func removePackages(packagesToRemove []types.Package, b *Bundle, zarfPackageName
}

sha := strings.Split(pkg.Ref, "sha256:")[1]
source, err := sources.New(b.cfg.RemoveOpts.Source, zarfPackageName, opts, sha, nil)
source, err := sources.New(b.cfg.RemoveOpts.Source, pkg.Name, opts, sha, nil)
if err != nil {
return err
}
Expand Down
20 changes: 0 additions & 20 deletions src/pkg/bundle/tarball.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"github.com/defenseunicorns/zarf/src/pkg/oci"
zarfUtils "github.com/defenseunicorns/zarf/src/pkg/utils"
"github.com/defenseunicorns/zarf/src/pkg/utils/helpers"
"github.com/defenseunicorns/zarf/src/pkg/zoci"
av3 "github.com/mholt/archiver/v3"
av4 "github.com/mholt/archiver/v4"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
Expand Down Expand Up @@ -327,22 +326,3 @@ func (tp *tarballBundleProvider) PublishBundle(bundle types.UDSBundle, remote *o
progressBar.Successf("Published %s", remote.Repo().Reference)
return nil
}

// ZarfPackageNameMap gets zarf package name mappings from tarball provider
func (tp *tarballBundleProvider) ZarfPackageNameMap() (map[string]string, error) {
bundleRootManifest, err := tp.getBundleManifest()
if err != nil {
return nil, err
}

nameMap := make(map[string]string)
for _, layer := range bundleRootManifest.Layers {
if layer.MediaType == zoci.ZarfLayerMediaTypeBlob {
// only the uds bundle layer will have AnnotationTitle set
if layer.Annotations[ocispec.AnnotationTitle] != config.BundleYAML {
nameMap[layer.Annotations[config.UDSPackageNameAnnotation]] = layer.Annotations[config.ZarfPackageNameAnnotation]
}
}
}
return nameMap, nil
}
26 changes: 5 additions & 21 deletions src/pkg/bundler/fetcher/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ type remoteFetcher struct {
// Fetch fetches a Zarf pkg and puts it into a local bundle
func (f *remoteFetcher) Fetch() ([]ocispec.Descriptor, error) {
fetchSpinner := message.NewProgressSpinner("Fetching package %s", f.pkg.Name)
zarfPackageName := ""
zarfRootLayerAdded := false
defer fetchSpinner.Stop()

layerDescs, err := f.layersToLocalBundle(fetchSpinner, f.cfg.PkgIter+1, f.cfg.NumPkgs)
Expand All @@ -58,22 +56,12 @@ func (f *remoteFetcher) Fetch() ([]ocispec.Descriptor, error) {
if err != nil {
return nil, err
}

// ensure media type is Zarf blob for layers in the bundle's root manifest
layerDesc.MediaType = zoci.ZarfLayerMediaTypeBlob

// add package name annotations
annotations := make(map[string]string)
layerDesc.Annotations = annotations
layerDesc.Annotations[config.UDSPackageNameAnnotation] = f.pkg.Name

// If zarf package name has been obtained from zarf config, set the zarf package name annotation
// This block of code will only be triggered if the zarf config is processed before the zarf image manifest
if zarfPackageName != "" {
layerDesc.Annotations[config.ZarfPackageNameAnnotation] = zarfPackageName
}

// add layer to bundle's root manifest
f.cfg.BundleRootManifest.Layers = append(f.cfg.BundleRootManifest.Layers, layerDesc)
zarfRootLayerAdded = true
} else if layerDesc.MediaType == zoci.ZarfConfigMediaType {
// read in and unmarshal zarf config
jsonData, err := os.ReadFile(filepath.Join(f.cfg.TmpDstDir, config.BlobsDir, layerDesc.Digest.Encoded()))
Expand All @@ -85,14 +73,9 @@ func (f *remoteFetcher) Fetch() ([]ocispec.Descriptor, error) {
if err != nil {
return nil, err
}
zarfPackageName = zarfConfigData.Annotations[ocispec.AnnotationTitle]
// Check if zarf image manifest has been added to root manifest already, if so add zarfPackageName annotation
// This block of code will only be triggered if the zarf image manifest is processed before the zarf config
if zarfRootLayerAdded {
f.cfg.BundleRootManifest.Layers[f.cfg.PkgIter].Annotations[config.ZarfPackageNameAnnotation] = zarfPackageName
}
}
}

fetchSpinner.Successf("Fetched package: %s", f.pkg.Name)
return layerDescs, nil
}
Expand Down Expand Up @@ -178,7 +161,8 @@ func (f *remoteFetcher) remoteToLocal(layersToCopy []ocispec.Descriptor) ([]ocis
}
}
} else {
// need to grab pkg root manifest manually bc we didn't use oras.Copy()
// need to grab pkg root manifest and config manually bc we didn't use oras.Copy()
// note we're creating a new desc because we're changing the media type of the pkg root manifest
pkgManifestDesc, err := utils.ToOCIStore(f.pkgRootManifest, ocispec.MediaTypeImageManifest, f.cfg.Store)
if err != nil {
return nil, err
Expand Down
10 changes: 0 additions & 10 deletions src/pkg/bundler/pusher/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ func NewPkgPusher(pkg types.Package, cfg Config) RemotePusher {

// Push pushes a Zarf pkg to a remote bundle
func (p *RemotePusher) Push() (ocispec.Descriptor, error) {
ctx := context.TODO()
zarfManifestDesc, err := p.PushManifest()
if err != nil {
return ocispec.Descriptor{}, err
Expand All @@ -52,15 +51,6 @@ func (p *RemotePusher) Push() (ocispec.Descriptor, error) {
url := fmt.Sprintf("%s:%s", p.pkg.Repository, p.pkg.Ref)
message.Debugf("Pushed %s sub-manifest into %s: %s", url, p.cfg.RemoteDst.Repo().Reference, message.JSONValue(zarfManifestDesc))

// add package name annotations to zarf manifest
zarfYamlFile, err := p.cfg.RemoteSrc.FetchZarfYAML(ctx)
if err != nil {
return ocispec.Descriptor{}, err
}
zarfManifestDesc.Annotations = make(map[string]string)
zarfManifestDesc.Annotations[config.UDSPackageNameAnnotation] = p.pkg.Name
zarfManifestDesc.Annotations[config.ZarfPackageNameAnnotation] = zarfYamlFile.Metadata.Name

pushSpinner := message.NewProgressSpinner("")
defer pushSpinner.Stop()

Expand Down
4 changes: 4 additions & 0 deletions src/pkg/sources/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ func (r *RemoteBundle) LoadPackage(dst *layout.PackagePaths, filter filters.Comp
}
}
addNamespaceOverrides(&pkg, r.nsOverrides)
// ensure we're using the correct package name as specified by the bundle
pkg.Metadata.Name = r.PkgName
return pkg, nil, err
}

Expand Down Expand Up @@ -151,6 +153,8 @@ func (r *RemoteBundle) LoadPackageMetadata(dst *layout.PackagePaths, _ bool, _ b
dst.SetFromLayers([]ocispec.Descriptor{pkgManifestDesc, checksumLayer})

err = sources.ValidatePackageIntegrity(dst, pkg.Metadata.AggregateChecksum, true)
// ensure we're using the correct package name as specified by the bundle
pkg.Metadata.Name = r.PkgName
return pkg, nil, err
}

Expand Down
4 changes: 4 additions & 0 deletions src/pkg/sources/tarball.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ func (t *TarballBundle) LoadPackage(dst *layout.PackagePaths, filter filters.Com
}
addNamespaceOverrides(&pkg, t.nsOverrides)
packageSpinner.Successf("Loaded bundled Zarf package: %s", t.PkgName)
// ensure we're using the correct package name as specified by the bundle
pkg.Metadata.Name = t.PkgName
return pkg, nil, err
}

Expand Down Expand Up @@ -187,6 +189,8 @@ func (t *TarballBundle) LoadPackageMetadata(dst *layout.PackagePaths, _ bool, _
}

err = sourceArchive.Close()
// ensure we're using the correct package name as specified by the bundle
pkg.Metadata.Name = t.PkgName
return pkg, nil, err
}

Expand Down
1 change: 1 addition & 0 deletions src/pkg/utils/oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ func GetZarfLayers(remote zoci.Remote, pkgRootManifest *oci.Manifest) ([]ocispec
if err != nil {
return nil, err
}

// get the layers that are always pulled
var metadataLayers []ocispec.Descriptor
for _, path := range zoci.PackageAlwaysPull {
Expand Down
29 changes: 29 additions & 0 deletions src/test/bundles/07-helm-overrides/duplicate/uds-bundle.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
kind: UDSBundle
metadata:
name: duplicates
description: testing a bundle with duplicate packages in specified namespaces
version: 0.0.1

packages:
- name: helm-overrides
# path: "../../../packages/helm"
repository: ghcr.io/unclegedd/helm-overrides
ref: 0.0.1
overrides:
podinfo-component:
unicorn-podinfo:
namespace: "override-namespace"
values:
- path: "podinfo.replicaCount"
value: 1
- name: helm-overrides-duplicate
# path: "../../../packages/helm"
repository: ghcr.io/unclegedd/helm-overrides
ref: 0.0.1
overrides:
podinfo-component:
unicorn-podinfo:
namespace: "override-namespace-2"
values:
- path: "podinfo.replicaCount"
value: 1
19 changes: 19 additions & 0 deletions src/test/e2e/variable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,25 @@ func TestBundleWithHelmOverrides(t *testing.T) {
remove(t, bundlePath)
}

func TestBundleWithDupPkgs(t *testing.T) {
deployZarfInit(t)
e2e.CreateZarfPkg(t, "src/test/packages/nginx", false)
bundleDir := "src/test/bundles/07-helm-overrides/duplicate"
bundlePath := filepath.Join(bundleDir, fmt.Sprintf("uds-bundle-duplicates-%s-0.0.1.tar.zst", e2e.Arch))

createLocal(t, bundleDir, e2e.Arch)
deploy(t, bundlePath)
defer remove(t, bundlePath)

// ensure there are 2 namespaces each with an nginx deployment
cmd := strings.Split("zarf tools kubectl get deploy -n override-namespace -o=jsonpath='{.items[*].metadata.name}'", " ")
deployments, _, _ := e2e.UDS(cmd...)
require.Equal(t, "'unicorn-podinfo'", deployments)
cmd = strings.Split("zarf tools kubectl get deploy -n override-namespace-2 -o=jsonpath='{.items[*].metadata.name}'", " ")
deployments, _, _ = e2e.UDS(cmd...)
require.Equal(t, "'unicorn-podinfo'", deployments)
}

func TestBundleWithOverridenNamespace(t *testing.T) {
deployZarfInit(t)
e2e.HelmDepUpdate(t, "src/test/packages/helm/unicorn-podinfo")
Expand Down
7 changes: 3 additions & 4 deletions src/types/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,9 @@ type BundleDeployOptions struct {
PublicKeyPath string
SetVariables map[string]string `json:"setVariables" jsonschema:"description=Key-Value map of variable names and their corresponding values that will be used by Zarf packages in a bundle"`
// Variables and SharedVariables are read in from uds-config.yaml
Variables map[string]map[string]interface{} `yaml:"variables,omitempty"`
SharedVariables map[string]interface{} `yaml:"shared,omitempty"`
ZarfPackageNameMap map[string]string `yaml:"-" json:"-"`
Retries int `yaml:"retries"`
Variables map[string]map[string]interface{} `yaml:"variables,omitempty"`
SharedVariables map[string]interface{} `yaml:"shared,omitempty"`
Retries int `yaml:"retries"`
}

// BundleInspectOptions is the options for the bundler.Inspect() function
Expand Down

0 comments on commit cf502b6

Please sign in to comment.