Reboot - Fix command not found, add Apline support, fix Solaris command (#49272)

* Fix various bugs related in reboot

- Use format strings for consistency and improve debug log messages
- Use local variables instead of class attributes in order to be thread safe
- Run setup module to get distribution and version
- Run find module to get full path of shutdown command
- Use ansible_os_family and ansible_distribution to find commands and args
- Use same command for all Solaris/SunOS distributions
- Move delay calculations to properties
- Reliably check for module run failure
- Fix bug in run_test_command() that accidentally made the method work properly
- Use better exceptions rather than Exception
- Use dict literals rather than constructors
- Correct _check_delay() so it always returns a value, not None
- Don't store and return result in run_test_command() because it's not used anywhere
- add test for post reboot command that fails
- test negative values for delay parameters
This commit is contained in:
Sam Doran 2018-12-11 11:05:10 -05:00 committed by GitHub
parent 2a469fd959
commit c1589c33c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 291 additions and 156 deletions

View file

@ -29,33 +29,36 @@ class ActionModule(RebootActionModule, ActionBase):
DEFAULT_BOOT_TIME_COMMAND = "(Get-WmiObject -ClassName Win32_OperatingSystem).LastBootUpTime"
DEFAULT_CONNECT_TIMEOUT = 5
DEFAULT_PRE_REBOOT_DELAY = 2
DEFAULT_SHUTDOWN_COMMAND_ARGS = '/r /t %d /c "%s"'
DEFAULT_SUDOABLE = False
DEFAULT_SHUTDOWN_COMMAND_ARGS = '/r /t {delay_sec} /c "{message}"'
DEPRECATED_ARGS = {
'shutdown_timeout': '2.5',
'shutdown_timeout_sec': '2.5',
}
def construct_command(self):
shutdown_command = self.DEFAULT_SHUTDOWN_COMMAND
pre_reboot_delay = int(self._task.args.get('pre_reboot_delay', self._task.args.get('pre_reboot_delay_sec', self.DEFAULT_PRE_REBOOT_DELAY)))
msg = self._task.args.get('msg', self.DEFAULT_REBOOT_MESSAGE)
shutdown_command_args = self.DEFAULT_SHUTDOWN_COMMAND_ARGS % (pre_reboot_delay, msg)
def __init__(self, *args, **kwargs):
super(ActionModule, self).__init__(*args, **kwargs)
reboot_command = '%s %s' % (shutdown_command, shutdown_command_args)
return reboot_command
def get_distribution(self, task_vars):
return {'name': 'windows', 'version': '', 'family': ''}
def perform_reboot(self):
display.debug("Rebooting server")
def get_shutdown_command(self, task_vars, distribution):
return self.DEFAULT_SHUTDOWN_COMMAND
def perform_reboot(self, task_vars, distribution):
shutdown_command = self.get_shutdown_command(task_vars, distribution)
shutdown_command_args = self.get_shutdown_command_args(distribution)
reboot_command = '{0} {1}'.format(shutdown_command, shutdown_command_args)
display.vvv("{action}: rebooting server...".format(action=self._task.action))
display.debug("{action}: distribution: {dist}".format(action=self._task.action, dist=distribution))
display.debug("{action}: rebooting server with command '{command}'".format(action=self._task.action, command=reboot_command))
remote_command = self.construct_command()
reboot_result = self._low_level_execute_command(remote_command, sudoable=self.DEFAULT_SUDOABLE)
result = {}
reboot_result = self._low_level_execute_command(reboot_command, sudoable=self.DEFAULT_SUDOABLE)
result['start'] = datetime.utcnow()
pre_reboot_delay = int(self._task.args.get('pre_reboot_delay', self._task.args.get('pre_reboot_delay_sec', self.DEFAULT_PRE_REBOOT_DELAY)))
# Test for "A system shutdown has already been scheduled. (1190)" and handle it gracefully
stdout = reboot_result['stdout']
stderr = reboot_result['stderr']
@ -66,7 +69,7 @@ class ActionModule(RebootActionModule, ActionBase):
result1 = self._low_level_execute_command('shutdown /a', sudoable=self.DEFAULT_SUDOABLE)
# Initiate reboot again
result2 = self._low_level_execute_command('shutdown /r /t %d' % pre_reboot_delay, sudoable=self.DEFAULT_SUDOABLE)
result2 = self._low_level_execute_command(reboot_command, sudoable=self.DEFAULT_SUDOABLE)
reboot_result['rc'] = result2['rc']
stdout += result1['stdout'] + result2['stdout']
@ -75,15 +78,10 @@ class ActionModule(RebootActionModule, ActionBase):
if reboot_result['rc'] != 0:
result['failed'] = True
result['rebooted'] = False
result['msg'] = "Shutdown command failed, error was: %s %s" % (to_native(stdout.strip()), to_native(stderr.strip()))
result['msg'] = "Reboot command failed, error was: {stdout} {stderr}".format(
stdout=to_native(stdout.strip()),
stderr=to_native(stderr.strip()))
return result
result['failed'] = False
# Get the original connection_timeout option var so it can be reset after
try:
self._original_connection_timeout = self._connection.get_option('connection_timeout')
except AnsibleError:
display.debug("%s: connect_timeout connection option has not been set" % self._task.action)
return result