diff --git a/etc/ironic/ironic.conf.sample b/etc/ironic/ironic.conf.sample index 55b72b26e6..096171bbad 100644 --- a/etc/ironic/ironic.conf.sample +++ b/etc/ironic/ironic.conf.sample @@ -1144,6 +1144,12 @@ # the temporary directory will be used. (string value) #terminal_pid_dir = +# Timeout (in seconds) for the terminal session to be closed +# on inactivity. Set to 0 to disable timeout. Used only by +# Socat console. (integer value) +# Minimum value: 0 +#terminal_timeout = 600 + # Time interval (in seconds) for checking the status of # console subprocess. (integer value) #subprocess_checking_interval = 1 diff --git a/ironic/conf/console.py b/ironic/conf/console.py index a6df1b5616..9a9999664d 100644 --- a/ironic/conf/console.py +++ b/ironic/conf/console.py @@ -31,6 +31,12 @@ opts = [ help=_('Directory for holding terminal pid files. ' 'If not specified, the temporary directory ' 'will be used.')), + cfg.IntOpt('terminal_timeout', + default=600, + min=0, + help=_('Timeout (in seconds) for the terminal session to be ' + 'closed on inactivity. Set to 0 to disable timeout. ' + 'Used only by Socat console.')), cfg.IntOpt('subprocess_checking_interval', default=1, help=_('Time interval (in seconds) for checking the status of ' diff --git a/ironic/drivers/modules/console_utils.py b/ironic/drivers/modules/console_utils.py index 07a6b800f6..02c21738c1 100644 --- a/ironic/drivers/modules/console_utils.py +++ b/ironic/drivers/modules/console_utils.py @@ -282,10 +282,11 @@ def start_socat_console(node_uuid, port, console_cmd): # put together the command and arguments for invoking the console args = ['socat'] - # set timeout check for user's connection. After 10min of inactivity - # on client side, connection will be closed. - # TODO(ashestakov) Make timeout value configurable - args.append('-T600') + # set timeout check for user's connection. If the timeout value + # is not 0, after timeout seconds of inactivity on the client side, + # the connection will be closed. + if CONF.console.terminal_timeout > 0: + args.append('-T%d' % CONF.console.terminal_timeout) args.append('-L%s' % pid_file) console_host = CONF.my_ip diff --git a/ironic/tests/unit/drivers/modules/test_console_utils.py b/ironic/tests/unit/drivers/modules/test_console_utils.py index d4e9a13231..1282eab0f3 100644 --- a/ironic/tests/unit/drivers/modules/test_console_utils.py +++ b/ironic/tests/unit/drivers/modules/test_console_utils.py @@ -28,6 +28,7 @@ import tempfile from ironic_lib import utils as ironic_utils import mock from oslo_config import cfg +from oslo_service import loopingcall from oslo_utils import netutils import psutil @@ -401,6 +402,44 @@ class ConsoleUtilsTestCase(db_base.DbTestCase): url = console_utils.get_socat_console_url(self.info['port']) self.assertEqual("tcp://[::1]:%s" % self.info['port'], url) + @mock.patch.object(subprocess, 'Popen', autospec=True) + @mock.patch.object(console_utils, '_get_console_pid_file', autospec=True) + @mock.patch.object(console_utils, '_ensure_console_pid_dir_exists', + autospec=True) + @mock.patch.object(console_utils, '_stop_console', autospec=True) + @mock.patch.object(loopingcall.FixedIntervalLoopingCall, 'start', + autospec=True) + def _test_start_socat_console_check_arg(self, mock_timer_start, + mock_stop, mock_dir_exists, + mock_get_pid, mock_popen): + mock_timer_start.return_value = mock.Mock() + mock_get_pid.return_value = '/tmp/%s.pid' % self.info['uuid'] + + 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() + mock_get_pid.assert_called_once_with(self.info['uuid']) + mock_timer_start.assert_called_once_with(mock.ANY, interval=mock.ANY) + mock_popen.assert_called_once_with(mock.ANY, stderr=subprocess.PIPE) + return mock_popen.call_args[0][0] + + def test_start_socat_console_check_arg_default_timeout(self): + args = self._test_start_socat_console_check_arg() + self.assertIn('-T600', args) + + def test_start_socat_console_check_arg_timeout(self): + self.config(terminal_timeout=1, group='console') + args = self._test_start_socat_console_check_arg() + self.assertIn('-T1', args) + + def test_start_socat_console_check_arg_timeout_disabled(self): + self.config(terminal_timeout=0, group='console') + args = self._test_start_socat_console_check_arg() + self.assertNotIn('-T0', args) + @mock.patch.object(os.path, 'exists', autospec=True) @mock.patch.object(subprocess, 'Popen', autospec=True) @mock.patch.object(psutil, 'pid_exists', autospec=True) diff --git a/releasenotes/notes/make-terminal-session-timeout-configurable-b2365b7699b0f98b.yaml b/releasenotes/notes/make-terminal-session-timeout-configurable-b2365b7699b0f98b.yaml new file mode 100644 index 0000000000..ad29f8de74 --- /dev/null +++ b/releasenotes/notes/make-terminal-session-timeout-configurable-b2365b7699b0f98b.yaml @@ -0,0 +1,7 @@ +--- +other: + - | + Adds configuration parameter ``terminal_timeout`` to section [console] + to allow operators to set the timeout value for the Socat console session. + It is time of client inactivity, in seconds, after which the connection + will be closed. \ No newline at end of file