working commit

This commit is contained in:
2026-03-16 20:55:36 +02:00
parent 5c1da77f4c
commit 13b1905e05
31 changed files with 177 additions and 151 deletions
+3 -3
View File
@@ -41,8 +41,8 @@ EXTRA_mstorectl_SOURCES = \
cmd/mstorectl/imagecmd/imagetags.go \ cmd/mstorectl/imagecmd/imagetags.go \
cmd/mstorectl/imagecmd/printresp.go \ cmd/mstorectl/imagecmd/printresp.go \
cmd/mstorectl/imagecmd/gcrimageconf.go \ cmd/mstorectl/imagecmd/gcrimageconf.go \
cmd/mstorectl/imagecmd/gcrpullimage.go \ cmd/mstorectl/imagecmd/pullimage.go \
cmd/mstorectl/imagecmd/gcrpushimage.go cmd/mstorectl/imagecmd/pushimage.go
mstored_SOURCES = cmd/mstored/main.go mstored_SOURCES = cmd/mstored/main.go
@@ -55,7 +55,7 @@ mstored$(EXEEXT): $(mstored_SOURCES) $(EXTRA_mstored_SOURCES)
env CGO_ENABLED=1 $(GO) build $(GOFLAGS) -o mstored$(EXEEXT) $(mstored_SOURCES) env CGO_ENABLED=1 $(GO) build $(GOFLAGS) -o mstored$(EXEEXT) $(mstored_SOURCES)
run: $(mstored_SOURCES) run: $(mstored_SOURCES)
cd cmd/mstored && env CGO_ENABLED=1 $(GO) run . --asDaemon=false cd cmd/mstored && env CGO_ENABLED=1 $(GO) run . --asDaemon=false --port=443
CWD=$(shell pwd) CWD=$(shell pwd)
+3 -3
View File
@@ -387,8 +387,8 @@ EXTRA_mstorectl_SOURCES = \
cmd/mstorectl/imagecmd/imagetags.go \ cmd/mstorectl/imagecmd/imagetags.go \
cmd/mstorectl/imagecmd/printresp.go \ cmd/mstorectl/imagecmd/printresp.go \
cmd/mstorectl/imagecmd/gcrimageconf.go \ cmd/mstorectl/imagecmd/gcrimageconf.go \
cmd/mstorectl/imagecmd/gcrpullimage.go \ cmd/mstorectl/imagecmd/pullimage.go \
cmd/mstorectl/imagecmd/gcrpushimage.go cmd/mstorectl/imagecmd/pushimage.go
mstored_SOURCES = cmd/mstored/main.go mstored_SOURCES = cmd/mstored/main.go
EXTRA_mstored_SOURCES = cmd/mstored/starter/starter.go \ EXTRA_mstored_SOURCES = cmd/mstored/starter/starter.go \
@@ -1130,7 +1130,7 @@ mstored$(EXEEXT): $(mstored_SOURCES) $(EXTRA_mstored_SOURCES)
env CGO_ENABLED=1 $(GO) build $(GOFLAGS) -o mstored$(EXEEXT) $(mstored_SOURCES) env CGO_ENABLED=1 $(GO) build $(GOFLAGS) -o mstored$(EXEEXT) $(mstored_SOURCES)
run: $(mstored_SOURCES) run: $(mstored_SOURCES)
cd cmd/mstored && env CGO_ENABLED=1 $(GO) run . --asDaemon=false cd cmd/mstored && env CGO_ENABLED=1 $(GO) run . --asDaemon=false --port=443
\ \
docs/helm-chart-manifest.json.txt \ docs/helm-chart-manifest.json.txt \
docs/mstore.drawio \ docs/mstore.drawio \
-1
View File
@@ -77,7 +77,6 @@ func (oper *Operator) CreateGrant(ctx context.Context, operatorID string, params
err := fmt.Errorf("Grant with this right already exists") err := fmt.Errorf("Grant with this right already exists")
return res, err return res, err
} }
oper.logg.Debugf("Call CreateGrant")
now := auxtool.TimeNow() now := auxtool.TimeNow()
grantDescr := &descr.Grant{ grantDescr := &descr.Grant{
ID: auxuuid.NewUUID(), ID: auxuuid.NewUUID(),
+1 -1
View File
@@ -52,7 +52,7 @@ func NewConfig() *Config {
logfile := fmt.Sprintf("%s.log", srvname) logfile := fmt.Sprintf("%s.log", srvname)
logpath := filepath.Join(logdir, logfile) logpath := filepath.Join(logdir, logfile)
runfile := fmt.Sprintf("%s.run", srvname) runfile := fmt.Sprintf("%s.pid", srvname)
runpath := filepath.Join(rundir, runfile) runpath := filepath.Join(rundir, runfile)
//certpath := fmt.Sprintf("%s.crt", srvname) //certpath := fmt.Sprintf("%s.crt", srvname)
+4 -4
View File
@@ -1,10 +1,10 @@
package config package config
const ( const (
confdir = "/home/ziggi/Projects/mstore/etc/mstore" confdir = "/etc/mstore"
rundir = "/home/ziggi/Projects/mstore/tmp/run" rundir = "/var/run/mstore"
logdir = "/home/ziggi/Projects/mstore/tmp/log" logdir = "/var/log/mstore"
datadir = "/home/ziggi/Projects/mstore/tmp/data" datadir = "/var/lib/mstore"
version = "0.2.0" version = "0.2.0"
srvname = "mstored" srvname = "mstored"
) )
-1
View File
@@ -92,7 +92,6 @@ func (oper *Operator) GetFile(ctx context.Context, operatorID string, params *Ge
for _, descr := range fileDescrs { for _, descr := range fileDescrs {
if descr.Type == hcMediaType { if descr.Type == hcMediaType {
meta := &chart.Metadata{} meta := &chart.Metadata{}
oper.logg.Debugf("=== %s", descr.HelmMeta)
err = json.Unmarshal([]byte(descr.HelmMeta), meta) err = json.Unmarshal([]byte(descr.HelmMeta), meta)
if err != nil { if err != nil {
code := http.StatusInternalServerError code := http.StatusInternalServerError
+1 -1
View File
@@ -54,7 +54,7 @@ func (hand *Handler) CheckAccess(rctx *router.Context) (bool, string, error) {
//hand.logg.Debugf("URL: %s", rctx.URL().String()) //hand.logg.Debugf("URL: %s", rctx.URL().String())
authHeader := rctx.GetHeader("Authorization") authHeader := rctx.GetHeader("Authorization")
hand.logg.Debugf("Authorization: %s", authHeader) hand.logg.Debugf("Authorization: [%s]", authHeader)
if authHeader != "" { if authHeader != "" {
username, password, err = auxhttp.ParseBasicAuth(authHeader) username, password, err = auxhttp.ParseBasicAuth(authHeader)
if err != nil { if err != nil {
-2
View File
@@ -25,7 +25,6 @@ func (hand *Handler) BlobExists(rctx *router.Context) {
digest, _ := rctx.GetSubpath("digest") digest, _ := rctx.GetSubpath("digest")
//hand.DumpHeaders("BlobExists", rctx) //hand.DumpHeaders("BlobExists", rctx)
params := &imageoper.BlobExistsParams{ params := &imageoper.BlobExistsParams{
Name: name, Name: name,
Digest: digest, Digest: digest,
@@ -63,7 +62,6 @@ func (hand *Handler) PostUpload(rctx *router.Context) {
name, _ := rctx.GetSubpath("name") name, _ := rctx.GetSubpath("name")
//hand.DumpHeaders("PostUploads", rctx) //hand.DumpHeaders("PostUploads", rctx)
authorization := rctx.GetHeader("Authorization") authorization := rctx.GetHeader("Authorization")
if authorization == "" { if authorization == "" {
rctx.SetHeader("WWW-Authenticate", `Basic realm="mstore"`) rctx.SetHeader("WWW-Authenticate", `Basic realm="mstore"`)
+1 -2
View File
@@ -24,7 +24,6 @@ type BlobExistsResult struct {
DockerContentDigest string DockerContentDigest string
ContentLength string ContentLength string
ContentType string ContentType string
//Exists bool
} }
func (oper *Operator) BlobExists(ctx context.Context, operatorID string, params *BlobExistsParams) (*BlobExistsResult, int, error) { func (oper *Operator) BlobExists(ctx context.Context, operatorID string, params *BlobExistsParams) (*BlobExistsResult, int, error) {
@@ -45,7 +44,7 @@ func (oper *Operator) BlobExists(ctx context.Context, operatorID string, params
defer oper.iLock.Done(resName) defer oper.iLock.Done(resName)
// Check blob descriptor // Check blob descriptor
descrExists, blobDescr, err := oper.mdb.GetBlobByNameDigest(ctx, params.Digest, params.Digest) descrExists, blobDescr, err := oper.mdb.GetBlobByNameDigest(ctx, params.Name, params.Digest)
if err != nil { if err != nil {
return res, http.StatusInternalServerError, err return res, http.StatusInternalServerError, err
} }
+5 -3
View File
@@ -50,8 +50,8 @@ func (oper *Operator) GetManifest(ctx context.Context, params *GetManifestParams
manDescr := descr.Manifest{} manDescr := descr.Manifest{}
var exists bool var exists bool
digobj, err := ocidigest.Parse(params.Reference) digobj, parseErr := ocidigest.Parse(params.Reference)
if err == nil { if parseErr == nil {
exists, manDescr, err = oper.mdb.GetManifestByDigest(ctx, params.Name, digobj.String()) exists, manDescr, err = oper.mdb.GetManifestByDigest(ctx, params.Name, digobj.String())
if err != nil { if err != nil {
return res, http.StatusInternalServerError, err return res, http.StatusInternalServerError, err
@@ -75,6 +75,7 @@ func (oper *Operator) GetManifest(ctx context.Context, params *GetManifestParams
return res, http.StatusNotFound, err return res, http.StatusNotFound, err
} }
if len(manDescrs) == 1 { if len(manDescrs) == 1 {
manDescr = manDescrs[0]
res.DockerContentDigest = manDescr.Digest res.DockerContentDigest = manDescr.Digest
size := int64(len(manDescr.Payload)) size := int64(len(manDescr.Payload))
res.ContentLength = strconv.FormatInt(size, 10) res.ContentLength = strconv.FormatInt(size, 10)
@@ -85,8 +86,9 @@ func (oper *Operator) GetManifest(ctx context.Context, params *GetManifestParams
if err != nil { if err != nil {
return res, http.StatusInternalServerError, err return res, http.StatusInternalServerError, err
} }
digobj := ocidigest.SHA256.FromBytes(indexdata) digobj := ocidigest.FromBytes(indexdata)
res.DockerContentDigest = digobj.String() res.DockerContentDigest = digobj.String()
size := int64(len(indexdata)) size := int64(len(indexdata))
res.ContentLength = strconv.FormatInt(size, 10) res.ContentLength = strconv.FormatInt(size, 10)
res.ContentType = oiiMediaType res.ContentType = oiiMediaType
+3 -4
View File
@@ -15,7 +15,6 @@ import (
"net/http" "net/http"
"strconv" "strconv"
//"mstore/pkg/auxoci"
"mstore/pkg/descr" "mstore/pkg/descr"
ocidigest "github.com/opencontainers/go-digest" ocidigest "github.com/opencontainers/go-digest"
@@ -48,8 +47,8 @@ func (oper *Operator) ManifestExists(ctx context.Context, params *ManifestExists
var man descr.Manifest var man descr.Manifest
var exist bool var exist bool
digobj, err := ocidigest.Parse(params.Reference) digobj, parseErr := ocidigest.Parse(params.Reference)
if err == nil { if parseErr == nil {
exist, man, err = oper.mdb.GetManifestByDigest(ctx, params.Name, digobj.String()) exist, man, err = oper.mdb.GetManifestByDigest(ctx, params.Name, digobj.String())
if err != nil { if err != nil {
return res, http.StatusInternalServerError, err return res, http.StatusInternalServerError, err
@@ -75,7 +74,7 @@ func (oper *Operator) ManifestExists(ctx context.Context, params *ManifestExists
if err != nil { if err != nil {
return res, http.StatusInternalServerError, err return res, http.StatusInternalServerError, err
} }
digobj := ocidigest.SHA256.FromBytes(indexdata) digobj := ocidigest.FromBytes(indexdata)
res.DockerContentDigest = digobj.String() res.DockerContentDigest = digobj.String()
size := int64(len(indexdata)) size := int64(len(indexdata))
res.ContentLength = strconv.FormatInt(size, 10) res.ContentLength = strconv.FormatInt(size, 10)
+10 -1
View File
@@ -19,6 +19,7 @@ import (
"net/http" "net/http"
"strconv" "strconv"
ocidigest "github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
) )
@@ -74,6 +75,14 @@ func (oper *Operator) PutManifest(ctx context.Context, params *PutManifestParams
return res, http.StatusInternalServerError, err return res, http.StatusInternalServerError, err
} }
inManData := buffer.Bytes() inManData := buffer.Bytes()
var digstr string
digobj, parseErr := ocidigest.Parse(params.Reference)
if parseErr == nil {
digstr = digobj.String()
} else {
digobj := ocidigest.FromBytes(inManData)
digstr = digobj.String()
}
if int64(len(inManData)) != contentLength { if int64(len(inManData)) != contentLength {
err = fmt.Errorf("Mismatch Content-Length and received manifest size: %d vs %d", err = fmt.Errorf("Mismatch Content-Length and received manifest size: %d vs %d",
contentLength, len(inManData)) contentLength, len(inManData))
@@ -112,6 +121,7 @@ func (oper *Operator) PutManifest(ctx context.Context, params *PutManifestParams
} }
inManDescr, inlayerdescrs, err := descrsFromManifest(name, reference, inMan, inManData) inManDescr, inlayerdescrs, err := descrsFromManifest(name, reference, inMan, inManData)
inManDescr.Digest = digstr
// Always check layer files for availability // Always check layer files for availability
var blobError error var blobError error
for _, blobDescr := range inlayerdescrs { for _, blobDescr := range inlayerdescrs {
@@ -178,7 +188,6 @@ func (oper *Operator) PutManifest(ctx context.Context, params *PutManifestParams
} }
} }
} }
for _, blobDescr := range inlayerdescrs { for _, blobDescr := range inlayerdescrs {
// TODO: move the requests to db layer transaction // TODO: move the requests to db layer transaction
blobDescrExists, _, err := oper.mdb.GetBlobByNameDigest(ctx, blobDescr.Name, blobDescr.Digest) blobDescrExists, _, err := oper.mdb.GetBlobByNameDigest(ctx, blobDescr.Name, blobDescr.Digest)
+2 -2
View File
@@ -21,14 +21,14 @@ import (
type Database struct { type Database struct {
datapath string datapath string
log *logger.Logger logg *logger.Logger
db *sqlx.DB db *sqlx.DB
} }
func NewDatabase(datapath string) *Database { func NewDatabase(datapath string) *Database {
return &Database{ return &Database{
datapath: datapath, datapath: datapath,
log: logger.NewLoggerWithSubject("maindb"), logg: logger.NewLoggerWithSubject("maindb"),
} }
} }
+1 -1
View File
@@ -89,7 +89,7 @@ func (srv *Server) SetAsDaemon(asDaemon bool) {
func (srv *Server) Configure() error { func (srv *Server) Configure() error {
var err error var err error
srv.logg.Infof("Configuration server") //srv.logg.Infof("Configuration server")
srv.conf = config.NewConfig() srv.conf = config.NewConfig()
if err != nil { if err != nil {
return err return err
+2 -2
View File
@@ -70,6 +70,8 @@ func (svc *Service) Build() error {
svc.rout.Use(router.NewCorsMiddleware()) svc.rout.Use(router.NewCorsMiddleware())
svc.rout.Use(svc.hand.AuthMiddleware) svc.rout.Use(svc.hand.AuthMiddleware)
svc.rout.Head(`/v2/{name}/blobs/{digest}`, svc.hand.BlobExists)
svc.rout.Get(`/v3/api/service/hello`, svc.hand.SendHello) svc.rout.Get(`/v3/api/service/hello`, svc.hand.SendHello)
svc.rout.Head(`/v3/api/file/{filepath}`, svc.hand.FileInfo) svc.rout.Head(`/v3/api/file/{filepath}`, svc.hand.FileInfo)
@@ -93,8 +95,6 @@ func (svc *Service) Build() error {
svc.rout.Get(`/v2/{name}/manifests/{reference}`, svc.hand.GetManifest) svc.rout.Get(`/v2/{name}/manifests/{reference}`, svc.hand.GetManifest)
svc.rout.Delete(`/v2/{name}/manifests/{reference}`, svc.hand.DeleteManifest) svc.rout.Delete(`/v2/{name}/manifests/{reference}`, svc.hand.DeleteManifest)
svc.rout.Head(`/v2/{name}/blobs/{digest}`, svc.hand.BlobExists)
svc.rout.Post(`/v2/{name}/blobs/uploads/`, svc.hand.PostUpload) svc.rout.Post(`/v2/{name}/blobs/uploads/`, svc.hand.PostUpload)
svc.rout.Patch(`/v2/{name}/blobs/uploads/{reference}`, svc.hand.PatchUpload) svc.rout.Patch(`/v2/{name}/blobs/uploads/{reference}`, svc.hand.PatchUpload)
svc.rout.Put(`/v2/{name}/blobs/uploads/{reference}`, svc.hand.PutUpload) svc.rout.Put(`/v2/{name}/blobs/uploads/{reference}`, svc.hand.PutUpload)
+1
View File
@@ -45,6 +45,7 @@ func (util *ImageUtil) catalogImages(common *CommonImageParams, params *CatalogI
if err != nil { if err != nil {
return res, err return res, err
} }
ref.SetUserinfo(common.Username, common.Password)
mw := repocli.NewBasicAuthMiddleware(ref.Userinfo()) mw := repocli.NewBasicAuthMiddleware(ref.Userinfo())
cli := repocli.NewClient(nil, mw) cli := repocli.NewClient(nil, mw)
opres, err := cli.GetCatalog(ctx, ref.Raw()) opres, err := cli.GetCatalog(ctx, ref.Raw())
+1
View File
@@ -43,6 +43,7 @@ func (util *ImageUtil) deleteImage(common *CommonImageParams, params *DeleteImag
if err != nil { if err != nil {
return res, err return res, err
} }
ref.SetUserinfo(common.Username, common.Password)
mw := repocli.NewBasicAuthMiddleware(ref.Userinfo()) mw := repocli.NewBasicAuthMiddleware(ref.Userinfo())
cli := repocli.NewClient(nil, mw) cli := repocli.NewClient(nil, mw)
_, err = cli.DeleteImage(ctx, ref.Raw()) _, err = cli.DeleteImage(ctx, ref.Raw())
-59
View File
@@ -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/gcrcli"
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 := gcrcli.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
}
-9
View File
@@ -102,14 +102,6 @@ func (util *ImageUtil) CreateImageCmds() *cobra.Command {
} }
subCmd.AddCommand(imageTagsCmd) subCmd.AddCommand(imageTagsCmd)
// ImageConfig
var imageConfigCmd = &cobra.Command{
Use: "config [user:pass@]hostname[:port]/path:tag",
Short: "Show container image config info",
Args: cobra.ExactArgs(1),
Run: util.ImageConfig,
}
subCmd.AddCommand(imageConfigCmd)
// CatalogImages // CatalogImages
var catalogImagesCmd = &cobra.Command{ var catalogImagesCmd = &cobra.Command{
Use: "catalog [user:pass@]hostname[:port]", Use: "catalog [user:pass@]hostname[:port]",
@@ -125,7 +117,6 @@ func (util *ImageUtil) CreateImageCmds() *cobra.Command {
type ImageUtil struct { type ImageUtil struct {
imageManifestParams ImageManifestParams imageManifestParams ImageManifestParams
imageTagsParams ImageTagsParams imageTagsParams ImageTagsParams
imageConfigParams ImageConfigParams
catalogImagesParams CatalogImagesParams catalogImagesParams CatalogImagesParams
pullImageParams PullImageParams pullImageParams PullImageParams
+1
View File
@@ -53,6 +53,7 @@ func (util *ImageUtil) imageManifest(common *CommonImageParams, params *ImageMan
if err != nil { if err != nil {
return res, err return res, err
} }
ref.SetUserinfo(common.Username, common.Password)
mw := repocli.NewBasicAuthMiddleware(ref.Userinfo()) mw := repocli.NewBasicAuthMiddleware(ref.Userinfo())
cli := repocli.NewClient(nil, mw) cli := repocli.NewClient(nil, mw)
exists, mime, man, _, err := cli.GetRawManifest(ctx, ref.RawRepo()) exists, mime, man, _, err := cli.GetRawManifest(ctx, ref.RawRepo())
+1
View File
@@ -47,6 +47,7 @@ func (util *ImageUtil) imageTags(common *CommonImageParams, params *ImageTagsPar
if err != nil { if err != nil {
return res, err return res, err
} }
ref.SetUserinfo(common.Username, common.Password)
mw := repocli.NewBasicAuthMiddleware(ref.Userinfo()) mw := repocli.NewBasicAuthMiddleware(ref.Userinfo())
cli := repocli.NewClient(nil, mw) cli := repocli.NewClient(nil, mw)
opres, err := cli.GetTags(ctx, ref.Raw()) opres, err := cli.GetTags(ctx, ref.Raw())
@@ -16,7 +16,10 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"mstore/pkg/auxtool"
"mstore/pkg/auxutar"
"mstore/pkg/gcrcli" "mstore/pkg/gcrcli"
"mstore/pkg/repocli"
) )
// PullImage // PullImage
@@ -39,6 +42,45 @@ func (util *ImageUtil) PullImage(cmd *cobra.Command, args []string) {
func (util *ImageUtil) pullImage(common *CommonImageParams, params *PullImageParams) (*PullImageResult, error) { func (util *ImageUtil) pullImage(common *CommonImageParams, params *PullImageParams) (*PullImageResult, error) {
var err error var err error
res := &PullImageResult{}
timeout := time.Duration(common.Timeout) * time.Second
ctx, _ := context.WithTimeout(context.Background(), timeout)
ref, err := repocli.NewReferer(params.Imagepath)
if err != nil {
return res, err
}
ref.SetUserinfo(common.Username, common.Password)
mw := repocli.NewBasicAuthMiddleware(ref.Userinfo())
cli := repocli.NewClient(nil, mw)
load := repocli.NewLoader(cli)
if err != nil {
return res, err
}
imageDir := auxtool.MakeTmpFilename(params.Filepath)
err = load.Pull(ctx, ref.Raw(), imageDir, "", "")
if err != nil {
return res, err
}
err = auxutar.Archive(imageDir, params.Filepath)
defer os.RemoveAll(imageDir)
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
}
func (util *ImageUtil) XXXpullImage(common *CommonImageParams, params *PullImageParams) (*PullImageResult, error) {
var err error
ctx := context.Background() ctx := context.Background()
res := &PullImageResult{} res := &PullImageResult{}
@@ -60,6 +102,5 @@ func (util *ImageUtil) pullImage(common *CommonImageParams, params *PullImagePar
} }
res.Size = filestat.Size() res.Size = filestat.Size()
res.Filepath = params.Filepath res.Filepath = params.Filepath
return res, err return res, err
} }
@@ -11,11 +11,15 @@ package imagecmd
import ( import (
"context" "context"
"os"
"time" "time"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"mstore/pkg/auxtool"
"mstore/pkg/auxutar"
"mstore/pkg/gcrcli" "mstore/pkg/gcrcli"
"mstore/pkg/repocli"
) )
// PushImage // PushImage
@@ -35,6 +39,36 @@ func (util *ImageUtil) PushImage(cmd *cobra.Command, args []string) {
} }
func (util *ImageUtil) pushImage(common *CommonImageParams, params *PushImageParams) (*PushImageResult, error) { func (util *ImageUtil) pushImage(common *CommonImageParams, params *PushImageParams) (*PushImageResult, error) {
var err error
res := &PushImageResult{}
timeout := time.Duration(common.Timeout) * time.Second
ctx, _ := context.WithTimeout(context.Background(), timeout)
ref, err := repocli.NewReferer(params.Imagepath)
if err != nil {
return res, err
}
ref.SetUserinfo(common.Username, common.Password)
mw := repocli.NewBasicAuthMiddleware(ref.Userinfo())
cli := repocli.NewClient(nil, mw)
load := repocli.NewLoader(cli)
imageDir := auxtool.MakeTmpFilename(params.Filepath)
err = auxutar.Unarchive(params.Filepath, imageDir)
defer os.RemoveAll(imageDir)
if err != nil {
return res, err
}
err = load.Push(ctx, imageDir, ref.Raw(), "", "")
if err != nil {
return res, err
}
return res, err
}
func (util *ImageUtil) XXXpushImage(common *CommonImageParams, params *PushImageParams) (*PushImageResult, error) {
var err error var err error
ctx := context.Background() ctx := context.Background()
res := &PushImageResult{} res := &PushImageResult{}
Vendored
+1 -1
View File
@@ -3826,7 +3826,7 @@ printf "%s\n" "$as_me: srv_libdir set as ${SRV_LIBDIR}" >&6;}
SRV_DATADIR="/var/data/${PACKAGE}" SRV_DATADIR="/var/lib/${PACKAGE}"
# Check whether --with-datadir was given. # Check whether --with-datadir was given.
+1 -1
View File
@@ -213,7 +213,7 @@ AC_MSG_NOTICE(srv_libdir set as ${SRV_LIBDIR})
dnl -------------------------------------------------------------------------------------- dnl --------------------------------------------------------------------------------------
SRV_DATADIR="/var/data/${PACKAGE}" SRV_DATADIR="/var/lib/${PACKAGE}"
AC_ARG_WITH(datadir, AC_ARG_WITH(datadir,
AS_HELP_STRING([--with-datadir=PATH],[set path for datadir (default: $SRV_DATADIR)]), AS_HELP_STRING([--with-datadir=PATH],[set path for datadir (default: $SRV_DATADIR)]),
+1 -1
View File
@@ -4,7 +4,7 @@ Description=mstored
[Service] [Service]
Type=forking Type=forking
PIDFile=@srv_rundir@/mstored.pid PIDFile=@srv_rundir@/mstored.pid
ExecStart=@prefix@/sbin/mstored -daemon=true ExecStart=@prefix@/sbin/mstored --asDaemon=true --port=443
ExecReload=/bin/kill -HUP $MAINPID ExecReload=/bin/kill -HUP $MAINPID
[Install] [Install]
+31 -31
View File
@@ -30,7 +30,7 @@ type Referer struct {
} }
func ParsePath(rawpath string) (*Referer, error) { func ParsePath(rawpath string) (*Referer, error) {
repo := &Referer{ ref := &Referer{
values: url.Values{}, values: url.Values{},
} }
if !strings.Contains(rawpath, "://") { if !strings.Contains(rawpath, "://") {
@@ -38,71 +38,71 @@ func ParsePath(rawpath string) (*Referer, error) {
} }
urlobj, err := url.Parse(rawpath) urlobj, err := url.Parse(rawpath)
if err != nil { if err != nil {
return repo, err return ref, err
} }
if urlobj.User != nil { if urlobj.User != nil {
repo.user = urlobj.User.Username() ref.user = urlobj.User.Username()
repo.pass, _ = urlobj.User.Password() ref.pass, _ = urlobj.User.Password()
urlobj.User = nil urlobj.User = nil
} }
repo.resource = path.Join("/", urlobj.Path) ref.resource = path.Join("/", urlobj.Path)
urlobj.Path = "/" urlobj.Path = "/"
repo.urlobj = urlobj ref.urlobj = urlobj
repo.values = urlobj.Query() ref.values = urlobj.Query()
return repo, err return ref, err
} }
func (repo *Referer) Raw() string { func (ref *Referer) Raw() string {
res := path.Join(repo.urlobj.Host, repo.resource) res := path.Join(ref.urlobj.Host, ref.resource)
query := repo.values.Encode() query := ref.values.Encode()
if query != "" { if query != "" {
return res + "?" + query return res + "?" + query
} }
return res return res
} }
func (repo *Referer) SetResource(resource string) { func (ref *Referer) SetResource(resource string) {
repo.resource = path.Join("/", resource) ref.resource = path.Join("/", resource)
} }
func (repo *Referer) JoinResource(resource string) { func (ref *Referer) JoinResource(resource string) {
repo.resource = path.Join("/", repo.resource, resource) ref.resource = path.Join("/", ref.resource, resource)
} }
func (repo *Referer) PathType(typ string) { func (ref *Referer) PathType(typ string) {
repo.values.Set("pathType", typ) ref.values.Set("pathType", typ)
} }
func (repo *Referer) DryRun(yesno bool) { func (ref *Referer) DryRun(yesno bool) {
repo.values.Set("dryRun", strconv.FormatBool(yesno)) ref.values.Set("dryRun", strconv.FormatBool(yesno))
} }
func (repo *Referer) FileEP() string { func (ref *Referer) FileEP() string {
curl := repo.urlobj.JoinPath("/v3/api/file/", repo.resource) curl := ref.urlobj.JoinPath("/v3/api/file/", ref.resource)
return curl.String() return curl.String()
} }
func (repo *Referer) FilesEP() string { func (ref *Referer) FilesEP() string {
curl := repo.urlobj.JoinPath("/v3/api/files/", repo.resource) curl := ref.urlobj.JoinPath("/v3/api/files/", ref.resource)
return curl.String() return curl.String()
} }
func (repo *Referer) CollectionEP() string { func (ref *Referer) CollectionEP() string {
curl := repo.urlobj.JoinPath("/v3/api/collection/", repo.resource) curl := ref.urlobj.JoinPath("/v3/api/collection/", ref.resource)
return curl.String() return curl.String()
} }
func (repo *Referer) CollectionsEP() string { func (ref *Referer) CollectionsEP() string {
curl := repo.urlobj.JoinPath("/v3/api/collections/", repo.resource) curl := ref.urlobj.JoinPath("/v3/api/collections/", ref.resource)
return curl.String() return curl.String()
} }
func (repo *Referer) Userinfo() (string, string) { func (ref *Referer) Userinfo() (string, string) {
return repo.user, repo.pass return ref.user, ref.pass
} }
func (repo *Referer) SetUserinfo(user, pass string) { func (ref *Referer) SetUserinfo(user, pass string) {
if user != "" && pass != "" { if user != "" && pass != "" {
repo.user, repo.pass = user, pass ref.user, ref.pass = user, pass
} }
} }
-2
View File
@@ -27,8 +27,6 @@ func (cli *Client) BlobExists(ctx context.Context, rawrepo string, digest string
return exist, size, err return exist, size, err
} }
uri := ref.BlobEP(digest) uri := ref.BlobEP(digest)
fmt.Println(uri)
req, err := http.NewRequestWithContext(ctx, http.MethodHead, uri, nil) req, err := http.NewRequestWithContext(ctx, http.MethodHead, uri, nil)
if err != nil { if err != nil {
return exist, size, err return exist, size, err
+8 -2
View File
@@ -17,7 +17,7 @@ import (
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
) )
func (down *Loader) Push(ctx context.Context, rawref, dir, osname, arch string) error { func (down *Loader) Push(ctx context.Context, dir, rawref, osname, arch string) error {
var err error var err error
ref, err := NewReferer(rawref) ref, err := NewReferer(rawref)
@@ -45,11 +45,16 @@ func (down *Loader) Push(ctx context.Context, rawref, dir, osname, arch string)
layers = append(layers, man.Layers...) layers = append(layers, man.Layers...)
layers = append(layers, man.Config) layers = append(layers, man.Config)
for _, layer := range layers { for _, layer := range layers {
digstr := layer.Digest.String()
exists, _, err := down.cli.BlobExists(ctx, ref.RawRepo(), digstr)
if err != nil {
return err
}
if !exists {
id, _, err := down.cli.GetUpload(ctx, ref.RawRepo()) id, _, err := down.cli.GetUpload(ctx, ref.RawRepo())
if err != nil { if err != nil {
return err return err
} }
digstr := layer.Digest.String()
size, reader, err := imager.LayerReader(ctx, digstr) size, reader, err := imager.LayerReader(ctx, digstr)
if err != nil { if err != nil {
return err return err
@@ -64,6 +69,7 @@ func (down *Loader) Push(ctx context.Context, rawref, dir, osname, arch string)
return err return err
} }
} }
}
err = down.cli.PutManifest(ctx, ref.Raw(), mandata, mime) err = down.cli.PutManifest(ctx, ref.Raw(), mandata, mime)
if err != nil { if err != nil {
return err return err
+1 -1
View File
@@ -28,7 +28,7 @@ func TestPushImage(t *testing.T) {
load := NewLoader(cli) load := NewLoader(cli)
require.NotNil(t, load) require.NotNil(t, load)
err := load.Push(ctx, "localhost:1025/test:v1.0", "test-oci", "", "") err := load.Push(ctx, "test-oci", "localhost:1025/test:v1.0", "", "")
require.NoError(t, err) require.NoError(t, err)
} }
//return //return
+6
View File
@@ -144,3 +144,9 @@ func (ref *Referer) CatalogEP() string {
func (ref *Referer) Userinfo() (string, string) { func (ref *Referer) Userinfo() (string, string) {
return ref.user, ref.pass return ref.user, ref.pass
} }
func (ref *Referer) SetUserinfo(user, pass string) {
if user != "" && pass != "" {
ref.user, ref.pass = user, pass
}
}