-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbackup.py
83 lines (64 loc) · 2.6 KB
/
backup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import logging
import dj_database_url
import configargparse
from datetime import datetime
from sultan.api import Sultan
from urllib import parse as urlparse
import ftputil
root = logging.getLogger()
root.setLevel(logging.INFO)
p = configargparse.ArgumentParser()
p.add('--db', required=True, help='database url (e.g. mysql://mysql@localhost/db)',
env_var='DATABASE_URL')
p.add('--ftp', required=True, help='FTP url (e.g. ftp://backup:password@backup.network/backups/mydb)',
env_var='FTP_URL')
p.add('--mysqldump', required=False, help='mysqldump path command',
env_var='MYSQLDUMP_COMMAND', default='mysqldump')
p.add('--max', required=False, help='maximum count of backups',
env_var='MAX_FILES', default=100)
p.add('--name', required=False, help='backup name',
env_var='BACKUP_NAME', default='manual_backup')
options = p.parse_args()
s = Sultan()
def backup_front_name(database):
db = dj_database_url.parse(database)
return db['HOST'] + '-' + db['NAME'] + '-' + options.name
def backup_name(database):
now = datetime.now()
now = now.replace(microsecond=0)
return backup_front_name(database) + '-' + now.isoformat() + ".sql"
def backup(database, ftp, mysqldump):
logging.info('Starting backup')
name = backup_name(database)
path = '/tmp/' + name
logging.info('Backup database to {}'.format(path))
db = dj_database_url.parse(database)
s.bash('-c', '"'+' '.join([mysqldump, '-u', db['USER'], '-p'+db['PASSWORD'], '-h', db['HOST'], '-P', str(db['PORT']), db['NAME']]) + '"').redirect(
path,
append=False,
stdout=True,
stderr=False).run()
s.tar('cf', path + '.tar.gz', path).run()
s.rm(path).run()
path = path + '.tar.gz'
ftp = urlparse.urlparse(ftp, 'ftp')
logging.info('Sending backup {} to {}'.format(path, ftp.hostname))
host = ftp.hostname
if ftp.port:
host = host + ':' + ftp.port
# noinspection is due to an error into FTPHost code
# noinspection PyDeprecation
with ftputil.FTPHost(host, ftp.username, ftp.password) as host:
host.makedirs(ftp.path)
host.upload_if_newer(path, ftp.path + name + '.tar.gz')
host.chdir(ftp.path)
files = [file for file in host.listdir(ftp.path) if file.startswith(backup_front_name(database))]
files.sort()
while len(files) > options.max:
old_file = files.pop(0)
host.remove(ftp.path + old_file)
logging.info("Deleted old file {}".format(old_file))
s.rm(path).run()
logging.info('Ended')
if __name__ == '__main__':
backup(options.db, options.ftp, options.mysqldump)