Footprintless
view release on metacpan or search on metacpan
lib/Footprintless.pm view on Meta::CPAN
my @config_dirs = ();
if ( $options{config_dirs} ) {
@config_dirs =
ref( $options{config_dirs} ) eq 'ARRAY'
? @{ $options{config_dirs} }
: ( $options{config_dirs} );
}
elsif ( $ENV{FPL_CONFIG_DIRS} ) {
@config_dirs = _split_dirs( $ENV{FPL_CONFIG_DIRS} );
}
else {
my $default = File::Spec->catdir( $fpl_home, 'config' );
if ( -d $default ) {
@config_dirs = ($default);
}
}
my @config_options = ();
if ( $options{config_properties} ) {
push( @config_options, properties_file => $options{config_properties} );
}
elsif ( $ENV{FPL_CONFIG_PROPS} ) {
my @properties = _split_dirs( $ENV{FPL_CONFIG_PROPS} );
push( @config_options, properties_file => \@properties );
}
else {
my $default = File::Spec->catdir( $fpl_home, 'properties.pl' );
if ( -f $default ) {
push( @config_options, properties_file => $default );
}
}
$logger->tracef(
"constructing entities with\n\tconfig_dirs: %s\n\tconfig_options: %s)",
\@config_dirs, {@config_options} );
$entities = Config::Entities->new( @config_dirs, {@config_options} );
}
$self->{factory} = factory($entities);
}
return $self;
}
sub localhost {
my ( $self, @args ) = @_;
$self->{factory}->localhost(@args);
}
sub log {
my ( $self, @args ) = @_;
$self->{factory}->log(@args);
}
sub plugins {
my ($self) = @_;
$self->{factory}->plugins();
}
sub overlay {
my ( $self, @args ) = @_;
$self->{factory}->overlay(@args);
}
sub resource_manager {
my ( $self, @args ) = @_;
$self->{factory}->resource_manager(@args);
}
sub service {
my ( $self, @args ) = @_;
$self->{factory}->service(@args);
}
sub tunnel {
my ( $self, @args ) = @_;
$self->{factory}->tunnel(@args);
}
sub _split_dirs {
my ($dirs_string) = @_;
my @dirs = ();
my $separator = ( $^O eq 'MSWin32' ) ? ';' : ':';
foreach my $dir ( split( /$separator/, $dirs_string ) ) {
$dir =~ s/^\s+//;
$dir =~ s/\s+$//;
push( @dirs, $dir );
}
return @dirs;
}
1;
__END__
=pod
=head1 NAME
Footprintless - A utility for managing systems with minimal installs
=head1 VERSION
version 1.29
=head1 SYNOPSIS
use Footprintless;
my $footprintless = Footprintless->new();
# Deploy initialize, start, and follow the log of the foo
$footprintless->overlay('dev.foo.overlay')->initialize();
$footprintless->service('dev.foo.service')->start();
$footprintless->log('dev.foo.logs.app')->follow();
=head1 DESCRIPTION
Footprintless is an automation framework with an application frontend for
managing diverse software stacks in a consistent fashion. It provides a
minimally invasive approach to configuration management. At its core,
L<Config::Entities> are used to define the whole
L<system|https://en.wikipedia.org/wiki/System>. Once defined, the
entities are used by all of the Footprintless modules to decouple the
environment from the action. The environment is defined by the
entities used to create
L<command options|Footprintless::CommandOptionsFactory>. Specifically:
hostname
ssh
sudo_username
username
Each module will have its own entities structure, see them for more
details.
=head1 ENTITIES
An example system my consist of multiple environments, each defined
in their own file:
./fooptintless
/entities
/foo
/dev.pm
/qa.pm
/prod.pm
Each one of them would likely be rather similar, perhaps a variation of:
return {
app => {
deployment => {
'Config::Entities::inherit' => ['hostname', 'sudo_username'],
clean => [
'/opt/foo/tomcat/conf/Catalina/localhost/',
'/opt/foo/tomcat/temp/',
'/opt/foo/tomcat/webapps/',
'/opt/foo/tomcat/work/'
],
resources => {
bar => 'com.pastdev:bar:war:1.0',
baz => 'com.pastdev:baz:war:1.0'
},
to_dir => '/opt/foo/tomcat/webapps'
},
hostname => 'app.pastdev.com',
logs => {
catalina => '/opt/foo/tomcat/logs/catalina.out'
},
overlay => {
'Config::Entities::inherit' => ['hostname', 'sudo_username'],
base_dir => '/home/me/git/foo/base',
clean => [
'/opt/foo/tomcat/'
],
deployment_coordinate => 'foo.dev.app.deployment',
key => 'T',
os => 'linux',
resolver_coordinate => 'foo.dev',
template_dir => '/home/me/git/foo/template',
to_dir => '/opt/foo/tomcat'
},
sudo_username => 'tomcat',
tomcat => {
'Config::Entities::inherit' => ['hostname', 'sudo_username'],
catalina_base => '/opt/foo/tomcat',
http => {
port => 20080
},
service => {
'Config::Entities::inherit' => ['hostname', 'sudo_username'],
action => {
'kill' => { command_args => 'stop -force' },
'status' => { use_pid => 1 }
},
command => '/opt/foo/tomcat/bin/catalina.sh',
pid_file => '/opt/foo/tomcat/bin/.catalina.pid',
},
shutdown => {
port => 20005,
password => $properties->{'foo.dev.app.tomcat.shutdown.password'},
},
trust_store => {
'Config::Entities::inherit' => ['hostname', 'sudo_username'],
file => '/opt/foo/tomcat/certs/truststore.jks',
include_java_home_cacerts => 1,
password => $properties->{'foo.dev.app.tomcat.trust_store.password'},
}
}
}
web => {
hostname => 'web.pastdev.com',
logs => {
error => '/var/log/httpd/error_log',
access => '/var/log/httpd/access_log'
}
sudo_username => 'apache'
}
}
Then when you decide to perform an action, the environment is just part
of the coordinate:
fpl log foo.dev.app.tomcat.logs.catalina follow
fpl service foo.qa.app.tomcat.service status
fpl deployment foo.prod.app.deployment deploy --clean
If using the framework instead, the story is the same:
lib/Footprintless.pm view on Meta::CPAN
operate on the deployment at C<$coordinate>. Supported options are
=over 4
=item command_options_factory
A C<command_options_factory> to use instead of that which is supplied by
this footprintless instance.
=item command_runner
A C<command_runner> to use instead of that which is supplied by
this footprintless instance.
=item localhost
A C<localhost> to use instead of that which is supplied by
this footprintless instance.
=item resource_manager
A C<resource_manager> to use instead of that which is supplied by
this footprintless instance.
=back
=head2 entities()
Returns the L<Config::Entities> that were resolved by this footprintless
instance.
=head2 localhost()
Returns the L<localhost|Footprintless::Localhost> resolver used by
this instance.
=head2 log($coordinate, %options)
Returns a new instance of L<Footprintless::Log> preconfigured to
operate on the log at C<$coordinate>. Supported options are
=over 4
=item command_options_factory
A C<command_options_factory> to use instead of that which is supplied by
this footprintless instance.
=item command_runner
A C<command_runner> to use instead of that which is supplied by
this footprintless instance.
=item localhost
A C<localhost> to use instead of that which is supplied by
this footprintless instance.
=back
=head2 overlay($coordinate, %options)
Returns a new instance of L<Footprintless::Overlay> preconfigured to
operate on the overlay at C<$coordinate>. Supported options are
=over 4
=item command_options_factory
A C<command_options_factory> to use instead of that which is supplied by
this footprintless instance.
=item command_runner
A C<command_runner> to use instead of that which is supplied by
this footprintless instance.
=item localhost
A C<localhost> to use instead of that which is supplied by
this footprintless instance.
=item resource_manager
A C<resource_manager> to use instead of that which is supplied by
this footprintless instance.
=back
=head2 plugins()
Returns the registered plugins for this instance.
=head2 resource_manager()
Returns the L<resource_manager|Footprintless::ResourceManager> used by
this instance.
=head2 service($coordinate, %options)
Returns a new instance of L<Footprintless::Service> preconfigured to
operate on the service at C<$coordinate>. Supported options are
=over 4
=item command_options_factory
A C<command_options_factory> to use instead of that which is supplied by
this footprintless instance.
=item command_runner
A C<command_runner> to use instead of that which is supplied by
this footprintless instance.
=item localhost
A C<localhost> to use instead of that which is supplied by
this footprintless instance.
=back
=head2 tunnel($coordinate, %options)
( run in 1.905 second using v1.01-cache-2.11-cpan-7fcb06a456a )