mirror of
https://github.com/hanzoai/forge.git
synced 2026-10-30 15:00:39 +00:00
Source files keep their SPDX-License-Identifier and Hanzo copyright line; the Gitea, Gogs and LFS Test Server copyrights they used to repeat now live once in NOTICE, alongside LICENSE. The header lint accepts any copyright line above the SPDX line, so it no longer demands an upstream one. Co-authored-by: Hanzo Dev <[email protected]>
135 lines
4.1 KiB
Go
135 lines
4.1 KiB
Go
// Copyright 2026 Hanzo AI, Inc. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package v1_20
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/hanzoai/git/models/db"
|
|
"github.com/hanzoai/git/modules/json"
|
|
)
|
|
|
|
func ChangeContainerMetadataMultiArch(x db.EngineMigration) 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()
|
|
}
|