mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-05-06 22:18:28 +00:00
Merge branch 'sbadia-swift'
Conflicts: AUTHORS
This commit is contained in:
+2
-1
@@ -8,12 +8,13 @@ env:
|
|||||||
global:
|
global:
|
||||||
- secure: "YSwtFrMqh4oUvdSQTXBXMHHLWeQgyNEL23ChIZwU0nuDGIcQZ65kipu0PzefedtUbK4ieC065YCUi4UDDh6gPotB/Wu1pnYg3dyQ7rFvhaVYAAUEpajAdXZhlx+7+J8a4FZMeC/kqiahxoRgLbthF9019ouIqhGB9zHKI6/yZwc="
|
- secure: "YSwtFrMqh4oUvdSQTXBXMHHLWeQgyNEL23ChIZwU0nuDGIcQZ65kipu0PzefedtUbK4ieC065YCUi4UDDh6gPotB/Wu1pnYg3dyQ7rFvhaVYAAUEpajAdXZhlx+7+J8a4FZMeC/kqiahxoRgLbthF9019ouIqhGB9zHKI6/yZwc="
|
||||||
- secure: "V7OjWrfQ8UbktgT036jYQPb/7GJT3Ol9LObDr8FYlzsQ+F1uj2wLac6ePuxcOS4FwWOJinWGM1h+JiFkbxbyFqfRNJ0jj0O2p93QyDojxFVOn1mXqqvV66KFqAWR2Vzkny/gDvj8LTvdB1cgAIm2FNOkQc6E1BFnyWS2sN9ea5E="
|
- secure: "V7OjWrfQ8UbktgT036jYQPb/7GJT3Ol9LObDr8FYlzsQ+F1uj2wLac6ePuxcOS4FwWOJinWGM1h+JiFkbxbyFqfRNJ0jj0O2p93QyDojxFVOn1mXqqvV66KFqAWR2Vzkny/gDvj8LTvdB1cgAIm2FNOkQc6E1BFnyWS2sN9ea5E="
|
||||||
|
- secure: "Nah4qrYI/uVhOlrL5xwgvMtK4TZPqw3hh+ApQTq5V6/EsSYLBGBoWEgR8LaKas8aaemeOEJJx6rwNBCpsF+UT7Hmf4eIsrV7dGSRRFZtd1VA8wI40iOWbsAHFWdeCYdXzqyrRWjXqm0ZCcKrnQeh/4N9i5vCLrAMjtCaUQuJKWY="
|
||||||
before_install:
|
before_install:
|
||||||
- sudo apt-get update -qq
|
- sudo apt-get update -qq
|
||||||
- sudo apt-get install -y python-virtualenv graphviz
|
- sudo apt-get install -y python-virtualenv graphviz
|
||||||
- virtualenv env
|
- virtualenv env
|
||||||
- . env/bin/activate
|
- . env/bin/activate
|
||||||
- pip install boto requests
|
- pip install boto requests python-swiftclient
|
||||||
install:
|
install:
|
||||||
- make prepare
|
- make prepare
|
||||||
|
|
||||||
|
|||||||
@@ -14,3 +14,4 @@ List of contributors, in chronological order:
|
|||||||
* Andrea Bernardo Ciddio (https://github.com/bcandrea)
|
* Andrea Bernardo Ciddio (https://github.com/bcandrea)
|
||||||
* Michael Koval (https://github.com/mkoval)
|
* Michael Koval (https://github.com/mkoval)
|
||||||
* Alexander Guy (https://github.com/alexanderguy)
|
* Alexander Guy (https://github.com/alexanderguy)
|
||||||
|
* Sebastien Badia (https://github.com/sbadia)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ gom 'github.com/julienschmidt/httprouter', :commit => '46807412fe50aaceb73bb5706
|
|||||||
gom 'github.com/mattn/go-shellwords', :commit => 'c7ca6f94add751566a61cf2199e1de78d4c3eee4'
|
gom 'github.com/mattn/go-shellwords', :commit => 'c7ca6f94add751566a61cf2199e1de78d4c3eee4'
|
||||||
gom 'github.com/mitchellh/goamz/s3', :commit => 'e7664b32019f31fd1bdf33f9e85f28722f700405'
|
gom 'github.com/mitchellh/goamz/s3', :commit => 'e7664b32019f31fd1bdf33f9e85f28722f700405'
|
||||||
gom 'github.com/mkrautz/goar', :commit => '36eb5f3452b1283a211fa35bc00c646fd0db5c4b'
|
gom 'github.com/mkrautz/goar', :commit => '36eb5f3452b1283a211fa35bc00c646fd0db5c4b'
|
||||||
|
gom 'github.com/ncw/swift', :commit => '384ef27c70645e285f8bb9d02276bf654d06027e'
|
||||||
gom 'github.com/smira/commander', :commit => 'f408b00e68d5d6e21b9f18bd310978dafc604e47'
|
gom 'github.com/smira/commander', :commit => 'f408b00e68d5d6e21b9f18bd310978dafc604e47'
|
||||||
gom 'github.com/smira/flag', :commit => '357ed3e599ffcbd4aeaa828e1d10da2df3ea5107'
|
gom 'github.com/smira/flag', :commit => '357ed3e599ffcbd4aeaa828e1d10da2df3ea5107'
|
||||||
gom 'github.com/smira/go-ftp-protocol/protocol', :commit => '066b75c2b70dca7ae10b1b88b47534a3c31ccfaa'
|
gom 'github.com/smira/go-ftp-protocol/protocol', :commit => '066b75c2b70dca7ae10b1b88b47534a3c31ccfaa'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
GOVERSION=$(shell go version | awk '{print $$3;}')
|
GOVERSION=$(shell go version | awk '{print $$3;}')
|
||||||
PACKAGES=context database deb files http query s3 utils
|
PACKAGES=context database deb files http query swift s3 utils
|
||||||
ALL_PACKAGES=api aptly context cmd console database deb files http query s3 utils
|
ALL_PACKAGES=api aptly context cmd console database deb files http query swift s3 utils
|
||||||
BINPATH=$(abspath ./_vendor/bin)
|
BINPATH=$(abspath ./_vendor/bin)
|
||||||
GOM_ENVIRONMENT=-test
|
GOM_ENVIRONMENT=-test
|
||||||
PYTHON?=python
|
PYTHON?=python
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// SigningOptions is a shared between publish API GPG options structure
|
||||||
type SigningOptions struct {
|
type SigningOptions struct {
|
||||||
Skip bool
|
Skip bool
|
||||||
Batch bool
|
Batch bool
|
||||||
|
|||||||
+4
-2
@@ -18,13 +18,15 @@ func aptlyTaskRun(cmd *commander.Command, args []string) error {
|
|||||||
var text string
|
var text string
|
||||||
cmdArgs := []string{}
|
cmdArgs := []string{}
|
||||||
|
|
||||||
if finfo, err := os.Stat(filename); os.IsNotExist(err) || finfo.IsDir() {
|
var finfo os.FileInfo
|
||||||
|
if finfo, err = os.Stat(filename); os.IsNotExist(err) || finfo.IsDir() {
|
||||||
return fmt.Errorf("no such file, %s\n", filename)
|
return fmt.Errorf("no such file, %s\n", filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("Reading file...\n")
|
fmt.Println("Reading file...\n")
|
||||||
|
|
||||||
file, err := os.Open(filename)
|
var file *os.File
|
||||||
|
file, err = os.Open(filename)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/smira/aptly/files"
|
"github.com/smira/aptly/files"
|
||||||
"github.com/smira/aptly/http"
|
"github.com/smira/aptly/http"
|
||||||
"github.com/smira/aptly/s3"
|
"github.com/smira/aptly/s3"
|
||||||
|
"github.com/smira/aptly/swift"
|
||||||
"github.com/smira/aptly/utils"
|
"github.com/smira/aptly/utils"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
@@ -326,6 +327,18 @@ func (context *AptlyContext) GetPublishedStorage(name string) aptly.PublishedSto
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
Fatal(err)
|
Fatal(err)
|
||||||
}
|
}
|
||||||
|
} else if strings.HasPrefix(name, "swift:") {
|
||||||
|
params, ok := context.Config().SwiftPublishRoots[name[6:]]
|
||||||
|
if !ok {
|
||||||
|
Fatal(fmt.Errorf("published Swift storage %v not configured", name[6:]))
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
publishedStorage, err = swift.NewPublishedStorage(params.UserName, params.Password,
|
||||||
|
params.AuthURL, params.Tenant, params.TenantID, params.Container, params.Prefix)
|
||||||
|
if err != nil {
|
||||||
|
Fatal(err)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Fatal(fmt.Errorf("unknown published storage format: %v", name))
|
Fatal(fmt.Errorf("unknown published storage format: %v", name))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// BuildGraph generates graph contents from aptly object database
|
||||||
func BuildGraph(collectionFactory *CollectionFactory) (gographviz.Interface, error) {
|
func BuildGraph(collectionFactory *CollectionFactory) (gographviz.Interface, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
|||||||
@@ -297,6 +297,7 @@ func (collection *SnapshotCollection) ForEach(handler func(*Snapshot) error) err
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ForEachSorted runs method for each snapshot following some sort order
|
||||||
func (collection *SnapshotCollection) ForEachSorted(sortMethod string, handler func(*Snapshot) error) error {
|
func (collection *SnapshotCollection) ForEachSorted(sortMethod string, handler func(*Snapshot) error) error {
|
||||||
sorter, err := newSnapshotSorter(sortMethod, collection)
|
sorter, err := newSnapshotSorter(sortMethod, collection)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+42
-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" "December 2014" "" ""
|
.TH "APTLY" "1" "February 2015" "" ""
|
||||||
.
|
.
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
\fBaptly\fR \- Debian repository management tool
|
\fBaptly\fR \- Debian repository management tool
|
||||||
@@ -60,6 +60,18 @@ Configuration file is stored in JSON format (default values shown below):
|
|||||||
"encryptionMethod": "",
|
"encryptionMethod": "",
|
||||||
"plusWorkaround": false
|
"plusWorkaround": false
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"SwiftPublishEndpoints": {
|
||||||
|
"test": {
|
||||||
|
"container": "repo",
|
||||||
|
"osname": "",
|
||||||
|
"password": "",
|
||||||
|
"prefix": "",
|
||||||
|
"authurl": "",
|
||||||
|
"tenant": "",
|
||||||
|
"tenantid": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.
|
.
|
||||||
.fi
|
.fi
|
||||||
@@ -162,6 +174,35 @@ In order to publish to S3, specify endpoint as \fBs3:endpoint\-name:\fR before p
|
|||||||
.P
|
.P
|
||||||
\fBaptly publish snapshot wheezy\-main s3:test:\fR
|
\fBaptly publish snapshot wheezy\-main s3:test:\fR
|
||||||
.
|
.
|
||||||
|
.SH "OPENSTACK SWIFT PUBLISHING ENDPOINTS"
|
||||||
|
aptly could be configured to publish repository directly to OpenStack Swift\. First, publishing endpoints should be described in aptly configuration file\. Each endpoint has name and associated settings:
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fBcontainer\fR
|
||||||
|
container name
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fBprefix\fR
|
||||||
|
(optional) do publishing under specified prefix in the container, defaults to no prefix (container root)
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fBosname\fR, \fBpassword\fR
|
||||||
|
(optional) OpenStack credentials to access Keystone\. If not supplied, environment variables \fBOS_USERNAME\fR and \fBOS_PASSWORD\fR are used\.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fBtenant\fR, \fBtenantid\fR
|
||||||
|
(optional) OpenStack tenant name and id (in order to use v2 authentication)\.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fBauthurl\fR
|
||||||
|
(optional) the full url of Keystone server (including port, and version)\. example \fBhttp://identity\.example\.com:5000/v2\.0\fR
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
In order to publish to Swift, specify endpoint as \fBswift:endpoint\-name:\fR before publishing prefix on the command line, e\.g\.:
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
\fBaptly publish snapshot jessie\-main swift:test:\fR
|
||||||
|
.
|
||||||
.SH "PACKAGE QUERY"
|
.SH "PACKAGE QUERY"
|
||||||
Some commands accept package queries to identify list of packages to process\. Package query syntax almost matches \fBreprepro\fR query language\. Query consists of the following simple terms:
|
Some commands accept package queries to identify list of packages to process\. Package query syntax almost matches \fBreprepro\fR query language\. Query consists of the following simple terms:
|
||||||
.
|
.
|
||||||
|
|||||||
@@ -52,6 +52,18 @@ Configuration file is stored in JSON format (default values shown below):
|
|||||||
"encryptionMethod": "",
|
"encryptionMethod": "",
|
||||||
"plusWorkaround": false
|
"plusWorkaround": false
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"SwiftPublishEndpoints": {
|
||||||
|
"test": {
|
||||||
|
"container": "repo",
|
||||||
|
"osname": "",
|
||||||
|
"password": "",
|
||||||
|
"prefix": "",
|
||||||
|
"authurl": "",
|
||||||
|
"tenant": "",
|
||||||
|
"tenantid": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
@@ -144,6 +156,31 @@ publishing prefix on the command line, e.g.:
|
|||||||
|
|
||||||
`aptly publish snapshot wheezy-main s3:test:`
|
`aptly publish snapshot wheezy-main s3:test:`
|
||||||
|
|
||||||
|
## OPENSTACK SWIFT PUBLISHING ENDPOINTS
|
||||||
|
|
||||||
|
aptly could be configured to publish repository directly to OpenStack Swift. First,
|
||||||
|
publishing endpoints should be described in aptly configuration file. Each endpoint
|
||||||
|
has name and associated settings:
|
||||||
|
|
||||||
|
* `container`:
|
||||||
|
container name
|
||||||
|
* `prefix`:
|
||||||
|
(optional) do publishing under specified prefix in the container, defaults to
|
||||||
|
no prefix (container root)
|
||||||
|
* `osname`, `password`:
|
||||||
|
(optional) OpenStack credentials to access Keystone. If not supplied,
|
||||||
|
environment variables `OS_USERNAME` and `OS_PASSWORD` are used.
|
||||||
|
* `tenant`, `tenantid`:
|
||||||
|
(optional) OpenStack tenant name and id (in order to use v2 authentication).
|
||||||
|
* `authurl`:
|
||||||
|
(optional) the full url of Keystone server (including port, and version).
|
||||||
|
example `http://identity.example.com:5000/v2.0`
|
||||||
|
|
||||||
|
In order to publish to Swift, specify endpoint as `swift:endpoint-name:` before
|
||||||
|
publishing prefix on the command line, e.g.:
|
||||||
|
|
||||||
|
`aptly publish snapshot jessie-main swift:test:`
|
||||||
|
|
||||||
## PACKAGE QUERY
|
## PACKAGE QUERY
|
||||||
|
|
||||||
Some commands accept package queries to identify list of packages to process.
|
Some commands accept package queries to identify list of packages to process.
|
||||||
|
|||||||
+229
@@ -0,0 +1,229 @@
|
|||||||
|
package swift
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/ncw/swift"
|
||||||
|
"github.com/smira/aptly/aptly"
|
||||||
|
"github.com/smira/aptly/files"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PublishedStorage abstract file system with published files (actually hosted on Swift)
|
||||||
|
type PublishedStorage struct {
|
||||||
|
conn swift.Connection
|
||||||
|
container string
|
||||||
|
prefix string
|
||||||
|
supportBulkDelete bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type swiftInfo map[string]interface{}
|
||||||
|
|
||||||
|
// Check interface
|
||||||
|
var (
|
||||||
|
_ aptly.PublishedStorage = (*PublishedStorage)(nil)
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewPublishedStorage creates new instance of PublishedStorage with specified Swift access
|
||||||
|
// keys, tenant and tenantId
|
||||||
|
func NewPublishedStorage(username string, password string, authURL string, tenant string, tenantID string, container string, prefix string) (*PublishedStorage, error) {
|
||||||
|
if username == "" {
|
||||||
|
if username = os.Getenv("OS_USERNAME"); username == "" {
|
||||||
|
username = os.Getenv("ST_USER")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if password == "" {
|
||||||
|
if password = os.Getenv("OS_PASSWORD"); password == "" {
|
||||||
|
password = os.Getenv("ST_KEY")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if authURL == "" {
|
||||||
|
if authURL = os.Getenv("OS_AUTH_URL"); authURL == "" {
|
||||||
|
authURL = os.Getenv("ST_AUTH")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if tenant == "" {
|
||||||
|
tenant = os.Getenv("OS_TENANT_NAME")
|
||||||
|
}
|
||||||
|
if tenantID == "" {
|
||||||
|
tenantID = os.Getenv("OS_TENANT_ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
ct := swift.Connection{
|
||||||
|
UserName: username,
|
||||||
|
ApiKey: password,
|
||||||
|
AuthUrl: authURL,
|
||||||
|
UserAgent: "aptly/" + aptly.Version,
|
||||||
|
Tenant: tenant,
|
||||||
|
TenantId: tenantID,
|
||||||
|
ConnectTimeout: 60 * time.Second,
|
||||||
|
Timeout: 60 * time.Second,
|
||||||
|
}
|
||||||
|
err := ct.Authenticate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("swift authentication failed: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var bulkDelete bool
|
||||||
|
resp, err := http.Get(filepath.Join(ct.StorageUrl, "..", "..") + "/info")
|
||||||
|
if err == nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
decoder := json.NewDecoder(resp.Body)
|
||||||
|
var infos swiftInfo
|
||||||
|
if decoder.Decode(&infos) == nil {
|
||||||
|
_, bulkDelete = infos["bulk_delete"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result := &PublishedStorage{
|
||||||
|
conn: ct,
|
||||||
|
container: container,
|
||||||
|
prefix: prefix,
|
||||||
|
supportBulkDelete: bulkDelete,
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String
|
||||||
|
func (storage *PublishedStorage) String() string {
|
||||||
|
return fmt.Sprintf("Swift: %s:%s/%s", storage.conn.StorageUrl, storage.container, storage.prefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MkDir creates directory recursively under public path
|
||||||
|
func (storage *PublishedStorage) MkDir(path string) error {
|
||||||
|
// no op for Swift
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PutFile puts file into published storage at specified path
|
||||||
|
func (storage *PublishedStorage) PutFile(path string, sourceFilename string) error {
|
||||||
|
var (
|
||||||
|
source *os.File
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
source, err = os.Open(sourceFilename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer source.Close()
|
||||||
|
|
||||||
|
_, err = storage.conn.ObjectPut(storage.container, filepath.Join(storage.prefix, path), source, false, "", "", nil)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error uploading %s to %s: %s", sourceFilename, storage, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove removes single file under public path
|
||||||
|
func (storage *PublishedStorage) Remove(path string) error {
|
||||||
|
err := storage.conn.ObjectDelete(storage.container, filepath.Join(storage.prefix, path))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error deleting %s from %s: %s", path, storage, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveDirs removes directory structure under public path
|
||||||
|
func (storage *PublishedStorage) RemoveDirs(path string, progress aptly.Progress) error {
|
||||||
|
path = filepath.Join(storage.prefix, path)
|
||||||
|
opts := swift.ObjectsOpts{
|
||||||
|
Prefix: path,
|
||||||
|
}
|
||||||
|
|
||||||
|
objects, err := storage.conn.ObjectNamesAll(storage.container, &opts)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error removing dir %s from %s: %s", path, storage, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for index, name := range objects {
|
||||||
|
objects[index] = name[len(storage.prefix):]
|
||||||
|
}
|
||||||
|
|
||||||
|
multiDelete := true
|
||||||
|
if storage.supportBulkDelete {
|
||||||
|
_, err := storage.conn.BulkDelete(storage.container, objects)
|
||||||
|
multiDelete = err != nil
|
||||||
|
}
|
||||||
|
if multiDelete {
|
||||||
|
for _, name := range objects {
|
||||||
|
if err := storage.conn.ObjectDelete(storage.container, name); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LinkFromPool links package file from pool to dist's pool location
|
||||||
|
//
|
||||||
|
// publishedDirectory is desired location in pool (like prefix/pool/component/liba/libav/)
|
||||||
|
// sourcePool is instance of aptly.PackagePool
|
||||||
|
// sourcePath is filepath to package file in package pool
|
||||||
|
//
|
||||||
|
// LinkFromPool returns relative path for the published file to be included in package index
|
||||||
|
func (storage *PublishedStorage) LinkFromPool(publishedDirectory string, sourcePool aptly.PackagePool,
|
||||||
|
sourcePath, sourceMD5 string, force bool) error {
|
||||||
|
// verify that package pool is local pool in filesystem
|
||||||
|
_ = sourcePool.(*files.PackagePool)
|
||||||
|
|
||||||
|
baseName := filepath.Base(sourcePath)
|
||||||
|
relPath := filepath.Join(publishedDirectory, baseName)
|
||||||
|
poolPath := filepath.Join(storage.prefix, relPath)
|
||||||
|
|
||||||
|
var (
|
||||||
|
info swift.Object
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
info, _, err = storage.conn.Object(storage.container, poolPath)
|
||||||
|
if err != nil {
|
||||||
|
if err != swift.ObjectNotFound {
|
||||||
|
return fmt.Errorf("error getting information about %s from %s: %s", poolPath, storage, err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !force && info.Hash != sourceMD5 {
|
||||||
|
return fmt.Errorf("error putting file to %s: file already exists and is different: %s", poolPath, storage)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return storage.PutFile(relPath, sourcePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filelist returns list of files under prefix
|
||||||
|
func (storage *PublishedStorage) Filelist(prefix string) ([]string, error) {
|
||||||
|
prefix = filepath.Join(storage.prefix, prefix)
|
||||||
|
if prefix != "" {
|
||||||
|
prefix += "/"
|
||||||
|
}
|
||||||
|
opts := swift.ObjectsOpts{
|
||||||
|
Prefix: prefix,
|
||||||
|
}
|
||||||
|
contents, err := storage.conn.ObjectNamesAll(storage.container, &opts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error listing under prefix %s in %s: %s", prefix, storage, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for index, name := range contents {
|
||||||
|
contents[index] = name[len(prefix):]
|
||||||
|
}
|
||||||
|
|
||||||
|
return contents, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RenameFile renames (moves) file
|
||||||
|
func (storage *PublishedStorage) RenameFile(oldName, newName string) error {
|
||||||
|
err := storage.conn.ObjectMove(storage.container, filepath.Join(storage.prefix, oldName), storage.container, filepath.Join(storage.prefix, newName))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error copying %s -> %s in %s: %s", oldName, newName, storage, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,187 @@
|
|||||||
|
package swift
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ncw/swift/swifttest"
|
||||||
|
"github.com/smira/aptly/files"
|
||||||
|
|
||||||
|
. "gopkg.in/check.v1"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
TestAddress = "localhost:5324"
|
||||||
|
AuthURL = "http://" + TestAddress + "/v1.0"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PublishedStorageSuite struct {
|
||||||
|
srv *swifttest.SwiftServer
|
||||||
|
storage, prefixedStorage *PublishedStorage
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = Suite(&PublishedStorageSuite{})
|
||||||
|
|
||||||
|
func (s *PublishedStorageSuite) SetUpTest(c *C) {
|
||||||
|
var err error
|
||||||
|
s.srv, err = swifttest.NewSwiftServer(TestAddress)
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
c.Assert(s.srv, NotNil)
|
||||||
|
|
||||||
|
s.storage, err = NewPublishedStorage("swifttest", "swifttest", AuthURL, "", "", "test", "")
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
|
s.prefixedStorage, err = NewPublishedStorage("swifttest", "swifttest", AuthURL, "", "", "test", "lala")
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
|
s.storage.conn.ContainerCreate("test", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PublishedStorageSuite) TearDownTest(c *C) {
|
||||||
|
s.srv.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PublishedStorageSuite) TestNewPublishedStorage(c *C) {
|
||||||
|
stor, err := NewPublishedStorage("swifttest", "swifttest", AuthURL, "", "", "", "")
|
||||||
|
c.Check(stor, NotNil)
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PublishedStorageSuite) TestPutFile(c *C) {
|
||||||
|
dir := c.MkDir()
|
||||||
|
err := ioutil.WriteFile(filepath.Join(dir, "a"), []byte("welcome to swift!"), 0644)
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
|
err = s.storage.PutFile("a/b.txt", filepath.Join(dir, "a"))
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
|
||||||
|
data, err := s.storage.conn.ObjectGetBytes("test", "a/b.txt")
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
c.Check(data, DeepEquals, []byte("welcome to swift!"))
|
||||||
|
|
||||||
|
err = s.prefixedStorage.PutFile("a/b.txt", filepath.Join(dir, "a"))
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
|
||||||
|
data, err = s.storage.conn.ObjectGetBytes("test", "lala/a/b.txt")
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
c.Check(data, DeepEquals, []byte("welcome to swift!"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PublishedStorageSuite) TestFilelist(c *C) {
|
||||||
|
dir := c.MkDir()
|
||||||
|
err := ioutil.WriteFile(filepath.Join(dir, "a"), []byte("welcome to swift!"), 0644)
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
|
paths := []string{"a", "b", "c", "testa", "test/a", "test/b", "lala/a", "lala/b", "lala/c"}
|
||||||
|
for _, path := range paths {
|
||||||
|
err = s.storage.PutFile(path, filepath.Join(dir, "a"))
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
}
|
||||||
|
|
||||||
|
list, err := s.storage.Filelist("")
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
c.Check(list, DeepEquals, []string{"a", "b", "c", "lala/a", "lala/b", "lala/c", "test/a", "test/b", "testa"})
|
||||||
|
|
||||||
|
list, err = s.storage.Filelist("test")
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
c.Check(list, DeepEquals, []string{"a", "b"})
|
||||||
|
|
||||||
|
list, err = s.storage.Filelist("test2")
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
c.Check(list, DeepEquals, []string{})
|
||||||
|
|
||||||
|
list, err = s.prefixedStorage.Filelist("")
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
c.Check(list, DeepEquals, []string{"a", "b", "c"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PublishedStorageSuite) TestRemove(c *C) {
|
||||||
|
dir := c.MkDir()
|
||||||
|
err := ioutil.WriteFile(filepath.Join(dir, "a"), []byte("welcome to swift!"), 0644)
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
|
err = s.storage.PutFile("a/b.txt", filepath.Join(dir, "a"))
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
|
||||||
|
err = s.storage.Remove("a/b.txt")
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
|
||||||
|
_, err = s.storage.conn.ObjectGetBytes("test", "a/b.txt")
|
||||||
|
c.Check(err, ErrorMatches, "Object Not Found")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PublishedStorageSuite) TestRemoveDirs(c *C) {
|
||||||
|
c.Skip("bulk-delete not available in s3test")
|
||||||
|
|
||||||
|
dir := c.MkDir()
|
||||||
|
err := ioutil.WriteFile(filepath.Join(dir, "a"), []byte("welcome to swift!"), 0644)
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
|
paths := []string{"a", "b", "c", "testa", "test/a", "test/b", "lala/a", "lala/b", "lala/c"}
|
||||||
|
for _, path := range paths {
|
||||||
|
err = s.storage.PutFile(path, filepath.Join(dir, "a"))
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.storage.RemoveDirs("test", nil)
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
|
||||||
|
list, err := s.storage.Filelist("")
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
c.Check(list, DeepEquals, []string{"a", "b", "c", "lala/a", "lala/b", "lala/c", "test/a", "test/b", "testa"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PublishedStorageSuite) TestRenameFile(c *C) {
|
||||||
|
c.Skip("copy not available in s3test")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PublishedStorageSuite) TestLinkFromPool(c *C) {
|
||||||
|
root := c.MkDir()
|
||||||
|
pool := files.NewPackagePool(root)
|
||||||
|
|
||||||
|
sourcePath := filepath.Join(root, "pool/c1/df/mars-invaders_1.03.deb")
|
||||||
|
err := os.MkdirAll(filepath.Dir(sourcePath), 0755)
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
|
err = ioutil.WriteFile(sourcePath, []byte("Contents"), 0644)
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
|
sourcePath2 := filepath.Join(root, "pool/e9/df/mars-invaders_1.03.deb")
|
||||||
|
err = os.MkdirAll(filepath.Dir(sourcePath2), 0755)
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
|
err = ioutil.WriteFile(sourcePath2, []byte("Spam"), 0644)
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
|
// first link from pool
|
||||||
|
err = s.storage.LinkFromPool(filepath.Join("", "pool", "main", "m/mars-invaders"), pool, sourcePath, "c1df1da7a1ce305a3b60af9d5733ac1d", false)
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
|
||||||
|
data, err := s.storage.conn.ObjectGetBytes("test", "pool/main/m/mars-invaders/mars-invaders_1.03.deb")
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
c.Check(data, DeepEquals, []byte("Contents"))
|
||||||
|
|
||||||
|
// duplicate link from pool
|
||||||
|
err = s.storage.LinkFromPool(filepath.Join("", "pool", "main", "m/mars-invaders"), pool, sourcePath, "c1df1da7a1ce305a3b60af9d5733ac1d", false)
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
|
||||||
|
data, err = s.storage.conn.ObjectGetBytes("test", "pool/main/m/mars-invaders/mars-invaders_1.03.deb")
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
c.Check(data, DeepEquals, []byte("Contents"))
|
||||||
|
|
||||||
|
// link from pool with conflict
|
||||||
|
err = s.storage.LinkFromPool(filepath.Join("", "pool", "main", "m/mars-invaders"), pool, sourcePath2, "e9dfd31cc505d51fc26975250750deab", false)
|
||||||
|
c.Check(err, ErrorMatches, ".*file already exists and is different.*")
|
||||||
|
|
||||||
|
data, err = s.storage.conn.ObjectGetBytes("test", "pool/main/m/mars-invaders/mars-invaders_1.03.deb")
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
c.Check(data, DeepEquals, []byte("Contents"))
|
||||||
|
|
||||||
|
// link from pool with conflict and force
|
||||||
|
err = s.storage.LinkFromPool(filepath.Join("", "pool", "main", "m/mars-invaders"), pool, sourcePath2, "e9dfd31cc505d51fc26975250750deab", true)
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
|
||||||
|
data, err = s.storage.conn.ObjectGetBytes("test", "pool/main/m/mars-invaders/mars-invaders_1.03.deb")
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
c.Check(data, DeepEquals, []byte("Spam"))
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
// Package swift handles publishing to OpenStack Swift
|
||||||
|
package swift
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package swift
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
. "gopkg.in/check.v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Launch gocheck tests
|
||||||
|
func Test(t *testing.T) {
|
||||||
|
TestingT(t)
|
||||||
|
}
|
||||||
+2
-1
@@ -10,6 +10,7 @@ import traceback
|
|||||||
|
|
||||||
from lib import BaseTest
|
from lib import BaseTest
|
||||||
from s3_lib import S3Test
|
from s3_lib import S3Test
|
||||||
|
from swift_lib import SwiftTest
|
||||||
from api_lib import APITest
|
from api_lib import APITest
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -37,7 +38,7 @@ def run(include_long_tests=False, capture_results=False, tests=None, filters=Non
|
|||||||
o = getattr(testModule, name)
|
o = getattr(testModule, name)
|
||||||
|
|
||||||
if not (inspect.isclass(o) and issubclass(o, BaseTest) and o is not BaseTest and
|
if not (inspect.isclass(o) and issubclass(o, BaseTest) and o is not BaseTest and
|
||||||
o is not S3Test and o is not APITest):
|
o is not SwiftTest and o is not S3Test and o is not APITest):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
newBase = o.__bases__[0]
|
newBase = o.__bases__[0]
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
from lib import BaseTest
|
||||||
|
import uuid
|
||||||
|
import os
|
||||||
|
|
||||||
|
try:
|
||||||
|
import swiftclient
|
||||||
|
|
||||||
|
if 'OS_USERNAME' in os.environ and 'OS_PASSWORD' in os.environ:
|
||||||
|
auth_username = os.environ.get('OS_USERNAME')
|
||||||
|
auth_password = os.environ.get('OS_PASSWORD')
|
||||||
|
# Using auth version 2 /v2.0/
|
||||||
|
auth_url = os.environ.get('OS_AUTH_URL')
|
||||||
|
auth_tenant = os.environ.get('OS_TENANT_NAME')
|
||||||
|
|
||||||
|
account_username = "%s:%s" % (auth_tenant, auth_username)
|
||||||
|
swift_conn = swiftclient.Connection(auth_url, account_username,
|
||||||
|
auth_password, auth_version=2)
|
||||||
|
elif 'ST_USER' in os.environ and 'ST_KEY' in os.environ:
|
||||||
|
auth_username = os.environ.get('ST_USER')
|
||||||
|
auth_password = os.environ.get('ST_KEY')
|
||||||
|
auth_url = os.environ.get('ST_AUTH')
|
||||||
|
# Using auth version 1 (/auth/v1.0)
|
||||||
|
swift_conn = swiftclient.Connection(auth_url, auth_username,
|
||||||
|
auth_password, auth_version=1)
|
||||||
|
else:
|
||||||
|
swift_conn = None
|
||||||
|
except ImportError:
|
||||||
|
swift_conn = None
|
||||||
|
|
||||||
|
|
||||||
|
class SwiftTest(BaseTest):
|
||||||
|
"""
|
||||||
|
BaseTest + support for Swift
|
||||||
|
"""
|
||||||
|
|
||||||
|
def fixture_available(self):
|
||||||
|
return super(SwiftTest, self).fixture_available() and swift_conn is not None
|
||||||
|
|
||||||
|
def prepare(self):
|
||||||
|
self.container_name = "aptly-sys-test-" + str(uuid.uuid4())
|
||||||
|
swift_conn.put_container(self.container_name)
|
||||||
|
|
||||||
|
self.configOverride = {"SwiftPublishEndpoints": {
|
||||||
|
"test1": {
|
||||||
|
"container": self.container_name,
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
super(SwiftTest, self).prepare()
|
||||||
|
|
||||||
|
def shutdown(self):
|
||||||
|
if hasattr(self, "container_name"):
|
||||||
|
for obj in swift_conn.get_container(self.container_name,
|
||||||
|
full_listing=True)[1]:
|
||||||
|
swift_conn.delete_object(self.container_name, obj.get("name"))
|
||||||
|
|
||||||
|
swift_conn.delete_container(self.container_name)
|
||||||
|
super(SwiftTest, self).shutdown()
|
||||||
|
|
||||||
|
def check_path(self, path):
|
||||||
|
if not hasattr(self, "container_contents"):
|
||||||
|
self.container_contents = [obj.get('name') for obj in
|
||||||
|
swift_conn.get_container(self.container_name)[1]]
|
||||||
|
|
||||||
|
if path in self.container_contents:
|
||||||
|
return True
|
||||||
|
|
||||||
|
if not path.endswith("/"):
|
||||||
|
path = path + "/"
|
||||||
|
|
||||||
|
for item in self.container_contents:
|
||||||
|
if item.startswith(path):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def check_exists(self, path):
|
||||||
|
if not self.check_path(path):
|
||||||
|
raise Exception("path %s doesn't exist" % (path, ))
|
||||||
|
|
||||||
|
def check_not_exists(self, path):
|
||||||
|
if self.check_path(path):
|
||||||
|
raise Exception("path %s exists" % (path, ))
|
||||||
|
|
||||||
|
def read_file(self, path):
|
||||||
|
hdrs, body = swift_conn.get_object(self.container_name, path)
|
||||||
|
return body
|
||||||
@@ -12,5 +12,6 @@
|
|||||||
"downloadSourcePackages": false,
|
"downloadSourcePackages": false,
|
||||||
"ppaDistributorID": "ubuntu",
|
"ppaDistributorID": "ubuntu",
|
||||||
"ppaCodename": "",
|
"ppaCodename": "",
|
||||||
"S3PublishEndpoints": {}
|
"S3PublishEndpoints": {},
|
||||||
|
"SwiftPublishEndpoints": {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,5 +12,6 @@
|
|||||||
"downloadSourcePackages": false,
|
"downloadSourcePackages": false,
|
||||||
"ppaDistributorID": "ubuntu",
|
"ppaDistributorID": "ubuntu",
|
||||||
"ppaCodename": "",
|
"ppaCodename": "",
|
||||||
"S3PublishEndpoints": {}
|
"S3PublishEndpoints": {},
|
||||||
|
"SwiftPublishEndpoints": {}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
Package: libboost-program-options-dev
|
||||||
|
Version: 1.49.0.1
|
||||||
|
Installed-Size: 26
|
||||||
|
Priority: optional
|
||||||
|
Section: libdevel
|
||||||
|
Maintainer: Debian Boost Team <pkg-boost-devel@lists.alioth.debian.org>
|
||||||
|
Architecture: i386
|
||||||
|
Description: program options library for C++ (default version)
|
||||||
|
This package forms part of the Boost C++ Libraries collection.
|
||||||
|
.
|
||||||
|
Library to let program developers obtain program options, that is
|
||||||
|
(name, value) pairs from the user, via conventional methods such as
|
||||||
|
command line and config file.
|
||||||
|
.
|
||||||
|
This package is a dependency package, which depends on Debian's default
|
||||||
|
Boost version (currently 1.49).
|
||||||
|
MD5sum: 0035d7822b2f8f0ec4013f270fd650c2
|
||||||
|
SHA1: 36895eb64cfe89c33c0a2f7ac2f0c6e0e889e04b
|
||||||
|
SHA256: c76b4bd12fd92e4dfe1b55b18a67a669d92f62985d6a96c8a21d96120982cf12
|
||||||
|
Filename: pool/main/b/boost-defaults/libboost-program-options-dev_1.49.0.1_i386.deb
|
||||||
|
Size: 2738
|
||||||
|
Homepage: http://www.boost.org/libs/program_options/
|
||||||
|
Source: boost-defaults
|
||||||
|
Depends: libboost-program-options1.49-dev
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
Loading packages...
|
||||||
|
Generating metadata files and linking package files...
|
||||||
|
Finalizing metadata files...
|
||||||
|
Signing file 'Release' with gpg, please enter your passphrase when prompted:
|
||||||
|
Clearsigning file 'Release' with gpg, please enter your passphrase when prompted:
|
||||||
|
|
||||||
|
Local repo local-repo has been successfully published.
|
||||||
|
Now you can add following line to apt sources:
|
||||||
|
deb http://your-server/ maverick main
|
||||||
|
deb-src http://your-server/ maverick main
|
||||||
|
Don't forget to add your GPG key to apt with apt-key.
|
||||||
|
|
||||||
|
You can also use `aptly serve` to publish your repositories over HTTP quickly.
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
Origin: . maverick
|
||||||
|
Label: . maverick
|
||||||
|
Codename: maverick
|
||||||
|
Date: Wed, 1 Oct 2014 08:48:48 UTC
|
||||||
|
Architectures: i386
|
||||||
|
Components: main
|
||||||
|
Description: Generated by aptly
|
||||||
|
MD5Sum:
|
||||||
|
b844530d1336e9a3c431f0d36cfc01b0 602 main/binary-i386/Packages.gz
|
||||||
|
1d7829dac8923aafe499f313abfaadd7 652 main/binary-i386/Packages.bz2
|
||||||
|
307b6495eab59c221e2ff8962896631b 2300 main/source/Sources
|
||||||
|
65dd7338cfac70762457b586629e87e4 839 main/source/Sources.gz
|
||||||
|
5cc219da21fdb8a96b265bca1c4c0808 1009 main/source/Sources.bz2
|
||||||
|
60b30b7b0c62ae04bb3bc457abadaced 90 main/binary-i386/Release
|
||||||
|
945211dc923a8d1b97835232648c0aa7 92 main/source/Release
|
||||||
|
d419bd11e2b7fe9669bccdf67a18ca17 984 main/binary-i386/Packages
|
||||||
|
SHA1:
|
||||||
|
1b314cedcf18a6d08d4aabbd8b9b5605ba293d04 602 main/binary-i386/Packages.gz
|
||||||
|
5406a984c100b20fbebacdbac24ae3378885f73b 652 main/binary-i386/Packages.bz2
|
||||||
|
e30d7bc51cd042ee987316967bf3043ab95c8ce9 2300 main/source/Sources
|
||||||
|
d60a7032080848eb48bcf68962698ba642dcc383 839 main/source/Sources.gz
|
||||||
|
fb194b90e0e0efd456a7346c4224294018b6677d 1009 main/source/Sources.bz2
|
||||||
|
2bfef2580deadf6863ee6f893e8b9a2c7522e1ed 90 main/binary-i386/Release
|
||||||
|
8b98a2148d157bf87cc1955ef00ba1ba31275f94 92 main/source/Release
|
||||||
|
be80e1c588c6052f30865e44e3f1429f730d5bc8 984 main/binary-i386/Packages
|
||||||
|
SHA256:
|
||||||
|
a079102fdc72e6228229aaa8e5e6ad59b582026419737e81e11a8af2addd125e 602 main/binary-i386/Packages.gz
|
||||||
|
25d101a333e85d952afc74f684cef3716d69e3c33d8a4b1544faec683c1b5d96 652 main/binary-i386/Packages.bz2
|
||||||
|
bcf1fcf1ca2d1bb5565da8b4c39052d906832ad4885c21682d605b830e55a506 2300 main/source/Sources
|
||||||
|
3e6cf6dc079333cdf01905957c611702f4ee10f654c84895ac7bf166bbbbd3bc 839 main/source/Sources.gz
|
||||||
|
47b9d37fa81d23d227dd26e85821dd4f74db8f17ddefbe6ca686f62ddfedd8ad 1009 main/source/Sources.bz2
|
||||||
|
1d91164164e6310a5e5fc93390995028956f657490a9ce7aa136dc94291828a8 90 main/binary-i386/Release
|
||||||
|
2d75333511325affcefe66c6cfbaa6ab21e6aa0e85a6b4fa39a4191146b81460 92 main/source/Release
|
||||||
|
59643cc2d105694d6876dc328290a1c949b4e91e62ee8db396abac83a7034f9f 984 main/binary-i386/Packages
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
Package: pyspi
|
||||||
|
Version: 0.6.1-1.3
|
||||||
|
Maintainer: Jose Carlos Garcia Sogo <jsogo@debian.org>
|
||||||
|
Architecture: any
|
||||||
|
Binary: python-at-spi
|
||||||
|
Standards-Version: 3.7.3
|
||||||
|
Format: 1.0
|
||||||
|
Files: 22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz
|
||||||
|
b72cb94699298a117b7c82641c68b6fd 1782 pyspi_0.6.1-1.3.dsc
|
||||||
|
def336bd566ea688a06ec03db7ccf1f4 29063 pyspi_0.6.1.orig.tar.gz
|
||||||
|
Checksums-Sha1: 95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz
|
||||||
|
56c8a9b1f4ab636052be8966690998cbe865cd6c 1782 pyspi_0.6.1-1.3.dsc
|
||||||
|
9694b80acc171c0a5bc99f707933864edfce555e 29063 pyspi_0.6.1.orig.tar.gz
|
||||||
|
Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk
|
||||||
|
Homepage: http://people.redhat.com/zcerza/dogtail
|
||||||
|
Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev
|
||||||
|
Directory: pool/main/p/pyspi
|
||||||
|
Checksums-Sha256: 2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz
|
||||||
|
d494aaf526f1ec6b02f14c2f81e060a5722d6532ddc760ec16972e45c2625989 1782 pyspi_0.6.1-1.3.dsc
|
||||||
|
64069ee828c50b1c597d10a3fefbba279f093a4723965388cdd0ac02f029bfb9 29063 pyspi_0.6.1.orig.tar.gz
|
||||||
|
|
||||||
|
Package: pyspi
|
||||||
|
Version: 0.6.1-1.4
|
||||||
|
Maintainer: Jose Carlos Garcia Sogo <jsogo@debian.org>
|
||||||
|
Architecture: any
|
||||||
|
Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk
|
||||||
|
Standards-Version: 3.7.3
|
||||||
|
Homepage: http://people.redhat.com/zcerza/dogtail
|
||||||
|
Directory: pool/main/p/pyspi
|
||||||
|
Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev
|
||||||
|
Checksums-Sha256: 289d3aefa970876e9c43686ce2b02f478d7f3ed35a713928464a98d54ae4fca3 893 pyspi-0.6.1-1.3.stripped.dsc
|
||||||
|
2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz
|
||||||
|
64069ee828c50b1c597d10a3fefbba279f093a4723965388cdd0ac02f029bfb9 29063 pyspi_0.6.1.orig.tar.gz
|
||||||
|
Format: 1.0
|
||||||
|
Checksums-Sha1: 5005fbd1f30637edc1d380b30f45db9b79100d07 893 pyspi-0.6.1-1.3.stripped.dsc
|
||||||
|
95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz
|
||||||
|
9694b80acc171c0a5bc99f707933864edfce555e 29063 pyspi_0.6.1.orig.tar.gz
|
||||||
|
Binary: python-at-spi
|
||||||
|
Files: 2f5bd47cf38852b6fc927a50f98c1448 893 pyspi-0.6.1-1.3.stripped.dsc
|
||||||
|
22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz
|
||||||
|
def336bd566ea688a06ec03db7ccf1f4 29063 pyspi_0.6.1.orig.tar.gz
|
||||||
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
Package: libboost-program-options-dev
|
||||||
|
Version: 1.49.0.1
|
||||||
|
Installed-Size: 26
|
||||||
|
Priority: optional
|
||||||
|
Section: libdevel
|
||||||
|
Maintainer: Debian Boost Team <pkg-boost-devel@lists.alioth.debian.org>
|
||||||
|
Architecture: i386
|
||||||
|
Description: program options library for C++ (default version)
|
||||||
|
This package forms part of the Boost C++ Libraries collection.
|
||||||
|
.
|
||||||
|
Library to let program developers obtain program options, that is
|
||||||
|
(name, value) pairs from the user, via conventional methods such as
|
||||||
|
command line and config file.
|
||||||
|
.
|
||||||
|
This package is a dependency package, which depends on Debian's default
|
||||||
|
Boost version (currently 1.49).
|
||||||
|
MD5sum: 0035d7822b2f8f0ec4013f270fd650c2
|
||||||
|
SHA1: 36895eb64cfe89c33c0a2f7ac2f0c6e0e889e04b
|
||||||
|
SHA256: c76b4bd12fd92e4dfe1b55b18a67a669d92f62985d6a96c8a21d96120982cf12
|
||||||
|
Source: boost-defaults
|
||||||
|
Filename: pool/main/b/boost-defaults/libboost-program-options-dev_1.49.0.1_i386.deb
|
||||||
|
Depends: libboost-program-options1.49-dev
|
||||||
|
Homepage: http://www.boost.org/libs/program_options/
|
||||||
|
Size: 2738
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
Loading packages...
|
||||||
|
Generating metadata files and linking package files...
|
||||||
|
Finalizing metadata files...
|
||||||
|
Signing file 'Release' with gpg, please enter your passphrase when prompted:
|
||||||
|
Clearsigning file 'Release' with gpg, please enter your passphrase when prompted:
|
||||||
|
Cleaning up prefix "." components main...
|
||||||
|
|
||||||
|
Publish for local repo swift:test1:./maverick [i386, source] publishes {main: [local-repo]} has been successfully updated.
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
Origin: . maverick
|
||||||
|
Label: . maverick
|
||||||
|
Codename: maverick
|
||||||
|
Date: Wed, 1 Oct 2014 09:13:14 UTC
|
||||||
|
Architectures: i386
|
||||||
|
Components: main
|
||||||
|
Description: Generated by aptly
|
||||||
|
MD5Sum:
|
||||||
|
d41d8cd98f00b204e9800998ecf8427e 0 main/source/Sources
|
||||||
|
f41c10a4b35cd3e1ec8abb9c2ab676ed 23 main/source/Sources.gz
|
||||||
|
4059d198768f9f8dc9372dc1c54bc3c3 14 main/source/Sources.bz2
|
||||||
|
60b30b7b0c62ae04bb3bc457abadaced 90 main/binary-i386/Release
|
||||||
|
945211dc923a8d1b97835232648c0aa7 92 main/source/Release
|
||||||
|
db76ccafa3c9e4c1dba620259df78f87 984 main/binary-i386/Packages
|
||||||
|
d666eb8b2fc8a0ef525d37aff33c7b2f 603 main/binary-i386/Packages.gz
|
||||||
|
ca2b3a9fc60f4a0a1091b9f0357b11eb 651 main/binary-i386/Packages.bz2
|
||||||
|
SHA1:
|
||||||
|
da39a3ee5e6b4b0d3255bfef95601890afd80709 0 main/source/Sources
|
||||||
|
92c6cff562771f64540523a54baaa0b2afe54b3f 23 main/source/Sources.gz
|
||||||
|
64a543afbb5f4bf728636bdcbbe7a2ed0804adc2 14 main/source/Sources.bz2
|
||||||
|
2bfef2580deadf6863ee6f893e8b9a2c7522e1ed 90 main/binary-i386/Release
|
||||||
|
8b98a2148d157bf87cc1955ef00ba1ba31275f94 92 main/source/Release
|
||||||
|
7dcfa6945771369da0a22c2f90f2300b5d238662 984 main/binary-i386/Packages
|
||||||
|
ba6efb87b17aa8d08476b3f181702e4d3199794e 603 main/binary-i386/Packages.gz
|
||||||
|
0b36a014d1a5ccbf3d73de0035970737659e3c0f 651 main/binary-i386/Packages.bz2
|
||||||
|
SHA256:
|
||||||
|
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 main/source/Sources
|
||||||
|
1775fca35fb6a4d31c541746eaea63c5cb3c00280c8b5a351d4e944cdca7489d 23 main/source/Sources.gz
|
||||||
|
d3dda84eb03b9738d118eb2be78e246106900493c0ae07819ad60815134a8058 14 main/source/Sources.bz2
|
||||||
|
1d91164164e6310a5e5fc93390995028956f657490a9ce7aa136dc94291828a8 90 main/binary-i386/Release
|
||||||
|
2d75333511325affcefe66c6cfbaa6ab21e6aa0e85a6b4fa39a4191146b81460 92 main/source/Release
|
||||||
|
0e2e7586903004efb49dd419be8a98260dab502352c4b1bf6074f658220aef4e 984 main/binary-i386/Packages
|
||||||
|
e2bd1d551b4983253cc26004504ead7b6987e609db8cb7185ab3dde69d346acd 603 main/binary-i386/Packages.gz
|
||||||
|
81bcd3d47fc3e9dbe1e201d7ec1b356dd2ae3bc5c171f76247243a64755c25d6 651 main/binary-i386/Packages.bz2
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
Package: gnuplot-x11
|
||||||
|
Version: 4.6.1-1~maverick2
|
||||||
|
Installed-Size: 1604
|
||||||
|
Priority: optional
|
||||||
|
Section: math
|
||||||
|
Maintainer: Debian Science Team <debian-science-maintainers@lists.alioth.debian.org>
|
||||||
|
Architecture: i386
|
||||||
|
Description: Command-line driven interactive plotting program
|
||||||
|
Gnuplot is a portable command-line driven interactive data and function
|
||||||
|
plotting utility that supports lots of output formats, including drivers
|
||||||
|
for many printers, (La)TeX, (x)fig, Postscript, and so on. The X11-output
|
||||||
|
is packaged in gnuplot-x11.
|
||||||
|
.
|
||||||
|
Data files and self-defined functions can be manipulated by the internal
|
||||||
|
C-like language. Can perform smoothing, spline-fitting, or nonlinear fits,
|
||||||
|
and can work with complex numbers.
|
||||||
|
.
|
||||||
|
This package contains the terminal driver that enables gnuplot to plot
|
||||||
|
images interactively under X11. Most users will want this, it is however
|
||||||
|
packaged separately so that low-end systems don't need X installed to use
|
||||||
|
gnuplot.
|
||||||
|
MD5sum: fcad938905d0ace50a6ce0c73b2c6583
|
||||||
|
SHA1: 02f9a93097a8f798a054e26154dbe5789088c069
|
||||||
|
Replaces: gnuplot (<< 4.0.0)
|
||||||
|
Filename: pool/main/g/gnuplot/gnuplot-x11_4.6.1-1~maverick2_i386.deb
|
||||||
|
Depends: gnuplot-nox (>= 4.6.1-1~maverick2), libc6 (>= 2.11), libcairo2 (>= 1.6.0), libedit2 (>= 2.5.cvs.20010821-1), libgcc1 (>= 1:4.1.1), libgd2-noxpm (>= 2.0.36~rc1~dfsg) | libgd2-xpm (>= 2.0.36~rc1~dfsg), libglib2.0-0 (>= 2.12.0), liblua5.1-0, libpango1.0-0 (>= 1.14.0), libstdc++6 (>= 4.1.1), libwxbase2.8-0 (>= 2.8.11.0), libwxgtk2.8-0 (>= 2.8.11.0), libx11-6
|
||||||
|
Size: 724388
|
||||||
|
Source: gnuplot
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
Loading packages...
|
||||||
|
Generating metadata files and linking package files...
|
||||||
|
Finalizing metadata files...
|
||||||
|
Signing file 'Release' with gpg, please enter your passphrase when prompted:
|
||||||
|
Clearsigning file 'Release' with gpg, please enter your passphrase when prompted:
|
||||||
|
Cleaning up prefix "." components main...
|
||||||
|
|
||||||
|
Publish for snapshot swift:test1:./maverick [amd64, i386] publishes {main: [snap3]: Pulled into 'snap2' with 'snap1' as source, pull request was: 'gnuplot-x11'} has been successfully switched to new snapshot.
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
Origin: . maverick
|
||||||
|
Label: . maverick
|
||||||
|
Codename: maverick
|
||||||
|
Date: Wed, 1 Oct 2014 09:16:49 UTC
|
||||||
|
Architectures: amd64 i386
|
||||||
|
Components: main
|
||||||
|
Description: Generated by aptly
|
||||||
|
MD5Sum:
|
||||||
|
4717e26fc4a8703cd8886feb8ff9532d 91 main/binary-amd64/Release
|
||||||
|
60b30b7b0c62ae04bb3bc457abadaced 90 main/binary-i386/Release
|
||||||
|
2b810443a56c38746aba877b84fc74a1 1526 main/binary-amd64/Packages
|
||||||
|
28bced4c89869001d9fe6b7c553dd1df 862 main/binary-amd64/Packages.gz
|
||||||
|
aaa2ee36bda75a9c66e31881ae128016 931 main/binary-amd64/Packages.bz2
|
||||||
|
aac26f9e4705d03000094f76d475aea2 1524 main/binary-i386/Packages
|
||||||
|
158aec0342fc4ca52178b4512c5ee1b5 862 main/binary-i386/Packages.gz
|
||||||
|
34859d0bf49cb66045de43d01b1de311 939 main/binary-i386/Packages.bz2
|
||||||
|
SHA1:
|
||||||
|
93c9982ebbb6a74a118d07e500b596097c8c4780 91 main/binary-amd64/Release
|
||||||
|
2bfef2580deadf6863ee6f893e8b9a2c7522e1ed 90 main/binary-i386/Release
|
||||||
|
876cafdad8672c4b0b66baec5b12213d2bcb4cf3 1526 main/binary-amd64/Packages
|
||||||
|
b3e2e9ad945a190e2ce4aeb36d1946d9ad04a075 862 main/binary-amd64/Packages.gz
|
||||||
|
bc8a7022261b79f5aeacdca551c51aeb7530b969 931 main/binary-amd64/Packages.bz2
|
||||||
|
7eca65cdb4a4a6bcb51747f2c8d4829f4457f22b 1524 main/binary-i386/Packages
|
||||||
|
e1f5ab02bdd1fcaa0ab93c5680919f612692992c 862 main/binary-i386/Packages.gz
|
||||||
|
8a7f311f39316dcedc8a199421116ba92a941028 939 main/binary-i386/Packages.bz2
|
||||||
|
SHA256:
|
||||||
|
73aa8d6aaf47a1bf3c546869ceb09a882a8c2d840f81878e552fe2d1260ac4e2 91 main/binary-amd64/Release
|
||||||
|
1d91164164e6310a5e5fc93390995028956f657490a9ce7aa136dc94291828a8 90 main/binary-i386/Release
|
||||||
|
f47ca8ea0dc02b4423b1291b302e5594c0ac5c01da72c6f9de1ae17d3eddef2f 1526 main/binary-amd64/Packages
|
||||||
|
0a939f23e1ed98ec3cf2033eb5665d4c40e7494d6331f453ac2043be3e234897 862 main/binary-amd64/Packages.gz
|
||||||
|
abdb8e2537c11272fc9f70ccbcbd2ee867ae797666d3bf11a51972fa2f4d0325 931 main/binary-amd64/Packages.bz2
|
||||||
|
7b1e711ab4647a3e200af742690ffee76bcf7244f597fda699495e29177b1c71 1524 main/binary-i386/Packages
|
||||||
|
5723a156f299c657b2eebd1c17ff1a0ca3f50036fc9a1b6c7d9f985a1841c171 862 main/binary-i386/Packages.gz
|
||||||
|
41f396a3b5c7f78d743971a1011706c6782c8abac3168ff862fa301255baa040 939 main/binary-i386/Packages.bz2
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Published repositories:
|
||||||
|
* swift:test1:./maverick [amd64, i386] publishes {main: [local-repo]}
|
||||||
|
* swift:test1:./xyz [amd64, i386] publishes {main: [local-repo]}
|
||||||
|
* swift:test1:prefix/maverick [amd64, i386] publishes {main: [local-repo]}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Cleaning up prefix "." components main...
|
||||||
|
|
||||||
|
Published repository has been removed successfully.
|
||||||
@@ -9,3 +9,4 @@ from .snapshot import *
|
|||||||
from .switch import *
|
from .switch import *
|
||||||
from .update import *
|
from .update import *
|
||||||
from .s3 import *
|
from .s3 import *
|
||||||
|
from .swift import *
|
||||||
|
|||||||
@@ -0,0 +1,158 @@
|
|||||||
|
from swift_lib import SwiftTest
|
||||||
|
|
||||||
|
|
||||||
|
def strip_processor(output):
|
||||||
|
return "\n".join([l for l in output.split("\n") if not l.startswith(' ') and not l.startswith('Date:')])
|
||||||
|
|
||||||
|
|
||||||
|
class SwiftPublish1Test(SwiftTest):
|
||||||
|
"""
|
||||||
|
publish to Swift: from repo
|
||||||
|
"""
|
||||||
|
fixtureCmds = [
|
||||||
|
"aptly repo create -distribution=maverick local-repo",
|
||||||
|
"aptly repo add local-repo ${files}",
|
||||||
|
]
|
||||||
|
runCmd = "aptly publish repo -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec local-repo swift:test1:"
|
||||||
|
|
||||||
|
def check(self):
|
||||||
|
super(SwiftPublish1Test, self).check()
|
||||||
|
|
||||||
|
self.check_exists('dists/maverick/InRelease')
|
||||||
|
self.check_exists('dists/maverick/Release')
|
||||||
|
self.check_exists('dists/maverick/Release.gpg')
|
||||||
|
|
||||||
|
self.check_exists('dists/maverick/main/binary-i386/Packages')
|
||||||
|
self.check_exists('dists/maverick/main/binary-i386/Packages.gz')
|
||||||
|
self.check_exists('dists/maverick/main/binary-i386/Packages.bz2')
|
||||||
|
self.check_exists('dists/maverick/main/source/Sources')
|
||||||
|
self.check_exists('dists/maverick/main/source/Sources.gz')
|
||||||
|
self.check_exists('dists/maverick/main/source/Sources.bz2')
|
||||||
|
|
||||||
|
self.check_exists('pool/main/p/pyspi/pyspi_0.6.1-1.3.dsc')
|
||||||
|
self.check_exists('pool/main/p/pyspi/pyspi_0.6.1-1.3.diff.gz')
|
||||||
|
self.check_exists('pool/main/p/pyspi/pyspi_0.6.1.orig.tar.gz')
|
||||||
|
self.check_exists('pool/main/p/pyspi/pyspi-0.6.1-1.3.stripped.dsc')
|
||||||
|
self.check_exists('pool/main/b/boost-defaults/libboost-program-options-dev_1.49.0.1_i386.deb')
|
||||||
|
|
||||||
|
# # verify contents except of sums
|
||||||
|
self.check_file_contents('dists/maverick/Release', 'release', match_prepare=strip_processor)
|
||||||
|
self.check_file_contents('dists/maverick/main/source/Sources', 'sources', match_prepare=lambda s: "\n".join(sorted(s.split("\n"))))
|
||||||
|
self.check_file_contents('dists/maverick/main/binary-i386/Packages', 'binary', match_prepare=lambda s: "\n".join(sorted(s.split("\n"))))
|
||||||
|
|
||||||
|
|
||||||
|
class SwiftPublish2Test(SwiftTest):
|
||||||
|
"""
|
||||||
|
publish to Swift: publish update removed some packages
|
||||||
|
"""
|
||||||
|
fixtureCmds = [
|
||||||
|
"aptly repo create -distribution=maverick local-repo",
|
||||||
|
"aptly repo add local-repo ${files}/",
|
||||||
|
"aptly publish repo -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec local-repo swift:test1:",
|
||||||
|
"aptly repo remove local-repo pyspi"
|
||||||
|
]
|
||||||
|
runCmd = "aptly publish update -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec maverick swift:test1:"
|
||||||
|
|
||||||
|
def check(self):
|
||||||
|
super(SwiftPublish2Test, self).check()
|
||||||
|
|
||||||
|
self.check_exists('dists/maverick/InRelease')
|
||||||
|
self.check_exists('dists/maverick/Release')
|
||||||
|
self.check_exists('dists/maverick/Release.gpg')
|
||||||
|
|
||||||
|
self.check_exists('dists/maverick/main/binary-i386/Packages')
|
||||||
|
self.check_exists('dists/maverick/main/binary-i386/Packages.gz')
|
||||||
|
self.check_exists('dists/maverick/main/binary-i386/Packages.bz2')
|
||||||
|
self.check_exists('dists/maverick/main/source/Sources')
|
||||||
|
self.check_exists('dists/maverick/main/source/Sources.gz')
|
||||||
|
self.check_exists('dists/maverick/main/source/Sources.bz2')
|
||||||
|
|
||||||
|
self.check_not_exists('pool/main/p/pyspi/pyspi_0.6.1-1.3.dsc')
|
||||||
|
self.check_not_exists('pool/main/p/pyspi/pyspi_0.6.1-1.3.diff.gz')
|
||||||
|
self.check_not_exists('pool/main/p/pyspi/pyspi_0.6.1.orig.tar.gz')
|
||||||
|
self.check_not_exists('pool/main/p/pyspi/pyspi-0.6.1-1.3.stripped.dsc')
|
||||||
|
self.check_exists('pool/main/b/boost-defaults/libboost-program-options-dev_1.49.0.1_i386.deb')
|
||||||
|
|
||||||
|
# verify contents except of sums
|
||||||
|
self.check_file_contents('dists/maverick/Release', 'release', match_prepare=strip_processor)
|
||||||
|
self.check_file_contents('dists/maverick/main/source/Sources', 'sources', match_prepare=lambda s: "\n".join(sorted(s.split("\n"))))
|
||||||
|
self.check_file_contents('dists/maverick/main/binary-i386/Packages', 'binary', match_prepare=lambda s: "\n".join(sorted(s.split("\n"))))
|
||||||
|
|
||||||
|
|
||||||
|
class SwiftPublish3Test(SwiftTest):
|
||||||
|
"""
|
||||||
|
publish to Swift: publish switch - removed some packages
|
||||||
|
"""
|
||||||
|
fixtureDB = True
|
||||||
|
fixturePool = True
|
||||||
|
fixtureCmds = [
|
||||||
|
"aptly snapshot create snap1 from mirror gnuplot-maverick",
|
||||||
|
"aptly snapshot create snap2 empty",
|
||||||
|
"aptly snapshot pull -no-deps -architectures=i386,amd64 snap2 snap1 snap3 gnuplot-x11",
|
||||||
|
"aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=maverick snap1 swift:test1:",
|
||||||
|
]
|
||||||
|
runCmd = "aptly publish switch -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec maverick swift:test1: snap3"
|
||||||
|
|
||||||
|
def check(self):
|
||||||
|
super(SwiftPublish3Test, self).check()
|
||||||
|
|
||||||
|
self.check_exists('dists/maverick/InRelease')
|
||||||
|
self.check_exists('dists/maverick/Release')
|
||||||
|
self.check_exists('dists/maverick/Release.gpg')
|
||||||
|
|
||||||
|
self.check_exists('dists/maverick/main/binary-i386/Packages.gz')
|
||||||
|
self.check_exists('dists/maverick/main/binary-i386/Packages.bz2')
|
||||||
|
self.check_exists('dists/maverick/main/binary-amd64/Packages')
|
||||||
|
self.check_exists('dists/maverick/main/binary-amd64/Packages.gz')
|
||||||
|
self.check_exists('dists/maverick/main/binary-amd64/Packages.bz2')
|
||||||
|
|
||||||
|
self.check_exists('pool/main/g/gnuplot/gnuplot-x11_4.6.1-1~maverick2_i386.deb')
|
||||||
|
self.check_exists('pool/main/g/gnuplot/gnuplot-x11_4.6.1-1~maverick2_amd64.deb')
|
||||||
|
self.check_not_exists('pool/main/g/gnuplot/gnuplot-nox_4.6.1-1~maverick2_i386.deb')
|
||||||
|
self.check_not_exists('pool/main/g/gnuplot/gnuplot-nox_4.6.1-1~maverick2_amd64.deb')
|
||||||
|
|
||||||
|
# verify contents except of sums
|
||||||
|
self.check_file_contents('dists/maverick/Release', 'release', match_prepare=strip_processor)
|
||||||
|
self.check_file_contents('dists/maverick/main/binary-i386/Packages', 'binary', match_prepare=lambda s: "\n".join(sorted(s.split("\n"))))
|
||||||
|
|
||||||
|
|
||||||
|
class SwiftPublish4Test(SwiftTest):
|
||||||
|
"""
|
||||||
|
publish to Swift: multiple repos, list
|
||||||
|
"""
|
||||||
|
fixtureCmds = [
|
||||||
|
"aptly repo create -distribution=maverick local-repo",
|
||||||
|
"aptly repo add local-repo ${udebs}",
|
||||||
|
"aptly publish repo -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec local-repo swift:test1:",
|
||||||
|
"aptly publish repo -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=xyz local-repo swift:test1:",
|
||||||
|
"aptly publish repo -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec local-repo swift:test1:prefix",
|
||||||
|
]
|
||||||
|
runCmd = "aptly publish list"
|
||||||
|
|
||||||
|
|
||||||
|
class SwiftPublish5Test(SwiftTest):
|
||||||
|
"""
|
||||||
|
publish to Swift: publish drop - component cleanup
|
||||||
|
"""
|
||||||
|
fixtureCmds = [
|
||||||
|
"aptly repo create local1",
|
||||||
|
"aptly repo create local2",
|
||||||
|
"aptly repo add local1 ${files}/libboost-program-options-dev_1.49.0.1_i386.deb",
|
||||||
|
"aptly repo add local2 ${files}",
|
||||||
|
"aptly publish repo -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=sq1 local1 swift:test1:",
|
||||||
|
"aptly publish repo -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=sq2 local2 swift:test1:",
|
||||||
|
]
|
||||||
|
runCmd = "aptly publish drop sq2 swift:test1:"
|
||||||
|
|
||||||
|
def check(self):
|
||||||
|
super(SwiftPublish5Test, self).check()
|
||||||
|
|
||||||
|
self.check_exists('dists/sq1')
|
||||||
|
self.check_not_exists('dists/sq2')
|
||||||
|
self.check_exists('pool/main/')
|
||||||
|
|
||||||
|
self.check_not_exists('pool/main/p/pyspi/pyspi_0.6.1-1.3.dsc')
|
||||||
|
self.check_not_exists('pool/main/p/pyspi/pyspi_0.6.1-1.3.diff.gz')
|
||||||
|
self.check_not_exists('pool/main/p/pyspi/pyspi_0.6.1.orig.tar.gz')
|
||||||
|
self.check_not_exists('pool/main/p/pyspi/pyspi-0.6.1-1.3.stripped.dsc')
|
||||||
|
self.check_exists('pool/main/b/boost-defaults/libboost-program-options-dev_1.49.0.1_i386.deb')
|
||||||
+27
-14
@@ -8,20 +8,21 @@ import (
|
|||||||
|
|
||||||
// ConfigStructure is structure of main configuration
|
// ConfigStructure is structure of main configuration
|
||||||
type ConfigStructure struct {
|
type ConfigStructure struct {
|
||||||
RootDir string `json:"rootDir"`
|
RootDir string `json:"rootDir"`
|
||||||
DownloadConcurrency int `json:"downloadConcurrency"`
|
DownloadConcurrency int `json:"downloadConcurrency"`
|
||||||
DownloadLimit int64 `json:"downloadSpeedLimit"`
|
DownloadLimit int64 `json:"downloadSpeedLimit"`
|
||||||
Architectures []string `json:"architectures"`
|
Architectures []string `json:"architectures"`
|
||||||
DepFollowSuggests bool `json:"dependencyFollowSuggests"`
|
DepFollowSuggests bool `json:"dependencyFollowSuggests"`
|
||||||
DepFollowRecommends bool `json:"dependencyFollowRecommends"`
|
DepFollowRecommends bool `json:"dependencyFollowRecommends"`
|
||||||
DepFollowAllVariants bool `json:"dependencyFollowAllVariants"`
|
DepFollowAllVariants bool `json:"dependencyFollowAllVariants"`
|
||||||
DepFollowSource bool `json:"dependencyFollowSource"`
|
DepFollowSource bool `json:"dependencyFollowSource"`
|
||||||
GpgDisableSign bool `json:"gpgDisableSign"`
|
GpgDisableSign bool `json:"gpgDisableSign"`
|
||||||
GpgDisableVerify bool `json:"gpgDisableVerify"`
|
GpgDisableVerify bool `json:"gpgDisableVerify"`
|
||||||
DownloadSourcePackages bool `json:"downloadSourcePackages"`
|
DownloadSourcePackages bool `json:"downloadSourcePackages"`
|
||||||
PpaDistributorID string `json:"ppaDistributorID"`
|
PpaDistributorID string `json:"ppaDistributorID"`
|
||||||
PpaCodename string `json:"ppaCodename"`
|
PpaCodename string `json:"ppaCodename"`
|
||||||
S3PublishRoots map[string]S3PublishRoot `json:"S3PublishEndpoints"`
|
S3PublishRoots map[string]S3PublishRoot `json:"S3PublishEndpoints"`
|
||||||
|
SwiftPublishRoots map[string]SwiftPublishRoot `json:"SwiftPublishEndpoints"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// S3PublishRoot describes single S3 publishing entry point
|
// S3PublishRoot describes single S3 publishing entry point
|
||||||
@@ -37,6 +38,17 @@ type S3PublishRoot struct {
|
|||||||
PlusWorkaround bool `json:"plusWorkaround"`
|
PlusWorkaround bool `json:"plusWorkaround"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SwiftPublishRoot describes single OpenStack Swift publishing entry point
|
||||||
|
type SwiftPublishRoot struct {
|
||||||
|
UserName string `json:"osname"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
AuthURL string `json:"authurl"`
|
||||||
|
Tenant string `json:"tenant"`
|
||||||
|
TenantID string `json:"tenantid"`
|
||||||
|
Prefix string `json:"prefix"`
|
||||||
|
Container string `json:"container"`
|
||||||
|
}
|
||||||
|
|
||||||
// Config is configuration for aptly, shared by all modules
|
// Config is configuration for aptly, shared by all modules
|
||||||
var Config = ConfigStructure{
|
var Config = ConfigStructure{
|
||||||
RootDir: filepath.Join(os.Getenv("HOME"), ".aptly"),
|
RootDir: filepath.Join(os.Getenv("HOME"), ".aptly"),
|
||||||
@@ -53,6 +65,7 @@ var Config = ConfigStructure{
|
|||||||
PpaDistributorID: "ubuntu",
|
PpaDistributorID: "ubuntu",
|
||||||
PpaCodename: "",
|
PpaCodename: "",
|
||||||
S3PublishRoots: map[string]S3PublishRoot{},
|
S3PublishRoots: map[string]S3PublishRoot{},
|
||||||
|
SwiftPublishRoots: map[string]SwiftPublishRoot{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadConfig loads configuration from json file
|
// LoadConfig loads configuration from json file
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ func (s *ConfigSuite) TestSaveConfig(c *C) {
|
|||||||
Region: "us-east-1",
|
Region: "us-east-1",
|
||||||
Bucket: "repo"}}
|
Bucket: "repo"}}
|
||||||
|
|
||||||
|
s.config.SwiftPublishRoots = map[string]SwiftPublishRoot{"test": SwiftPublishRoot{
|
||||||
|
Container: "repo"}}
|
||||||
|
|
||||||
err := SaveConfig(configname, &s.config)
|
err := SaveConfig(configname, &s.config)
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
@@ -71,6 +74,17 @@ func (s *ConfigSuite) TestSaveConfig(c *C) {
|
|||||||
" \"encryptionMethod\": \"\",\n"+
|
" \"encryptionMethod\": \"\",\n"+
|
||||||
" \"plusWorkaround\": false\n"+
|
" \"plusWorkaround\": false\n"+
|
||||||
" }\n"+
|
" }\n"+
|
||||||
|
" },\n"+
|
||||||
|
" \"SwiftPublishEndpoints\": {\n" +
|
||||||
|
" \"test\": {\n"+
|
||||||
|
" \"osname\": \"\",\n"+
|
||||||
|
" \"password\": \"\",\n"+
|
||||||
|
" \"authurl\": \"\",\n"+
|
||||||
|
" \"tenant\": \"\",\n"+
|
||||||
|
" \"tenantid\": \"\",\n"+
|
||||||
|
" \"prefix\": \"\",\n"+
|
||||||
|
" \"container\": \"repo\"\n"+
|
||||||
|
" }\n"+
|
||||||
" }\n"+
|
" }\n"+
|
||||||
"}")
|
"}")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user