예제 #1
0
    def _test__do_next_deploy_step_last_step_done(self, mock_execute,
                                                  mock_console,
                                                  console_enabled=False,
                                                  console_error=False):
        # Resume where last_step is the last deploy step that was executed
        driver_internal_info = {'deploy_step_index': 1,
                                'deploy_steps': self.deploy_steps}
        self._start_service()
        node = obj_utils.create_test_node(
            self.context, driver='fake-hardware',
            provision_state=states.DEPLOYWAIT,
            target_provision_state=states.ACTIVE,
            driver_internal_info=driver_internal_info,
            deploy_step=self.deploy_steps[1],
            console_enabled=console_enabled)
        mock_execute.return_value = None
        if console_error:
            mock_console.side_effect = exception.ConsoleError()

        task = task_manager.TaskManager(self.context, node.uuid)
        task.process_event('resume')

        deployments.do_next_deploy_step(task, None, self.service.conductor.id)
        node.refresh()
        # Deploying should be complete without calling additional steps
        self.assertEqual(states.ACTIVE, node.provision_state)
        self.assertEqual(states.NOSTATE, node.target_provision_state)
        self.assertEqual({}, node.deploy_step)
        self.assertNotIn('deploy_step_index', node.driver_internal_info)
        self.assertIsNone(node.driver_internal_info['deploy_steps'])
        self.assertFalse(mock_execute.called)
        if console_enabled:
            mock_console.assert_called_once_with(mock.ANY, task)
        else:
            self.assertFalse(mock_console.called)
예제 #2
0
def _stop_console(node_uuid):
    """Close the serial console for a node

    Kills the console process and deletes the PID file.

    :param node_uuid: the UUID of the node
    :raises: NoConsolePid if no console PID was found
    :raises: ConsoleError if unable to stop the console process
    """

    try:
        console_pid = _get_console_pid(node_uuid)

        os.kill(console_pid, signal.SIGTERM)
    except OSError as exc:
        if exc.errno != errno.ESRCH:
            msg = (_("Could not stop the console for node '%(node)s'. "
                     "Reason: %(err)s.") % {
                         'node': node_uuid,
                         'err': exc
                     })
            raise exception.ConsoleError(message=msg)
        else:
            LOG.warning(
                _LW("Console process for node %s is not running "
                    "but pid file exists."), node_uuid)
    finally:
        ironic_utils.unlink_without_raise(_get_console_pid_file(node_uuid))
예제 #3
0
    def test_start_console_fail_nodir(self, mock_exec):
        mock_exec.side_effect = exception.ConsoleError()

        with task_manager.acquire(self.context, self.node.uuid) as task:
            self.assertRaises(exception.ConsoleError,
                              self.driver.console.start_console, task)
        mock_exec.assert_called_once_with(self.node.uuid, mock.ANY, mock.ANY)
예제 #4
0
    def test_stop_console_fail(self, mock_stop):
        mock_stop.side_effect = iter([exception.ConsoleError()])

        with task_manager.acquire(self.context, self.node.uuid) as task:
            self.assertRaises(exception.ConsoleError,
                              self.driver.console.stop_console, task)

        mock_stop.assert_called_once_with(self.node.uuid)
예제 #5
0
    def test_start_socat_console_fail_nopiddir(self, mock_stop,
                                               mock_dir_exists, mock_popen):
        mock_dir_exists.side_effect = exception.ConsoleError(message='fail')

        self.assertRaises(exception.ConsoleError,
                          console_utils.start_socat_console, self.info['uuid'],
                          self.info['port'], 'ls&')

        mock_stop.assert_called_once_with(self.info['uuid'])
        mock_dir_exists.assert_called_once_with()
        self.assertEqual(0, mock_popen.call_count)
예제 #6
0
    def test_start_shellinabox_console_fail_nopiddir(self, mock_stop,
                                                     mock_dir_exists,
                                                     mock_popen):
        mock_dir_exists.side_effect = exception.ConsoleError(message='fail')
        mock_popen.return_value.poll.return_value = 0

        self.assertRaises(exception.ConsoleError,
                          console_utils.start_shellinabox_console,
                          self.info['uuid'], self.info['port'], 'ls&')

        mock_stop.assert_called_once_with(self.info['uuid'])
        mock_dir_exists.assert_called_once_with()
        self.assertFalse(mock_popen.called)
예제 #7
0
def _stop_console(node_uuid):
    """Close the serial console for a node

    Kills the console process and deletes the PID file.

    :param node_uuid: the UUID of the node
    :raises: NoConsolePid if no console PID was found
    :raises: ConsoleError if unable to stop the console process
    """

    try:
        console_pid = _get_console_pid(node_uuid)

        os.kill(console_pid, signal.SIGTERM)

        # make sure the process gets killed hard if required
        attempt = 0
        max_attempts = CONF.console.kill_timeout // 0.2

        while attempt < max_attempts:
            if psutil.pid_exists(console_pid):
                if attempt == max_attempts - 1:
                    os.kill(console_pid, signal.SIGKILL)
                LOG.debug(
                    "Waiting for the console process with PID %(pid)s "
                    "to exit. Node: %(node)s.", {
                        'pid': console_pid,
                        'node': node_uuid
                    })
                time.sleep(0.2)
                attempt += 1
            else:
                break

    except OSError as exc:
        if exc.errno != errno.ESRCH:
            msg = (_("Could not stop the console for node '%(node)s'. "
                     "Reason: %(err)s.") % {
                         'node': node_uuid,
                         'err': exc
                     })
            raise exception.ConsoleError(message=msg)
        else:
            LOG.warning(
                "Console process for node %s is not running "
                "but pid file exists.", node_uuid)
    finally:
        ironic_utils.unlink_without_raise(_get_console_pid_file(node_uuid))
예제 #8
0
def stop_shellinabox_console(node_uuid):
    """Close the serial console for a node.

    :param node_uuid: the UUID of the node
    :raises: ConsoleError if unable to stop the console process
    """

    try:
        _stop_console(node_uuid)
    except exception.NoConsolePid:
        LOG.warning(_LW("No console pid found for node %s while trying to "
                        "stop shellinabox console."), node_uuid)
    except processutils.ProcessExecutionError as exc:
            msg = (_("Could not stop the console for node '%(node)s'. "
                     "Reason: %(err)s.") % {'node': node_uuid, 'err': exc})
            raise exception.ConsoleError(message=msg)
예제 #9
0
def _ensure_console_pid_dir_exists():
    """Ensure that the console PID directory exists

    Checks that the directory for the console PID file exists
    and if not, creates it.

    :raises: ConsoleError if the directory doesn't exist and cannot be created
    """

    dir = _get_console_pid_dir()
    if not os.path.exists(dir):
        try:
            os.makedirs(dir)
        except OSError as exc:
            msg = (_("Cannot create directory '%(path)s' for console PID file."
                     " Reason: %(reason)s.") % {'path': dir, 'reason': exc})
            LOG.error(msg)
            raise exception.ConsoleError(message=msg)
def stop_ics_console(node_uuid):
    """Close the serial console for a node (ironic console server).

    :param node_uuid: the UUID of the node
    :raises: ConsoleError if unable to disable the console service
    """

    try:
        _send_signal(node_uuid, 'USR2')
    except exception.NoConsolePid:
        LOG.warning(
            _LW("No console pid found for node %s while trying to "
                "disable the console service."), node_uuid)
    except processutils.ProcessExecutionError as exc:
        msg = (_("Could not disable the console service for node "
                 "'%(node)s'. Reason: %(err)s.") % {
                     'node': node_uuid,
                     'err': exc
                 })
        raise exception.ConsoleError(message=msg)
def stop_ics_console_log(node_uuid):
    """Stop console logging of a node with ironic console server.

    :param node_uuid: the UUID of the node
    :raises: ConsoleError if unable to stop the console process
    """

    try:
        _stop_console(node_uuid)
    except exception.NoConsolePid:
        LOG.warning(
            _LW("No console pid found for node %s while trying to "
                "stop the console server."), node_uuid)
    except processutils.ProcessExecutionError as exc:
        msg = (_("Could not stop the console for node '%(node)s'. "
                 "Reason: %(err)s.") % {
                     'node': node_uuid,
                     'err': exc
                 })
        raise exception.ConsoleError(message=msg)
def clear_ics_console_log(node_uuid):
    """Clear the content of a console log (ironic console server).

    :param node_uuid: the uuid for the node.
    :raises: ConsoleError if unable to clear the console log
    """

    try:
        ironic_utils.unlink_without_raise(_get_console_log_file(node_uuid))
        _send_signal(node_uuid, 'HUP')
    except exception.NoConsolePid:
        LOG.warning(
            _LW("No console pid found for node %s while trying to "
                "enable the console service."), node_uuid)
    except processutils.ProcessExecutionError as exc:
        msg = (_("Could not enable the console service for node "
                 "'%(node)s'. Reason: %(err)s.") % {
                     'node': node_uuid,
                     'err': exc
                 })
        raise exception.ConsoleError(message=msg)