mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
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:
parent
4e6c113bf0
commit
1c87ea6fa6
4 changed files with 61 additions and 4 deletions
|
@ -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)'
|
|
@ -13,6 +13,9 @@ ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||||
DOCUMENTATION = r'''
|
DOCUMENTATION = r'''
|
||||||
module: reboot
|
module: reboot
|
||||||
short_description: Reboot a machine
|
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:
|
description:
|
||||||
- Reboot a machine, wait for it to go down, come back up, and respond to commands.
|
- 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.
|
- For Windows targets, use the M(win_reboot) module instead.
|
||||||
|
@ -54,6 +57,14 @@ options:
|
||||||
- Message to display to users before reboot.
|
- Message to display to users before reboot.
|
||||||
type: str
|
type: str
|
||||||
default: Reboot initiated by Ansible
|
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:
|
seealso:
|
||||||
- module: win_reboot
|
- module: win_reboot
|
||||||
author:
|
author:
|
||||||
|
|
|
@ -12,6 +12,7 @@ from datetime import datetime, timedelta
|
||||||
|
|
||||||
from ansible.errors import AnsibleError, AnsibleConnectionFailure
|
from ansible.errors import AnsibleError, AnsibleConnectionFailure
|
||||||
from ansible.module_utils._text import to_native, to_text
|
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.plugins.action import ActionBase
|
||||||
from ansible.utils.display import Display
|
from ansible.utils.display import Display
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ class TimedOutException(Exception):
|
||||||
|
|
||||||
class ActionModule(ActionBase):
|
class ActionModule(ActionBase):
|
||||||
TRANSFERS_FILES = False
|
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_REBOOT_TIMEOUT = 600
|
||||||
DEFAULT_CONNECT_TIMEOUT = None
|
DEFAULT_CONNECT_TIMEOUT = None
|
||||||
|
@ -130,13 +131,32 @@ class ActionModule(ActionBase):
|
||||||
|
|
||||||
def get_shutdown_command(self, task_vars, distribution):
|
def get_shutdown_command(self, task_vars, distribution):
|
||||||
shutdown_bin = self._get_value_from_facts('SHUTDOWN_COMMANDS', distribution, 'DEFAULT_SHUTDOWN_COMMAND')
|
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(
|
find_result = self._execute_module(
|
||||||
task_vars=task_vars,
|
task_vars=task_vars,
|
||||||
module_name='find',
|
module_name='find',
|
||||||
module_args={
|
module_args={
|
||||||
'paths': ['/sbin', '/usr/sbin', '/usr/local/sbin'],
|
'paths': search_paths,
|
||||||
'patterns': [shutdown_bin],
|
'patterns': [shutdown_bin],
|
||||||
'file_type': 'any'
|
'file_type': 'any'
|
||||||
}
|
}
|
||||||
|
@ -144,7 +164,7 @@ class ActionModule(ActionBase):
|
||||||
|
|
||||||
full_path = [x['path'] for x in find_result['files']]
|
full_path = [x['path'] for x in find_result['files']]
|
||||||
if not full_path:
|
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]
|
self._shutdown_command = full_path[0]
|
||||||
return self._shutdown_command
|
return self._shutdown_command
|
||||||
|
|
||||||
|
|
|
@ -37,11 +37,13 @@
|
||||||
- name: Reboot with all options
|
- name: Reboot with all options
|
||||||
reboot:
|
reboot:
|
||||||
connect_timeout: 30
|
connect_timeout: 30
|
||||||
|
search_paths: /usr/local/bin
|
||||||
msg: Rebooting
|
msg: Rebooting
|
||||||
post_reboot_delay: 1
|
post_reboot_delay: 1
|
||||||
pre_reboot_delay: 61
|
pre_reboot_delay: 61
|
||||||
test_command: uptime
|
test_command: uptime
|
||||||
reboot_timeout: 500
|
reboot_timeout: 500
|
||||||
|
register: reboot_result
|
||||||
|
|
||||||
- import_tasks: check_reboot.yml
|
- import_tasks: check_reboot.yml
|
||||||
|
|
||||||
|
@ -51,6 +53,7 @@
|
||||||
reboot:
|
reboot:
|
||||||
post_reboot_delay: -0.5
|
post_reboot_delay: -0.5
|
||||||
pre_reboot_delay: -61
|
pre_reboot_delay: -61
|
||||||
|
register: reboot_result
|
||||||
|
|
||||||
- import_tasks: check_reboot.yml
|
- import_tasks: check_reboot.yml
|
||||||
|
|
||||||
|
@ -75,6 +78,27 @@
|
||||||
vars:
|
vars:
|
||||||
timeout: "{{ timeout_value[ansible_facts['distribution'] | lower] | default(60) }}"
|
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:
|
always:
|
||||||
- name: Cleanup temp file
|
- name: Cleanup temp file
|
||||||
file:
|
file:
|
||||||
|
|
Loading…
Reference in a new issue