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 ""; $header = ""; $header .= ""; $header .= ""; echo $header; $computer = new Computer(); foreach ($hosts as $host) { echo ""; echo ""; echo ""; } echo $header; echo "
".__('List of host machines')."
".__('Name')."".__('Entity')."
"; if ($computer->can($host['computers_id'], READ)) { echo ""; echo $computer->fields['name'].""; $tooltip = "'; $tooltip.= "'; $tooltip.= "
".__('Name')."".$computer->fields['name']. '
".__('Serial number')."".$computer->fields['serial']. '
".__('Comments')."".$computer->fields['comment']. '
'; echo "  ".Html::showToolTip($tooltip, array('display' => false)); } else { echo $computer->fields['name']; } echo "
"; echo Dropdown::getDropdownName('glpi_entities', $computer->fields['entities_id']); 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 "
". ""; _e('Add a virtual machine'); 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 ""; } else { echo ""; $header = ""; if (Plugin::haveImport()) { $header .= ""; } $header .= ""; $header .= ""; $header .= ""; $header .= ""; $header .= ""; $header .= ""; $header .= ""; $header .= ""; echo $header; $vm = new self(); foreach ($virtualmachines as $virtualmachine) { $vm->getFromDB($virtualmachine['id']); echo ""; echo ""; if (Plugin::haveImport()) { echo ""; } echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; Session::addToNavigateListItems('ComputerVirtualMachine', $virtualmachine['id']); } echo $header; } echo "
".__('No virtual machine associated with the computer')."
".__('List of virtual machines')."
".__('Name')."".__('Automatic inventory')."".__('Virtualization system')."".__('Virtualization model')."".__('State of the virtual machine')."".__('UUID').""._x('quantity', 'Processors number')."".sprintf(__('%1$s (%2$s)'), __('Memory'),__('Mio'))."".__('Machine')."
".$vm->getLink()."".Dropdown::getYesNo($vm->isDynamic()).""; echo Dropdown::getDropdownName('glpi_virtualmachinetypes', $virtualmachine['virtualmachinetypes_id']); echo ""; echo Dropdown::getDropdownName('glpi_virtualmachinesystems', $virtualmachine['virtualmachinesystems_id']); echo ""; echo Dropdown::getDropdownName('glpi_virtualmachinestates', $virtualmachine['virtualmachinestates_id']); echo "".$virtualmachine['uuid']."".$virtualmachine['vcpu']."".$virtualmachine['ram'].""; if ($link_computer = self::findVirtualMachine($virtualmachine)) { $computer = new Computer(); if ($computer->can($link_computer, READ)) { $url = ""; $url .= $computer->fields["name"].""; $tooltip = "'; $tooltip.= "'; $tooltip.= "
".__('Name')."".$computer->fields['name']. '
".__('Serial number')."".$computer->fields['serial']. '
".__('Comments')."".$computer->fields['comment']. '
'; $url .= "  ".Html::showToolTip($tooltip, array('display' => false)); } else { $url = $computer->fields['name']; } echo $url; } 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; } } ?>