update & clean debug log

Signed-off-by: soulseen <sunzhu@yunify.com>
This commit is contained in:
soulseen
2019-08-24 14:54:23 +08:00
parent 8aadf7af34
commit 959791ead5
8 changed files with 122 additions and 72 deletions

View File

@@ -25,8 +25,8 @@ import (
"kubesphere.io/kubesphere/pkg/errors" "kubesphere.io/kubesphere/pkg/errors"
"kubesphere.io/kubesphere/pkg/models/registries" "kubesphere.io/kubesphere/pkg/models/registries"
log "github.com/golang/glog"
k8serror "k8s.io/apimachinery/pkg/api/errors" k8serror "k8s.io/apimachinery/pkg/api/errors"
log "k8s.io/klog"
) )
func RegistryVerify(request *restful.Request, response *restful.Response) { func RegistryVerify(request *restful.Request, response *restful.Response) {
@@ -51,21 +51,19 @@ func RegistryVerify(request *restful.Request, response *restful.Response) {
} }
func RegistryImageBlob(request *restful.Request, response *restful.Response) { func RegistryImageBlob(request *restful.Request, response *restful.Response) {
var statusUnauthorized = "Not found or unauthorized"
imageName := request.QueryParameter("image") imageName := request.QueryParameter("image")
namespace := request.QueryParameter("namespace") namespace := request.QueryParameter("namespace")
secretName := request.QueryParameter("secret") secretName := request.QueryParameter("secret")
// get entry // get entry
entry, err := registries.GetEntryBySecret(namespace, secretName) entry, err := registries.GetEntryBySecret(namespace, secretName)
if err != nil && k8serror.IsNotFound(err) {
log.Errorf("%+v", err)
errors.ParseSvcErr(restful.NewError(http.StatusBadRequest, err.Error()), response)
return
}
if err != nil { if err != nil {
log.Errorf("%+v", err) log.Errorf("%+v", err)
if k8serror.IsNotFound(err) {
log.Errorf("%+v", err)
errors.ParseSvcErr(restful.NewError(http.StatusBadRequest, err.Error()), response)
return
}
response.WriteAsJson(&registries.ImageDetails{Status: registries.StatusFailed, Message: err.Error()}) response.WriteAsJson(&registries.ImageDetails{Status: registries.StatusFailed, Message: err.Error()})
return return
} }
@@ -97,15 +95,15 @@ func RegistryImageBlob(request *restful.Request, response *restful.Response) {
} }
// Get digest. // Get digest.
imageManifest, err, statusCode := r.ImageManifest(image, token) imageManifest, err := r.ImageManifest(image, token)
if statusCode == http.StatusUnauthorized {
log.Errorf("%+v", err)
errors.ParseSvcErr(restful.NewError(statusCode, statusUnauthorized), response)
return
}
if err != nil { if err != nil {
if serviceError, ok := err.(restful.ServiceError); ok {
response.WriteAsJson(&registries.ImageDetails{Status: registries.StatusFailed, Message: serviceError.Message})
return
}
log.Errorf("%+v", err) log.Errorf("%+v", err)
response.WriteAsJson(&registries.ImageDetails{Status: registries.StatusFailed, Message: err.Error()}) response.WriteAsJson(&registries.ImageDetails{Status: registries.StatusFailed, Message: err.Error()})
return
} }
image.Digest = imageManifest.ManifestConfig.Digest image.Digest = imageManifest.ManifestConfig.Digest

View File

@@ -4,15 +4,16 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/docker/distribution/manifest/schema2" "github.com/docker/distribution/manifest/schema2"
log "github.com/golang/glog" log "k8s.io/klog"
"net/http" "net/http"
) )
// Digest returns the digest for an image. // Digest returns the digest for an image.
func (r *Registry) ImageBlob(image Image, token string) (*ImageBlob, error) { func (r *Registry) ImageBlob(image Image, token string) (*ImageBlob, error) {
if image.Path == "" {
return nil, fmt.Errorf("image is required")
}
url := r.GetBlobUrl(image) url := r.GetBlobUrl(image)
log.Info("registry.blobs.get url=" + url)
req, err := http.NewRequest("GET", url, nil) req, err := http.NewRequest("GET", url, nil)
if err != nil { if err != nil {
@@ -32,14 +33,14 @@ func (r *Registry) ImageBlob(image Image, token string) (*ImageBlob, error) {
respBody, _ := GetRespBody(resp) respBody, _ := GetRespBody(resp)
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNotFound { if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNotFound {
log.Info("got response: " + string(resp.StatusCode) + string(respBody)) log.Error("got response: " + string(resp.StatusCode) + string(respBody))
return nil, fmt.Errorf("got response: %s", respBody) return nil, fmt.Errorf("got image blob faild")
} }
imageBlob := &ImageBlob{} imageBlob := &ImageBlob{}
json.Unmarshal(respBody, imageBlob) err = json.Unmarshal(respBody, imageBlob)
return imageBlob, nil return imageBlob, err
} }
func (r *Registry) GetBlobUrl(image Image) string { func (r *Registry) GetBlobUrl(image Image) string {

View File

@@ -6,17 +6,19 @@ import (
"net/http" "net/http"
"github.com/docker/distribution/manifest/schema2" "github.com/docker/distribution/manifest/schema2"
log "github.com/golang/glog" "github.com/emicklei/go-restful"
log "k8s.io/klog"
) )
var statusUnauthorized = "Not found or unauthorized"
// Digest returns the digest for an image. // Digest returns the digest for an image.
func (r *Registry) ImageManifest(image Image, token string) (*ImageManifest, error, int) { func (r *Registry) ImageManifest(image Image, token string) (*ImageManifest, error) {
url := r.GetDigestUrl(image) url := r.GetDigestUrl(image)
log.Info("registry.manifests.get url=" + url)
req, err := http.NewRequest("GET", url, nil) req, err := http.NewRequest("GET", url, nil)
if err != nil { if err != nil {
return nil, err, http.StatusInternalServerError return nil, err
} }
req.Header.Add("Accept", schema2.MediaTypeManifest) req.Header.Add("Accept", schema2.MediaTypeManifest)
@@ -26,21 +28,25 @@ func (r *Registry) ImageManifest(image Image, token string) (*ImageManifest, err
resp, err := r.Client.Do(req) resp, err := r.Client.Do(req)
if err != nil { if err != nil {
return nil, err, http.StatusInternalServerError return nil, err
} }
defer resp.Body.Close() defer resp.Body.Close()
respBody, _ := GetRespBody(resp) respBody, _ := GetRespBody(resp)
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNotFound { if resp.StatusCode != http.StatusOK {
log.Info("got response: " + string(resp.StatusCode) + string(respBody)) if resp.StatusCode == http.StatusNotFound || resp.StatusCode == http.StatusUnauthorized {
return nil, fmt.Errorf("%s", respBody), resp.StatusCode log.Error(statusUnauthorized)
return nil, restful.NewError(resp.StatusCode, statusUnauthorized)
}
log.Error("got response: " + string(resp.StatusCode) + string(respBody))
return nil, restful.NewError(resp.StatusCode, "got image manifest failed")
} }
imageManifest := &ImageManifest{} imageManifest := &ImageManifest{}
json.Unmarshal(respBody, imageManifest) err = json.Unmarshal(respBody, imageManifest)
return imageManifest, nil, http.StatusOK return imageManifest, err
} }
func (r *Registry) GetDigestUrl(image Image) string { func (r *Registry) GetDigestUrl(image Image) string {

View File

@@ -20,7 +20,7 @@ func TestDigestFromDockerHub(t *testing.T) {
t.Fatalf("Could not get token: %s", err) t.Fatalf("Could not get token: %s", err)
} }
d, err, _ := r.ImageManifest(testImage, token) d, err := r.ImageManifest(testImage, token)
if err != nil { if err != nil {
t.Fatalf("Could not get digest: %s", err) t.Fatalf("Could not get digest: %s", err)
} }

View File

@@ -25,8 +25,8 @@ import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/client" "github.com/docker/docker/client"
"github.com/golang/glog" "github.com/golang/glog"
log "github.com/golang/glog"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
log "k8s.io/klog"
"kubesphere.io/kubesphere/pkg/informers" "kubesphere.io/kubesphere/pkg/informers"
) )
@@ -103,7 +103,7 @@ func getDockerEntryFromDockerSecret(instance *corev1.Secret) (dockerConfigEntry
if instance.Type != corev1.SecretTypeDockerConfigJson { if instance.Type != corev1.SecretTypeDockerConfigJson {
return nil, fmt.Errorf("secret %s in ns %s type should be %s", return nil, fmt.Errorf("secret %s in ns %s type should be %s",
instance.Namespace, instance.Name, corev1.SecretTypeDockerConfigJson) instance.Name, instance.Namespace, corev1.SecretTypeDockerConfigJson)
} }
dockerConfigBytes, ok := instance.Data[corev1.DockerConfigJsonKey] dockerConfigBytes, ok := instance.Data[corev1.DockerConfigJsonKey]
if !ok { if !ok {

View File

@@ -5,9 +5,9 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
log "github.com/golang/glog"
"io" "io"
"io/ioutil" "io/ioutil"
log "k8s.io/klog"
"net/http" "net/http"
"net/url" "net/url"
"regexp" "regexp"
@@ -19,6 +19,8 @@ const (
// DefaultDockerRegistry is the default docker registry address. // DefaultDockerRegistry is the default docker registry address.
DefaultDockerRegistry = "https://registry-1.docker.io" DefaultDockerRegistry = "https://registry-1.docker.io"
DefaultDockerHub = "docker.io"
DefaultTimeout = 30 * time.Second DefaultTimeout = 30 * time.Second
) )
@@ -31,8 +33,6 @@ var (
ErrBasicAuth = errors.New("basic auth required") ErrBasicAuth = errors.New("basic auth required")
gcrMatcher = regexp.MustCompile(`https://([a-z]+\.|)gcr\.io/`) gcrMatcher = regexp.MustCompile(`https://([a-z]+\.|)gcr\.io/`)
reProtocol = regexp.MustCompile("^https?://")
) )
// Registry defines the client for retrieving information from the registry API. // Registry defines the client for retrieving information from the registry API.
@@ -42,11 +42,11 @@ type Registry struct {
Username string Username string
Password string Password string
Client *http.Client Client *http.Client
Opt Opt Opt RegistryOpt
} }
// Opt holds the options for a new registry. // Opt holds the options for a new registry.
type Opt struct { type RegistryOpt struct {
Domain string Domain string
Timeout time.Duration Timeout time.Duration
Headers map[string]string Headers map[string]string
@@ -68,14 +68,12 @@ func CreateRegistryClient(username, password, domain string) (*Registry, error)
authDomain := domain authDomain := domain
auth, err := GetAuthConfig(username, password, authDomain) auth, err := GetAuthConfig(username, password, authDomain)
if err != nil { if err != nil {
log.Error(err)
return nil, err return nil, err
} }
// Create the registry client. // Create the registry client.
log.Infof("domain: %s", domain) return New(auth, RegistryOpt{
log.Infof("server address: %s", auth.ServerAddress)
return New(auth, Opt{
Domain: domain, Domain: domain,
}) })
} }
@@ -83,7 +81,7 @@ func CreateRegistryClient(username, password, domain string) (*Registry, error)
// GetAuthConfig returns the docker registry AuthConfig. // GetAuthConfig returns the docker registry AuthConfig.
func GetAuthConfig(username, password, registry string) (types.AuthConfig, error) { func GetAuthConfig(username, password, registry string) (types.AuthConfig, error) {
registry = setDefaultRegistry(registry) registry = setDefaultRegistry(registry)
if username != "" && password != "" && registry != "" { if username != "" && password != "" {
return types.AuthConfig{ return types.AuthConfig{
Username: username, Username: username,
Password: password, Password: password,
@@ -91,8 +89,6 @@ func GetAuthConfig(username, password, registry string) (types.AuthConfig, error
}, nil }, nil
} }
log.Info("Using registry ", registry, " with no authentication")
return types.AuthConfig{ return types.AuthConfig{
ServerAddress: registry, ServerAddress: registry,
}, nil }, nil
@@ -100,39 +96,31 @@ func GetAuthConfig(username, password, registry string) (types.AuthConfig, error
} }
func setDefaultRegistry(serverAddress string) string { func setDefaultRegistry(serverAddress string) string {
if serverAddress == "docker.io" || serverAddress == "" { if serverAddress == DefaultDockerHub || serverAddress == "" {
serverAddress = DefaultDockerRegistry serverAddress = DefaultDockerRegistry
} }
return serverAddress return serverAddress
} }
func newFromTransport(auth types.AuthConfig, opt Opt) (*Registry, error) { func newFromTransport(auth types.AuthConfig, opt RegistryOpt) (*Registry, error) {
if len(opt.Domain) < 1 || opt.Domain == "docker.io" { if len(opt.Domain) < 1 || opt.Domain == DefaultDockerHub {
opt.Domain = auth.ServerAddress opt.Domain = auth.ServerAddress
} }
url := strings.TrimSuffix(opt.Domain, "/") registryUrl := strings.TrimSuffix(opt.Domain, "/")
authURL := strings.TrimSuffix(auth.ServerAddress, "/")
if !reProtocol.MatchString(url) { if !strings.HasPrefix(registryUrl, "http://") && !strings.HasPrefix(registryUrl, "https://") {
if opt.UseSSL { if opt.UseSSL {
url = "https://" + url registryUrl = "https://" + registryUrl
} else { } else {
url = "http://" + url registryUrl = "http://" + registryUrl
}
}
if !reProtocol.MatchString(authURL) {
if opt.UseSSL {
authURL = "https://" + authURL
} else {
authURL = "http://" + authURL
} }
} }
registryURL, _ := url.Parse(registryUrl)
registry := &Registry{ registry := &Registry{
URL: url, URL: registryURL.String(),
Domain: reProtocol.ReplaceAllString(url, ""), Domain: registryURL.Host,
Client: &http.Client{ Client: &http.Client{
Timeout: DefaultTimeout, Timeout: DefaultTimeout,
}, },
@@ -152,7 +140,7 @@ func (r *Registry) url(pathTemplate string, args ...interface{}) string {
} }
// New creates a new Registry struct with the given URL and credentials. // New creates a new Registry struct with the given URL and credentials.
func New(auth types.AuthConfig, opt Opt) (*Registry, error) { func New(auth types.AuthConfig, opt RegistryOpt) (*Registry, error) {
return newFromTransport(auth, opt) return newFromTransport(auth, opt)
} }

View File

@@ -0,0 +1,61 @@
package registries
import (
"testing"
)
func TestCreateRegistryClient(t *testing.T) {
type imageInfo struct {
Username string
Password string
Domain string
ExDomain string
ExUrl string
}
testImages := []imageInfo{
{Domain: "kubesphere.io", ExDomain: "kubesphere.io", ExUrl: "http://kubesphere.io"},
{Domain: "127.0.0.1:5000", ExDomain: "127.0.0.1:5000", ExUrl: "http://127.0.0.1:5000"},
{Username: "Username", Password: "Password", Domain: "docker.io", ExDomain: "registry-1.docker.io", ExUrl: "https://registry-1.docker.io"},
{Domain: "harbor.devops.kubesphere.local:30280", ExDomain: "harbor.devops.kubesphere.local:30280", ExUrl: "http://harbor.devops.kubesphere.local:30280"},
}
for _, testImage := range testImages {
reg, err := CreateRegistryClient(testImage.Username, testImage.Password, testImage.Domain)
if err != nil {
t.Fatalf("Get err %s", err)
}
if reg.Domain != testImage.ExDomain {
t.Fatalf("Doamin got %v, expected %v", reg.Domain, testImage.ExDomain)
}
if reg.URL != testImage.ExUrl {
t.Fatalf("URL got %v, expected %v", reg.URL, testImage.ExUrl)
}
}
testImage := Image{Domain: "docker.io", Path: "library/alpine", Tag: "latest"}
r, err := CreateRegistryClient("", "", "docker.io")
if err != nil {
t.Fatalf("Could not get client: %s", err)
}
digestUrl := r.GetDigestUrl(testImage)
// Get token.
token, err := r.Token(digestUrl)
if err != nil || token == "" {
t.Fatalf("Could not get token: %s", err)
}
d, err := r.ImageManifest(testImage, token)
if err != nil {
t.Fatalf("Could not get digest: %s", err)
}
if d == nil {
t.Error("Empty digest received")
}
}

View File

@@ -7,8 +7,6 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
log "github.com/golang/glog"
) )
func (t authToken) String() (string, error) { func (t authToken) String() (string, error) {
@@ -52,7 +50,6 @@ func isTokenDemand(resp *http.Response) (*authService, error) {
// Token returns the required token for the specific resource url. If the registry requires basic authentication, this // Token returns the required token for the specific resource url. If the registry requires basic authentication, this
// function returns ErrBasicAuth. // function returns ErrBasicAuth.
func (r *Registry) Token(url string) (str string, err error) { func (r *Registry) Token(url string) (str string, err error) {
log.Info("Get token from ", url)
req, err := http.NewRequest("GET", url, nil) req, err := http.NewRequest("GET", url, nil)
if err != nil { if err != nil {
return "", err return "", err
@@ -72,17 +69,16 @@ func (r *Registry) Token(url string) (str string, err error) {
return "", ErrBasicAuth return "", ErrBasicAuth
} }
a, err := isTokenDemand(resp) authService, err := isTokenDemand(resp)
if err != nil { if err != nil {
return "", err return "", err
} }
if a == nil { if authService == nil {
log.Info("registry.token authService=nil")
return "", nil return "", nil
} }
authReq, err := a.Request(r.Username, r.Password) authReq, err := authService.Request(r.Username, r.Password)
if err != nil { if err != nil {
return "", err return "", err
} }