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/
[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:
- restic_compose_backup.env
- alerts.env
labels:
restic-compose-backup.volumes: true
restic-compose-backup.volumes.include: 'src'
volumes:
# Map in docker socket
- /var/run/docker.sock:/tmp/docker.sock:ro
@@ -20,7 +23,7 @@ services:
restic-compose-backup.volumes: true
restic-compose-backup.volumes.include: "/tests"
volumes:
- ./tests:/srv/tests
- ./src/tests:/srv/tests
- ./.vscode:/srv/code
environment:
- SOME_VALUE=test

View File

@@ -22,7 +22,7 @@ copyright = '2019, Zetta.IO Technology AS'
author = 'Zetta.IO Technology AS'
# The full version, including alpha/beta/rc tags
release = '0.4.0'
release = '0.4.2'
# -- 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/...```
DOCKER_BASE_URL
~~~~~~~~~~~~~~~
DOCKER_HOST
~~~~~~~~~~~
**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
--------------

View File

@@ -13,9 +13,9 @@ When releasing a bugfix version we need to update the
main image as well.
```bash
docker build src --tag zettaio/restic-compose-backup:0.3
docker build src --tag zettaio/restic-compose-backup:0.3.3
docker build src --tag zettaio/restic-compose-backup:0.4
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.3.3
docker push zettaio/restic-compose-backup:0.4
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
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_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,
# auto_remove=True, # We remove the container further down
detach=True,
environment=environment,
environment=environment + ['BACKUP_PROCESS_CONTAINER=true'],
volumes=volumes,
network_mode=f'container:{source_container_id}', # Reuse original container's network stack.
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("Repository: '%s'", config.repository)
logger.info("Backup currently running?: %s", containers.backup_process_running)
logger.info("Checking docker availability")
utils.list_containers()
if 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')
volumes.update(mounts)
logger.debug('Starting backup container with image %s', containers.this_container.image)
try:
result = backup_runner.run(
image=containers.this_container.image,
@@ -151,12 +155,18 @@ def backup(config, containers):
def start_backup_process(config, containers):
"""The actual backup process running inside the spawned container"""
if (not containers.backup_process_container
or containers.this_container == containers.backup_process_container is False):
if not utils.is_true(os.environ.get('BACKUP_PROCESS_CONTAINER')):
logger.error(
"Cannot run backup process in this container. Use backup command instead. "
"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)
status(config, containers)

View File

@@ -10,7 +10,6 @@ class Config:
# Mandatory values
self.repository = 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_command = os.environ.get('CRON_COMMAND') or self.default_backup_command

View File

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

View File

@@ -3,7 +3,6 @@ import logging
from typing import List
from contextlib import contextmanager
import docker
from restic_compose_backup.config import Config
logger = logging.getLogger(__name__)
@@ -11,8 +10,18 @@ TRUE_VALUES = ['1', 'true', 'True', True, 1]
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]:

View File

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

View File

@@ -160,7 +160,7 @@
"OpenStdin": true,
"StdinOnce": true,
"Env": [
"DOCKER_BASE_URL=unix://tmp/docker.sock",
"DOCKER_HOST=unix://tmp/docker.sock",
"RESTIC_REPOSITORY=/tmp/backup",
"RESTIC_PASSWORD=password",
"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)):
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")
web_service = result.get_service('web')
self.assertNotEqual(web_service, None)