r24640 - in /scripts/KGB: debian/changelog server/KGB

tincho at users.alioth.debian.org tincho at users.alioth.debian.org
Wed Aug 27 07:25:26 UTC 2008


Author: tincho
Date: Wed Aug 27 07:25:20 2008
New Revision: 24640

URL: http://svn.debian.org/wsvn/?sc=1&rev=24640
Log:
server/KGB: support for reloading the configuration file with SIGHUP.

Modified:
    scripts/KGB/debian/changelog
    scripts/KGB/server/KGB

Modified: scripts/KGB/debian/changelog
URL: http://svn.debian.org/wsvn/scripts/KGB/debian/changelog?rev=24640&op=diff
==============================================================================
--- scripts/KGB/debian/changelog (original)
+++ scripts/KGB/debian/changelog Wed Aug 27 07:25:20 2008
@@ -8,5 +8,6 @@
     for future support of config reloading.
   * server/KGB: separate into packages for clearer code. Allow SIGQUIT to
     restart the server (with complete close and disconnect).
+  * server/KGB: support for reloading the configuration file with SIGHUP.
 
  -- Damyan Ivanov <dmn at debian.org>  Mon, 28 Jul 2008 14:44:04 +0300

Modified: scripts/KGB/server/KGB
URL: http://svn.debian.org/wsvn/scripts/KGB/server/KGB?rev=24640&op=diff
==============================================================================
--- scripts/KGB/server/KGB (original)
+++ scripts/KGB/server/KGB Wed Aug 27 07:25:20 2008
@@ -48,6 +48,7 @@
 our $config_file;
 our %const = (
     SOAPsvc => "SOAPServer",
+    Connsvc => "Connecter",
     NSsvc   => "NickServID",
     NRsvc   => "NickReclaim",
 );
@@ -119,6 +120,22 @@
     $config = $conf;
     return $conf;
 }
+sub reload_conf() {
+    my $new_conf = eval { KGB::read_conf($config_file) };
+    if($@) {
+        warn "Error in configuration file: $@";
+        return -1;
+    }
+    if($new_conf->{soap}{service_name} ne $config->{soap}{service_name}
+            or $new_conf->{soap}{server_port} ne $config->{soap}{server_port}
+            or $new_conf->{soap}{server_addr} ne $config->{soap}{server_addr}) {
+        warn "Cannot reload configuration file, restarting\n";
+        return -2; # need restart
+    }
+    warn "Configuration file reloaded\n";
+    $config = $new_conf;
+    return 0;
+}
 
 package KGB::POE;
 
@@ -132,21 +149,21 @@
     my $session = $_[SESSION];
     my $heap = $_[HEAP];
 
-    $kernel->sig( INT => 'sighandler' );
+    $kernel->sig( INT  => 'sighandler' );
     $kernel->sig( TERM => 'sighandler' );
     $kernel->sig( QUIT => 'restarthandler' );
+    $kernel->sig( HUP  => 'reloadhandler' );
 
     $kernel->alias_set($KGB::config->{soap}{service_name});
     $kernel->post(SOAPServer => 'ADDMETHOD',
-        $KGB::config->{soap}{service_name}, 'do_commit',
+        $KGB::config->{soap}{service_name}, 'commit',
         $KGB::config->{soap}{service_name}, 'commit',
     );
-    $kernel->signal($kernel => 'POCOIRC_REGISTER', $session->ID(), 'all');
-    $heap->{connector} = POE::Component::IRC::Plugin::Connector->new();
+    $kernel->yield("_irc_reconnect");
 
     warn("Listening on http://", $KGB::config->{soap}{server_addr}, ":",
-        $KGB::config->{soap}{server_port}, "?session=", $KGB::config->{soap}{service_name},
-        "\n");
+        $KGB::config->{soap}{server_port}, "?session=",
+        $KGB::config->{soap}{service_name}, "\n");
     undef;
 }
 sub _stop {
@@ -168,12 +185,32 @@
 sub restarthandler {
     my($kernel, $sig) = ($_[KERNEL], $_[ARG0]);
     warn "Signal $sig received, restarting...\n";
+    $kernel->sig_handled();
     $KGB::restart = 1;
-    $kernel->sig_handled();
-    $kernel->signal($kernel => 'POCOIRC_SHUTDOWN', "KGB going to drink vodka");
+    $kernel->signal($kernel => 'POCOIRC_SHUTDOWN', "KGB restartink");
     $kernel->post(SOAPServer => 'STOPLISTEN');
     my $heap = $_[HEAP];
     delete $heap->{$_} foreach(keys %$heap);
+    undef;
+}
+sub reloadhandler {
+    my($kernel, $sig) = ($_[KERNEL], $_[ARG0]);
+    warn "Signal $sig received, reloading...\n";
+    $kernel->sig_handled();
+    my $ret = KGB::reload_conf();
+    if($ret == -1) { # error in config file
+        return undef;
+    } elsif($ret == -2) { # needs reload
+        warn "Forcing restart\n";
+        $KGB::restart = 1;
+        $kernel->signal($kernel => 'POCOIRC_SHUTDOWN', "KGB restartink");
+        $kernel->post(SOAPServer => 'STOPLISTEN');
+        my $heap = $_[HEAP];
+        delete $heap->{$_} foreach(keys %$heap);
+        return undef;
+    }
+    # Reload successful
+    $kernel->yield("_irc_reconnect");
     undef;
 }
 
@@ -213,7 +250,9 @@
     foreach my $chan (@{$KGB::config->{repositories}{$repo_id}{channels}}) {
         my $alias = "irc_" . $KGB::config->{chanidx}{$chan}{network};
         $kernel->post($alias => privmsg => $chan => $_) foreach(@string);
-        print "$alias/$chan > $_\n" foreach(@string);
+        if($KGB::config->{debug}) {
+            print $KGB::out "$alias/$chan > $_\n" foreach(@string);
+        }
     }
     $response->content( "OK" );
     $kernel->post( SOAPServer => 'DONE', $response );
@@ -258,17 +297,17 @@
     }
     do_commit_01($kernel, $response, $repo_id, $rev, $paths, $log, $author);
 }
-sub do_commit {
+sub commit {
     my $kernel = $_[KERNEL];
     my $response = $_[ARG0];
     my $params = $response->soapbody;
-    warn("commit: " . YAML::Dump($params));
+    print $KGB::out "commit: " . YAML::Dump($params) if($KGB::config->{debug});
     unless(ref $params and ref $params eq "HASH"
             and $params->{Array} and ref $params->{Array}
             and ref $params->{Array} eq "ARRAY") {
         $kernel->post(SOAPServer => 'FAULT', $response, 'Client.Arguments',
             'commit(params ...)');
-        warn("Invalid call\n");
+        print $KGB::out "Invalid call\n" if($KGB::config->{debug});
         return;
     }
     if( @{$params->{Array}} == 6 ) {
@@ -283,7 +322,8 @@
 
         $kernel->yield('FAULT', $response, 'Client.commit.Arguments',
             "Protocol version $proto_ver not welcomed");
-        warn("Protocol version $proto_ver rejected\n");
+        print $KGB::out "Protocol version $proto_ver rejected\n" if(
+            $KGB::config->{debug});
         return
     }
     if($proto_ver == 1) {
@@ -291,7 +331,8 @@
     } else {
         $kernel->post(SOAPServer => 'FAULT', $response, 'Client.Arguments',
             "Invalid protocol version ($proto_ver)");
-        warn("Invalid protocol version ($proto_ver)\n");
+        print $KGB::out "Invalid protocol version ($proto_ver)\n" if(
+            $KGB::config->{debug});
         return;
     }
 }
@@ -303,19 +344,96 @@
 
 use POE;
 
+our %current = ();
+
+sub _irc_reconnect {
+    my ($kernel, $session) = @_[KERNEL, SESSION];
+    my(@to_start, @to_stop, @to_restart);
+
+    foreach my $net (keys %current) {
+        next unless(defined($current{$net}));
+        my($new, $old) = ($KGB::config->{networks}{$net}, $current{$net});
+        if(! $new) {
+            push @to_stop, $net;
+        } elsif($new->{nick} ne $old->{nick}
+                or $new->{ircname} ne $old->{ircname}
+                or $new->{username} ne $old->{username}
+                or ($new->{password} || "") ne ($old->{password} || "")
+                or ($new->{nickserv_password} || "") ne
+            ($old->{nickserv_password} || "")
+                or $new->{server} ne $old->{server}
+                or $new->{port} ne $old->{port}) {
+            push @to_restart, $net;
+        } else {
+            my(%newchan, %oldchan, %allchan);
+            %newchan = map({ $_ => 1 } @{$new->{channels}});
+            %oldchan = map({ $_ => 1 } @{$old->{channels}});
+            %allchan = (%newchan, %oldchan);
+            foreach my $chan (keys %allchan) {
+                if($newchan{$chan} and ! $oldchan{$chan}) {
+                    print $KGB::out "Joining $chan...\n";
+                    $kernel->post("irc_$net" => join => $chan);
+                } elsif(! $newchan{$chan} and $oldchan{$chan}) {
+                    print $KGB::out "Parting $chan...\n";
+                    $kernel->post("irc_$net" => part => $chan);
+                }
+            }
+            $current{$net} = $new;
+        }
+    }
+    foreach(keys %{$KGB::config->{networks}}) {
+        if(! $current{$_}) {
+            push @to_start, $_;
+        }
+    }
+    foreach my $net (@to_start) {
+        my $opts = $KGB::config->{networks}{$net};
+        $current{$net} = $opts;
+        my $irc = POE::Component::IRC::State->spawn(
+            Alias       => "irc_$net");
+
+        # No need to register, as it's done automatically now. If you register
+        # twice, POE never exits
+    }
+    foreach(@to_stop, @to_restart) {
+        print $KGB::out "Disconnecting from $_\n";
+        $kernel->post("irc_$_" => "shutdown");
+        delete $current{$_};
+    }
+    if(@to_restart) {
+        $kernel->delay("_irc_reconnect", 3);
+    }
+}
 sub irc_registered {
     my ($kernel, $heap, $sender, $irc_object) = @_[KERNEL, HEAP, SENDER, ARG0];
+
     my $alias = $irc_object->session_alias();
-
     $alias =~ s/^irc_//;
-    $irc_object->plugin_add('Connector' => $heap->{connector});
+    my $opts = $KGB::config->{networks}{$alias};
+
+    $irc_object->plugin_add($KGB::const{NSsvc},
+        POE::Component::IRC::Plugin::NickServID->new(
+            Password => $opts->{nickserv_password},
+        )) if($opts->{nickserv_password});
+
+    $irc_object->plugin_add($KGB::const{NRsvc},
+        POE::Component::IRC::Plugin::NickReclaim->new());
+
+    $irc_object->plugin_add($KGB::const{Connsvc},
+        POE::Component::IRC::Plugin::Connector->new());
+
     $kernel->post($sender => connect => {
-            Server      => $KGB::config->{networks}{$alias}{server},
-            Port        => $KGB::config->{networks}{$alias}{port},
+            Server      => $opts->{server},
+            Port        => $opts->{port},
+            Nick        => $opts->{nick},
+            Ircname     => $opts->{ircname},
+            Username    => $opts->{username},
+            Password    => $opts->{password}
         });
     undef;
 }
 sub _default {
+    return 0 unless($KGB::config->{debug});
     my ($event, $args) = @_[ ARG0 .. $#_ ];
     my $out = "$event ";
     foreach (@$args) {
@@ -329,16 +447,17 @@
             $out .= "undef ";
         }
     }
-    print "$out\n";
+    print $KGB::out "$out\n";
     return 0;
 }
 sub irc_public {
+    return undef unless($KGB::config->{debug});
     my ($kernel, $heap, $who, $where, $what) = @_[KERNEL, HEAP, ARG0, ARG1,
     ARG2];
     my $nick = (split /!/, $who)[0];
     my $chan = $where->[0];
 
-    print($chan . ':<' . $nick . '> ' . $what . "\n");
+    print $KGB::out ($chan . ':<' . $nick . '> ' . $what . "\n");
     undef;
 }
 sub irc_001 {
@@ -349,10 +468,10 @@
     $alias =~ s/^irc_//;
     # Get the component's object at any time by accessing the heap of
     # the SENDER
-    print "Connected to $alias (", $poco_object->server_name(), ")\n";
+    print $KGB::out "Connected to $alias (", $poco_object->server_name(), ")\n";
     my $channels = $KGB::config->{networks}{$alias}{channels};
     if($channels) {
-        print "Joining @$channels...\n";
+        print $KGB::out "Joining @$channels...\n";
         # In any irc_* events SENDER will be the PoCo-IRC session
         $kernel->post( $sender => join => $_ ) for @$channels;
     }
@@ -375,6 +494,7 @@
 use Proc::PID::File;
 
 KGB::save_argv();
+$KGB::out = \*STDERR;
 
 my $conf_file = '/etc/kgb/kgb.conf';
 GetOptions(
@@ -396,28 +516,15 @@
     PORT    => $KGB::config->{soap}{server_port},
 );
 
-while( my($net,$opts) = each %{$KGB::config->{networks}}) {
-    my $irc = POE::Component::IRC::State->spawn(
-        Alias       => "irc_$net",
-        Nick        => $opts->{nick},
-        Ircname     => $opts->{ircname},
-        Username    => $opts->{username},
-        Password    => $opts->{password}
-    );
-    $irc->plugin_add($KGB::const{NSsvc},
-        POE::Component::IRC::Plugin::NickServID->new(
-            Password=>$opts->{nickserv_password},
-        ),
-    ) if $opts->{nickserv_password};
-    $irc->plugin_add($KGB::const{NRsvc},
-        POE::Component::IRC::Plugin::NickReclaim->new());
-}
 POE::Session->create(
     package_states => [
-        "KGB::POE"  => [ qw(_start _stop sighandler restarthandler) ],
-        "KGB::IRC"  => [ qw(irc_registered irc_001 irc_public _default) ],
-        "KGB::SOAP" => [ qw(do_commit) ],
-    ]
+        "KGB::POE"  => [ qw(_start _stop sighandler restarthandler
+        reloadhandler) ],
+        "KGB::IRC"  => [ qw(_irc_reconnect irc_registered irc_001
+        irc_public _default) ],
+        "KGB::SOAP" => [ qw(commit) ],
+    ],
+#    options => {trace => 1, debug => 0}
 );
 
 $poe_kernel->run;




More information about the Pkg-perl-cvs-commits mailing list