Implement #9650 Add parameter hooks to inventory plugin iocage (#9651)

* Add parameter hooks to inventory plugin iocage.

* Add changelog fragment.

* Update plugins/inventory/iocage.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Parameter renamed to hooks_results

* Fix DOCUMENTATION YAML 4-space indentation.

* Fix DOCUMENTATION YAML 2-space indentation.

* Update changelogs/fragments/9651-iocage-inventory-hooks.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Add note about activated pool mountpoint.

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
pull/9733/head
Vladimir Botka 2025-02-11 18:05:27 +01:00 committed by GitHub
parent 7af5e158b8
commit fdd1331e4a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 149 additions and 76 deletions

View File

@ -0,0 +1,2 @@
minor_changes:
- iocage inventory plugin - the new parameter ``hooks_results`` of the plugin is a list of files inside a jail that provide configuration parameters for the inventory. The inventory plugin reads the files from the jails and put the contents into the items of created variable ``iocage_hooks`` (https://github.com/ansible-collections/community.general/issues/9650, https://github.com/ansible-collections/community.general/pull/9651).

View File

@ -6,85 +6,99 @@
from __future__ import annotations from __future__ import annotations
DOCUMENTATION = ''' DOCUMENTATION = r'''
name: iocage name: iocage
short_description: iocage inventory source short_description: iocage inventory source
version_added: 10.2.0 version_added: 10.2.0
author: author:
- Vladimir Botka (@vbotka) - Vladimir Botka (@vbotka)
requirements: requirements:
- iocage >= 1.8 - iocage >= 1.8
description:
- Get inventory hosts from the iocage jail manager running on O(host).
- By default, O(host) is V(localhost). If O(host) is not V(localhost) it
is expected that the user running Ansible on the controller can
connect to the O(host) account O(user) with SSH non-interactively and
execute the command C(iocage list).
- Uses a configuration file as an inventory source, it must end
in C(.iocage.yml) or C(.iocage.yaml).
extends_documentation_fragment:
- ansible.builtin.constructed
- ansible.builtin.inventory_cache
options:
plugin:
description: description:
- Get inventory hosts from the iocage jail manager running on O(host). - The name of this plugin, it should always be set to
- By default, O(host) is V(localhost). If O(host) is not V(localhost) it V(community.general.iocage) for this plugin to recognize
is expected that the user running Ansible on the controller can it as its own.
connect to the O(host) account O(user) with SSH non-interactively and required: true
execute the command C(iocage list). choices: ['community.general.iocage']
- Uses a configuration file as an inventory source, it must end type: str
in C(.iocage.yml) or C(.iocage.yaml). host:
extends_documentation_fragment: description: The IP/hostname of the C(iocage) host.
- ansible.builtin.constructed type: str
- ansible.builtin.inventory_cache default: localhost
options: user:
plugin: description:
description: - C(iocage) user.
- The name of this plugin, it should always be set to It is expected that the O(user) is able to connect to the
V(community.general.iocage) for this plugin to recognize O(host) with SSH and execute the command C(iocage list).
it as its own. This option is not required if O(host) is V(localhost).
required: true type: str
choices: ['community.general.iocage'] sudo:
type: str description:
host: - Enable execution as root.
description: The IP/hostname of the C(iocage) host. - This requires passwordless sudo of the command C(iocage list*).
type: str type: bool
default: localhost default: false
user: version_added: 10.3.0
description: sudo_preserve_env:
- C(iocage) user. description:
It is expected that the O(user) is able to connect to the - Preserve environment if O(sudo) is enabled.
O(host) with SSH and execute the command C(iocage list). - This requires C(SETENV) sudoers tag.
This option is not required if O(host) is V(localhost). type: bool
type: str default: false
sudo: version_added: 10.3.0
description: get_properties:
- Enable execution as root. description:
- This requires passwordless sudo of the command C(iocage list*). - Get jails' properties.
type: bool Creates dictionary C(iocage_properties) for each added host.
default: false type: bool
version_added: 10.3.0 default: false
sudo_preserve_env: env:
description: description:
- Preserve environment if O(sudo) is enabled. - O(user)'s environment on O(host).
- This requires C(SETENV) sudoers tag. - Enable O(sudo_preserve_env) if O(sudo) is enabled.
type: bool type: dict
default: false default: {}
version_added: 10.3.0 hooks_results:
get_properties: description:
description: - List of paths to the files in a jail.
- Get jails' properties. - Content of the files is stored in the items of the list C(iocage_hooks).
Creates dictionary C(iocage_properties) for each added host. - If a file is not available the item keeps the dash character C(-).
type: bool - The variable C(iocage_hooks) is not created if O(hooks_results) is empty.
default: false type: list
env: elements: path
description: version_added: 10.4.0
- O(user)'s environment on O(host). notes:
- Enable O(sudo_preserve_env) if O(sudo) is enabled. - You might want to test the command C(ssh user@host iocage list -l) on
type: dict the controller before using this inventory plugin with O(user) specified
default: {} and with O(host) other than V(localhost).
notes: - If you run this inventory plugin on V(localhost) C(ssh) is not used.
- You might want to test the command C(ssh user@host iocage list -l) on In this case, test the command C(iocage list -l).
the controller before using this inventory plugin with O(user) specified - This inventory plugin creates variables C(iocage_*) for each added host.
and with O(host) other than V(localhost). - The values of these variables are collected from the output of the
- If you run this inventory plugin on V(localhost) C(ssh) is not used. command C(iocage list -l).
In this case, test the command C(iocage list -l). - The names of these variables correspond to the output columns.
- This inventory plugin creates variables C(iocage_*) for each added host. - The column C(NAME) is used to name the added host.
- The values of these variables are collected from the output of the - The option O(hooks_results) expects the C(poolname) of a jail is mounted to
command C(iocage list -l). C(/poolname). For example, if you activate the pool C(iocage) this plugin
- The names of these variables correspond to the output columns. expects to find the O(hooks_results) items in the path
- The column C(NAME) is used to name the added host. C(/iocage/iocage/jails/<name>/root). If you mount the C(poolname) to a
different path the easiest remedy is to create a symlink.
''' '''
EXAMPLES = ''' EXAMPLES = r'''
--- ---
# file name must end with iocage.yaml or iocage.yml # file name must end with iocage.yaml or iocage.yml
plugin: community.general.iocage plugin: community.general.iocage
@ -142,6 +156,18 @@ keyed_groups:
key: iocage_release key: iocage_release
- prefix: state - prefix: state
key: iocage_state key: iocage_state
---
# Read the file /var/db/dhclient-hook.address.epair0b in the jails and use it as ansible_host
plugin: community.general.iocage
host: 10.1.0.73
user: admin
hooks_results:
- /var/db/dhclient-hook.address.epair0b
compose:
ansible_host: iocage_hooks.0
groups:
test: inventory_hostname.startswith('test')
''' '''
import re import re
@ -226,6 +252,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
sudo_preserve_env = self.get_option('sudo_preserve_env') sudo_preserve_env = self.get_option('sudo_preserve_env')
env = self.get_option('env') env = self.get_option('env')
get_properties = self.get_option('get_properties') get_properties = self.get_option('get_properties')
hooks_results = self.get_option('hooks_results')
cmd = [] cmd = []
my_env = os.environ.copy() my_env = os.environ.copy()
@ -286,6 +313,50 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
self.get_properties(t_stdout, results, hostname) self.get_properties(t_stdout, results, hostname)
if hooks_results:
cmd_get_pool = cmd.copy()
cmd_get_pool.append(self.IOCAGE)
cmd_get_pool.append('get')
cmd_get_pool.append('--pool')
try:
p = Popen(cmd_get_pool, stdout=PIPE, stderr=PIPE, env=my_env)
stdout, stderr = p.communicate()
if p.returncode != 0:
raise AnsibleError(
f'Failed to run cmd={cmd_get_pool}, rc={p.returncode}, stderr={to_native(stderr)}')
try:
iocage_pool = to_text(stdout, errors='surrogate_or_strict').strip()
except UnicodeError as e:
raise AnsibleError(f'Invalid (non unicode) input returned: {e}') from e
except Exception as e:
raise AnsibleError(f'Failed to get pool: {e}') from e
for hostname, host_vars in results['_meta']['hostvars'].items():
iocage_hooks = []
for hook in hooks_results:
path = "/" + iocage_pool + "/iocage/jails/" + hostname + "/root" + hook
cmd_cat_hook = cmd.copy()
cmd_cat_hook.append('cat')
cmd_cat_hook.append(path)
try:
p = Popen(cmd_cat_hook, stdout=PIPE, stderr=PIPE, env=my_env)
stdout, stderr = p.communicate()
if p.returncode != 0:
iocage_hooks.append('-')
continue
try:
iocage_hook = to_text(stdout, errors='surrogate_or_strict').strip()
except UnicodeError as e:
raise AnsibleError(f'Invalid (non unicode) input returned: {e}') from e
except Exception:
iocage_hooks.append('-')
else:
iocage_hooks.append(iocage_hook)
results['_meta']['hostvars'][hostname]['iocage_hooks'] = iocage_hooks
return results return results
def get_jails(self, t_stdout, results): def get_jails(self, t_stdout, results):