Skip to content

Commit ae84e6f

Browse files
authored
feat: support credential helpers (#65)
1 parent 88219a2 commit ae84e6f

File tree

4 files changed

+59
-2
lines changed

4 files changed

+59
-2
lines changed

cli/docker.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515

1616
dockertypes "github.com/docker/docker/api/types"
1717
"github.com/docker/docker/api/types/container"
18+
"github.com/google/go-containerregistry/pkg/name"
1819
"github.com/spf13/cobra"
1920
"golang.org/x/exp/slices"
2021
"golang.org/x/xerrors"
@@ -98,6 +99,7 @@ var (
9899
EnvMemory = "CODER_MEMORY"
99100
EnvAddGPU = "CODER_ADD_GPU"
100101
EnvUsrLibDir = "CODER_USR_LIB_DIR"
102+
EnvDockerConfig = "CODER_DOCKER_CONFIG"
101103
EnvDebug = "CODER_DEBUG"
102104
EnvDisableIDMappedMount = "CODER_DISABLE_IDMAPPED_MOUNT"
103105
)
@@ -133,6 +135,7 @@ type flags struct {
133135
boostrapScript string
134136
containerMounts string
135137
hostUsrLibDir string
138+
dockerConfig string
136139
cpus int
137140
memory int
138141
disableIDMappedMount bool
@@ -336,6 +339,7 @@ func dockerCmd() *cobra.Command {
336339
cliflag.StringVarP(cmd.Flags(), &flags.boostrapScript, "boostrap-script", "", EnvBootstrap, "", "The script to use to bootstrap the container. This should typically install and start the agent.")
337340
cliflag.StringVarP(cmd.Flags(), &flags.containerMounts, "mounts", "", EnvMounts, "", "Comma separated list of mounts in the form of '<source>:<target>[:options]' (e.g. /var/lib/docker:/var/lib/docker:ro,/usr/src:/usr/src).")
338341
cliflag.StringVarP(cmd.Flags(), &flags.hostUsrLibDir, "usr-lib-dir", "", EnvUsrLibDir, "", "The host /usr/lib mountpoint. Used to detect GPU drivers to mount into inner container.")
342+
cliflag.StringVarP(cmd.Flags(), &flags.dockerConfig, "docker-config", "", EnvDockerConfig, "/root/.docker/config.json", "The path to the docker config to consult when pulling an image.")
339343
cliflag.BoolVarP(cmd.Flags(), &flags.addTUN, "add-tun", "", EnvAddTun, false, "Add a TUN device to the inner container.")
340344
cliflag.BoolVarP(cmd.Flags(), &flags.addFUSE, "add-fuse", "", EnvAddFuse, false, "Add a FUSE device to the inner container.")
341345
cliflag.BoolVarP(cmd.Flags(), &flags.addGPU, "add-gpu", "", EnvAddGPU, false, "Add detected GPUs to the inner container.")
@@ -369,6 +373,19 @@ func runDockerCVM(ctx context.Context, log slog.Logger, client dockerutil.Docker
369373
}
370374
}
371375

376+
log.Info(ctx, "checking for docker config file", slog.F("path", flags.dockerConfig))
377+
if _, err := fs.Stat(flags.dockerConfig); err == nil {
378+
log.Info(ctx, "detected file", slog.F("image", flags.innerImage))
379+
ref, err := name.NewTag(flags.innerImage)
380+
if err != nil {
381+
return xerrors.Errorf("parse ref: %w", err)
382+
}
383+
dockerAuth, err = dockerutil.AuthConfigFromPath(flags.dockerConfig, ref.RegistryStr())
384+
if err != nil && !xerrors.Is(err, os.ErrNotExist) {
385+
return xerrors.Errorf("auth config from file: %w", err)
386+
}
387+
}
388+
372389
envs := defaultContainerEnvs(ctx, flags.agentToken)
373390

374391
innerEnvsTokens := strings.Split(flags.innerEnvs, ",")

dockerutil/client.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ import (
44
"context"
55
"encoding/base64"
66
"encoding/json"
7+
"os"
78

9+
"github.com/cpuguy83/dockercfg"
810
dockertypes "github.com/docker/docker/api/types"
911
dockerclient "github.com/docker/docker/client"
12+
1013
"golang.org/x/xerrors"
1114
)
1215

@@ -45,6 +48,39 @@ func (a AuthConfig) Base64() (string, error) {
4548
return base64.URLEncoding.EncodeToString(authStr), nil
4649
}
4750

51+
func AuthConfigFromPath(path string, registry string) (AuthConfig, error) {
52+
var config dockercfg.Config
53+
err := dockercfg.FromFile(path, &config)
54+
if err != nil {
55+
return AuthConfig{}, xerrors.Errorf("load config: %w", err)
56+
}
57+
58+
hostname := dockercfg.ResolveRegistryHost(registry)
59+
60+
if config, ok := config.AuthConfigs[registry]; ok {
61+
return AuthConfig(config), nil
62+
}
63+
64+
username, secret, err := config.GetRegistryCredentials(hostname)
65+
if err != nil {
66+
return AuthConfig{}, xerrors.Errorf("get credentials from helper: %w", err)
67+
}
68+
69+
if secret != "" {
70+
if username == "" {
71+
return AuthConfig{
72+
IdentityToken: secret,
73+
}, nil
74+
}
75+
return AuthConfig{
76+
Username: username,
77+
Password: secret,
78+
}, nil
79+
}
80+
81+
return AuthConfig{}, xerrors.Errorf("no auth config found for registry %s: %w", registry, os.ErrNotExist)
82+
}
83+
4884
func ParseAuthConfig(raw string) (AuthConfig, error) {
4985
type dockerConfig struct {
5086
AuthConfigs map[string]dockertypes.AuthConfig `json:"auths"`

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ require (
1313
cdr.dev/slog v1.5.4
1414
github.com/coder/coder v0.27.3
1515
github.com/coder/retry v1.4.0
16+
github.com/cpuguy83/dockercfg v0.3.1
1617
github.com/docker/docker v23.0.8+incompatible
18+
github.com/google/go-containerregistry v0.9.0
1719
github.com/opencontainers/image-spec v1.1.0-rc2
1820
github.com/ory/dockertest/v3 v3.10.0
1921
github.com/quasilyte/go-ruleguard/dsl v0.3.22
@@ -121,7 +123,6 @@ require (
121123
github.com/mitchellh/reflectwalk v1.0.2 // indirect
122124
github.com/moby/sys/mountinfo v0.6.2 // indirect
123125
github.com/moby/term v0.5.0 // indirect
124-
github.com/morikuni/aec v1.0.0 // indirect
125126
github.com/muesli/reflow v0.3.0 // indirect
126127
github.com/muesli/termenv v0.15.1 // indirect
127128
github.com/open-policy-agent/opa v0.51.0 // indirect

go.sum

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFE
155155
github.com/coreos/go-oidc/v3 v3.6.0 h1:AKVxfYw1Gmkn/w96z0DbT/B/xFnzTd3MkZvWLjF4n/o=
156156
github.com/coreos/go-oidc/v3 v3.6.0/go.mod h1:ZpHUsHBucTUj6WOkrP4E20UPynbLZzhTQ1XKCXkxyPc=
157157
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
158+
github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E=
159+
github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
158160
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
159161
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
160162
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
@@ -322,6 +324,8 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
322324
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
323325
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
324326
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
327+
github.com/google/go-containerregistry v0.9.0 h1:5Ths7RjxyFV0huKChQTgY6fLzvHhZMpLTFNja8U0/0w=
328+
github.com/google/go-containerregistry v0.9.0/go.mod h1:9eq4BnSufyT1kHNffX+vSXVonaJ7yaIOulrKZejMxnQ=
325329
github.com/google/go-github/v43 v43.0.1-0.20220414155304-00e42332e405 h1:DdHws/YnnPrSywrjNYu2lEHqYHWp/LnEx56w59esd54=
326330
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
327331
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -516,7 +520,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
516520
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
517521
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
518522
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
519-
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
520523
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
521524
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
522525
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=

0 commit comments

Comments
 (0)