diff --git a/pyinfra/facts/crontab.py b/pyinfra/facts/crontab.py index 9a6ad93a9..0e8922657 100644 --- a/pyinfra/facts/crontab.py +++ b/pyinfra/facts/crontab.py @@ -24,9 +24,14 @@ class CrontabDict(TypedDict): class CrontabFile: commands: List[CrontabDict] - def __init__(self): + def __init__(self, input: dict[str, CrontabDict] | None = None): super().__init__() self.commands = [] + if input: + for command, others in input.items(): + val = others.copy() + val['command'] = command + self.add_item(val) def add_item(self, item: CrontabDict): self.commands.append(item) @@ -34,13 +39,16 @@ def add_item(self, item: CrontabDict): def __len__(self): return len(self.commands) + def __bool__(self): + return len(self) > 0 + def items(self): return { item.get("command") or item.get('env'): item for item in self.commands } def get_command( - self, command: Optional[str] = None, name: Optional[str] = None + self, command: Optional[str] = None, name: Optional[str] = None ) -> Optional[CrontabDict]: assert command or name, "Either command or name must be provided" diff --git a/pyinfra/operations/crontab.py b/pyinfra/operations/crontab.py index 908043d32..102527f2f 100644 --- a/pyinfra/operations/crontab.py +++ b/pyinfra/operations/crontab.py @@ -5,10 +5,7 @@ from pyinfra import host from pyinfra.api import StringCommand, operation from pyinfra.api.util import try_int -from pyinfra.facts.crontab import CrontabFile -from pyinfra.facts.server import ( - Crontab, -) +from pyinfra.facts.crontab import CrontabFile, Crontab from pyinfra.operations.util.files import sed_replace @@ -77,24 +74,21 @@ def comma_sep(value): day_of_week = comma_sep(day_of_week) day_of_month = comma_sep(day_of_month) - crontab: CrontabFile = host.get_fact(Crontab, user=user) + ctb0: CrontabFile | dict = host.get_fact(Crontab, user=user) + # facts from test are in dict + if isinstance(ctb0, dict): + ctb = CrontabFile(ctb0) + else: + ctb = ctb0 name_comment = "# pyinfra-name={0}".format(cron_name) - existing_crontab = crontab.get_command(command) - existing_crontab_command = command - existing_crontab_match = command - - if not existing_crontab and cron_name: # find the crontab by name if provided - for cmd in crontab.commands: - if not cmd["comments"]: - continue - if name_comment in cmd["comments"]: - existing_crontab = cmd - existing_crontab_match = cmd["command"] - existing_crontab_command = cmd["command"] + existing_crontab = ctb.get_command(command=command, name=cron_name) + existing_crontab_command = existing_crontab['command'] if existing_crontab else command + existing_crontab_match = existing_crontab['command'] if existing_crontab else command + print('existing_crontab', existing_crontab) exists = existing_crontab is not None - exists_name = existing_crontab is not None and name_comment in existing_crontab["comments"] + exists_name = existing_crontab is not None and name_comment in existing_crontab.get("comments", '') edit_commands: list[str | StringCommand] = [] temp_filename = host.get_temp_filename() @@ -126,7 +120,8 @@ def comma_sep(value): # Want the cron but it doesn't exist? Append the line elif present and not exists: - if crontab: # append a blank line if cron entries already exist + print('present', present, 'exists', exists) + if ctb: # append a blank line if cron entries already exist edit_commands.append("echo '' >> {0}".format(temp_filename)) if cron_name: edit_commands.append( @@ -175,7 +170,7 @@ def comma_sep(value): crontab_args.append("-u {0}".format(user)) # List the crontab into a temporary file if it exists - if crontab: + if ctb: yield "crontab -l {0} > {1}".format(" ".join(crontab_args), temp_filename) # Now yield any edits diff --git a/tests/facts/server.Crontab/comments.json b/tests/facts/crontab.Crontab/comments.json similarity index 100% rename from tests/facts/server.Crontab/comments.json rename to tests/facts/crontab.Crontab/comments.json diff --git a/tests/facts/server.Crontab/simple.json b/tests/facts/crontab.Crontab/simple.json similarity index 100% rename from tests/facts/server.Crontab/simple.json rename to tests/facts/crontab.Crontab/simple.json diff --git a/tests/facts/server.Crontab/simple_user.json b/tests/facts/crontab.Crontab/simple_user.json similarity index 100% rename from tests/facts/server.Crontab/simple_user.json rename to tests/facts/crontab.Crontab/simple_user.json diff --git a/tests/operations/server.crontab/add.json b/tests/operations/crontab.crontab/add.json similarity index 88% rename from tests/operations/server.crontab/add.json rename to tests/operations/crontab.crontab/add.json index 53557f975..b9e66d2c8 100644 --- a/tests/operations/server.crontab/add.json +++ b/tests/operations/crontab.crontab/add.json @@ -1,7 +1,7 @@ { "args": ["this_is_a_command"], "facts": { - "server.Crontab": { + "crontab.Crontab": { "user=None": {} } }, diff --git a/tests/operations/server.crontab/add_another.json b/tests/operations/crontab.crontab/add_another.json similarity index 83% rename from tests/operations/server.crontab/add_another.json rename to tests/operations/crontab.crontab/add_another.json index 7a2bb333e..057a18508 100644 --- a/tests/operations/server.crontab/add_another.json +++ b/tests/operations/crontab.crontab/add_another.json @@ -1,7 +1,7 @@ { "args": ["this_is_a_command"], "facts": { - "server.Crontab": { + "crontab.Crontab": { "user=None": { "this_is_another_command": {} } @@ -9,6 +9,7 @@ }, "commands": [ "crontab -l > _tempfile_", + "echo '' >> _tempfile_", "echo '* * * * * this_is_a_command' >> _tempfile_", "crontab _tempfile_" ] diff --git a/tests/operations/server.crontab/add_existing.json b/tests/operations/crontab.crontab/add_existing.json similarity index 93% rename from tests/operations/server.crontab/add_existing.json rename to tests/operations/crontab.crontab/add_existing.json index b16782eef..831b5771d 100644 --- a/tests/operations/server.crontab/add_existing.json +++ b/tests/operations/crontab.crontab/add_existing.json @@ -1,7 +1,7 @@ { "args": ["this_is_a_command"], "facts": { - "server.Crontab": { + "crontab.Crontab": { "user=None": { "this_is_a_command": { "minute": "*", diff --git a/tests/operations/server.crontab/add_named.json b/tests/operations/crontab.crontab/add_named.json similarity index 95% rename from tests/operations/server.crontab/add_named.json rename to tests/operations/crontab.crontab/add_named.json index c6389166b..f559f1986 100644 --- a/tests/operations/server.crontab/add_named.json +++ b/tests/operations/crontab.crontab/add_named.json @@ -4,7 +4,7 @@ "cron_name": "a-name" }, "facts": { - "server.Crontab": { + "crontab.Crontab": { "user=None": { "apt update": { "minute": "*", diff --git a/tests/operations/server.crontab/add_special_time.json b/tests/operations/crontab.crontab/add_special_time.json similarity index 90% rename from tests/operations/server.crontab/add_special_time.json rename to tests/operations/crontab.crontab/add_special_time.json index ebdf38955..276d30fa8 100644 --- a/tests/operations/server.crontab/add_special_time.json +++ b/tests/operations/crontab.crontab/add_special_time.json @@ -4,7 +4,7 @@ "special_time": "@reboot" }, "facts": { - "server.Crontab": { + "crontab.Crontab": { "user=None": {} } }, diff --git a/tests/operations/server.crontab/add_user.json b/tests/operations/crontab.crontab/add_user.json similarity index 90% rename from tests/operations/server.crontab/add_user.json rename to tests/operations/crontab.crontab/add_user.json index 8abcc7e15..178afc7a2 100644 --- a/tests/operations/server.crontab/add_user.json +++ b/tests/operations/crontab.crontab/add_user.json @@ -4,7 +4,7 @@ "user": "pyinfra" }, "facts": { - "server.Crontab": { + "crontab.Crontab": { "user=pyinfra": {} } }, diff --git a/tests/operations/server.crontab/edit.json b/tests/operations/crontab.crontab/edit.json similarity index 95% rename from tests/operations/server.crontab/edit.json rename to tests/operations/crontab.crontab/edit.json index b8fe275e7..1f3111079 100644 --- a/tests/operations/server.crontab/edit.json +++ b/tests/operations/crontab.crontab/edit.json @@ -5,7 +5,7 @@ "day_of_week": [1, 2, "3"] }, "facts": { - "server.Crontab": { + "crontab.Crontab": { "user=None": { "this_is_a_command": { "minute": "*", diff --git a/tests/operations/server.crontab/edit_named.json b/tests/operations/crontab.crontab/edit_named.json similarity index 96% rename from tests/operations/server.crontab/edit_named.json rename to tests/operations/crontab.crontab/edit_named.json index cbfa5d7a7..99379501d 100644 --- a/tests/operations/server.crontab/edit_named.json +++ b/tests/operations/crontab.crontab/edit_named.json @@ -5,7 +5,7 @@ "cron_name": "name of cron" }, "facts": { - "server.Crontab": { + "crontab.Crontab": { "user=None": { "command_to_change": { "minute": "*", diff --git a/tests/operations/server.crontab/edit_special_time.json b/tests/operations/crontab.crontab/edit_special_time.json similarity index 94% rename from tests/operations/server.crontab/edit_special_time.json rename to tests/operations/crontab.crontab/edit_special_time.json index 47812b735..784183be8 100644 --- a/tests/operations/server.crontab/edit_special_time.json +++ b/tests/operations/crontab.crontab/edit_special_time.json @@ -4,7 +4,7 @@ "special_time": "@reboot" }, "facts": { - "server.Crontab": { + "crontab.Crontab": { "user=None": { "this_is_a_command": { "special_time": "@daily", diff --git a/tests/operations/server.crontab/remove.json b/tests/operations/crontab.crontab/remove.json similarity index 95% rename from tests/operations/server.crontab/remove.json rename to tests/operations/crontab.crontab/remove.json index c511c807b..a5368a990 100644 --- a/tests/operations/server.crontab/remove.json +++ b/tests/operations/crontab.crontab/remove.json @@ -4,7 +4,7 @@ "present": false }, "facts": { - "server.Crontab": { + "crontab.Crontab": { "user=None": { "this_is_a_command": { "minute": "*",