Skip to content

Commit

Permalink
Merge branch 'main' into fix/transport-retry-backoff-option
Browse files Browse the repository at this point in the history
  • Loading branch information
aslafy-z authored Nov 9, 2023
2 parents fc2ba98 + b2485cb commit f6da36f
Show file tree
Hide file tree
Showing 329 changed files with 6,628 additions and 4,469 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/bump-deps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:

- run: ./hack/bump-deps.sh
- name: Create Pull Request
uses: peter-evans/create-pull-request@v4
uses: peter-evans/create-pull-request@v5
with:
title: "Bump dependencies using hack/bump-deps.sh"
commit-message: "Bump dependencies using hack/bump-deps.sh"
Expand Down
13 changes: 7 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ jobs:
run: git fetch --prune --unshallow
- uses: actions/setup-go@v4
with:
go-version: 1.18
go-version: 1.21
check-latest: true
- uses: goreleaser/goreleaser-action@v4.2.0
id: run-goreleaser
with:
version: latest
version: v1.18.2
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -32,7 +32,7 @@ jobs:
set -euo pipefail
checksum_file=$(echo "$ARTIFACTS" | jq -r '.[] | select (.type=="Checksum") | .path')
echo "::set-output name=hashes::$(cat $checksum_file | base64 -w0)"
echo "hashes=$(cat $checksum_file | base64 -w0)" >> $GITHUB_OUTPUT
provenance:
needs: [goreleaser]
Expand All @@ -51,18 +51,19 @@ jobs:
permissions: read-all
steps:
- name: Install SLSA verifier
uses: slsa-framework/slsa-verifier/actions/installer@v2.1.0
uses: slsa-framework/slsa-verifier/actions/installer@v2.2.0
- name: Download assets
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PROVENANCE: "${{ needs.provenance.outputs.provenance-name }}"
run: |
set -euo pipefail
gh -R "$GITHUB_REPOSITORY" release download "$GITHUB_REF_NAME" -p "*.tar.gz"
gh -R "$GITHUB_REPOSITORY" release download "$GITHUB_REF_NAME" -p "multiple.intoto.jsonl"
gh -R "$GITHUB_REPOSITORY" release download "$GITHUB_REF_NAME" -p $PROVENANCE
- name: Verify assets
env:
CHECKSUMS: ${{ needs.goreleaser.outputs.hashes }}
PROVENANCE: "${{ needs.provenance.outputs.attestation-name }}"
PROVENANCE: "${{ needs.provenance.outputs.provenance-name }}"
run: |
set -euo pipefail
checksums=$(echo "$CHECKSUMS" | base64 -d)
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ jobs:

- run: go test -coverprofile=coverage.txt -covermode=atomic -race ./...

- uses: codecov/codecov-action@v3.1.1
- uses: codecov/codecov-action@v3.1.4
3 changes: 3 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ builds:
- arm64
- 386
- s390x
- ppc64le
goos:
- linux
- darwin
Expand All @@ -51,6 +52,7 @@ builds:
- arm64
- 386
- s390x
- ppc64le
goos:
- linux
- darwin
Expand Down Expand Up @@ -78,6 +80,7 @@ builds:
- arm64
- 386
- s390x
- ppc64le
goos:
- linux
- darwin
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Over time, we will add new functionality under experimental environment variable

| Env Var | Value(s) | What is does |
|---------|----------|--------------|
| `GGCR_EXPERIMENT_ESTARGZ` | `"1"` | When enabled this experiment will direct `tarball.LayerFromOpener` to emit [estargz](https://github.com/opencontainers/image-spec/issues/815) compatible layers, which enable them to be lazily loaded by an appropriately configured containerd. |
| `GGCR_EXPERIMENT_ESTARGZ` | `"1"` | ⚠️DEPRECATED⚠️: When enabled this experiment will direct `tarball.LayerFromOpener` to emit [estargz](https://github.com/opencontainers/image-spec/issues/815) compatible layers, which enable them to be lazily loaded by an appropriately configured containerd. |


### `v1.Image`
Expand Down
4 changes: 2 additions & 2 deletions cmd/crane/cmd/append.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ If the base image is a Windows base image (i.e., its config.OS is "windows"),
the contents of the tarballs will be modified to be suitable for a Windows
container image.`,
Args: cobra.NoArgs,
RunE: func(_ *cobra.Command, args []string) error {
RunE: func(cmd *cobra.Command, args []string) error {
var base v1.Image
var err error

Expand Down Expand Up @@ -103,7 +103,7 @@ container image.`,
if err != nil {
return fmt.Errorf("digest: %w", err)
}
fmt.Println(ref.Context().Digest(d.String()))
fmt.Fprintln(cmd.OutOrStdout(), ref.Context().Digest(d.String()))
}
return nil
},
Expand Down
112 changes: 111 additions & 1 deletion cmd/crane/cmd/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/crane"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote/transport"
"github.com/spf13/cobra"
)

Expand All @@ -39,7 +40,77 @@ func NewCmdAuth(options []crane.Option, argv ...string) *cobra.Command {
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error { return cmd.Usage() },
}
cmd.AddCommand(NewCmdAuthGet(options, argv...), NewCmdAuthLogin(argv...))
cmd.AddCommand(NewCmdAuthGet(options, argv...), NewCmdAuthLogin(argv...), NewCmdAuthLogout(argv...), NewCmdAuthToken(options))
return cmd
}

func NewCmdAuthToken(options []crane.Option) *cobra.Command {
var (
header bool
push bool
mounts []string
)
cmd := &cobra.Command{
Use: "token REPO",
Short: "Retrieves a token for a remote repo",
Example: `# If you wanted to mount a blob from debian to ubuntu.
$ curl -H "$(crane auth token -H --push --mount debian ubuntu)" ...
# To get the raw list tags response
$ curl -H "$(crane auth token -H ubuntu)" https://index.docker.io/v2/library/ubuntu/tags/list
`,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
repo, err := name.NewRepository(args[0])
if err != nil {
return err
}
o := crane.GetOptions(options...)

t := transport.NewLogger(o.Transport)
pr, err := transport.Ping(cmd.Context(), repo.Registry, t)
if err != nil {
return err
}

auth, err := o.Keychain.Resolve(repo)
if err != nil {
return err
}

scopes := []string{repo.Scope(transport.PullScope)}
if push {
scopes[0] = repo.Scope(transport.PushScope)
}

for _, m := range mounts {
mr, err := name.NewRepository(m)
if err != nil {
return err
}
scopes = append(scopes, mr.Scope(transport.PullScope))
}

tr, err := transport.Exchange(cmd.Context(), repo.Registry, auth, t, scopes, pr)
if err != nil {
return err
}

if header {
fmt.Fprintf(cmd.OutOrStdout(), "Authorization: Bearer %s", tr.Token)
return nil
}

if err := json.NewEncoder(os.Stdout).Encode(tr); err != nil {
return err
}

return nil
},
}
cmd.Flags().StringSliceVarP(&mounts, "mount", "m", []string{}, "Scopes to mount from")
cmd.Flags().BoolVarP(&header, "header", "H", false, "Output in header format")
cmd.Flags().BoolVar(&push, "push", false, "Request push scopes")
return cmd
}

Expand Down Expand Up @@ -203,3 +274,42 @@ func login(opts loginOptions) error {
log.Printf("logged in via %s", cf.Filename)
return nil
}

// NewCmdAuthLogout creates a new `crane auth logout` command.
func NewCmdAuthLogout(argv ...string) *cobra.Command {
eg := fmt.Sprintf(` # Log out of reg.example.com
%s logout reg.example.com`, strings.Join(argv, " "))

cmd := &cobra.Command{
Use: "logout [SERVER]",
Short: "Log out of a registry",
Example: eg,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
reg, err := name.NewRegistry(args[0])
if err != nil {
return err
}
serverAddress := reg.Name()

cf, err := config.Load(os.Getenv("DOCKER_CONFIG"))
if err != nil {
return err
}
creds := cf.GetCredentialsStore(serverAddress)
if serverAddress == name.DefaultRegistry {
serverAddress = authn.DefaultAuthKey
}
if err := creds.Erase(serverAddress); err != nil {
return err
}

if err := cf.Save(); err != nil {
return err
}
log.Printf("logged out via %s", cf.Filename)
return nil
},
}
return cmd
}
73 changes: 48 additions & 25 deletions cmd/crane/cmd/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,63 @@
package cmd

import (
"context"
"fmt"
"os"
"strings"
"io"
"path"

"github.com/google/go-containerregistry/pkg/crane"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/spf13/cobra"
)

// NewCmdCatalog creates a new cobra.Command for the repos subcommand.
func NewCmdCatalog(options *[]crane.Option, argv ...string) *cobra.Command {
if len(argv) == 0 {
argv = []string{os.Args[0]}
// NewCmdCatalog creates a new cobra.Command for the catalog subcommand.
func NewCmdCatalog(options *[]crane.Option, _ ...string) *cobra.Command {
var fullRef bool
cmd := &cobra.Command{
Use: "catalog REGISTRY",
Short: "List the repos in a registry",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
o := crane.GetOptions(*options...)

return catalog(cmd.Context(), cmd.OutOrStdout(), args[0], fullRef, o)
},
}
cmd.Flags().BoolVar(&fullRef, "full-ref", false, "(Optional) if true, print the full image reference")

baseCmd := strings.Join(argv, " ")
eg := fmt.Sprintf(` # list the repos for reg.example.com
$ %s catalog reg.example.com`, baseCmd)

return &cobra.Command{
Use: "catalog [REGISTRY]",
Short: "List the repos in a registry",
Example: eg,
Args: cobra.ExactArgs(1),
RunE: func(_ *cobra.Command, args []string) error {
reg := args[0]
repos, err := crane.Catalog(reg, *options...)
if err != nil {
return fmt.Errorf("reading repos for %s: %w", reg, err)
}
return cmd
}

func catalog(ctx context.Context, w io.Writer, src string, fullRef bool, o crane.Options) error {
reg, err := name.NewRegistry(src, o.Name...)
if err != nil {
return fmt.Errorf("parsing reg %q: %w", src, err)
}

for _, repo := range repos {
fmt.Println(repo)
puller, err := remote.NewPuller(o.Remote...)
if err != nil {
return err
}

catalogger, err := puller.Catalogger(ctx, reg)
if err != nil {
return fmt.Errorf("reading tags for %s: %w", reg, err)
}

for catalogger.HasNext() {
repos, err := catalogger.Next(ctx)
if err != nil {
return err
}
for _, repo := range repos.Repos {
if fullRef {
fmt.Fprintln(w, path.Join(src, repo))
} else {
fmt.Fprintln(w, repo)
}
return nil
},
}
}
return nil
}
4 changes: 2 additions & 2 deletions cmd/crane/cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ func NewCmdConfig(options *[]crane.Option) *cobra.Command {
Use: "config IMAGE",
Short: "Get the config of an image",
Args: cobra.ExactArgs(1),
RunE: func(_ *cobra.Command, args []string) error {
RunE: func(cmd *cobra.Command, args []string) error {
cfg, err := crane.Config(args[0], *options...)
if err != nil {
return fmt.Errorf("fetching config: %w", err)
}
fmt.Print(string(cfg))
fmt.Fprint(cmd.OutOrStdout(), string(cfg))
return nil
},
}
Expand Down
20 changes: 18 additions & 2 deletions cmd/crane/cmd/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,36 @@
package cmd

import (
"runtime"

"github.com/google/go-containerregistry/pkg/crane"
"github.com/spf13/cobra"
)

// NewCmdCopy creates a new cobra.Command for the copy subcommand.
func NewCmdCopy(options *[]crane.Option) *cobra.Command {
return &cobra.Command{
allTags := false
noclobber := false
jobs := runtime.GOMAXPROCS(0)
cmd := &cobra.Command{
Use: "copy SRC DST",
Aliases: []string{"cp"},
Short: "Efficiently copy a remote image from src to dst while retaining the digest value",
Args: cobra.ExactArgs(2),
RunE: func(_ *cobra.Command, args []string) error {
opts := append(*options, crane.WithJobs(jobs), crane.WithNoClobber(noclobber))
src, dst := args[0], args[1]
return crane.Copy(src, dst, *options...)
if allTags {
return crane.CopyRepository(src, dst, opts...)
}

return crane.Copy(src, dst, opts...)
},
}

cmd.Flags().BoolVarP(&allTags, "all-tags", "a", false, "(Optional) if true, copy all tags from SRC to DST")
cmd.Flags().BoolVarP(&noclobber, "no-clobber", "n", false, "(Optional) if true, avoid overwriting existing tags in DST")
cmd.Flags().IntVarP(&jobs, "jobs", "j", 0, "(Optional) The maximum number of concurrent copies, defaults to GOMAXPROCS")

return cmd
}
4 changes: 2 additions & 2 deletions cmd/crane/cmd/digest.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ func NewCmdDigest(options *[]crane.Option) *cobra.Command {
if err != nil {
return err
}
fmt.Println(ref.Context().Digest(digest))
fmt.Fprintln(cmd.OutOrStdout(), ref.Context().Digest(digest))
} else {
fmt.Println(digest)
fmt.Fprintln(cmd.OutOrStdout(), digest)
}
return nil
},
Expand Down
Loading

0 comments on commit f6da36f

Please sign in to comment.