Rework the way database is open/re-open in aptly

Allow database to be initialized without opening, unify all the
open paths to retry on failure.

In API router make sure open requests are matched with acks in explicit
way.

This also enables re-open attempts in all the aptly commands, so it
should make running aptly CLI much easier now hopefully.

Fix up system tests for oldoldstable ;)
This commit is contained in:
Andrey Smirnov
2017-07-05 00:17:48 +03:00
parent af2f7baf63
commit 211ac0501f
36 changed files with 138 additions and 106 deletions

View File

@@ -23,11 +23,18 @@ func apiVersion(c *gin.Context) {
c.JSON(200, gin.H{"Version": aptly.Version}) c.JSON(200, gin.H{"Version": aptly.Version})
} }
type dbRequestKind int
const ( const (
acquiredb = iota acquiredb dbRequestKind = iota
releasedb releasedb
) )
type dbRequest struct {
kind dbRequestKind
err chan<- error
}
// Flushes all collections which cache in-memory objects // Flushes all collections which cache in-memory objects
func flushColections() { func flushColections() {
// lock everything to eliminate in-progress calls // lock everything to eliminate in-progress calls
@@ -52,50 +59,48 @@ func flushColections() {
} }
// Periodically flushes CollectionFactory to free up memory used by // Periodically flushes CollectionFactory to free up memory used by
// collections, flushing caches. If the two channels are provided, // collections, flushing caches.
// they are used to acquire and release the database.
// //
// Should be run in goroutine! // Should be run in goroutine!
func cacheFlusher(requests chan int, acks chan error) { func cacheFlusher() {
ticker := time.Tick(15 * time.Minute) ticker := time.Tick(15 * time.Minute)
for { for {
<-ticker <-ticker
// if aptly API runs in -no-lock mode, flushColections()
// caches are flushed when DB is closed anyway, no need
// to flush them here
if requests == nil {
flushColections()
}
} }
} }
// Acquire database lock and release it when not needed anymore. Two // Acquire database lock and release it when not needed anymore.
// channels must be provided. The first one is to receive requests to
// acquire/release the database and the second one is to send acks.
// //
// Should be run in a goroutine! // Should be run in a goroutine!
func acquireDatabase(requests chan int, acks chan error) { func acquireDatabase(requests <-chan dbRequest) {
clients := 0 clients := 0
for { for request := range requests {
request := <-requests var err error
switch request {
switch request.kind {
case acquiredb: case acquiredb:
if clients == 0 { if clients == 0 {
acks <- context.ReOpenDatabase() err = context.ReOpenDatabase()
} else { }
acks <- nil
request.err <- err
if err == nil {
clients++
} }
clients++
case releasedb: case releasedb:
clients-- clients--
if clients == 0 { if clients == 0 {
flushColections() flushColections()
acks <- context.CloseDatabase() err = context.CloseDatabase()
} else { } else {
acks <- nil err = nil
} }
request.err <- err
} }
} }
} }

View File

@@ -20,35 +20,35 @@ func Router(c *ctx.AptlyContext) http.Handler {
// We use a goroutine to count the number of // We use a goroutine to count the number of
// concurrent requests. When no more requests are // concurrent requests. When no more requests are
// running, we close the database to free the lock. // running, we close the database to free the lock.
requests := make(chan int) requests := make(chan dbRequest)
acks := make(chan error)
go acquireDatabase(requests, acks) go acquireDatabase(requests)
go cacheFlusher(requests, acks)
router.Use(func(c *gin.Context) { router.Use(func(c *gin.Context) {
var err error var err error
requests <- acquiredb errCh := make(chan error)
requests <- dbRequest{acquiredb, errCh}
err = <-errCh
if err != nil {
c.Fail(500, err)
return
}
defer func() { defer func() {
requests <- releasedb requests <- dbRequest{releasedb, errCh}
err = <-acks err = <-errCh
if err != nil { if err != nil {
c.Fail(500, err) c.Fail(500, err)
} }
}() }()
err = <-acks
if err != nil {
c.Fail(500, err)
return
}
c.Next() c.Next()
}) })
} else { } else {
go cacheFlusher(nil, nil) go cacheFlusher()
} }
root := router.Group("/api") root := router.Group("/api")

View File

@@ -111,6 +111,7 @@ package environment to new version.`,
}, },
} }
cmd.Flag.Int("db-open-attempts", 10, "number of attempts to open DB if it's locked by other instance")
cmd.Flag.Bool("dep-follow-suggests", false, "when processing dependencies, follow Suggests") cmd.Flag.Bool("dep-follow-suggests", false, "when processing dependencies, follow Suggests")
cmd.Flag.Bool("dep-follow-source", false, "when processing dependencies, follow from binary to Source packages") cmd.Flag.Bool("dep-follow-source", false, "when processing dependencies, follow from binary to Source packages")
cmd.Flag.Bool("dep-follow-recommends", false, "when processing dependencies, follow Recommends") cmd.Flag.Bool("dep-follow-recommends", false, "when processing dependencies, follow Recommends")

View File

@@ -3,6 +3,7 @@ package context
import ( import (
"fmt" "fmt"
"math/rand"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
@@ -238,13 +239,34 @@ func (context *AptlyContext) _database() (database.Storage, error) {
if context.database == nil { if context.database == nil {
var err error var err error
context.database, err = database.OpenDB(context.dbPath()) context.database, err = database.NewDB(context.dbPath())
if err != nil { if err != nil {
return nil, fmt.Errorf("can't open database: %s", err) return nil, fmt.Errorf("can't instanciate database: %s", err)
} }
} }
return context.database, nil tries := context.flags.Lookup("db-open-attempts").Value.Get().(int)
const BaseDelay = 10 * time.Second
const Jitter = 1 * time.Second
for ; tries >= 0; tries-- {
err := context.database.Open()
if err == nil || !strings.Contains(err.Error(), "resource temporarily unavailable") {
return context.database, err
}
if tries > 0 {
delay := time.Duration(rand.NormFloat64()*float64(Jitter) + float64(BaseDelay))
if delay < 0 {
delay = time.Second
}
context._progress().Printf("Unable to open database, sleeping %s, attempts left %d...\n", delay, tries)
time.Sleep(delay)
}
}
return nil, fmt.Errorf("unable to reopen the DB, maximum number of retries reached")
} }
// CloseDatabase closes the db temporarily // CloseDatabase closes the db temporarily
@@ -261,26 +283,9 @@ func (context *AptlyContext) CloseDatabase() error {
// ReOpenDatabase reopens the db after close // ReOpenDatabase reopens the db after close
func (context *AptlyContext) ReOpenDatabase() error { func (context *AptlyContext) ReOpenDatabase() error {
context.Lock() _, err := context.Database()
defer context.Unlock()
if context.database == nil { return err
return nil
}
const MaxTries = 10
const Delay = 10 * time.Second
for try := 0; try < MaxTries; try++ {
err := context.database.ReOpen()
if err == nil || !strings.Contains(err.Error(), "resource temporarily unavailable") {
return err
}
context._progress().Printf("Unable to reopen database, sleeping %s\n", Delay)
<-time.After(Delay)
}
return fmt.Errorf("unable to reopen the DB, maximum number of retries reached")
} }
// CollectionFactory builds factory producing all kinds of collections // CollectionFactory builds factory producing all kinds of collections

View File

@@ -32,8 +32,8 @@ type Storage interface {
ProcessByPrefix(prefix []byte, proc StorageProcessor) error ProcessByPrefix(prefix []byte, proc StorageProcessor) error
KeysByPrefix(prefix []byte) [][]byte KeysByPrefix(prefix []byte) [][]byte
FetchByPrefix(prefix []byte) [][]byte FetchByPrefix(prefix []byte) [][]byte
Open() error
Close() error Close() error
ReOpen() error
StartBatch() StartBatch()
FinishBatch() error FinishBatch() error
CompactDB() error CompactDB() error
@@ -66,13 +66,19 @@ func internalOpen(path string, throttleCompaction bool) (*leveldb.DB, error) {
return leveldb.OpenFile(path, o) return leveldb.OpenFile(path, o)
} }
// OpenDB opens (creates) LevelDB database // NewDB creates new instance of DB, but doesn't open it (yet)
func OpenDB(path string) (Storage, error) { func NewDB(path string) (Storage, error) {
db, err := internalOpen(path, false) return &levelDB{path: path}, nil
}
// NewOpenDB creates new instance of DB and opens it
func NewOpenDB(path string) (Storage, error) {
db, err := NewDB(path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &levelDB{db: db, path: path}, nil
return db, db.Open()
} }
// RecoverDB recovers LevelDB database from corruption // RecoverDB recovers LevelDB database from corruption
@@ -215,8 +221,8 @@ func (l *levelDB) Close() error {
return err return err
} }
// Reopen tries to re-open the database // Reopen tries to open (re-open) the database
func (l *levelDB) ReOpen() error { func (l *levelDB) Open() error {
if l.db != nil { if l.db != nil {
return nil return nil
} }

View File

@@ -22,7 +22,7 @@ func (s *LevelDBSuite) SetUpTest(c *C) {
var err error var err error
s.path = c.MkDir() s.path = c.MkDir()
s.db, err = OpenDB(s.path) s.db, err = NewOpenDB(s.path)
c.Assert(err, IsNil) c.Assert(err, IsNil)
} }
@@ -46,7 +46,7 @@ func (s *LevelDBSuite) TestRecoverDB(c *C) {
err = RecoverDB(s.path) err = RecoverDB(s.path)
c.Check(err, IsNil) c.Check(err, IsNil)
s.db, err = OpenDB(s.path) s.db, err = NewOpenDB(s.path)
c.Check(err, IsNil) c.Check(err, IsNil)
result, err := s.db.Get(key) result, err := s.db.Get(key)
@@ -223,7 +223,7 @@ func (s *LevelDBSuite) TestReOpen(c *C) {
err = s.db.Close() err = s.db.Close()
c.Assert(err, IsNil) c.Assert(err, IsNil)
err = s.db.ReOpen() err = s.db.Open()
c.Assert(err, IsNil) c.Assert(err, IsNil)
result, err := s.db.Get(key) result, err := s.db.Get(key)

View File

@@ -22,7 +22,7 @@ func (s *ChecksumCollectionSuite) SetUpTest(c *C) {
SHA1: "da39a3ee5e6b4b0d3255bfef95601890afd80709", SHA1: "da39a3ee5e6b4b0d3255bfef95601890afd80709",
SHA256: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", SHA256: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
} }
s.db, _ = database.OpenDB(c.MkDir()) s.db, _ = database.NewOpenDB(c.MkDir())
s.collection = NewChecksumCollection(s.db) s.collection = NewChecksumCollection(s.db)
} }

View File

@@ -18,7 +18,7 @@ type LocalRepoSuite struct {
var _ = Suite(&LocalRepoSuite{}) var _ = Suite(&LocalRepoSuite{})
func (s *LocalRepoSuite) SetUpTest(c *C) { func (s *LocalRepoSuite) SetUpTest(c *C) {
s.db, _ = database.OpenDB(c.MkDir()) s.db, _ = database.NewOpenDB(c.MkDir())
s.list = NewPackageList() s.list = NewPackageList()
s.list.Add(&Package{Name: "lib", Version: "1.7", Architecture: "i386"}) s.list.Add(&Package{Name: "lib", Version: "1.7", Architecture: "i386"})
s.list.Add(&Package{Name: "app", Version: "1.9", Architecture: "amd64"}) s.list.Add(&Package{Name: "app", Version: "1.9", Architecture: "amd64"})
@@ -83,7 +83,7 @@ type LocalRepoCollectionSuite struct {
var _ = Suite(&LocalRepoCollectionSuite{}) var _ = Suite(&LocalRepoCollectionSuite{})
func (s *LocalRepoCollectionSuite) SetUpTest(c *C) { func (s *LocalRepoCollectionSuite) SetUpTest(c *C) {
s.db, _ = database.OpenDB(c.MkDir()) s.db, _ = database.NewOpenDB(c.MkDir())
s.collection = NewLocalRepoCollection(s.db) s.collection = NewLocalRepoCollection(s.db)
s.list = NewPackageList() s.list = NewPackageList()

View File

@@ -17,7 +17,7 @@ var _ = Suite(&PackageCollectionSuite{})
func (s *PackageCollectionSuite) SetUpTest(c *C) { func (s *PackageCollectionSuite) SetUpTest(c *C) {
s.p = NewPackageFromControlFile(packageStanza.Copy()) s.p = NewPackageFromControlFile(packageStanza.Copy())
s.db, _ = database.OpenDB(c.MkDir()) s.db, _ = database.NewOpenDB(c.MkDir())
s.collection = NewPackageCollection(s.db) s.collection = NewPackageCollection(s.db)
} }

View File

@@ -87,7 +87,7 @@ var _ = Suite(&PublishedRepoSuite{})
func (s *PublishedRepoSuite) SetUpTest(c *C) { func (s *PublishedRepoSuite) SetUpTest(c *C) {
s.SetUpPackages() s.SetUpPackages()
s.db, _ = database.OpenDB(c.MkDir()) s.db, _ = database.NewOpenDB(c.MkDir())
s.factory = NewCollectionFactory(s.db) s.factory = NewCollectionFactory(s.db)
s.root = c.MkDir() s.root = c.MkDir()
@@ -449,7 +449,7 @@ type PublishedRepoCollectionSuite struct {
var _ = Suite(&PublishedRepoCollectionSuite{}) var _ = Suite(&PublishedRepoCollectionSuite{})
func (s *PublishedRepoCollectionSuite) SetUpTest(c *C) { func (s *PublishedRepoCollectionSuite) SetUpTest(c *C) {
s.db, _ = database.OpenDB(c.MkDir()) s.db, _ = database.NewOpenDB(c.MkDir())
s.factory = NewCollectionFactory(s.db) s.factory = NewCollectionFactory(s.db)
s.snapshotCollection = s.factory.SnapshotCollection() s.snapshotCollection = s.factory.SnapshotCollection()
@@ -640,7 +640,7 @@ type PublishedRepoRemoveSuite struct {
var _ = Suite(&PublishedRepoRemoveSuite{}) var _ = Suite(&PublishedRepoRemoveSuite{})
func (s *PublishedRepoRemoveSuite) SetUpTest(c *C) { func (s *PublishedRepoRemoveSuite) SetUpTest(c *C) {
s.db, _ = database.OpenDB(c.MkDir()) s.db, _ = database.NewOpenDB(c.MkDir())
s.factory = NewCollectionFactory(s.db) s.factory = NewCollectionFactory(s.db)
s.snapshotCollection = s.factory.SnapshotCollection() s.snapshotCollection = s.factory.SnapshotCollection()

View File

@@ -44,7 +44,7 @@ func (s *PackageRefListSuite) SetUpTest(c *C) {
} }
func (s *PackageRefListSuite) TestNewPackageListFromRefList(c *C) { func (s *PackageRefListSuite) TestNewPackageListFromRefList(c *C) {
db, _ := database.OpenDB(c.MkDir()) db, _ := database.NewOpenDB(c.MkDir())
coll := NewPackageCollection(db) coll := NewPackageCollection(db)
coll.Update(s.p1) coll.Update(s.p1)
coll.Update(s.p3) coll.Update(s.p3)
@@ -166,7 +166,7 @@ func (s *PackageRefListSuite) TestSubstract(c *C) {
} }
func (s *PackageRefListSuite) TestDiff(c *C) { func (s *PackageRefListSuite) TestDiff(c *C) {
db, _ := database.OpenDB(c.MkDir()) db, _ := database.NewOpenDB(c.MkDir())
coll := NewPackageCollection(db) coll := NewPackageCollection(db)
packages := []*Package{ packages := []*Package{
@@ -238,7 +238,7 @@ func (s *PackageRefListSuite) TestDiff(c *C) {
} }
func (s *PackageRefListSuite) TestMerge(c *C) { func (s *PackageRefListSuite) TestMerge(c *C) {
db, _ := database.OpenDB(c.MkDir()) db, _ := database.NewOpenDB(c.MkDir())
coll := NewPackageCollection(db) coll := NewPackageCollection(db)
packages := []*Package{ packages := []*Package{

View File

@@ -92,7 +92,7 @@ func (s *RemoteRepoSuite) SetUpTest(c *C) {
s.flat, _ = NewRemoteRepo("exp42", "http://repos.express42.com/virool/precise/", "./", []string{}, []string{}, false, false) s.flat, _ = NewRemoteRepo("exp42", "http://repos.express42.com/virool/precise/", "./", []string{}, []string{}, false, false)
s.downloader = http.NewFakeDownloader().ExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/Release", exampleReleaseFile) s.downloader = http.NewFakeDownloader().ExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/Release", exampleReleaseFile)
s.progress = console.NewProgress() s.progress = console.NewProgress()
s.db, _ = database.OpenDB(c.MkDir()) s.db, _ = database.NewOpenDB(c.MkDir())
s.collectionFactory = NewCollectionFactory(s.db) s.collectionFactory = NewCollectionFactory(s.db)
s.packagePool = files.NewPackagePool(c.MkDir(), false) s.packagePool = files.NewPackagePool(c.MkDir(), false)
s.cs = files.NewMockChecksumStorage() s.cs = files.NewMockChecksumStorage()
@@ -615,7 +615,7 @@ type RemoteRepoCollectionSuite struct {
var _ = Suite(&RemoteRepoCollectionSuite{}) var _ = Suite(&RemoteRepoCollectionSuite{})
func (s *RemoteRepoCollectionSuite) SetUpTest(c *C) { func (s *RemoteRepoCollectionSuite) SetUpTest(c *C) {
s.db, _ = database.OpenDB(c.MkDir()) s.db, _ = database.NewOpenDB(c.MkDir())
s.collection = NewRemoteRepoCollection(s.db) s.collection = NewRemoteRepoCollection(s.db)
s.SetUpPackages() s.SetUpPackages()
} }

View File

@@ -112,7 +112,7 @@ type SnapshotCollectionSuite struct {
var _ = Suite(&SnapshotCollectionSuite{}) var _ = Suite(&SnapshotCollectionSuite{})
func (s *SnapshotCollectionSuite) SetUpTest(c *C) { func (s *SnapshotCollectionSuite) SetUpTest(c *C) {
s.db, _ = database.OpenDB(c.MkDir()) s.db, _ = database.NewOpenDB(c.MkDir())
s.collection = NewSnapshotCollection(s.db) s.collection = NewSnapshotCollection(s.db)
s.SetUpPackages() s.SetUpPackages()

View File

@@ -1,7 +1,9 @@
package main package main
import ( import (
"math/rand"
"os" "os"
"time"
"github.com/smira/aptly/aptly" "github.com/smira/aptly/aptly"
"github.com/smira/aptly/cmd" "github.com/smira/aptly/cmd"
@@ -17,5 +19,7 @@ func main() {
aptly.Version = Version aptly.Version = Version
rand.Seed(time.Now().UnixNano())
os.Exit(cmd.Run(cmd.RootCommand(), os.Args[1:], true)) os.Exit(cmd.Run(cmd.RootCommand(), os.Args[1:], true))
} }

View File

@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "APTLY" "1" "April 2017" "" "" .TH "APTLY" "1" "July 2017" "" ""
. .
.SH "NAME" .SH "NAME"
\fBaptly\fR \- Debian repository management tool \fBaptly\fR \- Debian repository management tool
@@ -392,6 +392,10 @@ list of architectures to consider during (comma\-separated), default to all avai
location of configuration file (default locations are /etc/aptly\.conf, ~/\.aptly\.conf) location of configuration file (default locations are /etc/aptly\.conf, ~/\.aptly\.conf)
. .
.TP .TP
\-\fBdb\-open\-attempts\fR=10
number of attempts to open DB if it\(cqs locked by other instance
.
.TP
\-\fBdep\-follow\-all\-variants\fR=false \-\fBdep\-follow\-all\-variants\fR=false
when processing dependencies, follow a & b if dependency is \(cqa|b\(cq when processing dependencies, follow a & b if dependency is \(cqa|b\(cq
. .

View File

@@ -13,6 +13,7 @@ package environment to new version.
Options: Options:
-architectures="": list of architectures to consider during (comma-separated), default to all available -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) -config="": location of configuration file (default locations are /etc/aptly.conf, ~/.aptly.conf)
-db-open-attempts=10: number of attempts to open DB if it's locked by other instance
-dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b' -dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b'
-dep-follow-recommends=false: when processing dependencies, follow Recommends -dep-follow-recommends=false: when processing dependencies, follow Recommends
-dep-follow-source=false: when processing dependencies, follow from binary to Source packages -dep-follow-source=false: when processing dependencies, follow from binary to Source packages

View File

@@ -21,6 +21,7 @@ Use "aptly help <command>" for more information about a command.
Options: Options:
-architectures="": list of architectures to consider during (comma-separated), default to all available -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) -config="": location of configuration file (default locations are /etc/aptly.conf, ~/.aptly.conf)
-db-open-attempts=10: number of attempts to open DB if it's locked by other instance
-dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b' -dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b'
-dep-follow-recommends=false: when processing dependencies, follow Recommends -dep-follow-recommends=false: when processing dependencies, follow Recommends
-dep-follow-source=false: when processing dependencies, follow from binary to Source packages -dep-follow-source=false: when processing dependencies, follow from binary to Source packages

View File

@@ -15,6 +15,7 @@ Example:
Options: Options:
-architectures="": list of architectures to consider during (comma-separated), default to all available -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) -config="": location of configuration file (default locations are /etc/aptly.conf, ~/.aptly.conf)
-db-open-attempts=10: number of attempts to open DB if it's locked by other instance
-dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b' -dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b'
-dep-follow-recommends=false: when processing dependencies, follow Recommends -dep-follow-recommends=false: when processing dependencies, follow Recommends
-dep-follow-source=false: when processing dependencies, follow from binary to Source packages -dep-follow-source=false: when processing dependencies, follow from binary to Source packages

View File

@@ -6,6 +6,7 @@ aptly mirror create - create new mirror
Options: Options:
-architectures="": list of architectures to consider during (comma-separated), default to all available -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) -config="": location of configuration file (default locations are /etc/aptly.conf, ~/.aptly.conf)
-db-open-attempts=10: number of attempts to open DB if it's locked by other instance
-dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b' -dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b'
-dep-follow-recommends=false: when processing dependencies, follow Recommends -dep-follow-recommends=false: when processing dependencies, follow Recommends
-dep-follow-source=false: when processing dependencies, follow from binary to Source packages -dep-follow-source=false: when processing dependencies, follow from binary to Source packages

View File

@@ -17,6 +17,7 @@ Use "mirror help <command>" for more information about a command.
Options: Options:
-architectures="": list of architectures to consider during (comma-separated), default to all available -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) -config="": location of configuration file (default locations are /etc/aptly.conf, ~/.aptly.conf)
-db-open-attempts=10: number of attempts to open DB if it's locked by other instance
-dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b' -dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b'
-dep-follow-recommends=false: when processing dependencies, follow Recommends -dep-follow-recommends=false: when processing dependencies, follow Recommends
-dep-follow-source=false: when processing dependencies, follow from binary to Source packages -dep-follow-source=false: when processing dependencies, follow from binary to Source packages

View File

@@ -17,6 +17,7 @@ Use "mirror help <command>" for more information about a command.
Options: Options:
-architectures="": list of architectures to consider during (comma-separated), default to all available -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) -config="": location of configuration file (default locations are /etc/aptly.conf, ~/.aptly.conf)
-db-open-attempts=10: number of attempts to open DB if it's locked by other instance
-dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b' -dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b'
-dep-follow-recommends=false: when processing dependencies, follow Recommends -dep-follow-recommends=false: when processing dependencies, follow Recommends
-dep-follow-source=false: when processing dependencies, follow from binary to Source packages -dep-follow-source=false: when processing dependencies, follow from binary to Source packages

View File

@@ -7,6 +7,7 @@ aptly mirror create - create new mirror
Options: Options:
-architectures="": list of architectures to consider during (comma-separated), default to all available -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) -config="": location of configuration file (default locations are /etc/aptly.conf, ~/.aptly.conf)
-db-open-attempts=10: number of attempts to open DB if it's locked by other instance
-dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b' -dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b'
-dep-follow-recommends=false: when processing dependencies, follow Recommends -dep-follow-recommends=false: when processing dependencies, follow Recommends
-dep-follow-source=false: when processing dependencies, follow from binary to Source packages -dep-follow-source=false: when processing dependencies, follow from binary to Source packages

View File

@@ -11,10 +11,10 @@ Information from release file:
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
Codename: wheezy Codename: wheezy
Components: main contrib non-free Components: main contrib non-free
Date: Sat, 04 Jun 2016 11:47:54 UTC Date: Sat, 17 Jun 2017 08:55:32 UTC
Description: Debian 7.11 Released 04 June 2016 Description: Debian 7.11 Released 04 June 2016
Label: Debian Label: Debian
Origin: Debian Origin: Debian
Suite: oldstable Suite: oldoldstable
Version: 7.11 Version: 7.11

View File

@@ -11,10 +11,10 @@ Information from release file:
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
Codename: wheezy Codename: wheezy
Components: main contrib non-free Components: main contrib non-free
Date: Sat, 04 Jun 2016 11:47:54 UTC Date: Sat, 17 Jun 2017 08:55:32 UTC
Description: Debian 7.11 Released 04 June 2016 Description: Debian 7.11 Released 04 June 2016
Label: Debian Label: Debian
Origin: Debian Origin: Debian
Suite: oldstable Suite: oldoldstable
Version: 7.11 Version: 7.11

View File

@@ -11,10 +11,10 @@ Information from release file:
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
Codename: wheezy Codename: wheezy
Components: main contrib non-free Components: main contrib non-free
Date: Sat, 04 Jun 2016 11:47:54 UTC Date: Sat, 17 Jun 2017 08:55:32 UTC
Description: Debian 7.11 Released 04 June 2016 Description: Debian 7.11 Released 04 June 2016
Label: Debian Label: Debian
Origin: Debian Origin: Debian
Suite: oldstable Suite: oldoldstable
Version: 7.11 Version: 7.11

View File

@@ -15,5 +15,5 @@ Description: Long Term Support for Debian 7
Label: Debian-Security Label: Debian-Security
Origin: Debian Origin: Debian
Suite: oldstable Suite: oldoldstable
Version: 7.0 Version: 7.0

View File

@@ -11,10 +11,10 @@ Information from release file:
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
Codename: wheezy Codename: wheezy
Components: main contrib non-free Components: main contrib non-free
Date: Sat, 04 Jun 2016 11:47:54 UTC Date: Sat, 17 Jun 2017 08:55:32 UTC
Description: Debian 7.11 Released 04 June 2016 Description: Debian 7.11 Released 04 June 2016
Label: Debian Label: Debian
Origin: Debian Origin: Debian
Suite: oldstable Suite: oldoldstable
Version: 7.11 Version: 7.11

View File

@@ -17,5 +17,5 @@ Description: Long Term Support for Debian 7
Label: Debian-Security Label: Debian-Security
Origin: Debian Origin: Debian
Suite: oldstable Suite: oldoldstable
Version: 7.0 Version: 7.0

View File

@@ -11,10 +11,10 @@ Information from release file:
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
Codename: wheezy Codename: wheezy
Components: main contrib non-free Components: main contrib non-free
Date: Sat, 04 Jun 2016 11:47:54 UTC Date: Sat, 17 Jun 2017 08:55:32 UTC
Description: Debian 7.11 Released 04 June 2016 Description: Debian 7.11 Released 04 June 2016
Label: Debian Label: Debian
Origin: Debian Origin: Debian
Suite: oldstable Suite: oldoldstable
Version: 7.11 Version: 7.11

View File

@@ -11,10 +11,10 @@ Information from release file:
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
Codename: wheezy Codename: wheezy
Components: main contrib non-free Components: main contrib non-free
Date: Sat, 04 Jun 2016 11:47:54 UTC Date: Sat, 17 Jun 2017 08:55:32 UTC
Description: Debian 7.11 Released 04 June 2016 Description: Debian 7.11 Released 04 June 2016
Label: Debian Label: Debian
Origin: Debian Origin: Debian
Suite: oldstable Suite: oldoldstable
Version: 7.11 Version: 7.11

View File

@@ -11,10 +11,10 @@ Information from release file:
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
Codename: wheezy Codename: wheezy
Components: main contrib non-free Components: main contrib non-free
Date: Sat, 04 Jun 2016 11:47:54 UTC Date: Sat, 17 Jun 2017 08:55:32 UTC
Description: Debian 7.11 Released 04 June 2016 Description: Debian 7.11 Released 04 June 2016
Label: Debian Label: Debian
Origin: Debian Origin: Debian
Suite: oldstable Suite: oldoldstable
Version: 7.11 Version: 7.11

View File

@@ -11,10 +11,10 @@ Information from release file:
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
Codename: wheezy Codename: wheezy
Components: main contrib non-free Components: main contrib non-free
Date: Sat, 04 Jun 2016 11:47:54 UTC Date: Sat, 17 Jun 2017 08:55:32 UTC
Description: Debian 7.11 Released 04 June 2016 Description: Debian 7.11 Released 04 June 2016
Label: Debian Label: Debian
Origin: Debian Origin: Debian
Suite: oldstable Suite: oldoldstable
Version: 7.11 Version: 7.11

View File

@@ -15,5 +15,5 @@ Description: Long Term Support for Debian 7
Label: Debian-Security Label: Debian-Security
Origin: Debian Origin: Debian
Suite: oldstable Suite: oldoldstable
Version: 7.0 Version: 7.0

View File

@@ -11,10 +11,10 @@ Information from release file:
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
Codename: wheezy Codename: wheezy
Components: main contrib non-free Components: main contrib non-free
Date: Sat, 04 Jun 2016 11:47:54 UTC Date: Sat, 17 Jun 2017 08:55:32 UTC
Description: Debian 7.11 Released 04 June 2016 Description: Debian 7.11 Released 04 June 2016
Label: Debian Label: Debian
Origin: Debian Origin: Debian
Suite: oldstable Suite: oldoldstable
Version: 7.11 Version: 7.11

View File

@@ -11,10 +11,10 @@ Information from release file:
Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
Codename: wheezy Codename: wheezy
Components: main contrib non-free Components: main contrib non-free
Date: Sat, 04 Jun 2016 11:47:54 UTC Date: Sat, 17 Jun 2017 08:55:32 UTC
Description: Debian 7.11 Released 04 June 2016 Description: Debian 7.11 Released 04 June 2016
Label: Debian Label: Debian
Origin: Debian Origin: Debian
Suite: oldstable Suite: oldoldstable
Version: 7.11 Version: 7.11

View File

@@ -17,5 +17,5 @@ Description: Long Term Support for Debian 7
Label: Debian-Security Label: Debian-Security
Origin: Debian Origin: Debian
Suite: oldstable Suite: oldoldstable
Version: 7.0 Version: 7.0