grthtrhthjhtyjytjytkergtrhtrjytjerhrfh4:24 29/09/2026.
--------------------------------------------------------------------------
*/
/** @file
* @brief Virtual machine management
*/
if (!defined('GLPI_ROOT')) {
die("Sorry. You can't access this file directly");
}
/**
* ComputerVirtualMachine Class
*
* Class to manage virtual machines
**/
class ComputerVirtualMachine extends CommonDBChild {
// From CommonDBChild
static public $itemtype = 'Computer';
static public $items_id = 'computers_id';
public $dohistory = true;
static function getTypeName($nb=0) {
return _n('Virtual machine', 'Virtual machines', $nb);
}
/**
* @see CommonGLPI::getTabNameForItem()
**/
function getTabNameForItem(CommonGLPI $item, $withtemplate=0) {
if (!$withtemplate
&& ($item->getType() == 'Computer')
&& Computer::canView()) {
$nb = 0;
if ($_SESSION['glpishow_count_on_tabs']) {
$nb = countElementsInTable('glpi_computervirtualmachines',
"computers_id = '".$item->getID()."' AND `is_deleted`='0'");
}
return self::createTabEntry(self::getTypeName(Session::getPluralNumber()), $nb);
}
return '';
}
/**
* @see CommonGLPI::defineTabs()
*
* @since version 0.85
**/
function defineTabs($options=array()) {
$ong = array();
$this->addDefaultFormTab($ong);
return $ong;
}
/**
* @param $item CommonGLPI object
* @param $tabnum (default 1)
* @param $withtemplate (default 0)
**/
static function displayTabContentForItem(CommonGLPI $item, $tabnum=1, $withtemplate=0) {
self::showForVirtualMachine($item);
self::showForComputer($item);
return true;
}
function post_getEmpty() {
$this->fields["vcpu"] = '0';
$this->fields["ram"] = '0';
}
/**
* Print the version form
*
* @param $ID integer ID of the item
* @param $options array
* - target for the Form
* - computers_id ID of the computer for add process
*
* @return true if displayed false if item not found or not right to display
**/
function showForm($ID, $options=array()) {
global $CFG_GLPI;
if (!Session::haveRight("computer", UPDATE)) {
return false;
}
$comp = new Computer();
if ($ID > 0) {
$this->check($ID, READ);
$comp->getFromDB($this->fields['computers_id']);
} else {
// Create item
$this->check(-1, CREATE, $options);
$comp->getFromDB($options['computers_id']);
}
$this->showFormHeader($options);
if ($this->isNewID($ID)) {
echo " ";
}
echo "
";
echo "".__('Computer')." ";
echo "".$comp->getLink()." ";
if (Plugin::haveImport()) {
echo "".__('Automatic inventory')." ";
echo "";
if ($ID && $this->fields['is_dynamic']) {
Plugin::doHook("autoinventory_information", $this);
} else {
_e('No');
}
echo " ";
} else {
echo " ";
}
echo " \n";
echo "";
echo "".__('Name')." ";
echo "";
Html::autocompletionTextField($this, "name");
echo " ".__('Comments')." ";
echo "";
echo "";
echo " ";
echo "";
echo "".__('Virtualization system')." ";
echo "";
VirtualMachineType::dropdown(array('value' => $this->fields['virtualmachinetypes_id']));
echo " ";
echo "";
echo "".__('Virtualization model')." ";
echo "";
VirtualMachineSystem::dropdown(array('value' => $this->fields['virtualmachinesystems_id']));
echo " ";
echo "".__('State of the virtual machine')." ";
echo "";
VirtualMachineState::dropdown(array('value' => $this->fields['virtualmachinestates_id']));
echo " ";
echo "";
echo "".__('UUID')." ";
echo "";
Html::autocompletionTextField($this, "uuid");
echo " ";
echo "".__('Machine')." ";
echo "";
if ($link_computer = self::findVirtualMachine($this->fields)) {
$computer = new Computer();
if ($computer->getFromDB($link_computer)) {
echo $computer->getLink(array('comments' => true));
} else {
echo NOT_AVAILABLE;
}
}
echo " ";
echo " ";
echo "";
echo "".sprintf(__('%1$s (%2$s)'),__('Memory'),__('Mio'))." ";
echo "";
Html::autocompletionTextField($this, "ram");
echo " ";
echo ""._x('quantity', 'Processors number')." ";
echo "";
Html::autocompletionTextField($this, "vcpu");
echo " ";
$this->showFormButtons($options);
return true;
}
/**
* Show hosts for a virtualmachine
*
* @param $comp Computer object that represents the virtual machine
*
* @return Nothing (call to classes members)
**/
static function showForVirtualMachine(Computer $comp) {
global $DB;
$ID = $comp->fields['id'];
if (!$comp->getFromDB($ID) || !$comp->can($ID, READ)) {
return false;
}
$canedit = $comp->canEdit($ID);
echo "";
if (isset($comp->fields['uuid']) && ($comp->fields['uuid'] != '')) {
$where = "LOWER(`uuid`)".self::getUUIDRestrictRequest($comp->fields['uuid']);
$hosts = getAllDatasFromTable('glpi_computervirtualmachines', $where);
if (!empty($hosts)) {
echo "
";
echo "".__('List of host machines')." ";
$header = "".__('Name')." ";
$header .= "".__('Entity')." ";
$header .= " ";
echo $header;
$computer = new Computer();
foreach ($hosts as $host) {
echo "";
echo "";
if ($computer->can($host['computers_id'], READ)) {
echo "";
echo $computer->fields['name']." ";
$tooltip = "".__('Name')." ".$computer->fields['name'].
' ';
$tooltip.= "".__('Serial number')." ".$computer->fields['serial'].
' ';
$tooltip.= "".__('Comments')." ".$computer->fields['comment'].
'
';
echo " ".Html::showToolTip($tooltip, array('display' => false));
} else {
echo $computer->fields['name'];
}
echo " ";
echo "";
echo Dropdown::getDropdownName('glpi_entities', $computer->fields['entities_id']);
echo " ";
}
echo $header;
echo "
";
}
}
echo "
";
if (!empty($hosts)) {
echo " ";
}
}
/**
* Print the computers disks
*
* @param $comp Computer object
*
* @return Nothing (call to classes members)
**/
static function showForComputer(Computer $comp) {
global $DB;
$ID = $comp->fields['id'];
if (!$comp->getFromDB($ID) || !$comp->can($ID, READ)) {
return false;
}
$canedit = $comp->canEdit($ID);
if ($canedit) {
echo "\n";
}
echo "";
$virtualmachines = getAllDatasFromTable('glpi_computervirtualmachines',
"`computers_id` = '$ID' AND `is_deleted` = '0'");
echo "
";
Session::initNavigateListItems('ComputerVirtualMachine',
sprintf(__('%1$s = %2$s'), __('Computer'),
(empty($comp->fields['name'])
? "($ID)" : $comp->fields['name'])));
if (empty($virtualmachines)) {
echo "".__('No virtual machine associated with the computer')." ";
} else {
echo "".__('List of virtual machines')." ";
$header = "".__('Name')." ";
if (Plugin::haveImport()) {
$header .= "".__('Automatic inventory')." ";
}
$header .= "".__('Virtualization system')." ";
$header .= "".__('Virtualization model')." ";
$header .= "".__('State of the virtual machine')." ";
$header .= "".__('UUID')." ";
$header .= ""._x('quantity', 'Processors number')." ";
$header .= "".sprintf(__('%1$s (%2$s)'), __('Memory'),__('Mio'))." ";
$header .= "".__('Machine')." ";
$header .= " ";
echo $header;
$vm = new self();
foreach ($virtualmachines as $virtualmachine) {
$vm->getFromDB($virtualmachine['id']);
echo "";
echo "".$vm->getLink()." ";
if (Plugin::haveImport()) {
echo "".Dropdown::getYesNo($vm->isDynamic())." ";
}
echo "";
echo Dropdown::getDropdownName('glpi_virtualmachinetypes',
$virtualmachine['virtualmachinetypes_id']);
echo " ";
echo "";
echo Dropdown::getDropdownName('glpi_virtualmachinesystems',
$virtualmachine['virtualmachinesystems_id']);
echo " ";
echo "";
echo Dropdown::getDropdownName('glpi_virtualmachinestates',
$virtualmachine['virtualmachinestates_id']);
echo " ";
echo "".$virtualmachine['uuid']." ";
echo "".$virtualmachine['vcpu']." ";
echo "".$virtualmachine['ram']." ";
echo "";
if ($link_computer = self::findVirtualMachine($virtualmachine)) {
$computer = new Computer();
if ($computer->can($link_computer, READ)) {
$url = "";
$url .= $computer->fields["name"]." ";
$tooltip = "".__('Name')." ".$computer->fields['name'].
' ';
$tooltip.= "".__('Serial number')." ".$computer->fields['serial'].
' ';
$tooltip.= "".__('Comments')." ".$computer->fields['comment'].
'
';
$url .= " ".Html::showToolTip($tooltip, array('display' => false));
} else {
$url = $computer->fields['name'];
}
echo $url;
}
echo " ";
echo " ";
Session::addToNavigateListItems('ComputerVirtualMachine', $virtualmachine['id']);
}
echo $header;
}
echo "
";
echo "
";
}
/**
* Get correct uuid sql search for virtualmachines
*
* @param $uuid the uuid given
*
* @return the restrict which contains uuid, uuid with first block flipped,
* uuid with 3 first block flipped
**/
static function getUUIDRestrictRequest($uuid) {
//More infos about uuid, please see wikipedia :
//http://en.wikipedia.org/wiki/Universally_unique_identifier
//Some uuid are not conform, so preprocessing is necessary
//A good uuid likes lik : 550e8400-e29b-41d4-a716-446655440000
//Case one : for example some uuid are like that :
//56 4d 77 d0 6b ef 3d da-4d 67 5c 80 a9 52 e2 c9
$pattern = "/([\w]{2})\ ([\w]{2})\ ([\w]{2})\ ([\w]{2})\ ";
$pattern .= "([\w]{2})\ ([\w]{2})\ ([\w]{2})\ ([\w]{2})-";
$pattern .= "([\w]{2})\ ([\w]{2})\ ([\w]{2})\ ([\w]{2})\ ";
$pattern .= "([\w]{2})\ ([\w]{2})\ ([\w]{2})\ ([\w]{2})/";
if (preg_match($pattern, $uuid)) {
$uuid = preg_replace($pattern, "$1$2$3$4-$5$6-$7$8-$9$10-$11$12$13$14$15$16", $uuid);
}
//Case two : why this code ? Because some dmidecode < 2.10 is buggy.
//On unix is flips first block of uuid and on windows flips 3 first blocks...
$in = " IN ('".strtolower($uuid)."'";
$regexes = array("/([\w]{2})([\w]{2})([\w]{2})([\w]{2})(.*)/" => "$4$3$2$1$5",
"/([\w]{2})([\w]{2})([\w]{2})([\w]{2})-([\w]{2})([\w]{2})-([\w]{2})([\w]{2})(.*)/"
=> "$4$3$2$1-$6$5-$8$7$9");
foreach ($regexes as $pattern => $replace) {
$reverse_uuid = preg_replace($pattern, $replace, $uuid);
if ($reverse_uuid) {
$in .= " ,'".strtolower($reverse_uuid)."'";
}
}
$in .= ")";
return $in;
}
/**
* Find a virtual machine by uuid
*
* @param fields array of virtualmachine fields
*
* @return the ID of the computer that have this uuid or false otherwise
**/
static function findVirtualMachine($fields=array()) {
global $DB;
if (!isset($fields['uuid']) || empty($fields['uuid'])) {
return false;
}
$query = "SELECT `id`
FROM `glpi_computers`
WHERE LOWER(`uuid`) ".self::getUUIDRestrictRequest($fields['uuid']);
$result = $DB->query($query);
//Virtual machine found, return ID
if ($DB->numrows($result)) {
return $DB->result($result,0,'id');
}
return false;
}
}
?>