summaryrefslogtreecommitdiffstats
path: root/nova/virt
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2013-02-21 00:29:50 +0000
committerGerrit Code Review <review@openstack.org>2013-02-21 00:29:50 +0000
commit31347223a655f33cff6b51916eba0ea96da7a4e3 (patch)
tree622e0c4da24c64876c85fdb6e6dc1b3f49a9f7ea /nova/virt
parent20422f46e8a506a751844c94f0f7b25bf8220e2b (diff)
parent48439b98a1a7ac2dded34c8899918773f70667f2 (diff)
downloadnova-31347223a655f33cff6b51916eba0ea96da7a4e3.tar.gz
nova-31347223a655f33cff6b51916eba0ea96da7a4e3.tar.xz
nova-31347223a655f33cff6b51916eba0ea96da7a4e3.zip
Merge "Wait for baremetal deploy inside driver.spawn"
Diffstat (limited to 'nova/virt')
-rwxr-xr-xnova/virt/baremetal/driver.py25
-rw-r--r--nova/virt/baremetal/pxe.py53
2 files changed, 63 insertions, 15 deletions
diff --git a/nova/virt/baremetal/driver.py b/nova/virt/baremetal/driver.py
index 379eaf04d..7fc03efe0 100755
--- a/nova/virt/baremetal/driver.py
+++ b/nova/virt/baremetal/driver.py
@@ -26,7 +26,6 @@ from oslo.config import cfg
from nova.compute import power_state
from nova import context as nova_context
from nova import exception
-from nova.openstack.common.db.sqlalchemy import session as db_session
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
from nova import paths
@@ -219,6 +218,7 @@ class BareMetalDriver(driver.ComputeDriver):
node = db.bm_node_set_uuid_safe(context, node_id,
{'instance_uuid': instance['uuid'],
'task_state': baremetal_states.BUILDING})
+
pm = get_power_manager(node=node, instance=instance)
try:
@@ -249,6 +249,15 @@ class BareMetalDriver(driver.ComputeDriver):
)
try:
self.driver.activate_bootloader(context, node, instance)
+ pm.activate_node()
+ pm.start_console()
+ if pm.state != baremetal_states.ACTIVE:
+ raise exception.NovaException(_(
+ "Baremetal power manager failed to start node "
+ "for instance %r") % instance['uuid'])
+ self.driver.activate_node(context, node, instance)
+ _update_state(context, node, instance,
+ baremetal_states.ACTIVE)
except Exception, e:
self.driver.deactivate_bootloader(context, node, instance)
raise e
@@ -257,20 +266,8 @@ class BareMetalDriver(driver.ComputeDriver):
raise e
except Exception, e:
# TODO(deva): do network and volume cleanup here
+ _update_state(context, node, instance, baremetal_states.ERROR)
raise e
- else:
- # NOTE(deva): pm.activate_node should not raise exceptions.
- # We check its success in "finally" block
- pm.activate_node()
- pm.start_console()
- finally:
- if pm.state != baremetal_states.ACTIVE:
- pm.state = baremetal_states.ERROR
- try:
- _update_state(context, node, instance, pm.state)
- except db_session.DBError, e:
- LOG.warning(_("Failed to update state record for "
- "baremetal node %s") % instance['uuid'])
def reboot(self, context, instance, network_info, reboot_type,
block_device_info=None):
diff --git a/nova/virt/baremetal/pxe.py b/nova/virt/baremetal/pxe.py
index e6cefcca1..0abede93c 100644
--- a/nova/virt/baremetal/pxe.py
+++ b/nova/virt/baremetal/pxe.py
@@ -20,6 +20,7 @@
Class for PXE bare-metal nodes.
"""
+import datetime
import os
from oslo.config import cfg
@@ -29,6 +30,9 @@ from nova import exception
from nova.openstack.common.db.sqlalchemy import session as db_session
from nova.openstack.common import fileutils
from nova.openstack.common import log as logging
+from nova.openstack.common import timeutils
+from nova import utils
+from nova.virt.baremetal import baremetal_states
from nova.virt.baremetal import base
from nova.virt.baremetal import db
from nova.virt.baremetal import utils as bm_utils
@@ -47,6 +51,9 @@ pxe_opts = [
cfg.StrOpt('pxe_config_template',
default='$pybasedir/nova/virt/baremetal/pxe_config.template',
help='Template file for PXE configuration'),
+ cfg.IntOpt('pxe_deploy_timeout',
+ help='Timeout for PXE deployments. Default: 0 (unlimited)',
+ default=0),
]
LOG = logging.getLogger(__name__)
@@ -431,7 +438,51 @@ class PXE(base.NodeDriver):
os.path.join(CONF.baremetal.tftp_root, instance['uuid']))
def activate_node(self, context, node, instance):
- pass
+ """Wait for PXE deployment to complete."""
+
+ locals = {'error': '', 'started': False}
+
+ def _wait_for_deploy():
+ """Called at an interval until the deployment completes."""
+ try:
+ row = db.bm_node_get(context, node['id'])
+ if instance['uuid'] != row.get('instance_uuid'):
+ locals['error'] = _("Node associated with another instance"
+ " while waiting for deploy of %s")
+ raise utils.LoopingCallDone()
+
+ status = row.get('task_state')
+ if (status == baremetal_states.DEPLOYING
+ and locals['started'] == False):
+ LOG.info(_("PXE deploy started for instance %s")
+ % instance['uuid'])
+ locals['started'] = True
+ elif status in (baremetal_states.DEPLOYDONE,
+ baremetal_states.ACTIVE):
+ LOG.info(_("PXE deploy completed for instance %s")
+ % instance['uuid'])
+ raise utils.LoopingCallDone()
+ elif status == baremetal_states.DEPLOYFAIL:
+ locals['error'] = _("PXE deploy failed for instance %s")
+ except exception.InstanceNotFound:
+ locals['error'] = _("Baremetal node deleted while waiting "
+ "for deployment of instance %s")
+
+ if (CONF.baremetal.pxe_deploy_timeout and
+ timeutils.utcnow() > expiration):
+ locals['error'] = _("Timeout reached while waiting for "
+ "PXE deploy of instance %s")
+ if locals['error']:
+ raise utils.LoopingCallDone()
+
+ expiration = timeutils.utcnow() + datetime.timedelta(
+ seconds=CONF.baremetal.pxe_deploy_timeout)
+ timer = utils.FixedIntervalLoopingCall(_wait_for_deploy)
+ timer.start(interval=1).wait()
+
+ if locals['error']:
+ raise exception.InstanceDeployFailure(
+ locals['error'] % instance['uuid'])
def deactivate_node(self, context, node, instance):
pass