Merge lp:~nuclearbob/utah/no-rewrite into lp:utah

Proposed by Max Brustkern
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
Reviewer Review Type Date Requested Status
Javier Collado (community) Needs Fixing
Review via email: mp+122137@code.launchpad.net

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.

To post a comment you must log in.
Revision history for this message
Javier Collado (javier.collado) wrote :

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:
- CustomIntallationMixin._setuppreseed
  - 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

- CustomIntallationMixin._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.provsioning.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
understand what each rewrite options means? In particular, looking at the
docstring in utah.provisioning.provisioning.Machine what I read would be
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.

review: Needs Fixing
Revision history for this message
Javier Collado (javier.collado) wrote :

I tried to test the changes running the following command:

$ PYTHONPATH=. ./examples/run_utah_tests.py -i <image> -p <preseed> <runlist> -d -n --rewrite casperonly

and I got this error:

Traceback (most recent call last):
  File "./examples/run_utah_tests.py", line 113, in <module>
    run_utah_tests()
  File "./examples/run_utah_tests.py", line 99, in run_utah_tests
    function(args=args)
  File "/home/javi/code/bzr/utah/no-rewrite/examples/run_install_test.py", line 91, in run_install_test
    exitstatus, locallogs = run_tests(args, machine)
  File "/home/javi/code/bzr/utah/no-rewrite/utah/run.py", line 32, in run_tests
    machine.installclient()
  File "/home/javi/code/bzr/utah/no-rewrite/utah/provisioning/provisioning.py", line 279, in installclient
    self.uploadfiles([clientdeb], tmppath)
  File "/home/javi/code/bzr/utah/no-rewrite/utah/provisioning/provisioning.py", line 532, in uploadfiles
    self.activecheck()
  File "/home/javi/code/bzr/utah/no-rewrite/utah/provisioning/vm/libvirtvm.py", line 93, in activecheck
    self.provisioncheck()
  File "/home/javi/code/bzr/utah/no-rewrite/utah/provisioning/provisioning.py", line 234, in provisioncheck
    utah.timeout.timeout(config.installtimeout, self._provision)
  File "/home/javi/code/bzr/utah/no-rewrite/utah/timeout.py", line 47, in timeout
    retval = command(*args, **kw)
  File "/home/javi/code/bzr/utah/no-rewrite/utah/provisioning/vm/libvirtvm.py", line 66, in _provision
    self._create()
  File "/home/javi/code/bzr/utah/no-rewrite/utah/provisioning/vm/libvirtvm.py", line 674, in _create
    self._installvm(lv=self.lv, tmpdir=tmpdir, xml=xml)
  File "/home/javi/code/bzr/utah/no-rewrite/utah/provisioning/vm/libvirtvm.py", line 597, in _installvm
    vm.create()
  File "/usr/lib/python2.7/dist-packages/libvirt.py", line 551, in create
    if ret == -1: raise libvirtError ('virDomainCreate() failed', dom=self)
libvirt.libvirtError: internal error cannot load AppArmor profile 'libvirt-00000000-0000-0000-0000-000000000000'

Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
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).

Revision history for this message
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

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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

Subscribers

People subscribed via source and target branches