Skip to content

Commit

Permalink
Dev: utils: Avoid hardcoding the ssh key type as RSA
Browse files Browse the repository at this point in the history
In utils.ssh_copy_id_no_raise, the ssh key type is hardcoded as RSA.
Then the join process will fail if the existing key type is not RSA.

Also see:
ClusterLabs#1504 (comment)
  • Loading branch information
liangxin1300 committed Nov 1, 2024
1 parent 917b0d9 commit 6ef4944
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
38 changes: 35 additions & 3 deletions crmsh/ssh_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ def _add_remote(self, host: str, user: str, key: Key):
tmp.flush()
self._add_by_ssh_copy_id(user, host, tmp.name)

@classmethod
def _add_by_editing_file(cls, user: str, key: Key):
@staticmethod
def _add_by_editing_file(user: str, key: Key):
public_key = key.public_key()
dir = f'~{user}/.ssh'
file = f'{dir}/authorized_keys'
Expand Down Expand Up @@ -208,7 +208,7 @@ def load_public_keys_for_user(self, host: typing.Optional[str], user: str) -> ty
filenames = self.list_public_key_for_user(host, user)
if not filenames:
return list()
cmd = f'cat ~{user}/.ssh/{{{",".join(filenames)}}}'
cmd = f'cat {",".join(filenames)}'
result = self.cluster_shell.subprocess_run_without_input(
host, user,
cmd,
Expand Down Expand Up @@ -265,3 +265,35 @@ def ensure_key_pair_exists_for_user(
else:
keys.append(InMemoryPublicKey(line))
return generated, keys


def fetch_public_key_list(
host: typing.Optional[str],
user: str,
generate_key_pair: bool = False,
with_content: bool = False
) -> typing.List[str]:
"""
Fetch the public key list for the specified user on the specified host.
:param host: the host where the user is located. If None, the local host is assumed.
:param user: the user name
:param generate_key_pair: whether to generate a new key pair if no key pair is found,
default is False
:param with_content: whether to return the content of the public key files,
default is False
:return: a list of public key files if with_content is False, otherwise a list of public key strings
:raise Error: if no public key file is found for the user
"""
key_file_manager = KeyFileManager(sh.cluster_shell())
if generate_key_pair:
key_file_manager.ensure_key_pair_exists_for_user(host, user)
public_keys = key_file_manager.list_public_key_for_user(host, user)
if not public_keys:
host_str = f'@{host}' if host else ' locally'
raise Error(f'No public key file found for {user}{host_str}')
if with_content:
return [KeyFile(_path).public_key() for _path in public_keys]
return public_keys
4 changes: 3 additions & 1 deletion crmsh/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
from . import constants
from . import options
from . import term
from . import ssh_key
from .constants import SSH_OPTION
from . import log
from .prun import prun
Expand Down Expand Up @@ -138,8 +139,9 @@ def ssh_copy_id_no_raise(local_user, remote_user, remote_node, shell: sh.LocalSh
if shell is None:
shell = sh.LocalShell()
if check_ssh_passwd_need(local_user, remote_user, remote_node, shell):
local_public_key = ssh_key.fetch_public_key_list(None, local_user)[0]
logger.info("Configuring SSH passwordless with {}@{}".format(remote_user, remote_node))
cmd = "ssh-copy-id -i ~/.ssh/id_rsa.pub '{}@{}' &> /dev/null".format(remote_user, remote_node)
cmd = f"ssh-copy-id -i {local_public_key} '{remote_user}@{remote_node}' &> /dev/null"
result = shell.su_subprocess_run(local_user, cmd, tty=True)
return result.returncode
else:
Expand Down

0 comments on commit 6ef4944

Please sign in to comment.