lilalo

annotate lm @ 100:2c00c61f2d7b

Коммичу изменения, но сам не знаю зачем.
Нужно l3-cgi переписать вообще с нуля.
Он мерзкий.

И продумать нужно, как он вообще должен работать.
Понятно, приблизительно, как он должен показывать журнал,
когда до него уже дошли,
но вот если не дошли, то что делать не понятно.
Короче, продумать систему навигации.
author devi
date Wed Jun 14 21:37:22 2006 +0300 (2006-06-14)
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