Merge pull request #751 from sliverc/repo_include_api

Expose repo include through API
This commit is contained in:
Oliver Sauder
2018-06-19 16:02:22 +02:00
committed by GitHub
16 changed files with 681 additions and 188 deletions

View File

@@ -8,6 +8,7 @@ import (
"github.com/aptly-dev/aptly/aptly"
"github.com/aptly-dev/aptly/database"
"github.com/aptly-dev/aptly/deb"
"github.com/aptly-dev/aptly/query"
"github.com/aptly-dev/aptly/utils"
"github.com/gin-gonic/gin"
)
@@ -367,3 +368,77 @@ func apiReposPackageFromDir(c *gin.Context) {
"FailedFiles": failedFiles,
})
}
// POST /repos/:name/include/:dir/:file
func apiReposIncludePackageFromFile(c *gin.Context) {
// redirect all work to dir method
apiReposIncludePackageFromDir(c)
}
// POST /repos/:name/include/:dir
func apiReposIncludePackageFromDir(c *gin.Context) {
forceReplace := c.Request.URL.Query().Get("forceReplace") == "1"
noRemoveFiles := c.Request.URL.Query().Get("noRemoveFiles") == "1"
acceptUnsigned := c.Request.URL.Query().Get("acceptUnsigned") == "1"
ignoreSignature := c.Request.URL.Query().Get("ignoreSignature") == "1"
repoTemplateString := c.Params.ByName("name")
if !verifyDir(c) {
return
}
fileParam := c.Params.ByName("file")
if fileParam != "" && !verifyPath(fileParam) {
c.AbortWithError(400, fmt.Errorf("wrong file"))
return
}
var (
err error
verifier = context.GetVerifier()
sources, changesFiles []string
failedFiles, failedFiles2 []string
reporter = &aptly.RecordingResultReporter{
Warnings: []string{},
AddedLines: []string{},
RemovedLines: []string{},
}
)
if fileParam == "" {
sources = []string{filepath.Join(context.UploadPath(), c.Params.ByName("dir"))}
} else {
sources = []string{filepath.Join(context.UploadPath(), c.Params.ByName("dir"), c.Params.ByName("file"))}
}
localRepoCollection := context.CollectionFactory().LocalRepoCollection()
localRepoCollection.Lock()
defer localRepoCollection.Unlock()
changesFiles, failedFiles = deb.CollectChangesFiles(sources, reporter)
_, failedFiles2, err = deb.ImportChangesFiles(
changesFiles, reporter, acceptUnsigned, ignoreSignature, forceReplace, noRemoveFiles, verifier,
repoTemplateString, context.Progress(), localRepoCollection, context.CollectionFactory().PackageCollection(),
context.PackagePool(), context.CollectionFactory().ChecksumCollection(), nil, query.Parse)
failedFiles = append(failedFiles, failedFiles2...)
if err != nil {
c.AbortWithError(500, fmt.Errorf("unable to import changes files: %s", err))
return
}
if !noRemoveFiles {
// atempt to remove dir, if it fails, that's fine: probably it's not empty
os.Remove(filepath.Join(context.UploadPath(), c.Params.ByName("dir")))
}
if failedFiles == nil {
failedFiles = []string{}
}
c.JSON(200, gin.H{
"Report": reporter,
"FailedFiles": failedFiles,
})
}

View File

@@ -71,6 +71,9 @@ func Router(c *ctx.AptlyContext) http.Handler {
root.POST("/repos/:name/file/:dir/:file", apiReposPackageFromFile)
root.POST("/repos/:name/file/:dir", apiReposPackageFromDir)
root.POST("/repos/:name/include/:dir/:file", apiReposIncludePackageFromFile)
root.POST("/repos/:name/include/:dir", apiReposIncludePackageFromDir)
root.POST("/repos/:name/snapshots", apiSnapshotsCreateFromRepository)
}

View File

@@ -1,16 +1,11 @@
package cmd
import (
"bytes"
"fmt"
"os"
"path/filepath"
"text/template"
"github.com/aptly-dev/aptly/aptly"
"github.com/aptly-dev/aptly/deb"
"github.com/aptly-dev/aptly/query"
"github.com/aptly-dev/aptly/utils"
"github.com/smira/commander"
"github.com/smira/flag"
)
@@ -35,11 +30,7 @@ func aptlyRepoInclude(cmd *commander.Command, args []string) error {
acceptUnsigned := context.Flags().Lookup("accept-unsigned").Value.Get().(bool)
ignoreSignatures := context.Flags().Lookup("ignore-signatures").Value.Get().(bool)
noRemoveFiles := context.Flags().Lookup("no-remove-files").Value.Get().(bool)
repoTemplate, err := template.New("repo").Parse(context.Flags().Lookup("repo").Value.Get().(string))
if err != nil {
return fmt.Errorf("error parsing -repo template: %s", err)
}
repoTemplateString := context.Flags().Lookup("repo").Value.Get().(string)
uploaders := (*deb.Uploaders)(nil)
uploadersFile := context.Flags().Lookup("uploaders-file").Value.Get().(string)
@@ -59,143 +50,15 @@ func aptlyRepoInclude(cmd *commander.Command, args []string) error {
reporter := &aptly.ConsoleResultReporter{Progress: context.Progress()}
var changesFiles, failedFiles, processedFiles []string
var changesFiles, failedFiles, failedFiles2 []string
changesFiles, failedFiles = deb.CollectChangesFiles(args, reporter)
for _, path := range changesFiles {
var changes *deb.Changes
changes, err = deb.NewChanges(path)
if err != nil {
failedFiles = append(failedFiles, path)
reporter.Warning("unable to process file %s: %s", path, err)
continue
}
err = changes.VerifyAndParse(acceptUnsigned, ignoreSignatures, verifier)
if err != nil {
failedFiles = append(failedFiles, path)
reporter.Warning("unable to process file %s: %s", changes.ChangesName, err)
changes.Cleanup()
continue
}
err = changes.Prepare()
if err != nil {
failedFiles = append(failedFiles, path)
reporter.Warning("unable to process file %s: %s", changes.ChangesName, err)
changes.Cleanup()
continue
}
repoName := &bytes.Buffer{}
err = repoTemplate.Execute(repoName, changes.Stanza)
if err != nil {
return fmt.Errorf("error applying template to repo: %s", err)
}
context.Progress().Printf("Loading repository %s for changes file %s...\n", repoName.String(), changes.ChangesName)
var repo *deb.LocalRepo
repo, err = context.CollectionFactory().LocalRepoCollection().ByName(repoName.String())
if err != nil {
failedFiles = append(failedFiles, path)
reporter.Warning("unable to process file %s: %s", changes.ChangesName, err)
changes.Cleanup()
continue
}
currentUploaders := uploaders
if repo.Uploaders != nil {
currentUploaders = repo.Uploaders
for i := range currentUploaders.Rules {
currentUploaders.Rules[i].CompiledCondition, err = query.Parse(currentUploaders.Rules[i].Condition)
if err != nil {
return fmt.Errorf("error parsing query %s: %s", currentUploaders.Rules[i].Condition, err)
}
}
}
if currentUploaders != nil {
if err = currentUploaders.IsAllowed(changes); err != nil {
failedFiles = append(failedFiles, path)
reporter.Warning("changes file skipped due to uploaders config: %s, keys %#v: %s",
changes.ChangesName, changes.SignatureKeys, err)
changes.Cleanup()
continue
}
}
err = context.CollectionFactory().LocalRepoCollection().LoadComplete(repo)
if err != nil {
return fmt.Errorf("unable to load repo: %s", err)
}
var list *deb.PackageList
list, err = deb.NewPackageListFromRefList(repo.RefList(), context.CollectionFactory().PackageCollection(), context.Progress())
if err != nil {
return fmt.Errorf("unable to load packages: %s", err)
}
packageFiles, otherFiles, _ := deb.CollectPackageFiles([]string{changes.TempDir}, reporter)
var restriction deb.PackageQuery
restriction, err = changes.PackageQuery()
if err != nil {
failedFiles = append(failedFiles, path)
reporter.Warning("unable to process file %s: %s", changes.ChangesName, err)
changes.Cleanup()
continue
}
var processedFiles2, failedFiles2 []string
processedFiles2, failedFiles2, err = deb.ImportPackageFiles(list, packageFiles, forceReplace, verifier, context.PackagePool(),
context.CollectionFactory().PackageCollection(), reporter, restriction, context.CollectionFactory().ChecksumCollection())
if err != nil {
return fmt.Errorf("unable to import package files: %s", err)
}
repo.UpdateRefList(deb.NewPackageRefListFromPackageList(list))
err = context.CollectionFactory().LocalRepoCollection().Update(repo)
if err != nil {
return fmt.Errorf("unable to save: %s", err)
}
err = changes.Cleanup()
if err != nil {
return err
}
for _, file := range failedFiles2 {
failedFiles = append(failedFiles, filepath.Join(changes.BasePath, filepath.Base(file)))
}
for _, file := range processedFiles2 {
processedFiles = append(processedFiles, filepath.Join(changes.BasePath, filepath.Base(file)))
}
for _, file := range otherFiles {
processedFiles = append(processedFiles, filepath.Join(changes.BasePath, filepath.Base(file)))
}
processedFiles = append(processedFiles, path)
}
if !noRemoveFiles {
processedFiles = utils.StrSliceDeduplicate(processedFiles)
for _, file := range processedFiles {
err = os.Remove(file)
if err != nil {
return fmt.Errorf("unable to remove file: %s", err)
}
}
}
_, failedFiles2, err = deb.ImportChangesFiles(
changesFiles, reporter, acceptUnsigned, ignoreSignatures, forceReplace, noRemoveFiles, verifier, repoTemplateString,
context.Progress(), context.CollectionFactory().LocalRepoCollection(), context.CollectionFactory().PackageCollection(),
context.PackagePool(), context.CollectionFactory().ChecksumCollection(),
uploaders, query.Parse)
failedFiles = append(failedFiles, failedFiles2...)
if len(failedFiles) > 0 {
context.Progress().ColoredPrintf("@y[!]@| @!Some files were skipped due to errors:@|")

View File

@@ -1,6 +1,7 @@
package deb
import (
"bytes"
"fmt"
"io"
"io/ioutil"
@@ -8,6 +9,7 @@ import (
"path/filepath"
"sort"
"strings"
"text/template"
"github.com/aptly-dev/aptly/aptly"
"github.com/aptly-dev/aptly/pgp"
@@ -164,7 +166,7 @@ func (c *Changes) Cleanup() error {
}
// PackageQuery returns query that every package should match to be included
func (c *Changes) PackageQuery() (PackageQuery, error) {
func (c *Changes) PackageQuery() PackageQuery {
var archQuery PackageQuery = &FieldQuery{Field: "$Architecture", Relation: VersionEqual, Value: ""}
for _, arch := range c.Architectures {
archQuery = &OrQuery{L: &FieldQuery{Field: "$Architecture", Relation: VersionEqual, Value: arch}, R: archQuery}
@@ -215,7 +217,7 @@ func (c *Changes) PackageQuery() (PackageQuery, error) {
nameQuery = &OrQuery{L: sourceQuery, R: binaryQuery}
}
return &AndQuery{L: archQuery, R: nameQuery}, nil
return &AndQuery{L: archQuery, R: nameQuery}
}
// GetField implements PackageLike interface
@@ -288,3 +290,143 @@ func CollectChangesFiles(locations []string, reporter aptly.ResultReporter) (cha
return
}
// ImportChangesFiles imports referenced files in changes files into local repository
func ImportChangesFiles(changesFiles []string, reporter aptly.ResultReporter, acceptUnsigned, ignoreSignatures, forceReplace, noRemoveFiles bool,
verifier pgp.Verifier, repoTemplateString string, progress aptly.Progress, localRepoCollection *LocalRepoCollection, packageCollection *PackageCollection,
pool aptly.PackagePool, checksumStorage aptly.ChecksumStorage, uploaders *Uploaders, parseQuery parseQuery) (processedFiles []string, failedFiles []string, err error) {
var repoTemplate *template.Template
repoTemplate, err = template.New("repo").Parse(repoTemplateString)
if err != nil {
return nil, nil, fmt.Errorf("error parsing -repo template: %s", err)
}
for _, path := range changesFiles {
var changes *Changes
changes, err = NewChanges(path)
if err != nil {
failedFiles = append(failedFiles, path)
reporter.Warning("unable to process file %s: %s", path, err)
continue
}
err = changes.VerifyAndParse(acceptUnsigned, ignoreSignatures, verifier)
if err != nil {
failedFiles = append(failedFiles, path)
reporter.Warning("unable to process file %s: %s", changes.ChangesName, err)
changes.Cleanup()
continue
}
err = changes.Prepare()
if err != nil {
failedFiles = append(failedFiles, path)
reporter.Warning("unable to process file %s: %s", changes.ChangesName, err)
changes.Cleanup()
continue
}
repoName := &bytes.Buffer{}
err = repoTemplate.Execute(repoName, changes.Stanza)
if err != nil {
return nil, nil, fmt.Errorf("error applying template to repo: %s", err)
}
if progress != nil {
progress.Printf("Loading repository %s for changes file %s...\n", repoName.String(), changes.ChangesName)
}
var repo *LocalRepo
repo, err = localRepoCollection.ByName(repoName.String())
if err != nil {
failedFiles = append(failedFiles, path)
reporter.Warning("unable to process file %s: %s", changes.ChangesName, err)
changes.Cleanup()
continue
}
currentUploaders := uploaders
if repo.Uploaders != nil {
currentUploaders = repo.Uploaders
for i := range currentUploaders.Rules {
currentUploaders.Rules[i].CompiledCondition, err = parseQuery(currentUploaders.Rules[i].Condition)
if err != nil {
return nil, nil, fmt.Errorf("error parsing query %s: %s", currentUploaders.Rules[i].Condition, err)
}
}
}
if currentUploaders != nil {
if err = currentUploaders.IsAllowed(changes); err != nil {
failedFiles = append(failedFiles, path)
reporter.Warning("changes file skipped due to uploaders config: %s, keys %#v: %s",
changes.ChangesName, changes.SignatureKeys, err)
changes.Cleanup()
continue
}
}
err = localRepoCollection.LoadComplete(repo)
if err != nil {
return nil, nil, fmt.Errorf("unable to load repo: %s", err)
}
var list *PackageList
list, err = NewPackageListFromRefList(repo.RefList(), packageCollection, progress)
if err != nil {
return nil, nil, fmt.Errorf("unable to load packages: %s", err)
}
packageFiles, otherFiles, _ := CollectPackageFiles([]string{changes.TempDir}, reporter)
restriction := changes.PackageQuery()
var processedFiles2, failedFiles2 []string
processedFiles2, failedFiles2, err = ImportPackageFiles(list, packageFiles, forceReplace, verifier, pool,
packageCollection, reporter, restriction, checksumStorage)
if err != nil {
return nil, nil, fmt.Errorf("unable to import package files: %s", err)
}
repo.UpdateRefList(NewPackageRefListFromPackageList(list))
err = localRepoCollection.Update(repo)
if err != nil {
return nil, nil, fmt.Errorf("unable to save: %s", err)
}
err = changes.Cleanup()
if err != nil {
return nil, nil, err
}
for _, file := range failedFiles2 {
failedFiles = append(failedFiles, filepath.Join(changes.BasePath, filepath.Base(file)))
}
for _, file := range processedFiles2 {
processedFiles = append(processedFiles, filepath.Join(changes.BasePath, filepath.Base(file)))
}
for _, file := range otherFiles {
processedFiles = append(processedFiles, filepath.Join(changes.BasePath, filepath.Base(file)))
}
processedFiles = append(processedFiles, path)
}
if !noRemoveFiles {
processedFiles = utils.StrSliceDeduplicate(processedFiles)
for _, file := range processedFiles {
err = os.Remove(file)
if err != nil {
return nil, nil, fmt.Errorf("unable to remove file: %s", err)
}
}
}
return processedFiles, failedFiles, nil
}

View File

@@ -4,24 +4,52 @@ import (
"os"
"path/filepath"
"github.com/aptly-dev/aptly/aptly"
"github.com/aptly-dev/aptly/console"
"github.com/aptly-dev/aptly/database"
"github.com/aptly-dev/aptly/files"
"github.com/aptly-dev/aptly/utils"
. "gopkg.in/check.v1"
)
type ChangesSuite struct {
Dir, Path string
Dir, Path string
Reporter aptly.ResultReporter
db database.Storage
localRepoCollection *LocalRepoCollection
packageCollection *PackageCollection
packagePool aptly.PackagePool
checksumStorage aptly.ChecksumStorage
progress aptly.Progress
}
var _ = Suite(&ChangesSuite{})
func (s *ChangesSuite) SetUpTest(c *C) {
s.Reporter = &aptly.RecordingResultReporter{
Warnings: []string{},
AddedLines: []string{},
RemovedLines: []string{},
}
s.Dir = c.MkDir()
s.Path = filepath.Join(s.Dir, "calamares.changes")
f, err := os.Create(s.Path)
err := utils.CopyFile("testdata/changes/calamares.changes", s.Path)
c.Assert(err, IsNil)
f.WriteString(changesFile)
f.Close()
s.db, _ = database.NewOpenDB(c.MkDir())
s.localRepoCollection = NewLocalRepoCollection(s.db)
s.packageCollection = NewPackageCollection(s.db)
s.checksumStorage = files.NewMockChecksumStorage()
s.packagePool = files.NewPackagePool(s.Dir, false)
s.progress = console.NewProgress()
s.progress.Start()
}
func (s *ChangesSuite) TearDownTest(c *C) {
s.progress.Shutdown()
s.db.Close()
}
func (s *ChangesSuite) TestParseAndVerify(c *C) {
@@ -44,6 +72,73 @@ func (s *ChangesSuite) TestParseAndVerify(c *C) {
c.Check(changes.Binary, DeepEquals, []string{"calamares", "calamares-dbg"})
}
func (s *ChangesSuite) TestCollectChangesFiles(c *C) {
changesFiles, failedFiles := CollectChangesFiles([]string{"testdata/changes"}, s.Reporter)
c.Check(failedFiles, HasLen, 0)
c.Check(changesFiles, DeepEquals, []string{
"testdata/changes/calamares.changes",
"testdata/changes/hardlink_0.2.1-invalidfiles_amd64.changes",
"testdata/changes/hardlink_0.2.1-invalidsig_amd64.changes",
"testdata/changes/hardlink_0.2.1_amd64.changes",
})
}
func (s *ChangesSuite) TestImportChangesFiles(c *C) {
repo := NewLocalRepo("test", "Test Comment")
c.Assert(s.localRepoCollection.Add(repo), IsNil)
origFailedFiles := []string{
"testdata/changes/calamares.changes",
"testdata/changes/hardlink_0.2.1-invalidfiles_amd64.changes",
"testdata/changes/hardlink_0.2.1-invalidsig_amd64.changes",
"testdata/changes/hardlink_0.2.0_i386.deb",
}
origProcessedFiles := []string{
"testdata/changes/hardlink_0.2.1.dsc",
"testdata/changes/hardlink_0.2.1.tar.gz",
"testdata/changes/hardlink_0.2.1_amd64.deb",
"testdata/changes/hardlink_0.2.1_amd64.buildinfo",
"testdata/changes/hardlink_0.2.1_amd64.changes",
}
var expectedProcessedFiles, expectedFailedFiles []string
for _, path := range origFailedFiles {
filename := filepath.Join(s.Dir, filepath.Base(path))
utils.CopyFile(path, filename)
expectedFailedFiles = append(expectedFailedFiles, filename)
}
for _, path := range origProcessedFiles {
filename := filepath.Join(s.Dir, filepath.Base(path))
utils.CopyFile(path, filename)
expectedProcessedFiles = append(expectedProcessedFiles, filename)
}
changesFiles, failedFiles := CollectChangesFiles([]string{s.Dir}, s.Reporter)
c.Check(failedFiles, HasLen, 0)
processedFiles, failedFiles, err := ImportChangesFiles(
append(changesFiles, "testdata/changes/notexistent.changes"),
s.Reporter, true, true, false, false, &NullVerifier{},
"test", s.progress, s.localRepoCollection, s.packageCollection, s.packagePool, s.checksumStorage,
nil, nil)
c.Assert(err, IsNil)
c.Check(failedFiles, DeepEquals, append(expectedFailedFiles, "testdata/changes/notexistent.changes"))
c.Check(processedFiles, DeepEquals, expectedProcessedFiles)
}
func (s *ChangesSuite) TestPrepare(c *C) {
changes, err := NewChanges("testdata/changes/hardlink_0.2.1_amd64.changes")
c.Assert(err, IsNil)
err = changes.Prepare()
c.Assert(err, IsNil)
_, err = os.Stat(filepath.Join(changes.TempDir, "hardlink_0.2.1_amd64.changes"))
c.Check(err, IsNil)
}
func (s *ChangesSuite) TestPackageQuery(c *C) {
changes, err := NewChanges(s.Path)
c.Assert(err, IsNil)
@@ -51,42 +146,7 @@ func (s *ChangesSuite) TestPackageQuery(c *C) {
err = changes.VerifyAndParse(true, true, &NullVerifier{})
c.Check(err, IsNil)
q, err := changes.PackageQuery()
c.Check(err, IsNil)
q := changes.PackageQuery()
c.Check(q.String(), Equals,
"(($Architecture (= amd64)) | (($Architecture (= source)) | ($Architecture (= )))), ((($PackageType (= source)), (Name (= calamares))) | ((!($PackageType (= source))), (((Name (= calamares-dbg)) | (Name (= calamares))) | ((Source (= calamares)), ((Name (= calamares-dbg-dbgsym)) | (Name (= calamares-dbgsym)))))))")
}
var changesFile = `Format: 1.8
Date: Thu, 27 Nov 2014 13:24:53 +0000
Source: calamares
Binary: calamares calamares-dbg
Architecture: source amd64
Version: 0+git20141127.99
Distribution: sid
Urgency: medium
Maintainer: Rohan Garg <rohan@kde.org>
Changed-By: Rohan <rohan@kde.org>
Description:
calamares - distribution-independent installer framework
calamares-dbg - distribution-independent installer framework -- debug symbols
Changes:
calamares (0+git20141127.99) sid; urgency=medium
.
* Update from git
Checksums-Sha1:
79f10e955dab6eb25b7f7bae18213f367a3a0396 1106 calamares_0+git20141127.99.dsc
294c28e2c8e34e72ca9ee0d9da5c14f3bf4188db 2694800 calamares_0+git20141127.99.tar.xz
d6c26c04b5407c7511f61cb3e3de60c4a1d6c4ff 1698924 calamares_0+git20141127.99_amd64.deb
a3da632d193007b0d4a1aff73159fde1b532d7a8 12835902 calamares-dbg_0+git20141127.99_amd64.deb
Checksums-Sha256:
35b3280a7b1ffe159a276128cb5c408d687318f60ecbb8ab6dedb2e49c4e82dc 1106 calamares_0+git20141127.99.dsc
5576b9caaf814564830f95561227e4f04ee87b31da22c1371aab155cbf7ce395 2694800 calamares_0+git20141127.99.tar.xz
2e6e2f232ed7ffe52369928ebdf5436d90feb37840286ffba79e87d57a43a2e9 1698924 calamares_0+git20141127.99_amd64.deb
8dd926080ed7bad2e2439e37e49ce12d5f1357c5041b7da4d860a1041f878a8a 12835902 calamares-dbg_0+git20141127.99_amd64.deb
Files:
05fd8f3ffe8f362c5ef9bad2f936a56e 1106 devel optional calamares_0+git20141127.99.dsc
097e55c81abd8e5f30bb2eed90c2c1e9 2694800 devel optional calamares_0+git20141127.99.tar.xz
827fb3b12534241e119815d331e8197b 1698924 devel optional calamares_0+git20141127.99_amd64.deb
e6f8ce70f564d1f68cb57758b15b13e3 12835902 debug optional calamares-dbg_0+git20141127.99_amd64.deb`

View File

@@ -26,6 +26,8 @@ const (
SourceRemoteRepo = "repo"
)
type parseQuery func(string) (PackageQuery, error)
// GetControlFileFromDeb reads control file from deb package
func GetControlFileFromDeb(packageFile string) (Stanza, error) {
file, err := os.Open(packageFile)

32
deb/testdata/changes/calamares.changes vendored Normal file
View File

@@ -0,0 +1,32 @@
Format: 1.8
Date: Thu, 27 Nov 2014 13:24:53 +0000
Source: calamares
Binary: calamares calamares-dbg
Architecture: source amd64
Version: 0+git20141127.99
Distribution: sid
Urgency: medium
Maintainer: Rohan Garg <rohan@kde.org>
Changed-By: Rohan <rohan@kde.org>
Description:
calamares - distribution-independent installer framework
calamares-dbg - distribution-independent installer framework -- debug symbols
Changes:
calamares (0+git20141127.99) sid; urgency=medium
.
* Update from git
Checksums-Sha1:
79f10e955dab6eb25b7f7bae18213f367a3a0396 1106 calamares_0+git20141127.99.dsc
294c28e2c8e34e72ca9ee0d9da5c14f3bf4188db 2694800 calamares_0+git20141127.99.tar.xz
d6c26c04b5407c7511f61cb3e3de60c4a1d6c4ff 1698924 calamares_0+git20141127.99_amd64.deb
a3da632d193007b0d4a1aff73159fde1b532d7a8 12835902 calamares-dbg_0+git20141127.99_amd64.deb
Checksums-Sha256:
35b3280a7b1ffe159a276128cb5c408d687318f60ecbb8ab6dedb2e49c4e82dc 1106 calamares_0+git20141127.99.dsc
5576b9caaf814564830f95561227e4f04ee87b31da22c1371aab155cbf7ce395 2694800 calamares_0+git20141127.99.tar.xz
2e6e2f232ed7ffe52369928ebdf5436d90feb37840286ffba79e87d57a43a2e9 1698924 calamares_0+git20141127.99_amd64.deb
8dd926080ed7bad2e2439e37e49ce12d5f1357c5041b7da4d860a1041f878a8a 12835902 calamares-dbg_0+git20141127.99_amd64.deb
Files:
05fd8f3ffe8f362c5ef9bad2f936a56e 1106 devel optional calamares_0+git20141127.99.dsc
097e55c81abd8e5f30bb2eed90c2c1e9 2694800 devel optional calamares_0+git20141127.99.tar.xz
827fb3b12534241e119815d331e8197b 1698924 devel optional calamares_0+git20141127.99_amd64.deb
e6f8ce70f564d1f68cb57758b15b13e3 12835902 debug optional calamares-dbg_0+git20141127.99_amd64.deb

Binary file not shown.

View File

@@ -0,0 +1,22 @@
Format: 1.8
Date: Sat, 12 May 2014 12:57:02 +0200
Source: hardlink
Binary: hardlink
Architecture: source amd64
Version: 0.2.1
Distribution: unstable
Urgency: low
Maintainer: Julian Andres Klode <jak@debian.org>
Changed-By: Aptly Tester (don't use it) <test@aptly.info>
Description:
hardlink - Hardlinks multiple copies of the same file
Changes:
hardlink (0.2.1) unstable; urgency=low
.
* Update just to try it out :)
Checksums-Sha1:
ff306b8f923653b78e00c45ebbc6c1c734859cdf 949 invalidhardlink_0.2.1.dsc
Checksums-Sha256:
c0d7458aa2ca3886cd6885f395a289efbc9a396e6765cbbca45f51fde859ea70 949 invalidhardlink_0.2.1.dsc
Files:
4efce26825af5842f43961096dd890b3 949 utils optional invalidhardlink_0.2.1.dsc

View File

@@ -0,0 +1,39 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Format: 1.8
Date: Sat, 12 May 2014 12:57:02 +0200
Source: hardlink
Binary: hardlink
Architecture: source amd64
Version: 0.2.1
Distribution: unstable
Urgency: low
Maintainer: Julian Andres Klode <jak@debian.org>
Changed-By: Aptly Tester (don't use it) <test@aptly.info>
Description:
hardlink - Hardlinks multiple copies of the same file
Changes:
hardlink (0.2.1) unstable; urgency=low
.
* Update just to try it out :)
Checksums-Sha1:
ff306b8f923653b78e00c45ebbc6c1c734859cdf 949 hardlink_0.2.1.dsc
6e95b8cba450343ab4dc01902e521f29fbd87ac2 12516 hardlink_0.2.1.tar.gz
1ac0e962854dff46f14fa7943746660d3cad1679 12468 hardlink_0.2.1_amd64.deb
Checksums-Sha256:
c0d7458aa2ca3886cd6885f395a289efbc9a396e6765cbbca45f51fde859ea70 949 hardlink_0.2.1.dsc
4df0adce005526a1f0e1b38171ddb1f017faae9205f5b1c6dfb0fb4207767271 12516 hardlink_0.2.1.tar.gz
668399580590bf1ffcd9eb161b6e574751e15f71820c6e08245dac7c5111a0ee 12468 hardlink_0.2.1_amd64.deb
Files:
4efce26825af5842f43961096dd890b3 949 utils optional hardlink_0.2.1.dsc
8e2caa4d82f228bac08dc9a38bc6edb3 12516 utils optional hardlink_0.2.1.tar.gz
2081e20b36c47f82811c25841cc0e41b 12468 utils optional hardlink_0.2.1_amd64.deb
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)
iEYEARECAAYFAlUFwywACgkQIdu4nBbbPm1DLACgwW4V8qLQC/QHC/7+t3Iq47Ez
eesAn3ZYLQvLYRw3wPTKVAPI+AW6Fjxi
=hRBo
-----END PGP SIGNATURE-----

19
deb/testdata/changes/hardlink_0.2.1.dsc vendored Normal file
View File

@@ -0,0 +1,19 @@
Format: 1.0
Source: hardlink
Binary: hardlink
Architecture: any
Version: 0.2.1
Maintainer: Julian Andres Klode <jak@debian.org>
Homepage: http://jak-linux.org/projects/hardlink/
Standards-Version: 3.9.3
Vcs-Browser: http://git.debian.org/?p=users/jak/hardlink.git;a=summary
Vcs-Git: git://git.debian.org/git/users/jak/hardlink.git
Build-Depends: debhelper (>= 9), pkg-config, libpcre3-dev
Package-List:
hardlink deb utils optional
Checksums-Sha1:
6e95b8cba450343ab4dc01902e521f29fbd87ac2 12516 hardlink_0.2.1.tar.gz
Checksums-Sha256:
4df0adce005526a1f0e1b38171ddb1f017faae9205f5b1c6dfb0fb4207767271 12516 hardlink_0.2.1.tar.gz
Files:
8e2caa4d82f228bac08dc9a38bc6edb3 12516 hardlink_0.2.1.tar.gz

Binary file not shown.

View File

@@ -0,0 +1,170 @@
Format: 1.0
Source: hardlink
Binary: hardlink
Architecture: amd64
Version: 0.2.0
Checksums-Md5:
2081e20b36c47f82811c25841cc0e41b 12468 hardlink_0.2.1_amd64.deb
Checksums-Sha1:
1ac0e962854dff46f14fa7943746660d3cad1679 12468 hardlink_0.2.1_amd64.deb
Checksums-Sha256:
668399580590bf1ffcd9eb161b6e574751e15f71820c6e08245dac7c5111a0ee 12468 hardlink_0.2.1_amd64.deb
Build-Origin: Debian
Build-Architecture: amd64
Build-Kernel-Version: 4.9.0-6-amd64 #1 SMP Debian 4.9.88-1+deb9u1 (2018-05-07)
Build-Date: Sun, 21 Jul 2019 08:01:03 +1400
Build-Path: /build/hardlink-0.3.0/2nd
Installed-Build-Depends:
autoconf (= 2.69-11),
automake (= 1:1.15.1-3.1),
autopoint (= 0.19.8.1-6),
autotools-dev (= 20180224.1),
base-files (= 10.1),
base-passwd (= 3.5.45),
bash (= 4.4.18-3),
binutils (= 2.30-21),
binutils-common (= 2.30-21),
binutils-x86-64-linux-gnu (= 2.30-21),
bsdmainutils (= 11.1.2+b1),
bsdutils (= 1:2.32-0.1),
build-essential (= 12.5),
bzip2 (= 1.0.6-8.1),
coreutils (= 8.28-1),
cpp (= 4:7.3.0-3),
cpp-7 (= 7.3.0-26+really21.0~reproducible0),
dash (= 0.5.8-2.10),
debconf (= 1.5.67),
debhelper (= 11.3.2),
debianutils (= 4.8.6),
dh-autoreconf (= 19),
dh-strip-nondeterminism (= 0.042-1),
diffutils (= 1:3.6-1),
dpkg (= 1.19.0.5.0~reproducible1),
dpkg-dev (= 1.19.0.5.0~reproducible1),
dwz (= 0.12-2),
fdisk (= 2.32-0.1),
file (= 1:5.33-3),
findutils (= 4.6.0+git+20171230-2),
g++ (= 4:7.3.0-3),
g++-7 (= 7.3.0-26+really21.0~reproducible0),
gcc (= 4:7.3.0-3),
gcc-7 (= 7.3.0-26+really21.0~reproducible0),
gcc-7-base (= 7.3.0-26+really21.0~reproducible0),
gcc-8-base (= 8.1.0-6),
gettext (= 0.19.8.1-6+b1),
gettext-base (= 0.19.8.1-6+b1),
grep (= 3.1-2),
groff-base (= 1.22.3-10),
gzip (= 1.6-5+b1),
hostname (= 3.20),
init-system-helpers (= 1.51),
intltool-debian (= 0.35.0+20060710.4),
libacl1 (= 2.2.52-3+b1),
libarchive-zip-perl (= 1.60-1),
libasan4 (= 7.3.0-26+really21.0~reproducible0),
libatomic1 (= 8.1.0-6),
libattr1 (= 1:2.4.47-2+b2),
libattr1-dev (= 1:2.4.47-2+b2),
libaudit-common (= 1:2.8.3-1),
libaudit1 (= 1:2.8.3-1),
libbinutils (= 2.30-21),
libblkid1 (= 2.32-0.1),
libbsd0 (= 0.9.1-1),
libbz2-1.0 (= 1.0.6-8.1),
libc-bin (= 2.27-3),
libc-dev-bin (= 2.27-3),
libc6 (= 2.27-3),
libc6-dev (= 2.27-3),
libcap-ng0 (= 0.7.9-1),
libcc1-0 (= 8.1.0-6),
libcilkrts5 (= 7.3.0-26+really21.0~reproducible0),
libcroco3 (= 0.6.12-2),
libdb5.3 (= 5.3.28-13.1+b1),
libdebconfclient0 (= 0.243),
libdpkg-perl (= 1.19.0.5.0~reproducible1),
libelf1 (= 0.170-0.4),
libfdisk1 (= 2.32-0.1),
libffi6 (= 3.2.1-8),
libfile-stripnondeterminism-perl (= 0.042-1),
libfreetype6 (= 2.8.1-2),
libgcc-7-dev (= 7.3.0-26+really21.0~reproducible0),
libgcc1 (= 1:8.1.0-6),
libgcrypt20 (= 1.8.3-1),
libgdbm-compat4 (= 1.14.1-6+b1),
libgdbm5 (= 1.14.1-6+b1),
libglib2.0-0 (= 2.56.1-2),
libgmp10 (= 2:6.1.2+dfsg-3),
libgomp1 (= 8.1.0-6),
libgpg-error0 (= 1.31-1),
libgraphite2-3 (= 1.3.11-2),
libharfbuzz0b (= 1.7.6-1+b1),
libicu-le-hb0 (= 1.0.3+git161113-5),
libicu60 (= 60.2-6),
libisl19 (= 0.19-1),
libitm1 (= 8.1.0-6),
liblsan0 (= 8.1.0-6),
liblz4-1 (= 1.8.2-1),
liblzma5 (= 5.2.2-1.3),
libmagic-mgc (= 1:5.33-3),
libmagic1 (= 1:5.33-3),
libmount1 (= 2.32-0.1),
libmpc3 (= 1.1.0-1),
libmpfr6 (= 4.0.1-1),
libmpx2 (= 8.1.0-6),
libncurses6 (= 6.1+20180210-4),
libncursesw6 (= 6.1+20180210-4),
libpam-modules (= 1.1.8-3.7),
libpam-modules-bin (= 1.1.8-3.7),
libpam-runtime (= 1.1.8-3.7),
libpam0g (= 1.1.8-3.7),
libpcre16-3 (= 2:8.39-9),
libpcre3 (= 2:8.39-9),
libpcre3-dev (= 2:8.39-9),
libpcre32-3 (= 2:8.39-9),
libpcrecpp0v5 (= 2:8.39-9),
libperl5.26 (= 5.26.2-6),
libpipeline1 (= 1.5.0-1),
libpng16-16 (= 1.6.34-1),
libquadmath0 (= 8.1.0-6),
libseccomp2 (= 2.3.3-2),
libselinux1 (= 2.8-1),
libsigsegv2 (= 2.12-2),
libsmartcols1 (= 2.32-0.1),
libstdc++-7-dev (= 7.3.0-26+really21.0~reproducible0),
libstdc++6 (= 8.1.0-6),
libsystemd0 (= 238-5),
libtimedate-perl (= 2.3000-2),
libtinfo6 (= 6.1+20180210-4),
libtool (= 2.4.6-2.1),
libtsan0 (= 8.1.0-6),
libubsan0 (= 7.3.0-26+really21.0~reproducible0),
libudev1 (= 238-5),
libunistring2 (= 0.9.8-1),
libuuid1 (= 2.32-0.1),
libxml2 (= 2.9.4+dfsg1-7),
linux-libc-dev (= 4.16.12-1),
login (= 1:4.5-1),
m4 (= 1.4.18-1),
make (= 4.2.1-1),
man-db (= 2.8.3-2),
mawk (= 1.3.3-17+b3),
ncurses-base (= 6.1+20180210-4),
ncurses-bin (= 6.1+20180210-4),
patch (= 2.7.6-2),
perl (= 5.26.2-6),
perl-base (= 5.26.2-6),
perl-modules-5.26 (= 5.26.2-6),
pkg-config (= 0.29-4+b1),
po-debconf (= 1.0.20),
sed (= 4.4-2),
sysvinit-utils (= 2.88dsf-59.10),
tar (= 1.30+dfsg-2),
util-linux (= 2.32-0.1),
xz-utils (= 5.2.2-1.3),
zlib1g (= 1:1.2.11.dfsg-1)
Environment:
BUILD_PATH_PREFIX_MAP="hardlink_0.3.0=/build/hardlink-0.3.0/2nd"
DEB_BUILD_OPTIONS="buildinfo=+all parallel=16"
LANG="C"
LC_ALL="C"
SOURCE_DATE_EPOCH="1411647982"

View File

@@ -0,0 +1,34 @@
Format: 1.8
Date: Sat, 12 May 2014 12:57:02 +0200
Source: hardlink
Binary: hardlink
Architecture: source amd64
Version: 0.2.1
Distribution: unstable
Urgency: low
Maintainer: Julian Andres Klode <jak@debian.org>
Changed-By: Aptly Tester (don't use it) <test@aptly.info>
Description:
hardlink - Hardlinks multiple copies of the same file
Changes:
hardlink (0.2.1) unstable; urgency=low
.
* Update just to try it out :)
Checksums-Sha1:
d20d6820bfccf5e3a5b120eedabba96e71da60ff 703 hardlink_0.2.1.dsc
6e95b8cba450343ab4dc01902e521f29fbd87ac2 12516 hardlink_0.2.1.tar.gz
1ac0e962854dff46f14fa7943746660d3cad1679 12468 hardlink_0.2.1_amd64.deb
06c38a55e81907e573641d7f979f428583bd3165 4885 hardlink_0.2.1_amd64.buildinfo
be2b66e32b29ab654190e7ecb4cc31f48ec061cb 12084 hardlink_0.2.0_i386.deb
Checksums-Sha256:
19d08cfadd58aee05fd06aca261a873bafeb55cac58bf4916cc070f5821803e7 703 hardlink_0.2.1.dsc
4df0adce005526a1f0e1b38171ddb1f017faae9205f5b1c6dfb0fb4207767271 12516 hardlink_0.2.1.tar.gz
668399580590bf1ffcd9eb161b6e574751e15f71820c6e08245dac7c5111a0ee 12468 hardlink_0.2.1_amd64.deb
2a4905626b8664868b712a5b3d21f44c2665d17f9a4b67dc2e2bfd03f4ec54ee 4885 hardlink_0.2.1_amd64.buildinfo
a9d657d9413029e484c2a8c059c95a3e31eb1b47eca96455c1b9c330352293c9 12084 hardlink_0.2.0_i386.deb
Files:
b75fe0616f24deb28a3017c1dbae219a 703 utils optional hardlink_0.2.1.dsc
8e2caa4d82f228bac08dc9a38bc6edb3 12516 utils optional hardlink_0.2.1.tar.gz
2081e20b36c47f82811c25841cc0e41b 12468 utils optional hardlink_0.2.1_amd64.deb
9468a19700d038fa6cd10c5e42063083 12084 utils optional hardlink_0.2.0_i386.deb
490174686848eca6da4e5f79d899efe7 4885 utils optional hardlink_0.2.1_amd64.buildinfo

Binary file not shown.

View File

@@ -176,6 +176,38 @@ class ReposAPITestAddFile(APITest):
self.check_not_exists("upload/" + d)
class ReposAPITestInclude(APITest):
"""
POST /api/repos/:name/include/:dir, GET /api/repos/:name/packages
"""
def check(self):
repo_name = self.random_name()
self.check_equal(self.post("/api/repos", json={"Name": repo_name, "Comment": "fun repo"}).status_code, 201)
d = self.random_name()
resp = self.upload("/api/files/" + d, "hardlink_0.2.1_amd64.changes",
"hardlink_0.2.1.dsc", "hardlink_0.2.1.tar.gz",
"hardlink_0.2.1_amd64.deb", directory='changes')
self.check_equal(resp.status_code, 200)
resp = self.post("/api/repos/" + repo_name + "/include/" + d, params={"ignoreSignature": 1})
self.check_equal(resp.status_code, 200)
self.check_equal(resp.json(), {
u'FailedFiles': [],
u'Report': {
u'Added': [u'hardlink_0.2.1_source added', 'hardlink_0.2.1_amd64 added'],
u'Removed': [],
u'Warnings': []}})
self.check_equal(
sorted(self.get("/api/repos/" + repo_name + "/packages").json()),
[u'Pamd64 hardlink 0.2.1 daf8fcecbf8210ad', u'Psource hardlink 0.2.1 8f72df429d7166e5']
)
self.check_not_exists("upload/" + d)
class ReposAPITestShowQuery(APITest):
"""
GET /api/repos/:name/packages?q=query