Code

first code snippets of messaging handling
[gosa.git] / gosa-si / server / events / clMessages.pm
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) && ( (-s $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; }
85         
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(":", $log);
105         my $client_fai_log_file = File::Spec->catfile( $client_fai_log_dir, $log_file);
107         open(my $LOG_FILE, ">$client_fai_log_file"); 
108         print $LOG_FILE &decode_base64($log_string);
109         close($LOG_FILE);
111     }
112     return;
116 sub LOGIN {
117     my ($msg, $msg_hash, $session_id) = @_;
118     my $header = @{$msg_hash->{'header'}}[0];
119     my $source = @{$msg_hash->{'source'}}[0];
120     my $login = @{$msg_hash->{$header}}[0];
122     my %add_hash = ( table=>$main::login_users_tn, 
123         primkey=> ['client', 'user'],
124         client=>$source,
125         user=>$login,
126         timestamp=>&get_time,
127         ); 
128     my ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
129     if ($res != 0)  {
130         &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
131         return;
132     }
134     return;   
138 sub LOGOUT {
139     my ($msg, $msg_hash, $session_id) = @_;
140     my $header = @{$msg_hash->{'header'}}[0];
141     my $source = @{$msg_hash->{'source'}}[0];
142     my $login = @{$msg_hash->{$header}}[0];
143     
144     my $sql_statement = "DELETE FROM $main::login_users_tn WHERE (client='$source' AND user='$login')"; 
145     my $res =  $main::login_users_db->del_dbentry($sql_statement);
146     &main::daemon_log("$session_id INFO: delete user '$login' at client '$source' from login_user_db", 5); 
147     
148     return;
152 sub CURRENTLY_LOGGED_IN {
153     my ($msg, $msg_hash, $session_id) = @_;
154     my ($sql_statement, $db_res);
155     my $header = @{$msg_hash->{'header'}}[0];
156     my $source = @{$msg_hash->{'source'}}[0];
157     my $login = @{$msg_hash->{$header}}[0];
159     if(ref $login eq "HASH") { 
160         &main::daemon_log("$session_id INFO: no logged in users reported from host '$source'", 5); 
161         return;     
162     }
163     
164     # fetch all user currently assigned to the client at login_users_db
165     my %currently_logged_in_user = (); 
166     $sql_statement = "SELECT * FROM $main::login_users_tn WHERE client='$source'"; 
167     $db_res = $main::login_users_db->select_dbentry($sql_statement);
168     while( my($hit_id, $hit) = each(%{$db_res}) ) {
169         $currently_logged_in_user{$hit->{'user'}} = 1;
170     }
171     &main::daemon_log("$session_id DEBUG: logged in users from login_user_db: ".join(", ", keys(%currently_logged_in_user)), 7); 
173     # update all reported users in login_user_db
174     my @logged_in_user = split(/\s+/, $login);
175     &main::daemon_log("$session_id DEBUG: logged in users reported from client: ".join(", ", @logged_in_user), 7); 
176     foreach my $user (@logged_in_user) {
177         my %add_hash = ( table=>$main::login_users_tn, 
178                 primkey=> ['client', 'user'],
179                 client=>$source,
180                 user=>$user,
181                 timestamp=>&get_time,
182                 ); 
183         my ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
184         if ($res != 0)  {
185             &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
186             return;
187         }
189         delete $currently_logged_in_user{$user};
190     }
192     # if there is still a user in %currently_logged_in_user 
193     # although he is not reported by client 
194     # then delete it from $login_user_db
195     foreach my $obsolete_user (keys(%currently_logged_in_user)) {
196         &main::daemon_log("$session_id WARNING: user '$obsolete_user' is currently not logged ".
197                 "in at client '$source' but still found at login_user_db", 3); 
198         my $sql_statement = "DELETE FROM $main::login_users_tn WHERE client='$source' AND user='$obsolete_user'"; 
199         my $res =  $main::login_users_db->del_dbentry($sql_statement);
200         &main::daemon_log("$session_id WARNING: delete user '$obsolete_user' at client '$source' from login_user_db", 3); 
201     }
203     return;
207 sub GOTOACTIVATION {
208     my ($msg, $msg_hash, $session_id) = @_;
209     my $header = @{$msg_hash->{'header'}}[0];
210     my $source = @{$msg_hash->{'target'}}[0];
211     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
213     # test whether content is an empty hash or a string which is required
214     my $content = @{$msg_hash->{$header}}[0];
215     if(ref($content) eq "HASH") { $content = ""; }
217     # clean up header
218     $header =~ s/CLMSG_//g;
220     my $sql_statement = "UPDATE $main::job_queue_tn ".
221             "SET status='processing', progress='goto-activation' ".
222             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
223     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
224     my $res = $main::job_db->update_dbentry($sql_statement);
225     &main::daemon_log("$session_id INFO: $header at '$macaddress'", 5); 
226     return; 
230 sub PROGRESS {
231     my ($msg, $msg_hash, $session_id) = @_;
232     my $header = @{$msg_hash->{'header'}}[0];
233     my $source = @{$msg_hash->{'target'}}[0];
234     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
236     # test whether content is an empty hash or a string which is required
237     my $content = @{$msg_hash->{$header}}[0];
238     if(ref($content) eq "HASH") { $content = ""; }
240     # clean up header
241     $header =~ s/CLMSG_//g;
243     my $sql_statement = "UPDATE $main::job_queue_tn ".
244         "SET progress='$content' ".
245         "WHERE status='processing' AND macaddress LIKE '$macaddress'";
246     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
247     my $res = $main::job_db->update_dbentry($sql_statement);
248     &main::daemon_log("$session_id INFO: $header at '$macaddress' - $content%", 5); 
250     return;
254 sub FAIREBOOT {
255     my ($msg, $msg_hash, $session_id) = @_;
256     my $header = @{$msg_hash->{'header'}}[0];
257     my $source = @{$msg_hash->{'target'}}[0];
258     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
260     # test whether content is an empty hash or a string which is required
261         my $content = @{$msg_hash->{$header}}[0];
262     if(ref($content) eq "HASH") { $content = ""; }
264     # clean up header
265     $header =~ s/CLMSG_//g;
267     my $sql_statement = "UPDATE $main::job_queue_tn ".
268             "SET status='processing', result='$header "."$content' ".
269             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
270     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
271     my $res = $main::job_db->update_dbentry($sql_statement);
272     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
274     return; 
278 sub TASKSKIP {
279     my ($msg, $msg_hash, $session_id) = @_;
280     my $header = @{$msg_hash->{'header'}}[0];
281     my $source = @{$msg_hash->{'target'}}[0];
282     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
284     # test whether content is an empty hash or a string which is required
285         my $content = @{$msg_hash->{$header}}[0];
286     if(ref($content) eq "HASH") { $content = ""; }
288     # clean up header
289     $header =~ s/CLMSG_//g;
291     my $sql_statement = "UPDATE $main::job_queue_tn ".
292             "SET status='processing', result='$header "."$content' ".
293             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
294     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
295     my $res = $main::job_db->update_dbentry($sql_statement);
296     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
298     return; 
302 sub TASKBEGIN {
303     my ($msg, $msg_hash, $session_id) = @_;
304     my $header = @{$msg_hash->{'header'}}[0];
305     my $source = @{$msg_hash->{'target'}}[0];
306     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
308     # test whether content is an empty hash or a string which is required
309         my $content = @{$msg_hash->{$header}}[0];
310     if(ref($content) eq "HASH") { $content = ""; }
312     # clean up header
313     $header =~ s/CLMSG_//g;
315     # TASKBEGIN eq finish or faiend 
316     if (($content eq 'finish') || ($content eq 'faiend')){
317         my $sql_statement = "UPDATE $main::job_queue_tn ".
318             "SET status='done', result='$header "."$content' ".
319             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
320         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
321         my $res = $main::job_db->update_dbentry($sql_statement);
322         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
323         
324         # set fai_state to localboot
325         &main::change_fai_state('localboot', \@{$msg_hash->{'macaddress'}}, $session_id);
327         # other TASKBEGIN msgs
328     } else {
329                 # select processing jobs for host
330                 my $sql_statement = "SELECT * FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
331                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
332                 my $res = $main::job_db->select_dbentry($sql_statement);
334                 # there is exactly one job entry in queue for this host
335                 if (keys(%$res) == 1) {
336                         &main::daemon_log("$session_id DEBUG: there is already one processing job in queue for host '$macaddress', run an update for this entry", 7);
337                         my $sql_statement = "UPDATE $main::job_queue_tn SET result='$header $content' WHERE status='processing' AND macaddress LIKE '$macaddress'";
338                         my $err = $main::job_db->update_dbentry($sql_statement);
339                         if (not defined  $err) {
340                                 &main::daemon_log("$session_id ERROR: cannot update job_db entry: ".Dumper($err), 1);
341                         }
342                         
343                 # there is no entry or more than one enties
344                 } else {
345                         # in case of more than one running jobs in queue, delete all jobs
346                         if (keys(%$res) > 1) {
347                                 &main::daemon_log("$session_id DEBUG: there are more than one processing job in queue for host '$macaddress', ".
348                                                                 "delete entries", 7); 
350                                 my $sql_statement = "DELETE FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'";
351                                 my ($err) = $main::job_db->del_dbentry($sql_statement);
352                                 if (not defined $err) {
353                                         &main::daemon_log("$session_id ERROR: can not delete multiple processing queue entries for host '$macaddress': ".Dumper($err), 1); 
354                                 }
355                         }
356                 
357                         # in case of no and more than one running jobs in queue, add on single job
358                         &main::daemon_log("$session_id DEBUG: add job to queue for host '$macaddress'", 7); 
359                         my $func_dic = {table=>$main::job_queue_tn,
360                                         primkey=>['id'],
361                                         timestamp=>&get_time,
362                                         status=>'processing',
363                                         result=>"$header $content",
364                                         progress=>'none',
365                                         headertag=>'trigger_action_reinstall',
366                                         targettag=>$source,
367                                         xmlmessage=>'none',
368                                         macaddress=>$macaddress,
369                         };
370                         my ($err, $error_str) = $main::job_db->add_dbentry($func_dic);
371                         if ($err != 0)  {
372                                         &main::daemon_log("$session_id ERROR: cannot add entry to job_db: $error_str", 1);
373                         }
375                 }
377 # -----------------------> Update hier
378 #  <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
379 #  <header>CLMSG_TASKBEGIN</header>
380 # macaddress auslesen, Client im LDAP lokalisieren
381 # FAIstate auf "localboot" setzen, wenn FAIstate "install" oder "softupdate" war
382     }
384     return; 
388 sub TASKEND {
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     # test whether content is an empty hash or a string which is required
395     my $content = @{$msg_hash->{$header}}[0];
396     if(ref($content) eq "HASH") { $content = ""; }
398     # clean up header
399     $header =~ s/CLMSG_//g;
401         if ($content eq "savelog 0") {
402                 &main::daemon_log("$session_id DEBUG: got savelog from host '$source' - jub done", 7);
403                 my $sql_statement = "DELETE FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
404                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
405                 my $res = $main::job_db->del_dbentry($sql_statement);
407         } else {
409                         my $sql_statement = "UPDATE $main::job_queue_tn ".
410                                         "SET status='processing', result='$header "."$content' ".
411                                         "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
412                         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
413                         my $res = $main::job_db->update_dbentry($sql_statement);
414                         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
416         }
417 # -----------------------> Update hier
418 #  <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
419 #  <header>CLMSG_TASKBEGIN</header>
420 # macaddress auslesen, Client im LDAP lokalisieren
421 # FAIstate auf "error" setzen
423     return; 
427 sub TASKERROR {
428     my ($msg, $msg_hash, $session_id) = @_;
429     my $header = @{$msg_hash->{'header'}}[0];
430     my $source = @{$msg_hash->{'target'}}[0];
431     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
433     # clean up header
434     $header =~ s/CLMSG_//g;
436     # test whether content is an empty hash or a string which is required
437     my $content = @{$msg_hash->{$header}}[0];
438     if(ref($content) eq "HASH") { $content = ""; } 
440         # set fai_state to localboot
441         &main::change_fai_state('error', \@{$msg_hash->{'macaddress'}}, $session_id);
442                 
443     my $sql_statement = "UPDATE $main::job_queue_tn ".
444             "SET status='processing', result='$header "."$content' ".
445             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
446     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
447     my $res = $main::job_db->update_dbentry($sql_statement);
448     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
450 # -----------------------> Update hier
451 #  <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
452 #  <header>CLMSG_TASKBEGIN</header>
453 # macaddress auslesen, Client im LDAP lokalisieren
454 # FAIstate auf "error" setzen
456     return; 
460 sub HOOK {
461     my ($msg, $msg_hash, $session_id) = @_;
462     my $header = @{$msg_hash->{'header'}}[0];
463     my $source = @{$msg_hash->{'target'}}[0];
464     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
466     # clean up header
467     $header =~ s/CLMSG_//g;
469     # test whether content is an empty hash or a string which is required
470         my $content = @{$msg_hash->{$header}}[0];
471     if(ref($content) eq "HASH") { $content = ""; }
473     my $sql_statement = "UPDATE $main::job_queue_tn ".
474             "SET status='processing', result='$header "."$content' ".
475             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
476     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
477     my $res = $main::job_db->update_dbentry($sql_statement);
478     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
480     return;
484 1;