Aller au contenu

Squash Orchestrator

Squash Orchestrator est le composant d'exécution distribué de la stack Squash. Il reçoit des jobs depuis Squash TM (signés JWT RS512), les achemine via SSH vers le test-runner, collecte les résultats et les retourne à Squash TM pour agrégation dans les campagnes.

Source de vérité

Cette page est tirée du bloc perfshop-orchestrator des fichiers compose et des quatre fichiers de configuration YAML bind-mountés : squash-orchestrator/pools.yaml, sshee.yaml, arranger.yaml, squashtf.yaml.

Architecture — OpenTestFactory

Squash Orchestrator est une implémentation de référence du framework OpenTestFactory (OTF) développé par Squashtest et Henix. Le framework est modulaire : plusieurs « services » (eventbus, sshee, arranger, workflow) communiquent entre eux via un bus d'événements interne, et chaque service a sa propre configuration.

flowchart LR
  STM["perfshop-testmgmt<br/>(Squash TM)"]

  subgraph ORCH["perfshop-orchestrator"]
    direction TB
    EB(["eventbus"])
    AR["arranger<br/>(reçoit les jobs HTTP)"]
    WF["workflow<br/>(exécute la séquence d'étapes)"]
    SSHEE["sshee<br/>(SSH executor engine)"]
    AR --> EB
    WF --> EB
    SSHEE --> EB
    EB --> WF
    EB --> SSHEE
  end

  TR["perfshop-test-runner<br/>(OpenSSH server)"]

  STM -->|"POST /jobs<br/>JWT RS512"| AR
  SSHEE -->|"SSH :22<br/>user=root password=perfshop"| TR

Service perfshop-orchestrator

perfshop-orchestrator:
  image: squashtest/squash-orchestrator:latest
  container_name: perfshop-orchestrator
  depends_on:
    perfshop-testmgmt:
      condition: service_healthy
    perfshop-test-runner:
      condition: service_started
  environment:
    - SQUASH_JWT_SECRET=${SQUASH_JWT_SECRET}
    - SQUASH_TM_URL=http://perfshop-testmgmt:8080/squash
    - SQUASH_TM_USER=${SQUASH_ADMIN_LOGIN:-admin}
    - SQUASH_TM_PASSWORD=${SQUASH_ADMIN_PASSWORD:-Squash2026*}
  volumes:
    - ./squash-orchestrator/pools.yaml:/etc/squashtf/pools.yaml:ro
    - ./squash-orchestrator/sshee.yaml:/etc/squashtf/sshee.yaml:ro
    - ./squash-orchestrator/arranger.yaml:/etc/squashtf/arranger.yaml:ro
    - ./squash-orchestrator/squashtf.yaml:/etc/squashtf/squashtf.yaml:ro
    - ./squash-seed/trusted_key.pub:/etc/squashtf/trusted_key.pub:ro

Variables d'environnement

Variable Rôle
SQUASH_JWT_SECRET Même secret que perfshop-testmgmt — utilisé pour vérifier les JWT signés par Squash TM
SQUASH_TM_URL URL interne de Squash TM (pour les callbacks de résultats)
SQUASH_TM_USER / _PASSWORD Compte utilisé pour poster les résultats dans Squash TM

Les quatre fichiers YAML

pools.yaml — définition du pool d'exécution

pools:
  default:
    - host: perfshop-test-runner
      port: 22
      username: root
      password: perfshop
      tags:
        - linux
        - robotframework
      namespaces: "default"

Un seul pool est défini, nommé default, contenant une seule cible : perfshop-test-runner sur le port SSH 22 avec l'utilisateur root et le mot de passe perfshop.

Champ Valeur Effet
host perfshop-test-runner DNS Docker interne
port 22 Port SSH standard du container test-runner
username: root / password: perfshop Credentials définis dans le Dockerfile du test-runner
tags [linux, robotframework] Tags pour le routage — un job qui déclare runs-on: robotframework sera acheminé vers ce pool
namespaces: "default" Force l'enregistrement dans le namespace "default" que l'agentchannel Java utilise pour router les workflows

Authentification SSH par mot de passe

Le test-runner accepte l'authentification SSH par mot de passe (clé en dur dans le Dockerfile). C'est acceptable parce que le container n'est pas exposé à l'extérieur (port 22 uniquement sur le réseau Docker interne), mais ne conviendrait pas à une exposition publique. Le Dockerfile le documente explicitement : « Accès root avec password "perfshop" — usage pédagogique uniquement ».

sshee.yaml — SSH Executor Engine

apiVersion: opentestfactory.org/v1alpha1
kind: SSHServiceConfig
current-context: default
contexts:
- context:
    port: 443
    host: 127.0.0.1
    ssl_context: adhoc
    logfile: sshee.log
    eventbus:
      endpoint: https://127.0.0.1:38368
      token: reuse
    targets: [default]
  name: default
- context:
    port: 7786
    host: 127.0.0.1
    ssl_context: disabled
    trusted_authorities:
    - /etc/squashtf/*
    logfile: sshee.log
    enable_insecure_login: true
    eventbus:
        endpoint: http://127.0.0.1:38368
        token: reuse
    targets: [default]
  name: allinone
- context:
    port: 9365
    host: 127.0.0.1
    ssl_context: disabled
    # ...
  name: insecure

Trois contextes sont déclarés :

Contexte Port SSL Usage
default 443 adhoc (certificat auto-signé généré au démarrage) Mode principal, HTTPS self-signed sur eventbus https://127.0.0.1:38368
allinone 7786 disabled Mode « tout-en-un » où eventbus, arranger, sshee tournent dans le même process avec SSL désactivé ; trusted_authorities lit la clé publique depuis /etc/squashtf/*
insecure 9365 disabled Mode explicite sans sécurité, pour debug

La connexion entre sshee et l'eventbus interne se fait en HTTP local (127.0.0.1) — c'est du loopback intra-container, pas du réseau Docker. Tous les sous-services OpenTestFactory tournent dans le même container.

arranger.yaml — ordonnanceur de jobs

apiVersion: opentestfactory.org/v1beta2
kind: ServiceConfig
current-context: default
contexts:
- context:
    port: 443
    host: 127.0.0.1
    ssl_context: adhoc
    logfile: arranger.log
    eventbus:
      endpoint: https://127.0.0.1:38368
      token: reuse
    max_jobs: 1024
    max_job_steps: 10240
    max_workers: 4
    default_timeout_minutes: 360
  name: default
# ... allinone et insecure contextes similaires

L'arranger est le frontend HTTP qui reçoit les jobs depuis Squash TM. Il expose l'API qui accepte les POST /jobs et les place dans l'eventbus interne pour traitement par le workflow engine.

Paramètre Valeur Effet
max_jobs 1024 Cap sur le nombre de jobs simultanément en attente
max_job_steps 10240 Cap sur le nombre d'étapes total d'un job
max_workers 4 Nombre de workers concurrents qui dépilent les jobs
default_timeout_minutes 360 (6 heures) Timeout par défaut par job
pending_timeout_minutes (contexte allinone) 5 Cap sur le temps d'attente avant exécution

squashtf.yaml — configuration du workflow engine

eventbus: python3 -m opentf.core.eventbus
services:
  - ${{ CORE }}/core
  - ${{ CORE }}/qualitygate
plugins:
  - ${{ CORE }}/plugins
  - /app/plugins
  - ${{ CORE }}/../squash/orchestrator
  - /app/tm-connector
aggregated:
- actionprovider
- cucumber
- cypress
- robotframework
- junit
- postman
- skf
- soapui
- playwright
disabled:
  - HelloWorld
  - localpublisher
  - dummygenerator
  - agentchannel

C'est le manifeste du workflow engine qui relie tous les plugins.

9 plugins agrégés

Plugin Usage
actionprovider Plugin de base qui expose les actions unitaires
cucumber Tests BDD Cucumber
cypress Tests E2E Cypress
robotframework Tests Robot Framework — c'est le plugin principal utilisé par PerfShop
junit Tests JUnit
postman Tests Postman/Newman
skf Squash Keyword Framework (tests par mots-clés)
soapui Tests SoapUI
playwright Tests E2E Playwright

Tous les plugins sont présents dans l'image officielle — PerfShop ne les sélectionne pas, c'est la configuration standard de l'éditeur. L'étudiant peut ainsi expérimenter avec n'importe lequel sans reconfiguration.

4 plugins désactivés

Plugin désactivé Pourquoi ?
HelloWorld Plugin exemple sans valeur
localpublisher Publisher local, remplacé par la connexion Squash TM
dummygenerator Générateur de données factices, inutile
agentchannel CRITIQUE — l'agentchannel Java répond « not found » avant le sshee et annule le workflow. Commenté en tête du fichier. Sans cette désactivation, aucun job ne s'exécute.

agentchannel désactivé — cas réel

Le commentaire en tête de squashtf.yaml est explicite : « agentchannel désactivé : il répond 'not found' avant le sshee et annule le workflow. Le sshee gère directement les SSH channels via sshee.yaml ». C'est une découverte pédagogique intéressante — elle montre comment un mauvais ordre de dispatch dans un bus d'événements peut bloquer silencieusement un système entier, et comment le désactiver explicitement résout le problème.

Le format d'un job JWT RS512

Squash TM signe ses jobs en RS512 (RSA SHA-512) avec la clé privée trusted_key.pem (stockée dans le container Squash TM) ; l'orchestrateur vérifie avec trusted_key.pub (bind-mountée dans /etc/squashtf/trusted_key.pub).

sequenceDiagram
  autonumber
  participant STM as Squash TM
  participant AR as orchestrator<br/>arranger
  participant SSHEE as orchestrator<br/>sshee
  participant TR as perfshop-test-runner

  STM->>STM: Génère jobspec<br/>(script, repo, commit, env vars)
  STM->>STM: Signe avec trusted_key.pem<br/>(RS512)
  STM->>AR: POST /jobs<br/>Authorization: Bearer <JWT>

  AR->>AR: Vérifie JWT avec trusted_key.pub
  alt JWT invalide
    AR-->>STM: 401 Unauthorized
  else JWT valide
    AR->>AR: Place dans eventbus (pending)
    AR-->>STM: 200 Accepted, job_id=...
  end

  AR->>SSHEE: Dispatch job (pool=default)
  SSHEE->>TR: SSH root@perfshop-test-runner<br/>(password perfshop)
  SSHEE->>TR: SCP script.robot
  SSHEE->>TR: Exec robot script.robot
  TR-->>SSHEE: Exit code + stdout/stderr
  SSHEE->>AR: Résultat (via eventbus)
  AR->>STM: POST /squash/api/rest/executions/...<br/>{status:PASS|FAIL, log:...}

Points clés :

  • Authentification mutuelle : Squash TM prouve son identité avec sa clé privée, l'orchestrateur vérifie avec la clé publique. Sans cette clé publique bind-mountée, aucun job ne peut être accepté.
  • Canal SSH : une fois le job accepté, l'orchestrateur ouvre une connexion SSH réelle vers le test-runner (pas de bus d'événements, pas de queue externe). C'est simple et robuste.
  • Retour des résultats : l'orchestrateur utilise SQUASH_TM_URL + SQUASH_TM_USER/PASSWORD pour poster les résultats dans l'API REST Squash TM.

Ordre de démarrage

L'orchestrateur dépend de deux services :

flowchart LR
  STM[("perfshop-testmgmt<br/>healthy")] --> ORCH
  TR[("perfshop-test-runner<br/>started")] --> ORCH
  ORCH["perfshop-orchestrator<br/>(démarre)"]
  • perfshop-testmgmt: service_healthy — pour pouvoir poster des résultats
  • perfshop-test-runner: service_started — l'orchestrateur n'attend pas un healthcheck particulier du runner (il lui ouvrira une connexion SSH au moment voulu)

Volumes

Volume Montage Contenu
./squash-orchestrator/pools.yaml (bind RO) /etc/squashtf/pools.yaml Définition des pools SSH
./squash-orchestrator/sshee.yaml (bind RO) /etc/squashtf/sshee.yaml SSH executor engine contexts
./squash-orchestrator/arranger.yaml (bind RO) /etc/squashtf/arranger.yaml Configuration arranger (max_jobs, max_workers)
./squash-orchestrator/squashtf.yaml (bind RO) /etc/squashtf/squashtf.yaml Manifeste du workflow engine (plugins)
./squash-seed/trusted_key.pub (bind RO) /etc/squashtf/trusted_key.pub Clé publique RSA pour vérifier les JWT

Ports

Le service perfshop-orchestrator n'expose aucun port à l'hôte — il n'est accessible que depuis le réseau Docker interne. Les ports HTTPS 443 (arranger) et HTTP 38368 (eventbus interne) sont en loopback intra-container.

Pour aller plus loin