mirror of
https://github.com/unraid/webgui.git
synced 2026-01-06 01:29:54 -06:00
Fix php error of too many variables in post.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<?PHP
|
||||
<?php
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
*
|
||||
@@ -13,166 +13,254 @@
|
||||
<?
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
|
||||
// add translations
|
||||
/* add translations */
|
||||
$_SERVER['REQUEST_URI'] = 'settings';
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
|
||||
function scan($line, $text) {
|
||||
return stripos($line,$text)!==false;
|
||||
return stripos($line ?? '', $text) !== false;
|
||||
}
|
||||
|
||||
function safe_get($array, $key, $default = null) {
|
||||
return $array[$key] ?? $default;
|
||||
}
|
||||
|
||||
$reply = [];
|
||||
$name = urldecode($_POST['name']);
|
||||
switch ($_POST['id']) {
|
||||
case 'vm':
|
||||
// update vm
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
$file = "/var/tmp/$name.tmp";
|
||||
if (!file_exists($file)) {
|
||||
$reply = ['error' => "File: '$file' not found"];
|
||||
break;
|
||||
}
|
||||
// read new cpu assignments
|
||||
$cpuset = explode(',',file_get_contents($file)); unlink($file);
|
||||
$vcpus = count($cpuset);
|
||||
// initial cores/threads assignment
|
||||
$cores = $vcpus;
|
||||
$threads = 1;
|
||||
$ht = exec("lscpu|grep -Po '^Thread\\(s\\) per core:\\s+\\K\\d+'") ?: 1; // fetch hyperthreading
|
||||
/* Update VM */
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
|
||||
/* Path to the temporary file containing new CPU assignments */
|
||||
$file = "/var/tmp/$name.tmp";
|
||||
if (!file_exists($file)) {
|
||||
$reply = ['error' => "File: '$file' not found"];
|
||||
break;
|
||||
}
|
||||
|
||||
/* Read new CPU assignments and delete the temporary file */
|
||||
$cpuset = explode(',', file_get_contents($file));
|
||||
unlink($file);
|
||||
$vcpus = count($cpuset);
|
||||
|
||||
/* Initial cores/threads assignment */
|
||||
$cores = $vcpus;
|
||||
$threads = 1;
|
||||
$ht = exec("lscpu|grep -Po '^Thread\\(s\\) per core:\\s+\\K\\d+'") ?: 1; /* Fetch hyperthreading */
|
||||
|
||||
/* Adjust for hyperthreading */
|
||||
if ($vcpus > $ht && $vcpus % $ht === 0) {
|
||||
$cores /= $ht;
|
||||
$threads = $ht;
|
||||
}
|
||||
|
||||
/* Get the UUID of the VM */
|
||||
$uuid = $lv->domain_get_uuid($lv->get_domain_by_name($name));
|
||||
$dom = $lv->domain_get_domain_by_uuid($uuid);
|
||||
$auto = $lv->domain_get_autostart($dom) == 1;
|
||||
|
||||
/* Load the VM's XML configuration */
|
||||
$xml = simplexml_load_string($lv->domain_get_xml($dom));
|
||||
|
||||
/* Update topology and vpcus in the XML configuration */
|
||||
$xml->cpu->topology['cores'] = $cores;
|
||||
$xml->cpu->topology['threads'] = $threads;
|
||||
$xml->vcpu = $vcpus;
|
||||
|
||||
/* Preserve existing emulatorpin attributes */
|
||||
$pin = [];
|
||||
foreach ($xml->cputune->emulatorpin->attributes() as $key => $value) {
|
||||
$pin[$key] = (string) $value;
|
||||
}
|
||||
unset($xml->cputune);
|
||||
|
||||
/* Add new cputune configuration */
|
||||
$xml->addChild('cputune');
|
||||
for ($i = 0; $i < $vcpus; $i++) {
|
||||
$vcpu = $xml->cputune->addChild('vcpupin');
|
||||
$vcpu['vcpu'] = $i;
|
||||
$vcpu['cpuset'] = safe_get($cpuset, $i);
|
||||
}
|
||||
if ($pin) {
|
||||
$attr = $xml->cputune->addChild('emulatorpin');
|
||||
foreach ($pin as $key => $value) {
|
||||
$attr[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/* Stop the running VM first if it is running */
|
||||
$running = $lv->domain_get_state($dom) == 'running';
|
||||
if ($running) {
|
||||
$lv->domain_shutdown($dom);
|
||||
for ($n = 0; $n < 30; $n++) { /* Allow up to 30s for VM to shutdown */
|
||||
sleep(1);
|
||||
if ($stopped = $lv->domain_get_state($dom) == 'shutoff') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$stopped = true;
|
||||
}
|
||||
|
||||
/* If the VM failed to stop, return an error */
|
||||
if (!$stopped) {
|
||||
$reply = ['error' => _('Failed to stop') . " '$name'"];
|
||||
break;
|
||||
}
|
||||
|
||||
/* Backup NVRAM, undefine the domain, and restore NVRAM */
|
||||
$lv->nvram_backup($uuid);
|
||||
$lv->domain_undefine($dom);
|
||||
$lv->nvram_restore($uuid);
|
||||
|
||||
/* Define the domain with the updated XML configuration */
|
||||
if (!$lv->domain_define($xml->saveXML())) {
|
||||
$reply = ['error' => $lv->get_last_error()];
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set autostart for the domain */
|
||||
$lv->domain_set_autostart($dom, $auto);
|
||||
|
||||
/* If the VM was running before, start it again */
|
||||
if ($running && !$lv->domain_start($dom)) {
|
||||
$reply = ['error' => $lv->get_last_error()];
|
||||
} else {
|
||||
$reply = ['success' => $name];
|
||||
}
|
||||
break;
|
||||
|
||||
// adjust for hyperthreading
|
||||
if ($vcpus > $ht && $vcpus%$ht===0) {
|
||||
$cores /= $ht;
|
||||
$threads = $ht;
|
||||
}
|
||||
$uuid = $lv->domain_get_uuid($lv->get_domain_by_name($name));
|
||||
$dom = $lv->domain_get_domain_by_uuid($uuid);
|
||||
$auto = $lv->domain_get_autostart($dom)==1;
|
||||
$xml = simplexml_load_string($lv->domain_get_xml($dom));
|
||||
// update topology and vpcus
|
||||
$xml->cpu->topology['cores'] = $cores;
|
||||
$xml->cpu->topology['threads'] = $threads;
|
||||
$xml->vcpu = $vcpus;
|
||||
$pin = []; foreach ($xml->cputune->emulatorpin->attributes() as $key => $value) $pin[$key] = (string)$value;
|
||||
unset($xml->cputune);
|
||||
$xml->addChild('cputune');
|
||||
for ($i = 0; $i < $vcpus; $i++) {
|
||||
$vcpu = $xml->cputune->addChild('vcpupin');
|
||||
$vcpu['vcpu'] = $i;
|
||||
$vcpu['cpuset'] = $cpuset[$i];
|
||||
}
|
||||
if ($pin) {
|
||||
$attr = $xml->cputune->addChild('emulatorpin');
|
||||
foreach ($pin as $key => $value) $attr[$key] = $value;
|
||||
}
|
||||
// stop running vm first?
|
||||
$running = $lv->domain_get_state($dom)=='running';
|
||||
if ($running) {
|
||||
$lv->domain_shutdown($dom);
|
||||
for ($n =0; $n < 30; $n++) { // allow up to 30s for VM to shutdown
|
||||
sleep(1);
|
||||
if ($stopped = $lv->domain_get_state($dom)=='shutoff') break;
|
||||
}
|
||||
} else $stopped = true;
|
||||
if (!$stopped) {
|
||||
$reply = ['error' => _('Failed to stop')." '$name'"];
|
||||
break;
|
||||
}
|
||||
$lv->nvram_backup($uuid);
|
||||
$lv->domain_undefine($dom);
|
||||
$lv->nvram_restore($uuid);
|
||||
if (!$lv->domain_define($xml->saveXML())) {
|
||||
$reply = ['error' => $lv->get_last_error()];
|
||||
break;
|
||||
}
|
||||
$lv->domain_set_autostart($dom, $auto);
|
||||
if ($running && !$lv->domain_start($dom)) {
|
||||
$reply = ['error' => $lv->get_last_error()];
|
||||
} else {
|
||||
$reply = ['success' => $name];
|
||||
}
|
||||
break;
|
||||
case 'ct':
|
||||
// update docker container
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
$DockerClient = new DockerClient();
|
||||
$DockerTemplates = new DockerTemplates();
|
||||
// get available networks
|
||||
$subnet = DockerUtil::network(DockerUtil::custom());
|
||||
// get full template path
|
||||
$xml = $DockerTemplates->getUserTemplate($name);
|
||||
list($cmd, $ct, $repository) = xmlToCommand($xml);
|
||||
$imageID = $DockerClient->getImageID($repository);
|
||||
// pull image
|
||||
$container = $DockerClient->getContainerDetails($ct);
|
||||
// determine if the container is still running
|
||||
if (!empty($container) && !empty($container['State']) && !empty($container['State']['Running'])) {
|
||||
// since container was already running, put it back it to a running state after update
|
||||
$cmd = str_replace('/docker create ', '/docker run -d ', $cmd);
|
||||
// attempt graceful stop of container first
|
||||
$DockerClient->stopContainer($ct);
|
||||
}
|
||||
// force kill container if still running after time-out
|
||||
$DockerClient->removeContainer($ct);
|
||||
execCommand($cmd,false);
|
||||
$DockerClient->flushCaches();
|
||||
$newImageID = $DockerClient->getImageID($repository);
|
||||
// remove old orphan image since it's no longer used by this container
|
||||
if ($imageID && $imageID != $newImageID) {
|
||||
$DockerClient->removeImage($imageID);
|
||||
}
|
||||
$reply = ['success' => $name];
|
||||
break;
|
||||
/* update docker container */
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
$DockerClient = new DockerClient();
|
||||
$DockerTemplates = new DockerTemplates();
|
||||
|
||||
/* get available networks */
|
||||
$subnet = DockerUtil::network(DockerUtil::custom());
|
||||
|
||||
/* get full template path */
|
||||
$xml = $DockerTemplates->getUserTemplate($name);
|
||||
list($cmd, $ct, $repository) = xmlToCommand($xml);
|
||||
$imageID = $DockerClient->getImageID($repository);
|
||||
|
||||
/* pull image */
|
||||
$container = $DockerClient->getContainerDetails($ct);
|
||||
|
||||
/* determine if the container is still running */
|
||||
if (!empty($container) && !empty($container['State']) && !empty($container['State']['Running'])) {
|
||||
/* since container was already running, put it back it to a running state after update */
|
||||
$cmd = str_replace('/docker create ', '/docker run -d ', $cmd);
|
||||
|
||||
/* attempt graceful stop of container first */
|
||||
$DockerClient->stopContainer($ct);
|
||||
}
|
||||
|
||||
/* force kill container if still running after time-out */
|
||||
$DockerClient->removeContainer($ct);
|
||||
execCommand($cmd, false);
|
||||
$DockerClient->flushCaches();
|
||||
$newImageID = $DockerClient->getImageID($repository);
|
||||
|
||||
/* remove old orphan image since it's no longer used by this container */
|
||||
if ($imageID && $imageID != $newImageID) {
|
||||
$DockerClient->removeImage($imageID);
|
||||
}
|
||||
$reply = ['success' => $name];
|
||||
break;
|
||||
|
||||
case 'is':
|
||||
$cfg = '/boot/syslinux/syslinux.cfg';
|
||||
$syslinux = file($cfg, FILE_IGNORE_NEW_LINES+FILE_SKIP_EMPTY_LINES);
|
||||
$size = count($syslinux);
|
||||
$make = false;
|
||||
$file = "/var/tmp/$name.tmp";
|
||||
$isolcpus = file_get_contents($file);
|
||||
if ($isolcpus != '') {
|
||||
$numbers = explode(',',$isolcpus);
|
||||
sort($numbers,SORT_NUMERIC);
|
||||
$isolcpus = $previous = array_shift($numbers);
|
||||
$range = false;
|
||||
// convert sequential numbers to a range
|
||||
foreach ($numbers as $number) {
|
||||
if ($number == $previous+1) {
|
||||
$range = true;
|
||||
} else {
|
||||
if ($range) {$isolcpus .= '-'.$previous; $range = false;}
|
||||
$isolcpus .= ','.$number;
|
||||
}
|
||||
$previous = $number;
|
||||
}
|
||||
if ($range) $isolcpus .= '-'.$previous;
|
||||
$isolcpus = "isolcpus=$isolcpus";
|
||||
}
|
||||
unlink($file);
|
||||
$i = 0;
|
||||
while ($i < $size) {
|
||||
// find sections and exclude safemode
|
||||
if (scan($syslinux[$i],'label ') && !scan($syslinux[$i],'safe mode') && !scan($syslinux[$i],'safemode')) {
|
||||
$n = $i + 1;
|
||||
// find the current requested setting
|
||||
while (!scan($syslinux[$n],'label ') && $n < $size) {
|
||||
if (scan($syslinux[$n],'append ')) {
|
||||
$cmd = preg_split('/\s+/',trim($syslinux[$n]));
|
||||
// replace an existing setting
|
||||
for ($c = 1; $c < count($cmd); $c++) if (scan($cmd[$c],'isolcpus')) {$make |= ($cmd[$c]!=$isolcpus); $cmd[$c] = $isolcpus; break;}
|
||||
// or insert a new setting
|
||||
if ($c==count($cmd) && $isolcpus) {array_splice($cmd,-1,0,$isolcpus); $make = true;}
|
||||
$syslinux[$n] = ' '.str_replace(' ',' ',implode(' ',$cmd));
|
||||
}
|
||||
$n++;
|
||||
}
|
||||
$i = $n - 1;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
if ($make) file_put_contents($cfg, implode("\n",$syslinux)."\n");
|
||||
$reply = ['success' => $name];
|
||||
break;
|
||||
/* Path to syslinux configuration file */
|
||||
$cfg = '/boot/syslinux/syslinux.cfg';
|
||||
|
||||
/* Read the syslinux configuration file into an array, ignoring empty lines */
|
||||
$syslinux = file($cfg, FILE_IGNORE_NEW_LINES + FILE_SKIP_EMPTY_LINES);
|
||||
$size = count($syslinux);
|
||||
$make = false;
|
||||
|
||||
/* Path to the temporary file containing new isolcpus settings */
|
||||
$file = "/var/tmp/$name.tmp";
|
||||
$isolcpus = file_get_contents($file);
|
||||
|
||||
if ($isolcpus != '') {
|
||||
/* Convert isolcpus string to an array of numbers and sort them */
|
||||
$numbers = explode(',', $isolcpus);
|
||||
sort($numbers, SORT_NUMERIC);
|
||||
|
||||
/* Initialize variables for range conversion */
|
||||
$isolcpus = $previous = array_shift($numbers);
|
||||
$range = false;
|
||||
|
||||
/* Convert sequential numbers to a range */
|
||||
foreach ($numbers as $number) {
|
||||
if ($number == $previous + 1) {
|
||||
$range = true;
|
||||
} else {
|
||||
if ($range) {
|
||||
$isolcpus .= '-' . $previous;
|
||||
$range = false;
|
||||
}
|
||||
$isolcpus .= ',' . $number;
|
||||
}
|
||||
$previous = $number;
|
||||
}
|
||||
if ($range) {
|
||||
$isolcpus .= '-' . $previous;
|
||||
}
|
||||
|
||||
/* Format isolcpus string for syslinux configuration */
|
||||
$isolcpus = "isolcpus=$isolcpus";
|
||||
}
|
||||
|
||||
/* Remove the temporary file */
|
||||
unlink($file);
|
||||
|
||||
$i = 0;
|
||||
while ($i < $size) {
|
||||
/* Find sections in syslinux config and exclude safemode */
|
||||
if (scan($syslinux[$i], 'label ') && !scan($syslinux[$i], 'safe mode') && !scan($syslinux[$i], 'safemode')) {
|
||||
$n = $i + 1;
|
||||
|
||||
/* Find the current requested setting */
|
||||
while ($n < $size && !scan($syslinux[$n], 'label ')) {
|
||||
if (scan($syslinux[$n], 'append ')) {
|
||||
$cmd = preg_split('/\s+/', trim($syslinux[$n]));
|
||||
|
||||
/* Replace an existing isolcpus setting */
|
||||
for ($c = 1; $c < count($cmd); $c++) {
|
||||
if (scan($cmd[$c], 'isolcpus')) {
|
||||
$make |= ($cmd[$c] != $isolcpus);
|
||||
$cmd[$c] = $isolcpus;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Or insert a new isolcpus setting if not found */
|
||||
if ($c == count($cmd) && $isolcpus) {
|
||||
array_splice($cmd, -1, 0, $isolcpus);
|
||||
$make = true;
|
||||
}
|
||||
|
||||
/* Update the syslinux configuration line */
|
||||
$syslinux[$n] = ' ' . str_replace(' ', ' ', implode(' ', $cmd));
|
||||
}
|
||||
$n++;
|
||||
}
|
||||
$i = $n - 1;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
/* Write the updated syslinux configuration back to the file if changes were made */
|
||||
if ($make) {
|
||||
file_put_contents($cfg, implode("\n", $syslinux) . "\n");
|
||||
}
|
||||
|
||||
$reply = ['success' => $name];
|
||||
break;
|
||||
}
|
||||
header('Content-Type: application/json');
|
||||
die(json_encode($reply));
|
||||
echo json_encode($reply);
|
||||
exit;
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user