diff --git a/emhttp/plugins/dynamix.vm.manager/VMMachines.page b/emhttp/plugins/dynamix.vm.manager/VMMachines.page index 138664951..f2374e4c1 100644 --- a/emhttp/plugins/dynamix.vm.manager/VMMachines.page +++ b/emhttp/plugins/dynamix.vm.manager/VMMachines.page @@ -326,15 +326,15 @@ _(ISO Image)_: _(New VM)_: - + _(Overwrite)_: -_(Start Cloned VM)_: +_(Start Cloned VM)_: -_(Edit VM after clone)_: +_(Edit VM after clone)_: _(Check Free Space)_: diff --git a/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php b/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php index e80ada8a7..d942c3d60 100644 --- a/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php +++ b/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php @@ -1481,13 +1481,16 @@ 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 != 'shutdown') $arrResponse = $lv->domain_destroy($vm) ; + 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) ; @@ -1498,7 +1501,6 @@ private static $encoding = 'UTF-8'; $file = $disk["file"] ; $pathinfo = pathinfo($file) ; $filenew = $pathinfo["dirname"].'/'.$pathinfo["filename"].'.'.$name.'qcow2' ; - $diskspec .= " --diskspec '".$disk["device"]."',snapshot=external,file='".$filenew."'" ; $capacity = $capacity + $disk["capacity"] ; } $dirpath = $pathinfo["dirname"] ; @@ -1509,7 +1511,7 @@ private static $encoding = 'UTF-8'; $capacity *= 1 ; - if ($free == "yes" && $dirfree < $capacity) { $arrResponse = ['error' => _("Insufficent Storage for Clone")]; return $arrResponse ;} + if ($free == "yes" && $dirfree < $capacity) { write("addLog\0".htmlspecialchars("Insufficent Storage for Clone")); return false ;} #Clone XML $uuid = $lv->domain_get_uuid($vm) ; @@ -1523,23 +1525,28 @@ private static $encoding = 'UTF-8'; $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("Overwrite $overwrite Start $start Edit $edit Check Freespace $free")); write("addLog\0".htmlspecialchars("Checking for image files")); - if ($file_exists && $overwrite != "yes") { $arrResponse = ['error' => _("New image file names exist and Overwrite is no")]; return $arrResponse ;} + if ($file_exists && $overwrite != "yes") { write("addLog\0".htmlspecialchars("New image file names exist and Overwrite is set to No")); return( false) ; } #Create duplicate files. - foreach($config["disk"] as $diskid => $disk) { - $cmdstr = "touch {$config['disk'][$diskid]['new']}" ; + 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'" ; $error = execCommand_nchan($cmdstr,$path) ; if (!$error) { $arrResponse = ['error' => substr($output[0],6) ] ; @@ -1549,14 +1556,12 @@ private static $encoding = 'UTF-8'; } } - write("

","addLog\0
"._("Options for Block $action").":

"._('Please wait')."
"); + write("

","addLog\0
"._("Options for Block $action").":

"); write("addLog\0".htmlspecialchars("Creating new XML $clone")); $xml = $lv->config_to_xml($config) ; - file_put_contents("/tmp/xml" ,$xml) ; - - - $arrResponse = ['error' => _("Insufficent Storage for Clone")]; - return$arrResponse ; + file_put_contents("/tmp/clonexml" ,$xml) ; + $rtn = $lv->domain_define($xml) ; + return($rtn) ; } diff --git a/emhttp/plugins/dynamix.vm.manager/javascript/vmmanager.js b/emhttp/plugins/dynamix.vm.manager/javascript/vmmanager.js index fed59144e..8b82d5c72 100644 --- a/emhttp/plugins/dynamix.vm.manager/javascript/vmmanager.js +++ b/emhttp/plugins/dynamix.vm.manager/javascript/vmmanager.js @@ -278,10 +278,9 @@ function VMClone(uuid, name){ var height = 200; box.html($("#templateClone").html()); box.find('#VMBeingCloned').html(name).change() ; + box.find('#target').val(name + "_clone") ; document.getElementById("Free").checked = true ; document.getElementById("Overwrite").checked = true ; - //document.getElementById("targetsnapkeep").checked = true ; - //document.getElementById("targetsnapfspc").checked = true ; box.dialog({ title: "VM Clone", @@ -300,8 +299,6 @@ function VMClone(uuid, name){ } else target = ''; var clone = box.find("#target").prop('value') ; - - x = box.find('#Start').prop('checked') ; if (x) start = 'yes' ; else start = 'no' ; x = box.find('#Edit').prop('checked') ; diff --git a/emhttp/plugins/dynamix.vm.manager/scripts/VMClone.php b/emhttp/plugins/dynamix.vm.manager/scripts/VMClone.php index 50d32782d..342242ddc 100755 --- a/emhttp/plugins/dynamix.vm.manager/scripts/VMClone.php +++ b/emhttp/plugins/dynamix.vm.manager/scripts/VMClone.php @@ -39,14 +39,15 @@ function execCommand_nchan($command,$idx) { $waitID = mt_rand(); [$cmd,$args] = explode(' ',$command,2); write("

","addLog\0
"._('Command execution')."".basename($cmd).' '.str_replace(" -","
  -",htmlspecialchars($args))."
"._('Please wait')."

","show_Wait\0$waitID"); - write("addLog\0
") ; + write("addToID\0$idx\0 $action") ; - $proc = popen("$command 2>&1",'r'); - while ($out = fgets($proc)) { + $proc = popen("$command 2>&1 &",'r'); + while ($out = fread($proc,100)) { $out = preg_replace("%[\t\n\x0B\f\r]+%", '',$out); - if (substr($out,0,1) == "B") { ; - write("progress\0$idx\0".htmlspecialchars(substr($out,strrpos($out,"Block Pull")))) ; - } else echo write("addToID\0$idx\0 ".htmlspecialchars($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]; + write("progress\0$idx\0".htmlspecialchars($string)) ; } $retval = pclose($proc); $out = $retval ? _('The command failed').'.' : _('The command finished successfully').'!'; @@ -73,18 +74,15 @@ foreach (explode('&', $url) as $chunk) { $id = 1 ; write(implode($style)."

"); $process = " " ; -write("

","addLog\0
"._("Options for Block $action").":

"._('Please wait')."
"); -write("addLog\0".htmlspecialchars("VMName $name ")); -write("addLog\0".htmlspecialchars("Clone $clone ")); -write("addLog\0".htmlspecialchars("Overwrite $overwrite Start $start Edit $edit Check Freespace $free")); +$actiontxt = ucfirst($action) ; +write("

","addLog\0
"._("Options for $actiontxt").":

"); +write("addLog\0".htmlspecialchars("Cloning $name to $clone")); switch ($action) { case "clone": - vm_clone($name,$clone,$overwrite,$start,$edit,$free,$waitID) ; - break ; + $rtn = vm_clone($name,$clone,$overwrite,$start,$edit,$free,$waitID) ; + break ; } -#execCommand_nchan("ls /") ; write("stop_Wait\0$waitID") ; -write('_DONE_',''); - +if ($rtn) write('_DONE_',''); else write('_ERROR_',''); ?> \ No newline at end of file diff --git a/emhttp/plugins/dynamix/DashStats.page b/emhttp/plugins/dynamix/DashStats.page index 20e17c8d0..acb7a3c65 100644 --- a/emhttp/plugins/dynamix/DashStats.page +++ b/emhttp/plugins/dynamix/DashStats.page @@ -181,6 +181,7 @@ div.last{padding-bottom:12px} div.leftside{float:left;width:66%} div.rightside{float:right;margin:0;text-align:center} div[id$=chart]{margin:-12px 8px -24px -18px} +div.template,div#dialogWindow,input#upload{display:none} span.green,span.red,span.orange{padding-left:0} span.ctrl{float:right;margin-top:0;margin-right:10px} span.ctrl span{font-size:2rem!important} @@ -1504,4 +1505,47 @@ $(function() { $.post('/webGui/include/InitCharts.php',{cmd:'set',data:JSON.stringify(data)}); }); }); + function dialogStyle() { + $('.ui-dialog-titlebar-close').css({'background':'transparent','border':'none','font-size':'1.8rem','margin-top':'-14px','margin-right':'-18px'}).html('').prop('title'); + $('.ui-dialog-title').css({'text-align':'center','width':'100%','font-size':'1.8rem'}); + $('.ui-dialog-content').css({'padding-top':'15px','vertical-align':'bottom'}); + $('.ui-button-text').css({'padding':'0px 5px'}); +} + +
+
+lang=""> + + + + + + + +"> + + +
+ + + + + + + + + + + + + + + + + + +
_(VM Being Cloned)_:
_(New VM)_:
_(Overwrite)_:
_(Check Free Space)_:
+ + +
\ No newline at end of file diff --git a/emhttp/plugins/dynamix/include/DefaultPageLayout.php b/emhttp/plugins/dynamix/include/DefaultPageLayout.php index f3e67955f..db36fda94 100644 --- a/emhttp/plugins/dynamix/include/DefaultPageLayout.php +++ b/emhttp/plugins/dynamix/include/DefaultPageLayout.php @@ -410,6 +410,14 @@ function openDone(data) { } return false; } +function openError(data) { + if (data == '_ERROR_') { + $('div.spinner.fixed').hide(); + $('button.confirm').text("").prop('disabled',false).show(); + return true; + } + return false; +} function showStatus(name,plugin,job) { $.post('/webGui/include/ProcessStatus.php',{name:name,plugin:plugin,job:job},function(status){$(".tabs").append(status);}); } @@ -940,7 +948,7 @@ nchan_docker.on('message', function(data) { }); var nchan_vmaction = new NchanSubscriber('/sub/vmaction',{subscriber:'websocket'}); nchan_vmaction.on('message', function(data) { - if (!data || openDone(data)) return; + if (!data || openDone(data) || openError(data)) return; var box = $('pre#swaltext'); data = data.split('\0'); switch (data[0]) {