46
from canonical.config import config
47
from canonical.database.constants import UTC_NOW
48
from canonical.database.datetimecol import UtcDateTimeCol
49
from canonical.database.enumcol import EnumCol
50
from canonical.database.sqlbase import (
57
from canonical.launchpad.components.decoratedresultset import (
60
from canonical.launchpad.components.tokens import (
61
create_unique_token_for_table,
64
from canonical.launchpad.database.librarian import (
68
from canonical.launchpad.interfaces.lpstorm import (
72
from canonical.launchpad.webapp.authorization import check_permission
73
from canonical.launchpad.webapp.interfaces import (
78
from canonical.launchpad.webapp.url import urlappend
46
79
from lp.app.errors import NotFoundError
47
80
from lp.app.interfaces.launchpad import ILaunchpadCelebrities
48
81
from lp.app.validators.name import valid_name
69
102
from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
70
103
from lp.registry.model.sourcepackagename import SourcePackageName
71
104
from lp.registry.model.teammembership import TeamParticipation
72
from lp.services.config import config
73
from lp.services.database.bulk import load_related
74
from lp.services.database.constants import UTC_NOW
75
from lp.services.database.datetimecol import UtcDateTimeCol
76
from lp.services.database.decoratedresultset import DecoratedResultSet
77
from lp.services.database.enumcol import EnumCol
78
from lp.services.database.lpstorm import (
82
from lp.services.database.sqlbase import (
89
from lp.services.features import getFeatureFlag
90
105
from lp.services.job.interfaces.job import JobStatus
91
from lp.services.librarian.model import (
95
106
from lp.services.propertycache import (
97
108
get_property_cache,
99
from lp.services.tokens import (
101
create_unique_token_for_table,
103
from lp.services.webapp.authorization import check_permission
104
from lp.services.webapp.interfaces import (
109
from lp.services.webapp.url import urlappend
110
110
from lp.soyuz.adapters.archivedependencies import expand_dependencies
111
111
from lp.soyuz.adapters.packagelocation import PackageLocation
112
112
from lp.soyuz.enums import (
786
768
BinaryPackagePublishingHistory.pocket = %s
787
769
""" % sqlvalues(pocket))
789
if created_since_date is not None:
791
"BinaryPackagePublishingHistory.datecreated >= %s"
792
% sqlvalues(created_since_date))
794
771
return clauses, clauseTables, orderBy
796
773
def getAllPublishedBinaries(self, name=None, version=None, status=None,
797
774
distroarchseries=None, pocket=None,
798
exact_match=False, created_since_date=None,
800
776
"""See `IArchive`."""
801
777
clauses, clauseTables, orderBy = self._getBinaryPublishingBaseClauses(
802
778
name=name, version=version, status=status, pocket=pocket,
803
distroarchseries=distroarchseries, exact_match=exact_match,
804
created_since_date=created_since_date, ordered=ordered)
779
distroarchseries=distroarchseries, exact_match=exact_match)
806
781
all_binaries = BinaryPackagePublishingHistory.select(
807
782
' AND '.join(clauses), clauseTables=clauseTables,
1539
1507
sources, to_pocket, to_series, include_binaries,
1542
def _validateAndFindSource(self, from_archive, source_name, version):
1510
def syncSource(self, source_name, version, from_archive, to_pocket,
1511
to_series=None, include_binaries=False, person=None):
1512
"""See `IArchive`."""
1543
1513
# Check to see if the source package exists, and raise a useful error
1544
1514
# if it doesn't.
1545
1515
getUtility(ISourcePackageNameSet)[source_name]
1546
1516
# Find and validate the source package version required.
1547
1517
source = from_archive.getPublishedSources(
1548
1518
name=source_name, version=version, exact_match=True).first()
1551
def syncSource(self, source_name, version, from_archive, to_pocket,
1552
to_series=None, include_binaries=False, person=None):
1553
"""See `IArchive`."""
1554
source = self._validateAndFindSource(
1555
from_archive, source_name, version)
1557
1520
self._copySources(
1558
1521
[source], to_pocket, to_series, include_binaries,
1561
def _checkCopyPackageFeatureFlags(self):
1562
"""Prevent copyPackage(s) if these conditions are not met."""
1563
if not getFeatureFlag(u"soyuz.copypackage.enabled"):
1564
raise ForbiddenByFeatureFlag
1566
not getFeatureFlag(u"soyuz.copypackageppa.enabled")):
1567
# We have no way of giving feedback about failed jobs yet,
1568
# so this is disabled for now.
1569
raise ForbiddenByFeatureFlag(
1570
"Not enabled for copying to PPAs yet.")
1572
def copyPackage(self, source_name, version, from_archive, to_pocket,
1573
person, to_series=None, include_binaries=False,
1575
"""See `IArchive`."""
1576
self._checkCopyPackageFeatureFlags()
1578
# Asynchronously copy a package using the job system.
1579
pocket = self._text_to_pocket(to_pocket)
1580
series = self._text_to_series(to_series)
1581
# Upload permission checks, this will raise CannotCopy as
1583
sourcepackagename = getUtility(ISourcePackageNameSet)[source_name]
1584
check_copy_permissions(
1585
person, self, series, pocket, [sourcepackagename])
1587
self._validateAndFindSource(from_archive, source_name, version)
1588
job_source = getUtility(IPlainPackageCopyJobSource)
1590
package_name=source_name, source_archive=from_archive,
1591
target_archive=self, target_distroseries=series,
1592
target_pocket=pocket,
1593
package_version=version, include_binaries=include_binaries,
1594
copy_policy=PackageCopyPolicy.INSECURE, requester=person,
1595
sponsored=sponsored)
1597
def copyPackages(self, source_names, from_archive, to_pocket,
1598
person, to_series=None, include_binaries=None,
1600
"""See `IArchive`."""
1601
self._checkCopyPackageFeatureFlags()
1603
sources = self._collectLatestPublishedSources(
1604
from_archive, source_names)
1607
"None of the supplied package names are published")
1609
# Bulk-load the sourcepackagereleases so that the list
1610
# comprehension doesn't generate additional queries. The
1611
# sourcepackagenames themselves will already have been loaded when
1612
# generating the list of source publications in "sources".
1614
SourcePackageRelease, sources, ["sourcepackagereleaseID"])
1615
sourcepackagenames = [source.sourcepackagerelease.sourcepackagename
1616
for source in sources]
1618
# Now do a mass check of permissions.
1619
pocket = self._text_to_pocket(to_pocket)
1620
series = self._text_to_series(to_series)
1621
check_copy_permissions(
1622
person, self, series, pocket, sourcepackagenames)
1624
# If we get this far then we can create the PackageCopyJob.
1626
for source in sources:
1628
source.sourcepackagerelease.sourcepackagename.name,
1629
source.sourcepackagerelease.version,
1632
PackagePublishingPocket.RELEASE
1634
copy_tasks.append(task)
1636
job_source = getUtility(IPlainPackageCopyJobSource)
1637
job_source.createMultiple(
1638
series, copy_tasks, person,
1639
copy_policy=PackageCopyPolicy.MASS_SYNC,
1640
include_binaries=include_binaries, sponsored=sponsored)
1642
1524
def _collectLatestPublishedSources(self, from_archive, source_names):
1643
1525
"""Private helper to collect the latest published sources for an
1660
1539
published_sources = from_archive.getPublishedSources(
1661
1540
name=name, exact_match=True,
1662
status=(PackagePublishingStatus.PUBLISHED,
1663
PackagePublishingStatus.PENDING))
1541
status=PackagePublishingStatus.PUBLISHED)
1664
1542
first_source = published_sources.first()
1665
1543
if first_source is not None:
1666
1544
sources.append(first_source)
1669
def _text_to_series(self, to_series):
1670
if to_series is not None:
1671
result = getUtility(IDistroSeriesSet).queryByName(
1672
self.distribution, to_series)
1674
raise NoSuchDistroSeries(to_series)
1681
def _text_to_pocket(self, to_pocket):
1682
# Convert the to_pocket string to its enum.
1684
pocket = PackagePublishingPocket.items[to_pocket.upper()]
1686
raise PocketNotFound(to_pocket.upper())
1690
1547
def _copySources(self, sources, to_pocket, to_series=None,
1691
1548
include_binaries=False, person=None):
1692
1549
"""Private helper function to copy sources to this archive.
1944
1815
def _setEnabledRestrictedFamilies(self, value):
1945
1816
"""Set the restricted architecture families this archive can
1947
# Main archives are not allowed to build on restricted
1948
# architectures unless they are set to build on virtualized
1950
if (self.is_main and not self.require_virtualized):
1818
# Main archives are always allowed to build on restricted
1951
1821
proc_family_set = getUtility(IProcessorFamilySet)
1952
1822
if set(value) != set(proc_family_set.getRestricted()):
1953
raise CannotRestrictArchitectures(
1954
"Main archives can not be restricted to certain "
1955
"architectures unless they are set to build on "
1956
"virtualized builders")
1823
raise CannotRestrictArchitectures("Main archives can not "
1824
"be restricted to certain architectures")
1957
1825
archive_arch_set = getUtility(IArchiveArchSet)
1958
1826
restricted_families = archive_arch_set.getRestrictedFamilies(self)
1959
1827
for (family, archive_arch) in restricted_families:
1972
1840
self.enabled_restricted_families = restricted
1975
def validatePPA(self, person, proposed_name, private=False):
1843
def validatePPA(self, person, proposed_name):
1976
1844
ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
1978
# NOTE: This duplicates the policy in lp/soyuz/configure.zcml
1979
# which says that one needs 'launchpad.Commercial' permission to
1980
# set 'private', and the logic in `AdminByCommercialTeamOrAdmins`
1981
# which determines who is granted launchpad.Commercial
1983
commercial = getUtility(ILaunchpadCelebrities).commercial_admin
1984
admin = getUtility(ILaunchpadCelebrities).admin
1985
if not person.inTeam(commercial) and not person.inTeam(admin):
1986
return '%s is not allowed to make private PPAs' % person.name
1987
if person.is_team and (
1845
if person.isTeam() and (
1988
1846
person.subscriptionpolicy in OPEN_TEAM_POLICY):
1989
1847
return "Open teams cannot have PPAs."
1990
1848
if proposed_name is not None and proposed_name == ubuntu.name: