Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to per-image tunnels, CRC on tags, and progressbar for image pushes #1590

Merged
merged 23 commits into from
Apr 18, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8228d89
Switch to per-image tunnels and progressbar
Racer159 Apr 11, 2023
616fc5d
Merge branch 'main' into 1568-registry-hanging-investigations
Racer159 Apr 11, 2023
35ede8d
Fix connect test
Racer159 Apr 12, 2023
98cc5eb
Fix gte check
Racer159 Apr 12, 2023
d9fb4bf
Close the tunnel manually instead of defer
Racer159 Apr 12, 2023
512caf9
Merge branch 'main' into 1568-registry-hanging-investigations
Racer159 Apr 12, 2023
1a637d0
Add support for no provided tag
Racer159 Apr 12, 2023
3f30601
Merge branch 'main' into 1568-registry-hanging-investigations
Racer159 Apr 13, 2023
4814d73
Fix logic for digests and non-tagged images
Racer159 Apr 13, 2023
89ab543
Fix registry scale down behavior
Racer159 Apr 14, 2023
9d89dbb
Explain more about when state is loaded
Racer159 Apr 14, 2023
82b8a7f
Show spinners when waiting for cluster connections
Racer159 Apr 14, 2023
07f398e
Add a warning for breaking changes that may exist
Racer159 Apr 16, 2023
55bc0e0
Merge branch 'main' into 1568-registry-hanging-investigations
Racer159 Apr 16, 2023
d8aa018
Fix web ui test
Racer159 Apr 17, 2023
5132129
Merge branch 'main' into 1568-registry-hanging-investigations
Racer159 Apr 17, 2023
bbdbd8e
Address feedback
Racer159 Apr 18, 2023
a0f072c
Merge branch 'main' into 1568-registry-hanging-investigations
Racer159 Apr 18, 2023
ba39205
Fix init test
Racer159 Apr 18, 2023
8ba22dd
Resolve more test errors
Racer159 Apr 18, 2023
7b3c924
Merge branch 'main' into 1568-registry-hanging-investigations
Racer159 Apr 18, 2023
55b8bc2
Merge branch 'main' into 1568-registry-hanging-investigations
Racer159 Apr 18, 2023
6a765d6
Merge branch 'main' into 1568-registry-hanging-investigations
Racer159 Apr 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/distros/k3s/common/zarf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ components:
only:
localOS: linux
description: >
*** REQUIRES ROOT ***
Install K3s, certified Kubernetes distribution built for IoT & Edge computing.
*** REQUIRES ROOT (not sudo) ***
Install K3s, a certified Kubernetes distribution built for IoT & Edge computing.
K3s provides the cluster need for Zarf running in Appliance Mode as well as can
host a low-resource Gitops Service if not using an existing Kubernetes platform.
actions:
Expand Down
2 changes: 2 additions & 0 deletions src/cmd/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ var packageDeployCmd = &cobra.Command{
pkgClient := packager.NewOrDie(&pkgConfig)
defer pkgClient.ClearTempPaths()

pterm.Println()

// Deploy the package
if err := pkgClient.Deploy(); err != nil {
message.Fatalf(err, "Failed to deploy package: %s", err.Error())
Expand Down
5 changes: 3 additions & 2 deletions src/internal/cluster/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ func NewClusterWithWait(timeout time.Duration, withSpinner bool) (*Cluster, erro

// NewCluster creates a new cluster instance without waiting for the cluster to be ready.
func NewCluster() (*Cluster, error) {
var err error
c := &Cluster{}
c.Kube, _ = k8s.New(message.Debugf, labels)
return c, nil
c.Kube, err = k8s.New(message.Debugf, labels)
return c, err
}
9 changes: 5 additions & 4 deletions src/internal/cluster/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ import (

// Zarf Cluster Constants.
const (
ZarfNamespace = "zarf"
ZarfStateSecretName = "zarf-state"
ZarfStateDataKey = "state"
ZarfPackageInfoLabel = "package-deploy-info"
ZarfNamespace = "zarf"
ZarfStateSecretName = "zarf-state"
ZarfStateDataKey = "state"
ZarfPackageInfoLabel = "package-deploy-info"
ZarfInitPackageInfoName = "zarf-package-init"
)

// InitZarfState initializes the Zarf state with the given temporary directory and init configs.
Expand Down
15 changes: 15 additions & 0 deletions src/internal/cluster/zarf.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,21 @@ func (c *Cluster) GetDeployedZarfPackages() ([]types.DeployedPackage, error) {
return deployedPackages, nil
}

// GetDeployedZarfInitPackage gets the metadata information about the currently deployed init package in the cluster.
// We determine what packages have been deployed to the cluster by looking for specific secrets in the Zarf namespace.
func (c *Cluster) GetDeployedZarfInitPackage() (types.DeployedPackage, error) {
Racer159 marked this conversation as resolved.
Show resolved Hide resolved
var deployedInitPackage = types.DeployedPackage{}

// Get the secret that describes the deployed init package
secret, err := c.Kube.GetSecret(ZarfNamespace, ZarfInitPackageInfoName)
if err != nil {
return deployedInitPackage, err
}

err = json.Unmarshal(secret.Data["data"], &deployedInitPackage)
return deployedInitPackage, err
}

// StripZarfLabelsAndSecretsFromNamespaces removes metadata and secrets from existing namespaces no longer manged by Zarf.
func (c *Cluster) StripZarfLabelsAndSecretsFromNamespaces() {
spinner := message.NewProgressSpinner("Removing zarf metadata & secrets from existing namespaces not managed by Zarf")
Expand Down
74 changes: 48 additions & 26 deletions src/pkg/message/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ const (
// NoProgress tracks whether spinner/progress bars show updates.
var NoProgress bool

// Separator is a string of 100 spaces to provide visual separation between elements.
var Separator = strings.Repeat(" ", 100)

var logLevel = InfoLevel

// Write logs to stderr and a buffer for logFile generation.
Expand Down Expand Up @@ -107,93 +110,94 @@ func Debug(payload ...any) {
// Debugf prints a debug message.
func Debugf(format string, a ...any) {
message := fmt.Sprintf(format, a...)
debugPrinter(3, message)
Debug(message)
}

// Error prints an error message.
func Error(err any, message string) {
debugPrinter(2, err)
Debug(err)
Warnf(message)
}

// ErrorWebf prints an error message and returns a web response.
func ErrorWebf(err any, w http.ResponseWriter, format string, a ...any) {
debugPrinter(2, err)
Debug(err)
message := fmt.Sprintf(format, a...)
Warn(message)
http.Error(w, message, http.StatusInternalServerError)
}

// Errorf prints an error message.
func Errorf(err any, format string, a ...any) {
debugPrinter(2, err)
Debug(err)
Warnf(format, a...)
}

// Warn prints a warning message.
func Warn(message string) {
Warnf(message)
Warnf("%s", message)
}

// Warnf prints a warning message.
func Warnf(format string, a ...any) {
message := paragraph(format, a...)
message := Paragraph(format, a...)
pterm.Warning.Println(message)
}

// Fatal prints a fatal error message and exits with a 1.
func Fatal(err any, message string) {
debugPrinter(2, err)
Debug(err)
errorPrinter(2).Println(message)
debugPrinter(2, string(debug.Stack()))
Debug(string(debug.Stack()))
os.Exit(1)
}

// Fatalf prints a fatal error message and exits with a 1.
func Fatalf(err any, format string, a ...any) {
debugPrinter(2, err)
message := paragraph(format, a...)
errorPrinter(2).Println(message)
debugPrinter(2, string(debug.Stack()))
os.Exit(1)
message := Paragraph(format, a...)
Fatal(err, message)
}

// Info prints an info message.
func Info(message string) {
Infof(message)
Infof("%s", message)
}

// Infof prints an info message.
func Infof(format string, a ...any) {
if logLevel > 0 {
message := paragraph(format, a...)
message := Paragraph(format, a...)
pterm.Info.Println(message)
}
}

// Successf prints a success message.
func Successf(format string, a ...any) {
message := paragraph(format, a...)
message := Paragraph(format, a...)
pterm.Success.Println(message)
}

// Question prints a formatted message used in conjunction with a user prompt.
func Question(text string) {
pterm.Println()
message := paragraph(text)
pterm.FgMagenta.Println(message)
Questionf("%s", text)
}

// Notef prints a formatted yellow message.
func Notef(format string, a ...any) {
message := fmt.Sprintf(format, a...)
Note(message)
// Questionf prints a formatted message used in conjunction with a user prompt.
func Questionf(format string, a ...any) {
pterm.Println()
message := Paragraph(format, a...)
pterm.FgLightGreen.Println(message)
}

// Note prints a formatted yellow message.
func Note(text string) {
Notef("%s", text)
}

// Notef prints a formatted yellow message.
func Notef(format string, a ...any) {
pterm.Println()
message := paragraph(text)
message := Paragraph(format, a...)
pterm.FgYellow.Println(message)
}

Expand All @@ -210,6 +214,18 @@ func HeaderInfof(format string, a ...any) {
Printfln(message + strings.Repeat(" ", padding))
}

// HorizontalRule prints a white horizontal rule to separate the terminal
func HorizontalRule() {
pterm.Println()
pterm.Println(strings.Repeat("━", 100))
}

// HorizontalRule prints a yellow horizontal rule to separate the terminal
func HorizontalNoteRule() {
pterm.Println()
pterm.FgYellow.Println(strings.Repeat("━", 100))
}

// JSONValue prints any value as JSON.
func JSONValue(value any) string {
bytes, err := json.MarshalIndent(value, "", " ")
Expand All @@ -219,8 +235,14 @@ func JSONValue(value any) string {
return string(bytes)
}

func paragraph(format string, a ...any) string {
return pterm.DefaultParagraph.WithMaxWidth(100).Sprintf(format, a...)
// Paragraph formats text into a 100 column paragraph
func Paragraph(format string, a ...any) string {
return Paragraphn(100, format, a...)
}

// Paragraphn formats text into an n column paragraph
func Paragraphn(n int, format string, a ...any) string {
return pterm.DefaultParagraph.WithMaxWidth(n).Sprintf(format, a...)
}

func debugPrinter(offset int, a ...any) {
Expand Down
9 changes: 4 additions & 5 deletions src/pkg/packager/components.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ import (
"github.com/pterm/pterm"
)

const horizontalRule = "───────────────────────────────────────────────────────────────────────────────────────"

func (p *Packager) getValidComponents() []types.ZarfComponent {
message.Debugf("packager.getValidComponents()")

Expand Down Expand Up @@ -182,13 +180,12 @@ func (p *Packager) confirmOptionalComponent(component types.ZarfComponent) (conf
return component.Default
}

pterm.Println(horizontalRule)
message.HorizontalRule()

displayComponent := component
displayComponent.Description = ""
utils.ColorPrintYAML(displayComponent)
if component.Description != "" {
pterm.Println()
message.Question(component.Description)
}

Expand Down Expand Up @@ -221,7 +218,7 @@ func (p *Packager) confirmChoiceGroup(componentGroup []types.ZarfComponent) type
message.Fatalf(nil, "You must specify at least one component from the group %#v when using the --confirm flag.", componentNames)
}

pterm.Println(horizontalRule)
message.HorizontalRule()

var chosen int
var options []string
Expand All @@ -236,6 +233,8 @@ func (p *Packager) confirmChoiceGroup(componentGroup []types.ZarfComponent) type
Options: options,
}

pterm.Println()

if err := survey.AskOne(prompt, &chosen); err != nil {
message.Fatalf(nil, "Component selection canceled: %s", err.Error())
}
Expand Down
64 changes: 64 additions & 0 deletions src/pkg/packager/deprecated/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,37 @@
package deprecated

import (
"strings"

"github.com/Masterminds/semver/v3"
"github.com/defenseunicorns/zarf/src/config"
"github.com/defenseunicorns/zarf/src/pkg/message"
"github.com/defenseunicorns/zarf/src/pkg/utils"
"github.com/defenseunicorns/zarf/src/types"
"github.com/pterm/pterm"
)

type BreakingChange struct {
version *semver.Version
title string
mitigation string
}

// List of migrations tracked in the zarf.yaml build data.
const (
ScriptsToActionsMigrated = "scripts-to-actions"
PluralizeSetVariable = "pluralize-set-variable"
)

// List of breaking changes to warn the user of.
var breakingChanges = []BreakingChange{
{
version: semver.New(0, 26, 0, "", ""),
title: "Zarf container images are now mutated based on tag instead of repository name.",
mitigation: "Reinitialize the cluster using v0.26.0 or later and redeploy existing packages to update the image references (you can view existing packages with 'zarf package list' and view cluster images with 'zarf tools registry catalog').",
},
}

// MigrateComponent runs all migrations on a component.
// Build should be empty on package create, but include just in case someone copied a zarf.yaml from a zarf package.
func MigrateComponent(build types.ZarfBuildData, c types.ZarfComponent) types.ZarfComponent {
Expand All @@ -37,3 +58,46 @@ func MigrateComponent(build types.ZarfBuildData, c types.ZarfComponent) types.Za
// Future migrations here.
return c
}

// PrintBreakingChanges prints the breaking changes between the provided version and the current CLIVersion
func PrintBreakingChanges(deployedZarfVersion string) {
deployedSemver, err := semver.NewVersion(deployedZarfVersion)

Racer159 marked this conversation as resolved.
Show resolved Hide resolved
if err == nil {
applicableBreakingChanges := []BreakingChange{}

// Calculate the applicable breaking changes
for _, breakingChange := range breakingChanges {
if deployedSemver.LessThan(breakingChange.version) {
applicableBreakingChanges = append(applicableBreakingChanges, breakingChange)
}
}

if len(applicableBreakingChanges) > 0 {
// Print header information
message.HorizontalNoteRule()
pterm.Println()
message.Warn(pterm.Bold.Sprint("Potential Breaking Changes Detected Between Versions"))

// Print information about the versions
format := pterm.FgYellow.Sprint("CLI version ") + "%s" + pterm.FgYellow.Sprint(" is being used to deploy to a cluster that was initialized with ") +
"%s" + pterm.FgYellow.Sprint(". Between these versions there are the following breaking changes to consider:")
cliVersion := pterm.Bold.Sprintf(config.CLIVersion)
deployedVersion := pterm.Bold.Sprintf(deployedZarfVersion)
pterm.Printfln("\n%s", message.Paragraphn(120, format, cliVersion, deployedVersion))

// Print each applicable breaking change
for idx, applicableBreakingChange := range applicableBreakingChanges {
titleFormat := pterm.Bold.Sprintf("\n %d. ", idx+1) + "%s"
title := pterm.FgYellow.Sprint(applicableBreakingChange.title)

pterm.Printfln(titleFormat, title)

mitigationText := message.Paragraphn(96, "%s", pterm.FgLightCyan.Sprint(applicableBreakingChange.mitigation))

pterm.Printfln("\n - %s", pterm.Bold.Sprint("Mitigation:"))
pterm.Printfln(" %s", strings.ReplaceAll(mitigationText, "\n", "\n "))
}
}
}
}
Loading