summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnnie Lezil <annie.lezil@gmail.com>2016-12-19 11:09:52 -0800
committerAnnie Lezil <annie.lezil@gmail.com>2017-01-20 12:55:12 -0800
commit20dc04e5e2b23f888ff79a3873d35fd4c170c8d8 (patch)
tree36f3cb9d72a1ed47622b4a42a9379ae5cc29f6e5
parent4cf29db7e229a3ca715272b8420f361ff3809c7d (diff)
downloadironic-python-agent-20dc04e5e2b23f888ff79a3873d35fd4c170c8d8.tar.gz
Reboot and Poweroff fails with coreos IPA image
The CoreOS IPA images do not support poweroff/reboot due to running in a chroot. For this case, we fall back to forcing poweroff or reboot via sysrq commands Change-Id: I75d68b6308beba299d043e43a5fa1671b6ef3ada Closes-Bug: #1628367
-rw-r--r--ironic_python_agent/extensions/standby.py10
-rw-r--r--ironic_python_agent/tests/unit/extensions/test_standby.py35
-rw-r--r--releasenotes/notes/coreos_ipa_image_poweroff_reboot_in_chroot_by_sysrq-42447fc4cdd7dafe.yaml5
3 files changed, 46 insertions, 4 deletions
diff --git a/ironic_python_agent/extensions/standby.py b/ironic_python_agent/extensions/standby.py
index 1ba396ea..637e4012 100644
--- a/ironic_python_agent/extensions/standby.py
+++ b/ironic_python_agent/extensions/standby.py
@@ -499,7 +499,15 @@ class StandbyExtension(base.BaseAgentExtension):
except errors.CommandExecutionError as e:
LOG.warning('Failed to sync file system buffers: % s', e)
try:
- utils.execute(command, check_exit_code=[0])
+ _, stderr = utils.execute(command, use_standard_locale=True,
+ check_exit_code=[0])
+ if 'ignoring request.' in stderr:
+ LOG.debug('%s command failed with error %s, '
+ 'falling back to sysrq-trigger.', command, stderr)
+ if command == 'poweroff':
+ utils.execute("echo o > /proc/sysrq-trigger", shell=True)
+ elif command == 'reboot':
+ utils.execute("echo b > /proc/sysrq-trigger", shell=True)
except processutils.ProcessExecutionError as e:
raise errors.SystemRebootError(e.exit_code, e.stdout, e.stderr)
diff --git a/ironic_python_agent/tests/unit/extensions/test_standby.py b/ironic_python_agent/tests/unit/extensions/test_standby.py
index b76dd596..6a98dd31 100644
--- a/ironic_python_agent/tests/unit/extensions/test_standby.py
+++ b/ironic_python_agent/tests/unit/extensions/test_standby.py
@@ -679,7 +679,34 @@ class TestStandbyExtension(test_base.BaseTestCase):
self.agent_extension._run_shutdown_command('poweroff')
calls = [mock.call('sync'),
- mock.call('poweroff', check_exit_code=[0])]
+ mock.call('poweroff', use_standard_locale=True,
+ check_exit_code=[0])]
+ execute_mock.assert_has_calls(calls)
+
+ @mock.patch('ironic_python_agent.utils.execute', autospec=True)
+ def test_run_shutdown_command_valid_poweroff_sysrq(self, execute_mock):
+ execute_mock.side_effect = [('', ''), ('',
+ 'Running in chroot, ignoring request.'),
+ ('', '')]
+
+ self.agent_extension._run_shutdown_command('poweroff')
+ calls = [mock.call('sync'),
+ mock.call('poweroff', use_standard_locale=True,
+ check_exit_code=[0]),
+ mock.call("echo o > /proc/sysrq-trigger", shell=True)]
+ execute_mock.assert_has_calls(calls)
+
+ @mock.patch('ironic_python_agent.utils.execute', autospec=True)
+ def test_run_shutdown_command_valid_reboot_sysrq(self, execute_mock):
+ execute_mock.side_effect = [('', ''), ('',
+ 'Running in chroot, ignoring request.'),
+ ('', '')]
+
+ self.agent_extension._run_shutdown_command('reboot')
+ calls = [mock.call('sync'),
+ mock.call('reboot', use_standard_locale=True,
+ check_exit_code=[0]),
+ mock.call("echo b > /proc/sysrq-trigger", shell=True)]
execute_mock.assert_has_calls(calls)
@mock.patch('ironic_python_agent.utils.execute', autospec=True)
@@ -689,7 +716,8 @@ class TestStandbyExtension(test_base.BaseTestCase):
success_result = self.agent_extension.run_image()
success_result.join()
calls = [mock.call('sync'),
- mock.call('reboot', check_exit_code=[0])]
+ mock.call('reboot', use_standard_locale=True,
+ check_exit_code=[0])]
execute_mock.assert_has_calls(calls)
self.assertEqual('SUCCEEDED', success_result.command_status)
@@ -711,7 +739,8 @@ class TestStandbyExtension(test_base.BaseTestCase):
success_result.join()
calls = [mock.call('sync'),
- mock.call('poweroff', check_exit_code=[0])]
+ mock.call('poweroff', use_standard_locale=True,
+ check_exit_code=[0])]
execute_mock.assert_has_calls(calls)
self.assertEqual('SUCCEEDED', success_result.command_status)
diff --git a/releasenotes/notes/coreos_ipa_image_poweroff_reboot_in_chroot_by_sysrq-42447fc4cdd7dafe.yaml b/releasenotes/notes/coreos_ipa_image_poweroff_reboot_in_chroot_by_sysrq-42447fc4cdd7dafe.yaml
new file mode 100644
index 00000000..0d416f5a
--- /dev/null
+++ b/releasenotes/notes/coreos_ipa_image_poweroff_reboot_in_chroot_by_sysrq-42447fc4cdd7dafe.yaml
@@ -0,0 +1,5 @@
+---
+fixes:
+ - Fixes a bug in the CoreOS IPA images (where IPA runs in a chroot), where
+ IPA could not power off or reboot properly. In this case, it will now use
+ SYSRQ commands to forcefully reboot or power off.