newnodecheckin.php 6.43 KB
Newer Older
1
e<?php
2 3 4 5 6 7
#
# EMULAB-COPYRIGHT
# Copyright (c) 2003 University of Utah and the Flux Group.
# All rights reserved.
#
require("defs.php3");
8
require("newnode-defs.php3");
9 10 11 12 13 14 15 16 17 18

#
# Note - this script is not meant to be called by humans! It returns no useful
# information whatsoever, and expects the client to fill in all fields
# properly.
# Since this script does not cause any action to actually happen, so it's save
# to leave 'in the open' - the worst someone can do is annoy the testbed admins
# with it!
#

19 20 21 22 23 24
#
# Grab the IP address that this node has right now, so that we can contact it
# later if we need to, say, reboot it.
#
$tmpIP = getenv("REMOTE_ADDR");

25 26 27
#
# Find all interfaces
#
28
$interfaces = array();
29 30 31 32 33 34 35
foreach ($HTTP_GET_VARS as $key => $value) {
    if (preg_match("/iface(name|mac)(\d+)/",$key,$matches)) {
        $vartype = $matches[1];
    	$ifacenum = $matches[2];
    	if ($vartype == "name") {
	    if (preg_match("/^([a-z]+)(\d+)$/i",$value,$matches)) {
		$interfaces[$ifacenum]["type"] = $matches[1];
36
	        $interfaces[$ifacenum]["card"] = $ifacenum;
37 38 39 40 41 42 43 44 45 46
	    } else {
		echo "Bad interface name $value!";
		continue;
	    }
	} else {
	    $interfaces[$ifacenum]["mac"] = $value;
	}
    }
}

47 48 49 50
#
# Use one of the interfaces to see if this node seems to have already checked
# in once
#
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
if (count($interfaces)) {
    $testmac = $interfaces[0]["mac"];

    #
    # First, make sure it isn't a 'real boy' - we should let the operators know
    # about this, because there may be some problem.
    #
    $query_result = DBQueryFatal("select n.node_id from " .
	"nodes as n left join interfaces as i " .
	"on n.node_id=i.node_id " .
	"where i.mac='$testmac'");
    if  (mysql_num_rows($query_result)) {
        $row = mysql_fetch_array($query_result);
	$node_id = $row["node_id"];
        echo "Node is already a real node, named $node_id\n";
	TBMAIL($TBMAIL_OPS,"Node Checkin Error","A node attempted to check " .
	    "in as a new node, but it is already\n in the database as " .
	    "$node_id!");
	exit;
    }


    #
    # Next, try the new nodes
    #
    $query_result = DBQueryFatal("select n.new_node_id, n.node_id from " .
	"new_nodes as n left join new_interfaces as i " .
	"on n.new_node_id=i.new_node_id " .
	"where i.mac='$testmac'");

    if  (mysql_num_rows($query_result)) {
        $row = mysql_fetch_array($query_result);
	$id = $row["new_node_id"];
	$node_id = $row["node_id"];
85 86
        echo "Node has already checked in\n";
	echo "Node ID is $id\n";
87 88 89 90 91 92 93 94 95 96

	#
	# Keep the temp. IP address around in case it's gotten a new one
	#
	DBQueryFatal("update new_nodes set temporary_IP='$tmpIP' " .
	    "where new_node_id=$id");

	exit;
    }
}
97

98 99

#
100 101
# Attempt to come up with a node_id and an IP address for it - unless one was
# provided by the client.
102
#
103 104 105 106 107 108 109 110 111 112 113 114 115 116
if (!$node_id) {
    $name_info = find_free_id("pc");
    $node_prefix = $name_info[0];
    $node_num = $name_info[1];
    $hostname = $node_prefix . $node_num;
} else {
    $hostname = $node_id;
}

if ($use_temp_IP) {
    $IP = $tmpIP;
} else {
    $IP = guess_IP($node_prefix,$node_num);
}
117 118

#
119
# Handle the node's type
120
#
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
if ($type) {
    #
    # If they gave us a type, let's see if that type exists or not
    #
    if (TBValidNodeType($type)) {
	#
	# Great, it already exists, nothin' else to do
	#
    } else {
	#
	# Okay, it doesn't exist. We'll create it.
	#
	make_node_type($type,$cpuspeed,$disksize);
    }
} else {
    #
    # Make an educated guess as to what type it belongs to
    #
139 140 141 142 143 144 145 146 147
    $type = guess_node_type($cpuspeed,$disksize);
}

#
# Default the role to 'testnode' if the node didn't supply a role
#
if (!$role) {
    $role = "testnode";
}
148 149 150 151

#
# Stash this information in the database
#
152 153 154 155 156
if ($identifier) {
    $identifier = "'$identifier'";
} else {
    $identifier = "NULL";
}
157
DBQueryFatal("insert into new_nodes set node_id='$hostname', type='$type', " .
158
	"IP='$IP', temporary_IP='$tmpIP', dmesg='$messages', created=now(), " .
159
	"identifier=$identifier, role='$role'");
160 161 162 163 164

$query_result = DBQueryFatal("select last_insert_id()");
$row = mysql_fetch_array($query_result);
$new_node_id = $row[0];

165 166
echo "Node ID is $new_node_id\n";

167
foreach ($interfaces as $interface) {
168
	$card = $interface["card"];
169 170
	$mac = $interface["mac"];
	$type = $interface["type"];
171 172 173
	DBQueryFatal("insert into new_interfaces set " .
	    "new_node_id=$new_node_id, card=$card, mac='$mac', " .
	    "interface_type='$type'");
174 175 176 177 178 179 180
}

#
# Send mail to testbed-ops about the new node
#
TBMAIL($TBMAIL_OPS,"New Node","A new node, $hostname, has checked in");

181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
function check_node_exists($node_id) {
    #
    # Just check to see if this node already exists in one of the
    # two tables - return 1 if it does, 0 if not
    #
    $query_result = DBQueryFatal("select node_id from nodes " .
	    "where node_id='$node_id'");
    if (mysql_num_rows($query_result)) {
	return 1;
    }
    $query_result = DBQueryFatal("select node_id from new_nodes " .
	    "where node_id='$node_id'");
    if (mysql_num_rows($query_result)) {
	return 1;
    }

    return 0;
}

200 201 202
function find_free_id($prefix) {

    #
203 204
    # First, check to see if there's a recent entry in new_nodes we can name
    # this node after
205
    #
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
    $query_result = DBQueryFatal("select node_id from new_nodes " .
        "order by created desc limit 1");
    if (mysql_num_rows($query_result)) {
        $row = mysql_fetch_array($query_result);
	$old_node_id = $row[0];
	#
	# Try to figure out if this is in some format we can increment
	#
	if (preg_match("/^(.*[^\d])(\d+)$/",$old_node_id,$matches)) {
	    echo "Matches pcXXX format";
	    # pcXXX format
	    $base = $matches[1];
	    $number = $matches[2];
	    $potential_name = $base . ($number + 1);
	    if (!check_node_exists($potential_name)) {
		return array($base,($number +1));
	    }
	} elseif (preg_match("/^(.*)-([a-zA-Z])$/",$old_node_id,$matches)) {
	    # Something like WAIL's (type-rack-A) format
	    $base = $matches[1];
	    $lastchar = $matches[2];
	    $newchar = chr(ord($lastchar) + 1);
	    $potential_name = $base . '-' . $newchar;
	    if (!check_node_exists($potential_name)) {
		return array($base . '-', $newchar);
	    }
	}
    }
234 235

    #
236
    # Okay, that didn't work.
237 238 239 240
    # Just go through the nodes and new_nodes tables looking for one that
    # hasn't been used yet - put in a silly little guard to prevent an
    # infinite loop in case of bugs.
    #
241 242
    $node_number = 0;
    while ($node_number < 10000) {
243 244
	$node_number++;
    	$potential_name = $prefix . $node_number;
245 246
	if (!check_node_exists($potential_name)) {
	    break;
247 248 249
	}
    }

250
    return array($prefix, $node_number);
251 252 253 254

}

?>