From 5db2a92b18de8f42bfb2cfd293cb625e343fa757 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Tue, 26 May 2015 14:17:35 -0400 Subject: [PATCH 01/48] Rewrites the collectd cookbook to utilize Poise. This is a complete rewrite of the collectd cookbook. It utilizes the best practices set forth by the Poise and Poise Service cookbooks. --- .gitignore | 54 ++++++- .kitchen.yml | 28 ++++ .rspec | 2 + .rubocop.yml | 43 ++++++ .travis.yml | 20 +++ .yardopts | 5 + Berksfile | 2 + Gemfile | 44 ++++++ Guardfile | 21 +++ LICENSE | 14 ++ README.md | 135 ++++++------------ Rakefile | 39 +++++ attributes/default.rb | 41 +++--- bin/berks | 16 +++ bin/kitchen | 16 +++ bin/rspec | 16 +++ definitions/collectd_plugin.rb | 52 ------- libraries/collectd_plugin.rb | 80 +++++++++++ libraries/collectd_service.rb | 113 +++++++++++++++ libraries/default.rb | 47 ------ libraries/helpers.rb | 43 ++++++ metadata.rb | 24 ++-- recipes/client.rb | 38 ++--- recipes/collectd_web.rb | 53 ------- recipes/default.rb | 93 ++---------- recipes/server.rb | 29 ++-- recipes/web.rb | 34 +++++ templates/default/collectd.conf.erb | 18 --- templates/default/plugin.conf.erb | 15 -- templates/default/thresholds.conf.erb | 37 ----- .../client/serverspec/client_spec.rb | 5 + .../default/serverspec/default_spec.rb | 46 ++++++ .../helpers/serverspec/spec_helper.rb | 3 + .../server/serverspec/server_spec.rb | 5 + test/integration/web/serverspec/web_spec.rb | 15 ++ test/spec/libraries/collectd_plugin_spec.rb | 25 ++++ test/spec/libraries/collectd_service_spec.rb | 7 + test/spec/recipes/client_spec.rb | 17 +++ test/spec/recipes/default_spec.rb | 16 +++ test/spec/recipes/server_spec.rb | 17 +++ test/spec/recipes/web_spec.rb | 15 ++ test/spec/spec_helper.rb | 40 ++++++ 42 files changed, 912 insertions(+), 471 deletions(-) create mode 100644 .kitchen.yml create mode 100644 .rspec create mode 100644 .rubocop.yml create mode 100644 .travis.yml create mode 100644 .yardopts create mode 100644 Berksfile create mode 100644 Gemfile create mode 100644 Guardfile create mode 100644 LICENSE create mode 100755 Rakefile create mode 100755 bin/berks create mode 100755 bin/kitchen create mode 100755 bin/rspec delete mode 100644 definitions/collectd_plugin.rb create mode 100644 libraries/collectd_plugin.rb create mode 100644 libraries/collectd_service.rb delete mode 100644 libraries/default.rb create mode 100644 libraries/helpers.rb delete mode 100644 recipes/collectd_web.rb create mode 100644 recipes/web.rb delete mode 100644 templates/default/collectd.conf.erb delete mode 100644 templates/default/plugin.conf.erb delete mode 100644 templates/default/thresholds.conf.erb create mode 100644 test/integration/client/serverspec/client_spec.rb create mode 100644 test/integration/default/serverspec/default_spec.rb create mode 100644 test/integration/helpers/serverspec/spec_helper.rb create mode 100644 test/integration/server/serverspec/server_spec.rb create mode 100644 test/integration/web/serverspec/web_spec.rb create mode 100644 test/spec/libraries/collectd_plugin_spec.rb create mode 100644 test/spec/libraries/collectd_service_spec.rb create mode 100644 test/spec/recipes/client_spec.rb create mode 100644 test/spec/recipes/default_spec.rb create mode 100644 test/spec/recipes/server_spec.rb create mode 100644 test/spec/recipes/web_spec.rb create mode 100644 test/spec/spec_helper.rb diff --git a/.gitignore b/.gitignore index 5598138..7815158 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,54 @@ -metadata.json +# Ignore docs files +_gh_pages +_site +.ruby-version +.node-version +Gemfile.lock +# Numerous always-ignore extensions +*.diff +*.err +*.orig +*.log +*.rej +*.swo +*.swp +*.zip +*.vi +*~ + +# OS or Editor folders +.DS_Store +._* +Thumbs.db +.cache +.project +.settings +.tmproj +*.esproj +nbproject +*.sublime-project +*.sublime-workspace +.idea + +# Komodo +*.komodoproject +.komodotools + +# grunt-html-validation +validation-status.json +validation-report.json + +# Folders to ignore +bin +node_modules +tmp +vendor +.bundle + +# Chef specifics to ignore +.chef +.chefdk +.kitchen +.vagrant +Berksfile.lock diff --git a/.kitchen.yml b/.kitchen.yml new file mode 100644 index 0000000..42d701b --- /dev/null +++ b/.kitchen.yml @@ -0,0 +1,28 @@ +--- +driver: + name: vagrant + +provisioner: + name: chef_zero + +platforms: + - name: ubuntu-14.04 + - name: ubuntu-12.04 + - name: ubuntu-10.04 + - name: centos-7.1 + - name: centos-6.6 + - name: centos-5.11 + +suites: + - name: default + run_list: + - recipe[collectd::default] + - name: server + run_list: + - recipe[collectd::server] + - name: client + run_list: + - recipe[collectd::client] + - name: web + run_list: + - recipe[collectd::web] diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..b4401c4 --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--default-path test/spec +--color diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..f10013f --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,43 @@ +--- +AlignParameters: + Enabled: false + +Encoding: + Enabled: false + +ClassLength: + Enabled: false + +MethodLength: + Enabled: false + +LineLength: + Enabled: false + +Documentation: + Enabled: false + +PerceivedComplexity: + Enabled: false + +CyclomaticComplexity: + Enabled: false + +Style/FileName: + Enabled: false + +Style/ClassAndModuleChildren: + Enabled: false + +Metrics/AbcSize: + Enabled: false + +AllCops: + Exclude: + - 'Guardfile' + - 'test/**/*_test.rb' + - 'test/**/*_spec.rb' + - 'bin/**' + +Style/GuardClause: + Enabled: false diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..419b164 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,20 @@ +--- +language: ruby +notifications: + slack: bloomberg-rnd:eHp3Czg42iGzaTgG8sAFeD9v +install: + - bundle install --retry 3 --without kitchen_vagrant kitchen_cloud + - bundle exec berks install +script: bundle exec rake travis +rvm: + - 2.1 + - 2.2 +cache: + directories: + - vendor/bundle +branches: + only: + - master +builder_args: --jobs 7 +matrix: + fast_finish: true diff --git a/.yardopts b/.yardopts new file mode 100644 index 0000000..fed27a8 --- /dev/null +++ b/.yardopts @@ -0,0 +1,5 @@ +--plugin classmethods +--embed-mixin ClassMethods +--hide-api private +--markup markdown +--hide-void-return diff --git a/Berksfile b/Berksfile new file mode 100644 index 0000000..9099626 --- /dev/null +++ b/Berksfile @@ -0,0 +1,2 @@ +source 'https://supermarket.chef.io' +metadata diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..43f8376 --- /dev/null +++ b/Gemfile @@ -0,0 +1,44 @@ +source 'https://rubygems.org' +gem 'poise', '~> 2.2' +gem 'poise-service', '~> 1.0' +gem 'poise-boiler' + +group :lint do + gem 'rubocop' + gem 'foodcritic' +end + +group :kitchen_common do + gem 'test-kitchen', '~> 1.4' +end + +group :kitchen_vagrant do + gem 'kitchen-vagrant', '~> 0.17' +end + +group :kitchen_cloud do + gem 'kitchen-openstack', '~> 1.8' +end + +group :unit do + gem 'berkshelf' + gem 'chefspec' +end + +group :integration do + gem 'serverspec' +end + +group :development do + gem 'awesome_print' + gem 'guard' + gem 'guard-kitchen' + gem 'guard-rspec' + gem 'guard-rubocop' + gem 'rake' + gem 'stove' +end + +group :doc do + gem 'yard' +end diff --git a/Guardfile b/Guardfile new file mode 100644 index 0000000..d3e0d54 --- /dev/null +++ b/Guardfile @@ -0,0 +1,21 @@ +guard 'foodcritic', cookbook_paths: '.', cli: '-t ~FC023 -t ~FC005', all_on_start: false do + watch(%r{^(?:recipes|libraries|providers|resources)/.+\.rb$}) + watch('metadata.rb') +end + +# More info at https://github.com/guard/guard#readme +guard 'rubocop' do + watch(%r{^attributes/.+\.rb$}) + watch(%r{^providers/.+\.rb$}) + watch(%r{^recipes/.+\.rb$}) + watch(%r{^resources/.+\.rb$}) + watch(%r{^libraries/.+\.rb$}) + watch('metadata.rb') +end + +guard :rspec, cmd: 'bin/rspec', all_on_start: false, notification: false do + watch(%r{^(recipes|libraries|providers|resources)/(.+)\.rb$}) do |m| + "test/spec/#{m[0]}/#{m[1]}_spec.rb" + end + watch('test/spec/spec_helper.rb') { 'test/spec' } +end diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..efdfaec --- /dev/null +++ b/LICENSE @@ -0,0 +1,14 @@ +Copyright 2010, Atari, Inc +Copyright 2015, 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. +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. diff --git a/README.md b/README.md index 10d7e5d..e293b29 100644 --- a/README.md +++ b/README.md @@ -1,92 +1,51 @@ -# DESCRIPTION # - -Configure and install the [collectd](http://collectd.org/) monitoring daemon. - -# REQUIREMENTS # - -This cookbook has only been tested on Ubuntu 10.04. - -To use the `collectd::collectd_web` recipe you need the [apache2](https://github.com/opscode/cookbooks/tree/master/apache2) cookbook. - -The [collectd_plugins](https://github.com/coderanger/chef-collectd_plugins) cookbook is not required, but provides many common plugin definitions for easy reuse. - -# ATTRIBUTES # - -* collectd.basedir - Base folder for collectd output data. -* collectd.plugin_dir - Base folder to find plugins. -* collectd.types_db - Array of files to read graph type information from. -* collectd.interval - Time period in seconds to wait between data reads. - -* collectd.collectd_web.path - Location to install collectd_web to. Defaults to /srv/collectd_web. -* collectd.collectd_web.hostname - Server name to use for collectd_web Apache site. - -# USAGE # - -Three main recipes are provided: - -* collectd - Install a standalone daemon. -* collectd::client - Install collectd and configure it to send data to a server. -* collectd::server - Install collectd and configure it to recieve data from clients. - -The client recipe will use the search index to automatically locate the server hosts, so no manual configuration is required. - -## Defines ## - -Several defines are provided to simplfy configuring plugins - -### collectd_plugin ### - -The `collectd_plugin` define configures and enables standard collect plugins. Example: - +# collectd-cookbook +[![Build Status](https://img.shields.io/travis/coderanger/chef-collectd.svg)](https://travis-ci.org/coderanger/chef-collectd) +[![Gem Version](https://img.shields.io/gem/v/poise.svg)](https://rubygems.org/gems/poise) +[![Cookbook Version](https://img.shields.io/cookbook/v/poise.svg)](https://supermarket.chef.io/cookbooks/poise) +[![Coverage](https://img.shields.io/codecov/c/github/coderanger/chef-collectd.svg)](https://codecov.io/github/coderanger/chef-collectd) +[![Gemnasium](https://img.shields.io/gemnasium/coderanger/chef-collectd.svg)](https://gemnasium.com/coderanger/chef-collectd) +[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) + +[Application cookbook][0] which installs and configures the +[collectd monitoring daemon][1]. + +This cookbook provides a dead-simple installation and configuration of +the collectd monitoring daemon. It provides two resources: the first +is for managing the collectd system service, and the second is for +configuring the daemon's plugins. Additionally, the +[collectd_plugins cookbook][4] may be used to configure many of the +common plugins that ship with the daemon. + +It is very important to note that distributions may ship different +major versions of the package, but the following platforms are tested +using the integration tests via [Test Kitchen][2]. +- Ubuntu ~> 10.04, 12.04, 14.04 +- CentOS ~> 5.8, 6.4, 7.1 +- RHEL ~> 5.8, 6.4, 7.1 + +## Basic Usage +The [default recipe](recipes/default.rb) in this cookbook simply +configures the monitoring daemon to run as a system service. The +configuration for this service can be tuned using the +[node attributes](attributes/default.rb). Additionally, a resource is +provided to configure plugins for the daemon. After a plugin has been +configured the daemon should be restarted. + +### Enabling Syslog +One of the simplest plugins to enable is the [collectd Syslog plugin][3] +which receives log messages from the daemon and dispatches them to the +to syslog. This allows the daemon's logs to easily integrate with +existing UNIX utilities. ```ruby -collectd_plugin "interface" do - options :interface=>"lo", :ignore_selected=>true +collectd_plugin 'syslog' do + options do + log_level 'info' + notify_level 'OKAY' + end end ``` -The options hash is converted to collectd-style settings automatically. Any symbol key will be converted to camel-case. In the above example :ignore_selected will be output as the -key "IgnoreSelected". If the key is already a string, this conversion is skipped. If the value is an array, it will be output as a separate line for each element. - -### collectd_python_plugin ### - -The `collectd_python_plugin` define configures and enables Python plugins using the collectd-python plugin. Example: - -```ruby -collectd_python_plugin "redis" do - options :host=>servers, :verbose=>true -end -``` - -Options are interpreted in the same way as with `collectd_plugin`. This define will not deploy the plugin script as well, so be sure to setup a cookbook_file resource -or other mechanism to handle distribution. Example: - -```ruby -cookbook_file File.join(node[:collectd][:plugin_dir], "redis.py") do - owner "root" - group "root" - mode "644" -end -``` - -## Web frontend ## - -The `collectd::collectd_web` recipe will automatically deploy the [collectd_web](https://github.com/httpdss/collectd-web) frontend using Apache. The -[apache2](https://github.com/opscode/cookbooks/tree/master/apache2) cookbook is required for this and is *not* included automatically as this is an optional -component, so be sure to configure the node with the correct recipes. - -# LICENSE & AUTHOR # - -Author:: Noah Kantrowitz () -Copyright:: 2010, Atari, Inc - -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. +[0]: http://blog.vialstudios.com/the-environment-cookbook-pattern#theapplicationcookbook +[1]: https://collectd.org +[2]: https://github.com/test-kitchen/test-kitchen +[3]: https://collectd.org/wiki/index.php/Plugin:SysLog diff --git a/Rakefile b/Rakefile new file mode 100755 index 0000000..a81d056 --- /dev/null +++ b/Rakefile @@ -0,0 +1,39 @@ +#!/usr/bin/env rake + +require 'bundler/setup' +require 'rspec/core/rake_task' +require 'rubocop/rake_task' +require 'foodcritic' +require 'kitchen' + +namespace :style do + desc 'Run Ruby style checks' + RuboCop::RakeTask.new(:ruby) + + desc 'Run Chef style checks' + FoodCritic::Rake::LintTask.new(:chef) +end + +desc 'Run all style checks' +task style: ['style:chef', 'style:ruby'] + +desc 'Run ChefSpec unit tests' +RSpec::Core::RakeTask.new(:unit) do |t| + t.pattern = 'test/spec/**{,/*/**}/*_spec.rb' +end + +# Integration tests. Kitchen.ci +desc 'Run Test Kitchen with Vagrant' +task :vagrant do + Kitchen.logger = Kitchen.default_file_logger + Kitchen::Config.new.instances.each do |instance| + instance.test(:always) + end +end + +desc 'Run style & unit tests on Travis' +task travis: %w(style unit) + +# Default +desc 'Run style, unit, and Vagrant-based integration tests' +task default: %w(style unit vagrant) diff --git a/attributes/default.rb b/attributes/default.rb index 0c81e17..b5af151 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -1,28 +1,23 @@ # -# Cookbook Name:: collectd -# Attributes:: default +# Cookbook: collectd +# License: Apache 2.0 # -# Copyright 2010, Atari, Inc -# -# 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. +# Copyright 2010, Atari, Inc. +# Copyright 2015, Bloomberg Finance L.P. # +default['collectd']['service_name'] = 'collectd' +default['collectd']['service_user'] = 'collectd' +default['collectd']['service_group'] = 'collectd' + +if node['platform'] == 'ubuntu' + default['collectd']['service']['package_name'] = 'collectd-core' +else + default['collectd']['service']['package_name'] = 'collectd' +end -default[:collectd][:base_dir] = "/var/lib/collectd" -default[:collectd][:plugin_dir] = "/usr/lib/collectd" -default[:collectd][:types_db] = ["/usr/share/collectd/types.db"] -default[:collectd][:interval] = 10 -default[:collectd][:read_threads] = 5 -default[:collectd][:pkg_name] = "collectd-core" +default['collectd']['service']['configuration']['plugin_dir'] = '/usr/lib64/collectd' +default['collectd']['service']['configuration']['types_d_b'] = '/usr/share/collectd/types.db' -default[:collectd][:collectd_web][:path] = "/srv/collectd_web" -default[:collectd][:collectd_web][:hostname] = "collectd" +default['collectd']['web']['options'] = { 'data_dir' => '/etc/collectd.d/collectd-web' } +default['collectd']['client']['options']['servers'] = [] +default['collectd']['server']['options']['listen'] = '0.0.0.0' diff --git a/bin/berks b/bin/berks new file mode 100755 index 0000000..2d5e5fe --- /dev/null +++ b/bin/berks @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'berks' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('berkshelf', 'berks') diff --git a/bin/kitchen b/bin/kitchen new file mode 100755 index 0000000..a130b9b --- /dev/null +++ b/bin/kitchen @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'kitchen' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('test-kitchen', 'kitchen') diff --git a/bin/rspec b/bin/rspec new file mode 100755 index 0000000..0c86b5c --- /dev/null +++ b/bin/rspec @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'rspec' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('rspec-core', 'rspec') diff --git a/definitions/collectd_plugin.rb b/definitions/collectd_plugin.rb deleted file mode 100644 index 75c665f..0000000 --- a/definitions/collectd_plugin.rb +++ /dev/null @@ -1,52 +0,0 @@ -# -# Cookbook Name:: collectd -# Definition:: collectd_plugin -# -# Copyright 2010, Atari, Inc -# -# 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. -# - -define :collectd_plugin, :options => {}, :template => nil, :cookbook => nil do - template "/etc/collectd/plugins/#{params[:name]}.conf" do - owner "root" - group "root" - mode "644" - if params[:template].nil? - source "plugin.conf.erb" - cookbook params[:cookbook] || "collectd" - else - source params[:template] - cookbook params[:cookbook] - end - variables :name=>params[:name], :options=>params[:options] - notifies :restart, resources(:service => "collectd") - end -end - -define :collectd_python_plugin, :options => {}, :module => nil, :path => nil do - begin - t = resources(:template => "/etc/collectd/plugins/python.conf") - rescue ArgumentError,Chef::Exceptions::ResourceNotFound - collectd_plugin "python" do - options :paths=>[node[:collectd][:plugin_dir]], :modules=>{} - template "python_plugin.conf.erb" - cookbook "collectd" - end - retry - end - if not params[:path].nil? - t.variables[:options][:paths] << params[:path] - end - t.variables[:options][:modules][params[:module] || params[:name]] = params[:options] -end diff --git a/libraries/collectd_plugin.rb b/libraries/collectd_plugin.rb new file mode 100644 index 0000000..2255244 --- /dev/null +++ b/libraries/collectd_plugin.rb @@ -0,0 +1,80 @@ +# +# Cookbook: collectd +# License: Apache 2.0 +# +# Copyright 2010, Atari, Inc. +# Copyright 2015, Bloomberg Finance L.P. +# +require_relative 'helpers' +require 'poise' + +module CollectdCookbook + module Resource + # A resource for managing collectd plugins. + # @since 2.0.0 + class Chef::Resource::CollectdPlugin < Chef::Resource + include Poise(fused: true) + provides(:collectd_plugin) + include CollectdCookbook::Helpers + + # @!attribute plugin_name + # Name of the collectd plugin to install and configure. + # @return [String] + attribute(:plugin_name, kind_of: String, name_attribute: true) + + # @!attribute directory + # Name of directory where plugin configuration resides. Defaults to + # '/etc/collectd.d'. + # @return [String] + attribute(:directory, kind_of: String, default: '/etc/collectd.d') + + # @!attribute user + # User which the configuration for {#plugin_name} is owned by. + # Defaults to 'collectd.' + # @return [String] + attribute(:user, kind_of: String, default: 'collectd') + + # @!attribute group + # Group which the configuration for {#plugin_name} is owned by. + # Defaults to 'collectd.' + # @return [String] + attribute(:group, kind_of: String, default: 'collectd') + + # @!attribute options + # Set of key-value options to configure the plugin. + # @return [Hash, Mash] + attribute(:options, option_collector: true) + + action(:create) do + notifying_block do + directory new_resource.directory do + recursive true + mode '0644' + end + + directives = [ + '# This file is autogenerated by Chef.', + '# Do not edit; All changes will be overwritten!', + %Q(LoadPlugin "#{new_resource.plugin_name}"), + %Q(), + new_resource.build_configuration(new_resource.options, 1), + "\n" + ] + + file ::File.join(new_resource.directory, "#{new_resource.plugin_name}.conf") do + content directives.flatten.join("\n") + mode '0644' + end + end + end + + action(:delete) do + notifying_block do + file ::File.join(new_resource.directory, "#{new_resource.plugin_name}.conf") do + action :delete + end + end + end + end + end +end diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb new file mode 100644 index 0000000..f20e5ff --- /dev/null +++ b/libraries/collectd_service.rb @@ -0,0 +1,113 @@ +# +# Cookbook: collectd +# License: Apache 2.0 +# +# Copyright 2010, Atari, Inc. +# Copyright 2015, Bloomberg Finance L.P. +# +require 'poise_service/service_mixin' + +module CollectdCookbook + module Resource + # A resource for managing the collectd monitoring daemon. + # @since 2.0.0 + class CollectdService < Chef::Resource + include Poise + provides(:collectd_service) + include PoiseService::ServiceMixin + + # @!attribute user + # User to run the collectd daemon as. Defaults to 'collectd.' + # @return [String] + attribute(:user, kind_of: String, default: 'collectd') + + # @!attribute group + # Group to run the collectd daemon as. Defaults to 'collectd.' + # @return [String] + attribute(:group, kind_of: String, default: 'collectd') + + # @!attribute directory + # The working directory for the service. Defaults to the data + # directory '/var/lib/collectd'. + # @return [String] + attribute(:directory, kind_of: String, default: '/var/lib/collectd') + + # @!attribute configuration_directory + # Name of directory where additional configurations reside. Defaults to + # '/etc/collectd.d'. + # @return [String] + attribute(:config_directory, kind_of: String, default: '/etc/collectd.d') + + # @!attribute config_filename + # The configuration file for the daemon service. Defaults to + # '/etc/collectd.conf'. + # @return [String] + attribute(:config_filename, kind_of: String, default: '/etc/collectd.conf') + + # @!attribute configuration + # Set of key-value options to write to {#config_filename}. + # @see {https://collectd.org/documentation/manpages/collectd.conf.5.shtml#global_options} + # @return [Hash, Mash] + attribute(:configuration, option_collector: true) + end + end + + module Provider + # A provider for managing collectd daemon as a service. + # @since 2.0.0 + class CollectdService < Chef::Provider + include Poise + provides(:collectd_service) + include PoiseService::ServiceMixin + include CollectdCookbook::Helpers + + def action_enable + notifying_block do + package new_resource.package_name do + version new_resource.package_version if new_resource.package_version + action :upgrade + end + + directory [new_resource.config_directory, new_resource.directory] do + recursive true + owner new_resource.user + group new_resource.group + mode '0755' + end + + directives = [ + '# This file is autogenerated by Chef.', + '# Do not edit; All changes will be overwritten!', + build_configuration(new_resource.configuration.merge( + 'base_dir' => new_resource.directory, + 'hostname' => node['hostname'] + )), + %Q(Include "#{new_resource.config_directory}"\n) + ] + + file new_resource.config_filename do + content directives.flatten.join("\n") + mode '0644' + end + end + super + end + + def action_disable + notifying_block do + file new_resource.config_filename do + action :delete + end + end + super + end + + # Sets the tuning options for service management with {PoiseService::ServiceMixin}. + # @param [PoiseService::Service] service + def service_options(service) + service.command("/usr/sbin/collectd -C #{new_resource.config_filename} -f") + service.restart_on_update(true) + end + end + end +end diff --git a/libraries/default.rb b/libraries/default.rb deleted file mode 100644 index 1f3e92b..0000000 --- a/libraries/default.rb +++ /dev/null @@ -1,47 +0,0 @@ -# -# Cookbook Name:: collectd -# Library:: default -# -# Copyright 2010, Atari, Inc -# -# 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. -# - -def collectd_key(option) - return option.to_s.split('_').map{|x| x.capitalize}.join() if option.instance_of?(Symbol) - "#{option}" -end - -def collectd_option(option) - return option if option.instance_of?(Fixnum) || option == true || option == false - "\"#{option}\"" -end - -def collectd_settings(options, level=0) - indent = ' ' * level - output = [] - options.each_pair do |key, value| - if value.is_a? Array - value.each do |subvalue| - output << "#{indent}#{collectd_key(key)} #{collectd_option(subvalue)}" - end - elsif value.is_a? Hash - value.each_pair do |name, suboptions| - output << "#{indent}<#{key} \"#{name}\">\n#{collectd_settings(suboptions, level+1)}\n#{indent}" - end - else - output << "#{indent}#{collectd_key(key)} #{collectd_option(value)}" - end - end - output.join("\n") -end diff --git a/libraries/helpers.rb b/libraries/helpers.rb new file mode 100644 index 0000000..e617b9f --- /dev/null +++ b/libraries/helpers.rb @@ -0,0 +1,43 @@ +# +# Cookbook: collectd +# License: Apache 2.0 +# +# Copyright 2010 Atari, Inc. +# Copyright 2015 Bloomberg Finance L.P. +# + +module CollectdCookbook + module Helpers + # Converts from snake case to a camel case string. + # @param [String, Symbol] s + # @param [String] + # @return [String] + def snake_to_camel(s) + s.to_s.split('_').map(&:capitalize).join("") + end + + # Builds a configuration file from {directives} and applys {indent}. + # @param [Hash] directives + # @param [Integer] indent + # @return [String] + def build_configuration(directives, indent=0) + tabs = ("\t" * indent) + directives.map do |key, value| + next if value.nil? + key = snake_to_camel(key) + if value.is_a?(Array) + %Q(#{tabs}#{key} "#{value.uniq.join('", "')}") + elsif value.kind_of?(Hash) + value.map do |n, v| + n = snake_to_camel(n) + %Q(#{tabs}<#{key} "#{n}">\n#{build_configuration(v, indent.next)}\n#{tabs}) + end + elsif value.is_a?(String) + %Q(#{tabs}#{key} "#{value.to_s}") + else + %Q(#{tabs}#{key} #{value.to_s}) + end + end.flatten.join("\n") + end + end +end diff --git a/metadata.rb b/metadata.rb index 3a0d763..fb7dba0 100644 --- a/metadata.rb +++ b/metadata.rb @@ -1,8 +1,16 @@ -name "collectd" -maintainer "Noan Kantrowitz" -maintainer_email "noah@coderanger.net" -license "Apache 2.0" -description "Install and configure the collectd monitoring daemon" -long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version "1.0.0" -supports "ubuntu" +name 'collectd' +maintainer 'Noah Kantrowitz' +maintainer_email 'noah@coderanger.net' +license 'Apache 2.0' +description 'Installs and configures the collectd monitoring daemon.' +long_description 'Installs and configures the collectd monitoring daemon.' +version '2.0.0' + +supports 'ubuntu', '>= 10.04' +supports 'centos', '>= 5.8' +supports 'redhat', '>= 5.8' + +depends 'httpd' +depends 'poise', '~> 2.2' +depends 'poise-service', '~> 1.0' +depends 'yum-epel' diff --git a/recipes/client.rb b/recipes/client.rb index d3b81dd..2e539fa 100644 --- a/recipes/client.rb +++ b/recipes/client.rb @@ -1,33 +1,15 @@ # -# Cookbook Name:: collectd -# Recipe:: client +# Cookbook: collectd +# License: Apache 2.0 # -# Copyright 2010, Atari, Inc +# Copyright 2010, Atari, Inc. +# Copyright 2015, 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. -# 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. -# - -include_recipe "collectd" - -servers = [] -search(:node, 'recipes:collectd\\:\\:server') do |n| - servers << n['fqdn'] -end - -if servers.empty? - raise "No servers found. Please configure at least one node with collectd::server." -end +include_recipe 'collectd::default' -collectd_plugin "network" do - options :server=>servers +collectd_plugin 'network' do + user node['collectd']['service_user'] + group node['collectd']['service_group'] + options node['collectd']['client']['options'] unless node['collectd']['client'].nil? + notifies :restart, "collectd_service[#{node['collectd']['service_name']}]", :delayed end diff --git a/recipes/collectd_web.rb b/recipes/collectd_web.rb deleted file mode 100644 index f0fd1a0..0000000 --- a/recipes/collectd_web.rb +++ /dev/null @@ -1,53 +0,0 @@ -# -# Cookbook Name:: collectd -# Recipe:: collectd_web -# -# Copyright 2010, Atari, Inc -# -# 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. -# - -include_recipe "collectd" -include_recipe "apache2" - -%w(libhtml-parser-perl liburi-perl librrds-perl libjson-perl).each do |name| - package name -end - -directory node[:collectd][:collectd_web][:path] do - owner "root" - group "root" - mode "755" -end - -bash "install_collectd_web" do - user "root" - cwd node[:collectd][:collectd_web][:path] - not_if do - File.exists?(File.join(node[:collectd][:collectd_web][:path], "index.html")) - end - code <<-EOH - wget --no-check-certificate -O collectd-web.tar.gz https://github.com/httpdss/collectd-web/tarball/master - tar --strip-components=1 -xzf collectd-web.tar.gz - rm collectd-web.tar.gz - EOH -end - -template "/etc/apache2/sites-available/collectd_web.conf" do - source "collectd_web.conf.erb" - owner "root" - group "root" - mode "644" -end - -apache_site "collectd_web.conf" diff --git a/recipes/default.rb b/recipes/default.rb index a34d2a8..f8f60f3 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -1,89 +1,18 @@ # -# Cookbook Name:: collectd -# Recipe:: default +# Cookbook: collectd +# License: Apache 2.0 # -# Copyright 2010, Atari, Inc +# Copyright 2010, Atari, Inc. +# Copyright 2015, 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. -# 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. -# - -package "collectd" do - package_name node[:collectd][:pkg_name] -end - -service "collectd" do - supports :restart => true, :status => true -end - -directory "/etc/collectd" do - owner "root" - group "root" - mode "755" -end - -directory "/etc/collectd/plugins" do - owner "root" - group "root" - mode "755" -end - -directory node[:collectd][:base_dir] do - owner "root" - group "root" - mode "755" - recursive true -end - -directory node[:collectd][:plugin_dir] do - owner "root" - group "root" - mode "755" - recursive true -end - -%w(collectd collection thresholds).each do |file| - template "/etc/collectd/#{file}.conf" do - source "#{file}.conf.erb" - owner "root" - group "root" - mode "644" - notifies :restart, resources(:service => "collectd") - end -end +include_recipe 'yum-epel::default' if platform_family?('redhat') -ruby_block "delete_old_plugins" do - block do - Dir['/etc/collectd/plugins/*.conf'].each do |path| - autogen = false - File.open(path).each_line do |line| - if line.start_with?('#') and line.include?('autogenerated') - autogen = true - break - end - end - if autogen - begin - resources(:template => path) - rescue ArgumentError, Chef::Exceptions::ResourceNotFound - # If the file is autogenerated and has no template it has likely been removed from the run list - Chef::Log.info("Deleting old plugin config in #{path}") - File.unlink(path) - end - end - end - end +poise_service_user node['collectd']['service_user'] do + group node['collectd']['service_group'] end -service "collectd" do - action [:enable, :start] +collectd_service node['collectd']['service_name'] do |r| + user node['collectd']['service_user'] + group node['collectd']['service_group'] + node['collectd']['service'].each_pair { |k, v| r.send(k, v) } end diff --git a/recipes/server.rb b/recipes/server.rb index 08b6320..02df9ec 100644 --- a/recipes/server.rb +++ b/recipes/server.rb @@ -1,24 +1,15 @@ # -# Cookbook Name:: collectd -# Recipe:: server +# Cookbook: collectd +# License: Apache 2.0 # -# Copyright 2010, Atari, Inc +# Copyright 2010, Atari, Inc. +# Copyright 2015, 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. -# 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. -# - -include_recipe "collectd" +include_recipe 'collectd::default' -collectd_plugin "network" do - options :listen=>'0.0.0.0' +collectd_plugin 'network' do + user node['collectd']['service_user'] + group node['collectd']['service_group'] + options node['collectd']['server']['options'] unless node['collectd']['server'].nil? + notifies :restart, "collectd_service[#{node['collectd']['service_name']}]", :delayed end diff --git a/recipes/web.rb b/recipes/web.rb new file mode 100644 index 0000000..a848a2c --- /dev/null +++ b/recipes/web.rb @@ -0,0 +1,34 @@ +# +# Cookbook: collectd +# License: Apache 2.0 +# +# Copyright 2010, Atari, Inc. +# Copyright 2015, Bloomberg Finance L.P. +# +require 'yaml' +include_recipe 'collectd::default' + +package %w(libhtml-parser liburi-perl librrds-perl libjson-perl) + +directory File.dirname(node['collectd']['web']['options']['data_dir']) do + recursive true + owner node['collectd']['service_user'] + group node['collectd']['service_group'] +end + +file '/etc/collectd.d/collection.conf' do + content node['collectd']['web']['options'].to_yaml + owner node['collectd']['service_user'] + group node['collectd']['service_group'] + mode '0640' +end + +# TODO: (jbellone) libartifact + +httpd_service 'default' do + action [:create, :start] +end + +httpd_config 'default' do + notifies :restart, 'httpd_service[default]' +end diff --git a/templates/default/collectd.conf.erb b/templates/default/collectd.conf.erb deleted file mode 100644 index b1e3964..0000000 --- a/templates/default/collectd.conf.erb +++ /dev/null @@ -1,18 +0,0 @@ -# Config file for collectd(1). -# -# Some plugins need additional configuration and are disabled by default. -# Please read collectd.conf(5) for details. -# -# You should also read /usr/share/doc/collectd/README.Debian.plugins before -# enabling any more plugins. - -Hostname "<%= @node[:fqdn] %>" -FQDNLookup true -BaseDir "<%= @node[:collectd][:base_dir] %>" -PluginDir "<%= @node[:collectd][:plugin_dir] %>" -TypesDB "<%= @node[:collectd][:types_db].join('", "') %>" -Interval <%= @node[:collectd][:interval] %> -ReadThreads <%= @node[:collectd][:read_threads] %> - -Include "/etc/collectd/plugins/*.conf" -Include "/etc/collectd/thresholds.conf" diff --git a/templates/default/plugin.conf.erb b/templates/default/plugin.conf.erb deleted file mode 100644 index ac5a824..0000000 --- a/templates/default/plugin.conf.erb +++ /dev/null @@ -1,15 +0,0 @@ -# This file autogenerated by Chef -# Do not edit, changes will be overwritten -LoadPlugin "<%= @name %>" - -<% if not @options.empty? %> -"> - <% @options.each_pair do |key, value| - if value.is_a? Array - value.each do |subvalue| %> - <%= collectd_key(key) %> <%= collectd_option(subvalue) %> - <% end else %> - <%= collectd_key(key) %> <%= collectd_option(value) %> - <% end end %> - -<% end %> diff --git a/templates/default/thresholds.conf.erb b/templates/default/thresholds.conf.erb deleted file mode 100644 index 690d103..0000000 --- a/templates/default/thresholds.conf.erb +++ /dev/null @@ -1,37 +0,0 @@ -# Threshold configuration for collectd(1). -# -# See the section "THRESHOLD CONFIGURATION" in collectd.conf(5) for details. - -# -# -# WarningMin 0.00 -# WarningMax 1000.00 -# FailureMin 0 -# FailureMax 1200.00 -# Invert false -# Persist false -# Instance "some_instance" -# -# -# -# Instance "eth0" -# -# DataSource "rx" -# FailureMax 10000000 -# -# -# -# -# -# Instance "idle" -# FailureMin 10 -# -# -# -# -# Instance "cached" -# WarningMin 100000000 -# -# -# -# diff --git a/test/integration/client/serverspec/client_spec.rb b/test/integration/client/serverspec/client_spec.rb new file mode 100644 index 0000000..72833c5 --- /dev/null +++ b/test/integration/client/serverspec/client_spec.rb @@ -0,0 +1,5 @@ +require 'server_spec' + +describe file('/etc/collectd.d/network.conf') do + it { should be_file } +end diff --git a/test/integration/default/serverspec/default_spec.rb b/test/integration/default/serverspec/default_spec.rb new file mode 100644 index 0000000..07ae3b7 --- /dev/null +++ b/test/integration/default/serverspec/default_spec.rb @@ -0,0 +1,46 @@ +require 'spec_helper' + +describe group('collectd') do + it { should exist } +end + +describe user('collectd') do + it { should exist } +end + +describe file('/var/lib/collectd') do + it { should be_directory } + it { should be_owned_by 'root' } + it { should be_grouped_into 'root' } +end + +describe file('/usr/lib64/collectd') do + it { should be_directory } + it { should be_owned_by 'root' } + it { should be_grouped_into 'root' } +end + +describe file('/etc/collectd.d') do + it { should be_directory } + it { should be_owned_by 'collectd' } + it { should be_grouped_into 'collectd' } +end + +describe file('/etc/collectd.conf') do + it { should be_file } + it { should be_owned_by 'collectd'} + it { should be_grouped_into 'collectd' } + it { should contain 'Interval 10' } + it { should contain 'ReadThreads 5' } + it { should contain 'WriteThreads 5' } + it { should_not contain 'Timeout' } + it { should_not contain 'WriteQueueLimitHigh' } + it { should_not contain 'WriteQueueLimitLow' } + it { should contain 'Include "/etc/collectd.d"' } +end + +describe file('/etc/collectd.d/threshold.conf') do + it { should be_file } + it { should be_owned_by 'collectd'} + it { should be_grouped_into 'collectd' } +end diff --git a/test/integration/helpers/serverspec/spec_helper.rb b/test/integration/helpers/serverspec/spec_helper.rb new file mode 100644 index 0000000..37af1b4 --- /dev/null +++ b/test/integration/helpers/serverspec/spec_helper.rb @@ -0,0 +1,3 @@ +require 'serverspec' + +set :backend, :exec diff --git a/test/integration/server/serverspec/server_spec.rb b/test/integration/server/serverspec/server_spec.rb new file mode 100644 index 0000000..d5c659d --- /dev/null +++ b/test/integration/server/serverspec/server_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe file('/etc/collectd.d/network.conf') do + it { should be_file } +end diff --git a/test/integration/web/serverspec/web_spec.rb b/test/integration/web/serverspec/web_spec.rb new file mode 100644 index 0000000..778d1c6 --- /dev/null +++ b/test/integration/web/serverspec/web_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe group('collectd') do + it { should exist } +end + +describe user('collectd') do + it { should exist } +end + +describe directory('/etc/collectd.d/collectd-web') do + it { should be_directory } + it { should be_owned_by 'collectd' } + it { should be_grouped_into 'collectd' } +end diff --git a/test/spec/libraries/collectd_plugin_spec.rb b/test/spec/libraries/collectd_plugin_spec.rb new file mode 100644 index 0000000..a2d1c6e --- /dev/null +++ b/test/spec/libraries/collectd_plugin_spec.rb @@ -0,0 +1,25 @@ +require 'chefspec/berkshelf' +require 'poise_boiler/spec_helper' +require_relative '../../../libraries/collectd_plugin' + +describe CollectdCookbook::Resource::CollectdPlugin do + step_into(:collectd_plugin) + context 'enables syslog plugin' do + recipe do + collectd_plugin 'syslog' do + options do + log_level 'info' + end + end + end + + it { is_expected.to render_file('/etc/collectd.d/syslog.conf').with_content(<<-EOH.chomp) } +# This file is autogenerated by Chef. +# Do not edit; All changes will be overwritten! +LoadPlugin "syslog" + + LogLevel "info" + +EOH + end +end diff --git a/test/spec/libraries/collectd_service_spec.rb b/test/spec/libraries/collectd_service_spec.rb new file mode 100644 index 0000000..aa9b411 --- /dev/null +++ b/test/spec/libraries/collectd_service_spec.rb @@ -0,0 +1,7 @@ +require 'chefspec/berkshelf' +require 'poise_boiler/spec_helper' +require_relative '../../../libraries/collectd_plugin' + +describe CollectdCookbook::Resource::CollectdService do + step_into(:collectd_service) +end diff --git a/test/spec/recipes/client_spec.rb b/test/spec/recipes/client_spec.rb new file mode 100644 index 0000000..89255c5 --- /dev/null +++ b/test/spec/recipes/client_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' + +describe_recipe 'collectd::client' do + cached(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) } + it { expect(chef_run).to include_recipe('collectd::default') } + + it do + expect(chef_run).to create_collectd_plugin('network') + .with(options: {'servers' => []}) + end + + context 'with default attributes' do + it 'converges successfully' do + chef_run + end + end +end diff --git a/test/spec/recipes/default_spec.rb b/test/spec/recipes/default_spec.rb new file mode 100644 index 0000000..5345c78 --- /dev/null +++ b/test/spec/recipes/default_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe_recipe 'collectd::default' do + cached(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) } + it do + expect(chef_run).to enable_collectd_service('collectd') + .with(service_user: 'collectd') + .with(service_group: 'collectd') + end + + context 'with default attributes' do + it 'converges successfully' do + chef_run + end + end +end diff --git a/test/spec/recipes/server_spec.rb b/test/spec/recipes/server_spec.rb new file mode 100644 index 0000000..967c0c2 --- /dev/null +++ b/test/spec/recipes/server_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' + +describe_recipe 'collectd::server' do + cached(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) } + it { expect(chef_run).to include_recipe('collectd::default') } + + it do + expect(chef_run).to create_collectd_plugin('network') + .with(options: {'listen' => '0.0.0.0'}) + end + + context 'with default attributes' do + it 'converges successfully' do + chef_run + end + end +end diff --git a/test/spec/recipes/web_spec.rb b/test/spec/recipes/web_spec.rb new file mode 100644 index 0000000..806b911 --- /dev/null +++ b/test/spec/recipes/web_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe_recipe 'collectd::web' do + it { expect(chef_run).to include_recipe('collectd::default') } + it { expect(chef_run).to create_httpd_service('default') } + it { expect(chef_run).to enable_httpd_service('default') } + it { expect(chef_run).to create_httpd_config('default') } + it { expect(chef_run).to create_directory('/etc/collectd.d/collectd-web') } + it { expect(chef_run).to render_file('/etc/collectd.d/collection.conf') } + context 'with default attributes' do + it 'converges successfully' do + chef_run + end + end +end diff --git a/test/spec/spec_helper.rb b/test/spec/spec_helper.rb new file mode 100644 index 0000000..e31950c --- /dev/null +++ b/test/spec/spec_helper.rb @@ -0,0 +1,40 @@ +require 'chefspec' +require 'chefspec/berkshelf' +require 'chefspec/cacher' + +RSpec.configure do |config| + # Set default platform family and version for ChefSpec. + config.platform = 'redhat' + config.version = '6.4' + + config.color = true + config.alias_example_group_to :describe_recipe, type: :recipe + config.alias_example_group_to :describe_resource, type: :resource + + config.filter_run :focus + config.run_all_when_everything_filtered = true + + Kernel.srand config.seed + config.order = :random + + config.default_formatter = 'doc' if config.files_to_run.one? + + config.expect_with :rspec do |expectations| + expectations.syntax = :expect + end + + config.mock_with :rspec do |mocks| + mocks.syntax = :expect + mocks.verify_partial_doubles = true + end +end + +at_exit { ChefSpec::Coverage.report! } + +module ChefSpec::Macros + alias_method :described_resource, :described_recipe +end + +RSpec.shared_context 'recipe tests', type: :recipe do + let(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) } +end From a5f4ae78c99e395399ddceca64b942eaf87e6706 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Tue, 1 Sep 2015 06:54:44 -0400 Subject: [PATCH 02/48] Fixes unit tests so that they go green. --- .gitattributes | 8 ++++++++ .gitignore | 1 + libraries/collectd_plugin.rb | 2 +- libraries/collectd_service.rb | 8 ++++++++ test/spec/libraries/collectd_plugin_spec.rb | 3 ++- test/spec/libraries/collectd_service_spec.rb | 3 ++- test/spec/recipes/default_spec.rb | 4 ++-- test/spec/recipes/server_spec.rb | 2 +- test/spec/recipes/web_spec.rb | 15 --------------- 9 files changed, 25 insertions(+), 21 deletions(-) create mode 100644 .gitattributes delete mode 100644 test/spec/recipes/web_spec.rb diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..c9a5fae --- /dev/null +++ b/.gitattributes @@ -0,0 +1,8 @@ +Gemfile export-ignore +Berksfile export-ignore +Vagrantfile export-ignore +Thorfile export-ignore +Guardfile export-ignore +.gitattributes export-ignore +.gitignore export-ignore +.gitmodules export-ignore diff --git a/.gitignore b/.gitignore index 7815158..0360a01 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,4 @@ vendor .kitchen .vagrant Berksfile.lock +coverage/ diff --git a/libraries/collectd_plugin.rb b/libraries/collectd_plugin.rb index 2255244..e44fc30 100644 --- a/libraries/collectd_plugin.rb +++ b/libraries/collectd_plugin.rb @@ -12,7 +12,7 @@ module CollectdCookbook module Resource # A resource for managing collectd plugins. # @since 2.0.0 - class Chef::Resource::CollectdPlugin < Chef::Resource + class CollectdPlugin < Chef::Resource include Poise(fused: true) provides(:collectd_plugin) include CollectdCookbook::Helpers diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb index f20e5ff..0b9b066 100644 --- a/libraries/collectd_service.rb +++ b/libraries/collectd_service.rb @@ -49,6 +49,14 @@ class CollectdService < Chef::Resource # @see {https://collectd.org/documentation/manpages/collectd.conf.5.shtml#global_options} # @return [Hash, Mash] attribute(:configuration, option_collector: true) + + # @!attribute package_name + # @return [String] + attribute(:package_name, kind_of: String, default: 'collectd') + + # @!attribute package_version + # @return [String] + attribute(:package_version, kind_of: String) end end diff --git a/test/spec/libraries/collectd_plugin_spec.rb b/test/spec/libraries/collectd_plugin_spec.rb index a2d1c6e..71089bc 100644 --- a/test/spec/libraries/collectd_plugin_spec.rb +++ b/test/spec/libraries/collectd_plugin_spec.rb @@ -1,3 +1,4 @@ +require 'chefspec' require 'chefspec/berkshelf' require 'poise_boiler/spec_helper' require_relative '../../../libraries/collectd_plugin' @@ -18,7 +19,7 @@ # Do not edit; All changes will be overwritten! LoadPlugin "syslog" - LogLevel "info" + LogLevel "info" EOH end diff --git a/test/spec/libraries/collectd_service_spec.rb b/test/spec/libraries/collectd_service_spec.rb index aa9b411..cc00c6a 100644 --- a/test/spec/libraries/collectd_service_spec.rb +++ b/test/spec/libraries/collectd_service_spec.rb @@ -1,6 +1,7 @@ +require 'chefspec' require 'chefspec/berkshelf' require 'poise_boiler/spec_helper' -require_relative '../../../libraries/collectd_plugin' +require_relative '../../../libraries/collectd_service' describe CollectdCookbook::Resource::CollectdService do step_into(:collectd_service) diff --git a/test/spec/recipes/default_spec.rb b/test/spec/recipes/default_spec.rb index 5345c78..ac4d95c 100644 --- a/test/spec/recipes/default_spec.rb +++ b/test/spec/recipes/default_spec.rb @@ -4,8 +4,8 @@ cached(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) } it do expect(chef_run).to enable_collectd_service('collectd') - .with(service_user: 'collectd') - .with(service_group: 'collectd') + .with(user: 'collectd') + .with(group: 'collectd') end context 'with default attributes' do diff --git a/test/spec/recipes/server_spec.rb b/test/spec/recipes/server_spec.rb index 967c0c2..9bb16ec 100644 --- a/test/spec/recipes/server_spec.rb +++ b/test/spec/recipes/server_spec.rb @@ -6,7 +6,7 @@ it do expect(chef_run).to create_collectd_plugin('network') - .with(options: {'listen' => '0.0.0.0'}) + .with(options: {'listen' => '0.0.0.0'}) end context 'with default attributes' do diff --git a/test/spec/recipes/web_spec.rb b/test/spec/recipes/web_spec.rb deleted file mode 100644 index 806b911..0000000 --- a/test/spec/recipes/web_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'spec_helper' - -describe_recipe 'collectd::web' do - it { expect(chef_run).to include_recipe('collectd::default') } - it { expect(chef_run).to create_httpd_service('default') } - it { expect(chef_run).to enable_httpd_service('default') } - it { expect(chef_run).to create_httpd_config('default') } - it { expect(chef_run).to create_directory('/etc/collectd.d/collectd-web') } - it { expect(chef_run).to render_file('/etc/collectd.d/collection.conf') } - context 'with default attributes' do - it 'converges successfully' do - chef_run - end - end -end From e66b42c1c117a33d72f9ea9d63ad5069d225dfad Mon Sep 17 00:00:00 2001 From: John Bellone Date: Tue, 1 Sep 2015 09:48:11 -0400 Subject: [PATCH 03/48] Fixes linting errors which Rubocop found. --- .rubocop.yml | 11 ++++++++--- README.md | 1 + libraries/collectd_plugin.rb | 4 ++-- libraries/collectd_service.rb | 2 +- libraries/helpers.rb | 14 +++++++------- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index f10013f..3404433 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -26,18 +26,23 @@ CyclomaticComplexity: Style/FileName: Enabled: false +Style/FirstParameterIndentation: + Enabled: false + Style/ClassAndModuleChildren: Enabled: false +Style/PercentLiteralDelimiters: + Enabled: false + Metrics/AbcSize: Enabled: false AllCops: Exclude: - 'Guardfile' - - 'test/**/*_test.rb' - - 'test/**/*_spec.rb' - - 'bin/**' + - 'test/**/*.rb' + - 'bin/*' Style/GuardClause: Enabled: false diff --git a/README.md b/README.md index e293b29..bb912c9 100644 --- a/README.md +++ b/README.md @@ -49,3 +49,4 @@ end [1]: https://collectd.org [2]: https://github.com/test-kitchen/test-kitchen [3]: https://collectd.org/wiki/index.php/Plugin:SysLog +[4]: https://github.com/coderanger/chef-collectd_plugins diff --git a/libraries/collectd_plugin.rb b/libraries/collectd_plugin.rb index e44fc30..9369818 100644 --- a/libraries/collectd_plugin.rb +++ b/libraries/collectd_plugin.rb @@ -55,8 +55,8 @@ class CollectdPlugin < Chef::Resource directives = [ '# This file is autogenerated by Chef.', '# Do not edit; All changes will be overwritten!', - %Q(LoadPlugin "#{new_resource.plugin_name}"), - %Q(), + %(LoadPlugin "#{new_resource.plugin_name}"), + %(), new_resource.build_configuration(new_resource.options, 1), "\n" ] diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb index 0b9b066..b35a682 100644 --- a/libraries/collectd_service.rb +++ b/libraries/collectd_service.rb @@ -90,7 +90,7 @@ def action_enable 'base_dir' => new_resource.directory, 'hostname' => node['hostname'] )), - %Q(Include "#{new_resource.config_directory}"\n) + %(Include "#{new_resource.config_directory}"\n) ] file new_resource.config_filename do diff --git a/libraries/helpers.rb b/libraries/helpers.rb index e617b9f..b35d771 100644 --- a/libraries/helpers.rb +++ b/libraries/helpers.rb @@ -13,29 +13,29 @@ module Helpers # @param [String] # @return [String] def snake_to_camel(s) - s.to_s.split('_').map(&:capitalize).join("") + s.to_s.split('_').map(&:capitalize).join('') end # Builds a configuration file from {directives} and applys {indent}. # @param [Hash] directives # @param [Integer] indent # @return [String] - def build_configuration(directives, indent=0) + def build_configuration(directives, indent = 0) tabs = ("\t" * indent) directives.map do |key, value| next if value.nil? key = snake_to_camel(key) if value.is_a?(Array) - %Q(#{tabs}#{key} "#{value.uniq.join('", "')}") - elsif value.kind_of?(Hash) + %(#{tabs}#{key} "#{value.uniq.join('", "')}") + elsif value.kind_of?(Hash) # rubocop:disable Style/ClassCheck value.map do |n, v| n = snake_to_camel(n) - %Q(#{tabs}<#{key} "#{n}">\n#{build_configuration(v, indent.next)}\n#{tabs}) + %(#{tabs}<#{key} "#{n}">\n#{build_configuration(v, indent.next)}\n#{tabs}) end elsif value.is_a?(String) - %Q(#{tabs}#{key} "#{value.to_s}") + %(#{tabs}#{key} "#{value}") else - %Q(#{tabs}#{key} #{value.to_s}) + %(#{tabs}#{key} #{value}) end end.flatten.join("\n") end From d2900ae93a12d1efa82a0f4090a63fd55792b8b8 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Wed, 2 Sep 2015 10:13:13 -0400 Subject: [PATCH 04/48] Fixes issue where poise_service_user runs if set root. If we're the root user we shouldn't try to create it. --- recipes/default.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/recipes/default.rb b/recipes/default.rb index f8f60f3..dce37f8 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -9,6 +9,7 @@ poise_service_user node['collectd']['service_user'] do group node['collectd']['service_group'] + not_if { node['collectd']['service_user'] == node['root_user'] } end collectd_service node['collectd']['service_name'] do |r| From 8be8432468c1ab28d926c6273e45104da47c4044 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Wed, 2 Sep 2015 10:13:35 -0400 Subject: [PATCH 05/48] Removes the client/server recipes. These recipes should now be used from collectd_plugins cookbook. --- recipes/client.rb | 15 --------------- recipes/server.rb | 15 --------------- test/spec/recipes/client_spec.rb | 17 ----------------- test/spec/recipes/server_spec.rb | 17 ----------------- 4 files changed, 64 deletions(-) delete mode 100644 recipes/client.rb delete mode 100644 recipes/server.rb delete mode 100644 test/spec/recipes/client_spec.rb delete mode 100644 test/spec/recipes/server_spec.rb diff --git a/recipes/client.rb b/recipes/client.rb deleted file mode 100644 index 2e539fa..0000000 --- a/recipes/client.rb +++ /dev/null @@ -1,15 +0,0 @@ -# -# Cookbook: collectd -# License: Apache 2.0 -# -# Copyright 2010, Atari, Inc. -# Copyright 2015, Bloomberg Finance L.P. -# -include_recipe 'collectd::default' - -collectd_plugin 'network' do - user node['collectd']['service_user'] - group node['collectd']['service_group'] - options node['collectd']['client']['options'] unless node['collectd']['client'].nil? - notifies :restart, "collectd_service[#{node['collectd']['service_name']}]", :delayed -end diff --git a/recipes/server.rb b/recipes/server.rb deleted file mode 100644 index 02df9ec..0000000 --- a/recipes/server.rb +++ /dev/null @@ -1,15 +0,0 @@ -# -# Cookbook: collectd -# License: Apache 2.0 -# -# Copyright 2010, Atari, Inc. -# Copyright 2015, Bloomberg Finance L.P. -# -include_recipe 'collectd::default' - -collectd_plugin 'network' do - user node['collectd']['service_user'] - group node['collectd']['service_group'] - options node['collectd']['server']['options'] unless node['collectd']['server'].nil? - notifies :restart, "collectd_service[#{node['collectd']['service_name']}]", :delayed -end diff --git a/test/spec/recipes/client_spec.rb b/test/spec/recipes/client_spec.rb deleted file mode 100644 index 89255c5..0000000 --- a/test/spec/recipes/client_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'spec_helper' - -describe_recipe 'collectd::client' do - cached(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) } - it { expect(chef_run).to include_recipe('collectd::default') } - - it do - expect(chef_run).to create_collectd_plugin('network') - .with(options: {'servers' => []}) - end - - context 'with default attributes' do - it 'converges successfully' do - chef_run - end - end -end diff --git a/test/spec/recipes/server_spec.rb b/test/spec/recipes/server_spec.rb deleted file mode 100644 index 9bb16ec..0000000 --- a/test/spec/recipes/server_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'spec_helper' - -describe_recipe 'collectd::server' do - cached(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) } - it { expect(chef_run).to include_recipe('collectd::default') } - - it do - expect(chef_run).to create_collectd_plugin('network') - .with(options: {'listen' => '0.0.0.0'}) - end - - context 'with default attributes' do - it 'converges successfully' do - chef_run - end - end -end From aa4d08bffc3ae06e23feb7cd90b74f684e310c6c Mon Sep 17 00:00:00 2001 From: John Bellone Date: Wed, 2 Sep 2015 10:13:53 -0400 Subject: [PATCH 06/48] Updates the collectd service options in resource. --- libraries/collectd_service.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb index b35a682..52125ff 100644 --- a/libraries/collectd_service.rb +++ b/libraries/collectd_service.rb @@ -114,6 +114,9 @@ def action_disable # @param [PoiseService::Service] service def service_options(service) service.command("/usr/sbin/collectd -C #{new_resource.config_filename} -f") + service.directory(new_resource.directory) + service.user(new_resource.user) + service.environment(new_resource.environment) service.restart_on_update(true) end end From 757d9f664b6d6f0c1f6f416f6cafdb0c9d83c916 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Wed, 2 Sep 2015 10:14:33 -0400 Subject: [PATCH 07/48] Removes the web recipe from the cookbook. I'll add this back later. For now let's get a working, reusable collectd cookbook. --- recipes/web.rb | 34 ---------------------------------- 1 file changed, 34 deletions(-) delete mode 100644 recipes/web.rb diff --git a/recipes/web.rb b/recipes/web.rb deleted file mode 100644 index a848a2c..0000000 --- a/recipes/web.rb +++ /dev/null @@ -1,34 +0,0 @@ -# -# Cookbook: collectd -# License: Apache 2.0 -# -# Copyright 2010, Atari, Inc. -# Copyright 2015, Bloomberg Finance L.P. -# -require 'yaml' -include_recipe 'collectd::default' - -package %w(libhtml-parser liburi-perl librrds-perl libjson-perl) - -directory File.dirname(node['collectd']['web']['options']['data_dir']) do - recursive true - owner node['collectd']['service_user'] - group node['collectd']['service_group'] -end - -file '/etc/collectd.d/collection.conf' do - content node['collectd']['web']['options'].to_yaml - owner node['collectd']['service_user'] - group node['collectd']['service_group'] - mode '0640' -end - -# TODO: (jbellone) libartifact - -httpd_service 'default' do - action [:create, :start] -end - -httpd_config 'default' do - notifies :restart, 'httpd_service[default]' -end From ff5d3bf7f23735ef1b8b6c7a88bb5468958a018d Mon Sep 17 00:00:00 2001 From: John Bellone Date: Wed, 2 Sep 2015 10:15:23 -0400 Subject: [PATCH 08/48] Removes old default attributes no longer necessary. --- attributes/default.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/attributes/default.rb b/attributes/default.rb index b5af151..82a6041 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -17,7 +17,3 @@ default['collectd']['service']['configuration']['plugin_dir'] = '/usr/lib64/collectd' default['collectd']['service']['configuration']['types_d_b'] = '/usr/share/collectd/types.db' - -default['collectd']['web']['options'] = { 'data_dir' => '/etc/collectd.d/collectd-web' } -default['collectd']['client']['options']['servers'] = [] -default['collectd']['server']['options']['listen'] = '0.0.0.0' From 598dd73cf1c271dbcf6ea8d2c2d6ae3f89f20fa1 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Wed, 2 Sep 2015 12:26:27 -0400 Subject: [PATCH 09/48] Fixes helper to properly build nested configs. --- libraries/collectd_plugin.rb | 19 +++++++--- libraries/helpers.rb | 10 +++--- test/spec/libraries/helpers_spec.rb | 54 +++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 9 deletions(-) create mode 100644 test/spec/libraries/helpers_spec.rb diff --git a/libraries/collectd_plugin.rb b/libraries/collectd_plugin.rb index 9369818..29eeddd 100644 --- a/libraries/collectd_plugin.rb +++ b/libraries/collectd_plugin.rb @@ -13,9 +13,9 @@ module Resource # A resource for managing collectd plugins. # @since 2.0.0 class CollectdPlugin < Chef::Resource - include Poise(fused: true) + include Poise provides(:collectd_plugin) - include CollectdCookbook::Helpers + actions(:create, :delete) # @!attribute plugin_name # Name of the collectd plugin to install and configure. @@ -44,8 +44,17 @@ class CollectdPlugin < Chef::Resource # Set of key-value options to configure the plugin. # @return [Hash, Mash] attribute(:options, option_collector: true) + end + end + + module Provider + # @since 2.0.0 + class CollectdPlugin < Chef::Provider + include Poise + provides(:collectd_plugin) + include CollectdCookbook::Helpers - action(:create) do + def action_create notifying_block do directory new_resource.directory do recursive true @@ -57,7 +66,7 @@ class CollectdPlugin < Chef::Resource '# Do not edit; All changes will be overwritten!', %(LoadPlugin "#{new_resource.plugin_name}"), %(), - new_resource.build_configuration(new_resource.options, 1), + self.build_configuration(new_resource.options, 1), "\n" ] @@ -68,7 +77,7 @@ class CollectdPlugin < Chef::Resource end end - action(:delete) do + def action_delete notifying_block do file ::File.join(new_resource.directory, "#{new_resource.plugin_name}.conf") do action :delete diff --git a/libraries/helpers.rb b/libraries/helpers.rb index b35d771..91dbf12 100644 --- a/libraries/helpers.rb +++ b/libraries/helpers.rb @@ -28,10 +28,12 @@ def build_configuration(directives, indent = 0) if value.is_a?(Array) %(#{tabs}#{key} "#{value.uniq.join('", "')}") elsif value.kind_of?(Hash) # rubocop:disable Style/ClassCheck - value.map do |n, v| - n = snake_to_camel(n) - %(#{tabs}<#{key} "#{n}">\n#{build_configuration(v, indent.next)}\n#{tabs}) - end + id = value.delete('id') + next if id.nil? + [%(#{tabs}<#{key} "#{id}">), + build_configuration(value, indent.next), + %(#{tabs}) + ].join("\n") elsif value.is_a?(String) %(#{tabs}#{key} "#{value}") else diff --git a/test/spec/libraries/helpers_spec.rb b/test/spec/libraries/helpers_spec.rb new file mode 100644 index 0000000..aa8ad84 --- /dev/null +++ b/test/spec/libraries/helpers_spec.rb @@ -0,0 +1,54 @@ +require_relative '../../../libraries/helpers' +describe CollectdCookbook::Helpers do + let(:subject) do + Class.new { include CollectdCookbook::Helpers }.new + end + + it { is_expected.to respond_to(:snake_to_camel).with(1).arguments } + it { is_expected.to respond_to(:build_configuration).with(1).arguments } + it { is_expected.to respond_to(:build_configuration).with(2).arguments } + + context '#snake_to_camel' do + it { expect(subject.snake_to_camel('load_plugin')).to eq('LoadPlugin') } + it { expect(subject.snake_to_camel('format')).to eq('Format') } + it { expect(subject.snake_to_camel('j_s_o_n')).to eq('JSON') } + end + + context '#build_configuration' do + it { expect(subject.build_configuration('string' => 'string')).to eq(%(String "string")) } + it { expect(subject.build_configuration('integer' => 1)).to eq(%(Integer 1)) } + it { expect(subject.build_configuration('true_class' => true)).to eq(%(TrueClass true)) } + it { expect(subject.build_configuration('false_class' => false)).to eq(%(FalseClass false)) } + it { expect(subject.build_configuration('symbol' => :symbol)).to eq(%(Symbol symbol)) } + it { expect(subject.build_configuration('array' => [1, 2, 3])).to eq(%(Array "1", "2", "3")) } + + it do + expect(subject.build_configuration('hash' => { + 'id' => 'id', + 'string' => 'string', + 'integer' => 1, + 'true_class' => true, + 'false_class' => false, + 'symbol' => :symbol, + 'array' => %w{1 2 3}, + 'hash' => { + 'id' => 'id', + 'string' => 'string' + } + })).to eq(<<-EOH.chomp) + + String "string" + Integer 1 + TrueClass true + FalseClass false + Symbol symbol + Array "1", "2", "3" + + String "string" + + +EOH + end + + end +end From 4a7129dbd8e5f45aea5d296fdf95828ecf990c37 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Wed, 2 Sep 2015 14:43:37 -0400 Subject: [PATCH 10/48] Fixes rubocop linting errors found in travis. --- libraries/collectd_plugin.rb | 2 +- libraries/helpers.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/collectd_plugin.rb b/libraries/collectd_plugin.rb index 29eeddd..ec5f103 100644 --- a/libraries/collectd_plugin.rb +++ b/libraries/collectd_plugin.rb @@ -66,7 +66,7 @@ def action_create '# Do not edit; All changes will be overwritten!', %(LoadPlugin "#{new_resource.plugin_name}"), %(), - self.build_configuration(new_resource.options, 1), + build_configuration(new_resource.options, 1), "\n" ] diff --git a/libraries/helpers.rb b/libraries/helpers.rb index 91dbf12..ec67a0a 100644 --- a/libraries/helpers.rb +++ b/libraries/helpers.rb @@ -31,8 +31,8 @@ def build_configuration(directives, indent = 0) id = value.delete('id') next if id.nil? [%(#{tabs}<#{key} "#{id}">), - build_configuration(value, indent.next), - %(#{tabs}) + build_configuration(value, indent.next), + %(#{tabs}) ].join("\n") elsif value.is_a?(String) %(#{tabs}#{key} "#{value}") From 92094a0b03dbf4d90a23704c769f372fdde0c116 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Wed, 9 Sep 2015 11:13:05 -0400 Subject: [PATCH 11/48] Adds collectd configuration resource. This replaces the helper code which was used in both the plugin and service resources. --- .kitchen.yml | 11 +-- README.md | 14 +++ attributes/default.rb | 4 + libraries/collectd_config.rb | 92 +++++++++++++++++++ libraries/collectd_plugin.rb | 47 ++++------ libraries/collectd_service.rb | 51 +++++----- libraries/helpers.rb | 45 --------- metadata.rb | 1 - templates/default/collectd_web.conf.erb | 32 ------- templates/default/collection.conf.erb | 2 - templates/default/python_plugin.conf.erb | 20 ---- .../client/serverspec/client_spec.rb | 5 - .../default/serverspec/default_spec.rb | 21 ++--- .../helpers/serverspec/spec_helper.rb | 1 - .../server/serverspec/server_spec.rb | 5 - test/integration/web/serverspec/web_spec.rb | 15 --- test/spec/libraries/collectd_config_spec.rb | 59 ++++++++++++ test/spec/libraries/collectd_plugin_spec.rb | 18 ++-- test/spec/libraries/collectd_service_spec.rb | 18 ++++ test/spec/libraries/helpers_spec.rb | 54 ----------- test/spec/recipes/default_spec.rb | 1 + 21 files changed, 256 insertions(+), 260 deletions(-) create mode 100644 libraries/collectd_config.rb delete mode 100644 libraries/helpers.rb delete mode 100644 templates/default/collectd_web.conf.erb delete mode 100644 templates/default/collection.conf.erb delete mode 100644 templates/default/python_plugin.conf.erb delete mode 100644 test/integration/client/serverspec/client_spec.rb delete mode 100644 test/integration/server/serverspec/server_spec.rb delete mode 100644 test/integration/web/serverspec/web_spec.rb create mode 100644 test/spec/libraries/collectd_config_spec.rb delete mode 100644 test/spec/libraries/helpers_spec.rb diff --git a/.kitchen.yml b/.kitchen.yml index 42d701b..a9e0870 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -10,19 +10,10 @@ platforms: - name: ubuntu-12.04 - name: ubuntu-10.04 - name: centos-7.1 - - name: centos-6.6 + - name: centos-6.7 - name: centos-5.11 suites: - name: default run_list: - recipe[collectd::default] - - name: server - run_list: - - recipe[collectd::server] - - name: client - run_list: - - recipe[collectd::client] - - name: web - run_list: - - recipe[collectd::web] diff --git a/README.md b/README.md index bb912c9..3f5373f 100644 --- a/README.md +++ b/README.md @@ -45,8 +45,22 @@ collectd_plugin 'syslog' do end ``` +## Advanced Usage +In order to enable the full functionality of some of the more +intrusive collectd plugins the daemon will need to run as the root +user. Since this is obviously a security risk it is not the default. +To achieve this behavior you're required to write a +[wrapper cookbook][5] which overrides the service user with the proper +root user. +```ruby +node.default['collectd']['service_user'] = node['root_user'] +node.default['collectd']['service_group'] = node['root_group'] +include_recipe 'collectd::default' +``` + [0]: http://blog.vialstudios.com/the-environment-cookbook-pattern#theapplicationcookbook [1]: https://collectd.org [2]: https://github.com/test-kitchen/test-kitchen [3]: https://collectd.org/wiki/index.php/Plugin:SysLog [4]: https://github.com/coderanger/chef-collectd_plugins +[5]: http://blog.vialstudios.com/the-environment-cookbook-pattern/#thewrappercookbook diff --git a/attributes/default.rb b/attributes/default.rb index 82a6041..6876ce0 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -17,3 +17,7 @@ default['collectd']['service']['configuration']['plugin_dir'] = '/usr/lib64/collectd' default['collectd']['service']['configuration']['types_d_b'] = '/usr/share/collectd/types.db' +default['collectd']['service']['configuration']['interval'] = 10 +default['collectd']['service']['configuration']['read_threads'] = 5 +default['collectd']['service']['configuration']['write_threads'] = 5 +default['collectd']['service']['configuration']['collect_internal_stats'] = true diff --git a/libraries/collectd_config.rb b/libraries/collectd_config.rb new file mode 100644 index 0000000..34f219b --- /dev/null +++ b/libraries/collectd_config.rb @@ -0,0 +1,92 @@ +# +# Cookbook: collectd +# License: Apache 2.0 +# +# Copyright 2010, Atari, Inc. +# Copyright 2015, Bloomberg Finance L.P. +# +require 'poise' + +module CollectdCookbook + module Resource + # A resource which manages collectd daemon configurations. + # @since 1.0.0 + # @example + # collectd_config '/etc/collectd.conf' do + # configuration('read_threads' => 5, + # 'write_threads' => 5, + # 'interval' => 10 + # ) + # end + class CollectdConfig < Chef::Resource + include Poise(fused: true) + provides(:collectd_config) + + attribute(:path, kind_of: String, name_attribute: true) + attribute(:owner, kind_of: String, default: 'collectd') + attribute(:group, kind_of: String, default: 'collectd') + attribute(:mode, kind_of: String, default: '0644') + + attribute(:configuration, option_collector: true) + + # Produces collectd {configuration} elements from resource. + # @return [String] + def content + write_elements(configuration).concat("\n") + end + + # Converts from snake case to a camel case string. + # @param [String, Symbol] s + # @return [String] + def snake_to_camel(s) + s.to_s.split('_').map(&:capitalize).join('') + end + + # Recursively writes out configuration elements from + # {directives} and applies the appropriate {indent}. + # @param [Hash] directives + # @param [Integer] indent + # @return [String] + def write_elements(directives, indent = 0) + tabs = ("\t" * indent) + directives.map do |key, value| + next if value.nil? + key = snake_to_camel(key) + if value.is_a?(Array) + %(#{tabs}#{key} "#{value.uniq.join('", "')}") + elsif value.kind_of?(Hash) # rubocop:disable Style/ClassCheck + id = value.delete('id') + next if id.nil? + [%(#{tabs}<#{key} "#{id}">), + write_elements(value, indent.next), + %(#{tabs}) + ].join("\n") + elsif value.is_a?(String) + %(#{tabs}#{key} "#{value}") + else + %(#{tabs}#{key} #{value}) + end + end.flatten.join("\n") + end + + action(:create) do + notifying_block do + file new_resource.path do + content new_resource.content + owner new_resource.owner + group new_resource.group + mode new_resource.mode + end + end + end + + action(:delete) do + notifying_block do + file new_resource.path do + action :delete + end + end + end + end + end +end diff --git a/libraries/collectd_plugin.rb b/libraries/collectd_plugin.rb index ec5f103..e35c1bf 100644 --- a/libraries/collectd_plugin.rb +++ b/libraries/collectd_plugin.rb @@ -5,7 +5,6 @@ # Copyright 2010, Atari, Inc. # Copyright 2015, Bloomberg Finance L.P. # -require_relative 'helpers' require 'poise' module CollectdCookbook @@ -13,9 +12,8 @@ module Resource # A resource for managing collectd plugins. # @since 2.0.0 class CollectdPlugin < Chef::Resource - include Poise + include Poise(fused: true) provides(:collectd_plugin) - actions(:create, :delete) # @!attribute plugin_name # Name of the collectd plugin to install and configure. @@ -44,42 +42,37 @@ class CollectdPlugin < Chef::Resource # Set of key-value options to configure the plugin. # @return [Hash, Mash] attribute(:options, option_collector: true) - end - end - module Provider - # @since 2.0.0 - class CollectdPlugin < Chef::Provider - include Poise - provides(:collectd_plugin) - include CollectdCookbook::Helpers + # @return [String] + def config_filename + ::File.join(directory, "#{plugin_name}.conf") + end - def action_create + action(:create) do notifying_block do directory new_resource.directory do recursive true - mode '0644' + owner new_resource.user + group new_resource.group + mode '0755' end - directives = [ - '# This file is autogenerated by Chef.', - '# Do not edit; All changes will be overwritten!', - %(LoadPlugin "#{new_resource.plugin_name}"), - %(), - build_configuration(new_resource.options, 1), - "\n" - ] - - file ::File.join(new_resource.directory, "#{new_resource.plugin_name}.conf") do - content directives.flatten.join("\n") - mode '0644' + collectd_config new_resource.config_filename do + owner new_resource.user + group new_resource.group + configuration( + 'load_plugin' => new_resource.plugin_name, + 'plugin' => { + 'id' => new_resource.plugin_name, + }.merge(new_resource.options) + ) end end end - def action_delete + action(:delete) do notifying_block do - file ::File.join(new_resource.directory, "#{new_resource.plugin_name}.conf") do + collectd_config new_resource.config_filename do action :delete end end diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb index 52125ff..d5bbe63 100644 --- a/libraries/collectd_service.rb +++ b/libraries/collectd_service.rb @@ -57,6 +57,10 @@ class CollectdService < Chef::Resource # @!attribute package_version # @return [String] attribute(:package_version, kind_of: String) + + # @!attribute package_source + # @return [String] + attribute(:package_source, kind_of: String) end end @@ -67,35 +71,40 @@ class CollectdService < Chef::Provider include Poise provides(:collectd_service) include PoiseService::ServiceMixin - include CollectdCookbook::Helpers def action_enable notifying_block do + # TODO: (jbellone) Fix the package resource for AIX so that + # it is able to install from a URL. + package_source = if new_resource.package_source + basename = ::File.basename(new_resource.package_source) + remote_file ::File.join(Chef::Config[:file_cache_path], basename) do + source new_resource.package_source + end.path + end + package new_resource.package_name do - version new_resource.package_version if new_resource.package_version + version new_resource.package_version + source package_source action :upgrade end - directory [new_resource.config_directory, new_resource.directory] do - recursive true - owner new_resource.user - group new_resource.group - mode '0755' + [new_resource.directory, new_resource.config_directory].each do |dirname| + directory dirname do + recursive true + owner new_resource.user + group new_resource.group + mode '0755' + end end - directives = [ - '# This file is autogenerated by Chef.', - '# Do not edit; All changes will be overwritten!', - build_configuration(new_resource.configuration.merge( + collectd_config new_resource.config_filename do + owner new_resource.user + group new_resource.group + configuration new_resource.configuration.merge( 'base_dir' => new_resource.directory, - 'hostname' => node['hostname'] - )), - %(Include "#{new_resource.config_directory}"\n) - ] - - file new_resource.config_filename do - content directives.flatten.join("\n") - mode '0644' + 'include' => "#{new_resource.config_directory}/*.conf" + ) end end super @@ -103,7 +112,7 @@ def action_enable def action_disable notifying_block do - file new_resource.config_filename do + collectd_config new_resource.config_filename do action :delete end end @@ -116,7 +125,7 @@ def service_options(service) service.command("/usr/sbin/collectd -C #{new_resource.config_filename} -f") service.directory(new_resource.directory) service.user(new_resource.user) - service.environment(new_resource.environment) + service.environment('PATH' => '/usr/local/bin:/usr/bin:/bin') service.restart_on_update(true) end end diff --git a/libraries/helpers.rb b/libraries/helpers.rb deleted file mode 100644 index ec67a0a..0000000 --- a/libraries/helpers.rb +++ /dev/null @@ -1,45 +0,0 @@ -# -# Cookbook: collectd -# License: Apache 2.0 -# -# Copyright 2010 Atari, Inc. -# Copyright 2015 Bloomberg Finance L.P. -# - -module CollectdCookbook - module Helpers - # Converts from snake case to a camel case string. - # @param [String, Symbol] s - # @param [String] - # @return [String] - def snake_to_camel(s) - s.to_s.split('_').map(&:capitalize).join('') - end - - # Builds a configuration file from {directives} and applys {indent}. - # @param [Hash] directives - # @param [Integer] indent - # @return [String] - def build_configuration(directives, indent = 0) - tabs = ("\t" * indent) - directives.map do |key, value| - next if value.nil? - key = snake_to_camel(key) - if value.is_a?(Array) - %(#{tabs}#{key} "#{value.uniq.join('", "')}") - elsif value.kind_of?(Hash) # rubocop:disable Style/ClassCheck - id = value.delete('id') - next if id.nil? - [%(#{tabs}<#{key} "#{id}">), - build_configuration(value, indent.next), - %(#{tabs}) - ].join("\n") - elsif value.is_a?(String) - %(#{tabs}#{key} "#{value}") - else - %(#{tabs}#{key} #{value}) - end - end.flatten.join("\n") - end - end -end diff --git a/metadata.rb b/metadata.rb index fb7dba0..6e90db0 100644 --- a/metadata.rb +++ b/metadata.rb @@ -10,7 +10,6 @@ supports 'centos', '>= 5.8' supports 'redhat', '>= 5.8' -depends 'httpd' depends 'poise', '~> 2.2' depends 'poise-service', '~> 1.0' depends 'yum-epel' diff --git a/templates/default/collectd_web.conf.erb b/templates/default/collectd_web.conf.erb deleted file mode 100644 index a0757fc..0000000 --- a/templates/default/collectd_web.conf.erb +++ /dev/null @@ -1,32 +0,0 @@ - - ServerName <%= @node[:collectd][:collectd_web][:hostname] %> - - DocumentRoot <%= @node[:collectd][:collectd_web][:path] %> - - Options FollowSymLinks - AllowOverride None - - > - Options Indexes FollowSymLinks MultiViews - AllowOverride None - Order allow,deny - Allow from all - - - ScriptAlias /cgi-bin/ <%= @node[:collectd][:collectd_web][:path] %>/cgi-bin/ - /cgi-bin"> - AllowOverride None - Options ExecCGI -MultiViews - Order allow,deny - Allow from all - - - ErrorLog /var/log/apache2/error.log - - # Possible values include: debug, info, notice, warn, error, crit, - # alert, emerg. - LogLevel warn - - CustomLog /var/log/apache2/access.log combined - ServerSignature On - diff --git a/templates/default/collection.conf.erb b/templates/default/collection.conf.erb deleted file mode 100644 index a114511..0000000 --- a/templates/default/collection.conf.erb +++ /dev/null @@ -1,2 +0,0 @@ -datadir: "/var/lib/collectd/rrd/" -libdir: "/usr/lib/collectd/" diff --git a/templates/default/python_plugin.conf.erb b/templates/default/python_plugin.conf.erb deleted file mode 100644 index 681d795..0000000 --- a/templates/default/python_plugin.conf.erb +++ /dev/null @@ -1,20 +0,0 @@ -# This file autogenerated by Chef -# Do not edit, changes will be overwritten - - Globals true - - - - <% @options[:paths].each do |path| %> - ModulePath "<%= path %>" - <% end %> - <% @options[:modules].each_key do |mod| %> - Import "<%= mod %>" - <% end %> - - <% @options[:modules].each_pair do |mod, config| %> - "> -<%= collectd_settings(config, 2) %> - - <% end %> - diff --git a/test/integration/client/serverspec/client_spec.rb b/test/integration/client/serverspec/client_spec.rb deleted file mode 100644 index 72833c5..0000000 --- a/test/integration/client/serverspec/client_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'server_spec' - -describe file('/etc/collectd.d/network.conf') do - it { should be_file } -end diff --git a/test/integration/default/serverspec/default_spec.rb b/test/integration/default/serverspec/default_spec.rb index 07ae3b7..738b64c 100644 --- a/test/integration/default/serverspec/default_spec.rb +++ b/test/integration/default/serverspec/default_spec.rb @@ -8,16 +8,15 @@ it { should exist } end -describe file('/var/lib/collectd') do - it { should be_directory } - it { should be_owned_by 'root' } - it { should be_grouped_into 'root' } +describe service('collectd') do + it { should be_enabled } + it { should be_running } end -describe file('/usr/lib64/collectd') do +describe file('/var/lib/collectd') do it { should be_directory } - it { should be_owned_by 'root' } - it { should be_grouped_into 'root' } + it { should be_owned_by 'collectd' } + it { should be_grouped_into 'collectd' } end describe file('/etc/collectd.d') do @@ -36,11 +35,5 @@ it { should_not contain 'Timeout' } it { should_not contain 'WriteQueueLimitHigh' } it { should_not contain 'WriteQueueLimitLow' } - it { should contain 'Include "/etc/collectd.d"' } -end - -describe file('/etc/collectd.d/threshold.conf') do - it { should be_file } - it { should be_owned_by 'collectd'} - it { should be_grouped_into 'collectd' } + it { should contain 'Include "/etc/collectd.d/*.conf"' } end diff --git a/test/integration/helpers/serverspec/spec_helper.rb b/test/integration/helpers/serverspec/spec_helper.rb index 37af1b4..590c2fa 100644 --- a/test/integration/helpers/serverspec/spec_helper.rb +++ b/test/integration/helpers/serverspec/spec_helper.rb @@ -1,3 +1,2 @@ require 'serverspec' - set :backend, :exec diff --git a/test/integration/server/serverspec/server_spec.rb b/test/integration/server/serverspec/server_spec.rb deleted file mode 100644 index d5c659d..0000000 --- a/test/integration/server/serverspec/server_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'spec_helper' - -describe file('/etc/collectd.d/network.conf') do - it { should be_file } -end diff --git a/test/integration/web/serverspec/web_spec.rb b/test/integration/web/serverspec/web_spec.rb deleted file mode 100644 index 778d1c6..0000000 --- a/test/integration/web/serverspec/web_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'spec_helper' - -describe group('collectd') do - it { should exist } -end - -describe user('collectd') do - it { should exist } -end - -describe directory('/etc/collectd.d/collectd-web') do - it { should be_directory } - it { should be_owned_by 'collectd' } - it { should be_grouped_into 'collectd' } -end diff --git a/test/spec/libraries/collectd_config_spec.rb b/test/spec/libraries/collectd_config_spec.rb new file mode 100644 index 0000000..172813d --- /dev/null +++ b/test/spec/libraries/collectd_config_spec.rb @@ -0,0 +1,59 @@ +require 'chefspec' +require 'chefspec/berkshelf' +require 'poise_boiler/spec_helper' +require_relative '../../../libraries/collectd_config' + +describe CollectdCookbook::Resource::CollectdConfig do + step_into(:collectd_config) + context '#snake_to_camel' do + recipe do + collectd_config '/etc/collectd.conf' do + configuration( + 'load_plugin' => 'foo', + 'format' => 'bar', + 'j_s_o_n' => 'baz' + ) + end + + it { expect(chef_run).to render_file('/etc/collectd.conf').with_content(<<-EOH.chomp) } +LoadPlugin "foo" +Format "bar" +JSON "baz" +EOH + end + end + + context '#write_elements' do + recipe do + collectd_config '/etc/collectd.conf' do + configuration('hash' => { + 'id' => 'id', + 'string' => 'string', + 'integer' => 1, + 'true_class' => true, + 'false_class' => false, + 'symbol' => :symbol, + 'array' => %w{1 2 3}, + 'hash' => { + 'id' => 'id', + 'string' => 'string' + } + }) + end + end + + it { expect(chef_run).to render_file('/etc/collectd.conf').with_content(<<-EOH.chomp) } + + String "string" + Integer 1 + TrueClass true + FalseClass false + Symbol symbol + Array "1", "2", "3" + + String "string" + + +EOH + end +end diff --git a/test/spec/libraries/collectd_plugin_spec.rb b/test/spec/libraries/collectd_plugin_spec.rb index 71089bc..fa6afc4 100644 --- a/test/spec/libraries/collectd_plugin_spec.rb +++ b/test/spec/libraries/collectd_plugin_spec.rb @@ -14,13 +14,15 @@ end end - it { is_expected.to render_file('/etc/collectd.d/syslog.conf').with_content(<<-EOH.chomp) } -# This file is autogenerated by Chef. -# Do not edit; All changes will be overwritten! -LoadPlugin "syslog" - - LogLevel "info" - -EOH + it do + expect(chef_run).to create_collectd_config('/etc/collectd.d/syslog.conf') + .with(configuration: { + 'load_plugin' => 'syslog', + 'plugin' => { + 'id' => 'syslog', + 'log_level' => 'info' + } + }) + end end end diff --git a/test/spec/libraries/collectd_service_spec.rb b/test/spec/libraries/collectd_service_spec.rb index cc00c6a..5801d77 100644 --- a/test/spec/libraries/collectd_service_spec.rb +++ b/test/spec/libraries/collectd_service_spec.rb @@ -5,4 +5,22 @@ describe CollectdCookbook::Resource::CollectdService do step_into(:collectd_service) + context 'with default attributes' do + recipe do + collectd_service 'collectd' + end + + it do + expect(chef_run).to create_directory('/etc/collectd.d') + .with(owner: 'collectd', group: 'collectd', mode: '0755') + end + + it do + expect(chef_run).to create_collectd_config('/etc/collectd.conf') + .with(configuration: { + 'include' => '/etc/collectd.d/*.conf', + 'base_dir' => '/var/lib/collectd' + }) + end + end end diff --git a/test/spec/libraries/helpers_spec.rb b/test/spec/libraries/helpers_spec.rb deleted file mode 100644 index aa8ad84..0000000 --- a/test/spec/libraries/helpers_spec.rb +++ /dev/null @@ -1,54 +0,0 @@ -require_relative '../../../libraries/helpers' -describe CollectdCookbook::Helpers do - let(:subject) do - Class.new { include CollectdCookbook::Helpers }.new - end - - it { is_expected.to respond_to(:snake_to_camel).with(1).arguments } - it { is_expected.to respond_to(:build_configuration).with(1).arguments } - it { is_expected.to respond_to(:build_configuration).with(2).arguments } - - context '#snake_to_camel' do - it { expect(subject.snake_to_camel('load_plugin')).to eq('LoadPlugin') } - it { expect(subject.snake_to_camel('format')).to eq('Format') } - it { expect(subject.snake_to_camel('j_s_o_n')).to eq('JSON') } - end - - context '#build_configuration' do - it { expect(subject.build_configuration('string' => 'string')).to eq(%(String "string")) } - it { expect(subject.build_configuration('integer' => 1)).to eq(%(Integer 1)) } - it { expect(subject.build_configuration('true_class' => true)).to eq(%(TrueClass true)) } - it { expect(subject.build_configuration('false_class' => false)).to eq(%(FalseClass false)) } - it { expect(subject.build_configuration('symbol' => :symbol)).to eq(%(Symbol symbol)) } - it { expect(subject.build_configuration('array' => [1, 2, 3])).to eq(%(Array "1", "2", "3")) } - - it do - expect(subject.build_configuration('hash' => { - 'id' => 'id', - 'string' => 'string', - 'integer' => 1, - 'true_class' => true, - 'false_class' => false, - 'symbol' => :symbol, - 'array' => %w{1 2 3}, - 'hash' => { - 'id' => 'id', - 'string' => 'string' - } - })).to eq(<<-EOH.chomp) - - String "string" - Integer 1 - TrueClass true - FalseClass false - Symbol symbol - Array "1", "2", "3" - - String "string" - - -EOH - end - - end -end diff --git a/test/spec/recipes/default_spec.rb b/test/spec/recipes/default_spec.rb index ac4d95c..5f8680c 100644 --- a/test/spec/recipes/default_spec.rb +++ b/test/spec/recipes/default_spec.rb @@ -2,6 +2,7 @@ describe_recipe 'collectd::default' do cached(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) } + it { expect(chef_run).to create_poise_service_user('collectd').with(group: 'collectd') } it do expect(chef_run).to enable_collectd_service('collectd') .with(user: 'collectd') From be8c0d697511bba0b3a173d39c8da5fe20bc78e0 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Wed, 9 Sep 2015 13:38:26 -0400 Subject: [PATCH 12/48] Fixes rubocop linting error in travis. --- libraries/collectd_plugin.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/collectd_plugin.rb b/libraries/collectd_plugin.rb index e35c1bf..f9ddf42 100644 --- a/libraries/collectd_plugin.rb +++ b/libraries/collectd_plugin.rb @@ -63,7 +63,7 @@ def config_filename configuration( 'load_plugin' => new_resource.plugin_name, 'plugin' => { - 'id' => new_resource.plugin_name, + 'id' => new_resource.plugin_name }.merge(new_resource.options) ) end From dd00574a9ecb3842f1c0ab954ef4eabbd117cf6c Mon Sep 17 00:00:00 2001 From: Shahul Hameed Date: Tue, 8 Sep 2015 17:49:48 +0000 Subject: [PATCH 13/48] Set directory permissions and collectd plugin dir correctly --- attributes/default.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/attributes/default.rb b/attributes/default.rb index 6876ce0..bc0202c 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -15,7 +15,7 @@ default['collectd']['service']['package_name'] = 'collectd' end -default['collectd']['service']['configuration']['plugin_dir'] = '/usr/lib64/collectd' +default['collectd']['service']['configuration']['plugin_dir'] = '/usr/lib/collectd' default['collectd']['service']['configuration']['types_d_b'] = '/usr/share/collectd/types.db' default['collectd']['service']['configuration']['interval'] = 10 default['collectd']['service']['configuration']['read_threads'] = 5 From d225b3aee5ee61d14ac0ba8f7c9c577a95194dc8 Mon Sep 17 00:00:00 2001 From: Shahul Hameed Date: Wed, 9 Sep 2015 17:01:47 +0000 Subject: [PATCH 14/48] Change directory permission, fix minor bugs --- attributes/default.rb | 2 +- libraries/collectd_service.rb | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/attributes/default.rb b/attributes/default.rb index bc0202c..6876ce0 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -15,7 +15,7 @@ default['collectd']['service']['package_name'] = 'collectd' end -default['collectd']['service']['configuration']['plugin_dir'] = '/usr/lib/collectd' +default['collectd']['service']['configuration']['plugin_dir'] = '/usr/lib64/collectd' default['collectd']['service']['configuration']['types_d_b'] = '/usr/share/collectd/types.db' default['collectd']['service']['configuration']['interval'] = 10 default['collectd']['service']['configuration']['read_threads'] = 5 diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb index d5bbe63..eedf093 100644 --- a/libraries/collectd_service.rb +++ b/libraries/collectd_service.rb @@ -61,6 +61,10 @@ class CollectdService < Chef::Resource # @!attribute package_source # @return [String] attribute(:package_source, kind_of: String) + + # @!attribute command + # @return [String] + attribute(:command, kind_of: String, default: '/usr/sbin/collectd -C /etc/collectd.conf -f') end end @@ -122,7 +126,7 @@ def action_disable # Sets the tuning options for service management with {PoiseService::ServiceMixin}. # @param [PoiseService::Service] service def service_options(service) - service.command("/usr/sbin/collectd -C #{new_resource.config_filename} -f") + service.command(new_resource.command) service.directory(new_resource.directory) service.user(new_resource.user) service.environment('PATH' => '/usr/local/bin:/usr/bin:/bin') From b95356799d28c9f9fea8c2411547c94611b288db Mon Sep 17 00:00:00 2001 From: Shahul Hameed Date: Wed, 9 Sep 2015 18:14:28 +0000 Subject: [PATCH 15/48] Change lib directory --- attributes/default.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/attributes/default.rb b/attributes/default.rb index 6876ce0..bc0202c 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -15,7 +15,7 @@ default['collectd']['service']['package_name'] = 'collectd' end -default['collectd']['service']['configuration']['plugin_dir'] = '/usr/lib64/collectd' +default['collectd']['service']['configuration']['plugin_dir'] = '/usr/lib/collectd' default['collectd']['service']['configuration']['types_d_b'] = '/usr/share/collectd/types.db' default['collectd']['service']['configuration']['interval'] = 10 default['collectd']['service']['configuration']['read_threads'] = 5 From 11ba4aa19944a92225fd9959d47be6aeaedde415 Mon Sep 17 00:00:00 2001 From: Shahul Hameed Date: Wed, 9 Sep 2015 19:11:54 +0000 Subject: [PATCH 16/48] Rebase on latest master --- libraries/collectd_config.rb | 7 ++++--- libraries/collectd_service.rb | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libraries/collectd_config.rb b/libraries/collectd_config.rb index 34f219b..20345a8 100644 --- a/libraries/collectd_config.rb +++ b/libraries/collectd_config.rb @@ -55,11 +55,12 @@ def write_elements(directives, indent = 0) if value.is_a?(Array) %(#{tabs}#{key} "#{value.uniq.join('", "')}") elsif value.kind_of?(Hash) # rubocop:disable Style/ClassCheck - id = value.delete('id') + id = value['id'] next if id.nil? + config_hash = value.reject { |k, _| k == 'id' } [%(#{tabs}<#{key} "#{id}">), - write_elements(value, indent.next), - %(#{tabs}) + write_elements(config_hash, indent.next), + %(#{tabs}) ].join("\n") elsif value.is_a?(String) %(#{tabs}#{key} "#{value}") diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb index eedf093..380752f 100644 --- a/libraries/collectd_service.rb +++ b/libraries/collectd_service.rb @@ -61,7 +61,7 @@ class CollectdService < Chef::Resource # @!attribute package_source # @return [String] attribute(:package_source, kind_of: String) - + # @!attribute command # @return [String] attribute(:command, kind_of: String, default: '/usr/sbin/collectd -C /etc/collectd.conf -f') From 76c4bb287df3d220185ec761fd3ddd9089853611 Mon Sep 17 00:00:00 2001 From: Shahul Hameed Date: Fri, 11 Sep 2015 15:21:35 +0000 Subject: [PATCH 17/48] Use lazy evaluation of collectd conf, dup to copy directives hash --- libraries/collectd_config.rb | 7 +++---- libraries/collectd_service.rb | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/libraries/collectd_config.rb b/libraries/collectd_config.rb index 20345a8..36747ed 100644 --- a/libraries/collectd_config.rb +++ b/libraries/collectd_config.rb @@ -49,17 +49,16 @@ def snake_to_camel(s) # @return [String] def write_elements(directives, indent = 0) tabs = ("\t" * indent) - directives.map do |key, value| + directives.dup.map do |key, value| next if value.nil? key = snake_to_camel(key) if value.is_a?(Array) %(#{tabs}#{key} "#{value.uniq.join('", "')}") elsif value.kind_of?(Hash) # rubocop:disable Style/ClassCheck - id = value['id'] + id = value.delete('id') next if id.nil? - config_hash = value.reject { |k, _| k == 'id' } [%(#{tabs}<#{key} "#{id}">), - write_elements(config_hash, indent.next), + write_elements(value, indent.next), %(#{tabs}) ].join("\n") elsif value.is_a?(String) diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb index 380752f..642a4cd 100644 --- a/libraries/collectd_service.rb +++ b/libraries/collectd_service.rb @@ -64,7 +64,7 @@ class CollectdService < Chef::Resource # @!attribute command # @return [String] - attribute(:command, kind_of: String, default: '/usr/sbin/collectd -C /etc/collectd.conf -f') + attribute(:command, kind_of: String, default: lazy { "/usr/sbin/collectd -C #{config_filename} -f" }) end end From 877b4f39cccaf40c130e13de18e00d18edd38118 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Sun, 13 Sep 2015 22:56:24 -0400 Subject: [PATCH 18/48] Updates travis configuration for containers. --- .travis.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 419b164..1d059d3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,20 +1,15 @@ --- language: ruby +sudo: false notifications: slack: bloomberg-rnd:eHp3Czg42iGzaTgG8sAFeD9v -install: - - bundle install --retry 3 --without kitchen_vagrant kitchen_cloud - - bundle exec berks install script: bundle exec rake travis +cache: bundler rvm: - 2.1 - 2.2 -cache: - directories: - - vendor/bundle branches: only: - master -builder_args: --jobs 7 matrix: fast_finish: true From 0638ec509f79c2b4677e89eab3847331fe50c653 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Sun, 13 Sep 2015 23:05:59 -0400 Subject: [PATCH 19/48] Adds an exclusion for vendor to Rubocop. --- .rubocop.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.rubocop.yml b/.rubocop.yml index 3404433..ff7c6b3 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -43,6 +43,7 @@ AllCops: - 'Guardfile' - 'test/**/*.rb' - 'bin/*' + - 'vendor/**/*' Style/GuardClause: Enabled: false From a9072e3b8a6acab5d220bc5f8e113069944e08f2 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Wed, 23 Sep 2015 10:21:42 -0400 Subject: [PATCH 20/48] Adds default environment hash. --- libraries/collectd_service.rb | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb index 642a4cd..3267df1 100644 --- a/libraries/collectd_service.rb +++ b/libraries/collectd_service.rb @@ -62,9 +62,14 @@ class CollectdService < Chef::Resource # @return [String] attribute(:package_source, kind_of: String) - # @!attribute command + # @!attribute environment # @return [String] - attribute(:command, kind_of: String, default: lazy { "/usr/sbin/collectd -C #{config_filename} -f" }) + attribute(:environment, kind_of: Hash, default: lazy { default_environment }) + + # @return [Hash] + def default_environment + { 'PATH' => '/usr/bin:/usr/sbin:/bin:/sbin' } + end end end @@ -126,10 +131,10 @@ def action_disable # Sets the tuning options for service management with {PoiseService::ServiceMixin}. # @param [PoiseService::Service] service def service_options(service) - service.command(new_resource.command) + service.command("collectd -C #{new_resource.config_filename} -f") service.directory(new_resource.directory) service.user(new_resource.user) - service.environment('PATH' => '/usr/local/bin:/usr/bin:/bin') + service.environment(new_resource.environment) service.restart_on_update(true) end end From 565e0a68bef89d9eabe5bbcb1a64c38ef014b1f3 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Fri, 25 Sep 2015 10:08:01 -0400 Subject: [PATCH 21/48] Fixes issue where sub-directory doesn't exist. This creates configuration directory. --- libraries/collectd_config.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/collectd_config.rb b/libraries/collectd_config.rb index 36747ed..d0528ef 100644 --- a/libraries/collectd_config.rb +++ b/libraries/collectd_config.rb @@ -71,6 +71,8 @@ def write_elements(directives, indent = 0) action(:create) do notifying_block do + directory ::File.dirname(new_resource.path) + file new_resource.path do content new_resource.content owner new_resource.owner From f4acb5b30145119145f853fa2ff8291243cf547c Mon Sep 17 00:00:00 2001 From: John Bellone Date: Fri, 25 Sep 2015 10:08:43 -0400 Subject: [PATCH 22/48] Fixes problem with root_user attribute not existing. --- recipes/default.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/recipes/default.rb b/recipes/default.rb index dce37f8..dbe8e58 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -9,11 +9,11 @@ poise_service_user node['collectd']['service_user'] do group node['collectd']['service_group'] - not_if { node['collectd']['service_user'] == node['root_user'] } + not_if { node['collectd']['service_user'] == 'root' } end -collectd_service node['collectd']['service_name'] do |r| +collectd_service node['collectd']['service_name'] user node['collectd']['service_user'] group node['collectd']['service_group'] - node['collectd']['service'].each_pair { |k, v| r.send(k, v) } + node['collectd']['service'].each_pair { |k, v| send(k, v) } end From f3905e6c274cdd826c14fe676ad9fd0b2718f503 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Fri, 25 Sep 2015 10:09:05 -0400 Subject: [PATCH 23/48] Adds string interpolation on source url. --- libraries/collectd_service.rb | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb index 3267df1..57238f4 100644 --- a/libraries/collectd_service.rb +++ b/libraries/collectd_service.rb @@ -85,16 +85,18 @@ def action_enable notifying_block do # TODO: (jbellone) Fix the package resource for AIX so that # it is able to install from a URL. - package_source = if new_resource.package_source - basename = ::File.basename(new_resource.package_source) - remote_file ::File.join(Chef::Config[:file_cache_path], basename) do - source new_resource.package_source - end.path - end + package_path = if new_resource.package_source + url = new_resource.package_source % { version: new_resource.package_version } + basename = ::File.basename(url) + remote_file ::File.join(Chef::Config[:file_cache_path], basename) do + source url + end.path + end package new_resource.package_name do + provider Chef::Provider::Package::Dpkg if platform?('ubuntu') version new_resource.package_version - source package_source + source package_path action :upgrade end From 86598364ada0ad55c3c17a59b0f42bd413991f6a Mon Sep 17 00:00:00 2001 From: John Bellone Date: Fri, 25 Sep 2015 10:11:49 -0400 Subject: [PATCH 24/48] Fixes syntax error in the recipe. --- recipes/default.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/default.rb b/recipes/default.rb index dbe8e58..5b6ab8e 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -12,7 +12,7 @@ not_if { node['collectd']['service_user'] == 'root' } end -collectd_service node['collectd']['service_name'] +collectd_service node['collectd']['service_name'] do user node['collectd']['service_user'] group node['collectd']['service_group'] node['collectd']['service'].each_pair { |k, v| send(k, v) } From ee436093f26b1d613297585f5db0509e8dd2d53c Mon Sep 17 00:00:00 2001 From: John Bellone Date: Fri, 25 Sep 2015 10:12:08 -0400 Subject: [PATCH 25/48] Bumps version of the recipe. --- metadata.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metadata.rb b/metadata.rb index 6e90db0..0e42852 100644 --- a/metadata.rb +++ b/metadata.rb @@ -4,7 +4,7 @@ license 'Apache 2.0' description 'Installs and configures the collectd monitoring daemon.' long_description 'Installs and configures the collectd monitoring daemon.' -version '2.0.0' +version '2.0.1' supports 'ubuntu', '>= 10.04' supports 'centos', '>= 5.8' From d19e7c7b269d17c9b6a6e5fee60ab52fe154f05f Mon Sep 17 00:00:00 2001 From: John Bellone Date: Fri, 25 Sep 2015 10:25:45 -0400 Subject: [PATCH 26/48] Adds a recursive creation to directories. --- libraries/collectd_config.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/collectd_config.rb b/libraries/collectd_config.rb index d0528ef..9a0f0ba 100644 --- a/libraries/collectd_config.rb +++ b/libraries/collectd_config.rb @@ -71,7 +71,9 @@ def write_elements(directives, indent = 0) action(:create) do notifying_block do - directory ::File.dirname(new_resource.path) + directory ::File.dirname(new_resource.path) do + recursive true + end file new_resource.path do content new_resource.content From 29e9ffd441577d99d907174470593e374e960828 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Fri, 25 Sep 2015 10:26:23 -0400 Subject: [PATCH 27/48] Fixes issue with sending attributes to resource. --- recipes/default.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/recipes/default.rb b/recipes/default.rb index 5b6ab8e..9e03c36 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -12,8 +12,8 @@ not_if { node['collectd']['service_user'] == 'root' } end -collectd_service node['collectd']['service_name'] do +collectd_service node['collectd']['service_name'] do |r| user node['collectd']['service_user'] group node['collectd']['service_group'] - node['collectd']['service'].each_pair { |k, v| send(k, v) } + node['collectd']['service'].each_pair { |k, v| r.send(k, v) } end From 8febcf87c7a1ec1a0bea85035d5851fb61b46455 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Fri, 25 Sep 2015 10:32:02 -0400 Subject: [PATCH 28/48] Adds default attribute for collectd plugin directory. --- attributes/default.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/attributes/default.rb b/attributes/default.rb index bc0202c..3709ad1 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -15,6 +15,7 @@ default['collectd']['service']['package_name'] = 'collectd' end +default['collectd']['plugin']['directory'] = '/etc/collectd.d' default['collectd']['service']['configuration']['plugin_dir'] = '/usr/lib/collectd' default['collectd']['service']['configuration']['types_d_b'] = '/usr/share/collectd/types.db' default['collectd']['service']['configuration']['interval'] = 10 From 5bfe3c3039583c8fdd4b5ad17a13d538e861e91a Mon Sep 17 00:00:00 2001 From: John Bellone Date: Fri, 25 Sep 2015 12:43:57 -0400 Subject: [PATCH 29/48] Adds environment to the service options. --- libraries/collectd_service.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb index 57238f4..5662f80 100644 --- a/libraries/collectd_service.rb +++ b/libraries/collectd_service.rb @@ -134,6 +134,7 @@ def action_disable # @param [PoiseService::Service] service def service_options(service) service.command("collectd -C #{new_resource.config_filename} -f") + service.environment(new_resource.environment) service.directory(new_resource.directory) service.user(new_resource.user) service.environment(new_resource.environment) From 2677d0934c4daddcef046383ad89a907e72cc42f Mon Sep 17 00:00:00 2001 From: John Bellone Date: Fri, 25 Sep 2015 12:56:56 -0400 Subject: [PATCH 30/48] Fixes some issues found during testing locally. --- attributes/default.rb | 2 +- libraries/collectd_service.rb | 12 +++++++----- metadata.rb | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/attributes/default.rb b/attributes/default.rb index 3709ad1..a3ed947 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -15,7 +15,7 @@ default['collectd']['service']['package_name'] = 'collectd' end -default['collectd']['plugin']['directory'] = '/etc/collectd.d' +default['collectd']['service']['config_directory'] = '/etc/collectd.d' default['collectd']['service']['configuration']['plugin_dir'] = '/usr/lib/collectd' default['collectd']['service']['configuration']['types_d_b'] = '/usr/share/collectd/types.db' default['collectd']['service']['configuration']['interval'] = 10 diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb index 5662f80..331989a 100644 --- a/libraries/collectd_service.rb +++ b/libraries/collectd_service.rb @@ -16,6 +16,8 @@ class CollectdService < Chef::Resource provides(:collectd_service) include PoiseService::ServiceMixin + attribute(:command, kind_of: String, default: lazy { default_command }) + # @!attribute user # User to run the collectd daemon as. Defaults to 'collectd.' # @return [String] @@ -64,11 +66,11 @@ class CollectdService < Chef::Resource # @!attribute environment # @return [String] - attribute(:environment, kind_of: Hash, default: lazy { default_environment }) + attribute(:environment, kind_of: Hash, default: { 'PATH' => '/usr/bin:/bin:/usr/sbin:/sbin' }) - # @return [Hash] - def default_environment - { 'PATH' => '/usr/bin:/usr/sbin:/bin:/sbin' } + # @return [String] + def default_command + "/usr/sbin/collectd -C #{config_filename} -f" end end end @@ -133,7 +135,7 @@ def action_disable # Sets the tuning options for service management with {PoiseService::ServiceMixin}. # @param [PoiseService::Service] service def service_options(service) - service.command("collectd -C #{new_resource.config_filename} -f") + service.command(new_resource.command) service.environment(new_resource.environment) service.directory(new_resource.directory) service.user(new_resource.user) diff --git a/metadata.rb b/metadata.rb index 0e42852..1249f86 100644 --- a/metadata.rb +++ b/metadata.rb @@ -4,7 +4,7 @@ license 'Apache 2.0' description 'Installs and configures the collectd monitoring daemon.' long_description 'Installs and configures the collectd monitoring daemon.' -version '2.0.1' +version '2.0.2' supports 'ubuntu', '>= 10.04' supports 'centos', '>= 5.8' From bb0d438a8e8d7f37423053f0177a55d3f432d545 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Thu, 1 Oct 2015 11:35:26 -0400 Subject: [PATCH 31/48] Removes explicit action for package upgrade. --- libraries/collectd_service.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb index 331989a..2a8375f 100644 --- a/libraries/collectd_service.rb +++ b/libraries/collectd_service.rb @@ -99,7 +99,6 @@ def action_enable provider Chef::Provider::Package::Dpkg if platform?('ubuntu') version new_resource.package_version source package_path - action :upgrade end [new_resource.directory, new_resource.config_directory].each do |dirname| From b6835165a6d08a794bf83ec56654d4825bc3e662 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Mon, 19 Oct 2015 10:05:14 -0400 Subject: [PATCH 32/48] Modifies package resource to perform an upgrade. The upgrade action also handles initial installation if the package is not already. --- libraries/collectd_service.rb | 1 + metadata.rb | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb index 2a8375f..331989a 100644 --- a/libraries/collectd_service.rb +++ b/libraries/collectd_service.rb @@ -99,6 +99,7 @@ def action_enable provider Chef::Provider::Package::Dpkg if platform?('ubuntu') version new_resource.package_version source package_path + action :upgrade end [new_resource.directory, new_resource.config_directory].each do |dirname| diff --git a/metadata.rb b/metadata.rb index 1249f86..d51c64c 100644 --- a/metadata.rb +++ b/metadata.rb @@ -4,11 +4,13 @@ license 'Apache 2.0' description 'Installs and configures the collectd monitoring daemon.' long_description 'Installs and configures the collectd monitoring daemon.' -version '2.0.2' +version '2.0.3' supports 'ubuntu', '>= 10.04' supports 'centos', '>= 5.8' supports 'redhat', '>= 5.8' +supports 'aix' +supports 'solaris2' depends 'poise', '~> 2.2' depends 'poise-service', '~> 1.0' From d22900569797a374df09d1cf63905941665b3c08 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Wed, 21 Oct 2015 09:27:05 -0400 Subject: [PATCH 33/48] Uses the solaris package provider instead of ips. --- libraries/collectd_service.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb index 331989a..a8ef0e3 100644 --- a/libraries/collectd_service.rb +++ b/libraries/collectd_service.rb @@ -97,6 +97,7 @@ def action_enable package new_resource.package_name do provider Chef::Provider::Package::Dpkg if platform?('ubuntu') + provider Chef::Provider::Package::Solaris if platform?('solaris2') version new_resource.package_version source package_path action :upgrade From 2b542f96aa2355413582530f083a72460aec8b11 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Wed, 21 Oct 2015 09:27:43 -0400 Subject: [PATCH 34/48] Bumps version of the cookbook. --- metadata.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metadata.rb b/metadata.rb index d51c64c..934328a 100644 --- a/metadata.rb +++ b/metadata.rb @@ -4,7 +4,7 @@ license 'Apache 2.0' description 'Installs and configures the collectd monitoring daemon.' long_description 'Installs and configures the collectd monitoring daemon.' -version '2.0.3' +version '2.0.4' supports 'ubuntu', '>= 10.04' supports 'centos', '>= 5.8' From 793d8745e9506b2fa43dd03fb8282bb06a50b1f9 Mon Sep 17 00:00:00 2001 From: Shahul Hameed Date: Wed, 21 Oct 2015 11:57:02 -0400 Subject: [PATCH 35/48] Use admin file for solaris package --- libraries/collectd_service.rb | 30 ++++++++++++++++++++++++++++-- metadata.rb | 2 +- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb index a8ef0e3..dfe7490 100644 --- a/libraries/collectd_service.rb +++ b/libraries/collectd_service.rb @@ -68,10 +68,20 @@ class CollectdService < Chef::Resource # @return [String] attribute(:environment, kind_of: Hash, default: { 'PATH' => '/usr/bin:/bin:/usr/sbin:/sbin' }) + # @!attribute solaris_admin_file + # @return [String] + attribute(:solaris_admin_file, kind_of: String, default: lazy { default_solaris_admin_file }) + # @return [String] def default_command "/usr/sbin/collectd -C #{config_filename} -f" end + + # @return [String] + def default_solaris_admin_file + ::File.join(Chef::Config[:file_cache_path],"default") + end + end end @@ -95,12 +105,28 @@ def action_enable end.path end + #create admin file for solaris package + ruby_block 'create solaris admin file' do + block do + if platform?('solaris2') + text = ::File.read('/var/sadm/install/admin/default') + ::File.write(new_resource.solaris_admin_file, text.gsub(/ask/,'nocheck')) + end + end + end + package new_resource.package_name do provider Chef::Provider::Package::Dpkg if platform?('ubuntu') - provider Chef::Provider::Package::Solaris if platform?('solaris2') + #solaris provider only supports install action and needs admin file + if platform?('solaris2') + provider Chef::Provider::Package::Solaris + options "-a #{new_resource.solaris_admin_file}" + action :install + else + action :upgrade + end version new_resource.package_version source package_path - action :upgrade end [new_resource.directory, new_resource.config_directory].each do |dirname| diff --git a/metadata.rb b/metadata.rb index 934328a..8c18edc 100644 --- a/metadata.rb +++ b/metadata.rb @@ -4,7 +4,7 @@ license 'Apache 2.0' description 'Installs and configures the collectd monitoring daemon.' long_description 'Installs and configures the collectd monitoring daemon.' -version '2.0.4' +version '2.0.5' supports 'ubuntu', '>= 10.04' supports 'centos', '>= 5.8' From 0d3d934d78d7475f376ebb14b2c6a2ad73670272 Mon Sep 17 00:00:00 2001 From: Shahul Hameed Date: Wed, 21 Oct 2015 12:05:11 -0400 Subject: [PATCH 36/48] Fix rubocop issues --- libraries/collectd_service.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb index dfe7490..76279e2 100644 --- a/libraries/collectd_service.rb +++ b/libraries/collectd_service.rb @@ -79,9 +79,8 @@ def default_command # @return [String] def default_solaris_admin_file - ::File.join(Chef::Config[:file_cache_path],"default") + ::File.join(Chef::Config[:file_cache_path], 'default') end - end end @@ -105,19 +104,19 @@ def action_enable end.path end - #create admin file for solaris package + # create admin file for solaris package ruby_block 'create solaris admin file' do block do if platform?('solaris2') text = ::File.read('/var/sadm/install/admin/default') - ::File.write(new_resource.solaris_admin_file, text.gsub(/ask/,'nocheck')) + ::File.write(new_resource.solaris_admin_file, text.gsub(/ask/, 'nocheck')) end end end package new_resource.package_name do provider Chef::Provider::Package::Dpkg if platform?('ubuntu') - #solaris provider only supports install action and needs admin file + # solaris provider only supports install action and needs admin file if platform?('solaris2') provider Chef::Provider::Package::Solaris options "-a #{new_resource.solaris_admin_file}" From 4fdac4a1d03ee64e5845e0a39b1751c92fe09ee3 Mon Sep 17 00:00:00 2001 From: Shahul Hameed Date: Fri, 23 Oct 2015 15:31:53 -0400 Subject: [PATCH 37/48] Use standard solaris provider --- libraries/collectd_service.rb | 22 +--------------------- metadata.rb | 2 +- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb index 76279e2..d2535df 100644 --- a/libraries/collectd_service.rb +++ b/libraries/collectd_service.rb @@ -68,19 +68,10 @@ class CollectdService < Chef::Resource # @return [String] attribute(:environment, kind_of: Hash, default: { 'PATH' => '/usr/bin:/bin:/usr/sbin:/sbin' }) - # @!attribute solaris_admin_file - # @return [String] - attribute(:solaris_admin_file, kind_of: String, default: lazy { default_solaris_admin_file }) - # @return [String] def default_command "/usr/sbin/collectd -C #{config_filename} -f" end - - # @return [String] - def default_solaris_admin_file - ::File.join(Chef::Config[:file_cache_path], 'default') - end end end @@ -104,22 +95,11 @@ def action_enable end.path end - # create admin file for solaris package - ruby_block 'create solaris admin file' do - block do - if platform?('solaris2') - text = ::File.read('/var/sadm/install/admin/default') - ::File.write(new_resource.solaris_admin_file, text.gsub(/ask/, 'nocheck')) - end - end - end - package new_resource.package_name do provider Chef::Provider::Package::Dpkg if platform?('ubuntu') - # solaris provider only supports install action and needs admin file + # solaris provider only supports install action if platform?('solaris2') provider Chef::Provider::Package::Solaris - options "-a #{new_resource.solaris_admin_file}" action :install else action :upgrade diff --git a/metadata.rb b/metadata.rb index 8c18edc..d775ac6 100644 --- a/metadata.rb +++ b/metadata.rb @@ -4,7 +4,7 @@ license 'Apache 2.0' description 'Installs and configures the collectd monitoring daemon.' long_description 'Installs and configures the collectd monitoring daemon.' -version '2.0.5' +version '2.0.6' supports 'ubuntu', '>= 10.04' supports 'centos', '>= 5.8' From 758be27ad2cc2622c4b0297dbdcc264f59c577e0 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Fri, 20 Nov 2015 16:24:38 -0500 Subject: [PATCH 38/48] Fixes issue where Solaris package isn't removed first. --- libraries/collectd_service.rb | 1 - metadata.rb | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb index d2535df..699f8fa 100644 --- a/libraries/collectd_service.rb +++ b/libraries/collectd_service.rb @@ -97,7 +97,6 @@ def action_enable package new_resource.package_name do provider Chef::Provider::Package::Dpkg if platform?('ubuntu') - # solaris provider only supports install action if platform?('solaris2') provider Chef::Provider::Package::Solaris action :install diff --git a/metadata.rb b/metadata.rb index d775ac6..6bbd2cd 100644 --- a/metadata.rb +++ b/metadata.rb @@ -4,7 +4,7 @@ license 'Apache 2.0' description 'Installs and configures the collectd monitoring daemon.' long_description 'Installs and configures the collectd monitoring daemon.' -version '2.0.6' +version '2.1.0' supports 'ubuntu', '>= 10.04' supports 'centos', '>= 5.8' From cb2e114f6da30b42518514c8cfa4a2e3494a6b1a Mon Sep 17 00:00:00 2001 From: Shahul Khajamohideen Date: Mon, 23 Nov 2015 16:30:46 -0500 Subject: [PATCH 39/48] Use upgrade action for solaris provider,restart collectd on updates --- libraries/collectd_service.rb | 10 ++++------ metadata.rb | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/libraries/collectd_service.rb b/libraries/collectd_service.rb index 699f8fa..7147428 100644 --- a/libraries/collectd_service.rb +++ b/libraries/collectd_service.rb @@ -97,14 +97,11 @@ def action_enable package new_resource.package_name do provider Chef::Provider::Package::Dpkg if platform?('ubuntu') - if platform?('solaris2') - provider Chef::Provider::Package::Solaris - action :install - else - action :upgrade - end + provider Chef::Provider::Package::Solaris if platform?('solaris2') + action :upgrade version new_resource.package_version source package_path + notifies :restart, new_resource, :delayed end [new_resource.directory, new_resource.config_directory].each do |dirname| @@ -123,6 +120,7 @@ def action_enable 'base_dir' => new_resource.directory, 'include' => "#{new_resource.config_directory}/*.conf" ) + notifies :restart, new_resource, :delayed end end super diff --git a/metadata.rb b/metadata.rb index 6bbd2cd..5fff183 100644 --- a/metadata.rb +++ b/metadata.rb @@ -4,7 +4,7 @@ license 'Apache 2.0' description 'Installs and configures the collectd monitoring daemon.' long_description 'Installs and configures the collectd monitoring daemon.' -version '2.1.0' +version '2.1.1' supports 'ubuntu', '>= 10.04' supports 'centos', '>= 5.8' From 63b722856d28d91ce41db10c19966556f35cce90 Mon Sep 17 00:00:00 2001 From: Yoga Ramalingam Date: Fri, 11 Dec 2015 16:11:48 -0500 Subject: [PATCH 40/48] Multi value configuration need to be on separate lines --- libraries/collectd_config.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/collectd_config.rb b/libraries/collectd_config.rb index 9a0f0ba..f7d7bce 100644 --- a/libraries/collectd_config.rb +++ b/libraries/collectd_config.rb @@ -53,7 +53,7 @@ def write_elements(directives, indent = 0) next if value.nil? key = snake_to_camel(key) if value.is_a?(Array) - %(#{tabs}#{key} "#{value.uniq.join('", "')}") + value.each{ |val| %(#{tabs}#{key} "#{val}") } elsif value.kind_of?(Hash) # rubocop:disable Style/ClassCheck id = value.delete('id') next if id.nil? From c725b05e506a90ed4e943df480bb7f36628e7776 Mon Sep 17 00:00:00 2001 From: Yoga Ramalingam Date: Fri, 11 Dec 2015 16:12:51 -0500 Subject: [PATCH 41/48] Increment version --- metadata.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metadata.rb b/metadata.rb index 5fff183..475184e 100644 --- a/metadata.rb +++ b/metadata.rb @@ -4,7 +4,7 @@ license 'Apache 2.0' description 'Installs and configures the collectd monitoring daemon.' long_description 'Installs and configures the collectd monitoring daemon.' -version '2.1.1' +version '2.1.2' supports 'ubuntu', '>= 10.04' supports 'centos', '>= 5.8' From 68e66c38907740bef2a94cab6fb63224bed37f0f Mon Sep 17 00:00:00 2001 From: Yoga Ramalingam Date: Fri, 11 Dec 2015 17:51:30 -0500 Subject: [PATCH 42/48] replaced for each with a map --- libraries/collectd_config.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libraries/collectd_config.rb b/libraries/collectd_config.rb index f7d7bce..b65c70d 100644 --- a/libraries/collectd_config.rb +++ b/libraries/collectd_config.rb @@ -53,7 +53,13 @@ def write_elements(directives, indent = 0) next if value.nil? key = snake_to_camel(key) if value.is_a?(Array) - value.each{ |val| %(#{tabs}#{key} "#{val}") } + value.map do |val| + if val.is_a?(String) + %(#{tabs}#{key} "#{val}") + else + %(#{tabs}#{key} #{val}) + end + end.join("\n") elsif value.kind_of?(Hash) # rubocop:disable Style/ClassCheck id = value.delete('id') next if id.nil? From 0d97e8962fdb209b72c3c49c3984d82877440a8d Mon Sep 17 00:00:00 2001 From: John Bellone Date: Thu, 17 Dec 2015 10:27:42 -0500 Subject: [PATCH 43/48] Updates the repository template configuration files. --- .gitignore | 2 ++ .rubocop.yml | 58 +++++++++++++++++++++++----------------------------- .travis.yml | 1 - Gemfile | 2 +- 4 files changed, 29 insertions(+), 34 deletions(-) diff --git a/.gitignore b/.gitignore index 0360a01..7fe508a 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,5 @@ vendor .vagrant Berksfile.lock coverage/ +Policyfile.lock.json +nodes/ diff --git a/.rubocop.yml b/.rubocop.yml index ff7c6b3..651a400 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,49 +1,43 @@ --- +AllCops: + Exclude: + - 'Guardfile' + - 'Rakefile' + - 'Vagrantfile' + - 'Policyfile.rb' + - 'Berksfile' + - 'Thorfile' + - 'Gemfile' + - 'test/**/*' + - 'bin/**' + - 'vendor/**/*' AlignParameters: Enabled: false - -Encoding: - Enabled: false - ClassLength: Enabled: false - -MethodLength: - Enabled: false - -LineLength: +CyclomaticComplexity: Enabled: false - Documentation: Enabled: false - -PerceivedComplexity: - Enabled: false - -CyclomaticComplexity: +Encoding: Enabled: false - Style/FileName: Enabled: false - -Style/FirstParameterIndentation: - Enabled: false - -Style/ClassAndModuleChildren: +LineLength: Enabled: false - -Style/PercentLiteralDelimiters: +MethodLength: Enabled: false - Metrics/AbcSize: Enabled: false - -AllCops: - Exclude: - - 'Guardfile' - - 'test/**/*.rb' - - 'bin/*' - - 'vendor/**/*' - +PerceivedComplexity: + Enabled: false +SingleSpaceBeforeFirstArg: + Enabled: false +Style/ClassAndModuleChildren: + Enabled: false +Style/FileName: + Enabled: false Style/GuardClause: Enabled: false +Style/PercentLiteralDelimiters: + Enabled: false diff --git a/.travis.yml b/.travis.yml index 1d059d3..3b2010c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,6 @@ sudo: false notifications: slack: bloomberg-rnd:eHp3Czg42iGzaTgG8sAFeD9v script: bundle exec rake travis -cache: bundler rvm: - 2.1 - 2.2 diff --git a/Gemfile b/Gemfile index 43f8376..c978b2b 100644 --- a/Gemfile +++ b/Gemfile @@ -13,7 +13,7 @@ group :kitchen_common do end group :kitchen_vagrant do - gem 'kitchen-vagrant', '~> 0.17' + gem 'kitchen-vagrant', '~> 0.19' end group :kitchen_cloud do From a8432836f53c816b135464e992c1d4066f6ce556 Mon Sep 17 00:00:00 2001 From: John Bellone Date: Thu, 17 Dec 2015 15:40:25 -0500 Subject: [PATCH 44/48] Updates the metadata url for source and issues. --- metadata.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/metadata.rb b/metadata.rb index 475184e..ad9c5ac 100644 --- a/metadata.rb +++ b/metadata.rb @@ -5,6 +5,8 @@ description 'Installs and configures the collectd monitoring daemon.' long_description 'Installs and configures the collectd monitoring daemon.' version '2.1.2' +source_url 'https://github.com/bloomberg/collectd-cookbook' +issues_url 'https://github.com/bloomberg/collectd-cookbook/issues' supports 'ubuntu', '>= 10.04' supports 'centos', '>= 5.8' From 852f098ac3afaf34028f2d6038ba832ca911d9e0 Mon Sep 17 00:00:00 2001 From: Yoga Ramalingam Date: Fri, 18 Dec 2015 11:07:16 -0500 Subject: [PATCH 45/48] added support for template configuration file --- libraries/collectd_plugin_file.rb | 93 +++++++++++++++++++++++++++++++ metadata.rb | 2 +- 2 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 libraries/collectd_plugin_file.rb diff --git a/libraries/collectd_plugin_file.rb b/libraries/collectd_plugin_file.rb new file mode 100644 index 0000000..5b925e3 --- /dev/null +++ b/libraries/collectd_plugin_file.rb @@ -0,0 +1,93 @@ +# +# Cookbook: collectd +# License: Apache 2.0 +# +# Copyright 2015, Bloomberg Finance L.P. +# +require 'poise' + +module CollectdCookbook + module Resource + # A resource for managing collectd plugins. + # @since 2.0.0 + class CollectdPluginFile < Chef::Resource + include Poise(fused: true) + provides(:collectd_plugin_file) + + # @!attribute plugin_name + # Name of the collectd plugin to install and configure. + # @return [String] + attribute(:plugin_name, kind_of: String, name_attribute: true) + + # @!attribute plugin_instance_name + # Name of the plugin instance name + # @return [String] + attribute(:plugin_instance_name, kind_of: String) + + # @!attribute directory + # Name of directory where plugin configuration resides. Defaults to + # '/etc/collectd.d'. + # @return [String] + attribute(:directory, kind_of: String, default: '/etc/collectd.d') + + # @!attribute user + # User which the configuration for {#plugin_name} is owned by. + # Defaults to 'collectd.' + # @return [String] + attribute(:user, kind_of: String, default: 'collectd') + + # @!attribute group + # Group which the configuration for {#plugin_name} is owned by. + # Defaults to 'collectd.' + # @return [String] + attribute(:group, kind_of: String, default: 'collectd') + + # @!attribute cookbook + # The name of the cookbook where template file lives + # @return [String] + attribute(:cookbook, kind_of: String) + + # @!attribute source + # The name of the template file in templates directory + # @return [String] + attribute(:source, kind_of: String) + + # @!attribute variables + # A Hash of variables that are used to replace variables in the + # template file + attribute(:variables, kind_of: Hash) + + # @return [String] + def config_filename + ::File.join(directory, "#{plugin_name}_#{plugin_instance_name}.conf") + end + + action(:create) do + notifying_block do + directory new_resource.directory do + recursive true + owner new_resource.user + group new_resource.group + mode '0755' + end + + template new_resource.config_filename do + owner new_resource.user + group new_resource.group + cookbook new_resource.cookbook + source new_resource.source + variables new_resource.variables + end + end + end + + action(:delete) do + notifying_block do + collectd_config new_resource.config_filename do + action :delete + end + end + end + end + end +end diff --git a/metadata.rb b/metadata.rb index 475184e..fe9012f 100644 --- a/metadata.rb +++ b/metadata.rb @@ -4,7 +4,7 @@ license 'Apache 2.0' description 'Installs and configures the collectd monitoring daemon.' long_description 'Installs and configures the collectd monitoring daemon.' -version '2.1.2' +version '2.1.3' supports 'ubuntu', '>= 10.04' supports 'centos', '>= 5.8' From a43cd1016700169bb362d42293df503b8965c3af Mon Sep 17 00:00:00 2001 From: Yoga Ramalingam Date: Fri, 18 Dec 2015 11:44:30 -0500 Subject: [PATCH 46/48] fixed broken test case --- test/spec/libraries/collectd_config_spec.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/spec/libraries/collectd_config_spec.rb b/test/spec/libraries/collectd_config_spec.rb index 172813d..0dada21 100644 --- a/test/spec/libraries/collectd_config_spec.rb +++ b/test/spec/libraries/collectd_config_spec.rb @@ -49,7 +49,9 @@ TrueClass true FalseClass false Symbol symbol - Array "1", "2", "3" + Array 1 + Array 2 + Array 3 String "string" From 2449cb24151b1b1033b943f5cbbd78c3e6ca220e Mon Sep 17 00:00:00 2001 From: Yoga Ramalingam Date: Fri, 18 Dec 2015 11:54:31 -0500 Subject: [PATCH 47/48] fixed rubocop errors --- libraries/collectd_plugin_file.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/collectd_plugin_file.rb b/libraries/collectd_plugin_file.rb index 5b925e3..78cc861 100644 --- a/libraries/collectd_plugin_file.rb +++ b/libraries/collectd_plugin_file.rb @@ -43,7 +43,7 @@ class CollectdPluginFile < Chef::Resource attribute(:group, kind_of: String, default: 'collectd') # @!attribute cookbook - # The name of the cookbook where template file lives + # The name of the cookbook where template file lives # @return [String] attribute(:cookbook, kind_of: String) @@ -53,7 +53,7 @@ class CollectdPluginFile < Chef::Resource attribute(:source, kind_of: String) # @!attribute variables - # A Hash of variables that are used to replace variables in the + # A Hash of variables that are used to replace variables in the # template file attribute(:variables, kind_of: Hash) From 16d05c748b0bb7c9cd5c840b0332ddd65d0ccb99 Mon Sep 17 00:00:00 2001 From: Yoga Ramalingam Date: Fri, 18 Dec 2015 12:10:18 -0500 Subject: [PATCH 48/48] fix brokern test case again --- test/spec/libraries/collectd_config_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/spec/libraries/collectd_config_spec.rb b/test/spec/libraries/collectd_config_spec.rb index 0dada21..71466e1 100644 --- a/test/spec/libraries/collectd_config_spec.rb +++ b/test/spec/libraries/collectd_config_spec.rb @@ -49,9 +49,9 @@ TrueClass true FalseClass false Symbol symbol - Array 1 - Array 2 - Array 3 + Array "1" + Array "2" + Array "3" String "string"