diff --git a/src/cmd/initialize.go b/src/cmd/initialize.go index 0543f97749..d2fe5d5d35 100644 --- a/src/cmd/initialize.go +++ b/src/cmd/initialize.go @@ -18,6 +18,7 @@ import ( "github.com/zarf-dev/zarf/src/cmd/common" "github.com/zarf-dev/zarf/src/config" "github.com/zarf-dev/zarf/src/config/lang" + "github.com/zarf-dev/zarf/src/pkg/logger" "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/pkg/packager" "github.com/zarf-dev/zarf/src/pkg/packager/sources" @@ -70,6 +71,9 @@ var initCmd = &cobra.Command{ if err != nil { return err } + // Since the new logger ignores pterm output the credential table is no longer printed on init. + // This note is the intended replacement, rather than printing creds by default. + logger.From(ctx).Info("init complete. To get credentials for Zarf deployed services run `zarf tools get-creds`") return nil }, } @@ -110,28 +114,26 @@ func findInitPackage(ctx context.Context, initPackageName string) (string, error return filepath.Join(absCachePath, initPackageName), nil } + if config.CommonOptions.Confirm { + return "", lang.ErrInitNotFound + } + // Finally, if the init-package doesn't exist in the cache directory, suggest downloading it downloadCacheTarget, err := downloadInitPackage(ctx, absCachePath) if err != nil { - if errors.Is(err, lang.ErrInitNotFound) { - return "", err - } return "", fmt.Errorf("failed to download the init package: %w", err) } return downloadCacheTarget, nil } func downloadInitPackage(ctx context.Context, cacheDirectory string) (string, error) { - if config.CommonOptions.Confirm { - return "", lang.ErrInitNotFound - } - + l := logger.From(ctx) url := zoci.GetInitPackageURL(config.CLIVersion) // Give the user the choice to download the init-package and note that this does require an internet connection message.Question(fmt.Sprintf(lang.CmdInitPullAsk, url)) - message.Note(lang.CmdInitPullNote) + l.Info("the init package was not found locally, but can be pulled in connected environments", "url", fmt.Sprintf("oci://%s", url)) var confirmDownload bool prompt := &survey.Confirm{ diff --git a/src/cmd/root.go b/src/cmd/root.go index 63513c7104..86f01eb1cc 100644 --- a/src/cmd/root.go +++ b/src/cmd/root.go @@ -222,8 +222,6 @@ func setupMessage(cfg messageCfg) error { message.InitializePTerm(io.Discard) // Disable all progress bars and spinners message.NoProgress = true - // Ensures no user input is needed while we maintain backwards compatibility with message - config.CommonOptions.Confirm = true return nil } diff --git a/src/pkg/cluster/injector.go b/src/pkg/cluster/injector.go index 8586934710..ff9aac1fb9 100644 --- a/src/pkg/cluster/injector.go +++ b/src/pkg/cluster/injector.go @@ -27,6 +27,7 @@ import ( "github.com/zarf-dev/zarf/src/config" "github.com/zarf-dev/zarf/src/internal/healthchecks" + "github.com/zarf-dev/zarf/src/pkg/logger" "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/pkg/transform" "github.com/zarf-dev/zarf/src/pkg/utils" @@ -34,6 +35,8 @@ import ( // StartInjection initializes a Zarf injection into the cluster. func (c *Cluster) StartInjection(ctx context.Context, tmpDir, imagesDir string, injectorSeedSrcs []string) error { + l := logger.From(ctx) + start := time.Now() // Stop any previous running injection before starting. err := c.StopInjection(ctx) if err != nil { @@ -42,6 +45,7 @@ func (c *Cluster) StartInjection(ctx context.Context, tmpDir, imagesDir string, spinner := message.NewProgressSpinner("Attempting to bootstrap the seed image into the cluster") defer spinner.Stop() + l.Info("creating Zarf injector resources") resReq := corev1.ResourceRequirements{ Requests: corev1.ResourceList{ @@ -123,11 +127,15 @@ func (c *Cluster) StartInjection(ctx context.Context, tmpDir, imagesDir string, } spinner.Success() + l.Debug("done with injection", "duration", time.Since(start)) return nil } // StopInjection handles cleanup once the seed registry is up. func (c *Cluster) StopInjection(ctx context.Context) error { + start := time.Now() + l := logger.From(ctx) + l.Debug("deleting injector resources") err := c.Clientset.CoreV1().Pods(ZarfNamespaceName).Delete(ctx, "injector", metav1.DeleteOptions{}) if err != nil && !kerrors.IsNotFound(err) { return err @@ -183,6 +191,7 @@ func (c *Cluster) StopInjection(ctx context.Context) error { if err != nil { return err } + l.Debug("done deleting injector resources", "duration", time.Since(start)) return nil } diff --git a/src/pkg/cluster/state.go b/src/pkg/cluster/state.go index 0ad4dac449..82ba76b28e 100644 --- a/src/pkg/cluster/state.go +++ b/src/pkg/cluster/state.go @@ -37,12 +37,14 @@ const ( // InitZarfState initializes the Zarf state with the given temporary directory and init configs. func (c *Cluster) InitZarfState(ctx context.Context, initOptions types.ZarfInitOptions) error { + l := logger.From(ctx) spinner := message.NewProgressSpinner("Gathering cluster state information") defer spinner.Stop() // Attempt to load an existing state prior to init. // NOTE: We are ignoring the error here because we don't really expect a state to exist yet. spinner.Updatef("Checking cluster for existing Zarf deployment") + l.Debug("checking cluster for existing Zarf deployment") state, err := c.LoadZarfState(ctx) if err != nil && !kerrors.IsNotFound(err) { return fmt.Errorf("failed to check for existing state: %w", err) @@ -52,7 +54,7 @@ func (c *Cluster) InitZarfState(ctx context.Context, initOptions types.ZarfInitO if state == nil { state = &types.ZarfState{} spinner.Updatef("New cluster, no prior Zarf deployments found") - + l.Debug("new cluster, no prior Zarf deployments found") if initOptions.ApplianceMode { // If the K3s component is being deployed, skip distro detection. state.Distro = DistroIsK3s @@ -75,6 +77,7 @@ func (c *Cluster) InitZarfState(ctx context.Context, initOptions types.ZarfInitO if state.Distro != DistroIsUnknown { spinner.Updatef("Detected K8s distro %s", state.Distro) + l.Debug("Detected K8s distro", "name", state.Distro) } // Setup zarf agent PKI @@ -90,7 +93,8 @@ func (c *Cluster) InitZarfState(ctx context.Context, initOptions types.ZarfInitO } // Mark existing namespaces as ignored for the zarf agent to prevent mutating resources we don't own. for _, namespace := range namespaceList.Items { - spinner.Updatef("Marking existing namespace %s as ignored by Zarf Agent", namespace.Name) + l.Debug("marking namespace as ignored by Zarf Agent", "name", namespace.Name) + if namespace.Labels == nil { // Ensure label map exists to avoid nil panic namespace.Labels = make(map[string]string) @@ -106,6 +110,7 @@ func (c *Cluster) InitZarfState(ctx context.Context, initOptions types.ZarfInitO // Try to create the zarf namespace. spinner.Updatef("Creating the Zarf namespace") + l.Debug("creating the Zarf namespace") zarfNamespace := NewZarfManagedNamespace(ZarfNamespaceName) err = func() error { _, err := c.Clientset.CoreV1().Namespaces().Create(ctx, zarfNamespace, metav1.CreateOptions{}) @@ -154,17 +159,21 @@ func (c *Cluster) InitZarfState(ctx context.Context, initOptions types.ZarfInitO initOptions.ArtifactServer.FillInEmptyValues() state.ArtifactServer = initOptions.ArtifactServer } else { + // TODO (@austinabro321) validate immediately in `zarf init` if these are set and not equal and error out if so if helpers.IsNotZeroAndNotEqual(initOptions.GitServer, state.GitServer) { message.Warn("Detected a change in Git Server init options on a re-init. Ignoring... To update run:") message.ZarfCommand("tools update-creds git") + l.Warn("ignoring change in git sever init options on re-init, to update run `zarf tools update-creds git`") } if helpers.IsNotZeroAndNotEqual(initOptions.RegistryInfo, state.RegistryInfo) { message.Warn("Detected a change in Image Registry init options on a re-init. Ignoring... To update run:") message.ZarfCommand("tools update-creds registry") + l.Warn("ignoring change to registry init options on re-init, to update run `zarf tools update-creds registry`") } if helpers.IsNotZeroAndNotEqual(initOptions.ArtifactServer, state.ArtifactServer) { message.Warn("Detected a change in Artifact Server init options on a re-init. Ignoring... To update run:") message.ZarfCommand("tools update-creds artifact") + l.Warn("ignoring change to registry init options on re-init, to update run `zarf tools update-creds registry`") } } diff --git a/src/pkg/logger/logger.go b/src/pkg/logger/logger.go index 82e98d44e6..c812f7b3ca 100644 --- a/src/pkg/logger/logger.go +++ b/src/pkg/logger/logger.go @@ -37,6 +37,22 @@ var ( Error = Level(slog.LevelError) // 8 ) +// String returns the string representation of the Level. +func (l Level) String() string { + switch l { + case Debug: + return "debug" + case Info: + return "info" + case Warn: + return "warn" + case Error: + return "error" + default: + return "unknown" + } +} + // validLevels is a set that provides an ergonomic way to check if a level is a member of the set. var validLevels = map[Level]bool{ Debug: true, @@ -99,6 +115,18 @@ var ( DestinationNone Destination = io.Discard ) +// can't define method on Destination type +func destinationString(d Destination) string { + switch { + case d == DestinationDefault: + return "os.Stderr" + case d == DestinationNone: + return "io.Discard" + default: + return "unknown" + } +} + // Config is configuration for a logger. type Config struct { // Level sets the log level. An empty value corresponds to Info aka 0. @@ -107,6 +135,15 @@ type Config struct { Destination } +// LogValue of config +func (c Config) LogValue() slog.Value { + return slog.GroupValue( + slog.String("level", c.Level.String()), + slog.Any("format", c.Format), + slog.Any("Destination", destinationString(c.Destination)), + ) +} + // ConfigDefault returns a Config with defaults like Text formatting at Info level writing to Stderr. func ConfigDefault() Config { return Config{ diff --git a/src/pkg/packager/deploy.go b/src/pkg/packager/deploy.go index 133dba9e8d..f21ddba5c2 100644 --- a/src/pkg/packager/deploy.go +++ b/src/pkg/packager/deploy.go @@ -285,7 +285,7 @@ func (p *Packager) deployInitComponent(ctx context.Context, component v1alpha1.Z // Do cleanup for when we inject the seed registry during initialization if isSeedRegistry { if err := p.cluster.StopInjection(ctx); err != nil { - return nil, fmt.Errorf("unable to seed the Zarf Registry: %w", err) + return nil, fmt.Errorf("failed to delete injector resources: %w", err) } } diff --git a/src/pkg/zoci/pull.go b/src/pkg/zoci/pull.go index 1984f87ffd..54e58cb4ed 100644 --- a/src/pkg/zoci/pull.go +++ b/src/pkg/zoci/pull.go @@ -35,7 +35,6 @@ var ( // - zarf.yaml.sig func (r *Remote) PullPackage(ctx context.Context, destinationDir string, concurrency int, layersToPull ...ocispec.Descriptor) (_ []ocispec.Descriptor, err error) { isPartialPull := len(layersToPull) > 0 - r.Log().Debug(fmt.Sprintf("Pulling %s", r.Repo().Reference)) manifest, err := r.FetchRoot(ctx) if err != nil { @@ -52,11 +51,14 @@ func (r *Remote) PullPackage(ctx context.Context, destinationDir string, concurr } layersToPull = append(layersToPull, manifest.Config) + layerSize := oci.SumDescsSize(layersToPull) + // TODO (@austinabro321) change this and other r.Log() calls to the proper slog format + r.Log().Info(fmt.Sprintf("Pulling %s, size: %s", r.Repo().Reference, utils.ByteFormat(float64(layerSize), 2))) + // Create a thread to update a progress bar as we save the package to disk doneSaving := make(chan error) successText := fmt.Sprintf("Pulling %q", helpers.OCIURLPrefix+r.Repo().Reference.String()) - layerSize := oci.SumDescsSize(layersToPull) go utils.RenderProgressBarForLocalDirWrite(destinationDir, layerSize, doneSaving, "Pulling", successText) dst, err := file.New(destinationDir)