summaryrefslogtreecommitdiff
path: root/src/local/server-tools
diff options
context:
space:
mode:
authorLV-426 <lv-426@taproot.org.il>2015-04-21 13:33:23 +0300
committerLV-426 <lv-426@taproot.org.il>2015-04-21 13:33:23 +0300
commit1739bcebf7a1e9deda64d45386083904e7cc216f (patch)
treed1d0a8cee69b913d1911a524f37c7c78ccd1e60c /src/local/server-tools
parent101095f23ba0e98e3d4f34185bdd53686ddfede6 (diff)
rename backup script, mv under server-tools/
Diffstat (limited to 'src/local/server-tools')
-rwxr-xr-xsrc/local/server-tools/rz_backup.py130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/local/server-tools/rz_backup.py b/src/local/server-tools/rz_backup.py
new file mode 100755
index 00000000..e642dd53
--- /dev/null
+++ b/src/local/server-tools/rz_backup.py
@@ -0,0 +1,130 @@
+#!/usr/bin/env python
+
+from datetime import datetime
+import os
+import shutil
+import re
+from glob import glob
+from os.path import basename, dirname, exists
+
+root = '/var/lib/rhizi/backup'
+
+debug = True
+
+backup_template = 'backup-%s.dump'
+backup_glob = backup_template % '*'
+backup_re = re.compile(backup_template % '(\d\d\d\d)(\d\d)(\d\d)')
+
+DAILY_KEPT = 7 # should be >= 7
+WEEKLY_KEPT = 5 # should be >= 5
+
+def unlink(filename):
+ if debug:
+ print("unlinking %s")
+ os.unlink(filename)
+
+def makedirs(path):
+ if exists(path):
+ return
+ if debug:
+ print("makedirs %s" % path)
+ os.makedirs(path)
+
+def copy(src, dst):
+ if debug:
+ print("copy %s %s" % (src, dst))
+ if not exists(src):
+ print("bug: %s doesn't exist") % src
+ raise SystemExit
+ dst_path = dirname(dst)
+ if not exists(dst_path):
+ makedirs(dst_path)
+ shutil.copy(src, dst)
+
+def neo4jshell(command, stdout):
+ cmdline = "neo4j-shell -c '%s' > '%s'" % (command, stdout)
+ if debug:
+ print("executing %r" % cmdline)
+ os.system(cmdline)
+
+def next_daily_filename():
+ filename = os.path.join(daily_root(), backup_template % datetime.now().strftime('%Y%m%d'))
+ return filename
+
+def daily_root():
+ return os.path.join(root, 'daily')
+
+def weekly_root():
+ return os.path.join(root, 'weekly')
+
+def monthly_root():
+ return os.path.join(root, 'monthly')
+
+def backup_year_month_day(filename):
+ return map(int, backup_re.match(basename(filename)).groups())
+
+def to_weekly(filename):
+ year, month, day = backup_year_month_day(filename)
+ _, (wkly_year, wkly_month, wkly_day) = latest_weekly()
+ #import pdb; pdb.set_trace()
+ delta = datetime(year, month, day) - datetime(wkly_year, wkly_month, wkly_day)
+ return delta.days >= 7
+
+def to_monthly(filename):
+ """ return True if filename is newer by a month from the newest monthly """
+ year, month, day = backup_year_month_day(filename)
+ _, (monthly_year, monthly_month, monthly_day) = latest_monthly()
+ if monthly_year < year:
+ month += 12
+ return month > monthly_month and day >= monthly_day
+
+def latest_weekly():
+ return latest(weekly_root())
+
+def latest_monthly():
+ return latest(monthly_root())
+
+def latest(subdir):
+ """
+ returns filename, (year, month, day)
+ """
+ filenames = glob(os.path.join(subdir, backup_glob))
+ if len(filenames) == 0:
+ return 'no_such_file', (1848, 1, 1)
+ return max((fname, backup_year_month_day(fname)) for fname in filenames)
+
+def sorted_backups(subdir):
+ def cmp_files(fa, fb):
+ ta = os.stat(fa).mtime
+ tb = os.stat(fb).mtime
+ if ta == tb:
+ return 0
+ if ta < tb:
+ return -1
+ return 1
+ return sorted(glob(os.path.join(weekly_root(), backup_glob)), cmp=cmp_files)
+
+def create_daily_backup():
+ filename = next_daily_filename()
+ makedirs(dirname(filename))
+ neo4jshell("dump", stdout=filename)
+ return filename
+
+def main():
+ # create the daily backup
+ filename = create_daily_backup()
+
+ # copy out to weekly if a week passed since last weekly, otherwise remove excess
+ if to_weekly(filename):
+ copy(filename, os.path.join(weekly_root(), basename(filename)))
+ for filename in sorted_backups(daily_root())[DAILY_KEPT:]:
+ unlink(filename)
+
+ # rotate out to monthly if a month passed since last monthly, otherwise remove excess
+ if to_monthly(filename):
+ copy(filename, os.path.join(monthly_root(), basename(filename)))
+ for filename in sorted_backups(weekly_root())[WEEKLY_KEPT:]:
+ unlink(filename)
+
+if __name__ == '__main__':
+ main()