mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-06-12 06:30:35 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2a99fdfcf1 | |||
| ab7e5710ee | |||
| 0c02707638 | |||
| 468a008a49 | |||
| 80e4e9bdac | |||
| 2974558aa7 | |||
| 00773f9840 |
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
name: CI
|
name: CI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
@@ -10,7 +11,6 @@ on:
|
|||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
# see: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#using-a-specific-shell
|
|
||||||
shell: bash --noprofile --norc -eo pipefail {0}
|
shell: bash --noprofile --norc -eo pipefail {0}
|
||||||
|
|
||||||
env:
|
env:
|
||||||
@@ -33,7 +33,7 @@ jobs:
|
|||||||
make docker-image
|
make docker-image
|
||||||
- name: "Unit Tests"
|
- name: "Unit Tests"
|
||||||
run: |
|
run: |
|
||||||
make docker-unit-tests
|
make docker-unit-test
|
||||||
mkdir -p out/coverage
|
mkdir -p out/coverage
|
||||||
mv unit.out out/coverage/
|
mv unit.out out/coverage/
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
@@ -140,7 +140,7 @@ jobs:
|
|||||||
|
|
||||||
- name: "Upload Code Coverage"
|
- name: "Upload Code Coverage"
|
||||||
if: github.actor != 'dependabot[bot]'
|
if: github.actor != 'dependabot[bot]'
|
||||||
uses: codecov/codecov-action@v5
|
uses: codecov/codecov-action@v7.0.0
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
files: coverage.txt
|
files: coverage.txt
|
||||||
|
|||||||
+1
-1
@@ -130,7 +130,7 @@ aptly version: 1.5.0+189+g0fc90dff
|
|||||||
|
|
||||||
In order to run aptly unit tests, enter the following:
|
In order to run aptly unit tests, enter the following:
|
||||||
```
|
```
|
||||||
make docker-unit-tests
|
make docker-unit-test
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Running system tests
|
#### Running system tests
|
||||||
|
|||||||
@@ -182,9 +182,6 @@ binaries: prepare swagger ## Build binary releases (FreeBSD, macOS, Linux gener
|
|||||||
docker-image: ## Build aptly-dev docker image
|
docker-image: ## Build aptly-dev docker image
|
||||||
@docker build -f system/Dockerfile . -t aptly-dev
|
@docker build -f system/Dockerfile . -t aptly-dev
|
||||||
|
|
||||||
docker-image-test: # Build aptly-test docker image for testing
|
|
||||||
@docker build -f docker/test.Dockerfile . -t aptly-test
|
|
||||||
|
|
||||||
docker-image-no-cache: ## Build aptly-dev docker image (no cache)
|
docker-image-no-cache: ## Build aptly-dev docker image (no cache)
|
||||||
@docker build --no-cache -f system/Dockerfile . -t aptly-dev
|
@docker build --no-cache -f system/Dockerfile . -t aptly-dev
|
||||||
|
|
||||||
@@ -197,7 +194,7 @@ docker-shell: ## Run aptly and other commands in docker container
|
|||||||
docker-deb: ## Build debian packages in docker container
|
docker-deb: ## Build debian packages in docker container
|
||||||
@$(DOCKER_RUN) -t aptly-dev /work/src/system/docker-wrapper dpkg DEBARCH=amd64
|
@$(DOCKER_RUN) -t aptly-dev /work/src/system/docker-wrapper dpkg DEBARCH=amd64
|
||||||
|
|
||||||
docker-unit-tests: ## Run unit tests in docker container (add TEST=regex to specify which tests to run)
|
docker-unit-test: ## Run unit tests in docker container (add TEST=regex to specify which tests to run)
|
||||||
$(DOCKER_RUN) -t --tmpfs /smallfs:rw,size=1m aptly-dev /work/src/system/docker-wrapper \
|
$(DOCKER_RUN) -t --tmpfs /smallfs:rw,size=1m aptly-dev /work/src/system/docker-wrapper \
|
||||||
azurite-start \
|
azurite-start \
|
||||||
AZURE_STORAGE_ENDPOINT=http://127.0.0.1:10000/devstoreaccount1 \
|
AZURE_STORAGE_ENDPOINT=http://127.0.0.1:10000/devstoreaccount1 \
|
||||||
|
|||||||
+8
-16
@@ -2,7 +2,6 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -268,7 +267,7 @@ func apiPublishRepoOrSnapshot(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resources = append(resources, string(snapshot.ResourceKey()))
|
resources = append(resources, string(snapshot.Key()))
|
||||||
sources = append(sources, snapshot)
|
sources = append(sources, snapshot)
|
||||||
}
|
}
|
||||||
} else if b.SourceKind == deb.SourceLocalRepo {
|
} else if b.SourceKind == deb.SourceLocalRepo {
|
||||||
@@ -299,23 +298,16 @@ func apiPublishRepoOrSnapshot(c *gin.Context) {
|
|||||||
multiDist = *b.MultiDist
|
multiDist = *b.MultiDist
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pre-register the published repo key in resources so that concurrent
|
|
||||||
// POST requests for the same prefix/distribution are serialized by the
|
|
||||||
// task queue rather than racing on CheckDuplicate + Add.
|
|
||||||
if b.Distribution != "" {
|
|
||||||
storagePrefix := prefix
|
|
||||||
if storage != "" {
|
|
||||||
storagePrefix = storage + ":" + prefix
|
|
||||||
}
|
|
||||||
resources = append(resources, "U"+storagePrefix+">>"+b.Distribution)
|
|
||||||
// Non-MultiDist publishes share a single pool/ directory under the
|
// Non-MultiDist publishes share a single pool/ directory under the
|
||||||
// prefix. Lock at the prefix level so that concurrent publish/drop
|
// prefix. Lock at the prefix level so that concurrent publish/drop
|
||||||
// operations on sibling distributions cannot race during cleanup.
|
// operations on sibling distributions cannot race during cleanup.
|
||||||
if !multiDist {
|
if !multiDist {
|
||||||
resources = append(resources, deb.PrefixPoolLockKey(storagePrefix))
|
storagePrefix := prefix
|
||||||
|
if storage != "" {
|
||||||
|
storagePrefix = storage + ":" + prefix
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
log.Printf("distribution not specified for publish to prefix '%s' - unable to lock ", prefix)
|
resources = append(resources, deb.PrefixPoolLockKey(storagePrefix))
|
||||||
}
|
}
|
||||||
|
|
||||||
taskName := fmt.Sprintf("Publish %s repository %s/%s with components \"%s\" and sources \"%s\"",
|
taskName := fmt.Sprintf("Publish %s repository %s/%s with components \"%s\" and sources \"%s\"",
|
||||||
@@ -507,7 +499,7 @@ func apiPublishUpdateSwitch(c *gin.Context) {
|
|||||||
AbortWithJSONError(c, http.StatusNotFound, err2)
|
AbortWithJSONError(c, http.StatusNotFound, err2)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resources = append(resources, string(snapshot.ResourceKey()))
|
resources = append(resources, string(snapshot.Key()))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AbortWithJSONError(c, http.StatusInternalServerError, fmt.Errorf("unknown published repository type"))
|
AbortWithJSONError(c, http.StatusInternalServerError, fmt.Errorf("unknown published repository type"))
|
||||||
@@ -1185,7 +1177,7 @@ func apiPublishUpdate(c *gin.Context) {
|
|||||||
AbortWithJSONError(c, http.StatusNotFound, err2)
|
AbortWithJSONError(c, http.StatusNotFound, err2)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resources = append(resources, string(snapshot.ResourceKey()))
|
resources = append(resources, string(snapshot.Key()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -429,48 +429,18 @@ func (s *PublishedFileMissingSuite) TestIdenticalPackageRace(c *C) {
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
//time.Sleep(5 * time.Millisecond)
|
s.httpRequest(c, "POST", fmt.Sprintf("/api/repos/%s/file/%s?noRemove=0", repos[0], uploadID1), nil)
|
||||||
c.Logf("[iter %d] Import A", iter)
|
|
||||||
resp := s.httpRequest(c, "POST", fmt.Sprintf("/api/repos/%s/file/%s?noRemove=0", repos[0], uploadID1), nil)
|
|
||||||
c.Logf("[iter %d] Import A complete: %d", iter, resp.Code)
|
|
||||||
|
|
||||||
updateBody, _ := json.Marshal(gin.H{"Signing": gin.H{"Skip": true}, "ForceOverwrite": true, "SkipBz2": true})
|
updateBody, _ := json.Marshal(gin.H{"Signing": gin.H{"Skip": true}, "ForceOverwrite": true, "SkipBz2": true})
|
||||||
c.Logf("[iter %d] Publish A", iter)
|
s.httpRequest(c, "PUT", fmt.Sprintf("/api/publish/identical/%s", dists[0]), updateBody)
|
||||||
resp = s.httpRequest(c, "PUT", fmt.Sprintf("/api/publish/identical/%s", dists[0]), updateBody)
|
|
||||||
c.Logf("[iter %d] Publish A complete: %d", iter, resp.Code)
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
//time.Sleep(7 * time.Millisecond)
|
s.httpRequest(c, "POST", fmt.Sprintf("/api/repos/%s/file/%s?noRemove=0", repos[1], uploadID2), nil)
|
||||||
c.Logf("[iter %d] Import B", iter)
|
|
||||||
resp := s.httpRequest(c, "POST", fmt.Sprintf("/api/repos/%s/file/%s?noRemove=0", repos[1], uploadID2), nil)
|
|
||||||
c.Logf("[iter %d] Import B complete: %d", iter, resp.Code)
|
|
||||||
|
|
||||||
updateBody, _ := json.Marshal(gin.H{"Signing": gin.H{"Skip": true}, "ForceOverwrite": true, "SkipBz2": true})
|
updateBody, _ := json.Marshal(gin.H{"Signing": gin.H{"Skip": true}, "ForceOverwrite": true, "SkipBz2": true})
|
||||||
c.Logf("[iter %d] Publish B", iter)
|
s.httpRequest(c, "PUT", fmt.Sprintf("/api/publish/identical/%s", dists[1]), updateBody)
|
||||||
resp = s.httpRequest(c, "PUT", fmt.Sprintf("/api/publish/identical/%s", dists[1]), updateBody)
|
|
||||||
c.Logf("[iter %d] Publish B complete: %d", iter, resp.Code)
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
//go func() {
|
|
||||||
//defer wg.Done()
|
|
||||||
//time.Sleep(15 * time.Millisecond)
|
|
||||||
//updateBody, _ := json.Marshal(gin.H{"Signing": gin.H{"Skip": true}, "ForceOverwrite": true, "SkipBz2": true})
|
|
||||||
//c.Logf("[iter %d] Publish A", iter)
|
|
||||||
//resp := s.httpRequest(c, "PUT", fmt.Sprintf("/api/publish/identical/%s", dists[0]), updateBody)
|
|
||||||
//c.Logf("[iter %d] Publish A complete: %d", iter, resp.Code)
|
|
||||||
//}()
|
|
||||||
|
|
||||||
//go func() {
|
|
||||||
//defer wg.Done()
|
|
||||||
//time.Sleep(18 * time.Millisecond)
|
|
||||||
//updateBody, _ := json.Marshal(gin.H{"Signing": gin.H{"Skip": true}, "ForceOverwrite": true, "SkipBz2": true})
|
|
||||||
//c.Logf("[iter %d] Publish B", iter)
|
|
||||||
//resp := s.httpRequest(c, "PUT", fmt.Sprintf("/api/publish/identical/%s", dists[1]), updateBody)
|
|
||||||
//c.Logf("[iter %d] Publish B complete: %d", iter, resp.Code)
|
|
||||||
//}()
|
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
time.Sleep(200 * time.Millisecond)
|
time.Sleep(200 * time.Millisecond)
|
||||||
c.Logf("[iter %d] All operations complete", iter)
|
c.Logf("[iter %d] All operations complete", iter)
|
||||||
|
|||||||
+10
-10
@@ -134,21 +134,14 @@ func apiReposCreate(c *gin.Context) {
|
|||||||
// Handler: Pre-task validations (shallow)
|
// Handler: Pre-task validations (shallow)
|
||||||
collectionFactory := context.NewCollectionFactory()
|
collectionFactory := context.NewCollectionFactory()
|
||||||
|
|
||||||
|
var resources []string
|
||||||
if b.FromSnapshot != "" {
|
if b.FromSnapshot != "" {
|
||||||
snapshotCollection := collectionFactory.SnapshotCollection()
|
snapshot, err := collectionFactory.SnapshotCollection().ByName(b.FromSnapshot)
|
||||||
|
|
||||||
_, err := snapshotCollection.ByName(b.FromSnapshot)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
AbortWithJSONError(c, http.StatusNotFound, fmt.Errorf("source snapshot not found: %s", err))
|
AbortWithJSONError(c, http.StatusNotFound, fmt.Errorf("source snapshot not found: %s", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Just verify it exists - don't load here
|
resources = append(resources, string(snapshot.Key()))
|
||||||
}
|
|
||||||
|
|
||||||
// Use generated key resource for repo being created
|
|
||||||
resources := []string{"LocalRepo:" + b.Name}
|
|
||||||
if b.FromSnapshot != "" {
|
|
||||||
resources = append(resources, "Snapshot:"+b.FromSnapshot)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
taskName := fmt.Sprintf("Create repository %s", b.Name)
|
taskName := fmt.Sprintf("Create repository %s", b.Name)
|
||||||
@@ -236,6 +229,13 @@ func apiReposEdit(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if b.Name != nil && *b.Name != name {
|
||||||
|
if _, err = collection.ByName(*b.Name); err == nil {
|
||||||
|
AbortWithJSONError(c, 409, fmt.Errorf("unable to rename: local repo %q already exists", *b.Name))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
resources := []string{string(repo.Key())}
|
resources := []string{string(repo.Key())}
|
||||||
taskName := fmt.Sprintf("Edit repository %s", name)
|
taskName := fmt.Sprintf("Edit repository %s", name)
|
||||||
|
|
||||||
|
|||||||
+23
-10
@@ -92,7 +92,7 @@ func apiSnapshotsCreateFromMirror(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// including snapshot resource key
|
// including snapshot resource key
|
||||||
resources := []string{string(repo.Key()), "S" + b.Name}
|
resources := []string{string(repo.Key())}
|
||||||
taskName := fmt.Sprintf("Create snapshot of mirror %s", name)
|
taskName := fmt.Sprintf("Create snapshot of mirror %s", name)
|
||||||
maybeRunTaskInBackground(c, taskName, resources, func(_ aptly.Progress, _ *task.Detail) (*task.ProcessReturnValue, error) {
|
maybeRunTaskInBackground(c, taskName, resources, func(_ aptly.Progress, _ *task.Detail) (*task.ProcessReturnValue, error) {
|
||||||
taskCollectionFactory := context.NewCollectionFactory()
|
taskCollectionFactory := context.NewCollectionFactory()
|
||||||
@@ -186,7 +186,7 @@ func apiSnapshotsCreate(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resources = append(resources, string(sources[i].ResourceKey()))
|
resources = append(resources, string(sources[i].Key()))
|
||||||
}
|
}
|
||||||
|
|
||||||
maybeRunTaskInBackground(c, "Create snapshot "+b.Name, resources, func(_ aptly.Progress, _ *task.Detail) (*task.ProcessReturnValue, error) {
|
maybeRunTaskInBackground(c, "Create snapshot "+b.Name, resources, func(_ aptly.Progress, _ *task.Detail) (*task.ProcessReturnValue, error) {
|
||||||
@@ -209,9 +209,20 @@ func apiSnapshotsCreate(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
list := deb.NewPackageList()
|
// Merge packages from all source snapshots
|
||||||
|
var refList *deb.PackageRefList
|
||||||
|
if len(freshSources) > 0 {
|
||||||
|
refList = freshSources[0].RefList()
|
||||||
|
for i := 1; i < len(freshSources); i++ {
|
||||||
|
refList = refList.Merge(freshSources[i].RefList(), true, false)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
refList = deb.NewPackageRefList()
|
||||||
|
}
|
||||||
|
|
||||||
// verify package refs and build package list using fresh factory
|
// Add any explicitly specified package refs on top
|
||||||
|
if len(b.PackageRefs) > 0 {
|
||||||
|
list := deb.NewPackageList()
|
||||||
for _, ref := range b.PackageRefs {
|
for _, ref := range b.PackageRefs {
|
||||||
p, err := taskPackageCollection.ByKey([]byte(ref))
|
p, err := taskPackageCollection.ByKey([]byte(ref))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -225,8 +236,10 @@ func apiSnapshotsCreate(c *gin.Context) {
|
|||||||
return &task.ProcessReturnValue{Code: http.StatusBadRequest, Value: nil}, err
|
return &task.ProcessReturnValue{Code: http.StatusBadRequest, Value: nil}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
refList = refList.Merge(deb.NewPackageRefListFromPackageList(list), true, false)
|
||||||
|
}
|
||||||
|
|
||||||
snapshot = deb.NewSnapshotFromRefList(b.Name, freshSources, deb.NewPackageRefListFromPackageList(list), b.Description)
|
snapshot = deb.NewSnapshotFromRefList(b.Name, freshSources, refList, b.Description)
|
||||||
|
|
||||||
err = taskSnapshotCollection.Add(snapshot)
|
err = taskSnapshotCollection.Add(snapshot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -278,7 +291,7 @@ func apiSnapshotsCreateFromRepository(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// including snapshot resource key
|
// including snapshot resource key
|
||||||
resources := []string{string(repo.Key()), "S" + b.Name}
|
resources := []string{string(repo.Key())}
|
||||||
taskName := fmt.Sprintf("Create snapshot of repo %s", name)
|
taskName := fmt.Sprintf("Create snapshot of repo %s", name)
|
||||||
maybeRunTaskInBackground(c, taskName, resources, func(_ aptly.Progress, _ *task.Detail) (*task.ProcessReturnValue, error) {
|
maybeRunTaskInBackground(c, taskName, resources, func(_ aptly.Progress, _ *task.Detail) (*task.ProcessReturnValue, error) {
|
||||||
taskCollectionFactory := context.NewCollectionFactory()
|
taskCollectionFactory := context.NewCollectionFactory()
|
||||||
@@ -362,7 +375,7 @@ func apiSnapshotsUpdate(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resources := []string{string(snapshot.ResourceKey()), "S" + b.Name}
|
resources := []string{string(snapshot.Key())}
|
||||||
taskName := fmt.Sprintf("Update snapshot %s", name)
|
taskName := fmt.Sprintf("Update snapshot %s", name)
|
||||||
|
|
||||||
maybeRunTaskInBackground(c, taskName, resources, func(_ aptly.Progress, _ *task.Detail) (*task.ProcessReturnValue, error) {
|
maybeRunTaskInBackground(c, taskName, resources, func(_ aptly.Progress, _ *task.Detail) (*task.ProcessReturnValue, error) {
|
||||||
@@ -457,7 +470,7 @@ func apiSnapshotsDrop(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resources := []string{string(snapshot.ResourceKey())}
|
resources := []string{string(snapshot.Key())}
|
||||||
taskName := fmt.Sprintf("Delete snapshot %s", name)
|
taskName := fmt.Sprintf("Delete snapshot %s", name)
|
||||||
|
|
||||||
maybeRunTaskInBackground(c, taskName, resources, func(_ aptly.Progress, _ *task.Detail) (*task.ProcessReturnValue, error) {
|
maybeRunTaskInBackground(c, taskName, resources, func(_ aptly.Progress, _ *task.Detail) (*task.ProcessReturnValue, error) {
|
||||||
@@ -655,7 +668,7 @@ func apiSnapshotsMerge(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resources[i] = string(sources[i].ResourceKey())
|
resources[i] = string(sources[i].Key())
|
||||||
}
|
}
|
||||||
|
|
||||||
maybeRunTaskInBackground(c, "Merge snapshot "+name, resources, func(_ aptly.Progress, _ *task.Detail) (*task.ProcessReturnValue, error) {
|
maybeRunTaskInBackground(c, "Merge snapshot "+name, resources, func(_ aptly.Progress, _ *task.Detail) (*task.ProcessReturnValue, error) {
|
||||||
@@ -776,7 +789,7 @@ func apiSnapshotsPull(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resources := []string{string(sourceSnapshot.ResourceKey()), string(toSnapshot.ResourceKey())}
|
resources := []string{string(sourceSnapshot.Key()), string(toSnapshot.Key())}
|
||||||
taskName := fmt.Sprintf("Pull snapshot %s into %s and save as %s", body.Source, name, body.Destination)
|
taskName := fmt.Sprintf("Pull snapshot %s into %s and save as %s", body.Source, name, body.Destination)
|
||||||
maybeRunTaskInBackground(c, taskName, resources, func(_ aptly.Progress, _ *task.Detail) (*task.ProcessReturnValue, error) {
|
maybeRunTaskInBackground(c, taskName, resources, func(_ aptly.Progress, _ *task.Detail) (*task.ProcessReturnValue, error) {
|
||||||
// Phase 2: Inside task lock - create fresh factory
|
// Phase 2: Inside task lock - create fresh factory
|
||||||
|
|||||||
@@ -143,12 +143,6 @@ func (s *Snapshot) Key() []byte {
|
|||||||
return []byte("S" + s.UUID)
|
return []byte("S" + s.UUID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResourceKey is a unique identifier of the resource
|
|
||||||
// this snapshot uses. Instead of uuid it uses name
|
|
||||||
// which needs to be unique as well.
|
|
||||||
func (s *Snapshot) ResourceKey() []byte {
|
|
||||||
return []byte("S" + s.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RefKey is a unique id for package reference list
|
// RefKey is a unique id for package reference list
|
||||||
func (s *Snapshot) RefKey() []byte {
|
func (s *Snapshot) RefKey() []byte {
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
FROM aptly-dev
|
|
||||||
|
|
||||||
ADD --chown=aptly:aptly . /work/src/
|
|
||||||
|
|
||||||
# Pre-populate the Go module cache so go mod verify works offline
|
|
||||||
RUN chown aptly /work/src && mkdir -p /work/src/.go && chown aptly /work/src/.go && \
|
|
||||||
cd /work/src && sudo -u aptly GOPATH=/work/src/.go GOCACHE=/work/src/.go/cache go mod download
|
|
||||||
@@ -1207,10 +1207,9 @@ class PublishSwitchAPITestSnapshot(APITest):
|
|||||||
self.check_equal(all_repos.status_code, 200)
|
self.check_equal(all_repos.status_code, 200)
|
||||||
self.check_in(repo_expected, all_repos.json())
|
self.check_in(repo_expected, all_repos.json())
|
||||||
|
|
||||||
# FIXME: what should exist here ? publish snapshot of snapshot
|
|
||||||
self.check_not_exists(
|
self.check_not_exists(
|
||||||
"public/" + prefix + "/pool/main/b/boost-defaults/libboost-program-options-dev_1.49.0.1_i386.deb")
|
"public/" + prefix + "/pool/main/b/boost-defaults/libboost-program-options-dev_1.49.0.1_i386.deb")
|
||||||
self.check_not_exists("public/" + prefix +
|
self.check_exists("public/" + prefix +
|
||||||
"/pool/main/p/pyspi/pyspi-0.6.1-1.3.stripped.dsc")
|
"/pool/main/p/pyspi/pyspi-0.6.1-1.3.stripped.dsc")
|
||||||
|
|
||||||
task = self.delete_task("/api/publish/" + prefix + "/wheezy")
|
task = self.delete_task("/api/publish/" + prefix + "/wheezy")
|
||||||
|
|||||||
+4
-4
@@ -67,7 +67,7 @@ func (list *List) consumer() {
|
|||||||
task.processReturnValue = retValue
|
task.processReturnValue = retValue
|
||||||
}
|
}
|
||||||
|
|
||||||
list.usedResources.Free(task.resources)
|
list.usedResources.Free(task.Resources)
|
||||||
|
|
||||||
task.wgTask.Done()
|
task.wgTask.Done()
|
||||||
list.wg.Done()
|
list.wg.Done()
|
||||||
@@ -76,9 +76,9 @@ func (list *List) consumer() {
|
|||||||
for _, t := range list.tasks {
|
for _, t := range list.tasks {
|
||||||
if t.State == IDLE {
|
if t.State == IDLE {
|
||||||
// check resources
|
// check resources
|
||||||
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)
|
||||||
// unlock list since queueing may block
|
// unlock list since queueing may block
|
||||||
list.Unlock()
|
list.Unlock()
|
||||||
unlocked = true
|
unlocked = true
|
||||||
@@ -219,7 +219,7 @@ func (list *List) RunTaskInBackground(name string, resources []string, process P
|
|||||||
// if not, task will be queued by the consumer once resources are available
|
// if not, task will be queued by the consumer once resources are available
|
||||||
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)
|
||||||
// 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
|
||||||
|
|||||||
+2
-2
@@ -52,7 +52,7 @@ type Task struct {
|
|||||||
Name string
|
Name string
|
||||||
ID int
|
ID int
|
||||||
State State
|
State State
|
||||||
resources []string
|
Resources []string
|
||||||
wgTask *sync.WaitGroup
|
wgTask *sync.WaitGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ func NewTask(process Process, name string, ID int, resources []string, wgTask *s
|
|||||||
Name: name,
|
Name: name,
|
||||||
ID: ID,
|
ID: ID,
|
||||||
State: IDLE,
|
State: IDLE,
|
||||||
resources: resources,
|
Resources: resources,
|
||||||
wgTask: wgTask,
|
wgTask: wgTask,
|
||||||
}
|
}
|
||||||
return task
|
return task
|
||||||
|
|||||||
Reference in New Issue
Block a user