mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-06-01 04:40:38 +00:00
Compare commits
64 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 28e050c14e | |||
| 8fb399026d | |||
| e15f23962a | |||
| 81af5882b9 | |||
| e554d8befa | |||
| 17c564358a | |||
| 2e4c1c491e | |||
| e7230d9ee6 | |||
| 0f1074a721 | |||
| 17ed34fdaa | |||
| 17b320eac4 | |||
| e3a71c81e1 | |||
| bf900deb4b | |||
| 142387311b | |||
| 68fbb0cbb9 | |||
| 835da9cb3c | |||
| 7cd0d394d4 | |||
| 2040be2f8a | |||
| 1957c811e8 | |||
| 2dae9b01a1 | |||
| 9a34b4ff1f | |||
| d218159455 | |||
| 8be6911238 | |||
| 20a7c5ae2d | |||
| e161313efa | |||
| 7192049c16 | |||
| ee71b93669 | |||
| 43ee735aa4 | |||
| da5b0c9a66 | |||
| e1dbab6988 | |||
| bcdfb7d99a | |||
| ac85a0897a | |||
| 9a4543500c | |||
| b0f9a4a419 | |||
| 71ea2be6c1 | |||
| b717caeda4 | |||
| fcc283bdb1 | |||
| d3d41dd1c9 | |||
| c72ef05a2a | |||
| a1e360b07b | |||
| 90bba977d7 | |||
| dc248c5603 | |||
| f007465d18 | |||
| 869e83713d | |||
| 7b9e3429fd | |||
| 5b75dbc481 | |||
| d96839f99d | |||
| 8b2920d5dd | |||
| 4240b134e6 | |||
| 1d31a5c25f | |||
| 05a42f4cba | |||
| 2cbb486f6b | |||
| d0ff11390b | |||
| b5d025f141 | |||
| 3c7a2281b2 | |||
| be3ad21fbe | |||
| 5301e8a341 | |||
| 49eed59238 | |||
| 3e78240b39 | |||
| 10bbefeb25 | |||
| 35eac72226 | |||
| 5371f94b7a | |||
| 53adf39d89 | |||
| bc7972ff68 |
@@ -1,10 +1,10 @@
|
|||||||
gom 'code.google.com/p/go-uuid/uuid', :commit => '5fac954758f5'
|
gom 'code.google.com/p/go-uuid/uuid', :commit => '5fac954758f5'
|
||||||
gom 'code.google.com/p/go.crypto/ssh/terminal', :commit => '7aa593ce8cea'
|
gom 'code.google.com/p/go.crypto/ssh/terminal', :commit => '7aa593ce8cea'
|
||||||
gom 'code.google.com/p/gographviz', :commit => '212766062629'
|
gom 'code.google.com/p/gographviz', :commit => '454bc64fdfa2'
|
||||||
gom 'code.google.com/p/snappy-go/snappy', :commit => '12e4b4183793'
|
gom 'code.google.com/p/snappy-go/snappy', :commit => '12e4b4183793'
|
||||||
gom 'github.com/cheggaaa/pb', :commit => '74be7a1388046f374ac36e93d46f5d56e856f827'
|
gom 'github.com/cheggaaa/pb', :commit => '74be7a1388046f374ac36e93d46f5d56e856f827'
|
||||||
gom 'github.com/smira/commander'
|
gom 'github.com/smira/commander', :commit => 'f408b00e68d5d6e21b9f18bd310978dafc604e47'
|
||||||
gom 'github.com/smira/flag'
|
gom 'github.com/smira/flag', :commit => '0d0aac2addb39050f45e92c5a6252926096dc841'
|
||||||
gom 'github.com/mkrautz/goar', :commit => '36eb5f3452b1283a211fa35bc00c646fd0db5c4b'
|
gom 'github.com/mkrautz/goar', :commit => '36eb5f3452b1283a211fa35bc00c646fd0db5c4b'
|
||||||
gom 'github.com/syndtr/goleveldb/leveldb', :commit => 'ff3719c6816e2cd194f05058452d660608e178ac'
|
gom 'github.com/syndtr/goleveldb/leveldb', :commit => 'ff3719c6816e2cd194f05058452d660608e178ac'
|
||||||
gom 'github.com/ugorji/go/codec', :commit => '71c2886f5a673a35f909803f38ece5810165097b'
|
gom 'github.com/ugorji/go/codec', :commit => '71c2886f5a673a35f909803f38ece5810165097b'
|
||||||
|
|||||||
@@ -72,4 +72,16 @@ package:
|
|||||||
-f -m "Andrey Smirnov <me@smira.ru>" --description="Debian repository management tool" -C root/ .
|
-f -m "Andrey Smirnov <me@smira.ru>" --description="Debian repository management tool" -C root/ .
|
||||||
mv aptly_$(VERSION)_*.deb ~
|
mv aptly_$(VERSION)_*.deb ~
|
||||||
|
|
||||||
|
src-package:
|
||||||
|
rm -rf aptly-$(VERSION)
|
||||||
|
mkdir -p aptly-$(VERSION)/src/github.com/smira/aptly/
|
||||||
|
cd aptly-$(VERSION)/src/github.com/smira/ && git clone https://github.com/smira/aptly && cd aptly && git checkout v$(VERSION)
|
||||||
|
cd aptly-$(VERSION)/src/github.com/smira/aptly && gom -production install
|
||||||
|
cd aptly-$(VERSION)/src/github.com/smira/aptly && find . -name .git -print | xargs rm -rf
|
||||||
|
cd aptly-$(VERSION)/src/github.com/smira/aptly && find . -name .bzr -print | xargs rm -rf
|
||||||
|
cd aptly-$(VERSION)/src/github.com/smira/aptly && find . -name .hg -print | xargs rm -rf
|
||||||
|
rm -rf aptly-$(VERSION)/src/github.com/smira/aptly/_vendor/{pkg,bin}
|
||||||
|
tar cyf aptly-$(VERSION)-src.tar.bz2 aptly-$(VERSION)
|
||||||
|
rm -rf aptly-$(VERSION)
|
||||||
|
|
||||||
.PHONY: coverage.out
|
.PHONY: coverage.out
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
package aptly
|
package aptly
|
||||||
|
|
||||||
// Version of aptly
|
// Version of aptly
|
||||||
const Version = "0.5"
|
const Version = "0.6"
|
||||||
|
|
||||||
// Enable debugging features?
|
// Enable debugging features?
|
||||||
const EnableDebug = false
|
const EnableDebug = false
|
||||||
|
|||||||
+6
-1
@@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/smira/aptly/files"
|
"github.com/smira/aptly/files"
|
||||||
"github.com/smira/aptly/http"
|
"github.com/smira/aptly/http"
|
||||||
"github.com/smira/aptly/utils"
|
"github.com/smira/aptly/utils"
|
||||||
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -48,7 +49,11 @@ type FatalError struct {
|
|||||||
|
|
||||||
// Fatal panics and aborts execution with exit code 1
|
// Fatal panics and aborts execution with exit code 1
|
||||||
func Fatal(err error) {
|
func Fatal(err error) {
|
||||||
panic(&FatalError{ReturnCode: 1, Message: err.Error()})
|
returnCode := 1
|
||||||
|
if err == commander.ErrFlagError || err == commander.ErrCommandError {
|
||||||
|
returnCode = 2
|
||||||
|
}
|
||||||
|
panic(&FatalError{ReturnCode: returnCode, Message: err.Error()})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config loads and returns current configuration
|
// Config loads and returns current configuration
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ func aptlyDbCleanup(cmd *commander.Command, args []string) error {
|
|||||||
|
|
||||||
if len(args) != 0 {
|
if len(args) != 0 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
// collect information about references packages...
|
// collect information about references packages...
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ func aptlyDbRecover(cmd *commander.Command, args []string) error {
|
|||||||
|
|
||||||
if len(args) != 0 {
|
if len(args) != 0 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
context.Progress().Printf("Recovering database...\n")
|
context.Progress().Printf("Recovering database...\n")
|
||||||
|
|||||||
+22
-18
@@ -13,14 +13,15 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func graphvizEscape(s string) string {
|
|
||||||
return fmt.Sprintf("\"%s\"", strings.Replace(s, "\"", "\\\"", 0))
|
|
||||||
}
|
|
||||||
|
|
||||||
func aptlyGraph(cmd *commander.Command, args []string) error {
|
func aptlyGraph(cmd *commander.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
graph := gographviz.NewGraph()
|
if len(args) != 0 {
|
||||||
|
cmd.Usage()
|
||||||
|
return commander.ErrCommandError
|
||||||
|
}
|
||||||
|
|
||||||
|
graph := gographviz.NewEscape()
|
||||||
graph.SetDir(true)
|
graph.SetDir(true)
|
||||||
graph.SetName("aptly")
|
graph.SetName("aptly")
|
||||||
|
|
||||||
@@ -34,13 +35,13 @@ func aptlyGraph(cmd *commander.Command, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
graph.AddNode("aptly", graphvizEscape(repo.UUID), map[string]string{
|
graph.AddNode("aptly", repo.UUID, map[string]string{
|
||||||
"shape": "Mrecord",
|
"shape": "Mrecord",
|
||||||
"style": "filled",
|
"style": "filled",
|
||||||
"fillcolor": "darkgoldenrod1",
|
"fillcolor": "darkgoldenrod1",
|
||||||
"label": graphvizEscape(fmt.Sprintf("{Mirror %s|url: %s|dist: %s|comp: %s|arch: %s|pkgs: %d}",
|
"label": fmt.Sprintf("{Mirror %s|url: %s|dist: %s|comp: %s|arch: %s|pkgs: %d}",
|
||||||
repo.Name, repo.ArchiveRoot, repo.Distribution, strings.Join(repo.Components, ", "),
|
repo.Name, repo.ArchiveRoot, repo.Distribution, strings.Join(repo.Components, ", "),
|
||||||
strings.Join(repo.Architectures, ", "), repo.NumPackages())),
|
strings.Join(repo.Architectures, ", "), repo.NumPackages()),
|
||||||
})
|
})
|
||||||
existingNodes[repo.UUID] = true
|
existingNodes[repo.UUID] = true
|
||||||
return nil
|
return nil
|
||||||
@@ -58,12 +59,12 @@ func aptlyGraph(cmd *commander.Command, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
graph.AddNode("aptly", graphvizEscape(repo.UUID), map[string]string{
|
graph.AddNode("aptly", repo.UUID, map[string]string{
|
||||||
"shape": "Mrecord",
|
"shape": "Mrecord",
|
||||||
"style": "filled",
|
"style": "filled",
|
||||||
"fillcolor": "mediumseagreen",
|
"fillcolor": "mediumseagreen",
|
||||||
"label": graphvizEscape(fmt.Sprintf("{Repo %s|comment: %s|pkgs: %d}",
|
"label": fmt.Sprintf("{Repo %s|comment: %s|pkgs: %d}",
|
||||||
repo.Name, repo.Comment, repo.NumPackages())),
|
repo.Name, repo.Comment, repo.NumPackages()),
|
||||||
})
|
})
|
||||||
existingNodes[repo.UUID] = true
|
existingNodes[repo.UUID] = true
|
||||||
return nil
|
return nil
|
||||||
@@ -91,18 +92,18 @@ func aptlyGraph(cmd *commander.Command, args []string) error {
|
|||||||
description = "Snapshot from repo"
|
description = "Snapshot from repo"
|
||||||
}
|
}
|
||||||
|
|
||||||
graph.AddNode("aptly", graphvizEscape(snapshot.UUID), map[string]string{
|
graph.AddNode("aptly", snapshot.UUID, map[string]string{
|
||||||
"shape": "Mrecord",
|
"shape": "Mrecord",
|
||||||
"style": "filled",
|
"style": "filled",
|
||||||
"fillcolor": "cadetblue1",
|
"fillcolor": "cadetblue1",
|
||||||
"label": graphvizEscape(fmt.Sprintf("{Snapshot %s|%s|pkgs: %d}", snapshot.Name, description, snapshot.NumPackages())),
|
"label": fmt.Sprintf("{Snapshot %s|%s|pkgs: %d}", snapshot.Name, description, snapshot.NumPackages()),
|
||||||
})
|
})
|
||||||
|
|
||||||
if snapshot.SourceKind == "repo" || snapshot.SourceKind == "local" || snapshot.SourceKind == "snapshot" {
|
if snapshot.SourceKind == "repo" || snapshot.SourceKind == "local" || snapshot.SourceKind == "snapshot" {
|
||||||
for _, uuid := range snapshot.SourceIDs {
|
for _, uuid := range snapshot.SourceIDs {
|
||||||
_, exists := existingNodes[uuid]
|
_, exists := existingNodes[uuid]
|
||||||
if exists {
|
if exists {
|
||||||
graph.AddEdge(graphvizEscape(uuid), "", graphvizEscape(snapshot.UUID), "", true, nil)
|
graph.AddEdge(uuid, snapshot.UUID, true, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,16 +117,19 @@ func aptlyGraph(cmd *commander.Command, args []string) error {
|
|||||||
fmt.Printf("Loading published repos...\n")
|
fmt.Printf("Loading published repos...\n")
|
||||||
|
|
||||||
context.CollectionFactory().PublishedRepoCollection().ForEach(func(repo *deb.PublishedRepo) error {
|
context.CollectionFactory().PublishedRepoCollection().ForEach(func(repo *deb.PublishedRepo) error {
|
||||||
graph.AddNode("aptly", graphvizEscape(repo.UUID), map[string]string{
|
graph.AddNode("aptly", repo.UUID, map[string]string{
|
||||||
"shape": "Mrecord",
|
"shape": "Mrecord",
|
||||||
"style": "filled",
|
"style": "filled",
|
||||||
"fillcolor": "darkolivegreen1",
|
"fillcolor": "darkolivegreen1",
|
||||||
"label": graphvizEscape(fmt.Sprintf("{Published %s/%s|comp: %s|arch: %s}", repo.Prefix, repo.Distribution, repo.Component, strings.Join(repo.Architectures, ", "))),
|
"label": fmt.Sprintf("{Published %s/%s|comp: %s|arch: %s}", repo.Prefix, repo.Distribution,
|
||||||
|
strings.Join(repo.Components(), " "), strings.Join(repo.Architectures, ", ")),
|
||||||
})
|
})
|
||||||
|
|
||||||
_, exists := existingNodes[repo.SourceUUID]
|
for _, uuid := range repo.Sources {
|
||||||
|
_, exists := existingNodes[uuid]
|
||||||
if exists {
|
if exists {
|
||||||
graph.AddEdge(graphvizEscape(repo.SourceUUID), "", graphvizEscape(repo.UUID), "", true, nil)
|
graph.AddEdge(uuid, repo.UUID, true, nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ func aptlyMirrorCreate(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if !(len(args) == 2 && strings.HasPrefix(args[1], "ppa:") || len(args) >= 3) {
|
if !(len(args) == 2 && strings.HasPrefix(args[1], "ppa:") || len(args) >= 3) {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
downloadSources := context.Config().DownloadSourcePackages || context.flags.Lookup("with-sources").Value.Get().(bool)
|
downloadSources := context.Config().DownloadSourcePackages || context.flags.Lookup("with-sources").Value.Get().(bool)
|
||||||
@@ -63,7 +63,8 @@ func makeCmdMirrorCreate() *commander.Command {
|
|||||||
Short: "create new mirror",
|
Short: "create new mirror",
|
||||||
Long: `
|
Long: `
|
||||||
Creates mirror <name> of remote repository, aptly supports both regular and flat Debian repositories exported
|
Creates mirror <name> of remote repository, aptly supports both regular and flat Debian repositories exported
|
||||||
via HTTP. aptly would try download Release file from remote repository and verify its' signature.
|
via HTTP. aptly would try download Release file from remote repository and verify its' signature. Command
|
||||||
|
line format resembles apt utlitily sources.list(5).
|
||||||
|
|
||||||
PPA urls could specified in short format:
|
PPA urls could specified in short format:
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ func aptlyMirrorDrop(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
name := args[0]
|
name := args[0]
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ func aptlyMirrorList(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) != 0 {
|
if len(args) != 0 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
raw := cmd.Flag.Lookup("raw").Value.Get().(bool)
|
raw := cmd.Flag.Lookup("raw").Value.Get().(bool)
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ func aptlyMirrorShow(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
name := args[0]
|
name := args[0]
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ func aptlyMirrorUpdate(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
name := args[0]
|
name := args[0]
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ func aptlyPublishDrop(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) < 1 || len(args) > 2 {
|
if len(args) < 1 || len(args) > 2 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
distribution := args[0]
|
distribution := args[0]
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ func aptlyPublishList(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) != 0 {
|
if len(args) != 0 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
raw := cmd.Flag.Lookup("raw").Value.Get().(bool)
|
raw := cmd.Flag.Lookup("raw").Value.Get().(bool)
|
||||||
|
|||||||
+7
-1
@@ -15,6 +15,12 @@ Command publishes current state of local repository ready to be consumed
|
|||||||
by apt tools. Published repostiories appear under rootDir/public directory.
|
by apt tools. Published repostiories appear under rootDir/public directory.
|
||||||
Valid GPG key is required for publishing.
|
Valid GPG key is required for publishing.
|
||||||
|
|
||||||
|
Multiple component repository could be published by specifying several
|
||||||
|
components split by commas via -component flag and multiple local
|
||||||
|
repositories as the arguments:
|
||||||
|
|
||||||
|
aptly publish repo -component=main,contrib repo-main repo-contrib
|
||||||
|
|
||||||
It is not recommended to publish local repositories directly unless the
|
It is not recommended to publish local repositories directly unless the
|
||||||
repository is for testing purposes and changes happen frequently. For
|
repository is for testing purposes and changes happen frequently. For
|
||||||
production usage please take snapshot of repository and publish it
|
production usage please take snapshot of repository and publish it
|
||||||
@@ -27,7 +33,7 @@ Example:
|
|||||||
Flag: *flag.NewFlagSet("aptly-publish-repo", flag.ExitOnError),
|
Flag: *flag.NewFlagSet("aptly-publish-repo", flag.ExitOnError),
|
||||||
}
|
}
|
||||||
cmd.Flag.String("distribution", "", "distribution name to publish")
|
cmd.Flag.String("distribution", "", "distribution name to publish")
|
||||||
cmd.Flag.String("component", "", "component name to publish")
|
cmd.Flag.String("component", "", "component name to publish (for multi-component publishing, separate components with commas)")
|
||||||
cmd.Flag.String("gpg-key", "", "GPG key ID to use when signing the release")
|
cmd.Flag.String("gpg-key", "", "GPG key ID to use when signing the release")
|
||||||
cmd.Flag.Var(&keyRingsFlag{}, "keyring", "GPG keyring to use (instead of default)")
|
cmd.Flag.Var(&keyRingsFlag{}, "keyring", "GPG keyring to use (instead of default)")
|
||||||
cmd.Flag.String("secret-keyring", "", "GPG secret keyring to use (instead of default)")
|
cmd.Flag.String("secret-keyring", "", "GPG secret keyring to use (instead of default)")
|
||||||
|
|||||||
+72
-20
@@ -11,27 +11,35 @@ import (
|
|||||||
|
|
||||||
func aptlyPublishSnapshotOrRepo(cmd *commander.Command, args []string) error {
|
func aptlyPublishSnapshotOrRepo(cmd *commander.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
if len(args) < 1 || len(args) > 2 {
|
|
||||||
|
components := strings.Split(context.flags.Lookup("component").Value.String(), ",")
|
||||||
|
|
||||||
|
if len(args) < len(components) || len(args) > len(components)+1 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
name := args[0]
|
|
||||||
|
|
||||||
var prefix string
|
var prefix string
|
||||||
if len(args) == 2 {
|
if len(args) == len(components)+1 {
|
||||||
prefix = args[1]
|
prefix = args[len(components)]
|
||||||
|
args = args[0 : len(args)-1]
|
||||||
} else {
|
} else {
|
||||||
prefix = ""
|
prefix = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
source interface{}
|
sources = []interface{}{}
|
||||||
message string
|
message string
|
||||||
)
|
)
|
||||||
|
|
||||||
if cmd.Name() == "snapshot" {
|
if cmd.Name() == "snapshot" {
|
||||||
var snapshot *deb.Snapshot
|
var (
|
||||||
|
snapshot *deb.Snapshot
|
||||||
|
emptyWarning = false
|
||||||
|
parts = []string{}
|
||||||
|
)
|
||||||
|
|
||||||
|
for _, name := range args {
|
||||||
snapshot, err = context.CollectionFactory().SnapshotCollection().ByName(name)
|
snapshot, err = context.CollectionFactory().SnapshotCollection().ByName(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to publish: %s", err)
|
return fmt.Errorf("unable to publish: %s", err)
|
||||||
@@ -42,10 +50,32 @@ func aptlyPublishSnapshotOrRepo(cmd *commander.Command, args []string) error {
|
|||||||
return fmt.Errorf("unable to publish: %s", err)
|
return fmt.Errorf("unable to publish: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
source = snapshot
|
sources = append(sources, snapshot)
|
||||||
message = fmt.Sprintf("Snapshot %s", snapshot.Name)
|
parts = append(parts, snapshot.Name)
|
||||||
|
|
||||||
|
if snapshot.NumPackages() == 0 {
|
||||||
|
emptyWarning = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(parts) == 1 {
|
||||||
|
message = fmt.Sprintf("Snapshot %s has", parts[0])
|
||||||
|
} else {
|
||||||
|
message = fmt.Sprintf("Snapshots %s have", strings.Join(parts, ", "))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if emptyWarning {
|
||||||
|
context.Progress().Printf("Warning: publishing from empty source, architectures list should be complete, it can't be changed after publishing (use -architectures flag)\n")
|
||||||
|
}
|
||||||
} else if cmd.Name() == "repo" {
|
} else if cmd.Name() == "repo" {
|
||||||
var localRepo *deb.LocalRepo
|
var (
|
||||||
|
localRepo *deb.LocalRepo
|
||||||
|
emptyWarning = false
|
||||||
|
parts = []string{}
|
||||||
|
)
|
||||||
|
|
||||||
|
for _, name := range args {
|
||||||
localRepo, err = context.CollectionFactory().LocalRepoCollection().ByName(name)
|
localRepo, err = context.CollectionFactory().LocalRepoCollection().ByName(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to publish: %s", err)
|
return fmt.Errorf("unable to publish: %s", err)
|
||||||
@@ -56,16 +86,31 @@ func aptlyPublishSnapshotOrRepo(cmd *commander.Command, args []string) error {
|
|||||||
return fmt.Errorf("unable to publish: %s", err)
|
return fmt.Errorf("unable to publish: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
source = localRepo
|
sources = append(sources, localRepo)
|
||||||
message = fmt.Sprintf("Local repo %s", localRepo.Name)
|
parts = append(parts, localRepo.Name)
|
||||||
|
|
||||||
|
if localRepo.NumPackages() == 0 {
|
||||||
|
emptyWarning = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(parts) == 1 {
|
||||||
|
message = fmt.Sprintf("Local repo %s has", parts[0])
|
||||||
|
} else {
|
||||||
|
message = fmt.Sprintf("Local repos %s have", strings.Join(parts, ", "))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if emptyWarning {
|
||||||
|
context.Progress().Printf("Warning: publishing from empty source, architectures list should be complete, it can't be changed after publishing (use -architectures flag)\n")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
panic("unknown command")
|
panic("unknown command")
|
||||||
}
|
}
|
||||||
|
|
||||||
component := context.flags.Lookup("component").Value.String()
|
|
||||||
distribution := context.flags.Lookup("distribution").Value.String()
|
distribution := context.flags.Lookup("distribution").Value.String()
|
||||||
|
|
||||||
published, err := deb.NewPublishedRepo(prefix, distribution, component, context.ArchitecturesList(), source, context.CollectionFactory())
|
published, err := deb.NewPublishedRepo(prefix, distribution, context.ArchitecturesList(), components, sources, context.CollectionFactory())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to publish: %s", err)
|
return fmt.Errorf("unable to publish: %s", err)
|
||||||
}
|
}
|
||||||
@@ -93,19 +138,20 @@ func aptlyPublishSnapshotOrRepo(cmd *commander.Command, args []string) error {
|
|||||||
return fmt.Errorf("unable to save to DB: %s", err)
|
return fmt.Errorf("unable to save to DB: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
prefix, component, distribution = published.Prefix, published.Component, published.Distribution
|
var repoComponents string
|
||||||
|
prefix, repoComponents, distribution = published.Prefix, strings.Join(published.Components(), " "), published.Distribution
|
||||||
if prefix == "." {
|
if prefix == "." {
|
||||||
prefix = ""
|
prefix = ""
|
||||||
} else if !strings.HasSuffix(prefix, "/") {
|
} else if !strings.HasSuffix(prefix, "/") {
|
||||||
prefix += "/"
|
prefix += "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
context.Progress().Printf("\n%s has been successfully published.\nPlease setup your webserver to serve directory '%s' with autoindexing.\n",
|
context.Progress().Printf("\n%s been successfully published.\nPlease setup your webserver to serve directory '%s' with autoindexing.\n",
|
||||||
message, context.PublishedStorage().PublicPath())
|
message, context.PublishedStorage().PublicPath())
|
||||||
context.Progress().Printf("Now you can add following line to apt sources:\n")
|
context.Progress().Printf("Now you can add following line to apt sources:\n")
|
||||||
context.Progress().Printf(" deb http://your-server/%s %s %s\n", prefix, distribution, component)
|
context.Progress().Printf(" deb http://your-server/%s %s %s\n", prefix, distribution, repoComponents)
|
||||||
if utils.StrSliceHasItem(published.Architectures, "source") {
|
if utils.StrSliceHasItem(published.Architectures, "source") {
|
||||||
context.Progress().Printf(" deb-src http://your-server/%s %s %s\n", prefix, distribution, component)
|
context.Progress().Printf(" deb-src http://your-server/%s %s %s\n", prefix, distribution, repoComponents)
|
||||||
}
|
}
|
||||||
context.Progress().Printf("Don't forget to add your GPG key to apt with apt-key.\n")
|
context.Progress().Printf("Don't forget to add your GPG key to apt with apt-key.\n")
|
||||||
context.Progress().Printf("\nYou can also use `aptly serve` to publish your repositories over HTTP quickly.\n")
|
context.Progress().Printf("\nYou can also use `aptly serve` to publish your repositories over HTTP quickly.\n")
|
||||||
@@ -123,6 +169,12 @@ Command publishes snapshot as Debian repository ready to be consumed
|
|||||||
by apt tools. Published repostiories appear under rootDir/public directory.
|
by apt tools. Published repostiories appear under rootDir/public directory.
|
||||||
Valid GPG key is required for publishing.
|
Valid GPG key is required for publishing.
|
||||||
|
|
||||||
|
Multiple component repository could be published by specifying several
|
||||||
|
components split by commas via -component flag and multiple snapshots
|
||||||
|
as the arguments:
|
||||||
|
|
||||||
|
aptly publish snapshot -component=main,contrib snap-main snap-contrib
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
$ aptly publish snapshot wheezy-main
|
$ aptly publish snapshot wheezy-main
|
||||||
@@ -130,7 +182,7 @@ Example:
|
|||||||
Flag: *flag.NewFlagSet("aptly-publish-snapshot", flag.ExitOnError),
|
Flag: *flag.NewFlagSet("aptly-publish-snapshot", flag.ExitOnError),
|
||||||
}
|
}
|
||||||
cmd.Flag.String("distribution", "", "distribution name to publish")
|
cmd.Flag.String("distribution", "", "distribution name to publish")
|
||||||
cmd.Flag.String("component", "", "component name to publish")
|
cmd.Flag.String("component", "", "component name to publish (for multi-component publishing, separate components with commas)")
|
||||||
cmd.Flag.String("gpg-key", "", "GPG key ID to use when signing the release")
|
cmd.Flag.String("gpg-key", "", "GPG key ID to use when signing the release")
|
||||||
cmd.Flag.Var(&keyRingsFlag{}, "keyring", "GPG keyring to use (instead of default)")
|
cmd.Flag.Var(&keyRingsFlag{}, "keyring", "GPG keyring to use (instead of default)")
|
||||||
cmd.Flag.String("secret-keyring", "", "GPG secret keyring to use (instead of default)")
|
cmd.Flag.String("secret-keyring", "", "GPG secret keyring to use (instead of default)")
|
||||||
|
|||||||
+42
-19
@@ -5,38 +5,32 @@ import (
|
|||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlyPublishSwitch(cmd *commander.Command, args []string) error {
|
func aptlyPublishSwitch(cmd *commander.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
if len(args) < 2 || len(args) > 3 {
|
|
||||||
|
components := strings.Split(context.flags.Lookup("component").Value.String(), ",")
|
||||||
|
|
||||||
|
if len(args) < len(components)+1 || len(args) > len(components)+2 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
distribution := args[0]
|
distribution := args[0]
|
||||||
prefix := "."
|
prefix := "."
|
||||||
|
|
||||||
var (
|
var (
|
||||||
name string
|
names []string
|
||||||
snapshot *deb.Snapshot
|
snapshot *deb.Snapshot
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(args) == 3 {
|
if len(args) == len(components)+2 {
|
||||||
prefix = args[1]
|
prefix = args[1]
|
||||||
name = args[2]
|
names = args[2:]
|
||||||
} else {
|
} else {
|
||||||
name = args[1]
|
names = args[1:]
|
||||||
}
|
|
||||||
|
|
||||||
snapshot, err = context.CollectionFactory().SnapshotCollection().ByName(name)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to switch: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = context.CollectionFactory().SnapshotCollection().LoadComplete(snapshot)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to switch: %s", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var published *deb.PublishedRepo
|
var published *deb.PublishedRepo
|
||||||
@@ -55,7 +49,28 @@ func aptlyPublishSwitch(cmd *commander.Command, args []string) error {
|
|||||||
return fmt.Errorf("unable to update: %s", err)
|
return fmt.Errorf("unable to update: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
published.UpdateSnapshot(snapshot)
|
publishedComponents := published.Components()
|
||||||
|
if len(components) == 1 && len(publishedComponents) == 1 && components[0] == "" {
|
||||||
|
components = publishedComponents
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(names) != len(components) {
|
||||||
|
return fmt.Errorf("mismatch in number of components (%d) and snapshots (%d)", len(components), len(names))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, component := range components {
|
||||||
|
snapshot, err = context.CollectionFactory().SnapshotCollection().ByName(names[i])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to switch: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = context.CollectionFactory().SnapshotCollection().LoadComplete(snapshot)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to switch: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
published.UpdateSnapshot(component, snapshot)
|
||||||
|
}
|
||||||
|
|
||||||
signer, err := getSigner(context.flags)
|
signer, err := getSigner(context.flags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -72,7 +87,7 @@ func aptlyPublishSwitch(cmd *commander.Command, args []string) error {
|
|||||||
return fmt.Errorf("unable to save to DB: %s", err)
|
return fmt.Errorf("unable to save to DB: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = context.CollectionFactory().PublishedRepoCollection().CleanupPrefixComponentFiles(published.Prefix, published.Component,
|
err = context.CollectionFactory().PublishedRepoCollection().CleanupPrefixComponentFiles(published.Prefix, components,
|
||||||
context.PublishedStorage(), context.CollectionFactory(), context.Progress())
|
context.PublishedStorage(), context.CollectionFactory(), context.Progress())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to update: %s", err)
|
return fmt.Errorf("unable to update: %s", err)
|
||||||
@@ -90,7 +105,14 @@ func makeCmdPublishSwitch() *commander.Command {
|
|||||||
Short: "update published repository by switching to new snapshot",
|
Short: "update published repository by switching to new snapshot",
|
||||||
Long: `
|
Long: `
|
||||||
Command switches in-place published repository with new snapshot contents. All
|
Command switches in-place published repository with new snapshot contents. All
|
||||||
publishing parameters are preserved (architecture list, distribution, component).
|
publishing parameters are preserved (architecture list, distribution,
|
||||||
|
component).
|
||||||
|
|
||||||
|
For multiple component repositories, flag -component should be given with
|
||||||
|
list of components to update. Corresponding snapshots should be given in the
|
||||||
|
same order, e.g.:
|
||||||
|
|
||||||
|
aptly publish update -component=main,contrib wheezy wh-main wh-contrib
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@@ -102,6 +124,7 @@ Example:
|
|||||||
cmd.Flag.Var(&keyRingsFlag{}, "keyring", "GPG keyring to use (instead of default)")
|
cmd.Flag.Var(&keyRingsFlag{}, "keyring", "GPG keyring to use (instead of default)")
|
||||||
cmd.Flag.String("secret-keyring", "", "GPG secret keyring to use (instead of default)")
|
cmd.Flag.String("secret-keyring", "", "GPG secret keyring to use (instead of default)")
|
||||||
cmd.Flag.Bool("skip-signing", false, "don't sign Release files with GPG")
|
cmd.Flag.Bool("skip-signing", false, "don't sign Release files with GPG")
|
||||||
|
cmd.Flag.String("component", "", "component names to update (for multi-component publishing, separate components with commas)")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ func aptlyPublishUpdate(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) < 1 || len(args) > 2 {
|
if len(args) < 1 || len(args) > 2 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
distribution := args[0]
|
distribution := args[0]
|
||||||
@@ -37,7 +37,10 @@ func aptlyPublishUpdate(cmd *commander.Command, args []string) error {
|
|||||||
return fmt.Errorf("unable to update: %s", err)
|
return fmt.Errorf("unable to update: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
published.UpdateLocalRepo()
|
components := published.Components()
|
||||||
|
for _, component := range components {
|
||||||
|
published.UpdateLocalRepo(component)
|
||||||
|
}
|
||||||
|
|
||||||
signer, err := getSigner(context.flags)
|
signer, err := getSigner(context.flags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -54,7 +57,7 @@ func aptlyPublishUpdate(cmd *commander.Command, args []string) error {
|
|||||||
return fmt.Errorf("unable to save to DB: %s", err)
|
return fmt.Errorf("unable to save to DB: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = context.CollectionFactory().PublishedRepoCollection().CleanupPrefixComponentFiles(published.Prefix, published.Component,
|
err = context.CollectionFactory().PublishedRepoCollection().CleanupPrefixComponentFiles(published.Prefix, components,
|
||||||
context.PublishedStorage(), context.CollectionFactory(), context.Progress())
|
context.PublishedStorage(), context.CollectionFactory(), context.Progress())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to update: %s", err)
|
return fmt.Errorf("unable to update: %s", err)
|
||||||
@@ -76,6 +79,9 @@ and <prefix> should be occupied with local repository published
|
|||||||
using command aptly publish repo. Update happens in-place with
|
using command aptly publish repo. Update happens in-place with
|
||||||
minimum possible downtime for published repository.
|
minimum possible downtime for published repository.
|
||||||
|
|
||||||
|
For multiple component published repositories, all local repositories
|
||||||
|
are updated.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
$ aptly publish update wheezy ppa
|
$ aptly publish update wheezy ppa
|
||||||
|
|||||||
+18
-1
@@ -16,7 +16,7 @@ func aptlyRepoAdd(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
name := args[0]
|
name := args[0]
|
||||||
@@ -41,11 +41,13 @@ func aptlyRepoAdd(cmd *commander.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
packageFiles := []string{}
|
packageFiles := []string{}
|
||||||
|
failedFiles := []string{}
|
||||||
|
|
||||||
for _, location := range args[1:] {
|
for _, location := range args[1:] {
|
||||||
info, err2 := os.Stat(location)
|
info, err2 := os.Stat(location)
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
context.Progress().ColoredPrintf("@y[!]@| @!Unable to process %s: %s@|", location, err2)
|
context.Progress().ColoredPrintf("@y[!]@| @!Unable to process %s: %s@|", location, err2)
|
||||||
|
failedFiles = append(failedFiles, location)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
@@ -68,6 +70,7 @@ func aptlyRepoAdd(cmd *commander.Command, args []string) error {
|
|||||||
packageFiles = append(packageFiles, location)
|
packageFiles = append(packageFiles, location)
|
||||||
} else {
|
} else {
|
||||||
context.Progress().ColoredPrintf("@y[!]@| @!Unknwon file extenstion: %s@|", location)
|
context.Progress().ColoredPrintf("@y[!]@| @!Unknwon file extenstion: %s@|", location)
|
||||||
|
failedFiles = append(failedFiles, location)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,6 +103,7 @@ func aptlyRepoAdd(cmd *commander.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
context.Progress().ColoredPrintf("@y[!]@| @!Unable to read file %s: %s@|", file, err)
|
context.Progress().ColoredPrintf("@y[!]@| @!Unable to read file %s: %s@|", file, err)
|
||||||
|
failedFiles = append(failedFiles, file)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,6 +122,7 @@ func aptlyRepoAdd(cmd *commander.Command, args []string) error {
|
|||||||
err = context.PackagePool().Import(file, checksums.MD5)
|
err = context.PackagePool().Import(file, checksums.MD5)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
context.Progress().ColoredPrintf("@y[!]@| @!Unable to import file %s into pool: %s@|", file, err)
|
context.Progress().ColoredPrintf("@y[!]@| @!Unable to import file %s into pool: %s@|", file, err)
|
||||||
|
failedFiles = append(failedFiles, file)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,6 +137,7 @@ func aptlyRepoAdd(cmd *commander.Command, args []string) error {
|
|||||||
err = context.PackagePool().Import(sourceFile, f.Checksums.MD5)
|
err = context.PackagePool().Import(sourceFile, f.Checksums.MD5)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
context.Progress().ColoredPrintf("@y[!]@| @!Unable to import file %s into pool: %s@|", sourceFile, err)
|
context.Progress().ColoredPrintf("@y[!]@| @!Unable to import file %s into pool: %s@|", sourceFile, err)
|
||||||
|
failedFiles = append(failedFiles, file)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,12 +151,14 @@ func aptlyRepoAdd(cmd *commander.Command, args []string) error {
|
|||||||
err = context.CollectionFactory().PackageCollection().Update(p)
|
err = context.CollectionFactory().PackageCollection().Update(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
context.Progress().ColoredPrintf("@y[!]@| @!Unable to save package %s: %s@|", p, err)
|
context.Progress().ColoredPrintf("@y[!]@| @!Unable to save package %s: %s@|", p, err)
|
||||||
|
failedFiles = append(failedFiles, file)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
err = list.Add(p)
|
err = list.Add(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
context.Progress().ColoredPrintf("@y[!]@| @!Unable to add package to repo %s: %s@|", p, err)
|
context.Progress().ColoredPrintf("@y[!]@| @!Unable to add package to repo %s: %s@|", p, err)
|
||||||
|
failedFiles = append(failedFiles, file)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,6 +184,15 @@ func aptlyRepoAdd(cmd *commander.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(failedFiles) > 0 {
|
||||||
|
context.Progress().ColoredPrintf("@y[!]@| @!Some files were skipped due to errors:@|")
|
||||||
|
for _, file := range failedFiles {
|
||||||
|
context.Progress().ColoredPrintf(" %s", file)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("some files failed to be added")
|
||||||
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ func aptlyRepoCreate(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
repo := deb.NewLocalRepo(args[0], context.flags.Lookup("comment").Value.String())
|
repo := deb.NewLocalRepo(args[0], context.flags.Lookup("comment").Value.String())
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ func aptlyRepoDrop(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
name := args[0]
|
name := args[0]
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ func aptlyRepoEdit(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, err := context.CollectionFactory().LocalRepoCollection().ByName(args[0])
|
repo, err := context.CollectionFactory().LocalRepoCollection().ByName(args[0])
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ func aptlyRepoList(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) != 0 {
|
if len(args) != 0 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
raw := cmd.Flag.Lookup("raw").Value.Get().(bool)
|
raw := cmd.Flag.Lookup("raw").Value.Get().(bool)
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ func aptlyRepoMoveCopyImport(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) < 3 {
|
if len(args) < 3 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
command := cmd.Name()
|
command := cmd.Name()
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ func aptlyRepoRemove(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
name := args[0]
|
name := args[0]
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ func aptlyRepoShow(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
name := args[0]
|
name := args[0]
|
||||||
|
|||||||
+8
-2
@@ -10,11 +10,17 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlyServe(cmd *commander.Command, args []string) error {
|
func aptlyServe(cmd *commander.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
if len(args) != 0 {
|
||||||
|
cmd.Usage()
|
||||||
|
return commander.ErrCommandError
|
||||||
|
}
|
||||||
|
|
||||||
if context.CollectionFactory().PublishedRepoCollection().Len() == 0 {
|
if context.CollectionFactory().PublishedRepoCollection().Len() == 0 {
|
||||||
fmt.Printf("No published repositories, unable to serve.\n")
|
fmt.Printf("No published repositories, unable to serve.\n")
|
||||||
return nil
|
return nil
|
||||||
@@ -69,11 +75,11 @@ func aptlyServe(cmd *commander.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("# %s\ndeb http://%s:%s/%s %s %s\n",
|
fmt.Printf("# %s\ndeb http://%s:%s/%s %s %s\n",
|
||||||
repo, listenHost, listenPort, prefix, repo.Distribution, repo.Component)
|
repo, listenHost, listenPort, prefix, repo.Distribution, strings.Join(repo.Components(), " "))
|
||||||
|
|
||||||
if utils.StrSliceHasItem(repo.Architectures, "source") {
|
if utils.StrSliceHasItem(repo.Architectures, "source") {
|
||||||
fmt.Printf("deb-src http://%s:%s/%s %s %s\n",
|
fmt.Printf("deb-src http://%s:%s/%s %s %s\n",
|
||||||
listenHost, listenPort, prefix, repo.Distribution, repo.Component)
|
listenHost, listenPort, prefix, repo.Distribution, strings.Join(repo.Components(), " "))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ func aptlySnapshotCreate(cmd *commander.Command, args []string) error {
|
|||||||
snapshot = deb.NewSnapshotFromPackageList(snapshotName, nil, packageList, "Created as empty")
|
snapshot = deb.NewSnapshotFromPackageList(snapshotName, nil, packageList, "Created as empty")
|
||||||
} else {
|
} else {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
err = context.CollectionFactory().SnapshotCollection().Add(snapshot)
|
err = context.CollectionFactory().SnapshotCollection().Add(snapshot)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ func aptlySnapshotDiff(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) != 2 {
|
if len(args) != 2 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
onlyMatching := context.flags.Lookup("only-matching").Value.Get().(bool)
|
onlyMatching := context.flags.Lookup("only-matching").Value.Get().(bool)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ func aptlySnapshotDrop(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
name := args[0]
|
name := args[0]
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ func aptlySnapshotList(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) != 0 {
|
if len(args) != 0 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
raw := cmd.Flag.Lookup("raw").Value.Get().(bool)
|
raw := cmd.Flag.Lookup("raw").Value.Get().(bool)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ func aptlySnapshotMerge(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
sources := make([]*deb.Snapshot, len(args)-1)
|
sources := make([]*deb.Snapshot, len(args)-1)
|
||||||
@@ -29,10 +29,15 @@ func aptlySnapshotMerge(cmd *commander.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
latest := context.flags.Lookup("latest").Value.Get().(bool)
|
latest := context.flags.Lookup("latest").Value.Get().(bool)
|
||||||
overrideMatching := !latest
|
noRemove := context.flags.Lookup("no-remove").Value.Get().(bool)
|
||||||
|
|
||||||
|
if noRemove && latest {
|
||||||
|
return fmt.Errorf("-no-remove and -latest can't be specified together")
|
||||||
|
}
|
||||||
|
|
||||||
|
overrideMatching := !latest && !noRemove
|
||||||
|
|
||||||
result := sources[0].RefList()
|
result := sources[0].RefList()
|
||||||
|
|
||||||
for i := 1; i < len(sources); i++ {
|
for i := 1; i < len(sources); i++ {
|
||||||
result = result.Merge(sources[i].RefList(), overrideMatching)
|
result = result.Merge(sources[i].RefList(), overrideMatching)
|
||||||
}
|
}
|
||||||
@@ -79,6 +84,7 @@ Example:
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flag.Bool("latest", false, "use only the latest version of each package")
|
cmd.Flag.Bool("latest", false, "use only the latest version of each package")
|
||||||
|
cmd.Flag.Bool("no-remove", false, "don't remove duplicate arch/name packages")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ func aptlySnapshotPull(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) < 4 {
|
if len(args) < 4 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
noDeps := context.flags.Lookup("no-deps").Value.Get().(bool)
|
noDeps := context.flags.Lookup("no-deps").Value.Get().(bool)
|
||||||
@@ -86,7 +86,7 @@ func aptlySnapshotPull(cmd *commander.Command, args []string) error {
|
|||||||
|
|
||||||
// Perform pull
|
// Perform pull
|
||||||
for _, arch := range architecturesList {
|
for _, arch := range architecturesList {
|
||||||
dependencies := make([]deb.Dependency, len(initialDependencies), 128)
|
dependencies := make([]deb.Dependency, len(initialDependencies), 2*len(initialDependencies))
|
||||||
for i := range dependencies {
|
for i := range dependencies {
|
||||||
dependencies[i] = initialDependencies[i]
|
dependencies[i] = initialDependencies[i]
|
||||||
dependencies[i].Architecture = arch
|
dependencies[i].Architecture = arch
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ func aptlySnapshotShow(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
name := args[0]
|
name := args[0]
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ func aptlySnapshotVerify(cmd *commander.Command, args []string) error {
|
|||||||
var err error
|
var err error
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return err
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshots := make([]*deb.Snapshot, len(args))
|
snapshots := make([]*deb.Snapshot, len(args))
|
||||||
|
|||||||
@@ -7,6 +7,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func aptlyVersion(cmd *commander.Command, args []string) error {
|
func aptlyVersion(cmd *commander.Command, args []string) error {
|
||||||
|
if len(args) != 0 {
|
||||||
|
cmd.Usage()
|
||||||
|
return commander.ErrCommandError
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Printf("aptly version: %s\n", aptly.Version)
|
fmt.Printf("aptly version: %s\n", aptly.Version)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ import (
|
|||||||
type Stanza map[string]string
|
type Stanza map[string]string
|
||||||
|
|
||||||
// Canonical order of fields in stanza
|
// Canonical order of fields in stanza
|
||||||
var canocialOrder = []string{"Origin", "Label", "Suite", "Package", "Version", "Installed-Size", "Priority", "Section", "Maintainer",
|
var canocialOrder = []string{"Package", "Origin", "Label", "Suite", "Version", "Installed-Size", "Priority", "Section", "Maintainer",
|
||||||
"Architecture", "Codename", "Date", "Architectures", "Components", "Description", "MD5sum", "MD5Sum", "SHA1", "SHA256"}
|
"Architecture", "Codename", "Date", "Architectures", "Components", "Description", "MD5sum", "MD5Sum", "SHA1", "SHA256"}
|
||||||
|
|
||||||
// Copy returns copy of Stanza
|
// Copy returns copy of Stanza
|
||||||
|
|||||||
+4
-4
@@ -86,11 +86,11 @@ func NewPackageListFromRefList(reflist *PackageRefList, collection *PackageColle
|
|||||||
|
|
||||||
// Add appends package to package list, additionally checking for uniqueness
|
// Add appends package to package list, additionally checking for uniqueness
|
||||||
func (l *PackageList) Add(p *Package) error {
|
func (l *PackageList) Add(p *Package) error {
|
||||||
key := string(p.Key(""))
|
key := string(p.ShortKey(""))
|
||||||
existing, ok := l.packages[key]
|
existing, ok := l.packages[key]
|
||||||
if ok {
|
if ok {
|
||||||
if !existing.Equals(p) {
|
if !existing.Equals(p) {
|
||||||
return fmt.Errorf("conflict in package %s: %#v != %#v", p, existing, p)
|
return fmt.Errorf("conflict in package %s", p)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -137,7 +137,7 @@ func (l *PackageList) Append(pl *PackageList) error {
|
|||||||
existing, ok := l.packages[k]
|
existing, ok := l.packages[k]
|
||||||
if ok {
|
if ok {
|
||||||
if !existing.Equals(p) {
|
if !existing.Equals(p) {
|
||||||
return fmt.Errorf("conflict in package %s: %#v != %#v", p, existing, p)
|
return fmt.Errorf("conflict in package %s", p)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
l.packages[k] = p
|
l.packages[k] = p
|
||||||
@@ -149,7 +149,7 @@ func (l *PackageList) Append(pl *PackageList) error {
|
|||||||
|
|
||||||
// Remove removes package from the list, and updates index when required
|
// Remove removes package from the list, and updates index when required
|
||||||
func (l *PackageList) Remove(p *Package) {
|
func (l *PackageList) Remove(p *Package) {
|
||||||
delete(l.packages, string(p.Key("")))
|
delete(l.packages, string(p.ShortKey("")))
|
||||||
if l.indexed {
|
if l.indexed {
|
||||||
for _, provides := range p.Provides {
|
for _, provides := range p.Provides {
|
||||||
for i, pkg := range l.providesIndex[provides] {
|
for i, pkg := range l.providesIndex[provides] {
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ func (s *PackageListSuite) SetUpTest(c *C) {
|
|||||||
stanza["Package"] = "mars-invaders"
|
stanza["Package"] = "mars-invaders"
|
||||||
s.p3 = NewPackageFromControlFile(stanza)
|
s.p3 = NewPackageFromControlFile(stanza)
|
||||||
stanza = packageStanza.Copy()
|
stanza = packageStanza.Copy()
|
||||||
stanza["Size"] = "42"
|
stanza["Source"] = "unknown-planet"
|
||||||
s.p4 = NewPackageFromControlFile(stanza)
|
s.p4 = NewPackageFromControlFile(stanza)
|
||||||
stanza = packageStanza.Copy()
|
stanza = packageStanza.Copy()
|
||||||
stanza["Package"] = "lonely-strangers"
|
stanza["Package"] = "lonely-strangers"
|
||||||
|
|||||||
+16
-1
@@ -26,6 +26,8 @@ type Package struct {
|
|||||||
IsSource bool
|
IsSource bool
|
||||||
// Hash of files section
|
// Hash of files section
|
||||||
FilesHash uint64
|
FilesHash uint64
|
||||||
|
// Is this >= 0.6 package?
|
||||||
|
V06Plus bool
|
||||||
// Offload fields
|
// Offload fields
|
||||||
deps *PackageDependencies
|
deps *PackageDependencies
|
||||||
extra *Stanza
|
extra *Stanza
|
||||||
@@ -41,6 +43,7 @@ func NewPackageFromControlFile(input Stanza) *Package {
|
|||||||
Version: input["Version"],
|
Version: input["Version"],
|
||||||
Architecture: input["Architecture"],
|
Architecture: input["Architecture"],
|
||||||
Source: input["Source"],
|
Source: input["Source"],
|
||||||
|
V06Plus: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(input, "Package")
|
delete(input, "Package")
|
||||||
@@ -89,6 +92,7 @@ func NewSourcePackageFromControlFile(input Stanza) (*Package, error) {
|
|||||||
Version: input["Version"],
|
Version: input["Version"],
|
||||||
Architecture: "source",
|
Architecture: "source",
|
||||||
SourceArchitecture: input["Architecture"],
|
SourceArchitecture: input["Architecture"],
|
||||||
|
V06Plus: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(input, "Package")
|
delete(input, "Package")
|
||||||
@@ -167,7 +171,16 @@ func NewSourcePackageFromControlFile(input Stanza) (*Package, error) {
|
|||||||
|
|
||||||
// Key returns unique key identifying package
|
// Key returns unique key identifying package
|
||||||
func (p *Package) Key(prefix string) []byte {
|
func (p *Package) Key(prefix string) []byte {
|
||||||
return []byte(prefix + "P" + p.Architecture + " " + p.Name + " " + p.Version)
|
if p.V06Plus {
|
||||||
|
return []byte(fmt.Sprintf("%sP%s %s %s %08x", prefix, p.Architecture, p.Name, p.Version, p.FilesHash))
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.ShortKey(prefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShortKey returns key for the package that should be unique in one list
|
||||||
|
func (p *Package) ShortKey(prefix string) []byte {
|
||||||
|
return []byte(fmt.Sprintf("%sP%s %s %s", prefix, p.Architecture, p.Name, p.Version))
|
||||||
}
|
}
|
||||||
|
|
||||||
// String creates readable representation
|
// String creates readable representation
|
||||||
@@ -411,6 +424,8 @@ func (p *Package) PoolDirectory() (string, error) {
|
|||||||
source := p.Source
|
source := p.Source
|
||||||
if source == "" {
|
if source == "" {
|
||||||
source = p.Name
|
source = p.Name
|
||||||
|
} else if pos := strings.Index(source, "("); pos != -1 {
|
||||||
|
source = strings.TrimSpace(source[:pos])
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(source) < 2 {
|
if len(source) < 2 {
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ func (collection *PackageCollection) ByKey(key []byte) (*Package, error) {
|
|||||||
p.UpdateFiles(PackageFiles(oldp.Files))
|
p.UpdateFiles(PackageFiles(oldp.Files))
|
||||||
|
|
||||||
// Save in new format
|
// Save in new format
|
||||||
err = collection.internalUpdate(p)
|
err = collection.Update(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -156,25 +156,6 @@ func (collection *PackageCollection) loadFiles(p *Package) *PackageFiles {
|
|||||||
|
|
||||||
// Update adds or updates information about package in DB checking for conficts first
|
// Update adds or updates information about package in DB checking for conficts first
|
||||||
func (collection *PackageCollection) Update(p *Package) error {
|
func (collection *PackageCollection) Update(p *Package) error {
|
||||||
existing, err := collection.ByKey(p.Key(""))
|
|
||||||
if err == nil {
|
|
||||||
// if .Files is different, consider to be conflict
|
|
||||||
if p.FilesHash != existing.FilesHash {
|
|
||||||
return fmt.Errorf("unable to save: %s, conflict with existing packge", p)
|
|
||||||
}
|
|
||||||
// ok, .Files are the same, but maybe some meta-data is different, proceed to saving
|
|
||||||
} else {
|
|
||||||
if err != database.ErrNotFound {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// ok, package doesn't exist yet
|
|
||||||
}
|
|
||||||
|
|
||||||
return collection.internalUpdate(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// internalUpdate updates information in DB about package and offloaded fields
|
|
||||||
func (collection *PackageCollection) internalUpdate(p *Package) error {
|
|
||||||
encoder := codec.NewEncoder(&collection.encodeBuffer, &codec.MsgpackHandle{})
|
encoder := codec.NewEncoder(&collection.encodeBuffer, &codec.MsgpackHandle{})
|
||||||
|
|
||||||
collection.encodeBuffer.Reset()
|
collection.encodeBuffer.Reset()
|
||||||
|
|||||||
@@ -48,20 +48,6 @@ func (s *PackageCollectionSuite) TestUpdate(c *C) {
|
|||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(res.Equals(s.p), Equals, false)
|
c.Assert(res.Equals(s.p), Equals, false)
|
||||||
c.Assert(res.Equals(p2), Equals, true)
|
c.Assert(res.Equals(p2), Equals, true)
|
||||||
|
|
||||||
// change file info
|
|
||||||
p2 = NewPackageFromControlFile(packageStanza.Copy())
|
|
||||||
p2.UpdateFiles(nil)
|
|
||||||
res, err = s.collection.ByKey(p2.Key(""))
|
|
||||||
err = s.collection.Update(p2)
|
|
||||||
c.Assert(err, ErrorMatches, ".*conflict with existing packge")
|
|
||||||
p2 = NewPackageFromControlFile(packageStanza.Copy())
|
|
||||||
files := p2.Files()
|
|
||||||
files[0].Checksums.MD5 = "abcdef"
|
|
||||||
p2.UpdateFiles(files)
|
|
||||||
res, err = s.collection.ByKey(p2.Key(""))
|
|
||||||
err = s.collection.Update(p2)
|
|
||||||
c.Assert(err, ErrorMatches, ".*conflict with existing packge")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PackageCollectionSuite) TestByKey(c *C) {
|
func (s *PackageCollectionSuite) TestByKey(c *C) {
|
||||||
|
|||||||
@@ -87,10 +87,21 @@ func (s *PackageSuite) TestWithProvides(c *C) {
|
|||||||
func (s *PackageSuite) TestKey(c *C) {
|
func (s *PackageSuite) TestKey(c *C) {
|
||||||
p := NewPackageFromControlFile(s.stanza)
|
p := NewPackageFromControlFile(s.stanza)
|
||||||
|
|
||||||
|
c.Check(p.Key(""), DeepEquals, []byte("Pi386 alien-arena-common 7.40-2 c8901eedd79ac51b"))
|
||||||
|
c.Check(p.Key("xD"), DeepEquals, []byte("xDPi386 alien-arena-common 7.40-2 c8901eedd79ac51b"))
|
||||||
|
|
||||||
|
p.V06Plus = false
|
||||||
c.Check(p.Key(""), DeepEquals, []byte("Pi386 alien-arena-common 7.40-2"))
|
c.Check(p.Key(""), DeepEquals, []byte("Pi386 alien-arena-common 7.40-2"))
|
||||||
c.Check(p.Key("xD"), DeepEquals, []byte("xDPi386 alien-arena-common 7.40-2"))
|
c.Check(p.Key("xD"), DeepEquals, []byte("xDPi386 alien-arena-common 7.40-2"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *PackageSuite) TestShortKey(c *C) {
|
||||||
|
p := NewPackageFromControlFile(s.stanza)
|
||||||
|
|
||||||
|
c.Check(p.ShortKey(""), DeepEquals, []byte("Pi386 alien-arena-common 7.40-2"))
|
||||||
|
c.Check(p.ShortKey("xD"), DeepEquals, []byte("xDPi386 alien-arena-common 7.40-2"))
|
||||||
|
}
|
||||||
|
|
||||||
func (s *PackageSuite) TestStanza(c *C) {
|
func (s *PackageSuite) TestStanza(c *C) {
|
||||||
p := NewPackageFromControlFile(s.stanza.Copy())
|
p := NewPackageFromControlFile(s.stanza.Copy())
|
||||||
stanza := p.Stanza()
|
stanza := p.Stanza()
|
||||||
@@ -230,6 +241,12 @@ func (s *PackageSuite) TestPoolDirectory(c *C) {
|
|||||||
c.Check(err, IsNil)
|
c.Check(err, IsNil)
|
||||||
c.Check(dir, Equals, "liba/libarena")
|
c.Check(dir, Equals, "liba/libarena")
|
||||||
|
|
||||||
|
p = NewPackageFromControlFile(packageStanza.Copy())
|
||||||
|
p.Source = "gcc-defaults (1.77)"
|
||||||
|
dir, err = p.PoolDirectory()
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
c.Check(dir, Equals, "g/gcc-defaults")
|
||||||
|
|
||||||
p = NewPackageFromControlFile(packageStanza.Copy())
|
p = NewPackageFromControlFile(packageStanza.Copy())
|
||||||
p.Source = "l"
|
p.Source = "l"
|
||||||
_, err = p.PoolDirectory()
|
_, err = p.PoolDirectory()
|
||||||
|
|||||||
+388
-139
@@ -17,6 +17,15 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type repoSourceItem struct {
|
||||||
|
// Pointer to snapshot if SourceKind == "snapshot"
|
||||||
|
snapshot *Snapshot
|
||||||
|
// Pointer to local repo if SourceKind == "local"
|
||||||
|
localRepo *LocalRepo
|
||||||
|
// Package references is SourceKind == "local"
|
||||||
|
packageRefs *PackageRefList
|
||||||
|
}
|
||||||
|
|
||||||
// PublishedRepo is a published for http/ftp representation of snapshot as Debian repository
|
// PublishedRepo is a published for http/ftp representation of snapshot as Debian repository
|
||||||
type PublishedRepo struct {
|
type PublishedRepo struct {
|
||||||
// Internal unique ID
|
// Internal unique ID
|
||||||
@@ -24,81 +33,38 @@ type PublishedRepo struct {
|
|||||||
// Prefix & distribution should be unique across all published repositories
|
// Prefix & distribution should be unique across all published repositories
|
||||||
Prefix string
|
Prefix string
|
||||||
Distribution string
|
Distribution string
|
||||||
Component string
|
|
||||||
Origin string
|
Origin string
|
||||||
Label string
|
Label string
|
||||||
// Architectures is a list of all architectures published
|
// Architectures is a list of all architectures published
|
||||||
Architectures []string
|
Architectures []string
|
||||||
// SourceKind is "local"/"repo"
|
// SourceKind is "local"/"repo"
|
||||||
SourceKind string
|
SourceKind string
|
||||||
|
|
||||||
|
// Map of sources by each component: component name -> source UUID
|
||||||
|
Sources map[string]string
|
||||||
|
|
||||||
|
// Legacy fields for compatibily with old published repositories (< 0.6)
|
||||||
|
Component string
|
||||||
// SourceUUID is UUID of either snapshot or local repo
|
// SourceUUID is UUID of either snapshot or local repo
|
||||||
SourceUUID string `codec:"SnapshotUUID"`
|
SourceUUID string `codec:"SnapshotUUID"`
|
||||||
|
|
||||||
// Pointer to snapshot if SourceKind == "snapshot"
|
// Map of component to source items
|
||||||
snapshot *Snapshot
|
sourceItems map[string]repoSourceItem
|
||||||
// Pointer to local repo if SourceKind == "local"
|
|
||||||
localRepo *LocalRepo
|
|
||||||
// Package references is SourceKind == "local"
|
|
||||||
packageRefs *PackageRefList
|
|
||||||
// True if repo is being re-published
|
// True if repo is being re-published
|
||||||
rePublishing bool
|
rePublishing bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPublishedRepo creates new published repository
|
// walkUpTree goes from source in the tree of source snapshots/mirrors/local repos
|
||||||
//
|
// gathering information about declared components and distributions
|
||||||
// prefix specifies publishing prefix
|
func walkUpTree(source interface{}, collectionFactory *CollectionFactory) (rootDistributions []string, rootComponents []string) {
|
||||||
// distribution, component and architectures are user-defined properties
|
|
||||||
// source could either be *Snapshot or *LocalRepo
|
|
||||||
func NewPublishedRepo(prefix string, distribution string, component string, architectures []string, source interface{}, collectionFactory *CollectionFactory) (*PublishedRepo, error) {
|
|
||||||
var ok bool
|
|
||||||
|
|
||||||
result := &PublishedRepo{
|
|
||||||
UUID: uuid.New(),
|
|
||||||
Architectures: architectures,
|
|
||||||
}
|
|
||||||
|
|
||||||
// figure out source
|
|
||||||
result.snapshot, ok = source.(*Snapshot)
|
|
||||||
if ok {
|
|
||||||
result.SourceKind = "snapshot"
|
|
||||||
result.SourceUUID = result.snapshot.UUID
|
|
||||||
} else {
|
|
||||||
result.localRepo, ok = source.(*LocalRepo)
|
|
||||||
if ok {
|
|
||||||
result.SourceKind = "local"
|
|
||||||
result.SourceUUID = result.localRepo.UUID
|
|
||||||
result.packageRefs = result.localRepo.RefList()
|
|
||||||
} else {
|
|
||||||
panic("unknown source kind")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// clean & verify prefix
|
|
||||||
prefix = filepath.Clean(prefix)
|
|
||||||
if strings.HasPrefix(prefix, "/") {
|
|
||||||
prefix = prefix[1:]
|
|
||||||
}
|
|
||||||
if strings.HasSuffix(prefix, "/") {
|
|
||||||
prefix = prefix[:len(prefix)-1]
|
|
||||||
}
|
|
||||||
prefix = filepath.Clean(prefix)
|
|
||||||
|
|
||||||
for _, part := range strings.Split(prefix, "/") {
|
|
||||||
if part == ".." || part == "dists" || part == "pool" {
|
|
||||||
return nil, fmt.Errorf("invalid prefix %s", prefix)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result.Prefix = prefix
|
|
||||||
|
|
||||||
// guessing distribution & component
|
|
||||||
if component == "" || distribution == "" {
|
|
||||||
var (
|
var (
|
||||||
head interface{}
|
head interface{}
|
||||||
current = []interface{}{source}
|
current = []interface{}{source}
|
||||||
|
)
|
||||||
|
|
||||||
rootComponents = []string{}
|
rootComponents = []string{}
|
||||||
rootDistributions = []string{}
|
rootDistributions = []string{}
|
||||||
)
|
|
||||||
|
|
||||||
// walk up the tree from current source up to roots (local or remote repos)
|
// walk up the tree from current source up to roots (local or remote repos)
|
||||||
// and collect information about distribution and components
|
// and collect information about distribution and components
|
||||||
@@ -144,53 +110,163 @@ func NewPublishedRepo(prefix string, distribution string, component string, arch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPublishedRepo creates new published repository
|
||||||
|
//
|
||||||
|
// prefix specifies publishing prefix
|
||||||
|
// distribution and architectures are user-defined properties
|
||||||
|
// components & sources are lists of component to source mapping (*Snapshot or *LocalRepo)
|
||||||
|
func NewPublishedRepo(prefix string, distribution string, architectures []string,
|
||||||
|
components []string, sources []interface{}, collectionFactory *CollectionFactory) (*PublishedRepo, error) {
|
||||||
|
result := &PublishedRepo{
|
||||||
|
UUID: uuid.New(),
|
||||||
|
Architectures: architectures,
|
||||||
|
Sources: make(map[string]string),
|
||||||
|
sourceItems: make(map[string]repoSourceItem),
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(sources) == 0 {
|
||||||
|
panic("publish with empty sources")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(sources) != len(components) {
|
||||||
|
panic("sources and components should be equal in size")
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
discoveredDistributions = []string{}
|
||||||
|
source interface{}
|
||||||
|
component string
|
||||||
|
snapshot *Snapshot
|
||||||
|
localRepo *LocalRepo
|
||||||
|
ok bool
|
||||||
|
)
|
||||||
|
|
||||||
|
// get first source
|
||||||
|
source = sources[0]
|
||||||
|
|
||||||
|
// figure out source kind
|
||||||
|
snapshot, ok = source.(*Snapshot)
|
||||||
|
if ok {
|
||||||
|
result.SourceKind = "snapshot"
|
||||||
|
} else {
|
||||||
|
localRepo, ok = source.(*LocalRepo)
|
||||||
|
if ok {
|
||||||
|
result.SourceKind = "local"
|
||||||
|
} else {
|
||||||
|
panic("unknown source kind")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range sources {
|
||||||
|
component, source = components[i], sources[i]
|
||||||
|
if distribution == "" || component == "" {
|
||||||
|
rootDistributions, rootComponents := walkUpTree(source, collectionFactory)
|
||||||
if distribution == "" {
|
if distribution == "" {
|
||||||
sort.Strings(rootDistributions)
|
discoveredDistributions = append(discoveredDistributions, rootDistributions...)
|
||||||
if len(rootDistributions) > 0 && rootDistributions[0] == rootDistributions[len(rootDistributions)-1] {
|
}
|
||||||
distribution = rootDistributions[0]
|
if component == "" {
|
||||||
|
sort.Strings(rootComponents)
|
||||||
|
if len(rootComponents) > 0 && rootComponents[0] == rootComponents[len(rootComponents)-1] {
|
||||||
|
component = rootComponents[0]
|
||||||
|
} else if len(sources) == 1 {
|
||||||
|
// only if going from one source, assume default component "main"
|
||||||
|
component = "main"
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("unable to figure out component name for %s", source)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, exists := result.Sources[component]
|
||||||
|
if exists {
|
||||||
|
return nil, fmt.Errorf("duplicate component name: %s", component)
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.SourceKind == "snapshot" {
|
||||||
|
snapshot = source.(*Snapshot)
|
||||||
|
result.Sources[component] = snapshot.UUID
|
||||||
|
result.sourceItems[component] = repoSourceItem{snapshot: snapshot}
|
||||||
|
} else if result.SourceKind == "local" {
|
||||||
|
localRepo = source.(*LocalRepo)
|
||||||
|
result.Sources[component] = localRepo.UUID
|
||||||
|
result.sourceItems[component] = repoSourceItem{localRepo: localRepo, packageRefs: localRepo.RefList()}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean & verify prefix
|
||||||
|
prefix = filepath.Clean(prefix)
|
||||||
|
if strings.HasPrefix(prefix, "/") {
|
||||||
|
prefix = prefix[1:]
|
||||||
|
}
|
||||||
|
if strings.HasSuffix(prefix, "/") {
|
||||||
|
prefix = prefix[:len(prefix)-1]
|
||||||
|
}
|
||||||
|
prefix = filepath.Clean(prefix)
|
||||||
|
|
||||||
|
for _, part := range strings.Split(prefix, "/") {
|
||||||
|
if part == ".." || part == "dists" || part == "pool" {
|
||||||
|
return nil, fmt.Errorf("invalid prefix %s", prefix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Prefix = prefix
|
||||||
|
|
||||||
|
// guessing distribution
|
||||||
|
if distribution == "" {
|
||||||
|
sort.Strings(discoveredDistributions)
|
||||||
|
if len(discoveredDistributions) > 0 && discoveredDistributions[0] == discoveredDistributions[len(discoveredDistributions)-1] {
|
||||||
|
distribution = discoveredDistributions[0]
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("unable to guess distribution name, please specify explicitly")
|
return nil, fmt.Errorf("unable to guess distribution name, please specify explicitly")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if component == "" {
|
result.Distribution = distribution
|
||||||
sort.Strings(rootComponents)
|
|
||||||
if len(rootComponents) > 0 && rootComponents[0] == rootComponents[len(rootComponents)-1] {
|
|
||||||
component = rootComponents[0]
|
|
||||||
} else {
|
|
||||||
component = "main"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result.Distribution, result.Component = distribution, component
|
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns human-readable represenation of PublishedRepo
|
// String returns human-readable represenation of PublishedRepo
|
||||||
func (p *PublishedRepo) String() string {
|
func (p *PublishedRepo) String() string {
|
||||||
|
var sources = []string{}
|
||||||
|
|
||||||
|
for _, component := range p.Components() {
|
||||||
var source string
|
var source string
|
||||||
|
|
||||||
if p.snapshot != nil {
|
item := p.sourceItems[component]
|
||||||
source = p.snapshot.String()
|
if item.snapshot != nil {
|
||||||
} else if p.localRepo != nil {
|
source = item.snapshot.String()
|
||||||
source = p.localRepo.String()
|
} else if item.localRepo != nil {
|
||||||
|
source = item.localRepo.String()
|
||||||
} else {
|
} else {
|
||||||
panic("no snapshot/localRepo")
|
panic("no snapshot/localRepo")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sources = append(sources, fmt.Sprintf("{%s: %s}", component, source))
|
||||||
|
}
|
||||||
|
|
||||||
var extra string
|
var extra string
|
||||||
|
|
||||||
if p.Origin != "" {
|
if p.Origin != "" {
|
||||||
extra += fmt.Sprintf(", origin: %s", p.Origin)
|
extra += fmt.Sprintf("origin: %s", p.Origin)
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.Label != "" {
|
if p.Label != "" {
|
||||||
extra += fmt.Sprintf(", label: %s", p.Label)
|
if extra != "" {
|
||||||
|
extra += ", "
|
||||||
|
}
|
||||||
|
extra += fmt.Sprintf("label: %s", p.Label)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("%s/%s (%s%s) [%s] publishes %s", p.Prefix, p.Distribution, p.Component, extra, strings.Join(p.Architectures, ", "), source)
|
if extra != "" {
|
||||||
|
extra = " (" + extra + ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s/%s%s [%s] publishes %s", p.Prefix, p.Distribution, extra, strings.Join(p.Architectures, ", "),
|
||||||
|
strings.Join(sources, ", "))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Key returns unique key identifying PublishedRepo
|
// Key returns unique key identifying PublishedRepo
|
||||||
@@ -199,37 +275,57 @@ func (p *PublishedRepo) Key() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RefKey is a unique id for package reference list
|
// RefKey is a unique id for package reference list
|
||||||
func (p *PublishedRepo) RefKey() []byte {
|
func (p *PublishedRepo) RefKey(component string) []byte {
|
||||||
return []byte("E" + p.UUID)
|
return []byte("E" + p.UUID + component)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefList returns list of package refs in local repo
|
// RefList returns list of package refs in local repo
|
||||||
func (p *PublishedRepo) RefList() *PackageRefList {
|
func (p *PublishedRepo) RefList(component string) *PackageRefList {
|
||||||
|
item := p.sourceItems[component]
|
||||||
if p.SourceKind == "local" {
|
if p.SourceKind == "local" {
|
||||||
return p.packageRefs
|
return item.packageRefs
|
||||||
}
|
}
|
||||||
if p.SourceKind == "snapshot" {
|
if p.SourceKind == "snapshot" {
|
||||||
return p.snapshot.RefList()
|
return item.snapshot.RefList()
|
||||||
}
|
}
|
||||||
panic("unknown source")
|
panic("unknown source")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PublishedRepo) UpdateLocalRepo() {
|
// Components returns sorted list of published repo components
|
||||||
|
func (p *PublishedRepo) Components() []string {
|
||||||
|
result := make([]string, 0, len(p.Sources))
|
||||||
|
for component := range p.Sources {
|
||||||
|
result = append(result, component)
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Strings(result)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateLocalRepo updates content from local repo in component
|
||||||
|
func (p *PublishedRepo) UpdateLocalRepo(component string) {
|
||||||
if p.SourceKind != "local" {
|
if p.SourceKind != "local" {
|
||||||
panic("not local repo publish")
|
panic("not local repo publish")
|
||||||
}
|
}
|
||||||
|
|
||||||
p.packageRefs = p.localRepo.RefList()
|
item := p.sourceItems[component]
|
||||||
|
item.packageRefs = item.localRepo.RefList()
|
||||||
|
p.sourceItems[component] = item
|
||||||
|
|
||||||
p.rePublishing = true
|
p.rePublishing = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PublishedRepo) UpdateSnapshot(snapshot *Snapshot) {
|
// UpdateSnapshot switches snapshot for component
|
||||||
|
func (p *PublishedRepo) UpdateSnapshot(component string, snapshot *Snapshot) {
|
||||||
if p.SourceKind != "snapshot" {
|
if p.SourceKind != "snapshot" {
|
||||||
panic("not snapshot publish")
|
panic("not snapshot publish")
|
||||||
}
|
}
|
||||||
|
|
||||||
p.snapshot = snapshot
|
item := p.sourceItems[component]
|
||||||
p.SourceUUID = snapshot.UUID
|
item.snapshot = snapshot
|
||||||
|
p.sourceItems[component] = item
|
||||||
|
|
||||||
|
p.Sources[component] = snapshot.UUID
|
||||||
p.rePublishing = true
|
p.rePublishing = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,9 +352,32 @@ func (p *PublishedRepo) Decode(input []byte) error {
|
|||||||
p.SourceKind = "snapshot"
|
p.SourceKind = "snapshot"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// <0.6 aptly used single SourceUUID + Component instead of Sources
|
||||||
|
if p.Component != "" && p.SourceUUID != "" && len(p.Sources) == 0 {
|
||||||
|
p.Sources = map[string]string{p.Component: p.SourceUUID}
|
||||||
|
p.Component = ""
|
||||||
|
p.SourceUUID = ""
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetOrigin returns default or manual Origin:
|
||||||
|
func (p *PublishedRepo) GetOrigin() string {
|
||||||
|
if p.Origin == "" {
|
||||||
|
return p.Prefix + " " + p.Distribution
|
||||||
|
}
|
||||||
|
return p.Origin
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLabel returns default or manual Label:
|
||||||
|
func (p *PublishedRepo) GetLabel() string {
|
||||||
|
if p.Label == "" {
|
||||||
|
return p.Prefix + " " + p.Distribution
|
||||||
|
}
|
||||||
|
return p.Label
|
||||||
|
}
|
||||||
|
|
||||||
// Publish publishes snapshot (repository) contents, links package files, generates Packages & Release files, signs them
|
// Publish publishes snapshot (repository) contents, links package files, generates Packages & Release files, signs them
|
||||||
func (p *PublishedRepo) Publish(packagePool aptly.PackagePool, publishedStorage aptly.PublishedStorage,
|
func (p *PublishedRepo) Publish(packagePool aptly.PackagePool, publishedStorage aptly.PublishedStorage,
|
||||||
collectionFactory *CollectionFactory, signer utils.Signer, progress aptly.Progress) error {
|
collectionFactory *CollectionFactory, signer utils.Signer, progress aptly.Progress) error {
|
||||||
@@ -276,19 +395,21 @@ func (p *PublishedRepo) Publish(packagePool aptly.PackagePool, publishedStorage
|
|||||||
progress.Printf("Loading packages...\n")
|
progress.Printf("Loading packages...\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lists := map[string]*PackageList{}
|
||||||
|
|
||||||
|
for component := range p.sourceItems {
|
||||||
// Load all packages
|
// Load all packages
|
||||||
list, err := NewPackageListFromRefList(p.RefList(), collectionFactory.PackageCollection(), progress)
|
lists[component], err = NewPackageListFromRefList(p.RefList(component), collectionFactory.PackageCollection(), progress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to load packages: %s", err)
|
return fmt.Errorf("unable to load packages: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if list.Len() == 0 {
|
|
||||||
return fmt.Errorf("source is empty")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !p.rePublishing {
|
if !p.rePublishing {
|
||||||
if len(p.Architectures) == 0 {
|
if len(p.Architectures) == 0 {
|
||||||
p.Architectures = list.Architectures(true)
|
for _, list := range lists {
|
||||||
|
p.Architectures = append(p.Architectures, list.Architectures(true)...)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(p.Architectures) == 0 {
|
if len(p.Architectures) == 0 {
|
||||||
@@ -296,6 +417,7 @@ func (p *PublishedRepo) Publish(packagePool aptly.PackagePool, publishedStorage
|
|||||||
}
|
}
|
||||||
|
|
||||||
sort.Strings(p.Architectures)
|
sort.Strings(p.Architectures)
|
||||||
|
p.Architectures = utils.StrSliceDeduplicate(p.Architectures)
|
||||||
}
|
}
|
||||||
|
|
||||||
var suffix string
|
var suffix string
|
||||||
@@ -310,17 +432,19 @@ func (p *PublishedRepo) Publish(packagePool aptly.PackagePool, publishedStorage
|
|||||||
progress.Printf("Generating metadata files and linking package files...\n")
|
progress.Printf("Generating metadata files and linking package files...\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
// For all architectures, generate release file
|
for component, list := range lists {
|
||||||
|
var relativePath string
|
||||||
|
|
||||||
|
// For all architectures, generate packages/sources files
|
||||||
for _, arch := range p.Architectures {
|
for _, arch := range p.Architectures {
|
||||||
if progress != nil {
|
if progress != nil {
|
||||||
progress.InitBar(int64(list.Len()), false)
|
progress.InitBar(int64(list.Len()), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
var relativePath string
|
|
||||||
if arch == "source" {
|
if arch == "source" {
|
||||||
relativePath = filepath.Join(p.Component, "source", "Sources")
|
relativePath = filepath.Join(component, "source", "Sources")
|
||||||
} else {
|
} else {
|
||||||
relativePath = filepath.Join(p.Component, fmt.Sprintf("binary-%s", arch), "Packages")
|
relativePath = filepath.Join(component, fmt.Sprintf("binary-%s", arch), "Packages")
|
||||||
}
|
}
|
||||||
err = publishedStorage.MkDir(filepath.Dir(filepath.Join(basePath, relativePath)))
|
err = publishedStorage.MkDir(filepath.Dir(filepath.Join(basePath, relativePath)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -344,7 +468,7 @@ func (p *PublishedRepo) Publish(packagePool aptly.PackagePool, publishedStorage
|
|||||||
progress.AddBar(1)
|
progress.AddBar(1)
|
||||||
}
|
}
|
||||||
if pkg.MatchesArchitecture(arch) {
|
if pkg.MatchesArchitecture(arch) {
|
||||||
err = pkg.LinkFromPool(publishedStorage, packagePool, p.Prefix, p.Component)
|
err = pkg.LinkFromPool(publishedStorage, packagePool, p.Prefix, component)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -412,26 +536,67 @@ func (p *PublishedRepo) Publish(packagePool aptly.PackagePool, publishedStorage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For all architectures, generate Release files
|
||||||
|
for _, arch := range p.Architectures {
|
||||||
release := make(Stanza)
|
release := make(Stanza)
|
||||||
if p.Origin == "" {
|
release["Archive"] = p.Distribution
|
||||||
release["Origin"] = p.Prefix + " " + p.Distribution
|
release["Architecture"] = arch
|
||||||
|
release["Component"] = component
|
||||||
|
release["Origin"] = p.GetOrigin()
|
||||||
|
release["Label"] = p.GetLabel()
|
||||||
|
|
||||||
|
if arch == "source" {
|
||||||
|
relativePath = filepath.Join(component, "source", "Release")
|
||||||
} else {
|
} else {
|
||||||
release["Origin"] = p.Origin
|
relativePath = filepath.Join(component, fmt.Sprintf("binary-%s", arch), "Release")
|
||||||
}
|
}
|
||||||
if p.Label == "" {
|
|
||||||
release["Label"] = p.Prefix + " " + p.Distribution
|
var file *os.File
|
||||||
} else {
|
file, err = publishedStorage.CreateFile(filepath.Join(basePath, relativePath+suffix))
|
||||||
release["Label"] = p.Label
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to create Release file: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if suffix != "" {
|
||||||
|
renameMap[filepath.Join(basePath, relativePath+suffix)] = filepath.Join(basePath, relativePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
bufWriter := bufio.NewWriter(file)
|
||||||
|
|
||||||
|
err = release.WriteTo(bufWriter)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to create Release file: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = bufWriter.Flush()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to create Release file: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
file.Close()
|
||||||
|
|
||||||
|
var checksumInfo utils.ChecksumInfo
|
||||||
|
checksumInfo, err = publishedStorage.ChecksumsForFile(filepath.Join(basePath, relativePath+suffix))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to collect checksums: %s", err)
|
||||||
|
}
|
||||||
|
generatedFiles[relativePath] = checksumInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
release := make(Stanza)
|
||||||
|
release["Origin"] = p.GetOrigin()
|
||||||
|
release["Label"] = p.GetLabel()
|
||||||
release["Codename"] = p.Distribution
|
release["Codename"] = p.Distribution
|
||||||
release["Date"] = time.Now().UTC().Format("Mon, 2 Jan 2006 15:04:05 MST")
|
release["Date"] = time.Now().UTC().Format("Mon, 2 Jan 2006 15:04:05 MST")
|
||||||
release["Components"] = p.Component
|
|
||||||
release["Architectures"] = strings.Join(utils.StrSlicesSubstract(p.Architectures, []string{"source"}), " ")
|
release["Architectures"] = strings.Join(utils.StrSlicesSubstract(p.Architectures, []string{"source"}), " ")
|
||||||
release["Description"] = " Generated by aptly\n"
|
release["Description"] = " Generated by aptly\n"
|
||||||
release["MD5Sum"] = "\n"
|
release["MD5Sum"] = "\n"
|
||||||
release["SHA1"] = "\n"
|
release["SHA1"] = "\n"
|
||||||
release["SHA256"] = "\n"
|
release["SHA256"] = "\n"
|
||||||
|
|
||||||
|
release["Components"] = strings.Join(p.Components(), " ")
|
||||||
|
|
||||||
for path, info := range generatedFiles {
|
for path, info := range generatedFiles {
|
||||||
release["MD5Sum"] += fmt.Sprintf(" %s %8d %s\n", info.MD5, info.Size, path)
|
release["MD5Sum"] += fmt.Sprintf(" %s %8d %s\n", info.MD5, info.Size, path)
|
||||||
release["SHA1"] += fmt.Sprintf(" %s %8d %s\n", info.SHA1, info.Size, path)
|
release["SHA1"] += fmt.Sprintf(" %s %8d %s\n", info.SHA1, info.Size, path)
|
||||||
@@ -498,7 +663,8 @@ func (p *PublishedRepo) Publish(packagePool aptly.PackagePool, publishedStorage
|
|||||||
// RemoveFiles removes files that were created by Publish
|
// RemoveFiles removes files that were created by Publish
|
||||||
//
|
//
|
||||||
// It can remove prefix fully, and part of pool (for specific component)
|
// It can remove prefix fully, and part of pool (for specific component)
|
||||||
func (p *PublishedRepo) RemoveFiles(publishedStorage aptly.PublishedStorage, removePrefix, removePoolComponent bool, progress aptly.Progress) error {
|
func (p *PublishedRepo) RemoveFiles(publishedStorage aptly.PublishedStorage, removePrefix bool,
|
||||||
|
removePoolComponents []string, progress aptly.Progress) error {
|
||||||
// I. Easy: remove whole prefix (meta+packages)
|
// I. Easy: remove whole prefix (meta+packages)
|
||||||
if removePrefix {
|
if removePrefix {
|
||||||
err := publishedStorage.RemoveDirs(filepath.Join(p.Prefix, "dists"), progress)
|
err := publishedStorage.RemoveDirs(filepath.Join(p.Prefix, "dists"), progress)
|
||||||
@@ -516,15 +682,13 @@ func (p *PublishedRepo) RemoveFiles(publishedStorage aptly.PublishedStorage, rem
|
|||||||
}
|
}
|
||||||
|
|
||||||
// III. Complex: there are no other publishes with the same prefix + component
|
// III. Complex: there are no other publishes with the same prefix + component
|
||||||
if removePoolComponent {
|
for _, component := range removePoolComponents {
|
||||||
err = publishedStorage.RemoveDirs(filepath.Join(p.Prefix, "pool", p.Component), progress)
|
err = publishedStorage.RemoveDirs(filepath.Join(p.Prefix, "pool", component), progress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
/// IV: Hard: should have removed published files from the pool + component
|
|
||||||
/// that are unique to this published repo
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -589,42 +753,74 @@ func (collection *PublishedRepoCollection) Update(repo *PublishedRepo) (err erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
if repo.SourceKind == "local" {
|
if repo.SourceKind == "local" {
|
||||||
err = collection.db.Put(repo.RefKey(), repo.packageRefs.Encode())
|
for component, item := range repo.sourceItems {
|
||||||
|
err = collection.db.Put(repo.RefKey(component), item.packageRefs.Encode())
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadComplete loads additional information for remote repo
|
// LoadComplete loads additional information for remote repo
|
||||||
func (collection *PublishedRepoCollection) LoadComplete(repo *PublishedRepo, collectionFactory *CollectionFactory) (err error) {
|
func (collection *PublishedRepoCollection) LoadComplete(repo *PublishedRepo, collectionFactory *CollectionFactory) (err error) {
|
||||||
|
repo.sourceItems = make(map[string]repoSourceItem)
|
||||||
|
|
||||||
if repo.SourceKind == "snapshot" {
|
if repo.SourceKind == "snapshot" {
|
||||||
repo.snapshot, err = collectionFactory.SnapshotCollection().ByUUID(repo.SourceUUID)
|
for component, sourceUUID := range repo.Sources {
|
||||||
|
item := repoSourceItem{}
|
||||||
|
|
||||||
|
item.snapshot, err = collectionFactory.SnapshotCollection().ByUUID(sourceUUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = collectionFactory.SnapshotCollection().LoadComplete(repo.snapshot)
|
err = collectionFactory.SnapshotCollection().LoadComplete(item.snapshot)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
repo.sourceItems[component] = item
|
||||||
|
}
|
||||||
} else if repo.SourceKind == "local" {
|
} else if repo.SourceKind == "local" {
|
||||||
repo.localRepo, err = collectionFactory.LocalRepoCollection().ByUUID(repo.SourceUUID)
|
for component, sourceUUID := range repo.Sources {
|
||||||
|
item := repoSourceItem{}
|
||||||
|
|
||||||
|
item.localRepo, err = collectionFactory.LocalRepoCollection().ByUUID(sourceUUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = collectionFactory.LocalRepoCollection().LoadComplete(repo.localRepo)
|
err = collectionFactory.LocalRepoCollection().LoadComplete(item.localRepo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var encoded []byte
|
var encoded []byte
|
||||||
encoded, err = collection.db.Get(repo.RefKey())
|
encoded, err = collection.db.Get(repo.RefKey(component))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
// < 0.6 saving w/o component name
|
||||||
|
if err == database.ErrNotFound && len(repo.Sources) == 1 {
|
||||||
|
encoded, err = collection.db.Get(repo.RefKey(""))
|
||||||
}
|
}
|
||||||
|
|
||||||
repo.packageRefs = &PackageRefList{}
|
if err != nil {
|
||||||
err = repo.packageRefs.Decode(encoded)
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item.packageRefs = &PackageRefList{}
|
||||||
|
err = item.packageRefs.Decode(encoded)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
repo.sourceItems[component] = item
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
panic("unknown SourceKind")
|
panic("unknown SourceKind")
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ByPrefixDistribution looks up repository by prefix & distribution
|
// ByPrefixDistribution looks up repository by prefix & distribution
|
||||||
@@ -651,9 +847,18 @@ func (collection *PublishedRepoCollection) ByUUID(uuid string) (*PublishedRepo,
|
|||||||
func (collection *PublishedRepoCollection) BySnapshot(snapshot *Snapshot) []*PublishedRepo {
|
func (collection *PublishedRepoCollection) BySnapshot(snapshot *Snapshot) []*PublishedRepo {
|
||||||
result := make([]*PublishedRepo, 0)
|
result := make([]*PublishedRepo, 0)
|
||||||
for _, r := range collection.list {
|
for _, r := range collection.list {
|
||||||
if r.SourceKind == "snapshot" && r.SourceUUID == snapshot.UUID {
|
if r.SourceKind == "snapshot" {
|
||||||
|
if r.SourceUUID == snapshot.UUID {
|
||||||
result = append(result, r)
|
result = append(result, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, sourceUUID := range r.Sources {
|
||||||
|
if sourceUUID == snapshot.UUID {
|
||||||
|
result = append(result, r)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@@ -662,9 +867,18 @@ func (collection *PublishedRepoCollection) BySnapshot(snapshot *Snapshot) []*Pub
|
|||||||
func (collection *PublishedRepoCollection) ByLocalRepo(repo *LocalRepo) []*PublishedRepo {
|
func (collection *PublishedRepoCollection) ByLocalRepo(repo *LocalRepo) []*PublishedRepo {
|
||||||
result := make([]*PublishedRepo, 0)
|
result := make([]*PublishedRepo, 0)
|
||||||
for _, r := range collection.list {
|
for _, r := range collection.list {
|
||||||
if r.SourceKind == "local" && r.SourceUUID == repo.UUID {
|
if r.SourceKind == "local" {
|
||||||
|
if r.SourceUUID == repo.UUID {
|
||||||
result = append(result, r)
|
result = append(result, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, sourceUUID := range r.Sources {
|
||||||
|
if sourceUUID == repo.UUID {
|
||||||
|
result = append(result, r)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@@ -687,24 +901,41 @@ func (collection *PublishedRepoCollection) Len() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CleanupPrefixComponentFiles removes all unreferenced files in published storage under prefix/component pair
|
// CleanupPrefixComponentFiles removes all unreferenced files in published storage under prefix/component pair
|
||||||
func (collection *PublishedRepoCollection) CleanupPrefixComponentFiles(prefix, component string,
|
func (collection *PublishedRepoCollection) CleanupPrefixComponentFiles(prefix string, components []string,
|
||||||
publishedStorage aptly.PublishedStorage, collectionFactory *CollectionFactory, progress aptly.Progress) error {
|
publishedStorage aptly.PublishedStorage, collectionFactory *CollectionFactory, progress aptly.Progress) error {
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
referencedFiles := []string{}
|
referencedFiles := map[string][]string{}
|
||||||
|
|
||||||
if progress != nil {
|
if progress != nil {
|
||||||
progress.Printf("Cleaning up prefix %#v component %#v...\n", prefix, component)
|
progress.Printf("Cleaning up prefix %#v components %s...\n", prefix, strings.Join(components, ", "))
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, r := range collection.list {
|
for _, r := range collection.list {
|
||||||
if r.Prefix == prefix && r.Component == component {
|
if r.Prefix == prefix {
|
||||||
|
matches := false
|
||||||
|
|
||||||
|
repoComponents := r.Components()
|
||||||
|
|
||||||
|
for _, component := range components {
|
||||||
|
if utils.StrSliceHasItem(repoComponents, component) {
|
||||||
|
matches = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !matches {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
err = collection.LoadComplete(r, collectionFactory)
|
err = collection.LoadComplete(r, collectionFactory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
packageList, err := NewPackageListFromRefList(r.RefList(), collectionFactory.PackageCollection(), progress)
|
for _, component := range components {
|
||||||
|
if utils.StrSliceHasItem(repoComponents, component) {
|
||||||
|
packageList, err := NewPackageListFromRefList(r.RefList(component), collectionFactory.PackageCollection(), progress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -716,15 +947,18 @@ func (collection *PublishedRepoCollection) CleanupPrefixComponentFiles(prefix, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, f := range p.Files() {
|
for _, f := range p.Files() {
|
||||||
referencedFiles = append(referencedFiles, filepath.Join(poolDir, f.Filename))
|
referencedFiles[component] = append(referencedFiles[component], filepath.Join(poolDir, f.Filename))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sort.Strings(referencedFiles)
|
for _, component := range components {
|
||||||
|
sort.Strings(referencedFiles[component])
|
||||||
|
|
||||||
rootPath := filepath.Join(prefix, "pool", component)
|
rootPath := filepath.Join(prefix, "pool", component)
|
||||||
existingFiles, err := publishedStorage.Filelist(rootPath)
|
existingFiles, err := publishedStorage.Filelist(rootPath)
|
||||||
@@ -734,7 +968,7 @@ func (collection *PublishedRepoCollection) CleanupPrefixComponentFiles(prefix, c
|
|||||||
|
|
||||||
sort.Strings(existingFiles)
|
sort.Strings(existingFiles)
|
||||||
|
|
||||||
filesToDelete := utils.StrSlicesSubstract(existingFiles, referencedFiles)
|
filesToDelete := utils.StrSlicesSubstract(existingFiles, referencedFiles[component])
|
||||||
|
|
||||||
for _, file := range filesToDelete {
|
for _, file := range filesToDelete {
|
||||||
err = publishedStorage.Remove(filepath.Join(rootPath, file))
|
err = publishedStorage.Remove(filepath.Join(rootPath, file))
|
||||||
@@ -742,6 +976,7 @@ func (collection *PublishedRepoCollection) CleanupPrefixComponentFiles(prefix, c
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -755,7 +990,8 @@ func (collection *PublishedRepoCollection) Remove(publishedStorage aptly.Publish
|
|||||||
}
|
}
|
||||||
|
|
||||||
removePrefix := true
|
removePrefix := true
|
||||||
removePoolComponent := true
|
removePoolComponents := repo.Components()
|
||||||
|
cleanComponents := []string{}
|
||||||
repoPosition := -1
|
repoPosition := -1
|
||||||
|
|
||||||
for i, r := range collection.list {
|
for i, r := range collection.list {
|
||||||
@@ -765,13 +1001,18 @@ func (collection *PublishedRepoCollection) Remove(publishedStorage aptly.Publish
|
|||||||
}
|
}
|
||||||
if r.Prefix == repo.Prefix {
|
if r.Prefix == repo.Prefix {
|
||||||
removePrefix = false
|
removePrefix = false
|
||||||
if r.Component == repo.Component {
|
|
||||||
removePoolComponent = false
|
rComponents := r.Components()
|
||||||
|
for _, component := range rComponents {
|
||||||
|
if utils.StrSliceHasItem(removePoolComponents, component) {
|
||||||
|
removePoolComponents = utils.StrSlicesSubstract(removePoolComponents, []string{component})
|
||||||
|
cleanComponents = append(cleanComponents, component)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = repo.RemoveFiles(publishedStorage, removePrefix, removePoolComponent, progress)
|
err = repo.RemoveFiles(publishedStorage, removePrefix, removePoolComponents, progress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -779,8 +1020,8 @@ func (collection *PublishedRepoCollection) Remove(publishedStorage aptly.Publish
|
|||||||
collection.list[len(collection.list)-1], collection.list[repoPosition], collection.list =
|
collection.list[len(collection.list)-1], collection.list[repoPosition], collection.list =
|
||||||
nil, collection.list[len(collection.list)-1], collection.list[:len(collection.list)-1]
|
nil, collection.list[len(collection.list)-1], collection.list[:len(collection.list)-1]
|
||||||
|
|
||||||
if !removePrefix && !removePoolComponent {
|
if len(cleanComponents) > 0 {
|
||||||
err = collection.CleanupPrefixComponentFiles(repo.Prefix, repo.Component, publishedStorage, collectionFactory, progress)
|
err = collection.CleanupPrefixComponentFiles(repo.Prefix, cleanComponents, publishedStorage, collectionFactory, progress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -790,5 +1031,13 @@ func (collection *PublishedRepoCollection) Remove(publishedStorage aptly.Publish
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return collection.db.Delete(repo.RefKey())
|
|
||||||
|
for _, component := range repo.Components() {
|
||||||
|
err = collection.db.Delete(repo.RefKey(component))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+171
-55
@@ -1,10 +1,12 @@
|
|||||||
package deb
|
package deb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/smira/aptly/aptly"
|
"github.com/smira/aptly/aptly"
|
||||||
"github.com/smira/aptly/database"
|
"github.com/smira/aptly/database"
|
||||||
"github.com/smira/aptly/files"
|
"github.com/smira/aptly/files"
|
||||||
|
"github.com/ugorji/go/codec"
|
||||||
. "launchpad.net/gocheck"
|
. "launchpad.net/gocheck"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -45,12 +47,12 @@ func (n *NullSigner) ClearSign(source string, destination string) error {
|
|||||||
|
|
||||||
type PublishedRepoSuite struct {
|
type PublishedRepoSuite struct {
|
||||||
PackageListMixinSuite
|
PackageListMixinSuite
|
||||||
repo, repo2 *PublishedRepo
|
repo, repo2, repo3, repo4 *PublishedRepo
|
||||||
root string
|
root string
|
||||||
publishedStorage aptly.PublishedStorage
|
publishedStorage aptly.PublishedStorage
|
||||||
packagePool aptly.PackagePool
|
packagePool aptly.PackagePool
|
||||||
localRepo *LocalRepo
|
localRepo *LocalRepo
|
||||||
snapshot *Snapshot
|
snapshot, snapshot2 *Snapshot
|
||||||
db database.Storage
|
db database.Storage
|
||||||
factory *CollectionFactory
|
factory *CollectionFactory
|
||||||
packageCollection *PackageCollection
|
packageCollection *PackageCollection
|
||||||
@@ -79,14 +81,21 @@ func (s *PublishedRepoSuite) SetUpTest(c *C) {
|
|||||||
s.snapshot, _ = NewSnapshotFromRepository("snap", repo)
|
s.snapshot, _ = NewSnapshotFromRepository("snap", repo)
|
||||||
s.factory.SnapshotCollection().Add(s.snapshot)
|
s.factory.SnapshotCollection().Add(s.snapshot)
|
||||||
|
|
||||||
|
s.snapshot2, _ = NewSnapshotFromRepository("snap", repo)
|
||||||
|
s.factory.SnapshotCollection().Add(s.snapshot2)
|
||||||
|
|
||||||
s.packageCollection = s.factory.PackageCollection()
|
s.packageCollection = s.factory.PackageCollection()
|
||||||
s.packageCollection.Update(s.p1)
|
s.packageCollection.Update(s.p1)
|
||||||
s.packageCollection.Update(s.p2)
|
s.packageCollection.Update(s.p2)
|
||||||
s.packageCollection.Update(s.p3)
|
s.packageCollection.Update(s.p3)
|
||||||
|
|
||||||
s.repo, _ = NewPublishedRepo("ppa", "squeeze", "main", nil, s.snapshot, s.factory)
|
s.repo, _ = NewPublishedRepo("ppa", "squeeze", nil, []string{"main"}, []interface{}{s.snapshot}, s.factory)
|
||||||
|
|
||||||
s.repo2, _ = NewPublishedRepo("ppa", "maverick", "main", nil, s.localRepo, s.factory)
|
s.repo2, _ = NewPublishedRepo("ppa", "maverick", nil, []string{"main"}, []interface{}{s.localRepo}, s.factory)
|
||||||
|
|
||||||
|
s.repo3, _ = NewPublishedRepo("linux", "natty", nil, []string{"main", "contrib"}, []interface{}{s.snapshot, s.snapshot2}, s.factory)
|
||||||
|
|
||||||
|
s.repo4, _ = NewPublishedRepo("ppa", "maverick", []string{"source"}, []string{"main"}, []interface{}{s.localRepo}, s.factory)
|
||||||
|
|
||||||
poolPath, _ := s.packagePool.Path(s.p1.Files()[0].Filename, s.p1.Files()[0].Checksums.MD5)
|
poolPath, _ := s.packagePool.Path(s.p1.Files()[0].Filename, s.p1.Files()[0].Checksums.MD5)
|
||||||
err := os.MkdirAll(filepath.Dir(poolPath), 0755)
|
err := os.MkdirAll(filepath.Dir(poolPath), 0755)
|
||||||
@@ -100,17 +109,39 @@ func (s *PublishedRepoSuite) TearDownTest(c *C) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *PublishedRepoSuite) TestNewPublishedRepo(c *C) {
|
func (s *PublishedRepoSuite) TestNewPublishedRepo(c *C) {
|
||||||
c.Check(s.repo.snapshot, Equals, s.snapshot)
|
c.Check(s.repo.sourceItems["main"].snapshot, Equals, s.snapshot)
|
||||||
c.Check(s.repo.SourceKind, Equals, "snapshot")
|
c.Check(s.repo.SourceKind, Equals, "snapshot")
|
||||||
c.Check(s.repo.SourceUUID, Equals, s.snapshot.UUID)
|
c.Check(s.repo.Sources["main"], Equals, s.snapshot.UUID)
|
||||||
|
c.Check(s.repo.Components(), DeepEquals, []string{"main"})
|
||||||
|
|
||||||
c.Check(s.repo2.localRepo, Equals, s.localRepo)
|
c.Check(s.repo2.sourceItems["main"].localRepo, Equals, s.localRepo)
|
||||||
c.Check(s.repo2.SourceKind, Equals, "local")
|
c.Check(s.repo2.SourceKind, Equals, "local")
|
||||||
c.Check(s.repo2.SourceUUID, Equals, s.localRepo.UUID)
|
c.Check(s.repo2.Sources["main"], Equals, s.localRepo.UUID)
|
||||||
c.Check(s.repo2.packageRefs.Len(), Equals, 3)
|
c.Check(s.repo2.sourceItems["main"].packageRefs.Len(), Equals, 3)
|
||||||
|
c.Check(s.repo2.Components(), DeepEquals, []string{"main"})
|
||||||
|
|
||||||
c.Check(s.repo.RefList().Len(), Equals, 3)
|
c.Check(s.repo.RefList("main").Len(), Equals, 3)
|
||||||
c.Check(s.repo2.RefList().Len(), Equals, 3)
|
c.Check(s.repo2.RefList("main").Len(), Equals, 3)
|
||||||
|
|
||||||
|
c.Check(s.repo3.Sources, DeepEquals, map[string]string{"main": s.snapshot.UUID, "contrib": s.snapshot2.UUID})
|
||||||
|
c.Check(s.repo3.SourceKind, Equals, "snapshot")
|
||||||
|
c.Check(s.repo3.sourceItems["main"].snapshot, Equals, s.snapshot)
|
||||||
|
c.Check(s.repo3.sourceItems["contrib"].snapshot, Equals, s.snapshot2)
|
||||||
|
c.Check(s.repo3.Components(), DeepEquals, []string{"contrib", "main"})
|
||||||
|
|
||||||
|
c.Check(s.repo3.RefList("main").Len(), Equals, 3)
|
||||||
|
c.Check(s.repo3.RefList("contrib").Len(), Equals, 3)
|
||||||
|
|
||||||
|
c.Check(func() { NewPublishedRepo(".", "a", nil, nil, nil, s.factory) }, PanicMatches, "publish with empty sources")
|
||||||
|
c.Check(func() {
|
||||||
|
NewPublishedRepo(".", "a", nil, []string{"main"}, []interface{}{s.snapshot, s.snapshot2}, s.factory)
|
||||||
|
}, PanicMatches, "sources and components should be equal in size")
|
||||||
|
c.Check(func() {
|
||||||
|
NewPublishedRepo(".", "a", nil, []string{"main", "contrib"}, []interface{}{s.localRepo, s.snapshot2}, s.factory)
|
||||||
|
}, PanicMatches, "interface conversion:.*")
|
||||||
|
|
||||||
|
_, err := NewPublishedRepo(".", "a", nil, []string{"main", "main"}, []interface{}{s.snapshot, s.snapshot2}, s.factory)
|
||||||
|
c.Check(err, ErrorMatches, "duplicate component name: main")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PublishedRepoSuite) TestPrefixNormalization(c *C) {
|
func (s *PublishedRepoSuite) TestPrefixNormalization(c *C) {
|
||||||
@@ -169,7 +200,7 @@ func (s *PublishedRepoSuite) TestPrefixNormalization(c *C) {
|
|||||||
errorExpected: "invalid prefix .*",
|
errorExpected: "invalid prefix .*",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
repo, err := NewPublishedRepo(t.prefix, "squeeze", "main", nil, s.snapshot, s.factory)
|
repo, err := NewPublishedRepo(t.prefix, "squeeze", nil, []string{"main"}, []interface{}{s.snapshot}, s.factory)
|
||||||
if t.errorExpected != "" {
|
if t.errorExpected != "" {
|
||||||
c.Check(err, ErrorMatches, t.errorExpected)
|
c.Check(err, ErrorMatches, t.errorExpected)
|
||||||
} else {
|
} else {
|
||||||
@@ -179,37 +210,45 @@ func (s *PublishedRepoSuite) TestPrefixNormalization(c *C) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *PublishedRepoSuite) TestDistributionComponentGuessing(c *C) {
|
func (s *PublishedRepoSuite) TestDistributionComponentGuessing(c *C) {
|
||||||
repo, err := NewPublishedRepo("ppa", "", "", nil, s.snapshot, s.factory)
|
repo, err := NewPublishedRepo("ppa", "", nil, []string{""}, []interface{}{s.snapshot}, s.factory)
|
||||||
c.Check(err, IsNil)
|
c.Check(err, IsNil)
|
||||||
c.Check(repo.Distribution, Equals, "squeeze")
|
c.Check(repo.Distribution, Equals, "squeeze")
|
||||||
c.Check(repo.Component, Equals, "main")
|
c.Check(repo.Components(), DeepEquals, []string{"main"})
|
||||||
|
|
||||||
repo, err = NewPublishedRepo("ppa", "wheezy", "", nil, s.snapshot, s.factory)
|
repo, err = NewPublishedRepo("ppa", "wheezy", nil, []string{""}, []interface{}{s.snapshot}, s.factory)
|
||||||
c.Check(err, IsNil)
|
c.Check(err, IsNil)
|
||||||
c.Check(repo.Distribution, Equals, "wheezy")
|
c.Check(repo.Distribution, Equals, "wheezy")
|
||||||
c.Check(repo.Component, Equals, "main")
|
c.Check(repo.Components(), DeepEquals, []string{"main"})
|
||||||
|
|
||||||
repo, err = NewPublishedRepo("ppa", "", "non-free", nil, s.snapshot, s.factory)
|
repo, err = NewPublishedRepo("ppa", "", nil, []string{"non-free"}, []interface{}{s.snapshot}, s.factory)
|
||||||
c.Check(err, IsNil)
|
c.Check(err, IsNil)
|
||||||
c.Check(repo.Distribution, Equals, "squeeze")
|
c.Check(repo.Distribution, Equals, "squeeze")
|
||||||
c.Check(repo.Component, Equals, "non-free")
|
c.Check(repo.Components(), DeepEquals, []string{"non-free"})
|
||||||
|
|
||||||
repo, err = NewPublishedRepo("ppa", "squeeze", "", nil, s.localRepo, s.factory)
|
repo, err = NewPublishedRepo("ppa", "squeeze", nil, []string{""}, []interface{}{s.localRepo}, s.factory)
|
||||||
c.Check(err, IsNil)
|
c.Check(err, IsNil)
|
||||||
c.Check(repo.Distribution, Equals, "squeeze")
|
c.Check(repo.Distribution, Equals, "squeeze")
|
||||||
c.Check(repo.Component, Equals, "main")
|
c.Check(repo.Components(), DeepEquals, []string{"main"})
|
||||||
|
|
||||||
repo, err = NewPublishedRepo("ppa", "", "main", nil, s.localRepo, s.factory)
|
repo, err = NewPublishedRepo("ppa", "", nil, []string{"main"}, []interface{}{s.localRepo}, s.factory)
|
||||||
c.Check(err, ErrorMatches, "unable to guess distribution name, please specify explicitly")
|
c.Check(err, ErrorMatches, "unable to guess distribution name, please specify explicitly")
|
||||||
|
|
||||||
s.localRepo.DefaultDistribution = "precise"
|
s.localRepo.DefaultDistribution = "precise"
|
||||||
s.localRepo.DefaultComponent = "contrib"
|
s.localRepo.DefaultComponent = "contrib"
|
||||||
s.factory.LocalRepoCollection().Update(s.localRepo)
|
s.factory.LocalRepoCollection().Update(s.localRepo)
|
||||||
|
|
||||||
repo, err = NewPublishedRepo("ppa", "", "", nil, s.localRepo, s.factory)
|
repo, err = NewPublishedRepo("ppa", "", nil, []string{""}, []interface{}{s.localRepo}, s.factory)
|
||||||
c.Check(err, IsNil)
|
c.Check(err, IsNil)
|
||||||
c.Check(repo.Distribution, Equals, "precise")
|
c.Check(repo.Distribution, Equals, "precise")
|
||||||
c.Check(repo.Component, Equals, "contrib")
|
c.Check(repo.Components(), DeepEquals, []string{"contrib"})
|
||||||
|
|
||||||
|
repo, err = NewPublishedRepo("ppa", "", nil, []string{"", "contrib"}, []interface{}{s.snapshot, s.snapshot2}, s.factory)
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
c.Check(repo.Distribution, Equals, "squeeze")
|
||||||
|
c.Check(repo.Components(), DeepEquals, []string{"contrib", "main"})
|
||||||
|
|
||||||
|
repo, err = NewPublishedRepo("ppa", "", nil, []string{"", ""}, []interface{}{s.snapshot, s.snapshot2}, s.factory)
|
||||||
|
c.Check(err, ErrorMatches, "duplicate component name: main")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PublishedRepoSuite) TestPublish(c *C) {
|
func (s *PublishedRepoSuite) TestPublish(c *C) {
|
||||||
@@ -245,6 +284,16 @@ func (s *PublishedRepoSuite) TestPublish(c *C) {
|
|||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(st, IsNil)
|
c.Assert(st, IsNil)
|
||||||
|
|
||||||
|
drf, err := os.Open(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/squeeze/main/binary-i386/Release"))
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
|
cfr = NewControlFileReader(drf)
|
||||||
|
st, err = cfr.ReadStanza()
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
|
c.Check(st["Archive"], Equals, "squeeze")
|
||||||
|
c.Check(st["Architecture"], Equals, "i386")
|
||||||
|
|
||||||
_, err = os.Stat(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/main/a/alien-arena/alien-arena-common_7.40-2_i386.deb"))
|
_, err = os.Stat(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/main/a/alien-arena/alien-arena-common_7.40-2_i386.deb"))
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
}
|
}
|
||||||
@@ -254,6 +303,7 @@ func (s *PublishedRepoSuite) TestPublishNoSigner(c *C) {
|
|||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/squeeze/Release"), PathExists)
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/squeeze/Release"), PathExists)
|
||||||
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/squeeze/main/binary-i386/Release"), PathExists)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PublishedRepoSuite) TestPublishLocalRepo(c *C) {
|
func (s *PublishedRepoSuite) TestPublishLocalRepo(c *C) {
|
||||||
@@ -261,25 +311,36 @@ func (s *PublishedRepoSuite) TestPublishLocalRepo(c *C) {
|
|||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/maverick/Release"), PathExists)
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/maverick/Release"), PathExists)
|
||||||
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/maverick/main/binary-i386/Release"), PathExists)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PublishedRepoSuite) TestPublishLocalSourceRepo(c *C) {
|
||||||
|
err := s.repo4.Publish(s.packagePool, s.publishedStorage, s.factory, nil, nil)
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/maverick/Release"), PathExists)
|
||||||
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/maverick/main/source/Release"), PathExists)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PublishedRepoSuite) TestString(c *C) {
|
func (s *PublishedRepoSuite) TestString(c *C) {
|
||||||
c.Check(s.repo.String(), Equals,
|
c.Check(s.repo.String(), Equals,
|
||||||
"ppa/squeeze (main) [] publishes [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze")
|
"ppa/squeeze [] publishes {main: [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze}")
|
||||||
c.Check(s.repo2.String(), Equals,
|
c.Check(s.repo2.String(), Equals,
|
||||||
"ppa/maverick (main) [] publishes [local1]: comment1")
|
"ppa/maverick [] publishes {main: [local1]: comment1}")
|
||||||
repo, _ := NewPublishedRepo("", "squeeze", "main", []string{"s390"}, s.snapshot, s.factory)
|
repo, _ := NewPublishedRepo("", "squeeze", []string{"s390"}, []string{"main"}, []interface{}{s.snapshot}, s.factory)
|
||||||
c.Check(repo.String(), Equals,
|
c.Check(repo.String(), Equals,
|
||||||
"./squeeze (main) [s390] publishes [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze")
|
"./squeeze [s390] publishes {main: [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze}")
|
||||||
repo, _ = NewPublishedRepo("", "squeeze", "main", []string{"i386", "amd64"}, s.snapshot, s.factory)
|
repo, _ = NewPublishedRepo("", "squeeze", []string{"i386", "amd64"}, []string{"main"}, []interface{}{s.snapshot}, s.factory)
|
||||||
c.Check(repo.String(), Equals,
|
c.Check(repo.String(), Equals,
|
||||||
"./squeeze (main) [i386, amd64] publishes [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze")
|
"./squeeze [i386, amd64] publishes {main: [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze}")
|
||||||
repo.Origin = "myorigin"
|
repo.Origin = "myorigin"
|
||||||
c.Check(repo.String(), Equals,
|
c.Check(repo.String(), Equals,
|
||||||
"./squeeze (main, origin: myorigin) [i386, amd64] publishes [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze")
|
"./squeeze (origin: myorigin) [i386, amd64] publishes {main: [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze}")
|
||||||
repo.Label = "mylabel"
|
repo.Label = "mylabel"
|
||||||
c.Check(repo.String(), Equals,
|
c.Check(repo.String(), Equals,
|
||||||
"./squeeze (main, origin: myorigin, label: mylabel) [i386, amd64] publishes [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze")
|
"./squeeze (origin: myorigin, label: mylabel) [i386, amd64] publishes {main: [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze}")
|
||||||
|
c.Check(s.repo3.String(), Equals,
|
||||||
|
"linux/natty [] publishes {contrib: [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze}, {main: [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze}")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PublishedRepoSuite) TestKey(c *C) {
|
func (s *PublishedRepoSuite) TestKey(c *C) {
|
||||||
@@ -287,7 +348,8 @@ func (s *PublishedRepoSuite) TestKey(c *C) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *PublishedRepoSuite) TestRefKey(c *C) {
|
func (s *PublishedRepoSuite) TestRefKey(c *C) {
|
||||||
c.Check(s.repo.RefKey(), DeepEquals, []byte("E"+s.repo.UUID))
|
c.Check(s.repo.RefKey(""), DeepEquals, []byte("E"+s.repo.UUID))
|
||||||
|
c.Check(s.repo.RefKey("main"), DeepEquals, []byte("E"+s.repo.UUID+"main"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PublishedRepoSuite) TestEncodeDecode(c *C) {
|
func (s *PublishedRepoSuite) TestEncodeDecode(c *C) {
|
||||||
@@ -295,7 +357,7 @@ func (s *PublishedRepoSuite) TestEncodeDecode(c *C) {
|
|||||||
repo := &PublishedRepo{}
|
repo := &PublishedRepo{}
|
||||||
err := repo.Decode(encoded)
|
err := repo.Decode(encoded)
|
||||||
|
|
||||||
s.repo.snapshot = nil
|
s.repo.sourceItems = nil
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(repo, DeepEquals, s.repo)
|
c.Assert(repo, DeepEquals, s.repo)
|
||||||
|
|
||||||
@@ -303,8 +365,7 @@ func (s *PublishedRepoSuite) TestEncodeDecode(c *C) {
|
|||||||
repo2 := &PublishedRepo{}
|
repo2 := &PublishedRepo{}
|
||||||
err = repo2.Decode(encoded2)
|
err = repo2.Decode(encoded2)
|
||||||
|
|
||||||
s.repo2.localRepo = nil
|
s.repo2.sourceItems = nil
|
||||||
s.repo2.packageRefs = nil
|
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(repo2, DeepEquals, s.repo2)
|
c.Assert(repo2, DeepEquals, s.repo2)
|
||||||
}
|
}
|
||||||
@@ -337,10 +398,10 @@ func (s *PublishedRepoCollectionSuite) SetUpTest(c *C) {
|
|||||||
s.localRepo = NewLocalRepo("local1", "comment1")
|
s.localRepo = NewLocalRepo("local1", "comment1")
|
||||||
s.factory.LocalRepoCollection().Add(s.localRepo)
|
s.factory.LocalRepoCollection().Add(s.localRepo)
|
||||||
|
|
||||||
s.repo1, _ = NewPublishedRepo("ppa", "anaconda", "main", []string{}, s.snap1, s.factory)
|
s.repo1, _ = NewPublishedRepo("ppa", "anaconda", []string{}, []string{"main"}, []interface{}{s.snap1}, s.factory)
|
||||||
s.repo2, _ = NewPublishedRepo("", "anaconda", "main", []string{}, s.snap2, s.factory)
|
s.repo2, _ = NewPublishedRepo("", "anaconda", []string{}, []string{"main", "contrib"}, []interface{}{s.snap2, s.snap1}, s.factory)
|
||||||
s.repo3, _ = NewPublishedRepo("ppa", "anaconda", "main", []string{}, s.snap2, s.factory)
|
s.repo3, _ = NewPublishedRepo("ppa", "anaconda", []string{}, []string{"main"}, []interface{}{s.snap2}, s.factory)
|
||||||
s.repo4, _ = NewPublishedRepo("ppa", "precise", "main", []string{}, s.localRepo, s.factory)
|
s.repo4, _ = NewPublishedRepo("ppa", "precise", []string{}, []string{"main"}, []interface{}{s.localRepo}, s.factory)
|
||||||
|
|
||||||
s.collection = s.factory.PublishedRepoCollection()
|
s.collection = s.factory.PublishedRepoCollection()
|
||||||
}
|
}
|
||||||
@@ -398,18 +459,61 @@ func (s *PublishedRepoCollectionSuite) TestUpdateLoadComplete(c *C) {
|
|||||||
collection := NewPublishedRepoCollection(s.db)
|
collection := NewPublishedRepoCollection(s.db)
|
||||||
r, err := collection.ByPrefixDistribution("ppa", "anaconda")
|
r, err := collection.ByPrefixDistribution("ppa", "anaconda")
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(r.snapshot, IsNil)
|
c.Assert(r.sourceItems["main"].snapshot, IsNil)
|
||||||
c.Assert(s.collection.LoadComplete(r, s.factory), IsNil)
|
c.Assert(s.collection.LoadComplete(r, s.factory), IsNil)
|
||||||
c.Assert(r.snapshot.UUID, Equals, s.repo1.snapshot.UUID)
|
c.Assert(r.Sources["main"], Equals, s.repo1.sourceItems["main"].snapshot.UUID)
|
||||||
c.Assert(r.RefList().Len(), Equals, 0)
|
c.Assert(r.RefList("main").Len(), Equals, 0)
|
||||||
|
|
||||||
r, err = collection.ByPrefixDistribution("ppa", "precise")
|
r, err = collection.ByPrefixDistribution("ppa", "precise")
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(r.localRepo, IsNil)
|
c.Assert(r.sourceItems["main"].localRepo, IsNil)
|
||||||
c.Assert(s.collection.LoadComplete(r, s.factory), IsNil)
|
c.Assert(s.collection.LoadComplete(r, s.factory), IsNil)
|
||||||
c.Assert(r.localRepo.UUID, Equals, s.repo4.localRepo.UUID)
|
c.Assert(r.sourceItems["main"].localRepo.UUID, Equals, s.repo4.sourceItems["main"].localRepo.UUID)
|
||||||
c.Assert(r.packageRefs.Len(), Equals, 0)
|
c.Assert(r.sourceItems["main"].packageRefs.Len(), Equals, 0)
|
||||||
c.Assert(r.RefList().Len(), Equals, 0)
|
c.Assert(r.RefList("main").Len(), Equals, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PublishedRepoCollectionSuite) TestLoadPre0_6(c *C) {
|
||||||
|
type oldPublishedRepo struct {
|
||||||
|
UUID string
|
||||||
|
Prefix string
|
||||||
|
Distribution string
|
||||||
|
Origin string
|
||||||
|
Label string
|
||||||
|
Architectures []string
|
||||||
|
SourceKind string
|
||||||
|
Component string
|
||||||
|
SourceUUID string `codec:"SnapshotUUID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
old := oldPublishedRepo{
|
||||||
|
UUID: s.repo1.UUID,
|
||||||
|
Prefix: "ppa",
|
||||||
|
Distribution: "anaconda",
|
||||||
|
Architectures: []string{"i386"},
|
||||||
|
SourceKind: "local",
|
||||||
|
Component: "contrib",
|
||||||
|
SourceUUID: s.localRepo.UUID,
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
encoder := codec.NewEncoder(&buf, &codec.MsgpackHandle{})
|
||||||
|
encoder.Encode(&old)
|
||||||
|
|
||||||
|
c.Assert(s.db.Put(s.repo1.Key(), buf.Bytes()), IsNil)
|
||||||
|
c.Assert(s.db.Put(s.repo1.RefKey(""), s.localRepo.RefList().Encode()), IsNil)
|
||||||
|
|
||||||
|
collection := NewPublishedRepoCollection(s.db)
|
||||||
|
repo, err := collection.ByPrefixDistribution("ppa", "anaconda")
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
c.Check(repo.Component, Equals, "")
|
||||||
|
c.Check(repo.SourceUUID, Equals, "")
|
||||||
|
c.Check(repo.Sources, DeepEquals, map[string]string{"contrib": s.localRepo.UUID})
|
||||||
|
|
||||||
|
c.Check(collection.LoadComplete(repo, s.factory), IsNil)
|
||||||
|
c.Check(repo.sourceItems["contrib"].localRepo.UUID, Equals, s.localRepo.UUID)
|
||||||
|
c.Check(repo.RefList("contrib").Len(), Equals, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PublishedRepoCollectionSuite) TestForEachAndLen(c *C) {
|
func (s *PublishedRepoCollectionSuite) TestForEachAndLen(c *C) {
|
||||||
@@ -437,7 +541,7 @@ func (s *PublishedRepoCollectionSuite) TestBySnapshot(c *C) {
|
|||||||
c.Check(s.collection.Add(s.repo1), IsNil)
|
c.Check(s.collection.Add(s.repo1), IsNil)
|
||||||
c.Check(s.collection.Add(s.repo2), IsNil)
|
c.Check(s.collection.Add(s.repo2), IsNil)
|
||||||
|
|
||||||
c.Check(s.collection.BySnapshot(s.snap1), DeepEquals, []*PublishedRepo{s.repo1})
|
c.Check(s.collection.BySnapshot(s.snap1), DeepEquals, []*PublishedRepo{s.repo1, s.repo2})
|
||||||
c.Check(s.collection.BySnapshot(s.snap2), DeepEquals, []*PublishedRepo{s.repo2})
|
c.Check(s.collection.BySnapshot(s.snap2), DeepEquals, []*PublishedRepo{s.repo2})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -472,10 +576,10 @@ func (s *PublishedRepoRemoveSuite) SetUpTest(c *C) {
|
|||||||
|
|
||||||
s.snapshotCollection.Add(s.snap1)
|
s.snapshotCollection.Add(s.snap1)
|
||||||
|
|
||||||
s.repo1, _ = NewPublishedRepo("ppa", "anaconda", "main", []string{}, s.snap1, s.factory)
|
s.repo1, _ = NewPublishedRepo("ppa", "anaconda", []string{}, []string{"main"}, []interface{}{s.snap1}, s.factory)
|
||||||
s.repo2, _ = NewPublishedRepo("", "anaconda", "main", []string{}, s.snap1, s.factory)
|
s.repo2, _ = NewPublishedRepo("", "anaconda", []string{}, []string{"main"}, []interface{}{s.snap1}, s.factory)
|
||||||
s.repo3, _ = NewPublishedRepo("ppa", "meduza", "main", []string{}, s.snap1, s.factory)
|
s.repo3, _ = NewPublishedRepo("ppa", "meduza", []string{}, []string{"main"}, []interface{}{s.snap1}, s.factory)
|
||||||
s.repo4, _ = NewPublishedRepo("ppa", "osminog", "contrib", []string{}, s.snap1, s.factory)
|
s.repo4, _ = NewPublishedRepo("ppa", "osminog", []string{}, []string{"contrib"}, []interface{}{s.snap1}, s.factory)
|
||||||
|
|
||||||
s.collection = s.factory.PublishedRepoCollection()
|
s.collection = s.factory.PublishedRepoCollection()
|
||||||
s.collection.Add(s.repo1)
|
s.collection.Add(s.repo1)
|
||||||
@@ -499,7 +603,7 @@ func (s *PublishedRepoRemoveSuite) TearDownTest(c *C) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *PublishedRepoRemoveSuite) TestRemoveFilesOnlyDist(c *C) {
|
func (s *PublishedRepoRemoveSuite) TestRemoveFilesOnlyDist(c *C) {
|
||||||
s.repo1.RemoveFiles(s.publishedStorage, false, false, nil)
|
s.repo1.RemoveFiles(s.publishedStorage, false, []string{}, nil)
|
||||||
|
|
||||||
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), Not(PathExists))
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), Not(PathExists))
|
||||||
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), PathExists)
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), PathExists)
|
||||||
@@ -511,7 +615,7 @@ func (s *PublishedRepoRemoveSuite) TestRemoveFilesOnlyDist(c *C) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *PublishedRepoRemoveSuite) TestRemoveFilesWithPool(c *C) {
|
func (s *PublishedRepoRemoveSuite) TestRemoveFilesWithPool(c *C) {
|
||||||
s.repo1.RemoveFiles(s.publishedStorage, false, true, nil)
|
s.repo1.RemoveFiles(s.publishedStorage, false, []string{"main"}, nil)
|
||||||
|
|
||||||
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), Not(PathExists))
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), Not(PathExists))
|
||||||
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), PathExists)
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), PathExists)
|
||||||
@@ -522,8 +626,20 @@ func (s *PublishedRepoRemoveSuite) TestRemoveFilesWithPool(c *C) {
|
|||||||
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "pool/main"), PathExists)
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "pool/main"), PathExists)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *PublishedRepoRemoveSuite) TestRemoveFilesWithTwoPools(c *C) {
|
||||||
|
s.repo1.RemoveFiles(s.publishedStorage, false, []string{"main", "contrib"}, nil)
|
||||||
|
|
||||||
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), Not(PathExists))
|
||||||
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), PathExists)
|
||||||
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/osminog"), PathExists)
|
||||||
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/main"), Not(PathExists))
|
||||||
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/pool/contrib"), Not(PathExists))
|
||||||
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "dists/anaconda"), PathExists)
|
||||||
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "pool/main"), PathExists)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *PublishedRepoRemoveSuite) TestRemoveFilesWithPrefix(c *C) {
|
func (s *PublishedRepoRemoveSuite) TestRemoveFilesWithPrefix(c *C) {
|
||||||
s.repo1.RemoveFiles(s.publishedStorage, true, true, nil)
|
s.repo1.RemoveFiles(s.publishedStorage, true, []string{"main"}, nil)
|
||||||
|
|
||||||
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), Not(PathExists))
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), Not(PathExists))
|
||||||
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), Not(PathExists))
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), Not(PathExists))
|
||||||
@@ -535,7 +651,7 @@ func (s *PublishedRepoRemoveSuite) TestRemoveFilesWithPrefix(c *C) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *PublishedRepoRemoveSuite) TestRemoveFilesWithPrefixRoot(c *C) {
|
func (s *PublishedRepoRemoveSuite) TestRemoveFilesWithPrefixRoot(c *C) {
|
||||||
s.repo2.RemoveFiles(s.publishedStorage, true, true, nil)
|
s.repo2.RemoveFiles(s.publishedStorage, true, []string{"main"}, nil)
|
||||||
|
|
||||||
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), PathExists)
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/anaconda"), PathExists)
|
||||||
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), PathExists)
|
c.Check(filepath.Join(s.publishedStorage.PublicPath(), "ppa/dists/meduza"), PathExists)
|
||||||
|
|||||||
+12
-9
@@ -194,26 +194,29 @@ func (l *PackageRefList) Diff(r *PackageRefList, packageCollection *PackageColle
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// is pl & pr the same package, but different version?
|
|
||||||
if pl.Name == pr.Name && pl.Architecture == pr.Architecture {
|
|
||||||
result = append(result, PackageDiff{Left: pl, Right: pr})
|
|
||||||
il++
|
|
||||||
ir++
|
|
||||||
pl, pr = nil, nil
|
|
||||||
} else {
|
|
||||||
// otherwise pl or pr is missing on one of the sides
|
// otherwise pl or pr is missing on one of the sides
|
||||||
if rel < 0 {
|
if rel < 0 {
|
||||||
|
// compaction: +(,A) -(B,) --> !(A,B)
|
||||||
|
if len(result) > 0 && result[len(result)-1].Left == nil && result[len(result)-1].Right.Name == pl.Name &&
|
||||||
|
result[len(result)-1].Right.Architecture == pl.Architecture {
|
||||||
|
result[len(result)-1] = PackageDiff{Left: pl, Right: result[len(result)-1].Right}
|
||||||
|
} else {
|
||||||
result = append(result, PackageDiff{Left: pl, Right: nil})
|
result = append(result, PackageDiff{Left: pl, Right: nil})
|
||||||
|
}
|
||||||
il++
|
il++
|
||||||
pl = nil
|
pl = nil
|
||||||
|
} else {
|
||||||
|
// compaction: -(A,) +(,B) --> !(A,B)
|
||||||
|
if len(result) > 0 && result[len(result)-1].Right == nil && result[len(result)-1].Left.Name == pr.Name &&
|
||||||
|
result[len(result)-1].Left.Architecture == pr.Architecture {
|
||||||
|
result[len(result)-1] = PackageDiff{Left: result[len(result)-1].Left, Right: pr}
|
||||||
} else {
|
} else {
|
||||||
result = append(result, PackageDiff{Left: nil, Right: pr})
|
result = append(result, PackageDiff{Left: nil, Right: pr})
|
||||||
|
}
|
||||||
ir++
|
ir++
|
||||||
pr = nil
|
pr = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ func (s *PackageRefListSuite) SetUpTest(c *C) {
|
|||||||
stanza["Package"] = "mars-invaders"
|
stanza["Package"] = "mars-invaders"
|
||||||
s.p3 = NewPackageFromControlFile(stanza)
|
s.p3 = NewPackageFromControlFile(stanza)
|
||||||
stanza = packageStanza.Copy()
|
stanza = packageStanza.Copy()
|
||||||
stanza["Size"] = "42"
|
stanza["Source"] = "unknown-planet"
|
||||||
s.p4 = NewPackageFromControlFile(stanza)
|
s.p4 = NewPackageFromControlFile(stanza)
|
||||||
stanza = packageStanza.Copy()
|
stanza = packageStanza.Copy()
|
||||||
stanza["Package"] = "lonely-strangers"
|
stanza["Package"] = "lonely-strangers"
|
||||||
|
|||||||
+11
-6
@@ -13,6 +13,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -66,9 +67,11 @@ func NewRemoteRepo(name string, archiveRoot string, distribution string, compone
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if result.Distribution == "." || result.Distribution == "./" {
|
if strings.HasSuffix(result.Distribution, "/") || strings.HasPrefix(result.Distribution, ".") {
|
||||||
// flat repo
|
// flat repo
|
||||||
result.Distribution = ""
|
if !strings.HasPrefix(result.Distribution, ".") {
|
||||||
|
result.Distribution = "./" + result.Distribution
|
||||||
|
}
|
||||||
result.Architectures = nil
|
result.Architectures = nil
|
||||||
if len(result.Components) > 0 {
|
if len(result.Components) > 0 {
|
||||||
return nil, fmt.Errorf("components aren't supported for flat repos")
|
return nil, fmt.Errorf("components aren't supported for flat repos")
|
||||||
@@ -106,7 +109,9 @@ func (repo *RemoteRepo) String() string {
|
|||||||
|
|
||||||
// IsFlat determines if repository is flat
|
// IsFlat determines if repository is flat
|
||||||
func (repo *RemoteRepo) IsFlat() bool {
|
func (repo *RemoteRepo) IsFlat() bool {
|
||||||
return repo.Distribution == ""
|
// aptly < 0.5.1 had Distribution = "" for flat repos
|
||||||
|
// aptly >= 0.5.1 had Distribution = "./[path]/" for flat repos
|
||||||
|
return repo.Distribution == "" || (strings.HasPrefix(repo.Distribution, ".") && strings.HasSuffix(repo.Distribution, "/"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// NumPackages return number of packages retrived from remote repo
|
// NumPackages return number of packages retrived from remote repo
|
||||||
@@ -129,7 +134,7 @@ func (repo *RemoteRepo) ReleaseURL(name string) *url.URL {
|
|||||||
if !repo.IsFlat() {
|
if !repo.IsFlat() {
|
||||||
path = &url.URL{Path: fmt.Sprintf("dists/%s/%s", repo.Distribution, name)}
|
path = &url.URL{Path: fmt.Sprintf("dists/%s/%s", repo.Distribution, name)}
|
||||||
} else {
|
} else {
|
||||||
path = &url.URL{Path: name}
|
path = &url.URL{Path: filepath.Join(repo.Distribution, name)}
|
||||||
}
|
}
|
||||||
|
|
||||||
return repo.archiveRootURL.ResolveReference(path)
|
return repo.archiveRootURL.ResolveReference(path)
|
||||||
@@ -137,13 +142,13 @@ func (repo *RemoteRepo) ReleaseURL(name string) *url.URL {
|
|||||||
|
|
||||||
// FlatBinaryURL returns URL to Packages files for flat repo
|
// FlatBinaryURL returns URL to Packages files for flat repo
|
||||||
func (repo *RemoteRepo) FlatBinaryURL() *url.URL {
|
func (repo *RemoteRepo) FlatBinaryURL() *url.URL {
|
||||||
path := &url.URL{Path: "Packages"}
|
path := &url.URL{Path: filepath.Join(repo.Distribution, "Packages")}
|
||||||
return repo.archiveRootURL.ResolveReference(path)
|
return repo.archiveRootURL.ResolveReference(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FlatSourcesURL returns URL to Sources files for flat repo
|
// FlatSourcesURL returns URL to Sources files for flat repo
|
||||||
func (repo *RemoteRepo) FlatSourcesURL() *url.URL {
|
func (repo *RemoteRepo) FlatSourcesURL() *url.URL {
|
||||||
path := &url.URL{Path: "Sources"}
|
path := &url.URL{Path: filepath.Join(repo.Distribution, "Sources")}
|
||||||
return repo.archiveRootURL.ResolveReference(path)
|
return repo.archiveRootURL.ResolveReference(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -101,10 +101,15 @@ func (s *RemoteRepoSuite) TestInvalidURL(c *C) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *RemoteRepoSuite) TestFlatCreation(c *C) {
|
func (s *RemoteRepoSuite) TestFlatCreation(c *C) {
|
||||||
c.Check(s.flat.Distribution, Equals, "")
|
c.Check(s.flat.IsFlat(), Equals, true)
|
||||||
|
c.Check(s.flat.Distribution, Equals, "./")
|
||||||
c.Check(s.flat.Architectures, IsNil)
|
c.Check(s.flat.Architectures, IsNil)
|
||||||
c.Check(s.flat.Components, IsNil)
|
c.Check(s.flat.Components, IsNil)
|
||||||
|
|
||||||
|
flat2, _ := NewRemoteRepo("flat2", "http://pkg.jenkins-ci.org/debian-stable", "binary/", []string{}, []string{}, false)
|
||||||
|
c.Check(flat2.IsFlat(), Equals, true)
|
||||||
|
c.Check(flat2.Distribution, Equals, "./binary/")
|
||||||
|
|
||||||
_, err := NewRemoteRepo("fl", "http://some.repo/", "./", []string{"main"}, []string{}, false)
|
_, err := NewRemoteRepo("fl", "http://some.repo/", "./", []string{"main"}, []string{}, false)
|
||||||
c.Check(err, ErrorMatches, "components aren't supported for flat repos")
|
c.Check(err, ErrorMatches, "components aren't supported for flat repos")
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -51,7 +51,12 @@ func NewDownloader(threads int, progress aptly.Progress) aptly.Downloader {
|
|||||||
unpause: make(chan bool),
|
unpause: make(chan bool),
|
||||||
threads: threads,
|
threads: threads,
|
||||||
progress: progress,
|
progress: progress,
|
||||||
client: &http.Client{Transport: &http.Transport{DisableCompression: true}},
|
client: &http.Client{
|
||||||
|
Transport: &http.Transport{
|
||||||
|
DisableCompression: true,
|
||||||
|
Proxy: http.ProxyFromEnvironment,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < downloader.threads; i++ {
|
for i := 0; i < downloader.threads; i++ {
|
||||||
|
|||||||
+67
-5
@@ -1,7 +1,7 @@
|
|||||||
.\" generated with Ronn/v0.7.3
|
.\" generated with Ronn/v0.7.3
|
||||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||||
.
|
.
|
||||||
.TH "APTLY" "1" "April 2014" "" ""
|
.TH "APTLY" "1" "June 2014" "" ""
|
||||||
.
|
.
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
\fBaptly\fR \- Debian repository management tool
|
\fBaptly\fR \- Debian repository management tool
|
||||||
@@ -166,7 +166,7 @@ when processing dependencies, follow Suggests
|
|||||||
\fBaptly\fR \fBmirror\fR \fBcreate\fR \fIname\fR \fIarchive url\fR \fIdistribution\fR [\fIcomponent1\fR \|\.\|\.\|\.]
|
\fBaptly\fR \fBmirror\fR \fBcreate\fR \fIname\fR \fIarchive url\fR \fIdistribution\fR [\fIcomponent1\fR \|\.\|\.\|\.]
|
||||||
.
|
.
|
||||||
.P
|
.P
|
||||||
Creates mirror \fIname\fR of remote repository, aptly supports both regular and flat Debian repositories exported via HTTP\. aptly would try download Release file from remote repository and verify its\(cq signature\.
|
Creates mirror \fIname\fR of remote repository, aptly supports both regular and flat Debian repositories exported via HTTP\. aptly would try download Release file from remote repository and verify its\(cq signature\. Command line format resembles apt utlitily sources\.list(5)\.
|
||||||
.
|
.
|
||||||
.P
|
.P
|
||||||
PPA urls could specified in short format:
|
PPA urls could specified in short format:
|
||||||
@@ -662,6 +662,10 @@ Options:
|
|||||||
\-\fBlatest\fR=false
|
\-\fBlatest\fR=false
|
||||||
use only the latest version of each package
|
use only the latest version of each package
|
||||||
.
|
.
|
||||||
|
.TP
|
||||||
|
\-\fBno\-remove\fR=false
|
||||||
|
don\(cqt remove duplicate arch/name packages
|
||||||
|
.
|
||||||
.SH "DELETE SNAPSHOT"
|
.SH "DELETE SNAPSHOT"
|
||||||
\fBaptly\fR \fBsnapshot\fR \fBdrop\fR \fIname\fR
|
\fBaptly\fR \fBsnapshot\fR \fBdrop\fR \fIname\fR
|
||||||
.
|
.
|
||||||
@@ -740,6 +744,19 @@ display list in machine\-readable format
|
|||||||
Command publishes current state of local repository ready to be consumed by apt tools\. Published repostiories appear under rootDir/public directory\. Valid GPG key is required for publishing\.
|
Command publishes current state of local repository ready to be consumed by apt tools\. Published repostiories appear under rootDir/public directory\. Valid GPG key is required for publishing\.
|
||||||
.
|
.
|
||||||
.P
|
.P
|
||||||
|
Multiple component repository could be published by specifying several components split by commas via \-component flag and multiple local repositories as the arguments:
|
||||||
|
.
|
||||||
|
.IP "" 4
|
||||||
|
.
|
||||||
|
.nf
|
||||||
|
|
||||||
|
aptly publish repo \-component=main,contrib repo\-main repo\-contrib
|
||||||
|
.
|
||||||
|
.fi
|
||||||
|
.
|
||||||
|
.IP "" 0
|
||||||
|
.
|
||||||
|
.P
|
||||||
It is not recommended to publish local repositories directly unless the repository is for testing purposes and changes happen frequently\. For production usage please take snapshot of repository and publish it using publish snapshot command\.
|
It is not recommended to publish local repositories directly unless the repository is for testing purposes and changes happen frequently\. For production usage please take snapshot of repository and publish it using publish snapshot command\.
|
||||||
.
|
.
|
||||||
.P
|
.P
|
||||||
@@ -760,7 +777,7 @@ Options:
|
|||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
\-\fBcomponent\fR=
|
\-\fBcomponent\fR=
|
||||||
component name to publish
|
component name to publish (for multi\-component publishing, separate components with commas)
|
||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
\-\fBdistribution\fR=
|
\-\fBdistribution\fR=
|
||||||
@@ -797,6 +814,19 @@ don\(cqt sign Release files with GPG
|
|||||||
Command publishes snapshot as Debian repository ready to be consumed by apt tools\. Published repostiories appear under rootDir/public directory\. Valid GPG key is required for publishing\.
|
Command publishes snapshot as Debian repository ready to be consumed by apt tools\. Published repostiories appear under rootDir/public directory\. Valid GPG key is required for publishing\.
|
||||||
.
|
.
|
||||||
.P
|
.P
|
||||||
|
Multiple component repository could be published by specifying several components split by commas via \-component flag and multiple snapshots as the arguments:
|
||||||
|
.
|
||||||
|
.IP "" 4
|
||||||
|
.
|
||||||
|
.nf
|
||||||
|
|
||||||
|
aptly publish snapshot \-component=main,contrib snap\-main snap\-contrib
|
||||||
|
.
|
||||||
|
.fi
|
||||||
|
.
|
||||||
|
.IP "" 0
|
||||||
|
.
|
||||||
|
.P
|
||||||
Example:
|
Example:
|
||||||
.
|
.
|
||||||
.IP "" 4
|
.IP "" 4
|
||||||
@@ -814,7 +844,7 @@ Options:
|
|||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
\-\fBcomponent\fR=
|
\-\fBcomponent\fR=
|
||||||
component name to publish
|
component name to publish (for multi\-component publishing, separate components with commas)
|
||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
\-\fBdistribution\fR=
|
\-\fBdistribution\fR=
|
||||||
@@ -851,6 +881,19 @@ don\(cqt sign Release files with GPG
|
|||||||
Command switches in\-place published repository with new snapshot contents\. All publishing parameters are preserved (architecture list, distribution, component)\.
|
Command switches in\-place published repository with new snapshot contents\. All publishing parameters are preserved (architecture list, distribution, component)\.
|
||||||
.
|
.
|
||||||
.P
|
.P
|
||||||
|
For multiple component repositories, flag \-component should be given with list of components to update\. Corresponding snapshots should be given in the same order, e\.g\.:
|
||||||
|
.
|
||||||
|
.IP "" 4
|
||||||
|
.
|
||||||
|
.nf
|
||||||
|
|
||||||
|
aptly publish update \-component=main,contrib wheezy wh\-main wh\-contrib
|
||||||
|
.
|
||||||
|
.fi
|
||||||
|
.
|
||||||
|
.IP "" 0
|
||||||
|
.
|
||||||
|
.P
|
||||||
Example:
|
Example:
|
||||||
.
|
.
|
||||||
.IP "" 4
|
.IP "" 4
|
||||||
@@ -867,6 +910,10 @@ $ aptly publish update wheezy ppa wheezy\-7\.5
|
|||||||
Options:
|
Options:
|
||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
|
\-\fBcomponent\fR=
|
||||||
|
component names to update (for multi\-component publishing, separate components with commas)
|
||||||
|
.
|
||||||
|
.TP
|
||||||
\-\fBgpg\-key\fR=
|
\-\fBgpg\-key\fR=
|
||||||
GPG key ID to use when signing the release
|
GPG key ID to use when signing the release
|
||||||
.
|
.
|
||||||
@@ -889,6 +936,9 @@ don\(cqt sign Release files with GPG
|
|||||||
Command re\-publishes (updates) published local repository\. \fIdistribution\fR and \fIprefix\fR should be occupied with local repository published using command aptly publish repo\. Update happens in\-place with minimum possible downtime for published repository\.
|
Command re\-publishes (updates) published local repository\. \fIdistribution\fR and \fIprefix\fR should be occupied with local repository published using command aptly publish repo\. Update happens in\-place with minimum possible downtime for published repository\.
|
||||||
.
|
.
|
||||||
.P
|
.P
|
||||||
|
For multiple component published repositories, all local repositories are updated\.
|
||||||
|
.
|
||||||
|
.P
|
||||||
Example:
|
Example:
|
||||||
.
|
.
|
||||||
.IP "" 4
|
.IP "" 4
|
||||||
@@ -979,7 +1029,19 @@ $ aptly graph
|
|||||||
If environment variable \fBHTTP_PROXY\fR is set \fBaptly\fR would use its value to proxy all HTTP requests\.
|
If environment variable \fBHTTP_PROXY\fR is set \fBaptly\fR would use its value to proxy all HTTP requests\.
|
||||||
.
|
.
|
||||||
.SH "RETURN VALUES"
|
.SH "RETURN VALUES"
|
||||||
\fBaptly\fR exists with 0 on success and with 1 on failure\.
|
\fBaptly\fR exists with:
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
0
|
||||||
|
success
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
1
|
||||||
|
general failure
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
2
|
||||||
|
command parse failure
|
||||||
.
|
.
|
||||||
.SH "AUTHORS"
|
.SH "AUTHORS"
|
||||||
Andrey Smirnov (me@smira\.ru)
|
Andrey Smirnov (me@smira\.ru)
|
||||||
|
|||||||
+10
-1
@@ -139,7 +139,16 @@ to proxy all HTTP requests.
|
|||||||
|
|
||||||
## RETURN VALUES
|
## RETURN VALUES
|
||||||
|
|
||||||
`aptly` exists with 0 on success and with 1 on failure.
|
`aptly` exists with:
|
||||||
|
|
||||||
|
* 0:
|
||||||
|
success
|
||||||
|
|
||||||
|
* 1:
|
||||||
|
general failure
|
||||||
|
|
||||||
|
* 2:
|
||||||
|
command parse failure
|
||||||
|
|
||||||
## AUTHORS
|
## AUTHORS
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Version: GnuPG v1.4.9 (GNU/Linux)
|
||||||
|
|
||||||
|
mQGiBEmFQG0RBACXScOxb6BTV6rQE/tcJopAEWsdvmE0jNIRWjDDzB7HovX6Anrq
|
||||||
|
n7+Vq4spAReSFbBVaYiiOx2cGDymj2dyx2i9NAI/9/cQXJOU+RPdDzHVlO1Edksp
|
||||||
|
5rKn0cGPWY5sLxRf8s/tO5oyKgwCVgTaB5a8gBHaoGms3nNC4YYf+lqlpwCgjbti
|
||||||
|
3u1iMIx6Rs+dG0+xw1oi5FUD/2tLJMx7vCUQHhPRupeYFPoD8vWpcbGb5nHfHi4U
|
||||||
|
8/x4qZspAIwvXtGw0UBHildGpqe9onp22Syadn/7JgMWhHoFw5Ke/rTMlxREL7pa
|
||||||
|
TiXuagD2G84tjJ66oJP1FigslJzrnG61y85V7THL61OFqDg6IOP4onbsdqHby4VD
|
||||||
|
zZj9A/9uQxIn5250AGLNpARStAcNPJNJbHOQuv0iF3vnG8uO7/oscB0TYb8/juxr
|
||||||
|
hs9GdSN0U0BxENR+8KWy5lttpqLMKlKRknQYy34UstQiyFgAQ9Epncu9uIbVDgWt
|
||||||
|
y7utnqXN033EyYkcWx5EhLAgHkC7wSzeSWABV3JSXN7CeeOif7QiS29oc3VrZSBL
|
||||||
|
YXdhZ3VjaGkgPGtrQGtvaHN1a2Uub3JnPohjBBMRAgAjAhsDBgsJCAcDAgQVAggD
|
||||||
|
BBYCAwECHgECF4AFAko/7vYCGQEACgkQm30y8tUFguabhgCgi54IQR4rpJZ/uUHe
|
||||||
|
ZB879zUWTQwAniQDBO+Zly7Fsvm0Mcvqvl02UzxCtC1Lb2hzdWtlIEthd2FndWNo
|
||||||
|
aSA8a29oc3VrZS5rYXdhZ3VjaGlAc3VuLmNvbT6IYAQTEQIAIAUCSj/qbQIbAwYL
|
||||||
|
CQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJEJt9MvLVBYLm38gAoIGR2+TQeJaCeEa8
|
||||||
|
CQhZYzDoiJkQAJ0cpmD+0VA+leOAr5LEccNVd70Z/dHNy83JARAAAQEAAAAAAAAA
|
||||||
|
AAAAAAD/2P/gABBKRklGAAEBAQBgAGAAAP/hAGBFeGlmAABJSSoACAAAAAQAMQEC
|
||||||
|
ABkAAAA+AAAAEFEBAAEAAAABQ5AAEVEEAAEAAAASCwAAElEEAAEAAAASCwAAAAAA
|
||||||
|
AE1hY3JvbWVkaWEgRmlyZXdvcmtzIDQuMAAA/9sAQwAIBgYHBgUIBwcHCQkICgwU
|
||||||
|
DQwLCwwZEhMPFB0aHx4dGhwcICQuJyAiLCMcHCg3KSwwMTQ0NB8nOT04MjwuMzQy
|
||||||
|
/9sAQwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy
|
||||||
|
MjIyMjIyMjIyMjIyMjIyMjIyMjIy/8AAEQgArgCWAwEiAAIRAQMRAf/EAB8AAAEF
|
||||||
|
AQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQEC
|
||||||
|
AwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
|
||||||
|
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqS
|
||||||
|
k5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk
|
||||||
|
5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkK
|
||||||
|
C//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGx
|
||||||
|
wQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFla
|
||||||
|
Y2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2
|
||||||
|
t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQAC
|
||||||
|
EQMRAD8A9wEj/wB9vzpfMf8Avt+dRinCpGSeY398/nS72/vH86YKBQBJvb+8fzpd
|
||||||
|
7f3j+dMFLQA/e394/nS7j6n86ZSimA7cfU07cfU1HnFOFADtx9aXJ9TTKUUxD8n1
|
||||||
|
pc+9Mp1AC5ozSUtAC0maKKADNFJ2ooAoCnCmilzWZQ6lFJSimAopaQUtAC54rOvN
|
||||||
|
dsLCTZPPGrdwXAry/wCKHxXfRppND0Mq16Bie5PIi9lHdv5V8/X+rXt/O8tzcyyy
|
||||||
|
MclnYkk0avYdl1PqPxT8VtH8NwqwzdXEuSkaHoB61wjftCXhlzHosBjHZpSCa8PW
|
||||||
|
O7uhuAkcDueaaYbhOqMMe1L5lcvWx9U+FPjJ4f8AEU0dpdhtLvXOFWdgY3PoH6fg
|
||||||
|
cV6MrZGa+EklIOJOPqK9i+G3xem0TytI8QSSXGnHCQXJO57f2Pqn6indrclq+x9G
|
||||||
|
5pwNVoLiO4hSaGRZIpFDKynIYHuKmBqyB+aWmg0uaAFopKKAFoozRQBQFLSUorMo
|
||||||
|
UUtJSigB1ZHijWovD/hu+1KZlUQxErnu3YfnWsK8k+Pt60PhaxtAxAnuOQO4UE0P
|
||||||
|
YaWp8/Xd1LeTz3Mzl5pnLuxPJJNa+i+HDclZZ1yp5C1Q0axa+1BEx8i8mvS7S3WG
|
||||||
|
NQo6elcWLxDprljuelgsOp+/IgtdCiVFVYx07CnXHhyNgflA/Ct+1BwOKmkVq8xS
|
||||||
|
m9bnr2S0sec6n4UVo2KKNw6Vx9xby2U3lSAj617NcR5J4zmua1/Q4r+1JVQJU5Ui
|
||||||
|
uzD4qUXyz2OHFYWM1zR3Ol+CHj0xXX/CKajMTHKd1g7H7r94/oeo9wR3r3tWr4ht
|
||||||
|
pZtNv4bmElZ7eVZUIOPmU5/pX2dpOpR6tpFnqMQxHdQpMoz03DOK9ePY8OaszUDU
|
||||||
|
+oFNSg0yUOopKWgAoo6mikBRpwptLWZY4UoptLTELXin7QbD7PoiFv45Gx+Ar2uv
|
||||||
|
FP2g7dfsejXOfm8x48evGf6UmNbnm3hCBls57sJuYnYg9TXSyW2uIgNpJbs5GWDj
|
||||||
|
gewrP8EJu0XIHKyNV2+j1txM0MzIQV8oIQN3POSenHTg15VSV6z2+Z7dGNqKt26G
|
||||||
|
hpeo6rC3lajZxKOgdG6/hW5NcoIC4HOOhrmbJb1IokuZWkfbmUsQQGz2xW5OAbAE
|
||||||
|
Y3d/es5TtJo6oRbjcx7uXVryXbblIIv723JqN9PuUdLhJ2aQf6xW6OP6VBqS6jcQ
|
||||||
|
sLS4aOQHCqH2qVx64znP8verWn2d/DKrPOzxbFBWQ5O7HJyOxParv7t7oxcfeasz
|
||||||
|
z3xBaC01uZV4RxvAr6X+F0rv8NdCMj7iICAfQBjgV87+NYzHr6jHHlA/rX0H8LFa
|
||||||
|
P4baLu3DMTHDDtvOPwr1sM7xR4mK0m/U7lTUyniqyGp1NbtHOmSUuaaDS1JQuaKS
|
||||||
|
ikBTpaQUVmUOpabS0xC15f8AF7wxc+IEsJI3VI4Nyrkfxtjn6YH616hWL4ptDd6B
|
||||||
|
cBTh0+cH0xUVL8j5dzSk0prm2PD/AAnYvp+ltazDbNHM6yD3BrpEiWToOKzPLktr
|
||||||
|
mRiSwlO7J9atQ3bFsCvGnJSlzM+gpLlXKJcpDAegGT+ZqYgPYAgVnz3DpKW8pJW6
|
||||||
|
AM2MUranci38vy4gBz/9alGF3dG0ppKzZYs0ilB4BwauOixggVlW9w8sivsWJuhC
|
||||||
|
nOanmun83bimtNCZPS5g6/osOta3Zq8giRImMjeoyMAe5Oa940SxTStFsbCM/JbQ
|
||||||
|
JGv0AryTTLRLzXIwwDOWVAvfGecCvZx19q9fAttPyPBzCyatuyyhqZTxVdDU612M
|
||||||
|
4ESg04GowacDUFjqKQc0UDKlLSUtZFC0UUCmAtMmiSeF4pBlHBVh7U6imI878Y+G
|
||||||
|
rbTbGC7tFf5WKyFmz1rimZoy2wZJGQBXter2C6lpc9qw++vy/XtXiMoe3upLeTiS
|
||||||
|
Nipry8XSUJJpaHq4Os5JpvUoC4uJr1rYIkJC7vMuGCgj2rZ/4Ry/aHzvtdltO4Ei
|
||||||
|
TPTH+NUrhFlUB1yQODVB8RjyRboR6hiAfqM4rCLTPR6aSt8rktzJc2l7HZgRXLOu
|
||||||
|
4SQPkKPU1fUtu3SHJUc/WqlvGIULKo3kdhgCr+lwfb9ZtLItxLIAx9upp25pKKMq
|
||||||
|
klFN3PTfDenR2mjWbtEvnsm8sVG4buevXpit1aiUAcAYHapVr6GMVGKij5iUnKTk
|
||||||
|
ydKnU1ClSikwRIKcD60wU4GpLQ7PpRSUUhlaikpc1kWLRSUUxC5ozSZozTA5Txn8
|
||||||
|
QtF8DxRDUDLPeTDdFaQAFyucbiTwo+vXsK8huNZHiVJddtbY2/mysfJL7iAD0JwM
|
||||||
|
1h/F+X7V8RtUKybzEUj5PTCjj8KseD2S304WbzxPJ9/CsDjcM4/DvXLjF+6TXc7M
|
||||||
|
F/EafY1YNThkVcttccMpqY3trtx8ufeoJbK3acrLECPcUsmj2EUYfyw27kcmvOjY
|
||||||
|
9NuS6kc+pxp8seWc8Koq7pWox+HLiHWdQSR0gO90jALYxjAzjnmsxbnTbCXMssMK
|
||||||
|
r6nk/h1rH17xLY3lpJa25dw4wWxgfrW9KnOU04owqziotSZ7r4S8daT4xFwunpcR
|
||||||
|
S24DPHOoBweMjBOa6pDXzn8JNej0nxdFbSKqwX6/ZtzHG1s5U59yMfjX0SpwcGvc
|
||||||
|
Wp4MlZltDUoNV42qYGpYIlFOzUYNOBqSx4opBzRSArUtNqrqWqWOj2D32pXcVrap
|
||||||
|
96WVsDPoO5PsOayNC5TXkWKJpZHVI0GWd2AVR7k9K8Z8R/HTazweHNPBHQXd4Ovu
|
||||||
|
sY/9mP4V5Trvi7XPETltW1S4uVzkRM2I1+iDCj8qtRYWPfvEXxh8L6GJIrWZ9Vu1
|
||||||
|
48u1/wBWD7yHj8s15Jr/AMYfFGtyOlvdDS7c5xFZnace7n5j+n0rz1n3Hmmk4zzV
|
||||||
|
KKFcdNPI7s0jM7sxZmY5LE9ST61CsrI25SQR3BwacWzwRUZX0qiblgaheq25bucH
|
||||||
|
18w086tqDrta9uCvp5hqng56UDmp5I9iueXcmDsxyzEn1JqROvNQKD7VKCqDJOas
|
||||||
|
kuRuMgjp711+n/FHxVpyIsWqNPHEAojukWQEe5PP61wvnEj0B4ApykZJJ7UDPfvD
|
||||||
|
Hxp0+/dLfXbYWMp4E8RLxH6jqv616laXtve26XFrPFPC/KyRsGU/iK+MBICcDitn
|
||||||
|
QPFWseHbvztMv5YM/eTOUb6qeDRcXKj7CV8ing1434V+NtpezR2niC3W0Y8fa4cm
|
||||||
|
PP8AtL1H1Ga9atrqG6gSe3mjmhcZSSNgysPYikTZouCiow4xRRYLmRr+tW/h7Qrv
|
||||||
|
Vbkbo7dCwQHBdugUfU4r5Y8TeKtV8Tak15qlwztk+XEDiOFf7qL2H6nvXr3x01n7
|
||||||
|
Po2n6SjfNcymaQf7K8D9T+leBzPuT3H8qiC0NHoNeYnvURc4phPNITmrJuLu5pSa
|
||||||
|
Z3pRyKYhM80oOaaetAoAkzwKTd6Cm5pBQA8EnqTijOSeOKaT2oHSgY7cTTg1Rilp
|
||||||
|
AS7/AGpc4UA96iHJApXbk0wJ0kOeDXTeGPGer+GbtZNOunWMnLwscxv9V/ya5T7q
|
||||||
|
D1NOEhQYHU9/Siw0z7A8KeJ7XxToceo2ymNs7JoicmNx1HuOcg0V5j8A9RQnWNKl
|
||||||
|
lVARHcruOOfut/7LRTViJaPQ5b42agbrx29uGytrAiAehPJ/nXmrNu2H14NdD481
|
||||||
|
A6j401S6zkPMQPoOP6VzQOcj0OaiGxctxpNA5obqfrQKokSlWkzQDzQAMOaSnN1F
|
||||||
|
JQAtFFFAAKKKO9AC0UlGaBj0HemjlvrTkOEY03vQIe7YJP4CkTBfn6mkbkA/Wkzg
|
||||||
|
YHU9aYGtpl7Pau8kEzxMwwShwcUVUtWIU4oqbXLTFv3M0jSkksWJP481SU/Pk1Ym
|
||||||
|
b7/1FViMY96diWKwy5+tITTm+7mo6BC0DrR2oHWgB7dBTac3SmUALS0lKOtACUua
|
||||||
|
KKACm0vSk70ASLxF9TSYzznrQf8AVqKTPH40wHHHQfjTM55pTwp9+KQdKALEL7Is
|
||||||
|
+poph4Cr6Cigdz//2YhgBBMRAgAgBQJKP/cgAhsDBgsJCAcDAgQVAggDBBYCAwEC
|
||||||
|
HgECF4AACgkQm30y8tUFgua3awCdFQlChLgn/n4tb4jLe1RgxOxHxosAn2Cn2oNh
|
||||||
|
sZ91wUb4d5JuH88TCupsuQINBEmFQG0QCADqAXWgiis4yi96os3QZmK5809ojjTT
|
||||||
|
nlICgbztrT55cMVTDBc9SneyRQlC0cS+M1z4Do6lj81sNJdJiBPqTYYA1+exTFvs
|
||||||
|
5zCxPInDP3hvqXxHTP142XN1hdzt53R7smn8O0wyO+RCBUb44e9NkusvBd5UP3Je
|
||||||
|
449hnpXJ4WO3cVMFm4ghxs7ERlpAi5NTEsVVdM8dqHbZJtk8gbzdAHH0ybiAXmWy
|
||||||
|
LFGZDuuKiFAkqm/Wled7id6N+cPx107dwBclwPxzfEYKEqJ1YDDHoDlyfx4012y1
|
||||||
|
53e5sGyah/IPBYrrLMfG+Wmiwr5nCX0tmwOcyukuE94hbzJCX2wBdbWLAAMGCACz
|
||||||
|
l3cuM4lGt/wr5liM4gotXpZAopY+EnbLIBuOHFXXR7HnyAgST1jH/AUbafvPjyDh
|
||||||
|
EkFDyUP14XtHNIAqsN1UpuyYbM90bMPAWXJxrazMsSF+Tv5yIxHiy4cc1pjoqHA2
|
||||||
|
kwqIGHmTxYzOPOS19ZWQAtevoTE6pCARphY0dzpscCWaXGs/ZqNAhjL96WLYV1Oo
|
||||||
|
Ut+9mTnOcs6Vuxaxp2wN2S5DK1S9gdIxWEc8wMUPiQe8CYk0OySdORIblMs3bGqD
|
||||||
|
FoM5HcBAZP1YlXitPH2nIRv0DtOQGMQOCkqUWmQuQAUgKV+YO86lO4S7EhTET/GP
|
||||||
|
sQb6P7efm/Cs8wbq/wyIiEkEGBECAAkFAkmFQG0CGwwACgkQm30y8tUFgua2mACe
|
||||||
|
JNBW4snDC4OzjKU6QT386/GA9ssAn3vLzSwn8N1xv5MihWGr5kVzvaE2
|
||||||
|
=cjdq
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
+4
-1
@@ -77,6 +77,7 @@ class BaseTest(object):
|
|||||||
"ppaCodename": "",
|
"ppaCodename": "",
|
||||||
}
|
}
|
||||||
configOverride = {}
|
configOverride = {}
|
||||||
|
environmentOverride = {}
|
||||||
|
|
||||||
fixtureDBDir = os.path.join(os.environ["HOME"], "aptly-fixture-db")
|
fixtureDBDir = os.path.join(os.environ["HOME"], "aptly-fixture-db")
|
||||||
fixturePoolDir = os.path.join(os.environ["HOME"], "aptly-fixture-pool")
|
fixturePoolDir = os.path.join(os.environ["HOME"], "aptly-fixture-pool")
|
||||||
@@ -135,7 +136,8 @@ class BaseTest(object):
|
|||||||
self.run_cmd(["gpg", "--no-default-keyring", "--trust-model", "always", "--batch", "--keyring", "aptlytest.gpg", "--import",
|
self.run_cmd(["gpg", "--no-default-keyring", "--trust-model", "always", "--batch", "--keyring", "aptlytest.gpg", "--import",
|
||||||
os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "debian-archive-keyring.gpg"),
|
os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "debian-archive-keyring.gpg"),
|
||||||
os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "launchpad.key"),
|
os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "launchpad.key"),
|
||||||
os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "flat.key")])
|
os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "flat.key"),
|
||||||
|
os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "jenkins.key")])
|
||||||
|
|
||||||
if hasattr(self, "fixtureCmds"):
|
if hasattr(self, "fixtureCmds"):
|
||||||
for cmd in self.fixtureCmds:
|
for cmd in self.fixtureCmds:
|
||||||
@@ -160,6 +162,7 @@ class BaseTest(object):
|
|||||||
command = shlex.split(command)
|
command = shlex.split(command)
|
||||||
environ = os.environ.copy()
|
environ = os.environ.copy()
|
||||||
environ["LC_ALL"] = "C"
|
environ["LC_ALL"] = "C"
|
||||||
|
environ.update(self.environmentOverride)
|
||||||
proc = subprocess.Popen(command, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, env=environ)
|
proc = subprocess.Popen(command, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, env=environ)
|
||||||
output, _ = proc.communicate()
|
output, _ = proc.communicate()
|
||||||
#print "CMD %s: %.2f" % (" ".join(command), time.time()-start)
|
#print "CMD %s: %.2f" % (" ".join(command), time.time()-start)
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
aptly version: 0.5
|
aptly version: 0.6
|
||||||
|
|||||||
@@ -21,3 +21,4 @@ Options:
|
|||||||
-dep-follow-recommends=false: when processing dependencies, follow Recommends
|
-dep-follow-recommends=false: when processing dependencies, follow Recommends
|
||||||
-dep-follow-source=false: when processing dependencies, follow from binary to Source packages
|
-dep-follow-source=false: when processing dependencies, follow from binary to Source packages
|
||||||
-dep-follow-suggests=false: when processing dependencies, follow Suggests
|
-dep-follow-suggests=false: when processing dependencies, follow Suggests
|
||||||
|
ERROR: unable to parse command
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
Usage: aptly mirror create <name> <archive url> <distribution> [<component1> ...]
|
Usage: aptly mirror create <name> <archive url> <distribution> [<component1> ...]
|
||||||
|
|
||||||
Creates mirror <name> of remote repository, aptly supports both regular and flat Debian repositories exported
|
Creates mirror <name> of remote repository, aptly supports both regular and flat Debian repositories exported
|
||||||
via HTTP. aptly would try download Release file from remote repository and verify its' signature.
|
via HTTP. aptly would try download Release file from remote repository and verify its' signature. Command
|
||||||
|
line format resembles apt utlitily sources.list(5).
|
||||||
|
|
||||||
PPA urls could specified in short format:
|
PPA urls could specified in short format:
|
||||||
|
|
||||||
|
|||||||
@@ -13,3 +13,4 @@ Options:
|
|||||||
-ignore-signatures=false: disable verification of Release file signatures
|
-ignore-signatures=false: disable verification of Release file signatures
|
||||||
-keyring=: gpg keyring to use when verifying Release file (could be specified multiple times)
|
-keyring=: gpg keyring to use when verifying Release file (could be specified multiple times)
|
||||||
-with-sources=false: download source packages in addition to binary packages
|
-with-sources=false: download source packages in addition to binary packages
|
||||||
|
ERROR: unable to parse command
|
||||||
|
|||||||
@@ -18,3 +18,4 @@ Options:
|
|||||||
-dep-follow-recommends=false: when processing dependencies, follow Recommends
|
-dep-follow-recommends=false: when processing dependencies, follow Recommends
|
||||||
-dep-follow-source=false: when processing dependencies, follow from binary to Source packages
|
-dep-follow-source=false: when processing dependencies, follow from binary to Source packages
|
||||||
-dep-follow-suggests=false: when processing dependencies, follow Suggests
|
-dep-follow-suggests=false: when processing dependencies, follow Suggests
|
||||||
|
ERROR: unable to parse command
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
flag provided but not defined: -fxz
|
||||||
|
Usage: aptly mirror create <name> <archive url> <distribution> [<component1> ...]
|
||||||
|
|
||||||
|
aptly mirror create - create new mirror
|
||||||
|
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-architectures="": list of architectures to consider during (comma-separated), default to all available
|
||||||
|
-config="": location of configuration file (default locations are /etc/aptly.conf, ~/.aptly.conf)
|
||||||
|
-dep-follow-all-variants=false: when processing dependencies, follow a & b if depdency is 'a|b'
|
||||||
|
-dep-follow-recommends=false: when processing dependencies, follow Recommends
|
||||||
|
-dep-follow-source=false: when processing dependencies, follow from binary to Source packages
|
||||||
|
-dep-follow-suggests=false: when processing dependencies, follow Suggests
|
||||||
|
-ignore-signatures=false: disable verification of Release file signatures
|
||||||
|
-keyring=: gpg keyring to use when verifying Release file (could be specified multiple times)
|
||||||
|
-with-sources=false: download source packages in addition to binary packages
|
||||||
|
ERROR: unable to parse flags
|
||||||
@@ -10,6 +10,7 @@ class MainTest(BaseTest):
|
|||||||
"""
|
"""
|
||||||
main
|
main
|
||||||
"""
|
"""
|
||||||
|
expectedCode = 2
|
||||||
runCmd = "aptly"
|
runCmd = "aptly"
|
||||||
|
|
||||||
outputMatchPrepare = lambda _, s: re.sub(r' -(cpuprofile|memprofile|memstats|meminterval)=.*\n', '', s, flags=re.MULTILINE)
|
outputMatchPrepare = lambda _, s: re.sub(r' -(cpuprofile|memprofile|memstats|meminterval)=.*\n', '', s, flags=re.MULTILINE)
|
||||||
@@ -19,6 +20,7 @@ class MirrorTest(BaseTest):
|
|||||||
"""
|
"""
|
||||||
main
|
main
|
||||||
"""
|
"""
|
||||||
|
expectedCode = 2
|
||||||
runCmd = "aptly mirror"
|
runCmd = "aptly mirror"
|
||||||
|
|
||||||
|
|
||||||
@@ -26,6 +28,7 @@ class MirrorCreateTest(BaseTest):
|
|||||||
"""
|
"""
|
||||||
main
|
main
|
||||||
"""
|
"""
|
||||||
|
expectedCode = 2
|
||||||
runCmd = "aptly mirror create"
|
runCmd = "aptly mirror create"
|
||||||
|
|
||||||
|
|
||||||
@@ -50,3 +53,11 @@ class MirrorCreateHelpTest(BaseTest):
|
|||||||
main
|
main
|
||||||
"""
|
"""
|
||||||
runCmd = "aptly help mirror create"
|
runCmd = "aptly help mirror create"
|
||||||
|
|
||||||
|
|
||||||
|
class WrongFlagTest(BaseTest):
|
||||||
|
"""
|
||||||
|
main
|
||||||
|
"""
|
||||||
|
expectedCode = 2
|
||||||
|
runCmd = "aptly mirror create -fxz=sss"
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ Information from release file:
|
|||||||
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
|
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
|
||||||
Codename: wheezy
|
Codename: wheezy
|
||||||
Components: main contrib non-free
|
Components: main contrib non-free
|
||||||
Date: Sat, 08 Feb 2014 10:36:03 UTC
|
Date: Sat, 26 Apr 2014 09:27:11 UTC
|
||||||
Description: Debian 7.4 Released 08 February 2014
|
Description: Debian 7.5 Released 26 April 2014
|
||||||
|
|
||||||
Label: Debian
|
Label: Debian
|
||||||
Origin: Debian
|
Origin: Debian
|
||||||
Suite: stable
|
Suite: stable
|
||||||
Version: 7.4
|
Version: 7.5
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Name: mirror14
|
Name: mirror14
|
||||||
Archive Root URL: http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/
|
Archive Root URL: http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/
|
||||||
Distribution:
|
Distribution: ./
|
||||||
Components:
|
Components:
|
||||||
Architectures:
|
Architectures:
|
||||||
Download Sources: no
|
Download Sources: no
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ Information from release file:
|
|||||||
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
|
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
|
||||||
Codename: wheezy
|
Codename: wheezy
|
||||||
Components: main contrib non-free
|
Components: main contrib non-free
|
||||||
Date: Sat, 08 Feb 2014 10:36:03 UTC
|
Date: Sat, 26 Apr 2014 09:27:11 UTC
|
||||||
Description: Debian 7.4 Released 08 February 2014
|
Description: Debian 7.5 Released 26 April 2014
|
||||||
|
|
||||||
Label: Debian
|
Label: Debian
|
||||||
Origin: Debian
|
Origin: Debian
|
||||||
Suite: stable
|
Suite: stable
|
||||||
Version: 7.4
|
Version: 7.5
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ Information from release file:
|
|||||||
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
|
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
|
||||||
Codename: wheezy
|
Codename: wheezy
|
||||||
Components: main contrib non-free
|
Components: main contrib non-free
|
||||||
Date: Sat, 08 Feb 2014 10:36:03 UTC
|
Date: Sat, 26 Apr 2014 09:27:11 UTC
|
||||||
Description: Debian 7.4 Released 08 February 2014
|
Description: Debian 7.5 Released 26 April 2014
|
||||||
|
|
||||||
Label: Debian
|
Label: Debian
|
||||||
Origin: Debian
|
Origin: Debian
|
||||||
Suite: stable
|
Suite: stable
|
||||||
Version: 7.4
|
Version: 7.5
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Downloading http://security.debian.org/dists/wheezy/updates/InRelease...
|
||||||
|
Downloading http://security.debian.org/dists/wheezy/updates/Release...
|
||||||
|
ERROR: unable to fetch mirror: Get http://security.debian.org/dists/wheezy/updates/Release: http: error connecting to proxy http://127.0.0.1:3137: dial tcp 127.0.0.1:3137: connection refused
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
Downloading http://pkg.jenkins-ci.org/debian-stable/binary/InRelease...
|
||||||
|
Downloading http://pkg.jenkins-ci.org/debian-stable/binary/Release...
|
||||||
|
Downloading http://pkg.jenkins-ci.org/debian-stable/binary/Release.gpg...
|
||||||
|
gpgv: DSA key ID D50582E6
|
||||||
|
gpgv: Good signature from "Kohsuke Kawaguchi <kk@kohsuke.org>"
|
||||||
|
gpgv: aka "Kohsuke Kawaguchi <kohsuke.kawaguchi@sun.com>"
|
||||||
|
gpgv: aka "[invalid image]"
|
||||||
|
|
||||||
|
Mirror [mirror21]: http://pkg.jenkins-ci.org/debian-stable/ ./binary/ successfully added.
|
||||||
|
You can run 'aptly mirror update mirror21' to download repository contents.
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
Name: mirror21
|
||||||
|
Archive Root URL: http://pkg.jenkins-ci.org/debian-stable/
|
||||||
|
Distribution: ./binary/
|
||||||
|
Components:
|
||||||
|
Architectures:
|
||||||
|
Download Sources: no
|
||||||
|
Last update: never
|
||||||
|
|
||||||
|
Information from release file:
|
||||||
|
Architectures: all
|
||||||
|
Date: Fri, 30 May 2014 07:36:11 UTC
|
||||||
|
Origin: jenkins-ci.org
|
||||||
|
Suite: binary
|
||||||
@@ -10,10 +10,10 @@ Information from release file:
|
|||||||
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
|
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
|
||||||
Codename: wheezy
|
Codename: wheezy
|
||||||
Components: main contrib non-free
|
Components: main contrib non-free
|
||||||
Date: Sat, 08 Feb 2014 10:36:03 UTC
|
Date: Sat, 26 Apr 2014 09:27:11 UTC
|
||||||
Description: Debian 7.4 Released 08 February 2014
|
Description: Debian 7.5 Released 26 April 2014
|
||||||
|
|
||||||
Label: Debian
|
Label: Debian
|
||||||
Origin: Debian
|
Origin: Debian
|
||||||
Suite: stable
|
Suite: stable
|
||||||
Version: 7.4
|
Version: 7.5
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ Information from release file:
|
|||||||
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
|
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
|
||||||
Codename: wheezy
|
Codename: wheezy
|
||||||
Components: main contrib non-free
|
Components: main contrib non-free
|
||||||
Date: Sat, 08 Feb 2014 10:36:03 UTC
|
Date: Sat, 26 Apr 2014 09:27:11 UTC
|
||||||
Description: Debian 7.4 Released 08 February 2014
|
Description: Debian 7.5 Released 26 April 2014
|
||||||
|
|
||||||
Label: Debian
|
Label: Debian
|
||||||
Origin: Debian
|
Origin: Debian
|
||||||
Suite: stable
|
Suite: stable
|
||||||
Version: 7.4
|
Version: 7.5
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ Information from release file:
|
|||||||
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
|
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
|
||||||
Codename: wheezy
|
Codename: wheezy
|
||||||
Components: main contrib non-free
|
Components: main contrib non-free
|
||||||
Date: Sat, 08 Feb 2014 10:36:03 UTC
|
Date: Sat, 26 Apr 2014 09:27:11 UTC
|
||||||
Description: Debian 7.4 Released 08 February 2014
|
Description: Debian 7.5 Released 26 April 2014
|
||||||
|
|
||||||
Label: Debian
|
Label: Debian
|
||||||
Origin: Debian
|
Origin: Debian
|
||||||
Suite: stable
|
Suite: stable
|
||||||
Version: 7.4
|
Version: 7.5
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ Information from release file:
|
|||||||
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
|
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
|
||||||
Codename: wheezy
|
Codename: wheezy
|
||||||
Components: main contrib non-free
|
Components: main contrib non-free
|
||||||
Date: Sat, 08 Feb 2014 10:36:03 UTC
|
Date: Sat, 26 Apr 2014 09:27:11 UTC
|
||||||
Description: Debian 7.4 Released 08 February 2014
|
Description: Debian 7.5 Released 26 April 2014
|
||||||
|
|
||||||
Label: Debian
|
Label: Debian
|
||||||
Origin: Debian
|
Origin: Debian
|
||||||
Suite: stable
|
Suite: stable
|
||||||
Version: 7.4
|
Version: 7.5
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
|
|
||||||
|
|
||||||
Building download queue...
|
Building download queue...
|
||||||
Download queue: 28 items (11.04 MiB)
|
Download queue: 30 items (11.70 MiB)
|
||||||
Downloading & parsing package files...
|
Downloading & parsing package files...
|
||||||
Downloading http://repo.varnish-cache.org/debian/dists/wheezy/Release...
|
Downloading http://repo.varnish-cache.org/debian/dists/wheezy/Release...
|
||||||
Downloading http://repo.varnish-cache.org/debian/dists/wheezy/varnish-3.0/binary-amd64/Packages.bz2...
|
Downloading http://repo.varnish-cache.org/debian/dists/wheezy/varnish-3.0/binary-amd64/Packages.bz2...
|
||||||
Downloading http://repo.varnish-cache.org/debian/dists/wheezy/varnish-3.0/binary-i386/Packages.bz2...
|
Downloading http://repo.varnish-cache.org/debian/dists/wheezy/varnish-3.0/binary-i386/Packages.bz2...
|
||||||
Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish-agent/varnish-agent_2.2.0~wheezy_amd64.deb...
|
Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish-agent/varnish-agent_2.2.0~wheezy_amd64.deb...
|
||||||
Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish-agent/varnish-agent_2.2.0~wheezy_i386.deb...
|
Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish-agent/varnish-agent_2.2.0~wheezy_i386.deb...
|
||||||
|
Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish-agent/varnish-agent_2.2.1~wheezy_amd64.deb...
|
||||||
|
Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish-agent/varnish-agent_2.2.1~wheezy_i386.deb...
|
||||||
Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi-dev_3.0.3-1~wheezy_amd64.deb...
|
Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi-dev_3.0.3-1~wheezy_amd64.deb...
|
||||||
Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi-dev_3.0.3-1~wheezy_i386.deb...
|
Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi-dev_3.0.3-1~wheezy_i386.deb...
|
||||||
Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi-dev_3.0.4-1~wheezy_amd64.deb...
|
Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi-dev_3.0.4-1~wheezy_amd64.deb...
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ class CreateMirror18Test(BaseTest):
|
|||||||
|
|
||||||
class CreateMirror19Test(BaseTest):
|
class CreateMirror19Test(BaseTest):
|
||||||
"""
|
"""
|
||||||
create mirror: mirror with / in components
|
create mirror: mirror with / in distribution
|
||||||
"""
|
"""
|
||||||
fixtureGpg = True
|
fixtureGpg = True
|
||||||
outputMatchPrepare = lambda _, s: re.sub(r'Signature made .* using', '', s)
|
outputMatchPrepare = lambda _, s: re.sub(r'Signature made .* using', '', s)
|
||||||
@@ -224,3 +224,30 @@ class CreateMirror19Test(BaseTest):
|
|||||||
|
|
||||||
self.check_output()
|
self.check_output()
|
||||||
self.check_cmd_output("aptly mirror show mirror19", "mirror_show", match_prepare=removeDates)
|
self.check_cmd_output("aptly mirror show mirror19", "mirror_show", match_prepare=removeDates)
|
||||||
|
|
||||||
|
|
||||||
|
class CreateMirror20Test(BaseTest):
|
||||||
|
"""
|
||||||
|
create mirror: using failing HTTP_PROXY
|
||||||
|
"""
|
||||||
|
fixtureGpg = True
|
||||||
|
|
||||||
|
runCmd = "aptly -architectures='i386' mirror create -keyring=aptlytest.gpg -with-sources mirror20 http://security.debian.org/ wheezy/updates main"
|
||||||
|
environmentOverride = {"HTTP_PROXY": "127.0.0.1:3137"}
|
||||||
|
expectedCode = 1
|
||||||
|
|
||||||
|
|
||||||
|
class CreateMirror21Test(BaseTest):
|
||||||
|
"""
|
||||||
|
create mirror: flat repository in subdir
|
||||||
|
"""
|
||||||
|
runCmd = "aptly mirror create -keyring=aptlytest.gpg mirror21 http://pkg.jenkins-ci.org/debian-stable binary/"
|
||||||
|
fixtureGpg = True
|
||||||
|
outputMatchPrepare = lambda _, s: re.sub(r'Signature made .* using', '', s)
|
||||||
|
|
||||||
|
def check(self):
|
||||||
|
def removeSHA512(s):
|
||||||
|
return re.sub(r"SHA512: .+\n", "", s)
|
||||||
|
|
||||||
|
self.check_output()
|
||||||
|
self.check_cmd_output("aptly mirror show mirror21", "mirror_show", match_prepare=removeSHA512)
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
Snapshot `snap1` is published currently:
|
Snapshot `snap1` is published currently:
|
||||||
* ./maverick (main) [amd64, i386] publishes [snap1]: Snapshot from mirror [gnuplot-maverick]: http://ppa.launchpad.net/gladky-anton/gnuplot/ubuntu/ maverick
|
* ./maverick [amd64, i386] publishes {main: [snap1]: Snapshot from mirror [gnuplot-maverick]: http://ppa.launchpad.net/gladky-anton/gnuplot/ubuntu/ maverick}
|
||||||
ERROR: unable to drop: snapshot is published
|
ERROR: unable to drop: snapshot is published
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
Snapshot `snap1` is published currently:
|
Snapshot `snap1` is published currently:
|
||||||
* ./maverick (main) [amd64, i386] publishes [snap1]: Snapshot from mirror [gnuplot-maverick]: http://ppa.launchpad.net/gladky-anton/gnuplot/ubuntu/ maverick
|
* ./maverick [amd64, i386] publishes {main: [snap1]: Snapshot from mirror [gnuplot-maverick]: http://ppa.launchpad.net/gladky-anton/gnuplot/ubuntu/ maverick}
|
||||||
ERROR: unable to drop: snapshot is published
|
ERROR: unable to drop: snapshot is published
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
|||||||
|
ERROR: -no-remove and -latest can't be specified together
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
Snapshot snap4 successfully created.
|
||||||
|
You can run 'aptly publish snapshot snap4' to publish snapshot as Debian repository.
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -136,3 +136,51 @@ class MergeSnapshot8Test(BaseTest):
|
|||||||
]
|
]
|
||||||
runCmd = "aptly snapshot diff snap4 snap5"
|
runCmd = "aptly snapshot diff snap4 snap5"
|
||||||
expectedCode = 0
|
expectedCode = 0
|
||||||
|
|
||||||
|
|
||||||
|
class MergeSnapshot9Test(BaseTest):
|
||||||
|
"""
|
||||||
|
merge snapshots: -no-remove
|
||||||
|
"""
|
||||||
|
fixtureDB = True
|
||||||
|
fixtureCmds = [
|
||||||
|
"aptly snapshot create snap1 from mirror wheezy-main",
|
||||||
|
"aptly snapshot create snap2 from mirror wheezy-non-free",
|
||||||
|
"aptly snapshot create snap3 from mirror wheezy-backports",
|
||||||
|
]
|
||||||
|
runCmd = "aptly snapshot merge -no-remove snap4 snap1 snap2 snap3"
|
||||||
|
expectedCode = 0
|
||||||
|
|
||||||
|
def check(self):
|
||||||
|
def remove_created_at(s):
|
||||||
|
return re.sub(r"Created At: [0-9:A-Za-z -]+\n", "", s)
|
||||||
|
|
||||||
|
self.check_output()
|
||||||
|
self.check_cmd_output("aptly snapshot show -with-packages snap4", "snapshot_show", match_prepare=remove_created_at)
|
||||||
|
|
||||||
|
|
||||||
|
class MergeSnapshot10Test(BaseTest):
|
||||||
|
"""
|
||||||
|
merge snapshots: compare -no-remove and regular
|
||||||
|
"""
|
||||||
|
fixtureDB = True
|
||||||
|
fixtureCmds = [
|
||||||
|
"aptly snapshot create snap1 from mirror wheezy-main",
|
||||||
|
"aptly snapshot create snap2 from mirror wheezy-non-free",
|
||||||
|
"aptly snapshot create snap3 from mirror wheezy-backports",
|
||||||
|
"aptly snapshot merge snap4 snap3 snap2 snap1",
|
||||||
|
"aptly snapshot merge -no-remove snap5 snap3 snap2 snap1",
|
||||||
|
]
|
||||||
|
runCmd = "aptly snapshot diff snap4 snap5"
|
||||||
|
expectedCode = 0
|
||||||
|
|
||||||
|
|
||||||
|
class MergeSnapshot11Test(BaseTest):
|
||||||
|
"""
|
||||||
|
merge snapshots: -no-remove & -latest conflict
|
||||||
|
"""
|
||||||
|
fixtureCmds = [
|
||||||
|
"aptly snapshot create snap1 empty"
|
||||||
|
]
|
||||||
|
runCmd = "aptly snapshot merge -no-remove -latest snap2 snap1"
|
||||||
|
expectedCode = 1
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Removing ${HOME}/.aptly/public/dists/sq1...
|
Removing ${HOME}/.aptly/public/dists/sq1...
|
||||||
Cleaning up prefix "." component "main"...
|
Cleaning up prefix "." components main...
|
||||||
|
|
||||||
Published repository has been removed successfully.
|
Published repository has been removed successfully.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Removing ${HOME}/.aptly/public/dists/sq2...
|
Removing ${HOME}/.aptly/public/dists/sq2...
|
||||||
Cleaning up prefix "." component "main"...
|
Cleaning up prefix "." components main...
|
||||||
|
|
||||||
Published repository has been removed successfully.
|
Published repository has been removed successfully.
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
Published repositories:
|
Published repositories:
|
||||||
* ./maverick (main) [amd64, i386] publishes [snap1]: Snapshot from mirror [gnuplot-maverick]: http://ppa.launchpad.net/gladky-anton/gnuplot/ubuntu/ maverick
|
* ./maverick [amd64, i386] publishes {main: [snap1]: Snapshot from mirror [gnuplot-maverick]: http://ppa.launchpad.net/gladky-anton/gnuplot/ubuntu/ maverick}
|
||||||
* ppa/smira/wheezy (contrib) [amd64] publishes [snap2]: Merged from sources: 'snap1'
|
* ppa/maverick [amd64, i386] publishes {contrib: [snap2]: Merged from sources: 'snap1'}, {main: [snap1]: Snapshot from mirror [gnuplot-maverick]: http://ppa.launchpad.net/gladky-anton/gnuplot/ubuntu/ maverick}
|
||||||
* ppa/tr1/maverick (main, origin: origin1) [amd64, i386] publishes [snap2]: Merged from sources: 'snap1'
|
* ppa/smira/wheezy [amd64] publishes {contrib: [snap2]: Merged from sources: 'snap1'}
|
||||||
* ppa/tr2/maverick (main, label: label1) [amd64, i386] publishes [snap2]: Merged from sources: 'snap1'
|
* ppa/tr1/maverick (origin: origin1) [amd64, i386] publishes {main: [snap2]: Merged from sources: 'snap1'}
|
||||||
|
* ppa/tr2/maverick (label: label1) [amd64, i386] publishes {main: [snap2]: Merged from sources: 'snap1'}
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
|
Warning: publishing from empty source, architectures list should be complete, it can't be changed after publishing (use -architectures flag)
|
||||||
Loading packages...
|
Loading packages...
|
||||||
ERROR: unable to publish: source is empty
|
ERROR: unable to publish: unable to figure out list of architectures, please supply explicit list
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
Warning: publishing from empty source, architectures list should be complete, it can't be changed after publishing (use -architectures flag)
|
||||||
|
Loading packages...
|
||||||
|
Generating metadata files and linking package files...
|
||||||
|
Signing file '${HOME}/.aptly/public/dists/maverick/Release' with gpg, please enter your passphrase when prompted:
|
||||||
|
Clearsigning file '${HOME}/.aptly/public/dists/maverick/Release' with gpg, please enter your passphrase when prompted:
|
||||||
|
|
||||||
|
Local repo local-repo has been successfully published.
|
||||||
|
Please setup your webserver to serve directory '${HOME}/.aptly/public' with autoindexing.
|
||||||
|
Now you can add following line to apt sources:
|
||||||
|
deb http://your-server/ maverick main
|
||||||
|
deb-src http://your-server/ maverick main
|
||||||
|
Don't forget to add your GPG key to apt with apt-key.
|
||||||
|
|
||||||
|
You can also use `aptly serve` to publish your repositories over HTTP quickly.
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
Loading packages...
|
||||||
|
Generating metadata files and linking package files...
|
||||||
|
Signing file '${HOME}/.aptly/public/dists/maverick/Release' with gpg, please enter your passphrase when prompted:
|
||||||
|
Clearsigning file '${HOME}/.aptly/public/dists/maverick/Release' with gpg, please enter your passphrase when prompted:
|
||||||
|
|
||||||
|
Local repos repo1, repo2 have been successfully published.
|
||||||
|
Please setup your webserver to serve directory '${HOME}/.aptly/public' with autoindexing.
|
||||||
|
Now you can add following line to apt sources:
|
||||||
|
deb http://your-server/ maverick contrib main
|
||||||
|
deb-src http://your-server/ maverick contrib main
|
||||||
|
Don't forget to add your GPG key to apt with apt-key.
|
||||||
|
|
||||||
|
You can also use `aptly serve` to publish your repositories over HTTP quickly.
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
Origin: . maverick
|
||||||
|
Label: . maverick
|
||||||
|
Codename: maverick
|
||||||
|
Architectures: i386
|
||||||
|
Components: contrib main
|
||||||
|
Description: Generated by aptly
|
||||||
|
MD5Sum:
|
||||||
|
SHA1:
|
||||||
|
SHA256:
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
Loading packages...
|
||||||
|
Generating metadata files and linking package files...
|
||||||
|
Signing file '${HOME}/.aptly/public/dists/squeeze/Release' with gpg, please enter your passphrase when prompted:
|
||||||
|
Clearsigning file '${HOME}/.aptly/public/dists/squeeze/Release' with gpg, please enter your passphrase when prompted:
|
||||||
|
|
||||||
|
Local repos repo1, repo2 have been successfully published.
|
||||||
|
Please setup your webserver to serve directory '${HOME}/.aptly/public' with autoindexing.
|
||||||
|
Now you can add following line to apt sources:
|
||||||
|
deb http://your-server/ squeeze contrib main
|
||||||
|
deb-src http://your-server/ squeeze contrib main
|
||||||
|
Don't forget to add your GPG key to apt with apt-key.
|
||||||
|
|
||||||
|
You can also use `aptly serve` to publish your repositories over HTTP quickly.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
ERROR: unable to publish: duplicate component name: contrib
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Warning: publishing from empty source, architectures list should be complete, it can't be changed after publishing (use -architectures flag)
|
||||||
|
ERROR: unable to publish: duplicate component name: b
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Warning: publishing from empty source, architectures list should be complete, it can't be changed after publishing (use -architectures flag)
|
||||||
|
ERROR: unable to publish: unable to guess distribution name, please specify explicitly
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
ERROR: unable to publish: local repo with name repo2 not found
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
ERROR: unable to parse command
|
||||||
@@ -1 +1 @@
|
|||||||
ERROR: prefix/distribution already used by another published repo: ./maverick (main) [i386, source] publishes [local-repo]
|
ERROR: prefix/distribution already used by another published repo: ./maverick [i386, source] publishes {main: [local-repo]}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
ERROR: prefix/distribution already used by another published repo: ppa/maverick (main) [i386, source] publishes [local-repo]
|
ERROR: prefix/distribution already used by another published repo: ppa/maverick [i386, source] publishes {main: [local-repo]}
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
|
Warning: publishing from empty source, architectures list should be complete, it can't be changed after publishing (use -architectures flag)
|
||||||
Loading packages...
|
Loading packages...
|
||||||
ERROR: unable to publish: source is empty
|
ERROR: unable to publish: unable to figure out list of architectures, please supply explicit list
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Origin: . maverick
|
||||||
|
Label: . maverick
|
||||||
|
Architecture: amd64
|
||||||
|
Archive: maverick
|
||||||
|
Component: main
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Origin: . maverick
|
||||||
|
Label: . maverick
|
||||||
|
Architecture: i386
|
||||||
|
Archive: maverick
|
||||||
|
Component: main
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
Warning: publishing from empty source, architectures list should be complete, it can't be changed after publishing (use -architectures flag)
|
||||||
|
Loading packages...
|
||||||
|
Generating metadata files and linking package files...
|
||||||
|
Signing file '${HOME}/.aptly/public/dists/maverick/Release' with gpg, please enter your passphrase when prompted:
|
||||||
|
Clearsigning file '${HOME}/.aptly/public/dists/maverick/Release' with gpg, please enter your passphrase when prompted:
|
||||||
|
|
||||||
|
Snapshot snap25 has been successfully published.
|
||||||
|
Please setup your webserver to serve directory '${HOME}/.aptly/public' with autoindexing.
|
||||||
|
Now you can add following line to apt sources:
|
||||||
|
deb http://your-server/ maverick main
|
||||||
|
Don't forget to add your GPG key to apt with apt-key.
|
||||||
|
|
||||||
|
You can also use `aptly serve` to publish your repositories over HTTP quickly.
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user