aboutsummaryrefslogtreecommitdiff
path: root/lib/App/Acmeman/Apache/Layout.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/App/Acmeman/Apache/Layout.pm')
-rw-r--r--lib/App/Acmeman/Apache/Layout.pm186
1 files changed, 111 insertions, 75 deletions
diff --git a/lib/App/Acmeman/Apache/Layout.pm b/lib/App/Acmeman/Apache/Layout.pm
index 7cc8399..39e40d5 100644
--- a/lib/App/Acmeman/Apache/Layout.pm
+++ b/lib/App/Acmeman/Apache/Layout.pm
@@ -4,112 +4,148 @@ use strict;
use warnings;
use Carp;
use File::Basename;
+use feature 'state';
+use App::Acmeman::Log qw(:all);
-require Exporter;
-our @ISA = qw(Exporter);
-
-my %apache_layout_tab = (
- slackware => {
- _test => sub { -d '/etc/httpd/extra' },
- _config_file => '/etc/httpd/httpd.conf',
- _incdir => '/etc/httpd/extra',
- _restart => '/etc/rc.d/rc.httpd restart'
- },
- debian => {
- _config_file => '/etc/apache2/apache2.conf',
- _incdir => sub {
- for my $dir ('/etc/apache2/conf-available',
- '/etc/apache2/conf.d') {
- return $dir if -d $dir;
- }
- carp 'none of the expected configuration directories found; falling back to /etc/apache2';
- return '/etc/apache2';
- },
- _restart => '/usr/sbin/service apache2 restart',
- _post_setup => sub {
- my ($filename) = @_;
- my $dir = dirname($filename);
- my $name = basename($filename);
- if ($dir eq '/etc/apache2/conf-available') {
- chdir('/etc/apache2/conf-enabled');
- symlink "../conf-available/$name", $name;
+sub _find_httpd {
+ my $httpd;
+ foreach my $d (split /:/, $ENV{PATH}) {
+ foreach my $n (glob "$d/apachectl $d/httpd") {
+ if (-x $n) {
+ return $n;
}
}
- },
- rh => {
- _config_file => '/etc/httpd/conf/httpd.conf',
- _incdir => '/etc/httpd/conf.d',
- _restart => '/usr/sbin/service httpd restart'
- },
- suse => {
- _config_file => '/etc/apache2/httpd.conf',
- _test => sub { ! -f '/etc/apache2/apache2.conf' },
- _incdir => '/etc/apache2/conf.d',
- _restart => '/usr/sbin/service httpd restart'
- # or systemctl restart apache2.service
}
-);
+}
+
+sub modules {
+ my $class = shift;
+ my @path = split /::/, $class;
+
+ state $loaders //=
+ [map { $_->[1] }
+ sort { $a->[0] <=> $b->[0] }
+ map {
+ my ($modname) = $class . '::' . fileparse($_, '.pm');
+ eval {
+ no strict 'refs';
+ if (scalar %{ $modname.'::' }) {
+ die "INCLUDED $modname";
+ };
+ require $_;
+ my $prio = ${$modname.'::PRIORITY'} // 0;
+ [ $prio, $modname ]
+ };
+ }
+ map { glob File::Spec->catfile($_, '*.pm') }
+ grep { -d $_ }
+ map { File::Spec->catfile($_, @path) } @INC];
+ @$loaders;
+}
# new(NAME)
# new()
sub new {
my $class = shift;
- my $self = bless { }, $class;
- my $name;
if (@_ == 0) {
- # Autodetect
- while (my ($n, $layout) = each %apache_layout_tab) {
- if (-f $layout->{_config_file}) {
- if (exists($layout->{_test}) && !&{$layout->{_test}}) {
- next;
- }
- $name = $n;
- last;
+ # Autodetect
+ my $ap = new Apache::Defaults(server => $class->_find_httpd,
+ on_error => 'return');
+ if ($ap->status) {
+ croak "unable to get Apache defaults: " . $ap->error;
+ }
+
+ foreach my $mod ($class->modules) {
+ my $obj;
+ eval {
+ $obj = $mod->new($ap);
+ };
+ if ($obj) {
+ return $obj;
}
+# print "A $mod: $@\n";
+ }
+
+ if ($ap) {
+ return new App::Acmeman::Apache::Layout::auto($ap);
}
- croak "unrecognized Apache layout" unless defined $name;
- } elsif (@_ == 1) {
- $name = shift;
+
+ croak "unrecognized Apache layout";
}
-
- if (exists($apache_layout_tab{$name})) {
- @{$self}{keys %{$apache_layout_tab{$name}}} =
- values %{$apache_layout_tab{$name}};
- } else {
- croak "undefined Apache layout $name";
+
+ my ($name, %args) = @_;
+ if (ref($name) eq '') {
+ my $mod = "$class::$name";
+ my $obj;
+ eval {
+ require $mod;
+ };
+ croak "undefined Apache layout $name" if ($@);
+ return $mod->new;
+ }
+
+ unless ($name->isa('Apache::Defaults')) {
+ croak "unrecognized argument";
+ }
+
+ my $self = bless { _defaults => $name }, $class;
+ foreach my $kw (qw(layout_name incdir restart_command)) {
+ if (defined(my $v = delete $args{$kw})) {
+ $self->{$kw} = $v;
+ }
}
- $self->{_layout_name} = $name;
-
return $self;
-}
+}
+
+sub apache { shift->{_defaults} }
sub name {
my $self = shift;
- return $self->{_layout_name};
+ unless ($self->{layout_name}) {
+ $self->{layout_name} = ref($self);
+ $self->{layout_name} =~ s/.*:://;
+ $self->{layout_name} =~ s/\.pm$//;
+ }
+ return $self->{layout_name};
}
-sub config_file {
+sub config_file { shift->apache->server_config }
+
+sub incdir {
my $self = shift;
- return $self->{_config_file};
+ unless ($self->{incdir}) {
+ $self->{incdir} = dirname($self->config_file);
+ }
+ return $self->{incdir};
}
+sub server_command { join(' ', shift->apache->server_command) }
+
sub restart_command {
my $self = shift;
- return $self->{_restart};
-}
-sub incdir {
- my $self = shift;
- if (exists($self->{_incdir})) {
- if (ref($self->{_incdir}) eq 'CODE') {
- return &{$self->{_incdir}};
+ unless (exists($self->{restart_command})) {
+ if ($self->server_command =~ m{/apachectl$}) {
+ $self->{restart_command} = $self->server_command . ' restart';
} else {
- return $self->{_incdir};
+ error("no postrenew command defined", prefix => 'warning');
+ $self->{restart_command} = undef
}
}
- return dirname($self->{_config_file});
+ return $self->{restart_command};
+}
+
+sub post_setup {}
+
+package App::Acmeman::Apache::Layout::auto;
+use parent 'App::Acmeman::Apache::Layout';
+use App::Acmeman::Log qw(:all);
+
+sub new {
+ my ($class, $ap) = @_;
+ return $class->SUPER::new($ap);
}
1;

Return to:

Send suggestions and report system problems to the System administrator.