diff --git a/sos/collector/transports/juju.py b/sos/collector/transports/juju.py index bea95fb6f9..13dab704fc 100644 --- a/sos/collector/transports/juju.py +++ b/sos/collector/transports/juju.py @@ -13,7 +13,7 @@ from sos.collector.exceptions import JujuNotInstalledException from sos.collector.transports import RemoteTransport -from sos.utilities import sos_get_command_output +from sos.utilities import sos_get_command_output, parse_version class JujuSSH(RemoteTransport): @@ -72,12 +72,29 @@ def remote_exec(self): option = f"{model_option} {target_option}" return f"juju ssh {option}" + def _get_juju_version(self): + """Grab the version of juju""" + res = sos_get_command_output("juju version") + return res['output'].split("-")[0] + def _retrieve_file(self, fname, dest): self._chmod(fname) # juju scp needs the archive to be world-readable model, unit = self.address.split(":") model_option = f"-m {model}" if model else "" - cmd = f"juju scp {model_option} -- -r {unit}:{fname} {dest}" - res = sos_get_command_output(cmd) + if parse_version(self._get_juju_version()) > parse_version("3"): + # juju version above 3 is strictly confined, and therefore + # the way we grab the data is slightly different + juju_tmpdir = f"/tmp/snap-private-tmp/snap.juju/{self.tmpdir}" + sos_get_command_output(f"sudo mkdir {juju_tmpdir}") + sos_get_command_output(f"sudo chmod o+rwx {juju_tmpdir}") + cmd = f"juju scp {model_option} -- -r {unit}:{fname} {self.tmpdir}" + res = sos_get_command_output(cmd) + cmd2 = f"sudo cp {juju_tmpdir}/{fname.split('/')[-1]} {dest}" + sos_get_command_output(cmd2) + sos_get_command_output(f"sudo chmod 644 {dest}") + else: + cmd = f"juju scp {model_option} -- -r {unit}:{fname} {dest}" + res = sos_get_command_output(cmd) return res["status"] == 0 diff --git a/tests/unittests/juju/juju_transports_test.py b/tests/unittests/juju/juju_transports_test.py index 911a957e43..b600b16259 100644 --- a/tests/unittests/juju/juju_transports_test.py +++ b/tests/unittests/juju/juju_transports_test.py @@ -33,6 +33,9 @@ def setUp(self): address="model_abc:unit_abc", ) + def get_juju_version(): + return "2.9.45" + @patch("sos.collector.transports.juju.subprocess.check_output") def test_check_juju_installed_err(self, mock_subprocess_check_output): """Raise error if juju is not installed.""" @@ -70,12 +73,16 @@ def test_remote_exec(self): self.juju_ssh.remote_exec == "juju ssh -m model_abc unit_abc" ) + @patch( + "sos.collector.transports.juju.JujuSSH._get_juju_version", + side_effect=get_juju_version, + ) @patch( "sos.collector.transports.juju.sos_get_command_output", return_value={"status": 0}, ) @patch("sos.collector.transports.juju.JujuSSH._chmod", return_value=True) - def test_retrieve_file(self, mock_chmod, mock_sos_get_cmd_output): + def test_retrieve_file(self, mock_chmod, mock_sos_get_cmd_output, mock_get_juju_version): self.juju_ssh._retrieve_file(fname="file_abc", dest="/tmp/sos-juju/") mock_sos_get_cmd_output.assert_called_with( "juju scp -m model_abc -- -r unit_abc:file_abc /tmp/sos-juju/"