Skip to content

Commit

Permalink
Improve Pull API/Options from user perspective. Simplify progress han…
Browse files Browse the repository at this point in the history
…dling
  • Loading branch information
tomekjarosik committed Sep 28, 2024
1 parent 9c57501 commit 6da9d44
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 40 deletions.
5 changes: 5 additions & 0 deletions cmd/geranos/cmd/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,16 @@ func NewCmdPull() *cobra.Command {
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
src := TheAppConfig.Override(args[0])
progress := make(chan transporter.ProgressUpdate)
defer close(progress)

opts := []transporter.Option{
transporter.WithImagesPath(TheAppConfig.ImagesDirectory),
transporter.WithContext(cmd.Context()),
transporter.WithVerbose(viper.GetBool("verbose")),
transporter.WithProgressChannel(progress),
}
go transporter.PrintProgress(progress)
return transporter.Pull(src, opts...)
},
}
Expand Down
27 changes: 27 additions & 0 deletions pkg/transporter/manifest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package transporter

import (
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/mobileinf/geranos/pkg/layout"
)

func ReadManifest(src string, opt ...Option) (*v1.Manifest, error) {
opts := makeOptions(opt...)
ref, err := name.ParseReference(src, name.StrictValidation)
if err != nil {
return nil, err
}
lm := layout.NewMapper(opts.imagesPath, opts.dirimageOptions...)
return lm.ReadManifest(ref)
}

func ReadDigest(src string, opt ...Option) (v1.Hash, error) {
opts := makeOptions(opt...)
ref, err := name.ParseReference(src, name.StrictValidation)
if err != nil {
return v1.Hash{}, err
}
lm := layout.NewMapper(opts.imagesPath, opts.dirimageOptions...)
return lm.ReadDigest(ref)
}
37 changes: 33 additions & 4 deletions pkg/transporter/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/mobileinf/geranos/pkg/dirimage"
"log"
)

type options struct {
Expand All @@ -13,6 +15,7 @@ type options struct {
mountedReference name.Reference
insecure bool
remoteOptions []remote.Option
dirimageOptions []dirimage.Option
refValidation name.Option
workersCount int
verbose bool
Expand Down Expand Up @@ -62,6 +65,12 @@ func WithContext(ctx context.Context) Option {
func WithVerbose(verbose bool) Option {
return func(o *options) {
o.verbose = verbose
if verbose {
o.dirimageOptions = append(o.dirimageOptions, dirimage.WithLogFunction(log.Printf))
} else {
o.dirimageOptions = append(o.dirimageOptions, dirimage.WithLogFunction(func(fmt string, args ...any) {
}))
}
}
}

Expand All @@ -71,6 +80,25 @@ func WithForce(force bool) Option {
}
}

func WithProgressChannel(c chan<- ProgressUpdate) Option {
return func(o *options) {
// Create a new dirimage channel to be used internally
dirimageChan := make(chan dirimage.ProgressUpdate)

// Start a goroutine to convert dirimage.ProgressUpdate to ProgressUpdate
go func() {
for progress := range dirimageChan {
// Convert ProgressUpdate to dirimage.ProgressUpdate and send it
c <- ProgressUpdate{
BytesProcessed: progress.BytesProcessed,
BytesTotal: progress.BytesTotal,
}
}
}()
o.dirimageOptions = append(o.dirimageOptions, dirimage.WithProgressChannel(dirimageChan))
}
}

func makeOptions(opts ...Option) *options {
res := options{
imagesPath: mustExpandUser("~/.geranos/images"),
Expand All @@ -80,10 +108,11 @@ func makeOptions(opts ...Option) *options {
remoteOptions: []remote.Option{
remote.WithAuthFromKeychain(authn.DefaultKeychain),
},
refValidation: name.StrictValidation,
workersCount: 8,
verbose: false,
ctx: context.Background(),
dirimageOptions: []dirimage.Option{},
refValidation: name.StrictValidation,
workersCount: 8,
verbose: false,
ctx: context.Background(),
}
for _, o := range opts {
o(&res)
Expand Down
26 changes: 26 additions & 0 deletions pkg/transporter/progressbar.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package transporter

import (
"fmt"
"github.com/mobileinf/geranos/pkg/dirimage"
"strings"
)

type ProgressUpdate dirimage.ProgressUpdate

func PrintProgress(progress <-chan ProgressUpdate) {
updateProgress := func(progress int64) {
buffer := new(strings.Builder)
fmt.Fprintf(buffer, "\rProgress: [%-100s] %d%%", strings.Repeat("=", int(progress)), progress)
fmt.Print(buffer.String())
}
last := int64(0)
for p := range progress {
current := 100 * p.BytesProcessed / p.BytesTotal
if current != last {
updateProgress(current)
}
last = current
}
fmt.Printf("\n")
}
37 changes: 1 addition & 36 deletions pkg/transporter/pull.go
Original file line number Diff line number Diff line change
@@ -1,33 +1,11 @@
package transporter

import (
"fmt"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/mobileinf/geranos/pkg/dirimage"
"github.com/mobileinf/geranos/pkg/layout"
"log"
"strings"
)

func updateProgress(progress int64) {
buffer := new(strings.Builder)
fmt.Fprintf(buffer, "\rProgress: [%-100s] %d%%", strings.Repeat("=", int(progress)), progress)
fmt.Print(buffer.String())
}

func printProgress(progress <-chan dirimage.ProgressUpdate) {
last := int64(0)
for p := range progress {
current := 100 * p.BytesProcessed / p.BytesTotal
if current != last {
updateProgress(current)
}
last = current
}
fmt.Printf("\n")
}

func Pull(src string, opt ...Option) error {
opts := makeOptions(opt...)
ref, err := name.ParseReference(src, name.StrictValidation)
Expand All @@ -40,20 +18,7 @@ func Pull(src string, opt ...Option) error {
}
// Cache is not important if Sketch is working properly
//img = cache.Image(img, diskcache.NewFilesystemCache(opts.cachePath))
progress := make(chan dirimage.ProgressUpdate)
defer close(progress)

dirimageOptions := []dirimage.Option{
dirimage.WithProgressChannel(progress),
dirimage.WithLogFunction(func(fmt string, args ...any) {
}),
}
if opts.verbose {
dirimageOptions = append(dirimageOptions, dirimage.WithLogFunction(log.Printf))
}

lm := layout.NewMapper(opts.imagesPath, dirimageOptions...)
go printProgress(progress)
lm := layout.NewMapper(opts.imagesPath, opts.dirimageOptions...)
if opts.force {
return lm.Write(opts.ctx, img, ref)
}
Expand Down

0 comments on commit 6da9d44

Please sign in to comment.