feat: add option to add tags to db and minecraft containers

Closes #6
This commit is contained in:
Silthus 2020-11-25 19:32:32 +01:00
parent 9eb050173f
commit 3a19623351
9 changed files with 54 additions and 16 deletions

View File

@ -48,6 +48,7 @@ services:
image: mariadb:10
labels:
restic-compose-backup.mariadb: true
restic-compose-backup.tags: db,test
environment:
- MYSQL_ROOT_PASSWORD=my-secret-pw
- MYSQL_DATABASE=mydb
@ -71,6 +72,7 @@ services:
image: itzg/minecraft-server
labels:
restic-compose-backup.minecraft: true
restic-compose-backup.tags: "test,foo,bar"
restic-compose-backup.volumes.include: "minecraft"
environment:
- RCON_PASSWORD=minecraft

View File

@ -316,6 +316,7 @@ def cleanup(config, containers):
config.keep_monthly,
config.keep_yearly,
config.keep_tags,
config.filter_tags
)
logger.info('Prune stale data freeing storage space')
prune_result = restic.prune(config.repository)

View File

@ -28,6 +28,7 @@ class Config:
self.keep_monthly = os.environ.get('KEEP_MONTHLY') or "12"
self.keep_yearly = os.environ.get('KEEP_YEARLY') or "3"
self.keep_tags = os.environ.get('KEEP_TAGS') or "keep"
self.filter_tags = os.environ.get('FILTER_TAGS') or ""
if check:
self.check()

View File

@ -186,6 +186,11 @@ class Container:
"""Is this container the running backup process?"""
return self.get_label(self.backup_process_label) == 'True'
@property
def tags(self) -> str:
"""Gets all backup tags"""
return self.get_label(enums.LABEL_RESTIC_TAGS)
@property
def is_running(self) -> bool:
"""bool: Is the container running?"""

View File

@ -54,6 +54,7 @@ class MariadbContainer(Container):
config.repository,
self.backup_destination_path(),
self.dump_command(),
tags=self.tags
)
def backup_destination_path(self) -> str:
@ -115,6 +116,7 @@ class MysqlContainer(Container):
config.repository,
self.backup_destination_path(),
self.dump_command(),
tags=self.tags
)
def backup_destination_path(self) -> str:
@ -175,6 +177,7 @@ class PostgresContainer(Container):
config.repository,
self.backup_destination_path(),
self.dump_command(),
tags=self.tags
)
def backup_destination_path(self) -> str:

View File

@ -64,7 +64,7 @@ class MinecraftContainer(Container):
for mount in self.filter_mounts():
backup_data = self.get_volume_backup_destination(mount, '/minecraft')
logger.info('Backing up %s', mount.source)
vol_result = restic.backup_files(config.repository, source=backup_data)
vol_result = restic.backup_files(config.repository, source=backup_data, tags=self.tags)
logger.debug('Minecraft backup exit code: %s', vol_result)
if vol_result != 0:
logger.error('Minecraft backup exited with non-zero code: %s', vol_result)

View File

@ -10,4 +10,6 @@ LABEL_MARIADB_ENABLED = 'restic-compose-backup.mariadb'
LABEL_BACKUP_PROCESS = 'restic-compose-backup.process'
LABEL_MINECRAFT_ENABLED = 'restic-compose-backup.minecraft'
LABEL_MINECRAFT_ENABLED = 'restic-compose-backup.minecraft'
LABEL_RESTIC_TAGS = 'restic-compose-backup.tags'

View File

@ -4,7 +4,7 @@ Restic commands
import logging
from typing import List, Tuple
from subprocess import Popen, PIPE
from restic_compose_backup import commands
from restic_compose_backup import commands, utils
logger = logging.getLogger(__name__)
@ -19,25 +19,29 @@ def init_repo(repository: str):
]))
def backup_files(repository: str, source='/volumes'):
return commands.run(restic(repository, [
def backup_files(repository: str, source='/volumes', tags=''):
args = [
"--verbose",
"backup",
source,
]))
source
]
args.extend(utils.format_tags(tags))
return commands.run(restic(repository, args))
def backup_from_stdin(repository: str, filename: str, source_command: List[str]):
def backup_from_stdin(repository: str, filename: str, source_command: List[str], tags=''):
"""
Backs up from stdin running the source_command passed in.
It will appear in restic with the filename (including path) passed in.
"""
dest_command = restic(repository, [
args = [
'backup',
'--stdin',
'--stdin-filename',
filename,
])
]
args.extend(utils.format_tags(tags))
dest_command = restic(repository, args)
# pipe source command into dest command
source_process = Popen(source_command, stdout=PIPE, bufsize=65536)
@ -75,8 +79,8 @@ def is_initialized(repository: str) -> bool:
return commands.run(restic(repository, ["snapshots", '--last'])) == 0
def forget(repository: str, keeplast: str, hourly: str, daily: str, weekly: str, monthly: str, yearly: str, tags: str):
return commands.run(restic(repository, [
def forget(repository: str, keeplast: str, hourly: str, daily: str, weekly: str, monthly: str, yearly: str, keep_tags='', filter_tags=''):
args = [
'forget',
'--group-by',
'paths,tags',
@ -91,10 +95,11 @@ def forget(repository: str, keeplast: str, hourly: str, daily: str, weekly: str,
'--keep-monthly',
monthly,
'--keep-yearly',
yearly,
'--keep-tag',
tags,
]))
yearly
]
args.extend(utils.format_tags(keep_tags, '--keep-tag'))
args.extend(utils.format_tags(filter_tags))
return commands.run(restic(repository, args))
def prune(repository: str):

View File

@ -82,6 +82,25 @@ def strip_root(path):
return path
def format_tags(tags: str, arg = "--tag") -> List[str]:
"""
Takes a comma separated list of tags.
Splits them and appends --tag to each tag.
Use the output as the command line argument for the restic cli.
Example: foo,bar,test becomes --tag foo --tag bar --tag test
"""
if not tags:
return []
tags = tags.strip()
splitTags = tags.split(",")
output = []
for tag in splitTags:
tag = tag.strip()
if tag:
output.extend([arg, tag])
return output
@contextmanager
def environment(name, value):