Skip to content

Commit

Permalink
support artifact discovery for oras cli
Browse files Browse the repository at this point in the history
Signed-off-by: Shiwei Zhang <shizh@microsoft.com>
  • Loading branch information
shizhMSFT committed Mar 29, 2021
1 parent 55d1abe commit 8d49927
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 30 deletions.
92 changes: 92 additions & 0 deletions cmd/oras/discover.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package main

import (
"context"
"errors"
"fmt"

ctxo "github.com/deislabs/oras/pkg/context"
"github.com/deislabs/oras/pkg/oras"

"github.com/containerd/containerd/reference"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

type discoverOptions struct {
targetRef string
artifactType string
verbose bool

debug bool
configs []string
username string
password string
insecure bool
plainHTTP bool
}

func discoverCmd() *cobra.Command {
var opts discoverOptions
cmd := &cobra.Command{
Use: "discover [options] <name:tag|name@digest>",
Short: "discover artifacts from remote registry",
Long: `discover artifacts from remote registry
Example - Discover artifacts of type "" linked with the specified reference:
oras discover --artifact-type application/vnd.cncf.notary.v2 localhost:5000/hello:latest
`,
Args: cobra.ExactArgs(1),
PreRunE: func(cmd *cobra.Command, args []string) error {
if opts.artifactType == "" {
return errors.New("artifact type not specified")
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
opts.targetRef = args[0]
return runDiscover(opts)
},
}

cmd.Flags().StringVarP(&opts.artifactType, "artifact-type", "", "", "artifact type")
cmd.Flags().BoolVarP(&opts.verbose, "verbose", "v", false, "verbose output")

cmd.Flags().BoolVarP(&opts.debug, "debug", "d", false, "debug mode")
cmd.Flags().StringArrayVarP(&opts.configs, "config", "c", nil, "auth config path")
cmd.Flags().StringVarP(&opts.username, "username", "u", "", "registry username")
cmd.Flags().StringVarP(&opts.password, "password", "p", "", "registry password")
cmd.Flags().BoolVarP(&opts.insecure, "insecure", "", false, "allow connections to SSL registry without certs")
cmd.Flags().BoolVarP(&opts.plainHTTP, "plain-http", "", false, "use plain http and not https")
return cmd
}

func runDiscover(opts discoverOptions) error {
ctx := context.Background()
if opts.debug {
logrus.SetLevel(logrus.DebugLevel)
} else if !opts.verbose {
ctx = ctxo.WithLoggerDiscarded(ctx)
}

resolver := newResolver(opts.username, opts.password, opts.insecure, opts.plainHTTP, opts.configs...)

desc, artifacts, err := oras.Discover(ctx, resolver, opts.targetRef, opts.artifactType)
if err != nil {
if err == reference.ErrObjectRequired {
return fmt.Errorf("image reference format is invalid. Please specify <name:tag|name@digest>")
}
return err
}

fmt.Println("Discovered", len(artifacts), "artifacts referencing", opts.targetRef)
fmt.Println("Digest:", desc.Digest)
for _, artifact := range artifacts {
fmt.Println("Reference:", artifact.ArtifactType)
for _, blob := range artifact.Blobs {
fmt.Println("-", blob.Digest)
}
}

return nil
}
9 changes: 8 additions & 1 deletion cmd/oras/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ func main() {
Use: "oras [command]",
SilenceUsage: true,
}
cmd.AddCommand(pullCmd(), pushCmd(), loginCmd(), logoutCmd(), versionCmd())
cmd.AddCommand(
pullCmd(),
pushCmd(),
discoverCmd(),
loginCmd(),
logoutCmd(),
versionCmd(),
)
if err := cmd.Execute(); err != nil {
os.Exit(1)
}
Expand Down
58 changes: 29 additions & 29 deletions pkg/oras/discover.go
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
package oras

import (
"context"

"github.com/containerd/containerd/remotes"
artifactspec "github.com/notaryproject/artifacts/specs-go/v2"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)

// Discover discovers artifacts referencing the specified artifact
func Discover(ctx context.Context, resolver remotes.Resolver, ref, artifactType string) (ocispec.Descriptor, []artifactspec.Artifact, error) {
_, desc, err := resolver.Resolve(ctx, ref)
if err != nil {
return ocispec.Descriptor{}, nil, err
}

discoverer, err := resolver.Discoverer(ctx, ref)
if err != nil {
return ocispec.Descriptor{}, nil, err
}

artifacts, err := discoverer.Discover(ctx, desc, artifactType)
if err != nil {
return ocispec.Descriptor{}, nil, err
}

return desc, artifacts, err
}
package oras

import (
"context"

"github.com/containerd/containerd/remotes"
artifactspec "github.com/notaryproject/artifacts/specs-go/v2"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)

// Discover discovers artifacts referencing the specified artifact
func Discover(ctx context.Context, resolver remotes.Resolver, ref, artifactType string) (ocispec.Descriptor, []artifactspec.Artifact, error) {
_, desc, err := resolver.Resolve(ctx, ref)
if err != nil {
return ocispec.Descriptor{}, nil, err
}

discoverer, err := resolver.Discoverer(ctx, ref)
if err != nil {
return ocispec.Descriptor{}, nil, err
}

artifacts, err := discoverer.Discover(ctx, desc, artifactType)
if err != nil {
return ocispec.Descriptor{}, nil, err
}

return desc, artifacts, err
}

0 comments on commit 8d49927

Please sign in to comment.