mirror of
https://github.com/cupcakearmy/autorestic.git
synced 2024-12-22 08:16:25 +00:00
commit
ddc3accb30
@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [1.3.0] - 2021-10-26
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Pass restic backup metadata as ENV to hooks
|
||||||
|
- Support for `XDG_CONFIG_HOME` and `${HOME}/.config` as default locations for `.autorestic.yaml` file.
|
||||||
|
- Binary restic flags are now supported
|
||||||
|
- Pass encryption keys from env variables or files.
|
||||||
|
|
||||||
## [1.2.0] - 2021-08-05
|
## [1.2.0] - 2021-08-05
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
> [Overview](/backend/overview)
|
> [Overview](/backend/overview)
|
||||||
> [Available Backends](/backend/available)
|
> [Available Backends](/backend/available)
|
||||||
> [Options](/backend/options)
|
> [Options](/backend/options)
|
||||||
|
> [Environment](/backend/env)
|
||||||
|
|
||||||
> :Collapse label=CLI
|
> :Collapse label=CLI
|
||||||
>
|
>
|
||||||
|
36
docs/markdown/backend/env.md
Normal file
36
docs/markdown/backend/env.md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# Environment
|
||||||
|
|
||||||
|
> ⚠ Available since version `v1.3.0`
|
||||||
|
|
||||||
|
Sometimes it's favorable not having the encryption keys in the config files.
|
||||||
|
For that `autorestic` allows passing the backend keys as `ENV` variables, or through an env file.
|
||||||
|
|
||||||
|
The syntax for the `ENV` variables is as follows: `AUTORESTIC_[BACKEND NAME]_KEY`.
|
||||||
|
|
||||||
|
```yaml | autorestic.yaml
|
||||||
|
backend:
|
||||||
|
foo:
|
||||||
|
type: ...
|
||||||
|
path: ...
|
||||||
|
key: secret123 # => AUTORESTIC_FOO_KEY=secret123
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
This means we could remove `key: secret123` from `.autorestic.yaml` and execute as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
AUTORESTIC_FOO_KEY=secret123 autorestic backup ...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Env file
|
||||||
|
|
||||||
|
Alternatively `autorestic` can load an env file, located next to `autorestic.yml` called `.autorestic.env`.
|
||||||
|
|
||||||
|
```| .autorestic.env
|
||||||
|
AUTORESTIC_FOO_KEY=secret123
|
||||||
|
```
|
||||||
|
|
||||||
|
after that you can simply use `autorestic` as your are used to.
|
||||||
|
|
||||||
|
> :ToCPrevNext
|
@ -18,6 +18,8 @@ backend:
|
|||||||
|
|
||||||
In this example, whenever `autorestic` runs `restic backup` it will append a `--tag abc --tag` to the native command.
|
In this example, whenever `autorestic` runs `restic backup` it will append a `--tag abc --tag` to the native command.
|
||||||
|
|
||||||
For more detail see the [location docs](/location/options) for options, as they are the same
|
For more detail see the [location docs](/location/options) for options, as they are the same.
|
||||||
|
|
||||||
|
> For flags without arguments you can set them to `true`. They will be handled accordingly.
|
||||||
|
|
||||||
> :ToCPrevNext
|
> :ToCPrevNext
|
||||||
|
@ -37,11 +37,17 @@ Then paste this at the bottom of the file and save it. Note that in this specifi
|
|||||||
PATH="/usr/local/bin:/usr/bin:/bin"
|
PATH="/usr/local/bin:/usr/bin:/bin"
|
||||||
|
|
||||||
# Example running every 5 minutes
|
# Example running every 5 minutes
|
||||||
*/5 * * * * autorestic --ci cron
|
*/5 * * * * autorestic -c /path/to/my/.autorestic.yml --ci cron
|
||||||
```
|
```
|
||||||
|
|
||||||
> The `--ci` option is not required, but recommended
|
> The `--ci` option is not required, but recommended
|
||||||
|
|
||||||
|
To debug a cron job you can use
|
||||||
|
|
||||||
|
```bash
|
||||||
|
*/5 * * * * autorestic -c /path/to/my/.autorestic.yml --ci cron > /tmp/autorestic.log 2>&1
|
||||||
|
```
|
||||||
|
|
||||||
Now you can add as many `cron` attributes as you wish in the config file ⏱
|
Now you can add as many `cron` attributes as you wish in the config file ⏱
|
||||||
|
|
||||||
> Also note that manually triggered backups with `autorestic backup` will not influence the cron timeline, they are willingly not linked.
|
> Also note that manually triggered backups with `autorestic backup` will not influence the cron timeline, they are willingly not linked.
|
||||||
|
@ -35,8 +35,46 @@ locations:
|
|||||||
2. Run backup
|
2. Run backup
|
||||||
3. `after` hook
|
3. `after` hook
|
||||||
4. - `success` hook if no errors were found
|
4. - `success` hook if no errors were found
|
||||||
- `failure` hook if at least error was encountered
|
- `failure` hook if at least one error was encountered
|
||||||
|
|
||||||
If the `before` hook encounters errors the backup and `after` hooks will be skipped and only the `failed` hooks will run.
|
If the `before` hook encounters errors the backup and `after` hooks will be skipped and only the `failed` hooks will run.
|
||||||
|
|
||||||
|
## Environment variables
|
||||||
|
|
||||||
|
All hooks are exposed to the `AUTORESTIC_LOCATION` environment variable, which contains the location name.
|
||||||
|
|
||||||
|
The `after` and `success` hooks have access to additional information with the following syntax:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
AUTORESTIC_[TYPE]_[I]
|
||||||
|
AUTORESTIC_[TYPE]_[BACKEND_NAME]
|
||||||
|
```
|
||||||
|
|
||||||
|
Every type of metadata is appended with both the name of the backend associated with and the number in which the backends where executed.
|
||||||
|
|
||||||
|
### Available Metadata Types
|
||||||
|
|
||||||
|
- `SNAPSHOT_ID`
|
||||||
|
- `PARENT_SNAPSHOT_ID`
|
||||||
|
- `FILES_ADDED`
|
||||||
|
- `FILES_CHANGED`
|
||||||
|
- `FILES_UNMODIFIED`
|
||||||
|
- `DIRS_ADDED`
|
||||||
|
- `DIRS_CHANGED`
|
||||||
|
- `DIRS_UNMODIFIED`
|
||||||
|
- `ADDED_SIZE`
|
||||||
|
- `PROCESSED_FILES`
|
||||||
|
- `PROCESSED_SIZE`
|
||||||
|
- `PROCESSED_DURATION`
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
Assuming you have a location `bar` that backs up to a single backend named `foo` you could expect the following env variables:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
AUTORESTIC_LOCATION=bar
|
||||||
|
AUTORESTIC_FILES_ADDED_0=42
|
||||||
|
AUTORESTIC_FILES_ADDED_FOO=42
|
||||||
|
```
|
||||||
|
|
||||||
> :ToCPrevNext
|
> :ToCPrevNext
|
||||||
|
@ -18,4 +18,6 @@ locations:
|
|||||||
|
|
||||||
In this example, whenever `autorestic` runs `restic backup` it will append a `--tag abc --tag` to the native command.
|
In this example, whenever `autorestic` runs `restic backup` it will append a `--tag abc --tag` to the native command.
|
||||||
|
|
||||||
|
> For flags without arguments you can set them to `true`. They will be handled accordingly.
|
||||||
|
|
||||||
> :ToCPrevNext
|
> :ToCPrevNext
|
||||||
|
1122
docs/package-lock.json
generated
Normal file
1122
docs/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
436
docs/pnpm-lock.yaml
generated
436
docs/pnpm-lock.yaml
generated
@ -1,436 +0,0 @@
|
|||||||
lockfileVersion: 5.3
|
|
||||||
|
|
||||||
specifiers:
|
|
||||||
'@codedoc/cli': ^0.2.8
|
|
||||||
|
|
||||||
dependencies:
|
|
||||||
'@codedoc/cli': 0.2.8
|
|
||||||
|
|
||||||
packages:
|
|
||||||
|
|
||||||
/@codedoc/cli/0.2.8:
|
|
||||||
resolution: {integrity: sha512-WLZ/i/AkNy8j4d2QLvMn5AZga/CVpP0eKzZ6+Wh6lSvPzDxG1bNeAVOe4sN6fj5tkznbjoo3/R+Emxu0/CLzFg==}
|
|
||||||
hasBin: true
|
|
||||||
dependencies:
|
|
||||||
chalk: 4.1.2
|
|
||||||
shelljs: 0.8.4
|
|
||||||
ts-node: 8.10.2_typescript@3.9.10
|
|
||||||
ts-node-dev: 1.1.8_typescript@3.9.10
|
|
||||||
typescript: 3.9.10
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- node-notifier
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@types/strip-bom/3.0.0:
|
|
||||||
resolution: {integrity: sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@types/strip-json-comments/0.0.30:
|
|
||||||
resolution: {integrity: sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/ansi-styles/4.3.0:
|
|
||||||
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
|
||||||
engines: {node: '>=8'}
|
|
||||||
dependencies:
|
|
||||||
color-convert: 2.0.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/anymatch/3.1.2:
|
|
||||||
resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==}
|
|
||||||
engines: {node: '>= 8'}
|
|
||||||
dependencies:
|
|
||||||
normalize-path: 3.0.0
|
|
||||||
picomatch: 2.3.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/arg/4.1.3:
|
|
||||||
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/balanced-match/1.0.2:
|
|
||||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/binary-extensions/2.2.0:
|
|
||||||
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
|
|
||||||
engines: {node: '>=8'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/brace-expansion/1.1.11:
|
|
||||||
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
|
|
||||||
dependencies:
|
|
||||||
balanced-match: 1.0.2
|
|
||||||
concat-map: 0.0.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/braces/3.0.2:
|
|
||||||
resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
|
|
||||||
engines: {node: '>=8'}
|
|
||||||
dependencies:
|
|
||||||
fill-range: 7.0.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/buffer-from/1.1.2:
|
|
||||||
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/chalk/4.1.2:
|
|
||||||
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
|
||||||
engines: {node: '>=10'}
|
|
||||||
dependencies:
|
|
||||||
ansi-styles: 4.3.0
|
|
||||||
supports-color: 7.2.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/chokidar/3.5.2:
|
|
||||||
resolution: {integrity: sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==}
|
|
||||||
engines: {node: '>= 8.10.0'}
|
|
||||||
dependencies:
|
|
||||||
anymatch: 3.1.2
|
|
||||||
braces: 3.0.2
|
|
||||||
glob-parent: 5.1.2
|
|
||||||
is-binary-path: 2.1.0
|
|
||||||
is-glob: 4.0.3
|
|
||||||
normalize-path: 3.0.0
|
|
||||||
readdirp: 3.6.0
|
|
||||||
optionalDependencies:
|
|
||||||
fsevents: 2.3.2
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/color-convert/2.0.1:
|
|
||||||
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
|
||||||
engines: {node: '>=7.0.0'}
|
|
||||||
dependencies:
|
|
||||||
color-name: 1.1.4
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/color-name/1.1.4:
|
|
||||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/concat-map/0.0.1:
|
|
||||||
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/create-require/1.1.1:
|
|
||||||
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/diff/4.0.2:
|
|
||||||
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
|
|
||||||
engines: {node: '>=0.3.1'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/dynamic-dedupe/0.3.0:
|
|
||||||
resolution: {integrity: sha1-BuRMIj9eTpTXjvnbI6ZRXOL5YqE=}
|
|
||||||
dependencies:
|
|
||||||
xtend: 4.0.2
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/fill-range/7.0.1:
|
|
||||||
resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
|
|
||||||
engines: {node: '>=8'}
|
|
||||||
dependencies:
|
|
||||||
to-regex-range: 5.0.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/fs.realpath/1.0.0:
|
|
||||||
resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/fsevents/2.3.2:
|
|
||||||
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
|
||||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
|
||||||
os: [darwin]
|
|
||||||
requiresBuild: true
|
|
||||||
dev: false
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
/function-bind/1.1.1:
|
|
||||||
resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/glob-parent/5.1.2:
|
|
||||||
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
|
||||||
engines: {node: '>= 6'}
|
|
||||||
dependencies:
|
|
||||||
is-glob: 4.0.3
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/glob/7.2.0:
|
|
||||||
resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==}
|
|
||||||
dependencies:
|
|
||||||
fs.realpath: 1.0.0
|
|
||||||
inflight: 1.0.6
|
|
||||||
inherits: 2.0.4
|
|
||||||
minimatch: 3.0.4
|
|
||||||
once: 1.4.0
|
|
||||||
path-is-absolute: 1.0.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/has-flag/4.0.0:
|
|
||||||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
|
||||||
engines: {node: '>=8'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/has/1.0.3:
|
|
||||||
resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
|
|
||||||
engines: {node: '>= 0.4.0'}
|
|
||||||
dependencies:
|
|
||||||
function-bind: 1.1.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/inflight/1.0.6:
|
|
||||||
resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=}
|
|
||||||
dependencies:
|
|
||||||
once: 1.4.0
|
|
||||||
wrappy: 1.0.2
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/inherits/2.0.4:
|
|
||||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/interpret/1.4.0:
|
|
||||||
resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==}
|
|
||||||
engines: {node: '>= 0.10'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/is-binary-path/2.1.0:
|
|
||||||
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
|
||||||
engines: {node: '>=8'}
|
|
||||||
dependencies:
|
|
||||||
binary-extensions: 2.2.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/is-core-module/2.8.0:
|
|
||||||
resolution: {integrity: sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==}
|
|
||||||
dependencies:
|
|
||||||
has: 1.0.3
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/is-extglob/2.1.1:
|
|
||||||
resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=}
|
|
||||||
engines: {node: '>=0.10.0'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/is-glob/4.0.3:
|
|
||||||
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
|
|
||||||
engines: {node: '>=0.10.0'}
|
|
||||||
dependencies:
|
|
||||||
is-extglob: 2.1.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/is-number/7.0.0:
|
|
||||||
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
|
|
||||||
engines: {node: '>=0.12.0'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/make-error/1.3.6:
|
|
||||||
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/minimatch/3.0.4:
|
|
||||||
resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==}
|
|
||||||
dependencies:
|
|
||||||
brace-expansion: 1.1.11
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/minimist/1.2.5:
|
|
||||||
resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/mkdirp/1.0.4:
|
|
||||||
resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
|
|
||||||
engines: {node: '>=10'}
|
|
||||||
hasBin: true
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/normalize-path/3.0.0:
|
|
||||||
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
|
|
||||||
engines: {node: '>=0.10.0'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/once/1.4.0:
|
|
||||||
resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=}
|
|
||||||
dependencies:
|
|
||||||
wrappy: 1.0.2
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/path-is-absolute/1.0.1:
|
|
||||||
resolution: {integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=}
|
|
||||||
engines: {node: '>=0.10.0'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/path-parse/1.0.7:
|
|
||||||
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/picomatch/2.3.0:
|
|
||||||
resolution: {integrity: sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==}
|
|
||||||
engines: {node: '>=8.6'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/readdirp/3.6.0:
|
|
||||||
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
|
|
||||||
engines: {node: '>=8.10.0'}
|
|
||||||
dependencies:
|
|
||||||
picomatch: 2.3.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/rechoir/0.6.2:
|
|
||||||
resolution: {integrity: sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=}
|
|
||||||
engines: {node: '>= 0.10'}
|
|
||||||
dependencies:
|
|
||||||
resolve: 1.20.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/resolve/1.20.0:
|
|
||||||
resolution: {integrity: sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==}
|
|
||||||
dependencies:
|
|
||||||
is-core-module: 2.8.0
|
|
||||||
path-parse: 1.0.7
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/rimraf/2.7.1:
|
|
||||||
resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==}
|
|
||||||
hasBin: true
|
|
||||||
dependencies:
|
|
||||||
glob: 7.2.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/shelljs/0.8.4:
|
|
||||||
resolution: {integrity: sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==}
|
|
||||||
engines: {node: '>=4'}
|
|
||||||
hasBin: true
|
|
||||||
dependencies:
|
|
||||||
glob: 7.2.0
|
|
||||||
interpret: 1.4.0
|
|
||||||
rechoir: 0.6.2
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/source-map-support/0.5.20:
|
|
||||||
resolution: {integrity: sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==}
|
|
||||||
dependencies:
|
|
||||||
buffer-from: 1.1.2
|
|
||||||
source-map: 0.6.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/source-map/0.6.1:
|
|
||||||
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
|
|
||||||
engines: {node: '>=0.10.0'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/strip-bom/3.0.0:
|
|
||||||
resolution: {integrity: sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=}
|
|
||||||
engines: {node: '>=4'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/strip-json-comments/2.0.1:
|
|
||||||
resolution: {integrity: sha1-PFMZQukIwml8DsNEhYwobHygpgo=}
|
|
||||||
engines: {node: '>=0.10.0'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/supports-color/7.2.0:
|
|
||||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
|
||||||
engines: {node: '>=8'}
|
|
||||||
dependencies:
|
|
||||||
has-flag: 4.0.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/to-regex-range/5.0.1:
|
|
||||||
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
|
||||||
engines: {node: '>=8.0'}
|
|
||||||
dependencies:
|
|
||||||
is-number: 7.0.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/tree-kill/1.2.2:
|
|
||||||
resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
|
|
||||||
hasBin: true
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/ts-node-dev/1.1.8_typescript@3.9.10:
|
|
||||||
resolution: {integrity: sha512-Q/m3vEwzYwLZKmV6/0VlFxcZzVV/xcgOt+Tx/VjaaRHyiBcFlV0541yrT09QjzzCxlDZ34OzKjrFAynlmtflEg==}
|
|
||||||
engines: {node: '>=0.8.0'}
|
|
||||||
hasBin: true
|
|
||||||
peerDependencies:
|
|
||||||
node-notifier: '*'
|
|
||||||
typescript: '*'
|
|
||||||
peerDependenciesMeta:
|
|
||||||
node-notifier:
|
|
||||||
optional: true
|
|
||||||
dependencies:
|
|
||||||
chokidar: 3.5.2
|
|
||||||
dynamic-dedupe: 0.3.0
|
|
||||||
minimist: 1.2.5
|
|
||||||
mkdirp: 1.0.4
|
|
||||||
resolve: 1.20.0
|
|
||||||
rimraf: 2.7.1
|
|
||||||
source-map-support: 0.5.20
|
|
||||||
tree-kill: 1.2.2
|
|
||||||
ts-node: 9.1.1_typescript@3.9.10
|
|
||||||
tsconfig: 7.0.0
|
|
||||||
typescript: 3.9.10
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/ts-node/8.10.2_typescript@3.9.10:
|
|
||||||
resolution: {integrity: sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==}
|
|
||||||
engines: {node: '>=6.0.0'}
|
|
||||||
hasBin: true
|
|
||||||
peerDependencies:
|
|
||||||
typescript: '>=2.7'
|
|
||||||
dependencies:
|
|
||||||
arg: 4.1.3
|
|
||||||
diff: 4.0.2
|
|
||||||
make-error: 1.3.6
|
|
||||||
source-map-support: 0.5.20
|
|
||||||
typescript: 3.9.10
|
|
||||||
yn: 3.1.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/ts-node/9.1.1_typescript@3.9.10:
|
|
||||||
resolution: {integrity: sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==}
|
|
||||||
engines: {node: '>=10.0.0'}
|
|
||||||
hasBin: true
|
|
||||||
peerDependencies:
|
|
||||||
typescript: '>=2.7'
|
|
||||||
dependencies:
|
|
||||||
arg: 4.1.3
|
|
||||||
create-require: 1.1.1
|
|
||||||
diff: 4.0.2
|
|
||||||
make-error: 1.3.6
|
|
||||||
source-map-support: 0.5.20
|
|
||||||
typescript: 3.9.10
|
|
||||||
yn: 3.1.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/tsconfig/7.0.0:
|
|
||||||
resolution: {integrity: sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==}
|
|
||||||
dependencies:
|
|
||||||
'@types/strip-bom': 3.0.0
|
|
||||||
'@types/strip-json-comments': 0.0.30
|
|
||||||
strip-bom: 3.0.0
|
|
||||||
strip-json-comments: 2.0.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/typescript/3.9.10:
|
|
||||||
resolution: {integrity: sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==}
|
|
||||||
engines: {node: '>=4.2.0'}
|
|
||||||
hasBin: true
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/wrappy/1.0.2:
|
|
||||||
resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/xtend/4.0.2:
|
|
||||||
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
|
|
||||||
engines: {node: '>=0.4'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/yn/3.1.1:
|
|
||||||
resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
|
|
||||||
engines: {node: '>=6'}
|
|
||||||
dev: false
|
|
1
go.mod
1
go.mod
@ -6,6 +6,7 @@ require (
|
|||||||
github.com/blang/semver/v4 v4.0.0
|
github.com/blang/semver/v4 v4.0.0
|
||||||
github.com/buger/goterm v1.0.0
|
github.com/buger/goterm v1.0.0
|
||||||
github.com/fatih/color v1.10.0
|
github.com/fatih/color v1.10.0
|
||||||
|
github.com/joho/godotenv v1.4.0
|
||||||
github.com/mitchellh/go-homedir v1.1.0
|
github.com/mitchellh/go-homedir v1.1.0
|
||||||
github.com/robfig/cron v1.2.0
|
github.com/robfig/cron v1.2.0
|
||||||
github.com/spf13/cobra v1.1.3
|
github.com/spf13/cobra v1.1.3
|
||||||
|
2
go.sum
2
go.sum
@ -101,6 +101,8 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p
|
|||||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
|
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
|
||||||
|
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||||
|
@ -58,7 +58,15 @@ func (b Backend) generateRepo() (string, error) {
|
|||||||
|
|
||||||
func (b Backend) getEnv() (map[string]string, error) {
|
func (b Backend) getEnv() (map[string]string, error) {
|
||||||
env := make(map[string]string)
|
env := make(map[string]string)
|
||||||
|
if b.Key != "" {
|
||||||
env["RESTIC_PASSWORD"] = b.Key
|
env["RESTIC_PASSWORD"] = b.Key
|
||||||
|
} else {
|
||||||
|
key, err := b.getKey()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
env["RESTIC_PASSWORD"] = key
|
||||||
|
}
|
||||||
repo, err := b.generateRepo()
|
repo, err := b.generateRepo()
|
||||||
env["RESTIC_REPOSITORY"] = repo
|
env["RESTIC_REPOSITORY"] = repo
|
||||||
for key, value := range b.Env {
|
for key, value := range b.Env {
|
||||||
@ -77,6 +85,17 @@ func generateRandomKey() string {
|
|||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b Backend) getKey() (string, error) {
|
||||||
|
if b.Key != "" {
|
||||||
|
return b.Key, nil
|
||||||
|
}
|
||||||
|
keyName := "AUTORESTIC_" + strings.ToUpper(b.name) + "_KEY"
|
||||||
|
if key, found := os.LookupEnv(keyName); found {
|
||||||
|
return key, nil
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("no key found for backend \"%s\"", b.name)
|
||||||
|
}
|
||||||
|
|
||||||
func (b Backend) validate() error {
|
func (b Backend) validate() error {
|
||||||
if b.Type == "" {
|
if b.Type == "" {
|
||||||
return fmt.Errorf(`Backend "%s" has no "type"`, b.name)
|
return fmt.Errorf(`Backend "%s" has no "type"`, b.name)
|
||||||
@ -85,6 +104,9 @@ func (b Backend) validate() error {
|
|||||||
return fmt.Errorf(`Backend "%s" has no "path"`, b.name)
|
return fmt.Errorf(`Backend "%s" has no "path"`, b.name)
|
||||||
}
|
}
|
||||||
if b.Key == "" {
|
if b.Key == "" {
|
||||||
|
// Check if key is set in environment
|
||||||
|
if _, err := b.getKey(); err != nil {
|
||||||
|
// If not generate a new one
|
||||||
key := generateRandomKey()
|
key := generateRandomKey()
|
||||||
b.Key = key
|
b.Key = key
|
||||||
c := GetConfig()
|
c := GetConfig()
|
||||||
@ -95,6 +117,7 @@ func (b Backend) validate() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
env, err := b.getEnv()
|
env, err := b.getEnv()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -10,12 +10,13 @@ import (
|
|||||||
|
|
||||||
"github.com/cupcakearmy/autorestic/internal/colors"
|
"github.com/cupcakearmy/autorestic/internal/colors"
|
||||||
"github.com/cupcakearmy/autorestic/internal/lock"
|
"github.com/cupcakearmy/autorestic/internal/lock"
|
||||||
|
"github.com/joho/godotenv"
|
||||||
"github.com/mitchellh/go-homedir"
|
"github.com/mitchellh/go-homedir"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
const VERSION = "1.2.0"
|
const VERSION = "1.3.0"
|
||||||
|
|
||||||
var CI bool = false
|
var CI bool = false
|
||||||
var VERBOSE bool = false
|
var VERBOSE bool = false
|
||||||
@ -36,7 +37,13 @@ func GetConfig() *Config {
|
|||||||
if err := viper.ReadInConfig(); err == nil {
|
if err := viper.ReadInConfig(); err == nil {
|
||||||
if !CRON_LEAN {
|
if !CRON_LEAN {
|
||||||
absConfig, _ := filepath.Abs(viper.ConfigFileUsed())
|
absConfig, _ := filepath.Abs(viper.ConfigFileUsed())
|
||||||
colors.Faint.Println("Using config file:", absConfig)
|
colors.Faint.Println("Using config: \t", absConfig)
|
||||||
|
// Load env file
|
||||||
|
envFile := filepath.Join(filepath.Dir(absConfig), ".autorestic.env")
|
||||||
|
err = godotenv.Load(envFile)
|
||||||
|
if err == nil {
|
||||||
|
colors.Faint.Println("Using env:\t", envFile)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
@ -232,7 +239,18 @@ func getOptions(options Options, key string) []string {
|
|||||||
var selected []string
|
var selected []string
|
||||||
for k, values := range options[key] {
|
for k, values := range options[key] {
|
||||||
for _, value := range values {
|
for _, value := range values {
|
||||||
selected = append(selected, fmt.Sprintf("--%s", k), value)
|
// Bool
|
||||||
|
asBool, ok := value.(bool)
|
||||||
|
if ok && asBool {
|
||||||
|
selected = append(selected, fmt.Sprintf("--%s", k))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// String
|
||||||
|
asString, ok := value.(string)
|
||||||
|
if ok {
|
||||||
|
selected = append(selected, fmt.Sprintf("--%s", k), asString)
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return selected
|
return selected
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/cupcakearmy/autorestic/internal/colors"
|
"github.com/cupcakearmy/autorestic/internal/colors"
|
||||||
"github.com/cupcakearmy/autorestic/internal/lock"
|
"github.com/cupcakearmy/autorestic/internal/lock"
|
||||||
|
"github.com/cupcakearmy/autorestic/internal/metadata"
|
||||||
"github.com/robfig/cron"
|
"github.com/robfig/cron"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ type Hooks struct {
|
|||||||
Failure HookArray `yaml:"failure,omitempty"`
|
Failure HookArray `yaml:"failure,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Options map[string]map[string][]string
|
type Options map[string]map[string][]interface{}
|
||||||
|
|
||||||
type Location struct {
|
type Location struct {
|
||||||
name string `yaml:",omitempty"`
|
name string `yaml:",omitempty"`
|
||||||
@ -130,6 +131,9 @@ func (l Location) Backup(cron bool) []error {
|
|||||||
t := l.getType()
|
t := l.getType()
|
||||||
options := ExecuteOptions{
|
options := ExecuteOptions{
|
||||||
Command: "bash",
|
Command: "bash",
|
||||||
|
Envs: map[string]string{
|
||||||
|
"AUTORESTIC_LOCATION": l.name,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := l.validate(); err != nil {
|
if err := l.validate(); err != nil {
|
||||||
@ -151,7 +155,7 @@ func (l Location) Backup(cron bool) []error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Backup
|
// Backup
|
||||||
for _, to := range l.To {
|
for i, to := range l.To {
|
||||||
backend, _ := GetBackend(to)
|
backend, _ := GetBackend(to)
|
||||||
colors.Secondary.Printf("Backend: %s\n", backend.name)
|
colors.Secondary.Printf("Backend: %s\n", backend.name)
|
||||||
env, err := backend.getEnv()
|
env, err := backend.getEnv()
|
||||||
@ -187,6 +191,13 @@ func (l Location) Backup(cron bool) []error {
|
|||||||
errors = append(errors, err)
|
errors = append(errors, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
md := metadata.ExtractMetadataFromBackupLog(out)
|
||||||
|
mdEnv := metadata.MakeEnvFromMetadata(&md)
|
||||||
|
for k, v := range mdEnv {
|
||||||
|
options.Envs[k+"_"+fmt.Sprint(i)] = v
|
||||||
|
options.Envs[k+"_"+strings.ToUpper(backend.name)] = v
|
||||||
|
}
|
||||||
if VERBOSE {
|
if VERBOSE {
|
||||||
colors.Faint.Println(out)
|
colors.Faint.Println(out)
|
||||||
}
|
}
|
||||||
|
22
internal/metadata/extractor_added.go
Normal file
22
internal/metadata/extractor_added.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package metadata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type addedExtractor struct {
|
||||||
|
re *regexp.Regexp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e addedExtractor) Matches(line string) bool {
|
||||||
|
return e.re.MatchString(line)
|
||||||
|
}
|
||||||
|
func (e addedExtractor) Extract(metadata *BackupLogMetadata, line string) {
|
||||||
|
// Sample line: "Added to the repo: 0 B"
|
||||||
|
metadata.AddedSize = strings.TrimSpace(e.re.ReplaceAllString(line, ""))
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAddedExtractor() MetadatExtractor {
|
||||||
|
return addedExtractor{regexp.MustCompile(`(?i)^Added to the repo:`)}
|
||||||
|
}
|
57
internal/metadata/extractor_changeset.go
Normal file
57
internal/metadata/extractor_changeset.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package metadata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ChangeSetExtractor struct {
|
||||||
|
re *regexp.Regexp
|
||||||
|
cleaner *regexp.Regexp
|
||||||
|
saver changeSetSaver
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ChangeSetExtractor) Matches(line string) bool {
|
||||||
|
return e.re.MatchString(line)
|
||||||
|
}
|
||||||
|
func (e ChangeSetExtractor) Extract(metadata *BackupLogMetadata, line string) {
|
||||||
|
// Sample line: "Files: 0 new, 0 changed, 2 unmodified"
|
||||||
|
trimmed := strings.TrimSpace(e.re.ReplaceAllString(line, ""))
|
||||||
|
splitted := strings.Split(trimmed, ",")
|
||||||
|
var changeset BackupLogMetadataChangeset = BackupLogMetadataChangeset{}
|
||||||
|
changeset.Added = e.cleaner.ReplaceAllString(splitted[0], "")
|
||||||
|
changeset.Changed = e.cleaner.ReplaceAllString(splitted[1], "")
|
||||||
|
changeset.Unmodified = e.cleaner.ReplaceAllString(splitted[2], "")
|
||||||
|
e.saver.Save(metadata, changeset)
|
||||||
|
}
|
||||||
|
|
||||||
|
type changeSetSaver interface {
|
||||||
|
Save(metadata *BackupLogMetadata, changeset BackupLogMetadataChangeset)
|
||||||
|
}
|
||||||
|
|
||||||
|
type fileSaver struct{}
|
||||||
|
|
||||||
|
func (f fileSaver) Save(metadata *BackupLogMetadata, changeset BackupLogMetadataChangeset) {
|
||||||
|
metadata.Files = changeset
|
||||||
|
}
|
||||||
|
|
||||||
|
type dirsSaver struct{}
|
||||||
|
|
||||||
|
func (d dirsSaver) Save(metadata *BackupLogMetadata, changeset BackupLogMetadataChangeset) {
|
||||||
|
metadata.Dirs = changeset
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFilesExtractor() MetadatExtractor {
|
||||||
|
return ChangeSetExtractor{
|
||||||
|
re: regexp.MustCompile(`(?i)^Files:`),
|
||||||
|
cleaner: regexp.MustCompile(`[^\d]`),
|
||||||
|
saver: fileSaver{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func NewDirsExtractor() MetadatExtractor {
|
||||||
|
return ChangeSetExtractor{
|
||||||
|
re: regexp.MustCompile(`(?i)^Dirs:`),
|
||||||
|
cleaner: regexp.MustCompile(`[^\d]`),
|
||||||
|
saver: dirsSaver{},
|
||||||
|
}
|
||||||
|
}
|
22
internal/metadata/extractor_parent.go
Normal file
22
internal/metadata/extractor_parent.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package metadata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type parentSnapshotIDExtractor struct {
|
||||||
|
re *regexp.Regexp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e parentSnapshotIDExtractor) Matches(line string) bool {
|
||||||
|
return e.re.MatchString(line)
|
||||||
|
}
|
||||||
|
func (e parentSnapshotIDExtractor) Extract(metadata *BackupLogMetadata, line string) {
|
||||||
|
// Sample line: "using parent snapshot c65d9310"
|
||||||
|
metadata.ParentSnapshotID = strings.TrimSpace(e.re.ReplaceAllString(line, ""))
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewParentSnapshotIDExtractor() MetadatExtractor {
|
||||||
|
return parentSnapshotIDExtractor{regexp.MustCompile(`(?i)^using parent snapshot`)}
|
||||||
|
}
|
32
internal/metadata/extractor_processed.go
Normal file
32
internal/metadata/extractor_processed.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package metadata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type processedExtractor struct {
|
||||||
|
re *regexp.Regexp
|
||||||
|
cleaner *regexp.Regexp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e processedExtractor) Matches(line string) bool {
|
||||||
|
return e.re.MatchString(line)
|
||||||
|
}
|
||||||
|
func (e processedExtractor) Extract(metadata *BackupLogMetadata, line string) {
|
||||||
|
// Sample line: "processed 2 files, 24 B in 0:00"
|
||||||
|
var processed = BackupLogMetadataProcessed{}
|
||||||
|
split := strings.Split(line, "in")
|
||||||
|
processed.Duration = strings.TrimSpace(split[1])
|
||||||
|
split = strings.Split(split[0], ",")
|
||||||
|
processed.Files = e.cleaner.ReplaceAllString(split[0], "")
|
||||||
|
processed.Size = strings.TrimSpace(split[1])
|
||||||
|
metadata.Processed = processed
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProcessedExtractor() MetadatExtractor {
|
||||||
|
return processedExtractor{
|
||||||
|
regexp.MustCompile(`(?i)^processed \d* files`),
|
||||||
|
regexp.MustCompile(`(?i)[^\d]`),
|
||||||
|
}
|
||||||
|
}
|
22
internal/metadata/extractor_snapshot.go
Normal file
22
internal/metadata/extractor_snapshot.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package metadata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type snapshotExtractor struct {
|
||||||
|
re *regexp.Regexp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e snapshotExtractor) Matches(line string) bool {
|
||||||
|
return e.re.MatchString(line)
|
||||||
|
}
|
||||||
|
func (e snapshotExtractor) Extract(metadata *BackupLogMetadata, line string) {
|
||||||
|
// Sample line: "snapshot 917c7691 saved"
|
||||||
|
metadata.SnapshotID = strings.Split(line, " ")[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSnapshotExtractor() MetadatExtractor {
|
||||||
|
return snapshotExtractor{regexp.MustCompile(`(?i)^snapshot \w+ saved`)}
|
||||||
|
}
|
72
internal/metadata/metadata.go
Normal file
72
internal/metadata/metadata.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package metadata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BackupLogMetadataChangeset struct {
|
||||||
|
Added string
|
||||||
|
Changed string
|
||||||
|
Unmodified string
|
||||||
|
}
|
||||||
|
type BackupLogMetadataProcessed struct {
|
||||||
|
Files string
|
||||||
|
Size string
|
||||||
|
Duration string
|
||||||
|
}
|
||||||
|
type BackupLogMetadata struct {
|
||||||
|
ParentSnapshotID string
|
||||||
|
Files BackupLogMetadataChangeset
|
||||||
|
Dirs BackupLogMetadataChangeset
|
||||||
|
AddedSize string
|
||||||
|
Processed BackupLogMetadataProcessed
|
||||||
|
SnapshotID string
|
||||||
|
}
|
||||||
|
|
||||||
|
type MetadatExtractor interface {
|
||||||
|
Matches(line string) bool
|
||||||
|
Extract(metadata *BackupLogMetadata, line string)
|
||||||
|
}
|
||||||
|
|
||||||
|
var extractors = []MetadatExtractor{
|
||||||
|
NewParentSnapshotIDExtractor(),
|
||||||
|
NewFilesExtractor(),
|
||||||
|
NewDirsExtractor(),
|
||||||
|
NewAddedExtractor(),
|
||||||
|
NewProcessedExtractor(),
|
||||||
|
NewSnapshotExtractor(),
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExtractMetadataFromBackupLog(log string) BackupLogMetadata {
|
||||||
|
var md BackupLogMetadata
|
||||||
|
for _, line := range strings.Split(log, "\n") {
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
for _, extractor := range extractors {
|
||||||
|
if extractor.Matches(line) {
|
||||||
|
extractor.Extract(&md, line)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return md
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeEnvFromMetadata(metadata *BackupLogMetadata) map[string]string {
|
||||||
|
env := make(map[string]string)
|
||||||
|
var prefix = "AUTORESTIC_"
|
||||||
|
|
||||||
|
env[prefix+"SNAPSHOT_ID"] = metadata.SnapshotID
|
||||||
|
env[prefix+"PARENT_SNAPSHOT_ID"] = metadata.ParentSnapshotID
|
||||||
|
env[prefix+"FILES_ADDED"] = metadata.Files.Added
|
||||||
|
env[prefix+"FILES_CHANGED"] = metadata.Files.Changed
|
||||||
|
env[prefix+"FILES_UNMODIFIED"] = metadata.Files.Unmodified
|
||||||
|
env[prefix+"DIRS_ADDED"] = metadata.Dirs.Added
|
||||||
|
env[prefix+"DIRS_CHANGED"] = metadata.Dirs.Changed
|
||||||
|
env[prefix+"DIRS_UNMODIFIED"] = metadata.Dirs.Unmodified
|
||||||
|
env[prefix+"ADDED_SIZE"] = metadata.AddedSize
|
||||||
|
env[prefix+"PROCESSED_FILES"] = metadata.Processed.Files
|
||||||
|
env[prefix+"PROCESSED_SIZE"] = metadata.Processed.Size
|
||||||
|
env[prefix+"PROCESSED_DURATION"] = metadata.Processed.Duration
|
||||||
|
|
||||||
|
return env
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user