Handle hostnames with upper-case letters
[webmin.git] / cfengine / cluster.cgi
1 #!/usr/local/bin/perl
2 # cluster.cgi
3 # Optionally copy to and run the configuration on all managed hosts
4
5 require './cfengine-lib.pl';
6 &foreign_require("servers", "servers-lib.pl");
7 &ReadParse();
8 &ui_print_header(undef, $text{'cluster_title'}, "");
9 $| = 1;
10
11 # Build options string
12 $args .= " -v" if ($in{'verbose'});
13 $args .= " --dry-run" if ($in{'dry'});
14 $args .= " -i" if ($in{'noifc'});
15 $args .= " -m" if ($in{'nomnt'});
16 $args .= " -s" if ($in{'nocmd'});
17 $args .= " -t" if ($in{'notidy'});
18 $args .= " -X" if ($in{'nolinks'});
19
20 # Setup error handler for down hosts
21 sub run_error
22 {
23 $run_error_msg = join("", @_);
24 }
25 &remote_error_setup(\&run_error);
26
27 # Run on all hosts
28 print "<b>$text{'cluster_header'}</b><p>\n";
29 @hosts = &list_cfengine_hosts();
30 @servers = &list_servers();
31 $p = 0;
32 foreach $h (@hosts) {
33         local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers;
34  
35         local ($rh = "READ$p", $wh = "WRITE$p");
36         pipe($rh, $wh);
37         if (!fork()) {
38                 close($rh);
39                 &remote_foreign_require($s->{'host'}, "cfengine",
40                                         "cfengine-lib.pl");
41                 if ($run_error_msg) {
42                         # Host is down
43                         print $wh &serialise_variable([ 0, $run_error_msg ]);
44                         exit;
45                         }
46                 local $rconf = &remote_eval($s->{'host'}, "cfengine",
47                                 "\$cfengine_conf");
48
49                 # Copy the config if requested and if not local
50                 if ($in{'copy'} && $s->{'id'}) {
51                         $lst = [ stat($cfengine_conf) ];
52                         $rst = &remote_eval($s->{'host'}, "cfengine",
53                                         '[ stat($cfengine_conf) ]');
54                         if ($lst->[1] != $rst->[1] ||
55                             $lst->[7] != $rst->[7] ||
56                             $lst->[9] != $rst->[9]) {
57                                 &remote_write($s->{'host'}, $cfengine_conf, $rconf);
58                                 }
59                         }
60
61                 # Execute code to run cfengine
62                 $out = &remote_eval($s->{'host'}, "cfengine",
63                         "\$ENV{'CFINPUTS'} = \$config{'cfengine_dir'}; `\$config{'cfengine'} -f \$cfengine_conf $args 2>&1 </dev/null`");
64                 print $wh &serialise_variable([ 1, $out ]);
65                 close($wh);
66                 exit;
67                 }
68         close($wh);
69         $p++;
70         }
71
72 # Read back the results
73 $p = 0;
74 foreach $h (@hosts) {
75         local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers;
76         local $d = $s->{'desc'} ? $s->{'desc'} : $s->{'host'};
77         local $rh = "READ$p";
78         local $line = <$rh>;
79         local $rv = &unserialise_variable($line);
80         close($rh);
81
82         print &ui_hr();
83         if ($rv && $rv->[0]) {
84                 # Run ok! Show the output
85                 print "<font size=+1>",&text('cluster_success', $d),"</font><br>\n";
86                 print "<font size=-1><pre>$rv->[1]</pre></font>\n";
87                 }
88         else {
89                 # Something went wrong
90                 print &text('cluster_failed', $d, $rv->[1]),"<br>\n";
91                 }
92         $p++;
93         }
94
95 &remote_finished();
96 &ui_print_footer("list_hosts.cgi", $text{'hosts_return'});
97