Merge lp:~vishvananda/nova/lp829020 into lp:~hudson-openstack/nova/trunk

Proposed by Vish Ishaya
Status: Merged
Approved by: Dan Prince
Approved revision: 1545
Merged at revision: 1581
Proposed branch: lp:~vishvananda/nova/lp829020
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 132 lines (+40/-37)
1 file modified
nova/virt/libvirt/connection.py (+40/-37)
To merge this branch: bzr merge lp:~vishvananda/nova/lp829020
Reviewer Review Type Date Requested Status
Dan Prince (community) Approve
Devin Carlen (community) Approve
Review via email: mp+75433@code.launchpad.net

Description of the change

Fixes libvirt rescue to use the same strategy as xen. Use a new copy of the base image as the rescue image. It leaves the original rescue image flags in, so a hand picked rescue image can still be used if desired.

To post a comment you must log in.
Revision history for this message
Devin Carlen (devcamcar) wrote :

You've got a merge conflict that needs to be resolved.

review: Needs Fixing
lp:~vishvananda/nova/lp829020 updated
1543. By Vish Ishaya

write out xml for rescue

1544. By Vish Ishaya

merge trunk

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

devin: fixed

Revision history for this message
Devin Carlen (devcamcar) wrote :

lgtm

review: Approve
Revision history for this message
Dan Prince (dan-prince) wrote :

Hey Vish,

I'm getting some permissions issues when trying to go into rescue mode using libvirt:

2011-09-16 14:58:03,439 INFO nova.virt.libvirt_conn [-] instance instance-00000001: Creating image
2011-09-16 14:58:03,440 ERROR nova.exception [-] Uncaught exception
(nova.exception): TRACE: Traceback (most recent call last):
(nova.exception): TRACE: File "/usr/lib/pymodules/python2.6/nova/exception.py", line 98, in wrapped
(nova.exception): TRACE: return f(*args, **kw)
(nova.exception): TRACE: File "/usr/lib/pymodules/python2.6/nova/virt/libvirt/connection.py", line 564, in rescue
(nova.exception): TRACE: network_info=network_info)
(nova.exception): TRACE: File "/usr/lib/pymodules/python2.6/nova/virt/libvirt/connection.py", line 818, in _create_image
(nova.exception): TRACE: os.O_CREAT | os.O_WRONLY, 0660))
(nova.exception): TRACE: OSError: [Errno 13] Permission denied: '/var/lib/nova/instances/instance-00000001/console.log'

review: Needs Fixing
lp:~vishvananda/nova/lp829020 updated
1545. By Vish Ishaya

fix permissions

Revision history for this message
Dan Prince (dan-prince) wrote :

This looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'nova/virt/libvirt/connection.py'
--- nova/virt/libvirt/connection.py 2011-09-16 01:57:03 +0000
+++ nova/virt/libvirt/connection.py 2011-09-16 15:52:14 +0000
@@ -29,9 +29,9 @@
29 (default: kvm).29 (default: kvm).
30:libvirt_uri: Override for the default libvirt URI (depends on libvirt_type).30:libvirt_uri: Override for the default libvirt URI (depends on libvirt_type).
31:libvirt_xml_template: Libvirt XML Template.31:libvirt_xml_template: Libvirt XML Template.
32:rescue_image_id: Rescue ami image (default: ami-rescue).32:rescue_image_id: Rescue ami image (None = original image).
33:rescue_kernel_id: Rescue aki image (default: aki-rescue).33:rescue_kernel_id: Rescue aki image (None = original image).
34:rescue_ramdisk_id: Rescue ari image (default: ari-rescue).34:rescue_ramdisk_id: Rescue ari image (None = original image).
35:injected_network_template: Template file for injected network35:injected_network_template: Template file for injected network
36:allow_same_net_traffic: Whether to allow in project network traffic36:allow_same_net_traffic: Whether to allow in project network traffic
3737
@@ -84,9 +84,9 @@
84FLAGS = flags.FLAGS84FLAGS = flags.FLAGS
85flags.DECLARE('live_migration_retry_count', 'nova.compute.manager')85flags.DECLARE('live_migration_retry_count', 'nova.compute.manager')
86# TODO(vish): These flags should probably go into a shared location86# TODO(vish): These flags should probably go into a shared location
87flags.DEFINE_string('rescue_image_id', 'ami-rescue', 'Rescue ami image')87flags.DEFINE_string('rescue_image_id', None, 'Rescue ami image')
88flags.DEFINE_string('rescue_kernel_id', 'aki-rescue', 'Rescue aki image')88flags.DEFINE_string('rescue_kernel_id', None, 'Rescue aki image')
89flags.DEFINE_string('rescue_ramdisk_id', 'ari-rescue', 'Rescue ari image')89flags.DEFINE_string('rescue_ramdisk_id', None, 'Rescue ari image')
90flags.DEFINE_string('libvirt_xml_template',90flags.DEFINE_string('libvirt_xml_template',
91 utils.abspath('virt/libvirt.xml.template'),91 utils.abspath('virt/libvirt.xml.template'),
92 'Libvirt XML Template')92 'Libvirt XML Template')
@@ -468,7 +468,7 @@
468 snapshot_ptr.delete(0)468 snapshot_ptr.delete(0)
469469
470 @exception.wrap_exception()470 @exception.wrap_exception()
471 def reboot(self, instance, network_info, reboot_type):471 def reboot(self, instance, network_info, reboot_type=None, xml=None):
472 """Reboot a virtual machine, given an instance reference.472 """Reboot a virtual machine, given an instance reference.
473473
474 This method actually destroys and re-creates the domain to ensure the474 This method actually destroys and re-creates the domain to ensure the
@@ -479,7 +479,9 @@
479 # NOTE(itoumsn): Use XML delived from the running instance479 # NOTE(itoumsn): Use XML delived from the running instance
480 # instead of using to_xml(instance, network_info). This is almost480 # instead of using to_xml(instance, network_info). This is almost
481 # the ultimate stupid workaround.481 # the ultimate stupid workaround.
482 xml = virt_dom.XMLDesc(0)482 if not xml:
483 xml = virt_dom.XMLDesc(0)
484
483 # NOTE(itoumsn): self.shutdown() and wait instead of self.destroy() is485 # NOTE(itoumsn): self.shutdown() and wait instead of self.destroy() is
484 # better because we cannot ensure flushing dirty buffers486 # better because we cannot ensure flushing dirty buffers
485 # in the guest OS. But, in case of KVM, shutdown() does not work...487 # in the guest OS. But, in case of KVM, shutdown() does not work...
@@ -543,43 +545,42 @@
543 data recovery.545 data recovery.
544546
545 """547 """
546 self.destroy(instance, network_info, cleanup=False)548
549 virt_dom = self._conn.lookupByName(instance['name'])
550 unrescue_xml = virt_dom.XMLDesc(0)
551 unrescue_xml_path = os.path.join(FLAGS.instances_path,
552 instance['name'],
553 'unrescue.xml')
554 f = open(unrescue_xml_path, 'w')
555 f.write(unrescue_xml)
556 f.close()
547557
548 xml = self.to_xml(instance, network_info, rescue=True)558 xml = self.to_xml(instance, network_info, rescue=True)
549 rescue_images = {'image_id': FLAGS.rescue_image_id,559 rescue_images = {
550 'kernel_id': FLAGS.rescue_kernel_id,560 'image_id': FLAGS.rescue_image_id or instance['image_ref'],
551 'ramdisk_id': FLAGS.rescue_ramdisk_id}561 'kernel_id': FLAGS.rescue_kernel_id or instance['kernel_id'],
552 self._create_image(context, instance, xml, '.rescue', rescue_images)562 'ramdisk_id': FLAGS.rescue_ramdisk_id or instance['ramdisk_id'],
553 self._create_new_domain(xml)563 }
554564 self._create_image(context, instance, xml, '.rescue', rescue_images,
555 def _wait_for_rescue():565 network_info=network_info)
556 """Called at an interval until the VM is running again."""566 self.reboot(instance, network_info, xml=xml)
557 instance_name = instance['name']
558
559 try:
560 state = self.get_info(instance_name)['state']
561 except exception.NotFound:
562 msg = _("During reboot, %s disappeared.") % instance_name
563 LOG.error(msg)
564 raise utils.LoopingCallDone
565
566 if state == power_state.RUNNING:
567 msg = _("Instance %s rescued successfully.") % instance_name
568 LOG.info(msg)
569 raise utils.LoopingCallDone
570
571 timer = utils.LoopingCall(_wait_for_rescue)
572 return timer.start(interval=0.5, now=True)
573567
574 @exception.wrap_exception()568 @exception.wrap_exception()
575 def unrescue(self, instance, network_info):569 def unrescue(self, instance, callback, network_info):
576 """Reboot the VM which is being rescued back into primary images.570 """Reboot the VM which is being rescued back into primary images.
577571
578 Because reboot destroys and re-creates instances, unresue should572 Because reboot destroys and re-creates instances, unresue should
579 simply call reboot.573 simply call reboot.
580574
581 """575 """
582 self.reboot(instance, network_info)576 unrescue_xml_path = os.path.join(FLAGS.instances_path,
577 instance['name'],
578 'unrescue.xml')
579 f = open(unrescue_xml_path)
580 unrescue_xml = f.read()
581 f.close()
582 os.remove(unrescue_xml_path)
583 self.reboot(instance, network_info, xml=unrescue_xml)
583584
584 @exception.wrap_exception()585 @exception.wrap_exception()
585 def poll_rescued_instances(self, timeout):586 def poll_rescued_instances(self, timeout):
@@ -814,8 +815,10 @@
814 utils.execute('mkdir', '-p', container_dir)815 utils.execute('mkdir', '-p', container_dir)
815816
816 # NOTE(vish): No need add the suffix to console.log817 # NOTE(vish): No need add the suffix to console.log
817 os.close(os.open(basepath('console.log', ''),818 console_log = basepath('console.log', '')
818 os.O_CREAT | os.O_WRONLY, 0660))819 if os.path.exists(console_log):
820 utils.execute('chown', os.getuid(), console_log, run_as_root=True)
821 os.close(os.open(console_log, os.O_CREAT | os.O_WRONLY, 0660))
819822
820 if not disk_images:823 if not disk_images:
821 disk_images = {'image_id': inst['image_ref'],824 disk_images = {'image_id': inst['image_ref'],