mod 'puppetlabs/concat', '1.2.2'
mod 'puppetlabs/rabbitmq', '5.2.1'
mod 'elasticsearch/elasticsearch', '0.9.5'
+mod 'nanliu/staging', '1.0.3'
--- /dev/null
+source "https://rubygems.org"
+
+group :development, :test do
+ gem 'bodeco_module_helper', :git => 'https://github.com/bodeco/bodeco_module_helper.git'
+ gem 'rspec', "~> 2.11.0", :require => false
+ gem 'mocha', "~> 0.10.5", :require => false
+end
--- /dev/null
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
--- /dev/null
+# Staging module for Puppet
+
+Manages staging directory, along with download/extraction of compressed files.
+
+[![Build Status](https://secure.travis-ci.org/nanliu/puppet-staging.png?branch=master)](http://travis-ci.org/nanliu/puppet-staging)
+
+WARNING: Version 0.2.0 no longer uses hiera functions. The same behavior should be available in Puppet 3.0.
+
+NOTE: Version 1.0.0 will be the last feature release. New functionality such as checksum will be implemented in a type/provider module [puppet-archive](https://www.github.com/nanliu/puppet-archive).
+
+## Usage
+
+Specify a different default staging path (must be declared before using resource):
+```puppet
+class { 'staging':
+ path => '/var/staging',
+ owner => 'puppet',
+ group => 'puppet',
+}
+```
+
+Staging files from various sources:
+```puppet
+staging::file { 'sample':
+ source => 'puppet://modules/staging/sample',
+}
+
+staging::file { 'apache-tomcat-6.0.35':
+ source => 'http://apache.cs.utah.edu/tomcat/tomcat-6/v6.0.35/bin/apache-tomcat-6.0.35.tar.gz',
+}
+```
+
+Staging and extracting files:
+```puppet
+staging::file { 'sample.tar.gz':
+ source => 'puppet:///modules/staging/sample.tar.gz'
+}
+
+staging::extract { 'sample.tar.gz':
+ target => '/tmp/staging',
+ creates => '/tmp/staging/sample',
+ require => Staging::File['sample.tar.gz'],
+}
+```
+
+Deploying a file (combining staging and extract):
+```puppet
+staging::deploy { 'sample.tar.gz':
+ source => 'puppet:///modules/staging/sample.tar.gz',
+ target => '/usr/local',
+}
+```
+
+Staging files currently support the following source:
+
+* http(s)://
+* puppet://
+* ftp://
+* s3:// (requires aws cli to be installed and configured.)
+* local (though this doesn't serve any real purpose.)
+
+## Contributor
+
+* Adrien Thebo
+* gizero
+* Harald Skoglund
+* Hunter Haugen
+* Justin Clayton
+* Owen Jacobson
+* Reid Vandewiele
--- /dev/null
+require 'bodeco_module_helper/rake_tasks'
--- /dev/null
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+Vagrant.configure("2") do |config|
+ # All Vagrant configuration is done here. The most common configuration
+ # options are documented and commented below. For a complete reference,
+ # please see the online documentation at vagrantup.com.
+
+ #config.vm.synced_folder "manifests", "/tmp/manifests", "tests"
+ config.vm.synced_folder "./", "/etc/puppet/modules/staging"
+
+ config.vm.define :staging do |m|
+ m.vm.box = "centos63"
+ m.vm.box_url = "https://dl.dropbox.com/s/eqdrqnla4na8qax/centos63.box"
+
+ m.vm.hostname = 'staging'
+ m.vm.provider :vmware_fusion do |v|
+ v.vmx["displayName"] = "staging"
+ v.vmx["memsize"] = 512
+ v.vmx["numvcpus"] = 4
+ end
+
+ m.vm.provision :puppet do |puppet|
+ puppet.manifests_path = "tests"
+ puppet.module_path = "spec/fixtures/modules/"
+ puppet.manifest_file = "init.pp"
+ end
+ end
+end
--- /dev/null
+{
+ "Gemfile": "270871f3fe4a93fd7c2df1666717cabb",
+ "LICENSE": "cdbf8d74b765504fbdf8e154bb4458a1",
+ "README.md": "af449710d996f056cf718289ff800af7",
+ "Rakefile": "a56b311c2311136cccbc2fdc3490dc77",
+ "Vagrantfile": "eef71b5e6febf751053145cc86752758",
+ "docs/deploy.html": "d9342a62d811e8d331c83a9521d7cb60",
+ "docs/extract.html": "ddfc7718ed639b24861b5a1d68cf0b0c",
+ "docs/file.html": "879efe671f96a8eaeb5fb023ced5b7ab",
+ "docs/init.html": "c16ebedfb85ab41558ad2fdea679177d",
+ "files/sample": "c668e2074cc870f9ef59b6b33ffda097",
+ "files/sample.tar.bz2": "d063a08e52797236df1b769dbdbd2c69",
+ "files/sample.tar.gz": "eba24f899d8b439f5c461f728563ece6",
+ "lib/facter/staging_http_get.rb": "1f89d73e82135c4c9533119e2a95690d",
+ "lib/facter/staging_windir.rb": "6897a62c26ff15041cae6b62bf9b7a35",
+ "lib/puppet/parser/functions/scope_defaults.rb": "da916d46f3ff3be8359f75c93c2b5532",
+ "lib/puppet/parser/functions/staging_parse.rb": "cf6a6648b567b6efd3d0741e5f690ca8",
+ "manifests/deploy.pp": "f2a3e783e69ab878ac2e115fdf897e52",
+ "manifests/extract.pp": "b4ac5a23a1e307c46764bca61c28e21c",
+ "manifests/file.pp": "9488fefca4c3aca6d293ae0d76db84aa",
+ "manifests/init.pp": "8363cfb8b0ec3c378a9b58e4749c57ee",
+ "manifests/params.pp": "229aaeafe695fa94e8c5b5602f4a9f77",
+ "metadata.json": "85161c511984d3151e884c448e7aaae8",
+ "spec/defines/staging_deploy_spec.rb": "d4310153779c65fb168ab275c81c7f36",
+ "spec/defines/staging_extract_spec.rb": "1aa0aa8419fcf98f374e3a62e2d01958",
+ "spec/defines/staging_file_spec.rb": "a11f653feeb70cd8631de5f69aaa4dcb",
+ "spec/fixtures/hiera.yaml": "324e9873e29c1970850f01b0f64c0269",
+ "spec/spec_helper.rb": "050ea9cc153b1c6da1db53cf6cf214a8",
+ "spec/unit/puppet/parser/functions/scope_defaults_spec.rb": "16a2af56511497feb7417e226161221f",
+ "spec/unit/puppet/parser/functions/staging_parse_spec.rb": "1a811cf7ca52b4b6fe3fe59ae0ebd38b",
+ "tests/deploy.pp": "27e2deca3fd5353dc8aa37c9162b2368",
+ "tests/extract.pp": "8076b72133e9240500b8e04eea023918",
+ "tests/file.pp": "8588e9c8b5e2ca430271ba2045dfb286",
+ "tests/init.pp": "d889d06d4cb307c38cba9267aaac978f",
+ "tests/scope_defaults.pp": "b620b367fc13aad2ff6f09f0c18463ba",
+ "tests/staging_parse.pp": "bec31082b383ef5bf6f81e4e82ec3b94"
+}
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html;charset=utf-8">
+ <title>deploy.pp</title>
+ <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
+</head>
+<body>
+<div id='container'>
+ <div id="background"></div>
+ <div id="jump_to">
+ Jump To …
+ <div id="jump_wrapper">
+ <div id="jump_page">
+ <a class="source" href="deploy.html">deploy.pp</a>
+ <a class="source" href="extract.html">extract.pp</a>
+ <a class="source" href="file.html">file.pp</a>
+ <a class="source" href="init.html">init.pp</a>
+ </div>
+ </div>
+ </div>
+ <table cellspacing=0 cellpadding=0>
+ <thead>
+ <tr>
+ <th class=docs><h1>deploy.pp</h1></th>
+ <th class=code></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr id='section-Define:_staging::deploy'>
+ <td class=docs>
+ <div class="pilwrap">
+ <a class="pilcrow" href="#section-Define:_staging::deploy">¶</a>
+ </div>
+ <h3>Define: staging::deploy</h3>
+
+<p>The define resource extracts compressed file to a staging location.</p>
+
+<h3>Parameters:</h3>
+
+<ul>
+<li>[<em>source</em>]: the source file location, supports local files, puppet://, http://, https://, ftp:// (default: )</li>
+<li>[<em>target</em>]: the target extraction directory (default: )</li>
+<li>[<em>staging_path</em>]: the staging location for compressed file. defaults to ${staging::path}/${caller_module_name} (default: undef)</li>
+<li>[<em>username</em>]: https or ftp username (default: undef)</li>
+<li>[<em>certificate</em>]: https certifcate file (default: undef)</li>
+<li>[<em>password</em>]: https or ftp user password or https certificate password (default: undef)</li>
+<li>[<em>environment</em>]: environment variable for settings such as http_proxy (default: undef)</li>
+<li>[<em>timeout</em>]: the time to wait for the file transfer to complete (default: undef)</li>
+<li>[<em>user</em>]: extract file as this user (default: undef)</li>
+<li>[<em>group</em>]: extract group as this group (default: undef)</li>
+<li>[<em>creates</em>]: the file/folder created after extraction. if unspecified defaults to ${target}/${name} (default: undef)</li>
+<li>[<em>unless</em>]: alternative way to conditionally extract file (default: undef)</li>
+<li>[<em>onlyif</em>]: alternative way to conditionally extract file (default: undef)</li>
+</ul>
+
+
+<h3>Usage:</h3>
+
+<pre><code>staging::deploy { 'sample.tar.gz':
+ source => 'puppet:///modules/staging/sample.tar.gz',
+ target => '/usr/local',
+}
+</code></pre>
+
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">define</span> <span class="n">staging</span><span class="o">::</span><span class="n">deploy</span> <span class="p">(</span>
+ <span class="vg">$source</span><span class="p">,</span>
+ <span class="vg">$target</span><span class="p">,</span>
+ <span class="vg">$staging_path</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$username</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$certificate</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$password</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$environment</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$timeout</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$user</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$group</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$creates</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$unless</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$onlyif</span> <span class="o">=</span> <span class="k">undef</span>
+<span class="p">)</span> <span class="p">{</span>
+
+ <span class="n">staging</span><span class="o">::</span><span class="n">file</span> <span class="p">{</span> <span class="vg">$name</span><span class="p">:</span>
+ <span class="n">source</span> <span class="o">=></span> <span class="vg">$source</span><span class="p">,</span>
+ <span class="n">target</span> <span class="o">=></span> <span class="vg">$staging_path</span><span class="p">,</span>
+ <span class="n">username</span> <span class="o">=></span> <span class="vg">$username</span><span class="p">,</span>
+ <span class="n">certificate</span> <span class="o">=></span> <span class="vg">$certificate</span><span class="p">,</span>
+ <span class="n">password</span> <span class="o">=></span> <span class="vg">$password</span><span class="p">,</span>
+ <span class="n">environment</span> <span class="o">=></span> <span class="vg">$environment</span><span class="p">,</span>
+ <span class="n">subdir</span> <span class="o">=></span> <span class="vg">$caller_module_name</span><span class="p">,</span>
+ <span class="n">timeout</span> <span class="o">=></span> <span class="vg">$timeout</span><span class="p">,</span>
+ <span class="p">}</span>
+
+ <span class="n">staging</span><span class="o">::</span><span class="n">extract</span> <span class="p">{</span> <span class="vg">$name</span><span class="p">:</span>
+ <span class="n">target</span> <span class="o">=></span> <span class="vg">$target</span><span class="p">,</span>
+ <span class="n">source</span> <span class="o">=></span> <span class="vg">$staging_path</span><span class="p">,</span>
+ <span class="n">user</span> <span class="o">=></span> <span class="vg">$user</span><span class="p">,</span>
+ <span class="n">group</span> <span class="o">=></span> <span class="vg">$group</span><span class="p">,</span>
+ <span class="n">environment</span> <span class="o">=></span> <span class="vg">$environment</span><span class="p">,</span>
+ <span class="n">subdir</span> <span class="o">=></span> <span class="vg">$caller_module_name</span><span class="p">,</span>
+ <span class="n">creates</span> <span class="o">=></span> <span class="vg">$creates</span><span class="p">,</span>
+ <span class="k">unless</span> <span class="o">=></span> <span class="vg">$unless</span><span class="p">,</span>
+ <span class="n">onlyif</span> <span class="o">=></span> <span class="vg">$onlyif</span><span class="p">,</span>
+ <span class="nb">require</span> <span class="o">=></span> <span class="no">Staging</span><span class="o">::</span><span class="no">File</span><span class="o">[</span><span class="vg">$name</span><span class="o">]</span><span class="p">,</span>
+ <span class="p">}</span>
+
+<span class="p">}</span></pre></div>
+ </td>
+ </tr>
+ </table>
+</div>
+</body>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html;charset=utf-8">
+ <title>extract.pp</title>
+ <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
+</head>
+<body>
+<div id='container'>
+ <div id="background"></div>
+ <div id="jump_to">
+ Jump To …
+ <div id="jump_wrapper">
+ <div id="jump_page">
+ <a class="source" href="deploy.html">deploy.pp</a>
+ <a class="source" href="extract.html">extract.pp</a>
+ <a class="source" href="file.html">file.pp</a>
+ <a class="source" href="init.html">init.pp</a>
+ </div>
+ </div>
+ </div>
+ <table cellspacing=0 cellpadding=0>
+ <thead>
+ <tr>
+ <th class=docs><h1>extract.pp</h1></th>
+ <th class=code></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr id='section-Define:_staging::extract'>
+ <td class=docs>
+ <div class="pilwrap">
+ <a class="pilcrow" href="#section-Define:_staging::extract">¶</a>
+ </div>
+ <h3>Define: staging::extract</h3>
+
+<p>Define resource to extract files from staging directories to target directories.</p>
+
+<h3>Parameters:</h3>
+
+<ul>
+<li>[<em>target</em>]: the target extraction directory (default: )</li>
+<li>[<em>source</em>]: the source compression file, supports tar, tar.gz, zip, war (default: undef)</li>
+<li>[<em>creates</em>]: the file created after extraction. if unspecified defaults ${staging::path}/${caller_module_name}/${name} ${target}/${name} (default: undef)</li>
+<li>[<em>unless</em>]: alternative way to conditionally check whether to extract file. (default: undef)</li>
+<li>[<em>onlyif</em>]: alternative way to conditionally check whether to extract file. (default: undef)</li>
+<li>[<em>user</em>]: extract file as this user. (default: undef)</li>
+<li>[<em>group</em>]: extract file as this group. (default: undef)</li>
+<li>[<em>environment</em>]: environment variables. (default: undef)</li>
+<li>[<em>subdir</em>]: subdir per module in staging directory. (default: $caller_module_name)</li>
+</ul>
+
+
+<h3>Usage:</h3>
+
+<pre><code>$caller_module_name = 'demo'
+
+class { 'staging':
+ path => '/tmp/staging',
+}
+
+staging::file { 'sample.tar.gz':
+ source => 'puppet:///modules/staging/sample.tar.gz'
+}
+
+staging::extract { 'sample.tar.gz':
+ target => '/tmp/staging',
+ creates => '/tmp/staging/sample',
+ require => Staging::File['sample.tar.gz'],
+}
+</code></pre>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">define</span> <span class="n">staging</span><span class="o">::</span><span class="n">extract</span> <span class="p">(</span>
+ <span class="vg">$target</span><span class="p">,</span>
+ <span class="vg">$source</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$creates</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$unless</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$onlyif</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$user</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$group</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$environment</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$subdir</span> <span class="o">=</span> <span class="vg">$caller_module_name</span>
+<span class="p">)</span> <span class="p">{</span>
+
+ <span class="kp">include</span> <span class="n">staging</span>
+
+ <span class="k">if</span> <span class="vg">$source</span> <span class="p">{</span>
+ <span class="vg">$source_path</span> <span class="o">=</span> <span class="vg">$source</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="vg">$source_path</span> <span class="o">=</span> <span class="s2">"${staging::path}/${subdir}/${name}"</span>
+ <span class="p">}</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-2'>
+ <td class=docs>
+ <div class="pilwrap">
+ <a class="pilcrow" href="#section-2">¶</a>
+ </div>
+ <p>Use user supplied creates path, set default value if creates, unless or
+onlyif is not supplied.</p>
+
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="k">if</span> <span class="vg">$creates</span> <span class="p">{</span>
+ <span class="vg">$creates_path</span> <span class="o">=</span> <span class="vg">$creates</span>
+ <span class="p">}</span> <span class="k">elsif</span> <span class="o">!</span> <span class="p">(</span><span class="vg">$unless</span> <span class="ow">or</span> <span class="vg">$onlyif</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="vg">$name</span> <span class="o">=~</span> <span class="sr">/.tar.gz$/</span> <span class="p">{</span>
+ <span class="vg">$folder</span> <span class="o">=</span> <span class="n">staging_parse</span><span class="p">(</span><span class="vg">$name</span><span class="p">,</span> <span class="s1">'basename'</span><span class="p">,</span> <span class="s1">'.tar.gz'</span><span class="p">)</span>
+ <span class="vg">$creates_path</span> <span class="o">=</span> <span class="s2">"${target}/${folder}"</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="vg">$folder</span> <span class="o">=</span> <span class="n">staging_parse</span><span class="p">(</span><span class="vg">$name</span><span class="p">,</span> <span class="s1">'basename'</span><span class="p">)</span>
+ <span class="vg">$creates_path</span> <span class="o">=</span> <span class="s2">"${target}/${folder}"</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+
+ <span class="k">if</span> <span class="n">scope_defaults</span><span class="p">(</span><span class="s1">'Exec'</span><span class="p">,</span><span class="s1">'path'</span><span class="p">)</span> <span class="p">{</span>
+ <span class="no">Exec</span><span class="p">{</span>
+ <span class="n">cwd</span> <span class="o">=></span> <span class="vg">$target</span><span class="p">,</span>
+ <span class="n">user</span> <span class="o">=></span> <span class="vg">$user</span><span class="p">,</span>
+ <span class="n">group</span> <span class="o">=></span> <span class="vg">$group</span><span class="p">,</span>
+ <span class="n">environment</span> <span class="o">=></span> <span class="vg">$environment</span><span class="p">,</span>
+ <span class="n">creates</span> <span class="o">=></span> <span class="vg">$creates_path</span><span class="p">,</span>
+ <span class="k">unless</span> <span class="o">=></span> <span class="vg">$unless</span><span class="p">,</span>
+ <span class="n">onlyif</span> <span class="o">=></span> <span class="vg">$onlyif</span><span class="p">,</span>
+ <span class="n">logoutput</span> <span class="o">=></span> <span class="n">on_failure</span><span class="p">,</span>
+ <span class="p">}</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="no">Exec</span><span class="p">{</span>
+ <span class="n">path</span> <span class="o">=></span> <span class="vg">$:</span><span class="ss">:path</span><span class="p">,</span>
+ <span class="n">cwd</span> <span class="o">=></span> <span class="vg">$target</span><span class="p">,</span>
+ <span class="n">user</span> <span class="o">=></span> <span class="vg">$user</span><span class="p">,</span>
+ <span class="n">group</span> <span class="o">=></span> <span class="vg">$group</span><span class="p">,</span>
+ <span class="n">environment</span> <span class="o">=></span> <span class="vg">$environment</span><span class="p">,</span>
+ <span class="n">creates</span> <span class="o">=></span> <span class="vg">$creates_path</span><span class="p">,</span>
+ <span class="k">unless</span> <span class="o">=></span> <span class="vg">$unless</span><span class="p">,</span>
+ <span class="n">onlyif</span> <span class="o">=></span> <span class="vg">$onlyif</span><span class="p">,</span>
+ <span class="n">logoutput</span> <span class="o">=></span> <span class="n">on_failure</span><span class="p">,</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+
+ <span class="k">case</span> <span class="vg">$name</span> <span class="p">{</span>
+ <span class="sr">/.tar$/</span><span class="p">:</span> <span class="p">{</span>
+ <span class="vg">$command</span> <span class="o">=</span> <span class="s2">"tar xf ${source_path}"</span>
+ <span class="p">}</span>
+
+ <span class="sr">/(.tgz|.tar.gz)$/</span><span class="p">:</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="vg">$:</span><span class="ss">:osfamily</span> <span class="o">==</span> <span class="s1">'Solaris'</span> <span class="p">{</span>
+ <span class="vg">$command</span> <span class="o">=</span> <span class="s2">"gunzip -dc < ${source_path} | tar xf - "</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="vg">$command</span> <span class="o">=</span> <span class="s2">"tar xzf ${source_path}"</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+
+ <span class="sr">/.zip$/</span><span class="p">:</span> <span class="p">{</span>
+ <span class="vg">$command</span> <span class="o">=</span> <span class="s2">"unzip ${source_path}"</span>
+ <span class="p">}</span>
+
+ <span class="sr">/.war$/</span><span class="p">:</span> <span class="p">{</span>
+ <span class="vg">$command</span> <span class="o">=</span> <span class="s2">"jar xf ${source_path}"</span>
+ <span class="p">}</span>
+
+ <span class="n">default</span><span class="p">:</span> <span class="p">{</span>
+ <span class="nb">fail</span><span class="p">(</span><span class="s2">"staging::extract: unsupported file format ${name}."</span><span class="p">)</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+
+ <span class="nb">exec</span> <span class="p">{</span> <span class="s2">"extract ${name}"</span><span class="p">:</span>
+ <span class="n">command</span> <span class="o">=></span> <span class="vg">$command</span><span class="p">,</span>
+ <span class="p">}</span>
+<span class="p">}</span></pre></div>
+ </td>
+ </tr>
+ </table>
+</div>
+</body>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html;charset=utf-8">
+ <title>file.pp</title>
+ <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
+</head>
+<body>
+<div id='container'>
+ <div id="background"></div>
+ <div id="jump_to">
+ Jump To …
+ <div id="jump_wrapper">
+ <div id="jump_page">
+ <a class="source" href="deploy.html">deploy.pp</a>
+ <a class="source" href="extract.html">extract.pp</a>
+ <a class="source" href="file.html">file.pp</a>
+ <a class="source" href="init.html">init.pp</a>
+ </div>
+ </div>
+ </div>
+ <table cellspacing=0 cellpadding=0>
+ <thead>
+ <tr>
+ <th class=docs><h1>file.pp</h1></th>
+ <th class=code></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr id='section-Define:_staging::file'>
+ <td class=docs>
+ <div class="pilwrap">
+ <a class="pilcrow" href="#section-Define:_staging::file">¶</a>
+ </div>
+ <h3>Define: staging::file</h3>
+
+<h4>Overview:</h4>
+
+<p>Define resource to retrieve files to staging directories. It is
+intententionally not replacing files, as these intend to be large binaries
+that are versioned.</p>
+
+<h4>Notes:</h4>
+
+<p> If you specify a different staging location, please manage the file
+ resource as necessary.</p>
+
+<h3>Parameters:</h3>
+
+<ul>
+<li>[<em>source</em>]: the source file location, supports local files, puppet://, http://, https://, ftp:// (default: )</li>
+<li>[<em>target</em>]: the target staging directory, if unspecified ${staging::path}/${caller_module_name} (default: undef)</li>
+<li>[<em>username</em>]: https or ftp username (default: undef)</li>
+<li>[<em>certificate</em>]: https certificate file (default: undef)</li>
+<li>[<em>password</em>]: https or ftp user password or https certificate password (default: undef)</li>
+<li>[<em>environment</em>]: environment variable for settings such as http_proxy, https_proxy, of ftp_proxy (default: undef)</li>
+<li>[<em>timeout</em>]: the the time to wait for the file transfer to complete (default: undef)</li>
+<li>[<em>subdir</em>]: (default: $caller_module_name)</li>
+</ul>
+
+
+<h3>Usage:</h3>
+
+<pre><code>$caller_module_name = 'demo'
+
+class { 'staging':
+ path => '/tmp/staging',
+}
+
+staging::file { 'sample':
+ source => 'puppet:///modules/staging/sample',
+}
+
+staging::file { 'passwd':
+ source => '/etc/passwd',
+}
+
+staging::file { 'manpage.html':
+ source => 'http://curl.haxx.se/docs/manpage.html',
+}
+</code></pre>
+
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">define</span> <span class="n">staging</span><span class="o">::</span><span class="n">file</span> <span class="p">(</span>
+ <span class="vg">$source</span><span class="p">,</span>
+ <span class="vg">$target</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$username</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$certificate</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$password</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$environment</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$timeout</span> <span class="o">=</span> <span class="k">undef</span><span class="p">,</span>
+ <span class="vg">$subdir</span> <span class="o">=</span> <span class="vg">$caller_module_name</span>
+<span class="p">)</span> <span class="p">{</span>
+
+ <span class="kp">include</span> <span class="n">staging</span>
+
+ <span class="k">if</span> <span class="vg">$target</span> <span class="p">{</span>
+ <span class="vg">$target_file</span> <span class="o">=</span> <span class="vg">$target</span>
+ <span class="vg">$staging_dir</span> <span class="o">=</span> <span class="n">staging_parse</span><span class="p">(</span><span class="vg">$target</span><span class="p">,</span> <span class="s1">'parent'</span><span class="p">)</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="vg">$staging_dir</span> <span class="o">=</span> <span class="s2">"${staging::path}/${subdir}"</span>
+ <span class="vg">$target_file</span> <span class="o">=</span> <span class="s2">"${staging_dir}/${name}"</span>
+
+ <span class="k">if</span> <span class="o">!</span> <span class="n">defined</span><span class="p">(</span><span class="no">File</span><span class="o">[</span><span class="vg">$staging_dir</span><span class="o">]</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">file</span> <span class="p">{</span> <span class="vg">$staging_dir</span><span class="p">:</span>
+ <span class="k">ensure</span><span class="o">=></span><span class="n">directory</span><span class="p">,</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+
+ <span class="no">Exec</span> <span class="p">{</span>
+ <span class="n">path</span> <span class="o">=></span> <span class="s1">'/usr/local/bin:/usr/bin:/bin'</span><span class="p">,</span>
+ <span class="n">environment</span> <span class="o">=></span> <span class="vg">$environment</span><span class="p">,</span>
+ <span class="n">cwd</span> <span class="o">=></span> <span class="vg">$staging_dir</span><span class="p">,</span>
+ <span class="n">creates</span> <span class="o">=></span> <span class="vg">$target_file</span><span class="p">,</span>
+ <span class="n">timeout</span> <span class="o">=></span> <span class="vg">$timeout</span><span class="p">,</span>
+ <span class="n">logoutput</span> <span class="o">=></span> <span class="n">on_failure</span><span class="p">,</span>
+ <span class="p">}</span>
+
+ <span class="k">case</span> <span class="vg">$source</span> <span class="p">{</span>
+ <span class="sr">/^\//</span><span class="p">:</span> <span class="p">{</span>
+ <span class="n">file</span> <span class="p">{</span> <span class="vg">$target_file</span><span class="p">:</span>
+ <span class="n">source</span> <span class="o">=></span> <span class="vg">$source</span><span class="p">,</span>
+ <span class="n">replace</span> <span class="o">=></span> <span class="kp">false</span><span class="p">,</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+
+ <span class="sr">/^puppet:\/\//</span><span class="p">:</span> <span class="p">{</span>
+ <span class="n">file</span> <span class="p">{</span> <span class="vg">$target_file</span><span class="p">:</span>
+ <span class="n">source</span> <span class="o">=></span> <span class="vg">$source</span><span class="p">,</span>
+ <span class="n">replace</span> <span class="o">=></span> <span class="kp">false</span><span class="p">,</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+
+ <span class="sr">/^http:\/\//</span><span class="p">:</span> <span class="p">{</span>
+ <span class="nb">exec</span> <span class="p">{</span> <span class="vg">$target_file</span><span class="p">:</span>
+ <span class="n">command</span> <span class="o">=></span> <span class="s2">"curl -L -o ${name} ${source}"</span><span class="p">,</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+
+ <span class="sr">/^https:\/\//</span><span class="p">:</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="vg">$username</span> <span class="p">{</span>
+ <span class="vg">$command</span> <span class="o">=</span> <span class="s2">"curl -L -o ${name} -u ${username}:${password} ${source}"</span>
+ <span class="p">}</span> <span class="k">elsif</span> <span class="vg">$certificate</span> <span class="p">{</span>
+ <span class="vg">$command</span> <span class="o">=</span> <span class="s2">"curl -L -o ${name} -E ${certificate}:${password} ${source}"</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="vg">$command</span> <span class="o">=</span> <span class="s2">"curl -L -o ${name} ${source}"</span>
+ <span class="p">}</span>
+
+ <span class="nb">exec</span> <span class="p">{</span> <span class="vg">$target_file</span><span class="p">:</span>
+ <span class="n">command</span> <span class="o">=></span> <span class="vg">$command</span><span class="p">,</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+
+ <span class="sr">/^ftp:\/\//</span><span class="p">:</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="vg">$username</span> <span class="p">{</span>
+ <span class="vg">$command</span> <span class="o">=</span> <span class="s2">"curl -o ${name} -u ${username}:${password} ${source}"</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="vg">$command</span> <span class="o">=</span> <span class="s2">"curl -o ${name} ${source}"</span>
+ <span class="p">}</span>
+
+ <span class="nb">exec</span> <span class="p">{</span> <span class="vg">$target_file</span><span class="p">:</span>
+ <span class="n">command</span> <span class="o">=></span> <span class="vg">$command</span><span class="p">,</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+
+ <span class="n">default</span><span class="p">:</span> <span class="p">{</span>
+ <span class="nb">fail</span><span class="p">(</span><span class="s2">"stage::file: do not recognize source ${source}."</span><span class="p">)</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+
+<span class="p">}</span></pre></div>
+ </td>
+ </tr>
+ </table>
+</div>
+</body>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html;charset=utf-8">
+ <title>init.pp</title>
+ <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
+</head>
+<body>
+<div id='container'>
+ <div id="background"></div>
+ <div id="jump_to">
+ Jump To …
+ <div id="jump_wrapper">
+ <div id="jump_page">
+ <a class="source" href="deploy.html">deploy.pp</a>
+ <a class="source" href="extract.html">extract.pp</a>
+ <a class="source" href="file.html">file.pp</a>
+ <a class="source" href="init.html">init.pp</a>
+ </div>
+ </div>
+ </div>
+ <table cellspacing=0 cellpadding=0>
+ <thead>
+ <tr>
+ <th class=docs><h1>init.pp</h1></th>
+ <th class=code></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr id='section-Class:_staging'>
+ <td class=docs>
+ <div class="pilwrap">
+ <a class="pilcrow" href="#section-Class:_staging">¶</a>
+ </div>
+ <h3>Class: staging</h3>
+
+<p>This module manages staging and extraction of files from various sources.</p>
+
+<h4>Actions:</h4>
+
+<p>Creates the root staging directory. By default files will be created in a subdirectory matching the caller_module_name.</p>
+
+<p> /opt/staging/</p>
+
+<pre><code> |-- puppet
+ | `-- puppet.enterprise.2.0.tar.gz
+ `-- tomcat
+ `-- tomcat.5.0.tar.gz
+</code></pre>
+
+<h3>Parameters:</h3>
+
+<ul>
+<li>[<em>path</em>]: staging directory filepath (default: ‘/opt/staging’)</li>
+<li>[<em>owner</em>]: staging directory owner (default: ‘0’)</li>
+<li>[<em>group</em>]: staging directory group (default: ‘0’)</li>
+<li>[<em>mode</em>]: staging directory permission (default: ‘0755’)</li>
+</ul>
+
+
+<h3>Usage:</h3>
+
+<pre><code>include staging
+</code></pre>
+
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="k">class</span> <span class="n">staging</span> <span class="p">(</span>
+ <span class="vg">$path</span> <span class="o">=</span> <span class="s1">'/opt/staging'</span><span class="p">,</span>
+ <span class="vg">$owner</span> <span class="o">=</span> <span class="s1">'0'</span><span class="p">,</span>
+ <span class="vg">$group</span> <span class="o">=</span> <span class="s1">'0'</span><span class="p">,</span>
+ <span class="vg">$mode</span> <span class="o">=</span> <span class="s1">'0755'</span>
+<span class="p">)</span> <span class="p">{</span>
+
+ <span class="n">file</span> <span class="p">{</span> <span class="vg">$path</span><span class="p">:</span>
+ <span class="k">ensure</span> <span class="o">=></span> <span class="n">directory</span><span class="p">,</span>
+ <span class="n">owner</span> <span class="o">=></span> <span class="vg">$owner</span><span class="p">,</span>
+ <span class="n">group</span> <span class="o">=></span> <span class="vg">$group</span><span class="p">,</span>
+ <span class="n">mode</span> <span class="o">=></span> <span class="vg">$mode</span><span class="p">,</span>
+ <span class="p">}</span>
+
+<span class="p">}</span></pre></div>
+ </td>
+ </tr>
+ </table>
+</div>
+</body>
--- /dev/null
+sample file to test module.
--- /dev/null
+Facter.add("staging_http_get") do
+ setcode do
+
+ fact = nil
+
+ which = lambda do |cmd|
+ result = nil
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
+ exts.each do |ext|
+ exe = File.join(path, "#{cmd}#{ext}")
+ result = exe if File.executable? exe
+ break if result
+ end
+ break if result
+ end
+ result
+ end
+
+ ['powershell', 'curl', 'wget'].each do |cmd|
+ available = which.call(cmd)
+ fact = available ? cmd : nil
+ break if fact
+ end
+
+ fact
+
+ end
+end
--- /dev/null
+Facter.add(:staging_windir) do
+ confine :osfamily => :windows
+ setcode do
+ program_data = `echo %SYSTEMDRIVE%\\ProgramData`.chomp
+ if File.directory? program_data
+ "#{program_data}\\staging"
+ else
+ "C:\\staging"
+ end
+ end
+end
--- /dev/null
+module Puppet::Parser::Functions
+ newfunction(:scope_defaults, :type => :rvalue, :doc => <<-EOS
+Determine if specified resource defaults have a attribute defined in
+current scope.
+EOS
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "scope_defaults(): Wrong number of arguments " +
+ "given (#{arguments.size} for 2)") if arguments.size != 2
+
+ # auto capitalize puppet resource for lookup:
+ res_type = arguments[0].split('::').collect{ |x| x.capitalize }.join('::')
+ res_attr = arguments[1]
+
+ return self.lookupdefaults(res_type).has_key?(res_attr.to_sym)
+ end
+end
--- /dev/null
+require 'uri'
+
+module Puppet::Parser::Functions
+ newfunction(:staging_parse, :type => :rvalue, :doc => <<-EOS
+Parse filepath to retrieve information about the file.
+ EOS
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "staging_parse(): Wrong number of arguments " +
+ "given (#{arguments.size} for 1, 2, 3)") if arguments.size < 1 || arguments.size > 3
+
+ source = arguments[0]
+ path = URI.parse(source.gsub('\\', '/')).path
+
+ raise Puppet::ParseError, "staging_parse(): #{source.inspect} has no URI " +
+ "'path' component" if path.nil?
+
+ info = arguments[1] ? arguments[1] : 'filename'
+ extension = arguments[2] ? arguments[2] : File.extname(path)
+
+ case info
+ when 'filename'
+ result = File.basename(path)
+ when 'basename'
+ result = File.basename(path, extension)
+ when 'extname'
+ result = File.extname(path)
+ when 'parent'
+ result = File.expand_path(File.join(path, '..'))
+ else
+ raise Puppet::ParseError, "staging_parse(), unknown parse info #{info}."
+ end
+
+ return result
+ end
+end
--- /dev/null
+# The define resource extracts compressed file to a staging location.
+define staging::deploy (
+ $source, #: the source file location, supports local files, puppet://, http://, https://, ftp://
+ $target, #: the target extraction directory
+ $staging_path = undef, #: the staging location for compressed file. defaults to ${staging::path}/${caller_module_name}
+ $username = undef, #: https or ftp username
+ $certificate = undef, #: https certifcate file
+ $password = undef, #: https or ftp user password or https certificate password
+ $environment = undef, #: environment variable for settings such as http_proxy
+ $timeout = undef, #: the time to wait for the file transfer to complete
+ $user = undef, #: extract file as this user
+ $group = undef, #: extract group as this group
+ $creates = undef, #: the file/folder created after extraction. if unspecified defaults to ${target}/${name}
+ $unless = undef, #: alternative way to conditionally extract file
+ $onlyif = undef #: alternative way to conditionally extract file
+) {
+
+ staging::file { $name:
+ source => $source,
+ target => $staging_path,
+ username => $username,
+ certificate => $certificate,
+ password => $password,
+ environment => $environment,
+ subdir => $caller_module_name,
+ timeout => $timeout,
+ }
+
+ staging::extract { $name:
+ target => $target,
+ source => $staging_path,
+ user => $user,
+ group => $group,
+ environment => $environment,
+ subdir => $caller_module_name,
+ creates => $creates,
+ unless => $unless,
+ onlyif => $onlyif,
+ require => Staging::File[$name],
+ }
+
+}
--- /dev/null
+# Define resource to extract files from staging directories to target directories.
+define staging::extract (
+ $target, #: the target extraction directory
+ $source = undef, #: the source compression file, supports tar, tar.gz, zip, war
+ $creates = undef, #: the file created after extraction. if unspecified defaults ${staging::path}/${caller_module_name}/${name} ${target}/${name}
+ $unless = undef, #: alternative way to conditionally check whether to extract file.
+ $onlyif = undef, #: alternative way to conditionally check whether to extract file.
+ $user = undef, #: extract file as this user.
+ $group = undef, #: extract file as this group.
+ $environment = undef, #: environment variables.
+ $strip = undef, #: extract file with the --strip=X option. Only works with GNU tar.
+ $subdir = $caller_module_name #: subdir per module in staging directory.
+) {
+
+ include staging
+
+ if $source {
+ $source_path = $source
+ } else {
+ $source_path = "${staging::path}/${subdir}/${name}"
+ }
+
+ # Use user supplied creates path, set default value if creates, unless or
+ # onlyif is not supplied.
+ if $creates {
+ $creates_path = $creates
+ } elsif ! ($unless or $onlyif) {
+ if $name =~ /.tar.gz$/ {
+ $folder = staging_parse($name, 'basename', '.tar.gz')
+ } elsif $name =~ /.tar.bz2$/ {
+ $folder = staging_parse($name, 'basename', '.tar.bz2')
+ } else {
+ $folder = staging_parse($name, 'basename')
+ }
+ $creates_path = "${target}/${folder}"
+ } else {
+ $creates_path = undef
+ }
+
+ if scope_defaults('Exec','path') {
+ Exec{
+ cwd => $target,
+ user => $user,
+ group => $group,
+ environment => $environment,
+ creates => $creates_path,
+ unless => $unless,
+ onlyif => $onlyif,
+ logoutput => on_failure,
+ }
+ } else {
+ Exec{
+ path => $::path,
+ cwd => $target,
+ user => $user,
+ group => $group,
+ environment => $environment,
+ creates => $creates_path,
+ unless => $unless,
+ onlyif => $onlyif,
+ logoutput => on_failure,
+ }
+ }
+
+ if $strip {
+ if $::osfamily == 'Solaris' or $name !~ /(.tar|.tgz|.tar.gz|.tar.bz2)$/ {
+ warning('strip is only supported with GNU tar, ignoring the parameter')
+ $strip_opt = ''
+ } else {
+ $strip_opt = " --strip=${strip}"
+ }
+ } else {
+ $strip_opt = ''
+ }
+
+ case $name {
+ /.tar$/: {
+ $command = "tar xf ${source_path}${strip_opt}"
+ }
+
+ /(.tgz|.tar.gz)$/: {
+ if $::osfamily == 'Solaris' {
+ $command = "gunzip -dc < ${source_path} | tar xf - "
+ } else {
+ $command = "tar xzf ${source_path}${strip_opt}"
+ }
+ }
+
+ /.tar.bz2$/: {
+ $command = "tar xjf ${source_path}${strip_opt}"
+ }
+
+ /.zip$/: {
+ $command = "unzip ${source_path}"
+ }
+
+ /(.war|.jar)$/: {
+ $command = "jar xf ${source_path}"
+ }
+
+ default: {
+ fail("staging::extract: unsupported file format ${name}.")
+ }
+ }
+
+ exec { "extract ${name}":
+ command => $command,
+ }
+}
--- /dev/null
+# #### Overview:
+#
+# Define resource to retrieve files to staging directories. It is
+# intententionally not replacing files, as these intend to be large binaries
+# that are versioned.
+#
+# #### Notes:
+#
+# If you specify a different staging location, please manage the file
+# resource as necessary.
+#
+define staging::file (
+ $source, #: the source file location, supports local files, puppet://, http://, https://, ftp://, s3://
+ $target = undef, #: the target file location, if unspecified ${staging::path}/${subdir}/${name}
+ $username = undef, #: https or ftp username
+ $certificate = undef, #: https certificate file
+ $password = undef, #: https or ftp user password or https certificate password
+ $environment = undef, #: environment variable for settings such as http_proxy, https_proxy, of ftp_proxy
+ $timeout = undef, #: the the time to wait for the file transfer to complete
+ $curl_option = undef, #: options to pass to curl
+ $wget_option = undef, #: options to pass to wget
+ $tries = undef, #: amount of retries for the file transfer when non transient connection errors exist
+ $try_sleep = undef, #: time to wait between retries for the file transfer
+ $subdir = $caller_module_name
+) {
+
+ include staging
+
+ $quoted_source = shellquote($source)
+
+ if $target {
+ $target_file = $target
+ $staging_dir = staging_parse($target, 'parent')
+ } else {
+ $staging_dir = "${staging::path}/${subdir}"
+ $target_file = "${staging_dir}/${name}"
+
+ if ! defined(File[$staging_dir]) {
+ file { $staging_dir:
+ ensure=>directory,
+ }
+ }
+ }
+
+ Exec {
+ path => $staging::exec_path,
+ environment => $environment,
+ cwd => $staging_dir,
+ creates => $target_file,
+ timeout => $timeout,
+ try_sleep => $try_sleep,
+ tries => $tries,
+ logoutput => on_failure,
+ }
+
+ case $::staging_http_get {
+ 'curl', default: {
+ $http_get = "curl ${curl_option} -f -L -o ${target_file} ${quoted_source}"
+ $http_get_passwd = "curl ${curl_option} -f -L -o ${target_file} -u ${username}:${password} ${quoted_source}"
+ $http_get_cert = "curl ${curl_option} -f -L -o ${target_file} -E ${certificate}:${password} ${quoted_source}"
+ $ftp_get = "curl ${curl_option} -o ${target_file} ${quoted_source}"
+ $ftp_get_passwd = "curl ${curl_option} -o ${target_file} -u ${username}:${password} ${quoted_source}"
+ }
+ 'wget': {
+ $http_get = "wget ${wget_option} -O ${target_file} ${quoted_source}"
+ $http_get_passwd = "wget ${wget_option} -O ${target_file} --user=${username} --password=${password} ${quoted_source}"
+ $http_get_cert = "wget ${wget_option} -O ${target_file} --user=${username} --certificate=${certificate} ${quoted_source}"
+ $ftp_get = $http_get
+ $ftp_get_passwd = $http_get_passwd
+ }
+ 'powershell':{
+ $http_get = "powershell.exe -Command \"\$wc = New-Object System.Net.WebClient;\$wc.DownloadFile('${source}','${target_file}')\""
+ $ftp_get = $http_get
+ $http_get_password = "powershell.exe -Command \"\$wc = (New-Object System.Net.WebClient);\$wc.Credentials = New-Object System.Net.NetworkCredential('${username}','${password}');\$wc.DownloadFile(${source},${target_file})\""
+ $ftp_get_password = $http_get_password
+ }
+ }
+
+ case $source {
+ /^\//: {
+ file { $target_file:
+ source => $source,
+ replace => false,
+ }
+ }
+ /^puppet:\/\//: {
+ file { $target_file:
+ source => $source,
+ replace => false,
+ }
+ }
+ /^http:\/\//: {
+ if $username { $command = $http_get_passwd }
+ else { $command = $http_get }
+ exec { $target_file:
+ command => $command,
+ }
+ }
+ /^https:\/\//: {
+ if $username { $command = $http_get_passwd }
+ elsif $certificate { $command = $http_get_cert }
+ else { $command = $http_get }
+ exec { $target_file:
+ command => $command,
+ }
+ }
+ /^ftp:\/\//: {
+ if $username { $command = $ftp_get_passwd }
+ else { $command = $ftp_get }
+ exec { $target_file:
+ command => $command,
+ }
+ }
+ /^s3:\/\//: {
+ $command = "aws s3 cp ${source} ${target_file}"
+ exec { $target_file:
+ command => $command,
+ }
+ }
+ default: {
+ fail("staging::file: do not recognize source ${source}.")
+ }
+ }
+
+}
--- /dev/null
+# This module manages staging and extraction of files from various sources.
+#
+# #### Actions:
+#
+# Creates the root staging directory. By default files will be created in a subdirectory matching the caller_module_name.
+#
+# /opt/staging/
+# |-- puppet
+# | `-- puppet.enterprise.2.0.tar.gz
+# `-- tomcat
+# `-- tomcat.5.0.tar.gz
+#
+class staging (
+ $path = $staging::params::path, #: staging directory filepath
+ $owner = $staging::params::owner, #: staging directory owner
+ $group = $staging::params::group, #: staging directory group
+ $mode = $staging::params::mode, #: staging directory permission
+ $exec_path = $staging::params::exec_path #: executable default path
+) inherits staging::params {
+
+ # Resolve conflict with pe_staging
+ if !defined(File[$path]) {
+ file { $path:
+ ensure => directory,
+ owner => $owner,
+ group => $group,
+ mode => $mode,
+ }
+ }
+
+}
--- /dev/null
+# OS specific parameters
+class staging::params {
+ case $::osfamily {
+ default: {
+ $path = '/opt/staging'
+ $owner = '0'
+ $group = '0'
+ $mode = '0755'
+ $exec_path = '/usr/local/bin:/usr/bin:/bin'
+ }
+ 'Solaris': {
+ $path = '/opt/staging'
+ $owner = '0'
+ $group = '0'
+ $mode = '0755'
+ $exec_path = '/usr/local/bin:/usr/bin:/bin:/usr/sfw/bin'
+ }
+ 'windows': {
+ $path = $::staging_windir
+ $owner = 'S-1-5-32-544' # Adminstrators
+ $group = 'S-1-5-18' # SYSTEM
+ $mode = '0660'
+ $exec_path = $::path
+ }
+ 'FreeBSD': {
+ $path = '/var/tmp/staging'
+ $owner = '0'
+ $group = '0'
+ $mode = '0755'
+ $exec_path = '/usr/local/bin:/usr/bin:/bin'
+ }
+ }
+}
--- /dev/null
+{
+ "name": "nanliu-staging",
+ "version": "1.0.3",
+ "author": "Nan Liu",
+ "summary": "Compressed file staging and deployment",
+ "license": "Apache-2.0",
+ "source": "git://github.com/nanliu/puppet-staging",
+ "project_page": "https://github.com/nanliu/puppet-staging",
+ "issues_url": "https://github.com/nanliu/puppet-staging/issues",
+ "operatingsystem_support": [
+ {
+ "operatingsystem": "RedHat",
+ "operatingsystemrelease": [
+ "4",
+ "5",
+ "6"
+ ]
+ },
+ {
+ "operatingsystem": "CentOS",
+ "operatingsystemrelease": [
+ "4",
+ "5",
+ "6"
+ ]
+ },
+ {
+ "operatingsystem": "OracleLinux",
+ "operatingsystemrelease": [
+ "4",
+ "5",
+ "6"
+ ]
+ },
+ {
+ "operatingsystem": "Scientific",
+ "operatingsystemrelease": [
+ "4",
+ "5",
+ "6"
+ ]
+ },
+ {
+ "operatingsystem": "SLES",
+ "operatingsystemrelease": [
+ "11 SP1"
+ ]
+ },
+ {
+ "operatingsystem": "Debian",
+ "operatingsystemrelease": [
+ "6",
+ "7"
+ ]
+ },
+ {
+ "operatingsystem": "Ubuntu",
+ "operatingsystemrelease": [
+ "10.04",
+ "12.04"
+ ]
+ },
+ {
+ "operatingsystem": "Solaris",
+ "operatingsystemrelease": [
+ "10",
+ "11"
+ ]
+ },
+ {
+ "operatingsystem": "Windows",
+ "operatingsystemrelease": [
+ "Server 2003",
+ "Server 2003 R2",
+ "Server 2008",
+ "Server 2008 R2",
+ "Server 2012",
+ "Server 2012 R2",
+ "7",
+ "8"
+ ]
+ },
+ {
+ "operatingsystem": "AIX",
+ "operatingsystemrelease": [
+ "5.3",
+ "6.1",
+ "7.1"
+ ]
+ }
+ ],
+ "requirements": [
+ {
+ "name": "pe",
+ "version_requirement": "3.x"
+ },
+ {
+ "name": "puppet",
+ "version_requirement": ">=2.7.0 <4.0.0"
+ }
+ ],
+ "description": "Manages compressed file staging and deployment.",
+ "dependencies": [
+
+ ]
+}
--- /dev/null
+require 'spec_helper'
+describe 'staging::deploy', :type => :define do
+
+ # forcing a more sane caller_module_name to match real usage.
+ let(:facts) { { :caller_module_name => 'spec',
+ :osfamily => 'RedHat',
+ :staging_http_get => 'curl',
+ :path => '/usr/local/bin:/usr/bin:/bin', } }
+
+ describe 'when deploying tar.gz' do
+ let(:title) { 'sample.tar.gz' }
+ let(:params) { { :source => 'puppet:///modules/staging/sample.tar.gz',
+ :target => '/usr/local' } }
+
+ it {
+ should contain_file('/opt/staging')
+ should contain_file('/opt/staging/spec/sample.tar.gz')
+ should contain_exec('extract sample.tar.gz').with({
+ :command => 'tar xzf /opt/staging/spec/sample.tar.gz',
+ :path => '/usr/local/bin:/usr/bin:/bin',
+ :cwd => '/usr/local',
+ :creates => '/usr/local/sample'
+ })
+ }
+ end
+
+end
--- /dev/null
+require 'spec_helper'
+describe 'staging::extract', :type => :define do
+
+ # forcing a more sane caller_module_name to match real usage.
+ let(:facts) { { :caller_module_name => 'spec',
+ :osfamily => 'RedHat',
+ :path => '/usr/local/bin:/usr/bin:/bin' } }
+
+ describe 'when deploying tar.gz' do
+ let(:title) { 'sample.tar.gz' }
+ let(:params) { { :target => '/opt' } }
+
+ it {
+ should contain_file('/opt/staging')
+ should contain_exec('extract sample.tar.gz').with({
+ :command => 'tar xzf /opt/staging/spec/sample.tar.gz',
+ :path => '/usr/local/bin:/usr/bin:/bin',
+ :cwd => '/opt',
+ :creates => '/opt/sample'
+ })
+ }
+ end
+
+ describe 'when deploying tar.gz with strip' do
+ let(:title) { 'sample.tar.gz' }
+ let(:params) { { :target => '/opt',
+ :strip => 1, } }
+
+ it {
+ should contain_file('/opt/staging')
+ should contain_exec('extract sample.tar.gz').with({
+ :command => 'tar xzf /opt/staging/spec/sample.tar.gz --strip=1',
+ :path => '/usr/local/bin:/usr/bin:/bin',
+ :cwd => '/opt',
+ :creates => '/opt/sample'
+ })
+ }
+ end
+
+ describe 'when deploying zip' do
+ let(:title) { 'sample.zip' }
+ let(:params) { { :target => '/opt' } }
+
+ it { should contain_file('/opt/staging')
+ should contain_exec('extract sample.zip').with({
+ :command => 'unzip /opt/staging/spec/sample.zip',
+ :path => '/usr/local/bin:/usr/bin:/bin',
+ :cwd => '/opt',
+ :creates => '/opt/sample'
+ })
+ }
+ end
+
+ describe 'when deploying zip with strip (noop)' do
+ let(:title) { 'sample.zip' }
+ let(:params) { { :target => '/opt',
+ :strip => 1, } }
+
+ it { should contain_file('/opt/staging')
+ should contain_exec('extract sample.zip').with({
+ :command => 'unzip /opt/staging/spec/sample.zip',
+ :path => '/usr/local/bin:/usr/bin:/bin',
+ :cwd => '/opt',
+ :creates => '/opt/sample'
+ })
+ }
+ end
+
+ describe 'when deploying war' do
+ let(:title) { 'sample.war' }
+ let(:params) { { :target => '/opt' } }
+
+ it { should contain_file('/opt/staging')
+ should contain_exec('extract sample.war').with({
+ :command => 'jar xf /opt/staging/spec/sample.war',
+ :path => '/usr/local/bin:/usr/bin:/bin',
+ :cwd => '/opt',
+ :creates => '/opt/sample'
+ })
+ }
+ end
+
+ describe 'when deploying war with strip (noop)' do
+ let(:title) { 'sample.war' }
+ let(:params) { { :target => '/opt',
+ :strip => 1, } }
+
+ it { should contain_file('/opt/staging')
+ should contain_exec('extract sample.war').with({
+ :command => 'jar xf /opt/staging/spec/sample.war',
+ :path => '/usr/local/bin:/usr/bin:/bin',
+ :cwd => '/opt',
+ :creates => '/opt/sample'
+ })
+ }
+ end
+
+ describe 'when deploying unknown' do
+ let(:title) { 'sample.zzz'}
+ let(:params) { { :target => '/opt' } }
+
+ it { expect { should contain_exec("exec sample.zzz") }.to raise_error(Puppet::Error) }
+ end
+end
--- /dev/null
+require 'spec_helper'
+describe 'staging::file', :type => :define do
+
+ # forcing a more sane caller_module_name to match real usage.
+ let(:facts) { { :caller_module_name => 'spec',
+ :osfamily => 'RedHat',
+ :staging_http_get => 'curl' } }
+
+ describe 'when deploying via puppet' do
+ let(:title) { 'sample.tar.gz' }
+ let(:params) { { :source => 'puppet:///modules/staging/sample.tar.gz' } }
+
+ it {
+ should contain_file('/opt/staging')
+ should contain_file('/opt/staging/spec/sample.tar.gz')
+ should_not contain_exec('/opt/staging/spec/sample.tar.gz')
+ }
+ end
+
+ describe 'when deploying via local' do
+ let(:title) { 'sample.tar.gz' }
+ let(:params) { { :source => '/nfs/sample.tar.gz',
+ :target => '/usr/local/sample.tar.gz',
+ } }
+
+ it {
+ should contain_file('/opt/staging')
+ should contain_file('/usr/local/sample.tar.gz')
+ should_not contain_exec('/opt/staging/spec/sample.tar.gz')
+ }
+ end
+
+ describe 'when deploying via http' do
+ let(:title) { 'sample.tar.gz' }
+ let(:params) { { :source => 'http://webserver/sample.tar.gz' } }
+
+ it {
+ should contain_file('/opt/staging')
+ should contain_exec('/opt/staging/spec/sample.tar.gz').with( {
+ :command => 'curl -f -L -o /opt/staging/spec/sample.tar.gz http://webserver/sample.tar.gz',
+ :path => '/usr/local/bin:/usr/bin:/bin',
+ :environment => nil,
+ :cwd => '/opt/staging/spec',
+ :creates => '/opt/staging/spec/sample.tar.gz',
+ :logoutput => 'on_failure',
+ })
+ }
+ end
+
+ describe 'when deploying via http with custom curl options' do
+ let(:title) { 'sample.tar.gz' }
+ let(:params) { {
+ :source => 'http://webserver/sample.tar.gz',
+ :curl_option => '-b',
+ } }
+
+ it {
+ should contain_file('/opt/staging')
+ should contain_exec('/opt/staging/spec/sample.tar.gz').with( {
+ :command => 'curl -b -f -L -o /opt/staging/spec/sample.tar.gz http://webserver/sample.tar.gz',
+ :path => '/usr/local/bin:/usr/bin:/bin',
+ :environment => nil,
+ :cwd => '/opt/staging/spec',
+ :creates => '/opt/staging/spec/sample.tar.gz',
+ :logoutput => 'on_failure',
+ })
+ }
+ end
+
+ describe 'when deploying via http with parameters' do
+ let(:title) { 'sample.tar.gz' }
+ let(:params) { { :source => 'http://webserver/sample.tar.gz',
+ :target => '/usr/local/sample.tar.gz',
+ :tries => '10',
+ :try_sleep => '6',
+ } }
+
+ it { should contain_file('/opt/staging')
+ should contain_exec('/usr/local/sample.tar.gz').with( {
+ :command => 'curl -f -L -o /usr/local/sample.tar.gz http://webserver/sample.tar.gz',
+ :path => '/usr/local/bin:/usr/bin:/bin',
+ :environment => nil,
+ :cwd => '/usr/local',
+ :creates => '/usr/local/sample.tar.gz',
+ :tries => '10',
+ :try_sleep => '6',
+ })
+ }
+ end
+
+ describe 'when deploying via https' do
+ let(:title) { 'sample.tar.gz' }
+ let(:params) { { :source => 'https://webserver/sample.tar.gz' } }
+
+ it { should contain_file('/opt/staging') }
+ it { should contain_exec('/opt/staging/spec/sample.tar.gz').with( {
+ :command => 'curl -f -L -o /opt/staging/spec/sample.tar.gz https://webserver/sample.tar.gz',
+ :path => '/usr/local/bin:/usr/bin:/bin',
+ :environment => nil,
+ :cwd => '/opt/staging/spec',
+ :creates => '/opt/staging/spec/sample.tar.gz',
+ :logoutput => 'on_failure',
+ }) }
+ end
+
+ describe 'when deploying via https with parameters' do
+ let(:title) { 'sample.tar.gz' }
+ let(:params) { { :source => 'https://webserver/sample.tar.gz',
+ :username => 'puppet',
+ :password => 'puppet',
+ } }
+
+ it {
+ should contain_file('/opt/staging')
+ should contain_exec('/opt/staging/spec/sample.tar.gz').with( {
+ :command => 'curl -f -L -o /opt/staging/spec/sample.tar.gz -u puppet:puppet https://webserver/sample.tar.gz',
+ :path => '/usr/local/bin:/usr/bin:/bin',
+ :environment => nil,
+ :cwd => '/opt/staging/spec',
+ :creates => '/opt/staging/spec/sample.tar.gz',
+ :logoutput => 'on_failure',
+ })
+ }
+ end
+
+ describe 'when deploying via ftp' do
+ let(:title) { 'sample.tar.gz' }
+ let(:params) { { :source => 'ftp://webserver/sample.tar.gz' } }
+
+ it {
+ should contain_file('/opt/staging')
+ should contain_exec('/opt/staging/spec/sample.tar.gz').with( {
+ :command => 'curl -o /opt/staging/spec/sample.tar.gz ftp://webserver/sample.tar.gz',
+ :path => '/usr/local/bin:/usr/bin:/bin',
+ :environment => nil,
+ :cwd => '/opt/staging/spec',
+ :creates => '/opt/staging/spec/sample.tar.gz',
+ :logoutput => 'on_failure',
+ })
+ }
+ end
+
+ describe 'when deploying via ftp with parameters' do
+ let(:title) { 'sample.tar.gz' }
+ let(:params) { { :source => 'ftp://webserver/sample.tar.gz',
+ :username => 'puppet',
+ :password => 'puppet',
+ } }
+
+ it {
+ should contain_file('/opt/staging')
+ should contain_exec('/opt/staging/spec/sample.tar.gz').with( {
+ :command => 'curl -o /opt/staging/spec/sample.tar.gz -u puppet:puppet ftp://webserver/sample.tar.gz',
+ :path => '/usr/local/bin:/usr/bin:/bin',
+ :environment => nil,
+ :cwd => '/opt/staging/spec',
+ :creates => '/opt/staging/spec/sample.tar.gz',
+ :logoutput => 'on_failure',
+ })
+ }
+ end
+
+end
--- /dev/null
+require 'rubygems'
+require 'puppetlabs_spec_helper/module_spec_helper'
+
+RSpec.configure do |c|
+ c.include PuppetlabsSpec::Files
+
+ c.before :each do
+ # Ensure that we don't accidentally cache facts and environment
+ # between test cases.
+ Facter::Util::Loader.any_instance.stubs(:load_all)
+ Facter.clear
+ Facter.clear_messages
+
+ # Store any environment variables away to be restored later
+ @old_env = {}
+ ENV.each_key {|k| @old_env[k] = ENV[k]}
+
+ if Gem::Version.new(`puppet --version`) >= Gem::Version.new('3.5')
+ Puppet.settings[:strict_variables]=true
+ end
+ if ENV['PARSER']
+ Puppet.settings[:parser]=ENV['PARSER']
+ end
+ end
+
+ c.after :each do
+ PuppetlabsSpec::Files.cleanup
+ end
+end
--- /dev/null
+#!/usr/bin/env rspec
+require 'spec_helper'
+
+describe "the scope_defaults function" do
+ let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
+
+ it "should exist" do
+ Puppet::Parser::Functions.function("scope_defaults").should == "function_scope_defaults"
+ end
+
+ it "should raise a ParseError if there is less than 2 arguments" do
+ expect{ scope.function_scope_defaults([]) }.
+ to raise_error(Puppet::ParseError)
+ end
+
+ it "should raise a ParseError if there is more than 2 arguments" do
+ expect{ scope.function_scope_defaults(['exec', 'path', 'error']) }.
+ to raise_error(Puppet::ParseError)
+ end
+
+ it "should return false for invalid resource" do
+ result = scope.function_scope_defaults(['foo', 'path'])
+ result.should(eq(false))
+ end
+
+ it "should return false for resource without default attributes" do
+ if scope.respond_to? :define_settings
+ scope.define_settings('Exec', Puppet::Parser::Resource::Param.new(:name => :path, :value => "/bin"))
+ else
+ scope.setdefaults('Exec', Puppet::Parser::Resource::Param.new(:name => :path, :value => "/bin"))
+ end
+ result = scope.function_scope_defaults(['Exec', 'foo'])
+ result.should(eq(false))
+ end
+
+ it "should return true for resource with default attributes" do
+ if scope.respond_to? :define_settings
+ scope.define_settings('Exec', Puppet::Parser::Resource::Param.new(:name => :path, :value => "/bin"))
+ else
+ scope.setdefaults('Exec', Puppet::Parser::Resource::Param.new(:name => :path, :value => "/bin"))
+ end
+ result = scope.function_scope_defaults(['Exec', 'path'])
+ result.should(eq(true))
+ end
+end
--- /dev/null
+#!/usr/bin/env rspec
+require 'spec_helper'
+
+describe "the staging parser function" do
+ let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
+
+ it "should exist" do
+ Puppet::Parser::Functions.function("staging_parse").should == "function_staging_parse"
+ end
+
+ it "should raise a ParseError if there is less than 1 arguments" do
+ lambda { scope.function_staging_parse([]) }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should raise a ParseError if there is more than 3 arguments" do
+ lambda { scope.function_staging_parse(['/etc', 'filename', '.zip', 'error']) }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should raise a ParseError if there is an invalid info request" do
+ lambda { scope.function_staging_parse(['/etc', 'sheep', '.zip']) }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should raise a ParseError if 'source' doesn't have a URI path component" do
+ lambda { scope.function_staging_parse(['uri:without-path']) }.should( raise_error(Puppet::ParseError, /has no URI 'path' component/))
+ end
+
+ it "should return the filename by default" do
+ result = scope.function_staging_parse(["/etc/puppet/sample.tar.gz"])
+ result.should(eq('sample.tar.gz'))
+ end
+
+ it "should return the file basename" do
+ result = scope.function_staging_parse(["/etc/puppet/sample.tar.gz", "basename"])
+ result.should(eq('sample.tar'))
+ end
+
+ it "should return the file basename with custom extensions" do
+ result = scope.function_staging_parse(["/etc/puppet/sample.tar.gz", "basename", ".tar.gz"])
+ result.should(eq('sample'))
+ end
+
+ it "should return the file extname" do
+ result = scope.function_staging_parse(["/etc/puppet/sample.tar.gz", "extname"])
+ result.should(eq('.gz'))
+ end
+
+ it "should return the file parent" do
+ result = scope.function_staging_parse(["/etc/puppet/sample.tar.gz", "parent"])
+ result.should(eq('/etc/puppet'))
+ end
+end
--- /dev/null
+staging::deploy { 'sample.tar.gz':
+ source => 'puppet:///modules/staging/sample.tar.gz',
+ target => '/usr/local',
+}
--- /dev/null
+$caller_module_name = 'demo'
+
+class { 'staging':
+ path => '/tmp/staging',
+}
+
+staging::file { 'sample.tar.gz':
+ source => 'puppet:///modules/staging/sample.tar.gz'
+}
+
+staging::extract { 'sample.tar.gz':
+ target => '/tmp/staging',
+ creates => '/tmp/staging/sample',
+ require => Staging::File['sample.tar.gz'],
+}
+
+staging::file { 'sample.tar.bz2':
+ source => 'puppet:///modules/staging/sample.tar.bz2'
+}
+
+staging::extract { 'sample.tar.bz2':
+ target => '/tmp/staging',
+ creates => '/tmp/staging/sample-tar-bz2',
+ require => Staging::File['sample.tar.bz2'],
+}
--- /dev/null
+$caller_module_name = 'demo'
+
+class { 'staging':
+ path => '/tmp/staging',
+}
+
+staging::file { 'sample':
+ source => 'puppet:///modules/staging/sample',
+}
+
+staging::file { 'passwd':
+ source => '/etc/passwd',
+}
+
+staging::file { 'manpage.html':
+ source => 'http://curl.haxx.se/docs/manpage.html',
+}
--- /dev/null
+include staging
--- /dev/null
+Exec {
+ path => '/bin',
+}
+
+if scope_defaults('Exec', 'path') {
+ notice('good')
+}
--- /dev/null
+$file = '/etc/puppetlabs/foo.bar.tar.gz'
+$filename = staging_parse($file)
+$basename = staging_parse($file, 'basename')
+$extname = staging_parse($file, 'extname')
+$parent = staging_parse($file, 'parent')
+$rbasename = staging_parse($file, 'basename', '.tar.gz')
+
+notice($filename)
+notice($basename)
+notice($extname)
+notice($parent)
+notice($rbasename)