mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-06-13 06:40:41 +00:00
Merge pull request #589 from smira/api-db-no-lock-fix
Rework the way database is open/re-open in aptly
This commit is contained in:
+28
-23
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-13
@@ -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")
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
+27
-22
@@ -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
|
||||||
|
|||||||
+13
-7
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -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()
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -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()
|
||||||
|
|||||||
@@ -395,6 +395,4 @@ func (l *PackageRefList) FilterLatestRefs() {
|
|||||||
|
|
||||||
lastArch, lastName, lastVer = arch, name, ver
|
lastArch, lastName, lastVer = arch, name, ver
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -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{
|
||||||
|
|||||||
+1
-1
@@ -198,7 +198,7 @@ func (repo *RemoteRepo) IndexesRootURL() *url.URL {
|
|||||||
if !repo.IsFlat() {
|
if !repo.IsFlat() {
|
||||||
path = &url.URL{Path: fmt.Sprintf("dists/%s/", repo.Distribution)}
|
path = &url.URL{Path: fmt.Sprintf("dists/%s/", repo.Distribution)}
|
||||||
} else {
|
} else {
|
||||||
path = &url.URL{Path: fmt.Sprintf("%s", repo.Distribution)}
|
path = &url.URL{Path: repo.Distribution}
|
||||||
}
|
}
|
||||||
|
|
||||||
return repo.archiveRootURL.ResolveReference(path)
|
return repo.archiveRootURL.ResolveReference(path)
|
||||||
|
|||||||
+2
-2
@@ -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()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|
||||||
|
|||||||
@@ -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))
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -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
|
||||||
.
|
.
|
||||||
|
|||||||
+4
-8
@@ -1,10 +1,6 @@
|
|||||||
package query
|
package query
|
||||||
|
|
||||||
import (
|
import . "gopkg.in/check.v1"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
. "gopkg.in/check.v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
type LexerSuite struct {
|
type LexerSuite struct {
|
||||||
}
|
}
|
||||||
@@ -46,13 +42,13 @@ func (s *LexerSuite) TestConsume(c *C) {
|
|||||||
func (s *LexerSuite) TestString(c *C) {
|
func (s *LexerSuite) TestString(c *C) {
|
||||||
l, _ := lex("query", "package (<< 1.3)")
|
l, _ := lex("query", "package (<< 1.3)")
|
||||||
|
|
||||||
c.Check(fmt.Sprintf("%s", l.Current()), Equals, "\"package\"")
|
c.Check(l.Current().String(), Equals, "\"package\"")
|
||||||
l.Consume()
|
l.Consume()
|
||||||
c.Check(fmt.Sprintf("%s", l.Current()), Equals, "(")
|
c.Check(l.Current().String(), Equals, "(")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LexerSuite) TestError(c *C) {
|
func (s *LexerSuite) TestError(c *C) {
|
||||||
l, _ := lex("query", "'package")
|
l, _ := lex("query", "'package")
|
||||||
|
|
||||||
c.Check(fmt.Sprintf("%s", l.Current()), Equals, "error: unexpected eof in quoted string")
|
c.Check(l.Current().String(), Equals, "error: unexpected eof in quoted string")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user