diff --git a/doc/source/contributing/developer_guide.rst b/doc/source/contributing/developer_guide.rst index 7ec27b606..7e1581490 100644 --- a/doc/source/contributing/developer_guide.rst +++ b/doc/source/contributing/developer_guide.rst @@ -1,22 +1,6 @@ Developer's Guide ================= -And a new entry in the sphinx documentation index:: - - $ [vim|emacs] doc/source/index.rst - ... - Existing validations: - - .. toctree:: - :maxdepth: 2 - - validations-no-op-details - validations-prep-details - validations-pre-introspection-details - validations-pre-deployment-details - validations-post-deployment-details - ... - Writing Validations ------------------- @@ -69,7 +53,9 @@ Sample Validation Each validation is an Ansible playbook located in the ``playbooks`` directory calling his own Ansible role located in the ``roles`` directory. Each playbook -have some metadata. Here is what a minimal validation would look like:: +have some metadata. Here is what a minimal validation would look like: + +.. code-block:: yaml --- - hosts: undercloud @@ -98,7 +84,9 @@ reported by the API. The validations can be grouped together by specifying a ``groups`` metadata. Groups function similar to tags and a validation can thus be part of many groups. Here is, for example, how to have a validation be part of the -`pre-deployment` and `hardware` groups:: +`pre-deployment` and `hardware` groups: + +.. code-block:: yaml metadata: groups: @@ -130,7 +118,9 @@ command. As the playbooks are located in their own directory and not at the same level as the ``roles``, ``callback_plugins``, ``library`` and ``lookup_plugins`` -directories, you will have to export some Ansible variables first:: +directories, you will have to export some Ansible variables first: + +.. code-block:: console $ cd tripleo-validations/ $ export ANSIBLE_CALLBACK_PLUGINS="${PWD}/callback_plugins" @@ -146,7 +136,9 @@ Hosts file When more flexibility than what the current dynamic inventory provides is needed or when running validations against a host that hasn't been deployed via heat (such as the ``prep`` validations), it is possible to write a custom hosts -inventory file. It should look something like this:: +inventory file. It should look something like this: + +.. code-block:: INI [undercloud] undercloud.example.com @@ -192,7 +184,9 @@ In case the `available Ansible modules needs, it is possible to write your own. Modules belong to the ``library`` directory. -Here is a sample module that will always fail:: +Here is a sample module that will always fail + +.. code-block:: python #!/usr/bin/env python @@ -203,7 +197,9 @@ Here is a sample module that will always fail:: module.fail_json(msg="This module always fails.") Save it as ``library/my_module.py`` and use it in a validation like -so:: +so: + +.. code-block:: yaml tasks: ... # some tasks @@ -217,6 +213,11 @@ The name of the module in the validation ``my_module`` must match the file name The custom modules can accept parameters and do more complex reporting. Please refer to the guide on writing modules in the Ansible documentation. +.. Warning:: + + Each custom module must be accompanied by the most complete unit tests + possible. + Learn more at the `Ansible documentation page about writing custom modules `__. @@ -229,7 +230,9 @@ an account it can ssh to and perform passwordless sudo. The nodes need to be present in the static inventory file or available from the dynamic inventory script depending on which one the operator chooses to use. -Check which nodes are available with:: +Check which nodes are available with: + +.. code-block:: console $ source stackrc $ tripleo-ansible-inventory --list @@ -238,7 +241,7 @@ In general, Ansible and the validations will be located on the *undercloud*, because it should have connectivity to all the *overcloud* nodes is already set up to SSH to them. -:: +.. code-block:: console $ source ~/stackrc $ /bin/run-validations.sh --help @@ -257,6 +260,7 @@ up to SSH to them. $ /bin/run-validations.sh --validation-name validation + Example: Verify Undercloud RAM requirements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -264,7 +268,9 @@ The Undercloud has a requirement of 16GB RAM. Let's write a validation that verifies this is indeed the case before deploying anything. Let's create ``playbooks/undercloud-ram.yaml`` and put some metadata -in there:: +in there: + +.. code-block:: yaml --- - hosts: undercloud @@ -277,6 +283,7 @@ in there:: - prep - pre-introspection + The ``hosts`` key will tell which server should the validation run on. The common values are ``undercloud``, ``overcloud`` (i.e. all overcloud nodes), ``controller`` and ``compute`` (i.e. just the controller or the compute nodes). @@ -287,14 +294,18 @@ metadata applies a tag to the validation and allows to group them together in order to perform group operations, such are running them all in one call. Now let's include the Ansible role associated to this validation. Add this under -the same indentation as ``hosts`` and ``vars``:: +the same indentation as ``hosts`` and ``vars``: + +.. code-block:: yaml roles: - undercloud-ram Now let's create the ``undercloud-ram`` Ansible role which will contain the necessary task(s) for checking if the Undercloud has the mininum amount of RAM -required.:: +required: + +.. code-block:: console $ cd tripleo-validations $ ansible-galaxy init --init-path=roles/ undercloud-ram @@ -312,16 +323,19 @@ The tree of the new created role should look like:: └── vars └── main.yml -Now let's add an Ansible task to test that it's all set up properly:: +Now let's add an Ansible task to test that it's all set up properly: - $ cd roles - $ cat <> undercloud-ram/tasks/main.yml +.. code-block:: yaml + + $ cat <> roles/undercloud-ram/tasks/main.yml - name: Test Output debug: msg: "Hello World!" EOF -When running it, it should output something like this:: +When running it, it should output something like this: + +.. code-block:: console $ /bin/run-validations.sh --validation-name undercloud-ram.yaml --ansible-default-callback @@ -342,11 +356,12 @@ When running it, it should output something like this:: If you run into an issue where the validation isn't found, it may be because the run-validations.sh script is searching for it in the path where the packaging installs validations. For development, export an environment variable named -VALIDATIONS_BASEDIR with the value of base path of your git repo.:: +VALIDATIONS_BASEDIR with the value of base path of your git repo: - cd /path/to/git/repo - export VALIDATIONS_BASEDIR=$(pwd) +.. code-block:: console + $ cd /path/to/git/repo + $ export VALIDATIONS_BASEDIR=$(pwd) Writing the full validation code is quite easy in this case because Ansible has done all the hard work for us already. We can use the ``ansible_memtotal_mb`` @@ -354,19 +369,24 @@ fact to get the amount of RAM (in megabytes) the tested server currently has. For other useful values, run ``ansible -i /usr/bin/tripleo-ansible-inventory undercloud -m setup``. -So, let's replace the hello world task with a real one:: +So, let's replace the hello world task with a real one: + +.. code-block:: yaml tasks: - name: Verify the RAM requirements fail: msg="The RAM on the undercloud node is {{ ansible_memtotal_mb }} MB, the minimal recommended value is 16 GB." failed_when: "({{ ansible_memtotal_mb }}) < 16000" -Running this, we see:: +Running this, we see: + +.. code-block:: console TASK: [Verify the RAM requirements] ******************************************* failed: [localhost] => {"failed": true, "failed_when_result": true} msg: The RAM on the undercloud node is 8778 MB, the minimal recommended value is 16 GB. + Because our Undercloud node really does not have enough RAM. Your mileage may vary. @@ -388,7 +408,9 @@ have one place where to change it if we need to and we'll be able to test the validation better as well! So, let's call the variable ``minimum_ram_gb`` and set it to ``16``. Do this in -the ``vars`` section:: +the ``vars`` section: + +.. code-block:: yaml vars: metadata: @@ -399,11 +421,15 @@ the ``vars`` section:: Make sure it's on the same indentation level as ``metadata``. -Then, update ``failed_when`` like this:: +Then, update ``failed_when`` like this: + +.. code-block:: yaml failed_when: "({{ ansible_memtotal_mb }}) < {{ minimum_ram_gb|int * 1024 }}" -And ``fail`` like so:: +And ``fail`` like so: + +.. code-block:: yaml fail: msg="The RAM on the undercloud node is {{ ansible_memtotal_mb }} MB, the minimal recommended value is {{ minimum_ram_gb|int * 1024 }} MB." @@ -416,10 +442,14 @@ Let's do that to test both success and failure cases. This should succeed but saying the RAM requirement is 1 GB:: +.. code-block:: console + ansible-playbook -i /usr/bin/tripleo-ansible-inventory playbooks/undercloud-ram.yaml -e minimum_ram_gb=1 And this should fail by requiring much more RAM than is necessary:: +.. code-block:: console + ansible-playbook -i /usr/bin/tripleo-ansible-inventory playbooks/undercloud-ram.yaml -e minimum_ram_gb=128 (the actual values may be different in your configuration -- just make sure one @@ -451,7 +481,11 @@ It will also add a new **job** entry into the `zuul.d/molecule.yaml`. - job: files: - - ^roles/${NEWROLENAME}/.* + - ^roles/${NEWROLENAME}/.* + - ^tests/prepare-test-host.yml + - ^ci/playbooks/pre.yml + - ^ci/playbooks/run.yml + - ^molecule-requirements.txt name: tripleo-validations-centos-8-molecule-${NEWROLENAME} parent: tripleo-validations-centos-8-base vars: @@ -480,13 +514,168 @@ as an "example" playbook. You will now be able to develop your new validation! +Developing your own molecule test(s) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The role addition process will create a default Molecule scenario from the +skeleton. By using Molecule, you will be able to test it locally and of course +it will be executed during the CI checks. + +In your role directory, you will notice a `molecule` folder which contains a +single `Scenario` called `default`. Scenarios are the starting point for a lot +of powerful functionality that Molecule offers. A scenario is a kind of a test +suite for your newly created role. + +The Scenario layout ++++++++++++++++++++ + +Within the `molecule/default` folder, you will find those files: + +.. code-block:: console + + $ ls + molecule.yml converge.yml prepare.yml verify.yml + +* ``molecule.yml`` is the central configuration entrypoint for `Molecule`. With this + file, you can configure each tool that `Molecule` will employ when testing + your role. + +.. note:: + + `Tripleo-validations` uses a global configuration file for `Molecule`. + This file is located at the repository level (``tripleo-validations/.config/molecule/.config.yml``). + and defines all the default values for all the ``molecule.yml``. By default, + the role addition process will produce an empty ``molecule.yml`` inheriting + this ``config.yml`` file. Any key defined in the role ``molecule.yml`` file + will override values from the ``config.yml`` file. + + But, if you want to override the default values set in the ``config.yml`` + file, you will have to redefine them completely in your ``molecule.yml`` + file. `Molecule` won't merge both configuration files and that's why you + will have to redefine them completely. + +* ``prepare.yml`` is the playbook file that contains everything you need to + include before your test. It could include packages installation, file + creation, whatever your need on the instance created by the driver. + +* ``converge.yml`` is the playbook file that contains the call for you + role. `Molecule` will invoke this playbook with ``ansible-playbook`` and run + it against and instance created by the driver. + +* ``verify.yml`` is the Ansible file used for testing as Ansible is the default + ``Verifier``. This allows you to write specific tests against the state of the + container after your role has finished executing. + +Inspecting the Global Molecule Configuration file ++++++++++++++++++++++++++++++++++++++++++++++++++ + +As mentioned above, ``tripleo-validations`` uses a global configuration for +Molecule. + +.. literalinclude:: ../../../.config/molecule/config.yml + :language: yaml + +* The ``Driver`` provider: ``podman`` is the default. Molecule will use the + driver to delegate the task of creating instances. +* The ``Platforms`` definitions: Molecule relies on this to know which instances + to create, name and to which group each instance + belongs. ``Tripleo-validations`` uses ``Universal Base Images (UBI8)`` which + are container images based on a foundation of Red Hat Enterprise Linux + software. See `Using Red Hat Universal Base Images`_ for details on using Red + Hat UBI container images. +* The ``Provisioner``: Molecule only provides an Ansible provisioner. Ansible + manages the life cycle of the instance based on this configuration. +* The ``Scenario`` definition: Molecule relies on this configuration to control + the scenario sequence order. +* The ``Verifier`` framework. Molecule uses Ansible by default to provide a way + to write specific stat checking tests (such as deployment smoke tests) on the + target instance. + +.. _Using Red Hat Universal Base Images: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html-single/building_running_and_managing_containers/index/#using_red_hat_universal_base_images_standard_minimal_and_runtimes + Local testing of new roles -------------------------- -Local testing of new roles can be done in any number of ways, however, -the easiest way is via the script `run-local-test` on a *CentOS 8* machaine. +Local testing of new roles can be done in two ways: + +* with `tox-ansible `_, +* or via the script `scripts/run-local-test`. + +Running molecule tests with `tox-ansible`_ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +`Tox-ansible `_ is a plugin +for `tox`_ which auto-generates tox environments for running quality assurance +tools like `ansible-test`_ or `molecule`_. + +Tox-ansible will generate as many tox environment(s) as molecule scenarios in +your role. This way you will be able to run locally the desired molecule scenario. + +To list all the defined environments generated by tox-ansible: + +.. code-block:: console + + $ tox -va + default environments: + ceph -> Auto-generated for: cd roles/ceph && molecule test -s default + ceph-ceph-ansible-installed -> Auto-generated for: cd roles/ceph && molecule test -s ceph-ansible-installed + check_for_dangling_images -> Auto-generated for: cd roles/check_for_dangling_images && molecule test -s default + check_kernel_version -> Auto-generated for: cd roles/check_kernel_version && molecule test -s default + check_network_gateway -> Auto-generated for: cd roles/check_network_gateway && molecule test -s default + check_rhsm_version -> Auto-generated for: cd roles/check_rhsm_version && molecule test -s default + check_rhsm_version-rhsm_mismatch -> Auto-generated for: cd roles/check_rhsm_version && molecule test -s rhsm_mismatch + check_uc_hostname -> Auto-generated for: cd roles/check_uc_hostname && molecule test -s default + check_undercloud_conf -> Auto-generated for: cd roles/check_undercloud_conf && molecule test -s default + check_undercloud_conf-config_OK -> Auto-generated for: cd roles/check_undercloud_conf && molecule test -s config_OK + check_undercloud_conf-deprecated_drivers -> Auto-generated for: cd roles/check_undercloud_conf && molecule test -s deprecated_drivers + check_undercloud_conf-deprecated_params -> Auto-generated for: cd roles/check_undercloud_conf && molecule test -s deprecated_params + check_undercloud_conf-required_missing -> Auto-generated for: cd roles/check_undercloud_conf && molecule test -s required_missing + collect_flavors_and_verify_profiles -> Auto-generated for: cd roles/collect_flavors_and_verify_profiles && molecule test -s default + container_status -> Auto-generated for: cd roles/container_status && molecule test -s default + controller_token -> Auto-generated for: cd roles/controller_token && molecule test -s default + controller_ulimits -> Auto-generated for: cd roles/controller_ulimits && molecule test -s default + ... + + additional environments: + bindep -> [no description] + debug -> [no description] + pep8 -> [no description] + ansible-lint -> [no description] + yamllint -> [no description] + bashate -> [no description] + whitespace -> [no description] + shebangs -> [no description] + releasenotes -> [no description] + cover -> [no description] + +To execute one molecule scenario with tox, run the following command: + +.. code-block:: console + + $ tox -e check_undercloud_conf + +If you want to run several molecule scenarios at once, you will have to +explicitly list all of them and separating them with commas: + +.. code-block:: console + + $ tox -e check_undercloud_conf,check_undercloud_conf-config_OK,check_undercloud_conf-deprecated_drivers + +.. warning:: + + Running multiple molecule scenarios at once could be time-consuming due to + the fact that each Molecule execution will create a new container instance + and will destroy it at the end of each scenario. + +.. _tox: https://tox.readthedocs.io/en/latest/index.html +.. _ansible-test: https://docs.ansible.com/ansible/latest/dev_guide/developing_collections_testing.html#testing-collections +.. _molecule: https://github.com/ansible-community/molecule + +Running molecule tests with the script run-local-test +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + This script will setup the local work environment to execute tests mimicking -what Zuul does. +what Zuul does on a *CentOS 8* machine. .. warning:: diff --git a/doc/source/groups.rst b/doc/source/groups.rst index 10988648e..7bf09e40e 100644 --- a/doc/source/groups.rst +++ b/doc/source/groups.rst @@ -8,9 +8,10 @@ Adding a new group ------------------ To add a new group, you will need to edit the ``groups.yaml`` file located in -the root of the TripleO Validations directory:: +the root of the TripleO Validations directory: + +.. code-block:: yaml - $ [vim|emacs] groups.yaml ... pre-update: - description: >- @@ -18,11 +19,12 @@ the root of the TripleO Validations directory:: update it. ... -And a new entry in the sphinx documentation index:: +And a new entry in the sphinx documentation index ``doc/source/index.rst``: - $ [vim|emacs] doc/source/index.rst - ... - Existing validations: +.. code-block:: RST + + Existing validations + ==================== .. toctree:: :maxdepth: 2 diff --git a/doc/source/roles/role-check_for_dangling_images.rst b/doc/source/roles/role-check_for_dangling_images.rst index ca8a3256d..54c65aca1 100644 --- a/doc/source/roles/role-check_for_dangling_images.rst +++ b/doc/source/roles/role-check_for_dangling_images.rst @@ -1,8 +1,8 @@ -================================ -Role - check_for_dangling_images -================================ +========================= +check_for_dangling_images +========================= -.. include:: ../../../roles/check_for_dangling_images/README.md +.. literalinclude:: ../../../roles/check_for_dangling_images/README.md .. ansibleautoplugin:: :role: roles/check_for_dangling_images diff --git a/doc/source/roles/role-check_kernel_version.rst b/doc/source/roles/role-check_kernel_version.rst index b95743a75..b3c77a513 100644 --- a/doc/source/roles/role-check_kernel_version.rst +++ b/doc/source/roles/role-check_kernel_version.rst @@ -1,6 +1,6 @@ -=========================== -Role - check_kernel_version -=========================== +==================== +check_kernel_version +==================== .. ansibleautoplugin:: :role: roles/check_kernel_version diff --git a/doc/source/roles/role-check_rhsm_version.rst b/doc/source/roles/role-check_rhsm_version.rst index b5ef8cbd9..9b77b1324 100644 --- a/doc/source/roles/role-check_rhsm_version.rst +++ b/doc/source/roles/role-check_rhsm_version.rst @@ -1,6 +1,6 @@ -========================= -Role - check_rhsm_version -========================= +================== +check_rhsm_version +================== .. ansibleautoplugin:: :role: roles/check_rhsm_version diff --git a/doc/source/roles/role-check_uc_hostname.rst b/doc/source/roles/role-check_uc_hostname.rst index 65c026e59..bb80924b8 100644 --- a/doc/source/roles/role-check_uc_hostname.rst +++ b/doc/source/roles/role-check_uc_hostname.rst @@ -1,8 +1,8 @@ -======================== -Role - check_uc_hostname -======================== +================= +check_uc_hostname +================= -.. include:: ../../../roles/check_uc_hostname/README.md +.. literalinclude:: ../../../roles/check_uc_hostname/README.md .. ansibleautoplugin:: :role: roles/check_uc_hostname diff --git a/doc/source/roles/role-check_undercloud_conf.rst b/doc/source/roles/role-check_undercloud_conf.rst index c5018a4aa..3c341e96b 100644 --- a/doc/source/roles/role-check_undercloud_conf.rst +++ b/doc/source/roles/role-check_undercloud_conf.rst @@ -1,6 +1,6 @@ -============================ -Role - check_undercloud_conf -============================ +===================== +check_undercloud_conf +===================== .. ansibleautoplugin:: :role: roles/check_undercloud_conf diff --git a/doc/source/roles/role-package_version.rst b/doc/source/roles/role-package_version.rst index f436305f3..f6bc6ac7d 100644 --- a/doc/source/roles/role-package_version.rst +++ b/doc/source/roles/role-package_version.rst @@ -1,6 +1,6 @@ -====================== -Role - package_version -====================== +=============== +package_version +=============== .. ansibleautoplugin:: :role: roles/package_version diff --git a/doc/source/roles/role-system_encoding.rst b/doc/source/roles/role-system_encoding.rst index abf53cee5..704c737ba 100644 --- a/doc/source/roles/role-system_encoding.rst +++ b/doc/source/roles/role-system_encoding.rst @@ -1,6 +1,6 @@ -====================== -Role - system_encoding -====================== +=============== +system_encoding +=============== .. ansibleautoplugin:: :role: roles/system_encoding