3673.6.16
by Malcolm Cleaton
Addressed review comments |
1 |
# Copyright 2006 Canonical Ltd. All rights reserved.
|
2 |
#
|
|
3 |
||
4 |
"""Code for 'processing' 'uploads'. Also see nascentupload.py.
|
|
5 |
||
6 |
Uploads are directories in the 'incoming' queue directory. They may have
|
|
7 |
arrived manually from a distribution contributor, via a poppy upload, or
|
|
8 |
they may have come from a build.
|
|
9 |
||
10 |
Within an upload, we may find no changes file, one, or several. One is
|
|
11 |
the usual number. To process the upload, we process each changes file
|
|
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
12 |
in turn. These changes files may be within a structure of sub-directories,
|
13 |
in which case we extract information from the names of these, to calculate
|
|
14 |
which distribution and which PPA are being uploaded to.
|
|
3673.6.16
by Malcolm Cleaton
Addressed review comments |
15 |
|
16 |
To process a changes file, we make checks such as that the other files
|
|
17 |
referenced by it are present, formatting is valid, signatures are correct,
|
|
18 |
checksums match, and that the .changes file represents an upload which makes
|
|
19 |
sense, eg. it is not a binary for which we have no source, or an older
|
|
4285.2.8
by Mark Shuttleworth
Test fixes for archive uploader |
20 |
version than already exists in the same target distroseries pocket.
|
3673.6.16
by Malcolm Cleaton
Addressed review comments |
21 |
|
22 |
Depending on the outcome of these checks, the changes file will either be
|
|
23 |
accepted (and the information from it, and the referenced files, imported
|
|
24 |
into the database) or it won't (and the database will be unchanged). If not
|
|
25 |
accepted, a changes file might be 'failed' or 'rejected', where failed
|
|
26 |
changes files are dropped silently, but rejected ones generate a rejection
|
|
27 |
email back to the uploader.
|
|
28 |
||
29 |
There are several valid reasons to fail (the changes file is so mangled
|
|
30 |
that we can't read who we should send a rejection to, or it's not correctly
|
|
31 |
signed, so we can't be sure a rejection wouldn't be spam (it may not have
|
|
32 |
been uploaded by who it says it was uploaded by). In practice, in the code
|
|
33 |
as it stands, we also consider the processing of a changes file to have
|
|
34 |
failed if it generates an unexpected exception, and there are some known
|
|
35 |
cases where it does this and a rejection would have been more useful
|
|
36 |
(see bug 35965).
|
|
37 |
||
38 |
Each upload directory is saved after processing, in case it is needed for
|
|
39 |
debugging purposes. This is done by moving it to a directory inside the queue
|
|
40 |
directory, beside incoming, named after the result - 'failed', 'rejected' or
|
|
41 |
'accepted'. Where there are no changes files, the upload is considered failed,
|
|
42 |
and where there is more than one changes file, the upload is assigned the
|
|
43 |
worst of the results from the various changes files found (in the order
|
|
44 |
above, failed being worst).
|
|
45 |
||
46 |
"""
|
|
47 |
||
48 |
__metaclass__ = type |
|
49 |
||
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
50 |
import os |
3804.1.12
by Celso Providelo
Fixing soyuz-set-of-upload and related code. |
51 |
import shutil |
5089.1.2
by Celso Providelo
applying review comments, r=kiko. |
52 |
import stat |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
53 |
|
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
54 |
from zope.component import getUtility |
55 |
||
4197.1.1
by Christian Reis
Break apart upload code into canonical/archiveuploader |
56 |
from canonical.archiveuploader.nascentupload import ( |
4936.3.4
by Julian Edwards
Improve the API for error checking and early rejection. |
57 |
NascentUpload, FatalUploadError, EarlyReturnUploadError) |
4197.1.1
by Christian Reis
Break apart upload code into canonical/archiveuploader |
58 |
from canonical.archiveuploader.uploadpolicy import ( |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
59 |
findPolicyByOptions, UploadPolicyError) |
3691.443.65
by Celso Providelo
Automatically creating PPAs based on the first successfully upload. Adding Archive.description text. |
60 |
from canonical.launchpad.interfaces import ( |
5028.1.2
by David Murphy
Removed ArchivePurpose from canonical.lp.dbschema. |
61 |
ArchivePurpose, IDistributionSet, IPersonSet, NotFoundError) |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
62 |
|
63 |
from contrib.glock import GlobalLock |
|
64 |
||
65 |
__all__ = ['UploadProcessor'] |
|
66 |
||
3673.6.20
by Malcolm Cleaton
Second review comments |
67 |
|
68 |
class UploadStatusEnum: |
|
69 |
"""Possible results from processing an upload.
|
|
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
70 |
|
3673.6.20
by Malcolm Cleaton
Second review comments |
71 |
ACCEPTED: all goes well, we commit nascentupload's changes to the db
|
72 |
REJECTED: nascentupload gives a well-formed rejection error,
|
|
73 |
we send a rejection email and rollback.
|
|
74 |
FAILED: nascentupload code raises an exception, no email, rollback
|
|
75 |
"""
|
|
76 |
ACCEPTED = 'accepted' |
|
77 |
REJECTED = 'rejected' |
|
78 |
FAILED = 'failed' |
|
79 |
||
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
80 |
|
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
81 |
class UploadPathError(Exception): |
82 |
"""This exception happened when parsing the upload path."""
|
|
83 |
||
4810.3.1
by Julian Edwards
PPA upload emails should go to the uploader (and hence package signer) only. |
84 |
class PPAUploadPathError(Exception): |
85 |
"""Exception when parsing a PPA upload path."""
|
|
86 |
||
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
87 |
class UploadProcessor: |
3673.6.16
by Malcolm Cleaton
Addressed review comments |
88 |
"""Responsible for processing uploads. See module docstring."""
|
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
89 |
|
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
90 |
def __init__(self, options, ztm, log): |
91 |
self.options = options |
|
92 |
self.ztm = ztm |
|
93 |
self.log = log |
|
4162.3.2
by Celso Providelo
correct varname. |
94 |
self.last_processed_upload = None |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
95 |
|
3673.6.20
by Malcolm Cleaton
Second review comments |
96 |
def processUploadQueue(self): |
3673.6.16
by Malcolm Cleaton
Addressed review comments |
97 |
"""Search for uploads, and process them.
|
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
98 |
|
3673.6.16
by Malcolm Cleaton
Addressed review comments |
99 |
Uploads are searched for in the 'incoming' directory inside the
|
100 |
base_fsroot.
|
|
101 |
||
102 |
This method also creates the 'incoming', 'accepted', 'rejected', and
|
|
103 |
'failed' directories inside the base_fsroot if they don't yet exist.
|
|
104 |
"""
|
|
3673.6.7
by Malcolm Cleaton
Incorporate peer-review suggestions from dsilvers |
105 |
try: |
106 |
self.log.debug("Beginning processing") |
|
3673.6.16
by Malcolm Cleaton
Addressed review comments |
107 |
|
3673.6.7
by Malcolm Cleaton
Incorporate peer-review suggestions from dsilvers |
108 |
for subdir in ["incoming", "accepted", "rejected", "failed"]: |
109 |
full_subdir = os.path.join(self.options.base_fsroot, subdir) |
|
110 |
if not os.path.exists(full_subdir): |
|
111 |
self.log.debug("Creating directory %s" % full_subdir) |
|
112 |
os.mkdir(full_subdir) |
|
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
113 |
|
3673.6.7
by Malcolm Cleaton
Incorporate peer-review suggestions from dsilvers |
114 |
fsroot = os.path.join(self.options.base_fsroot, "incoming") |
3673.6.16
by Malcolm Cleaton
Addressed review comments |
115 |
uploads_to_process = self.locateDirectories(fsroot) |
3673.6.7
by Malcolm Cleaton
Incorporate peer-review suggestions from dsilvers |
116 |
self.log.debug("Checked in %s, found %s" |
3673.6.16
by Malcolm Cleaton
Addressed review comments |
117 |
% (fsroot, uploads_to_process)) |
118 |
for upload in uploads_to_process: |
|
119 |
self.log.debug("Considering upload %s" % upload) |
|
120 |
self.processUpload(fsroot, upload) |
|
3673.6.7
by Malcolm Cleaton
Incorporate peer-review suggestions from dsilvers |
121 |
|
122 |
finally: |
|
123 |
self.log.debug("Rolling back any remaining transactions.") |
|
124 |
self.ztm.abort() |
|
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
125 |
|
3673.6.16
by Malcolm Cleaton
Addressed review comments |
126 |
def processUpload(self, fsroot, upload): |
127 |
"""Process an upload's changes files, and move it to a new directory.
|
|
128 |
||
129 |
The destination directory depends on the result of the processing
|
|
130 |
of the changes files. If there are no changes files, the result
|
|
131 |
is 'failed', otherwise it is the worst of the results from the
|
|
132 |
individual changes files, in order 'failed', 'rejected', 'accepted'.
|
|
133 |
||
134 |
If the leafname option is set but its value is not the same as the
|
|
135 |
name of the upload directory, skip it entirely.
|
|
136 |
||
137 |
"""
|
|
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
138 |
if (self.options.leafname is not None and |
3673.6.16
by Malcolm Cleaton
Addressed review comments |
139 |
upload != self.options.leafname): |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
140 |
self.log.debug("Skipping %s -- does not match %s" % ( |
3673.6.16
by Malcolm Cleaton
Addressed review comments |
141 |
upload, self.options.leafname)) |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
142 |
return
|
143 |
||
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
144 |
upload_path = os.path.join(fsroot, upload) |
3673.6.16
by Malcolm Cleaton
Addressed review comments |
145 |
changes_files = self.locateChangesFiles(upload_path) |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
146 |
|
147 |
# Keep track of the various results
|
|
148 |
some_failed = False |
|
149 |
some_rejected = False |
|
150 |
some_accepted = False |
|
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
151 |
|
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
152 |
for changes_file in changes_files: |
153 |
self.log.debug("Considering changefile %s" % changes_file) |
|
154 |
try: |
|
3673.6.16
by Malcolm Cleaton
Addressed review comments |
155 |
result = self.processChangesFile(upload_path, changes_file) |
3673.6.20
by Malcolm Cleaton
Second review comments |
156 |
if result == UploadStatusEnum.FAILED: |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
157 |
some_failed = True |
3673.6.20
by Malcolm Cleaton
Second review comments |
158 |
elif result == UploadStatusEnum.REJECTED: |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
159 |
some_rejected = True |
160 |
else: |
|
161 |
some_accepted = True |
|
3691.117.6
by Malcolm Cleaton
Tidying |
162 |
except (KeyboardInterrupt, SystemExit): |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
163 |
raise
|
164 |
except: |
|
5353.1.4
by Celso Providelo
review comments, r=mwhudson. |
165 |
self.log.error( |
166 |
"Unhandled exception from processing an upload", |
|
167 |
exc_info=True) |
|
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
168 |
some_failed = True |
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
169 |
|
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
170 |
if some_failed: |
171 |
destination = "failed" |
|
172 |
elif some_rejected: |
|
173 |
destination = "rejected" |
|
174 |
elif some_accepted: |
|
175 |
destination = "accepted" |
|
176 |
else: |
|
3673.6.16
by Malcolm Cleaton
Addressed review comments |
177 |
# There were no changes files at all. We consider
|
178 |
# the upload to be failed in this case.
|
|
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
179 |
destination = "failed" |
180 |
||
3673.6.16
by Malcolm Cleaton
Addressed review comments |
181 |
self.moveUpload(upload_path, destination) |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
182 |
|
3673.6.16
by Malcolm Cleaton
Addressed review comments |
183 |
def locateDirectories(self, fsroot): |
184 |
"""List directories in given directory, usually 'incoming'."""
|
|
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
185 |
# Protecting listdir by a lock ensures that we only get
|
186 |
# completely finished directories listed. See
|
|
187 |
# PoppyInterface for the other locking place.
|
|
5089.1.2
by Celso Providelo
applying review comments, r=kiko. |
188 |
lockfile_path = os.path.join(fsroot, ".lock") |
189 |
fsroot_lock = GlobalLock(lockfile_path) |
|
5554.1.2
by Celso Providelo
applying review comments, r=salgado. |
190 |
mode = stat.S_IMODE(os.stat(lockfile_path).st_mode) |
191 |
||
6916.1.1
by Curtis Hovey
Fixed comment formats to fidn missing persons, dates, and some bugs. |
192 |
# XXX cprov 20081024 bug=185731: The lockfile permission can only be
|
193 |
# changed by its owner. Since we can't predict which process will
|
|
194 |
# create it in production systems we simply ignore errors when trying
|
|
195 |
# to grant the right permission. At least, one of the process will
|
|
196 |
# be able to do so.
|
|
5554.1.1
by Celso Providelo
Fixing share lockfile issue between poppy (lp_upload) and process-upload (lp_queue). Ignoring exceptions raised while trying to grant the write permission to the group. |
197 |
try: |
198 |
os.chmod(lockfile_path, mode | stat.S_IWGRP) |
|
5554.1.2
by Celso Providelo
applying review comments, r=salgado. |
199 |
except OSError, err: |
200 |
self.log.debug('Could not fix the lockfile permission: %s' % err) |
|
5089.1.2
by Celso Providelo
applying review comments, r=kiko. |
201 |
|
3673.6.16
by Malcolm Cleaton
Addressed review comments |
202 |
try: |
3691.348.5
by kiko
I changed the semantics for acquire() to be non-blocking by default, so make it explicit in these callsites |
203 |
fsroot_lock.acquire(blocking=True) |
3673.6.16
by Malcolm Cleaton
Addressed review comments |
204 |
dir_names = os.listdir(fsroot) |
205 |
finally: |
|
5089.1.2
by Celso Providelo
applying review comments, r=kiko. |
206 |
# Skip lockfile deletion, see similar code in poppyinterface.py.
|
207 |
fsroot_lock.release(skip_delete=True) |
|
3673.6.16
by Malcolm Cleaton
Addressed review comments |
208 |
|
209 |
dir_names = [dir_name for dir_name in dir_names if |
|
210 |
os.path.isdir(os.path.join(fsroot, dir_name))] |
|
211 |
return dir_names |
|
212 |
||
213 |
def locateChangesFiles(self, upload_path): |
|
214 |
"""Locate .changes files in the given upload directory.
|
|
215 |
||
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
216 |
Return .changes files sorted with *_source.changes first. This
|
217 |
is important to us, as in an upload containing several changes files,
|
|
218 |
it's possible the binary ones will depend on the source ones, so
|
|
219 |
the source ones should always be considered first.
|
|
3673.6.16
by Malcolm Cleaton
Addressed review comments |
220 |
"""
|
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
221 |
changes_files = [] |
3691.443.60
by Celso Providelo
merge from RF, bunch of conflicts fixed. storing upload_archive in the policy. |
222 |
|
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
223 |
for dirpath, dirnames, filenames in os.walk(upload_path): |
3691.443.60
by Celso Providelo
merge from RF, bunch of conflicts fixed. storing upload_archive in the policy. |
224 |
relative_path = dirpath[len(upload_path) + 1:] |
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
225 |
for filename in filenames: |
226 |
if filename.endswith(".changes"): |
|
5353.1.4
by Celso Providelo
review comments, r=mwhudson. |
227 |
changes_files.append( |
228 |
os.path.join(relative_path, filename)) |
|
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
229 |
return self.orderFilenames(changes_files) |
230 |
||
3673.6.16
by Malcolm Cleaton
Addressed review comments |
231 |
def processChangesFile(self, upload_path, changes_file): |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
232 |
"""Process a single changes file.
|
233 |
||
3673.6.16
by Malcolm Cleaton
Addressed review comments |
234 |
This is done by obtaining the appropriate upload policy (according
|
235 |
to command-line options and the value in the .distro file beside
|
|
236 |
the upload, if present), creating a NascentUpload object and calling
|
|
237 |
its process method.
|
|
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
238 |
|
239 |
We obtain the context for this processing from the relative path,
|
|
240 |
within the upload folder, of this changes file. This influences
|
|
241 |
our creation both of upload policy and the NascentUpload object.
|
|
3673.6.16
by Malcolm Cleaton
Addressed review comments |
242 |
|
243 |
See nascentupload.py for the gory details.
|
|
244 |
||
3691.117.1
by Malcolm Cleaton
Fix and test for 35965. Also first functional (non-doc) test for uploading, watch for more complete support for this in the future. |
245 |
Returns a value from UploadStatusEnum, or re-raises an exception
|
246 |
from NascentUpload.
|
|
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
247 |
"""
|
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
248 |
# Calculate the distribution from the path within the upload
|
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
249 |
# Reject the upload since we could not process the path,
|
250 |
# Store the exception information as a rejection message.
|
|
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
251 |
relative_path = os.path.dirname(changes_file) |
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
252 |
error = None |
253 |
try: |
|
5353.1.4
by Celso Providelo
review comments, r=mwhudson. |
254 |
(distribution, suite_name, |
255 |
archive) = self.getDistributionAndArchive(relative_path) |
|
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
256 |
except UploadPathError, e: |
257 |
# pick some defaults to create the NascentUploap() object.
|
|
258 |
# We will be rejecting the upload so it doesn matter much.
|
|
3691.443.95
by Celso Providelo
implementing path-based suite(distrorelease) overriding for PPA uploads. |
259 |
distribution = getUtility(IDistributionSet)['ubuntu'] |
260 |
suite_name = None |
|
261 |
archive = distribution.main_archive |
|
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
262 |
error = str(e) |
4810.3.1
by Julian Edwards
PPA upload emails should go to the uploader (and hence package signer) only. |
263 |
except PPAUploadPathError, e: |
264 |
# Again, pick some defaults but leave a hint for the rejection
|
|
265 |
# emailer that it was a PPA failure.
|
|
266 |
distribution = getUtility(IDistributionSet)['ubuntu'] |
|
267 |
suite_name = None |
|
6500.1.11
by Celso Providelo
Fixing test failure with a evil hack, God forbids. |
268 |
# XXX cprov 20071212: using the first available PPA is not exactly
|
5353.1.1
by Celso Providelo
Fixing bug 172377 (adding 'X-Launchpad-PPA' header in PPA upload notifications). |
269 |
# fine because it can confuse the code that sends rejection
|
270 |
# messages if it relies only on archive.purpose (which should be
|
|
271 |
# enough). On the other hand if we set an arbitrary owner it
|
|
272 |
# will break nascentupload ACL calculations.
|
|
6500.1.11
by Celso Providelo
Fixing test failure with a evil hack, God forbids. |
273 |
archive = distribution.getAllPPAs()[0] |
4810.3.1
by Julian Edwards
PPA upload emails should go to the uploader (and hence package signer) only. |
274 |
error = str(e) |
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
275 |
|
276 |
self.log.debug("Finding fresh policy") |
|
3691.443.95
by Celso Providelo
implementing path-based suite(distrorelease) overriding for PPA uploads. |
277 |
self.options.distro = distribution.name |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
278 |
policy = findPolicyByOptions(self.options) |
3691.443.60
by Celso Providelo
merge from RF, bunch of conflicts fixed. storing upload_archive in the policy. |
279 |
policy.archive = archive |
4285.2.8
by Mark Shuttleworth
Test fixes for archive uploader |
280 |
# DistroSeries overriding respect the following precedence:
|
3691.443.95
by Celso Providelo
implementing path-based suite(distrorelease) overriding for PPA uploads. |
281 |
# 1. process-upload.py command-line option (-r),
|
282 |
# 2. upload path,
|
|
283 |
# 3. changesfile 'Distribution' field.
|
|
284 |
if suite_name is not None: |
|
4285.2.8
by Mark Shuttleworth
Test fixes for archive uploader |
285 |
policy.setDistroSeriesAndPocket(suite_name) |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
286 |
|
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
287 |
# The path we want for NascentUpload is the path to the folder
|
288 |
# containing the changes file (and the other files referenced by it).
|
|
3804.1.15
by Celso Providelo
code review, pending tests for NUF and changes in publication lookup. |
289 |
changesfile_path = os.path.join(upload_path, changes_file) |
290 |
upload = NascentUpload(changesfile_path, policy, self.log) |
|
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
291 |
|
3691.443.62
by Celso Providelo
merge from RF, conflict solving. |
292 |
# Store archive lookup error in the upload if it was the case.
|
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
293 |
if error is not None: |
3691.443.62
by Celso Providelo
merge from RF, conflict solving. |
294 |
upload.reject(error) |
295 |
||
4162.3.1
by Celso Providelo
Fix #110576 (security uploads are broken in nu-cataclysm). More precise tests for security uploads. |
296 |
# Store processed NascentUpload instance, mostly used for tests.
|
297 |
self.last_processed_upload = upload |
|
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
298 |
|
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
299 |
try: |
3804.1.8
by Celso Providelo
nascentupload.txt fixed, still having problems with archivepublisher.ftests.test_uploadprocessor. |
300 |
self.log.info("Processing upload %s" % upload.changes.filename) |
3673.6.20
by Malcolm Cleaton
Second review comments |
301 |
result = UploadStatusEnum.ACCEPTED |
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
302 |
|
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
303 |
try: |
304 |
upload.process() |
|
305 |
except UploadPolicyError, e: |
|
306 |
upload.reject("UploadPolicyError escaped upload.process: " |
|
307 |
"%s " % e) |
|
308 |
self.log.debug("UploadPolicyError escaped upload.process", |
|
309 |
exc_info=True) |
|
3806.2.11
by kiko
Cleanups and move some code around, no functional changes. |
310 |
except FatalUploadError, e: |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
311 |
upload.reject("UploadError escaped upload.process: %s" % e) |
312 |
self.log.debug("UploadError escaped upload.process", |
|
313 |
exc_info=True) |
|
3691.117.6
by Malcolm Cleaton
Tidying |
314 |
except (KeyboardInterrupt, SystemExit): |
3691.117.1
by Malcolm Cleaton
Fix and test for 35965. Also first functional (non-doc) test for uploading, watch for more complete support for this in the future. |
315 |
raise
|
4936.3.4
by Julian Edwards
Improve the API for error checking and early rejection. |
316 |
except EarlyReturnUploadError: |
317 |
# An error occurred that prevented further error collection,
|
|
318 |
# add this fact to the list of errors.
|
|
319 |
upload.reject( |
|
320 |
"Further error processing not possible because of "
|
|
321 |
"a critical previous error.") |
|
3691.117.1
by Malcolm Cleaton
Fix and test for 35965. Also first functional (non-doc) test for uploading, watch for more complete support for this in the future. |
322 |
except Exception, e: |
323 |
# In case of unexpected unhandled exception, we'll
|
|
324 |
# *try* to reject the upload. This may fail and cause
|
|
325 |
# a further exception, depending on the state of the
|
|
326 |
# nascentupload objects. In that case, we've lost nothing,
|
|
327 |
# the new exception will be handled by the caller just like
|
|
328 |
# the one we caught would have been, by failing the upload
|
|
329 |
# with no email.
|
|
3691.148.1
by Malcolm Cleaton
Fix bad use of log.exception |
330 |
self.log.exception("Unhandled exception processing upload") |
3691.117.1
by Malcolm Cleaton
Fix and test for 35965. Also first functional (non-doc) test for uploading, watch for more complete support for this in the future. |
331 |
upload.reject("Unhandled exception processing upload: %s" % e) |
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
332 |
|
4664.1.1
by Curtis Hovey
Normalized comments for bug 3732. |
333 |
# XXX julian 2007-05-25 bug=29744:
|
4204.2.19
by Julian Edwards
Add an XXX that I forgot about from the last commital. |
334 |
# When bug #29744 is fixed (zopeless mails should only be sent
|
335 |
# when transaction is committed) this will cause any emails sent
|
|
336 |
# sent by do_reject to be lost.
|
|
4310.2.4
by Julian Edwards
Amend readability of some code as per the review. |
337 |
notify = True |
338 |
if self.options.dryrun or self.options.nomails: |
|
339 |
notify = False |
|
3804.1.8
by Celso Providelo
nascentupload.txt fixed, still having problems with archivepublisher.ftests.test_uploadprocessor. |
340 |
if upload.is_rejected: |
3673.6.20
by Malcolm Cleaton
Second review comments |
341 |
result = UploadStatusEnum.REJECTED |
4310.2.3
by Julian Edwards
Add a notification flag to the do_reject call. |
342 |
upload.do_reject(notify) |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
343 |
self.ztm.abort() |
344 |
else: |
|
4310.2.1
by Julian Edwards
Add a boolean flag "notify" to NascentUpload.do_accept() to say whether to |
345 |
successful = upload.do_accept(notify=notify) |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
346 |
if not successful: |
3673.6.20
by Malcolm Cleaton
Second review comments |
347 |
result = UploadStatusEnum.REJECTED |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
348 |
self.log.info("Rejection during accept. " |
349 |
"Aborting partial accept.") |
|
350 |
self.ztm.abort() |
|
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
351 |
|
4285.3.67
by Celso Providelo
Include rejection reasons in the uploader log output. |
352 |
if upload.is_rejected: |
353 |
self.log.warn("Upload was rejected:") |
|
354 |
for msg in upload.rejections: |
|
355 |
self.log.warn("\t%s" % msg) |
|
356 |
||
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
357 |
if self.options.dryrun: |
358 |
self.log.info("Dry run, aborting transaction.") |
|
359 |
self.ztm.abort() |
|
360 |
else: |
|
361 |
self.log.info("Committing the transaction and any mails " |
|
362 |
"associated with this upload.") |
|
363 |
self.ztm.commit() |
|
364 |
except: |
|
365 |
self.ztm.abort() |
|
366 |
raise
|
|
367 |
||
3673.6.16
by Malcolm Cleaton
Addressed review comments |
368 |
return result |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
369 |
|
3673.6.16
by Malcolm Cleaton
Addressed review comments |
370 |
def moveUpload(self, upload, subdir_name): |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
371 |
"""Move the upload to the named subdir of the root, eg 'accepted'.
|
372 |
||
3673.6.16
by Malcolm Cleaton
Addressed review comments |
373 |
This includes moving the given upload directory and moving the
|
374 |
matching .distro file, if it exists.
|
|
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
375 |
"""
|
376 |
if self.options.keep or self.options.dryrun: |
|
377 |
self.log.debug("Keeping contents untouched") |
|
378 |
return
|
|
379 |
||
3673.6.16
by Malcolm Cleaton
Addressed review comments |
380 |
pathname = os.path.basename(upload) |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
381 |
|
382 |
target_path = os.path.join( |
|
383 |
self.options.base_fsroot, subdir_name, pathname) |
|
3673.6.16
by Malcolm Cleaton
Addressed review comments |
384 |
self.log.debug("Moving upload directory %s to %s" % |
385 |
(upload, target_path)) |
|
3804.1.12
by Celso Providelo
Fixing soyuz-set-of-upload and related code. |
386 |
shutil.move(upload, target_path) |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
387 |
|
3673.6.16
by Malcolm Cleaton
Addressed review comments |
388 |
distro_filename = upload + ".distro" |
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
389 |
if os.path.isfile(distro_filename): |
390 |
target_path = os.path.join(self.options.base_fsroot, subdir_name, |
|
391 |
os.path.basename(distro_filename)) |
|
392 |
self.log.debug("Moving distro file %s to %s" % (distro_filename, |
|
393 |
target_path)) |
|
3804.1.12
by Celso Providelo
Fixing soyuz-set-of-upload and related code. |
394 |
shutil.move(distro_filename, target_path) |
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
395 |
|
3673.6.1
by Malcolm Cleaton
Tidying process-upload script and tests |
396 |
def orderFilenames(self, fnames): |
397 |
"""Order filenames, sorting *_source.changes before others.
|
|
398 |
||
399 |
Aside from that, a standard string sort.
|
|
400 |
"""
|
|
3673.6.22
by Malcolm Cleaton
Argh, TABS!! |
401 |
def sourceFirst(filename): |
402 |
return (not filename.endswith("_source.changes"), filename) |
|
3673.6.16
by Malcolm Cleaton
Addressed review comments |
403 |
|
404 |
return sorted(fnames, key=sourceFirst) |
|
405 |
||
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
406 |
def getDistributionAndArchive(self, relative_path): |
407 |
"""Locate the distribution and archive for the upload.
|
|
408 |
||
409 |
We do this by analysing the path to which the user has uploaded,
|
|
410 |
ie. the relative path within the upload folder to the changes file.
|
|
411 |
||
412 |
The valid paths are:
|
|
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
413 |
'' - default distro, ubuntu
|
414 |
'<distroname>' - given distribution
|
|
7465.2.2
by Celso Providelo
Revert RF 7436. |
415 |
'~<personname>/<distroname>/[distroseriesname]' - given ppa,
|
416 |
distribution and optionally a distroseries.
|
|
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
417 |
|
418 |
I raises UploadPathError if something was wrong when parsing it.
|
|
419 |
||
3691.443.95
by Celso Providelo
implementing path-based suite(distrorelease) overriding for PPA uploads. |
420 |
On success it returns a tuple of IDistribution, suite-name,
|
421 |
IArchive for the given path, where the second field can be None.
|
|
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
422 |
"""
|
423 |
parts = relative_path.split(os.path.sep) |
|
3691.443.50
by Celso Providelo
Fix #88611 (only one PPA per user) and simpler upload/publish paths for PPA. |
424 |
first_path = parts[0] |
425 |
||
4285.2.8
by Mark Shuttleworth
Test fixes for archive uploader |
426 |
# Empty distroseries override by default.
|
3691.443.95
by Celso Providelo
implementing path-based suite(distrorelease) overriding for PPA uploads. |
427 |
suite_name = None |
428 |
||
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
429 |
# Distribution name only, or nothing
|
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
430 |
if len(parts) == 1: |
3691.443.95
by Celso Providelo
implementing path-based suite(distrorelease) overriding for PPA uploads. |
431 |
distribution_name = first_path |
3691.443.50
by Celso Providelo
Fix #88611 (only one PPA per user) and simpler upload/publish paths for PPA. |
432 |
# fallback to ubuntu
|
3691.443.95
by Celso Providelo
implementing path-based suite(distrorelease) overriding for PPA uploads. |
433 |
if not distribution_name: |
434 |
distribution_name = 'ubuntu' |
|
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
435 |
|
3691.443.95
by Celso Providelo
implementing path-based suite(distrorelease) overriding for PPA uploads. |
436 |
distribution = getUtility(IDistributionSet).getByName( |
437 |
distribution_name) |
|
438 |
if not distribution: |
|
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
439 |
raise UploadPathError( |
3691.443.95
by Celso Providelo
implementing path-based suite(distrorelease) overriding for PPA uploads. |
440 |
"Could not find distribution '%s'" % distribution_name) |
441 |
archive = distribution.main_archive |
|
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
442 |
|
7465.2.2
by Celso Providelo
Revert RF 7436. |
443 |
# PPA upload (~<person>/<distro>/[distroseries])
|
444 |
elif len(parts) <= 3: |
|
3691.443.50
by Celso Providelo
Fix #88611 (only one PPA per user) and simpler upload/publish paths for PPA. |
445 |
if not first_path.startswith('~'): |
4810.3.1
by Julian Edwards
PPA upload emails should go to the uploader (and hence package signer) only. |
446 |
raise PPAUploadPathError( |
3691.443.50
by Celso Providelo
Fix #88611 (only one PPA per user) and simpler upload/publish paths for PPA. |
447 |
"PPA upload path must start with '~'.") |
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
448 |
|
449 |
# Skip over ~
|
|
3691.443.50
by Celso Providelo
Fix #88611 (only one PPA per user) and simpler upload/publish paths for PPA. |
450 |
person_name = first_path[1:] |
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
451 |
person = getUtility(IPersonSet).getByName(person_name) |
452 |
if person is None: |
|
4810.3.1
by Julian Edwards
PPA upload emails should go to the uploader (and hence package signer) only. |
453 |
raise PPAUploadPathError( |
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
454 |
"Could not find person '%s'" % person_name) |
3691.446.1
by Celso Providelo
Incorporate 'path-aware' upload processing as part of PPA upload support, doc/soyuz-upload.txt & doc/soyuz-set-of-uploads.txt are busted. |
455 |
|
7465.2.2
by Celso Providelo
Revert RF 7436. |
456 |
distribution_name = parts[1] |
3691.443.95
by Celso Providelo
implementing path-based suite(distrorelease) overriding for PPA uploads. |
457 |
distribution = getUtility(IDistributionSet).getByName( |
458 |
distribution_name) |
|
459 |
if distribution is None: |
|
4810.3.1
by Julian Edwards
PPA upload emails should go to the uploader (and hence package signer) only. |
460 |
raise PPAUploadPathError( |
3691.443.95
by Celso Providelo
implementing path-based suite(distrorelease) overriding for PPA uploads. |
461 |
"Could not find distribution '%s'" % distribution_name) |
3691.443.50
by Celso Providelo
Fix #88611 (only one PPA per user) and simpler upload/publish paths for PPA. |
462 |
|
4285.3.32
by Celso Providelo
Do not create new PPA on successfully uploads (it's required to create them via the web UI). Deny uploads for disabled PPAs. Minor style fixing in uploadprocessor.py. Tests inside (tm). |
463 |
archive = person.archive |
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
464 |
if archive is None: |
4810.3.1
by Julian Edwards
PPA upload emails should go to the uploader (and hence package signer) only. |
465 |
raise PPAUploadPathError( |
3691.443.50
by Celso Providelo
Fix #88611 (only one PPA per user) and simpler upload/publish paths for PPA. |
466 |
"Could not find PPA for '%s'" % person_name) |
467 |
||
4285.3.32
by Celso Providelo
Do not create new PPA on successfully uploads (it's required to create them via the web UI). Deny uploads for disabled PPAs. Minor style fixing in uploadprocessor.py. Tests inside (tm). |
468 |
if not archive.enabled: |
4810.3.1
by Julian Edwards
PPA upload emails should go to the uploader (and hence package signer) only. |
469 |
raise PPAUploadPathError( |
4285.3.32
by Celso Providelo
Do not create new PPA on successfully uploads (it's required to create them via the web UI). Deny uploads for disabled PPAs. Minor style fixing in uploadprocessor.py. Tests inside (tm). |
470 |
"%s is disabled" % archive.title) |
471 |
||
4285.3.42
by Celso Providelo
moving PPA handlers to IDistribution, improving IArchive tests, using IArchive.distribution in Publisher System, verifying Archive.distribution in upload time. *some* tests missing (tm). |
472 |
if archive.distribution != distribution: |
4810.3.1
by Julian Edwards
PPA upload emails should go to the uploader (and hence package signer) only. |
473 |
raise PPAUploadPathError( |
4285.3.42
by Celso Providelo
moving PPA handlers to IDistribution, improving IArchive tests, using IArchive.distribution in Publisher System, verifying Archive.distribution in upload time. *some* tests missing (tm). |
474 |
"%s only supports uploads to '%s'" |
475 |
% (archive.title, archive.distribution.name)) |
|
476 |
||
3691.443.95
by Celso Providelo
implementing path-based suite(distrorelease) overriding for PPA uploads. |
477 |
if len(parts) > 2: |
7465.2.2
by Celso Providelo
Revert RF 7436. |
478 |
suite_name = parts[2] |
3691.443.95
by Celso Providelo
implementing path-based suite(distrorelease) overriding for PPA uploads. |
479 |
# Check if the given suite name is valid.
|
480 |
# We will return the suite_name string simply.
|
|
481 |
try: |
|
4285.2.8
by Mark Shuttleworth
Test fixes for archive uploader |
482 |
suite = distribution.getDistroSeriesAndPocket(suite_name) |
3691.443.95
by Celso Providelo
implementing path-based suite(distrorelease) overriding for PPA uploads. |
483 |
except NotFoundError: |
4810.3.1
by Julian Edwards
PPA upload emails should go to the uploader (and hence package signer) only. |
484 |
raise PPAUploadPathError( |
3691.443.95
by Celso Providelo
implementing path-based suite(distrorelease) overriding for PPA uploads. |
485 |
"Could not find suite '%s'" % suite_name) |
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
486 |
else: |
487 |
raise UploadPathError( |
|
7465.2.2
by Celso Providelo
Revert RF 7436. |
488 |
"Path mismatch '%s'. Use ~<person>/<distro>/[distroseries]/" |
3691.443.95
by Celso Providelo
implementing path-based suite(distrorelease) overriding for PPA uploads. |
489 |
"[files] for PPAs and <distro>/[files] for normal uploads."
|
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
490 |
% (relative_path)) |
491 |
||
3691.443.95
by Celso Providelo
implementing path-based suite(distrorelease) overriding for PPA uploads. |
492 |
return (distribution, suite_name, archive) |
3691.443.31
by Celso Providelo
fix test_uploadprocessor and related code. |
493 |