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

feat: support oci layout target #692

Closed
wants to merge 68 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
66fff53
test: add tests for 0.15.0
qweeah Nov 15, 2022
d1b625d
remove null parameter
qweeah Nov 15, 2022
ace45ce
add push specs
qweeah Nov 15, 2022
0180e57
add push spec
qweeah Nov 15, 2022
14a3aea
fix spec
qweeah Nov 15, 2022
d6ef91d
add spec for annotation file
qweeah Nov 16, 2022
7e42ec9
prettify output
qweeah Nov 16, 2022
e88e2b6
add comment
qweeah Nov 16, 2022
eab12a2
fix failed
qweeah Nov 16, 2022
e5f1506
check annotation file in
qweeah Nov 16, 2022
8b13ad0
fix trimming
qweeah Nov 16, 2022
ff7c1f8
prepare test data in spec
qweeah Nov 16, 2022
2715e27
remove logging
qweeah Nov 16, 2022
70e78b3
add seed in repo
qweeah Nov 16, 2022
c1dc00b
fix typo
qweeah Nov 16, 2022
9e5accf
fix duplicated naming
qweeah Nov 16, 2022
0197050
add target flag
qweeah Nov 16, 2022
6947a1f
support copy
qweeah Nov 16, 2022
7d5a20e
fix parsing
qweeah Nov 17, 2022
277e990
Merge branch 'main' into oci-demo
qweeah Nov 17, 2022
0895ba9
add version
qweeah Nov 17, 2022
2e45215
fix bug
qweeah Nov 17, 2022
d4b5329
Merge branch 'main' into oci-demo
qweeah Dec 18, 2022
34e4adc
apply parse for all commands
qweeah Dec 18, 2022
771cddc
fix pulling
qweeah Dec 18, 2022
1e3a2d2
code clean
qweeah Dec 18, 2022
848853a
add unary target
qweeah Dec 18, 2022
9c09da8
Merge remote-tracking branch 'origin_src/main' into oci-demo
qweeah Dec 19, 2022
aa176bd
add input
qweeah Dec 19, 2022
6d9699e
code clean
qweeah Dec 19, 2022
aa19e0c
add tarball support
qweeah Dec 19, 2022
aa5cb18
update pulling
qweeah Dec 19, 2022
ee04805
add reference validation
qweeah Dec 19, 2022
b28c277
fix pull
qweeah Dec 19, 2022
3ad8950
fix pull
qweeah Dec 19, 2022
ec7577f
fix copy
qweeah Dec 19, 2022
37c6e4f
enable fetch
qweeah Dec 19, 2022
49699f4
attach changed
qweeah Dec 19, 2022
3fb6a98
fix: mandates empty referrer to empty array
qweeah Dec 20, 2022
c446d38
Merge branch 'fix-discover' into oci-demo
qweeah Dec 20, 2022
e9a509c
fix E2E
qweeah Dec 20, 2022
ee414af
fix e2e
qweeah Dec 20, 2022
f418ac4
Merge remote-tracking branch 'origin_src/main' into oci-demo
qweeah Dec 20, 2022
d88e810
change UX
qweeah Dec 20, 2022
e90f85d
fix bug
qweeah Dec 20, 2022
8e635e5
add blob fetch
qweeah Dec 21, 2022
9dc0385
update blob fetch
qweeah Dec 21, 2022
5580808
add blob push
qweeah Dec 21, 2022
c0fe7ad
update manifest push
qweeah Dec 21, 2022
1d9d07e
update tag
qweeah Dec 21, 2022
d9489cf
fix push
qweeah Dec 21, 2022
e49fd09
fix cp
qweeah Dec 21, 2022
5593f5a
support push
qweeah Dec 21, 2022
be4f4b8
fix pull
qweeah Dec 21, 2022
a719234
add short command
qweeah Dec 22, 2022
e61735b
Merge remote-tracking branch 'origin_src/main' into oci-demo
qweeah Dec 26, 2022
5a595dd
use tag finder
qweeah Dec 26, 2022
365ba07
bug fix
qweeah Dec 26, 2022
a2fd396
fix bug
qweeah Dec 26, 2022
281839e
code clean
qweeah Dec 26, 2022
3e216d8
fix bugs
qweeah Dec 26, 2022
e4daab2
code clean
qweeah Jan 3, 2023
d13a6cb
add unit tests
qweeah Jan 3, 2023
91fa420
make optional func private
qweeah Jan 4, 2023
38ffac9
add docs
qweeah Jan 4, 2023
4f66d23
rename reference
qweeah Jan 5, 2023
e161136
remove demo version
qweeah Jan 5, 2023
cb8a83b
add fetch config
qweeah Jan 5, 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
29 changes: 17 additions & 12 deletions cmd/oras/attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,16 @@ import (
"oras.land/oras-go/v2"
"oras.land/oras-go/v2/content"
"oras.land/oras-go/v2/content/file"
"oras.land/oras-go/v2/registry/remote"
oerrors "oras.land/oras/cmd/oras/internal/errors"
"oras.land/oras/cmd/oras/internal/option"
)

type attachOptions struct {
option.Common
option.Remote
option.Packer
option.Target

targetRef string
artifactType string
concurrency int
}
Expand Down Expand Up @@ -65,11 +65,11 @@ Example - Attach file 'hi.txt' and export the pushed manifest to 'manifest.json'
`,
Args: cobra.MinimumNArgs(1),
PreRunE: func(cmd *cobra.Command, args []string) error {
return opts.ReadPassword()
opts.FileRefs = args[1:]
opts.FqdnRef = args[0]
return option.Parse(&opts)
},
RunE: func(cmd *cobra.Command, args []string) error {
opts.targetRef = args[0]
opts.FileRefs = args[1:]
return runAttach(opts)
},
}
Expand All @@ -96,14 +96,15 @@ func runAttach(opts attachOptions) error {
defer store.Close()
store.AllowPathTraversalOnWrite = opts.PathValidationDisabled

dst, err := opts.NewRepository(opts.targetRef, opts.Common)
dst, err := opts.NewTarget(opts.Common)
if err != nil {
return err
}
if dst.Reference.Reference == "" {
return oerrors.NewErrInvalidReference(dst.Reference)
// sanctity check: should not be tarball
if opts.Reference == "" {
return oerrors.NewErrInvalidReferenceStr(opts.FqdnRef)
}
subject, err := dst.Resolve(ctx, dst.Reference.Reference)
subject, err := dst.Resolve(ctx, opts.Reference)
if err != nil {
return err
}
Expand Down Expand Up @@ -142,9 +143,13 @@ func runAttach(opts attachOptions) error {
return err
}

targetRef := dst.Reference
targetRef.Reference = subject.Digest.String()
fmt.Println("Attached to", targetRef)
if opts.Type == option.RemoteType {
// Reassemble a reference with subject digest
ref := dst.(*remote.Repository).Reference
ref.Reference = subject.Digest.String()
opts.FqdnRef = ref.String()
}
fmt.Println("Attached to", opts.FullReference())
fmt.Println("Digest:", root.Digest)

// Export manifest
Expand Down
2 changes: 1 addition & 1 deletion cmd/oras/blob/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Example - Delete a blob and print its descriptor:
if opts.OutputDescriptor && !opts.Confirmed {
return errors.New("must apply --force to confirm the deletion if the descriptor is outputted")
}
return opts.ReadPassword()
return option.Parse(&opts)
},
RunE: func(cmd *cobra.Command, args []string) error {
opts.targetRef = args[0]
Expand Down
29 changes: 15 additions & 14 deletions cmd/oras/blob/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ import (
"io"
"os"

"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/spf13/cobra"
"oras.land/oras-go/v2"
"oras.land/oras-go/v2/content"
"oras.land/oras-go/v2/registry/remote"
"oras.land/oras/cmd/oras/internal/option"
)

Expand All @@ -33,10 +35,9 @@ type fetchBlobOptions struct {
option.Common
option.Descriptor
option.Pretty
option.Remote
option.Target

outputPath string
targetRef string
}

func fetchCmd() *cobra.Command {
Expand All @@ -62,19 +63,17 @@ Example - Fetch the blob, save it to a local file and print the descriptor:
`,
Args: cobra.ExactArgs(1),
PreRunE: func(cmd *cobra.Command, args []string) error {
opts.FqdnRef = args[0]
if opts.outputPath == "" && !opts.OutputDescriptor {
return errors.New("either `--output` or `--descriptor` must be provided")
}

if opts.outputPath == "-" && opts.OutputDescriptor {
return errors.New("`--output -` cannot be used with `--descriptor` at the same time")
}

return opts.ReadPassword()
return option.Parse(&opts)
},
Aliases: []string{"get"},
RunE: func(cmd *cobra.Command, args []string) error {
opts.targetRef = args[0]
return fetchBlob(opts)
},
}
Expand All @@ -86,32 +85,34 @@ Example - Fetch the blob, save it to a local file and print the descriptor:

func fetchBlob(opts fetchBlobOptions) (fetchErr error) {
ctx, _ := opts.SetLoggerLevel()

repo, err := opts.NewRepository(opts.targetRef, opts.Common)
var target oras.ReadOnlyTarget
target, err := opts.NewReadonlyTarget(ctx, opts.Common)
if err != nil {
return err
}

if _, err = repo.Reference.Digest(); err != nil {
return fmt.Errorf("%s: blob reference must be of the form <name@digest>", opts.targetRef)
if err := digest.Digest(opts.Reference).Validate(); err != nil {
return fmt.Errorf("%s: blob reference must be of the form <name@digest>: %w", opts.FqdnRef, err)
}

src, err := opts.CachedTarget(repo.Blobs())
if repo, ok := target.(*remote.Repository); ok {
target = repo.Blobs()
}
src, err := opts.CachedTarget(target)
if err != nil {
return err
}

var desc ocispec.Descriptor
if opts.outputPath == "" {
// fetch blob descriptor only
desc, err = oras.Resolve(ctx, src, opts.targetRef, oras.DefaultResolveOptions)
desc, err = oras.Resolve(ctx, src, opts.Reference, oras.DefaultResolveOptions)
if err != nil {
return err
}
} else {
// fetch blob content
var rc io.ReadCloser
desc, rc, err = oras.Fetch(ctx, src, opts.targetRef, oras.DefaultFetchOptions)
desc, rc, err = oras.Fetch(ctx, src, opts.Reference, oras.DefaultFetchOptions)
if err != nil {
return err
}
Expand Down
19 changes: 9 additions & 10 deletions cmd/oras/blob/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,11 @@ type pushBlobOptions struct {
option.Common
option.Descriptor
option.Pretty
option.Remote
option.Target

fileRef string
mediaType string
size int64
targetRef string
fileRef string
}

func pushCmd() *cobra.Command {
Expand Down Expand Up @@ -71,7 +70,7 @@ Example - Push blob without TLS:
`,
Args: cobra.ExactArgs(2),
PreRunE: func(cmd *cobra.Command, args []string) error {
opts.targetRef = args[0]
opts.FqdnRef = args[0]
opts.fileRef = args[1]
if opts.fileRef == "-" {
if opts.PasswordFromStdin {
Expand All @@ -81,7 +80,7 @@ Example - Push blob without TLS:
return errors.New("`--size` must be provided if the blob is read from stdin")
}
}
return opts.ReadPassword()
return option.Parse(&opts)
},
RunE: func(cmd *cobra.Command, args []string) error {
return pushBlob(opts)
Expand All @@ -97,19 +96,19 @@ Example - Push blob without TLS:
func pushBlob(opts pushBlobOptions) (err error) {
ctx, _ := opts.SetLoggerLevel()

repo, err := opts.NewRepository(opts.targetRef, opts.Common)
target, err := opts.NewTarget(opts.Common)
if err != nil {
return err
}

// prepare blob content
desc, rc, err := file.PrepareBlobContent(opts.fileRef, opts.mediaType, repo.Reference.Reference, opts.size)
desc, rc, err := file.PrepareBlobContent(opts.fileRef, opts.mediaType, opts.Reference, opts.size)
if err != nil {
return err
}
defer rc.Close()

exists, err := repo.Exists(ctx, desc)
exists, err := target.Exists(ctx, desc)
if err != nil {
return err
}
Expand All @@ -122,7 +121,7 @@ func pushBlob(opts pushBlobOptions) (err error) {
if err := display.PrintStatus(desc, "Uploading", verbose); err != nil {
return err
}
if err = repo.Push(ctx, desc, rc); err != nil {
if err = target.Push(ctx, desc, rc); err != nil {
return err
}
if err := display.PrintStatus(desc, "Uploaded ", verbose); err != nil {
Expand All @@ -139,7 +138,7 @@ func pushBlob(opts pushBlobOptions) (err error) {
return opts.Output(os.Stdout, descJSON)
}

fmt.Println("Pushed", opts.targetRef)
fmt.Println("Pushed", opts.FullReference())
fmt.Println("Digest:", desc.Digest)

return nil
Expand Down
48 changes: 20 additions & 28 deletions cmd/oras/cp.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,12 @@ import (
)

type copyOptions struct {
src option.Remote
dst option.Remote
option.Common
option.Platform
recursive bool
option.BinaryTarget

concurrency int
srcRef string
dstRef string
extraRefs []string
}

Expand Down Expand Up @@ -68,18 +65,19 @@ Example - Copy the artifact tagged with 'v1' from repository 'localhost:5000/net
oras cp --concurrency 6 localhost:5000/net-monitor:v1 localhost:5000/net-monitor-copy:v1,tag2,tag3
`,
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
opts.srcRef = args[0]
PreRunE: func(cmd *cobra.Command, args []string) error {
opts.From.FqdnRef = args[0]
refs := strings.Split(args[1], ",")
opts.dstRef = refs[0]
opts.To.FqdnRef = refs[0]
opts.extraRefs = refs[1:]
return option.Parse(&opts)
},
RunE: func(cmd *cobra.Command, args []string) error {
return runCopy(opts)
},
}

cmd.Flags().BoolVarP(&opts.recursive, "recursive", "r", false, "recursively copy the artifact and its referrer artifacts")
opts.src.ApplyFlagsWithPrefix(cmd.Flags(), "from", "source")
opts.dst.ApplyFlagsWithPrefix(cmd.Flags(), "to", "destination")
cmd.Flags().IntVarP(&opts.concurrency, "concurrency", "", 3, "concurrency level")
option.ApplyFlags(&opts, cmd.Flags())

Expand All @@ -88,19 +86,19 @@ Example - Copy the artifact tagged with 'v1' from repository 'localhost:5000/net

func runCopy(opts copyOptions) error {
ctx, _ := opts.SetLoggerLevel()
targetPlatform, err := opts.Parse()
if err != nil {
return err
}

// Prepare source
src, err := opts.src.NewRepository(opts.srcRef, opts.Common)
src, err := opts.From.NewReadonlyTarget(ctx, opts.Common)
if err != nil {
return err
}
if opts.From.Reference == "" {
return errors.NewErrInvalidReferenceStr(opts.From.FqdnRef)
}

// Prepare destination
dst, err := opts.dst.NewRepository(opts.dstRef, opts.Common)

dst, err := opts.To.NewTarget(opts.Common)
if err != nil {
return err
}
Expand All @@ -122,14 +120,10 @@ func runCopy(opts copyOptions) error {
return display.PrintStatus(desc, "Exists ", opts.Verbose)
}

if src.Reference.Reference == "" {
return errors.NewErrInvalidReference(src.Reference)
}

var desc ocispec.Descriptor
if ref := dst.Reference.Reference; ref == "" {
if ref := opts.To.Reference; ref == "" {
// push to the destination with digest only if no tag specified
desc, err = src.Resolve(ctx, src.Reference.Reference)
desc, err = src.Resolve(ctx, opts.From.Reference)
if err != nil {
return err
}
Expand All @@ -140,27 +134,25 @@ func runCopy(opts copyOptions) error {
}
} else {
if opts.recursive {
desc, err = oras.ExtendedCopy(ctx, src, opts.srcRef, dst, opts.dstRef, extendedCopyOptions)
desc, err = oras.ExtendedCopy(ctx, src, opts.From.Reference, dst, opts.To.Reference, extendedCopyOptions)
} else {
copyOptions := oras.CopyOptions{
CopyGraphOptions: extendedCopyOptions.CopyGraphOptions,
}
if targetPlatform != nil {
copyOptions.WithTargetPlatform(targetPlatform)
}
desc, err = oras.Copy(ctx, src, opts.srcRef, dst, opts.dstRef, copyOptions)
copyOptions.WithTargetPlatform(opts.OCIPlatform)
desc, err = oras.Copy(ctx, src, opts.From.Reference, dst, opts.To.Reference, copyOptions)
}
}
if err != nil {
return err
}

fmt.Println("Copied", opts.srcRef, "=>", opts.dstRef)
fmt.Printf("Copied %s => %s \n", opts.From.FullReference(), opts.To.FullReference())

if len(opts.extraRefs) != 0 {
tagNOpts := oras.DefaultTagNOptions
tagNOpts.Concurrency = opts.concurrency
if err = oras.TagN(ctx, &display.TagManifestStatusPrinter{Repository: dst}, opts.dstRef, opts.extraRefs, tagNOpts); err != nil {
if err = oras.TagN(ctx, &display.TagManifestStatusPrinter{Target: dst}, opts.To.Reference, opts.extraRefs, tagNOpts); err != nil {
return err
}
}
Expand Down
8 changes: 2 additions & 6 deletions cmd/oras/discover.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Example - Discover referrers with type 'test-artifact' of manifest 'hello:latest
`,
Args: cobra.ExactArgs(1),
PreRunE: func(cmd *cobra.Command, args []string) error {
return opts.ReadPassword()
return option.Parse(&opts)
},
RunE: func(cmd *cobra.Command, args []string) error {
opts.targetRef = args[0]
Expand All @@ -86,14 +86,10 @@ func runDiscover(opts discoverOptions) error {
if repo.Reference.Reference == "" {
return errors.NewErrInvalidReference(repo.Reference)
}
targetPlatform, err := opts.Parse()
if err != nil {
return err
}

// discover artifacts
resolveOpts := oras.DefaultResolveOptions
resolveOpts.TargetPlatform = targetPlatform
resolveOpts.TargetPlatform = opts.OCIPlatform
desc, err := oras.Resolve(ctx, repo, repo.Reference.Reference, resolveOpts)
if err != nil {
return err
Expand Down
Loading