Skip to content
This repository was archived by the owner on Jan 23, 2026. It is now read-only.

Commit fea8bea

Browse files
committed
send SIGHUP at end of lease
1 parent afaf058 commit fea8bea

3 files changed

Lines changed: 18 additions & 1 deletion

File tree

packages/jumpstarter-cli/jumpstarter_cli/shell.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ def _run_shell_with_lease(lease, exporter_logs, config, command):
2020
def launch_remote_shell(path: str) -> int:
2121
return launch_shell(
2222
path, lease.exporter_name, config.drivers.allow, config.drivers.unsafe,
23-
config.shell.use_profiles, command=command
23+
config.shell.use_profiles, command=command,
24+
process_callback=lambda proc: setattr(lease, 'shell_process', proc)
2425
)
2526

2627
with lease.serve_unix() as path:

packages/jumpstarter/jumpstarter/client/lease.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class Lease(ContextManagerMixin, AsyncContextManagerMixin):
5353
grpc_options: dict[str, Any] = field(default_factory=dict)
5454
acquisition_timeout: int = field(default=7200) # Timeout in seconds for lease acquisition, polled in 5s intervals
5555
exporter_name: str = field(default="remote", init=False) # Populated during acquisition
56+
shell_process: Any = field(default=None, init=False) # Shell process to terminate on expiry
5657

5758
def __post_init__(self):
5859
if hasattr(super(), "__post_init__"):
@@ -262,6 +263,9 @@ async def _monitor():
262263
if remain < timedelta(0):
263264
# lease already expired, stopping monitor
264265
logger.info("Lease {} ended at {}".format(self.name, end_time))
266+
if self.shell_process is not None:
267+
import signal
268+
self.shell_process.send_signal(signal.SIGHUP)
265269
break
266270
# Log once when entering the threshold window
267271
if threshold - timedelta(seconds=check_interval) <= remain < threshold:

packages/jumpstarter/jumpstarter/common/utils.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ def launch_shell(
5454
use_profiles: bool,
5555
*,
5656
command: tuple[str, ...] | None = None,
57+
process_callback=None,
5758
) -> int:
5859
"""Launch a shell with a custom prompt indicating the exporter type.
5960
@@ -62,6 +63,7 @@ def launch_shell(
6263
context: The context of the shell (e.g. "local" or exporter name)
6364
allow: List of allowed drivers
6465
unsafe: Whether to allow drivers outside of the allow list
66+
process_callback: Optional callback to receive the process object before waiting
6567
"""
6668

6769
shell = os.environ.get("SHELL", "bash")
@@ -74,6 +76,8 @@ def launch_shell(
7476

7577
if command:
7678
process = Popen(command, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr, env=common_env)
79+
if process_callback:
80+
process_callback(process)
7781
return process.wait()
7882

7983
if shell_name.endswith("bash"):
@@ -85,6 +89,8 @@ def launch_shell(
8589
if not use_profiles:
8690
cmd.extend(["--norc", "--noprofile"])
8791
process = Popen(cmd, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr, env=env)
92+
if process_callback:
93+
process_callback(process)
8894
return process.wait()
8995

9096
elif shell_name == "fish":
@@ -103,6 +109,8 @@ def launch_shell(
103109
)
104110
cmd = [shell, "--init-command", fish_fn]
105111
process = Popen(cmd, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr, env=common_env)
112+
if process_callback:
113+
process_callback(process)
106114
return process.wait()
107115

108116
elif shell_name == "zsh":
@@ -120,8 +128,12 @@ def launch_shell(
120128
cmd.extend(["-o", "inc_append_history", "-o", "share_history"])
121129

122130
process = Popen(cmd, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr, env=env)
131+
if process_callback:
132+
process_callback(process)
123133
return process.wait()
124134

125135
else:
126136
process = Popen([shell], stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr, env=common_env)
137+
if process_callback:
138+
process_callback(process)
127139
return process.wait()

0 commit comments

Comments
 (0)