From a1119eb2d861fc7346f63807c3fac33e1ddd24f6 Mon Sep 17 00:00:00 2001 From: Ghanshyam Mann Date: Sat, 24 Feb 2024 10:47:35 -0800 Subject: [PATCH] Retire Tripleo: remove repo content TripleO project is retiring - https://review.opendev.org/c/openstack/governance/+/905145 this commit remove the content of this project repo Change-Id: I5080dd23acbf6beca58e70e6ae1f1bc3d1843161 --- .gitignore | 62 --- LICENSE | 202 -------- README.md | 144 ------ README.rst | 10 + docs/multi-virtual-undercloud/README.md | 174 ------- .../multi-virtual-undercloud-provisioner.sh | 46 -- .../multi-virtual-undercloud.sh | 115 ----- ...ti-virtual-undercloud_network-topology.png | Bin 229756 -> 0 bytes infrared/README.md | 52 -- infrared/infrared_instance-ha_plugin_main.yml | 128 ----- infrared/templates/ansible_hosts.yml.j2 | 27 -- .../baremetal-undercloud-validate-ha.yml | 148 ------ playbooks/overcloud-instance-ha.yml | 10 - playbooks/overcloud-stonith-config.yml | 7 - playbooks/overcloud-validate-ha.yml | 14 - plugin.spec | 37 -- rally/README.md | 53 -- rally/instance-ha.yml | 99 ---- rally/plugins/instanceha.py | 458 ------------------ rally/templates/instance-ha.yaml.j2 | 81 ---- roles/instance-ha/README.md | 226 --------- roles/instance-ha/defaults/main.yml | 13 - roles/instance-ha/tasks/apply.yml | 386 --------------- roles/instance-ha/tasks/main.yml | 31 -- roles/instance-ha/tasks/pre-checks.yml | 25 - roles/instance-ha/tasks/undo.yml | 168 ------- roles/stonith-config/README.md | 90 ---- roles/stonith-config/defaults/main.yml | 13 - roles/stonith-config/tasks/main.yml | 32 -- .../config-stonith-from-instackenv.py.j2 | 94 ---- .../config-stonith-from-instackenv.py.readme | 60 --- roles/validate-ha/README.md | 119 ----- roles/validate-ha/defaults/main.yml | 25 - roles/validate-ha/tasks/ha-test-suite.yml | 26 - .../tasks/heat-validation-check.yml | 7 - .../tasks/heat-validation-create.yml | 30 -- .../tasks/heat-validation-delete.yml | 16 - roles/validate-ha/tasks/main.yml | 147 ------ roles/validate-ha/tasks/manage-latency.yml | 12 - .../validate-ha-heat-environment.yaml.j2 | 13 - .../validate-ha-heat-template.yaml.j2 | 192 -------- roles/validate-ha/vars/test_list_liberty.yml | 7 - roles/validate-ha/vars/test_list_master.yml | 1 - roles/validate-ha/vars/test_list_mitaka.yml | 7 - roles/validate-ha/vars/test_list_newton.yml | 7 - roles/validate-ha/vars/test_list_ocata.yml | 7 - roles/validate-ha/vars/test_list_pike.yml | 7 - roles/validate-ha/vars/test_list_queens.yml | 7 - roles/validate-ha/vars/test_list_rhos-10.yml | 1 - roles/validate-ha/vars/test_list_rhos-11.yml | 1 - roles/validate-ha/vars/test_list_rhos-12.yml | 1 - roles/validate-ha/vars/test_list_rhos-13.yml | 1 - roles/validate-ha/vars/test_list_rhos-8.yml | 1 - roles/validate-ha/vars/test_list_rhos-9.yml | 1 - roles/validate-ha/vars/test_list_rocky.yml | 7 - setup.cfg | 38 -- setup.py | 20 - tools/ha-test-suite/README.md | 145 ------ tools/ha-test-suite/ha-test-suite.sh | 80 --- tools/ha-test-suite/include/functions | 151 ------ .../recovery/recovery_entire-cluster | 13 - .../recovery_keystone-constraint-removal | 7 - .../recovery/recovery_keystone-stop | 10 - .../recovery/recovery_master-slave | 7 - tools/ha-test-suite/recovery/recovery_mongo | 7 - .../recovery/recovery_pacemaker-light | 13 - .../recovery_processes-after-cluster-stop | 10 - .../test/test_check-failed-actions | 3 - .../test/test_keystone-constraint-removal | 40 -- tools/ha-test-suite/test/test_keystone-stop | 7 - tools/ha-test-suite/test/test_master-slave | 7 - .../test/test_mongo-with-aodh-ceilometer | 43 -- .../ha-test-suite/test/test_pacemaker-light-a | 19 - .../ha-test-suite/test/test_pacemaker-light-b | 19 - .../ha-test-suite/test/test_pacemaker-light-c | 22 - .../test/test_processes-after-cluster-stop | 10 - 76 files changed, 10 insertions(+), 4309 deletions(-) delete mode 100644 .gitignore delete mode 100644 LICENSE delete mode 100644 README.md create mode 100644 README.rst delete mode 100644 docs/multi-virtual-undercloud/README.md delete mode 100755 docs/multi-virtual-undercloud/multi-virtual-undercloud-provisioner.sh delete mode 100755 docs/multi-virtual-undercloud/multi-virtual-undercloud.sh delete mode 100644 docs/multi-virtual-undercloud/multi-virtual-undercloud_network-topology.png delete mode 100644 infrared/README.md delete mode 100644 infrared/infrared_instance-ha_plugin_main.yml delete mode 100644 infrared/templates/ansible_hosts.yml.j2 delete mode 100644 playbooks/baremetal-undercloud-validate-ha.yml delete mode 100644 playbooks/overcloud-instance-ha.yml delete mode 100644 playbooks/overcloud-stonith-config.yml delete mode 100644 playbooks/overcloud-validate-ha.yml delete mode 100644 plugin.spec delete mode 100644 rally/README.md delete mode 100644 rally/instance-ha.yml delete mode 100644 rally/plugins/instanceha.py delete mode 100644 rally/templates/instance-ha.yaml.j2 delete mode 100644 roles/instance-ha/README.md delete mode 100644 roles/instance-ha/defaults/main.yml delete mode 100644 roles/instance-ha/tasks/apply.yml delete mode 100644 roles/instance-ha/tasks/main.yml delete mode 100644 roles/instance-ha/tasks/pre-checks.yml delete mode 100644 roles/instance-ha/tasks/undo.yml delete mode 100644 roles/stonith-config/README.md delete mode 100644 roles/stonith-config/defaults/main.yml delete mode 100644 roles/stonith-config/tasks/main.yml delete mode 100644 roles/stonith-config/templates/config-stonith-from-instackenv.py.j2 delete mode 100644 roles/stonith-config/templates/config-stonith-from-instackenv.py.readme delete mode 100644 roles/validate-ha/README.md delete mode 100644 roles/validate-ha/defaults/main.yml delete mode 100644 roles/validate-ha/tasks/ha-test-suite.yml delete mode 100644 roles/validate-ha/tasks/heat-validation-check.yml delete mode 100644 roles/validate-ha/tasks/heat-validation-create.yml delete mode 100644 roles/validate-ha/tasks/heat-validation-delete.yml delete mode 100644 roles/validate-ha/tasks/main.yml delete mode 100644 roles/validate-ha/tasks/manage-latency.yml delete mode 100644 roles/validate-ha/templates/validate-ha-heat-environment.yaml.j2 delete mode 100644 roles/validate-ha/templates/validate-ha-heat-template.yaml.j2 delete mode 100644 roles/validate-ha/vars/test_list_liberty.yml delete mode 120000 roles/validate-ha/vars/test_list_master.yml delete mode 100644 roles/validate-ha/vars/test_list_mitaka.yml delete mode 100644 roles/validate-ha/vars/test_list_newton.yml delete mode 100644 roles/validate-ha/vars/test_list_ocata.yml delete mode 100644 roles/validate-ha/vars/test_list_pike.yml delete mode 100644 roles/validate-ha/vars/test_list_queens.yml delete mode 120000 roles/validate-ha/vars/test_list_rhos-10.yml delete mode 120000 roles/validate-ha/vars/test_list_rhos-11.yml delete mode 120000 roles/validate-ha/vars/test_list_rhos-12.yml delete mode 120000 roles/validate-ha/vars/test_list_rhos-13.yml delete mode 120000 roles/validate-ha/vars/test_list_rhos-8.yml delete mode 120000 roles/validate-ha/vars/test_list_rhos-9.yml delete mode 100644 roles/validate-ha/vars/test_list_rocky.yml delete mode 100644 setup.cfg delete mode 100644 setup.py delete mode 100644 tools/ha-test-suite/README.md delete mode 100755 tools/ha-test-suite/ha-test-suite.sh delete mode 100755 tools/ha-test-suite/include/functions delete mode 100644 tools/ha-test-suite/recovery/recovery_entire-cluster delete mode 100644 tools/ha-test-suite/recovery/recovery_keystone-constraint-removal delete mode 100644 tools/ha-test-suite/recovery/recovery_keystone-stop delete mode 100644 tools/ha-test-suite/recovery/recovery_master-slave delete mode 100644 tools/ha-test-suite/recovery/recovery_mongo delete mode 100644 tools/ha-test-suite/recovery/recovery_pacemaker-light delete mode 100644 tools/ha-test-suite/recovery/recovery_processes-after-cluster-stop delete mode 100644 tools/ha-test-suite/test/test_check-failed-actions delete mode 100644 tools/ha-test-suite/test/test_keystone-constraint-removal delete mode 100644 tools/ha-test-suite/test/test_keystone-stop delete mode 100644 tools/ha-test-suite/test/test_master-slave delete mode 100644 tools/ha-test-suite/test/test_mongo-with-aodh-ceilometer delete mode 100644 tools/ha-test-suite/test/test_pacemaker-light-a delete mode 100644 tools/ha-test-suite/test/test_pacemaker-light-b delete mode 100644 tools/ha-test-suite/test/test_pacemaker-light-c delete mode 100644 tools/ha-test-suite/test/test_processes-after-cluster-stop diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 792181d..0000000 --- a/.gitignore +++ /dev/null @@ -1,62 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] - -# C extensions -*.so - -# Distribution / packaging -.Python -env/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -sdist/ -var/ -*.egg-info/ -.installed.cfg -*.egg - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*,cover - -# Translations -*.mo -*.pot - -# Django stuff: -*.log - -# Sphinx documentation -doc/build/ - -# PyBuilder -target/ - -# virtualenv -.venv/ - -# Files created by releasenotes build -releasenotes/build - diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 8f71f43..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 4cc51f1..0000000 --- a/README.md +++ /dev/null @@ -1,144 +0,0 @@ -Utility roles and docs for TripleO -================================== - -These Ansible roles are a set of useful tools to be used on top of TripleO -deployments. They can also be used together with -[tripleo-quickstart](https://github.com/openstack/tripleo-quickstart) (and -[tripleo-quickstart-extras](https://github.com/openstack/tripleo-quickstart-extras)). - -The documentation of each role is located in the individual role folders. -General usage information about *tripleo-quickstart* can be found in the -[project documentation](https://docs.openstack.org/tripleo-quickstart/latest/). - -Using the playbook on an existing TripleO environment ------------------------------------------------------ - -The playbooks can be launched directly from the **undercloud** machine of the -**TripleO** deployment. The described steps are expected to be run inside the -*/home/stack* directory. - -First of all a clone of the *tripleo-ha-utils* repository must be -created: - - git clone https://github.com/openstack/tripleo-ha-utils - -then three environment variables needs to be exported, pointing three files: - - export ANSIBLE_CONFIG="/home/stack/ansible.cfg" - export ANSIBLE_INVENTORY="/home/stack/hosts" - export ANSIBLE_SSH_ARGS="-F /home/stack/ssh.config.ansible" - -These files are: - -**ansible.cfg** which must contain at least these lines: - - [defaults] - roles_path = /home/stack/tripleo-ha-utils/roles - -**hosts** which must be configured depending on the deployed environment, -reflecting these sections: - - undercloud ansible_host=undercloud ansible_user=stack ansible_private_key_file=/home/stack/.ssh/id_rsa - overcloud-compute-1 ansible_host=overcloud-compute-1 ansible_user=heat-admin ansible_private_key_file=/home/stack/.ssh/id_rsa - overcloud-compute-0 ansible_host=overcloud-compute-0 ansible_user=heat-admin ansible_private_key_file=/home/stack/.ssh/id_rsa - overcloud-controller-2 ansible_host=overcloud-controller-2 ansible_user=heat-admin ansible_private_key_file=/home/stack/.ssh/id_rsa - overcloud-controller-1 ansible_host=overcloud-controller-1 ansible_user=heat-admin ansible_private_key_file=/home/stack/.ssh/id_rsa - overcloud-controller-0 ansible_host=overcloud-controller-0 ansible_user=heat-admin ansible_private_key_file=/home/stack/.ssh/id_rsa - - [compute] - overcloud-compute-1 - overcloud-compute-0 - - [undercloud] - undercloud - - [overcloud] - overcloud-compute-1 - overcloud-compute-0 - overcloud-controller-2 - overcloud-controller-1 - overcloud-controller-0 - - [controller] - overcloud-controller-2 - overcloud-controller-1 - overcloud-controller-0 - -**ssh.config.ansible** which can be generated by these code lines: - - cat /home/stack/.ssh/id_rsa.pub >> /home/stack/.ssh/authorized_keys - echo -e "Host undercloud\n Hostname 127.0.0.1\n IdentityFile /home/stack/.ssh/id_rsa\n User stack\n StrictHostKeyChecking no\n UserKnownHostsFile=/dev/null\n" > ssh.config.ansible - . /home/stack/stackrc - openstack server list -c Name -c Networks | awk '/ctlplane/ {print $2, $4}' | sed s/ctlplane=//g | while read node; do node_name=$(echo $node | cut -f 1 -d " "); node_ip=$(echo $node | cut -f 2 -d " "); echo -e "Host $node_name\n Hostname $node_ip\n IdentityFile /home/stack/.ssh/id_rsa\n User heat-admin\n StrictHostKeyChecking no\n UserKnownHostsFile=/dev/null\n"; done >> ssh.config.ansible - - -It can *optionally* contain specific per-host connection options, like these: - - ... - ... - Host overcloud-controller-0 - ProxyCommand ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ConnectTimeout=60 -F /home/stack/ssh.config.ansible undercloud -W 192.168.24.16:22 - IdentityFile /home/stack/.ssh/id_rsa - User heat-admin - StrictHostKeyChecking no - UserKnownHostsFile=/dev/null - ... - ... - -In this example to connect to overcloud-controller-0 ansible will use -*undercloud* as a *ProxyHost*. - -With this setup in place is then possible to launch the playbook: - - ansible-playbook /home/stack/tripleo-ha-utils/playbooks/overcloud-instance-ha.yml -e release=newton - -Using the playbooks on tripleo-quickstart provided environment --------------------------------------------------------------- - -*tripleo-ha-utils* project can be set as a *tripleo-quickstart* -extra requirement, so all the code will be automatically downloaded and -available. -Inside the requirements.txt file you will need a line pointing to this repo: - - echo "https://github.com/openstack/tripleo-ha-utils/#egg=tripleo-ha-utils" >> tripleo-quickstart/quickstart-extras-requirements.txt - -Supposing the environment was successfully provided with a previous quickstart -execution, to use one of the utils playbook a command line like this one can be -used: - - ./quickstart.sh \ - --retain-inventory \ - --teardown none \ - --playbook overcloud-instance-ha.yml \ - --working-dir /path/to/workdir \ - --config /path/to/config.yml \ - --release \ - --tags all \ - - -Basically this command: - -- **Keep** existing data on the repo (by keeping the inventory and all the - virtual machines) -- Uses the *overcloud-instance-ha.yml* playbook -- Uses the same workdir where quickstart was first deployed -- Select the specific config file (optionally) -- Specifies the release (mitaka, newton, or “master” for ocata) -- Performs all the tasks in the playbook overcloud-instance-ha.yml - -**Important note** - -You might need to export *ANSIBLE_SSH_ARGS* with the path of the -*ssh.config.ansible* file to make the command work, like this: - - export ANSIBLE_SSH_ARGS="-F /path/to/quickstart/workdir/ssh.config.ansible" - -License -------- - -Licensed under the Apache License, Version 2.0. You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0]() - -Author Information ------------------- - -Raoul Scarazzini diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..4ee2c5f --- /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 +OFTC. diff --git a/docs/multi-virtual-undercloud/README.md b/docs/multi-virtual-undercloud/README.md deleted file mode 100644 index be6e1c7..0000000 --- a/docs/multi-virtual-undercloud/README.md +++ /dev/null @@ -1,174 +0,0 @@ -Multi Virtual Undercloud -======================== - -This document describes a way to deploy multiple virtual undercloud on the same -host. This is mainly for environments in which you want to manage multiple -baremetal overclouds without having one baremetal machine dedicated for each one -you deploy. - -Requirements ------------- - -**Physical switches** - -The switch(es) must support VLAN tagging and all the ports must be configured in -trunk, so that the dedicated network interface on the physical host (in the -examples the secondary interface, eth1) is able to offer PXE and dhcp to all the -overcloud machines via undercloud virtual machine's bridged interface. - -**Host hardware** - -The main requirement to make this kind of setup working is to have a host -powerful enough to run virtual machines with at least 16GB of RAM and 8 cpus. -The more power you have, the more undercloud machines you can spawn without -having impact on performances. - -**Host Network topology** - -Host is reachable via ssh from the machine launching quickstart and configured -with two main network interfaces: - -- **eth0**: bridged on **br0**, pointing to LAN (underclouds will own an IP to - be reachable via ssh); -- **eth1**: connected to the dedicated switch that supports all the VLANs that - will be used in the deployment; - -Over eth1, for each undercloud virtual machine two VLAN interfaces are created, -with associated bridges: - -- **Control plane network bridge** (i.e. br2100) built over VLAN interface (i.e. - eth1.2100) that will be eth1 on the undercloud virtual machine, used by - TripleO as br-ctlplane; -- **External network bridge** (i.e. br2105) built over VLAN interface (i.e. - eth1.2105) that will be eth2 on the undercloud virtual machine, used by - TripleO as external network device; - -![network-topology](./multi-virtual-undercloud_network-topology.png "Multi Virtual Undercloud - Network Topology") - -Quickstart configuration ------------------------- - -Virtual undercloud machine is treated as a baremetal one and the Quickstart -command relies on the baremetal undercloud role, and its playbook. -This means that any playbook similar to [baremetal-undercloud.yml](https://github.com/openstack/tripleo-quickstart-extras/blob/master/playbooks/baremetal-undercloud.yml "Baremetal undercloud playbook") should be okay. - -The configuration file has two specific sections that needs attention: - -- Additional interface for external network to route overcloud traffic: - - ```yaml - undercloud_networks: - external: - address: 172.20.0.254 - netmask: 255.255.255.0 - device_type: ethernet - device_name: eth2 - ``` - - **NOTE:** in this configuration eth2 is acting also as a default router for - the external network. - -- Baremetal provision script, which will be an helper for the - [multi-virtual-undercloud.sh](./multi-virtual-undercloud.sh) script on the : - - ```yaml - baremetal_provisioning_script: "/path/to/multi-virtual-undercloud-provisioner.sh " - ``` - - The supported parameters, with the exception of VIRTHOST, are the same ones - that are passed to the script that lives (and runs) on the VIRTHOST, - *multi-virtual-undercloud.sh*. - This helper script launches the remote command on VIRTHOST host and ensures - that the machine gets reachable via ssh before proceeding. - -The multi virtual undercloud script ------------------------------------ - -The [multi-virtual-undercloud.sh](./multi-virtual-undercloud.sh) script is -placed on the VIRTHOST and needs these parameters: - -1. **DISTRO**: this must be the name (without extension) of one of the images - present inside the */images* dir on the VIRTHOST; -2. **VMNAME**: the name of the undercloud virtual machine (the name that will be - used by libvirt); -3. **VMETH0IP**: IP of the virtual undercloud primary interface to wich - quickstart (and users) will connect via ssh; -4. **VMETH0NM**: Netmask of the virtual undercloud primary interface; -5. **VMETH0GW**: Gateway of the virtual undercloud primary interface; -6. **VMSSHKEY**: Public key to be enabled on the virtual undercloud; -7. **UCVLAN**: VLAN of the overcloud's ctlplane network; -8. **UCEXTVLAN**: VLAN of the overcloud's external network; - -The script's actions are basically: - -1. Destroy and undefine any existing machine named as the one we want to create; -2. Prepare the image on which the virtual undercloud will be created by copying - the available distro image and preparing it to be ready for the TripleO - installation, it fix size, network interfaces, packages and ssh keys; -3. Create and launch the virtual undercloud machine; - -**Note**: on the VIRTHOST there must exist an */images* directory containing -images suitable for the deploy. -Having this directory structure: - -```console -[root@VIRTHOST ~]# ls -l /images/ -total 1898320 -lrwxrwxrwx. 1 root root 34 14 feb 09.20 centos-7.qcow2 -> CentOS-7-x86_64-GenericCloud.qcow2 --rw-r--r--. 1 root root 1361182720 15 feb 10.57 CentOS-7-x86_64-GenericCloud.qcow2 -lrwxrwxrwx. 1 root root 36 14 feb 09.20 rhel-7.qcow2 -> rhel-guest-image-7.3-33.x86_64.qcow2 --rw-r--r--. 1 root root 582695936 19 ott 18.44 rhel-guest-image-7.3-33.x86_64.qcow2 -``` - -Helps on updating the images, since one can leave config files pointing to -*centos-7* and, in case of updates, make the symlink point a newer image. - -Quickstart command ------------------- - -A typical invocation of the TripleO Quickstart command is something similar to -this: - -```console -/path/to/tripleo-quickstart/quickstart.sh \ - --bootstrap \ - --ansible-debug \ - --no-clone \ - --playbook baremetal-undercloud.yml \ - --working-dir /path/to/workdir \ - --config /path/to/config.yml \ - --release $RELEASE \ - --tags "all" \ - $VIRTHOST -``` - -So nothing different from a normal quickstart deploy command line, the -difference here is made by the config.yml as described above, with its provision -script. - -Conclusions ------------ - -This approach can be considered useful in testing multi environments with -TripleO for three reasons: - -* It is *fast*: it takes the same time to install the undercloud but less to - provide it, since you don’t have to wait the physical undercloud provision; -* It is *isolated*: using VLANs to separate the traffic keeps each environment - completely isolated from the others; -* It is *reliable*: you can have the undercloud on a shared storage and think - about putting the undercloud vm in HA, live migrating it with libvirt, - pacemaker, whatever... - -There are no macroscopic cons, except for the initial configuration on the -VIRTHOST, that is made only one time, at the beginning. - -License -------- - -GPL - -Author Information ------------------- - -Raoul Scarazzini diff --git a/docs/multi-virtual-undercloud/multi-virtual-undercloud-provisioner.sh b/docs/multi-virtual-undercloud/multi-virtual-undercloud-provisioner.sh deleted file mode 100755 index 638feea..0000000 --- a/docs/multi-virtual-undercloud/multi-virtual-undercloud-provisioner.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash - -set -eux - -VIRTHOST=$1 -DISTRO=$2 -VMNAME=$3 -VMETH0IP=$4 -VMETH0NM=$5 -VMETH0GW=$6 -VMSSHKEY=$7 -UCVLAN=$8 -UCEXTVLAN=$9 - -function wait_machine_status { - UNDERCLOUD=$1 - STATUS=$2 - while true - do - nc $UNDERCLOUD 22 < /dev/null &> /dev/null - NCSTATUS=$? - if [ "$STATUS" == "up" ] - then - [ $NCSTATUS -eq 0 ] && break || (sleep 5; echo -n ".") - else - [ $NCSTATUS -ne 0 ] && break || (sleep 5; echo -n ".") - fi - done -} - -# Copying public key on VIRTHOST -echo -n "$(date) - Copying $VMSSHKEY on $VIRTHOST: " -scp $VMSSHKEY root@$VIRTHOST:$VMNAME\_key.pub -echo "Done." - -# Providing the machine -echo -n "$(date) - Starting provision of $VMNAME ($VMETH0IP) on $VIRTHOST: " -ssh root@$VIRTHOST /root/multi-virtual-undercloud.sh $DISTRO $VMNAME $VMETH0IP $VMETH0NM $VMETH0GW $VMNAME\_key.pub $UCVLAN $UCEXTVLAN -echo "Done." - -set +e - -# Wait for machine to come up -echo -n "$(date) - Waiting for $VMNAME to come up again after update: " -wait_machine_status $VMETH0IP "up" -echo "Done." diff --git a/docs/multi-virtual-undercloud/multi-virtual-undercloud.sh b/docs/multi-virtual-undercloud/multi-virtual-undercloud.sh deleted file mode 100755 index c141287..0000000 --- a/docs/multi-virtual-undercloud/multi-virtual-undercloud.sh +++ /dev/null @@ -1,115 +0,0 @@ -#!/bin/bash - -set -eux - -DISTRO=$1 -CLONEFROM=/images/$DISTRO\.qcow2 -VMNAME=$2 -VMIMG=/vms/$VMNAME\.qcow2 -VMIMGCOPY=/vms/ORIG-$VMNAME\.qcow2 -VMETH0IP=$3 -VMETH0NM=$4 -VMETH0GW=$5 -VMSSHKEY=$6 -VMDISKADD=50G -UCVLAN=$7 -UCEXTVLAN=$8 -WORKDIR=/tmp/virt-undercloud-$(date +%s) - -mkdir -p $WORKDIR -pushd $WORKDIR - -# Destroy the machine if it is running -ISRUNNING=$(virsh list | grep $VMNAME || true) -[ "x$ISRUNNING" != "x" ] && virsh destroy $VMNAME - -# Undefine the vm if it is defined -ISDEFINED=$(virsh list --all | grep $VMNAME || true) -[ "x$ISDEFINED" != "x" ] && virsh undefine $VMNAME - -# Copy qcow2 base image -cp -v $CLONEFROM $VMIMG - -echo "$(date) - Adding $VMDISKADD to $VMIMG: " -qemu-img resize $VMIMG +$VMDISKADD - -echo "$(date) - Resizing filesystem of $VMIMG: " -cp -v $VMIMG $VMIMGCOPY -virt-resize --expand /dev/sda1 $VMIMGCOPY $VMIMG -rm -fv $VMIMGCOPY - -echo "$(date) - Checking status of $VMIMG: " -qemu-img info $VMIMG -virt-filesystems --long -h --all -a $VMIMG - -cat > ifcfg-eth0 < ifcfg-eth1 <> ./authorized_keys - -case "$DISTRO" in -"centos-7") virt-customize -a $VMIMG \ - --root-password password:redhat \ - --install openssh-server \ - --run-command "xfs_growfs /" \ - --run-command "echo 'GRUB_CMDLINE_LINUX=\"console=tty0 crashkernel=auto no_timer_check net.ifnames=0 console=ttyS0,115200n8\"' >> /etc/default/grub" \ - --run-command "grubby --update-kernel=ALL --args=net.ifnames=0" \ - --run-command "systemctl enable sshd" \ - --mkdir /root/.ssh \ - --copy-in ifcfg-eth0:/etc/sysconfig/network-scripts/ \ - --copy-in ifcfg-eth1:/etc/sysconfig/network-scripts/ \ - --copy-in ./authorized_keys:/root/.ssh/ \ - --selinux-relabel - ;; -"rhel-7") virt-customize -a $VMIMG \ - --root-password password:redhat \ - --run-command "curl -o rhos-release-latest.noarch.rpm http://rhos-release.virt.bos.redhat.com/repos/rhos-release/rhos-release-latest.noarch.rpm" \ - --run-command "rpm -Uvh rhos-release-latest.noarch.rpm" \ - --run-command "rhos-release rhel-7.3" \ - --install openssh-server \ - --run-command "systemctl enable sshd" \ - --run-command "rpm -e rhos-release" \ - --run-command "sed -i -e '/\[rhelosp-rhel-7.3-server-opt\]/,/^\[/s/enabled=0/enabled=1/' /etc/yum.repos.d/rhos-release-rhel-7.3.repo" \ - --mkdir /root/.ssh \ - --copy-in ifcfg-eth0:/etc/sysconfig/network-scripts/ \ - --copy-in ifcfg-eth1:/etc/sysconfig/network-scripts/ \ - --copy-in ./authorized_keys:/root/.ssh/ \ - --selinux-relabel - ;; -esac - -# Deploy the vm -virt-install \ - --import \ - --name $VMNAME \ - --ram 16192 \ - --disk path=$VMIMG \ - --vcpus 8 \ - --os-type linux \ - --os-variant generic \ - --network bridge=br0 \ - --network bridge=br$UCVLAN \ - --network bridge=br$UCEXTVLAN \ - --graphics none \ - --noautoconsole - -rm -rf $WORKDIR -popd diff --git a/docs/multi-virtual-undercloud/multi-virtual-undercloud_network-topology.png b/docs/multi-virtual-undercloud/multi-virtual-undercloud_network-topology.png deleted file mode 100644 index d8d5049e28cbd9cc166c58edc24b4505afc47c8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 229756 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%0AT&L4fF#`$ELf~3N~uldVUrD5#bpWi7!mNmd2;~O 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 ssh.config.ansible - openstack server list -c Name -c Networks | awk '/ctlplane/ {print $2, $4}' | sed s/ctlplane=//g | while read node; do node_name=$(echo $node | cut -f 1 -d " "); node_ip=$(echo $node | cut -f 2 -d " "); echo -e "Host $node_name\n Hostname $node_ip\n IdentityFile /home/stack/.ssh/id_rsa\n User heat-admin\n StrictHostKeyChecking no\n UserKnownHostsFile=/dev/null\n"; done >> ssh.config.ansible - - - name: get tripleo-ha-utils repo - git: - repo: 'https://github.com/openstack/tripleo-ha-utils.git' - dest: /home/stack/tripleo-ha-utils - - - name: create ansible env file - shell: | - cat >/home/stack/ansible_ha.env< /home/stack/ansible.cfg - - - name: run instance-ha deploy script - shell: | - source /home/stack/ansible_ha.env - ansible-playbook -v /home/stack/tripleo-ha-utils/playbooks/overcloud-instance-ha.yml -e release={{release}} -e stonith_devices={{stonith_devices}} -e instance_ha_shared_storage={{instance_ha_shared_storage}} -e instance_ha_action={{instance_ha_action}} - register: instance_ha_deploy_outcome - - vars: - instance_ha_action: '{{ install.instance_ha_action }}' - release: '{{ install.release }}' - stonith_devices: '{{ install.stonith_devices }}' - instance_ha_shared_storage: '{{ install.instance_ha_shared_storage }}' diff --git a/infrared/templates/ansible_hosts.yml.j2 b/infrared/templates/ansible_hosts.yml.j2 deleted file mode 100644 index e333cfe..0000000 --- a/infrared/templates/ansible_hosts.yml.j2 +++ /dev/null @@ -1,27 +0,0 @@ -undercloud ansible_host=undercloud ansible_user=stack ansible_private_key_file=/home/stack/.ssh/id_rsa - -{% for overcloud_host in groups['overcloud_nodes'] %} -{{overcloud_host}} ansible_host={{overcloud_host}} ansible_user=heat-admin ansible_private_key_file=/home/stack/.ssh/id_rsa -{% endfor %} - -{% for overcloud_host in groups['overcloud_nodes'] %} -{{overcloud_host}} ansible_host={{overcloud_host}} ansible_user=heat-admin ansible_private_key_file=/home/stack/.ssh/id_rsa -{% endfor %} - -[compute] -{% for overcloud_host in groups['compute'] %} -{{overcloud_host}} -{% endfor %} - -[undercloud] -undercloud - -[overcloud] -{% for overcloud_host in groups['overcloud_nodes'] %} -{{overcloud_host}} -{% endfor %} - -[controller] -{% for overcloud_host in groups['controller'] %} -{{overcloud_host}} -{% endfor %} \ No newline at end of file diff --git a/playbooks/baremetal-undercloud-validate-ha.yml b/playbooks/baremetal-undercloud-validate-ha.yml deleted file mode 100644 index e97f274..0000000 --- a/playbooks/baremetal-undercloud-validate-ha.yml +++ /dev/null @@ -1,148 +0,0 @@ ---- -- name: Baremetal undercloud install - hosts: localhost - roles: - - baremetal-undercloud - tags: - - baremetal-undercloud - -- name: Add the undercloud node to the generated inventory - hosts: localhost - gather_facts: yes - roles: - - tripleo-inventory - tags: - - undercloud-inventory - -- name: Setup repositories - hosts: undercloud - gather_facts: yes - roles: - - repo-setup - tags: - - undercloud-repo-setup - -- name: Install packages - hosts: undercloud - gather_facts: no - roles: - - baremetal-undercloud/packages - tags: - - undercloud-pkgs-install - -- name: Deploy the undercloud - hosts: undercloud - gather_facts: no - roles: - - undercloud-deploy - tags: - - undercloud-deploy - -- name: Prepare baremetal for the overcloud deployment - hosts: undercloud - roles: - - baremetal-prep-overcloud - tags: - - baremetal-prep-overcloud - -- name: Prepare configuration files for the overcloud deployment - hosts: undercloud - gather_facts: no - roles: - - overcloud-prep-config - tags: - - overcloud-prep-config - -- name: Prepare overcloud containers - hosts: undercloud - gather_facts: no - roles: - - overcloud-prep-containers - tags: - - overcloud-prep-containers - -- name: Fetch the overcloud images - hosts: undercloud - gather_facts: no - become: true - roles: - - fetch-images - tags: - - overcloud-fetch-images - -- name: Prepare the overcloud images for deployment - hosts: undercloud - gather_facts: no - roles: - - overcloud-prep-images - tags: - - overcloud-prep-images - -- name: Prepare overcloud flavors - hosts: undercloud - gather_facts: no - roles: - - overcloud-prep-flavors - tags: - - overcloud-prep-flavors - -- name: Prepare the undercloud networks for the overcloud deployment - hosts: undercloud - gather_facts: no - roles: - - overcloud-prep-network - tags: - - overcloud-prep-network - -- name: Prepare SSL for the overcloud - hosts: undercloud - gather_facts: yes - roles: - - overcloud-ssl - tags: - - overcloud-ssl - -- name: Deploy the overcloud - hosts: undercloud - gather_facts: yes - roles: - - overcloud-deploy - tags: - - overcloud-deploy - -- name: Add the overcloud nodes to the generated inventory - hosts: undercloud - gather_facts: yes - vars: - inventory: all - roles: - - tripleo-inventory - tags: - - overcloud-inventory - -- name: Check the result of the deployment - hosts: localhost - tasks: - - name: ensure the deployment result has been read into memory - include_vars: "{{ local_working_dir }}/overcloud_deployment_result.json" - - # overcloud_deploy_result = ["failed", "passed"] - - name: did the deployment pass or fail? - debug: var=overcloud_deploy_result - failed_when: overcloud_deploy_result == "failed" - tags: - - overcloud-deploy-check - -- name: Gather undercloud and overcloud facts - hosts: undercloud overcloud - gather_facts: yes - tags: - - overcloud-validate-ha - -- name: Validate the overcloud using HA tests - hosts: undercloud - gather_facts: no - roles: - - validate-ha - tags: - - overcloud-validate-ha diff --git a/playbooks/overcloud-instance-ha.yml b/playbooks/overcloud-instance-ha.yml deleted file mode 100644 index fe94439..0000000 --- a/playbooks/overcloud-instance-ha.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -- name: Gather undercloud and overcloud facts - hosts: undercloud overcloud - gather_facts: yes - -- name: Configure Instance HA - hosts: undercloud - gather_facts: no - roles: - - instance-ha diff --git a/playbooks/overcloud-stonith-config.yml b/playbooks/overcloud-stonith-config.yml deleted file mode 100644 index 367f168..0000000 --- a/playbooks/overcloud-stonith-config.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- - -- name: Configure STONITH for all the hosts on the overcloud - hosts: undercloud - gather_facts: yes - roles: - - stonith-config diff --git a/playbooks/overcloud-validate-ha.yml b/playbooks/overcloud-validate-ha.yml deleted file mode 100644 index 57c0d5f..0000000 --- a/playbooks/overcloud-validate-ha.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- -- name: Gather undercloud and overcloud facts - hosts: undercloud overcloud - gather_facts: yes - tags: - - overcloud-validate-ha - -- name: Validate overcloud HA status - hosts: undercloud - gather_facts: yes - tags: - - overcloud-validate-ha - roles: - - validate-ha diff --git a/plugin.spec b/plugin.spec deleted file mode 100644 index 4876089..0000000 --- a/plugin.spec +++ /dev/null @@ -1,37 +0,0 @@ ---- -config: - entry_point: ./infrared/infrared_instance-ha_plugin_main.yml - plugin_type: install -subparsers: - instance-ha-deploy: - description: Collection of instance-ha configuration tasks - include_groups: ["Ansible options", "Inventory", "Common options", "Answers file"] - groups: - - - title: Instance HA - options: - instance_ha_action: - type: Value - default: install - help: | - Can be 'install' or 'uninstall' - - release: - type: Value - help: | - A rhos release - version_number. - Example: "rhos-10". - required: yes - stonith_devices: - type: Value - default: controllers - help: | - Can be all, controllers or computes - - instance_ha_shared_storage: - type: Bool - help: | - Do we have a shared storage or not? - default: False - - diff --git a/rally/README.md b/rally/README.md deleted file mode 100644 index 9b2b80f..0000000 --- a/rally/README.md +++ /dev/null @@ -1,53 +0,0 @@ -Rally tests -=========== - -This directory contains all the files available to use Rally for testing the -behavior of the TripleO environment. -For example you can test if instance HA is behaving correctly inside the -overcloud environment in which it was configured. - -Requirements ------------- - -A working and accessible TripleO environment, as described [here](https://github.com/openstack/tripleo-ha-utils/tree/master/README.md). -so an *hosts* file containing the whole environment inventory and, if needed, a -*ssh.config.ansible* with all the information to access nodes. - -How to use Rally to test Instance HA ------------------------------------- - -If you want to launch a Rally test session to check how Instance HA is behaving -into the overcloud you can rely on a command like this one: - - ansible-playbook -i hosts \ - -e public_physical_network="public" \ - -e floating_ip_cidr="192.168.99.0/24" \ - -e public_net_pool_start="192.168.99.211" \ - -e public_net_pool_end="192.168.99.216" \ - -e public_net_gateway="192.168.99.254" \ - tripleo-ha-utils/rally/instance-ha.yml - -this command can be launched from the *undercloud* machine or from a jump host -(which must have all the required file locally). -The requested parameters refers to the network settings in which the instances -will be spawned into. - -This will execute the tests contained in the template yaml: - -* *InstanceHA.recover_instance_fip_and_volume*: spawn an instance, stop the - compute it's running on, check it migrates, check node recovers; -* *InstanceHA.recover_stopped_instance_fip*: spawn an instance, put it in - stopped status, stop the compute it's running on, check it migrates, check - node recovers; -* *InstanceHA.recover_instance_two_cycles*: do as in the first step, but two - times; - -License -------- - -GPL - -Author Information ------------------- - -Raoul Scarazzini diff --git a/rally/instance-ha.yml b/rally/instance-ha.yml deleted file mode 100644 index 4effed9..0000000 --- a/rally/instance-ha.yml +++ /dev/null @@ -1,99 +0,0 @@ ---- -- hosts: undercloud - gather_facts: no - become: yes - become_method: sudo - tasks: - - name: Install Rally dependencies - shell: | - # Python pip - wget https://bootstrap.pypa.io/get-pip.py -O get-pip.py - python get-pip.py - # Depndencies - yum install -y gmp-devel libffi-devel libxml2-devel libxslt-devel openssl-devel postgresql-devel gcc python-devel - -- hosts: undercloud - gather_facts: no - tasks: - - name: Install Rally - shell: | - # Install Rally from upstream - wget -q -O- https://raw.githubusercontent.com/openstack/rally/master/install_rally.sh | bash |& tee rally-install.log - mkdir -p .rally/plugins - - name: Check Rally installation - shell: | - source /home/stack/rally/bin/activate - rally --version - -- hosts: undercloud - gather_facts: no - tasks: - - name: Copy instance-ha Rally plugin to remote rally directory - copy: - src: plugins/instanceha.py - dest: .rally/plugins - -- hosts: undercloud - gather_facts: no - tasks: - - name: Install Rally environment and create deployment - shell: | - source /home/stack/overcloudrc - source /home/stack/rally/bin/activate - export OS_INSECURE=True - rally deployment create --fromenv --name overcloud |& tee rally-instance-ha-deployment-create.log - rally deployment use overcloud - -- hosts: undercloud - gather_facts: no - tasks: - - name: Prepare overcloud env - shell: | - source /home/stack/overcloudrc - - projectid=$(openstack project list | awk '/admin/ {print $2}') - wget -O /tmp/cirros-0.3.4-x86_64-disk.img http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img - glance --os-project-id=$projectid image-create --name cirros --container-format bare --disk-format raw --file /tmp/cirros-0.3.4-x86_64-disk.img --visibility public - - nova flavor-create --ephemeral 0 --is-public True m1.tiny overcloud-instance-test-small-flavor 2048 20 1 - - neutron net-create {{ public_physical_network }}-network --router:external=True --provider:physical_network {{ public_physical_network }} --provider:network_type flat - neutron subnet-create --name {{ public_physical_network }}-subnet --disable-dhcp --allocation-pool start={{ public_net_pool_start }},end={{ public_net_pool_end }} --gateway {{ public_net_gateway }} {{ public_physical_network }}-network {{ floating_ip_cidr }} - -- hosts: undercloud - gather_facts: no - tasks: - - name: Copy Rally task file - template: - src: templates/instance-ha.yaml.j2 - dest: "/home/stack/instance-ha.yaml" - mode: 0666 - - - name: Start Rally task - shell: | - source /home/stack/rally/bin/activate - rally task start --task /home/stack/instance-ha.yaml --deployment overcloud |& tee rally-instance-ha-run.log - - - name: Create Report JUnit - shell: | - source /home/stack/rally/bin/activate - rally task report --junit --out /home/stack/nosetests.xml |& tee rally-instance-ha-report.log - - - fetch: - src: "/home/stack/nosetests.xml" - dest: "{{ lookup('env', 'PWD') }}/nosetests.xml" - flat: yes - -- hosts: undercloud - gather_facts: no - tasks: - - name: Remove overcloud env - shell: | - source /home/stack/overcloudrc - - projectid=$(openstack project list | awk '/admin/ {print $2}') - glance --os-project-id=$projectid image-delete $(glance --os-project-id=$projectid image-list | awk '/cirros/ {print $2}') - - nova flavor-delete overcloud-instance-test-small-flavor - - neutron net-delete {{ public_physical_network }}-network diff --git a/rally/plugins/instanceha.py b/rally/plugins/instanceha.py deleted file mode 100644 index aef9575..0000000 --- a/rally/plugins/instanceha.py +++ /dev/null @@ -1,458 +0,0 @@ -from os import path -import socket -import time - - -from rally.common import logging -from rally.common import sshutils -from rally import exceptions -from rally_openstack import consts -from rally_openstack import scenario -from rally_openstack.scenarios.vm import utils as vm_utils -from rally_openstack.scenarios.cinder import utils as cinder_utils -from rally.task import atomic -from rally.task import types -from rally.task import validation -from rally.task import utils as task_utils -import six - - -LOG = logging.getLogger(__name__) - - -def failover(self, host, command, port=22, username="", password="", - key_filename=None, pkey=None): - """Trigger failover at host - :param host: - :param command: - :return: - """ - if key_filename: - key_filename = path.expanduser(key_filename) - LOG.info("Host: %s. Injecting Failover %s" % (host, - command)) - try: - code, out, err = _run_command(self, server_ip=host, port=port, - username=username, - password=password, - key_filename=key_filename, - pkey=pkey, command=command - ) - if code and code > 0: - raise exceptions.ScriptError( - "Error running command %(command)s. " - "Error %(code)s: %(error)s" % { - "command": command, "code": code, "error": err}) - except exceptions.SSHTimeout: - LOG.debug("SSH session of disruptor command timeouted, continue...") - pass - - -def _run_command(self, server_ip, port, username, password, command, - pkey=None, key_filename=None): - """Run command via SSH on server. - Create SSH connection for server, wait for server to become available - (there is a delay between server being set to ACTIVE and sshd being - available). Then call run_command_over_ssh to actually execute the - command. - Note: Shadows vm.utils.VMScenario._run_command to support key_filename. - :param server_ip: server ip address - :param port: ssh port for SSH connection - :param username: str. ssh username for server - :param password: Password for SSH authentication - :param command: Dictionary specifying command to execute. - See `rally info find VMTasks.boot_runcommand_delete' parameter - `command' docstring for explanation. - :param key_filename: private key filename for SSH authentication - :param pkey: key for SSH authentication - :returns: tuple (exit_status, stdout, stderr) - """ - if not key_filename: - pkey = pkey or self.context["user"]["keypair"]["private"] - ssh = sshutils.SSH(username, server_ip, port=port, - pkey=pkey, password=password, - key_filename=key_filename) - self._wait_for_ssh(ssh) - return _run_command_over_ssh(self, ssh, command) - - -@atomic.action_timer("vm.run_command_over_ssh") -def _run_command_over_ssh(self, ssh, command): - """Run command inside an instance. - This is a separate function so that only script execution is timed. - :param ssh: A SSHClient instance. - :param command: Dictionary specifying command to execute. - See `rally info find VMTasks.boot_runcommand_delete' parameter - `command' docstring for explanation. - :returns: tuple (exit_status, stdout, stderr) - """ - cmd, stdin = [], None - - interpreter = command.get("interpreter") or [] - if interpreter: - if isinstance(interpreter, six.string_types): - interpreter = [interpreter] - elif type(interpreter) != list: - raise ValueError("command 'interpreter' value must be str " - "or list type") - cmd.extend(interpreter) - - remote_path = command.get("remote_path") or [] - if remote_path: - if isinstance(remote_path, six.string_types): - remote_path = [remote_path] - elif type(remote_path) != list: - raise ValueError("command 'remote_path' value must be str " - "or list type") - cmd.extend(remote_path) - if command.get("local_path"): - ssh.put_file(os.path.expanduser( - command["local_path"]), remote_path[-1], - mode=self.USER_RWX_OTHERS_RX_ACCESS_MODE) - - if command.get("script_file"): - stdin = open(os.path.expanduser(command["script_file"]), "rb") - - elif command.get("script_inline"): - stdin = six.moves.StringIO(command["script_inline"]) - - cmd.extend(command.get("command_args") or []) - - return ssh.execute(cmd, stdin=stdin, timeout=10) - - -def one_killing_iteration(self, server, fip, computes, disruptor_cmd, - stop_instance): - """Find the host where instance is hosted, disrupt the host and - verify status of the instance after the failover""" - - server_admin = self.admin_clients("nova").servers.get(server.id) - host_name_pre = getattr(server_admin, "OS-EXT-SRV-ATTR:host") - host_name_ext = host_name_pre.split('.')[0] + ".external" - hypervisors = self.admin_clients("nova").hypervisors.list() - hostnames = [] - for hypervisor in hypervisors: - hostnames.append(getattr(hypervisor, "hypervisor_hostname")) - if getattr(hypervisor, "hypervisor_hostname") == host_name_pre: - hypervisor_id = getattr(hypervisor, "id") - hypervisor = self.admin_clients("nova").hypervisors.get(hypervisor_id) - hypervisor_ip = socket.gethostbyname(host_name_ext.strip()) - - if not disruptor_cmd: - disruptor_cmd = { - "script_inline": "sudo sh -c \"echo b > /proc/sysrq-trigger\"", - "interpreter": "/bin/sh" - } - - # Trigger failover of compute node hosting the instance - failover(self, host=hypervisor_ip, - command=disruptor_cmd, - port=computes.get("port", 22), - username=computes.get("username"), - password=computes.get("password"), - key_filename=computes.get("key_filename"), - pkey=computes.get("pkey") - ) - # Wait for instance to be moved to different host - hostnames.remove(host_name_pre) - task_utils.wait_for( - server_admin, - status_attr="OS-EXT-SRV-ATTR:host", - ready_statuses=hostnames, - update_resource=task_utils.get_from_manager(), - timeout=120, - check_interval=5 - ) - - # Check the instance is SHUTOFF in the case of stopped instance or - # that the instance is pingable - if stop_instance: - task_utils.wait_for( - server, - ready_statuses=["SHUTOFF"], - update_resource=task_utils.get_from_manager(), - timeout=60, - check_interval=2 - ) - #server_admin = self.admin_clients("nova").servers.get(server.id) - #host_name_post = getattr(server_admin, "OS-EXT-SRV-ATTR:host") - #if host_name_post in host_name_pre: - #raise exceptions.InvalidHostException() - else: - try: - if self.wait_for_ping: - self._wait_for_ping(fip["ip"]) - except exceptions.TimeoutException: - console_logs = self._get_server_console_output(server, - None) - LOG.debug("VM console logs:\n%s", console_logs) - raise - - -def recover_instance_ha(self, image, flavor, computes, - volume_args=None, - floating_network=None, - use_floating_ip=True, - force_delete=False, - stop_instance=False, - disruptor_cmd=None, - iterations=1, - wait_for_ping=True, - max_log_length=None, - **kwargs): - """Boot a server, trigger failover of host and verify instance. - - :param image: glance image name to use for the vm - :param flavor: VM flavor name - :param computes: dictionary with credentials to the compute nodes - consisting of username, password, port, key_filename, disruptor - command and pkey. - Examples:: - computes: { - username: heat-admin, - key_filename: /path/to/ssh/id_rsa.pub - port: 22 - } - :param volume_args: volume args for booting server from volume - :param floating_network: external network name, for floating ip - :param use_floating_ip: bool, floating or fixed IP for SSH connection - :param force_delete: whether to use force_delete for servers - :param stop_instance: whether to stop instance before disruptor command - :param disruptor_cmd: command to be send to hosting compute node - :param iterations: number of compute node killing iteration - :param wait_for_ping: whether to check connectivity on server creation - :param **kwargs: extra arguments for booting the server - :param max_log_length: The number of tail nova console-log lines user - would like to retrieve - :returns: - """ - - self.wait_for_ping = wait_for_ping - - if volume_args: - volume = self.cinder.create_volume(volume_args["size"], imageRef=None) - kwargs["block_device_mapping"] = {"vdrally": "%s:::1" % volume.id} - - server, fip = self._boot_server_with_fip( - image, flavor, use_floating_ip=use_floating_ip, - floating_network=floating_network, - key_name=self.context["user"]["keypair"]["name"], - **kwargs) - - task_utils.wait_for( - server, - ready_statuses=["ACTIVE"], - update_resource=task_utils.get_from_manager(), - timeout=120, - check_interval=2 - ) - - try: - if self.wait_for_ping: - self._wait_for_ping(fip["ip"]) - except exceptions.TimeoutException: - console_logs = self._get_server_console_output(server, - max_log_length) - LOG.debug("VM console logs:\n%s", console_logs) - raise - - if stop_instance: - self._stop_server(server) - task_utils.wait_for( - server, - ready_statuses=["SHUTOFF"], - update_resource=task_utils.get_from_manager(), - timeout=120, - check_interval=2 - ) - - # Wait a little before killing the compute - # If we do not wait, backing image will get corrupted which was reported as bug - time.sleep(30) - - for iteration in range(1, iterations+1): - one_killing_iteration(self, server, fip, computes, - disruptor_cmd, stop_instance) - # Give cluster some time to recover original compute node - LOG.info("Wait for compute nodes to come online after previous disruption") - time.sleep(360) - - if stop_instance: - # Start instance If It was stopped. - self._start_server(server) - - task_utils.wait_for( - server, - ready_statuses=["ACTIVE"], - update_resource=task_utils.get_from_manager(), - timeout=120, - check_interval=2 - ) - self._delete_server_with_fip(server, fip, force_delete=force_delete) - - -@types.convert(image={"type": "glance_image"}, - flavor={"type": "nova_flavor"}) -@validation.add("image_valid_on_flavor", - flavor_param="flavor", image_param="image") -@validation.add("valid_command", param_name="command", required=False) -@validation.add("number", param_name="port", minval=1, maxval=65535, - nullable=True, integer_only=True) -@validation.add("external_network_exists", param_name="floating_network") -@validation.add("required_services", - services=[consts.Service.NOVA, consts.Service.CINDER]) -@validation.add("required_platform", platform="openstack", - users=True, admin=True) -@scenario.configure(context={"cleanup@openstack": ["nova", "cinder"], - "keypair@openstack": {}, "allow_ssh@openstack": None}, - name="InstanceHA.recover_instance_fip_and_volume", - platform="openstack") -class InstanceHARecoverFIPAndVolume(vm_utils.VMScenario, cinder_utils.CinderBasic): - - def __init__(self, *args, **kwargs): - super(InstanceHARecoverFIPAndVolume, self).__init__(*args, **kwargs) - - def run(self, image, flavor, computes, - volume_args=None, - floating_network=None, - use_floating_ip=True, - force_delete=False, - wait_for_ping=True, - max_log_length=None, - **kwargs): - - recover_instance_ha(self, image, flavor, computes, - volume_args=volume_args, - floating_network=floating_network, - use_floating_ip=use_floating_ip, - force_delete=force_delete, - wait_for_ping=wait_for_ping, - max_log_length=max_log_length, - **kwargs) - - -@types.convert(image={"type": "glance_image"}, - flavor={"type": "nova_flavor"}) -@validation.add("image_valid_on_flavor", - flavor_param="flavor", image_param="image") -@validation.add("valid_command", param_name="command", required=False) -@validation.add("number", param_name="port", minval=1, maxval=65535, - nullable=True, integer_only=True) -@validation.add("external_network_exists", param_name="floating_network") -@validation.add("required_services", - services=[consts.Service.NOVA, consts.Service.CINDER]) -@validation.add("required_platform", platform="openstack", - users=True, admin=True) -@scenario.configure(context={"cleanup@openstack": ["nova", "cinder"], - "keypair@openstack": {}, "allow_ssh@openstack": None}, - name="InstanceHA.recover_instance_two_cycles", - platform="openstack") -class InstanceHARecoverTwoCycle(vm_utils.VMScenario, cinder_utils.CinderBasic): - - def __init__(self, *args, **kwargs): - super(InstanceHARecoverTwoCycle, self).__init__(*args, **kwargs) - - def run(self, image, flavor, computes, - volume_args=None, - floating_network=None, - use_floating_ip=True, - force_delete=False, - wait_for_ping=True, - max_log_length=None, - **kwargs): - - recover_instance_ha(self, image, flavor, computes, - volume_args=volume_args, - floating_network=floating_network, - use_floating_ip=use_floating_ip, - force_delete=force_delete, - iterations=2, - wait_for_ping=wait_for_ping, - max_log_length=max_log_length, - **kwargs) - - -@types.convert(image={"type": "glance_image"}, - flavor={"type": "nova_flavor"}) -@validation.add("image_valid_on_flavor", - flavor_param="flavor", image_param="image") -@validation.add("valid_command", param_name="command", required=False) -@validation.add("number", param_name="port", minval=1, maxval=65535, - nullable=True, integer_only=True) -@validation.add("external_network_exists", param_name="floating_network") -@validation.add("required_services", - services=[consts.Service.NOVA, consts.Service.CINDER]) -@validation.add("required_platform", platform="openstack", - users=True, admin=True) -@scenario.configure(context={"cleanup@openstack": ["nova", "cinder"], - "keypair@openstack": {}, "allow_ssh@openstack": None}, - name="InstanceHA.recover_stopped_instance_fip", - platform="openstack") -class InstanceHARecoverStopped(vm_utils.VMScenario, cinder_utils.CinderBasic): - - def __init__(self, *args, **kwargs): - super(InstanceHARecoverStopped, self).__init__(*args, **kwargs) - - def run(self, image, flavor, computes, - volume_args=None, - floating_network=None, - use_floating_ip=True, - force_delete=False, - wait_for_ping=True, - max_log_length=None, - **kwargs): - - recover_instance_ha(self, image, flavor, computes, - volume_args=volume_args, - floating_network=floating_network, - use_floating_ip=use_floating_ip, - force_delete=force_delete, - stop_instance=True, - wait_for_ping=wait_for_ping, - max_log_length=max_log_length, - **kwargs) - - -@types.convert(image={"type": "glance_image"}, - flavor={"type": "nova_flavor"}) -@validation.add("image_valid_on_flavor", - flavor_param="flavor", image_param="image") -@validation.add("valid_command", param_name="command", required=False) -@validation.add("number", param_name="port", minval=1, maxval=65535, - nullable=True, integer_only=True) -@validation.add("external_network_exists", param_name="floating_network") -@validation.add("required_services", - services=[consts.Service.NOVA, consts.Service.CINDER]) -@validation.add("required_platform", platform="openstack", - users=True, admin=True) -@scenario.configure(context={"cleanup@openstack": ["nova", "cinder"], - "keypair@openstack": {}, "allow_ssh@openstack": None}, - name="InstanceHA.recover_instance_nova_compute", - platform="openstack") -class InstanceHARecoverNovaCompute(vm_utils.VMScenario, cinder_utils.CinderBasic): - - def __init__(self, *args, **kwargs): - super(InstanceHARecoverNovaCompute, self).__init__(*args, **kwargs) - - def run(self, image, flavor, computes, - volume_args=None, - floating_network=None, - use_floating_ip=True, - force_delete=False, - wait_for_ping=True, - max_log_length=None, - **kwargs): - - disruptor_cmd = { - "script_inline": "sudo kill -9 $(ps -ef | grep ^nova* | awk \'{print$2}\'); echo {}", - "interpreter": "/bin/sh" - } - recover_instance_ha(self, image, flavor, computes, - volume_args=volume_args, - floating_network=floating_network, - use_floating_ip=use_floating_ip, - force_delete=force_delete, - disruptor_cmd=disruptor_cmd, - wait_for_ping=wait_for_ping, - max_log_length=max_log_length, - **kwargs) diff --git a/rally/templates/instance-ha.yaml.j2 b/rally/templates/instance-ha.yaml.j2 deleted file mode 100644 index 79f1c7d..0000000 --- a/rally/templates/instance-ha.yaml.j2 +++ /dev/null @@ -1,81 +0,0 @@ ---- - InstanceHA.recover_instance_fip_and_volume: - - - args: - flavor: - name: "m1.tiny" - image: - name: cirros - volume_args: - size: 1 - floating_network: "{{ public_physical_network }}-network" - force_delete: false - wait_for_ping: false - computes: - username: "heat-admin" - key_filename: "/home/stack/.ssh/id_rsa" - port: 22 - runner: - type: "constant" - times: 1 - concurrency: 1 - context: - users: - tenants: 2 - users_per_tenant: 1 - network: {} - sla: - failure_rate: - max: 0.0 - InstanceHA.recover_stopped_instance_fip: - - - args: - flavor: - name: "m1.tiny" - image: - name: cirros - floating_network: "{{ public_physical_network }}-network" - force_delete: false - wait_for_ping: false - computes: - username: "heat-admin" - key_filename: "/home/stack/.ssh/id_rsa" - port: 22 - runner: - type: "constant" - times: 1 - concurrency: 1 - context: - users: - tenants: 2 - users_per_tenant: 1 - network: {} - sla: - failure_rate: - max: 0.0 - InstanceHA.recover_instance_two_cycles: - - - args: - flavor: - name: "m1.tiny" - image: - name: cirros - floating_network: "{{ public_physical_network }}-network" - force_delete: false - wait_for_ping: false - computes: - username: "heat-admin" - key_filename: "/home/stack/.ssh/id_rsa" - port: 22 - runner: - type: "constant" - times: 1 - concurrency: 1 - context: - users: - tenants: 2 - users_per_tenant: 1 - network: {} - sla: - failure_rate: - max: 0.0 diff --git a/roles/instance-ha/README.md b/roles/instance-ha/README.md deleted file mode 100644 index 2f14882..0000000 --- a/roles/instance-ha/README.md +++ /dev/null @@ -1,226 +0,0 @@ -instance-ha -=========== - -This role aims to automate all the steps needed to configure instance HA on a -deployed TripleO overcloud environment. - -Requirements ------------- - -The TripleO environment must be prepared as described [here](https://github.com/openstack/tripleo-ha-utils/tree/master/README.md). - -**NOTE**: Instance-HA depends on STONITH. This means that all the steps -performed by this role make sense only if on the overcloud STONITH has been -configured. There is a dedicated role that automates the STONITH -configuration, named [stonith-config](https://github.com/openstack/tripleo-ha-utils/tree/master/roles/stonith-config). - -Instance HA ------------ - -Instance HA is a feature that gives a certain degree of high-availability to the -instances spawned by an OpenStack deployment. Namely, if a compute node on which -an instance is running breaks for whatever reason, this configuration will spawn -the instances that were running on the broken node onto a functioning one. -This role automates are all the necessary steps needed to configure Pacemaker -cluster to support this functionality. A typical cluster configuration on a -clean stock **newton** (or **osp10**) deployment is something like this: - - Online: [ overcloud-controller-0 overcloud-controller-1 overcloud-controller-2 ] - - Full list of resources: - - ip-192.168.24.10 (ocf::heartbeat:IPaddr2): Started overcloud-controller-0 - ip-172.18.0.11 (ocf::heartbeat:IPaddr2): Started overcloud-controller-0 - ip-172.20.0.19 (ocf::heartbeat:IPaddr2): Started overcloud-controller-1 - ip-172.17.0.11 (ocf::heartbeat:IPaddr2): Started overcloud-controller-1 - ip-172.19.0.12 (ocf::heartbeat:IPaddr2): Started overcloud-controller-0 - Clone Set: haproxy-clone [haproxy] - Started: [ overcloud-controller-0 overcloud-controller-1 overcloud-controller-2 ] - Master/Slave Set: galera-master [galera] - Masters: [ overcloud-controller-0 overcloud-controller-1 overcloud-controller-2 ] - ip-172.17.0.18 (ocf::heartbeat:IPaddr2): Started overcloud-controller-1 - Clone Set: rabbitmq-clone [rabbitmq] - Started: [ overcloud-controller-0 overcloud-controller-1 overcloud-controller-2 ] - Master/Slave Set: redis-master [redis] - Masters: [ overcloud-controller-0 ] - Slaves: [ overcloud-controller-1 overcloud-controller-2 ] - openstack-cinder-volume (systemd:openstack-cinder-volume): Started overcloud-controller-0 - -As you can see we have 3 controllers, six IP resources, four *core* resources -(*haproxy*, *galera*, *rabbitmq* and *redis*) and one last resource which is -*openstack-cinder-volume* that needs to run as a single active/passive resource -inside the cluster. This role configures all the additional resources needed -to have a working instance HA setup. Once the playbook is executed, the -configuration will be something like this: - - Online: [ overcloud-controller-0 overcloud-controller-1 overcloud-controller-2 ] - RemoteOnline: [ overcloud-compute-0 overcloud-compute-1 ] - - Full list of resources: - - ip-192.168.24.10 (ocf::heartbeat:IPaddr2): Started overcloud-controller-0 - ip-172.18.0.11 (ocf::heartbeat:IPaddr2): Started overcloud-controller-0 - ip-172.20.0.19 (ocf::heartbeat:IPaddr2): Started overcloud-controller-1 - ip-172.17.0.11 (ocf::heartbeat:IPaddr2): Started overcloud-controller-1 - ip-172.19.0.12 (ocf::heartbeat:IPaddr2): Started overcloud-controller-0 - Clone Set: haproxy-clone [haproxy] - Started: [ overcloud-controller-0 overcloud-controller-1 overcloud-controller-2 ] - Stopped: [ overcloud-compute-0 overcloud-compute-1 ] - Master/Slave Set: galera-master [galera] - Masters: [ overcloud-controller-0 overcloud-controller-1 overcloud-controller-2 ] - Stopped: [ overcloud-compute-0 overcloud-compute-1 ] - ip-172.17.0.18 (ocf::heartbeat:IPaddr2): Started overcloud-controller-1 - Clone Set: rabbitmq-clone [rabbitmq] - Started: [ overcloud-controller-0 overcloud-controller-1 overcloud-controller-2 ] - Stopped: [ overcloud-compute-0 overcloud-compute-1 ] - Master/Slave Set: redis-master [redis] - Masters: [ overcloud-controller-0 ] - Slaves: [ overcloud-controller-1 overcloud-controller-2 ] - Stopped: [ overcloud-compute-0 overcloud-compute-1 ] - openstack-cinder-volume (systemd:openstack-cinder-volume): Started overcloud-controller-0 - ipmilan-overcloud-compute-0 (stonith:fence_ipmilan): Started overcloud-controller-1 - ipmilan-overcloud-controller-2 (stonith:fence_ipmilan): Started overcloud-controller-0 - ipmilan-overcloud-controller-0 (stonith:fence_ipmilan): Started overcloud-controller-0 - ipmilan-overcloud-controller-1 (stonith:fence_ipmilan): Started overcloud-controller-1 - ipmilan-overcloud-compute-1 (stonith:fence_ipmilan): Started overcloud-controller-1 - nova-evacuate (ocf::openstack:NovaEvacuate): Started overcloud-controller-0 - Clone Set: nova-compute-checkevacuate-clone [nova-compute-checkevacuate] - Started: [ overcloud-compute-0 overcloud-compute-1 ] - Stopped: [ overcloud-controller-0 overcloud-controller-1 overcloud-controller-2 ] - Clone Set: nova-compute-clone [nova-compute] - Started: [ overcloud-compute-0 overcloud-compute-1 ] - Stopped: [ overcloud-controller-0 overcloud-controller-1 overcloud-controller-2 ] - fence-nova (stonith:fence_compute): Started overcloud-controller-0 - overcloud-compute-1 (ocf::pacemaker:remote): Started overcloud-controller-0 - overcloud-compute-0 (ocf::pacemaker:remote): Started overcloud-controller-1 - -How Instance HA works ---------------------- - -There are three key resource agents you need to consider. Here's the list: - -- *fence_compute* (named **fence-nova** inside the cluster): which takes care - of marking a compute node with the attribute "evacuate" set to yes; -- *NovaEvacuate* (named **nova-evacuate** inside the cluster): which takes care - of the effective evacuation of the instances and runs on one of the - controllers; -- *nova-compute-wait* (named **nova-compute-checkevacuate** inside the - cluster): which waits for eventual evacuation before starting nova compute - services and runs on each compute nodes; - -Looking at the role you will notice that other systemd resources will be added -into the cluster on the compute nodes, especially in older release like mitaka -(*neutron-openvswitch-agent*, *libvirtd*, *openstack-ceilometer-compute* and -*nova-compute*), but the keys for the correct instance HA comprehension are the -aforementioned three resources. - -Evacuation ----------- - -The principle under which Instance HA works is *evacuation*. This means that -when a host becomes unavailablea for whatever reason, instances on it are -evacuated to another available host. -Instance HA works both on shared storage and local storage environments, which -means that evacuated instances will maintain the same network setup (static ip, -floating ip and so on) and characteristics inside the new host, even if they -will be spawned from scratch. - -What happens when a compute node is lost ----------------------------------------- - -Once configured, how does the system behaves when evacuation is needed? The -following sequence describes the actions taken by the cluster and the OpenStack -components: - -1. A compute node (say overcloud-compute-1) which is running instances goes - down for some reason (power outage, kernel panic, manual intervention); -2. The cluster starts the action sequence to fence this host, since it needs - to be sure that the host is *really* down before driving any other operation - (otherwise there is potential for data corruption or multiple identical VMs - running at the same time in the infrastructure). Setup is configured to have - two levels of fencing for the compute hosts: - - * **IPMI**: which will occur first and will take care of physically - resetting the host and hence assuring that the machine is really powered - off; - * **fence-nova**: which will occur afterwards and will take care of marking - with a cluster per-node attribute "evacuate=yes"; - - So the host gets reset and on the cluster a new node-property like the - following will appear: - - [root@overcloud-controller-0 ~]# attrd_updater -n evacuate -A - name="evacuate" host="overcloud-compute-1.localdomain" value="yes" - -3. At this point the resource **nova-evacuate** which constantly monitors the - attributes of the cluster in search of the evacuate tag will find out that - the *overcloud-compute-1* host needs evacuation, and by internally using - *nova-compute commands*, will start the evactuation of the instances towards - another host; -4. In the meantime, while compute-1 is booting up again, - **nova-compute-checkevacuate** will wait (with a default timeout of 120 - seconds) for the evacuation to complete before starting the chain via the - *NovaCompute* resource that will enable the fenced host to become available - again for running instances; - -What to look for when something is not working ----------------------------------------------- - -Here there are some tips to follow once you need to debug why instance HA is -not working: - -1. Check credentials: many resources require access data the the overcloud - coming form the overcloudrc file, so it's not so difficult to do copy - errors; -2. Check connectivity: stonith is essential for cluster and if for some reason - the cluster is not able to fence the compute nodes, the whole instance HA - environment will not work; -3. Check errors: inside the controller's cluster log - (*/var/log/cluster/corosync.log*) some errors may catch the eye. - -Examples on how to invoke the playbook via ansible --------------------------------------------------- - -This command line will install the whole instance-ha solution, with controller -stonith, compute stonith and all the instance ha steps in: - - ansible-playbook /home/stack/tripleo-ha-utils/playbooks/overcloud-instance-ha.yml -e release="rhos-10" - -By default the playbook will install the instance-ha solution with the shared -storage configuration, but it is possible to make the installation in a no -shared storage environment, passing the **instance_ha_shared_storage** variable -as **false**: - - ansible-playbook /home/stack/tripleo-ha-utils/playbooks/overcloud-instance-ha.yml -e release="rhos-10" -e instance_ha_shared_storage=false - -If a user configured the overcloud with a specific domain it is possible to -override the default "localdomain" value by passing the **overcloud_domain** -variable to the playbook: - - ansible-playbook /home/stack/tripleo-ha-utils/playbooks/overcloud-instance-ha.yml -e release="rhos-10" -e overcloud_domain="mydomain" - -If a user already installed STONITH for controllers and wants just to apply all -the instance HA steps with STONITH for the compute nodes can launch this: - - ansible-playbook /home/stack/tripleo-ha-utils/playbooks/overcloud-instance-ha.yml -e release="rhos-10" -e stonith_devices="computes" - -To uninstall the whole instance HA solution: - - ansible-playbook /home/stack/tripleo-ha-utils/playbooks/overcloud-instance-ha.yml -e release="rhos-10" -e instance_ha_action="uninstall" - -Or if you a user needs to omit STONITH for the controllers: - - ansible-playbook /home/stack/tripleo-ha-utils/playbooks/overcloud-instance-ha.yml -e release="rhos-10" -e stonith_devices="computes" -e instance_ha_action="uninstall" - -Is it also possible to totally omit STONITH configuration by passing "none" as -the value of *stonith_devices*. - -License -------- - -GPL - -Author Information ------------------- - -Raoul Scarazzini diff --git a/roles/instance-ha/defaults/main.yml b/roles/instance-ha/defaults/main.yml deleted file mode 100644 index d6675e3..0000000 --- a/roles/instance-ha/defaults/main.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- - -overcloud_working_dir: "/home/heat-admin" -working_dir: "/home/stack" - -# Can be install or uninstall -instance_ha_action: "install" - -# Do we have a shared storage or not? -instance_ha_shared_storage: true - -# Set overcloud domain -overcloud_domain: "localdomain" diff --git a/roles/instance-ha/tasks/apply.yml b/roles/instance-ha/tasks/apply.yml deleted file mode 100644 index d5af07f..0000000 --- a/roles/instance-ha/tasks/apply.yml +++ /dev/null @@ -1,386 +0,0 @@ ---- -- name: Apply STONITH for compute nodes - include_role: - name: stonith-config - vars: - stonith_devices: "computes" - when: - - stonith_devices in ["all","computes"] - -- name: Disable openstack-nova-compute on compute - service: - name: openstack-nova-compute - state: stopped - enabled: no - become: yes - delegate_to: "{{ item }}" - with_items: - - "{{ groups['compute'] }}" - when: release not in [ 'pike', 'rhos-12' ] - -- name: Disable neutron-openvswitch-agent on compute - service: - name: neutron-openvswitch-agent - state: stopped - enabled: no - become: yes - delegate_to: "{{ item }}" - with_items: - - "{{ groups['compute'] }}" - when: release in [ 'liberty', 'rhos-8', 'mitaka', 'rhos-9' ] - -- name: Disable openstack-ceilometer-compute on compute - service: - name: openstack-ceilometer-compute - state: stopped - enabled: no - become: yes - delegate_to: "{{ item }}" - with_items: - - "{{ groups['compute'] }}" - when: release in [ 'liberty', 'rhos-8', 'mitaka', 'rhos-9' ] - -- name: Disable libvirtd on compute - become: yes - service: - name: libvirtd - state: stopped - enabled: no - delegate_to: "{{ item }}" - with_items: - - "{{ groups['compute'] }}" - when: release in [ 'liberty', 'rhos-8', 'mitaka', 'rhos-9' ] - -- name: Generate authkey for remote pacemaker - shell: | - dd if=/dev/urandom of="/tmp/authkey" bs=4096 count=1 - delegate_to: localhost - -- name: Make sure pacemaker config dir exists - become: yes - file: - path: /etc/pacemaker - state: directory - mode: 0750 - group: "haclient" - delegate_to: "{{ item }}" - with_items: - - "{{ groups['controller'] }}" - - "{{ groups['compute'] }}" - -- name: Copy authkey on all the overcloud nodes - become: yes - copy: - src: /tmp/authkey - dest: /etc/pacemaker/authkey - mode: 0640 - group: "haclient" - delegate_to: "{{ item }}" - with_items: - - "{{ groups['controller'] }}" - - "{{ groups['compute'] }}" - -- name: Remove authkey from local dir - file: - path: /tmp/authkey - state: absent - delegate_to: localhost - -- name: Enable iptables traffic for pacemaker_remote - become: yes - shell: | - iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 3121 -j ACCEPT - delegate_to: "{{ item }}" - with_items: - - "{{ groups['controller'] }}" - - "{{ groups['compute'] }}" - -- name: Make iptables pacemaker_remote rule permanent - become: yes - lineinfile: - path: /etc/sysconfig/iptables - line: "-A INPUT -p tcp -m state --state NEW -m tcp --dport 3121 -j ACCEPT" - insertafter: ":OUTPUT ACCEPT" - delegate_to: "{{ item }}" - with_items: - - "{{ groups['controller'] }}" - - "{{ groups['compute'] }}" - -- name: Start pacemaker remote service on compute nodes - become: yes - service: - name: pacemaker_remote - enabled: yes - state: started - delegate_to: "{{ item }}" - with_items: - - "{{ groups['compute'] }}" - -- name: Get the name of the stack - shell: | - source {{ working_dir }}/stackrc - openstack stack list -f value -c 'Stack Name' - register: stack_name - -- name: Check if a v3 overcloud's rc file exists - stat: - path: "{{ working_dir }}/{{ stack_name.stdout }}rc.v3" - register: v3_rc_file_stat - -- name: Get the contents of the overcloud's rc file v3 - set_fact: - overcloudrc: "{{ stack_name.stdout }}rc.v3" - when: v3_rc_file_stat.stat.exists - -- name: Get the contents of the overcloud's rc file - set_fact: - overcloudrc: "{{ stack_name.stdout }}rc" - when: not v3_rc_file_stat.stat.exists - -- block: - - name: Get OS_USERNAME from overcloudrc - shell: | - grep OS_USERNAME {{ working_dir }}/{{ overcloudrc }} | sed 's/export OS_USERNAME=//g' - register: "OS_USERNAME" - - - name: Get OS_PASSWORD from overcloudrc - shell: | - grep OS_PASSWORD {{ working_dir }}/{{ overcloudrc }} | sed 's/export OS_PASSWORD=//g' - register: "OS_PASSWORD" - - - name: Get OS_AUTH_URL from overcloudrc - shell: | - grep OS_AUTH_URL {{ working_dir }}/{{ overcloudrc }} | sed 's/export OS_AUTH_URL=//g' - register: "OS_AUTH_URL" - - - name: Get OS_PROJECT_NAME or OS_TENANT_NAME from overcloudrc - shell: | - grep -E 'OS_PROJECT_NAME|OS_TENANT_NAME' {{ working_dir }}/{{ overcloudrc }} | tail -1 | sed 's/export OS_.*_NAME=//g' - register: "OS_TENANT_NAME" - - - name: Get OS_USER_DOMAIN_NAME from overcloudrc - shell: | - grep OS_USER_DOMAIN_NAME {{ working_dir }}/{{ overcloudrc }} | sed 's/export OS_USER_DOMAIN_NAME=//g' - register: "OS_USER_DOMAIN_NAME" - when: v3_rc_file_stat.stat.exists - - - name: Get OS_PROJECT_DOMAIN_NAME from overcloudrc - shell: | - grep OS_PROJECT_DOMAIN_NAME {{ working_dir }}/{{ overcloudrc }} | sed 's/export OS_PROJECT_DOMAIN_NAME=//g' - register: "OS_PROJECT_DOMAIN_NAME" - when: v3_rc_file_stat.stat.exists - -- name: Define variable for pcs additional options for overcloud's rc file v3 - set_fact: - pcs_v3_rc_file_opts: "" - -- name: Define variable for pcs additional options for no_shared_storage - set_fact: - pcs_NovaEvacuate_no_shared_storage_opts: "" - pcs_fence_compute_no_shared_storage_opts: "" - -- name: Set pcs additional options for overcloud's rc file v3 - set_fact: - pcs_v3_rc_file_opts: "project_domain=$OS_PROJECT_DOMAIN_NAME user_domain=$OS_USER_DOMAIN_NAME" - when: v3_rc_file_stat.stat.exists - -- name: Set pcs additional options for no_shared_storage - set_fact: - pcs_NovaEvacuate_no_shared_storage_opts: "no_shared_storage=1" - pcs_fence_compute_no_shared_storage_opts: "no-shared-storage=True" - when: not instance_ha_shared_storage|bool - -- block: - - name: Create resource nova-evacuate - shell: | - pcs resource create nova-evacuate ocf:openstack:NovaEvacuate auth_url=$OS_AUTH_URL username=$OS_USERNAME password=$OS_PASSWORD tenant_name=$OS_TENANT_NAME {{ pcs_v3_rc_file_opts }} {{ pcs_NovaEvacuate_no_shared_storage_opts }} --force - - - name: Create pacemaker constraint to start nova-evacuate only on non compute nodes - shell: | - pcs constraint location nova-evacuate rule resource-discovery=never score=-INFINITY osprole eq compute - - - name: Create pacemaker constraints to start VIP resources before nova-evacuate - shell: | - for i in $(pcs status | grep IP | awk '{ print $1 }') - do pcs constraint order start $i then nova-evacuate - done - - - name: Create pacemaker constraints to start openstack services before nova-evacuate - shell: "pcs constraint order start {{ item }} then nova-evacuate require-all=false" - with_items: - - openstack-glance-api-clone - - neutron-metadata-agent-clone - - openstack-nova-conductor-clone - when: release in [ 'liberty', 'rhos-8', 'mitaka', 'rhos-9' ] - - - name: Disable keystone resource - shell: "pcs resource disable openstack-keystone --wait=900" - when: release in [ 'liberty', 'rhos-8' ] - - # Keystone resource was replaced by openstack-core resource in RHOS9 - - name: Disable openstack-core resource - shell: "pcs resource disable openstack-core --wait=900" - when: release in [ 'mitaka', 'rhos-9' ] - - - name: Set controller pacemaker property on controllers - shell: "pcs property set --node {{ hostvars[item]['ansible_hostname'] }} osprole=controller" - with_items: "{{ groups['controller'] }}" - - - name: Get stonith devices - shell: "pcs stonith | awk '{print $1}' | tr '\n' ' '" - register: stonithdevs - - - name: Setup stonith devices - shell: | - for i in $(cibadmin -Q --xpath //primitive --node-path | awk -F "id='" '{print $2}' | awk -F "'" '{print $1}' | uniq); do - found=0 - if [ -n "{{ stonithdevs.stdout }}" ]; then - for x in {{ stonithdevs.stdout }}; do - if [ "$x" == "$i" ]; then - found=1 - fi - done - fi - if [ $found = 0 ]; then - pcs constraint location $i rule resource-discovery=exclusive score=0 osprole eq controller - fi - done - when: release not in [ 'pike', 'rhos-12' ] - - - name: Create compute pacemaker resources and constraints - shell: | - pcs resource create nova-compute-checkevacuate ocf:openstack:nova-compute-wait auth_url=$OS_AUTH_URL username=$OS_USERNAME password=$OS_PASSWORD tenant_name=$OS_TENANT_NAME domain={{ overcloud_domain }} op start timeout=300 --clone interleave=true --disabled --force - pcs constraint location nova-compute-checkevacuate-clone rule resource-discovery=exclusive score=0 osprole eq compute - pcs resource create nova-compute systemd:openstack-nova-compute op start timeout=60s --clone interleave=true --disabled --force - pcs constraint location nova-compute-clone rule resource-discovery=exclusive score=0 osprole eq compute - pcs constraint order start nova-compute-checkevacuate-clone then nova-compute-clone require-all=true - pcs constraint order start nova-compute-clone then nova-evacuate require-all=false - when: release not in [ 'pike', 'rhos-12' ] - - - name: Create compute pacemaker resources and constraints - shell: | - pcs resource create neutron-openvswitch-agent-compute systemd:neutron-openvswitch-agent --clone interleave=true --disabled --force - pcs constraint location neutron-openvswitch-agent-compute-clone rule resource-discovery=exclusive score=0 osprole eq compute - pcs resource create libvirtd-compute systemd:libvirtd --clone interleave=true --disabled --force - pcs constraint location libvirtd-compute-clone rule resource-discovery=exclusive score=0 osprole eq compute - pcs constraint order start neutron-openvswitch-agent-compute-clone then libvirtd-compute-clone - pcs constraint colocation add libvirtd-compute-clone with neutron-openvswitch-agent-compute-clone - pcs resource create ceilometer-compute systemd:openstack-ceilometer-compute --clone interleave=true --disabled --force - pcs constraint location ceilometer-compute-clone rule resource-discovery=exclusive score=0 osprole eq compute - pcs constraint order start libvirtd-compute-clone then ceilometer-compute-clone - pcs constraint colocation add ceilometer-compute-clone with libvirtd-compute-clone - pcs constraint order start libvirtd-compute-clone then nova-compute-clone - pcs constraint colocation add nova-compute-clone with libvirtd-compute-clone - when: release in [ 'liberty', 'rhos-8', 'mitaka', 'rhos-9' ] - - - name: Create pacemaker constraint for neutron-server, nova-conductor and ceilometer-notification - shell: | - pcs constraint order start neutron-server-clone then neutron-openvswitch-agent-compute-clone require-all=false - pcs constraint order start openstack-ceilometer-notification-clone then ceilometer-compute-clone require-all=false - pcs constraint order start openstack-nova-conductor-clone then nova-compute-checkevacuate-clone require-all=false - when: release in [ 'liberty', 'rhos-8', 'mitaka', 'rhos-9' ] - - - name: Set requires to fencing as default for all resources (Pike/RHOS-12) - shell: "pcs resource defaults requires=fencing" - when: release in [ 'pike', 'rhos-12' ] - - - name: Create fence-nova pacemaker resource (no shared storage) - shell: "pcs stonith create fence-nova fence_compute auth_url=$OS_AUTH_URL login=$OS_USERNAME passwd=$OS_PASSWORD tenant_name=$OS_TENANT_NAME domain={{ overcloud_domain }} record_only=1 {{ pcs_fence_compute_no_shared_storage_opts }} --force" - when: release not in [ 'pike', 'rhos-12' ] - - - name: Create fence-nova pacemaker resource (Pike/RHOS-12) - shell: "pcs stonith create fence-nova fence_compute auth_url=$OS_AUTH_URL login=$OS_USERNAME passwd=$OS_PASSWORD tenant_name=$OS_TENANT_NAME domain={{ overcloud_domain }} record_only=1 {{ pcs_fence_compute_no_shared_storage_opts }} meta provides=unfencing --force" - when: release in [ 'pike', 'rhos-12' ] - - - name: Create pacemaker constraint for fence-nova to fix it on controller node and set resource-discovery never - shell: "pcs constraint location fence-nova rule resource-discovery=never score=0 osprole eq controller" - - - name: Create pacemaker constraint for fence-nova to start after galera - shell: "pcs constraint order promote galera-master then fence-nova require-all=false" - when: release not in [ 'pike', 'rhos-12' ] - - - name: Create nova-compute order constraint on fence-nova - shell: "pcs constraint order start fence-nova then nova-compute-clone" - when: release not in [ 'pike', 'rhos-12' ] - - - name: Set cluster recheck interval to 1 minute - shell: "pcs property set cluster-recheck-interval=1min" - - - name: Create pacemaker remote resource on compute nodes - shell: "pcs resource create {{ hostvars[item]['ansible_hostname'] }} ocf:pacemaker:remote reconnect_interval=240 op monitor interval=20" - with_items: "{{ groups['compute'] }}" - - - name: Set osprole for compute nodes - shell: "pcs property set --node {{ hostvars[item]['ansible_hostname'] }} osprole=compute" - with_items: "{{ groups['compute'] }}" - - - name: Add STONITH level definitions for compute nodes - shell: | - compute_stonith_name=$(cibadmin --query --xpath "//primitive[@class='stonith']/instance_attributes/nvpair[@value='{{ item }}']" | sed 's/.*id="\(.*\)-instance_attributes-pcmk_host_list".*/\1/g') - pcs stonith level add 1 {{ item }} $compute_stonith_name,fence-nova - with_items: "{{ groups['compute'] }}" - - - name: Enable keystone resource - shell: "pcs resource enable openstack-keystone" - when: release in [ 'liberty', 'rhos-8' ] - - - name: Enable openstack-core resource - shell: "pcs resource enable openstack-core" - when: release in [ 'mitaka', 'rhos-9' ] - - - name: Wait for httpd service to be started - shell: "systemctl show httpd --property=ActiveState" - register: httpd_status_result - until: httpd_status_result.stdout.find('inactive') == -1 and httpd_status_result.stdout.find('activating') == -1 - retries: 30 - delay: 10 - when: release not in [ 'liberty', 'rhos-8', 'mitaka', 'rhos-9' ] - - - name: Enable compute nodes resources (nova) - shell: "pcs resource enable {{ item }}" - with_items: - - nova-compute-checkevacuate - - nova-compute - when: release not in [ 'pike', 'rhos-12' ] - - - name: Create compute unfence resource to override default resource requires (Pike/RHOS-12) - shell: | - pcs resource create compute-unfence-trigger ocf:pacemaker:Dummy op start requires="unfencing" --clone --disabled - pcs constraint location compute-unfence-trigger-clone rule resource-discovery=never score=-INFINITY osprole ne compute - pcs resource enable compute-unfence-trigger - when: release in [ 'pike', 'rhos-12' ] - - - name: Enable compute nodes resources (others) - shell: "pcs resource enable {{ item }}" - with_items: - - neutron-openvswitch-agent-compute - - libvirtd-compute - - ceilometer-compute - when: release in [ 'liberty', 'rhos-8', 'mitaka', 'rhos-9' ] - environment: - OS_USERNAME: "{{ OS_USERNAME.stdout }}" - OS_PASSWORD: "{{ OS_PASSWORD.stdout }}" - OS_AUTH_URL: "{{ OS_AUTH_URL.stdout }}" - OS_TENANT_NAME: "{{ OS_TENANT_NAME.stdout }}" - OS_USER_DOMAIN_NAME: "{{ OS_USER_DOMAIN_NAME.stdout }}" - OS_PROJECT_DOMAIN_NAME: "{{ OS_PROJECT_DOMAIN_NAME.stdout }}" - become: yes - delegate_to: "{{ groups.controller[0] }}" - -- name: Cleanup (if any) failed resources - shell: | - for resource in $(pcs status | sed -n -e '/Failed Actions:/,/^$/p' | egrep 'OCF_|not running|unknown' | awk '{print $2}' | cut -f1 -d_ | sort |uniq) - do - pcs resource cleanup $resource - done - become: yes - delegate_to: "{{ groups.controller[0] }}" - -- name: Wait for (if any) failed resources to recover - shell: pcs status | sed -n -e '/Failed Actions:/,/^$/p' | egrep 'OCF_|not running|unknown' | awk '{print $2}' | cut -f1 -d_ | sort |uniq - register: failed_resources - until: failed_resources.stdout != [] - retries: 10 - delay: 10 - become: yes - delegate_to: "{{ groups.controller[0] }}" diff --git a/roles/instance-ha/tasks/main.yml b/roles/instance-ha/tasks/main.yml deleted file mode 100644 index cc8694c..0000000 --- a/roles/instance-ha/tasks/main.yml +++ /dev/null @@ -1,31 +0,0 @@ ---- -- name: Check if Instance HA steps were already applied - include: pre-checks.yml - when: - - instance_ha_action == "install" - -- name: Apply STONITH for controller nodes - include_role: - name: stonith-config - when: - - instance_ha_action == "install" - - stonith_devices in ["all","controllers"] - -- name: Apply Instance High Availability steps - include: apply.yml - when: - - instance_ha_action == "install" - -- name: Undo Instance High Availability steps - include: undo.yml - when: - - instance_ha_action == "uninstall" - -- name: Remove STONITH for controller nodes - include_role: - name: stonith-config - vars: - stonith_action: "uninstall" - when: - - instance_ha_action == "uninstall" - - stonith_devices in ["all","controllers"] diff --git a/roles/instance-ha/tasks/pre-checks.yml b/roles/instance-ha/tasks/pre-checks.yml deleted file mode 100644 index 1111097..0000000 --- a/roles/instance-ha/tasks/pre-checks.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -- block: - - name: Check if STONITH resources already exist - shell: | - pcs stonith show | grep {{ item }} - with_items: - - fence-nova - register: pre_existing_stonith - failed_when: pre_existing_stonith.rc == 0 - - - name: Check if IHA resources already exist - shell: | - pcs resource show | grep "{{ item }}" - with_items: - - compute-unfence-trigger - - nova-compute-checkevacuate - - nova-compute - - nova-evacuate - - neutron-openvswitch-agent-compute - - libvirtd-compute - - ceilometer-compute - register: pre_existing_resources - failed_when: pre_existing_resources.rc == 0 - become: yes - delegate_to: "{{ groups.controller[0] }}" diff --git a/roles/instance-ha/tasks/undo.yml b/roles/instance-ha/tasks/undo.yml deleted file mode 100644 index 3a9f623..0000000 --- a/roles/instance-ha/tasks/undo.yml +++ /dev/null @@ -1,168 +0,0 @@ ---- -- block: - - name: Remove STONITH level definitions for compute nodes - shell: | - compute_stonith_name=$(cibadmin --query --xpath "//primitive[@class='stonith']/instance_attributes/nvpair[@value='{{ item }}']" | sed 's/.*id="\(.*\)-instance_attributes-pcmk_host_list".*/\1/g') - for stonith_level in $(cibadmin --query --xpath "//configuration/fencing-topology/fencing-level[@devices='$compute_stonith_name,fence-nova'][@index='1'][@target='{{ item }}']" --node-path) - do - pcs stonith level delete 1 {{ item }} $compute_stonith_name,fence-nova - done - with_items: "{{ groups['compute'] }}" - - - name: Remove fence-nova STONITH device - shell: | - for stonithid in $(pcs stonith show | awk '/fence_compute/ {print $1}') - do - pcs stonith delete fence-nova - done - - - name: Remove resources associated to remote nodes - shell: | - for resourceid in $(pcs resource show | grep compute | grep 'Clone Set:' | awk '{print $3}') - do - pcs resource cleanup $resourceid - pcs --force resource delete $resourceid - done - - - name: Remove NovaEvacuate resource - shell: | - for resourceid in $(pcs resource show | grep NovaEvacuate | awk '/NovaEvacuate/ {print $1}') - do - pcs resource cleanup $resourceid - pcs --force resource delete $resourceid - done - - - name: Remove pacemaker remote resource - shell: | - for resourceid in $(pcs resource show | awk '/:remote/ {print $1}') - do - pcs resource cleanup $resourceid - pcs --force resource delete $resourceid - done - - - name: Remove constraints related to role controller - shell: | - for constraintid in $(pcs config show | grep -B 3 "osprole eq controller" | awk '/Constraint/ {print $2}') - do - pcs constraint delete $constraintid - done - - - name: Unset controller pacemaker property on controllers - shell: | - for nodeid in $(pcs property | awk '/osprole/ { print $1 }' | cut -d: -f1) - do - pcs property unset --node $nodeid osprole - done - - - name: Unset cluster recheck interval to 1 minute - shell: | - for propertyid in $(pcs property | awk '/cluster-recheck-interval/ { print $1 }' | cut -d: -f1) - do - pcs property unset cluster-recheck-interval - done - become: yes - delegate_to: "{{ groups.controller[0] }}" - -- name: Cleanup failed resources (if any) - shell: | - for resource in $(pcs status | sed -n -e '/Failed Actions:/,/^$/p' | egrep 'OCF_|not running|unknown' | awk '{print $2}' | cut -f1 -d_ | sort |uniq) - do - pcs resource cleanup $resource - done - become: yes - delegate_to: "{{ groups.controller[0] }}" - -- name: Wait for failed resources to recover (if any) - shell: pcs status | sed -n -e '/Failed Actions:/,/^$/p' | egrep 'OCF_|not running|unknown' | awk '{print $2}' | cut -f1 -d_ | sort |uniq - register: failed_resources - until: failed_resources.stdout != [] - retries: 10 - delay: 10 - become: yes - delegate_to: "{{ groups.controller[0] }}" - -- name: Enable openstack-nova-compute on compute - service: - name: openstack-nova-compute - state: started - enabled: yes - become: yes - delegate_to: "{{ item }}" - with_items: - - "{{ groups['compute'] }}" - when: release not in [ 'pike', 'rhos-12' ] - -- name: Enable neutron-openvswitch-agent on compute - service: - name: neutron-openvswitch-agent - state: started - enabled: yes - become: yes - delegate_to: "{{ item }}" - with_items: - - "{{ groups['compute'] }}" - when: release in [ 'liberty', 'rhos-8', 'mitaka', 'rhos-9' ] - -- name: Enable openstack-ceilometer-compute on compute - service: - name: openstack-ceilometer-compute - state: started - enabled: yes - become: yes - delegate_to: "{{ item }}" - with_items: - - "{{ groups['compute'] }}" - when: release in [ 'liberty', 'rhos-8', 'mitaka', 'rhos-9' ] - -- name: Enable libvirtd on compute - become: yes - service: - name: libvirtd - state: started - enabled: yes - delegate_to: "{{ item }}" - with_items: - - "{{ groups['compute'] }}" - when: release in [ 'liberty', 'rhos-8', 'mitaka', 'rhos-9' ] - -- name: Stop pacemaker remote service on compute nodes - become: yes - service: - name: pacemaker_remote - enabled: no - state: stopped - delegate_to: "{{ item }}" - with_items: - - "{{ groups['compute'] }}" - -- name: Disable iptables traffic for pacemaker_remote - become: yes - shell: | - while [ $(iptables-save | grep -c "\-A INPUT \-p tcp \-m state \-\-state NEW \-m tcp \-\-dport 3121 \-j ACCEPT") -ne 0 ] - do - iptables -D INPUT -p tcp -m state --state NEW -m tcp --dport 3121 -j ACCEPT - done - delegate_to: "{{ item }}" - with_items: - - "{{ groups['controller'] }}" - - "{{ groups['compute'] }}" - -- name: Remove iptables pacemaker_remote permanent rule - become: yes - lineinfile: - path: /etc/sysconfig/iptables - line: "-A INPUT -p tcp -m state --state NEW -m tcp --dport 3121 -j ACCEPT" - state: absent - delegate_to: "{{ item }}" - with_items: - - "{{ groups['controller'] }}" - - "{{ groups['compute'] }}" - -- name: Undo STONITH for compute nodes - include_role: - name: stonith-config - vars: - stonith_action: "uninstall" - stonith_devices: "computes" - when: - - stonith_devices in ["all","computes"] diff --git a/roles/stonith-config/README.md b/roles/stonith-config/README.md deleted file mode 100644 index e194705..0000000 --- a/roles/stonith-config/README.md +++ /dev/null @@ -1,90 +0,0 @@ -stonith-config -============== - -This role acts on an already deployed tripleo environment, setting up STONITH -(Shoot The Other Node In The Head) inside the Pacemaker configuration for all -the hosts that are part of the overcloud. - -Requirements ------------- - -The TripleO environment must be prepared as described [here](https://github.com/openstack/tripleo-ha-utils/tree/master/README.md). - -STONITH -------- - -STONITH is the way a Pacemaker clusters use to be certain that a node is powered -off. STONITH is the only way to use a shared storage environment without -worrying about concurrent writes on disks. Inside TripleO environments STONITH -is a requisite also for activating features like Instance HA because, before -moving any machine, the system need to be sure that the "move from" machine is -off. -STONITH configuration relies on the **instackenv.json** file, used by TripleO -also to configure Ironic and all the provision stuff. -Basically this role enables STONITH on the Pacemaker cluster and takes all the -information from the mentioned file, creating a STONITH resource for each host -on the overcloud. -After running this playbook the cluster configuration will have this properties: - - $ sudo pcs property - Cluster Properties: - cluster-infrastructure: corosync - cluster-name: tripleo_cluster - ... - ... - **stonith-enabled: true** - -And something like this, depending on how many nodes are there in the overcloud: - - sudo pcs stonith - ipmilan-overcloud-compute-0 (stonith:fence_ipmilan): Started overcloud-controller-1 - ipmilan-overcloud-controller-2 (stonith:fence_ipmilan): Started overcloud-controller-0 - ipmilan-overcloud-controller-0 (stonith:fence_ipmilan): Started overcloud-controller-0 - ipmilan-overcloud-controller-1 (stonith:fence_ipmilan): Started overcloud-controller-1 - ipmilan-overcloud-compute-1 (stonith:fence_ipmilan): Started overcloud-controller-1 - -Having all this in place is a requirement for a reliable HA solution and for -configuring special OpenStack features like [Instance HA](https://github.com/openstack/tripleo-ha-utils/tree/master/roles/instance-ha). - -**Note**: by default this role configures STONITH for the controllers nodes, -but it is possible to configure all the nodes or to limitate it just for -computes, by setting the **stonith_devices** variable, which by default is set -to "controllers", but can also be "*all*" or "*computes*". - -Limitations ------------ - -The only kind of STONITH devices supported are **for the moment** IPMI. - -Examples on how to invoke the playbook via ansible --------------------------------------------------- - -This command line will install the STONITH devices for the controller nodes: - - ansible-playbook /home/stack/tripleo-ha-utils/playbooks/overcloud-stonith-config.yml - -If a user wants to install the STONITH devices for all the nodes: - - ansible-playbook /home/stack/tripleo-ha-utils/playbooks/overcloud-stonith-config.yml -e stonith_devices="all" - -To uninstall the STONITH devices for the controllers: - - ansible-playbook /home/stack/tripleo-ha-utils/playbooks/overcloud-stonith-config.yml -e stonith_action="uninstall" - -To uninstall the STONITH devices just for the computes: - - ansible-playbook /home/stack/tripleo-ha-utils/playbooks/overcloud-stonith-config.yml -e stonith_action="uninstall" -e stonith_devices="computes" - -The STONITH role supports also "none" as a valid value for *stonith_devices* -which can become useful when configuring instance HA in an environment already -configured with STONITH for both controllers and computes. - -License -------- - -GPL - -Author Information ------------------- - -Raoul Scarazzini diff --git a/roles/stonith-config/defaults/main.yml b/roles/stonith-config/defaults/main.yml deleted file mode 100644 index 170d29c..0000000 --- a/roles/stonith-config/defaults/main.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- - -overcloud_working_dir: "/home/heat-admin" -working_dir: "/home/stack" -instack_env_file: "{{ working_dir }}/instackenv.json" - -config_stonith_python_script: config-stonith-from-instackenv.py.j2 - -# Can be install, uninstall or none -stonith_action: "install" - -# Can be all, controllers or computes -stonith_devices: controllers diff --git a/roles/stonith-config/tasks/main.yml b/roles/stonith-config/tasks/main.yml deleted file mode 100644 index 58230e3..0000000 --- a/roles/stonith-config/tasks/main.yml +++ /dev/null @@ -1,32 +0,0 @@ ---- -- name: Load the STONITH creation script on the undercloud - template: - src: "{{ config_stonith_python_script }}" - dest: "{{ working_dir }}/config_stonith_from_instackenv.py" - mode: 0755 - -- name: Generate STONITH script - shell: | - source {{ working_dir }}/stackrc - {{ working_dir }}/config_stonith_from_instackenv.py {{ instack_env_file }} {{ stonith_action }} {{ stonith_devices }} - register: stonith_script - -- name: Delete the STONITH script on the overcloud (if exists) - file: - path: "{{ overcloud_working_dir }}/config-stonith.sh" - state: absent - delegate_to: "{{ groups.controller[0] }}" - -- name: Create the STONITH script on the overcloud - lineinfile: - destfile: "{{ overcloud_working_dir }}/config-stonith.sh" - line: "{{ stonith_script.stdout }}" - create: yes - mode: 0755 - delegate_to: "{{ groups.controller[0] }}" - -- name: Execute STONITH script - become: true - delegate_to: "{{ groups.controller[0] }}" - shell: > - {{ overcloud_working_dir }}/config-stonith.sh &> config_stonith.log diff --git a/roles/stonith-config/templates/config-stonith-from-instackenv.py.j2 b/roles/stonith-config/templates/config-stonith-from-instackenv.py.j2 deleted file mode 100644 index 6b12b64..0000000 --- a/roles/stonith-config/templates/config-stonith-from-instackenv.py.j2 +++ /dev/null @@ -1,94 +0,0 @@ -#!/bin/python - -import os -import json -import sys -from keystoneauth1.identity import v2 -from keystoneauth1 import session -from pprint import pprint -from novaclient import client - -# JSon file as first parameter -jdata = open(sys.argv[1]) -data = json.load(jdata) - -# install, uninstall, none -fence_config = sys.argv[2] -# controllers, computes, all or none -fence_devices = sys.argv[3] - -# Define variables to connect to nova -os_username = os.environ['OS_USERNAME'] -os_password = os.environ['OS_PASSWORD'] -os_auth_url = os.environ['OS_AUTH_URL'] -try: - os_tenant_name = os.environ['OS_TENANT_NAME'] -except: - os_project_name = os.environ['OS_PROJECT_NAME'] - os_project_domain_name=os.environ['OS_PROJECT_DOMAIN_NAME'] - os_user_domain_name=os.environ['OS_USER_DOMAIN_NAME'] -os_compute_api_version = os.environ['COMPUTE_API_VERSION'] - -# If fence_devices includes controllers then we act on the overall stonith-enabled property of the cluster -if (fence_devices in ['controllers','all']): - # If we're uninstalling then we disable stonith - if (fence_config == 'uninstall'): - print('pcs property set stonith-enabled=false') - # If we're installing then we enable it - elif (fence_config == 'install'): - print('pcs property set stonith-enabled=true') - -# Connect to nova -try: - # Liberty/OSP-8,Mitaka/OSP-9,Newton/OSP-10 - nt = client.Client(2, - os_username, - os_password, - os_tenant_name, - os_auth_url) - nt.hypervisors.list() -except: - try: - # Ocata/OSP-11 - nt = client.Client(2, - username=os_username, - password=os_password, - project_name=os_tenant_name, - auth_url=os_auth_url) - nt.hypervisors.list() - except: - # Pike/OSP-12 - nt = client.Client(2, - auth_url=os_auth_url, - username=os_username, - password=os_password, - project_name=os_project_name, - project_domain_name=os_project_domain_name, - user_domain_name=os_user_domain_name) - nt.hypervisors.list() - -# Parse instances -for instance in nt.servers.list(): - for node in data["nodes"]: - if (node["mac"][0].lower() == instance.addresses['ctlplane'][0]['OS-EXT-IPS-MAC:mac_addr'] - and - ( - ('controller' in instance.name and fence_devices in ['controllers','all']) - or - ('compute' in instance.name and fence_devices in ['computes','all']) - ) - ): - if (fence_config == 'uninstall'): - print('pcs stonith delete ipmilan-{} || /bin/true'.format(instance.name)) - elif (fence_config == 'install'): - try: - print('pcs stonith create ipmilan-{} fence_ipmilan pcmk_host_list="{}" ipaddr="{}" login="{}" passwd="{}" ipport={} lanplus="true" delay=20 op monitor interval=60s' - .format(instance.name,instance.name,node["pm_addr"],node["pm_user"],node["pm_password"],node["pm_port"])) - except: - print('pcs stonith create ipmilan-{} fence_ipmilan pcmk_host_list="{}" ipaddr="{}" login="{}" passwd="{}" lanplus="true" delay=20 op monitor interval=60s' - .format(instance.name,instance.name,node["pm_addr"],node["pm_user"],node["pm_password"])) - print('pcs constraint location ipmilan-{} avoids {}' - .format(instance.name,instance.name)) - -# Close nova connection -jdata.close() diff --git a/roles/stonith-config/templates/config-stonith-from-instackenv.py.readme b/roles/stonith-config/templates/config-stonith-from-instackenv.py.readme deleted file mode 100644 index c6e4b01..0000000 --- a/roles/stonith-config/templates/config-stonith-from-instackenv.py.readme +++ /dev/null @@ -1,60 +0,0 @@ -################ -# Python imports -################ -import os -import json -import sys -# The below will be enabled once OS_AUTH_URL=http://192.0.2.1:5000/v3 -#from keystoneauth1.identity import v3 -from keystoneauth1.identity import v2 -from keystoneauth1 import session -from pprint import pprint -from novaclient import client - -########################################################## -# Environment variables (need to source before launching): -########################################################## -export NOVA_VERSION=1.1 -export OS_PASSWORD=$(sudo hiera admin_password) -# If v3: - export OS_AUTH_URL=http://192.0.2.1:5000/v3 -# else - export OS_AUTH_URL=http://192.0.2.1:5000/v2.0 -export OS_USERNAME=admin -export OS_TENANT_NAME=admin -export COMPUTE_API_VERSION=1.1 -export OS_NO_CACHE=True - -############## -# JSON format: -############## -{ "nodes": [ -{ - "mac": [ -"b8:ca:3a:66:e3:82" - ], - "_comment":"host12-rack03.scale.openstack.engineering.redhat.com", - "cpu": "", - "memory": "", - "disk": "", - "arch": "x86_64", - "pm_type":"pxe_ipmitool", - "pm_user":"qe-scale", - "pm_password":"d0ckingSt4tion", - "pm_addr":"10.1.8.102" -}, -... - -######################################################################## -# To make the below working os_auth_url must be http://192.0.2.1:5000/v3 -######################################################################## -auth = v3.Password(auth_url=os_auth_url, - username=os_username, - password=os_password, -{% if release in [ 'liberty', 'rhos-8', 'mitaka', 'rhos-9' ] %} - tenant_name=os_tenant_name, -{% else %} - project_name=os_tenant_name, -{% endif %} - user_domain_id='default', - project_domain_id='default') diff --git a/roles/validate-ha/README.md b/roles/validate-ha/README.md deleted file mode 100644 index 6cc2471..0000000 --- a/roles/validate-ha/README.md +++ /dev/null @@ -1,119 +0,0 @@ -validate-ha -=========== - -This role acts on an already deployed tripleo environment, testing HA related -functionalities of the installation. - -Requirements ------------- - -The TripleO environment must be prepared as described [here](https://github.com/openstack/tripleo-ha-utils/tree/master/README.md). - -This role tests also instances spawning and to make this working the -definition of the floating network must be passed. -It can be contained in a config file, like this: - - private_network_cidr: "192.168.1.0/24" - public_physical_network: "floating" - floating_ip_cidr: "10.0.0.0/24" - public_net_pool_start: "10.0.0.191" - public_net_pool_end: "10.0.0.198" - public_net_gateway: "10.0.0.254" - -Or passed directly to the ansible command line (see examples below). - -HA tests --------- - -HA tests are meant to check the behavior of the environment in front of -circumstances that involve service interruption, lost of a node and in general -actions that stress the OpenStack installation with unexpected failures. -Each test is associated to a global variable that, if true, makes the test -happen. -Tests are grouped and performed by default depending on the OpenStack release. -This is the list of the supported variables, with test description and name of -the release on which the test is performed: - -- **test_ha_failed_actions**: Look for failed actions (**all**) -- **test_ha_master_slave**: Stop master slave resources (galera and redis), all -the resources should come down (**all**) -- **test_ha_keystone_constraint_removal**: Stop keystone resource (by stopping -httpd), check no other resource is stopped (**mitaka**) -- Next generation cluster checks (**newton**, **ocata**, **master**): - - **test_ha_ng_a**: Stop every systemd resource, stop Galera and Rabbitmq, -Start every systemd resource - - **test_ha_ng_b**: Stop Galera and Rabbitmq, stop every systemd resource, -Start every systemd resource - - **test_ha_ng_c**: Stop Galera and Rabbitmq, wait 20 minutes to see if -something fails - -It is also possible to omit (or add) tests not made for the specific release, -using the above vars, by passing to the command line variables like this: - - ... - -e test_ha_failed_actions=false \ - -e test_ha_ng_a=true \ - ... - -In this case we will not check for failed actions, a test that otherwise would -have been done in mitaka, and we will force the execution of the "ng_a" test -described earlier, which is originally executed just in newton versions or -above. - -All tests are performed using the tool [ha-test-suite](https://github.com/openstack/tripleo-ha-utils/tree/master/tools/ha-test-suite). - -Applying latency ----------------- - -It is possible to add an arbitrary amount of milliseconds of latency on each -overcloud node to check whether the environment can pass the HA validation in -any case. -Adding the latency will be a matter of passing two variables: - -* **latency_ms**: which will be the number of additional milliseconds to be -added to the interface; -* **latency_eth_interface**: the physical interface to which the user wants to -apply the latency, this must be present in all the overcloud nodes; - -So a typical command line in which a user wants to add 20ms of latency on the -ethernet device eth0 will contain something like this: - - ... - -e latency_ms=20 \ - -e latency_eth_interface=eth0 \ - ... - -The latency will be applied before the tests execution and remove right after. - -Examples on how to invoke the playbook via ansible --------------------------------------------------- - -Here's a way to invoke the tests from an *undercloud* machine prepared as -described [here](https://github.com/openstack/tripleo-ha-utils/tree/master/README.md). - - ansible-playbook /home/stack/tripleo-ha-utils/playbooks/overcloud-validate-ha.yml \ - -e release=ocata \ - -e local_working_dir=/home/stack \ - -e private_net_cidr="192.168.1.0/24" \ - -e public_physical_network="floating" \ - -e floating_ip_cidr="10.0.0.0/24" \ - -e public_net_pool_start="10.0.0.191" \ - -e public_net_pool_end="10.0.0.198" \ - -e public_net_gateway="10.0.0.254" - -Note that the variables above can be declared inside a config.yml file that can -be passed to the ansible-playbook command like this: - - ansible-playbook -vvvv /home/stack/tripleo-ha-utils/playbooks/overcloud-validate-ha.yml -e @/home/stack/config.yml - -The result will be the same. - -License -------- - -GPL - -Author Information ------------------- - -Raoul Scarazzini diff --git a/roles/validate-ha/defaults/main.yml b/roles/validate-ha/defaults/main.yml deleted file mode 100644 index eb9c7ef..0000000 --- a/roles/validate-ha/defaults/main.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- - -working_dir: "/home/stack" -validate_ha_logs_dir: "{{ working_dir }}/validate_ha_logs" -overcloud_working_dir: "/home/heat-admin" - -validate_ha_heat_environment: "validate-ha-heat-environment.yaml.j2" -validate_ha_heat_template: "validate-ha-heat-template.yaml.j2" -validate_ha_heat_instance_image_format: "qcow2" -validate_ha_heat_instance_image_location: "http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img" -validate_ha_heat_instance_volume_gb: 1 - -private_net_name: "private-network" -private_subnet_name: "private-subnet" -public_net_name: "public-network" -public_subnet_name: "public-subnet" -private_net_cidr: "10.1.1.0/24" -public_physical_network: "datacentre" -public_network_type: "flat" -floating_ip_cidr: "{{ undercloud_network_cidr|default('192.0.2.0/24') }}" -floating_ip_start: "{{ floating_ip_cidr|nthhost(100) }}" -floating_ip_end: "{{ floating_ip_cidr|nthhost(120) }}" -external_network_gateway: "{{ floating_ip_cidr|nthhost(1) }}" - -latency_ms: 0 diff --git a/roles/validate-ha/tasks/ha-test-suite.yml b/roles/validate-ha/tasks/ha-test-suite.yml deleted file mode 100644 index e192b2e..0000000 --- a/roles/validate-ha/tasks/ha-test-suite.yml +++ /dev/null @@ -1,26 +0,0 @@ ---- - -# Execute ha-test-suite test -- block: - - name: Testing {{ ha_test_name }} with recovery {{ ha_recovery_name }}" - delegate_to: "{{ groups.controller[0] }}" - shell: > - {{ overcloud_working_dir }}/ha-test-suite/ha-test-suite.sh \ - -t {{ overcloud_working_dir }}/ha-test-suite/test/{{ ha_test_name }} \ - -r {{ overcloud_working_dir }}/ha-test-suite/recovery/{{ ha_recovery_name }} - register: ha_test_cmd - - - include_tasks: heat-validation-create.yml - - include_tasks: heat-validation-check.yml - - include_tasks: heat-validation-delete.yml - - vars: - stack_name: "stack_{{ ha_test_name }}" - - always: - - name: Copy stdout for test {{ ha_test_name }} to undercloud - copy: content="{{ ha_test_cmd.stdout }}" dest="{{ validate_ha_logs_dir }}/{{ ha_test_name }}_stdout.log" - rescue: - - name: Copy stderr for test {{ ha_test_name }} to undercloud - copy: content="{{ ha_test_cmd.stderr }}" dest="{{ validate_ha_logs_dir }}/{{ ha_test_name }}_stderr.log" - - fail: msg="{{ ha_test_cmd.stderr }}" diff --git a/roles/validate-ha/tasks/heat-validation-check.yml b/roles/validate-ha/tasks/heat-validation-check.yml deleted file mode 100644 index a60397a..0000000 --- a/roles/validate-ha/tasks/heat-validation-check.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- - -- name: Wait up to five minutes for the instance to be reachable - wait_for: - host: "{{ vars[ stack_name + '_instance_ip'].stdout }}" - port: 22 - timeout: 300 diff --git a/roles/validate-ha/tasks/heat-validation-create.yml b/roles/validate-ha/tasks/heat-validation-create.yml deleted file mode 100644 index 7a182f0..0000000 --- a/roles/validate-ha/tasks/heat-validation-create.yml +++ /dev/null @@ -1,30 +0,0 @@ ---- - -- name: Load image in Glance to be used by Heat - shell: | - source {{ working_dir }}/overcloudrc - openstack image create \ - --disk-format {{ validate_ha_heat_instance_image_format }} \ - --file {{ working_dir }}/{{ heat_image_name }} \ - --format value \ - --column "id" \ - validate_ha_image > \ - {{ validate_ha_logs_dir }}/{{ ha_test_name }}_image-create.log 2>&1 - -- name: Execute environment validation via Heat - shell: | - source {{ working_dir }}/overcloudrc - openstack stack create \ - --environment validate-ha-heat-environment.yaml \ - --template validate-ha-heat-template.yaml \ - --wait \ - {{ stack_name }} > \ - {{ validate_ha_logs_dir }}/{{ ha_test_name }}_heat-create.log 2>&1 - -- name: Get instance IP - shell: | - source {{ working_dir }}/overcloudrc - openstack stack show -c outputs -f json {{ stack_name }} | \ - jq --raw-output '.outputs[] | select( .output_key == "server_public_ip") | .output_value' 2>&1 | \ - tee {{ validate_ha_logs_dir }}/{{ ha_test_name }}_heat-instance-ip.log - register: "{{ stack_name }}_instance_ip" diff --git a/roles/validate-ha/tasks/heat-validation-delete.yml b/roles/validate-ha/tasks/heat-validation-delete.yml deleted file mode 100644 index a17bf35..0000000 --- a/roles/validate-ha/tasks/heat-validation-delete.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- - -- name: Clean the created stack - shell: | - source {{ working_dir }}/overcloudrc - openstack stack delete \ - --yes \ - --wait \ - {{ stack_name }} > \ - {{ validate_ha_logs_dir }}/{{ ha_test_name }}_heat-delete.log 2>&1 - -- name: Clean image in Glance - shell: | - source {{ working_dir }}/overcloudrc - openstack image delete validate_ha_image > \ - {{ validate_ha_logs_dir }}/{{ ha_test_name }}_image-delete.log 2>&1 diff --git a/roles/validate-ha/tasks/main.yml b/roles/validate-ha/tasks/main.yml deleted file mode 100644 index ebcffba..0000000 --- a/roles/validate-ha/tasks/main.yml +++ /dev/null @@ -1,147 +0,0 @@ ---- - -- name: Include test sequence depending on release - include_vars: - dir: "vars" - files_matching: "test_list_{{ release }}.yml" - -- name: Create directory on the undercloud to store test results - file: path={{ validate_ha_logs_dir }} state=directory - -- name: Copy ha-test-suite on controllers - shell: > - {% if (undercloud_user == 'zuul') and (zuul.projects is defined) -%} - /usr/bin/rsync --delay-updates -F --compress --archive -e 'ssh -F {{ local_working_dir }}/ssh.config.ansible' /home/{{ undercloud_user }}/src/opendev.org/openstack/tripleo-ha-utils/tools/ha-test-suite {{ hostvars[item]['ansible_hostname'] }}: - {%- else -%} - /usr/bin/rsync --delay-updates -F --compress --archive -e 'ssh -F {{ local_working_dir }}/ssh.config.ansible' {{ local_working_dir }}/tripleo-ha-utils/tools/ha-test-suite {{ hostvars[item]['ansible_hostname'] }}: - {%- endif -%} - delegate_to: "localhost" - with_items: - - "{{ groups['controller'] }}" - -- name: Apply latency (if defined) - vars: - latency_action: "add" - include_tasks: manage-latency.yml - when: latency_ms|int > 0 - -- name: Create the environment template on undercloud - template: - src: "{{ validate_ha_heat_environment }}" - dest: "{{ working_dir }}/validate-ha-heat-environment.yaml" - mode: 0600 - -- name: Create the test template on undercloud - template: - src: "{{ validate_ha_heat_template }}" - dest: "{{ working_dir }}/validate-ha-heat-template.yaml" - mode: 0600 - -- name: Download and uncompress (if necessary) image file for Heat - shell: | - image_url="{{ validate_ha_heat_instance_image_location }}" - image_file=$(basename $image_url) - - curl -s -o $image_file $image_url - - case "$image_file" in - *.tar) - image_name=$(tar xvf $image_file) - ;; - *.tar.gz|*.tgz) - image_name=$(tar xzvf $image_file) - ;; - *.tar.bz2|*.tbz2) - image_name=$(tar xjvf $image_file) - ;; - *.tar.xz|*.txz) - image_name=$(tar xJf $image_file) - ;; - *.bz2) - bunzip2 --force --quiet $image_file - image_name=${image_file%.*}; - ;; - *.gz) - gunzip --force --quiet $image_file - image_name=${image_file%.*}; - ;; - *.xz) - xz --force --quiet --decompress $image_file - image_name=${image_file%.*}; - ;; - *) image_name=$image_file - ;; - esac - - echo $image_name - register: image_name - -- set_fact: - heat_image_name: "{{ image_name.stdout }}" - -# Test: failed actions -- name: HA test - Failed actions - vars: - ha_test_name: "test_ha_failed_actions" - ha_recovery_name: "" - include_tasks: ha-test-suite.yml - when: test_ha_failed_actions|bool - -# Test: Master/Slave -- name: HA test - Master/Slave core resource stop and start - vars: - ha_test_name: "test_master-slave" - ha_recovery_name: "recovery_master-slave" - include_tasks: ha-test-suite.yml - when: test_ha_master_slave|bool - -# Test: Keystone stop -- name: HA test - Keystone stop - vars: - ha_test_name: "test_keystone-stop" - ha_recovery_name: "recovery_keystone-stop" - include_tasks: ha-test-suite.yml - when: test_ha_keystone_stop|bool - -# Test: Keystone removal -- name: HA test - Keystone constraint removal - vars: - ha_test_name: "test_keystone-constraint-removal" - ha_recovery_name: "recovery_keystone-constraint-removal" - include_tasks: ha-test-suite.yml - when: test_ha_keystone_constraint_removal|bool - -# Test: NG A -- name: HA test - Pacemaker light test A - vars: - ha_test_name: "test_pacemaker-light-a" - ha_recovery_name: "recovery_pacemaker-light" - include_tasks: ha-test-suite.yml - when: test_ha_ng_a|bool - -# Test: NG B -- name: HA test - Pacemaker light test B - vars: - ha_test_name: "test_pacemaker-light-b" - ha_recovery_name: "recovery_pacemaker-light" - include_tasks: ha-test-suite.yml - when: test_ha_ng_b|bool - -# Test: NG C -- name: HA test - Pacemaker light test C - vars: - ha_test_name: "test_pacemaker-light-c" - ha_recovery_name: "recovery_pacemaker-light" - include_tasks: ha-test-suite.yml - when: test_ha_ng_c|bool - -- name: Remove image file - file: - path: "{{ working_dir }}/{{ heat_image_name }}" - state: absent - -- name: Remove latency (if defined) - vars: - latency_action: "del" - include_tasks: manage-latency.yml - when: latency_ms|int > 0 diff --git a/roles/validate-ha/tasks/manage-latency.yml b/roles/validate-ha/tasks/manage-latency.yml deleted file mode 100644 index fe1ac2e..0000000 --- a/roles/validate-ha/tasks/manage-latency.yml +++ /dev/null @@ -1,12 +0,0 @@ -# Manage latency on all nodes -- name: "Manage latency on all nodes" - shell: | - /usr/sbin/tc qdisc {{ latency_action }} dev {{ latency_eth_interface }} root netem delay {{ latency_ms }}ms - delegate_to: "{{ item }}" - become: true - with_items: - - "{{ groups['overcloud'] }}" - when: - - latency_action in [ "add", "del" ] - - latency_eth_interface is defined - - latency_ms|int > 0 diff --git a/roles/validate-ha/templates/validate-ha-heat-environment.yaml.j2 b/roles/validate-ha/templates/validate-ha-heat-environment.yaml.j2 deleted file mode 100644 index 1a85561..0000000 --- a/roles/validate-ha/templates/validate-ha-heat-environment.yaml.j2 +++ /dev/null @@ -1,13 +0,0 @@ -# Heat template parameters -parameters: - private_net_name: "{{ private_net_name }}" - private_subnet_name: "{{ private_subnet_name }}" - private_net_cidr: "{{ private_net_cidr }}" - public_net_name: "{{ public_net_name }}" - public_subnet_name: "{{ public_subnet_name }}" - public_physical_network: "{{ public_physical_network }}" - public_network_type: "{{ public_network_type }}" - public_net_cidr: "{{ floating_ip_cidr }}" - public_net_gateway: "{{ public_net_gateway }}" - public_net_pool_start: "{{ public_net_pool_start }}" - public_net_pool_end: "{{ public_net_pool_end }}" diff --git a/roles/validate-ha/templates/validate-ha-heat-template.yaml.j2 b/roles/validate-ha/templates/validate-ha-heat-template.yaml.j2 deleted file mode 100644 index 5229696..0000000 --- a/roles/validate-ha/templates/validate-ha-heat-template.yaml.j2 +++ /dev/null @@ -1,192 +0,0 @@ -heat_template_version: 2016-10-14 -description: spawning a server - -parameters: - private_net_name: - type: string - default: "private" - description: Name of private network into which servers get deployed - private_subnet_name: - type: string - default: private_subnet - description: Name of private subnet into which servers get deployed - private_net_cidr: - type: string - description: Private network address (CIDR notation) - public_physical_network: - type: string - default: "datacentre" - description: Physical network name - public_network_type: - type: string - default: "flat" - description: Type of the physical network (flat or vlan) - constraints: - - allowed_values: - - vlan - - flat - public_net_name: - type: string - default: public - description: Name of public network into which servers get deployed - public_subnet_name: - type: string - default: public_subnet - description: Name of public subnet into which servers get deployed - public_net_cidr: - type: string - description: Public network address (CIDR notation) - public_net_gateway: - type: string - description: Public network gateway address - public_net_pool_start: - type: string - description: Start of public network IP address allocation pool - public_net_pool_end: - type: string - description: End of public network IP address allocation pool - -resources: - - ########### - # Network # - ########### - - private_net: - type: OS::Neutron::Net - properties: - name: { get_param: private_net_name } - - private_subnet: - type: OS::Neutron::Subnet - properties: - name: { get_param: private_subnet_name } - network_id: { get_resource: private_net } - cidr: { get_param: private_net_cidr } - - public_net: - type: OS::Neutron::ProviderNet - properties: - name: { get_param: public_net_name } - router_external: true - physical_network: { get_param: public_physical_network } - network_type: { get_param: public_network_type } - - public_subnet: - type: OS::Neutron::Subnet - properties: - name: { get_param: public_subnet_name } - network_id: { get_resource: public_net } - cidr: { get_param: public_net_cidr } - gateway_ip: { get_param: public_net_gateway } - allocation_pools: - - start: { get_param: public_net_pool_start } - end: { get_param: public_net_pool_end } - - router: - type: OS::Neutron::Router - properties: - external_gateway_info: - network: { get_resource: public_net } - - router_interface: - type: OS::Neutron::RouterInterface - properties: - router_id: { get_resource: router } - subnet_id: { get_resource: private_subnet } - - public_net_port: - type: OS::Neutron::Port - properties: - network: { get_resource: private_net } - fixed_ips: - - subnet: { get_resource: private_subnet } - security_groups: [{ get_resource: public_security_group }] - - public_floating_ip: - type: OS::Neutron::FloatingIP - properties: - floating_network: { get_resource: public_net } - port_id: { get_resource: public_net_port } - - public_security_group: - type: OS::Neutron::SecurityGroup - properties: - description: Add security group rules for the multi-tier architecture - name: pingandssh - rules: - - remote_ip_prefix: 0.0.0.0/0 - protocol: tcp - port_range_min: 22 - port_range_max: 22 - - remote_ip_prefix: 0.0.0.0/0 - protocol: tcp - port_range_min: 80 - port_range_max: 80 - - remote_ip_prefix: 0.0.0.0/0 - protocol: icmp - - ########### - # Volume # - ########### - - instance_volume: - type: OS::Cinder::Volume - properties: - name: "instance_volume" - size: {{ validate_ha_heat_instance_volume_gb }} - image: "validate_ha_image" - - ########### - # Keypair # - ########### - - instance_keypair: - type: OS::Nova::KeyPair - properties: - name: "instance_keypair" - save_private_key: "true" - - ########### - # Flavor # - ########### - - instance_flavor: - type: OS::Nova::Flavor - properties: - name: "instance_flavor" - ephemeral: 0 - ram: 2048 - disk: 10 - vcpus: 2 - - ########### - # Server # - ########### - - instance: - type: OS::Nova::Server - properties: - name: "validate_ha_instance" - flavor: { get_resource: instance_flavor } - key_name: { get_resource: instance_keypair } - networks: - - port: { get_resource: public_net_port } - block_device_mapping: [{ device_name: "vda", volume_id : { get_resource : instance_volume }, delete_on_termination : "true" }] - -outputs: - server_private_ip: - description: IP address of first web server in private network - value: { get_attr: [ instance, first_address ] } - - server_public_ip: - description: Floating IP address of the web server - value: { get_attr: [ public_floating_ip, floating_ip_address ] } - - public_key: - description: The public key of the keypair. - value: { get_attr: [instance_keypair, public_key] } - - private_key: - description: The private key of the keypair. - value: { get_attr: [instance_keypair, private_key] } diff --git a/roles/validate-ha/vars/test_list_liberty.yml b/roles/validate-ha/vars/test_list_liberty.yml deleted file mode 100644 index b14ce36..0000000 --- a/roles/validate-ha/vars/test_list_liberty.yml +++ /dev/null @@ -1,7 +0,0 @@ -test_ha_failed_actions: true -test_ha_master_slave: true -test_ha_keystone_stop: true -test_ha_keystone_constraint_removal: false -test_ha_ng_a: false -test_ha_ng_b: false -test_ha_ng_c: false diff --git a/roles/validate-ha/vars/test_list_master.yml b/roles/validate-ha/vars/test_list_master.yml deleted file mode 120000 index 431cbf0..0000000 --- a/roles/validate-ha/vars/test_list_master.yml +++ /dev/null @@ -1 +0,0 @@ -test_list_rocky.yml \ No newline at end of file diff --git a/roles/validate-ha/vars/test_list_mitaka.yml b/roles/validate-ha/vars/test_list_mitaka.yml deleted file mode 100644 index acf6c91..0000000 --- a/roles/validate-ha/vars/test_list_mitaka.yml +++ /dev/null @@ -1,7 +0,0 @@ -test_ha_failed_actions: true -test_ha_master_slave: true -test_ha_keystone_stop: false -test_ha_keystone_constraint_removal: true -test_ha_ng_a: false -test_ha_ng_b: false -test_ha_ng_c: false diff --git a/roles/validate-ha/vars/test_list_newton.yml b/roles/validate-ha/vars/test_list_newton.yml deleted file mode 100644 index 404b481..0000000 --- a/roles/validate-ha/vars/test_list_newton.yml +++ /dev/null @@ -1,7 +0,0 @@ -test_ha_failed_actions: true -test_ha_master_slave: true -test_ha_keystone_stop: false -test_ha_keystone_constraint_removal: false -test_ha_ng_a: true -test_ha_ng_b: true -test_ha_ng_c: true diff --git a/roles/validate-ha/vars/test_list_ocata.yml b/roles/validate-ha/vars/test_list_ocata.yml deleted file mode 100644 index 404b481..0000000 --- a/roles/validate-ha/vars/test_list_ocata.yml +++ /dev/null @@ -1,7 +0,0 @@ -test_ha_failed_actions: true -test_ha_master_slave: true -test_ha_keystone_stop: false -test_ha_keystone_constraint_removal: false -test_ha_ng_a: true -test_ha_ng_b: true -test_ha_ng_c: true diff --git a/roles/validate-ha/vars/test_list_pike.yml b/roles/validate-ha/vars/test_list_pike.yml deleted file mode 100644 index 404b481..0000000 --- a/roles/validate-ha/vars/test_list_pike.yml +++ /dev/null @@ -1,7 +0,0 @@ -test_ha_failed_actions: true -test_ha_master_slave: true -test_ha_keystone_stop: false -test_ha_keystone_constraint_removal: false -test_ha_ng_a: true -test_ha_ng_b: true -test_ha_ng_c: true diff --git a/roles/validate-ha/vars/test_list_queens.yml b/roles/validate-ha/vars/test_list_queens.yml deleted file mode 100644 index 404b481..0000000 --- a/roles/validate-ha/vars/test_list_queens.yml +++ /dev/null @@ -1,7 +0,0 @@ -test_ha_failed_actions: true -test_ha_master_slave: true -test_ha_keystone_stop: false -test_ha_keystone_constraint_removal: false -test_ha_ng_a: true -test_ha_ng_b: true -test_ha_ng_c: true diff --git a/roles/validate-ha/vars/test_list_rhos-10.yml b/roles/validate-ha/vars/test_list_rhos-10.yml deleted file mode 120000 index cbce750..0000000 --- a/roles/validate-ha/vars/test_list_rhos-10.yml +++ /dev/null @@ -1 +0,0 @@ -test_list_newton.yml \ No newline at end of file diff --git a/roles/validate-ha/vars/test_list_rhos-11.yml b/roles/validate-ha/vars/test_list_rhos-11.yml deleted file mode 120000 index f088fd5..0000000 --- a/roles/validate-ha/vars/test_list_rhos-11.yml +++ /dev/null @@ -1 +0,0 @@ -test_list_ocata.yml \ No newline at end of file diff --git a/roles/validate-ha/vars/test_list_rhos-12.yml b/roles/validate-ha/vars/test_list_rhos-12.yml deleted file mode 120000 index a6b7c88..0000000 --- a/roles/validate-ha/vars/test_list_rhos-12.yml +++ /dev/null @@ -1 +0,0 @@ -test_list_pike.yml \ No newline at end of file diff --git a/roles/validate-ha/vars/test_list_rhos-13.yml b/roles/validate-ha/vars/test_list_rhos-13.yml deleted file mode 120000 index c3e8e4e..0000000 --- a/roles/validate-ha/vars/test_list_rhos-13.yml +++ /dev/null @@ -1 +0,0 @@ -test_list_queens.yml \ No newline at end of file diff --git a/roles/validate-ha/vars/test_list_rhos-8.yml b/roles/validate-ha/vars/test_list_rhos-8.yml deleted file mode 120000 index f0df72d..0000000 --- a/roles/validate-ha/vars/test_list_rhos-8.yml +++ /dev/null @@ -1 +0,0 @@ -test_list_liberty.yml \ No newline at end of file diff --git a/roles/validate-ha/vars/test_list_rhos-9.yml b/roles/validate-ha/vars/test_list_rhos-9.yml deleted file mode 120000 index 56df953..0000000 --- a/roles/validate-ha/vars/test_list_rhos-9.yml +++ /dev/null @@ -1 +0,0 @@ -test_list_mitaka.yml \ No newline at end of file diff --git a/roles/validate-ha/vars/test_list_rocky.yml b/roles/validate-ha/vars/test_list_rocky.yml deleted file mode 100644 index 404b481..0000000 --- a/roles/validate-ha/vars/test_list_rocky.yml +++ /dev/null @@ -1,7 +0,0 @@ -test_ha_failed_actions: true -test_ha_master_slave: true -test_ha_keystone_stop: false -test_ha_keystone_constraint_removal: false -test_ha_ng_a: true -test_ha_ng_b: true -test_ha_ng_c: true diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index b159d03..0000000 --- a/setup.cfg +++ /dev/null @@ -1,38 +0,0 @@ -[metadata] -name = tripleo-ha-utils -summary = Give a set of tools to test TripleO HA capabilities -description_file = -long_description_content_type = text/markdown - README.md -author = Raoul Scarazzini -author_email = rasca@redhat.com -home_page = https://github.com/openstack/tripleo-ha-utils/ -classifier = - License :: OSI Approved :: Apache Software License - Development Status :: 4 - Beta - Intended Audience :: Developers - Intended Audience :: System Administrators - Intended Audience :: Information Technology - Topic :: Utilities - -[build_sphinx] -all_files = 1 -build-dir = doc/build -source-dir = doc/source - -[global] -setup-hooks = - pbr.hooks.setup_hook - -[files] -data_files = - config = config/* - playbooks = playbooks/* - usr/local/share/ansible/roles = roles/* - -[wheel] -universal = 1 - -[pbr] -skip_authors = True -skip_changelog = True diff --git a/setup.py b/setup.py deleted file mode 100644 index 58ffb52..0000000 --- a/setup.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright Red Hat, Inc. All Rights Reserved. -# -# 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. - -import setuptools - -setuptools.setup( - setup_requires=['pbr'], - py_modules=[], - pbr=True) diff --git a/tools/ha-test-suite/README.md b/tools/ha-test-suite/README.md deleted file mode 100644 index 7ddbdc0..0000000 --- a/tools/ha-test-suite/README.md +++ /dev/null @@ -1,145 +0,0 @@ -# OpenStack TripleO HA Test Suite - -This project is a modular and a customizable test suite to be applied in an -Overcloud OpenStack environment deployed via TripleO upstream or Red Hat -OpenStack Director (OSPd). - -## Usage - -The script needs at least a test file (-t) which must contain the sequence of -the operations to be done. A recovery file (-r), with the sequence of the -operations needed to recovery the environment can also be passed. So a typical -invocation will be something like this: - -```console -[heat-admin@overcloud-controller-0 overcloud-ha-test-suite]$ ./overcloud-ha-test-suite.sh -t test/test_keystone-constraint-removal -r recovery/recovery_keystone-constraint-removal -Fri May 20 15:27:19 UTC 2016 - Populationg overcloud elements...OK -Fri May 20 15:27:22 UTC 2016 - Test: Stop keystone resource (by stopping httpd), check no other resource is stopped -Fri May 20 15:27:22 UTC 2016 * Step 1: disable keystone resource via httpd stop -Fri May 20 15:27:22 UTC 2016 - Performing action disable on resource httpd ..OK -Fri May 20 15:27:26 UTC 2016 - List of cluster's failed actions: -Cluster is OK. -Fri May 20 15:27:29 UTC 2016 * Step 2: check resource status -Fri May 20 15:27:29 UTC 2016 - Cycling for 10 minutes polling every minute the status of the resources -Fri May 20 15:28:29 UTC 2016 - Polling... -delay -> OK -galera -> OK -... -... -openstack-sahara-engine -> OK -rabbitmq -> OK -redis -> OK -Fri May 20 15:41:00 UTC 2016 - List of cluster's failed actions: -Cluster is OK. -Fri May 20 15:41:03 UTC 2016 - Waiting 10 seconds to recover environment -Fri May 20 15:41:13 UTC 2016 - Recovery: Enable keystone via httpd and check for failed actions -Fri May 20 15:41:13 UTC 2016 * Step 1: enable keystone resource via httpd -Fri May 20 15:41:13 UTC 2016 - Performing action enable on resource httpd-clone OK -Fri May 20 15:41:15 UTC 2016 - List of cluster's failed actions: -Cluster is OK. -Fri May 20 15:41:17 UTC 2016 - End -``` - -The exit status will depend on the result of the operations. If a disable -operation fails, if failed actions will appear, if recovery does not ends with -success exit status will not be 0. - -## Test and recoveries - -Test and recovery are bash script portions that are -included inside the main script. Some functions and variables are available to -help on recurring operations. These functions are listed here: - -- **check_failed_actions**: will print failed actions and return error in case - some of them are present; -- **check_resources_process_status**: will check for the process status of the - resources on the system (not in the cluster), i.e. will check if there is a - process for mysql daemon; -- **wait_resource_status**: will wail until a default timeout - ($RESOURCE_CHANGE_STATUS_TIMEOUT) for a resource to reach a status; -- **check_resource_status**: will check a resource status, i.e. if you want to - check if httpd resource is started; -- **wait_cluster_start**: will wait the until a timeout - ($RESOURCE_CHANGE_STATUS_TIMEOUT) to be started, specifically will wait for - all resources to be in state "Started"; -- **play_on_resources**: will set the status of a resource; - -The variables are: - -- **OVERCLOUD_CORE_RESOURCES**: which are galera and rabbitmq -- **OVERCLOUD_RESOURCES**: which are *all* the resources -- **OVERCLOUD_SYSTEMD_RESOURCES**: which are the resources managed via systemd - by pacemaker; - -And can be used in combination to wrote test and recovery files. - -### Test file contents - -A typical test file, say test/test_keystone-constraint-removal, will contain -something like this: - -```bash -# Test: Stop keystone resource (by stopping httpd), check no other resource is stopped - -echo "$(date) * Step 1: disable keystone resource via httpd stop" -play_on_resources "disable" "httpd" - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions - -echo "$(date) * Step 2: check resource status" -# Define resource list without httpd -OVERCLOUD_RESOURCES_NO_KEYSTONE="$(echo $OVERCLOUD_RESOURCES | sed 's/httpd/ /g')" -# Define number of minutes to look for status -MINUTES=10 -# Cycling for $MINUTES minutes polling every minute the status of the resources -echo "$(date) - Cycling for 10 minutes polling every minute the status of the resources" -i=0 -while [ $i -lt $MINUTES ] - do - # Wait a minute - sleep 60 - echo "$(date) - Polling..." - for resource in $OVERCLOUD_RESOURCES_NO_KEYSTONE - do - echo -n "$resource -> " - check_resource_status "$resource" "Started" - [ $? -eq 0 ] && echo "OK" || (FAILURES=1; echo "Error!") - done - let "i++" - done - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions -``` - -Code is commented and should be self explaining, but in short: -- the first commented line, after "# Test: " is read as test title; -- using play_on_resources it disables httpd resource; -- it checks for failed actions; -- it defines a list of variable named OVERCLOUD_RESOURCES_NO_KEYSTONE containing - all the variable but httpd; -- it cycles for 10 minutes, polling every minute the status of all the - resources; - -If any of these steps for some reason fails, then the overall test will be -considered failed and the exit status will not be 0. - -### Recovery file contents - -A typical recovery file, say recovery/recovery_keystone-constraint-removal, -will contain something like this: - -```bash -# Recovery: Enable keystone via httpd and check for failed actions - -echo "$(date) * Step 1: enable keystone resource via httpd" -play_on_resources "enable" "httpd-clone" - -echo "$(date) - List of cluster's failed actions:" check_failed_actions -``` - -Again: -- the first commented line, after "# Recovery: " is read as recovery title; -- using play_on_resources it enables httpd resource; -- it checks for failed actions; diff --git a/tools/ha-test-suite/ha-test-suite.sh b/tools/ha-test-suite/ha-test-suite.sh deleted file mode 100755 index 13b900e..0000000 --- a/tools/ha-test-suite/ha-test-suite.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash - -# Raoul Scarazzini (rasca@redhat.com) -# This script provides a testing suite for TripleO HA environments - -# Define main workdir -WORKDIR=$(dirname $0) - -# Source function library. -. $WORKDIR/include/functions - -# Fixed parameters -# How much time wait in seconds for a resource to change status (i.e. from started to stopped) -RESOURCE_CHANGE_STATUS_TIMEOUT=600 -# How much time wait in seconds before starting recovery -DEFAULT_RECOVERY_WAIT_TIME=10 - -# Command line parameters -if [ $# -gt 0 ] - then - while :; do - case $1 in - -h|-\?|--help) - usage - exit - ;; - -t|--test) - test_sequence="$2" - shift - ;; - -r|--recover) - recovery_sequence="$2" - shift - ;; - --) - shift - break - ;; - -?*) - usage - exit 1 - ;; - *) - break - esac - - shift - done - else - usage - exit 1 -fi - -# Populating overcloud elements -echo -n "$(date) - Populationg overcloud elements..." -OVERCLOUD_CORE_RESOURCES="galera redis rabbitmq" -OVERCLOUD_RESOURCES=$(sudo pcs resource show | egrep '^ (C|[a-Z])' | sed 's/.* \[\(.*\)\]/\1/g' | sed 's/ \(.*\)(.*):.*/\1/g' | sort) -OVERCLOUD_SYSTEMD_RESOURCES=$(sudo pcs config show | egrep "Resource:.*systemd"|grep -v "haproxy"|awk '{print $2}') -echo "OK" - -if [ -f "$test_sequence" ] - then - echo "$(date) - Test: $(grep '^#.*Test:' $test_sequence | sed 's/^#.*Test: //')" - . $test_sequence - else - echo "No test file passed or unable to read test file." -fi - -if [ -f "$recovery_sequence" ] - then - echo "$(date) - Waiting $DEFAULT_RECOVERY_WAIT_TIME seconds to recover environment" - sleep $DEFAULT_RECOVERY_WAIT_TIME - - echo "$(date) - Recovery: $(grep '^#.*Recovery:' $recovery_sequence | sed 's/^#.*Recovery: //')" - . $recovery_sequence - else - echo "No recovery file passed or unable to read recovery file." -fi - -echo "$(date) - End" diff --git a/tools/ha-test-suite/include/functions b/tools/ha-test-suite/include/functions deleted file mode 100755 index 765a0e3..0000000 --- a/tools/ha-test-suite/include/functions +++ /dev/null @@ -1,151 +0,0 @@ -# Raoul Scarazzini (rasca@redhat.com) -# This script provides a testing suite from TripleO/Directory OpenStack HA (so -# with Pacemaker) environments functions to be used inside TripleO/Director -# OpenStack HA environments - -function usage { - echo "Usage $0 -t [-r ] [-u] --t, --test Specify which file contains the test to run --r, --recover Specify which file (if any) should be used for recovery --u, --undercloud Test will be performed on undercloud -" -} - -function check_failed_actions { - resource=$1 - - sudo pcs status | grep "Failed Actions:" &> /dev/null - if [ $? -eq 0 ] - then - if [ "x$resource" == "x" ] - then - echo "Cluster has failed actions:" - sudo pcs status | sed -n -e '/Failed Actions:/,/^$/p' | egrep 'OCF_|not running|unknown' | awk '{print $2}' | cut -f1 -d_ | sort |uniq - exit 1 - else - errors=$(sudo pcs status | sed -n -e '/Failed Actions:/,/^$/p' | grep -A1 $resource) - if [ $? -eq 0 ] - then - echo "Resource $resource has failed actions:" - echo $errors - exit 1 - else - echo "No failed actions for $resource." - return 0 - fi - fi - else - [ "x$resource" == "x" ] && echo "Cluster is OK." || echo "No failed actions for $resource." - return 0 - fi -} - -function check_resources_process_status { - for resource in $OVERCLOUD_RESOURCES - do - echo -n "$resource -> " - - case $resource in - ip-*) #ip_addr=$(pcs resource show $resource | grep Attributes | sed 's/.*ip=\(.*\) cidr.*/\1/g') - ip_addr=$(echo $resource | sed 's/ip-//g') - sudo ip a s | grep $ip_addr &> /dev/null - ;; - rabbitmq) sudo /usr/sbin/rabbitmqctl cluster_status &> /dev/null - ;; - redis) pidof /usr/bin/redis-server &> /dev/null - ;; - galera) pidof /usr/libexec/mysqld &> /dev/null - ;; - *cleanup*|delay) echo -n "no need to check if it's " - ;; - *) systemctl is-active $resource &> /dev/null - ;; - esac - - [ $? -eq 0 ] && echo "active" || echo "inactive" - - done -} - -function wait_resource_status { - resource=$1 - status=$2 - i=1 - - while [ $i -lt $RESOURCE_CHANGE_STATUS_TIMEOUT ] - do - output=$(sudo pcs status resources | sed -n -e "/\(Clone\|Master\/Slave\) Set: .*\[$resource\]/,/^ [a-Z]/p" | head -n -1 | tail -n +2 | egrep -v "$status\:") - if [ "x$output" == "x" ] - then - return 0 - break - else - echo -n "." - sleep 1 - let "i++" - fi - done - check_failed_actions - exit 1 -} - -function check_resource_status { - resource=$1 - status=$2 - - output=$(sudo pcs status resources | sed -n -e "/\(Clone\|Master\/Slave\) Set: .*\[$resource\]/,/^ [a-Z]/p" | head -n -1 | tail -n +2 | egrep -v "$status\:") - # Since we are checking a specific status, if we have output from above it - # means that for some reason the resource is not in the state we are expecting - [ "x$output" == "x" ] && return 0 || (check_failed_actions; exit 1) -} - -function wait_cluster_start { - i=1 - while true; do - [ $i -eq $RESOURCE_CHANGE_STATUS_TIMEOUT ] && break - - # Check for failed actions - sudo pcs status | egrep "Failed" &> /dev/null - [ $? -eq 0 ] && break - - # If we have stopped resources let's wait - sudo pcs status | egrep "Stopped" &> /dev/null - if [ $? -eq 0 ] - then - echo -n "." - else - echo "All cluster resources are started." - return 0 - break - fi - sleep 1 - let "i++" - done - - # If we are here than we have problems: we hit timeout or we still have - # stopped resources - echo "Problems found. There are stopped or failed resources!" - check_failed_actions - exit 1 -} - -function play_on_resources { - action=$1 - resources=$2 - - for resource in $resources - do - echo -n "$(date) - Performing action $action on resource $resource " - # Do the action on the resource - sudo pcs resource $action $resource --wait=$RESOURCE_CHANGE_STATUS_TIMEOUT - if [ $? -ne 0 ] - then - echo "FAILURE!" - check_failed_actions $resource - exit 1 - else - echo "OK" - fi - done - return 0 -} diff --git a/tools/ha-test-suite/recovery/recovery_entire-cluster b/tools/ha-test-suite/recovery/recovery_entire-cluster deleted file mode 100644 index 05e539a..0000000 --- a/tools/ha-test-suite/recovery/recovery_entire-cluster +++ /dev/null @@ -1,13 +0,0 @@ -# Recovery: Enable all systemd and core resources, cleanup failed actions - -echo "$(date) * Step 1: enable all the cluster resources" -play_on_resources "enable" "$OVERCLOUD_RESOURCES" - -echo "$(date) * Step 2: Cleaning up failed resources" -sudo pcs status | sed -n -e '/Failed Actions:/,/^$/p' | egrep 'OCF_TIMEOUT|not running' | awk '{print $2}' | cut -f1 -d_ | sort | uniq | while read RES; do echo "Cleaning $RES"; sudo pcs resource cleanup $RES; done - -echo "$(date) * Step 3: Waiting all resources to start" -wait_cluster_start - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions diff --git a/tools/ha-test-suite/recovery/recovery_keystone-constraint-removal b/tools/ha-test-suite/recovery/recovery_keystone-constraint-removal deleted file mode 100644 index 312e41a..0000000 --- a/tools/ha-test-suite/recovery/recovery_keystone-constraint-removal +++ /dev/null @@ -1,7 +0,0 @@ -# Recovery: Enable keystone via httpd and check for failed actions - -echo "$(date) * Step 1: enable keystone resource via httpd" -play_on_resources "enable" "httpd-clone" - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions diff --git a/tools/ha-test-suite/recovery/recovery_keystone-stop b/tools/ha-test-suite/recovery/recovery_keystone-stop deleted file mode 100644 index 91385bf..0000000 --- a/tools/ha-test-suite/recovery/recovery_keystone-stop +++ /dev/null @@ -1,10 +0,0 @@ -# Recovery: Enable openstack-keystone and check for failed actions - -echo "$(date) * Step 1: enable openstack-keystone resource" -play_on_resources "enable" "openstack-keystone-clone" - -echo "$(date) - Checking for Stopped resources:" -wait_cluster_start - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions diff --git a/tools/ha-test-suite/recovery/recovery_master-slave b/tools/ha-test-suite/recovery/recovery_master-slave deleted file mode 100644 index df30314..0000000 --- a/tools/ha-test-suite/recovery/recovery_master-slave +++ /dev/null @@ -1,7 +0,0 @@ -# Recovery: Enable master slave resources (galera and redis), all the resources should come up - -echo "$(date) * Step 1: enable galera, redis and rabbitmq" -play_on_resources "enable" "$OVERCLOUD_CORE_RESOURCES" - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions diff --git a/tools/ha-test-suite/recovery/recovery_mongo b/tools/ha-test-suite/recovery/recovery_mongo deleted file mode 100644 index 24825b2..0000000 --- a/tools/ha-test-suite/recovery/recovery_mongo +++ /dev/null @@ -1,7 +0,0 @@ -# Recovery: Enable mongo and check for failed actions - -echo "$(date) * Step 1: enable mongo" -play_on_resources "enable" "mongo" - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions diff --git a/tools/ha-test-suite/recovery/recovery_pacemaker-light b/tools/ha-test-suite/recovery/recovery_pacemaker-light deleted file mode 100644 index fb75da3..0000000 --- a/tools/ha-test-suite/recovery/recovery_pacemaker-light +++ /dev/null @@ -1,13 +0,0 @@ -# Recovery: Enable all systemd and core resources, cleanup failed actions - -echo "$(date) * Step 1: enable core resources" -play_on_resources "enable" "$OVERCLOUD_CORE_RESOURCES" - -echo "$(date) * Step 2: enable all the systemd resources" -play_on_resources "enable" "$OVERCLOUD_SYSTEMD_RESOURCES" - -echo "$(date) * Step 3: Waiting all resources to start" -wait_cluster_start - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions diff --git a/tools/ha-test-suite/recovery/recovery_processes-after-cluster-stop b/tools/ha-test-suite/recovery/recovery_processes-after-cluster-stop deleted file mode 100644 index b129a01..0000000 --- a/tools/ha-test-suite/recovery/recovery_processes-after-cluster-stop +++ /dev/null @@ -1,10 +0,0 @@ -# Recovery: Start cluster again - -echo "$(date) * Step 1: start the cluster" -sudo pcs cluster start --all - -echo "$(date) * Step 2: Waiting all resources to start" -wait_cluster_start - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions diff --git a/tools/ha-test-suite/test/test_check-failed-actions b/tools/ha-test-suite/test/test_check-failed-actions deleted file mode 100644 index 80acc88..0000000 --- a/tools/ha-test-suite/test/test_check-failed-actions +++ /dev/null @@ -1,3 +0,0 @@ -# Test: Wait cluster start and look for failed actions -echo "$(date) - Waiting for cluster start and checking for failed resources:" -wait_cluster_start diff --git a/tools/ha-test-suite/test/test_keystone-constraint-removal b/tools/ha-test-suite/test/test_keystone-constraint-removal deleted file mode 100644 index aee50e9..0000000 --- a/tools/ha-test-suite/test/test_keystone-constraint-removal +++ /dev/null @@ -1,40 +0,0 @@ -# Test: Stop keystone resource (by stopping httpd), check no other resource is stopped - -echo "$(date) * Step 1: disable keystone resource via httpd stop" -play_on_resources "disable" "httpd" - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions - -echo "$(date) * Step 2: check resource status" -# Define resource list without httpd -OVERCLOUD_RESOURCES_NO_KEYSTONE="$(echo $OVERCLOUD_RESOURCES | sed 's/httpd/ /g')" -# Define number of minutes to look for status -MINUTES=10 -# Cycling for $MINUTES minutes polling every minute the status of the resources -echo "$(date) - Cycling for 10 minutes polling every minute the status of the resources" -i=0 -while [ $i -lt $MINUTES ] - do - # Wait a minute - sleep 60 - echo "$(date) - Polling..." - for resource in $OVERCLOUD_RESOURCES_NO_KEYSTONE - do - echo -n "$resource -> " - # If the resource is a multi state like galera or redis, do a different check - case $resource in - "galera") check_resource_status "$resource" "Masters" - ;; - "redis") check_resource_status "$resource" "(Masters|Slaves)" - ;; - *) check_resource_status "$resource" "Started" - ;; - esac - [ $? -eq 0 ] && echo "OK" || (FAILURES=1; echo "Error!"; break) - done - let "i++" - done - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions diff --git a/tools/ha-test-suite/test/test_keystone-stop b/tools/ha-test-suite/test/test_keystone-stop deleted file mode 100644 index 040aeaa..0000000 --- a/tools/ha-test-suite/test/test_keystone-stop +++ /dev/null @@ -1,7 +0,0 @@ -# Test: Stop openstack-keystone and look for failed actions - -echo "$(date) * Step 1: disable openstack-keystone resource" -play_on_resources "disable" "openstack-keystone-clone" - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions diff --git a/tools/ha-test-suite/test/test_master-slave b/tools/ha-test-suite/test/test_master-slave deleted file mode 100644 index 6c2b0bf..0000000 --- a/tools/ha-test-suite/test/test_master-slave +++ /dev/null @@ -1,7 +0,0 @@ -# Test: Stop master slave resources (galera and redis), all the resources should come down - -echo "$(date) * Step 1: disable galera, redis and rabbitmq" -play_on_resources "disable" "$OVERCLOUD_CORE_RESOURCES" - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions diff --git a/tools/ha-test-suite/test/test_mongo-with-aodh-ceilometer b/tools/ha-test-suite/test/test_mongo-with-aodh-ceilometer deleted file mode 100644 index cc8efea..0000000 --- a/tools/ha-test-suite/test/test_mongo-with-aodh-ceilometer +++ /dev/null @@ -1,43 +0,0 @@ -# Test: Stop mongo resource, check related systemd resources are fine - -echo "$(date) * Step 1: disable mongo" -play_on_resources "disable" "mongo" - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions - -echo "$(date) * Step 2: check resource status" -# Define related resources -OVERCLOUD_RESOURCES="openstack-aodh-evaluator openstack-aodh-listener openstack-aodh-notifier openstack-ceilometer-central.service openstack-ceilometer-collector.service openstack-ceilometer-notification.service" -# Define number of minutes to look for status -MINUTES=10 -# Cycling for $MINUTES minutes polling every minute the status of the resources -echo "$(date) - Cycling for 10 minutes polling every minute the status of the resources" -i=0 -while [ $i -lt $MINUTES ] - do - # Wait a minute - sleep 60 - echo "$(date) - Polling..." - for resource in $OVERCLOUD_RESOURCES - do - echo -n "$resource -> " - # Check if the resource is active for the system - systemctl is-active $resource - if [ $? -ne 0 ] - then - # Show status of the resource - echo "Error! Resource $resource is not active anymore." - systemctl status $resource - # Check in any case cluster's failed actions - echo "$(date) - List of cluster's failed actions:" - check_failed_actions - # Now exit with an error - exit 1 - fi - done - let "i++" - done - -# If we are here, test was successful -echo "$(date) - Test was successful" diff --git a/tools/ha-test-suite/test/test_pacemaker-light-a b/tools/ha-test-suite/test/test_pacemaker-light-a deleted file mode 100644 index 7149cf2..0000000 --- a/tools/ha-test-suite/test/test_pacemaker-light-a +++ /dev/null @@ -1,19 +0,0 @@ -# Test: Stop every systemd resource, stop Galera and Rabbitmq, Start every systemd resource - -echo "$(date) * Step 1: disable all the systemd resources" -play_on_resources "disable" "$OVERCLOUD_SYSTEMD_RESOURCES" - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions - -echo "$(date) * Step 2: disable core services" -play_on_resources "disable" "$OVERCLOUD_CORE_RESOURCES" - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions - -echo "$(date) * Step 3: enable each resource one by one and check the status" -play_on_resources "enable" "$OVERCLOUD_SYSTEMD_RESOURCES" - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions diff --git a/tools/ha-test-suite/test/test_pacemaker-light-b b/tools/ha-test-suite/test/test_pacemaker-light-b deleted file mode 100644 index 52a5d99..0000000 --- a/tools/ha-test-suite/test/test_pacemaker-light-b +++ /dev/null @@ -1,19 +0,0 @@ -# Test: Stop Galera and Rabbitmq, stop every systemd resource, Start every systemd resource - -echo "$(date) * Step 1: disable core services" -play_on_resources "disable" "$OVERCLOUD_CORE_RESOURCES" - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions - -echo "$(date) * Step 2: disable all the systemd resources" -play_on_resources "disable" "$OVERCLOUD_SYSTEMD_RESOURCES" - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions - -echo "$(date) * Step 3: enable all the systemd resources" -play_on_resources "enable" "$OVERCLOUD_SYSTEMD_RESOURCES" - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions diff --git a/tools/ha-test-suite/test/test_pacemaker-light-c b/tools/ha-test-suite/test/test_pacemaker-light-c deleted file mode 100644 index 9db2936..0000000 --- a/tools/ha-test-suite/test/test_pacemaker-light-c +++ /dev/null @@ -1,22 +0,0 @@ -# Test: Stop Galera and Rabbitmq, wait 20 minutes to see if something fails - -echo "$(date) * Step 1: disable core services" -play_on_resources "disable" "$OVERCLOUD_CORE_RESOURCES" - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions - -echo "$(date) * Step 2: poll every minute for twenty minutes the status of the resources" -for i in $(seq 1 20) - do - check_failed_actions - if [ $? -ne 0 ] - then - echo "Errors found, test is over." - break - fi - sleep 60 - done - -echo "$(date) - List of cluster's failed actions:" -check_failed_actions diff --git a/tools/ha-test-suite/test/test_processes-after-cluster-stop b/tools/ha-test-suite/test/test_processes-after-cluster-stop deleted file mode 100644 index 11208fb..0000000 --- a/tools/ha-test-suite/test/test_processes-after-cluster-stop +++ /dev/null @@ -1,10 +0,0 @@ -# Test: Check active processes after cluster stop - -echo "$(date) * Step 1: checking actual process status" -check_resources_process_status - -echo "$(date) * Step 2: stopping cluster" -sudo pcs cluster stop --all - -echo "$(date) * Step 3: checking actual process status" -check_resources_process_status