diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2020-01-01 20:24:46 +0100 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2020-01-02 00:08:21 +0100 |
commit | c59e5b99ae6c4f3e75284e1549ae72fcee0e2790 (patch) | |
tree | 39946747a67a3379d3745b1b3eac0f1b9424d103 | |
parent | 2a7586e63eb06a1509e76e885080db090b00beab (diff) | |
download | acmeman-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.pm | 3 | ||||
-rw-r--r-- | lib/App/Acmeman/Apache/Layout.pm | 186 | ||||
-rw-r--r-- | lib/App/Acmeman/Apache/Layout/debian.pm | 40 | ||||
-rw-r--r-- | lib/App/Acmeman/Apache/Layout/rh.pm | 21 | ||||
-rw-r--r-- | lib/App/Acmeman/Apache/Layout/slackware.pm | 24 | ||||
-rw-r--r-- | lib/App/Acmeman/Apache/Layout/suse.pm | 22 | ||||
-rw-r--r-- | lib/App/Acmeman/Source/Apache.pm | 4 |
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'); |