-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbackup
executable file
·125 lines (111 loc) · 4.58 KB
/
backup
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/usr/bin/python3
# Script to backup selected folders, made for cron
# By Trent Arcuri, 2019
import argparse
import time
import distutils.spawn
import os
import socket
import subprocess
import sys
# Test if running as root, if not, attemp a respawn using sudo
if os.geteuid() != 0:
print('This program requires root access, trying sudo')
os.execvp("sudo", ["sudo"] + sys.argv)
# Gather command line arguments
parser = argparse.ArgumentParser()
parser.add_argument('-s', '--sleep',
type=str, dest='warningseconds', default='10',
help='Specify seconds to show warning before continuing')
parser.add_argument('-n', '--name',
type=str, dest='backupname', default=socket.gethostname(),
help='Specify name for this backup')
parser.add_argument('-t', '--target',
type=str, dest='backuptarget', default='/',
help='Specify what to backup')
parser.add_argument('-d', '--directory',
type=str, dest='backupdir', default='/mnt/backup/',
help='Specify where to backup to')
parser.add_argument('-i', '--increment',
dest='increment', action='store_true', default=False,
help='Run an incremental backup')
parser.add_argument('-m', '--maxincrement',
type=int, dest='backupincmax', default=3,
help='Run an incremental backup')
args = parser.parse_args()
# Format/shorten arguments into sane variables
# Rsync copies here in the end
finalpath = args.backupdir + args.backupname + '/'
# When the script was called
launchtime = time.time()
humanlaunchtime = time.strftime("%Y-%m-%d %H:%M:%S")
# Rsync command sanitization
rsync = distutils.spawn.find_executable('rsync')
rsyncexcludearg = '--exclude='
rsyncoptions = ['-Pauvr', '--delete']
exclude = ["/dev/*",
"/proc/*",
"/sys/*",
"/tmp/*",
"/run/*",
"/mnt/*",
"/media/*",
"/lost+found"]
# Add rsyncexcludearg before every exclude listed above
rsyncexclude = [rsyncexcludearg + excludeitem for excludeitem in exclude]
rsyncargs = rsyncoptions + rsyncexclude
rsynccommand = [rsync] + rsyncargs + [args.backuptarget, finalpath]
def banner():
# Print some info about what is going to run
print("Backup running at", humanlaunchtime, "\n",
"Backup target:", args.backuptarget, "\n",
"Output directory:", args.backupdir, "\n",
"Backup name:", args.backupname, "\n",
"Maximum increments:", args.backupincmax, "\n",
"Warning timeout:", args.warningseconds, "\n",
"Increment mode:", args.increment)
def cleanup():
# Gather time as of completion, print, and increment if necessary
humanendtime = time.strftime("%Y-%m-%d %H:%M:%S")
print('Backup completed, cleaning up')
if args.increment:
incrementprebackup()
os.utime(args.backupdir + args.backupname, (launchtime, launchtime))
print(args.backupname, "backup stopped at", humanendtime)
def incrementprebackup():
# Test if any backups are older than X days, if so, delete //DESTRUCTIVE//
print('Deleting backups older than', args.backupincmax, 'days:')
for backup in os.listdir(args.backupdir + args.backuptarget):
backup = args.backupdir + args.backuptarget + '/' + backup
if os.stat(backup).st_mtime < launchtime - args.backupincmax * 86400:
os.remove(backup)
print('Deleted', backup)
def rsyncbackup():
# Run the backup process here, print command for log usage/debugging
print("Running", rsynccommand)
subprocess.call(rsynccommand)
def main():
# Main program entry point, call preliminary functions
banner()
# Test if xmessage is installed, if so, show a warning message
if distutils.spawn.find_executable("xmessage") is not None:
print('Xmessage found, launching warning message')
warning = subprocess.call(["xmessage", "-timeout", args.warningseconds,
"-nearmous",
"-buttons", "run,cancel",
"Performing backup in", args.warningseconds,
"seconds."])
else:
# This is necessary in case the program is run headlessly (e.g. ssh)
warning = 101
if warning == 102:
print('User cancelled backup.')
# Note this behaviour, an incremental cleanup is still performed
cleanup()
quit(1)
print('Running backup')
# Begin backup, after tests
rsyncbackup()
cleanup()
# Call main function
main()