Skip to content

Commit f6da36f

Browse files
authored
Merge branch 'main' into fix/transport-retry-backoff-option
2 parents fc2ba98 + b2485cb commit f6da36f

File tree

329 files changed

+6628
-4469
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

329 files changed

+6628
-4469
lines changed

.github/workflows/bump-deps.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626

2727
- run: ./hack/bump-deps.sh
2828
- name: Create Pull Request
29-
uses: peter-evans/create-pull-request@v4
29+
uses: peter-evans/create-pull-request@v5
3030
with:
3131
title: "Bump dependencies using hack/bump-deps.sh"
3232
commit-message: "Bump dependencies using hack/bump-deps.sh"

.github/workflows/release.yml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ jobs:
1515
run: git fetch --prune --unshallow
1616
- uses: actions/setup-go@v4
1717
with:
18-
go-version: 1.18
18+
go-version: 1.21
1919
check-latest: true
2020
- uses: goreleaser/[email protected]
2121
id: run-goreleaser
2222
with:
23-
version: latest
23+
version: v1.18.2
2424
args: release --rm-dist
2525
env:
2626
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -32,7 +32,7 @@ jobs:
3232
set -euo pipefail
3333
3434
checksum_file=$(echo "$ARTIFACTS" | jq -r '.[] | select (.type=="Checksum") | .path')
35-
echo "::set-output name=hashes::$(cat $checksum_file | base64 -w0)"
35+
echo "hashes=$(cat $checksum_file | base64 -w0)" >> $GITHUB_OUTPUT
3636
3737
provenance:
3838
needs: [goreleaser]
@@ -51,18 +51,19 @@ jobs:
5151
permissions: read-all
5252
steps:
5353
- name: Install SLSA verifier
54-
uses: slsa-framework/slsa-verifier/actions/installer@v2.1.0
54+
uses: slsa-framework/slsa-verifier/actions/installer@v2.2.0
5555
- name: Download assets
5656
env:
5757
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
58+
PROVENANCE: "${{ needs.provenance.outputs.provenance-name }}"
5859
run: |
5960
set -euo pipefail
6061
gh -R "$GITHUB_REPOSITORY" release download "$GITHUB_REF_NAME" -p "*.tar.gz"
61-
gh -R "$GITHUB_REPOSITORY" release download "$GITHUB_REF_NAME" -p "multiple.intoto.jsonl"
62+
gh -R "$GITHUB_REPOSITORY" release download "$GITHUB_REF_NAME" -p $PROVENANCE
6263
- name: Verify assets
6364
env:
6465
CHECKSUMS: ${{ needs.goreleaser.outputs.hashes }}
65-
PROVENANCE: "${{ needs.provenance.outputs.attestation-name }}"
66+
PROVENANCE: "${{ needs.provenance.outputs.provenance-name }}"
6667
run: |
6768
set -euo pipefail
6869
checksums=$(echo "$CHECKSUMS" | base64 -d)

.github/workflows/test.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ jobs:
2525

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

28-
- uses: codecov/[email protected].1
28+
- uses: codecov/[email protected].4

.goreleaser.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ builds:
2525
- arm64
2626
- 386
2727
- s390x
28+
- ppc64le
2829
goos:
2930
- linux
3031
- darwin
@@ -51,6 +52,7 @@ builds:
5152
- arm64
5253
- 386
5354
- s390x
55+
- ppc64le
5456
goos:
5557
- linux
5658
- darwin
@@ -78,6 +80,7 @@ builds:
7880
- arm64
7981
- 386
8082
- s390x
83+
- ppc64le
8184
goos:
8285
- linux
8386
- darwin

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Over time, we will add new functionality under experimental environment variable
3636

3737
| Env Var | Value(s) | What is does |
3838
|---------|----------|--------------|
39-
| `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. |
39+
| `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. |
4040

4141

4242
### `v1.Image`

cmd/crane/cmd/append.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ If the base image is a Windows base image (i.e., its config.OS is "windows"),
4545
the contents of the tarballs will be modified to be suitable for a Windows
4646
container image.`,
4747
Args: cobra.NoArgs,
48-
RunE: func(_ *cobra.Command, args []string) error {
48+
RunE: func(cmd *cobra.Command, args []string) error {
4949
var base v1.Image
5050
var err error
5151

@@ -103,7 +103,7 @@ container image.`,
103103
if err != nil {
104104
return fmt.Errorf("digest: %w", err)
105105
}
106-
fmt.Println(ref.Context().Digest(d.String()))
106+
fmt.Fprintln(cmd.OutOrStdout(), ref.Context().Digest(d.String()))
107107
}
108108
return nil
109109
},

cmd/crane/cmd/auth.go

Lines changed: 111 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/google/go-containerregistry/pkg/authn"
2929
"github.com/google/go-containerregistry/pkg/crane"
3030
"github.com/google/go-containerregistry/pkg/name"
31+
"github.com/google/go-containerregistry/pkg/v1/remote/transport"
3132
"github.com/spf13/cobra"
3233
)
3334

@@ -39,7 +40,77 @@ func NewCmdAuth(options []crane.Option, argv ...string) *cobra.Command {
3940
Args: cobra.NoArgs,
4041
RunE: func(cmd *cobra.Command, _ []string) error { return cmd.Usage() },
4142
}
42-
cmd.AddCommand(NewCmdAuthGet(options, argv...), NewCmdAuthLogin(argv...))
43+
cmd.AddCommand(NewCmdAuthGet(options, argv...), NewCmdAuthLogin(argv...), NewCmdAuthLogout(argv...), NewCmdAuthToken(options))
44+
return cmd
45+
}
46+
47+
func NewCmdAuthToken(options []crane.Option) *cobra.Command {
48+
var (
49+
header bool
50+
push bool
51+
mounts []string
52+
)
53+
cmd := &cobra.Command{
54+
Use: "token REPO",
55+
Short: "Retrieves a token for a remote repo",
56+
Example: `# If you wanted to mount a blob from debian to ubuntu.
57+
$ curl -H "$(crane auth token -H --push --mount debian ubuntu)" ...
58+
59+
# To get the raw list tags response
60+
$ curl -H "$(crane auth token -H ubuntu)" https://index.docker.io/v2/library/ubuntu/tags/list
61+
`,
62+
Args: cobra.ExactArgs(1),
63+
RunE: func(cmd *cobra.Command, args []string) error {
64+
repo, err := name.NewRepository(args[0])
65+
if err != nil {
66+
return err
67+
}
68+
o := crane.GetOptions(options...)
69+
70+
t := transport.NewLogger(o.Transport)
71+
pr, err := transport.Ping(cmd.Context(), repo.Registry, t)
72+
if err != nil {
73+
return err
74+
}
75+
76+
auth, err := o.Keychain.Resolve(repo)
77+
if err != nil {
78+
return err
79+
}
80+
81+
scopes := []string{repo.Scope(transport.PullScope)}
82+
if push {
83+
scopes[0] = repo.Scope(transport.PushScope)
84+
}
85+
86+
for _, m := range mounts {
87+
mr, err := name.NewRepository(m)
88+
if err != nil {
89+
return err
90+
}
91+
scopes = append(scopes, mr.Scope(transport.PullScope))
92+
}
93+
94+
tr, err := transport.Exchange(cmd.Context(), repo.Registry, auth, t, scopes, pr)
95+
if err != nil {
96+
return err
97+
}
98+
99+
if header {
100+
fmt.Fprintf(cmd.OutOrStdout(), "Authorization: Bearer %s", tr.Token)
101+
return nil
102+
}
103+
104+
if err := json.NewEncoder(os.Stdout).Encode(tr); err != nil {
105+
return err
106+
}
107+
108+
return nil
109+
},
110+
}
111+
cmd.Flags().StringSliceVarP(&mounts, "mount", "m", []string{}, "Scopes to mount from")
112+
cmd.Flags().BoolVarP(&header, "header", "H", false, "Output in header format")
113+
cmd.Flags().BoolVar(&push, "push", false, "Request push scopes")
43114
return cmd
44115
}
45116

@@ -203,3 +274,42 @@ func login(opts loginOptions) error {
203274
log.Printf("logged in via %s", cf.Filename)
204275
return nil
205276
}
277+
278+
// NewCmdAuthLogout creates a new `crane auth logout` command.
279+
func NewCmdAuthLogout(argv ...string) *cobra.Command {
280+
eg := fmt.Sprintf(` # Log out of reg.example.com
281+
%s logout reg.example.com`, strings.Join(argv, " "))
282+
283+
cmd := &cobra.Command{
284+
Use: "logout [SERVER]",
285+
Short: "Log out of a registry",
286+
Example: eg,
287+
Args: cobra.ExactArgs(1),
288+
RunE: func(cmd *cobra.Command, args []string) error {
289+
reg, err := name.NewRegistry(args[0])
290+
if err != nil {
291+
return err
292+
}
293+
serverAddress := reg.Name()
294+
295+
cf, err := config.Load(os.Getenv("DOCKER_CONFIG"))
296+
if err != nil {
297+
return err
298+
}
299+
creds := cf.GetCredentialsStore(serverAddress)
300+
if serverAddress == name.DefaultRegistry {
301+
serverAddress = authn.DefaultAuthKey
302+
}
303+
if err := creds.Erase(serverAddress); err != nil {
304+
return err
305+
}
306+
307+
if err := cf.Save(); err != nil {
308+
return err
309+
}
310+
log.Printf("logged out via %s", cf.Filename)
311+
return nil
312+
},
313+
}
314+
return cmd
315+
}

cmd/crane/cmd/catalog.go

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,40 +15,63 @@
1515
package cmd
1616

1717
import (
18+
"context"
1819
"fmt"
19-
"os"
20-
"strings"
20+
"io"
21+
"path"
2122

2223
"github.com/google/go-containerregistry/pkg/crane"
24+
"github.com/google/go-containerregistry/pkg/name"
25+
"github.com/google/go-containerregistry/pkg/v1/remote"
2326
"github.com/spf13/cobra"
2427
)
2528

26-
// NewCmdCatalog creates a new cobra.Command for the repos subcommand.
27-
func NewCmdCatalog(options *[]crane.Option, argv ...string) *cobra.Command {
28-
if len(argv) == 0 {
29-
argv = []string{os.Args[0]}
29+
// NewCmdCatalog creates a new cobra.Command for the catalog subcommand.
30+
func NewCmdCatalog(options *[]crane.Option, _ ...string) *cobra.Command {
31+
var fullRef bool
32+
cmd := &cobra.Command{
33+
Use: "catalog REGISTRY",
34+
Short: "List the repos in a registry",
35+
Args: cobra.ExactArgs(1),
36+
RunE: func(cmd *cobra.Command, args []string) error {
37+
o := crane.GetOptions(*options...)
38+
39+
return catalog(cmd.Context(), cmd.OutOrStdout(), args[0], fullRef, o)
40+
},
3041
}
42+
cmd.Flags().BoolVar(&fullRef, "full-ref", false, "(Optional) if true, print the full image reference")
3143

32-
baseCmd := strings.Join(argv, " ")
33-
eg := fmt.Sprintf(` # list the repos for reg.example.com
34-
$ %s catalog reg.example.com`, baseCmd)
35-
36-
return &cobra.Command{
37-
Use: "catalog [REGISTRY]",
38-
Short: "List the repos in a registry",
39-
Example: eg,
40-
Args: cobra.ExactArgs(1),
41-
RunE: func(_ *cobra.Command, args []string) error {
42-
reg := args[0]
43-
repos, err := crane.Catalog(reg, *options...)
44-
if err != nil {
45-
return fmt.Errorf("reading repos for %s: %w", reg, err)
46-
}
44+
return cmd
45+
}
46+
47+
func catalog(ctx context.Context, w io.Writer, src string, fullRef bool, o crane.Options) error {
48+
reg, err := name.NewRegistry(src, o.Name...)
49+
if err != nil {
50+
return fmt.Errorf("parsing reg %q: %w", src, err)
51+
}
4752

48-
for _, repo := range repos {
49-
fmt.Println(repo)
53+
puller, err := remote.NewPuller(o.Remote...)
54+
if err != nil {
55+
return err
56+
}
57+
58+
catalogger, err := puller.Catalogger(ctx, reg)
59+
if err != nil {
60+
return fmt.Errorf("reading tags for %s: %w", reg, err)
61+
}
62+
63+
for catalogger.HasNext() {
64+
repos, err := catalogger.Next(ctx)
65+
if err != nil {
66+
return err
67+
}
68+
for _, repo := range repos.Repos {
69+
if fullRef {
70+
fmt.Fprintln(w, path.Join(src, repo))
71+
} else {
72+
fmt.Fprintln(w, repo)
5073
}
51-
return nil
52-
},
74+
}
5375
}
76+
return nil
5477
}

cmd/crane/cmd/config.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ func NewCmdConfig(options *[]crane.Option) *cobra.Command {
2727
Use: "config IMAGE",
2828
Short: "Get the config of an image",
2929
Args: cobra.ExactArgs(1),
30-
RunE: func(_ *cobra.Command, args []string) error {
30+
RunE: func(cmd *cobra.Command, args []string) error {
3131
cfg, err := crane.Config(args[0], *options...)
3232
if err != nil {
3333
return fmt.Errorf("fetching config: %w", err)
3434
}
35-
fmt.Print(string(cfg))
35+
fmt.Fprint(cmd.OutOrStdout(), string(cfg))
3636
return nil
3737
},
3838
}

cmd/crane/cmd/copy.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,36 @@
1515
package cmd
1616

1717
import (
18+
"runtime"
19+
1820
"github.com/google/go-containerregistry/pkg/crane"
1921
"github.com/spf13/cobra"
2022
)
2123

2224
// NewCmdCopy creates a new cobra.Command for the copy subcommand.
2325
func NewCmdCopy(options *[]crane.Option) *cobra.Command {
24-
return &cobra.Command{
26+
allTags := false
27+
noclobber := false
28+
jobs := runtime.GOMAXPROCS(0)
29+
cmd := &cobra.Command{
2530
Use: "copy SRC DST",
2631
Aliases: []string{"cp"},
2732
Short: "Efficiently copy a remote image from src to dst while retaining the digest value",
2833
Args: cobra.ExactArgs(2),
2934
RunE: func(_ *cobra.Command, args []string) error {
35+
opts := append(*options, crane.WithJobs(jobs), crane.WithNoClobber(noclobber))
3036
src, dst := args[0], args[1]
31-
return crane.Copy(src, dst, *options...)
37+
if allTags {
38+
return crane.CopyRepository(src, dst, opts...)
39+
}
40+
41+
return crane.Copy(src, dst, opts...)
3242
},
3343
}
44+
45+
cmd.Flags().BoolVarP(&allTags, "all-tags", "a", false, "(Optional) if true, copy all tags from SRC to DST")
46+
cmd.Flags().BoolVarP(&noclobber, "no-clobber", "n", false, "(Optional) if true, avoid overwriting existing tags in DST")
47+
cmd.Flags().IntVarP(&jobs, "jobs", "j", 0, "(Optional) The maximum number of concurrent copies, defaults to GOMAXPROCS")
48+
49+
return cmd
3450
}

0 commit comments

Comments
 (0)