From c0ddec8a2a4cd348462257e0ceb253daf5692c32 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Sat, 29 Apr 2023 01:06:41 +0300 Subject: [PATCH] Revert "Add Debian package registry" (#24412) Reverts go-gitea/gitea#22854 --- assets/go-licenses.json | 5 - cmd/migrate_storage_test.go | 2 +- custom/conf/app.example.ini | 2 - .../config-cheat-sheet.en-us.md | 1 - .../doc/usage/packages/debian.en-us.md | 134 ------ .../doc/usage/packages/overview.en-us.md | 1 - go.mod | 3 +- go.sum | 2 - models/migrations/migrations.go | 2 - models/migrations/v1_20/v256.go | 23 - models/packages/container/search.go | 11 +- models/packages/debian/search.go | 131 ------ models/packages/descriptor.go | 26 +- models/packages/package.go | 19 +- models/packages/package_file.go | 25 +- models/packages/package_version.go | 6 +- models/user/setting.go | 5 - modules/packages/debian/metadata.go | 216 --------- modules/packages/debian/metadata_test.go | 171 ------- modules/packages/hashed_buffer.go | 22 +- modules/packages/hashed_buffer_test.go | 2 +- modules/packages/nuget/symbol_extractor.go | 2 +- modules/setting/packages.go | 2 - modules/util/filebuffer/file_backed_buffer.go | 5 +- options/locale/locale_en-US.ini | 8 - public/img/svg/gitea-debian.svg | 1 - routers/api/packages/api.go | 19 - routers/api/packages/cargo/cargo.go | 2 +- routers/api/packages/chef/chef.go | 2 +- routers/api/packages/composer/composer.go | 2 +- routers/api/packages/conan/conan.go | 13 +- routers/api/packages/conda/conda.go | 2 +- routers/api/packages/container/blob.go | 8 +- routers/api/packages/container/container.go | 4 +- routers/api/packages/debian/debian.go | 317 ------------- routers/api/packages/generic/generic.go | 2 +- routers/api/packages/helm/helm.go | 2 +- routers/api/packages/maven/maven.go | 2 +- routers/api/packages/npm/npm.go | 2 +- routers/api/packages/nuget/nuget.go | 6 +- routers/api/packages/pub/pub.go | 2 +- routers/api/packages/pypi/pypi.go | 2 +- routers/api/packages/rubygems/rubygems.go | 2 +- routers/api/packages/swift/swift.go | 2 +- routers/api/packages/vagrant/vagrant.go | 2 +- routers/api/v1/packages/package.go | 2 +- routers/web/user/package.go | 34 +- services/forms/package_form.go | 2 +- services/packages/cleanup/cleanup.go | 11 - services/packages/debian/repository.go | 443 ------------------ services/packages/packages.go | 46 +- templates/package/content/debian.tmpl | 65 --- templates/package/metadata/debian.tmpl | 4 - templates/package/view.tmpl | 2 - templates/swagger/v1_json.tmpl | 1 - tests/integration/api_packages_debian_test.go | 252 ---------- web_src/svg/gitea-debian.svg | 9 - 57 files changed, 96 insertions(+), 1995 deletions(-) delete mode 100644 docs/content/doc/usage/packages/debian.en-us.md delete mode 100644 models/migrations/v1_20/v256.go delete mode 100644 models/packages/debian/search.go delete mode 100644 modules/packages/debian/metadata.go delete mode 100644 modules/packages/debian/metadata_test.go delete mode 100644 public/img/svg/gitea-debian.svg delete mode 100644 routers/api/packages/debian/debian.go delete mode 100644 services/packages/debian/repository.go delete mode 100644 templates/package/content/debian.tmpl delete mode 100644 templates/package/metadata/debian.tmpl delete mode 100644 tests/integration/api_packages_debian_test.go delete mode 100644 web_src/svg/gitea-debian.svg diff --git a/assets/go-licenses.json b/assets/go-licenses.json index 57285b6a9..090f595e7 100644 --- a/assets/go-licenses.json +++ b/assets/go-licenses.json @@ -114,11 +114,6 @@ "path": "github.com/bits-and-blooms/bitset/LICENSE", "licenseText": "Copyright (c) 2014 Will Fitzgerald. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" }, - { - "name": "github.com/blakesmith/ar", - "path": "github.com/blakesmith/ar/COPYING", - "licenseText": "Copyright (c) 2013 Blake Smith \u003cblakesmith0@gmail.com\u003e\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n" - }, { "name": "github.com/blevesearch/bleve/v2", "path": "github.com/blevesearch/bleve/v2/LICENSE", diff --git a/cmd/migrate_storage_test.go b/cmd/migrate_storage_test.go index 7f3de894b..e6658b6e6 100644 --- a/cmd/migrate_storage_test.go +++ b/cmd/migrate_storage_test.go @@ -25,7 +25,7 @@ func TestMigratePackages(t *testing.T) { creator := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) content := "package main\n\nfunc main() {\nfmt.Println(\"hi\")\n}\n" - buf, err := packages_module.CreateHashedBufferFromReaderWithSize(strings.NewReader(content), 1024) + buf, err := packages_module.CreateHashedBufferFromReader(strings.NewReader(content), 1024) assert.NoError(t, err) defer buf.Close() diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index f24770860..3687e0fbd 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -2501,8 +2501,6 @@ ROUTER = console ;LIMIT_SIZE_CONDA = -1 ;; Maximum size of a Container upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`) ;LIMIT_SIZE_CONTAINER = -1 -;; Maximum size of a Debian upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`) -;LIMIT_SIZE_DEBIAN = -1 ;; Maximum size of a Generic upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`) ;LIMIT_SIZE_GENERIC = -1 ;; Maximum size of a Helm upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`) diff --git a/docs/content/doc/administration/config-cheat-sheet.en-us.md b/docs/content/doc/administration/config-cheat-sheet.en-us.md index 44ea3633a..03cd93f91 100644 --- a/docs/content/doc/administration/config-cheat-sheet.en-us.md +++ b/docs/content/doc/administration/config-cheat-sheet.en-us.md @@ -1252,7 +1252,6 @@ Task queue configuration has been moved to `queue.task`. However, the below conf - `LIMIT_SIZE_CONAN`: **-1**: Maximum size of a Conan upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`) - `LIMIT_SIZE_CONDA`: **-1**: Maximum size of a Conda upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`) - `LIMIT_SIZE_CONTAINER`: **-1**: Maximum size of a Container upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`) -- `LIMIT_SIZE_DEBIAN`: **-1**: Maximum size of a Debian upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`) - `LIMIT_SIZE_GENERIC`: **-1**: Maximum size of a Generic upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`) - `LIMIT_SIZE_HELM`: **-1**: Maximum size of a Helm upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`) - `LIMIT_SIZE_MAVEN`: **-1**: Maximum size of a Maven upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`) diff --git a/docs/content/doc/usage/packages/debian.en-us.md b/docs/content/doc/usage/packages/debian.en-us.md deleted file mode 100644 index ac1abed18..000000000 --- a/docs/content/doc/usage/packages/debian.en-us.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -date: "2023-01-07T00:00:00+00:00" -title: "Debian Packages Repository" -slug: "packages/debian" -draft: false -toc: false -menu: - sidebar: - parent: "packages" - name: "Debian" - weight: 35 - identifier: "debian" ---- - -# Debian Packages Repository - -Publish [Debian](https://www.debian.org/distrib/packages) packages for your user or organization. - -**Table of Contents** - -{{< toc >}} - -## Requirements - -To work with the Debian registry, you need to use a HTTP client like `curl` to upload and a package manager like `apt` to consume packages. - -The following examples use `apt`. - -## Configuring the package registry - -To register the Debian registry add the url to the list of known apt sources: - -```shell -echo "deb https://gitea.example.com/api/packages/{owner}/debian {distribution} {component}" | sudo tee -a /etc/apt/sources.list.d/gitea.list -``` - -| Placeholder | Description | -| -------------- | ----------- | -| `owner` | The owner of the package. | -| `distribution` | The distribution to use. | -| `component` | The component to use. | - -If the registry is private, provide credentials in the url. You can use a password or a [personal access token]({{< relref "doc/development/api-usage.en-us.md#authentication" >}}): - -```shell -echo "deb https://{username}:{your_password_or_token}@gitea.example.com/api/packages/{owner}/debian {distribution} {component}" | sudo tee -a /etc/apt/sources.list.d/gitea.list -``` - -The Debian registry files are signed with a PGP key which must be known to apt: - -```shell -sudo curl https://gitea.example.com/api/packages/{owner}/debian/repository.key -o /etc/apt/trusted.gpg.d/gitea-{owner}.asc -``` - -Afterwards update the local package index: - -```shell -apt update -``` - -## Publish a package - -To publish a Debian package (`*.deb`), perform a HTTP PUT operation with the package content in the request body. - -``` -PUT https://gitea.example.com/api/packages/{owner}/debian/pool/{distribution}/{component}/upload -``` - -| Parameter | Description | -| -------------- | ----------- | -| `owner` | The owner of the package. | -| `distribution` | The distribution may match the release name of the OS, ex: `bionic`. | -| `component` | The component can be used to group packages or just `main` or similar. | - -Example request using HTTP Basic authentication: - -```shell -curl --user your_username:your_password_or_token \ - --upload-file path/to/file.deb \ - https://gitea.example.com/api/packages/testuser/debian/pool/bionic/main/upload -``` - -If you are using 2FA or OAuth use a [personal access token]({{< relref "doc/development/api-usage.en-us.md#authentication" >}}) instead of the password. -You cannot publish a file with the same name twice to a package. You must delete the existing package version first. - -The server reponds with the following HTTP Status codes. - -| HTTP Status Code | Meaning | -| ----------------- | ------- | -| `201 Created` | The package has been published. | -| `400 Bad Request` | The package name, version, distribution, component or architecture are invalid. | -| `409 Conflict` | A package file with the same combination of parameters exist already in the package. | - -## Delete a package - -To delete a Debian package perform a HTTP DELETE operation. This will delete the package version too if there is no file left. - -``` -DELETE https://gitea.example.com/api/packages/{owner}/debian/pool/{distribution}/{component}/{package_name}/{package_version}/{architecture} -``` - -| Parameter | Description | -| ----------------- | ----------- | -| `owner` | The owner of the package. | -| `package_name` | The package name. | -| `package_version` | The package version. | -| `distribution` | The package distribution. | -| `component` | The package component. | -| `architecture` | The package architecture. | - -Example request using HTTP Basic authentication: - -```shell -curl --user your_username:your_token_or_password -X DELETE \ - https://gitea.example.com/api/packages/testuser/debian/pools/bionic/main/test-package/1.0.0/amd64 -``` - -The server reponds with the following HTTP Status codes. - -| HTTP Status Code | Meaning | -| ----------------- | ------- | -| `204 No Content` | Success | -| `404 Not Found` | The package or file was not found. | - -## Install a package - -To install a package from the Debian registry, execute the following commands: - -```shell -# use latest version -apt install {package_name} -# use specific version -apt install {package_name}={package_version} -``` diff --git a/docs/content/doc/usage/packages/overview.en-us.md b/docs/content/doc/usage/packages/overview.en-us.md index 8e4fd87e7..fdeaf15af 100644 --- a/docs/content/doc/usage/packages/overview.en-us.md +++ b/docs/content/doc/usage/packages/overview.en-us.md @@ -33,7 +33,6 @@ The following package managers are currently supported: | [Conan]({{< relref "doc/usage/packages/conan.en-us.md" >}}) | C++ | `conan` | | [Conda]({{< relref "doc/usage/packages/conda.en-us.md" >}}) | - | `conda` | | [Container]({{< relref "doc/usage/packages/container.en-us.md" >}}) | - | any OCI compliant client | -| [Debian]({{< relref "doc/usage/packages/debian.en-us.md" >}}) | - | `apt` | | [Generic]({{< relref "doc/usage/packages/generic.en-us.md" >}}) | - | any HTTP client | | [Helm]({{< relref "doc/usage/packages/helm.en-us.md" >}}) | - | any HTTP client, `cm-push` | | [Maven]({{< relref "doc/usage/packages/maven.en-us.md" >}}) | Java | `mvn`, `gradle` | diff --git a/go.mod b/go.mod index ef5f22d96..a71b136cb 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,6 @@ require ( github.com/NYTimes/gziphandler v1.1.1 github.com/PuerkitoBio/goquery v1.8.0 github.com/alecthomas/chroma/v2 v2.5.0 - github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb github.com/blevesearch/bleve/v2 v2.3.6 github.com/bufbuild/connect-go v1.3.1 github.com/buildkite/terminal-to-html/v3 v3.7.0 @@ -97,7 +96,6 @@ require ( github.com/stretchr/testify v1.8.1 github.com/syndtr/goleveldb v1.0.0 github.com/tstranex/u2f v1.0.0 - github.com/ulikunitz/xz v0.5.11 github.com/urfave/cli v1.22.12 github.com/xanzy/go-gitlab v0.80.2 github.com/xeipuuv/gojsonschema v1.2.0 @@ -262,6 +260,7 @@ require ( github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect github.com/subosito/gotenv v1.4.1 // indirect github.com/toqueteos/webbrowser v1.2.0 // indirect + github.com/ulikunitz/xz v0.5.11 // indirect github.com/unknwon/com v1.0.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.44.0 // indirect diff --git a/go.sum b/go.sum index ba969ddde..2a3cc5967 100644 --- a/go.sum +++ b/go.sum @@ -162,8 +162,6 @@ github.com/bits-and-blooms/bitset v1.1.10/go.mod h1:w0XsmFg8qg6cmpTtJ0z3pKgjTDBM github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8= github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4= -github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= github.com/blevesearch/bleve/v2 v2.0.5/go.mod h1:ZjWibgnbRX33c+vBRgla9QhPb4QOjD6fdVJ+R1Bk8LM= github.com/blevesearch/bleve/v2 v2.3.6 h1:NlntUHcV5CSWIhpugx4d/BRMGCiaoI8ZZXrXlahzNq4= github.com/blevesearch/bleve/v2 v2.3.6/go.mod h1:JM2legf1cKVkdV8Ehu7msKIOKC0McSw0Q16Fmv9vsW4= diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 0e84ae9f0..1f1f43796 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -489,8 +489,6 @@ var migrations = []Migration{ NewMigration("Add ActionTaskOutput table", v1_20.AddActionTaskOutputTable), // v255 -> v256 NewMigration("Add ArchivedUnix Column", v1_20.AddArchivedUnixToRepository), - // v256 -> v257 - NewMigration("Add is_internal column to package", v1_20.AddIsInternalColumnToPackage), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/v1_20/v256.go b/models/migrations/v1_20/v256.go deleted file mode 100644 index ddb487f68..000000000 --- a/models/migrations/v1_20/v256.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2023 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package v1_20 //nolint - -import ( - "xorm.io/xorm" -) - -func AddIsInternalColumnToPackage(x *xorm.Engine) error { - type Package struct { - ID int64 `xorm:"pk autoincr"` - OwnerID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` - RepoID int64 `xorm:"INDEX"` - Type string `xorm:"UNIQUE(s) INDEX NOT NULL"` - Name string `xorm:"NOT NULL"` - LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"` - SemverCompatible bool `xorm:"NOT NULL DEFAULT false"` - IsInternal bool `xorm:"INDEX NOT NULL DEFAULT false"` - } - - return x.Sync2(new(Package)) -} diff --git a/models/packages/container/search.go b/models/packages/container/search.go index 0d3664d38..b65c8634d 100644 --- a/models/packages/container/search.go +++ b/models/packages/container/search.go @@ -101,7 +101,16 @@ func getContainerBlobsLimit(ctx context.Context, opts *BlobSearchOptions, limit return nil, err } - return packages.GetPackageFileDescriptors(ctx, pfs) + pfds := make([]*packages.PackageFileDescriptor, 0, len(pfs)) + for _, pf := range pfs { + pfd, err := packages.GetPackageFileDescriptor(ctx, pf) + if err != nil { + return nil, err + } + pfds = append(pfds, pfd) + } + + return pfds, nil } // GetManifestVersions gets all package versions representing the matching manifest diff --git a/models/packages/debian/search.go b/models/packages/debian/search.go deleted file mode 100644 index 332a4f704..000000000 --- a/models/packages/debian/search.go +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2023 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package debian - -import ( - "context" - "strconv" - - "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/models/packages" - debian_module "code.gitea.io/gitea/modules/packages/debian" - - "xorm.io/builder" -) - -type PackageSearchOptions struct { - OwnerID int64 - Distribution string - Component string - Architecture string -} - -// SearchLatestPackages gets the latest packages matching the search options -func SearchLatestPackages(ctx context.Context, opts *PackageSearchOptions) ([]*packages.PackageFileDescriptor, error) { - var cond builder.Cond = builder.Eq{ - "package_file.is_lead": true, - "package.type": packages.TypeDebian, - "package.owner_id": opts.OwnerID, - "package.is_internal": false, - "package_version.is_internal": false, - } - - props := make(map[string]string) - if opts.Distribution != "" { - props[debian_module.PropertyDistribution] = opts.Distribution - } - if opts.Component != "" { - props[debian_module.PropertyComponent] = opts.Component - } - if opts.Architecture != "" { - props[debian_module.PropertyArchitecture] = opts.Architecture - } - - if len(props) > 0 { - var propsCond builder.Cond = builder.Eq{ - "package_property.ref_type": packages.PropertyTypeFile, - } - propsCond = propsCond.And(builder.Expr("package_property.ref_id = package_file.id")) - - propsCondBlock := builder.NewCond() - for name, value := range props { - propsCondBlock = propsCondBlock.Or(builder.Eq{ - "package_property.name": name, - "package_property.value": value, - }) - } - propsCond = propsCond.And(propsCondBlock) - - cond = cond.And(builder.Eq{ - strconv.Itoa(len(props)): builder.Select("COUNT(*)").Where(propsCond).From("package_property"), - }) - } - - cond = cond. - And(builder.Expr("pv2.id IS NULL")) - - joinCond := builder. - Expr("package_version.package_id = pv2.package_id AND (package_version.created_unix < pv2.created_unix OR (package_version.created_unix = pv2.created_unix AND package_version.id < pv2.id))"). - And(builder.Eq{"pv2.is_internal": false}) - - pfs := make([]*packages.PackageFile, 0, 10) - err := db.GetEngine(ctx). - Table("package_file"). - Select("package_file.*"). - Join("INNER", "package_version", "package_version.id = package_file.version_id"). - Join("LEFT", "package_version pv2", joinCond). - Join("INNER", "package", "package.id = package_version.package_id"). - Where(cond). - Desc("package_version.created_unix"). - Find(&pfs) - if err != nil { - return nil, err - } - - return packages.GetPackageFileDescriptors(ctx, pfs) -} - -// GetDistributions gets all available distributions -func GetDistributions(ctx context.Context, ownerID int64) ([]string, error) { - return getDistinctPropertyValues(ctx, ownerID, "", debian_module.PropertyDistribution) -} - -// GetComponents gets all available components for the given distribution -func GetComponents(ctx context.Context, ownerID int64, distribution string) ([]string, error) { - return getDistinctPropertyValues(ctx, ownerID, distribution, debian_module.PropertyComponent) -} - -// GetArchitectures gets all available architectures for the given distribution -func GetArchitectures(ctx context.Context, ownerID int64, distribution string) ([]string, error) { - return getDistinctPropertyValues(ctx, ownerID, distribution, debian_module.PropertyArchitecture) -} - -func getDistinctPropertyValues(ctx context.Context, ownerID int64, distribution, propName string) ([]string, error) { - var cond builder.Cond = builder.Eq{ - "package_property.ref_type": packages.PropertyTypeFile, - "package_property.name": propName, - "package.type": packages.TypeDebian, - "package.owner_id": ownerID, - } - if distribution != "" { - innerCond := builder. - Expr("pp.ref_id = package_property.ref_id"). - And(builder.Eq{ - "pp.ref_type": packages.PropertyTypeFile, - "pp.name": debian_module.PropertyDistribution, - "pp.value": distribution, - }) - cond = cond.And(builder.Exists(builder.Select("pp.ref_id").From("package_property pp").Where(innerCond))) - } - - values := make([]string, 0, 5) - return values, db.GetEngine(ctx). - Table("package_property"). - Distinct("package_property.value"). - Join("INNER", "package_file", "package_file.id = package_property.ref_id"). - Join("INNER", "package_version", "package_version.id = package_file.version_id"). - Join("INNER", "package", "package.id = package_version.package_id"). - Where(cond). - Find(&values) -} diff --git a/models/packages/descriptor.go b/models/packages/descriptor.go index 9256dd563..974c5b2c3 100644 --- a/models/packages/descriptor.go +++ b/models/packages/descriptor.go @@ -18,7 +18,6 @@ import ( "code.gitea.io/gitea/modules/packages/conan" "code.gitea.io/gitea/modules/packages/conda" "code.gitea.io/gitea/modules/packages/container" - "code.gitea.io/gitea/modules/packages/debian" "code.gitea.io/gitea/modules/packages/helm" "code.gitea.io/gitea/modules/packages/maven" "code.gitea.io/gitea/modules/packages/npm" @@ -128,9 +127,13 @@ func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDesc return nil, err } - pfds, err := GetPackageFileDescriptors(ctx, pfs) - if err != nil { - return nil, err + pfds := make([]*PackageFileDescriptor, 0, len(pfs)) + for _, pf := range pfs { + pfd, err := GetPackageFileDescriptor(ctx, pf) + if err != nil { + return nil, err + } + pfds = append(pfds, pfd) } var metadata interface{} @@ -147,8 +150,6 @@ func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDesc metadata = &conda.VersionMetadata{} case TypeContainer: metadata = &container.Metadata{} - case TypeDebian: - metadata = &debian.Metadata{} case TypeGeneric: // generic packages have no metadata case TypeHelm: @@ -209,19 +210,6 @@ func GetPackageFileDescriptor(ctx context.Context, pf *PackageFile) (*PackageFil }, nil } -// GetPackageFileDescriptors gets the package file descriptors for the package files -func GetPackageFileDescriptors(ctx context.Context, pfs []*PackageFile) ([]*PackageFileDescriptor, error) { - pfds := make([]*PackageFileDescriptor, 0, len(pfs)) - for _, pf := range pfs { - pfd, err := GetPackageFileDescriptor(ctx, pf) - if err != nil { - return nil, err - } - pfds = append(pfds, pfd) - } - return pfds, nil -} - // GetPackageDescriptors gets the package descriptions for the versions func GetPackageDescriptors(ctx context.Context, pvs []*PackageVersion) ([]*PackageDescriptor, error) { pds := make([]*PackageDescriptor, 0, len(pvs)) diff --git a/models/packages/package.go b/models/packages/package.go index 579e9e4d5..ccc9257c3 100644 --- a/models/packages/package.go +++ b/models/packages/package.go @@ -36,7 +36,6 @@ const ( TypeConan Type = "conan" TypeConda Type = "conda" TypeContainer Type = "container" - TypeDebian Type = "debian" TypeGeneric Type = "generic" TypeHelm Type = "helm" TypeMaven Type = "maven" @@ -56,7 +55,6 @@ var TypeList = []Type{ TypeConan, TypeConda, TypeContainer, - TypeDebian, TypeGeneric, TypeHelm, TypeMaven, @@ -84,8 +82,6 @@ func (pt Type) Name() string { return "Conda" case TypeContainer: return "Container" - case TypeDebian: - return "Debian" case TypeGeneric: return "Generic" case TypeHelm: @@ -125,8 +121,6 @@ func (pt Type) SVGName() string { return "gitea-conda" case TypeContainer: return "octicon-container" - case TypeDebian: - return "gitea-debian" case TypeGeneric: return "octicon-package" case TypeHelm: @@ -160,7 +154,6 @@ type Package struct { Name string `xorm:"NOT NULL"` LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"` SemverCompatible bool `xorm:"NOT NULL DEFAULT false"` - IsInternal bool `xorm:"INDEX NOT NULL DEFAULT false"` } // TryInsertPackage inserts a package. If a package exists already, ErrDuplicatePackage is returned @@ -221,10 +214,9 @@ func GetPackageByID(ctx context.Context, packageID int64) (*Package, error) { // GetPackageByName gets a package by name func GetPackageByName(ctx context.Context, ownerID int64, packageType Type, name string) (*Package, error) { var cond builder.Cond = builder.Eq{ - "package.owner_id": ownerID, - "package.type": packageType, - "package.lower_name": strings.ToLower(name), - "package.is_internal": false, + "package.owner_id": ownerID, + "package.type": packageType, + "package.lower_name": strings.ToLower(name), } p := &Package{} @@ -244,9 +236,8 @@ func GetPackageByName(ctx context.Context, ownerID int64, packageType Type, name // GetPackagesByType gets all packages of a specific type func GetPackagesByType(ctx context.Context, ownerID int64, packageType Type) ([]*Package, error) { var cond builder.Cond = builder.Eq{ - "package.owner_id": ownerID, - "package.type": packageType, - "package.is_internal": false, + "package.owner_id": ownerID, + "package.type": packageType, } ps := make([]*Package, 0, 10) diff --git a/models/packages/package_file.go b/models/packages/package_file.go index 337ab1135..97e7a0d40 100644 --- a/models/packages/package_file.go +++ b/models/packages/package_file.go @@ -117,15 +117,13 @@ func DeleteFileByID(ctx context.Context, fileID int64) error { // PackageFileSearchOptions are options for SearchXXX methods type PackageFileSearchOptions struct { - OwnerID int64 - PackageType string - VersionID int64 - Query string - CompositeKey string - Properties map[string]string - OlderThan time.Duration - HashAlgorithmn string - Hash string + OwnerID int64 + PackageType string + VersionID int64 + Query string + CompositeKey string + Properties map[string]string + OlderThan time.Duration db.Paginator } @@ -184,15 +182,6 @@ func (opts *PackageFileSearchOptions) toConds() builder.Cond { cond = cond.And(builder.Lt{"package_file.created_unix": time.Now().Add(-opts.OlderThan).Unix()}) } - if opts.Hash != "" && (opts.HashAlgorithmn == "md5" || opts.HashAlgorithmn == "sha1" || opts.HashAlgorithmn == "sha256" || opts.HashAlgorithmn == "sha512") { - innerCond := builder. - Expr("package_blob.id = package_file.blob_id"). - And(builder.Eq{ - "package_blob.hash_" + opts.HashAlgorithmn: opts.Hash, - }) - cond = cond.And(builder.Exists(builder.Select("package_blob.id").From("package_blob").Where(innerCond))) - } - return cond } diff --git a/models/packages/package_version.go b/models/packages/package_version.go index ab1bcddae..759c20abe 100644 --- a/models/packages/package_version.go +++ b/models/packages/package_version.go @@ -173,7 +173,7 @@ const ( ) // PackageSearchOptions are options for SearchXXX methods -// All fields optional and are not used if they have their default value (nil, "", 0) +// Besides IsInternal are all fields optional and are not used if they have their default value (nil, "", 0) type PackageSearchOptions struct { OwnerID int64 RepoID int64 @@ -192,9 +192,7 @@ type PackageSearchOptions struct { func (opts *PackageSearchOptions) toConds() builder.Cond { cond := builder.NewCond() if !opts.IsInternal.IsNone() { - cond = builder.Eq{ - "package_version.is_internal": opts.IsInternal.IsTrue(), - } + cond = builder.Eq{"package_version.is_internal": opts.IsInternal.IsTrue()} } if opts.OwnerID != 0 { diff --git a/models/user/setting.go b/models/user/setting.go index a41e494db..aec79b756 100644 --- a/models/user/setting.go +++ b/models/user/setting.go @@ -11,7 +11,6 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/cache" setting_module "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/util" "xorm.io/builder" ) @@ -43,10 +42,6 @@ func (err ErrUserSettingIsNotExist) Error() string { return fmt.Sprintf("Setting[%s] is not exist", err.Key) } -func (err ErrUserSettingIsNotExist) Unwrap() error { - return util.ErrNotExist -} - // IsErrUserSettingIsNotExist return true if err is ErrSettingIsNotExist func IsErrUserSettingIsNotExist(err error) bool { _, ok := err.(ErrUserSettingIsNotExist) diff --git a/modules/packages/debian/metadata.go b/modules/packages/debian/metadata.go deleted file mode 100644 index 08daaf082..000000000 --- a/modules/packages/debian/metadata.go +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright 2023 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package debian - -import ( - "archive/tar" - "bufio" - "compress/gzip" - "io" - "net/mail" - "regexp" - "strings" - - "code.gitea.io/gitea/modules/util" - "code.gitea.io/gitea/modules/validation" - - "github.com/blakesmith/ar" - "github.com/klauspost/compress/zstd" - "github.com/ulikunitz/xz" -) - -const ( - PropertyDistribution = "debian.distribution" - PropertyComponent = "debian.component" - PropertyArchitecture = "debian.architecture" - PropertyControl = "debian.control" - PropertyRepositoryIncludeInRelease = "debian.repository.include_in_release" - - SettingKeyPrivate = "debian.key.private" - SettingKeyPublic = "debian.key.public" - - RepositoryPackage = "_debian" - RepositoryVersion = "_repository" -) - -var ( - ErrMissingControlFile = util.NewInvalidArgumentErrorf("control file is missing") - ErrUnsupportedCompression = util.NewInvalidArgumentErrorf("unsupported compression algorithmn") - ErrInvalidName = util.NewInvalidArgumentErrorf("package name is invalid") - ErrInvalidVersion = util.NewInvalidArgumentErrorf("package version is invalid") - ErrInvalidArchitecture = util.NewInvalidArgumentErrorf("package architecture is invalid") - - // https://www.debian.org/doc/debian-policy/ch-controlfields.html#source - namePattern = regexp.MustCompile(`\A[a-z0-9][a-z0-9+-.]+\z`) - // https://www.debian.org/doc/debian-policy/ch-controlfields.html#version - versionPattern = regexp.MustCompile(`\A(?:[0-9]:)?[a-zA-Z0-9.+~]+(?:-[a-zA-Z0-9.+-~]+)?\z`) -) - -type Package struct { - Name string - Version string - Architecture string - Control string - Metadata *Metadata -} - -type Metadata struct { - Maintainer string `json:"maintainer,omitempty"` - ProjectURL string `json:"project_url,omitempty"` - Description string `json:"description,omitempty"` - Dependencies []string `json:"dependencies,omitempty"` -} - -// ParsePackage parses the Debian package file -// https://manpages.debian.org/bullseye/dpkg-dev/deb.5.en.html -func ParsePackage(r io.Reader) (*Package, error) { - arr := ar.NewReader(r) - - for { - hd, err := arr.Next() - if err == io.EOF { - break - } - if err != nil { - return nil, err - } - - if strings.HasPrefix(hd.Name, "control.tar") { - var inner io.Reader - switch hd.Name[11:] { - case "": - inner = arr - case ".gz": - gzr, err := gzip.NewReader(arr) - if err != nil { - return nil, err - } - defer gzr.Close() - - inner = gzr - case ".xz": - xzr, err := xz.NewReader(arr) - if err != nil { - return nil, err - } - - inner = xzr - case ".zst": - zr, err := zstd.NewReader(arr) - if err != nil { - return nil, err - } - defer zr.Close() - - inner = zr - default: - return nil, ErrUnsupportedCompression - } - - tr := tar.NewReader(inner) - for { - hd, err := tr.Next() - if err == io.EOF { - break - } - if err != nil { - return nil, err - } - - if hd.Typeflag != tar.TypeReg { - continue - } - - if hd.FileInfo().Name() == "control" { - return ParseControlFile(tr) - } - } - } - } - - return nil, ErrMissingControlFile -} - -// ParseControlFile parses a Debian control file to retrieve the metadata -func ParseControlFile(r io.Reader) (*Package, error) { - p := &Package{ - Metadata: &Metadata{}, - } - - key := "" - var depends strings.Builder - var control strings.Builder - - s := bufio.NewScanner(io.TeeReader(r, &control)) - for s.Scan() { - line := s.Text() - - trimmed := strings.TrimSpace(line) - if trimmed == "" { - continue - } - - if line[0] == ' ' || line[0] == '\t' { - switch key { - case "Description": - p.Metadata.Description += line - case "Depends": - depends.WriteString(trimmed) - } - } else { - parts := strings.SplitN(trimmed, ":", 2) - if len(parts) < 2 { - continue - } - - key = parts[0] - value := strings.TrimSpace(parts[1]) - switch key { - case "Package": - if !namePattern.MatchString(value) { - return nil, ErrInvalidName - } - p.Name = value - case "Version": - if !versionPattern.MatchString(value) { - return nil, ErrInvalidVersion - } - p.Version = value - case "Architecture": - if value == "" { - return nil, ErrInvalidArchitecture - } - p.Architecture = value - case "Maintainer": - a, err := mail.ParseAddress(value) - if err != nil || a.Name == "" { - p.Metadata.Maintainer = value - } else { - p.Metadata.Maintainer = a.Name - } - case "Description": - p.Metadata.Description = value - case "Depends": - depends.WriteString(value) - case "Homepage": - if validation.IsValidURL(value) { - p.Metadata.ProjectURL = value - } - } - } - } - if err := s.Err(); err != nil { - return nil, err - } - - dependencies := strings.Split(depends.String(), ",") - for i := range dependencies { - dependencies[i] = strings.TrimSpace(dependencies[i]) - } - p.Metadata.Dependencies = dependencies - - p.Control = control.String() - - return p, nil -} diff --git a/modules/packages/debian/metadata_test.go b/modules/packages/debian/metadata_test.go deleted file mode 100644 index 69fd51ea7..000000000 --- a/modules/packages/debian/metadata_test.go +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright 2023 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package debian - -import ( - "archive/tar" - "bytes" - "compress/gzip" - "io" - "testing" - - "github.com/blakesmith/ar" - "github.com/klauspost/compress/zstd" - "github.com/stretchr/testify/assert" - "github.com/ulikunitz/xz" -) - -const ( - packageName = "gitea" - packageVersion = "0:1.0.1-te~st" - packageArchitecture = "amd64" - packageAuthor = "KN4CK3R" - description = "Description with multiple lines." - projectURL = "https://gitea.io" -) - -func TestParsePackage(t *testing.T) { - createArchive := func(files map[string][]byte) io.Reader { - var buf bytes.Buffer - aw := ar.NewWriter(&buf) - aw.WriteGlobalHeader() - for filename, content := range files { - hdr := &ar.Header{ - Name: filename, - Mode: 0o600, - Size: int64(len(content)), - } - aw.WriteHeader(hdr) - aw.Write(content) - } - return &buf - } - - t.Run("MissingControlFile", func(t *testing.T) { - data := createArchive(map[string][]byte{"dummy.txt": {}}) - - p, err := ParsePackage(data) - assert.Nil(t, p) - assert.ErrorIs(t, err, ErrMissingControlFile) - }) - - t.Run("Compression", func(t *testing.T) { - t.Run("Unsupported", func(t *testing.T) { - data := createArchive(map[string][]byte{"control.tar.foo": {}}) - - p, err := ParsePackage(data) - assert.Nil(t, p) - assert.ErrorIs(t, err, ErrUnsupportedCompression) - }) - - var buf bytes.Buffer - tw := tar.NewWriter(&buf) - tw.WriteHeader(&tar.Header{ - Name: "control", - Mode: 0o600, - Size: 50, - }) - tw.Write([]byte("Package: gitea\nVersion: 1.0.0\nArchitecture: amd64\n")) - tw.Close() - - t.Run("None", func(t *testing.T) { - data := createArchive(map[string][]byte{"control.tar": buf.Bytes()}) - - p, err := ParsePackage(data) - assert.NotNil(t, p) - assert.NoError(t, err) - assert.Equal(t, "gitea", p.Name) - }) - - t.Run("gz", func(t *testing.T) { - var zbuf bytes.Buffer - zw := gzip.NewWriter(&zbuf) - zw.Write(buf.Bytes()) - zw.Close() - - data := createArchive(map[string][]byte{"control.tar.gz": zbuf.Bytes()}) - - p, err := ParsePackage(data) - assert.NotNil(t, p) - assert.NoError(t, err) - assert.Equal(t, "gitea", p.Name) - }) - - t.Run("xz", func(t *testing.T) { - var xbuf bytes.Buffer - xw, _ := xz.NewWriter(&xbuf) - xw.Write(buf.Bytes()) - xw.Close() - - data := createArchive(map[string][]byte{"control.tar.xz": xbuf.Bytes()}) - - p, err := ParsePackage(data) - assert.NotNil(t, p) - assert.NoError(t, err) - assert.Equal(t, "gitea", p.Name) - }) - - t.Run("zst", func(t *testing.T) { - var zbuf bytes.Buffer - zw, _ := zstd.NewWriter(&zbuf) - zw.Write(buf.Bytes()) - zw.Close() - - data := createArchive(map[string][]byte{"control.tar.zst": zbuf.Bytes()}) - - p, err := ParsePackage(data) - assert.NotNil(t, p) - assert.NoError(t, err) - assert.Equal(t, "gitea", p.Name) - }) - }) -} - -func TestParseControlFile(t *testing.T) { - buildContent := func(name, version, architecture string) *bytes.Buffer { - var buf bytes.Buffer - buf.WriteString("Package: " + name + "\nVersion: " + version + "\nArchitecture: " + architecture + "\nMaintainer: " + packageAuthor + " \nHomepage: " + projectURL + "\nDepends: a,\n b\nDescription: Description\n with multiple\n lines.") - return &buf - } - - t.Run("InvalidName", func(t *testing.T) { - for _, name := range []string{"", "-cd"} { - p, err := ParseControlFile(buildContent(name, packageVersion, packageArchitecture)) - assert.Nil(t, p) - assert.ErrorIs(t, err, ErrInvalidName) - } - }) - - t.Run("InvalidVersion", func(t *testing.T) { - for _, version := range []string{"", "1-", ":1.0", "1_0"} { - p, err := ParseControlFile(buildContent(packageName, version, packageArchitecture)) - assert.Nil(t, p) - assert.ErrorIs(t, err, ErrInvalidVersion) - } - }) - - t.Run("InvalidArchitecture", func(t *testing.T) { - p, err := ParseControlFile(buildContent(packageName, packageVersion, "")) - assert.Nil(t, p) - assert.ErrorIs(t, err, ErrInvalidArchitecture) - }) - - t.Run("Valid", func(t *testing.T) { - content := buildContent(packageName, packageVersion, packageArchitecture) - full := content.String() - - p, err := ParseControlFile(content) - assert.NoError(t, err) - assert.NotNil(t, p) - - assert.Equal(t, packageName, p.Name) - assert.Equal(t, packageVersion, p.Version) - assert.Equal(t, packageArchitecture, p.Architecture) - assert.Equal(t, description, p.Metadata.Description) - assert.Equal(t, projectURL, p.Metadata.ProjectURL) - assert.Equal(t, packageAuthor, p.Metadata.Maintainer) - assert.Equal(t, []string{"a", "b"}, p.Metadata.Dependencies) - assert.Equal(t, full, p.Control) - }) -} diff --git a/modules/packages/hashed_buffer.go b/modules/packages/hashed_buffer.go index 017ddf1c8..ef00a4505 100644 --- a/modules/packages/hashed_buffer.go +++ b/modules/packages/hashed_buffer.go @@ -25,15 +25,8 @@ type HashedBuffer struct { combinedWriter io.Writer } -const DefaultMemorySize = 32 * 1024 * 1024 - -// NewHashedBuffer creates a hashed buffer with the default memory size -func NewHashedBuffer() (*HashedBuffer, error) { - return NewHashedBufferWithSize(DefaultMemorySize) -} - -// NewHashedBuffer creates a hashed buffer with a specific memory size -func NewHashedBufferWithSize(maxMemorySize int) (*HashedBuffer, error) { +// NewHashedBuffer creates a hashed buffer with a specific maximum memory size +func NewHashedBuffer(maxMemorySize int) (*HashedBuffer, error) { b, err := filebuffer.New(maxMemorySize) if err != nil { return nil, err @@ -50,14 +43,9 @@ func NewHashedBufferWithSize(maxMemorySize int) (*HashedBuffer, error) { }, nil } -// CreateHashedBufferFromReader creates a hashed buffer with the default memory size and copies the provided reader data into it. -func CreateHashedBufferFromReader(r io.Reader) (*HashedBuffer, error) { - return CreateHashedBufferFromReaderWithSize(r, DefaultMemorySize) -} - -// CreateHashedBufferFromReaderWithSize creates a hashed buffer and copies the provided reader data into it. -func CreateHashedBufferFromReaderWithSize(r io.Reader, maxMemorySize int) (*HashedBuffer, error) { - b, err := NewHashedBufferWithSize(maxMemorySize) +// CreateHashedBufferFromReader creates a hashed buffer and copies the provided reader data into it. +func CreateHashedBufferFromReader(r io.Reader, maxMemorySize int) (*HashedBuffer, error) { + b, err := NewHashedBuffer(maxMemorySize) if err != nil { return nil, err } diff --git a/modules/packages/hashed_buffer_test.go b/modules/packages/hashed_buffer_test.go index 564e782f1..e907aa060 100644 --- a/modules/packages/hashed_buffer_test.go +++ b/modules/packages/hashed_buffer_test.go @@ -26,7 +26,7 @@ func TestHashedBuffer(t *testing.T) { } for _, c := range cases { - buf, err := CreateHashedBufferFromReaderWithSize(strings.NewReader(c.Data), c.MaxMemorySize) + buf, err := CreateHashedBufferFromReader(strings.NewReader(c.Data), c.MaxMemorySize) assert.NoError(t, err) assert.EqualValues(t, len(c.Data), buf.Size()) diff --git a/modules/packages/nuget/symbol_extractor.go b/modules/packages/nuget/symbol_extractor.go index 81bf0371a..b709eac4c 100644 --- a/modules/packages/nuget/symbol_extractor.go +++ b/modules/packages/nuget/symbol_extractor.go @@ -63,7 +63,7 @@ func ExtractPortablePdb(r io.ReaderAt, size int64) (PortablePdbList, error) { return err } - buf, err := packages.CreateHashedBufferFromReader(f) + buf, err := packages.CreateHashedBufferFromReader(f, 32*1024*1024) f.Close() diff --git a/modules/setting/packages.go b/modules/setting/packages.go index b52bbf40c..89601c3b9 100644 --- a/modules/setting/packages.go +++ b/modules/setting/packages.go @@ -30,7 +30,6 @@ var ( LimitSizeConan int64 LimitSizeConda int64 LimitSizeContainer int64 - LimitSizeDebian int64 LimitSizeGeneric int64 LimitSizeHelm int64 LimitSizeMaven int64 @@ -74,7 +73,6 @@ func loadPackagesFrom(rootCfg ConfigProvider) { Packages.LimitSizeConan = mustBytes(sec, "LIMIT_SIZE_CONAN") Packages.LimitSizeConda = mustBytes(sec, "LIMIT_SIZE_CONDA") Packages.LimitSizeContainer = mustBytes(sec, "LIMIT_SIZE_CONTAINER") - Packages.LimitSizeDebian = mustBytes(sec, "LIMIT_SIZE_DEBIAN") Packages.LimitSizeGeneric = mustBytes(sec, "LIMIT_SIZE_GENERIC") Packages.LimitSizeHelm = mustBytes(sec, "LIMIT_SIZE_HELM") Packages.LimitSizeMaven = mustBytes(sec, "LIMIT_SIZE_MAVEN") diff --git a/modules/util/filebuffer/file_backed_buffer.go b/modules/util/filebuffer/file_backed_buffer.go index 6b07bd041..bfddf90e9 100644 --- a/modules/util/filebuffer/file_backed_buffer.go +++ b/modules/util/filebuffer/file_backed_buffer.go @@ -7,10 +7,11 @@ import ( "bytes" "errors" "io" - "math" "os" ) +const maxInt = int(^uint(0) >> 1) // taken from bytes.Buffer + var ( // ErrInvalidMemorySize occurs if the memory size is not in a valid range ErrInvalidMemorySize = errors.New("Memory size must be greater 0 and lower math.MaxInt32") @@ -36,7 +37,7 @@ type FileBackedBuffer struct { // New creates a file backed buffer with a specific maximum memory size func New(maxMemorySize int) (*FileBackedBuffer, error) { - if maxMemorySize < 0 || maxMemorySize > math.MaxInt32 { + if maxMemorySize < 0 || maxMemorySize > maxInt { return nil, ErrInvalidMemorySize } diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 76d8e5d4d..0072ac6fc 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -3258,14 +3258,6 @@ container.layers = Image Layers container.labels = Labels container.labels.key = Key container.labels.value = Value -debian.registry = Setup this registry from the command line: -debian.registry.info = Choose <distribution> and <component> from the list below. -debian.install = To install the package, run the following command: -debian.documentation = For more information on the Debian registry, see the documentation. -debian.repository = Repository Info -debian.repository.distributions = Distributions -debian.repository.components = Components -debian.repository.architectures = Architectures generic.download = Download package from the command line: generic.documentation = For more information on the generic registry, see the documentation. helm.registry = Setup this registry from the command line: diff --git a/public/img/svg/gitea-debian.svg b/public/img/svg/gitea-debian.svg deleted file mode 100644 index 96f8f468e..000000000 --- a/public/img/svg/gitea-debian.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go index 2ce233171..d5acd3d26 100644 --- a/routers/api/packages/api.go +++ b/routers/api/packages/api.go @@ -21,7 +21,6 @@ import ( "code.gitea.io/gitea/routers/api/packages/conan" "code.gitea.io/gitea/routers/api/packages/conda" "code.gitea.io/gitea/routers/api/packages/container" - "code.gitea.io/gitea/routers/api/packages/debian" "code.gitea.io/gitea/routers/api/packages/generic" "code.gitea.io/gitea/routers/api/packages/helm" "code.gitea.io/gitea/routers/api/packages/maven" @@ -273,24 +272,6 @@ func CommonRoutes(ctx gocontext.Context) *web.Route { conda.UploadPackageFile(ctx) }) }, reqPackageAccess(perm.AccessModeRead)) - r.Group("/debian", func() { - r.Get("/repository.key", debian.GetRepositoryKey) - r.Group("/dists/{distribution}", func() { - r.Get("/{filename}", debian.GetRepositoryFile) - r.Get("/by-hash/{algorithmn}/{hash}", debian.GetRepositoryFileByHash) - r.Group("/{component}/{architecture}", func() { - r.Get("/{filename}", debian.GetRepositoryFile) - r.Get("/by-hash/{algorithmn}/{hash}", debian.GetRepositoryFileByHash) - }) - }) - r.Group("/pool/{distribution}/{component}", func() { - r.Get("/{name}_{version}_{architecture}.deb", debian.DownloadPackageFile) - r.Group("", func() { - r.Put("/upload", debian.UploadPackageFile) - r.Delete("/{name}/{version}/{architecture}", debian.DeletePackageFile) - }, reqPackageAccess(perm.AccessModeWrite)) - }) - }, reqPackageAccess(perm.AccessModeRead)) r.Group("/generic", func() { r.Group("/{packagename}/{packageversion}", func() { r.Delete("", reqPackageAccess(perm.AccessModeWrite), generic.DeletePackage) diff --git a/routers/api/packages/cargo/cargo.go b/routers/api/packages/cargo/cargo.go index 18c93d328..e0bf5da13 100644 --- a/routers/api/packages/cargo/cargo.go +++ b/routers/api/packages/cargo/cargo.go @@ -173,7 +173,7 @@ func UploadPackage(ctx *context.Context) { return } - buf, err := packages_module.CreateHashedBufferFromReader(cp.Content) + buf, err := packages_module.CreateHashedBufferFromReader(cp.Content, 32*1024*1024) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return diff --git a/routers/api/packages/chef/chef.go b/routers/api/packages/chef/chef.go index b48b1778c..28d07dea4 100644 --- a/routers/api/packages/chef/chef.go +++ b/routers/api/packages/chef/chef.go @@ -263,7 +263,7 @@ func UploadPackage(ctx *context.Context) { } defer file.Close() - buf, err := packages_module.CreateHashedBufferFromReader(file) + buf, err := packages_module.CreateHashedBufferFromReader(file, 32*1024*1024) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return diff --git a/routers/api/packages/composer/composer.go b/routers/api/packages/composer/composer.go index d93b11efd..a623952aa 100644 --- a/routers/api/packages/composer/composer.go +++ b/routers/api/packages/composer/composer.go @@ -192,7 +192,7 @@ func DownloadPackageFile(ctx *context.Context) { // UploadPackage creates a new package func UploadPackage(ctx *context.Context) { - buf, err := packages_module.CreateHashedBufferFromReader(ctx.Req.Body) + buf, err := packages_module.CreateHashedBufferFromReader(ctx.Req.Body, 32*1024*1024) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return diff --git a/routers/api/packages/conan/conan.go b/routers/api/packages/conan/conan.go index caeb8c11b..d538cc7d3 100644 --- a/routers/api/packages/conan/conan.go +++ b/routers/api/packages/conan/conan.go @@ -318,7 +318,7 @@ func uploadFile(ctx *context.Context, fileFilter container.Set[string], fileKey defer upload.Close() } - buf, err := packages_module.CreateHashedBufferFromReader(upload) + buf, err := packages_module.CreateHashedBufferFromReader(upload, 32*1024*1024) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return @@ -648,7 +648,10 @@ func deleteRecipeOrPackage(apictx *context.Context, rref *conan_module.RecipeRef } for _, pf := range pfs { - if err := packages_service.DeletePackageFile(ctx, pf); err != nil { + if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeFile, pf.ID); err != nil { + return err + } + if err := packages_model.DeleteFileByID(ctx, pf.ID); err != nil { return err } } @@ -661,7 +664,11 @@ func deleteRecipeOrPackage(apictx *context.Context, rref *conan_module.RecipeRef if !has { versionDeleted = true - if err := packages_service.DeletePackageVersionAndReferences(ctx, pv); err != nil { + if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeVersion, pv.ID); err != nil { + return err + } + + if err := packages_model.DeleteVersionByID(ctx, pv.ID); err != nil { return err } } diff --git a/routers/api/packages/conda/conda.go b/routers/api/packages/conda/conda.go index f77869063..2ff619fed 100644 --- a/routers/api/packages/conda/conda.go +++ b/routers/api/packages/conda/conda.go @@ -183,7 +183,7 @@ func UploadPackageFile(ctx *context.Context) { defer upload.Close() } - buf, err := packages_module.CreateHashedBufferFromReader(upload) + buf, err := packages_module.CreateHashedBufferFromReader(upload, 32*1024*1024) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return diff --git a/routers/api/packages/container/blob.go b/routers/api/packages/container/blob.go index c8e8dd054..f0457c55e 100644 --- a/routers/api/packages/container/blob.go +++ b/routers/api/packages/container/blob.go @@ -27,6 +27,10 @@ var uploadVersionMutex sync.Mutex // saveAsPackageBlob creates a package blob from an upload // The uploaded blob gets stored in a special upload version to link them to the package/image func saveAsPackageBlob(hsr packages_module.HashedSizeReader, pci *packages_service.PackageCreationInfo) (*packages_model.PackageBlob, error) { + if err := packages_service.CheckSizeQuotaExceeded(db.DefaultContext, pci.Creator, pci.Owner, packages_model.TypeContainer, hsr.Size()); err != nil { + return nil, err + } + pb := packages_service.NewPackageBlob(hsr) exists := false @@ -39,10 +43,6 @@ func saveAsPackageBlob(hsr packages_module.HashedSizeReader, pci *packages_servi } err = db.WithTx(db.DefaultContext, func(ctx context.Context) error { - if err := packages_service.CheckSizeQuotaExceeded(ctx, pci.Creator, pci.Owner, packages_model.TypeContainer, hsr.Size()); err != nil { - return err - } - pb, exists, err = packages_model.GetOrInsertBlob(ctx, pb) if err != nil { log.Error("Error inserting package blob: %v", err) diff --git a/routers/api/packages/container/container.go b/routers/api/packages/container/container.go index 63c49809a..883fe73cb 100644 --- a/routers/api/packages/container/container.go +++ b/routers/api/packages/container/container.go @@ -219,7 +219,7 @@ func InitiateUploadBlob(ctx *context.Context) { digest := ctx.FormTrim("digest") if digest != "" { - buf, err := packages_module.CreateHashedBufferFromReader(ctx.Req.Body) + buf, err := packages_module.CreateHashedBufferFromReader(ctx.Req.Body, 32*1024*1024) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return @@ -538,7 +538,7 @@ func UploadManifest(ctx *context.Context) { } maxSize := maxManifestSize + 1 - buf, err := packages_module.CreateHashedBufferFromReaderWithSize(&io.LimitedReader{R: ctx.Req.Body, N: int64(maxSize)}, maxSize) + buf, err := packages_module.CreateHashedBufferFromReader(&io.LimitedReader{R: ctx.Req.Body, N: int64(maxSize)}, maxSize) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return diff --git a/routers/api/packages/debian/debian.go b/routers/api/packages/debian/debian.go deleted file mode 100644 index 3cda04f96..000000000 --- a/routers/api/packages/debian/debian.go +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright 2023 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package debian - -import ( - stdctx "context" - "errors" - "fmt" - "io" - "net/http" - "strings" - - "code.gitea.io/gitea/models/db" - packages_model "code.gitea.io/gitea/models/packages" - "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/notification" - packages_module "code.gitea.io/gitea/modules/packages" - debian_module "code.gitea.io/gitea/modules/packages/debian" - "code.gitea.io/gitea/modules/util" - "code.gitea.io/gitea/routers/api/packages/helper" - packages_service "code.gitea.io/gitea/services/packages" - debian_service "code.gitea.io/gitea/services/packages/debian" -) - -func apiError(ctx *context.Context, status int, obj interface{}) { - helper.LogAndProcessError(ctx, status, obj, func(message string) { - ctx.PlainText(status, message) - }) -} - -func GetRepositoryKey(ctx *context.Context) { - _, pub, err := debian_service.GetOrCreateKeyPair(ctx.Package.Owner.ID) - if err != nil { - apiError(ctx, http.StatusInternalServerError, err) - return - } - - ctx.ServeContent(strings.NewReader(pub), &context.ServeHeaderOptions{ - ContentType: "application/pgp-keys", - Filename: "repository.key", - }) -} - -// https://wiki.debian.org/DebianRepository/Format#A.22Release.22_files -// https://wiki.debian.org/DebianRepository/Format#A.22Packages.22_Indices -func GetRepositoryFile(ctx *context.Context) { - pv, err := debian_service.GetOrCreateRepositoryVersion(ctx.Package.Owner.ID) - if err != nil { - apiError(ctx, http.StatusInternalServerError, err) - return - } - - key := ctx.Params("distribution") - - component := ctx.Params("component") - architecture := strings.TrimPrefix(ctx.Params("architecture"), "binary-") - if component != "" && architecture != "" { - key += "|" + component + "|" + architecture - } - - s, pf, err := packages_service.GetFileStreamByPackageVersion( - ctx, - pv, - &packages_service.PackageFileInfo{ - Filename: ctx.Params("filename"), - CompositeKey: key, - }, - ) - if err != nil { - if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } - return - } - defer s.Close() - - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) -} - -// https://wiki.debian.org/DebianRepository/Format#indices_acquisition_via_hashsums_.28by-hash.29 -func GetRepositoryFileByHash(ctx *context.Context) { - pv, err := debian_service.GetOrCreateRepositoryVersion(ctx.Package.Owner.ID) - if err != nil { - apiError(ctx, http.StatusInternalServerError, err) - return - } - - algorithmn := strings.ToLower(ctx.Params("algorithmn")) - if algorithmn == "md5sum" { - algorithmn = "md5" - } - - pfs, _, err := packages_model.SearchFiles(ctx, &packages_model.PackageFileSearchOptions{ - VersionID: pv.ID, - Hash: strings.ToLower(ctx.Params("hash")), - HashAlgorithmn: algorithmn, - }) - if err != nil { - apiError(ctx, http.StatusInternalServerError, err) - return - } - if len(pfs) != 1 { - apiError(ctx, http.StatusNotFound, nil) - return - } - - s, pf, err := packages_service.GetPackageFileStream(ctx, pfs[0]) - if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } - return - } - defer s.Close() - - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) -} - -func UploadPackageFile(ctx *context.Context) { - distribution := strings.TrimSpace(ctx.Params("distribution")) - component := strings.TrimSpace(ctx.Params("component")) - if distribution == "" || component == "" { - apiError(ctx, http.StatusBadRequest, "invalid distribution or component") - return - } - - upload, close, err := ctx.UploadStream() - if err != nil { - apiError(ctx, http.StatusInternalServerError, err) - return - } - if close { - defer upload.Close() - } - - buf, err := packages_module.CreateHashedBufferFromReader(upload) - if err != nil { - apiError(ctx, http.StatusInternalServerError, err) - return - } - defer buf.Close() - - pck, err := debian_module.ParsePackage(buf) - if err != nil { - if errors.Is(err, util.ErrInvalidArgument) { - apiError(ctx, http.StatusBadRequest, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } - return - } - - if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) - return - } - - _, _, err = packages_service.CreatePackageOrAddFileToExisting( - &packages_service.PackageCreationInfo{ - PackageInfo: packages_service.PackageInfo{ - Owner: ctx.Package.Owner, - PackageType: packages_model.TypeDebian, - Name: pck.Name, - Version: pck.Version, - }, - Creator: ctx.Doer, - Metadata: pck.Metadata, - }, - &packages_service.PackageFileCreationInfo{ - PackageFileInfo: packages_service.PackageFileInfo{ - Filename: fmt.Sprintf("%s_%s_%s.deb", pck.Name, pck.Version, pck.Architecture), - CompositeKey: fmt.Sprintf("%s|%s", distribution, component), - }, - Creator: ctx.Doer, - Data: buf, - IsLead: true, - Properties: map[string]string{ - debian_module.PropertyDistribution: distribution, - debian_module.PropertyComponent: component, - debian_module.PropertyArchitecture: pck.Architecture, - debian_module.PropertyControl: pck.Control, - }, - }, - ) - if err != nil { - switch err { - case packages_model.ErrDuplicatePackageVersion: - apiError(ctx, http.StatusBadRequest, 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 := debian_service.BuildSpecificRepositoryFiles(ctx, ctx.Package.Owner.ID, distribution, component, pck.Architecture); err != nil { - apiError(ctx, http.StatusInternalServerError, err) - return - } - - ctx.Status(http.StatusCreated) -} - -func DownloadPackageFile(ctx *context.Context) { - name := ctx.Params("name") - version := ctx.Params("version") - - s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( - ctx, - &packages_service.PackageInfo{ - Owner: ctx.Package.Owner, - PackageType: packages_model.TypeDebian, - Name: name, - Version: version, - }, - &packages_service.PackageFileInfo{ - Filename: fmt.Sprintf("%s_%s_%s.deb", name, version, ctx.Params("architecture")), - CompositeKey: fmt.Sprintf("%s|%s", ctx.Params("distribution"), ctx.Params("component")), - }, - ) - if err != nil { - if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } - return - } - defer s.Close() - - ctx.ServeContent(s, &context.ServeHeaderOptions{ - ContentType: "application/vnd.debian.binary-package", - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) -} - -func DeletePackageFile(ctx *context.Context) { - distribution := ctx.Params("distribution") - component := ctx.Params("component") - name := ctx.Params("name") - version := ctx.Params("version") - architecture := ctx.Params("architecture") - - owner := ctx.Package.Owner - - var pd *packages_model.PackageDescriptor - - err := db.WithTx(ctx, func(ctx stdctx.Context) error { - pv, err := packages_model.GetVersionByNameAndVersion(ctx, owner.ID, packages_model.TypeDebian, name, version) - if err != nil { - return err - } - - pf, err := packages_model.GetFileForVersionByName( - ctx, - pv.ID, - fmt.Sprintf("%s_%s_%s.deb", name, version, architecture), - fmt.Sprintf("%s|%s", distribution, component), - ) - if err != nil { - return err - } - - if err := packages_service.DeletePackageFile(ctx, pf); err != nil { - return err - } - - has, err := packages_model.HasVersionFileReferences(ctx, pv.ID) - if err != nil { - return err - } - if !has { - pd, err = packages_model.GetPackageDescriptor(ctx, pv) - if err != nil { - return err - } - - if err := packages_service.DeletePackageVersionAndReferences(ctx, pv); err != nil { - return err - } - } - - return nil - }) - if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } - return - } - - if pd != nil { - notification.NotifyPackageDelete(ctx, ctx.Doer, pd) - } - - if err := debian_service.BuildSpecificRepositoryFiles(ctx, ctx.Package.Owner.ID, distribution, component, architecture); err != nil { - apiError(ctx, http.StatusInternalServerError, err) - return - } - - ctx.Status(http.StatusNoContent) -} diff --git a/routers/api/packages/generic/generic.go b/routers/api/packages/generic/generic.go index 0c873119e..5fba02cac 100644 --- a/routers/api/packages/generic/generic.go +++ b/routers/api/packages/generic/generic.go @@ -84,7 +84,7 @@ func UploadPackage(ctx *context.Context) { defer upload.Close() } - buf, err := packages_module.CreateHashedBufferFromReader(upload) + buf, err := packages_module.CreateHashedBufferFromReader(upload, 32*1024*1024) if err != nil { log.Error("Error creating hashed buffer: %v", err) apiError(ctx, http.StatusInternalServerError, err) diff --git a/routers/api/packages/helm/helm.go b/routers/api/packages/helm/helm.go index b7edc8b7f..3bcce6bdf 100644 --- a/routers/api/packages/helm/helm.go +++ b/routers/api/packages/helm/helm.go @@ -155,7 +155,7 @@ func UploadPackage(ctx *context.Context) { defer upload.Close() } - buf, err := packages_module.CreateHashedBufferFromReader(upload) + buf, err := packages_module.CreateHashedBufferFromReader(upload, 32*1024*1024) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return diff --git a/routers/api/packages/maven/maven.go b/routers/api/packages/maven/maven.go index dd270ff0e..a3a23ecfa 100644 --- a/routers/api/packages/maven/maven.go +++ b/routers/api/packages/maven/maven.go @@ -245,7 +245,7 @@ func UploadPackageFile(ctx *context.Context) { packageName := params.GroupID + "-" + params.ArtifactID - buf, err := packages_module.CreateHashedBufferFromReader(ctx.Req.Body) + buf, err := packages_module.CreateHashedBufferFromReader(ctx.Req.Body, 32*1024*1024) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return diff --git a/routers/api/packages/npm/npm.go b/routers/api/packages/npm/npm.go index 89476a776..51b34d3e2 100644 --- a/routers/api/packages/npm/npm.go +++ b/routers/api/packages/npm/npm.go @@ -189,7 +189,7 @@ func UploadPackage(ctx *context.Context) { } } - buf, err := packages_module.CreateHashedBufferFromReader(bytes.NewReader(npmPackage.Data)) + buf, err := packages_module.CreateHashedBufferFromReader(bytes.NewReader(npmPackage.Data), 32*1024*1024) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return diff --git a/routers/api/packages/nuget/nuget.go b/routers/api/packages/nuget/nuget.go index f6143ce29..3418bf995 100644 --- a/routers/api/packages/nuget/nuget.go +++ b/routers/api/packages/nuget/nuget.go @@ -475,7 +475,7 @@ func UploadSymbolPackage(ctx *context.Context) { Version: np.Version, } - _, err = packages_service.AddFileToExistingPackage( + _, _, err = packages_service.AddFileToExistingPackage( pi, &packages_service.PackageFileCreationInfo{ PackageFileInfo: packages_service.PackageFileInfo{ @@ -501,7 +501,7 @@ func UploadSymbolPackage(ctx *context.Context) { } for _, pdb := range pdbs { - _, err := packages_service.AddFileToExistingPackage( + _, _, err := packages_service.AddFileToExistingPackage( pi, &packages_service.PackageFileCreationInfo{ PackageFileInfo: packages_service.PackageFileInfo{ @@ -545,7 +545,7 @@ func processUploadedFile(ctx *context.Context, expectedType nuget_module.Package closables = append(closables, upload) } - buf, err := packages_module.CreateHashedBufferFromReader(upload) + buf, err := packages_module.CreateHashedBufferFromReader(upload, 32*1024*1024) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return nil, nil, closables diff --git a/routers/api/packages/pub/pub.go b/routers/api/packages/pub/pub.go index ae0c6e785..1ece4e18e 100644 --- a/routers/api/packages/pub/pub.go +++ b/routers/api/packages/pub/pub.go @@ -166,7 +166,7 @@ func UploadPackageFile(ctx *context.Context) { } defer file.Close() - buf, err := packages_module.CreateHashedBufferFromReader(file) + buf, err := packages_module.CreateHashedBufferFromReader(file, 32*1024*1024) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return diff --git a/routers/api/packages/pypi/pypi.go b/routers/api/packages/pypi/pypi.go index 90a37ec2a..2f71801a8 100644 --- a/routers/api/packages/pypi/pypi.go +++ b/routers/api/packages/pypi/pypi.go @@ -117,7 +117,7 @@ func UploadPackageFile(ctx *context.Context) { } defer file.Close() - buf, err := packages_module.CreateHashedBufferFromReader(file) + buf, err := packages_module.CreateHashedBufferFromReader(file, 32*1024*1024) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return diff --git a/routers/api/packages/rubygems/rubygems.go b/routers/api/packages/rubygems/rubygems.go index 740efa9ba..af358fb82 100644 --- a/routers/api/packages/rubygems/rubygems.go +++ b/routers/api/packages/rubygems/rubygems.go @@ -209,7 +209,7 @@ func UploadPackageFile(ctx *context.Context) { defer upload.Close() } - buf, err := packages_module.CreateHashedBufferFromReader(upload) + buf, err := packages_module.CreateHashedBufferFromReader(upload, 32*1024*1024) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return diff --git a/routers/api/packages/swift/swift.go b/routers/api/packages/swift/swift.go index 06f592dd6..f78f70377 100644 --- a/routers/api/packages/swift/swift.go +++ b/routers/api/packages/swift/swift.go @@ -300,7 +300,7 @@ func UploadPackageFile(ctx *context.Context) { } defer file.Close() - buf, err := packages_module.CreateHashedBufferFromReader(file) + buf, err := packages_module.CreateHashedBufferFromReader(file, 32*1024*1024) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return diff --git a/routers/api/packages/vagrant/vagrant.go b/routers/api/packages/vagrant/vagrant.go index cefdc45b1..7b76ab79b 100644 --- a/routers/api/packages/vagrant/vagrant.go +++ b/routers/api/packages/vagrant/vagrant.go @@ -158,7 +158,7 @@ func UploadPackageFile(ctx *context.Context) { defer upload.Close() } - buf, err := packages_module.CreateHashedBufferFromReader(upload) + buf, err := packages_module.CreateHashedBufferFromReader(upload, 32*1024*1024) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return diff --git a/routers/api/v1/packages/package.go b/routers/api/v1/packages/package.go index ac48eb8a5..200dc5aaf 100644 --- a/routers/api/v1/packages/package.go +++ b/routers/api/v1/packages/package.go @@ -40,7 +40,7 @@ func ListPackages(ctx *context.APIContext) { // in: query // description: package type filter // type: string - // enum: [cargo, chef, composer, conan, conda, container, debian, generic, helm, maven, npm, nuget, pub, pypi, rubygems, swift, vagrant] + // enum: [cargo, chef, composer, conan, conda, container, generic, helm, maven, npm, nuget, pub, pypi, rubygems, swift, vagrant] // - name: q // in: query // description: name filter diff --git a/routers/web/user/package.go b/routers/web/user/package.go index 37ee0b863..a9acc5281 100644 --- a/routers/web/user/package.go +++ b/routers/web/user/package.go @@ -14,10 +14,8 @@ import ( access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" - debian_module "code.gitea.io/gitea/modules/packages/debian" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" @@ -165,32 +163,6 @@ func ViewPackageVersion(ctx *context.Context) { ctx.Data["IsPackagesPage"] = true ctx.Data["PackageDescriptor"] = pd - switch pd.Package.Type { - case packages_model.TypeContainer: - ctx.Data["RegistryHost"] = setting.Packages.RegistryHost - case packages_model.TypeDebian: - distributions := make(container.Set[string]) - components := make(container.Set[string]) - architectures := make(container.Set[string]) - - for _, f := range pd.Files { - for _, pp := range f.Properties { - switch pp.Name { - case debian_module.PropertyDistribution: - distributions.Add(pp.Value) - case debian_module.PropertyComponent: - components.Add(pp.Value) - case debian_module.PropertyArchitecture: - architectures.Add(pp.Value) - } - } - } - - ctx.Data["Distributions"] = distributions.Values() - ctx.Data["Components"] = components.Values() - ctx.Data["Architectures"] = architectures.Values() - } - var ( total int64 pvs []*packages_model.PackageVersion @@ -198,6 +170,8 @@ func ViewPackageVersion(ctx *context.Context) { ) switch pd.Package.Type { case packages_model.TypeContainer: + ctx.Data["RegistryHost"] = setting.Packages.RegistryHost + pvs, total, err = container_model.SearchImageTags(ctx, &container_model.ImageTagsSearchOptions{ Paginator: db.NewAbsoluteListOptions(0, 5), PackageID: pd.Package.ID, @@ -209,6 +183,10 @@ func ViewPackageVersion(ctx *context.Context) { PackageID: pd.Package.ID, IsInternal: util.OptionalBoolFalse, }) + if err != nil { + ctx.ServerError("SearchVersions", err) + return + } } if err != nil { ctx.ServerError("", err) diff --git a/services/forms/package_form.go b/services/forms/package_form.go index efe4a0d84..699d0fe44 100644 --- a/services/forms/package_form.go +++ b/services/forms/package_form.go @@ -15,7 +15,7 @@ import ( type PackageCleanupRuleForm struct { ID int64 Enabled bool - Type string `binding:"Required;In(cargo,chef,composer,conan,conda,container,debian,generic,helm,maven,npm,nuget,pub,pypi,rubygems,swift,vagrant)"` + Type string `binding:"Required;In(cargo,chef,composer,conan,conda,container,generic,helm,maven,npm,nuget,pub,pypi,rubygems,swift,vagrant)"` KeepCount int `binding:"In(0,1,5,10,25,50,100)"` KeepPattern string `binding:"RegexPattern"` RemoveDays int `binding:"In(0,7,14,30,60,90,180)"` diff --git a/services/packages/cleanup/cleanup.go b/services/packages/cleanup/cleanup.go index 43fbc1ad9..2d62a028a 100644 --- a/services/packages/cleanup/cleanup.go +++ b/services/packages/cleanup/cleanup.go @@ -17,7 +17,6 @@ import ( packages_service "code.gitea.io/gitea/services/packages" cargo_service "code.gitea.io/gitea/services/packages/cargo" container_service "code.gitea.io/gitea/services/packages/container" - debian_service "code.gitea.io/gitea/services/packages/debian" ) // Cleanup removes expired package data @@ -46,7 +45,6 @@ func Cleanup(taskCtx context.Context, olderThan time.Duration) error { return fmt.Errorf("CleanupRule [%d]: GetPackagesByType failed: %w", pcr.ID, err) } - anyVersionDeleted := false for _, p := range packages { pvs, _, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{ PackageID: p.ID, @@ -93,7 +91,6 @@ func Cleanup(taskCtx context.Context, olderThan time.Duration) error { } versionDeleted = true - anyVersionDeleted = true } if versionDeleted { @@ -108,14 +105,6 @@ func Cleanup(taskCtx context.Context, olderThan time.Duration) error { } } } - - if anyVersionDeleted { - if pcr.Type == packages_model.TypeDebian { - if err := debian_service.BuildAllRepositoryFiles(ctx, pcr.OwnerID); err != nil { - return fmt.Errorf("CleanupRule [%d]: debian.BuildAllRepositoryFiles failed: %w", pcr.ID, err) - } - } - } return nil }) if err != nil { diff --git a/services/packages/debian/repository.go b/services/packages/debian/repository.go deleted file mode 100644 index eac878256..000000000 --- a/services/packages/debian/repository.go +++ /dev/null @@ -1,443 +0,0 @@ -// Copyright 2023 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package debian - -import ( - "bytes" - "compress/gzip" - "context" - "errors" - "fmt" - "io" - "sort" - "strings" - "time" - - "code.gitea.io/gitea/models/db" - packages_model "code.gitea.io/gitea/models/packages" - debian_model "code.gitea.io/gitea/models/packages/debian" - user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/log" - packages_module "code.gitea.io/gitea/modules/packages" - debian_module "code.gitea.io/gitea/modules/packages/debian" - "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/util" - packages_service "code.gitea.io/gitea/services/packages" - - "github.com/keybase/go-crypto/openpgp" - "github.com/keybase/go-crypto/openpgp/armor" - "github.com/keybase/go-crypto/openpgp/clearsign" - "github.com/keybase/go-crypto/openpgp/packet" - "github.com/ulikunitz/xz" -) - -// GetOrCreateRepositoryVersion gets or creates the internal repository package -// The Debian registry needs multiple index files which are stored in this package. -func GetOrCreateRepositoryVersion(ownerID int64) (*packages_model.PackageVersion, error) { - var repositoryVersion *packages_model.PackageVersion - - return repositoryVersion, db.WithTx(db.DefaultContext, func(ctx context.Context) error { - p := &packages_model.Package{ - OwnerID: ownerID, - Type: packages_model.TypeDebian, - Name: debian_module.RepositoryPackage, - LowerName: debian_module.RepositoryPackage, - IsInternal: true, - } - var err error - if p, err = packages_model.TryInsertPackage(ctx, p); err != nil { - if err != packages_model.ErrDuplicatePackage { - log.Error("Error inserting package: %v", err) - return err - } - } - - pv := &packages_model.PackageVersion{ - PackageID: p.ID, - CreatorID: ownerID, - Version: debian_module.RepositoryVersion, - LowerVersion: debian_module.RepositoryVersion, - IsInternal: true, - MetadataJSON: "null", - } - if pv, err = packages_model.GetOrInsertVersion(ctx, pv); err != nil { - if err != packages_model.ErrDuplicatePackageVersion { - log.Error("Error inserting package version: %v", err) - return err - } - } - - repositoryVersion = pv - - return nil - }) -} - -// GetOrCreateKeyPair gets or creates the PGP keys used to sign repository files -func GetOrCreateKeyPair(ownerID int64) (string, string, error) { - priv, err := user_model.GetSetting(ownerID, debian_module.SettingKeyPrivate) - if err != nil && !errors.Is(err, util.ErrNotExist) { - return "", "", err - } - - pub, err := user_model.GetSetting(ownerID, debian_module.SettingKeyPublic) - if err != nil && !errors.Is(err, util.ErrNotExist) { - return "", "", err - } - - if priv == "" || pub == "" { - priv, pub, err = generateKeypair() - if err != nil { - return "", "", err - } - - if err := user_model.SetUserSetting(ownerID, debian_module.SettingKeyPrivate, priv); err != nil { - return "", "", err - } - - if err := user_model.SetUserSetting(ownerID, debian_module.SettingKeyPublic, pub); err != nil { - return "", "", err - } - } - - return priv, pub, nil -} - -func generateKeypair() (string, string, error) { - e, err := openpgp.NewEntity(setting.AppName, "Debian Registry", "", nil) - if err != nil { - return "", "", err - } - - var priv strings.Builder - var pub strings.Builder - - w, err := armor.Encode(&priv, openpgp.PrivateKeyType, nil) - if err != nil { - return "", "", err - } - if err := e.SerializePrivate(w, nil); err != nil { - return "", "", err - } - w.Close() - - w, err = armor.Encode(&pub, openpgp.PublicKeyType, nil) - if err != nil { - return "", "", err - } - if err := e.Serialize(w); err != nil { - return "", "", err - } - w.Close() - - return priv.String(), pub.String(), nil -} - -// BuildAllRepositoryFiles (re)builds all repository files for every available distributions, components and architectures -func BuildAllRepositoryFiles(ctx context.Context, ownerID int64) error { - pv, err := GetOrCreateRepositoryVersion(ownerID) - if err != nil { - return err - } - - // 1. Delete all existing repository files - pfs, err := packages_model.GetFilesByVersionID(ctx, pv.ID) - if err != nil { - return err - } - - for _, pf := range pfs { - if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeFile, pf.ID); err != nil { - return err - } - if err := packages_model.DeleteFileByID(ctx, pf.ID); err != nil { - return err - } - } - - // 2. (Re)Build repository files for existing packages - distributions, err := debian_model.GetDistributions(ctx, ownerID) - if err != nil { - return err - } - for _, distribution := range distributions { - components, err := debian_model.GetComponents(ctx, ownerID, distribution) - if err != nil { - return err - } - architectures, err := debian_model.GetArchitectures(ctx, ownerID, distribution) - if err != nil { - return err - } - - for _, component := range components { - for _, architecture := range architectures { - if err := buildRepositoryFiles(ctx, ownerID, pv, distribution, component, architecture); err != nil { - return fmt.Errorf("failed to build repository files [%s/%s/%s]: %w", distribution, component, architecture, err) - } - } - } - } - - return nil -} - -// BuildSpecificRepositoryFiles builds index files for the repository -func BuildSpecificRepositoryFiles(ctx context.Context, ownerID int64, distribution, component, architecture string) error { - pv, err := GetOrCreateRepositoryVersion(ownerID) - if err != nil { - return err - } - - return buildRepositoryFiles(ctx, ownerID, pv, distribution, component, architecture) -} - -func buildRepositoryFiles(ctx context.Context, ownerID int64, repoVersion *packages_model.PackageVersion, distribution, component, architecture string) error { - if err := buildPackagesIndices(ctx, ownerID, repoVersion, distribution, component, architecture); err != nil { - return err - } - - return buildReleaseFiles(ctx, ownerID, repoVersion, distribution) -} - -// https://wiki.debian.org/DebianRepository/Format#A.22Packages.22_Indices -func buildPackagesIndices(ctx context.Context, ownerID int64, repoVersion *packages_model.PackageVersion, distribution, component, architecture string) error { - pfds, err := debian_model.SearchLatestPackages(ctx, &debian_model.PackageSearchOptions{ - OwnerID: ownerID, - Distribution: distribution, - Component: component, - Architecture: architecture, - }) - if err != nil { - return err - } - - // Delete the package indices if there are no packages - if len(pfds) == 0 { - key := fmt.Sprintf("%s|%s|%s", distribution, component, architecture) - for _, filename := range []string{"Packages", "Packages.gz", "Packages.xz"} { - pf, err := packages_model.GetFileForVersionByName(ctx, repoVersion.ID, filename, key) - if err != nil && !errors.Is(err, util.ErrNotExist) { - return err - } - - if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeFile, pf.ID); err != nil { - return err - } - if err := packages_model.DeleteFileByID(ctx, pf.ID); err != nil { - return err - } - } - - return nil - } - - packagesContent, _ := packages_module.NewHashedBuffer() - - packagesGzipContent, _ := packages_module.NewHashedBuffer() - gzw := gzip.NewWriter(packagesGzipContent) - - packagesXzContent, _ := packages_module.NewHashedBuffer() - xzw, _ := xz.NewWriter(packagesXzContent) - - w := io.MultiWriter(packagesContent, gzw, xzw) - - addSeperator := false - for _, pfd := range pfds { - if addSeperator { - fmt.Fprintln(w) - } - addSeperator = true - - fmt.Fprint(w, pfd.Properties.GetByName(debian_module.PropertyControl)) - - fmt.Fprintf(w, "Filename: pool/%s/%s/%s\n", distribution, component, pfd.File.Name) - fmt.Fprintf(w, "Size: %d\n", pfd.Blob.Size) - fmt.Fprintf(w, "MD5sum: %s\n", pfd.Blob.HashMD5) - fmt.Fprintf(w, "SHA1: %s\n", pfd.Blob.HashSHA1) - fmt.Fprintf(w, "SHA256: %s\n", pfd.Blob.HashSHA256) - fmt.Fprintf(w, "SHA512: %s\n", pfd.Blob.HashSHA512) - } - - gzw.Close() - xzw.Close() - - for _, file := range []struct { - Name string - Data packages_module.HashedSizeReader - }{ - {"Packages", packagesContent}, - {"Packages.gz", packagesGzipContent}, - {"Packages.xz", packagesXzContent}, - } { - _, err = packages_service.AddFileToPackageVersionInternal( - repoVersion, - &packages_service.PackageFileCreationInfo{ - PackageFileInfo: packages_service.PackageFileInfo{ - Filename: file.Name, - CompositeKey: fmt.Sprintf("%s|%s|%s", distribution, component, architecture), - }, - Creator: user_model.NewGhostUser(), - Data: file.Data, - IsLead: false, - OverwriteExisting: true, - Properties: map[string]string{ - debian_module.PropertyRepositoryIncludeInRelease: "", - debian_module.PropertyDistribution: distribution, - debian_module.PropertyComponent: component, - debian_module.PropertyArchitecture: architecture, - }, - }, - ) - if err != nil { - return err - } - } - - return nil -} - -// https://wiki.debian.org/DebianRepository/Format#A.22Release.22_files -func buildReleaseFiles(ctx context.Context, ownerID int64, repoVersion *packages_model.PackageVersion, distribution string) error { - pfs, _, err := packages_model.SearchFiles(ctx, &packages_model.PackageFileSearchOptions{ - VersionID: repoVersion.ID, - Properties: map[string]string{ - debian_module.PropertyRepositoryIncludeInRelease: "", - debian_module.PropertyDistribution: distribution, - }, - }) - if err != nil { - return err - } - - // Delete the release files if there are no packages - if len(pfs) == 0 { - for _, filename := range []string{"Release", "Release.gpg", "InRelease"} { - pf, err := packages_model.GetFileForVersionByName(ctx, repoVersion.ID, filename, distribution) - if err != nil && !errors.Is(err, util.ErrNotExist) { - return err - } - - if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeFile, pf.ID); err != nil { - return err - } - if err := packages_model.DeleteFileByID(ctx, pf.ID); err != nil { - return err - } - } - - return nil - } - - components, err := debian_model.GetComponents(ctx, ownerID, distribution) - if err != nil { - return err - } - - sort.Strings(components) - - architectures, err := debian_model.GetArchitectures(ctx, ownerID, distribution) - if err != nil { - return err - } - - sort.Strings(architectures) - - priv, _, err := GetOrCreateKeyPair(ownerID) - if err != nil { - return err - } - - block, err := armor.Decode(strings.NewReader(priv)) - if err != nil { - return err - } - - e, err := openpgp.ReadEntity(packet.NewReader(block.Body)) - if err != nil { - return err - } - - inReleaseContent, _ := packages_module.NewHashedBuffer() - sw, err := clearsign.Encode(inReleaseContent, e.PrivateKey, nil) - if err != nil { - return err - } - - var buf bytes.Buffer - - w := io.MultiWriter(sw, &buf) - - fmt.Fprintf(w, "Origin: %s\n", setting.AppName) - fmt.Fprintf(w, "Label: %s\n", setting.AppName) - fmt.Fprintf(w, "Suite: %s\n", distribution) - fmt.Fprintf(w, "Codename: %s\n", distribution) - fmt.Fprintf(w, "Components: %s\n", strings.Join(components, " ")) - fmt.Fprintf(w, "Architectures: %s\n", strings.Join(architectures, " ")) - fmt.Fprintf(w, "Date: %s\n", time.Now().UTC().Format(time.RFC1123)) - fmt.Fprint(w, "Acquire-By-Hash: yes") - - pfds, err := packages_model.GetPackageFileDescriptors(ctx, pfs) - if err != nil { - return err - } - - var md5, sha1, sha256, sha512 strings.Builder - for _, pfd := range pfds { - path := fmt.Sprintf("%s/binary-%s/%s", pfd.Properties.GetByName(debian_module.PropertyComponent), pfd.Properties.GetByName(debian_module.PropertyArchitecture), pfd.File.Name) - fmt.Fprintf(&md5, " %s %d %s\n", pfd.Blob.HashMD5, pfd.Blob.Size, path) - fmt.Fprintf(&sha1, " %s %d %s\n", pfd.Blob.HashSHA1, pfd.Blob.Size, path) - fmt.Fprintf(&sha256, " %s %d %s\n", pfd.Blob.HashSHA256, pfd.Blob.Size, path) - fmt.Fprintf(&sha512, " %s %d %s\n", pfd.Blob.HashSHA512, pfd.Blob.Size, path) - } - - fmt.Fprintln(w, "MD5Sum:") - fmt.Fprint(w, md5.String()) - fmt.Fprintln(w, "SHA1:") - fmt.Fprint(w, sha1.String()) - fmt.Fprintln(w, "SHA256:") - fmt.Fprint(w, sha256.String()) - fmt.Fprintln(w, "SHA512:") - fmt.Fprint(w, sha512.String()) - - sw.Close() - - releaseGpgContent, _ := packages_module.NewHashedBuffer() - if err := openpgp.ArmoredDetachSign(releaseGpgContent, e, bytes.NewReader(buf.Bytes()), nil); err != nil { - return err - } - - releaseContent, _ := packages_module.CreateHashedBufferFromReader(&buf) - - for _, file := range []struct { - Name string - Data packages_module.HashedSizeReader - }{ - {"Release", releaseContent}, - {"Release.gpg", releaseGpgContent}, - {"InRelease", inReleaseContent}, - } { - _, err = packages_service.AddFileToPackageVersionInternal( - repoVersion, - &packages_service.PackageFileCreationInfo{ - PackageFileInfo: packages_service.PackageFileInfo{ - Filename: file.Name, - CompositeKey: distribution, - }, - Creator: user_model.NewGhostUser(), - Data: file.Data, - IsLead: false, - OverwriteExisting: true, - Properties: map[string]string{ - debian_module.PropertyDistribution: distribution, - }, - }, - ) - if err != nil { - return err - } - } - - return nil -} diff --git a/services/packages/packages.go b/services/packages/packages.go index 735e52c85..dd5c63470 100644 --- a/services/packages/packages.go +++ b/services/packages/packages.go @@ -187,33 +187,19 @@ func createPackageAndVersion(ctx context.Context, pvci *PackageCreationInfo, all } // AddFileToExistingPackage adds a file to an existing package. If the package does not exist, ErrPackageNotExist is returned -func AddFileToExistingPackage(pvi *PackageInfo, pfci *PackageFileCreationInfo) (*packages_model.PackageFile, error) { - return addFileToPackageWrapper(func(ctx context.Context) (*packages_model.PackageFile, *packages_model.PackageBlob, bool, error) { - pv, err := packages_model.GetVersionByNameAndVersion(ctx, pvi.Owner.ID, pvi.PackageType, pvi.Name, pvi.Version) - if err != nil { - return nil, nil, false, err - } - - return addFileToPackageVersion(ctx, pv, pvi, pfci) - }) -} - -// AddFileToPackageVersionInternal adds a file to the package -// This method skips quota checks and should only be used for system-managed packages. -func AddFileToPackageVersionInternal(pv *packages_model.PackageVersion, pfci *PackageFileCreationInfo) (*packages_model.PackageFile, error) { - return addFileToPackageWrapper(func(ctx context.Context) (*packages_model.PackageFile, *packages_model.PackageBlob, bool, error) { - return addFileToPackageVersionUnchecked(ctx, pv, pfci) - }) -} - -func addFileToPackageWrapper(fn func(ctx context.Context) (*packages_model.PackageFile, *packages_model.PackageBlob, bool, error)) (*packages_model.PackageFile, error) { +func AddFileToExistingPackage(pvi *PackageInfo, pfci *PackageFileCreationInfo) (*packages_model.PackageVersion, *packages_model.PackageFile, error) { ctx, committer, err := db.TxContext(db.DefaultContext) if err != nil { - return nil, err + return nil, nil, err } defer committer.Close() - pf, pb, blobCreated, err := fn(ctx) + pv, err := packages_model.GetVersionByNameAndVersion(ctx, pvi.Owner.ID, pvi.PackageType, pvi.Name, pvi.Version) + if err != nil { + return nil, nil, err + } + + pf, pb, blobCreated, err := addFileToPackageVersion(ctx, pv, pvi, pfci) removeBlob := false defer func() { if removeBlob { @@ -225,15 +211,15 @@ func addFileToPackageWrapper(fn func(ctx context.Context) (*packages_model.Packa }() if err != nil { removeBlob = blobCreated - return nil, err + return nil, nil, err } if err := committer.Commit(); err != nil { removeBlob = blobCreated - return nil, err + return nil, nil, err } - return pf, nil + return pv, pf, nil } // NewPackageBlob creates a package blob instance @@ -250,16 +236,12 @@ func NewPackageBlob(hsr packages_module.HashedSizeReader) *packages_model.Packag } func addFileToPackageVersion(ctx context.Context, pv *packages_model.PackageVersion, pvi *PackageInfo, pfci *PackageFileCreationInfo) (*packages_model.PackageFile, *packages_model.PackageBlob, bool, error) { + log.Trace("Adding package file: %v, %s", pv.ID, pfci.Filename) + if err := CheckSizeQuotaExceeded(ctx, pfci.Creator, pvi.Owner, pvi.PackageType, pfci.Data.Size()); err != nil { return nil, nil, false, err } - return addFileToPackageVersionUnchecked(ctx, pv, pfci) -} - -func addFileToPackageVersionUnchecked(ctx context.Context, pv *packages_model.PackageVersion, pfci *PackageFileCreationInfo) (*packages_model.PackageFile, *packages_model.PackageBlob, bool, error) { - log.Trace("Adding package file: %v, %s", pv.ID, pfci.Filename) - pb, exists, err := packages_model.GetOrInsertBlob(ctx, NewPackageBlob(pfci.Data)) if err != nil { log.Error("Error inserting package blob: %v", err) @@ -363,8 +345,6 @@ func CheckSizeQuotaExceeded(ctx context.Context, doer, owner *user_model.User, p typeSpecificSize = setting.Packages.LimitSizeConda case packages_model.TypeContainer: typeSpecificSize = setting.Packages.LimitSizeContainer - case packages_model.TypeDebian: - typeSpecificSize = setting.Packages.LimitSizeDebian case packages_model.TypeGeneric: typeSpecificSize = setting.Packages.LimitSizeGeneric case packages_model.TypeHelm: diff --git a/templates/package/content/debian.tmpl b/templates/package/content/debian.tmpl deleted file mode 100644 index c10c3042b..000000000 --- a/templates/package/content/debian.tmpl +++ /dev/null @@ -1,65 +0,0 @@ -{{if eq .PackageDescriptor.Package.Type "debian"}} -

{{.locale.Tr "packages.installation"}}

-
-
-
- -
sudo curl  -o /etc/apt/trusted.gpg.d/gitea-{{$.PackageDescriptor.Owner.Name}}.asc
-echo "deb  <distribution> <component>" | sudo tee -a /etc/apt/sources.list.d/gitea.list
-sudo apt update
-

{{.locale.Tr "packages.debian.registry.info" | Safe}}

-
-
- -
-
sudo apt install {{$.PackageDescriptor.Package.Name}}={{$.PackageDescriptor.Version.Version}}
-
-
-
- -
-
-
- -

{{.locale.Tr "packages.debian.repository"}}

-
- - - - - - - - - - - - - - - -
{{.locale.Tr "packages.debian.repository.distributions"}}
{{Join .Distributions ", "}}
{{.locale.Tr "packages.debian.repository.components"}}
{{Join .Components ", "}}
{{.locale.Tr "packages.debian.repository.architectures"}}
{{Join .Architectures ", "}}
-
- - {{if .PackageDescriptor.Metadata.Description}} -

{{.locale.Tr "packages.about"}}

-
- {{.PackageDescriptor.Metadata.Description}} -
- {{end}} - - {{if .PackageDescriptor.Metadata.Dependencies}} -

{{.locale.Tr "packages.dependencies"}}

-
- - - {{range .PackageDescriptor.Metadata.Dependencies}} - - - - {{end}} - -
{{.}}
-
- {{end}} -{{end}} diff --git a/templates/package/metadata/debian.tmpl b/templates/package/metadata/debian.tmpl deleted file mode 100644 index 93b6db3bd..000000000 --- a/templates/package/metadata/debian.tmpl +++ /dev/null @@ -1,4 +0,0 @@ -{{if eq .PackageDescriptor.Package.Type "debian"}} - {{if .PackageDescriptor.Metadata.Maintainer}}
{{svg "octicon-person" 16 "mr-3"}} {{.PackageDescriptor.Metadata.Maintainer}}
{{end}} - {{if .PackageDescriptor.Metadata.ProjectURL}}
{{svg "octicon-link-external" 16 "mr-3"}} {{.locale.Tr "packages.details.project_site"}}
{{end}} -{{end}} diff --git a/templates/package/view.tmpl b/templates/package/view.tmpl index 30e737d09..3cb130851 100644 --- a/templates/package/view.tmpl +++ b/templates/package/view.tmpl @@ -25,7 +25,6 @@ {{template "package/content/conan" .}} {{template "package/content/conda" .}} {{template "package/content/container" .}} - {{template "package/content/debian" .}} {{template "package/content/generic" .}} {{template "package/content/helm" .}} {{template "package/content/maven" .}} @@ -53,7 +52,6 @@ {{template "package/metadata/conan" .}} {{template "package/metadata/conda" .}} {{template "package/metadata/container" .}} - {{template "package/metadata/debian" .}} {{template "package/metadata/generic" .}} {{template "package/metadata/helm" .}} {{template "package/metadata/maven" .}} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index d65666436..2db950b57 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -2415,7 +2415,6 @@ "conan", "conda", "container", - "debian", "generic", "helm", "maven", diff --git a/tests/integration/api_packages_debian_test.go b/tests/integration/api_packages_debian_test.go deleted file mode 100644 index 3e25acd8c..000000000 --- a/tests/integration/api_packages_debian_test.go +++ /dev/null @@ -1,252 +0,0 @@ -// Copyright 2023 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package integration - -import ( - "archive/tar" - "bytes" - "compress/gzip" - "fmt" - "io" - "net/http" - "strings" - "testing" - - "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/models/packages" - "code.gitea.io/gitea/models/unittest" - user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/base" - debian_module "code.gitea.io/gitea/modules/packages/debian" - "code.gitea.io/gitea/tests" - - "github.com/blakesmith/ar" - "github.com/stretchr/testify/assert" -) - -func TestPackageDebian(t *testing.T) { - defer tests.PrepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - - packageName := "gitea" - packageVersion := "1.0.3" - packageDescription := "Package Description" - - createArchive := func(name, version, architecture string) io.Reader { - var cbuf bytes.Buffer - zw := gzip.NewWriter(&cbuf) - tw := tar.NewWriter(zw) - tw.WriteHeader(&tar.Header{ - Name: "control", - Mode: 0o600, - Size: 50, - }) - fmt.Fprintf(tw, "Package: %s\nVersion: %s\nArchitecture: %s\nDescription: %s\n", name, version, architecture, packageDescription) - tw.Close() - zw.Close() - - var buf bytes.Buffer - aw := ar.NewWriter(&buf) - aw.WriteGlobalHeader() - hdr := &ar.Header{ - Name: "control.tar.gz", - Mode: 0o600, - Size: int64(cbuf.Len()), - } - aw.WriteHeader(hdr) - aw.Write(cbuf.Bytes()) - return &buf - } - - distributions := []string{"test", "gitea"} - components := []string{"main", "stable"} - architectures := []string{"all", "amd64"} - - rootURL := fmt.Sprintf("/api/packages/%s/debian", user.Name) - - t.Run("RepositoryKey", func(t *testing.T) { - defer tests.PrintCurrentTest(t)() - - req := NewRequest(t, "GET", rootURL+"/repository.key") - resp := MakeRequest(t, req, http.StatusOK) - - assert.Equal(t, "application/pgp-keys", resp.Header().Get("Content-Type")) - assert.Contains(t, resp.Body.String(), "-----BEGIN PGP PUBLIC KEY BLOCK-----") - }) - - for _, distribution := range distributions { - t.Run(fmt.Sprintf("[Distribution:%s]", distribution), func(t *testing.T) { - for _, component := range components { - for _, architecture := range architectures { - t.Run(fmt.Sprintf("[Component:%s,Architecture:%s]", component, architecture), func(t *testing.T) { - t.Run("Upload", func(t *testing.T) { - defer tests.PrintCurrentTest(t)() - - uploadURL := fmt.Sprintf("%s/pool/%s/%s/upload", rootURL, distribution, component) - - req := NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader([]byte{})) - MakeRequest(t, req, http.StatusUnauthorized) - - req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader([]byte{})) - AddBasicAuthHeader(req, user.Name) - MakeRequest(t, req, http.StatusBadRequest) - - req = NewRequestWithBody(t, "PUT", uploadURL, createArchive("", "", "")) - AddBasicAuthHeader(req, user.Name) - MakeRequest(t, req, http.StatusBadRequest) - - req = NewRequestWithBody(t, "PUT", uploadURL, createArchive(packageName, packageVersion, architecture)) - AddBasicAuthHeader(req, user.Name) - MakeRequest(t, req, http.StatusCreated) - - pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeDebian) - assert.NoError(t, err) - assert.Len(t, pvs, 1) - - pd, err := packages.GetPackageDescriptor(db.DefaultContext, pvs[0]) - assert.NoError(t, err) - assert.Nil(t, pd.SemVer) - assert.IsType(t, &debian_module.Metadata{}, pd.Metadata) - assert.Equal(t, packageName, pd.Package.Name) - assert.Equal(t, packageVersion, pd.Version.Version) - - pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID) - assert.NoError(t, err) - assert.NotEmpty(t, pfs) - assert.Condition(t, func() bool { - seen := false - expectedFilename := fmt.Sprintf("%s_%s_%s.deb", packageName, packageVersion, architecture) - expectedCompositeKey := fmt.Sprintf("%s|%s", distribution, component) - for _, pf := range pfs { - if pf.Name == expectedFilename && pf.CompositeKey == expectedCompositeKey { - if seen { - return false - } - seen = true - - assert.True(t, pf.IsLead) - - pfps, err := packages.GetProperties(db.DefaultContext, packages.PropertyTypeFile, pf.ID) - assert.NoError(t, err) - - for _, pfp := range pfps { - switch pfp.Name { - case debian_module.PropertyDistribution: - assert.Equal(t, distribution, pfp.Value) - case debian_module.PropertyComponent: - assert.Equal(t, component, pfp.Value) - case debian_module.PropertyArchitecture: - assert.Equal(t, architecture, pfp.Value) - } - } - } - } - return seen - }) - }) - - t.Run("Download", func(t *testing.T) { - defer tests.PrintCurrentTest(t)() - - req := NewRequest(t, "GET", fmt.Sprintf("%s/pool/%s/%s/%s_%s_%s.deb", rootURL, distribution, component, packageName, packageVersion, architecture)) - resp := MakeRequest(t, req, http.StatusOK) - - assert.Equal(t, "application/vnd.debian.binary-package", resp.Header().Get("Content-Type")) - }) - - t.Run("Packages", func(t *testing.T) { - defer tests.PrintCurrentTest(t)() - - url := fmt.Sprintf("%s/dists/%s/%s/binary-%s/Packages", rootURL, distribution, component, architecture) - - req := NewRequest(t, "GET", url) - resp := MakeRequest(t, req, http.StatusOK) - - body := resp.Body.String() - - assert.Contains(t, body, "Package: "+packageName) - assert.Contains(t, body, "Version: "+packageVersion) - assert.Contains(t, body, "Architecture: "+architecture) - assert.Contains(t, body, fmt.Sprintf("Filename: pool/%s/%s/%s_%s_%s.deb", distribution, component, packageName, packageVersion, architecture)) - - req = NewRequest(t, "GET", url+".gz") - MakeRequest(t, req, http.StatusOK) - - req = NewRequest(t, "GET", url+".xz") - MakeRequest(t, req, http.StatusOK) - - url = fmt.Sprintf("%s/dists/%s/%s/%s/by-hash/SHA256/%s", rootURL, distribution, component, architecture, base.EncodeSha256(body)) - req = NewRequest(t, "GET", url) - resp = MakeRequest(t, req, http.StatusOK) - - assert.Equal(t, body, resp.Body.String()) - }) - }) - } - } - - t.Run("Release", func(t *testing.T) { - defer tests.PrintCurrentTest(t)() - - req := NewRequest(t, "GET", fmt.Sprintf("%s/dists/%s/Release", rootURL, distribution)) - resp := MakeRequest(t, req, http.StatusOK) - - body := resp.Body.String() - - assert.Contains(t, body, "Components: "+strings.Join(components, " ")) - assert.Contains(t, body, "Architectures: "+strings.Join(architectures, " ")) - - for _, component := range components { - for _, architecture := range architectures { - assert.Contains(t, body, fmt.Sprintf("%s/binary-%s/Packages", component, architecture)) - assert.Contains(t, body, fmt.Sprintf("%s/binary-%s/Packages.gz", component, architecture)) - assert.Contains(t, body, fmt.Sprintf("%s/binary-%s/Packages.xz", component, architecture)) - } - } - - req = NewRequest(t, "GET", fmt.Sprintf("%s/dists/%s/by-hash/SHA256/%s", rootURL, distribution, base.EncodeSha256(body))) - resp = MakeRequest(t, req, http.StatusOK) - - assert.Equal(t, body, resp.Body.String()) - - req = NewRequest(t, "GET", fmt.Sprintf("%s/dists/%s/Release.gpg", rootURL, distribution)) - resp = MakeRequest(t, req, http.StatusOK) - - assert.Contains(t, resp.Body.String(), "-----BEGIN PGP SIGNATURE-----") - - req = NewRequest(t, "GET", fmt.Sprintf("%s/dists/%s/InRelease", rootURL, distribution)) - resp = MakeRequest(t, req, http.StatusOK) - - assert.Contains(t, resp.Body.String(), "-----BEGIN PGP SIGNED MESSAGE-----") - }) - }) - } - - t.Run("Delete", func(t *testing.T) { - defer tests.PrintCurrentTest(t)() - - distribution := distributions[0] - architecture := architectures[0] - - for _, component := range components { - req := NewRequest(t, "DELETE", fmt.Sprintf("%s/pool/%s/%s/%s/%s/%s", rootURL, distribution, component, packageName, packageVersion, architecture)) - MakeRequest(t, req, http.StatusUnauthorized) - - req = NewRequest(t, "DELETE", fmt.Sprintf("%s/pool/%s/%s/%s/%s/%s", rootURL, distribution, component, packageName, packageVersion, architecture)) - AddBasicAuthHeader(req, user.Name) - MakeRequest(t, req, http.StatusNoContent) - - req = NewRequest(t, "GET", fmt.Sprintf("%s/dists/%s/%s/binary-%s/Packages", rootURL, distribution, component, architecture)) - MakeRequest(t, req, http.StatusNotFound) - } - - req := NewRequest(t, "GET", fmt.Sprintf("%s/dists/%s/Release", rootURL, distribution)) - resp := MakeRequest(t, req, http.StatusOK) - - body := resp.Body.String() - - assert.Contains(t, body, "Components: "+strings.Join(components, " ")) - assert.Contains(t, body, "Architectures: "+architectures[1]) - }) -} diff --git a/web_src/svg/gitea-debian.svg b/web_src/svg/gitea-debian.svg deleted file mode 100644 index 4046f7fc7..000000000 --- a/web_src/svg/gitea-debian.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - -