13007.1.2
by Jeroen Vermeulen
Tests passing. |
1 |
# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
|
8687.15.17
by Karl Fogel
Add the copyright header block to the rest of the files under lib/lp/. |
2 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
3 |
||
6455.2.1
by Celso Providelo
Moving PackageCopier & UnembargoSecurityPackage script classes out of ftpmaster.py file. |
4 |
"""PackageCopier utilities."""
|
5 |
||
6 |
__metaclass__ = type |
|
7 |
||
8 |
__all__ = [ |
|
9 |
'PackageCopier', |
|
10 |
'UnembargoSecurityPackage', |
|
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
11 |
'CopyChecker', |
13007.1.2
by Jeroen Vermeulen
Tests passing. |
12 |
'check_copy_permissions', |
6455.2.2
by Celso Providelo
moving the auxiliary copy-methos to scripts/packagecopier.py. |
13 |
'do_copy', |
7675.235.5
by Celso Providelo
applying review comments, r=abentley. |
14 |
'_do_delayed_copy', |
15 |
'_do_direct_copy', |
|
8589.3.4
by Celso Providelo
name extracted functions appropriately. |
16 |
're_upload_file', |
17 |
'update_files_privacy', |
|
6455.2.1
by Celso Providelo
Moving PackageCopier & UnembargoSecurityPackage script classes out of ftpmaster.py file. |
18 |
]
|
19 |
||
20 |
import os |
|
21 |
import tempfile |
|
22 |
||
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
23 |
import apt_pkg |
7675.575.1
by William Grant
Move lp.soyuz.interfaces.build.BuildStatus to lp.buildmaster.interfaces.buildbase. Sort various imports along the way. |
24 |
from lazr.delegates import delegates |
6455.2.1
by Celso Providelo
Moving PackageCopier & UnembargoSecurityPackage script classes out of ftpmaster.py file. |
25 |
from zope.component import getUtility |
26 |
||
8426.3.4
by Celso Providelo
Another importing order issue. |
27 |
from canonical.launchpad.interfaces.librarian import ILibraryFileAliasSet |
28 |
from canonical.librarian.utils import copy_and_close |
|
12177.12.5
by William Grant
do_delayed_copy no longer copies builds without a corresponding enabled architecture in the target series. |
29 |
from lp.app.errors import NotFoundError |
11458.1.1
by Jelmer Vernooij
Move enums of buildmaster. |
30 |
from lp.buildmaster.enums import BuildStatus |
14168.3.9
by Jeroen Vermeulen
Format imports. |
31 |
from lp.soyuz.adapters.notification import notify |
7675.575.1
by William Grant
Move lp.soyuz.interfaces.build.BuildStatus to lp.buildmaster.interfaces.buildbase. Sort various imports along the way. |
32 |
from lp.soyuz.adapters.packagelocation import build_package_location |
12981.1.2
by Raphael Badin
Roll back 12977. |
33 |
from lp.soyuz.enums import ( |
34 |
ArchivePurpose, |
|
14191.2.3
by Julian Edwards
Prevent copying of DDEBs into primary archives. |
35 |
BinaryPackageFileType, |
12981.1.2
by Raphael Badin
Roll back 12977. |
36 |
SourcePackageFormat, |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
37 |
)
|
12981.1.2
by Raphael Badin
Roll back 12977. |
38 |
from lp.soyuz.interfaces.archive import CannotCopy |
10667.2.2
by Michael Nelson
Mass renaming of imports and references to IBuild/Build/IBuildSet |
39 |
from lp.soyuz.interfaces.binarypackagebuild import BuildSetStatus |
8294.6.1
by Julian Edwards
First stab at code-reorg. Still got a discrepancy on stuff I assigned to registry but not migrated yet. |
40 |
from lp.soyuz.interfaces.publishing import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
41 |
active_publishing_status, |
42 |
IBinaryPackagePublishingHistory, |
|
43 |
IPublishingSet, |
|
44 |
ISourcePackagePublishingHistory, |
|
45 |
)
|
|
10549.1.1
by Steve Kowalik
Also copy custom files from the restricted librarian when doing a delayed copy |
46 |
from lp.soyuz.interfaces.queue import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
47 |
IPackageUpload, |
48 |
IPackageUploadCustom, |
|
49 |
IPackageUploadSet, |
|
50 |
)
|
|
51 |
from lp.soyuz.scripts.ftpmasterbase import ( |
|
52 |
SoyuzScript, |
|
53 |
SoyuzScriptError, |
|
54 |
)
|
|
7675.575.1
by William Grant
Move lp.soyuz.interfaces.build.BuildStatus to lp.buildmaster.interfaces.buildbase. Sort various imports along the way. |
55 |
from lp.soyuz.scripts.processaccepted import close_bugs_for_sourcepublication |
6455.2.1
by Celso Providelo
Moving PackageCopier & UnembargoSecurityPackage script classes out of ftpmaster.py file. |
56 |
|
14027.3.1
by Jeroen Vermeulen
Fix lots of lint in recently-changed files. |
57 |
|
8589.3.4
by Celso Providelo
name extracted functions appropriately. |
58 |
def re_upload_file(libraryfile, restricted=False): |
8589.3.3
by Celso Providelo
Extracting and testing unembaroging base procedures. |
59 |
"""Re-upload a librarian file to the public server.
|
60 |
||
61 |
:param libraryfile: a `LibraryFileAlias`.
|
|
8589.3.5
by Celso Providelo
applying review comments, r=gmb. |
62 |
:param restricted: whether or not the new file should be restricted.
|
8589.3.3
by Celso Providelo
Extracting and testing unembaroging base procedures. |
63 |
|
8589.3.5
by Celso Providelo
applying review comments, r=gmb. |
64 |
:return: A new `LibraryFileAlias`.
|
8589.3.1
by Celso Providelo
Make the functions used for delayed-copies standalone and ensure the tests pass. |
65 |
"""
|
14027.3.1
by Jeroen Vermeulen
Fix lots of lint in recently-changed files. |
66 |
# XXX cprov 2009-06-12: This function could be incorporated in ILFA.
|
67 |
# I just don't see a clear benefit in doing that right now.
|
|
68 |
||
8589.3.3
by Celso Providelo
Extracting and testing unembaroging base procedures. |
69 |
# Open the the libraryfile for reading.
|
70 |
libraryfile.open() |
|
8589.3.1
by Celso Providelo
Make the functions used for delayed-copies standalone and ensure the tests pass. |
71 |
|
72 |
# Make a temporary file to hold the download. It's annoying
|
|
73 |
# having to download to a temp file but there are no guarantees
|
|
74 |
# how large the files are, so using StringIO would be dangerous.
|
|
75 |
fd, filepath = tempfile.mkstemp() |
|
9209.5.1
by Celso Providelo
Fixing opened-file leak when processing delayed-copies. |
76 |
temp_file = os.fdopen(fd, 'wb') |
8589.3.1
by Celso Providelo
Make the functions used for delayed-copies standalone and ensure the tests pass. |
77 |
|
78 |
# Read the old library file into the temp file.
|
|
8589.3.3
by Celso Providelo
Extracting and testing unembaroging base procedures. |
79 |
copy_and_close(libraryfile, temp_file) |
8589.3.1
by Celso Providelo
Make the functions used for delayed-copies standalone and ensure the tests pass. |
80 |
|
81 |
# Upload the file to the unrestricted librarian and make
|
|
82 |
# sure the publishing record points to it.
|
|
8589.3.3
by Celso Providelo
Extracting and testing unembaroging base procedures. |
83 |
new_lfa = getUtility(ILibraryFileAliasSet).create( |
84 |
libraryfile.filename, libraryfile.content.filesize, |
|
85 |
open(filepath, "rb"), libraryfile.mimetype, restricted=restricted) |
|
8589.3.1
by Celso Providelo
Make the functions used for delayed-copies standalone and ensure the tests pass. |
86 |
|
87 |
# Junk the temporary file.
|
|
88 |
os.remove(filepath) |
|
89 |
||
90 |
return new_lfa |
|
91 |
||
13007.1.2
by Jeroen Vermeulen
Tests passing. |
92 |
|
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
93 |
# XXX cprov 2009-06-12: this function should be incorporated in
|
94 |
# IPublishing.
|
|
8589.3.4
by Celso Providelo
name extracted functions appropriately. |
95 |
def update_files_privacy(pub_record): |
10549.1.1
by Steve Kowalik
Also copy custom files from the restricted librarian when doing a delayed copy |
96 |
"""Update file privacy according the publishing destination
|
8589.3.1
by Celso Providelo
Make the functions used for delayed-copies standalone and ensure the tests pass. |
97 |
|
98 |
:param pub_record: One of a SourcePackagePublishingHistory or
|
|
99 |
BinaryPackagePublishingHistory record.
|
|
8589.3.3
by Celso Providelo
Extracting and testing unembaroging base procedures. |
100 |
|
101 |
:return: a list of re-uploaded `LibraryFileAlias` objects.
|
|
8589.3.1
by Celso Providelo
Make the functions used for delayed-copies standalone and ensure the tests pass. |
102 |
"""
|
8589.3.3
by Celso Providelo
Extracting and testing unembaroging base procedures. |
103 |
package_files = [] |
10549.1.1
by Steve Kowalik
Also copy custom files from the restricted librarian when doing a delayed copy |
104 |
archive = None |
8589.3.1
by Celso Providelo
Make the functions used for delayed-copies standalone and ensure the tests pass. |
105 |
if ISourcePackagePublishingHistory.providedBy(pub_record): |
10549.1.1
by Steve Kowalik
Also copy custom files from the restricted librarian when doing a delayed copy |
106 |
archive = pub_record.archive |
8589.3.3
by Celso Providelo
Extracting and testing unembaroging base procedures. |
107 |
# Re-upload the package files files if necessary.
|
8589.3.1
by Celso Providelo
Make the functions used for delayed-copies standalone and ensure the tests pass. |
108 |
sourcepackagerelease = pub_record.sourcepackagerelease |
8589.3.3
by Celso Providelo
Extracting and testing unembaroging base procedures. |
109 |
package_files.extend( |
110 |
[(source_file, 'libraryfile') |
|
111 |
for source_file in sourcepackagerelease.files]) |
|
112 |
# Re-upload the package diff files if necessary.
|
|
113 |
package_files.extend( |
|
114 |
[(diff, 'diff_content') |
|
115 |
for diff in sourcepackagerelease.package_diffs]) |
|
8589.3.1
by Celso Providelo
Make the functions used for delayed-copies standalone and ensure the tests pass. |
116 |
# Re-upload the source upload changesfile if necessary.
|
117 |
package_upload = sourcepackagerelease.package_upload |
|
8589.3.3
by Celso Providelo
Extracting and testing unembaroging base procedures. |
118 |
package_files.append((package_upload, 'changesfile')) |
12792.3.2
by Julian Edwards
Add fix |
119 |
package_files.append((sourcepackagerelease, 'changelog')) |
8589.3.1
by Celso Providelo
Make the functions used for delayed-copies standalone and ensure the tests pass. |
120 |
elif IBinaryPackagePublishingHistory.providedBy(pub_record): |
10549.1.1
by Steve Kowalik
Also copy custom files from the restricted librarian when doing a delayed copy |
121 |
archive = pub_record.archive |
8589.3.3
by Celso Providelo
Extracting and testing unembaroging base procedures. |
122 |
# Re-upload the binary files if necessary.
|
123 |
binarypackagerelease = pub_record.binarypackagerelease |
|
124 |
package_files.extend( |
|
125 |
[(binary_file, 'libraryfile') |
|
126 |
for binary_file in binarypackagerelease.files]) |
|
127 |
# Re-upload the upload changesfile file as necessary.
|
|
128 |
build = binarypackagerelease.build |
|
8589.3.1
by Celso Providelo
Make the functions used for delayed-copies standalone and ensure the tests pass. |
129 |
package_upload = build.package_upload |
8589.3.3
by Celso Providelo
Extracting and testing unembaroging base procedures. |
130 |
package_files.append((package_upload, 'changesfile')) |
8589.3.1
by Celso Providelo
Make the functions used for delayed-copies standalone and ensure the tests pass. |
131 |
# Re-upload the buildlog file as necessary.
|
7675.687.131
by Michael Nelson
test_copypackage |
132 |
package_files.append((build, 'log')) |
10549.1.1
by Steve Kowalik
Also copy custom files from the restricted librarian when doing a delayed copy |
133 |
elif IPackageUploadCustom.providedBy(pub_record): |
134 |
# Re-upload the custom files included
|
|
135 |
package_files.append((pub_record, 'libraryfilealias')) |
|
136 |
# And set archive to the right attribute for PUCs
|
|
137 |
archive = pub_record.packageupload.archive |
|
8589.3.1
by Celso Providelo
Make the functions used for delayed-copies standalone and ensure the tests pass. |
138 |
else: |
139 |
raise AssertionError( |
|
10549.1.1
by Steve Kowalik
Also copy custom files from the restricted librarian when doing a delayed copy |
140 |
"pub_record is not one of SourcePackagePublishingHistory, "
|
141 |
"BinaryPackagePublishingHistory or PackageUploadCustom.") |
|
8589.3.1
by Celso Providelo
Make the functions used for delayed-copies standalone and ensure the tests pass. |
142 |
|
8589.3.3
by Celso Providelo
Extracting and testing unembaroging base procedures. |
143 |
re_uploaded_files = [] |
144 |
for obj, attr_name in package_files: |
|
145 |
old_lfa = getattr(obj, attr_name, None) |
|
146 |
# Only reupload restricted files published in public archives,
|
|
147 |
# not the opposite. We don't have a use-case for privatizing
|
|
148 |
# files yet.
|
|
149 |
if (old_lfa is None or |
|
10549.1.1
by Steve Kowalik
Also copy custom files from the restricted librarian when doing a delayed copy |
150 |
old_lfa.restricted == archive.private or |
8589.3.3
by Celso Providelo
Extracting and testing unembaroging base procedures. |
151 |
old_lfa.restricted == False): |
8589.3.1
by Celso Providelo
Make the functions used for delayed-copies standalone and ensure the tests pass. |
152 |
continue
|
8589.3.4
by Celso Providelo
name extracted functions appropriately. |
153 |
new_lfa = re_upload_file( |
10549.1.1
by Steve Kowalik
Also copy custom files from the restricted librarian when doing a delayed copy |
154 |
old_lfa, restricted=archive.private) |
8589.3.3
by Celso Providelo
Extracting and testing unembaroging base procedures. |
155 |
setattr(obj, attr_name, new_lfa) |
156 |
re_uploaded_files.append(new_lfa) |
|
157 |
||
158 |
return re_uploaded_files |
|
159 |
||
160 |
||
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
161 |
# XXX cprov 2009-07-01: should be part of `ISourcePackagePublishingHistory`.
|
162 |
def has_restricted_files(source): |
|
163 |
"""Whether or not a given source files has restricted files."""
|
|
164 |
for source_file in source.sourcepackagerelease.files: |
|
165 |
if source_file.libraryfile.restricted: |
|
166 |
return True |
|
167 |
||
168 |
for binary in source.getBuiltBinaries(): |
|
169 |
for binary_file in binary.binarypackagerelease.files: |
|
170 |
if binary_file.libraryfile.restricted: |
|
171 |
return True |
|
172 |
||
173 |
return False |
|
174 |
||
175 |
||
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
176 |
class CheckedCopy: |
177 |
"""Representation of a copy that was checked and approved.
|
|
178 |
||
179 |
Decorates `ISourcePackagePublishingHistory`, tweaking
|
|
180 |
`getStatusSummaryForBuilds` to return `BuildSetStatus.NEEDSBUILD`
|
|
181 |
for source-only copies.
|
|
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
182 |
|
183 |
It also store the 'delayed' boolean, which controls the way this source
|
|
184 |
should be copied to the destionation archive (see `_do_delayed_copy` and
|
|
185 |
`_do_direct_copy`)
|
|
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
186 |
"""
|
187 |
delegates(ISourcePackagePublishingHistory) |
|
188 |
||
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
189 |
def __init__(self, context, include_binaries, delayed): |
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
190 |
self.context = context |
191 |
self.include_binaries = include_binaries |
|
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
192 |
self.delayed = delayed |
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
193 |
|
194 |
def getStatusSummaryForBuilds(self): |
|
195 |
"""Always `BuildSetStatus.NEEDSBUILD` for source-only copies."""
|
|
196 |
if self.include_binaries: |
|
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
197 |
return self.context.getStatusSummaryForBuilds() |
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
198 |
else: |
199 |
return {'status': BuildSetStatus.NEEDSBUILD} |
|
200 |
||
201 |
||
13007.1.2
by Jeroen Vermeulen
Tests passing. |
202 |
def check_copy_permissions(person, archive, series, pocket, |
13007.1.6
by Jeroen Vermeulen
Check permissions for all packages at once, to accommodate planned optimizations. |
203 |
sourcepackagenames): |
13007.1.2
by Jeroen Vermeulen
Tests passing. |
204 |
"""Check that `person` has permission to copy a package.
|
205 |
||
206 |
:param person: User attempting the upload.
|
|
207 |
:param archive: Destination `Archive`.
|
|
208 |
:param series: Destination `DistroSeries`.
|
|
209 |
:param pocket: Destination `Pocket`.
|
|
13007.1.6
by Jeroen Vermeulen
Check permissions for all packages at once, to accommodate planned optimizations. |
210 |
:param sourcepackagenames: Sequence of `SourcePackageName`s for the
|
211 |
packages to be copied.
|
|
13007.1.2
by Jeroen Vermeulen
Tests passing. |
212 |
:raises CannotCopy: If the copy is not allowed.
|
213 |
"""
|
|
214 |
if person is None: |
|
215 |
raise CannotCopy("Cannot check copy permissions (no requester).") |
|
216 |
||
217 |
# If there is a requester, check that he has upload permission into
|
|
218 |
# the destination (archive, component, pocket). This check is done
|
|
219 |
# here rather than in the security adapter because it requires more
|
|
220 |
# info than is available in the security adapter.
|
|
13007.1.6
by Jeroen Vermeulen
Check permissions for all packages at once, to accommodate planned optimizations. |
221 |
for spn in set(sourcepackagenames): |
222 |
package = series.getSourcePackage(spn) |
|
223 |
destination_component = package.latest_published_component |
|
224 |
||
225 |
# If destination_component is not None, make sure the person
|
|
226 |
# has upload permission for this component. Otherwise, any
|
|
227 |
# upload permission on this archive will do.
|
|
228 |
strict_component = destination_component is not None |
|
229 |
reason = archive.checkUpload( |
|
230 |
person, series, spn, destination_component, pocket, |
|
231 |
strict_component=strict_component) |
|
232 |
||
233 |
if reason is not None: |
|
234 |
raise CannotCopy(reason) |
|
13007.1.2
by Jeroen Vermeulen
Tests passing. |
235 |
|
236 |
||
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
237 |
class CopyChecker: |
238 |
"""Check copy candiates.
|
|
239 |
||
240 |
Allows the checker function to identify conflicting copy candidates
|
|
241 |
within the copying batch.
|
|
242 |
"""
|
|
13168.12.23
by Raphael Badin
Refactor initialization to use the packagecopier if the destination archive is not empty. |
243 |
def __init__(self, archive, include_binaries, allow_delayed_copies=True, |
244 |
strict_binaries=True): |
|
13168.12.30
by Raphael Badin
Add doc tests. |
245 |
"""Initialize a copy checker.
|
246 |
||
247 |
:param archive: the target `IArchive`.
|
|
248 |
:param include_binaries: controls whether or not the published
|
|
249 |
binaries for each given source should be also copied along
|
|
250 |
with the source.
|
|
251 |
:param allow_delayed_copies: boolean indicating whether or not private
|
|
252 |
sources can be copied to public archives using delayed_copies.
|
|
13168.12.32
by Raphael Badin
Apply MP's comments. |
253 |
:param strict_binaries: If 'include_binaries' is True then setting
|
254 |
this to True will make the copy fail if binaries cannot be also
|
|
255 |
copied.
|
|
13168.12.30
by Raphael Badin
Add doc tests. |
256 |
"""
|
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
257 |
self.archive = archive |
258 |
self.include_binaries = include_binaries |
|
13168.12.23
by Raphael Badin
Refactor initialization to use the packagecopier if the destination archive is not empty. |
259 |
self.strict_binaries = strict_binaries |
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
260 |
self.allow_delayed_copies = allow_delayed_copies |
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
261 |
self._inventory = {} |
262 |
||
263 |
def _getInventoryKey(self, candidate): |
|
264 |
"""Return a key representing the copy candidate in the inventory.
|
|
265 |
||
266 |
:param candidate: a `ISourcePackagePublishingHistory` copy candidate.
|
|
267 |
:return: a tuple with the source (name, version) strings.
|
|
268 |
"""
|
|
269 |
return ( |
|
270 |
candidate.source_package_name, candidate.source_package_version) |
|
271 |
||
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
272 |
def addCopy(self, source, delayed): |
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
273 |
"""Story a copy in the inventory as a `CheckedCopy` instance."""
|
274 |
inventory_key = self._getInventoryKey(source) |
|
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
275 |
checked_copy = CheckedCopy(source, self.include_binaries, delayed) |
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
276 |
candidates = self._inventory.setdefault(inventory_key, []) |
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
277 |
candidates.append(checked_copy) |
278 |
||
279 |
def getCheckedCopies(self): |
|
280 |
"""Return a list of copies allowed to be performed."""
|
|
281 |
for copies in self._inventory.values(): |
|
282 |
for copy in copies: |
|
283 |
yield copy |
|
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
284 |
|
285 |
def getConflicts(self, candidate): |
|
286 |
"""Conflicting `CheckedCopy` objects in the inventory.
|
|
287 |
||
288 |
:param candidate: a `ISourcePackagePublishingHistory` copy candidate.
|
|
289 |
:return: a list of conflicting copies in the inventory, in case
|
|
290 |
of non-conflicting candidates an empty list is returned.
|
|
291 |
"""
|
|
292 |
inventory_key = self._getInventoryKey(candidate) |
|
293 |
return self._inventory.get(inventory_key, []) |
|
294 |
||
295 |
def _checkArchiveConflicts(self, source, series): |
|
296 |
"""Check for possible conflicts in the destination archive.
|
|
297 |
||
298 |
Check if there is a source with the same name and version published
|
|
299 |
in the destination archive or in the inventory of copies already
|
|
300 |
approved. If it exists (regardless of the series and pocket) and
|
|
301 |
it has built or will build binaries, do not allow the copy without
|
|
302 |
binaries.
|
|
303 |
||
304 |
This is because the copied source will rebuild binaries that
|
|
305 |
conflict with existing ones.
|
|
306 |
||
307 |
Even when the binaries are included, they are checked for conflict.
|
|
308 |
||
309 |
:param source: copy candidate, `ISourcePackagePublishingHistory`.
|
|
310 |
:param series: destination `IDistroSeries`.
|
|
311 |
||
312 |
:raise CannotCopy: when a copy is not allowed to be performed
|
|
313 |
containing the reason of the error.
|
|
314 |
"""
|
|
315 |
destination_archive_conflicts = self.archive.getPublishedSources( |
|
316 |
name=source.sourcepackagerelease.name, |
|
317 |
version=source.sourcepackagerelease.version, |
|
318 |
exact_match=True) |
|
319 |
||
320 |
inventory_conflicts = self.getConflicts(source) |
|
321 |
||
10827.6.7
by Steve Kowalik
* Correct some thinkos in the interface docstring. |
322 |
# If there are no conflicts with the same version, we can skip the
|
323 |
# rest of the checks, but we still want to check conflicting files
|
|
12505.4.1
by Robert Collins
Hopefully fix bug 727560 by permitting a much better query plan for folk querying the primary archive. |
324 |
if (destination_archive_conflicts.is_empty() and |
7675.677.1
by Steve Kowalik
Merge from lp:~stevenk/launchpad/more-copypackage-fixes branch. This fixes three issues with copying packages. |
325 |
len(inventory_conflicts) == 0): |
326 |
self._checkConflictingFiles(source) |
|
327 |
return
|
|
328 |
||
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
329 |
# Cache the conflicting publications because they will be iterated
|
330 |
# more than once.
|
|
331 |
destination_archive_conflicts = list(destination_archive_conflicts) |
|
332 |
destination_archive_conflicts.extend(inventory_conflicts) |
|
333 |
||
334 |
# Identify published binaries and incomplete builds or unpublished
|
|
335 |
# binaries from archive conflicts. Either will deny source-only
|
|
336 |
# copies, since a rebuild will result in binaries that cannot be
|
|
337 |
# published in the archive because they will conflict with the
|
|
338 |
# existent ones.
|
|
339 |
published_binaries = set() |
|
340 |
for candidate in destination_archive_conflicts: |
|
341 |
# If the candidate refers to a different sourcepackagerelease
|
|
342 |
# with the same name and version there is a high chance that
|
|
343 |
# they have conflicting files that cannot be published in the
|
|
344 |
# repository pool. So, we deny the copy until the existing
|
|
345 |
# source gets deleted (and removed from the archive).
|
|
346 |
if (source.sourcepackagerelease.id != |
|
347 |
candidate.sourcepackagerelease.id): |
|
348 |
raise CannotCopy( |
|
349 |
'a different source with the same version is published '
|
|
350 |
'in the destination archive') |
|
351 |
||
352 |
# If the conflicting candidate (which we already know refer to
|
|
353 |
# the same sourcepackagerelease) was found in the copy
|
|
354 |
# destination series we don't have to check its building status
|
|
355 |
# if binaries are included. It's not going to change in terms of
|
|
356 |
# new builds and the resulting binaries will match. See more
|
|
357 |
# details in `ISourcePackageRelease.getBuildsByArch`.
|
|
358 |
if (candidate.distroseries.id == series.id and |
|
359 |
self.archive.id == source.archive.id and |
|
360 |
self.include_binaries): |
|
361 |
continue
|
|
362 |
||
363 |
# Conflicting candidates pending build or building in a different
|
|
364 |
# series are a blocker for the copy. The copied source will
|
|
365 |
# certainly produce conflicting binaries.
|
|
366 |
build_summary = candidate.getStatusSummaryForBuilds() |
|
367 |
building_states = ( |
|
368 |
BuildSetStatus.NEEDSBUILD, |
|
369 |
BuildSetStatus.BUILDING, |
|
370 |
)
|
|
371 |
if build_summary['status'] in building_states: |
|
372 |
raise CannotCopy( |
|
373 |
"same version already building in the destination "
|
|
374 |
"archive for %s" % candidate.distroseries.displayname) |
|
375 |
||
376 |
# If the set of built binaries does not match the set of published
|
|
377 |
# ones the copy should be denied and the user should wait for the
|
|
378 |
# next publishing cycle to happen before copying the package.
|
|
379 |
# The copy is only allowed when all built binaries are published,
|
|
380 |
# this way there is no chance of a conflict.
|
|
381 |
if build_summary['status'] == BuildSetStatus.FULLYBUILT_PENDING: |
|
382 |
raise CannotCopy( |
|
383 |
"same version has unpublished binaries in the "
|
|
384 |
"destination archive for %s, please wait for them to be " |
|
385 |
"published before copying" % |
|
386 |
candidate.distroseries.displayname) |
|
387 |
||
388 |
# Update published binaries inventory for the conflicting
|
|
389 |
# candidates.
|
|
390 |
archive_binaries = set( |
|
391 |
pub_binary.binarypackagerelease.id |
|
392 |
for pub_binary in candidate.getBuiltBinaries()) |
|
393 |
published_binaries.update(archive_binaries) |
|
394 |
||
395 |
if not self.include_binaries: |
|
396 |
if len(published_binaries) > 0: |
|
397 |
raise CannotCopy( |
|
398 |
"same version already has published binaries in the "
|
|
399 |
"destination archive") |
|
400 |
else: |
|
401 |
# Since DEB files are compressed with 'ar' (encoding the creation
|
|
402 |
# timestamp) and serially built by our infrastructure, it's
|
|
403 |
# correct to assume that the set of BinaryPackageReleases being
|
|
404 |
# copied can only be a superset of the set of
|
|
405 |
# BinaryPackageReleases published in the destination archive.
|
|
406 |
copied_binaries = set( |
|
407 |
pub.binarypackagerelease.id |
|
408 |
for pub in source.getBuiltBinaries()) |
|
409 |
if not copied_binaries.issuperset(published_binaries): |
|
410 |
raise CannotCopy( |
|
411 |
"binaries conflicting with the existing ones") |
|
7675.687.131
by Michael Nelson
test_copypackage |
412 |
self._checkConflictingFiles(source) |
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
413 |
|
7675.677.1
by Steve Kowalik
Merge from lp:~stevenk/launchpad/more-copypackage-fixes branch. This fixes three issues with copying packages. |
414 |
def _checkConflictingFiles(self, source): |
415 |
# If both the source and destination archive are the same, we don't
|
|
416 |
# need to perform this test, since that guarantees the filenames
|
|
417 |
# do not conflict.
|
|
418 |
if source.archive.id == self.archive.id: |
|
419 |
return None |
|
10827.6.5
by Steve Kowalik
* Fix IArchive.getFilesAndSha1s() to take a list of source files, rather than |
420 |
source_files = [ |
7675.687.131
by Michael Nelson
test_copypackage |
421 |
sprf.libraryfile.filename for sprf in |
10827.6.5
by Steve Kowalik
* Fix IArchive.getFilesAndSha1s() to take a list of source files, rather than |
422 |
source.sourcepackagerelease.files] |
423 |
destination_sha1s = self.archive.getFilesAndSha1s(source_files) |
|
10652.3.2
by Steve Kowalik
Change some variable names, from a suggestion from noodles |
424 |
for lf in source.sourcepackagerelease.files: |
10827.6.4
by Steve Kowalik
* Write IArchive.getFilesAndSha1s() that returns the filenames and sha1s for |
425 |
if lf.libraryfile.filename in destination_sha1s: |
10827.2.1
by Steve Kowalik
Compare the sha1 of the files, since comparing the LFA objects themselves is wrong. Add a test that checks that. |
426 |
sha1 = lf.libraryfile.content.sha1 |
10827.6.4
by Steve Kowalik
* Write IArchive.getFilesAndSha1s() that returns the filenames and sha1s for |
427 |
if sha1 != destination_sha1s[lf.libraryfile.filename]: |
10561.2.2
by Steve Kowalik
Re-order the conflicting files check to the end to avoid stomping over the other checks performed. |
428 |
raise CannotCopy( |
429 |
"%s already exists in destination archive with " |
|
10652.3.2
by Steve Kowalik
Change some variable names, from a suggestion from noodles |
430 |
"different contents." % lf.libraryfile.filename) |
10561.2.2
by Steve Kowalik
Re-order the conflicting files check to the end to avoid stomping over the other checks performed. |
431 |
|
12981.1.2
by Raphael Badin
Roll back 12977. |
432 |
def checkCopy(self, source, series, pocket, person=None, |
433 |
check_permissions=True): |
|
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
434 |
"""Check if the source can be copied to the given location.
|
435 |
||
436 |
Check possible conflicting publications in the destination archive.
|
|
437 |
See `_checkArchiveConflicts()`.
|
|
438 |
||
439 |
Also checks if the version of the source being copied is equal or
|
|
440 |
higher than any version of the same source present in the
|
|
441 |
destination suite (series + pocket).
|
|
442 |
||
12981.1.2
by Raphael Badin
Roll back 12977. |
443 |
If person is not None, check that this person has upload rights to
|
444 |
the destination (archive, component, pocket).
|
|
445 |
||
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
446 |
:param source: copy candidate, `ISourcePackagePublishingHistory`.
|
447 |
:param series: destination `IDistroSeries`.
|
|
448 |
:param pocket: destination `PackagePublishingPocket`.
|
|
12981.1.2
by Raphael Badin
Roll back 12977. |
449 |
:param person: requester `IPerson`.
|
450 |
:param check_permissions: boolean indicating whether or not the
|
|
451 |
requester's permissions to copy should be checked.
|
|
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
452 |
|
453 |
:raise CannotCopy when a copy is not allowed to be performed
|
|
454 |
containing the reason of the error.
|
|
455 |
"""
|
|
12981.1.2
by Raphael Badin
Roll back 12977. |
456 |
if check_permissions: |
13007.1.2
by Jeroen Vermeulen
Tests passing. |
457 |
check_copy_permissions( |
458 |
person, self.archive, series, pocket, |
|
13007.1.9
by Jeroen Vermeulen
Last-minute fix: check_copy_permissions now takes a list of SPNs, not just one SPN. |
459 |
[source.sourcepackagerelease.sourcepackagename]) |
12981.1.2
by Raphael Badin
Roll back 12977. |
460 |
|
9965.4.1
by Jelmer Vernooij
Allow copies between distributions as long as the target distroseries exists for the target distribution. |
461 |
if series not in self.archive.distribution.series: |
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
462 |
raise CannotCopy( |
9965.4.1
by Jelmer Vernooij
Allow copies between distributions as long as the target distroseries exists for the target distribution. |
463 |
"No such distro series %s in distribution %s." % |
464 |
(series.name, source.distroseries.distribution.name)) |
|
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
465 |
|
7675.424.28
by William Grant
s/SourceFormatSelection/SourcePackageFormatSelection/, and make it use an enum instead. |
466 |
format = SourcePackageFormat.getTermByToken( |
467 |
source.sourcepackagerelease.dsc_format).value |
|
468 |
||
7675.424.30
by William Grant
Fix token lookup in the copier. |
469 |
if not series.isSourcePackageFormatPermitted(format): |
7675.424.22
by William Grant
Forbid source copies to series that do not support the necessary format. |
470 |
raise CannotCopy( |
471 |
"Source format '%s' not supported by target series %s." % |
|
472 |
(source.sourcepackagerelease.dsc_format, series.name)) |
|
473 |
||
10806.1.1
by Steve Kowalik
Refuse to copy expired sources. |
474 |
# Deny copies of source publications containing files with an
|
475 |
# expiration date set.
|
|
476 |
for source_file in source.sourcepackagerelease.files: |
|
477 |
if source_file.libraryfile.expires is not None: |
|
478 |
raise CannotCopy('source contains expired files') |
|
479 |
||
13168.12.23
by Raphael Badin
Refactor initialization to use the packagecopier if the destination archive is not empty. |
480 |
if self.include_binaries and self.strict_binaries: |
12301.2.5
by William Grant
Use getBuiltBinaries(want_files) in checkCopy's expiry check, eliminating hundreds of queries from large copies. |
481 |
built_binaries = source.getBuiltBinaries(want_files=True) |
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
482 |
if len(built_binaries) == 0: |
483 |
raise CannotCopy("source has no binaries to be copied") |
|
484 |
# Deny copies of binary publications containing files with
|
|
485 |
# expiration date set. We only set such value for immediate
|
|
486 |
# expiration of old superseded binaries, so no point in
|
|
487 |
# checking its content, the fact it is set is already enough
|
|
488 |
# for denying the copy.
|
|
489 |
for binary_pub in built_binaries: |
|
490 |
for binary_file in binary_pub.binarypackagerelease.files: |
|
491 |
if binary_file.libraryfile.expires is not None: |
|
492 |
raise CannotCopy('source has expired binaries') |
|
14191.2.3
by Julian Edwards
Prevent copying of DDEBs into primary archives. |
493 |
if (self.archive.is_main and |
494 |
binary_file.filetype == BinaryPackageFileType.DDEB): |
|
495 |
raise CannotCopy( |
|
496 |
"Cannot copy DDEBs to a primary archive") |
|
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
497 |
|
498 |
# Check if there is already a source with the same name and version
|
|
499 |
# published in the destination archive.
|
|
500 |
self._checkArchiveConflicts(source, series) |
|
501 |
||
502 |
ancestry = source.getAncestry( |
|
503 |
self.archive, series, pocket, status=active_publishing_status) |
|
504 |
if ancestry is not None: |
|
505 |
ancestry_version = ancestry.sourcepackagerelease.version |
|
506 |
copy_version = source.sourcepackagerelease.version |
|
507 |
apt_pkg.InitSystem() |
|
508 |
if apt_pkg.VersionCompare(copy_version, ancestry_version) < 0: |
|
509 |
raise CannotCopy( |
|
510 |
"version older than the %s published in %s" % |
|
511 |
(ancestry.displayname, ancestry.distroseries.name)) |
|
7954.2.1
by Celso Providelo
Fix bug #340660 (deny copy request that will cause file conflicts in the repository). |
512 |
|
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
513 |
delayed = ( |
514 |
self.allow_delayed_copies and |
|
515 |
not self.archive.private and |
|
516 |
has_restricted_files(source)) |
|
517 |
||
518 |
if delayed: |
|
519 |
upload_conflict = getUtility(IPackageUploadSet).findSourceUpload( |
|
520 |
name=source.sourcepackagerelease.name, |
|
521 |
version=source.sourcepackagerelease.version, |
|
522 |
archive=self.archive, distribution=series.distribution) |
|
523 |
if upload_conflict is not None: |
|
524 |
raise CannotCopy( |
|
525 |
'same version already uploaded and waiting in '
|
|
526 |
'ACCEPTED queue') |
|
527 |
||
528 |
# Copy is approved, update the copy inventory.
|
|
529 |
self.addCopy(source, delayed) |
|
7548.3.1
by Celso Providelo
Fixing bug #316424 (denying copies of private sources to public archives). |
530 |
|
531 |
||
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
532 |
def do_copy(sources, archive, series, pocket, include_binaries=False, |
7675.1191.29
by Julian Edwards
Add override processing to do_copy |
533 |
allow_delayed_copies=True, person=None, check_permissions=True, |
13403.2.1
by Raphael Badin
Add a parameter to control the creation of dsd jobs. |
534 |
overrides=None, send_email=False, strict_binaries=True, |
14421.2.2
by Julian Edwards
Fix packagecopier to accept a "sponsored" IPerson for sponsored syncs/copies. |
535 |
close_bugs=True, create_dsd_job=True, announce_from_person=None, |
536 |
sponsored=None): |
|
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
537 |
"""Perform the complete copy of the given sources incrementally.
|
538 |
||
539 |
Verifies if each copy can be performed using `CopyChecker` and
|
|
540 |
raises `CannotCopy` if one or more copies could not be performed.
|
|
541 |
||
14168.3.1
by Jeroen Vermeulen
Make get_recipients a bit easier to follow. |
542 |
When `CannotCopy` is raised, call sites are responsible for rolling
|
543 |
back the transaction. Otherwise, performed copies will be commited.
|
|
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
544 |
|
545 |
Wrapper for `do_direct_copy`.
|
|
546 |
||
12981.1.2
by Raphael Badin
Roll back 12977. |
547 |
:param sources: a list of `ISourcePackagePublishingHistory`.
|
548 |
:param archive: the target `IArchive`.
|
|
549 |
:param series: the target `IDistroSeries`, if None is given the same
|
|
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
550 |
current source distroseries will be used as destination.
|
12981.1.2
by Raphael Badin
Roll back 12977. |
551 |
:param pocket: the target `PackagePublishingPocket`.
|
552 |
:param include_binaries: optional boolean, controls whether or
|
|
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
553 |
not the published binaries for each given source should be also
|
554 |
copied along with the source.
|
|
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
555 |
:param allow_delayed_copies: boolean indicating whether or not private
|
556 |
sources can be copied to public archives using delayed_copies.
|
|
557 |
Defaults to True, only set as False in the UnembargoPackage context.
|
|
12981.1.2
by Raphael Badin
Roll back 12977. |
558 |
:param person: the requester `IPerson`.
|
559 |
:param check_permissions: boolean indicating whether or not the
|
|
560 |
requester's permissions to copy should be checked.
|
|
7675.1191.29
by Julian Edwards
Add override processing to do_copy |
561 |
:param overrides: A list of `IOverride` as returned from one of the copy
|
562 |
policies which will be used as a manual override insyead of using the
|
|
563 |
default override returned by IArchive.getOverridePolicy(). There
|
|
564 |
must be the same number of overrides as there are sources and each
|
|
565 |
override must be for the corresponding source in the sources list.
|
|
566 |
Overrides will be ignored for delayed copies.
|
|
13136.1.2
by Steve Kowalik
Clean up the e-mail body when we have no changes file. |
567 |
:param send_email: Should we notify for the copy performed?
|
13697.7.4
by Julian Edwards
Changes from allenap's review. |
568 |
NOTE: If running in zopeless mode, the email is sent even if the
|
569 |
transaction is later aborted. (See bug 29744)
|
|
13543.4.3
by Julian Edwards
Make sure that announcement emails for syncs into distros are sent from the |
570 |
:param announce_from_person: If send_email is True,
|
571 |
then send announcement emails with this person as the From:
|
|
13168.12.32
by Raphael Badin
Apply MP's comments. |
572 |
:param strict_binaries: If 'include_binaries' is True then setting this
|
573 |
to True will make the copy fail if binaries cannot be also copied.
|
|
13403.3.1
by Raphael Badin
Do not close bugs on the copied publication when initializing. |
574 |
:param close_bugs: A boolean indicating whether or not bugs on the
|
575 |
copied publications should be closed.
|
|
13457.4.4
by Raphael Badin
Create DSDJs outside the packages copy loop. |
576 |
:param create_dsd_job: A boolean indicating whether or not a dsd job
|
577 |
should be created for the new source publication.
|
|
14421.2.2
by Julian Edwards
Fix packagecopier to accept a "sponsored" IPerson for sponsored syncs/copies. |
578 |
:param sponsored: An `IPerson` representing the person who is
|
579 |
being sponsored for this copy. May be None, but if present will
|
|
580 |
affect the "From:" address on notifications and the creator of the
|
|
581 |
publishing record will be set to this person.
|
|
13403.3.1
by Raphael Badin
Do not close bugs on the copied publication when initializing. |
582 |
|
6455.2.2
by Celso Providelo
moving the auxiliary copy-methos to scripts/packagecopier.py. |
583 |
|
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
584 |
:raise CannotCopy when one or more copies were not allowed. The error
|
585 |
will contain the reason why each copy was denied.
|
|
586 |
||
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
587 |
:return: a list of `ISourcePackagePublishingHistory` and
|
588 |
`BinaryPackagePublishingHistory` corresponding to the copied
|
|
589 |
publications.
|
|
590 |
"""
|
|
591 |
copies = [] |
|
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
592 |
errors = [] |
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
593 |
copy_checker = CopyChecker( |
13168.12.23
by Raphael Badin
Refactor initialization to use the packagecopier if the destination archive is not empty. |
594 |
archive, include_binaries, allow_delayed_copies, |
595 |
strict_binaries=strict_binaries) |
|
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
596 |
|
597 |
for source in sources: |
|
598 |
if series is None: |
|
599 |
destination_series = source.distroseries |
|
600 |
else: |
|
601 |
destination_series = series |
|
602 |
try: |
|
12981.1.2
by Raphael Badin
Roll back 12977. |
603 |
copy_checker.checkCopy( |
604 |
source, destination_series, pocket, person, check_permissions) |
|
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
605 |
except CannotCopy, reason: |
606 |
errors.append("%s (%s)" % (source.displayname, reason)) |
|
607 |
continue
|
|
608 |
||
609 |
if len(errors) != 0: |
|
13697.7.2
by Julian Edwards
Code somewhat fixed. |
610 |
error_text = "\n".join(errors) |
611 |
if send_email: |
|
612 |
source = sources[0] |
|
13697.7.4
by Julian Edwards
Changes from allenap's review. |
613 |
# Although the interface allows multiple sources to be copied
|
614 |
# at once, we can only send rejection email if a single source
|
|
615 |
# is specified for now. This is only relied on by packagecopyjob
|
|
616 |
# which will only process one package at a time. We need to
|
|
617 |
# make the notification code handle atomic rejections such that
|
|
618 |
# it notifies about multiple packages.
|
|
13697.7.2
by Julian Edwards
Code somewhat fixed. |
619 |
if series is None: |
620 |
series = source.distroseries |
|
13697.7.4
by Julian Edwards
Changes from allenap's review. |
621 |
# In zopeless mode this email will be sent immediately.
|
13697.7.2
by Julian Edwards
Code somewhat fixed. |
622 |
notify( |
623 |
person, source.sourcepackagerelease, [], [], archive, |
|
14168.3.8
by Jeroen Vermeulen
Move recipients gathering back into notify, as per chat w Julian. |
624 |
series, pocket, summary_text=error_text, action='rejected') |
13697.7.2
by Julian Edwards
Code somewhat fixed. |
625 |
raise CannotCopy(error_text) |
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
626 |
|
7675.1191.29
by Julian Edwards
Add override processing to do_copy |
627 |
overrides_index = 0 |
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
628 |
for source in copy_checker.getCheckedCopies(): |
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
629 |
if series is None: |
630 |
destination_series = source.distroseries |
|
631 |
else: |
|
632 |
destination_series = series |
|
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
633 |
if source.delayed: |
634 |
delayed_copy = _do_delayed_copy( |
|
13136.1.1
by Steve Kowalik
First shot at generating notifications from copies. |
635 |
source, archive, destination_series, pocket, |
636 |
include_binaries) |
|
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
637 |
sub_copies = [delayed_copy] |
638 |
else: |
|
7675.1191.31
by Julian Edwards
Fix test failures caused by db-devel merge |
639 |
override = None |
640 |
if overrides: |
|
641 |
override = overrides[overrides_index] |
|
13785.8.21
by Julian Edwards
Make sure old_version is always set regardless of whether we're sending |
642 |
# Make a note of the destination source's version for use
|
643 |
# in sending the email notification and closing bugs.
|
|
644 |
existing = archive.getPublishedSources( |
|
645 |
name=source.sourcepackagerelease.name, exact_match=True, |
|
646 |
status=active_publishing_status, |
|
647 |
distroseries=series, pocket=pocket).first() |
|
648 |
if existing: |
|
649 |
old_version = existing.sourcepackagerelease.version |
|
650 |
else: |
|
651 |
old_version = None |
|
14421.2.2
by Julian Edwards
Fix packagecopier to accept a "sponsored" IPerson for sponsored syncs/copies. |
652 |
if sponsored is not None: |
653 |
announce_from_person = sponsored |
|
654 |
creator = sponsored |
|
655 |
else: |
|
656 |
creator = person |
|
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
657 |
sub_copies = _do_direct_copy( |
13136.1.1
by Steve Kowalik
First shot at generating notifications from copies. |
658 |
source, archive, destination_series, pocket, |
13457.4.4
by Raphael Badin
Create DSDJs outside the packages copy loop. |
659 |
include_binaries, override, close_bugs=close_bugs, |
13785.8.19
by Julian Edwards
Make changes to the packagecopier so it will close bugs for all bugs |
660 |
create_dsd_job=create_dsd_job, |
14421.2.2
by Julian Edwards
Fix packagecopier to accept a "sponsored" IPerson for sponsored syncs/copies. |
661 |
close_bugs_since_version=old_version, creator=creator) |
13136.1.2
by Steve Kowalik
Clean up the e-mail body when we have no changes file. |
662 |
if send_email: |
663 |
notify( |
|
664 |
person, source.sourcepackagerelease, [], [], archive, |
|
14168.3.4
by Jeroen Vermeulen
Externalize recipients gathering for soyuz upload notifications. |
665 |
destination_series, pocket, action='accepted', |
13755.2.15
by Julian Edwards
re-instate backed out changes and move the aggregate_changelog method to SPPH and make it parse changelog instead of iterating over many changelog_entry |
666 |
announce_from_person=announce_from_person, |
14168.3.8
by Jeroen Vermeulen
Move recipients gathering back into notify, as per chat w Julian. |
667 |
previous_version=old_version) |
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
668 |
|
7675.1191.29
by Julian Edwards
Add override processing to do_copy |
669 |
overrides_index += 1 |
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
670 |
copies.extend(sub_copies) |
671 |
||
672 |
return copies |
|
673 |
||
674 |
||
7675.1191.29
by Julian Edwards
Add override processing to do_copy |
675 |
def _do_direct_copy(source, archive, series, pocket, include_binaries, |
13785.8.19
by Julian Edwards
Make changes to the packagecopier so it will close bugs for all bugs |
676 |
override=None, close_bugs=True, create_dsd_job=True, |
14017.1.1
by Raphael Badin
Code changes for the creation of spph.creator. |
677 |
close_bugs_since_version=None, creator=None): |
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
678 |
"""Copy publishing records to another location.
|
679 |
||
6455.2.2
by Celso Providelo
moving the auxiliary copy-methos to scripts/packagecopier.py. |
680 |
Copy each item of the given list of `SourcePackagePublishingHistory`
|
6755.4.2
by Celso Providelo
Fixing bug #251492 (Avoid duplications copying packages incrementally and removing check denying copies of source with in-progress builds or with unpublished binaries). |
681 |
to the given destination if they are not yet available (previously
|
682 |
copied).
|
|
683 |
||
684 |
Also copy published binaries for each source if requested to. Again,
|
|
685 |
only copy binaries that were not yet copied before.
|
|
6455.2.2
by Celso Providelo
moving the auxiliary copy-methos to scripts/packagecopier.py. |
686 |
|
12981.1.2
by Raphael Badin
Roll back 12977. |
687 |
:param source: an `ISourcePackagePublishingHistory`.
|
688 |
:param archive: the target `IArchive`.
|
|
689 |
:param series: the target `IDistroSeries`, if None is given the same
|
|
7675.235.5
by Celso Providelo
applying review comments, r=abentley. |
690 |
current source distroseries will be used as destination.
|
12981.1.2
by Raphael Badin
Roll back 12977. |
691 |
:param pocket: the target `PackagePublishingPocket`.
|
692 |
:param include_binaries: optional boolean, controls whether or
|
|
6455.2.2
by Celso Providelo
moving the auxiliary copy-methos to scripts/packagecopier.py. |
693 |
not the published binaries for each given source should be also
|
7675.235.5
by Celso Providelo
applying review comments, r=abentley. |
694 |
copied along with the source.
|
7675.1191.29
by Julian Edwards
Add override processing to do_copy |
695 |
:param override: An `IOverride` as per do_copy().
|
13403.3.1
by Raphael Badin
Do not close bugs on the copied publication when initializing. |
696 |
:param close_bugs: A boolean indicating whether or not bugs on the
|
697 |
copied publication should be closed.
|
|
13457.4.4
by Raphael Badin
Create DSDJs outside the packages copy loop. |
698 |
:param create_dsd_job: A boolean indicating whether or not a dsd job
|
699 |
should be created for the new source publication.
|
|
13785.8.19
by Julian Edwards
Make changes to the packagecopier so it will close bugs for all bugs |
700 |
:param close_bugs_since_version: If close_bugs is True,
|
701 |
then this parameter says which changelog entries to parse looking
|
|
702 |
for bugs to close. See `close_bugs_for_sourcepackagerelease`.
|
|
14017.1.1
by Raphael Badin
Code changes for the creation of spph.creator. |
703 |
:param creator: the requester `IPerson`.
|
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
704 |
|
6455.2.3
by Celso Providelo
Fixing bug #237353 (Duplicated arch-indep copies causes confusion in domination sub-system). Unifying copy-package backend, now both, UI and scripts, use check_copy/do_copy functions which is safe agains duplications and other problematic copies. |
705 |
:return: a list of `ISourcePackagePublishingHistory` and
|
6455.2.2
by Celso Providelo
moving the auxiliary copy-methos to scripts/packagecopier.py. |
706 |
`BinaryPackagePublishingHistory` corresponding to the copied
|
707 |
publications.
|
|
708 |
"""
|
|
709 |
copies = [] |
|
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
710 |
|
711 |
# Copy source if it's not yet copied.
|
|
712 |
source_in_destination = archive.getPublishedSources( |
|
713 |
name=source.sourcepackagerelease.name, exact_match=True, |
|
714 |
version=source.sourcepackagerelease.version, |
|
715 |
status=active_publishing_status, |
|
716 |
distroseries=series, pocket=pocket) |
|
7675.1174.2
by Julian Edwards
fix my stupidity |
717 |
policy = archive.getOverridePolicy() |
12505.4.1
by Robert Collins
Hopefully fix bug 727560 by permitting a much better query plan for folk querying the primary archive. |
718 |
if source_in_destination.is_empty(): |
7675.1191.29
by Julian Edwards
Add override processing to do_copy |
719 |
# If no manual overrides were specified and the archive has an
|
720 |
# override policy then use that policy to get overrides.
|
|
721 |
if override is None and policy is not None: |
|
7675.1174.2
by Julian Edwards
fix my stupidity |
722 |
package_names = (source.sourcepackagerelease.sourcepackagename,) |
7675.1181.4
by Julian Edwards
fix the silly list arguemnt for overrides on copyTo since it will only ever override a single source |
723 |
# Only one override can be returned so take the first
|
724 |
# element of the returned list.
|
|
7675.1181.12
by Julian Edwards
fix bustage caused by merging db-devel that had jtv's changes to the job schema. |
725 |
overrides = policy.calculateSourceOverrides( |
726 |
archive, series, pocket, package_names) |
|
7675.1181.4
by Julian Edwards
fix the silly list arguemnt for overrides on copyTo since it will only ever override a single source |
727 |
# Only one override can be returned so take the first
|
728 |
# element of the returned list.
|
|
7675.1181.9
by Julian Edwards
Stupid typos R me |
729 |
assert len(overrides) == 1, ( |
7675.1181.8
by Julian Edwards
review comments from allenap |
730 |
"More than one override encountered, something is wrong.") |
7675.1181.9
by Julian Edwards
Stupid typos R me |
731 |
override = overrides[0] |
13403.2.1
by Raphael Badin
Add a parameter to control the creation of dsd jobs. |
732 |
source_copy = source.copyTo( |
14017.1.1
by Raphael Badin
Code changes for the creation of spph.creator. |
733 |
series, pocket, archive, override, create_dsd_job=create_dsd_job, |
734 |
creator=creator) |
|
13403.3.1
by Raphael Badin
Do not close bugs on the copied publication when initializing. |
735 |
if close_bugs: |
13785.8.19
by Julian Edwards
Make changes to the packagecopier so it will close bugs for all bugs |
736 |
close_bugs_for_sourcepublication( |
737 |
source_copy, close_bugs_since_version) |
|
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
738 |
copies.append(source_copy) |
739 |
else: |
|
12505.4.1
by Robert Collins
Hopefully fix bug 727560 by permitting a much better query plan for folk querying the primary archive. |
740 |
source_copy = source_in_destination.first() |
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
741 |
|
742 |
if not include_binaries: |
|
7399.1.1
by Celso Providelo
Try to create missing builds when copying packages, even when copying binaries. It makes copies to distroseries with new architectures more efficient and useful. |
743 |
source_copy.createMissingBuilds() |
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
744 |
return copies |
745 |
||
746 |
# Copy missing binaries for the matching architectures in the
|
|
747 |
# destination series. ISPPH.getBuiltBinaries() return only
|
|
7675.235.5
by Celso Providelo
applying review comments, r=abentley. |
748 |
# unique publication per binary package releases (i.e. excludes
|
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
749 |
# irrelevant arch-indep publications) and IBPPH.copy is prepared
|
750 |
# to expand arch-indep publications.
|
|
13168.12.28
by Raphael Badin
Check emptiness of binaries inside copyBinariesTo. |
751 |
binary_copies = getUtility(IPublishingSet).copyBinariesTo( |
752 |
source.getBuiltBinaries(), series, pocket, archive, policy=policy) |
|
9792.2.5
by Michael Nelson
Updated the packagecopier script to use the new copyBinariesTo utility method. |
753 |
|
13168.12.33
by Raphael Badin
Raise InitializationError if do_copy raises CannotCopy. |
754 |
if binary_copies is not None: |
755 |
copies.extend(binary_copies) |
|
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
756 |
|
757 |
# Always ensure the needed builds exist in the copy destination
|
|
758 |
# after copying the binaries.
|
|
759 |
source_copy.createMissingBuilds() |
|
7399.1.1
by Celso Providelo
Try to create missing builds when copying packages, even when copying binaries. It makes copies to distroseries with new architectures more efficient and useful. |
760 |
|
6455.2.2
by Celso Providelo
moving the auxiliary copy-methos to scripts/packagecopier.py. |
761 |
return copies |
762 |
||
763 |
||
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
764 |
class DelayedCopy: |
765 |
"""Decorates `IPackageUpload` with a more descriptive 'displayname'."""
|
|
766 |
||
767 |
delegates(IPackageUpload) |
|
768 |
||
769 |
def __init__(self, context): |
|
770 |
self.context = context |
|
771 |
||
772 |
@property
|
|
773 |
def displayname(self): |
|
774 |
return 'Delayed copy of %s (%s)' % ( |
|
775 |
self.context.sourcepackagerelease.title, |
|
776 |
self.context.displayarchs) |
|
777 |
||
778 |
||
7675.235.5
by Celso Providelo
applying review comments, r=abentley. |
779 |
def _do_delayed_copy(source, archive, series, pocket, include_binaries): |
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
780 |
"""Schedule the given source for copy.
|
781 |
||
7675.235.5
by Celso Providelo
applying review comments, r=abentley. |
782 |
Schedule the copy of each item of the given list of
|
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
783 |
`SourcePackagePublishingHistory` to the given destination.
|
784 |
||
785 |
Also include published builds for each source if requested to.
|
|
786 |
||
12981.1.2
by Raphael Badin
Roll back 12977. |
787 |
:param source: an `ISourcePackagePublishingHistory`.
|
788 |
:param archive: the target `IArchive`.
|
|
789 |
:param series: the target `IDistroSeries`.
|
|
790 |
:param pocket: the target `PackagePublishingPocket`.
|
|
791 |
:param include_binaries: optional boolean, controls whether or
|
|
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
792 |
not the published binaries for each given source should be also
|
7675.235.5
by Celso Providelo
applying review comments, r=abentley. |
793 |
copied along with the source.
|
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
794 |
|
795 |
:return: a list of `IPackageUpload` corresponding to the publications
|
|
796 |
scheduled for copy.
|
|
797 |
"""
|
|
7675.235.5
by Celso Providelo
applying review comments, r=abentley. |
798 |
# XXX cprov 2009-06-22 bug=385503: At some point we will change
|
799 |
# the copy signature to allow a user to be passed in, so will
|
|
800 |
# be able to annotate that information in delayed copied as well,
|
|
801 |
# by using the right key. For now it's undefined.
|
|
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
802 |
# See also the comment on acceptFromCopy()
|
803 |
delayed_copy = getUtility(IPackageUploadSet).createDelayedCopy( |
|
804 |
archive, series, pocket, None) |
|
805 |
||
806 |
# Include the source and any custom upload.
|
|
807 |
delayed_copy.addSource(source.sourcepackagerelease) |
|
808 |
original_source_upload = source.sourcepackagerelease.package_upload |
|
809 |
for custom in original_source_upload.customfiles: |
|
810 |
delayed_copy.addCustom( |
|
811 |
custom.libraryfilealias, custom.customformat) |
|
812 |
||
7675.235.5
by Celso Providelo
applying review comments, r=abentley. |
813 |
# If binaries are included in the copy we include binary custom files.
|
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
814 |
if include_binaries: |
815 |
for build in source.getBuilds(): |
|
12177.12.5
by William Grant
do_delayed_copy no longer copies builds without a corresponding enabled architecture in the target series. |
816 |
# Don't copy builds that aren't yet done, or those without a
|
817 |
# corresponding enabled architecture in the new series.
|
|
818 |
try: |
|
819 |
target_arch = series[build.arch_tag] |
|
820 |
except NotFoundError: |
|
821 |
continue
|
|
822 |
if (not target_arch.enabled or |
|
823 |
build.status != BuildStatus.FULLYBUILT): |
|
7675.254.1
by Celso Providelo
Fixing the way we handle delayed-copies of partially built sources. |
824 |
continue
|
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
825 |
delayed_copy.addBuild(build) |
826 |
original_build_upload = build.package_upload |
|
827 |
for custom in original_build_upload.customfiles: |
|
828 |
delayed_copy.addCustom( |
|
829 |
custom.libraryfilealias, custom.customformat) |
|
830 |
||
7675.235.5
by Celso Providelo
applying review comments, r=abentley. |
831 |
# XXX cprov 2009-06-22 bug=385503: when we have a 'user' responsible
|
832 |
# for the copy we can also decide whether a copy should be immediately
|
|
833 |
# accepted or moved to the UNAPPROVED queue, based on the user's
|
|
834 |
# permission to the destination context.
|
|
835 |
||
836 |
# Accept the delayed-copy, which implicitly verifies if it fits
|
|
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
837 |
# the destination context.
|
838 |
delayed_copy.acceptFromCopy() |
|
839 |
||
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
840 |
return DelayedCopy(delayed_copy) |
7675.235.3
by Celso Providelo
Extract do_direct_copy() and implement do_delayed_copy() with the same signature. Very soon we can embed the decision to whether copying with direct or delayed mode in do_copy(). |
841 |
|
842 |
||
6455.2.1
by Celso Providelo
Moving PackageCopier & UnembargoSecurityPackage script classes out of ftpmaster.py file. |
843 |
class PackageCopier(SoyuzScript): |
844 |
"""SoyuzScript that copies published packages between locations.
|
|
845 |
||
846 |
Possible exceptions raised are:
|
|
847 |
* PackageLocationError: specified package or distro does not exist
|
|
848 |
* PackageCopyError: the copy operation itself has failed
|
|
849 |
* LaunchpadScriptFailure: only raised if entering via main(), ie this
|
|
850 |
code is running as a genuine script. In this case, this is
|
|
851 |
also the _only_ exception to be raised.
|
|
852 |
||
853 |
The test harness doesn't enter via main(), it calls doCopy(), so
|
|
854 |
it only sees the first two exceptions.
|
|
855 |
"""
|
|
856 |
||
857 |
usage = '%prog -s warty mozilla-firefox --to-suite hoary' |
|
858 |
description = 'MOVE or COPY a published package to another suite.' |
|
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
859 |
allow_delayed_copies = True |
6455.2.1
by Celso Providelo
Moving PackageCopier & UnembargoSecurityPackage script classes out of ftpmaster.py file. |
860 |
|
861 |
def add_my_options(self): |
|
862 |
||
863 |
SoyuzScript.add_my_options(self) |
|
864 |
||
865 |
self.parser.add_option( |
|
866 |
"-b", "--include-binaries", dest="include_binaries", |
|
867 |
default=False, action="store_true", |
|
868 |
help='Whether to copy related binaries or not.') |
|
869 |
||
870 |
self.parser.add_option( |
|
871 |
'--to-distribution', dest='to_distribution', |
|
872 |
default='ubuntu', action='store', |
|
873 |
help='Destination distribution name.') |
|
874 |
||
875 |
self.parser.add_option( |
|
876 |
'--to-suite', dest='to_suite', default=None, |
|
877 |
action='store', help='Destination suite name.') |
|
878 |
||
879 |
self.parser.add_option( |
|
880 |
'--to-ppa', dest='to_ppa', default=None, |
|
881 |
action='store', help='Destination PPA owner name.') |
|
882 |
||
883 |
self.parser.add_option( |
|
7548.5.5
by Julian Edwards
Resurrection part 5 |
884 |
'--to-ppa-name', dest='to_ppa_name', default='ppa', |
885 |
action='store', help='Destination PPA name.') |
|
886 |
||
887 |
self.parser.add_option( |
|
6455.2.1
by Celso Providelo
Moving PackageCopier & UnembargoSecurityPackage script classes out of ftpmaster.py file. |
888 |
'--to-partner', dest='to_partner', default=False, |
889 |
action='store_true', help='Destination set to PARTNER archive.') |
|
890 |
||
891 |
def checkCopyOptions(self): |
|
892 |
"""Check if the locations options are sane.
|
|
893 |
||
894 |
* Catch Cross-PARTNER copies, they are not allowed.
|
|
895 |
* Catch simulataneous PPA and PARTNER locations or destinations,
|
|
896 |
results are unpredictable (in fact, the code will ignore PPA and
|
|
897 |
operate only in PARTNER, but that's odd)
|
|
898 |
"""
|
|
899 |
if ((self.options.partner_archive and not self.options.to_partner) |
|
900 |
or (self.options.to_partner and not |
|
901 |
self.options.partner_archive)): |
|
902 |
raise SoyuzScriptError( |
|
903 |
"Cross-PARTNER copies are not allowed.") |
|
904 |
||
905 |
if self.options.archive_owner_name and self.options.partner_archive: |
|
906 |
raise SoyuzScriptError( |
|
907 |
"Cannot operate with location PARTNER and PPA "
|
|
908 |
"simultaneously.") |
|
909 |
||
910 |
if self.options.to_ppa and self.options.to_partner: |
|
911 |
raise SoyuzScriptError( |
|
912 |
"Cannot operate with destination PARTNER and PPA "
|
|
913 |
"simultaneously.") |
|
914 |
||
915 |
def mainTask(self): |
|
916 |
"""Execute package copy procedure.
|
|
917 |
||
918 |
Copy source publication and optionally also copy its binaries by
|
|
919 |
passing '-b' (include_binary) option.
|
|
920 |
||
921 |
Modules using this class outside of its normal usage in the
|
|
922 |
copy-package.py script can call this method to start the copy.
|
|
923 |
||
924 |
In this case the caller can override test_args on __init__
|
|
925 |
to set the command line arguments.
|
|
926 |
||
927 |
Can raise SoyuzScriptError.
|
|
928 |
"""
|
|
929 |
assert self.location, ( |
|
930 |
"location is not available, call PackageCopier.setupLocation() "
|
|
931 |
"before dealing with mainTask.") |
|
932 |
||
933 |
self.checkCopyOptions() |
|
934 |
||
935 |
sourcename = self.args[0] |
|
936 |
||
937 |
self.setupDestination() |
|
938 |
||
939 |
self.logger.info("FROM: %s" % (self.location)) |
|
940 |
self.logger.info("TO: %s" % (self.destination)) |
|
941 |
||
942 |
to_copy = [] |
|
943 |
source_pub = self.findLatestPublishedSource(sourcename) |
|
944 |
to_copy.append(source_pub) |
|
945 |
if self.options.include_binaries: |
|
946 |
to_copy.extend(source_pub.getPublishedBinaries()) |
|
947 |
||
948 |
self.logger.info("Copy candidates:") |
|
949 |
for candidate in to_copy: |
|
950 |
self.logger.info('\t%s' % candidate.displayname) |
|
951 |
||
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
952 |
sources = [source_pub] |
6455.2.3
by Celso Providelo
Fixing bug #237353 (Duplicated arch-indep copies causes confusion in domination sub-system). Unifying copy-package backend, now both, UI and scripts, use check_copy/do_copy functions which is safe agains duplications and other problematic copies. |
953 |
try: |
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
954 |
copies = do_copy( |
955 |
sources, self.destination.archive, |
|
6455.2.3
by Celso Providelo
Fixing bug #237353 (Duplicated arch-indep copies causes confusion in domination sub-system). Unifying copy-package backend, now both, UI and scripts, use check_copy/do_copy functions which is safe agains duplications and other problematic copies. |
956 |
self.destination.distroseries, self.destination.pocket, |
12981.1.2
by Raphael Badin
Roll back 12977. |
957 |
self.options.include_binaries, self.allow_delayed_copies, |
958 |
check_permissions=False) |
|
8730.2.2
by Celso Providelo
Fixes bug #387613 (changing do_copy() to identify conflicting candidates in the same batch keeping its transactional behavior without relying on the DB transaction to be aborted). |
959 |
except CannotCopy, error: |
960 |
self.logger.error(str(error)) |
|
6455.2.3
by Celso Providelo
Fixing bug #237353 (Duplicated arch-indep copies causes confusion in domination sub-system). Unifying copy-package backend, now both, UI and scripts, use check_copy/do_copy functions which is safe agains duplications and other problematic copies. |
961 |
return [] |
962 |
||
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
963 |
self.logger.info("Copied:") |
964 |
for copy in copies: |
|
965 |
self.logger.info('\t%s' % copy.displayname) |
|
966 |
||
6455.2.1
by Celso Providelo
Moving PackageCopier & UnembargoSecurityPackage script classes out of ftpmaster.py file. |
967 |
if len(copies) == 1: |
968 |
self.logger.info( |
|
969 |
"%s package successfully copied." % len(copies)) |
|
970 |
elif len(copies) > 1: |
|
971 |
self.logger.info( |
|
972 |
"%s packages successfully copied." % len(copies)) |
|
973 |
else: |
|
6876.4.1
by Celso Providelo
Fixing misleading copy-package script output. |
974 |
self.logger.info("No packages copied.") |
6455.2.1
by Celso Providelo
Moving PackageCopier & UnembargoSecurityPackage script classes out of ftpmaster.py file. |
975 |
|
976 |
# Information returned mainly for the benefit of the test harness.
|
|
977 |
return copies |
|
978 |
||
979 |
def setupDestination(self): |
|
980 |
"""Build PackageLocation for the destination context."""
|
|
981 |
if self.options.to_partner: |
|
982 |
self.destination = build_package_location( |
|
983 |
self.options.to_distribution, |
|
984 |
self.options.to_suite, |
|
985 |
ArchivePurpose.PARTNER) |
|
986 |
elif self.options.to_ppa: |
|
987 |
self.destination = build_package_location( |
|
988 |
self.options.to_distribution, |
|
989 |
self.options.to_suite, |
|
990 |
ArchivePurpose.PPA, |
|
7548.5.5
by Julian Edwards
Resurrection part 5 |
991 |
self.options.to_ppa, |
992 |
self.options.to_ppa_name) |
|
6455.2.1
by Celso Providelo
Moving PackageCopier & UnembargoSecurityPackage script classes out of ftpmaster.py file. |
993 |
else: |
994 |
self.destination = build_package_location( |
|
995 |
self.options.to_distribution, |
|
996 |
self.options.to_suite) |
|
997 |
||
998 |
if self.location == self.destination: |
|
999 |
raise SoyuzScriptError( |
|
1000 |
"Can not sync between the same locations: '%s' to '%s'" % ( |
|
1001 |
self.location, self.destination)) |
|
1002 |
||
1003 |
||
1004 |
class UnembargoSecurityPackage(PackageCopier): |
|
1005 |
"""`SoyuzScript` that unembargoes security packages and their builds.
|
|
1006 |
||
1007 |
Security builds are done in the ubuntu-security private PPA.
|
|
1008 |
When they are ready to be unembargoed, this script will copy
|
|
1009 |
them from the PPA to the Ubuntu archive and re-upload any files
|
|
1010 |
from the restricted librarian into the non-restricted one.
|
|
1011 |
||
1012 |
This script simply wraps up PackageCopier with some nicer options,
|
|
1013 |
and implements the file re-uploading.
|
|
1014 |
||
1015 |
An assumption is made, to reduce the number of command line options,
|
|
7250.4.5
by Julian Edwards
Expand on the class docstring to talk about the staging via -proposed. |
1016 |
that packages are always copied between the same distroseries. The user
|
1017 |
can, however, select which target pocket to unembargo into. This is
|
|
1018 |
useful to the security team when there are major version upgrades
|
|
1019 |
and they want to stage it through -proposed first for testing.
|
|
6455.2.1
by Celso Providelo
Moving PackageCopier & UnembargoSecurityPackage script classes out of ftpmaster.py file. |
1020 |
"""
|
1021 |
||
7250.4.1
by Julian Edwards
Allow overiding of the destination suite when unembargoing. |
1022 |
usage = ("%prog [-d <distribution>] [-s <suite>] [--ppa <private ppa>] " |
6455.2.1
by Celso Providelo
Moving PackageCopier & UnembargoSecurityPackage script classes out of ftpmaster.py file. |
1023 |
"<package(s)>") |
1024 |
description = ("Unembargo packages in a private PPA by copying to the " |
|
1025 |
"specified location and re-uploading any files to the "
|
|
1026 |
"unrestricted librarian.") |
|
7675.249.1
by Celso Providelo
Integrating delayed-copies and other minor tweaks (db permissions and build creation for source-only delayed copies). All copy methods (web UI, API and 'copy-package' script) will use delayed-copies instead of direct-copies when file privacy mismatch is detected. 'unembargo-package' continues to work with direct-copies and fixing privacy mismatch in place. |
1027 |
allow_delayed_copies = False |
6455.2.1
by Celso Providelo
Moving PackageCopier & UnembargoSecurityPackage script classes out of ftpmaster.py file. |
1028 |
|
1029 |
def add_my_options(self): |
|
1030 |
"""Add -d, -s, dry-run and confirmation options."""
|
|
1031 |
SoyuzScript.add_distro_options(self) |
|
1032 |
SoyuzScript.add_transaction_options(self) |
|
1033 |
||
1034 |
self.parser.add_option( |
|
1035 |
"-p", "--ppa", dest="archive_owner_name", |
|
1036 |
default="ubuntu-security", action="store", |
|
1037 |
help="Private PPA owner's name.") |
|
1038 |
||
7548.5.5
by Julian Edwards
Resurrection part 5 |
1039 |
self.parser.add_option( |
1040 |
"--ppa-name", dest="archive_name", |
|
1041 |
default="ppa", action="store", |
|
1042 |
help="Private PPA name.") |
|
1043 |
||
7250.4.1
by Julian Edwards
Allow overiding of the destination suite when unembargoing. |
1044 |
def setUpCopierOptions(self): |
7250.4.4
by Julian Edwards
Don't assume -security any more; explicitly fail the operation if someone forgets to supply a pocket. |
1045 |
"""Set up options needed by PackageCopier.
|
7399.1.3
by Celso Providelo
Modifying ISPPH.getBuiltBinaries() and IBPPH.copyTo to deal easily with arch-indep binaries. |
1046 |
|
7250.4.4
by Julian Edwards
Don't assume -security any more; explicitly fail the operation if someone forgets to supply a pocket. |
1047 |
:return: False if there is a problem with the options.
|
1048 |
"""
|
|
6455.2.1
by Celso Providelo
Moving PackageCopier & UnembargoSecurityPackage script classes out of ftpmaster.py file. |
1049 |
# Set up the options for PackageCopier that are needed in addition
|
1050 |
# to the ones that this class sets up.
|
|
1051 |
self.options.to_partner = False |
|
1052 |
self.options.to_ppa = False |
|
1053 |
self.options.partner_archive = None |
|
1054 |
self.options.include_binaries = True |
|
1055 |
self.options.to_distribution = self.options.distribution_name |
|
7250.4.4
by Julian Edwards
Don't assume -security any more; explicitly fail the operation if someone forgets to supply a pocket. |
1056 |
from_suite = self.options.suite.split("-") |
1057 |
if len(from_suite) == 1: |
|
1058 |
self.logger.error("Can't unembargo into the release pocket") |
|
1059 |
return False |
|
7250.4.1
by Julian Edwards
Allow overiding of the destination suite when unembargoing. |
1060 |
else: |
7250.4.4
by Julian Edwards
Don't assume -security any more; explicitly fail the operation if someone forgets to supply a pocket. |
1061 |
# The PackageCopier parent class uses options.suite as the
|
1062 |
# source suite, so we need to override it to remove the
|
|
1063 |
# pocket since PPAs are pocket-less.
|
|
7250.4.1
by Julian Edwards
Allow overiding of the destination suite when unembargoing. |
1064 |
self.options.to_suite = self.options.suite |
7250.4.4
by Julian Edwards
Don't assume -security any more; explicitly fail the operation if someone forgets to supply a pocket. |
1065 |
self.options.suite = from_suite[0] |
6455.2.1
by Celso Providelo
Moving PackageCopier & UnembargoSecurityPackage script classes out of ftpmaster.py file. |
1066 |
self.options.version = None |
1067 |
self.options.component = None |
|
1068 |
||
7250.4.4
by Julian Edwards
Don't assume -security any more; explicitly fail the operation if someone forgets to supply a pocket. |
1069 |
return True |
1070 |
||
7250.4.1
by Julian Edwards
Allow overiding of the destination suite when unembargoing. |
1071 |
def mainTask(self): |
1072 |
"""Invoke PackageCopier to copy the package(s) and re-upload files."""
|
|
7250.4.4
by Julian Edwards
Don't assume -security any more; explicitly fail the operation if someone forgets to supply a pocket. |
1073 |
if not self.setUpCopierOptions(): |
1074 |
return None |
|
1075 |
||
1076 |
# Generate the location for PackageCopier after overriding the
|
|
1077 |
# options.
|
|
1078 |
self.setupLocation() |
|
7250.4.1
by Julian Edwards
Allow overiding of the destination suite when unembargoing. |
1079 |
|
6455.2.1
by Celso Providelo
Moving PackageCopier & UnembargoSecurityPackage script classes out of ftpmaster.py file. |
1080 |
# Invoke the package copy operation.
|
1081 |
copies = PackageCopier.mainTask(self) |
|
1082 |
||
8589.3.3
by Celso Providelo
Extracting and testing unembaroging base procedures. |
1083 |
# Fix copies by overriding them according the current ancestry
|
1084 |
# and re-upload files with privacy mismatch.
|
|
6455.2.1
by Celso Providelo
Moving PackageCopier & UnembargoSecurityPackage script classes out of ftpmaster.py file. |
1085 |
for pub_record in copies: |
8720.3.1
by Celso Providelo
PackageCopier cleanup, implementing getAncestry() and overrideFromAncestry() on IPublishing. |
1086 |
pub_record.overrideFromAncestry() |
8589.3.4
by Celso Providelo
name extracted functions appropriately. |
1087 |
for new_file in update_files_privacy(pub_record): |
8589.3.3
by Celso Providelo
Extracting and testing unembaroging base procedures. |
1088 |
self.logger.info( |
1089 |
"Re-uploaded %s to librarian" % new_file.filename) |
|
6455.2.1
by Celso Providelo
Moving PackageCopier & UnembargoSecurityPackage script classes out of ftpmaster.py file. |
1090 |
|
1091 |
# Return this for the benefit of the test suite.
|
|
1092 |
return copies |