Skip to content

Commit

Permalink
Fix: bootstrap: should check if sudo is available when running `clust…
Browse files Browse the repository at this point in the history
…er join -c` with a non-root destination user (bsc#1228950)
  • Loading branch information
nicholasyang2022 committed Aug 15, 2024
1 parent 2030d23 commit 2cd0834
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 7 deletions.
13 changes: 7 additions & 6 deletions crmsh/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -1625,6 +1625,13 @@ def join_ssh_impl(local_user, seed_host, seed_user, ssh_public_keys: typing.List
raise ValueError(msg)
# After this, login to remote_node is passwordless
swap_public_ssh_key(seed_host, local_user, seed_user, local_user, seed_user, add=True)
ssh_shell = sh.SSHShell(local_shell, local_user)
if seed_user != 'root' and 0 != ssh_shell.subprocess_run_without_input(
seed_host, seed_user, 'sudo true',
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
).returncode:
raise ValueError(f'Failed to sudo on {seed_user}@{seed_host}')

user_by_host = utils.HostUserConfig()
user_by_host.clear()
Expand Down Expand Up @@ -1655,12 +1662,6 @@ def join_ssh_with_ssh_agent(
if not shell.can_run_as(seed_host, seed_user):
for key in ssh_public_keys:
authorized_key_manager.add(seed_host, seed_user, key)
if seed_user != 'root' and 0 != shell.subprocess_run_without_input(
seed_host, seed_user, 'sudo true',
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
).returncode:
raise ValueError(f'Failed to sudo on {seed_user}@{seed_host}')
for key in ssh_public_keys:
authorized_key_manager.add(None, local_user, key)

Expand Down
12 changes: 11 additions & 1 deletion test/unittests/test_bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -581,19 +581,24 @@ def test_join_ssh_no_seed_host(self, mock_error):
@mock.patch('crmsh.bootstrap.get_node_canonical_hostname')
@mock.patch('crmsh.bootstrap.swap_public_ssh_key_for_secondary_user')
@mock.patch('crmsh.bootstrap.change_user_shell')
@mock.patch('crmsh.sh.SSHShell')
@mock.patch('crmsh.bootstrap.swap_public_ssh_key')
@mock.patch('crmsh.utils.ssh_copy_id_no_raise')
@mock.patch('crmsh.bootstrap.configure_ssh_key')
@mock.patch('crmsh.service_manager.ServiceManager.start_service')
def test_join_ssh(
self,
mock_start_service, mock_config_ssh, mock_ssh_copy_id, mock_swap, mock_change, mock_swap_2,
mock_start_service, mock_config_ssh, mock_ssh_copy_id, mock_swap,
mock_ssh_shell,
mock_change, mock_swap_2,
mock_get_node_cononical_hostname,
mock_detect_cluster_service_on_node
):
bootstrap._context = mock.Mock(current_user="bob", default_nic="eth1", use_ssh_agent=False, stage=None)
mock_swap.return_value = None
mock_ssh_copy_id.return_value = 0
mock_subprocess_run_without_input = mock_ssh_shell.return_value.subprocess_run_without_input
mock_subprocess_run_without_input.return_value = mock.Mock(returncode=0)
mock_get_node_cononical_hostname.return_value='node1'

bootstrap.join_ssh("node1", "alice")
Expand All @@ -604,6 +609,11 @@ def test_join_ssh(
mock.call("hacluster"),
])
mock_ssh_copy_id.assert_called_once_with("bob", "alice", "node1")
mock_subprocess_run_without_input.assert_called_once_with(
'node1', 'alice', 'sudo true',
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
mock_swap.assert_called_once_with("node1", "bob", "alice", "bob", "alice", add=True)
mock_swap_2.assert_called_once()
args, kwargs = mock_swap_2.call_args
Expand Down

0 comments on commit 2cd0834

Please sign in to comment.