package Test::Instance::Apache::Modules;
use Moo;
use IO::All;
=head1 NAME
Test::Instance::Apache::Modules - Apache module management for T::I::A
=head1 SYNOPSIS
use FindBin qw/ $Bin /;
use Test::Instance::Apache::Modules;
my $modules = Test::Instance::Apache::Modules->new(
server_root => "$Bin/conf",
modules => [ qw/ mpm_prefork authz_core mome / ],
);
# get include paths for config
my $paths = $modules->include_modules;
=head1 DESCRIPTION
Test::Instance::Apache::Modules sets up the required modules for Apache
according to an array of module names. This functions similarly to C<a2enmod>
which comes as part of the Apache distribution, however is much more simplified
to only do what is necessary for T::I::A.
The module creates a C<mods-available> and C<mods-enabled> folder inside the
L</server_root> directory, and then copies the contents of
C</etc/apache2/mods-available> into the new C<mods-available> folder. Then,
symlinks are created across to the C<mods-enabled> folder, ready for Apache to
include from the L</include_modules> list.
=head2 Attributes
These are the available attributes on Test::Instance::Apache::Modules
=head3 modules
The arrayref of modules to symlink into C<mods-enabled> folder. This is
required. Note that any modules specified here will need to be installed on
your local machine, and you will have to specify ALL modules required - there
are no assumptions made for modules to include.
=cut
has modules => (
is => 'ro',
required => 1,
isa => sub { die "modules must be an array!\n" unless ref $_[0] eq 'ARRAY' },
);
=head3 server_root
The root directory of the server config. This directory is where
C<mods-available> and C<mods-enabled> directories will be created. This
attribute is required.
=cut
has server_root => (
is => 'ro',
required => 1,
);
has _available_mods_folder => (
is => 'lazy',
builder => sub {
my $self = shift;
return $self->make_server_dir( 'mods-available' );
},
);
has _enabled_mods_folder => (
is => 'lazy',
builder => sub {
my $self = shift;
return $self->make_server_dir( 'mods-enabled' );
},
);
=head3 include_modules
This creates the include paths for the C<conf> and C<load> files as required by
Apache.
=cut
has include_modules => (
is => 'lazy',
builder => sub {
my $self = shift;
my @include;
foreach ( qw/ load conf / ) {
push @include, 'Include';
push @include, sprintf( '%s/*.%s', $self->_enabled_mods_folder, $_ );
}
return \@include;
},
);
=head2 Methods
These are the methods available on Test::Instance::Apache::Modules.
=head3 load_modules
This function performs the main part of this module. This copies all the
current mods from C</etc/apache2/mods-available> to the C<mods-available>
directory, and then symlinks all the required modules across to the
C<mods-enabled> folder.
=cut
sub load_modules {
my $self = shift;
io->dir( '/etc/apache2/mods-available' )->copy( $self->_available_mods_folder );
for my $module ( @{ $self->modules } ) {
for my $suffix ( qw/ conf load / ) {
my $source_filename = File::Spec->catfile(
$self->_available_mods_folder,
sprintf( '%s.%s', $module, $suffix )
);
my $target_filename = File::Spec->catfile(
$self->_enabled_mods_folder,
sprintf( '%s.%s', $module, $suffix )
);
if ( -f $source_filename ) {
# if the file does not exist, just ignore it as not all mods have config files
symlink( $source_filename, $target_filename );
}
}
}
}
=head3 make_server_dir
Utility function to create a new directory in the L</server_root>.
=cut
sub make_server_dir {
my ( $self, @dirnames ) = @_;
my $dir = File::Spec->catdir( $self->server_root, @dirnames );
mkdir $dir;
return $dir;
}
=head1 AUTHOR
Tom Bloor E<lt>t.bloor@shadowcat.co.ukE<gt>
=head1 COPYRIGHT
Copyright 2016 Tom Bloor
=head1 LICENCE
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=head1 SEE ALSO
=over
=item * L<Test::Instance::Apache>
=back
=cut
1;