diff --git a/plugins/module_utils/module.py b/plugins/module_utils/module.py index 4db5ace..44cac13 100644 --- a/plugins/module_utils/module.py +++ b/plugins/module_utils/module.py @@ -1,14 +1,12 @@ import pathlib -from typing import (Any, Callable, ClassVar, Dict, NoReturn, Optional, TypeVar, - overload) +from typing import Any, Callable, ClassVar, Dict, NoReturn, Optional, Type, TypeVar, overload import ansible.module_utils.basic as basic try: - from ansible_collections.sebastian.systemd.plugins.module_utils.generic import \ - _sdict + from ansible_collections.sebastian.systemd.plugins.module_utils.generic import Types, _sdict except ImportError: - from plugins.module_utils.generic import _sdict + from plugins.module_utils.generic import Types, _sdict __all__ = ( "AnsibleModule", @@ -183,6 +181,21 @@ class SystemdUnitModule(AnsibleModule): _common_args = dict( supports_check_mode=True, add_file_common_args=True, + argument_spec=dict( + description=Types.str(help="An description for programs that access systemd"), + documentation=Types.list(str, help="Paths where documentation can be found"), + requires=Types.list( + str, + help="list of units that this unit requires. If it fails or can't be started this unit fails. without before/after this is started at the same time", + ), + wants=Types.list(str, help="list of units that this unit wants. If it fails or can't be started it does not affect this unit"), + partof=Types.list( + str, + help="list of units that this unit is part of.\nIf the restart this unit does it too, but if this restarts it does not affect the other units.", + ), + before=Types.list(str, help="list of units that this unit needs to be started before this unit."), + after=Types.list(str, help="list of units that this unit wants to be started after this unit"), + ), ) #: if defined it will be called after run has changed the unitfile post: Optional[Callable[[], None]] @@ -190,6 +203,24 @@ class SystemdUnitModule(AnsibleModule): def unit(self) -> str: raise NotImplementedError() + def header(self) -> str: + header = "[Unit]\n" + if self.get("description", False): + header += "Description={}\n".format(self.get("description")) + if self.get("documentation", False): + header += "Documentation={}\n".format(" ".join(self.get("documentation"))) + if self.get("requires", False): + header += "Requires={}\n".format(" ".join(self.get("requires"))) + if self.get("wants", False): + header += "Wants={}\n".format(" ".join(self.get("wants"))) + if self.get("partof", False): + header += "PartOf={}\n".format(" ".join(self.get("partof"))) + if self.get("before", False): + header += "Before={}\n".format(" ".join(self.get("before"))) + if self.get("after", False): + header += "After={}\n".format(" ".join(self.get("after"))) + return header + def unitfile_gen(self): path = self.tmpdir / "newunit" with open(path, "w") as unit: @@ -251,3 +282,32 @@ class SystemdUnitModule(AnsibleModule): ) if hasattr(self, "post") and self.post is not None: self.post() + + +_INSTALL_MAPPING = dict( + required_by="RequiredBy", + wanted_by="WantedBy", +) + + +def installable(_class: Type[SystemdUnitModule]): + """adds the required arguments to the spec and adds the install method for the unit method""" + arguments = dict( + required_by=Types.list(elements=str, help="systemd units that require this mount"), + wanted_by=Types.list( + elements=str, + help="systemd units that want the mount, but not explicitly require it. Commonly used for target if not service explicitly require it.", + ), + ) + _class.module_spec["argument_spec"].update(arguments) + + def install(self: SystemdUnitModule) -> str: + output = "[Install]\n" + for argument, key in _INSTALL_MAPPING.items(): + if self.get(argument, False): + for unit in self.get(argument): + output += "{}={}\n".format(key, unit) + return output + + _class.install = install + return _class