From 9df6f15602ea56bf3d1916041e65ce6cb6600f97 Mon Sep 17 00:00:00 2001 From: Andreas Jaeger Date: Wed, 18 Dec 2019 19:38:07 +0100 Subject: [PATCH] Retire repository Fuel repositories are all retired in openstack namespace, retire remaining fuel repos in x namespace since they are unused now. This change removes all content from the repository and adds the usual README file to point out that the repository is retired following the process from https://docs.openstack.org/infra/manual/drivers.html#retiring-a-project See also http://lists.openstack.org/pipermail/openstack-discuss/2019-December/011675.html A related change is: https://review.opendev.org/699752 . Change-Id: I45375a928e84a015f4fcc43f14dcc8d88eb1d6d6 --- .gitignore | 17 -- Gemfile | 33 --- LICENSE | 202 ------------- README.md | 280 ------------------ README.rst | 10 + Rakefile | 183 ------------ deployment_scripts/ha_fencing_deploy.pp | 34 --- .../ha_fencing_hiera_override.pp | 29 -- .../puppet/modules/pcs_fencing/.fixtures.yml | 11 - .../puppet/modules/pcs_fencing/.gitignore | 3 - .../puppet/modules/pcs_fencing/Gemfile | 17 -- .../puppet/modules/pcs_fencing/LICENSE | 201 ------------- .../puppet/modules/pcs_fencing/README.md | 87 ------ .../puppet/modules/pcs_fencing/Rakefile | 7 - .../pcs_fencing/examples/pcs_fencing.yaml | 117 -------- .../examples/pcs_fencing_virsh.yaml | 43 --- .../pcs_fencing/lib/facter/fencing_config.rb | 15 - .../modules/pcs_fencing/lib/facter/naily.rb | 16 - .../lib/facter/pacemaker_hostname.rb | 9 - .../puppet/parser/functions/filter_hash.rb | 13 - .../puppet/parser/functions/filter_nodes.rb | 9 - .../lib/puppet/parser/functions/parseyaml.rb | 24 -- .../lib/puppet/provider/corosync.rb | 144 --------- .../lib/puppet/provider/cs_fencetopo/crm.rb | 134 --------- .../lib/puppet/type/cs_fencetopo.rb | 55 ---- .../modules/pcs_fencing/manifests/fencing.pp | 81 ----- .../manifests/fencing_primitives.pp | 84 ------ .../puppet/modules/pcs_fencing/metadata.json | 36 --- .../spec/classes/fencing_primitives_spec.rb | 71 ----- .../pcs_fencing/spec/defines/fencing_spec.rb | 85 ------ .../pcs_fencing/spec/fixtures/cib/cib.xml | 60 ---- .../spec/fixtures/cib/cib_no_topo.xml | 54 ---- .../modules/pcs_fencing/spec/spec_helper.rb | 5 - .../puppet/provider/cs_fencetopo/crm_spec.rb | 150 ---------- .../unit/puppet/type/cs_fencetopo_spec.rb | 92 ------ .../puppet/modules/pcs_fencing/test/site.pp | 24 -- environment_config.yaml | 13 - metadata.yaml | 52 ---- modules.disable_rspec | 1 - pre_build_hook | 33 --- repositories/centos/.gitkeep | 0 repositories/ubuntu/.gitkeep | 0 tasks.yaml | 22 -- 43 files changed, 10 insertions(+), 2546 deletions(-) delete mode 100644 .gitignore delete mode 100644 Gemfile delete mode 100644 LICENSE delete mode 100644 README.md create mode 100644 README.rst delete mode 100644 Rakefile delete mode 100644 deployment_scripts/ha_fencing_deploy.pp delete mode 100644 deployment_scripts/ha_fencing_hiera_override.pp delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/.fixtures.yml delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/.gitignore delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/Gemfile delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/LICENSE delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/README.md delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/Rakefile delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/examples/pcs_fencing.yaml delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/examples/pcs_fencing_virsh.yaml delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/lib/facter/fencing_config.rb delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/lib/facter/naily.rb delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/lib/facter/pacemaker_hostname.rb delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/parser/functions/filter_hash.rb delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/parser/functions/filter_nodes.rb delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/parser/functions/parseyaml.rb delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/provider/corosync.rb delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/provider/cs_fencetopo/crm.rb delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/lib/puppet/type/cs_fencetopo.rb delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/manifests/fencing.pp delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/manifests/fencing_primitives.pp delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/metadata.json delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/spec/classes/fencing_primitives_spec.rb delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/spec/defines/fencing_spec.rb delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/spec/fixtures/cib/cib.xml delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/spec/fixtures/cib/cib_no_topo.xml delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/spec/spec_helper.rb delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/spec/unit/puppet/provider/cs_fencetopo/crm_spec.rb delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/spec/unit/puppet/type/cs_fencetopo_spec.rb delete mode 100644 deployment_scripts/puppet/modules/pcs_fencing/test/site.pp delete mode 100644 environment_config.yaml delete mode 100644 metadata.yaml delete mode 100644 modules.disable_rspec delete mode 100755 pre_build_hook delete mode 100644 repositories/centos/.gitkeep delete mode 100644 repositories/ubuntu/.gitkeep delete mode 100644 tasks.yaml 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