Code

Don't remove FAI-State when reboot, rescan or wakeup is requested. Set FAI-State...
[gosa.git] / trunk / gosa-si / gosa-si-server
index a2a49db1e6e4ded0161e8c8f9f0ea4a60ac3c7ac..ae3a97e0d9dce646df43c933f3f114e7270f6db1 100755 (executable)
@@ -79,11 +79,10 @@ my ($xml);
 my $sources_list;
 my $max_clients;
 my %repo_files=();
-my $repo_path;
 my %repo_dirs=();
 
 # Variables declared in config file are always set to 'our'
-our (%cfg_defaults, $log_file, $pid_file, 
+our (%cfg_defaults, $log_file, $pid_file, $repo_basepath,
     $server_ip, $server_port, $ClientPackages_key, $dns_lookup,
     $arp_activ, $gosa_unit_tag,
     $GosaPackages_key, $gosa_timeout,
@@ -91,7 +90,7 @@ our (%cfg_defaults, $log_file, $pid_file,
     $wake_on_lan_passwd, $job_synchronization, $modified_jobs_loop_delay,
     $arp_enabled, $arp_interface,
     $opsi_enabled, $opsi_server, $opsi_admin, $opsi_password,
-               $new_systems_ou,
+    $new_systems_ou, $logged_in_users_delay,
 );
 
 # additional variable which should be globaly accessable
@@ -228,8 +227,9 @@ our $logged_in_user_date_of_expiry = 600;
 
 %cfg_defaults = (
 "general" => {
-    "log-file" => [\$log_file, "/var/run/".$prg.".log"],
-    "pid-file" => [\$pid_file, "/var/run/".$prg.".pid"],
+    "log-file"      => [\$log_file, "/var/run/".$prg.".log"],
+    "pid-file"      => [\$pid_file, "/var/run/".$prg.".pid"],
+    "repo-basepath" => [\$repo_basepath, "/srv/www"],
     },
 "server" => {
     "ip"                    => [\$server_ip, "0.0.0.0"],
@@ -244,7 +244,6 @@ our $logged_in_user_date_of_expiry = 600;
     "messaging"             => [\$messaging_file_name, '/var/lib/gosa-si/messaging.db'],
     "foreign-clients"       => [\$foreign_clients_file_name, '/var/lib/gosa-si/foreign_clients.db'],
     "source-list"           => [\$sources_list, '/etc/apt/sources.list'],
-    "repo-path"             => [\$repo_path, '/srv/www/repository'],
     "ldap-uri"              => [\$ldap_uri, ""],
     "ldap-base"             => [\$ldap_base, ""],
     "ldap-admin-dn"         => [\$ldap_admin_dn, ""],
@@ -276,6 +275,7 @@ our $logged_in_user_date_of_expiry = 600;
     "key-lifetime" => [\$foreign_servers_register_delay, 120],
     "job-synchronization-enabled" => [\$job_synchronization, "true"],
     "synchronization-loop" => [\$modified_jobs_loop_delay, 5],
+    "report-logged-in-users" => [\$logged_in_users_delay, 600],
     },
 "ArpHandler" => {
     "enabled"   => [\$arp_enabled, "true"],
@@ -510,27 +510,33 @@ sub password_check {
 
 }
 
+sub clean_shutdown
+{
+    unlink($pid_file) if (-w $pid_file);
+    unlink($packages_list_under_construction) if (-w $packages_list_under_construction);
+}
 
-#===  FUNCTION  ================================================================
-#         NAME:  sig_int_handler
-#   PARAMETERS:  signal - string - signal arose from system
-#      RETURNS:  nothing
-#  DESCRIPTION:  handels tasks to be done befor signal becomes active
-#===============================================================================
-sub sig_int_handler {
+sub sig_int_or_term_handler
+{
     my ($signal) = @_;
+    daemon_log("Got SIG${signal} - shutting down gosa-si-server", 1);
+    clean_shutdown();
+    POE::Kernel->signal('gosa-si_server_session', 'KILL');
+    POE::Kernel->signal('TCP_SERVER', 'KILL');
+    return 1;
+}
 
-#      if (defined($ldap_handle)) {
-#              $ldap_handle->disconnect;
-#      }
-    # TODO alle verbliebenden ldap verbindungen aus allen heaps beenden
-    
-
-    daemon_log("shutting down gosa-si-server", 1);
-    system("kill `ps -C gosa-si-server -o pid=`");
+sub sig_warn_handler
+{
+    my @loc = caller(0);
+    daemon_log( "SIGWARN line " . $loc[2] . ": " . $_[0], 1 );
+    return 1;
 }
-$SIG{INT} = \&sig_int_handler;
 
+$SIG{'INT'} = \&sig_int_or_term_handler;
+$SIG{'TERM'} = \&sig_int_or_term_handler;
+$SIG{'__WARN__'} = \&sig_warn_handler;
+$SIG{'USR1'} = 'IGNORE';
 
 sub check_key_and_xml_validity {
     my ($crypted_msg, $module_key, $session_id) = @_;
@@ -1056,14 +1062,6 @@ sub reactivate_job_with_delay {
 }
 
 
-sub sig_handler {
-       my ($kernel, $signal) = @_[KERNEL, ARG0] ;
-       daemon_log("0 INFO got signal '$signal'", 1); 
-       $kernel->sig_handled();
-       return;
-}
-
-
 sub msg_to_decrypt {
        my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];
        my $session_id = $session->ID;
@@ -1564,12 +1562,12 @@ sub process_task {
 
 sub session_start {
     my ($kernel) = $_[KERNEL];
+    $kernel->alias_set('gosa-si_server_session');
     $global_kernel = $kernel;
     $kernel->yield('register_at_foreign_servers');
        $kernel->yield('create_fai_server_db', $fai_server_tn );
        $kernel->yield('create_fai_release_db', $fai_release_tn );
     $kernel->yield('watch_for_next_tasks');
-       $kernel->sig(USR1 => "sig_handler");
        $kernel->sig(USR2 => "recreate_packages_db");
        $kernel->delay_set('watch_for_new_jobs', $job_queue_loop_delay);
        $kernel->delay_set('watch_for_done_jobs', $job_queue_loop_delay); 
@@ -1578,14 +1576,20 @@ sub session_start {
     $kernel->delay_set('watch_for_delivery_messages', $messaging_db_loop_delay);
        $kernel->delay_set('watch_for_done_messages', $messaging_db_loop_delay);
     $kernel->delay_set('watch_for_old_known_clients', $job_queue_loop_delay);
+    $kernel->delay_set('watch_for_logged_in_users', $logged_in_users_delay);
 
     # Start opsi check
     if ($opsi_enabled eq "true") {
         $kernel->delay_set('watch_for_opsi_jobs', $job_queue_opsi_delay); 
     }
-
 }
 
+sub session_stop {
+    my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];
+    $kernel->alias_remove($heap->{alias});
+    $kernel->alarm_remove_all();
+    $kernel->post($heap->{child_session}, '_stop');
+}
 
 sub watch_for_done_jobs {
        #CHECK: $heap for what?
@@ -1942,7 +1946,8 @@ sub watch_for_delivery_messages {
     my ($kernel, $heap) = @_[KERNEL, HEAP];
 
     # select outgoing messages
-    my $sql_statement = "SELECT * FROM $messaging_tn WHERE ( flag='p' AND direction='out' )";
+    my $timestamp= &get_time();
+    my $sql_statement = "SELECT * FROM $messaging_tn WHERE ( flag='p' AND direction='out' AND delivery_time<$timestamp)";
     #&daemon_log("0 DEBUG: $sql", 7);
     my $res = $messaging_db->exec_statement( $sql_statement );
     
@@ -2128,6 +2133,31 @@ sub watch_for_next_tasks {
     $kernel->delay_set('watch_for_next_tasks', 1); 
 }
 
+sub watch_for_logged_in_users {
+    my ($kernel,$heap) = @_[KERNEL, HEAP];
+
+    # Get list of currently logged in users
+    my $sql = "SELECT * FROM $login_users_tn WHERE regserver='localhost'";
+    my $res = $main::login_users_db->select_dbentry($sql);
+    my $msg_hash = &create_xml_hash("information_sharing", $server_address, "KNOWN_SERVER");
+    while (my ($hit_id, $hit) = each(%$res)) {
+        &add_content2xml_hash($msg_hash, 'user_db', $hit->{'client'}.";".$hit->{'user'});
+    }
+    my $msg = &create_xml_string($msg_hash);
+
+    # Inform all other server which users are logged in at clients registered at local server
+    my $sql_statement= "SELECT * FROM $known_server_tn";
+    my $query_res = $known_server_db->select_dbentry( $sql_statement );
+    while( my ($hit_num, $hit) = each %{ $query_res } ) {
+        my $host_name = $hit->{hostname};
+        my $host_key = $hit->{hostkey};
+        $msg =~ s/<target>\S+<\/target>/<target>$host_name<\/target>/g;
+       # TODO: get session_id
+        my $error = &send_msg_to_target($msg, $host_name, $host_key, "information_sharing", 0);
+    }
+
+    $kernel->delay_set('watch_for_logged_in_users', $logged_in_users_delay); 
+}
 
 sub get_ldap_handle {
        my ($session_id) = @_;
@@ -2174,12 +2204,12 @@ sub change_fai_state {
     $session_id = 0 if not defined $session_id;
     # Set FAI state to localboot
     my %mapActions= (
-        reboot    => '',
+        reboot    => 'localboot',
         update    => 'softupdate',
         localboot => 'localboot',
         reinstall => 'install',
-        rescan    => '',
-        wake      => '',
+        rescan    => 'localboot',
+        wake      => 'localboot',
         memcheck  => 'memcheck',
         sysinfo   => 'sysinfo',
         install   => 'install',
@@ -2773,7 +2803,10 @@ sub run_create_packages_list_db {
 
 sub create_packages_list_db {
        my ($ldap_handle, $sources_file, $session_id) = @_;
-       
+
+       # Cleanup repo basepath
+       $repo_basepath = File::Spec->canonpath($repo_basepath);
+
        # it should not be possible to trigger a recreation of packages_list_db
        # while packages_list_db is under construction, so set flag packages_list_under_construction
        # which is tested befor recreation can be started
@@ -2993,7 +3026,10 @@ sub parse_package_info {
     my ($baseurl, $dist, $section, $session_id)= @_;
     my ($package);
     if (not defined $session_id) { $session_id = 0; }
-    my ($path) = ($baseurl =~ m%://[^/]*(.*)$%);
+    my ($path) = ($baseurl =~ m%://[^/]*/(.*)$%);
+
+    my $repo_path = File::Spec->join($repo_basepath, $path);
+
     $repo_dirs{ "${repo_path}/pool" } = 1;
 
     foreach $package ("Packages.gz"){
@@ -3087,6 +3123,8 @@ sub parse_package {
         # Trigger for filename
         if ($line =~ /^Filename:\s/){
             my ($filename) = ($line =~ /^Filename: (.*)$/);
+            # Construct real path
+            my $repo_path = File::Spec->join($repo_basepath, $srv_path);
             store_fileinfo( $package, $filename, $dist, $srv_path, $version, $repo_path );
             next;
         }
@@ -3218,32 +3256,39 @@ $adm_gid = getgrnam('adm');
 
 $SIG{CHLD} = 'IGNORE';
 
-# forward error messages to logfile
-if( ! $foreground ) {
-  open( STDIN,  '+>/dev/null' );
-  open( STDOUT, '+>&STDIN'    );
-  open( STDERR, '+>&STDIN'    );
-}
-
 # Just fork, if we are not in foreground mode
 if( ! $foreground ) { 
-    chdir '/'                 or die "Can't chdir to /: $!";
+    if (! chdir('/')) {
+        daemon_log("Can't chdir to /: $!", 1);
+        exit( 1 );
+    }
+    umask( 0 );
     $pid = fork;
-    setsid                    or die "Can't start a new session: $!";
-    umask 0;
 } else { 
     $pid = $$; 
 }
 
-# Do something useful - put our PID into the pid_file
 if( 0 != $pid ) {
+    # Parent: put PID into the $pid_file
     open( LOCK_FILE, ">$pid_file" );
     print LOCK_FILE "$pid\n";
     close( LOCK_FILE );
     if( !$foreground ) { 
-        exit( 0 ) 
-    };
+        exit( 0 );
 }
+}
+else {
+    # Child
+    open( STDIN,  '+>/dev/null' );
+    open( STDOUT, '+>&STDIN'    );
+    open( STDERR, '+>&STDIN'    );
+    if (! POSIX::setsid()) {
+        daemon_log("Can't start a new session: $!");
+        exit( 1 );
+    }
+    $poe_kernel->has_forked() if ($poe_kernel->can('has_forked'));
+}
+
 
 # parse head url and revision from svn
 my $server_status_hash = { 'developmental'=>'revision', 'stable'=>'release'};
@@ -3497,8 +3542,8 @@ daemon_log("0 INFO: start socket for incoming xml messages at port '$server_port
 POE::Session->create(
        inline_states => {
                _start => \&session_start,
+        _stop => \&session_stop,
         register_at_foreign_servers => \&register_at_foreign_servers,
-        sig_handler => \&sig_handler,
         next_task => \&next_task,
         task_result => \&handle_task_result,
         task_done   => \&handle_task_done,
@@ -3512,6 +3557,7 @@ POE::Session->create(
         watch_for_done_jobs => \&watch_for_done_jobs,
         watch_for_opsi_jobs => \&watch_for_opsi_jobs,
         watch_for_old_known_clients => \&watch_for_old_known_clients,
+        watch_for_logged_in_users => \&watch_for_logged_in_users,
         create_packages_list_db => \&run_create_packages_list_db,
         create_fai_server_db => \&run_create_fai_server_db,
         create_fai_release_db => \&run_create_fai_release_db,