diff --git a/.gitignore b/.gitignore deleted file mode 100644 index c8b8df8..0000000 --- a/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -# Plugin -deployment_scripts/puppet/modules/corosync -deployment_scripts/puppet/modules/pacemaker -deployment_scripts/puppet/modules/stdlib -.build -tmp -*.rpm -*.fp - -# Editors -*.swp -*~ - -# Bundle -Gemfile.lock -.bundled_gems -.bundle diff --git a/Gemfile b/Gemfile deleted file mode 100644 index 028f675..0000000 --- a/Gemfile +++ /dev/null @@ -1,33 +0,0 @@ -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/LICENSE b/LICENSE deleted file mode 100644 index e06d208..0000000 --- a/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - 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 deleted file mode 100644 index a6d909a..0000000 --- a/README.md +++ /dev/null @@ -1,280 +0,0 @@ -Fuel Fencing Plugin -=================== - -#### Table of Contents - -1. [Overview - What is the Fuel fencing plugin?](#overview) -2. [Plugin Description - What does the plugin do?](#plugin-description) -3. [Setup - The basics of getting started with Fuel fencing plugin](#setup) -4. [Implementation - An under-the-hood peek at what the plugin is doing](#implementation) -5. [Limitations - OS compatibility, etc.](#limitations) -6. [Development - Guide for contributing to the plugin](#development) -7. [Contributors - Those with commits](#contributors) -8. [Versioning - Fuel and plugin versions](#versioning) -9. [Known Issues - Issues and workarounds](#known-issues) -10. [Release Notes - Notes on the most recent updates to the plugin](#release-notes) - -Overview --------- - -The Fuel fencing plugin is a Puppet configuration module being executed as an -additional post deployment step in order to provide HA fencing (STONITH based) -of a failed cluster nodes. -The plugin itself is used to describe a datacenter's HW power management -configuration - such as PDU outlets, IPMI and other agents - and represent -it as a fencing topology for Corosync & Pacemaker cluster. - -[About Fuel plugins](https://software.mirantis.com/mirantis-openstack-fuel-plug-in-development/) - -Plugin Description ------------------- - -The Fuel fencing plugin is intended to provide STONITHing of the failed nodes -in Corosync & Pacemaker cluster. -Fencing plugin operates the YAML data structures and extends the Fuel YAML -configuration file. - -It suggests the manual definition of the YAML data structures with all required -parameters for existing power management (PM) devices for every controller node. -It is up to the user to collect and verify all the needed IP adresses, credentials, -power outlets layouts, BM hosts to PM devices mappings and other parameters. - -This plugin also installs fence-agents package and assumes -there is the one avaiable in the OS repositories. - -Setup ------ - -### Installing Fencing plugin - -Please refer to the [plugins dev guide](http://docs.mirantis.com/fuel/fuel-6.1/plugin-dev.html#what-is-pluggable-architecture) -Note that in order to build this plugin the following tools must present: -* rsync -* wget - -### Beginning with Fencing plugin - -* Create an HA environment and select the fencing policy (reboot, poweroff or - disabled) at the settings tab. - Note, that there is no difference between the 'reboot' and 'poweroff' policy for - this version of the plugin. The 'reboot' or 'poweroff' value just enables the - fencing feature, while the 'disabled' value - disables it. The difference may - present for future versions, when creation of the YAML configuration files for - nodes will be automated. - -* Assign roles to the nodes as always, but use Fuel CLI instead of Deploy button - to provision all nodes in the environment. Please note, that the power management - devices should be reachable from the management network via TCP protocol: - - ``` - fuel --env node --provision --node - ``` - - (node list should be comma-separated like 1,2,3,4) - -* Define YAML configuration files for controller nodes and existing power management - (PM aka STONITH) devices. See an example in - [deployment_scripts/puppet/modules/pcs_fencing/examples/pcs_fencing.yaml](https://github.com/openstack/fuel-plugin-ha-fencing/blob/master/deployment_scripts/puppet/modules/pcs_fencing/examples/pcs_fencing.yaml). - Note, that quotes for the 'off' and 'reboot' values are important as just an ``off`` - would be equal to ``false``, which is wrong. - - In the given example we assume 'reboot' policy, which is a hard resetting of - the failed nodes in Pacemaker cluster. We define IPMI reset action and PSU OFF/ON - actions for ``fence_ipmilan`` and ``fence_apc_snmp`` agent types. - These agents will be contacted by Pacemaker stonith-ng daemon to STONITH controller - nodes (there are 3 of them according to the given fence topology) in the following - order: - - * If IPMI device reported OK on reset action requested, STONITH is completed. - * if IPMI device cannot succeed on reset action for some reason, PSU OFF action - will be requested. - * In the case of PSU OFF action success, PSU ON action will be requested as well. - * In the case of both OFF and ON actions success, STONITH is completed OK. - * If either of them failed, repeat from the step 1, untill timeout exceeded. - (if timeout exceeded, STONITH is failed) - - For other controllers, the same configuration stanza should be manually populated. - IP addresses, credentials, delay and indexes of the power outlets (in case of PDU/PSU) - of STONISH devices being connected by these agents should be updated as well as - node names. - - Please note, that each controller node should have configured all of its fence agent - types ``delay`` parameters with an increased values. That is required in order to - resolve a mutual fencing situations then the nodes are triyng to STONITH each other. - For example, if you have 3 controllers, set all delay values as 0 for 1st controller, - 10 - for 2nd one and 20 seconds - for the last one. The other timeouts should be - as well adjusted as the following: - ``` - delay + shell_timeout + login_timeout < power_wait < power_timeout - ``` - - Fencing topology could vary for controller nodes but usually it is the same. - It provides an ordering of STONITH agents to call in case of the fencing actions. - It is recommended to configure several types of the fencing devices and put - them to the dedicated admin network. This network should be either directly connected - or reached from the management interfaces of controller nodes in order to provide a - connectivity to the fencing devices. - - In the given example we define the same topology for node-10 and node-11 and slightly - different one for node-12 - just to illustrate that each node could have a different - fence agent types configured, hence, the different topology as well. So, we configure - nodes 10 and 11 to rely on IPMI and PSU devices, while the node 12 is a virtual node - and relies on virsh agent. - - Please also note, that the names of nodes in fence topology stanza and ``pcmk_*`` - parameters should be specified as FQDN names in case of RedHat OS family and as a - short names in case of Debian OS family. That is related to the node naming rules in - Pacemaker cluster in different OS types. - -* Put created fencing configuration YAML files as ``/etc/pcs_fencing.yaml`` - for corresponding controller nodes. - -* Deploy HA environment either by Deploy button in UI or by CLI command: - - ``` - fuel --env node --deploy --node - ``` - - (node list should be comma-separated like 1,2,3,4) - -TODO(bogdando) finish the guide, add agents and devices verification commands - -Please also note that for clusters containing 3,5,7 or more controllers the recommended -value for the ``no-quorum-policy`` cluster property should be changed manually -(after deployment is done) from ignore/stopped to suicide. -For more information on no-quorum policy, see the [Cluster Options](http://clusterlabs.org/doc/en-US/Pacemaker/1.0/html/Pacemaker_Explained/s-cluster-options.html) -section in the official Pacemaker documentation. You can set this property by the command -``` -pcs property set no-quorum-policy=suicide -``` - -Implementation --------------- - -### Fuel Fencing plugin - -This plugin is a combination of Puppet module and metadata required to -describe and configure the fencing topology for Corosync & Pacemaker -cluster. The plugin includes custom puppet module pcs_fencing and as a dependencies, -custom corosync module and puppetlabs/stdlib module v4.5.0. - -It changes global cluster properties: -* cluster-recheck-interval = 3 minutes -* stonith-enabled = True - -It creates a set of STONITH primitives in Pacemaker cluster and runs them in a way, -that ensures the node will never try to shoot itself (-inf location constraint). -It configures a fencing topology singleton primitive in Pacemaker cluster. -It uses crm command line tool which is deprecated and will be replaced to pcs later. - -Limitations ------------ - -* It is not recommended to use this plugin, if controller nodes contain any additional - roles (such as storage, monitoring, compute) in Openstack environment, because - STONITH'ed node in Pacemaker cluster will bring these additional roles residing at - this node down as well. -* Can be used only with the Debian and RedHat OS families with crm command line tool - available. - -Development ------------ - -Developer documentation for the entire Fuel project. - -* https://wiki.openstack.org/wiki/Fuel#Where_can_documentation_be_found - -Contributors ------------- - -Will be added later - -Versioning ----------- - -This module has been given version 6 to track the Fuel releases. The -versioning for plugin releases are as follows: - -``` -Plugin :: Fuel version -6.0.0 -> 6.0 -6.0.1 -> 6.0.1 -8.0.0 -> 6.1, 7.0, 8.0 -``` - -Known Issues ------------- - -### Concurrent nodes deployment issue [LP1411603](https://bugs.launchpad.net/fuel/+bug/1411603) - -After the deployment is finished, please make sure all of the controller nodes have -corresponding ``stonith__*`` primitives and the stonith verification command gives -no errors. - -You can list the STONITH primitives and check their health by the commands: -``` -pcs stonith -pcs stonith level verify -``` - -And the location constraints could be shown by the commands: -``` -pcs constraint list -pcs constraint ref -``` - -It is expected that every ``stonith_*`` primitive should have one "prohibit" and -one "allow" location shown by the ref command. - -If some of the controller nodes does not have corresponding stonith primitives -or locations for them, please follow the workaround provided at the LP bug. - -### Timer expired responses - -There is also possible that fencing actions are timed out with the errors like: - -``` -error: remote_op_done: Operation reboot of node-8 by node-7 for -crmd.7932@node-7.d3cb0ebd: Timer expired -``` - -or some nodes configured with 'reboot' policy may enter the reboot loop caused by -the fencing action. - -All of this means that the given values for timeouts should be verified and adjusted -as appropriate. - -### Node stucks in pending state after was powered on - -There is a known bug in pacemaker 1.1.10 when the fenced node returns back too fast -(see this [mail thread](http://oss.clusterlabs.org/pipermail/pacemaker/2014-April/021564.html) for details): - -Essentially the node is returning "too fast" (specifically, before the fencing -notification arrives) causing pacemaker to forget the node is up and healthy. -The fix for this is https://github.com/beekhof/pacemaker/commit/e777b17 and is -present in 1.1.11 - -As a workaround you should not bring the failed node back within few minutes after -it had been STONITHed. And if it still stucks in pending state, you can restart its -corosync service. And if corosync service hangs on stop and have to be killed and -restarted - make it fast, otherwise another STONITH action triggered by dead corosync -process would arrive. - -Note, this issue should not be relevant since the Fuel 6.1 release containing -the pacemaker 1.1.12 - -Release Notes -------------- - -*** 6.0.0 *** - -* This is the initial release of this plugin. - -*** 6.0.1 *** - -* Add support of the Fuel 6.0.1 - -*** 8.0.0 *** - -* Add support of the Fuel 6.1, 7.0, 8.0 -* Use rpm for the plugin package distribution diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..86e34d6 --- /dev/null +++ b/README.rst @@ -0,0 +1,10 @@ +This project is no longer maintained. + +The contents of this repository are still available in the Git +source code management system. To see the contents of this +repository before it reached its end of life, please check out the +previous commit with "git checkout HEAD^1". + +For any further questions, please email +openstack-discuss@lists.openstack.org or join #openstack-dev on +Freenode. diff --git a/Rakefile b/Rakefile deleted file mode 100644 index 429c176..0000000 --- a/Rakefile +++ /dev/null @@ -1,183 +0,0 @@ -############################################################################### -# 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/ha_fencing_deploy.pp b/deployment_scripts/ha_fencing_deploy.pp deleted file mode 100644 index 3f3916d..0000000 --- a/deployment_scripts/ha_fencing_deploy.pp +++ /dev/null @@ -1,34 +0,0 @@ -notice('MODULAR: ha_fencing/ha_fencing_deploy.pp') - -$role = hiera('role', '') -$primary_controller = $role ? { - 'primary-controller'=>true, default=>false } -$is_controller = $role ? { - 'controller'=>true, default=>false } - -if ($is_controller or $primary_controller) { - include stdlib - # Fetch fencing policy and settings - $ha_fencing_hash = hiera_hash('ha_fencing', {}) - $fence_policy = $ha_fencing_hash['fence_policy'] - $fencing_enabled = $fence_policy ? { - 'disabled'=>false, 'reboot'=>true, - 'poweroff'=>true, default=>false } - - if $fencing_enabled { - $fence_primitives = hiera_hash('fence_primitives', {}) - $fence_topology = hiera_hash('fence_topology', {}) - - $nodes = hiera('nodes', {}) - $controllers = concat( - filter_nodes($nodes,'role','primary-controller'), - filter_nodes($nodes,'role','controller')) - - class { '::pcs_fencing::fencing_primitives': - fence_primitives => $fence_primitives, - fence_topology => $fence_topology, - nodes => $controllers, - primary_controller => $primary_controller, - } - } -} diff --git a/deployment_scripts/ha_fencing_hiera_override.pp b/deployment_scripts/ha_fencing_hiera_override.pp deleted file mode 100644 index 55da3c3..0000000 --- a/deployment_scripts/ha_fencing_hiera_override.pp +++ /dev/null @@ -1,29 +0,0 @@ -notice('MODULAR: ha_fencing/ha_fencing_hiera_override.pp') - -$ha_fencing_hash = hiera('ha_fencing', undef) -$hiera_dir = '/etc/hiera/override' -$plugin_name = 'ha_fencing' -$plugin_yaml = "${plugin_name}.yaml" - -if $ha_fencing_hash { - $yaml_additional_config = pick( - $ha_fencing_hash['yaml_additional_config'], {}) - - file {'/etc/hiera/override': - ensure => directory, - } -> - file { "${hiera_dir}/${plugin_yaml}": - ensure => file, - source => $yaml_additional_config, - } - - package {'ruby-deep-merge': - ensure => 'installed', - } - - file_line {"${plugin_name}_hiera_override": - path => '/etc/hiera.yaml', - line => " - override/${plugin_name}", - after => ' - override/module/%{calling_module}', - } -} diff --git a/deployment_scripts/puppet/modules/pcs_fencing/.fixtures.yml b/deployment_scripts/puppet/modules/pcs_fencing/.fixtures.yml deleted file mode 100644 index 4df429d..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/.fixtures.yml +++ /dev/null @@ -1,11 +0,0 @@ -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/.gitignore b/deployment_scripts/puppet/modules/pcs_fencing/.gitignore deleted file mode 100644 index 353d51f..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -Gemfile.lock -spec/fixtures -.bundle diff --git a/deployment_scripts/puppet/modules/pcs_fencing/Gemfile b/deployment_scripts/puppet/modules/pcs_fencing/Gemfile deleted file mode 100644 index 6f0ea8a..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/Gemfile +++ /dev/null @@ -1,17 +0,0 @@ -source 'https://rubygems.org' - -group :development, :test do - gem 'rspec-puppet', :require => false - gem 'puppetlabs_spec_helper', :require => false - 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 - -if puppetversion = ENV['PUPPET_GEM_VERSION'] - gem 'puppet', puppetversion, :require => false -else - gem 'puppet', :require => false -end diff --git a/deployment_scripts/puppet/modules/pcs_fencing/LICENSE b/deployment_scripts/puppet/modules/pcs_fencing/LICENSE deleted file mode 100644 index 96f12d3..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2014 OpenStack Foundation - - 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/deployment_scripts/puppet/modules/pcs_fencing/README.md b/deployment_scripts/puppet/modules/pcs_fencing/README.md deleted file mode 100644 index b7a13ee..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/README.md +++ /dev/null @@ -1,87 +0,0 @@ -pcs_fencing -=========== - -#### Table of Contents - -1. [Overview - What is the pcs_fencing module?](#overview) -2. [Module Description - What does the module do?](#module-description) -3. [Setup - The basics of getting started with pcs_fencing](#setup) -4. [Implementation - An under-the-hood peek at what the module is doing](#implementation) -5. [Limitations - OS compatibility, etc.](#limitations) -6. [Development - Guide for contributing to the module](#development) -7. [Contributors - Those with commits](#contributors) -8. [Release Notes - Notes on the most recent updates to the module](#release-notes) - -Overview --------- - -TODO(bogdando) provide a link to Fuel plugin repo then ready. -The pcs_fencing module is a part of Fencing plugin for Fuel and have no -a separate code repository. -The module itself is used to configure fencing primitives in Pacemaker -and combine them into the Fencing topology. - -Module Description ------------------- - -The pcs_fencing module is intended to provide STONITH based HA fencing -of the failed nodes in Corosync & Pacemaker cluster. This module -cannot be used separately from Fuel Fencing plugin. -Pcs_fencing module operates the data structures which are tight to the ones -in Fuel YAML configuration file and has no its own parameters. -This module also installs fence-agents package and assumes there is -the one avaiable in the OS repositories. - -Setup ------ - -### Installing pcs_fencing - -This module is being installed automatically as a part of Fuel Fencing -plugin. -The module's rspec tests could be run only after the plugin is built as -its pre build hook will download required Fuel custom puppet module for corosync -and puppetlabs/stdlib module. - -### Beginning with pcs_fencing - -Instructions for beginning with pcs_fencing will be added later. - -Implementation --------------- - -### pcs_fencing - -pcs_fencing is a combination of Puppet manifest and ruby code to delivery -configuration and extra functionality through custom types, providers, parser -functions and facts from Fuel library of puppet manifests. -Note that it requires a custom module for corosync and includes a custom -provider for fencing topology. - -Limitations ------------ - -Limitations will be added as they are discovered. - -Development ------------ - -Developer documentation for the entire Fuel project. - -* https://wiki.openstack.org/wiki/Fuel#Where_can_documentation_be_found - -Contributors ------------- - -Will be added later - -Versioning ----------- - -This module is being versioned as well as Fuel Fencing plugin. - -Release Notes -------------- - -This module has no a separate release notes. See the release notes for -Fuel Fencing plugin. diff --git a/deployment_scripts/puppet/modules/pcs_fencing/Rakefile b/deployment_scripts/puppet/modules/pcs_fencing/Rakefile deleted file mode 100644 index 67e846c..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/Rakefile +++ /dev/null @@ -1,7 +0,0 @@ -require 'rubygems' -require 'puppetlabs_spec_helper/rake_tasks' -require 'puppet-lint/tasks/puppet-lint' - -PuppetLint.configuration.fail_on_warnings = true -PuppetLint.configuration.send('disable_80chars') -PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "pkg/**/*.pp"] diff --git a/deployment_scripts/puppet/modules/pcs_fencing/examples/pcs_fencing.yaml b/deployment_scripts/puppet/modules/pcs_fencing/examples/pcs_fencing.yaml deleted file mode 100644 index 2dfc584..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/examples/pcs_fencing.yaml +++ /dev/null @@ -1,117 +0,0 @@ -#fence_policy: reboot -fence_topology: - node-10.test.local: - '1': - - ipmi_reset - '2': - - psu_off - - psu_on - node-11.test.local: - '1': - - ipmi_reset - '2': - - psu_off - - psu_on - node-12.test.local: - '1': - - virsh_reset -fence_primitives: - ipmi_reset: - agent_type: fence_ipmilan - operations: - monitor: - interval: 3600s - timeout: 120s - start: - interval: '0' - timeout: 120s - on-fail: restart - stop: - interval: '0' - timeout: 1800s - on-fail: restart - meta: - migration-threshold: '5' - failure-timeout: '180' - parameters: - ipaddr: 10.11.12.13 - login: ipmi_user - passwd: ipmi_pass - privlvl: operator - auth: password - power_wait: '15' - delay: '300' - action: 'reboot' - pcmk_reboot_action: 'reboot' - pcmk_off_action: 'reboot' - pcmk_host_list: node-10.test.local - psu_off: - agent_type: fence_apc_snmp - operations: - monitor: - interval: 3600s - timeout: 120s - start: - interval: '0' - timeout: 120s - on-fail: restart - stop: - interval: '0' - timeout: 1800s - on-fail: fence - meta: - migration-threshold: '5' - failure-timeout: '180' - parameters: - ipaddr: 10.11.12.14 - login: tripplite - community: QWErty123 - snmp_auth_prot: MD5 - snmp_priv_prot: DES - port: '5' - snmp_sec_level: authPriv - passwd: QWErty123 - power_timeout: '30' - shell_timeout: '10' - login_timeout: '10' - power_wait: '15' - delay: '300' - action: 'off' - pcmk_reboot_action: 'off' - pcmk_off_action: 'off' - pcmk_host_list: node-10.test.local - psu_on: - agent_type: fence_apc_snmp - operations: - monitor: - interval: 3600s - timeout: 120s - start: - interval: '0' - timeout: 120s - on-fail: restart - stop: - interval: '0' - timeout: 1800s - on-fail: fence - meta: - migration-threshold: '5' - failure-timeout: '180' - parameters: - ipaddr: 10.11.12.14 - login: tripplite - community: QWErty123 - snmp_auth_prot: MD5 - snmp_priv_prot: DES - port: '5' - snmp_sec_level: authPriv - passwd: QWErty123 - power_timeout: '30' - shell_timeout: '10' - login_timeout: '10' - power_wait: '15' - delay: '300' - action: 'on' - pcmk_reboot_action: 'on' - pcmk_off_action: 'on' - pcmk_host_list: node-10.test.local diff --git a/deployment_scripts/puppet/modules/pcs_fencing/examples/pcs_fencing_virsh.yaml b/deployment_scripts/puppet/modules/pcs_fencing/examples/pcs_fencing_virsh.yaml deleted file mode 100644 index 47406d7..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/examples/pcs_fencing_virsh.yaml +++ /dev/null @@ -1,43 +0,0 @@ -#fence_policy: reboot -fence_topology: - node-7: - '1': - - virsh_reset - node-8: - '1': - - virsh_reset - node-9: - '1': - - virsh_reset -fence_primitives: - virsh_reset: - agent_type: fence_virsh - operations: - monitor: - interval: 3600s - timeout: 120s - start: - interval: '0' - timeout: 120s - on-fail: restart - stop: - interval: '0' - timeout: 1800s - on-fail: restart - meta: - migration-threshold: '5' - failure-timeout: '180' - parameters: - ipaddr: 10.108.5.1 - login: virsh_ssh_user - passwd: virsh_ssh_pass - power_wait: '15' - power_timeout: '20' - shell_timeout: '10' - login_timeout: '5' - secure: true - delay: '300' - action: 'reboot' - pcmk_reboot_action: 'reboot' - pcmk_off_action: 'reboot' - pcmk_host_map: 'node-7:env60_slave-07' diff --git a/deployment_scripts/puppet/modules/pcs_fencing/lib/facter/fencing_config.rb b/deployment_scripts/puppet/modules/pcs_fencing/lib/facter/fencing_config.rb deleted file mode 100644 index 93a8632..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/lib/facter/fencing_config.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'facter' - -fencing_settings_path = ['/etc/pcs_fencing.yaml'] - -fencing_settings_path.each do |fencing_file| - if File.exist?(fencing_file) - Facter.add('fencing_settings_file') do - setcode { fencing_file } - end - Facter.add('fencing_settings_yaml') do - setcode { File.read(fencing_file) } - end - break - end -end diff --git a/deployment_scripts/puppet/modules/pcs_fencing/lib/facter/naily.rb b/deployment_scripts/puppet/modules/pcs_fencing/lib/facter/naily.rb deleted file mode 100644 index 06755d1..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/lib/facter/naily.rb +++ /dev/null @@ -1,16 +0,0 @@ -require 'facter' - -# This file is created and managed by Astute -astute_settings_path = ['/etc/fuel/astute.yaml', '/etc/astute.yaml'] - -astute_settings_path.each do |astute_file| - if File.exist?(astute_file) - Facter.add('astute_settings_file') do - setcode { astute_file } - end - Facter.add('astute_settings_yaml') do - setcode { File.read(astute_file) } - end - break - end -end diff --git a/deployment_scripts/puppet/modules/pcs_fencing/lib/facter/pacemaker_hostname.rb b/deployment_scripts/puppet/modules/pcs_fencing/lib/facter/pacemaker_hostname.rb deleted file mode 100644 index 83cd20e..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/lib/facter/pacemaker_hostname.rb +++ /dev/null @@ -1,9 +0,0 @@ -# Fact: pacemaker_hostname -# -# Purpose: Return name of the node used by Pacemaker -# -Facter.add(:pacemaker_hostname) do - setcode do - rv = Facter::Util::Resolution.exec('crm_node -n') - end -end diff --git a/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/parser/functions/filter_hash.rb b/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/parser/functions/filter_hash.rb deleted file mode 100644 index bbf0529..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/parser/functions/filter_hash.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Puppet::Parser::Functions - newfunction(:filter_hash, :type => :rvalue, :doc => <<-EOS - Map array of hashes $arg0 to an array yielding - an element from each hash by key $arg1 - EOS - ) do |args| - hash = args[0] - field = args[1] - hash.map do |e| - e[field] - end - end -end diff --git a/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/parser/functions/filter_nodes.rb b/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/parser/functions/filter_nodes.rb deleted file mode 100644 index 89a58da..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/parser/functions/filter_nodes.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Puppet::Parser::Functions - newfunction(:filter_nodes, :type => :rvalue) do |args| - name = args[1] - value = args[2] - args[0].select do |it| - it[name] == value - end - end -end \ No newline at end of file diff --git a/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/parser/functions/parseyaml.rb b/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/parser/functions/parseyaml.rb deleted file mode 100644 index 53d54fa..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/parser/functions/parseyaml.rb +++ /dev/null @@ -1,24 +0,0 @@ -# -# parseyaml.rb -# - -module Puppet::Parser::Functions - newfunction(:parseyaml, :type => :rvalue, :doc => <<-EOS -This function accepts YAML as a string and converts it into the correct -Puppet structure. - EOS - ) do |arguments| - - if (arguments.size != 1) then - raise(Puppet::ParseError, "parseyaml(): Wrong number of arguments "+ - "given #{arguments.size} for 1") - end - - require 'yaml' - - YAML::load(arguments[0]) - - end -end - -# vim: set ts=2 sw=2 et : diff --git a/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/provider/corosync.rb b/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/provider/corosync.rb deleted file mode 100644 index 014e87b..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/provider/corosync.rb +++ /dev/null @@ -1,144 +0,0 @@ -require 'pp' -require 'open3' -require 'rexml/document' - -class Puppet::Provider::Corosync < Puppet::Provider - - def self.dump_cib - self.block_until_ready - stdout = Open3.popen3("#{command(:crm)} configure show xml")[1].read - return stdout, nil - end - - def try_command(command,resource_name,should=nil,cib=nil,timeout=120) - cmd = "#{command(:crm)} configure #{command} #{resource_name} #{should} ".rstrip - env = {} - if cib - env["CIB_shadow"]=cib.to_s - end - Timeout::timeout(timeout) do - debug("Issuing #{cmd} for CIB #{cib} ") - loop do - break if exec_withenv(cmd,env) == 0 - sleep 2 - end - end - end - - def exec_withenv(cmd,env=nil) - self.class.exec_withenv(cmd,env) - end - - def self.exec_withenv(cmd,env=nil) - Process.fork do - ENV.update(env) if !env.nil? - Process.exec(cmd) - end - Process.wait - $?.exitstatus - end - - # Corosync takes a while to build the initial CIB configuration once the - # service is started for the first time. This provides us a way to wait - # until we're up so we can make changes that don't disappear in to a black - # hole. - - def self.block_until_ready(timeout = 120) - cmd = "#{command(:crm_attribute)} --type crm_config --query --name dc-version 2>/dev/null" - Timeout::timeout(timeout) do - until exec_withenv(cmd) == 0 - debug('Corosync not ready, retrying') - sleep 2 - end - # Sleeping a spare two since it seems that dc-version is returning before - # It is really ready to take config changes, but it is close enough. - # Probably need to find a better way to check for reediness. - sleep 2 - end - end - - def self.prefetch(resources) - instances.each do |prov| - if res = resources[prov.name.to_s] - res.provider = prov - end - end - end - - def exists? - self.class.block_until_ready - Puppet.debug "Call exists? on cs_resource '#{@resource[:name]}'" - out = !(@property_hash[:ensure] == :absent or @property_hash.empty?) - Puppet.debug "Return: #{out}" - Puppet.debug "Current state:\n#{@property_hash.pretty_inspect}" if @property_hash.any? - out - end - - def get_scope(type) - case type - when 'resource' - scope='resources' - when /^(colocation|order|location)$/ - scope='constraints' - when 'rsc_defaults' - scope='rsc_defaults' - else - fail('unknown resource type') - scope=nil - end - return scope - end - - def apply_changes(res_name,tmpfile,res_type) - env={} - shadow_name="#{res_type}_#{res_name}" - original_cib="/tmp/#{shadow_name}_orig.xml" - new_cib="/tmp/#{shadow_name}_new.xml" - begin - debug('trying to delete old shadow if exists') - crm_shadow("-b","-f","-D",shadow_name) - rescue Puppet::ExecutionFailure - debug('delete failed but proceeding anyway') - end - if !get_scope(res_type).nil? - cibadmin_scope = "-o #{get_scope(res_type)}" - else - cibadmin_scope = nil - end - crm_shadow("-b","-c",shadow_name) - env["CIB_shadow"] = shadow_name - orig_status = exec_withenv("#{command(:cibadmin)} #{cibadmin_scope} -Q > /tmp/#{shadow_name}_orig.xml", env) - #cibadmin returns code 6 if scope is empty - #in this case write empty file - if orig_status == 6 or File.open("/tmp/#{shadow_name}_orig.xml").read.empty? - cur_scope=REXML::Element.new(get_scope(res_type)).to_s - emptydoc=REXML::Document.new(cur_scope) - emptydoc.write(File.new("/tmp/#{shadow_name}_orig.xml",'w')) - end - exec_withenv("#{command(:crm)} configure load update #{tmpfile.path.to_s}",env) - exec_withenv("#{command(:cibadmin)} #{cibadmin_scope} -Q > /tmp/#{shadow_name}_new.xml",env) - patch = Open3.popen3("#{command(:crm_diff)} --original #{original_cib} --new #{new_cib}")[1].read - if patch.empty? - debug("no difference - nothing to apply") - return - end - xml_patch = REXML::Document.new(patch) - wrap_cib=REXML::Element.new('cib') - wrap_configuration=REXML::Element.new('configuration') - wrap_cib.add_element(wrap_configuration) - wrap_cib_a=Marshal.load(Marshal.dump(wrap_cib)) - wrap_cib_r=Marshal.load(Marshal.dump(wrap_cib)) - diff_a=REXML::XPath.first(xml_patch,'//diff-added') - diff_r=REXML::XPath.first(xml_patch,'//diff-removed') - diff_a_elements=diff_a.elements - diff_r_elements=diff_r.elements - wrap_configuration_a=REXML::XPath.first(wrap_cib_a,'//configuration') - wrap_configuration_r=REXML::XPath.first(wrap_cib_r,'//configuration') - diff_a_elements.each {|element| wrap_configuration_a.add_element(element)} - diff_r_elements.each {|element| wrap_configuration_r.add_element(element)} - diff_a.add_element(wrap_cib_a) - diff_r.add_element(wrap_cib_r) - cibadmin '--patch', '--sync-call', '--xml-text', xml_patch - end - -end diff --git a/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/provider/cs_fencetopo/crm.rb b/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/provider/cs_fencetopo/crm.rb deleted file mode 100644 index c4d7f8d..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/provider/cs_fencetopo/crm.rb +++ /dev/null @@ -1,134 +0,0 @@ -require 'pathname' -require 'open3' -require Pathname.new(__FILE__).dirname.dirname.expand_path + 'corosync' -require 'rexml/document' - -Puppet::Type.type(:cs_fencetopo).provide(:crm, :parent => Puppet::Provider::Corosync) do - desc 'Specific provider for a rather specific type since I currently have no plan to - abstract corosync/pacemaker vs. keepalived. This provider will create or destroy - a singleton for fencing topology configuration.' - - # Path to the crm binary for interacting with the cluster configuration. - commands :crm => 'crm' - commands :cibadmin => 'cibadmin' - commands :crm_attribute => 'crm_attribute' - - def self.instances - - block_until_ready - - raw, status = dump_cib - doc = REXML::Document.new(raw) - nodes = [] - fence_topology = {} - # return empty array, if there is no topology singleton configured in cib - stanzas = doc.root.elements['configuration/fencing-topology'] rescue nil - return [] if stanzas.nil? - # otherwise, parse cib for existing topology singleton and return it as provider instance - stanzas.each_element do |e| - items = e.attributes - line = { :fence_primitives => items['devices'], :node => items['target'], :index => items['index'] } - primitives = line[:fence_primitives].split(',') - if primitives.length > 1 then - agents = [] - primitives.each { |primitive| agents << (/^stonith__([^__].+)__.*$/.match(primitive)[1] rescue 'primitive_name_parse_error') } - else - agents = [(/^stonith__([^__].+)__.*$/.match(primitives[0])[1] rescue 'primitive_name_parse_error')] - end - nodes.push(line[:node]) unless nodes.include?(line[:node]) - fence_topology[line[:node]] = {} if fence_topology[line[:node]].nil? - fence_topology[line[:node]][line[:index]] = agents - end - property_instance = { - :name => 'myfencetopo', - :ensure => :present, - :fence_topology => fence_topology, - :nodes => nodes, - :provider => self.name - } - [new(property_instance)] - end - - # SET - def nodes=(should) - @property_hash[:nodes] = should - end - - def fence_topology=(should) - @property_hash[:fence_topology] = should - end - #GET - def nodes - @property_hash[:nodes] - end - - def fence_topology - @property_hash[:fence_topology] - end - - def create - @property_hash = { - :name => @resource[:name], - :ensure => :present, - :fence_topology => @resource[:fence_topology], - :nodes => @resource[:nodes] - } - @property_hash[:cib] = @resource[:cib] if ! @resource[:cib].nil? - end - - def destroy - debug("Removing fencing topology") - env = {} - env["CIB_shadow"] = @resource[:cib].to_s if !@resource[:cib].nil? - commands_to_exec = '' - commands_to_exec << "#{command(:cibadmin)} --scope fencing-topology --delete-all --force --xpath //fencing-level 2>&1" - commands_to_exec << "\n" - commands_to_exec << "#{command(:cibadmin)} --delete --xml-text '' 2>&1" - exec_withenv(commands_to_exec, env) - @property_hash.clear - end - - def exists? - self.class.block_until_ready - debug(@property_hash.inspect) - env = {} - env["CIB_shadow"] = @resource[:cib].to_s if !@resource[:cib].nil? - commands_to_exec = "#{command(:cibadmin)} --query --scope fencing-topology" - exec_withenv(commands_to_exec, env) == 0 - end - - def flush - unless @property_hash.empty? or self.class.instances != [] - self.class.block_until_ready - args = '' - @property_hash[:nodes].each do |node| - # extract node's short name from its fqdn, if defined - shortname = /^([^.]+)\..*$/.match(node)[1] rescue node - pos = 1 - # start crafting node's topology from position #1, - # nodes' topology lines should be separated by whitespace - line = " #{node}: " - @property_hash[:fence_topology][node].sort.each do |index, primitives| - primitives.each do |primitive| - line += case pos - # first primitive should be put after its node fqdn - when 1 then "stonith__#{primitive}__#{shortname}" - # all primitives with the same indexes should be grouped together, coma separated - when index then ",stonith__#{primitive}__#{shortname}" - # all groups with different indexes should be separated by whitespace - else " stonith__#{primitive}__#{shortname}" - end - pos = index if index != pos - end - end - args += line - # proceed to the next node - end - # send topology lines crafted for all nodes to crm - env = {} - env["CIB_shadow"] = @resource[:cib].to_s if !@resource[:cib].nil? - command_to_exec = "#{command(:crm)} --force configure fencing_topology#{args} 2>&1" - exec_withenv(command_to_exec, env) - end - end -end 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 deleted file mode 100644 index e6e5d74..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/type/cs_fencetopo.rb +++ /dev/null @@ -1,55 +0,0 @@ -module Puppet - newtype(:cs_fencetopo) do - @doc = "Type for manipulating corosync/pacemaker configuration for fencing topology. - More information on fencing topologies can be found here: - * http://clusterlabs.org/wiki/Fencing_topology - " - - ensurable - - newparam(:name) do - desc "Fencing topology name reference." - - isnamevar - end - - newparam(:cib) do - desc "Corosync applies its configuration immediately. Using a CIB allows - you to group multiple primitives and relationships to be applied at - once. This can be necessary to insert complex configurations into - Corosync correctly. - - This paramater sets the CIB this order should be created in. A - cs_shadow resource with a title of the same name as this value should - also be added to your manifest." - end - - newproperty(:nodes, :array_matching=>:all) do - desc "An array with cluster nodes' fqdns" - isrequired - end - - newproperty(:fence_topology) do - desc "A hash with predefined fence topology." - isrequired - validate do |fence_topology| - raise Puppet::Error, "Puppet::Type::Cs_FenceTopo: fencing topology entries must be a hashes." unless fence_topology.is_a? Hash - end - defaultto Hash.new - end - - autorequire(:service) do - [ 'corosync', 'pacemaker' ] - end - - autorequire(:cs_shadow) do - autos = [] - if @parameters[:cib] - autos << @parameters[:cib].value - end - - autos - end - - end -end diff --git a/deployment_scripts/puppet/modules/pcs_fencing/manifests/fencing.pp b/deployment_scripts/puppet/modules/pcs_fencing/manifests/fencing.pp deleted file mode 100644 index 666a4ec..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/manifests/fencing.pp +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright 2013 Mirantis, 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: pcs_fencing::fencing -# -# Configure STONITH resources for Pacemaker. -# -# === Parameters: -# -# [*agent_type*] -# The fence agent name for a STONITH resource -# Defaults to undef -# -# [*parameters*] -# The hash of parameters for a STONITH resource -# Defaults to False -# -# [*operations*] -# The hash of operations for a STONITH resource -# Defaults to False -# -# [*meta*] -# The hash of metadata for a STONITH resource -# Defaults to False -# -define pcs_fencing::fencing ( - $agent_type, - $parameters = false, - $operations = false, - $meta = false, -){ - $res_name = "stonith__${title}__${::hostname}" - - cs_resource { $res_name: - ensure => present, - # stonith does not support providers - provided_by => undef, - primitive_class => 'stonith', - primitive_type => $agent_type, - parameters => $parameters, - operations => $operations, - metadata => $meta, - } - - cs_rsc_location {"location__prohibit__${res_name}": - node_name => $::pacemaker_hostname, - node_score => '-INFINITY', - primitive => $res_name, - } - - cs_rsc_location {"location__allow__${res_name}": - primitive => $res_name, - rules => [ - { - 'score' => '100', - 'boolean' => '', - 'expressions' => [ - { - 'attribute'=> '#uname', - 'operation'=>'ne', - 'value'=>$::pacemaker_hostname, - }, - ], - }, - ], - } - - Cs_resource[$res_name] -> - Cs_rsc_location<||> -} diff --git a/deployment_scripts/puppet/modules/pcs_fencing/manifests/fencing_primitives.pp b/deployment_scripts/puppet/modules/pcs_fencing/manifests/fencing_primitives.pp deleted file mode 100644 index 780ba0e..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/manifests/fencing_primitives.pp +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright 2013 Mirantis, 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. -# -# == Class: pcs_fencing::fencing_primitives -# -# Creates Pacemaker fencing primitives and topology for given nodes. -# Assumes all nodes have the same OS installed. -# -# === Parameters: -# -# [*fence_primitives*] -# The hash of parameters for STONITH resources in Pacemaker -# Defaults to undef -# -# [*fence_topology*] -# The hash of parameters for a fencing topology in Pacemaker -# Defaults to undef -# -# [*node*] -# The array of node names in Pacemaker cluster -# Defaults to undef -# -class pcs_fencing::fencing_primitives ( - $fence_primitives, - $fence_topology, - $nodes, - $primary_controller = true, -) { - case $::osfamily { - 'RedHat': { - $names = filter_hash($nodes, 'fqdn') - $prov = 'pcs' - } - 'Debian': { - $names = filter_hash($nodes, 'name') - $prov = 'crm' - } - default: { - fail("Unsupported osfamily: ${::osfamily} operatingsystem: ${::operatingsystem}, module ${module_name} only support osfamily RedHat and Debian") - } - } - - anchor {'Fencing primitives start':} - anchor {'Fencing primitives end':} - - create_resources('::pcs_fencing::fencing', $fence_primitives) - - if $primary_controller { - cs_fencetopo { 'fencing_topology': - #TODO(bogdando) make crm/pcs providers - ensure => present, - fence_topology => $fence_topology, - nodes => $names, - } - cs_property { 'stonith-enabled': - value => 'true', - provider => $prov, - } - cs_property { 'cluster-recheck-interval': - value => '3min', - provider => $prov, - } - } - - package {'fence-agents':} - - Anchor['Fencing primitives start'] -> - Package['fence-agents'] -> - Pcs_fencing::Fencing<||> -> - Cs_fencetopo<||> -> - Cs_property<||> -> - Anchor['Fencing primitives end'] -} diff --git a/deployment_scripts/puppet/modules/pcs_fencing/metadata.json b/deployment_scripts/puppet/modules/pcs_fencing/metadata.json deleted file mode 100644 index d050044..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/metadata.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "pcs_fencing", - "version": "6.1.0", - "author": "Bogdan Dobrelya ", - "summary": "Puppet Pacemaker fencing Module for Fuel fencing plugin", - "license": "Apache License 2.0", - "source": "git://github.com/bogdando/pcs_fencing.git", - "project_page": "none", - "issues_url": "none", - "requirements": [ - { "name": "pe","version_requirement": "3.x" }, - { "name": "puppet","version_requirement": "3.x" } - ], - "operatingsystem_support": [ - { - "operatingsystem": "Debian", - "operatingsystemrelease": ["7"] - }, - { - "operatingsystem": "Fedora", - "operatingsystemrelease": ["20"] - }, - { - "operatingsystem": "RedHat", - "operatingsystemrelease": ["6.5","7"] - }, - { - "operatingsystem": "Ubuntu", - "operatingsystemrelease": ["12.04","14.04"] - } - ], - "description": "Puppet module for configuring Pacemaker HA fencing in Fuel plugin", - "dependencies": [ - { "name":"puppetlabs/stdlib","version_requirement": "4.x" } - ] -} 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 deleted file mode 100644 index bd1808a..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/spec/classes/fencing_primitives_spec.rb +++ /dev/null @@ -1,71 +0,0 @@ -require 'spec_helper' - -describe 'pcs_fencing::fencing_primitives' do - - let :params do - { - :fence_primitives => { - 'ipmi_off' => { - 'agent_type' => 'fence_ipmilan', - 'operations' => false, - 'meta' => false, - 'parameters' => false - } - }, - :fence_topology => { - 'node-1.foo.bar' => { - '1' => [ 'ipmi_off' ] - } - }, - :nodes => [ - { - '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', 'node-2.foo.bar' ] } - let(:facts) {{ :osfamily => 'RedHat' }} - - context 'then configuring fencing' do - - it 'should install fence-agents' do - should contain_package('fence-agents') - end - - it 'should contain its class' do - should contain_class('pcs_fencing::fencing_primitives').with(params) - end - - it 'should create fencing primitives' do - should contain_pcs_fencing__fencing('ipmi_off').with( - params[:fence_primitives]['ipmi_off'] - ) - end - - it 'should enable fencing' do - should contain_cs_property('stonith-enabled') - end - - it 'should update cluster recheck interval' do - should contain_cs_property('cluster-recheck-interval') - end - - it 'should create a topology' do - should contain_cs_fencetopo('fencing_topology').with( - { - :ensure => 'present', - :fence_topology => params[:fence_topology], - :nodes => names, - } - ) - end - end -end 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 deleted file mode 100644 index 85c95d8..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/spec/defines/fencing_spec.rb +++ /dev/null @@ -1,85 +0,0 @@ -require 'spec_helper' - -describe 'pcs_fencing::fencing', :type => :define do - - let (:title) { 'virsh_off' } - let (:node) { 'node-1' } - let (:res_name) { "stonith__#{title}__#{node}" } - let :params do - { - :agent_type => 'fence_virsh', - :parameters => false, - :operations => false, - :meta => false - } - end - let :primitive_params do - { - :ensure => 'present', - :provided_by => nil, - :primitive_class => 'stonith', - :primitive_type => params[:agent_type], - :parameters => params[:parameters], - :operations => params[:operations], - :metadata => params[:meta] - } - end - let :location_prohibit_params do - { - :node_name => node, - :score => '-INFINITY', - :primitive => res_name - } - end - let :location_allow_params do - { - :primitive => res_name, - :rules => [ - ["score", "100"], - ["boolean", ""], - ["expressions", [ - {"attribute"=>"#uname", - "operation"=>"ne", - "value"=>"node-1"}]]] - } - end - let(:facts) {{ :osfamily => 'Debian' }} - let(:facts) {{ :pacemaker_hostname => node }} - - context 'then configuring STONITH primitive' do - it 'should contain its definition' do - should contain_pcs_fencing__fencing(title).with(params) - end - - it 'should create a pacemaker primitive' do - should contain_cs_resource(res_name).with( - { - 'ensure' => primitive_params[:ensure], - 'primitive_class' => primitive_params[:primitive_class], - 'primitive_type' => primitive_params[:primitive_type], - 'provided_by' => primitive_params[:provided_by], - 'parameters' => primitive_params[:parameters], - 'operations' => primitive_params[:operations], - 'metadata' => primitive_params[:metadata] - } - ) - end - it 'should create a prohibit location' do - should contain_cs_rsc_location("location__prohibit__#{res_name}").with( - { - 'node_name' => location_prohibit_params[:node_name], - 'node_score' => location_prohibit_params[:score], - 'primitive' => location_prohibit_params[:primitive] - } - ) - end - it 'should create an allow location' do - should contain_cs_rsc_location("location__allow__#{res_name}").with( - { - 'primitive' => location_allow_params[:primitive], - 'rules' => location_allow_params[:rules] - } - ) - end - end -end diff --git a/deployment_scripts/puppet/modules/pcs_fencing/spec/fixtures/cib/cib.xml b/deployment_scripts/puppet/modules/pcs_fencing/spec/fixtures/cib/cib.xml deleted file mode 100644 index 60a9f1f..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/spec/fixtures/cib/cib.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/deployment_scripts/puppet/modules/pcs_fencing/spec/fixtures/cib/cib_no_topo.xml b/deployment_scripts/puppet/modules/pcs_fencing/spec/fixtures/cib/cib_no_topo.xml deleted file mode 100644 index aab8cc4..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/spec/fixtures/cib/cib_no_topo.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/deployment_scripts/puppet/modules/pcs_fencing/spec/spec_helper.rb b/deployment_scripts/puppet/modules/pcs_fencing/spec/spec_helper.rb deleted file mode 100644 index 3ba70bd..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/spec/spec_helper.rb +++ /dev/null @@ -1,5 +0,0 @@ -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 deleted file mode 100644 index c020a84..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/spec/unit/puppet/provider/cs_fencetopo/crm_spec.rb +++ /dev/null @@ -1,150 +0,0 @@ -require 'spec_helper' - -describe Puppet::Type.type(:cs_fencetopo).provider(:crm) do - - $fence_topology = { - 'node-1.test.local' => { - '1' => [ - 'ipmi_reset', - ], - '2' => [ - 'psu_off','psu_on' - ], - }, - 'node-2.test.local' => { - '1' => [ - 'ilo_reset', - ], - '2' => [ - 'psu_snmp_off','psu_snmp_on' - ], - }, - } - $nodes = [ 'node-1.test.local', 'node-2.test.local' ] - - $foo_topology = { - 'node-1.foo-test.local' => { - '1' => [ - 'ipmi_off', 'dirac_off', 'ilo_off' - ], - '2' => [ - 'psu1_off','psu2_off' - ], - }, - 'node-2.foo-test.local' => { - '1' => [ - 'ipmi_off', 'dirac_off', 'ilo_off' - ], - '2' => [ - 'psu1_off','psu2_off' - ], - }, - 'node-3.foo-test.local' => { - '1' => [ - 'ipmi_off', 'dirac_off', 'ilo_off' - ], - '2' => [ - 'psu1_off','psu2_off' - ], - }, - } - $foo_nodes = [ 'node-1.foo-test.local', 'node-2.foo-test.local', 'node-3.foo-test.local' ] - - let(:resource) { Puppet::Type.type(:cs_fencetopo).new( - :name=>'myfencetopo', - :provider=>:crm, - :ensure=>:present, - :nodes=>$nodes, - :fence_topology=>$fence_topology) } - - let(:provider) { resource.provider } - let(:instance) { provider.class.instances } - - let(:foo_resource) { Puppet::Type.type(:cs_fencetopo).new( - :name=>'myfootopo', - :provider=>:crm, - :ensure=>:present, - :nodes=>$foo_nodes, - :fence_topology=>$foo_topology) } - - let(:foo_provider) { foo_resource.provider } - let(:foo_instance) { foo_provider.class.instances } - - describe "#create" do - before(:each) do - provider.class.stubs(:exec_withenv).returns(0) - end - - it "should create topology singleton with corresponding nodes list and fence primitives" do - provider.class.stubs(:block_until_ready).returns(true) - provider.class.stubs(:instances).returns([]) - provider.expects(:exec_withenv).with(' --force configure fencing_topology node-1.test.local: stonith__ipmi_reset__node-1 stonith__psu_off__node-1,stonith__psu_on__node-1 node-2.test.local: stonith__ilo_reset__node-2 stonith__psu_snmp_off__node-2,stonith__psu_snmp_on__node-2 2>&1', {}) - provider.create - provider.flush - end - - it "should not try to recreate the same topology (idempotency test)" do - provider.class.stubs(:block_until_ready).returns(true) - provider.class.stubs(:instances).returns([instance]) - provider.create - provider.flush - instance.instance_eval{@property_hash}.should be_nil - end - - it "should not create new topology, if one already exists (singleton test)" do - foo_provider.class.stubs(:block_until_ready).returns(true) - foo_provider.class.stubs(:instances).returns([instance]) - foo_provider.create - foo_provider.flush - foo_instance.instance_eval{@property_hash}.should be_nil - end - end - - describe "#destroy" do - it "should destroy topology singleton" do - expected = '' - expected << ' --scope fencing-topology --delete-all --force --xpath //fencing-level 2>&1' - expected << "\n" - expected << " --delete --xml-text '' 2>&1" - provider.expects(:exec_withenv).with(expected, {}) - provider.destroy - end - end - - describe "#instances" do - it "should find topology singleton" do - provider.class.stubs(:block_until_ready).returns(true) - out=File.open(File.dirname(__FILE__) + '/../../../../fixtures/cib/cib.xml') - provider.class.stubs(:dump_cib).returns(out,nil) - expected = {:name=>"myfencetopo", :fence_topology=>$fence_topology, :nodes=>$nodes, :ensure=>:present, :provider=>:crm} - instance[0].instance_eval{@property_hash}.should eql(expected) - end - - it "should not find topology singleton" do - provider.class.stubs(:block_until_ready).returns(true) - out=File.open(File.dirname(__FILE__) + '/../../../../fixtures/cib/cib_no_topo.xml') - provider.class.stubs(:dump_cib).returns(out,nil) - instance[0].instance_eval{@property_hash}.should be_nil - end - - end - - describe '#exists?' do - it 'checks if topology singleton exists' do - provider.class.stubs(:block_until_ready).returns(true) - 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_truthy - end - - it 'checks if topology singleton does not exist' do - provider.class.stubs(:block_until_ready).returns(true) - 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_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 deleted file mode 100644 index e80eb63..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/spec/unit/puppet/type/cs_fencetopo_spec.rb +++ /dev/null @@ -1,92 +0,0 @@ -require 'spec_helper' - -describe Puppet::Type.type(:cs_fencetopo) do - subject do - Puppet::Type.type(:cs_fencetopo) - end - - $fence_topology = { - 'node-1.test.local' => { - '1' => [ - 'ipmi_reset', - ], - '2' => [ - 'psu_off','psu_on' - ], - }, - 'node-2.test.local' => { - '1' => [ - 'ilo_reset', - ], - '2' => [ - 'psu_snmp_off','psu_snmp_on' - ], - } - } - $nodes = [ 'node-1.test.local', 'node-2.test.local' ] - - $foo_topology = { - 'node-1.foo-test.local' => { - '1' => [ - 'ipmi_off', 'dirac_off', 'ilo_off' - ], - '2' => [ - 'psu1_off','psu2_off' - ], - }, - 'node-2.foo-test.local' => { - '1' => [ - 'ipmi_off', 'dirac_off', 'ilo_off' - ], - '2' => [ - 'psu1_off','psu2_off' - ], - }, - 'node-3.foo-test.local' => { - '1' => [ - 'ipmi_off', 'dirac_off', 'ilo_off' - ], - '2' => [ - 'psu1_off','psu2_off' - ], - }, - } - $foo_nodes = [ 'node-1.foo-test.local', 'node-2.foo-test.local', 'node-3.foo-test.local' ] - - it "should have a 'name' parameter" do - subject.new(:name => 'mock_resource')[:name].should == 'mock_resource' - end - - describe "basic structure" do - it "should be able to create a singleton instance" do - provider_class = Puppet::Type::Cs_fencetopo.provider(Puppet::Type::Cs_fencetopo.providers[0]) - Puppet::Type::Cs_fencetopo.expects(:defaultprovider).returns(provider_class) - - subject.new(:name => "mock_resource").should_not be_nil - end - - #it "should not be able to create other instances" do - #TODO verify if fencetopo has a singleton nature - #end - - [:cib, :name ].each do |param| - it "should have a #{param} parameter" do - subject.validparameter?(param).should be_truthy - end - - it "should have documentation for its #{param} parameter" do - subject.paramclass(param).doc.should be_instance_of(String) - end - end - - [ :nodes, :fence_topology ].each do |prop| - it "should have a #{prop} property" do - subject.validproperty?(prop).should be_truthy - end - - it "should have documentation for its #{prop} property" do - subject.propertybyname(prop).doc.should be_instance_of(String) - end - end - end -end diff --git a/deployment_scripts/puppet/modules/pcs_fencing/test/site.pp b/deployment_scripts/puppet/modules/pcs_fencing/test/site.pp deleted file mode 100644 index 3d45524..0000000 --- a/deployment_scripts/puppet/modules/pcs_fencing/test/site.pp +++ /dev/null @@ -1,24 +0,0 @@ -node default { - class { 'pcs_fencing::fencing_primitives': - fence_primitives => { - 'ipmi_off' => { - 'agent_type' => 'fence_ipmilan', - 'operations' => false, - 'meta' => false, - 'parameters' => false, - }, - }, - fence_topology => { - 'node-1' => { - '1' => [ 'ipmi_off' ], - } - }, - nodes => [ - { - 'name' => 'node-1', - 'fqdn' => 'node-1.foo.bar', - 'role' => 'primary-controller', - }, - ], - } -} diff --git a/environment_config.yaml b/environment_config.yaml deleted file mode 100644 index 986472d..0000000 --- a/environment_config.yaml +++ /dev/null @@ -1,13 +0,0 @@ -attributes: - fence_policy: - value: 'reboot' - label: 'Policy for HA fencing [disabled, reboot, poweroff]' - description: 'Pick a type of HA fencing policy' - weight: 25 - type: "text" - yaml_additional_config: - value: '/etc/pcs_fencing.yaml' - label: 'Yaml settings file for fencing configuration' - description: 'Pick a Yaml file for fencing config' - weight: 25 - type: "text" diff --git a/metadata.yaml b/metadata.yaml deleted file mode 100644 index 65c73db..0000000 --- a/metadata.yaml +++ /dev/null @@ -1,52 +0,0 @@ -# Plugin name -name: ha_fencing -title: HA fencing for Pacemaker cluster -# Plugin version -version: 8.0.0 -# Description -description: Enables STONITH of the failed nodes in Corosync & Pacemaker cluster -# Required fuel version -fuel_version: ['6.1', '7.0', '8.0'] -# Specify license of your plugin -licenses: ['Apache License Version 2.0'] -# Specify author or company name -authors: ['Bogdan Dobrelya','Mirantis'] -# A link to the plugin's page -homepage: 'https://github.com/openstack/fuel-plugin-ha-fencing' -# Specify a group which your plugin implements, possible options: -# network, storage, storage::cinder, storage::glance, hypervisor -groups: [network] -# The plugin is compatible with releases in the list -releases: - - os: ubuntu - version: 2014.2.2-6.1 - mode: ['ha'] - deployment_scripts_path: deployment_scripts/ - repository_path: repositories/ubuntu - - os: centos - version: 2014.2.2-6.1 - mode: ['ha'] - deployment_scripts_path: deployment_scripts/ - repository_path: repositories/centos - - os: ubuntu - version: 2015.1.0-7.0 - mode: ['ha'] - deployment_scripts_path: deployment_scripts/ - repository_path: repositories/ubuntu - - os: centos - version: 2015.1.0-7.0 - mode: ['ha'] - deployment_scripts_path: deployment_scripts/ - repository_path: repositories/centos - - os: ubuntu - version: 2015.1.0-8.0 - mode: ['ha'] - deployment_scripts_path: deployment_scripts/ - repository_path: repositories/ubuntu - - os: centos - version: 2015.1.0-8.0 - mode: ['ha'] - deployment_scripts_path: deployment_scripts/ - repository_path: repositories/centos -# Version of plugin package -package_version: '2.0.0' diff --git a/modules.disable_rspec b/modules.disable_rspec deleted file mode 100644 index 73aa0aa..0000000 --- a/modules.disable_rspec +++ /dev/null @@ -1 +0,0 @@ -pacemaker diff --git a/pre_build_hook b/pre_build_hook deleted file mode 100755 index c740a68..0000000 --- a/pre_build_hook +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -set -eux - -ROOT="$(dirname `readlink -f $0`)" -MODULES="${ROOT}"/deployment_scripts/puppet/modules/ -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 "${TMP_DIR}" -zxvf - \ - puppetlabs-puppetlabs-stdlib-80f0962 && \ - cp -Rf "${TMP_DIR}puppetlabs-puppetlabs-stdlib-80f0962" "${MODULES}stdlib" - -#Puppet-community/puppet-corosync 0.8.0 -REPO_PATH='https://github.com/puppet-community/puppet-corosync/tarball/88e267b00add700aeb0f4dae301bd327a8b18b54' - -wget -qO- "${REPO_PATH}" | \ - 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" - diff --git a/repositories/centos/.gitkeep b/repositories/centos/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/repositories/ubuntu/.gitkeep b/repositories/ubuntu/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/tasks.yaml b/tasks.yaml deleted file mode 100644 index 11ec776..0000000 --- a/tasks.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# Deployment tasks -- id: ha-fencing-hiera-override - role: ['primary-controller', 'controller'] - stage: post_deployment - requires: [post_deployment_start] - required_for: [post_deployment_end] - type: puppet - parameters: - puppet_manifest: "ha_fencing_hiera_override.pp" - puppet_modules: "puppet/modules" - timeout: 120 - -- id: ha-fencing-deploy - role: ['primary-controller', 'controller'] - stage: post_deployment - requires: [post_deployment_start, ha-fencing-hiera-override] - required_for: [post_deployment_end] - type: puppet - parameters: - puppet_manifest: "ha_fencing_deploy.pp" - puppet_modules: "puppet/modules" - timeout: 600