Update logrotate cookbook

This commit is contained in:
Greg 2017-05-02 11:58:32 +02:00
parent 180b3f5df0
commit ccbf11a407
23 changed files with 679 additions and 506 deletions

2
Batali
View File

@ -36,6 +36,6 @@ Batali.define do
cookbook 'timezone-ii'
cookbook 'nodejs', '~> 3.0.0'
cookbook 'ark', '~> 3.0.0'
cookbook 'logrotate'
cookbook 'logrotate', '~> 2.1.0'
cookbook 'openssl', '~> 7.0.1'
end

View File

@ -1035,18 +1035,6 @@
"version": "3.0.0"
}
},
{
"name": "homebrew",
"dependencies": [
],
"version": "3.0.0",
"source": {
"type": "Batali::Source::Site",
"url": "https://supermarket.chef.io:443/api/v1/cookbooks/homebrew/versions/3.0.0/download",
"version": "3.0.0"
}
},
{
"name": "ark",
"dependencies": [
@ -1071,15 +1059,30 @@
}
},
{
"name": "logrotate",
"name": "homebrew",
"dependencies": [
],
"version": "1.9.2",
"version": "3.0.0",
"source": {
"type": "Batali::Source::Site",
"url": "https://supermarket.chef.io:443/api/v1/cookbooks/logrotate/versions/1.9.2/download",
"version": "1.9.2"
"url": "https://supermarket.chef.io:443/api/v1/cookbooks/homebrew/versions/3.0.0/download",
"version": "3.0.0"
}
},
{
"name": "logrotate",
"dependencies": [
[
"compat_resource",
">= 0.0.0"
]
],
"version": "2.1.0",
"source": {
"type": "Batali::Source::Site",
"url": "https://supermarket.chef.io:443/api/v1/cookbooks/logrotate/versions/2.1.0/download",
"version": "2.1.0"
}
}
]

View File

@ -6,7 +6,7 @@ platforms:
- name: ubuntu-12.04
run_list:
- recipe[fake::prep]
- name: centos-6.5
- name: centos-6.7
suites:
- name: default

View File

@ -1,6 +1,10 @@
sudo: false
branches:
only:
- master
language: ruby
cache: bundler
rvm:
- 2.0.0
- 2.2
script:
- bundle exec foodcritic -f any . --tags ~FC015
- bundle exec rspec --color --format progress
- bundle exec rubocop -l
- make travis

View File

@ -0,0 +1,7 @@
source "https://supermarket.getchef.com"
metadata
group :development do
cookbook "fake", path: "test/fixtures/cookbooks/fake"
end

View File

@ -3,6 +3,64 @@ logrotate Cookbook CHANGELOG
This file is used to list changes made in each version of the
logrotate cookbook.
v2.1.0
------
# Bug Fixes
- Restore `cookbook` parameter for `logrotate_app` resource due to
popular demand.
- Add a `template_name` parameter to replace the 1.x `template`
parameter. The name `template` can't be used inside a resource
without conflicting with an attribute of the same name.
- Fix exception when `options` specified as a string rather than an
array
v2.0.0
------
- Convert the logrotate_app definition to a resource
- Accept all options included in logrotate 3.9.2
# Known incompatibilities
- The `cookbook` parameter to `logrotate_app` is no longer accepted.
v1.9.2
------
## Bug Fixes
- Fix deprecation warnings from ChefSpec
v1.9.1
------
## Bug Fixes
- Fixes regression in the sharedscripts logrotate_app
parameter (Bug #69)
v1.9.0
------
### Improvements
- All configuration options from the logrotate 3.8.8 manual page can
be used by the global configuration and the logrotate_app
definition.
- Berkshelf is no longer a development dependency of the
logrotate cookbook.
- Rubocop lint failures have been resolved.
v1.8.0
------

View File

@ -11,6 +11,36 @@
- Please ensure all tests and lint checking pass before submitting
pull requests.
## Testing
## Development
Please read TESTING.md for details on testing this cookbook.
### Requirements
- Ruby 2.0+
- Bundler (`gem install bundler`)
- [Vagrant](https://vagrantup.com)
- [VirtualBox](https://virtualbox.org)
### Development Flow
1. Clone the git repository from GitHub:
$ git clone git@github.com:stevendanna/logrotate.git
2. Install the dependencies using bundler:
$ bundle install
3. Create a branch for your changes:
$ git checkout -b my_bug_fix
4. Make any changes
5. Write tests to support those changes. It is highly recommended you
write both unit and integration tests.
6. Run the tests:
- `make travis`
- `kitchen test`
7. Assuming the tests pass, open a Pull Request on GitHub

View File

@ -1,9 +1,11 @@
source 'https://rubygems.org'
gem 'chefspec', '~> 4.0'
gem 'foodcritic', '~> 4.0'
gem 'rubocop', '~> 0.12'
source "https://rubygems.org"
gem "berkshelf", "~> 4.0"
gem "chefspec", "~> 4.0"
gem "foodcritic", "~> 6.0"
gem "chefstyle", github: "chef/chefstyle"
group :integration do
gem 'test-kitchen', '~> 1.0'
gem 'kitchen-vagrant', '~> 0.11'
gem "test-kitchen", "~> 1.0"
gem "kitchen-vagrant", "~> 0.11"
end

View File

@ -1,141 +1,262 @@
GIT
remote: git://github.com/chef/chefstyle.git
revision: cc37808b7849fdcf49f04011626143940f83fe92
specs:
chefstyle (0.3.1)
rubocop (= 0.39.0)
GEM
remote: https://rubygems.org/
specs:
ast (2.0.0)
astrolabe (1.3.0)
parser (>= 2.2.0.pre.3, < 3.0)
chef (12.0.3)
chef-zero (~> 3.2)
addressable (2.4.0)
artifactory (2.3.2)
ast (2.2.0)
berkshelf (4.3.2)
addressable (~> 2.3, >= 2.3.4)
berkshelf-api-client (~> 2.0, >= 2.0.2)
buff-config (~> 1.0)
buff-extensions (~> 1.0)
buff-shell_out (~> 0.1)
celluloid (= 0.16.0)
celluloid-io (~> 0.16.1)
cleanroom (~> 1.0)
faraday (~> 0.9)
httpclient (~> 2.7)
minitar (~> 0.5, >= 0.5.4)
octokit (~> 4.0)
retryable (~> 2.0)
ridley (~> 4.5)
solve (~> 2.0)
thor (~> 0.19)
berkshelf-api-client (2.0.2)
faraday (~> 0.9.1)
httpclient (~> 2.7.0)
ridley (~> 4.5)
buff-config (1.0.1)
buff-extensions (~> 1.0)
varia_model (~> 0.4)
buff-extensions (1.0.0)
buff-ignore (1.1.1)
buff-ruby_engine (0.1.0)
buff-shell_out (0.2.0)
buff-ruby_engine (~> 0.1.0)
builder (3.2.2)
celluloid (0.16.0)
timers (~> 4.0.0)
celluloid-io (0.16.2)
celluloid (>= 0.16.0)
nio4r (>= 1.1.0)
chef (12.9.38)
bundler (>= 1.10)
chef-config (= 12.9.38)
chef-zero (~> 4.5)
diff-lcs (~> 1.2, >= 1.2.4)
erubis (~> 2.7)
ffi-yajl (~> 1.2)
ffi-yajl (~> 2.2)
highline (~> 1.6, >= 1.6.9)
mixlib-authentication (~> 1.3)
mixlib-authentication (~> 1.4)
mixlib-cli (~> 1.4)
mixlib-config (~> 2.0)
mixlib-log (~> 1.3)
mixlib-shellout (>= 2.0.0.rc.0, < 3.0)
net-ssh (~> 2.6)
mixlib-shellout (~> 2.0)
net-sftp (~> 2.1, >= 2.1.2)
net-ssh (>= 2.9, < 4.0)
net-ssh-multi (~> 1.1)
ohai (~> 8.0)
plist (~> 3.1.0)
pry (~> 0.9)
chef-zero (3.2.1)
ffi-yajl (~> 1.1)
hashie (~> 2.0)
ohai (>= 8.6.0.alpha.1, < 9)
plist (~> 3.2)
proxifier (~> 1.0)
rspec-core (~> 3.4)
rspec-expectations (~> 3.4)
rspec-mocks (~> 3.4)
rspec_junit_formatter (~> 0.2.0)
serverspec (~> 2.7)
specinfra (~> 2.10)
syslog-logger (~> 1.6)
uuidtools (~> 2.1.5)
chef-config (12.9.38)
fuzzyurl (~> 0.8.0)
mixlib-config (~> 2.0)
mixlib-shellout (~> 2.0)
chef-zero (4.6.1)
ffi-yajl (~> 2.2)
hashie (>= 2.0, < 4.0)
mixlib-log (~> 1.3)
rack
uuidtools (~> 2.1)
chefspec (4.2.0)
chefspec (4.6.1)
chef (>= 11.14)
fauxhai (~> 2.0)
fauxhai (~> 3.2)
rspec (~> 3.0)
coderay (1.1.0)
cleanroom (1.0.0)
cucumber-core (1.4.0)
gherkin (~> 3.2.0)
diff-lcs (1.2.5)
erubis (2.7.0)
fauxhai (2.3.0)
faraday (0.9.2)
multipart-post (>= 1.2, < 3)
fauxhai (3.3.0)
net-ssh
ohai
ffi (1.9.6)
ffi-yajl (1.4.0)
ffi (~> 1.5)
ffi (1.9.10)
ffi-yajl (2.2.3)
libyajl2 (~> 1.2)
foodcritic (4.0.0)
foodcritic (6.1.1)
cucumber-core (>= 1.3)
erubis
gherkin (~> 2.11)
nokogiri (~> 1.5)
nokogiri (>= 1.5, < 2.0)
rake
rufus-lru (~> 1.0)
treetop (~> 1.4)
yajl-ruby (~> 1.1)
gherkin (2.12.2)
multi_json (~> 1.3)
hashie (2.1.2)
highline (1.7.1)
ipaddress (0.8.0)
kitchen-vagrant (0.15.0)
test-kitchen (~> 1.0)
fuzzyurl (0.8.0)
gherkin (3.2.0)
hashie (3.4.3)
highline (1.7.8)
hitimes (1.2.3)
httpclient (2.7.1)
ipaddress (0.8.3)
json (1.8.3)
kitchen-vagrant (0.20.0)
test-kitchen (~> 1.4)
libyajl2 (1.2.0)
method_source (0.8.2)
mime-types (2.4.3)
mini_portile (0.6.2)
mixlib-authentication (1.3.0)
mini_portile2 (2.0.0)
minitar (0.5.4)
mixlib-authentication (1.4.0)
mixlib-log
rspec-core (~> 3.2)
rspec-expectations (~> 3.2)
rspec-mocks (~> 3.2)
mixlib-cli (1.5.0)
mixlib-config (2.1.0)
mixlib-config (2.2.1)
mixlib-install (1.0.7)
artifactory
mixlib-shellout
mixlib-versioning
mixlib-log (1.6.0)
mixlib-shellout (2.0.1)
multi_json (1.10.1)
net-dhcp (1.3.2)
mixlib-shellout (2.2.6)
mixlib-versioning (1.1.0)
molinillo (0.4.4)
multi_json (1.11.2)
multipart-post (2.0.0)
net-scp (1.2.1)
net-ssh (>= 2.6.5)
net-ssh (2.9.2)
net-sftp (2.1.2)
net-ssh (>= 2.6.5)
net-ssh (3.1.1)
net-ssh-gateway (1.2.0)
net-ssh (>= 2.6.5)
net-ssh-multi (1.2.0)
net-ssh-multi (1.2.1)
net-ssh (>= 2.6.5)
net-ssh-gateway (>= 1.2.0)
nokogiri (1.6.6.2)
mini_portile (~> 0.6.0)
ohai (8.1.1)
net-telnet (0.1.1)
nio4r (1.2.1)
nokogiri (1.6.7.2)
mini_portile2 (~> 2.0.0.rc2)
octokit (4.3.0)
sawyer (~> 0.7.0, >= 0.5.3)
ohai (8.14.0)
chef-config (>= 12.5.0.alpha.1, < 13)
ffi (~> 1.9)
ffi-yajl (~> 1.1)
ffi-yajl (~> 2.2)
ipaddress
mime-types (~> 2.0)
mixlib-cli
mixlib-config (~> 2.0)
mixlib-log
mixlib-shellout (~> 2.0)
net-dhcp
rake (~> 10.1)
plist (~> 3.1)
systemu (~> 2.6.4)
wmi-lite (~> 1.0)
parser (2.2.0.3)
ast (>= 1.1, < 3.0)
plist (3.1.0)
parser (2.3.0.7)
ast (~> 2.2)
plist (3.2.0)
polyglot (0.3.5)
powerpack (0.1.0)
pry (0.10.1)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
rack (1.6.0)
rainbow (2.0.0)
rake (10.4.2)
rspec (3.2.0)
rspec-core (~> 3.2.0)
rspec-expectations (~> 3.2.0)
rspec-mocks (~> 3.2.0)
rspec-core (3.2.0)
rspec-support (~> 3.2.0)
rspec-expectations (3.2.0)
powerpack (0.1.1)
proxifier (1.0.3)
rack (1.6.4)
rainbow (2.1.0)
rake (11.1.2)
retryable (2.0.3)
ridley (4.5.0)
addressable
buff-config (~> 1.0)
buff-extensions (~> 1.0)
buff-ignore (~> 1.1)
buff-shell_out (~> 0.1)
celluloid (~> 0.16.0)
celluloid-io (~> 0.16.1)
chef-config (>= 12.5.0)
erubis
faraday (~> 0.9.0)
hashie (>= 2.0.2, < 4.0.0)
httpclient (~> 2.7)
json (>= 1.7.7)
mixlib-authentication (>= 1.3.0)
retryable (~> 2.0)
semverse (~> 1.1)
varia_model (~> 0.4.0)
rspec (3.4.0)
rspec-core (~> 3.4.0)
rspec-expectations (~> 3.4.0)
rspec-mocks (~> 3.4.0)
rspec-core (3.4.4)
rspec-support (~> 3.4.0)
rspec-expectations (3.4.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.2.0)
rspec-mocks (3.2.0)
rspec-support (~> 3.4.0)
rspec-its (1.2.0)
rspec-core (>= 3.0.0)
rspec-expectations (>= 3.0.0)
rspec-mocks (3.4.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.2.0)
rspec-support (3.2.1)
rubocop (0.29.1)
astrolabe (~> 1.3)
parser (>= 2.2.0.1, < 3.0)
rspec-support (~> 3.4.0)
rspec-support (3.4.1)
rspec_junit_formatter (0.2.3)
builder (< 4)
rspec-core (>= 2, < 4, != 2.12.0)
rubocop (0.39.0)
parser (>= 2.3.0.7, < 3.0)
powerpack (~> 0.1)
rainbow (>= 1.99.1, < 3.0)
ruby-progressbar (~> 1.4)
ruby-progressbar (1.7.1)
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1)
ruby-progressbar (1.7.5)
rufus-lru (1.0.5)
safe_yaml (1.0.4)
slop (3.6.0)
systemu (2.6.4)
test-kitchen (1.3.1)
sawyer (0.7.0)
addressable (>= 2.3.5, < 2.5)
faraday (~> 0.8, < 0.10)
semverse (1.2.1)
serverspec (2.31.1)
multi_json
rspec (~> 3.0)
rspec-its
specinfra (~> 2.53)
sfl (2.2)
solve (2.0.3)
molinillo (~> 0.4.2)
semverse (~> 1.1)
specinfra (2.56.1)
net-scp
net-ssh (>= 2.7, < 4.0)
net-telnet
sfl
syslog-logger (1.6.8)
systemu (2.6.5)
test-kitchen (1.7.3)
mixlib-install (~> 1.0, >= 1.0.4)
mixlib-shellout (>= 1.2, < 3.0)
net-scp (~> 1.1)
net-ssh (~> 2.7)
net-ssh (>= 2.9, < 4.0)
safe_yaml (~> 1.0)
thor (~> 0.18)
thor (0.19.1)
treetop (1.5.3)
timers (4.0.4)
hitimes
treetop (1.6.5)
polyglot (~> 0.3)
unicode-display_width (1.0.3)
uuidtools (2.1.5)
varia_model (0.4.1)
buff-extensions (~> 1.0)
hashie (>= 2.0.2, < 4.0.0)
wmi-lite (1.0.0)
yajl-ruby (1.2.1)
@ -143,8 +264,12 @@ PLATFORMS
ruby
DEPENDENCIES
berkshelf (~> 4.0)
chefspec (~> 4.0)
foodcritic (~> 4.0)
chefstyle!
foodcritic (~> 6.0)
kitchen-vagrant (~> 0.11)
rubocop (~> 0.12)
test-kitchen (~> 1.0)
BUNDLED WITH
1.11.2

View File

@ -186,7 +186,9 @@ APPENDIX: How to apply the Apache License to your work.
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright 2009-2013, Chef Software, Inc.
Copyright 2015-2016, Steven Danna
Copyright 2016, Bloomberg Finance L.P.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@ -0,0 +1,13 @@
travis: bundle berks
bundle exec chefstyle -D
bundle exec foodcritic .
bundle exec rspec --color --format doc
integration: bundle berks
bundle exec kitchen test
bundle:
bundle install
berks:
bundle exec berks install

View File

@ -1,41 +1,53 @@
logrotate Cookbook
==================
# logrotate Cookbook
[![Build Status](https://secure.travis-ci.org/stevendanna/logrotate.png?branch=master)](http://travis-ci.org/stevendanna/logrotate)
Manages the logrotate package and provides a definition to manage application specific logrotate configuration.
Manages the logrotate package and provides a definition to manage
application specific logrotate configuration.
Requirements
------------
Should work on any platform that includes a 'logrotate' package and writes logrotate configuration to /etc/logrotate.d. Tested on Ubuntu, Debian and Red Hat/CentOS.
## Requirements
Should work on any platform that includes a 'logrotate' package and
writes logrotate configuration to /etc/logrotate.d. Tested on Ubuntu
and Centos.
Recipes
-------
## Recipes
### global
Generates and controls a global `/etc/logrotate.conf` file that will include additional files generated by the `logrotate_app` definition (see below). The contents of the configuration file is controlled through node attributes under `node['logrotate']['global']`. The default attributes are based on the configuration from the Ubuntu logrotate package.
To define a valueless directive (e.g. `compress`, `copy`) simply add an attribute named for the directive with a truthy value :
Generates and controls a global `/etc/logrotate.conf` file that will
include additional files generated by the `logrotate_app` definition
(see below). The contents of the configuration file is controlled
through node attributes under `node['logrotate']['global']`. The
default attributes are based on the configuration from the Ubuntu
logrotate package.
To define a valueless directive (e.g. `compress`, `copy`) simply add
an attribute named for the directive with a truthy value:
```ruby
node['logrotate']['global']['compress'] = 'any value here'
```
Note that defining a valueless directive with a falsey value will not make it false, but will remove it:
Note that defining a valueless directive with a falsey value will not
make it false, but will remove it:
```ruby
# Removes a defaulted 'compress' directive; does not add a 'nocompress' directive.
node.override['logrotate']['global']['compress'] = false
```
To fully override a booleanish directive like `compress`, you should probably remove the positive form and add the negative form:
To fully override a booleanish directive like `compress`, you should
probably remove the positive form and add the negative form:
```ruby
node.override['logrotate']['global']['compress'] = false
node.override['logrotate']['global']['nocompress'] = true
```
The same is true of frequency directives; to be certain the frequency directive you want is included in the global configuration, you should override the ones you don't want as false:
The same is true of frequency directives; to be certain the frequency
directive you want is included in the global configuration, you should
override the ones you don't want as false:
```ruby
%w[ daily weekly yearly ].each do |freq|
@ -44,13 +56,17 @@ end
node.override['logrotate']['global']['monthly'] = true
```
To define a parameter with a value (e.g. `create`, `mail`) add an attribute with the desired value:
To define a parameter with a value (e.g. `create`, `mail`) add an
attribute with the desired value:
```ruby
node['logrotate']['global']['create'] = '0644 root adm'
```
To define a path stanza in the global configuration (generally unneeded because of the `logrotate_app` definition) just add an attribute with the path as the name and a hash containing directives and parameters as described above:
To define a path stanza in the global configuration (generally
unneeded because of the `logrotate_app` definition) just add an
attribute with the path as the name and a hash containing directives
and parameters as described above:
```ruby
node['logrotate']['global']['/var/log/wtmp'] = {
@ -61,7 +77,9 @@ node['logrotate']['global']['/var/log/wtmp'] = {
}
```
`firstaction`, `prerotate`, `postrotate`, and `lastaction` scripts can be defined either as arrays of the lines to put in the script or multiline strings:
`firstaction`, `prerotate`, `postrotate`, and `lastaction` scripts can
be defined either as arrays of the lines to put in the script or
multiline strings:
```ruby
node['logrotate']['global']['/var/log/foo/*.log'] = {
@ -78,43 +96,76 @@ node['logrotate']['global']['/var/log/foo/*.log'] = {
```
Definitions
Resources
-----------
### logrotate_app
This definition can be used to drop off customized logrotate config files on a per application basis.
The definition takes the following params:
This resource can be used to drop off customized logrotate config
files on a per application basis.
- `path`: specifies a single path (string) or multiple paths (array) that should have logrotation stanzas created in the config file. No default, this must be specified.
- `enable`: true/false, if true it will create the template in /etc/logrotate.d.
- `frequency`: sets the frequency for rotation. Default value is 'weekly'. Valid values are: daily, weekly, monthly, yearly, see the logrotate man page for more information.
- `dateformat`: specifies date extension with %Y, %m, %d, and %s. The default value is -%Y%m%d.
- `size`: Log files are rotated when they grow bigger than size bytes.
- `maxsize`: Log files are rotated when they grow bigger than size bytes even before the additionally specified time interval.
- `su`: Rotate log files set under this user and group instead of using default user/group.
- `template`: sets the template source, default is "logrotate.erb".
- `template_mode`: the mode to create the logrotate template with (default "0440")
- `template_owner`: the owner of the logrotate template (default "root")
- `template_group`: the group of the logrotate template (default "root")
- `cookbook`: select the template source from the specified cookbook. By default it will use the template from the logrotate cookbook.
- `create`: creation parameters for the logrotate "create" config, follows the form "mode owner group". This is an optional parameter, and is nil by default.
- `firstaction`: lines to be executed once before all log files that match the wildcarded pattern are rotated, before pre-rotate script is run and only if at least one log will actually be rotated
- `postrotate`: lines to be executed after the log file is rotated
- `prerotate`: lines to be executed before the log file is rotated
- `lastaction`: lines to be executed once after all log files that match the wildcarded pattern are rotated, after postrotate script is run and only if at least one log is rotated
- `rotate`: Log files are rotated this many times before being removed or mailed.
- `sharedscripts`: if true, the sharedscripts options is specified which makes sure prescript and postscript commands are run only once (even if multiple files match the path)
The resource takes the following properties:
- `path`: specifies a single path (string) or multiple paths (array)
that should have logrotation stanzas created in the config file. No
default, this must be specified.
Usage
-----
The default recipe will ensure logrotate is always up to date.
- `cookbook`: The cookbook that continues the template for
logrotate_app config definitions. By default this is `logrotate`.
Users can provide their own template by setting this attribute to
point at a different cookbook.
To create application specific logrotate configs, use the `logrotate_app` definition. For example, to rotate logs for a tomcat application named myapp that writes its log file to `/var/log/tomcat/myapp.log`:
- `template_name`: sets the template source, default is
"logrotate.erb".
- `template_mode`: the mode to create the logrotate template with
(default: "0440")
- `template_owner`: the owner of the logrotate template (default:
"root")
- `template_group`: the group of the logrotate template (default:
"root")
- `frequency`: sets the frequency for rotation. Default value is
'weekly'. Valid values are: hourly, daily, weekly, monthly, yearly,
see the logrotate man page for more information. Note that usually
logrotate is configured to be run by cron daily. You have to change
this configuration and run logrotate hourly to be able to really
rotate logs hourly. Hourly rotation requires logrotate v3.8.5 or
higher.
- `options`: Any logrotate configuration option that doesn't specify a
value. See the logrotate(8) manual page of v3.9.2 or earlier for
details.
In addition to these properties, any logrotate option that takes a
parameter can be used as a logrotate_app property. For example, to set
the `rotate` option you can use a resource declaration such as:
```ruby
logrotate_app 'tomcat-myapp' do
path '/var/log/tomcat/myapp.log'
frequency 'daily'
rotate 30
create '644 root adm'
end
```
See the logrotate(8) manual page of v3.9.2 or earlier for the list of
available options.
## Usage
The default recipe will ensure logrotate is always up to date.
To create application specific logrotate configs, use the
`logrotate_app` definition. For example, to rotate logs for a tomcat
application named myapp that writes its log file to
`/var/log/tomcat/myapp.log`:
```ruby
logrotate_app 'tomcat-myapp' do
cookbook 'logrotate'
path '/var/log/tomcat/myapp.log'
frequency 'daily'
rotate 30
@ -126,7 +177,6 @@ To rotate multiple logfile paths, specify the path as an array:
```ruby
logrotate_app 'tomcat-myapp' do
cookbook 'logrotate'
path ['/var/log/tomcat/myapp.log', '/opt/local/tomcat/catalina.out']
frequency 'daily'
create '644 root adm'
@ -138,7 +188,6 @@ To specify which logrotate options, specify the options as an array:
```ruby
logrotate_app 'tomcat-myapp' do
cookbook 'logrotate'
path '/var/log/tomcat/myapp.log'
options ['missingok', 'delaycompress', 'notifempty']
frequency 'daily'
@ -147,15 +196,16 @@ logrotate_app 'tomcat-myapp' do
end
```
## License & Authors
License & Authors
-----------------
- Author:: Steven Danna (<steve@chef.io>)
- Author:: Scott M. Likens (<scott@likens.us>)
- Author:: Joshua Timberman (<joshua@chef.io>)
```text
Copyright 2009, Scott M. Likens
Copyright 2011-2012, Chef Software, Inc.
Copyright 2016, Steven Danna
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@ -1,49 +0,0 @@
This cookbook uses a variety of testing components:
- Unit tests: [ChefSpec](https://github.com/acrmp/chefspec)
- Integration tests: [Test Kitchen](https://github.com/chef/test-kitchen)
- Chef Style lints: [Foodcritic](https://github.com/acrmp/foodcritic)
- Ruby Style lints: [Rubocop](https://github.com/bbatsov/rubocop)
Prerequisites
-------------
To develop on this cookbook, you must have a sane Ruby 1.9+ environment. Given the nature of this installation process (and it's variance across multiple operating systems), we will leave this installation process to the user.
You must also have `bundler` installed:
$ gem install bundler
You must also have Vagrant and VirtualBox installed:
- [Vagrant](https://vagrantup.com)
- [VirtualBox](https://virtualbox.org)
Once installed, you must install the `vagrant-berkshelf` plugin:
$ vagrant plugin install vagrant-berkshelf
Development
-----------
1. Clone the git repository from GitHub:
$ git clone git@github.com:stevendanna/logrotate.git
2. Install the dependencies using bundler:
$ bundle install
3. Create a branch for your changes:
$ git checkout -b my_bug_fix
4. Make any changes
5. Write tests to support those changes. It is highly recommended you write both unit and integration tests.
6. Run the tests:
- `bundle exec rspec`
- `bundle exec foodcritic .`
- `bundle exec rubocop -l `
- `bundle exec kitchen test`
7. Assuming the tests pass, open a Pull Request on GitHub

View File

@ -2,7 +2,9 @@
# Cookbook Name:: logrotate
# Attribute:: default
#
# Copyright 2013, Chef
# Copyright 2013, Chef Software, Inc
# Copyright 2015-2016, Steven Danna
# Copyright 2016, Bloomberg Finance L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -17,22 +19,36 @@
# limitations under the License.
#
default['logrotate']['global'] = {
'weekly' => true,
'rotate' => 4,
'create' => '',
default["logrotate"]["package"] = {
"name" => "logrotate",
"source" => nil,
"version" => nil,
"provider" => nil,
}
'/var/log/wtmp' => {
'missingok' => true,
'monthly' => true,
'create' => '0664 root utmp',
'rotate' => 1
default["logrotate"]["directory"] = "/etc/logrotate.d"
default["logrotate"]["cron"]["install"] = platform?("solaris2") || platform?("aix")
default["logrotate"]["cron"]["name"] = "logrotate"
default["logrotate"]["cron"]["command"] = "/usr/sbin/logrotate /etc/logrotate.conf"
default["logrotate"]["cron"]["minute"] = 35
default["logrotate"]["cron"]["hour"] = 2
default["logrotate"]["global"] = {
"weekly" => true,
"rotate" => 4,
"create" => "",
"/var/log/wtmp" => {
"missingok" => true,
"monthly" => true,
"create" => "0664 root utmp",
"rotate" => 1,
},
'/var/log/btmp' => {
'missingok' => true,
'monthly' => true,
'create' => '0660 root utmp',
'rotate' => 1
}
"/var/log/btmp" => {
"missingok" => true,
"monthly" => true,
"create" => "0660 root utmp",
"rotate" => 1,
},
}

View File

@ -1,77 +0,0 @@
#
# Cookbook Name:: logrotate
# Definition:: logrotate_instance
#
# Copyright 2009, Scott M. Likens
#
# 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.
#
log_rotate_params = {
:enable => true,
:frequency => 'weekly',
:template => 'logrotate.erb',
:cookbook => 'logrotate',
:template_mode => '0440',
:template_owner => 'root',
:template_group => 'root',
:postrotate => nil,
:prerotate => nil,
:firstaction => nil,
:lastaction => nil,
:sharedscripts => false
}
define(:logrotate_app, log_rotate_params) do
include_recipe 'logrotate::default'
options_tmp = params[:options] ||= %w(missingok compress delaycompress copytruncate notifempty)
options = options_tmp.respond_to?(:each) ? options_tmp : options_tmp.split
options << 'sharedscripts' if params[:sharedscripts]
if params[:enable]
invalid_options = options - CookbookLogrotate::DIRECTIVES
unless invalid_options.empty?
Chef::Log.error("Invalid option(s) passed to logrotate: #{invalid_options.join(', ')}")
raise
end
logrotate_config = {
:path => Array(params[:path]).map { |path| path.to_s.inspect }.join(' '),
:frequency => params[:frequency],
:options => options
}
CookbookLogrotate::VALUES.each do |opt_name|
logrotate_config[opt_name.to_sym] = params[opt_name.to_sym]
end
CookbookLogrotate::SCRIPTS.each do |script_name|
logrotate_config[script_name.to_sym] = Array(params[script_name.to_sym]).join("\n")
end
template "/etc/logrotate.d/#{params[:name]}" do
source params[:template]
cookbook params[:cookbook]
mode params[:template_mode]
owner params[:template_owner]
group params[:template_group]
backup false
variables logrotate_config
end
else
file "/etc/logrotate.d/#{params[:name]}" do
action :delete
end
end
end

View File

@ -19,18 +19,18 @@
# Helper module for Logrotate configuration module CookbookLogrotate
module CookbookLogrotate
DIRECTIVES = %w(compress copy copytruncate daily dateext
DIRECTIVES = %w{compress copy copytruncate daily dateext
dateyesterday delaycompress hourly ifempty mailfirst maillast
missingok monthly nocompress nocopy nocopytruncate nocreate
missingok monthly nocompress nocopy nocopytruncate nocreate nocreateolddir
nodelaycompress nodateext nomail nomissingok noolddir
nosharedscripts noshred notifempty sharedscripts shred weekly
yearly) unless const_defined?(:DIRECTIVES)
nosharedscripts noshred notifempty renamecopy sharedscripts shred weekly
yearly} unless const_defined?(:DIRECTIVES)
VALUES = %w(compresscmd uncompresscmd compressext compressoptions
create dateformat include mail extension maxage minsize maxsize
rotate size shredcycles start tabooext su olddir) unless const_defined?(:VALUES)
VALUES = %w{compresscmd uncompresscmd compressext compressoptions
create createolddir dateformat include mail extension maxage minsize maxsize
rotate size shredcycles start tabooext su olddir} unless const_defined?(:VALUES)
SCRIPTS = %w(firstaction prerotate postrotate lastaction preremove) unless const_defined?(:SCRIPTS)
SCRIPTS = %w{firstaction prerotate postrotate lastaction preremove} unless const_defined?(:SCRIPTS)
DIRECTIVES_AND_VALUES = DIRECTIVES + VALUES unless const_defined?(:DIRECTIVES_AND_VALUES)
@ -52,11 +52,11 @@ module CookbookLogrotate
end
def paths_from(hash)
hash.select { |k| !(DIRECTIVES_AND_VALUES.include?(k)) }.reduce({}) do | accum_paths, (path, config) |
hash.select { |k| !(DIRECTIVES_AND_VALUES.include?(k)) }.reduce({}) do |accum_paths, (path, config)|
accum_paths[path] = {
'directives' => directives_from(config),
'values' => values_from(config),
'scripts' => scripts_from(config)
"directives" => directives_from(config),
"values" => values_from(config),
"scripts" => scripts_from(config),
}
accum_paths
@ -65,7 +65,7 @@ module CookbookLogrotate
def scripts_from(hash)
defined_scripts = hash.select { |k| SCRIPTS.include?(k) }
defined_scripts.reduce({}) do | accum_scripts, (script, lines) |
defined_scripts.reduce({}) do |accum_scripts, (script, lines)|
if lines.respond_to?(:join)
accum_scripts[script] = lines.join("\n")
else

View File

@ -1,154 +1,9 @@
if defined?(ChefSpec)
def enable_logrotate_app(name)
LogrotateAppMatcher.new(name)
def enable_logrotate_app(resource)
ChefSpec::Matchers::ResourceMatcher.new(:logrotate_app, :enable, resource)
end
class LogrotateAppMatcher
def initialize(name)
@name = name
end
def with(parameters = {})
params.merge!(parameters)
self
end
def at_compile_time
raise ArgumentError, 'Cannot specify both .at_converge_time and .at_compile_time!' if @converge_time
@compile_time = true
self
end
def at_converge_time
raise ArgumentError, 'Cannot specify both .at_compile_time and .at_converge_time!' if @compile_time
@converge_time = true
self
end
#
# Allow users to specify fancy #with matchers.
#
def method_missing(m, *args, &block)
if m.to_s =~ /^with_(.+)$/
with($1.to_sym => args.first)
self
else
super
end
end
def description
%Q{"enable" #{@name} "logrotate_app"}
end
def matches?(runner)
@runner = runner
if resource
resource.performed_action?('create') && unmatched_parameters.empty? && correct_phase?
else
false
end
end
def failure_message
if resource
if resource.performed_action?('create')
if unmatched_parameters.empty?
if @compile_time
%Q{expected "#{resource}" to be run at compile time}
else
%Q{expected "#{resource}" to be run at converge time}
end
else
%Q{expected "#{resource}" to have parameters:} \
"\n\n" \
" " + unmatched_parameters.collect { |parameter, h|
"#{parameter} #{h[:expected].inspect}, was #{h[:actual].inspect}"
}.join("\n ")
end
else
%Q{expected "#{resource}" actions #{resource.performed_actions.inspect}} \
" to include : create"
end
else
%Q{expected "logrotate_app[#{@name}] with"} \
" enable : true to be in Chef run. Other" \
" #{@name} resources:" \
"\n\n" \
" " + similar_resources.map(&:to_s).join("\n ") + "\n "
end
end
def failure_message_when_negated
if resource
message = %Q{expected "#{resource}" actions #{resource.performed_actions.inspect} to not exist}
else
message = %Q{expected "#{resource}" to not exist}
end
message << " at compile time" if @compile_time
message << " at converge time" if @converge_time
message
end
private
def unmatched_parameters
return @_unmatched_parameters if @_unmatched_parameters
@_unmatched_parameters = {}
params.each do |parameter, expected|
unless matches_parameter?(parameter, expected)
@_unmatched_parameters[parameter] = {
:expected => expected,
:actual => safe_send(parameter),
}
end
end
@_unmatched_parameters
end
def matches_parameter?(parameter, expected)
# Chef 11+ stores the source parameter internally as an Array
#
case parameter
when :cookbook
expected === safe_send(parameter)
when :path
Array(expected == safe_send('variables')[parameter])
else
expected == safe_send('variables')[parameter]
end
end
def correct_phase?
if @compile_time
resource.performed_action('create')[:compile_time]
elsif @converge_time
resource.performed_action('create')[:converge_time]
else
true
end
end
def safe_send(parameter)
resource.send(parameter)
rescue NoMethodError
nil
end
def similar_resources
@_similar_resources ||= @runner.find_resources('template')
end
def resource
@_resource ||= @runner.find_resource('template', "/etc/logrotate.d/#{@name}")
end
def params
@_params ||= {}
end
def disable_logrotate_app(resource)
ChefSpec::Matchers::ResourceMatcher.new(:logrotate_app, :disable, resource)
end
end

View File

@ -16,7 +16,7 @@
"ubuntu": ">= 0.0.0"
},
"dependencies": {
"compat_resource": ">= 0.0.0"
},
"recommendations": {
@ -42,7 +42,17 @@
"recipes": {
"logrotate": "Installs logrotate package"
},
"version": "1.9.2",
"source_url": "",
"issues_url": ""
"version": "2.1.0",
"source_url": "https://github.com/stevendanna/logrotate",
"issues_url": "https://github.com/stevendanna/logrotate/issues",
"privacy": false,
"chef_versions": [
],
"ohai_versions": [
],
"gems": [
]
}

View File

@ -1,13 +1,18 @@
name 'logrotate'
maintainer 'Steven Danna'
maintainer_email 'steve@chef.io'
license 'Apache 2.0'
description 'Installs logrotate package and provides a definition for logrotate configs'
long_description 'Installs the logrotate package, manages /etc/logrotate.conf, and provides a logrotate_app definition.'
version '1.9.2'
name "logrotate"
maintainer "Steven Danna"
maintainer_email "steve@chef.io"
license "Apache 2.0"
description "Installs logrotate package and provides a definition for logrotate configs"
long_description "Installs the logrotate package, manages /etc/logrotate.conf, and provides a logrotate_app definition."
version "2.1.0"
recipe 'logrotate', 'Installs logrotate package'
provides 'logrotate_app'
source_url "https://github.com/stevendanna/logrotate" if respond_to?(:source_url)
issues_url "https://github.com/stevendanna/logrotate/issues" if respond_to?(:issues_url)
recipe "logrotate", "Installs logrotate package"
provides "logrotate_app"
depends "compat_resource"
%w{amazon centos debian fedora redhat scientific solaris2 ubuntu}.each do |platform|
supports platform

View File

@ -3,6 +3,8 @@
# Recipe:: default
#
# Copyright 2009-2013, Chef Software, Inc.
# Copyright 2015-2016, Steven Danna
# Copyright 2016, Bloomberg Finance L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -16,20 +18,25 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
return if platform?("windows")
package 'logrotate'
directory "/etc/logrotate.d" do
owner "root"
group "root"
mode "0755"
action :create
package node["logrotate"]["package"]["name"] do
provider node["logrotate"]["package"]["provider"] if node["logrotate"]["package"]["provider"]
source node["logrotate"]["package"]["source"] if node["logrotate"]["package"]["source"]
version node["logrotate"]["package"]["version"] if node["logrotate"]["package"]["version"]
action :upgrade
end
if platform? "solaris2" # ~FC023 style preference
cron "logrotate" do
minute "35"
hour "7"
command "/usr/sbin/logrotate /etc/logrotate.conf"
directory node["logrotate"]["directory"] do
owner "root"
group node["root_group"]
mode "0755"
end
if node["logrotate"]["cron"]["install"] # ~FC023
cron node["logrotate"]["cron"]["name"] do
minute node["logrotate"]["cron"]["minute"]
hour node["logrotate"]["cron"]["hour"]
command node["logrotate"]["cron"]["command"]
end
end

View File

@ -17,13 +17,13 @@
# limitations under the License.
#
include_recipe 'logrotate::default'
include_recipe "logrotate::default"
parsed_configuration = CookbookLogrotate::LogrotateConfiguration.from_hash(node['logrotate']['global'].to_hash)
parsed_configuration = CookbookLogrotate::LogrotateConfiguration.from_hash(node["logrotate"]["global"].to_hash)
template '/etc/logrotate.conf' do
source 'logrotate-global.erb'
mode '0644'
template "/etc/logrotate.conf" do
source "logrotate-global.erb"
mode "0644"
variables(
:configuration => parsed_configuration
)

View File

@ -0,0 +1,116 @@
#
# Copyright 2016, Steven Danna
#
# 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.
#
resource_name :logrotate_app
property :path, [String, Array], required: true
property :frequency, String, default: "weekly"
property :cookbook, default: "logrotate"
property :template_name, default: "logrotate.erb"
property :template_mode, default: "0644"
property :template_owner, default: "root"
property :template_group, default: "root"
property :base_dir, String, default: "/etc/logrotate.d"
property :options, [Array, String], default: %w{missingok compress delaycompress copytruncate notifempty}
default_action :enable
CookbookLogrotate::SCRIPTS.each do |script_name|
property script_name.to_sym, coerce: Proc.new { |val| Array(val).join("\n") }
end
CookbookLogrotate::VALUES.each do |configurable_name|
property configurable_name.to_sym
end
# Deprecated options
property :sharedscripts, [TrueClass, FalseClass], default: false
property :enable, [TrueClass, FalseClass], default: true
action :enable do
if !new_resource.enable
Chef::Log.deprecation "Use `action :disable` rather than `enable false` in the logrotate_app resource"
action_disable
return true
end
logrotate_config = {
# The path should be a space separated list of quoted filesystem paths
path: Array(new_resource.path).map { |path| path.to_s.inspect }.join(" "),
frequency: new_resource.frequency,
directives: handle_options(new_resource),
scripts: handle_scripts(new_resource),
configurables: handle_configurables(new_resource),
}
directory new_resource.base_dir do
owner "root"
group node["root_group"]
mode "0755"
action :create
end
template "#{new_resource.base_dir}/#{new_resource.name}" do
source new_resource.template_name
cookbook new_resource.cookbook
mode new_resource.template_mode
owner new_resource.template_owner
group new_resource.template_group
backup false
variables logrotate_config
end
end
action :disable do
file "#{new_resource.base_dir}/#{new_resource.name}" do
action :delete
end
end
def handle_configurables(new_resource)
configurables = {}
CookbookLogrotate::VALUES.each do |opt_name|
if value = new_resource.send(opt_name.to_sym)
configurables[opt_name] = value
end
end
configurables
end
def handle_scripts(new_resource)
scripts = {}
CookbookLogrotate::SCRIPTS.each do |script_name|
if script_body = new_resource.send(script_name.to_sym)
scripts[script_name] = script_body
end
end
scripts
end
def handle_options(new_resource)
opts = if new_resource.options.is_a?(Array)
new_resource.options.dup
else
new_resource.options.split
end
if new_resource.sharedscripts
Chef::Log.deprecation("The sharedscripts resource property is deprecated. Use the options property instead to set this value")
opts << "sharedscripts"
end
opts
end

View File

@ -5,19 +5,15 @@
<%- if @frequency %>
<%= @frequency %>
<%- end %>
<%- CookbookLogrotate::VALUES.each do |opt_name| %>
<% if instance_variable_get("@#{opt_name}") %>
<%= "#{opt_name} #{instance_variable_get("@#{opt_name}")}" %>
<%- end %>
<%- @configurables.each do |name, value| %>
<%= "#{name} #{value}" %>
<%- end %>
<% @options.each do |o| -%>
<% @directives.each do |o| -%>
<%= o %>
<% end -%>
<%- CookbookLogrotate::SCRIPTS.each do |script_name| %>
<% unless instance_variable_get("@#{script_name}").empty? %>
<%- @scripts.each do |script_name, script| %>
<%= script_name %>
<%= instance_variable_get("@#{script_name}") %>
<%= script %>
endscript
<%- end %>
<%- end %>
}