diff --git a/Makefile b/Makefile index 6adc76e641..7a81ba94eb 100644 --- a/Makefile +++ b/Makefile @@ -78,6 +78,7 @@ delete-packages: ## Delete all Zarf package tarballs in the project recursively # Note: the path to the main.go file is not used due to https://github.com/golang/go/issues/51831#issuecomment-1074188363 .PHONY: build build: ## Build the Zarf CLI for the machines OS and architecture + go mod tidy $(MAKE) $(BUILD_CLI_FOR_SYSTEM) build-cli-linux-amd: ## Build the Zarf CLI for Linux on AMD64 diff --git a/SUPPORT.md b/SUPPORT.md new file mode 100644 index 0000000000..690b7d8402 --- /dev/null +++ b/SUPPORT.md @@ -0,0 +1,47 @@ +# Support Guidelines + +We strive to create clear guidelines on communication to the Zarf team to provide a good community experience. + +## Questions +For guidance on using Zarf, [the documentation](https://docs.zarf.dev/) should cover most use cases. +For all questions documentation may not cover, we suggest utilizing [Github Discussions](https://github.com/defenseunicorns/zarf/discussions). + +## Standard Process +All code issues should be a [Github Issue](https://github.com/defenseunicorns/zarf/issues/new/choose) that follows the issue template. + +Following the templates provides the Zarf community a foundation of understanding to be able to assist quickly. +After an issue is made, this issue can be brought into other chanels such as the [Kubernetes Slack #Zarf](https://zarf.dev/slack) channel or the [bi-weekly Zarf Community Meeting](https://docs.zarf.dev/contribute/contributor-guide/). + + Github Issue + / \ + Zarf Slack Channel Zarf Community Call + + + +## Sensitive Information Process +For issues from those who are unable to post on Github, you may send an email using the following issue template filled out to [zarf-dev-private@googlegroups.com](zarf-dev-private@googlegroups.com) + +The response time to emails may be delayed as they are not able to receive community help, so we encourage participation into Github Issues as much as possible. + +``` +### Environment +Device and OS: +App version: +Kubernetes distro being used: +Other: + +### Steps to reproduce +1. + +### Expected result + +### Actual Result + +### Visual Proof (screenshots, videos, text, etc) + +### Severity/Priority + +### Additional Context +Add any other context or screenshots about the technical debt here. + +``` \ No newline at end of file diff --git a/site/src/content/docs/commands/zarf_package_inspect.md b/site/src/content/docs/commands/zarf_package_inspect.md index def3845bb1..7a27daff9f 100644 --- a/site/src/content/docs/commands/zarf_package_inspect.md +++ b/site/src/content/docs/commands/zarf_package_inspect.md @@ -22,6 +22,7 @@ zarf package inspect [ PACKAGE_SOURCE ] [flags] ``` -h, --help help for inspect + --list-images List images in the package (prints to stdout) -s, --sbom View SBOM contents while inspecting the package --sbom-out string Specify an output directory for the SBOMs from the inspected Zarf package ``` diff --git a/site/src/content/docs/ref/deploy.mdx b/site/src/content/docs/ref/deploy.mdx index f6b144c9bd..3b92ee1070 100644 --- a/site/src/content/docs/ref/deploy.mdx +++ b/site/src/content/docs/ref/deploy.mdx @@ -120,3 +120,41 @@ $ zarf connect [service name] You can also specify a package locally, or via oci such as `zarf package deploy oci://defenseunicorns/dos-games:1.0.0-$(uname -m) --key=https://zarf.dev/cosign.pub` ::: + +## Installing, Upgrading, and Rolling Back with Helm + +Zarf deploys resources in Kubernetes using [Helm's Go SDK](https://helm.sh/docs/topics/advanced/#go-sdk), and converts manifests into Helm charts for installation. + +If no existing Helm releases match a given chart in the cluster, Zarf executes a `helm install`. + +Should matching releases exist, a `helm upgrade` is performed. + +### Handling CustomResourceDefinitions (CRDs) + + - CRDs are _included_ during `helm install` to support Kubernetes Operator deployments + - CRDs are _excluded_ during `helm upgrade` due to [Helm's lack of support for upgrading CRDs](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/#some-caveats-and-explanations) + +### Waiting for Resource Readiness + +By default, Zarf waits for all resources to deploy successfully during install, upgrade, and rollback operations. + +You can override this behavior during install and upgrade by setting the `noWait: true` key under the `charts` and `manifests` fields. + +### Timeout Settings + +The default timeout for Helm operations in Zarf is 15 minutes. + +Use the `--timeout` flag with `zarf init` and `zarf package deploy` to modify the timeout duration. + +### Retry Policy + +Zarf retries install and upgrade operations up to three times by default if an error occurs. + +Use the `--retries` flag with `zarf init` and `zarf package deploy` to change the number of retry attempts. + +### Rollback Process + +If attempts to upgrade a chart fail, Zarf tries to roll the chart back to its last successful release. During this rollback process: + + - Any resources created during the failed upgrade attempt are deleted (`helm rollback --cleanup-on-fail`) + - Resource updates are forced through delete and recreate if needed (`helm rollback --force`) diff --git a/src/cmd/package.go b/src/cmd/package.go index e3fb00b48a..a0f124a864 100644 --- a/src/cmd/package.go +++ b/src/cmd/package.go @@ -422,6 +422,7 @@ func bindInspectFlags(_ *viper.Viper) { inspectFlags := packageInspectCmd.Flags() inspectFlags.BoolVarP(&pkgConfig.InspectOpts.ViewSBOM, "sbom", "s", false, lang.CmdPackageInspectFlagSbom) inspectFlags.StringVar(&pkgConfig.InspectOpts.SBOMOutputDir, "sbom-out", "", lang.CmdPackageInspectFlagSbomOut) + inspectFlags.BoolVar(&pkgConfig.InspectOpts.ListImages, "list-images", false, lang.CmdPackageInspectFlagListImages) } func bindRemoveFlags(v *viper.Viper) { diff --git a/src/config/lang/english.go b/src/config/lang/english.go index 1d1847d207..224e269166 100644 --- a/src/config/lang/english.go +++ b/src/config/lang/english.go @@ -308,9 +308,10 @@ $ zarf package mirror-resources \ CmdPackageMirrorFlagComponents = "Comma-separated list of components to mirror. This list will be respected regardless of a component's 'required' or 'default' status. Globbing component names with '*' and deselecting components with a leading '-' are also supported." CmdPackageMirrorFlagNoChecksum = "Turns off the addition of a checksum to image tags (as would be used by the Zarf Agent) while mirroring images." - CmdPackageInspectFlagSbom = "View SBOM contents while inspecting the package" - CmdPackageInspectFlagSbomOut = "Specify an output directory for the SBOMs from the inspected Zarf package" - CmdPackageInspectErr = "Failed to inspect package: %s" + CmdPackageInspectFlagSbom = "View SBOM contents while inspecting the package" + CmdPackageInspectFlagSbomOut = "Specify an output directory for the SBOMs from the inspected Zarf package" + CmdPackageInspectFlagListImages = "List images in the package (prints to stdout)" + CmdPackageInspectErr = "Failed to inspect package: %s" CmdPackageRemoveShort = "Removes a Zarf package that has been deployed already (runs offline)" CmdPackageRemoveFlagConfirm = "REQUIRED. Confirm the removal action to prevent accidental deletions" diff --git a/src/internal/packager/helm/chart.go b/src/internal/packager/helm/chart.go index 72b80d65f9..9252bf40d4 100644 --- a/src/internal/packager/helm/chart.go +++ b/src/internal/packager/helm/chart.go @@ -82,7 +82,7 @@ func (h *Helm) InstallOrUpgradeChart() (types.ConnectStrings, string, error) { } if err != nil { - return fmt.Errorf("unable to complete the helm chart install/upgrade: %w", err) + return err } message.Debug(output.Info.Description) @@ -92,7 +92,6 @@ func (h *Helm) InstallOrUpgradeChart() (types.ConnectStrings, string, error) { err = helpers.Retry(tryHelm, h.retries, 5*time.Second, message.Warnf) if err != nil { - // Try to rollback any deployed releases releases, _ := histClient.Run(h.chart.ReleaseName) previouslyDeployedVersion := 0 @@ -103,25 +102,21 @@ func (h *Helm) InstallOrUpgradeChart() (types.ConnectStrings, string, error) { } } - // On total failure try to rollback (if there was a previously deployed version) or uninstall. - if previouslyDeployedVersion > 0 { - spinner.Updatef("Performing chart rollback") - - err = h.rollbackChart(h.chart.ReleaseName, previouslyDeployedVersion) - if err != nil { - return nil, "", fmt.Errorf("unable to upgrade chart after %d attempts and unable to rollback: %w", h.retries, err) - } + removeMsg := "if you need to remove the failed chart, use `zarf package remove`" - return nil, "", fmt.Errorf("unable to upgrade chart after %d attempts", h.retries) + // No prior releases means this was an initial install. + if previouslyDeployedVersion == 0 { + return nil, "", fmt.Errorf("unable to install chart after %d attempts: %s", h.retries, removeMsg) } - spinner.Updatef("Performing chart uninstall") - _, err = h.uninstallChart(h.chart.ReleaseName) + // Attempt to rollback on a failed upgrade. + spinner.Updatef("Performing chart rollback") + err = h.rollbackChart(h.chart.ReleaseName, previouslyDeployedVersion) if err != nil { - return nil, "", fmt.Errorf("unable to install chart after %d attempts and unable to uninstall: %w", h.retries, err) + return nil, "", fmt.Errorf("unable to upgrade chart after %d attempts and unable to rollback: %s", h.retries, removeMsg) } - return nil, "", fmt.Errorf("unable to install chart after %d attempts", h.retries) + return nil, "", fmt.Errorf("unable to upgrade chart after %d attempts: %s", h.retries, removeMsg) } // return any collected connect strings for zarf connect. diff --git a/src/pkg/packager/creator/differential.go b/src/pkg/packager/creator/differential.go index 59915eead1..ee373836d0 100644 --- a/src/pkg/packager/creator/differential.go +++ b/src/pkg/packager/creator/differential.go @@ -5,17 +5,13 @@ package creator import ( - "fmt" "os" "github.com/defenseunicorns/zarf/src/config" - "github.com/defenseunicorns/zarf/src/internal/packager/git" "github.com/defenseunicorns/zarf/src/pkg/layout" "github.com/defenseunicorns/zarf/src/pkg/packager/sources" - "github.com/defenseunicorns/zarf/src/pkg/transform" "github.com/defenseunicorns/zarf/src/pkg/utils" "github.com/defenseunicorns/zarf/src/types" - "github.com/go-git/go-git/v5/plumbing" ) // loadDifferentialData sets any images and repos from the existing reference package in the DifferentialData and returns it. @@ -58,47 +54,3 @@ func loadDifferentialData(diffPkgPath string) (diffData *types.DifferentialData, DifferentialPackageVersion: diffPkg.Metadata.Version, }, nil } - -// removeCopiesFromComponents removes any images and repos already present in the reference package components. -func removeCopiesFromComponents(components []types.ZarfComponent, loadedDiffData *types.DifferentialData) (diffComponents []types.ZarfComponent, err error) { - for _, component := range components { - newImageList := []string{} - newRepoList := []string{} - - for _, img := range component.Images { - imgRef, err := transform.ParseImageRef(img) - if err != nil { - return nil, fmt.Errorf("unable to parse image ref %s: %s", img, err.Error()) - } - - imgTag := imgRef.TagOrDigest - includeImage := imgTag == ":latest" || imgTag == ":stable" || imgTag == ":nightly" - if includeImage || !loadedDiffData.DifferentialImages[img] { - newImageList = append(newImageList, img) - } - } - - for _, repoURL := range component.Repos { - _, refPlain, err := transform.GitURLSplitRef(repoURL) - if err != nil { - return nil, err - } - - var ref plumbing.ReferenceName - if refPlain != "" { - ref = git.ParseRef(refPlain) - } - - includeRepo := ref == "" || (!ref.IsTag() && !plumbing.IsHash(refPlain)) - if includeRepo || !loadedDiffData.DifferentialRepos[repoURL] { - newRepoList = append(newRepoList, repoURL) - } - } - - component.Images = newImageList - component.Repos = newRepoList - diffComponents = append(diffComponents, component) - } - - return diffComponents, nil -} diff --git a/src/pkg/packager/creator/normal.go b/src/pkg/packager/creator/normal.go index fed5003380..81478c730e 100644 --- a/src/pkg/packager/creator/normal.go +++ b/src/pkg/packager/creator/normal.go @@ -27,6 +27,7 @@ import ( "github.com/defenseunicorns/zarf/src/pkg/layout" "github.com/defenseunicorns/zarf/src/pkg/message" "github.com/defenseunicorns/zarf/src/pkg/packager/actions" + "github.com/defenseunicorns/zarf/src/pkg/packager/filters" "github.com/defenseunicorns/zarf/src/pkg/packager/sources" "github.com/defenseunicorns/zarf/src/pkg/transform" "github.com/defenseunicorns/zarf/src/pkg/utils" @@ -110,7 +111,8 @@ func (pc *PackageCreator) LoadPackageDefinition(dst *layout.PackagePaths) (pkg t return types.ZarfPackage{}, nil, errors.New(lang.PkgCreateErrDifferentialNoVersion) } - pkg.Components, err = removeCopiesFromComponents(pkg.Components, diffData) + filter := filters.ByDifferentialData(diffData) + pkg.Components, err = filter.Apply(pkg) if err != nil { return types.ZarfPackage{}, nil, err } diff --git a/src/pkg/packager/deploy.go b/src/pkg/packager/deploy.go index ef4495be0a..181a52cb42 100644 --- a/src/pkg/packager/deploy.go +++ b/src/pkg/packager/deploy.go @@ -340,7 +340,7 @@ func (p *Packager) deployComponent(component types.ZarfComponent, noImgChecksum if hasCharts || hasManifests { if charts, err = p.installChartAndManifests(componentPath, component); err != nil { - return charts, fmt.Errorf("unable to install helm chart(s): %w", err) + return charts, err } } diff --git a/src/pkg/packager/filters/diff.go b/src/pkg/packager/filters/diff.go new file mode 100644 index 0000000000..fe722e9741 --- /dev/null +++ b/src/pkg/packager/filters/diff.go @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2021-Present The Zarf Authors + +package filters + +import ( + "fmt" + + "github.com/defenseunicorns/zarf/src/internal/packager/git" + "github.com/defenseunicorns/zarf/src/pkg/transform" + "github.com/defenseunicorns/zarf/src/types" + "github.com/go-git/go-git/v5/plumbing" +) + +// ByDifferentialData filters any images and repos already present in the reference package components. +func ByDifferentialData(diffData *types.DifferentialData) ComponentFilterStrategy { + return &differentialDataFilter{ + diffData: diffData, + } +} + +type differentialDataFilter struct { + diffData *types.DifferentialData +} + +func (f *differentialDataFilter) Apply(pkg types.ZarfPackage) ([]types.ZarfComponent, error) { + diffComponents := []types.ZarfComponent{} + for _, component := range pkg.Components { + filteredImages := []string{} + for _, img := range component.Images { + imgRef, err := transform.ParseImageRef(img) + if err != nil { + return nil, fmt.Errorf("unable to parse image ref %s: %w", img, err) + } + imgTag := imgRef.TagOrDigest + includeImage := imgTag == ":latest" || imgTag == ":stable" || imgTag == ":nightly" + if includeImage || !f.diffData.DifferentialImages[img] { + filteredImages = append(filteredImages, img) + } + } + component.Images = filteredImages + + filteredRepos := []string{} + for _, repoURL := range component.Repos { + _, refPlain, err := transform.GitURLSplitRef(repoURL) + if err != nil { + return nil, err + } + var ref plumbing.ReferenceName + if refPlain != "" { + ref = git.ParseRef(refPlain) + } + includeRepo := ref == "" || (!ref.IsTag() && !plumbing.IsHash(refPlain)) + if includeRepo || !f.diffData.DifferentialRepos[repoURL] { + filteredRepos = append(filteredRepos, repoURL) + } + } + component.Repos = filteredRepos + + diffComponents = append(diffComponents, component) + } + return diffComponents, nil +} diff --git a/src/pkg/packager/creator/differential_test.go b/src/pkg/packager/filters/diff_test.go similarity index 59% rename from src/pkg/packager/creator/differential_test.go rename to src/pkg/packager/filters/diff_test.go index cc616f92ed..8ee64fab84 100644 --- a/src/pkg/packager/creator/differential_test.go +++ b/src/pkg/packager/filters/diff_test.go @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2021-Present The Zarf Authors -package creator +package filters import ( "testing" @@ -10,25 +10,27 @@ import ( "github.com/stretchr/testify/require" ) -func TestRemoveCopiesFromComponents(t *testing.T) { - components := []types.ZarfComponent{ - { - Images: []string{ - "example.com/include-image-tag:latest", - "example.com/image-with-tag:v1", - "example.com/diff-image-with-tag:v1", - "example.com/image-with-digest@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "example.com/diff-image-with-digest@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "example.com/image-with-tag-and-digest:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "example.com/diff-image-with-tag-and-digest:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - }, - Repos: []string{ - "https://example.com/no-ref.git", - "https://example.com/branch.git@refs/heads/main", - "https://example.com/tag.git@v1", - "https://example.com/diff-tag.git@v1", - "https://example.com/commit.git@524980951ff16e19dc25232e9aea8fd693989ba6", - "https://example.com/diff-commit.git@524980951ff16e19dc25232e9aea8fd693989ba6", +func TestCopyFilter(t *testing.T) { + pkg := types.ZarfPackage{ + Components: []types.ZarfComponent{ + { + Images: []string{ + "example.com/include-image-tag:latest", + "example.com/image-with-tag:v1", + "example.com/diff-image-with-tag:v1", + "example.com/image-with-digest@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "example.com/diff-image-with-digest@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "example.com/image-with-tag-and-digest:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "example.com/diff-image-with-tag-and-digest:v1@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + }, + Repos: []string{ + "https://example.com/no-ref.git", + "https://example.com/branch.git@refs/heads/main", + "https://example.com/tag.git@v1", + "https://example.com/diff-tag.git@v1", + "https://example.com/commit.git@524980951ff16e19dc25232e9aea8fd693989ba6", + "https://example.com/diff-commit.git@524980951ff16e19dc25232e9aea8fd693989ba6", + }, }, }, } @@ -46,7 +48,9 @@ func TestRemoveCopiesFromComponents(t *testing.T) { "https://example.com/diff-commit.git@524980951ff16e19dc25232e9aea8fd693989ba6": true, }, } - diffComponents, err := removeCopiesFromComponents(components, &loadedDiffData) + + filter := ByDifferentialData(&loadedDiffData) + diffComponents, err := filter.Apply(pkg) require.NoError(t, err) expectedImages := []string{ diff --git a/src/pkg/packager/inspect.go b/src/pkg/packager/inspect.go index 6a6cc7fac9..56645e2d54 100644 --- a/src/pkg/packager/inspect.go +++ b/src/pkg/packager/inspect.go @@ -5,6 +5,10 @@ package packager import ( + "fmt" + "os" + + "github.com/defenseunicorns/pkg/helpers" "github.com/defenseunicorns/zarf/src/internal/packager/sbom" "github.com/defenseunicorns/zarf/src/pkg/utils" ) @@ -18,7 +22,18 @@ func (p *Packager) Inspect() (err error) { return err } - utils.ColorPrintYAML(p.cfg.Pkg, nil, false) + if p.cfg.InspectOpts.ListImages { + imageList := []string{} + for _, component := range p.cfg.Pkg.Components { + imageList = append(imageList, component.Images...) + } + imageList = helpers.Unique(imageList) + for _, image := range imageList { + fmt.Fprintln(os.Stdout, "-", image) + } + } else { + utils.ColorPrintYAML(p.cfg.Pkg, nil, false) + } sbomDir := p.layout.SBOMs.Path diff --git a/src/test/e2e/06_create_sbom_test.go b/src/test/e2e/06_create_sbom_test.go index 9a6027bb14..d040ba2e05 100644 --- a/src/test/e2e/06_create_sbom_test.go +++ b/src/test/e2e/06_create_sbom_test.go @@ -41,6 +41,10 @@ func TestCreateSBOM(t *testing.T) { _, err = os.ReadFile(filepath.Join(sbomPath, "dos-games", "docker.io_defenseunicorns_zarf-game_multi-tile-dark.json")) require.NoError(t, err) + stdOut, _, err = e2e.Zarf("package", "inspect", pkgName, "--list-images") + require.NoError(t, err) + require.Equal(t, "- defenseunicorns/zarf-game:multi-tile-dark\n", stdOut) + // Pull the current zarf binary version to find the corresponding init package version, stdErr, err := e2e.Zarf("version") require.NoError(t, err, version, stdErr) diff --git a/src/test/e2e/25_helm_test.go b/src/test/e2e/25_helm_test.go index 1926785c9a..e09d6cf47f 100644 --- a/src/test/e2e/25_helm_test.go +++ b/src/test/e2e/25_helm_test.go @@ -130,16 +130,19 @@ func testHelmUninstallRollback(t *testing.T) { // This package contains SBOMable things but was created with --skip-sbom require.Contains(t, string(stdErr), "This package does NOT contain an SBOM.") - // Ensure that this does not leave behind a dos-games chart + // Ensure this leaves behind a dos-games chart. + // We do not want to uninstall charts that had failed installs/upgrades + // to prevent unintentional deletion and/or data loss in production environments. + // https://github.com/defenseunicorns/zarf/issues/2455 helmOut, err := exec.Command("helm", "list", "-n", "dos-games").Output() require.NoError(t, err) - require.NotContains(t, string(helmOut), "zarf-f53a99d4a4dd9a3575bedf59cd42d48d751ae866") + require.Contains(t, string(helmOut), "zarf-f53a99d4a4dd9a3575bedf59cd42d48d751ae866") // Deploy the good package. stdOut, stdErr, err = e2e.Zarf("package", "deploy", goodPath, "--confirm") require.NoError(t, err, stdOut, stdErr) - // Ensure that this does create a dos-games chart + // Ensure this upgrades/fixes the dos-games chart. helmOut, err = exec.Command("helm", "list", "-n", "dos-games").Output() require.NoError(t, err) require.Contains(t, string(helmOut), "zarf-f53a99d4a4dd9a3575bedf59cd42d48d751ae866") @@ -151,7 +154,7 @@ func testHelmUninstallRollback(t *testing.T) { // Ensure that we rollback properly helmOut, err = exec.Command("helm", "history", "-n", "dos-games", "zarf-f53a99d4a4dd9a3575bedf59cd42d48d751ae866", "--max", "1").Output() require.NoError(t, err) - require.Contains(t, string(helmOut), "Rollback to 1") + require.Contains(t, string(helmOut), "Rollback to 4") // Deploy the evil package (again to ensure we check full history) stdOut, stdErr, err = e2e.Zarf("package", "deploy", evilPath, "--timeout", "10s", "--confirm") @@ -160,7 +163,7 @@ func testHelmUninstallRollback(t *testing.T) { // Ensure that we rollback properly helmOut, err = exec.Command("helm", "history", "-n", "dos-games", "zarf-f53a99d4a4dd9a3575bedf59cd42d48d751ae866", "--max", "1").Output() require.NoError(t, err) - require.Contains(t, string(helmOut), "Rollback to 5") + require.Contains(t, string(helmOut), "Rollback to 8") // Remove the package. stdOut, stdErr, err = e2e.Zarf("package", "remove", "dos-games", "--confirm") diff --git a/src/test/e2e/36_custom_retries_test.go b/src/test/e2e/36_custom_retries_test.go index a0f33b94ac..cbe5428a25 100644 --- a/src/test/e2e/36_custom_retries_test.go +++ b/src/test/e2e/36_custom_retries_test.go @@ -28,5 +28,8 @@ func TestRetries(t *testing.T) { stdOut, stdErr, err = e2e.Zarf("package", "deploy", path.Join(tmpDir, pkgName), "--retries", "2", "--timeout", "3s", "--tmpdir", tmpDir, "--confirm") require.Error(t, err, stdOut, stdErr) require.Contains(t, stdErr, "Retrying in 5s") - require.Contains(t, stdErr, "unable to install chart after 2 attempts") + require.Contains(t, e2e.StripMessageFormatting(stdErr), "unable to install chart after 2 attempts") + + _, _, err = e2e.Zarf("package", "remove", "dos-games", "--confirm") + require.NoError(t, err) } diff --git a/src/types/runtime.go b/src/types/runtime.go index 3d9ea5d09a..24a466926e 100644 --- a/src/types/runtime.go +++ b/src/types/runtime.go @@ -38,8 +38,12 @@ type ZarfPackageOptions struct { // ZarfInspectOptions tracks the user-defined preferences during a package inspection. type ZarfInspectOptions struct { - ViewSBOM bool `json:"sbom" jsonschema:"description=View SBOM contents while inspecting the package"` - SBOMOutputDir string `json:"sbomOutput" jsonschema:"description=Location to output an SBOM into after package inspection"` + // View SBOM contents while inspecting the package + ViewSBOM bool + // Location to output an SBOM into after package inspection + SBOMOutputDir string + // ListImages will list the images in the package + ListImages bool } // ZarfFindImagesOptions tracks the user-defined preferences during a prepare find-images search.