The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
<html><head><title>Footprintless</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" >

<style type="text/css">
 <!--/*--><![CDATA[/*><!--*/
BODY {
  background: white;
  color: black;
  font-family: arial,sans-serif;
  margin: 0;
  padding: 1ex;
}

A:link, A:visited {
  background: transparent;
  color: #006699;
}

A[href="#POD_ERRORS"] {
  background: transparent;
  color: #FF0000;
}

DIV {
  border-width: 0;
}

DT {
  margin-top: 1em;
  margin-left: 1em;
}

.pod { margin-right: 20ex; }

.pod PRE     {
  background: #eeeeee;
  border: 1px solid #888888;
  color: black;
  padding: 1em;
  white-space: pre;
}

.pod H1      {
  background: transparent;
  color: #006699;
  font-size: large;
}

.pod H1 A { text-decoration: none; }
.pod H2 A { text-decoration: none; }
.pod H3 A { text-decoration: none; }
.pod H4 A { text-decoration: none; }

.pod H2      {
  background: transparent;
  color: #006699;
  font-size: medium;
}

.pod H3      {
  background: transparent;
  color: #006699;
  font-size: medium;
  font-style: italic;
}

.pod H4      {
  background: transparent;
  color: #006699;
  font-size: medium;
  font-weight: normal;
}

.pod IMG     {
  vertical-align: top;
}

.pod .toc A  {
  text-decoration: none;
}

.pod .toc LI {
  line-height: 1.2em;
  list-style-type: none;
}

  /*]]>*/-->
</style>


</head>
<body class='pod'>
<!--
  generated by Pod::Simple::HTML v3.32,
  using Pod::Simple::PullParser v3.32,
  under Perl v5.025000 at Tue Feb 13 13:45:22 2018 GMT.

 If you want to change this HTML document, you probably shouldn't do that
   by changing it directly.  Instead, see about changing the calling options
   to Pod::Simple::HTML, and/or subclassing Pod::Simple::HTML,
   then reconverting this document from the Pod source.
   When in doubt, email the author of Pod::Simple::HTML for advice.
   See 'perldoc Pod::Simple::HTML' for more info.

-->

<!-- start doc -->
<a name='___top' class='dummyTopAnchor' ></a>

<div class='indexgroup'>
<ul   class='indexList indexList1'>
  <li class='indexItem indexItem1'><a href='#NAME'>NAME</a>
  <li class='indexItem indexItem1'><a href='#VERSION'>VERSION</a>
  <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a>
  <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a>
  <li class='indexItem indexItem1'><a href='#ENTITIES'>ENTITIES</a>
  <li class='indexItem indexItem1'><a href='#CONSTRUCTORS'>CONSTRUCTORS</a>
  <ul   class='indexList indexList2'>
    <li class='indexItem indexItem2'><a href='#new(%5C%25entity%2C_%25options)'>new(\%entity, %options)</a>
  </ul>
  <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a>
  <ul   class='indexList indexList2'>
    <li class='indexItem indexItem2'><a href='#agent(%25options)'>agent(%options)</a>
    <li class='indexItem indexItem2'><a href='#command_options_factory()'>command_options_factory()</a>
    <li class='indexItem indexItem2'><a href='#command_runner()'>command_runner()</a>
    <li class='indexItem indexItem2'><a href='#deployment(%24coordinate%2C_%25options)'>deployment($coordinate, %options)</a>
    <li class='indexItem indexItem2'><a href='#entities()'>entities()</a>
    <li class='indexItem indexItem2'><a href='#localhost()'>localhost()</a>
    <li class='indexItem indexItem2'><a href='#log(%24coordinate%2C_%25options)'>log($coordinate, %options)</a>
    <li class='indexItem indexItem2'><a href='#overlay(%24coordinate%2C_%25options)'>overlay($coordinate, %options)</a>
    <li class='indexItem indexItem2'><a href='#plugins()'>plugins()</a>
    <li class='indexItem indexItem2'><a href='#resource_manager()'>resource_manager()</a>
    <li class='indexItem indexItem2'><a href='#service(%24coordinate%2C_%25options)'>service($coordinate, %options)</a>
    <li class='indexItem indexItem2'><a href='#tunnel(%24coordinate%2C_%25options)'>tunnel($coordinate, %options)</a>
  </ul>
  <li class='indexItem indexItem1'><a href='#AUTHOR'>AUTHOR</a>
  <li class='indexItem indexItem1'><a href='#COPYRIGHT_AND_LICENSE'>COPYRIGHT AND LICENSE</a>
  <li class='indexItem indexItem1'><a href='#SEE_ALSO'>SEE ALSO</a>
</ul>
</div>

<h1><a class='u' href='#___top' title='click to go to top of document'
name="NAME"
>NAME</a></h1>

<p>Footprintless - A utility for managing systems with minimal installs</p>

<h1><a class='u' href='#___top' title='click to go to top of document'
name="VERSION"
>VERSION</a></h1>

<p>version 1.27</p>

<h1><a class='u' href='#___top' title='click to go to top of document'
name="SYNOPSIS"
>SYNOPSIS</a></h1>

<pre>    use Footprintless;

    my $footprintless = Footprintless-&#62;new();

    # Deploy initialize, start, and follow the log of the foo
    $footprintless-&#62;overlay(&#39;dev.foo.overlay&#39;)-&#62;initialize();
    $footprintless-&#62;service(&#39;dev.foo.service&#39;)-&#62;start();
    $footprintless-&#62;log(&#39;dev.foo.logs.app&#39;)-&#62;follow();</pre>

<h1><a class='u' href='#___top' title='click to go to top of document'
name="DESCRIPTION"
>DESCRIPTION</a></h1>

<p>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, <a href="http://search.cpan.org/perldoc?Config%3A%3AEntities" class="podlinkpod"
>Config::Entities</a> are used to define the whole <a href="https://en.wikipedia.org/wiki/System" class="podlinkurl"
>system</a>. 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 <a href="http://search.cpan.org/perldoc?Footprintless%3A%3ACommandOptionsFactory" class="podlinkpod"
>command options</a>. Specifically:</p>

<pre>    hostname
    ssh
    sudo_username
    username</pre>

<p>Each module will have its own entities structure, see them for more details.</p>

<h1><a class='u' href='#___top' title='click to go to top of document'
name="ENTITIES"
>ENTITIES</a></h1>

<p>An example system my consist of multiple environments, each defined in their own file:</p>

<pre>    ./fooptintless
                  /entities
                           /foo
                               /dev.pm
                               /qa.pm
                               /prod.pm</pre>

<p>Each one of them would likely be rather similar, perhaps a variation of:</p>

<pre>    return {
        app =&#62; {
            deployment =&#62; {
                &#39;Config::Entities::inherit&#39; =&#62; [&#39;hostname&#39;, &#39;sudo_username&#39;],
                clean =&#62; [
                    &#39;/opt/foo/tomcat/conf/Catalina/localhost/&#39;,
                    &#39;/opt/foo/tomcat/temp/&#39;,
                    &#39;/opt/foo/tomcat/webapps/&#39;,
                    &#39;/opt/foo/tomcat/work/&#39;
                ],
                resources =&#62; {
                    bar =&#62; &#39;com.pastdev:bar:war:1.0&#39;,
                    baz =&#62; &#39;com.pastdev:baz:war:1.0&#39;
                },
                to_dir =&#62; &#39;/opt/foo/tomcat/webapps&#39;
            },
            hostname =&#62; &#39;app.pastdev.com&#39;,
            logs =&#62; {
                catalina =&#62; &#39;/opt/foo/tomcat/logs/catalina.out&#39;
            },
            overlay =&#62; {
                &#39;Config::Entities::inherit&#39; =&#62; [&#39;hostname&#39;, &#39;sudo_username&#39;],
                base_dir =&#62; &#39;/home/me/git/foo/base&#39;,
                clean =&#62; [
                    &#39;/opt/foo/tomcat/&#39;
                ],
                deployment_coordinate =&#62; &#39;foo.dev.app.deployment&#39;,
                key =&#62; &#39;T&#39;,
                os =&#62; &#39;linux&#39;,
                resolver_coordinate =&#62; &#39;foo.dev&#39;,
                template_dir =&#62; &#39;/home/me/git/foo/template&#39;,
                to_dir =&#62; &#39;/opt/foo/tomcat&#39;
            },
            sudo_username =&#62; &#39;tomcat&#39;,
            tomcat =&#62; {
                &#39;Config::Entities::inherit&#39; =&#62; [&#39;hostname&#39;, &#39;sudo_username&#39;],
                catalina_base =&#62; &#39;/opt/foo/tomcat&#39;,
                http =&#62; {
                    port =&#62; 20080
                },
                service =&#62; {
                    &#39;Config::Entities::inherit&#39; =&#62; [&#39;hostname&#39;, &#39;sudo_username&#39;],
                    action =&#62; {
                        &#39;kill&#39; =&#62; { command_args =&#62; &#39;stop -force&#39; },
                        &#39;status&#39; =&#62; { use_pid =&#62; 1 }
                    },
                    command =&#62; &#39;/opt/foo/tomcat/bin/catalina.sh&#39;,
                    pid_file =&#62; &#39;/opt/foo/tomcat/bin/.catalina.pid&#39;,
                },
                shutdown =&#62; {
                    port =&#62; 20005,
                    password =&#62; $properties-&#62;{&#39;foo.dev.app.tomcat.shutdown.password&#39;},
                },
                trust_store =&#62; {
                    &#39;Config::Entities::inherit&#39; =&#62; [&#39;hostname&#39;, &#39;sudo_username&#39;],
                    file =&#62; &#39;/opt/foo/tomcat/certs/truststore.jks&#39;,
                    include_java_home_cacerts =&#62; 1,
                    password =&#62; $properties-&#62;{&#39;foo.dev.app.tomcat.trust_store.password&#39;},
                }
            }
        }
        web =&#62; {
            hostname =&#62; &#39;web.pastdev.com&#39;,
            logs =&#62; {
                error =&#62; &#39;/var/log/httpd/error_log&#39;,
                access =&#62; &#39;/var/log/httpd/access_log&#39;
            }
            sudo_username =&#62; &#39;apache&#39;
        }
    }</pre>

<p>Then when you decide to perform an action, the environment is just part of the coordinate:</p>

<pre>    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</pre>

<p>If using the framework instead, the story is the same:</p>

<pre>    my $permission_denied = Footprintless-&#62;new()
        -&#62;log(&#39;foo.prod.web.logs.error&#39;)
        -&#62;grep(options =&#62; &#39;Permission denied&#39;);</pre>

<h1><a class='u' href='#___top' title='click to go to top of document'
name="CONSTRUCTORS"
>CONSTRUCTORS</a></h1>

<h2><a class='u' href='#___top' title='click to go to top of document'
name="new(\%entity,_%options)"
>new(\%entity, %options)</a></h2>

<p>Creates a new Footprintless factory. Available options are:</p>

<dl>
<dt><a name="config_dirs"
>config_dirs</a></dt>

<dd>
<p>The root folder(s) for configuration entities. Defaults to the <code>$FPL_CONFIG_DIRS</code> environment variable if set, <code>$FPL_HOME/config</code> if not. <code>config_dirs</code> can be a scalar (one directory), or an array ref if there is more than one directory. If set via the <code>$FPL_CONFIG_DIRS</code> environment variable, and you need more than one directory, use a <code>;</code> to delimit on windows, or a <code>:</code> to delimit on *nix (same as the <code>$PATH</code> variable).</p>

<dt><a name="config_properties"
>config_properties</a></dt>

<dd>
<p>The properties file(s) used for placeholder replacement for configuration entities. Defaults to the <code>$FPL_CONFIG_PROPS</code> environment variable if set, <code>$FPL_HOME/properties.pl</code> if not. <code>config_properties</code> can be a scalar (one file), or an array ref if there is more than one directory. If set via the <code>$FPL_CONFIG_PROPS</code> environment variable, and you need more than one directory, use a <code>;</code> to delimit on windows, or a <code>:</code> to delimit on *nix (same as the <code>$PATH</code> variable).</p>

<dt><a name="command_options_factory"
>command_options_factory</a></dt>

<dd>
<p>Sets the <code>command_options_factory</code> for this instance. Must be an instance or subclass of <code>Footprintless::CommandOptionsFactory</code>.</p>

<dt><a name="command_runner"
>command_runner</a></dt>

<dd>
<p>Sets the <code>command_runner</code> for this instance. Must be an a subclass of <code>Footprintless::CommandRunner</code>.</p>

<dt><a name="entities"
>entities</a></dt>

<dd>
<p>If supplied, <code>entities</code> will serve as the configuration for this instance. All other configuration sources will be ignored. Must be either a hashref, or an instance of <a href="http://search.cpan.org/perldoc?Config%3A%3AEntities" class="podlinkpod"
>Config::Entities</a>.</p>

<dt><a name="fpl_home"
>fpl_home</a></dt>

<dd>
<p>The root folder for footprintless configuration. Defaults to the <code>$FPL_HOME</code> environment variable if set, <code>~/.footprintless</code> if not.</p>

<dt><a name="localhost"
>localhost</a></dt>

<dd>
<p>Sets the <code>localhost</code> resolver for this instance. Must be an instance or subclass of <code>Footprintless::Localhost</code>.</p>
</dd>
</dl>

<h1><a class='u' href='#___top' title='click to go to top of document'
name="METHODS"
>METHODS</a></h1>

<h2><a class='u' href='#___top' title='click to go to top of document'
name="agent(%options)"
>agent(%options)</a></h2>

<p>Returns a new <a href="http://search.cpan.org/perldoc?LWP%3A%3AUserAgent" class="podlinkpod"
>agent</a> obtained from <code>agent</code> in <a href="http://search.cpan.org/perldoc?Footprintless%3A%3AUtil" class="podlinkpod"
>Footprintless::Util</a>. The supported options are:</p>

<dl>
<dt><a name="cookie_jar"
>cookie_jar</a></dt>

<dd>
<p>A hashref for storing cookies. If not supplied, cookies will be ignored.</p>

<dt><a name="timeout"
>timeout</a></dt>

<dd>
<p>The http request timeout.</p>
</dd>
</dl>

<h2><a class='u' href='#___top' title='click to go to top of document'
name="command_options_factory()"
>command_options_factory()</a></h2>

<p>Returns the <a href="http://search.cpan.org/perldoc?Footprintless%3A%3ACommandOptionsFactory" class="podlinkpod"
>command_options_factory</a> used by this instance.</p>

<h2><a class='u' href='#___top' title='click to go to top of document'
name="command_runner()"
>command_runner()</a></h2>

<p>Returns the <a href="http://search.cpan.org/perldoc?Footprintless%3A%3ACommandRunner" class="podlinkpod"
>command_runner</a> used by this instance.</p>

<h2><a class='u' href='#___top' title='click to go to top of document'
name="deployment($coordinate,_%options)"
>deployment($coordinate, %options)</a></h2>

<p>Returns a new instance of <a href="http://search.cpan.org/perldoc?Footprintless%3A%3ADeployment" class="podlinkpod"
>Footprintless::Deployment</a> preconfigured to operate on the deployment at <code>$coordinate</code>. Supported options are</p>

<dl>
<dt><a name="command_options_factory"
>command_options_factory</a></dt>

<dd>
<p>A <code>command_options_factory</code> to use instead of that which is supplied by this footprintless instance.</p>

<dt><a name="command_runner"
>command_runner</a></dt>

<dd>
<p>A <code>command_runner</code> to use instead of that which is supplied by this footprintless instance.</p>

<dt><a name="localhost"
>localhost</a></dt>

<dd>
<p>A <code>localhost</code> to use instead of that which is supplied by this footprintless instance.</p>

<dt><a name="resource_manager"
>resource_manager</a></dt>

<dd>
<p>A <code>resource_manager</code> to use instead of that which is supplied by this footprintless instance.</p>
</dd>
</dl>

<h2><a class='u' href='#___top' title='click to go to top of document'
name="entities()"
>entities()</a></h2>

<p>Returns the <a href="http://search.cpan.org/perldoc?Config%3A%3AEntities" class="podlinkpod"
>Config::Entities</a> that were resolved by this footprintless instance.</p>

<h2><a class='u' href='#___top' title='click to go to top of document'
name="localhost()"
>localhost()</a></h2>

<p>Returns the <a href="http://search.cpan.org/perldoc?Footprintless%3A%3ALocalhost" class="podlinkpod"
>localhost</a> resolver used by this instance.</p>

<h2><a class='u' href='#___top' title='click to go to top of document'
name="log($coordinate,_%options)"
>log($coordinate, %options)</a></h2>

<p>Returns a new instance of <a href="http://search.cpan.org/perldoc?Footprintless%3A%3ALog" class="podlinkpod"
>Footprintless::Log</a> preconfigured to operate on the log at <code>$coordinate</code>. Supported options are</p>

<dl>
<dt><a name="command_options_factory"
>command_options_factory</a></dt>

<dd>
<p>A <code>command_options_factory</code> to use instead of that which is supplied by this footprintless instance.</p>

<dt><a name="command_runner"
>command_runner</a></dt>

<dd>
<p>A <code>command_runner</code> to use instead of that which is supplied by this footprintless instance.</p>

<dt><a name="localhost"
>localhost</a></dt>

<dd>
<p>A <code>localhost</code> to use instead of that which is supplied by this footprintless instance.</p>
</dd>
</dl>

<h2><a class='u' href='#___top' title='click to go to top of document'
name="overlay($coordinate,_%options)"
>overlay($coordinate, %options)</a></h2>

<p>Returns a new instance of <a href="http://search.cpan.org/perldoc?Footprintless%3A%3AOverlay" class="podlinkpod"
>Footprintless::Overlay</a> preconfigured to operate on the overlay at <code>$coordinate</code>. Supported options are</p>

<dl>
<dt><a name="command_options_factory"
>command_options_factory</a></dt>

<dd>
<p>A <code>command_options_factory</code> to use instead of that which is supplied by this footprintless instance.</p>

<dt><a name="command_runner"
>command_runner</a></dt>

<dd>
<p>A <code>command_runner</code> to use instead of that which is supplied by this footprintless instance.</p>

<dt><a name="localhost"
>localhost</a></dt>

<dd>
<p>A <code>localhost</code> to use instead of that which is supplied by this footprintless instance.</p>

<dt><a name="resource_manager"
>resource_manager</a></dt>

<dd>
<p>A <code>resource_manager</code> to use instead of that which is supplied by this footprintless instance.</p>
</dd>
</dl>

<h2><a class='u' href='#___top' title='click to go to top of document'
name="plugins()"
>plugins()</a></h2>

<p>Returns the registered plugins for this instance.</p>

<h2><a class='u' href='#___top' title='click to go to top of document'
name="resource_manager()"
>resource_manager()</a></h2>

<p>Returns the <a href="http://search.cpan.org/perldoc?Footprintless%3A%3AResourceManager" class="podlinkpod"
>resource_manager</a> used by this instance.</p>

<h2><a class='u' href='#___top' title='click to go to top of document'
name="service($coordinate,_%options)"
>service($coordinate, %options)</a></h2>

<p>Returns a new instance of <a href="http://search.cpan.org/perldoc?Footprintless%3A%3AService" class="podlinkpod"
>Footprintless::Service</a> preconfigured to operate on the service at <code>$coordinate</code>. Supported options are</p>

<dl>
<dt><a name="command_options_factory"
>command_options_factory</a></dt>

<dd>
<p>A <code>command_options_factory</code> to use instead of that which is supplied by this footprintless instance.</p>

<dt><a name="command_runner"
>command_runner</a></dt>

<dd>
<p>A <code>command_runner</code> to use instead of that which is supplied by this footprintless instance.</p>

<dt><a name="localhost"
>localhost</a></dt>

<dd>
<p>A <code>localhost</code> to use instead of that which is supplied by this footprintless instance.</p>
</dd>
</dl>

<h2><a class='u' href='#___top' title='click to go to top of document'
name="tunnel($coordinate,_%options)"
>tunnel($coordinate, %options)</a></h2>

<p>Returns a new instance of <a href="http://search.cpan.org/perldoc?Footprintless%3A%3ATunnel" class="podlinkpod"
>Footprintless::Tunnel</a> preconfigured for <code>$coordinate</code>.</p>

<h1><a class='u' href='#___top' title='click to go to top of document'
name="AUTHOR"
>AUTHOR</a></h1>

<p>Lucas Theisen &#60;lucastheisen@pastdev.com&#62;</p>

<h1><a class='u' href='#___top' title='click to go to top of document'
name="COPYRIGHT_AND_LICENSE"
>COPYRIGHT AND LICENSE</a></h1>

<p>This software is copyright (c) 2016 by Lucas Theisen.</p>

<p>This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.</p>

<h1><a class='u' href='#___top' title='click to go to top of document'
name="SEE_ALSO"
>SEE ALSO</a></h1>

<p>Please see those modules/websites for more information related to this module.</p>

<ul>
<li><a href="http://search.cpan.org/perldoc?Footprintless%3A%3ADeployment" class="podlinkpod"
>Footprintless::Deployment</a></li>

<li><a href="http://search.cpan.org/perldoc?Footprintless%3A%3ALog" class="podlinkpod"
>Footprintless::Log</a></li>

<li><a href="http://search.cpan.org/perldoc?Footprintless%3A%3AOverlay" class="podlinkpod"
>Footprintless::Overlay</a></li>

<li><a href="http://search.cpan.org/perldoc?Footprintless%3A%3AService" class="podlinkpod"
>Footprintless::Service</a></li>

<li><a href="https://github.com/lucastheisen/footprintless" class="podlinkurl"
>https://github.com/lucastheisen/footprintless</a></li>
</ul>

<!-- end doc -->

</body></html>