Handle hostnames with upper-case letters
[webmin.git] / heartbeat / heartbeat-lib.pl
1 # heartbeat-lib.pl
2 # Common functions for heartbeat tool configuration
3
4 BEGIN { push(@INC, ".."); };
5 use WebminCore;
6 &init_config();
7
8 $ha_cf = $config{'ha_cf'} ? $config{'ha_cf'} : "$config{'ha_dir'}/ha.cf";
9 $haresources = $config{'haresources'} ? $config{'haresources'}
10                                       : "$config{'ha_dir'}/haresources";
11 $authkeys = $config{'authkeys'} ? $config{'authkeys'}
12                                 : "$config{'ha_dir'}/authkeys";
13 $resource_d = $config{'resource_d'} ? $config{'resource_d'}
14                                     : "$config{'ha_dir'}/resource.d";
15
16 open(VERSION, "$module_config_directory/version");
17 chop($heartbeat_version = <VERSION>);
18 close(VERSION);
19
20 sub get_ha_config
21 {
22 local @rv;
23 local $lnum = 0;
24 open(CONF, $ha_cf);
25 while(<CONF>) {
26         s/\s+$//;
27         s/#.*$//;
28         if (/^(\S+)\s+(\S.*)$/) {
29                 push(@rv, { 'name' => $1,
30                             'value' => $2,
31                             'line' => $lnum });
32                 }
33         $lnum++;
34         }
35 close(CONF);
36 return @rv;
37 }
38
39 # find(name, &config)
40 sub find
41 {
42 local @rv;
43 foreach $c (@{$_[1]}) {
44         if ($c->{'name'} eq $_[0]) {
45                 push(@rv, $c->{'value'});
46                 }
47         }
48 return wantarray ? @rv : @rv==0 ? undef : $rv[0];
49 }
50
51 # find_struct(name, &config)
52 sub find_struct
53 {
54 local @rv;
55 foreach $c (@{$_[1]}) {
56         if ($c->{'name'} eq $_[0]) {
57                 push(@rv, $c);
58                 }
59         }
60 return wantarray ? @rv : @rv==0 ? undef : $rv[0];
61 }
62
63 # save_directive(&config, name, &values)
64 sub save_directive
65 {
66 local $lref = &read_file_lines($ha_cf);
67 local @old = &find_struct($_[1], $_[0]);
68 for($i=0; $i<@old || $i<@{$_[2]}; $i++) {
69         if ($i >= @old) {
70                 # adding a directive
71                 push(@$lref, "$_[1]\t$_[2]->[$i]");
72                 push(@{$_[0]}, { 'name' => $_[1],
73                                  'value' => $_[2]->[$i],
74                                  'line' => scalar(@$lref)-1 });
75                 }
76         elsif ($i >= @{$_[2]}) {
77                 # removing a directive
78                 splice(@$lref, $old[$i]->{'line'}, 1);
79                 splice(@{$_[0]}, &indexof($old[$i], @{$_[0]}), 1);
80                 &renumber($_[0], $old[$i]->{'line'}, -1);
81                 }
82         else {
83                 # updating a directive
84                 splice(@$lref, $old[$i]->{'line'}, 1, "$_[1]\t$_[2]->[$i]");
85                 $old[$i]->{'value'} = $_[2]->[$i];
86                 }
87         }
88 }
89
90 # renumber(&config, line, offset)
91 sub renumber
92 {
93 foreach $c (@{$_[0]}) {
94         if ($c->{'line'} > $_[1]) {
95                 $c->{'line'} += $_[2];
96                 }
97         }
98 }
99
100 sub list_resources()
101 {
102 local @rv;
103 local $lnum = 0;
104 open(RES, $haresources);
105 while(<RES>) {
106         s/\s+$//;
107         s/#.*$//;
108         local @res = split(/\s+/, $_);
109         if (@res > 0) {
110                 local $r = { 'node' => shift(@res),
111                              'line' => $lnum };
112                 foreach $v (@res) {
113                         if ($v =~ /^[0-9\.\/]+$/) {
114                                 push(@{$r->{'ips'}}, $v);
115                                 }
116                         elsif ($v =~ /^IPaddr::(\S+)$/) {
117                                 push(@{$r->{'ips'}}, $1);
118                                 }
119                         else {
120                                 push(@{$r->{'servs'}}, $v);
121                                 }
122                         }
123                 push(@rv, $r);
124                 }
125         $lnum++;
126         }
127 close(RES);
128 return @rv;
129 }
130
131 sub create_resource
132 {
133 local $lref = &read_file_lines($haresources);
134 push(@$lref, &resource_line($_[0]));
135 &flush_file_lines();
136 }
137
138 sub modify_resource
139 {
140 local $lref = &read_file_lines($haresources);
141 $lref->[$_[0]->{'line'}] = &resource_line($_[0]);
142 &flush_file_lines();
143 }
144
145 sub delete_resource
146 {
147 local $lref = &read_file_lines($haresources);
148 splice(@$lref, $_[0]->{'line'}, 1);
149 &flush_file_lines();
150 }
151
152 sub resource_line
153 {
154 local @l = ( $_[0]->{'node'} );
155 push(@l, @{$_[0]->{'ips'}});
156 push(@l, @{$_[0]->{'servs'}});
157 return join(" ", @l);
158 }
159
160 sub get_auth_config
161 {
162 local $rv;
163 open(AUTH, $authkeys);
164 while(<AUTH>) {
165         s/\r|\n//g;
166         s/#.*$//;
167         local @l = split(/\s+/, $_);
168         if (@l > 0) {
169                 $rv->{shift(@l)} = \@l;
170                 }
171         }
172 close(AUTH);
173 return $rv;
174 }
175
176 sub save_auth_config
177 {
178 local %auth;
179 &open_tempfile(AUTH, ">$authkeys");
180 if ($_[0]->{'auth'}) {
181         &print_tempfile(AUTH, "auth ",join(" ", @{$_[0]->{'auth'}}),"\n");
182         map { $auth{$_}++ } @{$_[0]->{'auth'}};
183         }
184 foreach $k (keys %{$_[0]}) {
185         if ($k ne 'auth') {
186                 &print_tempfile(AUTH, "# ") if (!$auth{$k});
187                 &print_tempfile(AUTH, "$k ",join(" ", @{$_[0]->{$k}}),"\n");
188                 }
189         }
190 &close_tempfile(AUTH);
191 }
192
193 # add two more functions (Christof Amelunxen, 22.08.2003)
194 sub check_status_resource {
195         @ips = @_;
196         $ifconfig="/sbin/ifconfig";
197         @lines=qx|$ifconfig| or die("ifconfig does not seem to work: ".$!);
198         foreach(@lines){
199         if(/inet addr:([\d.]+)/){ 
200                 push(@realips,$1);
201         }
202         }
203         $iplist = join (' ',@realips);
204         foreach my $ip (@ips) {
205                 $ip =~ s/\/.*//;
206                 return 0 unless ( $iplist =~ m/$ip/);
207         }               
208         return 1;
209 }
210
211 sub get_resource {
212         foreach(@_) {
213                 system("$config{req_resource_cmd} $_");
214         }
215 }       
216
217 # version_atleast(v1, v2, v3)
218 sub version_atleast
219 {
220 local @vsp = split(/\./, $heartbeat_version);
221 local $i;
222 for($i=0; $i<@vsp || $i<@_; $i++) {
223         return 0 if ($vsp[$i] < $_[$i]);
224         return 1 if ($vsp[$i] > $_[$i]);
225         }
226 return 1;       # same!
227 }
228
229 # apply_configuration()
230 # Apply the heartbeat configuration, and return undef on success or an error
231 # message on failure
232 sub apply_configuration
233 {
234 if ($config{'apply_cmd'}) {
235         $out = &backquote_logged("$config{'apply_cmd'} 2>&1 </dev/null");
236         if ($?) {
237                 return $out;
238                 }
239         }
240 else {
241         local $pid = &check_pid_file($config{'pid_file'});
242         if ($pid) {
243                 kill(HUP, $pid);
244                 }
245         else {
246                 return $text{'apply_epid'};
247                 }
248         }
249 return undef;
250 }
251
252 1;
253