func (c *Client) Getv2() error {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	req, err := c.NewRequest("/v2/")
	if err != nil {
		return err
	}
	resp, err := c.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case http.StatusUnauthorized:
		h := resp.Header.Get("www-authenticate")
		c.getToken(h)
		tokenReq, err := c.NewRequest("/v2/")
		if err != nil {
			return err
		}
		tokenResp, err := c.Do(tokenReq)
		if err != nil {
			return err
		}
		defer tokenResp.Body.Close()
		if tokenResp.StatusCode != http.StatusOK {
			msg := fmt.Sprintf("Token not accepted by /v2/ - %s", tokenResp.Status)
			log.Warn(msg)
			return errors.New(msg)
		}
		log.Debug("GET /v2/ successful with new token")
	case http.StatusOK:
		if c.token == "" {
			log.Debug("GET /v2/ successful without token")
		} else {
			log.Debug("GET /v2/ successful with existing token")
		}
	default:
		msg := fmt.Sprintf("Bad response from /v2/ - %s", resp.Status)
		log.Warn(msg)
		return errors.New(msg)
	}
	return nil
}
Getv2 - makes a GET request to the registry's /v2/ endpoint. If a 401
Unauthorized response is received, this method attempts to obtain an oauth
token and tries again with the new token. If a username and password are
available, they are used with Basic Auth in the request to the token
service. This method is goroutine-safe.
package oauth
import (
	"crypto/tls"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"regexp"
	"sync"
	"time"
	log "github.com/sirupsen/logrus"
)
type authResponse struct {
	Token string `json:"access_token"`
}
func NewClient(user, pass string, skipVerify bool, url *url.URL) *Client {
	transport := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: skipVerify}}
	if skipVerify == true {
		log.Warn("skipping verification of registry TLS certificate per adapter configuration")
	}
	return &Client{
		user:   user,
		pass:   pass,
		url:    url,
		mutex:  &sync.Mutex{},
		client: &http.Client{Timeout: time.Second * 60, Transport: transport},
	}
}
type Client struct {
	user   string
	pass   string
	token  string
	mutex  *sync.Mutex
	client *http.Client
	url    *url.URL
}
func (c *Client) NewRequest(path string) (*http.Request, error) {
	req, err := http.NewRequest("GET", c.url.String(), nil)
	if err != nil {
		return nil, err
	}
	req.URL.Path = path
	if c.token != "" {
		req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", c.token))
	}
	req.Header.Add("Accept", "application/json")
	return req, nil
}
func (c *Client) Do(req *http.Request) (*http.Response, error) {
	return c.client.Do(req)
}