From 9f19026885dffa520813434f37bd048d296ca9e5 Mon Sep 17 00:00:00 2001 From: Simon L Date: Wed, 17 May 2023 20:48:08 +0200 Subject: [PATCH] allow to include volumes in backup and restore Signed-off-by: Simon L --- Containers/borgbackup/backupscript.sh | 8 ++++++ manual-install/update-yaml.sh | 1 + php/containers-schema.json | 10 +++++++- php/containers.json | 35 ++++++++++---------------- php/src/Container/Container.php | 8 ++++++ php/src/ContainerDefinitionFetcher.php | 6 +++++ php/src/Docker/DockerActionManager.php | 23 +++++++++++++++++ 7 files changed, 68 insertions(+), 23 deletions(-) diff --git a/Containers/borgbackup/backupscript.sh b/Containers/borgbackup/backupscript.sh index d877affe..871dabe2 100644 --- a/Containers/borgbackup/backupscript.sh +++ b/Containers/borgbackup/backupscript.sh @@ -24,6 +24,14 @@ for directory in "${VOLUME_DIRS[@]}"; do exit 1 fi done +# Test if default volumes are there +DEFAULT_VOLUMES=(nextcloud_aio_apache nextcloud_aio_nextcloud nextcloud_aio_database nextcloud_aio_database_dump nextcloud_aio_elasticsearch nextcloud_aio_nextcloud_data nextcloud_aio_mastercontainer) +for volume in "${DEFAULT_VOLUMES[@]}"; do + if ! mountpoint -q "/nextcloud_aio_volumes/$volume"; then + echo "$volume is missing which is not intended." + exit 1 + fi +done # Check if target is mountpoint if ! mountpoint -q /mnt/borgbackup; then diff --git a/manual-install/update-yaml.sh b/manual-install/update-yaml.sh index c0cd8872..c37a45c1 100644 --- a/manual-install/update-yaml.sh +++ b/manual-install/update-yaml.sh @@ -15,6 +15,7 @@ OUTPUT="$(cat /tmp/containers.json)" OUTPUT="$(echo "$OUTPUT" | jq 'del(.services[].internal_port)')" OUTPUT="$(echo "$OUTPUT" | jq 'del(.services[].secrets)')" OUTPUT="$(echo "$OUTPUT" | jq 'del(.services[].devices)')" +OUTPUT="$(echo "$OUTPUT" | jq 'del(.services[].backup_volumes)')" OUTPUT="$(echo "$OUTPUT" | jq 'del(.services[] | select(.container_name == "nextcloud-aio-watchtower"))')" OUTPUT="$(echo "$OUTPUT" | jq 'del(.services[] | select(.container_name == "nextcloud-aio-domaincheck"))')" OUTPUT="$(echo "$OUTPUT" | jq 'del(.services[] | select(.container_name == "nextcloud-aio-borgbackup"))')" diff --git a/php/containers-schema.json b/php/containers-schema.json index 919f60e0..e2d37767 100644 --- a/php/containers-schema.json +++ b/php/containers-schema.json @@ -106,6 +106,13 @@ "apparmor_unconfined": { "type": "boolean" }, + "backup_volumes": { + "type": "array", + "items": { + "type": "string", + "pattern": "^nextcloud_aio_[a-z_]+$" + } + }, "volumes": { "type": "array", "items": { @@ -119,7 +126,8 @@ }, "source": { "type": "string", - "pattern": "^(([a-z_]+)|(%[A-Z_]+%))$" }, + "pattern": "^((nextcloud_aio_[a-z_]+)|(%[A-Z_]+%))$" + }, "writeable": { "type": "boolean" } diff --git a/php/containers.json b/php/containers.json index 61992be6..eb16c316 100644 --- a/php/containers.json +++ b/php/containers.json @@ -41,7 +41,11 @@ "writeable": true } ], - "restart": "unless-stopped" + "restart": "unless-stopped", + "backup_volumes": [ + "nextcloud_aio_nextcloud", + "nextcloud_aio_apache" + ] }, { "container_name": "nextcloud-aio-database", @@ -75,7 +79,11 @@ ], "stop_grace_period": 1800, "restart": "unless-stopped", - "shm_size": 268435456 + "shm_size": 268435456, + "backup_volumes": [ + "nextcloud_aio_database", + "nextcloud_aio_database_dump" + ] }, { "container_name": "nextcloud-aio-nextcloud", @@ -167,6 +175,9 @@ "restart": "unless-stopped", "devices": [ "/dev/dri" + ], + "backup_volumes": [ + "nextcloud_aio_nextcloud" ] }, { @@ -270,31 +281,11 @@ "destination": "/root", "writeable": true }, - { - "source": "nextcloud_aio_nextcloud", - "destination": "/nextcloud_aio_volumes/nextcloud_aio_nextcloud", - "writeable": true - }, { "source": "%NEXTCLOUD_DATADIR%", "destination": "/nextcloud_aio_volumes/nextcloud_aio_nextcloud_data", "writeable": true }, - { - "source": "nextcloud_aio_database", - "destination": "/nextcloud_aio_volumes/nextcloud_aio_database", - "writeable": true - }, - { - "source": "nextcloud_aio_database_dump", - "destination": "/nextcloud_aio_volumes/nextcloud_aio_database_dump", - "writeable": true - }, - { - "source": "nextcloud_aio_apache", - "destination": "/nextcloud_aio_volumes/nextcloud_aio_apache", - "writeable": true - }, { "source": "nextcloud_aio_mastercontainer", "destination": "/nextcloud_aio_volumes/nextcloud_aio_mastercontainer", diff --git a/php/src/Container/Container.php b/php/src/Container/Container.php index 442ee587..0ca8e872 100644 --- a/php/src/Container/Container.php +++ b/php/src/Container/Container.php @@ -27,6 +27,8 @@ class Container { private array $capAdd; private int $shmSize; private bool $apparmorUnconfined; + /** @var string[] */ + private array $backupVolumes; private DockerActionManager $dockerActionManager; public function __construct( @@ -45,6 +47,7 @@ class Container { array $capAdd, int $shmSize, bool $apparmorUnconfined, + array $backupVolumes, DockerActionManager $dockerActionManager ) { $this->identifier = $identifier; @@ -62,6 +65,7 @@ class Container { $this->capAdd = $capAdd; $this->shmSize = $shmSize; $this->apparmorUnconfined = $apparmorUnconfined; + $this->backupVolumes = $backupVolumes; $this->dockerActionManager = $dockerActionManager; } @@ -105,6 +109,10 @@ class Container { return $this->capAdd; } + public function GetBackupVolumes() : array { + return $this->backupVolumes; + } + public function GetPorts() : ContainerPorts { return $this->ports; } diff --git a/php/src/ContainerDefinitionFetcher.php b/php/src/ContainerDefinitionFetcher.php index 50901f8f..75bd2c2e 100644 --- a/php/src/ContainerDefinitionFetcher.php +++ b/php/src/ContainerDefinitionFetcher.php @@ -228,6 +228,11 @@ class ContainerDefinitionFetcher $apparmorUnconfined = $entry['apparmor_unconfined']; } + $backupVolumes = []; + if (isset($entry['backup_volumes'])) { + $backupVolumes = $entry['backup_volumes']; + } + $containers[] = new Container( $entry['container_name'], $displayName, @@ -244,6 +249,7 @@ class ContainerDefinitionFetcher $capAdd, $shmSize, $apparmorUnconfined, + $backupVolumes, $this->container->get(DockerActionManager::class) ); } diff --git a/php/src/Docker/DockerActionManager.php b/php/src/Docker/DockerActionManager.php index bd159311..ef41a1f5 100644 --- a/php/src/Docker/DockerActionManager.php +++ b/php/src/Docker/DockerActionManager.php @@ -429,6 +429,11 @@ class DockerActionManager if ($container->GetIdentifier() === 'nextcloud-aio-borgbackup') { // Additional backup directories $mounts = []; + foreach ($this->getAllBackupVolumes() as $additionalBackupVolumes) { + if ($additionalBackupVolumes !== '') { + $mounts[] = ["Type" => "volume", "Source" => $additionalBackupVolumes, "Target" => "/nextcloud_aio_volumes/" . $additionalBackupVolumes, "ReadOnly" => false]; + } + } foreach ($this->configurationManager->GetAdditionalBackupDirectoriesArray() as $additionalBackupDirectories) { if ($additionalBackupDirectories !== '') { if (!str_starts_with($additionalBackupDirectories, '/')) { @@ -503,6 +508,24 @@ class DockerActionManager } } + private function getBackupVolumes(string $id) : array + { + $container = $this->containerDefinitionFetcher->GetContainerById($id); + + $backupVolumes = $container->GetBackupVolumes(); + + foreach ($container->GetDependsOn() as $dependency) { + $backupVolumes[] = $this->getBackupVolumes($dependency); + } + return $backupVolumes; + } + + private function getAllBackupVolumes() : array { + $id = 'nextcloud-aio-apache'; + + return array_unique($this->getBackupVolumes($id)); + } + private function GetRepoDigestsOfContainer(string $containerName) : ?array { try { $containerUrl = $this->BuildApiUrl(sprintf('containers/%s/json', $containerName));