release r010 add Unraid health and Community Apps tools

This commit is contained in:
Mikei386
2026-08-21 10:14:16 +02:00
parent e586b22b13
commit 771b8c43a1
14 changed files with 831 additions and 33 deletions
+81 -1
View File
@@ -9,6 +9,7 @@
* modify <container> <field> <value>
* update <container>
* rebuild <container>
* ca-install <template_url> <container_name> <overrides_json> <start:true|false>
*
* modify fields:
* port value: newExternalPort (z.B. "8466")
@@ -242,6 +243,80 @@ function modify_template(string $name, string $field, string $value): void {
rebuild_container($name, false, true);
}
function ca_install(string $template_url, string $name, string $overrides_json, bool $start): void {
if (!preg_match('/^[a-zA-Z0-9._-]{1,128}$/', $name)) {
fail('Invalid container name');
}
$url = parse_url($template_url);
if (!is_array($url) || ($url['scheme'] ?? '') !== 'https' || empty($url['host'])) {
fail('Community Applications template must use HTTPS');
}
$host = strtolower((string)$url['host']);
if ($host === 'localhost' || str_ends_with($host, '.local')) {
fail('Private template hosts are rejected');
}
if (filter_var($host, FILTER_VALIDATE_IP) &&
!filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
fail('Private or reserved template IPs are rejected');
}
$template_path = "/boot/config/plugins/dockerMan/templates-user/my-$name.xml";
if (file_exists($template_path)) fail("Template already exists: $name");
$existing = trim(docker_exec('inspect --type container --format {{.Name}} ' . escapeshellarg($name)));
if ($existing !== '' && stripos($existing, 'Error:') !== 0) fail("Container already exists: $name");
$context = stream_context_create(['http' => [
'timeout' => 30,
'follow_location' => 0,
'user_agent' => 'MUA Community Applications Installer',
]]);
$xml = @file_get_contents($template_url, false, $context, 0, 1024 * 1024 + 1);
if ($xml === false || strlen($xml) === 0) fail('Unable to download Community Applications template');
if (strlen($xml) > 1024 * 1024) fail('Community Applications template is too large');
$dom = new DOMDocument();
$old = libxml_use_internal_errors(true);
$loaded = $dom->loadXML($xml, LIBXML_NONET | LIBXML_NOBLANKS);
libxml_clear_errors();
libxml_use_internal_errors($old);
if (!$loaded || !$dom->documentElement || $dom->documentElement->nodeName !== 'Container') {
fail('Invalid Community Applications container template');
}
$repositories = $dom->getElementsByTagName('Repository');
if ($repositories->length !== 1 || trim($repositories->item(0)->textContent) === '') {
fail('Template has no valid Docker repository');
}
$names = $dom->getElementsByTagName('Name');
if ($names->length === 0) {
$name_node = $dom->createElement('Name', $name);
$dom->documentElement->insertBefore($name_node, $dom->documentElement->firstChild);
} else {
$names->item(0)->nodeValue = $name;
}
$overrides = json_decode($overrides_json, true);
if (!is_array($overrides) || count($overrides) > 32) fail('Invalid overrides object');
foreach ($overrides as $target => $value) {
if (!is_string($target) || !is_string($value) || strlen($value) > 4096) fail('Invalid override');
$found = false;
foreach ($dom->getElementsByTagName('Config') as $config) {
if ($config->getAttribute('Target') === $target) {
set_config_value($config, $value);
$found = true;
break;
}
}
if (!$found) fail("Override target not present in template: $target");
}
$dom->formatOutput = true;
if ($dom->save($template_path) === false) fail('Unable to write Unraid user template');
chmod($template_path, 0600);
out("Community Applications template saved: $name");
rebuild_container($name, true, $start);
out('Container is managed by the Unraid user template');
}
// ── Main ─────────────────────────────────────────────────────────────────
$argv = $_SERVER['argv'];
$action = $argv[1] ?? '';
@@ -273,6 +348,11 @@ switch ($action) {
rebuild_container($arg1, false);
break;
case 'ca-install':
if (!$arg1 || !$arg2) fail('Usage: ca-install <template_url> <container_name> <overrides_json> <start:true|false>');
ca_install($arg1, $arg2, $arg3 ?: '{}', ($argv[5] ?? 'false') === 'true');
break;
default:
fail("Unknown action: $action. Usage: create|modify|update|rebuild");
fail("Unknown action: $action. Usage: create|modify|update|rebuild|ca-install");
}