12 Commits
0.4.1 ... 0.4.2

Author SHA1 Message Date
Einar Forselv
74c0954e6f pep8 2019-12-16 22:38:52 +01:00
Einar Forselv
f6995eb506 Update env var docs including docker config 2019-12-16 22:36:23 +01:00
Einar Forselv
ef28baed5e Update fixtures 2019-12-16 22:36:04 +01:00
Einar Forselv
336cace237 Bump version 2019-12-16 22:21:11 +01:00
Einar Forselv
cab4676b91 Create docker client from standard env vars 2019-12-16 22:19:57 +01:00
Einar Forselv
d002ad9390 Update env example 2019-12-16 22:19:05 +01:00
Einar Forselv
98a10bf994 Mark backup process container with env variable 2019-12-16 21:51:37 +01:00
Einar Forselv
2535ce3421 Add sponsor 2019-12-11 13:17:32 +01:00
Einar Forselv
8858f88ba4 Broken test 2019-12-10 17:28:35 +01:00
Einar Forselv
c5b7f11db7 Attempt to partly fix #18 2019-12-10 07:57:37 +01:00
Einar Forselv
a099060b2e Bump version 2019-12-09 06:33:31 +01:00
Einar Forselv
dd40152fe1 dev compose mapping incorrect tests dir 2019-12-09 06:32:31 +01:00
16 changed files with 68 additions and 22 deletions

BIN
.github/logo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -168,3 +168,8 @@ Contributions are welcome regardless of experience level. Don't hesitate submitt
[restic]: https://restic.net/ [restic]: https://restic.net/
[documentation]: https://restic-compose-backup.readthedocs.io [documentation]: https://restic-compose-backup.readthedocs.io
---
This project is sponsored by [zetta.io](https://www.zetta.io)
[![Zetta.IO](https://raw.githubusercontent.com/ZettaIO/restic-compose-backup/master/.github/logo.png)](https://www.zetta.io)

View File

@@ -5,6 +5,9 @@ services:
env_file: env_file:
- restic_compose_backup.env - restic_compose_backup.env
- alerts.env - alerts.env
labels:
restic-compose-backup.volumes: true
restic-compose-backup.volumes.include: 'src'
volumes: volumes:
# Map in docker socket # Map in docker socket
- /var/run/docker.sock:/tmp/docker.sock:ro - /var/run/docker.sock:/tmp/docker.sock:ro
@@ -20,7 +23,7 @@ services:
restic-compose-backup.volumes: true restic-compose-backup.volumes: true
restic-compose-backup.volumes.include: "/tests" restic-compose-backup.volumes.include: "/tests"
volumes: volumes:
- ./tests:/srv/tests - ./src/tests:/srv/tests
- ./.vscode:/srv/code - ./.vscode:/srv/code
environment: environment:
- SOME_VALUE=test - SOME_VALUE=test

View File

@@ -22,7 +22,7 @@ copyright = '2019, Zetta.IO Technology AS'
author = 'Zetta.IO Technology AS' author = 'Zetta.IO Technology AS'
# The full version, including alpha/beta/rc tags # The full version, including alpha/beta/rc tags
release = '0.4.0' release = '0.4.2'
# -- General configuration --------------------------------------------------- # -- General configuration ---------------------------------------------------

View File

@@ -166,12 +166,27 @@ a webhook that will post embedded messages to a specific channel.
The url usually looks like this: ``https://discordapp.com/api/webhooks/...``` The url usually looks like this: ``https://discordapp.com/api/webhooks/...```
DOCKER_BASE_URL DOCKER_HOST
~~~~~~~~~~~~~~~ ~~~~~~~~~~~
**Default value**: ``unix://tmp/docker.sock`` **Default value**: ``unix://tmp/docker.sock``
The location of the docker socket. The socket or host of the docker service.
DOCKER_TLS_VERIFY
~~~~~~~~~~~~~~~~~
If defined verify the host against a CA certificate.
Path to certs is defined in ``DOCKER_CERT_PATH``
and can be copied or mapped into this backup container.
DOCKER_CERT_PATH
~~~~~~~~~~~~~~~~
A path to a directory containing TLS certificates to use when
connecting to the Docker host. Combined with ``DOCKER_TLS_VERIFY``
this can be used to talk to docker through TLS in cases
were we cannot map in the docker socket.
Compose Labels Compose Labels
-------------- --------------

View File

@@ -13,9 +13,9 @@ When releasing a bugfix version we need to update the
main image as well. main image as well.
```bash ```bash
docker build src --tag zettaio/restic-compose-backup:0.3 docker build src --tag zettaio/restic-compose-backup:0.4
docker build src --tag zettaio/restic-compose-backup:0.3.3 docker build src --tag zettaio/restic-compose-backup:0.4.1
docker push zettaio/restic-compose-backup:0.3 docker push zettaio/restic-compose-backup:0.4
docker push zettaio/restic-compose-backup:0.3.3 docker push zettaio/restic-compose-backup:0.4.1
``` ```

View File

@@ -1,6 +1,9 @@
# DON'T COMMIT THIS FILE IF YOU MODIFY IN DEV # DON'T COMMIT THIS FILE IF YOU MODIFY IN DEV
DOCKER_BASE_URL=unix://tmp/docker.sock # DOCKER_HOST=unix://tmp/docker.sock
# DOCKER_TLS_VERIFY=1
# DOCKER_CERT_PATH=''
RESTIC_REPOSITORY=/restic_data RESTIC_REPOSITORY=/restic_data
RESTIC_PASSWORD=password RESTIC_PASSWORD=password

View File

@@ -1 +1 @@
__version__ = '0.4.0' __version__ = '0.4.2'

View File

@@ -17,7 +17,7 @@ def run(image: str = None, command: str = None, volumes: dict = None,
labels=labels, labels=labels,
# auto_remove=True, # We remove the container further down # auto_remove=True, # We remove the container further down
detach=True, detach=True,
environment=environment, environment=environment + ['BACKUP_PROCESS_CONTAINER=true'],
volumes=volumes, volumes=volumes,
network_mode=f'container:{source_container_id}', # Reuse original container's network stack. network_mode=f'container:{source_container_id}', # Reuse original container's network stack.
working_dir=os.getcwd(), working_dir=os.getcwd(),

View File

@@ -57,6 +57,9 @@ def status(config, containers):
logger.info("Status for compose project '%s'", containers.project_name) logger.info("Status for compose project '%s'", containers.project_name)
logger.info("Repository: '%s'", config.repository) logger.info("Repository: '%s'", config.repository)
logger.info("Backup currently running?: %s", containers.backup_process_running) logger.info("Backup currently running?: %s", containers.backup_process_running)
logger.info("Checking docker availability")
utils.list_containers()
if containers.stale_backup_process_containers: if containers.stale_backup_process_containers:
utils.remove_containers(containers.stale_backup_process_containers) utils.remove_containers(containers.stale_backup_process_containers)
@@ -117,6 +120,7 @@ def backup(config, containers):
mounts = containers.generate_backup_mounts('/volumes') mounts = containers.generate_backup_mounts('/volumes')
volumes.update(mounts) volumes.update(mounts)
logger.debug('Starting backup container with image %s', containers.this_container.image)
try: try:
result = backup_runner.run( result = backup_runner.run(
image=containers.this_container.image, image=containers.this_container.image,
@@ -151,12 +155,18 @@ def backup(config, containers):
def start_backup_process(config, containers): def start_backup_process(config, containers):
"""The actual backup process running inside the spawned container""" """The actual backup process running inside the spawned container"""
if (not containers.backup_process_container if not utils.is_true(os.environ.get('BACKUP_PROCESS_CONTAINER')):
or containers.this_container == containers.backup_process_container is False):
logger.error( logger.error(
"Cannot run backup process in this container. Use backup command instead. " "Cannot run backup process in this container. Use backup command instead. "
"This will spawn a new container with the necessary mounts." "This will spawn a new container with the necessary mounts."
) )
alerts.send(
subject="Cannot run backup process in this container",
body=(
"Cannot run backup process in this container. Use backup command instead. "
"This will spawn a new container with the necessary mounts."
)
)
exit(1) exit(1)
status(config, containers) status(config, containers)

View File

@@ -10,7 +10,6 @@ class Config:
# Mandatory values # Mandatory values
self.repository = os.environ.get('RESTIC_REPOSITORY') self.repository = os.environ.get('RESTIC_REPOSITORY')
self.password = os.environ.get('RESTIC_REPOSITORY') self.password = os.environ.get('RESTIC_REPOSITORY')
self.docker_base_url = os.environ.get('DOCKER_BASE_URL') or "unix://tmp/docker.sock"
self.cron_schedule = os.environ.get('CRON_SCHEDULE') or self.default_crontab_schedule self.cron_schedule = os.environ.get('CRON_SCHEDULE') or self.default_crontab_schedule
self.cron_command = os.environ.get('CRON_COMMAND') or self.default_backup_command self.cron_command = os.environ.get('CRON_COMMAND') or self.default_backup_command

View File

@@ -1,9 +1,11 @@
import os import os
import logging
from pathlib import Path from pathlib import Path
from typing import List from typing import List
from restic_compose_backup import enums, utils from restic_compose_backup import enums, utils
logger = logging.getLogger(__name__)
VOLUME_TYPE_BIND = "bind" VOLUME_TYPE_BIND = "bind"
VOLUME_TYPE_VOLUME = "volume" VOLUME_TYPE_VOLUME = "volume"
@@ -355,7 +357,7 @@ class RunningContainers:
# Detect containers belonging to the current compose setup # Detect containers belonging to the current compose setup
if (container.project_name == self.this_container.project_name if (container.project_name == self.this_container.project_name
and not container.is_oneoff): and not container.is_oneoff):
if container.id != self.this_container.id: if container != self.backup_process_container:
self.containers.append(container) self.containers.append(container)
@property @property

View File

@@ -3,7 +3,6 @@ import logging
from typing import List from typing import List
from contextlib import contextmanager from contextlib import contextmanager
import docker import docker
from restic_compose_backup.config import Config
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -11,8 +10,18 @@ TRUE_VALUES = ['1', 'true', 'True', True, 1]
def docker_client(): def docker_client():
config = Config() """
return docker.DockerClient(base_url=config.docker_base_url) Create a docker client from the following environment variables::
DOCKER_HOST=unix://tmp/docker.sock
DOCKER_TLS_VERIFY=1
DOCKER_CERT_PATH=''
"""
# NOTE: Remove this fallback in 1.0
if not os.environ.get('DOCKER_HOST'):
os.environ['DOCKER_HOST'] = 'unix://tmp/docker.sock'
return docker.from_env()
def list_containers() -> List[dict]: def list_containers() -> List[dict]:

View File

@@ -3,7 +3,7 @@ from setuptools import setup, find_namespace_packages
setup( setup(
name="restic-compose-backup", name="restic-compose-backup",
url="https://github.com/ZettaIO/restic-compose-backup", url="https://github.com/ZettaIO/restic-compose-backup",
version="0.4.0", version="0.4.2",
author="Einar Forselv", author="Einar Forselv",
author_email="eforselv@gmail.com", author_email="eforselv@gmail.com",
packages=find_namespace_packages(include=['restic_compose_backup']), packages=find_namespace_packages(include=['restic_compose_backup']),

View File

@@ -160,7 +160,7 @@
"OpenStdin": true, "OpenStdin": true,
"StdinOnce": true, "StdinOnce": true,
"Env": [ "Env": [
"DOCKER_BASE_URL=unix://tmp/docker.sock", "DOCKER_HOST=unix://tmp/docker.sock",
"RESTIC_REPOSITORY=/tmp/backup", "RESTIC_REPOSITORY=/tmp/backup",
"RESTIC_PASSWORD=password", "RESTIC_PASSWORD=password",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

View File

@@ -77,7 +77,7 @@ class ResticBackupTests(unittest.TestCase):
] ]
with mock.patch(list_containers_func, fixtures.containers(containers=containers)): with mock.patch(list_containers_func, fixtures.containers(containers=containers)):
result = RunningContainers() result = RunningContainers()
self.assertEqual(len(result.containers), 3, msg="Three containers expected") self.assertEqual(len(result.containers), 4, msg="Three containers expected")
self.assertNotEqual(result.this_container, None, msg="No backup container found") self.assertNotEqual(result.this_container, None, msg="No backup container found")
web_service = result.get_service('web') web_service = result.get_service('web')
self.assertNotEqual(web_service, None) self.assertNotEqual(web_service, None)