Compare commits

...

97 Commits

Author SHA1 Message Date
Andrey Smirnov 3008147b3a One more "fix" for FreeBSD & gpg. 2014-02-10 23:25:41 +04:00
Andrey Smirnov 421283d161 Output match processor to fix CentOS build was placed incorrectly. 2014-02-10 23:13:49 +04:00
Andrey Smirnov 4020e30f07 Fixing system test on CentOS (different version of gpg). 2014-02-10 22:53:52 +04:00
Andrey Smirnov 766d634fbb terminal.IsTerminal() is not available on FreeBSD until go1.3 2014-02-10 22:48:12 +04:00
Andrey Smirnov 1bba0319cb aptly version 0.3. 2014-02-10 21:12:08 +04:00
Andrey Smirnov 651f6e934c Use temp file with .png extension. 2014-02-10 20:43:05 +04:00
Andrey Smirnov f2a7018335 New command: aptly graph to generate graph of entities created. 2014-02-10 17:33:07 +04:00
Andrey Smirnov 7a3063963c Add note on downloading keys from repository. 2014-02-10 15:29:48 +04:00
Andrey Smirnov 0c85e5252f Ignore timestamp formatting. 2014-02-10 15:29:37 +04:00
Andrey Smirnov d0e73a3e00 Tests for flat repository mirroring. 2014-02-10 15:06:11 +04:00
Andrey Smirnov 955b09a41c Add one more key for flat repos. 2014-02-10 15:05:18 +04:00
Andrey Smirnov 3075addd46 Support for flat repositories. 2014-02-10 14:47:52 +04:00
Andrey Smirnov ecbd146cd3 If repo's distribution is empty, don't use it. 2014-02-10 14:23:55 +04:00
Andrey Smirnov 80100a2eda New wheezy version has been released. 2014-02-10 14:17:27 +04:00
Andrey Smirnov fc51eb8414 Add spaces to SHA1/SHA256 sums in packages. 2014-02-10 13:40:34 +04:00
Andrey Smirnov 8c83706684 Test disable signing & verifying via config file. 2014-02-07 21:09:46 +04:00
Andrey Smirnov 3e5d54f3ef Use config file with all options. 2014-02-07 20:47:29 +04:00
Andrey Smirnov 9b4e858734 Fix root dir location in config file. 2014-02-07 20:46:43 +04:00
Andrey Smirnov 14e66c03a6 Tests for config in other file. 2014-02-07 20:00:43 +04:00
Andrey Smirnov 803570bf26 Support for running individual suites. 2014-02-07 20:00:21 +04:00
Andrey Smirnov 66d1f40a49 Support for config file in any file. 2014-02-07 19:59:26 +04:00
Andrey Smirnov 610940ae5d Mention create empty in command help. 2014-02-07 13:50:20 +04:00
Andrey Smirnov cddce9a5f7 Fix system test: skip gpg. 2014-02-07 13:50:12 +04:00
Andrey Smirnov 36892a2797 Fix tests. 2014-02-07 13:41:53 +04:00
Andrey Smirnov f3bad4ee2c Style fixes. 2014-02-07 13:36:10 +04:00
Andrey Smirnov bb13462f7b Fix error message. 2014-02-07 13:33:15 +04:00
Andrey Smirnov a3dbc8444b Publishing empty snapshot should fail. 2014-02-07 13:33:01 +04:00
Andrey Smirnov 9dccf2a4ee System test for aptly snapshot create empty. 2014-02-07 13:28:09 +04:00
Andrey Smirnov 919dc53814 aptly snapshot create .. empty command 2014-02-07 13:27:47 +04:00
Andrey Smirnov 87c0430628 Import keys as trusted. 2014-02-07 12:17:55 +04:00
Andrey Smirnov ca4736674e Make gpg be less chattly about untrusted keys. 2014-02-07 12:17:33 +04:00
Andrey Smirnov cf3dc6be27 Tests for mirroring repositories with signatures. 2014-02-07 12:06:38 +04:00
Andrey Smirnov d4307ad03c Test on publishing with --skip-signing. 2014-02-07 11:37:01 +04:00
Andrey Smirnov 47225a0e2d Add keyring parameter to supress help messages on empty default keyring. 2014-02-07 10:58:01 +04:00
Andrey Smirnov f4bf144145 Revert "Use non-default keyring in test, so that we don't have extra messages."
This reverts commit ad623f7d74.
2014-02-07 10:57:19 +04:00
Andrey Smirnov ad623f7d74 Use non-default keyring in test, so that we don't have extra messages. 2014-02-07 02:07:49 +04:00
Andrey Smirnov 3a51116881 Use better words. 2014-02-07 02:07:41 +04:00
Andrey Smirnov 39d2dd2483 Update system tests not to fail with GPG verification. 2014-02-07 01:23:11 +04:00
Andrey Smirnov b532cb19ee Verifying and signing releases with GPG, new flags. 2014-02-07 01:22:53 +04:00
Andrey Smirnov f5ee710098 Major rework of GnuPG interface: support verifying, more help to the user. 2014-02-07 01:22:13 +04:00
Andrey Smirnov 7cbba33fe7 Fetching mirror (Release files) with crypto signatures. 2014-02-06 22:12:31 +04:00
Andrey Smirnov a9c812a1b3 Style fix. 2014-02-06 21:58:56 +04:00
Andrey Smirnov 09648044db Test for new config options. 2014-02-06 21:58:40 +04:00
Andrey Smirnov a97365377f New configuration options to disable gpg usage in aptly. 2014-02-06 19:56:26 +04:00
Andrey Smirnov 0e9ccb4481 Publishing repository without signer (no signed files). 2014-02-06 19:55:55 +04:00
Andrey Smirnov c4a30ce0ce Update docs, we have more features. [ci skip] 2014-02-04 14:12:00 +04:00
Andrey Smirnov d350e9edba Fix broken code due to addition of Progress. 2014-02-04 13:06:55 +04:00
Andrey Smirnov ab468bcac4 Use progress when downloading repo. 2014-02-04 12:38:32 +04:00
Andrey Smirnov 679fc3e5fd Bind progress into Downloader. 2014-02-04 12:38:14 +04:00
Andrey Smirnov e99fee3908 Progress reporter: progress bar + messages. 2014-02-04 12:37:55 +04:00
Andrey Smirnov c3bcc9f7cb Tests for downloading from broken mirror (checksums). 2014-02-03 23:16:41 +04:00
Andrey Smirnov 62d3c625ed Support for internal webserver in tests. 2014-02-03 23:15:50 +04:00
Andrey Smirnov 3a9ce36662 Fix broken test: nil.Close() 2014-02-03 21:18:30 +04:00
Andrey Smirnov b4d7f8ec55 Add flag "-ignore-cheksums" to aptly mirror update. 2014-02-03 21:00:12 +04:00
Andrey Smirnov 79eaf5d460 Parsing Release files for checksums of Packages files. 2014-02-03 20:57:34 +04:00
Andrey Smirnov 502ed4366a ignoreMismatch flag for downloading. 2014-02-03 20:56:51 +04:00
Andrey Smirnov d65de9bd30 Rename serve test names. 2014-02-03 17:42:51 +04:00
Andrey Smirnov c1feb4210c Pass expected checksums for package files to downloader. 2014-02-03 17:42:12 +04:00
Andrey Smirnov 360e09cc7d Update to new non-pointer interfaces. 2014-02-03 17:41:54 +04:00
Andrey Smirnov 182a4bd39c Update tests. 2014-02-03 17:41:39 +04:00
Andrey Smirnov 35976f5ff1 Trim hashes when parsing packages, export package expected checksums. 2014-02-03 17:41:12 +04:00
Andrey Smirnov 982a25992e Checksum verification while downloading files. 2014-02-03 17:40:41 +04:00
Andrey Smirnov 08123ef5e3 Use values instead of pointers and use io.MultiWriter instead of homegrown impl. 2014-02-03 17:39:49 +04:00
Andrey Smirnov 0dd44f98b8 Restore old function check_file. 2014-02-02 20:08:51 +04:00
Andrey Smirnov 996fc445be Refactor download test to use internal HTTP server. 2014-01-31 22:26:26 +04:00
Andrey Smirnov df0a678863 Refactor checksum calculation to implement transparent checksum writer. 2014-01-31 21:46:38 +04:00
Andrey Smirnov 89ac907ca3 Sytem test for aptly publish list/drop. 2014-01-31 21:14:48 +04:00
Andrey Smirnov 7ce8b0ff7b Add note that repo has been dropped. 2014-01-31 21:14:35 +04:00
Andrey Smirnov a1258f2125 Revert: run all tests. 2014-01-31 21:14:13 +04:00
Andrey Smirnov 59d72c8112 System tests for aptly publish snapshot. 2014-01-31 19:04:44 +04:00
Andrey Smirnov 5bd0546fb7 Add note about aptly serve to command output 2014-01-31 19:04:25 +04:00
Andrey Smirnov 67422642ef Fix order of fields. 2014-01-31 19:03:50 +04:00
Andrey Smirnov de5e39818e Fix description to be more readable. 2014-01-31 19:03:30 +04:00
Andrey Smirnov cfdcf84fa5 Fix help message. 2014-01-30 13:16:35 +04:00
Andrey Smirnov 043ed13c18 aptly serve command: handle publishing of repositories, with system test. 2014-01-30 13:10:19 +04:00
Andrey Smirnov 0271456ca4 Add 2014 to LICENSE file. 2014-01-30 11:59:19 +04:00
Andrey Smirnov 08bf46e486 Clarify command line usage a bit. 2014-01-29 19:22:56 +04:00
Andrey Smirnov 93eef2cc80 aptly snapshot drop with system tests. 2014-01-29 19:04:53 +04:00
Andrey Smirnov c4f1179b65 Lookup PublishedRepo by snapshot. 2014-01-29 18:11:40 +04:00
Andrey Smirnov 2487d5da37 Fix option name in error message. 2014-01-29 18:05:22 +04:00
Andrey Smirnov 772035ad44 Find snapshot by source. 2014-01-29 18:00:53 +04:00
Andrey Smirnov e49afbcd2d Snapshot dropping. 2014-01-29 17:13:42 +04:00
Andrey Smirnov 1803252f33 Command aptly mirror drop with system tests. 2014-01-29 16:57:10 +04:00
Andrey Smirnov 555256c1fe Search snapshots by source repo. 2014-01-29 16:16:24 +04:00
Andrey Smirnov 26267802e9 Dropping remote repos. 2014-01-29 15:57:19 +04:00
Andrey Smirnov 69eb6a85b0 Add comment to exported function. 2014-01-29 14:34:56 +04:00
Andrey Smirnov 78c7bf6af1 Double delete is not a problem. 2014-01-29 14:34:30 +04:00
Andrey Smirnov d5bc13751b Update version in test as well. 2014-01-28 19:21:42 +04:00
Andrey Smirnov b04027edad Bump version: waiting for 0.3 2014-01-28 18:33:49 +04:00
Andrey Smirnov 5c6e4fffc4 Better words. 2014-01-28 13:02:05 +04:00
Andrey Smirnov 0da53a2d87 Add '+' to list of skipped symbols. 2014-01-28 12:41:31 +04:00
Andrey Smirnov db4ccce9e4 Remove updated at while comparing. 2014-01-28 12:35:20 +04:00
Andrey Smirnov c538ca8cc6 Add options --with-packages to show list of packages in snapshot & mirror. 2014-01-28 12:26:05 +04:00
Andrey Smirnov 00bb27fcea Don't run fixtured DB on go1.1. 2014-01-27 20:05:01 +04:00
Andrey Smirnov b571e4d79b Clone from https url. 2014-01-27 19:51:55 +04:00
Andrey Smirnov 29cb5d9c9e Prepare Travis with all files to run aptly system tests with DB fixture. 2014-01-27 19:45:35 +04:00
Andrey Smirnov 899a28cc27 Clarify go version required in README. #2 2014-01-25 23:10:22 +04:00
142 changed files with 3729 additions and 298 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright 2013 Andrey Smirnov. All rights reserved.
Copyright 2013-2014 Andrey Smirnov. All rights reserved.
MIT License
+4 -1
View File
@@ -46,8 +46,11 @@ check:
golint .
system-test:
ifeq ($(GOVERSION), go1.2)
if [ ! -e ~/aptly-fixture-db ]; then git clone https://github.com/aptly-dev/aptly-fixture-db.git ~/aptly-fixture-db/; fi
endif
go install
PATH=$(BINPATH):$(PATH) python system/run.py
PATH=$(BINPATH):$(PATH) python system/run.py --long
travis: $(TRAVIS_TARGET) system-test
+4 -3
View File
@@ -26,8 +26,7 @@ Aptly features: ("+" means planned features)
Current limitations:
* source packages, debian-installer and translations not supported yet
* checksums and signature are not verified while downloading
* deleting created items is not implemented
* signature is not verified while downloading
* cleaning up stale files is not implemented
Currently aptly is under heavy development, so please use it with care.
@@ -37,6 +36,8 @@ Download
Binary executables (depends almost only on libc) are available for download from `Bintray <http://dl.bintray.com/smira/aptly/>`_.
If you have Go environment set up, you can build aptly from source by running::
If you have Go environment set up, you can build aptly from source by running (go 1.1+ required)::
go get github.com/smira/aptly
If you don't have Go installed (or older version), you can easily install Go using `gvm <https://github.com/moovweb/gvm/>`_.
+174
View File
@@ -0,0 +1,174 @@
package main
import (
"bytes"
"code.google.com/p/gographviz"
"fmt"
"github.com/gonuts/commander"
"github.com/gonuts/flag"
"github.com/smira/aptly/debian"
"io"
"io/ioutil"
"os"
"os/exec"
"strings"
)
func graphvizEscape(s string) string {
return fmt.Sprintf("\"%s\"", strings.Replace(s, "\"", "\\\"", 0))
}
func aptlyGraph(cmd *commander.Command, args []string) error {
var err error
graph := gographviz.NewGraph()
graph.SetDir(true)
graph.SetName("aptly")
fmt.Printf("Loading mirrors...\n")
repoCollection := debian.NewRemoteRepoCollection(context.database)
err = repoCollection.ForEach(func(repo *debian.RemoteRepo) error {
err := repoCollection.LoadComplete(repo)
if err != nil {
return err
}
graph.AddNode("aptly", graphvizEscape(repo.UUID), map[string]string{
"shape": "Mrecord",
"style": "filled",
"fillcolor": "darkgoldenrod1",
"label": graphvizEscape(fmt.Sprintf("{Mirror %s|url: %s|dist: %s|comp: %s|arch: %s|pkgs: %d}",
repo.Name, repo.ArchiveRoot, repo.Distribution, strings.Join(repo.Components, ", "),
strings.Join(repo.Architectures, ", "), repo.NumPackages())),
})
return nil
})
if err != nil {
return err
}
fmt.Printf("Loading snapshots...\n")
snapshotCollection := debian.NewSnapshotCollection(context.database)
err = snapshotCollection.ForEach(func(snapshot *debian.Snapshot) error {
err := snapshotCollection.LoadComplete(snapshot)
if err != nil {
return err
}
description := snapshot.Description
if snapshot.SourceKind == "repo" {
description = "Snapshot from repo"
}
graph.AddNode("aptly", graphvizEscape(snapshot.UUID), map[string]string{
"shape": "Mrecord",
"style": "filled",
"fillcolor": "cadetblue1",
"label": graphvizEscape(fmt.Sprintf("{Snapshot %s|%s|pkgs: %d}", snapshot.Name, description, snapshot.NumPackages())),
})
if snapshot.SourceKind == "repo" {
for _, uuid := range snapshot.SourceIDs {
graph.AddEdge(graphvizEscape(uuid), "", graphvizEscape(snapshot.UUID), "", true, nil)
}
} else if snapshot.SourceKind == "snapshot" {
for _, uuid := range snapshot.SourceIDs {
graph.AddEdge(graphvizEscape(uuid), "", graphvizEscape(snapshot.UUID), "", true, nil)
}
}
return nil
})
if err != nil {
return err
}
fmt.Printf("Loading published repos...\n")
publishedCollection := debian.NewPublishedRepoCollection(context.database)
publishedCollection.ForEach(func(repo *debian.PublishedRepo) error {
graph.AddNode("aptly", graphvizEscape(repo.UUID), map[string]string{
"shape": "Mrecord",
"style": "filled",
"fillcolor": "darkolivegreen1",
"label": graphvizEscape(fmt.Sprintf("{Published %s/%s|comp: %s|arch: %s}", repo.Prefix, repo.Distribution, repo.Component, strings.Join(repo.Architectures, ", "))),
})
graph.AddEdge(graphvizEscape(repo.SnapshotUUID), "", graphvizEscape(repo.UUID), "", true, nil)
return nil
})
fmt.Printf("Generating graph...\n")
buf := bytes.NewBufferString(graph.String())
tempfile, err := ioutil.TempFile("", "aptly-graph")
if err != nil {
return err
}
tempfile.Close()
os.Remove(tempfile.Name())
tempfilename := tempfile.Name() + ".png"
command := exec.Command("dot", "-Tpng", "-o"+tempfilename)
command.Stderr = os.Stderr
stdin, err := command.StdinPipe()
if err != nil {
return err
}
err = command.Start()
if err != nil {
return fmt.Errorf("unable to execute dot: %s (is graphviz package installed?)", err)
}
_, err = io.Copy(stdin, buf)
if err != nil {
return err
}
err = stdin.Close()
if err != nil {
return err
}
err = command.Wait()
if err != nil {
return err
}
err = exec.Command("open", tempfilename).Run()
if err != nil {
fmt.Printf("Rendered to PNG file: %s\n", tempfilename)
err = nil
}
return err
}
func makeCmdGraph() *commander.Command {
cmd := &commander.Command{
Run: aptlyGraph,
UsageLine: "graph",
Short: "display graph of dependencies between aptly objects (requires graphviz)",
Long: `
Command graph displays relationship between mirrors, snapshots and published repositories using
graphviz package to render graph as image.
ex:
$ aptly graph
`,
Flag: *flag.NewFlagSet("aptly-graph", flag.ExitOnError),
}
return cmd
}
+131 -4
View File
@@ -10,6 +10,43 @@ import (
"strings"
)
func getVerifier(cmd *commander.Command) (utils.Verifier, error) {
if utils.Config.GpgDisableVerify || cmd.Flag.Lookup("ignore-signatures").Value.Get().(bool) {
return nil, nil
}
verifier := &utils.GpgVerifier{}
for _, keyRing := range keyRings.keyRings {
verifier.AddKeyring(keyRing)
}
err := verifier.InitKeyring()
if err != nil {
return nil, err
}
return verifier, nil
}
type keyRingsFlag struct {
keyRings []string
}
func (k *keyRingsFlag) Set(value string) error {
k.keyRings = append(k.keyRings, value)
return nil
}
func (k *keyRingsFlag) Get() interface{} {
return k.keyRings
}
func (k *keyRingsFlag) String() string {
return strings.Join(k.keyRings, ",")
}
var keyRings = keyRingsFlag{}
func aptlyMirrorList(cmd *commander.Command, args []string) error {
var err error
if len(args) != 0 {
@@ -53,7 +90,12 @@ func aptlyMirrorCreate(cmd *commander.Command, args []string) error {
return fmt.Errorf("unable to create mirror: %s", err)
}
err = repo.Fetch(context.downloader)
verifier, err := getVerifier(cmd)
if err != nil {
return fmt.Errorf("unable to initialize GPG verifier: %s", err)
}
err = repo.Fetch(context.downloader, verifier)
if err != nil {
return fmt.Errorf("unable to fetch mirror: %s", err)
}
@@ -106,6 +148,15 @@ func aptlyMirrorShow(cmd *commander.Command, args []string) error {
fmt.Printf("%s: %s\n", k, repo.Meta[k])
}
withPackages := cmd.Flag.Lookup("with-packages").Value.Get().(bool)
if withPackages {
if repo.LastDownloadDate.IsZero() {
fmt.Printf("Unable to show package list, mirror hasn't been downloaded yet.\n")
} else {
ListPackagesRefList(repo.RefList())
}
}
return err
}
@@ -129,14 +180,21 @@ func aptlyMirrorUpdate(cmd *commander.Command, args []string) error {
return fmt.Errorf("unable to update: %s", err)
}
err = repo.Fetch(context.downloader)
ignoreMismatch := cmd.Flag.Lookup("ignore-checksums").Value.Get().(bool)
verifier, err := getVerifier(cmd)
if err != nil {
return fmt.Errorf("unable to initialize GPG verifier: %s", err)
}
err = repo.Fetch(context.downloader, verifier)
if err != nil {
return fmt.Errorf("unable to update: %s", err)
}
packageCollection := debian.NewPackageCollection(context.database)
err = repo.Download(context.downloader, packageCollection, context.packageRepository)
err = repo.Download(context.downloader, packageCollection, context.packageRepository, ignoreMismatch)
if err != nil {
return fmt.Errorf("unable to update: %s", err)
}
@@ -150,6 +208,46 @@ func aptlyMirrorUpdate(cmd *commander.Command, args []string) error {
return err
}
func aptlyMirrorDrop(cmd *commander.Command, args []string) error {
var err error
if len(args) != 1 {
cmd.Usage()
return err
}
name := args[0]
repoCollection := debian.NewRemoteRepoCollection(context.database)
repo, err := repoCollection.ByName(name)
if err != nil {
return fmt.Errorf("unable to drop: %s", err)
}
force := cmd.Flag.Lookup("force").Value.Get().(bool)
if !force {
snapshotCollection := debian.NewSnapshotCollection(context.database)
snapshots := snapshotCollection.ByRemoteRepoSource(repo)
if len(snapshots) > 0 {
fmt.Printf("Mirror `%s` was used to create following snapshots:\n", repo.Name)
for _, snapshot := range snapshots {
fmt.Printf(" * %s\n", snapshot)
}
return fmt.Errorf("won't delete mirror with snapshots, use -force to override")
}
}
err = repoCollection.Drop(repo)
if err != nil {
return fmt.Errorf("unable to drop: %s", err)
}
fmt.Printf("Mirror `%s` has been removed.\n", repo.Name)
return err
}
func makeCmdMirrorCreate() *commander.Command {
cmd := &commander.Command{
Run: aptlyMirrorCreate,
@@ -164,6 +262,9 @@ ex:
Flag: *flag.NewFlagSet("aptly-mirror-create", flag.ExitOnError),
}
cmd.Flag.Bool("ignore-signatures", false, "disable verification of Release file signatures")
cmd.Flag.Var(&keyRings, "keyring", "gpg keyring to use when verifying Release file (could be specified multiple times)")
return cmd
}
@@ -199,6 +300,8 @@ ex:
Flag: *flag.NewFlagSet("aptly-mirror-show", flag.ExitOnError),
}
cmd.Flag.Bool("with-packages", false, "show list of packages")
return cmd
}
@@ -216,6 +319,30 @@ ex:
Flag: *flag.NewFlagSet("aptly-mirror-update", flag.ExitOnError),
}
cmd.Flag.Bool("ignore-checksums", false, "ignore checksum mismatches while downloading package files and metadata")
cmd.Flag.Bool("ignore-signatures", false, "disable verification of Release file signatures")
cmd.Flag.Var(&keyRings, "keyring", "gpg keyring to use when verifying Release file (could be specified multiple times)")
return cmd
}
func makeCmdMirrorDrop() *commander.Command {
cmd := &commander.Command{
Run: aptlyMirrorDrop,
UsageLine: "drop <name>",
Short: "delete remote repository mirror",
Long: `
Drop deletes information about remote repository mirror. Package data is not deleted
(it could be still used by other mirrors or snapshots).
ex:
$ aptly mirror drop wheezy-main
`,
Flag: *flag.NewFlagSet("aptly-mirror-drop", flag.ExitOnError),
}
cmd.Flag.Bool("force", false, "force mirror deletion even if used by snapshots")
return cmd
}
@@ -227,7 +354,7 @@ func makeCmdMirror() *commander.Command {
makeCmdMirrorCreate(),
makeCmdMirrorList(),
makeCmdMirrorShow(),
//makeCmdMirrorDestroy(),
makeCmdMirrorDrop(),
makeCmdMirrorUpdate(),
},
Flag: *flag.NewFlagSet("aptly-mirror", flag.ExitOnError),
+33 -4
View File
@@ -10,6 +10,27 @@ import (
"strings"
)
func getSigner(cmd *commander.Command) (utils.Signer, error) {
if cmd.Flag.Lookup("skip-signing").Value.Get().(bool) || utils.Config.GpgDisableSign {
return nil, nil
}
signer := &utils.GpgSigner{}
key := cmd.Flag.Lookup("gpg-key").Value.String()
if key != "" {
signer.SetKey(key)
}
err := signer.Init()
if err != nil {
return nil, err
}
return signer, nil
}
func aptlyPublishSnapshot(cmd *commander.Command, args []string) error {
var err error
if len(args) < 1 || len(args) > 2 {
@@ -60,14 +81,13 @@ func aptlyPublishSnapshot(cmd *commander.Command, args []string) error {
if distribution == "" {
if sourceRepo != nil {
distribution = sourceRepo.Distribution
} else {
}
if distribution == "" {
return fmt.Errorf("unable to guess distribution name, please specify explicitly")
}
}
signer := &utils.GpgSigner{}
signer.SetKey(cmd.Flag.Lookup("gpg-key").Value.String())
published, err := debian.NewPublishedRepo(prefix, distribution, component, context.architecturesList, snapshot)
if err != nil {
return fmt.Errorf("unable to publish: %s", err)
@@ -79,6 +99,11 @@ func aptlyPublishSnapshot(cmd *commander.Command, args []string) error {
return fmt.Errorf("prefix/distribution already used by another published repo: %s", duplicate)
}
signer, err := getSigner(cmd)
if err != nil {
return fmt.Errorf("unable to initialize GPG signer: %s", err)
}
packageCollection := debian.NewPackageCollection(context.database)
err = published.Publish(context.packageRepository, packageCollection, signer)
if err != nil {
@@ -99,6 +124,7 @@ func aptlyPublishSnapshot(cmd *commander.Command, args []string) error {
fmt.Printf("Now you can add following line to apt sources:\n")
fmt.Printf(" deb http://your-server/%s %s %s\n", prefix, distribution, component)
fmt.Printf("Don't forget to add your GPG key to apt with apt-key.\n")
fmt.Printf("\nYou can also use `aptly serve` to publish your repositories over HTTP quickly.\n")
return err
}
@@ -166,6 +192,8 @@ func aptlyPublishDrop(cmd *commander.Command, args []string) error {
return fmt.Errorf("unable to remove: %s", err)
}
fmt.Printf("\nPublished repositroy has been removed successfully.\n")
return err
}
@@ -185,6 +213,7 @@ ex.
cmd.Flag.String("distribution", "", "distribution name to publish")
cmd.Flag.String("component", "", "component name to publish")
cmd.Flag.String("gpg-key", "", "GPG key ID to use when signing the release")
cmd.Flag.Bool("skip-signing", false, "don't sign Release files with GPG")
return cmd
}
+106
View File
@@ -0,0 +1,106 @@
package main
import (
"fmt"
"github.com/gonuts/commander"
"github.com/gonuts/flag"
"github.com/smira/aptly/debian"
"net"
"net/http"
"os"
"sort"
)
func aptlyServe(cmd *commander.Command, args []string) error {
var err error
publishedCollection := debian.NewPublishedRepoCollection(context.database)
snapshotCollection := debian.NewSnapshotCollection(context.database)
if publishedCollection.Len() == 0 {
fmt.Printf("No published repositories, unable to serve.\n")
return nil
}
listen := cmd.Flag.Lookup("listen").Value.String()
listenHost, listenPort, err := net.SplitHostPort(listen)
if err != nil {
return fmt.Errorf("wrong -listen specification: %s", err)
}
if listenHost == "" {
listenHost, err = os.Hostname()
if err != nil {
listenHost = "localhost"
}
}
fmt.Printf("Serving published repositories, recommended apt sources list:\n\n")
sources := make(sort.StringSlice, 0, publishedCollection.Len())
published := make(map[string]*debian.PublishedRepo, publishedCollection.Len())
err = publishedCollection.ForEach(func(repo *debian.PublishedRepo) error {
err := publishedCollection.LoadComplete(repo, snapshotCollection)
if err != nil {
return err
}
sources = append(sources, repo.String())
published[repo.String()] = repo
return nil
})
if err != nil {
return fmt.Errorf("unable to serve: %s", err)
}
sort.Strings(sources)
for _, source := range sources {
repo := published[source]
prefix := repo.Prefix
if prefix == "." {
prefix = ""
} else {
prefix += "/"
}
fmt.Printf("# %s\ndeb http://%s:%s/%s %s %s\n",
repo, listenHost, listenPort, prefix, repo.Distribution, repo.Component)
}
context.database.Close()
fmt.Printf("\nStarting web server at: %s (press Ctrl+C to quit)...\n", listen)
err = http.ListenAndServe(listen, http.FileServer(http.Dir(context.packageRepository.PublicPath())))
if err != nil {
return fmt.Errorf("unable to serve: %s", err)
}
return nil
}
func makeCmdServe() *commander.Command {
cmd := &commander.Command{
Run: aptlyServe,
UsageLine: "serve",
Short: "start embedded HTTP server to serve published repositories",
Long: `
Command serve starts embedded HTTP server (not suitable for real production usage) to serve
contents of public/ subdirectory of aptly's root that contains published repositories.
ex:
$ aptly serve -listen=:8080
`,
Flag: *flag.NewFlagSet("aptly-serve", flag.ExitOnError),
}
cmd.Flag.String("listen", ":8080", "host:port for HTTP listening")
return cmd
}
+105 -25
View File
@@ -11,14 +11,14 @@ import (
)
func aptlySnapshotCreate(cmd *commander.Command, args []string) error {
var err error
var (
err error
snapshot *debian.Snapshot
)
if len(args) < 4 || args[1] != "from" || args[2] != "mirror" {
cmd.Usage()
return err
}
repoName, mirrorName := args[3], args[0]
if len(args) == 4 && args[1] == "from" && args[2] == "mirror" {
// aptly snapshot create snap from mirror mirror
repoName, snapshotName := args[3], args[0]
repoCollection := debian.NewRemoteRepoCollection(context.database)
repo, err := repoCollection.ByName(repoName)
@@ -31,10 +31,21 @@ func aptlySnapshotCreate(cmd *commander.Command, args []string) error {
return fmt.Errorf("unable to create snapshot: %s", err)
}
snapshot, err := debian.NewSnapshotFromRepository(mirrorName, repo)
snapshot, err = debian.NewSnapshotFromRepository(snapshotName, repo)
if err != nil {
return fmt.Errorf("unable to create snapshot: %s", err)
}
} else if len(args) == 2 && args[1] == "empty" {
// aptly snapshot create snap empty
snapshotName := args[0]
packageList := debian.NewPackageList()
snapshot = debian.NewSnapshotFromPackageList(snapshotName, nil, packageList, "Created as empty")
} else {
cmd.Usage()
return err
}
snapshotCollection := debian.NewSnapshotCollection(context.database)
@@ -106,20 +117,10 @@ func aptlySnapshotShow(cmd *commander.Command, args []string) error {
fmt.Printf("Created At: %s\n", snapshot.CreatedAt.Format("2006-01-02 15:04:05 MST"))
fmt.Printf("Description: %s\n", snapshot.Description)
fmt.Printf("Number of packages: %d\n", snapshot.NumPackages())
fmt.Printf("Packages:\n")
packageCollection := debian.NewPackageCollection(context.database)
err = snapshot.RefList().ForEach(func(key []byte) error {
p, err := packageCollection.ByKey(key)
if err != nil {
return err
}
fmt.Printf(" %s\n", p)
return nil
})
if err != nil {
return fmt.Errorf("unable to load packages: %s", err)
withPackages := cmd.Flag.Lookup("with-packages").Value.Get().(bool)
if withPackages {
ListPackagesRefList(snapshot.RefList())
}
return err
@@ -499,15 +500,72 @@ func aptlySnapshotMerge(cmd *commander.Command, args []string) error {
return err
}
func aptlySnapshotDrop(cmd *commander.Command, args []string) error {
var err error
if len(args) != 1 {
cmd.Usage()
return err
}
name := args[0]
snapshotCollection := debian.NewSnapshotCollection(context.database)
snapshot, err := snapshotCollection.ByName(name)
if err != nil {
return fmt.Errorf("unable to drop: %s", err)
}
publishedRepoCollection := debian.NewPublishedRepoCollection(context.database)
published := publishedRepoCollection.BySnapshot(snapshot)
if len(published) > 0 {
fmt.Printf("Snapshot `%s` is published currently:\n", snapshot.Name)
for _, repo := range published {
err = publishedRepoCollection.LoadComplete(repo, snapshotCollection)
if err != nil {
return fmt.Errorf("unable to load published: %s", err)
}
fmt.Printf(" * %s\n", repo)
}
return fmt.Errorf("unable to drop: snapshot is published")
}
force := cmd.Flag.Lookup("force").Value.Get().(bool)
if !force {
snapshots := snapshotCollection.BySnapshotSource(snapshot)
if len(snapshots) > 0 {
fmt.Printf("Snapshot `%s` was used as a source in following snapshots:\n", snapshot.Name)
for _, snap := range snapshots {
fmt.Printf(" * %s\n", snap)
}
return fmt.Errorf("won't delete snapshot that was used as source for other snapshots, use -force to override")
}
}
err = snapshotCollection.Drop(snapshot)
if err != nil {
return fmt.Errorf("unable to drop: %s", err)
}
fmt.Printf("Snapshot `%s` has been dropped.\n", snapshot.Name)
return err
}
func makeCmdSnapshotCreate() *commander.Command {
cmd := &commander.Command{
Run: aptlySnapshotCreate,
UsageLine: "create <name> from mirror <mirror-name>",
Short: "creates snapshot out of any mirror",
UsageLine: "create <name> from mirror <mirror-name> | create <name> empty",
Short: "creates immutable snapshot of mirror contents",
Long: `
Command create makes persistent immutable snapshot of remote repository mirror. Snapshot could be
Command create .. from mirror makes persistent immutable snapshot of remote repository mirror. Snapshot could be
published or further modified using merge, pull and other aptly features.
Command create .. empty creates empty snapshot that could be used as a basis for snapshot pull operations, for example.
As snapshots are immutable, creating one empty snapshot should be enough.
ex.
$ aptly snapshot create wheezy-main-today from mirror wheezy-main
`,
@@ -549,6 +607,8 @@ ex.
Flag: *flag.NewFlagSet("aptly-snapshot-show", flag.ExitOnError),
}
cmd.Flag.Bool("with-packages", false, "show list of packages")
return cmd
}
@@ -631,6 +691,26 @@ ex.
return cmd
}
func makeCmdSnapshotDrop() *commander.Command {
cmd := &commander.Command{
Run: aptlySnapshotDrop,
UsageLine: "drop <name>",
Short: "delete snapshot",
Long: `
Drop removes information about snapshot. If snapshot is published,
it can't be dropped.
ex.
$ aptly snapshot drop wheezy-main
`,
Flag: *flag.NewFlagSet("aptly-snapshot-drop", flag.ExitOnError),
}
cmd.Flag.Bool("force", false, "remove snapshot even if it was used as source for other snapshots")
return cmd
}
func makeCmdSnapshot() *commander.Command {
return &commander.Command{
UsageLine: "snapshot",
@@ -643,7 +723,7 @@ func makeCmdSnapshot() *commander.Command {
makeCmdSnapshotPull(),
makeCmdSnapshotDiff(),
makeCmdSnapshotMerge(),
//makeCmdSnapshotDestroy(),
makeCmdSnapshotDrop(),
},
Flag: *flag.NewFlagSet("aptly-snapshot", flag.ExitOnError),
}
+27
View File
@@ -0,0 +1,27 @@
package main
import (
"fmt"
"github.com/smira/aptly/debian"
)
//ListPackagesRefList shows list of packages in PackageRefList
func ListPackagesRefList(reflist *debian.PackageRefList) (err error) {
fmt.Printf("Packages:\n")
packageCollection := debian.NewPackageCollection(context.database)
err = reflist.ForEach(func(key []byte) error {
p, err := packageCollection.ByKey(key)
if err != nil {
return err
}
fmt.Printf(" %s\n", p)
return nil
})
if err != nil {
return fmt.Errorf("unable to load packages: %s", err)
}
return
}
+3
View File
@@ -59,6 +59,9 @@ func (s *LevelDBSuite) TestDelete(c *C) {
_, err = s.db.Get(key)
c.Assert(err, ErrorMatches, "key not found")
err = s.db.Delete(key)
c.Assert(err, IsNil)
}
func (s *LevelDBSuite) TestFetchByPrefix(c *C) {
+2 -1
View File
@@ -11,7 +11,8 @@ import (
type Stanza map[string]string
// Canonical order of fields in stanza
var canocialOrder = []string{"Package", "Version", "Installed-Size", "Priority", "Section", "Maintainer", "Architecture"}
var canocialOrder = []string{"Origin", "Label", "Suite", "Package", "Version", "Installed-Size", "Priority", "Section", "Maintainer",
"Architecture", "Codename", "Date", "Architectures", "Components", "Description", "MD5sum", "MD5Sum", "SHA1", "SHA256"}
// Copy returns copy of Stanza
func (s Stanza) Copy() (result Stanza) {
+7 -7
View File
@@ -89,9 +89,9 @@ func NewPackageFromControlFile(input Stanza) *Package {
Filename: input["Filename"],
Checksums: utils.ChecksumInfo{
Size: filesize,
MD5: input["MD5sum"],
SHA1: input["SHA1"],
SHA256: input["SHA256"],
MD5: strings.TrimSpace(input["MD5sum"]),
SHA1: strings.TrimSpace(input["SHA1"]),
SHA256: strings.TrimSpace(input["SHA256"]),
},
})
@@ -177,10 +177,10 @@ func (p *Package) Stanza() (result Stanza) {
result["MD5sum"] = p.Files[0].Checksums.MD5
}
if p.Files[0].Checksums.SHA1 != "" {
result["SHA1"] = p.Files[0].Checksums.SHA1
result["SHA1"] = " " + p.Files[0].Checksums.SHA1
}
if p.Files[0].Checksums.SHA256 != "" {
result["SHA256"] = p.Files[0].Checksums.SHA256
result["SHA256"] = " " + p.Files[0].Checksums.SHA256
}
if p.Depends != nil {
@@ -273,7 +273,7 @@ func (p *Package) PoolDirectory() (string, error) {
type PackageDownloadTask struct {
RepoURI string
DestinationPath string
Size int64
Checksums utils.ChecksumInfo
}
// DownloadList returns list of missing package files for download in format
@@ -293,7 +293,7 @@ func (p *Package) DownloadList(packageRepo *Repository) (result []PackageDownloa
}
if !verified {
result = append(result, PackageDownloadTask{RepoURI: f.Filename, DestinationPath: poolPath, Size: f.Checksums.Size})
result = append(result, PackageDownloadTask{RepoURI: f.Filename, DestinationPath: poolPath, Checksums: f.Checksums})
}
}
+6 -2
View File
@@ -2,12 +2,13 @@ package debian
import (
"github.com/smira/aptly/database"
"github.com/smira/aptly/utils"
. "launchpad.net/gocheck"
"os"
"path/filepath"
)
var packageStanza = Stanza{"Source": "alien-arena", "Pre-Depends": "dpkg (>= 1.6)", "Suggests": "alien-arena-mars", "Recommends": "aliean-arena-luna", "Depends": "libc6 (>= 2.7), alien-arena-data (>= 7.40)", "Filename": "pool/contrib/a/alien-arena/alien-arena-common_7.40-2_i386.deb", "SHA1": "46955e48cad27410a83740a21d766ce362364024", "SHA256": "eb4afb9885cba6dc70cccd05b910b2dbccc02c5900578be5e99f0d3dbf9d76a5", "Priority": "extra", "Maintainer": "Debian Games Team <pkg-games-devel@lists.alioth.debian.org>", "Description": "Common files for Alien Arena client and server ALIEN ARENA is a standalone 3D first person online deathmatch shooter\n crafted from the original source code of Quake II and Quake III, released\n by id Software under the GPL license. With features including 32 bit\n graphics, new particle engine and effects, light blooms, reflective water,\n hi resolution textures and skins, hi poly models, stain maps, ALIEN ARENA\n pushes the envelope of graphical beauty rivaling today's top games.\n .\n This package installs the common files for Alien Arena.\n", "Homepage": "http://red.planetarena.org", "Tag": "role::app-data, role::shared-lib, special::auto-inst-parts", "Installed-Size": "456", "Version": "7.40-2", "Replaces": "alien-arena (<< 7.33-1)", "Size": "187518", "MD5sum": "1e8cba92c41420aa7baa8a5718d67122", "Package": "alien-arena-common", "Section": "contrib/games", "Architecture": "i386"}
var packageStanza = Stanza{"Source": "alien-arena", "Pre-Depends": "dpkg (>= 1.6)", "Suggests": "alien-arena-mars", "Recommends": "aliean-arena-luna", "Depends": "libc6 (>= 2.7), alien-arena-data (>= 7.40)", "Filename": "pool/contrib/a/alien-arena/alien-arena-common_7.40-2_i386.deb", "SHA1": " 46955e48cad27410a83740a21d766ce362364024", "SHA256": " eb4afb9885cba6dc70cccd05b910b2dbccc02c5900578be5e99f0d3dbf9d76a5", "Priority": "extra", "Maintainer": "Debian Games Team <pkg-games-devel@lists.alioth.debian.org>", "Description": "Common files for Alien Arena client and server ALIEN ARENA is a standalone 3D first person online deathmatch shooter\n crafted from the original source code of Quake II and Quake III, released\n by id Software under the GPL license. With features including 32 bit\n graphics, new particle engine and effects, light blooms, reflective water,\n hi resolution textures and skins, hi poly models, stain maps, ALIEN ARENA\n pushes the envelope of graphical beauty rivaling today's top games.\n .\n This package installs the common files for Alien Arena.\n", "Homepage": "http://red.planetarena.org", "Tag": "role::app-data, role::shared-lib, special::auto-inst-parts", "Installed-Size": "456", "Version": "7.40-2", "Replaces": "alien-arena (<< 7.33-1)", "Size": "187518", "MD5sum": "1e8cba92c41420aa7baa8a5718d67122", "Package": "alien-arena-common", "Section": "contrib/games", "Architecture": "i386"}
type PackageSuite struct {
stanza Stanza
@@ -193,7 +194,10 @@ func (s *PackageSuite) TestDownloadList(c *C) {
PackageDownloadTask{
RepoURI: "pool/contrib/a/alien-arena/alien-arena-common_7.40-2_i386.deb",
DestinationPath: poolPath,
Size: 5}})
Checksums: utils.ChecksumInfo{Size: 5,
MD5: "1e8cba92c41420aa7baa8a5718d67122",
SHA1: "46955e48cad27410a83740a21d766ce362364024",
SHA256: "eb4afb9885cba6dc70cccd05b910b2dbccc02c5900578be5e99f0d3dbf9d76a5"}}})
err = os.MkdirAll(filepath.Dir(poolPath), 0755)
c.Assert(err, IsNil)
+16 -3
View File
@@ -109,7 +109,7 @@ func (p *PublishedRepo) Publish(repo *Repository, packageCollection *PackageColl
}
if list.Len() == 0 {
return fmt.Errorf("repository is empty, can't publish")
return fmt.Errorf("snapshot is empty")
}
if len(p.Architectures) == 0 {
@@ -120,7 +120,7 @@ func (p *PublishedRepo) Publish(repo *Repository, packageCollection *PackageColl
return fmt.Errorf("unable to figure out list of architectures, please supply explicit list")
}
generatedFiles := map[string]*utils.ChecksumInfo{}
generatedFiles := map[string]utils.ChecksumInfo{}
// For all architectures, generate release file
for _, arch := range p.Architectures {
@@ -201,7 +201,7 @@ func (p *PublishedRepo) Publish(repo *Repository, packageCollection *PackageColl
release["Date"] = time.Now().UTC().Format("Mon, 2 Jan 2006 15:04:05 MST")
release["Components"] = p.Component
release["Architectures"] = strings.Join(p.Architectures, " ")
release["Description"] = "Generated by aptly\n"
release["Description"] = " Generated by aptly\n"
release["MD5Sum"] = "\n"
release["SHA1"] = "\n"
release["SHA256"] = "\n"
@@ -232,6 +232,7 @@ func (p *PublishedRepo) Publish(repo *Repository, packageCollection *PackageColl
releaseFilename := releaseFile.Name()
releaseFile.Close()
if signer != nil {
err = signer.DetachedSign(releaseFilename, releaseFilename+".gpg")
if err != nil {
return fmt.Errorf("unable to sign Release file: %s", err)
@@ -241,6 +242,7 @@ func (p *PublishedRepo) Publish(repo *Repository, packageCollection *PackageColl
if err != nil {
return fmt.Errorf("unable to sign Release file: %s", err)
}
}
return nil
}
@@ -365,6 +367,17 @@ func (collection *PublishedRepoCollection) ByUUID(uuid string) (*PublishedRepo,
return nil, fmt.Errorf("published repo with uuid %s not found", uuid)
}
// BySnapshot looks up repository by snapshot source
func (collection *PublishedRepoCollection) BySnapshot(snapshot *Snapshot) []*PublishedRepo {
result := make([]*PublishedRepo, 0)
for _, r := range collection.list {
if r.SnapshotUUID == snapshot.UUID {
result = append(result, r)
}
}
return result
}
// ForEach runs method for each repository
func (collection *PublishedRepoCollection) ForEach(handler func(*PublishedRepo) error) error {
var err error
+30 -11
View File
@@ -8,8 +8,25 @@ import (
"path/filepath"
)
type pathExistsChecker struct {
*CheckerInfo
}
var PathExists = &pathExistsChecker{
&CheckerInfo{Name: "PathExists", Params: []string{"path"}},
}
func (checker *pathExistsChecker) Check(params []interface{}, names []string) (result bool, error string) {
_, err := os.Stat(params[0].(string))
return err == nil, ""
}
type NullSigner struct{}
func (n *NullSigner) Init() error {
return nil
}
func (n *NullSigner) SetKey(keyRef string) {
}
@@ -165,6 +182,13 @@ func (s *PublishedRepoSuite) TestPublish(c *C) {
c.Assert(err, IsNil)
}
func (s *PublishedRepoSuite) TestPublishNoSigner(c *C) {
err := s.repo.Publish(s.packageRepo, s.packageCollection, nil)
c.Assert(err, IsNil)
c.Check(filepath.Join(s.packageRepo.RootPath, "public/ppa/dists/squeeze/Release"), PathExists)
}
func (s *PublishedRepoSuite) TestString(c *C) {
c.Check(s.repo.String(), Equals,
"ppa/squeeze (main) publishes [snap]: Snapshot from mirror [yandex]: http://mirror.yandex.ru/debian/ squeeze")
@@ -223,7 +247,7 @@ func (s *PublishedRepoCollectionSuite) TearDownTest(c *C) {
s.db.Close()
}
func (s *PublishedRepoCollectionSuite) TestAddByName(c *C) {
func (s *PublishedRepoCollectionSuite) TestAddByPrefixDistribution(c *C) {
r, err := s.collection.ByPrefixDistribution("ppa", "anaconda")
c.Assert(err, ErrorMatches, "*.not found")
@@ -296,17 +320,12 @@ func (s *PublishedRepoCollectionSuite) TestForEachAndLen(c *C) {
c.Assert(err, Equals, e)
}
type pathExistsChecker struct {
*CheckerInfo
}
func (s *PublishedRepoCollectionSuite) TestBySnapshot(c *C) {
c.Check(s.collection.Add(s.repo1), IsNil)
c.Check(s.collection.Add(s.repo2), IsNil)
var PathExists = &pathExistsChecker{
&CheckerInfo{Name: "PathExists", Params: []string{"path"}},
}
func (checker *pathExistsChecker) Check(params []interface{}, names []string) (result bool, error string) {
_, err := os.Stat(params[0].(string))
return err == nil, ""
c.Check(s.collection.BySnapshot(s.snap1), DeepEquals, []*PublishedRepo{s.repo1})
c.Check(s.collection.BySnapshot(s.snap2), DeepEquals, []*PublishedRepo{s.repo2})
}
type PublishedRepoRemoveSuite struct {
+193 -20
View File
@@ -10,6 +10,8 @@ import (
"github.com/ugorji/go/codec"
"log"
"net/url"
"os"
"strconv"
"strings"
"time"
)
@@ -35,6 +37,8 @@ type RemoteRepo struct {
Meta Stanza
// Last update date
LastDownloadDate time.Time
// Checksums for release files
ReleaseFiles map[string]utils.ChecksumInfo
// "Snapshot" of current list of packages
packageRefs *PackageRefList
// Parsed archived root
@@ -56,6 +60,17 @@ func NewRemoteRepo(name string, archiveRoot string, distribution string, compone
if err != nil {
return nil, err
}
if result.Distribution == "." || result.Distribution == "./" {
// flat repo
result.Distribution = ""
result.Architectures = nil
if len(result.Components) > 0 {
return nil, fmt.Errorf("components aren't supported for flat repos")
}
result.Components = nil
}
return result, nil
}
@@ -70,6 +85,11 @@ func (repo *RemoteRepo) String() string {
return fmt.Sprintf("[%s]: %s %s", repo.Name, repo.ArchiveRoot, repo.Distribution)
}
// IsFlat determines if repository is flat
func (repo *RemoteRepo) IsFlat() bool {
return repo.Distribution == ""
}
// NumPackages return number of packages retrived from remore repo
func (repo *RemoteRepo) NumPackages() int {
if repo.packageRefs == nil {
@@ -78,10 +98,27 @@ func (repo *RemoteRepo) NumPackages() int {
return repo.packageRefs.Len()
}
// ReleaseURL returns URL to Release file in repo root
// TODO: InRelease, Release.gz, Release.bz2 handling
func (repo *RemoteRepo) ReleaseURL() *url.URL {
path := &url.URL{Path: fmt.Sprintf("dists/%s/Release", repo.Distribution)}
// RefList returns package list for repo
func (repo *RemoteRepo) RefList() *PackageRefList {
return repo.packageRefs
}
// ReleaseURL returns URL to Release* files in repo root
func (repo *RemoteRepo) ReleaseURL(name string) *url.URL {
var path *url.URL
if !repo.IsFlat() {
path = &url.URL{Path: fmt.Sprintf("dists/%s/%s", repo.Distribution, name)}
} else {
path = &url.URL{Path: name}
}
return repo.archiveRootURL.ResolveReference(path)
}
// FlatBinaryURL returns URL to Package files for flat repo
func (repo *RemoteRepo) FlatBinaryURL() *url.URL {
path := &url.URL{Path: "Packages"}
return repo.archiveRootURL.ResolveReference(path)
}
@@ -100,12 +137,57 @@ func (repo *RemoteRepo) PackageURL(filename string) *url.URL {
}
// Fetch updates information about repository
func (repo *RemoteRepo) Fetch(d utils.Downloader) error {
// Download release file to temporary URL
release, err := utils.DownloadTemp(d, repo.ReleaseURL().String())
func (repo *RemoteRepo) Fetch(d utils.Downloader, verifier utils.Verifier) error {
var (
release *os.File
err error
)
if verifier == nil {
// 0. Just download release file to temporary URL
release, err = utils.DownloadTemp(d, repo.ReleaseURL("Release").String())
if err != nil {
return err
}
} else {
// 1. try InRelease file
inrelease, err := utils.DownloadTemp(d, repo.ReleaseURL("InRelease").String())
if err != nil {
goto splitsignature
}
defer inrelease.Close()
release, err = verifier.VerifyClearsigned(inrelease)
if err != nil {
goto splitsignature
}
goto ok
splitsignature:
// 2. try Release + Release.gpg
release, err = utils.DownloadTemp(d, repo.ReleaseURL("Release").String())
if err != nil {
return err
}
releasesig, err := utils.DownloadTemp(d, repo.ReleaseURL("Release.gpg").String())
if err != nil {
return err
}
err = verifier.VerifyDetachedSignature(releasesig, release)
if err != nil {
return err
}
_, err = release.Seek(0, 0)
if err != nil {
return err
}
}
ok:
defer release.Close()
sreader := NewControlFileReader(release)
@@ -114,6 +196,7 @@ func (repo *RemoteRepo) Fetch(d utils.Downloader) error {
return err
}
if !repo.IsFlat() {
architectures := strings.Split(stanza["Architectures"], " ")
if len(repo.Architectures) == 0 {
repo.Architectures = architectures
@@ -135,25 +218,81 @@ func (repo *RemoteRepo) Fetch(d utils.Downloader) error {
return err
}
}
}
repo.ReleaseFiles = make(map[string]utils.ChecksumInfo)
parseSums := func(field string, setter func(sum *utils.ChecksumInfo, data string)) error {
for _, line := range strings.Split(stanza[field], "\n") {
line = strings.TrimSpace(line)
if line == "" {
continue
}
parts := strings.Fields(line)
if len(parts) != 3 {
return fmt.Errorf("unparseable hash sum line: %#v", line)
}
size, err := strconv.ParseInt(parts[1], 10, 64)
if err != nil {
return fmt.Errorf("unable to parse size: %s", err)
}
sum := repo.ReleaseFiles[parts[2]]
sum.Size = size
setter(&sum, parts[0])
repo.ReleaseFiles[parts[2]] = sum
}
delete(stanza, field)
return nil
}
err = parseSums("MD5Sum", func(sum *utils.ChecksumInfo, data string) { sum.MD5 = data })
if err != nil {
return err
}
err = parseSums("SHA1", func(sum *utils.ChecksumInfo, data string) { sum.SHA1 = data })
if err != nil {
return err
}
err = parseSums("SHA256", func(sum *utils.ChecksumInfo, data string) { sum.SHA256 = data })
if err != nil {
return err
}
delete(stanza, "MD5Sum")
delete(stanza, "SHA1")
delete(stanza, "SHA256")
repo.Meta = stanza
return nil
}
// Download downloads all repo files
func (repo *RemoteRepo) Download(d utils.Downloader, packageCollection *PackageCollection, packageRepo *Repository) error {
func (repo *RemoteRepo) Download(d utils.Downloader, packageCollection *PackageCollection, packageRepo *Repository, ignoreMismatch bool) error {
list := NewPackageList()
fmt.Printf("Downloading & parsing package files...\n")
d.GetProgress().Printf("Downloading & parsing package files...\n")
// Download and parse all Release files
// Download and parse all Packages files
packagesURLs := []string{}
if repo.IsFlat() {
packagesURLs = append(packagesURLs, repo.FlatBinaryURL().String())
} else {
for _, component := range repo.Components {
for _, architecture := range repo.Architectures {
packagesReader, packagesFile, err := utils.DownloadTryCompression(d, repo.BinaryURL(component, architecture).String())
packagesURLs = append(packagesURLs, repo.BinaryURL(component, architecture).String())
}
}
}
for _, url := range packagesURLs {
packagesReader, packagesFile, err := utils.DownloadTryCompression(d, url, repo.ReleaseFiles, ignoreMismatch)
if err != nil {
return err
}
@@ -175,12 +314,14 @@ func (repo *RemoteRepo) Download(d utils.Downloader, packageCollection *PackageC
list.Add(p)
}
}
}
fmt.Printf("Saving packages to database...\n")
d.GetProgress().Printf("Saving packages to database...\n")
d.GetProgress().InitBar(int64(list.Len()), false)
// Save package meta information to DB
err := list.ForEach(func(p *Package) error {
d.GetProgress().AddBar(1)
return packageCollection.Update(p)
})
@@ -188,7 +329,9 @@ func (repo *RemoteRepo) Download(d utils.Downloader, packageCollection *PackageC
return fmt.Errorf("unable to save packages to db: %s", err)
}
fmt.Printf("Building download queue...\n")
d.GetProgress().ShutdownBar()
d.GetProgress().Printf("Building download queue...\n")
// Build download queue
queued := make(map[string]PackageDownloadTask, list.Len())
@@ -206,7 +349,7 @@ func (repo *RemoteRepo) Download(d utils.Downloader, packageCollection *PackageC
_, found := queued[key]
if !found {
count++
downloadSize += task.Size
downloadSize += task.Checksums.Size
queued[key] = task
}
}
@@ -218,13 +361,15 @@ func (repo *RemoteRepo) Download(d utils.Downloader, packageCollection *PackageC
return fmt.Errorf("unable to build download queue: %s", err)
}
fmt.Printf("Download queue: %d items, %.2f GiB size\n", count, float64(downloadSize)/(1024.0*1024.0*1024.0))
d.GetProgress().Printf("Download queue: %d items, %.2f GiB size\n", count, float64(downloadSize)/(1024.0*1024.0*1024.0))
d.GetProgress().InitBar(downloadSize, true)
// Download all package files
ch := make(chan error, len(queued))
for _, task := range queued {
d.Download(repo.PackageURL(task.RepoURI).String(), task.DestinationPath, ch)
d.DownloadWithChecksum(repo.PackageURL(task.RepoURI).String(), task.DestinationPath, ch, task.Checksums, ignoreMismatch)
}
// Wait for all downloads to finish
@@ -238,6 +383,8 @@ func (repo *RemoteRepo) Download(d utils.Downloader, packageCollection *PackageC
count--
}
d.GetProgress().ShutdownBar()
if len(errors) > 0 {
return fmt.Errorf("download errors:\n %s\n", strings.Join(errors, "\n "))
}
@@ -387,3 +534,29 @@ func (collection *RemoteRepoCollection) ForEach(handler func(*RemoteRepo) error)
func (collection *RemoteRepoCollection) Len() int {
return len(collection.list)
}
// Drop removes remote repo from collection
func (collection *RemoteRepoCollection) Drop(repo *RemoteRepo) error {
repoPosition := -1
for i, r := range collection.list {
if r == repo {
repoPosition = i
break
}
}
if repoPosition == -1 {
panic("repo not found!")
}
collection.list[len(collection.list)-1], collection.list[repoPosition], collection.list =
nil, collection.list[len(collection.list)-1], collection.list[:len(collection.list)-1]
err := collection.db.Delete(repo.Key())
if err != nil {
return err
}
return collection.db.Delete(repo.RefKey())
}
+150 -12
View File
@@ -4,7 +4,10 @@ import (
"errors"
"github.com/smira/aptly/database"
"github.com/smira/aptly/utils"
"io"
"io/ioutil"
. "launchpad.net/gocheck"
"os"
"testing"
)
@@ -13,6 +16,29 @@ func Test(t *testing.T) {
TestingT(t)
}
type NullVerifier struct {
}
func (n *NullVerifier) InitKeyring() error {
return nil
}
func (n *NullVerifier) AddKeyring(keyring string) {
}
func (n *NullVerifier) VerifyDetachedSignature(signature, cleartext io.Reader) error {
return nil
}
func (n *NullVerifier) VerifyClearsigned(clearsigned io.Reader) (text *os.File, err error) {
text, _ = ioutil.TempFile("", "aptly-test")
io.Copy(text, clearsigned)
text.Seek(0, 0)
os.Remove(text.Name())
return
}
type PackageListMixinSuite struct {
p1, p2, p3 *Package
list *PackageList
@@ -40,6 +66,7 @@ func (s *PackageListMixinSuite) SetUpPackages() {
type RemoteRepoSuite struct {
PackageListMixinSuite
repo *RemoteRepo
flat *RemoteRepo
downloader *utils.FakeDownloader
db database.Storage
packageCollection *PackageCollection
@@ -50,6 +77,7 @@ var _ = Suite(&RemoteRepoSuite{})
func (s *RemoteRepoSuite) SetUpTest(c *C) {
s.repo, _ = NewRemoteRepo("yandex", "http://mirror.yandex.ru/debian/", "squeeze", []string{"main"}, []string{})
s.flat, _ = NewRemoteRepo("exp42", "http://repos.express42.com/virool/precise/", "./", []string{}, []string{})
s.downloader = utils.NewFakeDownloader().ExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/Release", exampleReleaseFile)
s.db, _ = database.OpenDB(c.MkDir())
s.packageCollection = NewPackageCollection(s.db)
@@ -66,42 +94,100 @@ func (s *RemoteRepoSuite) TestInvalidURL(c *C) {
c.Assert(err, ErrorMatches, ".*hexadecimal escape in host.*")
}
func (s *RemoteRepoSuite) TestFlatCreation(c *C) {
c.Check(s.flat.Distribution, Equals, "")
c.Check(s.flat.Architectures, IsNil)
c.Check(s.flat.Components, IsNil)
_, err := NewRemoteRepo("fl", "http://some.repo/", "./", []string{"main"}, []string{})
c.Check(err, ErrorMatches, "components aren't supported for flat repos")
}
func (s *RemoteRepoSuite) TestNumPackages(c *C) {
c.Check(s.repo.NumPackages(), Equals, 0)
s.repo.packageRefs = s.reflist
c.Check(s.repo.NumPackages(), Equals, 3)
}
func (s *RemoteRepoSuite) TestIsFlat(c *C) {
c.Check(s.repo.IsFlat(), Equals, false)
c.Check(s.flat.IsFlat(), Equals, true)
}
func (s *RemoteRepoSuite) TestRefList(c *C) {
s.repo.packageRefs = s.reflist
c.Check(s.repo.RefList(), Equals, s.reflist)
}
func (s *RemoteRepoSuite) TestReleaseURL(c *C) {
c.Assert(s.repo.ReleaseURL().String(), Equals, "http://mirror.yandex.ru/debian/dists/squeeze/Release")
c.Assert(s.repo.ReleaseURL("Release").String(), Equals, "http://mirror.yandex.ru/debian/dists/squeeze/Release")
c.Assert(s.repo.ReleaseURL("InRelease").String(), Equals, "http://mirror.yandex.ru/debian/dists/squeeze/InRelease")
c.Assert(s.flat.ReleaseURL("Release").String(), Equals, "http://repos.express42.com/virool/precise/Release")
}
func (s *RemoteRepoSuite) TestBinaryURL(c *C) {
c.Assert(s.repo.BinaryURL("main", "amd64").String(), Equals, "http://mirror.yandex.ru/debian/dists/squeeze/main/binary-amd64/Packages")
}
func (s *RemoteRepoSuite) TestFlatBinaryURL(c *C) {
c.Assert(s.flat.FlatBinaryURL().String(), Equals, "http://repos.express42.com/virool/precise/Packages")
}
func (s *RemoteRepoSuite) TestPackageURL(c *C) {
c.Assert(s.repo.PackageURL("pool/main/0/0ad/0ad_0~r11863-2_i386.deb").String(), Equals,
"http://mirror.yandex.ru/debian/pool/main/0/0ad/0ad_0~r11863-2_i386.deb")
}
func (s *RemoteRepoSuite) TestFetch(c *C) {
err := s.repo.Fetch(s.downloader)
err := s.repo.Fetch(s.downloader, nil)
c.Assert(err, IsNil)
c.Assert(s.repo.Architectures, DeepEquals, []string{"amd64", "armel", "armhf", "i386", "powerpc"})
c.Assert(s.repo.Components, DeepEquals, []string{"main"})
c.Assert(s.downloader.Empty(), Equals, true)
c.Check(s.repo.ReleaseFiles, HasLen, 39)
c.Check(s.repo.ReleaseFiles["main/binary-i386/Packages.bz2"], DeepEquals,
utils.ChecksumInfo{
Size: 734,
MD5: "7954ed80936429687122b554620c1b5b",
SHA1: "95a463a0739bf9ff622c8d68f6e4598d400f5248",
SHA256: "377890a26f99db55e117dfc691972dcbbb7d8be1630c8fc8297530c205377f2b"})
}
func (s *RemoteRepoSuite) TestFetchNullVerifier1(c *C) {
downloader := utils.NewFakeDownloader()
downloader.ExpectError("http://mirror.yandex.ru/debian/dists/squeeze/InRelease", errors.New("404"))
downloader.ExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/Release", exampleReleaseFile)
downloader.ExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/Release.gpg", "GPG")
err := s.repo.Fetch(downloader, &NullVerifier{})
c.Assert(err, IsNil)
c.Assert(s.repo.Architectures, DeepEquals, []string{"amd64", "armel", "armhf", "i386", "powerpc"})
c.Assert(s.repo.Components, DeepEquals, []string{"main"})
c.Assert(downloader.Empty(), Equals, true)
}
func (s *RemoteRepoSuite) TestFetchNullVerifier2(c *C) {
downloader := utils.NewFakeDownloader()
downloader.ExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/InRelease", exampleReleaseFile)
err := s.repo.Fetch(downloader, &NullVerifier{})
c.Assert(err, IsNil)
c.Assert(s.repo.Architectures, DeepEquals, []string{"amd64", "armel", "armhf", "i386", "powerpc"})
c.Assert(s.repo.Components, DeepEquals, []string{"main"})
c.Assert(downloader.Empty(), Equals, true)
}
func (s *RemoteRepoSuite) TestFetchWrongArchitecture(c *C) {
s.repo, _ = NewRemoteRepo("s", "http://mirror.yandex.ru/debian/", "squeeze", []string{"main"}, []string{"xyz"})
err := s.repo.Fetch(s.downloader)
err := s.repo.Fetch(s.downloader, nil)
c.Assert(err, ErrorMatches, "architecture xyz not available in repo.*")
}
func (s *RemoteRepoSuite) TestFetchWrongComponent(c *C) {
s.repo, _ = NewRemoteRepo("s", "http://mirror.yandex.ru/debian/", "squeeze", []string{"xyz"}, []string{"i386"})
err := s.repo.Fetch(s.downloader)
err := s.repo.Fetch(s.downloader, nil)
c.Assert(err, ErrorMatches, "component xyz not available in repo.*")
}
@@ -128,7 +214,7 @@ func (s *RemoteRepoSuite) TestRefKey(c *C) {
func (s *RemoteRepoSuite) TestDownload(c *C) {
s.repo.Architectures = []string{"i386"}
err := s.repo.Fetch(s.downloader)
err := s.repo.Fetch(s.downloader, nil)
c.Assert(err, IsNil)
s.downloader.ExpectError("http://mirror.yandex.ru/debian/dists/squeeze/main/binary-i386/Packages.bz2", errors.New("HTTP 404"))
@@ -136,7 +222,7 @@ func (s *RemoteRepoSuite) TestDownload(c *C) {
s.downloader.ExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/main/binary-i386/Packages", examplePackagesFile)
s.downloader.ExpectResponse("http://mirror.yandex.ru/debian/pool/main/a/amanda/amanda-client_3.3.1-3~bpo60+1_amd64.deb", "xyz")
err = s.repo.Download(s.downloader, s.packageCollection, s.packageRepo)
err = s.repo.Download(s.downloader, s.packageCollection, s.packageRepo, false)
c.Assert(err, IsNil)
c.Assert(s.downloader.Empty(), Equals, true)
c.Assert(s.repo.packageRefs, NotNil)
@@ -151,6 +237,32 @@ func (s *RemoteRepoSuite) TestDownload(c *C) {
c.Check(pkg.Name, Equals, "amanda-client")
}
func (s *RemoteRepoSuite) TestDownloadFlat(c *C) {
downloader := utils.NewFakeDownloader()
downloader.ExpectResponse("http://repos.express42.com/virool/precise/Release", exampleReleaseFile)
downloader.ExpectError("http://repos.express42.com/virool/precise/Packages.bz2", errors.New("HTTP 404"))
downloader.ExpectError("http://repos.express42.com/virool/precise/Packages.gz", errors.New("HTTP 404"))
downloader.ExpectResponse("http://repos.express42.com/virool/precise/Packages", examplePackagesFile)
downloader.ExpectResponse("http://repos.express42.com/virool/precise/pool/main/a/amanda/amanda-client_3.3.1-3~bpo60+1_amd64.deb", "xyz")
err := s.flat.Fetch(downloader, nil)
c.Assert(err, IsNil)
err = s.flat.Download(downloader, s.packageCollection, s.packageRepo, false)
c.Assert(err, IsNil)
c.Assert(downloader.Empty(), Equals, true)
c.Assert(s.flat.packageRefs, NotNil)
pkg, err := s.packageCollection.ByKey(s.flat.packageRefs.Refs[0])
c.Assert(err, IsNil)
result, err := pkg.VerifyFiles(s.packageRepo)
c.Check(result, Equals, true)
c.Check(err, IsNil)
c.Check(pkg.Name, Equals, "amanda-client")
}
type RemoteRepoCollectionSuite struct {
PackageListMixinSuite
db database.Storage
@@ -242,6 +354,32 @@ func (s *RemoteRepoCollectionSuite) TestForEachAndLen(c *C) {
c.Assert(err, Equals, e)
}
func (s *RemoteRepoCollectionSuite) TestDrop(c *C) {
repo1, _ := NewRemoteRepo("yandex", "http://mirror.yandex.ru/debian/", "squeeze", []string{"main"}, []string{})
s.collection.Add(repo1)
repo2, _ := NewRemoteRepo("tyndex", "http://mirror.yandex.ru/debian/", "wheezy", []string{"main"}, []string{})
s.collection.Add(repo2)
r1, _ := s.collection.ByUUID(repo1.UUID)
c.Check(r1, Equals, repo1)
err := s.collection.Drop(repo1)
c.Check(err, IsNil)
_, err = s.collection.ByUUID(repo1.UUID)
c.Check(err, ErrorMatches, "mirror .* not found")
collection := NewRemoteRepoCollection(s.db)
_, err = collection.ByName("yandex")
c.Check(err, ErrorMatches, "mirror .* not found")
r2, _ := collection.ByName("tyndex")
c.Check(r2.String(), Equals, repo2.String())
c.Check(func() { s.collection.Drop(repo1) }, Panics, "repo not found!")
}
const exampleReleaseFile = `Origin: LP-PPA-agenda-developers-daily
Label: Agenda Daily Builds
Suite: precise
@@ -264,7 +402,7 @@ MD5Sum:
c63d31e8e3a5650c29a7124e541d6c23 134 main/binary-armhf/Release
4059d198768f9f8dc9372dc1c54bc3c3 14 main/binary-armhf/Packages.bz2
d41d8cd98f00b204e9800998ecf8427e 0 main/binary-armhf/Packages
708fc548e709eea0dfd2d7edb6098829 1344 main/binary-i386/Packages
c8d336856df67d509032bb54145c2f89 826 main/binary-i386/Packages
92262f0668b265401291f0467bc93763 133 main/binary-i386/Release
7954ed80936429687122b554620c1b5b 734 main/binary-i386/Packages.bz2
e2eef4fe7d285b12c511adfa3a39069e 641 main/binary-i386/Packages.gz
@@ -304,7 +442,7 @@ SHA1:
585a452e27c2e7e047c49d4b0a7459d8c627aa08 134 main/binary-armhf/Release
64a543afbb5f4bf728636bdcbbe7a2ed0804adc2 14 main/binary-armhf/Packages.bz2
da39a3ee5e6b4b0d3255bfef95601890afd80709 0 main/binary-armhf/Packages
2bfad956c2d2437924a8527970858c59823451b7 1344 main/binary-i386/Packages
1d2f0cd7a3c9e687b853eb277e241cd712b6e3b1 826 main/binary-i386/Packages
16020809662f9bda36eb516d0995658dd94d1ad5 133 main/binary-i386/Release
95a463a0739bf9ff622c8d68f6e4598d400f5248 734 main/binary-i386/Packages.bz2
bf8c0dec9665ba78311c97cae1755d4b2e60af76 641 main/binary-i386/Packages.gz
@@ -344,7 +482,7 @@ SHA256:
d25382b633c4a1621f8df6ce86e5c63da2e506a377e05ae9453238bb18191540 134 main/binary-armhf/Release
d3dda84eb03b9738d118eb2be78e246106900493c0ae07819ad60815134a8058 14 main/binary-armhf/Packages.bz2
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 main/binary-armhf/Packages
9cd4bad3462e795bad509a44bae48622f2e9c9e56aafc999419cc5221f087dc8 1344 main/binary-i386/Packages
b1bb341bb613363ca29440c2eb9c08a9289de5458209990ec502ed27711a83a2 826 main/binary-i386/Packages
e5aaceaac5ecb59143a4b4ed2bf700fe85d6cf08addd10cf2058bde697b7b219 133 main/binary-i386/Release
377890a26f99db55e117dfc691972dcbbb7d8be1630c8fc8297530c205377f2b 734 main/binary-i386/Packages.bz2
6361e8efc67d2e7c1a8db45388aec0311007c0a1bd96698623ddeb5ed0bdc914 641 main/binary-i386/Packages.gz
@@ -388,7 +526,7 @@ Section: utils
Priority: optional
Filename: pool/main/a/amanda/amanda-client_3.3.1-3~bpo60+1_amd64.deb
Size: 3
MD5sum: cdc997dc06126e18ea9ba843efed9811
SHA1: 049ba341d520c447fa2e6a1f8c871b3dbbe00106
SHA256: 4487115ca47fe9acd95355b9278f30e18c53f33c385252252d3d7948d650d1d0
MD5sum: d16fb36f0911f878998c136191af705e
SHA1: 66b27417d37e024c46526c2f6d358a754fc552f3
SHA256: 3608bca1e44ea6c4d268eb6db02260269892c0b42b86bbf1e77a6fa16c3c9282
`
+1 -1
View File
@@ -88,6 +88,6 @@ func (r *Repository) LinkFromPool(prefix string, component string, sourcePath st
}
// ChecksumsForFile proxies requests to utils.ChecksumsForFile, joining public path
func (r *Repository) ChecksumsForFile(path string) (*utils.ChecksumInfo, error) {
func (r *Repository) ChecksumsForFile(path string) (utils.ChecksumInfo, error) {
return utils.ChecksumsForFile(filepath.Join(r.RootPath, "public", path))
}
+51
View File
@@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"github.com/smira/aptly/database"
"github.com/smira/aptly/utils"
"github.com/ugorji/go/codec"
"log"
"time"
@@ -194,6 +195,30 @@ func (collection *SnapshotCollection) ByUUID(uuid string) (*Snapshot, error) {
return nil, fmt.Errorf("snapshot with uuid %s not found", uuid)
}
// ByRemoteRepoSource looks up snapshots that have specified RepoteRepo as a source
func (collection *SnapshotCollection) ByRemoteRepoSource(repo *RemoteRepo) []*Snapshot {
result := make([]*Snapshot, 0)
for _, s := range collection.list {
if s.SourceKind == "repo" && utils.StrSliceHasItem(s.SourceIDs, repo.UUID) {
result = append(result, s)
}
}
return result
}
// BySnapshotSource looks up snapshots that have specified snapshot as a source
func (collection *SnapshotCollection) BySnapshotSource(snapshot *Snapshot) []*Snapshot {
result := make([]*Snapshot, 0)
for _, s := range collection.list {
if s.SourceKind == "snapshot" && utils.StrSliceHasItem(s.SourceIDs, snapshot.UUID) {
result = append(result, s)
}
}
return result
}
// ForEach runs method for each snapshot
func (collection *SnapshotCollection) ForEach(handler func(*Snapshot) error) error {
var err error
@@ -211,3 +236,29 @@ func (collection *SnapshotCollection) ForEach(handler func(*Snapshot) error) err
func (collection *SnapshotCollection) Len() int {
return len(collection.list)
}
// Drop removes snapshot from collection
func (collection *SnapshotCollection) Drop(snapshot *Snapshot) error {
snapshotPosition := -1
for i, s := range collection.list {
if s == snapshot {
snapshotPosition = i
break
}
}
if snapshotPosition == -1 {
panic("snapshot not found!")
}
collection.list[len(collection.list)-1], collection.list[snapshotPosition], collection.list =
nil, collection.list[len(collection.list)-1], collection.list[:len(collection.list)-1]
err := collection.db.Delete(snapshot.Key())
if err != nil {
return err
}
return collection.db.Delete(snapshot.RefKey())
}
+49
View File
@@ -158,3 +158,52 @@ func (s *SnapshotCollectionSuite) TestForEachAndLen(c *C) {
})
c.Assert(err, Equals, e)
}
func (s *SnapshotCollectionSuite) TestFindByRemoteRepoSource(c *C) {
c.Assert(s.collection.Add(s.snapshot1), IsNil)
c.Assert(s.collection.Add(s.snapshot2), IsNil)
c.Check(s.collection.ByRemoteRepoSource(s.repo1), DeepEquals, []*Snapshot{s.snapshot1})
c.Check(s.collection.ByRemoteRepoSource(s.repo2), DeepEquals, []*Snapshot{s.snapshot2})
repo3, _ := NewRemoteRepo("other", "http://mirror.yandex.ru/debian/", "lenny", []string{"main"}, []string{})
c.Check(s.collection.ByRemoteRepoSource(repo3), DeepEquals, []*Snapshot{})
}
func (s *SnapshotCollectionSuite) TestFindSnapshotSource(c *C) {
snapshot3 := NewSnapshotFromRefList("snap3", []*Snapshot{s.snapshot1, s.snapshot2}, s.reflist, "desc1")
snapshot4 := NewSnapshotFromRefList("snap4", []*Snapshot{s.snapshot1}, s.reflist, "desc2")
snapshot5 := NewSnapshotFromRefList("snap5", []*Snapshot{snapshot3}, s.reflist, "desc3")
c.Assert(s.collection.Add(s.snapshot1), IsNil)
c.Assert(s.collection.Add(s.snapshot2), IsNil)
c.Assert(s.collection.Add(snapshot3), IsNil)
c.Assert(s.collection.Add(snapshot4), IsNil)
c.Assert(s.collection.Add(snapshot5), IsNil)
c.Check(s.collection.BySnapshotSource(s.snapshot1), DeepEquals, []*Snapshot{snapshot3, snapshot4})
c.Check(s.collection.BySnapshotSource(s.snapshot2), DeepEquals, []*Snapshot{snapshot3})
c.Check(s.collection.BySnapshotSource(snapshot5), DeepEquals, []*Snapshot{})
}
func (s *SnapshotCollectionSuite) TestDrop(c *C) {
s.collection.Add(s.snapshot1)
s.collection.Add(s.snapshot2)
snap, _ := s.collection.ByUUID(s.snapshot1.UUID)
c.Check(snap, Equals, s.snapshot1)
err := s.collection.Drop(s.snapshot1)
c.Check(err, IsNil)
_, err = s.collection.ByUUID(s.snapshot1.UUID)
c.Check(err, ErrorMatches, "snapshot .* not found")
collection := NewSnapshotCollection(s.db)
_, err = collection.ByUUID(s.snapshot1.UUID)
c.Check(err, ErrorMatches, "snapshot .* not found")
c.Check(func() { s.collection.Drop(s.snapshot1) }, Panics, "snapshot not found!")
}
+13 -1
View File
@@ -13,7 +13,7 @@ import (
)
// aptly version
const Version = "0.2"
const Version = "0.3"
var cmd *commander.Command
@@ -30,6 +30,8 @@ take snapshots and publish them back as Debian repositories.`,
makeCmdMirror(),
makeCmdSnapshot(),
makeCmdPublish(),
makeCmdServe(),
makeCmdGraph(),
makeCmdVersion(),
},
}
@@ -38,6 +40,7 @@ take snapshots and publish them back as Debian repositories.`,
cmd.Flag.Bool("dep-follow-recommends", false, "when processing dependencies, follow Recommends")
cmd.Flag.Bool("dep-follow-all-variants", false, "when processing dependencies, follow a & b if depdency is 'a|b'")
cmd.Flag.String("architectures", "", "list of architectures to consider during (comma-separated), default to all available")
cmd.Flag.String("config", "", "location of configuration file (default locations are /etc/aptly.conf, ~/.aptly.conf)")
}
var context struct {
@@ -59,6 +62,14 @@ func main() {
fatal(err)
}
configLocation := cmd.Flag.Lookup("config").Value.String()
if configLocation != "" {
err = utils.LoadConfig(configLocation, &utils.Config)
if err != nil {
fatal(err)
}
} else {
configLocations := []string{
filepath.Join(os.Getenv("HOME"), ".aptly.conf"),
"/etc/aptly.conf",
@@ -78,6 +89,7 @@ func main() {
fmt.Printf("Config file not found, creating default config at %s\n\n", configLocations[0])
utils.SaveConfig(configLocations[0], &utils.Config)
}
}
context.dependencyOptions = 0
if utils.Config.DepFollowSuggests || cmd.Flag.Lookup("dep-follow-suggests").Value.Get().(bool) {
Binary file not shown.
+19
View File
@@ -0,0 +1,19 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.5 (GNU/Linux)
mQGiBE9p65cRBACFOL5YS4kW6xieXa98meE+RVu1hfBi1n7ajAy+ZQOfNa2Xb9if
H8WAcwJD4cTZYB19/O/xVxCYf1hnC/T34XGC5PUzMzBDKde86UDqvT4YNHDQA/E1
I6UUzE0MgLINO4Dt7Mw62koVrlPXklc2Zn83ucZB7YgBzJOIBFUQLghikwCgnubS
n/9lw8Hm8CIsg4nWtHwHGPED/jXIsH7ON3PBx2wIdRsealsx5sPGHQSlq1grRHcN
YT5/glXmVqnexY/+IFhcpjjb3vMMQ5LYq8+bDWGVMQx3GZrJs66rwPbo4kZ92OdC
RTnY/nznJlf5gS86DaFl+NFuO7F1k8ju4CurXXGXPF7nk8cgV6CrYHz1AtNyLVqa
306IA/9j9rdD/MY9SYT16eFMo7C2ieIS0RxxU3q9w0e8EucQKiHWMtjTPJ0Ik0GO
TY5lAPasnD6ZBA15XSiTi2Ck2QoZQZCxdtId/nL7lNG4+vQ8HACNDkxxK4yHJiFa
frMdlWi5cYgAMYzbYPekbhaamDR7Gh4NU7z72QZTPELKyZD/pbRGaG9tZTpEZWVw
RGl2ZXIxOTc1IE9CUyBQcm9qZWN0IDxob21lOkRlZXBEaXZlcjE5NzVAYnVpbGQu
b3BlbnN1c2Uub3JnPohlBBMRAgAmBQJPaeuXAhsDBQkEHrAABgsJCAcDAgQVAggD
BBYCAwECHgECF4AACgkQuCWWGBBIwf+tEgCcDEzTAilZDvOr0OKHHmguuKFXoHMA
ljX7B6nKOYoiHoGpBeOwr8U5ZB6IRgQTEQIABgUCT2nrlwAKCRA7MBG3a51lI7Rt
AJ4mYeomQiHHfd+7c8T0JhbGKUIDlACglHyTlouU5vCpUEHDyLvwrHFylpk=
=b/6f
-----END PGP PUBLIC KEY BLOCK-----
+3
View File
@@ -9,3 +9,6 @@ aptly mirror update wheezy-contrib
aptly mirror update wheezy-non-free
aptly mirror update wheezy-updates
aptly mirror update wheezy-backports
aptly mirror create gnuplot-maverick http://ppa.launchpad.net/gladky-anton/gnuplot/ubuntu/ maverick
aptly mirror update gnuplot-maverick
+100 -7
View File
@@ -7,9 +7,46 @@ import inspect
import json
import subprocess
import os
import posixpath
import shlex
import shutil
import string
import threading
import urllib
import SocketServer
import SimpleHTTPServer
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass
class FileHTTPServerRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def translate_path(self, path):
"""Translate a /-separated PATH to the local filename syntax.
Components that mean special things to the local file system
(e.g. drive or directory names) are ignored. (XXX They should
probably be diagnosed.)
"""
# abandon query parameters
path = path.split('?', 1)[0]
path = path.split('#', 1)[0]
path = posixpath.normpath(urllib.unquote(path))
words = path.split('/')
words = filter(None, words)
path = self.rootPath
for word in words:
drive, word = os.path.splitdrive(word)
head, word = os.path.split(word)
if word in (os.curdir, os.pardir):
continue
path = os.path.join(path, word)
return path
def log_message(self, format, *args):
pass
class BaseTest(object):
@@ -20,6 +57,8 @@ class BaseTest(object):
longTest = False
fixturePool = False
fixtureDB = False
fixtureGpg = False
fixtureWebServer = False
expectedCode = 0
configFile = {
@@ -28,7 +67,9 @@ class BaseTest(object):
"architectures": [],
"dependencyFollowSuggests": False,
"dependencyFollowRecommends": False,
"dependencyFollowAllVariants": False
"dependencyFollowAllVariants": False,
"gpgDisableVerify": False,
"gpgDisableSign": False,
}
configOverride = {}
@@ -47,6 +88,8 @@ class BaseTest(object):
shutil.rmtree(os.path.join(os.environ["HOME"], ".aptly"))
if os.path.exists(os.path.join(os.environ["HOME"], ".aptly.conf")):
os.remove(os.path.join(os.environ["HOME"], ".aptly.conf"))
if os.path.exists(os.path.join(os.environ["HOME"], ".gnupg", "aptlytest.gpg")):
os.remove(os.path.join(os.environ["HOME"], ".gnupg", "aptlytest.gpg"))
def prepare_default_config(self):
cfg = self.configFile.copy()
@@ -71,7 +114,19 @@ class BaseTest(object):
if self.fixtureDB:
shutil.copytree(self.fixtureDBDir, os.path.join(os.environ["HOME"], ".aptly", "db"))
if self.fixtureWebServer:
self.webServerUrl = self.start_webserver(os.path.join(os.path.dirname(inspect.getsourcefile(self.__class__)),
self.fixtureWebServer))
if self.fixtureGpg:
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", "flat.key")])
if hasattr(self, "fixtureCmds"):
if self.fixtureWebServer:
params = {'url': self.webServerUrl}
self.fixtureCmds = [string.Template(cmd).substitute(params) for cmd in self.fixtureCmds]
for cmd in self.fixtureCmds:
self.run_cmd(cmd)
@@ -80,7 +135,11 @@ class BaseTest(object):
def run_cmd(self, command, expected_code=0):
try:
proc = subprocess.Popen(shlex.split(command), stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
if not hasattr(command, "__iter__"):
command = shlex.split(command)
environ = os.environ.copy()
environ["LC_ALL"] = "C"
proc = subprocess.Popen(command, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, env=environ)
output, _ = proc.communicate()
if proc.returncode != expected_code:
raise Exception("exit code %d != %d (output: %s)" % (proc.returncode, expected_code, output))
@@ -104,8 +163,28 @@ class BaseTest(object):
def check_output(self):
self.verify_match(self.get_gold(), self.output, match_prepare=self.outputMatchPrepare)
def check_cmd_output(self, command, gold_name, match_prepare=None):
self.verify_match(self.get_gold(gold_name), self.run_cmd(command), match_prepare)
def check_cmd_output(self, command, gold_name, match_prepare=None, expected_code=0):
self.verify_match(self.get_gold(gold_name), self.run_cmd(command, expected_code=expected_code), match_prepare)
def read_file(self, path):
with open(os.path.join(os.environ["HOME"], ".aptly", path), "r") as f:
return f.read()
def check_file_contents(self, path, gold_name, match_prepare=None):
contents = self.read_file(path)
self.verify_match(self.get_gold(gold_name), contents, match_prepare=match_prepare)
def check_file(self):
self.verify_match(self.get_gold(), open(self.checkedFile, "r").read())
def check_exists(self, path):
if not os.path.exists(os.path.join(os.environ["HOME"], ".aptly", path)):
raise Exception("path %s doesn't exist" % (path, ))
def check_not_exists(self, path):
if os.path.exists(os.path.join(os.environ["HOME"], ".aptly", path)):
raise Exception("path %s exists" % (path, ))
def verify_match(self, a, b, match_prepare=None):
if match_prepare is not None:
@@ -117,12 +196,26 @@ class BaseTest(object):
raise Exception("content doesn't match:\n" + diff + "\n")
def check_file(self):
self.verify_match(self.get_gold(), open(self.checkedFile, "r").read())
check = check_output
def prepare(self):
self.prepare_remove_all()
self.prepare_default_config()
self.prepare_fixture()
def start_webserver(self, directory):
FileHTTPServerRequestHandler.rootPath = directory
self.webserver = ThreadedTCPServer(("localhost", 0), FileHTTPServerRequestHandler)
server_thread = threading.Thread(target=self.webserver.serve_forever)
server_thread.daemon = True
server_thread.start()
return "http://%s:%d/" % self.webserver.server_address
def shutdown(self):
if hasattr(self, 'webserver'):
self.shutdown_webserver()
def shutdown_webserver(self):
self.webserver.shutdown()
+12 -3
View File
@@ -15,10 +15,11 @@ except ImportError:
return s
def run(include_long_tests=False):
def run(include_long_tests=False, tests=None):
"""
Run system test.
"""
if tests is None:
tests = glob.glob("t*_*")
fails = []
numTests = numFailed = numSkipped = 0
@@ -51,6 +52,8 @@ def run(include_long_tests=False):
else:
sys.stdout.write(colored("OK\n", color="green"))
t.shutdown()
print "TESTS: %d SUCCESS: %d FAIL: %d SKIP: %d" % (numTests, numTests - numFailed, numFailed, numSkipped)
if len(fails) > 0:
@@ -65,5 +68,11 @@ def run(include_long_tests=False):
if __name__ == "__main__":
os.chdir(os.path.realpath(os.path.dirname(sys.argv[0])))
include_long_tests = len(sys.argv) > 1 and sys.argv[1] == "--long"
run(include_long_tests)
include_long_tests = False
tests = None
if len(sys.argv) > 1:
if sys.argv[1] == "--long":
include_long_tests = True
else:
tests = sys.argv[1:]
run(include_long_tests, tests)
+1 -1
View File
@@ -1 +1 @@
aptly version: 0.2
aptly version: 0.3
+20
View File
@@ -0,0 +1,20 @@
aptly - Debian repository management tool
Commands:
graph display graph of dependencies between aptly objects (requires graphviz)
mirror manage mirrors of remote repositories
publish manage published repositories
serve start embedded HTTP server to serve published repositories
snapshot manage snapshots of repositories
version display version
Use "aptly help <command>" for more information about a command.
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-suggests=false: when processing dependencies, follow Suggests
@@ -0,0 +1 @@
ERROR: open nosuchfile.conf: no such file or directory
+3 -1
View File
@@ -4,5 +4,7 @@
"architectures": [],
"dependencyFollowSuggests": false,
"dependencyFollowRecommends": false,
"dependencyFollowAllVariants": false
"dependencyFollowAllVariants": false,
"gpgDisableSign": false,
"gpgDisableVerify": false
}
+18
View File
@@ -3,6 +3,7 @@ Test config file
"""
import os
import inspect
from lib import BaseTest
@@ -33,3 +34,20 @@ class BadConfigTest(BaseTest):
f = open(os.path.join(os.environ["HOME"], ".aptly.conf"), "w")
f.write("{some crap")
f.close()
class ConfigInFileTest(BaseTest):
"""
config in other file test
"""
runCmd = ["aptly", "-config=%s" % (os.path.join(os.path.dirname(inspect.getsourcefile(BadConfigTest)), "aptly.conf"), )]
prepare = BaseTest.prepare_remove_all
class ConfigInMissingFileTest(BaseTest):
"""
config in other file test
"""
runCmd = ["aptly", "-config=nosuchfile.conf"]
expectedCode = 1
prepare = BaseTest.prepare_remove_all
+10
View File
@@ -0,0 +1,10 @@
{
"rootDir": "/tmp/aptly",
"downloadConcurrency": 4,
"architectures": [],
"dependencyFollowSuggests": false,
"dependencyFollowRecommends": false,
"dependencyFollowAllVariants": false,
"gpgDisableSign": false,
"gpgDisableVerify": false
}
+1
View File
@@ -4,6 +4,7 @@ take snapshots and publish them back as Debian repositories.
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-suggests=false: when processing dependencies, follow Suggests
+3
View File
@@ -2,8 +2,10 @@ aptly - Debian repository management tool
Commands:
graph display graph of dependencies between aptly objects (requires graphviz)
mirror manage mirrors of remote repositories
publish manage published repositories
serve start embedded HTTP server to serve published repositories
snapshot manage snapshots of repositories
version display version
@@ -12,6 +14,7 @@ Use "aptly help <command>" for more information about a command.
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-suggests=false: when processing dependencies, follow Suggests
@@ -5,3 +5,7 @@ Create records information about new mirror and fetches Release file (it doesn't
ex:
$ aptly mirror create wheezy-main http://mirror.yandex.ru/debian/ wheezy main
Options:
-ignore-signatures=false: disable verification of Release file signatures
-keyring=: gpg keyring to use when verifying Release file (could be specified multiple times)
+4
View File
@@ -2,3 +2,7 @@ Usage: aptly mirror create <name> <archive url> <distribution> [<component1> ...
aptly mirror create - create new mirror of Debian repository
Options:
-ignore-signatures=false: disable verification of Release file signatures
-keyring=: gpg keyring to use when verifying Release file (could be specified multiple times)
+1
View File
@@ -3,6 +3,7 @@ aptly mirror - manage mirrors of remote repositories
Commands:
create create new mirror of Debian repository
drop delete remote repository mirror
list list mirrors of remote repositories
show show details about remote repository mirror
update update packages from remote mirror
+1
View File
@@ -3,6 +3,7 @@ aptly mirror - manage mirrors of remote repositories
Commands:
create create new mirror of Debian repository
drop delete remote repository mirror
list list mirrors of remote repositories
show show details about remote repository mirror
update update packages from remote mirror
+10
View File
@@ -0,0 +1,10 @@
Downloading http://mirror.yandex.ru/debian-backports/dists/squeeze-backports/InRelease...
gpgv: keyblock resource `${HOME}/.gnupg/aptlytest.gpg': file open error
gpgv: RSA key ID 46925553
gpgv: Can't check signature: public key not found
Downloading http://mirror.yandex.ru/debian-backports/dists/squeeze-backports/Release...
Downloading http://mirror.yandex.ru/debian-backports/dists/squeeze-backports/Release.gpg...
gpgv: keyblock resource `${HOME}/.gnupg/aptlytest.gpg': file open error
gpgv: RSA key ID 46925553
gpgv: Can't check signature: public key not found
ERROR: unable to fetch mirror: verification of detached signature failed: exit status 2
+10
View File
@@ -0,0 +1,10 @@
Downloading http://mirror.yandex.ru/debian/dists/squeeze/InRelease...
Downloading http://mirror.yandex.ru/debian/dists/squeeze/Release...
Downloading http://mirror.yandex.ru/debian/dists/squeeze/Release.gpg...
gpgv: RSA key ID 473041FA
gpgv: Good signature from "Debian Archive Automatic Signing Key (6.0/squeeze) <ftpmaster@debian.org>"
gpgv: RSA key ID B98321F9
gpgv: Good signature from "Squeeze Stable Release Key <debian-release@lists.debian.org>"
Mirror [mirror11]: http://mirror.yandex.ru/debian/ squeeze successfully added.
You can run 'aptly mirror update mirror11' to download repository contents.
@@ -0,0 +1,18 @@
Name: mirror11
Archive Root URL: http://mirror.yandex.ru/debian/
Distribution: squeeze
Components: main, contrib, non-free
Architectures: amd64, armel, i386, ia64, kfreebsd-amd64, kfreebsd-i386, mips, mipsel, powerpc, s390, sparc
Last update: never
Information from release file:
Architectures: amd64 armel i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 sparc
Codename: squeeze
Components: main contrib non-free
Date: Sat, 19 Oct 2013 13:54:21 UTC
Description: Debian 6.0.8 Released 19 October 2013
Label: Debian
Origin: Debian
Suite: oldstable
Version: 6.0.8
@@ -0,0 +1,9 @@
Downloading http://mirror.yandex.ru/debian/dists/squeeze/InRelease...
Downloading http://mirror.yandex.ru/debian/dists/squeeze/Release...
Downloading http://mirror.yandex.ru/debian/dists/squeeze/Release.gpg...
gpgv: keyblock resource `${HOME}/.gnupg/aptlytest.gpg': file open error
gpgv: RSA key ID 473041FA
gpgv: Can't check signature: public key not found
gpgv: RSA key ID B98321F9
gpgv: Can't check signature: public key not found
ERROR: unable to fetch mirror: verification of detached signature failed: exit status 2
@@ -0,0 +1,4 @@
Downloading http://mirror.yandex.ru/debian/dists/wheezy/Release...
Mirror [mirror13]: http://mirror.yandex.ru/debian/ wheezy successfully added.
You can run 'aptly mirror update mirror13' to download repository contents.
@@ -0,0 +1,18 @@
Name: mirror13
Archive Root URL: http://mirror.yandex.ru/debian/
Distribution: wheezy
Components: main, contrib, non-free
Architectures: amd64, armel, armhf, i386, ia64, kfreebsd-amd64, kfreebsd-i386, mips, mipsel, powerpc, s390, s390x, sparc
Last update: never
Information from release file:
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
Codename: wheezy
Components: main contrib non-free
Date: Sat, 08 Feb 2014 10:36:03 UTC
Description: Debian 7.4 Released 08 February 2014
Label: Debian
Origin: Debian
Suite: stable
Version: 7.4
@@ -0,0 +1,8 @@
Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/InRelease...
Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Release...
Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Release.gpg...
gpgv: Signature made Tue May 21 23:01:30 2013 MSK using DSA key ID 1048C1FF
gpgv: Good signature from "home:DeepDiver1975 OBS Project <home:DeepDiver1975@build.opensuse.org>"
Mirror [mirror14]: http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/ successfully added.
You can run 'aptly mirror update mirror14' to download repository contents.
@@ -0,0 +1,14 @@
Name: mirror14
Archive Root URL: http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/
Distribution:
Components:
Architectures:
Last update: never
Information from release file:
Date: Tue May 21 21:01:30 2013
Description: Open Build Service home:DeepDiver1975 xUbuntu_10.04
Label: DeepDiver1975's Home Project (xUbuntu_10.04)
Origin: Open Build Service home:DeepDiver1975 xUbuntu_10.04
Version: 0.00
@@ -0,0 +1 @@
ERROR: unable to create mirror: components aren't supported for flat repos
@@ -9,10 +9,10 @@ Information from release file:
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
Codename: wheezy
Components: main contrib non-free
Date: Sat, 14 Dec 2013 10:51:30 UTC
Description: Debian 7.3 Released 14 December 2013
Date: Sat, 08 Feb 2014 10:36:03 UTC
Description: Debian 7.4 Released 08 February 2014
Label: Debian
Origin: Debian
Suite: stable
Version: 7.3
Version: 7.4
@@ -9,10 +9,10 @@ Information from release file:
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
Codename: wheezy
Components: main contrib non-free
Date: Sat, 14 Dec 2013 10:51:30 UTC
Description: Debian 7.3 Released 14 December 2013
Date: Sat, 08 Feb 2014 10:36:03 UTC
Description: Debian 7.4 Released 08 February 2014
Label: Debian
Origin: Debian
Suite: stable
Version: 7.3
Version: 7.4
@@ -9,10 +9,10 @@ Information from release file:
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
Codename: wheezy
Components: main contrib non-free
Date: Sat, 14 Dec 2013 10:51:30 UTC
Description: Debian 7.3 Released 14 December 2013
Date: Sat, 08 Feb 2014 10:36:03 UTC
Description: Debian 7.4 Released 08 February 2014
Label: Debian
Origin: Debian
Suite: stable
Version: 7.3
Version: 7.4
+1
View File
@@ -1,2 +1,3 @@
Downloading http://mirror.yandex.ru/debian/dists/suslik/InRelease...
Downloading http://mirror.yandex.ru/debian/dists/suslik/Release...
ERROR: unable to fetch mirror: HTTP code 404 while fetching http://mirror.yandex.ru/debian/dists/suslik/Release
@@ -9,10 +9,10 @@ Information from release file:
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
Codename: wheezy
Components: main contrib non-free
Date: Sat, 14 Dec 2013 10:51:30 UTC
Description: Debian 7.3 Released 14 December 2013
Date: Sat, 08 Feb 2014 10:36:03 UTC
Description: Debian 7.4 Released 08 February 2014
Label: Debian
Origin: Debian
Suite: stable
Version: 7.3
Version: 7.4
+9
View File
@@ -0,0 +1,9 @@
Downloading http://mirror.yandex.ru/debian-backports/dists/squeeze-backports/InRelease...
gpgv: Signature made Fri Feb 7 06:56:50 2014 MSK using RSA key ID 46925553
gpgv: Good signature from "Debian Archive Automatic Signing Key (7.0/wheezy) <ftpmaster@debian.org>"
gpg: Signature made Fri Feb 7 06:56:50 2014 MSK using RSA key ID 46925553
gpg: Good signature from "Debian Archive Automatic Signing Key (7.0/wheezy) <ftpmaster@debian.org>"
gpg: WARNING: Using untrusted key!
Mirror [mirror9]: http://mirror.yandex.ru/debian-backports/ squeeze-backports successfully added.
You can run 'aptly mirror update mirror9' to download repository contents.
@@ -0,0 +1,20 @@
Name: mirror9
Archive Root URL: http://mirror.yandex.ru/debian-backports/
Distribution: squeeze-backports
Components: main, contrib, non-free
Architectures: amd64, armel, i386, ia64, kfreebsd-amd64, kfreebsd-i386, mips, mipsel, powerpc, s390, sparc
Last update: never
Information from release file:
Architectures: amd64 armel i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 sparc
ButAutomaticUpgrades: yes
Codename: squeeze-backports
Components: main contrib non-free
Date: Fri, 07 Feb 2014 02:56:49 UTC
Description: Backports for the Squeeze Distribution
Label: Debian Backports
NotAutomatic: yes
Origin: Debian Backports
Suite: squeeze-backports
Valid-Until: Fri, 14 Feb 2014 02:56:49 UTC
+1
View File
@@ -0,0 +1 @@
Mirror `mirror1` has been removed.
@@ -0,0 +1 @@
ERROR: unable to show: mirror with name mirror1 not found
+3
View File
@@ -0,0 +1,3 @@
Mirror `wheezy-main` was used to create following snapshots:
* [wheez]: Snapshot from mirror [wheezy-main]: http://mirror.yandex.ru/debian/ wheezy
ERROR: won't delete mirror with snapshots, use -force to override
+1
View File
@@ -0,0 +1 @@
Mirror `wheezy-main` has been removed.
+1
View File
@@ -0,0 +1 @@
ERROR: unable to drop: mirror with name mirror1 not found
+3 -3
View File
@@ -9,10 +9,10 @@ Information from release file:
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
Codename: wheezy
Components: main contrib non-free
Date: Sat, 14 Dec 2013 10:51:30 UTC
Description: Debian 7.3 Released 14 December 2013
Date: Sat, 08 Feb 2014 10:36:03 UTC
Description: Debian 7.4 Released 08 February 2014
Label: Debian
Origin: Debian
Suite: stable
Version: 7.3
Version: 7.4
+345
View File
@@ -0,0 +1,345 @@
Name: wheezy-contrib
Archive Root URL: http://mirror.yandex.ru/debian/
Distribution: wheezy
Components: contrib
Architectures: i386, amd64
Last update: 2014-01-21 19:09:24 MSK
Number of packages: 325
Information from release file:
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
Codename: wheezy
Components: main contrib non-free
Date: Sat, 14 Dec 2013 10:51:30 UTC
Description: Debian 7.3 Released 14 December 2013
Label: Debian
Origin: Debian
Suite: stable
Version: 7.3
Packages:
bgoffice-dict-downloader-0.09_all
biomaj-watcher-1.2.1-1_all
cicero-0.7.2-2_all
cl-sql-oracle-6.2.0-1_all
cl-umlisp-1:2007ac.2-6_all
cl-umlisp-orf-3.3.2-3_all
cltl-1.0.26_all
crafty-bitmaps-1.0-1_all
crafty-books-medium-1.0.debian1-2_all
crafty-books-medtosmall-1.0.debian1-2_all
crafty-books-small-1.0.debian1-2_all
cytadela-data-1.0.1-2_all
dynagen-0.11.0-6_all
dynare-matlab-4.3.0-2_all
esix-1-2_all
festvox-don-1.4.0-4_all
festvox-en1-1.95-1_all
festvox-rablpc16k-1.4.0-2_all
festvox-rablpc8k-1.4.0-2_all
festvox-us1-1.95-1_all
festvox-us2-1.95-1_all
festvox-us3-1.95-1_all
firmware-b43-installer-1:015-14.1_all
firmware-b43-lpphy-installer-1:015-14.1_all
firmware-b43legacy-installer-1:015-14.1_all
game-data-packager-30_all
geoip-database-contrib-1.8_all
gns3-0.7.4-1_all
gnuvd-gnome-1.0.11-1_all
googleearth-package-0.7.0_all
horae-071~svn536-1_all
hts-voice-nitech-jp-atr503-m001-1.04-1_all
hyperspec-1.30+nmu2_all
ifeffit-doc-2:1.2.11d-8_all
imgtex-0.20050123-8_all
java-package-0.50+nmu2_all
kcemu-common-0.5.1+dfsg-5_all
libgooglecharts-ruby-1.6.8-2_all
libgooglecharts-ruby1.8-1.6.8-2_all
libjlapack-java-0.8~dfsg-1_all
libmtj-java-0.9.14~dfsg-2_all
libmtj-java-doc-0.9.14~dfsg-2_all
libnetlib-java-0.9.3-1_all
libviennacl-dev-1.2.0-2_all
libviennacl-doc-1.2.0-2_all
linux-wlan-ng-firmware-0.2.9+dfsg-5_all
mathematica-fonts-16_all
matlab-gdf-0.1.2-2_all
matlab-support-0.0.18_all
mess-desktop-entries-0.2-2_all
netdisco-mibs-installer-1.7.1_all
opendict-plugins-lingvosoft-0.8-2_all
ora2pg-8.11-1_all
phoronix-test-suite-3.8.0-1_all
playonlinux-4.1.1-1_all
premail-0.46-9_all
python-ldap-doc-2.3-2.2_all
python-pycuda-doc-2012.1-1_all
python-pycuda-headers-2012.1-1_all
python-pyopencl-doc-2012.1.dfsg-1_all
python-pyopencl-headers-2012.1.dfsg-1_all
qmhandle-1.3.2-1_all
quake-2_all
quake-server-2_all
quake3-1.4_all
quake3-server-1.4_all
raccoon-1.0-1_all
ruby-googlecharts-1.6.8-2_all
sabnzbdplus-0.6.15-1_all
sabnzbdplus-theme-classic-0.6.15-1_all
sabnzbdplus-theme-iphone-0.6.15-1_all
sabnzbdplus-theme-mobile-0.6.15-1_all
sabnzbdplus-theme-plush-0.6.15-1_all
sabnzbdplus-theme-smpl-0.6.15-1_all
sapgui-package-0.0.10_all
sauerbraten-wake6-1.0-1.1_all
sdic-2.1.3-22_all
sdic-edict-2.1.3-22_all
sdic-eijiro-2.1.3-22_all
sdic-gene95-2.1.3-22_all
series60-remote-0.4.0+dfsg.1-1_all
sixpack-1:0.68-1_all
sqldeveloper-package-0.2.4_all
sugar-etoys-activity-116-3_all
susv2-1.1_all
susv3-6.1_all
tightvnc-java-1.2.7-8_all
ttf-mathematica4.1-16_all
ttf-mscorefonts-installer-3.4+nmu1_all
ttf-root-installer-5.34.00-2_all
uqm-russian-1.0.2-5_all
vmware-manager-0.2.0-3_all
vnc-java-3.3.3r2-8_all
vusb-analyzer-1.1-3_all
winetricks-0.0+20121030+svn918-1_all
wnn7egg-1.02-8_all
x-pgp-sig-el-1.3.5.1-4.1_all
alien-arena-7.53+dfsg-3_amd64
alien-arena-server-7.53+dfsg-3_amd64
alsa-firmware-loaders-1.0.25-2_amd64
amoeba-1.1-26_amd64
assaultcube-1.1.0.4+dfsg2-1_amd64
atari800-2.2.1-2_amd64
b43-fwcutter-1:015-14.1_amd64
basilisk2-0.9.20120331-2_amd64
boinc-nvidia-cuda-7.0.27+dfsg-5_amd64
cbedic-4.0-3_amd64
chocolate-doom-1.7.0-3+b1_amd64
conky-all-1.9.0-2_amd64
cpp-doc-5:4_amd64
cytadela-1.0.1-2_amd64
cytadela-dbg-1.0.1-2_amd64
dosemu-1.4.0+svn.2080-1_amd64
e-uae-0.8.29-WIP4-10_amd64
e-uae-dbg-0.8.29-WIP4-10_amd64
easyspice-0.6.8-2_amd64
exult-1.2-15.2_amd64
exult-studio-1.2-15.2_amd64
flashplugin-nonfree-1:3.2_amd64
frogatto-1.2+dfsg-1+b1_amd64
gcc-doc-5:4_amd64
gcj-doc-5:4_amd64
gfortran-doc-5:4_amd64
glx-alternative-fglrx-0.2.2_amd64
glx-alternative-mesa-0.2.2_amd64
glx-alternative-nvidia-0.2.2_amd64
glx-diversions-0.2.2_amd64
gnat-doc-5:4_amd64
gnome-speech-swift-1:0.4.25-5_amd64
gnome-video-arcade-0.8.3-1_amd64
gnuboy-sdl-1.0.3-6.1_amd64
gnuboy-svga-1.0.3-6.1_amd64
gnuboy-x-1.0.3-6.1_amd64
gnuvd-1.0.11-1_amd64
gobi-loader-0.6-1_amd64
gtktrain-0.9b-13_amd64
hannah-foo2zjs-1:1_amd64
ifeffit-2:1.2.11d-8_amd64
isdnactivecards-1:3.9.20060704-11_amd64
isight-firmware-tools-1.6-1_amd64
iucode-tool-0.8.3-1_amd64
ivtv-utils-1.4.1-2_amd64
kcemu-0.5.1+dfsg-5_amd64
libcplgasgano20-6.1.1-2_amd64
libdbd-oracle-perl-1.44-1_amd64
libifeffit-perl-2:1.2.11d-8_amd64
libpgplot-perl-1:2.21-3_amd64
libsocl-contrib-1.0-1.0.1+dfsg-1_amd64
libstarpu-contrib-1.0-1.0.1+dfsg-1_amd64
libstarpu-contrib-dev-1.0.1+dfsg-1_amd64
libstarpu-contribfft-1.0-1.0.1+dfsg-1_amd64
libstarpu-contribmpi-1.0-1.0.1+dfsg-1_amd64
libsuitesparse-metis-3.1.0-3.1.0-2_amd64
libsuitesparse-metis-dbg-3.1.0-2_amd64
libsuitesparse-metis-dev-3.1.0-2_amd64
libtrain-bin-0.9b-11_amd64
libtrain-dev-0.9b-11_amd64
libtrain1-0.9b-11_amd64
libxnvctrl-dev-304.88-1_amd64
libxnvctrl0-304.88-1_amd64
libydpdict2-1.0.2-1_amd64
libydpdict2-dev-1.0.2-1_amd64
lugaru-0~20110520.1+hge4354+dfsg-3_amd64
microcode.ctl-1.18~0+nmu2_amd64
nvidia-installer-cleanup-20120630+3_amd64
nvidia-kernel-common-20120630+3_amd64
nvidia-settings-304.88-1_amd64
nvidia-settings-legacy-173xx-173.14.35-2_amd64
nvidia-support-20120630+3_amd64
nvidia-xconfig-304.48-1_amd64
pidgin-skype-20110407+svn628+dfsg-1_amd64
pidgin-skype-dbg-20110407+svn628+dfsg-1_amd64
prism2-usb-firmware-installer-0.2.9+dfsg-5_amd64
pvpgn-1.8.1-2.1+b1_amd64
python-ifeffit-2:1.2.11d-8_amd64
python-pycuda-2012.1-1_amd64
python-pyopencl-2012.1.dfsg-1_amd64
python3-pyopencl-2012.1.dfsg-1_amd64
r-cran-surveillance-1.2-1-3_amd64
redeclipse-1.2-3_amd64
redeclipse-dbg-1.2-3_amd64
redeclipse-server-1.2-3_amd64
redeclipse-server-dbg-1.2-3_amd64
reminiscence-0.2.1-1_amd64
rocksndiamonds-3.3.0.1+dfsg1-2.2_amd64
rott-1.1.2-1_amd64
ruby-pgplot-0.1.3-6_amd64
ruby-pgplot-dbg-0.1.3-6_amd64
sandboxgamemaker-2.7.1+dfsg-2_amd64
sauerbraten-0.0.20100728.dfsg+repack-3_amd64
sauerbraten-dbg-0.0.20100728.dfsg+repack-3_amd64
sauerbraten-server-0.0.20100728.dfsg+repack-3_amd64
spectemu-common-0.94a-15_amd64
spectemu-svga-0.94a-15_amd64
spectemu-x11-0.94a-15_amd64
starpu-contrib-examples-1.0.1+dfsg-1_amd64
starpu-contrib-tools-1.0.1+dfsg-1_amd64
uae-0.8.29-7_amd64
uae-dbg-0.8.29-7_amd64
uqm-0.6.2.dfsg-9_amd64
vice-2.3.dfsg-4_amd64
vmware-view-open-client-4.5.0-297975+dfsg-4+b1_amd64
vor-0.5.5-2_amd64
wdq2wav-0.8.3-2_amd64
wolf4sdl-1.7+svn262+dfsg1-1_amd64
xserver-xorg-video-ivtv-1.1.2-1+b3_amd64
xserver-xorg-video-ivtv-dbg-1.1.2-1+b3_amd64
xtrs-4.9c-3.4_amd64
xvba-va-driver-0.8.0-5_amd64
ydpdict-1.0.0-2_amd64
alien-arena-7.53+dfsg-3_i386
alien-arena-server-7.53+dfsg-3_i386
alsa-firmware-loaders-1.0.25-2_i386
amoeba-1.1-26_i386
assaultcube-1.1.0.4+dfsg2-1_i386
atari800-2.2.1-2_i386
b43-fwcutter-1:015-14.1_i386
basilisk2-0.9.20120331-2_i386
boinc-nvidia-cuda-7.0.27+dfsg-5_i386
cbedic-4.0-3_i386
chocolate-doom-1.7.0-3_i386
conky-all-1.9.0-2_i386
cpp-doc-5:4_i386
cytadela-1.0.1-2_i386
cytadela-dbg-1.0.1-2_i386
dosemu-1.4.0+svn.2080-1_i386
e-uae-0.8.29-WIP4-10_i386
e-uae-dbg-0.8.29-WIP4-10_i386
easyspice-0.6.8-2_i386
exult-1.2-15.2_i386
exult-studio-1.2-15.2_i386
flashplugin-nonfree-1:3.2_i386
flashplugin-nonfree-extrasound-0.0.svn2431-3_i386
frogatto-1.2+dfsg-1_i386
gcc-doc-5:4_i386
gcj-doc-5:4_i386
gfortran-doc-5:4_i386
glx-alternative-fglrx-0.2.2_i386
glx-alternative-mesa-0.2.2_i386
glx-alternative-nvidia-0.2.2_i386
glx-diversions-0.2.2_i386
gnat-doc-5:4_i386
gnome-speech-dectalk-1:0.4.25-5_i386
gnome-speech-ibmtts-1:0.4.25-5_i386
gnome-speech-swift-1:0.4.25-5_i386
gnome-video-arcade-0.8.3-1_i386
gnuboy-sdl-1.0.3-6.1_i386
gnuboy-svga-1.0.3-6.1_i386
gnuboy-x-1.0.3-6.1_i386
gnuvd-1.0.11-1_i386
gobi-loader-0.6-1_i386
gtktrain-0.9b-13_i386
hannah-foo2zjs-1:1_i386
ifeffit-2:1.2.11d-8_i386
isdnactivecards-1:3.9.20060704-11_i386
isight-firmware-tools-1.6-1_i386
iucode-tool-0.8.3-1_i386
ivtv-utils-1.4.1-2_i386
kcemu-0.5.1+dfsg-5_i386
libcplgasgano20-6.1.1-2_i386
libdbd-oracle-perl-1.44-1_i386
libifeffit-perl-2:1.2.11d-8_i386
libpgplot-perl-1:2.21-3_i386
libsocl-contrib-1.0-1.0.1+dfsg-1_i386
libstarpu-contrib-1.0-1.0.1+dfsg-1_i386
libstarpu-contrib-dev-1.0.1+dfsg-1_i386
libstarpu-contribfft-1.0-1.0.1+dfsg-1_i386
libstarpu-contribmpi-1.0-1.0.1+dfsg-1_i386
libsuitesparse-metis-3.1.0-3.1.0-2_i386
libsuitesparse-metis-dbg-3.1.0-2_i386
libsuitesparse-metis-dev-3.1.0-2_i386
libtrain-bin-0.9b-11_i386
libtrain-dev-0.9b-11_i386
libtrain1-0.9b-11_i386
libxnvctrl-dev-304.88-1_i386
libxnvctrl0-304.88-1_i386
libydpdict2-1.0.2-1_i386
libydpdict2-dev-1.0.2-1_i386
lugaru-0~20110520.1+hge4354+dfsg-3_i386
microcode.ctl-1.18~0+nmu2_i386
nvidia-installer-cleanup-20120630+3_i386
nvidia-kernel-common-20120630+3_i386
nvidia-settings-304.88-1_i386
nvidia-settings-legacy-173xx-173.14.35-2_i386
nvidia-support-20120630+3_i386
nvidia-xconfig-304.48-1_i386
pidgin-skype-20110407+svn628+dfsg-1_i386
pidgin-skype-dbg-20110407+svn628+dfsg-1_i386
prism2-usb-firmware-installer-0.2.9+dfsg-5_i386
pvpgn-1.8.1-2.1+b1_i386
python-ifeffit-2:1.2.11d-8_i386
python-pycuda-2012.1-1_i386
python-pyopencl-2012.1.dfsg-1_i386
python3-pyopencl-2012.1.dfsg-1_i386
q-tools-0.4-1_i386
r-cran-surveillance-1.2-1-3_i386
redeclipse-1.2-3_i386
redeclipse-dbg-1.2-3_i386
redeclipse-server-1.2-3_i386
redeclipse-server-dbg-1.2-3_i386
reminiscence-0.2.1-1_i386
rocksndiamonds-3.3.0.1+dfsg1-2.2_i386
rott-1.1.2-1_i386
sandboxgamemaker-2.7.1+dfsg-2_i386
sauerbraten-0.0.20100728.dfsg+repack-3_i386
sauerbraten-dbg-0.0.20100728.dfsg+repack-3_i386
sauerbraten-server-0.0.20100728.dfsg+repack-3_i386
spectemu-common-0.94a-15_i386
spectemu-svga-0.94a-15_i386
spectemu-x11-0.94a-15_i386
starpu-contrib-examples-1.0.1+dfsg-1_i386
starpu-contrib-tools-1.0.1+dfsg-1_i386
uae-0.8.29-7_i386
uae-dbg-0.8.29-7_i386
uqm-0.6.2.dfsg-9_i386
vice-2.3.dfsg-4_i386
vmware-view-open-client-4.5.0-297975+dfsg-4+b1_i386
vor-0.5.5-2_i386
wdq2wav-0.8.3-2_i386
wolf4sdl-1.7+svn262+dfsg1-1_i386
xserver-xorg-video-ivtv-1.1.2-1+b3_i386
xserver-xorg-video-ivtv-dbg-1.1.2-1+b3_i386
xtrs-4.9c-3.4_i386
xvba-va-driver-0.8.0-5_i386
ydpdict-1.0.0-2_i386
+6
View File
@@ -0,0 +1,6 @@
Downloading ${url}dists/hardy/Release...
Downloading & parsing package files...
Downloading ${url}dists/hardy/main/binary-amd64/Packages.bz2...
Downloading ${url}dists/hardy/main/binary-amd64/Packages.gz...
Downloading ${url}dists/hardy/main/binary-amd64/Packages...
ERROR: unable to update: ${url}dists/hardy/main/binary-amd64/Packages: sha256 hash mismatch "494414ded24da13c451b13b424928821351c78fce49f93d9e1b55f102790c206" != "8a21688ae769f2b4ffcaa366409f679d"
+7
View File
@@ -0,0 +1,7 @@
Downloading ${url}dists/hardy/Release...
Downloading & parsing package files...
Downloading ${url}dists/hardy/main/binary-amd64/Packages.bz2...
Downloading ${url}dists/hardy/main/binary-amd64/Packages.gz...
Downloading ${url}dists/hardy/main/binary-amd64/Packages...
WARNING: ${url}dists/hardy/main/binary-amd64/Packages: sha256 hash mismatch "494414ded24da13c451b13b424928821351c78fce49f93d9e1b55f102790c206" != "8a21688ae769f2b4ffcaa366409f679d"
ERROR: unable to update: malformed stanza syntax
+12
View File
@@ -0,0 +1,12 @@
Downloading ${url}dists/hardy/Release...
Downloading & parsing package files...
Downloading ${url}dists/hardy/main/binary-amd64/Packages.bz2...
Downloading ${url}dists/hardy/main/binary-amd64/Packages.gz...
Downloading ${url}dists/hardy/main/binary-amd64/Packages...
Saving packages to database...
Building download queue...
Download queue: 1 items, 0.00 GiB size
Downloading ${url}pool/main/a/amanda/amanda-client_3.3.1-3~bpo60+1_amd64.deb...
ERROR: unable to update: download errors:
${url}pool/main/a/amanda/amanda-client_3.3.1-3~bpo60+1_amd64.deb: sha1 hash mismatch "8d3a014000038725d6daf8771b42a0784253688f" != "66b27417d37e024c46526c2f6d358a754fc552f3"
+12
View File
@@ -0,0 +1,12 @@
Downloading ${url}dists/hardy/Release...
Downloading & parsing package files...
Downloading ${url}dists/hardy/main/binary-amd64/Packages.bz2...
Downloading ${url}dists/hardy/main/binary-amd64/Packages.gz...
Downloading ${url}dists/hardy/main/binary-amd64/Packages...
Saving packages to database...
Building download queue...
Download queue: 1 items, 0.00 GiB size
Downloading ${url}pool/main/a/amanda/amanda-client_3.3.1-3~bpo60+1_amd64.deb...
WARNING: ${url}pool/main/a/amanda/amanda-client_3.3.1-3~bpo60+1_amd64.deb: sha1 hash mismatch "8d3a014000038725d6daf8771b42a0784253688f" != "66b27417d37e024c46526c2f6d358a754fc552f3"
Mirror `failure` has been successfully updated.
+18
View File
@@ -0,0 +1,18 @@
Building download queue...
Download queue: 4 items, 0.00 GiB size
Downloading & parsing package files...
Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/InRelease...
Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Packages.bz2...
Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Packages.gz...
Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Release...
Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Release.gpg...
Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/amd64/libiniparser-dev_3.1-1_amd64.deb...
Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/amd64/libiniparser_3.1-1_amd64.deb...
Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/i386/libiniparser-dev_3.1-1_i386.deb...
Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/i386/libiniparser_3.1-1_i386.deb...
Mirror `flat` has been successfully updated.
Saving packages to database...
gpgv: Good signature from "home:DeepDiver1975 OBS Project <home:DeepDiver1975@build.opensuse.org>"
gpgv: Signature made Tue May 21 23:01:30 2013 MSK using DSA key ID 1048C1FF
+1
View File
@@ -6,3 +6,4 @@ from .create import *
from .show import *
from .list import *
from .update import *
from .drop import *
+95 -9
View File
@@ -1,3 +1,5 @@
import re
from lib import BaseTest
@@ -5,7 +7,7 @@ class CreateMirror1Test(BaseTest):
"""
create mirror: all architectures + all components
"""
runCmd = "aptly mirror create mirror1 http://mirror.yandex.ru/debian/ wheezy"
runCmd = "aptly mirror create --ignore-signatures mirror1 http://mirror.yandex.ru/debian/ wheezy"
def check(self):
self.check_output()
@@ -16,7 +18,7 @@ class CreateMirror2Test(BaseTest):
"""
create mirror: all architectures and 1 component
"""
runCmd = "aptly mirror create mirror2 http://mirror.yandex.ru/debian/ wheezy main"
runCmd = "aptly mirror create --ignore-signatures mirror2 http://mirror.yandex.ru/debian/ wheezy main"
def check(self):
self.check_output()
@@ -27,7 +29,7 @@ class CreateMirror3Test(BaseTest):
"""
create mirror: some architectures and 2 components
"""
runCmd = "aptly -architectures=i386,amd64 mirror create mirror3 http://mirror.yandex.ru/debian/ wheezy main contrib"
runCmd = "aptly -architectures=i386,amd64 mirror create --ignore-signatures mirror3 http://mirror.yandex.ru/debian/ wheezy main contrib"
def check(self):
self.check_output()
@@ -40,7 +42,7 @@ class CreateMirror4Test(BaseTest):
"""
expectedCode = 1
runCmd = "aptly -architectures=i386,amd64 mirror create mirror4 http://mirror.yandex.ru/debian/ wheezy life"
runCmd = "aptly -architectures=i386,amd64 mirror create --ignore-signatures mirror4 http://mirror.yandex.ru/debian/ wheezy life"
class CreateMirror5Test(BaseTest):
@@ -49,7 +51,7 @@ class CreateMirror5Test(BaseTest):
"""
expectedCode = 1
runCmd = "aptly -architectures=i386,nano68 mirror create mirror5 http://mirror.yandex.ru/debian/ wheezy"
runCmd = "aptly -architectures=i386,nano68 mirror create --ignore-signatures mirror5 http://mirror.yandex.ru/debian/ wheezy"
class CreateMirror6Test(BaseTest):
@@ -58,14 +60,14 @@ class CreateMirror6Test(BaseTest):
"""
expectedCode = 1
runCmd = "aptly mirror create mirror6 http://mirror.yandex.ru/debian/ suslik"
runCmd = "aptly mirror create --keyring=aptlytest.gpg mirror6 http://mirror.yandex.ru/debian/ suslik"
class CreateMirror7Test(BaseTest):
"""
create mirror: architectures fixed via config file
"""
runCmd = "aptly mirror create mirror7 http://mirror.yandex.ru/debian/ wheezy main contrib"
runCmd = "aptly mirror create --ignore-signatures mirror7 http://mirror.yandex.ru/debian/ wheezy main contrib"
configOverride = {"architectures": ["i386", "amd64"]}
def check(self):
@@ -78,7 +80,91 @@ class CreateMirror8Test(BaseTest):
create mirror: already exists
"""
fixtureCmds = [
"aptly mirror create mirror8 http://mirror.yandex.ru/debian/ wheezy main contrib"
"aptly mirror create --ignore-signatures mirror8 http://mirror.yandex.ru/debian/ wheezy main contrib"
]
runCmd = "aptly mirror create mirror8 http://mirror.yandex.ru/debian/ wheezy main contrib"
runCmd = "aptly mirror create --ignore-signatures mirror8 http://mirror.yandex.ru/debian/ wheezy main contrib"
expectedCode = 1
class CreateMirror9Test(BaseTest):
"""
create mirror: repo with InRelease verification
"""
runCmd = "aptly mirror create --keyring=aptlytest.gpg mirror9 http://mirror.yandex.ru/debian-backports/ squeeze-backports"
fixtureGpg = True
outputMatchPrepare = lambda _, s: re.sub(r'Signature made .* using|Warning: using insecure memory!\n', '', s)
def check(self):
def removeDates(s):
return re.sub(r"(Date|Valid-Until): [,0-9:+A-Za-z -]+\n", "", s)
self.check_output()
self.check_cmd_output("aptly mirror show mirror9", "mirror_show", match_prepare=removeDates)
class CreateMirror10Test(BaseTest):
"""
create mirror: repo with InRelease verification, failure
"""
runCmd = "aptly mirror create --keyring=aptlytest.gpg mirror10 http://mirror.yandex.ru/debian-backports/ squeeze-backports"
fixtureGpg = False
gold_processor = BaseTest.expand_environ
outputMatchPrepare = lambda _, s: re.sub(r'Signature made .* using|gpgv: keyblock resource .*$|gpgv: Can\'t check signature: .*$', '', s, flags=re.MULTILINE)
expectedCode = 1
class CreateMirror11Test(BaseTest):
"""
create mirror: repo with Release + Release.gpg verification
"""
runCmd = "aptly mirror create --keyring=aptlytest.gpg mirror11 http://mirror.yandex.ru/debian/ squeeze"
fixtureGpg = True
outputMatchPrepare = lambda _, s: re.sub(r'Signature made .* using', '', s)
def check(self):
self.check_output()
self.check_cmd_output("aptly mirror show mirror11", "mirror_show")
class CreateMirror12Test(BaseTest):
"""
create mirror: repo with Release+Release.gpg verification, failure
"""
runCmd = "aptly mirror create --keyring=aptlytest.gpg mirror12 http://mirror.yandex.ru/debian/ squeeze"
fixtureGpg = False
gold_processor = BaseTest.expand_environ
outputMatchPrepare = lambda _, s: re.sub(r'Signature made .* using|gpgv: keyblock resource .*$|gpgv: Can\'t check signature: .*$', '', s, flags=re.MULTILINE)
expectedCode = 1
class CreateMirror13Test(BaseTest):
"""
create mirror: skip verification using config file
"""
runCmd = "aptly mirror create mirror13 http://mirror.yandex.ru/debian/ wheezy"
configOverride = {"gpgDisableVerify": True}
def check(self):
self.check_output()
self.check_cmd_output("aptly mirror show mirror13", "mirror_show")
class CreateMirror14Test(BaseTest):
"""
create mirror: flat repository
"""
runCmd = "aptly mirror create --keyring=aptlytest.gpg mirror14 http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/ ./"
fixtureGpg = True
outputMatchPrepare = lambda _, s: re.sub(r'Signature made .* using', '', s)
def check(self):
self.check_output()
self.check_cmd_output("aptly mirror show mirror14", "mirror_show")
class CreateMirror15Test(BaseTest):
"""
create mirror: flat repository + components
"""
runCmd = "aptly mirror create --keyring=aptlytest.gpg mirror14 http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/ ./ main"
expectedCode = 1
+46
View File
@@ -0,0 +1,46 @@
from lib import BaseTest
class DropMirror1Test(BaseTest):
"""
drop mirror: regular list
"""
fixtureCmds = [
"aptly mirror create --ignore-signatures mirror1 http://mirror.yandex.ru/debian/ wheezy",
]
runCmd = "aptly mirror drop mirror1"
def check(self):
self.check_output()
self.check_cmd_output("aptly mirror show mirror1", "mirror_show", expected_code=1)
class DropMirror2Test(BaseTest):
"""
drop mirror: in use by snapshots
"""
fixtureDB = True
fixtureCmds = [
"aptly snapshot create wheez from mirror wheezy-main"
]
runCmd = "aptly mirror drop wheezy-main"
expectedCode = 1
class DropMirror3Test(BaseTest):
"""
drop mirror: force
"""
fixtureDB = True
fixtureCmds = [
"aptly snapshot create wheez from mirror wheezy-main"
]
runCmd = "aptly mirror drop --force wheezy-main"
class DropMirror4Test(BaseTest):
"""
drop mirror: no such mirror
"""
runCmd = "aptly mirror drop mirror1"
expectedCode = 1
+3 -3
View File
@@ -6,9 +6,9 @@ class ListMirror1Test(BaseTest):
list mirrors: regular list
"""
fixtureCmds = [
"aptly mirror create mirror1 http://mirror.yandex.ru/debian/ wheezy",
"aptly mirror create mirror2 http://mirror.yandex.ru/debian/ squeeze contrib",
"aptly -architectures=i386 mirror create mirror3 http://mirror.yandex.ru/debian/ squeeze non-free",
"aptly mirror create --ignore-signatures mirror1 http://mirror.yandex.ru/debian/ wheezy",
"aptly mirror create --ignore-signatures mirror2 http://mirror.yandex.ru/debian/ squeeze contrib",
"aptly -architectures=i386 mirror create --ignore-signatures mirror3 http://mirror.yandex.ru/debian/ squeeze non-free",
]
runCmd = "aptly mirror list"
+11 -1
View File
@@ -1,11 +1,12 @@
from lib import BaseTest
import re
class ShowMirror1Test(BaseTest):
"""
show mirror: regular mirror
"""
fixtureCmds = ["aptly mirror create mirror1 http://mirror.yandex.ru/debian/ wheezy"]
fixtureCmds = ["aptly mirror create --ignore-signatures mirror1 http://mirror.yandex.ru/debian/ wheezy"]
runCmd = "aptly mirror show mirror1"
@@ -15,3 +16,12 @@ class ShowMirror2Test(BaseTest):
"""
runCmd = "aptly mirror show mirror-xx"
expectedCode = 1
class ShowMirror3Test(BaseTest):
"""
show mirror: regular mirror with packages
"""
fixtureDB = True
runCmd = "aptly mirror show --with-packages wheezy-contrib"
outputMatchPrepare = lambda _, s: re.sub(r"Last update: [0-9:+A-Za-z -]+\n", "", s)
@@ -0,0 +1,15 @@
Origin: test
Label: failure
Suite: test
Version: 6.0.8
Codename: hardy
Date: Sat, 19 Oct 2013 13:54:21 UTC
Architectures: amd64
Components: main
Description: Debian 6.0.8 Released 19 October 2013
MD5Sum:
2e3817293fc275dbee74bd71ce6eb056 4 main/binary-amd64/Packages
SHA1:
4d13fcc6eda389d4d679602171e11593eadae9b9 4 main/binary-amd64/Packages
SHA256:
8a21688ae769f2b4ffcaa366409f679d 4 main/binary-amd64/Packages
@@ -0,0 +1,11 @@
Origin: test
Label: failure
Suite: test
Version: 6.0.8
Codename: hardy
Date: Sat, 19 Oct 2013 13:54:21 UTC
Architectures: amd64
Components: main
Description: Debian 6.0.8 Released 19 October 2013
MD5Sum:
846549680001f5c632b6ee8e0f183825 827 main/binary-amd64/Packages
@@ -0,0 +1,19 @@
Package: amanda-client
Source: amanda
Version: 1:3.3.1-3~bpo60+1
Installed-Size: 880
Maintainer: Bdale Garbee <bdale@gag.com>
Architecture: amd64
Replaces: amanda-common (<< 1:2.5.2p1-3)
Depends: libc6 (>= 2.3), libcurl3 (>= 7.16.2-1), libglib2.0-0 (>= 2.12.0), libreadline6 (>= 6.0), libssl0.9.8 (>= 0.9.8m-1), amanda-common (= 1:3.3.1-3~bpo60+1)
Suggests: gnuplot, dump, smbclient
Conflicts: amanda, amanda-common (<< 1:2.5.2p1-3)
Description: Advanced Maryland Automatic Network Disk Archiver (Client)
Description-md5: 21af3684379a64cacc51c39152ab1062
Section: utils
Priority: optional
Filename: pool/main/a/amanda/amanda-client_3.3.1-3~bpo60+1_amd64.deb
Size: 30
MD5sum: 4f7223ebadee9fb57b6796570d60638f
SHA1: 66b27417d37e024c46526c2f6d358a754fc552f3
SHA256: 3608bca1e44ea6c4d268eb6db02260269892c0b42b86bbf1e77a6fa16c3c9282
@@ -0,0 +1 @@
012345678901234567890123456789
+78 -2
View File
@@ -1,3 +1,5 @@
import string
import re
from lib import BaseTest
@@ -7,9 +9,9 @@ class UpdateMirror1Test(BaseTest):
"""
longTest = True
fixtureCmds = [
"aptly -architectures=i386,amd64 mirror create alsa-ppa http://ppa.launchpad.net/alsa-backports/ubuntu/ hardy main",
"aptly -architectures=i386,amd64 mirror create --ignore-signatures alsa-ppa http://ppa.launchpad.net/alsa-backports/ubuntu/ hardy main",
]
runCmd = "aptly mirror update alsa-ppa"
runCmd = "aptly mirror update --ignore-signatures alsa-ppa"
def output_processor(self, output):
return "\n".join(sorted(output.split("\n")))
@@ -21,3 +23,77 @@ class UpdateMirror2Test(BaseTest):
"""
runCmd = "aptly mirror update mirror-xyz"
expectedCode = 1
class UpdateMirror3Test(BaseTest):
"""
update mirrors: wrong checksum in release file
"""
fixtureCmds = [
"aptly mirror create --ignore-signatures failure ${url} hardy main",
]
fixtureWebServer = "test_release"
runCmd = "aptly mirror update --ignore-signatures failure"
expectedCode = 1
def gold_processor(self, gold):
return string.Template(gold).substitute({'url': self.webServerUrl})
class UpdateMirror4Test(BaseTest):
"""
update mirrors: wrong checksum in release file, but ignore
"""
fixtureCmds = [
"aptly mirror create --ignore-signatures failure ${url} hardy main",
]
fixtureWebServer = "test_release"
runCmd = "aptly mirror update -ignore-checksums --ignore-signatures failure"
expectedCode = 1
def gold_processor(self, gold):
return string.Template(gold).substitute({'url': self.webServerUrl})
class UpdateMirror5Test(BaseTest):
"""
update mirrors: wrong checksum in package
"""
fixtureCmds = [
"aptly mirror create --ignore-signatures failure ${url} hardy main",
]
fixtureWebServer = "test_release2"
runCmd = "aptly mirror update --ignore-signatures failure"
expectedCode = 1
def gold_processor(self, gold):
return string.Template(gold).substitute({'url': self.webServerUrl})
class UpdateMirror6Test(BaseTest):
"""
update mirrors: wrong checksum in package, but ignore
"""
fixtureCmds = [
"aptly mirror create --ignore-signatures failure ${url} hardy main",
]
fixtureWebServer = "test_release2"
runCmd = "aptly mirror update -ignore-checksums --ignore-signatures failure"
def gold_processor(self, gold):
return string.Template(gold).substitute({'url': self.webServerUrl})
class UpdateMirror7Test(BaseTest):
"""
update mirrors: flat repository
"""
fixtureGpg = True
fixtureCmds = [
"aptly mirror create --keyring=aptlytest.gpg flat http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/ ./",
]
runCmd = "aptly mirror update --keyring=aptlytest.gpg flat"
outputMatchPrepare = lambda _, s: re.sub(r'Signature made .* using', '', s)
def output_processor(self, output):
return "\n".join(sorted(output.split("\n")))
@@ -0,0 +1,3 @@
Snapshot snap4 successfully created.
You can run 'aptly publish snapshot snap4' to publish snapshot as Debian repository.
@@ -0,0 +1,4 @@
Name: snap4
Description: Created as empty
Number of packages: 0
Packages:
@@ -0,0 +1 @@
ERROR: unable to add snapshot: snapshot with name snap5 already exists
@@ -0,0 +1 @@
Snapshot `snap1` has been dropped.
@@ -0,0 +1 @@
ERROR: unable to show: snapshot with name snap1 not found
@@ -0,0 +1,3 @@
Snapshot `snap1` was used as a source in following snapshots:
* [snap2]: Merged from sources: 'snap1'
ERROR: won't delete snapshot that was used as source for other snapshots, use -force to override
@@ -0,0 +1 @@
Snapshot `snap1` has been dropped.
@@ -0,0 +1 @@
ERROR: unable to show: snapshot with name snap1 not found
@@ -0,0 +1,3 @@
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
ERROR: unable to drop: snapshot is published
@@ -0,0 +1,3 @@
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
ERROR: unable to drop: snapshot is published
@@ -0,0 +1 @@
ERROR: unable to drop: snapshot with name no-such-snapshot not found
@@ -0,0 +1 @@
Snapshot `snap1` has been dropped.
@@ -0,0 +1,4 @@
Name: snap1
Created At: 2014-01-24 13:06:43 MSK
Description: Snapshot from mirror [wheezy-non-free]: http://mirror.yandex.ru/debian/ wheezy
Number of packages: 661
+1
View File
@@ -9,3 +9,4 @@ from .verify import *
from .pull import *
from .diff import *
from .merge import *
from .drop import *
+24 -1
View File
@@ -14,7 +14,7 @@ class CreateSnapshot1Test(BaseTest):
return re.sub(r"Created At: [0-9:A-Za-z -]+\n", "", s)
self.check_output()
self.check_cmd_output("aptly snapshot show snap1", "snapshot_show", match_prepare=remove_created_at)
self.check_cmd_output("aptly snapshot show -with-packages snap1", "snapshot_show", match_prepare=remove_created_at)
class CreateSnapshot2Test(BaseTest):
@@ -34,3 +34,26 @@ class CreateSnapshot3Test(BaseTest):
fixtureCmds = ["aptly snapshot create snap1 from mirror wheezy-main"]
runCmd = "aptly snapshot create snap1 from mirror wheezy-contrib"
expectedCode = 1
class CreateSnapshot4Test(BaseTest):
"""
create snapshot: empty
"""
runCmd = "aptly snapshot create snap4 empty"
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 CreateSnapshot5Test(BaseTest):
"""
create snapshot: empty duplicate name
"""
fixtureCmds = ["aptly snapshot create snap5 empty"]
runCmd = "aptly snapshot create snap5 empty"
expectedCode = 1
+94
View File
@@ -0,0 +1,94 @@
from lib import BaseTest
class DropSnapshot1Test(BaseTest):
"""
drop snapshot: just drop
"""
fixtureDB = True
fixtureCmds = ["aptly snapshot create snap1 from mirror wheezy-non-free"]
runCmd = "aptly snapshot drop snap1"
def check(self):
self.check_output()
self.check_cmd_output("aptly snapshot show snap1", "snapshot_show", expected_code=1)
class DropSnapshot2Test(BaseTest):
"""
drop snapshot: used as source
"""
fixtureDB = True
fixtureCmds = [
"aptly snapshot create snap1 from mirror wheezy-non-free",
"aptly snapshot merge snap2 snap1",
]
runCmd = "aptly snapshot drop snap1"
expectedCode = 1
class DropSnapshot3Test(BaseTest):
"""
drop snapshot: -force
"""
fixtureDB = True
fixtureCmds = [
"aptly snapshot create snap1 from mirror wheezy-non-free",
"aptly snapshot merge snap2 snap1",
]
runCmd = "aptly snapshot drop -force snap1"
def check(self):
self.check_output()
self.check_cmd_output("aptly snapshot show snap1", "snapshot_show", expected_code=1)
class DropSnapshot4Test(BaseTest):
"""
drop snapshot: already published
"""
fixtureDB = True
fixturePool = True
fixtureCmds = [
"aptly snapshot create snap1 from mirror gnuplot-maverick",
"aptly publish snapshot snap1"
]
runCmd = "aptly snapshot drop snap1"
expectedCode = 1
class DropSnapshot5Test(BaseTest):
"""
drop snapshot: already published with -force
"""
fixtureDB = True
fixturePool = True
fixtureCmds = [
"aptly snapshot create snap1 from mirror gnuplot-maverick",
"aptly publish snapshot snap1"
]
runCmd = "aptly snapshot drop --force snap1"
expectedCode = 1
class DropSnapshot6Test(BaseTest):
"""
drop snapshot: no such snapshot
"""
fixtureDB = True
runCmd = "aptly snapshot drop no-such-snapshot"
expectedCode = 1
class DropSnapshot7Test(BaseTest):
"""
drop snapshot: publish, drop publish, drop snapshot
"""
fixtureDB = True
fixturePool = True
fixtureCmds = [
"aptly snapshot create snap1 from mirror gnuplot-maverick",
"aptly publish snapshot snap1",
"aptly publish drop maverick",
]
runCmd = "aptly snapshot drop snap1"
+2 -2
View File
@@ -18,7 +18,7 @@ class MergeSnapshot1Test(BaseTest):
return re.sub(r"Created At: [0-9:A-Za-z -]+\n", "", s)
self.check_output()
self.check_cmd_output("aptly snapshot show snap3", "snapshot_show", match_prepare=remove_created_at)
self.check_cmd_output("aptly snapshot show -with-packages snap3", "snapshot_show", match_prepare=remove_created_at)
class MergeSnapshot2Test(BaseTest):
@@ -53,7 +53,7 @@ class MergeSnapshot3Test(BaseTest):
return re.sub(r"Created At: [0-9:A-Za-z -]+\n", "", s)
self.check_output()
self.check_cmd_output("aptly snapshot show snap4", "snapshot_show", match_prepare=remove_created_at)
self.check_cmd_output("aptly snapshot show -with-packages snap4", "snapshot_show", match_prepare=remove_created_at)
class MergeSnapshot4Test(BaseTest):
+4 -6
View File
@@ -19,7 +19,7 @@ class PullSnapshot1Test(BaseTest):
return re.sub(r"Created At: [0-9:A-Za-z -]+\n", "", s)
self.check_output()
self.check_cmd_output("aptly snapshot show snap3", "snapshot_show", match_prepare=remove_created_at)
self.check_cmd_output("aptly snapshot show -with-packages snap3", "snapshot_show", match_prepare=remove_created_at)
class PullSnapshot2Test(BaseTest):
@@ -39,7 +39,7 @@ class PullSnapshot2Test(BaseTest):
return re.sub(r"Created At: [0-9:A-Za-z -]+\n", "", s)
self.check_output()
self.check_cmd_output("aptly snapshot show snap3", "snapshot_show", match_prepare=remove_created_at)
self.check_cmd_output("aptly snapshot show -with-packages snap3", "snapshot_show", match_prepare=remove_created_at)
class PullSnapshot3Test(BaseTest):
@@ -59,7 +59,7 @@ class PullSnapshot3Test(BaseTest):
return re.sub(r"Created At: [0-9:A-Za-z -]+\n", "", s)
self.check_output()
self.check_cmd_output("aptly snapshot show snap3", "snapshot_show", match_prepare=remove_created_at)
self.check_cmd_output("aptly snapshot show -with-packages snap3", "snapshot_show", match_prepare=remove_created_at)
class PullSnapshot4Test(BaseTest):
@@ -136,6 +136,4 @@ class PullSnapshot8Test(BaseTest):
return re.sub(r"Created At: [0-9:A-Za-z -]+\n", "", s)
self.check_output()
self.check_cmd_output("aptly snapshot show snap3", "snapshot_show", match_prepare=remove_created_at)
self.check_cmd_output("aptly snapshot show --with-packages snap3", "snapshot_show", match_prepare=remove_created_at)
+11 -1
View File
@@ -8,7 +8,7 @@ class ShowSnapshot1Test(BaseTest):
"""
fixtureDB = True
fixtureCmds = ["aptly snapshot create snap1 from mirror wheezy-non-free"]
runCmd = "aptly snapshot show snap1"
runCmd = "aptly snapshot show --with-packages snap1"
outputMatchPrepare = lambda _, s: re.sub(r"Created At: [0-9:A-Za-z -]+\n", "", s)
@@ -19,3 +19,13 @@ class ShowSnapshot2Test(BaseTest):
fixtureDB = True
runCmd = "aptly snapshot show no-such-snapshot"
expectedCode = 1
class ShowSnapshot3Test(BaseTest):
"""
show snapshot: from mirror w/o packages
"""
fixtureDB = True
fixtureCmds = ["aptly snapshot create snap1 from mirror wheezy-non-free"]
runCmd = "aptly snapshot show snap1"
outputMatchPrepare = lambda _, s: re.sub(r"Created At: [0-9:A-Za-z -]+\n", "", s)
+4
View File
@@ -0,0 +1,4 @@
Removing ${HOME}/.aptly/public/dists...
Removing ${HOME}/.aptly/public/pool...
Published repositroy has been removed successfully.
+4
View File
@@ -0,0 +1,4 @@
Removing ${HOME}/.aptly/public/ppa/smira/dists...
Removing ${HOME}/.aptly/public/ppa/smira/pool...
Published repositroy has been removed successfully.
+3
View File
@@ -0,0 +1,3 @@
Removing ${HOME}/.aptly/public/dists/sq1...
Published repositroy has been removed successfully.
+4
View File
@@ -0,0 +1,4 @@
Removing ${HOME}/.aptly/public/dists/sq1...
Removing ${HOME}/.aptly/public/pool/contrib...
Published repositroy has been removed successfully.

Some files were not shown because too many files have changed in this diff Show More