Merge lp:~nuclearbob/utah/no-rewrite into lp:utah
- no-rewrite
- Merge into dev
Status: | Merged |
---|---|
Merged at revision: | 701 |
Proposed branch: | lp:~nuclearbob/utah/no-rewrite |
Merge into: | lp:utah |
Diff against target: |
607 lines (+265/-201) 6 files modified
examples/run_install_test.py (+4/-1) examples/run_test_cobbler.py (+4/-1) examples/run_utah_tests.py (+3/-0) utah/config.py (+1/-0) utah/provisioning/provisioning.py (+135/-99) utah/provisioning/vm/libvirtvm.py (+118/-100) |
To merge this branch: | bzr merge lp:~nuclearbob/utah/no-rewrite |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Javier Collado (community) | Needs Fixing | ||
Review via email:
|
Commit message
Description of the change
This adds a config option and a command line option to remove the configuration rewriting currently done to allow an automated install.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Javier Collado (javier.collado) wrote : | # |
I tried to test the changes running the following command:
$ PYTHONPATH=. ./examples/
and I got this error:
Traceback (most recent call last):
File "./examples/
run_
File "./examples/
function(
File "/home/
exitstatus, locallogs = run_tests(args, machine)
File "/home/
machine.
File "/home/
self.
File "/home/
self.
File "/home/
self.
File "/home/
utah.
File "/home/
retval = command(*args, **kw)
File "/home/
self._create()
File "/home/
self.
File "/home/
vm.create()
File "/usr/lib/
if ret == -1: raise libvirtError ('virDomainCreate() failed', dom=self)
libvirt.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Max Brustkern (nuclearbob) wrote : | # |
Refactoring the preseed setup is possible. It's setup the way it is right now so that we don't have to make multiple passes over the file. Probably there's some way to do templating or filtering that would make the whole thing less of a mess, but I'm not familiar enough with any better system to use it. If you have something in mind, I'd be happy to rewrite it using that.
The flush is currently necessary because the preseed file can be longer than the default file buffer. We flush after every line to make sure the buffer doesn't fill up. Maybe just using a larger buffer would be better.
Automating livecd behavior seems like something we'd want a custom InitRD for. The ISO testing code I think did support packing arbitrary files into an InitRD, so if we need that added to utah, that's doable. I'm not sure of the best format for that? We could support a directory structure or an archive of files to be overlaid into the initrd, or if we have a specific purpose in mind, like casper hooks, we can add something to write scripts for that. Perhaps I need to take a better look at what we're trying to do.
I suppose one more test of self.rewrite in cases where it isn't 'all' isn't going to ruin performance for everything else. I can unindent that block.
Thanks for all the feedback!
I like your table. Maybe I can make a better one, but I'm not entirely sure. I'm not great at tables.
'internal error cannot load AppArmor profile' is something I've seen before, but never consistently enough to track it down. If you're always getting that with these options, we probably need to modify the default XML.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Javier Collado (javier.collado) wrote : | # |
Regarding the preseed, I'm working on some changes to parse the preseed file and expose some methods to update the contents easily and write them to another file. I'll create a merge proposal when I'm done so that you can take a look at it and let me know what do you think.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Javier Collado (javier.collado) wrote : | # |
I've pushed a branch with the changes explained in the comment above here:
lp:~javier.collado/utah/preseed-parser
I haven't created a merge proposal because I don't really see huge improvements since the final code is really close to the original one (just the "for line in file" loop has been removed). Anyway, if you want to take a look at it just in case it leads to a better idea. Maybe using templates as you mentioned, could be an improvement. I've got to think about that.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Max Brustkern (nuclearbob) wrote : | # |
I like your changes. The whole "line in preseed" thing seems much more like good python than just looping over the file. That also makes it very easy to say "if line in preseed, then edit the line, else add the line" which is something I've wanted to add at some point.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Javier Collado (javier.collado) wrote : | # |
@Max
Please let me know if there's some way I can help with this. If you like, I could create a new branch based on yours, go through the issues in my first comment and create a merge request with fixes for some of them (I still don't know how would I boot up from a livecd though).
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Max Brustkern (nuclearbob) wrote : | # |
If you want to make a branch with the changes, go ahead. I've been planning to, but I've been mostly trying to get arm working first, so I had planned to come back to this next week.
Preview Diff
1 | === modified file 'examples/run_install_test.py' |
2 | --- examples/run_install_test.py 2012-08-20 20:56:16 +0000 |
3 | +++ examples/run_install_test.py 2012-08-30 20:00:24 +0000 |
4 | @@ -61,6 +61,9 @@ |
5 | help='Enable json logging (Default is YAML)') |
6 | parser.add_argument('--diskbus', choices=('virtio', 'sata', 'ide'), |
7 | help='Disk bus to use for customvm installation') |
8 | + parser.add_argument('--rewrite', choices=('all', 'minimal', 'casperonly', |
9 | + 'none'), help='Enable or disable automatic ' |
10 | + 'configuration rewriting') |
11 | return parser |
12 | |
13 | |
14 | @@ -84,7 +87,7 @@ |
15 | dlpercentincrement=10, emulator=args.emulator, |
16 | image=args.image, initrd=args.initrd, installtype=args.type, |
17 | kernel=args.kernel, new=True, preseed=args.preseed, |
18 | - series=args.series, xml=args.xml) |
19 | + rewrite=args.rewrite, series=args.series, xml=args.xml) |
20 | exitstatus, locallogs = run_tests(args, machine) |
21 | |
22 | except UTAHException as error: |
23 | |
24 | === modified file 'examples/run_test_cobbler.py' |
25 | --- examples/run_test_cobbler.py 2012-08-28 15:35:55 +0000 |
26 | +++ examples/run_test_cobbler.py 2012-08-30 20:00:24 +0000 |
27 | @@ -40,6 +40,9 @@ |
28 | help='Enable debug logging') |
29 | parser.add_argument('-j', '--json', action='store_true', |
30 | help='Enable json logging (Default is YAML)') |
31 | + parser.add_argument('--rewrite', choices=('all', 'minimal', 'casperonly', |
32 | + 'none'), help='Enable or disable automatic ' |
33 | + 'configuration rewriting') |
34 | return parser |
35 | |
36 | |
37 | @@ -65,7 +68,7 @@ |
38 | try: |
39 | inventory = ManualCobblerSQLiteInventory() |
40 | kw = {} |
41 | - for arg in ['image', 'preseed']: |
42 | + for arg in ['image', 'preseed', 'rewrite']: |
43 | value = vars(args)[arg] |
44 | if value is not None: |
45 | kw.update([(arg, value)]) |
46 | |
47 | === modified file 'examples/run_utah_tests.py' |
48 | --- examples/run_utah_tests.py 2012-08-14 15:42:17 +0000 |
49 | +++ examples/run_utah_tests.py 2012-08-30 20:00:24 +0000 |
50 | @@ -63,6 +63,9 @@ |
51 | parser.add_argument('--name', help='Name of machine to provision' |
52 | + ' (currently only supported for physical machine' |
53 | + ' provisioning)') |
54 | + parser.add_argument('--rewrite', choices=('all', 'minimal', 'casperonly', |
55 | + 'none'), help='Enable or disable automatic ' |
56 | + 'configuration rewriting') |
57 | return parser |
58 | |
59 | |
60 | |
61 | === modified file 'utah/config.py' |
62 | --- utah/config.py 2012-08-22 15:20:25 +0000 |
63 | +++ utah/config.py 2012-08-30 20:00:24 +0000 |
64 | @@ -45,6 +45,7 @@ |
65 | powertimeout=5, |
66 | preseed=None, |
67 | qemupath='qemu:///system', |
68 | + rewrite='all', |
69 | series='precise', |
70 | template=None, |
71 | ) |
72 | |
73 | === modified file 'utah/provisioning/provisioning.py' |
74 | --- utah/provisioning/provisioning.py 2012-08-29 18:46:24 +0000 |
75 | +++ utah/provisioning/provisioning.py 2012-08-30 20:00:24 +0000 |
76 | @@ -43,8 +43,8 @@ |
77 | def __init__(self, arch=None, debug=False, directory=None, image=None, |
78 | dlpercentincrement=1, initrd=None, installtype=None, |
79 | kernel=None, machineid=None, machineuuid=None, name=None, |
80 | - new=False, prefix='utah', preseed=None, series=None, |
81 | - template=None, xml=None): |
82 | + new=False, prefix='utah', preseed=None, rewrite=None, |
83 | + series=None, template=None, xml=None): |
84 | """ |
85 | Initialize the object representing the machine. |
86 | One of these groups of arguments should be included: |
87 | @@ -71,6 +71,13 @@ |
88 | new: Request a new machine (or a reinstall if a specific machine |
89 | was requested.) |
90 | prefix: prefix for automatically named machines. |
91 | + rewrite: How much to alter supplied preseed and xml files. |
92 | + all: everything we need for an automated install |
93 | + minimal: insert latecommand into preseed |
94 | + insert preseed into casper (desktop only) |
95 | + edit VM XML to handle reboots properly |
96 | + casperonly: insert preseed into casper (desktop only) |
97 | + none: do not alter preseed or VM XML |
98 | """ |
99 | # TODO: Make this work right with super at some point. |
100 | self.arch = arch |
101 | @@ -86,6 +93,11 @@ |
102 | self._namesetup(name) |
103 | self._dirsetup(directory) |
104 | |
105 | + if rewrite is None: |
106 | + self.rewrite = config.rewrite |
107 | + else: |
108 | + self.rewrite = rewrite |
109 | + |
110 | if machineuuid is None: |
111 | self.uuid = str(uuid.uuid4()) |
112 | else: |
113 | @@ -648,7 +660,6 @@ |
114 | Provide routines for unpacking necessary boot files from images, |
115 | rewriting them to our liking, and repacking them. |
116 | """ |
117 | - # TODO: setup variable(s) to suppress adding and rewriting |
118 | def _preparekernel(self, kernel=None, tmpdir=None): |
119 | """ |
120 | If we haven't been given a kernel file, unpack one from the image. |
121 | @@ -772,86 +783,103 @@ |
122 | self.logger.info('Setting up preseed') |
123 | if tmpdir is None: |
124 | tmpdir = self.tmpdir |
125 | - preseed = open(os.path.join(tmpdir, 'initrd.d', 'preseed.cfg'), 'w') |
126 | - for line in open(self.preseed, 'r'): |
127 | - if 'preseed/late_command string' in line: |
128 | - if self.installtype == 'desktop': |
129 | - self.logger.info('Changing d-i latecommand ' |
130 | - + 'to ubiquity success_command ' |
131 | - + 'and prepending ubiquity lines') |
132 | - line = line.replace('d-i', 'ubiquity') |
133 | - line = line.replace('preseed/late_command string ', |
134 | - ('ubiquity/success_command ' |
135 | - 'string chroot /target sh -c \'' # chroot start |
136 | - 'export LOG_FILE=/var/log/utah-install; ' |
137 | - 'apt-get install -y --force-yes openssh-server ' |
138 | - '>>$LOG_FILE 2>&1 ; ' |
139 | - 'apt-get install -y --force-yes gdebi-core ' |
140 | - '>>$LOG_FILE 2>&1 ; ' |
141 | - '\'; '), # chroot end |
142 | - 1) |
143 | - line = ("ubiquity ubiquity/summary note\n" |
144 | - "ubiquity ubiquity/reboot boolean true\n" |
145 | - + line) |
146 | - else: |
147 | - self.logger.info('Prepending latecommand') |
148 | - line = line.replace('preseed/late_command string ', |
149 | - ('preseed/late_command string ' |
150 | + if self.rewrite in ['all', 'minimal']: |
151 | + preseed = open(os.path.join(tmpdir, 'initrd.d', 'preseed.cfg') |
152 | + , 'w') |
153 | + for line in open(self.preseed, 'r'): |
154 | + if 'preseed/late_command string' in line: |
155 | + if self.installtype == 'desktop': |
156 | + self.logger.info('Changing d-i latecommand ' |
157 | + + 'to ubiquity success_command ' |
158 | + + 'and prepending ubiquity lines') |
159 | + line = line.replace('d-i', 'ubiquity') |
160 | + line = line.replace('preseed/late_command string ', |
161 | + ('ubiquity/success_command ' |
162 | + 'string chroot /target sh -c \'' # chroot |
163 | + 'export LOG_FILE=/var/log/utah-install; ' |
164 | + 'apt-get install -y --force-yes openssh-server ' |
165 | + '>>$LOG_FILE 2>&1 ; ' |
166 | + 'apt-get install -y --force-yes gdebi-core ' |
167 | + '>>$LOG_FILE 2>&1 ; ' |
168 | + '\'; '), # chroot end |
169 | + 1) |
170 | + line = ("ubiquity ubiquity/summary note\n" |
171 | + "ubiquity ubiquity/reboot boolean true\n" |
172 | + + line) |
173 | + else: |
174 | + self.logger.info('Prepending latecommand') |
175 | + line = line.replace('preseed/late_command string ', |
176 | + ('preseed/late_command string ' |
177 | + 'sh utah-latecommand ; '), 1) |
178 | + line = line.rstrip(' ;') |
179 | + if 'ubiquity/success_command string' in line: |
180 | + self.logger.info('Prepending success_command') |
181 | + line = line.replace('ubiquity/success_command string', |
182 | + ('ubiquity/success_command string ' |
183 | 'sh utah-latecommand ; '), 1) |
184 | - line = line.rstrip(' ;') |
185 | - if 'ubiquity/success_command string' in line: |
186 | - self.logger.info('Prepending success_command') |
187 | - line = line.replace('ubiquity/success_command string', |
188 | - ('ubiquity/success_command string ' |
189 | - 'sh utah-latecommand ; '), 1) |
190 | - line = line.rstrip(' ;') |
191 | - if 'pkgsel/include' in line: |
192 | - for pkgname in ('openssh-server', 'gdebi-core'): |
193 | - if pkgname not in line: |
194 | - self.logger.info('Adding {} to preseeded packages' |
195 | - .format(pkgname)) |
196 | - line = line.replace('string ', |
197 | - 'string {} '.format(pkgname)) |
198 | - line = line.rstrip() + "\n" |
199 | - if 'netcfg/get_hostname' in line: |
200 | - self.logger.info('Rewriting hostname to ' + self.name) |
201 | - line = 'd-i netcfg/get_hostname string ' + self.name + "\n" |
202 | - if 'passwd/username' in line: |
203 | - self.logger.info('Rewriting username to ' + config.user) |
204 | - line = 'd-i passwd/username string ' + config.user + "\n" |
205 | - #Now that debug keeps the directory, this may not be needed |
206 | - #self.logger.debug('Preseed line: ' + line) |
207 | - preseed.write(line) |
208 | - preseed.flush() |
209 | - |
210 | - if self.installtype == 'desktop': |
211 | - self.logger.info('Inserting preseed into casper') |
212 | - preseedscript = os.path.join(tmpdir, 'initrd.d', 'scripts', |
213 | - 'casper-bottom', 'utah') |
214 | - open(preseedscript, 'w').write( |
215 | + line = line.rstrip(' ;') |
216 | + if self.rewrite == 'all': |
217 | + if 'pkgsel/include' in line: |
218 | + for pkgname in ('openssh-server', 'gdebi-core'): |
219 | + if pkgname not in line: |
220 | + self.logger.info('Adding {} to preseeded ' |
221 | + 'packages'.format(pkgname)) |
222 | + line = line.replace('string ', |
223 | + 'string {} '.format(pkgname)) |
224 | + line = line.rstrip() + "\n" |
225 | + if 'netcfg/get_hostname' in line: |
226 | + self.logger.info('Rewriting hostname to ' + self.name) |
227 | + line = ('d-i netcfg/get_hostname string ' + |
228 | + self.name + "\n") |
229 | + if 'passwd/username' in line: |
230 | + self.logger.info('Rewriting username to ' + config.user) |
231 | + line = 'd-i passwd/username string ' + config.user + "\n" |
232 | + #Now that debug keeps the directory, this may not be needed |
233 | + #self.logger.debug('Preseed line: ' + line) |
234 | + preseed.write(line) |
235 | + preseed.flush() |
236 | + else: |
237 | + self.logger.info('Not altering preseed because rewrite is ' + |
238 | + self.rewrite) |
239 | + |
240 | + if (self.installtype == 'desktop' and |
241 | + self.rewrite in ['all', 'minimal', 'casperonly']): |
242 | + self._preseedcasper(tmpdir=tmpdir) |
243 | + |
244 | + def _preseedcasper(self, tmpdir=None): |
245 | + """ |
246 | + Insert a preseed file into casper. |
247 | + """ |
248 | + self.logger.info('Inserting preseed into casper') |
249 | + if tmpdir is None: |
250 | + tmpdir = self.tmpdir |
251 | + self.logger.info('Inserting preseed into casper') |
252 | + preseedscript = os.path.join(tmpdir, 'initrd.d', 'scripts', |
253 | + 'casper-bottom', 'utah') |
254 | + open(preseedscript, 'w').write( |
255 | """#!/bin/sh |
256 | |
257 | cp preseed.cfg utah-ssh-key utah-latecommand /root |
258 | cp 50-utahdefault.conf /root/etc/rsyslog.d |
259 | """) |
260 | - os.chmod(preseedscript, 0755) |
261 | - casper_dir = os.path.join(tmpdir, 'initrd.d', 'scripts', |
262 | - 'casper-bottom') |
263 | - tmpfilename = os.path.join(casper_dir, 'ORDER.tmp') |
264 | - tmpfile = open(tmpfilename, 'w') |
265 | - orderfilename = os.path.join(casper_dir, 'ORDER') |
266 | - orderfile = open(orderfilename, 'r') |
267 | - tmpfile.write( |
268 | + os.chmod(preseedscript, 0755) |
269 | + casper_dir = os.path.join(tmpdir, 'initrd.d', 'scripts', |
270 | + 'casper-bottom') |
271 | + tmpfilename = os.path.join(casper_dir, 'ORDER.tmp') |
272 | + tmpfile = open(tmpfilename, 'w') |
273 | + orderfilename = os.path.join(casper_dir, 'ORDER') |
274 | + orderfile = open(orderfilename, 'r') |
275 | + tmpfile.write( |
276 | """/scripts/casper-bottom/utah |
277 | [ -e /conf/param.conf ] && . /conf/param.conf |
278 | """) |
279 | + tmpfile.flush() |
280 | + for line in orderfile: |
281 | + tmpfile.write(line) |
282 | tmpfile.flush() |
283 | - for line in orderfile: |
284 | - tmpfile.write(line) |
285 | - tmpfile.flush() |
286 | - tmpfile.close() |
287 | - orderfile.close() |
288 | - os.rename(tmpfilename, orderfilename) |
289 | + tmpfile.close() |
290 | + orderfile.close() |
291 | + os.rename(tmpfilename, orderfilename) |
292 | |
293 | def _setuplogging(self, tmpdir=None): |
294 | """ |
295 | @@ -925,34 +953,42 @@ |
296 | else: |
297 | self.cmdline = boot |
298 | self.boottimeout = config.boottimeout |
299 | - if self.installtype == 'desktop': |
300 | - if 'automatic-ubiquity' not in self.cmdline: |
301 | - self.logger.info('Adding automatic-ubiquity option ' |
302 | - 'since installtype is desktop') |
303 | - self.cmdline += ' automatic-ubiquity' |
304 | - if 'boot=' not in self.cmdline: |
305 | - self.logger.info('Adding boot=casper option ' |
306 | - 'since installtype is desktop') |
307 | - self.cmdline += ' boot=casper' |
308 | - if 'keyboard-configuration/layoutcode=' not in self.cmdline: |
309 | - self.logger.info('Adding keyboard-configuration/layoutcode=us ' |
310 | - 'option since installtype is desktop') |
311 | - self.cmdline += ' keyboard-configuration/layoutcode=us' |
312 | - if 'noprompt' not in self.cmdline: |
313 | - self.logger.info('Adding noprompt option ' |
314 | - 'since installtype is desktop') |
315 | - self.cmdline += ' noprompt' |
316 | + if self.rewrite == 'all': |
317 | + self.logger.info('Adding needed command line options') |
318 | + if self.installtype == 'desktop': |
319 | + if 'automatic-ubiquity' not in self.cmdline: |
320 | + self.logger.info('Adding automatic-ubiquity option ' |
321 | + 'since installtype is desktop') |
322 | + self.cmdline += ' automatic-ubiquity' |
323 | + if 'boot=' not in self.cmdline: |
324 | + self.logger.info('Adding boot=casper option ' |
325 | + 'since installtype is desktop') |
326 | + self.cmdline += ' boot=casper' |
327 | + if 'keyboard-configuration/layoutcode=' not in self.cmdline: |
328 | + self.logger.info('Adding keyboard-configuration/' |
329 | + 'layoutcode=us option since installtype ' |
330 | + 'is desktop') |
331 | + self.cmdline += ' keyboard-configuration/layoutcode=us' |
332 | + if 'noprompt' not in self.cmdline: |
333 | + self.logger.info('Adding noprompt option ' |
334 | + 'since installtype is desktop') |
335 | + self.cmdline += ' noprompt' |
336 | + else: |
337 | + if (self.installtype == 'server' |
338 | + and 'DEBCONF_DEBUG' not in self.cmdline): |
339 | + self.logger.info('Adding DEBCONF_DEBUG=developer option ' |
340 | + 'since installtype is not server') |
341 | + self.cmdline += ' DEBCONF_DEBUG=developer' |
342 | + if 'debconf/priority=' not in self.cmdline: |
343 | + self.logger.info('Adding debconf/priority=critical option ' |
344 | + 'since installtype is not desktop') |
345 | + self.cmdline += ' debconf/priority=critical' |
346 | else: |
347 | - if (self.installtype == 'server' |
348 | - and 'DEBCONF_DEBUG' not in self.cmdline): |
349 | - self.logger.info('Adding DEBCONF_DEBUG=developer option ' |
350 | - 'since installtype is not server') |
351 | - self.cmdline += ' DEBCONF_DEBUG=developer' |
352 | - if 'debconf/priority=' not in self.cmdline: |
353 | - self.logger.info('Adding debconf/priority=critical option ' |
354 | - 'since installtype is not desktop') |
355 | - self.cmdline += ' debconf/priority=critical' |
356 | + self.logger.info('Not altering command line since rewrite is ' + |
357 | + self.rewrite) |
358 | self.cmdline.strip() |
359 | + self.logger.debug('Boot command line is:') |
360 | + self.logger.debug(self.cmdline) |
361 | |
362 | def _custominit(self, arch=None, boot=None, installtype=None, series=None): |
363 | """ |
364 | |
365 | === modified file 'utah/provisioning/vm/libvirtvm.py' |
366 | --- utah/provisioning/vm/libvirtvm.py 2012-08-24 18:26:16 +0000 |
367 | +++ utah/provisioning/vm/libvirtvm.py 2012-08-30 20:00:24 +0000 |
368 | @@ -477,97 +477,104 @@ |
369 | if tmpdir is None: |
370 | tmpdir = self.tmpdir |
371 | xmlt = ElementTree.ElementTree(file=xml) |
372 | - self.logger.debug('Rewriting basic info') |
373 | - xmlt.find('name').text = self.name |
374 | - xmlt.find('uuid').text = self.uuid |
375 | - self.logger.debug('Setting type to qemu ' |
376 | - 'in case no hardware virtualization present') |
377 | - xmlt.getroot().set('type', self.domaintype) |
378 | - ose = xmlt.find('os') |
379 | - if self.arch == ('i386'): |
380 | - ose.find('type').set('arch', 'i686') |
381 | - elif self.arch == ('amd64'): |
382 | - ose.find('type').set('arch', 'x86_64') |
383 | - else: |
384 | - ose.find('type').set('arch', self.arch) |
385 | - self.logger.debug('Setting up boot info') |
386 | - for kernele in list(ose.iterfind('kernel')): |
387 | - ose.remove(kernel) |
388 | - kernele = ElementTree.Element('kernel') |
389 | - kernele.text = kernel |
390 | - ose.append(kernele) |
391 | - for initrde in list(ose.iterfind('initrd')): |
392 | - ose.remove(initrd) |
393 | - initrde = ElementTree.Element('initrd') |
394 | - initrde.text = initrd |
395 | - ose.append(initrde) |
396 | - for cmdline in list(ose.iterfind('cmdline')): |
397 | - ose.remove(cmdline) |
398 | - cmdlinee = ElementTree.Element('cmdline') |
399 | - cmdlinee.text = cmdline |
400 | - ose.append(cmdlinee) |
401 | - xmlt.find('on_reboot').text = 'destroy' |
402 | - self.logger.debug('Setting up devices') |
403 | - devices = xmlt.find('devices') |
404 | - self.logger.debug('Setting up disks') |
405 | - for disk in list(devices.iterfind('disk')): |
406 | - if disk.get('device') == 'disk': |
407 | - devices.remove(disk) |
408 | - self.logger.debug('Removed existing disk') |
409 | - #TODO: Add a cdrom if none exists |
410 | - if disk.get('device') == 'cdrom': |
411 | - if disk.find('source') is not None: |
412 | - disk.find('source').set('file', self.image.image) |
413 | - self.logger.debug('Rewrote existing CD-ROM') |
414 | + if self.rewrite in ['all', 'minimal']: |
415 | + self.logger.debug('Setting VM to shutdown on reboot') |
416 | + xmlt.find('on_reboot').text = 'destroy' |
417 | + if self.rewrite == 'all': |
418 | + self.logger.debug('Rewriting basic info') |
419 | + xmlt.find('name').text = self.name |
420 | + xmlt.find('uuid').text = self.uuid |
421 | + self.logger.debug('Setting type to qemu in case no ' |
422 | + 'hardware virtualization present') |
423 | + xmlt.getroot().set('type', self.domaintype) |
424 | + ose = xmlt.find('os') |
425 | + if self.arch == ('i386'): |
426 | + ose.find('type').set('arch', 'i686') |
427 | + elif self.arch == ('amd64'): |
428 | + ose.find('type').set('arch', 'x86_64') |
429 | else: |
430 | + ose.find('type').set('arch', self.arch) |
431 | + self.logger.debug('Setting up boot info') |
432 | + for kernele in list(ose.iterfind('kernel')): |
433 | + ose.remove(kernel) |
434 | + kernele = ElementTree.Element('kernel') |
435 | + kernele.text = kernel |
436 | + ose.append(kernele) |
437 | + for initrde in list(ose.iterfind('initrd')): |
438 | + ose.remove(initrd) |
439 | + initrde = ElementTree.Element('initrd') |
440 | + initrde.text = initrd |
441 | + ose.append(initrde) |
442 | + for cmdline in list(ose.iterfind('cmdline')): |
443 | + ose.remove(cmdline) |
444 | + cmdlinee = ElementTree.Element('cmdline') |
445 | + cmdlinee.text = cmdline |
446 | + ose.append(cmdlinee) |
447 | + self.logger.debug('Setting up devices') |
448 | + devices = xmlt.find('devices') |
449 | + self.logger.debug('Setting up disks') |
450 | + for disk in list(devices.iterfind('disk')): |
451 | + if disk.get('device') == 'disk': |
452 | + devices.remove(disk) |
453 | + self.logger.debug('Removed existing disk') |
454 | + #TODO: Add a cdrom if none exists |
455 | + if disk.get('device') == 'cdrom': |
456 | + if disk.find('source') is not None: |
457 | + disk.find('source').set('file', self.image.image) |
458 | + self.logger.debug('Rewrote existing CD-ROM') |
459 | + else: |
460 | + source = ElementTree.Element('source') |
461 | + source.set('file', self.image.image) |
462 | + disk.append(source) |
463 | + self.logger.debug('Added source to existing ' |
464 | + 'CD-ROM') |
465 | + for disk in self.disks: |
466 | + diske = ElementTree.Element('disk') |
467 | + diske.set('type', 'file') |
468 | + diske.set('device', 'disk') |
469 | + driver = ElementTree.Element('driver') |
470 | + driver.set('name', 'qemu') |
471 | + driver.set('type', disk['type']) |
472 | + diske.append(driver) |
473 | source = ElementTree.Element('source') |
474 | - source.set('file', self.image.image) |
475 | - disk.append(source) |
476 | - self.logger.debug('Added source to existing CD-ROM') |
477 | - for disk in self.disks: |
478 | - diske = ElementTree.Element('disk') |
479 | - diske.set('type', 'file') |
480 | - diske.set('device', 'disk') |
481 | - driver = ElementTree.Element('driver') |
482 | - driver.set('name', 'qemu') |
483 | - driver.set('type', disk['type']) |
484 | - diske.append(driver) |
485 | - source = ElementTree.Element('source') |
486 | - source.set('file', disk['file']) |
487 | - diske.append(source) |
488 | - target = ElementTree.Element('target') |
489 | - dev = "vd%s" % (string.ascii_lowercase[self.disks.index(disk)]) |
490 | - target.set('dev', dev) |
491 | - target.set('bus', disk['bus']) |
492 | - diske.append(target) |
493 | - devices.append(diske) |
494 | - self.logger.debug('Added ' + str(disk['size']) + ' disk') |
495 | - macs = list(self.macs) |
496 | - for interface in devices.iterfind('interface'): |
497 | - if interface.get('type') in ['network', 'bridge']: |
498 | - if len(macs) > 0: |
499 | - mac = macs.pop(0) |
500 | - interface.find('mac').set('address', mac) |
501 | - self.logger.debug('Rewrote interface ' |
502 | - 'to use specified mac address ' + mac) |
503 | - else: |
504 | - mac = random_mac_address() |
505 | - interface.find('mac').set('address', mac) |
506 | - self.macs.append(mac) |
507 | - self.logger.debug('Rewrote interface ' |
508 | - 'to use random mac address ' + mac) |
509 | - if interface.get('type') == 'bridge': |
510 | - interface.find('source').set('bridge', config.bridge) |
511 | - serial = ElementTree.Element('serial') |
512 | - serial.set('type', 'file') |
513 | - source = ElementTree.Element('source') |
514 | - log_filename = os.path.join(config.logpath, self.name + '.syslog.log') |
515 | - source.set('path', log_filename) |
516 | - serial.append(source) |
517 | - target = ElementTree.Element('target') |
518 | - target.set('port', '0') |
519 | - serial.append(target) |
520 | - devices.append(serial) |
521 | + source.set('file', disk['file']) |
522 | + diske.append(source) |
523 | + target = ElementTree.Element('target') |
524 | + dev = "vd%s" % (string.ascii_lowercase[self.disks.index(disk)]) |
525 | + target.set('dev', dev) |
526 | + target.set('bus', disk['bus']) |
527 | + diske.append(target) |
528 | + devices.append(diske) |
529 | + self.logger.debug('Added ' + str(disk['size']) + ' disk') |
530 | + macs = list(self.macs) |
531 | + for interface in devices.iterfind('interface'): |
532 | + if interface.get('type') in ['network', 'bridge']: |
533 | + if len(macs) > 0: |
534 | + mac = macs.pop(0) |
535 | + interface.find('mac').set('address', mac) |
536 | + self.logger.debug('Rewrote interface ' |
537 | + 'to use specified mac address ' + mac) |
538 | + else: |
539 | + mac = random_mac_address() |
540 | + interface.find('mac').set('address', mac) |
541 | + self.macs.append(mac) |
542 | + self.logger.debug('Rewrote interface ' |
543 | + 'to use random mac address ' + mac) |
544 | + if interface.get('type') == 'bridge': |
545 | + interface.find('source').set('bridge', config.bridge) |
546 | + serial = ElementTree.Element('serial') |
547 | + serial.set('type', 'file') |
548 | + source = ElementTree.Element('source') |
549 | + log_filename = os.path.join(config.logpath, self.name + '.syslog.log') |
550 | + source.set('path', log_filename) |
551 | + serial.append(source) |
552 | + target = ElementTree.Element('target') |
553 | + target.set('port', '0') |
554 | + serial.append(target) |
555 | + devices.append(serial) |
556 | + else: |
557 | + self.logger.info('Not rewriting XML because rewrite is ' + |
558 | + self.rewrite) |
559 | if self.debug: |
560 | xmlt.write(os.path.join(tmpdir, 'install.xml')) |
561 | self.logger.info('Installation XML ready') |
562 | @@ -609,16 +616,23 @@ |
563 | xml = ElementTree.ElementTree(file=self.xml) |
564 | if tmpdir is None: |
565 | tmpdir = self.tmpdir |
566 | - ose = xml.find('os') |
567 | - for kernel in ose.iterfind('kernel'): |
568 | - ose.remove(kernel) |
569 | - for initrd in ose.iterfind('initrd'): |
570 | - ose.remove(initrd) |
571 | - for cmdline in ose.iterfind('cmdline'): |
572 | - ose.remove(cmdline) |
573 | - xml.find('on_reboot').text = 'restart' |
574 | - devices = xml.find('devices') |
575 | - devices.remove(devices.find('serial')) |
576 | + if self.rewrite in ['all', 'minimal']: |
577 | + self.logger.debug('Setting VM to reboot normally on reboot') |
578 | + xml.find('on_reboot').text = 'restart' |
579 | + if self.rewrite == 'all': |
580 | + self.logger.debug('Removing VM install parameters') |
581 | + ose = xml.find('os') |
582 | + for kernel in ose.iterfind('kernel'): |
583 | + ose.remove(kernel) |
584 | + for initrd in ose.iterfind('initrd'): |
585 | + ose.remove(initrd) |
586 | + for cmdline in ose.iterfind('cmdline'): |
587 | + ose.remove(cmdline) |
588 | + devices = xml.find('devices') |
589 | + devices.remove(devices.find('serial')) |
590 | + else: |
591 | + self.logger.info('Not rewriting XML because rewrite is ' + |
592 | + self.rewrite) |
593 | if self.debug: |
594 | xml.write(os.path.join(tmpdir, 'final.xml')) |
595 | return xml |
596 | @@ -644,7 +658,11 @@ |
597 | |
598 | self._setuppreseed(tmpdir=tmpdir) |
599 | |
600 | - self._setuplogging(tmpdir=tmpdir) |
601 | + if self.rewrite == 'all': |
602 | + self._setuplogging(tmpdir=tmpdir) |
603 | + else: |
604 | + self.logger.debug('Skipping logging setup because rewrite is' + |
605 | + self.rewrite) |
606 | |
607 | initrd = self._repackinitrd(tmpdir=tmpdir) |
608 |
Thanks for this change. The rewrite options is a nice step forward to be able
to manage live session scenarios.
Please find below some comments: onMixin. _setuppreseed
- CustomIntallati
- This method is getting quite complex. Could it be refactored into smaller methods?
- I think it's confusing to have both `preseed` and `self.preseed`. What
about something like `input_preseed` and `output_preseed`?
- The files above are opened, but the don't seem to be closed. Maybe using
context managers will make easier to handle them?
- Once `preseed` is properly closed, I don't think `preseed.flush` is needed
- CustomIntallati onMixin. _preseedcasper
- There's a duplicated `logger.info` line
- I see this should make possible to boot the VM from a livecd. However, it
doesn't make possible to add scripts to automate the livecd behaviour right?
For example, in the ISO testing tests, I see that a script is used to
create a desktop file to be automatically executed and run some tests.
- utah.provsionin g.vm.libvirtvm
- It seems that when rewrite='minimal' just a small change is applied and
because of that all the code for 'all' is indented one more level. I
believe this should be refactored:
if self.rewrite in ['all', 'minimal']:
self.logger. debug(' Setting VM to shutdown on reboot')
xmlt.find( 'on_reboot' ).text = 'destroy'
....
....
if self.rewrite == 'all':
Regarding documentation strings, what about having a table to make easier to ng.provisioning .Machine what I read would be
understand what each rewrite options means? In particular, looking at the
docstring in utah.provisioni
roughly equivalent to this:
| preseed | casper | VM xml | other | ------- ------- ------- ------- ------- -----
-------
all | X | X | X | X |
minimal | X | X | X | |
casperonly| | X | | |
none | | | | |
However, I'm sure you can provide a better table.