Allow cron.present to change a timespec from non-special to special

Previously when changing a cron.present job from using a normal time
specification to special or vice-versa, it would duplicate the entry in
the crontab.
This commit is contained in:
Alan Somers 2021-10-04 12:17:11 -06:00 committed by Megan Wilhite
parent d22291d7e9
commit c89a0c19f0
3 changed files with 48 additions and 2 deletions

1
changelog/60997.fixed Normal file
View file

@ -0,0 +1 @@
Fix cron.present duplicating entries when changing timespec to special.

View file

@ -355,6 +355,9 @@ def present(
return ret return ret
if special is None: if special is None:
antidata = __salt__["cron.rm_special"](
user, name, special=special, identifier=identifier
)
data = __salt__["cron.set_job"]( data = __salt__["cron.set_job"](
user=user, user=user,
minute=minute, minute=minute,
@ -368,6 +371,7 @@ def present(
identifier=identifier, identifier=identifier,
) )
else: else:
antidata = __salt__["cron.rm_job"](user, name, identifier=identifier)
data = __salt__["cron.set_special"]( data = __salt__["cron.set_special"](
user=user, user=user,
special=special, special=special,
@ -376,15 +380,23 @@ def present(
commented=commented, commented=commented,
identifier=identifier, identifier=identifier,
) )
if data == "present":
if data == "present" and antidata == "removed":
ret["comment"] = "Duplicate Cron {} removed".format(name)
return ret
if data == "present" and antidata == "absent":
ret["comment"] = "Cron {} already present".format(name) ret["comment"] = "Cron {} already present".format(name)
return ret return ret
if data == "new": if data == "new" and antidata == "absent":
ret["comment"] = "Cron {} added to {}'s crontab".format(name, user) ret["comment"] = "Cron {} added to {}'s crontab".format(name, user)
ret["changes"] = {user: name} ret["changes"] = {user: name}
return ret return ret
if data == "new" and antidata == "removed":
ret["comment"] = "Cron {} time specification changed".format(name)
if data == "updated": if data == "updated":
ret["comment"] = "Cron {} updated".format(name) ret["comment"] = "Cron {} updated".format(name)
ret["changes"] = {user: name} ret["changes"] = {user: name}

View file

@ -24,6 +24,8 @@ class CronTestCase(TestCase, LoaderModuleMockMixin):
"cron.list_tab": cronmod.list_tab, "cron.list_tab": cronmod.list_tab,
"cron.rm_job": cronmod.rm_job, "cron.rm_job": cronmod.rm_job,
"cron.set_job": cronmod.set_job, "cron.set_job": cronmod.set_job,
"cron.rm_special": cronmod.rm_special,
"cron.set_special": cronmod.set_special,
}, },
} }
return {cron: loader_gloabals, cronmod: loader_gloabals} return {cron: loader_gloabals, cronmod: loader_gloabals}
@ -133,6 +135,37 @@ class CronTestCase(TestCase, LoaderModuleMockMixin):
"* 2 * * * foo", "* 2 * * * foo",
) )
def test_present_special(self):
cron.present(name="foo", special="@hourly", identifier="1", user="root")
self.assertMultiLineEqual(
self.get_crontab(),
"# Lines below here are managed by Salt, do not edit\n"
"# SALT_CRON_IDENTIFIER:1\n"
"@hourly foo",
)
def test_present_special_after_unspecial(self):
"""cron.present should remove an unspecial entry with the same identifier"""
cron.present(name="foo", hour="1", identifier="1", user="root")
cron.present(name="foo", special="@hourly", identifier="1", user="root")
self.assertMultiLineEqual(
self.get_crontab(),
"# Lines below here are managed by Salt, do not edit\n"
"# SALT_CRON_IDENTIFIER:1\n"
"@hourly foo",
)
def test_present_unspecial_after_special(self):
"""cron.present should remove an special entry with the same identifier"""
cron.present(name="foo", special="@hourly", identifier="1", user="root")
cron.present(name="foo", hour="1", identifier="1", user="root")
self.assertMultiLineEqual(
self.get_crontab(),
"# Lines below here are managed by Salt, do not edit\n"
"# SALT_CRON_IDENTIFIER:1\n"
"* 1 * * * foo",
)
def test_remove(self): def test_remove(self):
with patch.dict(cron.__opts__, {"test": True}): with patch.dict(cron.__opts__, {"test": True}):
self.set_crontab( self.set_crontab(