0
Fork 0
mirror of https://github.com/project-zot/zot.git synced 2024-12-30 22:34:13 -05:00

refactor: Reduce zb binary size (#1783)

Signed-off-by: Alexei Dodon <adodon@cisco.com>
This commit is contained in:
Alexei Dodon 2023-09-13 10:28:14 +03:00 committed by GitHub
parent 98ab43f6ef
commit 48bf7f69f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 243 additions and 152 deletions

View file

@ -0,0 +1,73 @@
name: "Check binary size increase"
on:
pull_request:
branches: [main]
permissions: read-all
jobs:
compare-binary-sizes:
runs-on: ubuntu-latest
name: compare-with-main
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
cache: false
go-version: 1.20.x
- name: Checkout zot (main branch)
run: |
mkdir -p $GITHUB_WORKSPACE/zot_main
git clone https://github.com/project-zot/zot zot_main/
- name: Check if zot-minimal binary increased with more than 1%
run: |
echo "Building zot-minimal and check size"
cd $GITHUB_WORKSPACE
make binary-minimal
BINSIZE=$(stat -c%s "bin/zot-linux-amd64-minimal")
echo "Building zot-minimal on main branch and check size"
cd zot_main
make binary-minimal
BINSIZE_MAIN=$(stat -c%s "bin/zot-linux-amd64-minimal")
echo "PR binary size: $BINSIZE Bytes"
echo "main branch binary size: $BINSIZE_MAIN Bytes"
[[ $BINSIZE -eq $BINSIZE_MAIN ]] && echo "zot-minimal binary size is not affected by PR" && exit 0
if [[ $BINSIZE -gt $BINSIZE_MAIN ]]; then \
PERCENTAGE=$(echo "scale=2; (($BINSIZE-$BINSIZE_MAIN)*100)/$BINSIZE_MAIN" | bc); \
echo "zot minimal binary increased by $PERCENTAGE% comparing with main"; \
if ((`bc <<< "$PERCENTAGE>=1.0"`)); then exit 1; fi; \
else \
PERCENTAGE=$(echo "scale=2; (($BINSIZE_MAIN-$BINSIZE)*100)/$BINSIZE_MAIN" | bc); \
echo "zot minimal binary decreased by $PERCENTAGE% comparing with main"; \
fi
- if: always()
name: Check if zb binary increased with more than 1%
run: |
echo "Building zb and check size"
cd $GITHUB_WORKSPACE
make bench
BINSIZE=$(stat -c%s "bin/zb-linux-amd64")
echo "Building zb on main branch and check size"
cd zot_main
make bench
BINSIZE_MAIN=$(stat -c%s "bin/zb-linux-amd64")
echo "PR binary size: $BINSIZE Bytes"
echo "main branch binary size: $BINSIZE_MAIN Bytes"
[[ $BINSIZE -eq $BINSIZE_MAIN ]] && echo "zb binary size is not affected by PR" && exit 0
if [[ $BINSIZE -gt $BINSIZE_MAIN ]]; then \
PERCENTAGE=$(echo "scale=2; (($BINSIZE-$BINSIZE_MAIN)*100)/$BINSIZE_MAIN" | bc); \
echo "zb binary increased by $PERCENTAGE% comparing with main"; \
if ((`bc <<< "$PERCENTAGE>=1.0"`)); then exit 1; fi; \
else \
PERCENTAGE=$(echo "scale=2; (($BINSIZE_MAIN-$BINSIZE)*100)/$BINSIZE_MAIN" | bc); \
echo "zb binary decreased by $PERCENTAGE% comparing with main"; \
fi

View file

@ -36,9 +36,6 @@ jobs:
# Optional: show only new issues if it's a pull request. The default value is `false`. # Optional: show only new issues if it's a pull request. The default value is `false`.
# only-new-issues: true # only-new-issues: true
# Optional: if set to true then the action will use pre-installed Go.
skip-go-installation: true
# Optional: if set to true then the action don't cache or restore ~/go/pkg. # Optional: if set to true then the action don't cache or restore ~/go/pkg.
# skip-pkg-cache: true # skip-pkg-cache: true

View file

@ -1,40 +0,0 @@
name: "zot minimal binary size"
on:
pull_request:
branches: [main]
permissions: read-all
jobs:
zot-minimal-size:
runs-on: ubuntu-latest
name: compare-binary-size
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
cache: false
go-version: 1.20.x
- name: Check if zot-minimal binary increased with more than 1%
run: |
echo "Building zot-minimal and check size"
cd $GITHUB_WORKSPACE
make binary-minimal
BINSIZE=$(stat -c%s "bin/zot-linux-amd64-minimal")
echo "Building zot-minimal on main branch and check size"
mkdir -p zot_main
git clone https://github.com/project-zot/zot zot_main/
cd zot_main
make binary-minimal
BINSIZE_MAIN=$(stat -c%s "bin/zot-linux-amd64-minimal")
cd $GITHUB_WORKSPACE && rm -rf zot_main
[[ $BINSIZE -gt $BINSIZE_MAIN ]] || exit 0
echo "PR changes increased size of zot-minimal binary"
echo "PR binary size: $BINSIZE Bytes"
echo "main branch binary size: $BINSIZE_MAIN Bytes"
PERCENTACE=$(echo "scale=2; (($BINSIZE-$BINSIZE_MAIN)*100)/$BINSIZE_MAIN" | bc)
if ((`bc <<< "$PERCENTACE>=1.0"`)); then echo "zot minimal binary increased by $PERCENTACE% comparing with main"; exit 1; fi

View file

@ -2,10 +2,12 @@ package main
import ( import (
"bytes" "bytes"
crand "crypto/rand"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"log" "log"
"math/big"
"math/rand" "math/rand"
"net/http" "net/http"
"os" "os"
@ -14,13 +16,14 @@ import (
"time" "time"
"github.com/google/uuid" "github.com/google/uuid"
godigest "github.com/opencontainers/go-digest"
imeta "github.com/opencontainers/image-spec/specs-go" imeta "github.com/opencontainers/image-spec/specs-go"
ispec "github.com/opencontainers/image-spec/specs-go/v1" ispec "github.com/opencontainers/image-spec/specs-go/v1"
"gopkg.in/resty.v1" "gopkg.in/resty.v1"
zerr "zotregistry.io/zot/errors" zerr "zotregistry.io/zot/errors"
"zotregistry.io/zot/pkg/api" "zotregistry.io/zot/pkg/common"
"zotregistry.io/zot/pkg/test" testc "zotregistry.io/zot/pkg/test/common"
) )
func makeHTTPGetRequest(url string, resultPtr interface{}, client *resty.Client) error { func makeHTTPGetRequest(url string, resultPtr interface{}, client *resty.Client) error {
@ -62,7 +65,7 @@ func makeHTTPDeleteRequest(url string, client *resty.Client) error {
func deleteTestRepo(repos []string, url string, client *resty.Client) error { func deleteTestRepo(repos []string, url string, client *resty.Client) error {
for _, repo := range repos { for _, repo := range repos {
var tags api.ImageTags var tags common.ImageTags
// get tags // get tags
err := makeHTTPGetRequest(fmt.Sprintf("%s/v2/%s/tags/list", url, repo), &tags, client) err := makeHTTPGetRequest(fmt.Sprintf("%s/v2/%s/tags/list", url, repo), &tags, client)
@ -342,7 +345,7 @@ func pushMonolithImage(workdir, url, trepo string, repos []string, config testCo
resp.StatusCode(), string(resp.Body())) //nolint: goerr113 resp.StatusCode(), string(resp.Body())) //nolint: goerr113
} }
loc := test.Location(url, resp) loc := testc.Location(url, resp)
var size int var size int
@ -396,8 +399,8 @@ func pushMonolithImage(workdir, url, trepo string, repos []string, config testCo
resp.StatusCode(), string(resp.Body())) resp.StatusCode(), string(resp.Body()))
} }
loc = test.Location(url, resp) loc = testc.Location(url, resp)
cblob, cdigest := test.GetRandomImageConfig() cblob, cdigest := getRandomImageConfig()
resp, err = client.R(). resp, err = client.R().
SetContentLength(true). SetContentLength(true).
SetHeader("Content-Length", fmt.Sprintf("%d", len(cblob))). SetHeader("Content-Length", fmt.Sprintf("%d", len(cblob))).
@ -524,7 +527,7 @@ func pushMonolithAndCollect(workdir, url, trepo string, count int,
return return
} }
loc := test.Location(url, resp) loc := testc.Location(url, resp)
var size int var size int
@ -592,8 +595,8 @@ func pushMonolithAndCollect(workdir, url, trepo string, count int,
return return
} }
loc = test.Location(url, resp) loc = testc.Location(url, resp)
cblob, cdigest := test.GetRandomImageConfig() cblob, cdigest := getRandomImageConfig()
resp, err = client.R(). resp, err = client.R().
SetContentLength(true). SetContentLength(true).
SetHeader("Content-Length", fmt.Sprintf("%d", len(cblob))). SetHeader("Content-Length", fmt.Sprintf("%d", len(cblob))).
@ -728,7 +731,7 @@ func pushChunkAndCollect(workdir, url, trepo string, count int,
return return
} }
loc := test.Location(url, resp) loc := testc.Location(url, resp)
var size int var size int
@ -766,7 +769,7 @@ func pushChunkAndCollect(workdir, url, trepo string, count int,
return return
} }
loc = test.Location(url, resp) loc = testc.Location(url, resp)
// request specific check // request specific check
statusCode = resp.StatusCode() statusCode = resp.StatusCode()
@ -820,8 +823,8 @@ func pushChunkAndCollect(workdir, url, trepo string, count int,
return return
} }
loc = test.Location(url, resp) loc = testc.Location(url, resp)
cblob, cdigest := test.GetRandomImageConfig() cblob, cdigest := getRandomImageConfig()
resp, err = client.R(). resp, err = client.R().
SetContentLength(true). SetContentLength(true).
SetHeader("Content-Type", "application/octet-stream"). SetHeader("Content-Type", "application/octet-stream").
@ -857,7 +860,7 @@ func pushChunkAndCollect(workdir, url, trepo string, count int,
return return
} }
loc = test.Location(url, resp) loc = testc.Location(url, resp)
// request specific check // request specific check
statusCode = resp.StatusCode() statusCode = resp.StatusCode()
@ -1017,3 +1020,48 @@ func loadOrStore(statusRequests *sync.Map, key string, value int) int { //nolint
return intValue return intValue
} }
// TO DO: replace with pkg/test/images when available.
func getRandomImageConfig() ([]byte, godigest.Digest) {
const maxLen = 16
randomAuthor := randomString(maxLen)
config := ispec.Image{
Platform: ispec.Platform{
Architecture: "amd64",
OS: "linux",
},
RootFS: ispec.RootFS{
Type: "layers",
DiffIDs: []godigest.Digest{},
},
Author: randomAuthor,
}
configBlobContent, err := json.MarshalIndent(&config, "", "\t")
if err != nil {
log.Fatal(err)
}
configBlobDigestRaw := godigest.FromBytes(configBlobContent)
return configBlobContent, configBlobDigestRaw
}
func randomString(n int) string {
const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"
ret := make([]byte, n)
for count := 0; count < n; count++ {
num, err := crand.Int(crand.Reader, big.NewInt(int64(len(letters))))
if err != nil {
panic(err)
}
ret[count] = letters[num.Int64()]
}
return string(ret)
}

View file

@ -61,6 +61,7 @@ import (
"zotregistry.io/zot/pkg/storage" "zotregistry.io/zot/pkg/storage"
storageConstants "zotregistry.io/zot/pkg/storage/constants" storageConstants "zotregistry.io/zot/pkg/storage/constants"
"zotregistry.io/zot/pkg/test" "zotregistry.io/zot/pkg/test"
testc "zotregistry.io/zot/pkg/test/common"
"zotregistry.io/zot/pkg/test/inject" "zotregistry.io/zot/pkg/test/inject"
"zotregistry.io/zot/pkg/test/mocks" "zotregistry.io/zot/pkg/test/mocks"
) )
@ -3788,7 +3789,7 @@ func TestAuthorizationWithOnlyAnonymousPolicy(t *testing.T) {
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp, ShouldNotBeNil) So(resp, ShouldNotBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc = test.Location(baseURL, resp) loc = testc.Location(baseURL, resp)
// uploading blob should get 201 // uploading blob should get 201
resp, err = resty.R().SetHeader("Content-Length", fmt.Sprintf("%d", len(cblob))). resp, err = resty.R().SetHeader("Content-Length", fmt.Sprintf("%d", len(cblob))).
@ -3833,7 +3834,7 @@ func TestAuthorizationWithOnlyAnonymousPolicy(t *testing.T) {
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp, ShouldNotBeNil) So(resp, ShouldNotBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc = test.Location(baseURL, resp) loc = testc.Location(baseURL, resp)
// uploading blob should get 201 // uploading blob should get 201
resp, err = resty.R(). resp, err = resty.R().
SetHeader("Content-Length", fmt.Sprintf("%d", len(updateBlob))). SetHeader("Content-Length", fmt.Sprintf("%d", len(updateBlob))).
@ -4494,7 +4495,7 @@ func TestCrossRepoMount(t *testing.T) {
Post(baseURL + "/v2/zot-y-test/blobs/uploads/") Post(baseURL + "/v2/zot-y-test/blobs/uploads/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(postResponse.StatusCode(), ShouldEqual, http.StatusAccepted) So(postResponse.StatusCode(), ShouldEqual, http.StatusAccepted)
So(test.Location(baseURL, postResponse), ShouldStartWith, fmt.Sprintf("%s%s/zot-y-test/%s/%s", So(testc.Location(baseURL, postResponse), ShouldStartWith, fmt.Sprintf("%s%s/zot-y-test/%s/%s",
baseURL, constants.RoutePrefix, constants.Blobs, constants.Uploads)) baseURL, constants.RoutePrefix, constants.Blobs, constants.Uploads))
// Use correct request // Use correct request
@ -4505,7 +4506,7 @@ func TestCrossRepoMount(t *testing.T) {
Post(baseURL + "/v2/zot-c-test/blobs/uploads/") Post(baseURL + "/v2/zot-c-test/blobs/uploads/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(postResponse.StatusCode(), ShouldEqual, http.StatusAccepted) So(postResponse.StatusCode(), ShouldEqual, http.StatusAccepted)
So(test.Location(baseURL, postResponse), ShouldStartWith, fmt.Sprintf("%s%s/zot-c-test/%s/%s", So(testc.Location(baseURL, postResponse), ShouldStartWith, fmt.Sprintf("%s%s/zot-c-test/%s/%s",
baseURL, constants.RoutePrefix, constants.Blobs, constants.Uploads)) baseURL, constants.RoutePrefix, constants.Blobs, constants.Uploads))
// Send same request again // Send same request again
@ -4578,7 +4579,7 @@ func TestCrossRepoMount(t *testing.T) {
Post(baseURL + "/v2/zot-mount-test/blobs/uploads/") Post(baseURL + "/v2/zot-mount-test/blobs/uploads/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(postResponse.StatusCode(), ShouldEqual, http.StatusCreated) So(postResponse.StatusCode(), ShouldEqual, http.StatusCreated)
So(test.Location(baseURL, postResponse), ShouldEqual, fmt.Sprintf("%s%s/zot-mount-test/%s/%s:%s", So(testc.Location(baseURL, postResponse), ShouldEqual, fmt.Sprintf("%s%s/zot-mount-test/%s/%s:%s",
baseURL, constants.RoutePrefix, constants.Blobs, godigest.SHA256, blob)) baseURL, constants.RoutePrefix, constants.Blobs, godigest.SHA256, blob))
// Check os.SameFile here // Check os.SameFile here
@ -4603,7 +4604,7 @@ func TestCrossRepoMount(t *testing.T) {
Post(baseURL + "/v2/zot-mount1-test/blobs/uploads/") Post(baseURL + "/v2/zot-mount1-test/blobs/uploads/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(postResponse.StatusCode(), ShouldEqual, http.StatusCreated) So(postResponse.StatusCode(), ShouldEqual, http.StatusCreated)
So(test.Location(baseURL, postResponse), ShouldEqual, fmt.Sprintf("%s%s/zot-mount1-test/%s/%s:%s", So(testc.Location(baseURL, postResponse), ShouldEqual, fmt.Sprintf("%s%s/zot-mount1-test/%s/%s:%s",
baseURL, constants.RoutePrefix, constants.Blobs, godigest.SHA256, blob)) baseURL, constants.RoutePrefix, constants.Blobs, godigest.SHA256, blob))
linkPath = path.Join(ctlr.Config.Storage.RootDirectory, "zot-mount1-test", "blobs/sha256", dgst.Encoded()) linkPath = path.Join(ctlr.Config.Storage.RootDirectory, "zot-mount1-test", "blobs/sha256", dgst.Encoded())
@ -5556,7 +5557,7 @@ func TestArtifactReferences(t *testing.T) {
resp, err = resty.R().Post(baseURL + fmt.Sprintf("/v2/%s/blobs/uploads/", repoName)) resp, err = resty.R().Post(baseURL + fmt.Sprintf("/v2/%s/blobs/uploads/", repoName))
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc := test.Location(baseURL, resp) loc := testc.Location(baseURL, resp)
cblob, cdigest := test.GetEmptyImageConfig() cblob, cdigest := test.GetEmptyImageConfig()
resp, err = resty.R(). resp, err = resty.R().
@ -5653,7 +5654,7 @@ func TestArtifactReferences(t *testing.T) {
resp, err = resty.R().Post(baseURL + fmt.Sprintf("/v2/%s/blobs/uploads/", repoName)) resp, err = resty.R().Post(baseURL + fmt.Sprintf("/v2/%s/blobs/uploads/", repoName))
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc := test.Location(baseURL, resp) loc := testc.Location(baseURL, resp)
cblob = []byte("{}") cblob = []byte("{}")
cdigest = godigest.FromBytes(cblob) cdigest = godigest.FromBytes(cblob)
So(cdigest, ShouldNotBeNil) So(cdigest, ShouldNotBeNil)
@ -6514,7 +6515,7 @@ func TestListingTags(t *testing.T) {
So(resp, ShouldNotBeNil) So(resp, ShouldNotBeNil)
So(resp.StatusCode, ShouldEqual, http.StatusOK) So(resp.StatusCode, ShouldEqual, http.StatusOK)
var tags api.ImageTags var tags common.ImageTags
err := json.NewDecoder(resp.Body).Decode(&tags) err := json.NewDecoder(resp.Body).Decode(&tags)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(tags.Tags, ShouldEqual, testCase.expectedTags) So(tags.Tags, ShouldEqual, testCase.expectedTags)
@ -6886,7 +6887,7 @@ func TestManifestImageIndex(t *testing.T) {
So(resp, ShouldNotBeNil) So(resp, ShouldNotBeNil)
So(resp.StatusCode, ShouldEqual, http.StatusOK) So(resp.StatusCode, ShouldEqual, http.StatusOK)
var tags api.ImageTags var tags common.ImageTags
err = json.NewDecoder(resp.Body).Decode(&tags) err = json.NewDecoder(resp.Body).Decode(&tags)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(len(tags.Tags), ShouldEqual, 3) So(len(tags.Tags), ShouldEqual, 3)
@ -7216,7 +7217,7 @@ func TestPullRange(t *testing.T) {
resp, err := resty.R().Post(baseURL + "/v2/index/blobs/uploads/") resp, err := resty.R().Post(baseURL + "/v2/index/blobs/uploads/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc := test.Location(baseURL, resp) loc := testc.Location(baseURL, resp)
So(loc, ShouldNotBeEmpty) So(loc, ShouldNotBeEmpty)
// since we are not specifying any prefix i.e provided in config while starting server, // since we are not specifying any prefix i.e provided in config while starting server,
@ -7379,7 +7380,7 @@ func TestInjectInterruptedImageManifest(t *testing.T) {
resp, err := resty.R().Post(baseURL + "/v2/repotest/blobs/uploads/") resp, err := resty.R().Post(baseURL + "/v2/repotest/blobs/uploads/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc := test.Location(baseURL, resp) loc := testc.Location(baseURL, resp)
So(loc, ShouldNotBeEmpty) So(loc, ShouldNotBeEmpty)
// since we are not specifying any prefix i.e provided in config while starting server, // since we are not specifying any prefix i.e provided in config while starting server,
@ -7407,7 +7408,7 @@ func TestInjectInterruptedImageManifest(t *testing.T) {
resp, err = resty.R().Post(baseURL + "/v2/repotest/blobs/uploads/") resp, err = resty.R().Post(baseURL + "/v2/repotest/blobs/uploads/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc = test.Location(baseURL, resp) loc = testc.Location(baseURL, resp)
cblob, cdigest := test.GetRandomImageConfig() cblob, cdigest := test.GetRandomImageConfig()
resp, err = resty.R(). resp, err = resty.R().
@ -7488,7 +7489,7 @@ func TestInjectTooManyOpenFiles(t *testing.T) {
resp, err := resty.R().Post(baseURL + "/v2/repotest/blobs/uploads/") resp, err := resty.R().Post(baseURL + "/v2/repotest/blobs/uploads/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc := test.Location(baseURL, resp) loc := testc.Location(baseURL, resp)
So(loc, ShouldNotBeEmpty) So(loc, ShouldNotBeEmpty)
// since we are not specifying any prefix i.e provided in config while starting server, // since we are not specifying any prefix i.e provided in config while starting server,
@ -7540,7 +7541,7 @@ func TestInjectTooManyOpenFiles(t *testing.T) {
resp, err = resty.R().Post(baseURL + "/v2/repotest/blobs/uploads/") resp, err = resty.R().Post(baseURL + "/v2/repotest/blobs/uploads/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc = test.Location(baseURL, resp) loc = testc.Location(baseURL, resp)
cblob, cdigest := test.GetRandomImageConfig() cblob, cdigest := test.GetRandomImageConfig()
resp, err = resty.R(). resp, err = resty.R().
@ -9466,7 +9467,7 @@ func RunAuthorizationTests(t *testing.T, client *resty.Client, baseURL string, c
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp, ShouldNotBeNil) So(resp, ShouldNotBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc = test.Location(baseURL, resp) loc = testc.Location(baseURL, resp)
// uploading blob should get 201 // uploading blob should get 201
resp, err = client.R(). resp, err = client.R().
@ -9486,7 +9487,7 @@ func RunAuthorizationTests(t *testing.T, client *resty.Client, baseURL string, c
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp, ShouldNotBeNil) So(resp, ShouldNotBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc = test.Location(baseURL, resp) loc = testc.Location(baseURL, resp)
// uploading blob should get 201 // uploading blob should get 201
resp, err = client.R(). resp, err = client.R().

View file

@ -261,11 +261,6 @@ func (rh *RouteHandler) CheckVersionSupport(response http.ResponseWriter, reques
zcommon.WriteData(response, http.StatusOK, "application/json", []byte{}) zcommon.WriteData(response, http.StatusOK, "application/json", []byte{})
} }
type ImageTags struct {
Name string `json:"name"`
Tags []string `json:"tags"`
}
// ListTags godoc // ListTags godoc
// @Summary List image tags // @Summary List image tags
// @Description List all image tags in a repository // @Description List all image tags in a repository
@ -275,7 +270,7 @@ type ImageTags struct {
// @Param name path string true "test" // @Param name path string true "test"
// @Param n query integer true "limit entries for pagination" // @Param n query integer true "limit entries for pagination"
// @Param last query string true "last tag value for pagination" // @Param last query string true "last tag value for pagination"
// @Success 200 {object} api.ImageTags // @Success 200 {object} common.ImageTags
// @Failure 404 {string} string "not found" // @Failure 404 {string} string "not found"
// @Failure 400 {string} string "bad request". // @Failure 400 {string} string "bad request".
func (rh *RouteHandler) ListTags(response http.ResponseWriter, request *http.Request) { func (rh *RouteHandler) ListTags(response http.ResponseWriter, request *http.Request) {
@ -373,7 +368,7 @@ func (rh *RouteHandler) ListTags(response http.ResponseWriter, request *http.Req
} }
} }
pTags := ImageTags{Name: name} pTags := zcommon.ImageTags{Name: name}
if paginate && numTags == 0 { if paginate && numTags == 0 {
pTags.Tags = []string{} pTags.Tags = []string{}

View file

@ -33,6 +33,7 @@ import (
extconf "zotregistry.io/zot/pkg/extensions/config" extconf "zotregistry.io/zot/pkg/extensions/config"
zlog "zotregistry.io/zot/pkg/log" zlog "zotregistry.io/zot/pkg/log"
"zotregistry.io/zot/pkg/test" "zotregistry.io/zot/pkg/test"
testc "zotregistry.io/zot/pkg/test/common"
) )
func TestSearchImageCmd(t *testing.T) { func TestSearchImageCmd(t *testing.T) {
@ -1941,7 +1942,7 @@ func uploadTestMultiarch(baseURL string) {
func uploadManifest(url string) error { func uploadManifest(url string) error {
// create and upload a blob/layer // create and upload a blob/layer
resp, _ := resty.R().Post(url + "/v2/repo7/blobs/uploads/") resp, _ := resty.R().Post(url + "/v2/repo7/blobs/uploads/")
loc := test.Location(url, resp) loc := testc.Location(url, resp)
content := []byte("this is a blob5") content := []byte("this is a blob5")
digest := godigest.FromBytes(content) digest := godigest.FromBytes(content)
@ -1973,7 +1974,7 @@ func uploadManifest(url string) error {
// upload image config blob // upload image config blob
resp, _ = resty.R().Post(url + "/v2/repo7/blobs/uploads/") resp, _ = resty.R().Post(url + "/v2/repo7/blobs/uploads/")
loc = test.Location(url, resp) loc = testc.Location(url, resp)
_, _ = resty.R(). _, _ = resty.R().
SetContentLength(true). SetContentLength(true).
@ -2079,7 +2080,7 @@ func uploadManifestDerivedBase(url string) error {
// upload image config blob // upload image config blob
resp, _ := resty.R().Post(url + "/v2/repo7/blobs/uploads/") resp, _ := resty.R().Post(url + "/v2/repo7/blobs/uploads/")
loc := test.Location(url, resp) loc := testc.Location(url, resp)
_, _ = resty.R(). _, _ = resty.R().
SetContentLength(true). SetContentLength(true).

View file

@ -254,3 +254,8 @@ type BookmarkedReposResponse struct {
BookmarkedRepos `json:"data"` BookmarkedRepos `json:"data"`
Errors []ErrorGQL `json:"errors"` Errors []ErrorGQL `json:"errors"`
} }
type ImageTags struct {
Name string `json:"name"`
Tags []string `json:"tags"`
}

View file

@ -23,6 +23,7 @@ import (
"zotregistry.io/zot/pkg/api/constants" "zotregistry.io/zot/pkg/api/constants"
"zotregistry.io/zot/pkg/compliance" "zotregistry.io/zot/pkg/compliance"
"zotregistry.io/zot/pkg/test" "zotregistry.io/zot/pkg/test"
testc "zotregistry.io/zot/pkg/test/common"
) )
func CheckWorkflows(t *testing.T, config *compliance.Config) { func CheckWorkflows(t *testing.T, config *compliance.Config) {
@ -118,7 +119,7 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
resp, err := resty.R().Post(baseURL + "/v2/repo2/blobs/uploads/") resp, err := resty.R().Post(baseURL + "/v2/repo2/blobs/uploads/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc := test.Location(baseURL, resp) loc := testc.Location(baseURL, resp)
So(loc, ShouldNotBeEmpty) So(loc, ShouldNotBeEmpty)
resp, err = resty.R().Get(loc) resp, err = resty.R().Get(loc)
@ -154,7 +155,7 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
SetHeader("Content-Type", "application/octet-stream").SetBody(content).Put(loc) SetHeader("Content-Type", "application/octet-stream").SetBody(content).Put(loc)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusCreated) So(resp.StatusCode(), ShouldEqual, http.StatusCreated)
blobLoc := test.Location(baseURL, resp) blobLoc := testc.Location(baseURL, resp)
So(blobLoc, ShouldNotBeEmpty) So(blobLoc, ShouldNotBeEmpty)
So(resp.Header().Get("Content-Length"), ShouldEqual, "0") So(resp.Header().Get("Content-Length"), ShouldEqual, "0")
So(resp.Header().Get(constants.DistContentDigestKey), ShouldNotBeEmpty) So(resp.Header().Get(constants.DistContentDigestKey), ShouldNotBeEmpty)
@ -198,7 +199,7 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
Post(baseURL + "/v2/repo2/blobs/uploads/") Post(baseURL + "/v2/repo2/blobs/uploads/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusCreated) So(resp.StatusCode(), ShouldEqual, http.StatusCreated)
loc := test.Location(baseURL, resp) loc := testc.Location(baseURL, resp)
So(loc, ShouldNotBeEmpty) So(loc, ShouldNotBeEmpty)
// blob reference should be accessible // blob reference should be accessible
resp, err = resty.R().Get(loc) resp, err = resty.R().Get(loc)
@ -211,7 +212,7 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
resp, err := resty.R().Post(baseURL + "/v2/repo10/repo20/repo30/blobs/uploads/") resp, err := resty.R().Post(baseURL + "/v2/repo10/repo20/repo30/blobs/uploads/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc := test.Location(baseURL, resp) loc := testc.Location(baseURL, resp)
So(loc, ShouldNotBeEmpty) So(loc, ShouldNotBeEmpty)
resp, err = resty.R().Get(loc) resp, err = resty.R().Get(loc)
@ -247,7 +248,7 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
SetHeader("Content-Type", "application/octet-stream").SetBody(content).Put(loc) SetHeader("Content-Type", "application/octet-stream").SetBody(content).Put(loc)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusCreated) So(resp.StatusCode(), ShouldEqual, http.StatusCreated)
blobLoc := test.Location(baseURL, resp) blobLoc := testc.Location(baseURL, resp)
So(blobLoc, ShouldNotBeEmpty) So(blobLoc, ShouldNotBeEmpty)
So(resp.Header().Get("Content-Length"), ShouldEqual, "0") So(resp.Header().Get("Content-Length"), ShouldEqual, "0")
So(resp.Header().Get(constants.DistContentDigestKey), ShouldNotBeEmpty) So(resp.Header().Get(constants.DistContentDigestKey), ShouldNotBeEmpty)
@ -266,7 +267,7 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
resp, err := resty.R().Post(baseURL + "/v2/repo3/blobs/uploads/") resp, err := resty.R().Post(baseURL + "/v2/repo3/blobs/uploads/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc := test.Location(baseURL, resp) loc := testc.Location(baseURL, resp)
So(loc, ShouldNotBeEmpty) So(loc, ShouldNotBeEmpty)
var buf bytes.Buffer var buf bytes.Buffer
@ -313,7 +314,7 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
SetHeader("Content-Type", "application/octet-stream").SetBody(chunk2).Put(loc) SetHeader("Content-Type", "application/octet-stream").SetBody(chunk2).Put(loc)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusCreated) So(resp.StatusCode(), ShouldEqual, http.StatusCreated)
blobLoc := test.Location(baseURL, resp) blobLoc := testc.Location(baseURL, resp)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusCreated) So(resp.StatusCode(), ShouldEqual, http.StatusCreated)
So(blobLoc, ShouldNotBeEmpty) So(blobLoc, ShouldNotBeEmpty)
@ -334,7 +335,7 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
resp, err := resty.R().Post(baseURL + "/v2/repo40/repo50/repo60/blobs/uploads/") resp, err := resty.R().Post(baseURL + "/v2/repo40/repo50/repo60/blobs/uploads/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc := test.Location(baseURL, resp) loc := testc.Location(baseURL, resp)
So(loc, ShouldNotBeEmpty) So(loc, ShouldNotBeEmpty)
var buf bytes.Buffer var buf bytes.Buffer
@ -381,7 +382,7 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
SetHeader("Content-Type", "application/octet-stream").SetBody(chunk2).Put(loc) SetHeader("Content-Type", "application/octet-stream").SetBody(chunk2).Put(loc)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusCreated) So(resp.StatusCode(), ShouldEqual, http.StatusCreated)
blobLoc := test.Location(baseURL, resp) blobLoc := testc.Location(baseURL, resp)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusCreated) So(resp.StatusCode(), ShouldEqual, http.StatusCreated)
So(blobLoc, ShouldNotBeEmpty) So(blobLoc, ShouldNotBeEmpty)
@ -403,7 +404,7 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
resp, err := resty.R().Post(baseURL + "/v2/repo4/blobs/uploads/") resp, err := resty.R().Post(baseURL + "/v2/repo4/blobs/uploads/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc := test.Location(baseURL, resp) loc := testc.Location(baseURL, resp)
So(loc, ShouldNotBeEmpty) So(loc, ShouldNotBeEmpty)
// delete this upload // delete this upload
@ -418,7 +419,7 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
resp, err := resty.R().Post(baseURL + "/v2/repo5/blobs/uploads/") resp, err := resty.R().Post(baseURL + "/v2/repo5/blobs/uploads/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc := test.Location(baseURL, resp) loc := testc.Location(baseURL, resp)
So(loc, ShouldNotBeEmpty) So(loc, ShouldNotBeEmpty)
content := []byte("this is a blob4") content := []byte("this is a blob4")
@ -429,7 +430,7 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
SetHeader("Content-Type", "application/octet-stream").SetBody(content).Put(loc) SetHeader("Content-Type", "application/octet-stream").SetBody(content).Put(loc)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusCreated) So(resp.StatusCode(), ShouldEqual, http.StatusCreated)
blobLoc := test.Location(baseURL, resp) blobLoc := testc.Location(baseURL, resp)
So(blobLoc, ShouldNotBeEmpty) So(blobLoc, ShouldNotBeEmpty)
So(resp.Header().Get(constants.DistContentDigestKey), ShouldNotBeEmpty) So(resp.Header().Get(constants.DistContentDigestKey), ShouldNotBeEmpty)
@ -454,7 +455,7 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
resp, err := resty.R().Post(baseURL + "/v2/repo7/blobs/uploads/") resp, err := resty.R().Post(baseURL + "/v2/repo7/blobs/uploads/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc := test.Location(baseURL, resp) loc := testc.Location(baseURL, resp)
So(loc, ShouldNotBeEmpty) So(loc, ShouldNotBeEmpty)
// since we are not specifying any prefix i.e provided in config while starting server, // since we are not specifying any prefix i.e provided in config while starting server,
@ -666,7 +667,7 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
resp, err := resty.R().Post(baseURL + "/v2/firsttest/first/blobs/uploads/") resp, err := resty.R().Post(baseURL + "/v2/firsttest/first/blobs/uploads/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
firstloc := test.Location(baseURL, resp) firstloc := testc.Location(baseURL, resp)
So(firstloc, ShouldNotBeEmpty) So(firstloc, ShouldNotBeEmpty)
resp, err = resty.R().Get(firstloc) resp, err = resty.R().Get(firstloc)
@ -681,7 +682,7 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
resp, err = resty.R().Post(baseURL + "/v2/secondtest/second/blobs/uploads/") resp, err = resty.R().Post(baseURL + "/v2/secondtest/second/blobs/uploads/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
secondloc := test.Location(baseURL, resp) secondloc := testc.Location(baseURL, resp)
So(secondloc, ShouldNotBeEmpty) So(secondloc, ShouldNotBeEmpty)
resp, err = resty.R().Get(secondloc) resp, err = resty.R().Get(secondloc)

View file

@ -24,6 +24,7 @@ import (
"zotregistry.io/zot/pkg/log" "zotregistry.io/zot/pkg/log"
"zotregistry.io/zot/pkg/storage/local" "zotregistry.io/zot/pkg/storage/local"
"zotregistry.io/zot/pkg/test" "zotregistry.io/zot/pkg/test"
testc "zotregistry.io/zot/pkg/test/common"
) )
const ( const (
@ -257,7 +258,7 @@ func TestVerifyMandatoryAnnotations(t *testing.T) {
resp, err = resty.R(). resp, err = resty.R().
Post(fmt.Sprintf("%s/v2/zot-test/blobs/uploads/", baseURL)) Post(fmt.Sprintf("%s/v2/zot-test/blobs/uploads/", baseURL))
So(err, ShouldBeNil) So(err, ShouldBeNil)
loc := test.Location(baseURL, resp) loc := testc.Location(baseURL, resp)
_, err = resty.R(). _, err = resty.R().
SetContentLength(true). SetContentLength(true).
@ -344,7 +345,7 @@ func TestVerifyMandatoryAnnotations(t *testing.T) {
_, err = resty.R(). _, err = resty.R().
Post(fmt.Sprintf("%s/v2/zot-test/blobs/uploads/", baseURL)) Post(fmt.Sprintf("%s/v2/zot-test/blobs/uploads/", baseURL))
So(err, ShouldBeNil) So(err, ShouldBeNil)
loc := test.Location(baseURL, resp) loc := testc.Location(baseURL, resp)
_, err = resty.R(). _, err = resty.R().
SetContentLength(true). SetContentLength(true).

View file

@ -48,6 +48,7 @@ import (
mTypes "zotregistry.io/zot/pkg/meta/types" mTypes "zotregistry.io/zot/pkg/meta/types"
storageConstants "zotregistry.io/zot/pkg/storage/constants" storageConstants "zotregistry.io/zot/pkg/storage/constants"
"zotregistry.io/zot/pkg/test" "zotregistry.io/zot/pkg/test"
testc "zotregistry.io/zot/pkg/test/common"
"zotregistry.io/zot/pkg/test/mocks" "zotregistry.io/zot/pkg/test/mocks"
) )
@ -6329,7 +6330,7 @@ func pushRepo(url, repoName string) godigest.Digest {
panic(err) panic(err)
} }
loc := test.Location(url, resp) loc := testc.Location(url, resp)
_, err = resty.R().Get(loc) _, err = resty.R().Get(loc)
if err != nil { if err != nil {
@ -6356,7 +6357,7 @@ func pushRepo(url, repoName string) godigest.Digest {
panic(fmt.Errorf("invalid status code: %d %w", resp.StatusCode(), errBadStatus)) panic(fmt.Errorf("invalid status code: %d %w", resp.StatusCode(), errBadStatus))
} }
loc = test.Location(url, resp) loc = testc.Location(url, resp)
cblob, cdigest := ispec.DescriptorEmptyJSON.Data, ispec.DescriptorEmptyJSON.Digest cblob, cdigest := ispec.DescriptorEmptyJSON.Data, ispec.DescriptorEmptyJSON.Digest
resp, err = resty.R(). resp, err = resty.R().
@ -6385,7 +6386,7 @@ func pushRepo(url, repoName string) godigest.Digest {
panic(fmt.Errorf("invalid status code: %d %w", resp.StatusCode(), errBadStatus)) panic(fmt.Errorf("invalid status code: %d %w", resp.StatusCode(), errBadStatus))
} }
loc = test.Location(url, resp) loc = testc.Location(url, resp)
cblob, cdigest = test.GetRandomImageConfig() cblob, cdigest = test.GetRandomImageConfig()
resp, err = resty.R(). resp, err = resty.R().
@ -6553,7 +6554,7 @@ func pushBlob(url string, repoName string, buf []byte) godigest.Digest {
panic(fmt.Errorf("invalid status code: %d %w", resp.StatusCode(), errBadStatus)) panic(fmt.Errorf("invalid status code: %d %w", resp.StatusCode(), errBadStatus))
} }
loc := test.Location(url, resp) loc := testc.Location(url, resp)
digest := godigest.FromBytes(buf) digest := godigest.FromBytes(buf)
resp, err = resty.R(). resp, err = resty.R().

View file

@ -25,6 +25,7 @@ import (
"zotregistry.io/zot/pkg/api/constants" "zotregistry.io/zot/pkg/api/constants"
"zotregistry.io/zot/pkg/log" "zotregistry.io/zot/pkg/log"
. "zotregistry.io/zot/pkg/test" . "zotregistry.io/zot/pkg/test"
testc "zotregistry.io/zot/pkg/test/common"
) )
const ( const (
@ -127,7 +128,7 @@ func TestAuditLogMessages(t *testing.T) {
resp, err := resty.R().SetBasicAuth(username, passphrase).Post(baseURL + path) resp, err := resty.R().SetBasicAuth(username, passphrase).Post(baseURL + path)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc := Location(baseURL, resp) loc := testc.Location(baseURL, resp)
So(loc, ShouldNotBeEmpty) So(loc, ShouldNotBeEmpty)
location := resp.Header().Get("Location") location := resp.Header().Get("Location")
So(location, ShouldNotBeEmpty) So(location, ShouldNotBeEmpty)
@ -163,7 +164,7 @@ func TestAuditLogMessages(t *testing.T) {
SetHeader("Content-Type", "application/octet-stream").SetBody(content).Put(loc) SetHeader("Content-Type", "application/octet-stream").SetBody(content).Put(loc)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusCreated) So(resp.StatusCode(), ShouldEqual, http.StatusCreated)
blobLoc := Location(baseURL, resp) blobLoc := testc.Location(baseURL, resp)
So(blobLoc, ShouldNotBeEmpty) So(blobLoc, ShouldNotBeEmpty)
So(resp.Header().Get(constants.DistContentDigestKey), ShouldNotBeEmpty) So(resp.Header().Get(constants.DistContentDigestKey), ShouldNotBeEmpty)
@ -223,7 +224,7 @@ func TestAuditLogMessages(t *testing.T) {
resp, err := resty.R().SetBasicAuth(username, passphrase).Post(baseURL + path) resp, err := resty.R().SetBasicAuth(username, passphrase).Post(baseURL + path)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted) So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc := Location(baseURL, resp) loc := testc.Location(baseURL, resp)
So(loc, ShouldNotBeEmpty) So(loc, ShouldNotBeEmpty)
location := resp.Header().Get("Location") location := resp.Header().Get("Location")
So(location, ShouldNotBeEmpty) So(location, ShouldNotBeEmpty)

View file

@ -18,7 +18,6 @@ import (
mathRand "math/rand" mathRand "math/rand"
"net" "net"
"net/http" "net/http"
"net/url"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
@ -55,6 +54,7 @@ import (
storageCommon "zotregistry.io/zot/pkg/storage/common" storageCommon "zotregistry.io/zot/pkg/storage/common"
"zotregistry.io/zot/pkg/storage/local" "zotregistry.io/zot/pkg/storage/local"
stypes "zotregistry.io/zot/pkg/storage/types" stypes "zotregistry.io/zot/pkg/storage/types"
testc "zotregistry.io/zot/pkg/test/common"
"zotregistry.io/zot/pkg/test/inject" "zotregistry.io/zot/pkg/test/inject"
"zotregistry.io/zot/pkg/test/mocks" "zotregistry.io/zot/pkg/test/mocks"
) )
@ -158,24 +158,6 @@ func MakeHtpasswdFileFromString(fileContent string) string {
return htpasswdFile.Name() return htpasswdFile.Name()
} }
func Location(baseURL string, resp *resty.Response) string {
// For some API responses, the Location header is set and is supposed to
// indicate an opaque value. However, it is not clear if this value is an
// absolute URL (https://server:port/v2/...) or just a path (/v2/...)
// zot implements the latter as per the spec, but some registries appear to
// return the former - this needs to be clarified
loc := resp.Header().Get("Location")
uloc, err := url.Parse(loc)
if err != nil {
return ""
}
path := uloc.Path
return baseURL + path
}
func CopyFiles(sourceDir, destDir string) error { func CopyFiles(sourceDir, destDir string) error {
sourceMeta, err := os.Stat(sourceDir) sourceMeta, err := os.Stat(sourceDir)
if err != nil { if err != nil {
@ -954,7 +936,7 @@ func UploadImage(img Image, baseURL, repo, ref string) error {
return ErrPostBlob return ErrPostBlob
} }
loc := Location(baseURL, resp) loc := testc.Location(baseURL, resp)
// uploading blob should get 201 // uploading blob should get 201
resp, err = resty.R(). resp, err = resty.R().
@ -1633,7 +1615,7 @@ func UploadImageWithBasicAuth(img Image, baseURL, repo, ref, user, password stri
return ErrPostBlob return ErrPostBlob
} }
loc := Location(baseURL, resp) loc := testc.Location(baseURL, resp)
// uploading blob should get 201 // uploading blob should get 201
resp, err = resty.R(). resp, err = resty.R().

25
pkg/test/common/utils.go Normal file
View file

@ -0,0 +1,25 @@
package common
import (
"net/url"
"gopkg.in/resty.v1"
)
func Location(baseURL string, resp *resty.Response) string {
// For some API responses, the Location header is set and is supposed to
// indicate an opaque value. However, it is not clear if this value is an
// absolute URL (https://server:port/v2/...) or just a path (/v2/...)
// zot implements the latter as per the spec, but some registries appear to
// return the former - this needs to be clarified
loc := resp.Header().Get("Location")
uloc, err := url.Parse(loc)
if err != nil {
return ""
}
path := uloc.Path
return baseURL + path
}

View file

@ -1146,7 +1146,7 @@ const docTemplate = `{
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"$ref": "#/definitions/api.ImageTags" "$ref": "#/definitions/common.ImageTags"
} }
}, },
"400": { "400": {
@ -1280,13 +1280,10 @@ const docTemplate = `{
} }
} }
}, },
"api.ImageTags": { "api.RepositoryList": {
"type": "object", "type": "object",
"properties": { "properties": {
"name": { "repositories": {
"type": "string"
},
"tags": {
"type": "array", "type": "array",
"items": { "items": {
"type": "string" "type": "string"
@ -1294,10 +1291,13 @@ const docTemplate = `{
} }
} }
}, },
"api.RepositoryList": { "common.ImageTags": {
"type": "object", "type": "object",
"properties": { "properties": {
"repositories": { "name": {
"type": "string"
},
"tags": {
"type": "array", "type": "array",
"items": { "items": {
"type": "string" "type": "string"

View file

@ -1137,7 +1137,7 @@
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"$ref": "#/definitions/api.ImageTags" "$ref": "#/definitions/common.ImageTags"
} }
}, },
"400": { "400": {
@ -1271,13 +1271,10 @@
} }
} }
}, },
"api.ImageTags": { "api.RepositoryList": {
"type": "object", "type": "object",
"properties": { "properties": {
"name": { "repositories": {
"type": "string"
},
"tags": {
"type": "array", "type": "array",
"items": { "items": {
"type": "string" "type": "string"
@ -1285,10 +1282,13 @@
} }
} }
}, },
"api.RepositoryList": { "common.ImageTags": {
"type": "object", "type": "object",
"properties": { "properties": {
"repositories": { "name": {
"type": "string"
},
"tags": {
"type": "array", "type": "array",
"items": { "items": {
"type": "string" "type": "string"

View file

@ -83,18 +83,18 @@ definitions:
manifest forming an association between the image manifest and the other manifest forming an association between the image manifest and the other
manifest. manifest.
type: object type: object
api.ImageTags: api.RepositoryList:
properties: properties:
name: repositories:
type: string
tags:
items: items:
type: string type: string
type: array type: array
type: object type: object
api.RepositoryList: common.ImageTags:
properties: properties:
repositories: name:
type: string
tags:
items: items:
type: string type: string
type: array type: array
@ -994,7 +994,7 @@ paths:
"200": "200":
description: OK description: OK
schema: schema:
$ref: '#/definitions/api.ImageTags' $ref: '#/definitions/common.ImageTags'
"400": "400":
description: bad request". description: bad request".
schema: schema: