summarylogtreecommitdiffstats
path: root/systemd-crontab-generator
diff options
context:
space:
mode:
Diffstat (limited to 'systemd-crontab-generator')
-rwxr-xr-xsystemd-crontab-generator301
1 files changed, 0 insertions, 301 deletions
diff --git a/systemd-crontab-generator b/systemd-crontab-generator
deleted file mode 100755
index 0f6408b516e9..000000000000
--- a/systemd-crontab-generator
+++ /dev/null
@@ -1,301 +0,0 @@
-#!/usr/bin/python2
-import sys
-import pwd
-import os
-import re
-
-def files(dirname):
- try:
- return filter(os.path.isfile, map(lambda f: os.path.join(dirname, f), os.listdir(dirname)))
- except OSError:
- return []
-
-envvar_re = re.compile(r'^([A-Za-z_0-9]+)\s*=\s*(.*)$')
-
-CRONTAB_FILES = ['/etc/crontab'] + files('/etc/cron.d')
-ANACRONTAB_FILES = ['/etc/anacrontab']
-USERCRONTAB_FILES = files('/var/spool/cron')
-
-TARGER_DIR = sys.argv[1]
-TIMERS_DIR = os.path.join(TARGER_DIR, 'cron.target.wants')
-SELF = os.path.basename(sys.argv[0])
-
-MINUTES_SET = range(0, 60)
-HOURS_SET = range(0, 24)
-DAYS_SET = range(0, 32)
-DOWS_SET = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
-MONTHS_SET = range(0, 13)
-
-ROOT_USER = pwd.getpwnam('root')
-
-try:
- os.makedirs(TIMERS_DIR)
-except OSError as e:
- if e.errno != os.errno.EEXIST:
- raise
-
-def parse_crontab(filename, withuser=True, monotonic=False):
- basename = os.path.basename(filename)
- environment = {
- 'SHELL': '/bin/sh',
- 'PATH': '/usr/bin:/bin',
- }
- with open(filename, 'r') as f:
- for line in f.readlines():
- if line.startswith('#'):
- continue
-
- line = line.rstrip('\n')
- envvar = envvar_re.match(line)
- if envvar:
- environment[envvar.group(1)] = envvar.group(2)
- continue
-
- parts = line.split()
- line = ' '.join(parts)
-
- if monotonic:
- if len(parts) < 4:
- continue
-
- period, delay, jobid = parts[0:3]
- command = ' '.join(parts[3:])
- period = {
- '1': 'daily',
- '7': 'weekly',
- '@midnight': 'daily'
- }.get(period, None) or period.lstrip('@')
-
- environment['LOGNAME'] = environment['USER'] = 'root'
- environment['HOME'] = ROOT_USER.pw_dir
- yield {
- 'e': ' '.join('"%s=%s"' % kv for kv in environment.iteritems()),
- 's': environment['SHELL'],
- 'l': line,
- 'f': filename,
- 'p': period,
- 'd': delay,
- 'j': jobid,
- 'c': command,
- 'u': 'root'
- }
-
- else:
- if line.startswith('@'):
- if len(parts) < 2:
- continue
-
- period = parts[0]
- period = {
- '1': 'daily',
- '7': 'weekly',
- '@midnight': 'daily'
- }.get(period, None) or period.lstrip('@')
-
- user, command = (parts[1], ' '.join(parts[2:])) if withuser else (basename, ' '.join(parts[1:]))
-
- environment['LOGNAME'] = environment['USER'] = user
- environment['HOME'] = pwd.getpwnam(user).pw_dir
-
- yield {
- 'e': ' '.join('"%s=%s"' % kv for kv in environment.iteritems()),
- 's': environment['SHELL'],
- 'l': line,
- 'f': filename,
- 'p': period,
- 'u': user,
- 'c': command
- }
- else:
- if len(parts) < 6 + int(withuser):
- continue
-
- minutes, hours, days = parts[0:3]
- months, dows = parts[3:5]
- user, command = (parts[5], ' '.join(parts[6:])) if withuser else (basename, ' '.join(parts[5:]))
-
- environment['LOGNAME'] = environment['USER'] = user
- environment['HOME'] = pwd.getpwnam(user).pw_dir
-
- yield {
- 'e': ' '.join('"%s=%s"' % kv for kv in environment.iteritems()),
- 's': environment['SHELL'],
- 'l': line,
- 'f': filename,
- 'm': parse_time_unit(minutes, MINUTES_SET),
- 'h': parse_time_unit(hours, HOURS_SET),
- 'd': parse_time_unit(days, DAYS_SET),
- 'w': parse_time_unit(dows, DOWS_SET, dow_map),
- 'M': parse_time_unit(months, MONTHS_SET, month_map),
- 'u': user,
- 'c': command
- }
-
-def parse_time_unit(value, values, mapping=int):
- if value == '*':
- return ['*']
- return sorted(list(reduce(lambda a, i: a.union(set(i)), map(values.__getitem__,
- map(parse_period(mapping), value.split(','))), set())))
-
-def month_map(month):
- try:
- return int(month)
- except ValueError:
- return ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'nov', 'dec'].index(month.lower()[0:3]) + 1
-
-def dow_map(dow):
- try:
- return ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'].index(dow[0:3].lower())
- except ValueError:
- return int(dow) % 7
-
-def parse_period(mapping=int):
- def parser(value):
- try:
- range, step = value.split('/')
- except ValueError:
- value = mapping(value)
- return slice(value, value + 1)
-
- if range == '*':
- return slice(None, None, int(step))
-
- try:
- start, end = range.split('-')
- except ValueError:
- return slice(mapping(range), None, int(step))
-
- return slice(mapping(start), mapping(end), int(step))
-
- return parser
-
-def generate_timer_unit(job, seq):
- n = next(seq)
- unit_name = "cron-%s-%s" % (job['u'], n)
-
- if 'p' in job:
- if job['p'] == 'reboot':
- schedule = 'OnBootSec=%sm' % job.get('d', 5)
- else:
- try:
- schedule = 'OnCalendar=*-*-1/%s 0:%s:0' % (int(job['p']), job.get('d', 0))
- except ValueError:
- schedule = 'OnCalendar=%s' % job['p']
-
- accuracy = job.get('d', 1)
-
- else:
- dows = ','.join(job['w'])
- dows = '' if dows == '*' else dows + ' '
-
- schedule = 'OnCalendar=%s*-%s-%s %s:%s:00' % (dows, ','.join(map(str, job['M'])),
- ','.join(map(str, job['d'])), ','.join(map(str, job['h'])), ','.join(map(str, job['m'])))
- accuracy = 1
-
- with open('%s/%s.timer' % (TARGER_DIR, unit_name), 'w') as f:
- f.write('''# Automatically generated by %s
-# Source crontab: %s
-
-[Unit]
-Description=[Cron] "%s"
-PartOf=cron.target
-RefuseManualStart=true
-RefuseManualStop=true
-
-[Timer]
-Unit=%s.service
-Persistent=true
-AccuracySec=%sm
-%s
-''' % (SELF, job['f'], job['l'], unit_name, accuracy, schedule))
-
- try:
- os.symlink('%s/%s.timer' % (TARGER_DIR, unit_name), '%s/%s.timer' % (TIMERS_DIR, unit_name))
- except OSError as e:
- if e.errno != os.errno.EEXIST:
- raise
-
- with open('%s/%s.service' % (TARGER_DIR, unit_name), 'w') as f:
- f.write('''# Automatically generated by %s
-# Source crontab: %s
-
-[Unit]
-Description=[Cron] "%s"
-RefuseManualStart=true
-RefuseManualStop=true
-
-[Service]
-Type=oneshot
-User=%s
-Environment=%s
-ExecStart=%s -c '%s'
-''' % (SELF, job['f'], job['l'], job['u'], job['e'], job['s'], job['c']))
-
- return '%s.timer' % unit_name
-
-def generate_path_unit():
- combinedcronfiles = [ '/etc/crontab', '/etc/cron.d', '/etc/anacrontab', '/var/spool/cron' ]
- with open('%s/systemd-crontab-update.path' % (TARGER_DIR), 'w') as f:
- f.write('''# Automatically generated by %s
-
-[Unit]
-Description=[Cron] Update cron units
-RefuseManualStart=true
-RefuseManualStop=true
-
-[Path]
-%s
-''' % (SELF,'\n'.join([ "PathChanged="+f for f in combinedcronfiles ]) ))
-
- try:
- os.symlink('%s/systemd-crontab-update.path' % (TARGER_DIR), '%s/systemd-crontab-update.path' % (TIMERS_DIR))
- except OSError as e:
- if e.errno != os.errno.EEXIST:
- raise
-
- with open('%s/systemd-crontab-update.service' % (TARGER_DIR), 'w') as f:
- f.write('''# Automatically generated by %s
-
-[Unit]
-Description=[Cron] Update cron units
-
-[Service]
-Type=oneshot
-ExecStart=/usr/bin/systemd-crontab-update
-''' % (SELF))
-
- return "systemd-crontab-update.path"
-
-seqs = {}
-def count():
- n = 0
- while True:
- yield n
- n += 1
-
-
-for filename in CRONTAB_FILES:
- try:
- for job in parse_crontab(filename, withuser=True):
- generate_timer_unit(job, seqs.setdefault(job['u'], count()))
- except IOError:
- pass
-
-for filename in ANACRONTAB_FILES:
- try:
- for job in parse_crontab(filename, monotonic=True):
- generate_timer_unit(job, seqs.setdefault(job['u'], count()))
- except IOError:
- pass
-
-for filename in USERCRONTAB_FILES:
- try:
- for job in parse_crontab(filename, withuser=False):
- generate_timer_unit(job, seqs.setdefault(job['u'], count()))
- except IOError:
- pass
-
-try:
- generate_path_unit()
-except IOError:
- pass