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