99
1010if TYPE_CHECKING :
1111 from ddev .cli .application import Application
12+ from ddev .e2e .agent .interface import AgentInterface
13+
14+
15+ def _invoke_check_with_retry (
16+ agent : AgentInterface , args : list [str ], * , retries : int = 3 , backoff : float = 0.5
17+ ) -> None :
18+ """Invoke ``agent check`` with bounded retry on non-zero exits.
19+
20+ E2E callers race the Agent's check loader: a config-swap or
21+ autodiscovery reload can briefly leave the check unregistered,
22+ causing ``agent check`` to exit with "no valid check found".
23+ Output streams live (not captured) so we can't filter by stderr;
24+ the bound ensures a genuinely broken check still surfaces.
25+ """
26+ import subprocess
27+ import time
28+
29+ for attempt in range (retries + 1 ):
30+ try :
31+ agent .invoke (args )
32+ return
33+ except subprocess .CalledProcessError :
34+ if attempt >= retries :
35+ raise
36+ click .echo (
37+ f'agent check failed (attempt { attempt + 1 } /{ retries + 1 } ), '
38+ f'retrying in { backoff :.1f} s...' ,
39+ err = True ,
40+ )
41+ time .sleep (backoff )
1242
1343
1444@click .command (
@@ -54,7 +84,10 @@ def agent(app: Application, *, intg_name: str, environment: str, args: tuple[str
5484
5585 if config_file is None or not trigger_run :
5686 try :
57- agent .invoke (full_args )
87+ if trigger_run :
88+ _invoke_check_with_retry (agent , full_args )
89+ else :
90+ agent .invoke (full_args )
5891 except subprocess .CalledProcessError as e :
5992 app .abort (code = e .returncode )
6093
@@ -67,14 +100,14 @@ def agent(app: Application, *, intg_name: str, environment: str, args: tuple[str
67100 if not env_data .config_file .is_file ():
68101 try :
69102 env_data .write_config (config )
70- agent . invoke ( full_args )
103+ _invoke_check_with_retry ( agent , full_args )
71104 finally :
72105 env_data .config_file .unlink ()
73106 else :
74107 temp_config_file = env_data .config_file .parent / f'{ env_data .config_file .name } .bak.example'
75108 env_data .config_file .replace (temp_config_file )
76109 try :
77110 env_data .write_config (config )
78- agent . invoke ( full_args )
111+ _invoke_check_with_retry ( agent , full_args )
79112 finally :
80113 temp_config_file .replace (env_data .config_file )
0 commit comments