mirror of
https://github.com/unraid/webgui.git
synced 2026-01-04 00:19:57 -06:00
Wip update.
This commit is contained in:
@@ -267,7 +267,7 @@
|
||||
}
|
||||
|
||||
|
||||
function config_to_xml($config) {
|
||||
function config_to_xml($config,$vmclone = false) {
|
||||
$domain = $config['domain'];
|
||||
$media = $config['media'];
|
||||
$nics = $config['nic'];
|
||||
@@ -463,19 +463,27 @@
|
||||
$usbstr = '';
|
||||
if (!empty($usb)) {
|
||||
foreach($usb as $i => $v){
|
||||
$usbx = explode(':', $v);
|
||||
if ($vmclone) $usbx = explode(':', $v['id']); else $usbx = explode(':', $v);
|
||||
$startupPolicy = '' ;
|
||||
if (isset($usbopt[$v])) {
|
||||
if (isset($usbopt[$v]) && !$vmclone ) {
|
||||
if (strpos($usbopt[$v], "#remove") == false) $startupPolicy = 'startupPolicy="optional"' ; else $startupPolicy = '' ;
|
||||
}
|
||||
}
|
||||
if ($vmclone ) {
|
||||
if ($v["startupPolicy"] == "optional" ) $startupPolicy = 'startupPolicy="optional"' ; else $startupPolicy = '' ;
|
||||
#$startupPolicy = 'startupPolicy="optional"' ;
|
||||
}
|
||||
|
||||
$usbstr .= "<hostdev mode='subsystem' type='usb'>
|
||||
<source $startupPolicy>
|
||||
<vendor id='0x".$usbx[0]."'/>
|
||||
<product id='0x".$usbx[1]."'/>
|
||||
</source>" ;
|
||||
if (!empty($usbboot[$v])) {
|
||||
if (!empty($usbboot[$v]) && !$vmclone ) {
|
||||
$usbstr .= "<boot order='".$usbboot[$v]."'/>" ;
|
||||
}
|
||||
}
|
||||
if ($vmclone ) {
|
||||
if ($v["usbboot"] != NULL) $usbstr .= "<boot order='".$v["usbboot"]."'/>" ;
|
||||
}
|
||||
$usbstr .= "</hostdev>";
|
||||
}
|
||||
}
|
||||
@@ -857,20 +865,23 @@
|
||||
if (empty($pci_id) || in_array($pci_id, $pcidevs_used)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
[$pci_bus, $pci_slot, $pci_function] = my_explode(":", str_replace('.', ':', $pci_id), 3);
|
||||
if ($vmclone) [$pci_bus, $pci_slot, $pci_function] = my_explode(":", str_replace('.', ':', $pci_id['id']), 3);
|
||||
else [$pci_bus, $pci_slot, $pci_function] = my_explode(":", str_replace('.', ':', $pci_id), 3);
|
||||
|
||||
$pcidevs .= "<hostdev mode='subsystem' type='pci' managed='yes'>
|
||||
<driver name='vfio'/>
|
||||
<source>
|
||||
<address domain='0x0000' bus='0x" . $pci_bus . "' slot='0x" . $pci_slot . "' function='0x" . $pci_function . "'/>
|
||||
</source>" ;
|
||||
if (!empty($pciboot[$pci_id])) {
|
||||
if (!empty($pciboot[$pci_id]) && !$vmclone) {
|
||||
$pcidevs .= "<boot order='".$pciboot[$pci_id]."'/>" ;
|
||||
}
|
||||
if (!empty($pci_id["boot"]) && $vmclone) {
|
||||
$pcidevs .= "<boot order='".$pci_id["boot"]."'/>" ;
|
||||
}
|
||||
$pcidevs .= "</hostdev>";
|
||||
|
||||
$pcidevs_used[] = $pci_id;
|
||||
if ($vmclone) $pcidevs_used[] = $pci_id['d']; else $pcidevs_used[] = $pci_id ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1481,84 +1481,86 @@ private static $encoding = 'UTF-8';
|
||||
|
||||
If option to edit, show VMUpdate
|
||||
*/
|
||||
$uuid = $lv->domain_get_uuid($clone) ;
|
||||
write("addLog\0".htmlspecialchars("checking if Clone UUID exists $uuid"));
|
||||
if ($uuid) { $arrResponse = ['error' => _("Clone VM name already inuse")]; return $arrResponse ;}
|
||||
#VM must be shutdown.
|
||||
$res = $lv->get_domain_by_name($vm);
|
||||
$dom = $lv->domain_get_info($res);
|
||||
$state = $lv->domain_state_translate($dom['state']);
|
||||
file_put_contents("/tmp/cloningxml" ,$lv->domain_get_xml($res)) ;
|
||||
# if VM running shutdown. Record was running.
|
||||
if ($state != 'shutoff') {write("addLog\0".htmlspecialchars("Shuting down $vm current $state")); $arrResponse = $lv->domain_destroy($vm) ; }
|
||||
# Wait for shutdown?
|
||||
$uuid = $lv->domain_get_uuid($clone) ;
|
||||
write("addLog\0".htmlspecialchars(_("Checking if clone exists")));
|
||||
if ($uuid) { $arrResponse = ['error' => _("Clone VM name already inuse")]; return $arrResponse ;}
|
||||
#VM must be shutdown.
|
||||
$res = $lv->get_domain_by_name($vm);
|
||||
$dom = $lv->domain_get_info($res);
|
||||
$state = $lv->domain_state_translate($dom['state']);
|
||||
$vmxml = $lv->domain_get_xml($res) ;
|
||||
file_put_contents("/tmp/cloningxml" ,$vmxml) ;
|
||||
# if VM running shutdown. Record was running.
|
||||
if ($state != 'shutoff') {write("addLog\0".htmlspecialchars(_("Shuting down $vm current $state"))); $arrResponse = $lv->domain_destroy($vm) ; }
|
||||
# Wait for shutdown?
|
||||
|
||||
$disks =$lv->get_disk_stats($vm) ;
|
||||
$disks =$lv->get_disk_stats($vm) ;
|
||||
|
||||
$capacity = 0 ;
|
||||
|
||||
foreach($disks as $disk) {
|
||||
$file = $disk["file"] ;
|
||||
$pathinfo = pathinfo($file) ;
|
||||
$filenew = $pathinfo["dirname"].'/'.$pathinfo["filename"].'.'.$name.'qcow2' ;
|
||||
$capacity = $capacity + $disk["capacity"] ;
|
||||
$capacity = 0 ;
|
||||
|
||||
foreach($disks as $disk) {
|
||||
$file = $disk["file"] ;
|
||||
$pathinfo = pathinfo($file) ;
|
||||
$filenew = $pathinfo["dirname"].'/'.$pathinfo["filename"].'.'.$name.'qcow2' ;
|
||||
$capacity = $capacity + $disk["capacity"] ;
|
||||
}
|
||||
$dirpath = $pathinfo["dirname"] ;
|
||||
|
||||
#Check free space.
|
||||
write("addLog\0".htmlspecialchars("Checking for free space"));
|
||||
$dirfree = disk_free_space($pathinfo["dirname"]) ;
|
||||
|
||||
$capacity *= 1 ;
|
||||
|
||||
if ($free == "yes" && $dirfree < $capacity) { write("addLog\0".htmlspecialchars(_("Insufficent storage for clone"))); return false ;}
|
||||
|
||||
#Clone XML
|
||||
$uuid = $lv->domain_get_uuid($vm) ;
|
||||
$config=domain_to_config($uuid) ;
|
||||
|
||||
$config["domain"]["name"] = $clone ;
|
||||
$config["domain"]["uuid"] = $lv->domain_generate_uuid() ;
|
||||
foreach($config["nic"] as $index => $detail) {
|
||||
$config["nic"][$index]["mac"] = $lv->generate_random_mac_addr() ;
|
||||
}
|
||||
$config["domain"]["type"] = "kvm";
|
||||
|
||||
$usbs = getVMUSBs($vmxml) ;
|
||||
foreach($usbs as $i => $usb) {
|
||||
if ($usb["checked"] == "checked") continue ;
|
||||
unset($usbs[$i]) ;
|
||||
}
|
||||
$config["domain"]["usb"] = $usbs ;
|
||||
|
||||
$files_exist = false ;
|
||||
$files_clone = array() ;
|
||||
foreach ($config["disk"] as $diskid => $disk) {
|
||||
$file_clone[$diskid]["source"] = $config["disk"][$diskid]["new"] ;
|
||||
$config["disk"][$diskid]["new"] = str_replace($vm,$clone,$config["disk"][$diskid]["new"]) ;
|
||||
$pi = pathinfo($config["disk"][$diskid]["new"]) ;
|
||||
$isdir = is_dir($pi['dirname']) ;
|
||||
if (is_file($config["disk"][$diskid]["new"])) $file_exists = true ;
|
||||
$file_clone[$diskid]["target"] = $config["disk"][$diskid]["new"] ;
|
||||
}
|
||||
$dirpath = $pathinfo["dirname"] ;
|
||||
|
||||
#Check free space.
|
||||
write("addLog\0".htmlspecialchars("Checking for free space"));
|
||||
$dirfree = disk_free_space($pathinfo["dirname"]) ;
|
||||
|
||||
$capacity *= 1 ;
|
||||
|
||||
if ($free == "yes" && $dirfree < $capacity) { write("addLog\0".htmlspecialchars("Insufficent Storage for Clone")); return false ;}
|
||||
|
||||
#Clone XML
|
||||
$uuid = $lv->domain_get_uuid($vm) ;
|
||||
$config=domain_to_config($uuid) ;
|
||||
|
||||
$config["domain"]["name"] = $clone ;
|
||||
$config["domain"]["uuid"] = $lv->domain_generate_uuid() ;
|
||||
foreach($config["nic"] as $index => $detail) {
|
||||
$config["nic"][$index]["mac"] = $lv->generate_random_mac_addr() ;
|
||||
}
|
||||
$config["domain"]["type"] = "kvm";
|
||||
|
||||
$files_exist = false ;
|
||||
$files_clone = array() ;
|
||||
foreach ($config["disk"] as $diskid => $disk) {
|
||||
$file_clone[$diskid]["source"] = $config["disk"][$diskid]["new"] ;
|
||||
$config["disk"][$diskid]["new"] = str_replace($vm,$clone,$config["disk"][$diskid]["new"]) ;
|
||||
$pi = pathinfo($config["disk"][$diskid]["new"]) ;
|
||||
$isdir = is_dir($pi['dirname']) ;
|
||||
if (is_file($config["disk"][$diskid]["new"])) $file_exists = true ;
|
||||
$file_clone[$diskid]["target"] = $config["disk"][$diskid]["new"] ;
|
||||
}
|
||||
|
||||
$clonedir = $domain_cfg['DOMAINDIR'].$clone ;
|
||||
if (!is_dir($clonedir)) mkdir($clonedir) ;
|
||||
write("addLog\0".htmlspecialchars("Checking for image files"));
|
||||
if ($file_exists && $overwrite != "yes") { write("addLog\0".htmlspecialchars("New image file names exist and Overwrite is set to No")); return( false) ; }
|
||||
if ($file_exists && $overwrite != "yes") { write("addLog\0".htmlspecialchars(_("New image file names exist and Overwrite is not allowed"))); return( false) ; }
|
||||
|
||||
#Create duplicate files.
|
||||
foreach($file_clone as $diskid => $disk) {
|
||||
$cmdstr = "touch {$disk['target']}" ;
|
||||
$sparse = "-S ";
|
||||
$target = $disk['target'] ;
|
||||
$source = $disk['source'] ;
|
||||
$cmdstr = "rsync -ahPIX $sparse --out-format=%f --info=flist0,misc0,stats0,name1,progress2 '$source' '$target'" ;
|
||||
$cmdstr = "rsync -ahPIXS --out-format=%f --info=flist0,misc0,stats0,name1,progress2 '$source' '$target'" ;
|
||||
$error = execCommand_nchan($cmdstr,$path) ;
|
||||
if (!$error) {
|
||||
$arrResponse = ['error' => substr($output[0],6) ] ;
|
||||
return($arrResponse) ;
|
||||
} else {
|
||||
$arrResponse = ['success' => true] ;
|
||||
}
|
||||
|
||||
if (!$error) { write("addLog\0".htmlspecialchars("Image copied failed.")); return( false) ; }
|
||||
}
|
||||
write("<p class='logLine'></p>","addLog\0<fieldset class='docker'><legend>"._("Options for Block $action").": </legend><p class='logLine'></p><span id='wait-$waitID'></span></fieldset>");
|
||||
|
||||
write("<p class='logLine'></p>","addLog\0<fieldset class='docker'><legend>"._("Completing Clone").": </legend><p class='logLine'></p><span id='wait-$waitID'></span></fieldset>");
|
||||
write("addLog\0".htmlspecialchars("Creating new XML $clone"));
|
||||
$xml = $lv->config_to_xml($config) ;
|
||||
|
||||
$xml = $lv->config_to_xml($config, true) ;
|
||||
file_put_contents("/tmp/clonexml" ,$xml) ;
|
||||
$rtn = $lv->domain_define($xml) ;
|
||||
return($rtn) ;
|
||||
|
||||
@@ -21,6 +21,7 @@ $login_locale = _var($display,'locale');
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
function write(...$messages){
|
||||
$com = curl_init();
|
||||
curl_setopt_array($com,[
|
||||
@@ -40,16 +41,18 @@ function execCommand_nchan($command,$idx) {
|
||||
[$cmd,$args] = explode(' ',$command,2);
|
||||
write("<p class='logLine'></p>","addLog\0<fieldset class='docker'><legend>"._('Command execution')."</legend>".basename($cmd).' '.str_replace(" -","<br> -",htmlspecialchars($args))."<br><span id='wait-$waitID'>"._('Please wait')." </span><p class='logLine'></p></fieldset>","show_Wait\0$waitID");
|
||||
|
||||
write("addToID\0$idx\0 $action") ;
|
||||
write("addToID\0$idx\0Cloning VM: ") ;
|
||||
$proc = popen("$command 2>&1 &",'r');
|
||||
while ($out = fread($proc,100)) {
|
||||
$out = preg_replace("%[\t\n\x0B\f\r]+%", '',$out);
|
||||
$out = trim($out) ;
|
||||
$values = explode(' ',$out) ;
|
||||
$string = "Data copied: ".$values[0]." Percentage: ".$values[1]." Transfer Rate: ".$values[2]." Time remaining: ".$values[3]." ".$values[4]." ".$values[5];
|
||||
$string = _("Data copied: ").$values[0]._(" Percentage: ").$values[1]._(" Transfer Rate: ").$values[2]._(" Time remaining: ").$values[3] ;
|
||||
write("progress\0$idx\0".htmlspecialchars($string)) ;
|
||||
if ($out) $stringsave=$string ;
|
||||
}
|
||||
$retval = pclose($proc);
|
||||
write("progress\0$idx\0".htmlspecialchars($stringsave)) ;
|
||||
$out = $retval ? _('The command failed').'.' : _('The command finished successfully').'!';
|
||||
write("stop_Wait\0$waitID","addLog\0<br><b>$out</b>");
|
||||
return $retval===0;
|
||||
|
||||
Reference in New Issue
Block a user