VCL-1126 - allocate computer already having specified IP address for server reservations with specified IP
OS.pm: modified confirm_fixed_ip_is_available: added $computer_id argument when calling is_ip_assigned_query; added check for assigned computer having specified IP address and if so, skip ping check
utils.pm: modified is_ip_assigned_query: added 2nd (optional) argument for a computer ID; if computer ID is passed in, don't include that computer in query results
utils.php:
-modified isAvailable: added check for any mapped computers already having the requested IP address, and if so, limit mapped computers to just those and set a flag that mapped computers have been limited; at first check for no computers being available if mapped computer flag is set, use -4 return code instead of 0; if mapped computer flag set, skip removing recently reserved computers that may have failed
-modified debugIsAvailable: changed message for case 2 to say an unavailable computer has the requested IP instead of stating an overlapping server reservation has the address assigned
diff --git a/managementnode/lib/VCL/Module/OS.pm b/managementnode/lib/VCL/Module/OS.pm
index 32c25cf..fb0d6ec 100644
--- a/managementnode/lib/VCL/Module/OS.pm
+++ b/managementnode/lib/VCL/Module/OS.pm
@@ -1424,12 +1424,19 @@
my $server_request_fixed_ip = $self->data->get_server_request_fixed_ip();
#check VCL computer table
- if (is_ip_assigned_query($server_request_fixed_ip)) {
+ if (is_ip_assigned_query($server_request_fixed_ip, $computer_id)) {
notify($ERRORS{'WARNING'}, 0, "$server_request_fixed_ip is already assigned");
insertloadlog($reservation_id, $computer_id, "failed","$server_request_fixed_ip is already assigned");
return 0;
}
+ #check if the assigned computer has the specified address
+ my $retrieved_public_ip_address = $self->get_public_ip_address();
+ if ($retrieved_public_ip_address eq $server_request_fixed_ip) {
+ notify($ERRORS{'DEBUG'}, 0, "$server_request_fixed_ip is assigned to reserved computer, skipping ping test");
+ return 1;
+ }
+
#Is IP pingable
if (_pingnode($server_request_fixed_ip)) {
notify($ERRORS{'WARNING'}, 0, "$server_request_fixed_ip is answering ping test");
diff --git a/managementnode/lib/VCL/utils.pm b/managementnode/lib/VCL/utils.pm
index 5f7b6ae..5204b82 100644
--- a/managementnode/lib/VCL/utils.pm
+++ b/managementnode/lib/VCL/utils.pm
@@ -11905,20 +11905,25 @@
=head2 is_ip_assigned_query
- Parameters : IP address
+ Parameters : IP address, Computer ID (optional)
Returns : boolean
- Description : checks if IP address exists in db
+ Description : checks if IP address exists in db; ignores computer with
+ specified ID if supplied
=cut
sub is_ip_assigned_query {
- my ($ip_address) = @_;
+ my ($ip_address) = shift;
+ my ($computer_id) = shift;
if (!defined($ip_address)) {
notify($ERRORS{'WARNING'}, 0, "IPaddress argument was not supplied");
return;
- }
+ }
+ if (!defined($computer_id)) {
+ $computer_id = 0;
+ }
my $select_statement = <<EOF;
SELECT
@@ -11930,6 +11935,7 @@
WHERE
computer.IPaddress = '$ip_address' AND
computer.stateid = state.id AND
+computer.id != $computer_id AND
state.name != 'deleted' AND
computer.vmhostid IS NOT NULL
EOF
diff --git a/web/.ht-inc/utils.php b/web/.ht-inc/utils.php
index aaf3cbd..21c3304 100644
--- a/web/.ht-inc/utils.php
+++ b/web/.ht-inc/utils.php
@@ -4870,6 +4870,7 @@
// if $ip specified, only look at computers under management nodes that can
# handle that network
+ $ipmaplimited = 0;
if($ip != '') {
$mappedmns = getMnsFromImage($imageid);
$mnnets = checkAvailableNetworks($ip);
@@ -4886,6 +4887,24 @@
return debugIsAvailable(0, 18, $start, $end, $imagerevisionid);
}
$mappedcomputers = implode(',', $newcompids);
+ // if existing, available, and mapped computer already has requested IP
+ //address, limit $mappedcomputers to just that one
+ $query = "SELECT c.id "
+ . "FROM computer c "
+ . "JOIN state s ON (c.stateid = s.id) "
+ . "WHERE c.IPaddress = '$ip' AND "
+ . "c.id in ($mappedcomputers) AND "
+ . "s.name != 'deleted' AND "
+ . "c.deleted = 0 AND "
+ . "(c.type != 'virtualmachine' OR c.vmhostid IS NOT NULL)";
+ $tmpmapped = array();
+ $qh = doQuery($query);
+ while($row = mysqli_fetch_assoc($qh))
+ $tmpmapped[] = $row['id'];
+ if(count($tmpmapped)) {
+ $ipmaplimited = 1;
+ $mappedcomputers = implode(',', $tmpmapped);
+ }
}
#get computers for available schedules and platforms
@@ -4999,8 +5018,11 @@
}
# return 0 if no computers available
- if(empty($computerids) && empty($blockids))
+ if(empty($computerids) && empty($blockids)) {
+ if($ipmaplimited)
+ return debugIsAvailable(-4, 2, $start, $end, $imagerevisionid, $computerids, $currentids, $blockids, array(), $virtual);
return debugIsAvailable(0, 21, $start, $end, $imagerevisionid, $computerids, $currentids, $blockids, array(), $virtual);
+ }
#remove computers from list that are already scheduled
$usedComputerids = array();
@@ -5142,7 +5164,7 @@
# undetected failure
$failedids = getPossibleRecentFailures($userid, $imageid);
$shortened = 0;
- if(! empty($failedids)) {
+ if(! empty($failedids) && ! $ipmaplimited) {
$origcomputerids = $computerids;
$origcurrentids = $currentids;
$origblockids = $blockids;
@@ -5231,7 +5253,7 @@
$msg = "invalid image id submitted - not found in images available to the user";
break;
case "2":
- $msg = "an overlapping server reservation has the same fixed IP or MAC address";
+ $msg = "an unavailable computer has the requested fixed IP or MAC address";
break;
case "16":
$msg = "the requested fixed IP address is currently in use by a management node";