added initial beginnings to actions
This commit is contained in:
parent
ec6c9a7a46
commit
3a9294dcf1
9 changed files with 172 additions and 55 deletions
|
@ -1,27 +1,29 @@
|
||||||
import ../model/config_type
|
import ../model/config_type
|
||||||
import ../model/state_type
|
import ../model/state_type
|
||||||
|
import ../model/borg_type
|
||||||
import ../notifier/notifier
|
import ../notifier/notifier
|
||||||
import strutils, sequtils
|
import ../utils/actions
|
||||||
|
import strutils
|
||||||
|
import strformat
|
||||||
|
import sequtils
|
||||||
import osproc
|
import osproc
|
||||||
import times
|
import times
|
||||||
import os
|
import os
|
||||||
import nativesockets
|
import nativesockets
|
||||||
|
|
||||||
const BORG_BIN = "borg"
|
|
||||||
|
|
||||||
proc genArchiveName(): string =
|
proc genArchiveName(): string =
|
||||||
let hostname = getHostname()
|
let hostname = getHostname()
|
||||||
let ts = getTime().format("yyyy-MM-dd'T'HH:mm:ss'.'ffffff")
|
let ts = getTime().format("yyyy-MM-dd'T'HH:mm:ss'.'ffffff")
|
||||||
return hostname & "-" & ts
|
return fmt"{hostname}-{ts}"
|
||||||
|
|
||||||
proc genCommand(cmd: string, repo: string, others: seq[string]): string =
|
proc genCommand(cmd: string, repo: string, others: seq[string]): string =
|
||||||
var str = BORG_BIN & " " & cmd & " "
|
let args = others.join(" ")
|
||||||
str &= " " & repo & " "
|
let cmd = fmt"{BORG_BIN} {cmd} {repo} {args}"
|
||||||
str &= others.join(" ")
|
return cmd
|
||||||
return str
|
|
||||||
|
|
||||||
proc run(cmd: string): int =
|
proc run(cmd: string): int =
|
||||||
echo "Trying to run : ", cmd
|
echo fmt"Trying to run : {cmd}"
|
||||||
try:
|
try:
|
||||||
let res = execProcess(cmd)
|
let res = execProcess(cmd)
|
||||||
echo res
|
echo res
|
||||||
|
@ -29,7 +31,7 @@ proc run(cmd: string): int =
|
||||||
echo getCurrentExceptionMsg()
|
echo getCurrentExceptionMsg()
|
||||||
|
|
||||||
proc runDiscard(cmd: string): int =
|
proc runDiscard(cmd: string): int =
|
||||||
echo "Trying to run : ", cmd
|
echo fmt"Trying to run : {cmd}"
|
||||||
try:
|
try:
|
||||||
let res = execCmd(cmd)
|
let res = execCmd(cmd)
|
||||||
return res
|
return res
|
||||||
|
@ -40,13 +42,23 @@ proc runDiscard(cmd: string): int =
|
||||||
proc initRepo(nc: NorgConfig, repo: Repository): int =
|
proc initRepo(nc: NorgConfig, repo: Repository): int =
|
||||||
return runDiscard genCommand(cmd = "init", repo = repo.path, others = nc.args.others)
|
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 =
|
proc backupSources(nc: NorgConfig, repo: Repository): int =
|
||||||
let start_time = now()
|
let start_time = now()
|
||||||
notify(nc.notifiers, state=Running)
|
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 end_time = now()
|
||||||
|
let archivename = repo.path & "::" & genArchiveName()
|
||||||
|
let res = createArchive(nc, repo, archivename)
|
||||||
let total = (end_time - start_time).inMilliSeconds()
|
let total = (end_time - start_time).inMilliSeconds()
|
||||||
case res
|
case res
|
||||||
of 0:
|
of 0:
|
||||||
|
@ -55,6 +67,7 @@ proc backupSources(nc: NorgConfig, repo: Repository): int =
|
||||||
notify(nc.notifiers, state=Failure, runtime=total)
|
notify(nc.notifiers, state=Failure, runtime=total)
|
||||||
else:
|
else:
|
||||||
notify(nc.notifiers, state=Failure, runtime=total)
|
notify(nc.notifiers, state=Failure, runtime=total)
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
proc listArchives(nc: NorgConfig, repo: Repository): int =
|
proc listArchives(nc: NorgConfig, repo: Repository): int =
|
||||||
|
@ -65,7 +78,7 @@ proc mountArchive(nc: NorgConfig, repo: Repository): int =
|
||||||
let others = nc.args.others[1..^1]
|
let others = nc.args.others[1..^1]
|
||||||
let ok = runDiscard genCommand(cmd = "mount", repo = archive, others = others)
|
let ok = runDiscard genCommand(cmd = "mount", repo = archive, others = others)
|
||||||
if ok == 0:
|
if ok == 0:
|
||||||
echo "Mounted ", archive, " at ", others[0]
|
echo fmt"Mounted {archive} at {others[0]}"
|
||||||
else:
|
else:
|
||||||
echo "Failed to mount ", archive
|
echo "Failed to mount ", archive
|
||||||
|
|
||||||
|
@ -83,7 +96,7 @@ proc isEmpty(dir: string): bool =
|
||||||
return count == 0
|
return count == 0
|
||||||
|
|
||||||
proc extractArchive(nc: NorgConfig, repo: Repository): int =
|
proc extractArchive(nc: NorgConfig, repo: Repository): int =
|
||||||
let archive = repo.path & "::" & nc.args.others[0]
|
let archive = fmt"{repo.path}::{nc.args.others[0]}"
|
||||||
var others = nc.args.others[1..^1]
|
var others = nc.args.others[1..^1]
|
||||||
if nc.args.extract_destination != "":
|
if nc.args.extract_destination != "":
|
||||||
discard existsOrCreateDir(nc.args.extract_destination)
|
discard existsOrCreateDir(nc.args.extract_destination)
|
||||||
|
@ -96,22 +109,51 @@ proc extractArchive(nc: NorgConfig, repo: Repository): int =
|
||||||
else:
|
else:
|
||||||
echo "Not restoring to non-empty destination\r\nPlease use the --destination flag"
|
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) =
|
proc execute*(nc: NorgConfig) =
|
||||||
putEnv("BORG_PASSPHRASE", nc.getEncryptionPassword())
|
run_actions(norg_config.actions.before_everything)
|
||||||
for repo in nc.repositories:
|
for repo in nc.repositories:
|
||||||
|
run_actions(norg_config.actions.before_actions)
|
||||||
case nc.args.borg_cmd
|
case nc.args.borg_cmd
|
||||||
of "init":
|
of INIT:
|
||||||
discard initRepo(nc, repo)
|
discard initRepo(nc, repo)
|
||||||
of "backup":
|
of CREATE:
|
||||||
|
run_actions(norg_config.actions.before_backup)
|
||||||
discard backupSources(nc, repo)
|
discard backupSources(nc, repo)
|
||||||
of "create":
|
run_actions(norg_config.actions.after_backup)
|
||||||
discard backupSources(nc, repo)
|
of LIST:
|
||||||
of "list":
|
|
||||||
discard listArchives(nc, repo)
|
discard listArchives(nc, repo)
|
||||||
of "mount":
|
of MOUNT:
|
||||||
discard mountArchive(nc, repo)
|
discard mountArchive(nc, repo)
|
||||||
of "umount":
|
of UMOUNT:
|
||||||
discard unmountArchive(nc)
|
discard unmountArchive(nc)
|
||||||
of "extract":
|
of EXTRACT:
|
||||||
|
run_actions(norg_config.actions.before_extract)
|
||||||
discard extractArchive(nc, repo)
|
discard extractArchive(nc, repo)
|
||||||
delEnv("BORG_PASSPHRASE")
|
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)
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import argparse
|
import argparse
|
||||||
|
import ../model/borg_type
|
||||||
|
|
||||||
type
|
type
|
||||||
NorgArgs* = object
|
NorgArgs* = object
|
||||||
config_file*: string
|
config_file*: string
|
||||||
extract_destination*: string
|
extract_destination*: string
|
||||||
borg_cmd*: string
|
borg_cmd*: BorgCommand
|
||||||
others*: seq[string]
|
others*: seq[string]
|
||||||
|
|
||||||
var norg_args*: NorgArgs = NorgArgs()
|
var norg_args*: NorgArgs = NorgArgs()
|
||||||
|
@ -20,7 +21,7 @@ proc parseArgs*() =
|
||||||
var opts = p.parse(commandLineParams())
|
var opts = p.parse(commandLineParams())
|
||||||
norg_args.config_file = opts.config
|
norg_args.config_file = opts.config
|
||||||
norg_args.extract_destination = opts.destination
|
norg_args.extract_destination = opts.destination
|
||||||
norg_args.borg_cmd = opts.borg_cmd
|
norg_args.borg_cmd = opts.borg_cmd.toBorgCommand()
|
||||||
norg_args.others = opts.others
|
norg_args.others = opts.others
|
||||||
|
|
||||||
except ShortCircuit as err:
|
except ShortCircuit as err:
|
||||||
|
|
|
@ -4,18 +4,34 @@ import ../model/config_type
|
||||||
import notifier_config
|
import notifier_config
|
||||||
export config_type
|
export config_type
|
||||||
|
|
||||||
proc parseConfigFile*(file: string): NorgConfig =
|
proc parseSourceDirectories*(in_conf: TomlValueRef): seq[string] =
|
||||||
norg_config = newNorgConfig()
|
var src_dirs: seq[string] = @[]
|
||||||
let in_conf = parsetoml.parseFile(file)
|
for dir in in_conf{"source_directories"}.getElems():
|
||||||
|
src_dirs.add(dir.getStr())
|
||||||
|
# this is here for backwards compatibiliy
|
||||||
for dir in in_conf{"source_dirs"}.getElems():
|
for dir in in_conf{"source_dirs"}.getElems():
|
||||||
norg_config.source_dirs.add(dir.getStr())
|
norg_config.source_directories.add(dir.getStr())
|
||||||
for r in in_conf{"repositories"}.getElems():
|
return src_dirs
|
||||||
|
|
||||||
|
proc parseEncryption*(enc_conf: TomlValueRef) =
|
||||||
|
norg_config.setEncryptionPassphrase(enc_conf{"encryption_passphrase"}.getStr(""))
|
||||||
|
|
||||||
|
proc parseRepositories*(rep_conf: TomlValueRef): seq[Repository] =
|
||||||
|
var repos: seq[Repository] = @[]
|
||||||
|
for r in rep_conf.getElems():
|
||||||
let rtable = r.getTable()
|
let rtable = r.getTable()
|
||||||
var repo = Repository()
|
var repo = Repository()
|
||||||
repo.path = rtable["path"].getStr()
|
repo.path = rtable["path"].getStr()
|
||||||
repo.label = rtable["label"].getStr()
|
repo.label = rtable["label"].getStr()
|
||||||
norg_config.repositories.add(repo)
|
repos.add(repo)
|
||||||
norg_config.setEncryptionPassword(in_conf{"encryption_password"}.getStr(""))
|
return repos
|
||||||
|
|
||||||
|
proc parseConfigFile*(file: string): NorgConfig =
|
||||||
|
norg_config = newNorgConfig()
|
||||||
|
let in_conf = parsetoml.parseFile(file)
|
||||||
|
norg_config.source_directories = parseSourceDirectories(in_conf)
|
||||||
|
parseEncryption(in_conf{"encryption"})
|
||||||
|
norg_config.repositories = parseRepositories(in_conf{"repositories"})
|
||||||
norg_config.notifiers = parseNotifiers(in_conf)
|
norg_config.notifiers = parseNotifiers(in_conf)
|
||||||
return norg_config
|
return norg_config
|
||||||
|
|
||||||
|
|
|
@ -18,5 +18,4 @@ proc parseNotifiers*(in_conf: TomlValueRef): Notifiers =
|
||||||
if in_conf.hasKey("uptimekuma"):
|
if in_conf.hasKey("uptimekuma"):
|
||||||
let u = parseUptimeKumaConf(in_conf["uptimekuma"])
|
let u = parseUptimeKumaConf(in_conf["uptimekuma"])
|
||||||
notifiers.uptimekuma = u
|
notifiers.uptimekuma = u
|
||||||
echo notifiers
|
|
||||||
return notifiers
|
return notifiers
|
||||||
|
|
24
norg/model/actions_type.nim
Normal file
24
norg/model/actions_type.nim
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
|
||||||
|
type
|
||||||
|
Actions* = object
|
||||||
|
# Before and after everything for all repositories
|
||||||
|
before_everything*: seq[string]
|
||||||
|
after_everything*: seq[string]
|
||||||
|
# before and after each reposistory
|
||||||
|
before_actions*: seq[string]
|
||||||
|
after_actions*: seq[string]
|
||||||
|
# before and after a backup per respository
|
||||||
|
before_backup*: seq[string]
|
||||||
|
after_backup*: seq[string]
|
||||||
|
# before and after a prune per repository
|
||||||
|
before_prune*: seq[string]
|
||||||
|
after_prune*: seq[string]
|
||||||
|
# before and after an extract per repository
|
||||||
|
before_extract*: seq[string]
|
||||||
|
after_extract*: seq[string]
|
||||||
|
# before and after an compact per repository
|
||||||
|
before_compact*: seq[string]
|
||||||
|
after_compact*: seq[string]
|
||||||
|
# before and after an check per repository
|
||||||
|
before_check*: seq[string]
|
||||||
|
after_check*: seq[string]
|
19
norg/model/borg_type.nim
Normal file
19
norg/model/borg_type.nim
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
const BORG_BIN* = "borg"
|
||||||
|
|
||||||
|
type
|
||||||
|
BorgCommand* = enum
|
||||||
|
LIST = "list"
|
||||||
|
INIT = "init",
|
||||||
|
CREATE = "create",
|
||||||
|
EXTRACT = "extract",
|
||||||
|
MOUNT = "mount",
|
||||||
|
UMOUNT = "umount",
|
||||||
|
PRUNE = "prune",
|
||||||
|
CHECK = "check",
|
||||||
|
COMPACT = "compact"
|
||||||
|
|
||||||
|
proc toBorgCommand*(str: string): BorgCommand =
|
||||||
|
for cmd in BorgCommand.items:
|
||||||
|
if str == $cmd: return cmd
|
||||||
|
|
||||||
|
|
|
@ -1,44 +1,54 @@
|
||||||
import repository_type
|
import repository_type
|
||||||
import notifier_types
|
import notifier_types
|
||||||
|
import actions_type
|
||||||
import ../config/args
|
import ../config/args
|
||||||
|
import os
|
||||||
|
|
||||||
export repository_type
|
export repository_type
|
||||||
export notifier_types
|
export notifier_types
|
||||||
|
export actions_type
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
NorgConfig* = ref object
|
NorgConfig* = ref object
|
||||||
source_dirs*: seq[string]
|
retries*: int
|
||||||
|
source_directories*: seq[string]
|
||||||
repositories*: seq[Repository]
|
repositories*: seq[Repository]
|
||||||
|
maintenance*: Maintenance
|
||||||
|
#checks*: Check - see borgmatic
|
||||||
|
notifiers*: Notifiers
|
||||||
|
actions*: Actions
|
||||||
|
args*: NorgArgs
|
||||||
|
Maintenance* = object
|
||||||
keep_daily*: int
|
keep_daily*: int
|
||||||
keep_weekly*: int
|
keep_weekly*: int
|
||||||
keep_monthly*: int
|
keep_monthly*: int
|
||||||
#checks*: Check - see borgmatic
|
|
||||||
notifiers*: Notifiers
|
|
||||||
args*: NorgArgs
|
|
||||||
encryption_password: string
|
|
||||||
|
|
||||||
var norg_config*: NorgConfig
|
var norg_config*: NorgConfig
|
||||||
|
|
||||||
|
proc newMaintenance*(): Maintenance =
|
||||||
|
var m = Maintenance()
|
||||||
|
m.keep_daily = 7
|
||||||
|
m.keep_weekly = 4
|
||||||
|
m.keep_monthly = 6
|
||||||
|
return m
|
||||||
|
|
||||||
proc newNorgConfig*(): NorgConfig =
|
proc newNorgConfig*(): NorgConfig =
|
||||||
var nc = NorgConfig()
|
var nc = NorgConfig()
|
||||||
nc.keep_daily = 7
|
nc.maintenance = newMaintenance()
|
||||||
nc.keep_weekly = 4
|
|
||||||
nc.keep_monthly = 6
|
|
||||||
return nc
|
return nc
|
||||||
|
|
||||||
proc `$`*(c: NorgConfig): string =
|
#proc `$`*(c: NorgConfig): string =
|
||||||
var msg: string = "Source Dirs: " & $c.source_dirs & "\r\n"
|
# var msg: string = "Source Dirs: " & $c.source_directories & "\r\n"
|
||||||
msg &= "Repositories: " & $c.repositories & "\r\n"
|
# msg &= "Repositories: " & $c.repositories & "\r\n"
|
||||||
msg &= "Keep Daily: " & $c.keep_daily & "\r\n"
|
# msg &= "Notifiers: " & $c.notifiers & "\r\n"
|
||||||
msg &= "Keep Weekly: " & $c.keep_weekly & "\r\n"
|
# return msg
|
||||||
msg &= "Keep Monthly: " & $c.keep_monthly & "\r\n"
|
|
||||||
msg &= "Notifiers: " & $c.notifiers & "\r\n"
|
proc setEncryptionPassphrase*(nc: var NorgConfig, pw: string) =
|
||||||
return msg
|
putEnv("BORG_PASSPHRASE", pw)
|
||||||
|
|
||||||
|
proc delEncryptionPassphraseInfo*() =
|
||||||
|
delEnv("BORG_PASSPHRASE")
|
||||||
|
|
||||||
proc setEncryptionPassword*(nc: var NorgConfig, pw: string) =
|
|
||||||
nc.encryption_password = pw
|
|
||||||
|
|
||||||
proc getEncryptionPassword*(nc: NorgConfig): string =
|
|
||||||
return nc.encryption_password
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ proc start() =
|
||||||
parseArgs()
|
parseArgs()
|
||||||
norg_config = parseConfigFile(norg_args.config_file)
|
norg_config = parseConfigFile(norg_args.config_file)
|
||||||
norg_config.args = norg_args
|
norg_config.args = norg_args
|
||||||
if norg_config.source_dirs.len > 0 and norg_config.repositories.len > 0:
|
if norg_config.source_directories.len > 0 and norg_config.repositories.len > 0:
|
||||||
borg.execute(norg_config)
|
borg.execute(norg_config)
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
|
|
6
norg/utils/actions.nim
Normal file
6
norg/utils/actions.nim
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import osproc
|
||||||
|
|
||||||
|
proc run_actions*(actions: seq[string]): int {.discardable.} =
|
||||||
|
for action in actions:
|
||||||
|
echo execCmd(action)
|
||||||
|
|
Loading…
Reference in a new issue