aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2020-01-01 20:24:46 +0100
committerSergey Poznyakoff <gray@gnu.org.ua>2020-01-02 00:08:21 +0100
commitc59e5b99ae6c4f3e75284e1549ae72fcee0e2790 (patch)
tree39946747a67a3379d3745b1b3eac0f1b9424d103
parent2a7586e63eb06a1509e76e885080db090b00beab (diff)
downloadacmeman-c59e5b99ae6c4f3e75284e1549ae72fcee0e2790.tar.gz
acmeman-c59e5b99ae6c4f3e75284e1549ae72fcee0e2790.tar.bz2
Use external modules to support different Apache configuration layouts.
* lib/App/Acmeman.pm: Minor change. * lib/App/Acmeman/Apache/Layout.pm: Rewrite. Use external modules to support different layouts. * lib/App/Acmeman/Apache/Layout/debian.pm: Definition of Debian layout. * lib/App/Acmeman/Apache/Layout/rh.pm: Definition of Red Hat layout. * lib/App/Acmeman/Apache/Layout/slackware.pm: Definition of Slackware layout. * lib/App/Acmeman/Apache/Layout/suse.pm: Definition of Suse layout
-rw-r--r--lib/App/Acmeman.pm3
-rw-r--r--lib/App/Acmeman/Apache/Layout.pm186
-rw-r--r--lib/App/Acmeman/Apache/Layout/debian.pm40
-rw-r--r--lib/App/Acmeman/Apache/Layout/rh.pm21
-rw-r--r--lib/App/Acmeman/Apache/Layout/slackware.pm24
-rw-r--r--lib/App/Acmeman/Apache/Layout/suse.pm22
-rw-r--r--lib/App/Acmeman/Source/Apache.pm4
7 files changed, 221 insertions, 79 deletions
diff --git a/lib/App/Acmeman.pm b/lib/App/Acmeman.pm
index 01191ab..02231bf 100644
--- a/lib/App/Acmeman.pm
+++ b/lib/App/Acmeman.pm
@@ -333,7 +333,8 @@ sub renew {
local $ENV{ACMEMAN_ALT_NAMES} =
join(' ', map { ($_->alt) } @renewed);
if ($self->cf->is_set(qw(core postrenew))) {
- foreach my $cmd ($self->cf->get(qw(core postrenew))) {
+ foreach my $cmd (grep { defined($_) }
+ $self->cf->get(qw(core postrenew))) {
$self->runcmd($cmd);
}
} else {
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;
diff --git a/lib/App/Acmeman/Apache/Layout/debian.pm b/lib/App/Acmeman/Apache/Layout/debian.pm
new file mode 100644
index 0000000..663883e
--- /dev/null
+++ b/lib/App/Acmeman/Apache/Layout/debian.pm
@@ -0,0 +1,40 @@
+package App::Acmeman::Apache::Layout::debian;
+use strict;
+use warnings;
+use Carp;
+use parent 'App::Acmeman::Apache::Layout';
+use File::Basename;
+
+our $PRIORITY = 20;
+
+sub new {
+ my $class = shift;
+ my $ap = shift;
+
+ if ($ap->server_config eq '/etc/apache2/apache2.conf') {
+ return $class->SUPER::new($ap,
+ restart_command => '/usr/sbin/service apache2 restart'
+ );
+ }
+}
+
+sub incdir {
+ 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';
+}
+
+sub post_setup {
+ my ($self,$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;
+ }
+}
+
+1;
diff --git a/lib/App/Acmeman/Apache/Layout/rh.pm b/lib/App/Acmeman/Apache/Layout/rh.pm
new file mode 100644
index 0000000..9adea70
--- /dev/null
+++ b/lib/App/Acmeman/Apache/Layout/rh.pm
@@ -0,0 +1,21 @@
+package App::Acmeman::Apache::Layout::rh;
+use strict;
+use warnings;
+use Carp;
+use parent 'App::Acmeman::Apache::Layout';
+
+our $PRIORITY = 30;
+
+sub new {
+ my $class = shift;
+ my $ap = shift;
+
+ if ($ap->server_config eq '/etc/httpd/conf/httpd.conf') {
+ return $class->SUPER::new($ap,
+ incdir => '/etc/httpd/conf.d',
+ restart_command => '/usr/sbin/service httpd restart'
+ );
+ }
+}
+
+1;
diff --git a/lib/App/Acmeman/Apache/Layout/slackware.pm b/lib/App/Acmeman/Apache/Layout/slackware.pm
new file mode 100644
index 0000000..89297fc
--- /dev/null
+++ b/lib/App/Acmeman/Apache/Layout/slackware.pm
@@ -0,0 +1,24 @@
+package App::Acmeman::Apache::Layout::slackware;
+use strict;
+use warnings;
+use Carp;
+use parent 'App::Acmeman::Apache::Layout';
+
+our $PRIORITY = 10;
+
+sub new {
+ my $class = shift;
+ my $ap = shift;
+
+ if ($ap->server_config eq '/etc/httpd/httpd.conf'
+ && -d '/etc/httpd/extra') {
+ return $class->SUPER::new($ap,
+ incdir => '/etc/httpd/extra',
+ restart_command => '/etc/rc.d/rc.httpd restart'
+ );
+ }
+}
+
+1;
+
+
diff --git a/lib/App/Acmeman/Apache/Layout/suse.pm b/lib/App/Acmeman/Apache/Layout/suse.pm
new file mode 100644
index 0000000..f524442
--- /dev/null
+++ b/lib/App/Acmeman/Apache/Layout/suse.pm
@@ -0,0 +1,22 @@
+package App::Acmeman::Apache::Layout::suse;
+use strict;
+use warnings;
+use Carp;
+use parent 'App::Acmeman::Apache::Layout';
+
+our $PRIORITY = 40;
+
+sub new {
+ my $class = shift;
+ my $ap = shift;
+
+ if ($ap->server_config eq '/etc/apache2/httpd.conf'
+ && ! -f '/etc/apache2/apache2.conf') {
+ return $class->SUPER::new($ap,
+ incdir => '/etc/apache2/conf.d',
+ restart_command => '/usr/sbin/service httpd restart'
+ );
+ }
+}
+
+1;
diff --git a/lib/App/Acmeman/Source/Apache.pm b/lib/App/Acmeman/Source/Apache.pm
index ecde285..8b7eda1 100644
--- a/lib/App/Acmeman/Source/Apache.pm
+++ b/lib/App/Acmeman/Source/Apache.pm
@@ -216,9 +216,7 @@ EOT
;
close $fd;
- if (exists($self->{_post_setup})) {
- &{$self->{_post_setup}}($filename);
- }
+ $self->layout->post_setup($filename);
}
error("created file \"$filename\"", prefix => 'note');

Return to:

Send suggestions and report system problems to the System administrator.