Compare commits
No commits in common. "4e2f50f79b6ef2c6e499fbca13fe3830b7c9f54d" and "6c178b514ab07a14dc42037cd2900cb82a8ba48b" have entirely different histories.
4e2f50f79b
...
6c178b514a
12 changed files with 23 additions and 113 deletions
|
@ -1,3 +0,0 @@
|
||||||
!/bin/bash
|
|
||||||
|
|
||||||
zfs send tank/nextcloud@test1 | ssh backup-receiver@10.0.0.5 sudo zfs recv tank/nextcloud
|
|
|
@ -9,29 +9,6 @@ defaults = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
|
||||||
'zfs/datasets'
|
|
||||||
)
|
|
||||||
def zfs(metadata):
|
|
||||||
datasets = {}
|
|
||||||
|
|
||||||
for other_node in repo.nodes:
|
|
||||||
if (
|
|
||||||
other_node.has_bundle('backup') and
|
|
||||||
other_node.metadata.get('backup/server') == node.name
|
|
||||||
):
|
|
||||||
datasets[f"tank/{other_node.metadata.get('id')}/fs"] = {
|
|
||||||
'mountpoint': f"/mnt/backups/{other_node.metadata.get('id')}",
|
|
||||||
'backup': False,
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
'zfs': {
|
|
||||||
'datasets': datasets,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'dns'
|
'dns'
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
path=$1
|
PATH=$1
|
||||||
|
SERVER=$(jq -r .server < /etc/backup/config.json)
|
||||||
|
|
||||||
if zfs list -H -o mountpoint | grep -q "$path"
|
if zfs list -H -o mountpoint | grep -q "$PATH"
|
||||||
then
|
then
|
||||||
/opt/backuo/backup_path_via_zfs "$path"
|
TYPE=zfs
|
||||||
elif test -d "$path"
|
elif test -d "$PATH"
|
||||||
then
|
then
|
||||||
/opt/backuo/backup_path_via_zfs "$path"
|
TYPE=directory
|
||||||
|
elif test -f "$PATH"
|
||||||
|
then
|
||||||
|
TYPE=file
|
||||||
else
|
else
|
||||||
echo "UNKNOWN PATH: $path"
|
echo "UNKNOWN TYPE: $PATH"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
|
|
||||||
path=$1
|
|
||||||
uuid=$(jq -r .client_uuid < /etc/backup/config.json)
|
|
||||||
server=$(jq -r .server_hostname < /etc/backup/config.json)
|
|
||||||
ssh="ssh -o StrictHostKeyChecking=no backup-receiver@$server"
|
|
||||||
|
|
||||||
source_dataset=$(zfs list -H -o mountpoint,name | grep -P "^$path\t" | cut -d $'\t' -f 2)
|
|
||||||
target_dataset="tank/$uuid/$source_dataset"
|
|
||||||
new_bookmark="auto-backup_$(date +"%Y-%m-%d_%H:%M:%S")"
|
|
||||||
|
|
||||||
echo "BACKUP ZFS DATASET - PATH: $path, SERVER: $server, UUID: $uuid, SOURCE_DATASET: $source_dataset, TARGET_DATASET: $TARGET_DATASET"
|
|
||||||
|
|
||||||
# if ! $SSH zfs list -t filesystem -H -o name | grep -q "^$TARGET_DATASET$"
|
|
||||||
# then
|
|
||||||
# echo "CREATING TARGET DATASET..."
|
|
||||||
# $ssh sudo zfs create -p -o mountpoint=none "$target_dataset"
|
|
||||||
# fi
|
|
||||||
|
|
||||||
zfs snap $source_dataset@$new_bookmark
|
|
||||||
|
|
||||||
if zfs list -t bookmark -H -o name | grep '#auto-backup' | wc -l | grep -q "^0$"
|
|
||||||
then
|
|
||||||
echo "INITIAL BACKUP"
|
|
||||||
zfs send -v "$source_dataset@$new_bookmark" | $ssh sudo zfs recv $target_dataset
|
|
||||||
else
|
|
||||||
echo "INCREMENTAL BACKUP"
|
|
||||||
last_bookmark=$(zfs list -t bookmark -H -o name | sort | tail -1 | cut -d '#' -f 2)
|
|
||||||
zfs send -v -i "#$last_bookmark" "$source_dataset@$new_bookmark" | $ssh sudo zfs recv $target_dataset
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$?" == "0" ]]
|
|
||||||
then
|
|
||||||
echo "SUCCESS"
|
|
||||||
zfs bookmark "$source_dataset@$new_bookmark" "$source_dataset#$new_bookmark"
|
|
||||||
zfs destroy "$source_dataset@$new_bookmark"
|
|
||||||
else
|
|
||||||
echo "ERROR"
|
|
||||||
zfs destroy "$source_dataset@$new_bookmark"
|
|
||||||
exit 99
|
|
||||||
fi
|
|
|
@ -1,27 +1,11 @@
|
||||||
from json import dumps
|
from json import dumps
|
||||||
|
|
||||||
directories['/opt/backup'] = {}
|
|
||||||
|
|
||||||
files['/opt/backup/backup_all'] = {
|
|
||||||
'mode': '700',
|
|
||||||
}
|
|
||||||
files['/opt/backup/backup_path'] = {
|
|
||||||
'mode': '700',
|
|
||||||
}
|
|
||||||
files['/opt/backup/backup_path_via_zfs'] = {
|
|
||||||
'mode': '700',
|
|
||||||
}
|
|
||||||
files['/opt/backup/backup_path_via_rsync'] = {
|
|
||||||
'mode': '700',
|
|
||||||
}
|
|
||||||
|
|
||||||
directories['/etc/backup'] = {}
|
directories['/etc/backup'] = {}
|
||||||
|
|
||||||
files['/etc/backup/config.json'] = {
|
files['/etc/backup/config.json'] = {
|
||||||
'content': dumps(
|
'content': dumps(
|
||||||
{
|
{
|
||||||
'server_hostname': repo.get_node(node.metadata.get('backup/server')).metadata.get('backup-server/hostname'),
|
'server_hostname': repo.get_node(node.metadata.get('backup/server')).metadata.get('backup-server/hostname'),
|
||||||
'client_uuid': node.metadata.get('id'),
|
|
||||||
'paths': sorted(set(node.metadata.get('backup/paths'))),
|
'paths': sorted(set(node.metadata.get('backup/paths'))),
|
||||||
},
|
},
|
||||||
indent=4,
|
indent=4,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
defaults = {
|
defaults = {
|
||||||
'apt': {
|
'apt': {
|
||||||
'packages': {
|
'packages': {
|
||||||
'jq': {},
|
|
||||||
'rsync': {},
|
'rsync': {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -63,9 +63,6 @@ defaults = {
|
||||||
'datasets': {
|
'datasets': {
|
||||||
'tank/nextcloud': {
|
'tank/nextcloud': {
|
||||||
'mountpoint': '/var/lib/nextcloud',
|
'mountpoint': '/var/lib/nextcloud',
|
||||||
'needed_by': [
|
|
||||||
'bundle:nextcloud',
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,27 +2,29 @@ for group, config in node.metadata.get('groups', {}).items():
|
||||||
groups[group] = config
|
groups[group] = config
|
||||||
|
|
||||||
for name, config in node.metadata.get('users').items():
|
for name, config in node.metadata.get('users').items():
|
||||||
|
users[name] = {
|
||||||
|
k:v for k,v in config.items() if k in [
|
||||||
|
"full_name", "gid", "groups", "home", "password_hash", "shell", "uid",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
directories[config['home']] = {
|
directories[config['home']] = {
|
||||||
'owner': name,
|
'owner': name,
|
||||||
'mode': '700',
|
'mode': '700',
|
||||||
}
|
}
|
||||||
|
|
||||||
files[f"{config['home']}/.ssh/id_{config['keytype']}"] = {
|
files[f"{config['home']}/.ssh/id_{config['keytype']}"] = {
|
||||||
'content': config['privkey'] + '\n',
|
'content': config['privkey'],
|
||||||
'owner': name,
|
'owner': name,
|
||||||
'mode': '0600',
|
'mode': '0600',
|
||||||
}
|
}
|
||||||
files[f"{config['home']}/.ssh/id_{config['keytype']}.pub"] = {
|
files[f"{config['home']}/.ssh/id_{config['keytype']}.pub"] = {
|
||||||
'content': config['pubkey'] + '\n',
|
'content': config['pubkey'],
|
||||||
'owner': name,
|
'owner': name,
|
||||||
'mode': '0600',
|
'mode': '0600',
|
||||||
}
|
}
|
||||||
files[config['home'] + '/.ssh/authorized_keys'] = {
|
files[config['home'] + '/.ssh/authorized_keys'] = {
|
||||||
'content': '\n'.join(sorted(config['authorized_keys'])) + '\n',
|
'content': '\n'.join(sorted(config['authorized_keys'])),
|
||||||
'owner': name,
|
'owner': name,
|
||||||
'mode': '0600',
|
'mode': '0600',
|
||||||
}
|
}
|
||||||
|
|
||||||
users[name] = config
|
|
||||||
for option in ['authorized_keys', 'privkey', 'pubkey', 'keytype']:
|
|
||||||
users[name].pop(option, None)
|
|
||||||
|
|
|
@ -26,12 +26,10 @@ svc_systemd = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, config in node.metadata.get('zfs/datasets', {}).items():
|
zfs_datasets = node.metadata.get('zfs/datasets')
|
||||||
zfs_datasets[name] = config
|
|
||||||
zfs_datasets[name].pop('backup', None)
|
|
||||||
|
|
||||||
for name, config in node.metadata.get('zfs/pools', {}).items():
|
for name, attrs in node.metadata.get('zfs/pools', {}).items():
|
||||||
zfs_pools[name] = config
|
zfs_pools[name] = attrs
|
||||||
|
|
||||||
# actions[f'pool_{name}_enable_trim'] = {
|
# actions[f'pool_{name}_enable_trim'] = {
|
||||||
# 'command': f'zpool set autotrim=on {name}',
|
# 'command': f'zpool set autotrim=on {name}',
|
||||||
|
|
|
@ -14,10 +14,6 @@ def create(node, path, options):
|
||||||
option_list.append("-o {}={}".format(quote(option), quote(value)))
|
option_list.append("-o {}={}".format(quote(option), quote(value)))
|
||||||
option_args = " ".join(option_list)
|
option_args = " ".join(option_list)
|
||||||
|
|
||||||
print("zfs create {} {}".format(
|
|
||||||
option_args,
|
|
||||||
quote(path),
|
|
||||||
))
|
|
||||||
node.run(
|
node.run(
|
||||||
"zfs create {} {}".format(
|
"zfs create {} {}".format(
|
||||||
option_args,
|
option_args,
|
||||||
|
|
|
@ -18,7 +18,7 @@ def generate_ad25519_key_pair(secret):
|
||||||
'-----BEGIN OPENSSH PRIVATE KEY-----',
|
'-----BEGIN OPENSSH PRIVATE KEY-----',
|
||||||
b64encode(deterministic_bytes).decode(),
|
b64encode(deterministic_bytes).decode(),
|
||||||
'-----END OPENSSH PRIVATE KEY-----',
|
'-----END OPENSSH PRIVATE KEY-----',
|
||||||
])
|
]) + '\n'
|
||||||
|
|
||||||
public_key = privkey_bytes.public_key().public_bytes(
|
public_key = privkey_bytes.public_key().public_bytes(
|
||||||
encoding=serialization.Encoding.OpenSSH,
|
encoding=serialization.Encoding.OpenSSH,
|
||||||
|
|
Loading…
Reference in a new issue