genirack 21 KB
Newer Older
1
#
Leigh B Stoller's avatar
Leigh B Stoller committed
2
3
# TODO:
#
4
# Bake in the routable ip space if possible
Leigh B Stoller's avatar
Leigh B Stoller committed
5
6
# Add partial reverse zone stuff. See the NOTES file.
#
7
8
# Add /usr/testbed/bin and sbin to elabman path.
# Kill OUTERBOSS_NODENAME and OUTERBOSS_SSLCERTNAME from defs
Leigh B Stoller's avatar
Leigh B Stoller committed
9

10
11
12
13
use strict;
use libinstall;
use installvars;
use libtestbed;
14
use emutil;
Leigh B Stoller's avatar
Leigh B Stoller committed
15
use libEmulab;
16
17
18
use emdb;
use User;
use NodeType;
Leigh B Stoller's avatar
Leigh B Stoller committed
19
use OSinfo;
Leigh B Stoller's avatar
Leigh B Stoller committed
20
use Image;
Leigh B Stoller's avatar
Leigh B Stoller committed
21
22
use Node;
use EmulabFeatures;
23
24
25

my $EMULABDEVEL  = "git://git-public.flux.utah.edu/emulab-devel.git";
my $EMULABSTABLE = "git://git-public.flux.utah.edu/emulab-stable.git";
26
27
28
my $NODETYPEXML  = "$TOP_SRCDIR/install/genirack/nodetype.xml";
my $SWITCHSQL    = "$TOP_SRCDIR/install/genirack/tbdb.sql";
my $CONFIGVARS   = "$PREFIX/configvars.txt";
29
30
31
my $RACKVARS     = "$PREFIX/etc/genirack/variables.txt";
my $RACKIPS      = "$PREFIX/etc/genirack/ips.txt";
my $RACKILO      = "$PREFIX/etc/genirack/ilo.xml";
32
my $RACKWIRES    = "$TOP_SRCDIR/install/genirack/wiring-A.xml";
Leigh B Stoller's avatar
Leigh B Stoller committed
33
my $ILOPASSWORD  = "$PREFIX/etc/ilo.pswd";
34
my $ELABPASSWORD = "$PREFIX/etc/elabman.pswd";
35
36
my $HPPASSWORD   = "$PREFIX/etc/switch.pswd";
my $PORTSRC      = "http://www.emulab.net/downloads/FreeBSD-9.0-ports.tar.gz";
37
38
39
if ($FBSD_MAJOR >= 10) {
    $PORTSRC      = "http://www.emulab.net/downloads/FreeBSD-10.0-ports.tar.gz";
}
Leigh B Stoller's avatar
Leigh B Stoller committed
40
41
my $ZZZ		 = "/usr/local/etc/rc.d/zzz-inelab.sh";
my $DEFAULTOSID  = "FEDORA15-STD";
Leigh B Stoller's avatar
Leigh B Stoller committed
42
my @EXPORTEDOSIDS= ("FBSD82-STD", "UBUNTU12-64-STD");
Leigh B Stoller's avatar
Leigh B Stoller committed
43
my $PGOSSITEVAR  = "protogeni/default_osname";
44
my $CHPASS	 = "/usr/bin/chpass";
45
my $SSHTB	 = "$PREFIX/bin/sshtb";
Leigh B Stoller's avatar
Leigh B Stoller committed
46
my $DELETENODE	 = "$PREFIX/sbin/deletenode";
47
48
my $RACKNTPCONF  = "$TOP_SRCDIR/install/genirack/ntp.conf";
my $ETCNTPCONF   = "/etc/ntp.conf";
Leigh B Stoller's avatar
Leigh B Stoller committed
49
my $ELABMANDIR   = "/users/elabman";
50
51
52
53
54

my %INTERFACES = (
    "xn1"   => "inet 10.1.1.1 netmask 255.255.255.0",
    "xn2"   => "inet 10.2.1.1 netmask 255.255.255.0",
    "xn3"   => "inet 10.3.1.1 netmask 255.255.255.0",
Leigh B Stoller's avatar
Leigh B Stoller committed
55
56
    # Direct connect to FOAM VM on the same node.
    "xn4"   => "inet 10.4.1.1 netmask 255.255.255.0",
57
58
);

Leigh B Stoller's avatar
Leigh B Stoller committed
59
my %HOSTNAMES = (
60
    "procurve1"       => "10.1.1.253",
61
62
    "procurve1-alt"   => "10.2.1.253",
    "procurve2"       => "10.3.1.253",
63
64
    "foam-priv"	      => "10.4.1.2",
    "flowvisor-priv"  => "10.4.1.3",
65
);
66
67
68
69

sub Install($$$)
{
    my ($server, $isupdate, $impotent) = @_;
70
    my %configvars = ();
71
72
73
74
75

    # Replace if this script does an update for ip/domain.
    return 0
	if ($isupdate);

76
77
    SET_TESTBED_VERSION("Genirack");

78
79
80
81
    Phase "genirack", "Doing additional Geni Rack tasks", sub {
	PhaseSkip("Not a Rack")
	    if (!$PROTOGENI_GENIRACK);

82
	Phase "config", "Reading in Emulab config variables", sub {
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
	    PhaseFail("No config file")
		if (! -e $CONFIGVARS);
	    
	    open(CN, $CONFIGVARS)
		 or PhaseFail("Could not open $CONFIGVARS: $!");
	    while (<CN>) {
		if ($_ =~ /^([-\w]*)\s*=\s*(.*)$/) {
		    my $key = $1;
		    my $val = $2;
		    if ($val =~ /^'(.*)'$/) {
			$val = $1;
		    }
		    $configvars{$key} = "$val";
		}
	    }
	    close(CN);
	};

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
	Phase "rackconfig", "Reading in GeniRack config variables", sub {
	    PhaseFail("No config file")
		if (! -e $RACKVARS);
	    
	    open(CN, $RACKVARS)
		 or PhaseFail("Could not open $RACKVARS: $!");
	    while (<CN>) {
		if ($_ =~ /^([-\w]*)\s*=\s*(.*)$/) {
		    my $key = $1;
		    my $val = $2;
		    if ($val =~ /^'(.*)'$/) {
			$val = $1;
		    }
		    $configvars{$key} = "$val";
		}
	    }
	    close(CN);
	};

120
121
122
123
124
125
126
127
128
	#
	# Have not figured this out yet; it runs during boss setup but
        # the line in fstab gets lost. Run again and it works fine. 
	#
	Phase "swapon", "Reruning rc.freebsd", sub {
	    PhaseSkip("already enabled") unless `grep -q swap $FSTAB`;
	    ExecQuietFatal("/usr/local/etc/emulab/rc/rc.freebsd");
	};

Leigh B Stoller's avatar
Leigh B Stoller committed
129
130
131
132
133
134
	Phase "rclocal", "Removing $ZZZ", sub {
	    PhaseSkip("already deleted")
		if (! -e $ZZZ);
	    DeleteFileFatal($ZZZ);
	};

135
	#
Leigh B Stoller's avatar
Leigh B Stoller committed
136
	# Update geniuser password.
137
138
139
140
141
142
143
144
145
146
	#
	if (exists($configvars{'PROTOGENI_PASSWORD'}) &&
	    $configvars{'PROTOGENI_PASSWORD'} ne "") {
	    my $geniuser = User->Lookup("geniuser");
	    PhaseFail("No geniuser account")
		if (!defined($geniuser));
	    my $passhash = PassWordHash($configvars{'PROTOGENI_PASSWORD'});
	    $geniuser->SetPassword($passhash);
	}

Leigh B Stoller's avatar
Leigh B Stoller committed
147
148
149
150
151
152
153
154
155
156
157
	#
	# This is the password to use when creating the elabman user
	# on each node iLo.
	#
	if (exists($configvars{'GENIRACK_ILO_PASSWORD'}) &&
	    $configvars{'GENIRACK_ILO_PASSWORD'} ne "" &&
	    ! -e $ILOPASSWORD) {
	    CreateFileFatal($ILOPASSWORD, $configvars{'GENIRACK_ILO_PASSWORD'});
	    ExecQuietFatal("$CHMOD 400 $ILOPASSWORD");
	}

158
159
160
161
162
163
164
165
166
167
168
	#
	# This is the password for the switches.
	#
	if (exists($configvars{'GENIRACK_SWITCH_PASSWORD'}) &&
	    $configvars{'GENIRACK_SWITCH_PASSWORD'} ne "" &&
	    ! -e $HPPASSWORD) {
	    CreateFileFatal($HPPASSWORD,
			    $configvars{'GENIRACK_SWITCH_PASSWORD'});
	    ExecQuietFatal("$CHMOD 400 $HPPASSWORD");
	}

169
170
171
	#
	# This is the elabman password.
	#
172
173
174
175
	if (exists($configvars{'PASSWORD'}) && $configvars{'PASSWORD'} ne "") {
	    my $PASSWORD = $configvars{'PASSWORD'};
	    my $passhash = PassWordHash($PASSWORD);
	    
176
	    Phase "elabman_pswd", "Storing the elabman password", sub {
177
178
179
180
181
182
183
184
185
186
		PhaseSkip("exists")
		    if (-e $ELABPASSWORD);
		
		CreateFileFatal($ELABPASSWORD, $PASSWORD);
		ExecQuietFatal("$CHMOD 400 $ELABPASSWORD");
	    };

	    #
	    # Make sure root/toor have the same password on boss/ops.
	    #
187
	    Phase "root_pswd", "Setting root password on boss", sub {
188
189
190
191
192
193
194
195
		ExecQuietFatal("$CHPASS -p '$passhash' root");
		ExecQuietFatal("$CHPASS -p '$passhash' toor");
	    };

	    # shell escape.
	    $passhash =~ s/\$/\\\$/g;
	    $passhash =~ s/\*/\\\*/g;

196
	    Phase "root_pswdops", "Setting root password on ops", sub {
197
198
199
200
201
202
203
		ExecQuietFatal("$SSHTB -host $USERNODE ".
			       "  $CHPASS -p '$passhash' root");
		ExecQuietFatal("$SSHTB -host $USERNODE ".
			       "  $CHPASS -p '$passhash' toor");
	    };
	}

204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
	#
	# Create an ssh config file for root, to ssh to the switches.
	# Need to also put root public key here tftp can get it.
	#
	my $SSHCONFIG = "/root/.ssh/config";
	my $SSHPUBKEY = "/root/.ssh/id_rsa.pub";
	my $COPYPUBKEY= "$TFTP_DIR/id_rsa.pub";
	
	Phase "sshconfig", "Creating $SSHCONFIG", sub {
	    DoneIfExists($SSHCONFIG);
	    CreateFileFatal($SSHCONFIG,
			    "Host procurve1 procurve2", 
			    "User manager",
			    "IdentitiesOnly yes",
			    "IdentityFile /root/.ssh/id_rsa");
	    ExecQuietFatal("$CHMOD 644 $SSHCONFIG");
	};
	Phase "sshpubkey", "Copying $SSHPUBKEY to $TFTP_DIR", sub {
	    DoneIfExists($COPYPUBKEY);
	    ExecQuietFatal("/bin/cp -p $SSHPUBKEY $COPYPUBKEY");
	};

226
227
228
229
230
231
232
233
234
235
	#
	# This is the elabman SSL cert password.
	#
	my $SSLCERT_PSWDFILE = "/users/elabman/.ssl/password";
	
	if (exists($configvars{'ELABMAN_SSLCERT_PASSWORD'}) &&
	    $configvars{'ELABMAN_SSLCERT_PASSWORD'} ne "") {
	    if (! -e $SSLCERT_PSWDFILE) {
		CreateFileFatal($SSLCERT_PSWDFILE,
				$configvars{'ELABMAN_SSLCERT_PASSWORD'});
236
237
		ExecQuietFatal("$CHMOD 400 $SSLCERT_PSWDFILE");
		ExecQuietFatal("$CHOWN elabman:emulab-ops $SSLCERT_PSWDFILE");
238
239
240
241
	    }
	    #
	    # Create encrypted SSL cert for elabman, for testing PG later.
	    #
242
	    ExecQuietFatal("$SUDO -u $PROTOUSER $PREFIX/sbin/mkusercert ".
243
	         " -p " . $configvars{'ELABMAN_SSLCERT_PASSWORD'} . " elabman");
244
245
	}

Leigh B Stoller's avatar
Leigh B Stoller committed
246
247
248
249
250
	#
	# Trun on arp lockdown.
	#
	Phase "arplockdown", "Turning on arplockdown", sub {
	    ExecQuietFatal("$PREFIX/sbin/setsitevar ".
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
			   "general/arplockdown static");
	};

	#
	# Mike says: With the default server/client settings, the
	# client is still dropping packets and causing re-requests of
	# blocks. So for now, use the sitevars to scale back the frisbeed
	# send rate to 50000000 (50Mb/sec) for both system and user
	# images. The run time for single client is actually slightly
	# improved at this lower rate due to many fewer re-requests.
	#
	Phase "frisbeerate", "Setting frisbeed max rate", sub {
	    ExecQuietFatal("$PREFIX/sbin/setsitevar ".
			   "images/frisbee/maxrate_std 50000000");
	    ExecQuietFatal("$PREFIX/sbin/setsitevar ".
			   "images/frisbee/maxrate_usr 50000000");
Leigh B Stoller's avatar
Leigh B Stoller committed
267
268
	};

Leigh B Stoller's avatar
Leigh B Stoller committed
269
270
271
	#
	# A reasonable default image.
	#
Leigh B Stoller's avatar
Leigh B Stoller committed
272
	Phase "sitevar1", "Setting sitevar $PGOSSITEVAR", sub {
Leigh B Stoller's avatar
Leigh B Stoller committed
273
274
275
276
277
278
279
	    my $osinfo = OSinfo->LookupByName($DEFAULTOSID);
	    PhaseFail("Could not look up $DEFAULTOSID osid")
		if (!defined($osinfo));
	    
	    ExecQuietFatal("$PREFIX/sbin/setsitevar ".
			   "'$PGOSSITEVAR' '$DEFAULTOSID'");
	};
Leigh B Stoller's avatar
Leigh B Stoller committed
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308

	#
	# Latitude/Longitude
	#
	if (exists($configvars{'GENIRACK_COUNTRY'}) &&
	    $configvars{'GENIRACK_COUNTRY'} ne "") {
	    Phase "sitevar2", "Setting country sitevar", sub {
		SetSiteVar("general/default_country",
			   $configvars{'GENIRACK_COUNTRY'})
		    or PhaseFail("failed");
	    };
	}
	if (exists($configvars{'GENIRACK_LATITUDE'}) &&
	    $configvars{'GENIRACK_LATITUDE'} ne "") {
	    Phase "sitevar3", "Setting latitude sitevar", sub {
		SetSiteVar("general/default_latitude",
			   $configvars{'GENIRACK_LATITUDE'})
		    or PhaseFail("failed");
	    };
	}
	if (exists($configvars{'GENIRACK_LONGITUDE'}) &&
	    $configvars{'GENIRACK_LONGITUDE'} ne "") {
	    Phase "sitevar4", "Setting longitude sitevar", sub {
		SetSiteVar("general/default_longitude",
			   $configvars{'GENIRACK_LONGITUDE'})
		    or PhaseFail("failed");
	    };
	}
	
Leigh B Stoller's avatar
Leigh B Stoller committed
309
	
310
311
312
313
314
315
316
317
318
	#
	# Shutdown the testbed for the rest of this.
	#
	Phase "shutdown", "Shutting down the testbed", sub {
	    PhaseSkip("not running")
		if (!CheckDaemonRunning("stated"));
	    ExecQuietFatal("$TESTBED_CONTROL shutdown");
	};

319
320
321
	#
	# Create a clone of emulab-devel while we are close to the server.
	#
Leigh B Stoller's avatar
Leigh B Stoller committed
322
	if (0) {
323
324
325
326
327
328
329
330
331
332
	Phase "cloning1", "Cloning emulab-devel repository", sub {
	    DoneIfExists("$PREFIX/src/emulab-devel");
	    ExecQuietFatal("cd $PREFIX/src; ".
			   "    git clone $EMULABDEVEL emulab-devel");
	};
	Phase "cloning2", "Cloning emulab-stable repository", sub {
	    DoneIfExists("$PREFIX/src/emulab-stable");
	    ExecQuietFatal("cd $PREFIX/src; ".
			   "    git clone $EMULABSTABLE emulab-stable");
	};
Leigh B Stoller's avatar
Leigh B Stoller committed
333
	}
334

335
336
337
338
339
340
341
342
343
344
345
	#
	# Also grab the port source while close to the server.
	#
	Phase "portsrc", "Getting port source tarball", sub {
	    DoneIfExists("$PREFIX/ports.tar.gz");
	    FetchFileFatal($PORTSRC, "$PREFIX/ports.tar.gz");
	};
	Phase "ports", "Unpacking port source tarball", sub {
	    DoneIfExists("$PREFIX/ports/Mk");
	    ExecQuietFatal("cd $PREFIX; $TAR zxf $PREFIX/ports.tar.gz");
	};
346
	Phase "portlink", "Linking to unpacked ports tree", sub {
347
348
	    ExecQuietFatal("/bin/rm -rf /usr/ports")
		if (-e "/usr/ports" && -d "/usr/ports");
349
	    ExecQuietFatal("cd /usr; ln -sf testbed/ports .");
350
	};
351
352

	# Need to add a symlink. 
353
	
354
355
356
357
358
359
	#
	# Need to remove the ELABINELAB flag.
	#
	my $OLDDEFSFILE = "$main::TOP_SRCDIR/defs-elabinelab";
	my $NEWDEFSFILE = "$main::TOP_SRCDIR/defs-genirack";
	
360
	Phase "elabinelab", "Removing ELABINELAB stuff from defs file", sub {
361
	    DoneIfExists($NEWDEFSFILE);
Leigh B Stoller's avatar
Leigh B Stoller committed
362
363
364
	    # And some other stuff.
	    ExecQuietFatal("echo 'EC2META_ENABLE=1' | ".
			   " cat $OLDDEFSFILE - | sed ".
365
366
			   "   -e 's/^ELABINELAB/#ELABINELAB/' ".
			   "   -e 's/^WWWHOST=boss/WWWHOST=www/' ".
367
			   "   -e 's/^EXTERNAL_NTPS/#EXTERNAL_NTPS/' ".
368
369
370
371
372
373
374
			   "   > $NEWDEFSFILE");
	};

	#
	# Build and install software without ELABINELAB defined.
	#
	Phase "Software", "Rebuilding and Reinstalling Software", sub {
375
376
	    DoneIfExists("$PREFIX/marker");
	    
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
	    Phase "cleaning", "Cleaning (please be patient)", sub {
		ExecQuietFatal("cd $TOP_OBJDIR; $GMAKE clean");
	    };
	    Phase "config", "Configuring (please be patient)", sub {
		ExecQuietFatal("cd $TOP_OBJDIR; ".
			       "   $main::TOP_SRCDIR/configure ".
			       "      --with-TBDEFS=$NEWDEFSFILE ".
			       "      --disable-windows");
	    };
	    Phase "building", "Building (please be patient)", sub {
		ExecQuietFatal("cd $TOP_OBJDIR; $GMAKE");
	    };
	    Phase "installing", "Installing (please be patient)", sub {
		ExecQuietFatal("cd $TOP_OBJDIR; $GMAKE boss-install");
	    };
	    Phase "postinstall", "Post Installing Testbed Software", sub {
		ExecQuietFatal("cd $TOP_OBJDIR; $GMAKE post-install");
	    };
	    Phase "rc.testbed", "Installing testbed RC scripts", sub {
		ExecQuietFatal("$GMAKE -C $TOP_OBJDIR/rc.d install");
	    };
398
399
400
	    Phase "ntpd", "Installing testbed ntp config", sub {
		ExecQuietFatal("$GMAKE -C $TOP_OBJDIR/ntpd install");
	    };
401
	    CreateFile("$PREFIX/marker", "genirack install marker");
402
	};
403
404

	#
Leigh B Stoller's avatar
Leigh B Stoller committed
405
	# Add /etc/hosts entries for the switches. 
406
407
408
409
	#
	Phase "etchosts", "Adding hosts entries for switches", sub {
	    my @strings = ();
	    
Leigh B Stoller's avatar
Leigh B Stoller committed
410
411
	    foreach my $switch (keys(%HOSTNAMES)) {
		my $ip = $HOSTNAMES{$switch};
412
413
414
415
416
		push(@strings, "$ip\t$switch");
	    }
	    DoneIfEdited($HOSTS);
	    AppendToFileFatal($HOSTS, @strings);
	};
Leigh B Stoller's avatar
Leigh B Stoller committed
417
418
419
420
421
422
423
424
425
426
427
428

	#
	# Also need to do:
	#
	# * Comment out all the natd stuff.
	# * Comment out all static route lines except frisbee.
	# * Comment out firewall stuff.
	# * Comment out xn0 alias.
	# * Set the xn0 config to the real config.
	# * Set the defaultrouter to the real one. 
	
	Phase "rcconf", "Updating rcconf for actual boot", sub {
429
430
431
	    my @strings = ();
	    my @ifaces  = ();

Leigh B Stoller's avatar
Leigh B Stoller committed
432
	    # /etc/rc.conf entries for the switches.
433
434
435
436
437
	    foreach my $iface (keys(%INTERFACES)) {
		my $line = $INTERFACES{$iface};
		push(@strings, "ifconfig_${iface}=\"$line\"");
		push(@ifaces, $iface);
	    }
Leigh B Stoller's avatar
Leigh B Stoller committed
438
439
440
441
442
443
444
445
446
	    push(@strings,
		 "network_interfaces=\"\$network_interfaces @ifaces\"");
	    push(@strings,
		 "ifconfig_xn0=\"inet ". $configvars{"GENIRACK_BOSSIP"} . 
		 " netmask " . $configvars{"GENIRACK_NETMASK"} . " -tso\"");
	    # Jail network.
	    push(@strings,
		 "ifconfig_xn0_alias0=\"inet 172.17.254.254 ".
		 "netmask 255.240.0.0\"");
447
448
449
450
	    # ilo network. The control node takes .253
	    push(@strings,
		 "ifconfig_xn0_alias1=\"inet 10.249.249.254 ".
		 "netmask 255.255.255.0\"");
Leigh B Stoller's avatar
Leigh B Stoller committed
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
	    # Actual default router.
	    push(@strings,
		 "defaultrouter=\"" . $configvars{"GENIRACK_ROUTER"} . "\"");
	    # Going to lose all static routes below, so add this back.
	    push(@strings,
		 "static_routes=\"\$static_routes frisbee\"");

	    #
	    # Okay, we want to comment out a bunch of stuff.
	    #
	    my @patterns = (qr(^natd),
			    qr(^firewall),
			    qr(^defaultrouter),
			    qr(^static_routes),
			    qr(^route_genirack),
			    qr(^route_outerboss),
			    qr(^route_vnodes),
			    qr(^ifconfig_xn0),
			    qr(^ifconfig_xn0_alias0),
	    );
471
	    DoneIfEdited($RCCONF);
Leigh B Stoller's avatar
Leigh B Stoller committed
472
	    UpdateFileFatal($RCCONF, \@patterns, @strings);
473
474
475
476
477
478
479
480
481
	};

	#
	# Add in the switch stuff which is all hard coded sql.
	#
	Phase "sql", "Adding switch goo to the database", sub {
	    ExecQuietFatal("$MYSQL $DBNAME < $SWITCHSQL");
	};

482
483
484
485
486
487
488
	#
	# Extra install
	# 
	Phase "genirack", "Installing extra scripts", sub {
	    ExecQuietFatal("cd $TOP_OBJDIR/install/genirack; $GMAKE install");
	};

489
490
491
	#
	# Add the nodes to the DB.
	#
492
	my $ILOIP = $configvars{"GENIRACK_ILOIP"};
493

494
	Phase "nodes", "Adding nodes to the DB", sub {
495
496
497
	    PhaseSkip("No ILO definitions file")
		if (! -e $RACKILO);
	    
498
499
500
501
502
503
504
505
506
	    my $query_result =
		DBQueryWarn("select node_id from nodes where node_id='pc1'");
	    PhaseFail("DB error")
		if (!$query_result);
	    PhaseSkip("already added")
		if ($query_result->numrows);

	    ExecQuietFatal("cd $TOP_OBJDIR/install/genirack; ".
			   "  $SUDO -u $PROTOUSER $WAP ".
507
			   "  perl mknewconfig -i $ILOIP ".
508
			   "       /tmp/output $RACKIPS $RACKILO $RACKWIRES");
509
510
511
512

	    PhaseFail("initilo.sh not generated")
		if (! -e "/tmp/output/initilo.sh");
	    ExecQuietFatal("/bin/cp -p /tmp/output/initilo.sh $PREFIX/etc");
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
	};

	Phase "outlets", "Adding outlets to the DB", sub {
	    my $query_result =
		DBQueryWarn("select node_id from nodes where role='testnode'");
	    PhaseFail("DB error")
		if (!$query_result);

	    while (my ($node_id) = $query_result->fetchrow_array()) {
		Phase "$node_id", "Adding outlet for $node_id", sub {
		    my $outlet_result =
			DBQueryWarn("select * from outlets ".
				    "where node_id='$node_id'");
		
		    PhaseFail("DB error")
			if (!$outlet_result);
		    PhaseSkip("already added")
			if ($outlet_result->numrows);

		    ExecQuietFatal("cd $TOP_OBJDIR/install/genirack; ".
				   "  $SUDO perl initilo.pl -o $node_id");
		};
	    }
	};

Leigh B Stoller's avatar
Leigh B Stoller committed
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
	#
	# Add this feature so we get the right libvtop.
	#
	my $LIBVTOP_FEATURE     = "LibVtopTest";
	my $LIBVTOP_DESRIPTION  = "Test version of libvtop";
    
	my $feature = EmulabFeatures->Lookup($LIBVTOP_FEATURE);
	Phase "feature", "Adding libvtop_test feature", sub {
	    PhaseSkip("already exists")
		if (defined($feature));
	    $feature = EmulabFeatures->Create($LIBVTOP_FEATURE,
					      $LIBVTOP_DESRIPTION);
	    PhaseFail("Failed to create feature")
		if (!defined($feature));
	};
	Phase "feature", "Enabling libvtop_test feature", sub {
	    $feature->SetGlobalEnable(1) == 0
		or PhaseFail("Could not enable feature");
556
557
	    $feature->SetGlobalDisable(0) == 0
		or PhaseFail("Could not clear disable flag on feature");
Leigh B Stoller's avatar
Leigh B Stoller committed
558
559
	};

560
561
562
563
564
565
566
567
568
569
	#
	# Update the DB with the switch community string.
	#
	if (exists($configvars{'GENIRACK_COMMUNITY'})) {
	    my $safe_password = DBQuoteSpecial($configvars{'GENIRACK_COMMUNITY'});
	    DBQueryWarn("update switch_stack_types set ".
			"snmp_community=$safe_password")
		or PhaseFail("Could not set snmp community strings");
	}

Leigh B Stoller's avatar
Leigh B Stoller committed
570
571
572
573
574
575
576
577
578
	#
	# Delete existing ops node; we recreate it later. 
	#
	Phase "opsnode", "Deleting ops node", sub {
	    PhaseSkip("already deleted")
		if (!defined(Node->Lookup("ops")));
	    ExecQuietFatal("$DELETENODE -f -s ops");
	};

579
580
581
582
583
584
585
586
587
	#
	# Shutdown DHCP and fix the dynamic range that rc.mkelab changed.
	# This is okay since the subnet is different then Emulab.
	#
	Phase "dhcpd", "Fixing dhcpd configuration", sub {
	    ExecQuietFatal("/bin/rm -f $DHCPD_TEMPLATE");
	    ExecQuietFatal("cd $TOP_OBJDIR/dhcpd; $GMAKE install");
	    ExecQuietFatal("$DHCPD_MAKECONF -i");
	};
Leigh B Stoller's avatar
Leigh B Stoller committed
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606

	#
	# This adds the nightly download of new images from Utah.
	#
	Phase "crontab", "Editing $CRONTAB", sub {
	    DoneIfEdited($CRONTAB);
	    AppendToFileFatal($CRONTAB,
		      "0  \t6\t*\t*\t*\troot\t$PREFIX/sbin/getimages");
	};

	foreach my $osid (@EXPORTEDOSIDS) {
	    Phase "$osid", "Enabling protogeni export for $osid", sub {
		my $osinfo = OSinfo->LookupByName($osid);
		PhaseFail("No such osid")
		    if (!defined($osinfo));
		$osinfo->Update({"protogeni_export" => 1}) == 0
		    or PhaseFail("DB query failed");
	    };
	}
607
608
609
610
611

	#
	# Create a local named forward fragment file with some extra stuff.
	#
	my $reversedots;
612
	my $forwarddots;
613
614
615
616
617
618
619
620
621
622
623
624
625
626
	my @forward_strings = ();
	my @reverse_strings = ();
	my %local_dns = ("GENIRACK_FOAMIP"    => "foam",
			 "GENIRACK_FLOWIP"    => "flowvisor",
			 "GENIRACK_CONTROLIP" => "control",
			 "GENIRACK_ILOIP"     => "control-ilo");

	foreach my $name (keys(%local_dns)) {
	    next
		if (!exists($configvars{$name}));

	    my $hostname = $local_dns{$name};
	    my $ip = $configvars{$name};
	    my ($a,$b,$c,$num) = split(/\./, $ip);
627
	    $forwarddots = "${a}.${b}.${c}";
628
629
630
631
632
633
634
	    $reversedots = "${c}.${b}.${a}";
	    
	    push(@forward_strings, "$hostname\tIN\tA\t$ip");
	    push(@reverse_strings, "$num\tIN\tPTR\t${hostname}.${OURDOMAIN}.");
	}
	my $FORWARDFRAGMENT1 = "$NAMED_DIR/${OURDOMAIN}.internal.db.local";
	my $FORWARDFRAGMENT2 = "$NAMED_DIR/${OURDOMAIN}.db.local";
635
	my $REVERSEFRAGMENT  = "$NAMED_DIR/reverse/${forwarddots}.db.local";
636
637
638
639
640
641
642
643
644
645
646
647
	Phase "forward1", "Creating $FORWARDFRAGMENT1", sub {
	    DoneIfExists($FORWARDFRAGMENT1);
	    CreateFileFatal($FORWARDFRAGMENT1, @forward_strings);
	};
	Phase "forward2", "Creating $FORWARDFRAGMENT2", sub {
	    DoneIfExists($FORWARDFRAGMENT2);
	    CreateFileFatal($FORWARDFRAGMENT2, @forward_strings);
	};
	Phase "reverse", "Creating $REVERSEFRAGMENT", sub {
	    DoneIfExists($REVERSEFRAGMENT);
	    CreateFileFatal($REVERSEFRAGMENT, @reverse_strings);
	};
648

Leigh B Stoller's avatar
Leigh B Stoller committed
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
	#
	# 
	#
	Phase "buildenv", "Creating build environment", sub {
	    Phase "mkdir", "Creating directory in elabman", sub {
		DoneIfExists("$ELABMANDIR/emulab-devel");
		mkdir "$ELABMANDIR/emulab-devel",0775 or
		    PhaseFail("Unable to create $ELABMANDIR/emulab-devel: $!");

	    };
	    Phase "cpdefs", "Coping defs file to elabman", sub {
		DoneIfExists("$ELABMANDIR/emulab-devel/defs-genirack");
		ExecQuietFatal("/bin/cp -f $PREFIX/src/testbed/defs-genirack ".
			       "        $ELABMANDIR/emulab-devel");
	    };
	    Phase "mvsrc", "Moving src directory to elabman", sub {
		DoneIfExists("$ELABMANDIR/emulab-devel/emulab-devel");
		ExecQuietFatal("/bin/mv -f $PREFIX/src/testbed ".
			       "        $ELABMANDIR/emulab-devel/emulab-devel");
	    };
	    Phase "mvobj", "Moving obj directory to elabman", sub {
		DoneIfExists("$ELABMANDIR/emulab-devel/obj");
		ExecQuietFatal("/bin/mv -f $PREFIX/obj/testbed ".
			       "        $ELABMANDIR/emulab-devel/obj");
	    };
	    Phase "srcsymlink", "Leaving src symlink behind", sub {
		DoneIfExists("$PREFIX/src/testbed");
		ExecQuietFatal("cd $PREFIX/src; ln -s ".
			       "  $ELABMANDIR/emulab-devel/emulab-devel ".
			       "  testbed");
	    };
	    Phase "objsymlink", "Leaving obj symlink behind", sub {
		DoneIfExists("$PREFIX/obj/testbed");
		ExecQuietFatal("cd $PREFIX/obj; ln -s ".
			       "  $ELABMANDIR/emulab-devel/obj obj");
	    };
685
686
687
	    Phase "chown", "Changing owner and group", sub {
		ExecQuietFatal("$CHOWN -R elabman:emulab-ops ".
			       "   $ELABMANDIR/emulab-devel");
688
689
		ExecQuietFatal("$CHOWN -R -h elabman:emulab-ops ".
			       "   $ELABMANDIR/emulab-devel");
690
	    };
Leigh B Stoller's avatar
Leigh B Stoller committed
691
692
	};

693
694
695
696
697
698
699
700
	PhaseSucceed("Rack Setup Done");
    };
    return 0;
}

# Local Variables:
# mode:perl
# End: