newnode-defs.php3 6.78 KB
Newer Older
1 2
<?PHP
#
3
# Copyright (c) 2003, 2005, 2006, 2007 University of Utah and the Flux Group.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
23 24 25 26 27 28 29 30
#

#
# This is a simple library for use by the new-node pages, with functions that
# need to be called both by the initial checkin page and the adminstrator
# node-adding page.
#

31
function find_switch_macs(&$mac_list) {
32

33
    global $uid, $gid, $TBSUEXEC_PATH, $ELABINELAB;
34 35 36 37 38 39 40 41 42 43 44

    #
    # Avoid SIGPROF in child.
    #   
    set_time_limit(0); 
    
    $macs = popen("$TBSUEXEC_PATH $uid $gid switchmac 2>&1","r");

    #
    # XXX - error checking
    #
45
    $line = fgets($macs);
46
    while (!feof($macs)) {
47
        $line = rtrim($line);
48 49 50 51 52
	$exploded = explode(",",$line);
	$MAC = $exploded[0];
	$switchport = $exploded[1];
	$vlan = $exploded[2];
	$iface = $exploded[3];
53
	$class = $exploded[4];
54
	if (!preg_match("/^([\w-]+)\/(\d+)\.(\d+)$/",$switchport,$matches)) {
55
	    echo "<h3>Bad line from switchmac: $line</h3>\n";
56 57 58 59 60 61 62 63 64 65 66 67 68 69
	} else {
	    $switch = $matches[1];
	    $card = $matches[2];
	    $port = $matches[3];
	    if (isset($mac_list[$MAC]) ) {
		$mac_list[$MAC]["switch"] = $switch;
		$mac_list[$MAC]["switch_card"] = $card;
		$mac_list[$MAC]["switch_port"] = $port;
		if ($ELABINELAB) {
		    # We let switchmac tell us.
		    $mac_list[$MAC]["class"] = $class;
		    # Need this to reorder the interfaces.
		    $mac_list[$MAC]["iface"] = $iface;
		}
70
	    }
71
	}
72
	$line = fgets($macs);
73 74
    }

75 76
    # Return exit status to caller! 
    return pclose($macs);
77 78 79 80 81 82 83
}

function guess_node_type($proc,$disk) {

    #
    # Allow the reported speed to differ from the one in the database
    #
84
    $fudge_factor = .10;
85 86 87 88 89 90 91 92 93 94 95 96

    #
    # Convert disk size from megabytes to gigabtypes
    #
    $disk /= 1000.0;

    #
    # Go through node types and try to find a single one that matches
    # this node's processor speed. This is a totally bogus way to do this,
    # but it's the best we got for now.
    #
    $node_type = "";
97 98
    $query_result = DBQueryFatal("select type from node_types " .
				 "where !isvirtnode and !isremotenode");
99 100
    while ($row = mysql_fetch_array($query_result)) {
	$type = $row["type"];
101 102 103 104 105 106 107 108

	NodeTypeAttribute($type, "frequency", $speed);
	NodeTypeAttribute($type, "disksize", $HD);

	if (is_null($speed) || is_null($HD))
	    continue;

	echo "Checking type $type: $speed vs $proc, $HD vs $disk\n";
109 110 111 112 113 114
	if (($proc > ($speed * (1.0 - $fudge_factor))) &&
	    ($proc < ($speed * (1.0 + $fudge_factor))) &&
	    ($disk > ($HD * (1.0 - $fudge_factor))) &&
	    ($disk < ($HD * (1.0 + $fudge_factor)))) {
	    if ($node_type != "") {
	        # We found two potential matches, choose neither
115 116
		echo "Found another match ($type), using that\n";
		$node_type = $type;
117 118 119 120 121 122 123 124 125 126 127
	    } else {
		echo "Found a first match ($type)\n";
	        $node_type = $type;
	    }
	}
    }

    echo "Returning $node_type\n";
    return $node_type;
}

128 129 130
#
# Create a new node type
# XXX - Right now, this is really only meant for inserting a node_types entry
131 132
# for ops. It misses doing a lot of important things, like setting the class 
# and default OSID for types other than ops
133
#
134
function make_node_type($type,$speed,$disk) {
135 136 137 138
    $type  = addslashes($type);
    $speed = addslashes($speed);
    $disk  = addslashes($disk);
    
139 140 141
    #
    # Just insert a stub entry for this type
    #
142
    $class = "unknown";
143 144 145 146 147
    $defosid = "";
    if (!strcmp($type,"ops")) {
	$class = "misc";
	$defosid = "emulab-ops-OPSNODE-BSD";
    }
148 149 150 151 152 153 154 155 156 157
    DBQueryFatal("insert into node_types set type='$type', class='$class'");
    DBQueryFatal("insert into node_type_attributes set type='$type', ".
		 " attrkey='frequency',attrvalue='$speed',attrtype='integer'");
    DBQueryFatal("insert into node_type_attributes set type='$type', ".
		 " attrkey='disksize',attrvalue='$disk',attrtype='float'");
    if ($defosid != "") {
	DBQueryFatal("insert into node_type_attributes set type='$type', ".
		     " attrkey='default_osid',attrvalue='$defosid', ".
		     " attrtype='string'");
    }
158 159
}

160
function guess_IP ($prefix, $number) {
161
    global $CONTROL_NETWORK;
162 163 164 165

    $hostname = $prefix . $number;

    #
166
    # First, lets see if they've already added to to DNS - the PHP
167 168 169 170 171 172 173 174
    # gethostbyname has a really dumb way to return failure - it just
    # gives you the hostname back.
    #
    $IP = gethostbyname($hostname);
    if (strcmp($IP,$hostname)) {
    	return $IP;
    }

175
    #
Leigh Stoller's avatar
Leigh Stoller committed
176 177
    # We want to be able to handle both numeric and character 'number's 
    # Figure out which we have
178
    #
179
    $ndigits = 0;
Leigh Stoller's avatar
Leigh Stoller committed
180
    if (! is_numeric($number)) {
181 182 183 184
	$using_char = 1;
	$number = ord($number);
    } else {
	$using_char = 0;
185 186 187
	if (preg_match("/^(0\d+)$/",$number)) {
	    $ndigits = strlen($number);
	}
188 189
    }

190 191 192 193 194 195 196 197
    #
    # Okay, no such luck. We'll go backwards through the host list until
    # we find the previous node with an established IP, then add our offset
    # onto that
    #
    $i = $number - 1;
    $IP = "";
    while ($i > 0) {
198 199
        if ($using_char) {
	    $node = $prefix . chr($i);
200 201 202
	} elseif ($ndigits) {
	    $fmt = "%0" . $ndigits . "d";
	    $node = $prefix . sprintf($fmt, $i);
203 204 205
	} else {
	    $node = $prefix . $i;
	}
Leigh Stoller's avatar
Leigh Stoller committed
206 207 208 209
        $query_result =
	    DBQueryFatal("select IP from interfaces as i " .
			 "where i.node_id='$node' and ".
			 "      i.role='" . TBDB_IFACEROLE_CONTROL . "'");
210 211
        if (mysql_num_rows($query_result)) {
	    $row = mysql_fetch_array($query_result);
Leigh Stoller's avatar
Leigh Stoller committed
212
	    $IP = $row["IP"];
213 214 215 216 217
	    break;
	}

	# Try new_nodes too
        $query_result = DBQueryFatal("select IP from new_nodes " .
218
		"where node_id='$node'");
219 220
        if (mysql_num_rows($query_result)) {
	    $row = mysql_fetch_array($query_result);
Leigh Stoller's avatar
Leigh Stoller committed
221
	    $IP = $row["IP"];
222 223 224 225 226 227
	    break;
	}

	$i--;
    }

228 229 230
    #
    # Lets start out as the first address on the given control network.
    # 
231
    if ($i <= 0) {
232
    	$IP = $CONTROL_NETWORK;
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
    }

    #
    # Parse the IP we got into the last octet and everything else. Note that we
    # don't really do the IP address calcuation correctly - just an
    # approximation of the right thing.
    #
    list($oct1,$oct2,$oct3,$oct4) = explode(".",$IP);
    $oct4 += $number - $i;

    # We don't yet wrap - it may not be OK to do
    if ($oct4 > 254) {
        return 0;
    }

    return "$oct1.$oct2.$oct3.$oct4";
    
}


?>