From 4f7ccdedb51c15e83407ed057a851c46d554730d Mon Sep 17 00:00:00 2001 From: "Simon L." Date: Fri, 27 Feb 2026 14:48:21 +0100 Subject: [PATCH 1/2] aio-interface: offer system prune button Signed-off-by: Simon L. --- php/public/index.php | 1 + php/src/Controller/DockerController.php | 5 ++++ php/src/Docker/DockerActionManager.php | 32 +++++++++++++++++++++++++ php/templates/containers.twig | 5 ++++ 4 files changed, 43 insertions(+) diff --git a/php/public/index.php b/php/public/index.php index fb4f6117dd0..c5336cfd67f 100644 --- a/php/public/index.php +++ b/php/public/index.php @@ -66,6 +66,7 @@ $app->post('/api/docker/backup-test', AIO\Controller\DockerController::class . ':StartBackupContainerTest'); $app->post('/api/docker/restore', AIO\Controller\DockerController::class . ':StartBackupContainerRestore'); $app->post('/api/docker/stop', AIO\Controller\DockerController::class . ':StopContainer'); +$app->post('/api/docker/prune', AIO\Controller\DockerController::class . ':SystemPrune'); $app->get('/api/docker/logs', AIO\Controller\DockerController::class . ':GetLogs'); $app->post('/api/auth/login', AIO\Controller\LoginController::class . ':TryLogin'); $app->get('/api/auth/getlogin', AIO\Controller\LoginController::class . ':GetTryLogin'); diff --git a/php/src/Controller/DockerController.php b/php/src/Controller/DockerController.php index dc3a292e346..cc7012fb1b0 100644 --- a/php/src/Controller/DockerController.php +++ b/php/src/Controller/DockerController.php @@ -285,6 +285,11 @@ public function StopContainer(Request $request, Response $response, array $args) return $response->withStatus(201)->withHeader('Location', '.'); } + public function SystemPrune(Request $request, Response $response, array $args) : Response { + $this->dockerActionManager->SystemPrune(); + return $response->withStatus(201)->withHeader('Location', '.'); + } + public function stopTopContainer() : void { $id = self::TOP_CONTAINER; $this->PerformRecursiveContainerStop($id); diff --git a/php/src/Docker/DockerActionManager.php b/php/src/Docker/DockerActionManager.php index 5ac1c60e9bc..bbf0d53b286 100644 --- a/php/src/Docker/DockerActionManager.php +++ b/php/src/Docker/DockerActionManager.php @@ -983,4 +983,36 @@ public function GetLatestDigestOfTag(string $imageName, string $tag): ?string { return $this->dockerHubManager->GetLatestDigestOfTag($imageName, $tag); } } + + public function SystemPrune(): void { + $endpoints = [ + // Remove stopped containers + 'containers/prune', + // Remove unused images + 'images/prune', + // Remove unused volumes + 'volumes/prune', + // Remove unused networks + 'networks/prune', + // Prune build cache + 'build/prune', + ]; + + foreach ($endpoints as $endpoint) { + // Special-case images prune to include the dangling filter as requested + if ($endpoint === 'images/prune') { + $filters = json_encode(['dangling' => ['false']]); + $url = $this->BuildApiUrl($endpoint . '?filters=' . urlencode($filters)); + } else { + $url = $this->BuildApiUrl($endpoint); + } + + try { + $this->guzzleClient->post($url); + } catch (RequestException $e) { + error_log(sprintf('Docker prune (%s) failed: %s', $endpoint, $e->getMessage())); + // continue with next prune step + } + } + } } diff --git a/php/templates/containers.twig b/php/templates/containers.twig index ebe2552f1f1..a2a5198d219 100644 --- a/php/templates/containers.twig +++ b/php/templates/containers.twig @@ -322,6 +322,11 @@ +
+ + + +
{% endif %} {% else %} {% if isBackupOrRestoreRunning == true %} From 04c08b586f10e16447ba4a201ec8cee94b10e598 Mon Sep 17 00:00:00 2001 From: "Simon L." Date: Fri, 27 Feb 2026 14:55:16 +0100 Subject: [PATCH 2/2] wip Signed-off-by: Simon L. --- php/src/Controller/DockerController.php | 8 ++++++-- php/src/Docker/DockerActionManager.php | 17 ++++++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/php/src/Controller/DockerController.php b/php/src/Controller/DockerController.php index cc7012fb1b0..21076129fb9 100644 --- a/php/src/Controller/DockerController.php +++ b/php/src/Controller/DockerController.php @@ -286,8 +286,12 @@ public function StopContainer(Request $request, Response $response, array $args) } public function SystemPrune(Request $request, Response $response, array $args) : Response { - $this->dockerActionManager->SystemPrune(); - return $response->withStatus(201)->withHeader('Location', '.'); + $results = $this->dockerActionManager->SystemPrune(); + $body = $response->getBody(); + $body->write(json_encode($results)); + return $response + ->withStatus(200) + ->withHeader('Content-Type', 'application/json; charset=utf-8'); } public function stopTopContainer() : void { diff --git a/php/src/Docker/DockerActionManager.php b/php/src/Docker/DockerActionManager.php index bbf0d53b286..af10a9b8b63 100644 --- a/php/src/Docker/DockerActionManager.php +++ b/php/src/Docker/DockerActionManager.php @@ -984,7 +984,7 @@ public function GetLatestDigestOfTag(string $imageName, string $tag): ?string { } } - public function SystemPrune(): void { + public function SystemPrune(): array { $endpoints = [ // Remove stopped containers 'containers/prune', @@ -998,6 +998,7 @@ public function SystemPrune(): void { 'build/prune', ]; + $results = []; foreach ($endpoints as $endpoint) { // Special-case images prune to include the dangling filter as requested if ($endpoint === 'images/prune') { @@ -1008,11 +1009,21 @@ public function SystemPrune(): void { } try { - $this->guzzleClient->post($url); + $resp = $this->guzzleClient->post($url); + $body = (string)$resp->getBody(); + $json = null; + try { + $json = json_decode($body, true, 512, JSON_THROW_ON_ERROR); + } catch (\Throwable $e) { + // Non-JSON body, keep raw + $json = $body; + } + $results[$endpoint] = $json; } catch (RequestException $e) { error_log(sprintf('Docker prune (%s) failed: %s', $endpoint, $e->getMessage())); + $results[$endpoint] = ['error' => $e->getMessage()]; // continue with next prune step } } + return $results; } -}