mirror of
https://github.com/kevinveenbirkenbach/docker-volume-backup.git
synced 2026-08-02 13:02:41 +00:00
Autolint
This commit is contained in:
@@ -100,7 +100,9 @@ def parse_args() -> argparse.Namespace:
|
||||
if bool(args.snapshot) != bool(args.snapshot_subject):
|
||||
p.error("--snapshot and --snapshot-subject must be given together")
|
||||
if args.snapshot and args.shutdown:
|
||||
p.error("--shutdown is meaningless with --snapshot: containers are never stopped")
|
||||
p.error(
|
||||
"--shutdown is meaningless with --snapshot: containers are never stopped"
|
||||
)
|
||||
if args.snapshot and args.hard_restart_projects:
|
||||
p.error(
|
||||
"--hard-restart-projects is meaningless with --snapshot: the flag exists "
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
"""Fixtures and paths the e2e suite builds its scenarios from."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import shutil
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
"""Process, docker and readiness helpers for the e2e suite."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
|
||||
@@ -25,7 +25,9 @@ GENERATION = f"{VERSIONS}/20260731"
|
||||
def shell(command: str) -> list[str]:
|
||||
proc = subprocess.run(command, shell=True, capture_output=True, text=True)
|
||||
if proc.returncode != 0:
|
||||
raise SnapshotError(f"{command} exited {proc.returncode}: {proc.stderr.strip()}")
|
||||
raise SnapshotError(
|
||||
f"{command} exited {proc.returncode}: {proc.stderr.strip()}"
|
||||
)
|
||||
return proc.stdout.splitlines()
|
||||
|
||||
|
||||
|
||||
@@ -22,7 +22,9 @@ EXPECT = sys.argv[3]
|
||||
def shell(command: str) -> list[str]:
|
||||
proc = subprocess.run(command, shell=True, capture_output=True, text=True)
|
||||
if proc.returncode != 0:
|
||||
raise SnapshotError(f"{command} exited {proc.returncode}: {proc.stderr.strip()}")
|
||||
raise SnapshotError(
|
||||
f"{command} exited {proc.returncode}: {proc.stderr.strip()}"
|
||||
)
|
||||
return proc.stdout.splitlines()
|
||||
|
||||
|
||||
@@ -55,5 +57,8 @@ with volume_snapshot(KIND, SUBJECT, "e2e", run=shell) as resolve:
|
||||
|
||||
root = Path(resolve(SUBJECT))
|
||||
|
||||
check("the snapshot is removed afterwards", not root.exists() or not (root / "volumes").exists())
|
||||
check(
|
||||
"the snapshot is removed afterwards",
|
||||
not root.exists() or not (root / "volumes").exists(),
|
||||
)
|
||||
print("ALL OK", flush=True)
|
||||
|
||||
@@ -29,7 +29,7 @@ LOOP_FS = {
|
||||
"ext4": "mkdir -p /subject/docker",
|
||||
}
|
||||
# A container carries no /lib/modules, so modprobe fails even on a loaded module.
|
||||
ZFS_READY = '{ [ -c /dev/zfs ] || modprobe zfs 2>/dev/null; }; [ -c /dev/zfs ]'
|
||||
ZFS_READY = "{ [ -c /dev/zfs ] || modprobe zfs 2>/dev/null; }; [ -c /dev/zfs ]"
|
||||
|
||||
|
||||
def mount_script(fstype: str) -> str:
|
||||
@@ -51,7 +51,13 @@ def zfs_usable() -> bool:
|
||||
"""Whether this host's kernel can serve zfs to a privileged container."""
|
||||
proc = run(
|
||||
[
|
||||
"docker", "run", "--rm", "--privileged", IMAGE, "sh", "-lc",
|
||||
"docker",
|
||||
"run",
|
||||
"--rm",
|
||||
"--privileged",
|
||||
IMAGE,
|
||||
"sh",
|
||||
"-lc",
|
||||
f"apk add -q zfs >/dev/null 2>&1 && {ZFS_READY}",
|
||||
],
|
||||
capture=True,
|
||||
@@ -87,11 +93,20 @@ def drive(fstype: str, kind: str, expect: str) -> str:
|
||||
try:
|
||||
proc = run(
|
||||
[
|
||||
"docker", "run", "--rm", "--privileged",
|
||||
"--name", staged.name,
|
||||
"-v", f"{staged / 'src'}:/src:ro",
|
||||
"-v", f"{staged / 'driver.py'}:/driver.py:ro",
|
||||
IMAGE, "sh", "-lc", script,
|
||||
"docker",
|
||||
"run",
|
||||
"--rm",
|
||||
"--privileged",
|
||||
"--name",
|
||||
staged.name,
|
||||
"-v",
|
||||
f"{staged / 'src'}:/src:ro",
|
||||
"-v",
|
||||
f"{staged / 'driver.py'}:/driver.py:ro",
|
||||
IMAGE,
|
||||
"sh",
|
||||
"-lc",
|
||||
script,
|
||||
],
|
||||
capture=True,
|
||||
check=False,
|
||||
@@ -99,7 +114,9 @@ def drive(fstype: str, kind: str, expect: str) -> str:
|
||||
finally:
|
||||
shutil.rmtree(staged, ignore_errors=True)
|
||||
if proc.returncode != 0:
|
||||
raise AssertionError(f"{fstype}/{kind} driver failed:\n{proc.stdout}\n{proc.stderr}")
|
||||
raise AssertionError(
|
||||
f"{fstype}/{kind} driver failed:\n{proc.stdout}\n{proc.stderr}"
|
||||
)
|
||||
return proc.stdout
|
||||
|
||||
|
||||
@@ -125,7 +142,9 @@ class TestE2ESnapshot(unittest.TestCase):
|
||||
"E2E_REQUIRE_FILESYSTEMS demands zfs, but this kernel provides no "
|
||||
"zfs module; load it before running the suite"
|
||||
)
|
||||
self.skipTest("this kernel provides no zfs module, so no pool can be created")
|
||||
self.skipTest(
|
||||
"this kernel provides no zfs module, so no pool can be created"
|
||||
)
|
||||
self.assert_freezes("zfs")
|
||||
|
||||
def test_ext4_has_no_snapshot_and_says_so(self) -> None:
|
||||
|
||||
@@ -68,11 +68,20 @@ class TestE2ESnapshotDatabase(unittest.TestCase):
|
||||
try:
|
||||
proc = run(
|
||||
[
|
||||
"docker", "run", "--rm", "--privileged",
|
||||
"--name", staged.name,
|
||||
"-v", f"{staged / 'src'}:/src:ro",
|
||||
"-v", f"{staged / 'driver.py'}:/driver.py:ro",
|
||||
IMAGE, "sh", "-lc", SCRIPT,
|
||||
"docker",
|
||||
"run",
|
||||
"--rm",
|
||||
"--privileged",
|
||||
"--name",
|
||||
staged.name,
|
||||
"-v",
|
||||
f"{staged / 'src'}:/src:ro",
|
||||
"-v",
|
||||
f"{staged / 'driver.py'}:/driver.py:ro",
|
||||
IMAGE,
|
||||
"sh",
|
||||
"-lc",
|
||||
SCRIPT,
|
||||
],
|
||||
capture=True,
|
||||
check=False,
|
||||
|
||||
@@ -12,6 +12,7 @@ from baudolo.backup.snapshot import volume_snapshot
|
||||
def stubbed_snapshot(kind: str, subject: str, tag: str):
|
||||
return volume_snapshot(kind, subject, tag, run=lambda command: [])
|
||||
|
||||
|
||||
ARGV = [
|
||||
"baudolo",
|
||||
"--compose-dir",
|
||||
|
||||
@@ -39,7 +39,9 @@ class TestSnapshotFlags(unittest.TestCase):
|
||||
parse("--snapshot", "ext4", "--snapshot-subject", "/var/lib/docker")
|
||||
|
||||
def test_zfs_is_accepted(self) -> None:
|
||||
self.assertEqual(parse("--snapshot", "zfs", "--snapshot-subject", "/d").snapshot, "zfs")
|
||||
self.assertEqual(
|
||||
parse("--snapshot", "zfs", "--snapshot-subject", "/d").snapshot, "zfs"
|
||||
)
|
||||
|
||||
def test_shutdown_is_rejected_because_nothing_is_stopped(self) -> None:
|
||||
with self.assertRaises(SystemExit):
|
||||
|
||||
@@ -35,11 +35,15 @@ class TestBtrfs(unittest.TestCase):
|
||||
run = Runner()
|
||||
with volume_snapshot("btrfs", "/var/lib/docker", "20260731", run=run):
|
||||
pass
|
||||
self.assertEqual(run.calls[-1], "btrfs subvolume delete /var/lib/docker/.baudolo-20260731")
|
||||
self.assertEqual(
|
||||
run.calls[-1], "btrfs subvolume delete /var/lib/docker/.baudolo-20260731"
|
||||
)
|
||||
|
||||
def test_it_maps_a_volume_path_into_the_snapshot(self) -> None:
|
||||
run = Runner()
|
||||
with volume_snapshot("btrfs", "/var/lib/docker", "20260731", run=run) as resolve:
|
||||
with volume_snapshot(
|
||||
"btrfs", "/var/lib/docker", "20260731", run=run
|
||||
) as resolve:
|
||||
self.assertEqual(
|
||||
resolve("/var/lib/docker/volumes/postgres_data/_data"),
|
||||
"/var/lib/docker/.baudolo-20260731/volumes/postgres_data/_data",
|
||||
@@ -47,7 +51,9 @@ class TestBtrfs(unittest.TestCase):
|
||||
|
||||
def test_it_keeps_the_trailing_slash_rsync_reads_as_contents(self) -> None:
|
||||
run = Runner()
|
||||
with volume_snapshot("btrfs", "/var/lib/docker", "20260731", run=run) as resolve:
|
||||
with volume_snapshot(
|
||||
"btrfs", "/var/lib/docker", "20260731", run=run
|
||||
) as resolve:
|
||||
self.assertEqual(
|
||||
resolve("/var/lib/docker/volumes/postgres_data/_data/"),
|
||||
"/var/lib/docker/.baudolo-20260731/volumes/postgres_data/_data/",
|
||||
@@ -102,14 +108,20 @@ class TestRejections(unittest.TestCase):
|
||||
|
||||
def test_a_path_outside_the_subject_is_rejected(self) -> None:
|
||||
run = Runner()
|
||||
with volume_snapshot("btrfs", "/var/lib/docker", "20260731", run=run) as resolve:
|
||||
with volume_snapshot(
|
||||
"btrfs", "/var/lib/docker", "20260731", run=run
|
||||
) as resolve:
|
||||
with self.assertRaises(SnapshotError):
|
||||
resolve("/etc/passwd")
|
||||
|
||||
def test_the_subject_itself_resolves_to_the_snapshot_root(self) -> None:
|
||||
run = Runner()
|
||||
with volume_snapshot("btrfs", "/var/lib/docker", "20260731", run=run) as resolve:
|
||||
self.assertEqual(resolve("/var/lib/docker"), "/var/lib/docker/.baudolo-20260731")
|
||||
with volume_snapshot(
|
||||
"btrfs", "/var/lib/docker", "20260731", run=run
|
||||
) as resolve:
|
||||
self.assertEqual(
|
||||
resolve("/var/lib/docker"), "/var/lib/docker/.baudolo-20260731"
|
||||
)
|
||||
|
||||
|
||||
class Busy(Runner):
|
||||
|
||||
Reference in New Issue
Block a user