def main(): args = docopt(USAGE) exitcode = 0 cwd = Path(getcwdu()) if args['mkfs']: root = Path(args['<root>'] or ".", cwd) if args['<data>']: data = Path(args['<data>'], cwd) else: data = Path(".farmfs/userdata", root) mkfs(root, data) print "FileSystem Created %s using blobstore %s" % (root, data) else: vol = getvol(cwd) paths = map(lambda x: Path(x, cwd), empty2dot(args['<path>'])) if args['status']: vol_status = partial(status, vol) map(vol_status, paths) elif args['freeze']: map(vol.freeze, paths) elif args['thaw']: map(vol.thaw, paths) elif args['fsck']: for corruption in vol.fsck(): exitcode = 1 print corruption elif args['count']: for f, c in vol.count().items(): print c, f elif args['similarity']: for (dir_a, dir_b, sim) in vol.similarity(): print sim, dir_a, dir_b elif args['gc']: for f in farmfs.gc(vol): print "Removing", f elif args['snap']: snapdb = vol.snapdb if args['list']: print "\n".join(snapdb.list()) else: name = args['<snap>'] if args['make']: snapdb.write(name, vol.tree()) elif args['read']: snap = snapdb.read(name) for i in snap: print i elif args['delete']: snapdb.delete(name) elif args['restore']: snap = snapdb.read(name) tree = vol.tree() snap_pull(vol.root, tree, vol.udd, snap, vol.udd) elif args['remote']: remotedb = vol.remotedb if args["add"]: remote_vol = getvol(Path(args['<root>'], cwd)) remotedb.write(args['<remote>'], remote_vol) elif args["remove"]: remotedb.delete(args['<remote>']) elif args["list"]: if args["<remote>"]: remote_vol = remotedb.read(args['<remote>']) print "\n".join(remote_vol.snapdb.list()) else: for remote in remotedb.list(): print remote elif args['pull']: remotedb = vol.remotedb remote_vol = remotedb.read(args['<remote>']) snap_name = args['<snap>'] if snap_name is None: remote_snap = remote_vol.tree() else: remote_snap = remote_vol.snapdb.read(snap_name) snap_pull(vol.root, vol.tree(), vol.udd, remote_snap, remote_vol.udd) exit(exitcode)
def vol2(tmp): root = tmp.join("vol2") udd = root.join('.farmfs').join('userdata') mkfs(root, udd) return root
def farmfs_ui(argv, cwd): exitcode = 0 args = docopt(UI_USAGE, argv) if args['mkfs']: root = userPath2Path(args['<root>'] or ".", cwd) data = userPath2Path(args['<data>'], cwd) if args.get('<data>') else Path(".farmfs/userdata", root) mkfs(root, data) print("FileSystem Created %s using blobstore %s" % (root, data)) else: vol = getvol(cwd) paths = empty_default(map(lambda x: userPath2Path(x, cwd), args['<path>']), [vol.root]) def delta_printr(delta): deltaPath = delta.path(vol.root).relative_to(cwd) print("diff: %s %s %s" % (delta.mode, deltaPath, delta.csum)) stream_delta_printr = fmap(identify(delta_printr)) def op_printr(op): (blob_op, tree_op, (desc, path)) = op print(desc % path.relative_to(cwd)) stream_op_printr = fmap(identify(op_printr)) if args['status']: get_thawed = fmap(vol.thawed) pipeline(get_thawed, concat, fmap(lambda p: p.relative_to(cwd)), fmap(print), consume)(paths) elif args['freeze']: def printr(freeze_op): s = "Imported %s with checksum %s" % \ (freeze_op['path'].relative_to(cwd), freeze_op['csum']) if freeze_op['was_dup']: print(s, "was a duplicate") else: print(s) importer = fmap(vol.freeze) get_thawed = fmap(vol.thawed) print_list = fmap(printr) pipeline(get_thawed, concat, importer, print_list, consume)(paths) elif args['thaw']: def printr(path): print("Exported %s" % path.relative_to(cwd)) exporter = fmap(vol.thaw) get_frozen = fmap(vol.frozen) print_list = fmap(printr) pipeline(get_frozen, concat, exporter, print_list, consume)(paths) elif args['fsck']: fsck_actions = { '--broken': (fsck_missing_blobs, 1), '--frozen-ignored': (fsck_frozen_ignored, 4), '--blob-permissions': (fsck_blob_permissions, 8), '--checksums': (fsck_checksum_mismatches, 2), } fsck_tasks = [action for (verb, action) in fsck_actions.items() if args[verb]] if len(fsck_tasks) == 0: # No options were specified, run the whole suite. fsck_tasks = fsck_actions.values() for foo, fail_code in fsck_tasks: exitcode = exitcode | (foo(vol, cwd) and fail_code) elif args['count']: trees = vol.trees() tree_items = concatMap(lambda t: zipFrom(t,iter(t))) tree_links = ffilter(uncurry(lambda snap, item: item.is_link())) checksum_grouper = partial(groupby, uncurry(lambda snap, item: item.csum())) def count_printr(csum, snap_items): print(csum, count(snap_items)) for (snap, item) in snap_items: print(snap.name, item.to_path(vol.root).relative_to(cwd)) counts_printr = fmap(identify(uncurry(count_printr))) pipeline( tree_items, tree_links, checksum_grouper, counts_printr, consume )(trees) elif args['similarity']: dir_a = userPath2Path(args['<dir_a>'], cwd) dir_b = userPath2Path(args['<dir_b>'], cwd) print("left", "both", "right", "jaccard_similarity", sep="\t") print(* vol.similarity(dir_a, dir_b), sep="\t") elif args['gc']: applyfn = fmap(identity) if args.get('--noop') else fmap(vol.bs.delete_blob) fns = [fmap(identify(partial(print, "Removing"))), applyfn, consume] pipeline(*fns)(sorted(vol.unused_blobs(vol.items()))) elif args['snap']: snapdb = vol.snapdb if args['list']: #TODO have an optional argument for which remote. print("\n".join(snapdb.list())) else: name = args['<snap>'] if args['delete']: snapdb.delete(name) elif args['make']: snapdb.write(name, vol.tree()) else: snap = snapdb.read(name) if args['read']: for i in snap: print(i) elif args['restore']: tree = vol.tree() diff = tree_diff(vol.tree(), snap) pipeline( stream_delta_printr, tree_patcher(vol, vol), stream_op_printr, stream_op_doer, consume)(diff) elif args['diff']: diff = tree_diff(vol.tree(), snap) pipeline(stream_delta_printr, consume)(diff) elif args['remote']: if args["add"]: remote_vol = getvol(userPath2Path(args['<root>'], cwd)) vol.remotedb.write(args['<remote>'], remote_vol) elif args["remove"]: vol.remotedb.delete(args['<remote>']) elif args["list"]: if args["<remote>"]: remote_vol = vol.remotedb.read(args['<remote>']) print("\n".join(remote_vol.snapdb.list())) else: for remote_name in vol.remotedb.list(): remote_vol = vol.remotedb.read(remote_name) print(remote_name, remote_vol.root) elif args['pull'] or args['diff']: remote_vol = vol.remotedb.read(args['<remote>']) snap_name = args['<snap>'] remote_snap = remote_vol.snapdb.read(snap_name) if snap_name else remote_vol.tree() diff = tree_diff(vol.tree(), remote_snap) if args['pull']: patcher = tree_patcher(vol, remote_vol) pipeline( stream_delta_printr, patcher, stream_op_printr, stream_op_doer, consume)(diff) else: # diff pipeline(stream_delta_printr, consume)(diff) return exitcode
def vol(tmp): udd = tmp.join('.farmfs').join('userdata') mkfs(tmp, udd) return tmp