mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-06-01 04:40:38 +00:00
Compare commits
8 Commits
c77d788493
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 8dc61cf362 | |||
| 4a9ddbdc34 | |||
| c316ea9b73 | |||
| d027a251ba | |||
| 16b6348710 | |||
| 1c1abe6b10 | |||
| c4bfbe52ca | |||
| c723fea807 |
@@ -155,7 +155,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
name: ["Debian 13/trixie", "Debian 12/bookworm", "Debian 11/bullseye", "Ubuntu 24.04", "Ubuntu 22.04", "Ubuntu 20.04"]
|
name: ["Debian 13/trixie", "Debian 12/bookworm", "Debian 11/bullseye", "Ubuntu 26.04", "Ubuntu 24.04", "Ubuntu 22.04", "Ubuntu 20.04"]
|
||||||
arch: ["amd64", "i386" , "arm64" , "armhf"]
|
arch: ["amd64", "i386" , "arm64" , "armhf"]
|
||||||
include:
|
include:
|
||||||
- name: "Debian 13/trixie"
|
- name: "Debian 13/trixie"
|
||||||
@@ -167,6 +167,9 @@ jobs:
|
|||||||
- name: "Debian 11/bullseye"
|
- name: "Debian 11/bullseye"
|
||||||
suite: bullseye
|
suite: bullseye
|
||||||
image: debian:bullseye-slim
|
image: debian:bullseye-slim
|
||||||
|
- name: "Ubuntu 26.04"
|
||||||
|
suite: resolute
|
||||||
|
image: ubuntu:26.04
|
||||||
- name: "Ubuntu 24.04"
|
- name: "Ubuntu 24.04"
|
||||||
suite: noble
|
suite: noble
|
||||||
image: ubuntu:24.04
|
image: ubuntu:24.04
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ Please report unacceptable behavior on [https://github.com/aptly-dev/aptly/discu
|
|||||||
### List of Repositories
|
### List of Repositories
|
||||||
|
|
||||||
* [aptly-dev/aptly](https://github.com/aptly-dev/aptly) - aptly source code, functional tests, man page
|
* [aptly-dev/aptly](https://github.com/aptly-dev/aptly) - aptly source code, functional tests, man page
|
||||||
* [apty-dev/aptly-dev.github.io](https://github.com/aptly-dev/aptly-dev.github.io) - aptly website (https://www.aptly.info/)
|
* [aptly-dev/aptly-dev.github.io](https://github.com/aptly-dev/aptly-dev.github.io) - aptly website (https://www.aptly.info/)
|
||||||
* [aptly-dev/aptly-fixture-db](https://github.com/aptly-dev/aptly-fixture-db) & [aptly-dev/aptly-fixture-pool](https://github.com/aptly-dev/aptly-fixture-pool) provide
|
* [aptly-dev/aptly-fixture-db](https://github.com/aptly-dev/aptly-fixture-db) & [aptly-dev/aptly-fixture-pool](https://github.com/aptly-dev/aptly-fixture-pool) provide
|
||||||
fixtures for aptly functional tests
|
fixtures for aptly functional tests
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -54,7 +54,7 @@ type gpgDeleteKeyParams struct {
|
|||||||
// @Summary Add GPG Keys
|
// @Summary Add GPG Keys
|
||||||
// @Description **Adds GPG keys to aptly keyring**
|
// @Description **Adds GPG keys to aptly keyring**
|
||||||
// @Description
|
// @Description
|
||||||
// @Description Add GPG public keys for veryfing remote repositories for mirroring.
|
// @Description Add GPG public keys for verifying remote repositories for mirroring.
|
||||||
// @Description
|
// @Description
|
||||||
// @Description Keys can be added in two ways:
|
// @Description Keys can be added in two ways:
|
||||||
// @Description * By providing the ASCII armord key in `GpgKeyArmor` (leave Keyserver and GpgKeyID empty)
|
// @Description * By providing the ASCII armord key in `GpgKeyArmor` (leave Keyserver and GpgKeyID empty)
|
||||||
|
|||||||
+1
-1
@@ -497,7 +497,7 @@ func apiMirrorsEdit(c *gin.Context) {
|
|||||||
type mirrorUpdateParams struct {
|
type mirrorUpdateParams struct {
|
||||||
// Change mirror name to `Name`
|
// Change mirror name to `Name`
|
||||||
Name string ` json:"Name" example:"mirror1"`
|
Name string ` json:"Name" example:"mirror1"`
|
||||||
// Gpg keyring(s) for verifing Release file
|
// Gpg keyring(s) for verifying Release file
|
||||||
Keyrings []string ` json:"Keyrings" example:"trustedkeys.gpg"`
|
Keyrings []string ` json:"Keyrings" example:"trustedkeys.gpg"`
|
||||||
// Set "true" to ignore checksum errors
|
// Set "true" to ignore checksum errors
|
||||||
IgnoreChecksums bool ` json:"IgnoreChecksums"`
|
IgnoreChecksums bool ` json:"IgnoreChecksums"`
|
||||||
|
|||||||
+9
-59
@@ -124,7 +124,7 @@ func apiPublishList(c *gin.Context) {
|
|||||||
// @Description See also: `aptly publish show`
|
// @Description See also: `aptly publish show`
|
||||||
// @Tags Publish
|
// @Tags Publish
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param prefix path string true "publishing prefix, use `:.` instead of `.` because it is ambigious in URLs"
|
// @Param prefix path string true "publishing prefix, use `:.` instead of `.` because it is ambiguous in URLs"
|
||||||
// @Param distribution path string true "distribution name"
|
// @Param distribution path string true "distribution name"
|
||||||
// @Success 200 {object} deb.PublishedRepo
|
// @Success 200 {object} deb.PublishedRepo
|
||||||
// @Failure 404 {object} Error "Published repository not found"
|
// @Failure 404 {object} Error "Published repository not found"
|
||||||
@@ -255,13 +255,13 @@ func apiPublishRepoOrSnapshot(c *gin.Context) {
|
|||||||
if b.SourceKind == deb.SourceSnapshot {
|
if b.SourceKind == deb.SourceSnapshot {
|
||||||
var snapshot *deb.Snapshot
|
var snapshot *deb.Snapshot
|
||||||
|
|
||||||
tmpCollection := collectionFactory.SnapshotCollection()
|
snapshotCollection := collectionFactory.SnapshotCollection()
|
||||||
|
|
||||||
for _, source := range b.Sources {
|
for _, source := range b.Sources {
|
||||||
components = append(components, source.Component)
|
components = append(components, source.Component)
|
||||||
names = append(names, source.Name)
|
names = append(names, source.Name)
|
||||||
|
|
||||||
snapshot, err = tmpCollection.ByName(source.Name)
|
snapshot, err = snapshotCollection.ByName(source.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
AbortWithJSONError(c, http.StatusNotFound, fmt.Errorf("unable to publish: %s", err))
|
AbortWithJSONError(c, http.StatusNotFound, fmt.Errorf("unable to publish: %s", err))
|
||||||
return
|
return
|
||||||
@@ -273,13 +273,13 @@ func apiPublishRepoOrSnapshot(c *gin.Context) {
|
|||||||
} else if b.SourceKind == deb.SourceLocalRepo {
|
} else if b.SourceKind == deb.SourceLocalRepo {
|
||||||
var localRepo *deb.LocalRepo
|
var localRepo *deb.LocalRepo
|
||||||
|
|
||||||
tmpCollection := collectionFactory.LocalRepoCollection()
|
localCollection := collectionFactory.LocalRepoCollection()
|
||||||
|
|
||||||
for _, source := range b.Sources {
|
for _, source := range b.Sources {
|
||||||
components = append(components, source.Component)
|
components = append(components, source.Component)
|
||||||
names = append(names, source.Name)
|
names = append(names, source.Name)
|
||||||
|
|
||||||
localRepo, err = tmpCollection.ByName(source.Name)
|
localRepo, err = localCollection.ByName(source.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
AbortWithJSONError(c, http.StatusNotFound, fmt.Errorf("unable to publish: %s", err))
|
AbortWithJSONError(c, http.StatusNotFound, fmt.Errorf("unable to publish: %s", err))
|
||||||
return
|
return
|
||||||
@@ -332,6 +332,8 @@ func apiPublishRepoOrSnapshot(c *gin.Context) {
|
|||||||
return &task.ProcessReturnValue{Code: http.StatusInternalServerError, Value: nil}, fmt.Errorf("unable to publish: %s", err)
|
return &task.ProcessReturnValue{Code: http.StatusInternalServerError, Value: nil}, fmt.Errorf("unable to publish: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resources = append(resources, string(published.Key()))
|
||||||
|
|
||||||
if b.Origin != "" {
|
if b.Origin != "" {
|
||||||
published.Origin = b.Origin
|
published.Origin = b.Origin
|
||||||
}
|
}
|
||||||
@@ -385,46 +387,6 @@ func apiPublishRepoOrSnapshot(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return resources to be locked for a Snapshot name
|
|
||||||
func getSnapshotResources(snapshotCollection *deb.SnapshotCollection, snapshotName string) (resources []string, err error) {
|
|
||||||
snapshot, err := snapshotCollection.ByName(snapshotName)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resources = append(resources, string(snapshot.ResourceKey()))
|
|
||||||
|
|
||||||
for _, sourceID := range snapshot.SourceIDs {
|
|
||||||
if snapshot.SourceKind == deb.SourceSnapshot {
|
|
||||||
snapshot2, err2 := snapshotCollection.ByUUID(sourceID)
|
|
||||||
if err2 != nil {
|
|
||||||
err = err2
|
|
||||||
return
|
|
||||||
}
|
|
||||||
res, err3 := getSnapshotResources(snapshotCollection, snapshot2.Name)
|
|
||||||
if err3 != nil {
|
|
||||||
err = err3
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resources = append(resources, res...)
|
|
||||||
} else if snapshot.SourceKind == deb.SourceLocalRepo {
|
|
||||||
var repo *deb.LocalRepo
|
|
||||||
repo, err = context.NewCollectionFactory().LocalRepoCollection().ByUUID(sourceID)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resources = append(resources, string(repo.Key()))
|
|
||||||
} else if snapshot.SourceKind == deb.SourceRemoteRepo {
|
|
||||||
var mirror *deb.RemoteRepo
|
|
||||||
mirror, err = context.NewCollectionFactory().RemoteRepoCollection().ByUUID(sourceID)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resources = append(resources, string(mirror.Key()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type publishedRepoUpdateSwitchParams struct {
|
type publishedRepoUpdateSwitchParams struct {
|
||||||
// when publishing, overwrite files in pool/ directory without notice
|
// when publishing, overwrite files in pool/ directory without notice
|
||||||
ForceOverwrite bool ` json:"ForceOverwrite" example:"false"`
|
ForceOverwrite bool ` json:"ForceOverwrite" example:"false"`
|
||||||
@@ -503,31 +465,18 @@ func apiPublishUpdateSwitch(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resources := []string{string(published.Key())}
|
|
||||||
|
|
||||||
if published.SourceKind == deb.SourceLocalRepo {
|
if published.SourceKind == deb.SourceLocalRepo {
|
||||||
if len(b.Snapshots) > 0 {
|
if len(b.Snapshots) > 0 {
|
||||||
AbortWithJSONError(c, http.StatusBadRequest, fmt.Errorf("snapshots shouldn't be given when updating local repo"))
|
AbortWithJSONError(c, http.StatusBadRequest, fmt.Errorf("snapshots shouldn't be given when updating local repo"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
localCollection := collectionFactory.LocalRepoCollection()
|
|
||||||
for _, sourceID := range published.Sources {
|
|
||||||
localRepo, err2 := localCollection.ByUUID(sourceID)
|
|
||||||
if err2 != nil {
|
|
||||||
AbortWithJSONError(c, http.StatusNotFound, err2)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resources = append(resources, string(localRepo.Key()))
|
|
||||||
}
|
|
||||||
} else if published.SourceKind == deb.SourceSnapshot {
|
} else if published.SourceKind == deb.SourceSnapshot {
|
||||||
for _, snapshotInfo := range b.Snapshots {
|
for _, snapshotInfo := range b.Snapshots {
|
||||||
res, err2 := getSnapshotResources(snapshotCollection, snapshotInfo.Name)
|
_, err2 := snapshotCollection.ByName(snapshotInfo.Name)
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
AbortWithJSONError(c, http.StatusNotFound, err2)
|
AbortWithJSONError(c, http.StatusNotFound, err2)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resources = append(resources, res...)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AbortWithJSONError(c, http.StatusInternalServerError, fmt.Errorf("unknown published repository type"))
|
AbortWithJSONError(c, http.StatusInternalServerError, fmt.Errorf("unknown published repository type"))
|
||||||
@@ -566,6 +515,7 @@ func apiPublishUpdateSwitch(c *gin.Context) {
|
|||||||
published.Version = *b.Version
|
published.Version = *b.Version
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resources := []string{string(published.Key())}
|
||||||
taskName := fmt.Sprintf("Update published %s repository %s/%s", published.SourceKind, published.StoragePrefix(), published.Distribution)
|
taskName := fmt.Sprintf("Update published %s repository %s/%s", published.SourceKind, published.StoragePrefix(), published.Distribution)
|
||||||
maybeRunTaskInBackground(c, taskName, resources, func(out aptly.Progress, _ *task.Detail) (*task.ProcessReturnValue, error) {
|
maybeRunTaskInBackground(c, taskName, resources, func(out aptly.Progress, _ *task.Detail) (*task.ProcessReturnValue, error) {
|
||||||
err = collection.LoadComplete(published, collectionFactory)
|
err = collection.LoadComplete(published, collectionFactory)
|
||||||
|
|||||||
+2
-2
@@ -102,7 +102,7 @@ type repoCreateParams struct {
|
|||||||
DefaultDistribution string ` json:"DefaultDistribution" example:"stable"`
|
DefaultDistribution string ` json:"DefaultDistribution" example:"stable"`
|
||||||
// Default component when publishing from this local repo
|
// Default component when publishing from this local repo
|
||||||
DefaultComponent string ` json:"DefaultComponent" example:"main"`
|
DefaultComponent string ` json:"DefaultComponent" example:"main"`
|
||||||
// Snapshot name to create repoitory from (optional)
|
// Snapshot name to create repository from (optional)
|
||||||
FromSnapshot string ` json:"FromSnapshot" example:""`
|
FromSnapshot string ` json:"FromSnapshot" example:""`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +180,7 @@ type reposEditParams struct {
|
|||||||
Comment *string ` json:"Comment" example:"example repo"`
|
Comment *string ` json:"Comment" example:"example repo"`
|
||||||
// Change Default Distribution for publishing
|
// Change Default Distribution for publishing
|
||||||
DefaultDistribution *string ` json:"DefaultDistribution" example:""`
|
DefaultDistribution *string ` json:"DefaultDistribution" example:""`
|
||||||
// Change Devault Component for publishing
|
// Change Default Component for publishing
|
||||||
DefaultComponent *string ` json:"DefaultComponent" example:""`
|
DefaultComponent *string ` json:"DefaultComponent" example:""`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -168,6 +168,8 @@ func (collection *LocalRepoCollection) Update(repo *LocalRepo) error {
|
|||||||
|
|
||||||
// LoadComplete loads additional information for local repo
|
// LoadComplete loads additional information for local repo
|
||||||
func (collection *LocalRepoCollection) LoadComplete(repo *LocalRepo) error {
|
func (collection *LocalRepoCollection) LoadComplete(repo *LocalRepo) error {
|
||||||
|
repo.packageRefs = &PackageRefList{}
|
||||||
|
|
||||||
encoded, err := collection.db.Get(repo.RefKey())
|
encoded, err := collection.db.Get(repo.RefKey())
|
||||||
if err == database.ErrNotFound {
|
if err == database.ErrNotFound {
|
||||||
return nil
|
return nil
|
||||||
@@ -176,7 +178,6 @@ func (collection *LocalRepoCollection) LoadComplete(repo *LocalRepo) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
repo.packageRefs = &PackageRefList{}
|
|
||||||
return repo.packageRefs.Decode(encoded)
|
return repo.packageRefs.Decode(encoded)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -133,6 +133,18 @@ func (s *LocalRepoCollectionSuite) TestByUUID(c *C) {
|
|||||||
c.Assert(r.String(), Equals, repo.String())
|
c.Assert(r.String(), Equals, repo.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *LocalRepoCollectionSuite) TestLoadCompleteNoRefKey(c *C) {
|
||||||
|
repo := NewLocalRepo("local1", "Comment 1")
|
||||||
|
c.Assert(s.collection.Update(repo), IsNil)
|
||||||
|
|
||||||
|
r, err := s.collection.ByName("local1")
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
|
c.Assert(s.collection.LoadComplete(r), IsNil)
|
||||||
|
c.Assert(r.packageRefs, NotNil)
|
||||||
|
c.Assert(r.NumPackages(), Equals, 0)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *LocalRepoCollectionSuite) TestUpdateLoadComplete(c *C) {
|
func (s *LocalRepoCollectionSuite) TestUpdateLoadComplete(c *C) {
|
||||||
repo := NewLocalRepo("local1", "Comment 1")
|
repo := NewLocalRepo("local1", "Comment 1")
|
||||||
c.Assert(s.collection.Update(repo), IsNil)
|
c.Assert(s.collection.Update(repo), IsNil)
|
||||||
|
|||||||
@@ -609,12 +609,7 @@ func (p *PublishedRepo) StoragePrefix() string {
|
|||||||
|
|
||||||
// Key returns unique key identifying PublishedRepo
|
// Key returns unique key identifying PublishedRepo
|
||||||
func (p *PublishedRepo) Key() []byte {
|
func (p *PublishedRepo) Key() []byte {
|
||||||
if p.MultiDist {
|
|
||||||
// do not lock Distribution in MultiDist
|
|
||||||
return []byte("UM" + p.StoragePrefix())
|
|
||||||
} else {
|
|
||||||
return []byte("U" + p.StoragePrefix() + ">>" + p.Distribution)
|
return []byte("U" + p.StoragePrefix() + ">>" + p.Distribution)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefKey is a unique id for package reference list
|
// RefKey is a unique id for package reference list
|
||||||
|
|||||||
@@ -79,6 +79,9 @@ func (l *PackageRefList) Decode(input []byte) error {
|
|||||||
|
|
||||||
// ForEach calls handler for each package ref in list
|
// ForEach calls handler for each package ref in list
|
||||||
func (l *PackageRefList) ForEach(handler func([]byte) error) error {
|
func (l *PackageRefList) ForEach(handler func([]byte) error) error {
|
||||||
|
if l == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
var err error
|
var err error
|
||||||
for _, p := range l.Refs {
|
for _, p := range l.Refs {
|
||||||
err = handler(p)
|
err = handler(p)
|
||||||
|
|||||||
@@ -130,6 +130,17 @@ func (s *PackageRefListSuite) TestPackageRefListForeach(c *C) {
|
|||||||
c.Check(err, Equals, e)
|
c.Check(err, Equals, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *PackageRefListSuite) TestForEachNilList(c *C) {
|
||||||
|
var l *PackageRefList
|
||||||
|
called := false
|
||||||
|
err := l.ForEach(func([]byte) error {
|
||||||
|
called = true
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
c.Assert(called, Equals, false)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *PackageRefListSuite) TestHas(c *C) {
|
func (s *PackageRefListSuite) TestHas(c *C) {
|
||||||
_ = s.list.Add(s.p1)
|
_ = s.list.Add(s.p1)
|
||||||
_ = s.list.Add(s.p3)
|
_ = s.list.Add(s.p3)
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
<div>
|
<div>
|
||||||
|
|
||||||
In order to add debian package files to a local repository, files are first uploaded to a temporary directory.
|
In order to add debian package files to a local repository, files are first uploaded to a temporary directory.
|
||||||
Then the directory (or a specific file within) is added to a repository. After adding to a repositorty, the directory resp. files are removed bt default.
|
Then the directory (or a specific file within) is added to a repository. After adding to a repository, the directory resp. files are removed bt default.
|
||||||
|
|
||||||
All uploaded files are stored under `<rootDir>/upload/<tempdir>` directory.
|
All uploaded files are stored under `<rootDir>/upload/<tempdir>` directory.
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
# Search Package Collection
|
# Search Package Collection
|
||||||
<div>
|
<div>
|
||||||
Perform operations on the whole collection of packages in apty database.
|
Perform operations on the whole collection of packages in aptly database.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -35,6 +35,6 @@ aptly publish repo my-repo --gpg-key=KEY_ID_a --gpg-key=KEY_ID_b
|
|||||||
#### Parameters
|
#### Parameters
|
||||||
|
|
||||||
Publish APIs use following convention to identify published repositories: `/api/publish/:prefix/:distribution`. `:distribution` is distribution name, while `:prefix` is `[<storage>:]<prefix>` (storage is optional, it defaults to empty string), if publishing prefix contains slashes `/`, they should be replaced with underscores (`_`) and underscores
|
Publish APIs use following convention to identify published repositories: `/api/publish/:prefix/:distribution`. `:distribution` is distribution name, while `:prefix` is `[<storage>:]<prefix>` (storage is optional, it defaults to empty string), if publishing prefix contains slashes `/`, they should be replaced with underscores (`_`) and underscores
|
||||||
should be replaced with double underscore (`__`). To specify root `:prefix`, use `:.`, as `.` is ambigious in URLs.
|
should be replaced with double underscore (`__`). To specify root `:prefix`, use `:.`, as `.` is ambiguous in URLs.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
# Manage Local Repositories
|
# Manage Local Repositories
|
||||||
<div>
|
<div>
|
||||||
A local repository is a collection of versionned packages (usually custom packages created internally).
|
A local repository is a collection of versioned packages (usually custom packages created internally).
|
||||||
|
|
||||||
Packages can be added, removed, moved or copied between repos.
|
Packages can be added, removed, moved or copied between repos.
|
||||||
|
|
||||||
|
|||||||
@@ -992,232 +992,6 @@ class PublishSwitchAPITestRepo(APITest):
|
|||||||
self.check_not_exists("public/" + prefix + "dists/")
|
self.check_not_exists("public/" + prefix + "dists/")
|
||||||
|
|
||||||
|
|
||||||
class PublishSwitchAPITestMirror(APITest):
|
|
||||||
"""
|
|
||||||
PUT /publish/:prefix/:distribution (snapshots), DELETE /publish/:prefix/:distribution
|
|
||||||
"""
|
|
||||||
fixtureGpg = True
|
|
||||||
|
|
||||||
def check(self):
|
|
||||||
mirror_name = self.random_name()
|
|
||||||
mirror_desc = {'Name': mirror_name,
|
|
||||||
'ArchiveURL': 'http://repo.aptly.info/system-tests/packagecloud.io/varnishcache/varnish30/debian/',
|
|
||||||
'Distribution': 'wheezy',
|
|
||||||
'Keyrings': ["aptlytest.gpg"],
|
|
||||||
'Architectures': ["amd64"],
|
|
||||||
'Components': ['main']}
|
|
||||||
mirror_desc['IgnoreSignatures'] = True
|
|
||||||
|
|
||||||
# Create Mirror
|
|
||||||
resp = self.post("/api/mirrors", json=mirror_desc)
|
|
||||||
self.check_equal(resp.status_code, 201)
|
|
||||||
|
|
||||||
# Get Mirror
|
|
||||||
resp = self.get("/api/mirrors/" + mirror_name + "/packages")
|
|
||||||
self.check_equal(resp.status_code, 404)
|
|
||||||
|
|
||||||
# Update Mirror
|
|
||||||
resp = self.put_task("/api/mirrors/" + mirror_name, json=mirror_desc)
|
|
||||||
self.check_task(resp)
|
|
||||||
|
|
||||||
# Snapshot Mirror
|
|
||||||
snapshot1_name = self.random_name()
|
|
||||||
task = self.post_task("/api/mirrors/" + mirror_name + '/snapshots', json={'Name': snapshot1_name})
|
|
||||||
self.check_task(task)
|
|
||||||
|
|
||||||
# Publish Snapshot
|
|
||||||
prefix = self.random_name()
|
|
||||||
task = self.post_task(
|
|
||||||
"/api/publish/" + prefix,
|
|
||||||
json={
|
|
||||||
"Architectures": ["i386", "source"],
|
|
||||||
"SourceKind": "snapshot",
|
|
||||||
"Sources": [{"Name": snapshot1_name}],
|
|
||||||
"Signing": DefaultSigningOptions,
|
|
||||||
})
|
|
||||||
self.check_task(task)
|
|
||||||
|
|
||||||
repo_expected = {
|
|
||||||
'AcquireByHash': False,
|
|
||||||
'Architectures': ['i386', 'source'],
|
|
||||||
'Codename': '',
|
|
||||||
'Distribution': 'wheezy',
|
|
||||||
'Label': '',
|
|
||||||
'NotAutomatic': '',
|
|
||||||
'ButAutomaticUpgrades': '',
|
|
||||||
'Origin': 'packagecloud.io/varnishcache/varnish30',
|
|
||||||
'Version': '',
|
|
||||||
'Path': prefix + '/' + 'wheezy',
|
|
||||||
'Prefix': prefix,
|
|
||||||
'SignedBy': '',
|
|
||||||
'SkipContents': False,
|
|
||||||
'MultiDist': False,
|
|
||||||
'SourceKind': 'snapshot',
|
|
||||||
'Sources': [{'Component': 'main', 'Name': snapshot1_name}],
|
|
||||||
'Storage': '',
|
|
||||||
'Suite': ''}
|
|
||||||
all_repos = self.get("/api/publish")
|
|
||||||
self.check_equal(all_repos.status_code, 200)
|
|
||||||
self.check_in(repo_expected, all_repos.json())
|
|
||||||
|
|
||||||
# Snapshot Mirror 2
|
|
||||||
snapshot2_name = self.random_name()
|
|
||||||
task = self.post_task("/api/mirrors/" + mirror_name + '/snapshots', json={'Name': snapshot2_name})
|
|
||||||
self.check_task(task)
|
|
||||||
|
|
||||||
task = self.put_task(
|
|
||||||
"/api/publish/" + prefix + "/wheezy",
|
|
||||||
json={
|
|
||||||
"Snapshots": [{"Component": "main", "Name": snapshot2_name}],
|
|
||||||
"Signing": DefaultSigningOptions,
|
|
||||||
"SkipContents": True,
|
|
||||||
"Label": "fun",
|
|
||||||
"Origin": "earth",
|
|
||||||
"Version": "13.3",
|
|
||||||
})
|
|
||||||
self.check_task(task)
|
|
||||||
repo_expected = {
|
|
||||||
'AcquireByHash': False,
|
|
||||||
'Architectures': ['i386', 'source'],
|
|
||||||
'Codename': '',
|
|
||||||
'Distribution': 'wheezy',
|
|
||||||
'Label': 'fun',
|
|
||||||
'Origin': 'earth',
|
|
||||||
'Version': '13.3',
|
|
||||||
'NotAutomatic': '',
|
|
||||||
'ButAutomaticUpgrades': '',
|
|
||||||
'Path': prefix + '/' + 'wheezy',
|
|
||||||
'Prefix': prefix,
|
|
||||||
'SignedBy': '',
|
|
||||||
'SkipContents': True,
|
|
||||||
'MultiDist': False,
|
|
||||||
'SourceKind': 'snapshot',
|
|
||||||
'Sources': [{'Component': 'main', 'Name': snapshot2_name}],
|
|
||||||
'Storage': '',
|
|
||||||
'Suite': ''}
|
|
||||||
|
|
||||||
all_repos = self.get("/api/publish")
|
|
||||||
self.check_equal(all_repos.status_code, 200)
|
|
||||||
self.check_in(repo_expected, all_repos.json())
|
|
||||||
|
|
||||||
task = self.delete_task("/api/publish/" + prefix + "/wheezy")
|
|
||||||
self.check_task(task)
|
|
||||||
self.check_not_exists("public/" + prefix + "dists/")
|
|
||||||
|
|
||||||
|
|
||||||
class PublishSwitchAPITestSnapshot(APITest):
|
|
||||||
"""
|
|
||||||
publish snapshot of snapshot
|
|
||||||
"""
|
|
||||||
fixtureGpg = True
|
|
||||||
|
|
||||||
def check(self):
|
|
||||||
repo_name = self.random_name()
|
|
||||||
self.check_equal(self.post(
|
|
||||||
"/api/repos", json={"Name": repo_name, "DefaultDistribution": "wheezy"}).status_code, 201)
|
|
||||||
|
|
||||||
d = self.random_name()
|
|
||||||
self.check_equal(
|
|
||||||
self.upload("/api/files/" + d,
|
|
||||||
"pyspi_0.6.1-1.3.dsc",
|
|
||||||
"pyspi_0.6.1-1.3.diff.gz", "pyspi_0.6.1.orig.tar.gz",
|
|
||||||
"pyspi-0.6.1-1.3.stripped.dsc").status_code, 200)
|
|
||||||
task = self.post_task("/api/repos/" + repo_name + "/file/" + d)
|
|
||||||
self.check_task(task)
|
|
||||||
|
|
||||||
snapshot1_name = self.random_name()
|
|
||||||
task = self.post_task("/api/repos/" + repo_name + '/snapshots', json={'Name': snapshot1_name})
|
|
||||||
self.check_task(task)
|
|
||||||
|
|
||||||
prefix = self.random_name()
|
|
||||||
task = self.post_task(
|
|
||||||
"/api/publish/" + prefix,
|
|
||||||
json={
|
|
||||||
"Architectures": ["i386", "source"],
|
|
||||||
"SourceKind": "snapshot",
|
|
||||||
"Sources": [{"Name": snapshot1_name}],
|
|
||||||
"Signing": DefaultSigningOptions,
|
|
||||||
})
|
|
||||||
self.check_task(task)
|
|
||||||
|
|
||||||
repo_expected = {
|
|
||||||
'AcquireByHash': False,
|
|
||||||
'Architectures': ['i386', 'source'],
|
|
||||||
'Codename': '',
|
|
||||||
'Distribution': 'wheezy',
|
|
||||||
'Label': '',
|
|
||||||
'NotAutomatic': '',
|
|
||||||
'ButAutomaticUpgrades': '',
|
|
||||||
'Origin': '',
|
|
||||||
'Version': '',
|
|
||||||
'Path': prefix + '/' + 'wheezy',
|
|
||||||
'Prefix': prefix,
|
|
||||||
'SignedBy': '',
|
|
||||||
'SkipContents': False,
|
|
||||||
'MultiDist': False,
|
|
||||||
'SourceKind': 'snapshot',
|
|
||||||
'Sources': [{'Component': 'main', 'Name': snapshot1_name}],
|
|
||||||
'Storage': '',
|
|
||||||
'Suite': ''}
|
|
||||||
all_repos = self.get("/api/publish")
|
|
||||||
self.check_equal(all_repos.status_code, 200)
|
|
||||||
self.check_in(repo_expected, all_repos.json())
|
|
||||||
|
|
||||||
self.check_not_exists(
|
|
||||||
"public/" + prefix + "/pool/main/b/boost-defaults/libboost-program-options-dev_1.49.0.1_i386.deb")
|
|
||||||
self.check_exists("public/" + prefix +
|
|
||||||
"/pool/main/p/pyspi/pyspi-0.6.1-1.3.stripped.dsc")
|
|
||||||
|
|
||||||
snapshot2_name = self.random_name()
|
|
||||||
task = self.post_task("/api/snapshots", json={"Name": snapshot2_name, 'SourceSnapshots': [snapshot1_name]})
|
|
||||||
self.check_task(task)
|
|
||||||
|
|
||||||
task = self.put_task(
|
|
||||||
"/api/publish/" + prefix + "/wheezy",
|
|
||||||
json={
|
|
||||||
"Snapshots": [{"Component": "main", "Name": snapshot2_name}],
|
|
||||||
"Signing": DefaultSigningOptions,
|
|
||||||
"SkipContents": True,
|
|
||||||
"Label": "fun",
|
|
||||||
"Origin": "earth",
|
|
||||||
"Version": "13.3",
|
|
||||||
})
|
|
||||||
self.check_task(task)
|
|
||||||
repo_expected = {
|
|
||||||
'AcquireByHash': False,
|
|
||||||
'Architectures': ['i386', 'source'],
|
|
||||||
'Codename': '',
|
|
||||||
'Distribution': 'wheezy',
|
|
||||||
'Label': 'fun',
|
|
||||||
'Origin': 'earth',
|
|
||||||
'Version': '13.3',
|
|
||||||
'NotAutomatic': '',
|
|
||||||
'ButAutomaticUpgrades': '',
|
|
||||||
'Path': prefix + '/' + 'wheezy',
|
|
||||||
'Prefix': prefix,
|
|
||||||
'SignedBy': '',
|
|
||||||
'SkipContents': True,
|
|
||||||
'MultiDist': False,
|
|
||||||
'SourceKind': 'snapshot',
|
|
||||||
'Sources': [{'Component': 'main', 'Name': snapshot2_name}],
|
|
||||||
'Storage': '',
|
|
||||||
'Suite': ''}
|
|
||||||
|
|
||||||
all_repos = self.get("/api/publish")
|
|
||||||
self.check_equal(all_repos.status_code, 200)
|
|
||||||
self.check_in(repo_expected, all_repos.json())
|
|
||||||
|
|
||||||
# FIXME: what should exist here ? publish snapshot of snapshot
|
|
||||||
self.check_not_exists(
|
|
||||||
"public/" + prefix + "/pool/main/b/boost-defaults/libboost-program-options-dev_1.49.0.1_i386.deb")
|
|
||||||
self.check_not_exists("public/" + prefix +
|
|
||||||
"/pool/main/p/pyspi/pyspi-0.6.1-1.3.stripped.dsc")
|
|
||||||
|
|
||||||
task = self.delete_task("/api/publish/" + prefix + "/wheezy")
|
|
||||||
self.check_task(task)
|
|
||||||
self.check_not_exists("public/" + prefix + "dists/")
|
|
||||||
|
|
||||||
|
|
||||||
class PublishSwitchAPITestRepoSignedBy(APITest):
|
class PublishSwitchAPITestRepoSignedBy(APITest):
|
||||||
"""
|
"""
|
||||||
PUT /publish/:prefix/:distribution (snapshots), DELETE /publish/:prefix/:distribution
|
PUT /publish/:prefix/:distribution (snapshots), DELETE /publish/:prefix/:distribution
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ func (list *List) consumer() {
|
|||||||
task.State = SUCCEEDED
|
task.State = SUCCEEDED
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("RACE DEBUG: Task Done '%s', freeing %s\n", task.Name, task.resources)
|
|
||||||
list.usedResources.Free(task.resources)
|
list.usedResources.Free(task.resources)
|
||||||
|
|
||||||
task.wgTask.Done()
|
task.wgTask.Done()
|
||||||
@@ -78,8 +77,6 @@ func (list *List) consumer() {
|
|||||||
blockingTasks := list.usedResources.UsedBy(t.resources)
|
blockingTasks := list.usedResources.UsedBy(t.resources)
|
||||||
if len(blockingTasks) == 0 {
|
if len(blockingTasks) == 0 {
|
||||||
list.usedResources.MarkInUse(t.resources, t)
|
list.usedResources.MarkInUse(t.resources, t)
|
||||||
|
|
||||||
fmt.Printf("RACE DEBUG: Task Resuming '%s', locking %s\n", t.Name, t.resources)
|
|
||||||
// unlock list since queueing may block
|
// unlock list since queueing may block
|
||||||
list.Unlock()
|
list.Unlock()
|
||||||
unlocked = true
|
unlocked = true
|
||||||
@@ -212,12 +209,10 @@ func (list *List) RunTaskInBackground(name string, resources []string, process P
|
|||||||
tasks := list.usedResources.UsedBy(resources)
|
tasks := list.usedResources.UsedBy(resources)
|
||||||
if len(tasks) == 0 {
|
if len(tasks) == 0 {
|
||||||
list.usedResources.MarkInUse(task.resources, task)
|
list.usedResources.MarkInUse(task.resources, task)
|
||||||
fmt.Printf("RACE DEBUG: Task Starting '%s', locking %s\n", name, resources)
|
|
||||||
// queueing task might block if channel not ready, unlock list before queueing
|
// queueing task might block if channel not ready, unlock list before queueing
|
||||||
list.Unlock()
|
list.Unlock()
|
||||||
list.queue <- task
|
list.queue <- task
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("RACE DEBUG: Task Queued '%s', waiting on %s\n", name, resources)
|
|
||||||
list.Unlock()
|
list.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user