Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2015-02-09 21:48:21 +0100
committerArthur de Jong <arthur@arthurdejong.org>2015-02-21 16:16:46 +0100
commite84cdc530ff422a3c8c8d9c9f6d0acf9baef1b81 (patch)
tree469cf713d0cc53c8c512ef0d030b84de39c098c5
parent4b383b0d0587e574888abf06fdf7c077535a4323 (diff)
Implement a command to list backups
This writes an info.json file that contains information on each backup that was made and shows that information with a backups command.
-rwxr-xr-xbackup.py83
-rw-r--r--cmdline.py5
2 files changed, 88 insertions, 0 deletions
diff --git a/backup.py b/backup.py
index 86dbd16..a4fc78b 100755
--- a/backup.py
+++ b/backup.py
@@ -27,6 +27,7 @@ import math
import os
import os.path
import random
+import socket
import sqlite3
import string
import tarfile
@@ -211,6 +212,15 @@ class FileRepository(object):
filelist.sort()
return filelist
+ def list_snapshots(self):
+ """Return snapshots that are found in the repository."""
+ import re
+ filelist = list()
+ for filename in self.listdir('snapshots'):
+ filelist.append(filename)
+ filelist.sort()
+ return filelist
+
def write_file(self, filename, executable=False,
encryption=None, compression=None):
"""Return an open file handle that can be used to write a file
@@ -644,6 +654,12 @@ def backup(config, repo):
snapshot = generate_snapshot_name()
# TODO: or have some way to specify it on the command-line
+ try:
+ from dateutil.tz import tzlocal
+ start_time = datetime.datetime.now(tzlocal())
+ except ImportError:
+ start_time = datetime.datetime.now()
+
# fill the crawled table with information from the filesystem
db.connection.executescript('''
CREATE TEMPORARY TABLE `crawled`
@@ -716,6 +732,34 @@ def backup(config, repo):
write_restore_sh(restorescript, snapshot, used_archives)
restorescript.close()
+ # get statistics from crawled
+ cursor = db.connection.execute('''
+ SELECT COUNT(*), SUM(`size`)
+ FROM `crawled`
+ ''')
+ files, size = cursor.fetchone()
+
+ # write meta-data
+ f = repo.write_file(
+ 'snapshots/%s/info.json' % snapshot,
+ encryption=encryption, compression=compression)
+ try:
+ from dateutil.tz import tzlocal
+ end_time = datetime.datetime.now(tzlocal())
+ except ImportError:
+ end_time = datetime.datetime.now()
+ json.dump(dict(
+ snapshot=snapshot,
+ start_time=start_time.isoformat(),
+ end_time=end_time.isoformat(),
+ files=files,
+ size=size,
+ hostname=socket.gethostname(),
+ paths=args.files,
+ archives=[archive for archive, extractlist in used_archives],
+ ), f)
+ f.close()
+
def set_keys(config, repo):
@@ -728,6 +772,43 @@ def set_keys(config, repo):
repo.write_passphrase(passphrase)
+def list_backups(config, repo):
+ """List snapshots in the repository and print information."""
+ import dateutil.parser
+ from filters import GnuPGKeyEncryption
+ repo.keyencryption = GnuPGKeyEncryption()
+ for snapshot in repo.list_snapshots():
+ try:
+ f = repo.read_file('%s/info.json' % snapshot)
+ info = json.load(f)
+ f.close()
+ start_time = info.get('start_time', '')
+ if start_time:
+ start_time = dateutil.parser.parse(start_time)
+ start_time = start_time.strftime('%Y-%m-%d %H:%M:%S %z').strip()
+ end_time = info.get('end_time', '')
+ if end_time:
+ end_time = dateutil.parser.parse(end_time)
+ end_time = end_time.strftime('%Y-%m-%d %H:%M:%S %z').strip()
+ print '%s %s .. %s' % (
+ os.path.basename(snapshot),
+ start_time, end_time)
+ hostname = info.get('hostname')
+ for path in info.get('paths', ()):
+ print ' %s%s%s' % (hostname, ':' if hostname else '', path)
+ extra = []
+ if 'files' in info:
+ extra.append('%d files' % info['files'])
+ if 'size' in info:
+ extra.append('%d bytes' % info['size'])
+ if 'archives' in info:
+ extra.append('%d archives used' % len(info['archives']))
+ if extra:
+ print ' %s' % ', '.join(extra)
+ except IOError:
+ pass
+
+
if __name__ == '__main__':
from cmdline import parser
@@ -744,3 +825,5 @@ if __name__ == '__main__':
backup(config, repo)
elif args.command == 'set-keys':
set_keys(config, repo)
+ elif args.command == 'backups':
+ list_backups(config, repo)
diff --git a/cmdline.py b/cmdline.py
index 4436df0..5c2f9f7 100644
--- a/cmdline.py
+++ b/cmdline.py
@@ -92,3 +92,8 @@ set_keys_command = subparsers.add_parser(
set_keys_command.add_argument(
'keys', metavar='KEYID', nargs='+',
help='the GnuPG key IDs used for encryption')
+
+# the backups command
+backups_command = subparsers.add_parser(
+ 'backups', parents=[global_options],
+ help='list backups in the repository')