gitforge/models/gitea_migrations/v1_20/v250.go
Mathieu Fenniak 29eddd311b chore: upgrade to https://code.forgejo.org/xorm/xorm v1.4.0 (#12639)
Upgrade Forgejo to our forked [xorm v1.4.0](https://code.forgejo.org/xorm/xorm/compare/v1.3.9-forgejo.12...v1.4.0), which is now named `code.forgejo.org/xorm/xorm` to reflect the current expectation that it is a permanent fork.  A small number of API changes were made recently in https://code.forgejo.org/xorm/xorm/issues/120 which are accounted for in this PR, in addition to the module rename.

## Checklist

The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).

### Documentation

- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.

### Release notes

- [ ] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [x] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12639
Reviewed-by: Otto <otto@codeberg.org>
2026-05-20 20:20:08 +02:00

135 lines
4.1 KiB
Go

// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_20
import (
"strings"
"forgejo.org/modules/json"
"code.forgejo.org/xorm/xorm"
)
func ChangeContainerMetadataMultiArch(x *xorm.Engine) error {
sess := x.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
return err
}
type PackageVersion struct {
ID int64 `xorm:"pk autoincr"`
MetadataJSON string `xorm:"metadata_json"`
}
type PackageBlob struct{}
// Get all relevant packages (manifest list images have a container.manifest.reference property)
var pvs []*PackageVersion
err := sess.
Table("package_version").
Select("id, metadata_json").
Where("id IN (SELECT DISTINCT ref_id FROM package_property WHERE ref_type = 0 AND name = 'container.manifest.reference')").
Find(&pvs)
if err != nil {
return err
}
type MetadataOld struct {
Type string `json:"type"`
IsTagged bool `json:"is_tagged"`
Platform string `json:"platform,omitempty"`
Description string `json:"description,omitempty"`
Authors []string `json:"authors,omitempty"`
Licenses string `json:"license,omitempty"`
ProjectURL string `json:"project_url,omitempty"`
RepositoryURL string `json:"repository_url,omitempty"`
DocumentationURL string `json:"documentation_url,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
ImageLayers []string `json:"layer_creation,omitempty"`
MultiArch map[string]string `json:"multiarch,omitempty"`
}
type Manifest struct {
Platform string `json:"platform"`
Digest string `json:"digest"`
Size int64 `json:"size"`
}
type MetadataNew struct {
Type string `json:"type"`
IsTagged bool `json:"is_tagged"`
Platform string `json:"platform,omitempty"`
Description string `json:"description,omitempty"`
Authors []string `json:"authors,omitempty"`
Licenses string `json:"license,omitempty"`
ProjectURL string `json:"project_url,omitempty"`
RepositoryURL string `json:"repository_url,omitempty"`
DocumentationURL string `json:"documentation_url,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
ImageLayers []string `json:"layer_creation,omitempty"`
Manifests []*Manifest `json:"manifests,omitempty"`
}
for _, pv := range pvs {
var old *MetadataOld
if err := json.Unmarshal([]byte(pv.MetadataJSON), &old); err != nil {
return err
}
// Calculate the size of every contained manifest
manifests := make([]*Manifest, 0, len(old.MultiArch))
for platform, digest := range old.MultiArch {
size, err := sess.
Table("package_blob").
Join("INNER", "package_file", "package_blob.id = package_file.blob_id").
Join("INNER", "package_version pv", "pv.id = package_file.version_id").
Join("INNER", "package_version pv2", "pv2.package_id = pv.package_id").
Where("pv.lower_version = ? AND pv2.id = ?", strings.ToLower(digest), pv.ID).
SumInt(new(PackageBlob), "size")
if err != nil {
return err
}
manifests = append(manifests, &Manifest{
Platform: platform,
Digest: digest,
Size: size,
})
}
// Convert to new metadata format
newMetadata := &MetadataNew{
Type: old.Type,
IsTagged: old.IsTagged,
Platform: old.Platform,
Description: old.Description,
Authors: old.Authors,
Licenses: old.Licenses,
ProjectURL: old.ProjectURL,
RepositoryURL: old.RepositoryURL,
DocumentationURL: old.DocumentationURL,
Labels: old.Labels,
ImageLayers: old.ImageLayers,
Manifests: manifests,
}
metadataJSON, err := json.Marshal(newMetadata)
if err != nil {
return err
}
pv.MetadataJSON = string(metadataJSON)
if _, err := sess.ID(pv.ID).Update(pv); err != nil {
return err
}
}
return sess.Commit()
}