Skip to content

Commit 0bbed02

Browse files
committed
- remove a way to get token from docker library
- use `go-containerregistry` library to retrieve authConfig, make sure we use the same way to handle pulling image from private registry. Signed-off-by: Chuan-Yen Chiang <[email protected]>
1 parent b6943fd commit 0bbed02

File tree

4 files changed

+19
-100
lines changed

4 files changed

+19
-100
lines changed

cmd/crank/render/runtime_docker.go

Lines changed: 16 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,19 @@ package render
1818

1919
import (
2020
"context"
21+
"encoding/base64"
2122
"fmt"
2223
"io"
2324
"net"
24-
"os"
25-
"path/filepath"
2625

27-
"github.com/distribution/reference"
28-
"github.com/docker/cli/cli/config"
29-
"github.com/docker/cli/cli/config/configfile"
3026
"github.com/docker/docker/api/types/container"
3127
"github.com/docker/docker/api/types/filters"
3228
typesimage "github.com/docker/docker/api/types/image"
33-
registrytypes "github.com/docker/docker/api/types/registry"
3429
"github.com/docker/docker/client"
3530
"github.com/docker/docker/errdefs"
36-
"github.com/docker/docker/registry"
3731
"github.com/docker/go-connections/nat"
32+
"github.com/google/go-containerregistry/pkg/authn"
33+
"github.com/google/go-containerregistry/pkg/name"
3834

3935
"github.com/crossplane/crossplane-runtime/pkg/errors"
4036
"github.com/crossplane/crossplane-runtime/pkg/logging"
@@ -113,12 +109,12 @@ type RuntimeDocker struct {
113109
// Cleanup controls how the containers are handled after rendering.
114110
Cleanup DockerCleanup
115111

116-
// ConfigFile contains information like credentials for each registry, default to ~/.docker/config.json
117-
ConfigFile *configfile.ConfigFile
118-
119112
// PullPolicy controls how the runtime image is pulled.
120113
PullPolicy DockerPullPolicy
121114

115+
// Keychain to use for pulling images from private registry.
116+
Keychain authn.Keychain
117+
122118
// log is the logger for this runtime.
123119
log logging.Logger
124120
}
@@ -163,31 +159,12 @@ func GetRuntimeDocker(fn pkgv1.Function, log logging.Logger) (*RuntimeDocker, er
163159
return nil, errors.Wrapf(err, "cannot get pull policy for Function %q", fn.GetName())
164160
}
165161

166-
// Initial ConfigFile, first check environment variable XDG_RUNTIME_DIR for Podman if it exists
167-
// Otherwise, use the default Docker config file
168-
var configFile *configfile.ConfigFile
169-
if _, err := os.Stat(filepath.Join(os.Getenv("XDG_RUNTIME_DIR"), "containers/auth.json")); err == nil {
170-
// Use the auth.json file if specified XDG_RUNTIME_DIR and file exists
171-
f, err := os.Open(filepath.Join(os.Getenv("XDG_RUNTIME_DIR"), "containers/auth.json"))
172-
if err != nil {
173-
return nil, errors.Wrapf(err, "cannot open file %s", filepath.Join(os.Getenv("XDG_RUNTIME_DIR"), "containers/auth.json"))
174-
}
175-
defer f.Close() //nolint:errcheck // Only open for reading.
176-
177-
configFile, err = config.LoadFromReader(f)
178-
if err != nil {
179-
return nil, errors.Wrapf(err, "cannot load config file from reader")
180-
}
181-
} else {
182-
configFile = config.LoadDefaultConfigFile(os.Stderr)
183-
}
184-
185162
r := &RuntimeDocker{
186163
Image: fn.Spec.Package,
187164
Name: "",
188165
Cleanup: cleanup,
189-
ConfigFile: configFile,
190166
PullPolicy: pullPolicy,
167+
Keychain: authn.DefaultKeychain,
191168
log: log,
192169
}
193170

@@ -318,33 +295,29 @@ func (r *RuntimeDocker) createContainer(ctx context.Context, cli *client.Client)
318295
}
319296

320297
func (r *RuntimeDocker) getPullOptions() (typesimage.PullOptions, error) {
321-
// Resolve auth token by looking into config file
322-
named, err := reference.ParseNormalizedNamed(r.Image)
298+
// Resolve auth token by looking into keychain
299+
ref, err := name.ParseReference(r.Image)
323300
if err != nil {
324301
return typesimage.PullOptions{}, errors.Wrapf(err, "Image is not a valid reference %s", r.Image)
325302
}
326303

327-
repoInfo, err := registry.ParseRepositoryInfo(named)
304+
auth, err := r.Keychain.Resolve(ref.Context().Registry)
328305
if err != nil {
329-
return typesimage.PullOptions{}, errors.Wrapf(err, "Cannot parse repository info: %s", named.String())
306+
return typesimage.PullOptions{}, errors.Wrapf(err, "Cannot resolve auth for %s", ref.Context().RegistryStr())
330307
}
331308

332-
configKey := repoInfo.Index.Name
333-
if repoInfo.Index.Official {
334-
configKey = registry.IndexServer
335-
}
336-
authConfig, err := r.ConfigFile.GetAuthConfig(configKey)
309+
authConfig, err := auth.Authorization()
337310
if err != nil {
338-
return typesimage.PullOptions{}, errors.Wrapf(err, "Cannot get auth config info with configKey: %s", configKey)
311+
return typesimage.PullOptions{}, errors.Wrapf(err, "Cannot get auth config for %s", ref.Context().RegistryStr())
339312
}
340313

341-
encodedAuth, err := registrytypes.EncodeAuthConfig(registrytypes.AuthConfig(authConfig))
314+
token, err := authConfig.MarshalJSON()
342315
if err != nil {
343-
return typesimage.PullOptions{}, errors.Wrapf(err, "Cannot encode auth config with configKey: %s", configKey)
316+
return typesimage.PullOptions{}, errors.Wrapf(err, "Cannot marshal auth config for %s", ref.Context().RegistryStr())
344317
}
345318

346319
return typesimage.PullOptions{
347-
RegistryAuth: encodedAuth,
320+
RegistryAuth: base64.URLEncoding.EncodeToString(token),
348321
}, nil
349322
}
350323

cmd/crank/render/runtime_docker_test.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@ package render
1919
import (
2020
"context"
2121
"io"
22-
"os"
2322
"testing"
2423

25-
"github.com/docker/cli/cli/config"
2624
"github.com/docker/docker/api/types/image"
2725
"github.com/google/go-cmp/cmp"
2826
"github.com/google/go-cmp/cmp/cmpopts"
@@ -78,7 +76,6 @@ func TestGetRuntimeDocker(t *testing.T) {
7876
want: want{
7977
rd: &RuntimeDocker{
8078
Image: "test-image-from-annotation",
81-
ConfigFile: config.LoadDefaultConfigFile(os.Stderr),
8279
Cleanup: AnnotationValueRuntimeDockerCleanupOrphan,
8380
PullPolicy: AnnotationValueRuntimeDockerPullPolicyAlways,
8481
},
@@ -105,7 +102,6 @@ func TestGetRuntimeDocker(t *testing.T) {
105102
want: want{
106103
rd: &RuntimeDocker{
107104
Image: "test-image-from-annotation",
108-
ConfigFile: config.LoadDefaultConfigFile(os.Stderr),
109105
Cleanup: AnnotationValueRuntimeDockerCleanupOrphan,
110106
Name: "test-container-name-function",
111107
PullPolicy: AnnotationValueRuntimeDockerPullPolicyIfNotPresent,
@@ -129,7 +125,6 @@ func TestGetRuntimeDocker(t *testing.T) {
129125
want: want{
130126
rd: &RuntimeDocker{
131127
Image: "test-package",
132-
ConfigFile: config.LoadDefaultConfigFile(os.Stderr),
133128
Cleanup: AnnotationValueRuntimeDockerCleanupRemove,
134129
PullPolicy: AnnotationValueRuntimeDockerPullPolicyIfNotPresent,
135130
},
@@ -194,7 +189,6 @@ func TestGetRuntimeDocker(t *testing.T) {
194189
want: want{
195190
rd: &RuntimeDocker{
196191
Image: "test-package",
197-
ConfigFile: config.LoadDefaultConfigFile(os.Stderr),
198192
Cleanup: AnnotationValueRuntimeDockerCleanupStop,
199193
PullPolicy: AnnotationValueRuntimeDockerPullPolicyIfNotPresent,
200194
},
@@ -204,7 +198,7 @@ func TestGetRuntimeDocker(t *testing.T) {
204198
for name, tc := range cases {
205199
t.Run(name, func(t *testing.T) {
206200
rd, err := GetRuntimeDocker(tc.args.fn, logging.NewNopLogger())
207-
if diff := cmp.Diff(tc.want.rd, rd, cmpopts.IgnoreUnexported(RuntimeDocker{})); diff != "" {
201+
if diff := cmp.Diff(tc.want.rd, rd, cmpopts.IgnoreUnexported(RuntimeDocker{}), cmpopts.IgnoreFields(RuntimeDocker{}, "Keychain")); diff != "" {
208202
t.Errorf("\n%s\nGetRuntimeDocker(...): -want, +got:\n%s", tc.reason, diff)
209203
}
210204
if diff := cmp.Diff(tc.want.err, err, cmpopts.EquateErrors()); diff != "" {

go.mod

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ require (
88
github.com/Masterminds/semver v1.5.0
99
github.com/alecthomas/kong v0.9.0
1010
github.com/crossplane/crossplane-runtime v1.19.0-rc.0.0.20241105071456-19d95a69cc03
11-
github.com/distribution/reference v0.5.0
1211
github.com/docker/docker v27.1.1+incompatible
1312
github.com/docker/go-connections v0.5.0
1413
github.com/emicklei/dot v1.6.2
@@ -64,8 +63,7 @@ require (
6463
github.com/cyphar/filepath-securejoin v0.2.5 // indirect
6564
github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 // indirect
6665
github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 // indirect
67-
github.com/docker/go-metrics v0.0.1 // indirect
68-
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect
66+
github.com/distribution/reference v0.5.0 // indirect
6967
github.com/dustin/go-humanize v1.0.1 // indirect
7068
github.com/emirpasic/gods v1.18.1 // indirect
7169
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
@@ -89,7 +87,6 @@ require (
8987
github.com/google/certificate-transparency-go v1.2.1 // indirect
9088
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
9189
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
92-
github.com/gorilla/mux v1.8.1 // indirect
9390
github.com/gorilla/websocket v1.5.1 // indirect
9491
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
9592
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
@@ -192,7 +189,7 @@ require (
192189
github.com/dave/jennifer v1.6.0 // indirect
193190
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
194191
github.com/dimchansky/utfbom v1.1.1 // indirect
195-
github.com/docker/cli v27.4.1+incompatible
192+
github.com/docker/cli v27.4.1+incompatible // indirect
196193
github.com/docker/distribution v2.8.3+incompatible // indirect
197194
github.com/docker/docker-credential-helpers v0.8.2
198195
github.com/docker/go-units v0.5.0 // indirect

0 commit comments

Comments
 (0)