diff --git a/Makefile.am b/Makefile.am index c1d22ee..d75544c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -99,7 +99,6 @@ EXTRA_mstored_SOURCES += \ app/imageoper/getman.go \ app/imageoper/getrefer.go \ app/imageoper/gettags.go \ - app/imageoper/imgaux.go \ app/imageoper/listman.go \ app/imageoper/manexist.go \ app/imageoper/ociaux.go \ @@ -146,7 +145,6 @@ EXTRA_mstored_SOURCES += \ pkg/accntcli/updgrant.go \ pkg/auxhttp/basic.go \ pkg/auxhttp/crange.go \ - pkg/auxoci/ociaux.go \ pkg/auxpwd/passwd.go \ pkg/auxtool/cleandir.go \ pkg/auxtool/fileex.go \ diff --git a/Makefile.in b/Makefile.in index f14ff13..590c621 100644 --- a/Makefile.in +++ b/Makefile.in @@ -411,29 +411,28 @@ EXTRA_mstored_SOURCES = cmd/mstored/starter/starter.go \ app/imageoper/delblob.go app/imageoper/delman.go \ app/imageoper/getblob.go app/imageoper/getman.go \ app/imageoper/getrefer.go app/imageoper/gettags.go \ - app/imageoper/imgaux.go app/imageoper/listman.go \ - app/imageoper/manexist.go app/imageoper/ociaux.go \ - app/imageoper/operator.go app/imageoper/patchupload.go \ - app/imageoper/postupload.go app/imageoper/putman.go \ - app/imageoper/putupload.go app/imageoper/service.go \ - app/imageoper/version.go app/locker/locker.go \ - app/logger/logger.go app/maindb/account.go app/maindb/blob.go \ - app/maindb/file.go app/maindb/grant.go app/maindb/init.go \ - app/maindb/maindb.go app/maindb/manifest.go \ - app/maindb/scheme.go app/router/bindobj.go \ - app/router/context.go app/router/corsmw.go \ - app/router/loggingmw.go app/router/pathc.go \ - app/router/recovermw.go app/router/router.go \ - app/server/server.go app/service/service.go \ - app/storage/storage.go pkg/accntcli/client.go \ - pkg/accntcli/createacc.go pkg/accntcli/creategrant.go \ - pkg/accntcli/delacc.go pkg/accntcli/delgrant.go \ - pkg/accntcli/getacc.go pkg/accntcli/getgrant.go \ - pkg/accntcli/httpcall.go pkg/accntcli/listacc.go \ - pkg/accntcli/listgrants.go pkg/accntcli/referer.go \ - pkg/accntcli/servhello.go pkg/accntcli/updateacc.go \ - pkg/accntcli/updgrant.go pkg/auxhttp/basic.go \ - pkg/auxhttp/crange.go pkg/auxoci/ociaux.go \ + app/imageoper/listman.go app/imageoper/manexist.go \ + app/imageoper/ociaux.go app/imageoper/operator.go \ + app/imageoper/patchupload.go app/imageoper/postupload.go \ + app/imageoper/putman.go app/imageoper/putupload.go \ + app/imageoper/service.go app/imageoper/version.go \ + app/locker/locker.go app/logger/logger.go \ + app/maindb/account.go app/maindb/blob.go app/maindb/file.go \ + app/maindb/grant.go app/maindb/init.go app/maindb/maindb.go \ + app/maindb/manifest.go app/maindb/scheme.go \ + app/router/bindobj.go app/router/context.go \ + app/router/corsmw.go app/router/loggingmw.go \ + app/router/pathc.go app/router/recovermw.go \ + app/router/router.go app/server/server.go \ + app/service/service.go app/storage/storage.go \ + pkg/accntcli/client.go pkg/accntcli/createacc.go \ + pkg/accntcli/creategrant.go pkg/accntcli/delacc.go \ + pkg/accntcli/delgrant.go pkg/accntcli/getacc.go \ + pkg/accntcli/getgrant.go pkg/accntcli/httpcall.go \ + pkg/accntcli/listacc.go pkg/accntcli/listgrants.go \ + pkg/accntcli/referer.go pkg/accntcli/servhello.go \ + pkg/accntcli/updateacc.go pkg/accntcli/updgrant.go \ + pkg/auxhttp/basic.go pkg/auxhttp/crange.go \ pkg/auxpwd/passwd.go pkg/auxtool/cleandir.go \ pkg/auxtool/fileex.go pkg/auxtool/randstr.go \ pkg/auxtool/tmpfile.go pkg/auxtool/unixnow.go \ diff --git a/app/config/variant.go b/app/config/variant.go index 0786735..bc04665 100644 --- a/app/config/variant.go +++ b/app/config/variant.go @@ -6,5 +6,5 @@ const ( logdir = "/var/log/mstore" datadir = "/var/data/mstore" version = "0.2.0" - srvname = "mstored" + srvname = "mstored" ) diff --git a/app/fileoper/operator.go b/app/fileoper/operator.go index 236586c..790bdc2 100644 --- a/app/fileoper/operator.go +++ b/app/fileoper/operator.go @@ -26,7 +26,6 @@ type Operator struct { store *storage.Storage logg *logger.Logger iLock *locker.Locker - fLock *locker.Locker } func NewOperator(params *OperatorParams) (*Operator, error) { @@ -36,7 +35,6 @@ func NewOperator(params *OperatorParams) (*Operator, error) { store: params.Store, } oper.iLock = locker.NewLocker() - oper.fLock = locker.NewLocker() oper.logg = logger.NewLoggerWithSubject("fileoper") return oper, err } diff --git a/app/imageoper/delman.go b/app/imageoper/delman.go index 7853c89..a2e74e0 100644 --- a/app/imageoper/delman.go +++ b/app/imageoper/delman.go @@ -15,6 +15,8 @@ import ( "net/http" "mstore/pkg/descr" + + ocidigest "github.com/opencontainers/go-digest" ) type DeleteManifestParams struct { @@ -43,26 +45,27 @@ func (oper *Operator) DeleteManifest(ctx context.Context, params *DeleteManifest var exists bool var reference string - manifestDescr := descr.Manifest{} + mandescr := descr.Manifest{} // Check manifest by digest as name - if stringLikeSHADigest(params.Reference) { - digest := normalizeSHADigest(params.Reference) - exists, manifestDescr, err = oper.mdb.GetManifestByDigest(ctx, params.Name, digest) + + digobj, err := ocidigest.Parse(params.Reference) + if err == nil { + exists, mandescr, err = oper.mdb.GetManifestByDigest(ctx, params.Name, digobj.String()) if err != nil { return res, http.StatusInternalServerError, err } if !exists { return res, http.StatusNotFound, err } - reference = manifestDescr.Reference + reference = mandescr.Reference err = oper.deleteManifestObjects(ctx, params.Name, reference) if err != nil { return res, http.StatusInternalServerError, err } } else { // Check manifest by name and reference - exists, manifestDescrs, err := oper.mdb.GetManifestsByReference(ctx, params.Name, params.Reference) + exists, mandescrs, err := oper.mdb.GetManifestsByReference(ctx, params.Name, params.Reference) if err != nil { return res, http.StatusInternalServerError, err } @@ -70,8 +73,8 @@ func (oper *Operator) DeleteManifest(ctx context.Context, params *DeleteManifest return res, http.StatusNotFound, err } reference = params.Reference - for _, manifestDescr := range manifestDescrs { - reference = manifestDescr.Reference + for _, mandescr := range mandescrs { + reference = mandescr.Reference err = oper.deleteManifestObjects(ctx, params.Name, reference) if err != nil { return res, http.StatusInternalServerError, err diff --git a/app/imageoper/getman.go b/app/imageoper/getman.go index ee229c7..80e5e72 100644 --- a/app/imageoper/getman.go +++ b/app/imageoper/getman.go @@ -15,8 +15,9 @@ import ( "net/http" "strconv" - "mstore/pkg/auxoci" "mstore/pkg/descr" + + ocidigest "github.com/opencontainers/go-digest" ) type GetManifestParams struct { @@ -47,56 +48,42 @@ func (oper *Operator) GetManifest(ctx context.Context, params *GetManifestParams oper.iLock.WaitAndLock(resName) defer oper.iLock.Done(resName) - manifestDescr := descr.Manifest{} + manDescr := descr.Manifest{} var exists bool - // TODO: checking layers? - if stringLikeSHADigest(params.Reference) { - digest := normalizeSHADigest(params.Reference) - exists, manifestDescr, err = oper.mdb.GetManifestByDigest(ctx, params.Name, digest) + digobj, err := ocidigest.Parse(params.Reference) + if err == nil { + exists, manDescr, err = oper.mdb.GetManifestByDigest(ctx, params.Name, digobj.String()) if err != nil { return res, http.StatusInternalServerError, err } if !exists { return res, http.StatusNotFound, err } - - manifestDigest := auxoci.SHA256DigestFromString(manifestDescr.Payload) - res.DockerContentDigest = manifestDigest.String() - - res.ContentLength = strconv.FormatInt(int64(len(manifestDescr.Payload)), 10) - res.ContentType = manifestDescr.ContentType - res.Payload = manifestDescr.Payload + res.DockerContentDigest = manDescr.Digest + size := int64(len(manDescr.Payload)) + res.ContentLength = strconv.FormatInt(size, 10) + res.ContentType = manDescr.ContentType + res.Payload = manDescr.Payload } else { // Create index of manifests - exists, manifestDescrs, err := oper.mdb.GetManifestsByReference(ctx, params.Name, params.Reference) + exists, manDescrs, err := oper.mdb.GetManifestsByReference(ctx, params.Name, params.Reference) if err != nil { return res, http.StatusInternalServerError, err } if !exists { return res, http.StatusNotFound, err } - /* - index, indexBytes, err := indexFromManigestDescrs(manifestDescrs) - if err != nil { - return res, http.StatusInternalServerError, err - } - indexDigest := auxoci.SHA256DigestFromString(indexBytes) - res.DockerContentDigest = indexDigest.String() - - res.ContentLength = strconv.FormatInt(int64(len(indexBytes)), 10) - res.ContentType = index.MediaType - res.Payload = string(indexBytes) - */ - manifestDescr = manifestDescrs[0] - - manifestDigest := auxoci.SHA256DigestFromString(manifestDescr.Payload) - res.DockerContentDigest = manifestDigest.String() - - res.ContentLength = strconv.FormatInt(int64(len(manifestDescr.Payload)), 10) - res.ContentType = manifestDescr.ContentType - res.Payload = manifestDescr.Payload - + _, indexdata, err := indexFromManigestDescrs(manDescrs) + if err != nil { + return res, http.StatusInternalServerError, err + } + digobj := ocidigest.SHA256.FromBytes(indexdata) + res.DockerContentDigest = digobj.String() + size := int64(len(indexdata)) + res.ContentLength = strconv.FormatInt(size, 10) + res.ContentType = oiiMediaType + res.Payload = string(indexdata) } return res, http.StatusOK, err } diff --git a/app/imageoper/imgaux.go b/app/imageoper/imgaux.go deleted file mode 100644 index b9070f0..0000000 --- a/app/imageoper/imgaux.go +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2026 Oleg Borodin - * - * 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 imageoper - -import ( - "encoding/hex" - "strings" -) - -const sha256prefix = "sha256:" -const sha512prefix = "sha512:" - -func normalizeSHADigest(digest string) string { - if stringLikeSHA256Digest(digest) && !strings.HasPrefix(digest, sha256prefix) { - digest = sha256prefix + digest - } else if stringLikeSHA512Digest(digest) && !strings.HasPrefix(digest, sha512prefix) { - digest = sha512prefix + digest - } - return digest -} - -func stringLikeSHADigest(some string) bool { - return stringLikeSHA256Digest(some) || stringLikeSHA512Digest(some) -} - -func stringLikeSHA256Digest(some string) bool { - if strings.HasPrefix(some, sha256prefix) { - some = strings.TrimPrefix(some, sha256prefix) - } - _, err := hex.DecodeString(some) - if err != nil { - return false - } - if len(some) == 64 { - return true - } - return false -} - -func stringLikeSHA512Digest(some string) bool { - if strings.HasPrefix(some, sha512prefix) { - some = strings.TrimPrefix(some, sha512prefix) - } - _, err := hex.DecodeString(some) - if err != nil { - return false - } - if len(some) == 128 { - return true - } - return false -} diff --git a/app/imageoper/manexist.go b/app/imageoper/manexist.go index 22b4f39..a93bb00 100644 --- a/app/imageoper/manexist.go +++ b/app/imageoper/manexist.go @@ -15,8 +15,10 @@ import ( "net/http" "strconv" - "mstore/pkg/auxoci" + //"mstore/pkg/auxoci" "mstore/pkg/descr" + + ocidigest "github.com/opencontainers/go-digest" ) type ManifestExistsParams struct { @@ -43,35 +45,42 @@ func (oper *Operator) ManifestExists(ctx context.Context, params *ManifestExists return res, http.StatusBadRequest, err } - var manifest descr.Manifest - manifests := make([]descr.Manifest, 0) - var exists bool - if stringLikeSHA256Digest(params.Reference) { - digest := fmt.Sprintf("%s:%s", sha256prefix, params.Reference) - exists, manifest, err = oper.mdb.GetManifestByDigest(ctx, params.Name, digest) + var man descr.Manifest + var exist bool + + digobj, err := ocidigest.Parse(params.Reference) + if err == nil { + exist, man, err = oper.mdb.GetManifestByDigest(ctx, params.Name, digobj.String()) if err != nil { return res, http.StatusInternalServerError, err } - if !exists { + if !exist { return res, http.StatusNotFound, err } + size := int64(len(man.Payload)) + res.ContentLength = strconv.FormatInt(size, 10) + res.ContentType = man.ContentType + res.DockerContentDigest = man.Digest + res.Exists = exist } else { - exists, manifests, err = oper.mdb.GetManifestsByReference(ctx, params.Name, params.Reference) + // Create index of manifests + exists, manDescrs, err := oper.mdb.GetManifestsByReference(ctx, params.Name, params.Reference) if err != nil { return res, http.StatusInternalServerError, err } if !exists { return res, http.StatusNotFound, err } - manifest = manifests[0] // TODO: tmp + _, indexdata, err := indexFromManigestDescrs(manDescrs) + if err != nil { + return res, http.StatusInternalServerError, err + } + digobj := ocidigest.SHA256.FromBytes(indexdata) + res.DockerContentDigest = digobj.String() + size := int64(len(indexdata)) + res.ContentLength = strconv.FormatInt(size, 10) + res.ContentType = oiiMediaType + res.Exists = true } - - digest := auxoci.SHA256DigestFromString(manifest.Payload) - payloadSize := len(manifest.Payload) - res.ContentLength = strconv.FormatInt(int64(payloadSize), 10) - res.ContentType = manifest.ContentType - res.DockerContentDigest = digest.String() - res.Exists = exists - return res, http.StatusOK, err } diff --git a/app/imageoper/ociaux.go b/app/imageoper/ociaux.go index c5c9c14..64dd44b 100644 --- a/app/imageoper/ociaux.go +++ b/app/imageoper/ociaux.go @@ -12,7 +12,7 @@ package imageoper import ( "encoding/json" - "mstore/pkg/auxoci" + //"mstore/pkg/auxoci" "mstore/pkg/auxtool" "mstore/pkg/auxuuid" "mstore/pkg/descr" @@ -26,45 +26,50 @@ const ( oimMediaType = "application/vnd.oci.image.manifest.v1+json" ) -func indexFromManigestDescrs(manifestDescrs []descr.Manifest) (ocispec.Index, string, error) { +func indexFromManigestDescrs(mandescrs []descr.Manifest) (ocispec.Index, []byte, error) { var err error - var payload string + var indexdata []byte index := ocispec.Index{ MediaType: oiiMediaType, Manifests: make([]ocispec.Descriptor, 0), } index.Versioned.SchemaVersion = 2 - for _, manifestDescr := range manifestDescrs { - var ociManifest ocispec.Manifest + for _, mandescr := range mandescrs { + var man ocispec.Manifest - ociManifest.Subject = &ocispec.Descriptor{} - ociManifest.Subject.Platform = &ocispec.Platform{} - ociManifest.Config = ocispec.Descriptor{} - ociManifest.Config.Platform = &ocispec.Platform{} + man.Subject = &ocispec.Descriptor{} + man.Subject.Platform = &ocispec.Platform{} + man.Config = ocispec.Descriptor{} + man.Config.Platform = &ocispec.Platform{} - err = json.Unmarshal([]byte(manifestDescr.Payload), &ociManifest) + err = json.Unmarshal([]byte(mandescr.Payload), &man) if err != nil { - return index, payload, err + return index, indexdata, err } + digobj, err := ocidigest.Parse(mandescr.Digest) + if err != nil { + return index, indexdata, err + } + size := int64(len(mandescr.Payload)) descriptor := ocispec.Descriptor{ - MediaType: oimMediaType, - Digest: auxoci.SHA256DigestFromString(manifestDescr.Payload), - Size: int64(len(manifestDescr.Payload)), - Platform: ociManifest.Subject.Platform, + MediaType: mandescr.ContentType, + Digest: digobj, + Size: size, + Platform: man.Subject.Platform, } index.Manifests = append(index.Manifests, descriptor) } - indexBytes, err := json.Marshal(index) + indexdata, err = json.Marshal(index) if err != nil { - return index, payload, err + return index, indexdata, err } - payload = string(indexBytes) - return index, payload, err + indexdata = indexdata + return index, indexdata, err } func descrsFromManifest(name, reference string, manifest *ocispec.Manifest, rawManifest []byte) (descr.Manifest, []descr.Blob, error) { var err error - manifestDescr := descr.Manifest{} + mandescr := descr.Manifest{} //configDescr := descr.Blob{} blobDescrs := make([]descr.Blob, 0) @@ -72,7 +77,7 @@ func descrsFromManifest(name, reference string, manifest *ocispec.Manifest, rawM // Make manifest descriptor manifestDigest := ocidigest.SHA256.FromBytes(rawManifest).String() - manifestDescr = descr.Manifest{ + mandescr = descr.Manifest{ ID: auxuuid.NewUUID(), Name: name, Reference: reference, @@ -114,7 +119,7 @@ func descrsFromManifest(name, reference string, manifest *ocispec.Manifest, rawM layerMap[string(layer.Digest)] = true } } - return manifestDescr, blobDescrs, err + return mandescr, blobDescrs, err } func layersDiff(name, reference string, existingManifest, incomingManifest *ocispec.Manifest, rawManifest []byte) ([]descr.Blob, []descr.Blob, error) { diff --git a/app/imageoper/operator.go b/app/imageoper/operator.go index f45606b..7c1026c 100644 --- a/app/imageoper/operator.go +++ b/app/imageoper/operator.go @@ -26,7 +26,6 @@ type Operator struct { store *storage.Storage logg *logger.Logger iLock *locker.Locker - fLock *locker.Locker } func NewOperator(params *OperatorParams) (*Operator, error) { @@ -36,7 +35,6 @@ func NewOperator(params *OperatorParams) (*Operator, error) { store: params.Store, } oper.iLock = locker.NewLocker() - oper.fLock = locker.NewLocker() oper.logg = logger.NewLoggerWithSubject("imageoper") return oper, err } diff --git a/app/imageoper/putman.go b/app/imageoper/putman.go index 8818508..56afbbf 100644 --- a/app/imageoper/putman.go +++ b/app/imageoper/putman.go @@ -12,13 +12,14 @@ package imageoper import ( "bytes" "context" + "encoding/json" "errors" "fmt" "io" "net/http" "strconv" - "mstore/pkg/auxoci" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) type PutManifestParams struct { @@ -53,14 +54,8 @@ func (oper *Operator) PutManifest(ctx context.Context, params *PutManifestParams err = fmt.Errorf("Empty name") return res, http.StatusBadRequest, err } - // Check Content-Type - var mimeIsAcceptably bool - mimeIsAcceptably = mimeIsAcceptably || params.ContentType == oimMimeType - mimeIsAcceptably = mimeIsAcceptably || params.ContentType == ddmMimeType - //mimeIsAcceptably = mimeIsAcceptably || params.ContentType == oicMimeType - //mimeIsAcceptably = mimeIsAcceptably || params.ContentType == dciMimeType - if !mimeIsAcceptably { + if params.ContentType != oimMimeType && params.ContentType != ddmMimeType { err = fmt.Errorf("Unknown or empty Content-Type: %s", params.ContentType) return res, http.StatusNotFound, err } @@ -86,47 +81,48 @@ func (oper *Operator) PutManifest(ctx context.Context, params *PutManifestParams if err != nil { return res, http.StatusInternalServerError, err } - - incomingManifestBytes := buffer.Bytes() - - if int64(len(incomingManifestBytes)) != contentLength { + inManData := buffer.Bytes() + if int64(len(inManData)) != contentLength { err = fmt.Errorf("Mismatch Content-Length and received manifest size: %d vs %d", - contentLength, len(incomingManifestBytes)) + contentLength, len(inManData)) code := http.StatusInternalServerError return res, code, err } - if len(incomingManifestBytes) > (4 * 1024 * 1024) { - err = fmt.Errorf("Payload more 4M: %d bytes", len(incomingManifestBytes)) + if len(inManData) > (4 * 1024 * 1024) { + err = fmt.Errorf("Payload more 4M: %d bytes", len(inManData)) code := http.StatusRequestEntityTooLarge return res, code, err } - - incomingManifest, err := auxoci.ParseOCIManifest(incomingManifestBytes) + inMan := &ocispec.Manifest{} + err = json.Unmarshal(inManData, inMan) if err != nil { - err = fmt.Errorf("Parsing OCI manifest error: %v", err) + err = fmt.Errorf("Manifest parsing error: %v", err) return res, http.StatusInternalServerError, err } - if incomingManifest.MediaType == "" { - incomingManifest.MediaType = params.ContentType + if inMan.MediaType == "" { + inMan.MediaType = params.ContentType } name := params.Name reference := params.Reference - arch := incomingManifest.Subject.Platform.Architecture - os := incomingManifest.Subject.Platform.OS - variant := incomingManifest.Subject.Platform.Variant + if inMan.Subject == nil { + } - manifestExists, existingManifestDescr, err := oper.mdb.GetManifestsByReferenceArchitecture(ctx, name, reference, arch, os, variant) + arch := inMan.Subject.Platform.Architecture + os := inMan.Subject.Platform.OS + variant := inMan.Subject.Platform.Variant + + manexist, exMandescr, err := oper.mdb.GetManifestsByReferenceArchitecture(ctx, name, reference, arch, os, variant) if err != nil { return res, http.StatusInternalServerError, err } - incomingManifestDescr, incomingLayerDescrs, err := descrsFromManifest(name, reference, incomingManifest, incomingManifestBytes) + inManDescr, inlayerdescrs, err := descrsFromManifest(name, reference, inMan, inManData) // Always check layer files for availability var blobError error - for _, blobDescr := range incomingLayerDescrs { + for _, blobDescr := range inlayerdescrs { blobExists, _, err := oper.store.BlobExists(blobDescr.Digest) if err != nil { return res, http.StatusInternalServerError, err @@ -141,32 +137,33 @@ func (oper *Operator) PutManifest(ctx context.Context, params *PutManifestParams // TODO: more relevant code? return res, http.StatusFailedDependency, blobError } - if !manifestExists { + if !manexist { // Store manifest and layesrs data - err = oper.mdb.InsertManifestWithLayers(ctx, &incomingManifestDescr, incomingLayerDescrs) + err = oper.mdb.InsertManifestWithLayers(ctx, &inManDescr, inlayerdescrs) if err != nil { return res, http.StatusInternalServerError, err } } else { /* TODO: only update descr - if bytes.Equal(existingManifestBytes, incomingManifestBytes) { + if bytes.Equal(exManData, inManData) { return res, http.StatusCreated, err } */ - existingManifestBytes := []byte(existingManifestDescr.Payload) - existingManifest, err := auxoci.ParseOCIManifest(existingManifestBytes) + exManData := []byte(exMandescr.Payload) + exMan := &ocispec.Manifest{} + err := json.Unmarshal(exManData, exMan) if err != nil { return res, http.StatusInternalServerError, err } addedBlobDescrs, uselessBlobDescrs, err := layersDiff(name, reference, - existingManifest, incomingManifest, incomingManifestBytes) + exMan, inMan, inManData) if err != nil { return res, http.StatusInternalServerError, err } // Starting manifest and blobs transaction - err = oper.mdb.UpdateManifestWithBlobs(ctx, &incomingManifestDescr, addedBlobDescrs, uselessBlobDescrs) + err = oper.mdb.UpdateManifestWithBlobs(ctx, &inManDescr, addedBlobDescrs, uselessBlobDescrs) if err != nil { return res, http.StatusInternalServerError, err } @@ -190,7 +187,7 @@ func (oper *Operator) PutManifest(ctx context.Context, params *PutManifestParams } } - for _, blobDescr := range incomingLayerDescrs { + for _, blobDescr := range inlayerdescrs { // TODO: move the requests to db layer transaction blobDescrExists, _, err := oper.mdb.GetBlobByNameDigest(ctx, blobDescr.Name, blobDescr.Digest) if err != nil { diff --git a/pkg/auxoci/ociaux.go b/pkg/auxoci/ociaux.go deleted file mode 100644 index deb51db..0000000 --- a/pkg/auxoci/ociaux.go +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2026 Oleg Borodin - * - * 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 auxoci - -import ( - "encoding/json" - "fmt" - - ocidigest "github.com/opencontainers/go-digest" - ocispec "github.com/opencontainers/image-spec/specs-go/v1" -) - -func ParseOCIManifest(rawManifest []byte) (*ocispec.Manifest, error) { - manifest := &ocispec.Manifest{} - manifest.Subject = &ocispec.Descriptor{} - manifest.Subject.Platform = &ocispec.Platform{} - manifest.Config = ocispec.Descriptor{} - manifest.Config.Platform = &ocispec.Platform{} - - err := json.Unmarshal(rawManifest, &manifest) - if err != nil { - err = fmt.Errorf("Manifest parsing error: %v", err) - return manifest, err - } - return manifest, err -} - -func SHA256DigestFromString(payload string) ocidigest.Digest { - return ocidigest.SHA256.FromString(payload) -} diff --git a/pkg/digest/digest.go b/pkg/digest/digest.go index 55179a8..484ae13 100644 --- a/pkg/digest/digest.go +++ b/pkg/digest/digest.go @@ -1,3 +1,12 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 digest import ( diff --git a/pkg/filecli/authbas.go b/pkg/filecli/authbas.go index 4e51400..d6524d0 100644 --- a/pkg/filecli/authbas.go +++ b/pkg/filecli/authbas.go @@ -1,3 +1,12 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 filecli import ( diff --git a/pkg/filecli/client.go b/pkg/filecli/client.go index c92eaec..b987148 100644 --- a/pkg/filecli/client.go +++ b/pkg/filecli/client.go @@ -1,3 +1,12 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 filecli import ( diff --git a/pkg/filecli/copyctx.go b/pkg/filecli/copyctx.go index 9b3c077..897e4da 100644 --- a/pkg/filecli/copyctx.go +++ b/pkg/filecli/copyctx.go @@ -1,3 +1,12 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 filecli import ( diff --git a/pkg/filecli/delcoll.go b/pkg/filecli/delcoll.go index f04bb84..05f8e05 100644 --- a/pkg/filecli/delcoll.go +++ b/pkg/filecli/delcoll.go @@ -1,3 +1,12 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 filecli import ( diff --git a/pkg/filecli/delfile.go b/pkg/filecli/delfile.go index 5c8a735..589a832 100644 --- a/pkg/filecli/delfile.go +++ b/pkg/filecli/delfile.go @@ -1,3 +1,12 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 filecli import ( diff --git a/pkg/filecli/fileinfo.go b/pkg/filecli/fileinfo.go index d1b65cd..21650ce 100644 --- a/pkg/filecli/fileinfo.go +++ b/pkg/filecli/fileinfo.go @@ -1,3 +1,12 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 filecli import ( diff --git a/pkg/filecli/getfile.go b/pkg/filecli/getfile.go index e75f019..1dc9dc8 100644 --- a/pkg/filecli/getfile.go +++ b/pkg/filecli/getfile.go @@ -1,3 +1,12 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 filecli import ( diff --git a/pkg/filecli/listcoll.go b/pkg/filecli/listcoll.go index 7ec600d..62a3206 100644 --- a/pkg/filecli/listcoll.go +++ b/pkg/filecli/listcoll.go @@ -1,3 +1,12 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 filecli import ( diff --git a/pkg/filecli/listfiles.go b/pkg/filecli/listfiles.go index 93ff735..6a48990 100644 --- a/pkg/filecli/listfiles.go +++ b/pkg/filecli/listfiles.go @@ -1,3 +1,12 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 filecli import ( diff --git a/pkg/filecli/putfile.go b/pkg/filecli/putfile.go index 24f4535..bf219dd 100644 --- a/pkg/filecli/putfile.go +++ b/pkg/filecli/putfile.go @@ -1,3 +1,12 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 filecli import ( diff --git a/pkg/filecli/referer.go b/pkg/filecli/referer.go index dc0b4e1..0a834c3 100644 --- a/pkg/filecli/referer.go +++ b/pkg/filecli/referer.go @@ -1,3 +1,12 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 filecli import ( diff --git a/pkg/repocli/blobexist.go b/pkg/repocli/blobexist.go index d5c49ae..6ac1453 100644 --- a/pkg/repocli/blobexist.go +++ b/pkg/repocli/blobexist.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/blobexist_test.go b/pkg/repocli/blobexist_test.go index 8c52352..b75f9f4 100644 --- a/pkg/repocli/blobexist_test.go +++ b/pkg/repocli/blobexist_test.go @@ -1,3 +1,12 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/client.go b/pkg/repocli/client.go index 5f55d95..396cf21 100644 --- a/pkg/repocli/client.go +++ b/pkg/repocli/client.go @@ -1,3 +1,12 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/copywctx.go b/pkg/repocli/copywctx.go index b9a8acf..a46e1a2 100644 --- a/pkg/repocli/copywctx.go +++ b/pkg/repocli/copywctx.go @@ -1,3 +1,12 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/copywctx_test.go b/pkg/repocli/copywctx_test.go index b6c991e..12355bf 100644 --- a/pkg/repocli/copywctx_test.go +++ b/pkg/repocli/copywctx_test.go @@ -1,3 +1,12 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/delblob.go b/pkg/repocli/delblob.go index 68bd10d..262f4e1 100644 --- a/pkg/repocli/delblob.go +++ b/pkg/repocli/delblob.go @@ -1,3 +1,12 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/delman.go b/pkg/repocli/delman.go index 46a79ce..ec0a7c7 100644 --- a/pkg/repocli/delman.go +++ b/pkg/repocli/delman.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/getblob.go b/pkg/repocli/getblob.go index f241327..f285980 100644 --- a/pkg/repocli/getblob.go +++ b/pkg/repocli/getblob.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/getblob_test.go b/pkg/repocli/getblob_test.go index ac1657a..719884b 100644 --- a/pkg/repocli/getblob_test.go +++ b/pkg/repocli/getblob_test.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/getcatalog.go b/pkg/repocli/getcatalog.go index 58c43f7..14c0756 100644 --- a/pkg/repocli/getcatalog.go +++ b/pkg/repocli/getcatalog.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/getman.go b/pkg/repocli/getman.go index 1efef8d..8af6a92 100644 --- a/pkg/repocli/getman.go +++ b/pkg/repocli/getman.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/getman_test.go b/pkg/repocli/getman_test.go index 7f9c527..e976c66 100644 --- a/pkg/repocli/getman_test.go +++ b/pkg/repocli/getman_test.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/getreferers.go b/pkg/repocli/getreferers.go index 55a63d2..422febc 100644 --- a/pkg/repocli/getreferers.go +++ b/pkg/repocli/getreferers.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/gettags.go b/pkg/repocli/gettags.go index b72d3b4..b142a82 100644 --- a/pkg/repocli/gettags.go +++ b/pkg/repocli/gettags.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/gettoken.go b/pkg/repocli/gettoken.go index a6987a6..1390034 100644 --- a/pkg/repocli/gettoken.go +++ b/pkg/repocli/gettoken.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/gettoken_test.go b/pkg/repocli/gettoken_test.go index 0272cc7..812fcf3 100644 --- a/pkg/repocli/gettoken_test.go +++ b/pkg/repocli/gettoken_test.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/getupload.go b/pkg/repocli/getupload.go index 7dc4f53..0794fc4 100644 --- a/pkg/repocli/getupload.go +++ b/pkg/repocli/getupload.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/getupload_test.go b/pkg/repocli/getupload_test.go index 3e0e253..8e9fb17 100644 --- a/pkg/repocli/getupload_test.go +++ b/pkg/repocli/getupload_test.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/imager.go b/pkg/repocli/imager.go index a13f74b..50be0a2 100644 --- a/pkg/repocli/imager.go +++ b/pkg/repocli/imager.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/imager_test.go b/pkg/repocli/imager_test.go index ae643fa..0c4a862 100644 --- a/pkg/repocli/imager_test.go +++ b/pkg/repocli/imager_test.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/manexist.go b/pkg/repocli/manexist.go index b5aa679..d326a13 100644 --- a/pkg/repocli/manexist.go +++ b/pkg/repocli/manexist.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/manexist_test.go b/pkg/repocli/manexist_test.go index 93d4e4d..ba98ec7 100644 --- a/pkg/repocli/manexist_test.go +++ b/pkg/repocli/manexist_test.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/patchupload.go b/pkg/repocli/patchupload.go index 9b64980..9aa5cea 100644 --- a/pkg/repocli/patchupload.go +++ b/pkg/repocli/patchupload.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/pullimage.go b/pkg/repocli/pullimage.go index 9290317..b5e7553 100644 --- a/pkg/repocli/pullimage.go +++ b/pkg/repocli/pullimage.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/pullimage_test.go b/pkg/repocli/pullimage_test.go index c6742bb..28fcccf 100644 --- a/pkg/repocli/pullimage_test.go +++ b/pkg/repocli/pullimage_test.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/pushimage.go b/pkg/repocli/pushimage.go index 0030d87..c188013 100644 --- a/pkg/repocli/pushimage.go +++ b/pkg/repocli/pushimage.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/pushimage_test.go b/pkg/repocli/pushimage_test.go index 492c9c5..b810130 100644 --- a/pkg/repocli/pushimage_test.go +++ b/pkg/repocli/pushimage_test.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/putman.go b/pkg/repocli/putman.go index 6d6fc6b..2216cfc 100644 --- a/pkg/repocli/putman.go +++ b/pkg/repocli/putman.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/putupload.go b/pkg/repocli/putupload.go index 9ea895a..b12996e 100644 --- a/pkg/repocli/putupload.go +++ b/pkg/repocli/putupload.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/referer.go b/pkg/repocli/referer.go index 72b240c..fe13ae4 100644 --- a/pkg/repocli/referer.go +++ b/pkg/repocli/referer.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/referer_test.go b/pkg/repocli/referer_test.go index eeb63e2..9af1c4d 100644 --- a/pkg/repocli/referer_test.go +++ b/pkg/repocli/referer_test.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import ( diff --git a/pkg/repocli/uuid.go b/pkg/repocli/uuid.go index d79621f..590f4db 100644 --- a/pkg/repocli/uuid.go +++ b/pkg/repocli/uuid.go @@ -1,3 +1,13 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 repocli import (