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

tincho at users.alioth.debian.org tincho at users.alioth.debian.org
Wed Aug 27 04:47:38 UTC 2008


Author: tincho
Date: Wed Aug 27 04:46:56 2008
New Revision: 24639

URL: http://svn.debian.org/wsvn/?sc=1&rev=24639
Log:
server/KGB: separate into packages for clearer code. Allow SIGQUIT to
restart the server (with complete close and disconnect).

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=24639&op=diff
==============================================================================
--- scripts/KGB/debian/changelog (original)
+++ scripts/KGB/debian/changelog Wed Aug 27 04:46:56 2008
@@ -6,5 +6,7 @@
   [ Martín Ferrari ]
   * server/KGB: move configuration reading and verification to a subroutine,
     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).
 
  -- 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=24639&op=diff
==============================================================================
--- scripts/KGB/server/KGB (original)
+++ scripts/KGB/server/KGB Wed Aug 27 04:46:56 2008
@@ -39,79 +39,29 @@
 =back
 
 =cut
+package KGB;
 
 use strict;
 use warnings;
 
-use POE;
-use POE::Component::Server::SOAP;
-use POE::Component::IRC::State;
-use POE::Component::IRC::Plugin::Connector;
-use POE::Component::IRC::Plugin::NickServID;
-use Getopt::Long;
-use List::Util qw(max);
-use YAML ();
-use Digest::SHA1 qw(sha1_hex);
-use Proc::PID::File;
-
-sub read_conf ($);
-
-my $conf_file = '/etc/kgb/kgb.conf';
-GetOptions(
-    'config=s'  => \$conf_file,
-) or die 'Invalid parameters';
-
- at ARGV and die "No command line arguments supported\n";
-
-my $conf = read_conf($conf_file);
-
-die "Already running\n"
-    if Proc::PID::File->running(
-	verify	=> 1,
-	dir	=> $conf->{pid_dir},
-    );
-    
-POE::Component::Server::SOAP->new(
-    ALIAS   => "SOAPServer",
-    ADDRESS => $conf->{soap}{server_addr},
-    PORT    => $conf->{soap}{server_port},
+our $config;
+our $config_file;
+our %const = (
+    SOAPsvc => "SOAPServer",
+    NSsvc   => "NickServID",
+    NRsvc   => "NickReclaim",
 );
-
-while( my($net,$opts) = each %{$conf->{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( 'NickServID',
-        POE::Component::IRC::Plugin::NickServID->new(
-            Password=>$opts->{nickserv_password},
-        ),
-    ) if $opts->{nickserv_password};
-}
-POE::Session->create(
-    inline_states => {
-        _start          => \&setup_service,
-        _stop           => \&shutdown_service,
-        soap_commit     => \&do_commit,
-        soap_dump       => \&do_dump,
-        irc_registered  => \&irc_registered,
-        irc_001         => \&irc_001,
-        irc_public      => \&irc_public,
-        _default        => \&irc_default,
-        sighandler      => \&sighandler,
-    },
-);
-
-$poe_kernel->run;
-exit 0;
-
+our @argv;
+our $restart = 0;
+
+sub save_argv () {
+    @argv = ($0, @ARGV);
+}
 sub read_conf ($) {
     my $file = shift;
 
-    my $conf = YAML::LoadFile($file) or die "Error loading config from $conf_file\n";
+    my $conf = YAML::LoadFile($file)
+        or die "Error loading config from $file\n";
 
     die "Invalid or missing config key: soap" unless(ref $conf->{soap}
             and ref $conf->{soap} eq "HASH"); 
@@ -141,11 +91,11 @@
 
     foreach(@{$conf->{channels}}) {
         die "Missing channel name at channel\n" unless($_->{name});
-        die "Invalid network at channel ".$_->{name}."\n" unless($_->{network}
-                and $conf->{networks}{$_->{network}});
+        die "Invalid network at channel ".$_->{name}."\n" unless(
+            $_->{network} and $conf->{networks}{$_->{network}});
         push @{$conf->{networks}{$_->{network}}{channels}}, $_->{name};
-        die "Invalid repos key at channel ".$_->{name}."\n" unless(ref $_->{repos}
-                and ref $_->{repos} eq "ARRAY");
+        die "Invalid repos key at channel ".$_->{name}."\n" unless(
+            ref $_->{repos} and ref $_->{repos} eq "ARRAY");
         warn "Channel ".$_->{name}." doesn't listen on any repository\n" unless(
             @{$_->{repos}});
         foreach my $repo (@{$_->{repos}}) {
@@ -157,47 +107,53 @@
     my %chanidx = map ({ $conf->{channels}[$_]{name} => $conf->{channels}[$_] }
         0..$#{$conf->{channels}});
     $conf->{chanidx} = \%chanidx;
+
     return $conf;
 }
-
-sub setup_service {
+sub load_conf($) {
+    my $file = shift;
+    my $conf = read_conf($file);
+
+    # Save globals
+    $config_file = $file;
+    $config = $conf;
+    return $conf;
+}
+
+package KGB::POE;
+
+use strict;
+use warnings;
+
+use POE;
+
+sub _start {
     my $kernel = $_[KERNEL];
     my $session = $_[SESSION];
     my $heap = $_[HEAP];
 
     $kernel->sig( INT => 'sighandler' );
     $kernel->sig( TERM => 'sighandler' );
-
-    $kernel->alias_set($conf->{soap}{service_name});
+    $kernel->sig( QUIT => 'restarthandler' );
+
+    $kernel->alias_set($KGB::config->{soap}{service_name});
     $kernel->post(SOAPServer => 'ADDMETHOD',
-        $conf->{soap}{service_name}, 'soap_commit',
-        $conf->{soap}{service_name}, 'commit',
+        $KGB::config->{soap}{service_name}, 'do_commit',
+        $KGB::config->{soap}{service_name}, 'commit',
     );
     $kernel->signal($kernel => 'POCOIRC_REGISTER', $session->ID(), 'all');
     $heap->{connector} = POE::Component::IRC::Plugin::Connector->new();
 
-    warn("Listening on http://", $conf->{soap}{server_addr}, ":",
-        $conf->{soap}{server_port}, "?session=", $conf->{soap}{service_name},
+    warn("Listening on http://", $KGB::config->{soap}{server_addr}, ":",
+        $KGB::config->{soap}{server_port}, "?session=", $KGB::config->{soap}{service_name},
         "\n");
     undef;
 }
-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});
-    $kernel->post($sender => connect => {
-            Server      => $conf->{networks}{$alias}{server},
-            Port        => $conf->{networks}{$alias}{port},
-        });
-    undef;
-}
-sub shutdown_service {
+sub _stop {
     my $kernel = $_[KERNEL];
     my $session = $_[SESSION]->ID();
     warn "_stop \@session $session\n";
-    $kernel->post(SOAPServer => 'DELSERVICE', $conf->{soap}{service_name});
+    $kernel->post(SOAPServer => 'DELSERVICE', $KGB::config->{soap}{service_name});
 }
 sub sighandler {
     my($kernel, $sig) = ($_[KERNEL], $_[ARG0]);
@@ -209,6 +165,27 @@
     delete $heap->{$_} foreach(keys %$heap);
     undef;
 }
+sub restarthandler {
+    my($kernel, $sig) = ($_[KERNEL], $_[ARG0]);
+    warn "Signal $sig received, restarting...\n";
+    $KGB::restart = 1;
+    $kernel->sig_handled();
+    $kernel->signal($kernel => 'POCOIRC_SHUTDOWN', "KGB going to drink vodka");
+    $kernel->post(SOAPServer => 'STOPLISTEN');
+    my $heap = $_[HEAP];
+    delete $heap->{$_} foreach(keys %$heap);
+    undef;
+}
+
+package KGB::SOAP;
+
+use strict;
+use warnings;
+
+use POE;
+use List::Util qw(max);
+use Digest::SHA1 qw(sha1_hex);
+
 sub do_commit_01 {
     my($kernel, $response, $repo_id, $rev, $paths, $log, $author) = @_;
     my @log = split(/\n+/, $log);
@@ -222,7 +199,7 @@
     # resending to clients because of prefix.
     # Let's trim on 400, to be safe
     my $MAGIC_MAX_LINE = (400 - length("PRIVMSG ") - 
-        max(map(length, @{$conf->{repositories}{$repo_id}{channels}})) -
+        max(map(length, @{$KGB::config->{repositories}{$repo_id}{channels}})) -
         length(" :"));
     while($_ = shift @string) {
         if(length($_) > $MAGIC_MAX_LINE) {
@@ -233,8 +210,8 @@
         }
     }
     @string = @tmp;
-    foreach my $chan (@{$conf->{repositories}{$repo_id}{channels}}) {
-        my $alias = "irc_" . $conf->{chanidx}{$chan}{network};
+    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);
     }
@@ -243,20 +220,20 @@
 }
 sub do_commit_0 {
     my($kernel, $response, $repo_id, $passwd, $rev, $paths, $log, $author) = @_;
-    unless($conf->{min_protocol_version} == 0) {
+    unless($KGB::config->{min_protocol_ver} == 0) {
         $kernel->post(SOAPServer => 'FAULT', $response, 'Client.Arguments',
             "Protocol version 0 not welcome");
         warn("Protocol version 0 rejected\n");
         return
     }
-    unless($conf->{repositories}{$repo_id}) {
+    unless($KGB::config->{repositories}{$repo_id}) {
         $kernel->post(SOAPServer => 'FAULT', $response, 'Client.Arguments',
             "Repository $repo_id is unknown");
         warn("Unknown repository\n");
         return
     }
-    if($conf->{repositories}{$repo_id}{password} and
-        $conf->{repositories}{$repo_id}{password} ne $passwd) {
+    if($KGB::config->{repositories}{$repo_id}{password} and
+        $KGB::config->{repositories}{$repo_id}{password} ne $passwd) {
         $kernel->post(SOAPServer => 'FAULT', $response, 'Client.Arguments',
             "Invalid password for repository $repo_id");
         warn("Invalid password\n");
@@ -266,13 +243,13 @@
 }
 sub do_commit_1 {
     my($kernel, $response, $repo_id, $checksum, $rev, $paths, $log, $author) = @_;
-    unless($conf->{repositories}{$repo_id}) {
+    unless($KGB::config->{repositories}{$repo_id}) {
         $kernel->post(SOAPServer => 'FAULT', $response, 'Client.Arguments',
             "Repository $repo_id is unknown");
         warn("Unknown repository\n");
         return
     }
-    if($conf->{repositories}{$repo_id}{password}
+    if($KGB::config->{repositories}{$repo_id}{password}
 	    and sha1_hex($repo_id, $rev, @$paths, $log, $author) ne $checksum) {
         $kernel->post(SOAPServer => 'FAULT', $response, 'Client.Arguments',
             "Authentication failed for repository $repo_id");
@@ -296,21 +273,21 @@
     }
     if( @{$params->{Array}} == 6 ) {
     	# protocol 0
-	return do_commit_0($kernel, $response, @{$params->{Array}});
+        return do_commit_0($kernel, $response, @{$params->{Array}});
     } 
     my $proto_ver = shift @{$params->{Array}};
     unless(defined($proto_ver) and $proto_ver =~ /^\d{1,5}$/
-        and $conf->{min_protocol_version} <= $proto_ver)
+        and $KGB::config->{min_protocol_ver} <= $proto_ver)
     {
         $proto_ver = "<undef>" unless defined($proto_ver);
 
         $kernel->yield('FAULT', $response, 'Client.commit.Arguments',
-            "Protocol version $proto_ver not welcome");
+            "Protocol version $proto_ver not welcomed");
         warn("Protocol version $proto_ver rejected\n");
         return
     }
     if($proto_ver == 1) {
-	return do_commit_1($kernel, $response, @{$params->{Array}})
+        return do_commit_1($kernel, $response, @{$params->{Array}})
     } else {
         $kernel->post(SOAPServer => 'FAULT', $response, 'Client.Arguments',
             "Invalid protocol version ($proto_ver)");
@@ -318,7 +295,27 @@
         return;
     }
 }
-sub irc_default {
+
+package KGB::IRC;
+
+use strict;
+use warnings;
+
+use POE;
+
+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});
+    $kernel->post($sender => connect => {
+            Server      => $KGB::config->{networks}{$alias}{server},
+            Port        => $KGB::config->{networks}{$alias}{port},
+        });
+    undef;
+}
+sub _default {
     my ($event, $args) = @_[ ARG0 .. $#_ ];
     my $out = "$event ";
     foreach (@$args) {
@@ -353,7 +350,7 @@
     # Get the component's object at any time by accessing the heap of
     # the SENDER
     print "Connected to $alias (", $poco_object->server_name(), ")\n";
-    my $channels = $conf->{networks}{$alias}{channels};
+    my $channels = $KGB::config->{networks}{$alias}{channels};
     if($channels) {
         print "Joining @$channels...\n";
         # In any irc_* events SENDER will be the PoCo-IRC session
@@ -361,3 +358,70 @@
     }
     undef;
 }
+
+package main;
+
+use strict;
+use warnings;
+
+use POE;
+use POE::Component::Server::SOAP;
+use POE::Component::IRC::State;
+use POE::Component::IRC::Plugin::Connector;
+use POE::Component::IRC::Plugin::NickReclaim;
+use POE::Component::IRC::Plugin::NickServID;
+use Getopt::Long;
+use YAML ();
+use Proc::PID::File;
+
+KGB::save_argv();
+
+my $conf_file = '/etc/kgb/kgb.conf';
+GetOptions(
+    'config=s'  => \$conf_file,
+) or die 'Invalid parameters';
+
+ at ARGV and die "No command line arguments supported\n";
+
+KGB::load_conf($conf_file);
+
+die "Already running\n" if(Proc::PID::File->running(
+        verify	=> 1,
+        dir	=> $KGB::config->{pid_dir},
+    ));
+
+POE::Component::Server::SOAP->new(
+    ALIAS   => $KGB::const{SOAPsvc},
+    ADDRESS => $KGB::config->{soap}{server_addr},
+    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) ],
+    ]
+);
+
+$poe_kernel->run;
+if($KGB::restart) {
+    exec @KGB::argv or die "couldn't re-exec: $!\ņ";
+}
+exit 0;




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