mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-19 01:06:27 +00:00
cmd: Add support for private repositories and registries
This commit adds support for authentication for image pulls for 'linuxkit build'. For each image reference we look up credentials via the docker CLI configuration and use it if defined for a given registry server. The code caches credentials to avoid lookups for every image. Signed-off-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
This commit is contained in:
parent
1679668121
commit
615b122767
@ -14,13 +14,25 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/containerd/containerd/reference"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/config"
|
||||
"github.com/docker/cli/cli/config/configfile"
|
||||
distref "github.com/docker/distribution/reference"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/registry"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var (
|
||||
// configFile is a cached copy of the client config file
|
||||
configFile *configfile.ConfigFile
|
||||
// authCache maps a registry URL to encoded authentication
|
||||
authCache map[string]string
|
||||
)
|
||||
|
||||
func dockerRun(input io.Reader, output io.Writer, trust bool, img string, args ...string) error {
|
||||
log.Debugf("docker run %s (trust=%t) (input): %s", img, trust, strings.Join(args, " "))
|
||||
docker, err := exec.LookPath("docker")
|
||||
@ -146,7 +158,8 @@ func dockerPull(ref *reference.Spec, forcePull, trustedPull bool) error {
|
||||
}
|
||||
|
||||
log.Infof("Pull image: %s", ref)
|
||||
r, err := cli.ImagePull(context.Background(), ref.String(), types.ImagePullOptions{})
|
||||
pullOptions := types.ImagePullOptions{RegistryAuth: getAuth(cli, ref.String())}
|
||||
r, err := cli.ImagePull(context.Background(), ref.String(), pullOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -191,3 +204,48 @@ func dockerInspectImage(cli *client.Client, ref *reference.Spec, trustedPull boo
|
||||
|
||||
return inspect, nil
|
||||
}
|
||||
|
||||
// getAuth attempts to get an encoded authentication spec for a reference
|
||||
// This function does not error. It simply returns a empty string if something fails.
|
||||
func getAuth(cli *client.Client, refStr string) string {
|
||||
// Initialise state on first use
|
||||
if authCache == nil {
|
||||
authCache = make(map[string]string)
|
||||
}
|
||||
if configFile == nil {
|
||||
configFile = config.LoadDefaultConfigFile(ioutil.Discard)
|
||||
}
|
||||
|
||||
// Normalise ref
|
||||
ref, err := distref.ParseNormalizedNamed(refStr)
|
||||
if err != nil {
|
||||
log.Debugf("Failed to parse reference %s: %v: %v", refStr, err)
|
||||
return ""
|
||||
}
|
||||
hostname := distref.Domain(ref)
|
||||
// Special case for docker.io which currently is stored as https://index.docker.io/v1/ in authentication map.
|
||||
// Other registries are stored under their domain name.
|
||||
if hostname == registry.IndexName {
|
||||
hostname = registry.IndexServer
|
||||
}
|
||||
|
||||
// Look up in cache
|
||||
if val, ok := authCache[hostname]; ok {
|
||||
log.Debugf("Returning cached credentials for %s", hostname)
|
||||
return val
|
||||
}
|
||||
|
||||
authConfig, err := configFile.GetAuthConfig(hostname)
|
||||
if err != nil {
|
||||
log.Debugf("Failed to get authentication config for %s. Ignoring: %v", hostname, err)
|
||||
return ""
|
||||
}
|
||||
log.Debugf("Looked up credentials for %s", hostname)
|
||||
|
||||
encodedAuth, err := command.EncodeAuthToBase64(authConfig)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
authCache[hostname] = encodedAuth
|
||||
return encodedAuth
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user