Added modules
This commit is contained in:
parent
c53c931217
commit
59ec520742
646 changed files with 35182 additions and 0 deletions
127
modules/concat/CHANGELOG
Normal file
127
modules/concat/CHANGELOG
Normal file
|
@ -0,0 +1,127 @@
|
|||
2014-05-14 1.1.0
|
||||
|
||||
Summary
|
||||
|
||||
This release is primarily a bugfix release since 1.1.0-rc1.
|
||||
|
||||
Features:
|
||||
- Improved testing, with tests moved to beaker
|
||||
|
||||
Bugfixes:
|
||||
- No longer attempts to set fragment owner and mode on Windows
|
||||
- Fix numeric sorting
|
||||
- Fix incorrect quoting
|
||||
- Fix newlines
|
||||
|
||||
2014-01-03 1.1.0-rc1
|
||||
|
||||
Summary:
|
||||
|
||||
This release of concat was 90% written by Joshua Hoblitt, and the module team
|
||||
would like to thank him for the huge amount of work he put into this release.
|
||||
|
||||
This module deprecates a bunch of old parameters and usage patterns, modernizes
|
||||
much of the manifest code, simplifies a whole bunch of logic and makes
|
||||
improvements to almost all parts of the module.
|
||||
|
||||
The other major feature is windows support, courtesy of luisfdez, with an
|
||||
alternative version of the concat bash script in ruby. We've attempted to
|
||||
ensure that there are no backwards incompatible changes, all users of 1.0.0
|
||||
should be able to use 1.1.0 without any failures, but you may find deprecation
|
||||
warnings and we'll be aggressively moving for a 2.0 to remove those too.
|
||||
|
||||
For further information on deprecations, please read:
|
||||
https://github.com/puppetlabs/puppetlabs-concat/blob/master/README.md#api-deprecations
|
||||
|
||||
Removed:
|
||||
- Puppet 0.24 support.
|
||||
- Filebucket backup of all file resources except the target concatenated file.
|
||||
- Default owner/user/group values.
|
||||
- Purging of long unused /usr/local/bin/concatfragments.sh
|
||||
|
||||
Features:
|
||||
- Windows support via a ruby version of the concat bash script.
|
||||
- Huge amount of acceptance testing work added.
|
||||
- Documentation (README) completely rewritten.
|
||||
- New parameters in concat:
|
||||
- `ensure`: Controls if the file should be present/absent at all.
|
||||
- Remove requirement to include concat::setup in manifests.
|
||||
- Made `gnu` parameter deprecated.
|
||||
- Added parameter validation.
|
||||
|
||||
Bugfixes:
|
||||
- Ensure concat::setup runs before concat::fragment in all cases.
|
||||
- Pluginsync references updated for modern Puppet.
|
||||
- Fix incorrect group parameter.
|
||||
- Use $owner instead of $id to avoid confusion with $::id
|
||||
- Compatibility fixes for Puppet 2.7/ruby 1.8.7
|
||||
- Use LC_ALL=C instead of LANG=C
|
||||
- Always exec the concatfragments script as root when running as root.
|
||||
- Syntax and other cleanup changes.
|
||||
|
||||
2013-08-09 1.0.0
|
||||
|
||||
Summary:
|
||||
|
||||
Many new features and bugfixes in this release, and if you're a heavy concat
|
||||
user you should test carefully before upgrading. The features should all be
|
||||
backwards compatible but only light testing has been done from our side before
|
||||
this release.
|
||||
|
||||
Features:
|
||||
- New parameters in concat:
|
||||
- `replace`: specify if concat should replace existing files.
|
||||
- `ensure_newline`: controls if fragments should contain a newline at the end.
|
||||
- Improved README documentation.
|
||||
- Add rspec:system tests (rake spec:system to test concat)
|
||||
|
||||
Bugfixes
|
||||
- Gracefully handle \n in a fragment resource name.
|
||||
- Adding more helpful message for 'pluginsync = true'
|
||||
- Allow passing `source` and `content` directly to file resource, rather than
|
||||
defining resource defaults.
|
||||
- Added -r flag to read so that filenames with \ will be read correctly.
|
||||
- sort always uses LANG=C.
|
||||
- Allow WARNMSG to contain/start with '#'.
|
||||
- Replace while-read pattern with for-do in order to support Solaris.
|
||||
|
||||
CHANGELOG:
|
||||
- 2010/02/19 - initial release
|
||||
- 2010/03/12 - add support for 0.24.8 and newer
|
||||
- make the location of sort configurable
|
||||
- add the ability to add shell comment based warnings to
|
||||
top of files
|
||||
- add the ablity to create empty files
|
||||
- 2010/04/05 - fix parsing of WARN and change code style to match rest
|
||||
of the code
|
||||
- Better and safer boolean handling for warn and force
|
||||
- Don't use hard coded paths in the shell script, set PATH
|
||||
top of the script
|
||||
- Use file{} to copy the result and make all fragments owned
|
||||
by root. This means we can chnage the ownership/group of the
|
||||
resulting file at any time.
|
||||
- You can specify ensure => "/some/other/file" in concat::fragment
|
||||
to include the contents of a symlink into the final file.
|
||||
- 2010/04/16 - Add more cleaning of the fragment name - removing / from the $name
|
||||
- 2010/05/22 - Improve documentation and show the use of ensure =>
|
||||
- 2010/07/14 - Add support for setting the filebucket behavior of files
|
||||
- 2010/10/04 - Make the warning message configurable
|
||||
- 2010/12/03 - Add flags to make concat work better on Solaris - thanks Jonathan Boyett
|
||||
- 2011/02/03 - Make the shell script more portable and add a config option for root group
|
||||
- 2011/06/21 - Make base dir root readable only for security
|
||||
- 2011/06/23 - Set base directory using a fact instead of hardcoding it
|
||||
- 2011/06/23 - Support operating as non privileged user
|
||||
- 2011/06/23 - Support dash instead of bash or sh
|
||||
- 2011/07/11 - Better solaris support
|
||||
- 2011/12/05 - Use fully qualified variables
|
||||
- 2011/12/13 - Improve Nexenta support
|
||||
- 2012/04/11 - Do not use any GNU specific extensions in the shell script
|
||||
- 2012/03/24 - Comply to community style guides
|
||||
- 2012/05/23 - Better errors when basedir isnt set
|
||||
- 2012/05/31 - Add spec tests
|
||||
- 2012/07/11 - Include concat::setup in concat improving UX
|
||||
- 2012/08/14 - Puppet Lint improvements
|
||||
- 2012/08/30 - The target path can be different from the $name
|
||||
- 2012/08/30 - More Puppet Lint cleanup
|
||||
- 2012/09/04 - RELEASE 0.2.0
|
||||
- 2012/12/12 - Added (file) $replace parameter to concat
|
20
modules/concat/Gemfile
Normal file
20
modules/concat/Gemfile
Normal file
|
@ -0,0 +1,20 @@
|
|||
source ENV['GEM_SOURCE'] || "https://rubygems.org"
|
||||
|
||||
group :development, :test do
|
||||
gem 'rake', :require => false
|
||||
gem 'rspec-puppet', :require => false
|
||||
gem 'puppetlabs_spec_helper', :require => false
|
||||
gem 'beaker', :require => false
|
||||
gem 'beaker-rspec', :require => false
|
||||
gem 'puppet-lint', :require => false
|
||||
gem 'serverspec', :require => false
|
||||
gem 'pry', :require => false
|
||||
end
|
||||
|
||||
if puppetversion = ENV['PUPPET_GEM_VERSION']
|
||||
gem 'puppet', puppetversion, :require => false
|
||||
else
|
||||
gem 'puppet', :require => false
|
||||
end
|
||||
|
||||
# vim:ft=ruby
|
14
modules/concat/LICENSE
Normal file
14
modules/concat/LICENSE
Normal file
|
@ -0,0 +1,14 @@
|
|||
Copyright 2012 R.I.Pienaar
|
||||
|
||||
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.
|
||||
|
9
modules/concat/Modulefile
Normal file
9
modules/concat/Modulefile
Normal file
|
@ -0,0 +1,9 @@
|
|||
name 'puppetlabs-concat'
|
||||
version '1.1.0'
|
||||
source 'git://github.com/puppetlabs/puppetlabs-concat.git'
|
||||
author 'Puppetlabs'
|
||||
license 'Apache 2.0'
|
||||
summary 'Concat module'
|
||||
description 'Concat module'
|
||||
project_page 'http://github.com/puppetlabs/puppetlabs-concat'
|
||||
dependency 'puppetlabs/stdlib', '>= 4.0.0'
|
441
modules/concat/README.md
Normal file
441
modules/concat/README.md
Normal file
|
@ -0,0 +1,441 @@
|
|||
#Concat
|
||||
|
||||
[](https://travis-ci.org/puppetlabs/puppetlabs-concat)
|
||||
|
||||
####Table of Contents
|
||||
|
||||
1. [Overview](#overview)
|
||||
2. [Module Description - What the module does and why it is useful](#module-description)
|
||||
3. [Setup - The basics of getting started with concat](#setup)
|
||||
* [What concat affects](#what-concat-affects)
|
||||
* [Setup requirements](#setup-requirements)
|
||||
* [Beginning with concat](#beginning-with-concat)
|
||||
4. [Usage - Configuration options and additional functionality](#usage)
|
||||
* [API _deprecations_](#api-deprecations)
|
||||
5. [Reference - An under-the-hood peek at what the module is doing and how](#reference)
|
||||
5. [Limitations - OS compatibility, etc.](#limitations)
|
||||
6. [Development - Guide for contributing to the module](#development)
|
||||
|
||||
##Overview
|
||||
|
||||
This module constructs files from multiple fragments in an ordered way.
|
||||
|
||||
##Module Description
|
||||
|
||||
This module lets you use many concat::fragment{} resources throughout
|
||||
your modules to construct a single file at the end. It does this through
|
||||
a shell (or ruby) script and a temporary holding space for the fragments.
|
||||
|
||||
##Setup
|
||||
|
||||
###What concat affects
|
||||
|
||||
* Installs concatfragments.[sh|rb] based on platform.
|
||||
* Adds a concat/ directory into Puppets `vardir`.
|
||||
|
||||
###Beginning with concat
|
||||
|
||||
To start using concat you need to create:
|
||||
|
||||
* A concat{} resource for the final file.
|
||||
* One or more concat::fragment{}'s.
|
||||
|
||||
A minimal example might be:
|
||||
|
||||
```puppet
|
||||
concat { '/tmp/file':
|
||||
ensure => present,
|
||||
}
|
||||
|
||||
concat::fragment { 'tmpfile':
|
||||
target => '/tmp/file'
|
||||
content => 'test contents',
|
||||
order => '01'
|
||||
}
|
||||
```
|
||||
|
||||
##Usage
|
||||
|
||||
Please be aware that there have been a number of [API
|
||||
_deprecations_](#api-deprecations).
|
||||
|
||||
If you wanted a /etc/motd file that listed all the major modules
|
||||
on the machine. And that would be maintained automatically even
|
||||
if you just remove the include lines for other modules you could
|
||||
use code like below, a sample /etc/motd would be:
|
||||
|
||||
<pre>
|
||||
Puppet modules on this server:
|
||||
|
||||
-- Apache
|
||||
-- MySQL
|
||||
</pre>
|
||||
|
||||
Local sysadmins can also append to the file by just editing /etc/motd.local
|
||||
their changes will be incorporated into the puppet managed motd.
|
||||
|
||||
```puppet
|
||||
class motd {
|
||||
$motd = '/etc/motd'
|
||||
|
||||
concat { $motd:
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644'
|
||||
}
|
||||
|
||||
concat::fragment{ 'motd_header':
|
||||
target => $motd,
|
||||
content => "\nPuppet modules on this server:\n\n",
|
||||
order => '01'
|
||||
}
|
||||
|
||||
# local users on the machine can append to motd by just creating
|
||||
# /etc/motd.local
|
||||
concat::fragment{ 'motd_local':
|
||||
target => $motd,
|
||||
source => '/etc/motd.local',
|
||||
order => '15'
|
||||
}
|
||||
}
|
||||
|
||||
# used by other modules to register themselves in the motd
|
||||
define motd::register($content="", $order=10) {
|
||||
if $content == "" {
|
||||
$body = $name
|
||||
} else {
|
||||
$body = $content
|
||||
}
|
||||
|
||||
concat::fragment{ "motd_fragment_$name":
|
||||
target => '/etc/motd',
|
||||
order => $order,
|
||||
content => " -- $body\n"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To use this you'd then do something like:
|
||||
|
||||
```puppet
|
||||
class apache {
|
||||
include apache::install, apache::config, apache::service
|
||||
|
||||
motd::register{ 'Apache': }
|
||||
}
|
||||
```
|
||||
|
||||
##Reference
|
||||
|
||||
###Classes
|
||||
|
||||
####Public classes
|
||||
|
||||
####Private classes
|
||||
* `concat::setup`: Sets up the concat script/directories.
|
||||
|
||||
###Parameters
|
||||
|
||||
###Defines
|
||||
|
||||
####concat
|
||||
|
||||
#####`ensure`
|
||||
Controls if the combined file is present or absent.
|
||||
|
||||
######Example
|
||||
- ensure => present
|
||||
- ensure => absent
|
||||
|
||||
#####`path`
|
||||
Controls the destination of the file to create.
|
||||
|
||||
######Example
|
||||
- path => '/tmp/filename'
|
||||
|
||||
#####`owner`
|
||||
Set the owner of the combined file.
|
||||
|
||||
######Example
|
||||
- owner => 'root'
|
||||
|
||||
#####`group`
|
||||
Set the group of the combined file.
|
||||
|
||||
######Example
|
||||
- group => 'root'
|
||||
|
||||
#####`mode`
|
||||
Set the mode of the combined file.
|
||||
|
||||
######Example
|
||||
- mode => '0644'
|
||||
|
||||
#####`warn`
|
||||
Determine if a warning message should be added at the top of the file to let
|
||||
users know it was autogenerated by Puppet.
|
||||
|
||||
######Example
|
||||
- warn => true
|
||||
- warn => false
|
||||
|
||||
#####`warn_message`
|
||||
Set the contents of the warning message.
|
||||
|
||||
######Example
|
||||
- warn_message => 'This file is autogenerated!'
|
||||
|
||||
#####`force`
|
||||
Determine if empty files are allowed when no fragments were added.
|
||||
|
||||
######Example
|
||||
- force => true
|
||||
- force => false
|
||||
|
||||
#####`backup`
|
||||
Controls the filebucket behavior used for the file.
|
||||
|
||||
######Example
|
||||
- backup => 'puppet'
|
||||
|
||||
#####`replace`
|
||||
Controls if Puppet should replace the destination file if it already exists.
|
||||
|
||||
######Example
|
||||
- replace => true
|
||||
- replace => false
|
||||
|
||||
#####`order`
|
||||
Controls the way in which the shell script chooses to sort the files. It's
|
||||
rare you'll need to adjust this.
|
||||
|
||||
######Allowed Values
|
||||
- order => 'alpha'
|
||||
- order => 'numeric'
|
||||
|
||||
#####`ensure_newline`
|
||||
Ensure there's a newline at the end of the fragments.
|
||||
|
||||
######Example
|
||||
- ensure_newline => true
|
||||
- ensure_newline => false
|
||||
|
||||
####concat::fragment
|
||||
|
||||
#####`target`
|
||||
Choose the destination file of the fragment.
|
||||
|
||||
######Example
|
||||
- target => '/tmp/testfile'
|
||||
|
||||
#####`content`
|
||||
Create the content of the fragment.
|
||||
|
||||
######Example
|
||||
- content => 'test file contents'
|
||||
|
||||
#####`source`
|
||||
Find the sources within Puppet of the fragment.
|
||||
|
||||
######Example
|
||||
- source => 'puppet:///modules/test/testfile'
|
||||
- source => ['puppet:///modules/test/1', 'puppet:///modules/test/2']
|
||||
|
||||
#####`order`
|
||||
Order the fragments.
|
||||
|
||||
######Example
|
||||
- order => '01'
|
||||
|
||||
#####`ensure`
|
||||
Control the file of fragment created.
|
||||
|
||||
######Example
|
||||
- ensure => 'present'
|
||||
- ensure => 'absent'
|
||||
- ensure => 'file'
|
||||
- ensure => 'directory'
|
||||
|
||||
#####`mode`
|
||||
Set the mode of the fragment.
|
||||
|
||||
######Example
|
||||
- mode => '0644'
|
||||
|
||||
#####`owner`
|
||||
Set the owner of the fragment.
|
||||
|
||||
######Example
|
||||
- owner => 'root'
|
||||
|
||||
#####`group`
|
||||
Set the group of the fragment.
|
||||
|
||||
######Example
|
||||
- group => 'root'
|
||||
|
||||
#####`backup`
|
||||
Control the filebucket behavior for the fragment.
|
||||
|
||||
######Example
|
||||
- backup => 'puppet'
|
||||
|
||||
### API _deprecations_
|
||||
|
||||
#### Since version `1.0.0`
|
||||
|
||||
##### `concat{}` `warn` parameter
|
||||
|
||||
```puppet
|
||||
concat { '/tmp/file':
|
||||
ensure => present,
|
||||
warn => 'true', # generates stringified boolean value warning
|
||||
}
|
||||
```
|
||||
|
||||
Using stringified Boolean values as the `warn` parameter to `concat` is
|
||||
deprecated, generates a catalog compile time warning, and will be silently
|
||||
treated as the concatenated file header/warning message in a future release.
|
||||
|
||||
The following strings are considered a stringified Boolean value:
|
||||
|
||||
* `'true'`
|
||||
* `'yes'`
|
||||
* `'on'`
|
||||
* `'false'`
|
||||
* `'no'`
|
||||
* `'off'`
|
||||
|
||||
Please migrate to using the Puppet DSL's native [Boolean data
|
||||
type](http://docs.puppetlabs.com/puppet/3/reference/lang_datatypes.html#booleans).
|
||||
|
||||
##### `concat{}` `gnu` parameter
|
||||
|
||||
```puppet
|
||||
concat { '/tmp/file':
|
||||
ensure => present,
|
||||
gnu => $foo, # generates deprecation warning
|
||||
}
|
||||
```
|
||||
|
||||
The `gnu` parameter to `concat` is deprecated, generates a catalog compile time
|
||||
warning, and has no effect. This parameter will be removed in a future
|
||||
release.
|
||||
|
||||
Note that this parameter was silently ignored in the `1.0.0` release.
|
||||
|
||||
##### `concat::fragment{}` `ensure` parameter
|
||||
|
||||
```puppet
|
||||
concat::fragment { 'cpuinfo':
|
||||
ensure => '/proc/cpuinfo', # generates deprecation warning
|
||||
target => '/tmp/file',
|
||||
}
|
||||
```
|
||||
|
||||
Passing a value other than `'present'` or `'absent'` as the `ensure` parameter
|
||||
to `concat::fragment` is deprecated and generates a catalog compile time
|
||||
warning. The warning will become a catalog compilation failure in a future
|
||||
release.
|
||||
|
||||
This type emulates the Puppet core `file` type's disfavored [`ensure`
|
||||
semantics](http://docs.puppetlabs.com/references/latest/type.html#file-attribute-ensure)
|
||||
of treating a file path as a directive to create a symlink. This feature is
|
||||
problematic in several ways. It copies an API semantic of another type that is
|
||||
both frowned upon and not generally well known. It's behavior may be
|
||||
surprising in that the target concatenated file will not be a symlink nor is
|
||||
there any common file system that has a concept of a section of a plain file
|
||||
being symbolically linked to another file. Additionally, the behavior is
|
||||
generally inconsistent with most Puppet types in that a missing source file
|
||||
will be silently ignored.
|
||||
|
||||
If you want to use the content of a file as a fragment please use the `source`
|
||||
parameter.
|
||||
|
||||
##### `concat::fragment{}` `mode/owner/group` parameters
|
||||
|
||||
```puppet
|
||||
concat::fragment { 'foo':
|
||||
target => '/tmp/file',
|
||||
content => 'foo',
|
||||
mode => $mode, # generates deprecation warning
|
||||
owner => $owner, # generates deprecation warning
|
||||
group => $group, # generates deprecation warning
|
||||
}
|
||||
```
|
||||
|
||||
The `mode` parameter to `concat::fragment` is deprecated, generates a catalog compile time warning, and has no effect.
|
||||
|
||||
The `owner` parameter to `concat::fragment` is deprecated, generates a catalog
|
||||
compile time warning, and has no effect.
|
||||
|
||||
The `group` parameter to `concat::fragment` is deprecated, generates a catalog
|
||||
compile time warning, and has no effect.
|
||||
|
||||
These parameters had no user visible effect in version `1.0.0` and will be
|
||||
removed in a future release.
|
||||
|
||||
##### `concat::fragment{}` `backup` parameter
|
||||
|
||||
```puppet
|
||||
concat::fragment { 'foo':
|
||||
target => '/tmp/file',
|
||||
content => 'foo',
|
||||
backup => 'bar', # generates deprecation warning
|
||||
}
|
||||
```
|
||||
|
||||
The `backup` parameter to `concat::fragment` is deprecated, generates a catalog
|
||||
compile time warning, and has no effect. It will be removed in a future
|
||||
release.
|
||||
|
||||
In the `1.0.0` release this parameter controlled file bucketing of the file
|
||||
fragment. Bucketting the fragment(s) is redundant with bucketting the final
|
||||
concatenated file and this feature has been removed.
|
||||
|
||||
##### `class { 'concat::setup': }`
|
||||
|
||||
```puppet
|
||||
include concat::setup # generates deprecation warning
|
||||
|
||||
class { 'concat::setup: } # generates deprecation warning
|
||||
```
|
||||
|
||||
The `concat::setup` class is deprecated as a public API of this module and
|
||||
should no longer be directly included in the manifest. This class may be
|
||||
removed in a future release.
|
||||
|
||||
##### Parameter validation
|
||||
|
||||
While not an API depreciation, users should be aware that all public parameters
|
||||
in this module are now validated for at least variable type. This may cause
|
||||
validation errors in a manifest that was previously silently misbehaving.
|
||||
|
||||
##Limitations
|
||||
|
||||
This module has been tested on:
|
||||
|
||||
* RedHat Enterprise Linux (and Centos) 5/6
|
||||
* Debian 6/7
|
||||
* Ubuntu 12.04
|
||||
|
||||
Testing on other platforms has been light and cannot be guaranteed.
|
||||
|
||||
#Development
|
||||
|
||||
Puppet Labs modules on the Puppet Forge are open projects, and community
|
||||
contributions are essential for keeping them great. We can’t access the
|
||||
huge number of platforms and myriad of hardware, software, and deployment
|
||||
configurations that Puppet is intended to serve.
|
||||
|
||||
We want to keep it as easy as possible to contribute changes so that our
|
||||
modules work in your environment. There are a few guidelines that we need
|
||||
contributors to follow so that we can have a chance of keeping on top of things.
|
||||
|
||||
You can read the complete module contribution guide [on the Puppet Labs wiki.](http://projects.puppetlabs.com/projects/module-site/wiki/Module_contributing)
|
||||
|
||||
###Contributors
|
||||
|
||||
The list of contributors can be found at:
|
||||
|
||||
https://github.com/puppetlabs/puppetlabs-concat/graphs/contributors
|
5
modules/concat/Rakefile
Normal file
5
modules/concat/Rakefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
require 'puppetlabs_spec_helper/rake_tasks'
|
||||
require 'puppet-lint/tasks/puppet-lint'
|
||||
|
||||
PuppetLint.configuration.send('disable_80chars')
|
||||
PuppetLint.configuration.send('disable_quoted_booleans')
|
137
modules/concat/files/concatfragments.rb
Executable file
137
modules/concat/files/concatfragments.rb
Executable file
|
@ -0,0 +1,137 @@
|
|||
# Script to concat files to a config file.
|
||||
#
|
||||
# Given a directory like this:
|
||||
# /path/to/conf.d
|
||||
# |-- fragments
|
||||
# | |-- 00_named.conf
|
||||
# | |-- 10_domain.net
|
||||
# | `-- zz_footer
|
||||
#
|
||||
# The script supports a test option that will build the concat file to a temp location and
|
||||
# use /usr/bin/cmp to verify if it should be run or not. This would result in the concat happening
|
||||
# twice on each run but gives you the option to have an unless option in your execs to inhibit rebuilds.
|
||||
#
|
||||
# Without the test option and the unless combo your services that depend on the final file would end up
|
||||
# restarting on each run, or in other manifest models some changes might get missed.
|
||||
#
|
||||
# OPTIONS:
|
||||
# -o The file to create from the sources
|
||||
# -d The directory where the fragments are kept
|
||||
# -t Test to find out if a build is needed, basically concats the files to a temp
|
||||
# location and compare with what's in the final location, return codes are designed
|
||||
# for use with unless on an exec resource
|
||||
# -w Add a shell style comment at the top of the created file to warn users that it
|
||||
# is generated by puppet
|
||||
# -f Enables the creation of empty output files when no fragments are found
|
||||
# -n Sort the output numerically rather than the default alpha sort
|
||||
#
|
||||
# the command:
|
||||
#
|
||||
# concatfragments.rb -o /path/to/conffile.cfg -d /path/to/conf.d
|
||||
#
|
||||
# creates /path/to/conf.d/fragments.concat and copies the resulting
|
||||
# file to /path/to/conffile.cfg. The files will be sorted alphabetically
|
||||
# pass the -n switch to sort numerically.
|
||||
#
|
||||
# The script does error checking on the various dirs and files to make
|
||||
# sure things don't fail.
|
||||
require 'optparse'
|
||||
require 'fileutils'
|
||||
|
||||
settings = {
|
||||
:outfile => "",
|
||||
:workdir => "",
|
||||
:test => false,
|
||||
:force => false,
|
||||
:warn => "",
|
||||
:sortarg => ""
|
||||
}
|
||||
|
||||
OptionParser.new do |opts|
|
||||
opts.banner = "Usage: #{$0} [options]"
|
||||
opts.separator "Specific options:"
|
||||
|
||||
opts.on("-o", "--outfile OUTFILE", String, "The file to create from the sources") do |o|
|
||||
settings[:outfile] = o
|
||||
end
|
||||
|
||||
opts.on("-d", "--workdir WORKDIR", String, "The directory where the fragments are kept") do |d|
|
||||
settings[:workdir] = d
|
||||
end
|
||||
|
||||
opts.on("-t", "--test", "Test to find out if a build is needed") do
|
||||
settings[:test] = true
|
||||
end
|
||||
|
||||
opts.separator "Other options:"
|
||||
opts.on("-w", "--warn WARNMSG", String,
|
||||
"Add a shell style comment at the top of the created file to warn users that it is generated by puppet") do |w|
|
||||
settings[:warn] = w
|
||||
end
|
||||
|
||||
opts.on("-f", "--force", "Enables the creation of empty output files when no fragments are found") do
|
||||
settings[:force] = true
|
||||
end
|
||||
|
||||
opts.on("-n", "--sort", "Sort the output numerically rather than the default alpha sort") do
|
||||
settings[:sortarg] = "-n"
|
||||
end
|
||||
end.parse!
|
||||
|
||||
# do we have -o?
|
||||
raise 'Please specify an output file with -o' unless !settings[:outfile].empty?
|
||||
|
||||
# do we have -d?
|
||||
raise 'Please specify fragments directory with -d' unless !settings[:workdir].empty?
|
||||
|
||||
# can we write to -o?
|
||||
if File.file?(settings[:outfile])
|
||||
if !File.writable?(settings[:outfile])
|
||||
raise "Cannot write to #{settings[:outfile]}"
|
||||
end
|
||||
else
|
||||
if !File.writable?(File.dirname(settings[:outfile]))
|
||||
raise "Cannot write to dirname #{File.dirname(settings[:outfile])} to create #{settings[:outfile]}"
|
||||
end
|
||||
end
|
||||
|
||||
# do we have a fragments subdir inside the work dir?
|
||||
if !File.directory?(File.join(settings[:workdir], "fragments")) && !File.executable?(File.join(settings[:workdir], "fragments"))
|
||||
raise "Cannot access the fragments directory"
|
||||
end
|
||||
|
||||
# are there actually any fragments?
|
||||
if (Dir.entries(File.join(settings[:workdir], "fragments")) - %w{ . .. }).empty?
|
||||
if !settings[:force]
|
||||
raise "The fragments directory is empty, cowardly refusing to make empty config files"
|
||||
end
|
||||
end
|
||||
|
||||
Dir.chdir(settings[:workdir])
|
||||
|
||||
if settings[:warn].empty?
|
||||
File.open("fragments.concat", 'w') {|f| f.write("") }
|
||||
else
|
||||
File.open("fragments.concat", 'w') {|f| f.write("#{settings[:warn]}\n") }
|
||||
end
|
||||
|
||||
# find all the files in the fragments directory, sort them numerically and concat to fragments.concat in the working dir
|
||||
open('fragments.concat', 'a') do |f|
|
||||
Dir.entries("fragments").sort.each{ |entry|
|
||||
if File.file?(File.join("fragments", entry))
|
||||
f << File.read(File.join("fragments", entry))
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
if !settings[:test]
|
||||
# This is a real run, copy the file to outfile
|
||||
FileUtils.cp 'fragments.concat', settings[:outfile]
|
||||
else
|
||||
# Just compare the result to outfile to help the exec decide
|
||||
if FileUtils.cmp 'fragments.concat', settings[:outfile]
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
end
|
||||
end
|
140
modules/concat/files/concatfragments.sh
Executable file
140
modules/concat/files/concatfragments.sh
Executable file
|
@ -0,0 +1,140 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Script to concat files to a config file.
|
||||
#
|
||||
# Given a directory like this:
|
||||
# /path/to/conf.d
|
||||
# |-- fragments
|
||||
# | |-- 00_named.conf
|
||||
# | |-- 10_domain.net
|
||||
# | `-- zz_footer
|
||||
#
|
||||
# The script supports a test option that will build the concat file to a temp location and
|
||||
# use /usr/bin/cmp to verify if it should be run or not. This would result in the concat happening
|
||||
# twice on each run but gives you the option to have an unless option in your execs to inhibit rebuilds.
|
||||
#
|
||||
# Without the test option and the unless combo your services that depend on the final file would end up
|
||||
# restarting on each run, or in other manifest models some changes might get missed.
|
||||
#
|
||||
# OPTIONS:
|
||||
# -o The file to create from the sources
|
||||
# -d The directory where the fragments are kept
|
||||
# -t Test to find out if a build is needed, basically concats the files to a temp
|
||||
# location and compare with what's in the final location, return codes are designed
|
||||
# for use with unless on an exec resource
|
||||
# -w Add a shell style comment at the top of the created file to warn users that it
|
||||
# is generated by puppet
|
||||
# -f Enables the creation of empty output files when no fragments are found
|
||||
# -n Sort the output numerically rather than the default alpha sort
|
||||
#
|
||||
# the command:
|
||||
#
|
||||
# concatfragments.sh -o /path/to/conffile.cfg -d /path/to/conf.d
|
||||
#
|
||||
# creates /path/to/conf.d/fragments.concat and copies the resulting
|
||||
# file to /path/to/conffile.cfg. The files will be sorted alphabetically
|
||||
# pass the -n switch to sort numerically.
|
||||
#
|
||||
# The script does error checking on the various dirs and files to make
|
||||
# sure things don't fail.
|
||||
|
||||
OUTFILE=""
|
||||
WORKDIR=""
|
||||
TEST=""
|
||||
FORCE=""
|
||||
WARN=""
|
||||
SORTARG=""
|
||||
ENSURE_NEWLINE=""
|
||||
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
|
||||
## Well, if there's ever a bad way to do things, Nexenta has it.
|
||||
## http://nexenta.org/projects/site/wiki/Personalities
|
||||
unset SUN_PERSONALITY
|
||||
|
||||
while getopts "o:s:d:tnw:fl" options; do
|
||||
case $options in
|
||||
o ) OUTFILE=$OPTARG;;
|
||||
d ) WORKDIR=$OPTARG;;
|
||||
n ) SORTARG="-n";;
|
||||
w ) WARNMSG="$OPTARG";;
|
||||
f ) FORCE="true";;
|
||||
t ) TEST="true";;
|
||||
l ) ENSURE_NEWLINE="true";;
|
||||
* ) echo "Specify output file with -o and fragments directory with -d"
|
||||
exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
# do we have -o?
|
||||
if [ "x${OUTFILE}" = "x" ]; then
|
||||
echo "Please specify an output file with -o"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# do we have -d?
|
||||
if [ "x${WORKDIR}" = "x" ]; then
|
||||
echo "Please fragments directory with -d"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# can we write to -o?
|
||||
if [ -f "${OUTFILE}" ]; then
|
||||
if [ ! -w "${OUTFILE}" ]; then
|
||||
echo "Cannot write to ${OUTFILE}"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if [ ! -w `dirname "${OUTFILE}"` ]; then
|
||||
echo "Cannot write to `dirname \"${OUTFILE}\"` to create ${OUTFILE}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# do we have a fragments subdir inside the work dir?
|
||||
if [ ! -d "${WORKDIR}/fragments" ] && [ ! -x "${WORKDIR}/fragments" ]; then
|
||||
echo "Cannot access the fragments directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# are there actually any fragments?
|
||||
if [ ! "$(ls -A """${WORKDIR}/fragments""")" ]; then
|
||||
if [ "x${FORCE}" = "x" ]; then
|
||||
echo "The fragments directory is empty, cowardly refusing to make empty config files"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
cd "${WORKDIR}"
|
||||
|
||||
if [ "x${WARNMSG}" = "x" ]; then
|
||||
: > "fragments.concat"
|
||||
else
|
||||
printf '%s\n' "$WARNMSG" > "fragments.concat"
|
||||
fi
|
||||
|
||||
# find all the files in the fragments directory, sort them numerically and concat to fragments.concat in the working dir
|
||||
IFS_BACKUP=$IFS
|
||||
IFS='
|
||||
'
|
||||
for fragfile in `find fragments/ -type f -follow -print0 | xargs -0 -n1 basename | LC_ALL=C sort ${SORTARG}`
|
||||
do
|
||||
cat "fragments/$fragfile" >> "fragments.concat"
|
||||
# Handle newlines.
|
||||
if [ "x${ENSURE_NEWLINE}" != "x" ]; then
|
||||
echo >> "fragments.concat"
|
||||
fi
|
||||
done
|
||||
IFS=$IFS_BACKUP
|
||||
|
||||
if [ "x${TEST}" = "x" ]; then
|
||||
# This is a real run, copy the file to outfile
|
||||
cp fragments.concat "${OUTFILE}"
|
||||
RETVAL=$?
|
||||
else
|
||||
# Just compare the result to outfile to help the exec decide
|
||||
cmp "${OUTFILE}" fragments.concat
|
||||
RETVAL=$?
|
||||
fi
|
||||
|
||||
exit $RETVAL
|
11
modules/concat/lib/facter/concat_basedir.rb
Normal file
11
modules/concat/lib/facter/concat_basedir.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
# == Fact: concat_basedir
|
||||
#
|
||||
# A custom fact that sets the default location for fragments
|
||||
#
|
||||
# "${::vardir}/concat/"
|
||||
#
|
||||
Facter.add("concat_basedir") do
|
||||
setcode do
|
||||
File.join(Puppet[:vardir],"concat")
|
||||
end
|
||||
end
|
121
modules/concat/manifests/fragment.pp
Normal file
121
modules/concat/manifests/fragment.pp
Normal file
|
@ -0,0 +1,121 @@
|
|||
# == Define: concat::fragment
|
||||
#
|
||||
# Puts a file fragment into a directory previous setup using concat
|
||||
#
|
||||
# === Options:
|
||||
#
|
||||
# [*target*]
|
||||
# The file that these fragments belong to
|
||||
# [*content*]
|
||||
# If present puts the content into the file
|
||||
# [*source*]
|
||||
# If content was not specified, use the source
|
||||
# [*order*]
|
||||
# By default all files gets a 10_ prefix in the directory you can set it to
|
||||
# anything else using this to influence the order of the content in the file
|
||||
# [*ensure*]
|
||||
# Present/Absent or destination to a file to include another file
|
||||
# [*mode*]
|
||||
# Deprecated
|
||||
# [*owner*]
|
||||
# Deprecated
|
||||
# [*group*]
|
||||
# Deprecated
|
||||
# [*backup*]
|
||||
# Deprecated
|
||||
#
|
||||
define concat::fragment(
|
||||
$target,
|
||||
$content = undef,
|
||||
$source = undef,
|
||||
$order = 10,
|
||||
$ensure = undef,
|
||||
$mode = undef,
|
||||
$owner = undef,
|
||||
$group = undef,
|
||||
$backup = undef
|
||||
) {
|
||||
validate_string($target)
|
||||
validate_string($content)
|
||||
if !(is_string($source) or is_array($source)) {
|
||||
fail('$source is not a string or an Array.')
|
||||
}
|
||||
validate_string($order)
|
||||
if $mode {
|
||||
warning('The $mode parameter to concat::fragment is deprecated and has no effect')
|
||||
}
|
||||
if $owner {
|
||||
warning('The $owner parameter to concat::fragment is deprecated and has no effect')
|
||||
}
|
||||
if $group {
|
||||
warning('The $group parameter to concat::fragment is deprecated and has no effect')
|
||||
}
|
||||
if $backup {
|
||||
warning('The $backup parameter to concat::fragment is deprecated and has no effect')
|
||||
}
|
||||
if $ensure == undef {
|
||||
$_ensure = getparam(Concat[$target], 'ensure')
|
||||
} else {
|
||||
if ! ($ensure in [ 'present', 'absent' ]) {
|
||||
warning('Passing a value other than \'present\' or \'absent\' as the $ensure parameter to concat::fragment is deprecated. If you want to use the content of a file as a fragment please use the $source parameter.')
|
||||
}
|
||||
$_ensure = $ensure
|
||||
}
|
||||
|
||||
include concat::setup
|
||||
|
||||
$safe_name = regsubst($name, '[/:\n]', '_', 'GM')
|
||||
$safe_target_name = regsubst($target, '[/:\n]', '_', 'GM')
|
||||
$concatdir = $concat::setup::concatdir
|
||||
$fragdir = "${concatdir}/${safe_target_name}"
|
||||
$fragowner = $concat::setup::fragment_owner
|
||||
$fragmode = $concat::setup::fragment_mode
|
||||
|
||||
# The file type's semantics are problematic in that ensure => present will
|
||||
# not over write a pre-existing symlink. We are attempting to provide
|
||||
# backwards compatiblity with previous concat::fragment versions that
|
||||
# supported the file type's ensure => /target syntax
|
||||
|
||||
# be paranoid and only allow the fragment's file resource's ensure param to
|
||||
# be file, absent, or a file target
|
||||
$safe_ensure = $_ensure ? {
|
||||
'' => 'file',
|
||||
undef => 'file',
|
||||
'file' => 'file',
|
||||
'present' => 'file',
|
||||
'absent' => 'absent',
|
||||
default => $_ensure,
|
||||
}
|
||||
|
||||
# if it looks line ensure => /target syntax was used, fish that out
|
||||
if ! ($_ensure in ['', 'present', 'absent', 'file' ]) {
|
||||
$ensure_target = $_ensure
|
||||
} else {
|
||||
$ensure_target = undef
|
||||
}
|
||||
|
||||
# the file type's semantics only allows one of: ensure => /target, content,
|
||||
# or source
|
||||
if ($ensure_target and $source) or
|
||||
($ensure_target and $content) or
|
||||
($source and $content) {
|
||||
fail('You cannot specify more than one of $content, $source, $ensure => /target')
|
||||
}
|
||||
|
||||
if ! ($content or $source or $ensure_target) {
|
||||
crit('No content, source or symlink specified')
|
||||
}
|
||||
|
||||
# punt on group ownership until some point in the distant future when $::gid
|
||||
# can be relied on to be present
|
||||
file { "${fragdir}/fragments/${order}_${safe_name}":
|
||||
ensure => $safe_ensure,
|
||||
owner => $fragowner,
|
||||
mode => $fragmode,
|
||||
source => $source,
|
||||
content => $content,
|
||||
backup => false,
|
||||
alias => "concat_fragment_${name}",
|
||||
notify => Exec["concat_${target}"]
|
||||
}
|
||||
}
|
232
modules/concat/manifests/init.pp
Normal file
232
modules/concat/manifests/init.pp
Normal file
|
@ -0,0 +1,232 @@
|
|||
# == Define: concat
|
||||
#
|
||||
# Sets up so that you can use fragments to build a final config file,
|
||||
#
|
||||
# === Options:
|
||||
#
|
||||
# [*ensure*]
|
||||
# Present/Absent
|
||||
# [*path*]
|
||||
# The path to the final file. Use this in case you want to differentiate
|
||||
# between the name of a resource and the file path. Note: Use the name you
|
||||
# provided in the target of your fragments.
|
||||
# [*owner*]
|
||||
# Who will own the file
|
||||
# [*group*]
|
||||
# Who will own the file
|
||||
# [*mode*]
|
||||
# The mode of the final file
|
||||
# [*force*]
|
||||
# Enables creating empty files if no fragments are present
|
||||
# [*warn*]
|
||||
# Adds a normal shell style comment top of the file indicating that it is
|
||||
# built by puppet
|
||||
# [*force*]
|
||||
# [*backup*]
|
||||
# Controls the filebucketing behavior of the final file and see File type
|
||||
# reference for its use. Defaults to 'puppet'
|
||||
# [*replace*]
|
||||
# Whether to replace a file that already exists on the local system
|
||||
# [*order*]
|
||||
# [*ensure_newline*]
|
||||
# [*gnu*]
|
||||
# Deprecated
|
||||
#
|
||||
# === Actions:
|
||||
# * Creates fragment directories if it didn't exist already
|
||||
# * Executes the concatfragments.sh script to build the final file, this
|
||||
# script will create directory/fragments.concat. Execution happens only
|
||||
# when:
|
||||
# * The directory changes
|
||||
# * fragments.concat != final destination, this means rebuilds will happen
|
||||
# whenever someone changes or deletes the final file. Checking is done
|
||||
# using /usr/bin/cmp.
|
||||
# * The Exec gets notified by something else - like the concat::fragment
|
||||
# define
|
||||
# * Copies the file over to the final destination using a file resource
|
||||
#
|
||||
# === Aliases:
|
||||
#
|
||||
# * The exec can notified using Exec["concat_/path/to/file"] or
|
||||
# Exec["concat_/path/to/directory"]
|
||||
# * The final file can be referenced as File["/path/to/file"] or
|
||||
# File["concat_/path/to/file"]
|
||||
#
|
||||
define concat(
|
||||
$ensure = 'present',
|
||||
$path = $name,
|
||||
$owner = undef,
|
||||
$group = undef,
|
||||
$mode = '0644',
|
||||
$warn = false,
|
||||
$force = false,
|
||||
$backup = 'puppet',
|
||||
$replace = true,
|
||||
$order = 'alpha',
|
||||
$ensure_newline = false,
|
||||
$gnu = undef
|
||||
) {
|
||||
validate_re($ensure, '^present$|^absent$')
|
||||
validate_absolute_path($path)
|
||||
validate_string($owner)
|
||||
validate_string($group)
|
||||
validate_string($mode)
|
||||
if ! (is_string($warn) or $warn == true or $warn == false) {
|
||||
fail('$warn is not a string or boolean')
|
||||
}
|
||||
validate_bool($force)
|
||||
validate_string($backup)
|
||||
validate_bool($replace)
|
||||
validate_re($order, '^alpha$|^numeric$')
|
||||
validate_bool($ensure_newline)
|
||||
if $gnu {
|
||||
warning('The $gnu parameter to concat is deprecated and has no effect')
|
||||
}
|
||||
|
||||
include concat::setup
|
||||
|
||||
$safe_name = regsubst($name, '[/:]', '_', 'G')
|
||||
$concatdir = $concat::setup::concatdir
|
||||
$fragdir = "${concatdir}/${safe_name}"
|
||||
$concat_name = 'fragments.concat.out'
|
||||
$script_command = $concat::setup::script_command
|
||||
$default_warn_message = '# This file is managed by Puppet. DO NOT EDIT.'
|
||||
$bool_warn_message = 'Using stringified boolean values (\'true\', \'yes\', \'on\', \'false\', \'no\', \'off\') to represent boolean true/false as the $warn parameter to concat is deprecated and will be treated as the warning message in a future release'
|
||||
|
||||
case $warn {
|
||||
true: {
|
||||
$warn_message = $default_warn_message
|
||||
}
|
||||
'true', 'yes', 'on': {
|
||||
warning($bool_warn_message)
|
||||
$warn_message = $default_warn_message
|
||||
}
|
||||
false: {
|
||||
$warn_message = ''
|
||||
}
|
||||
'false', 'no', 'off': {
|
||||
warning($bool_warn_message)
|
||||
$warn_message = ''
|
||||
}
|
||||
default: {
|
||||
$warn_message = $warn
|
||||
}
|
||||
}
|
||||
|
||||
$warnmsg_escaped = regsubst($warn_message, '\'', '\'\\\'\'', 'G')
|
||||
$warnflag = $warnmsg_escaped ? {
|
||||
'' => '',
|
||||
default => "-w '${warnmsg_escaped}'"
|
||||
}
|
||||
|
||||
$forceflag = $force ? {
|
||||
true => '-f',
|
||||
false => '',
|
||||
}
|
||||
|
||||
$orderflag = $order ? {
|
||||
'numeric' => '-n',
|
||||
'alpha' => '',
|
||||
}
|
||||
|
||||
$newlineflag = $ensure_newline ? {
|
||||
true => '-l',
|
||||
false => '',
|
||||
}
|
||||
|
||||
File {
|
||||
backup => false,
|
||||
}
|
||||
|
||||
if $ensure == 'present' {
|
||||
file { $fragdir:
|
||||
ensure => directory,
|
||||
mode => '0750',
|
||||
}
|
||||
|
||||
file { "${fragdir}/fragments":
|
||||
ensure => directory,
|
||||
mode => '0750',
|
||||
force => true,
|
||||
ignore => ['.svn', '.git', '.gitignore'],
|
||||
notify => Exec["concat_${name}"],
|
||||
purge => true,
|
||||
recurse => true,
|
||||
}
|
||||
|
||||
file { "${fragdir}/fragments.concat":
|
||||
ensure => present,
|
||||
mode => '0640',
|
||||
}
|
||||
|
||||
file { "${fragdir}/${concat_name}":
|
||||
ensure => present,
|
||||
mode => '0640',
|
||||
}
|
||||
|
||||
file { $name:
|
||||
ensure => present,
|
||||
owner => $owner,
|
||||
group => $group,
|
||||
mode => $mode,
|
||||
replace => $replace,
|
||||
path => $path,
|
||||
alias => "concat_${name}",
|
||||
source => "${fragdir}/${concat_name}",
|
||||
backup => $backup,
|
||||
}
|
||||
|
||||
# remove extra whitespace from string interpolation to make testing easier
|
||||
$command = strip(regsubst("${script_command} -o \"${fragdir}/${concat_name}\" -d \"${fragdir}\" ${warnflag} ${forceflag} ${orderflag} ${newlineflag}", '\s+', ' ', 'G'))
|
||||
|
||||
# if puppet is running as root, this exec should also run as root to allow
|
||||
# the concatfragments.sh script to potentially be installed in path that
|
||||
# may not be accessible by a target non-root owner.
|
||||
exec { "concat_${name}":
|
||||
alias => "concat_${fragdir}",
|
||||
command => $command,
|
||||
notify => File[$name],
|
||||
subscribe => File[$fragdir],
|
||||
unless => "${command} -t",
|
||||
path => $::path,
|
||||
require => [
|
||||
File[$fragdir],
|
||||
File["${fragdir}/fragments"],
|
||||
File["${fragdir}/fragments.concat"],
|
||||
],
|
||||
}
|
||||
} else {
|
||||
file { [
|
||||
$fragdir,
|
||||
"${fragdir}/fragments",
|
||||
"${fragdir}/fragments.concat",
|
||||
"${fragdir}/${concat_name}"
|
||||
]:
|
||||
ensure => absent,
|
||||
force => true,
|
||||
}
|
||||
|
||||
file { $path:
|
||||
ensure => absent,
|
||||
backup => $backup,
|
||||
}
|
||||
|
||||
$absent_exec_command = $::kernel ? {
|
||||
'windows' => 'cmd.exe /c exit 0',
|
||||
default => 'true',
|
||||
}
|
||||
|
||||
$absent_exec_path = $::kernel ? {
|
||||
'windows' => $::path,
|
||||
default => '/bin:/usr/bin',
|
||||
}
|
||||
|
||||
exec { "concat_${name}":
|
||||
alias => "concat_${fragdir}",
|
||||
command => $absent_exec_command,
|
||||
path => $absent_exec_path
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# vim:sw=2:ts=2:expandtab:textwidth=79
|
58
modules/concat/manifests/setup.pp
Normal file
58
modules/concat/manifests/setup.pp
Normal file
|
@ -0,0 +1,58 @@
|
|||
# === Class: concat::setup
|
||||
#
|
||||
# Sets up the concat system. This is a private class.
|
||||
#
|
||||
# [$concatdir]
|
||||
# is where the fragments live and is set on the fact concat_basedir.
|
||||
# Since puppet should always manage files in $concatdir and they should
|
||||
# not be deleted ever, /tmp is not an option.
|
||||
#
|
||||
# It also copies out the concatfragments.sh file to ${concatdir}/bin
|
||||
#
|
||||
class concat::setup {
|
||||
if $caller_module_name != $module_name {
|
||||
warning("${name} is deprecated as a public API of the ${module_name} module and should no longer be directly included in the manifest.")
|
||||
}
|
||||
|
||||
if $::concat_basedir {
|
||||
$concatdir = $::concat_basedir
|
||||
} else {
|
||||
fail ('$concat_basedir not defined. Try running again with pluginsync=true on the [master] and/or [main] section of your node\'s \'/etc/puppet/puppet.conf\'.')
|
||||
}
|
||||
|
||||
# owner and mode of fragment files (on windows owner and access rights should be inherited from concatdir and not explicitly set to avoid problems)
|
||||
$fragment_owner = $osfamily ? { 'windows' => undef, default => $::id }
|
||||
$fragment_mode = $osfamily ? { 'windows' => undef, default => '0640' }
|
||||
|
||||
$script_name = $::kernel ? {
|
||||
'windows' => 'concatfragments.rb',
|
||||
default => 'concatfragments.sh'
|
||||
}
|
||||
|
||||
$script_path = "${concatdir}/bin/${script_name}"
|
||||
|
||||
$script_owner = $osfamily ? { 'windows' => undef, default => $::id }
|
||||
|
||||
$script_mode = $osfamily ? { 'windows' => undef, default => '0755' }
|
||||
|
||||
$script_command = $::kernel ? {
|
||||
'windows' => "ruby.exe ${script_path}",
|
||||
default => $script_path
|
||||
}
|
||||
|
||||
File {
|
||||
backup => false,
|
||||
}
|
||||
|
||||
file { $script_path:
|
||||
ensure => file,
|
||||
owner => $script_owner,
|
||||
mode => $script_mode,
|
||||
source => "puppet:///modules/concat/${script_name}",
|
||||
}
|
||||
|
||||
file { [ $concatdir, "${concatdir}/bin" ]:
|
||||
ensure => directory,
|
||||
mode => '0755',
|
||||
}
|
||||
}
|
67
modules/concat/metadata.json
Normal file
67
modules/concat/metadata.json
Normal file
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"name": "puppetlabs-concat",
|
||||
"version": "1.1.0",
|
||||
"source": "git://github.com/puppetlabs/puppetlabs-concat.git",
|
||||
"author": "Puppetlabs",
|
||||
"license": "Apache 2.0",
|
||||
"summary": "Concat module",
|
||||
"description": "Concat module",
|
||||
"project_page": "http://github.com/puppetlabs/puppetlabs-concat",
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "puppetlabs/stdlib",
|
||||
"version_requirement": ">= 4.0.0"
|
||||
}
|
||||
],
|
||||
"types": [
|
||||
|
||||
],
|
||||
"checksums": {
|
||||
"CHANGELOG": "fca146b0dcd7cc60a9082b8e301a2e18",
|
||||
"Gemfile": "3cadf91e1baf9c8b7d2b1c3036676ba9",
|
||||
"LICENSE": "f5a76685d453424cd63dde1535811cf0",
|
||||
"Modulefile": "f8abb1236ed5211c4a3aa732431c2e19",
|
||||
"README.md": "adecb8db1313997083179540b20ede86",
|
||||
"Rakefile": "e415d40cd8db238f02bf4575d5e1e693",
|
||||
"files/concatfragments.rb": "6784c28044a4204efb75fe4eb759816a",
|
||||
"files/concatfragments.sh": "7bbe7c5fce25a5ddd20415d909ba44fc",
|
||||
"lib/facter/concat_basedir.rb": "ff080677e7f192b9b96911698b0b9b3d",
|
||||
"manifests/fragment.pp": "8bfd199e757f6a57f6174b558f87d2ce",
|
||||
"manifests/init.pp": "79c6dc5bf0b2b0da3ce84cc2f0ae5f02",
|
||||
"manifests/setup.pp": "0ff9f4d9b4c01360606ae29d8df31ff0",
|
||||
"spec/acceptance/backup_spec.rb": "d4ffdf3d4f5a1b7c0aa64dd118375124",
|
||||
"spec/acceptance/concat_spec.rb": "600243521241dac0b238ad01b10c7132",
|
||||
"spec/acceptance/deprecation_warnings_spec.rb": "40286704d0f544437293ed8a1cc66fe9",
|
||||
"spec/acceptance/empty_spec.rb": "c2edc5cef72870b0894e1b2184207325",
|
||||
"spec/acceptance/fragment_source_spec.rb": "c5cda233f208b71d7d5cc89dfa4be81d",
|
||||
"spec/acceptance/newline_spec.rb": "55b9f470bdff4c0245da6895c9b6e64d",
|
||||
"spec/acceptance/nodesets/aix-71-vcloud.yml": "de6cc5bf18be2be8d50e62503652cb32",
|
||||
"spec/acceptance/nodesets/centos-59-x64.yml": "57eb3e471b9042a8ea40978c467f8151",
|
||||
"spec/acceptance/nodesets/centos-64-x64-pe.yml": "ec075d95760df3d4702abea1ce0a829b",
|
||||
"spec/acceptance/nodesets/centos-64-x64.yml": "092dd2c588a9f87fa1fb12997c0723ef",
|
||||
"spec/acceptance/nodesets/debian-607-x64.yml": "d566bf76f534e2af7c9a4605316d232c",
|
||||
"spec/acceptance/nodesets/debian-70rc1-x64.yml": "31ccca73af7b74e1cc2fb0035c230b2c",
|
||||
"spec/acceptance/nodesets/debian-73-x64.yml": "bd3ea8245ce691c2b234529d62d043eb",
|
||||
"spec/acceptance/nodesets/default.yml": "3d68f9581097bb3a807ba1931c961959",
|
||||
"spec/acceptance/nodesets/fedora-18-x64.yml": "80e41b1ee16ea489f53164bfdae58855",
|
||||
"spec/acceptance/nodesets/rhel-7-x64.yml": "91b55d29f059e23383c7bc352b5d671d",
|
||||
"spec/acceptance/nodesets/sles-11-x64.yml": "44e4c6c15c018333bfa9840a5e702f66",
|
||||
"spec/acceptance/nodesets/sles-11sp1-x64.yml": "fa0046bd89c1ab4ba9521ad79db234cd",
|
||||
"spec/acceptance/nodesets/ubuntu-server-10044-x64.yml": "75e86400b7889888dc0781c0ae1a1297",
|
||||
"spec/acceptance/nodesets/ubuntu-server-12042-x64.yml": "d30d73e34cd50b043c7d14e305955269",
|
||||
"spec/acceptance/nodesets/ubuntu-server-1404-x64.yml": "5f0aed10098ac5b78e4217bb27c7aaf0",
|
||||
"spec/acceptance/order_spec.rb": "0de9b4993a3e3f6f36c52bb18f48280c",
|
||||
"spec/acceptance/quoted_paths_spec.rb": "953a5a665bd4bb468e70856260c47c6e",
|
||||
"spec/acceptance/replace_spec.rb": "7072d819d5997ad227fc17f4b813fe4f",
|
||||
"spec/acceptance/symbolic_name_spec.rb": "10e856a87253cf8bbef95f8f9635b63e",
|
||||
"spec/acceptance/warn_spec.rb": "ec03f0fa8086fc4be03da1c5aff25097",
|
||||
"spec/spec_helper.rb": "0db89c9a486df193c0e40095422e19dc",
|
||||
"spec/spec_helper_acceptance.rb": "5be78c42f01346abf097bbcab34ff424",
|
||||
"spec/unit/classes/concat_setup_spec.rb": "6d3729833715d65f3c50c2153caed6bc",
|
||||
"spec/unit/defines/concat_fragment_spec.rb": "ced7c3b1b6d7f2e65c6dc066aa8c0527",
|
||||
"spec/unit/defines/concat_spec.rb": "d8da592546c9811bf40e111bf52755dc",
|
||||
"spec/unit/facts/concat_basedir_spec.rb": "cf00f5a07948436fa0a84d00fc098539",
|
||||
"tests/fragment.pp": "9adc3d9ba61676066072e1b949a37dbb",
|
||||
"tests/init.pp": "bd3ce7d2ee146744b5dbbaae8a927043"
|
||||
}
|
||||
}
|
101
modules/concat/spec/acceptance/backup_spec.rb
Normal file
101
modules/concat/spec/acceptance/backup_spec.rb
Normal file
|
@ -0,0 +1,101 @@
|
|||
require 'spec_helper_acceptance'
|
||||
|
||||
describe 'concat backup parameter' do
|
||||
context '=> puppet' do
|
||||
before :all do
|
||||
shell('rm -rf /tmp/concat')
|
||||
shell('mkdir -p /tmp/concat')
|
||||
shell("/bin/echo 'old contents' > /tmp/concat/file")
|
||||
end
|
||||
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file':
|
||||
backup => 'puppet',
|
||||
}
|
||||
concat::fragment { 'new file':
|
||||
target => '/tmp/concat/file',
|
||||
content => 'new contents',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with "Filebucketed" stdout and no stderr' do
|
||||
apply_manifest(pp, :catch_failures => true) do |r|
|
||||
expect(r.stderr).to eq("")
|
||||
expect(r.stdout).to match(/Filebucketed \/tmp\/concat\/file to puppet with sum 0140c31db86293a1a1e080ce9b91305f/) # sum is for file contents of 'old contents'
|
||||
end
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should contain 'new contents' }
|
||||
end
|
||||
end
|
||||
|
||||
context '=> .backup' do
|
||||
before :all do
|
||||
shell('rm -rf /tmp/concat')
|
||||
shell('mkdir -p /tmp/concat')
|
||||
shell("/bin/echo 'old contents' > /tmp/concat/file")
|
||||
end
|
||||
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file':
|
||||
backup => '.backup',
|
||||
}
|
||||
concat::fragment { 'new file':
|
||||
target => '/tmp/concat/file',
|
||||
content => 'new contents',
|
||||
}
|
||||
EOS
|
||||
|
||||
# XXX Puppet doesn't mention anything about filebucketing with a given
|
||||
# extension like .backup
|
||||
it 'applies the manifest twice no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should contain 'new contents' }
|
||||
end
|
||||
describe file('/tmp/concat/file.backup') do
|
||||
it { should be_file }
|
||||
it { should contain 'old contents' }
|
||||
end
|
||||
end
|
||||
|
||||
# XXX The backup parameter uses validate_string() and thus can't be the
|
||||
# boolean false value, but the string 'false' has the same effect in Puppet 3
|
||||
context "=> 'false'" do
|
||||
before :all do
|
||||
shell('rm -rf /tmp/concat')
|
||||
shell('mkdir -p /tmp/concat')
|
||||
shell("/bin/echo 'old contents' > /tmp/concat/file")
|
||||
end
|
||||
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file':
|
||||
backup => '.backup',
|
||||
}
|
||||
concat::fragment { 'new file':
|
||||
target => '/tmp/concat/file',
|
||||
content => 'new contents',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no "Filebucketed" stdout and no stderr' do
|
||||
apply_manifest(pp, :catch_failures => true) do |r|
|
||||
expect(r.stderr).to eq("")
|
||||
expect(r.stdout).to_not match(/Filebucketed/)
|
||||
end
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should contain 'new contents' }
|
||||
end
|
||||
end
|
||||
end
|
204
modules/concat/spec/acceptance/concat_spec.rb
Normal file
204
modules/concat/spec/acceptance/concat_spec.rb
Normal file
|
@ -0,0 +1,204 @@
|
|||
require 'spec_helper_acceptance'
|
||||
|
||||
describe 'basic concat test' do
|
||||
|
||||
shared_examples 'successfully_applied' do |pp|
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file("#{default['puppetvardir']}/concat") do
|
||||
it { should be_directory }
|
||||
it { should be_owned_by 'root' }
|
||||
it { should be_grouped_into 'root' }
|
||||
it { should be_mode 755 }
|
||||
end
|
||||
describe file("#{default['puppetvardir']}/concat/bin") do
|
||||
it { should be_directory }
|
||||
it { should be_owned_by 'root' }
|
||||
it { should be_grouped_into 'root' }
|
||||
it { should be_mode 755 }
|
||||
end
|
||||
describe file("#{default['puppetvardir']}/concat/bin/concatfragments.sh") do
|
||||
it { should be_file }
|
||||
it { should be_owned_by 'root' }
|
||||
#it { should be_grouped_into 'root' }
|
||||
it { should be_mode 755 }
|
||||
end
|
||||
describe file("#{default['puppetvardir']}/concat/_tmp_concat_file") do
|
||||
it { should be_directory }
|
||||
it { should be_owned_by 'root' }
|
||||
it { should be_grouped_into 'root' }
|
||||
it { should be_mode 750 }
|
||||
end
|
||||
describe file("#{default['puppetvardir']}/concat/_tmp_concat_file/fragments") do
|
||||
it { should be_directory }
|
||||
it { should be_owned_by 'root' }
|
||||
it { should be_grouped_into 'root' }
|
||||
it { should be_mode 750 }
|
||||
end
|
||||
describe file("#{default['puppetvardir']}/concat/_tmp_concat_file/fragments.concat") do
|
||||
it { should be_file }
|
||||
it { should be_owned_by 'root' }
|
||||
it { should be_grouped_into 'root' }
|
||||
it { should be_mode 640 }
|
||||
end
|
||||
describe file("#{default['puppetvardir']}/concat/_tmp_concat_file/fragments.concat.out") do
|
||||
it { should be_file }
|
||||
it { should be_owned_by 'root' }
|
||||
it { should be_grouped_into 'root' }
|
||||
it { should be_mode 640 }
|
||||
end
|
||||
end
|
||||
|
||||
context 'owner/group root' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file':
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
}
|
||||
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/file',
|
||||
content => '1',
|
||||
order => '01',
|
||||
}
|
||||
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat/file',
|
||||
content => '2',
|
||||
order => '02',
|
||||
}
|
||||
EOS
|
||||
|
||||
it_behaves_like 'successfully_applied', pp
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should be_owned_by 'root' }
|
||||
it { should be_grouped_into 'root' }
|
||||
it { should be_mode 644 }
|
||||
it { should contain '1' }
|
||||
it { should contain '2' }
|
||||
end
|
||||
describe file("#{default['puppetvardir']}/concat/_tmp_concat_file/fragments/01_1") do
|
||||
it { should be_file }
|
||||
it { should be_owned_by 'root' }
|
||||
it { should be_grouped_into 'root' }
|
||||
it { should be_mode 640 }
|
||||
end
|
||||
describe file("#{default['puppetvardir']}/concat/_tmp_concat_file/fragments/02_2") do
|
||||
it { should be_file }
|
||||
it { should be_owned_by 'root' }
|
||||
it { should be_grouped_into 'root' }
|
||||
it { should be_mode 640 }
|
||||
end
|
||||
end
|
||||
|
||||
context 'owner/group non-root' do
|
||||
before(:all) do
|
||||
shell "groupadd -g 64444 bob"
|
||||
shell "useradd -u 42 -g 64444 bob"
|
||||
end
|
||||
after(:all) do
|
||||
shell "userdel bob"
|
||||
end
|
||||
|
||||
pp="
|
||||
concat { '/tmp/concat/file':
|
||||
owner => 'bob',
|
||||
group => 'bob',
|
||||
mode => '0644',
|
||||
}
|
||||
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/file',
|
||||
content => '1',
|
||||
order => '01',
|
||||
}
|
||||
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat/file',
|
||||
content => '2',
|
||||
order => '02',
|
||||
}
|
||||
"
|
||||
|
||||
it_behaves_like 'successfully_applied', pp
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should be_owned_by 'bob' }
|
||||
it { should be_grouped_into 'bob' }
|
||||
it { should be_mode 644 }
|
||||
it { should contain '1' }
|
||||
it { should contain '2' }
|
||||
end
|
||||
describe file("#{default['puppetvardir']}/concat/_tmp_concat_file/fragments/01_1") do
|
||||
it { should be_file }
|
||||
it { should be_owned_by 'root' }
|
||||
it { should be_grouped_into 'root' }
|
||||
it { should be_mode 640 }
|
||||
it { should contain '1' }
|
||||
end
|
||||
describe file("#{default['puppetvardir']}/concat/_tmp_concat_file/fragments/02_2") do
|
||||
it { should be_file }
|
||||
it { should be_owned_by 'root' }
|
||||
it { should be_grouped_into 'root' }
|
||||
it { should be_mode 640 }
|
||||
it { should contain '2' }
|
||||
end
|
||||
end
|
||||
|
||||
context 'ensure' do
|
||||
context 'works when set to present with path set' do
|
||||
pp="
|
||||
concat { 'file':
|
||||
ensure => present,
|
||||
path => '/tmp/concat/file',
|
||||
mode => '0644',
|
||||
}
|
||||
concat::fragment { '1':
|
||||
target => 'file',
|
||||
content => '1',
|
||||
order => '01',
|
||||
}
|
||||
"
|
||||
|
||||
it_behaves_like 'successfully_applied', pp
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should be_mode 644 }
|
||||
it { should contain '1' }
|
||||
end
|
||||
end
|
||||
context 'works when set to absent with path set' do
|
||||
pp="
|
||||
concat { 'file':
|
||||
ensure => absent,
|
||||
path => '/tmp/concat/file',
|
||||
mode => '0644',
|
||||
}
|
||||
concat::fragment { '1':
|
||||
target => 'file',
|
||||
content => '1',
|
||||
order => '01',
|
||||
}
|
||||
"
|
||||
|
||||
# Can't used shared examples as this will always trigger the exec when
|
||||
# absent is set.
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should_not be_file }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
230
modules/concat/spec/acceptance/deprecation_warnings_spec.rb
Normal file
230
modules/concat/spec/acceptance/deprecation_warnings_spec.rb
Normal file
|
@ -0,0 +1,230 @@
|
|||
require 'spec_helper_acceptance'
|
||||
|
||||
describe 'deprecation warnings' do
|
||||
|
||||
shared_examples 'has_warning'do |pp, w|
|
||||
it 'applies the manifest twice with a stderr regex' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to match(/#{Regexp.escape(w)}/m)
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to match(/#{Regexp.escape(w)}/m)
|
||||
end
|
||||
end
|
||||
|
||||
context 'concat gnu parameter' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file':
|
||||
gnu => 'foo',
|
||||
}
|
||||
concat::fragment { 'foo':
|
||||
target => '/tmp/concat/file',
|
||||
content => 'bar',
|
||||
}
|
||||
EOS
|
||||
w = 'The $gnu parameter to concat is deprecated and has no effect'
|
||||
|
||||
it_behaves_like 'has_warning', pp, w
|
||||
end
|
||||
|
||||
context 'concat warn parameter =>' do
|
||||
['true', 'yes', 'on'].each do |warn|
|
||||
context warn do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file':
|
||||
warn => '#{warn}',
|
||||
}
|
||||
concat::fragment { 'foo':
|
||||
target => '/tmp/concat/file',
|
||||
content => 'bar',
|
||||
}
|
||||
EOS
|
||||
w = 'Using stringified boolean values (\'true\', \'yes\', \'on\', \'false\', \'no\', \'off\') to represent boolean true/false as the $warn parameter to concat is deprecated and will be treated as the warning message in a future release'
|
||||
|
||||
it_behaves_like 'has_warning', pp, w
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should contain '# This file is managed by Puppet. DO NOT EDIT.' }
|
||||
it { should contain 'bar' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
['false', 'no', 'off'].each do |warn|
|
||||
context warn do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file':
|
||||
warn => '#{warn}',
|
||||
}
|
||||
concat::fragment { 'foo':
|
||||
target => '/tmp/concat/file',
|
||||
content => 'bar',
|
||||
}
|
||||
EOS
|
||||
w = 'Using stringified boolean values (\'true\', \'yes\', \'on\', \'false\', \'no\', \'off\') to represent boolean true/false as the $warn parameter to concat is deprecated and will be treated as the warning message in a future release'
|
||||
|
||||
it_behaves_like 'has_warning', pp, w
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should_not contain '# This file is managed by Puppet. DO NOT EDIT.' }
|
||||
it { should contain 'bar' }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'concat::fragment ensure parameter' do
|
||||
context 'target file exists' do
|
||||
before(:all) do
|
||||
shell("/bin/echo 'file1 contents' > /tmp/concat/file1")
|
||||
end
|
||||
after(:all) do
|
||||
# XXX this test may leave behind a symlink in the fragment directory
|
||||
# which could cause warnings and/or breakage from the subsequent tests
|
||||
# unless we clean it up.
|
||||
shell('rm -rf /tmp/concat /var/lib/puppet/concat')
|
||||
shell('mkdir -p /tmp/concat')
|
||||
end
|
||||
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file': }
|
||||
concat::fragment { 'foo':
|
||||
target => '/tmp/concat/file',
|
||||
ensure => '/tmp/concat/file1',
|
||||
}
|
||||
EOS
|
||||
w = 'Passing a value other than \'present\' or \'absent\' as the $ensure parameter to concat::fragment is deprecated. If you want to use the content of a file as a fragment please use the $source parameter.'
|
||||
|
||||
it_behaves_like 'has_warning', pp, w
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should contain 'file1 contents' }
|
||||
end
|
||||
|
||||
describe 'the fragment can be changed from a symlink to a plain file' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file': }
|
||||
concat::fragment { 'foo':
|
||||
target => '/tmp/concat/file',
|
||||
content => 'new content',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should contain 'new content' }
|
||||
it { should_not contain 'file1 contents' }
|
||||
end
|
||||
end
|
||||
end # target file exists
|
||||
|
||||
context 'target does not exist' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file': }
|
||||
concat::fragment { 'foo':
|
||||
target => '/tmp/concat/file',
|
||||
ensure => '/tmp/concat/file1',
|
||||
}
|
||||
EOS
|
||||
w = 'Passing a value other than \'present\' or \'absent\' as the $ensure parameter to concat::fragment is deprecated. If you want to use the content of a file as a fragment please use the $source parameter.'
|
||||
|
||||
it_behaves_like 'has_warning', pp, w
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
end
|
||||
|
||||
describe 'the fragment can be changed from a symlink to a plain file' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file': }
|
||||
concat::fragment { 'foo':
|
||||
target => '/tmp/concat/file',
|
||||
content => 'new content',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should contain 'new content' }
|
||||
end
|
||||
end
|
||||
end # target file exists
|
||||
|
||||
end # concat::fragment ensure parameter
|
||||
|
||||
context 'concat::fragment mode parameter' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file': }
|
||||
concat::fragment { 'foo':
|
||||
target => '/tmp/concat/file',
|
||||
content => 'bar',
|
||||
mode => 'bar',
|
||||
}
|
||||
EOS
|
||||
w = 'The $mode parameter to concat::fragment is deprecated and has no effect'
|
||||
|
||||
it_behaves_like 'has_warning', pp, w
|
||||
end
|
||||
|
||||
context 'concat::fragment owner parameter' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file': }
|
||||
concat::fragment { 'foo':
|
||||
target => '/tmp/concat/file',
|
||||
content => 'bar',
|
||||
owner => 'bar',
|
||||
}
|
||||
EOS
|
||||
w = 'The $owner parameter to concat::fragment is deprecated and has no effect'
|
||||
|
||||
it_behaves_like 'has_warning', pp, w
|
||||
end
|
||||
|
||||
context 'concat::fragment group parameter' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file': }
|
||||
concat::fragment { 'foo':
|
||||
target => '/tmp/concat/file',
|
||||
content => 'bar',
|
||||
group => 'bar',
|
||||
}
|
||||
EOS
|
||||
w = 'The $group parameter to concat::fragment is deprecated and has no effect'
|
||||
|
||||
it_behaves_like 'has_warning', pp, w
|
||||
end
|
||||
|
||||
context 'concat::fragment backup parameter' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file': }
|
||||
concat::fragment { 'foo':
|
||||
target => '/tmp/concat/file',
|
||||
content => 'bar',
|
||||
backup => 'bar',
|
||||
}
|
||||
EOS
|
||||
w = 'The $backup parameter to concat::fragment is deprecated and has no effect'
|
||||
|
||||
it_behaves_like 'has_warning', pp, w
|
||||
end
|
||||
|
||||
context 'include concat::setup' do
|
||||
pp = <<-EOS
|
||||
include concat::setup
|
||||
EOS
|
||||
w = 'concat::setup is deprecated as a public API of the concat module and should no longer be directly included in the manifest.'
|
||||
|
||||
it_behaves_like 'has_warning', pp, w
|
||||
end
|
||||
|
||||
end
|
24
modules/concat/spec/acceptance/empty_spec.rb
Normal file
24
modules/concat/spec/acceptance/empty_spec.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
require 'spec_helper_acceptance'
|
||||
|
||||
describe 'concat force empty parameter' do
|
||||
context 'should run successfully' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file':
|
||||
owner => root,
|
||||
group => root,
|
||||
mode => '0644',
|
||||
force => true,
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should_not contain '1\n2' }
|
||||
end
|
||||
end
|
||||
end
|
134
modules/concat/spec/acceptance/fragment_source_spec.rb
Normal file
134
modules/concat/spec/acceptance/fragment_source_spec.rb
Normal file
|
@ -0,0 +1,134 @@
|
|||
require 'spec_helper_acceptance'
|
||||
|
||||
describe 'concat::fragment source' do
|
||||
context 'should read file fragments from local system' do
|
||||
before(:all) do
|
||||
shell("/bin/echo 'file1 contents' > /tmp/concat/file1")
|
||||
shell("/bin/echo 'file2 contents' > /tmp/concat/file2")
|
||||
end
|
||||
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/foo': }
|
||||
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/foo',
|
||||
source => '/tmp/concat/file1',
|
||||
}
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat/foo',
|
||||
content => 'string1 contents',
|
||||
}
|
||||
concat::fragment { '3':
|
||||
target => '/tmp/concat/foo',
|
||||
source => '/tmp/concat/file2',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/foo') do
|
||||
it { should be_file }
|
||||
it { should contain 'file1 contents' }
|
||||
it { should contain 'string1 contents' }
|
||||
it { should contain 'file2 contents' }
|
||||
end
|
||||
end # should read file fragments from local system
|
||||
|
||||
context 'should create files containing first match only.' do
|
||||
before(:all) do
|
||||
shell('rm -rf /tmp/concat /var/lib/puppet/concat')
|
||||
shell('mkdir -p /tmp/concat')
|
||||
shell("/bin/echo 'file1 contents' > /tmp/concat/file1")
|
||||
shell("/bin/echo 'file2 contents' > /tmp/concat/file2")
|
||||
end
|
||||
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/result_file1':
|
||||
owner => root,
|
||||
group => root,
|
||||
mode => '0644',
|
||||
}
|
||||
concat { '/tmp/concat/result_file2':
|
||||
owner => root,
|
||||
group => root,
|
||||
mode => '0644',
|
||||
}
|
||||
concat { '/tmp/concat/result_file3':
|
||||
owner => root,
|
||||
group => root,
|
||||
mode => '0644',
|
||||
}
|
||||
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/result_file1',
|
||||
source => [ '/tmp/concat/file1', '/tmp/concat/file2' ],
|
||||
order => '01',
|
||||
}
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat/result_file2',
|
||||
source => [ '/tmp/concat/file2', '/tmp/concat/file1' ],
|
||||
order => '01',
|
||||
}
|
||||
concat::fragment { '3':
|
||||
target => '/tmp/concat/result_file3',
|
||||
source => [ '/tmp/concat/file1', '/tmp/concat/file2' ],
|
||||
order => '01',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
describe file('/tmp/concat/result_file1') do
|
||||
it { should be_file }
|
||||
it { should contain 'file1 contents' }
|
||||
it { should_not contain 'file2 contents' }
|
||||
end
|
||||
describe file('/tmp/concat/result_file2') do
|
||||
it { should be_file }
|
||||
it { should contain 'file2 contents' }
|
||||
it { should_not contain 'file1 contents' }
|
||||
end
|
||||
describe file('/tmp/concat/result_file3') do
|
||||
it { should be_file }
|
||||
it { should contain 'file1 contents' }
|
||||
it { should_not contain 'file2 contents' }
|
||||
end
|
||||
end
|
||||
|
||||
context 'should fail if no match on source.' do
|
||||
before(:all) do
|
||||
shell('rm -rf /tmp/concat /var/lib/puppet/concat')
|
||||
shell('mkdir -p /tmp/concat')
|
||||
shell('/bin/rm -rf /tmp/concat/fail_no_source /tmp/concat/nofilehere /tmp/concat/nothereeither')
|
||||
end
|
||||
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/fail_no_source':
|
||||
owner => root,
|
||||
group => root,
|
||||
mode => '0644',
|
||||
}
|
||||
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/fail_no_source',
|
||||
source => [ '/tmp/concat/nofilehere', '/tmp/concat/nothereeither' ],
|
||||
order => '01',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest with resource failures' do
|
||||
apply_manifest(pp, :expect_failures => true)
|
||||
end
|
||||
describe file('/tmp/concat/fail_no_source') do
|
||||
#FIXME: Serverspec::Type::File doesn't support exists? for some reason. so... hack.
|
||||
it { should_not be_file }
|
||||
it { should_not be_directory }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
57
modules/concat/spec/acceptance/newline_spec.rb
Normal file
57
modules/concat/spec/acceptance/newline_spec.rb
Normal file
|
@ -0,0 +1,57 @@
|
|||
require 'spec_helper_acceptance'
|
||||
|
||||
describe 'concat ensure_newline parameter' do
|
||||
context '=> false' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file':
|
||||
ensure_newline => false,
|
||||
}
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/file',
|
||||
content => '1',
|
||||
}
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat/file',
|
||||
content => '2',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should contain '12' }
|
||||
end
|
||||
end
|
||||
|
||||
context '=> true' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file':
|
||||
ensure_newline => true,
|
||||
}
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/file',
|
||||
content => '1',
|
||||
}
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat/file',
|
||||
content => '2',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
#XXX ensure_newline => true causes changes on every run because the files
|
||||
#are modified in place.
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should contain "1\n2\n" }
|
||||
end
|
||||
end
|
||||
end
|
19
modules/concat/spec/acceptance/nodesets/aix-71-vcloud.yml
Normal file
19
modules/concat/spec/acceptance/nodesets/aix-71-vcloud.yml
Normal file
|
@ -0,0 +1,19 @@
|
|||
HOSTS:
|
||||
pe-aix-71-acceptance:
|
||||
roles:
|
||||
- master
|
||||
- dashboard
|
||||
- database
|
||||
- agent
|
||||
- default
|
||||
platform: aix-7.1-power
|
||||
hypervisor: aix
|
||||
ip: pe-aix-71-acceptance.delivery.puppetlabs.net
|
||||
CONFIG:
|
||||
type: pe
|
||||
nfs_server: NONE
|
||||
consoleport: 443
|
||||
datastore: instance0
|
||||
folder: Delivery/Quality Assurance/Enterprise/Dynamic
|
||||
resourcepool: delivery/Quality Assurance/Enterprise/Dynamic
|
||||
pooling_api: http://vcloud.delivery.puppetlabs.net/
|
10
modules/concat/spec/acceptance/nodesets/centos-59-x64.yml
Normal file
10
modules/concat/spec/acceptance/nodesets/centos-59-x64.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
HOSTS:
|
||||
centos-59-x64:
|
||||
roles:
|
||||
- master
|
||||
platform: el-5-x86_64
|
||||
box : centos-59-x64-vbox4210-nocm
|
||||
box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-59-x64-vbox4210-nocm.box
|
||||
hypervisor : vagrant
|
||||
CONFIG:
|
||||
type: git
|
12
modules/concat/spec/acceptance/nodesets/centos-64-x64-pe.yml
Normal file
12
modules/concat/spec/acceptance/nodesets/centos-64-x64-pe.yml
Normal file
|
@ -0,0 +1,12 @@
|
|||
HOSTS:
|
||||
centos-64-x64:
|
||||
roles:
|
||||
- master
|
||||
- database
|
||||
- dashboard
|
||||
platform: el-6-x86_64
|
||||
box : centos-64-x64-vbox4210-nocm
|
||||
box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box
|
||||
hypervisor : vagrant
|
||||
CONFIG:
|
||||
type: pe
|
10
modules/concat/spec/acceptance/nodesets/centos-64-x64.yml
Normal file
10
modules/concat/spec/acceptance/nodesets/centos-64-x64.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
HOSTS:
|
||||
centos-64-x64:
|
||||
roles:
|
||||
- master
|
||||
platform: el-6-x86_64
|
||||
box : centos-64-x64-vbox4210-nocm
|
||||
box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box
|
||||
hypervisor : vagrant
|
||||
CONFIG:
|
||||
type: foss
|
10
modules/concat/spec/acceptance/nodesets/debian-607-x64.yml
Normal file
10
modules/concat/spec/acceptance/nodesets/debian-607-x64.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
HOSTS:
|
||||
debian-607-x64:
|
||||
roles:
|
||||
- master
|
||||
platform: debian-6-amd64
|
||||
box : debian-607-x64-vbox4210-nocm
|
||||
box_url : http://puppet-vagrant-boxes.puppetlabs.com/debian-607-x64-vbox4210-nocm.box
|
||||
hypervisor : vagrant
|
||||
CONFIG:
|
||||
type: git
|
10
modules/concat/spec/acceptance/nodesets/debian-70rc1-x64.yml
Normal file
10
modules/concat/spec/acceptance/nodesets/debian-70rc1-x64.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
HOSTS:
|
||||
debian-70rc1-x64:
|
||||
roles:
|
||||
- master
|
||||
platform: debian-7-amd64
|
||||
box : debian-70rc1-x64-vbox4210-nocm
|
||||
box_url : http://puppet-vagrant-boxes.puppetlabs.com/debian-70rc1-x64-vbox4210-nocm.box
|
||||
hypervisor : vagrant
|
||||
CONFIG:
|
||||
type: git
|
11
modules/concat/spec/acceptance/nodesets/debian-73-x64.yml
Normal file
11
modules/concat/spec/acceptance/nodesets/debian-73-x64.yml
Normal file
|
@ -0,0 +1,11 @@
|
|||
HOSTS:
|
||||
debian-73-x64.localhost:
|
||||
roles:
|
||||
- master
|
||||
platform: debian-7-amd64
|
||||
box : debian-73-x64-virtualbox-nocm
|
||||
box_url : http://puppet-vagrant-boxes.puppetlabs.com/debian-73-x64-virtualbox-nocm.box
|
||||
hypervisor : vagrant
|
||||
CONFIG:
|
||||
log_level: debug
|
||||
type: foss
|
10
modules/concat/spec/acceptance/nodesets/default.yml
Normal file
10
modules/concat/spec/acceptance/nodesets/default.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
HOSTS:
|
||||
centos-64-x64.localdomain:
|
||||
roles:
|
||||
- master
|
||||
platform: el-6-x86_64
|
||||
box : centos-65-x64-virtualbox-nocm
|
||||
box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-65-x64-virtualbox-nocm.box
|
||||
hypervisor : vagrant
|
||||
CONFIG:
|
||||
type: foss
|
10
modules/concat/spec/acceptance/nodesets/fedora-18-x64.yml
Normal file
10
modules/concat/spec/acceptance/nodesets/fedora-18-x64.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
HOSTS:
|
||||
fedora-18-x64:
|
||||
roles:
|
||||
- master
|
||||
platform: fedora-18-x86_64
|
||||
box : fedora-18-x64-vbox4210-nocm
|
||||
box_url : http://puppet-vagrant-boxes.puppetlabs.com/fedora-18-x64-vbox4210-nocm.box
|
||||
hypervisor : vagrant
|
||||
CONFIG:
|
||||
type: foss
|
15
modules/concat/spec/acceptance/nodesets/rhel-7-x64.yml
Normal file
15
modules/concat/spec/acceptance/nodesets/rhel-7-x64.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
HOSTS:
|
||||
'redhat-7-vcloud':
|
||||
roles:
|
||||
- master
|
||||
platform: el-7-x86_64
|
||||
hypervisor: vcloud
|
||||
template: redhat-7-x86_64
|
||||
CONFIG:
|
||||
type: foss
|
||||
ssh:
|
||||
keys: "~/.ssh/id_rsa-acceptance"
|
||||
datastore: instance0
|
||||
folder: Delivery/Quality Assurance/Enterprise/Dynamic
|
||||
resourcepool: delivery/Quality Assurance/Enterprise/Dynamic
|
||||
pooling_api: http://vcloud.delivery.puppetlabs.net/
|
10
modules/concat/spec/acceptance/nodesets/sles-11-x64.yml
Normal file
10
modules/concat/spec/acceptance/nodesets/sles-11-x64.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
HOSTS:
|
||||
sles-11-x64.local:
|
||||
roles:
|
||||
- master
|
||||
platform: sles-11-x64
|
||||
box : sles-11sp1-x64-vbox4210-nocm
|
||||
box_url : http://puppet-vagrant-boxes.puppetlabs.com/sles-11sp1-x64-vbox4210-nocm.box
|
||||
hypervisor : vagrant
|
||||
CONFIG:
|
||||
type: foss
|
10
modules/concat/spec/acceptance/nodesets/sles-11sp1-x64.yml
Normal file
10
modules/concat/spec/acceptance/nodesets/sles-11sp1-x64.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
HOSTS:
|
||||
sles-11sp1-x64:
|
||||
roles:
|
||||
- master
|
||||
platform: sles-11-x86_64
|
||||
box : sles-11sp1-x64-vbox4210-nocm
|
||||
box_url : http://puppet-vagrant-boxes.puppetlabs.com/sles-11sp1-x64-vbox4210-nocm.box
|
||||
hypervisor : vagrant
|
||||
CONFIG:
|
||||
type: git
|
|
@ -0,0 +1,10 @@
|
|||
HOSTS:
|
||||
ubuntu-server-10044-x64:
|
||||
roles:
|
||||
- master
|
||||
platform: ubuntu-10.04-amd64
|
||||
box : ubuntu-server-10044-x64-vbox4210-nocm
|
||||
box_url : http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-10044-x64-vbox4210-nocm.box
|
||||
hypervisor : vagrant
|
||||
CONFIG:
|
||||
type: foss
|
|
@ -0,0 +1,10 @@
|
|||
HOSTS:
|
||||
ubuntu-server-12042-x64:
|
||||
roles:
|
||||
- master
|
||||
platform: ubuntu-12.04-amd64
|
||||
box : ubuntu-server-12042-x64-vbox4210-nocm
|
||||
box_url : http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-12042-x64-vbox4210-nocm.box
|
||||
hypervisor : vagrant
|
||||
CONFIG:
|
||||
type: foss
|
|
@ -0,0 +1,11 @@
|
|||
HOSTS:
|
||||
ubuntu-server-1404-x64:
|
||||
roles:
|
||||
- master
|
||||
platform: ubuntu-14.04-amd64
|
||||
box : puppetlabs/ubuntu-14.04-64-nocm
|
||||
box_url : https://vagrantcloud.com/puppetlabs/ubuntu-14.04-64-nocm
|
||||
hypervisor : vagrant
|
||||
CONFIG:
|
||||
log_level : debug
|
||||
type: git
|
137
modules/concat/spec/acceptance/order_spec.rb
Normal file
137
modules/concat/spec/acceptance/order_spec.rb
Normal file
|
@ -0,0 +1,137 @@
|
|||
require 'spec_helper_acceptance'
|
||||
|
||||
describe 'concat order' do
|
||||
before(:all) do
|
||||
shell('rm -rf /tmp/concat /var/lib/puppet/concat')
|
||||
shell('mkdir -p /tmp/concat')
|
||||
end
|
||||
|
||||
context '=> alpha' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/foo':
|
||||
order => 'alpha'
|
||||
}
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/foo',
|
||||
content => 'string1',
|
||||
}
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat/foo',
|
||||
content => 'string2',
|
||||
}
|
||||
concat::fragment { '10':
|
||||
target => '/tmp/concat/foo',
|
||||
content => 'string10',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/foo') do
|
||||
it { should be_file }
|
||||
it { should contain "string10\nstring1\nsring2" }
|
||||
end
|
||||
end
|
||||
|
||||
context '=> numeric' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/foo':
|
||||
order => 'numeric'
|
||||
}
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/foo',
|
||||
content => 'string1',
|
||||
}
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat/foo',
|
||||
content => 'string2',
|
||||
}
|
||||
concat::fragment { '10':
|
||||
target => '/tmp/concat/foo',
|
||||
content => 'string10',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/foo') do
|
||||
it { should be_file }
|
||||
it { should contain "string1\nstring2\nsring10" }
|
||||
end
|
||||
end
|
||||
end # concat order
|
||||
|
||||
describe 'concat::fragment order' do
|
||||
before(:all) do
|
||||
shell('rm -rf /tmp/concat /var/lib/puppet/concat')
|
||||
shell('mkdir -p /tmp/concat')
|
||||
end
|
||||
|
||||
context '=> reverse order' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/foo': }
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/foo',
|
||||
content => 'string1',
|
||||
order => '15',
|
||||
}
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat/foo',
|
||||
content => 'string2',
|
||||
# default order 10
|
||||
}
|
||||
concat::fragment { '3':
|
||||
target => '/tmp/concat/foo',
|
||||
content => 'string3',
|
||||
order => '1',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/foo') do
|
||||
it { should be_file }
|
||||
it { should contain "string3\nstring2\nsring1" }
|
||||
end
|
||||
end
|
||||
|
||||
context '=> normal order' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/foo': }
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/foo',
|
||||
content => 'string1',
|
||||
order => '01',
|
||||
}
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat/foo',
|
||||
content => 'string2',
|
||||
order => '02'
|
||||
}
|
||||
concat::fragment { '3':
|
||||
target => '/tmp/concat/foo',
|
||||
content => 'string3',
|
||||
order => '03',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/foo') do
|
||||
it { should be_file }
|
||||
it { should contain "string1\nstring2\nsring3" }
|
||||
end
|
||||
end
|
||||
end # concat::fragment order
|
33
modules/concat/spec/acceptance/quoted_paths_spec.rb
Normal file
33
modules/concat/spec/acceptance/quoted_paths_spec.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
require 'spec_helper_acceptance'
|
||||
|
||||
describe 'quoted paths' do
|
||||
before(:all) do
|
||||
shell('rm -rf "/tmp/concat test" /var/lib/puppet/concat')
|
||||
shell('mkdir -p "/tmp/concat test"')
|
||||
end
|
||||
|
||||
context 'path with blanks' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat test/foo':
|
||||
}
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat test/foo',
|
||||
content => 'string1',
|
||||
}
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat test/foo',
|
||||
content => 'string2',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat test/foo') do
|
||||
it { should be_file }
|
||||
it { should contain "string1\nsring2" }
|
||||
end
|
||||
end
|
||||
end
|
241
modules/concat/spec/acceptance/replace_spec.rb
Normal file
241
modules/concat/spec/acceptance/replace_spec.rb
Normal file
|
@ -0,0 +1,241 @@
|
|||
require 'spec_helper_acceptance'
|
||||
|
||||
describe 'replacement of' do
|
||||
context 'file' do
|
||||
context 'should not succeed' do
|
||||
before(:all) do
|
||||
shell('mkdir -p /tmp/concat')
|
||||
shell('echo "file exists" > /tmp/concat/file')
|
||||
end
|
||||
after(:all) do
|
||||
shell('rm -rf /tmp/concat /var/lib/puppet/concat')
|
||||
end
|
||||
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file':
|
||||
replace => false,
|
||||
}
|
||||
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/file',
|
||||
content => '1',
|
||||
}
|
||||
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat/file',
|
||||
content => '2',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should contain 'file exists' }
|
||||
it { should_not contain '1' }
|
||||
it { should_not contain '2' }
|
||||
end
|
||||
end
|
||||
|
||||
context 'should succeed' do
|
||||
before(:all) do
|
||||
shell('mkdir -p /tmp/concat')
|
||||
shell('echo "file exists" > /tmp/concat/file')
|
||||
end
|
||||
after(:all) do
|
||||
shell('rm -rf /tmp/concat /var/lib/puppet/concat')
|
||||
end
|
||||
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file':
|
||||
replace => true,
|
||||
}
|
||||
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/file',
|
||||
content => '1',
|
||||
}
|
||||
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat/file',
|
||||
content => '2',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should_not contain 'file exists' }
|
||||
it { should contain '1' }
|
||||
it { should contain '2' }
|
||||
end
|
||||
end
|
||||
end # file
|
||||
|
||||
context 'symlink' do
|
||||
context 'should not succeed' do
|
||||
# XXX the core puppet file type will replace a symlink with a plain file
|
||||
# when using ensure => present and source => ... but it will not when using
|
||||
# ensure => present and content => ...; this is somewhat confusing behavior
|
||||
before(:all) do
|
||||
shell('mkdir -p /tmp/concat')
|
||||
shell('ln -s /tmp/concat/dangling /tmp/concat/file')
|
||||
end
|
||||
after(:all) do
|
||||
shell('rm -rf /tmp/concat /var/lib/puppet/concat')
|
||||
end
|
||||
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file':
|
||||
replace => false,
|
||||
}
|
||||
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/file',
|
||||
content => '1',
|
||||
}
|
||||
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat/file',
|
||||
content => '2',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_linked_to '/tmp/concat/dangling' }
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/dangling') do
|
||||
# XXX serverspec does not have a matcher for 'exists'
|
||||
it { should_not be_file }
|
||||
it { should_not be_directory }
|
||||
end
|
||||
end
|
||||
|
||||
context 'should succeed' do
|
||||
# XXX the core puppet file type will replace a symlink with a plain file
|
||||
# when using ensure => present and source => ... but it will not when using
|
||||
# ensure => present and content => ...; this is somewhat confusing behavior
|
||||
before(:all) do
|
||||
shell('mkdir -p /tmp/concat')
|
||||
shell('ln -s /tmp/concat/dangling /tmp/concat/file')
|
||||
end
|
||||
after(:all) do
|
||||
shell('rm -rf /tmp/concat /var/lib/puppet/concat')
|
||||
end
|
||||
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file':
|
||||
replace => true,
|
||||
}
|
||||
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/file',
|
||||
content => '1',
|
||||
}
|
||||
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat/file',
|
||||
content => '2',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should contain '1' }
|
||||
it { should contain '2' }
|
||||
end
|
||||
end
|
||||
end # symlink
|
||||
|
||||
context 'directory' do
|
||||
context 'should not succeed' do
|
||||
before(:all) do
|
||||
shell('mkdir -p /tmp/concat/file')
|
||||
end
|
||||
after(:all) do
|
||||
shell('rm -rf /tmp/concat /var/lib/puppet/concat')
|
||||
end
|
||||
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file': }
|
||||
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/file',
|
||||
content => '1',
|
||||
}
|
||||
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat/file',
|
||||
content => '2',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with stderr for changing to file' do
|
||||
expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/change from directory to file failed/)
|
||||
expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/change from directory to file failed/)
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_directory }
|
||||
end
|
||||
end
|
||||
|
||||
# XXX concat's force param currently enables the creation of empty files
|
||||
# when there are no fragments, and the replace param will only replace
|
||||
# files and symlinks, not directories. The semantics either need to be
|
||||
# changed, extended, or a new param introduced to control directory
|
||||
# replacement.
|
||||
context 'should succeed', :pending => 'not yet implemented' do
|
||||
before(:all) do
|
||||
shell('mkdir -p /tmp/concat/file')
|
||||
end
|
||||
after(:all) do
|
||||
shell('rm -rf /tmp/concat /var/lib/puppet/concat')
|
||||
end
|
||||
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file':
|
||||
force => true,
|
||||
}
|
||||
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/file',
|
||||
content => '1',
|
||||
}
|
||||
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat/file',
|
||||
content => '2',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should contain '1' }
|
||||
end
|
||||
end
|
||||
end # directory
|
||||
end
|
32
modules/concat/spec/acceptance/symbolic_name_spec.rb
Normal file
32
modules/concat/spec/acceptance/symbolic_name_spec.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
require 'spec_helper_acceptance'
|
||||
|
||||
describe 'symbolic name' do
|
||||
pp = <<-EOS
|
||||
concat { 'not_abs_path':
|
||||
path => '/tmp/concat/file',
|
||||
}
|
||||
|
||||
concat::fragment { '1':
|
||||
target => 'not_abs_path',
|
||||
content => '1',
|
||||
order => '01',
|
||||
}
|
||||
|
||||
concat::fragment { '2':
|
||||
target => 'not_abs_path',
|
||||
content => '2',
|
||||
order => '02',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should contain '1' }
|
||||
it { should contain '2' }
|
||||
end
|
||||
end
|
97
modules/concat/spec/acceptance/warn_spec.rb
Normal file
97
modules/concat/spec/acceptance/warn_spec.rb
Normal file
|
@ -0,0 +1,97 @@
|
|||
require 'spec_helper_acceptance'
|
||||
|
||||
describe 'concat warn =>' do
|
||||
context 'true should enable default warning message' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file':
|
||||
warn => true,
|
||||
}
|
||||
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/file',
|
||||
content => '1',
|
||||
order => '01',
|
||||
}
|
||||
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat/file',
|
||||
content => '2',
|
||||
order => '02',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should contain '# This file is managed by Puppet. DO NOT EDIT.' }
|
||||
it { should contain '1' }
|
||||
it { should contain '2' }
|
||||
end
|
||||
end
|
||||
context 'false should not enable default warning message' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file':
|
||||
warn => false,
|
||||
}
|
||||
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/file',
|
||||
content => '1',
|
||||
order => '01',
|
||||
}
|
||||
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat/file',
|
||||
content => '2',
|
||||
order => '02',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should_not contain '# This file is managed by Puppet. DO NOT EDIT.' }
|
||||
it { should contain '1' }
|
||||
it { should contain '2' }
|
||||
end
|
||||
end
|
||||
context '# foo should overide default warning message' do
|
||||
pp = <<-EOS
|
||||
concat { '/tmp/concat/file':
|
||||
warn => '# foo',
|
||||
}
|
||||
|
||||
concat::fragment { '1':
|
||||
target => '/tmp/concat/file',
|
||||
content => '1',
|
||||
order => '01',
|
||||
}
|
||||
|
||||
concat::fragment { '2':
|
||||
target => '/tmp/concat/file',
|
||||
content => '2',
|
||||
order => '02',
|
||||
}
|
||||
EOS
|
||||
|
||||
it 'applies the manifest twice with no stderr' do
|
||||
expect(apply_manifest(pp, :catch_failures => true).stderr).to eq("")
|
||||
expect(apply_manifest(pp, :catch_changes => true).stderr).to eq("")
|
||||
end
|
||||
|
||||
describe file('/tmp/concat/file') do
|
||||
it { should be_file }
|
||||
it { should contain '# foo' }
|
||||
it { should contain '1' }
|
||||
it { should contain '2' }
|
||||
end
|
||||
end
|
||||
end
|
1
modules/concat/spec/spec_helper.rb
Normal file
1
modules/concat/spec/spec_helper.rb
Normal file
|
@ -0,0 +1 @@
|
|||
require 'puppetlabs_spec_helper/module_spec_helper'
|
39
modules/concat/spec/spec_helper_acceptance.rb
Normal file
39
modules/concat/spec/spec_helper_acceptance.rb
Normal file
|
@ -0,0 +1,39 @@
|
|||
require 'beaker-rspec/spec_helper'
|
||||
require 'beaker-rspec/helpers/serverspec'
|
||||
|
||||
unless ENV['RS_PROVISION'] == 'no' or ENV['BEAKER_provision'] == 'no'
|
||||
if hosts.first.is_pe?
|
||||
install_pe
|
||||
else
|
||||
install_puppet
|
||||
end
|
||||
hosts.each do |host|
|
||||
on hosts, "mkdir -p #{host['distmoduledir']}"
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.configure do |c|
|
||||
# Project root
|
||||
proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
||||
|
||||
# Readable test descriptions
|
||||
c.formatter = :documentation
|
||||
|
||||
# Configure all nodes in nodeset
|
||||
c.before :suite do
|
||||
# Install module and dependencies
|
||||
puppet_module_install(:source => proj_root, :module_name => 'concat')
|
||||
hosts.each do |host|
|
||||
on host, puppet('module','install','puppetlabs-stdlib'), { :acceptable_exit_codes => [0,1] }
|
||||
end
|
||||
end
|
||||
|
||||
c.before(:all) do
|
||||
shell('mkdir -p /tmp/concat')
|
||||
end
|
||||
c.after(:all) do
|
||||
shell('rm -rf /tmp/concat /var/lib/puppet/concat')
|
||||
end
|
||||
|
||||
c.treat_symbols_as_metadata_keys_with_true_values = true
|
||||
end
|
42
modules/concat/spec/unit/classes/concat_setup_spec.rb
Normal file
42
modules/concat/spec/unit/classes/concat_setup_spec.rb
Normal file
|
@ -0,0 +1,42 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'concat::setup', :type => :class do
|
||||
|
||||
shared_examples 'setup' do |concatdir|
|
||||
concatdir = '/foo' if concatdir.nil?
|
||||
|
||||
let(:facts) {{ :concat_basedir => concatdir }}
|
||||
|
||||
it do
|
||||
should contain_file("#{concatdir}/bin/concatfragments.sh").with({
|
||||
:mode => '0755',
|
||||
:source => 'puppet:///modules/concat/concatfragments.sh',
|
||||
:backup => false,
|
||||
})
|
||||
end
|
||||
|
||||
[concatdir, "#{concatdir}/bin"].each do |file|
|
||||
it do
|
||||
should contain_file(file).with({
|
||||
:ensure => 'directory',
|
||||
:mode => '0755',
|
||||
:backup => false,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'facts' do
|
||||
context 'concat_basedir =>' do
|
||||
context '/foo' do
|
||||
it_behaves_like 'setup', '/foo'
|
||||
end
|
||||
end
|
||||
end # facts
|
||||
|
||||
context 'deprecated as a public class' do
|
||||
it 'should create a warning' do
|
||||
pending('rspec-puppet support for testing warning()')
|
||||
end
|
||||
end
|
||||
end
|
267
modules/concat/spec/unit/defines/concat_fragment_spec.rb
Normal file
267
modules/concat/spec/unit/defines/concat_fragment_spec.rb
Normal file
|
@ -0,0 +1,267 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'concat::fragment', :type => :define do
|
||||
|
||||
shared_examples 'fragment' do |title, params|
|
||||
params = {} if params.nil?
|
||||
|
||||
p = {
|
||||
:content => nil,
|
||||
:source => nil,
|
||||
:order => 10,
|
||||
:ensure => 'present',
|
||||
}.merge(params)
|
||||
|
||||
safe_name = title.gsub(/[\/\n]/, '_')
|
||||
safe_target_name = p[:target].gsub(/[\/\n]/, '_')
|
||||
concatdir = '/var/lib/puppet/concat'
|
||||
fragdir = "#{concatdir}/#{safe_target_name}"
|
||||
id = 'root'
|
||||
if p[:ensure] == 'absent'
|
||||
safe_ensure = p[:ensure]
|
||||
else
|
||||
safe_ensure = 'file'
|
||||
end
|
||||
|
||||
let(:title) { title }
|
||||
let(:facts) {{ :concat_basedir => concatdir, :id => id }}
|
||||
let(:params) { params }
|
||||
let(:pre_condition) do
|
||||
"concat{ '#{p[:target]}': }"
|
||||
end
|
||||
|
||||
it do
|
||||
should contain_class('concat::setup')
|
||||
should contain_concat(p[:target])
|
||||
should contain_file("#{fragdir}/fragments/#{p[:order]}_#{safe_name}").with({
|
||||
:ensure => safe_ensure,
|
||||
:owner => id,
|
||||
:mode => '0640',
|
||||
:source => p[:source],
|
||||
:content => p[:content],
|
||||
:alias => "concat_fragment_#{title}",
|
||||
:backup => false,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
context 'title' do
|
||||
['0', '1', 'a', 'z'].each do |title|
|
||||
it_behaves_like 'fragment', title, {
|
||||
:target => '/etc/motd',
|
||||
}
|
||||
end
|
||||
end # title
|
||||
|
||||
context 'target =>' do
|
||||
['./etc/motd', 'etc/motd', 'motd_header'].each do |target|
|
||||
context target do
|
||||
it_behaves_like 'fragment', target, {
|
||||
:target => '/etc/motd',
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context 'false' do
|
||||
let(:title) { 'motd_header' }
|
||||
let(:facts) {{ :concat_basedir => '/tmp' }}
|
||||
let(:params) {{ :target => false }}
|
||||
|
||||
it 'should fail' do
|
||||
expect { should }.to raise_error(Puppet::Error, /is not a string/)
|
||||
end
|
||||
end
|
||||
end # target =>
|
||||
|
||||
context 'ensure =>' do
|
||||
['present', 'absent'].each do |ens|
|
||||
context ens do
|
||||
it_behaves_like 'fragment', 'motd_header', {
|
||||
:ensure => ens,
|
||||
:target => '/etc/motd',
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context 'any value other than \'present\' or \'absent\'' do
|
||||
let(:title) { 'motd_header' }
|
||||
let(:facts) {{ :concat_basedir => '/tmp' }}
|
||||
let(:params) {{ :ensure => 'invalid', :target => '/etc/motd' }}
|
||||
|
||||
it 'should create a warning' do
|
||||
pending('rspec-puppet support for testing warning()')
|
||||
end
|
||||
end
|
||||
end # ensure =>
|
||||
|
||||
context 'content =>' do
|
||||
['', 'ashp is our hero'].each do |content|
|
||||
context content do
|
||||
it_behaves_like 'fragment', 'motd_header', {
|
||||
:content => content,
|
||||
:target => '/etc/motd',
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context 'false' do
|
||||
let(:title) { 'motd_header' }
|
||||
let(:facts) {{ :concat_basedir => '/tmp' }}
|
||||
let(:params) {{ :content => false, :target => '/etc/motd' }}
|
||||
|
||||
it 'should fail' do
|
||||
expect { should }.to raise_error(Puppet::Error, /is not a string/)
|
||||
end
|
||||
end
|
||||
end # content =>
|
||||
|
||||
context 'source =>' do
|
||||
['', '/foo/bar', ['/foo/bar', '/foo/baz']].each do |source|
|
||||
context source do
|
||||
it_behaves_like 'fragment', 'motd_header', {
|
||||
:source => source,
|
||||
:target => '/etc/motd',
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context 'false' do
|
||||
let(:title) { 'motd_header' }
|
||||
let(:facts) {{ :concat_basedir => '/tmp' }}
|
||||
let(:params) {{ :source => false, :target => '/etc/motd' }}
|
||||
|
||||
it 'should fail' do
|
||||
expect { should }.to raise_error(Puppet::Error, /is not a string or an Array/)
|
||||
end
|
||||
end
|
||||
end # source =>
|
||||
|
||||
context 'order =>' do
|
||||
['', '42', 'a', 'z'].each do |order|
|
||||
context '\'\'' do
|
||||
it_behaves_like 'fragment', 'motd_header', {
|
||||
:order => order,
|
||||
:target => '/etc/motd',
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context 'false' do
|
||||
let(:title) { 'motd_header' }
|
||||
let(:facts) {{ :concat_basedir => '/tmp' }}
|
||||
let(:params) {{ :order => false, :target => '/etc/motd' }}
|
||||
|
||||
it 'should fail' do
|
||||
expect { should }.to raise_error(Puppet::Error, /is not a string/)
|
||||
end
|
||||
end
|
||||
end # order =>
|
||||
|
||||
context 'more than one content source' do
|
||||
error_msg = 'You cannot specify more than one of $content, $source, $ensure => /target'
|
||||
|
||||
context 'ensure => target and source' do
|
||||
let(:title) { 'motd_header' }
|
||||
let(:facts) {{ :concat_basedir => '/tmp' }}
|
||||
let(:params) do
|
||||
{
|
||||
:target => '/etc/motd',
|
||||
:ensure => '/foo',
|
||||
:source => '/bar',
|
||||
}
|
||||
end
|
||||
|
||||
it 'should fail' do
|
||||
expect { should }.to raise_error(Puppet::Error, /#{Regexp.escape(error_msg)}/m)
|
||||
end
|
||||
end
|
||||
|
||||
context 'ensure => target and content' do
|
||||
let(:title) { 'motd_header' }
|
||||
let(:facts) {{ :concat_basedir => '/tmp' }}
|
||||
let(:params) do
|
||||
{
|
||||
:target => '/etc/motd',
|
||||
:ensure => '/foo',
|
||||
:content => 'bar',
|
||||
}
|
||||
end
|
||||
|
||||
it 'should fail' do
|
||||
expect { should }.to raise_error(Puppet::Error, /#{Regexp.escape(error_msg)}/m)
|
||||
end
|
||||
end
|
||||
|
||||
context 'source and content' do
|
||||
let(:title) { 'motd_header' }
|
||||
let(:facts) {{ :concat_basedir => '/tmp' }}
|
||||
let(:params) do
|
||||
{
|
||||
:target => '/etc/motd',
|
||||
:source => '/foo',
|
||||
:content => 'bar',
|
||||
}
|
||||
end
|
||||
|
||||
it 'should fail' do
|
||||
expect { should }.to raise_error(Puppet::Error, /#{Regexp.escape(error_msg)}/m)
|
||||
end
|
||||
end
|
||||
|
||||
end # more than one content source
|
||||
|
||||
describe 'deprecated parameter' do
|
||||
context 'mode =>' do
|
||||
context '1755' do
|
||||
it_behaves_like 'fragment', 'motd_header', {
|
||||
:mode => '1755',
|
||||
:target => '/etc/motd',
|
||||
}
|
||||
|
||||
it 'should create a warning' do
|
||||
pending('rspec-puppet support for testing warning()')
|
||||
end
|
||||
end
|
||||
end # mode =>
|
||||
|
||||
context 'owner =>' do
|
||||
context 'apenny' do
|
||||
it_behaves_like 'fragment', 'motd_header', {
|
||||
:owner => 'apenny',
|
||||
:target => '/etc/motd',
|
||||
}
|
||||
|
||||
it 'should create a warning' do
|
||||
pending('rspec-puppet support for testing warning()')
|
||||
end
|
||||
end
|
||||
end # owner =>
|
||||
|
||||
context 'group =>' do
|
||||
context 'apenny' do
|
||||
it_behaves_like 'fragment', 'motd_header', {
|
||||
:group => 'apenny',
|
||||
:target => '/etc/motd',
|
||||
}
|
||||
|
||||
it 'should create a warning' do
|
||||
pending('rspec-puppet support for testing warning()')
|
||||
end
|
||||
end
|
||||
end # group =>
|
||||
|
||||
context 'backup =>' do
|
||||
context 'foo' do
|
||||
it_behaves_like 'fragment', 'motd_header', {
|
||||
:backup => 'foo',
|
||||
:target => '/etc/motd',
|
||||
}
|
||||
|
||||
it 'should create a warning' do
|
||||
pending('rspec-puppet support for testing warning()')
|
||||
end
|
||||
end
|
||||
end # backup =>
|
||||
end # deprecated params
|
||||
|
||||
end
|
380
modules/concat/spec/unit/defines/concat_spec.rb
Normal file
380
modules/concat/spec/unit/defines/concat_spec.rb
Normal file
|
@ -0,0 +1,380 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'concat', :type => :define do
|
||||
|
||||
shared_examples 'concat' do |title, params, id|
|
||||
params = {} if params.nil?
|
||||
id = 'root' if id.nil?
|
||||
|
||||
# default param values
|
||||
p = {
|
||||
:ensure => 'present',
|
||||
:path => title,
|
||||
:owner => nil,
|
||||
:group => nil,
|
||||
:mode => '0644',
|
||||
:warn => false,
|
||||
:force => false,
|
||||
:backup => 'puppet',
|
||||
:replace => true,
|
||||
:order => 'alpha',
|
||||
:ensure_newline => false,
|
||||
}.merge(params)
|
||||
|
||||
safe_name = title.gsub('/', '_')
|
||||
concatdir = '/var/lib/puppet/concat'
|
||||
fragdir = "#{concatdir}/#{safe_name}"
|
||||
concat_name = 'fragments.concat.out'
|
||||
default_warn_message = '# This file is managed by Puppet. DO NOT EDIT.'
|
||||
|
||||
file_defaults = {
|
||||
:backup => false,
|
||||
}
|
||||
|
||||
let(:title) { title }
|
||||
let(:params) { params }
|
||||
let(:facts) {{ :concat_basedir => concatdir, :id => id }}
|
||||
|
||||
if p[:ensure] == 'present'
|
||||
it do
|
||||
should contain_file(fragdir).with(file_defaults.merge({
|
||||
:ensure => 'directory',
|
||||
:mode => '0750',
|
||||
}))
|
||||
end
|
||||
|
||||
it do
|
||||
should contain_file("#{fragdir}/fragments").with(file_defaults.merge({
|
||||
:ensure => 'directory',
|
||||
:mode => '0750',
|
||||
:force => true,
|
||||
:ignore => ['.svn', '.git', '.gitignore'],
|
||||
:purge => true,
|
||||
:recurse => true,
|
||||
}))
|
||||
end
|
||||
|
||||
[
|
||||
"#{fragdir}/fragments.concat",
|
||||
"#{fragdir}/#{concat_name}",
|
||||
].each do |file|
|
||||
it do
|
||||
should contain_file(file).with(file_defaults.merge({
|
||||
:ensure => 'present',
|
||||
:mode => '0640',
|
||||
}))
|
||||
end
|
||||
end
|
||||
|
||||
it do
|
||||
should contain_file(title).with(file_defaults.merge({
|
||||
:ensure => 'present',
|
||||
:owner => p[:owner],
|
||||
:group => p[:group],
|
||||
:mode => p[:mode],
|
||||
:replace => p[:replace],
|
||||
:path => p[:path],
|
||||
:alias => "concat_#{title}",
|
||||
:source => "#{fragdir}/#{concat_name}",
|
||||
:backup => p[:backup],
|
||||
}))
|
||||
end
|
||||
|
||||
cmd = "#{concatdir}/bin/concatfragments.sh " +
|
||||
"-o \"#{concatdir}/#{safe_name}/fragments.concat.out\" " +
|
||||
"-d \"#{concatdir}/#{safe_name}\""
|
||||
|
||||
# flag order: fragdir, warnflag, forceflag, orderflag, newlineflag
|
||||
if p.has_key?(:warn)
|
||||
case p[:warn]
|
||||
when TrueClass
|
||||
message = default_warn_message
|
||||
when 'true', 'yes', 'on'
|
||||
# should generate a stringified boolean warning
|
||||
message = default_warn_message
|
||||
when FalseClass
|
||||
message = nil
|
||||
when 'false', 'no', 'off'
|
||||
# should generate a stringified boolean warning
|
||||
message = nil
|
||||
else
|
||||
message = p[:warn]
|
||||
end
|
||||
|
||||
unless message.nil?
|
||||
cmd += " -w \'#{message}\'"
|
||||
end
|
||||
end
|
||||
|
||||
cmd += " -f" if p[:force]
|
||||
cmd += " -n" if p[:order] == 'numeric'
|
||||
cmd += " -l" if p[:ensure_newline] == true
|
||||
|
||||
it do
|
||||
should contain_exec("concat_#{title}").with({
|
||||
:alias => "concat_#{fragdir}",
|
||||
:command => cmd,
|
||||
:unless => "#{cmd} -t",
|
||||
})
|
||||
end
|
||||
else
|
||||
[
|
||||
fragdir,
|
||||
"#{fragdir}/fragments",
|
||||
"#{fragdir}/fragments.concat",
|
||||
"#{fragdir}/#{concat_name}",
|
||||
].each do |file|
|
||||
it do
|
||||
should contain_file(file).with(file_defaults.merge({
|
||||
:ensure => 'absent',
|
||||
:backup => false,
|
||||
:force => true,
|
||||
}))
|
||||
end
|
||||
end
|
||||
|
||||
it do
|
||||
should contain_file(title).with(file_defaults.merge({
|
||||
:ensure => 'absent',
|
||||
:backup => p[:backup],
|
||||
}))
|
||||
end
|
||||
|
||||
it do
|
||||
should contain_exec("concat_#{title}").with({
|
||||
:alias => "concat_#{fragdir}",
|
||||
:command => 'true',
|
||||
:path => '/bin:/usr/bin',
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'title' do
|
||||
context 'without path param' do
|
||||
# title/name is the default value for the path param. therefore, the
|
||||
# title must be an absolute path unless path is specified
|
||||
['/foo', '/foo/bar', '/foo/bar/baz'].each do |title|
|
||||
context title do
|
||||
it_behaves_like 'concat', '/etc/foo.bar'
|
||||
end
|
||||
end
|
||||
|
||||
['./foo', 'foo', 'foo/bar'].each do |title|
|
||||
context title do
|
||||
let(:title) { title }
|
||||
it 'should fail' do
|
||||
expect { should }.to raise_error(Puppet::Error, /is not an absolute path/)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with path param' do
|
||||
['./foo', 'foo', 'foo/bar'].each do |title|
|
||||
context title do
|
||||
it_behaves_like 'concat', title, { :path => '/etc/foo.bar' }
|
||||
end
|
||||
end
|
||||
end
|
||||
end # title =>
|
||||
|
||||
context 'as non-root user' do
|
||||
it_behaves_like 'concat', '/etc/foo.bar', {}, 'bob'
|
||||
end
|
||||
|
||||
context 'ensure =>' do
|
||||
['present', 'absent'].each do |ens|
|
||||
context ens do
|
||||
it_behaves_like 'concat', '/etc/foo.bar', { :ensure => ens }
|
||||
end
|
||||
end
|
||||
|
||||
context 'invalid' do
|
||||
let(:title) { '/etc/foo.bar' }
|
||||
let(:params) {{ :ensure => 'invalid' }}
|
||||
it 'should fail' do
|
||||
expect { should }.to raise_error(Puppet::Error, /#{Regexp.escape('does not match "^present$|^absent$"')}/)
|
||||
end
|
||||
end
|
||||
end # ensure =>
|
||||
|
||||
context 'path =>' do
|
||||
context '/foo' do
|
||||
it_behaves_like 'concat', '/etc/foo.bar', { :path => '/foo' }
|
||||
end
|
||||
|
||||
['./foo', 'foo', 'foo/bar', false].each do |path|
|
||||
context path do
|
||||
let(:title) { '/etc/foo.bar' }
|
||||
let(:params) {{ :path => path }}
|
||||
it 'should fail' do
|
||||
expect { should }.to raise_error(Puppet::Error, /is not an absolute path/)
|
||||
end
|
||||
end
|
||||
end
|
||||
end # path =>
|
||||
|
||||
context 'owner =>' do
|
||||
context 'apenney' do
|
||||
it_behaves_like 'concat', '/etc/foo.bar', { :owner => 'apenny' }
|
||||
end
|
||||
|
||||
context 'false' do
|
||||
let(:title) { '/etc/foo.bar' }
|
||||
let(:params) {{ :owner => false }}
|
||||
it 'should fail' do
|
||||
expect { should }.to raise_error(Puppet::Error, /is not a string/)
|
||||
end
|
||||
end
|
||||
end # owner =>
|
||||
|
||||
context 'group =>' do
|
||||
context 'apenney' do
|
||||
it_behaves_like 'concat', '/etc/foo.bar', { :group => 'apenny' }
|
||||
end
|
||||
|
||||
context 'false' do
|
||||
let(:title) { '/etc/foo.bar' }
|
||||
let(:params) {{ :group => false }}
|
||||
it 'should fail' do
|
||||
expect { should }.to raise_error(Puppet::Error, /is not a string/)
|
||||
end
|
||||
end
|
||||
end # group =>
|
||||
|
||||
context 'mode =>' do
|
||||
context '1755' do
|
||||
it_behaves_like 'concat', '/etc/foo.bar', { :mode => '1755' }
|
||||
end
|
||||
|
||||
context 'false' do
|
||||
let(:title) { '/etc/foo.bar' }
|
||||
let(:params) {{ :mode => false }}
|
||||
it 'should fail' do
|
||||
expect { should }.to raise_error(Puppet::Error, /is not a string/)
|
||||
end
|
||||
end
|
||||
end # mode =>
|
||||
|
||||
context 'warn =>' do
|
||||
[true, false, '# foo'].each do |warn|
|
||||
context warn do
|
||||
it_behaves_like 'concat', '/etc/foo.bar', { :warn => warn }
|
||||
end
|
||||
end
|
||||
|
||||
context '(stringified boolean)' do
|
||||
['true', 'yes', 'on', 'false', 'no', 'off'].each do |warn|
|
||||
context warn do
|
||||
it_behaves_like 'concat', '/etc/foo.bar', { :warn => warn }
|
||||
|
||||
it 'should create a warning' do
|
||||
pending('rspec-puppet support for testing warning()')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context '123' do
|
||||
let(:title) { '/etc/foo.bar' }
|
||||
let(:params) {{ :warn => 123 }}
|
||||
it 'should fail' do
|
||||
expect { should }.to raise_error(Puppet::Error, /is not a string or boolean/)
|
||||
end
|
||||
end
|
||||
end # warn =>
|
||||
|
||||
context 'force =>' do
|
||||
[true, false].each do |force|
|
||||
context force do
|
||||
it_behaves_like 'concat', '/etc/foo.bar', { :force => force }
|
||||
end
|
||||
end
|
||||
|
||||
context '123' do
|
||||
let(:title) { '/etc/foo.bar' }
|
||||
let(:params) {{ :force => 123 }}
|
||||
it 'should fail' do
|
||||
expect { should }.to raise_error(Puppet::Error, /is not a boolean/)
|
||||
end
|
||||
end
|
||||
end # force =>
|
||||
|
||||
context 'backup =>' do
|
||||
context 'reverse' do
|
||||
it_behaves_like 'concat', '/etc/foo.bar', { :backup => 'reverse' }
|
||||
end
|
||||
|
||||
context 'false' do
|
||||
let(:title) { '/etc/foo.bar' }
|
||||
let(:params) {{ :backup => false }}
|
||||
it 'should fail' do
|
||||
expect { should }.to raise_error(Puppet::Error, /is not a string/)
|
||||
end
|
||||
end
|
||||
end # backup =>
|
||||
|
||||
context 'replace =>' do
|
||||
[true, false].each do |replace|
|
||||
context replace do
|
||||
it_behaves_like 'concat', '/etc/foo.bar', { :replace => replace }
|
||||
end
|
||||
end
|
||||
|
||||
context '123' do
|
||||
let(:title) { '/etc/foo.bar' }
|
||||
let(:params) {{ :replace => 123 }}
|
||||
it 'should fail' do
|
||||
expect { should }.to raise_error(Puppet::Error, /is not a boolean/)
|
||||
end
|
||||
end
|
||||
end # replace =>
|
||||
|
||||
context 'order =>' do
|
||||
['alpha', 'numeric'].each do |order|
|
||||
context order do
|
||||
it_behaves_like 'concat', '/etc/foo.bar', { :order => order }
|
||||
end
|
||||
end
|
||||
|
||||
context 'invalid' do
|
||||
let(:title) { '/etc/foo.bar' }
|
||||
let(:params) {{ :order => 'invalid' }}
|
||||
it 'should fail' do
|
||||
expect { should }.to raise_error(Puppet::Error, /#{Regexp.escape('does not match "^alpha$|^numeric$"')}/)
|
||||
end
|
||||
end
|
||||
end # order =>
|
||||
|
||||
context 'ensure_newline =>' do
|
||||
[true, false].each do |ensure_newline|
|
||||
context 'true' do
|
||||
it_behaves_like 'concat', '/etc/foo.bar', { :ensure_newline => ensure_newline}
|
||||
end
|
||||
end
|
||||
|
||||
context '123' do
|
||||
let(:title) { '/etc/foo.bar' }
|
||||
let(:params) {{ :ensure_newline => 123 }}
|
||||
it 'should fail' do
|
||||
expect { should }.to raise_error(Puppet::Error, /is not a boolean/)
|
||||
end
|
||||
end
|
||||
end # ensure_newline =>
|
||||
|
||||
describe 'deprecated parameter' do
|
||||
context 'gnu =>' do
|
||||
context 'foo' do
|
||||
it_behaves_like 'concat', '/etc/foo.bar', { :gnu => 'foo'}
|
||||
|
||||
it 'should create a warning' do
|
||||
pending('rspec-puppet support for testing warning()')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# vim:sw=2:ts=2:expandtab:textwidth=79
|
18
modules/concat/spec/unit/facts/concat_basedir_spec.rb
Normal file
18
modules/concat/spec/unit/facts/concat_basedir_spec.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'concat_basedir', :type => :fact do
|
||||
before(:each) { Facter.clear }
|
||||
|
||||
context 'Puppet[:vardir] ==' do
|
||||
it '/var/lib/puppet' do
|
||||
Puppet.stubs(:[]).with(:vardir).returns('/var/lib/puppet')
|
||||
Facter.fact(:concat_basedir).value.should == '/var/lib/puppet/concat'
|
||||
end
|
||||
|
||||
it '/home/apenny/.puppet/var' do
|
||||
Puppet.stubs(:[]).with(:vardir).returns('/home/apenny/.puppet/var')
|
||||
Facter.fact(:concat_basedir).value.should == '/home/apenny/.puppet/var/concat'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
19
modules/concat/tests/fragment.pp
Normal file
19
modules/concat/tests/fragment.pp
Normal file
|
@ -0,0 +1,19 @@
|
|||
concat { 'testconcat':
|
||||
ensure => present,
|
||||
path => '/tmp/concat',
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0664',
|
||||
}
|
||||
|
||||
concat::fragment { '1':
|
||||
target => 'testconcat',
|
||||
content => '1',
|
||||
order => '01',
|
||||
}
|
||||
|
||||
concat::fragment { '2':
|
||||
target => 'testconcat',
|
||||
content => '2',
|
||||
order => '02',
|
||||
}
|
7
modules/concat/tests/init.pp
Normal file
7
modules/concat/tests/init.pp
Normal file
|
@ -0,0 +1,7 @@
|
|||
concat { '/tmp/concat':
|
||||
ensure => present,
|
||||
force => true,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue