-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdocker-backup.py
168 lines (137 loc) · 4.61 KB
/
docker-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
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import docker
import subprocess
import os
import time
import tarfile
import traceback
from datetime import date
from rclone_python import rclone
prefix = "docker-backup"
timestamp = date.strftime(date.today(), "%m-%d-%y")
filename = prefix + "_" + str(timestamp) + ".tar.gz"
docker_dir = "/var/docks"
exclude_dirs = [os.path.normpath(r"/var/docks/plex/Library/'Application Support'/'Plex Media Server'/Media"),
os.path.normpath(r"/var/docks/plex/Library/'Application Support'/'Plex Media Server'/Cache"),
os.path.normpath(r"/var/docks/influx/data/engine"),
os.path.normpath(r"/var/docks/frigate/config/model_cache")]
exclude_exts = [".db"]
client = docker.from_env()
containers = client.containers.list()
for container in containers:
dep_container = str(container.labels['com.docker.compose.depends_on'])
if dep_container != "":
dep_container = dep_container[:dep_container.index(":")]
containers.remove(client.containers.get(dep_container))
def filter_func(tarinfo):
if any(dir in os.path.normpath(os.path.abspath(tarinfo.name)) for dir in exclude_dirs):
return None
elif any(ext in tarinfo.name for ext in exclude_exts):
return None
return tarinfo
try:
print("************************************")
print("**********docker-backup.py**********")
print("************************************")
print("...")
print("...")
print("...")
print("Stopping all containers...")
print("...")
print("...")
print("...")
for container in client.containers.list():
if str(container.status) == "running":
try:
print("Stopping container " + str(container.name) + " ...")
container.stop(timeout=30)
container.wait(timeout=600)
except:
traceback.print_exc(limit=1)
continue
for container in client.containers.list():
if str(container.status) == "running":
print("...")
print("...")
print("...")
print("Container " + str(container.name) + " has not stopped. Sending kill signal...")
container.kill()
container.wait(timeout=30)
print("...")
print("...")
print("...")
print("Creating tar.gz file...")
tar = tarfile.open(filename, "w:gz", dereference=True)
tar.add(docker_dir, filter=filter_func)
tar.close()
print("...")
print("...")
print("...")
print("Starting all containers...")
for container in containers:
subprocess.run([
"/usr/local/bin/docker-compose",
"-f",
container.labels['com.docker.compose.project.config_files'],
"up",
"-d",
"--pull",
"missing",
"--wait"])
print("...")
print("...")
print("...")
print("Uploading to gdrive...")
rclone.copy(filename, "gdrive:/lab", args=["--retries=5"])
print("...")
print("...")
print("...")
print("Deleting tar.gz file...")
if os.path.exists(os.path.abspath(filename)):
os.remove(os.path.abspath(filename))
backups = rclone.ls(
"gdrive:/lab",
files_only=True,
args=["--include=" + prefix + "*"])
sorted_backups = sorted(backups, key=lambda x : x['ModTime'], reverse=True)
if len(sorted_backups) > 2:
backups_to_delete = sorted_backups[2:]
print("...")
print("...")
print("...")
print("Deleting " + str(len(backups_to_delete)) + " backups...")
for backup in backups_to_delete:
rclone.delete("gdrive:/lab" + "/" + backup['Path'],
args=["--drive-use-trash=false"])
else:
print("...")
print("...")
print("...")
print("No backups to delete...")
print("...")
print("...")
print("...")
print("success")
except:
print("...")
print("...")
print("...")
print("Exception occured in overall block, printing traceback...")
traceback.print_exc(limit=1)
if os.path.exists(filename):
os.remove(filename)
print("...")
print("...")
print("...")
print("Starting all containers...")
for container in client.containers.list():
if str(container.status) != "running":
try:
container.start()
except:
continue
for container in client.containers.list():
if str(container.status) != "running":
try:
container.start()
except:
print("Failed to start container " + str(container.name) + "...")