Files
unraid-podman/webui/plugins/podman/ajax/system.php
T
maggesandClaude Sonnet 5 5b47b4cc0a Add catatonit/nftables/docker-compose packages, fix CSRF/streaming/storage bugs found by live testing
- Package #9-11: catatonit (pod infra init), nftables (netavark firewall
  backend), docker-compose (external compose provider for `podman compose`)
  — all vendored prebuilt binaries, versions.env pinned, propagated through
  build-packages.sh/release.sh/podman.plg/verify+update-packages.sh.
- Fix WebUI: every POST action was silently failing (empty response body)
  because Unraid's own CSRF protection was never satisfied — app.js now
  sends the page's csrf_token as X-CSRF-Token.
- Fix WebUI: PodmanClient::pullImage() assumed a single JSON response, but
  /images/pull actually streams newline-delimited JSON — every successful
  pull was throwing "Expected a JSON object/array response".
- Fix WebUI: compose.php's up/down status detection had the same
  single-JSON-vs-NDJSON bug for `podman compose ps`, plus stderr was
  corrupting the parse.
- Add cache-busting (?v=<mtime>) to Podman.page's script/style tags so a
  redeployed JS/CSS fix isn't served stale from browser cache.
- Add a reusable modal dialog (app.js openFormModal) replacing
  prompt()/alert() for New Volume/Network/Pull Image.
- Add host-path (bind-mount) support when creating a named volume.
- Add Create Container (image, name, network mode incl. custom networks,
  ports, volumes, env, restart policy, privileged, start-after-create),
  auto-pulling the image on first use since /containers/create doesn't.

All fixes verified live against a real podman system service and, where
reachable, via the actual WebUI over the real socket — not just unit-level.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 11:51:17 +00:00

80 lines
2.3 KiB
PHP

<?php
/**
* ajax/system.php
*
* Backs the Dashboard panel's summary tiles and the service-status line
* shown in the page header — aggregates across several libpod endpoints
* into the one shape javascript/dashboard.js needs, so the frontend
* doesn't have to make (and wait on) five separate round trips.
*
* Actions (?action=...):
* summary GET -> counts, storage usage, engine version, ping status
*/
declare(strict_types=1);
require __DIR__ . '/../include/bootstrap.php';
$action = $_GET['action'] ?? '';
switch ($action) {
case 'summary':
podman_json_response(system_summary($client, $podmanConfig));
break;
default:
podman_json_error("Unknown action '{$action}'", 400);
}
/** @return array<string,mixed> */
function system_summary(PodmanClient $client, PodmanConfig $config): array
{
if (!$client->ping()) {
return [
'reachable' => false,
'socketPath' => $config->socketPath,
];
}
$containers = $client->listContainers(true);
$running = 0;
foreach ($containers as $c) {
if (strtolower((string) ($c['State'] ?? '')) === 'running') {
$running++;
}
}
$pods = $client->listPods();
$images = $client->listImages();
$volumes = $client->listVolumes();
$networks = $client->listNetworks();
$info = $client->info();
$df = $client->systemDf();
$imagesSize = 0;
foreach (($df['Images'] ?? []) as $img) {
$imagesSize += (int) ($img['Size'] ?? 0);
}
return [
'reachable' => true,
'socketPath' => $config->socketPath,
// libpod's /info nests the version block under lowercase "version"
// (unlike most other libpod endpoints, which are PascalCase
// throughout) — verified live against a real podman system service.
'podmanVersion' => $info['version']['Version'] ?? null,
'containers' => [
'total' => count($containers),
'running' => $running,
],
'pods' => count($pods),
'images' => count($images),
'volumes' => count($volumes),
'networks' => count($networks),
'storage' => [
'imagesSizeBytes' => $imagesSize,
'imagesSizeFormatted' => podman_format_bytes($imagesSize),
],
];
}