diff options
Diffstat (limited to 'nova/virt/baremetal')
-rw-r--r-- | nova/virt/baremetal/base.py | 2 | ||||
-rw-r--r-- | nova/virt/baremetal/db/api.py | 36 | ||||
-rw-r--r-- | nova/virt/baremetal/db/sqlalchemy/api.py | 108 | ||||
-rw-r--r-- | nova/virt/baremetal/db/sqlalchemy/migrate_repo/versions/008_remove_bm_pxe_ips_table.py | 61 | ||||
-rw-r--r-- | nova/virt/baremetal/db/sqlalchemy/models.py | 9 | ||||
-rwxr-xr-x | nova/virt/baremetal/driver.py | 9 | ||||
-rw-r--r-- | nova/virt/baremetal/fake.py | 2 | ||||
-rw-r--r-- | nova/virt/baremetal/pxe.py | 58 | ||||
-rw-r--r-- | nova/virt/baremetal/pxe_config.template | 2 | ||||
-rwxr-xr-x | nova/virt/baremetal/tilera.py | 32 | ||||
-rwxr-xr-x | nova/virt/baremetal/tilera_pdu.py | 2 | ||||
-rw-r--r-- | nova/virt/baremetal/utils.py | 29 | ||||
-rw-r--r-- | nova/virt/baremetal/virtual_power_driver.py | 2 | ||||
-rw-r--r-- | nova/virt/baremetal/volume_driver.py | 11 |
14 files changed, 139 insertions, 224 deletions
diff --git a/nova/virt/baremetal/base.py b/nova/virt/baremetal/base.py index 2029400ba..876c70b23 100644 --- a/nova/virt/baremetal/base.py +++ b/nova/virt/baremetal/base.py @@ -30,7 +30,7 @@ class NodeDriver(object): def destroy_images(self, context, node, instance): raise NotImplementedError() - def activate_bootloader(self, context, node, instance): + def activate_bootloader(self, context, node, instance, **kwargs): raise NotImplementedError() def deactivate_bootloader(self, context, node, instance): diff --git a/nova/virt/baremetal/db/api.py b/nova/virt/baremetal/db/api.py index 91edc05d9..3943b7902 100644 --- a/nova/virt/baremetal/db/api.py +++ b/nova/virt/baremetal/db/api.py @@ -121,42 +121,6 @@ def bm_node_associate_and_update(context, node_uuid, values): return IMPL.bm_node_associate_and_update(context, node_uuid, values) -def bm_pxe_ip_create(context, address, server_address): - return IMPL.bm_pxe_ip_create(context, address, server_address) - - -def bm_pxe_ip_create_direct(context, bm_pxe_ip): - return IMPL.bm_pxe_ip_create_direct(context, bm_pxe_ip) - - -def bm_pxe_ip_destroy(context, ip_id): - return IMPL.bm_pxe_ip_destroy(context, ip_id) - - -def bm_pxe_ip_destroy_by_address(context, address): - return IMPL.bm_pxe_ip_destroy_by_address(context, address) - - -def bm_pxe_ip_get_all(context): - return IMPL.bm_pxe_ip_get_all(context) - - -def bm_pxe_ip_get(context, ip_id): - return IMPL.bm_pxe_ip_get(context, ip_id) - - -def bm_pxe_ip_get_by_bm_node_id(context, bm_node_id): - return IMPL.bm_pxe_ip_get_by_bm_node_id(context, bm_node_id) - - -def bm_pxe_ip_associate(context, bm_node_id): - return IMPL.bm_pxe_ip_associate(context, bm_node_id) - - -def bm_pxe_ip_disassociate(context, bm_node_id): - return IMPL.bm_pxe_ip_disassociate(context, bm_node_id) - - def bm_interface_get(context, if_id): return IMPL.bm_interface_get(context, if_id) diff --git a/nova/virt/baremetal/db/sqlalchemy/api.py b/nova/virt/baremetal/db/sqlalchemy/api.py index 88d44e3d3..3c140556e 100644 --- a/nova/virt/baremetal/db/sqlalchemy/api.py +++ b/nova/virt/baremetal/db/sqlalchemy/api.py @@ -236,111 +236,6 @@ def bm_node_destroy(context, bm_node_id): @sqlalchemy_api.require_admin_context -def bm_pxe_ip_get_all(context): - query = model_query(context, models.BareMetalPxeIp, read_deleted="no") - return query.all() - - -@sqlalchemy_api.require_admin_context -def bm_pxe_ip_create(context, address, server_address): - ref = models.BareMetalPxeIp() - ref.address = address - ref.server_address = server_address - _save(ref) - return ref - - -@sqlalchemy_api.require_admin_context -def bm_pxe_ip_create_direct(context, bm_pxe_ip): - ref = bm_pxe_ip_create(context, - address=bm_pxe_ip['address'], - server_address=bm_pxe_ip['server_address']) - return ref - - -@sqlalchemy_api.require_admin_context -def bm_pxe_ip_destroy(context, ip_id): - # Delete physically since it has unique columns - model_query(context, models.BareMetalPxeIp, read_deleted="no").\ - filter_by(id=ip_id).\ - delete() - - -@sqlalchemy_api.require_admin_context -def bm_pxe_ip_destroy_by_address(context, address): - # Delete physically since it has unique columns - model_query(context, models.BareMetalPxeIp, read_deleted="no").\ - filter_by(address=address).\ - delete() - - -@sqlalchemy_api.require_admin_context -def bm_pxe_ip_get(context, ip_id): - result = model_query(context, models.BareMetalPxeIp, read_deleted="no").\ - filter_by(id=ip_id).\ - first() - - return result - - -@sqlalchemy_api.require_admin_context -def bm_pxe_ip_get_by_bm_node_id(context, bm_node_id): - result = model_query(context, models.BareMetalPxeIp, read_deleted="no").\ - filter_by(bm_node_id=bm_node_id).\ - first() - - if not result: - raise exception.NodeNotFound(node_id=bm_node_id) - - return result - - -@sqlalchemy_api.require_admin_context -def bm_pxe_ip_associate(context, bm_node_id): - session = db_session.get_session() - with session.begin(): - # Check if the node really exists - node_ref = model_query(context, models.BareMetalNode, - read_deleted="no", session=session).\ - filter_by(id=bm_node_id).\ - first() - if not node_ref: - raise exception.NodeNotFound(node_id=bm_node_id) - - # Check if the node already has a pxe_ip - ip_ref = model_query(context, models.BareMetalPxeIp, - read_deleted="no", session=session).\ - filter_by(bm_node_id=bm_node_id).\ - first() - if ip_ref: - return ip_ref.id - - # with_lockmode('update') and filter_by(bm_node_id=None) will lock all - # records. It may cause a performance problem in high-concurrency - # environment. - ip_ref = model_query(context, models.BareMetalPxeIp, - read_deleted="no", session=session).\ - filter_by(bm_node_id=None).\ - with_lockmode('update').\ - first() - - # this exception is not caught in nova/compute/manager - if not ip_ref: - raise exception.NovaException(_("No more PXE IPs available")) - - ip_ref.bm_node_id = bm_node_id - session.add(ip_ref) - return ip_ref.id - - -@sqlalchemy_api.require_admin_context -def bm_pxe_ip_disassociate(context, bm_node_id): - model_query(context, models.BareMetalPxeIp, read_deleted="no").\ - filter_by(bm_node_id=bm_node_id).\ - update({'bm_node_id': None}) - - -@sqlalchemy_api.require_admin_context def bm_interface_get(context, if_id): result = model_query(context, models.BareMetalInterface, read_deleted="no").\ @@ -402,8 +297,7 @@ def bm_interface_set_vif_uuid(context, if_id, vif_uuid): if str(e).find('IntegrityError') != -1: raise exception.NovaException(_("Baremetal interface %s " "already in use") % vif_uuid) - else: - raise e + raise @sqlalchemy_api.require_admin_context diff --git a/nova/virt/baremetal/db/sqlalchemy/migrate_repo/versions/008_remove_bm_pxe_ips_table.py b/nova/virt/baremetal/db/sqlalchemy/migrate_repo/versions/008_remove_bm_pxe_ips_table.py new file mode 100644 index 000000000..22b45c480 --- /dev/null +++ b/nova/virt/baremetal/db/sqlalchemy/migrate_repo/versions/008_remove_bm_pxe_ips_table.py @@ -0,0 +1,61 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2013 Mirantis 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. + +from sqlalchemy import Boolean +from sqlalchemy import Column +from sqlalchemy import DateTime +from sqlalchemy import Index +from sqlalchemy import Integer +from sqlalchemy import MetaData +from sqlalchemy import String +from sqlalchemy import Table + + +table_name = 'bm_pxe_ips' + + +def upgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + + table = Table(table_name, meta, autoload=True) + table.drop() + + +def downgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + + bm_pxe_ips = Table(table_name, meta, + Column('created_at', DateTime), + Column('updated_at', DateTime), + Column('deleted_at', DateTime), + Column('deleted', Boolean), + Column('id', Integer, primary_key=True, nullable=False), + Column('address', String(length=255), unique=True), + Column('bm_node_id', Integer), + Column('server_address', + String(length=255), unique=True), + mysql_engine='InnoDB', + ) + bm_pxe_ips.create() + + Index( + 'idx_bm_pxe_ips_bm_node_id_deleted', + bm_pxe_ips.c.bm_node_id, + bm_pxe_ips.c.deleted + ).create(migrate_engine) diff --git a/nova/virt/baremetal/db/sqlalchemy/models.py b/nova/virt/baremetal/db/sqlalchemy/models.py index dbc9386ec..e21999634 100644 --- a/nova/virt/baremetal/db/sqlalchemy/models.py +++ b/nova/virt/baremetal/db/sqlalchemy/models.py @@ -54,15 +54,6 @@ class BareMetalNode(BASE, models.NovaBase): swap_mb = Column(Integer) -class BareMetalPxeIp(BASE, models.NovaBase): - __tablename__ = 'bm_pxe_ips' - id = Column(Integer, primary_key=True) - deleted = Column(Boolean, default=False) - address = Column(String(255), unique=True) - server_address = Column(String(255), unique=True) - bm_node_id = Column(Integer, ForeignKey('bm_nodes.id'), nullable=True) - - class BareMetalInterface(BASE, models.NovaBase): __tablename__ = 'bm_interfaces' id = Column(Integer, primary_key=True) diff --git a/nova/virt/baremetal/driver.py b/nova/virt/baremetal/driver.py index 376921360..703cc0980 100755 --- a/nova/virt/baremetal/driver.py +++ b/nova/virt/baremetal/driver.py @@ -248,8 +248,10 @@ class BareMetalDriver(driver.ComputeDriver): injected_files=injected_files, network_info=network_info, ) - self.driver.activate_bootloader(context, node, instance) - self.power_on(instance, node) + self.driver.activate_bootloader(context, node, instance, + network_info=network_info) + self.power_on(context, instance, network_info, block_device_info, + node) self.driver.activate_node(context, node, instance) _update_state(context, node, instance, baremetal_states.ACTIVE) except Exception: @@ -330,7 +332,8 @@ class BareMetalDriver(driver.ComputeDriver): "for instance %r") % instance['uuid']) pm.stop_console() - def power_on(self, instance, node=None): + def power_on(self, context, instance, network_info, block_device_info=None, + node=None): """Power on the specified instance.""" if not node: node = _get_baremetal_node_by_instance_uuid(instance['uuid']) diff --git a/nova/virt/baremetal/fake.py b/nova/virt/baremetal/fake.py index b3f39fdc3..76586ab74 100644 --- a/nova/virt/baremetal/fake.py +++ b/nova/virt/baremetal/fake.py @@ -28,7 +28,7 @@ class FakeDriver(base.NodeDriver): def destroy_images(self, context, node, instance): pass - def activate_bootloader(self, context, node, instance): + def activate_bootloader(self, context, node, instance, **kwargs): pass def deactivate_bootloader(self, context, node, instance): diff --git a/nova/virt/baremetal/pxe.py b/nova/virt/baremetal/pxe.py index 6a5a5ece5..21fc2ce47 100644 --- a/nova/virt/baremetal/pxe.py +++ b/nova/virt/baremetal/pxe.py @@ -54,6 +54,10 @@ pxe_opts = [ cfg.IntOpt('pxe_deploy_timeout', help='Timeout for PXE deployments. Default: 0 (unlimited)', default=0), + cfg.BoolOpt('pxe_network_config', + help='If set, pass the network configuration details to the ' + 'initramfs via cmdline.', + default=False), ] LOG = logging.getLogger(__name__) @@ -77,9 +81,22 @@ def _get_cheetah(): return CHEETAH +def build_pxe_network_config(network_info): + interfaces = bm_utils.map_network_interfaces(network_info, CONF.use_ipv6) + template = None + if not CONF.use_ipv6: + template = "ip=%(address)s::%(gateway)s:%(netmask)s::%(name)s:off" + else: + template = ("ip=[%(address_v6)s]::[%(gateway_v6)s]:" + "[%(netmask_v6)s]::%(name)s:off") + + net_config = [template % iface for iface in interfaces] + return ' '.join(net_config) + + def build_pxe_config(deployment_id, deployment_key, deployment_iscsi_iqn, deployment_aki_path, deployment_ari_path, - aki_path, ari_path): + aki_path, ari_path, network_info): """Build the PXE config file for a node This method builds the PXE boot configuration file for a node, @@ -90,6 +107,11 @@ def build_pxe_config(deployment_id, deployment_key, deployment_iscsi_iqn, """ LOG.debug(_("Building PXE config for deployment %s.") % deployment_id) + + network_config = None + if network_info and CONF.baremetal.pxe_network_config: + network_config = build_pxe_network_config(network_info) + pxe_options = { 'deployment_id': deployment_id, 'deployment_key': deployment_key, @@ -99,6 +121,7 @@ def build_pxe_config(deployment_id, deployment_key, deployment_iscsi_iqn, 'aki_path': aki_path, 'ari_path': ari_path, 'pxe_append_params': CONF.baremetal.pxe_append_params, + 'pxe_network_config': network_config, } cheetah = _get_cheetah() pxe_config = str(cheetah( @@ -110,33 +133,7 @@ def build_pxe_config(deployment_id, deployment_key, deployment_iscsi_iqn, def build_network_config(network_info): - # TODO(deva): fix assumption that device names begin with "eth" - # and fix assumption about ordering - try: - assert isinstance(network_info, list) - except AssertionError: - network_info = [network_info] - interfaces = [] - for id, (network, mapping) in enumerate(network_info): - address_v6 = None - gateway_v6 = None - netmask_v6 = None - if CONF.use_ipv6: - address_v6 = mapping['ip6s'][0]['ip'] - netmask_v6 = mapping['ip6s'][0]['netmask'] - gateway_v6 = mapping['gateway_v6'] - interface = { - 'name': 'eth%d' % id, - 'address': mapping['ips'][0]['ip'], - 'gateway': mapping['gateway'], - 'netmask': mapping['ips'][0]['netmask'], - 'dns': ' '.join(mapping['dns']), - 'address_v6': address_v6, - 'gateway_v6': gateway_v6, - 'netmask_v6': netmask_v6, - } - interfaces.append(interface) - + interfaces = bm_utils.map_network_interfaces(network_info, CONF.use_ipv6) cheetah = _get_cheetah() network_config = str(cheetah( open(CONF.baremetal.net_config_template).read(), @@ -216,7 +213,7 @@ def get_tftp_image_info(instance, instance_type): image_info['ramdisk'][0] = str(instance['ramdisk_id']) image_info['deploy_kernel'][0] = get_deploy_aki_id(instance_type) image_info['deploy_ramdisk'][0] = get_deploy_ari_id(instance_type) - except KeyError as e: + except KeyError: pass missing_labels = [] @@ -354,7 +351,7 @@ class PXE(base.NodeDriver): bm_utils.unlink_without_raise(get_image_file_path(instance)) bm_utils.rmtree_without_raise(get_image_dir_path(instance)) - def activate_bootloader(self, context, node, instance): + def activate_bootloader(self, context, node, instance, network_info): """Configure PXE boot loader for an instance Kernel and ramdisk images are downloaded by cache_tftp_images, @@ -398,6 +395,7 @@ class PXE(base.NodeDriver): image_info['deploy_ramdisk'][1], image_info['kernel'][1], image_info['ramdisk'][1], + network_info, ) bm_utils.write_to_file(pxe_config_file_path, pxe_config) diff --git a/nova/virt/baremetal/pxe_config.template b/nova/virt/baremetal/pxe_config.template index f2fcc9b14..54dd98baf 100644 --- a/nova/virt/baremetal/pxe_config.template +++ b/nova/virt/baremetal/pxe_config.template @@ -8,4 +8,4 @@ ipappend 3 label boot kernel ${pxe_options.aki_path} -append initrd=${pxe_options.ari_path} root=${ROOT} ro ${pxe_options.pxe_append_params} +append initrd=${pxe_options.ari_path} root=${ROOT} ro ${pxe_options.pxe_append_params} ${pxe_options.pxe_network_config} diff --git a/nova/virt/baremetal/tilera.py b/nova/virt/baremetal/tilera.py index 64335298c..36127bfa2 100755 --- a/nova/virt/baremetal/tilera.py +++ b/nova/virt/baremetal/tilera.py @@ -55,31 +55,7 @@ def _get_cheetah(): def build_network_config(network_info): - try: - assert isinstance(network_info, list) - except AssertionError: - network_info = [network_info] - interfaces = [] - for id, (network, mapping) in enumerate(network_info): - address_v6 = None - gateway_v6 = None - netmask_v6 = None - if CONF.use_ipv6: - address_v6 = mapping['ip6s'][0]['ip'] - netmask_v6 = mapping['ip6s'][0]['netmask'] - gateway_v6 = mapping['gateway_v6'] - interface = { - 'name': 'eth%d' % id, - 'address': mapping['ips'][0]['ip'], - 'gateway': mapping['gateway'], - 'netmask': mapping['ips'][0]['netmask'], - 'dns': ' '.join(mapping['dns']), - 'address_v6': address_v6, - 'gateway_v6': gateway_v6, - 'netmask_v6': netmask_v6, - } - interfaces.append(interface) - + interfaces = bm_utils.map_network_interfaces(network_info, CONF.use_ipv6) cheetah = _get_cheetah() network_config = str(cheetah( open(CONF.baremetal.net_config_template).read(), @@ -130,7 +106,7 @@ def get_tftp_image_info(instance): } try: image_info['kernel'][0] = str(instance['kernel_id']) - except KeyError as e: + except KeyError: pass missing_labels = [] @@ -262,7 +238,7 @@ class Tilera(base.NodeDriver): bm_utils.unlink_without_raise(get_image_file_path(instance)) bm_utils.rmtree_without_raise(get_image_dir_path(instance)) - def activate_bootloader(self, context, node, instance): + def activate_bootloader(self, context, node, instance, network_info): """Configure Tilera boot loader for an instance Kernel and ramdisk images are downloaded by cache_tftp_images, @@ -371,7 +347,7 @@ class Tilera(base.NodeDriver): user_data = instance['user_data'] try: self._iptables_set(node_ip, user_data) - except Exception as ex: + except Exception: self.deactivate_bootloader(context, node, instance) raise exception.NovaException(_("Node is " "unknown error state.")) diff --git a/nova/virt/baremetal/tilera_pdu.py b/nova/virt/baremetal/tilera_pdu.py index 0e491168f..90f9287e4 100755 --- a/nova/virt/baremetal/tilera_pdu.py +++ b/nova/virt/baremetal/tilera_pdu.py @@ -109,7 +109,7 @@ class Pdu(base.PowerManager): return CONF.baremetal.tile_pdu_off else: try: - out = utils.execute(CONF.baremetal.tile_pdu_mgr, + utils.execute(CONF.baremetal.tile_pdu_mgr, CONF.baremetal.tile_pdu_ip, mode) time.sleep(CONF.baremetal.tile_power_wait) return mode diff --git a/nova/virt/baremetal/utils.py b/nova/virt/baremetal/utils.py index b18bfac85..96abcd41b 100644 --- a/nova/virt/baremetal/utils.py +++ b/nova/virt/baremetal/utils.py @@ -81,3 +81,32 @@ def random_alnum(count): import string chars = string.ascii_uppercase + string.digits return "".join(random.choice(chars) for _ in range(count)) + + +def map_network_interfaces(network_info, use_ipv6=False): + # TODO(deva): fix assumption that device names begin with "eth" + # and fix assumption about ordering + if not isinstance(network_info, list): + network_info = [network_info] + + interfaces = [] + for id, (network, mapping) in enumerate(network_info): + address_v6 = None + gateway_v6 = None + netmask_v6 = None + if use_ipv6: + address_v6 = mapping['ip6s'][0]['ip'] + netmask_v6 = mapping['ip6s'][0]['netmask'] + gateway_v6 = mapping['gateway_v6'] + interface = { + 'name': 'eth%d' % id, + 'address': mapping['ips'][0]['ip'], + 'gateway': mapping['gateway'], + 'netmask': mapping['ips'][0]['netmask'], + 'dns': ' '.join(mapping['dns']), + 'address_v6': address_v6, + 'gateway_v6': gateway_v6, + 'netmask_v6': netmask_v6, + } + interfaces.append(interface) + return interfaces diff --git a/nova/virt/baremetal/virtual_power_driver.py b/nova/virt/baremetal/virtual_power_driver.py index e110bf436..303e5a009 100644 --- a/nova/virt/baremetal/virtual_power_driver.py +++ b/nova/virt/baremetal/virtual_power_driver.py @@ -59,7 +59,6 @@ CONF.register_group(baremetal_vp) CONF.register_opts(opts, baremetal_vp) _conn = None -_virtual_power_settings = None _vp_cmd = None _cmds = None @@ -84,7 +83,6 @@ class VirtualPowerManager(base.PowerManager): """ def __init__(self, **kwargs): global _conn - global _virtual_power_settings global _cmds if _cmds is None: diff --git a/nova/virt/baremetal/volume_driver.py b/nova/virt/baremetal/volume_driver.py index 6cf6b775f..f634fa76a 100644 --- a/nova/virt/baremetal/volume_driver.py +++ b/nova/virt/baremetal/volume_driver.py @@ -21,6 +21,7 @@ import re from oslo.config import cfg from nova import context as nova_context +from nova.db import api as nova_db_api from nova import exception from nova.openstack.common import importutils from nova.openstack.common import log as logging @@ -219,10 +220,9 @@ class LibvirtVolumeDriver(VolumeDriver): return method(connection_info, *args, **kwargs) def attach_volume(self, connection_info, instance, mountpoint): - node = _get_baremetal_node_by_instance_uuid(instance['uuid']) ctx = nova_context.get_admin_context() - pxe_ip = bmdb.bm_pxe_ip_get_by_bm_node_id(ctx, node['id']) - if not pxe_ip: + fixed_ips = nova_db_api.fixed_ip_get_by_instance(ctx, instance['uuid']) + if not fixed_ips: if not CONF.baremetal.use_unsafe_iscsi: raise exception.NovaException(_( 'No fixed PXE IP is associated to %s') % instance['uuid']) @@ -236,8 +236,9 @@ class LibvirtVolumeDriver(VolumeDriver): tid = _get_next_tid() _create_iscsi_export_tgtadm(device_path, tid, iqn) - if pxe_ip: - _allow_iscsi_tgtadm(tid, pxe_ip['address']) + if fixed_ips: + for ip in fixed_ips: + _allow_iscsi_tgtadm(tid, ip['address']) else: # NOTE(NTTdocomo): Since nova-compute does not know the # instance's initiator ip, it allows any initiators |