[fix] default design_links to empty list

When doing a single-node deployment, the site_design.network_links
may not have any contents. In this case, default to empty list
so that subsequent loops do not break

- Add checks for 'no work' contexts so that tasks
  fast exit and mark themselves successful

Change-Id: I4261abf7456ab16806916af75024e347c6e1e1ce
This commit is contained in:
Bryan Strassner 2018-03-24 13:52:15 -05:00
parent 12650c7909
commit be667ab3c0
4 changed files with 141 additions and 72 deletions

View File

@ -225,10 +225,20 @@ class CreateNetworkTemplate(BaseMaasAction):
self.task.save()
return
if not site_design.network_links:
msg = ("Site design has no network links, no work to do.")
self.logger.debug(msg)
self.task.add_status_msg(
msg=msg, error=False, ctx='NA', ctx_type='NA')
self.task.success()
self.task.set_status(hd_fields.TaskStatus.Complete)
self.task.save()
return
# Try to true up MaaS definitions of fabrics/vlans/subnets
# with the networks defined in Drydock
design_networks = list()
design_links = site_design.network_links
design_links = site_design.network_links or []
fabrics = maas_fabric.Fabrics(self.maas_client)
fabrics.refresh()
@ -645,30 +655,40 @@ class ConfigureUserCredentials(BaseMaasAction):
site_model = site_design.get_site()
for k in getattr(site_model, 'authorized_keys', []):
try:
if len(key_list.query({'key': k.replace("\n", "")})) == 0:
new_key = maas_keys.SshKey(self.maas_client, key=k)
new_key = key_list.add(new_key)
msg = "Added SSH key %s to MaaS user profile. Will be installed on all deployed nodes." % (
k[:16])
self.logger.debug(msg)
key_list = getattr(site_model, 'authorized_keys', None) or []
if key_list:
for k in key_list:
try:
if len(key_list.query({'key': k.replace("\n", "")})) == 0:
new_key = maas_keys.SshKey(self.maas_client, key=k)
new_key = key_list.add(new_key)
msg = "Added SSH key %s to MaaS user profile. Will be installed on all deployed nodes." % (
k[:16])
self.logger.debug(msg)
self.task.add_status_msg(
msg=msg, error=False, ctx='NA', ctx_type='NA')
self.task.success()
else:
msg = "SSH key %s already exists in MaaS user profile." % k[:
16]
self.logger.debug(msg)
self.task.add_status_msg(
msg=msg, error=False, ctx='NA', ctx_type='NA')
self.task.success()
except Exception as ex:
msg = "Error adding SSH key to MaaS user profile: %s" % str(
ex)
self.logger.warning(msg)
self.task.add_status_msg(
msg=msg, error=False, ctx='NA', ctx_type='NA')
self.task.success()
else:
msg = "SSH key %s already exists in MaaS user profile." % k[:
16]
self.logger.debug(msg)
self.task.add_status_msg(
msg=msg, error=False, ctx='NA', ctx_type='NA')
self.task.success()
except Exception as ex:
msg = "Error adding SSH key to MaaS user profile: %s" % str(ex)
self.logger.warning(msg)
self.task.add_status_msg(
msg=msg, error=True, ctx='NA', ctx_type='NA')
self.task.failure()
msg=msg, error=True, ctx='NA', ctx_type='NA')
self.task.failure()
else:
msg = ("No keys to add, no work to do.")
self.logger.debug(msg)
self.task.success()
self.task.add_status_msg(
msg=msg, error=False, ctx='NA', ctx_type='NA')
self.task.set_status(hd_fields.TaskStatus.Complete)
self.task.save()
@ -958,19 +978,27 @@ class ApplyNodeNetworking(BaseMaasAction):
if machine is not None:
if machine.status_name.startswith('Failed Dep'):
msg = ("Node %s has failed deployment, releasing to try again." % n.name)
msg = (
"Node %s has failed deployment, releasing to try again."
% n.name)
self.logger.debug(msg)
try:
machine.release()
machine.refresh()
except errors.DriverError as ex:
msg = ("Node %s could not be released, skipping deployment." % n.name)
msg = (
"Node %s could not be released, skipping deployment."
% n.name)
self.logger.info(msg)
self.task.add_status_msg(
msg=msg, error=True, ctx=n.name, ctx_type='node')
msg=msg,
error=True,
ctx=n.name,
ctx_type='node')
self.task.failure(focus=n.name)
continue
msg = ("Released failed node %s to retry deployment." % n.name)
msg = ("Released failed node %s to retry deployment." %
n.name)
self.logger.info(msg)
self.task.add_status_msg(
msg=msg, error=False, ctx=n.name, ctx_type='node')

View File

@ -204,10 +204,15 @@ class MaasNodeDriver(NodeDriver):
maas_client=maas_client)
action.start()
except Exception as e:
msg = ("Subtask for action %s raised unexpected exception: %s" % (task.action, str(e)))
msg = (
"Subtask for action %s raised unexpected exception: %s" %
(task.action, str(e)))
self.logger.error(msg, exc_info=e)
task.add_status_msg(
msg, error=True, ctx=str(task.get_id()), ctx_type='task')
msg=msg,
error=True,
ctx=str(task.get_id()),
ctx_type='task')
task.failure()
task.set_status(hd_fields.TaskStatus.Complete)

View File

@ -378,55 +378,67 @@ class VerifyNodes(BaseAction):
target_nodes = self.orchestrator.process_node_filter(
node_filter, site_design)
for n in target_nodes:
if n.oob_type not in oob_type_partition.keys():
oob_type_partition[n.oob_type] = []
if target_nodes:
for n in target_nodes:
if n.oob_type not in oob_type_partition.keys():
oob_type_partition[n.oob_type] = []
oob_type_partition[n.oob_type].append(n)
oob_type_partition[n.oob_type].append(n)
task_futures = dict()
for oob_type, oob_nodes in oob_type_partition.items():
oob_driver = self._get_driver('oob', oob_type)
task_futures = dict()
for oob_type, oob_nodes in oob_type_partition.items():
oob_driver = self._get_driver('oob', oob_type)
if oob_driver is None:
self.logger.warning(
"Node OOB type %s has no enabled driver." % oob_type)
self.task.failure()
for n in oob_nodes:
self.task.add_status_msg(
msg="Node %s OOB type %s is not supported." %
(n.get_name(), oob_type),
error=True,
ctx=n.get_name(),
ctx_type='node')
continue
if oob_driver is None:
self.logger.warning(
"Node OOB type %s has no enabled driver." % oob_type)
self.task.failure()
for n in oob_nodes:
self.task.add_status_msg(
msg="Node %s OOB type %s is not supported." %
(n.get_name(), oob_type),
error=True,
ctx=n.get_name(),
ctx_type='node')
continue
nf = self.orchestrator.create_nodefilter_from_nodelist(oob_nodes)
nf = self.orchestrator.create_nodefilter_from_nodelist(
oob_nodes)
oob_driver_task = self.orchestrator.create_task(
design_ref=self.task.design_ref,
action=hd_fields.OrchestratorAction.InterrogateOob,
node_filter=nf)
self.task.register_subtask(oob_driver_task)
oob_driver_task = self.orchestrator.create_task(
design_ref=self.task.design_ref,
action=hd_fields.OrchestratorAction.InterrogateOob,
node_filter=nf)
self.task.register_subtask(oob_driver_task)
self.logger.info(
"Starting task %s for node verification via OOB type %s" %
(oob_driver_task.get_id(), oob_type))
task_futures.update(
self._parallelize_subtasks(oob_driver.execute_task,
[oob_driver_task.get_id()]))
self.logger.info(
"Starting task %s for node verification via OOB type %s" %
(oob_driver_task.get_id(), oob_type))
task_futures.update(
self._parallelize_subtasks(oob_driver.execute_task,
[oob_driver_task.get_id()]))
try:
self._collect_subtask_futures(
task_futures,
timeout=(config.config_mgr.conf.timeouts.drydock_timeout * 60))
self.logger.debug(
"Collected subtasks for task %s" % str(self.task.get_id()))
except errors.CollectSubtaskTimeout as ex:
self.logger.warning(str(ex))
try:
self._collect_subtask_futures(
task_futures,
timeout=(
config.config_mgr.conf.timeouts.drydock_timeout * 60))
self.logger.debug(
"Collected subtasks for task %s" % str(self.task.get_id()))
except errors.CollectSubtaskTimeout as ex:
self.logger.warning(str(ex))
else:
# no target nodes
self.task.add_status_msg(
msg="No nodes in scope, no work to to do.",
error=False,
ctx='NA',
ctx_type='NA')
self.task.success()
# Set task complete and persist that info.
self.task.set_status(hd_fields.TaskStatus.Complete)
self.task.save()
return
@ -458,6 +470,17 @@ class PrepareNodes(BaseAction):
target_nodes = self.orchestrator.get_target_nodes(self.task)
if not target_nodes:
self.task.add_status_msg(
msg="No nodes in scope, no work to to do.",
error=False,
ctx='NA',
ctx_type='NA')
self.task.success()
self.task.set_status(hd_fields.TaskStatus.Complete)
self.task.save()
return
# Parallelize this task so that node progression is
# not interlinked
if len(target_nodes) > 1:
@ -786,6 +809,19 @@ class DeployNodes(BaseAction):
self.task.save()
return
target_nodes = self.orchestrator.get_target_nodes(self.task)
if not target_nodes:
self.task.add_status_msg(
msg="No nodes in scope, no work to to do.",
error=False,
ctx='NA',
ctx_type='NA')
self.task.success()
self.task.set_status(hd_fields.TaskStatus.Complete)
self.task.save()
return
node_networking_task = self.orchestrator.create_task(
design_ref=self.task.design_ref,
action=hd_fields.OrchestratorAction.ApplyNodeNetworking,

View File

@ -282,8 +282,8 @@ class DrydockState(object):
"""
try:
conn = self.db_engine.connect()
query = self.tasks_tbl.insert().values(
**(task.to_db(include_id=True)))
query = self.tasks_tbl.insert().values(**(
task.to_db(include_id=True)))
conn.execute(query)
conn.close()
return True