You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

127 lines
4.2 KiB

from ansible.module_utils.basic import AnsibleModule
import os
import re
def parse_mkinitcpio_line(type: str, line: str) -> list[str]:
regex = "^" + type + r"=\((.*)\)$"
result = re.search(regex, line)
if result is None:
return None
return list(filter(lambda v: v != "", result.group(1).split(" ")))
def build_mkinitcpio_line(type: str, values: list[str]) -> str:
return type + "=(" + " ".join(values) + ")"
def update_mkinitcpio_line(type: str, desired_state: str, values: list[str], line) -> tuple[str, bool]:
current_values = parse_mkinitcpio_line(type, line)
changed = False
if current_values is not None:
if desired_state == "present":
for value in values:
if value not in current_values:
current_values.append(value)
changed = True
elif desired_state == "absent":
for value in values:
if value in current_values:
current_values.remove(value)
changed = True
else:
raise ValueError("Invalid state: %" % desired_state)
return build_mkinitcpio_line(type, current_values), changed
else:
return None, False
def run_module():
# define available arguments/parameters a user can pass to the module
module_args = dict(
state=dict(default='present', choices=['present', 'absent']),
binaries=dict(type='list'),
files=dict(type='list'),
hooks=dict(type='list'),
path=dict(type='str', default='/etc/mkinitcpio.conf')
)
# seed the result dict in the object
# we primarily care about changed and state
# changed is if this module effectively modified the target
# state will include any data that you want your module to pass back
# for consumption, for example, in a subsequent task
result = dict(
changed=False,
)
# the AnsibleModule object will be our abstraction working with Ansible
# this includes instantiation, a couple of common attr would be the
# args/params passed to the execution, as well as if the module
# supports check mode
module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=True
)
# if the user is working with this module in only check mode we do not
# want to make any changes to the environment, just return the current
# state with no modifications
if module.check_mode:
module.exit_json(**result)
path = module.params['path']
if not os.path.isfile(path):
module.fail_json(msg="The path is invalid: %s does not exist" % path)
state = module.params['state']
binaries = module.params['binaries']
files = module.params['files']
hooks = module.params['hooks']
file = open(path, "r")
lines = file.readlines()
for index, line in enumerate(lines):
if binaries is not None:
updated_line, updated = update_mkinitcpio_line(
"BINARIES", state, binaries, line)
if updated:
result['changed'] = True
if updated_line is not None:
lines[index] = updated_line
if files is not None:
updated_line, updated = update_mkinitcpio_line(
"FILES", state, files, line)
if updated:
result['changed'] = True
if updated_line is not None:
lines[index] = updated_line
if hooks is not None:
updated_line, updated = update_mkinitcpio_line(
"HOOKS", state, hooks, line)
if updated:
result['changed'] = True
if updated_line is not None:
lines[index] = updated_line
if result['changed']:
file = open(path, "w")
file.write("".join(lines))
# manipulate or modify the state as needed (this is going to be the
# part where your module will do what it needs to do)
# in the event of a successful module execution, you will want to
# simple AnsibleModule.exit_json(), passing the key/value results
module.exit_json(**result)
def main():
run_module()
if __name__ == '__main__':
main()