Introduce experimental option to create a new VM
authorMichal Novotny <minovotn@redhat.com>
Thu, 21 Jul 2011 15:57:13 +0000 (17:57 +0200)
committerMichal Novotny <minovotn@redhat.com>
Thu, 21 Jul 2011 15:57:13 +0000 (17:57 +0200)
Requires latest version of libvirt-php to work properly.

Signed-off-by: Michal Novotny <minovotn@redhat.com>

classes/language.php
classes/libvirt.php
lang/cs.php
lang/en.php
manager.css
pages/details/network-devices.php
pages/details/overview.php
pages/details/screenshot.php
pages/domain-list.php
pages/new-vm.php [new file with mode: 0644]

index 0f5c99f..44342ea 100644 (file)
                                                                'directory for the apache user (you will most likely need to change it if you are using a '.
                                                                'different user name to run Apache/php) and creates the hidden SSH settings directory. Then '.
                                                                'a SSH key is being generated (if it doesn\'t exist yet) and copied to the destination machine.',
+                                       'create-new-vm' => 'Create a new VM',
+                                       'install-image' => 'Install image',
+                                       'create-vm' => 'Create VM',
+                                       'clock-offset' => 'Clock offset',
+                                       'features' => 'Features',
+                                       'setup' => 'Setup',
+                                       'nic' => 'network',
+                                       'disk' => 'disk',
+                                       'new-vm-disk' => 'VM Disk',
+                                       'new-vm-existing' => 'Use existing disk image',
+                                       'new-vm-create' => 'Create new disk image',
+                                       'vm-disk-size' => 'New disk size',
                                        );
 
                        $this->trans = $trans;
index 8026107..be1ac05 100644 (file)
                        return true;
                }
 
+               function get_capabilities() {
+                       $tmp = libvirt_connect_get_capabilities($this->conn);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function get_default_emulator() {
+                       $tmp = libvirt_connect_get_capabilities($this->conn, '//capabilities/guest/arch/domain/emulator');
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function domain_new($name, $img, $vcpus, $features, $mem, $maxmem, $clock, $nic, $disk) {
+                       $uuid = $this->domain_generate_uuid_unique();
+                       $emulator = $this->get_default_emulator();
+                       $name = str_replace(' ', '', $name);
+
+                       $mem *= 1024;
+                       $maxmem *= 1024;
+
+                       $fs = '';
+                       for ($i = 0; $i < sizeof($features); $i++) {
+                               $fs .= '<'.$features[$i].' />';
+                       }
+
+                       $diskstr = '';
+                       if (!empty($disk)) {
+                               if ($disk['size'])
+                                       if (!$this->create_image($disk['image'], $disk['size'], $disk['driver']))
+                                               return false;
+
+                               $path = ini_get('libvirt.image_path');
+                               $diskstr = "<disk type='file' device='disk'>
+                                               <driver name='qemu' type='{$disk['driver']}' />
+                                                <source file='$path/{$disk['image']}'/>
+                                                <target bus='{$disk['bus']}' dev='hda' />
+                                         </disk>";
+                       }
+                       $netstr = '';
+                       if (!empty($nic)) {
+                               $model = '';
+                               if ($nic['type'] != 'default')
+                                       $model = "<model type='{$nic['type']}'/>";
+                               $netstr = "
+                                           <interface type='network'>
+                                             <mac address='{$nic['mac']}'/>
+                                             <source network='{$nic['network']}'/>
+                                             $model
+                                           </interface>";
+                       }
+
+                       $xml = "<domain type='kvm'>
+                               <name>$name</name>
+                               <currentMemory>$mem</currentMemory>
+                               <memory>$maxmem</memory>
+                               <uuid>$uuid</uuid>
+                               <os>
+                                       <type arch='i686'>hvm</type>
+                                       <boot dev='cdrom'/>
+                                       <boot dev='hd'/>
+                               </os>
+                               <features>
+                               $fs
+                               </features>
+                               <clock offset=\"$clock\"/>
+                               <on_poweroff>destroy</on_poweroff>
+                               <on_reboot>destroy</on_reboot>
+                               <on_crash>destroy</on_crash>
+                               <vcpu>$vcpus</vcpu>
+                               <devices>
+                                       <emulator>$emulator</emulator>
+                                       $diskstr
+                                       <disk type='file' device='cdrom'>
+                                               <driver name='qemu'/>
+                                               <source file='$img'/>
+                                               <target dev='hdc' bus='ide'/>
+                                               <readonly/>
+                                       </disk>
+                                       $netstr
+                                       <input type='mouse' bus='ps2'/>
+                                       <graphics type='vnc' port='-1'/>
+                                       <console type='pty'/>
+                                       <sound model='ac97'/>
+                                       <video>
+                                               <model type='cirrus'/>
+                                       </video>
+                               </devices>
+                               </domain>";
+
+                       $tmp = libvirt_domain_create_xml($this->conn, $xml);
+                       if (!$tmp)
+                               return $this->_set_last_error();
+
+                       $xml = "<domain type='kvm'>
+                               <name>$name</name>
+                               <currentMemory>$mem</currentMemory>
+                               <memory>$maxmem</memory>
+                               <uuid>$uuid</uuid>
+                               <os>
+                                       <type arch='i686'>hvm</type>
+                                       <boot dev='hd'/>
+                               </os>
+                               <features>
+                               $fs
+                               </features>
+                               <clock offset=\"$clock\"/>
+                               <on_poweroff>destroy</on_poweroff>
+                               <on_reboot>destroy</on_reboot>
+                               <on_crash>destroy</on_crash>
+                               <vcpu>$vcpus</vcpu>
+                               <devices>
+                                       <emulator>$emulator</emulator>
+                                       $diskstr
+                                       $netstr
+                                       <input type='mouse' bus='ps2'/>
+                                       <graphics type='vnc' port='-1'/>
+                                       <console type='pty'/>
+                                       <sound model='ac97'/>
+                                       <video>
+                                               <model type='cirrus'/>
+                                       </video>
+                               </devices>
+                               </domain>";
+                               
+                       $tmp = libvirt_domain_define_xml($this->conn, $xml);
+                       return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
+               function create_image($image, $size, $driver) {
+                       $tmp = libvirt_image_create($this->conn, $image, $size, $driver);
+                        return ($tmp) ? $tmp : $this->_set_last_error();
+               }
+
                function generate_connection_uri($hv, $remote, $remote_method, $remote_username, $remote_hostname, $session=false) {
                        if ($hv == 'qemu') {
                                if ($session)
                        return ($tmp) ? $tmp : $this->_set_last_error();
                }
 
+               function domain_generate_uuid($seed=false) {
+                       if (!$seed)
+                               $seed = time();
+                       srand($seed);
+
+                       $ret = array();
+                       for ($i = 0; $i < 16; $i++)
+                               $ret[] = $this->macbyte(rand() % 256);
+
+                       $a = $ret[0].$ret[1].$ret[2].$ret[3];
+                       $b = $ret[4].$ret[5];
+                       $c = $ret[6].$ret[7];
+                       $d = $ret[8].$ret[9];
+                       $e = $ret[10].$ret[11].$ret[12].$ret[13].$ret[14].$ret[15];
+
+                       return $a.'-'.$b.'-'.$c.'-'.$d.'-'.$e;
+               }
+
+               function domain_generate_uuid_unique() {
+                       $uuid = $this->domain_generate_uuid();
+
+                       while ($this->domain_get_name_by_uuid($uuid))
+                               $uuid = $this->domain_generate_uuid();
+
+                       return $uuid;
+               }
+
                function domain_shutdown($domain) {
                        $dom = $this->get_domain_object($domain);
                        if (!$dom)
index 5ad4d4a..3d1d645 100644 (file)
@@ -27,7 +27,7 @@
                                        'pool_running_inac' => 'Běží, ale není dostupný',
                                        'unknown' => 'Neznámo',
                                        'dom_running' => 'spuštěno',
-                                       'dom_nostate' => 'beze stave',
+                                       'dom_nostate' => 'beze stavu',
                                        'dom_blocked' => 'blokováno',
                                        'dom_paused' =>  'zapauzovano',
                                        'dom_shutdown' => 'vypnuto',
                                                                '<b>apache-key-copy</b> musí být spuštěna v kontextu superuživatele root, aby byla schopná přepnutí do uživatele '.
                                                                'apache i v případě, že uživatel nemá přiřazený žádný shell. Zde bude aplikace přistupovat domovský adresář '.
                                                                'uživatele apache, kde vytvoří SSH klíč (pokud neexistuje) a zkopíruje veřejný klíč na vzdálený systém, který '.
-                                                               'chcete spravovat.'
+                                                               'chcete spravovat.',
+                                       'create-new-vm' => 'Vytvořit nový virtuální stroj',
+                                       'install-image' => 'Instalační obraz',
+                                       'create-vm' => 'Vytvořit VM',
+                                       'clock-offset' => 'Hodinový offset',
+                                       'features' => 'Vlastnosti',
+                                       'setup' => 'Nastavit',
+                                       'nic' => 'síť',
+                                       'disk' => 'disk',
+                                       'new-vm-disk' => 'VM Disk',
+                                       'new-vm-existing' => 'Použít existující disk',
+                                       'new-vm-create' => 'Vytvořit nový disk',
+                                       'vm-disk-size' => 'Nová velikost disku',
                                        );
 ?>
index 44cfed1..73734ee 100644 (file)
                                                                'directory for the apache user (you will most likely need to change it if you are using a '.
                                                                'different user name to run Apache/php) and creates the hidden SSH settings directory. Then '.
                                                                'a SSH key is being generated (if it doesn\'t exist yet) and copied to the destination machine.',
+                                       'create-new-vm' => 'Create a new VM',
+                                       'install-image' => 'Install image',
+                                       'create-vm' => 'Create VM',
+                                       'clock-offset' => 'Clock offset',
+                                       'features' => 'Features',
+                                       'setup' => 'Setup',
+                                       'nic' => 'network',
+                                       'disk' => 'disk',
+                                       'new-vm-disk' => 'VM Disk',
+                                       'new-vm-existing' => 'Use existing disk image',
+                                       'new-vm-create' => 'Create new disk image',
+                                       'vm-disk-size' => 'New disk size',
                                        );
 ?>
index b423864..98c69a8 100644 (file)
        width: 200px;
 }
 
+#content #form-table .checkbox {
+       width: 20px;
+}
+
 #content #form-table select {
        width: 200px;
 }
index 1f39f38..6fcce9b 100644 (file)
     </div>
 
 <?php
+    if (!$tmp)
+       $tmp = array();
+
     for ($i = 0; $i < sizeof($tmp); $i++):
         $nic = $tmp[$i];
 ?>
index b5ba0ce..94ae16a 100644 (file)
       <div class="nl" />
     </div>
     <div class="item">
-      <div class="label">Clock offset:</div>
+      <div class="label"><?= $lang->get('clock-offset') ?>:</div>
       <div class="value">
         <select name="clock_offset">
           <option value="utc" <?= ($clock == 'utc'  ? 'selected="selected"' : '') ?>>UTC</option>
index 0d229f6..c334e96 100644 (file)
        $dims = $lv->domain_get_screen_dimensions($name);
 ?>
 
-<?php
-    if (ALLOW_EXPERIMENTAL_VNC):
-?>
 <div id="ajax-msg"></div>
 
     <script language="javascript">
     <!--
         timerId = null;
         delay = <?= $interval * 1000 ?>;
+
+<?php
+    if (ALLOW_EXPERIMENTAL_VNC):
+?>
        var IE = document.all ? true : false;
        if (!IE) document.captureEvents(Event.MOUSEMOVE)
        document.onmousemove = getMouseXY;
                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;
                sendMouse();
        }
 
-        timerID = setTimeout("update_screenshot()", delay);
-    -->
-    </script>
 <?php
     endif;
 ?>
+        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();
+        }
+
+        timerID = setTimeout("update_screenshot()", delay);
+    -->
+    </script>
 
     <!-- SETTINGS SECTION -->
     <form class="table-form" method="POST">
index aa06408..4c8fde9 100644 (file)
 
 <table id="domain-list">
   <tr>
+    <td colspan="2" align="left">
+      <a href="?page=new-vm"><?= $lang->get('create-new-vm') ?></a>
+    </td>
+  </tr>
+  <tr>
     <th><?= $lang->get('name') ?></th>
     <th><?= $lang->get('arch') ?></th>
     <th><?= $lang->get('vcpus') ?></th>
diff --git a/pages/new-vm.php b/pages/new-vm.php
new file mode 100644 (file)
index 0000000..6eb8859
--- /dev/null
@@ -0,0 +1,276 @@
+<?php
+  $skip = false;
+  $msg = false;
+  if (array_key_exists('sent', $_POST)) {
+       $features = array('apic', 'acpi', 'pae', 'hap');
+
+       $iso_path = ini_get('libvirt.iso_path');
+
+       $img = $iso_path.'/'.$_POST['install_img'];
+
+       $feature = array();
+       for ($i = 0; $i < sizeof($features); $i++)
+               if (array_key_exists('feature_'.$features[$i], $_POST))
+                       $feature[] = $features[$i];
+
+       $nic = array();
+       if ($_POST['setup_nic']) {
+               $nic['mac'] = $_POST['nic_mac'];
+               $nic['type'] = $_POST['nic_type'];
+               $nic['network'] = $_POST['nic_net'];
+       }
+       $disk = array();
+       if ($_POST['setup_disk']) {
+               if ($_POST['new_vm_disk']) {
+                       $disk['image'] = $_POST['name'].'.'.$_POST['disk_driver'];
+                       $disk['size'] = (int)$_POST['img_data'];
+                       $disk['bus'] = $_POST['disk_bus'];
+                       $disk['driver'] = $_POST['disk_driver'];
+               }
+               else {
+                       $disk['image'] = $_POST['img_data'];
+                       $disk['size'] = 0;
+                       $disk['bus'] = $_POST['disk_bus'];
+                       $disk['driver'] = $_POST['disk_driver'];
+               }
+       }
+
+       $tmp = $lv->domain_new($_POST['name'], $img, $_POST['cpu_count'], $feature, $_POST['memory'], $_POST['maxmem'], $_POST['clock_offset'], $nic, $disk);
+       if (!$tmp)
+               $msg = $lv->get_last_error();
+       else {
+               $skip = true;
+               $msg = 'Domain has been created successfully';
+       }
+  }
+
+  $isos = libvirt_get_iso_images();
+
+  $ci  = $lv->get_connect_information();
+  $maxcpu = $ci['hypervisor_maxvcpus'];
+  unset($ci);
+?>
+
+<?php
+    if ($msg):
+?>
+    <div id="msg"><b><?= $lang->get('msg') ?>: </b><?= $msg ?></div>
+<?php
+    endif;
+?>
+
+<?php
+    if (!$skip):
+?>
+<script>
+<!--
+       function change_divs(what, val) {
+               if (val == 1)
+                       style = 'table-row';
+               else
+                       style = 'none';
+
+               for (i = 1; i < 10; i++) {
+                       name = 'setup_'+what+i;
+                       d = document.getElementById(name);
+                       if (d == null)
+                               break;
+                       d.style.display = style;
+               }
+       }
+
+       function vm_disk_change(val) {
+               if (val == 0) {
+                       document.getElementById('vm_disk_existing').style.display = 'inline';
+                       document.getElementById('vm_disk_create').style.display = 'none';
+               } else {
+                       document.getElementById('vm_disk_existing').style.display = 'none';
+                       document.getElementById('vm_disk_create').style.display = 'inline';
+               }
+       }
+-->
+</script>
+
+<div id="content">
+
+<div class="section"><?= $lang->get('create-new-vm') ?></div>
+
+<form method="POST">
+
+<table id="form-table">
+<tr>
+    <td align="right"><?= $lang->get('name') ?>: </td>
+    <td><input type="text" name="name" /></td>
+</tr>
+
+<tr>
+    <td align="right"><?= $lang->get('install-image') ?>: </td>
+    <td>
+               <select name="install_img">
+<?php
+               for ($i = 0; $i < sizeof($isos); $i++)
+                       echo "<option value=\"{$isos[$i]}\">{$isos[$i]}</option>";
+?>
+               </select>
+       </td>
+
+<tr>
+    <td align="right"><?= $lang->get('vcpus') ?>: </td>
+    <td>
+               <select name="cpu_count">
+<?php
+        for ($i = 1; $i <= $maxcpu; $i++)
+            echo '<option value='.$i.'>'.$i.'</option>';
+?>
+               </select>
+</td>
+
+<tr>
+    <td align="right"><?= $lang->get('features') ?>:</td>
+    <td>
+        <input class="checkbox" type="checkbox" value="1" name="feature_apic" checked="checked" /> APIC<br />
+        <input class="checkbox" type="checkbox" value="1" name="feature_acpi" checked="checked" /> ACPI<br />
+        <input class="checkbox" type="checkbox" value="1" name="feature_pae" checked="checked" /> PAE<br />
+        <input class="checkbox" type="checkbox" value="1" name="feature_hap" /> HAP
+    </td>
+</tr>
+
+<tr>
+    <td align="right"><?= $lang->get('mem') ?> (MiB):</td>
+    <td><input type="text" name="memory" value="512" /></td>
+</tr>
+
+<tr>
+    <td align="right"><?= $lang->get('mem_alloc_max') ?> (MiB):</td>
+    <td><input type="text" name="maxmem" value="512" /></td>
+</tr>
+
+<tr>
+    <td align="right"><?= $lang->get('clock-offset') ?>:</td>
+    <td>
+        <select name="clock_offset">
+          <option value="utc">UTC</option>
+          <option value="localtime">localtime</option>
+        </select>
+    </td>
+</tr>
+
+<tr>
+    <td align="right"><?= $lang->get('setup').' '.$lang->get('nic') ?>:</td>
+    <td>
+      <select name="setup_nic" onchange="change_divs('network', this.value)">
+       <option value="0"><?= $lang->get('No') ?></option>
+       <option value="1"><?= $lang->get('Yes') ?></option>
+      </select>
+    </td>
+</tr>
+
+<tr id="setup_network1" style="display: none">
+    <td align="right"><?= $lang->get('vm_network_mac') ?>:</td>
+    <td><input type="text" name="nic_mac" value="<?= $lv->generate_random_mac_addr() ?>"/></td>
+</tr>
+
+<tr id="setup_network2" style="display: none">
+    <td align="right"><?= $lang->get('vm_network_type') ?>:</td>
+    <td>
+                      <select name="nic_type">';
+
+<?php
+       $models = $lv->get_nic_models();
+        for ($i = 0; $i < sizeof($models); $i++)
+                echo '<option value="'.$models[$i].'">'.$models[$i].'</option>';
+?>
+                      </select>
+    </td>
+</tr>
+
+<tr id="setup_network3" style="display: none">
+    <td align="right"><?= $lang->get('vm_network_net') ?>:</td>
+    <td>
+                      <select name="nic_net">';
+
+<?php
+        $nets = $lv->get_networks();
+        for ($i = 0; $i < sizeof($nets); $i++)
+                echo '<option value="'.$nets[$i].'">'.$nets[$i].'</option>';
+?>
+                      </select>
+    </td>
+</tr>
+
+<tr>
+    <td align="right"><?= $lang->get('setup').' '.$lang->get('disk') ?>:</td>
+    <td>
+      <select name="setup_disk" onchange="change_divs('disk', this.value)">
+        <option value="0"><?= $lang->get('No') ?></option>
+        <option value="1"><?= $lang->get('Yes') ?></option>
+      </select>
+    </td>
+</tr>
+
+<tr id="setup_disk1" style="display: none">
+        <td align="right"><?= $lang->get('new-vm-disk')?>: </td>
+        <td>
+               <select name="new_vm_disk" onchange="vm_disk_change(this.value)">
+                       <option value="0"><?= $lang->get('new-vm-existing') ?></option>
+                       <option value="1"><?= $lang->get('new-vm-create') ?></option>
+               </select>
+       </td>
+</tr>
+
+<tr id="setup_disk2" style="display: none">
+       <td align="right">
+               <span id="vm_disk_existing">
+               <?= $lang->get('vm_disk_image')?>:
+               </span>
+               <span id="vm_disk_create" style="display: none">
+               <?= $lang->get('vm-disk-size') ?> (MiB): 
+               </span>
+       </td>
+       <td><input type="text" name="img_data" /></td>
+</tr>
+
+<tr id="setup_disk3" style="display: none">
+       <td align="right"><?= $lang->get('vm_disk_location') ?>: </td>
+       <td>
+               <select name="disk_bus">
+                       <option value="ide">IDE Bus</option>
+                       <option value="scsi">SCSI Bus</option>
+               </select>
+       </td>
+</tr>
+<tr id="setup_disk4" style="display: none">
+       <td align="right"><?= $lang->get('vm_disk_type') ?>: </td>
+       <td>
+               <select name="disk_driver">
+                       <option value="raw">raw</option>
+                       <option value="qcow">qcow</option>
+                       <option value="qcow2">qcow2</option>
+               </select>
+       </td>
+</tr>
+<tr id="setup_disk5" style="display: none">
+       <td align="right"><?= $lang->get('vm_disk_dev') ?>: </td>
+       <td>hda</td>
+</tr>
+
+</div>
+
+<tr align="center">
+    <td colspan="2">
+    <input type="submit" value=" <?= $lang->get('create-vm') ?> " />
+    </td>
+</tr>
+
+<input type="hidden" name="sent" value="1" />
+</form>
+
+<?php
+  else:
+?>
+  <br /><a href="?name=<?= $_POST['name'] ?>"><?= $lang->get('vm_details') ?></a>
+<?php
+  endif;
+?>
+
+</div>