summaryrefslogtreecommitdiffstats
path: root/nova/virt
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2013-02-21 00:30:45 +0000
committerGerrit Code Review <review@openstack.org>2013-02-21 00:30:45 +0000
commit65d315929d64fcf199271a21c62c4cd2649556fc (patch)
treeefe233306ec863e0ec6c477a5b21b2a9f45efd38 /nova/virt
parent61290aa603f08a927f7c7a82f0b5d0319b7c67f8 (diff)
parentab9f8667c63d901f37d1662c5204fb2938be44fe (diff)
Merge "Identify baremetal nodes by UUID."
Diffstat (limited to 'nova/virt')
-rw-r--r--nova/virt/baremetal/db/api.py8
-rw-r--r--nova/virt/baremetal/db/sqlalchemy/api.py38
-rw-r--r--nova/virt/baremetal/db/sqlalchemy/migrate_repo/versions/003_add_uuid_to_bm_nodes.py40
-rw-r--r--nova/virt/baremetal/db/sqlalchemy/models.py1
-rwxr-xr-xnova/virt/baremetal/driver.py32
-rw-r--r--nova/virt/baremetal/pxe.py4
6 files changed, 93 insertions, 30 deletions
diff --git a/nova/virt/baremetal/db/api.py b/nova/virt/baremetal/db/api.py
index 44a5c1bcd..91edc05d9 100644
--- a/nova/virt/baremetal/db/api.py
+++ b/nova/virt/baremetal/db/api.py
@@ -101,6 +101,10 @@ def bm_node_get_by_instance_uuid(context, instance_uuid):
instance_uuid)
+def bm_node_get_by_node_uuid(context, node_uuid):
+ return IMPL.bm_node_get_by_node_uuid(context, node_uuid)
+
+
def bm_node_create(context, values):
return IMPL.bm_node_create(context, values)
@@ -113,8 +117,8 @@ def bm_node_update(context, bm_node_id, values):
return IMPL.bm_node_update(context, bm_node_id, values)
-def bm_node_set_uuid_safe(context, bm_node_id, uuid):
- return IMPL.bm_node_set_uuid_safe(context, bm_node_id, uuid)
+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):
diff --git a/nova/virt/baremetal/db/sqlalchemy/api.py b/nova/virt/baremetal/db/sqlalchemy/api.py
index 4a27e48be..e06bcd7d2 100644
--- a/nova/virt/baremetal/db/sqlalchemy/api.py
+++ b/nova/virt/baremetal/db/sqlalchemy/api.py
@@ -20,6 +20,8 @@
"""Implementation of SQLAlchemy backend."""
+import uuid
+
from sqlalchemy.sql.expression import asc
from sqlalchemy.sql.expression import literal_column
@@ -132,7 +134,7 @@ def bm_node_get(context, bm_node_id):
first()
if not result:
- raise exception.InstanceNotFound(instance_id=bm_node_id)
+ raise exception.NodeNotFound(node_id=bm_node_id)
return result
@@ -153,7 +155,21 @@ def bm_node_get_by_instance_uuid(context, instance_uuid):
@sqlalchemy_api.require_admin_context
+def bm_node_get_by_node_uuid(context, bm_node_uuid):
+ result = model_query(context, models.BareMetalNode, read_deleted="no").\
+ filter_by(uuid=bm_node_uuid).\
+ first()
+
+ if not result:
+ raise exception.NodeNotFoundByUUID(node_uuid=bm_node_uuid)
+
+ return result
+
+
+@sqlalchemy_api.require_admin_context
def bm_node_create(context, values):
+ if not values.get('uuid'):
+ values['uuid'] = str(uuid.uuid4())
bm_node_ref = models.BareMetalNode()
bm_node_ref.update(values)
_save(bm_node_ref)
@@ -167,11 +183,11 @@ def bm_node_update(context, bm_node_id, values):
update(values)
if not rows:
- raise exception.InstanceNotFound(instance_id=bm_node_id)
+ raise exception.NodeNotFound(node_id=bm_node_id)
@sqlalchemy_api.require_admin_context
-def bm_node_set_uuid_safe(context, bm_node_id, values):
+def bm_node_associate_and_update(context, node_uuid, values):
"""Associate an instance to a node safely
Associate an instance to a node only if that node is not yet assocated.
@@ -182,21 +198,21 @@ def bm_node_set_uuid_safe(context, bm_node_id, values):
"""
if 'instance_uuid' not in values:
raise exception.NovaException(_(
- "instance_uuid must be supplied to bm_node_set_uuid_safe"))
+ "instance_uuid must be supplied to bm_node_associate_and_update"))
session = db_session.get_session()
with session.begin():
query = model_query(context, models.BareMetalNode,
session=session, read_deleted="no").\
- filter_by(id=bm_node_id)
+ filter_by(uuid=node_uuid)
count = query.filter_by(instance_uuid=None).\
update(values, synchronize_session=False)
if count != 1:
raise exception.NovaException(_(
- "Failed to associate instance %(uuid)s to baremetal node "
- "%(id)s.") % {'id': bm_node_id,
- 'uuid': values['instance_uuid']})
+ "Failed to associate instance %(i_uuid)s to baremetal node "
+ "%(n_uuid)s.") % {'i_uuid': values['instance_uuid'],
+ 'n_uuid': node_uuid})
ref = query.first()
return ref
@@ -270,7 +286,7 @@ def bm_pxe_ip_get_by_bm_node_id(context, bm_node_id):
first()
if not result:
- raise exception.InstanceNotFound(instance_id=bm_node_id)
+ raise exception.NodeNotFound(node_id=bm_node_id)
return result
@@ -285,7 +301,7 @@ def bm_pxe_ip_associate(context, bm_node_id):
filter_by(id=bm_node_id).\
first()
if not node_ref:
- raise exception.InstanceNotFound(instance_id=bm_node_id)
+ raise exception.NodeNotFound(node_id=bm_node_id)
# Check if the node already has a pxe_ip
ip_ref = model_query(context, models.BareMetalPxeIp,
@@ -408,6 +424,6 @@ def bm_interface_get_all_by_bm_node_id(context, bm_node_id):
all()
if not result:
- raise exception.InstanceNotFound(instance_id=bm_node_id)
+ raise exception.NodeNotFound(node_id=bm_node_id)
return result
diff --git a/nova/virt/baremetal/db/sqlalchemy/migrate_repo/versions/003_add_uuid_to_bm_nodes.py b/nova/virt/baremetal/db/sqlalchemy/migrate_repo/versions/003_add_uuid_to_bm_nodes.py
new file mode 100644
index 000000000..cc9a9316d
--- /dev/null
+++ b/nova/virt/baremetal/db/sqlalchemy/migrate_repo/versions/003_add_uuid_to_bm_nodes.py
@@ -0,0 +1,40 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 Hewlett-Packard Development Company, L.P.
+# 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 Column, MetaData, String, Table, Index
+
+
+def upgrade(migrate_engine):
+ meta = MetaData()
+ meta.bind = migrate_engine
+
+ t = Table('bm_nodes', meta, autoload=True)
+ uuid_col = Column('uuid', String(36))
+ t.create_column(uuid_col)
+
+ uuid_ux = Index('uuid_ux', t.c.uuid, unique=True)
+ uuid_ux.create(migrate_engine)
+
+
+def downgrade(migrate_engine):
+ meta = MetaData()
+ meta.bind = migrate_engine
+
+ t = Table('bm_nodes', meta, autoload=True)
+ uuid_col = Column('uuid', String(length=36))
+
+ t.drop_column(uuid_col)
diff --git a/nova/virt/baremetal/db/sqlalchemy/models.py b/nova/virt/baremetal/db/sqlalchemy/models.py
index fe86d7244..e1a8ebb3a 100644
--- a/nova/virt/baremetal/db/sqlalchemy/models.py
+++ b/nova/virt/baremetal/db/sqlalchemy/models.py
@@ -34,6 +34,7 @@ class BareMetalNode(BASE, models.NovaBase):
__tablename__ = 'bm_nodes'
id = Column(Integer, primary_key=True)
+ uuid = Column(String(36))
service_host = Column(String(255))
instance_uuid = Column(String(36), nullable=True)
cpus = Column(Integer)
diff --git a/nova/virt/baremetal/driver.py b/nova/virt/baremetal/driver.py
index d3d45682b..b95a3ad61 100755
--- a/nova/virt/baremetal/driver.py
+++ b/nova/virt/baremetal/driver.py
@@ -186,17 +186,17 @@ class BareMetalDriver(driver.ComputeDriver):
return l
def _require_node(self, instance):
- """Get a node_id out of a manager instance dict.
+ """Get a node's uuid out of a manager instance dict.
- The compute manager is meant to know the node id, so a missing node is
+ The compute manager is meant to know the node uuid, so missing uuid
a significant issue - it may mean we've been passed someone elses data.
"""
- node_id = instance.get('node')
- if not node_id:
+ node_uuid = instance.get('node')
+ if not node_uuid:
raise exception.NovaException(_(
"Baremetal node id not supplied to driver for %r")
% instance['uuid'])
- return node_id
+ return node_uuid
def _attach_block_devices(self, instance, block_device_info):
block_device_mapping = driver.\
@@ -230,18 +230,19 @@ class BareMetalDriver(driver.ComputeDriver):
def macs_for_instance(self, instance):
context = nova_context.get_admin_context()
- node_id = self._require_node(instance)
- return set(iface['address'] for iface in
- db.bm_interface_get_all_by_bm_node_id(context, node_id))
+ node_uuid = self._require_node(instance)
+ node = db.bm_node_get_by_node_uuid(context, node_uuid)
+ ifaces = db.bm_interface_get_all_by_bm_node_id(context, node['id'])
+ return set(iface['address'] for iface in ifaces)
def spawn(self, context, instance, image_meta, injected_files,
admin_password, network_info=None, block_device_info=None):
- node_id = self._require_node(instance)
+ node_uuid = self._require_node(instance)
# NOTE(deva): this db method will raise an exception if the node is
# already in use. We call it here to ensure no one else
# allocates this node before we begin provisioning it.
- node = db.bm_node_set_uuid_safe(context, node_id,
+ node = db.bm_node_associate_and_update(context, node_uuid,
{'instance_uuid': instance['uuid'],
'task_state': baremetal_states.BUILDING})
@@ -265,7 +266,8 @@ class BareMetalDriver(driver.ComputeDriver):
with excutils.save_and_reraise_exception():
LOG.error(_("Error deploying instance %(instance)s "
"on baremetal node %(node)s.") %
- {'instance': instance['uuid'], 'node': node['id']})
+ {'instance': instance['uuid'],
+ 'node': node['uuid']})
# Do not set instance=None yet. This prevents another
# spawn() while we are cleaning up.
@@ -408,7 +410,7 @@ class BareMetalDriver(driver.ComputeDriver):
'local_gb_used': local_gb_used,
'hypervisor_type': self.get_hypervisor_type(),
'hypervisor_version': self.get_hypervisor_version(),
- 'hypervisor_hostname': str(node['id']),
+ 'hypervisor_hostname': str(node['uuid']),
'cpu_info': 'baremetal cpu',
}
return dic
@@ -418,7 +420,7 @@ class BareMetalDriver(driver.ComputeDriver):
def get_available_resource(self, nodename):
context = nova_context.get_admin_context()
- node = db.bm_node_get(context, nodename)
+ node = db.bm_node_get_by_node_uuid(context, nodename)
dic = self._node_resource(node)
return dic
@@ -438,7 +440,7 @@ class BareMetalDriver(driver.ComputeDriver):
service_host=CONF.host)
for node in nodes:
res = self._node_resource(node)
- nodename = str(node['id'])
+ nodename = str(node['uuid'])
data = {}
data['vcpus'] = res['vcpus']
data['vcpus_used'] = res['vcpus_used']
@@ -489,5 +491,5 @@ class BareMetalDriver(driver.ComputeDriver):
def get_available_nodes(self):
context = nova_context.get_admin_context()
- return [str(n['id']) for n in
+ return [str(n['uuid']) for n in
db.bm_node_get_unassociated(context, service_host=CONF.host)]
diff --git a/nova/virt/baremetal/pxe.py b/nova/virt/baremetal/pxe.py
index 0abede93c..813f95c05 100644
--- a/nova/virt/baremetal/pxe.py
+++ b/nova/virt/baremetal/pxe.py
@@ -413,7 +413,7 @@ class PXE(base.NodeDriver):
'pxe_config_path': None,
'root_mb': 0,
'swap_mb': 0})
- except exception.InstanceNotFound:
+ except exception.NodeNotFound:
pass
try:
@@ -464,7 +464,7 @@ class PXE(base.NodeDriver):
raise utils.LoopingCallDone()
elif status == baremetal_states.DEPLOYFAIL:
locals['error'] = _("PXE deploy failed for instance %s")
- except exception.InstanceNotFound:
+ except exception.NodeNotFound:
locals['error'] = _("Baremetal node deleted while waiting "
"for deployment of instance %s")