func WithConfigHosts(configHosts []ConfigHost) Opt {
	return func(rc *regClient) {
		if configHosts == nil || len(configHosts) == 0 {
			return
		}
		for _, configHost := range configHosts {
			if configHost.Name == "" {
				continue
			}
			if configHost.Name == DockerRegistry || configHost.Name == DockerRegistryDNS || configHost.Name == DockerRegistryAuth {
				configHost.Name = DockerRegistry
				if configHost.Hostname == "" || configHost.Hostname == DockerRegistry || configHost.Hostname == DockerRegistryAuth {
					configHost.Hostname = DockerRegistryDNS
				}
			}
			tls, _ := configHost.TLS.MarshalText()
			rc.log.WithFields(logrus.Fields{
				"name":       configHost.Name,
				"user":       configHost.User,
				"hostname":   configHost.Hostname,
				"tls":        string(tls),
				"pathPrefix": configHost.PathPrefix,
				"mirrors":    configHost.Mirrors,
				"api":        configHost.API,
				"blobMax":    configHost.BlobMax,
				"blobChunk":  configHost.BlobChunk,
			}).Debug("Loading host config")
			err := rc.hostSet(configHost)
			if err != nil {
				rc.log.WithFields(logrus.Fields{
					"host":  configHost.Name,
					"user":  configHost.User,
					"error": err,
				}).Warn("Failed to update host config")
			}
		}
		return
	}
}
WithConfigHosts adds a list of config host settings
package regclient
import (
	"io/ioutil"
	"path/filepath"
	"strings"
	"sync"
	"time"
	_ "crypto/sha256"
	_ "crypto/sha512"
	"crypto/tls"
	"fmt"
	"net/http"
	"os"
	dockercfg "github.com/docker/cli/cli/config"
	"github.com/regclient/regclient/pkg/auth"
	"github.com/regclient/regclient/pkg/retryable"
	"github.com/sirupsen/logrus"
)
const (
	DefaultBlobChunk = 1024 * 1024
	DefaultBlobMax = -1
	DefaultRetryLimit = 3
	DefaultUserAgent = "regclient/regclient"
	DockerCertDir = "/etc/docker/certs.d"
	DockerRegistry = "docker.io"
	DockerRegistryAuth = "https://index.docker.io/v1/"
	DockerRegistryDNS = "registry-1.docker.io"
)
var (
	VCSRef = "unknown"
)
type RegClient interface {
	RepoClient
	TagClient
	ManifestClient
	ImageClient
	BlobClient
}
type regClient struct {
	certPaths      []string
	hosts          map[string]*regClientHost
	log            *logrus.Logger
	retryLimit     int
	retryDelayInit time.Duration
	retryDelayMax  time.Duration
	blobChunkSize  int64
	blobMaxPut     int64
	mu             sync.Mutex
	userAgent      string
}
type regClientHost struct {
	config    *ConfigHost
	retryable retryable.Retryable
}
type Opt func(*regClient)
func NewRegClient(opts ...Opt) RegClient {
	var rc = regClient{
		certPaths:     []string{},
		hosts:         map[string]*regClientHost{},
		retryLimit:    DefaultRetryLimit,
		userAgent:     DefaultUserAgent,
		blobChunkSize: DefaultBlobChunk,
		blobMaxPut:    DefaultBlobMax,
		log: &logrus.Logger{Out: ioutil.Discard},
	}
	rc.hostSet(ConfigHost{
		Name:     DockerRegistry,
		TLS:      TLSEnabled,
		Hostname: DockerRegistryDNS,
	})
	for _, opt := range opts {
		opt(&rc)
	}
	rc.log.Debug("regclient initialized")
	return &rc
}
func WithCertDir(path string) Opt {
	return func(rc *regClient) {
		rc.certPaths = append(rc.certPaths, path)
		return
	}
}
func WithDockerCerts() Opt {
	return func(rc *regClient) {
		rc.certPaths = append(rc.certPaths, DockerCertDir)
		return
	}
}
func WithDockerCreds() Opt {
	return func(rc *regClient) {
		err := rc.loadDockerCreds()
		if err != nil {
			rc.log.WithFields(logrus.Fields{
				"err": err,
			}).Warn("Failed to load docker creds")
		}
		return
	}
}