1 /** 2 Copyright: Copyright (c) 2019, Joakim Brännström. All rights reserved. 3 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) 4 Author: Joakim Brännström (joakim.brannstrom@gmx.com) 5 */ 6 module dsnapshot.cmdgroup.diskusage; 7 8 import logger = std.experimental.logger; 9 import std.array : empty; 10 import std.algorithm; 11 import std.exception : collectException; 12 13 import dsnapshot.config : Config; 14 import dsnapshot.exception; 15 import dsnapshot.types; 16 17 int cmdDiskUsage(Snapshot[] snapshots, const Config.Diskusage conf) nothrow { 18 import dsnapshot.layout; 19 import dsnapshot.layout_utils; 20 21 if (conf.name.value.empty) { 22 logger.error("No snapshot name specified (-s|--snapshot)").collectException; 23 return 1; 24 } 25 26 foreach (snapshot; snapshots.filter!(a => a.name == conf.name.value)) { 27 const cmdDu = snapshot.syncCmd.match!((None a) => null, (RsyncConfig a) => a.cmdDiskUsage); 28 if (cmdDu.empty) { 29 logger.errorf("cmd_du is not set for snapshot %s", snapshot.name).collectException; 30 return 1; 31 } 32 33 try { 34 auto flow = snapshot.syncCmd.match!((None a) => None.init.Flow, (RsyncConfig a) => a 35 .flow); 36 // dfmt off 37 return flow.match!((None a) => 1, 38 (FlowRsyncToLocal a) => localDiskUsage(cmdDu, a.dst.value.Path), 39 (FlowLocal a) => localDiskUsage(cmdDu, a.dst.value.Path), 40 (FlowLocalToRsync a) => remoteDiskUsage(a.dst, snapshot.remoteCmd, cmdDu) 41 ); 42 // dfmt on 43 } catch (SnapshotException e) { 44 e.errMsg.match!(a => a.print).collectException; 45 logger.error(e.msg).collectException; 46 } catch (Exception e) { 47 logger.error(e.msg).collectException; 48 break; 49 } 50 } 51 52 logger.errorf("No snapshot with the name %s found", conf.name.value).collectException; 53 logger.infof("Available snapshots are: %-(%s, %)", 54 snapshots.map!(a => a.name)).collectException; 55 return 1; 56 } 57 58 int localDiskUsage(const string[] cmdDu, Path p) { 59 import std.process : spawnProcess, wait; 60 61 auto cmd = cmdDu ~ p.toString; 62 logger.infof("%-(%s %)", cmd); 63 return spawnProcess(cmd).wait; 64 } 65 66 int remoteDiskUsage(RsyncAddr addr, RemoteCmd remote, const string[] cmdDu) { 67 import std.process : spawnProcess, wait; 68 69 auto cmd = remote.match!((SshRemoteCmd a) => a.rsh); 70 cmd ~= addr.addr ~ cmdDu ~ addr.path; 71 logger.infof("%-(%s %)", cmd); 72 return spawnProcess(cmd).wait; 73 }