← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~cjwatson/launchpad/refactor-custom-archive-config into lp:launchpad

 

Colin Watson has proposed merging lp:~cjwatson/launchpad/refactor-custom-archive-config into lp:launchpad.

Commit message:
Refactor custom uploads to pass an Archive through to specific implementations rather than a publisher config.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/refactor-custom-archive-config/+merge/296704

Refactor custom uploads to pass an Archive through to specific implementations rather than a publisher config.

Tests have to do a bit more setup now, but also require fewer fake objects, and this makes it easier for custom uploads to sign files with the archive key in the future.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/refactor-custom-archive-config into lp:launchpad.
=== modified file 'lib/lp/archivepublisher/customupload.py'
--- lib/lp/archivepublisher/customupload.py	2016-05-23 10:18:21 +0000
+++ lib/lp/archivepublisher/customupload.py	2016-06-07 17:11:14 +0000
@@ -123,11 +123,11 @@
         self.tmpdir = None
         self.logger = logger
 
-    def process(self, pubconf, tarfile_path, suite):
+    def process(self, archive, tarfile_path, suite):
         """Process the upload and install it into the archive."""
         self.tarfile_path = tarfile_path
         try:
-            self.setTargetDirectory(pubconf, tarfile_path, suite)
+            self.setTargetDirectory(archive, tarfile_path, suite)
             self.checkForConflicts()
             self.extract()
             self.installFiles()
@@ -147,7 +147,7 @@
         """Set instance variables based on decomposing the filename."""
         raise NotImplementedError
 
-    def setTargetDirectory(self, pubconf, tarfile_path, suite):
+    def setTargetDirectory(self, archive, tarfile_path, suite):
         """Set self.targetdir based on parameters.
 
         This should also set self.version and self.arch (if applicable) as a

=== modified file 'lib/lp/archivepublisher/ddtp_tarball.py'
--- lib/lp/archivepublisher/ddtp_tarball.py	2016-05-23 10:18:21 +0000
+++ lib/lp/archivepublisher/ddtp_tarball.py	2016-06-07 17:11:14 +0000
@@ -18,6 +18,7 @@
 
 import os
 
+from lp.archivepublisher.config import getPubConfig
 from lp.archivepublisher.customupload import CustomUpload
 
 
@@ -58,8 +59,9 @@
         _, self.component, self.version = self.parsePath(tarfile_path)
         self.arch = None
 
-    def setTargetDirectory(self, pubconf, tarfile_path, suite):
+    def setTargetDirectory(self, archive, tarfile_path, suite):
         self.setComponents(tarfile_path)
+        pubconf = getPubConfig(archive)
         self.targetdir = os.path.join(
             pubconf.archiveroot, 'dists', suite, self.component)
 

=== modified file 'lib/lp/archivepublisher/debian_installer.py'
--- lib/lp/archivepublisher/debian_installer.py	2016-05-23 10:18:21 +0000
+++ lib/lp/archivepublisher/debian_installer.py	2016-06-07 17:11:14 +0000
@@ -15,6 +15,7 @@
 import os
 import shutil
 
+from lp.archivepublisher.config import getPubConfig
 from lp.archivepublisher.customupload import CustomUpload
 
 
@@ -50,8 +51,9 @@
     def setComponents(self, tarfile_path):
         _, self.version, self.arch = self.parsePath(tarfile_path)
 
-    def setTargetDirectory(self, pubconf, tarfile_path, suite):
+    def setTargetDirectory(self, archive, tarfile_path, suite):
         self.setComponents(tarfile_path)
+        pubconf = getPubConfig(archive)
         self.targetdir = os.path.join(
             pubconf.archiveroot, 'dists', suite, 'main',
             'installer-%s' % self.arch)

=== modified file 'lib/lp/archivepublisher/dist_upgrader.py'
--- lib/lp/archivepublisher/dist_upgrader.py	2016-05-23 10:18:21 +0000
+++ lib/lp/archivepublisher/dist_upgrader.py	2016-06-07 17:11:14 +0000
@@ -11,6 +11,7 @@
 
 import os
 
+from lp.archivepublisher.config import getPubConfig
 from lp.archivepublisher.customupload import CustomUpload
 from lp.archivepublisher.debversion import (
     BadUpstreamError,
@@ -65,8 +66,9 @@
     def setComponents(self, tarfile_path):
         _, self.version, self.arch = self.parsePath(tarfile_path)
 
-    def setTargetDirectory(self, pubconf, tarfile_path, suite):
+    def setTargetDirectory(self, archive, tarfile_path, suite):
         self.setComponents(tarfile_path)
+        pubconf = getPubConfig(archive)
         self.targetdir = os.path.join(
             pubconf.archiveroot, 'dists', suite, 'main',
             'dist-upgrader-%s' % self.arch)

=== modified file 'lib/lp/archivepublisher/publishing.py'
--- lib/lp/archivepublisher/publishing.py	2016-06-06 17:00:54 +0000
+++ lib/lp/archivepublisher/publishing.py	2016-06-07 17:11:14 +0000
@@ -3,6 +3,7 @@
 
 __all__ = [
     'cannot_modify_suite',
+    'DirectoryHash',
     'FORMAT_TO_SUBCOMPONENT',
     'GLOBAL_PUBLISHER_LOCK',
     'Publisher',

=== modified file 'lib/lp/archivepublisher/rosetta_translations.py'
--- lib/lp/archivepublisher/rosetta_translations.py	2016-05-23 10:14:39 +0000
+++ lib/lp/archivepublisher/rosetta_translations.py	2016-06-07 17:11:14 +0000
@@ -139,7 +139,7 @@
         """Sets the package name parsed from the lfa filename."""
         self.package_name = self.parsePath(tarfile_name)[0]
 
-    def setTargetDirectory(self, pubconf, tarfile_path, distroseries):
+    def setTargetDirectory(self, archive, tarfile_path, distroseries):
         pass
 
     @classmethod

=== modified file 'lib/lp/archivepublisher/signing.py'
--- lib/lp/archivepublisher/signing.py	2016-06-06 16:53:57 +0000
+++ lib/lp/archivepublisher/signing.py	2016-06-07 17:11:14 +0000
@@ -25,8 +25,8 @@
 import tempfile
 import textwrap
 
+from lp.archivepublisher.config import getPubConfig
 from lp.archivepublisher.customupload import CustomUpload
-from lp.archivepublisher.utils import RepositoryIndexFile
 from lp.services.osutils import remove_if_exists
 from lp.soyuz.interfaces.queue import CustomUploadError
 
@@ -79,7 +79,9 @@
         self.package, self.version, self.arch = self.parsePath(
             tarfile_path)
 
-    def setTargetDirectory(self, pubconf, tarfile_path, suite):
+    def setTargetDirectory(self, archive, tarfile_path, suite):
+        self.archive = archive
+        pubconf = getPubConfig(archive)
         if pubconf.signingroot is None:
             if self.logger is not None:
                 self.logger.warning(
@@ -125,14 +127,6 @@
         except ValueError:
             return None
 
-    def getArchiveOwnerAndName(self):
-        # XXX apw 2016-05-18: pull out the PPA owner and name to seed key CN
-        archive_name = os.path.dirname(self.archiveroot)
-        owner_name = os.path.basename(os.path.dirname(archive_name))
-        archive_name = os.path.basename(archive_name)
-
-        return owner_name + ' ' + archive_name
-
     def callLog(self, description, cmdl):
         status = subprocess.call(cmdl)
         if status != 0:
@@ -179,7 +173,8 @@
         if not os.path.exists(directory):
             os.makedirs(directory)
 
-        common_name = '/CN=PPA ' + self.getArchiveOwnerAndName() + '/'
+        common_name = '/CN=PPA %s %s/' % (
+            self.archive.owner.name, self.archive.name)
 
         old_mask = os.umask(0o077)
         try:
@@ -214,8 +209,6 @@
         old_mask = os.umask(0o077)
         try:
             with tempfile.NamedTemporaryFile(suffix='.keygen') as tf:
-                common_name = self.getArchiveOwnerAndName()
-
                 genkey_text = textwrap.dedent("""\
                     [ req ]
                     default_bits = 4096
@@ -225,14 +218,14 @@
                     x509_extensions = myexts
 
                     [ req_distinguished_name ]
-                    CN = /CN=PPA """ + common_name + """ kmod/
+                    CN = /CN=PPA %s %s kmod/
 
                     [ myexts ]
                     basicConstraints=critical,CA:FALSE
                     keyUsage=digitalSignature
                     subjectKeyIdentifier=hash
                     authorityKeyIdentifier=keyid
-                    """)
+                    """ % (self.archive.owner.name, self.archive.name))
 
                 print(genkey_text, file=tf)
 

=== modified file 'lib/lp/archivepublisher/tests/test_ddtp_tarball.py'
--- lib/lp/archivepublisher/tests/test_ddtp_tarball.py	2016-05-23 10:14:39 +0000
+++ lib/lp/archivepublisher/tests/test_ddtp_tarball.py	2016-06-07 17:11:14 +0000
@@ -9,23 +9,30 @@
 
 import os
 
+from zope.component import getUtility
+
+from lp.archivepublisher.config import getPubConfig
 from lp.archivepublisher.ddtp_tarball import DdtpTarballUpload
+from lp.archivepublisher.interfaces.publisherconfig import IPublisherConfigSet
 from lp.services.tarfile_helpers import LaunchpadWriteTarFile
-from lp.testing import TestCase
-
-
-class FakeConfig:
-    """A fake publisher configuration."""
-    def __init__(self, archiveroot):
-        self.archiveroot = archiveroot
-
-
-class TestDdtpTarball(TestCase):
+from lp.soyuz.enums import ArchivePurpose
+from lp.testing import TestCaseWithFactory
+from lp.testing.layers import ZopelessDatabaseLayer
+
+
+class TestDdtpTarball(TestCaseWithFactory):
+
+    layer = ZopelessDatabaseLayer
 
     def setUp(self):
         super(TestDdtpTarball, self).setUp()
         self.temp_dir = self.makeTemporaryDirectory()
-        self.pubconf = FakeConfig(self.temp_dir)
+        self.distro = self.factory.makeDistribution()
+        db_pubconf = getUtility(IPublisherConfigSet).getByDistribution(
+            self.distro)
+        db_pubconf.root_dir = unicode(self.temp_dir)
+        self.archive = self.factory.makeArchive(
+            distribution=self.distro, purpose=ArchivePurpose.PRIMARY)
         self.suite = "distroseries"
         # CustomUpload.installFiles requires a umask of 0o022.
         old_umask = os.umask(0o022)
@@ -35,21 +42,22 @@
         self.path = os.path.join(
             self.temp_dir, "translations_main_%s.tar.gz" % version)
         self.buffer = open(self.path, "wb")
-        self.archive = LaunchpadWriteTarFile(self.buffer)
+        self.tarfile = LaunchpadWriteTarFile(self.buffer)
 
     def process(self):
-        self.archive.close()
+        self.tarfile.close()
         self.buffer.close()
-        DdtpTarballUpload().process(self.pubconf, self.path, self.suite)
+        DdtpTarballUpload().process(self.archive, self.path, self.suite)
 
     def getTranslationsPath(self, filename):
+        pubconf = getPubConfig(self.archive)
         return os.path.join(
-            self.temp_dir, "dists", self.suite, "main", "i18n", filename)
+            pubconf.archiveroot, "dists", self.suite, "main", "i18n", filename)
 
     def test_basic(self):
         # Processing a simple correct tar file works.
         self.openArchive("20060728")
-        self.archive.add_file("i18n/Translation-de", "")
+        self.tarfile.add_file("i18n/Translation-de", "")
         self.process()
         self.assertTrue(os.path.exists(
             self.getTranslationsPath("Translation-de")))
@@ -57,8 +65,8 @@
     def test_ignores_empty_directories(self):
         # Empty directories in the tarball are not extracted.
         self.openArchive("20060728")
-        self.archive.add_file("i18n/Translation-de", "")
-        self.archive.add_directory("i18n/foo")
+        self.tarfile.add_file("i18n/Translation-de", "")
+        self.tarfile.add_directory("i18n/foo")
         self.process()
         self.assertTrue(os.path.exists(
             self.getTranslationsPath("Translation-de")))
@@ -68,15 +76,15 @@
         # If a DDTP tarball only contains a subset of published translation
         # files, these are updated and the rest are left untouched.
         self.openArchive("20060728")
-        self.archive.add_file("i18n/Translation-bn", "bn")
-        self.archive.add_file("i18n/Translation-ca", "ca")
+        self.tarfile.add_file("i18n/Translation-bn", "bn")
+        self.tarfile.add_file("i18n/Translation-ca", "ca")
         self.process()
         with open(self.getTranslationsPath("Translation-bn")) as bn_file:
             self.assertEqual("bn", bn_file.read())
         with open(self.getTranslationsPath("Translation-ca")) as ca_file:
             self.assertEqual("ca", ca_file.read())
         self.openArchive("20060817")
-        self.archive.add_file("i18n/Translation-bn", "new bn")
+        self.tarfile.add_file("i18n/Translation-bn", "new bn")
         self.process()
         with open(self.getTranslationsPath("Translation-bn")) as bn_file:
             self.assertEqual("new bn", bn_file.read())
@@ -90,7 +98,7 @@
         # into place, so making this work requires special care.  Test that
         # that care has been taken.
         self.openArchive("20060728")
-        self.archive.add_file("i18n/Translation-ca", "")
+        self.tarfile.add_file("i18n/Translation-ca", "")
         self.process()
         ca = self.getTranslationsPath("Translation-ca")
         bn = self.getTranslationsPath("Translation-bn")
@@ -99,7 +107,7 @@
         self.assertEqual(2, os.stat(bn).st_nlink)
         self.assertEqual(2, os.stat(ca).st_nlink)
         self.openArchive("20060817")
-        self.archive.add_file("i18n/Translation-bn", "break hard link")
+        self.tarfile.add_file("i18n/Translation-bn", "break hard link")
         self.process()
         with open(bn) as bn_file:
             self.assertEqual("break hard link", bn_file.read())

=== modified file 'lib/lp/archivepublisher/tests/test_debian_installer.py'
--- lib/lp/archivepublisher/tests/test_debian_installer.py	2016-05-23 10:14:39 +0000
+++ lib/lp/archivepublisher/tests/test_debian_installer.py	2016-06-07 17:11:14 +0000
@@ -9,27 +9,34 @@
 
 import os
 
+from zope.component import getUtility
+
+from lp.archivepublisher.config import getPubConfig
 from lp.archivepublisher.customupload import (
     CustomUploadAlreadyExists,
     CustomUploadBadUmask,
     )
 from lp.archivepublisher.debian_installer import DebianInstallerUpload
+from lp.archivepublisher.interfaces.publisherconfig import IPublisherConfigSet
 from lp.services.tarfile_helpers import LaunchpadWriteTarFile
-from lp.testing import TestCase
-
-
-class FakeConfig:
-    """A fake publisher configuration."""
-    def __init__(self, archiveroot):
-        self.archiveroot = archiveroot
-
-
-class TestDebianInstaller(TestCase):
+from lp.soyuz.enums import ArchivePurpose
+from lp.testing import TestCaseWithFactory
+from lp.testing.layers import ZopelessDatabaseLayer
+
+
+class TestDebianInstaller(TestCaseWithFactory):
+
+    layer = ZopelessDatabaseLayer
 
     def setUp(self):
         super(TestDebianInstaller, self).setUp()
         self.temp_dir = self.makeTemporaryDirectory()
-        self.pubconf = FakeConfig(self.temp_dir)
+        self.distro = self.factory.makeDistribution()
+        db_pubconf = getUtility(IPublisherConfigSet).getByDistribution(
+            self.distro)
+        db_pubconf.root_dir = unicode(self.temp_dir)
+        self.archive = self.factory.makeArchive(
+            distribution=self.distro, purpose=ArchivePurpose.PRIMARY)
         self.suite = "distroseries"
         # CustomUpload.installFiles requires a umask of 0o022.
         old_umask = os.umask(0o022)
@@ -42,24 +49,25 @@
             self.temp_dir,
             "debian-installer-images_%s_%s.tar.gz" % (self.version, self.arch))
         self.buffer = open(self.path, "wb")
-        self.archive = LaunchpadWriteTarFile(self.buffer)
+        self.tarfile = LaunchpadWriteTarFile(self.buffer)
 
     def addFile(self, path, contents):
-        self.archive.add_file(
+        self.tarfile.add_file(
             "installer-%s/%s/%s" % (self.arch, self.version, path), contents)
 
     def addSymlink(self, path, target):
-        self.archive.add_symlink(
+        self.tarfile.add_symlink(
             "installer-%s/%s/%s" % (self.arch, self.version, path), target)
 
     def process(self):
-        self.archive.close()
+        self.tarfile.close()
         self.buffer.close()
-        DebianInstallerUpload().process(self.pubconf, self.path, self.suite)
+        DebianInstallerUpload().process(self.archive, self.path, self.suite)
 
     def getInstallerPath(self, versioned_filename=None):
+        pubconf = getPubConfig(self.archive)
         installer_path = os.path.join(
-            self.temp_dir, "dists", self.suite, "main",
+            pubconf.archiveroot, "dists", self.suite, "main",
             "installer-%s" % self.arch)
         if versioned_filename is not None:
             installer_path = os.path.join(

=== modified file 'lib/lp/archivepublisher/tests/test_dist_upgrader.py'
--- lib/lp/archivepublisher/tests/test_dist_upgrader.py	2016-05-23 10:14:39 +0000
+++ lib/lp/archivepublisher/tests/test_dist_upgrader.py	2016-06-07 17:11:14 +0000
@@ -9,6 +9,9 @@
 
 import os
 
+from zope.component import getUtility
+
+from lp.archivepublisher.config import getPubConfig
 from lp.archivepublisher.customupload import (
     CustomUploadAlreadyExists,
     CustomUploadBadUmask,
@@ -17,8 +20,11 @@
     DistUpgraderBadVersion,
     DistUpgraderUpload,
     )
+from lp.archivepublisher.interfaces.publisherconfig import IPublisherConfigSet
 from lp.services.tarfile_helpers import LaunchpadWriteTarFile
-from lp.testing import TestCase
+from lp.soyuz.enums import ArchivePurpose
+from lp.testing import TestCaseWithFactory
+from lp.testing.layers import ZopelessDatabaseLayer
 
 
 class FakeConfig:
@@ -27,12 +33,19 @@
         self.archiveroot = archiveroot
 
 
-class TestDistUpgrader(TestCase):
+class TestDistUpgrader(TestCaseWithFactory):
+
+    layer = ZopelessDatabaseLayer
 
     def setUp(self):
         super(TestDistUpgrader, self).setUp()
         self.temp_dir = self.makeTemporaryDirectory()
-        self.pubconf = FakeConfig(self.temp_dir)
+        self.distro = self.factory.makeDistribution()
+        db_pubconf = getUtility(IPublisherConfigSet).getByDistribution(
+            self.distro)
+        db_pubconf.root_dir = unicode(self.temp_dir)
+        self.archive = self.factory.makeArchive(
+            distribution=self.distro, purpose=ArchivePurpose.PRIMARY)
         self.suite = "distroseries"
         # CustomUpload.installFiles requires a umask of 0o022.
         old_umask = os.umask(0o022)
@@ -42,41 +55,43 @@
         self.path = os.path.join(
             self.temp_dir, "dist-upgrader_%s_all.tar.gz" % version)
         self.buffer = open(self.path, "wb")
-        self.archive = LaunchpadWriteTarFile(self.buffer)
+        self.tarfile = LaunchpadWriteTarFile(self.buffer)
 
     def process(self):
-        self.archive.close()
+        self.tarfile.close()
         self.buffer.close()
-        DistUpgraderUpload().process(self.pubconf, self.path, self.suite)
+        DistUpgraderUpload().process(self.archive, self.path, self.suite)
 
     def getUpgraderPath(self):
+        pubconf = getPubConfig(self.archive)
         return os.path.join(
-            self.temp_dir, "dists", self.suite, "main", "dist-upgrader-all")
+            pubconf.archiveroot, "dists", self.suite, "main",
+            "dist-upgrader-all")
 
     def test_basic(self):
         # Processing a simple correct tar file works.
         self.openArchive("20060302.0120")
-        self.archive.add_file("20060302.0120/hello", "world")
+        self.tarfile.add_file("20060302.0120/hello", "world")
         self.process()
 
     def test_already_exists(self):
         # If the target directory already exists, processing fails.
         self.openArchive("20060302.0120")
-        self.archive.add_file("20060302.0120/hello", "world")
+        self.tarfile.add_file("20060302.0120/hello", "world")
         os.makedirs(os.path.join(self.getUpgraderPath(), "20060302.0120"))
         self.assertRaises(CustomUploadAlreadyExists, self.process)
 
     def test_bad_umask(self):
         # The umask must be 0o022 to avoid incorrect permissions.
         self.openArchive("20060302.0120")
-        self.archive.add_file("20060302.0120/file", "foo")
+        self.tarfile.add_file("20060302.0120/file", "foo")
         os.umask(0o002)  # cleanup already handled by setUp
         self.assertRaises(CustomUploadBadUmask, self.process)
 
     def test_current_symlink(self):
         # A "current" symlink is created to the last version.
         self.openArchive("20060302.0120")
-        self.archive.add_file("20060302.0120/hello", "world")
+        self.tarfile.add_file("20060302.0120/hello", "world")
         self.process()
         upgrader_path = self.getUpgraderPath()
         self.assertContentEqual(
@@ -91,7 +106,7 @@
     def test_bad_version(self):
         # Bad versions in the tarball are refused.
         self.openArchive("20070219.1234")
-        self.archive.add_file("foobar/foobar/dapper.tar.gz", "")
+        self.tarfile.add_file("foobar/foobar/dapper.tar.gz", "")
         self.assertRaises(DistUpgraderBadVersion, self.process)
 
     def test_getSeriesKey_extracts_architecture(self):

=== modified file 'lib/lp/archivepublisher/tests/test_signing.py'
--- lib/lp/archivepublisher/tests/test_signing.py	2016-06-06 14:26:00 +0000
+++ lib/lp/archivepublisher/tests/test_signing.py	2016-06-07 17:11:14 +0000
@@ -10,19 +10,24 @@
 import tarfile
 
 from fixtures import MonkeyPatch
+from zope.component import getUtility
 
+from lp.archivepublisher.config import getPubConfig
 from lp.archivepublisher.customupload import (
     CustomUploadAlreadyExists,
     CustomUploadBadUmask,
     )
+from lp.archivepublisher.interfaces.publisherconfig import IPublisherConfigSet
 from lp.archivepublisher.signing import (
     SigningUpload,
     UefiUpload,
     )
 from lp.services.osutils import write_file
 from lp.services.tarfile_helpers import LaunchpadWriteTarFile
-from lp.testing import TestCase
+from lp.soyuz.enums import ArchivePurpose
+from lp.testing import TestCaseWithFactory
 from lp.testing.fakemethod import FakeMethod
+from lp.testing.layers import ZopelessDatabaseLayer
 
 
 class FakeMethodCallLog(FakeMethod):
@@ -74,49 +79,37 @@
         return self.callers.get(caller, 0)
 
 
-class FakeConfigPrimary:
-    """A fake publisher configuration for the main archive."""
-    def __init__(self, distroroot, signingroot):
-        self.distroroot = distroroot
-        self.signingroot = signingroot
-        self.archiveroot = os.path.join(self.distroroot, 'ubuntu')
-        self.signingautokey = False
-
-
-class FakeConfigCopy:
-    """A fake publisher configuration for a copy archive."""
-    def __init__(self, distroroot):
-        self.distroroot = distroroot
-        self.signingroot = None
-        self.archiveroot = os.path.join(self.distroroot, 'ubuntu')
-        self.signingautokey = False
-
-
-class FakeConfigPPA:
-    """A fake publisher configuration for a PPA."""
-    def __init__(self, distroroot, signingroot, owner, ppa):
-        self.distroroot = distroroot
-        self.signingroot = signingroot
-        self.archiveroot = os.path.join(self.distroroot, owner, ppa, 'ubuntu')
-        self.signingautokey = True
-
-
-class TestSigningHelpers(TestCase):
+class TestSigningHelpers(TestCaseWithFactory):
+
+    layer = ZopelessDatabaseLayer
 
     def setUp(self):
         super(TestSigningHelpers, self).setUp()
         self.temp_dir = self.makeTemporaryDirectory()
-        self.signing_dir = self.makeTemporaryDirectory()
-        self.pubconf = FakeConfigPrimary(self.temp_dir, self.signing_dir)
+        self.distro = self.factory.makeDistribution()
+        db_pubconf = getUtility(IPublisherConfigSet).getByDistribution(
+            self.distro)
+        db_pubconf.root_dir = unicode(self.temp_dir)
+        self.archive = self.factory.makeArchive(
+            distribution=self.distro, purpose=ArchivePurpose.PRIMARY)
+        self.signing_dir = os.path.join(
+            self.temp_dir, self.distro.name + "-signing")
         self.suite = "distroseries"
         # CustomUpload.installFiles requires a umask of 0o022.
         old_umask = os.umask(0o022)
         self.addCleanup(os.umask, old_umask)
 
     def setUpPPA(self):
-        self.pubconf = FakeConfigPPA(self.temp_dir, self.signing_dir,
-            'ubuntu-archive', 'testing')
-        self.testcase_cn = '/CN=PPA ubuntu-archive testing/'
+        self.pushConfig(
+            "personalpackagearchive", root=self.temp_dir,
+            signing_keys_root=self.temp_dir)
+        owner = self.factory.makePerson(name="signing-owner")
+        self.archive = self.factory.makeArchive(
+            distribution=self.distro, owner=owner, name="testing",
+            purpose=ArchivePurpose.PPA)
+        self.signing_dir = os.path.join(
+            self.temp_dir, "signing", "signing-owner", "testing")
+        self.testcase_cn = '/CN=PPA signing-owner testing/'
 
     def setUpUefiKeys(self, create=True):
         self.key = os.path.join(self.signing_dir, "uefi.key")
@@ -136,11 +129,11 @@
         self.path = os.path.join(
             self.temp_dir, "%s_%s_%s.tar.gz" % (loader_type, version, arch))
         self.buffer = open(self.path, "wb")
-        self.archive = LaunchpadWriteTarFile(self.buffer)
+        self.tarfile = LaunchpadWriteTarFile(self.buffer)
 
     def getDistsPath(self):
-        return os.path.join(self.pubconf.archiveroot, "dists",
-            self.suite, "main")
+        pubconf = getPubConfig(self.archive)
+        return os.path.join(pubconf.archiveroot, "dists", self.suite, "main")
 
 
 class TestSigning(TestSigningHelpers):
@@ -150,19 +143,19 @@
             "%s-%s" % (loader_type, arch))
 
     def process_emulate(self):
-        self.archive.close()
+        self.tarfile.close()
         self.buffer.close()
         upload = SigningUpload()
         # Under no circumstances is it safe to execute actual commands.
         self.fake_call = FakeMethod(result=0)
         upload.callLog = FakeMethodCallLog(upload=upload)
         self.useFixture(MonkeyPatch("subprocess.call", self.fake_call))
-        upload.process(self.pubconf, self.path, self.suite)
+        upload.process(self.archive, self.path, self.suite)
 
         return upload
 
     def process(self):
-        self.archive.close()
+        self.tarfile.close()
         self.buffer.close()
         upload = SigningUpload()
         upload.signUefi = FakeMethod()
@@ -170,7 +163,7 @@
         # Under no circumstances is it safe to execute actual commands.
         fake_call = FakeMethod(result=0)
         self.useFixture(MonkeyPatch("subprocess.call", fake_call))
-        upload.process(self.pubconf, self.path, self.suite)
+        upload.process(self.archive, self.path, self.suite)
         self.assertEqual(0, fake_call.call_count)
 
         return upload
@@ -178,10 +171,11 @@
     def test_archive_copy(self):
         # If there is no key/cert configuration, processing succeeds but
         # nothing is signed.
-        self.pubconf = FakeConfigCopy(self.temp_dir)
+        self.archive = self.factory.makeArchive(
+            distribution=self.distro, purpose=ArchivePurpose.COPY)
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/empty.efi", "")
-        self.archive.add_file("1.0/empty.ko", "")
+        self.tarfile.add_file("1.0/empty.efi", "")
+        self.tarfile.add_file("1.0/empty.ko", "")
         upload = self.process_emulate()
         self.assertEqual(0, upload.callLog.caller_count('UEFI keygen'))
         self.assertEqual(0, upload.callLog.caller_count('Kmod keygen key'))
@@ -193,8 +187,8 @@
         # If the configured key/cert are missing, processing succeeds but
         # nothing is signed.
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/empty.efi", "")
-        self.archive.add_file("1.0/empty.ko", "")
+        self.tarfile.add_file("1.0/empty.efi", "")
+        self.tarfile.add_file("1.0/empty.ko", "")
         upload = self.process_emulate()
         self.assertEqual(0, upload.callLog.caller_count('UEFI keygen'))
         self.assertEqual(0, upload.callLog.caller_count('Kmod keygen key'))
@@ -208,8 +202,8 @@
         self.setUpUefiKeys()
         self.setUpKmodKeys()
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/empty.efi", "")
-        self.archive.add_file("1.0/empty.ko", "")
+        self.tarfile.add_file("1.0/empty.efi", "")
+        self.tarfile.add_file("1.0/empty.ko", "")
         upload = self.process_emulate()
         self.assertEqual(0, upload.callLog.caller_count('UEFI keygen'))
         self.assertEqual(0, upload.callLog.caller_count('Kmod keygen key'))
@@ -222,8 +216,8 @@
         # nothing is signed.
         self.setUpPPA()
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/empty.efi", "")
-        self.archive.add_file("1.0/empty.ko", "")
+        self.tarfile.add_file("1.0/empty.efi", "")
+        self.tarfile.add_file("1.0/empty.ko", "")
         upload = self.process_emulate()
         self.assertEqual(1, upload.callLog.caller_count('UEFI keygen'))
         self.assertEqual(1, upload.callLog.caller_count('Kmod keygen key'))
@@ -235,7 +229,7 @@
         # If the configured key/cert are missing, processing succeeds but
         # nothing is signed.
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/raw-signing.options", "")
+        self.tarfile.add_file("1.0/raw-signing.options", "")
         upload = self.process_emulate()
         self.assertContentEqual([], upload.signing_options.keys())
 
@@ -243,7 +237,7 @@
         # If the configured key/cert are missing, processing succeeds but
         # nothing is signed.
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/raw-signing.options", "first\n")
+        self.tarfile.add_file("1.0/raw-signing.options", "first\n")
         upload = self.process_emulate()
         self.assertContentEqual(['first'], upload.signing_options.keys())
 
@@ -251,7 +245,7 @@
         # If the configured key/cert are missing, processing succeeds but
         # nothing is signed.
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/raw-signing.options", "first\nsecond\n")
+        self.tarfile.add_file("1.0/raw-signing.options", "first\nsecond\n")
         upload = self.process_emulate()
         self.assertContentEqual(['first', 'second'],
             upload.signing_options.keys())
@@ -261,8 +255,8 @@
         self.setUpUefiKeys()
         self.setUpKmodKeys()
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/empty.efi", "")
-        self.archive.add_file("1.0/empty.ko", "")
+        self.tarfile.add_file("1.0/empty.efi", "")
+        self.tarfile.add_file("1.0/empty.ko", "")
         self.process_emulate()
         self.assertTrue(os.path.exists(os.path.join(
             self.getSignedPath("test", "amd64"), "1.0", "empty.efi")))
@@ -279,9 +273,9 @@
         self.setUpUefiKeys()
         self.setUpKmodKeys()
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/raw-signing.options", "tarball")
-        self.archive.add_file("1.0/empty.efi", "")
-        self.archive.add_file("1.0/empty.ko", "")
+        self.tarfile.add_file("1.0/raw-signing.options", "tarball")
+        self.tarfile.add_file("1.0/empty.efi", "")
+        self.tarfile.add_file("1.0/empty.ko", "")
         self.process_emulate()
         self.assertFalse(os.path.exists(os.path.join(
             self.getSignedPath("test", "amd64"), "1.0", "empty.efi")))
@@ -302,9 +296,9 @@
         self.setUpUefiKeys()
         self.setUpKmodKeys()
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/raw-signing.options", "signed-only")
-        self.archive.add_file("1.0/empty.efi", "")
-        self.archive.add_file("1.0/empty.ko", "")
+        self.tarfile.add_file("1.0/raw-signing.options", "signed-only")
+        self.tarfile.add_file("1.0/empty.efi", "")
+        self.tarfile.add_file("1.0/empty.ko", "")
         self.process_emulate()
         self.assertFalse(os.path.exists(os.path.join(
             self.getSignedPath("test", "amd64"), "1.0", "empty.efi")))
@@ -322,10 +316,10 @@
         self.setUpUefiKeys()
         self.setUpKmodKeys()
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/raw-signing.options",
+        self.tarfile.add_file("1.0/raw-signing.options",
             "tarball\nsigned-only")
-        self.archive.add_file("1.0/empty.efi", "")
-        self.archive.add_file("1.0/empty.ko", "")
+        self.tarfile.add_file("1.0/empty.efi", "")
+        self.tarfile.add_file("1.0/empty.ko", "")
         self.process_emulate()
         tarfilename = os.path.join(self.getSignedPath("test", "amd64"),
             "1.0", "signed.tar.gz")
@@ -341,7 +335,7 @@
         # Nothing is signed.
         self.setUpUefiKeys()
         self.openArchive("empty", "1.0", "amd64")
-        self.archive.add_file("1.0/hello", "world")
+        self.tarfile.add_file("1.0/hello", "world")
         upload = self.process()
         self.assertTrue(os.path.exists(os.path.join(
             self.getSignedPath("empty", "amd64"), "1.0", "hello")))
@@ -352,7 +346,7 @@
         # If the target directory already exists, processing fails.
         self.setUpUefiKeys()
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/empty.efi", "")
+        self.tarfile.add_file("1.0/empty.efi", "")
         os.makedirs(os.path.join(self.getSignedPath("test", "amd64"), "1.0"))
         self.assertRaises(CustomUploadAlreadyExists, self.process)
 
@@ -360,7 +354,7 @@
         # The umask must be 0o022 to avoid incorrect permissions.
         self.setUpUefiKeys()
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/dir/file.efi", "foo")
+        self.tarfile.add_file("1.0/dir/file.efi", "foo")
         os.umask(0o002)  # cleanup already handled by setUp
         self.assertRaises(CustomUploadBadUmask, self.process)
 
@@ -373,7 +367,7 @@
         upload = SigningUpload()
         upload.generateUefiKeys = FakeMethod()
         upload.setTargetDirectory(
-            self.pubconf, "test_1.0_amd64.tar.gz", "distroseries")
+            self.archive, "test_1.0_amd64.tar.gz", "distroseries")
         upload.signUefi('t.efi')
         self.assertEqual(1, fake_call.call_count)
         # Assert command form.
@@ -393,7 +387,7 @@
         upload = SigningUpload()
         upload.generateUefiKeys = FakeMethod()
         upload.setTargetDirectory(
-            self.pubconf, "test_1.0_amd64.tar.gz", "distroseries")
+            self.archive, "test_1.0_amd64.tar.gz", "distroseries")
         upload.signUefi('t.efi')
         self.assertEqual(0, fake_call.call_count)
         self.assertEqual(0, upload.generateUefiKeys.call_count)
@@ -407,7 +401,7 @@
         self.useFixture(MonkeyPatch("subprocess.call", fake_call))
         upload = SigningUpload()
         upload.setTargetDirectory(
-            self.pubconf, "test_1.0_amd64.tar.gz", "distroseries")
+            self.archive, "test_1.0_amd64.tar.gz", "distroseries")
         upload.generateUefiKeys()
         self.assertEqual(1, fake_call.call_count)
         # Assert the actual command matches.
@@ -428,7 +422,7 @@
         upload = SigningUpload()
         upload.generateKmodKeys = FakeMethod()
         upload.setTargetDirectory(
-            self.pubconf, "test_1.0_amd64.tar.gz", "distroseries")
+            self.archive, "test_1.0_amd64.tar.gz", "distroseries")
         upload.signKmod('t.ko')
         self.assertEqual(1, fake_call.call_count)
         # Assert command form.
@@ -449,7 +443,7 @@
         upload = SigningUpload()
         upload.generateKmodKeys = FakeMethod()
         upload.setTargetDirectory(
-            self.pubconf, "test_1.0_amd64.tar.gz", "distroseries")
+            self.archive, "test_1.0_amd64.tar.gz", "distroseries")
         upload.signUefi('t.ko')
         self.assertEqual(0, fake_call.call_count)
         self.assertEqual(0, upload.generateKmodKeys.call_count)
@@ -463,7 +457,7 @@
         self.useFixture(MonkeyPatch("subprocess.call", fake_call))
         upload = SigningUpload()
         upload.setTargetDirectory(
-            self.pubconf, "test_1.0_amd64.tar.gz", "distroseries")
+            self.archive, "test_1.0_amd64.tar.gz", "distroseries")
         upload.generateKmodKeys()
         self.assertEqual(2, fake_call.call_count)
         # Assert the actual command matches.
@@ -489,7 +483,7 @@
         # Each image in the tarball is signed.
         self.setUpUefiKeys()
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/empty.efi", "")
+        self.tarfile.add_file("1.0/empty.efi", "")
         upload = self.process()
         self.assertEqual(1, upload.signUefi.call_count)
 
@@ -497,7 +491,7 @@
         # Each image in the tarball is signed.
         self.setUpKmodKeys()
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/empty.ko", "")
+        self.tarfile.add_file("1.0/empty.ko", "")
         upload = self.process()
         self.assertEqual(1, upload.signKmod.call_count)
 
@@ -505,9 +499,9 @@
         # Each image in the tarball is signed.
         self.setUpKmodKeys()
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/empty.efi", "")
-        self.archive.add_file("1.0/empty.ko", "")
-        self.archive.add_file("1.0/empty2.ko", "")
+        self.tarfile.add_file("1.0/empty.efi", "")
+        self.tarfile.add_file("1.0/empty.ko", "")
+        self.tarfile.add_file("1.0/empty2.ko", "")
         upload = self.process()
         self.assertEqual(1, upload.signUefi.call_count)
         self.assertEqual(2, upload.signKmod.call_count)
@@ -516,7 +510,7 @@
         # Files in the tarball are installed correctly.
         self.setUpUefiKeys()
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/empty.efi", "")
+        self.tarfile.add_file("1.0/empty.efi", "")
         self.process()
         self.assertTrue(os.path.isdir(os.path.join(
             self.getDistsPath(), "signed")))
@@ -528,7 +522,7 @@
         os.makedirs(os.path.join(self.getDistsPath(), "uefi"))
         self.setUpUefiKeys()
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/empty.efi", "")
+        self.tarfile.add_file("1.0/empty.efi", "")
         self.process()
         self.assertTrue(os.path.isdir(os.path.join(
             self.getDistsPath(), "signed")))
@@ -540,7 +534,7 @@
         os.makedirs(os.path.join(self.getDistsPath(), "signing"))
         self.setUpUefiKeys()
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/empty.efi", "")
+        self.tarfile.add_file("1.0/empty.efi", "")
         self.process()
         self.assertTrue(os.path.isdir(os.path.join(
             self.getDistsPath(), "signed")))
@@ -557,7 +551,7 @@
         upload = SigningUpload()
         upload.callLog = FakeMethodCallLog(upload=upload)
         upload.setTargetDirectory(
-            self.pubconf, "test_1.0_amd64.tar.gz", "distroseries")
+            self.archive, "test_1.0_amd64.tar.gz", "distroseries")
         upload.signUefi(os.path.join(self.makeTemporaryDirectory(), 't.efi'))
         self.assertEqual(0, upload.callLog.caller_count('UEFI keygen'))
         self.assertFalse(os.path.exists(self.key))
@@ -574,7 +568,7 @@
         upload = SigningUpload()
         upload.callLog = FakeMethodCallLog(upload=upload)
         upload.setTargetDirectory(
-            self.pubconf, "test_1.0_amd64.tar.gz", "distroseries")
+            self.archive, "test_1.0_amd64.tar.gz", "distroseries")
         upload.signUefi(os.path.join(self.makeTemporaryDirectory(), 't.efi'))
         self.assertEqual(1, upload.callLog.caller_count('UEFI keygen'))
         self.assertTrue(os.path.exists(self.key))
@@ -592,7 +586,7 @@
         upload = SigningUpload()
         upload.callLog = FakeMethodCallLog(upload=upload)
         upload.setTargetDirectory(
-            self.pubconf, "test_1.0_amd64.tar.gz", "distroseries")
+            self.archive, "test_1.0_amd64.tar.gz", "distroseries")
         upload.signKmod(os.path.join(self.makeTemporaryDirectory(), 't.ko'))
         self.assertEqual(0, upload.callLog.caller_count('Kmod keygen key'))
         self.assertEqual(0, upload.callLog.caller_count('Kmod keygen cert'))
@@ -610,7 +604,7 @@
         upload = SigningUpload()
         upload.callLog = FakeMethodCallLog(upload=upload)
         upload.setTargetDirectory(
-            self.pubconf, "test_1.0_amd64.tar.gz", "distroseries")
+            self.archive, "test_1.0_amd64.tar.gz", "distroseries")
         upload.signKmod(os.path.join(self.makeTemporaryDirectory(), 't.ko'))
         self.assertEqual(1, upload.callLog.caller_count('Kmod keygen key'))
         self.assertEqual(1, upload.callLog.caller_count('Kmod keygen cert'))
@@ -625,8 +619,8 @@
         self.setUpUefiKeys()
         self.setUpKmodKeys()
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/empty.efi", "")
-        self.archive.add_file("1.0/empty.ko", "")
+        self.tarfile.add_file("1.0/empty.efi", "")
+        self.tarfile.add_file("1.0/empty.ko", "")
         self.process_emulate()
         sha256file = os.path.join(self.getSignedPath("test", "amd64"),
              "1.0", "SHA256SUMS")
@@ -640,7 +634,7 @@
             "%s-%s" % (loader_type, arch))
 
     def process(self):
-        self.archive.close()
+        self.tarfile.close()
         self.buffer.close()
         upload = UefiUpload()
         upload.signUefi = FakeMethod()
@@ -648,7 +642,7 @@
         # Under no circumstances is it safe to execute actual commands.
         fake_call = FakeMethod(result=0)
         self.useFixture(MonkeyPatch("subprocess.call", fake_call))
-        upload.process(self.pubconf, self.path, self.suite)
+        upload.process(self.archive, self.path, self.suite)
         self.assertEqual(0, fake_call.call_count)
 
         return upload
@@ -657,7 +651,7 @@
         # Files in the tarball are installed correctly.
         self.setUpUefiKeys()
         self.openArchive("test", "1.0", "amd64")
-        self.archive.add_file("1.0/empty.efi", "")
+        self.tarfile.add_file("1.0/empty.efi", "")
         self.process()
         self.assertTrue(os.path.isdir(os.path.join(
             self.getDistsPath(), "uefi")))


Follow ups