Skip to content

Commit

Permalink
feat: migrate package create to slog (#3132)
Browse files Browse the repository at this point in the history
Signed-off-by: Kit Patella <kit@defenseunicorns.com>
Co-authored-by: Austin Abro <37223396+AustinAbro321@users.noreply.github.com>
  • Loading branch information
mkcp and AustinAbro321 authored Oct 25, 2024
1 parent 22dd49a commit 413b56c
Show file tree
Hide file tree
Showing 20 changed files with 458 additions and 117 deletions.
3 changes: 3 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ linters-settings:
- (*github.com/spf13/cobra.Command).MarkFlagRequired
- (*github.com/spf13/pflag.FlagSet).MarkHidden
- (*github.com/spf13/pflag.FlagSet).MarkDeprecated
sloglint:
no-mixed-args: true
key-naming-case: camel
issues:
# Revive rules that are disabled by default.
include:
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@ require (
github.com/go-git/go-git/v5 v5.12.0
github.com/goccy/go-yaml v1.12.0
github.com/gofrs/flock v0.12.1
github.com/golang-cz/devslog v0.0.11
github.com/google/go-containerregistry v0.20.2
github.com/gosuri/uitable v0.0.4
github.com/invopop/jsonschema v0.12.0
github.com/mholt/archiver/v3 v3.5.1
github.com/moby/moby v27.3.1+incompatible
github.com/opencontainers/image-spec v1.1.0
github.com/phsym/console-slog v0.3.1
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.20.5
github.com/pterm/pterm v0.12.79
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,8 @@ github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-cz/devslog v0.0.11 h1:v4Yb9o0ZpuZ/D8ZrtVw1f9q5XrjnkxwHF1XmWwO8IHg=
github.com/golang-cz/devslog v0.0.11/go.mod h1:bSe5bm0A7Nyfqtijf1OMNgVJHlWEuVSXnkuASiE1vV8=
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
Expand Down Expand Up @@ -1420,6 +1422,8 @@ github.com/petergtz/pegomock v2.9.0+incompatible h1:BKfb5XfkJfehe5T+O1xD4Zm26Sb9
github.com/petergtz/pegomock v2.9.0+incompatible/go.mod h1:nuBLWZpVyv/fLo56qTwt/AUau7jgouO1h7bEvZCq82o=
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI=
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
github.com/phsym/console-slog v0.3.1 h1:Fuzcrjr40xTc004S9Kni8XfNsk+qrptQmyR+wZw9/7A=
github.com/phsym/console-slog v0.3.1/go.mod h1:oJskjp/X6e6c0mGpfP8ELkfKUsrkDifYRAqJQgmdDS0=
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
Expand Down
11 changes: 10 additions & 1 deletion src/cmd/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -47,25 +49,32 @@ 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) {
// TODO(mkcp): Remove message on logger release
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
}

v := common.GetViper()
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())

// NOTE(mkcp): LintErrors are rendered with a table
var lintErr *lint.LintError
if errors.As(err, &lintErr) {
common.PrintFindings(lintErr)
Expand Down
67 changes: 53 additions & 14 deletions src/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,6 @@ func preRun(cmd *cobra.Command, _ []string) error {
if cmd.Parent() == nil {
skipLogFile = true
}
err := setupMessage(LogLevelCLI, skipLogFile, NoColor)
if err != nil {
return err
}

// Configure logger and add it to cmd context.
l, err := setupLogger(LogLevelCLI, LogFormat)
Expand All @@ -95,6 +91,21 @@ func preRun(cmd *cobra.Command, _ []string) error {
ctx := logger.WithContext(cmd.Context(), l)
cmd.SetContext(ctx)

// Configure the global message instance.
var disableMessage bool
if LogFormat != "" {
disableMessage = true
}
err = setupMessage(messageCfg{
level: LogLevelCLI,
skipLogFile: skipLogFile,
noColor: NoColor,
featureDisabled: disableMessage,
})
if err != nil {
return err
}

// Print out config location
common.PrintViperConfigUsed(cmd.Context())
return nil
Expand All @@ -116,14 +127,22 @@ func Execute(ctx context.Context) {
if err == nil {
return
}

// Check if we need to use the default err printer
defaultPrintCmds := []string{"helm", "yq", "kubectl"}
comps := strings.Split(cmd.CommandPath(), " ")
if len(comps) > 1 && comps[1] == "tools" && slices.Contains(defaultPrintCmds, comps[2]) {
cmd.PrintErrln(cmd.ErrPrefix(), err.Error())
} else {
errParagraph := message.Paragraph(err.Error())
pterm.Error.Println(errParagraph)
os.Exit(1)
}

// TODO(mkcp): Remove message on logger release
errParagraph := message.Paragraph(err.Error())
pterm.Error.Println(errParagraph)

// NOTE(mkcp): The default logger is set with user flags downstream in rootCmd's preRun func, so we don't have
// access to it on Execute's ctx.
logger.Default().Error(err.Error())
os.Exit(1)
}

Expand Down Expand Up @@ -184,14 +203,34 @@ func setupLogger(level, format string) (*slog.Logger, error) {
return l, nil
}

type messageCfg struct {
level string
skipLogFile bool
noColor bool
// featureDisabled is a feature flag that disables it
featureDisabled bool
}

// setupMessage configures message while we migrate over to logger.
func setupMessage(logLevel string, skipLogFile, noColor bool) error {
// TODO(mkcp): Delete no-color
if noColor {
func setupMessage(cfg messageCfg) error {
// HACK(mkcp): Discard message logs if feature is disabled. message calls InitializePTerm once in its init() fn so
// this ends up being a messy solution.
if cfg.featureDisabled {
// Discard all* PTerm messages. *see below
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
}

if cfg.noColor {
message.DisableColor()
}

if logLevel != "" {
level := cfg.level
if cfg.level != "" {
match := map[string]message.LogLevel{
// NOTE(mkcp): Add error for forwards compatibility with logger
"error": message.WarnLevel,
Expand All @@ -200,12 +239,12 @@ func setupMessage(logLevel string, skipLogFile, noColor bool) error {
"debug": message.DebugLevel,
"trace": message.TraceLevel,
}
lvl, ok := match[logLevel]
lvl, ok := match[level]
if !ok {
return errors.New("invalid log level, valid options are warn, info, debug, error, and trace")
}
message.SetLogLevel(lvl)
message.Debug("Log level set to " + logLevel)
message.Debug("Log level set to " + level)
}

// Disable progress bars for CI envs
Expand All @@ -214,7 +253,7 @@ func setupMessage(logLevel string, skipLogFile, noColor bool) error {
message.NoProgress = true
}

if !skipLogFile {
if !cfg.skipLogFile {
ts := time.Now().Format("2006-01-02-15-04-05")
f, err := os.CreateTemp("", fmt.Sprintf("zarf-%s-*.log", ts))
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/tools/zarf.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
63 changes: 59 additions & 4 deletions src/internal/packager/helm/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ import (
"context"
"errors"
"fmt"
"github.com/zarf-dev/zarf/src/pkg/logger"
"log/slog"
"os"
"path/filepath"
"strings"
"time"

"github.com/defenseunicorns/pkg/helpers/v2"
"helm.sh/helm/v3/pkg/action"
Expand Down Expand Up @@ -38,7 +41,9 @@ func (h *Helm) PackageChart(ctx context.Context, cosignKeyPath string) error {
// check if the chart is a git url with a ref (if an error is returned url will be empty)
isGitURL := strings.HasSuffix(url, ".git")
if err != nil {
// TODO(mkcp): Remove message on logger release
message.Debugf("unable to parse the url, continuing with %s", h.chart.URL)
logger.From(ctx).Debug("unable to parse the url, continuing", "url", h.chart.URL)
}

if isGitURL {
Expand Down Expand Up @@ -68,6 +73,13 @@ func (h *Helm) PackageChart(ctx context.Context, cosignKeyPath string) error {

// PackageChartFromLocalFiles creates a chart archive from a path to a chart on the host os.
func (h *Helm) PackageChartFromLocalFiles(ctx context.Context, cosignKeyPath string) error {
l := logger.From(ctx)
l.Info("processing local helm chart",
"name", h.chart.Name,
"version", h.chart.Version,
"path", h.chart.LocalPath,
)
// TODO(mkcp): Remove message on logger release
spinner := message.NewProgressSpinner("Processing helm chart %s:%s from %s", h.chart.Name, h.chart.Version, h.chart.LocalPath)
defer spinner.Stop()

Expand All @@ -94,7 +106,12 @@ func (h *Helm) PackageChartFromLocalFiles(ctx context.Context, cosignKeyPath str
saved = filepath.Join(temp, filepath.Base(h.chart.LocalPath))
err = helpers.CreatePathAndCopy(h.chart.LocalPath, saved)
}
defer os.RemoveAll(temp)
defer func(l *slog.Logger) {
err := os.RemoveAll(temp)
if err != nil {
l.Error(err.Error())
}
}(l)

if err != nil {
return fmt.Errorf("unable to save the archive and create the package %s: %w", saved, err)
Expand All @@ -108,11 +125,19 @@ func (h *Helm) PackageChartFromLocalFiles(ctx context.Context, cosignKeyPath str

spinner.Success()

l.Debug("done processing local helm chart",
"name", h.chart.Name,
"version", h.chart.Version,
"path", h.chart.LocalPath,
)
return nil
}

// PackageChartFromGit is a special implementation of chart archiving that supports the https://p1.dso.mil/#/products/big-bang/ model.
func (h *Helm) PackageChartFromGit(ctx context.Context, cosignKeyPath string) error {
l := logger.From(ctx)
l.Info("processing helm chart", "name", h.chart.Name)
// TODO(mkcp): Remove message on logger release
spinner := message.NewProgressSpinner("Processing helm chart %s", h.chart.Name)
defer spinner.Stop()

Expand All @@ -121,7 +146,11 @@ func (h *Helm) PackageChartFromGit(ctx context.Context, cosignKeyPath string) er
if err != nil {
return err
}
defer os.RemoveAll(gitPath)
defer func(l *slog.Logger) {
if err := os.RemoveAll(gitPath); err != nil {
l.Error(err.Error())
}
}(l)

// Set the directory for the chart and package it
h.chart.LocalPath = filepath.Join(gitPath, h.chart.GitPath)
Expand All @@ -130,6 +159,14 @@ func (h *Helm) PackageChartFromGit(ctx context.Context, cosignKeyPath string) er

// DownloadPublishedChart loads a specific chart version from a remote repo.
func (h *Helm) DownloadPublishedChart(ctx context.Context, cosignKeyPath string) error {
l := logger.From(ctx)
l.Info("processing helm chart",
"name", h.chart.Name,
"version", h.chart.Version,
"repo", h.chart.URL,
)
start := time.Now()
// TODO(mkcp): Remove message on logger release
spinner := message.NewProgressSpinner("Processing helm chart %s:%s from repo %s", h.chart.Name, h.chart.Version, h.chart.URL)
defer spinner.Stop()

Expand All @@ -146,7 +183,12 @@ func (h *Helm) DownloadPublishedChart(ctx context.Context, cosignKeyPath string)

// Not returning the error here since the repo file is only needed if we are pulling from a repo that requires authentication
if err != nil {
// TODO(mkcp): Remove message on logger release
message.Debugf("Unable to load the repo file at %q: %s", pull.Settings.RepositoryConfig, err.Error())
l.Debug("unable to load the repo file",
"path", pull.Settings.RepositoryConfig,
"error", err.Error(),
)
}

var username string
Expand Down Expand Up @@ -202,7 +244,12 @@ func (h *Helm) DownloadPublishedChart(ctx context.Context, cosignKeyPath string)
if err = helpers.CreateDirectory(temp, helpers.ReadWriteExecuteUser); err != nil {
return fmt.Errorf("unable to create helm chart temp directory: %w", err)
}
defer os.RemoveAll(temp)
defer func(l *slog.Logger) {
err := os.RemoveAll(temp)
if err != nil {
l.Error(err.Error())
}
}(l)

saved, _, err := chartDownloader.DownloadTo(chartURL, pull.Version, temp)
if err != nil {
Expand All @@ -222,7 +269,12 @@ func (h *Helm) DownloadPublishedChart(ctx context.Context, cosignKeyPath string)
}

spinner.Success()

l.Debug("done downloading helm chart",
"name", h.chart.Name,
"version", h.chart.Version,
"repo", h.chart.URL,
"duration", time.Since(start),
)
return nil
}

Expand Down Expand Up @@ -304,13 +356,16 @@ func (h *Helm) buildChartDependencies() error {
var notFoundErr *downloader.ErrRepoNotFound
if errors.As(err, &notFoundErr) {
// If we encounter a repo not found error point the user to `zarf tools helm repo add`
// TODO(mkcp): Remove message on logger release
message.Warnf("%s. Please add the missing repo(s) via the following:", notFoundErr.Error())
for _, repository := range notFoundErr.Repos {
// TODO(mkcp): Remove message on logger release
message.ZarfCommand(fmt.Sprintf("tools helm repo add <your-repo-name> %s", repository))
}
return err
}
if err != nil {
// TODO(mkcp): Remove message on logger release
message.ZarfCommand("tools helm dependency build --verify")
message.Warnf("Unable to perform a rebuild of Helm dependencies: %s", err.Error())
return err
Expand Down
Loading

0 comments on commit 413b56c

Please sign in to comment.