From 287518360aaade3943e91d14b4bc9f806cdc73c6 Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Wed, 27 Nov 2024 10:54:25 +0000 Subject: [PATCH] nixos-rebuild-ng: validate NIX_SSHOPTS --- .../src/nixos_rebuild/__init__.py | 2 +- .../src/nixos_rebuild/process.py | 48 +++++++++++++------ 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/__init__.py b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/__init__.py index a9a7d4d2bef3..47ca3f5f030c 100644 --- a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/__init__.py +++ b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/__init__.py @@ -112,7 +112,7 @@ def parse_args(argv: list[str]) -> argparse.Namespace: # TODO: use deprecated=True in Python >=3.13 if args.no_ssh_tty: - parser_warn("--no-ssh-tty deprecated, SSH's pseudo-TTY is never used anymore") + parser_warn("--no-ssh-tty deprecated, SSH's TTY is never used anymore") if args.action == Action.EDIT.value and (args.file or args.attr): parser.error("--file and --attr are not supported with 'edit'") diff --git a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/process.py b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/process.py index e53f46ff8626..db470ee5753c 100644 --- a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/process.py +++ b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/process.py @@ -7,6 +7,8 @@ from getpass import getpass from pathlib import Path from typing import Self, Sequence, TypedDict, Unpack +from .utils import info + @dataclass(frozen=True) class Remote: @@ -21,23 +23,39 @@ class Remote: ask_sudo_password: bool | None, tmp_dir: Path, ) -> Self | None: - if host: - opts = os.getenv("NIX_SSHOPTS", "").split() + [ - # SSH ControlMaster flags, allow for faster re-connection - "-o", - "ControlMaster=auto", - "-o", - f"ControlPath={tmp_dir / "ssh-%n"}", - "-o", - "ControlPersist=60", - ] - sudo_password = None - if ask_sudo_password: - sudo_password = getpass(f"[sudo] password for {host}: ") - return cls(host, opts, sudo_password) - else: + if not host: return None + opts = os.getenv("NIX_SSHOPTS", "").split() + cls._validate_opts(opts, ask_sudo_password) + opts += [ + # SSH ControlMaster flags, allow for faster re-connection + "-o", + "ControlMaster=auto", + "-o", + f"ControlPath={tmp_dir / "ssh-%n"}", + "-o", + "ControlPersist=60", + ] + sudo_password = None + if ask_sudo_password: + sudo_password = getpass(f"[sudo] password for {host}: ") + return cls(host, opts, sudo_password) + + @staticmethod + def _validate_opts(opts: list[str], ask_sudo_password: bool | None) -> None: + for o in opts: + if o in ["-t", "-tt", "RequestTTY=yes", "RequestTTY=force"]: + info( + f"warning: detected option '{o}' in NIX_SSHOPTS. SSH's TTY " + + "may cause issues, it is recommended to remove this option" + ) + if not ask_sudo_password: + info( + "If you want to prompt for sudo password use " + + "'--ask-sudo-password' option instead" + ) + # Not exhaustive, but we can always extend it later. class RunKwargs(TypedDict, total=False):