99from centml .sdk import auth
1010from centml .sdk .api import get_centml_client
1111from centml .sdk .config import settings
12- from centml .sdk .shell import ShellError , build_ws_url , exec_session , interactive_session , resolve_pod
12+ from centml .sdk .shell import PodNotFoundError , ShellError , build_ws_url , exec_session , get_running_pods , interactive_session
1313
1414
15- def _connect_args (deployment_id , pod , shell_type ):
15+ def _resolve_pod (running_pods : list [str ], pod_name : str ) -> str :
16+ """Validate that *pod_name* exists in *running_pods*."""
17+ if pod_name not in running_pods :
18+ pods_list = ", " .join (running_pods )
19+ raise PodNotFoundError (f"Pod '{ pod_name } ' not found. Available running pods: { pods_list } " )
20+ return pod_name
21+
22+
23+
24+ def _select_pod (running_pods , deployment_id ):
25+ click .echo (f"Multiple running pods found for deployment { deployment_id } :" )
26+ for i , name in enumerate (running_pods , 1 ):
27+ click .echo (f" [{ i } ] { name } " )
28+
29+ choice = click .prompt (
30+ "Select a pod" ,
31+ type = click .IntRange (1 , len (running_pods )),
32+ prompt_suffix = f" [1-{ len (running_pods )} ]: " ,
33+ )
34+ return running_pods [choice - 1 ]
35+
36+
37+ def _connect_args (deployment_id , pod , shell_type , first_pod = False ):
1638 """Resolve pod, build WebSocket URL, and obtain auth token."""
1739 with get_centml_client () as cclient :
18- try :
19- pod_name , warning = resolve_pod (cclient , deployment_id , pod )
20- except ShellError as exc :
21- raise click .ClickException (str (exc )) from exc
22- if warning is not None :
23- click .echo (f"{ warning } Use --pod to specify a different pod." , err = True )
40+ running_pods = get_running_pods (cclient , deployment_id )
41+ if not running_pods :
42+ raise click .ClickException (f"No running pods found for deployment { deployment_id } " )
43+
44+ if pod is not None :
45+ try :
46+ pod_name = _resolve_pod (running_pods , pod )
47+ except ShellError as exc :
48+ raise click .ClickException (str (exc )) from exc
49+ elif len (running_pods ) == 1 or first_pod :
50+ pod_name = running_pods [0 ]
51+ else :
52+ pod_name = _select_pod (running_pods , deployment_id )
2453
2554 ws_url = build_ws_url (settings .CENTML_PLATFORM_API_URL , deployment_id , pod_name , shell_type )
2655 token = auth .get_centml_token ()
@@ -29,14 +58,15 @@ def _connect_args(deployment_id, pod, shell_type):
2958
3059@click .command (help = "Open an interactive shell to a deployment pod" )
3160@click .argument ("deployment_id" , type = int )
32- @click .option ("--pod" , default = None , help = "Specify a pod name (Default: auto-selects first running pod) " )
61+ @click .option ("--pod" , default = None , help = "Specify a pod name" )
3362@click .option ("--shell" , "shell_type" , default = None , type = click .Choice (["bash" , "sh" , "zsh" ]), help = "Shell type" )
63+ @click .option ("--first-pod" , is_flag = True , default = False , help = "Auto-select the first running pod (skip interactive selection)" )
3464@handle_exception
35- def shell (deployment_id , pod , shell_type ):
65+ def shell (deployment_id , pod , shell_type , first_pod ):
3666 if not sys .stdin .isatty ():
3767 raise click .ClickException ("Interactive shell requires a terminal (TTY)" )
3868
39- ws_url , token = _connect_args (deployment_id , pod , shell_type )
69+ ws_url , token = _connect_args (deployment_id , pod , shell_type , first_pod )
4070 exit_code = asyncio .run (interactive_session (ws_url , token ))
4171 sys .exit (exit_code )
4272
@@ -46,8 +76,9 @@ def shell(deployment_id, pod, shell_type):
4676@click .argument ("command" , nargs = - 1 , required = True , type = click .UNPROCESSED )
4777@click .option ("--pod" , default = None , help = "Specific pod name" )
4878@click .option ("--shell" , "shell_type" , default = None , type = click .Choice (["bash" , "sh" , "zsh" ]), help = "Shell type" )
79+ @click .option ("--first-pod" , is_flag = True , default = False , help = "Auto-select the first running pod (skip interactive selection)" )
4980@handle_exception
50- def exec_cmd (deployment_id , command , pod , shell_type ):
51- ws_url , token = _connect_args (deployment_id , pod , shell_type )
81+ def exec_cmd (deployment_id , command , pod , shell_type , first_pod ):
82+ ws_url , token = _connect_args (deployment_id , pod , shell_type , first_pod )
5283 exit_code = asyncio .run (exec_session (ws_url , token , " " .join (command )))
5384 sys .exit (exit_code )
0 commit comments