diff --git a/src/cmd/package.go b/src/cmd/package.go index 58e714a543..5a2d17cef7 100644 --- a/src/cmd/package.go +++ b/src/cmd/package.go @@ -14,6 +14,8 @@ import ( "runtime" "strings" + "github.com/zarf-dev/zarf/src/pkg/logger" + "github.com/AlecAivazis/survey/v2" "github.com/defenseunicorns/pkg/helpers/v2" "github.com/spf13/cobra" @@ -47,11 +49,12 @@ var packageCreateCmd = &cobra.Command{ Short: lang.CmdPackageCreateShort, Long: lang.CmdPackageCreateLong, RunE: func(cmd *cobra.Command, args []string) error { + l := logger.From(cmd.Context()) pkgConfig.CreateOpts.BaseDir = setBaseDirectory(args) var isCleanPathRegex = regexp.MustCompile(`^[a-zA-Z0-9\_\-\/\.\~\\:]+$`) if !isCleanPathRegex.MatchString(config.CommonOptions.CachePath) { - message.Warnf(lang.CmdPackageCreateCleanPathErr, config.ZarfDefaultCachePath) + l.Warn("invalid characters in Zarf cache path, using default", "cfg", config.ZarfDefaultCachePath, "default", config.ZarfDefaultCachePath) config.CommonOptions.CachePath = config.ZarfDefaultCachePath } @@ -59,13 +62,18 @@ var packageCreateCmd = &cobra.Command{ pkgConfig.CreateOpts.SetVariables = helpers.TransformAndMergeMap( v.GetStringMapString(common.VPkgCreateSet), pkgConfig.CreateOpts.SetVariables, strings.ToUpper) - pkgClient, err := packager.New(&pkgConfig) + pkgClient, err := packager.New(&pkgConfig, + packager.WithContext(cmd.Context()), + ) if err != nil { return err } defer pkgClient.ClearTempPaths() - err = pkgClient.Create(cmd.Context()) + // TODO(mkcp): Finish migrating packager.Create + err = pkgClient.Create() + + // TODO(mkcp): Migrate linterrs to logger var lintErr *lint.LintError if errors.As(err, &lintErr) { common.PrintFindings(lintErr) diff --git a/src/cmd/tools/zarf.go b/src/cmd/tools/zarf.go index df516f9506..1bf56fd574 100644 --- a/src/cmd/tools/zarf.go +++ b/src/cmd/tools/zarf.go @@ -173,7 +173,7 @@ var updateCredsCmd = &cobra.Command{ } // Update Zarf 'init' component Helm releases if present - h := helm.NewClusterOnly(&types.PackagerConfig{}, template.GetZarfVariableConfig(), newState, c) + h := helm.NewClusterOnly(&types.PackagerConfig{}, template.GetZarfVariableConfig(cmd.Context()), newState, c) if slices.Contains(args, message.RegistryKey) && newState.RegistryInfo.IsInternal() { err = h.UpdateZarfRegistryValues(ctx) diff --git a/src/config/lang/english.go b/src/config/lang/english.go index 38717db929..cb1683dde8 100644 --- a/src/config/lang/english.go +++ b/src/config/lang/english.go @@ -270,7 +270,6 @@ $ zarf package mirror-resources \ CmdPackageCreateFlagDifferential = "[beta] Build a package that only contains the differential changes from local resources and differing remote resources from the specified previously built package" CmdPackageCreateFlagRegistryOverride = "Specify a map of domains to override on package create when pulling images (e.g. --registry-override docker.io=dockerio-reg.enterprise.intranet)" CmdPackageCreateFlagFlavor = "The flavor of components to include in the resulting package (i.e. have a matching or empty \"only.flavor\" key)" - CmdPackageCreateCleanPathErr = "Invalid characters in Zarf cache path, defaulting to %s" CmdPackageDeployFlagConfirm = "Confirms package deployment without prompting. ONLY use with packages you trust. Skips prompts to review SBOM, configure variables, select optional components and review potential breaking changes." CmdPackageDeployFlagAdoptExistingResources = "Adopts any pre-existing K8s resources into the Helm charts managed by Zarf. ONLY use when you have existing deployments you want Zarf to takeover." diff --git a/src/internal/packager/template/template.go b/src/internal/packager/template/template.go index 872754ce4d..662e7a2647 100644 --- a/src/internal/packager/template/template.go +++ b/src/internal/packager/template/template.go @@ -5,9 +5,10 @@ package template import ( + "context" "encoding/base64" "fmt" - "log/slog" + "github.com/zarf-dev/zarf/src/pkg/logger" "strings" "github.com/zarf-dev/zarf/src/api/v1alpha1" @@ -26,7 +27,7 @@ const ( ) // GetZarfVariableConfig gets a variable configuration specific to Zarf -func GetZarfVariableConfig() *variables.VariableConfig { +func GetZarfVariableConfig(ctx context.Context) *variables.VariableConfig { prompt := func(variable v1alpha1.InteractiveVariable) (value string, err error) { if config.CommonOptions.Confirm { return variable.Default, nil @@ -34,10 +35,7 @@ func GetZarfVariableConfig() *variables.VariableConfig { return interactive.PromptVariable(variable) } - return variables.New( - "zarf", - prompt, - slog.New(message.ZarfHandler{})) + return variables.New("zarf", prompt, logger.From(ctx)) } // GetZarfTemplates returns the template keys and values to be used for templating. diff --git a/src/pkg/packager/actions/actions.go b/src/pkg/packager/actions/actions.go index dbef82b613..158333997f 100644 --- a/src/pkg/packager/actions/actions.go +++ b/src/pkg/packager/actions/actions.go @@ -7,6 +7,7 @@ package actions import ( "context" "fmt" + "github.com/zarf-dev/zarf/src/pkg/logger" "regexp" "runtime" "strings" @@ -24,7 +25,7 @@ import ( // Run runs all provided actions. func Run(ctx context.Context, defaultCfg v1alpha1.ZarfComponentActionDefaults, actions []v1alpha1.ZarfComponentAction, variableConfig *variables.VariableConfig) error { if variableConfig == nil { - variableConfig = template.GetZarfVariableConfig() + variableConfig = template.GetZarfVariableConfig(ctx) } for _, a := range actions { @@ -37,13 +38,13 @@ func Run(ctx context.Context, defaultCfg v1alpha1.ZarfComponentActionDefaults, a // Run commands that a component has provided. func runAction(ctx context.Context, defaultCfg v1alpha1.ZarfComponentActionDefaults, action v1alpha1.ZarfComponentAction, variableConfig *variables.VariableConfig) error { - var ( - cmdEscaped string - out string - err error + var cmdEscaped string + var out string + var err error + l := logger.From(ctx) + cmd := action.Cmd - cmd = action.Cmd - ) + l.Error("TODO: Refactor runAction") // If the action is a wait, convert it to a command. if action.Wait != nil { diff --git a/src/pkg/packager/common.go b/src/pkg/packager/common.go index 1325a70b46..47defa9b52 100644 --- a/src/pkg/packager/common.go +++ b/src/pkg/packager/common.go @@ -8,6 +8,7 @@ import ( "context" "errors" "fmt" + "github.com/zarf-dev/zarf/src/pkg/logger" "os" "slices" "strings" @@ -30,6 +31,7 @@ import ( // Packager is the main struct for managing packages. type Packager struct { + ctx context.Context cfg *types.PackagerConfig variableConfig *variables.VariableConfig state *types.ZarfState @@ -65,36 +67,41 @@ func WithTemp(base string) Modifier { } } +// WithContext sets the packager's context +func WithContext(ctx context.Context) Modifier { + return func(p *Packager) { + p.ctx = ctx + } +} + /* New creates a new package instance with the provided config. Note: This function creates a tmp directory that should be cleaned up with p.ClearTempPaths(). */ func New(cfg *types.PackagerConfig, mods ...Modifier) (*Packager, error) { + var err error if cfg == nil { return nil, fmt.Errorf("no config provided") } - var ( - err error - pkgr = &Packager{ - cfg: cfg, - } - ) + pkgr := &Packager{cfg: cfg} + for _, mod := range mods { + mod(pkgr) + } - pkgr.variableConfig = template.GetZarfVariableConfig() + l := logger.From(pkgr.ctx) + pkgr.variableConfig = template.GetZarfVariableConfig(pkgr.ctx) + cacheDir := config.CommonOptions.CachePath + tmpDir := config.CommonOptions.TempDirectory if config.CommonOptions.TempDirectory != "" { // If the cache directory is within the temp directory, warn the user - if strings.HasPrefix(config.CommonOptions.CachePath, config.CommonOptions.TempDirectory) { - message.Warnf("The cache directory (%q) is within the temp directory (%q) and will be removed when the temp directory is cleaned up", config.CommonOptions.CachePath, config.CommonOptions.TempDirectory) + if strings.HasPrefix(cacheDir, tmpDir) { + l.Warn("the cache directory is within the temp directory and will be removed when the temp directory is cleaned up", "cacheDir", cacheDir, "tmpDir", tmpDir) } } - for _, mod := range mods { - mod(pkgr) - } - // Fill the source if it wasn't provided - note source can be nil if the package is being created if pkgr.source == nil && pkgr.cfg.CreateOpts.BaseDir == "" { pkgr.source, err = sources.New(&pkgr.cfg.PkgOpts) @@ -109,7 +116,7 @@ func New(cfg *types.PackagerConfig, mods ...Modifier) (*Packager, error) { if err != nil { return nil, fmt.Errorf("unable to create package temp paths: %w", err) } - message.Debug("Using temporary directory:", dir) + l.Debug("using temporary directory", "tmpDir", dir) pkgr.layout = layout.New(dir) } @@ -119,8 +126,16 @@ func New(cfg *types.PackagerConfig, mods ...Modifier) (*Packager, error) { // ClearTempPaths removes the temp directory and any files within it. func (p *Packager) ClearTempPaths() { // Remove the temp directory, but don't throw an error if it fails - _ = os.RemoveAll(p.layout.Base) - _ = os.RemoveAll(layout.SBOMDir) + l := logger.From(p.ctx) + l.Debug("clearing temp paths") + err := os.RemoveAll(p.layout.Base) + if err != nil { + l.Error(err.Error(), "basePath", p.layout.Base) + } + err2 := os.RemoveAll(layout.SBOMDir) + if err2 != nil { + l.Error(err2.Error(), "SBOMDir", layout.SBOMDir) + } } // GetVariableConfig returns the variable configuration for the packager. diff --git a/src/pkg/packager/create.go b/src/pkg/packager/create.go index 517726eba4..a6275171fc 100755 --- a/src/pkg/packager/create.go +++ b/src/pkg/packager/create.go @@ -5,47 +5,53 @@ package packager import ( - "context" "fmt" + "github.com/zarf-dev/zarf/src/pkg/logger" "os" "github.com/defenseunicorns/pkg/helpers/v2" "github.com/zarf-dev/zarf/src/config" "github.com/zarf-dev/zarf/src/pkg/layout" - "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/pkg/packager/creator" ) // Create generates a Zarf package tarball for a given PackageConfig and optional base directory. -func (p *Packager) Create(ctx context.Context) error { +func (p *Packager) Create() error { cwd, err := os.Getwd() if err != nil { return err } + l := logger.From(p.ctx) - if err := os.Chdir(p.cfg.CreateOpts.BaseDir); err != nil { - return fmt.Errorf("unable to access directory %q: %w", p.cfg.CreateOpts.BaseDir, err) + // Set basedir + baseDir := p.cfg.CreateOpts.BaseDir + if err := os.Chdir(baseDir); err != nil { + return fmt.Errorf("unable to access directory %q: %w", baseDir, err) } + l.Info("using build directory", "baseDir", baseDir) - message.Note(fmt.Sprintf("Using build directory %s", p.cfg.CreateOpts.BaseDir)) - + // Setup package creator pc := creator.NewPackageCreator(p.cfg.CreateOpts, cwd) - if err := helpers.CreatePathAndCopy(layout.ZarfYAML, p.layout.ZarfYAML); err != nil { return err } - pkg, warnings, err := pc.LoadPackageDefinition(ctx, p.layout) + // Load package def and store on packager config + // TODO(mkcp): Migrate to logger + pkg, warnings, err := pc.LoadPackageDefinition(p.ctx, p.layout) if err != nil { return err } p.cfg.Pkg = pkg + // TODO(mkcp): Interactive isolate with slog + // Maybe just comment this out point at if !p.confirmAction(config.ZarfCreateStage, warnings, nil) { return fmt.Errorf("package creation canceled") } - if err := pc.Assemble(ctx, p.layout, p.cfg.Pkg.Components, p.cfg.Pkg.Metadata.Architecture); err != nil { + // TODO(mkcp): Migrate to logger + if err := pc.Assemble(p.ctx, p.layout, p.cfg.Pkg.Components, p.cfg.Pkg.Metadata.Architecture); err != nil { return err } @@ -54,5 +60,9 @@ func (p *Packager) Create(ctx context.Context) error { return err } - return pc.Output(ctx, p.layout, &p.cfg.Pkg) + // TODO(mkcp): migrate pc.Output to logger + if err = pc.Output(p.ctx, p.layout, &p.cfg.Pkg); err != nil { + return err + } + return nil } diff --git a/src/pkg/packager/creator/normal.go b/src/pkg/packager/creator/normal.go index 3b7d4a7698..314b60ca4c 100644 --- a/src/pkg/packager/creator/normal.go +++ b/src/pkg/packager/creator/normal.go @@ -8,6 +8,8 @@ import ( "context" "errors" "fmt" + "github.com/zarf-dev/zarf/src/pkg/logger" + "github.com/zarf-dev/zarf/src/pkg/message" "math/rand" "os" "path/filepath" @@ -27,7 +29,6 @@ import ( "github.com/zarf-dev/zarf/src/internal/packager/kustomize" "github.com/zarf-dev/zarf/src/internal/packager/sbom" "github.com/zarf-dev/zarf/src/pkg/layout" - "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/pkg/packager/actions" "github.com/zarf-dev/zarf/src/pkg/packager/filters" "github.com/zarf-dev/zarf/src/pkg/packager/sources" @@ -119,9 +120,10 @@ func (pc *PackageCreator) LoadPackageDefinition(ctx context.Context, src *layout return pkg, warnings, nil } -// Assemble assembles all of the package assets into Zarf's tmp directory layout. +// Assemble copies all package assets into Zarf's tmp directory layout. func (pc *PackageCreator) Assemble(ctx context.Context, dst *layout.PackagePaths, components []v1alpha1.ZarfComponent, arch string) error { var imageList []transform.Image + l := logger.From(ctx) skipSBOMFlagUsed := pc.createOpts.SkipSBOM componentSBOMs := map[string]*layout.ComponentSBOM{} @@ -131,21 +133,24 @@ func (pc *PackageCreator) Assemble(ctx context.Context, dst *layout.PackagePaths onFailure := func() { if err := actions.Run(ctx, onCreate.Defaults, onCreate.OnFailure, nil); err != nil { - message.Debugf("unable to run component failure action: %s", err.Error()) + l.Debug("unable to run component failure action", "error", err.Error()) } } + // TODO(mkcp): Migrate to logger if err := pc.addComponent(ctx, component, dst); err != nil { onFailure() return fmt.Errorf("unable to add component %q: %w", component.Name, err) } + // TODO(mkcp): Migrate to logger if err := actions.Run(ctx, onCreate.Defaults, onCreate.OnSuccess, nil); err != nil { onFailure() return fmt.Errorf("unable to run component success action: %w", err) } if !skipSBOMFlagUsed { + // TODO(mkcp): Migrate to logger componentSBOM, err := pc.getFilesToSBOM(component, dst) if err != nil { return fmt.Errorf("unable to create component SBOM: %w", err) @@ -156,6 +161,7 @@ func (pc *PackageCreator) Assemble(ctx context.Context, dst *layout.PackagePaths } // Combine all component images into a single entry for efficient layer reuse. + // TODO(mkcp): Migrate to logger for _, src := range component.Images { refInfo, err := transform.ParseImageRef(src) if err != nil { @@ -173,8 +179,6 @@ func (pc *PackageCreator) Assemble(ctx context.Context, dst *layout.PackagePaths // Images are handled separately from other component assets. if len(imageList) > 0 { - message.HeaderInfof("📦 PACKAGE IMAGES") - dst.AddImages() cachePath, err := config.GetAbsCachePath() @@ -189,6 +193,7 @@ func (pc *PackageCreator) Assemble(ctx context.Context, dst *layout.PackagePaths CacheDirectory: filepath.Join(cachePath, layout.ImagesDir), } + // TODO(mkcp): Migrate to logger pulled, err := images.Pull(ctx, pullCfg) if err != nil { return err @@ -216,12 +221,13 @@ func (pc *PackageCreator) Assemble(ctx context.Context, dst *layout.PackagePaths // Ignore SBOM creation if the flag is set. if skipSBOMFlagUsed { - message.Debug("Skipping image SBOM processing per --skip-sbom flag") - } else { - dst.AddSBOMs() - if err := sbom.Catalog(ctx, componentSBOMs, sbomImageList, dst); err != nil { - return fmt.Errorf("unable to create an SBOM catalog for the package: %w", err) - } + l.Debug("skipping image SBOM processing per --skip-sbom flag") + return nil + } + + dst.AddSBOMs() + if err := sbom.Catalog(ctx, componentSBOMs, sbomImageList, dst); err != nil { + return fmt.Errorf("unable to create an SBOM catalog for the package: %w", err) } return nil diff --git a/src/types/packager.go b/src/types/packager.go index fb3f68bfd5..0540e228e2 100644 --- a/src/types/packager.go +++ b/src/types/packager.go @@ -4,10 +4,17 @@ // Package types contains all the types used by Zarf. package types -import "github.com/zarf-dev/zarf/src/api/v1alpha1" +import ( + "context" + + "github.com/zarf-dev/zarf/src/api/v1alpha1" +) // PackagerConfig is the main struct that the packager uses to hold high-level options. type PackagerConfig struct { + // Context provides deadlines, cancellations, and values throughout the API. + Context context.Context + // CreateOpts tracks the user-defined options used to create the package CreateOpts ZarfCreateOptions