Skip to content

Commit

Permalink
Publish / pull UX improvement and minor fixes (#2047)
Browse files Browse the repository at this point in the history
## Description

This improves the pull user experience and also introduces minor fixes
for other UX bugs.

## Related Issue

Fixes #2044 

## Type of change

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [X] Other (security config, docs update, etc)

## Checklist before merging

- [X] Test, docs, adr added or updated as needed
- [X] [Contributor Guide
Steps](https://github.com/defenseunicorns/zarf/blob/main/CONTRIBUTING.md#developer-workflow)
followed
  • Loading branch information
Racer159 authored Oct 3, 2023
1 parent 41a1464 commit a9e7f34
Show file tree
Hide file tree
Showing 12 changed files with 61 additions and 27 deletions.
25 changes: 25 additions & 0 deletions src/extensions/bigbang/bigbang.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,26 @@ func Skeletonize(tmpPaths *layout.ComponentPaths, c types.ZarfComponent) (types.
c.Extensions.BigBang.ValuesFiles[valuesIdx] = rel
}

for fluxPatchFileIdx, fluxPatchFile := range c.Extensions.BigBang.FluxPatchFiles {
// Define the name as the file name without the extension.
baseName := strings.TrimSuffix(fluxPatchFile, filepath.Ext(fluxPatchFile))

// Replace non-alphanumeric characters with a dash.
baseName = nonAlphnumeric.ReplaceAllString(baseName, "-")

// Add the skeleton name prefix.
skelName := fmt.Sprintf("bb-ext-skeleton-flux-patches-%s.yaml", baseName)

rel := filepath.Join(layout.TempDir, skelName)
dst := filepath.Join(tmpPaths.Base, rel)

if err := utils.CreatePathAndCopy(fluxPatchFile, dst); err != nil {
return c, err
}

c.Extensions.BigBang.FluxPatchFiles[fluxPatchFileIdx] = rel
}

return c, nil
}

Expand All @@ -278,6 +298,11 @@ func Compose(pathAncestry string, c types.ZarfComponent) types.ZarfComponent {
c.Extensions.BigBang.ValuesFiles[valuesIdx] = parentRel
}

for fluxPatchFileIdx, fluxPatchFile := range c.Extensions.BigBang.FluxPatchFiles {
parentRel := filepath.Join(pathAncestry, fluxPatchFile)
c.Extensions.BigBang.FluxPatchFiles[fluxPatchFileIdx] = parentRel
}

return c
}

Expand Down
3 changes: 2 additions & 1 deletion src/internal/packager/images/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ func (i *ImageConfig) PullAll() (map[transform.Image]v1.Image, error) {
doneSaving := make(chan int)
var progressBarWaitGroup sync.WaitGroup
progressBarWaitGroup.Add(1)
go utils.RenderProgressBarForLocalDirWrite(i.ImagesPath, totalBytes, &progressBarWaitGroup, doneSaving, fmt.Sprintf("Pulling %d images", imageCount))
updateText := fmt.Sprintf("Pulling %d images", imageCount)
go utils.RenderProgressBarForLocalDirWrite(i.ImagesPath, totalBytes, &progressBarWaitGroup, doneSaving, updateText, updateText)

// Spawn a goroutine for each layer to write it to disk using crane

Expand Down
4 changes: 2 additions & 2 deletions src/pkg/oci/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ func NewOrasRemote(url string) (*OrasRemote, error) {
}

copyOpts := oras.DefaultCopyOptions
copyOpts.OnCopySkipped = o.printLayerSuccess
copyOpts.PostCopy = o.printLayerSuccess
copyOpts.OnCopySkipped = o.printLayerSkipped
copyOpts.PostCopy = o.printLayerCopied
o.CopyOpts = copyOpts

o.WithContext(context.TODO())
Expand Down
3 changes: 2 additions & 1 deletion src/pkg/oci/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@ func (o *OrasRemote) CopyWithProgress(layers []ocispec.Descriptor, store oras.Ta
doneSaving := make(chan int)
var wg sync.WaitGroup
wg.Add(1)
go utils.RenderProgressBarForLocalDirWrite(destinationDir, estimatedBytes, &wg, doneSaving, "Pulling")
successText := fmt.Sprintf("Pulling %q", helpers.OCIURLPrefix+o.repo.Reference.String())
go utils.RenderProgressBarForLocalDirWrite(destinationDir, estimatedBytes, &wg, doneSaving, "Pulling", successText)
_, err := oras.Copy(o.ctx, o.repo, o.repo.Reference.String(), store, o.repo.Reference.String(), *copyOpts)
if err != nil {
return err
Expand Down
22 changes: 16 additions & 6 deletions src/pkg/oci/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,26 @@ func ReferenceFromMetadata(registryLocation string, metadata *types.ZarfMetadata
return ref.String(), nil
}

// printLayerSuccess prints a success message to the console when a layer has been successfully published/pulled to/from a registry.
func (o *OrasRemote) printLayerSuccess(_ context.Context, desc ocispec.Descriptor) error {
// printLayerSkipped prints a debug message when a layer has been successfully skipped.
func (o *OrasRemote) printLayerSkipped(_ context.Context, desc ocispec.Descriptor) error {
return o.printLayer(desc, "skipped")
}

// printLayerCopied prints a debug message when a layer has been successfully copied to/from a registry.
func (o *OrasRemote) printLayerCopied(_ context.Context, desc ocispec.Descriptor) error {
return o.printLayer(desc, "copied")
}

// printLayer prints a debug message when a layer has been successfully published/pulled to/from a registry.
func (o *OrasRemote) printLayer(desc ocispec.Descriptor, suffix string) error {
title := desc.Annotations[ocispec.AnnotationTitle]
var format string
var layerInfo string
if title != "" {
format = fmt.Sprintf("%s %s", desc.Digest.Encoded()[:12], utils.First30last30(title))
layerInfo = fmt.Sprintf("%s %s", desc.Digest.Encoded()[:12], utils.First30last30(title))
} else {
format = fmt.Sprintf("%s [%s]", desc.Digest.Encoded()[:12], desc.MediaType)
layerInfo = fmt.Sprintf("%s [%s]", desc.Digest.Encoded()[:12], desc.MediaType)
}
message.Successf(format)
message.Debugf("%s (%s)", layerInfo, suffix)
return nil
}

Expand Down
3 changes: 3 additions & 0 deletions src/pkg/packager/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,9 @@ func (p *Packager) mergeComponentOverrides(target *types.ZarfComponent, override
if override.Extensions.BigBang.ValuesFiles != nil {
target.Extensions.BigBang.ValuesFiles = append(target.Extensions.BigBang.ValuesFiles, override.Extensions.BigBang.ValuesFiles...)
}
if override.Extensions.BigBang.FluxPatchFiles != nil {
target.Extensions.BigBang.FluxPatchFiles = append(target.Extensions.BigBang.FluxPatchFiles, override.Extensions.BigBang.FluxPatchFiles...)
}
}

// Merge deprecated scripts for backwards compatibility with older zarf binaries.
Expand Down
8 changes: 3 additions & 5 deletions src/pkg/packager/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,6 @@ func (p *Packager) Create() (err error) {

p.layout = p.layout.AddImages()

message.HeaderInfof("📦 PACKAGE IMAGES")

pulled := map[transform.Image]v1.Image{}

doPull := func() error {
Expand Down Expand Up @@ -245,9 +243,9 @@ func (p *Packager) Create() (err error) {
flags = "--insecure"
}
message.Title("To inspect/deploy/pull:", "")
message.ZarfCommand("package inspect oci://%s %s", p.remote.Repo().Reference, flags)
message.ZarfCommand("package deploy oci://%s %s", p.remote.Repo().Reference, flags)
message.ZarfCommand("package pull oci://%s %s", p.remote.Repo().Reference, flags)
message.ZarfCommand("package inspect %s %s", helpers.OCIURLPrefix+p.remote.Repo().Reference.String(), flags)
message.ZarfCommand("package deploy %s %s", helpers.OCIURLPrefix+p.remote.Repo().Reference.String(), flags)
message.ZarfCommand("package pull %s %s", helpers.OCIURLPrefix+p.remote.Repo().Reference.String(), flags)
} else {
// Use the output path if the user specified it.
packageName := filepath.Join(p.cfg.CreateOpts.Output, p.GetPackageName())
Expand Down
3 changes: 2 additions & 1 deletion src/pkg/packager/publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/defenseunicorns/zarf/src/pkg/oci"
"github.com/defenseunicorns/zarf/src/pkg/packager/sources"
"github.com/defenseunicorns/zarf/src/pkg/utils"
"github.com/defenseunicorns/zarf/src/pkg/utils/helpers"
"github.com/defenseunicorns/zarf/src/types"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras-go/v2/content"
Expand Down Expand Up @@ -115,7 +116,7 @@ func (p *Packager) Publish() (err error) {
Name: fmt.Sprintf("import-%s", c.Name),
Import: types.ZarfComponentImport{
ComponentName: c.Name,
URL: fmt.Sprintf("oci://%s", p.remote.Repo().Reference),
URL: helpers.OCIURLPrefix + p.remote.Repo().Reference.String(),
},
})
}
Expand Down
6 changes: 1 addition & 5 deletions src/pkg/packager/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ package packager

import (
"fmt"

"github.com/defenseunicorns/zarf/src/pkg/message"
)

// Pull pulls a Zarf package and saves it as a compressed tarball.
Expand All @@ -16,12 +14,10 @@ func (p *Packager) Pull() (err error) {
return fmt.Errorf("pull does not support optional components")
}

tb, err := p.source.Collect(p.cfg.PullOpts.OutputDirectory)
_, err = p.source.Collect(p.cfg.PullOpts.OutputDirectory)
if err != nil {
return err
}

message.Infof("Pulled %q into %q", p.cfg.PkgOpts.PackageSource, tb)

return nil
}
8 changes: 4 additions & 4 deletions src/pkg/utils/bytes.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,25 +58,25 @@ func ByteFormat(inputNum float64, precision int) string {

// RenderProgressBarForLocalDirWrite creates a progress bar that continuously tracks the progress of writing files to a local directory and all of its subdirectories.
// NOTE: This function runs infinitely until the completeChan is triggered, this function should be run in a goroutine while a different thread/process is writing to the directory.
func RenderProgressBarForLocalDirWrite(filepath string, expectedTotal int64, wg *sync.WaitGroup, completeChan chan int, updateText string) {
func RenderProgressBarForLocalDirWrite(filepath string, expectedTotal int64, wg *sync.WaitGroup, completeChan chan int, updateText string, successText string) {

// Create a progress bar
title := fmt.Sprintf("Pulling Zarf package data (%s of %s)", ByteFormat(float64(0), 2), ByteFormat(float64(expectedTotal), 2))
title := fmt.Sprintf("%s (%s of %s)", updateText, ByteFormat(float64(0), 2), ByteFormat(float64(expectedTotal), 2))
progressBar := message.NewProgressBar(expectedTotal, title)

for {
select {
case <-completeChan:
// Send success message
progressBar.Successf("%s (%s)", updateText, ByteFormat(float64(expectedTotal), 2))
progressBar.Successf("%s (%s)", successText, ByteFormat(float64(expectedTotal), 2))
wg.Done()
return

default:
// Read the directory size
currentBytes, dirErr := GetDirSize(filepath)
if dirErr != nil {
message.Debugf("unable to get the updated progress of the image pull: %s", dirErr.Error())
message.Debugf("unable to get updated progress: %s", dirErr.Error())
time.Sleep(200 * time.Millisecond)
continue
}
Expand Down
1 change: 0 additions & 1 deletion src/pkg/utils/helpers/url.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (

// Nonstandard URL schemes or prefixes
const (
OCIURLScheme = "oci"
OCIURLPrefix = "oci://"

SGETURLPrefix = "sget://"
Expand Down
2 changes: 1 addition & 1 deletion src/test/e2e/50_oci_package_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (suite *RegistryClientTestSuite) Test_1_Pull() {
// Pull the package via OCI.
stdOut, stdErr, err := e2e.Zarf("package", "pull", "oci://"+ref, "--insecure")
suite.NoError(err, stdOut, stdErr)
suite.Contains(stdErr, fmt.Sprintf("Pulled %q", "oci://"+ref))
suite.Contains(stdErr, fmt.Sprintf("Pulling %q", "oci://"+ref))

// Verify the package was pulled.
suite.FileExists(out)
Expand Down

0 comments on commit a9e7f34

Please sign in to comment.