diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2015-02-09 21:48:21 +0100 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2015-02-21 16:16:46 +0100 |
commit | e84cdc530ff422a3c8c8d9c9f6d0acf9baef1b81 (patch) | |
tree | 469cf713d0cc53c8c512ef0d030b84de39c098c5 | |
parent | 4b383b0d0587e574888abf06fdf7c077535a4323 (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-x | backup.py | 83 | ||||
-rw-r--r-- | cmdline.py | 5 |
2 files changed, 88 insertions, 0 deletions
@@ -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) @@ -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') |