Skip to content

Commit

Permalink
Clean up Henzell config.
Browse files Browse the repository at this point in the history
Use YAML config instead of home-rolled garbage.

Some spadework to allow additional services that depend on Henzell/Sequell.
  • Loading branch information
greensnark committed Jan 5, 2013
1 parent 4acaf35 commit cfb58dd
Show file tree
Hide file tree
Showing 58 changed files with 1,165 additions and 613 deletions.
127 changes: 7 additions & 120 deletions Henzell/Config.pm
Expand Up @@ -6,6 +6,8 @@ use warnings;
use base 'Exporter'; use base 'Exporter';


use Henzell::ServerConfig; use Henzell::ServerConfig;
use YAML::Any;
use Cwd;


our @EXPORT_OK = qw/read get %CONFIG %CMD %CMDPATH %PUBLIC_CMD our @EXPORT_OK = qw/read get %CONFIG %CMD %CMDPATH %PUBLIC_CMD
@LOGS @MILESTONES/; @LOGS @MILESTONES/;
Expand All @@ -16,9 +18,6 @@ my %DEFAULT_CONFIG = (use_pm => 0,
irc_port => 6667, irc_port => 6667,
lock_name => 'henzell', lock_name => 'henzell',


milestones => 'config/def.stones',
logs => 'config/def.logs',

# Does the bot respond to SQL queries (default: NO) # Does the bot respond to SQL queries (default: NO)
sql_queries => 0, sql_queries => 0,
# Does the bot store logfiles and milestones in # Does the bot store logfiles and milestones in
Expand Down Expand Up @@ -58,113 +57,9 @@ sub get() {
\%CONFIG \%CONFIG
} }


sub abbrev_load() {
%ABBRMAP = Henzell::ServerConfig::server_abbreviations();
for my $key (keys %CONFIG) {
if ($key =~ /^abbr\.(\w+)$/) {
$ABBRMAP{$1} = $CONFIG{$key};
}
}
}

sub abbrev_expand($) {
my $abbr = shift;
# Expand if possible, else leave unchanged:
$ABBRMAP{$abbr} || "\$$abbr"
}

sub abbrev_expand_all($) {
my $text = shift;
return $text unless defined $text;
s/\$(\w+)/abbrev_expand($1)/ge for $text;
$text
}

sub parse_header_field($$) {
my ($hash, $piece) = @_;
my $host = $CONFIG{host} || '';
if ($piece =~ /^local:(\w+)$/) {
if ($1 eq $host) {
$$hash{local} = 1;
$$hash{src} = $1;
}
} elsif ($piece =~ /^remote:(\w+)(?::(.*))?$/) {
if ($host ne $1) {
$$hash{remote} = 1;
$$hash{src} = $1;
$$hash{url} = abbrev_expand_all($2);
}
} elsif ($piece eq 'alpha') {
$$hash{alpha} = 1;
} else {
die "Unknown header field: $piece\n";
}
}

sub log_header_hash($) {
my $header = shift;
s/^\[//, s/\]$// for $header;

my %hash;
for my $piece (split(/;/, $header)) {
s/^\s+//, s/\s+$// for $piece;
parse_header_field(\%hash, $piece);
}

# Has to be either local or remote:
return undef unless $hash{local} || $hash{remote};

\%hash
}

sub resolve_log_path($) {
my $path = shift;
return $path if $path =~ m{/};
"server-xlogs/$path"
}

sub log_path($$) {
my ($header, $path) = @_;

my $log = log_header_hash($header);
return undef unless $log;
$$log{path} = resolve_log_path($path);
$log
}

sub load_log_paths($$$) {
my ($paths, $file, $name) = @_;

@$paths = ();

open my $inf, '<', $file or return;

my $header;

while (<$inf>) {
chomp;
next unless /\S/ && !/^\s*#/;

s/^\s+//; s/\s+$//;

if (/^\[.*\]$/) {
$header = $_;
next;
}

if ($header) {
my $path = $_;
my $logpath = log_path($header, $path);
push @$paths, $logpath if $logpath;
}
}
close $inf;
}

sub load_file_paths() { sub load_file_paths() {
abbrev_load(); @LOGS = Henzell::ServerConfig::server_logfiles();
load_log_paths(\@LOGS, $CONFIG{logs}, "logfiles"); @MILESTONES = Henzell::ServerConfig::server_milestones();
load_log_paths(\@MILESTONES, $CONFIG{milestones}, "milestones");
} }


sub load_public_commands($) { sub load_public_commands($) {
Expand Down Expand Up @@ -209,6 +104,7 @@ sub load_commands($$) {
} }


sub setup_env() { sub setup_env() {
$ENV{HENZELL_ROOT} = getcwd();
if ($CONFIG{host}) { if ($CONFIG{host}) {
$ENV{HENZELL_HOST} = $CONFIG{host}; $ENV{HENZELL_HOST} = $CONFIG{host};
} else { } else {
Expand All @@ -230,18 +126,9 @@ sub read {
%CONFIG = %DEFAULT_CONFIG; %CONFIG = %DEFAULT_CONFIG;


my $inf; my $inf;
open $inf, '<', ($config || $CONFIG_FILE) or undef $inf;
if ($inf) {
while (<$inf>) {
s/^\s+//; s/\s+$//;
next unless /\S/;
if (/^([\w.]+)\s*=\s*(.*)/) {
$CONFIG{$1} = $2;
}
}
close $inf;
}


my $config_file = $config || $CONFIG_FILE;
%CONFIG = (%DEFAULT_CONFIG, %{YAML::Any::LoadFile($config_file)});
# So that users don't have to check for undef warnings. # So that users don't have to check for undef warnings.
$CONFIG{host} ||= ''; $CONFIG{host} ||= '';


Expand Down
19 changes: 18 additions & 1 deletion Henzell/ServerConfig.pm
Expand Up @@ -6,9 +6,26 @@ package Henzell::ServerConfig;
use base 'Exporter'; use base 'Exporter';
use YAML::Any qw/LoadFile/; use YAML::Any qw/LoadFile/;


my $SERVER_CONFIG_FILE = 'config/servers.yml'; use Henzell::SourceServer;

my $SERVER_CONFIG_FILE = 'config/sources.yml';
my $SERVERCFG = LoadFile($SERVER_CONFIG_FILE); my $SERVERCFG = LoadFile($SERVER_CONFIG_FILE);


my @SERVERS = map(Henzell::SourceServer->new($_),
@{$SERVERCFG->{sources}});

sub servers {
@SERVERS
}

sub server_logfiles {
map($_->logfiles(), servers())
}

sub server_milestones {
map($_->milestones(), servers())
}

sub source_hostname { sub source_hostname {
my $source = shift; my $source = shift;
$$SERVERCFG{sources}{$source} $$SERVERCFG{sources}{$source}
Expand Down
79 changes: 79 additions & 0 deletions Henzell/SourceServer.pm
@@ -0,0 +1,79 @@
# Object for a single server (CAO, etc.) and its logfiles / milestones
package Henzell::SourceServer;

use strict;
use warnings;

use Henzell::XlogSrc;

sub new {
my ($cls, $yaml_config) = @_;
my $self = bless { _config => $yaml_config }, $cls;
$self->initialize();
$self
}

sub initialize {
my $self = shift;
$self->{logfiles} = [map {
Henzell::XlogSrc->new($_, 1, $self)
} $self->_expand_files('logfiles')];
$self->{milestones} = [map {
Henzell::XlogSrc->new($_, 0, $self)
} $self->_expand_files('milestones')];
my %duplicate;
for my $source (@{$self->{logfiles}}, @{$self->{milestones}}) {
my $cname = $source->canonical_name();
if ($duplicate{$cname}) {
die("xlogfile collision: " . $source->source_name() . " and " .
$duplicate{$cname}->source_name() . " have same canonical name: " .
$cname);
}
$duplicate{$cname} = $source;
}
}

sub name {
my $self = shift;
$self->{name} ||= $self->{_config}{name}
}

sub local_base {
my $self = shift;
$self->{local_base} ||= $self->{_config}{local}
}

sub http_base {
my $self = shift;
$self->{http_base} ||= $self->{_config}{base}
}

sub logfiles {
my $self = shift;
@{$self->{logfiles}}
}

sub milestones {
my $self = shift;
@{$self->{milestones}}
}

sub split_files {
my $file = shift;
if (ref($file) eq 'HASH') {
my $key = (keys %$file)[0];
my $tag = $file->{$key};
return map(+{ $_ => $tag }, split_files($key));
}
my $asterisked = $file =~ /\*/;
my $suffix = $asterisked ? '*' : '';
$file =~ s/\*//g;
map($_ . $suffix, glob($file))
}

sub _expand_files {
my ($self, $key) = @_;
map(split_files($_), @{$self->{_config}{$key}})
}

1
27 changes: 25 additions & 2 deletions Henzell/Utils.pm
Expand Up @@ -10,12 +10,35 @@ use POSIX;
our @EXPORT = qw/tailed_handle/; our @EXPORT = qw/tailed_handle/;
our @EXPORT_OK = qw/lock_or_die lock daemonify/; our @EXPORT_OK = qw/lock_or_die lock daemonify/;


sub service_def {
my $service_def = shift;
die "Bad service def: must have name, command\n" unless ref($service_def) eq 'HASH';
die "Service def without command\n" unless $service_def->{command};
die "Service def without name\n" unless $service_def->{name};
$service_def
}

sub spawn_services {
my $service_defs = shift;
return unless $service_defs;
for my $service_def (@$service_defs) {
my $service = service_def($service_def);
spawn_service($service->{name}, $service->{directory}, $service->{command});
}
}

sub spawn_service { sub spawn_service {
my ($service_name, $commandline) = @_; my ($service_name, $directory, $commandline) = @_;
$service_name =~ tr/a-zA-Z 0-9//cd;
$service_name =~ tr/ /_/;
$service_name = lc $service_name;
print "Spawning service $service_name in $directory: $commandline\n";
my $pid = fork; my $pid = fork;
return if $pid; return if $pid;


print "Spawning service $service_name: $commandline\n"; if ($directory) {
chdir $directory or die "Couldn't cd $directory: $!\n";
}
my $log_file = "$service_name.log"; my $log_file = "$service_name.log";
open my $logf, '>', $log_file or die "Can't write $log_file: $!\n"; open my $logf, '>', $log_file or die "Can't write $log_file: $!\n";
$logf->autoflush; $logf->autoflush;
Expand Down

0 comments on commit cfb58dd

Please sign in to comment.