Merge pull request #1375 from aol-nnov/api-create-repo-from-snapshot

Update create repo API to support snapshots
This commit is contained in:
André Roth
2024-10-22 11:45:47 +02:00
committed by GitHub
3 changed files with 96 additions and 16 deletions

View File

@@ -63,3 +63,4 @@ List of contributors, in chronological order:
* Ramón N.Rodriguez (https://github.com/runitonmetal)
* Golf Hu (https://github.com/hudeng-go)
* Cookie Fei (https://github.com/wuhuang26)
* Andrey Loukhnov (https://github.com/aol-nnov)

View File

@@ -69,25 +69,32 @@ func apiReposList(c *gin.Context) {
c.JSON(200, result)
}
type repoCreateParams struct {
// Name of repository to create
Name string `binding:"required" json:"Name" example:"repo1"`
// Text describing the repository (optional)
Comment string ` json:"Comment" example:"this is a repo"`
// Default distribution when publishing from this local repo
DefaultDistribution string ` json:"DefaultDistribution" example:"stable"`
// Default component when publishing from this local repo
DefaultComponent string ` json:"DefaultComponent" example:"main"`
// Snapshot name to create repoitory from (optional)
FromSnapshot string ` json:"FromSnapshot" example:"snapshot1"`
}
// @Summary Create repository
// @Description Create a local repository.
// @Tags Repos
// @Produce json
// @Consume json
// @Param Name query string false "Name of repository to be created."
// @Param Comment query string false "Text describing local repository, for the user"
// @Param DefaultDistribution query string false "Default distribution when publishing from this local repo"
// @Param DefaultComponent query string false "Default component when publishing from this local repo"
// @Param request body repoCreateParams true "Parameters"
// @Success 201 {object} deb.LocalRepo
// @Failure 400 {object} Error "Repository already exists"
// @Failure 404 {object} Error "Source snapshot not found"
// @Failure 409 {object} Error "Local repo already exists"
// @Failure 500 {object} Error "Internal error"
// @Router /api/repos [post]
func apiReposCreate(c *gin.Context) {
var b struct {
Name string `binding:"required"`
Comment string
DefaultDistribution string
DefaultComponent string
}
var b repoCreateParams
if c.Bind(&b) != nil {
return
@@ -98,14 +105,41 @@ func apiReposCreate(c *gin.Context) {
repo.DefaultDistribution = b.DefaultDistribution
collectionFactory := context.NewCollectionFactory()
collection := collectionFactory.LocalRepoCollection()
err := collection.Add(repo)
if err != nil {
AbortWithJSONError(c, 400, err)
if b.FromSnapshot != "" {
var snapshot *deb.Snapshot
snapshotCollection := collectionFactory.SnapshotCollection()
snapshot, err := snapshotCollection.ByName(b.FromSnapshot)
if err != nil {
AbortWithJSONError(c, http.StatusNotFound, fmt.Errorf("source snapshot not found: %s", err))
return
}
err = snapshotCollection.LoadComplete(snapshot)
if err != nil {
AbortWithJSONError(c, http.StatusInternalServerError, fmt.Errorf("unable to load source snapshot: %s", err))
return
}
repo.UpdateRefList(snapshot.RefList())
}
localRepoCollection := collectionFactory.LocalRepoCollection()
if _, err := localRepoCollection.ByName(b.Name); err == nil {
AbortWithJSONError(c, http.StatusConflict, fmt.Errorf("local repo with name %s already exists", b.Name))
return
}
c.JSON(201, repo)
err := localRepoCollection.Add(repo)
if err != nil {
AbortWithJSONError(c, http.StatusInternalServerError, err)
return
}
c.JSON(http.StatusCreated, repo)
}
// PUT /api/repos/:name

View File

@@ -28,6 +28,51 @@ class ReposAPITestCreateShow(APITest):
self.check_equal(self.get("/api/repos/" + self.random_name()).status_code, 404)
class ReposAPITestCreateFromSnapshot(APITest):
"""
Create repo from snapshot
"""
def check(self):
initial_repo = self.random_name()
self.check_equal(self.post("/api/repos", json={"Name": initial_repo}).status_code, 201)
d = self.random_name()
self.check_equal(self.upload("/api/files/" + d,
"libboost-program-options-dev_1.49.0.1_i386.deb").status_code, 200)
task = self.post_task("/api/repos/" + initial_repo + "/file/" + d)
self.check_task(task)
snapshot_name = self.random_name()
task = self.post_task("/api/repos/" + initial_repo + '/snapshots', json={'Name': snapshot_name})
self.check_task(task)
self.check_equal(self.get("/api/snapshots/" + snapshot_name).status_code, 200)
repo_from_snapshot = self.random_name()
new_repo = {'Name': repo_from_snapshot,
'FromSnapshot': snapshot_name}
resp = self.post("/api/repos", json=new_repo)
self.check_equal(resp.status_code, 201)
self.check_equal(self.get("/api/repos/" + repo_from_snapshot + "/packages").json(),
['Pi386 libboost-program-options-dev 1.49.0.1 918d2f433384e378'])
class ReposAPITestCreateFromWrongSnapshot(APITest):
"""
Create repo from snapshot
"""
def check(self):
snapshot_name = self.random_name() # non-existing snapshot
repo_from_snapshot = self.random_name()
new_repo = {'Name': repo_from_snapshot,
'FromSnapshot': snapshot_name}
resp = self.post("/api/repos", json=new_repo)
self.check_equal(resp.status_code, 404)
class ReposAPITestCreateIndexDelete(APITest):
"""
GET /api/repos, POST /api/repos, DELETE /api/repos/:name