From 25f9c29f001da82ed6b01e810185bf1a7c2164e2 Mon Sep 17 00:00:00 2001 From: Clemens Rabe Date: Fri, 24 Mar 2017 16:34:13 +0100 Subject: [PATCH] Implemented filesystem endpoint with support for hardlinks, symlinks and copy. --- aptly/interfaces.go | 4 +- cmd/publish_snapshot.go | 2 +- cmd/serve.go | 2 +- context/context.go | 9 +- deb/package_test.go | 2 +- deb/publish_test.go | 8 +- files/public.go | 89 ++- files/public_test.go | 92 ++- man/aptly.1 | 40 +- man/aptly.1.ronn.tmpl | 43 +- system/fs_endpoint_lib.py | 48 ++ system/run.py | 3 +- system/t02_config/ConfigShowTest_gold | 1 + system/t02_config/CreateConfigTest_gold | 1 + .../FSEndpointPublishSnapshot10Test_gold | 3 + .../pyspi_0.6.1-1.5.dsc | 12 + .../pyspi_0.6.1.orig.tar.gz | 1 + .../FSEndpointPublishSnapshot11Test_gold | 3 + .../pyspi_0.6.1-1.5.dsc | 12 + .../pyspi_0.6.1.orig.tar.gz | 1 + .../FSEndpointPublishSnapshot12Test_file | 1 + .../FSEndpointPublishSnapshot12Test_gold | 16 + .../pyspi_0.6.1-1.5.dsc | 12 + .../pyspi_0.6.1.orig.tar.gz | 1 + .../FSEndpointPublishSnapshot13Test_gold | 3 + .../pyspi_0.6.1-1.5.dsc | 12 + .../pyspi_0.6.1.orig.tar.gz | 1 + .../FSEndpointPublishSnapshot14Test_file | 1 + .../FSEndpointPublishSnapshot14Test_gold | 16 + .../pyspi_0.6.1-1.5.dsc | 12 + .../pyspi_0.6.1.orig.tar.gz | 1 + .../FSEndpointPublishSnapshot15Test_gold | 3 + .../pyspi_0.6.1-1.5.dsc | 12 + .../pyspi_0.6.1.orig.tar.gz | 1 + .../FSEndpointPublishSnapshot16Test_file | 1 + .../FSEndpointPublishSnapshot16Test_gold | 16 + ...oken-program-options-dev_1.49.0.1_i386.deb | Bin 0 -> 2009 bytes ...oken-program-options-dev_1.49.0.1_i386.deb | Bin 0 -> 2009 bytes .../FSEndpointPublishSnapshot17Test_gold | 3 + ...oken-program-options-dev_1.49.0.1_i386.deb | Bin 0 -> 2009 bytes ...oken-program-options-dev_1.49.0.1_i386.deb | Bin 0 -> 2009 bytes .../FSEndpointPublishSnapshot18Test_gold | 14 + .../FSEndpointPublishSnapshot1Test_gold | 13 + .../FSEndpointPublishSnapshot2Test_gold | 13 + .../FSEndpointPublishSnapshot3Test_gold | 13 + .../FSEndpointPublishSnapshot4Test_gold | 13 + .../FSEndpointPublishSnapshot5Test_gold | 13 + .../FSEndpointPublishSnapshot6Test_gold | 4 + .../FSEndpointPublishSnapshot7Test_gold | 4 + .../FSEndpointPublishSnapshot8Test_gold | 1 + .../FSEndpointPublishSnapshot9Test_gold | 4 + system/t06_publish/__init__.py | 1 + system/t06_publish/fs_endpoint.py | 569 ++++++++++++++++++ utils/checksum.go | 17 + utils/checksum_test.go | 7 + utils/config.go | 43 +- utils/config_test.go | 11 + 57 files changed, 1178 insertions(+), 50 deletions(-) create mode 100644 system/fs_endpoint_lib.py create mode 100644 system/t06_publish/FSEndpointPublishSnapshot10Test_gold create mode 100644 system/t06_publish/FSEndpointPublishSnapshot11Test/pyspi_0.6.1-1.5.dsc create mode 100644 system/t06_publish/FSEndpointPublishSnapshot11Test/pyspi_0.6.1.orig.tar.gz create mode 100644 system/t06_publish/FSEndpointPublishSnapshot11Test_gold create mode 100644 system/t06_publish/FSEndpointPublishSnapshot12Test/pyspi_0.6.1-1.5.dsc create mode 100644 system/t06_publish/FSEndpointPublishSnapshot12Test/pyspi_0.6.1.orig.tar.gz create mode 100644 system/t06_publish/FSEndpointPublishSnapshot12Test_file create mode 100644 system/t06_publish/FSEndpointPublishSnapshot12Test_gold create mode 100644 system/t06_publish/FSEndpointPublishSnapshot13Test/pyspi_0.6.1-1.5.dsc create mode 100644 system/t06_publish/FSEndpointPublishSnapshot13Test/pyspi_0.6.1.orig.tar.gz create mode 100644 system/t06_publish/FSEndpointPublishSnapshot13Test_gold create mode 100644 system/t06_publish/FSEndpointPublishSnapshot14Test/pyspi_0.6.1-1.5.dsc create mode 100644 system/t06_publish/FSEndpointPublishSnapshot14Test/pyspi_0.6.1.orig.tar.gz create mode 100644 system/t06_publish/FSEndpointPublishSnapshot14Test_file create mode 100644 system/t06_publish/FSEndpointPublishSnapshot14Test_gold create mode 100644 system/t06_publish/FSEndpointPublishSnapshot15Test/pyspi_0.6.1-1.5.dsc create mode 100644 system/t06_publish/FSEndpointPublishSnapshot15Test/pyspi_0.6.1.orig.tar.gz create mode 100644 system/t06_publish/FSEndpointPublishSnapshot15Test_gold create mode 100644 system/t06_publish/FSEndpointPublishSnapshot16Test/pyspi_0.6.1-1.5.dsc create mode 100644 system/t06_publish/FSEndpointPublishSnapshot16Test/pyspi_0.6.1.orig.tar.gz create mode 100644 system/t06_publish/FSEndpointPublishSnapshot16Test_file create mode 100644 system/t06_publish/FSEndpointPublishSnapshot16Test_gold create mode 100644 system/t06_publish/FSEndpointPublishSnapshot17Test/1/libboost-broken-program-options-dev_1.49.0.1_i386.deb create mode 100644 system/t06_publish/FSEndpointPublishSnapshot17Test/2/libboost-broken-program-options-dev_1.49.0.1_i386.deb create mode 100644 system/t06_publish/FSEndpointPublishSnapshot17Test_gold create mode 100644 system/t06_publish/FSEndpointPublishSnapshot18Test/1/libboost-broken-program-options-dev_1.49.0.1_i386.deb create mode 100644 system/t06_publish/FSEndpointPublishSnapshot18Test/2/libboost-broken-program-options-dev_1.49.0.1_i386.deb create mode 100644 system/t06_publish/FSEndpointPublishSnapshot18Test_gold create mode 100644 system/t06_publish/FSEndpointPublishSnapshot1Test_gold create mode 100644 system/t06_publish/FSEndpointPublishSnapshot2Test_gold create mode 100644 system/t06_publish/FSEndpointPublishSnapshot3Test_gold create mode 100644 system/t06_publish/FSEndpointPublishSnapshot4Test_gold create mode 100644 system/t06_publish/FSEndpointPublishSnapshot5Test_gold create mode 100644 system/t06_publish/FSEndpointPublishSnapshot6Test_gold create mode 100644 system/t06_publish/FSEndpointPublishSnapshot7Test_gold create mode 100644 system/t06_publish/FSEndpointPublishSnapshot8Test_gold create mode 100644 system/t06_publish/FSEndpointPublishSnapshot9Test_gold create mode 100644 system/t06_publish/fs_endpoint.py diff --git a/aptly/interfaces.go b/aptly/interfaces.go index 2a974efd..9c77c359 100644 --- a/aptly/interfaces.go +++ b/aptly/interfaces.go @@ -42,8 +42,8 @@ type PublishedStorage interface { RenameFile(oldName, newName string) error } -// LocalPublishedStorage is published storage on local filesystem -type LocalPublishedStorage interface { +// FileSystemPublishedStorage is published storage on filesystem +type FileSystemPublishedStorage interface { // PublicPath returns root of public part PublicPath() string } diff --git a/cmd/publish_snapshot.go b/cmd/publish_snapshot.go index 1cd89377..9349811e 100644 --- a/cmd/publish_snapshot.go +++ b/cmd/publish_snapshot.go @@ -163,7 +163,7 @@ func aptlyPublishSnapshotOrRepo(cmd *commander.Command, args []string) error { context.Progress().Printf("\n%s been successfully published.\n", message) - if localStorage, ok := context.GetPublishedStorage(storage).(aptly.LocalPublishedStorage); ok { + if localStorage, ok := context.GetPublishedStorage(storage).(aptly.FileSystemPublishedStorage); ok { context.Progress().Printf("Please setup your webserver to serve directory '%s' with autoindexing.\n", localStorage.PublicPath()) } diff --git a/cmd/serve.go b/cmd/serve.go index 9e371436..18d03d89 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -96,7 +96,7 @@ func aptlyServe(cmd *commander.Command, args []string) error { } } - publicPath := context.GetPublishedStorage("").(aptly.LocalPublishedStorage).PublicPath() + publicPath := context.GetPublishedStorage("").(aptly.FileSystemPublishedStorage).PublicPath() ShutdownContext() fmt.Printf("\nStarting web server at: %s (press Ctrl+C to quit)...\n", listen) diff --git a/context/context.go b/context/context.go index 1ab789df..049e7c4e 100644 --- a/context/context.go +++ b/context/context.go @@ -317,7 +317,14 @@ func (context *AptlyContext) GetPublishedStorage(name string) aptly.PublishedSto publishedStorage, ok := context.publishedStorages[name] if !ok { if name == "" { - publishedStorage = files.NewPublishedStorage(context.config().RootDir) + publishedStorage = files.NewPublishedStorage(filepath.Join(context.config().RootDir, "public"), "hardlink", "") + } else if strings.HasPrefix(name, "filesystem:") { + params, ok := context.config().FileSystemPublishRoots[name[11:]] + if !ok { + Fatal(fmt.Errorf("published local storage %v not configured", name[6:])) + } + + publishedStorage = files.NewPublishedStorage(params.RootDir, params.LinkMethod, params.VerifyMethod) } else if strings.HasPrefix(name, "s3:") { params, ok := context.config().S3PublishRoots[name[3:]] if !ok { diff --git a/deb/package_test.go b/deb/package_test.go index 335956ce..1d999c1d 100644 --- a/deb/package_test.go +++ b/deb/package_test.go @@ -364,7 +364,7 @@ func (s *PackageSuite) TestPoolDirectory(c *C) { func (s *PackageSuite) TestLinkFromPool(c *C) { packagePool := files.NewPackagePool(c.MkDir()) - publishedStorage := files.NewPublishedStorage(c.MkDir()) + publishedStorage := files.NewPublishedStorage(c.MkDir(), "", "") p := NewPackageFromControlFile(s.stanza) poolPath, _ := packagePool.Path(p.Files()[0].Filename, p.Files()[0].Checksums) diff --git a/deb/publish_test.go b/deb/publish_test.go index efed85c6..b526315c 100644 --- a/deb/publish_test.go +++ b/deb/publish_test.go @@ -90,9 +90,9 @@ func (s *PublishedRepoSuite) SetUpTest(c *C) { s.factory = NewCollectionFactory(s.db) s.root = c.MkDir() - s.publishedStorage = files.NewPublishedStorage(s.root) + s.publishedStorage = files.NewPublishedStorage(s.root, "", "") s.root2 = c.MkDir() - s.publishedStorage2 = files.NewPublishedStorage(s.root2) + s.publishedStorage2 = files.NewPublishedStorage(s.root2, "", "") s.provider = &FakeStorageProvider{map[string]aptly.PublishedStorage{ "": s.publishedStorage, "files:other": s.publishedStorage2}} @@ -653,7 +653,7 @@ func (s *PublishedRepoRemoveSuite) SetUpTest(c *C) { s.collection.Add(s.repo5) s.root = c.MkDir() - s.publishedStorage = files.NewPublishedStorage(s.root) + s.publishedStorage = files.NewPublishedStorage(s.root, "", "") s.publishedStorage.MkDir("ppa/dists/anaconda") s.publishedStorage.MkDir("ppa/dists/meduza") s.publishedStorage.MkDir("ppa/dists/osminog") @@ -663,7 +663,7 @@ func (s *PublishedRepoRemoveSuite) SetUpTest(c *C) { s.publishedStorage.MkDir("pool/main") s.root2 = c.MkDir() - s.publishedStorage2 = files.NewPublishedStorage(s.root2) + s.publishedStorage2 = files.NewPublishedStorage(s.root2, "", "") s.publishedStorage2.MkDir("ppa/dists/osminog") s.publishedStorage2.MkDir("ppa/pool/contrib") diff --git a/files/public.go b/files/public.go index ecd4de32..68c83759 100644 --- a/files/public.go +++ b/files/public.go @@ -5,6 +5,7 @@ import ( "io" "os" "path/filepath" + "strings" "syscall" "github.com/smira/aptly/aptly" @@ -13,18 +14,53 @@ import ( // PublishedStorage abstract file system with public dirs (published repos) type PublishedStorage struct { - rootPath string + rootPath string + linkMethod uint + verifyMethod uint } // Check interfaces var ( - _ aptly.PublishedStorage = (*PublishedStorage)(nil) - _ aptly.LocalPublishedStorage = (*PublishedStorage)(nil) + _ aptly.PublishedStorage = (*PublishedStorage)(nil) + _ aptly.FileSystemPublishedStorage = (*PublishedStorage)(nil) +) + +// Constants defining the type of creating links +const ( + LinkMethodHardLink uint = iota + LinkMethodSymLink + LinkMethodCopy +) + +// Constants defining the type of file verification for LinkMethodCopy +const ( + VerificationMethodChecksum uint = iota + VerificationMethodFileSize ) // NewPublishedStorage creates new instance of PublishedStorage which specified root -func NewPublishedStorage(root string) *PublishedStorage { - return &PublishedStorage{rootPath: filepath.Join(root, "public")} +func NewPublishedStorage(root string, linkMethod string, verifyMethod string) *PublishedStorage { + // Ensure linkMethod is one of 'hardlink', 'symlink', 'copy' + var verifiedLinkMethod uint + + if strings.EqualFold(linkMethod, "copy") { + verifiedLinkMethod = LinkMethodCopy + } else if strings.EqualFold(linkMethod, "symlink") { + verifiedLinkMethod = LinkMethodSymLink + } else { + verifiedLinkMethod = LinkMethodHardLink + } + + var verifiedVerifyMethod uint + + if strings.EqualFold(verifyMethod, "size") { + verifiedVerifyMethod = VerificationMethodFileSize + } else { + verifiedVerifyMethod = VerificationMethodChecksum + } + + return &PublishedStorage{rootPath: root, linkMethod: verifiedLinkMethod, + verifyMethod: verifiedVerifyMethod} } // PublicPath returns root of public part @@ -105,12 +141,35 @@ func (storage *PublishedStorage) LinkFromPool(publishedDirectory string, sourceP return err } - srcSys := srcStat.Sys().(*syscall.Stat_t) - dstSys := dstStat.Sys().(*syscall.Stat_t) + if storage.linkMethod == LinkMethodCopy { + if storage.verifyMethod == VerificationMethodFileSize { + // if source and destination have the same size, no need to copy + if srcStat.Size() == dstStat.Size() { + return nil + } + } else { + // if source and destination have the same checksums, no need to copy + dstMD5, err := utils.MD5ChecksumForFile(filepath.Join(poolPath, baseName)) - // source and destination inodes match, no need to link - if srcSys.Ino == dstSys.Ino { - return nil + if err != nil { + return err + } + + if dstMD5 == sourceChecksums.MD5 { + return nil + } + } + } else { + srcSys := srcStat.Sys().(*syscall.Stat_t) + dstSys := dstStat.Sys().(*syscall.Stat_t) + + // if source and destination inodes match, no need to link + + // Symlink can point to different filesystem with identical inodes + // so we have to check the device as well. + if srcSys.Ino == dstSys.Ino && srcSys.Dev == dstSys.Dev { + return nil + } } // source and destination have different inodes, if !forced, this is fatal error @@ -126,7 +185,15 @@ func (storage *PublishedStorage) LinkFromPool(publishedDirectory string, sourceP } // destination doesn't exist (or forced), create link - return os.Link(sourcePath, filepath.Join(poolPath, baseName)) + if storage.linkMethod == LinkMethodCopy { + err = utils.CopyFile(sourcePath, filepath.Join(poolPath, baseName)) + } else if storage.linkMethod == LinkMethodSymLink { + err = os.Symlink(sourcePath, filepath.Join(poolPath, baseName)) + } else { + err = os.Link(sourcePath, filepath.Join(poolPath, baseName)) + } + + return err } // Filelist returns list of files under prefix diff --git a/files/public_test.go b/files/public_test.go index d11a179c..27717b6a 100644 --- a/files/public_test.go +++ b/files/public_test.go @@ -12,19 +12,40 @@ import ( ) type PublishedStorageSuite struct { - root string - storage *PublishedStorage + root string + storage *PublishedStorage + storageSymlink *PublishedStorage + storageCopy *PublishedStorage + storageCopySize *PublishedStorage } var _ = Suite(&PublishedStorageSuite{}) func (s *PublishedStorageSuite) SetUpTest(c *C) { s.root = c.MkDir() - s.storage = NewPublishedStorage(s.root) + s.storage = NewPublishedStorage(filepath.Join(s.root, "public"), "", "") + s.storageSymlink = NewPublishedStorage(filepath.Join(s.root, "public_symlink"), "symlink", "") + s.storageCopy = NewPublishedStorage(filepath.Join(s.root, "public_copy"), "copy", "") + s.storageCopySize = NewPublishedStorage(filepath.Join(s.root, "public_copysize"), "copy", "size") +} + +func (s *PublishedStorageSuite) TestLinkMethodField(c *C) { + c.Assert(s.storage.linkMethod, Equals, LinkMethodHardLink) + c.Assert(s.storageSymlink.linkMethod, Equals, LinkMethodSymLink) + c.Assert(s.storageCopy.linkMethod, Equals, LinkMethodCopy) + c.Assert(s.storageCopySize.linkMethod, Equals, LinkMethodCopy) +} + +func (s *PublishedStorageSuite) TestVerifyMethodField(c *C) { + c.Assert(s.storageCopy.verifyMethod, Equals, VerificationMethodChecksum) + c.Assert(s.storageCopySize.verifyMethod, Equals, VerificationMethodFileSize) } func (s *PublishedStorageSuite) TestPublicPath(c *C) { c.Assert(s.storage.PublicPath(), Equals, filepath.Join(s.root, "public")) + c.Assert(s.storageSymlink.PublicPath(), Equals, filepath.Join(s.root, "public_symlink")) + c.Assert(s.storageCopy.PublicPath(), Equals, filepath.Join(s.root, "public_copy")) + c.Assert(s.storageCopySize.PublicPath(), Equals, filepath.Join(s.root, "public_copysize")) } func (s *PublishedStorageSuite) TestMkDir(c *C) { @@ -35,7 +56,7 @@ func (s *PublishedStorageSuite) TestMkDir(c *C) { c.Assert(err, IsNil) } -func (s *PublishedStorageSuite) TesPutFile(c *C) { +func (s *PublishedStorageSuite) TestPutFile(c *C) { err := s.storage.MkDir("ppa/dists/squeeze/") c.Assert(err, IsNil) @@ -156,7 +177,10 @@ func (s *PublishedStorageSuite) TestLinkFromPool(c *C) { err = ioutil.WriteFile(t.sourcePath, []byte("Contents"), 0644) c.Assert(err, IsNil) - err = s.storage.LinkFromPool(filepath.Join(t.prefix, "pool", t.component, t.poolDirectory), pool, t.sourcePath, utils.ChecksumInfo{}, false) + sourceChecksum, err := utils.ChecksumsForFile(t.sourcePath) + c.Assert(err, IsNil) + + err = s.storage.LinkFromPool(filepath.Join(t.prefix, "pool", t.component, t.poolDirectory), pool, t.sourcePath, sourceChecksum, false) c.Assert(err, IsNil) st, err := os.Stat(filepath.Join(s.storage.rootPath, t.prefix, t.expectedFilename)) @@ -164,6 +188,36 @@ func (s *PublishedStorageSuite) TestLinkFromPool(c *C) { info := st.Sys().(*syscall.Stat_t) c.Check(int(info.Nlink), Equals, 2) + + // Test using symlinks + err = s.storageSymlink.LinkFromPool(filepath.Join(t.prefix, "pool", t.component, t.poolDirectory), pool, t.sourcePath, sourceChecksum, false) + c.Assert(err, IsNil) + + st, err = os.Stat(filepath.Join(s.storageSymlink.rootPath, t.prefix, t.expectedFilename)) + c.Assert(err, IsNil) + + info = st.Sys().(*syscall.Stat_t) + c.Check(int(info.Nlink), Equals, 2) + + // Test using copy with checksum verification + err = s.storageCopy.LinkFromPool(filepath.Join(t.prefix, "pool", t.component, t.poolDirectory), pool, t.sourcePath, sourceChecksum, false) + c.Assert(err, IsNil) + + st, err = os.Stat(filepath.Join(s.storageCopy.rootPath, t.prefix, t.expectedFilename)) + c.Assert(err, IsNil) + + info = st.Sys().(*syscall.Stat_t) + c.Check(int(info.Nlink), Equals, 1) + + // Test using copy with size verification + err = s.storageCopySize.LinkFromPool(filepath.Join(t.prefix, "pool", t.component, t.poolDirectory), pool, t.sourcePath, sourceChecksum, false) + c.Assert(err, IsNil) + + st, err = os.Stat(filepath.Join(s.storageCopySize.rootPath, t.prefix, t.expectedFilename)) + c.Assert(err, IsNil) + + info = st.Sys().(*syscall.Stat_t) + c.Check(int(info.Nlink), Equals, 1) } // test linking files to duplicate final name @@ -171,10 +225,14 @@ func (s *PublishedStorageSuite) TestLinkFromPool(c *C) { err := os.MkdirAll(filepath.Dir(sourcePath), 0755) c.Assert(err, IsNil) - err = ioutil.WriteFile(sourcePath, []byte("Contents"), 0644) + // use same size to ensure copy with size check will fail on this one + err = ioutil.WriteFile(sourcePath, []byte("cONTENTS"), 0644) c.Assert(err, IsNil) - err = s.storage.LinkFromPool(filepath.Join("", "pool", "main", "m/mars-invaders"), pool, sourcePath, utils.ChecksumInfo{}, false) + sourceChecksum, err := utils.ChecksumsForFile(sourcePath) + c.Assert(err, IsNil) + + err = s.storage.LinkFromPool(filepath.Join("", "pool", "main", "m/mars-invaders"), pool, sourcePath, sourceChecksum, false) c.Check(err, ErrorMatches, ".*file already exists and is different") st, err := os.Stat(sourcePath) @@ -184,7 +242,7 @@ func (s *PublishedStorageSuite) TestLinkFromPool(c *C) { c.Check(int(info.Nlink), Equals, 1) // linking with force - err = s.storage.LinkFromPool(filepath.Join("", "pool", "main", "m/mars-invaders"), pool, sourcePath, utils.ChecksumInfo{}, true) + err = s.storage.LinkFromPool(filepath.Join("", "pool", "main", "m/mars-invaders"), pool, sourcePath, sourceChecksum, true) c.Check(err, IsNil) st, err = os.Stat(sourcePath) @@ -192,4 +250,22 @@ func (s *PublishedStorageSuite) TestLinkFromPool(c *C) { info = st.Sys().(*syscall.Stat_t) c.Check(int(info.Nlink), Equals, 2) + + // Test using symlinks + err = s.storageSymlink.LinkFromPool(filepath.Join("", "pool", "main", "m/mars-invaders"), pool, sourcePath, sourceChecksum, false) + c.Check(err, ErrorMatches, ".*file already exists and is different") + + err = s.storageSymlink.LinkFromPool(filepath.Join("", "pool", "main", "m/mars-invaders"), pool, sourcePath, sourceChecksum, true) + c.Check(err, IsNil) + + // Test using copy with checksum verification + err = s.storageCopy.LinkFromPool(filepath.Join("", "pool", "main", "m/mars-invaders"), pool, sourcePath, sourceChecksum, false) + c.Check(err, ErrorMatches, ".*file already exists and is different") + + err = s.storageCopy.LinkFromPool(filepath.Join("", "pool", "main", "m/mars-invaders"), pool, sourcePath, sourceChecksum, true) + c.Check(err, IsNil) + + // Test using copy with size verification (this will NOT detect the difference) + err = s.storageCopySize.LinkFromPool(filepath.Join("", "pool", "main", "m/mars-invaders"), pool, sourcePath, sourceChecksum, false) + c.Check(err, IsNil) } diff --git a/man/aptly.1 b/man/aptly.1 index 68d2a30d..f3778be9 100644 --- a/man/aptly.1 +++ b/man/aptly.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "APTLY" "1" "March 2017" "" "" +.TH "APTLY" "1" "April 2017" "" "" . .SH "NAME" \fBaptly\fR \- Debian repository management tool @@ -50,6 +50,21 @@ Configuration file is stored in JSON format (default values shown below): "ppaDistributorID": "ubuntu", "ppaCodename": "", "skipContentsPublishing": false, + "FileSystemPublishEndpoints": { + "test1": { + "rootDir": "/opt/srv1/aptly_public", + "linkMethod": "symlink" + }, + "test2": { + "rootDir": "/opt/srv2/aptly_public", + "linkMethod": "copy", + "verifyMethod": "md5" + }, + "test3": { + "rootDir": "/opt/srv3/aptly_public", + "linkMethod": "hardlink" + } + }, "S3PublishEndpoints": { "test": { "region": "us\-east\-1", @@ -89,7 +104,7 @@ Options: . .TP \fBrootDir\fR -is root of directory storage to store database (\fBrootDir\fR/db), downloaded packages (\fBrootDir\fR/pool) and published repositories (\fBrootDir\fR/public) +is root of directory storage to store database (\fBrootDir\fR/db), downloaded packages (\fBrootDir\fR/pool) and the default for published repositories (\fBrootDir\fR/public) . .TP \fBdownloadConcurrency\fR @@ -147,6 +162,27 @@ configuration of Amazon S3 publishing endpoints (see below) \fBSwiftPublishEndpoints\fR configuration of OpenStack Swift publishing endpoints (see below) . +.SH "FILESYSTEM PUBLISHING ENDPOINTS" +aptly defaults to publish to a single publish directory under \fBrootDir\fR/public\. For a more advanced publishing strategy, you can define one or more filesystem endpoints in the \fBFileSystemPublishEndpoints\fR list of the aptly configuration file\. Each endpoint has a name and the following associated settings: +. +.TP +\fBrootDir\fR +The publish directory, e\.g\., \fB/opt/srv/aptly_public\fR\. +. +.TP +\fBlinkMethod\fR +This is one of \fBhardlink\fR, \fBsymlink\fR or \fBcopy\fR\. It specifies how aptly links the files from the internal pool to the published directory\. If not specified, empty or wrong, this defaults to \fBhardlink\fR\. +. +.TP +\fBverifyMethod\fR +This is used only when setting the \fBlinkMethod\fR to \fBcopy\fR\. Possible values are \fBmd5\fR and \fBsize\fR\. It specifies how aptly compares existing links from the internal pool to the published directory\. The \fBsize\fR method compares only the file sizes, whereas the \fBmd5\fR method calculates the md5 checksum of the found file and compares it to the desired one\. If not specified, empty or wrong, this defaults to \fBmd5\fR\. +. +.P +In order to publish to such an endpoint, specify the endpoint as \fBfilesystem:endpoint\-name\fR with \fBendpoint\-name\fR as the name given in the aptly configuration file\. For example: +. +.P +\fBaptly publish snapshot wheezy\-main filesystem:test1:wheezy/daily\fR +. .SH "S3 PUBLISHING ENDPOINTS" aptly could be configured to publish repository directly to Amazon S3 (or S3\-compatible cloud storage)\. First, publishing endpoints should be described in aptly configuration file\. Each endpoint has name and associated settings: . diff --git a/man/aptly.1.ronn.tmpl b/man/aptly.1.ronn.tmpl index 0bbd7377..fe12b68e 100644 --- a/man/aptly.1.ronn.tmpl +++ b/man/aptly.1.ronn.tmpl @@ -42,6 +42,21 @@ Configuration file is stored in JSON format (default values shown below): "ppaDistributorID": "ubuntu", "ppaCodename": "", "skipContentsPublishing": false, + "FileSystemPublishEndpoints": { + "test1": { + "rootDir": "/opt/srv1/aptly_public", + "linkMethod": "symlink" + }, + "test2": { + "rootDir": "/opt/srv2/aptly_public", + "linkMethod": "copy", + "verifyMethod": "md5" + }, + "test3": { + "rootDir": "/opt/srv3/aptly_public", + "linkMethod": "hardlink" + } + }, "S3PublishEndpoints": { "test": { "region": "us-east-1", @@ -76,7 +91,7 @@ Options: * `rootDir`: is root of directory storage to store database (`rootDir`/db), downloaded packages (`rootDir`/pool) and - published repositories (`rootDir`/public) + the default for published repositories (`rootDir`/public) * `downloadConcurrency`: is a number of parallel download threads to use when downloading packages @@ -125,6 +140,32 @@ Options: * `SwiftPublishEndpoints`: configuration of OpenStack Swift publishing endpoints (see below) +## FILESYSTEM PUBLISHING ENDPOINTS + +aptly defaults to publish to a single publish directory under `rootDir`/public. For +a more advanced publishing strategy, you can define one or more filesystem endpoints in the +`FileSystemPublishEndpoints` list of the aptly configuration file. Each endpoint has a name +and the following associated settings: + + * `rootDir`: + The publish directory, e.g., `/opt/srv/aptly_public`. + * `linkMethod`: + This is one of `hardlink`, `symlink` or `copy`. It specifies how aptly links the + files from the internal pool to the published directory. + If not specified, empty or wrong, this defaults to `hardlink`. + * `verifyMethod`: + This is used only when setting the `linkMethod` to `copy`. Possible values are + `md5` and `size`. It specifies how aptly compares existing links from the + internal pool to the published directory. The `size` method compares only the + file sizes, whereas the `md5` method calculates the md5 checksum of the found + file and compares it to the desired one. + If not specified, empty or wrong, this defaults to `md5`. + +In order to publish to such an endpoint, specify the endpoint as `filesystem:endpoint-name` +with `endpoint-name` as the name given in the aptly configuration file. For example: + + `aptly publish snapshot wheezy-main filesystem:test1:wheezy/daily` + ## S3 PUBLISHING ENDPOINTS aptly could be configured to publish repository directly to Amazon S3 (or S3-compatible diff --git a/system/fs_endpoint_lib.py b/system/fs_endpoint_lib.py new file mode 100644 index 00000000..53600c87 --- /dev/null +++ b/system/fs_endpoint_lib.py @@ -0,0 +1,48 @@ +import os +from lib import BaseTest + +class FileSystemEndpointTest(BaseTest): + """ + BaseTest + support for filesystem endpoints + """ + + def prepare(self): + self.configOverride = { "FileSystemPublishEndpoints": { + "symlink": { + "rootDir": os.path.join(os.environ["HOME"], ".aptly", "public_symlink"), + "linkMethod": "symlink" + }, + "hardlink": { + "rootDir": os.path.join(os.environ["HOME"], ".aptly", "public_hardlink"), + "linkMethod": "hardlink" + }, + "copy": { + "rootDir": os.path.join(os.environ["HOME"], ".aptly", "public_copy"), + "linkMethod": "copy", + "verifyMethod": "md5" + }, + "copysize": { + "rootDir": os.path.join(os.environ["HOME"], ".aptly", "public_copysize"), + "linkMethod": "copy", + "verifyMethod": "size" + } + }} + super(FileSystemEndpointTest, self).prepare() + + + def check_is_regular(self, path): + if not os.path.isfile(os.path.join(os.environ["HOME"], ".aptly", path)): + raise Exception("path %s is not a regular file" % (path, )) + + def check_is_symlink(self, path): + if not os.path.islink(os.path.join(os.environ["HOME"], ".aptly", path)): + raise Exception("path %s is not a symlink" % (path, )) + + def check_is_hardlink(self, path): + if os.stat(os.path.join(os.environ["HOME"], ".aptly", path)) <= 1: + raise Exception("path %s is not a hardlink" % (path, )) + + def check_is_copy(self, path): + fullpath = os.path.join(os.environ["HOME"], ".aptly", path) + if not ( os.path.isfile(fullpath) and not self.check_is_hardlink(path) ): + raise Exception("path %s is not a copy" % (path, )) diff --git a/system/run.py b/system/run.py index ba80b0d2..b107152b 100755 --- a/system/run.py +++ b/system/run.py @@ -13,6 +13,7 @@ from lib import BaseTest from s3_lib import S3Test from swift_lib import SwiftTest from api_lib import APITest +from fs_endpoint_lib import FileSystemEndpointTest try: from termcolor import colored @@ -39,7 +40,7 @@ def run(include_long_tests=False, capture_results=False, tests=None, filters=Non o = getattr(testModule, name) if not (inspect.isclass(o) and issubclass(o, BaseTest) and o is not BaseTest and - o is not SwiftTest and o is not S3Test and o is not APITest): + o is not SwiftTest and o is not S3Test and o is not APITest and o is not FileSystemEndpointTest): continue newBase = o.__bases__[0] diff --git a/system/t02_config/ConfigShowTest_gold b/system/t02_config/ConfigShowTest_gold index 2f57b119..92558d20 100644 --- a/system/t02_config/ConfigShowTest_gold +++ b/system/t02_config/ConfigShowTest_gold @@ -14,6 +14,7 @@ "ppaDistributorID": "ubuntu", "ppaCodename": "", "skipContentsPublishing": false, + "FileSystemPublishEndpoints": {}, "S3PublishEndpoints": {}, "SwiftPublishEndpoints": {} } diff --git a/system/t02_config/CreateConfigTest_gold b/system/t02_config/CreateConfigTest_gold index 46c4306b..eac6ea97 100644 --- a/system/t02_config/CreateConfigTest_gold +++ b/system/t02_config/CreateConfigTest_gold @@ -14,6 +14,7 @@ "ppaDistributorID": "ubuntu", "ppaCodename": "", "skipContentsPublishing": false, + "FileSystemPublishEndpoints": {}, "S3PublishEndpoints": {}, "SwiftPublishEndpoints": {} } \ No newline at end of file diff --git a/system/t06_publish/FSEndpointPublishSnapshot10Test_gold b/system/t06_publish/FSEndpointPublishSnapshot10Test_gold new file mode 100644 index 00000000..e7cd4619 --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot10Test_gold @@ -0,0 +1,3 @@ +filesystem:copy:. maverick +filesystem:hardlink:. maverick +filesystem:symlink:snap_symlink/daily maverick diff --git a/system/t06_publish/FSEndpointPublishSnapshot11Test/pyspi_0.6.1-1.5.dsc b/system/t06_publish/FSEndpointPublishSnapshot11Test/pyspi_0.6.1-1.5.dsc new file mode 100644 index 00000000..bde66d8c --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot11Test/pyspi_0.6.1-1.5.dsc @@ -0,0 +1,12 @@ +Format: 1.0 +Source: pyspi +Binary: python-at-spi +Architecture: any +Version: 0.6.1-1.5 +Maintainer: Jose Carlos Garcia Sogo +Homepage: http://people.redhat.com/zcerza/dogtail +Standards-Version: 3.7.3 +Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk +Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev +Files: + 68ba00eb6995aeecb19773a27bf81b3d 9 pyspi_0.6.1.orig.tar.gz diff --git a/system/t06_publish/FSEndpointPublishSnapshot11Test/pyspi_0.6.1.orig.tar.gz b/system/t06_publish/FSEndpointPublishSnapshot11Test/pyspi_0.6.1.orig.tar.gz new file mode 100644 index 00000000..dfe437bd --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot11Test/pyspi_0.6.1.orig.tar.gz @@ -0,0 +1 @@ +Contents diff --git a/system/t06_publish/FSEndpointPublishSnapshot11Test_gold b/system/t06_publish/FSEndpointPublishSnapshot11Test_gold new file mode 100644 index 00000000..c4d8e93b --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot11Test_gold @@ -0,0 +1,3 @@ +Loading packages... +Generating metadata files and linking package files... +ERROR: unable to publish: unable to process packages: error linking file to ${HOME}/.aptly/public_symlink/pool/main/p/pyspi/pyspi_0.6.1.orig.tar.gz: file already exists and is different diff --git a/system/t06_publish/FSEndpointPublishSnapshot12Test/pyspi_0.6.1-1.5.dsc b/system/t06_publish/FSEndpointPublishSnapshot12Test/pyspi_0.6.1-1.5.dsc new file mode 100644 index 00000000..bde66d8c --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot12Test/pyspi_0.6.1-1.5.dsc @@ -0,0 +1,12 @@ +Format: 1.0 +Source: pyspi +Binary: python-at-spi +Architecture: any +Version: 0.6.1-1.5 +Maintainer: Jose Carlos Garcia Sogo +Homepage: http://people.redhat.com/zcerza/dogtail +Standards-Version: 3.7.3 +Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk +Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev +Files: + 68ba00eb6995aeecb19773a27bf81b3d 9 pyspi_0.6.1.orig.tar.gz diff --git a/system/t06_publish/FSEndpointPublishSnapshot12Test/pyspi_0.6.1.orig.tar.gz b/system/t06_publish/FSEndpointPublishSnapshot12Test/pyspi_0.6.1.orig.tar.gz new file mode 100644 index 00000000..dfe437bd --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot12Test/pyspi_0.6.1.orig.tar.gz @@ -0,0 +1 @@ +Contents diff --git a/system/t06_publish/FSEndpointPublishSnapshot12Test_file b/system/t06_publish/FSEndpointPublishSnapshot12Test_file new file mode 100644 index 00000000..dfe437bd --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot12Test_file @@ -0,0 +1 @@ +Contents diff --git a/system/t06_publish/FSEndpointPublishSnapshot12Test_gold b/system/t06_publish/FSEndpointPublishSnapshot12Test_gold new file mode 100644 index 00000000..731b4dee --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot12Test_gold @@ -0,0 +1,16 @@ +WARNING: force overwrite mode enabled, aptly might corrupt other published repositories sharing the same package pool. + +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: + +Snapshot snap2 has been successfully published. +Please setup your webserver to serve directory '${HOME}/.aptly/public_symlink' with autoindexing. +Now you can add following line to apt sources: + deb http://your-server/ squeeze main + deb-src http://your-server/ squeeze 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. diff --git a/system/t06_publish/FSEndpointPublishSnapshot13Test/pyspi_0.6.1-1.5.dsc b/system/t06_publish/FSEndpointPublishSnapshot13Test/pyspi_0.6.1-1.5.dsc new file mode 100644 index 00000000..bde66d8c --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot13Test/pyspi_0.6.1-1.5.dsc @@ -0,0 +1,12 @@ +Format: 1.0 +Source: pyspi +Binary: python-at-spi +Architecture: any +Version: 0.6.1-1.5 +Maintainer: Jose Carlos Garcia Sogo +Homepage: http://people.redhat.com/zcerza/dogtail +Standards-Version: 3.7.3 +Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk +Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev +Files: + 68ba00eb6995aeecb19773a27bf81b3d 9 pyspi_0.6.1.orig.tar.gz diff --git a/system/t06_publish/FSEndpointPublishSnapshot13Test/pyspi_0.6.1.orig.tar.gz b/system/t06_publish/FSEndpointPublishSnapshot13Test/pyspi_0.6.1.orig.tar.gz new file mode 100644 index 00000000..dfe437bd --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot13Test/pyspi_0.6.1.orig.tar.gz @@ -0,0 +1 @@ +Contents diff --git a/system/t06_publish/FSEndpointPublishSnapshot13Test_gold b/system/t06_publish/FSEndpointPublishSnapshot13Test_gold new file mode 100644 index 00000000..2dd9ab0f --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot13Test_gold @@ -0,0 +1,3 @@ +Loading packages... +Generating metadata files and linking package files... +ERROR: unable to publish: unable to process packages: error linking file to ${HOME}/.aptly/public_copy/pool/main/p/pyspi/pyspi_0.6.1.orig.tar.gz: file already exists and is different diff --git a/system/t06_publish/FSEndpointPublishSnapshot14Test/pyspi_0.6.1-1.5.dsc b/system/t06_publish/FSEndpointPublishSnapshot14Test/pyspi_0.6.1-1.5.dsc new file mode 100644 index 00000000..bde66d8c --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot14Test/pyspi_0.6.1-1.5.dsc @@ -0,0 +1,12 @@ +Format: 1.0 +Source: pyspi +Binary: python-at-spi +Architecture: any +Version: 0.6.1-1.5 +Maintainer: Jose Carlos Garcia Sogo +Homepage: http://people.redhat.com/zcerza/dogtail +Standards-Version: 3.7.3 +Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk +Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev +Files: + 68ba00eb6995aeecb19773a27bf81b3d 9 pyspi_0.6.1.orig.tar.gz diff --git a/system/t06_publish/FSEndpointPublishSnapshot14Test/pyspi_0.6.1.orig.tar.gz b/system/t06_publish/FSEndpointPublishSnapshot14Test/pyspi_0.6.1.orig.tar.gz new file mode 100644 index 00000000..dfe437bd --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot14Test/pyspi_0.6.1.orig.tar.gz @@ -0,0 +1 @@ +Contents diff --git a/system/t06_publish/FSEndpointPublishSnapshot14Test_file b/system/t06_publish/FSEndpointPublishSnapshot14Test_file new file mode 100644 index 00000000..dfe437bd --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot14Test_file @@ -0,0 +1 @@ +Contents diff --git a/system/t06_publish/FSEndpointPublishSnapshot14Test_gold b/system/t06_publish/FSEndpointPublishSnapshot14Test_gold new file mode 100644 index 00000000..a9aa654c --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot14Test_gold @@ -0,0 +1,16 @@ +WARNING: force overwrite mode enabled, aptly might corrupt other published repositories sharing the same package pool. + +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: + +Snapshot snap2 has been successfully published. +Please setup your webserver to serve directory '${HOME}/.aptly/public_copy' with autoindexing. +Now you can add following line to apt sources: + deb http://your-server/ squeeze main + deb-src http://your-server/ squeeze 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. diff --git a/system/t06_publish/FSEndpointPublishSnapshot15Test/pyspi_0.6.1-1.5.dsc b/system/t06_publish/FSEndpointPublishSnapshot15Test/pyspi_0.6.1-1.5.dsc new file mode 100644 index 00000000..bde66d8c --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot15Test/pyspi_0.6.1-1.5.dsc @@ -0,0 +1,12 @@ +Format: 1.0 +Source: pyspi +Binary: python-at-spi +Architecture: any +Version: 0.6.1-1.5 +Maintainer: Jose Carlos Garcia Sogo +Homepage: http://people.redhat.com/zcerza/dogtail +Standards-Version: 3.7.3 +Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk +Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev +Files: + 68ba00eb6995aeecb19773a27bf81b3d 9 pyspi_0.6.1.orig.tar.gz diff --git a/system/t06_publish/FSEndpointPublishSnapshot15Test/pyspi_0.6.1.orig.tar.gz b/system/t06_publish/FSEndpointPublishSnapshot15Test/pyspi_0.6.1.orig.tar.gz new file mode 100644 index 00000000..dfe437bd --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot15Test/pyspi_0.6.1.orig.tar.gz @@ -0,0 +1 @@ +Contents diff --git a/system/t06_publish/FSEndpointPublishSnapshot15Test_gold b/system/t06_publish/FSEndpointPublishSnapshot15Test_gold new file mode 100644 index 00000000..c2c67869 --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot15Test_gold @@ -0,0 +1,3 @@ +Loading packages... +Generating metadata files and linking package files... +ERROR: unable to publish: unable to process packages: error linking file to ${HOME}/.aptly/public_copysize/pool/main/p/pyspi/pyspi_0.6.1.orig.tar.gz: file already exists and is different diff --git a/system/t06_publish/FSEndpointPublishSnapshot16Test/pyspi_0.6.1-1.5.dsc b/system/t06_publish/FSEndpointPublishSnapshot16Test/pyspi_0.6.1-1.5.dsc new file mode 100644 index 00000000..bde66d8c --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot16Test/pyspi_0.6.1-1.5.dsc @@ -0,0 +1,12 @@ +Format: 1.0 +Source: pyspi +Binary: python-at-spi +Architecture: any +Version: 0.6.1-1.5 +Maintainer: Jose Carlos Garcia Sogo +Homepage: http://people.redhat.com/zcerza/dogtail +Standards-Version: 3.7.3 +Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk +Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev +Files: + 68ba00eb6995aeecb19773a27bf81b3d 9 pyspi_0.6.1.orig.tar.gz diff --git a/system/t06_publish/FSEndpointPublishSnapshot16Test/pyspi_0.6.1.orig.tar.gz b/system/t06_publish/FSEndpointPublishSnapshot16Test/pyspi_0.6.1.orig.tar.gz new file mode 100644 index 00000000..dfe437bd --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot16Test/pyspi_0.6.1.orig.tar.gz @@ -0,0 +1 @@ +Contents diff --git a/system/t06_publish/FSEndpointPublishSnapshot16Test_file b/system/t06_publish/FSEndpointPublishSnapshot16Test_file new file mode 100644 index 00000000..dfe437bd --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot16Test_file @@ -0,0 +1 @@ +Contents diff --git a/system/t06_publish/FSEndpointPublishSnapshot16Test_gold b/system/t06_publish/FSEndpointPublishSnapshot16Test_gold new file mode 100644 index 00000000..446408fb --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot16Test_gold @@ -0,0 +1,16 @@ +WARNING: force overwrite mode enabled, aptly might corrupt other published repositories sharing the same package pool. + +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: + +Snapshot snap2 has been successfully published. +Please setup your webserver to serve directory '${HOME}/.aptly/public_copysize' with autoindexing. +Now you can add following line to apt sources: + deb http://your-server/ squeeze main + deb-src http://your-server/ squeeze 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. diff --git a/system/t06_publish/FSEndpointPublishSnapshot17Test/1/libboost-broken-program-options-dev_1.49.0.1_i386.deb b/system/t06_publish/FSEndpointPublishSnapshot17Test/1/libboost-broken-program-options-dev_1.49.0.1_i386.deb new file mode 100644 index 0000000000000000000000000000000000000000..c30b896133e7a0e49ed340f944741bde4578cf92 GIT binary patch literal 2009 zcmaizdpOgJAIGI9q@w3Ugpd+R7?WJ*p{bBdE_2x|Hij|GWfikdxgC^7qZ856DA!Oq zGa-&kD!DZ*+i0!jI@#nhd{4jU{C>aZ`8~fs&inIvKL33_f4$yEY=ZHqa65T)Xh=jb z?o>zwE*O7RTU#4sW@c*nb4*OMwSV$6e{Yb9$!RcHTl**f&SiO1BNKU43@!m56J?YT zj5oqu`{(=97XSHhSzaqgPU>Hg-nmf7#eOo`-z%DL|IA@F_CP+5yLGBchBEhA=|7)O z?8}eJVHJ|Uq>1af>*p*2n7HKd-YL6dehqE}E~9|I_WJY0ZnEKpo|DTdCOH*ln7gnoX@LwSybv+Ni3Q&`Of&RDTF((FJ&)ci=#XBm zI6{^=>Om*;=yUt-S6?Z(hP)SfIF&Z>n*L51JKZ%UQ>Tlax=8Rc5>76LZq@lR{mVW& zGx}A^U)5h+XG$hRDrW<-`IHu@pnBB0=s{FE5x)5l>nx>v%XtW&%R{KqZsB_myS}XX zVK?KHgaR1|S`hm+6l6(aYkj%cr~AH2alcCKhnZcd-rRjX36s!GUgd3(b(PddM7k}==~FF^YBzjh$@}^HpxH*JnR$T z_sq8bI`u$ZamEYjCYGTv1ypWz9+nJ2=fDttapPvd(WkGBKb@F&y1F*QM2#ZJnwzQztXQ(1Tx3AGVmKHR;o z19Zm1^zVB7kKMjR4<*5&_J;@k@<*STvt*WK$j)JOV}*g?3l(qKn$6Q~lMIoz+K9w& z(f2kxo}hR(K=+%f4%q3g>fz(|x##WF&h8I9BL7={pNDIu3>3Th5Og|CZ4PF3Y@FZ@ zMupwKO-c*EkmAjRuRcg@+67lRT!yd?enj$`nl@NbdCn?W1E>|MtZCB-j zZ#@Ri&IwVkvKfw~7fw&}#Q^e~)?-`ELVo(_{@x8sLa>4QFX4sLUPNzlh=X{n|86AB zxdjk9Y`xlH!K=JcgIq+$Wo}@?!N3I)MJ81Q6_16FyfFAy>5Cm6M%$m50dDe!`tS9r znny6qGHpSm*|rbxRnpy&hJva(1>Ab{)>Q6^zE5Lz%ZY2r&1y~3dpgvcdg{6%Y`f?I zvl&>qDM~?1^k)$u!rIzmdaGspu{P1jE=Cnzv840%K+M-v0+pJG>sfj;-e zkv@~7-EZOo@7B+=Mwgj^$Pdxg`7r%{OqCGDDtzERJK2cxU!HJ8O(-Mb5iO~M2YgoA zs_Vt)l^duqFJN|K`b<7UFvc^9Rz11#hxMlTfvKKb8b~pPSp+jq~HPt^iNqpqFPH z;kk{D<53ld`um4!SgE-B2CFlLqK=hP@~(!l{8$#fuQjXcPqsW{C12#zwy0jG6tclfi*;BiA(~_lMV$~Zlu3UPZMmN_rNR)~#B6z4o zdciI4gq1S6z_*TBC8hVo8bR=L-gre(+lK#SzNi~x`+zQsH&tia1ZuFJtqU6J)q^ zmF^)$X7|Apy!wM<+qTy=h+%_4_5JHSZbn#Ndn?#7IDrxsKGK%iFXQju>ARsiv$*!X zY&(j`^z#k4L&YMRR@cY%!t!#7MEajutAlZpUgrUeXt_}%c-2R5n8yecCV8p5;Lc^k mMPK+4`^w?mo7t3Kuizx5hu=d5@_R*(07rK>Z>XEMm;7I2vGlqC literal 0 HcmV?d00001 diff --git a/system/t06_publish/FSEndpointPublishSnapshot17Test/2/libboost-broken-program-options-dev_1.49.0.1_i386.deb b/system/t06_publish/FSEndpointPublishSnapshot17Test/2/libboost-broken-program-options-dev_1.49.0.1_i386.deb new file mode 100644 index 0000000000000000000000000000000000000000..ec3a934bb1c34c0858758bc4bdb0d7219d054fdf GIT binary patch literal 2009 zcmai#dpOgJAIDvukcysPL~qiZD@fE6}%8J!-)kKnWUNcA?@afl%B`$mGnrj zR!%{dIhsMo4Cr%vimI;UUqjxHJeW$Gcujw&ik?kxgNwUovRp;;_t^Uj|5rE4vAQccCOBphZWo z$38KW>?AlPuibCgrSR^T2JMojYBJ_ICeh6E!u3vQ`q2BQ)aK!-k`Q$|`)!hu8hF?z z!0)+3-F51|+Tx5CGL1O>-Lhaa@15zD{3qg|hLdPRd^j~~{rlqf0WG6+?TQ1VoPkeY zDe3eS4!nS#9ow0V@`4ey2%nz`k7q#~08R3ETRpJ2sSJxq0Je0XRVS$;K)3rzRUvs?5 z^^CKl3mVOPnTn;;$kujIHKXi8DF54=qY5{4|Bp2*uC(@tJ9H^SDJgVtLhyg1{WJIf z)DF-|Ym2|?@jvPIC3>j{4zxeo@0U0F)QTmyEJt<=qnjxW44*B3%hqn5ZkuF?bTvjK zev7`h+3^JB(*gS5)b+qF_tXy_b;>>CsBwC4;336d^ZL9zD&(Np%}1aUX&Q4d%Om3i zPcSO1=r$=W07Htm6u$Z(v2Pb#mhd(iFru6|mtRV~h_!fx zsPd@_)kU0;RuJ7NmUZf>uU;ai0?}K53Lbi2phC#s9`vMnc;<^AI&H0AFD_Fd+}WbrCoSqY+US%^*kzTkw%M%00Z#qvLvk|=ViBB*#QeB_1Ew+dhE@G#ox*bH!!H`IT> zPu(hlVVUUwBF(mafUlD7jnwB?)+*uFqqnAVkM(^Tb6iebOK#R^l-bpx+1OLt4PiS* z4_MB?$}CVyVxm8b01?*I6w_O6;*Ye6Ms_eN@yaEgw+CXrrV^;sL|o6(oB7V9Lid-I z#);jVV~kl1^jiamn1I!6{=1IBl2vW9_PZ%pey^~*=IM@rBVYG!lormRfxhbFZx^l^ z#YFl{j&{F^3%pl1&l+831|mO1SLMMB`!SV56szEY=j>zy%71y{6ly{h36E$=9o*-$ z(pFU`KBHPsgH#UCzRP+Pjv#UVUX`yqq^V?*|;qpJMv|flCJ*e8mm?=LnOTX22 z4y|WHt0p7_leRgJJ!7%yK=CfuAj=dDi&n9Z5C5{~xsSW_@0^6;>{4izlIiXtn9jP| z#CRTrLD^n$te8^Gwcq1%YRWC=zF-g2s@}3vw?_Cx z)xxe_ZR*jnO0ISfOE~TWxLb(t9n2p{Qx?3@22DcM82nfg7<_JSXE)4`&w2nnfwRFK zvxp1Z=r|r#d8ogCsG60EtE;y?Ss?0IDJAcyAIpnn(feAnDi4GQJZSpPPC>wULPD;X zp&_4Hfrd2u{uo8(>>IF8s@JEbcw|kiuFD_av6Gf8^AfAsfbrncYqh$$9zmj1Y$3r* zE%FlF=5AOilM8(7m{n1EPplRMH}S^H3)?pQC-X$z7>5URdAx-t(>_p(^?Y4WU#A(w zY5oEgRIe?nrBb>UO6+V_;481^o(*Bb9@^F$@#mkhdy5~ll0oIo09DzJV`7Vl-OPvP z8?ST^DKoqGALG^SAKP}gu0;$R465s2=W#Q_`r2E;Ho*y$sPK`t%zin4|4!cx^_j)B z?+>@5h)h4&V6Y6`FX=neB4VZtOY^%p$3 nY`EwPKVnZAoO?5y^2-&Rr1ao>s6cVI=rQo;9}dMO#4G+AX)*P> literal 0 HcmV?d00001 diff --git a/system/t06_publish/FSEndpointPublishSnapshot17Test_gold b/system/t06_publish/FSEndpointPublishSnapshot17Test_gold new file mode 100644 index 00000000..55738f7e --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot17Test_gold @@ -0,0 +1,3 @@ +Loading packages... +Generating metadata files and linking package files... +ERROR: unable to publish: unable to process packages: error linking file to ${HOME}/.aptly/public_copy/pool/main/b/boost-defaults/libboost-broken-program-options-dev_1.49.0.1_i386.deb: file already exists and is different diff --git a/system/t06_publish/FSEndpointPublishSnapshot18Test/1/libboost-broken-program-options-dev_1.49.0.1_i386.deb b/system/t06_publish/FSEndpointPublishSnapshot18Test/1/libboost-broken-program-options-dev_1.49.0.1_i386.deb new file mode 100644 index 0000000000000000000000000000000000000000..c30b896133e7a0e49ed340f944741bde4578cf92 GIT binary patch literal 2009 zcmaizdpOgJAIGI9q@w3Ugpd+R7?WJ*p{bBdE_2x|Hij|GWfikdxgC^7qZ856DA!Oq zGa-&kD!DZ*+i0!jI@#nhd{4jU{C>aZ`8~fs&inIvKL33_f4$yEY=ZHqa65T)Xh=jb z?o>zwE*O7RTU#4sW@c*nb4*OMwSV$6e{Yb9$!RcHTl**f&SiO1BNKU43@!m56J?YT zj5oqu`{(=97XSHhSzaqgPU>Hg-nmf7#eOo`-z%DL|IA@F_CP+5yLGBchBEhA=|7)O z?8}eJVHJ|Uq>1af>*p*2n7HKd-YL6dehqE}E~9|I_WJY0ZnEKpo|DTdCOH*ln7gnoX@LwSybv+Ni3Q&`Of&RDTF((FJ&)ci=#XBm zI6{^=>Om*;=yUt-S6?Z(hP)SfIF&Z>n*L51JKZ%UQ>Tlax=8Rc5>76LZq@lR{mVW& zGx}A^U)5h+XG$hRDrW<-`IHu@pnBB0=s{FE5x)5l>nx>v%XtW&%R{KqZsB_myS}XX zVK?KHgaR1|S`hm+6l6(aYkj%cr~AH2alcCKhnZcd-rRjX36s!GUgd3(b(PddM7k}==~FF^YBzjh$@}^HpxH*JnR$T z_sq8bI`u$ZamEYjCYGTv1ypWz9+nJ2=fDttapPvd(WkGBKb@F&y1F*QM2#ZJnwzQztXQ(1Tx3AGVmKHR;o z19Zm1^zVB7kKMjR4<*5&_J;@k@<*STvt*WK$j)JOV}*g?3l(qKn$6Q~lMIoz+K9w& z(f2kxo}hR(K=+%f4%q3g>fz(|x##WF&h8I9BL7={pNDIu3>3Th5Og|CZ4PF3Y@FZ@ zMupwKO-c*EkmAjRuRcg@+67lRT!yd?enj$`nl@NbdCn?W1E>|MtZCB-j zZ#@Ri&IwVkvKfw~7fw&}#Q^e~)?-`ELVo(_{@x8sLa>4QFX4sLUPNzlh=X{n|86AB zxdjk9Y`xlH!K=JcgIq+$Wo}@?!N3I)MJ81Q6_16FyfFAy>5Cm6M%$m50dDe!`tS9r znny6qGHpSm*|rbxRnpy&hJva(1>Ab{)>Q6^zE5Lz%ZY2r&1y~3dpgvcdg{6%Y`f?I zvl&>qDM~?1^k)$u!rIzmdaGspu{P1jE=Cnzv840%K+M-v0+pJG>sfj;-e zkv@~7-EZOo@7B+=Mwgj^$Pdxg`7r%{OqCGDDtzERJK2cxU!HJ8O(-Mb5iO~M2YgoA zs_Vt)l^duqFJN|K`b<7UFvc^9Rz11#hxMlTfvKKb8b~pPSp+jq~HPt^iNqpqFPH z;kk{D<53ld`um4!SgE-B2CFlLqK=hP@~(!l{8$#fuQjXcPqsW{C12#zwy0jG6tclfi*;BiA(~_lMV$~Zlu3UPZMmN_rNR)~#B6z4o zdciI4gq1S6z_*TBC8hVo8bR=L-gre(+lK#SzNi~x`+zQsH&tia1ZuFJtqU6J)q^ zmF^)$X7|Apy!wM<+qTy=h+%_4_5JHSZbn#Ndn?#7IDrxsKGK%iFXQju>ARsiv$*!X zY&(j`^z#k4L&YMRR@cY%!t!#7MEajutAlZpUgrUeXt_}%c-2R5n8yecCV8p5;Lc^k mMPK+4`^w?mo7t3Kuizx5hu=d5@_R*(07rK>Z>XEMm;7I2vGlqC literal 0 HcmV?d00001 diff --git a/system/t06_publish/FSEndpointPublishSnapshot18Test/2/libboost-broken-program-options-dev_1.49.0.1_i386.deb b/system/t06_publish/FSEndpointPublishSnapshot18Test/2/libboost-broken-program-options-dev_1.49.0.1_i386.deb new file mode 100644 index 0000000000000000000000000000000000000000..ec3a934bb1c34c0858758bc4bdb0d7219d054fdf GIT binary patch literal 2009 zcmai#dpOgJAIDvukcysPL~qiZD@fE6}%8J!-)kKnWUNcA?@afl%B`$mGnrj zR!%{dIhsMo4Cr%vimI;UUqjxHJeW$Gcujw&ik?kxgNwUovRp;;_t^Uj|5rE4vAQccCOBphZWo z$38KW>?AlPuibCgrSR^T2JMojYBJ_ICeh6E!u3vQ`q2BQ)aK!-k`Q$|`)!hu8hF?z z!0)+3-F51|+Tx5CGL1O>-Lhaa@15zD{3qg|hLdPRd^j~~{rlqf0WG6+?TQ1VoPkeY zDe3eS4!nS#9ow0V@`4ey2%nz`k7q#~08R3ETRpJ2sSJxq0Je0XRVS$;K)3rzRUvs?5 z^^CKl3mVOPnTn;;$kujIHKXi8DF54=qY5{4|Bp2*uC(@tJ9H^SDJgVtLhyg1{WJIf z)DF-|Ym2|?@jvPIC3>j{4zxeo@0U0F)QTmyEJt<=qnjxW44*B3%hqn5ZkuF?bTvjK zev7`h+3^JB(*gS5)b+qF_tXy_b;>>CsBwC4;336d^ZL9zD&(Np%}1aUX&Q4d%Om3i zPcSO1=r$=W07Htm6u$Z(v2Pb#mhd(iFru6|mtRV~h_!fx zsPd@_)kU0;RuJ7NmUZf>uU;ai0?}K53Lbi2phC#s9`vMnc;<^AI&H0AFD_Fd+}WbrCoSqY+US%^*kzTkw%M%00Z#qvLvk|=ViBB*#QeB_1Ew+dhE@G#ox*bH!!H`IT> zPu(hlVVUUwBF(mafUlD7jnwB?)+*uFqqnAVkM(^Tb6iebOK#R^l-bpx+1OLt4PiS* z4_MB?$}CVyVxm8b01?*I6w_O6;*Ye6Ms_eN@yaEgw+CXrrV^;sL|o6(oB7V9Lid-I z#);jVV~kl1^jiamn1I!6{=1IBl2vW9_PZ%pey^~*=IM@rBVYG!lormRfxhbFZx^l^ z#YFl{j&{F^3%pl1&l+831|mO1SLMMB`!SV56szEY=j>zy%71y{6ly{h36E$=9o*-$ z(pFU`KBHPsgH#UCzRP+Pjv#UVUX`yqq^V?*|;qpJMv|flCJ*e8mm?=LnOTX22 z4y|WHt0p7_leRgJJ!7%yK=CfuAj=dDi&n9Z5C5{~xsSW_@0^6;>{4izlIiXtn9jP| z#CRTrLD^n$te8^Gwcq1%YRWC=zF-g2s@}3vw?_Cx z)xxe_ZR*jnO0ISfOE~TWxLb(t9n2p{Qx?3@22DcM82nfg7<_JSXE)4`&w2nnfwRFK zvxp1Z=r|r#d8ogCsG60EtE;y?Ss?0IDJAcyAIpnn(feAnDi4GQJZSpPPC>wULPD;X zp&_4Hfrd2u{uo8(>>IF8s@JEbcw|kiuFD_av6Gf8^AfAsfbrncYqh$$9zmj1Y$3r* zE%FlF=5AOilM8(7m{n1EPplRMH}S^H3)?pQC-X$z7>5URdAx-t(>_p(^?Y4WU#A(w zY5oEgRIe?nrBb>UO6+V_;481^o(*Bb9@^F$@#mkhdy5~ll0oIo09DzJV`7Vl-OPvP z8?ST^DKoqGALG^SAKP}gu0;$R465s2=W#Q_`r2E;Ho*y$sPK`t%zin4|4!cx^_j)B z?+>@5h)h4&V6Y6`FX=neB4VZtOY^%p$3 nY`EwPKVnZAoO?5y^2-&Rr1ao>s6cVI=rQo;9}dMO#4G+AX)*P> literal 0 HcmV?d00001 diff --git a/system/t06_publish/FSEndpointPublishSnapshot18Test_gold b/system/t06_publish/FSEndpointPublishSnapshot18Test_gold new file mode 100644 index 00000000..57f46ad3 --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot18Test_gold @@ -0,0 +1,14 @@ +Loading packages... +Generating metadata files and linking package files... +[!] Failed to generate package contents: unable to read .tar archive from ${HOME}/.aptly/pool/a5/d5/libboost-broken-program-options-dev_1.49.0.1_i386.deb: unexpected EOF +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: + +Snapshot snap2 has been successfully published. +Please setup your webserver to serve directory '${HOME}/.aptly/public_copysize' with autoindexing. +Now you can add following line to apt sources: + deb http://your-server/ squeeze 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. diff --git a/system/t06_publish/FSEndpointPublishSnapshot1Test_gold b/system/t06_publish/FSEndpointPublishSnapshot1Test_gold new file mode 100644 index 00000000..c66cbee2 --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot1Test_gold @@ -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: + +Snapshot snap1 has been successfully published. +Please setup your webserver to serve directory '${HOME}/.aptly/public_symlink' with autoindexing. +Now you can add following line to apt sources: + deb http://your-server/ maverick main +Don't forget to add your GPG key to apt with apt-key. + +You can also use `aptly serve` to publish your repositories over HTTP quickly. diff --git a/system/t06_publish/FSEndpointPublishSnapshot2Test_gold b/system/t06_publish/FSEndpointPublishSnapshot2Test_gold new file mode 100644 index 00000000..4ae0b662 --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot2Test_gold @@ -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: + +Snapshot snap1 has been successfully published. +Please setup your webserver to serve directory '${HOME}/.aptly/public_hardlink' with autoindexing. +Now you can add following line to apt sources: + deb http://your-server/ maverick main +Don't forget to add your GPG key to apt with apt-key. + +You can also use `aptly serve` to publish your repositories over HTTP quickly. diff --git a/system/t06_publish/FSEndpointPublishSnapshot3Test_gold b/system/t06_publish/FSEndpointPublishSnapshot3Test_gold new file mode 100644 index 00000000..c41e79d6 --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot3Test_gold @@ -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: + +Snapshot snap1 has been successfully published. +Please setup your webserver to serve directory '${HOME}/.aptly/public_copy' with autoindexing. +Now you can add following line to apt sources: + deb http://your-server/ maverick main +Don't forget to add your GPG key to apt with apt-key. + +You can also use `aptly serve` to publish your repositories over HTTP quickly. diff --git a/system/t06_publish/FSEndpointPublishSnapshot4Test_gold b/system/t06_publish/FSEndpointPublishSnapshot4Test_gold new file mode 100644 index 00000000..4ae0b662 --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot4Test_gold @@ -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: + +Snapshot snap1 has been successfully published. +Please setup your webserver to serve directory '${HOME}/.aptly/public_hardlink' with autoindexing. +Now you can add following line to apt sources: + deb http://your-server/ maverick main +Don't forget to add your GPG key to apt with apt-key. + +You can also use `aptly serve` to publish your repositories over HTTP quickly. diff --git a/system/t06_publish/FSEndpointPublishSnapshot5Test_gold b/system/t06_publish/FSEndpointPublishSnapshot5Test_gold new file mode 100644 index 00000000..b20395ec --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot5Test_gold @@ -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: + +Snapshot snap1 has been successfully published. +Please setup your webserver to serve directory '${HOME}/.aptly/public_hardlink' with autoindexing. +Now you can add following line to apt sources: + deb http://your-server/snap_hardlink/daily/ 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. diff --git a/system/t06_publish/FSEndpointPublishSnapshot6Test_gold b/system/t06_publish/FSEndpointPublishSnapshot6Test_gold new file mode 100644 index 00000000..13a68100 --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot6Test_gold @@ -0,0 +1,4 @@ +Removing ${HOME}/.aptly/public_copy/dists... +Removing ${HOME}/.aptly/public_copy/pool... + +Published repository has been removed successfully. diff --git a/system/t06_publish/FSEndpointPublishSnapshot7Test_gold b/system/t06_publish/FSEndpointPublishSnapshot7Test_gold new file mode 100644 index 00000000..798cae88 --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot7Test_gold @@ -0,0 +1,4 @@ +Removing ${HOME}/.aptly/public_hardlink/dists... +Removing ${HOME}/.aptly/public_hardlink/pool... + +Published repository has been removed successfully. diff --git a/system/t06_publish/FSEndpointPublishSnapshot8Test_gold b/system/t06_publish/FSEndpointPublishSnapshot8Test_gold new file mode 100644 index 00000000..837b207b --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot8Test_gold @@ -0,0 +1 @@ +Snapshot `snap1` has been dropped. diff --git a/system/t06_publish/FSEndpointPublishSnapshot9Test_gold b/system/t06_publish/FSEndpointPublishSnapshot9Test_gold new file mode 100644 index 00000000..c974deea --- /dev/null +++ b/system/t06_publish/FSEndpointPublishSnapshot9Test_gold @@ -0,0 +1,4 @@ +Snapshot `snap1` is published currently: + * filesystem:hardlink:./maverick [amd64, i386] publishes {main: [snap1]: Snapshot from mirror [gnuplot-maverick]: http://ppa.launchpad.net/gladky-anton/gnuplot/ubuntu/ maverick} + * filesystem:symlink:./maverick [amd64, i386] publishes {main: [snap1]: Snapshot from mirror [gnuplot-maverick]: http://ppa.launchpad.net/gladky-anton/gnuplot/ubuntu/ maverick} +ERROR: unable to drop: snapshot is published diff --git a/system/t06_publish/__init__.py b/system/t06_publish/__init__.py index 8187f03e..0ee80cf6 100644 --- a/system/t06_publish/__init__.py +++ b/system/t06_publish/__init__.py @@ -2,6 +2,7 @@ Testing publishing snapshots """ +from .fs_endpoint import * from .drop import * from .show import * from .list import * diff --git a/system/t06_publish/fs_endpoint.py b/system/t06_publish/fs_endpoint.py new file mode 100644 index 00000000..34898e5f --- /dev/null +++ b/system/t06_publish/fs_endpoint.py @@ -0,0 +1,569 @@ +from fs_endpoint_lib import FileSystemEndpointTest + + +class FSEndpointPublishSnapshot1Test(FileSystemEndpointTest): + """ + publish snapshot: using symlinks + """ + fixtureDB = True + fixturePool = True + fixtureCmds = [ + "aptly snapshot create snap1 from mirror gnuplot-maverick", + ] + runCmd = "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:symlink:" + gold_processor = FileSystemEndpointTest.expand_environ + + def check(self): + super(FSEndpointPublishSnapshot1Test, self).check() + + self.check_is_regular('public_symlink/dists/maverick/InRelease') + self.check_is_regular('public_symlink/dists/maverick/Release') + self.check_is_regular('public_symlink/dists/maverick/Release.gpg') + + self.check_is_regular('public_symlink/dists/maverick/main/binary-i386/Release') + self.check_is_regular('public_symlink/dists/maverick/main/binary-i386/Packages') + self.check_is_regular('public_symlink/dists/maverick/main/binary-i386/Packages.gz') + self.check_is_regular('public_symlink/dists/maverick/main/binary-i386/Packages.bz2') + self.check_is_regular('public_symlink/dists/maverick/main/Contents-i386.gz') + self.check_is_regular('public_symlink/dists/maverick/main/binary-amd64/Release') + self.check_is_regular('public_symlink/dists/maverick/main/binary-amd64/Packages') + self.check_is_regular('public_symlink/dists/maverick/main/binary-amd64/Packages.gz') + self.check_is_regular('public_symlink/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_is_regular('public_symlink/dists/maverick/main/Contents-amd64.gz') + self.check_not_exists('public_symlink/dists/maverick/main/debian-installer/binary-i386/Packages') + self.check_not_exists('public_symlink/dists/maverick/main/debian-installer/binary-amd64/Packages') + + self.check_is_symlink('public_symlink/pool/main/g/gnuplot/gnuplot-doc_4.6.1-1~maverick2_all.deb') + + +class FSEndpointPublishSnapshot2Test(FileSystemEndpointTest): + """ + publish snapshot: using hardlinks + """ + fixtureDB = True + fixturePool = True + fixtureCmds = [ + "aptly snapshot create snap1 from mirror gnuplot-maverick", + ] + runCmd = "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:hardlink:" + gold_processor = FileSystemEndpointTest.expand_environ + + def check(self): + super(FSEndpointPublishSnapshot2Test, self).check() + + self.check_is_regular('public_hardlink/dists/maverick/InRelease') + self.check_is_regular('public_hardlink/dists/maverick/Release') + self.check_is_regular('public_hardlink/dists/maverick/Release.gpg') + + self.check_is_regular('public_hardlink/dists/maverick/main/binary-i386/Release') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-i386/Packages') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-i386/Packages.gz') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-i386/Packages.bz2') + self.check_is_regular('public_hardlink/dists/maverick/main/Contents-i386.gz') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-amd64/Release') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-amd64/Packages') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-amd64/Packages.gz') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_is_regular('public_hardlink/dists/maverick/main/Contents-amd64.gz') + self.check_not_exists('public_hardlink/dists/maverick/main/debian-installer/binary-i386/Packages') + self.check_not_exists('public_hardlink/dists/maverick/main/debian-installer/binary-amd64/Packages') + + self.check_is_hardlink('public_hardlink/pool/main/g/gnuplot/gnuplot-doc_4.6.1-1~maverick2_all.deb') + + +class FSEndpointPublishSnapshot3Test(FileSystemEndpointTest): + """ + publish snapshot: using copy + """ + fixtureDB = True + fixturePool = True + fixtureCmds = [ + "aptly snapshot create snap1 from mirror gnuplot-maverick", + ] + runCmd = "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:copy:" + gold_processor = FileSystemEndpointTest.expand_environ + + def check(self): + super(FSEndpointPublishSnapshot3Test, self).check() + + self.check_is_regular('public_copy/dists/maverick/InRelease') + self.check_is_regular('public_copy/dists/maverick/Release') + self.check_is_regular('public_copy/dists/maverick/Release.gpg') + + self.check_is_regular('public_copy/dists/maverick/main/binary-i386/Release') + self.check_is_regular('public_copy/dists/maverick/main/binary-i386/Packages') + self.check_is_regular('public_copy/dists/maverick/main/binary-i386/Packages.gz') + self.check_is_regular('public_copy/dists/maverick/main/binary-i386/Packages.bz2') + self.check_is_regular('public_copy/dists/maverick/main/Contents-i386.gz') + self.check_is_regular('public_copy/dists/maverick/main/binary-amd64/Release') + self.check_is_regular('public_copy/dists/maverick/main/binary-amd64/Packages') + self.check_is_regular('public_copy/dists/maverick/main/binary-amd64/Packages.gz') + self.check_is_regular('public_copy/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_is_regular('public_copy/dists/maverick/main/Contents-amd64.gz') + self.check_not_exists('public_copy/dists/maverick/main/debian-installer/binary-i386/Packages') + self.check_not_exists('public_copy/dists/maverick/main/debian-installer/binary-amd64/Packages') + + self.check_is_copy('public_copy/pool/main/g/gnuplot/gnuplot-doc_4.6.1-1~maverick2_all.deb') + + + +class FSEndpointPublishSnapshot4Test(FileSystemEndpointTest): + """ + publish snapshot: using copy, symlink and hardlink variants + """ + fixtureDB = True + fixturePool = True + fixtureCmds = [ + "aptly snapshot create snap1 from mirror gnuplot-maverick", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:copy:", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:symlink:", + ] + runCmd = "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:hardlink:" + gold_processor = FileSystemEndpointTest.expand_environ + + def check(self): + super(FSEndpointPublishSnapshot4Test, self).check() + + self.check_is_regular('public_copy/dists/maverick/InRelease') + self.check_is_regular('public_copy/dists/maverick/Release') + self.check_is_regular('public_copy/dists/maverick/Release.gpg') + + self.check_is_regular('public_copy/dists/maverick/main/binary-i386/Release') + self.check_is_regular('public_copy/dists/maverick/main/binary-i386/Packages') + self.check_is_regular('public_copy/dists/maverick/main/binary-i386/Packages.gz') + self.check_is_regular('public_copy/dists/maverick/main/binary-i386/Packages.bz2') + self.check_is_regular('public_copy/dists/maverick/main/Contents-i386.gz') + self.check_is_regular('public_copy/dists/maverick/main/binary-amd64/Release') + self.check_is_regular('public_copy/dists/maverick/main/binary-amd64/Packages') + self.check_is_regular('public_copy/dists/maverick/main/binary-amd64/Packages.gz') + self.check_is_regular('public_copy/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_is_regular('public_copy/dists/maverick/main/Contents-amd64.gz') + self.check_not_exists('public_copy/dists/maverick/main/debian-installer/binary-i386/Packages') + self.check_not_exists('public_copy/dists/maverick/main/debian-installer/binary-amd64/Packages') + + self.check_is_copy('public_copy/pool/main/g/gnuplot/gnuplot-doc_4.6.1-1~maverick2_all.deb') + + self.check_is_regular('public_symlink/dists/maverick/InRelease') + self.check_is_regular('public_symlink/dists/maverick/Release') + self.check_is_regular('public_symlink/dists/maverick/Release.gpg') + + self.check_is_regular('public_symlink/dists/maverick/main/binary-i386/Release') + self.check_is_regular('public_symlink/dists/maverick/main/binary-i386/Packages') + self.check_is_regular('public_symlink/dists/maverick/main/binary-i386/Packages.gz') + self.check_is_regular('public_symlink/dists/maverick/main/binary-i386/Packages.bz2') + self.check_is_regular('public_symlink/dists/maverick/main/Contents-i386.gz') + self.check_is_regular('public_symlink/dists/maverick/main/binary-amd64/Release') + self.check_is_regular('public_symlink/dists/maverick/main/binary-amd64/Packages') + self.check_is_regular('public_symlink/dists/maverick/main/binary-amd64/Packages.gz') + self.check_is_regular('public_symlink/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_is_regular('public_symlink/dists/maverick/main/Contents-amd64.gz') + self.check_not_exists('public_symlink/dists/maverick/main/debian-installer/binary-i386/Packages') + self.check_not_exists('public_symlink/dists/maverick/main/debian-installer/binary-amd64/Packages') + + self.check_is_symlink('public_symlink/pool/main/g/gnuplot/gnuplot-doc_4.6.1-1~maverick2_all.deb') + + self.check_is_regular('public_hardlink/dists/maverick/InRelease') + self.check_is_regular('public_hardlink/dists/maverick/Release') + self.check_is_regular('public_hardlink/dists/maverick/Release.gpg') + + self.check_is_regular('public_hardlink/dists/maverick/main/binary-i386/Release') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-i386/Packages') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-i386/Packages.gz') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-i386/Packages.bz2') + self.check_is_regular('public_hardlink/dists/maverick/main/Contents-i386.gz') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-amd64/Release') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-amd64/Packages') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-amd64/Packages.gz') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_is_regular('public_hardlink/dists/maverick/main/Contents-amd64.gz') + self.check_not_exists('public_hardlink/dists/maverick/main/debian-installer/binary-i386/Packages') + self.check_not_exists('public_hardlink/dists/maverick/main/debian-installer/binary-amd64/Packages') + + self.check_is_hardlink('public_hardlink/pool/main/g/gnuplot/gnuplot-doc_4.6.1-1~maverick2_all.deb') + + +class FSEndpointPublishSnapshot5Test(FileSystemEndpointTest): + """ + publish snapshot: using copy, symlink and hardlink variants under prefixes + """ + fixtureDB = True + fixturePool = True + fixtureCmds = [ + "aptly snapshot create snap1 from mirror gnuplot-maverick", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:copy:snap_copy/daily", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:symlink:snap_symlink/daily", + ] + runCmd = "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:hardlink:snap_hardlink/daily" + gold_processor = FileSystemEndpointTest.expand_environ + + def check(self): + super(FSEndpointPublishSnapshot5Test, self).check() + + self.check_is_regular('public_copy/snap_copy/daily/dists/maverick/InRelease') + self.check_is_regular('public_copy/snap_copy/daily/dists/maverick/Release') + self.check_is_regular('public_copy/snap_copy/daily/dists/maverick/Release.gpg') + + self.check_is_regular('public_copy/snap_copy/daily/dists/maverick/main/binary-i386/Release') + self.check_is_regular('public_copy/snap_copy/daily/dists/maverick/main/binary-i386/Packages') + self.check_is_regular('public_copy/snap_copy/daily/dists/maverick/main/binary-i386/Packages.gz') + self.check_is_regular('public_copy/snap_copy/daily/dists/maverick/main/binary-i386/Packages.bz2') + self.check_is_regular('public_copy/snap_copy/daily/dists/maverick/main/Contents-i386.gz') + self.check_is_regular('public_copy/snap_copy/daily/dists/maverick/main/binary-amd64/Release') + self.check_is_regular('public_copy/snap_copy/daily/dists/maverick/main/binary-amd64/Packages') + self.check_is_regular('public_copy/snap_copy/daily/dists/maverick/main/binary-amd64/Packages.gz') + self.check_is_regular('public_copy/snap_copy/daily/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_is_regular('public_copy/snap_copy/daily/dists/maverick/main/Contents-amd64.gz') + self.check_not_exists('public_copy/snap_copy/daily/dists/maverick/main/debian-installer/binary-i386/Packages') + self.check_not_exists('public_copy/snap_copy/daily/dists/maverick/main/debian-installer/binary-amd64/Packages') + + self.check_is_copy('public_copy/snap_copy/daily/pool/main/g/gnuplot/gnuplot-doc_4.6.1-1~maverick2_all.deb') + + self.check_is_regular('public_symlink/snap_symlink/daily/dists/maverick/InRelease') + self.check_is_regular('public_symlink/snap_symlink/daily/dists/maverick/Release') + self.check_is_regular('public_symlink/snap_symlink/daily/dists/maverick/Release.gpg') + + self.check_is_regular('public_symlink/snap_symlink/daily/dists/maverick/main/binary-i386/Release') + self.check_is_regular('public_symlink/snap_symlink/daily/dists/maverick/main/binary-i386/Packages') + self.check_is_regular('public_symlink/snap_symlink/daily/dists/maverick/main/binary-i386/Packages.gz') + self.check_is_regular('public_symlink/snap_symlink/daily/dists/maverick/main/binary-i386/Packages.bz2') + self.check_is_regular('public_symlink/snap_symlink/daily/dists/maverick/main/Contents-i386.gz') + self.check_is_regular('public_symlink/snap_symlink/daily/dists/maverick/main/binary-amd64/Release') + self.check_is_regular('public_symlink/snap_symlink/daily/dists/maverick/main/binary-amd64/Packages') + self.check_is_regular('public_symlink/snap_symlink/daily/dists/maverick/main/binary-amd64/Packages.gz') + self.check_is_regular('public_symlink/snap_symlink/daily/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_is_regular('public_symlink/snap_symlink/daily/dists/maverick/main/Contents-amd64.gz') + self.check_not_exists('public_symlink/snap_symlink/daily/dists/maverick/main/debian-installer/binary-i386/Packages') + self.check_not_exists('public_symlink/snap_symlink/daily/dists/maverick/main/debian-installer/binary-amd64/Packages') + + self.check_is_symlink('public_symlink/snap_symlink/daily/pool/main/g/gnuplot/gnuplot-doc_4.6.1-1~maverick2_all.deb') + + self.check_is_regular('public_hardlink/snap_hardlink/daily/dists/maverick/InRelease') + self.check_is_regular('public_hardlink/snap_hardlink/daily/dists/maverick/Release') + self.check_is_regular('public_hardlink/snap_hardlink/daily/dists/maverick/Release.gpg') + + self.check_is_regular('public_hardlink/snap_hardlink/daily/dists/maverick/main/binary-i386/Release') + self.check_is_regular('public_hardlink/snap_hardlink/daily/dists/maverick/main/binary-i386/Packages') + self.check_is_regular('public_hardlink/snap_hardlink/daily/dists/maverick/main/binary-i386/Packages.gz') + self.check_is_regular('public_hardlink/snap_hardlink/daily/dists/maverick/main/binary-i386/Packages.bz2') + self.check_is_regular('public_hardlink/snap_hardlink/daily/dists/maverick/main/Contents-i386.gz') + self.check_is_regular('public_hardlink/snap_hardlink/daily/dists/maverick/main/binary-amd64/Release') + self.check_is_regular('public_hardlink/snap_hardlink/daily/dists/maverick/main/binary-amd64/Packages') + self.check_is_regular('public_hardlink/snap_hardlink/daily/dists/maverick/main/binary-amd64/Packages.gz') + self.check_is_regular('public_hardlink/snap_hardlink/daily/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_is_regular('public_hardlink/snap_hardlink/daily/dists/maverick/main/Contents-amd64.gz') + self.check_not_exists('public_hardlink/snap_hardlink/daily/dists/maverick/main/debian-installer/binary-i386/Packages') + self.check_not_exists('public_hardlink/snap_hardlink/daily/dists/maverick/main/debian-installer/binary-amd64/Packages') + + self.check_is_hardlink('public_hardlink/snap_hardlink/daily/pool/main/g/gnuplot/gnuplot-doc_4.6.1-1~maverick2_all.deb') + + +class FSEndpointPublishSnapshot6Test(FileSystemEndpointTest): + """ + publish snapshot: drop one + """ + fixtureDB = True + fixturePool = True + fixtureCmds = [ + "aptly snapshot create snap1 from mirror gnuplot-maverick", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:copy:", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:symlink:", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:hardlink:" + ] + runCmd = "aptly publish drop maverick filesystem:copy:" + gold_processor = FileSystemEndpointTest.expand_environ + + def check(self): + super(FSEndpointPublishSnapshot6Test, self).check() + + self.check_not_exists('public_copy/dists/') + self.check_not_exists('public_copy/pool/') + + self.check_is_regular('public_symlink/dists/maverick/InRelease') + self.check_is_regular('public_symlink/dists/maverick/Release') + self.check_is_regular('public_symlink/dists/maverick/Release.gpg') + + self.check_is_regular('public_symlink/dists/maverick/main/binary-i386/Release') + self.check_is_regular('public_symlink/dists/maverick/main/binary-i386/Packages') + self.check_is_regular('public_symlink/dists/maverick/main/binary-i386/Packages.gz') + self.check_is_regular('public_symlink/dists/maverick/main/binary-i386/Packages.bz2') + self.check_is_regular('public_symlink/dists/maverick/main/Contents-i386.gz') + self.check_is_regular('public_symlink/dists/maverick/main/binary-amd64/Release') + self.check_is_regular('public_symlink/dists/maverick/main/binary-amd64/Packages') + self.check_is_regular('public_symlink/dists/maverick/main/binary-amd64/Packages.gz') + self.check_is_regular('public_symlink/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_is_regular('public_symlink/dists/maverick/main/Contents-amd64.gz') + self.check_not_exists('public_symlink/dists/maverick/main/debian-installer/binary-i386/Packages') + self.check_not_exists('public_symlink/dists/maverick/main/debian-installer/binary-amd64/Packages') + + self.check_is_symlink('public_symlink/pool/main/g/gnuplot/gnuplot-doc_4.6.1-1~maverick2_all.deb') + + self.check_is_regular('public_hardlink/dists/maverick/InRelease') + self.check_is_regular('public_hardlink/dists/maverick/Release') + self.check_is_regular('public_hardlink/dists/maverick/Release.gpg') + + self.check_is_regular('public_hardlink/dists/maverick/main/binary-i386/Release') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-i386/Packages') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-i386/Packages.gz') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-i386/Packages.bz2') + self.check_is_regular('public_hardlink/dists/maverick/main/Contents-i386.gz') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-amd64/Release') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-amd64/Packages') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-amd64/Packages.gz') + self.check_is_regular('public_hardlink/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_is_regular('public_hardlink/dists/maverick/main/Contents-amd64.gz') + self.check_not_exists('public_hardlink/dists/maverick/main/debian-installer/binary-i386/Packages') + self.check_not_exists('public_hardlink/dists/maverick/main/debian-installer/binary-amd64/Packages') + + self.check_is_hardlink('public_hardlink/pool/main/g/gnuplot/gnuplot-doc_4.6.1-1~maverick2_all.deb') + + +class FSEndpointPublishSnapshot7Test(FileSystemEndpointTest): + """ + publish snapshot: drop two + """ + fixtureDB = True + fixturePool = True + fixtureCmds = [ + "aptly snapshot create snap1 from mirror gnuplot-maverick", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:copy:", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:symlink:", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:hardlink:", + "aptly publish drop maverick filesystem:copy:" + ] + runCmd = "aptly publish drop maverick filesystem:hardlink:" + gold_processor = FileSystemEndpointTest.expand_environ + + def check(self): + super(FSEndpointPublishSnapshot7Test, self).check() + + self.check_not_exists('public_copy/dists/') + self.check_not_exists('public_copy/pool/') + + self.check_is_regular('public_symlink/dists/maverick/InRelease') + self.check_is_regular('public_symlink/dists/maverick/Release') + self.check_is_regular('public_symlink/dists/maverick/Release.gpg') + + self.check_is_regular('public_symlink/dists/maverick/main/binary-i386/Release') + self.check_is_regular('public_symlink/dists/maverick/main/binary-i386/Packages') + self.check_is_regular('public_symlink/dists/maverick/main/binary-i386/Packages.gz') + self.check_is_regular('public_symlink/dists/maverick/main/binary-i386/Packages.bz2') + self.check_is_regular('public_symlink/dists/maverick/main/Contents-i386.gz') + self.check_is_regular('public_symlink/dists/maverick/main/binary-amd64/Release') + self.check_is_regular('public_symlink/dists/maverick/main/binary-amd64/Packages') + self.check_is_regular('public_symlink/dists/maverick/main/binary-amd64/Packages.gz') + self.check_is_regular('public_symlink/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_is_regular('public_symlink/dists/maverick/main/Contents-amd64.gz') + self.check_not_exists('public_symlink/dists/maverick/main/debian-installer/binary-i386/Packages') + self.check_not_exists('public_symlink/dists/maverick/main/debian-installer/binary-amd64/Packages') + + self.check_is_symlink('public_symlink/pool/main/g/gnuplot/gnuplot-doc_4.6.1-1~maverick2_all.deb') + + self.check_not_exists('public_hardlink/dists/') + self.check_not_exists('public_hardlink/pool/') + + +class FSEndpointPublishSnapshot8Test(FileSystemEndpointTest): + """ + publish snapshot: remove snapshot + """ + fixtureDB = True + fixturePool = True + fixtureCmds = [ + "aptly snapshot create snap1 from mirror gnuplot-maverick", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:copy:", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:symlink:", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:hardlink:", + "aptly publish drop maverick filesystem:copy:", + "aptly publish drop maverick filesystem:symlink:", + "aptly publish drop maverick filesystem:hardlink:", + ] + runCmd = "aptly snapshot drop snap1" + gold_processor = FileSystemEndpointTest.expand_environ + + +class FSEndpointPublishSnapshot9Test(FileSystemEndpointTest): + """ + publish snapshot: remove snapshot error + """ + fixtureDB = True + fixturePool = True + fixtureCmds = [ + "aptly snapshot create snap1 from mirror gnuplot-maverick", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:copy:", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:symlink:", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:hardlink:", + "aptly publish drop maverick filesystem:copy:", + ] + runCmd = "aptly snapshot drop snap1" + expectedCode = 1 + + +class FSEndpointPublishSnapshot10Test(FileSystemEndpointTest): + """ + publish list: several repos list + """ + fixtureDB = True + fixturePool = True + fixtureCmds = [ + "aptly snapshot create snap1 from mirror gnuplot-maverick", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:copy:", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:symlink:snap_symlink/daily", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec snap1 filesystem:hardlink:" + ] + runCmd = "aptly publish list -raw" + + +class FSEndpointPublishSnapshot11Test(FileSystemEndpointTest): + """ + publish snapshot: conflicting files in the snapshot using symlink method + """ + fixtureCmds = [ + "aptly repo create local-repo1", + "aptly repo add local-repo1 ${files}", + "aptly snapshot create snap1 from repo local-repo1", + "aptly repo create local-repo2", + "aptly repo add local-repo2 ${testfiles}", + "aptly snapshot create snap2 from repo local-repo2", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=maverick snap1 filesystem:symlink:" + ] + runCmd = "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=squeeze snap2 filesystem:symlink:" + expectedCode = 1 + gold_processor = FileSystemEndpointTest.expand_environ + + +class FSEndpointPublishSnapshot12Test(FileSystemEndpointTest): + """ + publish snapshot: conflicting files in the snapshot using symlink method. -force-overwrite + """ + fixtureCmds = [ + "aptly repo create local-repo1", + "aptly repo add local-repo1 ${files}", + "aptly snapshot create snap1 from repo local-repo1", + "aptly repo create local-repo2", + "aptly repo add local-repo2 ${testfiles}", + "aptly snapshot create snap2 from repo local-repo2", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=maverick snap1 filesystem:symlink:" + ] + runCmd = "aptly publish snapshot -force-overwrite -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=squeeze snap2 filesystem:symlink:" + gold_processor = FileSystemEndpointTest.expand_environ + + def check(self): + super(FSEndpointPublishSnapshot12Test, self).check() + + self.check_file_contents("public_symlink/pool/main/p/pyspi/pyspi_0.6.1.orig.tar.gz", "file") + + +class FSEndpointPublishSnapshot13Test(FileSystemEndpointTest): + """ + publish snapshot: conflicting files in the snapshot using copy method with md5 verification + """ + fixtureCmds = [ + "aptly repo create local-repo1", + "aptly repo add local-repo1 ${files}", + "aptly snapshot create snap1 from repo local-repo1", + "aptly repo create local-repo2", + "aptly repo add local-repo2 ${testfiles}", + "aptly snapshot create snap2 from repo local-repo2", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=maverick snap1 filesystem:copy:" + ] + runCmd = "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=squeeze snap2 filesystem:copy:" + expectedCode = 1 + gold_processor = FileSystemEndpointTest.expand_environ + + +class FSEndpointPublishSnapshot14Test(FileSystemEndpointTest): + """ + publish snapshot: conflicting files in the snapshot using copy method with md5 verification. -force-overwrite + """ + fixtureCmds = [ + "aptly repo create local-repo1", + "aptly repo add local-repo1 ${files}", + "aptly snapshot create snap1 from repo local-repo1", + "aptly repo create local-repo2", + "aptly repo add local-repo2 ${testfiles}", + "aptly snapshot create snap2 from repo local-repo2", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=maverick snap1 filesystem:copy:" + ] + runCmd = "aptly publish snapshot -force-overwrite -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=squeeze snap2 filesystem:copy:" + gold_processor = FileSystemEndpointTest.expand_environ + + def check(self): + super(FSEndpointPublishSnapshot14Test, self).check() + + self.check_file_contents("public_copy/pool/main/p/pyspi/pyspi_0.6.1.orig.tar.gz", "file") + + +class FSEndpointPublishSnapshot15Test(FileSystemEndpointTest): + """ + publish snapshot: conflicting files in the snapshot using copy method with size verification + """ + fixtureCmds = [ + "aptly repo create local-repo1", + "aptly repo add local-repo1 ${files}", + "aptly snapshot create snap1 from repo local-repo1", + "aptly repo create local-repo2", + "aptly repo add local-repo2 ${testfiles}", + "aptly snapshot create snap2 from repo local-repo2", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=maverick snap1 filesystem:copysize:" + ] + runCmd = "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=squeeze snap2 filesystem:copysize:" + expectedCode = 1 + gold_processor = FileSystemEndpointTest.expand_environ + + +class FSEndpointPublishSnapshot16Test(FileSystemEndpointTest): + """ + publish snapshot: conflicting files in the snapshot using copy method with size verification. -force-overwrite + """ + fixtureCmds = [ + "aptly repo create local-repo1", + "aptly repo add local-repo1 ${files}", + "aptly snapshot create snap1 from repo local-repo1", + "aptly repo create local-repo2", + "aptly repo add local-repo2 ${testfiles}", + "aptly snapshot create snap2 from repo local-repo2", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=maverick snap1 filesystem:copysize:" + ] + runCmd = "aptly publish snapshot -force-overwrite -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=squeeze snap2 filesystem:copysize:" + gold_processor = FileSystemEndpointTest.expand_environ + + def check(self): + super(FSEndpointPublishSnapshot16Test, self).check() + + self.check_file_contents("public_copysize/pool/main/p/pyspi/pyspi_0.6.1.orig.tar.gz", "file") + + +class FSEndpointPublishSnapshot17Test(FileSystemEndpointTest): + """ + publish snapshot: conflicting files in the snapshot using copy method with md5 verification + """ + fixtureCmds = [ + "aptly repo create local-repo1", + "aptly repo add local-repo1 ${testfiles}/1", + "aptly snapshot create snap1 from repo local-repo1", + "aptly repo create local-repo2", + "aptly repo add local-repo2 ${testfiles}/2", + "aptly snapshot create snap2 from repo local-repo2", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=maverick snap1 filesystem:copy:" + ] + runCmd = "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=squeeze snap2 filesystem:copy:" + expectedCode = 1 + gold_processor = FileSystemEndpointTest.expand_environ + + +class FSEndpointPublishSnapshot18Test(FileSystemEndpointTest): + """ + publish snapshot: conflicting files in the snapshot using copy method with size verification (not detected!) + """ + fixtureCmds = [ + "aptly repo create local-repo1", + "aptly repo add local-repo1 ${testfiles}/1", + "aptly snapshot create snap1 from repo local-repo1", + "aptly repo create local-repo2", + "aptly repo add local-repo2 ${testfiles}/2", + "aptly snapshot create snap2 from repo local-repo2", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=maverick snap1 filesystem:copysize:" + ] + runCmd = "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=squeeze snap2 filesystem:copysize:" + gold_processor = FileSystemEndpointTest.expand_environ + diff --git a/utils/checksum.go b/utils/checksum.go index 41a304e5..38747779 100644 --- a/utils/checksum.go +++ b/utils/checksum.go @@ -11,6 +11,23 @@ import ( "os" ) +// MD5ChecksumForFile computes just the MD5 hash and not all the others +func MD5ChecksumForFile(path string) (string, error) { + file, err := os.Open(path) + if err != nil { + return "", err + } + defer file.Close() + + hash := md5.New() + _, err = io.Copy(hash, file) + if err != nil { + return "", err + } + + return fmt.Sprintf("%x", hash.Sum(nil)), nil +} + // ChecksumInfo represents checksums for a single file type ChecksumInfo struct { Size int64 diff --git a/utils/checksum_test.go b/utils/checksum_test.go index b2ff1eca..a29d602f 100644 --- a/utils/checksum_test.go +++ b/utils/checksum_test.go @@ -31,3 +31,10 @@ func (s *ChecksumSuite) TestChecksumsForFile(c *C) { c.Check(info.SHA1, Equals, "1743f8408261b4f1eff88e0fca15a7077223fa79") c.Check(info.SHA256, Equals, "f2775692fd3b70bd0faa4054b7afa92d427bf994cd8629741710c4864ee4dc95") } + +func (s *ChecksumSuite) TestMD5ChecksumForFile(c *C) { + md5sum, err := MD5ChecksumForFile(s.tempfile.Name()) + + c.Assert(err, IsNil) + c.Check(md5sum, Equals, "43470766afbfdca292440eecdceb80fb") +} diff --git a/utils/config.go b/utils/config.go index 5afa99c4..6a50ecd6 100644 --- a/utils/config.go +++ b/utils/config.go @@ -8,23 +8,31 @@ import ( // ConfigStructure is structure of main configuration type ConfigStructure struct { - RootDir string `json:"rootDir"` - DownloadConcurrency int `json:"downloadConcurrency"` - DownloadLimit int64 `json:"downloadSpeedLimit"` - Architectures []string `json:"architectures"` - DepFollowSuggests bool `json:"dependencyFollowSuggests"` - DepFollowRecommends bool `json:"dependencyFollowRecommends"` - DepFollowAllVariants bool `json:"dependencyFollowAllVariants"` - DepFollowSource bool `json:"dependencyFollowSource"` - DepVerboseResolve bool `json:"dependencyVerboseResolve"` - GpgDisableSign bool `json:"gpgDisableSign"` - GpgDisableVerify bool `json:"gpgDisableVerify"` - DownloadSourcePackages bool `json:"downloadSourcePackages"` - PpaDistributorID string `json:"ppaDistributorID"` - PpaCodename string `json:"ppaCodename"` - SkipContentsPublishing bool `json:"skipContentsPublishing"` - S3PublishRoots map[string]S3PublishRoot `json:"S3PublishEndpoints"` - SwiftPublishRoots map[string]SwiftPublishRoot `json:"SwiftPublishEndpoints"` + RootDir string `json:"rootDir"` + DownloadConcurrency int `json:"downloadConcurrency"` + DownloadLimit int64 `json:"downloadSpeedLimit"` + Architectures []string `json:"architectures"` + DepFollowSuggests bool `json:"dependencyFollowSuggests"` + DepFollowRecommends bool `json:"dependencyFollowRecommends"` + DepFollowAllVariants bool `json:"dependencyFollowAllVariants"` + DepFollowSource bool `json:"dependencyFollowSource"` + DepVerboseResolve bool `json:"dependencyVerboseResolve"` + GpgDisableSign bool `json:"gpgDisableSign"` + GpgDisableVerify bool `json:"gpgDisableVerify"` + DownloadSourcePackages bool `json:"downloadSourcePackages"` + PpaDistributorID string `json:"ppaDistributorID"` + PpaCodename string `json:"ppaCodename"` + SkipContentsPublishing bool `json:"skipContentsPublishing"` + FileSystemPublishRoots map[string]FileSystemPublishRoot `json:"FileSystemPublishEndpoints"` + S3PublishRoots map[string]S3PublishRoot `json:"S3PublishEndpoints"` + SwiftPublishRoots map[string]SwiftPublishRoot `json:"SwiftPublishEndpoints"` +} + +// FileSystemPublishRoot describes single filesystem publishing entry point +type FileSystemPublishRoot struct { + RootDir string `json:"rootDir"` + LinkMethod string `json:"linkMethod"` + VerifyMethod string `json:"verifyMethod"` } // S3PublishRoot describes single S3 publishing entry point @@ -75,6 +83,7 @@ var Config = ConfigStructure{ DownloadSourcePackages: false, PpaDistributorID: "ubuntu", PpaCodename: "", + FileSystemPublishRoots: map[string]FileSystemPublishRoot{}, S3PublishRoots: map[string]S3PublishRoot{}, SwiftPublishRoots: map[string]SwiftPublishRoot{}, } diff --git a/utils/config_test.go b/utils/config_test.go index 02db3d35..24eeff12 100644 --- a/utils/config_test.go +++ b/utils/config_test.go @@ -30,6 +30,10 @@ func (s *ConfigSuite) TestSaveConfig(c *C) { s.config.RootDir = "/tmp/aptly" s.config.DownloadConcurrency = 5 + + s.config.FileSystemPublishRoots = map[string]FileSystemPublishRoot{"test": { + RootDir: "/opt/aptly-publish"}} + s.config.S3PublishRoots = map[string]S3PublishRoot{"test": { Region: "us-east-1", Bucket: "repo"}} @@ -64,6 +68,13 @@ func (s *ConfigSuite) TestSaveConfig(c *C) { " \"ppaDistributorID\": \"\",\n"+ " \"ppaCodename\": \"\",\n"+ " \"skipContentsPublishing\": false,\n"+ + " \"FileSystemPublishEndpoints\": {\n"+ + " \"test\": {\n"+ + " \"rootDir\": \"/opt/aptly-publish\",\n"+ + " \"linkMethod\": \"\",\n"+ + " \"verifyMethod\": \"\"\n"+ + " }\n"+ + " },\n"+ " \"S3PublishEndpoints\": {\n"+ " \"test\": {\n"+ " \"region\": \"us-east-1\",\n"+