package docker import ( "crypto/tls" "fmt" "log" "net" "net/http" "strings" "time" drc "github.com/rusenask/docker-registry-client/registry" ) type LogfCallback func(format string, args ...interface{}) type Registry struct { URL string Client *http.Client Logf LogfCallback } /* * Pass log messages along to Go's "log" module. */ func Log(format string, args ...interface{}) { log.Printf(format, args...) } /* * Create a new Registry with the given URL and credentials, then Ping()s it * before returning it to verify that the registry is available. * * You can, alternately, construct a Registry manually by populating the fields. * This passes http.DefaultTransport to WrapTransport when creating the * http.Client. */ func New(registryURL, username, password string) *Registry { transport := &http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: (&net.Dialer{ Timeout: 10 * time.Second, KeepAlive: 30 * time.Second, DualStack: true, }).DialContext, MaxIdleConns: 10, IdleConnTimeout: 90 * time.Second, TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, } return newFromTransport(registryURL, username, password, transport, Log) } /* * Create a new Registry, as with New, using an http.Transport that disables * SSL certificate verification. */ func NewInsecure(registryURL, username, password string) *Registry { transport := &http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: (&net.Dialer{ Timeout: 10 * time.Second, KeepAlive: 30 * time.Second, DualStack: true, }).DialContext, TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, }, MaxIdleConns: 10, IdleConnTimeout: 90 * time.Second, TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, } return newFromTransport(registryURL, username, password, transport, Log) } func newFromTransport(registryURL, username, password string, transport *http.Transport, logf LogfCallback) *Registry { url := strings.TrimSuffix(registryURL, "/") registry := &Registry{ URL: url, Client: &http.Client{ Transport: drc.WrapTransport(transport, url, username, password), }, Logf: logf, } return registry } func (r *Registry) Ping() error { url := r.url("/v2/") r.Logf("registry.ping url=%s", url) resp, err := r.Client.Get(url) if resp != nil { defer resp.Body.Close() } return err } type tagsResponse struct { Tags []string `json:"tags"` } func (r *Registry) url(pathTemplate string, args ...interface{}) string { pathSuffix := fmt.Sprintf(pathTemplate, args...) url := fmt.Sprintf("%s%s", r.URL, pathSuffix) return url }