Added parameter handling, config file checks, example config file, error and syslog handling
This commit is contained in:
parent
2f88df233c
commit
085dfd85a7
|
@ -1,2 +1,3 @@
|
||||||
config.json
|
config.json
|
||||||
env
|
env
|
||||||
|
.vscode
|
151
backup.py
151
backup.py
|
@ -0,0 +1,151 @@
|
||||||
|
import os
|
||||||
|
import sched
|
||||||
|
import time
|
||||||
|
import sys
|
||||||
|
from termcolor import colored, cprint
|
||||||
|
import getpass
|
||||||
|
import json
|
||||||
|
import datetime
|
||||||
|
import uuid
|
||||||
|
import logging
|
||||||
|
import logging.handlers
|
||||||
|
import multiprocessing
|
||||||
|
|
||||||
|
syslog = True
|
||||||
|
debug = False
|
||||||
|
config_path = '/etc/python-backup.json'
|
||||||
|
Config = None
|
||||||
|
|
||||||
|
|
||||||
|
###############
|
||||||
|
# Helpers #
|
||||||
|
###############
|
||||||
|
|
||||||
|
|
||||||
|
def log(message):
|
||||||
|
if debug:
|
||||||
|
cprint('[DEBUG]: %s' % message, 'yellow')
|
||||||
|
|
||||||
|
|
||||||
|
def error(message):
|
||||||
|
cprint('[ERROR]: %s' % message, 'white', 'on_red')
|
||||||
|
|
||||||
|
|
||||||
|
def printHelp():
|
||||||
|
cprint(
|
||||||
|
'Please run backup.py like so:\n~$ python3 ./backup.py\t\t\tRun with default configuration file (/etc/python-backup.json)\n\
|
||||||
|
or\n~$ python3 ./backup.py {parameter}\n\
|
||||||
|
-h (--help)\t\t\tShow help\n\
|
||||||
|
-v (--version)\t\t\tShow script version\n\
|
||||||
|
-d (--debug)\t\t\tShow debug messages\n\
|
||||||
|
-c (--config) [PATH]\t\tConfiguration file path\n\
|
||||||
|
--single\t\t\tRun single backup - otherwise run in daemon mode\n', 'cyan')
|
||||||
|
|
||||||
|
|
||||||
|
def printVersion():
|
||||||
|
cprint('Python-backup version 1.0\nBy Dominik Dancs | email> do@dancs.sk | web> https://do.dancs.sk', 'cyan')
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
def loadConfig():
|
||||||
|
global config_path, Config, syslog
|
||||||
|
try:
|
||||||
|
Config = json.load(open(config_path))
|
||||||
|
try:
|
||||||
|
Config['syslog']
|
||||||
|
if isinstance(Config['syslog'], bool) and not Config['syslog']:
|
||||||
|
syslog = False
|
||||||
|
Config['unit-name']
|
||||||
|
Config['to-backup']
|
||||||
|
if not isinstance(Config['to-backup'], list):
|
||||||
|
raise Exception('Paths to backup must be a list!')
|
||||||
|
for location in Config['to-backup']:
|
||||||
|
location['path']
|
||||||
|
location['name']
|
||||||
|
Config['compression-level']
|
||||||
|
if not isinstance(Config['compression-level'], int) or Config['compression-level'] < 0 or Config['compression-level'] > 9:
|
||||||
|
raise Exception(
|
||||||
|
'Compression level must be a number between 0 - 9!')
|
||||||
|
Config['cpu-threads']
|
||||||
|
if not isinstance(Config['cpu-threads'], int):
|
||||||
|
raise Exception('Number of CPU threads must be a number!')
|
||||||
|
if Config['cpu-threads'] < 1 or Config['cpu-threads'] > multiprocessing.cpu_count():
|
||||||
|
raise Exception('Invalid number of CPU threads!')
|
||||||
|
Config['backup-locations']
|
||||||
|
if not isinstance(Config['backup-locations'], list):
|
||||||
|
raise Exception('Backup locations must be a priority list!')
|
||||||
|
for location in Config['backup-locations']:
|
||||||
|
location['path']
|
||||||
|
location['priority']
|
||||||
|
if not isinstance(location['priority'], int) or location['priority'] < 0 or location['priority'] > 999:
|
||||||
|
raise Exception(
|
||||||
|
'Location priority must be a number from 0 - 999')
|
||||||
|
except Exception as e:
|
||||||
|
if e == 'syslog':
|
||||||
|
error('Please specify unit name!')
|
||||||
|
if e == 'unit-name':
|
||||||
|
error('Please specify unit name!')
|
||||||
|
elif e == 'to-backup':
|
||||||
|
error('Please specify paths to backup!')
|
||||||
|
elif e == 'compression-level':
|
||||||
|
error('Please specify compression level (0-9)!')
|
||||||
|
elif e == 'cpu-threads':
|
||||||
|
error('Please specify number of available CPU threads!')
|
||||||
|
elif e == 'backup-locations':
|
||||||
|
error('Please specify backup locations!')
|
||||||
|
else:
|
||||||
|
error('Config file does not follow standards!')
|
||||||
|
log(e)
|
||||||
|
exit(1)
|
||||||
|
except Exception as e:
|
||||||
|
error('Unable to read config file!')
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
########################
|
||||||
|
# Argument parsing #
|
||||||
|
########################
|
||||||
|
|
||||||
|
|
||||||
|
# not enough parameters supplied - show help
|
||||||
|
if len(sys.argv) > 0:
|
||||||
|
i = 1
|
||||||
|
while i < len(sys.argv):
|
||||||
|
arg = sys.argv[i]
|
||||||
|
i += 1
|
||||||
|
if arg == '-h' or arg == '--help':
|
||||||
|
printHelp()
|
||||||
|
exit(0)
|
||||||
|
if arg == '-v' or arg == '--version':
|
||||||
|
printVersion()
|
||||||
|
exit(0)
|
||||||
|
if arg == '-d' or arg == '--debug':
|
||||||
|
debug = True
|
||||||
|
elif arg == '-c' or arg == '--config':
|
||||||
|
try:
|
||||||
|
config_path = sys.argv[i]
|
||||||
|
i += 1
|
||||||
|
except:
|
||||||
|
error('No config file provided!')
|
||||||
|
printHelp()
|
||||||
|
exit(1)
|
||||||
|
else:
|
||||||
|
error('Unrecognized argument')
|
||||||
|
printHelp()
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
loadConfig()
|
||||||
|
|
||||||
|
|
||||||
|
########################
|
||||||
|
# Setup syslog #
|
||||||
|
########################
|
||||||
|
|
||||||
|
|
||||||
|
if syslog:
|
||||||
|
logger = logging.getLogger('python-backup')
|
||||||
|
handler = logging.handlers.SysLogHandler(address='/dev/log')
|
||||||
|
handler.setFormatter(logging.Formatter(
|
||||||
|
'%(name)s: [%(levelname)s] %(message)s'
|
||||||
|
))
|
||||||
|
logger.addHandler(handler)
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"unit-name": "vm-us-east-01",
|
||||||
|
"syslog": true,
|
||||||
|
"compression-level": 9,
|
||||||
|
"cpu-threads": 8,
|
||||||
|
"backup-locations": [
|
||||||
|
{ "priority": 0, "path": "/backup1" },
|
||||||
|
{ "priority": 1, "path": "/backup2" }
|
||||||
|
],
|
||||||
|
"backup-format": "{path}/{}",
|
||||||
|
"to-backup": [{
|
||||||
|
"path": "/home",
|
||||||
|
"name": "home"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/data",
|
||||||
|
"name": "data"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/root",
|
||||||
|
"name": "root"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/opt",
|
||||||
|
"name": "opt"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue