forked from TrueCloudLab/distribution
Add tags implementation
Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
This commit is contained in:
parent
2eb9b286ed
commit
7d630192dd
4 changed files with 98 additions and 25 deletions
|
@ -112,3 +112,10 @@ func parseHTTPErrorResponse(response *http.Response) error {
|
|||
}
|
||||
return &errors
|
||||
}
|
||||
|
||||
func handleErrorResponse(resp *http.Response) error {
|
||||
if resp.StatusCode >= 400 && resp.StatusCode < 500 {
|
||||
return parseHTTPErrorResponse(resp)
|
||||
}
|
||||
return &UnexpectedHTTPStatusError{Status: resp.Status}
|
||||
}
|
||||
|
|
|
@ -26,14 +26,10 @@ type httpLayerUpload struct {
|
|||
}
|
||||
|
||||
func (hlu *httpLayerUpload) handleErrorResponse(resp *http.Response) error {
|
||||
switch {
|
||||
case resp.StatusCode == http.StatusNotFound:
|
||||
if resp.StatusCode == http.StatusNotFound {
|
||||
return &BlobUploadNotFoundError{Location: hlu.location}
|
||||
case resp.StatusCode >= 400 && resp.StatusCode < 500:
|
||||
return parseHTTPErrorResponse(resp)
|
||||
default:
|
||||
return &UnexpectedHTTPStatusError{Status: resp.Status}
|
||||
}
|
||||
return handleErrorResponse(resp)
|
||||
}
|
||||
|
||||
func (hlu *httpLayerUpload) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
@ -90,7 +91,36 @@ type manifests struct {
|
|||
}
|
||||
|
||||
func (ms *manifests) Tags() ([]string, error) {
|
||||
panic("not implemented")
|
||||
u, err := ms.ub.BuildTagsURL(ms.name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := ms.client.Get(u)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch {
|
||||
case resp.StatusCode == http.StatusOK:
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tagsResponse := struct {
|
||||
Tags []string `json:"tags"`
|
||||
}{}
|
||||
if err := json.Unmarshal(b, &tagsResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tagsResponse.Tags, nil
|
||||
case resp.StatusCode == http.StatusNotFound:
|
||||
return nil, nil
|
||||
default:
|
||||
return nil, handleErrorResponse(resp)
|
||||
}
|
||||
}
|
||||
|
||||
func (ms *manifests) Exists(dgst digest.Digest) (bool, error) {
|
||||
|
@ -113,10 +143,8 @@ func (ms *manifests) ExistsByTag(tag string) (bool, error) {
|
|||
return true, nil
|
||||
case resp.StatusCode == http.StatusNotFound:
|
||||
return false, nil
|
||||
case resp.StatusCode >= 400 && resp.StatusCode < 500:
|
||||
return false, parseHTTPErrorResponse(resp)
|
||||
default:
|
||||
return false, &UnexpectedHTTPStatusError{Status: resp.Status}
|
||||
return false, handleErrorResponse(resp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,10 +174,8 @@ func (ms *manifests) GetByTag(tag string) (*manifest.SignedManifest, error) {
|
|||
}
|
||||
|
||||
return &sm, nil
|
||||
case resp.StatusCode >= 400 && resp.StatusCode < 500:
|
||||
return nil, parseHTTPErrorResponse(resp)
|
||||
default:
|
||||
return nil, &UnexpectedHTTPStatusError{Status: resp.Status}
|
||||
return nil, handleErrorResponse(resp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,10 +200,8 @@ func (ms *manifests) Put(m *manifest.SignedManifest) error {
|
|||
case resp.StatusCode == http.StatusAccepted:
|
||||
// TODO(dmcgowan): Use or check digest header
|
||||
return nil
|
||||
case resp.StatusCode >= 400 && resp.StatusCode < 500:
|
||||
return parseHTTPErrorResponse(resp)
|
||||
default:
|
||||
return &UnexpectedHTTPStatusError{Status: resp.Status}
|
||||
return handleErrorResponse(resp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,10 +224,8 @@ func (ms *manifests) Delete(dgst digest.Digest) error {
|
|||
switch {
|
||||
case resp.StatusCode == http.StatusOK:
|
||||
return nil
|
||||
case resp.StatusCode >= 400 && resp.StatusCode < 500:
|
||||
return parseHTTPErrorResponse(resp)
|
||||
default:
|
||||
return &UnexpectedHTTPStatusError{Status: resp.Status}
|
||||
return handleErrorResponse(resp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,10 +297,8 @@ func (ls *layers) Upload() (distribution.LayerUpload, error) {
|
|||
startedAt: time.Now(),
|
||||
location: location,
|
||||
}, nil
|
||||
case resp.StatusCode >= 400 && resp.StatusCode < 500:
|
||||
return nil, parseHTTPErrorResponse(resp)
|
||||
default:
|
||||
return nil, &UnexpectedHTTPStatusError{Status: resp.Status}
|
||||
return nil, handleErrorResponse(resp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,9 +347,7 @@ func (ls *layers) fetchLayer(dgst digest.Digest) (distribution.Layer, error) {
|
|||
BlobSum: dgst,
|
||||
},
|
||||
}
|
||||
case resp.StatusCode >= 400 && resp.StatusCode < 500:
|
||||
return nil, parseHTTPErrorResponse(resp)
|
||||
default:
|
||||
return nil, &UnexpectedHTTPStatusError{Status: resp.Status}
|
||||
return nil, handleErrorResponse(resp)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"log"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -602,3 +603,54 @@ func TestManifestPut(t *testing.T) {
|
|||
|
||||
// TODO(dmcgowan): Check for error cases
|
||||
}
|
||||
|
||||
func TestManifestTags(t *testing.T) {
|
||||
repo := "test.example.com/repo/tags/list"
|
||||
tagsList := []byte(strings.TrimSpace(`
|
||||
{
|
||||
"name": "test.example.com/repo/tags/list",
|
||||
"tags": [
|
||||
"tag1",
|
||||
"tag2",
|
||||
"funtag"
|
||||
]
|
||||
}
|
||||
`))
|
||||
var m testutil.RequestResponseMap
|
||||
addPing(&m)
|
||||
m = append(m, testutil.RequestResponseMapping{
|
||||
Request: testutil.Request{
|
||||
Method: "GET",
|
||||
Route: "/v2/" + repo + "/tags/list",
|
||||
},
|
||||
Response: testutil.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Body: tagsList,
|
||||
Headers: http.Header(map[string][]string{
|
||||
"Content-Length": {fmt.Sprint(len(tagsList))},
|
||||
"Last-Modified": {time.Now().Add(-1 * time.Second).Format(time.ANSIC)},
|
||||
}),
|
||||
},
|
||||
})
|
||||
|
||||
e, c := testServer(m)
|
||||
defer c()
|
||||
|
||||
r, err := NewRepository(context.Background(), repo, e, &RepositoryConfig{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ms := r.Manifests()
|
||||
tags, err := ms.Tags()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(tags) != 3 {
|
||||
t.Fatalf("Wrong number of tags returned: %d, expected 3", len(tags))
|
||||
}
|
||||
// TODO(dmcgowan): Check array
|
||||
|
||||
// TODO(dmcgowan): Check for error cases
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue