diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b4726a915a..79dcf5109a8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -92,256 +92,3 @@ jobs: name: ${{ matrix.tag }}-intgcheck-valgrind path: | ./sssd/ci-build-debug/*.valgrind.log - - system: - if: github.event_name == 'push' || !contains(github.event.pull_request.labels.*.name, 'Accepted') - needs: [prepare] - strategy: - fail-fast: false - matrix: - tag: ${{ fromJson(needs.prepare.outputs.matrix).multihost }} - runs-on: ubuntu-26.04 - permissions: - contents: read - steps: - - uses: actions/setup-python@v7 - with: - python-version: '3.x' - - - name: Checkout sssd repository - uses: actions/checkout@v7 - with: - path: sssd - - - name: Install and load kernel module for passkey testing - shell: bash - run: | - set -ex -o pipefail - - sudo apt-get update - sudo apt-get install -y linux-modules-$(uname -r) - - sudo modprobe vhci-hcd - - - name: Setup containers - uses: SSSD/sssd-ci-containers/actions/setup@master - with: - path: sssd-ci-containers - tag: ${{ matrix.tag }} - override: | - services: - client: - image: ${REGISTRY}/ci-client-devel:${TAG} - shm_size: 4G - tmpfs: - - /dev/shm - volumes: - - ../sssd:/sssd:rw - ipa: - image: ${REGISTRY}/ci-ipa-devel:${TAG} - shm_size: 4G - tmpfs: - - /dev/shm - volumes: - - ../sssd:/sssd:rw - - - name: Build SSSD on the client and IPA - uses: SSSD/sssd-ci-containers/actions/exec@master - with: - log-file: build.log - working-directory: /sssd - where: | - client - ipa - script: | - #!/bin/bash - set -ex - - ./contrib/ci/run --deps-only - autoreconf -if - - mkdir -p /dev/shm/sssd - pushd /dev/shm/sssd - /sssd/configure --enable-silent-rules - make rpms - - - name: Install SSSD on the client and IPA - uses: SSSD/sssd-ci-containers/actions/exec@master - with: - log-file: install.log - user: root - where: | - client - ipa - script: | - #!/bin/bash - set -ex - - # Avoid error 'Lower version of database is expected!' for locally built installed rpms - systemctl stop sssd - rm -f /var/lib/sss/db/* - - dnf install -y /dev/shm/sssd/rpmbuild/RPMS/*/*.rpm - rm -fr /dev/shm/sssd - - # We need to reenable sssd-kcm since it was disabled by removing sssd not not enabled again - systemctl enable --now sssd-kcm.socket - - - name: Restart SSSD on IPA server - uses: SSSD/sssd-ci-containers/actions/exec@master - with: - user: root - where: ipa - script: | - #!/bin/bash - set -ex - - systemctl restart sssd || systemctl status sssd - - - name: Patch the SSH configuration - uses: SSSD/sssd-ci-containers/actions/exec@master - with: - user: root - script: | - #!/bin/bash - test -x /usr/bin/sss_ssh_knownhosts && \ - sed -e 's/GlobalKnownHostsFile/#GlobalKnownHostsFile/' \ - -e 's/ProxyCommand \/usr\/bin\/sss_ssh_knownhostsproxy -p %p %h/KnownHostsCommand \/usr\/bin\/sss_ssh_knownhosts %H/' \ - -i /etc/ssh/ssh_config.d/04-ipa.conf - - - name: Install system tests dependencies - shell: bash - working-directory: ./sssd/src/tests/system - run: | - set -ex - - sudo apt-get update - - # Install dependencies for python-ldap - sudo apt-get install -y libsasl2-dev python3-dev libldap2-dev libssl-dev libssh-dev - - # Virtualenv - pip3 install virtualenv - python3 -m venv .venv - source .venv/bin/activate - - # Install system tests requirements - pip3 install -r ./requirements.txt - - # Install yq to parse yaml files - sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 - sudo chmod a+x /usr/local/bin/yq - - - name: Remove ad from mhc.yaml - shell: bash - working-directory: ./sssd/src/tests/system - run: | - yq -i 'del(.domains[0].hosts.[] | select(.role == "ad"))' mhc.yaml - - - name: Get changed tests - shell: bash {0} - env: - PR_ID: ${{ github.event.pull_request.number }} - GH_TOKEN: ${{ github.token }} - working-directory: sssd - id: select-tests - run: | - set -e - - # Check if non-test files were changed or not run inside PR - FILES=`gh pr diff "$PR_ID" --name-only 2>&1 || exit 0` - - if echo "$FILES" | grep 'no pull requests found'; then - echo "Script not running against PR event. Will run all tests." - echo "SELECT_TESTS=" >> "$GITHUB_OUTPUT" - exit 0 - elif echo "$FILES" | grep -v 'src/tests/system/tests'; then - echo "Non-test files were changed. Will run all tests." - echo "SELECT_TESTS=" >> "$GITHUB_OUTPUT" - exit 0 - fi - - DIFF=`gh pr diff "$PR_ID"` - - # Find if any non-test function was modified, in that case we need to - # run all tests as we do not know where the function is used - if echo "$DIFF" | grep -P '^(@@.+|\+|-)\s*def (?!test_)'; then - echo "Non-test function was modified. Will run all tests." - echo "SELECT_TESTS=" >> "$GITHUB_OUTPUT" - exit 0 - fi - - # Find all tests that were added - ADDED=`echo "$DIFF" | grep -P "^\+\s*def test_" | sed -E 's/.+def (test_[^(]+).+/\1/'` - - # Find all tests that are used as tokens in diff - MODIFIED=`echo "$DIFF" | grep -E "^@@.+def test_" | sed -E 's/.+def (test_[^(]+).+/\1/'` - - # Combine and sort - TESTS=`echo -e "$ADDED\n$MODIFIED" | sort | uniq` - - echo "Following tests were added or modified (or token is present in diff):" - echo "$TESTS" - - ARGS="" - if [ ! -z "$TESTS" ]; then - FILTER=`echo "$TESTS" | xargs | sed 's/ / or /g'` - ARGS="-k \"$FILTER\"" - fi - - echo "SELECT_TESTS=$ARGS" >> "$GITHUB_OUTPUT" - - echo "Set SELECT_TESTS as GitHub Output:" - grep SELECT_TESTS "$GITHUB_OUTPUT" - - - name: Check polarion metadata - shell: bash - working-directory: ./sssd/src/tests/system - run: | - # Run pytest in collect only mode to quickly catch issues in Polarion metadata. - set -ex -o pipefail - - mkdir -p $GITHUB_WORKSPACE/artifacts - source .venv/bin/activate - pytest \ - --color=yes \ - --mh-config=./mhc.yaml \ - --mh-artifacts-dir=$GITHUB_WORKSPACE/artifacts \ - --polarion-config=../polarion.yaml \ - --output-polarion-testcase=$GITHUB_WORKSPACE/artifacts/testcase.xml \ - ${{ steps.select-tests.outputs.SELECT_TESTS }} \ - --collect-only . |& tee $GITHUB_WORKSPACE/pytest-collect.log - - - name: Run tests - shell: bash - working-directory: ./sssd/src/tests/system - run: | - set -ex -o pipefail - - mkdir -p $GITHUB_WORKSPACE/artifacts - source .venv/bin/activate - pytest \ - --durations=0 \ - --color=yes \ - --show-capture=no \ - --mh-config=./mhc.yaml \ - --mh-artifacts-dir=$GITHUB_WORKSPACE/artifacts \ - --polarion-config=../polarion.yaml \ - --output-polarion-testcase=$GITHUB_WORKSPACE/artifacts/testcase.xml \ - --output-polarion-testrun=$GITHUB_WORKSPACE/artifacts/testrun.xml \ - ${{ steps.select-tests.outputs.SELECT_TESTS }} \ - -vvv . |& tee $GITHUB_WORKSPACE/pytest.log - - - name: Upload artifacts - if: always() - uses: actions/upload-artifact@v7 - with: - if-no-files-found: ignore - name: ${{ matrix.tag }}-system - path: | - sssd/ci-install-deps.log - artifacts - build.log - install.log - pytest.log - pytest-collect.log diff --git a/.packit.yaml b/.packit.yaml index 09788d3f164..4ef8dc0981e 100644 --- a/.packit.yaml +++ b/.packit.yaml @@ -32,27 +32,39 @@ jobs: trigger: commit packages: - upstream - targets: + targets: &copr_targets - fedora-all - centos-stream-10 + sync_test_job_statuses_with_builds: False # Produce COPR build on each pull request - job: copr_build trigger: pull_request packages: - upstream - targets: - - fedora-all - - centos-stream-10 + targets: *copr_targets + sync_test_job_statuses_with_builds: False + + # Run TMT tests after COPR builds complete, always on a Fedora-latest + # Testing Farm guest regardless of which target the build was for. + - job: tests + trigger: commit + packages: + - upstream + targets: *copr_targets + skip_install: True + tf_extra_params: &tests_tf_extra_params + environments: + - os: + compose: Fedora-latest - # Run TMT tests after COPR builds complete - job: tests trigger: pull_request packages: - upstream - targets: - - fedora-all - - centos-stream-10 + skip_install: True + targets: *copr_targets + tf_extra_params: *tests_tf_extra_params # Create Fedora pull request on release - job: propose_downstream diff --git a/plans/passkey.fmf b/plans/passkey.fmf deleted file mode 100644 index 44d96bc4cd2..00000000000 --- a/plans/passkey.fmf +++ /dev/null @@ -1,244 +0,0 @@ -summary: SSSD passkey tests -description: | - Test passkey functionality with SSSD across different identity providers - (IPA, LDAP, Samba). -tag: passkey - -provision: - how: virtual - hardware: - memory: ">= 16 GB" - -prepare: - - name: Enable EPEL repository for CentOS Stream - how: shell - script: | - if grep -q "CentOS Stream" /etc/os-release 2>/dev/null; then - dnf install -y epel-release - fi - - - name: Install general dependencies - how: install - package: - - expect - - gcc - - git - - libssh-devel - - openldap-devel - - podman - - podman-compose - - podman-docker - - python3-devel - - python3-pip - - yq - - - name: Setup docker-compose compatibility - how: shell - script: | - if ! command -v docker-compose >/dev/null 2>&1; then - ln -sf $(command -v podman-compose) /usr/local/bin/docker-compose - fi - - - name: Install and load kernel module for passkey testing on Fedora - how: shell - script: | - if grep -q "^ID=fedora" /etc/os-release 2>/dev/null; then - dnf install -y kernel-modules-extra-$(uname -r) - modprobe vhci_hcd - fi - - - name: Clone sssd - how: shell - script: | - if [ -n "$PACKIT_SOURCE_BRANCH" ] && [ -n "$PACKIT_SOURCE_URL" ]; then - echo "Direct PR branch clone: url $PACKIT_SOURCE_URL branch $PACKIT_SOURCE_BRANCH" - git clone --branch "$PACKIT_SOURCE_BRANCH" "$PACKIT_SOURCE_URL" /tmp/sssd - elif [ -n "$PACKIT_PR_ID" ]; then - echo "PR ID fetch: PR ID $PACKIT_PR_ID" - git clone https://github.com/SSSD/sssd.git /tmp/sssd - cd /tmp/sssd - git fetch origin "pull/$PACKIT_PR_ID/head:pr-$PACKIT_PR_ID" - git checkout "pr-$PACKIT_PR_ID" - else - echo "No PR context found, master branch fallback" - git clone https://github.com/SSSD/sssd.git /tmp/sssd - fi - - cd /tmp/sssd - echo "Current branch: $(git branch --show-current)" - echo "Current commit: $(git rev-parse HEAD)" - - - name: Clone sssd-ci-containers - how: shell - script: - - git clone https://github.com/SSSD/sssd-ci-containers.git /tmp/sssd-ci-containers - - - name: Install test dependencies - how: shell - script: - - pip3 install --break-system-packages -r /tmp/sssd/src/tests/system/requirements.txt - - - name: Setup containers - how: shell - script: | - cd /tmp/sssd-ci-containers - systemctl enable --now podman.socket - setsebool container_manage_cgroup true - cp env.example .env - - # Detect system distribution and set appropriate container tag - . /tmp/sssd/contrib/ci/distro.sh - if [ "$DISTRO_ID" = "centos" ]; then - CONTAINER_TAG="centos-$DISTRO_RELEASE" - else - CONTAINER_TAG="fedora-$DISTRO_RELEASE" - fi - echo "Using container tag: $CONTAINER_TAG" - sed -i "s/TAG=latest/TAG=$CONTAINER_TAG/g" .env - - make setup-dns-files - make up - - - name: Fix SSH key permissions - how: shell - script: - - chmod 600 /tmp/sssd-ci-containers/data/ssh-keys/root.id_rsa - - - name: Wait for client and IPA containers to be ready - how: shell - script: | - # Wait for client container - for i in $(seq 1 60); do - if ssh -i /tmp/sssd-ci-containers/data/ssh-keys/root.id_rsa \ - -o StrictHostKeyChecking=no \ - -o ConnectTimeout=5 \ - root@client.test "echo 'ready'" >/dev/null 2>&1; then - echo "Client container ready" - break - fi - if [ $i -eq 60 ]; then - echo "ERROR: Client container not ready after 60 attempts" - exit 1 - fi - sleep 1 - done - - # Wait for IPA container - for i in $(seq 1 60); do - if ssh -i /tmp/sssd-ci-containers/data/ssh-keys/root.id_rsa \ - -o StrictHostKeyChecking=no \ - -o ConnectTimeout=5 \ - root@master.ipa.test "echo 'ready'" >/dev/null 2>&1; then - echo "IPA container ready" - break - fi - if [ $i -eq 60 ]; then - echo "ERROR: IPA container not ready after 60 attempts" - exit 1 - fi - sleep 1 - done - - - name: Install SSSD from PR build into containers - how: shell - script: | - # Get COPR repo name from environment - if [ -n "$PACKIT_COPR_PROJECT" ]; then - COPR_REPO="$PACKIT_COPR_PROJECT" - else - echo "WARNING: No PACKIT_COPR_PROJECT found, using latest master build" - COPR_REPO="packit/SSSD-sssd-master" - fi - - echo "Using COPR repo: $COPR_REPO" - - # Detect system distribution and set appropriate COPR command - . /tmp/sssd/contrib/ci/distro.sh - if [ "$DISTRO_ID" = "centos" ] && [ "$DISTRO_RELEASE" = "10" ]; then - COPR_ENABLE_CMD="dnf copr enable -y $COPR_REPO centos-stream-10-x86_64" - else - COPR_ENABLE_CMD="dnf copr enable -y $COPR_REPO" - fi - - # Install on client container - ssh -i /tmp/sssd-ci-containers/data/ssh-keys/root.id_rsa \ - -o StrictHostKeyChecking=no \ - root@client.test " - $COPR_ENABLE_CMD && \ - dnf upgrade -y --refresh sssd* - " - - # Install on IPA container - ssh -i /tmp/sssd-ci-containers/data/ssh-keys/root.id_rsa \ - -o StrictHostKeyChecking=no \ - root@master.ipa.test " - $COPR_ENABLE_CMD && \ - dnf upgrade -y --refresh sssd* - " - - - name: Restart SSSD services in containers - how: shell - script: | - # Restart SSSD on client container - ssh -i /tmp/sssd-ci-containers/data/ssh-keys/root.id_rsa \ - -o StrictHostKeyChecking=no \ - root@client.test "systemctl restart sssd" - - # Restart SSSD on IPA container - ssh -i /tmp/sssd-ci-containers/data/ssh-keys/root.id_rsa \ - -o StrictHostKeyChecking=no \ - root@master.ipa.test "systemctl restart sssd" - - - name: Remove ad from mhc.yaml - how: shell - script: | - cd /tmp/sssd/src/tests/system - yq -i 'del(.domains[0].hosts[] | select(.role == "ad"))' mhc.yaml - - - name: Wait for samba domain connectivity - how: shell - script: | - echo "Wait for samba domain connectivity..." - - for i in $(seq 1 90); do - # Check if we can resolve users from samba.test domain - if ssh -i /tmp/sssd-ci-containers/data/ssh-keys/root.id_rsa \ - -o StrictHostKeyChecking=no \ - -o ConnectTimeout=5 \ - root@client.test " - timeout 10s getent passwd Administrator@samba.test >/dev/null 2>&1 - " 2>/dev/null; then - echo "Domain connectivity ready (${i}s)" - break - else - if [ $i -eq 90 ]; then - echo "User resolution not ready after 90 attempts, proceeding with tests anyway" - fi - sleep 1 - fi - done - -execute: - how: tmt - duration: 45m - script: | - mkdir -p /tmp/artifacts - cd /tmp/sssd/src/tests/system - pytest --durations=0 \ - --color=yes \ - --show-capture=no \ - --mh-config=mhc.yaml \ - --mh-artifacts-dir=/tmp/artifacts \ - -vvv tests/test_passkey.py - -finish: - - name: Copy artifacts - how: shell - script: | - if [ -d "/tmp/artifacts" ] && [ "$(ls -A /tmp/artifacts 2>/dev/null)" ]; then - mkdir -p $TMT_PLAN_DATA/artifacts - cp -r /tmp/artifacts/* $TMT_PLAN_DATA/artifacts/ - echo "Artifacts copied to: $TMT_PLAN_DATA/artifacts" - else - echo "No artifacts to copy" - fi diff --git a/tmt/plans/system-tests.fmf b/tmt/plans/system-tests.fmf new file mode 100644 index 00000000000..b747a3bfb2d --- /dev/null +++ b/tmt/plans/system-tests.fmf @@ -0,0 +1,130 @@ +summary: SSSD System Tests +description: Run SSSD system tests on sssd-ci-containers. +tag: system + +provision: + how: virtual + hardware: + memory: ">= 16 GB" + +prepare: + - name: Install and load kernel module for passkey testing + how: shell + script: | + set -ex -o pipefail + + dnf install -y kernel-modules-extra-$(uname -r) + modprobe vhci_hcd + + - name: Install system tests dependencies + how: shell + script: | + set -ex -o pipefail + + # Build dependencies for python-ldap and the test framework. + dnf install -y \ + ansifilter \ + cyrus-sasl-devel \ + gcc \ + git \ + libssh-devel \ + openldap-devel \ + openssl-devel \ + python3-devel \ + python3-pip \ + yq + + # Install the python test dependencies into a virtual environment. + # It must live outside $TMT_TREE to avoid clean up between steps. + python3 -m venv /tmp/venv + source /tmp/venv/bin/activate + pip3 install -r "$TMT_TREE/src/tests/system/requirements.txt" + + - name: Setup containers and install ci-* commands + how: shell + url: https://github.com/pbrezina/sssd-ci-containers.git + ref: tmt + script: $TMT_PREPARE_SHELL_URL_REPOSITORY/tmt/setup.sh + + - name: Install SSSD from the COPR build + how: shell + script: ci-install-copr --where "client ipa" + + - name: Restart SSSD on the IPA server + how: shell + script: ci-exec --where ipa --user root -- systemctl restart sssd + + - name: Select tests from the pull request diff and store it in SELECT_TESTS + how: shell + script: ci-select-tests --repo SSSD/sssd + + # - name: Patch the SSH configuration on the client + # how: shell + # script: | + # ci-exec --where client --user root <<'EOF' + # #!/bin/bash + # test -x /usr/bin/sss_ssh_knownhosts && \ + # sed -e 's/GlobalKnownHostsFile/#GlobalKnownHostsFile/' \ + # -e 's|ProxyCommand /usr/bin/sss_ssh_knownhostsproxy -p %p %h|KnownHostsCommand /usr/bin/sss_ssh_knownhosts %H|' \ + # -i /etc/ssh/ssh_config.d/04-ipa.conf + # EOF + + # - name: Wait for samba domain connectivity + # how: shell + # script: | + # set -e -o pipefail + # echo "Wait for samba domain connectivity..." + # for i in $(seq 1 90); do + # if ci-exec --where client --user root -- \ + # timeout 10s getent passwd Administrator@samba.test >/dev/null 2>&1; then + # echo "Domain connectivity ready (${i}s)" + # break + # fi + # if [ "$i" -eq 90 ]; then + # echo "User resolution not ready after 90 attempts, proceeding with tests anyway" + # fi + # sleep 1 + # done + +discover: + how: shell + tests: + - name: /system + summary: Run the SSSD system test suite + order: 20 + duration: 6h + test: | + set -e -o pipefail + + cd "$TMT_TREE/src/tests/system" + source /tmp/venv/bin/activate + + # Print the selected tests + echo "Filtering tests:" + if [ -n "${SELECT_TESTS:-}" ]; then + echo "$SELECT_TESTS" | sed 's/ or /\n/g' | sort | sed 's/^/ - /' + else + echo " - " + fi + echo "" + + # Remove AD from mhc.yaml + yq -i 'del(.domains[0].hosts[] | select(.role == "ad"))' "$TMT_TREE/src/tests/system/mhc.yaml" + + # Run the test. Artifacts go into $TMT_TEST_DATA, which tmt links to + # this test case in the results (unlike $TMT_PLAN_DATA, which is + # shared across the whole plan and not tied to any individual test). + pytest \ + --durations=0 \ + --color=yes \ + --show-capture=no \ + --mh-config=./mhc.yaml \ + --mh-artifacts-dir="$TMT_TEST_DATA/artifacts" \ + -k "${SELECT_TESTS:-}" \ + -vvv . |& tee "$TMT_TEST_DATA/pytest-colored.log" || rc=$? + + ansifilter "$TMT_TEST_DATA/pytest-colored.log" -o "$TMT_TEST_DATA/pytest.log" + exit "${rc:-0}" + +execute: + how: tmt diff --git a/tmt/readme.md b/tmt/readme.md new file mode 100644 index 00000000000..490999156ce --- /dev/null +++ b/tmt/readme.md @@ -0,0 +1,97 @@ +# System tests + +Test plans for the SSSD system test suite, written in [FMF](https://fmf.readthedocs.io/) +and executed by [tmt](https://tmt.readthedocs.io/) on +[Testing Farm](https://docs.testing-farm.io/). + +* `plans/` -- FMF plans, discovered and run by tmt. + +The plans' `prepare` step fetches +[sssd-ci-containers](https://github.com/pbrezina/sssd-ci-containers)`/tmt/setup.sh`, +which brings up the test containers and installs reusable `ci-*` helper commands +(`ci-exec`, `ci-install-copr`, `ci-select-tests`) used throughout the plans. + +## How it runs via Packit + +See [.packit.yaml](../.packit.yaml), job `tests`. On every pull request, once +the `copr_build` job finishes, Packit submits the plans in this directory to +Testing Farm for each configured target. + +### Rebuilding / rechecking from a pull request + +If a run fails because of infrastructure flakiness, or you just pushed a fix, +retrigger jobs with a PR comment instead of pushing an empty commit: + +``` +/packit build # rebuild the COPR package for every target +/packit test # rerun the `tests` job (waits for a successful build first) +``` + +Useful variants: + +* `/packit build --identifier ` / `/packit test --identifier ` -- only + run the job with the given identifier. +* `/packit test --env KEY=VALUE` -- pass extra environment variables to + Testing Farm (repeat the flag for multiple variables). +* `/packit help` -- list all available commands and options. + +You can also re-run an individual check from the GitHub PR "Checks" tab +(*Details* -> *Re-run*). See the +[Packit retriggering docs](https://packit.dev/docs/retriggering) for the full +command reference. + +## Running locally + +Install the CLI (see the +[CLI docs](https://docs.testing-farm.io/Testing%20Farm/0.1/cli.html) for +alternatives) and set up your +[API token](https://docs.testing-farm.io/Testing%20Farm/0.1/onboarding.html): + +``` +dnf copr enable @testing-farm/stable +dnf install testing-farm +export TESTING_FARM_API_TOKEN= +``` + +### Request a run + +Run from a checkout of the branch you want tested. The branch must be pushed to +a remote reachable by Testing Farm (e.g. your fork) -- it clones `url`/`ref` on +its own infrastructure, it does not see your local working tree. Uncommitted or +unpushed changes are not tested. + +``` +git checkout +testing-farm request --compose Fedora-latest --git-url https://github.com/SSSD/sssd.git --git-ref master +``` + +To request a run using specific COPR repository on specific sssd-ci-container +image use `-e KEY=VALUE` to set environment variables for the command. + +``` +testing-farm request --compose Fedora-latest \ + --git-url https://github.com/SSSD/sssd.git \ + --git-ref master \ + -e PACKIT_COPR_PROJECT=@sssd/nightly \ # Set COPR repository + -e PACKIT_COPR_RPMS='sssd*' \ # Setp packages to install on client and ipa container + -e TAG=centos-10 \ # Set sssd-ci-containers TAG +``` + +### Watch / list requests + +``` +testing-farm watch --id +testing-farm list +testing-farm list --state running +``` + +### Reserve a machine + +Get an interactive box matching the test environment, e.g. to debug a +failure manually: + +``` +testing-farm reserve --compose Fedora-latest +``` + +`testing-farm --help` and `testing-farm --help` cover the rest.