← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~jelmer/launchpad/syncpackagejob-1 into lp:launchpad/devel

 

Jelmer Vernooij has proposed merging lp:~jelmer/launchpad/syncpackagejob-1 into lp:launchpad/devel.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)


This branch adds the SyncPackageJob class for jobs that can copy packages between distributions. 

Pre-Implementation Call: with Julian
Tests: ./bin/test lp.soyuz.tests.test_syncpackagejob
-- 
https://code.launchpad.net/~jelmer/launchpad/syncpackagejob-1/+merge/40169
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jelmer/launchpad/syncpackagejob-1 into lp:launchpad/devel.
=== modified file 'lib/lp/soyuz/configure.zcml'
--- lib/lp/soyuz/configure.zcml	2010-10-12 08:14:07 +0000
+++ lib/lp/soyuz/configure.zcml	2010-11-05 10:46:49 +0000
@@ -899,18 +899,30 @@
       <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
     </class>
 
+    <!-- DistributionJob -->
+    <class class="lp.soyuz.model.distributionjob.DistributionJob">
+        <allow interface="lp.soyuz.interfaces.distributionjob.IDistributionJob" />
+    </class>
+
     <!-- InitialiseDistroSeriesJobSource -->
     <securedutility
       component="lp.soyuz.model.initialisedistroseriesjob.InitialiseDistroSeriesJob"
       provides="lp.soyuz.interfaces.distributionjob.IInitialiseDistroSeriesJobSource">
         <allow interface="lp.soyuz.interfaces.distributionjob.IInitialiseDistroSeriesJobSource"/>
     </securedutility>
-    <class class="lp.soyuz.model.distributionjob.DistributionJob">
-        <allow interface="lp.soyuz.interfaces.distributionjob.IDistributionJob" />
-    </class>
     <class class="lp.soyuz.model.initialisedistroseriesjob.InitialiseDistroSeriesJob">
         <allow interface="lp.soyuz.interfaces.distributionjob.IInitialiseDistroSeriesJob" />
         <allow interface="lp.soyuz.interfaces.distributionjob.IDistributionJob" />
     </class>
 
+    <!-- SyncPackageJobSource -->
+    <securedutility
+      component="lp.soyuz.model.syncpackagejob.SyncPackageJob"
+      provides="lp.soyuz.interfaces.distributionjob.ISyncPackageJobSource">
+        <allow interface="lp.soyuz.interfaces.distributionjob.ISyncPackageJobSource"/>
+    </securedutility>
+    <class class="lp.soyuz.model.syncpackagejob.SyncPackageJob">
+        <allow interface="lp.soyuz.interfaces.distributionjob.ISyncPackageJob" />
+        <allow interface="lp.soyuz.interfaces.distributionjob.IDistributionJob" />
+    </class>
 </configure>

=== modified file 'lib/lp/soyuz/interfaces/distributionjob.py'
--- lib/lp/soyuz/interfaces/distributionjob.py	2010-10-12 07:46:56 +0000
+++ lib/lp/soyuz/interfaces/distributionjob.py	2010-11-05 10:46:49 +0000
@@ -8,15 +8,32 @@
     "IDistributionJob",
     "IInitialiseDistroSeriesJob",
     "IInitialiseDistroSeriesJobSource",
+    "ISyncPackageJob",
+    "ISyncPackageJobSource",
 ]
 
-from lazr.enum import DBEnumeratedType, DBItem
-from zope.interface import Attribute, Interface
-from zope.schema import Int, Object
+from lazr.enum import (
+    DBEnumeratedType,
+    DBItem,
+    )
+from zope.interface import (
+    Attribute,
+    Interface,
+    )
+from zope.schema import (
+    Bool,
+    Int,
+    Object,
+    TextLine,
+    )
 
 from canonical.launchpad import _
 
-from lp.services.job.interfaces.job import IJob, IJobSource, IRunnableJob
+from lp.services.job.interfaces.job import (
+    IJob,
+    IJobSource,
+    IRunnableJob,
+    )
 from lp.registry.interfaces.distribution import IDistribution
 from lp.registry.interfaces.distroseries import IDistroSeries
 
@@ -54,13 +71,59 @@
         populating the archive from the parent distroseries.
         """)
 
+    SYNC_PACKAGE = DBItem(2, """
+        Synchronize a single package from another distribution.
+
+        This job copies a single package, optionally including binaries.
+        """)
+
 
 class IInitialiseDistroSeriesJobSource(IJobSource):
-    """An interface for acquiring IDistributionJobs."""
+    """An interface for acquiring IInitialiseDistroSeriesJobs."""
 
     def create(distroseries, arches, packagesets, rebuild):
         """Create a new initialisation job for a distroseries."""
 
 
+class ISyncPackageJobSource(IJobSource):
+    """An interface for acquiring IISyncPackageJobs."""
+
+    def create(source_archive, target_archive, distroseries, pocket,
+        source_package_name, version, include_binaries):
+        """Create a new sync package job."""
+
+    def getActiveJobs(archive):
+        """Retrieve all active sync jobs for an archive."""
+
+
 class IInitialiseDistroSeriesJob(IRunnableJob):
     """A Job that performs actions on a distribution."""
+
+
+class ISyncPackageJob(IRunnableJob):
+    """A Job that synchronizes packages."""
+
+    pocket = Int(
+            title=_('Target package publishing pocket'), required=True,
+            readonly=True,
+            )
+
+    source_archive = Int(
+            title=_('Source Archive ID'), required=True, readonly=True,
+            )
+
+    target_archive = Int(
+            title=_('Target Archive ID'), required=True, readonly=True,
+            )
+
+    source_package_name = TextLine(
+            title=_("Source Package Name"),
+            required=True, readonly=True)
+
+    source_package_version = TextLine(
+            title=_("Source Package Version"),
+            required=True, readonly=True)
+
+    include_binaries = Bool(
+            title=_("Copy binaries"),
+            required=False, readonly=True)

=== added file 'lib/lp/soyuz/model/syncpackagejob.py'
--- lib/lp/soyuz/model/syncpackagejob.py	1970-01-01 00:00:00 +0000
+++ lib/lp/soyuz/model/syncpackagejob.py	2010-11-05 10:46:49 +0000
@@ -0,0 +1,101 @@
+# Copyright 2010 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+__metaclass__ = type
+
+__all__ = [
+    "SyncPackageJob",
+]
+
+from zope.component import getUtility
+from zope.interface import (
+    classProvides,
+    implements,
+    )
+
+from canonical.launchpad.interfaces.lpstorm import (
+    IMasterStore,
+    IStore,
+    )
+
+from lp.registry.interfaces.pocket import PackagePublishingPocket
+from lp.soyuz.interfaces.archive import IArchiveSet
+from lp.soyuz.interfaces.distributionjob import (
+    DistributionJobType,
+    ISyncPackageJob,
+    ISyncPackageJobSource,
+    )
+from lp.soyuz.model.distributionjob import (
+    DistributionJob,
+    DistributionJobDerived,
+    )
+
+
+class SyncPackageJob(DistributionJobDerived):
+    """Job that copies a package between archives."""
+
+    implements(ISyncPackageJob)
+
+    class_job_type = DistributionJobType.SYNC_PACKAGE
+    classProvides(ISyncPackageJobSource)
+
+    @classmethod
+    def create(cls, source_archive, target_archive, distroseries,
+        pocket, source_package_name, source_package_version,
+        include_binaries):
+        """See `ISyncPackageJobSource`."""
+        metadata = {
+            'source_archive_id': source_archive.id,
+            'target_archive_id': target_archive.id,
+            'pocket': pocket.value,
+            'source_package_name': source_package_name,
+            'source_package_version': source_package_version,
+            'include_binaries': include_binaries,
+            }
+        job = DistributionJob(
+            distroseries.distribution, distroseries, cls.class_job_type,
+            metadata)
+        IMasterStore(DistributionJob).add(job)
+        return cls(job)
+
+    @classmethod
+    def getActiveJobs(cls, archive):
+        """See `ISyncPackageJobSource`."""
+        # TODO: JRV 20101104. This iterates manually over all active
+        # SyncPackageJobs. This should usually be a short enough list,
+        # but if it really becomes and issue target_archive should
+        # be moved into a separate database field.
+        jobs = IStore(DistributionJob).find(
+            DistributionJob,
+            DistributionJob.job_type == cls.class_job_type,
+            DistributionJob.distribution == archive.distribution)
+        jobs = [cls(job) for job in jobs]
+        return (job for job in jobs if job.target_archive == archive)
+
+    @property
+    def source_archive(self):
+        return getUtility(IArchiveSet).get(self.metadata['source_archive_id'])
+
+    @property
+    def target_archive(self):
+        return getUtility(IArchiveSet).get(self.metadata['target_archive_id'])
+
+    @property
+    def pocket(self):
+        return PackagePublishingPocket.items[self.metadata['pocket']]
+
+    @property
+    def include_binaries(self):
+        return self.metadata['include_binaries']
+
+    @property
+    def source_package_name(self):
+        return self.metadata['source_package_name']
+
+    @property
+    def source_package_version(self):
+        return self.metadata['source_package_version']
+
+    def run(self):
+        """See `IRunnableJob`."""
+        raise NotImplementedError(self.run)

=== modified file 'lib/lp/soyuz/tests/test_initialisedistroseriesjob.py'
--- lib/lp/soyuz/tests/test_initialisedistroseriesjob.py	2010-10-25 23:13:55 +0000
+++ lib/lp/soyuz/tests/test_initialisedistroseriesjob.py	2010-11-05 10:46:49 +0000
@@ -6,15 +6,12 @@
 import sys
 
 from storm.exceptions import IntegrityError
-from storm.store import Store
 import transaction
 from zope.component import getUtility
 from zope.security.proxy import removeSecurityProxy
 
 from canonical.config import config
 from canonical.testing import LaunchpadZopelessLayer
-from lp.buildmaster.enums import BuildStatus
-from lp.registry.interfaces.pocket import PackagePublishingPocket
 from lp.soyuz.interfaces.distributionjob import (
     IInitialiseDistroSeriesJobSource,
     )
@@ -26,7 +23,6 @@
 from lp.soyuz.scripts.initialise_distroseries import InitialisationError
 from lp.soyuz.tests.test_publishing import SoyuzTestPublisher
 from lp.testing import TestCaseWithFactory
-from lp.testing.matchers import Contains
 
 
 class InitialiseDistroSeriesJobTests(TestCaseWithFactory):

=== added file 'lib/lp/soyuz/tests/test_syncpackagejob.py'
--- lib/lp/soyuz/tests/test_syncpackagejob.py	1970-01-01 00:00:00 +0000
+++ lib/lp/soyuz/tests/test_syncpackagejob.py	2010-11-05 10:46:49 +0000
@@ -0,0 +1,47 @@
+# Copyright 2010 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+from zope.component import getUtility
+
+from canonical.testing import LaunchpadZopelessLayer
+from lp.soyuz.interfaces.distributionjob import (
+    ISyncPackageJob,
+    ISyncPackageJobSource,
+    )
+from lp.registry.interfaces.pocket import PackagePublishingPocket
+from lp.testing import TestCaseWithFactory
+
+
+class SyncPackageJobTests(TestCaseWithFactory):
+    """Test case for SyncPackageJob."""
+
+    layer = LaunchpadZopelessLayer
+
+    def test_create(self):
+        # A SyncPackageJob can be created and stores its arguments.
+        distroseries = self.factory.makeDistroSeries()
+        archive1 = self.factory.makeArchive(distroseries.distribution)
+        archive2 = self.factory.makeArchive(distroseries.distribution)
+        source = getUtility(ISyncPackageJobSource)
+        job = source.create(archive1, archive2, distroseries,
+                PackagePublishingPocket.RELEASE,
+                "foo", "1.0-1", include_binaries=False)
+        self.assertProvides(job, ISyncPackageJob)
+        self.assertEquals(distroseries, job.distroseries)
+        self.assertEquals(archive1, job.source_archive)
+        self.assertEquals(archive2, job.target_archive)
+        self.assertEquals(PackagePublishingPocket.RELEASE, job.pocket)
+        self.assertEquals("foo", job.source_package_name)
+        self.assertEquals("1.0-1", job.source_package_version)
+        self.assertEquals(False, job.include_binaries)
+
+    def test_getActiveJobs(self):
+        # getActiveJobs() can retrieve all active jobs for an archive.
+        distroseries = self.factory.makeDistroSeries()
+        archive1 = self.factory.makeArchive(distroseries.distribution)
+        archive2 = self.factory.makeArchive(distroseries.distribution)
+        source = getUtility(ISyncPackageJobSource)
+        job = source.create(archive1, archive2, distroseries,
+                PackagePublishingPocket.RELEASE,
+                "foo", "1.0-1", include_binaries=False)
+        self.assertContentEqual([job], source.getActiveJobs(archive2))


Follow ups