working commit
This commit is contained in:
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
|
||||
*
|
||||
* This work is published and licensed under a Creative Commons
|
||||
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
|
||||
*
|
||||
* Distribution of this work is permitted, but commercial use and
|
||||
* modifications are strictly prohibited.
|
||||
*/
|
||||
package accountcmd
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func packUserinfo(resurseuri, username, password string) (string, error) {
|
||||
var err error
|
||||
var res string
|
||||
if !strings.Contains(resurseuri, "://") {
|
||||
resurseuri = "https://" + resurseuri
|
||||
}
|
||||
uri, err := url.Parse(resurseuri)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
uri.Path = path.Clean(uri.Path)
|
||||
if username != "" && password != "" {
|
||||
uri.User = url.UserPassword(username, password)
|
||||
}
|
||||
res = uri.String()
|
||||
return res, err
|
||||
}
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"mstore/pkg/client"
|
||||
"mstore/pkg/repocli"
|
||||
)
|
||||
|
||||
// CatalogImages
|
||||
@@ -38,17 +38,16 @@ func (util *ImageUtil) catalogImages(common *CommonImageParams, params *CatalogI
|
||||
res := &CatalogImagesResult{
|
||||
Repositories: make([]string, 0),
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
cli := client.NewClient(common.SkipTLSVerify)
|
||||
timeout := time.Duration(common.Timeout) * time.Second
|
||||
ctx, _ := context.WithTimeout(context.Background(), timeout)
|
||||
|
||||
params.Source, err = packUserinfo(params.Source, common.Username, common.Password)
|
||||
ref, err := repocli.NewReferer(params.Source)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
ctx, _ = context.WithTimeout(ctx, timeout)
|
||||
opres, err := cli.CatalogImages(ctx, params.Source)
|
||||
mw := repocli.NewBasicAuthMiddleware(ref.Userinfo())
|
||||
cli := repocli.NewClient(nil, mw)
|
||||
opres, err := cli.GetCatalog(ctx, ref.Raw())
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"mstore/pkg/client"
|
||||
"mstore/pkg/repocli"
|
||||
)
|
||||
|
||||
// DeleteImage
|
||||
@@ -35,19 +35,20 @@ func (util *ImageUtil) DeleteImage(cmd *cobra.Command, args []string) {
|
||||
func (util *ImageUtil) deleteImage(common *CommonImageParams, params *DeleteImageParams) (*DeleteImageResult, error) {
|
||||
var err error
|
||||
res := &DeleteImageResult{}
|
||||
ctx := context.Background()
|
||||
|
||||
cli := client.NewClient(common.SkipTLSVerify)
|
||||
timeout := time.Duration(common.Timeout) * time.Second
|
||||
ctx, _ := context.WithTimeout(context.Background(), timeout)
|
||||
|
||||
params.Imagepath, err = packUserinfo(params.Imagepath, common.Username, common.Password)
|
||||
ref, err := repocli.NewReferer(params.Imagepath)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
ctx, _ = context.WithTimeout(ctx, timeout)
|
||||
err = cli.DeleteImage(ctx, params.Imagepath)
|
||||
mw := repocli.NewBasicAuthMiddleware(ref.Userinfo())
|
||||
cli := repocli.NewClient(nil, mw)
|
||||
_, err = cli.DeleteImage(ctx, ref.Raw())
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
|
||||
*
|
||||
* This work is published and licensed under a Creative Commons
|
||||
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
|
||||
*
|
||||
* Distribution of this work is permitted, but commercial use and
|
||||
* modifications are strictly prohibited.
|
||||
*/
|
||||
package imagecmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"mstore/pkg/client"
|
||||
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// ImageConfig
|
||||
type ImageConfigParams struct {
|
||||
Imagepath string
|
||||
}
|
||||
|
||||
type ImageConfigResult struct {
|
||||
ImageConfig *ocispec.Image `json:"imageConfig"`
|
||||
}
|
||||
|
||||
func (util *ImageUtil) ImageConfig(cmd *cobra.Command, args []string) {
|
||||
util.imageConfigParams.Imagepath = args[0]
|
||||
res, err := util.imageConfig(&util.commonImageParams, &util.imageConfigParams)
|
||||
printResponse(res, err)
|
||||
}
|
||||
|
||||
func (util *ImageUtil) imageConfig(common *CommonImageParams, params *ImageConfigParams) (*ImageConfigResult, error) {
|
||||
var err error
|
||||
res := &ImageConfigResult{
|
||||
ImageConfig: &ocispec.Image{},
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
cli := client.NewClient(common.SkipTLSVerify)
|
||||
timeout := time.Duration(common.Timeout) * time.Second
|
||||
|
||||
params.Imagepath, err = packUserinfo(params.Imagepath, common.Username, common.Password)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
ctx, _ = context.WithTimeout(ctx, timeout)
|
||||
opres, err := cli.ImageConfig(ctx, params.Imagepath)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
res.ImageConfig = opres
|
||||
return res, err
|
||||
}
|
||||
@@ -15,11 +15,10 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"mstore/pkg/repocli"
|
||||
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// ImageManifest
|
||||
@@ -55,8 +54,8 @@ func (util *ImageUtil) imageManifest(common *CommonImageParams, params *ImageMan
|
||||
return res, err
|
||||
}
|
||||
mw := repocli.NewBasicAuthMiddleware(ref.Userinfo())
|
||||
cli := repocli.NewClientWithTransport(nil, mw)
|
||||
exists, mime, man, err := cli.GetManifest(ctx, ref.Repo(), ref.Tag())
|
||||
cli := repocli.NewClient(nil, mw)
|
||||
exists, mime, man, err := cli.GetRawManifest(ctx, ref.Repo())
|
||||
if !exists {
|
||||
err = fmt.Errorf("Manifest not found")
|
||||
return res, err
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"mstore/pkg/client"
|
||||
"mstore/pkg/repocli"
|
||||
)
|
||||
|
||||
// ImageTags
|
||||
@@ -38,17 +38,17 @@ func (util *ImageUtil) imageTags(common *CommonImageParams, params *ImageTagsPar
|
||||
res := &ImageTagsResult{
|
||||
ImageTags: make([]string, 0),
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
cli := client.NewClient(common.SkipTLSVerify)
|
||||
timeout := time.Duration(common.Timeout) * time.Second
|
||||
ctx, _ := context.WithTimeout(context.Background(), timeout)
|
||||
|
||||
params.Imagepath, err = packUserinfo(params.Imagepath, common.Username, common.Password)
|
||||
ref, err := repocli.NewReferer(params.Imagepath)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
ctx, _ = context.WithTimeout(ctx, timeout)
|
||||
opres, err := cli.ImageTags(ctx, params.Imagepath)
|
||||
mw := repocli.NewBasicAuthMiddleware(ref.Userinfo())
|
||||
cli := repocli.NewClient(nil, mw)
|
||||
opres, err := cli.GetTags(ctx, ref.Raw())
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
|
||||
*
|
||||
* This work is published and licensed under a Creative Commons
|
||||
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
|
||||
*
|
||||
* Distribution of this work is permitted, but commercial use and
|
||||
* modifications are strictly prohibited.
|
||||
*/
|
||||
package imagecmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"mstore/pkg/client"
|
||||
)
|
||||
|
||||
// PullImage
|
||||
type PullImageParams struct {
|
||||
Imagepath string
|
||||
Filepath string
|
||||
}
|
||||
|
||||
type PullImageResult struct {
|
||||
Filepath string `json:"filepath"`
|
||||
Size int64 `json:"size"`
|
||||
}
|
||||
|
||||
func (util *ImageUtil) PullImage(cmd *cobra.Command, args []string) {
|
||||
util.pullImageParams.Imagepath = args[0]
|
||||
util.pullImageParams.Filepath = args[1]
|
||||
res, err := util.pullImage(&util.commonImageParams, &util.pullImageParams)
|
||||
printResponse(res, err)
|
||||
}
|
||||
|
||||
func (util *ImageUtil) pullImage(common *CommonImageParams, params *PullImageParams) (*PullImageResult, error) {
|
||||
var err error
|
||||
|
||||
ctx := context.Background()
|
||||
res := &PullImageResult{}
|
||||
|
||||
cli := client.NewClient(common.SkipTLSVerify)
|
||||
timeout := time.Duration(common.Timeout) * time.Second
|
||||
params.Imagepath, err = packUserinfo(params.Imagepath, common.Username, common.Password)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
ctx, _ = context.WithTimeout(ctx, timeout)
|
||||
err = cli.PullImage(ctx, params.Imagepath, params.Filepath)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
filestat, err := os.Stat(params.Filepath)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
res.Size = filestat.Size()
|
||||
res.Filepath = params.Filepath
|
||||
|
||||
return res, err
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
|
||||
*
|
||||
* This work is published and licensed under a Creative Commons
|
||||
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
|
||||
*
|
||||
* Distribution of this work is permitted, but commercial use and
|
||||
* modifications are strictly prohibited.
|
||||
*/
|
||||
package imagecmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"mstore/pkg/client"
|
||||
)
|
||||
|
||||
// PushImage
|
||||
type PushImageParams struct {
|
||||
Imagepath string
|
||||
Filepath string
|
||||
}
|
||||
|
||||
type PushImageResult struct{}
|
||||
|
||||
func (util *ImageUtil) PushImage(cmd *cobra.Command, args []string) {
|
||||
util.pushImageParams.Filepath = args[0]
|
||||
util.pushImageParams.Imagepath = args[1]
|
||||
|
||||
res, err := util.pushImage(&util.commonImageParams, &util.pushImageParams)
|
||||
printResponse(res, err)
|
||||
}
|
||||
|
||||
func (util *ImageUtil) pushImage(common *CommonImageParams, params *PushImageParams) (*PushImageResult, error) {
|
||||
var err error
|
||||
ctx := context.Background()
|
||||
res := &PushImageResult{}
|
||||
|
||||
cli := client.NewClient(common.SkipTLSVerify)
|
||||
timeout := time.Duration(common.Timeout) * time.Second
|
||||
params.Imagepath, err = packUserinfo(params.Imagepath, common.Username, common.Password)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
ctx, _ = context.WithTimeout(ctx, timeout)
|
||||
err = cli.PushImage(ctx, params.Filepath, params.Imagepath)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
@@ -16,7 +16,7 @@ func (cli *Client) DeleteCollection(ctx context.Context, rawpath string) ([]byte
|
||||
if err != nil {
|
||||
return list, err
|
||||
}
|
||||
uri := ref.Collection()
|
||||
uri := ref.CollectionEP()
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, uri, nil)
|
||||
if err != nil {
|
||||
return list, err
|
||||
|
||||
@@ -14,7 +14,7 @@ func (cli *Client) DeleteFile(ctx context.Context, rawpath string) (bool, error)
|
||||
if err != nil {
|
||||
return exist, err
|
||||
}
|
||||
uri := ref.File()
|
||||
uri := ref.FileEP()
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, uri, nil)
|
||||
if err != nil {
|
||||
return exist, err
|
||||
|
||||
@@ -17,7 +17,7 @@ func (cli *Client) FileInfo(ctx context.Context, rawpath string) (bool, int64, s
|
||||
if err != nil {
|
||||
return exist, size, digest, err
|
||||
}
|
||||
uri := ref.File()
|
||||
uri := ref.FileEP()
|
||||
|
||||
fmt.Println(uri)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodHead, uri, nil)
|
||||
|
||||
@@ -16,7 +16,7 @@ func (cli *Client) GetFile(ctx context.Context, rawpath string, writer io.Writer
|
||||
if err != nil {
|
||||
return exist, err
|
||||
}
|
||||
uri := ref.File()
|
||||
uri := ref.FileEP()
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -16,7 +16,7 @@ func (cli *Client) ListCollections(ctx context.Context, rawpath string) ([]byte,
|
||||
if err != nil {
|
||||
return list, err
|
||||
}
|
||||
uri := ref.Collections()
|
||||
uri := ref.CollectionsEP()
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -16,7 +16,7 @@ func (cli *Client) ListFiles(ctx context.Context, rawpath string) ([]byte, error
|
||||
if err != nil {
|
||||
return list, err
|
||||
}
|
||||
uri := ref.Files()
|
||||
uri := ref.FilesEP()
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -14,7 +14,7 @@ func (cli *Client) PutFile(ctx context.Context, rawpath string, src io.Reader, s
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
uri := ref.File()
|
||||
uri := ref.FileEP()
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPut, uri, src)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -68,22 +68,22 @@ func (repo *Referer) DryRun(yesno bool) {
|
||||
repo.values.Set("dryRun", strconv.FormatBool(yesno))
|
||||
}
|
||||
|
||||
func (repo *Referer) File() string {
|
||||
func (repo *Referer) FileEP() string {
|
||||
curl := repo.urlobj.JoinPath("/v3/api/file/", repo.resource)
|
||||
return curl.String()
|
||||
}
|
||||
|
||||
func (repo *Referer) Files() string {
|
||||
func (repo *Referer) FilesEP() string {
|
||||
curl := repo.urlobj.JoinPath("/v3/api/files/", repo.resource)
|
||||
return curl.String()
|
||||
}
|
||||
|
||||
func (repo *Referer) Collection() string {
|
||||
func (repo *Referer) CollectionEP() string {
|
||||
curl := repo.urlobj.JoinPath("/v3/api/collection/", repo.resource)
|
||||
return curl.String()
|
||||
}
|
||||
|
||||
func (repo *Referer) Collections() string {
|
||||
func (repo *Referer) CollectionsEP() string {
|
||||
curl := repo.urlobj.JoinPath("/v3/api/collections/", repo.resource)
|
||||
return curl.String()
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ func (cli *Client) BlobExists(ctx context.Context, rawrepo string, digest string
|
||||
if err != nil {
|
||||
return exist, size, err
|
||||
}
|
||||
uri := ref.Blob(digest)
|
||||
uri := ref.BlobEP(digest)
|
||||
|
||||
fmt.Println(uri)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodHead, uri, nil)
|
||||
|
||||
@@ -14,7 +14,7 @@ func xxxTestClientBlobExists(t *testing.T) {
|
||||
"mirror.gcr.io/alpine",
|
||||
}
|
||||
for _, rawrepo := range rawrepos {
|
||||
cli := NewClient()
|
||||
cli := NewClient(nil, nil)
|
||||
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
digstr := "sha256:3b8747b05489980f63da1d2b8e5a444c55777f69540394397b0bc1c76c3e41f2"
|
||||
exist, size, err := cli.BlobExists(ctx, rawrepo, digstr)
|
||||
|
||||
+9
-12
@@ -11,24 +11,19 @@ type Client struct {
|
||||
userAgent string
|
||||
}
|
||||
|
||||
func NewClient() *Client {
|
||||
defaultTripper := NewDefaultTransport()
|
||||
httpClient := &http.Client{
|
||||
Transport: defaultTripper,
|
||||
}
|
||||
return &Client{
|
||||
httpClient: httpClient,
|
||||
userAgent: "ociClient/1.0",
|
||||
}
|
||||
}
|
||||
|
||||
func NewClientWithTransport(transport http.RoundTripper, mwFunc ...MiddlewareFunc) *Client {
|
||||
func NewClient(transport http.RoundTripper, mwFuncs ...MiddlewareFunc) *Client {
|
||||
if transport == nil {
|
||||
transport = NewDefaultTransport()
|
||||
}
|
||||
for _, mwFunc := range mwFuncs {
|
||||
if mwFunc != nil {
|
||||
transport = mwFunc(transport)
|
||||
}
|
||||
}
|
||||
httpClient := &http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
|
||||
return &Client{
|
||||
httpClient: httpClient,
|
||||
userAgent: "ociClient/1.0",
|
||||
@@ -42,7 +37,9 @@ func (cli *Client) SetTransport(transport http.RoundTripper) {
|
||||
type MiddlewareFunc func(next http.RoundTripper) http.RoundTripper
|
||||
|
||||
func (cli *Client) UseMiddleware(mwFunc MiddlewareFunc) {
|
||||
if mwFunc != nil {
|
||||
cli.httpClient.Transport = mwFunc(cli.httpClient.Transport)
|
||||
}
|
||||
}
|
||||
|
||||
// ExampleMiddleware
|
||||
|
||||
@@ -14,7 +14,7 @@ func (cli *Client) DeleteBlob(ctx context.Context, rawrepo, digest string) (bool
|
||||
if err != nil {
|
||||
return exist, err
|
||||
}
|
||||
uri := ref.Blob(digest)
|
||||
uri := ref.BlobEP(digest)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, uri, nil)
|
||||
if err != nil {
|
||||
return exist, err
|
||||
|
||||
+12
-2
@@ -6,7 +6,17 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (cli *Client) DeleteManifest(ctx context.Context, rawrepo, tag string) (bool, error) {
|
||||
func (cli *Client) DeleteImage(ctx context.Context, rawrepo string) (bool, error) {
|
||||
var err error
|
||||
var exist bool
|
||||
ref, err := NewReferer(rawrepo)
|
||||
if err != nil {
|
||||
return exist, err
|
||||
}
|
||||
return cli.DeleteManifest(ctx, ref.ManifestEP())
|
||||
}
|
||||
|
||||
func (cli *Client) DeleteManifest(ctx context.Context, rawrepo string) (bool, error) {
|
||||
var err error
|
||||
var exist bool
|
||||
|
||||
@@ -14,7 +24,7 @@ func (cli *Client) DeleteManifest(ctx context.Context, rawrepo, tag string) (boo
|
||||
if err != nil {
|
||||
return exist, err
|
||||
}
|
||||
uri := ref.Manifest(tag)
|
||||
uri := ref.ManifestEP()
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, uri, nil)
|
||||
if err != nil {
|
||||
return exist, err
|
||||
|
||||
@@ -16,7 +16,7 @@ func (cli *Client) GetBlob(ctx context.Context, rawrepo string, writer io.Writer
|
||||
if err != nil {
|
||||
return exist, err
|
||||
}
|
||||
uri := ref.Blob(digest)
|
||||
uri := ref.BlobEP(digest)
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -15,7 +15,7 @@ func xxxTestClientGetBlob(t *testing.T) {
|
||||
"mirror.gcr.io/alpine",
|
||||
}
|
||||
for _, rawrepo := range rawrepos {
|
||||
cli := NewClient()
|
||||
cli := NewClient(nil, nil)
|
||||
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
digstr := "sha256:3b8747b05489980f63da1d2b8e5a444c55777f69540394397b0bc1c76c3e41f2"
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
func (cli *Client) GetCatalog(ctx context.Context, rawrepo string) ([]string, error) {
|
||||
var err error
|
||||
list := make([]string, 0)
|
||||
catdata, err := cli.getRawCatalog(ctx, rawrepo)
|
||||
catdata, err := cli.GetRawCatalog(ctx, rawrepo)
|
||||
if err != nil {
|
||||
return list, err
|
||||
}
|
||||
@@ -24,7 +24,7 @@ func (cli *Client) GetCatalog(ctx context.Context, rawrepo string) ([]string, er
|
||||
return list, err
|
||||
}
|
||||
|
||||
func (cli *Client) getRawCatalog(ctx context.Context, rawrepo string) ([]byte, error) {
|
||||
func (cli *Client) GetRawCatalog(ctx context.Context, rawrepo string) ([]byte, error) {
|
||||
var err error
|
||||
var list []byte
|
||||
|
||||
@@ -32,7 +32,7 @@ func (cli *Client) getRawCatalog(ctx context.Context, rawrepo string) ([]byte, e
|
||||
if err != nil {
|
||||
return list, err
|
||||
}
|
||||
uri := ref.Catalog()
|
||||
uri := ref.CatalogEP()
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -13,17 +13,18 @@ import (
|
||||
ocidigest "github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
func (cli *Client) GetManifest(ctx context.Context, rawrepo, tag string) (bool, string, []byte, error) {
|
||||
func (cli *Client) GetRawManifest(ctx context.Context, rawrepo string) (bool, string, []byte, error) {
|
||||
var err error
|
||||
var exist bool
|
||||
var mime string
|
||||
var man []byte
|
||||
|
||||
fmt.Printf("=== %s\n", rawrepo)
|
||||
ref, err := NewReferer(rawrepo)
|
||||
if err != nil {
|
||||
return exist, mime, man, err
|
||||
}
|
||||
uri := ref.Manifest(tag)
|
||||
uri := ref.ManifestEP()
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil)
|
||||
if err != nil {
|
||||
@@ -44,6 +45,11 @@ func (cli *Client) GetManifest(ctx context.Context, rawrepo, tag string) (bool,
|
||||
err := fmt.Errorf("Unxected response code %s", resp.Status)
|
||||
return exist, mime, man, err
|
||||
}
|
||||
digstr := resp.Header.Get("Docker-Content-Digest")
|
||||
if digstr == "" {
|
||||
err := fmt.Errorf("Empty digest declaration")
|
||||
return exist, mime, man, err
|
||||
}
|
||||
contentLength := resp.Header.Get("Content-Length")
|
||||
if contentLength == "" {
|
||||
err = errors.New("Empty Content-Length header")
|
||||
@@ -58,11 +64,6 @@ func (cli *Client) GetManifest(ctx context.Context, rawrepo, tag string) (bool,
|
||||
err := fmt.Errorf("Empty MIME type declaration")
|
||||
return exist, mime, man, err
|
||||
}
|
||||
digstr := resp.Header.Get("Docker-Content-Digest")
|
||||
if digstr == "" {
|
||||
err := fmt.Errorf("Empty digest declaration")
|
||||
return exist, mime, man, err
|
||||
}
|
||||
digstr = strings.ToLower(digstr)
|
||||
digobj, err := ocidigest.Parse(digstr)
|
||||
if err != nil {
|
||||
|
||||
@@ -18,9 +18,9 @@ func xxxTestClientGetManifest(t *testing.T) {
|
||||
"sha256:29e5ba63e79337818e6c63cfcc68e2ab4e9ca483853b2de303bfbfba9372426c",
|
||||
}
|
||||
for _, tag := range tags {
|
||||
cli := NewClient()
|
||||
cli := NewClient(nil, nil)
|
||||
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
exist, mime, man, err := cli.GetManifest(ctx, rawrepo, tag)
|
||||
exist, mime, man, err := cli.GetRawManifest(ctx, rawrepo+":"+tag)
|
||||
require.NoError(t, err)
|
||||
require.True(t, exist)
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
func (cli *Client) GetReferers(ctx context.Context, rawrepo, digest string) ([]string, error) {
|
||||
var err error
|
||||
list := make([]string, 0)
|
||||
tagdata, err := cli.getRawReferers(ctx, rawrepo, digest)
|
||||
tagdata, err := cli.GetRawReferers(ctx, rawrepo, digest)
|
||||
if err != nil {
|
||||
return list, err
|
||||
}
|
||||
@@ -24,7 +24,7 @@ func (cli *Client) GetReferers(ctx context.Context, rawrepo, digest string) ([]s
|
||||
return list, err
|
||||
}
|
||||
|
||||
func (cli *Client) getRawReferers(ctx context.Context, rawrepo, digest string) ([]byte, error) {
|
||||
func (cli *Client) GetRawReferers(ctx context.Context, rawrepo, digest string) ([]byte, error) {
|
||||
var err error
|
||||
var list []byte
|
||||
|
||||
@@ -32,7 +32,7 @@ func (cli *Client) getRawReferers(ctx context.Context, rawrepo, digest string) (
|
||||
if err != nil {
|
||||
return list, err
|
||||
}
|
||||
uri := ref.Referers(digest)
|
||||
uri := ref.ReferersEP(digest)
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
func (cli *Client) GetTags(ctx context.Context, rawrepo string) ([]string, error) {
|
||||
var err error
|
||||
list := make([]string, 0)
|
||||
tagdata, err := cli.getRawTags(ctx, rawrepo)
|
||||
tagdata, err := cli.GetRawTags(ctx, rawrepo)
|
||||
if err != nil {
|
||||
return list, err
|
||||
}
|
||||
@@ -24,7 +24,7 @@ func (cli *Client) GetTags(ctx context.Context, rawrepo string) ([]string, error
|
||||
return list, err
|
||||
}
|
||||
|
||||
func (cli *Client) getRawTags(ctx context.Context, rawrepo string) ([]byte, error) {
|
||||
func (cli *Client) GetRawTags(ctx context.Context, rawrepo string) ([]byte, error) {
|
||||
var err error
|
||||
var list []byte
|
||||
|
||||
@@ -32,7 +32,7 @@ func (cli *Client) getRawTags(ctx context.Context, rawrepo string) ([]byte, erro
|
||||
if err != nil {
|
||||
return list, err
|
||||
}
|
||||
uri := ref.Tags()
|
||||
uri := ref.TagsEP()
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -9,12 +9,12 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func xxxxTestClientGetToken(t *testing.T) {
|
||||
func xxxTestClientGetToken(t *testing.T) {
|
||||
var token string
|
||||
var err error
|
||||
{
|
||||
cli := NewClient()
|
||||
cli.UseMiddleware(NewBasicAuthMiddleware("xxxxxxx", "xxxxxxxxxx"))
|
||||
cli := NewClient(nil, nil)
|
||||
//cli.UseMiddleware(NewBasicAuthMiddleware("xxxxxxx", "xxxxxxxxxx"))
|
||||
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
token, err = cli.GetToken(ctx, "https://auth.docker.io/token")
|
||||
require.NoError(t, err)
|
||||
@@ -23,11 +23,12 @@ func xxxxTestClientGetToken(t *testing.T) {
|
||||
fmt.Printf("Token: %s\n", token)
|
||||
{
|
||||
rawrepo := "docker.io/onborodin/toolbox:0.18"
|
||||
cli := NewClient()
|
||||
cli.UseMiddleware(NewBearerAuthMiddleware(token))
|
||||
cli := NewClient(nil, nil)
|
||||
//cli.UseMiddleware(NewBearerAuthMiddleware(token))
|
||||
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
loc, err := cli.GetUpload(ctx, rawrepo)
|
||||
id, loc, err := cli.GetUpload(ctx, rawrepo)
|
||||
require.NoError(t, err)
|
||||
fmt.Printf("Upload ID: %s\n", id)
|
||||
fmt.Printf("Upload Location: %s\n", loc)
|
||||
}
|
||||
|
||||
|
||||
@@ -6,37 +6,42 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (cli *Client) GetUpload(ctx context.Context, rawrepo string) (string, error) {
|
||||
func (cli *Client) GetUpload(ctx context.Context, rawrepo string) (string, string, error) {
|
||||
var err error
|
||||
var loc string
|
||||
var id string
|
||||
|
||||
ref, err := NewReferer(rawrepo)
|
||||
if err != nil {
|
||||
return loc, err
|
||||
return id, loc, err
|
||||
}
|
||||
uri := ref.Upload()
|
||||
uri := ref.UploadEP()
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, uri, nil)
|
||||
if err != nil {
|
||||
return loc, err
|
||||
return id, loc, err
|
||||
}
|
||||
req.Header.Set("User-Agent", cli.userAgent)
|
||||
req.Header.Set("Accept", "*/*")
|
||||
resp, err := cli.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return loc, err
|
||||
return id, loc, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusAccepted {
|
||||
err := fmt.Errorf("Unxected response code %s", resp.Status)
|
||||
return loc, err
|
||||
return id, loc, err
|
||||
}
|
||||
loc = resp.Header.Get("Location")
|
||||
|
||||
if loc == "" {
|
||||
err := fmt.Errorf("Empty location declaration")
|
||||
return loc, err
|
||||
return id, loc, err
|
||||
}
|
||||
return loc, err
|
||||
id = resp.Header.Get("Docker-Upload-UUID")
|
||||
if id == "" {
|
||||
err := fmt.Errorf("Empty Docker-Upload-UUID declaration")
|
||||
return id, loc, err
|
||||
}
|
||||
return id, loc, err
|
||||
}
|
||||
|
||||
@@ -15,19 +15,20 @@ import (
|
||||
|
||||
func xxxTestClientGetUpload(t *testing.T) {
|
||||
rawrepos := []string{
|
||||
"mstore:mstore@localhost:1025/alpine:3.20.0",
|
||||
"localhost:1025/alpine:3.20.0",
|
||||
}
|
||||
cli := NewClient()
|
||||
cli.UseMiddleware(NewBasicAuthMiddleware("mstore", "mstore"))
|
||||
mw := NewBasicAuthMiddleware("mstore", "mstore")
|
||||
cli := NewClient(nil, mw)
|
||||
|
||||
for _, rawrepo := range rawrepos {
|
||||
var err error
|
||||
var loc string
|
||||
{
|
||||
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
loc, err = cli.GetUpload(ctx, rawrepo)
|
||||
id, loc, err := cli.GetUpload(ctx, rawrepo)
|
||||
require.NoError(t, err)
|
||||
fmt.Printf("Upload Location: %s\n", loc)
|
||||
fmt.Printf("Upload ID: %s\n", id)
|
||||
}
|
||||
{
|
||||
srcsize := 1024 + 145
|
||||
|
||||
@@ -85,6 +85,10 @@ func NewImagerFromPlace(place string) (*Imager, error) {
|
||||
return imager, err
|
||||
}
|
||||
|
||||
func (ima *Imager) Index() *ocispec.Index {
|
||||
return &ima.index
|
||||
}
|
||||
|
||||
func (ima *Imager) ReadManifest(ctx context.Context, digstr string) (bool, string, []byte, error) {
|
||||
var exist bool
|
||||
var mime string
|
||||
@@ -181,6 +185,28 @@ func (ima *Imager) writeManifest(ctx context.Context, digest, mime string, paylo
|
||||
return err
|
||||
}
|
||||
|
||||
func (ima *Imager) readIndex(ctx context.Context) (*ocispec.Index, error) {
|
||||
// Read index
|
||||
var err error
|
||||
res := &ocispec.Index{}
|
||||
ipath := filepath.Join(ima.place, ocispec.ImageIndexFile)
|
||||
ifile, err := os.OpenFile(ipath, os.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
defer ifile.Close()
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
_, err = io.Copy(buffer, buffer)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
err = json.Unmarshal(buffer.Bytes(), res)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (ima *Imager) writeIndex(ctx context.Context) error {
|
||||
indexdat, err := json.Marshal(ima.index)
|
||||
if err != nil {
|
||||
@@ -293,3 +319,26 @@ func (ima *Imager) ReadLayer(ctx context.Context, digstr string, writer io.Write
|
||||
exist = true
|
||||
return exist, err
|
||||
}
|
||||
|
||||
func (ima *Imager) LayerReader(ctx context.Context, digstr string) (int64, io.ReadCloser, error) {
|
||||
var reader io.ReadCloser
|
||||
var err error
|
||||
var size int64
|
||||
digobj, err := ocidigest.Parse(digstr)
|
||||
if err != nil {
|
||||
return size, reader, err
|
||||
}
|
||||
subdir := string(digobj.Algorithm())
|
||||
mpath := filepath.Join(ima.place, ocispec.ImageBlobsDir, subdir, digobj.Encoded())
|
||||
stat, err := os.Stat(mpath)
|
||||
if err != nil {
|
||||
return size, reader, err
|
||||
}
|
||||
size = stat.Size()
|
||||
mfile, err := os.OpenFile(mpath, os.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
return size, reader, err
|
||||
}
|
||||
reader = mfile
|
||||
return size, reader, err
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func (cli *Client) ManifestExists(ctx context.Context, rawrepo, tag string) (bool, string, int64, string, error) {
|
||||
func (cli *Client) ManifestExists(ctx context.Context, rawrepo string) (bool, string, int64, string, error) {
|
||||
var err error
|
||||
var exist bool
|
||||
var mime string
|
||||
@@ -18,7 +18,7 @@ func (cli *Client) ManifestExists(ctx context.Context, rawrepo, tag string) (boo
|
||||
if err != nil {
|
||||
return exist, mime, size, csum, err
|
||||
}
|
||||
uri := ref.Manifest(tag)
|
||||
uri := ref.ManifestEP()
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodHead, uri, nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -17,9 +17,9 @@ func xxxTestClientManifestExists(t *testing.T) {
|
||||
}
|
||||
for _, tag := range tags {
|
||||
|
||||
cli := NewClient()
|
||||
cli := NewClient(nil, nil)
|
||||
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
exist, mime, size, csum, err := cli.ManifestExists(ctx, rawrepo, tag)
|
||||
exist, mime, size, csum, err := cli.ManifestExists(ctx, rawrepo+":"+tag)
|
||||
require.NoError(t, err)
|
||||
require.True(t, exist)
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ func (cli *Client) PatchUpload(ctx context.Context, rawrepo string, src io.Reade
|
||||
if err != nil {
|
||||
return ouloc, err
|
||||
}
|
||||
uri, err := ref.Patch(uploc)
|
||||
uri, err := ref.PatchEP(uploc)
|
||||
if err != nil {
|
||||
return ouloc, err
|
||||
}
|
||||
|
||||
@@ -18,26 +18,26 @@ const (
|
||||
MediaTypeOIMv1 = "application/vnd.oci.image.manifest.v1+json"
|
||||
)
|
||||
|
||||
type Downloader struct {
|
||||
type Loader struct {
|
||||
cli *Client
|
||||
}
|
||||
|
||||
func NewDownloader(client *Client) *Downloader {
|
||||
return &Downloader{
|
||||
func NewLoader(client *Client) *Loader {
|
||||
return &Loader{
|
||||
cli: client,
|
||||
}
|
||||
}
|
||||
|
||||
func (down *Downloader) Pull(ctx context.Context, rawref, dir, osname, arch string) error {
|
||||
func (down *Loader) Pull(ctx context.Context, rawref, dir, osname, arch string) error {
|
||||
var err error
|
||||
ref, err := ParseReference(rawref)
|
||||
ref, err := NewReferer(rawref)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rawrepo := ref.Repo()
|
||||
rawrepo := ref.RawRepo()
|
||||
tag := ref.Tag()
|
||||
|
||||
exist, mime, man, err := down.cli.GetManifest(ctx, rawrepo, tag)
|
||||
exist, mime, man, err := down.cli.GetRawManifest(ctx, ref.Raw())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -64,8 +64,12 @@ func (down *Downloader) Pull(ctx context.Context, rawref, dir, osname, arch stri
|
||||
}
|
||||
}
|
||||
}
|
||||
if digstr == "" {
|
||||
err = errors.New("Manifest for required arch and OS not found")
|
||||
return err
|
||||
}
|
||||
fmt.Printf("Tag: %s\n", tag)
|
||||
exist, mime, man, err = down.cli.GetManifest(ctx, rawrepo, tag)
|
||||
exist, mime, man, err = down.cli.GetRawManifest(ctx, ref.RawWithTag(digstr))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -12,10 +12,10 @@ import (
|
||||
func TestPullImage(t *testing.T) {
|
||||
|
||||
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
cli := NewClientWithTransport(nil, nil)
|
||||
cli := NewClient(nil, nil)
|
||||
require.NotNil(t, cli)
|
||||
|
||||
down := NewDownloader(cli)
|
||||
down := NewLoader(cli)
|
||||
require.NotNil(t, down)
|
||||
|
||||
rawref := "mirror.gcr.io/alpine:3.20.0"
|
||||
|
||||
@@ -16,7 +16,7 @@ func (cli *Client) PutManifest(ctx context.Context, rawrepo, tag string, man []b
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
uri := ref.Manifest(tag)
|
||||
uri := ref.ManifestEP()
|
||||
|
||||
buffer := bytes.NewBuffer(man)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPut, uri, buffer)
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func (cli *Client) PutUpload(ctx context.Context, rawrepo string, src io.Reader, uploc, digest string, size int64) (string, error) {
|
||||
func (cli *Client) PutUpload(ctx context.Context, rawrepo string, src io.Reader, id, digest string, size int64) (string, error) {
|
||||
var err error
|
||||
var bloc string
|
||||
|
||||
@@ -16,7 +16,7 @@ func (cli *Client) PutUpload(ctx context.Context, rawrepo string, src io.Reader,
|
||||
if err != nil {
|
||||
return bloc, err
|
||||
}
|
||||
uri, err := ref.Put(uploc, digest)
|
||||
uri, err := ref.PutEP(id, digest)
|
||||
if err != nil {
|
||||
return bloc, err
|
||||
}
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
package repocli
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Reference struct {
|
||||
urlobj *url.URL
|
||||
user, pass string
|
||||
base, tag string
|
||||
}
|
||||
|
||||
func ParseReference(rawref string) (*Reference, error) {
|
||||
ref := &Reference{}
|
||||
if !strings.Contains(rawref, "://") {
|
||||
rawref = "https://" + rawref
|
||||
}
|
||||
urlobj, err := url.Parse(rawref)
|
||||
if err != nil {
|
||||
return ref, err
|
||||
}
|
||||
if urlobj.User != nil {
|
||||
ref.user = urlobj.User.Username()
|
||||
ref.pass, _ = urlobj.User.Password()
|
||||
urlobj.User = nil
|
||||
}
|
||||
ref.urlobj = urlobj
|
||||
|
||||
repotag := strings.SplitN(ref.urlobj.Path, ":", 2)
|
||||
if len(repotag) != 2 {
|
||||
err = errors.New("Incorrect reference format")
|
||||
return ref, err
|
||||
}
|
||||
ref.base = repotag[0]
|
||||
ref.tag = repotag[1]
|
||||
|
||||
ref.urlobj.Path = "/"
|
||||
ref.urlobj = urlobj
|
||||
|
||||
return ref, err
|
||||
}
|
||||
|
||||
func (ref *Reference) String() string {
|
||||
return path.Join(ref.urlobj.Host, ref.base+":"+ref.tag)
|
||||
}
|
||||
|
||||
func (ref *Reference) Repo() string {
|
||||
return path.Join(ref.urlobj.Host, ref.base)
|
||||
}
|
||||
|
||||
func (ref *Reference) Tag() string {
|
||||
return ref.tag
|
||||
}
|
||||
|
||||
func (ref *Reference) Userinfo() (string, string) {
|
||||
return ref.user, ref.pass
|
||||
}
|
||||
+60
-39
@@ -2,63 +2,84 @@ package repocli
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Referer struct {
|
||||
urlobj *url.URL
|
||||
user, pass string
|
||||
base string
|
||||
base, tag string
|
||||
}
|
||||
|
||||
func NewReferer(rawrepo string) (*Referer, error) {
|
||||
repo := &Referer{}
|
||||
if !strings.Contains(rawrepo, "://") {
|
||||
rawrepo = "https://" + rawrepo
|
||||
func NewReferer(rawref string) (*Referer, error) {
|
||||
ref := &Referer{}
|
||||
if !strings.Contains(rawref, "://") {
|
||||
rawref = "https://" + rawref
|
||||
}
|
||||
urlobj, err := url.Parse(rawrepo)
|
||||
urlobj, err := url.Parse(rawref)
|
||||
if err != nil {
|
||||
return repo, err
|
||||
return ref, err
|
||||
}
|
||||
if urlobj.User != nil {
|
||||
repo.user = urlobj.User.Username()
|
||||
repo.pass, _ = urlobj.User.Password()
|
||||
ref.user = urlobj.User.Username()
|
||||
ref.pass, _ = urlobj.User.Password()
|
||||
urlobj.User = nil
|
||||
}
|
||||
repo.urlobj = urlobj
|
||||
repo.base = repo.urlobj.Path
|
||||
repo.urlobj.Path = "/"
|
||||
repo.urlobj = urlobj
|
||||
ref.urlobj = urlobj
|
||||
if strings.Contains(ref.urlobj.Path, ":") {
|
||||
m := strings.SplitN(ref.urlobj.Path, ":", 2)
|
||||
ref.base = m[0]
|
||||
ref.tag = m[1]
|
||||
} else {
|
||||
ref.base = ref.urlobj.Path
|
||||
}
|
||||
ref.urlobj.Path = "/"
|
||||
ref.urlobj = urlobj
|
||||
|
||||
return repo, err
|
||||
return ref, err
|
||||
}
|
||||
|
||||
func (repo *Referer) String() string {
|
||||
curl := repo.urlobj.JoinPath(repo.base)
|
||||
func (ref *Referer) RawWithTag(tag string) string {
|
||||
return path.Join(ref.urlobj.Host, ref.base+":"+tag)
|
||||
}
|
||||
|
||||
func (ref *Referer) Raw() string {
|
||||
if ref.tag != "" {
|
||||
return path.Join(ref.urlobj.Host, ref.base+":"+ref.tag)
|
||||
}
|
||||
return path.Join(ref.urlobj.Host, ref.base)
|
||||
}
|
||||
|
||||
func (ref *Referer) RawRepo() string {
|
||||
return path.Join(ref.urlobj.Host, ref.base)
|
||||
}
|
||||
|
||||
func (ref *Referer) Tag() string {
|
||||
return ref.tag
|
||||
}
|
||||
|
||||
func (ref *Referer) ManifestEP() string {
|
||||
curl := ref.urlobj.JoinPath("/v2", ref.base, "/manifests", ref.tag)
|
||||
return curl.String()
|
||||
}
|
||||
|
||||
func (repo *Referer) Manifest(tag string) string {
|
||||
curl := repo.urlobj.JoinPath("/v2", repo.base, "/manifests", tag)
|
||||
func (ref *Referer) BlobEP(digest string) string {
|
||||
curl := ref.urlobj.JoinPath("/v2", ref.base, "/blobs", digest)
|
||||
return curl.String()
|
||||
}
|
||||
|
||||
func (repo *Referer) Blob(digest string) string {
|
||||
curl := repo.urlobj.JoinPath("/v2", repo.base, "/blobs", digest)
|
||||
func (ref *Referer) UploadEP() string {
|
||||
curl := ref.urlobj.JoinPath("/v2", ref.base, "/blobs/uploads/")
|
||||
return curl.String()
|
||||
}
|
||||
|
||||
func (repo *Referer) Upload() string {
|
||||
curl := repo.urlobj.JoinPath("/v2", repo.base, "/blobs/uploads/")
|
||||
return curl.String()
|
||||
}
|
||||
|
||||
func (repo *Referer) Patch(loc string) (string, error) {
|
||||
func (ref *Referer) PatchEP(loc string) (string, error) {
|
||||
var curl *url.URL
|
||||
var out string
|
||||
var err error
|
||||
if isUUID(loc) {
|
||||
curl = repo.urlobj.JoinPath("/v2/", repo.base, "/blobs/uploads/", loc)
|
||||
curl = ref.urlobj.JoinPath("/v2/", ref.base, "/blobs/uploads/", loc)
|
||||
return curl.String(), nil
|
||||
}
|
||||
if strings.Contains(loc, "://") {
|
||||
@@ -67,26 +88,26 @@ func (repo *Referer) Patch(loc string) (string, error) {
|
||||
return out, err
|
||||
}
|
||||
} else {
|
||||
curl = repo.urlobj.JoinPath(loc)
|
||||
curl = ref.urlobj.JoinPath(loc)
|
||||
}
|
||||
out = curl.String()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (repo *Referer) Put(loc, digest string) (string, error) {
|
||||
func (ref *Referer) PutEP(loc, digest string) (string, error) {
|
||||
var curl *url.URL
|
||||
var out string
|
||||
var err error
|
||||
|
||||
if isUUID(loc) {
|
||||
curl = repo.urlobj.JoinPath("/v2/", repo.base, "/blobs/uploads/", loc)
|
||||
curl = ref.urlobj.JoinPath("/v2/", ref.base, "/blobs/uploads/", loc)
|
||||
} else if strings.Contains(loc, "://") {
|
||||
curl, err = url.Parse(loc)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
} else {
|
||||
curl = repo.urlobj.JoinPath(loc)
|
||||
curl = ref.urlobj.JoinPath(loc)
|
||||
}
|
||||
query := curl.Query()
|
||||
query.Set("digest", digest)
|
||||
@@ -95,21 +116,21 @@ func (repo *Referer) Put(loc, digest string) (string, error) {
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (repo *Referer) Tags() string {
|
||||
curl := repo.urlobj.JoinPath("/v2", repo.base, "/tags/list")
|
||||
func (ref *Referer) TagsEP() string {
|
||||
curl := ref.urlobj.JoinPath("/v2", ref.base, "/tags/list")
|
||||
return curl.String()
|
||||
}
|
||||
|
||||
func (repo *Referer) Referers(digest string) string {
|
||||
curl := repo.urlobj.JoinPath("/v2", repo.base, "/referrers/", digest)
|
||||
func (ref *Referer) ReferersEP(digest string) string {
|
||||
curl := ref.urlobj.JoinPath("/v2", ref.base, "/referers/", digest)
|
||||
return curl.String()
|
||||
}
|
||||
|
||||
func (repo *Referer) Catalog() string {
|
||||
curl := repo.urlobj.JoinPath("/v2/_catalog")
|
||||
func (ref *Referer) CatalogEP() string {
|
||||
curl := ref.urlobj.JoinPath("/v2/_catalog")
|
||||
return curl.String()
|
||||
}
|
||||
|
||||
func (repo *Referer) Userinfo() (string, string) {
|
||||
return repo.user, repo.pass
|
||||
func (ref *Referer) Userinfo() (string, string) {
|
||||
return ref.user, ref.pass
|
||||
}
|
||||
|
||||
@@ -10,18 +10,18 @@ import (
|
||||
)
|
||||
|
||||
func xxxTestResrerer(t *testing.T) {
|
||||
ref, err := NewReferer("registry.example.com/lib/alpine")
|
||||
ref, err := NewReferer("registry.example.com/lib/alpine:3.30.0")
|
||||
require.NoError(t, err)
|
||||
|
||||
fmt.Printf("Manifest:\t%s\n", ref.Manifest("3.30.0"))
|
||||
fmt.Printf("Manifest:\t%s\n", ref.ManifestEP())
|
||||
|
||||
digobj := digest.NewDigest(digest.SHA256, []byte("qwerty"))
|
||||
fmt.Printf("Blob:\t\t%s\n", ref.Blob(digobj.Encoded()))
|
||||
fmt.Printf("POST:\t\t%s\n", ref.Upload())
|
||||
fmt.Printf("Blob:\t\t%s\n", ref.BlobEP(digobj.Encoded()))
|
||||
fmt.Printf("POST:\t\t%s\n", ref.UploadEP())
|
||||
uuid := "8be4df61-93ca-11d2-aa0d-00e098032b8c"
|
||||
rawurl, err := ref.Patch(uuid)
|
||||
rawurl, err := ref.PatchEP(uuid)
|
||||
require.NoError(t, err)
|
||||
fmt.Printf("PATH:\t\t%s\n", rawurl)
|
||||
rawurl, err = ref.Put(uuid, digobj.Encoded())
|
||||
rawurl, err = ref.PutEP(uuid, digobj.Encoded())
|
||||
fmt.Printf("PUT:\t\t%s\n", rawurl)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user