restic-compose-backup/src/restic_compose_backup/backup_runner.py

64 lines
2.0 KiB
Python
Raw Permalink Normal View History

2019-11-15 15:47:40 +00:00
import logging
2019-04-17 01:28:07 +00:00
import os
2019-12-07 23:57:23 +00:00
from restic_compose_backup import utils
2019-04-17 01:28:07 +00:00
2019-11-15 15:47:40 +00:00
logger = logging.getLogger(__name__)
2019-04-17 02:38:15 +00:00
2019-04-18 01:52:28 +00:00
def run(image: str = None, command: str = None, volumes: dict = None,
environment: dict = None, labels: dict = None, source_container_id: str = None):
2019-11-15 15:47:40 +00:00
logger.info("Starting backup container")
2019-12-07 23:57:23 +00:00
client = utils.docker_client()
2019-04-17 01:28:07 +00:00
container = client.containers.run(
2019-04-17 02:38:15 +00:00
image,
command,
2019-04-18 01:52:28 +00:00
labels=labels,
# auto_remove=True, # We remove the container further down
2019-04-17 01:28:07 +00:00
detach=True,
environment=environment + ['BACKUP_PROCESS_CONTAINER=true'],
volumes=volumes,
network_mode=f'container:{source_container_id}', # Reuse original container's network stack.
2019-04-17 01:28:07 +00:00
working_dir=os.getcwd(),
2019-04-18 05:22:59 +00:00
tty=True,
2019-04-17 01:28:07 +00:00
)
2019-11-15 15:47:40 +00:00
logger.info("Backup process container: %s", container.name)
2019-04-18 05:22:59 +00:00
log_generator = container.logs(stdout=True, stderr=True, stream=True, follow=True)
2019-11-15 15:47:40 +00:00
def readlines(stream):
"""Read stream line by line"""
while True:
line = ""
while True:
try:
# Make log streaming work for docker ce 17 and 18.
# For some reason strings are returned instead if bytes.
data = next(stream)
if isinstance(data, bytes):
line += data.decode()
elif isinstance(data, str):
line += data
2019-11-15 15:47:40 +00:00
if line.endswith('\n'):
break
except StopIteration:
break
if line:
yield line.rstrip()
2019-11-15 15:47:40 +00:00
else:
break
2019-04-18 05:22:59 +00:00
with open('backup.log', 'w') as fd:
2019-11-15 15:47:40 +00:00
for line in readlines(log_generator):
2019-04-18 05:22:59 +00:00
fd.write(line)
2019-11-26 18:46:59 +00:00
fd.write('\n')
2019-11-15 15:47:40 +00:00
logger.info(line)
2019-12-06 07:21:21 +00:00
container.wait()
2019-04-18 05:22:59 +00:00
container.reload()
2019-12-03 06:36:48 +00:00
logger.debug("Container ExitCode %s", container.attrs['State']['ExitCode'])
2019-04-18 05:22:59 +00:00
container.remove()
2019-12-03 06:36:48 +00:00
return container.attrs['State']['ExitCode']