Merge lp:~justin-fathomdb/nova/raw-disk-images into lp:~hudson-openstack/nova/trunk

Proposed by justinsb
Status: Superseded
Proposed branch: lp:~justin-fathomdb/nova/raw-disk-images
Merge into: lp:~hudson-openstack/nova/trunk
Prerequisite: lp:~justin-fathomdb/nova/check-subprocess-exit-code
Diff against target: 344 lines (+109/-49)
8 files modified
nova/api/ec2/cloud.py (+10/-4)
nova/compute/disk.py (+13/-5)
nova/flags.py (+3/-0)
nova/virt/libvirt.qemu.xml.template (+14/-10)
nova/virt/libvirt.uml.xml.template (+11/-11)
nova/virt/libvirt.xen.xml.template (+15/-10)
nova/virt/libvirt_conn.py (+42/-9)
tools/pip-requires (+1/-0)
To merge this branch: bzr merge lp:~justin-fathomdb/nova/raw-disk-images
Reviewer Review Type Date Requested Status
termie (community) Needs Fixing
Soren Hansen (community) Needs Fixing
Jay Pipes (community) Needs Fixing
Review via email: mp+33064@code.launchpad.net

This proposal has been superseded by a proposal from 2010-10-14.

Description of the change

Add support for disk images that are 'raw', i.e. don't need a kernel or ramdisk. This makes it simpler to have Windows VMs, or to use VirtualBox as the host. To remain EC2 API compatible, if you specify the kernel as aki-00000000, this triggers the 'raw disk image' behaviour.

To post a comment you must log in.
Revision history for this message
Jay Pipes (jaypipes) wrote :

Hi!

Good stuff, Justin! ++ for long option names :)

A couple tiny nits, though :)

27 + if not os.path.exists(mapped_device):
28 + raise exception.Error('Mapped device was not found: %s' % mapped_device)

There is a NotFound exception class in /nova/exception.py that may be better that raising the generic error here. Or, alternately, you could raise IOError, as that is what is raised by open() when the file does not exist?

77 + # This is correct for Ubuntu, but might not be right for other distros
78 + rulesfile = os.path.join(fs, 'etc', 'udev', 'rules.d', '70-persistent-net.rules')
79 + yield execute('rm -f %s' % rulesfile)

Best to add a TODO(justinsb) there so it's noted for future improvements :)

Finally, not sure about making Cheetah a dependency here...what do other think?

Cheers!
jay

review: Needs Fixing
162. By justinsb

Clarified what the 'Mapped device not found' exception really means.
Fixed TODO.
Some formatting to be closer to 80 chars

Revision history for this message
justinsb (justin-fathomdb) wrote :

Thanks for the review Jay.

The 'mapped device not found' exception is actually tricky; it is expected if we can't read the partitions after loopback, which happens if we have a non-raw-disk-image (i.e. a 'sparse' format). The test is to try to make that case obvious. I'm not sure what we should do here, but currently the caller (at least for virtualbox) ignores errors when trying to inject the machine image. I've therefore left it as a raw exception.Error, but clarified the message to make the intent clearer.

I've added the TODO. Again, there's a big picture question of what we should be injecting and how we should be injecting it; hopefully this will become clearer as we start launching more OSes and the guest agent shapes up (which is required for Windows, I believe)

As for Cheetah, I have no particular reason to choose Cheetah vs any other templating system - it looked like decent syntax, the project seemed not-dead, and there's an Ubuntu package. I would suggest that we do need _a_ templating system, for complex templating or optional inclusions (here I use it so that the kernel and ramdisk XML elements are only output if they are needed). What that templating system is, I don't really care. The one datapoint I have is that Cheetah "works for me", but if anyone else has more experience...

Revision history for this message
Jay Pipes (jaypipes) wrote :

> The 'mapped device not found' exception is actually tricky; it is expected if
> we can't read the partitions after loopback, which happens if we have a non-
> raw-disk-image (i.e. a 'sparse' format). The test is to try to make that case
> obvious. I'm not sure what we should do here, but currently the caller (at
> least for virtualbox) ignores errors when trying to inject the machine image.
> I've therefore left it as a raw exception.Error, but clarified the message to
> make the intent clearer.

OK, understood. I would still recommend making a new exception class in /nova/exception.py (MappedDeviceNotFound?) possibly inherited from IOError. Just makes the code a little cleaner, that's all.

> I've added the TODO. Again, there's a big picture question of what we should
> be injecting and how we should be injecting it; hopefully this will become
> clearer as we start launching more OSes and the guest agent shapes up (which
> is required for Windows, I believe)

Cool :)

> As for Cheetah, I have no particular reason to choose Cheetah vs any other
> templating system - it looked like decent syntax, the project seemed not-dead,
> and there's an Ubuntu package. I would suggest that we do need _a_ templating
> system, for complex templating or optional inclusions (here I use it so that
> the kernel and ramdisk XML elements are only output if they are needed). What
> that templating system is, I don't really care. The one datapoint I have is
> that Cheetah "works for me", but if anyone else has more experience...

Yeah, I'm not sure, which is why I asked others for opinions. I'm not familiar with Python's templating frameworks/libraries.

-jay

Revision history for this message
Soren Hansen (soren) wrote :

I'm cool with Cheetah. I've used it before and I don't know of another templating system that's supposed to be the canonical one.

As for the udev network thing: Ubuntu will refrain from storing the MAC->interface-name mapping if the MAC address is "locally administered". nova.utils.generate_mac() generates such a MAC. If you can somehow get VirtualBox to accept that MAC, you should be able to remove that hack.

> @defer.inlineCallbacks
> -def inject_data(image, key=None, net=None, partition=None, execute=None):
> +def inject_data( image, key=None, net=None, dns=None,
> + remove_network_udev=False,
> + partition=None, execute=None):

PEP-8 says not to put whitespace immediately inside parentheses.

=== modified file 'nova/virt/libvirt_conn.py'
--- nova/virt/libvirt_conn.py 2010-08-18 21:14:24 +0000
+++ nova/virt/libvirt_conn.py 2010-08-24 09:44:45 +0000
@@ -260,13 +275,28 @@
     def toXml(self, instance):
         # TODO(termie): cache?
         logging.debug("Starting the toXML method")
+ template_contents = open(FLAGS.libvirt_xml_template).read()
         xml_info = instance.datamodel.copy()
         # TODO(joshua): Make this xml express the attached disks as well

Since I added UML capabilities to Nova, the template to use is already
put into self.libvirt_xml in __init__. Please use that instead, as
it's based on a different template if libvirt_type is "uml". Also, the
changes you made to libvirt.qemu.xml.template need to be done similarly
for libvirt.uml.xml.template.

Other than that, it looks good, and I'm really looking forward to seeing
this land! :)

review: Needs Fixing
Revision history for this message
Vish Ishaya (vishvananda) wrote :

Justin, did we lose you? I'd like to get this merged, but it looks like there are a few fixes requested.

Revision history for this message
termie (termie) wrote :

I'll just weigh in here on my thoughts about Cheetah, mainly that I think it is bad to allow much logic in the template code. Agreed that we all need conditionals, but seeing 'getVar' in there really throws some flags for me.

A much much smaller but powerful and declarative-style templating engine that I've grown to prefer is called jsontemplate, http://json-template.googlecode.com/svn/trunk/doc/Introducing-JSON-Template.html

Our usage is pretty minimal here so the syntax isn't shockingly different but in Cheetah

#if $getVar('kernel', None)
        <kernel>${kernel}</kernel>
    #if $getVar('ramdisk', None)
        <initrd>${ramdisk}</initrd>
    #end if
        <cmdline>root=/dev/vda1 console=ttyS0</cmdline>
#end if

and

template_contents = open(FLAGS.libvirt_xml_template).read()
str(Template(template_contents, searchList=[ xml_info ] ))

becomes

{.section kernel}
        <kernel>{kernel}</kernel>
    {.section ramdisk}
        <initrd>{ramdisk}</initrd>
    {.end}
        <cmdline>root=/dev/vda1 console=ttyS0</cmdline>
{.end}

and

jsontemplate.FromFile(FLAGS.libvirt_xml_template).expand(xml_info)

The other benefits are that the engine is a single file and easily extensible with formatters

The "json" part of it comes from the fact that it was designed and implemented in python and javascript at the same time.

There are a variety of style nits (extra spaces before or around things, importing objects instead of modules, using tabs instead of spaces in the xml), so please take another scan over the code to resolve those :)

Other than those discussion points looks like a great addition to our core functionality :)

review: Needs Fixing
Revision history for this message
Rick Clark (dendrobates) wrote :

If Justin is willing to fix this up. I am fine with moving forward with cheetah. We can have an in depth discussions about templating engines at the summit if we want.

Today is the last day to get any preexisting feature merge requests merged.
The code base has changed quite a bit since this was proposed. It may be a difficult task to get it done today, but if Justin is will to do the work today, we will merge it.

163. By Justin Santa Barbara <justinsb@justinsb-desktop>

Merged with trunk, fixed broken stuff

164. By Justin Santa Barbara <justinsb@justinsb-desktop>

Minimized diff, fixed formatting

165. By Justin Santa Barbara <justinsb@justinsb-desktop>

Removed stray spaces that were causing an unnecessary diff line

166. By Justin Santa Barbara <justinsb@justinsb-desktop>

Removed 'and True' oddity

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'nova/api/ec2/cloud.py'
--- nova/api/ec2/cloud.py 2010-10-14 06:17:40 +0000
+++ nova/api/ec2/cloud.py 2010-10-14 20:50:58 +0000
@@ -794,9 +794,15 @@
794 kernel_id = kwargs.get('kernel_id', kernel_id)794 kernel_id = kwargs.get('kernel_id', kernel_id)
795 ramdisk_id = kwargs.get('ramdisk_id', ramdisk_id)795 ramdisk_id = kwargs.get('ramdisk_id', ramdisk_id)
796796
797 if kernel_id == str(FLAGS.null_kernel):
798 kernel_id = None
799 ramdisk_id = None
800
797 # make sure we have access to kernel and ramdisk801 # make sure we have access to kernel and ramdisk
798 images.get(context, kernel_id)802 if kernel_id:
799 images.get(context, ramdisk_id)803 images.get(context, kernel_id)
804 if ramdisk_id:
805 images.get(context, ramdisk_id)
800806
801 logging.debug("Going to run %s instances...", num_instances)807 logging.debug("Going to run %s instances...", num_instances)
802 launch_time = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())808 launch_time = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
@@ -823,8 +829,8 @@
823 base_options = {}829 base_options = {}
824 base_options['state_description'] = 'scheduling'830 base_options['state_description'] = 'scheduling'
825 base_options['image_id'] = image_id831 base_options['image_id'] = image_id
826 base_options['kernel_id'] = kernel_id832 base_options['kernel_id'] = kernel_id or ''
827 base_options['ramdisk_id'] = ramdisk_id833 base_options['ramdisk_id'] = ramdisk_id or ''
828 base_options['reservation_id'] = reservation_id834 base_options['reservation_id'] = reservation_id
829 base_options['key_data'] = key_data835 base_options['key_data'] = key_data
830 base_options['key_name'] = kwargs.get('key_name', None)836 base_options['key_name'] = kwargs.get('key_name', None)
831837
=== modified file 'nova/compute/disk.py'
--- nova/compute/disk.py 2010-08-16 12:16:21 +0000
+++ nova/compute/disk.py 2010-10-14 20:50:58 +0000
@@ -96,7 +96,7 @@
96 If partition is not specified it mounts the image as a single partition.96 If partition is not specified it mounts the image as a single partition.
9797
98 """98 """
99 out, err = yield execute('sudo losetup -f --show %s' % image)99 out, err = yield execute('sudo losetup --find --show %s' % image)
100 if err:100 if err:
101 raise exception.Error('Could not attach image to loopback: %s' % err)101 raise exception.Error('Could not attach image to loopback: %s' % err)
102 device = out.strip()102 device = out.strip()
@@ -110,6 +110,15 @@
110 partition)110 partition)
111 else:111 else:
112 mapped_device = device112 mapped_device = device
113
114 # We can only loopback mount raw images. If the device isn't there,
115 # it's normally because it's a .vmdk or a .vdi etc
116 if not os.path.exists(mapped_device):
117 raise exception.Error(
118 'Mapped device was not found (we can only inject raw disk images): %s'
119 % mapped_device)
120
121 # Configure ext2fs so that it doesn't auto-check every N boots
113 out, err = yield execute('sudo tune2fs -c 0 -i 0 %s' % mapped_device)122 out, err = yield execute('sudo tune2fs -c 0 -i 0 %s' % mapped_device)
114123
115 tmpdir = tempfile.mkdtemp()124 tmpdir = tempfile.mkdtemp()
@@ -137,12 +146,12 @@
137 yield execute('sudo kpartx -d %s' % device)146 yield execute('sudo kpartx -d %s' % device)
138 finally:147 finally:
139 # remove loopback148 # remove loopback
140 yield execute('sudo losetup -d %s' % device)149 yield execute('sudo losetup --detach %s' % device)
141150
142151
143@defer.inlineCallbacks152@defer.inlineCallbacks
144def _inject_key_into_fs(key, fs, execute=None):153def _inject_key_into_fs(key, fs, execute=None):
145 sshdir = os.path.join(os.path.join(fs, 'root'), '.ssh')154 sshdir = os.path.join(fs, 'root', '.ssh')
146 yield execute('sudo mkdir -p %s' % sshdir) # existing dir doesn't matter155 yield execute('sudo mkdir -p %s' % sshdir) # existing dir doesn't matter
147 yield execute('sudo chown root %s' % sshdir)156 yield execute('sudo chown root %s' % sshdir)
148 yield execute('sudo chmod 700 %s' % sshdir)157 yield execute('sudo chmod 700 %s' % sshdir)
@@ -152,7 +161,6 @@
152161
153@defer.inlineCallbacks162@defer.inlineCallbacks
154def _inject_net_into_fs(net, fs, execute=None):163def _inject_net_into_fs(net, fs, execute=None):
155 netfile = os.path.join(os.path.join(os.path.join(164 netfile = os.path.join(fs, 'etc', 'network', 'interfaces')
156 fs, 'etc'), 'network'), 'interfaces')
157 yield execute('sudo tee %s' % netfile, net)165 yield execute('sudo tee %s' % netfile, net)
158166
159167
=== modified file 'nova/flags.py'
--- nova/flags.py 2010-10-01 20:06:14 +0000
+++ nova/flags.py 2010-10-14 20:50:58 +0000
@@ -201,6 +201,9 @@
201 'default ramdisk to use, testing only')201 'default ramdisk to use, testing only')
202DEFINE_string('default_instance_type', 'm1.small',202DEFINE_string('default_instance_type', 'm1.small',
203 'default instance type to use, testing only')203 'default instance type to use, testing only')
204DEFINE_string('null_kernel', 'aki-00000000',
205 'kernel image that indicates not to use a kernel, '
206 ' but to use a raw disk image instead')
204207
205DEFINE_string('vpn_image_id', 'ami-CLOUDPIPE', 'AMI for cloudpipe vpn server')208DEFINE_string('vpn_image_id', 'ami-CLOUDPIPE', 'AMI for cloudpipe vpn server')
206DEFINE_string('vpn_key_suffix',209DEFINE_string('vpn_key_suffix',
207210
=== modified file 'nova/virt/libvirt.qemu.xml.template'
--- nova/virt/libvirt.qemu.xml.template 2010-09-27 11:13:29 +0000
+++ nova/virt/libvirt.qemu.xml.template 2010-10-14 20:50:58 +0000
@@ -1,24 +1,28 @@
1<domain type='%(type)s'>1<domain type='${type}'>
2 <name>%(name)s</name>2 <name>${name}</name>
3 <os>3 <os>
4 <type>hvm</type>4 <type>hvm</type>
5 <kernel>%(basepath)s/kernel</kernel>5#if $getVar('kernel', None)
6 <initrd>%(basepath)s/ramdisk</initrd>6 <kernel>${kernel}</kernel>
7 #if $getVar('ramdisk', None)
8 <initrd>${ramdisk}</initrd>
9 #end if
7 <cmdline>root=/dev/vda1 console=ttyS0</cmdline>10 <cmdline>root=/dev/vda1 console=ttyS0</cmdline>
11#end if
8 </os>12 </os>
9 <features>13 <features>
10 <acpi/>14 <acpi/>
11 </features>15 </features>
12 <memory>%(memory_kb)s</memory>16 <memory>${memory_kb}</memory>
13 <vcpu>%(vcpus)s</vcpu>17 <vcpu>${vcpus}</vcpu>
14 <devices>18 <devices>
15 <disk type='file'>19 <disk type='file'>
16 <source file='%(basepath)s/disk'/>20 <source file='${disk}'/>
17 <target dev='vda' bus='virtio'/>21 <target dev='vda' bus='virtio'/>
18 </disk>22 </disk>
19 <interface type='bridge'>23 <interface type='bridge'>
20 <source bridge='%(bridge_name)s'/>24 <source bridge='${bridge_name}'/>
21 <mac address='%(mac_address)s'/>25 <mac address='${mac_address}'/>
22 <!-- <model type='virtio'/> CANT RUN virtio network right now -->26 <!-- <model type='virtio'/> CANT RUN virtio network right now -->
23 <filterref filter="nova-instance-%(name)s">27 <filterref filter="nova-instance-%(name)s">
24 <parameter name="IP" value="%(ip_address)s" />28 <parameter name="IP" value="%(ip_address)s" />
@@ -26,7 +30,7 @@
26 </filterref>30 </filterref>
27 </interface>31 </interface>
28 <serial type="file">32 <serial type="file">
29 <source path='%(basepath)s/console.log'/>33 <source path='${basepath}/console.log'/>
30 <target port='1'/>34 <target port='1'/>
31 </serial>35 </serial>
32 </devices>36 </devices>
3337
=== modified file 'nova/virt/libvirt.uml.xml.template'
--- nova/virt/libvirt.uml.xml.template 2010-09-27 11:13:29 +0000
+++ nova/virt/libvirt.uml.xml.template 2010-10-14 20:50:58 +0000
@@ -1,26 +1,26 @@
1<domain type='%(type)s'>1<domain type='${type}'>
2 <name>%(name)s</name>2 <name>${name}</name>
3 <memory>%(memory_kb)s</memory>3 <memory>${memory_kb}</memory>
4 <os>4 <os>
5 <type>%(type)s</type>5 <type>${type}</type>
6 <kernel>/usr/bin/linux</kernel>6 <kernel>/usr/bin/linux</kernel>
7 <root>/dev/ubda1</root>7 <root>/dev/ubda1</root>
8 </os>8 </os>
9 <devices>9 <devices>
10 <disk type='file'>10 <disk type='file'>
11 <source file='%(basepath)s/disk'/>11 <source file='${disk}'/>
12 <target dev='ubd0' bus='uml'/>12 <target dev='ubd0' bus='uml'/>
13 </disk>13 </disk>
14 <interface type='bridge'>14 <interface type='bridge'>
15 <source bridge='%(bridge_name)s'/>15 <source bridge='${bridge_name}'/>
16 <mac address='%(mac_address)s'/>16 <mac address='${mac_address}'/>
17 <filterref filter="nova-instance-%(name)s">17 <filterref filter="nova-instance-${name}">
18 <parameter name="IP" value="%(ip_address)s" />18 <parameter name="IP" value="${ip_address}" />
19 <parameter name="DHCPSERVER" value="%(dhcp_server)s" />19 <parameter name="DHCPSERVER" value="${dhcp_server}" />
20 </filterref>20 </filterref>
21 </interface>21 </interface>
22 <console type="file">22 <console type="file">
23 <source path='%(basepath)s/console.log'/>23 <source path='${basepath}/console.log'/>
24 </console>24 </console>
25 </devices>25 </devices>
26</domain>26</domain>
2727
=== modified file 'nova/virt/libvirt.xen.xml.template'
--- nova/virt/libvirt.xen.xml.template 2010-09-20 09:33:35 +0000
+++ nova/virt/libvirt.xen.xml.template 2010-10-14 20:50:58 +0000
@@ -1,28 +1,33 @@
1<domain type='%(type)s'>1<domain type='${type}'>
2 <name>%(name)s</name>2 <name>${name}</name>
3 <os>3 <os>
4 <type>linux</type>4 <type>linux</type>
5 <kernel>%(basepath)s/kernel</kernel>5#if $getVar('kernel', None)
6 <initrd>%(basepath)s/ramdisk</initrd>6 <kernel>${kernel}</kernel>
7 #if $getVar('ramdisk', None)
8 <initrd>${ramdisk}</initrd>
9 #end if
10 <cmdline>root=/dev/vda1 console=ttyS0</cmdline>
11#end if
7 <root>/dev/xvda1</root>12 <root>/dev/xvda1</root>
8 <cmdline>ro</cmdline>13 <cmdline>ro</cmdline>
9 </os>14 </os>
10 <features>15 <features>
11 <acpi/>16 <acpi/>
12 </features>17 </features>
13 <memory>%(memory_kb)s</memory>18 <memory>${memory_kb}</memory>
14 <vcpu>%(vcpus)s</vcpu>19 <vcpu>${vcpus}</vcpu>
15 <devices>20 <devices>
16 <disk type='file'>21 <disk type='file'>
17 <source file='%(basepath)s/disk'/>22 <source file='${disk}'/>
18 <target dev='sda' />23 <target dev='sda' />
19 </disk>24 </disk>
20 <interface type='bridge'>25 <interface type='bridge'>
21 <source bridge='%(bridge_name)s'/>26 <source bridge='${bridge_name}'/>
22 <mac address='%(mac_address)s'/>27 <mac address='${mac_address}'/>
23 </interface>28 </interface>
24 <console type="file">29 <console type="file">
25 <source path='%(basepath)s/console.log'/>30 <source path='${basepath}/console.log'/>
26 <target port='1'/>31 <target port='1'/>
27 </console>32 </console>
28 </devices>33 </devices>
2934
=== modified file 'nova/virt/libvirt_conn.py'
--- nova/virt/libvirt_conn.py 2010-10-13 17:13:35 +0000
+++ nova/virt/libvirt_conn.py 2010-10-14 20:50:58 +0000
@@ -42,6 +42,8 @@
42from nova.compute import power_state42from nova.compute import power_state
43from nova.virt import images43from nova.virt import images
4444
45from Cheetah.Template import Template
46
45libvirt = None47libvirt = None
46libxml2 = None48libxml2 = None
4749
@@ -321,16 +323,26 @@
321323
322 if not os.path.exists(basepath('disk')):324 if not os.path.exists(basepath('disk')):
323 yield images.fetch(inst.image_id, basepath('disk-raw'), user, project)325 yield images.fetch(inst.image_id, basepath('disk-raw'), user, project)
324 if not os.path.exists(basepath('kernel')):326
325 yield images.fetch(inst.kernel_id, basepath('kernel'), user, project)327 using_kernel = inst.kernel_id and True
326 if not os.path.exists(basepath('ramdisk')):328 if using_kernel:
327 yield images.fetch(inst.ramdisk_id, basepath('ramdisk'), user, project)329 if not os.path.exists(basepath('kernel')):
330 yield images.fetch(inst.kernel_id, basepath('kernel'), user, project)
331 if not os.path.exists(basepath('ramdisk')):
332 yield images.fetch(inst.ramdisk_id, basepath('ramdisk'), user, project)
328333
329 execute = lambda cmd, process_input=None: \334 execute = lambda cmd, process_input=None: \
330 process.simple_execute(cmd=cmd,335 process.simple_execute(cmd=cmd,
331 process_input=process_input,336 process_input=process_input,
332 check_exit_code=True)337 check_exit_code=True)
333338
339 # For now, we assume that if we're not using a kernel, we're using a
340 # partitioned disk image where the target partition is the first
341 # partition
342 target_partition = None
343 if not using_kernel:
344 target_partition = "1"
345
334 key = str(inst['key_data'])346 key = str(inst['key_data'])
335 net = None347 net = None
336 network_ref = db.network_get_by_instance(None, inst['id'])348 network_ref = db.network_get_by_instance(None, inst['id'])
@@ -349,10 +361,19 @@
349 if net:361 if net:
350 logging.info('instance %s: injecting net into image %s',362 logging.info('instance %s: injecting net into image %s',
351 inst['name'], inst.image_id)363 inst['name'], inst.image_id)
352 yield disk.inject_data(basepath('disk-raw'), key, net, execute=execute)364 try:
365 yield disk.inject_data(basepath('disk-raw'), key, net,
366 partition=target_partition,
367 execute=execute)
368 except Exception as e:
369 # This could be a windows image, or a vmdk format disk
370 logging.warn('instance %s: ignoring error injecting data'
371 ' into image %s (%s)',
372 inst['name'], inst.image_id, e)
353373
354 if os.path.exists(basepath('disk')):374 if using_kernel:
355 yield process.simple_execute('rm -f %s' % basepath('disk'))375 if os.path.exists(basepath('disk')):
376 yield process.simple_execute('rm -f %s' % basepath('disk'))
356377
357 bytes = (instance_types.INSTANCE_TYPES[inst.instance_type]['local_gb']378 bytes = (instance_types.INSTANCE_TYPES[inst.instance_type]['local_gb']
358 * 1024 * 1024 * 1024)379 * 1024 * 1024 * 1024)
@@ -383,10 +404,22 @@
383 'mac_address': instance['mac_address'],404 'mac_address': instance['mac_address'],
384 'ip_address': ip_address,405 'ip_address': ip_address,
385 'dhcp_server': dhcp_server }406 'dhcp_server': dhcp_server }
386 libvirt_xml = self.libvirt_xml % xml_info407
408 if xml_info['kernel_id']:
409 xml_info['kernel'] = xml_info['basepath'] + "/kernel"
410
411 if xml_info['ramdisk_id']:
412 xml_info['ramdisk'] = xml_info['basepath'] + "/ramdisk"
413
414 if xml_info['ramdisk_id'] or xml_info['kernel_id']:
415 xml_info['disk'] = xml_info['basepath'] + "/disk"
416 else:
417 xml_info['disk'] = xml_info['basepath'] + "/disk-raw"
418
419 xml = str(Template(self.libvirt_xml, searchList=[ xml_info ] ))
387 logging.debug('instance %s: finished toXML method', instance['name'])420 logging.debug('instance %s: finished toXML method', instance['name'])
388421
389 return libvirt_xml422 return xml
390423
391 def get_info(self, instance_name):424 def get_info(self, instance_name):
392 virt_dom = self._conn.lookupByName(instance_name)425 virt_dom = self._conn.lookupByName(instance_name)
393426
=== modified file 'tools/pip-requires'
--- tools/pip-requires 2010-10-01 18:02:51 +0000
+++ tools/pip-requires 2010-10-14 20:50:58 +0000
@@ -2,6 +2,7 @@
2pep8==0.5.02pep8==0.5.0
3pylint==0.193pylint==0.19
4IPy==0.704IPy==0.70
5Cheetah==2.4.2.1
5M2Crypto==0.20.26M2Crypto==0.20.2
6amqplib==0.6.17amqplib==0.6.1
7anyjson==0.2.48anyjson==0.2.4