import ../model/config_type import ../model/state_type import ../notifier/notifier import strutils, sequtils import osproc import times import os import nativesockets const BORG_BIN = "borg" proc genArchiveName(): string = let hostname = getHostname() let ts = getTime().format("yyyy-MM-dd'T'HH:mm:ss'.'ffffff") return hostname & "-" & ts proc genCommand(cmd: string, repo: string, others: seq[string]): string = var str = BORG_BIN & " " & cmd & " " str &= " " & repo & " " str &= others.join(" ") return str proc run(cmd: string): int = echo "Trying to run : ", cmd try: let res = execProcess(cmd) echo res except: echo getCurrentExceptionMsg() proc runDiscard(cmd: string): int = echo "Trying to run : ", cmd try: let res = execCmd(cmd) return res except: echo getCurrentExceptionMsg() return 1 proc initRepo(nc: NorgConfig, repo: Repository): int = return runDiscard genCommand(cmd = "init", repo = repo.path, others = nc.args.others) proc backupSources(nc: NorgConfig, repo: Repository): int = let start_time = now() notify(nc.notifiers, state=Running) let others = concat(nc.source_dirs, nc.args.others) let archivename = repo.path & "::" & genArchiveName() let res = run genCommand(cmd = "create", repo = archivename, others = others) let end_time = now() let total = (end_time - start_time).inMilliSeconds() case res of 0: notify(nc.notifiers, state=Success, runtime=total) of 1: notify(nc.notifiers, state=Failure, runtime=total) else: notify(nc.notifiers, state=Failure, runtime=total) proc listArchives(nc: NorgConfig, repo: Repository): int = return run genCommand(cmd = "list", repo = repo.path, others = nc.args.others) proc mountArchive(nc: NorgConfig, repo: Repository): int = let archive = repo.path & "::" & nc.args.others[0] let others = nc.args.others[1..^1] let ok = runDiscard genCommand(cmd = "mount", repo = archive, others = others) if ok == 0: echo "Mounted ", archive, " at ", others[0] else: echo "Failed to mount ", archive proc unmountArchive(nc: NorgConfig): int = let ok = runDiscard genCommand(cmd = "umount", repo = "", others = nc.args.others) if ok == 0: echo "Unmounted ", nc.args.others[0] else: echo "Failed to unmount ", nc.args.others[0] proc isEmpty(dir: string): bool = var count = 0 for idx, f in walkDir(dir): return false #count += 1 return count == 0 proc extractArchive(nc: NorgConfig, repo: Repository): int = let archive = repo.path & "::" & nc.args.others[0] var others = nc.args.others[1..^1] if nc.args.extract_destination != "": discard existsOrCreateDir(nc.args.extract_destination) setCurrentDir(nc.args.extract_destination) let dir = getCurrentDir() if dir.isEmpty(): echo "Restoring..." let ok = run(genCommand(cmd = "extract", repo = archive, others = others)) return ok else: echo "Not restoring to non-empty destination\r\nPlease use the --destination flag" proc execute*(nc: NorgConfig) = putEnv("BORG_PASSPHRASE", nc.getEncryptionPassword()) for repo in nc.repositories: case nc.args.borg_cmd of "init": discard initRepo(nc, repo) of "backup": discard backupSources(nc, repo) of "create": discard backupSources(nc, repo) of "list": discard listArchives(nc, repo) of "mount": discard mountArchive(nc, repo) of "umount": discard unmountArchive(nc) of "extract": discard extractArchive(nc, repo) delEnv("BORG_PASSPHRASE")