Initial commit of php-virt-control 0.0.1
authorMichal Novotny <mignov@gmail.com>
Thu, 23 Jun 2011 09:00:04 +0000 (11:00 +0200)
committerMichal Novotny <mignov@gmail.com>
Thu, 23 Jun 2011 09:00:04 +0000 (11:00 +0200)
Signed-off-by: Michal Novotny <minovotn@redhat.com>

18 files changed:
error.php [new file with mode: 0644]
index.php [new file with mode: 0644]
libvirt.php [new file with mode: 0644]
main-menu.php [new file with mode: 0644]
manager.css [new file with mode: 0644]
menu.php [new file with mode: 0644]
pages/details/boot-options.php [new file with mode: 0644]
pages/details/disk-devices.php [new file with mode: 0644]
pages/details/host-devices.php [new file with mode: 0644]
pages/details/memory.php [new file with mode: 0644]
pages/details/multimedia-devices.php [new file with mode: 0644]
pages/details/network-devices.php [new file with mode: 0644]
pages/details/overview.php [new file with mode: 0644]
pages/details/processor.php [new file with mode: 0644]
pages/details/screenshot.php [new file with mode: 0644]
pages/domain-list.php [new file with mode: 0644]
pages/info.php [new file with mode: 0644]
pages/overview.php [new file with mode: 0644]

diff --git a/error.php b/error.php
new file mode 100644 (file)
index 0000000..63cc459
--- /dev/null
+++ b/error.php
@@ -0,0 +1,13 @@
+  <!-- CONTENTS -->
+  <div id="content">
+
+    <div class="section">Error</div>
+    <div class="item">
+      <div class="label">Page not found:</div>
+      <div class="value">The page you were looking for was not found. Please report to the administrator and try again later.</div>
+      <div class="nl" />
+    </div>
+
+    </form>
+
+  </div>
diff --git a/index.php b/index.php
new file mode 100644 (file)
index 0000000..1dec1ec
--- /dev/null
+++ b/index.php
@@ -0,0 +1,56 @@
+<?php
+  define('PHPVIRTCONTROL_VERSION', '0.0.1');
+
+  session_start();
+  require('libvirt.php');
+  $uri = array_key_exists('connection_uri', $_SESSION) ? $_SESSION['connection_uri'] : 'null';
+  $lg = array_key_exists('connection_logging', $_SESSION) ? $_SESSION['connection_logging'] : false;
+
+  if ($lg == '')
+       $lg = false;
+
+  if ($lg)
+    $lg = 'logs/'.$lg;
+
+  $errmsg = false;
+  $lv = new Libvirt($uri, $lg);
+  if ($lv->get_last_error()) {
+    $page = 'overview';
+    $name = false;
+    $errmsg = 'Cannot connect to hypervisor. Please change connection information.';
+  }
+  else {
+    $name = array_key_exists('name', $_GET) ? $_GET['name'] : false;
+    $res = $lv->get_domain_by_name($name);
+    $page = array_key_exists('page', $_GET) ? $_GET['page'] : 'overview';
+  }
+?>
+<html>
+<head>
+ <title>phpVirtControl - Virtual machine controller</title>
+ <link rel="STYLESHEET" type="text/css" href="manager.css"> 
+</head>
+<body>
+  <h1>PHP Virtual machine controller</h1>
+
+  <?php include('main-menu.php'); ?>
+
+  <?php
+       if ($name):
+  ?>
+       <h2 id="vm-name">Virtual machine <?= $name ?></h2>
+  <?php
+       include('menu.php');
+       if (File_Exists('./pages/details/'.$page.'.php'))
+               include('./pages/details/'.$page.'.php');
+       else
+               include('error.php');
+       else:
+       if (File_Exists('./pages/'.$page.'.php'))
+               include('./pages/'.$page.'.php');
+       else
+               include('error.php');
+       endif;
+  ?>
+</body>
+</html>
diff --git a/libvirt.php b/libvirt.php
new file mode 100644 (file)
index 0000000..aac74b4
--- /dev/null
@@ -0,0 +1,1225 @@
+<?php
+       class Libvirt {
+               private $conn;
+               private $last_error;
+               private $allow_cached = true;
+               private $dominfos = array();
+
+               function Libvirt($uri = false, $debug=false) {
+                       if ($debug)
+                               $this->set_logfile($debug);
+                       if ($uri != false)
+                               $this->connect($uri);
+               }
+
+               function _set_last_error()
+               {
+                       $this->last_error = libvirt_get_last_error();
+                       return false;
+               }
+
+               function set_logfile($filename)
+               {
+                       if (!libvirt_logfile_set($filename))
+                               return $this->_set_last_error();
+
+                       return true;
+               }
+
+               function generate_connection_uri($hv, $remote, $remote_method, $remote_username, $remote_hostname) {
+                       if ($hv == 'qemu')
+                               $append_type = 'system';
+
+                       if (!$remote) {
+                               if ($hv == 'xen')
+                                       return 'xen:///';
+                               if ($hv == 'qemu')
+                                       return 'qemu:///'.$append_type;
+
+                               return false;
+                       }
+
+                       if ($hv == 'xen')
+                               return 'xen+'.$remote_method.'://'.$remote_username.'@'.$remote_hostname;
+                       else
+                       if ($hv == 'qemu')
+                               return 'qemu+'.$remote_method.'://'.$remote_username.'@'.$remote_hostname.'/'.$append_type;
+               }
+
+               function print_resources() {
+                       return libvirt_print_binding_resources();
+               }
+
+               function connect($uri = 'null') {
+                       $this->conn=libvirt_connect($uri, false);
+                       if ($this->conn==false)
+                               return $this->_set_last_error();
+               }
+
+                function domain_disk_add($domain, $img, $dev, $type='scsi', $driver='raw') {
+                        $dom = $this->get_domain_object($domain);
+
+                        $tmp = libvirt_domain_disk_add($dom, $img, $dev, $type, $driver);
+                        return ($tmp) ? $tmp : $this->_set_last_error();
+                }
+
+               function domain_change_numVCpus($domain, $num) {
+                       $dom = $this->get_domain_object($domain);
+
+                       $tmp = libvirt_domain_change_vcpus($dom, $num);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_change_memory_allocation($domain, $memory, $maxmem) {
+                       $dom = $this->get_domain_object($domain);
+
+                       $tmp = libvirt_domain_change_memory($dom, $memory, $maxmem);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_change_boot_devices($domain, $first, $second) {
+                       $dom = $this->get_domain_object($domain);
+
+                       $tmp = libvirt_domain_change_boot_devices($dom, $first, $second);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_get_screenshot($domain) {
+                       $dom = $this->get_domain_object($domain);
+
+                       $tmp = libvirt_domain_get_screenshot($dom, $this->get_hostname() );
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_get_screenshot_thumbnail($domain, $w=120) {
+                       $screen = $this->domain_get_screenshot($domain);
+                       $imgFile = tempnam("/tmp", "libvirt-php-tmp-resize-XXXXXX");;
+
+                       if ($screen) {
+                               $fp = fopen($imgFile, "wb");
+                               fwrite($fp, $screen);
+                               fclose($fp);
+                       }
+
+                       if (file_exists($imgFile) && $screen) {
+                               list($width, $height) = getimagesize($imgFile); 
+                               $h = ($height / $width) * $w;
+                       } else {
+                               $w = $h = 1;
+                               //$h = $w * (3 / 4.5);
+                       }
+
+                       $new = imagecreatetruecolor($w, $h);
+                       if ($screen) {
+                               $img = imagecreatefrompng($imgFile);
+                               imagecopyresampled($new,$img,0,0,0,0, $w,$h,$width,$height);
+                               imagedestroy($img);
+                       }
+                       else {
+                               $c = imagecolorallocate($new, 255, 255, 255);
+                               imagefill($new, 0, 0, $c);
+                       }
+
+                       imagepng($new, $imgFile);
+                       imagedestroy($new);
+
+                       $fp = fopen($imgFile, "rb");
+                       $data = fread($fp, filesize($imgFile));
+                       fclose($fp);
+
+                       unlink($imgFile);
+                       return $data;
+               }
+
+                function domain_get_screen_dimensions($domain) {
+                       $screen = $this->domain_get_screenshot($domain);
+                       $imgFile = tempnam("/tmp", "libvirt-php-tmp-resize-XXXXXX");;
+
+                       $width = false;
+                       $height = false;
+
+                       if ($screen) {
+                                $fp = fopen($imgFile, "wb");
+                               fwrite($fp, $screen);
+                               fclose($fp);
+                       }
+                       if (file_exists($imgFile) && $screen)
+                               list($width, $height) = getimagesize($imgFile);
+
+                       unlink($imgFile);
+
+                       return array('height' => $height, 'width' => $width);
+               }
+
+               function domain_send_keys($domain, $keys) {
+                       $dom = $this->get_domain_object($domain);
+
+                       $tmp = libvirt_domain_send_keys($dom, $this->get_hostname(), $keys);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_send_pointer_event($domain, $x, $y, $clicked = 1) {
+                       $dom = $this->get_domain_object($domain);
+
+                       $tmp = libvirt_domain_send_pointer_event($dom, $this->get_hostname(), $x, $y, $clicked, true);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_disk_remove($domain, $dev) {
+                       $dom = $this->get_domain_object($domain);
+
+                       $tmp = libvirt_domain_disk_remove($dom, $dev);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function supports($name) {
+                       return libvirt_has_feature($name);
+               }
+
+               function macbyte($val) {
+                       if ($val < 16)
+                               return '0'.dechex($val);
+
+                       return dechex($val);
+               }
+
+               function generate_random_mac_addr($seed=false) {
+                       if (!$seed)
+                               $seed = 1;
+
+                       if ($this->get_hypervisor_name() == 'qemu')
+                               $prefix = '52:54:00';
+                       else
+                       if ($this->get_hypervisor_name() == 'xen')
+                               $prefix = '00:16:3e';
+                       else
+                               $prefix = $this->macbyte(($seed * rand()) % 256).':'.
+                                $this->macbyte(($seed * rand()) % 256).':'.
+                                $this->macbyte(($seed * rand()) % 256);
+
+                       return $prefix.':'.
+                               $this->macbyte(($seed * rand()) % 256).':'.
+                               $this->macbyte(($seed * rand()) % 256).':'.
+                               $this->macbyte(($seed * rand()) % 256);
+               }
+
+               function domain_nic_add($domain, $mac, $network, $model=false) {
+                       $dom = $this->get_domain_object($domain);
+
+                       if ($model == 'default')
+                               $model = false;
+
+                       $tmp = libvirt_domain_nic_add($dom, $mac, $network, $model);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_nic_remove($domain, $mac) {
+                       $dom = $this->get_domain_object($domain);
+
+                       $tmp = libvirt_domain_nic_remove($dom, $mac);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function get_connection() {
+                       return $this->conn;
+               }
+
+               function get_hostname() {
+                       return libvirt_connect_get_hostname($this->conn);
+               }
+
+               function get_domain_object($nameRes) {
+                       if (is_resource($nameRes))
+                               return $nameRes;
+
+                       $dom=libvirt_domain_lookup_by_name($this->conn, $nameRes);
+                       if (!$dom) {
+                               $dom=libvirt_domain_lookup_by_uuid_string($this->conn, $nameRes);
+                               if (!$dom)
+                                       return $this->_set_last_error();
+                       }
+
+                       return $dom;
+               }
+
+               function get_xpath($domain, $xpath, $inactive = false) {
+                       $dom = $this->get_domain_object($domain);
+                       $flags = 0;
+                       if ($inactive)
+                               $flags = VIR_DOMAIN_XML_INACTIVE;
+
+                       $tmp = libvirt_domain_xml_xpath($dom, $xpath, $flags); 
+                       if (!$tmp)
+                               return $this->_set_last_error();
+
+                       return $tmp;
+               }
+
+               function get_cdrom_stats($domain, $sort=true) {
+                       $dom = $this->get_domain_object($domain);
+
+                       $buses =  $this->get_xpath($dom, '//domain/devices/disk[@device="cdrom"]/target/@bus', false);
+                       $disks =  $this->get_xpath($dom, '//domain/devices/disk[@device="cdrom"]/target/@dev', false);
+
+                       $ret = array();
+                       for ($i = 0; $i < $disks['num']; $i++) {
+                               $tmp = libvirt_domain_get_block_info($dom, $disks[$i]);
+                               if ($tmp) {
+                                       $tmp['bus'] = $buses[$i];
+                                       $ret[] = $tmp;
+                               }
+                               else
+                                       $this->_set_last_error();
+                       }
+
+                       if ($sort) {
+                               for ($i = 0; $i < sizeof($ret); $i++) {
+                                       for ($ii = 0; $ii < sizeof($ret); $ii++) {
+                                               if (strcmp($ret[$i]['device'], $ret[$ii]['device']) < 0) {
+                                                       $tmp = $ret[$i];
+                                                       $ret[$i] = $ret[$ii];
+                                                       $ret[$ii] = $tmp;
+                                               }
+                                       }
+                               }
+                       }
+
+                       unset($buses);
+                       unset($disks);
+
+                       return $ret;
+               }
+
+               function get_disk_stats($domain, $sort=true) {
+                       $dom = $this->get_domain_object($domain);
+
+                       $buses =  $this->get_xpath($dom, '//domain/devices/disk[@device="disk"]/target/@bus', false);
+                       $disks =  $this->get_xpath($dom, '//domain/devices/disk[@device="disk"]/target/@dev', false);
+                       // create image as: qemu-img create -f qcow2 -o backing_file=RAW_IMG OUT_QCOW_IMG SIZE[K,M,G suffixed]
+
+                       $ret = array();
+                       for ($i = 0; $i < $disks['num']; $i++) {
+                               $tmp = libvirt_domain_get_block_info($dom, $disks[$i]);
+                               if ($tmp) {
+                                       $tmp['bus'] = $buses[$i];
+                                       $ret[] = $tmp;
+                               }
+                               else
+                                       $this->_set_last_error();
+                       }
+
+                       if ($sort) {
+                               for ($i = 0; $i < sizeof($ret); $i++) {
+                                       for ($ii = 0; $ii < sizeof($ret); $ii++) {
+                                               if (strcmp($ret[$i]['device'], $ret[$ii]['device']) < 0) {
+                                                       $tmp = $ret[$i];
+                                                       $ret[$i] = $ret[$ii];
+                                                       $ret[$ii] = $tmp;
+                                               }
+                                       }
+                               }
+                       }
+
+                       unset($buses);
+                       unset($disks);
+
+                       return $ret;
+               }
+
+                function get_nic_info($domain) {
+                        $dom = $this->get_domain_object($domain);
+
+                        $macs =  $this->get_xpath($dom, '//domain/devices/interface[@type="network"]/mac/@address', false);
+                       if (!$macs)
+                               return $this->_set_last_error();
+
+                       $ret = array();
+                       for ($i = 0; $i < $macs['num']; $i++) {
+                               $tmp = libvirt_domain_get_network_info($dom, $macs[$i]);
+                               if ($tmp)
+                                       $ret[] = $tmp;
+                               else
+                                       $this->_set_last_error();
+                       }
+
+                        return $ret;
+                }
+
+                function get_domain_type($domain) {
+                        $dom = $this->get_domain_object($domain);
+
+                        $tmp = $this->get_xpath($dom, '//domain/@type', false);
+                        if ($tmp['num'] == 0)
+                            return $this->_set_last_error();
+
+                        $ret = $tmp[0];
+                        unset($tmp);
+
+                        return $ret;
+                }
+
+                function get_domain_emulator($domain) {
+                        $dom = $this->get_domain_object($domain);
+
+                        $tmp =  $this->get_xpath($dom, '//domain/devices/emulator', false);
+                        if ($tmp['num'] == 0)
+                            return $this->_set_last_error();
+
+                        $ret = $tmp[0];
+                        unset($tmp);
+
+                        return $ret;
+                }
+
+               function get_network_cards($domain) {
+                       $dom = $this->get_domain_object($domain);
+
+                       $nics =  $this->get_xpath($dom, '//domain/devices/interface[@type="network"]', false);
+                       if (!is_array($nics))
+                               return $this->_set_last_error();
+
+                       return $nics['num'];
+               }
+
+               function get_disk_capacity($domain, $physical=false, $disk='*', $unit='?') {
+                       $dom = $this->get_domain_object($domain);
+                       $tmp = $this->get_disk_stats($dom);
+
+                       $ret = 0;
+                       for ($i = 0; $i < sizeof($tmp); $i++) {
+                               if (($disk == '*') || ($tmp[$i]['device'] == $disk))
+                                       if ($physical)
+                                               $ret += $tmp[$i]['physical'];
+                                       else
+                                               $ret += $tmp[$i]['capacity'];
+                       }
+                       unset($tmp);
+
+                       return $this->format_size($ret, 2, $unit);
+               }
+
+               function get_disk_count($domain) {
+                       $dom = $this->get_domain_object($domain);
+                       $tmp = $this->get_disk_stats($dom);
+                       $ret = sizeof($tmp);
+                       unset($tmp);
+
+                       return $ret;
+               }
+
+               function format_size($value, $decimals, $unit='?') {
+                       /* Autodetect unit that's appropriate */
+                       if ($unit == '?') {
+                               /* (1 << 40) is not working correctly on i386 systems */
+                               if ($value > 1099511627776)
+                                       $unit = 'T';
+                               else
+                               if ($value > (1 << 30))
+                                       $unit = 'G';
+                               else
+                               if ($value > (1 << 20))
+                                       $unit = 'M';
+                               else
+                               if ($value > (1 << 10))
+                                       $unit = 'K';
+                               else
+                                       $unit = 'B';
+                       }
+
+                       $unit = strtoupper($unit);
+
+                       switch ($unit) {
+                               case 'T': return number_format($value / (float)1099511627776, $decimals, '.', ' ').' TB';
+                               case 'G': return number_format($value / (float)(1 << 30), $decimals, '.', ' ').' GB';
+                               case 'M': return number_format($value / (float)(1 << 20), $decimals, '.', ' ').' MB';
+                               case 'K': return number_format($value / (float)(1 << 10), $decimals, '.', ' ').' kB';
+                               case 'B': return $value.' B';
+                       }
+
+                       return false;
+               }
+
+               function get_uri() {
+                       $tmp = libvirt_connect_get_uri($this->conn);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function get_domain_count() {
+                       $tmp = libvirt_domain_get_counts($this->conn);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function get_storagepools() {
+                       $tmp = libvirt_list_storagepools($this->conn);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function get_storagepool_res($res) {
+                       if ($res == false)
+                               return false;
+                       if (is_resource($res))
+                               return $res;
+
+                       $tmp = libvirt_storagepool_lookup_by_name($this->conn, $res);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function get_storagepool_info($name) {
+                       if (!($res = $this->get_storagepool_res($name)))
+                               return false;
+
+                       $path = libvirt_storagepool_get_xml_desc($res, '/pool/target/path');
+                       if (!$path)
+                               return $this->_set_last_error();
+                       $perms = libvirt_storagepool_get_xml_desc($res, '/pool/target/permissions/mode');
+                       if (!$perms)
+                               return $this->_set_last_error();
+                       $otmp1 = libvirt_storagepool_get_xml_desc($res, '/pool/target/permissions/owner');
+                       if (!is_string($otmp1))
+                               return $this->_set_last_error();
+                       $otmp2 = libvirt_storagepool_get_xml_desc($res, '/pool/target/permissions/group');
+                       if (!is_string($otmp2))
+                               return $this->_set_last_error();
+                       $tmp = libvirt_storagepool_get_info($res);
+                       $tmp['volume_count'] = sizeof( libvirt_storagepool_list_volumes($res) );
+                       $tmp['active'] = libvirt_storagepool_is_active($res);
+                       $tmp['path'] = $path;
+                       $tmp['permissions'] = $perms;
+                       $tmp['id_user'] = $otmp1;
+                       $tmp['id_group'] = $otmp2;
+
+                       return $tmp;
+               }
+
+               function storagepool_get_volume_information($pool, $name=false) {
+                       if (!is_resource($pool))
+                               $pool = $this->get_storagepool_res($pool);
+                       if (!$pool)
+                               return false;
+
+                       $out = array();
+                       $tmp = libvirt_storagepool_list_volumes($pool);
+                       for ($i = 0; $i < sizeof($tmp); $i++) {
+                               if (($tmp[$i] == $name) || ($name == false)) {
+                                       $r = libvirt_storagevolume_lookup_by_name($pool, $tmp[$i]);
+                                       $out[$tmp[$i]] = libvirt_storagevolume_get_info($r);
+                                       $out[$tmp[$i]]['path'] = libvirt_storagevolume_get_path($r);
+                                       unset($r);
+                               }
+                       }
+
+                       return $out;
+               }
+
+               function storagevolume_delete($path) {
+                       $vol = libvirt_storagevolume_lookup_by_path($this->conn, $path);
+                       if (!libvirt_storagevolume_delete($vol))
+                               return $this->_set_last_error();
+
+                       return true;
+               }
+
+               function translate_volume_type($type) {
+                       if ($type == 1)
+                               return 'Block device';
+
+                       return 'File image';
+               }
+
+               function translate_perms($mode) {
+                       $mode = (string)((int)$mode);
+
+                       $tmp = '---------';
+
+                       for ($i = 0; $i < 3; $i++) {
+                               $bits = (int)$mode[$i];
+                               if ($bits & 4)
+                                       $tmp[ ($i * 3) ] = 'r';
+                               if ($bits & 2)
+                                       $tmp[ ($i * 3) + 1 ] = 'w';
+                               if ($bits & 1)
+                                       $tmp[ ($i * 3) + 2 ] = 'x';
+                       }
+                       
+
+                       return $tmp;
+               }
+
+               function parse_size($size) {
+                       $unit = $size[ strlen($size) - 1 ];
+
+                       $size = (int)$size;
+                       switch (strtoupper($unit)) {
+                               case 'T': $size *= 1099511627776;
+                                         break;
+                               case 'G': $size *= 1073741824;
+                                         break;
+                               case 'M': $size *= 1048576;
+                                         break;
+                               case 'K': $size *= 1024;
+                                         break;
+                       }
+
+                       return $size;
+               }
+
+               function storagevolume_create($pool, $name, $capacity, $allocation) {
+                       $pool = $this->get_storagepool_res($pool);
+
+                       $capacity = $this->parse_size($capacity);
+                       $allocation = $this->parse_size($allocation);
+
+                       $xml = "<volume>\n".
+                               "  <name>$name</name>\n".
+                               "  <capacity>$capacity</capacity>\n".
+                               "  <allocation>$allocation</allocation>\n".
+                               "</volume>";
+
+                       $tmp = libvirt_storagevolume_create_xml($pool, $xml);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function get_hypervisor_name() {
+                       $tmp = libvirt_connect_get_information($this->conn);
+                       $hv = $tmp['hypervisor'];
+                       unset($tmp);
+
+                       switch (strtoupper($hv)) {
+                               case 'QEMU': $type = 'qemu';
+                                       break;
+                               case 'XEN': $type = 'xen';
+                                       break;
+
+                               default:
+                                       $type = $hv;
+                       }
+
+                       return $type;
+               }
+
+               function get_connect_information() {
+                       $tmp = libvirt_connect_get_information($this->conn);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_change_xml($domain, $xml) {
+                       $dom = $this->get_domain_object($domain);
+
+                       if (!($old_xml = libvirt_domain_get_xml_desc($dom, NULL)))
+                               return $this->_set_last_error();
+                       if (!libvirt_domain_undefine($dom))
+                               return $this->_set_last_error();
+                       if (!libvirt_domain_define_xml($this->conn, $xml)) {
+                               $this->last_error = libvirt_get_last_error();
+                               libvirt_domain_define_xml($this->conn, $old_xml);
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               function network_change_xml($network, $xml) {
+                       $net = $this->get_network_res($network);
+
+                       if (!($old_xml = libvirt_network_get_xml_desc($net, NULL))) {
+                               return $this->_set_last_error();
+                       }
+                       if (!libvirt_network_undefine($net)) {
+                               return $this->_set_last_error();
+                       }
+                       if (!libvirt_network_define_xml($this->conn, $xml)) {
+                               $this->last_error = libvirt_get_last_error();
+                               libvirt_network_define_xml($this->conn, $old_xml);
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               function translate_storagepool_state($state) {
+                       switch ($state) {
+                               case 0: return 'Not running';
+                                       break;
+                               case 1: return 'Building pool';
+                                       break;
+                               case 2: return 'Running';
+                                       break;
+                               case 3: return 'Running degraded';
+                                       break;
+                               case 4: return 'Running but inaccessible';
+                                       break;
+                       }
+
+                       return 'Unknown';
+               }
+
+               function get_domains() {
+                       $tmp = libvirt_list_domains($this->conn);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function get_domain_by_name($name) {
+                       $tmp = libvirt_domain_lookup_by_name($this->conn, $name);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function get_networks($type = VIR_NETWORKS_ALL) {
+                       $tmp = libvirt_list_networks($this->conn, $type);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function get_nic_models() {
+                       return array('default', 'rtl8139', 'e1000', 'pcnet', 'ne2k_pci', 'virtio');
+               }
+
+               function get_network_res($network) {
+                       if ($network == false)
+                               return false;
+                       if (is_resource($network))
+                               return $network;
+
+                       $tmp = libvirt_network_get($this->conn, $network);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function get_network_bridge($network) {
+                       $res = $this->get_network_res($network);
+                       if ($res == false)
+                               return false;
+
+                       $tmp = libvirt_network_get_bridge($res);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function get_network_active($network) {
+                       $res = $this->get_network_res($network);
+                       if ($res == false)
+                               return false;
+
+                       $tmp = libvirt_network_get_active($res);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function set_network_active($network, $active = true) {
+                       $res = $this->get_network_res($network);
+                       if ($res == false)
+                               return false;
+
+                       if (!libvirt_network_set_active($res, $active ? 1 : 0))
+                               return $this->_set_last_error();
+
+                       return true;
+               }
+
+               function get_network_information($network) {
+                       $res = $this->get_network_res($network);
+                       if ($res == false)
+                               return false;
+
+                       $tmp = libvirt_network_get_information($res);
+                       if (!$tmp)
+                               return $this->_set_last_error();
+                       $tmp['active'] = $this->get_network_active($res);
+                       return $tmp;
+               }
+
+               function get_network_xml($network) {
+                       $res = $this->get_network_res($network);
+                       if ($res == false)
+                               return false;
+
+                       $tmp = libvirt_network_get_xml_desc($res, NULL);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function get_node_devices($dev = false) {
+                       $tmp = ($dev == false) ? libvirt_list_nodedevs($this->conn) : libvirt_list_nodedevs($this->conn, $dev);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function get_node_device_res($res) {
+                       if ($res == false)
+                               return false;
+                       if (is_resource($res))
+                               return $res;
+
+                       $tmp = libvirt_nodedev_get($this->conn, $res);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function get_node_device_caps($dev) {
+                       $dev = $this->get_node_device_res($dev);
+
+                       $tmp = libvirt_nodedev_capabilities($dev);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function get_node_device_cap_options() {
+                       $all = $this->get_node_devices();
+
+                       $ret = array();
+                       for ($i = 0; $i < sizeof($all); $i++) {
+                               $tmp = $this->get_node_device_caps($all[$i]);
+
+                               for ($ii = 0; $ii < sizeof($tmp); $ii++)
+                                       if (!in_array($tmp[$ii], $ret))
+                                               $ret[] = $tmp[$ii];
+                       }
+
+                       return $ret;
+               }
+
+               function get_node_device_xml($dev) {
+                       $dev = $this->get_node_device_res($dev);
+
+                       $tmp = libvirt_nodedev_get_xml_desc($dev, NULL);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function get_node_device_information($dev) {
+                       $dev = $this->get_node_device_res($dev);
+
+                       $tmp = libvirt_nodedev_get_information($dev);                   
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_get_name($res) {
+                       return libvirt_domain_get_name($res);
+               }
+
+               function domain_get_info_call($name = false, $name_override = false) {
+                       $ret = array();
+
+                       if ($name != false) {
+                               $dom = $this->get_domain_object($name);
+                               if (!$dom)
+                                       return false;
+
+                               if ($name_override)
+                                       $name = $name_override;
+
+                               $ret[$name] = libvirt_domain_get_info($dom);
+                               return $ret;
+                       }
+                       else {
+                               $doms = libvirt_list_domains($this->conn);
+                               foreach ($doms as $dom) {
+                                       $tmp = $this->domain_get_name($dom);
+                                       $ret[$tmp] = libvirt_domain_get_info($dom);
+                               }
+                       }
+
+                       ksort($ret);
+                       return $ret;
+               }
+
+               function domain_get_info($name = false, $name_override = false) {
+                       if (!$this->allow_cached)
+                               return $this->domain_get_info_call($name, $name_override);
+
+                       $domname = $name_override ? $name_override : $name;
+                       $domkey  = $name_override ? $name_override : $this->domain_get_name($name);
+                       if (!array_key_exists($domkey, $this->dominfos)) {
+                               $tmp = $this->domain_get_info_call($name, $name_override);
+                               $this->dominfos[$domkey] = $tmp[$domname];
+                       }
+
+                       return $this->dominfos[$domkey];
+               }
+
+               function get_last_error() {
+                       return $this->last_error;
+               }
+
+               function domain_get_xml($domain, $get_inactive = false) {
+                       $dom = $this->get_domain_object($domain);
+                       if (!$dom)
+                               return false;
+
+                       $tmp = libvirt_domain_get_xml_desc($dom, $get_inactive ? VIR_DOMAIN_XML_INACTIVE : 0);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function network_get_xml($network) {
+                       $net = $this->get_network_res($network);
+                       if (!$net)
+                               return false;
+
+                       $tmp = libvirt_network_get_xml_desc($net, NULL);
+                       return ($tmp) ? $tmp : $this->_set_last_error();;
+               }
+
+               function domain_get_id($domain, $name = false) {
+                       $dom = $this->get_domain_object($domain);
+                       if ((!$dom) || (!$this->domain_is_running($dom, $name)))
+                               return false;
+
+                       $tmp = libvirt_domain_get_id($dom);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_get_interface_stats($nameRes, $iface) {
+                       $dom = $this->get_domain_object($domain);
+                       if (!$dom)
+                               return false;
+
+                       $tmp = libvirt_domain_interface_stats($dom, $iface);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_get_memory_stats($domain) {
+                       $dom = $this->get_domain_object($domain);
+                       if (!$dom)
+                               return false;
+
+                       $tmp = libvirt_domain_memory_stats($dom);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_start($dom) {
+                       $dom=$this->get_domain_object($dom);
+                       if ($dom) {
+                               $ret = libvirt_domain_create($dom);
+                               $this->last_error = libvirt_get_last_error();
+                               return $ret;
+                       }
+
+                       $ret = libvirt_domain_create_xml($this->conn, $dom);
+                       $this->last_error = libvirt_get_last_error();
+                       return $ret;
+               }
+
+               function domain_define($xml) {
+                       $tmp = libvirt_domain_define_xml($this->conn, $xml);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_destroy($domain) {
+                       $dom = $this->get_domain_object($domain);
+                       if (!$dom)
+                               return false;
+
+                       $tmp = libvirt_domain_destroy($dom);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_reboot($domain) {
+                       $dom = $this->get_domain_object($domain);
+                       if (!$dom)
+                               return false;
+
+                       $tmp = libvirt_domain_reboot($dom);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_suspend($domain) {
+                       $dom = $this->get_domain_object($domain);
+                       if (!$dom)
+                               return false;
+
+                       $tmp = libvirt_domain_suspend($dom);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_resume($domain) {
+                       $dom = $this->get_domain_object($domain);
+                       if (!$dom)
+                               return false;
+
+                       $tmp = libvirt_domain_resume($dom);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_get_name_by_uuid($uuid) {
+                       $dom = libvirt_domain_lookup_by_uuid_string($this->conn, $uuid);
+                       if (!$dom)
+                               return false;
+                       $tmp = libvirt_domain_get_name($dom);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_shutdown($domain) {
+                       $dom = $this->get_domain_object($domain);
+                       if (!$dom)
+                               return false;
+
+                       $tmp = libvirt_domain_shutdown($dom);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_undefine($domain) {
+                       $dom = $this->get_domain_object($domain);
+                       if (!$dom)
+                               return false;
+
+                       $tmp = libvirt_domain_undefine($dom);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_is_running($domain, $name = false) {
+                       $dom = $this->get_domain_object($domain);
+                       if (!$dom)
+                               return false;
+
+                       $tmp = $this->domain_get_info( $domain, $name );
+                       if (!$tmp)
+                               return $this->_set_last_error();
+                       $ret = ( ($tmp['state'] == VIR_DOMAIN_RUNNING) || ($tmp['state'] == VIR_DOMAIN_BLOCKED) );
+                       unset($tmp);
+                       return $ret;
+               }
+
+               function domain_state_translate($state) {
+                       switch ($state) {
+                               case VIR_DOMAIN_RUNNING:  return 'running';
+                               case VIR_DOMAIN_NOSTATE:  return 'nostate';
+                               case VIR_DOMAIN_BLOCKED:  return 'blocked';
+                               case VIR_DOMAIN_PAUSED:   return 'paused';
+                               case VIR_DOMAIN_SHUTDOWN: return 'shutdown';
+                               case VIR_DOMAIN_SHUTOFF:  return 'shutoff';
+                               case VIR_DOMAIN_CRASHED:  return 'crashed';
+                       }
+
+                       return 'unknown';
+               }
+
+               function domain_get_vnc_port($domain) {
+                       $tmp = $this->get_xpath($domain, '//domain/devices/graphics/@port', false);
+                       $var = (int)$tmp[0];
+                       unset($tmp);
+
+                       return $var;
+               }
+
+               function domain_get_arch($domain) {
+                       $domain = $this->get_domain_object($domain);
+
+                       $tmp = $this->get_xpath($domain, '//domain/os/type/@arch', false);
+                       $var = $tmp[0];
+                       unset($tmp);
+
+                       return $var;
+               }
+
+               function domain_get_description($domain) {
+                       $tmp = $this->get_xpath($domain, '//domain/description', false);
+                       $var = $tmp[0];
+                       unset($tmp);
+
+                       return $var;
+               }
+
+               function domain_get_clock_offset($domain) {
+                       $tmp = $this->get_xpath($domain, '//domain/clock/@offset', false);
+                       $var = $tmp[0];
+                       unset($tmp);
+
+                       return $var;
+               }
+
+               function domain_get_feature($domain, $feature) {
+                       $tmp = $this->get_xpath($domain, '//domain/features/'.$feature.'/..', false);
+                       $ret = ($tmp != false);
+                       unset($tmp);
+
+                       return $ret;
+               }
+
+               function domain_get_boot_devices($domain) {
+                       $tmp = $this->get_xpath($domain, '//domain/os/boot/@dev', false);
+                       if (!$tmp)
+                               return false;
+
+                       $devs = array();
+                       for ($i = 0; $i < $tmp['num']; $i++)
+                               $devs[] = $tmp[$i];
+
+                       return $devs;
+               }
+
+               function _get_single_xpath_result($domain, $xpath) {
+                       $tmp = $this->get_xpath($domain, $xpath, false);
+                       if (!$tmp)
+                               return false;
+
+                       if ($tmp['num'] == 0)
+                               return false;
+
+                       return $tmp[0];
+               }
+
+               function domain_get_multimedia_device($domain, $type, $display=false) {
+                       $domain = $this->get_domain_object($domain);
+
+                       if ($type == 'console') {
+                               $type = $this->_get_single_xpath_result($domain, '//domain/devices/console/@type');
+                               $targetType = $this->_get_single_xpath_result($domain, '//domain/devices/console/target/@type');
+                               $targetPort = $this->_get_single_xpath_result($domain, '//domain/devices/console/target/@port');
+
+                               if ($display)
+                                       return $type.' ('.$targetType.' on port '.$targetPort.')';
+                               else
+                                       return array('type' => $type, 'targetType' => $targetType, 'targetPort' => $targetPort);
+                       }
+                       else
+                       if ($type == 'input') {
+                               $type = $this->_get_single_xpath_result($domain, '//domain/devices/input/@type');
+                               $bus  = $this->_get_single_xpath_result($domain, '//domain/devices/input/@bus');
+
+                               if ($display)
+                                       return $type.' on '.$bus;
+                               else
+                                       return array('type' => $type, 'bus' => $bus);
+                       }
+                       else
+                       if ($type == 'graphics') {
+                               $type = $this->_get_single_xpath_result($domain, '//domain/devices/graphics/@type');
+                               $port = $this->_get_single_xpath_result($domain, '//domain/devices/graphics/@port');
+                               $autoport = $this->_get_single_xpath_result($domain, '//domain/devices/graphics/@autoport');
+
+                               if ($display)
+                                       return $type.' on port '.$port.' with'.($autoport ? '' : 'out').' autoport enabled';
+                               else
+                                       return array('type' => $type, 'port' => $port, 'autoport' => $autoport);
+                       }
+                       else
+                       if ($type == 'video') {
+                               $type  = $this->_get_single_xpath_result($domain, '//domain/devices/video/model/@type');
+                               $vram  = $this->_get_single_xpath_result($domain, '//domain/devices/video/model/@vram');
+                               $heads = $this->_get_single_xpath_result($domain, '//domain/devices/video/model/@heads');
+
+                               if ($display)
+                                       return $type.' with '.($vram / 1024).' MB VRAM, '.$heads.' head(s)';
+                               else
+                                       return array('type' => $type, 'vram' => $vram, 'heads' => $heads);
+                       }
+                       else
+                               return false;
+               }
+
+               function domain_get_host_devices_pci($domain) {
+                       $xpath = '//domain/devices/hostdev[@type="pci"]/source/address/@';
+
+                       $dom  = $this->get_xpath($domain, $xpath.'domain', false);
+                       $bus  = $this->get_xpath($domain, $xpath.'bus', false);
+                       $slot = $this->get_xpath($domain, $xpath.'slot', false);
+                       $func = $this->get_xpath($domain, $xpath.'function', false);
+
+                       $devs = array();
+                       for ($i = 0; $i < $bus['num']; $i++) {
+                               $d = str_replace('0x', '', $dom[$i]);
+                               $b = str_replace('0x', '', $bus[$i]);
+                               $s = str_replace('0x', '', $slot[$i]);
+                               $f = str_replace('0x', '', $func[$i]);
+                               $devid = 'pci_'.$d.'_'.$b.'_'.$s.'_'.$f;
+                               $tmp2 = $this->get_node_device_information($devid);
+                               $devs[] = array('domain' => $dom[$i], 'bus' => $bus[$i],
+                                               'slot' => $slot[$i], 'func' => $func[$i],
+                                               'vendor' => $tmp2['vendor_name'],
+                                               'vendor_id' => $tmp2['vendor_id'],
+                                               'product' => $tmp2['product_name'],
+                                               'product_id' => $tmp2['product_id']);
+                       }
+
+                       return $devs;
+               }
+
+               function _lookup_device_usb($vendor_id, $product_id) {
+                       $tmp = $this->get_node_devices(false);
+                       for ($i = 0; $i < sizeof($tmp); $i++) {
+                               $tmp2 = $this->get_node_device_information($tmp[$i]);
+                               if (array_key_exists('product_id', $tmp2)) {
+                                       if (($tmp2['product_id'] == $product_id)
+                                               && ($tmp2['vendor_id'] == $vendor_id))
+                                                       return $tmp2;
+                               }
+                       }
+
+                       return false;
+               }
+
+               function domain_get_host_devices_usb($domain) {
+                       $xpath = '//domain/devices/hostdev[@type="usb"]/source/';
+
+                       $vid = $this->get_xpath($domain, $xpath.'vendor/@id', false);
+                       $pid = $this->get_xpath($domain, $xpath.'product/@id', false);
+
+                       $devs = array();
+                       for ($i = 0; $i < $vid['num']; $i++) {
+                               $dev = $this->_lookup_device_usb($vid[$i], $pid[$i]);
+                               $devs[] = array('vendor_id' => $vid[$i], 'product_id' => $pid[$i],
+                                               'product' => $dev['product_name'],
+                                               'vendor' => $dev['vendor_name']);
+                       }
+
+                       return $devs;
+               }
+
+               function domain_get_host_devices($domain) {
+                       $domain = $this->get_domain_object($domain);
+
+                       $devs_pci = $this->domain_get_host_devices_pci($domain);
+                       $devs_usb = $this->domain_get_host_devices_usb($domain);
+
+                       return array('pci' => $devs_pci, 'usb' => $devs_usb);
+               }
+
+               function domain_set_feature($domain, $feature, $val) {
+                       $domain = $this->get_domain_object($domain);
+
+                       if ($this->domain_get_feature($domain, $feature) == $val)
+                               return true;
+
+                       $xml = $this->domain_get_xml($domain, true);
+                       if ($val) {
+                               if (strpos('features', $xml))
+                                       $xml = str_replace('<features>', "<features>\n<$feature/>", $xml);
+                               else
+                                       $xml = str_replace('</os>', "</os><features>\n<$feature/></features>", $xml);
+                       }
+                       else
+                               $xml = str_replace("<$feature/>\n", '', $xml);
+
+                       return $this->domain_change_xml($domain, $xml);
+               }
+
+               function domain_set_clock_offset($domain, $offset) {
+                       $domain = $this->get_domain_object($domain);
+
+                       if (($old_offset = $this->domain_get_clock_offset($domain)) == $offset)
+                               return true;
+
+                       $xml = $this->domain_get_xml($domain, true);
+                       $xml = str_replace("<clock offset='$old_offset'/>", "<clock offset='$offset'/>", $xml);
+
+                       return $this->domain_change_xml($domain, $xml);
+               }
+
+               function domain_set_description($domain, $desc) {
+                       $domain = $this->get_domain_object($domain);
+
+                       $description = $this->domain_get_description($domain);
+                       if ($description == $desc)
+                               return true;
+
+                       $xml = $this->domain_get_xml($domain, true);
+                       if (!$description)
+                               $xml = str_replace("</uuid>", "</uuid><description>$desc</description>", $xml);
+                       else {
+                               $tmp = explode("\n", $xml);
+                               for ($i = 0; $i < sizeof($tmp); $i++)
+                                       if (strpos('.'.$tmp[$i], '<description'))
+                                               $tmp[$i] = "<description>$desc</description>";
+
+                               $xml = join("\n", $tmp);
+                       }
+
+                       return $this->domain_change_xml($domain, $xml);
+               }
+
+               function host_get_node_info() {
+                       $tmp = libvirt_node_get_info($this->conn);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+       }
+?>
diff --git a/main-menu.php b/main-menu.php
new file mode 100644 (file)
index 0000000..c0bb2ff
--- /dev/null
@@ -0,0 +1,6 @@
+  <!-- MENU -->
+  <div id="main-menu">
+    <a href="?">Main menu</a>
+    | <a href="?page=domain-list">Domain list</a>
+    | <a href="?page=info">Information</a>
+  </div>
diff --git a/manager.css b/manager.css
new file mode 100644 (file)
index 0000000..5534dee
--- /dev/null
@@ -0,0 +1,106 @@
+#vm-name {
+       padding-left: 10px;
+}
+
+#msg {
+       margin-top: 20px;
+       padding: 5px 5px 5px 20px;
+       font-size: 18px;
+       background-color: lightgreen;
+       color: gray;
+       font-style: italic;
+}
+
+#menu {
+       background-color: lightblue;
+       padding: 10px;
+}
+
+#menu a {
+       font-size: 20px;
+       padding: 10px;
+       color: blue;
+       text-decoration: none;
+       font-weight: bold;
+}
+
+#main-menu {
+        background-color: lightgreen;
+        padding: 10px;
+       margin-bottom: 10px;
+}
+
+#main-menu a {
+        font-size: 20px;
+        padding: 10px;
+        color: blue;
+        text-decoration: none;
+        font-weight: bold;
+}
+
+#content {
+       font-size: 16px;
+}
+
+#content #domain-list {
+       padding-left: 30px;
+}
+
+#content #domain-list th {
+       padding-left: 30px;
+}
+
+#content #domain-list td {
+       padding-left: 30px;
+       text-align: center;
+}
+
+#content #domain-list .name {
+       text-align: left;
+}
+
+#content #domain-list td a {
+       text-decoration: none;
+       color: blue;
+       font-weight: bold;
+}
+
+#content #form-table input {
+       width: 200px;
+}
+
+#content #form-table select {
+       width: 200px;
+}
+
+#content .section {
+       padding: 10px;
+       padding-left: 20px;
+       margin-top: 20px;
+       margin-bottom: 20px;
+       font-size: 20px;
+       font-weight: bold;
+       font-style: italic;
+       background-color: lightgray;
+}
+
+#content .screenshot {
+       padding: 25px;
+       text-align: center;
+}
+
+#content .item .label {
+       width: 150px;
+       padding-right: 10px;
+       text-align: right;
+       float: left;
+       font-weight: bold;
+}
+
+#content .item .value {
+       float: left;
+}
+
+#content .item .nl {
+       clear: both;
+}
diff --git a/menu.php b/menu.php
new file mode 100644 (file)
index 0000000..7e500d6
--- /dev/null
+++ b/menu.php
@@ -0,0 +1,18 @@
+  <!-- MENU -->
+  <div id="menu">
+  <a href="?name=<?= $name ?>">Overview</a>
+  <!--
+  | <a href="?name=<?= $name ?>&amp;page=performance">Performance</a>
+  -->
+  | <a href="?name=<?= $name ?>&amp;page=processor">Processor</a>
+  | <a href="?name=<?= $name ?>&amp;page=memory">Memory</a>
+  | <a href="?name=<?= $name ?>&amp;page=boot-options">Boot options</a>
+  | <a href="?name=<?= $name ?>&amp;page=disk-devices">Disk devices</a>
+  | <a href="?name=<?= $name ?>&amp;page=network-devices">Network devices</a>
+  | <a href="?name=<?= $name ?>&amp;page=multimedia-devices">Multimedia devices</a>
+  | <a href="?name=<?= $name ?>&amp;page=host-devices">Host devices</a>
+<?php
+  if (($lv->domain_is_running($res, $name) && ($lv->supports('screenshot'))))
+    echo '| <a href="?name='.$name.'&amp;page=screenshot">Screenshot</a>';
+?>
+  </div>
diff --git a/pages/details/boot-options.php b/pages/details/boot-options.php
new file mode 100644 (file)
index 0000000..480d8ca
--- /dev/null
@@ -0,0 +1,89 @@
+<?
+  if ((array_key_exists('ch-discard', $_POST)) && ($_POST['ch-discard'])) 
+    Die(Header('Location: '.$_SERVER['REQUEST_URI']));
+
+  $bd1 = array_key_exists('bd_1st', $_POST) ? $_POST['bd_1st'] : false;
+  $bd2 = array_key_exists('bd_2nd', $_POST) ? $_POST['bd_2nd'] : false;
+
+  $msg = '';
+  if ($bd1) {
+    $msg = $lv->domain_change_boot_devices($name, $bd1, $bd2) ? 'Boot options for next run have been altered successfully'
+           : 'Cannot change guest boot options: '.$lv->get_last_error();
+  }
+
+  $devs = $lv->domain_get_boot_devices($res);
+  $bd_1st = $devs[0];
+  $bd_2nd = (sizeof($devs) > 1) ? $devs[1] : '-';
+  unset($devs);
+?>
+  <!-- CONTENTS -->
+  <div id="content">
+
+    <script language="javascript">
+    <!--
+        var change_el;
+
+        function setElement(t, x) {
+            if (t == 'change')
+                change_el = x.name;
+        }
+        function check() {
+            if (change_el == 'ch-apply')
+                return (confirm('Do you really want to apply your changes?'));
+            if (change_el == 'ch-discard')
+                return (confirm('Do you really want to discard your changes?'));
+        }
+    -->
+    </script>
+
+<?php
+    if ($msg):
+?>
+    <div id="msg"><b>Message: </b><?= $msg ?></div>
+<?php
+    endif;
+?>
+
+    <form action="#" method="POST" onsubmit="return check();">
+
+    <!-- HOST SECTION -->
+    <div class="section">Virtual machine boot options</div>
+    <div class="item">
+      <div class="label">First boot device:</div>
+      <div class="value">
+        <select name="bd_1st">
+          <option value="hd" <?= (($bd_1st == 'hd') ? 'selected="selected"' : '') ?>>Hard-drive</option>
+          <option value="cdrom" <?= (($bd_1st == 'cdrom') ? 'selected="selected"' : '') ?>>CD-ROM</option>
+          <option value="fd" <?= (($bd_1st == 'fd') ? 'selected="selected"' : '') ?>>Floppy</option>
+          <option value="network" <?= (($bd_1st == 'network') ? 'selected="selected"' : '') ?>>Network boot (PXE)</option>
+        </select>
+      </div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Second boot device:</div>
+      <div class="value">
+        <select name="bd_2nd">
+          <option value="-" <?= (($bd_2nd == '-') ? 'selected="selected"' : '') ?>>None</option>
+          <option value="hd" <?= (($bd_2nd == 'hd') ? 'selected="selected"' : '') ?>>Hard-drive</option>
+          <option value="cdrom" <?= (($bd_2nd == 'cdrom') ? 'selected="selected"' : '') ?>>CD-ROM</option>
+          <option value="fd" <?= (($bd_2nd == 'fd') ? 'selected="selected"' : '') ?>>Floppy</option>
+          <option value="network" <?= (($bd_2nd == 'network') ? 'selected="selected"' : '') ?>>Network boot (PXE)</option>
+        </select>
+      </div>
+      <div class="nl" />
+    </div>
+    <!-- ACTIONS SECTION -->
+    <div class="section">Actions</div>
+    <div class="item">
+      <div class="label">Changes:</div>
+      <div class="value">
+        <input type="submit" name="ch-apply" value=" Apply changes " onclick="setElement('change', this)" />
+        <input type="submit" name="ch-discard" value=" Discard changes " onclick="setElement('change', this)" />
+      </div>
+      <div class="nl" />
+    </div>
+
+    </form>
+
+  </div>
diff --git a/pages/details/disk-devices.php b/pages/details/disk-devices.php
new file mode 100644 (file)
index 0000000..39957a6
--- /dev/null
@@ -0,0 +1,213 @@
+<?php
+  $disk = array_key_exists('disk', $_GET) ? $_GET['disk'] : false;
+  $action = array_key_exists('action', $_GET) ? $_GET['action'] : false;
+
+  $msg = '';
+  $frm = '';
+  if (($action == 'del-disk') && ($disk)) {
+    $msg = $lv->domain_disk_remove($name, $disk) ? 'Disk has been removed successfully' : 'Cannot remove disk: '.$lv->get_last_error();
+  }
+  if ($action == 'add-disk') {
+    $img = array_key_exists('img', $_POST) ? $_POST['img'] : false;
+
+    if ($img)
+        $msg = $lv->domain_disk_add($name, $_POST['img'], $_POST['dev'], $_POST['bus'], $_POST['driver']) ?
+                                    'Disk has been successfully added to the guest' :
+                                    'Cannot add disk to the guest: '.$lv->get_last_error();
+    else
+        $frm = '<div class="section">Add a new disk device</div>
+                <form method="POST">
+                <table id="form-table">
+                  <tr>
+                    <td align="right"><b>Disk image: </b></td>
+                    <td><input type="text" name="img" /></td>
+                  </tr>
+                 <tr>
+                   <td align="right"><b>Location: </b></td>
+                   <td>
+                      <select name="bus">
+                        <option value="ide">IDE Bus</option>
+                        <option value="scsi">SCSI Bus</option>
+                      </select>
+                    </td>
+                 </tr>
+                  <tr>
+                    <td align="right"><b>Driver: </b></td>
+                    <td>
+                      <select name="driver">
+                        <option value="raw">raw</option>
+                       <option value="qcow">qcow</option>
+                       <option value="qcow2">qcow2</option>
+                      </select>
+                    </td>
+                  </tr>
+                  <tr>
+                    <td align="right"><b>Disk device in the guest: </b></td>
+                    <td><input type="text" name="dev" value="hdb" /></td>
+                  </tr>
+                  <tr align="center">
+                    <td colspan="2"><input type="submit" value=" Add new disk " /></td>
+                  </tr>
+                </table>
+                </form>';
+  }
+
+  $tmp = $lv->get_disk_stats($name);
+  $tmp2 = $lv->get_cdrom_stats($name, true);
+  $numDisks = sizeof($tmp);
+
+  $addmsg = (sizeof($tmp2) > 0) ? ' (disk) + '.(sizeof($tmp2)).' (cdrom)' : '';
+?>
+  <!-- CONTENTS -->
+  <div id="content">
+
+    <script language="javascript">
+    <!--
+        function confirmAddition() {
+            if (confirm('Do you really want to add a new disk ?')) {
+                location.href = '?name=<?= $name.'&page='.$page ?>&action=add-disk';
+            }
+        }
+        function askDiskDeletion(disk) {
+            if (confirm('Are you sure you want to delete disk '+disk+' from the guest?'))
+                location.href = '?name=<?= $name.'&page='.$page.'&action=del-disk&disk=' ?>'+disk;
+        }
+    -->
+    </script>
+
+<?php
+    if ($msg):
+?>
+    <div id="msg"><b>Message: </b><?= $msg ?></div>
+<?php
+    endif;
+?>
+<?php
+    if ($frm):
+?>
+    <div><?= $frm ?></div>
+<?php
+    endif;
+?>
+
+    <form action="#" method="POST">
+
+    <div class="section">Machine disk devices</div>
+    <div class="item">
+      <div class="label">Number of disks:</div>
+      <div class="value"><?= $numDisks.$addmsg ?></div>
+      <div class="nl" />
+    </div>
+
+<?php
+    for ($i = 0; $i < sizeof($tmp); $i++):
+      $disk = $tmp[$i];
+      $bus = ($disk['bus'] == 'ide') ? 'IDE' : 'SCSI';
+?>
+    <!-- DISK SECTION -->
+    <div class="section"><?= $bus ?> Disk <?= $i + 1 ?></div>
+    <div class="item">
+      <div class="label">Storage:</div>
+      <div class="value"><?= $disk['file'] ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Driver type:</div>
+      <div class="value"><?= $disk['type'] ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Domain device:</div>
+      <div class="value"><?= $disk['device'] ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Capacity:</div>
+      <div class="value"><?= $lv->format_size($disk['capacity'], 2) ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Allocation:</div>
+      <div class="value"><?= $lv->format_size($disk['allocation'], 2) ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Physical disk size:</div>
+      <div class="value"><?= $lv->format_size($disk['physical'], 2) ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Action:</div>
+      <div class="value">
+        <input type="button" onclick="askDiskDeletion('<?= $disk['device'] ?>')" value=" Remove disk " />
+      </div>
+      <div class="nl" />
+    </div>
+<?
+    endfor;
+?>
+
+<?php
+    for ($i = 0; $i < sizeof($tmp2); $i++):
+      $disk = $tmp2[$i];
+      $bus = ($disk['bus'] == 'ide') ? 'IDE' : 'SCSI';
+?>
+    <!-- DISK SECTION -->
+    <div class="section"><?= $bus ?> CD-ROM <?= $i + 1 ?></div>
+    <div class="item">
+      <div class="label">Storage:</div>
+      <div class="value"><?= $disk['file'] ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Driver type:</div>
+      <div class="value"><?= $disk['type'] ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Domain device:</div>
+      <div class="value"><?= $disk['device'] ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Capacity:</div>
+      <div class="value"><?= $lv->format_size($disk['capacity'], 2) ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Allocation:</div>
+      <div class="value"><?= $lv->format_size($disk['allocation'], 2) ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Physical disk size:</div>
+      <div class="value"><?= $lv->format_size($disk['physical'], 2) ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Action:</div>
+      <div class="value">
+        <input type="button" onclick="askDiskDeletion('<?= $disk['device'] ?>')" value=" Remove disk " />
+      </div>
+      <div class="nl" />
+    </div>
+
+<?php
+    endfor;
+    unset($tmp);
+    unset($tmp2);
+?>
+
+    <!-- ACTIONS SECTION -->
+    <div class="section">Actions</div>
+    <div class="item">
+      <div class="label">Changes:</div>
+      <div class="value">
+        <input type="button" name="add-disk" value=" Add new disk " onclick="confirmAddition()" />
+      </div>
+      <div class="nl" />
+    </div>
+
+    </form>
+
+  </div>
diff --git a/pages/details/host-devices.php b/pages/details/host-devices.php
new file mode 100644 (file)
index 0000000..5c40e5e
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+  $devs = $lv->domain_get_host_devices($name);
+?>
+  <!-- CONTENTS -->
+  <div id="content">
+
+    <form action="#" method="POST">
+
+    <div class="section">Machine host devices</div>
+
+<?php
+    for ($i = 0; $i < sizeof($devs['pci']); $i++):
+?>
+    <div class="item">
+      <div class="label">PCI Device #<?= $i+1 ?>:</div>
+      <div class="value"><?= $devs['pci'][$i]['product'].' from '.$devs['pci'][$i]['vendor'] ?></div>
+      <div class="nl" />
+    </div>
+<?php
+    endfor;
+?>
+
+<?php
+    for ($i = 0; $i < sizeof($devs['usb']); $i++):
+?>
+    <div class="item">
+      <div class="label">USB Device #<?= $i+1 ?>:</div>
+      <div class="value"><?= $devs['usb'][$i]['product'].' from '.$devs['usb'][$i]['vendor'] ?></div>
+      <div class="nl" />
+    </div>
+<?php
+    endfor;
+?>
+
+<?php
+    if (sizeof($devs['usb']) + sizeof($devs['pci']) == 0):
+?>
+    <div class="item">
+      <div class="label">Host devices:</div>
+      <div class="value">None</div>
+      <div class="nl" />
+    </div>
+<?
+    endif;
+?>
+
+    <!-- ACTIONS SECTION -->
+    <div class="section">Actions</div>
+    <div class="item">
+      <div class="label">Changes:</div>
+      <div class="value">
+        None (this page is currently read-only)
+      </div>
+      <div class="nl" />
+    </div>
+
+    </form>
+
+  </div>
diff --git a/pages/details/memory.php b/pages/details/memory.php
new file mode 100644 (file)
index 0000000..9ca4762
--- /dev/null
@@ -0,0 +1,89 @@
+<?php
+  if ((array_key_exists('ch-discard', $_POST)) && ($_POST['ch-discard'])) 
+    Die(Header('Location: '.$_SERVER['REQUEST_URI']));
+
+  $ci  = $lv->host_get_node_info();
+  $memory = round($ci['memory'] / 1024);
+  unset($ci);
+
+  $pmemory = array_key_exists('memory', $_POST) ? $_POST['memory'] : false;
+  $pmaxmem = array_key_exists('maxmem', $_POST) ? $_POST['maxmem'] : false;
+
+  $msg = '';
+  if ($pmemory && $pmaxmem) {
+    $msg = $lv->domain_change_memory_allocation($name, $pmemory, $pmaxmem) ? 'Memory allocation for next run has been altered successfully'
+           : 'Cannot change guest memory allocation: '.$lv->get_last_error();
+  }
+
+  $info = $lv->domain_get_info($name);
+  $guest_memory = round($info['memory'] / 1024);
+  $guest_maxmem = round($info['maxMem'] / 1024);
+  unset($info);
+?>
+  <!-- CONTENTS -->
+  <div id="content">
+
+    <script language="javascript">
+    <!--
+        var change_el;
+
+        function setElement(t, x) {
+            if (t == 'change')
+                change_el = x.name;
+        }
+        function check() {
+            if (change_el == 'ch-apply')
+                return (confirm('Do you really want to apply your changes?'));
+            if (change_el == 'ch-discard')
+                return (confirm('Do you really want to discard your changes?'));
+        }
+    -->
+    </script>
+
+<?php
+    if ($msg):
+?>
+    <div id="msg"><b>Message: </b><?= $msg ?></div>
+<?php
+    endif;
+?>
+
+    <form action="#" method="POST" onsubmit="return check();">
+
+    <!-- HOST SECTION -->
+    <div class="section">Host memory information</div>
+    <div class="item">
+      <div class="label">Total memory:</div>
+      <div class="value"><?= $memory ?> MiB</div>
+      <div class="nl" />
+    </div>
+    <!-- MACHINE SECTION -->
+    <div class="section">Machine memory allocation (in MiBs)</div>
+    <div class="item">
+      <div class="label">Current allocation:</div>
+      <div class="value">
+        <input type="text" name="memory" value="<?= $guest_memory ?>" />
+      </div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Max. allocation:</div>
+      <div class="value">
+        <input type="text" name="maxmem" value="<?= $guest_maxmem ?>" />
+      </div>
+      <div class="nl" />
+    </div>
+    <!-- ACTIONS SECTION -->
+    <div class="section">Actions</div>
+    <div class="item">
+      <div class="label">Changes:</div>
+      <div class="value">
+        <input type="submit" name="ch-apply" value=" Apply changes " onclick="setElement('change', this)" />
+        <input type="submit" name="ch-discard" value=" Discard changes " onclick="setElement('change', this)" />
+      </div>
+      <div class="nl" />
+    </div>
+
+    </form>
+
+  </div>
diff --git a/pages/details/multimedia-devices.php b/pages/details/multimedia-devices.php
new file mode 100644 (file)
index 0000000..120d934
--- /dev/null
@@ -0,0 +1,43 @@
+  <!-- CONTENTS -->
+  <div id="content">
+
+    <form action="#" method="POST">
+
+    <div class="section">Machine multimedia devices</div>
+    <div class="item">
+      <div class="label">Console:</div>
+      <div class="value"><?= $lv->domain_get_multimedia_device($res, 'console', true) ?></div>
+      <div class="nl" />
+    </div>
+
+    <div class="item">
+      <div class="label">Input device:</div>
+      <div class="value"><?= $lv->domain_get_multimedia_device($res, 'input', true) ?></div>
+      <div class="nl" />
+    </div>
+
+    <div class="item">
+      <div class="label">Graphics device:</div>
+      <div class="value"><?= $lv->domain_get_multimedia_device($res, 'graphics', true) ?></div>
+      <div class="nl" />
+    </div>
+
+    <div class="item">
+      <div class="label">Video:</div>
+      <div class="value"><?= $lv->domain_get_multimedia_device($res, 'video', true) ?></div>
+      <div class="nl" />
+    </div>
+
+    <!-- ACTIONS SECTION -->
+    <div class="section">Actions</div>
+    <div class="item">
+      <div class="label">Changes:</div>
+      <div class="value">
+        None (this page is currently read-only)
+      </div>
+      <div class="nl" />
+    </div>
+
+    </form>
+
+  </div>
diff --git a/pages/details/network-devices.php b/pages/details/network-devices.php
new file mode 100644 (file)
index 0000000..787c399
--- /dev/null
@@ -0,0 +1,147 @@
+<?php
+  $dev = array_key_exists('dev', $_GET) ? $_GET['dev'] : false;
+  $action = array_key_exists('action', $_GET) ? $_GET['action'] : false;
+
+  $msg = '';
+  $frm = '';
+  if (($action == 'del-nic') && ($dev)) {
+    $msg = $lv->domain_nic_remove($name, base64_decode($dev)) ? 'Network card has been removed successfully' :
+               'Cannot remove disk: '.$lv->get_last_error();
+  }
+  if ($action == 'add-nic') {
+    if (array_key_exists('mac', $_POST))
+        $msg = $lv->domain_nic_add($name, $_POST['mac'], $_POST['network'], $_POST['nic_type']) ?
+                                       'Network card has been successfully added to the guest' :
+                                       'Cannot add NIC to the guest: '.$lv->get_last_error();
+    else {
+       $nets = $lv->get_networks();
+       $models = $lv->get_nic_models();
+
+        $frm = '<div class="section">Add a new network interface card</div>
+                <form method="POST">
+                <table id="form-table">
+                  <tr>
+                    <td align="right"><b>MAC Address: </b></td>
+                    <td><input type="text" name="mac" value="'.$lv->generate_random_mac_addr().'"/></td>
+                  </tr>
+                 <tr>
+                   <td align="right"><b>Network: </b></td>
+                   <td>
+                      <select name="network">';
+
+       for ($i = 0; $i < sizeof($nets); $i++)
+               $frm .= '<option value="'.$nets[$i].'">'.$nets[$i].'</option>';
+
+       $frm .= '    </select>
+                    </td>
+                 </tr>
+                  <tr>
+                    <td align="right"><b>NIC Type: </b></td>
+                    <td>
+                      <select name="nic_type">';
+
+       for ($i = 0; $i < sizeof($models); $i++)
+               $frm .= '<option value="'.$models[$i].'">'.$models[$i].'</option>';
+
+       $frm .= '
+                      </select>
+                    </td>
+                  </tr>
+                  <tr align="center">
+                    <td colspan="2"><input type="submit" value=" Add new NIC " /></td>
+                  </tr>
+                </table>
+                </form>';
+    }
+  }
+
+  $tmp = $lv->get_nic_info($name);
+  $numDisks = sizeof($tmp);
+?>
+  <!-- CONTENTS -->
+  <div id="content">
+
+    <script language="javascript">
+    <!--
+        function confirmAddition() {
+            if (confirm('Do you really want to add a new network interface card ?')) {
+                location.href = '?name=<?= $name.'&page='.$page ?>&action=add-nic';
+            }
+        }
+        function askNicDeletion(mac, macb64) {
+            if (confirm('Are you sure you want to delete interface with MAC address '+mac+' from the guest?'))
+                location.href = '?name=<?= $name.'&page='.$page.'&action=del-nic&dev=' ?>'+macb64;
+        }
+    -->
+    </script>
+
+<?php
+    if ($msg):
+?>
+    <div id="msg"><b>Message: </b><?= $msg ?></div>
+<?php
+    endif;
+?>
+<?php
+    if ($frm):
+?>
+    <div><?= $frm ?></div>
+<?php
+    endif;
+?>
+
+    <form action="#" method="POST">
+
+    <div class="section">Machine network devices</div>
+    <div class="item">
+      <div class="label">Number of NICs:</div>
+      <div class="value"><?= $numDisks ?></div>
+      <div class="nl" />
+    </div>
+
+<?php
+    for ($i = 0; $i < sizeof($tmp); $i++):
+        $nic = $tmp[$i];
+?>
+    <!-- NIC SECTION -->
+    <div class="section">Network interface card #<?= $i + 1 ?></div>
+    <div class="item">
+      <div class="label">MAC Address:</div>
+      <div class="value"><?= $nic['mac'] ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Network:</div>
+      <div class="value"><?= $nic['network'] ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">NIC Type:</div>
+      <div class="value"><?= $nic['nic_type'] ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Action:</div>
+      <div class="value">
+        <input type="button" onclick="askNicDeletion('<?= $nic['mac'] ?>', '<?= base64_encode($nic['mac']) ?>')" value=" Remove network interface " />
+      </div>
+      <div class="nl" />
+    </div>
+<?
+    endfor;
+    unset($tmp);
+?>
+
+    <!-- ACTIONS SECTION -->
+    <div class="section">Actions</div>
+    <div class="item">
+      <div class="label">Changes:</div>
+      <div class="value">
+        <input type="button" name="add-nic" value=" Add new a new network interface " onclick="confirmAddition()" />
+      </div>
+      <div class="nl" />
+    </div>
+
+    </form>
+
+  </div>
diff --git a/pages/details/overview.php b/pages/details/overview.php
new file mode 100644 (file)
index 0000000..a1cc694
--- /dev/null
@@ -0,0 +1,133 @@
+<?php
+       if ((array_key_exists('ch-discard', $_POST)) && ($_POST['ch-discard']))
+               Die(Header('Location: '.$_SERVER['REQUEST_URI']));
+       if ((array_key_exists('ch-apply', $_POST)) && ($_POST['ch-apply'])) {
+               $features = array('apic', 'acpi', 'pae', 'hap');
+               for ($i = 0; $i < sizeof($features); $i++) {
+                       $feature = $features[$i];
+                       $val = (array_key_exists('feature_'.$feature, $_POST) && ($_POST['feature_'.$feature])) ? true : false;
+
+                       $lv->domain_set_feature($res, $feature, $val);
+               }
+
+               $lv->domain_set_clock_offset($res, $_POST['clock_offset']);
+               $lv->domain_set_description($res, $_POST['description']);
+       }
+
+       $uuid = libvirt_domain_get_uuid_string($res);
+       $info = $lv->domain_get_info($name);
+       $status = $lv->domain_state_translate($info['state']);
+       $desc = $lv->domain_get_description($res);
+       $arch = $lv->domain_get_arch($res);
+       $apic = $lv->domain_get_feature($res, 'apic');
+       $acpi = $lv->domain_get_feature($res, 'acpi');
+       $pae  = $lv->domain_get_feature($res, 'pae');
+       $hap  = $lv->domain_get_feature($res, 'hap');
+       $clock = $lv->domain_get_clock_offset($res);
+       unset($info);
+?>
+  <!-- CONTENTS -->
+  <div id="content">
+
+    <script language="javascript">
+    <!--
+        var change_el;
+
+        function setElement(t, x) {
+            if (t == 'change')
+                change_el = x.name;
+        }
+        function check() {
+            if (change_el == 'ch-apply')
+                return (confirm('Do you really want to apply your changes?'));
+            if (change_el == 'ch-discard')
+                return (confirm('Do you really want to discard your changes?'));
+        }
+    -->
+    </script>
+
+    <form action="#" method="POST" onsubmit="return check();">
+
+    <!-- GENERAL SECTION -->
+    <div class="section">General</div>
+    <div class="item">
+      <div class="label">Name:</div>
+      <div class="value"><?= $name ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">UUID:</div>
+      <div class="value"><?= $uuid ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Status:</div>
+      <div class="value"><?= $status ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Description:</div>
+      <div class="value">
+        <textarea rows="10" cols="60" name="description"><?= $desc ?></textarea>
+      </div>
+      <div class="nl" />
+    </div>
+    <!-- MACHINE DETAILS SECTION -->
+    <div class="section">Machine details</div>
+    <div class="item">
+      <div class="label">Architecture:</div>
+      <div class="value"><?= $arch ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">APIC:</div>
+      <div class="value">
+        <input type="checkbox" value="1" <?= ($apic ? 'checked="checked"' : '') ?> name="feature_apic" />
+      </div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">ACPI:</div>
+      <div class="value">
+        <input type="checkbox" value="1" <?= ($acpi ? 'checked="checked"' : '') ?> name="feature_acpi" />
+      </div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">PAE:</div>
+      <div class="value">
+        <input type="checkbox" value="1" <?= ($pae ? 'checked="checked"' : '') ?> name="feature_pae" />
+      </div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">HAP:</div>
+      <div class="value">
+        <input type="checkbox" value="1" <?= ($hap ? 'checked="checked"' : '') ?> name="feature_hap" />
+      </div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Clock offset:</div>
+      <div class="value">
+        <select name="clock_offset">
+          <option value="utc" <?= ($clock == 'utc'  ? 'selected="selected"' : '') ?>>UTC</option>
+          <option value="localtime" <?= ($clock == 'localtime'  ? 'selected="selected"' : '') ?>>localtime</option>
+        </select>
+      </div>
+      <div class="nl" />
+    </div>
+    <!-- ACTIONS SECTION -->
+    <div class="section">Actions</div>
+    <div class="item">
+      <div class="label">Changes:</div>
+      <div class="value">
+        <input type="submit" name="ch-apply" value=" Apply changes " onclick="setElement('change', this)" />
+        <input type="submit" name="ch-discard" value=" Discard changes " onclick="setElement('change', this)" />
+      </div>
+      <div class="nl" />
+    </div>
+
+    </form>
+
+  </div>
diff --git a/pages/details/processor.php b/pages/details/processor.php
new file mode 100644 (file)
index 0000000..0bc8db6
--- /dev/null
@@ -0,0 +1,88 @@
+<?php
+  $ci  = $lv->get_connect_information();
+  $max = $ci['hypervisor_maxvcpus'];
+  unset($ci);
+
+  $msg = '';
+  $cpus = array_key_exists('cpu_count', $_POST) ? $_POST['cpu_count'] : false;
+  if ($cpus) {
+    $msg = $lv->domain_change_numVCpus($name, $cpus) ? 'Number of VCPUs for next run has been altered successfully'
+           : 'Cannot change guest VCPU count: '.$lv->get_last_error();
+  }
+  $info = $lv->domain_get_info($name);
+  $guest_cpu_count = $info['nrVirtCpu'];
+  unset($info);
+  $ci  = $lv->host_get_node_info();
+  $cpus = $ci['cpus'];
+  unset($ci);
+?>
+  <!-- CONTENTS -->
+  <div id="content">
+
+    <script language="javascript">
+    <!--
+        var change_el;
+
+        function setElement(t, x) {
+            if (t == 'change')
+                change_el = x.name;
+        }
+        function check() {
+            if (change_el == 'ch-apply')
+                return (confirm('Do you really want to apply your changes?'));
+            if (change_el == 'ch-discard')
+                return (confirm('Do you really want to discard your changes?'));
+        }
+    -->
+    </script>
+
+<?php
+    if ($msg):
+?>
+    <div id="msg"><b>Message: </b><?= $msg ?></div>
+<?php
+    endif;
+?>
+
+    <form action="#" method="POST" onsubmit="return check();">
+
+    <!-- HOST SECTION -->
+    <div class="section">Host processor information</div>
+    <div class="item">
+      <div class="label">CPU count:</div>
+      <div class="value"><?= $cpus ?></div>
+      <div class="nl" />
+    </div>
+    <div class="item">
+      <div class="label">Max. per guest:</div>
+      <div class="value"><?= $max ?> vCPUs</div>
+      <div class="nl" />
+    </div>
+    <!-- MACHINE SECTION -->
+    <div class="section">Machine processor information</div>
+    <div class="item">
+      <div class="label">vCPU count:</div>
+      <div class="value">
+        <select name="cpu_count">
+<?
+        for ($i = 1; $i <= $max; $i++)
+            echo '<option value='.$i.' '.($i == $guest_cpu_count ? 'selected="selected"' : '').'>'.$i.'</option>';
+?>
+        </select>
+      </div>
+      <div class="nl" />
+    </div>
+    <!-- ACTIONS SECTION -->
+    <div class="section">Actions</div>
+    <div class="item">
+      <div class="label">Changes:</div>
+      <div class="value">
+        <input type="submit" name="ch-apply" value=" Apply changes " onclick="setElement('change', this)" />
+        <input type="submit" name="ch-discard" value=" Discard changes " onclick="setElement('change', this)" />
+      </div>
+      <div class="nl" />
+    </div>
+
+    </form>
+
+  </div>
diff --git a/pages/details/screenshot.php b/pages/details/screenshot.php
new file mode 100644 (file)
index 0000000..3944a10
--- /dev/null
@@ -0,0 +1,236 @@
+<?php
+  if (array_key_exists('x', $_GET)) {
+    ob_end_clean();
+    $tmp = $lv->domain_send_pointer_event($name, $_GET['x'], $_GET['y'], 1, true);
+    if (!$tmp)
+       die( 'Error occured while sending pointer event: '.$lv->get_last_error() );
+
+    die( $_GET['x'].','.$_GET['y'] );
+  }
+
+  $interval = array_key_exists('interval', $_POST) ? $_POST['interval'] : 5;
+  $msg = '';
+  if (!$lv->domain_is_running($name))
+    $msg = 'Domain is not running';
+  if (!$lv->supports('screenshot'))
+    $msg = 'Host machine doesn\'t support getting domain screenshots';
+
+  if (array_key_exists('keys', $_POST)) {
+    $keys = $_POST['keys'];
+    if (!strstr( $_POST['submit'], 'without' ))
+       $keys .= '\n';
+
+    $lv->domain_send_keys($name, $keys);
+  }
+
+ function error($w, $h, $msg) {
+    $im = imagecreatetruecolor($w, $h);
+    $text_color = imagecolorallocate($im, 233, 14, 11);
+    imagestring($im, 5, 5, 20, 'We are sorry!', $text_color);
+
+    $arr = explode("\n", $msg);
+    for ($i = 0; $i < sizeof($arr); $i++) {
+      imagestring($im, 5, 5, 50 + ($i * 20), $arr[$i], $text_color);
+    }
+
+    imagepng($im);
+    imagedestroy($im);
+ }
+
+  if (array_key_exists('data', $_GET) && ($_GET['data'] == 'png')) {
+    ob_end_clean();
+    $tmp = $lv->domain_get_screenshot($name);
+    Header('Content-Type: image/png');
+    if (!$tmp)
+        error(240, 130, "Cannot get the domain\nscreenshot for domain\nrequested.");
+    else
+        echo $tmp;
+
+    exit;
+  }
+?>
+  <!-- CONTENTS -->
+  <div id="content">
+
+<?php
+    if ($msg):
+?>
+    <div class="section">Domain screenshot</div>
+    <div id="msg"><b>Message: </b><?= $msg ?></div>
+<?php
+    else:
+       $dims = $lv->domain_get_screen_dimensions($name);
+?>
+
+<div id="ajax-msg"></div>
+
+    <script language="javascript">
+    <!--
+        timerId = null;
+        delay = <?= $interval * 1000 ?>;
+       var IE = document.all ? true : false;
+       if (!IE) document.captureEvents(Event.MOUSEMOVE)
+       document.onmousemove = getMouseXY;
+
+       var tempX = 0
+       var tempY = 0
+       var screenshotX = 0
+       var screenshotY = 0
+       var imgX = 0
+       var imgY = 0
+
+       function sendMouse() {
+               var ajaxRequest;
+               try {
+                       ajaxRequest = new XMLHttpRequest();
+               } catch (e) {
+                       try {
+                       ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
+                       } catch (e) {
+                               try {
+                                       ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
+                               } catch (e) {
+                                       alert("Cannot activate AJAX object!");
+                                       return false;
+                               }
+                       }
+               }
+               ajaxRequest.onreadystatechange = function(){
+                       if(ajaxRequest.readyState == 4){
+                               var ajaxDisplay = document.getElementById('ajax-msg');
+                               ajaxDisplay.innerHTML = ajaxRequest.responseText;
+                       }
+               }
+               var loc = "<?= $_SERVER['REQUEST_URI'] ?>&x="+imgX+"&y="+imgY;
+               ajaxRequest.open("GET", loc, true);
+               ajaxRequest.send(null); 
+       }
+
+        function change_interval() {
+               val = document.getElementById('interval').value;
+               delay = val * 1000;
+               alert('Delay has been changed to '+val+' seconds');
+       }
+
+        function update_screenshot() {
+                src = "<?= $_SERVER['REQUEST_URI'].'&data=png' ?>";
+                var date = new Date();
+                src = src + '&date=' + date.getTime()
+                document.getElementById('screenshot').src = src;
+
+                clearTimeout(timerId);
+                timerID = setTimeout("update_screenshot()", delay);
+        }
+
+       function change_interval() {
+               val = document.getElementById('interval').value;
+               delay = val * 1000;
+               alert('Delay has been changed to '+val+' second(s)');
+
+               update_screenshot();
+       }
+
+       function findPosX(obj)
+       {
+               var curleft = 0;
+               if(obj.offsetParent)
+                       while(1) {
+                               curleft += obj.offsetLeft;
+                               if(!obj.offsetParent)
+                                       break;
+                               obj = obj.offsetParent;
+                       }
+               else if(obj.x)
+                       curleft += obj.x;
+               return curleft;
+       }
+
+       function findPosY(obj)
+       {
+               var curtop = 0;
+               if(obj.offsetParent)
+                       while(1) {
+                               curtop += obj.offsetTop;
+                               if(!obj.offsetParent)
+                                       break;
+                               obj = obj.offsetParent;
+                       }
+               else if(obj.y)
+                       curtop += obj.y;
+               return curtop;
+       }
+
+       function getScreenshotPos() {
+               img = document.getElementById('screenshot');
+
+               screenshotX = findPosX(img);
+               screenshotY = findPosY(img);
+       }
+
+       function getMouseXY(e) {
+               if (IE) {
+                       tempX = event.clientX + document.body.scrollLeft
+                       tempY = event.clientY + document.body.scrollTop
+               } else {
+                       tempX = e.pageX
+                       tempY = e.pageY
+               }
+               if (tempX < 0) tempX = 0;
+               if (tempY < 0) tempY = 0;
+
+               if ((screenshotX == 0) || (screenshotY == 0)) {
+                       setTimeout("getScreenshotPos()", 500);
+                       return false;
+               }
+
+               imgX = tempX - screenshotX;
+               imgY = tempY - screenshotY;
+
+               if (((imgX > <?= $dims['width'] ?>) || (imgY > <?= $dims['height'] ?>))
+                       || (imgX < 0) || (imgY < 0)) {
+                       imgX = 0;
+                       imgY = 0;
+               }
+       }
+
+       function screenshotClick() {
+               if ((imgX <= 0) || (imgY <= 0))
+                       return;
+
+               sendMouse();
+       }
+
+        timerID = setTimeout("update_screenshot()", delay);
+    -->
+    </script>
+
+    <!-- SETTINGS SECTION -->
+    <form class="table-form" method="POST">
+    <div class="section">Settings</div>
+    <div class="item">
+      <div class="label">Interval (sec):</div>
+      <div class="value">
+       <input type="text" name="interval" value="<?= $interval ?>" id="interval">
+       <input type="button" value=" Change " onclick="change_interval()">
+      </div>
+      <div class="nl" />
+    </div>
+
+    <div class="section">Domain screenshot</div>
+
+    <div class="screenshot"><img id="screenshot" src="<?= $_SERVER['REQUEST_URI'] ?>&amp;data=png" onclick="screenshotClick()"><br />
+    <form class="table-form" method="POST">
+    <tr>
+      <td><input type="text" name="keys" style="width: <?= $dims['width'] - 260 ?>px" autocomplete="off">
+       <input type="submit" name="submit" value="Send keys" style="width: 100px">
+       <input type="submit" name="submit" value="Send without Enter" style="width: 150px">
+      </td>
+    </tr>
+    </div>
+<?php
+    endif;
+?>
+
+    </form>
+
+  </div>
diff --git a/pages/domain-list.php b/pages/domain-list.php
new file mode 100644 (file)
index 0000000..ff22c1e
--- /dev/null
@@ -0,0 +1,148 @@
+<?php
+  $action = array_key_exists('action', $_GET) ? $_GET['action'] : false;
+
+  $msg = '';
+  $frm = '';
+  if ($action == 'domain-start') {
+    $name = $_GET['dom'];
+    $msg = $lv->domain_start($name) ? 'Domain has been started successfully' :
+               'Error while starting domain: '.$lv->get_last_error();
+  }
+
+  if ($action == 'domain-stop') {
+    $name = $_GET['dom'];
+    $msg = $lv->domain_shutdown($name) ? 'Domain command to stop has been completed successfully' :
+               'Error while stopping domain: '.$lv->get_last_error();
+  }
+
+  if ($action == 'domain-destroy') {
+    $name = $_GET['dom'];
+    $msg = $lv->domain_destroy($name) ? 'Domain has been destroyed successfully' :
+                'Error while destroying domain: '.$lv->get_last_error();
+  }
+
+  if ($action == 'domain-dump') {
+    $name = $_GET['dom'];
+
+    $inactive = (!$lv->domain_is_running($name)) ? true : false;
+
+    $xml = $lv->domain_get_xml($name, $inactive);
+    $frm = '<div class="section">Domain XML description for domain <i>'.$name.'</i></div><form method="POST">
+            <table id="form-table"><tr><td>Domain XML description: </td>
+            <td><textarea readonly="readonly" name="xmldesc" rows="25" cols="90%">'.$xml.'</textarea></td></tr><tr align="center"><td colspan="2">
+            </tr></form></table>';
+  }
+
+  if ($action == 'domain-edit') {
+    $name = $_GET['dom'];
+
+    $inactive = (!$lv->domain_is_running($name)) ? true : false;
+
+    if (array_key_exists('xmldesc', $_POST)) {
+        $msg = $lv->domain_change_xml($name, $_POST['xmldesc']) ? 'Domain definition has been changed' :
+                                      'Error changing domain definition: '.$lv->get_last_error();
+
+    }
+    else {
+        $xml = $lv->domain_get_xml($name, $inactive);
+        $frm = '<div class="section">Edit domain XML description for domain <i>'.$name.'</i></div><form method="POST"><table id="form-table"><tr><td>Domain XML description: </td>
+             <td><textarea name="xmldesc" rows="25" cols="90%">'.$xml.'</textarea></td></tr><tr align="center"><td colspan="2">
+             <input type="submit" value=" Edit domain XML description "></tr></form></table>';
+    }
+  }
+?>
+<div id="content">
+
+<?php
+    if ($msg):
+?>
+    <div id="msg"><b>Message: </b><?= $msg ?></div>
+<?php
+    endif;
+?>
+
+<?php
+    if ($frm)
+       echo $frm;
+?>
+
+<div class="section">Domain list</div>
+
+<table id="domain-list">
+  <tr>
+    <th>Name</th>
+    <th>Architecture</th>
+    <th>vCPUs</th>
+    <th>Memory</th>
+    <th>Disk(s)</th>
+    <th>NICs</th>
+    <th>State</th>
+    <th>ID</th>
+    <th>Action</th>
+  </tr>
+<?php
+               $doms = $lv->get_domains();
+               sort($doms);
+               for ($i = 0; $i < sizeof($doms); $i++) {
+                       $name = $doms[$i];
+                       $res = $lv->get_domain_object($name);
+                       $uuid = libvirt_domain_get_uuid_string($res);
+                       $dom = $lv->domain_get_info($res, $name);
+                       $mem = number_format($dom['memory'] / 1024, 2, '.', ' ').' MiB';
+                       $cpu = $dom['nrVirtCpu'];
+                       $id = $lv->domain_get_id($res, $name);
+                       $arch = $lv->domain_get_arch($res);
+                       if (!$id)
+                               $id = '-';
+                       $state = $lv->domain_state_translate($dom['state']);
+                       $nics = $lv->get_network_cards($res);
+                       if (($diskcnt = $lv->get_disk_count($res)) > 0) {
+                               $disks = $diskcnt.' / '.$lv->get_disk_capacity($res);
+                               $diskdesc = 'Current physical size: '.$lv->get_disk_capacity($res, true);
+                       }
+                       else {
+                               $disks = 'diskless';
+                               $diskdesc = '';
+                       }
+
+                       $running = $lv->domain_is_running($res, $name);
+                       if (!$running) {
+                               $actions  = '<a href="?page='.$page.'&amp;action=domain-start&amp;dom='.$name.'">Start domain</a> | ';
+                               $actions .= '<a href="?page='.$page.'&amp;action=domain-dump&amp;dom='.$name.'">Dump domain XML</a> | ';
+                               $actions .= '<a href="?page='.$page.'&amp;action=domain-edit&amp;dom='.$name.'">Edit domain XML</a> | ';
+
+                               $actions[ strlen($actions) - 2 ] = ' ';
+                               $actions = Trim($actions);
+                       }
+                       else {
+                               $actions  = '<a href="?page='.$page.'&amp;action=domain-stop&amp;dom='.$name.'">Stop domain</a> | ';
+                               $actions .= '<a href="?page='.$page.'&amp;action=domain-destroy&amp;dom='.$name.'">Destroy domain</a> | ';
+                               $actions .= '<a href="?page='.$page.'&amp;action=domain-dump&amp;dom='.$name.'">Dump domain XML</a> | ';
+
+                               if ($lv->supports('screenshot'))
+                                       $actions .= '<a href="?name='.$name.'&amp;page=screenshot">Get screenshot</a> | ';
+
+                               $actions[ strlen($actions) - 2 ] = ' ';
+                               $actions = Trim($actions);
+                       }
+
+                       echo "<tr>
+                                        <td class=\"name\">
+                                            <a href=\"?name=$name\">$name</a>
+                                        </td>
+                                        <td>$arch</td>
+                                        <td>$cpu</td>
+                                        <td>$mem</td>
+                                        <td align=\"center\" title='$diskdesc'>$disks</td>
+                                        <td align=\"center\">$nics</td>
+                                        <td>$state</td>
+                                        <td align=\"center\">$id</td>
+                                        <td>
+                                           $actions
+                                        </td>
+                                  </tr>";
+                }
+       ?>
+</table>
+
+</div>
diff --git a/pages/info.php b/pages/info.php
new file mode 100644 (file)
index 0000000..75f97bb
--- /dev/null
@@ -0,0 +1,120 @@
+<?php
+       ob_start();
+       PHPInfo();
+       $c = ob_get_contents();
+       ob_end_clean();
+
+       $c = substr($c, strpos($c, 'module_libvirt'));
+        $c = substr($c, strpos($c, 'h2') + 3);
+
+       $p = strpos($c, 'module') - 3;
+       $out = substr($c, 0, $p);
+
+        $out = str_replace('<tr>', '<div class="item">', $out);
+       $out = str_replace('<td class="e">', '<div class="label">', $out);
+       $out = str_replace('</td><td class="v">', '</div><div class="value">', $out);
+       $out = str_replace('</td></tr>', '</div><div class="nl" /></div>', $out);
+
+       $tmp = explode("\n", $out);
+       $start_el = false;
+       $last_el = false;
+       for ($i = 0; $i < sizeof($tmp); $i++) {
+               if (strpos('.'.$tmp[$i], '</table'))
+                       $last_el = $i;
+               if (strpos('.'.$tmp[$i], '<table'))
+                       $start_el = $i + 1;
+       }
+
+       $tmp2 = array();
+       for ($i = $start_el; $i < $last_el; $i++)
+               $tmp2[] = $tmp[$i];
+       unset($tmp);
+
+       $out = join("\n", $tmp2);
+?>
+
+<div id="content">
+
+<div class="section">Virtual machine control for PHP</div>
+
+<div class="item">
+        <div class="label">Version</div>
+        <div class="value"><?= PHPVIRTCONTROL_VERSION ?></div>
+        <div class="nl">
+</div>
+
+<div class="section">Connection details</div>
+
+<?php
+       $tmp  = $lv->get_connect_information();
+?>
+
+<div class="item">
+        <div class="label">Hypervisor</div>
+        <div class="value"><?= $tmp['hypervisor_string'] ?></div>
+        <div class="nl">
+</div>
+
+<div class="item">
+        <div class="label">Connection URI</div>
+        <div class="value"><?= $tmp['uri'] ?></div>
+        <div class="nl">
+</div>
+
+<div class="item">
+        <div class="label">Hostname</div>
+        <div class="value"><?= $tmp['hostname'] ?></div>
+        <div class="nl">
+</div>
+
+<div class="item">
+        <div class="label">Encrypted</div>
+        <div class="value"><?= $tmp['encrypted'] ?></div>
+        <div class="nl">
+</div>
+
+<div class="item">
+        <div class="label">Secure</div>
+        <div class="value"><?= $tmp['secure'] ?></div>
+        <div class="nl">
+</div>
+
+<div class="item">
+        <div class="label">Hypervisor limit</div>
+        <div class="value"><?= $tmp['hypervisor_maxvcpus'] ?> vCPUs per guest</div>
+        <div class="nl">
+</div>
+
+<?php
+       unset($tmp);
+       $tmp = $lv->host_get_node_info();
+?>
+<div class="section">Host machine details</div>
+<div class="item">
+       <div class="label">Model</div>
+       <div class="value"><?= $tmp['model'] ?></div>
+       <div class="nl">
+</div>
+
+<div class="item">
+        <div class="label">Memory</div>
+        <div class="value"><?= (int)($tmp['memory'] / 1024) ?> MiB</div>
+        <div class="nl">
+</div>
+
+<div class="item">
+        <div class="label">CPUs/cores</div>
+        <div class="value"><?= $tmp['cpus'].' ('.$tmp['nodes'].' nodes, '.$tmp['sockets'].' sockets, '.$tmp['cores'].' cores)' ?></div>
+        <div class="nl">
+</div>
+
+<div class="item">
+        <div class="label">CPU Speed</div>
+        <div class="value"><?= $tmp['mhz'] ?> MHz</div>
+        <div class="nl">
+</div>
+<?php unset($tmp) ?>
+<div class="section">libvirt PHP module information</div>
+<?= $out ?>
+
+</div>
diff --git a/pages/overview.php b/pages/overview.php
new file mode 100644 (file)
index 0000000..e2ad4ca
--- /dev/null
@@ -0,0 +1,135 @@
+<div id="content">
+
+<div class="section">Connections</div>
+
+<?php
+       if ($errmsg)
+               echo '<div id="msg"><b>Message: </b>'.$errmsg.'</div>';
+?>
+
+<p>This is the virtual machine controller tool written in PHP language. You can manage virtual machines (guests) on your machines using this
+web-based controlling interface. For the navigation please use the upper menu and select the domain from the <i>Domain list</i> link to see
+the virtual machines available on the current machine. You can also see the information about the hypervisor connection, host machine and
+libvirt PHP module (used by this system) on the <i>Information</i> page.</p>
+
+<p>The hypervisor on the machine running Apache with PHP is being probed automatically if applicable however you can override the definition
+to connect to any other hypervisor on remote machine. To achieve this you need to select a connection and change the host using the form
+below. If you experience any issues (e.g. not working connectivity to SSH-based remote host) please make sure you're having all the prerequisites
+met. For more reference please check <a href="http://libvirt.org/auth.html" target="_blank">libvirt authentication documentation.</a></p>
+
+<?php
+       $hv = array_key_exists('lvchypervisor', $_POST) ? $_POST['lvchypervisor'] : false;
+       $rh = array_key_exists('lvcremotehost', $_POST) ? $_POST['lvcremotehost'] : false;
+       $rm = array_key_exists('lvcremotemethod', $_POST) ? $_POST['lvcremotemethod'] : false;
+       $un = array_key_exists('lvcusername', $_POST) ? $_POST['lvcusername'] : false;
+       $hn = array_key_exists('lvchostname', $_POST) ? $_POST['lvchostname'] : false;
+       $lg = array_key_exists('lvclogging', $_POST) ? $_POST['lvclogging'] : false;
+
+       if ($hv) {
+               $uri = $lv->generate_connection_uri($hv, $rh, $rm, $un, $hn);
+               $test = libvirt_connect($uri);
+               $ok = is_resource($test);
+               unset($test);
+
+               if ($ok) {
+                       $_SESSION['connection_uri'] = $uri;
+                       $_SESSION['connection_logging'] = $lg;
+                       echo '<p>Changed connection URI to <b>'.$uri.'</b></p>';
+
+                       echo '<a href="?">Click here to reload and connect using new URI</a>';
+                       die('</div>');
+               }
+               else {
+                       echo '<p>Connection to <b>'.$uri.'</b> failed. Not changing URI...</p>';
+               }
+       }
+
+       $ds = ($rh) ? 'table-row' : 'none';
+?>
+
+<p />
+
+<script language="javascript">
+<!--
+  function change_remote(el) {
+    val = el.value;
+
+    if (val == 0)
+      style = 'none';
+    else
+      style = 'table-row';
+
+    document.getElementById('remote1').style.display = style;
+    document.getElementById('remote2').style.display = style;
+    document.getElementById('remote3').style.display = style;
+  }
+-->
+</script>
+
+<form method="POST">
+<table id="form-table">
+  <tr>
+    <th colspan="2">Change host connection</th>
+  </tr>
+  <tr>
+    <td>Hypervisor: </td>
+    <td align="right">
+      <select name="lvchypervisor">
+        <option value="xen" <?= ($hv == 'xen') ? ' selected="selected"' : '' ?>>Xen</option>
+        <option value="qemu" <?= ($hv == 'qemu') ? ' selected="selected"' : '' ?>>QEMU/KVM</option>
+      </select>
+    </td>
+  </tr>
+  <tr>
+    <th colspan="2">Host options</th>
+  </tr>
+  <tr>
+    <td>Host type: </td>
+    <td align="right">
+      <select name="lvcremotehost" onchange="change_remote(this)">
+        <option value="0" <?= ($rh == '0') ? ' selected="selected"' : '' ?>>Local host</option>
+        <option value="1" <?= ($rh == '1') ? ' selected="selected"' : '' ?>>Remote host</option>
+      </select>
+    </td>
+  </tr>
+  <tr id="remote1" style="display: <?= $ds ?>">
+    <td>Connection method: </td>
+    <td align="right">
+      <select name="lvcremotemethod">
+        <option value="ssh" <?= ($rm == 'ssh') ? ' selected="selected"' : '' ?>>SSH</option>
+        <option value="tcp" <?= ($rm == 'tcp') ? ' selected="selected"' : '' ?>>TCP (SASL, Kerberos, ...)</option>
+        <option value="tls" <?= ($rm == 'tls') ? ' selected="selected"' : '' ?>>SSL/TLS with certificates</option>
+      </select>
+    </td>
+  </tr>
+  <tr id="remote2" style="display: <?= $ds ?>">
+    <td>User name: </td>
+    <td align="right">
+      <input type="text" name="lvcusername" value="<?= $un ?>" />
+    </td>
+  </tr>
+  <tr id="remote3" style="display: <?= $ds ?>">
+    <td>Host: </td>
+    <td align="right">
+      <input type="text" name="lvchostname" value="<?= $hn ?>" />
+    </td>
+  </tr>
+  <tr>
+    <th colspan="2">Logging options</th>
+  </tr>
+  <tr>
+    <td>Log file: </td>
+    <td align="right">
+      <input type="text" name="lvclogging" value="<?= $lg ?>" title="Leave empty to disable logging" />
+    </td>
+  </tr>
+  <tr align="center">
+    <td colspan="2">
+      <input type="submit" value=" Connect to the new host " />
+    </td>
+  </tr>
+</table>
+</form>
+
+</div>
+