feat: Backup Secrets (copy secrets) #28
This commit is contained in:
parent
ebc0ea5d84
commit
5d4def6143
30
backupbot.py
30
backupbot.py
|
@ -9,9 +9,11 @@ import docker
|
||||||
import restic
|
import restic
|
||||||
from restic.errors import ResticFailedError
|
from restic.errors import ResticFailedError
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from shutil import copyfile, rmtree
|
||||||
#logging.basicConfig(level=logging.INFO)
|
#logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
VOLUME_PATH = "/var/lib/docker/volumes/"
|
VOLUME_PATH = "/var/lib/docker/volumes/"
|
||||||
|
SECRET_PATH = '/secrets/'
|
||||||
SERVICE = None
|
SERVICE = None
|
||||||
|
|
||||||
@click.group()
|
@click.group()
|
||||||
|
@ -53,14 +55,15 @@ def export_secrets():
|
||||||
@cli.command()
|
@cli.command()
|
||||||
def create():
|
def create():
|
||||||
pre_commands, post_commands, backup_paths, apps = get_backup_cmds()
|
pre_commands, post_commands, backup_paths, apps = get_backup_cmds()
|
||||||
|
copy_secrets(apps)
|
||||||
|
backup_paths.append(SECRET_PATH)
|
||||||
run_commands(pre_commands)
|
run_commands(pre_commands)
|
||||||
backup_volumes(backup_paths, apps)
|
backup_volumes(backup_paths, apps)
|
||||||
run_commands(post_commands)
|
run_commands(post_commands)
|
||||||
|
|
||||||
def get_backup_cmds():
|
def get_backup_cmds():
|
||||||
client = docker.from_env()
|
client = docker.from_env()
|
||||||
containers = dict(map(lambda c: (
|
container_by_service = {c.labels['com.docker.swarm.service.name']: c for c in client.containers.list()}
|
||||||
c.labels['com.docker.swarm.service.name'], c), client.containers.list()))
|
|
||||||
backup_paths = set()
|
backup_paths = set()
|
||||||
backup_apps = set()
|
backup_apps = set()
|
||||||
pre_commands = {}
|
pre_commands = {}
|
||||||
|
@ -73,7 +76,9 @@ def get_backup_cmds():
|
||||||
if SERVICE and SERVICE != stack_name:
|
if SERVICE and SERVICE != stack_name:
|
||||||
continue
|
continue
|
||||||
backup_apps.add(stack_name)
|
backup_apps.add(stack_name)
|
||||||
container = containers[s.name]
|
container = container_by_service.get(s.name)
|
||||||
|
if not container:
|
||||||
|
logging.error("Container {s.name} is not running, hooks can not be executed")
|
||||||
if prehook:= labels.get('backupbot.backup.pre-hook'):
|
if prehook:= labels.get('backupbot.backup.pre-hook'):
|
||||||
pre_commands[container] = prehook
|
pre_commands[container] = prehook
|
||||||
if posthook:= labels.get('backupbot.backup.post-hook'):
|
if posthook:= labels.get('backupbot.backup.post-hook'):
|
||||||
|
@ -82,6 +87,25 @@ def get_backup_cmds():
|
||||||
Path(VOLUME_PATH).glob(f"{stack_name}_*"))
|
Path(VOLUME_PATH).glob(f"{stack_name}_*"))
|
||||||
return pre_commands, post_commands, list(backup_paths), list(backup_apps)
|
return pre_commands, post_commands, list(backup_paths), list(backup_apps)
|
||||||
|
|
||||||
|
def copy_secrets(apps):
|
||||||
|
rmtree(SECRET_PATH, ignore_errors=True)
|
||||||
|
os.mkdir(SECRET_PATH)
|
||||||
|
client = docker.from_env()
|
||||||
|
container_by_service = {c.labels['com.docker.swarm.service.name']: c for c in client.containers.list()}
|
||||||
|
services = client.services.list()
|
||||||
|
for s in services:
|
||||||
|
app_name = s.attrs['Spec']['Labels']['com.docker.stack.namespace']
|
||||||
|
if app_name in apps:
|
||||||
|
if app_secs:= s.attrs['Spec']['TaskTemplate']['ContainerSpec'].get('Secrets'):
|
||||||
|
if not container_by_service.get(s.name):
|
||||||
|
logging.error("Container {s.name} is not running, secrets can not be copied.")
|
||||||
|
continue
|
||||||
|
container_id = container_by_service[s.name].id
|
||||||
|
for sec in app_secs:
|
||||||
|
src = f'/var/lib/docker/containers/{container_id}/mounts/secrets/{sec["SecretID"]}'
|
||||||
|
dst = SECRET_PATH + sec['SecretName']
|
||||||
|
copyfile(src, dst)
|
||||||
|
|
||||||
def run_commands(commands):
|
def run_commands(commands):
|
||||||
for container, command in commands.items():
|
for container, command in commands.items():
|
||||||
if not command:
|
if not command:
|
||||||
|
|
|
@ -6,6 +6,7 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- "/var/run/docker.sock:/var/run/docker.sock"
|
- "/var/run/docker.sock:/var/run/docker.sock"
|
||||||
- "/var/lib/docker/volumes/:/var/lib/docker/volumes/"
|
- "/var/lib/docker/volumes/:/var/lib/docker/volumes/"
|
||||||
|
- "/var/lib/docker/containers/:/var/lib/docker/containers/:ro"
|
||||||
- backups:/backups
|
- backups:/backups
|
||||||
environment:
|
environment:
|
||||||
- CRON_SCHEDULE
|
- CRON_SCHEDULE
|
||||||
|
|
Loading…
Reference in New Issue