Skip to content

Commit db3500b

Browse files
authored
Merge branch 'main' into fix-bindata-clean
2 parents 5b1c073 + 6b8b580 commit db3500b

File tree

13 files changed

+188
-105
lines changed

13 files changed

+188
-105
lines changed

models/packages/container/const.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
package container
55

66
const (
7+
ContentTypeDockerDistributionManifestV2 = "application/vnd.docker.distribution.manifest.v2+json"
8+
79
ManifestFilename = "manifest.json"
810
UploadVersion = "_upload"
911
)

models/packages/container/search.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type BlobSearchOptions struct {
2525
Digest string
2626
Tag string
2727
IsManifest bool
28+
OnlyLead bool
2829
Repository string
2930
}
3031

@@ -45,6 +46,9 @@ func (opts *BlobSearchOptions) toConds() builder.Cond {
4546
if opts.IsManifest {
4647
cond = cond.And(builder.Eq{"package_file.lower_name": ManifestFilename})
4748
}
49+
if opts.OnlyLead {
50+
cond = cond.And(builder.Eq{"package_file.is_lead": true})
51+
}
4852
if opts.Digest != "" {
4953
var propsCond builder.Cond = builder.Eq{
5054
"package_property.ref_type": packages.PropertyTypeFile,
@@ -73,11 +77,9 @@ func GetContainerBlob(ctx context.Context, opts *BlobSearchOptions) (*packages.P
7377
pfds, err := getContainerBlobsLimit(ctx, opts, 1)
7478
if err != nil {
7579
return nil, err
76-
}
77-
if len(pfds) != 1 {
80+
} else if len(pfds) == 0 {
7881
return nil, ErrContainerBlobNotExist
7982
}
80-
8183
return pfds[0], nil
8284
}
8385

models/packages/package_file.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ func DeleteFileByID(ctx context.Context, fileID int64) error {
115115
return err
116116
}
117117

118+
func UpdateFile(ctx context.Context, pf *PackageFile, cols []string) error {
119+
_, err := db.GetEngine(ctx).ID(pf.ID).Cols(cols...).Update(pf)
120+
return err
121+
}
122+
118123
// PackageFileSearchOptions are options for SearchXXX methods
119124
type PackageFileSearchOptions struct {
120125
OwnerID int64

models/packages/package_property.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,20 @@ func UpdateProperty(ctx context.Context, pp *PackageProperty) error {
6666
return err
6767
}
6868

69+
func InsertOrUpdateProperty(ctx context.Context, refType PropertyType, refID int64, name, value string) error {
70+
pp := PackageProperty{RefType: refType, RefID: refID, Name: name}
71+
ok, err := db.GetEngine(ctx).Get(&pp)
72+
if err != nil {
73+
return err
74+
}
75+
if ok {
76+
_, err = db.GetEngine(ctx).Where("ref_type=? AND ref_id=? AND name=?", refType, refID, name).Cols("value").Update(&PackageProperty{Value: value})
77+
return err
78+
}
79+
_, err = InsertProperty(ctx, refType, refID, name, value)
80+
return err
81+
}
82+
6983
// DeleteAllProperties deletes all properties of a ref
7084
func DeleteAllProperties(ctx context.Context, refType PropertyType, refID int64) error {
7185
_, err := db.GetEngine(ctx).Where("ref_type = ? AND ref_id = ?", refType, refID).Delete(&PackageProperty{})

routers/api/packages/api.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -701,18 +701,18 @@ func ContainerRoutes() *web.Router {
701701
r.Get("/_catalog", container.ReqContainerAccess, container.GetRepositoryList)
702702
r.Group("/{username}", func() {
703703
r.PathGroup("/*", func(g *web.RouterPathGroup) {
704-
g.MatchPath("POST", "/<image:*>/blobs/uploads", reqPackageAccess(perm.AccessModeWrite), container.VerifyImageName, container.InitiateUploadBlob)
705-
g.MatchPath("GET", "/<image:*>/tags/list", container.VerifyImageName, container.GetTagList)
704+
g.MatchPath("POST", "/<image:*>/blobs/uploads", reqPackageAccess(perm.AccessModeWrite), container.VerifyImageName, container.PostBlobsUploads)
705+
g.MatchPath("GET", "/<image:*>/tags/list", container.VerifyImageName, container.GetTagsList)
706706
g.MatchPath("GET,PATCH,PUT,DELETE", `/<image:*>/blobs/uploads/<uuid:[-.=\w]+>`, reqPackageAccess(perm.AccessModeWrite), container.VerifyImageName, func(ctx *context.Context) {
707707
switch ctx.Req.Method {
708708
case http.MethodGet:
709-
container.GetUploadBlob(ctx)
709+
container.GetBlobsUpload(ctx)
710710
case http.MethodPatch:
711-
container.UploadBlob(ctx)
711+
container.PatchBlobsUpload(ctx)
712712
case http.MethodPut:
713-
container.EndUploadBlob(ctx)
713+
container.PutBlobsUpload(ctx)
714714
default: /* DELETE */
715-
container.CancelUploadBlob(ctx)
715+
container.DeleteBlobsUpload(ctx)
716716
}
717717
})
718718
g.MatchPath("HEAD", `/<image:*>/blobs/<digest>`, container.VerifyImageName, container.HeadBlob)
@@ -721,7 +721,7 @@ func ContainerRoutes() *web.Router {
721721

722722
g.MatchPath("HEAD", `/<image:*>/manifests/<reference>`, container.VerifyImageName, container.HeadManifest)
723723
g.MatchPath("GET", `/<image:*>/manifests/<reference>`, container.VerifyImageName, container.GetManifest)
724-
g.MatchPath("PUT", `/<image:*>/manifests/<reference>`, container.VerifyImageName, reqPackageAccess(perm.AccessModeWrite), container.UploadManifest)
724+
g.MatchPath("PUT", `/<image:*>/manifests/<reference>`, container.VerifyImageName, reqPackageAccess(perm.AccessModeWrite), container.PutManifest)
725725
g.MatchPath("DELETE", `/<image:*>/manifests/<reference>`, container.VerifyImageName, reqPackageAccess(perm.AccessModeWrite), container.DeleteManifest)
726726
})
727727
}, container.ReqContainerAccess, context.UserAssignmentWeb(), context.PackageAssignment(), reqPackageAccess(perm.AccessModeRead))

routers/api/packages/container/blob.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
container_module "code.gitea.io/gitea/modules/packages/container"
2121
"code.gitea.io/gitea/modules/util"
2222
packages_service "code.gitea.io/gitea/services/packages"
23+
24+
"github.com/opencontainers/go-digest"
2325
)
2426

2527
// saveAsPackageBlob creates a package blob from an upload
@@ -175,7 +177,7 @@ func createFileForBlob(ctx context.Context, pv *packages_model.PackageVersion, p
175177
return nil
176178
}
177179

178-
func deleteBlob(ctx context.Context, ownerID int64, image, digest string) error {
180+
func deleteBlob(ctx context.Context, ownerID int64, image string, digest digest.Digest) error {
179181
releaser, err := globallock.Lock(ctx, containerPkgName(ownerID, image))
180182
if err != nil {
181183
return err
@@ -186,7 +188,7 @@ func deleteBlob(ctx context.Context, ownerID int64, image, digest string) error
186188
pfds, err := container_model.GetContainerBlobs(ctx, &container_model.BlobSearchOptions{
187189
OwnerID: ownerID,
188190
Image: image,
189-
Digest: digest,
191+
Digest: string(digest),
190192
})
191193
if err != nil {
192194
return err

routers/api/packages/container/container.go

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ func GetRepositoryList(ctx *context.Context) {
231231
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#mounting-a-blob-from-another-repository
232232
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#single-post
233233
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks
234-
func InitiateUploadBlob(ctx *context.Context) {
234+
func PostBlobsUploads(ctx *context.Context) {
235235
image := ctx.PathParam("image")
236236

237237
mount := ctx.FormTrim("mount")
@@ -313,14 +313,13 @@ func InitiateUploadBlob(ctx *context.Context) {
313313

314314
setResponseHeaders(ctx.Resp, &containerHeaders{
315315
Location: fmt.Sprintf("/v2/%s/%s/blobs/uploads/%s", ctx.Package.Owner.LowerName, image, upload.ID),
316-
Range: "0-0",
317316
UploadUUID: upload.ID,
318317
Status: http.StatusAccepted,
319318
})
320319
}
321320

322-
// https://docs.docker.com/registry/spec/api/#get-blob-upload
323-
func GetUploadBlob(ctx *context.Context) {
321+
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks
322+
func GetBlobsUpload(ctx *context.Context) {
324323
uuid := ctx.PathParam("uuid")
325324

326325
upload, err := packages_model.GetBlobUploadByID(ctx, uuid)
@@ -333,15 +332,20 @@ func GetUploadBlob(ctx *context.Context) {
333332
return
334333
}
335334

336-
setResponseHeaders(ctx.Resp, &containerHeaders{
337-
Range: fmt.Sprintf("0-%d", upload.BytesReceived),
335+
// FIXME: undefined behavior when the uploaded content is empty: https://github.com/opencontainers/distribution-spec/issues/578
336+
respHeaders := &containerHeaders{
338337
UploadUUID: upload.ID,
339338
Status: http.StatusNoContent,
340-
})
339+
}
340+
if upload.BytesReceived > 0 {
341+
respHeaders.Range = fmt.Sprintf("0-%d", upload.BytesReceived-1)
342+
}
343+
setResponseHeaders(ctx.Resp, respHeaders)
341344
}
342345

346+
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#single-post
343347
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks
344-
func UploadBlob(ctx *context.Context) {
348+
func PatchBlobsUpload(ctx *context.Context) {
345349
image := ctx.PathParam("image")
346350

347351
uploader, err := container_service.NewBlobUploader(ctx, ctx.PathParam("uuid"))
@@ -377,16 +381,19 @@ func UploadBlob(ctx *context.Context) {
377381
return
378382
}
379383

380-
setResponseHeaders(ctx.Resp, &containerHeaders{
384+
respHeaders := &containerHeaders{
381385
Location: fmt.Sprintf("/v2/%s/%s/blobs/uploads/%s", ctx.Package.Owner.LowerName, image, uploader.ID),
382-
Range: fmt.Sprintf("0-%d", uploader.Size()-1),
383386
UploadUUID: uploader.ID,
384387
Status: http.StatusAccepted,
385-
})
388+
}
389+
if contentRange != "" {
390+
respHeaders.Range = fmt.Sprintf("0-%d", uploader.Size()-1)
391+
}
392+
setResponseHeaders(ctx.Resp, respHeaders)
386393
}
387394

388395
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks
389-
func EndUploadBlob(ctx *context.Context) {
396+
func PutBlobsUpload(ctx *context.Context) {
390397
image := ctx.PathParam("image")
391398

392399
digest := ctx.FormTrim("digest")
@@ -455,7 +462,7 @@ func EndUploadBlob(ctx *context.Context) {
455462
}
456463

457464
// https://docs.docker.com/registry/spec/api/#delete-blob-upload
458-
func CancelUploadBlob(ctx *context.Context) {
465+
func DeleteBlobsUpload(ctx *context.Context) {
459466
uuid := ctx.PathParam("uuid")
460467

461468
_, err := packages_model.GetBlobUploadByID(ctx, uuid)
@@ -479,16 +486,15 @@ func CancelUploadBlob(ctx *context.Context) {
479486
}
480487

481488
func getBlobFromContext(ctx *context.Context) (*packages_model.PackageFileDescriptor, error) {
482-
d := ctx.PathParam("digest")
483-
484-
if digest.Digest(d).Validate() != nil {
489+
d := digest.Digest(ctx.PathParam("digest"))
490+
if d.Validate() != nil {
485491
return nil, container_model.ErrContainerBlobNotExist
486492
}
487493

488494
return workaroundGetContainerBlob(ctx, &container_model.BlobSearchOptions{
489495
OwnerID: ctx.Package.Owner.ID,
490496
Image: ctx.PathParam("image"),
491-
Digest: d,
497+
Digest: string(d),
492498
})
493499
}
494500

@@ -528,9 +534,8 @@ func GetBlob(ctx *context.Context) {
528534

529535
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#deleting-blobs
530536
func DeleteBlob(ctx *context.Context) {
531-
d := ctx.PathParam("digest")
532-
533-
if digest.Digest(d).Validate() != nil {
537+
d := digest.Digest(ctx.PathParam("digest"))
538+
if d.Validate() != nil {
534539
apiErrorDefined(ctx, errBlobUnknown)
535540
return
536541
}
@@ -546,7 +551,7 @@ func DeleteBlob(ctx *context.Context) {
546551
}
547552

548553
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-manifests
549-
func UploadManifest(ctx *context.Context) {
554+
func PutManifest(ctx *context.Context) {
550555
reference := ctx.PathParam("reference")
551556

552557
mci := &manifestCreationInfo{
@@ -602,18 +607,18 @@ func UploadManifest(ctx *context.Context) {
602607
}
603608

604609
func getBlobSearchOptionsFromContext(ctx *context.Context) (*container_model.BlobSearchOptions, error) {
605-
reference := ctx.PathParam("reference")
606-
607610
opts := &container_model.BlobSearchOptions{
608611
OwnerID: ctx.Package.Owner.ID,
609612
Image: ctx.PathParam("image"),
610613
IsManifest: true,
611614
}
612615

613-
if digest.Digest(reference).Validate() == nil {
614-
opts.Digest = reference
616+
reference := ctx.PathParam("reference")
617+
if d := digest.Digest(reference); d.Validate() == nil {
618+
opts.Digest = string(d)
615619
} else if referencePattern.MatchString(reference) {
616620
opts.Tag = reference
621+
opts.OnlyLead = true
617622
} else {
618623
return nil, container_model.ErrContainerBlobNotExist
619624
}
@@ -730,7 +735,7 @@ func serveBlob(ctx *context.Context, pfd *packages_model.PackageFileDescriptor)
730735
}
731736

732737
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#content-discovery
733-
func GetTagList(ctx *context.Context) {
738+
func GetTagsList(ctx *context.Context) {
734739
image := ctx.PathParam("image")
735740

736741
if _, err := packages_model.GetPackageByName(ctx, ctx.Package.Owner.ID, packages_model.TypeContainer, image); err != nil {

0 commit comments

Comments
 (0)