mirror of
https://github.com/cupcakearmy/autorestic.git
synced 2025-09-06 10:30:39 +00:00
Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
06ce8180fb | ||
81f513d77b | |||
e32521e6ea | |||
f5c5b39b30 | |||
e016c8defc | |||
a2e0a0c9cc | |||
|
f9b04ea342 | ||
770c9dd7d4 | |||
|
851bbe5776 | ||
|
8fb6bdb3c6 | ||
|
47f5d91e89 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -3,7 +3,8 @@ package-lock.json
|
|||||||
.idea
|
.idea
|
||||||
yarn.lock
|
yarn.lock
|
||||||
|
|
||||||
config.yml
|
|
||||||
bin
|
bin
|
||||||
lib
|
lib
|
||||||
data
|
data
|
||||||
|
|
||||||
|
.autorestic.yml
|
122
README.md
122
README.md
@@ -1,9 +1,129 @@
|
|||||||
# autorestic
|
# autorestic
|
||||||
High level CLI utility for restic
|
High backup level CLI utility for [restic](https://restic.net/).
|
||||||
|
|
||||||
|
Autorestic is a wrapper around the amazing [restic](https://restic.net/). While being amazing the restic cli can be a bit overwhelming and difficoult to manage if you habe many different location that you want to backup to multiple locations. This utility is aimed at making this easier 🙂
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 🌈 Features
|
||||||
|
|
||||||
|
- Config files, no CLI
|
||||||
|
- Predictable
|
||||||
|
- Backup locations to multiple backends
|
||||||
|
- Simple interface
|
||||||
|
- Fully encrypted
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```
|
```
|
||||||
curl -s https://raw.githubusercontent.com/CupCakeArmy/autorestic/master/install.sh | sh
|
curl -s https://raw.githubusercontent.com/CupCakeArmy/autorestic/master/install.sh | sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 🚀 Quickstart
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
|
||||||
|
First we need to configure our locations and backends. Simply create a `.autorestic.yml` either in your home directory of in the folder from which you will execute `autorestic`.
|
||||||
|
|
||||||
|
Optionally you can specify the location of your config file by passing it as argument: `autorestic -c ../path/config.yml`
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
locations:
|
||||||
|
home:
|
||||||
|
from: /home/me
|
||||||
|
to: remote
|
||||||
|
|
||||||
|
important:
|
||||||
|
from: /path/to/important/stuff
|
||||||
|
to:
|
||||||
|
- remote
|
||||||
|
- hdd
|
||||||
|
|
||||||
|
backends:
|
||||||
|
remote:
|
||||||
|
type: b2
|
||||||
|
path: 'myBucket:backup/home'
|
||||||
|
B2_ACCOUNT_ID: account_id
|
||||||
|
B2_ACCOUNT_KEY: account_key
|
||||||
|
|
||||||
|
hdd:
|
||||||
|
type: local
|
||||||
|
path: /mnt/my_external_storage
|
||||||
|
```
|
||||||
|
|
||||||
|
Then we check if everything is correct by running the `check` command. We will pass the `-a` (or `--all`) to tell autorestic to check all the locations.
|
||||||
|
|
||||||
|
```
|
||||||
|
autorestic check -a
|
||||||
|
```
|
||||||
|
|
||||||
|
If we would check only one location we could run the following: `autorestic -l home check`.
|
||||||
|
|
||||||
|
### Backup
|
||||||
|
|
||||||
|
```
|
||||||
|
autorestic backup -a
|
||||||
|
```
|
||||||
|
|
||||||
|
### Restore
|
||||||
|
|
||||||
|
```
|
||||||
|
autorestic restore -a -- --target /path/where/to/restore
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 🗂 Locations
|
||||||
|
|
||||||
|
A location simply a folder on your machine that restic will backup. The paths can be relative from the config file. A location can have multiple backends, so that the data is secured across multiple servers.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
locations:
|
||||||
|
my-location-name:
|
||||||
|
from: path/to/backup
|
||||||
|
to:
|
||||||
|
- name-of-backend
|
||||||
|
- also-backup-to-this-backend
|
||||||
|
```
|
||||||
|
|
||||||
|
## 💽 Backends
|
||||||
|
|
||||||
|
Backends are the place where you data will be saved. Backups are incremental and encrypted.
|
||||||
|
|
||||||
|
### Fields
|
||||||
|
|
||||||
|
##### `type`
|
||||||
|
|
||||||
|
Type of the backend see a list [here](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html)
|
||||||
|
|
||||||
|
Supported are:
|
||||||
|
- [Local](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#local)
|
||||||
|
- [Backblaze B2](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#backblaze-b2)
|
||||||
|
- [Amazon S3](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#amazon-s3)
|
||||||
|
- [Minio](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#minio-server)
|
||||||
|
- [Google Cloud Storage](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#google-cloud-storage)
|
||||||
|
- [Microsoft Azure Storage](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#microsoft-azure-blob-storage)
|
||||||
|
|
||||||
|
For each backend you need to specify the right variables as shown in the example below.
|
||||||
|
|
||||||
|
##### `path`
|
||||||
|
|
||||||
|
The path on the remote server.
|
||||||
|
For object storages as
|
||||||
|
|
||||||
|
##### Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
backends:
|
||||||
|
name-of-backend:
|
||||||
|
type: b2
|
||||||
|
path: 'myAccount:myBucket/my/path'
|
||||||
|
B2_ACCOUNT_ID: backblaze_account_id
|
||||||
|
B2_ACCOUNT_KEY: backblaze_account_key
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##### Note
|
||||||
|
|
||||||
|
Note that the data is automatically encrypted on the server. The key will be generated and added to your config file. Every backend will have a separate key. You should keep a copy of the keys somewhere in case your server dies. Otherwise DATA IS LOST!
|
||||||
|
|
||||||
|
@@ -1,18 +0,0 @@
|
|||||||
locations:
|
|
||||||
home:
|
|
||||||
from: /home/myUser
|
|
||||||
to: remote
|
|
||||||
important:
|
|
||||||
from: /path/to/important/stuff
|
|
||||||
to:
|
|
||||||
- remote
|
|
||||||
- hdd
|
|
||||||
backends:
|
|
||||||
remote:
|
|
||||||
type: b2
|
|
||||||
path: 'myBucket:backup/home'
|
|
||||||
B2_ACCOUNT_ID: account_id
|
|
||||||
B2_ACCOUNT_KEY: account_key
|
|
||||||
hdd:
|
|
||||||
type: local
|
|
||||||
path: /mnt/my_external_storage
|
|
BIN
docs/Sketch.png
Normal file
BIN
docs/Sketch.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 MiB |
@@ -23,15 +23,10 @@ export const { _: commands, ...flags } = minimist(process.argv.slice(2), {
|
|||||||
string: ['l', 'b'],
|
string: ['l', 'b'],
|
||||||
})
|
})
|
||||||
|
|
||||||
export const VERSION = '0.5'
|
export const VERSION = '0.6'
|
||||||
export const INSTALL_DIR = '/usr/local/bin'
|
export const INSTALL_DIR = '/usr/local/bin'
|
||||||
export const VERBOSE = flags.verbose
|
export const VERBOSE = flags.verbose
|
||||||
|
|
||||||
if (flags.version) {
|
|
||||||
console.log('version'.grey, VERSION)
|
|
||||||
process.exit(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const config = init()
|
export const config = init()
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
|
@@ -5,13 +5,17 @@ import { getEnvFromBackend } from './backend'
|
|||||||
import { Locations, Location } from './types'
|
import { Locations, Location } from './types'
|
||||||
import { exec, ConfigError } from './utils'
|
import { exec, ConfigError } from './utils'
|
||||||
import { CONFIG_FILE } from './config'
|
import { CONFIG_FILE } from './config'
|
||||||
import { resolve, dirname } from 'path'
|
import { resolve, dirname, isAbsolute } from 'path'
|
||||||
|
|
||||||
export const backupSingle = (name: string, from: string, to: string) => {
|
export const backupSingle = (name: string, from: string, to: string) => {
|
||||||
if (!config) throw ConfigError
|
if (!config) throw ConfigError
|
||||||
const writer = new Writer(name + to.blue + ' : ' + 'Backing up... ⏳')
|
const writer = new Writer(name + to.blue + ' : ' + 'Backing up... ⏳')
|
||||||
const backend = config.backends[to]
|
const backend = config.backends[to]
|
||||||
const pathRelativeToConfigFile = resolve(dirname(CONFIG_FILE), from)
|
|
||||||
|
// Check if is an absolute path, otherwise get the path relative to the config file
|
||||||
|
const pathRelativeToConfigFile = isAbsolute(from)
|
||||||
|
? from
|
||||||
|
: resolve(dirname(CONFIG_FILE), from)
|
||||||
|
|
||||||
const cmd = exec('restic', ['backup', pathRelativeToConfigFile], {
|
const cmd = exec('restic', ['backup', pathRelativeToConfigFile], {
|
||||||
env: getEnvFromBackend(backend),
|
env: getEnvFromBackend(backend),
|
||||||
|
@@ -51,7 +51,7 @@ export const normalizeAndCheckBackups = (config: Config) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const findConfigFile = (): string => {
|
const findConfigFile = (): string | undefined => {
|
||||||
const config = '.autorestic.yml'
|
const config = '.autorestic.yml'
|
||||||
const paths = [
|
const paths = [
|
||||||
resolve(flags.config || ''),
|
resolve(flags.config || ''),
|
||||||
@@ -64,17 +64,14 @@ const findConfigFile = (): string => {
|
|||||||
if (file.isFile()) return path
|
if (file.isFile()) return path
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
throw new Error('No Config file found')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export let CONFIG_FILE: string = ''
|
export let CONFIG_FILE: string = ''
|
||||||
|
|
||||||
export const init = (): Config | undefined => {
|
export const init = (): Config | undefined => {
|
||||||
try {
|
const file = findConfigFile()
|
||||||
CONFIG_FILE = findConfigFile()
|
if (file) CONFIG_FILE = file
|
||||||
} catch (e) {
|
else return
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const raw: Config = makeObjectKeysLowercase(
|
const raw: Config = makeObjectKeysLowercase(
|
||||||
yaml.safeLoad(readFileSync(CONFIG_FILE).toString())
|
yaml.safeLoad(readFileSync(CONFIG_FILE).toString())
|
||||||
|
@@ -203,6 +203,9 @@ const handlers: Handlers = {
|
|||||||
|
|
||||||
w.done('All up to date! 🚀')
|
w.done('All up to date! 🚀')
|
||||||
},
|
},
|
||||||
|
version() {
|
||||||
|
console.log('version'.grey, VERSION)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const help = () => {
|
export const help = () => {
|
||||||
|
Reference in New Issue
Block a user