diff --git a/changelogs/fragments/reboot-add-last-boot-time-parameter.yaml b/changelogs/fragments/reboot-add-last-boot-time-parameter.yaml new file mode 100644 index 00000000000..829ee1e6df8 --- /dev/null +++ b/changelogs/fragments/reboot-add-last-boot-time-parameter.yaml @@ -0,0 +1,5 @@ +bugfixes: + - >- + reboot, win_reboot - add ``boot_time_command`` parameter to override the default command used to + determine whether or not a system was rebooted + (https://github.com/ansible/ansible/issues/58868) diff --git a/lib/ansible/modules/system/reboot.py b/lib/ansible/modules/system/reboot.py index ef00874e38f..0fab23a6099 100644 --- a/lib/ansible/modules/system/reboot.py +++ b/lib/ansible/modules/system/reboot.py @@ -65,6 +65,14 @@ options: type: list default: ['/sbin', '/usr/sbin', '/usr/local/sbin'] version_added: '2.8' + + boot_time_command: + description: + - Command to run that returns a unique string indicating the last time the system was booted. + - Setting this to a command that has different output each time it is run will cause the task to fail. + type: str + default: 'cat /proc/sys/kernel/random/boot_id' + version_added: '2.10' seealso: - module: win_reboot author: diff --git a/lib/ansible/modules/windows/win_reboot.py b/lib/ansible/modules/windows/win_reboot.py index b252c927b6b..1431804143d 100644 --- a/lib/ansible/modules/windows/win_reboot.py +++ b/lib/ansible/modules/windows/win_reboot.py @@ -61,6 +61,13 @@ options: - Message to display to users. type: str default: Reboot initiated by Ansible + boot_time_command: + description: + - Command to run that returns a unique string indicating the last time the system was booted. + - Setting this to a command that has different output each time it is run will cause the task to fail. + type: str + default: '(Get-WmiObject -ClassName Win32_OperatingSystem).LastBootUpTime' + version_added: '2.10' notes: - If a shutdown was already scheduled on the system, C(win_reboot) will abort the scheduled shutdown and enforce its own shutdown. - Beware that when C(win_reboot) returns, the Windows system may not have settled yet and some base services could be in limbo. diff --git a/lib/ansible/plugins/action/reboot.py b/lib/ansible/plugins/action/reboot.py index 4578997c0e3..1a7ecfcb134 100644 --- a/lib/ansible/plugins/action/reboot.py +++ b/lib/ansible/plugins/action/reboot.py @@ -13,6 +13,7 @@ from datetime import datetime, timedelta from ansible.errors import AnsibleError, AnsibleConnectionFailure from ansible.module_utils._text import to_native, to_text from ansible.module_utils.common.collections import is_string +from ansible.module_utils.common.validation import check_type_str from ansible.plugins.action import ActionBase from ansible.utils.display import Display @@ -25,7 +26,16 @@ class TimedOutException(Exception): class ActionModule(ActionBase): TRANSFERS_FILES = False - _VALID_ARGS = frozenset(('connect_timeout', 'msg', 'post_reboot_delay', 'pre_reboot_delay', 'test_command', 'reboot_timeout', 'search_paths')) + _VALID_ARGS = frozenset(( + 'boot_time_command', + 'connect_timeout', + 'msg', + 'post_reboot_delay', + 'pre_reboot_delay', + 'test_command', + 'reboot_timeout', + 'search_paths' + )) DEFAULT_REBOOT_TIMEOUT = 600 DEFAULT_CONNECT_TIMEOUT = None @@ -178,6 +188,14 @@ class ActionModule(ActionBase): def get_system_boot_time(self, distribution): boot_time_command = self._get_value_from_facts('BOOT_TIME_COMMANDS', distribution, 'DEFAULT_BOOT_TIME_COMMAND') + if self._task.args.get('boot_time_command'): + boot_time_command = self._task.args.get('boot_time_command') + + try: + check_type_str(boot_time_command, allow_conversion=False) + except TypeError as e: + raise AnsibleError("Invalid value given for 'boot_time_command': %s." % to_native(e)) + display.debug("{action}: getting boot time with command: '{command}'".format(action=self._task.action, command=boot_time_command)) command_result = self._low_level_execute_command(boot_time_command, sudoable=self.DEFAULT_SUDOABLE)