mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-24 23:33:33 +01:00
751028549d
Backport #26192 by @KN4CK3R Fixes #25918 The migration fails on MSSQL because xorm tries to update the primary key column. xorm prevents this if the column is marked as auto increment:c622cdaf89/internal/statements/update.go (L38-L40)
I think it would be better if xorm would check for primary key columns here because updating such columns is bad practice. It looks like if that auto increment check should do the same. fyi @lunny Co-authored-by: KN4CK3R <admin@oldschoolhack.me> (cherry picked from commitecfbcced46
)
135 lines
4.1 KiB
Go
135 lines
4.1 KiB
Go
// Copyright 2023 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package v1_20 //nolint
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"code.gitea.io/gitea/modules/json"
|
|
|
|
"xorm.io/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
|
|
|
|
new := &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(new)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
pv.MetadataJSON = string(metadataJSON)
|
|
|
|
if _, err := sess.ID(pv.ID).Update(pv); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return sess.Commit()
|
|
}
|