release r010 add Unraid health and Community Apps tools
This commit is contained in:
@@ -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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user