Merge pull request #6019 from thaJeztah/docker_auth_config_socket

cli/command/container: --use-api-socket: support DOCKER_AUTH_CONFIG
This commit is contained in:
Sebastiaan van Stijn 2025-05-16 11:57:49 +02:00 committed by GitHub
commit bca09c7ac4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 57 additions and 11 deletions

View File

@ -0,0 +1,46 @@
package container
import (
"fmt"
"os"
"strings"
"github.com/docker/cli/cli/config"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/config/types"
)
// readCredentials resolves auth-config from the current environment to be
// applied to the container if the `--use-api-socket` flag is set.
//
// - If a valid "DOCKER_AUTH_CONFIG" env-var is found, and it contains
// credentials, it's value is used.
// - If no "DOCKER_AUTH_CONFIG" env-var is found, or it does not contain
// credentials, it attempts to read from the CLI's credentials store.
//
// It returns an error if either the "DOCKER_AUTH_CONFIG" is incorrectly
// formatted, or when failing to read from the credentials store.
//
// A nil value is returned if neither option contained any credentials.
func readCredentials(dockerCLI config.Provider) (creds map[string]types.AuthConfig, _ error) {
if v, ok := os.LookupEnv("DOCKER_AUTH_CONFIG"); ok && v != "" {
// The results are expected to have been unmarshaled the same as
// when reading from a config-file, which includes decoding the
// base64-encoded "username:password" into the "UserName" and
// "Password" fields.
ac := &configfile.ConfigFile{}
if err := ac.LoadFromReader(strings.NewReader(v)); err != nil {
return nil, fmt.Errorf("failed to read credentials from DOCKER_AUTH_CONFIG: %w", err)
}
if len(ac.AuthConfigs) > 0 {
return ac.AuthConfigs, nil
}
}
// Resolve this here for later, ensuring we error our before we create the container.
creds, err := dockerCLI.ConfigFile().GetAllCredentials()
if err != nil {
return nil, fmt.Errorf("resolving credentials failed: %w", err)
}
return creds, nil
}

View File

@ -240,16 +240,6 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c
}
}
pullAndTagImage := func() error {
if err := pullImage(ctx, dockerCli, config.Image, options); err != nil {
return err
}
if taggedRef, ok := namedRef.(reference.NamedTagged); ok && trustedRef != nil {
return trust.TagTrusted(ctx, dockerCli.Client(), dockerCli.Err(), trustedRef, taggedRef)
}
return nil
}
const dockerConfigPathInContainer = "/run/secrets/docker/config.json"
var apiSocketCreds map[string]types.AuthConfig
@ -305,7 +295,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c
// what they're doing and don't inject the creds.
if !envvarPresent {
// Resolve this here for later, ensuring we error our before we create the container.
creds, err := dockerCli.ConfigFile().GetAllCredentials()
creds, err := readCredentials(dockerCli)
if err != nil {
return "", fmt.Errorf("resolving credentials failed: %w", err)
}
@ -331,6 +321,16 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c
platform = &p
}
pullAndTagImage := func() error {
if err := pullImage(ctx, dockerCli, config.Image, options); err != nil {
return err
}
if taggedRef, ok := namedRef.(reference.NamedTagged); ok && trustedRef != nil {
return trust.TagTrusted(ctx, dockerCli.Client(), dockerCli.Err(), trustedRef, taggedRef)
}
return nil
}
if options.pull == PullImageAlways {
if err := pullAndTagImage(); err != nil {
return "", err