diff --git a/crmsh/ssh_key.py b/crmsh/ssh_key.py index f45a0fe9e3..e9cb57a4a3 100644 --- a/crmsh/ssh_key.py +++ b/crmsh/ssh_key.py @@ -5,6 +5,7 @@ import subprocess import tempfile import typing +from io import StringIO from crmsh import sh @@ -18,11 +19,29 @@ def __init__(self, msg: str): class AgentNotAvailableError(Error): - pass + def __init__(self, msg): + super().__init__(f'{msg}{self.diagnose()}') + + @staticmethod + def diagnose() -> str: + with StringIO() as buf: + if 'SSH_AUTH_SOCK' not in os.environ: + buf.write(' Environmental variable SSH_AUTH_SOCK does not exists.') + if 'SUDO_USER' in os.environ: + buf.write(' Please make sure environmental variables are preserved across sudo calls.') + return buf.getvalue() class NoKeysInAgentError(Error): - pass + def __init__(self, msg): + super().__init__(f'{msg}{self.diagnose()}') + + @staticmethod + def diagnose() -> str: + ssh_auth_sock = os.environ["SSH_AUTH_SOCK"] + st = os.stat(ssh_auth_sock) + owner_name = pwd.getpwuid(st.st_uid).pw_name + return f' crmsh is using an ssh-agent listening at {ssh_auth_sock}, owned by {owner_name}. Please add at least one key pair with `ssh-add`' class Key: diff --git a/test/features/ssh_agent.feature b/test/features/ssh_agent.feature index 776975c774..0c5eb1dc5c 100644 --- a/test/features/ssh_agent.feature +++ b/test/features/ssh_agent.feature @@ -4,9 +4,19 @@ Feature: ssh-agent support Test ssh-agent support for crmsh Need nodes: hanode1 hanode2 hanode3 + Scenario: Errors are reported when ssh-agent is not avaible + When Try "crm cluster init --use-ssh-agent -y" on "hanode1" + Then Expected "Environmental variable SSH_AUTH_SOCK does not exists." in stderr + When Try "SSH_AUTH_SOCK=/root/ssh-auth-sock crm cluster init --use-ssh-agent -y" on "hanode1" + Then Expected "Environmental variable SSH_AUTH_SOCK does not exists." not in stderr + + Scenario: Errors are reported when there are no keys in ssh-agent + Given ssh-agent is started at "/root/ssh-auth-sock" on nodes ["hanode1", "hanode2", "hanode3"] + When Try "SSH_AUTH_SOCK=/root/ssh-auth-sock crm cluster init --use-ssh-agent -y" on "hanode1" + Then Expected "ssh-add" in stderr + Scenario: Skip creating ssh key pairs with --use-ssh-agent Given Run "mkdir /root/ssh_disabled && mv /root/.ssh/id_* /root/ssh_disabled" OK on "hanode1,hanode2,hanode3" - And ssh-agent is started at "/root/ssh-auth-sock" on nodes ["hanode1", "hanode2", "hanode3"] When Run "SSH_AUTH_SOCK=/root/ssh-auth-sock ssh-add /root/ssh_disabled/id_rsa" on "hanode1,hanode2,hanode3" And Run "SSH_AUTH_SOCK=/root/ssh-auth-sock crm cluster init --use-ssh-agent -y" on "hanode1" And Run "SSH_AUTH_SOCK=/root/ssh-auth-sock crm cluster join --use-ssh-agent -y -c hanode1" on "hanode2" diff --git a/test/features/steps/step_implementation.py b/test/features/steps/step_implementation.py index 1b3602721f..78d191fd26 100644 --- a/test/features/steps/step_implementation.py +++ b/test/features/steps/step_implementation.py @@ -100,7 +100,7 @@ def step_impl(context, addr, iface): @given('Run "{cmd}" OK on "{addr}"') def step_impl(context, cmd, addr): - _, out, _ = run_command_local_or_remote(context, cmd, addr) + _, out, _ = run_command_local_or_remote(context, cmd, addr, True) @when('Run "{cmd}" on "{addr}"') def step_impl(context, cmd, addr): @@ -109,7 +109,7 @@ def step_impl(context, cmd, addr): @then('Run "{cmd}" OK on "{addr}"') def step_impl(context, cmd, addr): - _, out, _ = run_command_local_or_remote(context, cmd, addr) + _, out, _ = run_command_local_or_remote(context, cmd, addr, True) @then('Print stdout')