Add watchdog device support to libvirt driver

This commit adds support for watchdog devices
to the libvirt driver.  The watchdog device
used is 'i6300esb', and the action is based
or the 'hw_watchdog_action' property of the image.

Implements: blueprint libvirt-watchdog
DocImpact

Change-Id: Icf1f51d7929e40d0caeae569bd2b6eee8be9689e
This commit is contained in:
Solly Ross 2014-01-15 16:31:03 -05:00
parent 8bbad1c1de
commit 33850f95d0
6 changed files with 121 additions and 0 deletions

View File

@ -1516,3 +1516,7 @@ class RngDeviceNotExist(Invalid):
class RequestedVRamTooHigh(NovaException):
msg_fmt = _("The requested amount of video memory %(req_vram)d is higher"
"than the maximum allowed by flavor %(max_vram)d.")
class InvalidWatchdogAction(Invalid):
msg_fmt = _("Provided watchdog action (%(action)s) is not supported.")

View File

@ -1245,6 +1245,52 @@ class LibvirtConnTestCase(test.TestCase):
self.assertEqual(cfg.devices[6].type, "vnc")
self.assertEqual(cfg.devices[7].type, "spice")
def test_invalid_watchdog_action(self):
self.flags(virt_type='kvm', group='libvirt')
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
instance_ref = db.instance_create(self.context, self.test_instance)
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
instance_ref)
image_meta = {"properties": {"hw_watchdog_action": "something"}}
self.assertRaises(exception.InvalidWatchdogAction,
conn.get_guest_config,
instance_ref,
[],
image_meta,
disk_info)
def test_get_guest_config_with_watchdog_action_through_image_meta(self):
self.flags(virt_type='kvm', group='libvirt')
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
instance_ref = db.instance_create(self.context, self.test_instance)
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
instance_ref)
image_meta = {"properties": {"hw_watchdog_action": "none"}}
cfg = conn.get_guest_config(instance_ref, [], image_meta, disk_info)
self.assertEqual(len(cfg.devices), 8)
self.assertIsInstance(cfg.devices[0],
vconfig.LibvirtConfigGuestDisk)
self.assertIsInstance(cfg.devices[1],
vconfig.LibvirtConfigGuestDisk)
self.assertIsInstance(cfg.devices[2],
vconfig.LibvirtConfigGuestSerial)
self.assertIsInstance(cfg.devices[3],
vconfig.LibvirtConfigGuestSerial)
self.assertIsInstance(cfg.devices[4],
vconfig.LibvirtConfigGuestInput)
self.assertIsInstance(cfg.devices[5],
vconfig.LibvirtConfigGuestGraphics)
self.assertIsInstance(cfg.devices[6],
vconfig.LibvirtConfigGuestVideo)
self.assertIsInstance(cfg.devices[7],
vconfig.LibvirtConfigGuestWatchdog)
self.assertEqual("none", cfg.devices[7].action)
def test_unsupported_video_driver_through_image_meta(self):
self.flags(virt_type='kvm', group='libvirt')

View File

@ -1644,3 +1644,18 @@ class LibvirtConfigGuestControllerTest(LibvirtConfigBaseTest):
xml = obj.to_xml()
self.assertXmlEqual(xml, """
<controller type='scsi' index='0' model='virtio-scsi'/>""")
class LibvirtConfigGuestWatchdogTest(LibvirtConfigBaseTest):
def test_config_watchdog(self):
obj = config.LibvirtConfigGuestWatchdog()
obj.action = 'none'
xml = obj.to_xml()
self.assertXmlEqual(xml, "<watchdog model='i6300esb' action='none'/>")
def test_config_watchdog_default_action(self):
obj = config.LibvirtConfigGuestWatchdog()
xml = obj.to_xml()
self.assertXmlEqual(xml, "<watchdog model='i6300esb' action='reset'/>")

View File

@ -1103,6 +1103,23 @@ class LibvirtConfigGuestChannel(LibvirtConfigGuestCharBase):
return dev
class LibvirtConfigGuestWatchdog(LibvirtConfigGuestDevice):
def __init__(self, **kwargs):
super(LibvirtConfigGuestWatchdog, self).__init__(root_name="watchdog",
**kwargs)
self.model = 'i6300esb'
self.action = 'reset'
def format_dom(self):
dev = super(LibvirtConfigGuestWatchdog, self).format_dom()
dev.set('model', self.model)
dev.set('action', self.action)
return dev
class LibvirtConfigGuest(LibvirtConfigObject):
def __init__(self, **kwargs):

View File

@ -102,6 +102,7 @@ from nova.virt.libvirt import imagebackend
from nova.virt.libvirt import imagecache
from nova.virt.libvirt import utils as libvirt_utils
from nova.virt import netutils
from nova.virt import watchdog_actions
from nova import volume
from nova.volume import encryptors
@ -3348,6 +3349,20 @@ class LibvirtDriver(driver.ComputeDriver):
raise exception.PciDeviceUnsupportedHypervisor(
type=CONF.libvirt.virt_type)
watchdog_action = 'disabled'
if (image_meta is not None and
image_meta.get('properties', {}).get('hw_watchdog_action')):
watchdog_action = image_meta['properties']['hw_watchdog_action']
# NB(sross): currently only actually supported by KVM/QEmu
if watchdog_action != 'disabled':
if watchdog_actions.is_valid_watchdog_action(watchdog_action):
bark = vconfig.LibvirtConfigGuestWatchdog()
bark.action = watchdog_action
guest.add_device(bark)
else:
raise exception.InvalidWatchdogAction(action=watchdog_action)
return guest
def to_xml(self, context, instance, network_info, disk_info,

View File

@ -0,0 +1,24 @@
# Copyright 2014 Red Hat, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Describes and verifies the watchdog device actions."""
# the values which may be passed to libvirt
RAW_WATCHDOG_ACTIONS = ['poweroff', 'reset', 'pause', 'none']
def is_valid_watchdog_action(val):
"""Check if the given value is a valid watchdog device parameter."""
return val in RAW_WATCHDOG_ACTIONS