norgbackup/norg/borg/borg.nim

159 lines
4.9 KiB
Nim

import ../model/config_type
import ../model/state_type
import ../model/borg_type
import ../notifier/notifier
import ../utils/actions
import strutils
import strformat
import sequtils
import osproc
import times
import os
import nativesockets
proc genArchiveName(): string =
let hostname = getHostname()
let ts = getTime().format("yyyy-MM-dd'T'HH:mm:ss'.'ffffff")
return fmt"{hostname}-{ts}"
proc genCommand(cmd: string, repo: string, others: seq[string]): string =
let args = others.join(" ")
let cmd = fmt"{BORG_BIN} {cmd} {repo} {args}"
return cmd
proc run(cmd: string): int =
echo fmt"Trying to run : {cmd}"
try:
let res = execProcess(cmd)
echo res
except:
echo getCurrentExceptionMsg()
proc runDiscard(cmd: string): int =
echo fmt"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 createArchive(nc: NorgConfig, repo: Repository, archivename: string, retry: int = 0): int =
let others = concat(nc.source_directories, nc.args.others)
let res = run genCommand(cmd = "create", repo = archivename, others = others)
if res == 1:
sleep 15 * 1000 # 15 seconds
if retry == nc.retries:
return 1
else:
return createArchive(nc, repo, archivename, retry + 1)
return res
proc backupSources(nc: NorgConfig, repo: Repository): int =
let start_time = now()
notify(nc.notifiers, state=Running)
let end_time = now()
let archivename = repo.path & "::" & genArchiveName()
let res = createArchive(nc, repo, archivename)
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)
return res
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 fmt"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 = fmt"{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 pruneRepo(nc: NorgConfig, repo: Repository): int =
echo "Not Yet Implemented."
discard
proc compactRepo(nc: NorgConfig, repo: Repository): int =
echo "Not Yet Implemented."
discard
proc checkRepo(nc: NorgConfig, repo: Repository): int =
echo "Not Yet Implemented."
discard
proc execute*(nc: NorgConfig) =
run_actions(norg_config.actions.before_everything)
for repo in nc.repositories:
run_actions(norg_config.actions.before_actions)
case nc.args.borg_cmd
of INIT:
discard initRepo(nc, repo)
of CREATE:
run_actions(norg_config.actions.before_backup)
discard backupSources(nc, repo)
run_actions(norg_config.actions.after_backup)
of LIST:
discard listArchives(nc, repo)
of MOUNT:
discard mountArchive(nc, repo)
of UMOUNT:
discard unmountArchive(nc)
of EXTRACT:
run_actions(norg_config.actions.before_extract)
discard extractArchive(nc, repo)
run_actions(norg_config.actions.after_extract)
of PRUNE:
run_actions(norg_config.actions.before_prune)
discard pruneRepo(nc, repo)
run_actions(norg_config.actions.after_prune)
of COMPACT:
run_actions(norg_config.actions.before_compact)
discard compactRepo(nc, repo)
run_actions(norg_config.actions.after_compact)
of CHECK:
run_actions(norg_config.actions.before_check)
discard checkRepo(nc, repo)
run_actions(norg_config.actions.after_check)
run_actions(norg_config.actions.after_actions)
delEncryptionPassphraseInfo()
run_actions(norg_config.actions.after_everything)