44package user
55
66import (
7+ "code.gitea.io/gitea/modules/json"
8+ packages_module "code.gitea.io/gitea/modules/packages"
9+ container_module "code.gitea.io/gitea/modules/packages/container"
10+ gocontext "context"
11+ "errors"
12+ oci "github.com/opencontainers/image-spec/specs-go/v1"
13+ "io"
714 "net/http"
815 "net/url"
916
@@ -162,13 +169,55 @@ func RedirectToLastVersion(ctx *context.Context) {
162169 ctx .Redirect (pd .VersionWebLink ())
163170}
164171
172+ func viewPackageContainerImage (ctx gocontext.Context , pd * packages_model.PackageDescriptor , digest string ) (* container_module.Metadata , error ) {
173+ manifestBlob , err := container_model .GetContainerBlob (ctx , & container_model.BlobSearchOptions {
174+ OwnerID : pd .Owner .ID ,
175+ Image : pd .Package .LowerName ,
176+ Digest : digest ,
177+ })
178+ if err != nil {
179+ return nil , err
180+ }
181+ subManifestStream , err := packages_service .OpenPackageBlobStream (manifestBlob .Blob )
182+ if err != nil {
183+ return nil , err
184+ }
185+ defer subManifestStream .Close ()
186+
187+ buf , err := io .ReadAll (subManifestStream )
188+ if err != nil {
189+ return nil , err
190+ }
191+ var manifest oci.Manifest
192+ if err := json .Unmarshal (buf , & manifest ); err != nil {
193+ return nil , err
194+ }
195+ configDescriptor , err := container_model .GetContainerBlob (ctx , & container_model.BlobSearchOptions {
196+ OwnerID : pd .Owner .ID ,
197+ Image : pd .Package .LowerName ,
198+ Digest : string (manifest .Config .Digest ),
199+ })
200+ if err != nil {
201+ return nil , err
202+ }
203+
204+ configReader , err := packages_module .NewContentStore ().OpenBlob (packages_module .BlobHash256Key (configDescriptor .Blob .HashSHA256 ))
205+ if err != nil {
206+ return nil , err
207+ }
208+ defer configReader .Close ()
209+
210+ return container_module .ParseImageConfig (manifest .Config .MediaType , configReader )
211+ }
212+
165213// ViewPackageVersion displays a single package version
166214func ViewPackageVersion (ctx * context.Context ) {
167215 if _ , err := shared_user .RenderUserOrgHeader (ctx ); err != nil {
168216 ctx .ServerError ("RenderUserOrgHeader" , err )
169217 return
170218 }
171219
220+ versionSub := ctx .PathParam ("version_sub" )
172221 pd := ctx .Package .Descriptor
173222 ctx .Data ["Title" ] = pd .Package .Name
174223 ctx .Data ["IsPackagesPage" ] = true
@@ -180,6 +229,9 @@ func ViewPackageVersion(ctx *context.Context) {
180229 }
181230 ctx .Data ["PackageRegistryHost" ] = registryHostURL .Host
182231
232+ var pvs []* packages_model.PackageVersion
233+ pvsTotal := int64 (0 )
234+
183235 switch pd .Package .Type {
184236 case packages_model .TypeAlpine :
185237 branches := make (container.Set [string ])
@@ -257,21 +309,26 @@ func ViewPackageVersion(ctx *context.Context) {
257309
258310 ctx .Data ["Groups" ] = util .Sorted (groups .Values ())
259311 ctx .Data ["Architectures" ] = util .Sorted (architectures .Values ())
260- }
261-
262- var (
263- total int64
264- pvs []* packages_model.PackageVersion
265- )
266- switch pd .Package .Type {
267312 case packages_model .TypeContainer :
268- pvs , total , err = container_model .SearchImageTags (ctx , & container_model.ImageTagsSearchOptions {
313+ pvs , pvsTotal , err = container_model .SearchImageTags (ctx , & container_model.ImageTagsSearchOptions {
269314 Paginator : db .NewAbsoluteListOptions (0 , 5 ),
270315 PackageID : pd .Package .ID ,
271316 IsTagged : true ,
272317 })
318+ ctx .Data ["ContainerImageMetadata" ] = pd .Metadata
319+ if versionSub != "" {
320+ imageMeta , err := viewPackageContainerImage (ctx , pd , versionSub )
321+ if errors .Is (err , util .ErrNotExist ) {
322+ ctx .NotFound (nil )
323+ return
324+ } else if err != nil {
325+ ctx .ServerError ("viewPackageContainerImage" , err )
326+ return
327+ }
328+ ctx .Data ["ContainerImageMetadata" ] = imageMeta
329+ }
273330 default :
274- pvs , total , err = packages_model .SearchVersions (ctx , & packages_model.PackageSearchOptions {
331+ pvs , pvsTotal , err = packages_model .SearchVersions (ctx , & packages_model.PackageSearchOptions {
275332 Paginator : db .NewAbsoluteListOptions (0 , 5 ),
276333 PackageID : pd .Package .ID ,
277334 IsInternal : optional .Some (false ),
@@ -283,7 +340,7 @@ func ViewPackageVersion(ctx *context.Context) {
283340 }
284341
285342 ctx .Data ["LatestVersions" ] = pvs
286- ctx .Data ["TotalVersionCount" ] = total
343+ ctx .Data ["TotalVersionCount" ] = pvsTotal
287344
288345 ctx .Data ["CanWritePackages" ] = ctx .Package .AccessMode >= perm .AccessModeWrite || ctx .IsUserSiteAdmin ()
289346
0 commit comments