diff --git a/packages/jumpstarter-cli/jumpstarter_cli/shell.py b/packages/jumpstarter-cli/jumpstarter_cli/shell.py index 64e682035..521a5b2ce 100644 --- a/packages/jumpstarter-cli/jumpstarter_cli/shell.py +++ b/packages/jumpstarter-cli/jumpstarter_cli/shell.py @@ -51,6 +51,7 @@ def shell(config, command: tuple[str, ...], lease_name, selector, duration, expo "remote", config.drivers.allow, config.drivers.unsafe, + config.shell_use_profiles, command=command, ) else: @@ -59,6 +60,7 @@ def shell(config, command: tuple[str, ...], lease_name, selector, duration, expo "remote", config.drivers.allow, config.drivers.unsafe, + config.shell.use_profiles, command=command, ) @@ -72,5 +74,6 @@ def shell(config, command: tuple[str, ...], lease_name, selector, duration, expo "local", allow=[], unsafe=True, + use_profiles=False, command=command, ) diff --git a/packages/jumpstarter/jumpstarter/common/utils.py b/packages/jumpstarter/jumpstarter/common/utils.py index f732c942a..7450aa764 100644 --- a/packages/jumpstarter/jumpstarter/common/utils.py +++ b/packages/jumpstarter/jumpstarter/common/utils.py @@ -51,6 +51,7 @@ def launch_shell( context: str, allow: list[str], unsafe: bool, + use_profiles: bool, *, command: tuple[str, ...] | None = None, ) -> int: @@ -79,7 +80,10 @@ def launch_shell( env = common_env | { "PS1": f"{ANSI_GRAY}{PROMPT_CWD} {ANSI_YELLOW}⚡{ANSI_WHITE}{context} {ANSI_YELLOW}➤{ANSI_RESET} ", } - cmd = [shell, "--norc", "--noprofile"] + + cmd = [shell] + if not use_profiles: + cmd.extend(['--norc','--noprofile']) process = Popen(cmd, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr, env=env) return process.wait() diff --git a/packages/jumpstarter/jumpstarter/common/utils_test.py b/packages/jumpstarter/jumpstarter/common/utils_test.py index ece4c3239..86cd52dfd 100644 --- a/packages/jumpstarter/jumpstarter/common/utils_test.py +++ b/packages/jumpstarter/jumpstarter/common/utils_test.py @@ -5,9 +5,20 @@ def test_launch_shell(tmp_path, monkeypatch): monkeypatch.setenv("SHELL", shutil.which("true")) - exit_code = launch_shell(host=str(tmp_path / "test.sock"), context="remote", allow=["*"], unsafe=False) + exit_code = launch_shell( + host=str(tmp_path / "test.sock"), + context="remote", + allow=["*"], + unsafe=False, + use_profiles=False + ) assert exit_code == 0 monkeypatch.setenv("SHELL", shutil.which("false")) - exit_code = launch_shell(host=str(tmp_path / "test.sock"), context="remote", allow=["*"], unsafe=False) + exit_code = launch_shell( + host=str(tmp_path / "test.sock"), + context="remote", allow=["*"], + unsafe=False, + use_profiles=False + ) assert exit_code == 1 diff --git a/packages/jumpstarter/jumpstarter/config/client.py b/packages/jumpstarter/jumpstarter/config/client.py index 0661c5019..332587ff1 100644 --- a/packages/jumpstarter/jumpstarter/config/client.py +++ b/packages/jumpstarter/jumpstarter/config/client.py @@ -24,6 +24,7 @@ from .common import CONFIG_PATH, ObjectMeta from .env import JMP_LEASE from .grpc import call_credentials +from .shell import ShellConfigV1Alpha1 from .tls import TLSConfigV1Alpha1 from jumpstarter.client.grpc import ClientService, WithLease, WithLeaseList from jumpstarter.common.exceptions import ( @@ -103,6 +104,8 @@ class ClientConfigV1Alpha1(BaseSettings): drivers: ClientConfigV1Alpha1Drivers = Field(default_factory=ClientConfigV1Alpha1Drivers) + shell: ShellConfigV1Alpha1 = Field(default_factory=ShellConfigV1Alpha1) + async def channel(self): if self.endpoint is None or self.token is None: raise ConfigurationError("endpoint or token not set in client config") diff --git a/packages/jumpstarter/jumpstarter/config/client_config_test.py b/packages/jumpstarter/jumpstarter/config/client_config_test.py index af9bd3735..3dbcdabf1 100644 --- a/packages/jumpstarter/jumpstarter/config/client_config_test.py +++ b/packages/jumpstarter/jumpstarter/config/client_config_test.py @@ -8,7 +8,7 @@ from pydantic import ValidationError from jumpstarter.common.exceptions import FileNotFoundError -from jumpstarter.config.client import ClientConfigV1Alpha1, ClientConfigV1Alpha1Drivers +from jumpstarter.config.client import ClientConfigV1Alpha1, ClientConfigV1Alpha1Drivers, ShellConfigV1Alpha1 from jumpstarter.config.common import ObjectMeta from jumpstarter.config.env import JMP_DRIVERS_ALLOW, JMP_ENDPOINT, JMP_NAME, JMP_NAMESPACE, JMP_TOKEN @@ -212,6 +212,8 @@ def test_client_config_save(monkeypatch: pytest.MonkeyPatch): - jumpstarter.drivers.* - vendorpackage.* unsafe: false +shell: + use_profiles: false """ config = ClientConfigV1Alpha1( alias="testclient", @@ -219,6 +221,7 @@ def test_client_config_save(monkeypatch: pytest.MonkeyPatch): endpoint="jumpstarter.my-lab.com:1443", token="dGhpc2lzYXRva2VuLTEyMzQxMjM0MTIzNEyMzQtc2Rxd3Jxd2VycXdlcnF3ZXJxd2VyLTEyMzQxMjM0MTIz", drivers=ClientConfigV1Alpha1Drivers(allow=["jumpstarter.drivers.*", "vendorpackage.*"], unsafe=False), + shell=ShellConfigV1Alpha1(use_profiles=False), ) with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: with patch.object(ClientConfigV1Alpha1, "_get_path", return_value=Path(f.name)) as _get_path_mock: @@ -248,6 +251,8 @@ def test_client_config_save_explicit_path(): - jumpstarter.drivers.* - vendorpackage.* unsafe: false +shell: + use_profiles: false """ config = ClientConfigV1Alpha1( alias="testclient", @@ -255,6 +260,7 @@ def test_client_config_save_explicit_path(): endpoint="jumpstarter.my-lab.com:1443", token="dGhpc2lzYXRva2VuLTEyMzQxMjM0MTIzNEyMzQtc2Rxd3Jxd2VycXdlcnF3ZXJxd2VyLTEyMzQxMjM0MTIz", drivers=ClientConfigV1Alpha1Drivers(allow=["jumpstarter.drivers.*", "vendorpackage.*"], unsafe=False), + shell=ShellConfigV1Alpha1(use_profiles=False), ) with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: with patch.object(ClientConfigV1Alpha1, "ensure_exists"): @@ -280,6 +286,8 @@ def test_client_config_save_unsafe_drivers(): drivers: allow: [] unsafe: true +shell: + use_profiles: false """ config = ClientConfigV1Alpha1( alias="testclient", @@ -287,6 +295,7 @@ def test_client_config_save_unsafe_drivers(): endpoint="jumpstarter.my-lab.com:1443", token="dGhpc2lzYXRva2VuLTEyMzQxMjM0MTIzNEyMzQtc2Rxd3Jxd2VycXdlcnF3ZXJxd2VyLTEyMzQxMjM0MTIz", drivers=ClientConfigV1Alpha1Drivers(allow=[], unsafe=True), + shell=ShellConfigV1Alpha1(use_profiles=False), ) with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: with patch.object(ClientConfigV1Alpha1, "ensure_exists"): diff --git a/packages/jumpstarter/jumpstarter/config/shell.py b/packages/jumpstarter/jumpstarter/config/shell.py new file mode 100644 index 000000000..c0109a574 --- /dev/null +++ b/packages/jumpstarter/jumpstarter/config/shell.py @@ -0,0 +1,5 @@ +from pydantic import BaseModel + + +class ShellConfigV1Alpha1(BaseModel): + use_profiles: bool = False