From 957848702bac595ed8700da8f852f298cee77748 Mon Sep 17 00:00:00 2001 From: Jiri Konecny Date: Thu, 23 Jan 2025 15:05:09 +0100 Subject: [PATCH 1/5] Remove outdated information from tests/README A lot changed from the past when the text was written and this documentation was not updated since. --- docs/images/tests/GH-self-hosted-runners.png | Bin 49815 -> 0 bytes tests/README.rst | 73 +++++-------------- 2 files changed, 17 insertions(+), 56 deletions(-) delete mode 100644 docs/images/tests/GH-self-hosted-runners.png diff --git a/docs/images/tests/GH-self-hosted-runners.png b/docs/images/tests/GH-self-hosted-runners.png deleted file mode 100644 index 8379bd74c5b553230d85e2e71f5eead5ec2bc54f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49815 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

$Wnz*nXXTe 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 R6F!WmEU$5=2x0c@{{i_cCISEe diff --git a/tests/README.rst b/tests/README.rst index 052b3de3e79..7d7407b9108 100644 --- a/tests/README.rst +++ b/tests/README.rst @@ -103,12 +103,9 @@ it locally again. Run rpm tests inside of container --------------------------------- -First, build the container image for running the test, as it does not yet get -published to any registry:: +The rpm tests are taking care that rpm file has all necessary content. - make -f Makefile.am anaconda-rpm-build - -Then run the test in that container:: +To run the test in a container:: make -f Makefile.am container-rpm-test @@ -148,29 +145,20 @@ its triggers and so on. Pull request for main: ________________________ -Unit and rpm tests are run by the `validate.yml workflow`_. We use GitHub's +Unit and rpm tests are using the GitHub `pull_request` trigger. We use GitHub's runners for this so we don't have to care about what is executed there. -The workflow rebuilds the ``anaconda-ci`` container if the container files +The test workflow rebuilds the ``anaconda-ci`` container if the container files have changed, otherwise it is pulling the container from `quay.io`_. For more information see below. Pull request for RHEL: ______________________ -Unit and rpm tests are run by the `validate-rhel-8.yml workflow`_ on (fully -automatically deployed) self-hosted runners in our Upshift instance. - -These runners are ``anaconda-ci:rhel8`` containers with all the dependencies in -place so the yml configuration will just execute tests. You can start runners -locally by running the container and providing GitHub token. That is pretty -valuable in case of workflow testing. See `github-action-run-once`_ for more -details. - -To protect our self-hosted runners, tests only run automatically for -`rhinstaller organization members `_. -For external contributors, an organization member needs to approve the test run -by sending a comment starting with ``/tests``. +Unit and rpm tests are using a similar solution as the upstream ones. Containers +are build on top of ``quay.io/centos/centos:streamXX`` images where ``XX`` is RHEL major release +number. Code for RHEL is shared with CentOS Stream so we decided to run tests on +CentOS Stream containers as these are easier to integrate. Running kickstart-tests: ________________________ @@ -188,7 +176,7 @@ Container maintenance All active branches run tests in containers. Containers have all the dependencies installed and the environment prepared to run tests or connect our -GitHub runners (used by RHEL only). +GitHub runners (for places where we need /dev/kvm access). Automatic container build _________________________ @@ -208,34 +196,6 @@ container you can push your branch to the origin repo and run it from there. Security precautions for testing RHEL ------------------------------------- -Getting into our host/internal network -______________________________________ - -One of the main precautions is that each container test run has -a limited time and is destroyed after timeout/end of test. That should narrow -what attackers could do or how they can create a backdoor. See the image for -more info: - -.. image:: ../docs/images/tests/GH-self-hosted-runners.png - - -Another hardening of this is potential issue is that only PRs -approved by/created by users with permission to write are able to run the tests. -To achieve this we have two ways how to start the test. - -**PR created by rhinstaller member** -- these are started from the RHEL branch -workflow file by ``pull_request_target`` as usual. This workflow has two -dependent jobs. First will check user privileges, second will run the tests in -case the first one succeeded. - -**PR created by external contributors** -- these have to be started by workflow -file `validate-rhel-8.yml workflow`_ from the ``main`` branch -checking all the comments. If comment starts with ``/test`` phrase it will check -the owner of the comment. When everything succeed it will set progress on the pull -request originating the comment and start the tests. This progress is updated -based on the result of the tests. As explained above, the whole implementation -of the workflow is in the ``main`` branch which could be pretty confusing. - Changing workflow file by attacker __________________________________ @@ -272,8 +232,6 @@ represents a different class of tests. They are - *cppcheck/* - static C/C++ code analysis using the *cppcheck* tool; - *shellcheck/* - shell code analyzer config; -- *dd_tests/* - Python unit tests for driver disk utilities (dracut/dd); -- *unit_tests/dracut_tests/* - Python unit tests for the dracut hooks used to configure the installation environment and load Anaconda; - *gettext/* - sanity tests of files used for translation; Written in Python and Bash; @@ -282,11 +240,15 @@ represents a different class of tests. They are a temporary directory without failing dependencies or other RPM issues and checks if all files are correctly present in the RPM; - *lib/* - helper modules used during testing; +- *unit_tests/dd_tests/* - Python unit tests for driver disk utilities (dracut/dd); +- *unit_tests/dracut_tests/* - Python unit tests for the dracut hooks used to configure the - *unit_tests/pyanaconda_tests/* - unit tests for the :mod:`pyanaconda` module; -- *pylint/* - checks the validity of Python source code using the *pocketlint* +- *unit_tests/regex_tests/* - Python unit tests for regular expressions defined in +- *unit_tests/shell_tests/* - Python unit tests for the shell code in Dracut +- *pylint/* - checks the validity of Python source code tool; - *ruff/* - config for fast but not 100% correct linter for Python; -- *unit_tests/regex_tests/* - Python unit tests for regular expressions defined in +- *vulture/* - scripts to execute vulture linter used to find a dead code in the project :mod:`pyanaconda.regexes`; .. NOTE:: @@ -306,10 +268,9 @@ The launcher scripts are listed under `TESTS` in `tests/Makefile.am`. .. _quay.io: https://quay.io/repository/rhinstaller/anaconda-ci .. _pytest -k: https://docs.pytest.org/en/7.1.x/reference/reference.html#command-line-flags .. _GitHub workflows: https://docs.github.com/en/free-pro-team@latest/actions -.. _validate.yml workflow: ../.github/workflows/validate.yml -.. _validate-rhel-8.yml workflow: ../.github/workflows/validate-rhel-8.yml .. _kickstart-tests.yml workflow: ../.github/workflows/kickstart-tests.yml .. _kickstart launch script: https://github.com/rhinstaller/kickstart-tests/blob/master/containers/runner/README.md .. _container-autoupdate.yml workflow: ../.github/workflows/container-autoupdate.yml .. _actions tab: https://github.com/rhinstaller/anaconda/actions?query=workflow%3A%22Refresh+container+images%22 -.. _github-action-run-once: https://github.com/rhinstaller/anaconda/blob/rhel-8/dockerfile/anaconda-ci/github-action-run-once +.. _unittests library: https://docs.python.org/3/library/unittest.html +.. _pytest: https://docs.pytest.org/en/stable/ From 49d9ea3bfbb41ea94e61dd14682c50c9d1180d60 Mon Sep 17 00:00:00 2001 From: Jiri Konecny Date: Thu, 23 Jan 2025 15:31:17 +0100 Subject: [PATCH 2/5] Improve security considerations in tests/README The security advices were not correct. This is attempt to improve the state. --- tests/README.rst | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/tests/README.rst b/tests/README.rst index 7d7407b9108..cd2ecb73eef 100644 --- a/tests/README.rst +++ b/tests/README.rst @@ -142,6 +142,10 @@ All test and maintenance actions are run by `GitHub workflows`_. These YAML files completely describe what steps are required to run some action, what are its triggers and so on. +Because we are using self-hosted runners, ``pull_request_trigger`` and other reasons, +we have our GitHub repositories configured that they need approval for every execution +of the tests (including after force push) for every external contributors. + Pull request for main: ________________________ @@ -196,25 +200,27 @@ container you can push your branch to the origin repo and run it from there. Security precautions for testing RHEL ------------------------------------- -Changing workflow file by attacker -__________________________________ +Beware of the ``pull_request_target`` +_____________________________________ + +For many reasons, we are using ``pull_request_trigger`` in our workflows, however, +this trigger is not secure in some scenarios. See `GitHub documentation`_ for more +information. We need to make sure that this trigger is not executed on an unsafe code. + +The main issue starts with running these on checkout code from PR. In this case, +the attacker has a free hand to change our code, do a release, or use our +self-hosted runners. -Because test description is part of the repository, attackers may change -workflow files by creating PR to do their malicious attack. Because of that we -are using ``pull_request_target`` instead of ``pull_request`` trigger. The main -difference is that ``pull_request_target`` will run your PR tests on the target -branch not on your PR branch. So workflow configuration has to be merged first -to apply workflow changes. This has to be set on all workflow files in all -branches, otherwise attackers could change existing workflow files to use our -runners even for branches where they are not normally used. Unfortunately, -self-hosted runners can’t be bound to the branch, they are bound to the repo. +As the first line of defense, we are not running automatically any workflows on +a pull request from external contributors and each test run have to be manually +approved by developer. How can I change the workflow _____________________________ -Due to our hardening it’s not possible to just create PR and see the result -of your change on the PR checks tab. You have to create PR on your fork branch -which has the updated workflow. I would recommend you to create a test +It depends on a `GitHub trigger`_ used by the workflow. However, if it is not +possible to create a PR and see your changes, you can create PR on your fork +branch which has the updated workflow. I would recommend you to create a test organization for this and avoid creating a new account. Similar situation works even for workflow to automatically update our containers. @@ -274,3 +280,5 @@ The launcher scripts are listed under `TESTS` in `tests/Makefile.am`. .. _actions tab: https://github.com/rhinstaller/anaconda/actions?query=workflow%3A%22Refresh+container+images%22 .. _unittests library: https://docs.python.org/3/library/unittest.html .. _pytest: https://docs.pytest.org/en/stable/ +.. _GitHub documentation: https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request_target +.. _GitHub trigger: https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows From 61f7bf026b0b1303fb7b868302341cff48619318 Mon Sep 17 00:00:00 2001 From: Jiri Konecny Date: Thu, 23 Jan 2025 15:32:19 +0100 Subject: [PATCH 3/5] Make minor improvements in test/README --- tests/README.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/README.rst b/tests/README.rst index cd2ecb73eef..705468ea423 100644 --- a/tests/README.rst +++ b/tests/README.rst @@ -173,7 +173,7 @@ comment that starts with ``/kickstart-tests `` to the pull request to trigger it. It is possible to use tests updated via a kickstart-tests repository PR. See the `kickstart-tests.yml workflow`_ for supported options. For more detailed information on tests selection see the -`kickstart launch script`_ documentation and-its ``--help`` +`kickstart launch script`_ documentation and-its ``--help``. Container maintenance --------------------- @@ -262,6 +262,9 @@ represents a different class of tests. They are All Python unit tests inherit from the standard :class:`unittest.TestCase` class unless specified otherwise! + Also tests are written in the Python `unittests library`_ style but they are executed + by `pytest`_. + Some tests require root privileges and will be skipped if running as regular user! From aae0a0868d78e4e25b18a6f3e969f5fe972555c1 Mon Sep 17 00:00:00 2001 From: Jiri Konecny Date: Thu, 23 Jan 2025 16:21:23 +0100 Subject: [PATCH 4/5] Fix the `Note` section in tests/README It was header section and the podman command was hard to read. This should improve the situation. --- tests/README.rst | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tests/README.rst b/tests/README.rst index 705468ea423..ad710e3e945 100644 --- a/tests/README.rst +++ b/tests/README.rst @@ -93,13 +93,6 @@ In case the *ci* target fails there is also a *coverage-report* target which can be used to combine the multiple `.coverage` files into one and produce a human readable report. -Note ----- - -Please update your container from time to time to have newest dependencies. -To do that, run `podman pull quay.io/rhinstaller/anaconda-ci:main` or build -it locally again. - Run rpm tests inside of container --------------------------------- @@ -134,6 +127,18 @@ Run unit tests with patched pykickstart or other libraries 5. Run other commands for container ci as usual. Don't forget to append ``CI_TAG=`` to make calls if you committed the container under a custom tag. +Keep your containers updated +---------------------------- + +Please update your container from time to time to have newest dependencies. +To do that, run:: + + podman pull quay.io/rhinstaller/anaconda-ci:main + +or build it locally again by:: + + make -f ./Makefile.am anaconda-ci-build + GitHub workflows ---------------- From 43598fcbacd32da31bf8aab6d17f3aa0f75278c6 Mon Sep 17 00:00:00 2001 From: Jiri Konecny Date: Thu, 23 Jan 2025 16:45:02 +0100 Subject: [PATCH 5/5] Improve sections structure in tests/README Let's put all the "how to containers" to one section with sub-sections. --- tests/README.rst | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/tests/README.rst b/tests/README.rst index ad710e3e945..8401ffcab9a 100644 --- a/tests/README.rst +++ b/tests/README.rst @@ -6,8 +6,14 @@ such as unit tests, rpm tests and translation tests. All the tests will be run together if you follow the steps below. For integration tests there is a separate repository kickstart-tests_ containing also tooling for running the tests. +Testing in containers +--------------------- + +Most of our current testing is set inside the containers. This section will describe +how to correctly run and build these containers. + Run unit tests inside of container ----------------------------------- +__________________________________ This is the primary and recommended way to run the tests. Right now only unit tests are supported by the container, not rpm-tests. @@ -45,7 +51,7 @@ modified/touched by the container (it works on an internal copy of the host's anaconda directory). Interactively work inside of container --------------------------------------- +______________________________________ For interactively working in the container you can run:: @@ -94,7 +100,7 @@ which can be used to combine the multiple `.coverage` files into one and produce a human readable report. Run rpm tests inside of container ---------------------------------- +_________________________________ The rpm tests are taking care that rpm file has all necessary content. @@ -103,7 +109,7 @@ To run the test in a container:: make -f Makefile.am container-rpm-test Run unit tests with patched pykickstart or other libraries ----------------------------------------------------------- +__________________________________________________________ 1. Pull the container:: @@ -128,7 +134,7 @@ Run unit tests with patched pykickstart or other libraries make calls if you committed the container under a custom tag. Keep your containers updated ----------------------------- +____________________________ Please update your container from time to time to have newest dependencies. To do that, run::