From 4dc81927d3fa8176c4a468f3aac4e23b84917fbc Mon Sep 17 00:00:00 2001 From: Wenkai Yin Date: Sun, 17 Apr 2016 22:39:10 +0800 Subject: [PATCH] remove useless code --- api/repository.go | 34 ++++++---- service/utils/cache.go | 11 +-- utils/registry/registry.go | 66 ++++++++++++++++-- utils/registry/registryutils.go | 115 -------------------------------- 4 files changed, 86 insertions(+), 140 deletions(-) delete mode 100644 utils/registry/registryutils.go diff --git a/api/repository.go b/api/repository.go index 40d8f6bb5..307ff60fe 100644 --- a/api/repository.go +++ b/api/repository.go @@ -225,15 +225,19 @@ func (ra *RepositoryAPI) GetTags() { var tags []string repoName := ra.GetString("repo_name") - result, err := registry.APIGet(registry.BuildRegistryURL(repoName, "tags", "list"), ra.username) + + tags, err := ra.registry.ListTag(repoName) if err != nil { - log.Errorf("Failed to get repo tags, repo name: %s, error: %v", repoName, err) - ra.RenderError(http.StatusInternalServerError, "Failed to get repo tags") - } else { - t := tag{} - json.Unmarshal(result, &t) - tags = t.Tags + e, ok := errors.ParseError(err) + if ok { + log.Info(e) + ra.CustomAbort(e.StatusCode, e.Message) + } else { + log.Error(err) + ra.CustomAbort(http.StatusInternalServerError, "internal error") + } } + ra.Data["json"] = tags ra.ServeJSON() } @@ -245,14 +249,20 @@ func (ra *RepositoryAPI) GetManifests() { item := models.RepoItem{} - result, err := registry.APIGet(registry.BuildRegistryURL(repoName, "manifests", tag), ra.username) + _, _, payload, err := ra.registry.PullManifest(repoName, tag, registry.ManifestVersion1) if err != nil { - log.Errorf("Failed to get manifests for repo, repo name: %s, tag: %s, error: %v", repoName, tag, err) - ra.RenderError(http.StatusInternalServerError, "Internal Server Error") - return + e, ok := errors.ParseError(err) + if ok { + log.Info(e) + ra.CustomAbort(e.StatusCode, e.Message) + } else { + log.Error(err) + ra.CustomAbort(http.StatusInternalServerError, "internal error") + } } + mani := manifest{} - err = json.Unmarshal(result, &mani) + err = json.Unmarshal(payload, &mani) if err != nil { log.Errorf("Failed to decode json from response for manifests, repo name: %s, tag: %s, error: %v", repoName, tag, err) ra.RenderError(http.StatusInternalServerError, "Internal Server Error") diff --git a/service/utils/cache.go b/service/utils/cache.go index 7f4508b0c..a97a4599c 100644 --- a/service/utils/cache.go +++ b/service/utils/cache.go @@ -16,11 +16,9 @@ package utils import ( - "encoding/json" "os" "time" - "github.com/vmware/harbor/models" "github.com/vmware/harbor/utils/log" "github.com/vmware/harbor/utils/registry" @@ -52,19 +50,14 @@ func init() { // RefreshCatalogCache calls registry's API to get repository list and write it to cache. func RefreshCatalogCache() error { log.Debug("refreshing catalog cache...") - result, err := registry.APIGet(registry.BuildRegistryURL("_catalog"), "") - if err != nil { - return err - } - repoResp := models.Repo{} - err = json.Unmarshal(result, &repoResp) + rs, err := registryClient.Catalog() if err != nil { return err } repos := []string{} - for _, repo := range repoResp.Repositories { + for _, repo := range rs { tags, err := registryClient.ListTag(repo) if err != nil { log.Errorf("error occurred while list tag for %s: %v", repo, err) diff --git a/utils/registry/registry.go b/utils/registry/registry.go index 5fe3283bd..e390c4c0d 100644 --- a/utils/registry/registry.go +++ b/utils/registry/registry.go @@ -22,6 +22,8 @@ import ( "net/http" "net/url" + "github.com/docker/distribution/manifest" + "github.com/docker/distribution/manifest/schema1" "github.com/docker/distribution/manifest/schema2" "github.com/vmware/harbor/utils/registry/errors" ) @@ -37,6 +39,19 @@ type uRLBuilder struct { root *url.URL } +var ( + // ManifestVersion1 : schema 1 + ManifestVersion1 = manifest.Versioned{ + SchemaVersion: 1, + MediaType: schema1.MediaTypeManifest, + } + // ManifestVersion2 : schema 2 + ManifestVersion2 = manifest.Versioned{ + SchemaVersion: 2, + MediaType: schema2.MediaTypeManifest, + } +) + // New returns an instance of Registry func New(endpoint string, client *http.Client) (*Registry, error) { u, err := url.Parse(endpoint) @@ -53,6 +68,46 @@ func New(endpoint string, client *http.Client) (*Registry, error) { }, nil } +// Catalog ... +func (r *Registry) Catalog() ([]string, error) { + repos := []string{} + req, err := http.NewRequest("GET", r.ub.buildCatalogURL(), nil) + if err != nil { + return repos, err + } + + resp, err := r.client.Do(req) + if err != nil { + return repos, err + } + + defer resp.Body.Close() + + b, err := ioutil.ReadAll(resp.Body) + if err != nil { + return repos, err + } + + if resp.StatusCode == http.StatusOK { + catalogResp := struct { + Repositories []string `json:"repositories"` + }{} + + if err := json.Unmarshal(b, &catalogResp); err != nil { + return repos, err + } + + repos = catalogResp.Repositories + + return repos, nil + } + + return repos, errors.Error{ + StatusCode: resp.StatusCode, + Message: string(b), + } +} + // ListTag ... func (r *Registry) ListTag(name string) ([]string, error) { tags := []string{} @@ -135,15 +190,14 @@ func (r *Registry) ManifestExist(name, reference string) (digest string, exist b } // PullManifest ... -func (r *Registry) PullManifest(name, reference string) (digest, mediaType string, payload []byte, err error) { +func (r *Registry) PullManifest(name, reference string, version manifest.Versioned) (digest, mediaType string, payload []byte, err error) { req, err := http.NewRequest("GET", r.ub.buildManifestURL(name, reference), nil) if err != nil { return } - // request Schema 2 manifest, if the registry does not support it, - // Schema 1 manifest will be returned - req.Header.Set(http.CanonicalHeaderKey("Accept"), schema2.MediaTypeManifest) + // if the registry does not support schema 2, schema 1 manifest will be returned + req.Header.Set(http.CanonicalHeaderKey("Accept"), version.MediaType) resp, err := r.client.Do(req) if err != nil { @@ -245,6 +299,10 @@ func (r *Registry) DeleteBlob(name, digest string) error { } } +func (u *uRLBuilder) buildCatalogURL() string { + return fmt.Sprintf("%s/v2/_catalog", u.root.String()) +} + func (u *uRLBuilder) buildTagListURL(name string) string { return fmt.Sprintf("%s/v2/%s/tags/list", u.root.String(), name) } diff --git a/utils/registry/registryutils.go b/utils/registry/registryutils.go deleted file mode 100644 index 54a0b6ddf..000000000 --- a/utils/registry/registryutils.go +++ /dev/null @@ -1,115 +0,0 @@ -/* - Copyright (c) 2016 VMware, Inc. All Rights Reserved. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package registry - -import ( - "errors" - "fmt" - "io/ioutil" - "net/http" - "os" - "regexp" - - token_util "github.com/vmware/harbor/service/token" - "github.com/vmware/harbor/utils/log" -) - -// BuildRegistryURL ... -func BuildRegistryURL(segments ...string) string { - registryURL := os.Getenv("REGISTRY_URL") - if registryURL == "" { - registryURL = "http://localhost:5000" - } - url := registryURL + "/v2" - for _, s := range segments { - if s == "v2" { - log.Debugf("unnecessary v2 in %v", segments) - continue - } - url += "/" + s - } - return url -} - -// APIGet triggers GET request to the URL which is the endpoint of registry and returns the response body. -// It will attach a valid jwt token to the request if registry requires. -func APIGet(url, username string) ([]byte, error) { - - log.Debugf("Registry API url: %s", url) - response, err := http.Get(url) - if err != nil { - return nil, err - } - result, err := ioutil.ReadAll(response.Body) - if err != nil { - return nil, err - } - defer response.Body.Close() - if response.StatusCode == http.StatusOK { - return result, nil - } else if response.StatusCode == http.StatusUnauthorized { - authenticate := response.Header.Get("WWW-Authenticate") - log.Debugf("authenticate header: %s", authenticate) - var service string - var scopes []string - //Disregard the case for hanlding multiple scopes for http call initiated from UI, as there's refactor planned. - re := regexp.MustCompile(`service=\"(.*?)\".*scope=\"(.*?)\"`) - res := re.FindStringSubmatch(authenticate) - if len(res) > 2 { - service = res[1] - scopes = append(scopes, res[2]) - } - token, err := token_util.GenTokenForUI(username, service, scopes) - if err != nil { - return nil, err - } - request, err := http.NewRequest("GET", url, nil) - if err != nil { - return nil, err - } - request.Header.Add("Authorization", "Bearer "+token) - client := &http.Client{} - client.CheckRedirect = func(req *http.Request, via []*http.Request) error { - // log.Infof("via length: %d\n", len(via)) - if len(via) >= 10 { - return fmt.Errorf("too many redirects") - } - for k, v := range via[0].Header { - if _, ok := req.Header[k]; !ok { - req.Header[k] = v - } - } - return nil - } - response, err = client.Do(request) - if err != nil { - return nil, err - } - if response.StatusCode != http.StatusOK { - errMsg := fmt.Sprintf("Unexpected return code from registry: %d", response.StatusCode) - log.Error(errMsg) - return nil, fmt.Errorf(errMsg) - } - result, err = ioutil.ReadAll(response.Body) - if err != nil { - return nil, err - } - defer response.Body.Close() - return result, nil - } else { - return nil, errors.New(string(result)) - } -}