- versions.env pins podman, conmon, crun, netavark, aardvark-dns, passt, and fuse-overlayfs to verified upstream source checksums; SlackBuild recipes, scripts/build-packages.sh, checksums.sh, release.sh, and update-versions.sh implement the reproducible pipeline; GitHub Actions workflows build in a Slackware container and publish releases without committing any binaries. - plugin/podman.plg installs/updates/removes all eight packages (the seven components plus the plugin's own unraid-podman scaffolding package) via upgradepkg, using the official Unraid array-event hook mechanism (event/disks_mounted, event/stopping) instead of editing /boot/config/go. rc.podman and the sbin/ helper scripts implement storage creation, config seeding/sync, preflight checks, autostart with per-container Safe-Mode, and package verify/update/rollback. - webui/plugins/podman implements the Dashboard, Containers, Pods, Images, Volumes, Networks, Logs, Terminal, Compose, and Settings panels against the approved mockup (webui/mockups/prototype.html), talking to podman system service exclusively via PodmanClient.php (libpod REST API over the Unix socket), with two documented exceptions: Terminal's one-shot exec model and Compose's use of the podman compose CLI, since libpod has no REST equivalent for either. - docs/ARCHITECTURE.md and docs/ROADMAP.md record the design decisions and honest current status (syntax-checked, unit- and integration-tested against fake sockets/servers; not yet run against a real Unraid/Podman/Slackware system). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
68 lines
2.8 KiB
PHP
68 lines
2.8 KiB
PHP
<?php
|
|
/**
|
|
* ajax/exec.php
|
|
*
|
|
* Backs the Terminal panel — and this is the one panel where "exclusively
|
|
* via podman system service, no shell hacks" needs an honest caveat
|
|
* spelled out rather than silently glossed over:
|
|
*
|
|
* libpod's real exec API (POST /containers/{id}/exec, then
|
|
* POST /exec/{id}/start) is used here — PodmanClient::execRun() never
|
|
* shells out to the `podman` binary. But that API's interactive mode works
|
|
* by HTTP connection hijacking: the HTTP connection is upgraded into a raw
|
|
* bidirectional byte stream for the lifetime of the shell session. That
|
|
* model assumes a long-lived process holding the socket open on both ends
|
|
* (an actual terminal emulator, or a WebSocket bridge) — it does not fit
|
|
* PHP-FPM's request/response lifecycle, where each AJAX call is a fresh,
|
|
* independent, short-lived process with no memory of any previous one.
|
|
*
|
|
* Rather than fake interactivity with something that would break on the
|
|
* first multi-line prompt, `sudo`, or interactive editor, this endpoint
|
|
* offers a deliberately simpler, honest contract: one command in, its
|
|
* complete output back, using Tty=true so output reads like a real
|
|
* terminal (colors, prompts-in-output, etc. survive) but with no
|
|
* persistent shell state (`cd` does not carry over between calls — see
|
|
* the "cwd" parameter below, which javascript/terminal.js tracks
|
|
* client-side and resends every time instead).
|
|
*
|
|
* A true interactive PTY (arrow-key history, tab completion, vim, ...)
|
|
* would need a WebSocket-capable process sitting between the browser and
|
|
* podman.sock — out of scope for this PHP/AJAX stack; tracked as a
|
|
* follow-up rather than implemented as a shell-out workaround.
|
|
*
|
|
* Actions (?action=...):
|
|
* run POST {"id": "...", "cmd": "ls -la", "cwd": "/config"}
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
require __DIR__ . '/../include/bootstrap.php';
|
|
|
|
$action = $_GET['action'] ?? '';
|
|
|
|
switch ($action) {
|
|
case 'run':
|
|
$body = podman_read_json_body();
|
|
$id = (string) ($body['id'] ?? '');
|
|
$commandLine = (string) ($body['cmd'] ?? '');
|
|
$cwd = (string) ($body['cwd'] ?? '');
|
|
|
|
if ($id === '' || trim($commandLine) === '') {
|
|
podman_json_error('Missing id or cmd in request body', 400);
|
|
}
|
|
|
|
// The command line is run through the container's own shell
|
|
// (sh -c) so the user can type ordinary shell syntax (pipes,
|
|
// globs, env vars) in the terminal box, exactly like a real
|
|
// shell prompt would accept — still one real exec API call, just
|
|
// with /bin/sh as the interpreter instead of us parsing shell
|
|
// syntax ourselves in PHP.
|
|
$output = $client->execRun($id, ['/bin/sh', '-c', $commandLine], $cwd);
|
|
|
|
podman_json_response(['output' => $output]);
|
|
break;
|
|
|
|
default:
|
|
podman_json_error("Unknown action '{$action}'", 400);
|
|
}
|