Merge lp:~nuclearbob/utah/output-preseed into lp:utah
- output-preseed
- Merge into dev
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Javier Collado | ||||||||
Approved revision: | 783 | ||||||||
Merged at revision: | 796 | ||||||||
Proposed branch: | lp:~nuclearbob/utah/output-preseed | ||||||||
Merge into: | lp:utah | ||||||||
Diff against target: |
627 lines (+179/-240) 9 files modified
examples/run_install_test.py (+11/-60) examples/run_test_bamboo_feeder.py (+9/-31) examples/run_test_cobbler.py (+9/-40) examples/run_test_vm.py (+2/-30) examples/run_utah_tests.py (+12/-56) utah/config.py (+3/-0) utah/provisioning/provisioning.py (+39/-13) utah/provisioning/vm/vm.py (+1/-6) utah/run.py (+93/-4) |
||||||||
To merge this branch: | bzr merge lp:~nuclearbob/utah/output-preseed | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Javier Collado (community) | Approve | ||
Max Brustkern (community) | Needs Resubmitting | ||
Review via email:
|
Commit message
Description of the change
This branch adds a --outputpreseed option. This options saves a copy of the final preseed to /var/log/utah and outputs the name of that preseed in the same manner as the other logs, so it will be automatically gathered. If we merge this, we should later update the job generation to include this option in jobs by default, or update the config file on the lab machines to enable it by default.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Javier Collado (javier.collado) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Max Brustkern (nuclearbob) wrote : | # |
These are both good suggestions. I'll resubmit after implementing them.
- 780. By Max Brustkern
-
Merged latest changes
* Updating to version 0.6
* Added baremetal fixes - 781. By Max Brustkern
-
Removed extraneous file
- 782. By Max Brustkern
-
Refactored command line argument sections per Javier's suggestion
- 783. By Max Brustkern
-
Added logging for why the preseed was captued
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Max Brustkern (nuclearbob) wrote : | # |
Those should be updated now.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Javier Collado (javier.collado) wrote : | # |
Thanks for the update Max.
The refactoring for the command line options looks nice.
Regarding writing to logs the configuration values, I meant to do that for
every value; but, since that's out of the scope for this bug, I've opened
bug1095994 to follow up on that issue.
I see some changes in provisioning.py regarding cleanup functions that I'm not
sure they fit wit hthe purpose of this merge request. Could you summarize what
are they intended to do?
Also, I see some conversions from OrderedSet to tuple in for loops. Is that
really needed? It should be possible to iterate over the OrderedSet without
such a conversion.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Max Brustkern (nuclearbob) wrote : | # |
I ran into a bunch of errors with the cleanup when I was testing this, and if one part failed, we just passed the exception up instead of continuing. I also found cases where cleanfunctions failed because it was expecting files to exist that were deleted by cleanfiles, so I reordered those. The tuple conversions may be unnecessary at this point; when I started working on cleanup, I had it broken into sections, and there was a weird construction to make the lists of things to do. They may be left over from that. I can test it without the tuple conversions and see if that creates an issue.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Javier Collado (javier.collado) wrote : | # |
I've tested with the `pass.run` runlist successfully without the `tuple`
conversions, so I'm merging these changes.
Preview Diff
1 | === modified file 'examples/run_install_test.py' |
2 | --- examples/run_install_test.py 2012-12-12 20:58:59 +0000 |
3 | +++ examples/run_install_test.py 2012-12-19 19:47:27 +0000 |
4 | @@ -18,12 +18,16 @@ |
5 | import argparse |
6 | import sys |
7 | |
8 | -from utah import config |
9 | from utah.exceptions import UTAHException |
10 | -from utah.url import url_argument |
11 | from utah.group import check_user_group, print_group_error_message |
12 | from utah.provisioning.vm.vm import CustomVM, TinySQLiteInventory |
13 | -from utah.run import run_tests |
14 | +from utah.run import ( |
15 | + common_arguments, |
16 | + custom_arguments, |
17 | + file_arguments, |
18 | + run_tests, |
19 | + virtual_arguments, |
20 | +) |
21 | |
22 | |
23 | def get_parser(): |
24 | @@ -37,63 +41,10 @@ |
25 | "\t\t/usr/share/utah/client/examples/master.run \\\n" |
26 | "\t\t'http://people.canonical.com/~max/max_test.run'"), |
27 | formatter_class=argparse.RawDescriptionHelpFormatter) |
28 | - parser.add_argument('runlists', metavar='runlist', nargs='+', |
29 | - type=url_argument, help='URLs of runlist files to run') |
30 | - parser.add_argument('-m', '--machinetype', metavar='MACHINETYPE', |
31 | - choices=('physical', 'virtual'), default='virtual', |
32 | - help='Type of machine to provision (%(choices)s)') |
33 | - parser.add_argument('-e', '--emulator', |
34 | - help=('Emulator to use (kvm and qemu are supported, ' |
35 | - 'kvm will be favored if available)')) |
36 | - parser.add_argument('-i', '--image', type=url_argument, |
37 | - help='Image/ISO file to use for installation') |
38 | - parser.add_argument('-k', '--kernel', type=url_argument, |
39 | - help='Kernel file to use for installation') |
40 | - parser.add_argument('-r', '--initrd', type=url_argument, |
41 | - help='InitRD file to use for installation') |
42 | - parser.add_argument('-p', '--preseed', type=url_argument, |
43 | - help='Preseed file to use for installation') |
44 | - parser.add_argument('-b', '--boot', |
45 | - help='Boot arguments for initial installation') |
46 | - parser.add_argument('-x', '--xml', type=url_argument, |
47 | - help='XML VM definition file') |
48 | - parser.add_argument('-g', '--gigabytes', action='append', |
49 | - help=('Size in gigabytes of virtual disk, ' |
50 | - 'specify more than once for multiple disks')) |
51 | - parser.add_argument('-s', '--series', metavar='SERIES', |
52 | - choices=config.serieschoices, |
53 | - help='Series to use for installation (%(choices)s)') |
54 | - parser.add_argument('-t', '--type', metavar='TYPE', |
55 | - choices=('desktop', 'server', 'mini', 'alternate'), |
56 | - help=('Install type to use for installation ' |
57 | - '(%(choices)s)')) |
58 | - parser.add_argument('-a', '--arch', metavar='ARCH', |
59 | - choices=('i386', 'amd64', 'arm'), |
60 | - help=('Architecture to use for installation ' |
61 | - '(%(choices)s)')) |
62 | - parser.add_argument('-v', '--variant', |
63 | - help='Variant of architecture, i.e., armel, armhf') |
64 | - parser.add_argument('-n', '--no-destroy', action='store_true', |
65 | - help='Preserve machine after tests have run') |
66 | - parser.add_argument('-d', '--debug', action='store_true', |
67 | - help='Enable debug logging') |
68 | - parser.add_argument('-j', '--json', action='store_true', |
69 | - help='Enable json logging (default is YAML)') |
70 | - parser.add_argument('-f', '--files', action='append', |
71 | - help='File or directory to copy from test system ') |
72 | - parser.add_argument('-o', '--outdir', |
73 | - help=('Directory to store locally copied files ' |
74 | - '(Default is ' + config.logpath + |
75 | - '/machine-name)')) |
76 | - parser.add_argument('--diskbus', metavar='DISKBUS', |
77 | - choices=('virtio', 'sata', 'ide'), |
78 | - help=('Disk bus to use for customvm installation ' |
79 | - '(%(choices)s)')) |
80 | - parser.add_argument('--rewrite', choices=('all', 'minimal', 'casperonly', |
81 | - 'none'), help='Enable or disable automatic ' |
82 | - 'configuration rewriting') |
83 | - parser.add_argument('--dumplogs', action='store_true', |
84 | - help='Write client output logs to standard out') |
85 | + parser = common_arguments(parser) |
86 | + parser = custom_arguments(parser) |
87 | + parser = file_arguments(parser) |
88 | + parser = virtual_arguments(parser) |
89 | return parser |
90 | |
91 | |
92 | |
93 | === modified file 'examples/run_test_bamboo_feeder.py' |
94 | --- examples/run_test_bamboo_feeder.py 2012-12-12 20:25:24 +0000 |
95 | +++ examples/run_test_bamboo_feeder.py 2012-12-19 19:47:27 +0000 |
96 | @@ -19,14 +19,17 @@ |
97 | import os |
98 | import sys |
99 | |
100 | -from utah import config |
101 | from utah.exceptions import UTAHException |
102 | from utah.group import check_user_group, print_group_error_message |
103 | from utah.provisioning.baremetal.bamboofeeder import BambooFeederMachine |
104 | from utah.provisioning.baremetal.inventory import \ |
105 | ManualBaremetalSQLiteInventory |
106 | -from utah.run import run_tests |
107 | -from utah.url import url_argument |
108 | +from utah.run import ( |
109 | + common_arguments, |
110 | + custom_arguments, |
111 | + name_argument, |
112 | + run_tests, |
113 | +) |
114 | |
115 | |
116 | def get_parser(): |
117 | @@ -40,34 +43,9 @@ |
118 | "\t\t/usr/share/utah/client/examples/master.run \\\n" |
119 | "\t\t'http://people.canonical.com/~max/max_test.run'"), |
120 | formatter_class=argparse.RawDescriptionHelpFormatter) |
121 | - parser.add_argument('runlists', metavar='runlist', nargs='+', |
122 | - help='URLs of runlist files to run') |
123 | - parser.add_argument('-s', '--series', metavar='SERIES', |
124 | - choices=config.serieschoices, |
125 | - help='Series to use for VM creation (%(choices)s)') |
126 | - parser.add_argument('-t', '--type', metavar='TYPE', |
127 | - choices=('desktop', 'server', 'mini', 'alternate'), |
128 | - help=('Install type to use for VM creation ' |
129 | - '(%(choices)s)')) |
130 | - parser.add_argument('-a', '--arch', metavar='ARCH', |
131 | - choices=('i386', 'amd64'), |
132 | - help=('Architecture to use for VM creation ' |
133 | - '(%(choices)s)')) |
134 | - parser.add_argument('--name', help='Name of machine to provision') |
135 | - parser.add_argument('-i', '--image', type=url_argument, |
136 | - help='Image/ISO file to use for installation') |
137 | - parser.add_argument('-p', '--preseed', type=url_argument, |
138 | - help='Preseed file to use for installation') |
139 | - parser.add_argument('-b', '--boot', |
140 | - help='Boot arguments for initial installation') |
141 | - parser.add_argument('-n', '--no-destroy', action='store_true', |
142 | - help='Preserve VM after tests have run') |
143 | - parser.add_argument('-d', '--debug', action='store_true', |
144 | - help='Enable debug logging') |
145 | - parser.add_argument('-j', '--json', action='store_true', |
146 | - help='Enable json logging (default is YAML)') |
147 | - parser.add_argument('--dumplogs', action='store_true', |
148 | - help='Write client output logs to standard out') |
149 | + parser = common_arguments(parser) |
150 | + parser = custom_arguments(parser) |
151 | + parser = name_argument(parser) |
152 | return parser |
153 | |
154 | |
155 | |
156 | === modified file 'examples/run_test_cobbler.py' |
157 | --- examples/run_test_cobbler.py 2012-12-13 09:07:58 +0000 |
158 | +++ examples/run_test_cobbler.py 2012-12-19 19:47:27 +0000 |
159 | @@ -18,14 +18,17 @@ |
160 | import argparse |
161 | import sys |
162 | |
163 | -from utah import config |
164 | from utah.exceptions import UTAHException |
165 | from utah.group import check_user_group, print_group_error_message |
166 | from utah.provisioning.baremetal.cobbler import CobblerMachine |
167 | from utah.provisioning.baremetal.inventory import \ |
168 | ManualBaremetalSQLiteInventory |
169 | -from utah.run import run_tests |
170 | -from utah.url import url_argument |
171 | +from utah.run import ( |
172 | + common_arguments, |
173 | + custom_arguments, |
174 | + name_argument, |
175 | + run_tests, |
176 | +) |
177 | |
178 | |
179 | def get_parser(): |
180 | @@ -39,43 +42,9 @@ |
181 | "\t\t/usr/share/utah/client/examples/master.run \\\n" |
182 | "\t\t'http://people.canonical.com/~max/max_test.run'"), |
183 | formatter_class=argparse.RawDescriptionHelpFormatter) |
184 | - parser.add_argument('runlists', metavar='runlist', nargs='+', |
185 | - help='URLs of runlist files to run') |
186 | - parser.add_argument('-n', '--name', help='Name of machine to provision') |
187 | - parser.add_argument('-i', '--image', type=url_argument, |
188 | - help='Image/ISO file to use for installation') |
189 | - parser.add_argument('-p', '--preseed', type=url_argument, |
190 | - help='Preseed file to use for installation') |
191 | - parser.add_argument('-b', '--boot', |
192 | - help='Boot arguments for initial installation') |
193 | - parser.add_argument('-s', '--series', metavar='SERIES', |
194 | - choices=config.serieschoices, |
195 | - help='Series to use for VM creation (%(choices)s)') |
196 | - parser.add_argument('-t', '--type', metavar='TYPE', |
197 | - choices=('desktop', 'server', 'mini', 'alternate'), |
198 | - help=('Install type to use for VM creation ' |
199 | - '(%(choices)s)')) |
200 | - parser.add_argument('-a', '--arch', metavar='ARCH', |
201 | - choices=('i386', 'amd64'), |
202 | - help=('Architecture to use for VM creation ' |
203 | - '(%(choices)s)')) |
204 | - parser.add_argument('--no-destroy', action='store_true', |
205 | - help='Preserve machine after tests have run') |
206 | - parser.add_argument('-d', '--debug', action='store_true', |
207 | - help='Enable debug logging') |
208 | - parser.add_argument('-j', '--json', action='store_true', |
209 | - help='Enable json logging (default is YAML)') |
210 | - parser.add_argument('-f', '--files', action='append', |
211 | - help='File or directory to copy from test system ') |
212 | - parser.add_argument('-o', '--outdir', |
213 | - help=('Directory to store locally copied files ' |
214 | - '(Default is ' + config.logpath + |
215 | - '/machine-name)')) |
216 | - parser.add_argument('--rewrite', choices=('all', 'minimal', 'casperonly', |
217 | - 'none'), help='Enable or disable automatic ' |
218 | - 'configuration rewriting') |
219 | - parser.add_argument('--dumplogs', action='store_true', |
220 | - help='Write client output logs to standard out') |
221 | + parser = common_arguments(parser) |
222 | + parser = custom_arguments(parser) |
223 | + parser = name_argument(parser) |
224 | return parser |
225 | |
226 | |
227 | |
228 | === modified file 'examples/run_test_vm.py' |
229 | --- examples/run_test_vm.py 2012-12-12 20:06:17 +0000 |
230 | +++ examples/run_test_vm.py 2012-12-19 19:47:27 +0000 |
231 | @@ -18,11 +18,10 @@ |
232 | import argparse |
233 | import sys |
234 | |
235 | -from utah import config |
236 | from utah.exceptions import UTAHException |
237 | from utah.group import check_user_group, print_group_error_message |
238 | from utah.provisioning.vm.vm import TinySQLiteInventory |
239 | -from utah.run import run_tests |
240 | +from utah.run import common_arguments, run_tests |
241 | |
242 | |
243 | def get_parser(): |
244 | @@ -36,34 +35,7 @@ |
245 | "\t\t/usr/share/utah/client/examples/master.run \\\n" |
246 | "\t\t'http://people.canonical.com/~max/max_test.run'"), |
247 | formatter_class=argparse.RawDescriptionHelpFormatter) |
248 | - parser.add_argument('runlists', metavar='runlist', nargs='+', |
249 | - help='URLs of runlist files to run') |
250 | - parser.add_argument('-s', '--series', metavar='SERIES', |
251 | - choices=config.serieschoices, |
252 | - help='Series to use for VM creation (%(choices)s)') |
253 | - parser.add_argument('-t', '--type', metavar='TYPE', |
254 | - choices=('desktop', 'server', 'mini', 'alternate'), |
255 | - help=('Install type to use for VM creation ' |
256 | - '(%(choices)s)')) |
257 | - parser.add_argument('-a', '--arch', metavar='ARCH', |
258 | - choices=('i386', 'amd64'), |
259 | - help=('Architecture to use for VM creation ' |
260 | - '(%(choices)s)')) |
261 | - parser.add_argument('-n', '--no-destroy', action='store_true', |
262 | - help='Preserve VM after tests have run') |
263 | - parser.add_argument('-d', '--debug', action='store_true', |
264 | - help='Enable debug logging') |
265 | - parser.add_argument('-j', '--json', action='store_true', |
266 | - help='Enable json logging (default is YAML)') |
267 | - parser.add_argument('-f', '--files', action='append', |
268 | - help='File or directory to copy from test system ') |
269 | - parser.add_argument('-o', '--outdir', |
270 | - help=('Directory to store locally copied files ' |
271 | - '(Default is ' + config.logpath + |
272 | - '/machine-name)')) |
273 | - parser.add_argument('--dumplogs', action='store_true', |
274 | - help='Write client output logs to standard out') |
275 | - return parser |
276 | + return common_arguments(parser) |
277 | |
278 | |
279 | def run_test_vm(args=None): |
280 | |
281 | === modified file 'examples/run_utah_tests.py' |
282 | --- examples/run_utah_tests.py 2012-12-12 11:21:10 +0000 |
283 | +++ examples/run_utah_tests.py 2012-12-19 19:47:27 +0000 |
284 | @@ -19,8 +19,14 @@ |
285 | import sys |
286 | |
287 | from utah import config |
288 | -from utah.url import url_argument |
289 | from utah.group import check_user_group, print_group_error_message |
290 | +from utah.run import ( |
291 | + common_arguments, |
292 | + custom_arguments, |
293 | + file_arguments, |
294 | + name_argument, |
295 | + virtual_arguments, |
296 | +) |
297 | from utah.timeout import timeout, UTAHTimeout |
298 | from run_install_test import run_install_test |
299 | |
300 | @@ -38,66 +44,16 @@ |
301 | "\t\t/usr/share/utah/client/examples/master.run \\\n" |
302 | "\t\t'http://people.canonical.com/~max/max_test.run'"), |
303 | formatter_class=argparse.RawDescriptionHelpFormatter) |
304 | - parser.add_argument('runlists', metavar='runlist', nargs='+', |
305 | - type=url_argument, help='URLs of runlist files to run') |
306 | parser.add_argument('-m', '--machinetype', metavar='MACHINETYPE', |
307 | choices=('physical', 'virtual'), |
308 | help='Type of machine to provision (%(choices)s)') |
309 | - parser.add_argument('-e', '--emulator', |
310 | - help=('Emulator to use (kvm and qemu are supported, ' |
311 | - 'kvm will be favored if available)')) |
312 | - parser.add_argument('-i', '--image', type=url_argument, |
313 | - help='Image/ISO file to use for installation') |
314 | - parser.add_argument('-k', '--kernel', type=url_argument, |
315 | - help='Kernel file to use for installation') |
316 | - parser.add_argument('-r', '--initrd', type=url_argument, |
317 | - help='InitRD file to use for installation') |
318 | - parser.add_argument('-p', '--preseed', type=url_argument, |
319 | - help='Preseed file to use for installation') |
320 | - parser.add_argument('-b', '--boot', |
321 | - help='Boot arguments for initial installation') |
322 | - parser.add_argument('-x', '--xml', type=url_argument, |
323 | - help='XML VM definition file') |
324 | - parser.add_argument('-g', '--gigabytes', action='append', |
325 | - help=('Size in gigabytes of virtual disk, ' |
326 | - 'specify more than once for multiple disks')) |
327 | - parser.add_argument('-s', '--series', metavar='SERIES', |
328 | - choices=config.serieschoices, |
329 | - help='Series to use for installation (%(choices)s)') |
330 | - parser.add_argument('-t', '--type', metavar='TYPE', |
331 | - choices=('desktop', 'server', 'mini', 'alternate'), |
332 | - help=('Install type to use for installation ' |
333 | - '(%(choices)s)')) |
334 | - parser.add_argument('-a', '--arch', metavar='ARCH', |
335 | - choices=('i386', 'amd64', 'arm'), |
336 | - help=('Architecture to use for installation ' |
337 | - '(%(choices)s)')) |
338 | parser.add_argument('-v', '--variant', |
339 | help='Variant of architecture, i.e., armel, armhf') |
340 | - parser.add_argument('-n', '--no-destroy', action='store_true', |
341 | - help='Preserve machine after tests have run') |
342 | - parser.add_argument('-d', '--debug', action='store_true', |
343 | - help='Enable debug logging') |
344 | - parser.add_argument('-j', '--json', action='store_true', |
345 | - help='Enable json logging (default is YAML)') |
346 | - parser.add_argument('-f', '--files', action='append', |
347 | - help='File or directory to copy from test system ') |
348 | - parser.add_argument('-o', '--outdir', |
349 | - help=('Directory to store locally copied files ' |
350 | - '(Default is ' + config.logpath + |
351 | - '/machine-name)')) |
352 | - parser.add_argument('--diskbus', metavar='DISKBUS', |
353 | - choices=('virtio', 'sata', 'ide'), |
354 | - help=('Disk bus to use for customvm installation ' |
355 | - '(%(choices)s)')) |
356 | - parser.add_argument('--name', help='Name of machine to provision' |
357 | - + ' (currently only supported for physical machine' |
358 | - + ' provisioning)') |
359 | - parser.add_argument('--rewrite', choices=('all', 'minimal', 'casperonly', |
360 | - 'none'), help='Enable or disable automatic ' |
361 | - 'configuration rewriting') |
362 | - parser.add_argument('--dumplogs', action='store_true', |
363 | - help='Write client output logs to standard out') |
364 | + parser = common_arguments(parser) |
365 | + parser = custom_arguments(parser) |
366 | + parser = file_arguments(parser) |
367 | + parser = name_argument(parser) |
368 | + parser = virtual_arguments(parser) |
369 | return parser |
370 | |
371 | |
372 | |
373 | === modified file 'utah/config.py' |
374 | --- utah/config.py 2012-12-11 09:03:17 +0000 |
375 | +++ utah/config.py 2012-12-19 19:47:27 +0000 |
376 | @@ -106,6 +106,9 @@ |
377 | nfsconfigfile=os.path.join('/', 'etc', 'exports'), |
378 | # Default options for NFS shares |
379 | nfsoptions='*(ro,async,no_root_squash,no_subtree_check)', |
380 | + # Whether to output the final preseed file as a log file during the main |
381 | + # Provision/Run Tests/Gather Results process |
382 | + outputpreseed=False, |
383 | # Directory where utah client and other needed packages reside |
384 | packagedir=os.path.join('/', 'usr', 'share', 'utah'), |
385 | # Time to wait between power off and power on for physical systems |
386 | |
387 | === modified file 'utah/provisioning/provisioning.py' |
388 | --- utah/provisioning/provisioning.py 2012-12-12 18:56:13 +0000 |
389 | +++ utah/provisioning/provisioning.py 2012-12-19 19:47:27 +0000 |
390 | @@ -202,6 +202,8 @@ |
391 | self.logger.debug(path + ' is locally available as ' |
392 | + getattr(self, item)) |
393 | |
394 | + self.finalpreseed = self.preseed |
395 | + |
396 | self.logger.debug('Machine init finished') |
397 | |
398 | def _namesetup(self, name=None): |
399 | @@ -600,15 +602,37 @@ |
400 | """ |
401 | if self.clean: |
402 | self.logger.debug('Running cleanup') |
403 | + for function in tuple(self.cleanfunctions): |
404 | + timeout, command, args, kw = function |
405 | + self.logger.debug('Running: ' + |
406 | + commandstr(command, *args, **kw)) |
407 | + try: |
408 | + utah.timeout.timeout(timeout, command, *args, **kw) |
409 | + except Exception as err: |
410 | + logger.warning('Exception while running cleanup ' |
411 | + 'function: {}'.format(str(err))) |
412 | + self.cleanfunctions.remove(function) |
413 | + for command in tuple(self.cleancommands): |
414 | + self._runargs(command) |
415 | + self.cleancommands.remove(command) |
416 | for path in tuple(self.cleanfiles): |
417 | if os.path.islink(path): |
418 | self.logger.debug('Removing link ' + path) |
419 | os.unlink(path) |
420 | elif os.path.isfile(path): |
421 | self.logger.debug('Changing permissions of ' + path) |
422 | - os.chmod(path, 0664) |
423 | + try: |
424 | + os.chmod(path, 0664) |
425 | + except OSError as err: |
426 | + self.logger.warning('OSError when changing file ' |
427 | + 'permissions: {}' |
428 | + .format(str(err))) |
429 | self.logger.debug('Removing file ' + path) |
430 | - os.unlink(path) |
431 | + try: |
432 | + os.unlink(path) |
433 | + except OSError as err: |
434 | + self.logger.warning('OSError when removing file: {}' |
435 | + .format(str(err))) |
436 | elif os.path.isdir(path): |
437 | # Cribbed from http://svn.python.org |
438 | # /projects/python/trunk/Mac/BuildScript/build-installer.py |
439 | @@ -618,23 +642,24 @@ |
440 | if not os.path.islink(absolute_name): |
441 | self.logger.debug('Changing permissions of ' |
442 | + absolute_name) |
443 | - os.chmod(absolute_name, 0775) |
444 | + try: |
445 | + os.chmod(absolute_name, 0775) |
446 | + except OSError as err: |
447 | + self.logger.warning('OSError when ' |
448 | + 'changing directory permissions: {}' |
449 | + .format(str(err))) |
450 | self.logger.debug('Recursively Removing directory ' |
451 | + path) |
452 | - shutil.rmtree(path) |
453 | + try: |
454 | + shutil.rmtree(path) |
455 | + except OSError as err: |
456 | + self.logger.warning('OSError when removing ' |
457 | + 'directory: {}' |
458 | + .format(str(err))) |
459 | else: |
460 | self.logger.debug(path + ' is not a link, file, or ' |
461 | 'directory; not removing') |
462 | self.cleanfiles.remove(path) |
463 | - for function in tuple(self.cleanfunctions): |
464 | - timeout, command, args, kw = function |
465 | - self.logger.debug('Running: ' + |
466 | - commandstr(command, *args, **kw)) |
467 | - utah.timeout.timeout(timeout, command, *args, **kw) |
468 | - self.cleanfunctions.remove(function) |
469 | - for command in tuple(self.cleancommands): |
470 | - self._runargs(command) |
471 | - self.cleancommands.remove(command) |
472 | else: |
473 | self.logger.debug('Not cleaning up') |
474 | |
475 | @@ -817,6 +842,7 @@ |
476 | 'initrd.d', 'preseed.cfg') |
477 | with open(output_preseed_filename, 'w') as f: |
478 | f.write(preseed.dump()) |
479 | + self.finalpreseed = output_preseed_filename |
480 | else: |
481 | self.logger.info('Not altering preseed because rewrite is ' + |
482 | self.rewrite) |
483 | |
484 | === modified file 'utah/provisioning/vm/vm.py' |
485 | --- utah/provisioning/vm/vm.py 2012-12-12 20:55:35 +0000 |
486 | +++ utah/provisioning/vm/vm.py 2012-12-19 19:47:27 +0000 |
487 | @@ -528,12 +528,7 @@ |
488 | self.logger.info('Setting up final VM') |
489 | self.vm = self.lv.defineXML(ElementTree.tostring(xml.getroot())) |
490 | |
491 | - if self.debug: |
492 | - self.logger.info('Leaving temp directory ' |
493 | - 'because debug is enabled: ' + tmpdir) |
494 | - else: |
495 | - self.logger.info('Cleaning up temp directory') |
496 | - shutil.rmtree(tmpdir) |
497 | + self.cleanfile(tmpdir) |
498 | return True |
499 | |
500 | def _start(self): |
501 | |
502 | === modified file 'utah/run.py' |
503 | --- utah/run.py 2012-12-13 18:48:32 +0000 |
504 | +++ utah/run.py 2012-12-19 19:47:27 +0000 |
505 | @@ -21,9 +21,89 @@ |
506 | import time |
507 | import urllib |
508 | import traceback |
509 | +import shutil |
510 | |
511 | from utah import config |
512 | from utah.exceptions import UTAHException |
513 | +from utah.url import url_argument |
514 | + |
515 | + |
516 | +def common_arguments(parser): |
517 | + parser.add_argument('runlist', metavar='runlist', |
518 | + help='URLs of runlist files to run') |
519 | + parser.add_argument('-s', '--series', metavar='SERIES', |
520 | + choices=config.serieschoices, |
521 | + help='Series to use for VM creation (%(choices)s)') |
522 | + parser.add_argument('-t', '--type', metavar='TYPE', |
523 | + choices=('desktop', 'server', 'mini', 'alternate'), |
524 | + help=('Install type to use for VM creation ' |
525 | + '(%(choices)s)')) |
526 | + parser.add_argument('-a', '--arch', metavar='ARCH', |
527 | + choices=('i386', 'amd64'), |
528 | + help=('Architecture to use for VM creation ' |
529 | + '(%(choices)s)')) |
530 | + parser.add_argument('-n', '--no-destroy', action='store_true', |
531 | + help='Preserve VM after tests have run') |
532 | + parser.add_argument('-d', '--debug', action='store_true', |
533 | + help='Enable debug logging') |
534 | + parser.add_argument('-j', '--json', action='store_true', |
535 | + help='Enable json logging (default is YAML)') |
536 | + parser.add_argument('-f', '--files', action='append', |
537 | + help='File or directory to copy from test system ') |
538 | + parser.add_argument('-o', '--outdir', |
539 | + help=('Directory to store locally copied files ' |
540 | + '(Default is ' + config.logpath + |
541 | + '/machine-name)')) |
542 | + parser.add_argument('--dumplogs', action='store_true', |
543 | + help='Write client output logs to standard out') |
544 | + parser.add_argument('--outputpreseed', action='store_true', |
545 | + help='Copy preseed to logs directory and list as ' |
546 | + 'log file in output') |
547 | + return parser |
548 | + |
549 | + |
550 | +def custom_arguments(parser): |
551 | + parser.add_argument('-i', '--image', type=url_argument, |
552 | + help='Image/ISO file to use for installation') |
553 | + parser.add_argument('-p', '--preseed', type=url_argument, |
554 | + help='Preseed file to use for installation') |
555 | + parser.add_argument('-b', '--boot', |
556 | + help='Boot arguments for initial installation') |
557 | + parser.add_argument('--rewrite', choices=('all', 'minimal', 'casperonly', |
558 | + 'none'), help='Enable or disable automatic ' |
559 | + 'configuration rewriting') |
560 | + return parser |
561 | + |
562 | + |
563 | +def file_arguments(parser): |
564 | + parser.add_argument('-k', '--kernel', type=url_argument, |
565 | + help='Kernel file to use for installation') |
566 | + parser.add_argument('-r', '--initrd', type=url_argument, |
567 | + help='InitRD file to use for installation') |
568 | + return parser |
569 | + |
570 | + |
571 | +def name_argument(parser): |
572 | + parser.add_argument('--name', help='Name of machine to provision' |
573 | + + ' (currently only supported for physical machine' |
574 | + + ' provisioning)') |
575 | + return parser |
576 | + |
577 | + |
578 | +def virtual_arguments(parser): |
579 | + parser.add_argument('-e', '--emulator', |
580 | + help=('Emulator to use (kvm and qemu are supported, ' |
581 | + 'kvm will be favored if available)')) |
582 | + parser.add_argument('-x', '--xml', type=url_argument, |
583 | + help='XML VM definition file') |
584 | + parser.add_argument('-g', '--gigabytes', action='append', |
585 | + help=('Size in gigabytes of virtual disk, ' |
586 | + 'specify more than once for multiple disks')) |
587 | + parser.add_argument('--diskbus', metavar='DISKBUS', |
588 | + choices=('virtio', 'sata', 'ide'), |
589 | + help=('Disk bus to use for customvm installation ' |
590 | + '(%(choices)s)')) |
591 | + return parser |
592 | |
593 | |
594 | def run_tests(args, machine): |
595 | @@ -105,14 +185,12 @@ |
596 | 'Writing empty reports.') |
597 | |
598 | # Make sure that default logs are written |
599 | - for runlist in args.runlists: |
600 | - _write(runlist) |
601 | + _write(args.runlist) |
602 | exitstatus = 1 |
603 | else: |
604 | # Server will return success code only if the execution |
605 | # of every runlist was successful |
606 | - exitstatuses = [_run(runlist) for runlist in args.runlists] |
607 | - exitstatus = int(any(exitstatuses)) |
608 | + exitstatus = _run(args.runlist) |
609 | |
610 | if args.files is not None: |
611 | try: |
612 | @@ -120,6 +198,17 @@ |
613 | except Exception as err: |
614 | machine.logger.warning('Failed to download files: ' + str(err)) |
615 | |
616 | + if args.outputpreseed or config.outputpreseed: |
617 | + if args.outputpreseed: |
618 | + machine.logger.debug('Capturing preseed due to ' |
619 | + 'command line option') |
620 | + elif config.outputpreseed: |
621 | + machine.logger.debug('Capturing preseed due to config option') |
622 | + preseedfile = os.path.join(config.logpath, |
623 | + machine.name + '-preseed.cfg') |
624 | + shutil.copyfile(machine.finalpreseed, preseedfile) |
625 | + locallogs.append(preseedfile) |
626 | + |
627 | return exitstatus, locallogs |
628 | |
629 |
I think it looks good, but I'd like you to update the code to merge nicely
after the reorganization changes, so that it can be easily tested.
Also, I've got a couple of comments that don't necessarily need to be addressed
now:
1) Arguments
Given that we've got several binaries with the same arguments (together with
slight differentces), it's quite against DRY having to write the same argument
5 times. We should be able to factor that out at least to some prototype:
(somewhere in a common file) argument = {'name': '--outputpreseed',
'action' : store_true',
'help' : Copy preseed to logs directory and list as log file in output',
}
outputpreseed_
(in every script) add_argument( **outputpreseed _argument)
parser.
2) Default values
I think that having always the options to pass a command line argument or setting the
same thing in a configuration file like in the following line:
if args.outputpreseed or config. outputpreseed:
can be confusing in a shared environment where the configuration won't be
controlled by a single person. To reduce the confusion a little bit, I propose
to dump in the logs what's the actual configuration UTAH is going to be used,
so that when unexpected behavior happens, it can be checked it that actually
matches with the final configuration from different sources.