Skip to content

Commit

Permalink
feat(oci-layout): support oras tag,oras repo tags and oras pull (
Browse files Browse the repository at this point in the history
…#753)

Related to #378

Signed-off-by: Billy Zha <jinzha1@microsoft.com>
  • Loading branch information
qweeah authored Jan 17, 2023
1 parent 6447e8e commit 2e9b0a6
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 38 deletions.
51 changes: 28 additions & 23 deletions cmd/oras/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,10 @@ import (
type pullOptions struct {
option.Cache
option.Common
option.Remote
option.Platform
option.Target

concurrency int
targetRef string
KeepOldFiles bool
IncludeSubject bool
PathTraversal bool
Expand All @@ -55,34 +54,40 @@ func pullCmd() *cobra.Command {
Short: "Pull files from remote registry",
Long: `Pull files from remote registry
Example - Pull all files:
Example - Pull artifact files from a registry:
oras pull localhost:5000/hello:latest
Example - Recursively pulling all files, including subjects of hello:latest:
Example - Recursively pulling all files from a registry, including subjects of hello:latest:
oras pull --include-subject localhost:5000/hello:latest
Example - Pull files from the insecure registry:
Example - Pull files from an insecure registry:
oras pull --insecure localhost:5000/hello:latest
Example - Pull files from the HTTP registry:
oras pull --plain-http localhost:5000/hello:latest
Example - Pull files with local cache:
Example - Pull files from a registry with local cache:
export ORAS_CACHE=~/.oras/cache
oras pull localhost:5000/hello:latest
Example - Pull files with certain platform:
Example - Pull files from a registry with certain platform:
oras pull --platform linux/arm/v5 localhost:5000/hello:latest
Example - Pull all files with concurrency level tuned:
oras pull --concurrency 6 localhost:5000/hello:latest
Example - Pull artifact files from an OCI layout folder 'layout-dir':
oras pull --oci-layout layout-dir:latest
Example - Pull artifact files from an OCI layout archive 'layout.tar':
oras pull --oci-layout layout.tar:latest
`,
Args: cobra.ExactArgs(1),
PreRunE: func(cmd *cobra.Command, args []string) error {
opts.RawReference = args[0]
return option.Parse(&opts)
},
RunE: func(cmd *cobra.Command, args []string) error {
opts.targetRef = args[0]
return runPull(opts)
},
}
Expand All @@ -98,23 +103,12 @@ Example - Pull all files with concurrency level tuned:
}

func runPull(opts pullOptions) error {
var printed sync.Map
repo, err := opts.NewRepository(opts.targetRef, opts.Common)
if err != nil {
return err
}
if repo.Reference.Reference == "" {
return errors.NewErrInvalidReference(repo.Reference)
}
src, err := opts.CachedTarget(repo)
if err != nil {
return err
}

// Copy Options
var printed sync.Map
copyOptions := oras.DefaultCopyOptions
copyOptions.Concurrency = opts.concurrency
var configPath, configMediaType string
var err error
if opts.ManifestConfigRef != "" {
configPath, configMediaType, err = fileref.Parse(opts.ManifestConfigRef, "")
if err != nil {
Expand Down Expand Up @@ -191,6 +185,17 @@ func runPull(opts pullOptions) error {
}

ctx, _ := opts.SetLoggerLevel()
target, err := opts.NewReadonlyTarget(ctx, opts.Common)
if err != nil {
return err
}
if opts.Reference == "" {
return errors.NewErrInvalidReferenceStr(opts.RawReference)
}
src, err := opts.CachedTarget(target)
if err != nil {
return err
}
var dst = file.New(opts.Output)
dst.AllowPathTraversalOnWrite = opts.PathTraversal
dst.DisableOverwrite = opts.KeepOldFiles
Expand Down Expand Up @@ -230,14 +235,14 @@ func runPull(opts pullOptions) error {
}

// Copy
desc, err := oras.Copy(ctx, src, repo.Reference.Reference, dst, repo.Reference.Reference, copyOptions)
desc, err := oras.Copy(ctx, src, opts.Reference, dst, opts.Reference, copyOptions)
if err != nil {
return err
}
if pulledEmpty {
fmt.Println("Downloaded empty artifact")
}
fmt.Println("Pulled", opts.targetRef)
fmt.Println("Pulled", opts.AnnotatedReference())
fmt.Println("Digest:", desc.Digest)
return nil
}
Expand Down
20 changes: 13 additions & 7 deletions cmd/oras/repository/tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ import (
)

type showTagsOptions struct {
option.Remote
option.Common
targetRef string
option.Target

last string
excludeDigestTag bool
}
Expand All @@ -49,14 +49,20 @@ Example - Show tags in the target repository with digest-like tags hidden:
Example - Show tags of the target repository that include values lexically after last:
oras repo tags --last "last_tag" localhost:5000/hello
Example - Show tags of the target OCI layout folder 'layout-dir':
oras repo tags --oci-layout layout-dir
Example - Show tags of the target OCI layout archive 'layout.tar':
oras repo tags --oci-layout layout.tar
`,
Args: cobra.ExactArgs(1),
Aliases: []string{"show-tags"},
PreRunE: func(cmd *cobra.Command, args []string) error {
opts.RawReference = args[0]
return option.Parse(&opts)
},
RunE: func(cmd *cobra.Command, args []string) error {
opts.targetRef = args[0]
return showTags(opts)
},
}
Expand All @@ -68,14 +74,14 @@ Example - Show tags of the target repository that include values lexically after

func showTags(opts showTagsOptions) error {
ctx, _ := opts.SetLoggerLevel()
repo, err := opts.NewRepository(opts.targetRef, opts.Common)
finder, err := opts.NewReadonlyTarget(ctx, opts.Common)
if err != nil {
return err
}
if repo.Reference.Reference != "" {
return fmt.Errorf("unexpected tag or digest %q found in repository reference %q", repo.Reference.Reference, opts.targetRef)
if opts.Reference != "" {
return fmt.Errorf("unexpected tag or digest %q found in repository reference %q", opts.Reference, opts.RawReference)
}
return repo.Tags(ctx, opts.last, func(tags []string) error {
return finder.Tags(ctx, opts.last, func(tags []string) error {
for _, tag := range tags {
if opts.excludeDigestTag && isDigestTag(tag) {
continue
Expand Down
18 changes: 10 additions & 8 deletions cmd/oras/tag/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,9 @@ import (

type tagOptions struct {
option.Common
option.Remote
option.Target

concurrency int
srcRef string
targetRefs []string
}

Expand All @@ -52,14 +51,17 @@ Example - Tag the manifest 'v1.0.1' in 'localhost:5000/hello' to 'v1.0.2', 'late
Example - Tag the manifest 'v1.0.1' in 'localhost:5000/hello' to 'v1.0.1', 'v1.0.2', 'latest' with concurrency level tuned:
oras tag --concurrency 1 localhost:5000/hello:v1.0.1 v1.0.2 latest
Example - Tag the manifest 'v1.0.1' to 'v1.0.2' in an OCI layout folder 'layout-dir':
oras tag layout-dir:v1.0.1 v1.0.2
`,
Args: cobra.MinimumNArgs(2),
PreRunE: func(cmd *cobra.Command, args []string) error {
opts.RawReference = args[0]
opts.targetRefs = args[1:]
return option.Parse(&opts)
},
RunE: func(_ *cobra.Command, args []string) error {
opts.srcRef = args[0]
opts.targetRefs = args[1:]
return tagManifest(opts)
},
}
Expand All @@ -71,17 +73,17 @@ Example - Tag the manifest 'v1.0.1' in 'localhost:5000/hello' to 'v1.0.1', 'v1.0

func tagManifest(opts tagOptions) error {
ctx, _ := opts.SetLoggerLevel()
repo, err := opts.NewRepository(opts.srcRef, opts.Common)
target, err := opts.NewTarget(opts.Common)
if err != nil {
return err
}

if repo.Reference.Reference == "" {
return errors.NewErrInvalidReference(repo.Reference)
if opts.Reference == "" {
return errors.NewErrInvalidReferenceStr(opts.RawReference)
}

tagNOpts := oras.DefaultTagNOptions
tagNOpts.Concurrency = opts.concurrency
_, err = oras.TagN(ctx, display.NewTagManifestStatusPrinter(repo), opts.srcRef, opts.targetRefs, tagNOpts)
_, err = oras.TagN(ctx, display.NewTagManifestStatusPrinter(target), opts.Reference, opts.targetRefs, tagNOpts)
return err
}

0 comments on commit 2e9b0a6

Please sign in to comment.