diff --git a/remotes/docker/scope.go b/remotes/docker/scope.go index 86bd81bf5..fa8401433 100644 --- a/remotes/docker/scope.go +++ b/remotes/docker/scope.go @@ -51,19 +51,25 @@ func contextWithRepositoryScope(ctx context.Context, refspec reference.Spec, pus if err != nil { return nil, err } - return context.WithValue(ctx, tokenScopesKey{}, []string{s}), nil + return WithScope(ctx, s), nil +} + +// WithScope appends a custom registry auth scope to the context. +func WithScope(ctx context.Context, scope string) context.Context { + var scopes []string + if v := ctx.Value(tokenScopesKey{}); v != nil { + scopes = v.([]string) + scopes = append(scopes, scope) + } else { + scopes = []string{scope} + } + return context.WithValue(ctx, tokenScopesKey{}, scopes) } // contextWithAppendPullRepositoryScope is used to append repository pull // scope into existing scopes indexed by the tokenScopesKey{}. func contextWithAppendPullRepositoryScope(ctx context.Context, repo string) context.Context { - var scopes []string - - if v := ctx.Value(tokenScopesKey{}); v != nil { - scopes = append(scopes, v.([]string)...) - } - scopes = append(scopes, fmt.Sprintf("repository:%s:pull", repo)) - return context.WithValue(ctx, tokenScopesKey{}, scopes) + return WithScope(ctx, fmt.Sprintf("repository:%s:pull", repo)) } // getTokenScopes returns deduplicated and sorted scopes from ctx.Value(tokenScopesKey{}) and common scopes. diff --git a/remotes/docker/scope_test.go b/remotes/docker/scope_test.go index 938129f46..2ec0feebd 100644 --- a/remotes/docker/scope_test.go +++ b/remotes/docker/scope_test.go @@ -22,6 +22,7 @@ import ( "github.com/containerd/containerd/reference" "gotest.tools/assert" + "gotest.tools/assert/cmp" ) func TestRepositoryScope(t *testing.T) { @@ -94,3 +95,14 @@ func TestGetTokenScopes(t *testing.T) { assert.DeepEqual(t, tc.expected, actual) } } + +func TestCustomScope(t *testing.T) { + scope := "whatever:foo/bar:pull" + ctx := WithScope(context.Background(), scope) + ctx = contextWithAppendPullRepositoryScope(ctx, "foo/bar") + + scopes := getTokenScopes(ctx, []string{}) + assert.Assert(t, cmp.Len(scopes, 2)) + assert.Check(t, cmp.Equal(scopes[0], "repository:foo/bar:pull")) + assert.Check(t, cmp.Equal(scopes[1], scope)) +}