summarylogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.SRCINFO14
-rw-r--r--PKGBUILD52
-rwxr-xr-xsystemd-crontab-generator301
3 files changed, 42 insertions, 325 deletions
diff --git a/.SRCINFO b/.SRCINFO
index d0e35c0306d2..0012d9a5b43c 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,26 +1,26 @@
pkgbase = systemd-crontab-generator
pkgdesc = systemd generator to generate timers/services from crontab and anacrontab files
- pkgver = 0.8
+ pkgver = 0.9.0
pkgrel = 1
- url = https://github.com/kstep/systemd-crontab-generator
- arch = any
+ url = https://github.com/systemd-cron/systemd-crontab-generator
+ arch = i686
+ arch = x86_64
license = GPL3
+ makedepends = rust
depends = python2
depends = systemd
provides = cron
provides = anacron
replaces = cron
replaces = anacron
- source = systemd-crontab-generator
+ source = https://github.com/systemd-cron/systemd-crontab-generator/archive/master.zip
source = systemd-crontab-update
- source = cron.target
source = crontab
source = systemd-crontab-generator.1
source = crontab.1
source = crontab.5
- md5sums = 3e6e2fb5bf3a6f05cacfbbb113516026
+ md5sums = 35e308952f6e4f7d80c50d83ba981c2a
md5sums = 6f00710ad710e319b52edef3e98bd010
- md5sums = 97450f27b69a1e88f1b21faad403df7c
md5sums = 4ac2cfc8de6dabf2e08f39b3c3557879
md5sums = 15acf6fd2a9533c13ce21c6e03210194
md5sums = d863925d682395cef72701725f180884
diff --git a/PKGBUILD b/PKGBUILD
index 3c2b3f4bfaee..06334a0371c0 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -1,42 +1,60 @@
# Maintainer: Konstantin Stepanov <me@kstep.me>
pkgname=systemd-crontab-generator
-pkgver=0.8
+pkgver=0.9.0
pkgrel=1
pkgdesc="systemd generator to generate timers/services from crontab and anacrontab files"
-url="https://github.com/kstep/systemd-crontab-generator"
-arch=('any')
+url="https://github.com/systemd-cron/systemd-crontab-generator"
+arch=('i686' 'x86_64')
license=('GPL3')
depends=('python2' 'systemd')
+makedepends=('rust')
provides=('cron' 'anacron')
replaces=('cron' 'anacron')
-source=(systemd-crontab-generator
- systemd-crontab-update
- cron.target
- crontab
- systemd-crontab-generator.1
- crontab.1
- crontab.5)
-md5sums=('3e6e2fb5bf3a6f05cacfbbb113516026'
+source=('https://github.com/systemd-cron/systemd-crontab-generator/archive/master.zip'
+ 'systemd-crontab-update'
+ 'crontab'
+ 'systemd-crontab-generator.1'
+ 'crontab.1'
+ 'crontab.5')
+md5sums=('35e308952f6e4f7d80c50d83ba981c2a'
'6f00710ad710e319b52edef3e98bd010'
- '97450f27b69a1e88f1b21faad403df7c'
'4ac2cfc8de6dabf2e08f39b3c3557879'
'15acf6fd2a9533c13ce21c6e03210194'
'd863925d682395cef72701725f180884'
'f5e92c03bcb37acd580e2e27f5facc6a')
+prepare() {
+ RUSTVER=$(rustc --version | awk '{ print $2 }')
+ if [[ -n "$RUSTVER" && ("$RUSTVER" < "1.3.0") ]]; then
+ error "Rust nightly is required to build this package."
+ error "Possible ways to get Rust nightly:"
+ error " - AUR package 'rust-nightly-bin',"
+ error " - AUR package 'multirust', and then choose"
+ error " nightly channel with 'multirust default nightly' command,"
+ error " - from official site: http://www.rust-lang.org/install.html."
+ return 1
+ fi
+}
+
build() {
- echo
+ cd "$srcdir/systemd-crontab-generator-master"
+ make release
}
package() {
- install --mode=0755 -D systemd-crontab-generator ${pkgdir}/usr/lib/systemd/system-generators/systemd-crontab-generator
+ cd "$srcdir/systemd-crontab-generator-master"
+ make install PREFIX="$pkgdir/usr"
+
+ cd "$srcdir/"
install --mode=0644 -D systemd-crontab-generator.1 ${pkgdir}/usr/share/man/man1/systemd-crontab-generator.1
gzip ${pkgdir}/usr/share/man/man1/systemd-crontab-generator.1
- install --mode=0755 -D systemd-crontab-update ${pkgdir}/usr/bin/systemd-crontab-update
- install --mode=0644 -D cron.target ${pkgdir}/usr/lib/systemd/system/cron.target
- install --mode=0755 -D crontab ${pkgdir}/usr/bin/crontab
+
install --mode=0644 -D crontab.1 ${pkgdir}/usr/share/man/man1/crontab.1
gzip ${pkgdir}/usr/share/man/man1/crontab.1
+
install --mode=0644 -D crontab.5 ${pkgdir}/usr/share/man/man5/crontab.5
gzip ${pkgdir}/usr/share/man/man5/crontab.5
+
+ install --mode=0755 -D systemd-crontab-update ${pkgdir}/usr/bin/systemd-crontab-update
+ install --mode=0755 -D crontab ${pkgdir}/usr/bin/crontab
}
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