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 # fetch all user currently assigned to the client at login_users_db
169 my %currently_logged_in_user = ();
170 $sql_statement = "SELECT * FROM $main::login_users_tn WHERE client='$source'";
171 $db_res = $main::login_users_db->select_dbentry($sql_statement);
172 while( my($hit_id, $hit) = each(%{$db_res}) ) {
173 $currently_logged_in_user{$hit->{'user'}} = 1;
174 }
175 &main::daemon_log("$session_id DEBUG: logged in users from login_user_db: ".join(", ", keys(%currently_logged_in_user)), 7);
177 #
178 my @logged_in_user = split(/\s+/, $login);
179 &main::daemon_log("$session_id DEBUG: logged in users reported from client: ".join(", ", @logged_in_user), 7);
180 foreach my $user (@logged_in_user) {
181 my %add_hash = ( table=>$main::login_users_tn,
182 primkey=> ['client', 'user'],
183 client=>$source,
184 user=>$user,
185 timestamp=>&get_time,
186 );
187 my ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
188 if ($res != 0) {
189 &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
190 return;
191 }
193 delete $currently_logged_in_user{$user};
194 }
196 # if there is still a user in %currently_logged_in_user
197 # although he is not reported by client
198 # then delete it from $login_user_db
199 foreach my $obsolete_user (keys(%currently_logged_in_user)) {
200 &main::daemon_log("$session_id WARNING: user '$obsolete_user' is currently not logged ".
201 "in at client '$source' but still found at login_user_db", 3);
202 my $sql_statement = "DELETE FROM $main::login_users_tn WHERE client='$source' AND user='$obsolete_user'";
203 my $res = $main::login_users_db->del_dbentry($sql_statement);
204 &main::daemon_log("$session_id WARNING: delete user '$obsolete_user' at client '$source' from login_user_db", 3);
205 }
207 return;
208 }
211 sub GOTOACTIVATION {
212 my ($msg, $msg_hash, $session_id) = @_;
213 my $header = @{$msg_hash->{'header'}}[0];
214 my $source = @{$msg_hash->{'target'}}[0];
215 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
217 # test whether content is an empty hash or a string which is required
218 my $content = @{$msg_hash->{$header}}[0];
219 eval{ if( 0 == keys(%$content) ) { $content = ""; } };
220 if( $@ ) { $content = "$content"; }
222 # clean up header
223 $header =~ s/CLMSG_//g;
225 my $sql_statement = "UPDATE $main::job_queue_tn ".
226 "SET status='processing', result='$header"."$content' ".
227 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
228 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
229 my $res = $main::job_db->update_dbentry($sql_statement);
230 &main::daemon_log("$session_id INFO: $header at '$macaddress'", 5);
231 return;
232 }
235 sub PROGRESS {
236 my ($msg, $msg_hash, $session_id) = @_;
237 my $header = @{$msg_hash->{'header'}}[0];
238 my $source = @{$msg_hash->{'target'}}[0];
239 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
241 # test whether content is an empty hash or a string which is required
242 my $content;
243 my $cont = @{$msg_hash->{$header}}[0];
244 eval{ if( 0 == keys(%$cont) ) { $content = ""; } };
245 if( $@ ) { $content = "$cont"; }
247 # clean up header
248 $header =~ s/CLMSG_//g;
250 my $sql_statement = "UPDATE $main::job_queue_tn ".
251 "SET progress='$content' ".
252 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
253 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
254 my $res = $main::job_db->update_dbentry($sql_statement);
255 &main::daemon_log("$session_id INFO: $header at '$macaddress' - $content%", 5);
257 return;
258 }
261 sub FAIREBOOT {
262 my ($msg, $msg_hash, $session_id) = @_;
263 my $header = @{$msg_hash->{'header'}}[0];
264 my $source = @{$msg_hash->{'target'}}[0];
265 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
267 # test whether content is an empty hash or a string which is required
268 my $content = @{$msg_hash->{$header}}[0];
269 eval{ if( 0 == keys(%$content) ) { $content = ""; } };
270 if( $@ ) { $content = "$content"; }
272 # clean up header
273 $header =~ s/CLMSG_//g;
275 my $sql_statement = "UPDATE $main::job_queue_tn ".
276 "SET status='processing', result='$header "."$content' ".
277 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
278 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
279 my $res = $main::job_db->update_dbentry($sql_statement);
280 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
282 return;
283 }
286 sub TASKSKIP {
287 my ($msg, $msg_hash, $session_id) = @_;
288 my $header = @{$msg_hash->{'header'}}[0];
289 my $source = @{$msg_hash->{'target'}}[0];
290 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
292 # test whether content is an empty hash or a string which is required
293 my $content = @{$msg_hash->{$header}}[0];
294 eval{ if( 0 == keys(%$content) ) { $content = ""; } };
295 if( $@ ) { $content = "$content"; }
297 # clean up header
298 $header =~ s/CLMSG_//g;
300 my $sql_statement = "UPDATE $main::job_queue_tn ".
301 "SET status='processing', result='$header "."$content' ".
302 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
303 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
304 my $res = $main::job_db->update_dbentry($sql_statement);
305 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
307 return;
308 }
311 sub TASKBEGIN {
312 my ($msg, $msg_hash, $session_id) = @_;
313 my $header = @{$msg_hash->{'header'}}[0];
314 my $source = @{$msg_hash->{'target'}}[0];
315 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
316 my $content = @{$msg_hash->{$header}}[0];
318 # test whether content is an empty hash or a string which is required
319 eval{ if( 0 == keys(%$content) ) { $content = ""; } };
320 if( $@ ) { $content = "$content"; }
322 # clean up header
323 $header =~ s/CLMSG_//g;
325 # check if installation finished
326 if (($content eq 'finish') || ($content eq 'faiend')){
327 my $sql_statement = "UPDATE $main::job_queue_tn ".
328 "SET status='done', result='$header "."$content' ".
329 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
330 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
331 my $res = $main::job_db->update_dbentry($sql_statement);
332 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
334 # set fai_state to localboot
335 &main::change_fai_state('localboot', \@{$msg_hash->{'macaddress'}}, $session_id);
337 } else {
338 my $sql_statement = "UPDATE $main::job_queue_tn ".
339 "SET status='processing', result='$header "."$content' ".
340 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
341 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
342 my $res = $main::job_db->update_dbentry($sql_statement);
343 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
346 # -----------------------> Update hier
347 # <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
348 # <header>CLMSG_TASKBEGIN</header>
349 # macaddress auslesen, Client im LDAP lokalisieren
350 # FAIstate auf "localboot" setzen, wenn FAIstate "install" oder "softupdate" war
351 }
353 return;
354 }
357 sub TASKEND {
358 my ($msg, $msg_hash, $session_id) = @_;
359 my $header = @{$msg_hash->{'header'}}[0];
360 my $source = @{$msg_hash->{'target'}}[0];
361 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
363 # test whether content is an empty hash or a string which is required
364 my $content = @{$msg_hash->{$header}}[0];
365 eval{ if( 0 == keys(%$content) ) { $content = ""; } };
366 if( $@ ) { $content = "$content"; }
368 # clean up header
369 $header =~ s/CLMSG_//g;
371 my $sql_statement = "UPDATE $main::job_queue_tn ".
372 "SET status='processing', result='$header "."$content' ".
373 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
374 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
375 my $res = $main::job_db->update_dbentry($sql_statement);
376 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
378 # -----------------------> Update hier
379 # <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
380 # <header>CLMSG_TASKBEGIN</header>
381 # macaddress auslesen, Client im LDAP lokalisieren
382 # FAIstate auf "error" setzen
384 return;
385 }
388 sub TASKERROR {
389 my ($msg, $msg_hash, $session_id) = @_;
390 my $header = @{$msg_hash->{'header'}}[0];
391 my $source = @{$msg_hash->{'target'}}[0];
392 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
394 # clean up header
395 $header =~ s/CLMSG_//g;
397 # test whether content is an empty hash or a string which is required
398 my $content = @{$msg_hash->{$header}}[0];
399 eval{ if( 0 == keys(%$content) ) { $content = ""; } };
400 if( $@ ) { $content = "$content"; }
402 my $sql_statement = "UPDATE $main::job_queue_tn ".
403 "SET status='processing', result='$header "."$content' ".
404 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
405 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
406 my $res = $main::job_db->update_dbentry($sql_statement);
407 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
409 # -----------------------> Update hier
410 # <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
411 # <header>CLMSG_TASKBEGIN</header>
412 # macaddress auslesen, Client im LDAP lokalisieren
413 # FAIstate auf "error" setzen
415 return;
416 }
419 sub HOOK {
420 my ($msg, $msg_hash, $session_id) = @_;
421 my $header = @{$msg_hash->{'header'}}[0];
422 my $source = @{$msg_hash->{'target'}}[0];
423 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
425 # clean up header
426 $header =~ s/CLMSG_//g;
428 # test whether content is an empty hash or a string which is required
429 my $content = @{$msg_hash->{$header}}[0];
430 eval{ if( 0 == keys(%$content) ) { $content = ""; } };
431 if( $@ ) { $content = "$content"; }
433 my $sql_statement = "UPDATE $main::job_queue_tn ".
434 "SET status='processing', result='$header "."$content' ".
435 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
436 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
437 my $res = $main::job_db->update_dbentry($sql_statement);
438 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
440 return;
441 }
444 1;