218 lines
6.1 KiB
Python
Executable File
218 lines
6.1 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
utilitaire de lancement en fonction
|
|
|
|
- cron
|
|
- bareos
|
|
|
|
"""
|
|
import sys
|
|
import time
|
|
from os import readlink, unlink
|
|
from os.path import join
|
|
from glob import glob
|
|
|
|
from pyeole.process import system_out
|
|
from pyeole.schedule import SCHEDULE_DIR
|
|
from pyeole.bareos import is_running_jobs, bareos_get_jobs_list
|
|
from creole.client import CreoleClient
|
|
from pyeole.i18n import i18n
|
|
from pyeole.log import init_logging
|
|
|
|
_ = i18n('eole-schedule')
|
|
|
|
log = init_logging(name=u'eole-schedule', level='info', syslog=True,
|
|
console=['stdout', 'stderr'])
|
|
|
|
client = CreoleClient()
|
|
|
|
NOW = time.strftime('%d/%m/%y %H:%M', time.localtime())
|
|
# day in month
|
|
MONTH_DAY = int(time.strftime('%d', time.localtime()))
|
|
# day in week
|
|
WEEK_DAY = int(time.strftime('%w', time.localtime()))
|
|
HOUR = int(time.strftime('%H', time.localtime()))
|
|
|
|
# night start at 12
|
|
if HOUR > 12:
|
|
WEEK_DAY += 1
|
|
|
|
if WEEK_DAY == 0:
|
|
# sunday is 7
|
|
WEEK_DAY = 7
|
|
if WEEK_DAY == 8:
|
|
WEEK_DAY = 1
|
|
|
|
|
|
def log_parts(func):
|
|
def split(msg):
|
|
shreds = msg.split('\n')
|
|
return [func(shred) for shred in shreds if len(shred) > 0]
|
|
return split
|
|
|
|
log.info = log_parts(log.info)
|
|
log.error = log_parts(log.error)
|
|
log.warning = log_parts(log.warning)
|
|
|
|
|
|
def run_runparts(mode, bareos_type):
|
|
"""
|
|
run part script
|
|
test if weekly or monthly script must be launched this day
|
|
"""
|
|
if mode == 'weekly' and WEEK_DAY != client.get('/schedule/schedule/weekday'):
|
|
return
|
|
if mode == 'monthly' and ( WEEK_DAY != client.get('/schedule/schedule/monthday') or MONTH_DAY > 7 ):
|
|
return
|
|
part_str = u"{} schedule {}".format(bareos_type, mode)
|
|
log.info(_("Starting {}").format(part_str))
|
|
dirname = join(SCHEDULE_DIR, mode, bareos_type)
|
|
env = {'PATH': '/sbin:/usr/sbin:/bin:/usr/bin:/usr/share/eole',
|
|
'LC_ALL': 'fr_FR.UTF-8'}
|
|
if mode != 'once':
|
|
runparts_cmd = "/bin/run-parts --exit-on-error --report {} --arg {}"
|
|
wrapped_runparts_cmd = ['/bin/bash',
|
|
'-c',
|
|
runparts_cmd.format(dirname, mode)]
|
|
ret, out, err = system_out(wrapped_runparts_cmd, env=env)
|
|
else:
|
|
# unlink script before launch it
|
|
# (for example remove 'reboot' link before restart the machine)
|
|
names = glob(join(dirname, '*'))
|
|
names.sort()
|
|
ret = 0
|
|
out = None
|
|
err = None
|
|
for name in names:
|
|
script = readlink(name)
|
|
unlink(name)
|
|
wrapped_runparts_cmd = ['/bin/bash',
|
|
'-c', script]
|
|
ret, out, err = system_out(wrapped_runparts_cmd, env=env)
|
|
if ret != 0:
|
|
break
|
|
if out:
|
|
log.info(out)
|
|
if err:
|
|
log.error(err)
|
|
if ret != 0:
|
|
# on affiche sur stderr pour que cron le récupère et le mail
|
|
# ce qui est printé sur stdout est envoyé dans les logs
|
|
if out:
|
|
sys.stderr.write(out)
|
|
if err:
|
|
sys.stderr.write(err)
|
|
sys.stderr.write(_("Error detected\n"))
|
|
log.error(_("{} exited with error return code").format(part_str))
|
|
sys.exit(ret)
|
|
else:
|
|
log.info(_("{} finished").format(part_str))
|
|
|
|
|
|
def schedule_pre():
|
|
run_runparts('daily', 'pre')
|
|
run_runparts('weekly', 'pre')
|
|
run_runparts('monthly', 'pre')
|
|
run_runparts('once', 'pre')
|
|
|
|
|
|
def schedule_post():
|
|
i = 0
|
|
while is_running_jobs():
|
|
time.sleep(1)
|
|
i += 1
|
|
if i == 30:
|
|
log.info(_("Job already running, cancelling"))
|
|
sys.exit(1)
|
|
run_runparts('daily', 'post')
|
|
run_runparts('weekly', 'post')
|
|
run_runparts('monthly', 'post')
|
|
run_runparts('once', 'post')
|
|
|
|
|
|
def schedule_cron():
|
|
"""
|
|
If schedule.py is launched by cron, try to run pre and post
|
|
cron file for daily, weekly and monthly if no backup is set this day
|
|
"""
|
|
def exit_not_cron():
|
|
log.info(_("bareos is set for this day, cancelled"))
|
|
sys.exit(0)
|
|
try:
|
|
bareosjobs = bareos_get_jobs_list()
|
|
for job in bareosjobs:
|
|
day = int(job['day'])
|
|
if job['job'] == 'daily':
|
|
if day <= WEEK_DAY <= job['end_day']:
|
|
exit_not_cron()
|
|
elif job['job'] == 'weekly':
|
|
if WEEK_DAY == day:
|
|
exit_not_cron()
|
|
elif job['job'] == 'monthly':
|
|
if WEEK_DAY == day and MONTH_DAY < 8:
|
|
exit_not_cron()
|
|
else:
|
|
raise Exception(_('Unknown job: {0}').format(job['job']))
|
|
except SystemExit:
|
|
raise
|
|
except:
|
|
pass
|
|
run_runparts('daily', 'pre')
|
|
run_runparts('daily', 'post')
|
|
|
|
run_runparts('weekly', 'pre')
|
|
run_runparts('weekly', 'post')
|
|
|
|
run_runparts('monthly', 'pre')
|
|
run_runparts('monthly', 'post')
|
|
|
|
run_runparts('once', 'pre')
|
|
run_runparts('once', 'post')
|
|
# __________________________________________________
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
usage = """usage:
|
|
{0} bareos [pre|post]
|
|
{0} cron""".format(sys.argv[0])
|
|
|
|
if len(sys.argv) == 1:
|
|
print usage
|
|
sys.exit(1)
|
|
|
|
if len(sys.argv) > 3:
|
|
log.error(_("Too many arguments: {0}").format(sys.argv))
|
|
print usage
|
|
sys.exit(1)
|
|
|
|
mode = sys.argv[1]
|
|
|
|
if mode == 'bareos':
|
|
# pre|post
|
|
if len(sys.argv) == 2:
|
|
log.error(_("Not enough arguments: {0}").format(sys.argv))
|
|
print usage
|
|
sys.exit(1)
|
|
if sys.argv[2] not in ['pre', 'post']:
|
|
log.error(_("Second argument must be pre or post: {0}").format(sys.argv))
|
|
print usage
|
|
sys.exit(1)
|
|
bareos_type = sys.argv[2]
|
|
if bareos_type == 'pre':
|
|
schedule_pre()
|
|
elif bareos_type == 'post':
|
|
schedule_post()
|
|
|
|
elif mode == 'cron':
|
|
if len(sys.argv) != 2:
|
|
log.error(_("Too many arguments for cron: {0}").format(sys.argv))
|
|
print usage
|
|
sys.exit(1)
|
|
schedule_cron()
|
|
else:
|
|
log.error(_("Unknown schedule type : {0}").format(mode))
|
|
print usage
|
|
sys.exit(1)
|