Fix: Change Libvirt::node_get_cpu_stats() output
[php-virt-control.git] / classes / libvirt.php
1 <?php
2         class Libvirt {
3                 private $conn;
4                 private $last_error;
5                 private $allow_cached = true;
6                 private $dominfos = array();
7                 private $lang_str;
8                 private $enabled = false;
9
10                 function Libvirt($uri = false, $login = false, $pwd = false, $debug=false, $lang=false) {
11                         if ($debug)
12                                 $this->set_logfile($debug);
13                         if ($uri != false) {
14                                 $this->enabled = true;
15                                 $this->connect($uri, $login, $pwd);
16                         }
17                         $this->lang_str = $lang;
18                 }
19
20                 function _set_last_error()
21                 {
22                         $this->last_error = libvirt_get_last_error();
23                         return false;
24                 }
25
26                 function enabled() {
27                         return $this->enabled;
28                 }
29
30                 function set_logfile($filename)
31                 {
32                         if (!libvirt_logfile_set($filename))
33                                 return $this->_set_last_error();
34
35                         return true;
36                 }
37
38                 function get_capabilities() {
39                         $tmp = libvirt_connect_get_capabilities($this->conn);
40                         return ($tmp) ? $tmp : $this->_set_last_error();
41                 }
42
43                 function get_default_emulator() {
44                         $tmp = libvirt_connect_get_capabilities($this->conn, '//capabilities/guest/arch/domain/emulator');
45                         return ($tmp) ? $tmp : $this->_set_last_error();
46                 }
47
48                 function domain_new($name, $img, $vcpus, $features, $mem, $maxmem, $clock, $nic, $disk, $persistent=true) {
49                         $uuid = $this->domain_generate_uuid();
50                         $emulator = $this->get_default_emulator();
51
52                         $mem *= 1024;
53                         $maxmem *= 1024;
54
55                         $fs = '';
56                         for ($i = 0; $i < sizeof($features); $i++) {
57                                 $fs .= '<'.$features[$i].' />';
58                         }
59
60                         $diskstr = '';
61                         if (!empty($disk)) {
62                                 if ($disk['size']) {
63                                         $disk['image'] = str_replace(' ', '_', $disk['image']);
64                                         if (!$this->create_image($disk['image'], $disk['size'], $disk['driver']))
65                                                 return false;
66                                 }
67
68                                 if ($disk['image'][0] != '/')
69                                         $path = ini_get('libvirt.image_path').'/'.$disk['image'];
70                                 else
71                                         $path = $disk['image'];
72
73                                 $diskstr = "<disk type='file' device='disk'>
74                                                 <driver name='qemu' type='{$disk['driver']}' />
75                                                 <source file='$path'/>
76                                                 <target bus='{$disk['bus']}' dev='hda' />
77                                          </disk>";
78                         }
79                         $netstr = '';
80                         if (!empty($nic)) {
81                                 $model = '';
82                                 if ($nic['type'] != 'default')
83                                         $model = "<model type='{$nic['type']}'/>";
84                                 $netstr = "
85                                             <interface type='network'>
86                                               <mac address='{$nic['mac']}'/>
87                                               <source network='{$nic['network']}'/>
88                                               $model
89                                             </interface>";
90                         }
91
92                         $xml = "<domain type='kvm'>
93                                 <name>$name</name>
94                                 <currentMemory>$mem</currentMemory>
95                                 <memory>$maxmem</memory>
96                                 <uuid>$uuid</uuid>
97                                 <os>
98                                         <type arch='i686'>hvm</type>
99                                         <boot dev='cdrom'/>
100                                         <boot dev='hd'/>
101                                 </os>
102                                 <features>
103                                 $fs
104                                 </features>
105                                 <clock offset=\"$clock\"/>
106                                 <on_poweroff>destroy</on_poweroff>
107                                 <on_reboot>destroy</on_reboot>
108                                 <on_crash>destroy</on_crash>
109                                 <vcpu>$vcpus</vcpu>
110                                 <devices>
111                                         <emulator>$emulator</emulator>
112                                         $diskstr
113                                         <disk type='file' device='cdrom'>
114                                                 <driver name='qemu'/>
115                                                 <source file='$img'/>
116                                                 <target dev='hdc' bus='ide'/>
117                                                 <readonly/>
118                                         </disk>
119                                         $netstr
120                                         <input type='mouse' bus='ps2'/>
121                                         <graphics type='vnc' port='-1'/>
122                                         <console type='pty'/>
123                                         <sound model='ac97'/>
124                                         <video>
125                                                 <model type='cirrus'/>
126                                         </video>
127                                 </devices>
128                                 </domain>";
129
130                         $tmp = libvirt_domain_create_xml($this->conn, $xml);
131                         if (!$tmp)
132                                 return $this->_set_last_error();
133
134                         if ($persistent) {
135                                 $xml = "<domain type='kvm'>
136                                         <name>$name</name>
137                                         <currentMemory>$mem</currentMemory>
138                                         <memory>$maxmem</memory>
139                                         <uuid>$uuid</uuid>
140                                         <os>
141                                                 <type arch='i686'>hvm</type>
142                                                 <boot dev='hd'/>
143                                         </os>
144                                         <features>
145                                         $fs
146                                         </features>
147                                         <clock offset=\"$clock\"/>
148                                         <on_poweroff>destroy</on_poweroff>
149                                         <on_reboot>destroy</on_reboot>
150                                         <on_crash>destroy</on_crash>
151                                         <vcpu>$vcpus</vcpu>
152                                         <devices>
153                                                 <emulator>$emulator</emulator>
154                                                 $diskstr
155                                                 $netstr
156                                                 <input type='mouse' bus='ps2'/>
157                                                 <graphics type='vnc' port='-1'/>
158                                                 <console type='pty'/>
159                                                 <sound model='ac97'/>
160                                                 <video>
161                                                         <model type='cirrus'/>
162                                                 </video>
163                                         </devices>
164                                         </domain>";
165                                 
166                                 $tmp = libvirt_domain_define_xml($this->conn, $xml);
167                                 return ($tmp) ? $tmp : $this->_set_last_error();
168                         }
169                         else
170                                 return $tmp;
171                 }
172
173                 function create_image($image, $size, $driver) {
174                         $tmp = libvirt_image_create($this->conn, $image, $size, $driver);
175                         return ($tmp) ? $tmp : $this->_set_last_error();
176                 }
177
178                 function remove_image($image, $ignore_error_codes=false ) {
179                         $tmp = libvirt_image_remove($this->conn, $image);
180                         if ((!$tmp) && ($ignore_error_codes)) {
181                                 $err = libvirt_get_last_error();
182                                 $comps = explode(':', $err);
183                                 $err = explode('(', $comps[sizeof($comps)-1]);
184                                 $code = (int)Trim($err[0]);
185
186                                 if (in_array($code, $ignore_error_codes))
187                                         return true;
188                         }
189
190                         return ($tmp) ? $tmp : $this->_set_last_error();
191                 }
192
193                 function migrate_to_uri($domain, $uri, $live = false, $bandwidth = 100) {
194                         $dom = $this->get_domain_object($domain);
195                         if (!$dom)
196                                 return false;
197
198                         $name = $this->domain_get_name($dom);
199                         $tmp = libvirt_domain_migrate_to_uri($dom, $uri, $live ? VIR_MIGRATE_LIVE : 0, $name, $bandwidth);
200                         return ($tmp) ? $tmp : $this->_set_last_error();
201                 }
202
203                 function migrate($domain, $conn, $live = false, $bandwidth = 100) {
204                         $dom = $this->get_domain_object($domain);
205                         if (!$dom)
206                                 return false;
207
208                         $name = $this->domain_get_name($dom);
209                         $tmp = libvirt_domain_migrate($dom, $conn, $live ? VIR_MIGRATE_LIVE : 0, $name, $bandwidth);
210                         return ($tmp) ? $tmp : $this->_set_last_error();
211                 }
212
213                 function generate_connection_uri($hv, $remote, $remote_method, $remote_username, $remote_hostname, $session=false) {
214                         if ($hv == 'qemu') {
215                                 if ($session)
216                                         $append_type = 'session';
217                                 else
218                                         $append_type = 'system';
219                         }
220
221                         if (!$remote) {
222                                 if ($hv == 'xen')
223                                         return 'xen:///';
224                                 if ($hv == 'qemu')
225                                         return 'qemu:///'.$append_type;
226
227                                 return false;
228                         }
229
230                         if ($hv == 'xen')
231                                 return 'xen+'.$remote_method.'://'.$remote_username.'@'.$remote_hostname;
232                         else
233                         if ($hv == 'qemu')
234                                 return 'qemu+'.$remote_method.'://'.$remote_username.'@'.$remote_hostname.'/'.$append_type;
235                 }
236
237                 function test_connection_uri($hv, $rh, $rm, $un, $pwd, $hn, $session=false) {
238                         $uri = $this->generate_connection_uri($hv, $rh, $rm, $un, $hn, $session);
239                         if (strlen($pwd) > 0) {
240                                 $credentials = array(VIR_CRED_AUTHNAME => $un, VIR_CRED_PASSPHRASE => $pwd);
241                                 $test = libvirt_connect($uri, false, $credentials);
242                         }
243                         else
244                                 $test = libvirt_connect($uri);
245                         $ok = is_resource($test);
246                         unset($test);
247
248                         if (!$ok)
249                                 $this->_set_last_error();
250
251                         return $ok;
252                 }
253
254                 function print_resources() {
255                         return libvirt_print_binding_resources();
256                 }
257
258                 function connect($uri = 'null', $login = false, $password = false) {
259                         if ($login !== false && $password !== false) {
260                                 $this->conn=libvirt_connect($uri, false, array(VIR_CRED_AUTHNAME => $login, VIR_CRED_PASSPHRASE => $password));
261                         } else {
262                                 $this->conn=libvirt_connect($uri, false);
263                         }
264                         if ($this->conn==false)
265                                 return $this->_set_last_error();
266                 }
267
268                 function domain_disk_add($domain, $img, $dev, $type='scsi', $driver='raw') {
269                         $dom = $this->get_domain_object($domain);
270
271                         $tmp = libvirt_domain_disk_add($dom, $img, $dev, $type, $driver);
272                         return ($tmp) ? $tmp : $this->_set_last_error();
273                 }
274
275                 function domain_change_numVCpus($domain, $num) {
276                         $dom = $this->get_domain_object($domain);
277
278                         $tmp = libvirt_domain_change_vcpus($dom, $num);
279                         return ($tmp) ? $tmp : $this->_set_last_error();
280                 }
281
282                 function domain_change_memory_allocation($domain, $memory, $maxmem) {
283                         $dom = $this->get_domain_object($domain);
284
285                         $tmp = libvirt_domain_change_memory($dom, $memory, $maxmem);
286                         return ($tmp) ? $tmp : $this->_set_last_error();
287                 }
288
289                 function domain_change_boot_devices($domain, $first, $second) {
290                         $dom = $this->get_domain_object($domain);
291
292                         $tmp = libvirt_domain_change_boot_devices($dom, $first, $second);
293                         return ($tmp) ? $tmp : $this->_set_last_error();
294                 }
295
296                 function domain_get_screenshot($domain) {
297                         $dom = $this->get_domain_object($domain);
298
299                         $tmp = libvirt_domain_get_screenshot($dom, $this->get_hostname(), 8 );
300                         if (Graphics::isBMPStream($tmp)) {
301                                 $gc = new Graphics();
302                                 $fn = tempnam("/tmp", "php-virt-control.tmp");
303                                 $fn2 = tempnam("/tmp", "php-virt-control.tmp");
304
305                                 $fp = fopen($fn, "wb");
306                                 fputs($fp, $tmp);
307                                 fclose($fp);
308
309                                 unset($tmp);
310                                 if ($gc->ConvertBMPToPNG($fn, $fn2) == false) {
311                                         unlink($fn);
312                                         return false;
313                                 }
314
315                                 $fp = fopen($fn2, "rb");
316                                 $tmp = fread($fp, filesize($fn2));
317                                 fclose($fp);
318
319                                 unlink($fn2);
320                                 unlink($fn);
321                                 unset($gc);
322                         }
323                         return ($tmp) ? $tmp : $this->_set_last_error();
324                 }
325
326                 function domain_get_screenshot_thumbnail($domain, $w=120) {
327                         $screen = $this->domain_get_screenshot($domain);
328                         $imgFile = tempnam("/tmp", "libvirt-php-tmp-resize-XXXXXX");;
329
330                         if ($screen) {
331                                 $fp = fopen($imgFile, "wb");
332                                 fwrite($fp, $screen);
333                                 fclose($fp);
334                         }
335
336                         if (file_exists($imgFile) && $screen) {
337                                 list($width, $height) = getimagesize($imgFile); 
338                                 $h = ($height / $width) * $w;
339                         } else {
340                                 $w = $h = 1;
341                                 //$h = $w * (3 / 4.5);
342                         }
343
344                         $new = imagecreatetruecolor($w, $h);
345                         if ($screen) {
346                                 $img = imagecreatefrompng($imgFile);
347                                 imagecopyresampled($new,$img,0,0,0,0, $w,$h,$width,$height);
348                                 imagedestroy($img);
349                         }
350                         else {
351                                 $c = imagecolorallocate($new, 255, 255, 255);
352                                 imagefill($new, 0, 0, $c);
353                         }
354
355                         imagepng($new, $imgFile);
356                         imagedestroy($new);
357
358                         $fp = fopen($imgFile, "rb");
359                         $data = fread($fp, filesize($imgFile));
360                         fclose($fp);
361
362                         unlink($imgFile);
363                         return $data;
364                 }
365
366                 function domain_get_screen_dimensions($domain) {
367                         $dom = $this->get_domain_object($domain);
368
369                         $tmp = libvirt_domain_get_screen_dimensions($dom, $this->get_hostname() );
370                         return ($tmp) ? $tmp : $this->_set_last_error();
371                 }
372
373                 function domain_send_keys($domain, $keys) {
374                         $dom = $this->get_domain_object($domain);
375
376                         $tmp = libvirt_domain_send_keys($dom, $this->get_hostname(), $keys);
377                         return ($tmp) ? $tmp : $this->_set_last_error();
378                 }
379
380                 function domain_send_pointer_event($domain, $x, $y, $clicked = 1, $release = false) {
381                         $dom = $this->get_domain_object($domain);
382
383                         $tmp = libvirt_domain_send_pointer_event($dom, $this->get_hostname(), $x, $y, $clicked, $release);
384                         return ($tmp) ? $tmp : $this->_set_last_error();
385                 }
386
387                 function domain_disk_remove($domain, $dev) {
388                         $dom = $this->get_domain_object($domain);
389
390                         $tmp = libvirt_domain_disk_remove($dom, $dev);
391                         return ($tmp) ? $tmp : $this->_set_last_error();
392                 }
393
394                 function supports($name) {
395                         return libvirt_has_feature($name);
396                 }
397
398                 function macbyte($val) {
399                         if ($val < 16)
400                                 return '0'.dechex($val);
401
402                         return dechex($val);
403                 }
404
405                 function generate_random_mac_addr($seed=false) {
406                         if (!$seed)
407                                 $seed = 1;
408
409                         if ($this->get_hypervisor_name() == 'qemu')
410                                 $prefix = '52:54:00';
411                         else
412                         if ($this->get_hypervisor_name() == 'xen')
413                                 $prefix = '00:16:3e';
414                         else
415                                 $prefix = $this->macbyte(($seed * rand()) % 256).':'.
416                                 $this->macbyte(($seed * rand()) % 256).':'.
417                                 $this->macbyte(($seed * rand()) % 256);
418
419                         return $prefix.':'.
420                                 $this->macbyte(($seed * rand()) % 256).':'.
421                                 $this->macbyte(($seed * rand()) % 256).':'.
422                                 $this->macbyte(($seed * rand()) % 256);
423                 }
424
425                 function domain_nic_add($domain, $mac, $network, $model=false) {
426                         $dom = $this->get_domain_object($domain);
427
428                         if ($model == 'default')
429                                 $model = false;
430
431                         $tmp = libvirt_domain_nic_add($dom, $mac, $network, $model);
432                         return ($tmp) ? $tmp : $this->_set_last_error();
433                 }
434
435                 function domain_nic_remove($domain, $mac) {
436                         $dom = $this->get_domain_object($domain);
437
438                         $tmp = libvirt_domain_nic_remove($dom, $mac);
439                         return ($tmp) ? $tmp : $this->_set_last_error();
440                 }
441
442                 function get_connection() {
443                         return $this->conn;
444                 }
445
446                 function get_hostname() {
447                         return libvirt_connect_get_hostname($this->conn);
448                 }
449
450                 function get_domain_object($nameRes) {
451                         if (is_resource($nameRes))
452                                 return $nameRes;
453
454                         $dom=libvirt_domain_lookup_by_name($this->conn, $nameRes);
455                         if (!$dom) {
456                                 $dom=libvirt_domain_lookup_by_uuid_string($this->conn, $nameRes);
457                                 if (!$dom)
458                                         return $this->_set_last_error();
459                         }
460
461                         return $dom;
462                 }
463
464                 function get_xpath($domain, $xpath, $inactive = false) {
465                         $dom = $this->get_domain_object($domain);
466                         $flags = 0;
467                         if ($inactive)
468                                 $flags = VIR_DOMAIN_XML_INACTIVE;
469
470                         $tmp = libvirt_domain_xml_xpath($dom, $xpath, $flags); 
471                         if (!$tmp)
472                                 return $this->_set_last_error();
473
474                         return $tmp;
475                 }
476
477                 function get_cdrom_stats($domain, $sort=true) {
478                         $dom = $this->get_domain_object($domain);
479
480                         $buses =  $this->get_xpath($dom, '//domain/devices/disk[@device="cdrom"]/target/@bus', false);
481                         $disks =  $this->get_xpath($dom, '//domain/devices/disk[@device="cdrom"]/target/@dev', false);
482                         $files =  $this->get_xpath($dom, '//domain/devices/disk[@device="cdrom"]/source/@file', false);
483
484                         $ret = array();
485                         for ($i = 0; $i < $disks['num']; $i++) {
486                                 $tmp = libvirt_domain_get_block_info($dom, $disks[$i]);
487                                 if ($tmp) {
488                                         $tmp['bus'] = $buses[$i];
489                                         $ret[] = $tmp;
490                                 }
491                                 else {
492                                         $this->_set_last_error();
493
494                                         $ret[] = array(
495                                                         'device' => $disks[$i],
496                                                         'file'   => $files[$i],
497                                                         'type'   => '-',
498                                                         'capacity' => '-',
499                                                         'allocation' => '-',
500                                                         'physical' => '-',
501                                                         'bus' => $buses[$i]
502                                                         );
503                                 }
504                         }
505
506                         if ($sort) {
507                                 for ($i = 0; $i < sizeof($ret); $i++) {
508                                         for ($ii = 0; $ii < sizeof($ret); $ii++) {
509                                                 if (strcmp($ret[$i]['device'], $ret[$ii]['device']) < 0) {
510                                                         $tmp = $ret[$i];
511                                                         $ret[$i] = $ret[$ii];
512                                                         $ret[$ii] = $tmp;
513                                                 }
514                                         }
515                                 }
516                         }
517
518                         unset($buses);
519                         unset($disks);
520                         unset($files);
521
522                         return $ret;
523                 }
524
525                 function get_disk_stats($domain, $sort=true) {
526                         $dom = $this->get_domain_object($domain);
527
528                         $buses =  $this->get_xpath($dom, '//domain/devices/disk[@device="disk"]/target/@bus', false);
529                         $disks =  $this->get_xpath($dom, '//domain/devices/disk[@device="disk"]/target/@dev', false);
530                         $files =  $this->get_xpath($dom, '//domain/devices/disk[@device="disk"]/source/@file', false);
531
532                         $ret = array();
533                         for ($i = 0; $i < $disks['num']; $i++) {
534                                 $tmp = libvirt_domain_get_block_info($dom, $disks[$i]);
535                                 if ($tmp) {
536                                         $tmp['bus'] = $buses[$i];
537                                         $ret[] = $tmp;
538                                 }
539                                 else {
540                                         $this->_set_last_error();
541
542                                         $ret[] = array(
543                                                         'device' => $disks[$i],
544                                                         'file'   => $files[$i],
545                                                         'type'   => '-',
546                                                         'capacity' => '-',
547                                                         'allocation' => '-',
548                                                         'physical' => '-',
549                                                         'bus' => $buses[$i]
550                                                         );
551                                 }
552                         }
553
554                         if ($sort) {
555                                 for ($i = 0; $i < sizeof($ret); $i++) {
556                                         for ($ii = 0; $ii < sizeof($ret); $ii++) {
557                                                 if (strcmp($ret[$i]['device'], $ret[$ii]['device']) < 0) {
558                                                         $tmp = $ret[$i];
559                                                         $ret[$i] = $ret[$ii];
560                                                         $ret[$ii] = $tmp;
561                                                 }
562                                         }
563                                 }
564                         }
565
566                         unset($buses);
567                         unset($disks);
568                         unset($files);
569
570                         return $ret;
571                 }
572
573                 function get_nic_info($domain) {
574                         $dom = $this->get_domain_object($domain);
575
576                         $macs =  $this->get_xpath($dom, '//domain/devices/interface/mac/@address', false);
577                         if (!$macs)
578                                 return $this->_set_last_error();
579
580                         $ret = array();
581                         for ($i = 0; $i < $macs['num']; $i++) {
582                                 $tmp = libvirt_domain_get_network_info($dom, $macs[$i]);
583                                 if ($tmp)
584                                         $ret[] = $tmp;
585                                 else {
586                                         $this->_set_last_error();
587
588                                         $ret[] = array(
589                                                         'mac' => $macs[$i],
590                                                         'network' => '-',
591                                                         'nic_type' => '-'
592                                                         );
593                                 }
594                         }
595
596                         return $ret;
597                 }
598
599                 function get_domain_type($domain) {
600                         $dom = $this->get_domain_object($domain);
601
602                         $tmp = $this->get_xpath($dom, '//domain/@type', false);
603                         if ($tmp['num'] == 0)
604                             return $this->_set_last_error();
605
606                         $ret = $tmp[0];
607                         unset($tmp);
608
609                         return $ret;
610                 }
611
612                 function get_domain_emulator($domain) {
613                         $dom = $this->get_domain_object($domain);
614
615                         $tmp =  $this->get_xpath($dom, '//domain/devices/emulator', false);
616                         if ($tmp['num'] == 0)
617                             return $this->_set_last_error();
618
619                         $ret = $tmp[0];
620                         unset($tmp);
621
622                         return $ret;
623                 }
624
625                 function get_network_cards($domain) {
626                         $dom = $this->get_domain_object($domain);
627
628                         $nics =  $this->get_xpath($dom, '//domain/devices/interface[@type="network"]', false);
629                         if (!is_array($nics))
630                                 return $this->_set_last_error();
631
632                         return $nics['num'];
633                 }
634
635                 function get_disk_capacity($domain, $physical=false, $disk='*', $unit='?') {
636                         $dom = $this->get_domain_object($domain);
637                         $tmp = $this->get_disk_stats($dom);
638
639                         $ret = 0;
640                         for ($i = 0; $i < sizeof($tmp); $i++) {
641                                 if (($disk == '*') || ($tmp[$i]['device'] == $disk))
642                                         if ($physical)
643                                                 $ret += $tmp[$i]['physical'];
644                                         else
645                                                 $ret += $tmp[$i]['capacity'];
646                         }
647                         unset($tmp);
648
649                         return $this->format_size($ret, 2, $unit);
650                 }
651
652                 function get_disk_count($domain) {
653                         $dom = $this->get_domain_object($domain);
654                         $tmp = $this->get_disk_stats($dom);
655                         $ret = sizeof($tmp);
656                         unset($tmp);
657
658                         return $ret;
659                 }
660
661                 function format_size($value, $decimals, $unit='?') {
662                         if ($value == '-')
663                                 return 'unknown';
664
665                         /* Autodetect unit that's appropriate */
666                         if ($unit == '?') {
667                                 /* (1 << 40) is not working correctly on i386 systems */
668                                 if ($value > 1099511627776)
669                                         $unit = 'T';
670                                 else
671                                 if ($value > (1 << 30))
672                                         $unit = 'G';
673                                 else
674                                 if ($value > (1 << 20))
675                                         $unit = 'M';
676                                 else
677                                 if ($value > (1 << 10))
678                                         $unit = 'K';
679                                 else
680                                         $unit = 'B';
681                         }
682
683                         $unit = strtoupper($unit);
684
685                         switch ($unit) {
686                                 case 'T': return number_format($value / (float)1099511627776, $decimals, '.', ' ').' TB';
687                                 case 'G': return number_format($value / (float)(1 << 30), $decimals, '.', ' ').' GB';
688                                 case 'M': return number_format($value / (float)(1 << 20), $decimals, '.', ' ').' MB';
689                                 case 'K': return number_format($value / (float)(1 << 10), $decimals, '.', ' ').' kB';
690                                 case 'B': return $value.' B';
691                         }
692
693                         return false;
694                 }
695
696                 function get_uri() {
697                         $tmp = libvirt_connect_get_uri($this->conn);
698                         return ($tmp) ? $tmp : $this->_set_last_error();
699                 }
700
701                 function get_domain_count() {
702                         $tmp = libvirt_domain_get_counts($this->conn);
703                         return ($tmp) ? $tmp : $this->_set_last_error();
704                 }
705
706                 function get_storagepools() {
707                         $tmp = libvirt_list_storagepools($this->conn);
708                         return ($tmp) ? $tmp : $this->_set_last_error();
709                 }
710
711                 function get_storagepool_res($res) {
712                         if ($res == false)
713                                 return false;
714                         if (is_resource($res))
715                                 return $res;
716
717                         $tmp = libvirt_storagepool_lookup_by_name($this->conn, $res);
718                         return ($tmp) ? $tmp : $this->_set_last_error();
719                 }
720
721                 function get_storagepool_info($name) {
722                         if (!($res = $this->get_storagepool_res($name)))
723                                 return false;
724
725                         $path = libvirt_storagepool_get_xml_desc($res, '/pool/target/path');
726                         if (!$path)
727                                 return $this->_set_last_error();
728                         $perms = libvirt_storagepool_get_xml_desc($res, '/pool/target/permissions/mode');
729                         if (!$perms)
730                                 return $this->_set_last_error();
731                         $otmp1 = libvirt_storagepool_get_xml_desc($res, '/pool/target/permissions/owner');
732                         if (!is_string($otmp1))
733                                 return $this->_set_last_error();
734                         $otmp2 = libvirt_storagepool_get_xml_desc($res, '/pool/target/permissions/group');
735                         if (!is_string($otmp2))
736                                 return $this->_set_last_error();
737                         $tmp = libvirt_storagepool_get_info($res);
738                         $tmp['volume_count'] = sizeof( libvirt_storagepool_list_volumes($res) );
739                         $tmp['active'] = libvirt_storagepool_is_active($res);
740                         $tmp['path'] = $path;
741                         $tmp['permissions'] = $perms;
742                         $tmp['id_user'] = $otmp1;
743                         $tmp['id_group'] = $otmp2;
744
745                         return $tmp;
746                 }
747
748                 function storagepool_get_volume_information($pool, $name=false) {
749                         if (!is_resource($pool))
750                                 $pool = $this->get_storagepool_res($pool);
751                         if (!$pool)
752                                 return false;
753
754                         $out = array();
755                         $tmp = libvirt_storagepool_list_volumes($pool);
756                         for ($i = 0; $i < sizeof($tmp); $i++) {
757                                 if (($tmp[$i] == $name) || ($name == false)) {
758                                         $r = libvirt_storagevolume_lookup_by_name($pool, $tmp[$i]);
759                                         $out[$tmp[$i]] = libvirt_storagevolume_get_info($r);
760                                         $out[$tmp[$i]]['path'] = libvirt_storagevolume_get_path($r);
761                                         unset($r);
762                                 }
763                         }
764
765                         return $out;
766                 }
767
768                 function storagevolume_delete($path) {
769                         $vol = libvirt_storagevolume_lookup_by_path($this->conn, $path);
770                         if (!libvirt_storagevolume_delete($vol))
771                                 return $this->_set_last_error();
772
773                         return true;
774                 }
775
776                 function translate_volume_type($type) {
777                         if ($type == 1)
778                                 return 'Block device';
779
780                         return 'File image';
781                 }
782
783                 function translate_perms($mode) {
784                         $mode = (string)((int)$mode);
785
786                         $tmp = '---------';
787
788                         for ($i = 0; $i < 3; $i++) {
789                                 $bits = (int)$mode[$i];
790                                 if ($bits & 4)
791                                         $tmp[ ($i * 3) ] = 'r';
792                                 if ($bits & 2)
793                                         $tmp[ ($i * 3) + 1 ] = 'w';
794                                 if ($bits & 1)
795                                         $tmp[ ($i * 3) + 2 ] = 'x';
796                         }
797                         
798
799                         return $tmp;
800                 }
801
802                 function parse_size($size) {
803                         $unit = $size[ strlen($size) - 1 ];
804
805                         $size = (int)$size;
806                         switch (strtoupper($unit)) {
807                                 case 'T': $size *= 1099511627776;
808                                           break;
809                                 case 'G': $size *= 1073741824;
810                                           break;
811                                 case 'M': $size *= 1048576;
812                                           break;
813                                 case 'K': $size *= 1024;
814                                           break;
815                         }
816
817                         return $size;
818                 }
819
820                 function storagevolume_create($pool, $name, $capacity, $allocation) {
821                         $pool = $this->get_storagepool_res($pool);
822
823                         $capacity = $this->parse_size($capacity);
824                         $allocation = $this->parse_size($allocation);
825
826                         $xml = "<volume>\n".
827                                "  <name>$name</name>\n".
828                                "  <capacity>$capacity</capacity>\n".
829                                "  <allocation>$allocation</allocation>\n".
830                                "</volume>";
831
832                         $tmp = libvirt_storagevolume_create_xml($pool, $xml);
833                         return ($tmp) ? $tmp : $this->_set_last_error();
834                 }
835
836                 function get_hypervisor_name() {
837                         $tmp = libvirt_connect_get_information($this->conn);
838                         $hv = $tmp['hypervisor'];
839                         unset($tmp);
840
841                         switch (strtoupper($hv)) {
842                                 case 'QEMU': $type = 'qemu';
843                                         break;
844                                 case 'XEN': $type = 'xen';
845                                         break;
846
847                                 default:
848                                         $type = $hv;
849                         }
850
851                         return $type;
852                 }
853
854                 function get_connect_information() {
855                         $tmp = libvirt_connect_get_information($this->conn);
856                         return ($tmp) ? $tmp : $this->_set_last_error();
857                 }
858
859                 function domain_change_xml($domain, $xml) {
860                         $dom = $this->get_domain_object($domain);
861
862                         if (!($old_xml = libvirt_domain_get_xml_desc($dom, NULL)))
863                                 return $this->_set_last_error();
864                         if (!libvirt_domain_undefine($dom))
865                                 return $this->_set_last_error();
866                         if (!libvirt_domain_define_xml($this->conn, $xml)) {
867                                 $this->last_error = libvirt_get_last_error();
868                                 libvirt_domain_define_xml($this->conn, $old_xml);
869                                 return false;
870                         }
871
872                         return true;
873                 }
874
875                 function network_change_xml($network, $xml) {
876                         $net = $this->get_network_res($network);
877
878                         if (!($old_xml = libvirt_network_get_xml_desc($net, NULL))) {
879                                 return $this->_set_last_error();
880                         }
881                         if (!libvirt_network_undefine($net)) {
882                                 return $this->_set_last_error();
883                         }
884                         if (!libvirt_network_define_xml($this->conn, $xml)) {
885                                 $this->last_error = libvirt_get_last_error();
886                                 libvirt_network_define_xml($this->conn, $old_xml);
887                                 return false;
888                         }
889
890                         return true;
891                 }
892
893                 function network_new($name, $ipinfo, $dhcpinfo=false, $forward=false, $forward_dev=false, $bridge=false) {
894                         $uuid = $this->network_generate_uuid();
895                         if (!$bridge) {
896                                 $maxid = -1;
897                                 $nets = $this->get_networks();
898                                 for ($i = 0; $i < sizeof($nets); $i++) {
899                                         $bridge = $this->get_network_bridge($nets[$i]);
900                                         if ($bridge) {
901                                                 $tmp = explode('br', $bridge);
902                                                 $id = (int)$tmp[1];
903
904                                                 if ($id > $maxid)
905                                                         $maxid = $id;
906                                         }
907                                 }
908
909                                 $newid = $maxid + 1;
910                                 $bridge = 'virbr'.$newid;
911                         }
912
913                         $forwards = '';
914                         if ($forward) {
915                                 if (!$forward_dev)
916                                         $forwards = "<forward mode='$forward' />";
917                                 else
918                                         $forwards = "<forward mode='$forward' dev='$forward_dev' />";
919                         }
920
921                         /* array('ip' => $ip, 'netmask' => $mask) has been passed */
922                         if (is_array($ipinfo)) {
923                                 $ip = $ipinfo['ip'];
924                                 $mask = $ipinfo['netmask'];
925                         }
926                         else {
927                                 /* CIDR definition otherwise, like 192.168.122.0/24 */
928                                 $tmp = explode('/', $ipinfo);
929                                 $ipc = explode('.', $tmp[0]);
930                                 $ipc[3] = (int)$ipc[3] + 1;
931                                 $ip = implode('.', $ipc);
932
933                                 $bin = '';
934                                 for ($i = 0; $i < $tmp[1]; $i++)
935                                         $bin .= '1';
936
937                                 $tmp = bindec($bin);
938                                 $ipc[0] = $tmp         % 256;
939                                 $ipc[1] = ($tmp >> 8 ) % 256;
940                                 $ipc[2] = ($tmp >> 16) % 256;
941                                 $ipc[3] = ($tmp >> 24) % 256;
942
943                                 $mask = implode('.', $ipc);
944                         }
945
946                         $dhcps = '';
947                         if ($dhcpinfo) {
948                                 /* For definition like array('start' => $dhcp_start, 'end' => $dhcp_end) */
949                                 if (is_array($dhcpinfo)) {
950                                         $dhcp_start = $dhcpinfo['start'];
951                                         $dhcp_end = $dhcpinfo['end'];
952                                 }
953                                 else {
954                                         /* Definition like '$dhcp_start - $dhcp_end' */
955                                         $tmp = explode('-', $dhcpinfo);
956                                         $dhcp_start = Trim($tmp[0]);
957                                         $dhcp_end = Trim($tmp[1]);
958                                 }
959
960                                 $dhcps = "<dhcp>
961                                                 <range start='$dhcp_start' end='$dhcp_end' />
962                                         </dhcp>";
963                         }
964
965                         $xml = "<network>
966                                 <name>$name</name>
967                                 <uuid>$uuid</uuid>
968                                 $forwards
969                                 <bridge name='$bridge' stp='on' delay='0' />
970                                 <ip address='$ip' netmask='$mask'>
971                                         $dhcps
972                                 </ip>
973                                 </network>";
974
975                         return $this->network_define($xml);
976                 }
977
978                 function network_define($xml) {
979                         $tmp = libvirt_network_define_xml($this->conn, $xml);
980                         return ($tmp) ? $tmp : $this->_set_last_error();
981                 }
982
983                 function network_undefine($network) {
984                         $net = $this->get_network_res($network);
985                         $tmp = libvirt_network_undefine($net);
986                         return ($tmp) ? $tmp : $this->_set_last_error();
987                 }
988
989                 function translate_storagepool_state($state) {
990                         $lang = new Language($this->lang_str);
991                         $ret = $lang->get('unknown');
992                         switch ($state) {
993                                 case 0: $ret = $lang->get('pool_not_running');
994                                         break;
995                                 case 1: $ret = $lang->get('pool_building');
996                                         break;
997                                 case 2: $ret = $lang->get('pool_running');
998                                         break;
999                                 case 3: $ret = $lang->get('pool_running_deg');
1000                                         break;
1001                                 case 4: $ret = $lang->get('pool_running_inac');
1002                                         break;
1003                         }
1004                         unset($lang);
1005
1006                         return $ret;
1007                 }
1008
1009                 function get_domains() {
1010                         $tmp = libvirt_list_domains($this->conn);
1011                         return ($tmp) ? $tmp : $this->_set_last_error();
1012                 }
1013
1014                 function get_domain_by_name($name) {
1015                         $tmp = libvirt_domain_lookup_by_name($this->conn, $name);
1016                         return ($tmp) ? $tmp : $this->_set_last_error();
1017                 }
1018
1019                 function get_networks($type = VIR_NETWORKS_ALL) {
1020                         $tmp = libvirt_list_networks($this->conn, $type);
1021                         return ($tmp) ? $tmp : $this->_set_last_error();
1022                 }
1023
1024                 function get_nic_models() {
1025                         return array('default', 'rtl8139', 'e1000', 'pcnet', 'ne2k_pci', 'virtio');
1026                 }
1027
1028                 function get_network_res($network) {
1029                         if ($network == false)
1030                                 return false;
1031                         if (is_resource($network))
1032                                 return $network;
1033
1034                         $tmp = libvirt_network_get($this->conn, $network);
1035                         return ($tmp) ? $tmp : $this->_set_last_error();
1036                 }
1037
1038                 function get_network_bridge($network) {
1039                         $res = $this->get_network_res($network);
1040                         if ($res == false)
1041                                 return false;
1042
1043                         $tmp = libvirt_network_get_bridge($res);
1044                         return ($tmp) ? $tmp : $this->_set_last_error();
1045                 }
1046
1047                 function get_network_active($network) {
1048                         $res = $this->get_network_res($network);
1049                         if ($res == false)
1050                                 return false;
1051
1052                         $tmp = libvirt_network_get_active($res);
1053                         return ($tmp) ? $tmp : $this->_set_last_error();
1054                 }
1055
1056                 function set_network_active($network, $active = true) {
1057                         $res = $this->get_network_res($network);
1058                         if ($res == false)
1059                                 return false;
1060
1061                         if (!libvirt_network_set_active($res, $active ? 1 : 0))
1062                                 return $this->_set_last_error();
1063
1064                         return true;
1065                 }
1066
1067                 function get_network_information($network) {
1068                         $res = $this->get_network_res($network);
1069                         if ($res == false)
1070                                 return false;
1071
1072                         $tmp = libvirt_network_get_information($res);
1073                         if (!$tmp)
1074                                 return $this->_set_last_error();
1075                         $tmp['active'] = $this->get_network_active($res);
1076                         return $tmp;
1077                 }
1078
1079                 function get_network_xml($network) {
1080                         $res = $this->get_network_res($network);
1081                         if ($res == false)
1082                                 return false;
1083
1084                         $tmp = libvirt_network_get_xml_desc($res, NULL);
1085                         return ($tmp) ? $tmp : $this->_set_last_error();
1086                 }
1087
1088                 function get_node_devices($dev = false) {
1089                         $tmp = ($dev == false) ? libvirt_list_nodedevs($this->conn) : libvirt_list_nodedevs($this->conn, $dev);
1090                         return ($tmp) ? $tmp : $this->_set_last_error();
1091                 }
1092
1093                 function get_node_device_res($res) {
1094                         if ($res == false)
1095                                 return false;
1096                         if (is_resource($res))
1097                                 return $res;
1098
1099                         $tmp = libvirt_nodedev_get($this->conn, $res);
1100                         return ($tmp) ? $tmp : $this->_set_last_error();
1101                 }
1102
1103                 function get_node_device_caps($dev) {
1104                         $dev = $this->get_node_device_res($dev);
1105
1106                         $tmp = libvirt_nodedev_capabilities($dev);
1107                         return ($tmp) ? $tmp : $this->_set_last_error();
1108                 }
1109
1110                 function get_node_device_cap_options() {
1111                         $all = $this->get_node_devices();
1112
1113                         $ret = array();
1114                         for ($i = 0; $i < sizeof($all); $i++) {
1115                                 $tmp = $this->get_node_device_caps($all[$i]);
1116
1117                                 for ($ii = 0; $ii < sizeof($tmp); $ii++)
1118                                         if (!in_array($tmp[$ii], $ret))
1119                                                 $ret[] = $tmp[$ii];
1120                         }
1121
1122                         return $ret;
1123                 }
1124
1125                 function get_node_device_xml($dev) {
1126                         $dev = $this->get_node_device_res($dev);
1127
1128                         $tmp = libvirt_nodedev_get_xml_desc($dev, NULL);
1129                         return ($tmp) ? $tmp : $this->_set_last_error();
1130                 }
1131
1132                 function get_node_device_information($dev) {
1133                         $dev = $this->get_node_device_res($dev);
1134
1135                         $tmp = libvirt_nodedev_get_information($dev);                   
1136                         return ($tmp) ? $tmp : $this->_set_last_error();
1137                 }
1138
1139                 function domain_get_name($res) {
1140                         return libvirt_domain_get_name($res);
1141                 }
1142
1143                 function domain_get_info_call($name = false, $name_override = false) {
1144                         $ret = array();
1145
1146                         if ($name != false) {
1147                                 $dom = $this->get_domain_object($name);
1148                                 if (!$dom)
1149                                         return false;
1150
1151                                 if ($name_override)
1152                                         $name = $name_override;
1153
1154                                 $ret[$name] = libvirt_domain_get_info($dom);
1155                                 return $ret;
1156                         }
1157                         else {
1158                                 $doms = libvirt_list_domains($this->conn);
1159                                 foreach ($doms as $dom) {
1160                                         $tmp = $this->domain_get_name($dom);
1161                                         $ret[$tmp] = libvirt_domain_get_info($dom);
1162                                 }
1163                         }
1164
1165                         ksort($ret);
1166                         return $ret;
1167                 }
1168
1169                 function domain_get_info($name = false, $name_override = false) {
1170                         if (!$name)
1171                                 return false;
1172
1173                         if (!$this->allow_cached)
1174                                 return $this->domain_get_info_call($name, $name_override);
1175
1176                         $domname = $name_override ? $name_override : $name;
1177                         $domkey  = $name_override ? $name_override : $this->domain_get_name($name);
1178                         if (!array_key_exists($domkey, $this->dominfos)) {
1179                                 $tmp = $this->domain_get_info_call($name, $name_override);
1180                                 $this->dominfos[$domkey] = $tmp[$domname];
1181                         }
1182
1183                         return $this->dominfos[$domkey];
1184                 }
1185
1186                 function get_last_error() {
1187                         return $this->last_error;
1188                 }
1189
1190                 function domain_get_xml($domain, $get_inactive = false) {
1191                         $dom = $this->get_domain_object($domain);
1192                         if (!$dom)
1193                                 return false;
1194
1195                         $tmp = libvirt_domain_get_xml_desc($dom, $get_inactive ? VIR_DOMAIN_XML_INACTIVE : 0);
1196                         return ($tmp) ? $tmp : $this->_set_last_error();
1197                 }
1198
1199                 function network_get_xml($network) {
1200                         $net = $this->get_network_res($network);
1201                         if (!$net)
1202                                 return false;
1203
1204                         $tmp = libvirt_network_get_xml_desc($net, NULL);
1205                         return ($tmp) ? $tmp : $this->_set_last_error();;
1206                 }
1207
1208                 function domain_get_id($domain, $name = false) {
1209                         $dom = $this->get_domain_object($domain);
1210                         if ((!$dom) || (!$this->domain_is_running($dom, $name)))
1211                                 return false;
1212
1213                         $tmp = libvirt_domain_get_id($dom);
1214                         return ($tmp) ? $tmp : $this->_set_last_error();
1215                 }
1216
1217                 function domain_get_interface_stats($nameRes, $iface) {
1218                         $dom = $this->get_domain_object($domain);
1219                         if (!$dom)
1220                                 return false;
1221
1222                         $tmp = libvirt_domain_interface_stats($dom, $iface);
1223                         return ($tmp) ? $tmp : $this->_set_last_error();
1224                 }
1225
1226                 function domain_get_memory_stats($domain) {
1227                         $dom = $this->get_domain_object($domain);
1228                         if (!$dom)
1229                                 return false;
1230
1231                         $tmp = libvirt_domain_memory_stats($dom);
1232                         return ($tmp) ? $tmp : $this->_set_last_error();
1233                 }
1234
1235                 function domain_start($dom) {
1236                         $dom=$this->get_domain_object($dom);
1237                         if ($dom) {
1238                                 $ret = libvirt_domain_create($dom);
1239                                 $this->last_error = libvirt_get_last_error();
1240                                 return $ret;
1241                         }
1242
1243                         $ret = libvirt_domain_create_xml($this->conn, $dom);
1244                         $this->last_error = libvirt_get_last_error();
1245                         return $ret;
1246                 }
1247
1248                 function domain_define($xml) {
1249                         $tmp = libvirt_domain_define_xml($this->conn, $xml);
1250                         return ($tmp) ? $tmp : $this->_set_last_error();
1251                 }
1252
1253                 function domain_destroy($domain) {
1254                         $dom = $this->get_domain_object($domain);
1255                         if (!$dom)
1256                                 return false;
1257
1258                         $tmp = libvirt_domain_destroy($dom);
1259                         return ($tmp) ? $tmp : $this->_set_last_error();
1260                 }
1261
1262                 function domain_reboot($domain) {
1263                         $dom = $this->get_domain_object($domain);
1264                         if (!$dom)
1265                                 return false;
1266
1267                         $tmp = libvirt_domain_reboot($dom);
1268                         return ($tmp) ? $tmp : $this->_set_last_error();
1269                 }
1270
1271                 function domain_suspend($domain) {
1272                         $dom = $this->get_domain_object($domain);
1273                         if (!$dom)
1274                                 return false;
1275
1276                         $tmp = libvirt_domain_suspend($dom);
1277                         return ($tmp) ? $tmp : $this->_set_last_error();
1278                 }
1279
1280                 function domain_resume($domain) {
1281                         $dom = $this->get_domain_object($domain);
1282                         if (!$dom)
1283                                 return false;
1284
1285                         $tmp = libvirt_domain_resume($dom);
1286                         return ($tmp) ? $tmp : $this->_set_last_error();
1287                 }
1288
1289                 function domain_get_name_by_uuid($uuid) {
1290                         $dom = libvirt_domain_lookup_by_uuid_string($this->conn, $uuid);
1291                         if (!$dom)
1292                                 return false;
1293                         $tmp = libvirt_domain_get_name($dom);
1294                         return ($tmp) ? $tmp : $this->_set_last_error();
1295                 }
1296
1297                 function generate_uuid($seed=false) {
1298                         if (!$seed)
1299                                 $seed = time();
1300                         srand($seed);
1301
1302                         $ret = array();
1303                         for ($i = 0; $i < 16; $i++)
1304                                 $ret[] = $this->macbyte(rand() % 256);
1305
1306                         $a = $ret[0].$ret[1].$ret[2].$ret[3];
1307                         $b = $ret[4].$ret[5];
1308                         $c = $ret[6].$ret[7];
1309                         $d = $ret[8].$ret[9];
1310                         $e = $ret[10].$ret[11].$ret[12].$ret[13].$ret[14].$ret[15];
1311
1312                         return $a.'-'.$b.'-'.$c.'-'.$d.'-'.$e;
1313                 }
1314
1315                 function domain_generate_uuid() {
1316                         $uuid = $this->generate_uuid();
1317
1318                         while ($this->domain_get_name_by_uuid($uuid))
1319                                 $uuid = $this->generate_uuid();
1320
1321                         return $uuid;
1322                 }
1323
1324                 function network_generate_uuid() {
1325                         /* TODO: Fix after virNetworkLookupByUUIDString is exposed
1326                                  to libvirt-php to ensure UUID uniqueness */
1327                         return $this->generate_uuid();
1328                 }
1329
1330                 function domain_shutdown($domain) {
1331                         $dom = $this->get_domain_object($domain);
1332                         if (!$dom)
1333                                 return false;
1334
1335                         $tmp = libvirt_domain_shutdown($dom);
1336                         return ($tmp) ? $tmp : $this->_set_last_error();
1337                 }
1338
1339                 function domain_undefine($domain) {
1340                         $dom = $this->get_domain_object($domain);
1341                         if (!$dom)
1342                                 return false;
1343
1344                         $tmp = libvirt_domain_undefine($dom);
1345                         return ($tmp) ? $tmp : $this->_set_last_error();
1346                 }
1347
1348                 function domain_is_running($domain, $name = false) {
1349                         $dom = $this->get_domain_object($domain);
1350                         if (!$dom)
1351                                 return false;
1352
1353                         $tmp = $this->domain_get_info( $domain, $name );
1354                         if (!$tmp)
1355                                 return $this->_set_last_error();
1356                         $ret = ( ($tmp['state'] == VIR_DOMAIN_RUNNING) || ($tmp['state'] == VIR_DOMAIN_BLOCKED) );
1357                         unset($tmp);
1358                         return $ret;
1359                 }
1360
1361                 function domain_state_translate($state) {
1362                         $lang = new Language($this->lang_str);
1363
1364                         $ret = $lang->get('unknown');
1365                         switch ($state) {
1366                                 case VIR_DOMAIN_RUNNING:  $ret = $lang->get('dom_running');
1367                                                           break;
1368                                 case VIR_DOMAIN_NOSTATE:  $ret = $lang->get('dom_nostate');
1369                                                           break;
1370                                 case VIR_DOMAIN_BLOCKED:  $ret = $lang->get('dom_blocked');
1371                                                           break;
1372                                 case VIR_DOMAIN_PAUSED:   $ret = $lang->get('dom_paused');
1373                                                           break;
1374                                 case VIR_DOMAIN_SHUTDOWN: $ret = $lang->get('dom_shutdown');
1375                                                           break;
1376                                 case VIR_DOMAIN_SHUTOFF:  $ret = $lang->get('dom_shutoff');
1377                                                           break;
1378                                 case VIR_DOMAIN_CRASHED:  $ret = $this->get('dom_crashed');
1379                                                           break;
1380                         }
1381                         unset($lang);
1382
1383                         return $ret;
1384                 }
1385
1386                 function domain_get_vnc_port($domain) {
1387                         $tmp = $this->get_xpath($domain, '//domain/devices/graphics/@port', false);
1388                         $var = (int)$tmp[0];
1389                         unset($tmp);
1390
1391                         return $var;
1392                 }
1393
1394                 function domain_get_arch($domain) {
1395                         $domain = $this->get_domain_object($domain);
1396
1397                         $tmp = $this->get_xpath($domain, '//domain/os/type/@arch', false);
1398                         $var = $tmp[0];
1399                         unset($tmp);
1400
1401                         return $var;
1402                 }
1403
1404                 function domain_get_description($domain) {
1405                         $tmp = $this->get_xpath($domain, '//domain/description', false);
1406                         $var = $tmp[0];
1407                         unset($tmp);
1408
1409                         return $var;
1410                 }
1411
1412                 function domain_get_clock_offset($domain) {
1413                         $tmp = $this->get_xpath($domain, '//domain/clock/@offset', false);
1414                         $var = $tmp[0];
1415                         unset($tmp);
1416
1417                         return $var;
1418                 }
1419
1420                 function domain_get_feature($domain, $feature) {
1421                         $tmp = $this->get_xpath($domain, '//domain/features/'.$feature.'/..', false);
1422                         $ret = ($tmp != false);
1423                         unset($tmp);
1424
1425                         return $ret;
1426                 }
1427
1428                 function domain_get_boot_devices($domain) {
1429                         $tmp = $this->get_xpath($domain, '//domain/os/boot/@dev', false);
1430                         if (!$tmp)
1431                                 return false;
1432
1433                         $devs = array();
1434                         for ($i = 0; $i < $tmp['num']; $i++)
1435                                 $devs[] = $tmp[$i];
1436
1437                         return $devs;
1438                 }
1439
1440                 function _get_single_xpath_result($domain, $xpath) {
1441                         $tmp = $this->get_xpath($domain, $xpath, false);
1442                         if (!$tmp)
1443                                 return false;
1444
1445                         if ($tmp['num'] == 0)
1446                                 return false;
1447
1448                         return $tmp[0];
1449                 }
1450
1451                 function domain_get_multimedia_device($domain, $type, $display=false) {
1452                         $domain = $this->get_domain_object($domain);
1453
1454                         if ($type == 'console') {
1455                                 $type = $this->_get_single_xpath_result($domain, '//domain/devices/console/@type');
1456                                 $targetType = $this->_get_single_xpath_result($domain, '//domain/devices/console/target/@type');
1457                                 $targetPort = $this->_get_single_xpath_result($domain, '//domain/devices/console/target/@port');
1458
1459                                 if ($display)
1460                                         return $type.' ('.$targetType.' on port '.$targetPort.')';
1461                                 else
1462                                         return array('type' => $type, 'targetType' => $targetType, 'targetPort' => $targetPort);
1463                         }
1464                         else
1465                         if ($type == 'input') {
1466                                 $type = $this->_get_single_xpath_result($domain, '//domain/devices/input/@type');
1467                                 $bus  = $this->_get_single_xpath_result($domain, '//domain/devices/input/@bus');
1468
1469                                 if ($display)
1470                                         return $type.' on '.$bus;
1471                                 else
1472                                         return array('type' => $type, 'bus' => $bus);
1473                         }
1474                         else
1475                         if ($type == 'graphics') {
1476                                 $type = $this->_get_single_xpath_result($domain, '//domain/devices/graphics/@type');
1477                                 $port = $this->_get_single_xpath_result($domain, '//domain/devices/graphics/@port');
1478                                 $autoport = $this->_get_single_xpath_result($domain, '//domain/devices/graphics/@autoport');
1479
1480                                 if ($display)
1481                                         return $type.' on port '.$port.' with'.($autoport ? '' : 'out').' autoport enabled';
1482                                 else
1483                                         return array('type' => $type, 'port' => $port, 'autoport' => $autoport);
1484                         }
1485                         else
1486                         if ($type == 'video') {
1487                                 $type  = $this->_get_single_xpath_result($domain, '//domain/devices/video/model/@type');
1488                                 $vram  = $this->_get_single_xpath_result($domain, '//domain/devices/video/model/@vram');
1489                                 $heads = $this->_get_single_xpath_result($domain, '//domain/devices/video/model/@heads');
1490
1491                                 if ($display)
1492                                         return $type.' with '.($vram / 1024).' MB VRAM, '.$heads.' head(s)';
1493                                 else
1494                                         return array('type' => $type, 'vram' => $vram, 'heads' => $heads);
1495                         }
1496                         else
1497                                 return false;
1498                 }
1499
1500                 function domain_get_host_devices_pci($domain) {
1501                         $xpath = '//domain/devices/hostdev[@type="pci"]/source/address/@';
1502
1503                         $dom  = $this->get_xpath($domain, $xpath.'domain', false);
1504                         $bus  = $this->get_xpath($domain, $xpath.'bus', false);
1505                         $slot = $this->get_xpath($domain, $xpath.'slot', false);
1506                         $func = $this->get_xpath($domain, $xpath.'function', false);
1507
1508                         $devs = array();
1509                         for ($i = 0; $i < $bus['num']; $i++) {
1510                                 $d = str_replace('0x', '', $dom[$i]);
1511                                 $b = str_replace('0x', '', $bus[$i]);
1512                                 $s = str_replace('0x', '', $slot[$i]);
1513                                 $f = str_replace('0x', '', $func[$i]);
1514                                 $devid = 'pci_'.$d.'_'.$b.'_'.$s.'_'.$f;
1515                                 $tmp2 = $this->get_node_device_information($devid);
1516                                 $devs[] = array('domain' => $dom[$i], 'bus' => $bus[$i],
1517                                                 'slot' => $slot[$i], 'func' => $func[$i],
1518                                                 'vendor' => $tmp2['vendor_name'],
1519                                                 'vendor_id' => $tmp2['vendor_id'],
1520                                                 'product' => $tmp2['product_name'],
1521                                                 'product_id' => $tmp2['product_id']);
1522                         }
1523
1524                         return $devs;
1525                 }
1526
1527                 function _lookup_device_usb($vendor_id, $product_id) {
1528                         $tmp = $this->get_node_devices(false);
1529                         for ($i = 0; $i < sizeof($tmp); $i++) {
1530                                 $tmp2 = $this->get_node_device_information($tmp[$i]);
1531                                 if (array_key_exists('product_id', $tmp2)) {
1532                                         if (($tmp2['product_id'] == $product_id)
1533                                                 && ($tmp2['vendor_id'] == $vendor_id))
1534                                                         return $tmp2;
1535                                 }
1536                         }
1537
1538                         return false;
1539                 }
1540
1541                 function domain_get_host_devices_usb($domain) {
1542                         $xpath = '//domain/devices/hostdev[@type="usb"]/source/';
1543
1544                         $vid = $this->get_xpath($domain, $xpath.'vendor/@id', false);
1545                         $pid = $this->get_xpath($domain, $xpath.'product/@id', false);
1546
1547                         $devs = array();
1548                         for ($i = 0; $i < $vid['num']; $i++) {
1549                                 $dev = $this->_lookup_device_usb($vid[$i], $pid[$i]);
1550                                 $devs[] = array('vendor_id' => $vid[$i], 'product_id' => $pid[$i],
1551                                                 'product' => $dev['product_name'],
1552                                                 'vendor' => $dev['vendor_name']);
1553                         }
1554
1555                         return $devs;
1556                 }
1557
1558                 function domain_get_host_devices($domain) {
1559                         $domain = $this->get_domain_object($domain);
1560
1561                         $devs_pci = $this->domain_get_host_devices_pci($domain);
1562                         $devs_usb = $this->domain_get_host_devices_usb($domain);
1563
1564                         return array('pci' => $devs_pci, 'usb' => $devs_usb);
1565                 }
1566
1567                 function domain_set_feature($domain, $feature, $val) {
1568                         $domain = $this->get_domain_object($domain);
1569
1570                         if ($this->domain_get_feature($domain, $feature) == $val)
1571                                 return true;
1572
1573                         $xml = $this->domain_get_xml($domain, true);
1574                         if ($val) {
1575                                 if (strpos('features', $xml))
1576                                         $xml = str_replace('<features>', "<features>\n<$feature/>", $xml);
1577                                 else
1578                                         $xml = str_replace('</os>', "</os><features>\n<$feature/></features>", $xml);
1579                         }
1580                         else
1581                                 $xml = str_replace("<$feature/>\n", '', $xml);
1582
1583                         return $this->domain_change_xml($domain, $xml);
1584                 }
1585
1586                 function domain_set_clock_offset($domain, $offset) {
1587                         $domain = $this->get_domain_object($domain);
1588
1589                         if (($old_offset = $this->domain_get_clock_offset($domain)) == $offset)
1590                                 return true;
1591
1592                         $xml = $this->domain_get_xml($domain, true);
1593                         $xml = str_replace("<clock offset='$old_offset'/>", "<clock offset='$offset'/>", $xml);
1594
1595                         return $this->domain_change_xml($domain, $xml);
1596                 }
1597
1598                 function domain_set_description($domain, $desc) {
1599                         $domain = $this->get_domain_object($domain);
1600
1601                         $description = $this->domain_get_description($domain);
1602                         if ($description == $desc)
1603                                 return true;
1604
1605                         $xml = $this->domain_get_xml($domain, true);
1606                         if (!$description)
1607                                 $xml = str_replace("</uuid>", "</uuid><description>$desc</description>", $xml);
1608                         else {
1609                                 $tmp = explode("\n", $xml);
1610                                 for ($i = 0; $i < sizeof($tmp); $i++)
1611                                         if (strpos('.'.$tmp[$i], '<description'))
1612                                                 $tmp[$i] = "<description>$desc</description>";
1613
1614                                 $xml = join("\n", $tmp);
1615                         }
1616
1617                         return $this->domain_change_xml($domain, $xml);
1618                 }
1619
1620                 function host_get_node_info() {
1621                         $tmp = libvirt_node_get_info($this->conn);
1622                         return ($tmp) ? $tmp : $this->_set_last_error();
1623                 }
1624
1625                 function node_get_cpu_stats() {
1626                         $tmp = libvirt_node_get_cpu_stats($this->conn);
1627                         if (!$tmp) return $this->_set_last_error();
1628
1629                         // tmp has two array, collected at 1sec delay. Make a diff
1630                         $newvalues = array();
1631                         foreach ($tmp[0] as $key => $elem) {
1632                                 $newvalues[$key] = $tmp[1][$key] - $elem;
1633                         }
1634                         return $newvalues;
1635                 }
1636
1637                 function node_get_mem_stats() {
1638                         $tmp = libvirt_node_get_mem_stats($this->conn);
1639                         return ($tmp) ? $tmp : $this->_set_last_error();
1640                 }
1641
1642                 function connect_get_sysinfo() {
1643                         $tmp = libvirt_connect_get_sysinfo($this->conn);
1644                         return ($tmp) ? $tmp : $this->_set_last_error();
1645                 }
1646         }
1647 ?>