Skip to content

Commit

Permalink
cc_ssh_import_id: add Alpine support and add doas support (#4277)
Browse files Browse the repository at this point in the history
Add Alpine to distros supported by this module.

If sudo is not available then try and use doas as an alternative
if it is available.
  • Loading branch information
dermotbradley authored Aug 1, 2023
1 parent 7cbe0f6 commit 9fdc7a9
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 8 deletions.
27 changes: 19 additions & 8 deletions cloudinit/config/cc_ssh_import_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from cloudinit.settings import PER_INSTANCE

# https://launchpad.net/ssh-import-id
distros = ["ubuntu", "debian", "cos"]
distros = ["alpine", "cos", "debian", "ubuntu"]

SSH_IMPORT_ID_BINARY = "ssh-import-id"
MODULE_DESCRIPTION = """\
Expand Down Expand Up @@ -152,13 +152,24 @@ def import_ssh_ids(ids, user):
# I'm including the `--preserve-env` here as a one-off, but we should
# have a better way of setting env earlier in boot and using it later.
# Perhaps a 'set_env' module?
cmd = [
"sudo",
"--preserve-env=https_proxy",
"-Hu",
user,
SSH_IMPORT_ID_BINARY,
] + ids
if subp.which("sudo"):
cmd = [
"sudo",
"--preserve-env=https_proxy",
"-Hu",
user,
SSH_IMPORT_ID_BINARY,
] + ids
elif subp.which("doas"):
cmd = [
"doas",
"-u",
user,
SSH_IMPORT_ID_BINARY,
] + ids
else:
LOG.error("Neither sudo nor doas available! Unable to import SSH ids.")
return
LOG.debug("Importing SSH ids for user %s.", user)

try:
Expand Down
49 changes: 49 additions & 0 deletions tests/unittests/config/test_cc_ssh_import_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,52 @@ def test_skip_inapplicable_configs(self, m_which, cfg, log, caplog):
cloud = get_cloud("ubuntu")
cc_ssh_import_id.handle("name", cfg, cloud, [])
assert log in caplog.text

@mock.patch("cloudinit.ssh_util.pwd.getpwnam")
@mock.patch("cloudinit.config.cc_ssh_import_id.subp.subp")
@mock.patch("cloudinit.subp.which")
def test_use_sudo(self, m_which, m_subp, m_getpwnam):
"""Check that sudo is available and use that"""
m_which.return_value = "/usr/bin/ssh-import-id"
ids = ["waffle"]
user = "bob"
cc_ssh_import_id.import_ssh_ids(ids, user)
m_subp.assert_called_once_with(
[
"sudo",
"--preserve-env=https_proxy",
"-Hu",
user,
"ssh-import-id",
]
+ ids,
capture=False,
)

@mock.patch("cloudinit.ssh_util.pwd.getpwnam")
@mock.patch("cloudinit.config.cc_ssh_import_id.subp.subp")
@mock.patch("cloudinit.subp.which")
def test_use_doas(self, m_which, m_subp, m_getpwnam):
"""Check that doas is available and use that"""
m_which.side_effect = [None, "/usr/bin/doas"]
ids = ["waffle"]
user = "bob"
cc_ssh_import_id.import_ssh_ids(ids, user)
m_subp.assert_called_once_with(
["doas", "-u", user, "ssh-import-id"] + ids, capture=False
)

@mock.patch("cloudinit.ssh_util.pwd.getpwnam")
@mock.patch("cloudinit.config.cc_ssh_import_id.subp.subp")
@mock.patch("cloudinit.subp.which")
def test_use_neither_sudo_nor_doas(
self, m_which, m_subp, m_getpwnam, caplog
):
"""Test when neither sudo nor doas is available"""
m_which.return_value = None
ids = ["waffle"]
user = "bob"
cc_ssh_import_id.import_ssh_ids(ids, user)
assert (
"Neither sudo nor doas available! Unable to import SSH ids"
) in caplog.text

0 comments on commit 9fdc7a9

Please sign in to comment.