Reboot - add parameter for paths to search for shutdown command (#51194)

* Look in /lib/molly-guard for shutdown command

Signed-off-by: Sam Doran <sdoran@redhat.com>

* Add parameter for extra_search_paths

Signed-off-by: Sam Doran <sdoran@redhat.com>

* Change option to search_paths

- Update docs
- Make the parameter replace the default values
- Add some sanity checking on the data type

Signed-off-by: Sam Doran <sdoran@redhat.com>

* Correct parameter in tests, change conditional for molly-guard tasks

Signed-off-by: Sam Doran <sdoran@redhat.com>

* Address feedback

* Simplify field validation

Needed the try except in case a non-iterable type is put in the search_paths field
This commit is contained in:
Sam Doran 2019-02-28 16:36:33 -05:00 committed by Matt Davis
parent 4e6c113bf0
commit 1c87ea6fa6
4 changed files with 61 additions and 4 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- 'reboot - add parameter for specifying paths to search for the ``shutdown`` command (https://github.com/ansible/ansible/issues/51190)'

View file

@ -13,6 +13,9 @@ ANSIBLE_METADATA = {'metadata_version': '1.1',
DOCUMENTATION = r'''
module: reboot
short_description: Reboot a machine
notes:
- C(PATH) is ignored on the remote node when searching for the C(shutdown) command. Use C(search_paths)
to specify locations to search if the default paths do not work.
description:
- Reboot a machine, wait for it to go down, come back up, and respond to commands.
- For Windows targets, use the M(win_reboot) module instead.
@ -54,6 +57,14 @@ options:
- Message to display to users before reboot.
type: str
default: Reboot initiated by Ansible
search_paths:
description:
- Paths to search on the remote machine for the C(shutdown) command.
- I(Only) these paths will be searched for the C(shutdown) command. C(PATH) is ignored in the remote node when searching for the C(shutdown) command.
type: list
default: ['/sbin', '/usr/sbin', '/usr/local/sbin']
version_added: '2.8'
seealso:
- module: win_reboot
author:

View file

@ -12,6 +12,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.plugins.action import ActionBase
from ansible.utils.display import Display
@ -24,7 +25,7 @@ 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'))
_VALID_ARGS = frozenset(('connect_timeout', 'msg', 'post_reboot_delay', 'pre_reboot_delay', 'test_command', 'reboot_timeout', 'search_paths'))
DEFAULT_REBOOT_TIMEOUT = 600
DEFAULT_CONNECT_TIMEOUT = None
@ -130,13 +131,32 @@ class ActionModule(ActionBase):
def get_shutdown_command(self, task_vars, distribution):
shutdown_bin = self._get_value_from_facts('SHUTDOWN_COMMANDS', distribution, 'DEFAULT_SHUTDOWN_COMMAND')
default_search_paths = ['/sbin', '/usr/sbin', '/usr/local/sbin']
search_paths = self._task.args.get('search_paths', default_search_paths)
display.debug('{action}: running find module to get path for "{command}"'.format(action=self._task.action, command=shutdown_bin))
# FIXME: switch all this to user arg spec validation methods when they are available
# Convert bare strings to a list
if is_string(search_paths):
search_paths = [search_paths]
# Error if we didn't get a list
err_msg = "'search_paths' must be a string or flat list of strings, got {0}"
try:
incorrect_type = any(not is_string(x) for x in search_paths)
except TypeError as te:
raise AnsibleError(err_msg.format(search_paths))
if not isinstance(search_paths, list) or incorrect_type:
raise AnsibleError(err_msg.format(search_paths))
display.debug('{action}: running find module looking in {paths} to get path for "{command}"'.format(
action=self._task.action,
command=shutdown_bin,
paths=search_paths))
find_result = self._execute_module(
task_vars=task_vars,
module_name='find',
module_args={
'paths': ['/sbin', '/usr/sbin', '/usr/local/sbin'],
'paths': search_paths,
'patterns': [shutdown_bin],
'file_type': 'any'
}
@ -144,7 +164,7 @@ class ActionModule(ActionBase):
full_path = [x['path'] for x in find_result['files']]
if not full_path:
raise AnsibleError('Unable to find command "{0}" in system paths.'.format(shutdown_bin))
raise AnsibleError('Unable to find command "{0}" in search paths: {1}'.format(shutdown_bin, search_paths))
self._shutdown_command = full_path[0]
return self._shutdown_command

View file

@ -37,11 +37,13 @@
- name: Reboot with all options
reboot:
connect_timeout: 30
search_paths: /usr/local/bin
msg: Rebooting
post_reboot_delay: 1
pre_reboot_delay: 61
test_command: uptime
reboot_timeout: 500
register: reboot_result
- import_tasks: check_reboot.yml
@ -51,6 +53,7 @@
reboot:
post_reboot_delay: -0.5
pre_reboot_delay: -61
register: reboot_result
- import_tasks: check_reboot.yml
@ -75,6 +78,27 @@
vars:
timeout: "{{ timeout_value[ansible_facts['distribution'] | lower] | default(60) }}"
- name: Test molly-guard
block:
- import_tasks: get_boot_time.yml
- name: Install molly-guard
apt:
update_cache: yes
name: molly-guard
state: present
- name: Reboot when molly-guard is installed
reboot:
search_paths: /lib/molly-guard
register: reboot_result
- import_tasks: check_reboot.yml
when: ansible_facts.distribution in ['Debian', 'Ubuntu']
tags:
- molly-guard
always:
- name: Cleanup temp file
file: