Skip to content

Commit

Permalink
feat: support credential helpers (#65)
Browse files Browse the repository at this point in the history
  • Loading branch information
sreya authored Feb 6, 2024
1 parent 88219a2 commit ae84e6f
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 2 deletions.
17 changes: 17 additions & 0 deletions cli/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (

dockertypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/google/go-containerregistry/pkg/name"
"github.com/spf13/cobra"
"golang.org/x/exp/slices"
"golang.org/x/xerrors"
Expand Down Expand Up @@ -98,6 +99,7 @@ var (
EnvMemory = "CODER_MEMORY"
EnvAddGPU = "CODER_ADD_GPU"
EnvUsrLibDir = "CODER_USR_LIB_DIR"
EnvDockerConfig = "CODER_DOCKER_CONFIG"
EnvDebug = "CODER_DEBUG"
EnvDisableIDMappedMount = "CODER_DISABLE_IDMAPPED_MOUNT"
)
Expand Down Expand Up @@ -133,6 +135,7 @@ type flags struct {
boostrapScript string
containerMounts string
hostUsrLibDir string
dockerConfig string
cpus int
memory int
disableIDMappedMount bool
Expand Down Expand Up @@ -336,6 +339,7 @@ func dockerCmd() *cobra.Command {
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.")
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).")
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.")
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.")
cliflag.BoolVarP(cmd.Flags(), &flags.addTUN, "add-tun", "", EnvAddTun, false, "Add a TUN device to the inner container.")
cliflag.BoolVarP(cmd.Flags(), &flags.addFUSE, "add-fuse", "", EnvAddFuse, false, "Add a FUSE device to the inner container.")
cliflag.BoolVarP(cmd.Flags(), &flags.addGPU, "add-gpu", "", EnvAddGPU, false, "Add detected GPUs to the inner container.")
Expand Down Expand Up @@ -369,6 +373,19 @@ func runDockerCVM(ctx context.Context, log slog.Logger, client dockerutil.Docker
}
}

log.Info(ctx, "checking for docker config file", slog.F("path", flags.dockerConfig))
if _, err := fs.Stat(flags.dockerConfig); err == nil {
log.Info(ctx, "detected file", slog.F("image", flags.innerImage))
ref, err := name.NewTag(flags.innerImage)
if err != nil {
return xerrors.Errorf("parse ref: %w", err)
}
dockerAuth, err = dockerutil.AuthConfigFromPath(flags.dockerConfig, ref.RegistryStr())
if err != nil && !xerrors.Is(err, os.ErrNotExist) {
return xerrors.Errorf("auth config from file: %w", err)
}
}

envs := defaultContainerEnvs(ctx, flags.agentToken)

innerEnvsTokens := strings.Split(flags.innerEnvs, ",")
Expand Down
36 changes: 36 additions & 0 deletions dockerutil/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import (
"context"
"encoding/base64"
"encoding/json"
"os"

"github.com/cpuguy83/dockercfg"
dockertypes "github.com/docker/docker/api/types"
dockerclient "github.com/docker/docker/client"

"golang.org/x/xerrors"
)

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

func AuthConfigFromPath(path string, registry string) (AuthConfig, error) {
var config dockercfg.Config
err := dockercfg.FromFile(path, &config)
if err != nil {
return AuthConfig{}, xerrors.Errorf("load config: %w", err)
}

hostname := dockercfg.ResolveRegistryHost(registry)

if config, ok := config.AuthConfigs[registry]; ok {
return AuthConfig(config), nil
}

username, secret, err := config.GetRegistryCredentials(hostname)
if err != nil {
return AuthConfig{}, xerrors.Errorf("get credentials from helper: %w", err)
}

if secret != "" {
if username == "" {
return AuthConfig{
IdentityToken: secret,
}, nil
}
return AuthConfig{
Username: username,
Password: secret,
}, nil
}

return AuthConfig{}, xerrors.Errorf("no auth config found for registry %s: %w", registry, os.ErrNotExist)
}

func ParseAuthConfig(raw string) (AuthConfig, error) {
type dockerConfig struct {
AuthConfigs map[string]dockertypes.AuthConfig `json:"auths"`
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ require (
cdr.dev/slog v1.5.4
github.com/coder/coder v0.27.3
github.com/coder/retry v1.4.0
github.com/cpuguy83/dockercfg v0.3.1
github.com/docker/docker v23.0.8+incompatible
github.com/google/go-containerregistry v0.9.0
github.com/opencontainers/image-spec v1.1.0-rc2
github.com/ory/dockertest/v3 v3.10.0
github.com/quasilyte/go-ruleguard/dsl v0.3.22
Expand Down Expand Up @@ -121,7 +123,6 @@ require (
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/sys/mountinfo v0.6.2 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/muesli/reflow v0.3.0 // indirect
github.com/muesli/termenv v0.15.1 // indirect
github.com/open-policy-agent/opa v0.51.0 // indirect
Expand Down
5 changes: 4 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFE
github.com/coreos/go-oidc/v3 v3.6.0 h1:AKVxfYw1Gmkn/w96z0DbT/B/xFnzTd3MkZvWLjF4n/o=
github.com/coreos/go-oidc/v3 v3.6.0/go.mod h1:ZpHUsHBucTUj6WOkrP4E20UPynbLZzhTQ1XKCXkxyPc=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E=
github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
Expand Down Expand Up @@ -322,6 +324,8 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-containerregistry v0.9.0 h1:5Ths7RjxyFV0huKChQTgY6fLzvHhZMpLTFNja8U0/0w=
github.com/google/go-containerregistry v0.9.0/go.mod h1:9eq4BnSufyT1kHNffX+vSXVonaJ7yaIOulrKZejMxnQ=
github.com/google/go-github/v43 v43.0.1-0.20220414155304-00e42332e405 h1:DdHws/YnnPrSywrjNYu2lEHqYHWp/LnEx56w59esd54=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
Expand Down Expand Up @@ -516,7 +520,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
Expand Down

0 comments on commit ae84e6f

Please sign in to comment.