diff --git a/.gitignore b/.gitignore index ae7297c..d2b3a5f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,16 @@ +# Plugin deployment_scripts/puppet/modules/corosync +deployment_scripts/puppet/modules/pacemaker deployment_scripts/puppet/modules/stdlib .build tmp *.fp + +# Editors +*.swp +*~ + +# Bundle +Gemfile.lock +.bundled_gems +.bundle diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..028f675 --- /dev/null +++ b/Gemfile @@ -0,0 +1,33 @@ +source 'https://rubygems.org' + +group :development, :test do + gem 'puppetlabs_spec_helper', :require => 'false' + gem 'rspec', '~>3.3', :require => 'false' + gem 'rspec-puppet', '~> 2.2.0', :require => 'false' + gem 'metadata-json-lint', :require => 'false' + gem 'puppet-lint-param-docs', :require => 'false' + gem 'puppet-lint-absolute_classname-check', :require => 'false' + gem 'puppet-lint-absolute_template_path', :require => 'false' + gem 'puppet-lint-unquoted_string-check', :require => 'false' + gem 'puppet-lint-leading_zero-check', :require => 'false' + gem 'puppet-lint-variable_contains_upcase', :require => 'false' + gem 'puppet-lint-numericvariable', :require => 'false' + gem 'puppet_facts', :require => 'false' + gem 'json', :require => 'false' + gem 'pry', :require => 'false' + gem 'simplecov', :require => 'false' + gem 'webmock', :require => 'false' + gem 'fakefs', :require => 'false' + gem 'fog-google', '0.1.0', :require => 'false' # 0.1.1+ requires ruby 2.0 + gem 'beaker-rspec', :require => 'false' + gem 'beaker-puppet_install_helper', :require => 'false' + gem 'puppet-blacksmith', :require => 'false' + +end + +if puppetversion = ENV['PUPPET_GEM_VERSION'] + gem 'puppet', puppetversion, :require => false +else + # TODO(bogdando): remove this version when 4 is supported + gem 'puppet', '~> 3.8', :require => false +end diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..429c176 --- /dev/null +++ b/Rakefile @@ -0,0 +1,183 @@ +############################################################################### +# 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. +############################################################################### +# +# Rakefile +# This file implements the lint and spec tasks for rake so that it will check +# the plugin's puppet modules in the deployment_scripts/puppet/modules +# folder by running the respective lint or test tasks for each module. +# It will then return 0 if there are issues or return 1 if any of the modules +# fail. +# +# Acknowledgements +# The Rakefile is based on the work of Alex Schultz , +# https://raw.githubusercontent.com/openstack/fuel-library/master/Rakefile +# +require 'puppetlabs_spec_helper/rake_tasks' +require 'puppet-lint/tasks/puppet-lint' +require 'puppet-syntax/tasks/puppet-syntax' +require 'rake' + +MODULES_PATH="./deployment_scripts/puppet/modules" +PuppetSyntax.exclude_paths ||= [] +PuppetSyntax.exclude_paths << "spec/fixtures/**/*" +PuppetSyntax.exclude_paths << "pkg/**/*" +PuppetSyntax.exclude_paths << "vendor/**/*" + +# Main task list +task :spec => ["spec:gemfile"] +task :lint => ["lint:manual"] + +namespace :common do + desc 'Task to generate a list of puppet modules' + task :modulelist, [:skip_file] do |t,args| + args.with_defaults(:skip_file => nil) + + cdir = Dir.pwd + skip_module_list = [] + $module_directories = [] + # NOTE(bogdando): some dependent modules may have no good tests an we need + # this file to exclude those + if not args[:skip_file].nil? and File.exists?(args[:skip_file]) + File.open(args[:skip_file], 'r').each_line { |line| + skip_module_list << line.chomp + } + end + + Dir.glob("#{MODULES_PATH}/*") do |mod| + next unless File.directory?(mod) + if skip_module_list.include?(File.basename(mod)) + $stderr.puts "Skipping tests... modules.disable_rspec includes #{mod}" + next + end + $module_directories << mod + end + end +end + +# The spec task to loop through the modules and run the tests +namespace :spec do + desc 'Run spec tasks via module bundler with Gemfile' + task :gemfile do |t| + Rake::Task["common:modulelist"].invoke('./modules.disable_rspec') + cdir = Dir.pwd + status = true + + ENV['GEM_HOME']="#{cdir}/.bundled_gems" + system("gem install bundler --no-rdoc --no-ri --verbose") + system("./pre_build_hook") + + $module_directories.each do |mod| + next unless File.exists?("#{mod}/Gemfile") + $stderr.puts '-'*80 + $stderr.puts "Running tests for #{mod}" + $stderr.puts '-'*80 + Dir.chdir(mod) + begin + system("bundle install") + result = system("bundle exec rake spec") + if !result + status = false + $stderr.puts "!"*80 + $stderr.puts "Unit tests failed for #{mod}" + $stderr.puts "!"*80 + end + rescue Exception => e + $stderr.puts "ERROR: Unable to run tests for #{mod}, #{e.message}" + status = false + end + Dir.chdir(cdir) + end + fail unless status + end +end + +# The lint tasks +namespace :lint do + desc 'Find all the puppet files and run puppet-lint on them' + task :manual do |t| + Rake::Task["common:modulelist"].invoke('./modules.disable_rspec rake-lint') + # lint checks to skip if no Gemfile or Rakefile + skip_checks = [ "--no-80chars-check", + "--no-autoloader_layout-check", + "--no-nested_classes_or_defines-check", + "--no-only_variable_string-check", + "--no-2sp_soft_tabs-check", + "--no-trailing_whitespace-check", + "--no-hard_tabs-check", + "--no-class_inherits_from_params_class-check", + "--with-filename"] + cdir = Dir.pwd + status = true + + ENV['GEM_HOME']="#{cdir}/.bundled_gems" + system("gem install bundler --no-rdoc --no-ri --verbose") + + $module_directories.each do |mod| + $stderr.puts '-'*80 + $stderr.puts "Running lint for #{mod}" + $stderr.puts '-'*80 + Dir.chdir(mod) + begin + result = true + Dir.glob("**/**.pp") do |puppet_file| + result = false unless system("puppet-lint #{skip_checks.join(" ")} #{puppet_file}") + end + if !result + status = false + $stderr.puts "!"*80 + $stderr.puts "puppet-lint failed for #{mod}" + $stderr.puts "!"*80 + end + rescue Exception => e + $stderr.puts "ERROR: Unable to run lint for #{mod}, #{e.message}" + status = false + end + Dir.chdir(cdir) + end + fail unless status + end + + desc 'Run lint tasks from modules with an existing Gemfile/Rakefile' + task :rakefile do |t| + Rake::Task["common:modulelist"].invoke('./modules.disable_rspec rake-lint') + cdir = Dir.pwd + status = true + + ENV['GEM_HOME']="#{cdir}/.bundled_gems" + system("gem install bundler --no-rdoc --no-ri --verbose") + + $module_directories.each do |mod| + next unless File.exists?("#{mod}/Rakefile") + $stderr.puts '-'*80 + $stderr.puts "Running lint for #{mod}" + $stderr.puts '-'*80 + Dir.chdir(mod) + begin + result = system("bundle exec rake lint > /dev/null") + $stderr.puts result + if !result + status = false + $stderr.puts "!"*80 + $stderr.puts "rake lint failed for #{mod}" + $stderr.puts "!"*80 + end + rescue Exception => e + $stderr.puts "ERROR: Unable to run lint for #{mod}, #{e.message}" + status = false + end + Dir.chdir(cdir) + end + fail unless status + end +end diff --git a/deployment_scripts/puppet/modules/pcs_fencing/.fixtures.yml b/deployment_scripts/puppet/modules/pcs_fencing/.fixtures.yml index 9d3d8c3..4df429d 100644 --- a/deployment_scripts/puppet/modules/pcs_fencing/.fixtures.yml +++ b/deployment_scripts/puppet/modules/pcs_fencing/.fixtures.yml @@ -1,9 +1,11 @@ fixtures: repositories: #corosync: 'https://github.com/puppetlabs/puppetlabs-corosync.git' + #pacemaker: 'https://github.com/puppet-community/puppet-corosync' #stdlib: 'https://github.com/puppetlabs/puppetlabs-stdlib.git' - + symlinks: pcs_fencing: "#{source_dir}" corosync: "#{source_dir}/../corosync" + pacemaker: "#{source_dir}/../pacemaker" stdlib: "#{source_dir}/../stdlib" diff --git a/deployment_scripts/puppet/modules/pcs_fencing/Gemfile b/deployment_scripts/puppet/modules/pcs_fencing/Gemfile index 2797c77..6f0ea8a 100644 --- a/deployment_scripts/puppet/modules/pcs_fencing/Gemfile +++ b/deployment_scripts/puppet/modules/pcs_fencing/Gemfile @@ -1,10 +1,11 @@ source 'https://rubygems.org' group :development, :test do + gem 'rspec-puppet', :require => false gem 'puppetlabs_spec_helper', :require => false - gem 'puppet-lint', '~> 0.3.2' - gem 'rake', '10.1.1' - gem 'rspec', '< 2.99' + gem 'puppet-lint', '~> 1.1.0' + gem 'rake', '~> 10.1.0', :require => false + gem 'rspec', '~> 3.3.0', :require => false gem 'json' gem 'webmock' end diff --git a/deployment_scripts/puppet/modules/pcs_fencing/Gemfile.lock b/deployment_scripts/puppet/modules/pcs_fencing/Gemfile.lock deleted file mode 100644 index a730a2f..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/Gemfile.lock +++ /dev/null @@ -1,56 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - addressable (2.3.6) - crack (0.4.2) - safe_yaml (~> 1.0.0) - diff-lcs (1.2.5) - facter (2.3.0) - hiera (1.3.4) - json_pure - json (1.8.1) - json_pure (1.8.1) - metaclass (0.0.4) - mocha (1.1.0) - metaclass (~> 0.0.1) - puppet (3.7.3) - facter (> 1.6, < 3) - hiera (~> 1.0) - json_pure - puppet-lint (0.3.2) - puppet-syntax (1.3.0) - rake - puppetlabs_spec_helper (0.8.2) - mocha - puppet-lint - puppet-syntax - rake - rspec - rspec-puppet - rake (10.1.1) - rspec (2.14.1) - rspec-core (~> 2.14.0) - rspec-expectations (~> 2.14.0) - rspec-mocks (~> 2.14.0) - rspec-core (2.14.8) - rspec-expectations (2.14.5) - diff-lcs (>= 1.1.3, < 2.0) - rspec-mocks (2.14.6) - rspec-puppet (1.0.1) - rspec - safe_yaml (1.0.4) - webmock (1.20.4) - addressable (>= 2.3.6) - crack (>= 0.3.2) - -PLATFORMS - ruby - -DEPENDENCIES - json - puppet - puppet-lint (~> 0.3.2) - puppetlabs_spec_helper - rake (= 10.1.1) - rspec (< 2.99) - webmock diff --git a/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/type/cs_fencetopo.rb b/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/type/cs_fencetopo.rb index 1565882..e6e5d74 100644 --- a/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/type/cs_fencetopo.rb +++ b/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/type/cs_fencetopo.rb @@ -39,7 +39,7 @@ module Puppet end autorequire(:service) do - [ 'corosync' ] + [ 'corosync', 'pacemaker' ] end autorequire(:cs_shadow) do diff --git a/deployment_scripts/puppet/modules/pcs_fencing/manifests/fencing.pp b/deployment_scripts/puppet/modules/pcs_fencing/manifests/fencing.pp index bb3a8bc..7afc6f7 100644 --- a/deployment_scripts/puppet/modules/pcs_fencing/manifests/fencing.pp +++ b/deployment_scripts/puppet/modules/pcs_fencing/manifests/fencing.pp @@ -52,13 +52,13 @@ define pcs_fencing::fencing ( metadata => $meta, } - cs_location {"location__prohibit__${res_name}": + cs_rsc_location {"location__prohibit__${res_name}": node_name => $::pacemaker_hostname, node_score => '-INFINITY', primitive => $res_name, } - cs_location {"location__allow__${res_name}": + cs_rsc_location {"location__allow__${res_name}": primitive => $res_name, rules => [ { @@ -74,7 +74,7 @@ define pcs_fencing::fencing ( }, ], } - + Cs_resource[$res_name] -> - Cs_location<||> + Cs_rsc_location<||> } diff --git a/deployment_scripts/puppet/modules/pcs_fencing/spec/classes/fencing_primitives_spec.rb b/deployment_scripts/puppet/modules/pcs_fencing/spec/classes/fencing_primitives_spec.rb index c0a31b7..bd1808a 100644 --- a/deployment_scripts/puppet/modules/pcs_fencing/spec/classes/fencing_primitives_spec.rb +++ b/deployment_scripts/puppet/modules/pcs_fencing/spec/classes/fencing_primitives_spec.rb @@ -22,11 +22,16 @@ describe 'pcs_fencing::fencing_primitives' do 'fqdn' => 'node-1.foo.bar', 'name' => 'node-1', 'role' => 'primary-controller' + }, + { + 'fqdn' => 'node-2.foo.bar', + 'name' => 'node-2', + 'role' => 'controller' } ] } end - let(:names) { [ 'node-1.foo.bar' ] } + let(:names) { [ 'node-1.foo.bar', 'node-2.foo.bar' ] } let(:facts) {{ :osfamily => 'RedHat' }} context 'then configuring fencing' do diff --git a/deployment_scripts/puppet/modules/pcs_fencing/spec/defines/fencing_spec.rb b/deployment_scripts/puppet/modules/pcs_fencing/spec/defines/fencing_spec.rb index 3bff555..8cf03d7 100644 --- a/deployment_scripts/puppet/modules/pcs_fencing/spec/defines/fencing_spec.rb +++ b/deployment_scripts/puppet/modules/pcs_fencing/spec/defines/fencing_spec.rb @@ -35,14 +35,12 @@ describe 'pcs_fencing::fencing', :type => :define do { :primitive => res_name, :rules => [ - { - 'score' => '100', - 'boolean' => '', - 'expressions' => [ - {'attribute'=>"#uname",'operation'=>'ne','value'=>node} - ] - } - ] + ["score", "100"], + ["boolean", ""], + ["expressions", [ + {"attribute"=>"#uname", + "operation"=>"ne", + "value"=>"node-1"}]]] } end let(:facts) {{ :osfamily => 'Debian' }} @@ -67,7 +65,7 @@ describe 'pcs_fencing::fencing', :type => :define do ) end it 'should create a prohibit location' do - should contain_cs_location("location__prohibit__#{res_name}").with( + should contain_cs_rsc_location("location__prohibit__#{res_name}").with( { 'node_name' => location_prohibit_params[:node_name], 'node_score' => location_prohibit_params[:score], @@ -76,7 +74,7 @@ describe 'pcs_fencing::fencing', :type => :define do ) end it 'should create an allow location' do - should contain_cs_location("location__allow__#{res_name}").with( + should contain_cs_rsc_location("location__allow__#{res_name}").with( { 'primitive' => location_allow_params[:primitive], 'rules' => location_allow_params[:rules] diff --git a/deployment_scripts/puppet/modules/pcs_fencing/spec/spec_helper.rb b/deployment_scripts/puppet/modules/pcs_fencing/spec/spec_helper.rb index 3d92005..3ba70bd 100644 --- a/deployment_scripts/puppet/modules/pcs_fencing/spec/spec_helper.rb +++ b/deployment_scripts/puppet/modules/pcs_fencing/spec/spec_helper.rb @@ -1 +1,5 @@ -require 'puppetlabs_spec_helper/module_spec_helper' \ No newline at end of file +require 'puppetlabs_spec_helper/module_spec_helper' + +RSpec.configure do |config| + config.expect_with(:rspec) { |c| c.syntax = :should } +end diff --git a/deployment_scripts/puppet/modules/pcs_fencing/spec/unit/puppet/provider/cs_fencetopo/crm_spec.rb b/deployment_scripts/puppet/modules/pcs_fencing/spec/unit/puppet/provider/cs_fencetopo/crm_spec.rb index 6097f44..c020a84 100644 --- a/deployment_scripts/puppet/modules/pcs_fencing/spec/unit/puppet/provider/cs_fencetopo/crm_spec.rb +++ b/deployment_scripts/puppet/modules/pcs_fencing/spec/unit/puppet/provider/cs_fencetopo/crm_spec.rb @@ -135,7 +135,7 @@ describe Puppet::Type.type(:cs_fencetopo).provider(:crm) do out=File.open(File.dirname(__FILE__) + '/../../../../fixtures/cib/cib.xml') provider.class.stubs(:dump_cib).returns(out,nil) provider.class.stubs(:exec_withenv).with(' --query --scope fencing-topology', {}).returns(0) - provider.exists?.should be_true + provider.exists?.should be_truthy end it 'checks if topology singleton does not exist' do @@ -143,7 +143,7 @@ describe Puppet::Type.type(:cs_fencetopo).provider(:crm) do out=File.open(File.dirname(__FILE__) + '/../../../../fixtures/cib/cib_no_topo.xml') provider.class.stubs(:dump_cib).returns(out,nil) provider.class.stubs(:exec_withenv).with(' --query --scope fencing-topology', {}).returns(6) - provider.exists?.should be_false + provider.exists?.should be_falsey end end end diff --git a/deployment_scripts/puppet/modules/pcs_fencing/spec/unit/puppet/type/cs_fencetopo_spec.rb b/deployment_scripts/puppet/modules/pcs_fencing/spec/unit/puppet/type/cs_fencetopo_spec.rb index 9d29091..e80eb63 100644 --- a/deployment_scripts/puppet/modules/pcs_fencing/spec/unit/puppet/type/cs_fencetopo_spec.rb +++ b/deployment_scripts/puppet/modules/pcs_fencing/spec/unit/puppet/type/cs_fencetopo_spec.rb @@ -71,7 +71,7 @@ describe Puppet::Type.type(:cs_fencetopo) do [:cib, :name ].each do |param| it "should have a #{param} parameter" do - subject.validparameter?(param).should be_true + subject.validparameter?(param).should be_truthy end it "should have documentation for its #{param} parameter" do @@ -81,7 +81,7 @@ describe Puppet::Type.type(:cs_fencetopo) do [ :nodes, :fence_topology ].each do |prop| it "should have a #{prop} property" do - subject.validproperty?(prop).should be_true + subject.validproperty?(prop).should be_truthy end it "should have documentation for its #{prop} property" do diff --git a/modules.disable_rspec b/modules.disable_rspec new file mode 100644 index 0000000..73aa0aa --- /dev/null +++ b/modules.disable_rspec @@ -0,0 +1 @@ +pacemaker diff --git a/pre_build_hook b/pre_build_hook index d9d91db..c740a68 100755 --- a/pre_build_hook +++ b/pre_build_hook @@ -4,23 +4,30 @@ set -eux ROOT="$(dirname `readlink -f $0`)" MODULES="${ROOT}"/deployment_scripts/puppet/modules/ -TMP_DIR="${ROOT}"/tmp +TMP_DIR="${ROOT}"/tmp/ mkdir -p "${MODULES}" mkdir -p "${TMP_DIR}" #Puppetlabs/stdlib 4.5.0 REPO_PATH='https://github.com/puppetlabs/puppetlabs-stdlib/tarball/80f09623b63cf6946b5913b629911e2c49b5d1dd' wget -qO- "${REPO_PATH}" | \ - tar -C "${MODULES}" -zxvf - \ + tar -C "${TMP_DIR}" -zxvf - \ puppetlabs-puppetlabs-stdlib-80f0962 && \ - mv "${MODULES}puppetlabs-puppetlabs-stdlib-80f0962" "${MODULES}stdlib" + cp -Rf "${TMP_DIR}puppetlabs-puppetlabs-stdlib-80f0962" "${MODULES}stdlib" -#Fuel 5.1.1 puppet-corosync -REPO_PATH='https://github.com/openstack/fuel-library/tarball/a3043477337b4a0a8fd166dc83d6cd5d504f5da8' -MODULES="${ROOT}"/deployment_scripts/puppet/modules/ +#Puppet-community/puppet-corosync 0.8.0 +REPO_PATH='https://github.com/puppet-community/puppet-corosync/tarball/88e267b00add700aeb0f4dae301bd327a8b18b54' wget -qO- "${REPO_PATH}" | \ - tar -C "${MODULES}" --strip-components=3 -zxvf - \ - openstack-fuel-library-a304347/deployment/puppet/corosync + tar -C "${TMP_DIR}" -zxvf - \ + puppet-community-puppet-corosync-88e267b && \ + cp -Rf "${TMP_DIR}puppet-community-puppet-corosync-88e267b" "${MODULES}corosync" +#Fuel 7.0 pacemaker +REPO_PATH='https://github.com/openstack/fuel-library/tarball/5d50055aeca1dd0dc53b43825dc4c8f7780be9dd' + +wget -qO- "${REPO_PATH}" | \ + tar -C "${TMP_DIR}" --strip-components=3 -zxvf - \ + openstack-fuel-library-5d50055 && \ + cp -Rf "${TMP_DIR}pacemaker" "${MODULES}pacemaker"