Commit 6f7c2d81 authored by Muhammad Umair Khan's avatar Muhammad Umair Khan
Browse files

Fix interactive sudo authentication failure when deploying without a password

Verify non-interactive sudo and SSH key access for both local (@local) and remote hosts when no password is provided at the initial prompt. If passwordless sudo is not configured on the target machine, display an explicit error explaining the authentication requirement and prompt for the SSH/sudo password automatically to prevent task execution failures.
parent 059a5e88
Loading
Loading
Loading
Loading
+22 −2
Original line number Diff line number Diff line
@@ -116,15 +116,35 @@ def get_k8s_inventory():
            "A single machine cannot act as both an independent master and worker node."
        )

    def _verify_and_prompt_pw(nodes, pw, label):
        if pw:
            return pw
        import subprocess
        for host_addr, ssh_user in nodes:
            if host_addr == "@local":
                cmd = ["sudo", "-n", "true"]
                err_msg = "[ERROR] Localhost (@local) requires a password for sudo, but no password was entered."
            else:
                cmd = ["ssh", "-o", "BatchMode=yes", "-o", "ConnectTimeout=5", f"{ssh_user}@{host_addr}", "sudo", "-n", "true"]
                err_msg = f"[ERROR] Remote host {host_addr} ({ssh_user}) requires a password for SSH or sudo, but no password was entered."

            res = subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
            if res.returncode != 0:
                print(f"\033[91m{err_msg}\033[0m")
                prompted = getpass.getpass(f"Enter SSH/sudo password for {label} ({host_addr}): ").strip()
                if prompted:
                    return prompted
        return None

    # 2. Credential acquisition (single unified prompt)
    master_pw = None
    worker_pw = None
    if is_interactive():
        prompted_m = getpass.getpass("Enter password for K8S_MASTERS node(s) (for SSH/sudo, or press Enter if using SSH keys/passwordless sudo): ").strip()
        master_pw = prompted_m if prompted_m else None
        master_pw = _verify_and_prompt_pw(masters, prompted_m if prompted_m else None, "K8S_MASTERS")
        if workers:
            prompted_w = getpass.getpass("Enter password for K8S_WORKERS node(s) (for SSH/sudo, or press Enter if using SSH keys/passwordless sudo): ").strip()
            worker_pw = prompted_w if prompted_w else None
            worker_pw = _verify_and_prompt_pw(workers, prompted_w if prompted_w else None, "K8S_WORKERS")

    # 3. Build PyInfra host tuples
    def _build_host_tuple(host_addr, ssh_user, pw):