Skip to content

Commit

Permalink
feat: add option to add tags to db and minecraft containers
Browse files Browse the repository at this point in the history
Closes ZettaIO#6
  • Loading branch information
Silthus committed Nov 25, 2020
1 parent 9eb0501 commit 3a19623
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 16 deletions.
2 changes: 2 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/restic_compose_backup/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions src/restic_compose_backup/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def __init__(self, check=True):
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()
Expand Down
5 changes: 5 additions & 0 deletions src/restic_compose_backup/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,11 @@ def is_backup_process_container(self) -> bool:
"""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?"""
Expand Down
3 changes: 3 additions & 0 deletions src/restic_compose_backup/containers_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def backup(self):
config.repository,
self.backup_destination_path(),
self.dump_command(),
tags=self.tags
)

def backup_destination_path(self) -> str:
Expand Down Expand Up @@ -115,6 +116,7 @@ def backup(self):
config.repository,
self.backup_destination_path(),
self.dump_command(),
tags=self.tags
)

def backup_destination_path(self) -> str:
Expand Down Expand Up @@ -175,6 +177,7 @@ def backup(self):
config.repository,
self.backup_destination_path(),
self.dump_command(),
tags=self.tags
)

def backup_destination_path(self) -> str:
Expand Down
2 changes: 1 addition & 1 deletion src/restic_compose_backup/containers_minecraft.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def backup(self) -> bool:
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)
Expand Down
4 changes: 3 additions & 1 deletion src/restic_compose_backup/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@

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'
33 changes: 19 additions & 14 deletions src/restic_compose_backup/restic.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
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__)

Expand All @@ -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)
Expand Down Expand Up @@ -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',
Expand All @@ -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):
Expand Down
19 changes: 19 additions & 0 deletions src/restic_compose_backup/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down

0 comments on commit 3a19623

Please sign in to comment.