Skip to content

Commit 450c9d6

Browse files
authored
Merge pull request #18 from tcorzo/feature/include-all-volumes #minor
Add INCLUDE_ALL_VOLUMES env var and related tests
2 parents e73e488 + 24531f6 commit 450c9d6

File tree

3 files changed

+126
-4
lines changed

3 files changed

+126
-4
lines changed

src/restic_compose_backup/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def __init__(self, check=True):
1515
self.swarm_mode = os.environ.get('SWARM_MODE') or False
1616
self.include_project_name = os.environ.get('INCLUDE_PROJECT_NAME') or False
1717
self.exclude_bind_mounts = os.environ.get('EXCLUDE_BIND_MOUNTS') or False
18+
self.include_all_volumes = os.environ.get('INCLUDE_ALL_VOLUMES') or False
1819

1920
# Log
2021
self.log_level = os.environ.get('LOG_LEVEL')

src/restic_compose_backup/containers.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,11 @@ def backup_enabled(self) -> bool:
146146
@property
147147
def volume_backup_enabled(self) -> bool:
148148
"""bool: If the ``stack-back.volumes`` label is set"""
149-
return utils.is_true(self.get_label(enums.LABEL_VOLUMES_ENABLED))
149+
label_value = self.get_label(enums.LABEL_VOLUMES_ENABLED)
150+
151+
return utils.is_true(label_value) or (
152+
utils.is_true(config.include_all_volumes) and label_value is None
153+
)
150154

151155
@property
152156
def database_backup_enabled(self) -> bool:

src/tests/tests.py

Lines changed: 120 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,14 @@
66
os.environ['RESTIC_REPOSITORY'] = "test"
77
os.environ['RESTIC_PASSWORD'] = "password"
88

9-
from restic_compose_backup import utils
9+
from restic_compose_backup import utils, config
1010
from restic_compose_backup.containers import RunningContainers
1111
import fixtures
1212

1313
list_containers_func = 'restic_compose_backup.utils.list_containers'
1414

1515

16-
class ResticBackupTests(unittest.TestCase):
17-
16+
class BaseTestCase(unittest.TestCase):
1817
@classmethod
1918
def setUpClass(cls):
2019
"""Set up basic environment variables"""
@@ -31,6 +30,7 @@ def createContainers(self):
3130
}
3231
]
3332

33+
class ResticBackupTests(BaseTestCase):
3434
def test_list_containers(self):
3535
"""Test a basic container list"""
3636
containers = [
@@ -201,3 +201,120 @@ def test_find_running_backup_container(self):
201201
with mock.patch(list_containers_func, fixtures.containers(containers=containers)):
202202
cnt = RunningContainers()
203203
self.assertTrue(cnt.backup_process_running)
204+
205+
206+
class IncludeAllVolumesTests(BaseTestCase):
207+
@classmethod
208+
def setUpClass(cls):
209+
config.config.include_all_volumes = "true"
210+
211+
@classmethod
212+
def tearDownClass(cls):
213+
config.config = config.Config()
214+
215+
def test_basic_functionality(self):
216+
"""Test that the INCLUDE_ALL_VOLUMES flag works"""
217+
containers = self.createContainers()
218+
containers += [
219+
{
220+
"service": "web",
221+
"mounts": [
222+
{
223+
"Source": "/srv/files/media",
224+
"Destination": "/srv/media",
225+
"Type": "bind",
226+
},
227+
{
228+
"Source": "/srv/files/stuff",
229+
"Destination": "/srv/stuff",
230+
"Type": "bind",
231+
},
232+
],
233+
},
234+
]
235+
with mock.patch(
236+
list_containers_func, fixtures.containers(containers=containers)
237+
):
238+
cnt = RunningContainers()
239+
240+
web_service = cnt.get_service("web")
241+
self.assertNotEqual(web_service, None, msg="Web service not found")
242+
243+
mounts = web_service.filter_mounts()
244+
print(mounts)
245+
self.assertEqual(len(mounts), 2)
246+
self.assertEqual(mounts[0].source, "/srv/files/media")
247+
self.assertEqual(mounts[1].source, "/srv/files/stuff")
248+
249+
def test_explicit_exclude(self):
250+
"""Test that a container can be excluded from the backup"""
251+
252+
containers = self.createContainers()
253+
containers += [
254+
{
255+
"service": "web",
256+
"labels": {
257+
"stack-back.volumes": False,
258+
},
259+
"mounts": [
260+
{
261+
"Source": "/srv/files/media",
262+
"Destination": "/srv/media",
263+
"Type": "bind",
264+
},
265+
{
266+
"Source": "/srv/files/stuff",
267+
"Destination": "/srv/stuff",
268+
"Type": "bind",
269+
},
270+
],
271+
},
272+
]
273+
with mock.patch(
274+
list_containers_func, fixtures.containers(containers=containers)
275+
):
276+
cnt = RunningContainers()
277+
278+
web_service = cnt.get_service("web")
279+
self.assertNotEqual(web_service, None, msg="Web service not found")
280+
281+
mounts = web_service.filter_mounts()
282+
print(mounts)
283+
self.assertEqual(len(mounts), 0)
284+
285+
def test_specific_volume_exclude(self):
286+
"""Test that a specific volume can be excluded from the backup"""
287+
288+
containers = self.createContainers()
289+
containers += [
290+
{
291+
"service": "web",
292+
"labels": {
293+
"stack-back.volumes.exclude": "stuff",
294+
},
295+
"mounts": [
296+
{
297+
"Source": "/srv/files/media",
298+
"Destination": "/srv/media",
299+
"Type": "bind",
300+
},
301+
{
302+
"Source": "/srv/files/stuff",
303+
"Destination": "/srv/stuff",
304+
"Type": "bind",
305+
},
306+
],
307+
},
308+
]
309+
with mock.patch(
310+
list_containers_func, fixtures.containers(containers=containers)
311+
):
312+
cnt = RunningContainers()
313+
314+
web_service = cnt.get_service("web")
315+
self.assertNotEqual(web_service, None, msg="Web service not found")
316+
317+
mounts = web_service.filter_mounts()
318+
print(mounts)
319+
self.assertEqual(len(mounts), 1)
320+
self.assertEqual(mounts[0].source, "/srv/files/media")

0 commit comments

Comments
 (0)