1 ## @file
2 # @brief Implementation of a GOsa-SI event module.
3 # @details A GOsa-SI event module containing all functions to handle incoming messages from clients.
5 package clMessages;
6 use Exporter;
7 @ISA = qw(Exporter);
8 my @events = (
9 "confirm_usr_msg",
10 "PROGRESS",
11 "FAIREBOOT",
12 "TASKSKIP",
13 "TASKBEGIN",
14 "TASKEND",
15 "TASKERROR",
16 "HOOK",
17 "GOTOACTIVATION",
18 "LOGIN",
19 "LOGOUT",
20 "CURRENTLY_LOGGED_IN",
21 "save_fai_log",
22 );
23 @EXPORT = @events;
25 use strict;
26 use warnings;
27 use Data::Dumper;
28 use GOSA::GosaSupportDaemon;
29 use MIME::Base64;
32 BEGIN {}
34 END {}
37 ## @method get_events()
38 # @details A brief function returning a list of functions which are exported by importing the module.
39 # @return List of all provided functions
40 sub get_events {
41 return \@events;
42 }
44 ## @method confirm_usr_msg()
45 # @details Confirmed messages are set in the messaging_db from d (deliverd) to s(seen).
46 # @param msg - STRING - xml message with tags 'message', 'subject' and 'usr'
47 # @param msg_hash - HASHREF - message information parsed into a hash
48 # @param session_id - INTEGER - POE session id of the processing of this message
49 sub confirm_usr_msg {
50 my ($msg, $msg_hash, $session_id) = @_;
51 my $message = @{$msg_hash->{'message'}}[0];
52 my $subject = @{$msg_hash->{'subject'}}[0];
53 my $usr = @{$msg_hash->{'usr'}}[0];
55 # set update for this message
56 my $sql = "UPDATE $main::messaging_tn SET flag='s' WHERE (message='$message' AND subject='$subject' AND message_to='$usr')";
57 &main::daemon_log("$session_id DEBUG: $sql", 7);
58 my $res = $main::messaging_db->exec_statement($sql);
61 return;
62 }
65 ## @method save_fai_log()
66 # @details Creates under /var/log/fai/ the directory '$macaddress' and stores within all FAI log files from client.
67 # @param msg - STRING - xml message with tags 'macaddress' and 'save_fai_log'
68 # @param msg_hash - HASHREF - message information parsed into a hash
69 # @param session_id - INTEGER - POE session id of the processing of this message
70 sub save_fai_log {
71 my ($msg, $msg_hash, $session_id) = @_;
72 my $header = @{$msg_hash->{'header'}}[0];
73 my $source = @{$msg_hash->{'source'}}[0];
74 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
75 my $all_logs = @{$msg_hash->{$header}}[0];
77 # if there is nothing to log
78 if( ref($all_logs) eq "HASH" ) {
79 &main::daemon_log("$session_id INFO: There is nothing to log!", 5);
80 return;
81 }
83 my $client_fai_log_dir = $main::client_fai_log_dir;
84 if (not -d $client_fai_log_dir) {
85 mkdir($client_fai_log_dir, 0755)
86 }
88 $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, $macaddress );
89 if (not -d $client_fai_log_dir) {
90 mkdir($client_fai_log_dir, 0755)
91 }
93 my $time = &get_time;
94 $time = substr($time, 0, 8)."_".substr($time, 8, 6);
95 $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, "install_$time" );
96 mkdir($client_fai_log_dir, 0755);
98 my @all_logs = split(/log_file:/, $all_logs);
99 foreach my $log (@all_logs) {
100 if (length $log == 0) { next; };
101 my ($log_file, $log_string) = split(":", $log);
102 my $client_fai_log_file = File::Spec->catfile( $client_fai_log_dir, $log_file);
104 open(my $LOG_FILE, ">$client_fai_log_file");
105 print $LOG_FILE &decode_base64($log_string);
106 close($LOG_FILE);
108 }
109 return;
110 }
112 ## @method LOGIN()
113 # @details Reported user from client is added to login_users_db.
114 # @param msg - STRING - xml message with tag 'LOGIN'
115 # @param msg_hash - HASHREF - message information parsed into a hash
116 # @param session_id - INTEGER - POE session id of the processing of this message
117 sub LOGIN {
118 my ($msg, $msg_hash, $session_id) = @_;
119 my $header = @{$msg_hash->{'header'}}[0];
120 my $source = @{$msg_hash->{'source'}}[0];
121 my $login = @{$msg_hash->{$header}}[0];
122 my $res;
123 my $error_str;
125 # Invoke set_last_system; message sets ldap attributes 'gotoLastSystemLogin' and 'gotoLastSystem'
126 $res = &set_last_system($msg, $msg_hash, $session_id);
128 # Add user to login_users_db
129 my %add_hash = ( table=>$main::login_users_tn,
130 primkey=> ['client', 'user'],
131 client=>$source,
132 user=>$login,
133 timestamp=>&get_time,
134 regserver=>'localhost',
135 );
136 ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
137 if ($res != 0) {
138 &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
139 return;
140 }
142 # Share login information with all other si-server
143 my %data = ( 'new_user' => "$source;$login" );
144 my $info_msg = &build_msg("information_sharing", $main::server_address, "KNOWN_SERVER", \%data);
146 return ($info_msg);
147 }
150 ## @method LOGOUT()
151 # @details Reported user from client is deleted from login_users_db.
152 # @param msg - STRING - xml message with tag 'LOGOUT'
153 # @param msg_hash - HASHREF - message information parsed into a hash
154 # @param session_id - INTEGER - POE session id of the processing of this message
155 sub LOGOUT {
156 my ($msg, $msg_hash, $session_id) = @_;
157 my $header = @{$msg_hash->{'header'}}[0];
158 my $source = @{$msg_hash->{'source'}}[0];
159 my $login = @{$msg_hash->{$header}}[0];
161 my $sql_statement = "DELETE FROM $main::login_users_tn WHERE (client='$source' AND user='$login')";
162 my $res = $main::login_users_db->del_dbentry($sql_statement);
163 &main::daemon_log("$session_id INFO: delete user '$login' at client '$source' from login_user_db", 5);
165 return;
166 }
169 ## @method CURRENTLY_LOGGED_IN()
170 # @details Reported users from client are updated in login_users_db. Users which are no longer logged in are deleted from DB.
171 # @param msg - STRING - xml message
172 # @param msg_hash - HASHREF - message information parsed into a hash
173 # @param session_id - INTEGER - POE session id of the processing of this message
174 sub CURRENTLY_LOGGED_IN {
175 my ($msg, $msg_hash, $session_id) = @_;
176 my ($sql_statement, $db_res);
177 my $header = @{$msg_hash->{'header'}}[0];
178 my $source = @{$msg_hash->{'source'}}[0];
179 my $login = @{$msg_hash->{$header}}[0];
181 if(ref $login eq "HASH") {
182 &main::daemon_log("$session_id INFO: no logged in users reported from host '$source'", 5);
183 return;
184 }
186 # Invoke set_last_system; message sets ldap attributes 'gotoLastSystemLogin' and 'gotoLastSystem'
187 my $res = &set_last_system($msg, $msg_hash, $session_id);
189 # fetch all user currently assigned to the client at login_users_db
190 my %currently_logged_in_user = ();
191 $sql_statement = "SELECT * FROM $main::login_users_tn WHERE client='$source'";
192 $db_res = $main::login_users_db->select_dbentry($sql_statement);
193 while( my($hit_id, $hit) = each(%{$db_res}) ) {
194 $currently_logged_in_user{$hit->{'user'}} = 1;
195 }
196 &main::daemon_log("$session_id DEBUG: logged in users from login_user_db: ".join(", ", keys(%currently_logged_in_user)), 7);
198 # update all reported users in login_user_db
199 my @logged_in_user = split(/\s+/, $login);
200 &main::daemon_log("$session_id DEBUG: logged in users reported from client: ".join(", ", @logged_in_user), 7);
201 foreach my $user (@logged_in_user) {
202 my %add_hash = ( table=>$main::login_users_tn,
203 primkey=> ['client', 'user'],
204 client=>$source,
205 user=>$user,
206 timestamp=>&get_time,
207 regserver=>'localhost',
208 );
209 my ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
210 if ($res != 0) {
211 &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
212 return;
213 }
215 delete $currently_logged_in_user{$user};
216 }
218 # if there is still a user in %currently_logged_in_user
219 # although he is not reported by client
220 # then delete it from $login_user_db
221 foreach my $obsolete_user (keys(%currently_logged_in_user)) {
222 &main::daemon_log("$session_id WARNING: user '$obsolete_user' is currently not logged ".
223 "in at client '$source' but still found at login_user_db", 3);
224 my $sql_statement = "DELETE FROM $main::login_users_tn WHERE client='$source' AND user='$obsolete_user'";
225 my $res = $main::login_users_db->del_dbentry($sql_statement);
226 &main::daemon_log("$session_id WARNING: delete user '$obsolete_user' at client '$source' from login_user_db", 3);
227 }
229 # Delete all users which logged in information is older than their logged_in_user_date_of_expiry
230 my $act_time = &get_time();
231 my $expiry_date = &calc_timestamp($act_time, "minus", $main::logged_in_user_date_of_expiry);
233 $sql_statement = "SELECT * FROM $main::login_users_tn WHERE CAST(timestamp as UNSIGNED)<$expiry_date";
234 $db_res = $main::login_users_db->select_dbentry($sql_statement);
236 while( my($hit_id, $hit) = each(%{$db_res}) ) {
237 &main::daemon_log("$session_id INFO: user '".$hit->{'user'}."' is no longer reported to be logged in at host '".$hit->{'client'}."'", 5);
238 my $sql = "DELETE FROM $main::login_users_tn WHERE (client='".$hit->{'client'}."' AND user='".$hit->{'user'}."')";
239 my $res = $main::login_users_db->del_dbentry($sql);
240 &main::daemon_log("$session_id INFO: delete user '".$hit->{'user'}."' at client '".$hit->{'client'}."' from login_user_db", 5);
241 }
243 # Inform all other server which users are logged in at clients registered at local server
244 my $info_sql = "SELECT * FROM $main::login_users_tn WHERE regserver='localhost'";
245 my $info_res = $main::login_users_db->select_dbentry($info_sql);
246 my $info_msg_hash = &create_xml_hash("information_sharing", $main::server_address, "KNOWN_SERVER");
247 while (my ($hit_id, $hit) = each(%$info_res)) {
248 &add_content2xml_hash($info_msg_hash, 'user_db', $hit->{'client'}.";".$hit->{'user'});
249 }
250 my $info_msg = &create_xml_string($info_msg_hash);
252 return ($info_msg);
253 }
256 ## @method set_last_system()
257 # @details Message sets ldap attributes 'gotoLastSystemLogin' and 'gotoLastSystem'
258 # @param msg - STRING - xml message with tag 'last_system_login' and 'last_system'
259 # @param msg_hash - HASHREF - message information parsed into a hash
260 # @param session_id - INTEGER - POE session id of the processing of this message
261 sub set_last_system {
262 my ($msg, $msg_hash, $session_id) = @_;
263 my $header = @{$msg_hash->{'header'}}[0];
264 my $source = @{$msg_hash->{'source'}}[0];
265 my $login = @{$msg_hash->{$header}}[0];
267 # Sanity check of needed parameter
268 if (not exists $msg_hash->{'timestamp'}){
269 &main::daemon_log("$session_id ERROR: message does not contain needed xml tag 'timestamp', ".
270 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
271 &main::daemon_log($msg, 1);
272 return;
273 }
274 if (@{$msg_hash->{'timestamp'}} != 1) {
275 &main::daemon_log("$session_id ERROR: xml tag 'timestamp' has no content or exists more than one time, ".
276 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
277 &ymain::daemon_log($msg, 1);
278 return;
279 }
280 if (not exists $msg_hash->{'macaddress'}){
281 &main::daemon_log("$session_id ERROR: message does not contain needed xml tag 'mac_address', ".
282 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
283 &main::daemon_log($msg, 1);
284 return;
285 }
286 if (@{$msg_hash->{'macaddress'}} != 1) {
287 &main::daemon_log("$session_id ERROR: xml tag 'macaddress' has no content or exists more than one time, ".
288 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
289 &ymain::daemon_log($msg, 1);
290 return;
291 }
293 # Fetch needed parameter
294 my $mac = @{$msg_hash->{'macaddress'}}[0];
295 my $timestamp = @{$msg_hash->{'timestamp'}}[0];
297 # Prepare login list
298 my @login_list = split(' ', @{$msg_hash->{$header}}[0] );
299 @login_list = &main::del_doubles(@login_list);
301 # Sanity check of login list
302 if (@login_list == 0) {
303 # TODO
304 return;
305 }
307 # Fetch ldap handle
308 my $ldap_handle = &main::get_ldap_handle();
310 # Get system info
311 my $ldap_mesg= $ldap_handle->search(
312 base => $main::ldap_base,
313 scope => 'sub',
314 filter => "macAddress=$mac",
315 );
316 if ($ldap_mesg->count == 0) {
317 &main::daemon_log("$session_id ERROR: no system with mac address='$mac' was found in base '".
318 $main::ldap_base."', setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
319 return;
320 }
322 my $ldap_entry = $ldap_mesg->pop_entry();
323 my $system_dn = $ldap_entry->dn();
325 # For each logged in user set gotoLastSystem and gotoLastSystemLogin
326 foreach my $user (@login_list) {
327 # Search user
328 my $ldap_mesg= $ldap_handle->search(
329 base => $main::ldap_base,
330 scope => 'sub',
331 filter => "uid=$user",
332 );
333 # Sanity check of user search
334 if ($ldap_mesg->count == 0) {
335 &main::daemon_log("$session_id ERROR: no user with uid='$user' was found in base '".
336 $main::ldap_base."', setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
338 # Set gotoLastSystem and gotoLastSystemLogin
339 } else {
340 my $ldap_entry= $ldap_mesg->pop_entry();
341 my $do_update = 0;
343 # Set gotoLastSystem information
344 my $last_system_dn = $ldap_entry->get_value('gotoLastSystem');
345 if ((defined $last_system_dn) && ($last_system_dn eq $system_dn)) {
346 &main::daemon_log("$session_id INFO: no new 'gotoLastSystem' inforamtion for ladp entry 'uid=$user', do nothing!", 5);
347 } elsif ((defined $last_system_dn) && ($last_system_dn ne $system_dn)) {
348 $ldap_entry->replace ( 'gotoLastSystem' => $system_dn );
349 &main::daemon_log("$session_id INFO: update attribute 'gotoLastSystem'='$system_dn' at ldap entry 'uid=$user'!",5);
350 $do_update++;
351 } else {
352 $ldap_entry->add( 'gotoLastSystem' => $system_dn );
353 &main::daemon_log("$session_id INFO: add attribute 'gotoLastSystem'='$system_dn' at ldap entry 'uid=$user'!", 5);
354 $do_update++;
355 }
357 # Set gotoLastSystemLogin information
358 # Attention: only write information if last_system_dn and system_dn differs
359 my $last_system_login = $ldap_entry->get_value('gotoLastSystemLogin');
360 if ((defined $last_system_login) && ($last_system_dn eq $system_dn)) {
361 &main::daemon_log("$session_id INFO: no new 'gotoLastSystemLogin' inforamtion for ladp entry 'uid=$user', do nothing!", 5);
362 } elsif ((defined $last_system_login) && ($last_system_dn ne $system_dn)) {
363 $ldap_entry->replace ( 'gotoLastSystemLogin' => $timestamp );
364 &main::daemon_log("$session_id INFO: update attribute 'gotoLastSystemLogin'='$timestamp' at ldap entry 'uid=$user'!", 5);
365 $do_update++;
366 } else {
367 $ldap_entry->add( 'gotoLastSystemLogin' => $timestamp );
368 &main::daemon_log("$session_id INFO: add attribute 'gotoLastSystemLogin'='$timestamp' at ldap entry 'uid=$user'!",5);
369 $do_update++;
370 }
372 if ($do_update) {
373 my $result = $ldap_entry->update($ldap_handle);
374 if ($result->code() != 0) {
375 &main::daemon_log("$session_id ERROR: setting 'gotoLastSystem' and 'gotoLastSystemLogin' at user '$user' failed: ".
376 $result->{'errorMessage'}."\n".
377 "\tbase: $main::ldap_base\n".
378 "\tscope: 'sub'\n".
379 "\tfilter: 'uid=$user'\n".
380 "\tmessage: $msg", 1);
381 }
382 }
383 }
384 }
386 return;
387 }
390 ## @method GOTOACTIVATION()
391 # @details Client is set at job_queue_db to status 'processing' and 'modified'.
392 # @param msg - STRING - xml message with tag 'macaddress'
393 # @param msg_hash - HASHREF - message information parsed into a hash
394 # @param session_id - INTEGER - POE session id of the processing of this message
395 sub GOTOACTIVATION {
396 my ($msg, $msg_hash, $session_id) = @_;
397 my $header = @{$msg_hash->{'header'}}[0];
398 my $source = @{$msg_hash->{'source'}}[0];
399 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
401 # test whether content is an empty hash or a string which is required
402 my $content = @{$msg_hash->{$header}}[0];
403 if(ref($content) eq "HASH") { $content = ""; }
405 # clean up header
406 $header =~ s/CLMSG_//g;
408 my $sql_statement = "UPDATE $main::job_queue_tn ".
409 "SET progress='goto-activation', modified='1' ".
410 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
411 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
412 my $res = $main::job_db->update_dbentry($sql_statement);
413 &main::daemon_log("$session_id INFO: $header at '$macaddress'", 5);
414 return;
415 }
418 ## @method PROGRESS()
419 # @details Message reports installation progress of the client. Installation job at job_queue_db is going to be updated.
420 # @param msg - STRING - xml message with tags 'macaddress' and 'PROGRESS'
421 # @param msg_hash - HASHREF - message information parsed into a hash
422 # @param session_id - INTEGER - POE session id of the processing of this message
423 sub PROGRESS {
424 my ($msg, $msg_hash, $session_id) = @_;
425 my $header = @{$msg_hash->{'header'}}[0];
426 my $source = @{$msg_hash->{'source'}}[0];
427 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
429 # test whether content is an empty hash or a string which is required
430 my $content = @{$msg_hash->{$header}}[0];
431 if(ref($content) eq "HASH") { $content = ""; }
433 # clean up header
434 $header =~ s/CLMSG_//g;
436 my $sql_statement = "UPDATE $main::job_queue_tn ".
437 "SET progress='$content', modified='1' ".
438 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
439 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
440 my $res = $main::job_db->update_dbentry($sql_statement);
441 &main::daemon_log("$session_id INFO: $header at '$macaddress' - $content%", 5);
443 return;
444 }
447 ## @method FAIREBOOT()
448 # @details Message reports a FAI reboot. Job at job_queue_db is going to be updated.
449 # @param msg - STRING - xml message with tag 'macaddress' and 'FAIREBOOT'
450 # @param msg_hash - HASHREF - message information parsed into a hash
451 # @param session_id - INTEGER - POE session id of the processing of this message
452 sub FAIREBOOT {
453 my ($msg, $msg_hash, $session_id) = @_;
454 my $header = @{$msg_hash->{'header'}}[0];
455 my $source = @{$msg_hash->{'source'}}[0];
456 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
458 # test whether content is an empty hash or a string which is required
459 my $content = @{$msg_hash->{$header}}[0];
460 if(ref($content) eq "HASH") { $content = ""; }
462 # clean up header
463 $header =~ s/CLMSG_//g;
465 my $sql_statement = "UPDATE $main::job_queue_tn ".
466 "SET result='$header "."$content', modified='1' ".
467 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
468 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
469 my $res = $main::job_db->update_dbentry($sql_statement);
470 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
472 return;
473 }
476 ## @method TASKSKIP()
477 # @details Message reports a skipped FAI task. Job at job_queue_db is going to be updated.
478 # @param msg - STRING - xml message with tag 'macaddress'.
479 # @param msg_hash - HASHREF - message information parsed into a hash
480 # @param session_id - INTEGER - POE session id of the processing of this message
481 sub TASKSKIP {
482 my ($msg, $msg_hash, $session_id) = @_;
483 my $header = @{$msg_hash->{'header'}}[0];
484 my $source = @{$msg_hash->{'source'}}[0];
485 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
487 # test whether content is an empty hash or a string which is required
488 my $content = @{$msg_hash->{$header}}[0];
489 if(ref($content) eq "HASH") { $content = ""; }
491 # clean up header
492 $header =~ s/CLMSG_//g;
494 my $sql_statement = "UPDATE $main::job_queue_tn ".
495 "SET result='$header "."$content', modified='1' ".
496 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
497 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
498 my $res = $main::job_db->update_dbentry($sql_statement);
499 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
501 return;
502 }
505 ## @method TASKBEGIN()
506 # @details Message reports a starting FAI task. If the task is equal to 'finish', 'faiend' or 'savelog', job at job_queue_db is being set to status 'done' and FAI state is being set to 'localboot'. If task is equal to 'chboot', 'test' or 'confdir', just do nothing. In all other cases, job at job_queue_db is going to be updated or created if not exists.
507 # @param msg - STRING - xml message with tag 'macaddress'.
508 # @param msg_hash - HASHREF - message information parsed into a hash
509 # @param session_id - INTEGER - POE session id of the processing of this message
510 sub TASKBEGIN {
511 my ($msg, $msg_hash, $session_id) = @_;
512 my $header = @{$msg_hash->{'header'}}[0];
513 my $source = @{$msg_hash->{'source'}}[0];
514 my $target = @{$msg_hash->{'target'}}[0];
515 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
517 # test whether content is an empty hash or a string which is required
518 my $content = @{$msg_hash->{$header}}[0];
519 if(ref($content) eq "HASH") { $content = ""; }
521 # clean up header
522 $header =~ s/CLMSG_//g;
524 # TASKBEGIN eq finish or faiend
525 if (($content eq 'finish')
526 || ($content eq 'faiend')
527 || ($content eq 'savelog')
528 ) {
529 my $sql_statement = "UPDATE $main::job_queue_tn ".
530 "SET status='done', result='$header "."$content', modified='1' ".
531 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
532 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
533 my $res = $main::job_db->update_dbentry($sql_statement);
534 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
536 # set fai_state to localboot
537 &main::change_fai_state('localboot', \@{$msg_hash->{'macaddress'}}, $session_id);
539 # TASKBEGIN eq chboot
540 } elsif (($content eq 'chboot')
541 || ($content eq 'test')
542 || ($content eq 'confdir')
543 ) {
544 # just ignor this client message
545 # do nothing
547 # other TASKBEGIN msgs
548 } else {
549 # select processing jobs for host
550 my $sql_statement = "SELECT * FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'";
551 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
552 my $res = $main::job_db->select_dbentry($sql_statement);
554 # there is exactly one job entry in queue for this host
555 if (keys(%$res) == 1) {
556 &main::daemon_log("$session_id DEBUG: there is already one processing job in queue for host '$macaddress', run an update for this entry", 7);
557 my $sql_statement = "UPDATE $main::job_queue_tn ".
558 "SET result='$header $content', modified='1', siserver='localhost' ".
559 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
560 my $err = $main::job_db->update_dbentry($sql_statement);
561 if (not defined $err) {
562 &main::daemon_log("$session_id ERROR: cannot update job_db entry: ".Dumper($err), 1);
563 }
565 # there is no entry or more than one enties
566 } else {
567 # in case of more than one running jobs in queue, delete all jobs
568 if (keys(%$res) > 1) {
569 &main::daemon_log("$session_id DEBUG: there are more than one processing job in queue for host '$macaddress', ".
570 "delete entries", 7);
572 # set job to status 'done', job will be deleted automatically
573 my $sql_statement = "UPDATE $main::job_queue_tn ".
574 "SET status='done', modified='1'".
575 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
576 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
577 my $res = $main::job_db->update_dbentry( $sql_statement );
579 }
581 # in case of no and more than one running jobs in queue, add one single job
582 # resolve plain name for host $macaddress
583 my $plain_name;
584 my $ldap_handle = &main::get_ldap_handle($session_id);
585 if( not defined $ldap_handle ) {
586 &main::daemon_log("$session_id ERROR: cannot connect to ldap", 1);
587 $plain_name = "none";
589 # try to fetch a 'real name'
590 } else {
591 my $mesg = $ldap_handle->search(
592 base => $main::ldap_base,
593 scope => 'sub',
594 attrs => ['cn'],
595 filter => "(macAddress=$macaddress)");
596 if($mesg->code) {
597 &main::daemon_log($mesg->error, 1);
598 $plain_name = "none";
599 } else {
600 my $entry= $mesg->entry(0);
601 $plain_name = $entry->get_value("cn");
602 }
603 }
605 # In any case add a new job to job queue
606 &main::daemon_log("$session_id DEBUG: add job to queue for host '$macaddress'", 7);
607 my $func_dic = {table=>$main::job_queue_tn,
608 primkey=>['macaddress', 'headertag'],
609 timestamp=>&get_time,
610 status=>'processing',
611 result=>"$header $content",
612 progress=>'none',
613 headertag=>'trigger_action_reinstall',
614 targettag=>$target,
615 xmlmessage=>'none',
616 macaddress=>$macaddress,
617 plainname=>$plain_name,
618 modified=>'1',
619 siserver=>'localhost',
620 };
621 my ($err, $error_str) = $main::job_db->add_dbentry($func_dic);
622 if ($err != 0) {
623 &main::daemon_log("$session_id ERROR: cannot add entry to job_db: $error_str", 1);
624 }
625 }
626 }
628 return;
629 }
632 ## @method TASKEND()
633 # @details Message reports a finished FAI task. If task is equal to 'savelog', job at job_queue_db is going to be set to status 'done'. Otherwise, job is going to be updated.
634 # @param msg - STRING - xml message with tag 'macaddress'.
635 # @param msg_hash - HASHREF - message information parsed into a hash
636 # @param session_id - INTEGER - POE session id of the processing of this message
637 sub TASKEND {
638 my ($msg, $msg_hash, $session_id) = @_;
639 my $header = @{$msg_hash->{'header'}}[0];
640 my $target = @{$msg_hash->{'target'}}[0];
641 my $source = @{$msg_hash->{'source'}}[0];
642 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
644 # test whether content is an empty hash or a string which is required
645 my $content = @{$msg_hash->{$header}}[0];
646 if(ref($content) eq "HASH") { $content = ""; }
648 # clean up header
649 $header =~ s/CLMSG_//g;
651 if ($content eq "savelog 0") {
652 &main::daemon_log("$session_id DEBUG: got savelog from host '$target' - job done", 7);
654 # set job to status 'done', job will be deleted automatically
655 my $sql_statement = "UPDATE $main::job_queue_tn ".
656 "SET status='done', modified='1'".
657 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
658 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
659 my $res = $main::job_db->update_dbentry( $sql_statement );
661 } else {
662 my $sql_statement = "UPDATE $main::job_queue_tn ".
663 "SET result='$header "."$content', modified='1' ".
664 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
665 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
666 my $res = $main::job_db->update_dbentry($sql_statement);
667 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
668 }
670 return;
671 }
674 ## @method TASKERROR()
675 # @details Message reports a FAI error. Job at job_queue_db is going to be updated.
676 # @param msg - STRING - xml message with tag 'macaddress' and 'TASKERROR'
677 # @param msg_hash - HASHREF - message information parsed into a hash
678 # @param session_id - INTEGER - POE session id of the processing of this message
679 sub TASKERROR {
680 my ($msg, $msg_hash, $session_id) = @_;
681 my $header = @{$msg_hash->{'header'}}[0];
682 my $source = @{$msg_hash->{'source'}}[0];
683 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
685 # clean up header
686 $header =~ s/CLMSG_//g;
688 # test whether content is an empty hash or a string which is required
689 my $content = @{$msg_hash->{$header}}[0];
690 if(ref($content) eq "HASH") { $content = ""; }
692 # set fai_state to localboot
693 &main::change_fai_state('error', \@{$msg_hash->{'macaddress'}}, $session_id);
695 my $sql_statement = "UPDATE $main::job_queue_tn ".
696 "SET result='$header "."$content', modified='1' ".
697 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
698 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
699 my $res = $main::job_db->update_dbentry($sql_statement);
700 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
702 return;
703 }
706 ## @method HOOK()
707 # @details Message reports a FAI hook. Job at job_queue_db is going to be updated.
708 # @param msg - STRING - xml message with tag 'macaddress' and 'HOOK'
709 # @param msg_hash - HASHREF - message information parsed into a hash
710 # @param session_id - INTEGER - POE session id of the processing of this message
711 sub HOOK {
712 my ($msg, $msg_hash, $session_id) = @_;
713 my $header = @{$msg_hash->{'header'}}[0];
714 my $source = @{$msg_hash->{'source'}}[0];
715 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
717 # clean up header
718 $header =~ s/CLMSG_//g;
720 # test whether content is an empty hash or a string which is required
721 my $content = @{$msg_hash->{$header}}[0];
722 if(not ref($content) eq "STRING") { $content = ""; }
724 my $sql_statement = "UPDATE $main::job_queue_tn ".
725 "SET result='$header "."$content', modified='1' ".
726 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
727 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
728 my $res = $main::job_db->update_dbentry($sql_statement);
729 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
731 return;
732 }
735 =pod
737 =head1 NAME
739 clMessages - Implementation of a GOsa-SI event module for GOsa-SI-server.
741 =head1 SYNOPSIS
743 use GOSA::GosaSupportDaemon;
744 use MIME::Base64;
746 =head1 DESCRIPTION
748 This GOsa-SI event module containing all functions to handle messages coming from GOsa-SI-clients.
750 This module will be automatically imported by GOsa-SI if it is under F</usr/lib/gosa-si/server/E<lt>PACKAGEMODULEE<gt>/> .
752 =head1 METHODS
754 =over 4
756 =item get_events ( )
758 =item confirm_usr_msg ( )
760 =item PROGRESS ( )
762 =item FAIREBOOT ( )
764 =item TASKSKIP ( )
766 =item TASKBEGIN ( )
768 =item TASKEND ( )
770 =item TASKERROR ( )
772 =item HOOK ( )
774 =item GOTOACTIVATION ( )
776 =item LOGIN ( )
778 =item LOGOUT ( )
780 =item CURRENTLY_LOGGED_IN ( )
782 =item save_fai_log ( )
784 =back
786 =head1 BUGS
788 Please report any bugs, or post any suggestions, to the GOsa mailing list E<lt>gosa-devel@oss.gonicus.deE<gt> or to L<https://oss.gonicus.de/labs/gosa>
790 =head1 COPYRIGHT
792 This code is part of GOsa (L<http://www.gosa-project.org>)
794 Copyright (C) 2003-2008 GONICUS GmbH
796 This program is distributed in the hope that it will be useful,
797 but WITHOUT ANY WARRANTY; without even the implied warranty of
798 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
799 GNU General Public License for more details.
801 =cut
804 1;