Retire stackforge/tripleo-ansible
This commit is contained in:
parent
bd0346b55b
commit
5730c2993a
@ -1,7 +0,0 @@
|
||||
[run]
|
||||
branch = True
|
||||
source = tripleo_ansible
|
||||
omit = tripleo_ansible/tests/*,tripleo_ansible/openstack/*
|
||||
|
||||
[report]
|
||||
ignore-errors = True
|
51
.gitignore
vendored
51
.gitignore
vendored
@ -1,51 +0,0 @@
|
||||
*.py[cod]
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Packages
|
||||
*.egg
|
||||
*.egg-info
|
||||
dist
|
||||
build
|
||||
eggs
|
||||
parts
|
||||
bin
|
||||
var
|
||||
sdist
|
||||
develop-eggs
|
||||
.installed.cfg
|
||||
lib
|
||||
lib64
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
.tox
|
||||
nosetests.xml
|
||||
.testrepository
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
|
||||
# Mr Developer
|
||||
.mr.developer.cfg
|
||||
.project
|
||||
.pydevproject
|
||||
|
||||
# Complexity
|
||||
output/*.html
|
||||
output/*/index.html
|
||||
|
||||
# Sphinx
|
||||
doc/build
|
||||
|
||||
# pbr generates these
|
||||
AUTHORS
|
||||
ChangeLog
|
||||
|
||||
# Editors
|
||||
*~
|
||||
.*.swp
|
@ -1,4 +0,0 @@
|
||||
[gerrit]
|
||||
host=review.openstack.org
|
||||
port=29418
|
||||
project=stackforge/tripleo-ansible.git
|
3
.mailmap
3
.mailmap
@ -1,3 +0,0 @@
|
||||
# Format is:
|
||||
# <preferred e-mail> <other e-mail 1>
|
||||
# <preferred e-mail> <other e-mail 2>
|
@ -1,7 +0,0 @@
|
||||
[DEFAULT]
|
||||
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
|
||||
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
|
||||
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \
|
||||
${PYTHON:-python} -m subunit.run discover -t ./ . $LISTOPT $IDOPTION
|
||||
test_id_option=--load-list $IDFILE
|
||||
test_list_option=--list
|
@ -1,16 +0,0 @@
|
||||
If you would like to contribute to the development of OpenStack,
|
||||
you must follow the steps in this page:
|
||||
|
||||
http://docs.openstack.org/infra/manual/developers.html
|
||||
|
||||
Once those steps have been completed, changes to OpenStack
|
||||
should be submitted for review via the Gerrit tool, following
|
||||
the workflow documented at:
|
||||
|
||||
http://docs.openstack.org/infra/manual/developers.html#development-workflow
|
||||
|
||||
Pull requests submitted through GitHub will be ignored.
|
||||
|
||||
Bugs should be filed on Launchpad, not GitHub:
|
||||
|
||||
https://bugs.launchpad.net/tripleo-ansible
|
@ -1,4 +0,0 @@
|
||||
tripleo-ansible Style Commandments
|
||||
===============================================
|
||||
|
||||
Read the OpenStack Style Commandments http://docs.openstack.org/developer/hacking/
|
175
LICENSE
175
LICENSE
@ -1,175 +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.
|
@ -1,6 +0,0 @@
|
||||
include AUTHORS
|
||||
include ChangeLog
|
||||
exclude .gitignore
|
||||
exclude .gitreview
|
||||
|
||||
global-exclude *.pyc
|
282
README.rst
282
README.rst
@ -1,279 +1,7 @@
|
||||
Using Ansible to update images
|
||||
==============================
|
||||
This project is no longer maintained.
|
||||
|
||||
This is a new approach to updating an in-place TripleO cloud with new
|
||||
images. We have chosen Ansible as it allows fine grained control of
|
||||
the work-flow without requiring one to write any idempotent bash or
|
||||
python. There are components that are bash or python scripts, and we are
|
||||
working hard not to replace the whole of TripleO with Ansible, but just
|
||||
the pieces that make updates more complicated than they need to be.
|
||||
|
||||
In general this update process works in the following manner:
|
||||
|
||||
* Gather inventory and facts about the deployed cloud from Heat and Nova
|
||||
* Quiesce the cloud by shutting down all OpenStack services on
|
||||
appropriate nodes
|
||||
* Nova-Rebuild nodes using requested image ids
|
||||
* Disable os-collect-config polling of Heat
|
||||
* Push Metadata from Heat to rebuilt nodes using Ansible and manually
|
||||
trigger os-collect-config
|
||||
* Start OpenStack services
|
||||
|
||||
Installing Ansible
|
||||
------------------
|
||||
|
||||
Ideally the node Ansible is to be executed from was built with the following
|
||||
disk image elements:
|
||||
|
||||
* ansible
|
||||
* tripleo-ansible
|
||||
|
||||
Systems that the playbooks are brining up should ideally have the following
|
||||
disk image elements:
|
||||
|
||||
* restore-ssh-host-keys
|
||||
* disable-os-collect-config
|
||||
|
||||
If Ansible is not preloaded, it can be installed via `pip install
|
||||
ansible` Ansible 1.8.1 or later is required.
|
||||
|
||||
If you have manually installed Ansible, see the section on "Setting
|
||||
the OS Environment" for details on ensuring your dependencies are
|
||||
met.
|
||||
|
||||
Executing Scripts and Playbooks
|
||||
-------------------------------
|
||||
|
||||
All Ansible playbooks and scripts have been written to be run directly
|
||||
from the tripleo-ansible folder.
|
||||
|
||||
An ``ansible.cfg`` file is provided. If you have a systemwide
|
||||
(/etc/ansible/ansible.conf) or user-specific ( ~/.ansible.cfg) Ansible
|
||||
config file, then Ansible will not utilize the provided configuration file.
|
||||
|
||||
Pre-flight check
|
||||
----------------
|
||||
|
||||
A playbook exists that can be used to check the controllers prior to the
|
||||
execution of the main playbook in order to quickly identify any issues in
|
||||
advance.
|
||||
|
||||
All controller nodes must be in a healty state (ACTIVE) for the pre flight
|
||||
checks to pass. We **CANNOT** proceed with an update if a controller node is
|
||||
down.
|
||||
|
||||
ansible-playbook -vvvv -M library/cloud -i plugins/inventory/heat.py -u heat-admin playbooks/pre-flight_check.yml
|
||||
|
||||
Running the updates
|
||||
-------------------
|
||||
|
||||
You will want to set your environment variables to the appropriate
|
||||
values for the following: OS_AUTH_URL, OS_USERNAME, OS_PASSWORD, and
|
||||
OS_TENANT_NAME
|
||||
|
||||
source /root/stackrc
|
||||
|
||||
Your new images will need to be uploaded to glance, such that an instance
|
||||
can be booted from them, and the image ID will need to be provided to
|
||||
the playbook as an argument.
|
||||
|
||||
You can obtain the ID with the `glance image-list` command, and then
|
||||
set them to be passed into ansible as arguments.
|
||||
|
||||
glance image-list
|
||||
|
||||
Upon execution, you will see output along these lines:
|
||||
|
||||
+--------------------------------------+---------------------------+-------------+------------------+------------+--------+
|
||||
| ID | Name | Disk Format | Container Format | Size | Status |
|
||||
+--------------------------------------+---------------------------+-------------+------------------+------------+--------+
|
||||
| 4ba4c941-2065-4925-8ddc-328d813051c3 | bm-deploy-kernel | aki | aki | 3194080 | active |
|
||||
| b0379d39-b73e-459e-a22d-a79645b83995 | bm-deploy-ramdisk | ari | ari | 24962351 | active |
|
||||
| b89342a9-94f7-4e19-a179-6b0d67a857a1 | overcloud-compute | qcow2 | bare | 706412544 | active |
|
||||
| f25cc0d7-ff6f-4beb-9456-e24b06f5a2e4 | overcloud-compute-initrd | ari | ari | 10557800 | active |
|
||||
| cbdccc2e-aaf0-4080-88bb-57656f31e747 | overcloud-compute-vmlinuz | aki | aki | 3194080 | active |
|
||||
| a5b85458-f355-49e0-bdc9-29824f2429d5 | overcloud-control | qcow2 | bare | 1210996736 | active |
|
||||
| 642f4197-5d4e-4e10-b466-188df9ac2915 | overcloud-control-initrd | ari | ari | 11652799 | active |
|
||||
| 9c386c74-66d8-4937-9438-d00c9740670d | overcloud-control-vmlinuz | aki | aki | 3194080 | active |
|
||||
| f52e97c6-e91a-4885-94be-97ea324f6c06 | overcloud-swift | qcow2 | bare | 440991744 | active |
|
||||
| 1fd49eff-bdbc-4176-b4f5-3779848c5894 | overcloud-swift-initrd | ari | ari | 10557940 | active |
|
||||
| 50aaab4b-8085-470c-9cc9-9fbfb9891071 | overcloud-swift-vmlinuz | aki | aki | 3194080 | active |
|
||||
+--------------------------------------+---------------------------+-------------+------------------+------------+--------+
|
||||
|
||||
It may be possible to infer the image IDs using the script
|
||||
"populate_image_vars". It will try to determine the latest image for
|
||||
each image class and set it as a group variable in inventory. For
|
||||
this to function correctly, the new images in glance must have the
|
||||
same names that the previous images had, which match the node type
|
||||
name, such as undercloud, swift, compute, control.
|
||||
|
||||
scripts/populate_image_vars
|
||||
|
||||
Upon execution, you will see output that indicates the ID values that
|
||||
have been stored for the image variable. Example output below:
|
||||
|
||||
{
|
||||
"nova-compute": {
|
||||
"buildnum": null,
|
||||
"id": "b89342a9-94f7-4e19-a179-6b0d67a857a1"
|
||||
},
|
||||
"swift-storage": {
|
||||
"buildnum": null,
|
||||
"id": "f52e97c6-e91a-4885-94be-97ea324f6c06"
|
||||
},
|
||||
"controller": {
|
||||
"buildnum": null,
|
||||
"id": "a5b85458-f355-49e0-bdc9-29824f2429d5"
|
||||
},
|
||||
}
|
||||
... Creating plugins/inventory/group_vars/nova-compute
|
||||
... Creating plugins/inventory/group_vars/swift-storage
|
||||
... Creating plugins/inventory/group_vars/controller
|
||||
|
||||
After the populate_image_vars script runs, inspect the output,
|
||||
example above, and if the data is what you expect, you can omit
|
||||
the image ids from the ansible command line below. Note, the
|
||||
undercloud is not shown in this list as this documentation is
|
||||
geared for overcloud updates, however when you utilize the update
|
||||
for the undercloud, the variable that needs to be set is
|
||||
undercloud_rebuild_image_id.
|
||||
|
||||
Once you are ready to execute the update, below is an example command
|
||||
for updating the overcloud, showing all of the disk image IDs being
|
||||
defined on the command line.
|
||||
|
||||
ansible-playbook -vvvv -u heat-admin -i plugins/inventory/heat.py -e nova_compute_rebuild_image_id=1ae9fe6e-c0cc-4f62-8e2b-1d382b20fdcb -e controller_rebuild_image_id=2432dd37-a072-463d-ab86-0861bb5f36cc -e swift_storage_rebuild_image_id=2432dd37-a072-463d-ab86-0861bb5f36cc playbooks/update_cloud.yml
|
||||
|
||||
If you have set the image ids in group vars or via the
|
||||
populate_image_vars script:
|
||||
|
||||
ansible-playbook -vvvv -u heat-admin -i plugins/inventory/heat.py playbooks/update_cloud.yml
|
||||
|
||||
Below, we break down the above command so you can see what each part does:
|
||||
|
||||
* -vvvv - Make Ansible very verbose.
|
||||
* -u heat-admin - Utilize the heat-admin user to connect to the remote machine.
|
||||
* -i plugins/inventory/heat.py - Sets the inventory plugin.
|
||||
* -e nova_compute_rebuild_image_id=1ae9fe6e-c0cc-4f62-8e2b-1d382b20fdcb - Sets the compute node image ID.
|
||||
* -e controller_rebuild_image_id=2432dd37-a072-463d-ab86-0861bb5f36cc - Sets the controller node image ID.
|
||||
* -e swift_storage_rebuild_image_id=2432dd37-a072-463d-ab86-0861bb5f36cc - Sets the swift storage node image ID.
|
||||
* playbooks/update_cloud.yml is the path and file name to the ansible playbook that will be utilized.
|
||||
|
||||
Upon a successful completion, ansible will print a summary report:
|
||||
|
||||
PLAY RECAP ********************************************************************
|
||||
192.0.2.24 : ok=18 changed=9 unreachable=0 failed=0
|
||||
192.0.2.25 : ok=19 changed=9 unreachable=0 failed=0
|
||||
192.0.2.26 : ok=18 changed=8 unreachable=0 failed=0
|
||||
|
||||
Additionally:
|
||||
|
||||
As ansible utilizes SSH, you may encounter ssh key errors if the IP
|
||||
address has been re-used. The fact that SSH keys aren't preserved is a
|
||||
defect that is being addressed. In order to avoid problems while this
|
||||
defect is being fixed, you will want to set an environment variable of
|
||||
"ANSIBLE_HOST_KEY_CHECKING=False", example below.
|
||||
|
||||
ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -vvvv -M library/cloud -i plugins/inventory/heat.py -e controller_rebuild_image_id=4bee1a0a-2670-48e4-a3a4-17da6be795cb -e nova_compute_rebuild_image_id=bd20e098-0753-4dc8-8dba-2f739c01ee65 -u heat-admin playbooks/update_cloud.yml
|
||||
|
||||
Python, the language that ansible is written in, buffers IO output by default.
|
||||
This can be observed as long pauses between sudden bursts of log entries where
|
||||
multiple steps are observed, particullarlly when executed by Jenkins. This
|
||||
behavior can be disabled by passing setting the an environment variable of
|
||||
"PYTHONUNBUFFERED=1", examble below.
|
||||
|
||||
PYTHONUNBUFFERED=1 ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -vvvv -M library/cloud -i plugins/inventory/heat.py -e controller_rebuild_image_id=4bee1a0a-2670-48e4-a3a4-17da6be795cb -e nova_compute_rebuild_image_id=bd20e098-0753-4dc8-8dba-2f739c01ee65 -u heat-admin playbooks/update_cloud.yml
|
||||
|
||||
For more information about Ansible, please refer to the documentation at http://docs.ansible.com/
|
||||
|
||||
Failure Handling
|
||||
----------------
|
||||
|
||||
Ansible has tunable options to abort the execution of a playbook upon
|
||||
encountering a failure.
|
||||
|
||||
The max_fail_percentage parameter allows users to define what percentage of
|
||||
nodes can fail before the playbook stops executing. This setting is pre-defined
|
||||
in the playbook file playbooks/update_cloud.yml. The default value is zero,
|
||||
which causes the playbook to abort execution if any node fails. You can read
|
||||
about this option at:
|
||||
http://docs.ansible.com/playbooks_delegation.html#maximum-failure-percentage
|
||||
|
||||
Additionally, it should be noted that the any_errors_fatal variable, when
|
||||
set to a value of True, will result in ansible aborting upon encountering
|
||||
any failures. This variable can be set by adding '-e any_errors_fatal=True'
|
||||
to the command line.
|
||||
|
||||
Additional Options
|
||||
------------------
|
||||
|
||||
The plugins/inventory/group_vars/all file has the following options in order
|
||||
to tune behavior of the playbook execution. These options can be enabled by
|
||||
defining the variable name that they represent on the ansible comamnd line, or
|
||||
by uncommenting the appropriate line in the plugins/inventory/group-vars/all
|
||||
file.
|
||||
|
||||
* force_rebuild - This option overrides the logic that prevents an instance
|
||||
from being rebuilt if the pre-existing image id maches the id being deployed.
|
||||
This may be useful for the purposes of testing.
|
||||
Example command line addition: -e force_rebuild=True
|
||||
* wait_for_hostkey - This option causes the playbook to wait for the
|
||||
SSH host keys to be restored. This option should only be used if
|
||||
the restore-ssh-host-keys element is built into the new image.
|
||||
* single_controller - This option is for when a single controller node is
|
||||
receiving an upgrade. It alters the logic so that mysql checks operate
|
||||
as if the mysql database cluster is being maintained online by other
|
||||
controller nodes during the upgrade. *IF* you are looking at this option
|
||||
due to an error indicating "Node appears to be the last node in a cluster"
|
||||
then consult Troubleshooting.rst.
|
||||
* ssh_timeout - This value, defaulted to 900 [seconds], is the maximum
|
||||
amount of time that the post-rebuild ssh connection test will wait for
|
||||
before proceeding.
|
||||
* pre_hook_command - This, when set to a command, such as /bin/date,
|
||||
will execute that command on the host where the playbook is run
|
||||
before starting any jobs.
|
||||
* post_hook_command - Similar to the pre_hook_command variable, when
|
||||
defined, will execute upon the completion of the upgrade job.
|
||||
* online_upgrade - This setting tells the script to attempt an online upgrade
|
||||
of the node. At present this is only known to work on compute nodes.
|
||||
|
||||
Online Upgrade
|
||||
--------------
|
||||
|
||||
When an upgrade *does not* require a kernel update, the Online Upgrade feature
|
||||
can be utilized to upgrade compute nodes while leaving their virtual machines
|
||||
in a running state. The result is a short one to two minute loss of network
|
||||
connectivity for the virtual machines as os-refresh-config stops and
|
||||
restarts key services which causes the loss in network connectivity.
|
||||
|
||||
This operation is performed by uploading the new image to the /tmp folder on
|
||||
the node, syncing file contents over while preserving key files, and then
|
||||
restarting services. This is only known to work on compute nodes.
|
||||
|
||||
Nova Powercontrol
|
||||
-----------------
|
||||
|
||||
A module named nova_powercontrol has been included which is intended to utilize
|
||||
nova for all instance power control operations. This utility module also records
|
||||
the previous state of the instance and has a special flag which allows the user
|
||||
to resume or restart all virtual machines that are powered off/suspended upon the
|
||||
completion of the upgrade if the module is utilized to shut down the instances.
|
||||
|
||||
To Use:
|
||||
|
||||
From the tripleo-ansible folder, execute the command:
|
||||
|
||||
bash scripts/retrieve_oc_vars
|
||||
|
||||
The script will then inform you of a file you need to source into your current
|
||||
user environment, it will contain the overcloud API credentials utilizing modified
|
||||
variable names which the playbook knows how to utilize.
|
||||
|
||||
source /root/oc-stackrc-tripleo-ansible
|
||||
|
||||
Now that the environment variables are present, add the following to the
|
||||
ansible-playbook command line for the playbooks to utilize the nova_powercontrol
|
||||
module:
|
||||
|
||||
-e use_nova_powercontrol=True
|
||||
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".
|
||||
|
||||
|
@ -1,578 +0,0 @@
|
||||
Retrying failed actions
|
||||
=======================
|
||||
|
||||
In some cases, steps may fail as some components may not yet be ready for
|
||||
use due to initialization times, which can vary based on hardware and volume
|
||||
In the event of this occurring, two options exist that allows a user to
|
||||
optionally re-attempt or resume playbook executions.
|
||||
|
||||
* Solutions:
|
||||
|
||||
* Ansible ansible-playbook command option --start-at-task="TASK NAME"
|
||||
allows resumption of a playbook, when used with the -l limit option.
|
||||
|
||||
* Ansible ansible-playbook command option --step allows a user to confirm
|
||||
each task executed by Ansible before it is executed upon.
|
||||
|
||||
A node goes to ERROR state during rebuild
|
||||
=========================================
|
||||
|
||||
This can happen from time to time due to network errors or temporary
|
||||
overload of the undercloud.
|
||||
|
||||
* Symptoms:
|
||||
|
||||
* After error, `nova list` shows node in ERROR
|
||||
|
||||
* Solution:
|
||||
|
||||
* Verify hardware is in working order.
|
||||
|
||||
* Verify that approximately 20% of the disk space is free on the Ironic
|
||||
server node.
|
||||
|
||||
* Get the image ID of the machine with `nova show`::
|
||||
|
||||
nova show $node_id
|
||||
|
||||
* Rebuild manually::
|
||||
|
||||
nova rebuild --preserve-ephemeral $node_id $image_id
|
||||
|
||||
A node times out after rebuild
|
||||
==============================
|
||||
|
||||
While rare, there is the possibility that something unexpected happened
|
||||
and the host has failed to reboot as expected from a rebuild.
|
||||
|
||||
* Symptoms:
|
||||
|
||||
* Error Message: `msg: Timeout waiting for the server to come up.. Please
|
||||
check manually`
|
||||
|
||||
* Solution:
|
||||
|
||||
* Follow the steps detailed above in "A node goes to ERROR state during
|
||||
rebuild"
|
||||
|
||||
MySQL CLI configuration file missing
|
||||
====================================
|
||||
|
||||
Should the post-rebuild restart fail, the possibility exists that the
|
||||
MySQL CLI configuration file is missing.
|
||||
|
||||
* Symptoms:
|
||||
|
||||
* Attempts to access the MySQL CLI command return an error::
|
||||
|
||||
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
|
||||
|
||||
* Solution:
|
||||
|
||||
* Verify that the MySQL CLI config file stored on the state drive
|
||||
is present and has content within the file. You can do this
|
||||
by executing the command below to display the contents in your
|
||||
terminal.::
|
||||
|
||||
sudo cat /mnt/state/root/metadata.my.cnf
|
||||
|
||||
* If the file is empty, run the command below which will retrieve current
|
||||
metadata and update config files on disk.::
|
||||
|
||||
sudo os-collect-config --force --one --command=os-apply-config
|
||||
|
||||
* Verify that the MySQL CLI config file is present in the root user
|
||||
directory by executing the following command::
|
||||
|
||||
sudo cat /root/.my.cnf
|
||||
|
||||
* If that file does not exist or is empty, two options exist.
|
||||
|
||||
* Add the following to your MySQL CLI command line::
|
||||
|
||||
--defaults-extra-file=/mnt/state/root/metadata.my.cnf
|
||||
|
||||
* Alternatively, copy configuration from the state drive.::
|
||||
|
||||
sudo cp -f /mnt/state/root/metadata.my.cnf /root/.my.cnf
|
||||
|
||||
|
||||
MySQL fails to start upon retrying update
|
||||
=========================================
|
||||
|
||||
If the update was aborted or failed during the Update sequence before a
|
||||
single MySQL controller was operational, MySQL will fail to start upon retrying.
|
||||
|
||||
* Symptoms:
|
||||
|
||||
* Update is being re-attempted.
|
||||
|
||||
* The following error messages having been observed.
|
||||
|
||||
* `msg: Starting MySQL (Percona XtraDB Cluster) database server: mysqld . . . . The server quit without updating PID file (/var/run/mysqld/mysqld.pid)`
|
||||
|
||||
* `stderr: ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (111)`
|
||||
|
||||
* `FATAL: all hosts have already failed -- aborting`
|
||||
|
||||
* Update automatically aborts.
|
||||
|
||||
* *WARNING*:
|
||||
|
||||
* The command `/etc/init.d/mysql bootstrap-pxc` which is mentioned below
|
||||
should only ever be executed when an entire MySQL cluster is down, and
|
||||
then only on the last node to have been shut down. Running this command
|
||||
on multiple nodes will cause the MySQL cluster to enter a split brain
|
||||
scenario effectively breaking the cluster which will result in
|
||||
unpredictable behavior.
|
||||
|
||||
* Solution:
|
||||
|
||||
* Use `nova list` to determine the IP of the controllerMgmt node, then ssh into it::
|
||||
|
||||
ssh heat-admin@$IP
|
||||
|
||||
* Verify MySQL is down by running the mysql client as root. It _should_ fail::
|
||||
|
||||
sudo mysql -e "SELECT 1"
|
||||
|
||||
* Attempt to restart MySQL in case another cluster node is online.
|
||||
This should fail in this error state, however if it succeeds your
|
||||
cluster should again be operational and the next step can be skipped.::
|
||||
|
||||
sudo /etc/init.d/mysql start
|
||||
|
||||
* Start MySQL back up in single node bootstrap mode::
|
||||
|
||||
sudo /etc/init.d/mysql bootstrap-pxc
|
||||
|
||||
|
||||
MySQL/Percona/Galera is out of sync
|
||||
===================================
|
||||
|
||||
OpenStack is configured to store all of its state in a multi-node
|
||||
synchronous replication Percona XtraDB Cluster database, which uses
|
||||
Galera for replication. This database must be in sync and have the full
|
||||
complement of servers before updates can be performed safely.
|
||||
|
||||
* Symptoms:
|
||||
|
||||
* Update fails with errors about Galera and/or MySQL being "Out of Sync"
|
||||
|
||||
* Solution:
|
||||
|
||||
* use `nova list` to determine IP of controllerMgmt node, then SSH to it::
|
||||
|
||||
ssh heat-admin@$IP
|
||||
|
||||
* Verify replication is out of sync::
|
||||
|
||||
sudo mysql -e "SHOW STATUS like 'wsrep_%'"
|
||||
|
||||
* Stop mysql::
|
||||
|
||||
sudo /etc/init.d/mysql stop
|
||||
|
||||
* Verify it is down by running the mysql client as root. It _should_ fail::
|
||||
|
||||
sudo mysql -e "SELECT 1"
|
||||
|
||||
* Start controllerMgmt0 MySQL back up in single node bootstrap mode::
|
||||
|
||||
sudo /etc/init.d/mysql bootstrap-pxc
|
||||
|
||||
* On the remaining controller nodes observed to be having issues, utilize
|
||||
the IP address via `nova list` and login to them.::
|
||||
|
||||
ssh heat-admin@$IP
|
||||
|
||||
* Verify replication is out of sync::
|
||||
|
||||
sudo mysql -e "SHOW STATUS like 'wsrep_%'"
|
||||
|
||||
* Stop mysql::
|
||||
|
||||
sudo /etc/init.d/mysql stop
|
||||
|
||||
* Verify it is down by running the mysql client as root. It _should_ fail::
|
||||
|
||||
sudo mysql -e "SELECT 1"
|
||||
|
||||
* Start MySQL back up so it attempts to connect to controllerMgmt0::
|
||||
|
||||
sudo /etc/init.d/mysql start
|
||||
|
||||
* If restarting MySQL fails, then the database is most certainly out of sync
|
||||
and the MySQL error logs, located at /var/log/mysql/error.log, will need
|
||||
to be consulted. In this case, never attempt to restart MySQL with
|
||||
`sudo /etc/init.d/mysql bootstrap-pxc` as it will bootstrap the host
|
||||
as a single node cluster thus worsening what already appears to be a
|
||||
split-brain scenario.
|
||||
|
||||
MysQL "Node appears to be the last node in a cluster" error
|
||||
===========================================================
|
||||
|
||||
This error occurs when one of the controller nodes does not have MySQL running.
|
||||
The playbook has detected that the current node is the last running node,
|
||||
although based on sequence it should not be the last node. As a result the
|
||||
error is thrown and update aborted.
|
||||
|
||||
* Symptoms:
|
||||
|
||||
* Update Failed with error message "Galera Replication - Node appears to be the last node in a cluster - cannot safely proceed unless overridden via single_controller setting - See README.rst"
|
||||
|
||||
* Actions:
|
||||
|
||||
* Run the pre-flight_check.yml playbook. It will attempt to restart MySQL
|
||||
on each node in the "Ensuring MySQL is running -" step. If that step
|
||||
succeeeds, you should be able to re-run the playbook and not encounter
|
||||
"Node appears to be last node in a cluster" error.
|
||||
|
||||
* IF pre-flight_check fails to restart MySQL, you will need to consult the
|
||||
MySQL logs (/var/log/mysql/error.log) to determine why the other nodes
|
||||
are not restarting.
|
||||
|
||||
SSH Connectivity is lost
|
||||
========================
|
||||
|
||||
Ansible uses SSH to communicate with remote nodes. In heavily loaded, single
|
||||
host virtualized environments, SSH can lose connectivity. It should be noted
|
||||
that similar issues in a physical environment may indicate issues in the
|
||||
underlying network infrastructure.
|
||||
|
||||
* Symptoms:
|
||||
|
||||
* Ansible update attempt fails.
|
||||
|
||||
* Error output::
|
||||
|
||||
fatal: [192.0.2.25] => SSH encountered an unknown error. The
|
||||
output was: OpenSSH_6.6.1, OpenSSL 1.0.1i-dev xx XXX xxxx
|
||||
debug1: Reading configuration data /etc/ssh/ssh_config debug1:
|
||||
/etc/ssh/ssh_config line 19: Applying options for * debug1:
|
||||
auto-mux: Trying existing master debug2: fd 3 setting
|
||||
O_NONBLOCK mux_client_hello_exchange: write packet: Broken
|
||||
pipe FATAL: all hosts have already failed – aborting
|
||||
|
||||
* Solution:
|
||||
|
||||
* You will generally be able to re-run the playbook and complete the
|
||||
upgrade, unless SSH connectivity is lost while all MySQL nodes are
|
||||
down. (See 'MySQL fails to start upon retrying update' to correct
|
||||
this issue.)
|
||||
|
||||
* Early Ubuntu Trusty kernel versions have known issues with KVM which
|
||||
will severely impact SSH connectivity to instances. Test hosts should
|
||||
have a minimum kernel version of 3.13.0-36-generic.
|
||||
The update steps, as root, are::
|
||||
|
||||
apt-get update
|
||||
apt-get dist-upgrade
|
||||
reboot
|
||||
|
||||
* If this issue is repeatedly encountered on a physical environment, the
|
||||
network infrastructure should be inspected for errors.
|
||||
|
||||
* Similar error messages to the error noted in the Symptom may occur with
|
||||
long running processes, such as database creation/upgrade steps. These
|
||||
cases will generally have partial program execution log output
|
||||
immediately before the broken pipe message visible.
|
||||
|
||||
Should this be the case, Ansible and OpenSSH may need to have their
|
||||
configuration files tuned to meet the needs of the environment.
|
||||
|
||||
Consult the Ansible configuration file to see available connection settings
|
||||
ssh_args, timeout, and possibly pipelining..::
|
||||
|
||||
https://github.com/ansible/ansible/blob/release1.7.0/examples/ansible.cfg
|
||||
|
||||
As Ansible uses OpenSSH, Please reference the ssh_config manual, in
|
||||
paricular the ServerAliveInterval and ServerAliveCountMax options.
|
||||
|
||||
Postfix fails to reload
|
||||
=======================
|
||||
|
||||
Occasionally the postfix mail transfer agent will fail to reload because
|
||||
it is not running when the system expects it to be running.
|
||||
|
||||
* Symptoms:
|
||||
|
||||
* Step in /var/log/upstart/os-collect-config.log shows that 'service postfix reload' failed.
|
||||
|
||||
Solution:
|
||||
|
||||
* Start postfix::
|
||||
|
||||
sudo service postfix start
|
||||
|
||||
Apache2 Fails to start
|
||||
======================
|
||||
|
||||
Apache2 requires some self-signed SSL certificates to be put in place
|
||||
that may not have been configured yet due to earlier failures in the
|
||||
setup process.
|
||||
|
||||
* Error Message:
|
||||
|
||||
* failed: [192.0.2.25] => (item=apache2) => {"failed": true, "item": "apache2"}
|
||||
* msg: start: Job failed to start
|
||||
|
||||
* Symptoms:
|
||||
|
||||
* apache2 service fails to start
|
||||
* /etc/ssl/certs/ssl-cert-snakeoil.pem is missing or empty
|
||||
|
||||
* Solution:
|
||||
|
||||
* Re-run `os-collect-config` to reassert the SSL certificates::
|
||||
|
||||
sudo os-collect-config --force --one
|
||||
|
||||
RabbitMQ still running when restart is attempted
|
||||
================================================
|
||||
|
||||
There are certain system states that cause RabbitMQ to fail to die on normal kill signals.
|
||||
|
||||
* Symptoms:
|
||||
|
||||
* Attempts to start rabbitmq fail because it is already running
|
||||
|
||||
* Solution:
|
||||
|
||||
* Find any processes running as `rabbitmq` on the box, and kill them, forcibly if need be.
|
||||
|
||||
Instance reported with status == "SHUTOFF" and task_state == "powering on"
|
||||
==========================================================================
|
||||
|
||||
If nova attempts to restart an instance when the compute node is not ready,
|
||||
it is possible that nova could entered a confused state where it thinks that
|
||||
an instance is starting when in fact the compute node is doing nothing.
|
||||
|
||||
* Symptoms:
|
||||
|
||||
* Command `nova list --all-tenants` reports instance(s) with STATUS ==
|
||||
"SHUTOFF" and task_state == "powering on".
|
||||
* Instance cannot be pinged.
|
||||
* No instance appears to be running on the compute node.
|
||||
* Nova hangs upon retrieving logs or returns old logs from the previous
|
||||
boot.
|
||||
* Console session cannot be established.
|
||||
|
||||
* Solution:
|
||||
|
||||
* On a controller logged in as root, after executing `source stackrc`:
|
||||
|
||||
* Execute `nova list --all-tenants` to obtain instance ID(s)
|
||||
|
||||
* Execute `nova show <instance-id>` on each suspected ID to identify
|
||||
suspected compute nodes.
|
||||
|
||||
* Log into the suspected compute node(s) and execute:
|
||||
`os-collect-config --force --one`
|
||||
|
||||
* Return to the controller node that you were logged into previously, and
|
||||
using the instancce IDs obtained previously, take the following steps.
|
||||
|
||||
* Execute `nova reset-state --active <instance-id>`
|
||||
|
||||
* Execute `nova stop <instance-id>`
|
||||
|
||||
* Execute `nova start <instance-id>`
|
||||
|
||||
* Once the above steps have been taken in order, you should see the
|
||||
instance status return to ACTIVE and the instance become accessible
|
||||
via the network.
|
||||
|
||||
state drive /mnt is not mounted
|
||||
===============================
|
||||
|
||||
In the rare event that something bad happened between the state drive being
|
||||
unmounted and the rebuild command being triggered, the /mnt volume on the
|
||||
instance that was being executed upon at that time will be in an unmounted
|
||||
state.
|
||||
|
||||
In such a state, pre-flight checks will fail attempting to start MySQL and
|
||||
RabbitMQ.
|
||||
|
||||
* Error Messages:
|
||||
|
||||
* Pre-flight check returns an error similar to::
|
||||
|
||||
failed: [192.0.2.24] => {"changed": true, "cmd":
|
||||
"rabbitmqctl -n rabbit@$(hostname) status" stderr: Error:
|
||||
unable to connect to node
|
||||
'rabbit@overcloud-controller0-vahypr34iy2x': nodedown
|
||||
|
||||
* Attempting to manually start MySQL or RabbitMQ return::
|
||||
|
||||
start: Job failed to start
|
||||
|
||||
* Upgrade execution returns with an error indicating::
|
||||
|
||||
TASK: [fail msg="Galera Replication - Node appears to be the
|
||||
last node in a cluster - cannot safely proceed unless
|
||||
overriden via single_controller setting - See README.rst"] ***
|
||||
|
||||
* Symptom:
|
||||
|
||||
* Execution of the `df` command does not show a volume mounted as /mnt.
|
||||
|
||||
* Unable to manually start services.
|
||||
|
||||
* Solution:
|
||||
|
||||
* Execute the os-collect config which will re-mount the state drive. This
|
||||
command may fail without additional intervention, however it should mount
|
||||
the state drive which is all that is needed to proceed to the next step.::
|
||||
|
||||
sudo os-collect-config --force --one
|
||||
|
||||
* At this point, the /mnt volume should be visible in the output of the `df`
|
||||
command.
|
||||
|
||||
* Start MySQL by executing::
|
||||
|
||||
sudo /etc/init.d/mysqld start
|
||||
|
||||
* If MySQL fails to start, and it has been verified that MySQL is not
|
||||
running on any controller nodes, then you will need to identify the
|
||||
*last* node that MySQL was stopped on and consult the section "MySQL
|
||||
fails to start upon retrying update" for guidance on restarting the
|
||||
cluster.
|
||||
|
||||
* Start RabbitMQ by executing::
|
||||
|
||||
service rabbitmq-server start
|
||||
|
||||
* If rabbitmq-server fails to start, then the cluster may be down. If
|
||||
this is the case, then the *last* node to be stopped will need to be
|
||||
identified and started before attempting to restart RabbitMQ on this
|
||||
node.
|
||||
|
||||
* At this point, re-execute the pre-flight check, and proceed with the
|
||||
upgrade.
|
||||
|
||||
VMs may not shut down properly during upgrade
|
||||
=============================================
|
||||
|
||||
During the upgrade process, VMs on compute nodes are shut down
|
||||
gracefully. If the VMs do not shut down, this can cause the upgrade to
|
||||
stop.
|
||||
|
||||
* Error Messages:
|
||||
|
||||
* A playbook run ends with a message similar to::
|
||||
|
||||
failed: [10.23.210.31] => {"failed": true} msg: The ephemeral
|
||||
storage of this system failed to be cleaned up properly and
|
||||
processes or files are still in use. The previous ansible play
|
||||
should have information to help troubleshoot this issue.
|
||||
|
||||
* The output of the playbook run prior to this message contains a
|
||||
process listing and a listing of open files.
|
||||
|
||||
* Symptoms:
|
||||
|
||||
* The state drive on the compute node, /mnt, is still in use and
|
||||
cannot be unmounted. You can confirm this by executing::
|
||||
|
||||
lsof -n | grep /mnt
|
||||
|
||||
* VMs are running on the node. To see which VMs are running, run::
|
||||
|
||||
virsh list
|
||||
|
||||
* If `virsh list` fails, you may need to restart libvirt-bin or
|
||||
libvirtd depending on which process you are running. Do
|
||||
so by running::
|
||||
|
||||
service libvirt-bin restart
|
||||
or
|
||||
service libvirtd restart
|
||||
|
||||
* Solution:
|
||||
|
||||
* Manual intervention is required. You will need to determine why
|
||||
the VMs did not shut down properly, and resolve the issue.
|
||||
|
||||
* Unresponsive VMs can be forcibly shutdown using `virsh destroy
|
||||
<id>`. Note that this can corrupt filesystems on the VM.
|
||||
|
||||
* Resume the playbook run once the VMs have been shut down.
|
||||
|
||||
Instances are inaccessible via network
|
||||
======================================
|
||||
|
||||
Upon restarting, it is possible that the virtual machine is
|
||||
unreachable due to Open vSwitch not being ready for the virtual machine
|
||||
networking.
|
||||
|
||||
* Symptom:
|
||||
|
||||
* After a restart, instances won't ping.
|
||||
|
||||
* Solution:
|
||||
|
||||
* To resolve:
|
||||
|
||||
* Log into a controller node and execute `source /root/stackrc`
|
||||
|
||||
* Stop all virtual machines on a compute node utilizing `nova
|
||||
hypervisor-servers <hostname>` and `nova stop <id>`
|
||||
|
||||
* Log into the undercloud node and execute `source /root/stackrc`
|
||||
|
||||
* Obtain a list of nodes by executing `nova list`
|
||||
|
||||
* Execute `nova stop <id>` for the affected compute node.
|
||||
|
||||
* Once the compute node has stopped, execute `nova start <id>` to
|
||||
reboot the compute node.
|
||||
|
||||
Online Upgrade fails with message saying glanceclient is not found.
|
||||
===================================================================
|
||||
|
||||
* Symptoms:
|
||||
|
||||
* Online upgrade has been attempted, however the playbook
|
||||
execution failed when attempting to download the new image from
|
||||
Glance reporting that glanceclient was not found.
|
||||
|
||||
* Solution:
|
||||
|
||||
* If you are attempting to execute the Ansible playbook on the seed or
|
||||
undercloud node, source the Ansible virtual environment by executing
|
||||
`source /opt/stack/venvs/ansible/bin/activate`
|
||||
|
||||
* Once the Ansible virtual environment has been sourced, execute
|
||||
`sudo pip install python-glanceclient` on the node you are attempting
|
||||
to execute Ansible from.
|
||||
|
||||
Online Upgrade of compute node failed
|
||||
=====================================
|
||||
|
||||
In the event that an online upgrade of a compute node somehow failed, the node
|
||||
can be recovered utilizing a traditional rebuild.
|
||||
|
||||
* Symptoms:
|
||||
|
||||
* Online upgrade was performed.
|
||||
|
||||
* Compute node cannot be logged into, or is otherwise in a
|
||||
non-working state.
|
||||
|
||||
* Solution:
|
||||
|
||||
* From the undercloud:
|
||||
|
||||
* Execute `source /root/stackrc`
|
||||
|
||||
* Identify the instance ID of the broken compute node via `nova list`
|
||||
|
||||
* Execute the command `nova stop <instance-id>` to stop the instance.
|
||||
|
||||
* Return to the host that you ran the upgrade from and re-run the playbook
|
||||
without the "-e online_upgrade=True" option.
|
||||
|
||||
* Additionally, you may need to utilize the "-e force_rebuild=True" option
|
||||
to force the instance to rebuild.
|
@ -1,3 +0,0 @@
|
||||
[defaults]
|
||||
timeout = 300
|
||||
pipelining = True
|
@ -1,75 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# 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 os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.abspath('../..'))
|
||||
# -- General configuration ----------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
#'sphinx.ext.intersphinx',
|
||||
'oslosphinx'
|
||||
]
|
||||
|
||||
# autodoc generation is a bit aggressive and a nuisance when doing heavy
|
||||
# text edit cycles.
|
||||
# execute "export SPHINX_DEBUG=1" in your terminal to disable
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'tripleo-ansible'
|
||||
copyright = u'2013, OpenStack Foundation'
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
add_module_names = True
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# -- Options for HTML output --------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. Major themes that come with
|
||||
# Sphinx are currently 'default' and 'sphinxdoc'.
|
||||
# html_theme_path = ["."]
|
||||
# html_theme = '_theme'
|
||||
# html_static_path = ['static']
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = '%sdoc' % project
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass
|
||||
# [howto/manual]).
|
||||
latex_documents = [
|
||||
('index',
|
||||
'%s.tex' % project,
|
||||
u'%s Documentation' % project,
|
||||
u'OpenStack Foundation', 'manual'),
|
||||
]
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
#intersphinx_mapping = {'http://docs.python.org/': None}
|
@ -1,4 +0,0 @@
|
||||
============
|
||||
Contributing
|
||||
============
|
||||
.. include:: ../../CONTRIBUTING.rst
|
@ -1,24 +0,0 @@
|
||||
.. tripleo-ansible documentation master file, created by
|
||||
sphinx-quickstart on Tue Jul 9 22:26:36 2013.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to tripleo-ansible's documentation!
|
||||
========================================================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
readme
|
||||
installation
|
||||
usage
|
||||
contributing
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
@ -1,12 +0,0 @@
|
||||
============
|
||||
Installation
|
||||
============
|
||||
|
||||
At the command line::
|
||||
|
||||
$ pip install tripleo-ansible
|
||||
|
||||
Or, if you have virtualenvwrapper installed::
|
||||
|
||||
$ mkvirtualenv tripleo-ansible
|
||||
$ pip install tripleo-ansible
|
@ -1 +0,0 @@
|
||||
.. include:: ../../README.rst
|
@ -1,7 +0,0 @@
|
||||
========
|
||||
Usage
|
||||
========
|
||||
|
||||
To use tripleo-ansible in a project::
|
||||
|
||||
import tripleo_ansible
|
@ -1,6 +0,0 @@
|
||||
Install tripleo-ansible repository
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
At present, there is no configuration for this element.
|
@ -1,2 +0,0 @@
|
||||
source-repositories
|
||||
ansible
|
@ -1,28 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
# 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.
|
||||
#
|
||||
|
||||
set -eux
|
||||
set -o pipefail
|
||||
|
||||
VENV=/opt/stack/venvs/ansible
|
||||
|
||||
set +u
|
||||
source $VENV/bin/activate
|
||||
set -u
|
||||
|
||||
$VENV/bin/pip install -r /opt/stack/tripleo-ansible/requirements.txt
|
@ -1 +0,0 @@
|
||||
tripleo-ansible git /opt/stack/tripleo-ansible https://github.com/SpamapS/tripleo-ansible.git
|
@ -1,20 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
--
|
||||
os_username: admin
|
||||
os_password: admin
|
||||
os_tenant_name: admin
|
||||
os_region_name: region.x
|
||||
os_auth_url: http://127.0.0.1:35357/v2.0/
|
@ -1,28 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
- name: rebuild a nova instance
|
||||
hosts: localhost
|
||||
tasks:
|
||||
- name: rebuild an instance
|
||||
nova_rebuild:
|
||||
region_name: regionOne
|
||||
login_username: admin
|
||||
login_password: setpassword
|
||||
login_tenant_name: admin
|
||||
auth_url: http://192.0.2.3:5000/v2.0
|
||||
name: overcloud-NovaCompute-setvmname
|
||||
image_id: 6663f30c-fff8-4c67-b0a9-fc72193b9eea
|
||||
preserve_ephemeral: yes
|
||||
wait_for: 200
|
@ -1,53 +0,0 @@
|
||||
A simple iterator for running a playbook.
|
||||
=========================================
|
||||
|
||||
Getting Started
|
||||
---------------
|
||||
|
||||
You will need:
|
||||
|
||||
* Stack environment variables loaded.
|
||||
|
||||
Example: source $TRIPLEO_ROOT/tripleo-incubator/undercloudrc
|
||||
|
||||
* An Ansible Inventory file defining localhost which makes use of a local connection. This file is passed in as the -i option to the included script. You can view such a file at ../hosts_local.
|
||||
|
||||
Example Content: "localhost ansible_connection=local"
|
||||
|
||||
More information can be found at http://docs.ansible.com/intro_inventory.html
|
||||
|
||||
* A file containing a list of instances you wish to run the playbook against.
|
||||
|
||||
Example: instances.txt
|
||||
|
||||
* A configuration file named update_config.cfg in the folder where your executing the script from. This file has sections that are based upon a portion of the instance name, such as "controller" and "NovaCompute". With-in each section is a "image_id" option which is where you would place the new image ID to rebuild the instance with. Image IDs can be obtained via `glance image-list` once you have the appropriate environment variables loaded.
|
||||
|
||||
Example: update_config.cfg
|
||||
|
||||
* A playbook, expecting expecting the following
|
||||
|
||||
* image_id - glance image id.
|
||||
* name - instance name
|
||||
|
||||
* A slightly modified copy of the simeple_rebuild.yml example playbook exists as main.yml
|
||||
|
||||
Putting it all together
|
||||
-----------------------
|
||||
|
||||
source $TRIPLEO_ROOT/tripleo-incubator/undercloudrc
|
||||
|
||||
python ./simple_update.py -p ./main.yml -l instances.txt -i ../hosts_local
|
||||
|
||||
A Few notes
|
||||
-----------
|
||||
|
||||
1) The variables defined in main.yml before the tasks level are presently
|
||||
redundant, as the underlying nova_rebuild module supports retrieval of the
|
||||
configuration from environment variables, although they could be useful for
|
||||
modules that do not presently support such functionality, or modules that
|
||||
need to execute remotely.
|
||||
|
||||
2) If an inventory is populated of each machine into ansible, then it would
|
||||
be easy to modify the playbook to connect out and perform actions on each
|
||||
instance, such as backup a database, fetch files, replace files, etc.
|
||||
|
@ -1,4 +0,0 @@
|
||||
overcloud-NovaCompute0-sbepht5ngm5v
|
||||
overcloud-NovaCompute1-7d2o5lpz32yt
|
||||
overcloud-NovaCompute2-wssjjvfecxwk
|
||||
overcloud-controller0-blhq6zj26lhh
|
@ -1,33 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
- name: rebuild an instance
|
||||
hosts: localhost
|
||||
vars:
|
||||
os_username: "{{ lookup('env','OS_USERNAME') }}"
|
||||
os_tenant_name: "{{ lookup('env','OS_TENANT_NAME') }}"
|
||||
os_password: "{{ lookup('env','OS_PASSWORD') }}"
|
||||
os_auth_url: "{{ lookup('env','OS_AUTH_URL') }}"
|
||||
tasks:
|
||||
- name: rebuild an instance
|
||||
nova_rebuild:
|
||||
region_name: regionOne
|
||||
login_username: "{{ os_username }}"
|
||||
login_password: "{{ os_password }}"
|
||||
login_tenant_name: "{{ os_tenant_name}}"
|
||||
auth_url: "{{ os_auth_url }}"
|
||||
name: "{{ name }}"
|
||||
image_id: "{{ image_id }}"
|
||||
preserve_ephemeral: yes
|
||||
wait_for: 300
|
@ -1,64 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import argparse
|
||||
import ConfigParser
|
||||
import subprocess
|
||||
|
||||
parser = argparse.ArgumentParser(description='Exmaple iterative updater')
|
||||
parser.add_argument('-p', dest='playbook', help='main.yml', required=True)
|
||||
parser.add_argument(
|
||||
'-l',
|
||||
dest='instances',
|
||||
help='instances.txt',
|
||||
required=True
|
||||
)
|
||||
parser.add_argument(
|
||||
'-i',
|
||||
dest='inventory',
|
||||
help='inventory.ini',
|
||||
required=True
|
||||
)
|
||||
parser.add_argument(
|
||||
'-c',
|
||||
dest='configfile',
|
||||
help='update_config.cfg',
|
||||
required=False,
|
||||
default='update_config.cfg'
|
||||
)
|
||||
|
||||
results = parser.parse_args()
|
||||
config = ConfigParser.RawConfigParser()
|
||||
config.read(results.configfile)
|
||||
|
||||
with open(results.instances) as list:
|
||||
for host in list:
|
||||
for section in config.sections():
|
||||
if section in host:
|
||||
hostname = host.strip('\n')
|
||||
image_id = config.get(section, 'image_id')
|
||||
args = (
|
||||
'ansible-playbook',
|
||||
results.playbook,
|
||||
'-e',
|
||||
"name=%s image_id=%s" % (hostname, image_id),
|
||||
'-i',
|
||||
results.inventory
|
||||
)
|
||||
print('Executing:\n')
|
||||
print(args)
|
||||
subprocess.call(args)
|
@ -1,26 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Each server name "class" should be a section with an underlying
|
||||
# image_id property that contains the Glance Image ID to be utilized.
|
||||
# You can obtain a list of loaded image ids utilizing the
|
||||
# `glance image-list` command.
|
||||
|
||||
[controller]
|
||||
image_id=7732e7ca-52fa-4acf-beeb-9cfd82e0e3df
|
||||
|
||||
[NovaCompute]
|
||||
image_id=0e09dcac-b4de-42c4-b7ad-d86a33c49ae0
|
||||
|
@ -1,185 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# This code is part of Ansible, but is an independent component.
|
||||
# This particular file snippet, and this file snippet only, is BSD licensed.
|
||||
# Modules you write using this snippet, which is embedded dynamically by Ansible
|
||||
# still belong to the author of the module, and may assign their own license
|
||||
# to the complete work.
|
||||
#
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import os
|
||||
|
||||
try:
|
||||
from novaclient.v1_1 import client as nova_client
|
||||
from novaclient import exceptions
|
||||
import time
|
||||
except ImportError:
|
||||
print("failed=True msg='novaclient is required for this module'")
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: nova_facts
|
||||
short_description: Return facts from Nova
|
||||
description:
|
||||
- Returns instance state and metadata from Openstack Nova.
|
||||
options:
|
||||
login_username:
|
||||
description:
|
||||
- login username to authenticate to keystone
|
||||
required: true
|
||||
default: admin
|
||||
login_password:
|
||||
description:
|
||||
- Password of login user
|
||||
required: true
|
||||
default: 'yes'
|
||||
login_tenant_name:
|
||||
description:
|
||||
- The tenant name of the login user
|
||||
required: true
|
||||
default: 'yes'
|
||||
auth_url:
|
||||
description:
|
||||
- The keystone url for authentication
|
||||
required: false
|
||||
default: 'http://127.0.0.1:35357/v2.0/'
|
||||
region_name:
|
||||
description:
|
||||
- Name of the region
|
||||
required: false
|
||||
default: None
|
||||
name:
|
||||
description:
|
||||
- Name of the instance for which facts will be retrieved.
|
||||
default: None
|
||||
instance_id:
|
||||
description:
|
||||
- Instance ID of the instance for which facts will be retrieved.
|
||||
default: None
|
||||
requirements: ["novaclient"]
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Rebuilds an existing VM with a new image
|
||||
- nova_facts:
|
||||
login_username: admin
|
||||
login_password: admin
|
||||
login_tenant_name: admin
|
||||
name: vm1
|
||||
image_id: 4f905f38-e52a-43d2-b6ec-754a13ffb529
|
||||
'''
|
||||
|
||||
|
||||
# The following openstack_ is a copy paste from an upcoming
|
||||
# core module "lib/ansible/module_utils/openstack.py" Once that's landed,
|
||||
# these should be replaced with a line at the bottom of the file:
|
||||
# from ansible.module_utils.openstack import *
|
||||
def openstack_argument_spec():
|
||||
# Consume standard OpenStack environment variables.
|
||||
# This is mainly only useful for ad-hoc command line operation as
|
||||
# in playbooks one would assume variables would be used appropriately
|
||||
OS_AUTH_URL = os.environ.get('OS_AUTH_URL', 'http://127.0.0.1:35357/v2.0/')
|
||||
OS_PASSWORD = os.environ.get('OS_PASSWORD', None)
|
||||
OS_REGION_NAME = os.environ.get('OS_REGION_NAME', None)
|
||||
OS_USERNAME = os.environ.get('OS_USERNAME', 'admin')
|
||||
OS_TENANT_NAME = os.environ.get('OS_TENANT_NAME', OS_USERNAME)
|
||||
|
||||
spec = dict(
|
||||
login_username=dict(default=OS_USERNAME),
|
||||
auth_url=dict(default=OS_AUTH_URL),
|
||||
region_name=dict(default=OS_REGION_NAME),
|
||||
availability_zone=dict(default=None),
|
||||
)
|
||||
if OS_PASSWORD:
|
||||
spec['login_password'] = dict(default=OS_PASSWORD)
|
||||
else:
|
||||
spec['login_password'] = dict(required=True)
|
||||
if OS_TENANT_NAME:
|
||||
spec['login_tenant_name'] = dict(default=OS_TENANT_NAME)
|
||||
else:
|
||||
spec['login_tenant_name'] = dict(required=True)
|
||||
return spec
|
||||
|
||||
|
||||
def _nova_facts(module, nova):
|
||||
server = None
|
||||
try:
|
||||
if module.params.get('instance_id') is None:
|
||||
servers = nova.servers.list(True, {'name': module.params['name']})
|
||||
if servers:
|
||||
# the {'name': module.params['name']} will also return servers
|
||||
# with names that partially match the server name, so we have to
|
||||
# strictly filter here
|
||||
servers = [
|
||||
x for x in servers if x.name == module.params['name']
|
||||
]
|
||||
if servers:
|
||||
server = servers[0]
|
||||
else:
|
||||
server = nova.servers.get(module.params['instance_id'])
|
||||
except Exception, e:
|
||||
module.fail_json(
|
||||
msg="Error in getting the server list: %s" % e.message
|
||||
)
|
||||
if not server:
|
||||
module.exit_json(changed=False, result="not present")
|
||||
|
||||
try:
|
||||
server = nova.servers.get(server.id)
|
||||
except Exception, e:
|
||||
module.fail_json(msg="not present")
|
||||
|
||||
facts = {'ansible_facts': {}}
|
||||
facts['ansible_facts']['instance_status'] = server.status
|
||||
facts['ansible_facts']['instance_metadata'] = server.metadata
|
||||
|
||||
module.exit_json(**facts)
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = openstack_argument_spec()
|
||||
argument_spec.update(dict(
|
||||
name=dict(),
|
||||
instance_id=dict(),
|
||||
))
|
||||
module = AnsibleModule(argument_spec=argument_spec)
|
||||
|
||||
nova = nova_client.Client(module.params['login_username'],
|
||||
module.params['login_password'],
|
||||
module.params['login_tenant_name'],
|
||||
module.params['auth_url'],
|
||||
region_name=module.params['region_name'],
|
||||
service_type='compute')
|
||||
try:
|
||||
nova.authenticate()
|
||||
except exceptions.Unauthorized, e:
|
||||
module.fail_json(
|
||||
msg="Invalid OpenStack Nova credentials.: %s" % e.message
|
||||
)
|
||||
except exceptions.AuthorizationFailure, e:
|
||||
module.fail_json(msg="Unable to authorize user: %s" % e.message)
|
||||
|
||||
_nova_facts(module, nova)
|
||||
# this is magic, see lib/ansible/module_common.py
|
||||
from ansible.module_utils.basic import *
|
||||
main()
|
@ -1,6 +0,0 @@
|
||||
[DEFAULT]
|
||||
|
||||
# The list of modules to copy from oslo-incubator.git
|
||||
|
||||
# The base module to hold the copy of openstack.common
|
||||
base=tripleo_ansible
|
@ -1,44 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
- name: Check if using lvm based storage
|
||||
stat: path=/mnt/state/var/lib/cinder/cinder-volumes-backing-file
|
||||
register: lvm_backing_file
|
||||
- name: Re-create cinder loopdevice
|
||||
command: losetup -f /mnt/state/var/lib/cinder/cinder-volumes-backing-file
|
||||
when: lvm_backing_file.stat.exists
|
||||
sudo: yes
|
||||
- pause: seconds=5
|
||||
when: lvm_backing_file.stat.exists
|
||||
- name: Re-scan for volume groups
|
||||
command: pvscan
|
||||
when: lvm_backing_file.stat.exists
|
||||
sudo: yes
|
||||
- pause: seconds=5
|
||||
- name: Re-enable volume groups
|
||||
command: vgchange -a y
|
||||
when: lvm_backing_file.stat.exists
|
||||
sudo: yes
|
||||
- pause: seconds=5
|
||||
when: lvm_backing_file.stat.exists
|
||||
- name: Get all cinder lvm volumes
|
||||
shell: "lvdisplay | grep cinder-volumes | grep 'LV Path' | awk '{print $3}'"
|
||||
when: lvm_backing_file.stat.exists
|
||||
register: cinder_volumes
|
||||
sudo: yes
|
||||
- name: Activate cinder lvm volumes
|
||||
shell: lvchange -a y {{ item }}
|
||||
with_items: cinder_volumes.stdout_lines
|
||||
when: lvm_backing_file.stat.exists
|
||||
sudo: yes
|
@ -1,17 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
- hosts: all
|
||||
tasks:
|
||||
- include: disable_os_collect_config.yml
|
@ -1,17 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
- hosts: all
|
||||
tasks:
|
||||
- include: refresh_config.yml
|
@ -1,36 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Remove any cinder volume mounts that may be present"
|
||||
sudo: yes
|
||||
script: files/cleanup_cinder_devices.sh
|
||||
register: test_cinder_cleanup
|
||||
ignore_errors: yes
|
||||
- name: "If cinder cleanup failed, collect volume group data"
|
||||
command: vgdisplay -v
|
||||
when: instance_status == "ACTIVE" and test_cinder_cleanup.rc != 0
|
||||
- include: step_fail_unmount.yml
|
||||
when: instance_status == "ACTIVE" and test_cinder_cleanup.rc != 0
|
||||
- name: "Detach any loop devices in use"
|
||||
sudo: yes
|
||||
script: files/cleanup_loop_devices.sh
|
||||
register: test_loop_device_cleanup
|
||||
- name: "Collect list of loop devices"
|
||||
sudo: yes
|
||||
command: losetup -a
|
||||
ignore_errors: yes
|
||||
when: test_loop_device_cleanup.rc != 0
|
||||
- include: step_fail_unmount.yml
|
||||
when: instance_status == "ACTIVE" and test_loop_device_cleanup.rc != 0
|
@ -1,31 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: Determine if node is part of a cluster
|
||||
shell: grep -q "$(hostname)" "/mnt/state/var/lib/rabbitmq/mnesia/rabbit@$(hostname)/cluster_nodes.config"
|
||||
ignore_errors: yes
|
||||
register: rabbit_cluster_test
|
||||
- name: Collect names of post-configure.d rabbitmq files
|
||||
shell: ls "{{os_refresh_config_folder}}/post-configure.d/"|grep '\-rabbitmq$'
|
||||
register: test_rabbitmq_script_list
|
||||
when: single_controller is not defined and rabbit_cluster_test.rc == 0
|
||||
- name: If node rabbitmq cluster config was present, re-enable os-refresh-config post-configure.d.
|
||||
sudo: yes
|
||||
file: mode=0755 path="{{os_refresh_config_folder}}/post-configure.d/{{item}}"
|
||||
when: single_controller is not defined and rabbit_cluster_test.rc == 0
|
||||
with_items: test_rabbitmq_script_list.stdout_lines
|
||||
- name: "Removing temporary rabbitmq-server override"
|
||||
sudo: yes
|
||||
file: path=/etc/init/rabbitmq-server.override state=absent
|
@ -1,37 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
# Stop and disable os-collect-config
|
||||
#
|
||||
# Run from the tripleo-ansible directory:
|
||||
#
|
||||
- name: "Disable os-collect-config service"
|
||||
sudo: yes
|
||||
service: name=os-collect-config enabled=no state=stopped
|
||||
- name: "Remove file that allows os-collect-config start via upstart"
|
||||
shell: os-svc-enable-upstart os-collect-config disable
|
||||
sudo: yes
|
||||
- name: "Ensure os-collect-config local-data folder is present"
|
||||
sudo: yes
|
||||
file: path=/var/lib/os-collect-config/local-data state=directory owner=root group=root mode=0700
|
||||
when: online_upgrade is defined
|
||||
- name: "Reconfigure os-collect-config for local collector"
|
||||
sudo: yes
|
||||
copy:
|
||||
src: files/os-collect-config.conf
|
||||
dest: /etc/os-collect-config.conf
|
||||
- name: "Install os-collect-config disable sentinel file"
|
||||
sudo: yes
|
||||
file: path=/mnt/state/disable-os-collect-config owner=root group=root mode=644 state=touch
|
@ -1,21 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Create file that allows os-collect-config start via upstart"
|
||||
shell: os-svc-enable-upstart os-collect-config enable
|
||||
sudo: yes
|
||||
- name: "Enable os-collect-config via upstart and start the service"
|
||||
service: name=os-collect-config state=started
|
||||
sudo: yes
|
@ -1,7 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -eux
|
||||
|
||||
for CINDER_VOLUME in `lvdisplay | grep cinder-volumes | grep 'LV Path' | awk '{print $3}'`; do
|
||||
lvchange -a n $CINDER_VOLUME
|
||||
done
|
||||
vgchange -a n
|
@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -eux
|
||||
|
||||
for loopdevice in `losetup -a| cut -d ':' -f 1`; do
|
||||
losetup --detach $loopdevice
|
||||
done
|
@ -1,176 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import grp
|
||||
import optparse
|
||||
import os
|
||||
import pwd
|
||||
import stat
|
||||
|
||||
|
||||
def get_object_ids(file):
|
||||
stat_information = os.stat(file)
|
||||
return(stat_information.st_uid, stat_information.st_gid)
|
||||
|
||||
|
||||
def get_username_from_uid(old_uid, old_password_file):
|
||||
file = open(old_password_file)
|
||||
passwd_file = file.readlines()
|
||||
for user_entry in passwd_file:
|
||||
(
|
||||
user,
|
||||
passwd,
|
||||
uid,
|
||||
gid,
|
||||
gecos,
|
||||
home,
|
||||
shell
|
||||
) = user_entry.split(':')
|
||||
if old_uid == int(uid):
|
||||
return user
|
||||
return "ErrUserNotFound"
|
||||
|
||||
|
||||
def get_groupname_from_gid(old_gid, old_group_file):
|
||||
file = open(old_group_file)
|
||||
group_file = file.readlines()
|
||||
for group_entry in group_file:
|
||||
(
|
||||
group,
|
||||
passwd,
|
||||
gid,
|
||||
members
|
||||
) = group_entry.split(':')
|
||||
if old_gid == int(gid):
|
||||
return group
|
||||
return "ErrUserNotFound"
|
||||
|
||||
|
||||
def get_new_uid(username):
|
||||
return pwd.getpwnam(username).pw_uid
|
||||
|
||||
|
||||
def get_new_gid(groupname):
|
||||
return grp.getgrnam(groupname).gr_gid
|
||||
|
||||
|
||||
def run_check(object, old_password_file, old_group_file):
|
||||
(old_uid, old_gid) = get_object_ids(object)
|
||||
old_username = get_username_from_uid(old_uid, old_password_file)
|
||||
old_groupname = get_groupname_from_gid(old_uid, old_group_file)
|
||||
try:
|
||||
new_uid = get_new_uid(old_username)
|
||||
new_gid = get_new_gid(old_groupname)
|
||||
if old_uid != new_uid:
|
||||
if old_username in object:
|
||||
return(True, old_username, new_uid, old_groupname, new_gid)
|
||||
return(False, old_username, new_uid, old_groupname, old_gid)
|
||||
except:
|
||||
return(False, old_username, -1, old_groupname, -1)
|
||||
|
||||
|
||||
def recursive_update(directory, new_uid, new_gid):
|
||||
os.chown(directory, new_uid, new_gid)
|
||||
for root, dirs, files in os.walk(directory):
|
||||
for dir in dirs:
|
||||
os.chown(os.path.join(root, dir), new_uid, new_gid)
|
||||
for file in files:
|
||||
os.chown(os.path.join(root, file), new_uid, new_gid)
|
||||
|
||||
|
||||
def main():
|
||||
usage = "Usage: %prog -f old_password_file -d directory_to_update"
|
||||
parser = optparse.OptionParser(usage)
|
||||
parser.add_option(
|
||||
"-f",
|
||||
action="store",
|
||||
default=False,
|
||||
dest="old_password_file",
|
||||
help="Path to previous system password file"
|
||||
)
|
||||
parser.add_option(
|
||||
"-g",
|
||||
action="store",
|
||||
default=False,
|
||||
dest="old_group_file",
|
||||
help="Path to previous system password file"
|
||||
)
|
||||
parser.add_option(
|
||||
"-d",
|
||||
action="store",
|
||||
default=False,
|
||||
dest="directory",
|
||||
help="Directory to check and apply permission updates to"
|
||||
)
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if not options.directory:
|
||||
print("Error: please define a directory to run the program with -d")
|
||||
parser.print_help()
|
||||
return -1
|
||||
|
||||
if not options.old_password_file:
|
||||
print("Error: please define a directory to run the program with -d")
|
||||
parser.print_help()
|
||||
return -1
|
||||
|
||||
if not options.old_group_file:
|
||||
print("Error: please define a directory to run the program with -d")
|
||||
parser.print_help()
|
||||
return -1
|
||||
|
||||
|
||||
for object in os.listdir(options.directory):
|
||||
if os.path.isdir(os.path.join(options.directory, object)):
|
||||
(changed, old_user, new_uid, old_groupname, new_gid) = run_check(
|
||||
os.path.join(options.directory, object),
|
||||
options.old_password_file,
|
||||
options.old_group_file
|
||||
)
|
||||
if changed:
|
||||
print("Updating %s/%s for ownership to uid %s for %s" % (
|
||||
options.directory,
|
||||
object,
|
||||
new_uid,
|
||||
old_user
|
||||
)
|
||||
)
|
||||
try:
|
||||
recursive_update(
|
||||
os.path.join(options.directory, object),
|
||||
new_uid,
|
||||
new_gid
|
||||
)
|
||||
except:
|
||||
print("Failed to update ownership of %s/%s " % (
|
||||
options.directory,
|
||||
object
|
||||
)
|
||||
)
|
||||
else:
|
||||
print("ignoring %s/%s" % (
|
||||
options.directory,
|
||||
object
|
||||
)
|
||||
)
|
||||
else:
|
||||
print("Ignoring %s/%s as it is not a directory" % (
|
||||
options.directory,
|
||||
object
|
||||
)
|
||||
)
|
||||
|
||||
main()
|
@ -1,24 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
set -eux
|
||||
set -o pipefail
|
||||
|
||||
PATH=/usr/local/bin/:$PATH
|
||||
# Execute database creation step although suppress output
|
||||
# that may contain passwords.
|
||||
sed -i 's/| mysql$/| mysql --defaults-file=\/mnt\/state\/root\/metadata.my.cnf/' /usr/local/bin/os-db-create
|
||||
reset-db -c 2>&1 |grep -v "db_pass" |grep -v "os-db-create"
|
||||
reset-db -m 2>&1 |grep -v "db_pass" |grep -v "os-db-create"
|
@ -1,27 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('path', default='/var/lib/os-collect-config/local-data')
|
||||
parser.add_argument('--deployments-key', default='deployments')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
for fname in os.listdir(args.path):
|
||||
f = os.path.join(args.path, fname)
|
||||
with open(f) as infile:
|
||||
x = json.loads(infile.read())
|
||||
dp = args.deployments_key
|
||||
final_list = []
|
||||
if dp in x:
|
||||
if isinstance(x[dp], list):
|
||||
for d in x[dp]:
|
||||
name = d['name']
|
||||
if d.get('group', 'Heat::Ungrouped') in ('os-apply-config', 'Heat::Ungrouped'):
|
||||
final_list.append((name, d['config']))
|
||||
for oname, oconfig in final_list:
|
||||
with open('%s%s' % (f, oname), 'w') as outfile:
|
||||
outfile.write(json.dumps(oconfig))
|
@ -1,4 +0,0 @@
|
||||
[DEFAULT]
|
||||
collectors = ec2
|
||||
collectors = local
|
||||
command = os-refresh-config
|
@ -1,31 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
set -eux
|
||||
set -o pipefail
|
||||
|
||||
# This turns on an internal heartbeat mechanism in the ssh client
|
||||
# to prevent the client from believing inactivity is a connection
|
||||
# failure.
|
||||
if ! grep -q '^\s*ServerAliveInterval' /etc/ssh/ssh_config; then
|
||||
echo " ServerAliveInterval 30" >>/etc/ssh/ssh_config
|
||||
fi
|
||||
|
||||
# This causes the connection to wait until the defined number of
|
||||
# heartbeats are missed before terminating the connection.
|
||||
if ! grep -q '^\s*ServerAliveCountMax' /etc/ssh/ssh_config; then
|
||||
echo " ServerAliveCountMax 6" >>/etc/ssh/ssh_config
|
||||
fi
|
||||
|
@ -1 +0,0 @@
|
||||
post-start exec /bin/true
|
@ -1,36 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eux
|
||||
set -o pipefail
|
||||
|
||||
# Get and return the wsrep_local_state.
|
||||
function get_state() {
|
||||
mysql --defaults-file=/mnt/state/root/metadata.my.cnf --socket /var/run/mysqld/mysqld.sock -N -e "SHOW STATUS LIKE 'wsrep_local_state'"|cut -f2
|
||||
}
|
||||
|
||||
# Loop until timed out, exit if wsrep_local_state equals Synced "4"
|
||||
function wait_for_wsrep_synced() {
|
||||
COUNT=0
|
||||
while true;
|
||||
do
|
||||
if [ "4" -eq $(get_state) ]; then
|
||||
echo "Local wsrep_local_state has reached Synced, breaking out of loop."
|
||||
break
|
||||
fi
|
||||
echo ".... Sleeping 30 seconds"
|
||||
sleep 30
|
||||
COUNT=$((COUNT + 1))
|
||||
if [ $COUNT -gt 61 ]; then
|
||||
echo "Aborting, exiting 1, waited for a 30 minutes. You can re-attempt this setup using ansible-playbook options --start-at-task or --step."
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
if ! which mysql &>/dev/null; then
|
||||
echo "Failure - MySQL CLI not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Beginning MySQL wait - Time: $(date)"
|
||||
wait_for_wsrep_synced
|
||||
echo "Exiting MySQL wait - Time: $(date)"
|
@ -1,38 +0,0 @@
|
||||
- name: Rename MySQL upstart script
|
||||
sudo: yes
|
||||
command: mv -f /etc/init/mysql.conf /etc/init/mysql-boot-control.conf removes=/etc/init/mysql.conf
|
||||
- service: name=mysql state=started
|
||||
ignore_errors: yes
|
||||
- name: Fetch Galera sync status from MySQL
|
||||
sudo: yes
|
||||
command: mysql --defaults-file=/mnt/state/root/metadata.my.cnf --socket /var/run/mysqld/mysqld.sock -N -e "SHOW STATUS LIKE 'wsrep_local_state'"
|
||||
when: helion is not defined
|
||||
register: wsrep_local_state
|
||||
- set_fact: galera_status="Synced"
|
||||
when: helion is not defined and wsrep_local_state.stdout == "wsrep_local_state\t4"
|
||||
- set_fact: galera_status="Out of Sync"
|
||||
when: helion is not defined and wsrep_local_state.stdout != "wsrep_local_state\t4"
|
||||
- name: Fetch Galera cluster size from MySQL
|
||||
sudo: yes
|
||||
shell: mysql --defaults-file=/mnt/state/root/metadata.my.cnf --socket /var/run/mysqld/mysqld.sock -N -e "SHOW STATUS LIKE 'wsrep_cluster_size'"|cut -f2
|
||||
when: helion is not defined
|
||||
register: wsrep_cluster_size
|
||||
- set_fact: galera_cluster_size="{{wsrep_cluster_size.stdout}}"
|
||||
when: helion is not defined
|
||||
- name: Fetch Galera sync status from MySQL - Helion
|
||||
sudo: yes
|
||||
command: mysql --defaults-file=/mnt/state/root/metadata.my.cnf -N -e "SHOW STATUS LIKE 'wsrep_local_state'"
|
||||
when: helion is defined
|
||||
register: wsrep_local_state
|
||||
- set_fact: galera_status="Synced"
|
||||
when: helion is defined and wsrep_local_state.stdout == "wsrep_local_state\t4"
|
||||
- set_fact: galera_status="Out of Sync"
|
||||
when: helion is defined and wsrep_local_state.stdout != "wsrep_local_state\t4"
|
||||
- name: Fetch Galera cluster size from MySQL - Helion
|
||||
sudo: yes
|
||||
shell: mysql --defaults-file=/mnt/state/root/metadata.my.cnf -N -e "SHOW STATUS LIKE 'wsrep_cluster_size'"|cut -f2
|
||||
when: helion is defined
|
||||
register: wsrep_cluster_size
|
||||
- set_fact: galera_cluster_size="{{wsrep_cluster_size.stdout}}"
|
||||
when: helion is defined
|
||||
|
@ -1,245 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# This code is part of Ansible, but is an independent component.
|
||||
# This particular file snippet, and this file snippet only, is BSD licensed.
|
||||
# Modules you write using this snippet, which is embedded dynamically by Ansible
|
||||
# still belong to the author of the module, and may assign their own license
|
||||
# to the complete work.
|
||||
#
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
try:
|
||||
import glanceclient.v2.client as glanceclient
|
||||
except ImportError:
|
||||
print("failed=True msg='module glanceclient is required for this module'")
|
||||
try:
|
||||
from keystoneclient.v3 import client as ksclient
|
||||
except ImportError:
|
||||
print(
|
||||
"failed=True msg='module keystoneclient is required for this module'"
|
||||
)
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
|
||||
try:
|
||||
from novaclient.v1_1 import client as nova_client
|
||||
from novaclient import exceptions
|
||||
except ImportError:
|
||||
print("failed=True msg='module novaclient is required for this module'")
|
||||
|
||||
import time
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: glance_download
|
||||
short_description: Download file from Glance
|
||||
description:
|
||||
- Return the requested file from Glance to a location defined by the user.
|
||||
options:
|
||||
login_username:
|
||||
description:
|
||||
- login username to authenticate to keystone
|
||||
required: true
|
||||
default: admin
|
||||
login_password:
|
||||
description:
|
||||
- Password of login user
|
||||
required: true
|
||||
default: 'yes'
|
||||
login_tenant_name:
|
||||
description:
|
||||
- The tenant name of the login user
|
||||
required: true
|
||||
default: 'yes'
|
||||
auth_url:
|
||||
description:
|
||||
- The keystone url for authentication
|
||||
required: false
|
||||
default: 'http://127.0.0.1:35357/v2.0/'
|
||||
region_name:
|
||||
description:
|
||||
- Name of the region
|
||||
required: false
|
||||
default: None
|
||||
image_id:
|
||||
description:
|
||||
- Glance file ID that you wish to download.
|
||||
required: true
|
||||
default: None
|
||||
path:
|
||||
description:
|
||||
- Location where to save the file from Glance to
|
||||
required: true
|
||||
default: None
|
||||
requirements: ["glanceclient"]
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Downloads a glance image to the defined path
|
||||
- glance_download:
|
||||
login_username: admin
|
||||
login_password: admin
|
||||
login_tenant_name: admin
|
||||
image_id: 4f905f38-e52a-43d2-b6ec-754a13ffb529
|
||||
path: /tmp/4f905f38-e52a-43d2-b6ec-754a13ffb529.qcow2
|
||||
'''
|
||||
|
||||
|
||||
# The following openstack_ is a copy paste from an upcoming
|
||||
# core module "lib/ansible/module_utils/openstack.py" Once that's landed,
|
||||
# these should be replaced with a line at the bottom of the file:
|
||||
# from ansible.module_utils.openstack import *
|
||||
def openstack_argument_spec():
|
||||
# Consume standard OpenStack environment variables.
|
||||
# This is mainly only useful for ad-hoc command line operation as
|
||||
# in playbooks one would assume variables would be used appropriately
|
||||
OS_AUTH_URL = os.environ.get('OS_AUTH_URL', 'http://127.0.0.1:35357/v2.0/')
|
||||
OS_PASSWORD = os.environ.get('OS_PASSWORD', None)
|
||||
OS_REGION_NAME = os.environ.get('OS_REGION_NAME', None)
|
||||
OS_USERNAME = os.environ.get('OS_USERNAME', 'admin')
|
||||
OS_TENANT_NAME = os.environ.get('OS_TENANT_NAME', OS_USERNAME)
|
||||
|
||||
spec = dict(
|
||||
login_username=dict(default=OS_USERNAME),
|
||||
auth_url=dict(default=OS_AUTH_URL),
|
||||
region_name=dict(default=OS_REGION_NAME),
|
||||
availability_zone=dict(default=None),
|
||||
)
|
||||
if OS_PASSWORD:
|
||||
spec['login_password'] = dict(default=OS_PASSWORD)
|
||||
else:
|
||||
spec['login_password'] = dict(required=True)
|
||||
if OS_TENANT_NAME:
|
||||
spec['login_tenant_name'] = dict(default=OS_TENANT_NAME)
|
||||
else:
|
||||
spec['login_tenant_name'] = dict(required=True)
|
||||
return spec
|
||||
|
||||
|
||||
def _glance_get_image_checksum(glance, image_id):
|
||||
return glance.images.get(image_id).checksum
|
||||
|
||||
|
||||
def _md5sum_file(path):
|
||||
try:
|
||||
with open(path) as file_object:
|
||||
checksum = hashlib.md5()
|
||||
while True:
|
||||
data = file_object.read(65535)
|
||||
if not data:
|
||||
break
|
||||
checksum.update(data)
|
||||
return checksum.hexdigest()
|
||||
except Excption, e:
|
||||
print("Checksum operaction failed: %s" % e.message)
|
||||
|
||||
|
||||
def _glance_download(module, glance, image_id, path):
|
||||
image_checksum = _glance_get_image_checksum(glance, image_id)
|
||||
if os.path.isfile(path):
|
||||
file_checksum = _md5sum_file(path)
|
||||
if image_checksum == file_checksum:
|
||||
module.exit_json(
|
||||
ansible_facts={
|
||||
'returned_checksum': file_checksum
|
||||
}
|
||||
)
|
||||
try:
|
||||
file_data = glance.images.data(image_id)
|
||||
glanceclient.utils.save_image(file_data, path)
|
||||
except:
|
||||
module.fail_json(
|
||||
msg="Retrieval of image from Glance failed."
|
||||
)
|
||||
file_checksum = _md5sum_file(path)
|
||||
if image_checksum == file_checksum:
|
||||
module.exit_json(
|
||||
ansible_facts={
|
||||
'returned_checksum': file_checksum
|
||||
}
|
||||
)
|
||||
else:
|
||||
module.fail_json(
|
||||
msg="Glance checksum %s != %s checksum %s" % (
|
||||
image_checksum,
|
||||
path,
|
||||
file_checksum
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = openstack_argument_spec()
|
||||
argument_spec.update(dict(
|
||||
image_id=dict(required=True),
|
||||
path=dict(required=True)
|
||||
))
|
||||
module = AnsibleModule(argument_spec=argument_spec)
|
||||
try:
|
||||
if '/v2.0' in module.params['auth_url']:
|
||||
module.params['auth_url'] = module.params['auth_url'].replace(
|
||||
'/v2.0',
|
||||
'/v3'
|
||||
)
|
||||
keystone = ksclient.Client(
|
||||
username=module.params['login_username'],
|
||||
password=module.params['login_password'],
|
||||
tenant=module.params['login_tenant_name'],
|
||||
auth_url=module.params['auth_url'],
|
||||
region_name=module.params['region_name']
|
||||
)
|
||||
keystone.authenticate()
|
||||
except:
|
||||
module.fail_json(
|
||||
msg="Failed to Authenticate to Keystone"
|
||||
)
|
||||
try:
|
||||
glance_endpoint = keystone.service_catalog.url_for(
|
||||
service_type='image',
|
||||
endpoint_type='publicURL'
|
||||
)
|
||||
except:
|
||||
module.fail_json(
|
||||
msg="Failed to retrieve image server URL"
|
||||
)
|
||||
try:
|
||||
glance = glanceclient.Client(
|
||||
endpoint=glance_endpoint,
|
||||
token=keystone.auth_token
|
||||
)
|
||||
except:
|
||||
module.fail_json(
|
||||
msg="Failed to connect to Glance"
|
||||
)
|
||||
|
||||
_glance_download(
|
||||
module,
|
||||
glance,
|
||||
module.params['image_id'],
|
||||
module.params['path']
|
||||
)
|
||||
|
||||
|
||||
from ansible.module_utils.basic import *
|
||||
main()
|
@ -1,350 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# This code is part of Ansible, but is an independent component. This
|
||||
# particular file snippet, and this file snippet only, is BSD
|
||||
# licensed. Modules you write using this snippet, which is embedded
|
||||
# dynamically by Ansible still belong to the author of the module, and
|
||||
# may assign their own license to the complete work.
|
||||
#
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import os
|
||||
|
||||
try:
|
||||
from novaclient.v1_1 import client as nova_client
|
||||
from novaclient import exceptions
|
||||
import time
|
||||
except ImportError:
|
||||
print("failed=True msg='novaclient is required for this module'")
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: nova_powercontrol
|
||||
short_description: Stops/Starts virtual machines via nova.
|
||||
description:
|
||||
- Controls the power state of virtual machines via nova.
|
||||
options:
|
||||
login_username:
|
||||
description:
|
||||
- login username to authenticate to keystone
|
||||
required: true
|
||||
default: admin
|
||||
login_password:
|
||||
description:
|
||||
- Password of login user
|
||||
required: true
|
||||
default: 'yes'
|
||||
login_tenant_name:
|
||||
description:
|
||||
- The tenant name of the login user
|
||||
required: true
|
||||
default: 'yes'
|
||||
auth_url:
|
||||
description:
|
||||
- The keystone url for authentication
|
||||
required: false
|
||||
default: 'http://127.0.0.1:35357/v2.0/'
|
||||
region_name:
|
||||
description:
|
||||
- Name of the region
|
||||
required: false
|
||||
default: None
|
||||
state:
|
||||
description:
|
||||
- The desired state for the instance to be set to.
|
||||
required: true
|
||||
default: None
|
||||
instance_id:
|
||||
description:
|
||||
- Instance ID of a single instance to control.
|
||||
default: None
|
||||
hypervisor:
|
||||
description:
|
||||
- Hypervisor ID of the instances to control.
|
||||
default: None
|
||||
zone:
|
||||
description:
|
||||
- zone name of the instances to control.
|
||||
default: None
|
||||
all_instances:
|
||||
description:
|
||||
- Any value to affirm decision to act upon all instances.
|
||||
default: None
|
||||
requirements: ["novaclient"]
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Changes the power state via nova
|
||||
- nova_power_control:
|
||||
login_username: admin
|
||||
login_password: admin
|
||||
login_tenant_name: admin
|
||||
instance_id: 4f905f38-e52a-43d2-b6ec-754a13ffb529
|
||||
state: stopped
|
||||
'''
|
||||
|
||||
|
||||
# The following two openstack_ are copy pasted from an upcoming
|
||||
# core module "lib/ansible/module_utils/openstack.py" Once that's landed,
|
||||
# these should be replaced with a line at the bottom of the file:
|
||||
# from ansible.module_utils.openstack import *
|
||||
def openstack_argument_spec():
|
||||
# Consume standard OpenStack environment variables.
|
||||
# This is mainly only useful for ad-hoc command line operation as
|
||||
# in playbooks one would assume variables would be used appropriately
|
||||
OS_AUTH_URL = os.environ.get('OS_AUTH_URL', 'http://127.0.0.1:35357/v2.0/')
|
||||
OS_PASSWORD = os.environ.get('OS_PASSWORD', None)
|
||||
OS_REGION_NAME = os.environ.get('OS_REGION_NAME', None)
|
||||
OS_USERNAME = os.environ.get('OS_USERNAME', 'admin')
|
||||
OS_TENANT_NAME = os.environ.get('OS_TENANT_NAME', OS_USERNAME)
|
||||
|
||||
spec = dict(
|
||||
login_username=dict(default=OS_USERNAME),
|
||||
auth_url=dict(default=OS_AUTH_URL),
|
||||
region_name=dict(default=OS_REGION_NAME),
|
||||
availability_zone=dict(default=None),
|
||||
)
|
||||
if OS_PASSWORD:
|
||||
spec['login_password'] = dict(default=OS_PASSWORD)
|
||||
else:
|
||||
spec['login_password'] = dict(required=True)
|
||||
if OS_TENANT_NAME:
|
||||
spec['login_tenant_name'] = dict(default=OS_TENANT_NAME)
|
||||
else:
|
||||
spec['login_tenant_name'] = dict(required=True)
|
||||
return spec
|
||||
|
||||
|
||||
def _get_server(nova, instance_id):
|
||||
try:
|
||||
return nova.servers.get(instance_id)
|
||||
except Exception, e:
|
||||
module.fail_json(
|
||||
msg="Error accessing instance %s: %s" % (instance_id, e.message)
|
||||
)
|
||||
|
||||
|
||||
def _write_metadata(nova, server):
|
||||
nova.servers.set_meta(
|
||||
server.id,
|
||||
{'ansible_previous_state': server.status}
|
||||
)
|
||||
|
||||
|
||||
def _suspend_instance(nova, instance_id):
|
||||
try:
|
||||
server = None
|
||||
server = _get_server(nova, instance_id)
|
||||
if server.status != "ACTIVE":
|
||||
if server.status != "PAUSED":
|
||||
return False
|
||||
_write_metadata(nova, server)
|
||||
nova.servers.suspend(server.id)
|
||||
return (True, nova.servers.suspend(server.id))
|
||||
except Exception, e:
|
||||
return (False, e.message)
|
||||
|
||||
|
||||
def _resume_instance(nova, instance_id):
|
||||
try:
|
||||
server = None
|
||||
server = _get_server(nova, instance_id)
|
||||
if server.status != "SUSPENDED":
|
||||
return False
|
||||
_write_metadata(nova, server)
|
||||
return (True, nova.servers.resume(server.id))
|
||||
except Exception, e:
|
||||
return (False, e.message)
|
||||
|
||||
|
||||
def _stop_instance(nova, instance_id):
|
||||
try:
|
||||
server = None
|
||||
server = _get_server(nova, instance_id)
|
||||
if server.status != "ACTIVE":
|
||||
if server.status != "PAUSED":
|
||||
return False
|
||||
_write_metadata(nova, server)
|
||||
return (True, nova.servers.stop(server.id))
|
||||
except Exception, e:
|
||||
return (False, e.message)
|
||||
|
||||
|
||||
def _start_instance(nova, instance_id):
|
||||
try:
|
||||
server = None
|
||||
server = _get_server(nova, instance_id)
|
||||
if server.status != "STOPPED":
|
||||
if server.status != "SUSPENDED":
|
||||
if server.status != "PAUSED":
|
||||
return False
|
||||
_write_metadata(nova, server)
|
||||
return (True, nova.servers.start(server.id))
|
||||
except Exception, e:
|
||||
return (False, e.message)
|
||||
|
||||
|
||||
def _previous_state(nova, instance_id):
|
||||
"""
|
||||
Attempts to return instances to their previous state if they were
|
||||
stopped or suspended.
|
||||
"""
|
||||
try:
|
||||
server = _get_server(nova, instance_id)
|
||||
if server.metadata["ansible_previous_state"] == "ACTIVE":
|
||||
if server.status != "ACTIVE":
|
||||
if server.status == "STOPPED":
|
||||
return _start_instance(nova, instance_id)
|
||||
if server.status == "SUSPENDED":
|
||||
return _resume_instance(nova, instance_id)
|
||||
return (False, None)
|
||||
except Exception, e:
|
||||
return (False, e.message)
|
||||
|
||||
|
||||
def _determine_task(nova, instance_id, action):
|
||||
choice = {
|
||||
'running': _start_instance,
|
||||
'start': _start_instance,
|
||||
'on': _start_instance,
|
||||
'stopped': _stop_instance,
|
||||
'stop': _stop_instance,
|
||||
'off': _stop_instance,
|
||||
'resume': _resume_instance,
|
||||
'previous': _previous_state
|
||||
}
|
||||
return choice[action](nova, instance_id)
|
||||
|
||||
|
||||
def _many_servers(module, nova, servers):
|
||||
"""
|
||||
Enumerates through the list of services and calls
|
||||
_determine_task.
|
||||
"""
|
||||
results = []
|
||||
for server in servers:
|
||||
result = _determine_task(nova, server.id, module.params['state'])
|
||||
results.append(results)
|
||||
module.exit_json(changed=True, output=results)
|
||||
|
||||
|
||||
def _all_instances(module, nova):
|
||||
"""
|
||||
Retrieves the entire list of servers and changes and applies the
|
||||
desired state.
|
||||
"""
|
||||
results = []
|
||||
for server in nova.servers.list():
|
||||
_determine_task(nova, server.id, module.params['state'])
|
||||
results.append(results)
|
||||
module.exit_json(changed=True, output=results)
|
||||
|
||||
|
||||
def _nova_powercontrol(module, nova):
|
||||
state = module.params['state']
|
||||
if module.params['instance_id'] is not None:
|
||||
(status, message) = _determine_task(
|
||||
nova,
|
||||
module.params['instance_id'],
|
||||
state
|
||||
)
|
||||
if status:
|
||||
module.exit_json(changed=True, output=message)
|
||||
else:
|
||||
module.fail_json(
|
||||
msg="Instance %s failed to update with error %s" % (
|
||||
module.params['instance_id'],
|
||||
message
|
||||
)
|
||||
)
|
||||
elif module.params['hypervisor'] is not None:
|
||||
try:
|
||||
hypervisor = nova.hypervisors.search(
|
||||
True,
|
||||
module.params['hypervisor'],
|
||||
servers=True
|
||||
)
|
||||
_many_servers(module, nova, hypervisor.servers)
|
||||
except:
|
||||
module.fail_json(
|
||||
msg="Unable to find zone %s" % module.params['hypervisor']
|
||||
)
|
||||
elif module.params['zone'] is not None:
|
||||
try:
|
||||
servers = nova.servers.list(
|
||||
True,
|
||||
{'OS-EXT-AZ:availability_zone': module.params['zone']}
|
||||
)
|
||||
_many_servers(module, nova, servers)
|
||||
except:
|
||||
module.fail_json(
|
||||
msg="Unable to find zone %s" % module.params['zone']
|
||||
)
|
||||
elif module.params['all_instances'] is not None:
|
||||
_all_instances(module, nova)
|
||||
else:
|
||||
module.fail_json(
|
||||
msg="Unable to proceed: Requires instance_id, hypervisor, "
|
||||
"zone, or special flag all_instances."
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = openstack_argument_spec()
|
||||
argument_spec.update(dict(
|
||||
state=dict(required=True),
|
||||
instance_id=dict(),
|
||||
hypervisor=dict(),
|
||||
zone=dict(),
|
||||
all_instances=dict()
|
||||
))
|
||||
module = AnsibleModule(argument_spec=argument_spec)
|
||||
|
||||
nova = nova_client.Client(module.params['login_username'],
|
||||
module.params['login_password'],
|
||||
module.params['login_tenant_name'],
|
||||
module.params['auth_url'],
|
||||
region_name=module.params['region_name'],
|
||||
service_type='compute')
|
||||
try:
|
||||
nova.authenticate()
|
||||
except exceptions.Unauthorized, e:
|
||||
module.fail_json(
|
||||
msg="Invalid OpenStack Nova credentials.: %s" % e.message
|
||||
)
|
||||
except exceptions.AuthorizationFailure, e:
|
||||
module.fail_json(
|
||||
msg="Unable to authorize user: %s" % e.message
|
||||
)
|
||||
|
||||
_nova_powercontrol(module, nova)
|
||||
|
||||
|
||||
# this is magic, see lib/ansible/module_common.py
|
||||
from ansible.module_utils.basic import *
|
||||
main()
|
@ -1,268 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# This code is part of Ansible, but is an independent component.
|
||||
# This particular file snippet, and this file snippet only, is BSD licensed.
|
||||
# Modules you write using this snippet, which is embedded dynamically by Ansible
|
||||
# still belong to the author of the module, and may assign their own license
|
||||
# to the complete work.
|
||||
#
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
try:
|
||||
from novaclient.v1_1 import client as nova_client
|
||||
from novaclient import exceptions
|
||||
import time
|
||||
except ImportError:
|
||||
print("failed=True msg='novaclient is required for this module'")
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: nova_rebuild
|
||||
short_description: Rebuild VMs from OpenStack
|
||||
description:
|
||||
- Rebuild (re-image) virtual machines from Openstack.
|
||||
options:
|
||||
login_username:
|
||||
description:
|
||||
- login username to authenticate to keystone
|
||||
required: true
|
||||
default: admin
|
||||
login_password:
|
||||
description:
|
||||
- Password of login user
|
||||
required: true
|
||||
default: 'yes'
|
||||
login_tenant_name:
|
||||
description:
|
||||
- The tenant name of the login user
|
||||
required: true
|
||||
default: 'yes'
|
||||
auth_url:
|
||||
description:
|
||||
- The keystone url for authentication
|
||||
required: false
|
||||
default: 'http://127.0.0.1:35357/v2.0/'
|
||||
region_name:
|
||||
description:
|
||||
- Name of the region
|
||||
required: false
|
||||
default: None
|
||||
name:
|
||||
description:
|
||||
- Name of the instance to be rebuilt
|
||||
default: None
|
||||
instance_id:
|
||||
description:
|
||||
- Instance ID of the instance to be rebuilt
|
||||
default: None
|
||||
image_id:
|
||||
description:
|
||||
- The id of the image that has to be cloned
|
||||
required: true
|
||||
default: None
|
||||
preserve_ephemeral:
|
||||
description:
|
||||
- Whether to preserve ephemeral storage on the instance
|
||||
required: false
|
||||
default: false
|
||||
wait:
|
||||
description:
|
||||
- If the module should wait for the VM to be created.
|
||||
required: false
|
||||
default: 'yes'
|
||||
wait_for:
|
||||
description:
|
||||
- Number of seconds the module should wait for the VM to get into active state
|
||||
required: false
|
||||
default: 600
|
||||
requirements: ["novaclient"]
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Rebuilds an existing VM with a new image
|
||||
- nova_rebuild:
|
||||
login_username: admin
|
||||
login_password: admin
|
||||
login_tenant_name: admin
|
||||
name: vm1
|
||||
image_id: 4f905f38-e52a-43d2-b6ec-754a13ffb529
|
||||
wait_for: 200
|
||||
'''
|
||||
|
||||
|
||||
# The following two openstack_ are copy paste from an upcoming
|
||||
# core module "lib/ansible/module_utils/openstack.py" Once that's landed,
|
||||
# these should be replaced with a line at the bottom of the file:
|
||||
# from ansible.module_utils.openstack import *
|
||||
def openstack_argument_spec():
|
||||
# Consume standard OpenStack environment variables.
|
||||
# This is mainly only useful for ad-hoc command line operation as
|
||||
# in playbooks one would assume variables would be used appropriately
|
||||
OS_AUTH_URL=os.environ.get('OS_AUTH_URL', 'http://127.0.0.1:35357/v2.0/')
|
||||
OS_PASSWORD=os.environ.get('OS_PASSWORD', None)
|
||||
OS_REGION_NAME=os.environ.get('OS_REGION_NAME', None)
|
||||
OS_USERNAME=os.environ.get('OS_USERNAME', 'admin')
|
||||
OS_TENANT_NAME=os.environ.get('OS_TENANT_NAME', OS_USERNAME)
|
||||
|
||||
spec = dict(
|
||||
login_username = dict(default=OS_USERNAME),
|
||||
auth_url = dict(default=OS_AUTH_URL),
|
||||
region_name = dict(default=OS_REGION_NAME),
|
||||
availability_zone = dict(default=None),
|
||||
)
|
||||
if OS_PASSWORD:
|
||||
spec['login_password'] = dict(default=OS_PASSWORD)
|
||||
else:
|
||||
spec['login_password'] = dict(required=True)
|
||||
if OS_TENANT_NAME:
|
||||
spec['login_tenant_name'] = dict(default=OS_TENANT_NAME)
|
||||
else:
|
||||
spec['login_tenant_name'] = dict(required=True)
|
||||
return spec
|
||||
|
||||
|
||||
def openstack_find_nova_addresses(addresses, ext_tag, key_name=None):
|
||||
|
||||
ret = []
|
||||
for (k, v) in addresses.iteritems():
|
||||
if key_name and k == key_name:
|
||||
ret.extend([addrs['addr'] for addrs in v])
|
||||
else:
|
||||
for interface_spec in v:
|
||||
if 'OS-EXT-IPS:type' in interface_spec and interface_spec['OS-EXT-IPS:type'] == ext_tag:
|
||||
ret.append(interface_spec['addr'])
|
||||
return ret
|
||||
|
||||
|
||||
def _rebuild_server(module, nova):
|
||||
server = None
|
||||
last_error = None
|
||||
last_stacktrace = None
|
||||
try:
|
||||
if module.params.get('instance_id') is None:
|
||||
servers = nova.servers.list(True, {'name': module.params['name']})
|
||||
if servers:
|
||||
# the {'name': module.params['name']} will also return servers
|
||||
# with names that partially match the server name, so we have to
|
||||
# strictly filter here
|
||||
servers = [x for x in servers if x.name == module.params['name']]
|
||||
if servers:
|
||||
server = servers[0]
|
||||
else:
|
||||
server = nova.servers.get(module.params['instance_id'])
|
||||
except Exception, e:
|
||||
module.fail_json(msg = "Error in getting the server list: %s" % e.message)
|
||||
if not server:
|
||||
module.exit_json(changed = False, result = "not present")
|
||||
|
||||
bootargs = [server, module.params['image_id']]
|
||||
bootkwargs = {
|
||||
'preserve_ephemeral' : module.params['preserve_ephemeral'],
|
||||
}
|
||||
try:
|
||||
server = nova.servers.rebuild(*bootargs, **bootkwargs)
|
||||
server = nova.servers.get(server.id)
|
||||
except Exception, e:
|
||||
module.fail_json( msg = "Error in rebuilding instance: %s " % e.message)
|
||||
if module.params['wait'] == 'yes':
|
||||
expire = time.time() + int(module.params['wait_for'])
|
||||
while time.time() < expire:
|
||||
try:
|
||||
server = nova.servers.get(server.id)
|
||||
except Exception, last_error:
|
||||
# This logic attempts to retry a failed status query
|
||||
# once before aborting and returning an error to
|
||||
# Ansible. This helps prevent momentarilly transient
|
||||
# issues from creating spurious issues.
|
||||
#
|
||||
# Ideally, we would change this logic to something
|
||||
# along the lines of wait_for, although logging
|
||||
# would need to be addressed so issues can be
|
||||
# identified should errors occur.
|
||||
last_error = traceback.format_exc
|
||||
time.sleep(2)
|
||||
try:
|
||||
server = nova.servers.get(server.id)
|
||||
except Exception, error:
|
||||
module.fail_json(
|
||||
msg = ("Error in getting info for instance: %s\n"
|
||||
"Initial error: %s\n"
|
||||
"Stack backtrace: %s\n"
|
||||
"Terminal error: %s\n"
|
||||
"Terminal stack backtrace: %s") % (
|
||||
last_stracetrace,
|
||||
last_error.message,
|
||||
error.message,
|
||||
traceback.format_exc
|
||||
)
|
||||
)
|
||||
|
||||
if server.status == 'ACTIVE':
|
||||
private = openstack_find_nova_addresses(getattr(server, 'addresses'), 'fixed', 'private')
|
||||
public = openstack_find_nova_addresses(getattr(server, 'addresses'), 'floating', 'public')
|
||||
module.exit_json(changed = True, id = server.id, private_ip=''.join(private), public_ip=''.join(public), status = server.status, info = server._info)
|
||||
if server.status == 'ERROR':
|
||||
module.fail_json(msg = "Instance exited Nova Rebuild in an ERROR state, please check OpenStack logs")
|
||||
time.sleep(2)
|
||||
|
||||
module.fail_json(msg = "Timeout waiting for the server to come up.. Please check manually")
|
||||
if server.status == 'ERROR':
|
||||
module.fail_json(msg = "Error in rebuilding the server.. Please check manually")
|
||||
private = openstack_find_nova_addresses(getattr(server, 'addresses'), 'fixed', 'private')
|
||||
public = openstack_find_nova_addresses(getattr(server, 'addresses'), 'floating', 'public')
|
||||
module.exit_json(changed = True, id = info['id'], private_ip=''.join(private), public_ip=''.join(public), status = server.status, info = server._info)
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = openstack_argument_spec()
|
||||
argument_spec.update(dict(
|
||||
name = dict(),
|
||||
instance_id = dict(),
|
||||
image_id = dict(required=True),
|
||||
preserve_ephemeral = dict(default=False, choices=[True, False]),
|
||||
wait = dict(default='yes', choices=['yes', 'no']),
|
||||
wait_for = dict(default=600),
|
||||
))
|
||||
module = AnsibleModule(argument_spec=argument_spec)
|
||||
|
||||
nova = nova_client.Client(module.params['login_username'],
|
||||
module.params['login_password'],
|
||||
module.params['login_tenant_name'],
|
||||
module.params['auth_url'],
|
||||
region_name=module.params['region_name'],
|
||||
service_type='compute')
|
||||
try:
|
||||
nova.authenticate()
|
||||
except exceptions.Unauthorized, e:
|
||||
module.fail_json(msg = "Invalid OpenStack Nova credentials.: %s" % e.message)
|
||||
except exceptions.AuthorizationFailure, e:
|
||||
module.fail_json(msg = "Unable to authorize user: %s" % e.message)
|
||||
|
||||
_rebuild_server(module, nova)
|
||||
|
||||
# this is magic, see lib/ansible/module_common.py
|
||||
from ansible.module_utils.basic import *
|
||||
main()
|
@ -1,42 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import subprocess
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
existing_services = set()
|
||||
for init_filename in os.listdir('/etc/init.d'):
|
||||
if init_filename[0] == '.':
|
||||
continue
|
||||
existing_services.add(init_filename)
|
||||
try:
|
||||
initctl_list = subprocess.Popen(['initctl', 'list'],
|
||||
stdout=subprocess.PIPE)
|
||||
for upstart_job in initctl_list.stdout:
|
||||
existing_services.add(upstart_job.split(' ', 1)[0])
|
||||
except subprocess.CalledProcessError as e:
|
||||
if e.errno != 2:
|
||||
raise e
|
||||
|
||||
module = AnsibleModule(argument_spec={})
|
||||
module.exit_json(ansible_facts={'existing_services':
|
||||
list(existing_services)})
|
||||
|
||||
|
||||
from ansible.module_utils.basic import *
|
||||
main()
|
@ -1,17 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
- name: "Ensure /root/.my.cnf is present"
|
||||
sudo: yes
|
||||
command: cp -a /mnt/state/root/metadata.my.cnf /root/.my.cnf creates=/root/.my.cnf
|
@ -1,17 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
- name: Rename MySQL upstart script
|
||||
sudo: yes
|
||||
command: mv -f /etc/init/mysql.conf /etc/init/mysql-boot-control.conf removes=/etc/init/mysql.conf
|
@ -1,124 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- hosts: localhost
|
||||
roles:
|
||||
- { role: pre_flight_disk_check, fail_percent: 20, exclude_mounts: [] }
|
||||
- hosts: undercloud
|
||||
roles:
|
||||
- { role: pre_flight_disk_check, fail_percent: 20, exclude_mounts: [], when: instance_status == "ACTIVE" }
|
||||
- hosts: controller
|
||||
vars:
|
||||
num_bootstrap_hosts: "{{ groups['controller-bootstrap'] | length }}"
|
||||
expected_bootstrap_hosts: 1
|
||||
num_controller_hosts: "{{ groups['controller'] | length }}"
|
||||
expected_controller_hosts: 2
|
||||
tasks:
|
||||
- name: "Verify correct number of controller bootstrap nodes"
|
||||
fail: >
|
||||
msg="The number of bootstrap nodes is "{{ num_bootstrap_hosts }}" \
|
||||
must be exactly "{{ expected_bootstrap_hosts }}"!"
|
||||
when: num_bootstrap_hosts | int != expected_bootstrap_hosts
|
||||
- name: "Verify correct number of controller non-bootstrap nodes"
|
||||
fail: >
|
||||
msg="The number of controller non-bootstrap nodes is \
|
||||
"{{ num_controller_hosts }}" must be exactly \
|
||||
"{{ expected_controller_hosts }}"!"
|
||||
when: num_controller_hosts | int != expected_controller_hosts
|
||||
- hosts: controller-bootstrap:controller
|
||||
name: "Check Controller Node Status - Ensuring MySQL is running"
|
||||
sudo: yes
|
||||
gather_facts: yes
|
||||
max_fail_percentage: 0
|
||||
tasks:
|
||||
- name: "Verify controller nodes are ACTIVE"
|
||||
fail: >
|
||||
msg="One of more controller nodes don't have a status of \
|
||||
ACTIVE in nova, cannot proceed with update"
|
||||
when: instance_status != "ACTIVE"
|
||||
- name: "Rename MySQL upstart configuration, if necessary, to obtain correct results."
|
||||
sudo: yes
|
||||
command: mv -f /etc/init/mysql.conf /etc/init/mysql-boot-control.conf removes=/etc/init/mysql.conf
|
||||
when: instance_status == "ACTIVE"
|
||||
- name: "Ensuring MySQL is running - If this fails, the cluster is likely not in a healthy state, and manual checks/recovery will be required."
|
||||
service: name=mysql state=started
|
||||
when: instance_status == "ACTIVE"
|
||||
- hosts: controller-bootstrap
|
||||
name: Check RabbitMQ Bootstrap Node
|
||||
sudo: yes
|
||||
gather_facts: yes
|
||||
max_fail_percentage: 0
|
||||
tasks:
|
||||
- name: "Execute RabbitMQ status Check to verify RabbitMQ is running."
|
||||
sudo: yes
|
||||
shell: rabbitmqctl -n rabbit@$(hostname) status
|
||||
when: instance_status == "ACTIVE"
|
||||
register: rabbitmq_status
|
||||
ignore_errors: yes
|
||||
- name: "Attempting to start RabbitMQ - Bootstrap Node"
|
||||
service: name=rabbitmq-server state=started
|
||||
when: rabbitmq_status.rc != 0
|
||||
- name: "Checking RabbitMQ Cluster Status - Bootstrap Node"
|
||||
shell: rabbitmqctl -n rabbit@$(hostname) status
|
||||
- hosts: controller
|
||||
name: "Check RabbitMQ server status"
|
||||
sudo: yes
|
||||
gather_facts: yes
|
||||
max_fail_percentage: 0
|
||||
tasks:
|
||||
- name: "Execute RabbitMQ status Check to verify RabbitMQ is running."
|
||||
shell: rabbitmqctl -n rabbit@$(hostname) status
|
||||
when: instance_status == "ACTIVE"
|
||||
register: rabbitmq_status
|
||||
ignore_errors: yes
|
||||
- name: "Attempting to start RabbitMQ"
|
||||
service: name=rabbitmq-server state=started
|
||||
when: rabbitmq_status.rc != 0
|
||||
- name: "Checking RabbitMQ Cluster Status"
|
||||
shell: rabbitmqctl -n rabbit@$(hostname) status
|
||||
- hosts: controller-bootstrap:controller
|
||||
name: Check controller MySQL Sync status
|
||||
gather_facts: no
|
||||
max_fail_percentage: 0
|
||||
tasks:
|
||||
- name: "Querying MySQL to determine Galera cluster status"
|
||||
sudo: yes
|
||||
shell: mysql --defaults-file=/mnt/state/root/metadata.my.cnf --socket /var/run/mysqld/mysqld.sock -N -e "SHOW STATUS LIKE 'wsrep_local_state'"|cut -f2
|
||||
when: helion is not defined
|
||||
register: wsrep_local_state
|
||||
- name: "Querying MySQL to determine Galera cluster size"
|
||||
sudo: yes
|
||||
shell: mysql --defaults-file=/mnt/state/root/metadata.my.cnf --socket /var/run/mysqld/mysqld.sock -N -e "SHOW STATUS LIKE 'wsrep_cluster_size'"|cut -f2
|
||||
when: helion is not defined
|
||||
register: wsrep_cluster_size
|
||||
- fail: msg="Galera wsrep_local_state is not indicating a healthy state, cluster node may be out of sync, manual intervention required."
|
||||
when: helion is not defined and wsrep_local_state.stdout != "4"
|
||||
- fail: msg="Galera cluster size is being reported as a single node. The cluster is in an unsafe, possibly split brain state."
|
||||
when: helion is not defined and wsrep_cluster_size.stdout == "1"
|
||||
# Helion
|
||||
- name: "Querying MySQL to determine Galera cluster status - Helion"
|
||||
sudo: yes
|
||||
shell: mysql --defaults-file=/mnt/state/root/metadata.my.cnf -N -e "SHOW STATUS LIKE 'wsrep_local_state'"|cut -f2
|
||||
when: helion is defined
|
||||
register: wsrep_local_state
|
||||
- name: "Querying MySQL to determine Galera cluster size - Helion"
|
||||
sudo: yes
|
||||
shell: mysql --defaults-file=/mnt/state/root/metadata.my.cnf -N -e "SHOW STATUS LIKE 'wsrep_cluster_size'"|cut -f2
|
||||
when: helion is defined
|
||||
register: wsrep_cluster_size
|
||||
- fail: msg="Galera wsrep_local_state is not indicating a healthy state, cluster node may be out of sync, manual intervention required."
|
||||
when: helion is defined and wsrep_local_state.stdout != "4"
|
||||
- fail: msg="Galera cluster size is being reported as a single node. The cluster is in an unsafe, possibly split brain state."
|
||||
when: helion is defined and wsrep_cluster_size.stdout == "1"
|
@ -1,33 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Removing any pre-existing host key backup directory"
|
||||
sudo: yes
|
||||
file: path=/mnt/state/_ssh_host_keys state=absent
|
||||
- name: "Create ssh host key backup directory"
|
||||
sudo: yes
|
||||
file:
|
||||
path=/mnt/state/_ssh_host_keys
|
||||
state=directory
|
||||
owner=root
|
||||
group=root
|
||||
mode=0700
|
||||
- name: "Preserve ssh host keys"
|
||||
sudo: yes
|
||||
action: shell cp -a /etc/ssh/ssh_host_* /mnt/state/_ssh_host_keys/
|
||||
- name: "Issue Sync to OS in order to help mitigate unsafe disk caching in virtualized environments."
|
||||
command: sync
|
||||
- name: "Pausing for 15 seconds to allow for any delayed IO in unsafe disk caches to be written to disk."
|
||||
pause: seconds=15
|
@ -1,26 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
- name: Determine if node is part of a cluster
|
||||
shell: grep -q "$(hostname)" "/mnt/state/var/lib/rabbitmq/mnesia/rabbit@$(hostname)/cluster_nodes.config"
|
||||
ignore_errors: yes
|
||||
register: rabbit_cluster_test
|
||||
- name: Collect names of post-configure.d rabbitmq files
|
||||
shell: ls "{{os_refresh_config_folder}}/post-configure.d/"|grep '\-rabbitmq$'
|
||||
register: test_rabbitmq_script_list
|
||||
when: rabbit_cluster_test.rc == 0
|
||||
- name: If node rabbitmq cluster config was present, prevent os-refresh-config post-configure.d job from executing.
|
||||
file: mode=0644 path="{{os_refresh_config_folder}}/post-configure.d/{{item}}"
|
||||
when: rabbit_cluster_test.rc == 0
|
||||
with_items: test_rabbitmq_script_list.stdout_lines
|
@ -1,13 +0,0 @@
|
||||
# Additional Steps for controller nodes only to rejoin the cluster
|
||||
- name: Get the bootstrap hostname
|
||||
set_fact:
|
||||
bootstrap_hostname={{ hostvars[groups['controller-bootstrap'][0]]['ansible_hostname'] }}
|
||||
- name: Stop the RabbitMQ application to enable rejoining the cluster
|
||||
command: rabbitmqctl stop_app
|
||||
sudo: yes
|
||||
- name: Re-join the RabbitMQ cluster
|
||||
command: rabbitmqctl join_cluster "rabbit@{{ bootstrap_hostname }}"
|
||||
failed_when: bootstrap_hostname is not defined
|
||||
- name: Start the RabbitMQ application
|
||||
command: rabbitmqctl start_app
|
||||
sudo: yes
|
@ -1,47 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Setting default fact indicating no rebuild has yet taken place"
|
||||
set_fact: instance_rebuilt=false
|
||||
- name: "Call nova_rebuild if instance needs to be updated"
|
||||
nova_rebuild:
|
||||
instance_id: "{{ instance_id }}"
|
||||
image_id: "{{ rebuild_image_id }}"
|
||||
preserve_ephemeral: true
|
||||
wait: "yes"
|
||||
wait_for: 900
|
||||
delegate_to: localhost
|
||||
when: instance_image_id != rebuild_image_id and force_rebuild is not defined
|
||||
register: test_rebuild_normal
|
||||
- name: "Record that instance was rebuilt under normal circumstances"
|
||||
set_fact: instance_rebuilt=true
|
||||
when: test_rebuild_normal.changed == true
|
||||
- name: "Call nova_rebuild if rebuild is mandated"
|
||||
nova_rebuild:
|
||||
instance_id: "{{ instance_id }}"
|
||||
image_id: "{{ rebuild_image_id }}"
|
||||
preserve_ephemeral: true
|
||||
wait: "yes"
|
||||
wait_for: 900
|
||||
delegate_to: localhost
|
||||
when: force_rebuild is defined
|
||||
register: test_rebuild_forced
|
||||
- name: "Record that instance was rebuilt under normal circumstances"
|
||||
set_fact: instance_rebuilt=true
|
||||
when: test_rebuild_forced.changed == true
|
||||
- name: "If we did not rebuild, and the image IDs already match, trigger the ephemeral disk to remount."
|
||||
sudo: yes
|
||||
command: "{{os_refresh_config_folder}}/pre-configure.d/00-fix-ephemeral-mount"
|
||||
when: instance_image_id == rebuild_image_id and force_rebuild is not defined or instance_rebuilt == false
|
@ -1,34 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
# Update the collect files to contain metadata obtained from Heat
|
||||
#
|
||||
- name: "Ensure heat local-data directory exists"
|
||||
sudo: yes
|
||||
file: path=/var/lib/os-collect-config/local-data state=directory
|
||||
- name: "Copy deployments exploder script"
|
||||
sudo: yes
|
||||
copy:
|
||||
src: files/explode-deployments.py
|
||||
dest: /usr/local/bin/explode-deployments
|
||||
mode: 0755
|
||||
- name: "Write out metadata"
|
||||
sudo: yes
|
||||
template:
|
||||
src: templates/host_metadata.json.j2
|
||||
dest: /var/lib/os-collect-config/local-data/host_metadata.json
|
||||
- name: "Explode deployments"
|
||||
sudo: yes
|
||||
command: /usr/local/bin/explode-deployments /var/lib/os-collect-config/local-data
|
@ -1,23 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
- name: Tell the cloud to shutdown via nova_powercontrol.
|
||||
nova_powercontrol:
|
||||
login_username: "{{ lookup('env',OC_OS_USERNAME'}}"
|
||||
login_password: "{{ lookup('env',OC_OS_PASSWORD'}}"
|
||||
login_tenant_name: "{{ lookup('env',OC_OS_TENANT_NAME'}}"
|
||||
auth_url: "{{ lookup('env',OC_OS_AUTH_URL'}}"
|
||||
all_instances: yes
|
||||
state: previous
|
||||
when: use_nova_powercontrol is defined
|
@ -1,24 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Restore ssh host keys"
|
||||
sudo: yes
|
||||
action: shell mv /mnt/state/_ssh_host_keys/ssh_host_* /etc/ssh/
|
||||
|
||||
- name: "Remove ssh host key backup directory"
|
||||
sudo: yes
|
||||
file:
|
||||
path=/mnt/state/_ssh_host_keys
|
||||
state=absent
|
@ -1,28 +0,0 @@
|
||||
Pre-flight disk check
|
||||
=====================
|
||||
|
||||
This role can be used to check for sufficient free disk space on
|
||||
hosts, and will fail if there is not enough space. The amount of space
|
||||
may be specified as a fixed amount (in bytes) using the `fail_size`
|
||||
variable, or as a percentage of the total, using the `fail_percent`
|
||||
variable. Additionally, mounted filesystems can be excluded by mount
|
||||
name, if specified, in `exclude_mounts`.
|
||||
|
||||
To use the role, either include as usual (to use the default values
|
||||
specified in defaults/main.yml::
|
||||
|
||||
- hosts: hostgroup
|
||||
roles:
|
||||
- preflight_disk_check
|
||||
|
||||
Or specify your own values when you add the role, as follows::
|
||||
|
||||
- hosts: hostgroup
|
||||
roles:
|
||||
- { role: preflight_disk_check, fail_percent: 10,
|
||||
exclude_mounts: [ "/mnt" ], when: instance_status == "ACTIVE"
|
||||
}
|
||||
|
||||
This will allow you to easily set different parameters for different
|
||||
types of hosts in your playbook. Note that only one of `fail_percent`
|
||||
or `fail_size` will be used.
|
@ -1,20 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
fail_percent: 10
|
||||
fail_size:
|
||||
exclude_mounts: []
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: Check if free disk percentage is too low
|
||||
fail: msg="ERROR - {{ item.size_available|filesizeformat }} is not enough (need at least {{ fail_percent }}% free)"
|
||||
with_items: "hostvars[inventory_hostname].ansible_mounts"
|
||||
when: item.mount not in exclude_mounts and fail_percent is defined and "{{ ((item.size_available / item.size_total) * 100)|round|int }}"|int < fail_percent
|
||||
- name: Check if free disk size is too low
|
||||
fail: msg="ERROR - {{ item.size_available|filesizeformat }} is not enough (need at least {{ fail_size }} free)"
|
||||
with_items: "hostvars[inventory_hostname].ansible_mounts"
|
||||
when: item.mount not in exclude_mounts and fail_size is defined and "{{ item.size_available }}"|int < fail_size
|
@ -1,36 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- hosts: controller
|
||||
name: Enable Overcloud Controller
|
||||
sudo: yes
|
||||
tasks:
|
||||
- service: name={{ item }} enabled=yes state=started
|
||||
with_items: overcloud_controller_services
|
||||
- hosts: nova-compute
|
||||
name: Enable Overcloud Compute
|
||||
sudo: yes
|
||||
tasks:
|
||||
- name: "Run os-collect-config"
|
||||
sudo: yes
|
||||
command: os-collect-config --force --one
|
||||
- service: name={{ item }} enabled=yes state=started
|
||||
with_items: overcloud_compute_services
|
||||
- hosts: undercloud
|
||||
name: Enable Undercloud
|
||||
sudo: yes
|
||||
tasks:
|
||||
- service: name={{ item }} enabled=yes state=started
|
||||
with_items: undercloud_services
|
@ -1,19 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
- name: Rename MySQL upstart script
|
||||
sudo: yes
|
||||
command: mv -f /etc/init/mysql.conf /etc/init/mysql-boot-control.conf removes=/etc/init/mysql.conf
|
||||
- service: name=mysql state=started enabled=yes
|
||||
sudo: yes
|
@ -1,38 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
- name: Determine if node is part of a cluster
|
||||
shell: grep -q "$(hostname)" "/mnt/state/var/lib/rabbitmq/mnesia/rabbit@$(hostname)/cluster_nodes.config"
|
||||
ignore_errors: yes
|
||||
register: rabbit_cluster_test
|
||||
- name: Collect names of post-configure.d rabbitmq files
|
||||
shell: ls "{{os_refresh_config_folder}}/post-configure.d/"|grep '\-rabbitmq$'
|
||||
register: test_rabbitmq_script_list
|
||||
when: rabbit_cluster_test.rc == 0
|
||||
- name: If node rabbitmq cluster config was present, prevent os-refresh-config post-configure.d job from executing.
|
||||
file: mode=0644 path="{{os_refresh_config_folder}}/post-configure.d/{{item}}"
|
||||
when: rabbit_cluster_test.rc == 0
|
||||
with_items: test_rabbitmq_script_list.stdout_lines
|
||||
sudo: yes
|
||||
- name: "Enable rabbitmq"
|
||||
command: os-svc-enable -n rabbitmq-server
|
||||
sudo: yes
|
||||
- name: "Replace rabbitmq-server override to avoid conditions where RabbitMQ can block upgrade."
|
||||
copy: src=files/rabbitmq-server.override dest=/etc/init/ owner=root group=root mode=0644
|
||||
sudo: yes
|
||||
- name: Start rabbitmq before os-collect-config if previously configured
|
||||
service: name=rabbitmq-server state=started
|
||||
sudo: yes
|
||||
- name: Wait for Rabbit to listen on its usual port
|
||||
wait_for: port=5672 state=started timeout=90 delay=10
|
@ -1,35 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- hosts: undercloud
|
||||
name: Check we have undercloud image ID for rebuild
|
||||
tasks:
|
||||
- fail: msg="undercloud_rebuild_image_id is not defined"
|
||||
when: undercloud_rebuild_image_id is not defined or undercloud_rebuild_image_id == "" or undercloud_rebuild_image_id == None
|
||||
- hosts: controller
|
||||
name: Check we have controller image ID for rebuild
|
||||
tasks:
|
||||
- fail: msg="controller_rebuild_image_id is not defined"
|
||||
when: controller_rebuild_image_id is not defined or controller_rebuild_image_id == "" or controller_rebuild_image_id == None
|
||||
- hosts: swift-storage
|
||||
name: Check we have swift storage image ID for rebuild
|
||||
tasks:
|
||||
- fail: msg="swift_storage_rebuild_image_id is not defined"
|
||||
when: swift_storage_rebuild_image_id is not defined or swift_storage_rebuild_image_id == "" or swift_storage_rebuild_image_id == None
|
||||
- hosts: nova-compute
|
||||
name: Check we have nova compute image ID for rebuild
|
||||
tasks:
|
||||
- fail: msg="nova_compute_rebuild_image_id is not defined"
|
||||
when: nova_compute_rebuild_image_id is not defined or nova_compute_rebuild_image_id == "" or nova_compute_rebuild_image_id == None
|
@ -1,25 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Cleaning up /mnt/state/_upgrade_recovery"
|
||||
sudo: yes
|
||||
file:
|
||||
path: /mnt/state/_upgrade_recovery
|
||||
state: absent
|
||||
- name: "Cleaning up /tmp/upgrade_image.qcow2"
|
||||
sudo: yes
|
||||
file:
|
||||
path: /tmp/upgrade_image.qcow2
|
||||
state: absent
|
@ -1,24 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Remove ssh from cloud-init job."
|
||||
sudo: yes
|
||||
command: sed -i 's/^ - ssh$/# - ssh/' /etc/cloud/cloud.cfg
|
||||
- name: "Remove ssh-authkey-fingerprints from cloud-init job."
|
||||
sudo: yes
|
||||
command: sed -i 's/^ - ssh-authkey-fingerprints$/# - ssh-authkey-fingerprints/' /etc/cloud/cloud.cfg
|
||||
- name: "Initiate cloudinit"
|
||||
sudo: yes
|
||||
command: /usr/bin/cloud-init init
|
@ -1,26 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Pausing for 60 seconds to give MySQL time to become ready - Helion"
|
||||
pause: seconds=60 prompt="Pausing for 60 seconds to give MySQL time to become ready"
|
||||
when: helion is defined
|
||||
- name: "Execute script to wait for MySQL to enter a Synced state"
|
||||
sudo: yes
|
||||
script: files/wait_for_database-helion.sh
|
||||
when: helion is defined
|
||||
- name: Triggering os-create-db on databases
|
||||
sudo: yes
|
||||
script: files/create-databases.sh
|
||||
when: helion is defined
|
@ -1,22 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Collect Open File List"
|
||||
sudo: yes
|
||||
shell: lsof -n|grep /mnt
|
||||
- name: "Collect process list"
|
||||
command: ps auxf
|
||||
- name: "Fail"
|
||||
fail: msg="The ephemeral storage of this system failed to be cleaned up properly and processes or files are still in use. The previous ansible play should have information to help troubleshoot this issue."
|
@ -1,24 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
# This is primarilly due to the fact that we can possibly interrupt existing
|
||||
# start-up sequences before this is done depending on system performance, and
|
||||
# as a result be unable later on to start services such as rabbitmq-server.
|
||||
#
|
||||
# This at some point should be replaced with comperable code in Ansible
|
||||
# to have the same end effect.
|
||||
- name: Trigger hosts file generation
|
||||
sudo: yes
|
||||
command: "{{os_refresh_config_folder}}/configure.d/51-hosts"
|
@ -1,18 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
- name: "Initiate os-apply-config"
|
||||
command: os-collect-config --force --one --command=os-apply-config
|
||||
ignore_errors: yes
|
||||
when: instance_rebuilt == true
|
@ -1,7 +0,0 @@
|
||||
---
|
||||
- name: "Test Connectivity to all hosts"
|
||||
hosts: all
|
||||
serial: 1
|
||||
tasks:
|
||||
ping:
|
||||
where: instance_status == "ACTIVE"
|
@ -1,26 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Execute LOCAL command on this node"
|
||||
hosts: localhost
|
||||
gather_facts: no
|
||||
sudo: yes
|
||||
max_fail_percentage: 0
|
||||
tasks:
|
||||
- name: "Execute Locally defined command"
|
||||
command: "{{ post_hook_command }}"
|
||||
delegate_to: 127.0.0.1
|
||||
when: post_hook_command is defined
|
||||
|
@ -1,26 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Execute LOCAL command on this node"
|
||||
hosts: localhost
|
||||
sudo: yes
|
||||
gather_facts: no
|
||||
max_fail_percentage: 0
|
||||
tasks:
|
||||
- name: "Execute Locally defined command"
|
||||
command: "{{ pre_hook_command }}"
|
||||
delegate_to: 127.0.0.1
|
||||
when: pre_hook_command is defined
|
||||
|
@ -1,21 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Ensure /mnt/state/etc/iscsi/ exists"
|
||||
sudo: yes
|
||||
file: path=/mnt/state/etc/iscsi/ state=directory mode=0755
|
||||
- name: "Backup /etc/iscsi/initiatorname.iscsi to /mnt/state/etc/iscsi/initiatorname.iscsi"
|
||||
sudo: yes
|
||||
command: cp -a /etc/iscsi/initiatorname.iscsi /mnt/state/etc/iscsi/initiatorname.iscsi
|
@ -1,23 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
- name: "Ensure /mnt/state/etc exists"
|
||||
sudo: yes
|
||||
file: path=/mnt/state/etc owner=root group=root mode=0755 state=directory
|
||||
- name: "Saving a copy of /etc/passwd to /mnt/state/etc/passwd.backup"
|
||||
sudo: yes
|
||||
command: cp -a /etc/passwd /mnt/state/etc/passwd.backup
|
||||
- name: "Saving a copy of /etc/group to /mnt/state/etc/passwd.backup"
|
||||
sudo: yes
|
||||
command: cp -a /etc/group /mnt/state/etc/group.backup
|
@ -1,21 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
- name: "Correcting Permissions for /mnt/state/var/log"
|
||||
sudo: yes
|
||||
script: files/correct_mnt_state_permissions.py -f /mnt/state/etc/passwd.backup -g /mnt/state/etc/group.backup -d /mnt/state/var/log
|
||||
- name: "Correcting Permissions for /mnt/state/var/lib"
|
||||
sudo: yes
|
||||
script: files/correct_mnt_state_permissions.py -f /mnt/state/etc/passwd.backup -g /mnt/state/etc/group.backup -d /mnt/state/var/lib
|
||||
- include: step_preserve_password_file.yml
|
@ -1,21 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Restoring the open-iscsi initiator name file"
|
||||
sudo: yes
|
||||
command: cp -a /mnt/state/etc/iscsi/initiatorname.iscsi /etc/iscsi/initiatorname.iscsi
|
||||
- name: "Restarting the open-iscsi service"
|
||||
sudo: yes
|
||||
service: name=open-iscsi state=restarted
|
@ -1,35 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: Remove os-collect-config disable sentinel file
|
||||
file: path=/mnt/state/disable-os-collect-config state=absent
|
||||
sudo: yes
|
||||
- name: "Setting default fact to run os-collect-config"
|
||||
set_fact: test_bypass_os_collect_config="False"
|
||||
- name: "Evaluate if os-collect-config needs to be run"
|
||||
command: grep -q -i "Completed phase migration" "{{os_collect_config_log}}"
|
||||
register: test_did_os_collect_config_complete
|
||||
ignore_errors: yes
|
||||
when: online_upgrade is not defined
|
||||
- name: "Setting fact to bypass os-collect-config if applicable"
|
||||
set_fact: test_bypass_os_collect_config="True"
|
||||
when: online_upgrade is not defined and test_did_os_collect_config_complete.rc == 0
|
||||
- name: "Execute os-collect-config"
|
||||
command: os-collect-config --force --one
|
||||
when: test_bypass_os_collect_config != true
|
||||
register: test_occ_results
|
||||
until: test_occ_results.rc == 0
|
||||
retries: 2
|
||||
delay: 15
|
@ -1,23 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Write image ID to instance disk for online upgrades to check"
|
||||
sudo: yes
|
||||
copy:
|
||||
content: "{{ rebuild_image_id }}"
|
||||
dest: /etc/tripleo_image_id
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
@ -1,24 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# Work around bug in init script that causes status to malfunction on tgt
|
||||
# The service will happily start over and over but stopping is tricky
|
||||
---
|
||||
# After shutdown of neutron services, neutron-ns-metadata-proxy is still present
|
||||
# This services logs to the ephemeral partition, so un-mounting is not possible
|
||||
# No upstart scripts for this service, so needs to be killed.
|
||||
- name: Kill neutron metadata proxy service
|
||||
command: pkill -9 -f neutron-ns-metadata-proxy
|
||||
ignore_errors: yes
|
@ -1,27 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Collect Service Facts"
|
||||
sudo: yes
|
||||
service_facts:
|
||||
when: instance_status == "ACTIVE"
|
||||
- name: "Stop services"
|
||||
sudo: yes
|
||||
service: name={{ item }} enabled=no state=stopped
|
||||
with_items: services_to_stop
|
||||
when: instance_status == "ACTIVE" and item in existing_services
|
||||
- include: stop_tgt.yml
|
||||
when: instance_status == "ACTIVE"
|
||||
sudo: yes
|
@ -1,21 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Purge previous backup folder"
|
||||
sudo: yes
|
||||
file: path=/mnt/state/_upgrade_backup_tftpboot.tar.bz state=absent
|
||||
- name: "Backup /tftpboot"
|
||||
sudo: yes
|
||||
command: tar --exclude='pxelinux.0' -cvjf /mnt/state/_upgrade_backup_tftpboot.tar.bz /tftpboot
|
@ -1,25 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
# These steps are to address Ironic bug
|
||||
# https://bugs.launchpad.net/ironic/+bug/1382698
|
||||
- name: Reset Ironic Reservations
|
||||
sudo: yes
|
||||
command: mysql --defaults-file=/mnt/state/root/metadata.my.cnf --socket /var/run/mysqld/mysqld.sock ironic -e 'update nodes set reservation=NULL where reservation="{{ ansible_fqdn }}";'
|
||||
when: helion is not defined
|
||||
- name: Reset Ironic Reservations - Helion
|
||||
sudo: yes
|
||||
shell: mysql --defaults-file=/mnt/state/root/metadata.my.cnf ironic -e 'update nodes set reservation=NULL where reservation="{{ ansible_fqdn }}";'
|
||||
when: helion is defined
|
@ -1,18 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Restore /tftpboot contents"
|
||||
sudo: yes
|
||||
command: tar -C / -xvjf /mnt/state/_upgrade_backup_tftpboot.tar.bz tftpboot
|
@ -1,23 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Change /mnt to be a read-only mount-point"
|
||||
sudo: yes
|
||||
command: umount /mnt
|
||||
ignore_errors: True
|
||||
register: test_remount
|
||||
when: instance_status == "ACTIVE" and online_upgrade is not defined
|
||||
- include: step_fail_unmount.yml
|
||||
when: instance_status == "ACTIVE" and online_upgrade is not defined and test_remount.rc != 0
|
@ -1,197 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Fail upgrade if node status is not ACTIVE"
|
||||
fail: "Failure: Node MUST be in ACTIVE state to proceed. Online upgrade cannot be completed, please consider a standard image rebuild upgrade."
|
||||
when: instance_status != "ACTIVE"
|
||||
- name: "Setting default fact indicating no rebuild has yet taken place"
|
||||
set_fact: instance_rebuilt=false
|
||||
- name: "Setting default policy to run upgrade"
|
||||
set_fact: test_run_upgrade=true
|
||||
- name: "Compare, if applicable, the currently deployed image id"
|
||||
command: grep -q "{{ rebuild_image_id }}" /etc/tripleo_image_id
|
||||
when: force_rebuild is not defined
|
||||
register: test_check_version
|
||||
ignore_errors: yes
|
||||
- name: "Set action to false if rebuild is not being forced and currently deployed version matches what is being deployed"
|
||||
set_fact: test_run_upgrade=false
|
||||
when: force_rebuild is not defined and test_check_version.rc == 0
|
||||
- name: "Ensure qemu-utils and rsync are installed"
|
||||
sudo: yes
|
||||
# This will require gather_facts to have logic at some point to
|
||||
# support operating systems that do not use apt.
|
||||
apt: pkg={{ item }} state=present
|
||||
with_items:
|
||||
- qemu-utils
|
||||
- rsync
|
||||
when: test_run_upgrade == true
|
||||
- name: "Load nbd kernel module"
|
||||
sudo: yes
|
||||
modprobe:
|
||||
name: nbd
|
||||
state: present
|
||||
params: "max_part=16"
|
||||
when: test_run_upgrade == true
|
||||
- name: "Triggering upload of image to node"
|
||||
sudo: yes
|
||||
include: step_upload_image.yml
|
||||
vars:
|
||||
update_image: "/tmp/image-{{ rebuild_image_id }}.qcow2"
|
||||
when: online_upgrade is defined and test_run_upgrade == true
|
||||
- name: "Creating directory for update to run from on node"
|
||||
sudo: yes
|
||||
file:
|
||||
path: /tmp/update_image
|
||||
state: directory
|
||||
when: test_run_upgrade == true
|
||||
- name: "Ensuring that the mountpoint is not already mounted"
|
||||
sudo: yes
|
||||
command: umount /tmp/update_image
|
||||
ignore_errors: yes
|
||||
when: test_run_upgrade == true
|
||||
- name: "Ensuring that the image is not already attached"
|
||||
sudo: yes
|
||||
command: /usr/bin/qemu-nbd -d /dev/nbd4
|
||||
ignore_errors: yes
|
||||
when: test_run_upgrade == true
|
||||
- name: "Attaching update image"
|
||||
sudo: yes
|
||||
command: /usr/bin/qemu-nbd -c /dev/nbd4 "{{ default_update_file_location }}"
|
||||
when: test_run_upgrade == true
|
||||
- name: "Preserving ssh keys in case online upgrade fails and full rebuild is required to recover"
|
||||
include: preserve_ssh_host_keys.yml
|
||||
when: online_upgrade is defined and test_run_upgrade == true
|
||||
- name: "Ensure that a previous online upgrade folder does not exist"
|
||||
sudo: yes
|
||||
file: path=/mnt/state/_upgrade_recovery state=absent
|
||||
when: test_run_upgrade == true
|
||||
- name: "Make an upgrade recovery folder on the ephemeral disk"
|
||||
sudo: yes
|
||||
file: path=/mnt/state/_upgrade_recovery state=directory owner=root group=root mode=0700
|
||||
when: test_run_upgrade == true
|
||||
- name: "Backup /etc to /mnt/state/_upgrade_recovery"
|
||||
sudo: yes
|
||||
shell: cp -a /etc /mnt/state/_upgrade_recovery/
|
||||
- name: "Backup /var/log to /mnt/state/_upgrade_recovery"
|
||||
sudo: yes
|
||||
shell: mkdir /mnt/state/_upgrade_recovery/var ; cp -a /var/log /mnt/state/_upgrade_recovery/var/
|
||||
- name: "Attaching image to mount point"
|
||||
sudo: yes
|
||||
command: mount /dev/nbd4 /tmp/update_image
|
||||
when: test_run_upgrade == true
|
||||
# The next several steps are intended as a feature to prevent an
|
||||
# image from being utilized in this fashion that is is known to be
|
||||
# incompatible (i.e. incompatible base library changes that would
|
||||
# normally result in a system being left in a damaged state).
|
||||
- name: "Verify that the disk image does not contain a warning flag"
|
||||
shell: test -x /tmp/update_image/boot/tripleo_incompatible_upgrade
|
||||
when: test_run_upgrade == true
|
||||
register: test_abort_incompatible
|
||||
ignore_errors: yes
|
||||
- name: "If aborting, detach update image mountpoint"
|
||||
sudo: yes
|
||||
command: umount /tmp/update_image
|
||||
when: test_run_upgrade == true and test_abort_incompatible.rc == 0
|
||||
- name: "If aborting, detach image"
|
||||
sudo: yes
|
||||
command: /usr/bin/qemu-nbd -d /dev/nbd4
|
||||
when: test_run_upgrade == true and test_abort_incompatible.rc == 0
|
||||
- name: "If aborting, fail."
|
||||
fail: "Image is marked as being incompatible for online upgrades. Please attempt a normal upgrade."
|
||||
when: test_run_upgrade == true and test_abort_incompatible.rc == 0
|
||||
- name: "Ensure folder exists for rsync log to be housed"
|
||||
sudo: yes
|
||||
file: path=/mnt/state/var/log/online_upgrade state=directory owner=root group=root mode=0700
|
||||
when: test_run_upgrade == true
|
||||
- name: "Pre-flight check that we appear to have an image mounted"
|
||||
shell: test -e /tmp/update_image/boot
|
||||
when: test_run_upgrade == true
|
||||
register: test_is_update_image
|
||||
ignore_errors: yes
|
||||
- name: "Fail if image does not appear to be valid"
|
||||
fail: "ERROR: Upgrade image did not mount, or is not valid."
|
||||
when: test_run_upgrade == true and test_is_update_image.rc != 0
|
||||
- name: "Initiating update of files, this may take a while."
|
||||
sudo: yes
|
||||
# The following list of files excluded are to ensure access by Ansible
|
||||
# and continuation of existing processes with minimal impact.
|
||||
# * /tmp - Excluded as this is the source folder
|
||||
# * /etc/hosts - Excluded as it is normally populated with host information
|
||||
# by os-collect-config, and being in a reverted state causes latency while
|
||||
# the host is attempting to resolve the IP address of the node connecting.
|
||||
# * /etc/ssh/ssh_host_* - This is to preserve the ssh host keys so Ansible
|
||||
# is able to reconnect.
|
||||
# * /etc/passwd /etc/shadow /etc/group - These are preserved so Ansible
|
||||
# is able to log back into the system after the system after the sync
|
||||
# has been completed as the heat-admin user is not bured into the image.
|
||||
# * /home/heat-admin - Same case as above.
|
||||
# * /mnt - Excluded as it is the ephemeral volume mount point.
|
||||
# * /var/log - Excluded to preserve logs.
|
||||
# * /lib/modules/$(uname -r) - The current running kernel's modules, which
|
||||
# need to be kept on disk until a kernel upgrade takes place.
|
||||
# * /var/lib/heat-* /var/lib/os-collect-config /var/lib/cloud - These
|
||||
# folders are preserved in order to give the instance a head start on
|
||||
# starting back up. Additionally /var/lib/cloud contains semaphor locks
|
||||
# that block operations that would be unsafe to perform at the time of an
|
||||
# upgrade.
|
||||
# * /dev - Excluded as the image contains a basic /dev folder, but the host
|
||||
# operates with devfs. Removal of files from devfs will result in
|
||||
# unpredictable behavior.
|
||||
# /var/cache/libvirt/qemu/capabilties /var/lib/libvirt - Removal of these
|
||||
# files will cause the current virtual machines to stop as they contain
|
||||
# state information.
|
||||
# * /var/lib/dhcpd/*.leases - Excluded as we want the DHCP client to attempt
|
||||
# a renewal instead of requesting a new address.
|
||||
# * /var/lib/openvswitch - Excluded as it contains the state information for
|
||||
# openvswitch and we want openvswitch to be running as long as possible
|
||||
# for minimal connectivity impact to the running virtual machines.
|
||||
shell: rsync -axHAXv /tmp/update_image/ / --exclude=/tmp --exclude=/etc/hosts --exclude='/etc/ssh/ssh_host_*' --exclude=/etc/passwd --exclude=/etc/shadow --exclude=/etc/group --exclude=/etc/sudoers --exclude=/home/heat-admin --exclude=/mnt --exclude=/var/log --exclude="/lib/modules/$(uname -r)" --exclude='/var/lib/heat-*' --exclude='/dev/' --exclude='/var/cache/libvirt/qemu/capabilities' --exclude='/var/lib/os-collect-config' --exclude='/var/lib/cloud' --exclude='/var/lib/libvirt' --exclude='/var/lib/dhcp/*.leases' --exclude='/var/lib/openvswitch' --delete-after | tee -a /mnt/state/var/log/online_upgrade/rsync.log ; cp -at /etc/ssh/ /mnt/state/_ssh_host_keys/ssh_host_* ; cp -at /etc/ /mnt/state/_upgrade_recovery/etc/hosts /mnt/state/_upgrade_recovery/etc/mtab
|
||||
when: test_run_upgrade == true
|
||||
register: test_rsync_completed
|
||||
- name: "Record that instance was rebuilt under normal circumstances"
|
||||
set_fact: instance_rebuilt=true
|
||||
when: test_rsync_completed.rc == 0
|
||||
- name: "Restart ssh service"
|
||||
sudo: yes
|
||||
service: name=ssh state=restarted
|
||||
# Note: gather_facts will be required to support restarting on
|
||||
# systems that use different names for their ssh services.
|
||||
when: test_run_upgrade == true
|
||||
- name: "Detach update image mountpoint"
|
||||
sudo: yes
|
||||
command: umount /tmp/update_image
|
||||
when: test_run_upgrade == true
|
||||
# bounce any core services like ssh TODO
|
||||
- name: "Remove the post-rsync folder"
|
||||
sudo: yes
|
||||
file:
|
||||
path: /tmp/update_image
|
||||
state: absent
|
||||
when: test_run_upgrade == true
|
||||
- name: "Ensure qemu-utils is installed"
|
||||
sudo: yes
|
||||
# This will require gather_facts to have logic at some point to
|
||||
# support operating systems that do not use apt.
|
||||
apt: pkg={{ item }} state=present
|
||||
with_items:
|
||||
- qemu-utils
|
||||
when: test_run_upgrade == true
|
||||
- name: "Detach upgrade image"
|
||||
sudo: yes
|
||||
command: /usr/bin/qemu-nbd -d /dev/nbd4
|
||||
when: test_run_upgrade == true
|
||||
# NOTE: Should TripleO one day support booting from the local block
|
||||
# device, then this is roughly the locaion where support for updating
|
||||
# the boot loader would be added.
|
@ -1,24 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# NOTE: This playbook MUST be executed one instance at a time as it
|
||||
# is notsafe to allow multiple machines to execute this task at one
|
||||
# time.
|
||||
---
|
||||
- name: "Download Image"
|
||||
glance_download:
|
||||
image_id: "{{ nova_compute_rebuild_image_id }}"
|
||||
path: "/tmp/image-{{ rebuild_image_id }}.qcow2"
|
||||
delegate_to: localhost
|
@ -1,26 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
- include: preserve_ssh_host_keys.yml
|
||||
when: instance_status == "ACTIVE"
|
||||
- include: step_unmount.yml
|
||||
when: instance_status == "ACTIVE"
|
||||
- { include: rebuild.yml, instance_id: "{{ instance_id }}", when: instance_status != "REBUILD" }
|
||||
- local_action: wait_for port=22 timeout="{{ ssh_timeout }}" host="{{ inventory_hostname }}" search_regex=TRIPLEO_HK_RESTORED delay=10
|
||||
when: wait_for_hostkey is defined
|
||||
ignore_errors: yes
|
||||
- local_action: wait_for port=22 timeout="{{ ssh_timeout }}" host="{{ inventory_hostname }}" search_regex=OpenSSH delay=10
|
||||
when: wait_for_hostkey is not defined
|
||||
ignore_errors: yes
|
||||
- include: refresh_config.yml
|
@ -1,22 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- name: "Upload Image to remote host"
|
||||
synchronize:
|
||||
compress: yes
|
||||
checksum: yes
|
||||
archive: yes
|
||||
src: "{{ update_image }}"
|
||||
dest: "{{ default_update_file_location }}"
|
@ -1,30 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
---
|
||||
- hosts: controller
|
||||
name: "Disable OpenStack Controller Services"
|
||||
tasks:
|
||||
- service: name={{ item }} enabled=no state=stopped
|
||||
with_items: control-services
|
||||
- hosts: nova-compute
|
||||
name: "Disable OpenStack Compute"
|
||||
tasks:
|
||||
- service: name={{ item }} enabled=no state=stopped
|
||||
with_items: compute-services
|
||||
- hosts: undercloud
|
||||
name: "Disable OpenStack Undercloud Services"
|
||||
tasks:
|
||||
- service: name={{ item }} enabled=no state=stopped
|
||||
with_items: undercloud-services
|
@ -1,21 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
- name: Stopping mysql and disabling via upstart
|
||||
service: name=mysql state=stopped enabled=no
|
||||
sudo: yes
|
||||
- name: Removing mysql starting via sysv
|
||||
command: update-rc.d mysql remove
|
||||
sudo: yes
|
||||
when: helion is defined
|
@ -1,23 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# Work around bug in init script that causes status to malfunction on tgt
|
||||
# The service will happily start over and over but stopping is tricky
|
||||
- name: Stop TGT
|
||||
sudo: yes
|
||||
service: name=tgt state=stopped enabled=no
|
||||
ignore_errors: yes
|
||||
- name: Wait for TGT to be down
|
||||
wait_for: port=3260 state=stopped timeout=300
|
@ -1,56 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
- service_facts:
|
||||
when: instance_status == "ACTIVE"
|
||||
- name: Ensure libvirt daemon is running
|
||||
sudo: yes
|
||||
service: name={{ item }} state=started enabled=yes
|
||||
when: use_nova_powercontrol is not defined and item in existing_services
|
||||
with_items: hypervisor_daemons
|
||||
- name: Collect list of VMs
|
||||
sudo: yes
|
||||
virt: command=list_vms
|
||||
register: virtual_machines
|
||||
when: use_nova_powercontrol is not defined
|
||||
- name: Issue graceful shutdowns
|
||||
sudo: yes
|
||||
virt: state=shutdown name={{item}}
|
||||
when: use_nova_powercontrol is not defined
|
||||
with_items: virtual_machines.list_vms
|
||||
- name: Tell the cloud to shutdown via nova_powercontrol.
|
||||
nova_powercontrol:
|
||||
login_username: "{{ lookup('env',OC_OS_USERNAME'}}"
|
||||
login_password: "{{ lookup('env',OC_OS_PASSWORD'}}"
|
||||
login_tenant_name: "{{ lookup('env',OC_OS_TENANT_NAME'}}"
|
||||
auth_url: "{{ lookup('env',OC_OS_AUTH_URL'}}"
|
||||
all_instances: yes
|
||||
state: stopped
|
||||
when: use_nova_powercontrol is defined
|
||||
- name: Pausing for 60 seconds to give VMs time to stop.
|
||||
pause: seconds=60
|
||||
- name: Collect list of VMs
|
||||
sudo: yes
|
||||
virt: command=list_vms
|
||||
register: virtual_machines
|
||||
when: use_nova_powercontrol is not defined
|
||||
- name: Issue graceful shutdowns
|
||||
sudo: yes
|
||||
virt: state=shutdown name={{item}}
|
||||
when: use_nova_powercontrol is not defined
|
||||
with_items: virtual_machines.list_vms
|
||||
register: test_from_second_shutdown_call
|
||||
- name: "Fail if virtual machines were still running"
|
||||
fail: msg="If the ansible playbook has failed and exited at this point, virtual machines were still running on the compute node after sixty seconds passed from the shutdown commands having been initiated. Please retry and/or manually ensure that virtual machines on the nodes to be updated have been shut down."
|
||||
when: use_nova_powercontrol is not defined and test_from_second_shutdown_call.changed == true
|
@ -1,12 +0,0 @@
|
||||
{
|
||||
"deployments": [],
|
||||
"os-collect-config": {
|
||||
"cfn": {
|
||||
"stack_name": "{% stack_name %},
|
||||
"metadata_url": "{% metadata_url %},
|
||||
"access_key_id": "{% access_key_id %},
|
||||
"secret_access_key": "{% sercret_access_key %}",
|
||||
"path": "{% path %}"
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user