Changeset 9c00d41
- Timestamp:
- Sep 12, 2007 5:47:56 PM (17 years ago)
- Branches:
- axis_example, compt_changes, info-ops, master, version-1.30, version-2.00, version-3.01, version-3.02
- Children:
- c9f5490
- Parents:
- 4addf9d
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
fedkit/splitter.pl
r4addf9d r9c00d41 2 2 3 3 use Getopt::Std; 4 use IO::File; 5 use IO::Dir; 6 use IO::Pipe; 7 use File::Copy; 4 8 5 9 @scripts = ("federate.sh", "smbmount.pl"); 6 10 $local_script_dir = "."; 11 12 # Parse the config file. The format is a colon-separated parameter name 13 # followed by the value of that parameter to the end of the line. This parses 14 # that format and puts the parameters into the referenced hash. Parameter 15 # names are mapped to lower case, parameter values are unchanged. Returns 0 on 16 # failure (e.g. file open) and 1 on success. 17 sub parse_config { 18 my($file, $href) = @_; 19 my($fh) = new IO::File($file); 20 21 unless ($fh) { 22 warn "Can't open $file: $!\n"; 23 return 0; 24 } 25 26 while (<$fh>) { 27 next if /^\s*#/ || /^\s*$/; # Skip comments & blanks 28 chomp; 29 /^([^:]+):\s*(.*)/ && do { 30 my($key) = $1; 31 32 $key =~ tr/A-Z/a-z/; 33 $href->{$key} = $2; 34 next; 35 }; 36 warn "Unparasble line in $file: $_\n"; 37 } 38 $fh->close(); # It will close when it goes out of scope, but... 39 return 1; 40 } 41 7 42 8 43 # use scp to transfer a file, reporting true if successful and false otherwise. … … 54 89 return 1; 55 90 } 91 92 # Ship per-testbed configuration generated by this script to the remote /proj 93 # directories on the remote testbeds 94 sub ship_configs { 95 my($host, $user, $src_dir, $dest_dir) = @_; # Where, who, where remotely 96 my($d, $f); 97 98 $d = IO::Dir->new($src_dir) || return 0; 99 100 while ( $f = $d->read()) { 101 next if $f =~ /^\./; 102 &scp_file("$src_dir/$f", "$user\@$host", $dest_dir) || return 0; 103 } 104 return 1; 105 } 106 56 107 57 108 … … 75 126 my($proj_dir) = "/proj/$pid/exp/$eid/tmp"; # Where to stash federation stuff 76 127 my($to_hostname) = "$proj_dir/hosts"; # remote hostnames file 128 my($status) = new IO::Pipe; # The pipe to get status 77 129 78 130 # Determine the status of the remote experiment 79 open(STATUS, "ssh $user\@$host /usr/testbed/bin/expinfo $pid $eid|") ||131 $status->reader("ssh $user\@$host /usr/testbed/bin/expinfo $pid $eid") || 80 132 die "Can't ssh to $user\@$host:$!\n"; 133 81 134 # XXX: this is simple now. Parsing may become more complex 82 while (< STATUS>) {135 while (<$status>) { 83 136 /State: (\w+)/ && ($state = $1); 84 137 /No\s+such\s+experiment/ && ($state = "none"); 85 138 } 86 close(STATUS);139 $status->close(); 87 140 print "$tb: $state\n"; 88 141 … … 95 148 return 0; 96 149 &ship_scripts($host, $user, $proj_dir) || return 0; 150 &ship_configs($host, $user, "$tmpdir/$tb", $proj_dir) || return 0; 97 151 &ssh_cmd($user, $host, "/usr/testbed/bin/modexp -r -s -w $pid " . 98 152 "$eid $tclfile", "modexp") || return 0; … … 107 161 &scp_file("./hostnames", "$user\@$host", $to_hostname) || return 0; 108 162 &ship_scripts($host, $user, $proj_dir) || return 0; 163 &ship_configs($host, $user, "$tmpdir/$tb", $proj_dir) || return 0; 109 164 # Now start up 110 165 &ssh_cmd($user, $host, "/usr/testbed/bin/swapexp -w $pid $eid in", … … 121 176 &scp_file("./hostnames", "$user\@$host", $to_hostname) || return 0; 122 177 &ship_scripts($host, $user, $proj_dir) || return 0; 178 &ship_configs($host, $user, "$tmpdir/$tb", $proj_dir) || return 0; 123 179 # Now start up 124 180 &ssh_cmd($user, $host, "/usr/testbed/bin/swapexp -w $pid $eid in", … … 147 203 } 148 204 149 # tcl program to split experiments150 # $tcl_splitter = "/usr/testbed/lib/ns2ir/parse.tcl";151 $tcl_splitter = "/users/faber/testbed/tbsetup/ns2ir/parse.tcl";152 $tclsh = "/usr/local/bin/otclsh"; # tclsh to call directly153 205 154 206 $pid = $gid = "dummy"; # Default project and group to pass to … … 157 209 # use them at all, but we supply them to 158 210 # keep our changes to the parser minimal. 159 160 211 # Argument processing. 161 getopts('d:c:m:e:f:nt:', \%opts); 162 163 $eid = $opts{'e'}; # Experiment ID 164 $tcl = $opts{'f'} || shift; # The experiment description 165 $master = $opts{'m'}; # Master testbed 166 $startem = $opts{'n'} ? 0 : 1; # If true, start the sub-experiments 167 $tmpdir = $opts{'t'} || "/tmp"; # where to collect tmp files 168 $config = $opts{'c'} || "./testbeds"; 169 $local_script_dir = $opts{'d'}; # Local scripts 170 212 getopts('c:f:nd', \%opts); 213 $splitter_config = $opts{'c'} || "./splitter.conf"; 214 $debug = $opts{'d'}; 215 &parse_config("$splitter_config", \%opts) || 216 die "Cannot read config file $splitter_conf: $!\n"; 217 218 219 $startem = $opts{'n'} ? 0 : 1; # If true, start the sub-experiments 220 $eid = $opts{'experiment'}; # Experiment ID 221 $tcl = $opts{'f'} || shift; # The experiment description 222 $master = $opts{'master'}; # Master testbed 223 $tmpdir = $opts{'tmpdir'} || $opts{'tempdir'}|| "/tmp"; # tmp files 224 $tb_config = $opts{'testbeds'} || "./testbeds"; # testbed configurations 225 $local_script_dir = $opts{'scriptdir'}; # Local scripts 226 # For now specify these. We may want to generate them later. 227 $gw_pubkey = $opts{'gatewaypubkey'}; 228 ($gw_pubkey_base = $gw_pubkey) =~ s#.*/##; 229 $gw_secretkey = $opts{'gatewaysecretkey'}; 230 ($gw_secretkey_base = $gw_secretkey) =~ s#.*/##; 231 232 # tcl program to split experiments (changed during devel) 233 $tcl_splitter = $opts{'tclparse'} || "/usr/testbed/lib/ns2ir/parse.tcl"; 234 # tclsh to call directly (changed during devel) 235 $tclsh = $opts{'tclsh'} || "/usr/local/bin/otclsh"; 236 237 # Prefix to avoid collisions 171 238 $tmpdir .= "/split$$"; 172 239 240 # Create a workspace 173 241 unless (-d "$tmpdir") { 174 242 mkdir("$tmpdir") || die "Can't create $tmpdir: $!"; 175 243 } 176 244 177 245 # Validate scripts directory 178 246 for $s (@scripts) { 179 247 die "$local_script_dir/$s not in local script directory. Try -d\n" … … 184 252 185 253 # Read a hash of per-testbed parameters from the local configurations. 186 open(CONF, $config) || die "can't read testbed configutions from $config: $!\n"; 187 while (<CONF>) { 254 $conf = new IO::File($tb_config) || 255 die "can't read testbed configutions from $tb_config: $!\n"; 256 while (<$conf>) { 188 257 next if /^#/; 189 258 chomp; … … 203 272 $domain{$tb} = ".$domain{$tb}" unless $domain{$tb} =~ /^\./; 204 273 } 205 close(CONF);274 $conf->close(); 206 275 207 276 # Open a pipe to the splitter program and start it parsing the experiments 208 open(PIPE, "$tclsh $tcl_splitter -s -m $master -p $pid $gid $eid $tcl|") || 277 $pipe = new IO::Pipe; 278 $pipe->reader("$tclsh $tcl_splitter -s -m $master -p $pid $gid $eid $tcl") || 209 279 die "Cannot execute $tclsh $tcl_splitter -s -p $pid $gid $eid $tcl:$!\n"; 210 280 211 # Parse the splitter output. 212 while (<PIPE>) { 281 # Parse the splitter output. This loop creates the sub experiments, gateway 282 # configurations and hostnames file 283 while (<$pipe>) { 213 284 # Start of a sub-experiment 214 285 /^#\s+Begin\s+Testbed\s+\((\w+)\)/ && do { … … 290 361 my($sdomain) = $domain{$gateways}; # domain for the source 291 362 my($ddomain) = $domain{$dtb}; # domain for the destination 363 my($sproject) = $project{$gateways}; # Project of the destination 292 364 293 365 $sdomain = ".$eid.$project{$gateways}$sdomain"; … … 305 377 # Write out the file 306 378 open(GWCONFIG, ">$tmpdir/$gateways/$myname$sdomain.gw.conf") || 307 die "can't open $tmpdir/ %gateways/$myname$sdomain.gw.conf: $!\n";379 die "can't open $tmpdir/$gateways/$myname$sdomain.gw.conf: $!\n"; 308 380 print GWCONFIG "Active: $active\n"; 309 381 print GWCONFIG "Type: $type\n"; 310 382 print GWCONFIG "Peer: $desthost$ddomain\n"; 311 print GWCONFIG "Pubkeys: /placeholder\n"; 312 print GWCONFIG "Privkeys: /placeholder\n"; 383 print GWCONFIG "Pubkeys: " . 384 "/proj/$sproject/exp/$eid/tmp/$gw_pubkey_base\n"; 385 print GWCONFIG "Privkeys: " . 386 "/proj/$sproject/exp/$eid/tmp/$gw_secretkey_base\n"; 313 387 close(GWCONFIG); 388 389 # This testbed has a gateway (most will) so make a copy of the keys it 390 # needs in this testbed's subdirectory. start_segment will transfer 391 # them. 392 unless (-r "$tmpdir/$gateways/$gw_pubkey_base" ) { 393 copy($gw_pubkey, "$tmpdir/$gateways/$gw_pubkey_base") || 394 die "Can't copy pubkeys ($gw_pubkey to " . 395 "$tmpdir/$gateways/$gw_pubkey_base): $!\n"; 396 } 397 if ($active eq "true" ) { 398 unless (-r "$tmpdir/$gateways/$gw_secretkey_base" ) { 399 copy($gw_secretkey, "$tmpdir/$gateways/$gw_secretkey_base") || 400 die "Can't copy secret keys ($gw_secretkey to " . 401 "$tmpdir/$gateways/$gw_secretkey_base): $!\n"; 402 } 403 } 314 404 315 405 #done processing gateway entry, ready for next line … … 336 426 print FILE; 337 427 } 338 close(PIPE);428 $pipe->close(); 339 429 die "No nodes in master testbed ($master)\n" unless $allocated{$master}; 340 430 … … 362 452 } 363 453 print "Experiment started\n"; 454 system("rm -rf $tmpdir") unless $debug; 364 455 exit(0); # set the exit value 365 456 … … 372 463 =head1 SYNOPSIS 373 464 374 B<splitter.pl> B<-e> I<experiment> B<-m> I<master_testbed> [B<-n>] 375 [B<-d> F<script_dir>] [B<-c> F<config_file>] [B<-f> F<experiment_tcl>] 465 B<splitter.pl> [B<-nd>] [B<-c> F<config_file>] [B<-f> F<experiment_tcl>] 376 466 [F<experiment_tcl>] 377 467 … … 384 474 385 475 The testbed labels are meaningful based on their presence in the testbeds file. 386 that file can be specified with the B<-c> option, and defaults to 387 F<./testbeds>. The syntax is described below. 476 that file can be specified in the configuration file using the B<Testbeds> 477 directive, and defaults to F<./testbeds>. The syntax is described below. 478 479 Most of the intermediate files are staged in a sub-directory of a temporary 480 files directory and deleted at the end of the script. Specifying the B<-d> 481 flag on the command line avoids the deletion for debbugging. By default the 482 temporary files directory is directory is F</tmp> and can be reset in the 483 configuration file using the B<Tmpdir> directive. Intermediate files are 484 stored under a subdirectory formed by adding the process ID of the splitter 485 process. For example, if the temporary files directory is F</tmp> and the 486 B<splitter.pl> process ID is 2323, the temporary files will be stored in 487 F</tmp/split2323/>. 388 488 389 489 The expreriment is split out into one experiment description per testbed in the 390 currentdirectory named as F<experiment.testbed.tcl> where the experiment is391 the argument to B<-e> and the testbed is the tb-set-node-testbed parameter for392 t he nodes in the file.490 temporary directory named as F<experiment.testbed.tcl> where the experiment is 491 the experiment ID given in the configuration file, and the testbed is the 492 tb-set-node-testbed parameter for the nodes in the file. 393 493 394 494 If the B<-n> option is absent the sub-experiments are then instantiated on 395 495 their testbeds. (Here B<-n> is analogous to its use in L<make(1)>). 396 Per-testbed parameters are set in the configurationfile. Sub-experiments on496 Per-testbed parameters are set in the testbeds file. Sub-experiments on 397 497 slave testbeds are instantiated in a random order, but the master testbed is 398 498 currently instantiated last. 399 499 400 Scripts to start federation are copied into the local experiment's tmp file - 401 e.g., F</proj/DETER/exp/simple-split/tmp>. These are taken from the directory 402 given by the B<-d> option. 500 Scripts to start federation (the federation kit) are copied into the local 501 experiment's tmp file - e.g., F</proj/DETER/exp/simple-split/tmp>. These are 502 taken from the directory given by the B<ScriptDir> directive in the 503 configuration file. 403 504 404 505 If any sub-experiment fails to instantiate, the other sub-exeriments are 405 506 swapped out. 406 507 407 =head2 Configuration file 508 =head2 Configuration File 509 510 The configuration file is a simple attribute-value pair set of colon-separated 511 parameters and values. A configuration file must be present, either specified 512 in the B<-c> flag or the default F<./splitter.conf>. All the parameter names 513 are case insensitive, but should not include any whitespace. Parameter values 514 may include whitespace, but no newlines. 515 516 Possible parameters are: 517 518 =over 5 519 520 =item Experiment 521 522 The name of the experiment on the various testbeds 523 524 =item Master 525 526 The master testbed label from the testbeds file, described below. 527 528 =item Testbeds 529 530 The testbeds file described below, giving per-testbed parameters. If this 531 directive is absent the testbeds file defaults to F<./testbeds> 532 533 =item ScriptDir 534 535 Location of the default federation scripts, i.e. the federation kit. 536 537 =item GatewayPubkey 538 539 =item GatewaySecretKey 540 541 The names of the files containing secret and public keys to use in setting up 542 tunnels between testbeds. These will eventually be automatically generated. 543 544 =item TmpDir 545 546 =item TempDir 547 548 The directory where temporary files are created. These are synonyms, but 549 should both be specified, B<TmpDir> has priority. If neither is specified, 550 F</tmp> is used. 551 552 =item Tclparse 553 554 The pathname to the experiment parsing program. Only developers should set 555 this. 556 557 =item Tclsh 558 559 The pathname to the local oTcl shell. Only developers should set 560 this. 561 562 =back 563 564 =head2 Testbeds file 408 565 409 566 The configuration file (F<./testbeds> unless overridden by B<-c>) is a … … 443 600 444 601 The start command to run on experimental nodes when this testbed is used as a 445 slave. 602 slave. In all the start commands the string FEDDIR will be replaced by the 603 local experiment's federation scripts directory and the string GWCONF replaced 604 by the gatway configuration file. 446 605 447 606 =item gateway start (slave) 448 607 608 The start command to run on gateway nodes when this testbed is used as a slave. 609 The same string substitutions are made in this command as in experiment start. 610 611 =item experiment start (master) 612 613 The start command to run on experimental nodes when this testbed is used as a 614 master. The same string substitutions are made in this command as in 615 experiment start. 616 617 =item gateway start (master) 618 449 619 The start command to run on gateway nodes when this testbed is used as a 450 slave. 451 452 =item experiment start (master) 453 454 The start command to run on experimental nodes when this testbed is used as a 455 master. 456 457 =item gateway start (master) 458 459 The start command to run on gateway nodes when this testbed is used as a 460 master. 620 master. The same string substitutions are made in this command as in 621 experiment start. 461 622 462 623 =item gateway image … … 466 627 =back 467 628 468 The parsing of the configurationis extremely simple. Colons separate each629 The parsing of the testbeds is extremely simple. Colons separate each 469 630 field and there is n provision for escaping them at this time. 470 631
Note: See TracChangeset
for help on using the changeset viewer.