New Baremetal provisioning framework.

This is a minimal patch for the new baremetal driver.

With this driver, nova compute registers multiple entries of baremetal
nodes. It periodically updates the capabilities of the multiple
baremetal nodes and reports it as a list of capabilities.

It does not include Tilera or PXE back-ends, which will be provided
by subsequent patches. It also does not include VIF or volume components.

Part 4 of 7: blueprint general-bare-metal-provisioning-framework.

Change-Id: I55617a8da52d20d4df727b8bbde8e5f72d3bf130
Co-authored-by: Mikyung Kang <mkkang@isi.edu>
Co-authored-by: David Kang <dkang@isi.edu>
Co-authored-by: Ken Igarashi <igarashik@nttdocomo.co.jp>
Co-authored-by: Arata Notsu <notsu@virtualtech.jp>
Co-authored-by: Chris Krelle <NobodyCam@gmail.com>
Co-authored-by: Devananda van der Veen <devananda.vdv@gmail.com>
This commit is contained in:
Mikyung Kang 2012-12-13 02:56:56 +09:00
parent 63f55af401
commit aaeb899f98
14 changed files with 794 additions and 67 deletions

View File

@ -12,4 +12,4 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from nova.tests import *
from nova.tests.baremetal import *

View File

@ -12,3 +12,4 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from nova.tests.baremetal.db import *

View File

@ -35,20 +35,3 @@ class BareMetalInterfaceTestCase(base.BMDBTestCase):
pif2_id = db.bm_interface_create(self.context, 2, '11:11:11:11:11:11',
'0x2', 2)
self.assertTrue(pif2_id is not None)
def test_unique_vif_uuid(self):
pif1_id = db.bm_interface_create(self.context, 1, '11:11:11:11:11:11',
'0x1', 1)
pif2_id = db.bm_interface_create(self.context, 2, '22:22:22:22:22:22',
'0x2', 2)
db.bm_interface_set_vif_uuid(self.context, pif1_id, 'AAAA')
self.assertRaises(exception.NovaException,
db.bm_interface_set_vif_uuid,
self.context, pif2_id, 'AAAA')
def test_vif_not_found(self):
pif_id = db.bm_interface_create(self.context, 1, '11:11:11:11:11:11',
'0x1', 1)
self.assertRaises(exception.NovaException,
db.bm_interface_set_vif_uuid,
self.context, pif_id + 1, 'AAAA')

View File

@ -60,7 +60,6 @@ def new_bm_interface(**kwargs):
x.address = kwargs.pop('address', None)
x.datapath_id = kwargs.pop('datapath_id', None)
x.port_no = kwargs.pop('port_no', None)
x.vif_uuid = kwargs.pop('vif_uuid', None)
if len(kwargs) > 0:
raise test.TestingException("unknown field: %s"
% ','.join(kwargs.keys()))

View File

@ -0,0 +1,173 @@
# Copyright (c) 2012 NTT DOCOMO, INC.
# Copyright (c) 2011 University of Southern California / ISI
# All Rights Reserved.
#
# 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.
"""
Tests for baremetal driver.
"""
import mox
from nova import exception
from nova.openstack.common import cfg
from nova import test
from nova.tests.baremetal.db import base
from nova.tests.baremetal.db import utils
from nova.tests.image import fake as fake_image
from nova.tests import test_virt_drivers
from nova.tests import utils as test_utils
from nova.virt.baremetal import baremetal_states
from nova.virt.baremetal import db
from nova.virt.baremetal import driver as bm_driver
from nova.virt.firewall import NoopFirewallDriver
CONF = cfg.CONF
FakeFirewallDriver = NoopFirewallDriver
NODE = utils.new_bm_node(cpus=2, memory_mb=4096, service_host="host1")
NICS = [
{'address': '01:23:45:67:89:01', 'datapath_id': '0x1', 'port_no': 1, },
{'address': '01:23:45:67:89:02', 'datapath_id': '0x2', 'port_no': 2, },
]
def class_path(class_):
return class_.__module__ + '.' + class_.__name__
COMMON_FLAGS = dict(
baremetal_sql_connection='sqlite:///:memory:',
baremetal_driver='nova.virt.baremetal.fake.Fake',
power_manager='nova.virt.baremetal.fake.FakePowerManager',
firewall_driver=class_path(FakeFirewallDriver),
instance_type_extra_specs=['cpu_arch:test'],
host=NODE['service_host'],
)
def _create_baremetal_stuff():
context = test_utils.get_test_admin_context()
node = db.bm_node_create(context, NODE)
for nic in NICS:
db.bm_interface_create(context,
node['id'],
nic['address'],
nic['datapath_id'],
nic['port_no'])
return node
class BaremetalDriverSpawnTestCase(base.Database):
def setUp(self):
super(BaremetalDriverSpawnTestCase, self).setUp()
self.flags(**COMMON_FLAGS)
fake_image.stub_out_image_service(self.stubs)
self.node = _create_baremetal_stuff()
self.node_id = self.node['id']
self.context = test_utils.get_test_admin_context()
self.instance = test_utils.get_test_instance()
self.network_info = test_utils.get_test_network_info()
self.block_device_info = None
self.image_meta = test_utils.get_test_image_info(None, self.instance)
self.driver = bm_driver.BareMetalDriver(None)
self.kwargs = dict(
context=self.context,
instance=self.instance,
image_meta=self.image_meta,
injected_files=[('/foo', 'bar'), ('/abc', 'xyz')],
admin_password='testpass',
network_info=self.network_info,
block_device_info=self.block_device_info)
self.addCleanup(fake_image.FakeImageService_reset)
def test_ok(self):
self.instance['node'] = str(self.node_id)
self.driver.spawn(**self.kwargs)
node = db.bm_node_get(self.context, self.node_id)
self.assertEqual(node['instance_uuid'], self.instance['uuid'])
self.assertEqual(node['task_state'], baremetal_states.ACTIVE)
def test_without_node(self):
self.assertRaises(
exception.NovaException,
self.driver.spawn,
**self.kwargs)
def test_node_not_found(self):
self.instance['node'] = "123456789"
self.assertRaises(
exception.InstanceNotFound,
self.driver.spawn,
**self.kwargs)
def test_node_in_use(self):
self.instance['node'] = str(self.node_id)
db.bm_node_update(self.context, self.node_id,
{'instance_uuid': 'something'})
self.assertRaises(
exception.NovaException,
self.driver.spawn,
**self.kwargs)
class BaremetalDriverTestCase(test_virt_drivers._VirtDriverTestCase,
base.Database):
def setUp(self):
super(BaremetalDriverTestCase, self).setUp()
self.driver_module = 'nova.virt.baremetal.BareMetalDriver'
self.flags(**COMMON_FLAGS)
self.node = _create_baremetal_stuff()
self.node_id = self.node['id']
fake_image.stub_out_image_service(self.stubs)
self.addCleanup(fake_image.FakeImageService_reset)
def _get_running_instance(self):
instance_ref = test_utils.get_test_instance()
instance_ref['node'] = str(self.node_id)
network_info = test_utils.get_test_network_info()
image_info = test_utils.get_test_image_info(None, instance_ref)
self.connection.spawn(self.ctxt, instance_ref, image_info,
[], 'herp', network_info=network_info)
return instance_ref, network_info
def test_loading_baremetal_drivers(self):
from nova.virt.baremetal import fake
drv = bm_driver.BareMetalDriver(None)
self.assertTrue(isinstance(drv.baremetal_nodes, fake.Fake))
self.assertTrue(isinstance(drv._firewall_driver, FakeFirewallDriver))
def test_get_host_stats(self):
self.flags(instance_type_extra_specs=['cpu_arch:x86_64',
'x:123',
'y:456', ])
drv = bm_driver.BareMetalDriver(None)
cap_list = drv.get_host_stats()
self.assertTrue(isinstance(cap_list, list))
self.assertEqual(len(cap_list), 1)
cap = cap_list[0]
self.assertEqual(cap['cpu_arch'], 'x86_64')
self.assertEqual(cap['x'], '123')
self.assertEqual(cap['y'], '456')
self.assertEqual(cap['hypervisor_type'], 'baremetal')
self.assertEqual(cap['baremetal_driver'],
'nova.virt.baremetal.fake.Fake')

View File

@ -12,3 +12,4 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from nova.virt.baremetal.driver import BareMetalDriver

View File

@ -0,0 +1,32 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2012 NTT DOCOMO, INC.
# Copyright 2010 OpenStack LLC.
# All Rights Reserved.
#
# 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.
"""
Possible baremetal node states for instances.
Compute instance baremetal states represent the state of an instance as it
pertains to a user or administrator. When combined with task states
(task_states.py), a better picture can be formed regarding the instance's
health.
"""
ACTIVE = 'active'
BUILDING = 'building'
DELETED = 'deleted'
ERROR = 'error'

View File

@ -0,0 +1,75 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2012 NTT DOCOMO, INC.
# Copyright (c) 2011 University of Southern California / ISI
# All Rights Reserved.
#
# 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.
from nova.virt.baremetal import baremetal_states
class NodeDriver(object):
def define_vars(self, instance, network_info, block_device_info):
raise NotImplementedError()
def create_image(self, var, context, image_meta, node, instance,
injected_files=None, admin_password=None):
raise NotImplementedError()
def destroy_images(self, var, context, node, instance):
raise NotImplementedError()
def activate_bootloader(self, var, context, node, instance, image_meta):
raise NotImplementedError()
def deactivate_bootloader(self, var, context, node, instance):
raise NotImplementedError()
def activate_node(self, var, context, node, instance):
"""For operations after power on."""
raise NotImplementedError()
def deactivate_node(self, var, context, node, instance):
"""For operations before power off."""
raise NotImplementedError()
def get_console_output(self, node, instance):
raise NotImplementedError()
class PowerManager(object):
def __init__(self, node):
pass
def activate_node(self):
return baremetal_states.ACTIVE
def reboot_node(self):
return baremetal_states.ACTIVE
def deactivate_node(self):
return baremetal_states.DELETED
def is_power_on(self):
"""Returns True or False according as the node's power state"""
return True
# TODO(NTTdocomo): split out console methods to its own class
def start_console(self):
pass
def stop_console(self):
pass

View File

@ -148,14 +148,6 @@ def bm_interface_create(context, bm_node_id, address, datapath_id, port_no):
datapath_id, port_no)
def bm_interface_set_vif_uuid(context, if_id, vif_uuid):
return IMPL.bm_interface_set_vif_uuid(context, if_id, vif_uuid)
def bm_interface_get_by_vif_uuid(context, vif_uuid):
return IMPL.bm_interface_get_by_vif_uuid(context, vif_uuid)
def bm_interface_get_all_by_bm_node_id(context, bm_node_id):
return IMPL.bm_interface_get_all_by_bm_node_id(context, bm_node_id)

View File

@ -310,46 +310,6 @@ def bm_interface_create(context, bm_node_id, address, datapath_id, port_no):
return ref.id
@require_admin_context
def bm_interface_set_vif_uuid(context, if_id, vif_uuid):
session = get_session()
with session.begin():
bm_interface = model_query(context, models.BareMetalInterface,
read_deleted="no", session=session).\
filter_by(id=if_id).\
with_lockmode('update').\
first()
if not bm_interface:
raise exception.NovaException(_("Baremetal interface %s "
"not found") % if_id)
bm_interface.vif_uuid = vif_uuid
try:
session.add(bm_interface)
session.flush()
except exception.DBError, e:
# TODO(deva): clean up when db layer raises DuplicateKeyError
if str(e).find('IntegrityError') != -1:
raise exception.NovaException(_("Baremetal interface %s "
"already in use") % vif_uuid)
else:
raise e
@require_admin_context
def bm_interface_get_by_vif_uuid(context, vif_uuid):
result = model_query(context, models.BareMetalInterface,
read_deleted="no").\
filter_by(vif_uuid=vif_uuid).\
first()
if not result:
raise exception.NovaException(_("Baremetal virtual interface %s "
"not found") % vif_uuid)
return result
@require_admin_context
def bm_interface_get_all_by_bm_node_id(context, bm_node_id):
result = model_query(context, models.BareMetalInterface,

View File

@ -0,0 +1,368 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# coding=utf-8
#
# Copyright (c) 2012 NTT DOCOMO, INC
# Copyright (c) 2011 University of Southern California / ISI
# All Rights Reserved.
#
# 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.
"""
A driver for Bare-metal platform.
"""
from nova.compute import power_state
from nova import context as nova_context
from nova import exception
from nova.openstack.common import cfg
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
from nova.virt.baremetal import baremetal_states
from nova.virt.baremetal import db as bmdb
from nova.virt import driver
from nova.virt import firewall
from nova.virt.libvirt import imagecache
opts = [
cfg.BoolOpt('baremetal_inject_password',
default=True,
help='Whether baremetal compute injects password or not'),
cfg.StrOpt('baremetal_injected_network_template',
default='$pybasedir/nova/virt/baremetal/interfaces.template',
help='Template file for injected network'),
cfg.ListOpt('instance_type_extra_specs',
default=[],
help='a list of additional capabilities corresponding to '
'instance_type_extra_specs for this compute '
'host to advertise. Valid entries are name=value, pairs '
'For example, "key1:val1, key2:val2"'),
cfg.StrOpt('baremetal_driver',
default='nova.virt.baremetal.pxe.PXE',
help='Baremetal driver back-end (pxe or tilera)'),
cfg.StrOpt('power_manager',
default='nova.virt.baremetal.ipmi.Ipmi',
help='Baremetal power management method'),
cfg.StrOpt('baremetal_tftp_root',
default='/tftpboot',
help='Baremetal compute node\'s tftp root path'),
]
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
CONF.register_opts(opts)
DEFAULT_FIREWALL_DRIVER = "%s.%s" % (
firewall.__name__,
firewall.NoopFirewallDriver.__name__)
def _get_baremetal_nodes(context):
nodes = bmdb.bm_node_get_all(context, service_host=CONF.host)
return nodes
def _get_baremetal_node_by_instance_uuid(instance_uuid):
ctx = nova_context.get_admin_context()
node = bmdb.bm_node_get_by_instance_uuid(ctx, instance_uuid)
if node['service_host'] != CONF.host:
LOG.error(_("Request for baremetal node %s "
"sent to wrong service host") % instance_uuid)
raise exception.InstanceNotFound(instance_id=instance_uuid)
return node
def _update_baremetal_state(context, node, instance, state):
instance_uuid = None
if instance:
instance_uuid = instance['uuid']
bmdb.bm_node_update(context, node['id'],
{'instance_uuid': instance_uuid,
'task_state': state,
})
def get_power_manager(node, **kwargs):
cls = importutils.import_class(CONF.power_manager)
return cls(node, **kwargs)
class BareMetalDriver(driver.ComputeDriver):
"""BareMetal hypervisor driver."""
capabilities = {
"has_imagecache": True,
}
def __init__(self, virtapi, read_only=False):
super(BareMetalDriver, self).__init__(virtapi)
self.baremetal_nodes = importutils.import_object(
CONF.baremetal_driver)
self._firewall_driver = firewall.load_driver(
default=DEFAULT_FIREWALL_DRIVER)
self._image_cache_manager = imagecache.ImageCacheManager()
extra_specs = {}
extra_specs["baremetal_driver"] = CONF.baremetal_driver
for pair in CONF.instance_type_extra_specs:
keyval = pair.split(':', 1)
keyval[0] = keyval[0].strip()
keyval[1] = keyval[1].strip()
extra_specs[keyval[0]] = keyval[1]
if not 'cpu_arch' in extra_specs:
LOG.warning(
_('cpu_arch is not found in instance_type_extra_specs'))
extra_specs['cpu_arch'] = ''
self._extra_specs = extra_specs
self._supported_instances = [
(extra_specs['cpu_arch'], 'baremetal', 'baremetal'),
]
@classmethod
def instance(cls):
if not hasattr(cls, '_instance'):
cls._instance = cls()
return cls._instance
def init_host(self, host):
return
def get_hypervisor_type(self):
return 'baremetal'
def get_hypervisor_version(self):
# TODO(deva): define the version properly elsewhere
return 1
def list_instances(self):
l = []
ctx = nova_context.get_admin_context()
for node in _get_baremetal_nodes(ctx):
if node['instance_uuid']:
inst = self.virtapi.instance_get_by_uuid(ctx,
node['instance_uuid'])
if inst:
l.append(inst['name'])
return l
def spawn(self, context, instance, image_meta, injected_files,
admin_password, network_info=None, block_device_info=None):
nodename = instance.get('node')
if not nodename:
raise exception.NovaException(_("Baremetal node id not supplied"
" to driver"))
node = bmdb.bm_node_get(context, nodename)
if node['instance_uuid']:
raise exception.NovaException(_("Baremetal node %s already"
" in use") % nodename)
# TODO(deva): split this huge try: block into manageable parts
try:
_update_baremetal_state(context, node, instance,
baremetal_states.BUILDING)
var = self.baremetal_nodes.define_vars(instance, network_info,
block_device_info)
self._firewall_driver.setup_basic_filtering(instance, network_info)
self._firewall_driver.prepare_instance_filter(instance,
network_info)
self.baremetal_nodes.create_image(var, context, image_meta, node,
instance,
injected_files=injected_files,
admin_password=admin_password)
self.baremetal_nodes.activate_bootloader(var, context, node,
instance, image_meta)
pm = get_power_manager(node)
state = pm.activate_node()
_update_baremetal_state(context, node, instance, state)
self.baremetal_nodes.activate_node(var, context, node, instance)
self._firewall_driver.apply_instance_filter(instance, network_info)
pm.start_console()
except Exception, e:
# TODO(deva): add tooling that can revert a failed spawn
_update_baremetal_state(context, node, instance,
baremetal_states.ERROR)
raise e
def reboot(self, instance, network_info, reboot_type,
block_device_info=None):
node = _get_baremetal_node_by_instance_uuid(instance['uuid'])
ctx = nova_context.get_admin_context()
pm = get_power_manager(node)
state = pm.reboot_node()
_update_baremetal_state(ctx, node, instance, state)
def destroy(self, instance, network_info, block_device_info=None):
ctx = nova_context.get_admin_context()
try:
node = _get_baremetal_node_by_instance_uuid(instance['uuid'])
except exception.InstanceNotFound:
# TODO(deva): refactor so that dangling files can be cleaned
# up even after a failed boot or delete
LOG.warning(_("Delete called on non-existing instance %s")
% instance['uuid'])
return
var = self.baremetal_nodes.define_vars(instance, network_info,
block_device_info)
self.baremetal_nodes.deactivate_node(var, ctx, node, instance)
pm = get_power_manager(node)
pm.stop_console()
## power off the node
state = pm.deactivate_node()
self.baremetal_nodes.deactivate_bootloader(var, ctx, node, instance)
self.baremetal_nodes.destroy_images(var, ctx, node, instance)
# stop firewall
self._firewall_driver.unfilter_instance(instance,
network_info=network_info)
_update_baremetal_state(ctx, node, None, state)
def power_off(self, instance):
"""Power off the specified instance."""
node = _get_baremetal_node_by_instance_uuid(instance['uuid'])
pm = get_power_manager(node)
pm.deactivate_node()
def power_on(self, instance):
"""Power on the specified instance"""
node = _get_baremetal_node_by_instance_uuid(instance['uuid'])
pm = get_power_manager(node)
pm.activate_node()
def get_info(self, instance):
# NOTE(deva): compute/manager.py expects to get NotFound exception
# so we convert from InstanceNotFound
inst_uuid = instance.get('uuid')
node = _get_baremetal_node_by_instance_uuid(inst_uuid)
pm = get_power_manager(node)
ps = power_state.SHUTDOWN
if pm.is_power_on():
ps = power_state.RUNNING
return {'state': ps,
'max_mem': node['memory_mb'],
'mem': node['memory_mb'],
'num_cpu': node['cpus'],
'cpu_time': 0}
def refresh_security_group_rules(self, security_group_id):
self._firewall_driver.refresh_security_group_rules(security_group_id)
return True
def refresh_security_group_members(self, security_group_id):
self._firewall_driver.refresh_security_group_members(security_group_id)
return True
def refresh_provider_fw_rules(self):
self._firewall_driver.refresh_provider_fw_rules()
def _node_resource(self, node):
vcpus_used = 0
memory_mb_used = 0
local_gb_used = 0
vcpus = node['cpus']
memory_mb = node['memory_mb']
local_gb = node['local_gb']
if node['registration_status'] != 'done' or node['instance_uuid']:
vcpus_used = node['cpus']
memory_mb_used = node['memory_mb']
local_gb_used = node['local_gb']
dic = {'vcpus': vcpus,
'memory_mb': memory_mb,
'local_gb': local_gb,
'vcpus_used': vcpus_used,
'memory_mb_used': memory_mb_used,
'local_gb_used': local_gb_used,
'hypervisor_type': self.get_hypervisor_type(),
'hypervisor_version': self.get_hypervisor_version(),
'hypervisor_hostname': str(node['id']),
'cpu_info': 'baremetal cpu',
}
return dic
def refresh_instance_security_rules(self, instance):
self._firewall_driver.refresh_instance_security_rules(instance)
def get_available_resource(self, nodename):
context = nova_context.get_admin_context()
node = bmdb.bm_node_get(context, nodename)
dic = self._node_resource(node)
return dic
def ensure_filtering_rules_for_instance(self, instance_ref, network_info):
self._firewall_driver.setup_basic_filtering(instance_ref, network_info)
self._firewall_driver.prepare_instance_filter(instance_ref,
network_info)
def unfilter_instance(self, instance_ref, network_info):
self._firewall_driver.unfilter_instance(instance_ref,
network_info=network_info)
def get_host_stats(self, refresh=False):
caps = []
context = nova_context.get_admin_context()
nodes = bmdb.bm_node_get_all(context,
service_host=CONF.host)
for node in nodes:
res = self._node_resource(node)
nodename = str(node['id'])
data = {}
data['vcpus'] = res['vcpus']
data['vcpus_used'] = res['vcpus_used']
data['cpu_info'] = res['cpu_info']
data['disk_total'] = res['local_gb']
data['disk_used'] = res['local_gb_used']
data['disk_available'] = res['local_gb'] - res['local_gb_used']
data['host_memory_total'] = res['memory_mb']
data['host_memory_free'] = res['memory_mb'] - res['memory_mb_used']
data['hypervisor_type'] = res['hypervisor_type']
data['hypervisor_version'] = res['hypervisor_version']
data['hypervisor_hostname'] = nodename
data['supported_instances'] = self._supported_instances
data.update(self._extra_specs)
data['host'] = CONF.host
data['node'] = nodename
# TODO(NTTdocomo): put node's extra specs here
caps.append(data)
return caps
def manage_image_cache(self, context, all_instances):
"""Manage the local cache of images."""
self._image_cache_manager.verify_base_images(context, all_instances)
def get_console_output(self, instance):
node = _get_baremetal_node_by_instance_uuid(instance['uuid'])
return self.baremetal_nodes.get_console_output(node, instance)
def get_available_nodes(self):
context = nova_context.get_admin_context()
return [str(n['id']) for n in _get_baremetal_nodes(context)]

View File

@ -0,0 +1,75 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2012 NTT DOCOMO, INC.
# Copyright (c) 2011 University of Southern California / ISI
# All Rights Reserved.
#
# 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.
from nova.virt.baremetal import baremetal_states
from nova.virt.baremetal import base
def get_baremetal_nodes():
return Fake()
class Fake(base.NodeDriver):
def define_vars(self, instance, network_info, block_device_info):
return {}
def create_image(self, var, context, image_meta, node, instance,
injected_files=None, admin_password=None):
pass
def destroy_images(self, var, context, node, instance):
pass
def activate_bootloader(self, var, context, node, instance, image_meta):
pass
def deactivate_bootloader(self, var, context, node, instance):
pass
def activate_node(self, var, context, node, instance):
"""For operations after power on."""
pass
def deactivate_node(self, var, context, node, instance):
"""For operations before power off."""
pass
def get_console_output(self, node, instance):
return 'fake\nconsole\noutput for instance %s' % instance['id']
class FakePowerManager(base.PowerManager):
def activate_node(self):
return baremetal_states.ACTIVE
def reboot_node(self):
return baremetal_states.ACTIVE
def deactivate_node(self):
return baremetal_states.DELETED
def is_power_on(self):
return True
def start_console(self):
pass
def stop_console(self):
pass

View File

@ -0,0 +1,31 @@
# Injected by Nova on instance boot
#
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
auto lo
iface lo inet loopback
#for $ifc in $interfaces
auto ${ifc.name}
iface ${ifc.name} inet static
address ${ifc.address}
netmask ${ifc.netmask}
broadcast ${ifc.broadcast}
gateway ${ifc.gateway}
#if $ifc.dns
dns-nameservers ${ifc.dns}
#end if
#if $ifc.hwaddress
hwaddress ether ${ifc.hwaddress}
#end if
#if $use_ipv6
iface ${ifc.name} inet6 static
address ${ifc.address_v6}
netmask ${ifc.netmask_v6}
gateway ${ifc.gateway_v6}
#end if
#end for

View File

@ -0,0 +1,37 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2012 NTT DOCOMO, INC.
# All Rights Reserved.
#
# 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.
import os
from nova.openstack.common import log as logging
from nova.virt.libvirt import utils as libvirt_utils
LOG = logging.getLogger(__name__)
def cache_image(context, target, image_id, user_id, project_id):
if not os.path.exists(target):
libvirt_utils.fetch_image(context, target, image_id,
user_id, project_id)
def unlink_without_raise(path):
try:
libvirt_utils.file_delete(path)
except OSError:
LOG.exception(_("failed to unlink %s") % path)