Rename project
This commit is contained in:
parent
2a861b0519
commit
fc5c6cc914
|
@ -2,8 +2,8 @@ FROM restic/restic:0.9.6
|
||||||
|
|
||||||
RUN apk update && apk add python3 dcron mariadb-client postgresql-client
|
RUN apk update && apk add python3 dcron mariadb-client postgresql-client
|
||||||
|
|
||||||
ADD . /restic-volume-backup
|
ADD . /restic-compose-backup
|
||||||
WORKDIR /restic-volume-backup
|
WORKDIR /restic-compose-backup
|
||||||
RUN pip3 install -U pip setuptools
|
RUN pip3 install -U pip setuptools
|
||||||
RUN pip3 install -e .
|
RUN pip3 install -e .
|
||||||
|
|
||||||
|
|
10
README.md
10
README.md
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
# restic-volume-backup
|
# restic-compose-backup
|
||||||
|
|
||||||
*WORK IN PROGRESS*
|
*WORK IN PROGRESS*
|
||||||
|
|
||||||
|
@ -67,8 +67,8 @@ A simple `include` and `exclude` filter is also available.
|
||||||
example:
|
example:
|
||||||
image: some_image
|
image: some_image
|
||||||
labels:
|
labels:
|
||||||
restic-volume-backup.enabled: true
|
restic-volume-backup.volumes: true
|
||||||
restic-volume-backup.include: "files,data"
|
restic-volume-backup.volumes.include: "files,data"
|
||||||
volumes:
|
volumes:
|
||||||
# Source don't match include filter. No backup.
|
# Source don't match include filter. No backup.
|
||||||
- media:/srv/media
|
- media:/srv/media
|
||||||
|
@ -88,8 +88,8 @@ Exclude
|
||||||
example:
|
example:
|
||||||
image: some_image
|
image: some_image
|
||||||
labels:
|
labels:
|
||||||
restic-volume-backup.enabled: true
|
restic-volume-backup.volumes: true
|
||||||
restic-volume-backup.exclude: "media"
|
restic-volume-backup.volumes.exclude: "media"
|
||||||
volumes:
|
volumes:
|
||||||
# Excluded by filter
|
# Excluded by filter
|
||||||
- media:/srv/media
|
- media:/srv/media
|
||||||
|
|
2
crontab
2
crontab
|
@ -1 +1 @@
|
||||||
1 * * * * source /env.sh && rvb backup > /proc/1/fd/1
|
1 * * * * source /env.sh && rcb backup > /proc/1/fd/1
|
||||||
|
|
|
@ -3,7 +3,7 @@ services:
|
||||||
backup:
|
backup:
|
||||||
build: .
|
build: .
|
||||||
env_file:
|
env_file:
|
||||||
- restic_volume_backup.env
|
- restic_compose_backup.env
|
||||||
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
|
||||||
|
@ -11,12 +11,12 @@ services:
|
||||||
- ./restic_data:/restic_data
|
- ./restic_data:/restic_data
|
||||||
- ./restic_cache:/restic_cache
|
- ./restic_cache:/restic_cache
|
||||||
# Map in project source
|
# Map in project source
|
||||||
- .:/restic-volume-backup
|
- .:/restic-compose-backup
|
||||||
web:
|
web:
|
||||||
image: nginx
|
image: nginx
|
||||||
labels:
|
labels:
|
||||||
restic-volume-backup.volumes: true
|
restic-compose-backup.volumes: true
|
||||||
restic-volume-backup.include: "/tests"
|
restic-compose-backup.volumes.include: "/tests"
|
||||||
volumes:
|
volumes:
|
||||||
- ./tests:/srv/tests
|
- ./tests:/srv/tests
|
||||||
- ./.vscode:/srv/code
|
- ./.vscode:/srv/code
|
||||||
|
@ -27,7 +27,7 @@ services:
|
||||||
mysql:
|
mysql:
|
||||||
image: mysql:5
|
image: mysql:5
|
||||||
labels:
|
labels:
|
||||||
restic-volume-backup.mysql: true
|
restic-compose-backup.mysql: true
|
||||||
environment:
|
environment:
|
||||||
- MYSQL_ROOT_PASSWORD=my-secret-pw
|
- MYSQL_ROOT_PASSWORD=my-secret-pw
|
||||||
- MYSQL_DATABASE=mydb
|
- MYSQL_DATABASE=mydb
|
||||||
|
@ -39,7 +39,7 @@ services:
|
||||||
mariadb:
|
mariadb:
|
||||||
image: mariadb:10
|
image: mariadb:10
|
||||||
labels:
|
labels:
|
||||||
restic-volume-backup.mariadb: true
|
restic-compose-backup.mariadb: true
|
||||||
environment:
|
environment:
|
||||||
- MYSQL_ROOT_PASSWORD=my-secret-pw
|
- MYSQL_ROOT_PASSWORD=my-secret-pw
|
||||||
- MYSQL_DATABASE=mydb
|
- MYSQL_DATABASE=mydb
|
||||||
|
@ -51,7 +51,7 @@ services:
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:11
|
image: postgres:11
|
||||||
labels:
|
labels:
|
||||||
restic-volume-backup.postgres: true
|
restic-compose-backup.postgres: true
|
||||||
environment:
|
environment:
|
||||||
- POSTGRES_USER=pguser
|
- POSTGRES_USER=pguser
|
||||||
- POSTGRES_PASSWORD=pgpassword
|
- POSTGRES_PASSWORD=pgpassword
|
||||||
|
|
|
@ -2,7 +2,7 @@ import logging
|
||||||
import os
|
import os
|
||||||
import docker
|
import docker
|
||||||
|
|
||||||
from restic_volume_backup.config import Config
|
from restic_compose_backup.config import Config
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
|
@ -2,11 +2,13 @@ import argparse
|
||||||
import pprint
|
import pprint
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from restic_volume_backup import log
|
from restic_compose_backup import (
|
||||||
from restic_volume_backup.config import Config
|
backup_runner,
|
||||||
from restic_volume_backup.containers import RunningContainers
|
log,
|
||||||
from restic_volume_backup import backup_runner
|
restic,
|
||||||
from restic_volume_backup import restic
|
)
|
||||||
|
from restic_compose_backup.config import Config
|
||||||
|
from restic_compose_backup.containers import RunningContainers
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -50,7 +52,7 @@ def status(config, containers):
|
||||||
logger.info(' - %s (is_ready=%s)', instance.container_type, ping == 0)
|
logger.info(' - %s (is_ready=%s)', instance.container_type, ping == 0)
|
||||||
|
|
||||||
if len(backup_containers) == 0:
|
if len(backup_containers) == 0:
|
||||||
logger.info("No containers in the project has 'restic-volume-backup.enabled' label")
|
logger.info("No containers in the project has 'restic-compose-backup.enabled' label")
|
||||||
|
|
||||||
|
|
||||||
def backup(config, containers):
|
def backup(config, containers):
|
||||||
|
@ -75,12 +77,12 @@ def backup(config, containers):
|
||||||
|
|
||||||
result = backup_runner.run(
|
result = backup_runner.run(
|
||||||
image=containers.this_container.image,
|
image=containers.this_container.image,
|
||||||
command='restic-volume-backup start-backup-process',
|
command='restic-compose-backup start-backup-process',
|
||||||
volumes=volumes,
|
volumes=volumes,
|
||||||
environment=containers.this_container.environment,
|
environment=containers.this_container.environment,
|
||||||
source_container_id=containers.this_container.id,
|
source_container_id=containers.this_container.id,
|
||||||
labels={
|
labels={
|
||||||
"restic-volume-backup.backup_process": 'True',
|
"restic-compose-backup.backup_process": 'True',
|
||||||
"com.docker.compose.project": containers.this_container.project_name,
|
"com.docker.compose.project": containers.this_container.project_name,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -125,7 +127,7 @@ def start_backup_process(config, containers):
|
||||||
|
|
||||||
|
|
||||||
def parse_args():
|
def parse_args():
|
||||||
parser = argparse.ArgumentParser(prog='restic_volume_backup')
|
parser = argparse.ArgumentParser(prog='restic_compose_backup')
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'action',
|
'action',
|
||||||
choices=['status', 'backup', 'start-backup-process'],
|
choices=['status', 'backup', 'start-backup-process'],
|
|
@ -2,7 +2,7 @@ import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from restic_volume_backup import utils
|
from restic_compose_backup import utils
|
||||||
|
|
||||||
VOLUME_TYPE_BIND = "bind"
|
VOLUME_TYPE_BIND = "bind"
|
||||||
VOLUME_TYPE_VOLUME = "volume"
|
VOLUME_TYPE_VOLUME = "volume"
|
||||||
|
@ -27,15 +27,15 @@ class Container:
|
||||||
if self._labels is None:
|
if self._labels is None:
|
||||||
raise ValueError('Container meta missing Config->Labels')
|
raise ValueError('Container meta missing Config->Labels')
|
||||||
|
|
||||||
self._include = self._parse_pattern(self.get_label('restic-volume-backup.include'))
|
self._include = self._parse_pattern(self.get_label('restic-compose-backup.volumes.include'))
|
||||||
self._exclude = self._parse_pattern(self.get_label('restic-volume-backup.exclude'))
|
self._exclude = self._parse_pattern(self.get_label('restic-compose-backup.volumes.exclude'))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def instance(self) -> 'Container':
|
def instance(self) -> 'Container':
|
||||||
"""Container: Get a service specific subclass instance"""
|
"""Container: Get a service specific subclass instance"""
|
||||||
# TODO: Do this smarter in the future (simple registry)
|
# TODO: Do this smarter in the future (simple registry)
|
||||||
if self.database_backup_enabled:
|
if self.database_backup_enabled:
|
||||||
from restic_volume_backup import containers_db
|
from restic_compose_backup import containers_db
|
||||||
if self.mariadb_backup_enabled:
|
if self.mariadb_backup_enabled:
|
||||||
return containers_db.MariadbContainer(self._data)
|
return containers_db.MariadbContainer(self._data)
|
||||||
if self.mysql_backup_enabled:
|
if self.mysql_backup_enabled:
|
||||||
|
@ -96,7 +96,7 @@ class Container:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def volume_backup_enabled(self) -> bool:
|
def volume_backup_enabled(self) -> bool:
|
||||||
return utils.is_true(self.get_label('restic-volume-backup.volumes'))
|
return utils.is_true(self.get_label('restic-compose-backup.volumes'))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def database_backup_enabled(self) -> bool:
|
def database_backup_enabled(self) -> bool:
|
||||||
|
@ -109,20 +109,20 @@ class Container:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mysql_backup_enabled(self) -> bool:
|
def mysql_backup_enabled(self) -> bool:
|
||||||
return utils.is_true(self.get_label('restic-volume-backup.mysql'))
|
return utils.is_true(self.get_label('restic-compose-backup.mysql'))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mariadb_backup_enabled(self) -> bool:
|
def mariadb_backup_enabled(self) -> bool:
|
||||||
return utils.is_true(self.get_label('restic-volume-backup.mariadb'))
|
return utils.is_true(self.get_label('restic-compose-backup.mariadb'))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def postgresql_backup_enabled(self) -> bool:
|
def postgresql_backup_enabled(self) -> bool:
|
||||||
return utils.is_true(self.get_label('restic-volume-backup.postgres'))
|
return utils.is_true(self.get_label('restic-compose-backup.postgres'))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_backup_process_container(self) -> bool:
|
def is_backup_process_container(self) -> bool:
|
||||||
"""Is this container the running backup process?"""
|
"""Is this container the running backup process?"""
|
||||||
return self.get_label('restic-volume-backup.backup_process') == 'True'
|
return self.get_label('restic-compose-backup.backup_process') == 'True'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_running(self) -> bool:
|
def is_running(self) -> bool:
|
|
@ -1,10 +1,10 @@
|
||||||
from restic_volume_backup.containers import Container
|
from restic_compose_backup.containers import Container
|
||||||
from restic_volume_backup.config import Config
|
from restic_compose_backup.config import Config
|
||||||
from restic_volume_backup import (
|
from restic_compose_backup import (
|
||||||
commands,
|
commands,
|
||||||
restic,
|
restic,
|
||||||
)
|
)
|
||||||
from restic_volume_backup import utils
|
from restic_compose_backup import utils
|
||||||
|
|
||||||
|
|
||||||
class MariadbContainer(Container):
|
class MariadbContainer(Container):
|
|
@ -2,7 +2,7 @@ import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
logger = logging.getLogger('restic_volume_backup')
|
logger = logging.getLogger('restic_compose_backup')
|
||||||
HOSTNAME = os.environ['HOSTNAME']
|
HOSTNAME = os.environ['HOSTNAME']
|
||||||
|
|
||||||
level = logging.INFO
|
level = logging.INFO
|
|
@ -16,7 +16,7 @@ def main():
|
||||||
|
|
||||||
def send_mail(text):
|
def send_mail(text):
|
||||||
msg = MIMEText(text)
|
msg = MIMEText(text)
|
||||||
msg['Subject'] = "Message from restic-volume-backup"
|
msg['Subject'] = "Message from restic-compose-backup"
|
||||||
msg['From'] = EMAIL_HOST_USER
|
msg['From'] = EMAIL_HOST_USER
|
||||||
msg['To'] = ', '.join(EMAIL_SEND_TO)
|
msg['To'] = ', '.join(EMAIL_SEND_TO)
|
||||||
|
|
|
@ -4,7 +4,7 @@ Restic commands
|
||||||
import logging
|
import logging
|
||||||
from typing import List
|
from typing import List
|
||||||
from subprocess import Popen, PIPE
|
from subprocess import Popen, PIPE
|
||||||
from restic_volume_backup import commands
|
from restic_compose_backup import commands
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
|
@ -2,7 +2,7 @@ import os
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
import docker
|
import docker
|
||||||
|
|
||||||
from restic_volume_backup.config import Config
|
from restic_compose_backup.config import Config
|
||||||
|
|
||||||
TRUE_VALUES = ['1', 'true', 'True', True, 1]
|
TRUE_VALUES = ['1', 'true', 'True', True, 1]
|
||||||
|
|
12
setup.py
12
setup.py
|
@ -1,17 +1,17 @@
|
||||||
from setuptools import setup, find_namespace_packages
|
from setuptools import setup, find_namespace_packages
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="restic-volume-backup",
|
name="restic-compose-backup",
|
||||||
url="https://github.com/ZettaIO/restic-volume-backup",
|
url="https://github.com/ZettaIO/restic-compose-backup",
|
||||||
version="1.0.0",
|
version="0.2.0",
|
||||||
author="Einar Forselv",
|
author="Einar Forselv",
|
||||||
author_email="eforselv@gmail.com",
|
author_email="eforselv@gmail.com",
|
||||||
packages=find_namespace_packages(include=['restic_volume_backup']),
|
packages=find_namespace_packages(include=['restic_compose_backup']),
|
||||||
install_requires=[
|
install_requires=[
|
||||||
'docker==3.7.2',
|
'docker==3.7.2',
|
||||||
],
|
],
|
||||||
entry_points={'console_scripts': [
|
entry_points={'console_scripts': [
|
||||||
'restic-volume-backup = restic_volume_backup.cli:main',
|
'restic-compose-backup = restic_compose_backup.cli:main',
|
||||||
'rvb = restic_volume_backup.cli:main',
|
'rcb = restic_compose_backup.cli:main',
|
||||||
]},
|
]},
|
||||||
)
|
)
|
||||||
|
|
|
@ -35,7 +35,7 @@ def containers(project="default", containers=[]):
|
||||||
'Id': container.get('id', generate_sha256()),
|
'Id': container.get('id', generate_sha256()),
|
||||||
'Name': container.get('service') + '_' + ''.join(random.choice(string.ascii_lowercase) for i in range(16)),
|
'Name': container.get('service') + '_' + ''.join(random.choice(string.ascii_lowercase) for i in range(16)),
|
||||||
'Config': {
|
'Config': {
|
||||||
'Image': 'restic-volume-backup_backup',
|
'Image': 'restic-compose-backup_backup',
|
||||||
'Labels': {
|
'Labels': {
|
||||||
'com.docker.compose.oneoff': 'False',
|
'com.docker.compose.oneoff': 'False',
|
||||||
'com.docker.compose.project': project,
|
'com.docker.compose.project': project,
|
||||||
|
|
|
@ -3,11 +3,11 @@ import os
|
||||||
import unittest
|
import unittest
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
from restic_volume_backup import utils
|
from restic_compose_backup import utils
|
||||||
from restic_volume_backup.containers import RunningContainers
|
from restic_compose_backup.containers import RunningContainers
|
||||||
import fixtures
|
import fixtures
|
||||||
|
|
||||||
list_containers_func = 'restic_volume_backup.utils.list_containers'
|
list_containers_func = 'restic_compose_backup.utils.list_containers'
|
||||||
|
|
||||||
|
|
||||||
class ResticBackupTests(unittest.TestCase):
|
class ResticBackupTests(unittest.TestCase):
|
||||||
|
@ -88,7 +88,7 @@ class ResticBackupTests(unittest.TestCase):
|
||||||
{
|
{
|
||||||
'service': 'web',
|
'service': 'web',
|
||||||
'labels': {
|
'labels': {
|
||||||
'restic-volume-backup.volumes': True,
|
'restic-compose-backup.volumes': True,
|
||||||
},
|
},
|
||||||
'mounts': [{
|
'mounts': [{
|
||||||
'Source': 'test',
|
'Source': 'test',
|
||||||
|
@ -99,7 +99,7 @@ class ResticBackupTests(unittest.TestCase):
|
||||||
{
|
{
|
||||||
'service': 'mysql',
|
'service': 'mysql',
|
||||||
'labels': {
|
'labels': {
|
||||||
'restic-volume-backup.mysql': True,
|
'restic-compose-backup.mysql': True,
|
||||||
},
|
},
|
||||||
'mounts': [{
|
'mounts': [{
|
||||||
'Source': 'data',
|
'Source': 'data',
|
||||||
|
@ -119,7 +119,7 @@ class ResticBackupTests(unittest.TestCase):
|
||||||
{
|
{
|
||||||
'service': 'web',
|
'service': 'web',
|
||||||
'labels': {
|
'labels': {
|
||||||
'restic-volume-backup.include': 'media',
|
'restic-compose-backup.include': 'media',
|
||||||
},
|
},
|
||||||
'mounts': [
|
'mounts': [
|
||||||
{
|
{
|
||||||
|
@ -151,7 +151,7 @@ class ResticBackupTests(unittest.TestCase):
|
||||||
{
|
{
|
||||||
'service': 'web',
|
'service': 'web',
|
||||||
'labels': {
|
'labels': {
|
||||||
'restic-volume-backup.exclude': 'stuff',
|
'restic-compose-backup.exclude': 'stuff',
|
||||||
},
|
},
|
||||||
'mounts': [
|
'mounts': [
|
||||||
{
|
{
|
||||||
|
@ -187,7 +187,7 @@ class ResticBackupTests(unittest.TestCase):
|
||||||
{
|
{
|
||||||
'service': 'backup_runner',
|
'service': 'backup_runner',
|
||||||
'labels': {
|
'labels': {
|
||||||
'restic-volume-backup.backup_process': 'True',
|
'restic-compose-backup.backup_process': 'True',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in New Issue