code.gitea.io/gitea@v1.21.7/services/packages/container/cleanup.go (about) 1 // Copyright 2022 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package container 5 6 import ( 7 "context" 8 "time" 9 10 packages_model "code.gitea.io/gitea/models/packages" 11 container_model "code.gitea.io/gitea/models/packages/container" 12 container_module "code.gitea.io/gitea/modules/packages/container" 13 "code.gitea.io/gitea/modules/util" 14 packages_service "code.gitea.io/gitea/services/packages" 15 16 digest "github.com/opencontainers/go-digest" 17 ) 18 19 // Cleanup removes expired container data 20 func Cleanup(ctx context.Context, olderThan time.Duration) error { 21 if err := cleanupExpiredBlobUploads(ctx, olderThan); err != nil { 22 return err 23 } 24 return cleanupExpiredUploadedBlobs(ctx, olderThan) 25 } 26 27 // cleanupExpiredBlobUploads removes expired blob uploads 28 func cleanupExpiredBlobUploads(ctx context.Context, olderThan time.Duration) error { 29 pbus, err := packages_model.FindExpiredBlobUploads(ctx, olderThan) 30 if err != nil { 31 return err 32 } 33 34 for _, pbu := range pbus { 35 if err := RemoveBlobUploadByID(ctx, pbu.ID); err != nil { 36 return err 37 } 38 } 39 40 return nil 41 } 42 43 // cleanupExpiredUploadedBlobs removes expired uploaded blobs not referenced by a manifest 44 func cleanupExpiredUploadedBlobs(ctx context.Context, olderThan time.Duration) error { 45 pfs, err := container_model.SearchExpiredUploadedBlobs(ctx, olderThan) 46 if err != nil { 47 return err 48 } 49 50 for _, pf := range pfs { 51 if err := packages_service.DeletePackageFile(ctx, pf); err != nil { 52 return err 53 } 54 } 55 56 pvs, _, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{ 57 Type: packages_model.TypeContainer, 58 Version: packages_model.SearchValue{ 59 ExactMatch: true, 60 Value: container_model.UploadVersion, 61 }, 62 IsInternal: util.OptionalBoolTrue, 63 HasFiles: util.OptionalBoolFalse, 64 }) 65 if err != nil { 66 return err 67 } 68 69 for _, pv := range pvs { 70 if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeVersion, pv.ID); err != nil { 71 return err 72 } 73 74 if err := packages_model.DeleteVersionByID(ctx, pv.ID); err != nil { 75 return err 76 } 77 } 78 79 return nil 80 } 81 82 func ShouldBeSkipped(ctx context.Context, pcr *packages_model.PackageCleanupRule, p *packages_model.Package, pv *packages_model.PackageVersion) (bool, error) { 83 // Always skip the "latest" tag 84 if pv.LowerVersion == "latest" { 85 return true, nil 86 } 87 88 // Check if the version is a digest (or untagged) 89 if digest.Digest(pv.LowerVersion).Validate() == nil { 90 // Check if there is another manifest referencing this version 91 has, err := packages_model.ExistVersion(ctx, &packages_model.PackageSearchOptions{ 92 PackageID: p.ID, 93 Properties: map[string]string{ 94 container_module.PropertyManifestReference: pv.LowerVersion, 95 }, 96 }) 97 if err != nil { 98 return false, err 99 } 100 101 // Skip it if the version is referenced 102 if has { 103 return true, nil 104 } 105 } 106 107 return false, nil 108 }