summaryrefslogtreecommitdiff
path: root/ironic/conductor
diff options
context:
space:
mode:
authorYuriy Zveryanskyy <yzveryanskyy@mirantis.com>2016-11-15 18:17:55 +0200
committerYuriy Zveryanskyy <yzveryanskyy@mirantis.com>2016-12-23 08:51:54 +0000
commit294f974fe70982624e626ed221715ae13194ef0d (patch)
tree645c6937a46199676bf7d9be8cd7fa37b52c007e /ironic/conductor
parent876db5a61314740dc949c2641131f230f9be6c98 (diff)
downloadironic-294f974fe70982624e626ed221715ae13194ef0d.tar.gz
Add node console notifications
This patch adds node console notifications, event types are: "baremetal.node.console_{set, restore}.{start, end, error}". Developer documentation updated. Change-Id: I3b3ac74607fd6e218fdf0ea3ff30964e527db399 Partial-Bug: #1606520
Diffstat (limited to 'ironic/conductor')
-rw-r--r--ironic/conductor/base_manager.py11
-rw-r--r--ironic/conductor/manager.py27
-rw-r--r--ironic/conductor/notification_utils.py24
3 files changed, 61 insertions, 1 deletions
diff --git a/ironic/conductor/base_manager.py b/ironic/conductor/base_manager.py
index 5d0260937..ccd10ad35 100644
--- a/ironic/conductor/base_manager.py
+++ b/ironic/conductor/base_manager.py
@@ -30,10 +30,12 @@ from ironic.common import hash_ring as hash
from ironic.common.i18n import _, _LC, _LE, _LI, _LW
from ironic.common import rpc
from ironic.common import states
+from ironic.conductor import notification_utils as notify_utils
from ironic.conductor import task_manager
from ironic.conf import CONF
from ironic.db import api as dbapi
from ironic import objects
+from ironic.objects import fields as obj_fields
LOG = log.getLogger(__name__)
@@ -383,12 +385,18 @@ class BaseConductorManager(object):
try:
with task_manager.acquire(context, node_uuid, shared=False,
purpose='start console') as task:
+ notify_utils.emit_console_notification(
+ task, 'console_restore',
+ obj_fields.NotificationStatus.START)
try:
LOG.debug('Trying to start console of node %(node)s',
{'node': node_uuid})
task.driver.console.start_console(task)
LOG.info(_LI('Successfully started console of node '
'%(node)s'), {'node': node_uuid})
+ notify_utils.emit_console_notification(
+ task, 'console_restore',
+ obj_fields.NotificationStatus.END)
except Exception as err:
msg = (_('Failed to start console of node %(node)s '
'while starting the conductor, so changing '
@@ -401,6 +409,9 @@ class BaseConductorManager(object):
task.node.last_error = msg
task.node.console_enabled = False
task.node.save()
+ notify_utils.emit_console_notification(
+ task, 'console_restore',
+ obj_fields.NotificationStatus.ERROR)
except exception.NodeLocked:
LOG.warning(_LW('Node %(node)s is locked while trying to '
'start console on conductor startup'),
diff --git a/ironic/conductor/manager.py b/ironic/conductor/manager.py
index d288de3cb..7bd7b07c9 100644
--- a/ironic/conductor/manager.py
+++ b/ironic/conductor/manager.py
@@ -69,6 +69,7 @@ from ironic.conf import CONF
from ironic.drivers import base as drivers_base
from ironic import objects
from ironic.objects import base as objects_base
+from ironic.objects import fields
MANAGER_TOPIC = 'ironic.conductor_manager'
@@ -1335,7 +1336,10 @@ class ConductorManager(base_manager.BaseConductorManager):
task.driver.deploy.take_over(task)
# NOTE(zhenguo): If console enabled, take over the console session
# as well.
+ console_error = None
if task.node.console_enabled:
+ notify_utils.emit_console_notification(
+ task, 'console_restore', fields.NotificationStatus.START)
try:
task.driver.console.start_console(task)
except Exception as err:
@@ -1347,10 +1351,17 @@ class ConductorManager(base_manager.BaseConductorManager):
# back to False and set node's last error.
task.node.last_error = msg
task.node.console_enabled = False
+ console_error = True
+ else:
+ notify_utils.emit_console_notification(
+ task, 'console_restore', fields.NotificationStatus.END)
# NOTE(lucasagomes): Set the ID of the new conductor managing
# this node
task.node.conductor_affinity = self.conductor.id
task.node.save()
+ if console_error:
+ notify_utils.emit_console_notification(
+ task, 'console_restore', fields.NotificationStatus.ERROR)
@METRICS.timer('ConductorManager._check_cleanwait_timeouts')
@periodics.periodic(spacing=CONF.conductor.check_provision_state_interval)
@@ -1510,12 +1521,20 @@ class ConductorManager(base_manager.BaseConductorManager):
'valid_states': states.DELETE_ALLOWED_STATES})
raise exception.InvalidState(msg)
if node.console_enabled:
+ notify_utils.emit_console_notification(
+ task, 'console_set', fields.NotificationStatus.START)
try:
task.driver.console.stop_console(task)
except Exception as err:
LOG.error(_LE('Failed to stop console while deleting '
'the node %(node)s: %(err)s.'),
{'node': node.uuid, 'err': err})
+ notify_utils.emit_console_notification(
+ task, 'console_set', fields.NotificationStatus.ERROR)
+ else:
+ node.console_enabled = False
+ notify_utils.emit_console_notification(
+ task, 'console_set', fields.NotificationStatus.END)
node.destroy()
LOG.info(_LI('Successfully deleted node %(node)s.'),
{'node': node.uuid})
@@ -1699,6 +1718,8 @@ class ConductorManager(base_manager.BaseConductorManager):
def _set_console_mode(self, task, enabled):
"""Internal method to set console mode on a node."""
node = task.node
+ notify_utils.emit_console_notification(
+ task, 'console_set', fields.NotificationStatus.START)
try:
if enabled:
task.driver.console.start_console(task)
@@ -1715,11 +1736,15 @@ class ConductorManager(base_manager.BaseConductorManager):
'error': e})
node.last_error = msg
LOG.error(msg)
+ node.save()
+ notify_utils.emit_console_notification(
+ task, 'console_set', fields.NotificationStatus.ERROR)
else:
node.console_enabled = enabled
node.last_error = None
- finally:
node.save()
+ notify_utils.emit_console_notification(
+ task, 'console_set', fields.NotificationStatus.END)
@METRICS.timer('ConductorManager.update_port')
@messaging.expected_exceptions(exception.NodeLocked,
diff --git a/ironic/conductor/notification_utils.py b/ironic/conductor/notification_utils.py
index ab75df75e..18fc938f2 100644
--- a/ironic/conductor/notification_utils.py
+++ b/ironic/conductor/notification_utils.py
@@ -152,3 +152,27 @@ def emit_provision_set_notification(task, level, status, prev_state,
prev_target=prev_target,
event=event
)
+
+
+def emit_console_notification(task, action, status):
+ """Helper for conductor sending a set console state notification.
+
+ :param task: a TaskManager instance.
+ :param action: Action string to go in the EventType. Must be either
+ 'console_set' or 'console_restore'.
+ :param status: One of `ironic.objects.fields.NotificationStatus.START`,
+ END or ERROR.
+ """
+ if status == fields.NotificationStatus.ERROR:
+ level = fields.NotificationLevel.ERROR
+ else:
+ level = fields.NotificationLevel.INFO
+
+ _emit_conductor_node_notification(
+ task,
+ node_objects.NodeConsoleNotification,
+ node_objects.NodePayload,
+ action,
+ level,
+ status,
+ )