Ensure trailing newline is written to cron file

Records whether existing cron file (or CRONCMD output) has a terminating newline, and ensures a trailing newline is written as necessary EVEN IF NO CHANGE WAS MADE to the target env/job

Fixes #2316
This commit is contained in:
Evan Kaufman 2016-08-03 16:29:47 -07:00 committed by Matt Clay
parent da71acf1bf
commit b416015634

View file

@ -224,6 +224,7 @@ class CronTab(object):
self.root = (os.getuid() == 0) self.root = (os.getuid() == 0)
self.lines = None self.lines = None
self.ansible = "#Ansible: " self.ansible = "#Ansible: "
self.terminated= True
if cron_file: if cron_file:
if os.path.isabs(cron_file): if os.path.isabs(cron_file):
@ -242,7 +243,9 @@ class CronTab(object):
# read the cronfile # read the cronfile
try: try:
f = open(self.cron_file, 'r') f = open(self.cron_file, 'r')
self.lines = f.read().splitlines() read_cron_file = f.read()
self.terminated = read_cron_file.endswith(('\r', '\n'))
self.lines = read_cron_file.splitlines()
f.close() f.close()
except IOError: except IOError:
# cron file does not exist # cron file does not exist
@ -256,6 +259,8 @@ class CronTab(object):
if rc != 0 and rc != 1: # 1 can mean that there are no jobs. if rc != 0 and rc != 1: # 1 can mean that there are no jobs.
raise CronTabError("Unable to read crontab") raise CronTabError("Unable to read crontab")
self.terminated = out.endswith(('\r', '\n'))
lines = out.splitlines() lines = out.splitlines()
count = 0 count = 0
for l in lines: for l in lines:
@ -464,8 +469,8 @@ class CronTab(object):
crons.append(cron) crons.append(cron)
result = '\n'.join(crons) result = '\n'.join(crons)
if result and result[-1] not in ['\n', '\r']: if result:
result += '\n' result = result.rstrip('\r\n') + '\n'
return result return result
def _read_user_execute(self): def _read_user_execute(self):
@ -660,6 +665,10 @@ def main():
crontab.remove_job(name) crontab.remove_job(name)
changed = True changed = True
# no changes to env/job, but existing crontab needs a terminating newline
if not changed and not crontab.terminated:
changed = True
res_args = dict( res_args = dict(
jobs = crontab.get_jobnames(), jobs = crontab.get_jobnames(),
envs = crontab.get_envnames(), envs = crontab.get_envnames(),