lilalo
annotate lm @ 119:71bd999bcb04
Исправлено несколько багов:
* выполняется корректная привязка diff'ов
* правильно запоминается raw_start и проч raw_*
* временно отключен вывод признака нажатия ctrl-c (он ставился неверно)
* в приглашение добавлен случайный nonce (для правильной отработки tab)
* выполняется корректная привязка diff'ов
* правильно запоминается raw_start и проч raw_*
* временно отключен вывод признака нажатия ctrl-c (он ставился неверно)
* в приглашение добавлен случайный nonce (для правильной отработки tab)
author | igor |
---|---|
date | Thu Mar 13 12:19:42 2008 +0200 (2008-03-13) |
parents | 3fb4d295fb65 |
children |
rev | line source |
---|---|
devi@0 | 1 #!/usr/bin/perl |
devi@0 | 2 |
devi@0 | 3 |
devi@0 | 4 use strict; |
devi@0 | 5 use Data::Dumper; |
devi@0 | 6 use Switch; |
devi@0 | 7 use XML::Simple; |
devi@0 | 8 use Getopt::Long; |
devi@4 | 9 use utf8; |
devi@0 | 10 |
devi@40 | 11 use lib "/usr/local/bin"; |
devi@40 | 12 use l3config; |
devi@40 | 13 |
devi@0 | 14 our $XMLClass; |
devi@0 | 15 our $XMLCourse; |
devi@0 | 16 our @Labs; |
devi@0 | 17 |
devi@92 | 18 our %Machines; # Machines list from class.xml |
devi@92 | 19 our @SelectedMachines; # Machines list given as the command line argument |
devi@0 | 20 |
devi@0 | 21 our $Config_File = "labmaker.conf"; |
devi@40 | 22 our %Config_ = ( |
devi@92 | 23 "show_host" => "no", |
devi@0 | 24 |
devi@92 | 25 # Вспомогательные программы |
devi@92 | 26 #"l3-report" => "./lm-report", |
devi@92 | 27 "l3-report" => "./l3-report", |
devi@3 | 28 |
devi@92 | 29 # Каталоги |
devi@92 | 30 "path_lilalo" => "/var/lilalo/", |
devi@92 | 31 "path_classes" => "/var/lilalo/classes/", |
devi@92 | 32 "path_lablogs" => "/var/lilalo/lablogs/", |
devi@92 | 33 "courses_path" => "/var/lilalo/courses/", |
devi@92 | 34 "outpath" => "/var/lilalo/out/", |
devi@92 | 35 "path_web" => "/var/www/l3", # Путь к web-отчётам |
devi@92 | 36 "path_share" => "./share/", # Путь к web-отчётам |
devi@0 | 37 |
devi@92 | 38 # Файлы |
devi@92 | 39 "runfile" => "lm.run", |
devi@92 | 40 "logfile" => "lm.log", |
devi@0 | 41 |
devi@92 | 42 "class" => "class", # Имя файла класса |
devi@92 | 43 "class_suffix" => ".xml", # Cуффикс файла класса |
devi@92 | 44 "classfile" => "", |
devi@0 | 45 |
devi@92 | 46 "sshkey" => "$ENV{HOME}/.ssh/id_dsa.pub", |
devi@92 | 47 "lmssh" => "./lm-ssh", |
devi@92 | 48 "lminstall" => "./lm-install", |
devi@92 | 49 "ssh_user" => "root", |
devi@0 | 50 ); |
devi@0 | 51 |
devi@0 | 52 our %Run = ( |
devi@92 | 53 "lab" => "" |
devi@0 | 54 ); |
devi@0 | 55 |
devi@0 | 56 our %Scripts; |
devi@0 | 57 |
devi@0 | 58 sub load_class; |
devi@0 | 59 sub load_config; |
devi@0 | 60 sub load_course; |
devi@0 | 61 sub load_scripts; |
devi@0 | 62 |
devi@92 | 63 sub lm_get; |
devi@0 | 64 sub lm_next; |
devi@0 | 65 sub lm_prev; |
devi@0 | 66 sub lm_start; |
devi@0 | 67 sub lm_stop; |
devi@0 | 68 sub lm_set; |
devi@0 | 69 sub lm_do; |
devi@0 | 70 sub lm_report; |
devi@0 | 71 sub lm_show_hosts; |
devi@69 | 72 sub lm_show_email; |
devi@0 | 73 sub lm_show_labs; |
devi@0 | 74 |
devi@0 | 75 sub load_run; |
devi@0 | 76 sub save_run; |
devi@0 | 77 sub print_log; |
devi@0 | 78 sub print_usage_info; |
devi@0 | 79 sub main(); |
devi@0 | 80 |
devi@0 | 81 main(); |
devi@0 | 82 |
devi@0 | 83 sub main() |
devi@0 | 84 { |
devi@92 | 85 binmode STDOUT, ":utf8"; |
devi@0 | 86 |
devi@92 | 87 if (! @ARGV) { |
devi@92 | 88 print_usage_info(); |
devi@92 | 89 exit(0); |
devi@92 | 90 } |
devi@0 | 91 |
devi@92 | 92 if ($ARGV[0] eq "get") { |
devi@92 | 93 lm_get; |
devi@92 | 94 exit(0); |
devi@92 | 95 } |
devi@0 | 96 |
devi@92 | 97 init_config(); |
devi@92 | 98 #load_config; |
devi@92 | 99 load_run; |
devi@92 | 100 load_scripts; |
devi@92 | 101 load_class; |
devi@92 | 102 load_course; |
devi@92 | 103 |
devi@92 | 104 my $arg = join " ", @ARGV; |
devi@0 | 105 |
devi@92 | 106 # Getting @SelectedMachines if any |
devi@92 | 107 if ($arg =~ s/@(.*?)\s//) { |
devi@92 | 108 my $machines = $1; |
devi@92 | 109 my @list = split /,/, $machines; |
devi@92 | 110 for my $interval (@list) { |
devi@92 | 111 my ($first, $last) = split /-/, $interval; |
devi@0 | 112 |
devi@92 | 113 push @SelectedMachines, $first; |
devi@92 | 114 while ($first < $last) { |
devi@92 | 115 push @SelectedMachines, ++$first; |
devi@92 | 116 } |
devi@92 | 117 } |
devi@92 | 118 } |
devi@92 | 119 |
devi@92 | 120 # Choose command to do |
devi@92 | 121 switch ($arg) { |
devi@92 | 122 case "next" { lm_next } |
devi@92 | 123 case "prev" { lm_prev } |
devi@92 | 124 case /set / { $arg =~ /set (.*)/; lm_set $1 } |
devi@92 | 125 case "report" { lm_report } |
devi@92 | 126 case "start" { lm_start } |
devi@92 | 127 case "stop" { lm_stop } |
devi@92 | 128 case "show hosts" { lm_show_hosts } |
devi@92 | 129 case "show email" { lm_show_email } |
devi@92 | 130 case "show labs" { lm_show_labs } |
devi@92 | 131 case /do / { $arg =~ /do (.*)/; lm_do "$1" } |
devi@92 | 132 else { print_usage_info() } |
devi@92 | 133 } |
devi@92 | 134 save_run; |
devi@92 | 135 exit(0); |
devi@0 | 136 } |
devi@0 | 137 |
devi@0 | 138 sub load_scripts |
devi@0 | 139 { |
devi@92 | 140 open (SCRIPTS, "$Config{l3scripts}") |
devi@92 | 141 or die "Cant open l3scripts file: ".$Config{l3scripts}.": $!\n"; |
devi@92 | 142 binmode SCRIPTS, ":utf8"; |
devi@92 | 143 local $/; |
devi@92 | 144 $_=<SCRIPTS>; |
devi@92 | 145 close(SCRIPTS); |
devi@40 | 146 |
devi@92 | 147 %Scripts = ("empty-element", split (/###(.*)\n/)); |
devi@92 | 148 delete($Scripts{"empty-element"}); |
devi@40 | 149 |
devi@0 | 150 } |
devi@0 | 151 |
devi@0 | 152 sub load_config |
devi@0 | 153 { |
devi@92 | 154 my %file_config; |
devi@92 | 155 my %argv_config; |
devi@92 | 156 #read_config_file(\%file_config, $Config_File); |
devi@92 | 157 GetOptions(\%argv_config, map "$_=s", keys %Config); |
devi@92 | 158 %Config = (%Config, %file_config, %argv_config); |
devi@0 | 159 } |
devi@0 | 160 |
devi@0 | 161 sub load_course |
devi@0 | 162 { |
devi@92 | 163 $XMLCourse = XMLin($Config{"courses_path"}.$XMLClass->{"course"}.".xml", ForceArray => 1 ) |
devi@92 | 164 or die "Can't open file of the course ",$XMLClass->{"course"}," [with .xml extension]\n"; |
devi@92 | 165 # print Dumper($XMLCourse); |
devi@92 | 166 for my $lab (@{$XMLCourse->{"module"}}) { |
devi@92 | 167 push @Labs, $lab->{"code"}; |
devi@92 | 168 } |
devi@0 | 169 } |
devi@0 | 170 |
devi@0 | 171 sub load_class |
devi@0 | 172 { |
devi@92 | 173 my $classfile = |
devi@92 | 174 $Config{"classfile"} || |
devi@92 | 175 $Config{"path_classes"}."/".$Config{"class"}.$Config{"class_suffix"}; |
devi@92 | 176 $XMLClass = XMLin($classfile , ForceArray => [ 'student' ] ) |
devi@92 | 177 or die "Can't open file of the class ",$classfile,"\n"; |
devi@0 | 178 |
devi@92 | 179 for my $student (@{$XMLClass->{"student"}}) { |
devi@92 | 180 $Machines{$student->{"host"}} = { |
devi@92 | 181 "name" => "$student->{firstname} $student->{surname}", |
devi@92 | 182 "firstname" => "$student->{firstname}", |
devi@92 | 183 "user" => "$student->{user}", |
devi@92 | 184 "email" => "$student->{email}", |
devi@92 | 185 "student" => $student, |
devi@92 | 186 } |
devi@92 | 187 } |
devi@92 | 188 # print Dumper($XMLClass); |
devi@92 | 189 # print Dumper(\%Machines); |
devi@92 | 190 } |
devi@92 | 191 |
devi@92 | 192 sub lm_get |
devi@92 | 193 { |
devi@92 | 194 print "Getting class description file..."; |
devi@95 | 195 if (system("cd $Config{path_classes}; rm -f class.xml ; wget xgu.ru/l3/classes/class.xml") ==0 ) |
devi@92 | 196 { |
devi@92 | 197 print "Ok\n"; |
devi@92 | 198 } |
devi@92 | 199 else { |
devi@92 | 200 die "Can't load class file\n" |
devi@92 | 201 } |
devi@0 | 202 } |
devi@0 | 203 |
devi@0 | 204 |
devi@0 | 205 sub lm_next |
devi@0 | 206 { |
devi@92 | 207 for(my $i=0; $i<=$#Labs; $i++){ |
devi@92 | 208 if ( $Labs[$i] eq $Run{"lab"} ) { |
devi@92 | 209 if ($i < $#Labs) { |
devi@92 | 210 lm_set($Labs[$i+1]); |
devi@92 | 211 return ; |
devi@92 | 212 } else { |
devi@92 | 213 die "Lab ", $Run{"lab"}, " is the last. Switch to next lab is impossible" |
devi@92 | 214 } |
devi@92 | 215 } |
devi@92 | 216 |
devi@92 | 217 } |
devi@92 | 218 die "Lab ", $Run{"lab"}, " not found. Don't know which is next" |
devi@0 | 219 } |
devi@0 | 220 |
devi@0 | 221 sub lm_prev |
devi@0 | 222 # Switch to previous lab |
devi@0 | 223 { |
devi@92 | 224 for(my $i=0; $i<=$#Labs; $i++){ |
devi@92 | 225 if ( $Labs[$i] eq $Run{"lab"} ) { |
devi@92 | 226 if ($i > 0) { |
devi@92 | 227 lm_set($Labs[$i-1]); |
devi@92 | 228 return ; |
devi@92 | 229 } else { |
devi@92 | 230 die "Lab ", $Run{"lab"}, " is the first. Switch to previous lab is impossible" |
devi@92 | 231 } |
devi@92 | 232 } |
devi@92 | 233 |
devi@92 | 234 } |
devi@92 | 235 die "Lab ", $Run{"lab"}, " not found. Don't know which is previous" |
devi@0 | 236 } |
devi@0 | 237 |
devi@0 | 238 sub lm_set |
devi@0 | 239 # Switch to $_[0] lab |
devi@0 | 240 # FIXME |
devi@0 | 241 { |
devi@92 | 242 my $lab = shift; |
devi@92 | 243 print "Current lab is $lab\n"; |
devi@92 | 244 $Run{"lab"} = "$lab"; |
devi@92 | 245 lm_do "setlab", $lab; |
devi@0 | 246 } |
devi@0 | 247 |
devi@0 | 248 |
devi@0 | 249 sub lm_start |
devi@0 | 250 # Start new training day |
devi@0 | 251 { |
devi@92 | 252 print_log(`date`." STARTED\n"); |
devi@92 | 253 if ($Run{"lab"}) { |
devi@92 | 254 lm_next; |
devi@92 | 255 } |
devi@92 | 256 else |
devi@92 | 257 { |
devi@92 | 258 # First lab in the course |
devi@92 | 259 lm_set($Labs[0]); |
devi@92 | 260 } |
devi@0 | 261 } |
devi@0 | 262 |
devi@0 | 263 sub lm_stop |
devi@0 | 264 # Stop this training day |
devi@0 | 265 { |
devi@92 | 266 print_log(`date`." STOPPED\n"); |
devi@0 | 267 } |
devi@0 | 268 |
devi@0 | 269 |
devi@0 | 270 sub lm_show_hosts |
devi@0 | 271 # Show hosts used to run a commands |
devi@0 | 272 { |
devi@92 | 273 my $i=1; |
devi@92 | 274 for my $m (sort keys %Machines) { |
devi@92 | 275 if (!@SelectedMachines || grep /^$i$/, @SelectedMachines) { |
devi@92 | 276 print "($i)","\t",$m,"\t",$Machines{$m}->{"name"},"\n"; |
devi@92 | 277 } |
devi@92 | 278 $i++; |
devi@92 | 279 } |
devi@0 | 280 } |
devi@0 | 281 |
devi@69 | 282 sub lm_show_email |
devi@69 | 283 # Show hosts used to run a commands |
devi@69 | 284 { |
devi@92 | 285 my $i=1; |
devi@92 | 286 for my $m (sort keys %Machines) { |
devi@92 | 287 if (!@SelectedMachines || grep /^$i$/, @SelectedMachines) { |
devi@92 | 288 print $Machines{$m}->{"email"},"\t",$Machines{$m}->{"name"},"\n"; |
devi@92 | 289 } |
devi@92 | 290 $i++; |
devi@92 | 291 } |
devi@69 | 292 } |
devi@69 | 293 |
devi@0 | 294 sub lm_show_labs |
devi@0 | 295 # Show hosts used to run a commands |
devi@0 | 296 { |
devi@92 | 297 my $i=1; |
devi@92 | 298 for my $lab (@Labs) { |
devi@92 | 299 print $lab; |
devi@92 | 300 print "*" if $lab eq $Run{"lab"}; |
devi@92 | 301 print "\n"; |
devi@92 | 302 } |
devi@0 | 303 } |
devi@0 | 304 |
devi@0 | 305 sub lm_do |
devi@0 | 306 # Do the $_[0] command on all of the hosts |
devi@0 | 307 { |
devi@92 | 308 my $command = shift; |
devi@92 | 309 my $arg = join " ", @_; |
devi@92 | 310 my $i=1; |
devi@40 | 311 |
devi@92 | 312 my %myenv = ( %Config, |
devi@92 | 313 lab => $arg, |
devi@92 | 314 center => $XMLClass->{"center"}, |
devi@92 | 315 course => $XMLClass->{"course"}, |
devi@92 | 316 date => $XMLClass->{"date"}, |
devi@92 | 317 stopdate => $XMLClass->{"stop-date"}, |
devi@92 | 318 instructor => $XMLClass->{"instructor"}->{"firstname"}." ".$XMLClass->{"instructor"}->{"surname"}, |
devi@92 | 319 manager => $XMLClass->{"manager"}->{"firstname"}." ".$XMLClass->{"manager"}->{"surname"}, |
devi@92 | 320 coursepath => $XMLCourse->{"path"}, |
devi@92 | 321 ); |
devi@40 | 322 |
devi@92 | 323 if (grep { $_ eq "PRE-$command"} keys %Scripts) { |
devi@92 | 324 $_=$Scripts{"PRE-$command"}; |
devi@92 | 325 s/\$(\w+)/$myenv{$1}/ge; |
devi@92 | 326 open(SHELL, "|/bin/sh -s"); |
devi@92 | 327 binmode SHELL, ":utf8"; |
devi@92 | 328 print SHELL $_; |
devi@92 | 329 close (SHELL); |
devi@92 | 330 } |
devi@40 | 331 |
devi@40 | 332 |
devi@92 | 333 for my $m (sort keys %Machines) { |
devi@92 | 334 if (!@SelectedMachines || grep $_ eq $i, @SelectedMachines) { |
devi@92 | 335 print "$m:\n" if $Config{"show_host"} =~ /y/i; |
devi@0 | 336 |
devi@92 | 337 %myenv = ( %myenv, |
devi@92 | 338 host => $m, |
devi@92 | 339 ipaddress => $Machines{$m}->{"ipaddress"}, |
devi@92 | 340 dirs => "/root /home/".$Machines{$m}->{"user"}, |
devi@92 | 341 lablogs => $Config{"path_lablogs"}."/". |
devi@92 | 342 $XMLClass->{"course"}."/". |
devi@92 | 343 $XMLClass->{"date"}."/". |
devi@92 | 344 "$m", |
devi@92 | 345 email => $Machines{$m}->{"student"}->{"email"}, |
devi@92 | 346 company => $Machines{$m}->{"student"}->{"company"}, |
devi@92 | 347 name => $Machines{$m}->{"name"}, |
devi@92 | 348 firstname => $Machines{$m}->{"firstname"}, |
devi@92 | 349 ); |
devi@92 | 350 if (grep { $_ eq $command} keys %Scripts) { |
devi@92 | 351 $_=$Scripts{"$command"}; |
devi@92 | 352 s/\$(\w+)/$myenv{$1}/ge; |
devi@92 | 353 open(SHELL, "|/bin/sh -s"); |
devi@92 | 354 binmode SHELL, ":utf8"; |
devi@92 | 355 print SHELL $_; |
devi@92 | 356 close (SHELL); |
devi@92 | 357 } |
devi@92 | 358 else { |
devi@92 | 359 my $res = `ssh $Config{"ssh_user"}\@$m $command`; |
devi@92 | 360 if ($res) { |
devi@92 | 361 my $count = ($res =~ s/(^)/$m: /mg); |
devi@92 | 362 print $res; |
devi@92 | 363 print "\n" if ($count > 1); |
devi@92 | 364 } |
devi@92 | 365 } |
devi@92 | 366 } |
devi@92 | 367 $i++; |
devi@92 | 368 } |
devi@40 | 369 |
devi@92 | 370 if (grep { $_ eq "POST-$command"} keys %Scripts) { |
devi@92 | 371 $_=$Scripts{"POST-$command"}; |
devi@92 | 372 s/\$(\w+)/$myenv{$1}/ge; |
devi@92 | 373 open(SHELL, "|/bin/sh -s"); |
devi@92 | 374 binmode SHELL, ":utf8"; |
devi@92 | 375 print SHELL $_; |
devi@92 | 376 close (SHELL); |
devi@92 | 377 } |
devi@0 | 378 } |
devi@0 | 379 |
devi@0 | 380 |
devi@3 | 381 |
devi@3 | 382 =cut comment |
devi@3 | 383 |
devi@3 | 384 lm report |
devi@3 | 385 |
devi@3 | 386 Построить html представление для журналов текущего класса. |
devi@3 | 387 Для построения используется скрипт l3-report. |
devi@3 | 388 |
devi@3 | 389 =cut |
devi@3 | 390 |
devi@0 | 391 sub lm_report |
devi@0 | 392 { |
devi@0 | 393 |
devi@92 | 394 my $webdir = $Config{"path_web"}; |
devi@92 | 395 my $course=$XMLClass->{"course"}; |
devi@92 | 396 my $date=$XMLClass->{"date"}; |
devi@92 | 397 my $encoding=$XMLClass->{"charset"}; |
devi@0 | 398 |
devi@92 | 399 my $center = $XMLClass->{"center"}; |
devi@92 | 400 my $instructor = $XMLClass->{"instructor"}->{"firstname"}." ".$XMLClass->{"instructor"}->{"surname"}; |
devi@92 | 401 my $course_name = $XMLCourse->{"fullname"}[0]; |
devi@4 | 402 |
devi@5 | 403 |
devi@92 | 404 # Собственно журналы |
devi@5 | 405 |
devi@92 | 406 for my $student (@{$XMLClass->{"student"}}) { |
devi@92 | 407 my $user = $student->{"user"}; |
devi@92 | 408 my $hostname = $student->{"host"}; |
devi@92 | 409 my $encoding = $student->{"charset"}; |
devi@92 | 410 my $student_name = $student->{"firstname"}." ".$student->{"surname"}; |
devi@5 | 411 |
devi@92 | 412 system("mkdir -p $webdir/$date/$hostname"); |
devi@92 | 413 system("cp ".$Config{"path_share"}."/*.{ico,css} $webdir/$date/$hostname"); |
devi@92 | 414 system($Config{"l3-report"}. |
devi@92 | 415 " --input ".$Config{"path_lablogs"}."/$course/$date/$hostname/$user". |
devi@92 | 416 " --diffs ".$Config{"path_lablogs"}."/$course/$date/$hostname/$user ". |
devi@92 | 417 $Config{"path_lablogs"}."/$course/$date/$hostname/root". |
devi@92 | 418 " --output $webdir/$date/$hostname/$user.html". |
devi@92 | 419 " --course-name '$course_name'". |
devi@92 | 420 " --course-code '$course'". |
devi@92 | 421 " --course-date '$date'". |
devi@92 | 422 " --course-center '$center'". |
devi@92 | 423 " --course-student '$student_name'". |
devi@92 | 424 " --course-trainer '$instructor'". |
devi@92 | 425 " --encoding $encoding" |
devi@92 | 426 ); |
devi@92 | 427 system($Config{"l3-report"}. |
devi@92 | 428 " --input ".$Config{"path_lablogs"}."/$course/$date/$hostname/root". |
devi@92 | 429 " --diffs ".$Config{"path_lablogs"}."/$course/$date/$hostname/root ". |
devi@92 | 430 " --output $webdir/$date/$hostname/root.html". |
devi@92 | 431 " --course-name '$course_name'". |
devi@92 | 432 " --course-code '$course'". |
devi@92 | 433 " --course-date '$date'". |
devi@92 | 434 " --course-center '$center'". |
devi@92 | 435 " --course-student '$student_name'". |
devi@92 | 436 " --course-trainer '$instructor'". |
devi@92 | 437 " --encoding $encoding" |
devi@92 | 438 ); |
devi@92 | 439 } |
devi@5 | 440 |
devi@92 | 441 # Индекс для данного класса |
devi@4 | 442 |
devi@92 | 443 my $head; |
devi@4 | 444 |
devi@92 | 445 $head="Журналы лабораторных работ"; |
devi@92 | 446 open(HTML, ">$webdir/$date/index.html") |
devi@92 | 447 or die "Can't open $webdir/$date/index.html for writing"; |
devi@92 | 448 binmode HTML, ":utf8"; |
devi@92 | 449 print HTML <<HEAD; |
devi@92 | 450 <html> |
devi@92 | 451 <head> |
devi@92 | 452 <meta content='text/html; charset=utf-8' http-equiv='Content-Type' /> |
devi@92 | 453 <title>$head</title> |
devi@92 | 454 </head> |
devi@92 | 455 <body> |
devi@92 | 456 <h1>$head</h1> |
devi@92 | 457 <p> |
devi@92 | 458 Курс: $course_name ($course)<br/> |
devi@92 | 459 Начало: $date<br/> |
devi@92 | 460 Учебный центр: $center <br/> |
devi@92 | 461 Инструктор: $instructor <br/> |
devi@92 | 462 </p> |
devi@92 | 463 <table> |
devi@4 | 464 HEAD |
devi@92 | 465 for my $student (@{$XMLClass->{"student"}}) { |
devi@92 | 466 my $user = $student->{"user"}; |
devi@92 | 467 my $hostname = $student->{"host"}; |
devi@92 | 468 print HTML "<tr>\n"; |
devi@92 | 469 print HTML "<td>",$student->{"firstname"}," ",$student->{"surname"},"</td>\n"; |
devi@92 | 470 print HTML "<td>",$hostname,"</td>\n"; |
devi@92 | 471 print HTML "<td><a href=\"$hostname/$user.html\">",$user,"</td>\n"; |
devi@92 | 472 print HTML "<td><a href=\"$hostname/root.html\">","root","</td>\n"; |
devi@92 | 473 print HTML "</tr>\n"; |
devi@92 | 474 } |
devi@92 | 475 print HTML <<TAIL; |
devi@92 | 476 </table> |
devi@92 | 477 </html> |
devi@4 | 478 TAIL |
devi@92 | 479 close (HTML); |
devi@4 | 480 |
devi@92 | 481 |
devi@92 | 482 |
devi@0 | 483 } |
devi@0 | 484 |
devi@0 | 485 sub load_run |
devi@0 | 486 { |
devi@92 | 487 my $runfile = $Config{"path_labmaker"}."/".$Config{"path_runfile"}; |
devi@92 | 488 open (RUN, $runfile) |
devi@92 | 489 or return; |
devi@92 | 490 while (<RUN>) { |
devi@92 | 491 chomp; |
devi@92 | 492 my ($var, $val) = split /\s+/,$_,2; |
devi@92 | 493 $Run{$var}=$val; |
devi@92 | 494 } |
devi@92 | 495 close (RUN); |
devi@0 | 496 } |
devi@0 | 497 |
devi@0 | 498 sub save_run |
devi@0 | 499 { |
devi@92 | 500 my $runfile = $Config{"path_labmaker"}."/".$Config{"path_runfile"}; |
devi@92 | 501 open (RN, "$runfile") |
devi@92 | 502 or die "Can't save running state to $runfile"; |
devi@92 | 503 for my $var (keys %Run) { |
devi@92 | 504 print RN $var,"\t",$Run{$var},"\n"; |
devi@92 | 505 } |
devi@92 | 506 close (RN); |
devi@0 | 507 } |
devi@0 | 508 |
devi@0 | 509 sub print_log |
devi@0 | 510 { |
devi@92 | 511 my $logfile = $Config{"path_labmaker"}."/".$Config{"path_logfile"}; |
devi@92 | 512 open (LOG, ">>$logfile") |
devi@92 | 513 or die "Can't open logfile $logfile for writing"; |
devi@92 | 514 print LOG @_; |
devi@92 | 515 close (LOG); |
devi@0 | 516 } |
devi@0 | 517 |
devi@0 | 518 |
devi@0 | 519 sub print_usage_info |
devi@0 | 520 { |
devi@92 | 521 print "Usage:\n\n\t$0 [host-list] command\n"; |
devi@92 | 522 print <<'USAGE'; |
devi@0 | 523 |
devi@0 | 524 Commands: |
devi@0 | 525 |
devi@92 | 526 next -- next lab |
devi@92 | 527 prev -- prev lab |
devi@92 | 528 set LAB -- set current lab to LAB |
devi@92 | 529 start -- start this day training |
devi@92 | 530 stop -- stop this day training |
devi@92 | 531 show hosts -- show available hosts in the class |
devi@92 | 532 show labs -- show available labs in the course |
devi@92 | 533 do COMMAND -- do specified command on the hosts of hostlist |
devi@92 | 534 report -- generate XML/HTML reports |
devi@0 | 535 |
devi@92 | 536 |
devi@0 | 537 do commands: |
devi@92 | 538 |
devi@92 | 539 install [PROFILE] -- install profile |
devi@92 | 540 |
devi@92 | 541 Host list: |
devi@0 | 542 |
devi@92 | 543 @N -- machine N |
devi@92 | 544 @N1-N2 -- all of the machines from N1 to N2 |
devi@92 | 545 @N1,N2,N3 -- machine N1, N2 and N3 |
devi@0 | 546 |
devi@92 | 547 N* is numbers or domain names of the machines. |
devi@92 | 548 |
devi@92 | 549 If host list is not specified, |
devi@92 | 550 command is executed on all of the machines |
devi@0 | 551 |
devi@40 | 552 USAGE |
devi@40 | 553 } |
devi@0 | 554 |
devi@0 | 555 |