Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to Hosts from deprecated resolver config #227

Merged
merged 1 commit into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions v2/cmd/manifest-tool/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,13 @@ var inspectCmd = &cli.Command{
logrus.Fatal("the --expand-config flag is only valid when used with --raw")
}
memoryStore := store.NewMemoryStore()
resolver := util.NewResolver(c.String("username"), c.String("password"), c.Bool("insecure"),
c.Bool("plain-http"), c.String("docker-cfg"))
err = util.CreateRegistryHost(imageRef, c.String("username"), c.String("password"), c.Bool("insecure"),
c.Bool("plain-http"), c.String("docker-cfg"), false)
if err != nil {
return fmt.Errorf("error creating registry host configuration: %v", err)
}

descriptor, err := registry.FetchDescriptor(resolver, memoryStore, imageRef)
descriptor, err := registry.FetchDescriptor(util.GetResolver(), memoryStore, imageRef)
if err != nil {
logrus.Error(err)
}
Expand Down
10 changes: 6 additions & 4 deletions v2/pkg/registry/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ func PushManifestList(username, password string, input types.YAMLInput, ignoreMi
return hash, length, fmt.Errorf("error parsing name for manifest list (%s): %v", input.Image, err)
}

resolver := util.NewResolver(username, password, insecure, plainHttp, configDir)

err = util.CreateRegistryHost(targetRef, username, password, insecure, plainHttp, configDir, true)
if err != nil {
return hash, length, fmt.Errorf("error creating registry host configuration: %v", err)
}
manifestList := types.ManifestList{
Name: input.Image,
Reference: targetRef,
Resolver: resolver,
Resolver: util.GetResolver(),
Type: manifestType,
}
// create an in-memory store for OCI descriptors and content used during the push operation
Expand All @@ -48,7 +50,7 @@ func PushManifestList(username, password string, input types.YAMLInput, ignoreMi
if reference.Domain(targetRef) != reference.Domain(ref) {
return hash, length, fmt.Errorf("source image (%s) registry does not match target image (%s) registry", ref, targetRef)
}
descriptor, err := FetchDescriptor(resolver, memoryStore, ref)
descriptor, err := FetchDescriptor(util.GetResolver(), memoryStore, ref)
if err != nil {
if ignoreMissing {
logrus.Warnf("Couldn't access image '%q'. Skipping due to 'ignore missing' configuration.", img.Image)
Expand Down
102 changes: 64 additions & 38 deletions v2/pkg/util/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package util

import (
"crypto/tls"
"fmt"
"net/http"
"os"
"strings"
Expand All @@ -11,64 +12,74 @@ import (
"github.com/docker/cli/cli/config"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/config/credentials"
"github.com/docker/distribution/reference"
"github.com/sirupsen/logrus"
)

func NewResolver(username, password string, insecure, plainHTTP bool, dockerConfigPath string) remotes.Resolver {
var registryHost docker.RegistryHost

opts := docker.ResolverOptions{
PlainHTTP: plainHTTP,
func CreateRegistryHost(imageRef reference.Named, username, password string, insecure, plainHTTP bool, dockerConfigPath string, pushOp bool) error {

hostname, _ := splitHostname(imageRef.String())
if hostname == "docker.io" {
hostname = "registry-1.docker.io"
}
registryHost = docker.RegistryHost{
Host: hostname,
Scheme: "https",
Path: "/v2",
Capabilities: docker.HostCapabilityPull | docker.HostCapabilityResolve,
}
if pushOp {
registryHost.Capabilities |= docker.HostCapabilityPush
}

client := http.DefaultClient

if insecure {
client.Transport = &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
}
opts.Client = client
registryHost.Client = client

if username != "" || password != "" {
opts.Credentials = func(hostName string) (string, string, error) {
return username, password, nil
}
return docker.NewResolver(opts)
if plainHTTP {
registryHost.Scheme = "http"
}
var (
err error
cfg *configfile.ConfigFile
)
if dockerConfigPath == "" || dockerConfigPath == config.Dir() {
cfg, err = config.Load(config.Dir())
if err != nil {
// handle error
logrus.Errorf("unable to load default Docker auth config: %v", err)

credFunc := func(hostName string) (string, string, error) {
if username != "" || password != "" {
return username, password, nil
}
} else {
cfg = configfile.New(dockerConfigPath)
if _, err := os.Stat(dockerConfigPath); err == nil {
file, err := os.Open(dockerConfigPath)
var (
err error
cfg *configfile.ConfigFile
)
if dockerConfigPath == "" || dockerConfigPath == config.Dir() {
cfg, err = config.Load(config.Dir())
if err != nil {
logrus.Errorf("Can't load docker config file %s: %v", dockerConfigPath, err)
// fall back to resolver with no config
return docker.NewResolver(opts)
logrus.Warnf("unable to load default Docker auth config: %v", err)
}
defer file.Close()
if err := cfg.LoadFromReader(file); err != nil {
logrus.Errorf("Can't read and parse docker config file %s: %v", dockerConfigPath, err)
return docker.NewResolver(opts)
} else {
cfg = configfile.New(dockerConfigPath)
if _, err := os.Stat(dockerConfigPath); err == nil {
file, err := os.Open(dockerConfigPath)
if err != nil {
return "", "", fmt.Errorf("can't load docker config file %s: %w", dockerConfigPath, err)
}
defer file.Close()
if err := cfg.LoadFromReader(file); err != nil {
return "", "", fmt.Errorf("can't read and parse docker config file %s: %v", dockerConfigPath, err)
}
} else if !os.IsNotExist(err) {
return "", "", fmt.Errorf("unable to open docker config file %s: %v", dockerConfigPath, err)
}
} else if !os.IsNotExist(err) {
logrus.Errorf("Unable to open docker config file %s: %v", dockerConfigPath, err)
return docker.NewResolver(opts)
}
}
if !cfg.ContainsAuth() {
cfg.CredentialsStore = credentials.DetectDefaultStore(cfg.CredentialsStore)
}
// support cred helpers
opts.Credentials = func(hostName string) (string, string, error) {
if !cfg.ContainsAuth() {
cfg.CredentialsStore = credentials.DetectDefaultStore(cfg.CredentialsStore)
}
hostname := resolveHostname(hostName)
auth, err := cfg.GetAuthConfig(hostname)
if err != nil {
Expand All @@ -78,10 +89,25 @@ func NewResolver(username, password string, insecure, plainHTTP bool, dockerConf
return "", auth.IdentityToken, nil
}
return auth.Username, auth.Password, nil

}
registryHost.Authorizer = docker.NewDockerAuthorizer(docker.WithAuthCreds(credFunc))

return nil
}

func GetResolver() remotes.Resolver {

opts := docker.ResolverOptions{
Hosts: getHosts,
}
return docker.NewResolver(opts)
}

func getHosts(name string) ([]docker.RegistryHost, error) {
return []docker.RegistryHost{registryHost}, nil
}

// resolveHostname resolves Docker specific hostnames
func resolveHostname(hostname string) string {
if strings.HasSuffix(hostname, "docker.io") {
Expand Down
Loading