Fix Alpine Registry packages with noarch not being found (#2285)

Fixes #2173
~~Still requires a bit of work to do, I'm not 100% happy with this solution.~~

The idea is to copy the noarch package to the architectures available in the package repository.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/2285
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Alexandre Oliveira <me+codeberg@aoalmeida.com>
Co-committed-by: Alexandre Oliveira <me+codeberg@aoalmeida.com>
This commit is contained in:
Alexandre Oliveira 2024-02-11 18:02:56 +00:00 committed by Earl Warren
parent 7b4dba3aa0
commit 29007c09bd
2 changed files with 337 additions and 40 deletions

View file

@ -14,6 +14,7 @@ import (
"strings"
packages_model "code.gitea.io/gitea/models/packages"
alpine_model "code.gitea.io/gitea/models/packages/alpine"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/json"
packages_module "code.gitea.io/gitea/modules/packages"
@ -30,6 +31,53 @@ func apiError(ctx *context.Context, status int, obj any) {
})
}
func createOrAddToExisting(ctx *context.Context, pck *alpine_module.Package, branch, repository, architecture string, buf packages_module.HashedSizeReader, fileMetadataRaw []byte) {
_, _, err := packages_service.CreatePackageOrAddFileToExisting(
ctx,
&packages_service.PackageCreationInfo{
PackageInfo: packages_service.PackageInfo{
Owner: ctx.Package.Owner,
PackageType: packages_model.TypeAlpine,
Name: pck.Name,
Version: pck.Version,
},
Creator: ctx.Doer,
Metadata: pck.VersionMetadata,
},
&packages_service.PackageFileCreationInfo{
PackageFileInfo: packages_service.PackageFileInfo{
Filename: fmt.Sprintf("%s-%s.apk", pck.Name, pck.Version),
CompositeKey: fmt.Sprintf("%s|%s|%s", branch, repository, architecture),
},
Creator: ctx.Doer,
Data: buf,
IsLead: true,
Properties: map[string]string{
alpine_module.PropertyBranch: branch,
alpine_module.PropertyRepository: repository,
alpine_module.PropertyArchitecture: architecture,
alpine_module.PropertyMetadata: string(fileMetadataRaw),
},
},
)
if err != nil {
switch err {
case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile:
apiError(ctx, http.StatusConflict, err)
case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
apiError(ctx, http.StatusForbidden, err)
default:
apiError(ctx, http.StatusInternalServerError, err)
}
return
}
if err := alpine_service.BuildSpecificRepositoryFiles(ctx, ctx.Package.Owner.ID, branch, repository, pck.FileMetadata.Architecture); err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
}
}
func GetRepositoryKey(ctx *context.Context) {
_, pub, err := alpine_service.GetOrCreateKeyPair(ctx, ctx.Package.Owner.ID)
if err != nil {
@ -133,49 +181,36 @@ func UploadPackageFile(ctx *context.Context) {
return
}
_, _, err = packages_service.CreatePackageOrAddFileToExisting(
ctx,
&packages_service.PackageCreationInfo{
PackageInfo: packages_service.PackageInfo{
Owner: ctx.Package.Owner,
PackageType: packages_model.TypeAlpine,
Name: pck.Name,
Version: pck.Version,
},
Creator: ctx.Doer,
Metadata: pck.VersionMetadata,
},
&packages_service.PackageFileCreationInfo{
PackageFileInfo: packages_service.PackageFileInfo{
Filename: fmt.Sprintf("%s-%s.apk", pck.Name, pck.Version),
CompositeKey: fmt.Sprintf("%s|%s|%s", branch, repository, pck.FileMetadata.Architecture),
},
Creator: ctx.Doer,
Data: buf,
IsLead: true,
Properties: map[string]string{
alpine_module.PropertyBranch: branch,
alpine_module.PropertyRepository: repository,
alpine_module.PropertyArchitecture: pck.FileMetadata.Architecture,
alpine_module.PropertyMetadata: string(fileMetadataRaw),
},
},
)
if err != nil {
switch err {
case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile:
apiError(ctx, http.StatusConflict, err)
case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
apiError(ctx, http.StatusForbidden, err)
default:
// Check whether the package being uploaded has no architecture defined.
// If true, loop through the available architectures in the repo and create
// the package file for the each architecture. If there are no architectures
// available on the repository, fallback to x86_64
if pck.FileMetadata.Architecture == "noarch" {
architectures, err := alpine_model.GetArchitectures(ctx, ctx.Package.Owner.ID, repository)
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
}
return
}
if err := alpine_service.BuildSpecificRepositoryFiles(ctx, ctx.Package.Owner.ID, branch, repository, pck.FileMetadata.Architecture); err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
if len(architectures) == 0 {
architectures = []string{
"x86_64",
}
}
for _, arch := range architectures {
pck.FileMetadata.Architecture = arch
fileMetadataRaw, err := json.Marshal(pck.FileMetadata)
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
}
createOrAddToExisting(ctx, pck, branch, repository, pck.FileMetadata.Architecture, buf, fileMetadataRaw)
}
} else {
createOrAddToExisting(ctx, pck, branch, repository, pck.FileMetadata.Architecture, buf, fileMetadataRaw)
}
ctx.Status(http.StatusCreated)