updated readme with some delete/forget options
This commit is contained in:
parent
53a956bdfa
commit
eaa47c9356
10 changed files with 84 additions and 25 deletions
|
@ -23,7 +23,7 @@ proc checkRepo(nc: NorgConfig, repo: Repository): int =
|
||||||
echo "Not Yet Implemented."
|
echo "Not Yet Implemented."
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc execute*(nc: NorgConfig, repo: Repository) =
|
proc execute*(nc: NorgConfig, repo: Repository): int {.discardable.} =
|
||||||
case nc.args.command
|
case nc.args.command
|
||||||
of INIT:
|
of INIT:
|
||||||
echo "Initializing repo: ", repo.label
|
echo "Initializing repo: ", repo.label
|
||||||
|
@ -51,6 +51,9 @@ proc execute*(nc: NorgConfig, repo: Repository) =
|
||||||
echo "Pruning repo: ", repo.label
|
echo "Pruning repo: ", repo.label
|
||||||
discard pruneRepo(nc, repo)
|
discard pruneRepo(nc, repo)
|
||||||
run_actions(norg_config.actions.after_prune)
|
run_actions(norg_config.actions.after_prune)
|
||||||
|
of DELETE:
|
||||||
|
echo "Deleting Archive ", nc.args.archive
|
||||||
|
discard deleteArchive(nc, repo)
|
||||||
of COMPACT:
|
of COMPACT:
|
||||||
run_actions(norg_config.actions.before_compact)
|
run_actions(norg_config.actions.before_compact)
|
||||||
discard compactRepo(nc, repo)
|
discard compactRepo(nc, repo)
|
||||||
|
|
|
@ -10,3 +10,8 @@ proc genCommand*(cmd: string, repo: string, further_args: seq[string]): string =
|
||||||
let cmd = fmt"{BORG_BIN} {cmd} {repo} {args}"
|
let cmd = fmt"{BORG_BIN} {cmd} {repo} {args}"
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
|
proc genDeleteCommand*(cmd: string, repo: string, archive: string, further_args: seq[string]): string =
|
||||||
|
let args = further_args.join(" ")
|
||||||
|
let cmd = fmt"{BORG_BIN} {cmd} {repo} {archive} {args}"
|
||||||
|
return cmd
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ 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 = fmt"{repo.path}::{nc.args.further_args[0]}"
|
let archive = fmt"{repo.path}::{nc.args.archive}"
|
||||||
var further_args = nc.args.further_args[1..^1]
|
var further_args = nc.args.further_args
|
||||||
if nc.args.extract_destination != "":
|
if nc.args.extract_destination != "":
|
||||||
discard existsOrCreateDir(nc.args.extract_destination)
|
discard existsOrCreateDir(nc.args.extract_destination)
|
||||||
setCurrentDir(nc.args.extract_destination)
|
setCurrentDir(nc.args.extract_destination)
|
||||||
|
|
|
@ -3,8 +3,8 @@ import execute
|
||||||
import strformat
|
import strformat
|
||||||
|
|
||||||
proc mountArchive*(nc: NorgConfig, repo: Repository): int =
|
proc mountArchive*(nc: NorgConfig, repo: Repository): int =
|
||||||
let archive = repo.path & "::" & nc.args.further_args[0]
|
let archive = fmt"{repo.path}::{nc.args.archive}"
|
||||||
let further_args = nc.args.further_args[1..^1]
|
let further_args = nc.args.further_args
|
||||||
let ok = runDiscard genCommand(cmd = "mount", repo = archive, further_args = further_args)
|
let ok = runDiscard genCommand(cmd = "mount", repo = archive, further_args = further_args)
|
||||||
if ok == 0:
|
if ok == 0:
|
||||||
echo fmt"Mounted {archive} at {further_args[0]}"
|
echo fmt"Mounted {archive} at {further_args[0]}"
|
||||||
|
|
|
@ -1,19 +1,12 @@
|
||||||
import ../model/config_type
|
import ../model/config_type
|
||||||
|
|
||||||
import strformat
|
|
||||||
|
|
||||||
import execute
|
import execute
|
||||||
|
|
||||||
proc addPruneOptions(cmd: var string, maintenance: Maintenance) =
|
|
||||||
cmd = fmt"""{cmd} \
|
|
||||||
--keep-hourly {maintenance.keep_hourly} \
|
|
||||||
--keep-daily {maintenance.keep_daily} \
|
|
||||||
--keep-weekly {maintenance.keep_weekly} \
|
|
||||||
--keep-monthly {maintenance.keep_monthly} \
|
|
||||||
--keep-yearly {maintenance.keep_yearly} \
|
|
||||||
"""
|
|
||||||
|
|
||||||
proc pruneRepo*(nc: NorgConfig, repo: Repository): int =
|
proc pruneRepo*(nc: NorgConfig, repo: Repository): int =
|
||||||
var cmd = genCommand(cmd = "prune", repo = repo.path, further_args = nc.args.further_args)
|
var cmd = genCommand(cmd = "prune", repo = repo.path, further_args = nc.args.further_args)
|
||||||
cmd.addPruneOptions(nc.maintenance)
|
cmd.addPruneOptions(nc.maintenance)
|
||||||
return run cmd
|
return run cmd
|
||||||
|
|
||||||
|
proc deleteArchive*(nc: NorgConfig, repo: Repository): int =
|
||||||
|
var cmd = genDeleteCommand(cmd = "delete", repo = repo.path, archive = nc.args.archive, further_args = nc.args.further_args)
|
||||||
|
return run cmd
|
||||||
|
|
|
@ -7,6 +7,7 @@ type
|
||||||
extract_destination*: string
|
extract_destination*: string
|
||||||
command*: Command
|
command*: Command
|
||||||
repository*: string
|
repository*: string
|
||||||
|
archive*: string
|
||||||
further_args*: seq[string]
|
further_args*: seq[string]
|
||||||
|
|
||||||
var norg_args*: NorgArgs = NorgArgs()
|
var norg_args*: NorgArgs = NorgArgs()
|
||||||
|
@ -17,6 +18,7 @@ proc parseArgs*() =
|
||||||
option("-c", "--config", help="Config file to use.", required = true)
|
option("-c", "--config", help="Config file to use.", required = true)
|
||||||
option("-d", "--destination", help="Destination when extracting backup", required = false)
|
option("-d", "--destination", help="Destination when extracting backup", required = false)
|
||||||
option("-r", "--repository", help="Define an explicit repository to work on by either label or path.", required = false)
|
option("-r", "--repository", help="Define an explicit repository to work on by either label or path.", required = false)
|
||||||
|
option("-a", "--archive", help="The archive or snapshot to operate on", required = false)
|
||||||
arg("command", help="The command to run, defaults to 'create' which will perform a backup.", default=some("create"))
|
arg("command", help="The command to run, defaults to 'create' which will perform a backup.", default=some("create"))
|
||||||
arg("further_args", nargs = -1, help="Any further arguments to send onto borg or restic.")
|
arg("further_args", nargs = -1, help="Any further arguments to send onto borg or restic.")
|
||||||
try:
|
try:
|
||||||
|
@ -25,6 +27,7 @@ proc parseArgs*() =
|
||||||
norg_args.extract_destination = opts.destination
|
norg_args.extract_destination = opts.destination
|
||||||
norg_args.command = opts.command.toCommand()
|
norg_args.command = opts.command.toCommand()
|
||||||
norg_args.repository = opts.repository
|
norg_args.repository = opts.repository
|
||||||
|
norg_args.archive = opts.archive
|
||||||
norg_args.further_args = opts.further_args
|
norg_args.further_args = opts.further_args
|
||||||
except ShortCircuit as err:
|
except ShortCircuit as err:
|
||||||
if err.flag == "argparse_help":
|
if err.flag == "argparse_help":
|
||||||
|
|
|
@ -10,6 +10,7 @@ type
|
||||||
MOUNT = "mount",
|
MOUNT = "mount",
|
||||||
UMOUNT = "umount",
|
UMOUNT = "umount",
|
||||||
PRUNE = "prune",
|
PRUNE = "prune",
|
||||||
|
DELETE = "delete"
|
||||||
CHECK = "check",
|
CHECK = "check",
|
||||||
COMPACT = "compact"
|
COMPACT = "compact"
|
||||||
|
|
||||||
|
@ -20,5 +21,6 @@ proc toCommand*(str: string): Command =
|
||||||
of "backup": return CREATE
|
of "backup": return CREATE
|
||||||
of "snapshots","archives": return LIST
|
of "snapshots","archives": return LIST
|
||||||
of "restore": return EXTRACT
|
of "restore": return EXTRACT
|
||||||
|
of "forget": return DELETE
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ proc isEmpty(dir: string): bool =
|
||||||
return count == 0
|
return count == 0
|
||||||
|
|
||||||
proc restoreSnapshot*(nc: NorgConfig, repo: Repository): int =
|
proc restoreSnapshot*(nc: NorgConfig, repo: Repository): int =
|
||||||
let repo_snapshot = fmt"{repo.path} {nc.args.further_args[0]}"
|
let repo_snapshot = fmt"{repo.path} {nc.args.archive}"
|
||||||
var further_args = nc.args.further_args[1..^1]
|
var further_args = nc.args.further_args
|
||||||
if nc.args.extract_destination != "":
|
if nc.args.extract_destination != "":
|
||||||
discard existsOrCreateDir(nc.args.extract_destination)
|
discard existsOrCreateDir(nc.args.extract_destination)
|
||||||
setCurrentDir(nc.args.extract_destination)
|
setCurrentDir(nc.args.extract_destination)
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import strformat
|
import strformat
|
||||||
import osproc
|
import osproc
|
||||||
|
|
||||||
|
import ../model/maintenance_type
|
||||||
|
|
||||||
|
|
||||||
proc run*(cmd: string): int =
|
proc run*(cmd: string): int =
|
||||||
echo fmt"Trying to run : {cmd}"
|
echo fmt"Trying to run : {cmd}"
|
||||||
try:
|
try:
|
||||||
|
@ -18,3 +21,12 @@ proc runDiscard*(cmd: string): int =
|
||||||
except:
|
except:
|
||||||
echo getCurrentExceptionMsg()
|
echo getCurrentExceptionMsg()
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
proc addPruneOptions*(cmd: var string, maintenance: Maintenance) =
|
||||||
|
cmd = fmt"""{cmd} \
|
||||||
|
--keep-hourly {maintenance.keep_hourly} \
|
||||||
|
--keep-daily {maintenance.keep_daily} \
|
||||||
|
--keep-weekly {maintenance.keep_weekly} \
|
||||||
|
--keep-monthly {maintenance.keep_monthly} \
|
||||||
|
--keep-yearly {maintenance.keep_yearly} \
|
||||||
|
"""
|
||||||
|
|
55
readme.md
55
readme.md
|
@ -12,7 +12,7 @@ source_directories = [
|
||||||
"/home/me/Pictures"
|
"/home/me/Pictures"
|
||||||
]
|
]
|
||||||
[[repositories]]
|
[[repositories]]
|
||||||
label = "A Repository"
|
label = "MyBorgRepo"
|
||||||
path = "/my/backup/location"
|
path = "/my/backup/location"
|
||||||
|
|
||||||
[[repositories]]
|
[[repositories]]
|
||||||
|
@ -33,7 +33,7 @@ base_url = "https://uptime.kuma.url/api/push/1234abcd"
|
||||||
states = ["Success","Failure", "Running"]
|
states = ["Success","Failure", "Running"]
|
||||||
```
|
```
|
||||||
|
|
||||||
You can then run the equivalent `borg` command to init, create, list, mount and extract your backups.
|
You can then run the equivalent `borg` or `restic` command to init, create, list, mount and extract your backups.
|
||||||
|
|
||||||
**Using BorgBackup**
|
**Using BorgBackup**
|
||||||
```sh
|
```sh
|
||||||
|
@ -47,16 +47,24 @@ norg -c myconfig.toml create
|
||||||
norg -c myconfig.toml list
|
norg -c myconfig.toml list
|
||||||
|
|
||||||
# Mount an Archive
|
# Mount an Archive
|
||||||
norg -c myconfig.toml mount pcname-2024-08-18T15:20:17773204 /home/me/mnt
|
norg -c myconfig.toml mount -r MyBorgRepo -a pcname-2024-08-18T15:20:17773204 /home/me/mnt
|
||||||
# Unmount an Archive
|
# Unmount an Archive
|
||||||
norg -c myconfig.toml umount /home/me/mnt
|
norg -c myconfig.toml umount -r MyBorgRepo /home/me/mnt
|
||||||
|
|
||||||
# Extract an Archive
|
# Extract an Archive
|
||||||
# You must be in an empty folder for this to work
|
# You must be in an empty folder for this to work
|
||||||
norg -c myconfig.toml extract pcname-2024-08-18T15:20:17773204
|
norg -c myconfig.toml extract -r MyBorgRepo -a pcname-2024-08-18T15:20:17773204
|
||||||
|
|
||||||
# Or You must set the destination to an empty folder
|
# Or You must set the destination to an empty folder
|
||||||
norg -c myconfig.toml extract pcname-2024-08-18T15:20:17773204 --destination /tmp/my_extracted_archive
|
norg -c myconfig.toml extract -r MyBorgRepo -a pcname-2024-08-18T15:20:17773204 --destination /tmp/my_extracted_archive
|
||||||
|
|
||||||
|
# Prune all repos
|
||||||
|
norg -c myconfig.toml prune
|
||||||
|
# Or specify a particula repo
|
||||||
|
norg -c myconfig.toml prune -r MyBorgRepo
|
||||||
|
|
||||||
|
# Delete an Archive
|
||||||
|
norg -c myconfig.toml delete -r MyBorgRepo -a pcname-2024-08-18T15:20:17773204
|
||||||
```
|
```
|
||||||
|
|
||||||
**Using Restic** _New in v0.1.6_
|
**Using Restic** _New in v0.1.6_
|
||||||
|
@ -83,9 +91,22 @@ norg -c myconfig.toml snapshots
|
||||||
norg -c myconfig.toml mount -r MyResticRepo /home/me/mnt
|
norg -c myconfig.toml mount -r MyResticRepo /home/me/mnt
|
||||||
|
|
||||||
# Restore an Archive (restore destination must be empty)
|
# Restore an Archive (restore destination must be empty)
|
||||||
norg -c myconfig.toml restore latest --destination /my/restore/location
|
norg -c myconfig.toml restore -a latest --destination /my/restore/location
|
||||||
|
|
||||||
|
# Prune a repo
|
||||||
|
norg -c myconfig.toml prune
|
||||||
|
|
||||||
|
# Forget a Snapshot
|
||||||
|
norg -c myconfig.toml forget -r MyBorgRepo -a a1b2c3d4
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Command line parameters
|
||||||
|
|
||||||
|
* `-c`, `--config`: The configuration file to use
|
||||||
|
* `-r`, `--repository`: The repository to work on
|
||||||
|
* `-a`, `--archive`: The Archive to operate on (snapshots for restic)
|
||||||
|
* `-d`, `--destination`: When extracting/restoring, the destination for the extracted files
|
||||||
|
|
||||||
# Build from Source
|
# Build from Source
|
||||||
Download and build from source
|
Download and build from source
|
||||||
```sh
|
```sh
|
||||||
|
@ -106,6 +127,26 @@ in line with the [Borg pseudo-species](https://memory-alpha.fandom.com/wiki/Borg
|
||||||
Also, sometimes I feel my code has elements of inexperience but loads of potential... which reminded me of [Nog](https://memory-alpha.fandom.com/wiki/Nog).
|
Also, sometimes I feel my code has elements of inexperience but loads of potential... which reminded me of [Nog](https://memory-alpha.fandom.com/wiki/Nog).
|
||||||
So, simply put, `Norg` is an portmanteau of "Borg" and "Nog".
|
So, simply put, `Norg` is an portmanteau of "Borg" and "Nog".
|
||||||
|
|
||||||
|
## Borg and Restic Notes
|
||||||
|
I love both Borg and Restic tools, they are both great and both have their pros and cons. As [BorgBase](https://borgbase.com) has repos for both, I felt it only sensible to
|
||||||
|
provide a tool that can use both.
|
||||||
|
Providing implementation for both means you could have duplicate backups using
|
||||||
|
different tools which should provide a certain amount of protection over failures in
|
||||||
|
a particular tool.
|
||||||
|
Caution should be taken when using additional flags when you have repositories of
|
||||||
|
both types in the same configuration file. I have tried to cater for some common flags
|
||||||
|
that will be converted to the correct type for a particular tool, but this may not always be the case. If in any doubt, it is advised to use the `--repository` flag for any borg/restic specific flags so as not to cause one the other tool to fail.
|
||||||
|
|
||||||
|
Some different yet similar commands should be converted to the correct type. A table below shows some of these:
|
||||||
|
| Borg Command | Restic Command | Result |
|
||||||
|
| create | backup | creates a backup |
|
||||||
|
| list | snapshots | lists archives/snapshots |
|
||||||
|
| extract | restore | restores/extracts a backup |
|
||||||
|
| delete | forget | removes a archive/snapshot |
|
||||||
|
| prune | forget (with --prune flag) | removes snapshots as per `--keep-*` config |
|
||||||
|
|
||||||
|
You may specify either command and it will work with both except the `forget` command. This will only forget a single snapshot in restic.
|
||||||
|
|
||||||
## Why create this when Borgmatic exists?
|
## Why create this when Borgmatic exists?
|
||||||
`Borgmatic` is absolutely fantastic, and I love it dearly. I even implemented
|
`Borgmatic` is absolutely fantastic, and I love it dearly. I even implemented
|
||||||
the `Uptime Kuma` hook that is in it. However, I got a little impatient waiting
|
the `Uptime Kuma` hook that is in it. However, I got a little impatient waiting
|
||||||
|
|
Loading…
Reference in a new issue