You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by jf...@apache.org on 2014/09/11 18:01:49 UTC
svn commit: r1624325 [2/13] - in /vcl/trunk/web: ./ .ht-inc/
.ht-inc/authmethods/ css/ js/ js/resources/
Added: vcl/trunk/web/.ht-inc/computer.php
URL: http://svn.apache.org/viewvc/vcl/trunk/web/.ht-inc/computer.php?rev=1624325&view=auto
==============================================================================
--- vcl/trunk/web/.ht-inc/computer.php (added)
+++ vcl/trunk/web/.ht-inc/computer.php Thu Sep 11 16:01:48 2014
@@ -0,0 +1,4354 @@
+<?php
+/*
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \class Computer
+///
+/// \brief extends Resource class to add things specific to resources of the
+/// computer type
+///
+////////////////////////////////////////////////////////////////////////////////
+class Computer extends Resource {
+ /////////////////////////////////////////////////////////////////////////////
+ ///
+ /// \fn __construct()
+ ///
+ /// \brief calls parent constructor; initializes things for Computer class
+ ///
+ /////////////////////////////////////////////////////////////////////////////
+ function __construct() {
+ parent::__construct();
+ $this->restype = 'computer';
+ $this->restypename = 'Computer';
+ $this->namefield = 'hostname';
+ $this->defaultGetDataArgs = array('sort' => 0,
+ 'includedeleted' => 0,
+ 'rscid' => '');
+ $this->basecdata['obj'] = $this;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ ///
+ /// \fn getData($args)
+ ///
+ /// \param $args - array of arguments that determine what data gets returned;
+ /// must include:\n
+ /// \param $sort - (optional) 1 to sort computers; 0 not to
+ /// \b includedeleted - 0 or 1; include deleted images\n
+ /// \b rscid - only return data for resource with this id; pass 0 for all
+ /// (from image table)
+ ///
+ /// \return array of data as returned from getImages
+ ///
+ /// \brief wrapper for calling getImages
+ ///
+ /////////////////////////////////////////////////////////////////////////////
+ function getData($args) {
+ return getComputers($args['sort'], $args['includedeleted'], $args['rscid']);
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ ///
+ /// \fn fieldDisplayName($field)
+ ///
+ /// \param $field - name of a resource field
+ ///
+ /// \return display value for $field
+ ///
+ /// \brief generates the display value for $field
+ ///
+ /////////////////////////////////////////////////////////////////////////////
+ function fieldDisplayName($field) {
+ switch($field) {
+ case 'currentimg':
+ return 'Current Image';
+ case 'nextimg':
+ return 'Next Image';
+ case 'ram':
+ return 'RAM';
+ case 'procnumber':
+ return 'Cores';
+ case 'procspeed':
+ return 'Processor speed';
+ case 'network':
+ return 'Network speed';
+ case 'IPaddress':
+ return 'Public IP Address';
+ case 'privateIPaddress':
+ return 'Private IP Address';
+ case 'eth0macaddress':
+ return 'Private MAC Address';
+ case 'eth1macaddress':
+ return 'Public MAC Address';
+ case 'vmhost':
+ return 'VM Host';
+ case 'provisioning':
+ return 'Provisioning Engine';
+ }
+ return ucfirst($field);
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ ///
+ /// \fn extraResourceFilters()
+ ///
+ /// \return html
+ ///
+ /// \brief generates HTML for computer utilities drop down and filtering by
+ /// computer group
+ ///
+ /////////////////////////////////////////////////////////////////////////////
+ function extraResourceFilters() {
+ $h = '';
+
+ # selected items menu
+ $h .= "<div dojoType=\"dijit.form.DropDownButton\">\n";
+ $h .= "<span>" . _("Actions for selected computers") . "</span>\n";
+ $h .= "<div dojoType=\"dijit.Menu\" id=\"actionmenu\">\n";
+
+ # reload
+ $resources = getUserResources(array("imageAdmin", "imageCheckOut"));
+ if(count($resources['image'])) {
+ $h .= " <div dojoType=\"dijit.PopupMenuItem\">\n";
+ $h .= " <span>Reload with an Image</span>\n";
+ $h .= " <div dojoType=\"dijit.layout.ContentPane\"\n";
+ $h .= " style=\"background-color: white; padding: 5px; border: 1px solid black;\">\n";
+ $h .= " Reload computers with the following image:<br>\n";
+ $h .= selectInputAutoDijitHTML('', $resources['image'], 'reloadimageid');
+ $cont = addContinuationsEntry('AJreloadComputers', $this->basecdata);
+ $h .= " <input type=\"hidden\" id=\"reloadcont\" value=\"$cont\"><br>\n";
+ $h .= dijitButton('', 'Confirm Reload Computers', 'confirmReload();', 0);
+ $h .= " </div>\n";
+ $h .= " </div>\n";
+ }
+
+ # delete
+ $h .= " <div dojoType=\"dijit.MenuItem\"\n";
+ $h .= " onClick=\"confirmDelete\">\n";
+ $h .= " Delete Computers\n";
+ $cont = addContinuationsEntry('AJdeleteComputers', $this->basecdata);
+ $h .= " <input type=\"hidden\" id=\"deletecont\" value=\"$cont\"><br>\n";
+ $h .= " </div>\n";
+
+ # change state
+ $states = array("2" => "available",
+ "23" => "hpc",
+ "10" => "maintenance",
+ "20" => "convert to vmhostinuse");
+ $h .= " <div dojoType=\"dijit.PopupMenuItem\">\n";
+ $h .= " <span>Change State</span>\n";
+ $h .= " <div dojoType=\"dijit.layout.ContentPane\"\n";
+ $h .= " style=\"background-color: white; padding: 5px; border: 1px solid black;\">\n";
+ $h .= " Change state to:<br>\n";
+ $h .= selectInputAutoDijitHTML('', $states, 'newstateid');
+ $cdata = $this->basecdata;
+ $cdata['states'] = $states;
+ $cont = addContinuationsEntry('AJcompStateChange', $cdata);
+ $h .= " <input type=\"hidden\" id=\"statechangecont\" value=\"$cont\"><br>\n";
+ $h .= dijitButton('', 'Confirm State Change', 'confirmStateChange();', 0);
+ $h .= " </div>\n";
+ $h .= " </div>\n";
+
+ # change schedule
+ $resources = getUserResources(array("scheduleAdmin"), array("manageGroup"));
+ if(count($resources['schedule'])) {
+ $h .= " <div dojoType=\"dijit.PopupMenuItem\">\n";
+ $h .= " <span>Change Schedule</span>\n";
+ $h .= " <div dojoType=\"dijit.layout.ContentPane\"\n";
+ $h .= " style=\"background-color: white; padding: 5px; border: 1px solid black;\">\n";
+ $h .= " Change schedule to:<br>\n";
+ $h .= selectInputAutoDijitHTML('', $resources['schedule'], 'newscheduleid');
+ $cont = addContinuationsEntry('AJcompScheduleChange', $this->basecdata);
+ $h .= " <input type=\"hidden\" id=\"schedulecont\" value=\"$cont\"><br>\n";
+ $h .= dijitButton('', 'Confirm Schedule Change', 'confirmScheduleChange();', 0);
+ $h .= " </div>\n";
+ $h .= " </div>\n";
+ }
+
+ # change provisioning engine
+ $provisioning = getProvisioning();
+ $h .= " <div dojoType=\"dijit.PopupMenuItem\">\n";
+ $h .= " <span>Change Provisioning Engine</span>\n";
+ $h .= " <div dojoType=\"dijit.layout.ContentPane\"\n";
+ $h .= " style=\"background-color: white; padding: 5px; border: 1px solid black;\">\n";
+ $h .= " Change Provisioning Engine to:<br>\n";
+ $h .= selectInputAutoDijitHTML('', $provisioning, 'newprovisioningid');
+ $cdata = $this->basecdata;
+ $cont = addContinuationsEntry('AJcompProvisioningChange', $cdata);
+ $h .= " <input type=\"hidden\" id=\"provisioningchangecont\" value=\"$cont\"><br>\n";
+ $h .= dijitButton('', 'Confirm Provisioning Engine Change', 'confirmProvisioningChange();', 0);
+ $h .= " </div>\n";
+ $h .= " </div>\n";
+
+ # generate private dhcpd data
+ $h .= " <div dojoType=\"dijit.PopupMenuItem\">\n";
+ $h .= " <span>Generate Private dhcpd Data</span>\n";
+ $h .= " <div dojoType=\"dijit.layout.ContentPane\"\n";
+ $h .= " style=\"background-color: white; padding: 5px; border: 1px solid black;\">\n";
+ $h .= " Enter the Management Node Private IP Address:<br>\n";
+ $h .= " <input type=\"text\" dojoType=\"dijit.form.TextBox\" id=\"mnprivipaddr\" ";
+ $h .= "required=\"false\"><br><br>\n";
+ $h .= " Select which NIC is used for the Private interface:<br>\n";
+ $h .= " <input type=\"radio\" name=\"prnic\" value=\"eth0\" id=\"preth0rdo\" ";
+ $h .= "checked=\"checked\"><label for=\"eth0rdo\">eth0</label><br>\n";
+ $h .= " <input type=\"radio\" name=\"prnic\" value=\"eth1\" id=\"preth1rdo\">";
+ $h .= "<label for=\"eth1rdo\">eth1</label><br>\n";
+ $h .= dijitButton('', 'Generate Data', "generateDHCPdata('private');", 0);
+ $cont = addContinuationsEntry('AJgenerateDHCPdata', $this->basecdata);
+ $h .= " <input type=\"hidden\" id=\"privatedhcpcont\" value=\"$cont\">\n";
+ $h .= " </div>\n";
+ $h .= " </div>\n";
+
+ # generate public dhcpd data
+ $h .= " <div dojoType=\"dijit.PopupMenuItem\">\n";
+ $h .= " <span>Generate Public dhcpd Data</span>\n";
+ $h .= " <div dojoType=\"dijit.layout.ContentPane\"\n";
+ $h .= " style=\"background-color: white; padding: 5px; border: 1px solid black;\">\n";
+ $h .= " Select which NIC is used for the Public interface:<br>\n";
+ $h .= " <input type=\"radio\" name=\"punic\" value=\"eth0\" id=\"pueth0rdo\">";
+ $h .= "<label for=\"eth0rdo\">eth0</label><br>\n";
+ $h .= " <input type=\"radio\" name=\"punic\" value=\"eth1\" id=\"pueth1rdo\" ";
+ $h .= "checked=\"checked\"><label for=\"eth1rdo\">eth1</label><br>\n";
+ $h .= dijitButton('', 'Generate Data', "generateDHCPdata('public');", 0);
+ $h .= " <input type=\"hidden\" id=\"publicdhcpcont\" value=\"$cont\">\n"; # use previous continuation
+ $h .= " </div>\n";
+ $h .= " </div>\n";
+
+ # generate /etc/hosts data
+ $h .= " <div dojoType=\"dijit.MenuItem\"\n";
+ $h .= " onClick=\"hostsData\">\n";
+ $h .= " Generate /etc/hosts Data\n";
+ $cont = addContinuationsEntry('AJhostsData', $this->basecdata);
+ $h .= " <input type=\"hidden\" id=\"hostsdatacont\" value=\"$cont\"><br>\n";
+ $h .= " </div>\n";
+
+ $h .= "</div>\n"; # close Menu
+ $h .= "</div>\n"; # close DropDownButton
+
+ # computer groups
+ $tmp = getUserResources(array($this->restype . 'Admin'), array('manageGroup'), 1);
+ $groups = $tmp[$this->restype];
+ $cont = addContinuationsEntry('AJfilterCompGroups', $this->basecdata);
+ $h .= "<input type=\"hidden\" id=\"filtercompgroupscont\" value=\"$cont\">\n";
+ $h .= "<div dojoType=\"dijit.form.DropDownButton\">\n";
+ $h .= " <span>Selected Computer Groups</span>\n";
+ $h .= " <div dojoType=\"dijit.TooltipDialog\" id=\"connectmethodttd\">\n";
+ $size = 10;
+ if(count($groups) < 10)
+ $size = count($groups);
+ $h .= selectInputHTML('', $groups, 'filtercompgroups',
+ "onChange=\"delayedCompGroupFilterSelection();\" size=\"$size\"",
+ -1, 0, 1);
+ $h .= " </div>\n"; # tooltip dialog
+ $h .= "</div>\n"; # drop down button
+
+ $h .= "<div dojoType=dijit.Dialog\n";
+ $h .= " id=\"confirmactiondlg\"\n";
+ $h .= " duration=250\n";
+ $h .= " autofocus=false\n";
+ $h .= " draggable=true>\n";
+ #$h .= "<div id=\"actionmsg\"></div>\n";
+ $h .= "<div dojoType=\"dijit.layout.ContentPane\" id=\"actionmsg\"\n";
+ $h .= " style=\"background-color: white; padding: 5px;\">\n";
+ $h .= "</div>\n";
+ $h .= "<div id=\"complist\" style=\"height: 87%; overflow: auto;\"></div>\n";
+ $h .= "<input type=\"hidden\" id=\"submitcont\">\n";
+ $h .= "<div style=\"text-align: center;\">\n";
+ $h .= "<span id=\"submitactionbtnspan\">\n";
+ $h .= dijitButton('submitactionbtn', 'Submit', 'submitAction();', 0);
+ $h .= "</span>\n";
+ $h .= dijitButton('cancelactionbtn', 'Cancel', 'cancelAction();', 0);
+ $h .= "</div>\n"; # btn div
+ $h .= "</div>\n"; # confirmactiondlg
+
+ $h .= "<div dojoType=dijit.Dialog\n";
+ $h .= " id=\"noschedulenoadd\"\n";
+ $h .= " title=\"Cannot Add Computers\"\n";
+ $h .= " duration=250\n";
+ $h .= " autofocus=false\n";
+ $h .= " draggable=true>\n";
+ $h .= "All computers must have a schedule assigned to them. You do not<br>\n";
+ $h .= "have to any schedules or no schedules exist. You must be granted<br>\n";
+ $h .= "access to or create at least one schedule to be able to add computers.<br><br>\n";
+ $h .= "<div style=\"text-align: center;\">\n";
+ $h .= dijitButton('', 'Close', 'dijit.byId("noschedulenoadd").hide();', 0);
+ $h .= "</div>\n"; # btn div
+ $h .= "</div>\n"; # noschedulenoadd
+
+ # filter table
+ $h .= "<div id=\"extrafiltersdiv\" style=\"height: 65px;\"></div>\n";
+ return $h;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ ///
+ /// \fn AJfilterCompGroups
+ ///
+ /// \brief generates regular expressions to match ids of all computers in the
+ /// submitted computer groups
+ ///
+ /////////////////////////////////////////////////////////////////////////////
+ function AJfilterCompGroups() {
+ $groupids = processInputVar('groupids', ARG_STRING);
+ if(! preg_match('/^[0-9,]+$/', $groupids)) {
+ $ret = array('status' => 'error',
+ 'errormsg' => "Invalid data submitted.");
+ sendJSON($ret);
+ return;
+ }
+ $groupids = explode(',', $groupids);
+ $tmp = getUserResources(array($this->restype . 'Admin'), array('manageGroup'), 1);
+ $groups = $tmp[$this->restype];
+ $groupnames = array();
+ foreach($groupids as $id) {
+ if(array_key_exists($id, $groups))
+ $groupnames[] = $groups[$id];
+ }
+ $comps = getResourcesFromGroups($groupnames, 'computer', 1);
+ $regids = "^" . implode('$|^', array_keys($comps)) . "$";
+ $arr = array('status' => 'success',
+ 'regids' => $regids);
+ sendJSON($arr);
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ ///
+ /// \fn addEditDialogHTML($add)
+ ///
+ /// \param $add - unused for this class
+ ///
+ /// \brief generates HTML for dialog used to edit resource
+ ///
+ /////////////////////////////////////////////////////////////////////////////
+ function addEditDialogHTML($add) {
+ global $user;
+ # dialog for on page editing
+ $h = '';
+ $h .= "<div dojoType=dijit.Dialog\n";
+ $h .= " id=\"addeditdlg\"\n";
+ $h .= " title=\"Edit {$this->restypename}\"\n";
+ $h .= " duration=250\n";
+ $h .= " draggable=true>\n";
+ $h .= "<div id=\"addeditdlgcontent\">\n";
+ $h .= "<div id=\"computerdlgcontent\">\n";
+ # id
+ $h .= "<input type=\"hidden\" id=\"editresid\">\n";
+
+ $types = array("blade" => "Bare Metal", "lab" => "Lab", "virtualmachine" => "Virtual Machine");
+ $provisioning = getProvisioning();
+ $provtypes = getProvisioningTypes();
+ $states = array('blade' => array(2 => 'available',
+ 10 => 'maintenance',
+ 20 => 'vmhostinuse'),
+ 'lab' => array(2 => 'available',
+ 10 => 'maintenance'),
+ 'virtualmachine' => array(10 => 'maintenance'));
+
+ $h .= "<script type=\"text/javascript\">\n";
+ $h .= "var options = {\n";
+ $options = array();
+ foreach($types as $type => $tmp) {
+ $opt = '';
+ $opt .= " $type: {\n";
+ $opt .= " provisioning: [\n";
+ $arr = array();
+ foreach($provtypes[$type] as $key => $val)
+ $arr[] = " {value: '$key', label: '$val'}";
+ $opt .= implode(",\n", $arr);
+ $opt .= "\n ],\n";
+ $opt .= " states: [\n";
+ $arr = array();
+ foreach($states[$type] as $key => $val)
+ $arr[] = " {value: '$key', label: '$val'}";
+ $opt .= implode(",\n", $arr);
+ $opt .= "\n ]\n";
+ $opt .= " }";
+ $options[] = $opt;
+ }
+ $h .= implode(",\n", $options);
+ $h .= "\n}\n";
+ $h .= "</script>\n";
+
+ # add single or multiple
+ $h .= "<div id=\"singlemultiplediv\" class=\"hidden\">\n";
+ /*$h .= "<label for=\"addsingle\">Add Single Computer</label><span ";
+ $h .= "class=\"labeledform\"><input type=\"radio\" name=\"mode\" ";
+ $h .= "id=\"addsingle\" checked=\"checked\" onclick=\"toggleAddSingle();\">";
+ $h .= "</span><br><br>\n";
+ $h .= "<label for=\"addmultiple\">Add Multiple Computers</label><span ";
+ $h .= "class=\"labeledform\"><input type=\"radio\" name=\"mode\" ";
+ $h .= "id=\"addmultiple\" onclick=\"toggleAddMultiple();\"><br><br>\n";*/
+ $extra = array('onChange' => 'toggleSingleMultiple();');
+ $modes = array('single' => 'Single Computer',
+ 'multiple' => 'Multiple Computers');
+ $h .= labeledFormItem('mode', 'Add ', 'select', $modes, 1, '', '', '', $extra);
+ $h .= "<br>\n";
+ $h .= "</div>\n"; # singlemultiplediv
+
+ # add multiple note
+ $h .= "<div id=\"multiplenotediv\" class=\"hidden\">\n";
+ $h .= "<b>NOTE</b>: 'Start IP' and 'End IP' can only differ in the number ";
+ $h .= "after the last '.'. The<br>hostnames will be generated from the ";
+ $h .= "'Hostname' field. The hostnames for each<br>computer can only differ ";
+ $h .= "by the value of a number in the first part of the hostname.<br>Place ";
+ $h .= "a '%' character in the 'Hostname' field where that number will be. ";
+ $h .= "Then fill in<br>'Start value' and 'End value' with the first and last ";
+ $h .= "values to be used in the hostname.<br><br>";
+ $h .= "</div>\n"; # multiplenotediv
+
+ # div for canceling moving blade to vmhostinuse
+ $h .= "<div class=\"highlightnoticewarn hidden\" id=\"cancelvmhostinusediv\">\n";
+ $h .= "<span id=\"tohostfuturespan\">\n";
+ $h .= "NOTICE: This computer is scheduled to start being reloaded as a vmhost at<br>";
+ $h .= "<span id=\"tohostfuturetimespan\"></span>";
+ $h .= ". You may cancel this scheduled<br>reload by clicking the button below.";
+ $h .= "<br><br></span>\n";
+ $h .= "<span id=\"tohostnowspan\">\n";
+ $h .= "NOTICE: This computer is currently being reloaded as a vmhost. You may cancel this<br>";
+ $h .= "process by clicking on the button below. After canceling the reload, it may take several<br>";
+ $h .= "minutes for the cancellation process to complete.";
+ $h .= "<br><br></span>\n";
+ $h .= "<input type=\"hidden\" id=\"tohostcancelcont\">\n";
+ $h .= "<button dojoType=\"dijit.form.Button\">\n";
+ $h .= " Cancel Scheduled Reload\n";
+ $h .= " <script type=\"dojo/method\" event=onClick>\n";
+ $h .= " cancelScheduledtovmhostinuse();\n";
+ $h .= " </script>\n";
+ $h .= "</button>\n";
+ $h .= "</div>\n"; # cancelvmhostinusediv
+ $h .= "<div class=\"highlightnoticenotify hidden\" id=\"cancelvmhostinuseokdiv\"></div>\n";
+
+ # hostname
+ $errmsg = "Name can only contain letters, numbers, dashes(-), periods(.), and underscores(_). It can be from 1 to 36 characters long.";
+ $h .= labeledFormItem('name', 'Name*', 'text', '^([a-zA-Z0-9_][-a-zA-Z0-9_\.]{1,35})$',
+ 1, '', $errmsg);
+
+ # start/end
+ $h .= "<div id=\"startenddiv\" class=\"hidden\">\n";
+ $extra = array('smallDelta' => 1, 'largeDelta' => 10);
+ $h .= labeledFormItem('startnum', 'Start*', 'spinner', '{min:0,max:255,places:0}', 1);
+ $h .= labeledFormItem('endnum', 'End*', 'spinner', '{min:0,max:255,places:0}', 1);
+ $h .= "</div>\n"; # startenddiv
+
+ # owner
+ $extra = array('onKeyPress' => 'setOwnerChecking');
+ $h .= labeledFormItem('owner', 'Owner*', 'text', '', 1,
+ "{$user['unityid']}@{$user['affiliation']}", 'Unknown user',
+ 'checkOwner', $extra);
+ $cont = addContinuationsEntry('AJvalidateUserid');
+ $h .= "<input type=\"hidden\" id=\"valuseridcont\" value=\"$cont\">\n";
+
+ # type
+ $extra = array('onChange' => 'selectType();');
+ $h .= labeledFormItem('type', 'Type', 'select', $types, 1, '', '', '', $extra);
+
+ # single computer fields
+ $h .= "<div id=\"singleipmacdiv\">\n";
+ # public IP
+ $ipreg = '(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)';
+ $ipreg1 = "^$ipreg$";
+ $errmsg = "Invalid Public IP address specified - must be a valid IPV4 address";
+ $h .= labeledFormItem('ipaddress', 'Public IP Address*', 'text', $ipreg1, 1, '', $errmsg);
+
+ # private IP
+ $errmsg = "Invalid Private IP address specified - must be a valid IPV4 address";
+ $h .= labeledFormItem('privateipaddress', 'Private IP Address', 'text', $ipreg1, 0, '', $errmsg);
+
+ # Public MAC
+ $macreg = '^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$';
+ $errmsg = "Invalid Public MAC address specified";
+ $h .= labeledFormItem('publicmac', 'Public MAC Address', 'text', $macreg, 0, '', $errmsg);
+
+ # private MAC
+ $errmsg = "Invalid Private MAC address specified";
+ $h .= labeledFormItem('privatemac', 'Private MAC Address', 'text', $macreg, 0, '', $errmsg);
+
+ $h .= "</div>\n"; # singleipmacdiv
+
+ # multi computer fields
+ $h .= "<div id=\"multiipmacdiv\" class=\"hidden\">\n";
+ # start public IP
+ $errmsg = "Invalid Start Public IP Address specified - must be a valid IPV4 address";
+ $h .= labeledFormItem('startpubipaddress', 'Start Public IP Address*', 'text', $ipreg1, 1, '', $errmsg);
+
+ # end public IP
+ $errmsg = "Invalid End Public IP Address specified - must be a valid IPV4 address";
+ $h .= labeledFormItem('endpubipaddress', 'End Public IP Address*', 'text', $ipreg1, 1, '', $errmsg);
+
+ # start private IP
+ $errmsg = "Invalid Start Private IP Address specified - must be a valid IPV4 address";
+ $h .= labeledFormItem('startprivipaddress', 'Start Private IP Address*', 'text', $ipreg1, 1, '', $errmsg);
+
+ # end private IP
+ $errmsg = "Invalid End Private IP Address specified - must be a valid IPV4 address";
+ $h .= labeledFormItem('endprivipaddress', 'End Private IP Address*', 'text', $ipreg1, 1, '', $errmsg);
+
+ # start MAC
+ $errmsg = "Invalid Start MAC Address specified";
+ $h .= labeledFormItem('startmac', 'Start MAC Address', 'text', $macreg, 0, '', $errmsg);
+
+ $h .= "</div>\n"; # multiipsdiv
+
+ # provisioning engine
+ $extra = array('onChange' => 'selectProvisioning();');
+ $h .= labeledFormItem('provisioningid', 'Provisioning Engine', 'selectonly', $provisioning, 1, '', '', '', $extra);
+
+ # state
+ $extra = array('onChange' => 'selectState();');
+ $states = array(2 => 'available',
+ 23 => 'hpc',
+ 10 => 'maintenance',
+ 20 => 'vmhostinuse');
+ $h .= labeledFormItem('stateid', 'State', 'selectonly', $states, 1, '', '', '', $extra);
+
+ # maintenance notes
+ $h .= "<div id=\"notesspan\">\n";
+ $h .= labeledFormItem('notes', 'Reason for maintenance', 'textarea');
+ $h .= "</div>\n";
+
+ # VMhost profile
+ $profiles = getVMProfiles();
+ uasort($profiles, 'sortKeepIndex');
+ $h .= "<div id=\"vmprofilespan\">\n";
+ $h .= labeledFormItem('vmprofileid', 'VM Host Porfile', 'select', $profiles);
+ $h .= "</div>\n";
+
+ # platform
+ $platforms = getPlatforms();
+ $h .= labeledFormItem('platformid', 'Platform', 'select', $platforms);
+
+ # schedule
+ $tmp = getUserResources(array("scheduleAdmin"), array("manageGroup"));
+ $schedules = $tmp["schedule"];
+ $h .= labeledFormItem('scheduleid', 'Schedule', 'select', $schedules);
+
+ # current image
+ $h .= "<div id=\"curimgspan\">\n";
+ $h .= "<label for=\"curimg\">Current Image:</label>\n";
+ $h .= "<span class=\"labeledform\" id=\"curimg\"></span><br>\n";
+ $h .= "</div>\n";
+
+ # ram
+ $extra = array('smallDelta' => 1024, 'largeDelta' => 4096);
+ $h .= labeledFormItem('ram', 'RAM (MB)*', 'spinner', '{min:500,max:16777215,places:0}', 1);
+
+ # cores
+ $extra = array('smallDelta' => 1, 'largeDelta' => 4);
+ $h .= labeledFormItem('cores', 'No. Cores*', 'spinner', '{min:1,max:255,places:0}', 1);
+
+ # proc speed
+ $extra = array('smallDelta' => 100, 'largeDelta' => 1000);
+ $h .= labeledFormItem('procspeed', 'Processor Speed (MHz)*', 'spinner', '{min:500,max:10000,places:0}', 1);
+
+ # network speed
+ $tmpArr = array("10" => "10", "100" => "100", "1000" => "1000", "10000" => "10000", "100000" => "100000");
+ $h .= labeledFormItem('network', 'Network', 'select', $tmpArr);
+
+ # compid
+ $h .= "<div id=\"compidspan\">\n";
+ $h .= "<label for=\"compid\">Computer ID:</label>\n";
+ $h .= "<span class=\"labeledform\" id=\"compid\"></span><br>\n";
+ $h .= "</div>\n";
+
+ # location
+ $errmsg = "Location can be up to 255 characters long and may contain letters, numbers, spaces, and these characters: - , . _ @ # ( )";
+ $h .= labeledFormItem('location', 'Location', 'text',
+ '^([-a-zA-Z0-9_\. ,@#\(\)]{0,255})$', 0, '', $errmsg);
+
+ $h .= "</div>\n"; # computerdlgcontent
+ $h .= "</div>\n"; # addeditdlgcontent
+
+ $h .= "<div id=\"addeditdlgerrmsg\" class=\"nperrormsg\"></div>\n";
+
+ $h .= "<div id=\"editdlgbtns\" align=\"center\">\n";
+ $h .= dijitButton('addeditbtn', "Confirm", "saveResource();");
+ $h .= dijitButton('', "Cancel", "dijit.byId('addeditdlg').hide();");
+ $h .= "</div>\n"; # editdlgbtns
+ $h .= "</div>\n"; # dialog
+
+ $h .= "<div dojoType=dijit.Dialog\n";
+ $h .= " id=\"groupingnote\"\n";
+ $h .= " title=\"Computer Grouping\"\n";
+ $h .= " duration=250\n";
+ $h .= " draggable=true>\n";
+ $h .= "Computer(s) successfully added. Each computer needs<br>to be a member of a computer resource group. The<br>following dialog<br>will allow you to add the new<br>computer(s) to a group.<br><br>\n";
+ $h .= "<div align=\"center\">\n";
+ $h .= dijitButton('', "Close", "dijit.byId('groupingnote').hide();");
+ $h .= "</div>\n"; # btn div
+ $h .= "</div>\n"; # groupingnote
+
+ $h .= "<div dojoType=dijit.Dialog\n";
+ $h .= " id=\"groupdlg\"\n";
+ $h .= " title=\"Computer Grouping\"\n";
+ $h .= " duration=250\n";
+ $h .= " draggable=true>\n";
+ $h .= "<div id=\"groupdlgcontent\"></div>\n";
+ $h .= "<div align=\"center\">\n";
+ $script = " dijit.byId('groupdlg').hide();\n";
+ $script .= " checkFirstAdd();\n";
+ $h .= dijitButton('', "Close", $script);
+ $h .= "</div>\n"; # btn div
+ $h .= "</div>\n"; # groupdlg
+ return $h;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ ///
+ /// \fn AJeditResource()
+ ///
+ /// \brief sends data for editing a resource
+ ///
+ /////////////////////////////////////////////////////////////////////////////
+ function AJeditResource() {
+ $rscid = processInputVar('rscid', ARG_NUMERIC);
+ $resources = getUserResources(array($this->restype . 'Admin'), array('administer'), 0, 1);
+ if(! array_key_exists($rscid, $resources[$this->restype])) {
+ $ret = array('status' => 'noaccess');
+ sendJSON($ret);
+ return;
+ }
+ $this->jsondata['showcancel'] = 0;
+ $query = "SELECT UNIX_TIMESTAMP(rq.start) AS start "
+ . "FROM request rq, "
+ . "reservation rs, "
+ . "state ls, "
+ . "state cs "
+ . "WHERE rs.requestid = rq.id AND "
+ . "rs.computerid = $rscid AND "
+ . "rq.laststateid = ls.id AND "
+ . "rq.stateid = cs.id AND "
+ . "ls.name = 'tovmhostinuse' AND "
+ . "cs.name NOT IN ('failed', 'maintenance', 'complete', 'deleted') AND "
+ . "rq.end > NOW() "
+ . "ORDER BY rq.start "
+ . "LIMIT 1";
+ $qh = doQuery($query);
+ if($row = mysql_fetch_assoc($qh)) {
+ $cdata = $this->basecdata;
+ $cdata['compid'] = $rscid;
+ $cont = addContinuationsEntry('AJcanceltovmhostinuse', $cdata, 300, 1, 0);
+ $this->jsondata['tohostcancelcont'] = $cont;
+ $this->jsondata['showcancel'] = 1;
+ $this->jsondata['tohoststart'] = date('g:i A \o\n l, F jS, Y', $row['start']);
+ if($row['start'] > time())
+ $this->jsondata['tohostfuture'] = 1;
+ else
+ $this->jsondata['tohostfuture'] = 0;
+ }
+ parent::AJeditResource();
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ ///
+ /// \fn AJsaveResource()
+ ///
+ /// \brief saves changes to resource
+ ///
+ /////////////////////////////////////////////////////////////////////////////
+ function AJsaveResource() {
+ global $user;
+ $add = getContinuationVar('add', 0);
+ $data = $this->validateResourceData();
+ if($data['error']) {
+ $ret = array('status' => 'error', 'msg' => $data['errormsg']);
+ sendJSON($ret);
+ return;
+ }
+
+ $promptuser = 0;
+ $promptuserfail = 0;
+ $multirefresh = 0;
+
+ if($add) {
+ if(! $data['rscid'] = $this->addResource($data)) {
+ sendJSON(array('status' => 'adderror',
+ 'errormsg' => 'Error encountered while trying to create new computer(s).<br>Please contact an admin for assistance.'));
+ return;
+ }
+ }
+ else {
+ $olddata = getContinuationVar('olddata');
+ $updates = array();
+ # hostname
+ if($data['name'] != $olddata['hostname'])
+ $updates[] = "hostname = '{$data['name']}'";
+
+ # ownerid
+ $ownerid = getUserlistID($data['owner']);
+ if($ownerid != $olddata['ownerid'])
+ $updates[] = "ownerid = $ownerid";
+
+ # cores
+ if($data['cores'] != $olddata['procnumber'])
+ $updates[] = "procnumber = '{$data['cores']}'";
+
+ # eth0macaddress
+ if($data['eth0macaddress'] != $olddata['eth0macaddress']) {
+ if($data['eth0macaddress'] == '')
+ $updates[] = "eth0macaddress = NULL";
+ else
+ $updates[] = "eth0macaddress = '{$data['eth0macaddress']}'";
+ }
+
+ # eth1macaddress
+ if($data['eth1macaddress'] != $olddata['eth1macaddress']) {
+ if($data['eth1macaddress'] == '')
+ $updates[] = "eth1macaddress = NULL";
+ else
+ $updates[] = "eth1macaddress = '{$data['eth1macaddress']}'";
+ }
+
+ # other fields
+ $fields = array('type', 'IPaddress', 'privateIPaddress',
+ 'provisioningid', 'platformid', 'scheduleid', 'ram',
+ 'procspeed', 'network', 'location');
+ foreach($fields as $field) {
+ if($data[$field] != $olddata[$field])
+ $updates[] = "`$field` = '{$data[$field]}'";
+ }
+
+ # notes
+ # staying in maintenance
+ if($olddata['stateid'] == 10 && $data['stateid'] == 10) {
+ $testnotes = $olddata['notes'];
+ # check for notes being changed
+ if(strpos($testnotes, '@') === true) {
+ $tmp = explode('@', $olddata['notes']);
+ $testnotes = $tmp[1];
+ }
+ if($testnotes != $data['notes']) {
+ $ts = unixToDatetime(time());
+ $updates[] = "notes = '{$user['unityid']} $ts@{$data['notes']}'";
+ }
+ }
+ # changing to maintenance
+ elseif($data['stateid'] == 10) {
+ $ts = unixToDatetime(time());
+ $updates[] = "notes = '{$user['unityid']} $ts@{$data['notes']}'";
+ }
+ # removing from maintenance
+ elseif($olddata['stateid'] == 10 && $data['stateid'] != 10) {
+ $updates[] = "notes = ''";
+ }
+
+ # stateid - if moving from vmhostinuse or reloading with a new image,
+ # make sure no reservations for VMs
+ if($olddata['stateid'] == 10 && $data['stateid'] == 20) {
+ $query = "SELECT vm.id "
+ . "FROM computer vm, "
+ . "vmhost v "
+ . "WHERE v.computerid = {$data['rscid']} AND "
+ . "vm.vmhostid = v.id AND "
+ . "vm.notes = 'maintenance with host {$data['rscid']}' AND "
+ . "vm.stateid = 10";
+ $qh = doQuery($query);
+ $vmids = array();
+ while($row = mysql_fetch_assoc($qh))
+ $vmids[] = $row['id'];
+ $allids = implode(',', $vmids);
+ if($data['provisioning'] != 'none') {
+ $profiles = getVMProfiles();
+ if(! array_key_exists('vmprofileid', $olddata) ||
+ $olddata['vmprofileid'] == '' ||
+ $profiles[$olddata['vmprofileid']]['imageid'] !=
+ $profiles[$data['vmprofileid']]['imageid']) {
+ # VCL provisioned, different image
+ # schedule VM host to be reloaded
+ $profiles = getVMProfiles($data['vmprofileid']);
+ $imageid = $profiles[$data['vmprofileid']]['imageid'];
+ $start = getReloadStartTime();
+ $rc = $this->scheduleTovmhostinuse($data['rscid'], $imageid, $start,
+ $data['vmprofileid'], $olddata['vmprofileid']);
+
+ if($rc == 0) {
+ $msg = '';
+ if(count($updates))
+ $msg .= "Computer information changes were saved.<br>\nHowever, a ";
+ else
+ $msg .= "A ";
+ $msg .= "problem was encountered while attempting to reload the ";
+ $msg .= "computer with the selected VM Host Profile. Please try ";
+ $msg .= "again at a later time.\n";
+ $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg);
+ $promptuserfail = 1;
+ $title = 'VM Host Reload Failed';
+ }
+ else {
+ if(count($vmids))
+ $this->scheduleVMsToAvailable($vmids);
+ $multirefresh = 3;
+ }
+ }
+ else {
+ # VCL provisioned, same image
+ $msg = '';
+ if(count($updates))
+ $msg .= "Computer information changes saved.<br><br>\nHowever, this ";
+ else
+ $msg .= "This ";
+ $msg .= "computer was previously in the vmhostinuse state. ";
+ $msg .= "You can:<br><br>\n";
+ $msg .= "<input type=\"radio\" name=\"mode\" value=\"vmhostinuse\" ";
+ $msg .= "id=\"modedirect\" checked=\"checked\"><label ";
+ $msg .= "for=\"modereload\">Move it directly back to vmhostinuse\n";
+ $msg .= "</label><br>\n";
+ $msg .= "<input type=\"radio\" name=\"mode\" value=\"reload\" ";
+ $msg .= "id=\"modereload\"><label for=\"modereload\">Have it reloaded ";
+ $msg .= "and then placed back into vmhostinuse</label><br><br>\n";
+ $promptuser = 1;
+ $cdata = $this->basecdata;
+ $cdata['compid'] = $data['rscid'];
+ $cdata['imageid'] = $profiles[$data['vmprofileid']]['imageid'];
+ $cdata['oldprofileid'] = $olddata['vmprofileid'];
+ $cdata['vmprofileid'] = $data['vmprofileid'];
+ $cdata['newstateid'] = $data['stateid'];
+ $cdata['oldstateid'] = $olddata['stateid'];
+ $cdata['vmids'] = $vmids;
+ $promptcont = addContinuationsEntry('AJsubmitComputerStateLater', $cdata, SECINDAY, 1, 0);
+ $btntxt = 'Submit';
+ $title = 'State Change Option';
+ }
+ $data['stateid'] = $olddata['stateid']; # prevent state from being updated directly
+ }
+ elseif(count($vmids)) {
+ $query = "UPDATE computer "
+ . "SET stateid = 2, "
+ . "notes = '' "
+ . "WHERE id in ($allids)";
+ doQuery($query);
+ $multirefresh = 1;
+ }
+ }
+ elseif($olddata['stateid'] != 20 && $data['stateid'] == 20) {
+ # check for reservations
+ moveReservationsOffComputer($data['rscid']);
+ cleanSemaphore();
+ $reloadstart = getCompFinalReservationTime($data['rscid'], 21);
+ $checkstart = getExistingChangeStateStartTime($data['rscid'], 21);
+ if($data['provisioning'] != 'none') {
+ # VCL provisioned
+ $profiles = getVMProfiles($data['vmprofileid']);
+ $imageid = $profiles[$data['vmprofileid']]['imageid'];
+ if($reloadstart) {
+ if($checkstart && $checkstart < $reloadstart)
+ $reloadstart = $checkstart;
+ # reservations, must wait until end time
+ $end = date('n/j/y g:i a', $reloadstart);
+ $msg = '';
+ if(count($updates))
+ $msg .= "Computer information changes saved.<br>\nHowever, this ";
+ else
+ $msg .= "This ";
+ $msg .= "computer is currently allocated until $end and cannot ";
+ $msg .= "be reloaded until then. You can:\n";
+ $msg .= "<ul><li>Cancel and try later</li>\n";
+ $msg .= "<li>Schedule the computer to be reloaded with the selected ";
+ $msg .= "profile at $end</li></ul>\n";
+ $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg);
+ $msg = preg_replace("|$end|", "<strong>$end</strong>", $msg, 1);
+ $promptuser = 1;
+ $cdata = $this->basecdata;
+ $cdata['maintenanceonly'] = 0;
+ $cdata['compid'] = $data['rscid'];
+ $cdata['reloadstart'] = $reloadstart;
+ $cdata['imageid'] = $imageid;
+ $cdata['oldprofileid'] = $olddata['vmprofileid'];
+ $cdata['vmprofileid'] = $data['vmprofileid'];
+ $cdata['newstateid'] = $data['stateid'];
+ $cdata['oldstateid'] = $olddata['stateid'];
+ $promptcont = addContinuationsEntry('AJsubmitComputerStateLater', $cdata, SECINDAY, 1, 0);
+ $btntxt = 'Schedule Reload';
+ $title = 'Delayed State Change';
+ }
+ else {
+ # no reservations
+ $start = getReloadStartTime();
+ $checkstart = getExistingChangeStateStartTime($data['rscid'], 21);
+ if($checkstart && $checkstart < $start)
+ $start = $checkstart;
+ $rc = $this->scheduleTovmhostinuse($data['rscid'], $imageid, $start,
+ $data['vmprofileid'], $olddata['vmprofileid']);
+
+ if($rc == 0) {
+ $msg = '';
+ if(count($updates))
+ $msg .= "Computer information changes were saved.<br>\nHowever, a ";
+ else
+ $msg .= "A ";
+ $msg .= "problem was encountered while attempting to reload the ";
+ $msg .= "computer with the selected VM Host Profile. Please try ";
+ $msg .= "again at a later time.\n";
+ $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg);
+ $promptuserfail = 1;
+ $title = 'VM Host Reload Failed';
+ }
+ else
+ $multirefresh = 3;
+ }
+ $data['stateid'] = $olddata['stateid']; # prevent state from being updated directly
+ }
+ else {
+ # manually provisioned
+ if($reloadstart) {
+ # reservations, must wait until end time
+ $end = date('n/j/y g:i a', $reloadstart);
+ $msg = '';
+ if(count($updates))
+ $msg .= "Computer information changes saved.<br>\nHowever, this ";
+ else
+ $msg .= "This ";
+ $msg .= "computer is currently allocated until $end and cannot ";
+ $msg .= "be converted to a VM host until then. You can:\n";
+ $msg .= "<ul><li>Cancel and do nothing</li>\n";
+ $msg .= "<li>Schedule the computer to go in to maintenance at $end ";
+ $msg .= "and manually move it to vmhostinuse after that</li></ul>\n";
+ $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg);
+ $msg = preg_replace("|$end|", "<strong>$end</strong>", $msg, 1);
+ $promptuser = 1;
+ $cdata = $this->basecdata;
+ $cdata['maintenanceonly'] = 1;
+ $cdata['reloadstart'] = $reloadstart;
+ $cdata['imageid'] = getImageId('noimage');
+ $cdata['compid'] = $data['rscid'];
+ $cdata['newstateid'] = $data['stateid'];
+ $cdata['oldstateid'] = $olddata['stateid'];
+ $promptcont = addContinuationsEntry('AJsubmitComputerStateLater', $cdata, SECINDAY, 1, 0);
+ $btntxt = 'Schedule State Change';
+ $title = 'Delayed State Change';
+ $data['stateid'] = $olddata['stateid']; # prevent state from being updated yet
+ }
+ else {
+ # no reservations
+ $this->updateVmhostProfile($data['rscid'], $data['vmprofileid'], $olddata['vmprofileid']);
+ }
+ }
+ }
+ elseif($olddata['stateid'] == 20 && $data['stateid'] == 2) {
+ # only valid condition for VCL provisioned
+ # check for reservations
+ moveReservationsOffVMs($data['rscid']);
+ cleanSemaphore();
+ $reloadstart = getCompFinalVMReservationTime($data['rscid'], 1);
+ if($reloadstart == -1) {
+ $msg = '';
+ if(count($updates))
+ $msg .= "Computer information changes were saved.<br>\nHowever, a ";
+ else
+ $msg .= "A ";
+ $msg .= "problem was encountered while attempting to move VMs ";
+ $msg .= "off of the computer. Please try again at a later time.\n";
+ $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg);
+ $promptuserfail = 1;
+ $title = 'Change to Available Failed';
+ $data['stateid'] = $olddata['stateid'];
+ }
+ elseif($reloadstart > 0) {
+ cleanSemaphore();
+ $end = date('n/j/y g:i a', $reloadstart);
+ $msg = '';
+ if(count($updates))
+ $msg .= "Computer information changes saved.<br>\nHowever, this ";
+ else
+ $msg .= "This ";
+ $msg .= "computer currently has VMs with reservations on them until ";
+ $msg .= "$end and cannot be moved to the available state until then. ";
+ $msg .= "You can:\n";
+ $msg .= "<ul><li>Cancel and do nothing</li>\n";
+ $msg .= "<li>Schedule the VMs to be removed at $end and the computer ";
+ $msg .= "to be moved to available that</li></ul>\n";
+ $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg);
+ $msg = preg_replace("|$end|", "<strong>$end</strong>", $msg, 1);
+ $promptuser = 1;
+ $cdata = $this->basecdata;
+ $cdata['reloadstart'] = $reloadstart;
+ $cdata['imageid'] = getImageId('noimage');
+ $cdata['compid'] = $data['rscid'];
+ $cdata['newstateid'] = $data['stateid'];
+ $cdata['oldstateid'] = $olddata['stateid'];
+ $promptcont = addContinuationsEntry('AJsubmitComputerStateLater', $cdata, SECINDAY, 1, 0);
+ $btntxt = 'Schedule State Change';
+ $title = 'Delayed State Change';
+ $data['stateid'] = $olddata['stateid']; # prevent state from being updated yet
+ }
+ else {
+ # schedule tomaintenance reservations for VMs
+ # might be better to just directly move the VMs to the maintenance state
+ $vclreloadid = getUserlistID('vclreload@Local');
+ $imageid = getImageId('noimage');
+ $revid = getProductionRevisionid($imageid);
+ $start = getReloadStartTime();
+ $end = $start + SECINMONTH;
+ $startdt = unixToDatetime($start);
+ $enddt = unixToDatetime($end);
+ $query = "SELECT vm.id "
+ . "FROM computer vm, "
+ . "vmhost v "
+ . "WHERE v.computerid = {$data['rscid']} AND "
+ . "vm.vmhostid = v.id";
+ $qh = doQuery($query);
+ $fail = 0;
+ while($row = mysql_fetch_assoc($qh)) {
+ if(! simpleAddRequest($row['id'], $imageid, $revid, $startdt,
+ $enddt, 18, $vclreloadid)) {
+ $fail = 1;
+ break;
+ }
+ else
+ $multirefresh = 2;
+ }
+ cleanSemaphore();
+ if($fail) {
+ $data['stateid'] = $olddata['stateid']; # prevent state from being updated yet
+ $msg = '';
+ if(count($updates))
+ $msg .= "Computer information changes were saved.<br>\nHowever, a ";
+ else
+ $msg .= "A ";
+ $msg .= "problem was encountered while attempting to remove VMs ";
+ $msg .= "from the computer. Please try again at a later time.\n";
+ $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg);
+ $promptuserfail = 1;
+ $title = 'Change State to Available Failed';
+ }
+ }
+ }
+ elseif($olddata['stateid'] == 20 && $data['stateid'] == 10) {
+ # VCL provisioned and manually provisioned are the same
+ # check for reservations
+ moveReservationsOffVMs($data['rscid']);
+ cleanSemaphore();
+ $reloadstart = getCompFinalVMReservationTime($data['rscid'], 1, 1);
+ if($reloadstart == -1) {
+ $msg = '';
+ if(count($updates))
+ $msg .= "Computer information changes were saved.<br>\nHowever, a ";
+ else
+ $msg .= "A ";
+ $msg .= "problem was encountered while attempting to place assigned VMs ";
+ $msg .= "into the maintenance state. Please try again at a later time.\n";
+ $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg);
+ $promptuserfail = 1;
+ $title = 'Change to Maintenance Failed';
+ }
+ elseif($reloadstart > 0) {
+ cleanSemaphore();
+ $end = date('n/j/y g:i a', $reloadstart);
+ $msg = '';
+ if(count($updates))
+ $msg .= "Computer information changes saved.<br>\nHowever, this ";
+ else
+ $msg .= "This ";
+ $msg .= "computer currently has VMs with reservations on them until ";
+ $msg .= "$end and cannot be moved to the maintenance state until then. ";
+ $msg .= "You can:\n";
+ $msg .= "<ul><li>Cancel and do nothing</li>\n";
+ $msg .= "<li>Schedule the computer and VMs to be moved into the ";
+ $msg .= "maintenance state at $end</li></ul>\n";
+ $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg);
+ $msg = preg_replace("|$end|", "<strong>$end</strong>", $msg, 1);
+ $promptuser = 1;
+ $cdata = $this->basecdata;
+ $cdata['reloadstart'] = $reloadstart;
+ $cdata['imageid'] = getImageId('noimage');
+ $cdata['compid'] = $data['rscid'];
+ $cdata['newstateid'] = $data['stateid'];
+ $cdata['oldstateid'] = $olddata['stateid'];
+ $promptcont = addContinuationsEntry('AJsubmitComputerStateLater', $cdata, SECINDAY, 1, 0);
+ $btntxt = 'Schedule State Change';
+ $title = 'Delayed State Change';
+ $data['stateid'] = $olddata['stateid']; # prevent state from being updated yet
+ }
+ else {
+ $query = "UPDATE computer c "
+ . "INNER JOIN vmhost v ON (c.vmhostid = v.id) "
+ . "SET c.stateid = 10, "
+ . "c.notes = 'maintenance with host {$data['rscid']}' "
+ . "WHERE v.computerid = {$data['rscid']}";
+ doQuery($query);
+ cleanSemaphore();
+ $multirefresh = 1;
+ }
+ }
+ elseif($olddata['stateid'] == 10 && $data['stateid'] == 2) {
+ if(is_numeric($olddata['vmprofileid'])) {
+ $vclreloadid = getUserlistID('vclreload@Local');
+ $imageid = getImageId('noimage');
+ $revid = getProductionRevisionid($imageid);
+ $start = getReloadStartTime();
+ $end = $start + SECINMONTH;
+ $startdt = unixToDatetime($start);
+ $enddt = unixToDatetime($end);
+ # move VMs to reload state so vcld will not skip them due to being in maintenance
+ $query = "UPDATE computer c, "
+ . "vmhost v "
+ . "SET c.stateid = 19, "
+ . "c.notes = '' "
+ . "WHERE v.computerid = {$data['rscid']} AND "
+ . "c.vmhostid = v.id";
+ doQuery($query);
+ $query = "SELECT vm.id "
+ . "FROM computer vm, "
+ . "vmhost v "
+ . "WHERE v.computerid = {$data['rscid']} AND "
+ . "vm.vmhostid = v.id";
+ $qh = doQuery($query);
+ $fails = array();
+ while($row = mysql_fetch_assoc($qh)) {
+ if(! simpleAddRequest($row['id'], $imageid, $revid, $startdt,
+ $enddt, 18, $vclreloadid)) {
+ $fails[] = $row['id'];
+ }
+ else
+ $multirefresh = 2;
+ }
+ if(count($fails)) {
+ # just directly remove any VMs that failed to be scheduled
+ $query = "UPDATE computer "
+ . "SET stateid = 10, "
+ . "vmhostid = NULL, "
+ . "notes = '' "
+ . "WHERE id IN (" . implode(',', $fails) . ")";
+ doQuery($query);
+ }
+ }
+ }
+ elseif($olddata['stateid'] == 20 && $data['stateid'] == 20 &&
+ $olddata['vmprofileid'] != $data['vmprofileid']) {
+ if($data['provisioning'] != 'none') {
+ $profiles = getVMProfiles($data['vmprofileid']);
+ if($profiles[$olddata['vmprofileid']]['imageid'] ==
+ $profiles[$data['vmprofileid']]['imageid']) {
+ $query = "UPDATE vmhost "
+ . "SET vmprofileid = {$data['vmprofileid']} "
+ . "WHERE computerid = {$data['rscid']} AND "
+ . "vmprofileid = {$olddata['vmprofileid']}";
+ doQuery($query);
+ }
+ else {
+ moveReservationsOffVMs($data['rscid']);
+ cleanSemaphore();
+ $reloadstart = getCompFinalVMReservationTime($data['rscid'], 1);
+ if($reloadstart == -1) {
+ $msg = '';
+ if(count($updates))
+ $msg .= "Computer information changes were saved.<br>\nHowever, a ";
+ else
+ $msg .= "A ";
+ $msg .= "problem was encountered while attempting to place assigned ";
+ $msg .= "VMs into the maintenance state while reloading the computer. ";
+ $msg .= "Please try again at a later time.\n";
+ $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg);
+ $promptuserfail = 1;
+ $title = 'Change VM Host Profile Failed';
+ }
+ elseif($reloadstart > 0) {
+ cleanSemaphore();
+ $end = date('n/j/y g:i a', $reloadstart);
+ $msg = '';
+ if(count($updates))
+ $msg .= "Computer information changes saved.<br>\nHowever, this ";
+ else
+ $msg .= "This ";
+ $msg .= "computer must be reloaded to change to the selected VM Host ";
+ $msg .= "Profile and there are VMs on it with reservations until $end. ";
+ $msg .= "You can:\n";
+ $msg .= "<ul><li>Cancel and do nothing</li>\n";
+ $msg .= "<li>Schedule the VMs to be removed and the computer to be ";
+ $msg .= "reloaded at $end</li></ul>\n";
+ $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg);
+ $msg = preg_replace("|$end|", "<strong>$end</strong>", $msg, 1);
+ $promptuser = 1;
+ $cdata = $this->basecdata;
+ $cdata['reloadstart'] = $reloadstart;
+ $cdata['imageid'] = $profiles[$data['vmprofileid']]['imageid'];
+ $cdata['compid'] = $data['rscid'];
+ $cdata['newstateid'] = $data['stateid'];
+ $cdata['oldstateid'] = $olddata['stateid'];
+ $cdata['oldprofileid'] = $olddata['vmprofileid'];
+ $cdata['vmprofileid'] = $data['vmprofileid'];
+ $promptcont = addContinuationsEntry('AJsubmitComputerStateLater', $cdata, SECINDAY, 1, 0);
+ $btntxt = 'Schedule Reload';
+ $title = 'Delayed VM Host Profile Change';
+ }
+ else {
+ # schedule VMs to be removed
+ $vclreloadid = getUserlistID('vclreload@Local');
+ $imageid = getImageId('noimage');
+ $revid = getProductionRevisionid($imageid);
+ $start = getReloadStartTime();
+ $end = $start + SECINMONTH;
+ $startdt = unixToDatetime($start);
+ $enddt = unixToDatetime($end);
+ $query = "SELECT vm.id "
+ . "FROM computer vm, "
+ . "vmhost v "
+ . "WHERE v.computerid = {$data['rscid']} AND "
+ . "vm.vmhostid = v.id";
+ $qh = doQuery($query);
+ $fails = array();
+ $cnt = 0;
+ while($row = mysql_fetch_assoc($qh)) {
+ $cnt++;
+ if(! simpleAddRequest($row['id'], $imageid, $revid, $startdt,
+ $enddt, 18, $vclreloadid)) {
+ $fails[] = $row['id'];
+ }
+ }
+ if(count($fails)) {
+ # just directly remove any VMs that failed to be scheduled
+ $query = "UPDATE computer "
+ . "SET stateid = 10, "
+ . "vmhostid = NULL, "
+ . "notes = '' "
+ . "WHERE id IN (" . implode(',', $fails) . ")";
+ doQuery($query);
+ }
+ cleanSemaphore();
+
+ # schedule host to be reloaded
+ if($cnt)
+ $start = time() + 120; # allow 2 minutes for VMs to be removed
+ $rc = $this->scheduleTovmhostinuse($data['rscid'],
+ $profiles[$data['vmprofileid']]['imageid'],
+ $start, $data['vmprofileid'],
+ $olddata['vmprofileid']);
+
+ if($rc == 0) {
+ $msg = '';
+ if(count($updates))
+ $msg .= "Computer information changes were saved.<br>\nHowever, a ";
+ else
+ $msg .= "A ";
+ $msg .= "problem was encountered while attempting to reload the ";
+ $msg .= "computer with the selected VM Host Profile. Please try ";
+ $msg .= "again at a later time.\n";
+ $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg);
+ $promptuserfail = 1;
+ $title = 'VM Host Reload Failed';
+ }
+ else
+ $multirefresh = 3;
+ }
+ }
+ }
+ else {
+ $query = "UPDATE vmhost "
+ . "SET vmprofileid = {$data['vmprofileid']} "
+ . "WHERE computerid = {$data['rscid']} AND "
+ . "vmprofileid = {$olddata['vmprofileid']}";
+ doQuery($query);
+ }
+ }
+ elseif($olddata['stateid'] != 10 && $data['stateid'] == 10) {
+ moveReservationsOffComputer($data['rscid']);
+ cleanSemaphore();
+ $reloadstart = getCompFinalReservationTime($data['rscid']);
+ if($reloadstart) {
+ $end = date('n/j/y g:i a', $reloadstart);
+ $msg = '';
+ if(count($updates))
+ $msg .= "Computer information changes saved.<br>\nHowever, this ";
+ else
+ $msg .= "This ";
+ $msg .= "computer has reservations on it until $end. You can:\n";
+ $msg .= "<ul><li>Cancel and do nothing</li>\n";
+ $msg .= "<li>Schedule the computer to be moved to maintenance at ";
+ $msg .= "$end</li></ul>\n";
+ $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg);
+ $msg = preg_replace("|$end|", "<strong>$end</strong>", $msg, 1);
+ $promptuser = 1;
+ $cdata = $this->basecdata;
+ $cdata['reloadstart'] = $reloadstart;
+ $cdata['imageid'] = getImageId('noimage');
+ $cdata['compid'] = $data['rscid'];
+ $cdata['newstateid'] = $data['stateid'];
+ $cdata['oldstateid'] = $olddata['stateid'];
+ $promptcont = addContinuationsEntry('AJsubmitComputerStateLater', $cdata, SECINDAY, 1, 0);
+ $btntxt = 'Schedule Maintenance';
+ $title = 'Delayed Maintenance';
+ }
+ # else let UPDATE move it to maintenance
+ }
+
+ # stateid
+ if($data['stateid'] != $olddata['stateid'])
+ $updates[] = "stateid = {$data['stateid']}";
+
+ if(count($updates)) {
+ $query = "UPDATE computer SET "
+ . implode(', ', $updates)
+ . " WHERE id = {$data['rscid']}";
+ doQuery($query);
+ }
+ }
+
+ # clear user resource cache for this type
+ $key = getKey(array(array($this->restype . "Admin"), array("administer"), 0, 1, 0));
+ unset($_SESSION['userresources'][$key]);
+ $key = getKey(array(array($this->restype . "Admin"), array("administer"), 0, 0, 0));
+ unset($_SESSION['userresources'][$key]);
+ $key = getKey(array(array($this->restype . "Admin"), array("manageGroup"), 0, 1, 0));
+ unset($_SESSION['userresources'][$key]);
+ $key = getKey(array(array($this->restype . "Admin"), array("manageGroup"), 0, 0, 0));
+ unset($_SESSION['userresources'][$key]);
+
+ $args = $this->defaultGetDataArgs;
+ $arr = array('status' => 'success');
+ if(is_array($data['rscid'])) {
+ $tmp = $this->getData($args);
+ $arr['addmode'] = 'multiple';
+ $arr['data'] = array();
+ foreach($data['rscid'] as $compid) {
+ $tmp[$compid]['name'] = $tmp[$compid]['hostname'];
+ $arr['data'][] = $tmp[$compid];
+ }
+ $arr['grouphelp'] = "Select groups from the list on the right and click the "
+ . "Add button to add the new computer set to those groups.<br><br>";
+ $cdata = $this->basecdata;
+ $cdata['newids'] = $data['rscid'];
+ $cdata['mode'] = 'add';
+ $arr['addcont'] = addContinuationsEntry('AJaddRemGroupResource', $cdata);
+ $cdata['mode'] = 'remove';
+ $arr['remcont'] = addContinuationsEntry('AJaddRemGroupResource', $cdata);
+ }
+ else {
+ if($add)
+ $arr['addmode'] = 'single';
+ $args['rscid'] = $data['rscid'];
+ $tmp = $this->getData($args);
+ $data = $tmp[$data['rscid']];
+ $arr['data'] = $data;
+ $arr['data']['name'] = $arr['data']['hostname'];
+ }
+ if($add) {
+ $arr['action'] = 'add';
+ $arr['nogroups'] = 0;
+ $groups = getUserResources(array($this->restype . 'Admin'), array('manageGroup'), 1);
+ if(count($groups[$this->restype]))
+ $arr['groupingHTML'] = $this->groupByResourceHTML();
+ else
+ $arr['nogroups'] = 1;
+ }
+ else
+ $arr['action'] = 'edit';
+ if($promptuser) {
+ $arr['promptuser'] = 1;
+ $arr['btntxt'] = $btntxt;
+ $arr['title'] = $title;
+ $arr['msg'] = $msg;
+ $arr['cont'] = $promptcont;
+ }
+ elseif($promptuserfail) {
+ $arr['promptuserfail'] = 1;
+ $arr['title'] = $title;
+ $arr['msg'] = $msg;
+ }
+ if($multirefresh)
+ $arr['multirefresh'] = $multirefresh;
+ sendJSON($arr);
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ ///
+ /// \fn validateResourceData()
+ ///
+ /// \return array with these fields:\n
+ /// \b rscid - id of resource (from computer table)\n
+ /// \b name - hostname of computer\n
+ /// \b startnum - start number when doing multiple add\n
+ /// \b endnum - end number when doing multiple add\n
+ /// \b owner\n
+ /// \b type - type of computer\n
+ /// \b IPaddress - public IP address\n
+ /// \b privateIPaddress - private IP address\n
+ /// \b eth0macaddress - public MAC address\n
+ /// \b eth1macaddress - private MAC address\n
+ /// \b startpubipaddress - start public IP address when doing multiple add\n
+ /// \b endpubipaddress - end public IP address when doing multiple add\n
+ /// \b startprivipaddress - start private IP address when doing multiple
+ /// add\n
+ /// \b endprivipaddress - end private IP address when doing multiple add\n
+ /// \b startmac - start MAC address when doing multiple add\n
+ /// \b provisioningid - id of provisioning engine for computer(s)\n
+ /// \b stateid - id for state of computer\n
+ /// \b notes - maintenance notes when setting computer to maintenance state\n
+ /// \b vmprofileid - id of vmprofile when setting to vmhostinuse state\n
+ /// \b platformid - id of platform\n
+ /// \b scheduleid - id of schedule\n
+ /// \b ram\n
+ /// \b cores\n
+ /// \b procspeed\n
+ /// \b network\n
+ /// \b location - free string describing location\n
+ /// \b mode - 'edit' or 'add'\n
+ /// \b addmode - 'single' or 'multiple'\n
+ /// \b startpubiplong - numeric value for start public IP address when doing
+ /// multiple add\n
+ /// \b endpubiplong - numeric value for end public IP address when doing
+ /// multiple add\n
+ /// \b startpriviplong - numeric value for start private IP address when
+ /// doing multiple add\n
+ /// \b endpriviplong - numeric value for end private IP address when doing
+ /// multiple add\n
+ /// \b error - 0 if submitted data validates; 1 if anything is invalid\n
+ /// \b errormsg - if error = 1; string of error messages separated by html
+ /// break tags
+ ///
+ /// \brief validates form input from editing or adding a computer
+ ///
+ /////////////////////////////////////////////////////////////////////////////
+ function validateResourceData() {
+ global $user;
+
+ $return = array('error' => 0);
+
+ $return['rscid'] = getContinuationVar('rscid', 0);
+ $return['name'] = processInputVar('name', ARG_STRING);
+ $return['startnum'] = processInputVar('startnum', ARG_NUMERIC);
+ $return['endnum'] = processInputVar('endnum', ARG_NUMERIC);
+ $return['owner'] = processInputVar('owner', ARG_STRING, "{$user['unityid']}@{$user['affiliation']}");
+ $return['type'] = processInputVar('type', ARG_STRING);
+ $return['IPaddress'] = processInputVar('ipaddress', ARG_STRING);
+ $return['privateIPaddress'] = processInputVar('privateipaddress', ARG_STRING);
+ $return['eth0macaddress'] = processInputVar('privatemac', ARG_STRING);
+ $return['eth1macaddress'] = processInputVar('publicmac', ARG_STRING);
+ $return['startpubipaddress'] = processInputVar('startpubipaddress', ARG_STRING);
+ $return['endpubipaddress'] = processInputVar('endpubipaddress', ARG_STRING);
+ $return['startprivipaddress'] = processInputVar('startprivipaddress', ARG_STRING);
+ $return['endprivipaddress'] = processInputVar('endprivipaddress', ARG_STRING);
+ $return['startmac'] = processInputVar('startmac', ARG_STRING);
+ $return['provisioningid'] = processInputVar('provisioningid', ARG_NUMERIC);
+ $return['stateid'] = processInputVar('stateid', ARG_NUMERIC);
+ $return['notes'] = processInputVar('notes', ARG_STRING);
+ $return['vmprofileid'] = processInputVar('vmprofileid', ARG_NUMERIC);
+ $return['platformid'] = processInputVar('platformid', ARG_NUMERIC);
+ $return['scheduleid'] = processInputVar('scheduleid', ARG_NUMERIC);
+ $return['ram'] = processInputVar('ram', ARG_NUMERIC);
+ $return['cores'] = processInputVar('cores', ARG_NUMERIC);
+ $return['procspeed'] = processInputVar('procspeed', ARG_NUMERIC);
+ $return['network'] = processInputVar('network', ARG_NUMERIC);
+ $return['location'] = processInputVar('location', ARG_STRING);
+ $addmode = processInputVar('addmode', ARG_STRING);
+
+ if(! is_null($addmode) && $addmode != 'single' && $addmode != 'multiple') {
+ $return['error'] = 1;
+ $return['errormsg'] = "Invalid Add mode submitted";
+ return $return;
+ }
+
+ $olddata = getContinuationVar('olddata');
+
+ if($return['rscid'] == 0)
+ $return['mode'] = 'add';
+ else
+ $return['mode'] = 'edit';
+
+ $errormsg = array();
+
+ # hostname
+ $hostreg = '/^[a-zA-Z0-9_][-a-zA-Z0-9_\.]{1,49}$/';
+ if($return['mode'] == 'add' && $addmode == 'multiple')
+ $hostreg = '/^[a-zA-Z0-9_%][-a-zA-Z0-9_\.%]{1,49}$/';
+ if(! preg_match($hostreg, $return['name'])) {
+ $return['error'] = 1;
+ $errormsg[] = "Hostname can only contain letters, numbers, dashes(-), periods(.), and underscores(_). It can be from 1 to 50 characters long";
+ }
+ elseif($this->checkForHostname($return['name'], $return['rscid'])) {
+ $return['error'] = 1;
+ $errormsg[] = "A computer already exists with this hostname.";
+ }
+ # add multiple
+ if($return['mode'] == 'add' && $addmode == 'multiple') {
+ # startnum/endnum
+ if($return['startnum'] < 0 || $return['startnum'] > 255) {
+ $return['error'] = 1;
+ $errormsg[] = "Start must be from 0 to 255";
+ }
+ if($return['endnum'] < 0 || $return['endnum'] > 255) {
+ $return['error'] = 1;
+ $errormsg[] = "End must be from 0 to 255";
+ }
+ if($return['startnum'] >= 0 && $return['startnum'] <= 255 &&
+ $return['endnum'] >= 0 && $return['endnum'] <= 255 &&
+ $return['startnum'] > $return['endnum']) {
+ $return['error'] = 1;
+ $errormsg[] = "Start must be >= End";
+ }
+ $checkhosts = array();
+ for($i = $return['startnum']; $i <= $return['endnum']; $i++)
+ $checkhosts[] = str_replace('%', $i, $return['name']);
+ $allhosts = implode("','", $checkhosts);
+ $query = "SELECT hostname FROM computer "
+ . "WHERE hostname IN ('$allhosts') AND "
+ . "deleted = 0";
+ $qh = doQuery($query);
+ $exists = array();
+ while($row = mysql_fetch_assoc($qh))
+ $exists[] = $row['hostname'];
+ if(count($exists)) {
+ $hosts = implode(', ', $exists);
+ $return['error'] = 1;
+ $errormsg[] = "There are already computers with these hostnames: $hosts";
+ }
+ }
+ else {
+ $return['startnum'] = 0;
+ $return['endnum'] = 0;
+ }
+ # owner
+ if(! validateUserid($return['owner'])) {
+ $return['error'] = 1;
+ $errormsg[] = "Submitted owner is not valid";
+ }
+ # type
+ if(! preg_match('/^(blade|lab|virtualmachine)$/', $return['type'])) {
+ $return['error'] = 1;
+ $errormsg[] = "Submitted type is not valid";
+ }
+ # edit or add single
+ if($return['rscid'] || ($return['mode'] == 'add' && $addmode == 'single')) {
+ # ipaddress
+ if(! validateIPv4addr($return['IPaddress'])) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid Public IP address. Must be w.x.y.z with each of "
+ . "w, x, y, and z being between 1 and 255 (inclusive)";
+ }
+ # private ipaddress
+ if(strlen($return['privateIPaddress']) &&
+ ! validateIPv4addr($return['privateIPaddress'])) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid Private IP address. Must be w.x.y.z with each of "
+ . "w, x, y, and z being between 1 and 255 (inclusive)";
+ }
+ # eth0macaddress
+ if(strlen($return['eth0macaddress'])) {
+ if(! preg_match('/^(([A-Fa-f0-9]){2}:){5}([A-Fa-f0-9]){2}$/', $return["eth0macaddress"])) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid Private MAC address. Must be XX:XX:XX:XX:XX:XX "
+ . "with each pair of XX being from 00 to FF (inclusive)";
+ }
+ elseif($this->checkForMACaddress($return['eth0macaddress'], 0, $return['rscid'])) {
+ $return['error'] = 1;
+ $errormsg[] = "There is already a computer with this Private MAC address.";
+ }
+ }
+ # eth1macaddress
+ if(strlen($return['eth1macaddress'])) {
+ if(! preg_match('/^(([A-Fa-f0-9]){2}:){5}([A-Fa-f0-9]){2}$/', $return["eth1macaddress"])) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid Public MAC address. Must be XX:XX:XX:XX:XX:XX "
+ . "with each pair of XX being from 00 to FF (inclusive)";
+ }
+ elseif($this->checkForMACaddress($return['eth1macaddress'], 1, $return['rscid'])) {
+ $return['error'] = 1;
+ $errormsg[] = "There is already a computer with this Public MAC address.";
+ }
+ }
+ }
+ else {
+ $return['IPaddress'] = '';
+ $return['privateIPaddress'] = '';
+ $return['eth0macaddress'] = '';
+ $return['eth1macaddress'] = '';
+ }
+ # add multiple
+ if($return['mode'] == 'add' && $addmode == 'multiple') {
+ if(! validateIPv4addr($return['startpubipaddress'])) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid Start Public IP address. Must be w.x.y.z with each of "
+ . "w, x, y, and z being between 1 and 255 (inclusive)";
+ }
+ if(! validateIPv4addr($return['endpubipaddress'])) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid End Public IP address. Must be w.x.y.z with each of "
+ . "w, x, y, and z being between 1 and 255 (inclusive)";
+ }
+ if(! validateIPv4addr($return['startprivipaddress'])) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid Start Private IP address. Must be w.x.y.z with each of "
+ . "w, x, y, and z being between 1 and 255 (inclusive)";
+ }
+ if(! validateIPv4addr($return['endprivipaddress'])) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid End Private IP address. Must be w.x.y.z with each of "
+ . "w, x, y, and z being between 1 and 255 (inclusive)";
+ }
+ $startpubiplong = ip2long($return['startpubipaddress']);
+ $endpubiplong = ip2long($return['endpubipaddress']);
+ if($startpubiplong > $endpubiplong) {
+ $return['error'] = 1;
+ $errormsg[] = "Start Public IP Address must be lower or equal to End Public IP Address";
+ }
+ elseif(($endpubiplong - $startpubiplong) != ($return['endnum'] - $return['startnum'])) {
+ $return['error'] = 1;
+ $errormsg[] = "Public IP Address range does not equal Start/End range";
+ }
+ $startpriviplong = ip2long($return['startprivipaddress']);
+ $endpriviplong = ip2long($return['endprivipaddress']);
+ if($startpriviplong > $endpriviplong) {
+ $return['error'] = 1;
+ $errormsg[] = "Start Private IP Address must be lower or equal to End Private IP Address";
+ }
+ elseif(($endpriviplong - $startpriviplong) != ($return['endnum'] - $return['startnum'])) {
+ $return['error'] = 1;
+ $errormsg[] = "Private IP Address range does not equal Start/End range";
+ }
+ $return['startpubiplong'] = $startpubiplong;
+ $return['endpubiplong'] = $endpubiplong;
+ $return['startpriviplong'] = $startpriviplong;
+ $return['endpriviplong'] = $endpriviplong;
+ $cnt = $endpubiplong - $startpubiplong + 1;
+ if($return['startmac'] != '') {
+ if(! preg_match('/^(([A-Fa-f0-9]){2}:){5}([A-Fa-f0-9]){2}$/', $return['startmac'])) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid Start MAC address. Must be XX:XX:XX:XX:XX:XX "
+ . "with each pair of XX being from 00 to FF (inclusive)";
+ }
+ elseif($this->checkMultiAddMacs($return['startmac'], $cnt, $msg, $macs)) {
+ $return['error'] = 1;
+ $errormsg[] = $msg;
+ }
+ $return['macs'] = $macs;
+ }
+ else
+ $return['macs'] = array();
+ }
+ else {
+ $return['startpubipaddress'] = '';
+ $return['endpubipaddress'] = '';
+ $return['startprivipaddress'] = '';
+ $return['endprivipaddress'] = '';
+ $return['startmac'] = '';
+ }
+ # provisioningid
+ $provisioning = getProvisioning();
+ if(! array_key_exists($return['provisioningid'], $provisioning)) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid Provisioning Engine selected";
+ }
+ else
+ $return['provisioning'] = $provisioning[$return['provisioningid']]['name'];
+ # stateid 2 - available, 10 - maintenance, 20 - vmhostinuse
+ if(! preg_match('/^(2|10|20)$/', $return['stateid']) &&
+ $return['stateid'] != $olddata['stateid']) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid value submitted for State";
+ }
+ # validate type/provisioning combinations
+ $provtypes = getProvisioningTypes();
+ if($olddata['provisioningid'] != $return['provisioningid'] &&
+ ! array_key_exists($return['provisioningid'], $provtypes[$return['type']])) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid Provisioning Engine selected for computer type";
+ }
+ # validate type/provisioning/state combinations
+ if($olddata['stateid'] != $return['stateid']) {
+ if($return['type'] == 'lab') {
+ if($return['stateid'] != 2 && $return['stateid'] != 10) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid state submitted for computer type Lab";
+ }
+ }
+ elseif($return['type'] == 'virtualmachine') {
+ if($return['stateid'] != 10 &&
+ (! is_numeric($olddata['vmhostid']) || $return['stateid'] != 2)) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid state submitted for computer type Virtual Machine";
+ }
+ }
+ elseif($return['type'] == 'blade') {
+ if($provisioning[$return['provisioningid']]['name'] == 'none' &&
+ $return['stateid'] != 10 && $return['stateid'] != 20) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid state submitted for computer type Bare Metal";
+ }
+ }
+ }
+ # notes
+ if($return['stateid'] == 10) {
+ if(! preg_match('/^([-a-zA-Z0-9_\. ,#\(\)=\+:;]{0,5000})$/', $return['notes'])) {
+ $return['error'] = 1;
+ $errormsg[] = "Maintenance reason can be up to 5000 characters long and may only<br>contain letters, numbers, spaces and these characters: - , . _ # ( ) = + : ;";
+ }
+ }
+ else
+ $return['notes'] = '';
+ # vmprofileid
+ $profiles = getVMProfiles();
+ if($return['type'] == 'blade' && $return['stateid'] == 20 &&
+ ! array_key_exists($return['vmprofileid'], $profiles)) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid value submitted for VM Host Profile";
+ }
+ # platformid
+ $platforms = getPlatforms();
+ if(! array_key_exists($return['platformid'], $platforms)) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid value submitted for Platform";
+ }
+ # scheduleid
+ $schedules = getSchedules();
+ if(! array_key_exists($return['scheduleid'], $schedules)) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid value submitted for Schedule";
+ }
+ # ram
+ if($return['ram'] < 500 || $return['ram'] > 16777215) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid value submitted for RAM";
+ }
+ # cores
+ if($return['cores'] < 1 || $return['cores'] > 255) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid value submitted for No. Cores";
+ }
+ # procspeed
+ if($return['procspeed'] < 500 || $return['procspeed'] > 10000) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid value submitted for Processor Speed";
+ }
+ # network
+ if(! preg_match('/^(10|100|1000|10000|100000)$/', $return['network'])) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid value submitted for Network";
+ }
+ # location
+ if(! preg_match('/^([-a-zA-Z0-9_\. ,@#\(\)]{0,255})$/', $return['location'])) {
+ $return['error'] = 1;
+ $errormsg[] = "Invalid value submitted for Location";
+ }
+
+ if($return['mode'] == 'add')
+ $return['addmode'] = $addmode;
+
+ if($return['error'])
+ $return['errormsg'] = implode('<br>', $errormsg);
+
+ return $return;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ ///
+ /// \fn checkForHostname($hostname, $compid)
+ ///
+ /// \param $hostname - a computer hostname
+ /// \param $compid - (optional) a computer id to ignore
+ ///
+ /// \return 1 if $hostname is already in the computer table, 0 if not
+ ///
+ /// \brief checks for $hostname being somewhere in the computer table except
+ /// for $compid
+ ///
+ /////////////////////////////////////////////////////////////////////////////
+ function checkForHostname($hostname, $compid='') {
+ $query = "SELECT id FROM computer "
+ . "WHERE hostname = '$hostname' AND "
+ . "deleted = 0";
+ if(! empty($compid))
+ $query .= " AND id != $compid";
+ $qh = doQuery($query);
+ if(mysql_num_rows($qh))
+ return 1;
+ return 0;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ ///
+ /// \fn checkForMACaddress($mac, $num, $compid)
+ ///
+ /// \param $mac - computer mac address
+ /// \param $num - which mac address to check - 0 or 1
+ /// \param $compid - (optional) a computer id to ignore
+ ///
+ /// \return 1 if $mac/$num is already in the computer table, 0 if not
+ ///
+ /// \brief checks for $mac being somewhere in the computer table except
+ /// for $compid
+ ///
+ /////////////////////////////////////////////////////////////////////////////
+ function checkForMACaddress($mac, $num, $compid='') {
+ if($num == 0)
+ $field = 'eth0macaddress';
+ else
+ $field = 'eth1macaddress';
+ $query = "SELECT id FROM computer "
+ . "WHERE $field = '$mac' AND "
+ . "deleted = 0";
+ if(! empty($compid))
+ $query .= " AND id != $compid";
+ $qh = doQuery($query);
+ if(mysql_num_rows($qh))
+ return 1;
+ return 0;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ ///
+ /// \fn checkForIPaddress($ipaddress, $type, $compid)
+ ///
+ /// \param $ipaddress - a computer ip address
+ /// \param $type - 'public' or 'private' - which IP address to check
+ /// \param $compid - (optional) a computer id to ignore
+ ///
+ /// \return 1 if $ipaddress is already in the computer table, 0 if not
+ ///
+ /// \brief checks for $ipaddress being somewhere in the computer table except
+ /// for $compid
+ ///
+ /////////////////////////////////////////////////////////////////////////////
+ function checkForIPaddress($ipaddress, $type, $compid='') {
+ if($type == 'public')
+ $field = 'IPaddress';
+ else
+ $field = 'privateIPaddress';
+ $query = "SELECT id FROM computer "
+ . "WHERE $field = '$ipaddress'";
+ if(! empty($compid))
+ $query .= " AND id != $compid";
+ $qh = doQuery($query);
+ if(mysql_num_rows($qh))
+ return 1;
+ return 0;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ ///
+ /// \fn addResource($data)
+ ///
+ /// \param $data - array of needed data for adding a new resource
+ ///
+ /// \return id of new resource
+ ///
+ /// \brief handles adding a new computer and other associated data to the
+ /// database
+ ///
+ /////////////////////////////////////////////////////////////////////////////
+ function addResource($data) {
+ global $user;
+ $ownerid = getUserlistID($data['owner']);
+ $noimageid = getImageId('noimage');
+ $norevid = getProductionRevisionid($noimageid);
+ $keys = array('hostname', 'ownerid',
+ 'type', 'IPaddress',
+ 'privateIPaddress', 'eth0macaddress',
+ 'eth1macaddress', 'provisioningid',
+ 'stateid', 'platformid',
+ 'scheduleid', 'RAM',
+ 'procnumber', 'procspeed',
+ 'network', 'currentimageid',
+ 'imagerevisionid', 'location');
+ if($data['addmode'] == 'single') {
+ $eth0 = "'{$data['eth0macaddress']}'";
+ if($data['eth0macaddress'] == '')
+ $eth0 = 'NULL';
+ $eth1 = "'{$data['eth1macaddress']}'";
+ if($data['eth1macaddress'] == '')
+ $eth1 = 'NULL';
+ $values = array("'{$data['name']}'", $ownerid,
+ "'{$data['type']}'", "'{$data['IPaddress']}'",
+ "'{$data['privateIPaddress']}'", $eth0,
+ $eth1, $data['provisioningid'],
+ $data['stateid'], $data['platformid'],
+ $data['scheduleid'], $data['ram'],
+ $data['cores'], $data['procspeed'],
+ $data['network'], $noimageid,
+ $norevid, "'{$data['location']}'");
+
+ $query = "INSERT INTO computer ("
+ . implode(', ', $keys) . ") VALUES ("
+ . implode(', ', $values) . ")";
+ doQuery($query);
+
+ $rscid = dbLastInsertID();
+
+ # vmhost entry
+ if($data['stateid'] == '20') {
+ $query = "INSERT INTO vmhost "
+ . "(computerid, "
+ . "vmlimit, "
+ . "vmprofileid) "
+ . "VALUES ($rscid, "
+ . "5, "
+ . "{$data['vmprofileid']})";
+ doQuery($query);
+ }
+
+ // add entry in resource table
+ $query = "INSERT INTO resource "
+ . "(resourcetypeid, "
+ . "subid) "
+ . "VALUES (12, "
+ . "$rscid)";
+ doQuery($query);
+
+ return $rscid;
+ }
+ else {
+ # add multiple computers
+ $alldis = array();
+ for($i = $data['startnum'], $cnt = 0; $i <= $data['endnum']; $i++, $cnt++) {
+ $hostname = str_replace('%', $i, $data["name"]);
+ $pubip = long2ip($data['startpubiplong'] + $cnt);
+ $privip = long2ip($data['startpriviplong'] + $cnt);
+ if(count($data['macs'])) {
+ $eth0 = "'" . $data['macs'][$cnt * 2] . "'";
+ $eth1 = "'" . $data['macs'][($cnt * 2) + 1] . "'";
+ }
+ else {
+ $eth0 = 'NULL';
+ $eth1 = 'NULL';
+ }
+ $values = array("'$hostname'", $ownerid,
+ "'{$data['type']}'", "'$pubip'",
+ "'$privip'", $eth0,
+ $eth1, $data['provisioningid'],
+ $data['stateid'], $data['platformid'],
+ $data['scheduleid'], $data['ram'],
+ $data['cores'], $data['procspeed'],
+ $data['network'], $noimageid,
+ $norevid, "'{$data['location']}'");
+
+ $query = "INSERT INTO computer ("
+ . implode(', ', $keys) . ") VALUES ("
+ . implode(', ', $values) . ")";
+ doQuery($query);
+
+ $rscid = dbLastInsertID();
+
+ # vmhost entry
+ if($data['stateid'] == '20') {
+ $query = "INSERT INTO vmhost "
+ . "(computerid, "
+ . "vmlimit, "
+ . "vmprofileid) "
+ . "VALUES ($rscid, "
+ . "5, "
+ . "{$data['vmprofileid']})";
+ doQuery($query);
+ }
+
+ // add entry in resource table
+ $query = "INSERT INTO resource "
+ . "(resourcetypeid, "
+ . "subid) "
+ . "VALUES (12, "
+ . "$rscid)";
+ doQuery($query);
+
+ $allids[] = $rscid;
+ }
+ return $allids;
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ ///
+ /// \fn AJcanceltovmhostinuse()
+ ///
+ /// \brief cancels any reservations to place the computer in the vmhostinuse
+ /// state
+ ///
+ ////////////////////////////////////////////////////////////////////////////////
+ function AJcanceltovmhostinuse() {
+ global $mysql_link_vcl;
+ $compid = getContinuationVar('compid');
+ $type = 'none';
+ $query = "DELETE FROM request "
+ . "WHERE start > NOW() AND "
+ . "stateid = 21 AND "
+ . "id IN (SELECT requestid "
+ . "FROM reservation "
+ . "WHERE computerid = $compid)";
+ doQuery($query);
+ if(mysql_affected_rows($mysql_link_vcl))
+ $type = 'future';
+ $query = "UPDATE request rq, "
+ . "reservation rs, "
+ . "state ls "
+ . "SET rq.stateid = 1 "
+ . "WHERE rs.requestid = rq.id AND "
+ . "rs.computerid = $compid AND "
+ . "rq.start <= NOW() AND "
+ . "rq.laststateid = ls.id AND "
+ . "ls.name = 'tovmhostinuse'";
+ doQuery($query);
+ if(mysql_affected_rows($mysql_link_vcl))
+ $type = 'current';
+ $query = "SELECT rq.start "
+ . "FROM request rq, "
+ . "reservation rs, "
+ . "state ls, "
+ . "state cs "
+ . "WHERE rs.requestid = rq.id AND "
+ . "rs.computerid = $compid AND "
+ . "rq.laststateid = ls.id AND "
+ . "rq.stateid = cs.id AND "
+ . "ls.name = 'tovmhostinuse' AND "
+ . "cs.name NOT IN ('failed', 'maintenance', 'complete', 'deleted') AND "
+ . "rq.end > NOW() "
+ . "ORDER BY rq.start";
+ $qh = doQuery($query);
+ if(mysql_num_rows($qh))
+ $arr = array('status' => 'failed');
+ else {
+ if($type == 'now')
+ $msg = "The reservation currently being processed to place this "
+ . "computer in the vmhostinuse state has been flagged for "
+ . "deletion. As soon as the deletion can be processed, the "
+ . "computer will be set to the available state.";
+ else
+ $msg = "The reservation scheduled to place this computer in the "
+ . "vmhostinuse state has been deleted.";
+ $arr = array('status' => 'success', 'msg' => $msg);
+ }
+ sendJSON($arr);
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ ///
+ /// \fn scheduleTovmhostinuse($compid, $imageid, $start, $vmprofileid,
+ /// $oldvmprofileid)
+ ///
+ /// \param $compid - id of a computer
+ /// \param $imageid - id of an image
+ /// \param $start - start time in unix timestamp format
+ /// \param $vmprofileid - id of vmprofile
+ /// \param $oldvmprofileid - id of possible previous vmprofile
+ ///
+ /// \return 0 on failure, 1 on success
+ ///
+ /// \brief schedules or updates a reservation to move a host to the
+ /// vmhostinuse state
+ ///
+ /////////////////////////////////////////////////////////////////////////////
+ function scheduleTovmhostinuse($compid, $imageid, $start, $vmprofileid,
+ $oldvmprofileid) {
+ # create a reload reservation to load machine with image
+ # corresponding to selected vm profile
+ $vclreloadid = getUserlistID('vclreload@Local');
+ $revid = getProductionRevisionid($imageid);
+ $end = $start + SECINYEAR; # don't want anyone making a future reservation for this machine
+ $startdt = unixToDatetime($start);
+ $enddt = unixToDatetime($end);
+ $failed = 0;
+
+ $mnid = findManagementNode($compid, $startdt, 'now');
+ if($mnid == 0)
+ return 0;
+
+ # check for existing tovmhostinuse reservation
+ $query = "SELECT rq.id, "
+ . "rq.start, "
+ . "rq.end, "
+ . "rs.imageid "
+ . "FROM request rq, "
+ . "reservation rs "
+ . "WHERE rs.requestid = rq.id AND "
+ . "rs.computerid = $compid AND "
+ . "rq.stateid = 21 AND "
+ . "rq.start > NOW() "
+ . "ORDER BY rq.start "
+ . "LIMIT 1";
+ $qh = doQuery($query);
+ if($row = mysql_fetch_assoc($qh)) {
+ if(! retryGetSemaphore($imageid, $revid, $mnid, $compid, $startdt, $enddt, $row['id']))
+ return 0;
+ # update existing reservation
+ $updates = array();
+ $startts = datetimeToUnix($row['start']);
+ if($start < $startts)
+ $updates[] = "rq.start = '$startdt'";
+ elseif($start > $startts)
+ $this->startchange = $startts;
+ if($row['imageid'] != $imageid)
+ $updates[] = "rs.imageid = $imageid";
+ if(count($updates)) {
+ $query = "UPDATE request rq, "
+ . "reservation rs "
+ . "SET " . implode(',', $updates)
+ ." WHERE rs.requestid = rq.id AND "
+ . "rq.id = {$row['id']}";
+ doQuery($query);
+ }
+ }
+ else {
+ if(! retryGetSemaphore($imageid, $revid, $mnid, $compid, $startdt, $enddt))
+ return 0;
+ # add new reservation
+ if(! (simpleAddRequest($compid, $imageid, $revid, $startdt, $enddt, 21,
+ $vclreloadid)))
+ return 0;
+ }
+
+ cleanSemaphore();
+
+ $this->updateVmhostProfile($compid, $vmprofileid, $oldvmprofileid);
+
+ return 1;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ ///
+ /// \fn updateVmhostProfile($compid, $newprofileid, $oldprofileid)
+ ///
+ /// \param $compid - id of computer
+ /// \param $newprofileid - id of new vmprofile
+ /// \param $oldprofileid - id of possible previous vmprofile
+ ///
+ /// \brief updates a vmhost entry's vmprofileid or creates a new vmhost entry
+ ///
+ /////////////////////////////////////////////////////////////////////////////
+ function updateVmhostProfile($compid, $newprofileid, $oldprofileid) {
+ if(is_numeric($oldprofileid)) {
+ if($oldprofileid != $newprofileid) {
+ # update existing entry
+ $query = "UPDATE vmhost "
+ . "SET vmprofileid = $newprofileid "
+ . "WHERE computerid = $compid AND "
+ . "vmprofileid = $oldprofileid";
+ doQuery($query);
+ }
+ }
+ else {
+ # create vmhost entry
+ $query = "INSERT INTO vmhost "
+ . "(computerid, "
+ . "vmlimit, "
+ . "vmprofileid) "
+ . "VALUES ($compid, "
+ . "5, "
+ . "$newprofileid)";
+ doQuery($query);
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ ///
+ /// \fn AJsubmitComputerStateLater()
+ ///
+ /// \brief schedules a computer to be converted to another state at a future
+ /// time
+ ///
+ /////////////////////////////////////////////////////////////////////////////
+ function AJsubmitComputerStateLater() {
+ $compid = getContinuationVar('compid');
+ $maintenanceonly = getContinuationVar('maintenanceonly', 0);
+ $start = getContinuationVar('reloadstart');
+ $end = $start + SECINYEAR;
+ $startdt = unixToDatetime($start);
+ $enddt = unixToDatetime($end);
+ $vmprofileid = getContinuationVar('vmprofileid', 0);
+ $oldprofileid = getContinuationVar('oldprofileid', 0);
+ $newstateid = getContinuationVar('newstateid', 0);
+ $oldstateid = getContinuationVar('oldstateid', 0);
+ $imageid = getContinuationVar('imageid');
+ $revid = getProductionRevisionid($imageid);
+ $mode = processInputVar('mode', ARG_STRING);
+ $msg = '';
+ $refreshcount = 0;
+
+ if($oldstateid == 10 && $newstateid == 20 &&
+ ! is_null($mode) && $mode != 'direct' && $mode != 'reload') {
+ $errmsg = "Invalid information submitted";
+ $ret = array('status' => 'error',
+ 'errormsg' => $errmsg);
+ sendJSON($ret);
+ return;
+ }
+
+ $delayed = 0;
+
+ # maintenance directly back to vmhostinuse
+ if($mode == 'direct') {
+ $vmids = getContinuationVar('vmids');
+ if(count($vmids)) {
+ $allids = implode(',', $vmids);
+ $query = "UPDATE computer "
+ . "SET stateid = 2, "
+ . "notes = '' "
+ . "WHERE id in ($allids)";
+ doQuery($query);
+ }
+ $query = "UPDATE computer "
+ . "SET stateid = 20, "
+ . "notes = '' "
+ . "WHERE id = $compid";
+ doQuery($query);
+ $msg .= "The computer has been moved back to the vmhostinuse state and ";
+ $msg .= "the appropriate VMs have been moved to the available state.";
+ $title = "Change to vmhostinuse";
+ $refreshcount = 1;
+ }
+ # maintenance back to vmhostinuse with a reload
+ elseif($mode == 'reload') {
+ $vmids = getContinuationVar('vmids');
+ if(count($vmids))
+ $this->scheduleVMsToAvailable($vmids);
+ $start = getReloadStartTime();
+ $rc = $this->scheduleTovmhostinuse($compid, $imageid, $start,
+ $vmprofileid, $oldprofileid);
+
+ if($rc == 0) {
+ $errmsg .= "A problem was encountered while attempting to reload the ";
+ $errmsg .= "computer with the selected VM Host Profile. Please try ";
+ $errmsg .= "again at a later time.\n";
+ $errmsg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $errmsg);
+ $ret = array('status' => 'error',
+ 'errormsg' => $errmsg);
+ sendJSON($ret);
+ return;
+ }
+ $msg .= "The computer has been scheduled to go back to the vmhostinuse ";
+ $msg .= "state and the appropriate VMs have been scheduled to go back ";
+ $msg .= "to the available state at %s.";
+ $title = "Change to vmhostinuse";
+ }
+ # anything else to vmhostinuse
+ elseif($oldstateid != 20 && $newstateid == 20) {
+ moveReservationsOffComputer($compid);
+ cleanSemaphore();
+
+ $mnid = findManagementNode($compid, unixToDatetime($start), 'future');
+ $tmp = getCompFinalReservationTime($compid, 21);
+ $checkstart = getExistingChangeStateStartTime($compid, 21);
+ if(! $checkstart && $checkstart != $start && $tmp > $start) {
+ $delayed = 1;
+ $start = $tmp;
+ $end = $start + SECINYEAR;
+ $startdt = unixToDatetime($start);
+ $enddt = unixToDatetime($end);
+ }
+ $vclreloadid = getUserlistID('vclreload@Local');
+ if($maintenanceonly) {
[... 2117 lines stripped ...]