Skip to content

Commit

Permalink
[crmsh-4.5] Dev: bootstrap: more robust implementation for ssh_merge …
Browse files Browse the repository at this point in the history
…(bsc#1230530) (#1575)

* Do not use legacy `write_remote_file`, which does not work well with
`_guess_user_for_ssh`.
* Implement deduplication when merging known_hosts
  • Loading branch information
nicholasyang2022 authored Nov 13, 2024
2 parents 21fd822 + 85ace09 commit 05da45b
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 33 deletions.
36 changes: 18 additions & 18 deletions crmsh/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# TODO: Make csync2 usage optional
# TODO: Configuration file for bootstrap?
import codecs
import io
import os
import subprocess
import sys
Expand All @@ -25,15 +26,13 @@

import yaml
import socket
from tempfile import mktemp
from string import Template
from lxml import etree

import crmsh.parallax
from . import config, constants
from . import utils
from . import xmlutil
from .cibconfig import mkset_obj, cib_factory
from .cibconfig import cib_factory
from . import corosync
from . import tmpfiles
from . import lock
Expand Down Expand Up @@ -855,8 +854,8 @@ def init_ssh_impl(local_user: str, user_node_list: typing.List[typing.Tuple[str,
public_key_list.append(swap_public_ssh_key(node, local_user, remote_user, local_user, remote_user, add=True))
hacluster_public_key_list.append(swap_public_ssh_key(node, 'hacluster', 'hacluster', local_user, remote_user, add=True))
if len(user_node_list) > 1:
shell_script = _merge_authorized_keys(public_key_list)
hacluster_shell_script = _merge_authorized_keys(hacluster_public_key_list)
shell_script = _merge_line_into_file('~/.ssh/authorized_keys', public_key_list).encode('utf-8')
hacluster_shell_script = _merge_line_into_file('~/.ssh/authorized_keys', hacluster_public_key_list).encode('utf-8')
for i, (remote_user, node) in enumerate(user_node_list):
result = utils.su_subprocess_run(
local_user,
Expand Down Expand Up @@ -885,16 +884,18 @@ def init_ssh_impl(local_user: str, user_node_list: typing.List[typing.Tuple[str,
change_user_shell('hacluster', node)


def _merge_authorized_keys(keys: typing.List[str]) -> bytes:
shell_script = '''for key in "${keys[@]}"; do
grep -F "$key" ~/.ssh/authorized_keys > /dev/null || sed -i "\\$a $key" ~/.ssh/authorized_keys
done'''
keys_definition = ("keys+=('{}')\n".format(key) for key in keys)
buf = bytearray()
def _merge_line_into_file(path: str, lines: typing.Iterable[str]) -> str:
shell_script = '''[ -e "$path" ] || echo '# created by crmsh' > "$path"
for key in "${keys[@]}"; do
grep -F "$key" "$path" > /dev/null || sed -i "\\$a $key" "$path"
done'''
keys_definition = ("keys+=('{}')\n".format(key) for key in lines)
buf = io.StringIO()
buf.write(f'path={path}\n')
for item in keys_definition:
buf.extend(item.encode('utf-8'))
buf.extend(shell_script.encode('utf-8'))
return buf
buf.write(item)
buf.write(shell_script)
return buf.getvalue()


def _fetch_core_hosts(local_user, remote_user, remote_host) -> typing.Tuple[typing.List[str], typing.List[str]]:
Expand Down Expand Up @@ -1832,7 +1833,7 @@ def join_ssh_merge(cluster_node, remote_user):
rc, _, _ = utils.get_stdout_stderr_as_local_sudoer("ssh {} {} true".format(SSH_OPTION, utils.this_node()))
assert rc == 0

known_hosts_new = set()
known_hosts_new: set[str] = set()

cat_cmd = "[ -e ~/.ssh/known_hosts ] && cat ~/.ssh/known_hosts || true"
#logger_utils.log_only_to_file("parallax.call {} : {}".format(hosts, cat_cmd))
Expand All @@ -1842,10 +1843,9 @@ def join_ssh_merge(cluster_node, remote_user):
known_hosts_new.update((utils.to_ascii(known_hosts_content) or "").splitlines())

if known_hosts_new:
hoststxt = "\n".join(sorted(known_hosts_new))
#results = parallax.parallax_copy(hosts, tmpf, known_hosts_path, strict=False)
script = _merge_line_into_file('~/.ssh/known_hosts', known_hosts_new)
for host in hosts:
utils.write_remote_file(hoststxt, "~/.ssh/known_hosts", utils.user_of(host), remote=host)
utils.get_stdout_or_raise_error(script, remote=host)


def update_expected_votes():
Expand Down
15 changes: 0 additions & 15 deletions crmsh/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -776,21 +776,6 @@ def str2file(s, fname, mod=0o644):
return False
return True

def write_remote_file(text, tofile, user, remote):
shell_script = f'''cat >> {tofile} << EOF
{text}
EOF
'''
result = subprocess_run_auto_ssh_no_input(
shell_script,
remote,
user,
stdout=subprocess.DEVNULL,
stderr=subprocess.PIPE,
)
if result.returncode != 0:
raise ValueError("Failed to write to {}@{}/{}: {}".format(user, remote, tofile, result.stdout.decode('utf-8')))

def copy_remote_textfile(remote_user, remote_node, remote_text_file, local_path):
"""
scp might lack permissions to copy the file for a non-root user.
Expand Down

0 comments on commit 05da45b

Please sign in to comment.