Skip to content

Refactor container and UI (#34736) #34739

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: release/v1.24
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions models/packages/container/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
package container

const (
ContentTypeDockerDistributionManifestV2 = "application/vnd.docker.distribution.manifest.v2+json"

ManifestFilename = "manifest.json"
UploadVersion = "_upload"
)
8 changes: 5 additions & 3 deletions models/packages/container/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type BlobSearchOptions struct {
Digest string
Tag string
IsManifest bool
OnlyLead bool
Repository string
}

Expand All @@ -45,6 +46,9 @@ func (opts *BlobSearchOptions) toConds() builder.Cond {
if opts.IsManifest {
cond = cond.And(builder.Eq{"package_file.lower_name": ManifestFilename})
}
if opts.OnlyLead {
cond = cond.And(builder.Eq{"package_file.is_lead": true})
}
if opts.Digest != "" {
var propsCond builder.Cond = builder.Eq{
"package_property.ref_type": packages.PropertyTypeFile,
Expand Down Expand Up @@ -73,11 +77,9 @@ func GetContainerBlob(ctx context.Context, opts *BlobSearchOptions) (*packages.P
pfds, err := getContainerBlobsLimit(ctx, opts, 1)
if err != nil {
return nil, err
}
if len(pfds) != 1 {
} else if len(pfds) == 0 {
return nil, ErrContainerBlobNotExist
}

return pfds[0], nil
}

Expand Down
5 changes: 5 additions & 0 deletions models/packages/package_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ func DeleteFileByID(ctx context.Context, fileID int64) error {
return err
}

func UpdateFile(ctx context.Context, pf *PackageFile, cols []string) error {
_, err := db.GetEngine(ctx).ID(pf.ID).Cols(cols...).Update(pf)
return err
}

// PackageFileSearchOptions are options for SearchXXX methods
type PackageFileSearchOptions struct {
OwnerID int64
Expand Down
14 changes: 14 additions & 0 deletions models/packages/package_property.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,20 @@ func UpdateProperty(ctx context.Context, pp *PackageProperty) error {
return err
}

func InsertOrUpdateProperty(ctx context.Context, refType PropertyType, refID int64, name, value string) error {
pp := PackageProperty{RefType: refType, RefID: refID, Name: name}
ok, err := db.GetEngine(ctx).Get(&pp)
if err != nil {
return err
}
if ok {
_, err = db.GetEngine(ctx).Where("ref_type=? AND ref_id=? AND name=?", refType, refID, name).Cols("value").Update(&PackageProperty{Value: value})
return err
}
_, err = InsertProperty(ctx, refType, refID, name, value)
return err
}

// DeleteAllProperties deletes all properties of a ref
func DeleteAllProperties(ctx context.Context, refType PropertyType, refID int64) error {
_, err := db.GetEngine(ctx).Where("ref_type = ? AND ref_id = ?", refType, refID).Delete(&PackageProperty{})
Expand Down
14 changes: 7 additions & 7 deletions routers/api/packages/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -701,18 +701,18 @@ func ContainerRoutes() *web.Router {
r.Get("/_catalog", container.ReqContainerAccess, container.GetRepositoryList)
r.Group("/{username}", func() {
r.PathGroup("/*", func(g *web.RouterPathGroup) {
g.MatchPath("POST", "/<image:*>/blobs/uploads", reqPackageAccess(perm.AccessModeWrite), container.VerifyImageName, container.InitiateUploadBlob)
g.MatchPath("GET", "/<image:*>/tags/list", container.VerifyImageName, container.GetTagList)
g.MatchPath("POST", "/<image:*>/blobs/uploads", reqPackageAccess(perm.AccessModeWrite), container.VerifyImageName, container.PostBlobsUploads)
g.MatchPath("GET", "/<image:*>/tags/list", container.VerifyImageName, container.GetTagsList)
g.MatchPath("GET,PATCH,PUT,DELETE", `/<image:*>/blobs/uploads/<uuid:[-.=\w]+>`, reqPackageAccess(perm.AccessModeWrite), container.VerifyImageName, func(ctx *context.Context) {
switch ctx.Req.Method {
case http.MethodGet:
container.GetUploadBlob(ctx)
container.GetBlobsUpload(ctx)
case http.MethodPatch:
container.UploadBlob(ctx)
container.PatchBlobsUpload(ctx)
case http.MethodPut:
container.EndUploadBlob(ctx)
container.PutBlobsUpload(ctx)
default: /* DELETE */
container.CancelUploadBlob(ctx)
container.DeleteBlobsUpload(ctx)
}
})
g.MatchPath("HEAD", `/<image:*>/blobs/<digest>`, container.VerifyImageName, container.HeadBlob)
Expand All @@ -721,7 +721,7 @@ func ContainerRoutes() *web.Router {

g.MatchPath("HEAD", `/<image:*>/manifests/<reference>`, container.VerifyImageName, container.HeadManifest)
g.MatchPath("GET", `/<image:*>/manifests/<reference>`, container.VerifyImageName, container.GetManifest)
g.MatchPath("PUT", `/<image:*>/manifests/<reference>`, container.VerifyImageName, reqPackageAccess(perm.AccessModeWrite), container.UploadManifest)
g.MatchPath("PUT", `/<image:*>/manifests/<reference>`, container.VerifyImageName, reqPackageAccess(perm.AccessModeWrite), container.PutManifest)
g.MatchPath("DELETE", `/<image:*>/manifests/<reference>`, container.VerifyImageName, reqPackageAccess(perm.AccessModeWrite), container.DeleteManifest)
})
}, container.ReqContainerAccess, context.UserAssignmentWeb(), context.PackageAssignment(), reqPackageAccess(perm.AccessModeRead))
Expand Down
6 changes: 4 additions & 2 deletions routers/api/packages/container/blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
container_module "code.gitea.io/gitea/modules/packages/container"
"code.gitea.io/gitea/modules/util"
packages_service "code.gitea.io/gitea/services/packages"

"github.com/opencontainers/go-digest"
)

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

func deleteBlob(ctx context.Context, ownerID int64, image, digest string) error {
func deleteBlob(ctx context.Context, ownerID int64, image string, digest digest.Digest) error {
releaser, err := globallock.Lock(ctx, containerPkgName(ownerID, image))
if err != nil {
return err
Expand All @@ -186,7 +188,7 @@ func deleteBlob(ctx context.Context, ownerID int64, image, digest string) error
pfds, err := container_model.GetContainerBlobs(ctx, &container_model.BlobSearchOptions{
OwnerID: ownerID,
Image: image,
Digest: digest,
Digest: string(digest),
})
if err != nil {
return err
Expand Down
34 changes: 16 additions & 18 deletions routers/api/packages/container/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ func GetRepositoryList(ctx *context.Context) {
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#mounting-a-blob-from-another-repository
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#single-post
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks
func InitiateUploadBlob(ctx *context.Context) {
func PostBlobsUploads(ctx *context.Context) {
image := ctx.PathParam("image")

mount := ctx.FormTrim("mount")
Expand Down Expand Up @@ -319,7 +319,7 @@ func InitiateUploadBlob(ctx *context.Context) {
}

// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks
func GetUploadBlob(ctx *context.Context) {
func GetBlobsUpload(ctx *context.Context) {
uuid := ctx.PathParam("uuid")

upload, err := packages_model.GetBlobUploadByID(ctx, uuid)
Expand All @@ -345,7 +345,7 @@ func GetUploadBlob(ctx *context.Context) {

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

uploader, err := container_service.NewBlobUploader(ctx, ctx.PathParam("uuid"))
Expand Down Expand Up @@ -393,7 +393,7 @@ func UploadBlob(ctx *context.Context) {
}

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

digest := ctx.FormTrim("digest")
Expand Down Expand Up @@ -462,7 +462,7 @@ func EndUploadBlob(ctx *context.Context) {
}

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

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

func getBlobFromContext(ctx *context.Context) (*packages_model.PackageFileDescriptor, error) {
d := ctx.PathParam("digest")

if digest.Digest(d).Validate() != nil {
d := digest.Digest(ctx.PathParam("digest"))
if d.Validate() != nil {
return nil, container_model.ErrContainerBlobNotExist
}

return workaroundGetContainerBlob(ctx, &container_model.BlobSearchOptions{
OwnerID: ctx.Package.Owner.ID,
Image: ctx.PathParam("image"),
Digest: d,
Digest: string(d),
})
}

Expand Down Expand Up @@ -535,9 +534,8 @@ func GetBlob(ctx *context.Context) {

// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#deleting-blobs
func DeleteBlob(ctx *context.Context) {
d := ctx.PathParam("digest")

if digest.Digest(d).Validate() != nil {
d := digest.Digest(ctx.PathParam("digest"))
if d.Validate() != nil {
apiErrorDefined(ctx, errBlobUnknown)
return
}
Expand All @@ -553,7 +551,7 @@ func DeleteBlob(ctx *context.Context) {
}

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

mci := &manifestCreationInfo{
Expand Down Expand Up @@ -609,18 +607,18 @@ func UploadManifest(ctx *context.Context) {
}

func getBlobSearchOptionsFromContext(ctx *context.Context) (*container_model.BlobSearchOptions, error) {
reference := ctx.PathParam("reference")

opts := &container_model.BlobSearchOptions{
OwnerID: ctx.Package.Owner.ID,
Image: ctx.PathParam("image"),
IsManifest: true,
}

if digest.Digest(reference).Validate() == nil {
opts.Digest = reference
reference := ctx.PathParam("reference")
if d := digest.Digest(reference); d.Validate() == nil {
opts.Digest = string(d)
} else if referencePattern.MatchString(reference) {
opts.Tag = reference
opts.OnlyLead = true
} else {
return nil, container_model.ErrContainerBlobNotExist
}
Expand Down Expand Up @@ -737,7 +735,7 @@ func serveBlob(ctx *context.Context, pfd *packages_model.PackageFileDescriptor)
}

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

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