Skip to content

Commit 461d8b5

Browse files
authored
Fix some RPM registry flaws (#28782)
Related #26984 (#26984 (comment)) Fix admin cleanup message. Fix models `Get` not respecting default values. Rebuild RPM repository files after cleanup. Do not add RPM group to package version name. Force stable sorting of Alpine/Debian/RPM repository data. Fix missing deferred `Close`. Add tests for multiple RPM groups. Removed non-cached `ReplaceAllStringRegex`. If there are multiple groups available, it's stated in the package installation screen: ![grafik](https://github.com/go-gitea/gitea/assets/1666336/8f132760-882c-4ab8-9678-77e47dfc4415)
1 parent 075c4c8 commit 461d8b5

File tree

18 files changed

+659
-503
lines changed

18 files changed

+659
-503
lines changed

docs/content/usage/packages/rpm.en-us.md

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,34 @@ The following examples use `dnf`.
2424

2525
## Configuring the package registry
2626

27-
To register the RPM registry add the url to the list of known apt sources:
27+
To register the RPM registry add the url to the list of known sources:
2828

2929
```shell
3030
dnf config-manager --add-repo https://gitea.example.com/api/packages/{owner}/rpm/{group}.repo
3131
```
3232

33-
| Placeholder | Description |
34-
| ----------- |----------------------------------------------------|
35-
| `owner` | The owner of the package. |
36-
| `group` | Everything, e.g. `el7`, `rocky/el9` , `test/fc38`.|
33+
| Placeholder | Description |
34+
| ----------- | ----------- |
35+
| `owner` | The owner of the package. |
36+
| `group` | Optional: Everything, e.g. empty, `el7`, `rocky/el9`, `test/fc38`. |
37+
38+
Example:
39+
40+
```shell
41+
# without a group
42+
dnf config-manager --add-repo https://gitea.example.com/api/packages/testuser/rpm.repo
43+
44+
# with the group 'centos/el7'
45+
dnf config-manager --add-repo https://gitea.example.com/api/packages/testuser/rpm/centos/el7.repo
46+
```
3747

3848
If the registry is private, provide credentials in the url. You can use a password or a [personal access token](development/api-usage.md#authentication):
3949

4050
```shell
4151
dnf config-manager --add-repo https://{username}:{your_password_or_token}@gitea.example.com/api/packages/{owner}/rpm/{group}.repo
4252
```
4353

44-
You have to add the credentials to the urls in the `rpm.repo` file in `/etc/yum.repos.d` too.
54+
You have to add the credentials to the urls in the created `.repo` file in `/etc/yum.repos.d` too.
4555

4656
## Publish a package
4757

@@ -54,11 +64,17 @@ PUT https://gitea.example.com/api/packages/{owner}/rpm/{group}/upload
5464
| Parameter | Description |
5565
| --------- | ----------- |
5666
| `owner` | The owner of the package. |
57-
| `group` | Everything, e.g. `el7`, `rocky/el9` , `test/fc38`.|
67+
| `group` | Optional: Everything, e.g. empty, `el7`, `rocky/el9`, `test/fc38`. |
5868

5969
Example request using HTTP Basic authentication:
6070

6171
```shell
72+
# without a group
73+
curl --user your_username:your_password_or_token \
74+
--upload-file path/to/file.rpm \
75+
https://gitea.example.com/api/packages/testuser/rpm/upload
76+
77+
# with the group 'centos/el7'
6278
curl --user your_username:your_password_or_token \
6379
--upload-file path/to/file.rpm \
6480
https://gitea.example.com/api/packages/testuser/rpm/centos/el7/upload
@@ -83,17 +99,22 @@ To delete an RPM package perform a HTTP DELETE operation. This will delete the p
8399
DELETE https://gitea.example.com/api/packages/{owner}/rpm/{group}/package/{package_name}/{package_version}/{architecture}
84100
```
85101

86-
| Parameter | Description |
87-
|-------------------|----------------------------|
88-
| `owner` | The owner of the package. |
89-
| `group` | The package group . |
90-
| `package_name` | The package name. |
91-
| `package_version` | The package version. |
92-
| `architecture` | The package architecture. |
102+
| Parameter | Description |
103+
| ----------------- | ----------- |
104+
| `owner` | The owner of the package. |
105+
| `group` | Optional: The package group. |
106+
| `package_name` | The package name. |
107+
| `package_version` | The package version. |
108+
| `architecture` | The package architecture. |
93109

94110
Example request using HTTP Basic authentication:
95111

96112
```shell
113+
# without a group
114+
curl --user your_username:your_token_or_password -X DELETE \
115+
https://gitea.example.com/api/packages/testuser/rpm/package/test-package/1.0.0/x86_64
116+
117+
# with the group 'centos/el7'
97118
curl --user your_username:your_token_or_password -X DELETE \
98119
https://gitea.example.com/api/packages/testuser/rpm/centos/el7/package/test-package/1.0.0/x86_64
99120
```

models/packages/package.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -191,18 +191,18 @@ type Package struct {
191191
func TryInsertPackage(ctx context.Context, p *Package) (*Package, error) {
192192
e := db.GetEngine(ctx)
193193

194-
key := &Package{
195-
OwnerID: p.OwnerID,
196-
Type: p.Type,
197-
LowerName: p.LowerName,
198-
}
194+
existing := &Package{}
199195

200-
has, err := e.Get(key)
196+
has, err := e.Where(builder.Eq{
197+
"owner_id": p.OwnerID,
198+
"type": p.Type,
199+
"lower_name": p.LowerName,
200+
}).Get(existing)
201201
if err != nil {
202202
return nil, err
203203
}
204204
if has {
205-
return key, ErrDuplicatePackage
205+
return existing, ErrDuplicatePackage
206206
}
207207
if _, err = e.Insert(p); err != nil {
208208
return nil, err

models/packages/package_blob.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,20 @@ type PackageBlob struct {
4141
func GetOrInsertBlob(ctx context.Context, pb *PackageBlob) (*PackageBlob, bool, error) {
4242
e := db.GetEngine(ctx)
4343

44-
has, err := e.Get(pb)
44+
existing := &PackageBlob{}
45+
46+
has, err := e.Where(builder.Eq{
47+
"size": pb.Size,
48+
"hash_md5": pb.HashMD5,
49+
"hash_sha1": pb.HashSHA1,
50+
"hash_sha256": pb.HashSHA256,
51+
"hash_sha512": pb.HashSHA512,
52+
}).Get(existing)
4553
if err != nil {
4654
return nil, false, err
4755
}
4856
if has {
49-
return pb, true, nil
57+
return existing, true, nil
5058
}
5159
if _, err = e.Insert(pb); err != nil {
5260
return nil, false, err

models/packages/package_file.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,18 @@ type PackageFile struct {
4646
func TryInsertFile(ctx context.Context, pf *PackageFile) (*PackageFile, error) {
4747
e := db.GetEngine(ctx)
4848

49-
key := &PackageFile{
50-
VersionID: pf.VersionID,
51-
LowerName: pf.LowerName,
52-
CompositeKey: pf.CompositeKey,
53-
}
49+
existing := &PackageFile{}
5450

55-
has, err := e.Get(key)
51+
has, err := e.Where(builder.Eq{
52+
"version_id": pf.VersionID,
53+
"lower_name": pf.LowerName,
54+
"composite_key": pf.CompositeKey,
55+
}).Get(existing)
5656
if err != nil {
5757
return nil, err
5858
}
5959
if has {
60-
return pf, ErrDuplicatePackageFile
60+
return existing, ErrDuplicatePackageFile
6161
}
6262
if _, err = e.Insert(pf); err != nil {
6363
return nil, err
@@ -93,13 +93,13 @@ func GetFileForVersionByName(ctx context.Context, versionID int64, name, key str
9393
return nil, ErrPackageFileNotExist
9494
}
9595

96-
pf := &PackageFile{
97-
VersionID: versionID,
98-
LowerName: strings.ToLower(name),
99-
CompositeKey: key,
100-
}
96+
pf := &PackageFile{}
10197

102-
has, err := db.GetEngine(ctx).Get(pf)
98+
has, err := db.GetEngine(ctx).Where(builder.Eq{
99+
"version_id": versionID,
100+
"lower_name": strings.ToLower(name),
101+
"composite_key": key,
102+
}).Get(pf)
103103
if err != nil {
104104
return nil, err
105105
}

models/packages/package_version.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,17 @@ type PackageVersion struct {
3939
func GetOrInsertVersion(ctx context.Context, pv *PackageVersion) (*PackageVersion, error) {
4040
e := db.GetEngine(ctx)
4141

42-
key := &PackageVersion{
43-
PackageID: pv.PackageID,
44-
LowerVersion: pv.LowerVersion,
45-
}
42+
existing := &PackageVersion{}
4643

47-
has, err := e.Get(key)
44+
has, err := e.Where(builder.Eq{
45+
"package_id": pv.PackageID,
46+
"lower_version": pv.LowerVersion,
47+
}).Get(existing)
4848
if err != nil {
4949
return nil, err
5050
}
5151
if has {
52-
return key, ErrDuplicatePackageVersion
52+
return existing, ErrDuplicatePackageVersion
5353
}
5454
if _, err = e.Insert(pv); err != nil {
5555
return nil, err

models/packages/rpm/search.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package rpm
5+
6+
import (
7+
"context"
8+
9+
packages_model "code.gitea.io/gitea/models/packages"
10+
rpm_module "code.gitea.io/gitea/modules/packages/rpm"
11+
)
12+
13+
// GetGroups gets all available groups
14+
func GetGroups(ctx context.Context, ownerID int64) ([]string, error) {
15+
return packages_model.GetDistinctPropertyValues(
16+
ctx,
17+
packages_model.TypeRpm,
18+
ownerID,
19+
packages_model.PropertyTypeFile,
20+
rpm_module.PropertyGroup,
21+
nil,
22+
)
23+
}

modules/packages/rpm/metadata.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ import (
1515
)
1616

1717
const (
18-
PropertyMetadata = "rpm.metadata"
18+
PropertyMetadata = "rpm.metadata"
19+
PropertyGroup = "rpm.group"
20+
PropertyArchitecture = "rpm.architecture"
21+
1922
SettingKeyPrivate = "rpm.key.private"
2023
SettingKeyPublic = "rpm.key.public"
2124

modules/templates/util_string.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
package templates
55

66
import (
7-
"regexp"
87
"strings"
98

109
"code.gitea.io/gitea/modules/base"
@@ -26,10 +25,6 @@ func (su *StringUtils) Contains(s, substr string) bool {
2625
return strings.Contains(s, substr)
2726
}
2827

29-
func (su *StringUtils) ReplaceAllStringRegex(s, regex, new string) string {
30-
return regexp.MustCompile(regex).ReplaceAllString(s, new)
31-
}
32-
3328
func (su *StringUtils) Split(s, sep string) []string {
3429
return strings.Split(s, sep)
3530
}

modules/util/slice.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package util
55

66
import (
7+
"cmp"
78
"slices"
89
"strings"
910
)
@@ -45,3 +46,10 @@ func SliceSortedEqual[T comparable](s1, s2 []T) bool {
4546
func SliceRemoveAll[T comparable](slice []T, target T) []T {
4647
return slices.DeleteFunc(slice, func(t T) bool { return t == target })
4748
}
49+
50+
// Sorted returns the sorted slice
51+
// Note: The parameter is sorted inline.
52+
func Sorted[S ~[]E, E cmp.Ordered](values S) S {
53+
slices.Sort(values)
54+
return values
55+
}

options/locale/locale_en-US.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3414,6 +3414,9 @@ rpm.registry = Setup this registry from the command line:
34143414
rpm.distros.redhat = on RedHat based distributions
34153415
rpm.distros.suse = on SUSE based distributions
34163416
rpm.install = To install the package, run the following command:
3417+
rpm.repository = Repository Info
3418+
rpm.repository.architectures = Architectures
3419+
rpm.repository.multiple_groups = This package is available in multiple groups.
34173420
rubygems.install = To install the package using gem, run the following command:
34183421
rubygems.install2 = or add it to the Gemfile:
34193422
rubygems.dependencies.runtime = Runtime Dependencies

0 commit comments

Comments
 (0)