1 package clMessages;
2 use Exporter;
3 @ISA = qw(Exporter);
4 my @events = (
5 "PROGRESS",
6 "FAIREBOOT",
7 "TASKSKIP",
8 "TASKBEGIN",
9 "TASKEND",
10 "TASKERROR",
11 "HOOK",
12 "GOTOACTIVATION",
13 "LOGIN",
14 "LOGOUT",
15 "CURRENTLY_LOGGED_IN",
16 "save_fai_log",
17 );
18 @EXPORT = @events;
20 use strict;
21 use warnings;
22 use Data::Dumper;
23 use GOSA::GosaSupportDaemon;
24 use MIME::Base64;
27 BEGIN {}
29 END {}
31 ### Start ######################################################################
33 my $ldap_uri;
34 my $ldap_base;
35 my $ldap_admin_dn;
36 my $ldap_admin_password;
38 my %cfg_defaults = (
39 "server" => {
40 "ldap-uri" => [\$ldap_uri, ""],
41 "ldap-base" => [\$ldap_base, ""],
42 "ldap-admin-dn" => [\$ldap_admin_dn, ""],
43 "ldap-admin-password" => [\$ldap_admin_password, ""],
44 },
45 );
46 &read_configfile($main::cfg_file, %cfg_defaults);
49 sub get_events {
50 return \@events;
51 }
54 sub read_configfile {
55 my ($cfg_file, %cfg_defaults) = @_;
56 my $cfg;
58 if( defined( $cfg_file) && ( length($cfg_file) > 0 )) {
59 if( -r $cfg_file ) {
60 $cfg = Config::IniFiles->new( -file => $cfg_file );
61 } else {
62 &main::daemon_log("ERROR: clMessages.pm couldn't read config file!", 1);
63 }
64 } else {
65 $cfg = Config::IniFiles->new() ;
66 }
67 foreach my $section (keys %cfg_defaults) {
68 foreach my $param (keys %{$cfg_defaults{ $section }}) {
69 my $pinfo = $cfg_defaults{ $section }{ $param };
70 ${@$pinfo[0]} = $cfg->val( $section, $param, @$pinfo[1] );
71 }
72 }
73 }
76 sub save_fai_log {
77 my ($msg, $msg_hash, $session_id) = @_;
78 my $header = @{$msg_hash->{'header'}}[0];
79 my $source = @{$msg_hash->{'source'}}[0];
80 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
81 my $all_logs = @{$msg_hash->{$header}}[0];
83 # if there is nothing to log
84 if( ref($all_logs) eq "HASH" ) { return; }
86 my $client_fai_log_dir = $main::client_fai_log_dir;
87 if (not -d $client_fai_log_dir) {
88 mkdir($client_fai_log_dir, 0755)
89 }
91 $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, $macaddress );
92 if (not -d $client_fai_log_dir) {
93 mkdir($client_fai_log_dir, 0755)
94 }
96 my $time = &get_time;
97 $time = substr($time, 0, 8)."_".substr($time, 8, 6);
98 $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, "install-$time" );
99 mkdir($client_fai_log_dir, 0755);
101 my @all_logs = split(/log_file:/, $all_logs);
102 foreach my $log (@all_logs) {
103 if (length $log == 0) { next; };
104 my ($log_file, $log_string) = split("\n", $log, 2);
105 my $client_fai_log_file = File::Spec->catfile( $client_fai_log_dir, $log_file);
106 open(my $LOG_FILE, ">$client_fai_log_file");
107 print $LOG_FILE &decode_base64($log_string);
108 close($LOG_FILE);
109 }
110 return;
111 }
114 sub LOGIN {
115 my ($msg, $msg_hash, $session_id) = @_;
116 my $header = @{$msg_hash->{'header'}}[0];
117 my $source = @{$msg_hash->{'source'}}[0];
118 my $login = @{$msg_hash->{$header}}[0];
120 my %add_hash = ( table=>$main::login_users_tn,
121 primkey=> ['client', 'user'],
122 client=>$source,
123 user=>$login,
124 timestamp=>&get_time,
125 );
126 my ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
127 if ($res != 0) {
128 &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
129 return;
130 }
132 return;
133 }
135 # TODO umstellen wie bei LOGIN
136 sub LOGOUT {
137 my ($msg, $msg_hash, $session_id) = @_;
138 my $header = @{$msg_hash->{'header'}}[0];
139 my $source = @{$msg_hash->{'source'}}[0];
140 my $login = @{$msg_hash->{$header}}[0];
142 my $sql_statement = "SELECT * FROM known_clients WHERE hostname='$source'";
143 my $res = $main::known_clients_db->select_dbentry($sql_statement);
144 if( 1 != keys(%$res) ) {
145 &main::daemon_log("DEBUG: clMessages.pm: LOGOUT: no or more hits found in known_clients_db for host '$source'");
146 return;
147 }
149 my $act_login = $res->{'1'}->{'login'};
150 $act_login =~ s/$login,?//gi;
152 if( $act_login eq "" ){ $act_login = "nobody"; }
154 $sql_statement = "UPDATE known_clients SET login='$act_login' WHERE hostname='$source'";
155 $res = $main::known_clients_db->update_dbentry($sql_statement);
157 return;
158 }
161 sub CURRENTLY_LOGGED_IN {
162 my ($msg, $msg_hash, $session_id) = @_;
163 my ($sql_statement, $db_res);
164 my $header = @{$msg_hash->{'header'}}[0];
165 my $source = @{$msg_hash->{'source'}}[0];
166 my $login = @{$msg_hash->{$header}}[0];
168 if(ref $login eq "HASH") {
169 &main::daemon_log("$session_id INFO: no logged in users reported from host '$source'", 5);
170 return;
171 }
173 # fetch all user currently assigned to the client at login_users_db
174 my %currently_logged_in_user = ();
175 $sql_statement = "SELECT * FROM $main::login_users_tn WHERE client='$source'";
176 $db_res = $main::login_users_db->select_dbentry($sql_statement);
177 while( my($hit_id, $hit) = each(%{$db_res}) ) {
178 $currently_logged_in_user{$hit->{'user'}} = 1;
179 }
180 &main::daemon_log("$session_id DEBUG: logged in users from login_user_db: ".join(", ", keys(%currently_logged_in_user)), 7);
182 # update all reported users in login_user_db
183 my @logged_in_user = split(/\s+/, $login);
184 &main::daemon_log("$session_id DEBUG: logged in users reported from client: ".join(", ", @logged_in_user), 7);
185 foreach my $user (@logged_in_user) {
186 my %add_hash = ( table=>$main::login_users_tn,
187 primkey=> ['client', 'user'],
188 client=>$source,
189 user=>$user,
190 timestamp=>&get_time,
191 );
192 my ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
193 if ($res != 0) {
194 &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
195 return;
196 }
198 delete $currently_logged_in_user{$user};
199 }
201 # if there is still a user in %currently_logged_in_user
202 # although he is not reported by client
203 # then delete it from $login_user_db
204 foreach my $obsolete_user (keys(%currently_logged_in_user)) {
205 &main::daemon_log("$session_id WARNING: user '$obsolete_user' is currently not logged ".
206 "in at client '$source' but still found at login_user_db", 3);
207 my $sql_statement = "DELETE FROM $main::login_users_tn WHERE client='$source' AND user='$obsolete_user'";
208 my $res = $main::login_users_db->del_dbentry($sql_statement);
209 &main::daemon_log("$session_id WARNING: delete user '$obsolete_user' at client '$source' from login_user_db", 3);
210 }
212 return;
213 }
216 sub GOTOACTIVATION {
217 my ($msg, $msg_hash, $session_id) = @_;
218 my $header = @{$msg_hash->{'header'}}[0];
219 my $source = @{$msg_hash->{'target'}}[0];
220 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
222 # test whether content is an empty hash or a string which is required
223 my $content = @{$msg_hash->{$header}}[0];
224 eval{ if( 0 == keys(%$content) ) { $content = ""; } };
225 if( $@ ) { $content = "$content"; }
227 # clean up header
228 $header =~ s/CLMSG_//g;
230 my $sql_statement = "UPDATE $main::job_queue_tn ".
231 "SET status='processing', result='$header"."$content' ".
232 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
233 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
234 my $res = $main::job_db->update_dbentry($sql_statement);
235 &main::daemon_log("$session_id INFO: $header at '$macaddress'", 5);
236 return;
237 }
240 sub PROGRESS {
241 my ($msg, $msg_hash, $session_id) = @_;
242 my $header = @{$msg_hash->{'header'}}[0];
243 my $source = @{$msg_hash->{'target'}}[0];
244 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
246 # test whether content is an empty hash or a string which is required
247 my $content;
248 my $cont = @{$msg_hash->{$header}}[0];
249 eval{ if( 0 == keys(%$cont) ) { $content = ""; } };
250 if( $@ ) { $content = "$cont"; }
252 # clean up header
253 $header =~ s/CLMSG_//g;
255 my $sql_statement = "UPDATE $main::job_queue_tn ".
256 "SET progress='$content' ".
257 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
258 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
259 my $res = $main::job_db->update_dbentry($sql_statement);
260 &main::daemon_log("$session_id INFO: $header at '$macaddress' - $content%", 5);
262 return;
263 }
266 sub FAIREBOOT {
267 my ($msg, $msg_hash, $session_id) = @_;
268 my $header = @{$msg_hash->{'header'}}[0];
269 my $source = @{$msg_hash->{'target'}}[0];
270 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
272 # test whether content is an empty hash or a string which is required
273 my $content = @{$msg_hash->{$header}}[0];
274 eval{ if( 0 == keys(%$content) ) { $content = ""; } };
275 if( $@ ) { $content = "$content"; }
277 # clean up header
278 $header =~ s/CLMSG_//g;
280 my $sql_statement = "UPDATE $main::job_queue_tn ".
281 "SET status='processing', result='$header "."$content' ".
282 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
283 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
284 my $res = $main::job_db->update_dbentry($sql_statement);
285 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
287 return;
288 }
291 sub TASKSKIP {
292 my ($msg, $msg_hash, $session_id) = @_;
293 my $header = @{$msg_hash->{'header'}}[0];
294 my $source = @{$msg_hash->{'target'}}[0];
295 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
297 # test whether content is an empty hash or a string which is required
298 my $content = @{$msg_hash->{$header}}[0];
299 eval{ if( 0 == keys(%$content) ) { $content = ""; } };
300 if( $@ ) { $content = "$content"; }
302 # clean up header
303 $header =~ s/CLMSG_//g;
305 my $sql_statement = "UPDATE $main::job_queue_tn ".
306 "SET status='processing', result='$header "."$content' ".
307 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
308 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
309 my $res = $main::job_db->update_dbentry($sql_statement);
310 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
312 return;
313 }
316 sub TASKBEGIN {
317 my ($msg, $msg_hash, $session_id) = @_;
318 my $header = @{$msg_hash->{'header'}}[0];
319 my $source = @{$msg_hash->{'target'}}[0];
320 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
321 my $content = @{$msg_hash->{$header}}[0];
323 # test whether content is an empty hash or a string which is required
324 eval{ if( 0 == keys(%$content) ) { $content = ""; } };
325 if( $@ ) { $content = "$content"; }
327 # clean up header
328 $header =~ s/CLMSG_//g;
330 # check if installation finished
331 if (($content eq 'finish') || ($content eq 'faiend')){
332 my $sql_statement = "UPDATE $main::job_queue_tn ".
333 "SET status='done', result='$header "."$content' ".
334 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
335 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
336 my $res = $main::job_db->update_dbentry($sql_statement);
337 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
339 # set fai_state to localboot
340 &main::change_fai_state('localboot', \@{$msg_hash->{'macaddress'}}, $session_id);
342 } else {
343 my $sql_statement = "UPDATE $main::job_queue_tn ".
344 "SET status='processing', result='$header "."$content' ".
345 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
346 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
347 my $res = $main::job_db->update_dbentry($sql_statement);
348 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
351 # -----------------------> Update hier
352 # <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
353 # <header>CLMSG_TASKBEGIN</header>
354 # macaddress auslesen, Client im LDAP lokalisieren
355 # FAIstate auf "localboot" setzen, wenn FAIstate "install" oder "softupdate" war
356 }
358 return;
359 }
362 sub TASKEND {
363 my ($msg, $msg_hash, $session_id) = @_;
364 my $header = @{$msg_hash->{'header'}}[0];
365 my $source = @{$msg_hash->{'target'}}[0];
366 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
368 # test whether content is an empty hash or a string which is required
369 my $content = @{$msg_hash->{$header}}[0];
370 eval{ if( 0 == keys(%$content) ) { $content = ""; } };
371 if( $@ ) { $content = "$content"; }
373 # clean up header
374 $header =~ s/CLMSG_//g;
376 my $sql_statement = "UPDATE $main::job_queue_tn ".
377 "SET status='processing', result='$header "."$content' ".
378 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
379 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
380 my $res = $main::job_db->update_dbentry($sql_statement);
381 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
383 # -----------------------> Update hier
384 # <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
385 # <header>CLMSG_TASKBEGIN</header>
386 # macaddress auslesen, Client im LDAP lokalisieren
387 # FAIstate auf "error" setzen
389 return;
390 }
393 sub TASKERROR {
394 my ($msg, $msg_hash, $session_id) = @_;
395 my $header = @{$msg_hash->{'header'}}[0];
396 my $source = @{$msg_hash->{'target'}}[0];
397 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
399 # clean up header
400 $header =~ s/CLMSG_//g;
402 # test whether content is an empty hash or a string which is required
403 my $content = @{$msg_hash->{$header}}[0];
404 eval{ if( 0 == keys(%$content) ) { $content = ""; } };
405 if( $@ ) { $content = "$content"; }
407 my $sql_statement = "UPDATE $main::job_queue_tn ".
408 "SET status='processing', result='$header "."$content' ".
409 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
410 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
411 my $res = $main::job_db->update_dbentry($sql_statement);
412 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
414 # -----------------------> Update hier
415 # <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
416 # <header>CLMSG_TASKBEGIN</header>
417 # macaddress auslesen, Client im LDAP lokalisieren
418 # FAIstate auf "error" setzen
420 return;
421 }
424 sub HOOK {
425 my ($msg, $msg_hash, $session_id) = @_;
426 my $header = @{$msg_hash->{'header'}}[0];
427 my $source = @{$msg_hash->{'target'}}[0];
428 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
430 # clean up header
431 $header =~ s/CLMSG_//g;
433 # test whether content is an empty hash or a string which is required
434 my $content = @{$msg_hash->{$header}}[0];
435 eval{ if( 0 == keys(%$content) ) { $content = ""; } };
436 if( $@ ) { $content = "$content"; }
438 my $sql_statement = "UPDATE $main::job_queue_tn ".
439 "SET status='processing', result='$header "."$content' ".
440 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
441 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
442 my $res = $main::job_db->update_dbentry($sql_statement);
443 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
445 return;
446 }
449 1;