]>
git.frykholm.com Git - butterbackup.git/blob - butterbackup.py
7c80e8b344467f61e1a9738508ec09f020a311c0
4 from subprocess
import check_call
, CalledProcessError
10 def __init__(self
, name
, config
):
13 if not self
.config
.has_section('host'):
14 self
.config
.add_section('host')
15 self
.store_dir
= self
.config
['host']['store_dir']
16 self
.host_dir
= os
.path
.join(self
.store_dir
, name
)
17 self
.subvol_dir
= os
.path
.join(self
.host_dir
, "latest")
18 self
.keep
= int(self
.config
.get("host", "keep", fallback
=-1))
21 if not os
.path
.exists(self
.host_dir
):
22 print("New host",host
,".")
23 os
.makedir(self
.host_dir
)
24 if not os
.path
.exists(self
.subvol_dir
):
26 check_call(shlex
.split("btrfs subvol create %s"% self
.subvol_dir
))
27 except CalledProcessError
as ex
:
28 print("Failed to create subvol! Aborting backup.")
31 command
= ("rsync -a --acls --xattrs --whole-file --numeric-ids --delete --delete-excluded --human-readable --inplace ")
32 excludes
= " --exclude " + " --exclude ".join(self
.config
.get("host", "exclude").split(',')) #FIXME
34 print(command
+ excludes
+ " root@%s:/ "%(self
.name
) + self
.subvol_dir
)
35 check_call(shlex
.split(command
+ excludes
+ " root@%s:/ "%(self
.name
) + self
.subvol_dir
))
36 except CalledProcessError
as ex
:
37 if ex
.returncode
not in (12, 30):
38 print("Rsync did not transfer anything from %s, skipping snapshot."%self
.name
)
40 todays_date
= datetime
.datetime
.now().date().strftime("%F")
41 if os
.path
.exists(os
.path
.join(self
.host_dir
, todays_date
)):
42 #There is a snapshot for today, removing it and creating a new one
44 check_call(shlex
.split("btrfs subvol delete %s"%(os
.path
.join(self
.host_dir
, todays_date
))))
45 except CalledProcessError
as ex
:
48 check_call(shlex
.split("btrfs subvol snapshot -r %s %s"%(self
.subvol_dir
,os
.path
.join(self
.host_dir
, todays_date
))))
49 except CalledProcessError
as ex
:
52 def prune_snapshots(self
):
54 print("No keep specified for %s, keeping all"%self
.name
)
57 snaps
= sorted([snap
for snap
in os
.listdir(self
.host_dir
) if not snap
== "latest" ], reverse
=True)
58 while len(snaps
) > self
.keep
:
61 check_call(shlex
.split("btrfs subvol delete %s"%(os
.path
.join(self
.host_dir
, snap
))))
62 except CalledProcessError
as ex
:
66 def __init__(self
, config_dir
, dest_dir
):
67 self
.config_dir
= config_dir
68 self
.dest_dir
= dest_dir
69 if not os
.path
.exists(self
.config_dir
):
70 print("No config found", self
.config_dir
)
74 self
.hosts
= os
.listdir(self
.config_dir
)
76 for host
in self
.hosts
:
77 if host
== 'default.cfg':
80 config
= configparser
.ConfigParser(strict
=False)
81 config
.read_file(open(os
.path
.join(self
.config_dir
, 'default.cfg'),'r'))
82 config
.read(os
.path
.join(self
.config_dir
, host
))
83 except BaseException
as ex
:
84 print("Config error for %s. Skipping host."%host
)
86 h
= Host(host
, config
)
90 if __name__
== "__main__":
92 print("You need to be root. Otherwise all permissions will be lost.")
94 br
= BackupRunner("/etc/butterbackup", "/mnt/data2")