Web files now served via symlink to the git repo so git pull changes survive reboots without rebuilding the txz. Also includes: docker pull/rebuild/restart with live log streaming, arr_profile_enforcer for Sonarr/Radarr quality profiles, monitor page cache fix (background writer now in cron), and ARR_KIDS/SONARR/RADARR profile name vars in master.conf.
89 lines
3.9 KiB
PHP
89 lines
3.9 KiB
PHP
<?php
|
|
header('Content-Type: application/json');
|
|
|
|
define('VV_JOB_DIR', '/tmp/varaverk_dk_jobs');
|
|
|
|
$action = trim($_POST['action'] ?? '');
|
|
$name = trim($_POST['name'] ?? '');
|
|
$jobId = trim($_POST['job_id'] ?? '');
|
|
|
|
// ── Job status (no name required) ─────────────────────────────────────────────
|
|
if ($action === 'job_status') {
|
|
if (!$jobId || !preg_match('/^[0-9a-f]+$/', $jobId)) {
|
|
echo json_encode(['ok' => false, 'error' => 'invalid job_id']); exit;
|
|
}
|
|
$file = VV_JOB_DIR . '/' . $jobId . '.json';
|
|
if (!file_exists($file)) {
|
|
echo json_encode(['ok' => true, 'status' => 'pending']); exit;
|
|
}
|
|
echo file_get_contents($file); exit;
|
|
}
|
|
|
|
// ── Logs ──────────────────────────────────────────────────────────────────────
|
|
if ($action === 'logs') {
|
|
if (!$name || !preg_match('/^[a-zA-Z0-9_.-]+$/', $name)) {
|
|
echo json_encode(['ok' => false, 'error' => 'invalid name']); exit;
|
|
}
|
|
$out = shell_exec('docker logs --tail 200 --timestamps ' . escapeshellarg($name) . ' 2>&1');
|
|
echo json_encode(['ok' => true, 'logs' => $out ?? '']); exit;
|
|
}
|
|
|
|
// ── Container-scoped actions ──────────────────────────────────────────────────
|
|
if (!$name || !preg_match('/^[a-zA-Z0-9_.-]+$/', $name)) {
|
|
echo json_encode(['ok' => false, 'error' => 'invalid name']); exit;
|
|
}
|
|
|
|
$check = trim(shell_exec(
|
|
'docker ps -a --filter ' . escapeshellarg('name=^' . $name . '$') . " --format '{{.Names}}' 2>/dev/null"
|
|
) ?? '');
|
|
if ($check !== $name) {
|
|
echo json_encode(['ok' => false, 'error' => 'Container not found']); exit;
|
|
}
|
|
|
|
if ($action === 'start' || $action === 'stop') {
|
|
exec(($action === 'start' ? 'docker start' : 'docker stop') . ' ' . escapeshellarg($name) . ' 2>&1', $out, $rc);
|
|
echo json_encode(['ok' => $rc === 0, 'output' => implode("\n", $out)]); exit;
|
|
}
|
|
|
|
if ($action === 'restart') {
|
|
$rebuild = '/usr/local/emhttp/plugins/dynamix.docker.manager/scripts/rebuild_container';
|
|
if (is_executable($rebuild)) {
|
|
exec($rebuild . ' ' . escapeshellarg($name) . ' 2>&1', $out, $rc);
|
|
} else {
|
|
exec('docker stop ' . escapeshellarg($name) . ' 2>&1', $o1, $rc1);
|
|
exec('docker start ' . escapeshellarg($name) . ' 2>&1', $o2, $rc2);
|
|
$out = array_merge($o1, $o2);
|
|
$rc = ($rc1 === 0 && $rc2 === 0) ? 0 : 1;
|
|
}
|
|
echo json_encode(['ok' => $rc === 0, 'output' => implode("\n", $out)]); exit;
|
|
}
|
|
|
|
if ($action === 'pull_rebuild') {
|
|
@mkdir(VV_JOB_DIR, 0700, true);
|
|
$jobId = bin2hex(random_bytes(8));
|
|
$jobFile = VV_JOB_DIR . '/' . $jobId . '.json';
|
|
$worker = __DIR__ . '/docker_pull_worker.php';
|
|
$rebuild = '/usr/local/emhttp/plugins/dynamix.docker.manager/scripts/rebuild_container';
|
|
|
|
$oldId = trim(shell_exec('docker inspect --format={{.Image}} ' . escapeshellarg($name) . ' 2>/dev/null') ?: '');
|
|
$image = trim(shell_exec('docker inspect --format={{.Config.Image}} ' . escapeshellarg($name) . ' 2>/dev/null') ?: '');
|
|
|
|
if (!$image) {
|
|
echo json_encode(['ok' => false, 'error' => 'Could not determine image']); exit;
|
|
}
|
|
|
|
file_put_contents($jobFile, json_encode(['ok' => true, 'status' => 'pulling', 'container' => $name]));
|
|
|
|
$cmd = 'php ' . escapeshellarg($worker) . ' ' .
|
|
escapeshellarg($name) . ' ' .
|
|
escapeshellarg($jobFile) . ' ' .
|
|
escapeshellarg($oldId) . ' ' .
|
|
escapeshellarg($image) . ' ' .
|
|
escapeshellarg($rebuild) . ' >/dev/null 2>&1 &';
|
|
exec($cmd);
|
|
|
|
echo json_encode(['ok' => true, 'status' => 'started', 'job_id' => $jobId]); exit;
|
|
}
|
|
|
|
echo json_encode(['ok' => false, 'error' => 'Unknown action']);
|