~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/soyuz/model/publishing.py

Undo rename. Again.

Show diffs side-by-side

added added

removed removed

Lines of Context:
114
114
from lp.soyuz.scripts.changeoverride import ArchiveOverriderError
115
115
 
116
116
 
 
117
PENDING = PackagePublishingStatus.PENDING
 
118
PUBLISHED = PackagePublishingStatus.PUBLISHED
 
119
 
 
120
 
 
121
# XXX cprov 2006-08-18: move it away, perhaps archivepublisher/pool.py
 
122
 
117
123
def makePoolPath(source_name, component_name):
118
 
    # XXX cprov 2006-08-18: move it away, perhaps archivepublisher/pool.py
119
124
    """Return the pool path for a given source name and component name."""
120
125
    from lp.archivepublisher.diskpool import poolify
121
126
    return os.path.join(
322
327
        fields = self.buildIndexStanzaFields()
323
328
        return fields.makeOutput()
324
329
 
325
 
    def setSuperseded(self):
326
 
        """Set to SUPERSEDED status."""
 
330
    def supersede(self):
 
331
        """See `IPublishing`."""
327
332
        self.status = PackagePublishingStatus.SUPERSEDED
328
333
        self.datesuperseded = UTC_NOW
329
334
 
330
 
    def setDeleted(self, removed_by, removal_comment=None):
331
 
        """Set to DELETED status."""
332
 
        getUtility(IPublishingSet).setMultipleDeleted(
333
 
            self.__class__, [self.id], removed_by, removal_comment)
 
335
    def requestDeletion(self, removed_by, removal_comment=None):
 
336
        """See `IPublishing`."""
 
337
        self.status = PackagePublishingStatus.DELETED
 
338
        self.datesuperseded = UTC_NOW
 
339
        self.removed_by = removed_by
 
340
        self.removal_comment = removal_comment
 
341
        if ISourcePackagePublishingHistory.providedBy(self):
 
342
            if self.archive == self.distroseries.main_archive:
 
343
                dsd_job_source = getUtility(IDistroSeriesDifferenceJobSource)
 
344
                dsd_job_source.createForPackagePublication(
 
345
                    self.distroseries,
 
346
                    self.sourcepackagerelease.sourcepackagename, self.pocket)
334
347
 
335
348
    def requestObsolescence(self):
336
349
        """See `IArchivePublisher`."""
420
433
    """A source package release publishing record."""
421
434
    implements(ISourcePackagePublishingHistory)
422
435
 
423
 
    sourcepackagename = ForeignKey(
424
 
        foreignKey='SourcePackageName', dbName='sourcepackagename')
425
 
    sourcepackagerelease = ForeignKey(
426
 
        foreignKey='SourcePackageRelease', dbName='sourcepackagerelease')
427
 
    distroseries = ForeignKey(
428
 
        foreignKey='DistroSeries', dbName='distroseries')
 
436
    sourcepackagerelease = ForeignKey(foreignKey='SourcePackageRelease',
 
437
        dbName='sourcepackagerelease')
 
438
    distroseries = ForeignKey(foreignKey='DistroSeries',
 
439
        dbName='distroseries')
429
440
    component = ForeignKey(foreignKey='Component', dbName='component')
430
441
    section = ForeignKey(foreignKey='Section', dbName='section')
431
442
    status = EnumCol(schema=PackagePublishingStatus)
448
459
    ancestor = ForeignKey(
449
460
        dbName="ancestor", foreignKey="SourcePackagePublishingHistory",
450
461
        default=None)
451
 
    creator = ForeignKey(
452
 
        dbName='creator', foreignKey='Person',
453
 
        storm_validator=validate_public_person, notNull=False, default=None)
454
462
 
455
463
    @property
456
464
    def package_creator(self):
687
695
        return self.distroseries.distribution.getSourcePackageRelease(
688
696
            self.supersededby)
689
697
 
690
 
    # XXX: StevenK 2011-09-13 bug=848563: This can die when
691
 
    # self.sourcepackagename is populated.
692
698
    @property
693
699
    def source_package_name(self):
694
700
        """See `ISourcePackagePublishingHistory`"""
740
746
 
741
747
    def supersede(self, dominant=None, logger=None):
742
748
        """See `ISourcePackagePublishingHistory`."""
743
 
        assert self.status in active_publishing_status, (
 
749
        assert self.status in [PUBLISHED, PENDING], (
744
750
            "Should not dominate unpublished source %s" %
745
751
            self.sourcepackagerelease.title)
746
752
 
747
 
        self.setSuperseded()
 
753
        super(SourcePackagePublishingHistory, self).supersede()
748
754
 
749
755
        if dominant is not None:
750
756
            if logger is not None:
797
803
            archive=current.archive)
798
804
 
799
805
    def copyTo(self, distroseries, pocket, archive, override=None,
800
 
               create_dsd_job=True, creator=None):
 
806
               create_dsd_job=True):
801
807
        """See `ISourcePackagePublishingHistory`."""
802
808
        component = self.component
803
809
        section = self.section
813
819
            component,
814
820
            section,
815
821
            pocket,
816
 
            ancestor=self,
817
 
            create_dsd_job=create_dsd_job,
818
 
            creator=creator)
 
822
            ancestor=None,
 
823
            create_dsd_job=create_dsd_job)
819
824
 
820
825
    def getStatusSummaryForBuilds(self):
821
826
        """See `ISourcePackagePublishingHistory`."""
889
894
                    diff.diff_content, self.archive).http_url
890
895
        return None
891
896
 
892
 
    def requestDeletion(self, removed_by, removal_comment=None):
893
 
        """See `IPublishing`."""
894
 
        self.setDeleted(removed_by, removal_comment)
895
 
        if self.archive.is_main:
896
 
            dsd_job_source = getUtility(IDistroSeriesDifferenceJobSource)
897
 
            dsd_job_source.createForPackagePublication(
898
 
                self.distroseries,
899
 
                self.sourcepackagerelease.sourcepackagename, self.pocket)
900
 
 
901
897
    def api_requestDeletion(self, removed_by, removal_comment=None):
902
898
        """See `IPublishingEdit`."""
903
899
        # Special deletion method for the api that makes sure binaries
911
907
 
912
908
    implements(IBinaryPackagePublishingHistory)
913
909
 
914
 
    binarypackagename = ForeignKey(
915
 
        foreignKey='BinaryPackageName', dbName='binarypackagename')
916
 
    binarypackagerelease = ForeignKey(
917
 
        foreignKey='BinaryPackageRelease', dbName='binarypackagerelease')
918
 
    distroarchseries = ForeignKey(
919
 
        foreignKey='DistroArchSeries', dbName='distroarchseries')
 
910
    binarypackagerelease = ForeignKey(foreignKey='BinaryPackageRelease',
 
911
                                      dbName='binarypackagerelease')
 
912
    distroarchseries = ForeignKey(foreignKey='DistroArchSeries',
 
913
                                   dbName='distroarchseries')
920
914
    component = ForeignKey(foreignKey='Component', dbName='component')
921
915
    section = ForeignKey(foreignKey='Section', dbName='section')
922
916
    priority = EnumCol(dbName='priority', schema=PackagePublishingPriority)
960
954
        """See `IBinaryPackagePublishingHistory`"""
961
955
        return self.distroarchseries.distroseries
962
956
 
963
 
    # XXX: StevenK 2011-09-13 bug=848563: This can die when
964
 
    # self.binarypackagename is populated.
965
957
    @property
966
958
    def binary_package_name(self):
967
959
        """See `IBinaryPackagePublishingHistory`"""
1088
1080
        return IMasterStore(BinaryPackagePublishingHistory).find(
1089
1081
                BinaryPackagePublishingHistory,
1090
1082
                BinaryPackagePublishingHistory.status.is_in(
1091
 
                    active_publishing_status),
 
1083
                    [PUBLISHED, PENDING]),
1092
1084
                BinaryPackagePublishingHistory.distroarchseriesID.is_in(
1093
1085
                    available_architectures),
1094
1086
                binarypackagerelease=self.binarypackagerelease,
1108
1100
        return IMasterStore(BinaryPackagePublishingHistory).find(
1109
1101
                BinaryPackagePublishingHistory,
1110
1102
                BinaryPackagePublishingHistory.status.is_in(
1111
 
                    active_publishing_status),
 
1103
                    [PUBLISHED, PENDING]),
1112
1104
                BinaryPackagePublishingHistory.distroarchseries ==
1113
1105
                    self.distroarchseries,
1114
1106
                binarypackagerelease=self.binarypackagerelease.debug_package,
1125
1117
        # tolerate SUPERSEDED architecture-independent binaries, because
1126
1118
        # they are dominated automatically once the first publication is
1127
1119
        # processed.
1128
 
        if self.status not in active_publishing_status:
 
1120
        if self.status not in [PUBLISHED, PENDING]:
1129
1121
            assert not self.binarypackagerelease.architecturespecific, (
1130
1122
                "Should not dominate unpublished architecture specific "
1131
1123
                "binary %s (%s)" % (
1133
1125
                self.distroarchseries.architecturetag))
1134
1126
            return
1135
1127
 
1136
 
        self.setSuperseded()
 
1128
        super(BinaryPackagePublishingHistory, self).supersede()
1137
1129
 
1138
1130
        if dominant is not None:
1139
1131
            # DDEBs cannot themselves be dominant; they are always dominated
1209
1201
 
1210
1202
        # Append the modified package publishing entry
1211
1203
        return BinaryPackagePublishingHistory(
1212
 
            binarypackagename=self.binarypackagerelease.binarypackagename,
1213
1204
            binarypackagerelease=self.binarypackagerelease,
1214
1205
            distroarchseries=self.distroarchseries,
1215
1206
            status=PackagePublishingStatus.PENDING,
1305
1296
        # different here (yet).
1306
1297
        self.requestDeletion(removed_by, removal_comment)
1307
1298
 
1308
 
    def requestDeletion(self, removed_by, removal_comment=None):
1309
 
        """See `IPublishing`."""
1310
 
        self.setDeleted(removed_by, removal_comment)
1311
 
 
1312
1299
 
1313
1300
def expand_binary_requests(distroseries, binaries):
1314
1301
    """Architecture-expand a dict of binary publication requests.
1441
1428
        insert_head = """
1442
1429
            INSERT INTO BinaryPackagePublishingHistory
1443
1430
            (archive, distroarchseries, pocket, binarypackagerelease,
1444
 
             binarypackagename, component, section, priority, status,
1445
 
             datecreated)
 
1431
             component, section, priority, status, datecreated)
1446
1432
            VALUES
1447
1433
            """
1448
1434
        insert_pubs = ", ".join(
1449
1435
            "(%s)" % ", ".join(sqlvalues(
1450
1436
                get_archive(archive, bpr).id, das.id, pocket, bpr.id,
1451
 
                bpr.binarypackagename,
1452
1437
                get_component(archive, das.distroseries, component).id,
1453
1438
                section.id, priority, PackagePublishingStatus.PENDING,
1454
1439
                UTC_NOW))
1477
1462
            "Will not create new publications in a disabled architecture.")
1478
1463
        return BinaryPackagePublishingHistory(
1479
1464
            archive=archive,
1480
 
            binarypackagename=binarypackagerelease.binarypackagename,
1481
1465
            binarypackagerelease=binarypackagerelease,
1482
1466
            distroarchseries=distroarchseries,
1483
1467
            component=get_component(
1490
1474
 
1491
1475
    def newSourcePublication(self, archive, sourcepackagerelease,
1492
1476
                             distroseries, component, section, pocket,
1493
 
                             ancestor=None, create_dsd_job=True,
1494
 
                             creator=None):
 
1477
                             ancestor=None, create_dsd_job=True):
1495
1478
        """See `IPublishingSet`."""
1496
1479
        # Avoid circular import.
1497
1480
        from lp.registry.model.distributionsourcepackage import (
1498
1481
            DistributionSourcePackage)
1499
1482
 
1500
 
        if creator is None:
1501
 
            creator = sourcepackagerelease.creator
1502
 
 
1503
1483
        pub = SourcePackagePublishingHistory(
1504
1484
            distroseries=distroseries,
1505
1485
            pocket=pocket,
1506
1486
            archive=archive,
1507
 
            sourcepackagename=sourcepackagerelease.sourcepackagename,
1508
1487
            sourcepackagerelease=sourcepackagerelease,
1509
1488
            component=get_component(archive, distroseries, component),
1510
1489
            section=section,
1511
1490
            status=PackagePublishingStatus.PENDING,
1512
1491
            datecreated=UTC_NOW,
1513
 
            ancestor=ancestor,
1514
 
            creator=creator)
 
1492
            ancestor=ancestor)
1515
1493
        DistributionSourcePackage.ensure(pub)
1516
1494
 
1517
1495
        if create_dsd_job:
1783
1761
 
1784
1762
        return result_set
1785
1763
 
1786
 
    def getBinaryPublicationsForSources(self,
1787
 
                                        one_or_more_source_publications):
 
1764
    def getBinaryPublicationsForSources(
 
1765
        self, one_or_more_source_publications):
1788
1766
        """See `IPublishingSet`."""
1789
 
        # Avoid circular imports.
1790
 
        from lp.soyuz.model.distroarchseries import DistroArchSeries
 
1767
        # Import Buildand DistroArchSeries locally to avoid circular imports,
 
1768
        # since Build uses SourcePackagePublishingHistory and DistroArchSeries
 
1769
        # uses BinaryPackagePublishingHistory.
 
1770
        from lp.soyuz.model.distroarchseries import (
 
1771
            DistroArchSeries)
1791
1772
 
1792
1773
        source_publication_ids = self._extractIDs(
1793
1774
            one_or_more_source_publications)
1974
1955
        return self.getBuildStatusSummariesForSourceIdsAndArchive([source_id],
1975
1956
            source_publication.archive)[source_id]
1976
1957
 
1977
 
    def setMultipleDeleted(self, publication_class, ids, removed_by,
1978
 
                           removal_comment=None):
1979
 
        """Mark multiple publication records as deleted."""
1980
 
        ids = list(ids)
1981
 
        if len(ids) == 0:
1982
 
            return
1983
 
 
1984
 
        permitted_classes = [
1985
 
            BinaryPackagePublishingHistory,
1986
 
            SourcePackagePublishingHistory,
1987
 
            ]
1988
 
        assert publication_class in permitted_classes, "Deleting wrong type."
1989
 
 
1990
 
        if removed_by is None:
1991
 
            removed_by_id = None
1992
 
        else:
1993
 
            removed_by_id = removed_by.id
1994
 
 
1995
 
        affected_pubs = IMasterStore(publication_class).find(
1996
 
            publication_class, publication_class.id.is_in(ids))
1997
 
        affected_pubs.set(
1998
 
            status=PackagePublishingStatus.DELETED,
1999
 
            datesuperseded=UTC_NOW,
2000
 
            removed_byID=removed_by_id,
2001
 
            removal_comment=removal_comment)
2002
 
 
2003
1958
    def requestDeletion(self, sources, removed_by, removal_comment=None):
2004
1959
        """See `IPublishingSet`."""
2005
 
        sources = list(sources)
 
1960
 
 
1961
        # The 'sources' parameter could actually be any kind of sequence
 
1962
        # (e.g. even a ResultSet) and the method would still work correctly.
 
1963
        # This is problematic when it comes to the type of the return value
 
1964
        # however.
 
1965
        # Apparently the caller anticipates that we return the sequence of
 
1966
        # instances "deleted" adhering to the original type of the 'sources'
 
1967
        # parameter.
 
1968
        # Since this is too messy we prescribe that the type of 'sources'
 
1969
        # must be a list and we return the instances manipulated as a list.
 
1970
        # This may not be an ideal solution but this way we at least achieve
 
1971
        # consistency.
 
1972
        assert isinstance(sources, list), (
 
1973
            "The 'sources' parameter must be a list.")
 
1974
 
2006
1975
        if len(sources) == 0:
2007
 
            return
2008
 
 
2009
 
        spph_ids = [spph.id for spph in sources]
2010
 
        self.setMultipleDeleted(
2011
 
            SourcePackagePublishingHistory, spph_ids, removed_by,
2012
 
            removal_comment=removal_comment)
2013
 
 
2014
 
        getUtility(IDistroSeriesDifferenceJobSource).createForSPPHs(sources)
2015
 
 
2016
 
        # Mark binary publications deleted.
2017
 
        bpph_ids = [
2018
 
            bpph.id
2019
 
            for source, bpph, bin, bin_name, arch
2020
 
                in self.getBinaryPublicationsForSources(sources)]
2021
 
        if len(bpph_ids) > 0:
2022
 
            self.setMultipleDeleted(
2023
 
                BinaryPackagePublishingHistory, bpph_ids, removed_by,
2024
 
                removal_comment=removal_comment)
 
1976
            return []
 
1977
 
 
1978
        # The following piece of query "boiler plate" will be used for
 
1979
        # both the source and the binary package publishing history table.
 
1980
        query_boilerplate = '''
 
1981
            SET status = %s,
 
1982
                datesuperseded = %s,
 
1983
                removed_by = %s,
 
1984
                removal_comment = %s
 
1985
            WHERE id IN
 
1986
            ''' % sqlvalues(PackagePublishingStatus.DELETED, UTC_NOW,
 
1987
                            removed_by, removal_comment)
 
1988
 
 
1989
        store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
 
1990
 
 
1991
        # First update the source package publishing history table.
 
1992
        source_ids = [source.id for source in sources]
 
1993
        if len(source_ids) > 0:
 
1994
            query = 'UPDATE SourcePackagePublishingHistory '
 
1995
            query += query_boilerplate
 
1996
            query += ' %s' % sqlvalues(source_ids)
 
1997
            store.execute(query)
 
1998
 
 
1999
        # Prepare the list of associated *binary* packages publishing
 
2000
        # history records.
 
2001
        binary_packages = []
 
2002
        for source in sources:
 
2003
            binary_packages.extend(source.getPublishedBinaries())
 
2004
 
 
2005
        if len(binary_packages) == 0:
 
2006
            return sources
 
2007
 
 
2008
        # Now run the query that marks the binary packages as deleted
 
2009
        # as well.
 
2010
        if len(binary_packages) > 0:
 
2011
            query = 'UPDATE BinaryPackagePublishingHistory '
 
2012
            query += query_boilerplate
 
2013
            query += ' %s' % sqlvalues(
 
2014
                [binary.id for binary in binary_packages])
 
2015
            store.execute(query)
 
2016
 
 
2017
        return sources + binary_packages
2025
2018
 
2026
2019
    def getNearestAncestor(
2027
2020
        self, package_name, archive, distroseries, pocket=None,