diff --git a/subiquity/client/client.py b/subiquity/client/client.py index 2dde8384..255c3735 100644 --- a/subiquity/client/client.py +++ b/subiquity/client/client.py @@ -31,6 +31,7 @@ from subiquitycore.async_helpers import ( from subiquitycore.screen import is_linux_tty from subiquitycore.tuicontroller import Skip from subiquitycore.tui import TuiApplication +from subiquitycore.utils import orig_environ from subiquitycore.view import BaseView from subiquity.client.controller import Confirm @@ -553,8 +554,10 @@ class SubiquityClient(TuiApplication): os.system("clear") print(DEBUG_SHELL_INTRO) + env = orig_environ(os.environ) + cmd = ["bash"] self.run_command_in_foreground( - ["bash"], before_hook=_before, after_hook=after_hook, cwd='/') + cmd, env=env, before_hook=_before, after_hook=after_hook, cwd='/') def note_file_for_apport(self, key, path): self.error_reporter.note_file_for_apport(key, path) diff --git a/subiquitycore/tests/test_utils.py b/subiquitycore/tests/test_utils.py new file mode 100644 index 00000000..b31da9fd --- /dev/null +++ b/subiquitycore/tests/test_utils.py @@ -0,0 +1,64 @@ +# Copyright 2022 Canonical, Ltd. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +# from unittest.mock import Mock + +from subiquitycore.tests import SubiTestCase +from subiquitycore.utils import orig_environ + + +class TestOrigEnviron(SubiTestCase): + def test_empty(self): + env = {} + expected = env + self.assertEqual(expected, orig_environ(env)) + + def test_orig_path(self): + env = {'PATH': 'a', 'PATH_ORIG': 'b'} + expected = {'PATH': 'b'} + self.assertEqual(expected, orig_environ(env)) + + def test_not_this_key(self): + env = {'PATH': 'a', 'PATH_ORIG_AAAAA': 'b'} + expected = env + self.assertEqual(expected, orig_environ(env)) + + def test_remove_empty_key(self): + env = {'STUFF': 'a', 'STUFF_ORIG': ''} + expected = {} + self.assertEqual(expected, orig_environ(env)) + + def test_practical(self): + snap = '/snap/subiquity/1234' + env = { + 'TERM': 'linux', + 'PYTHONIOENCODING_ORIG': '', + 'PYTHONIOENCODING': 'utf-8', + 'SUBIQUITY_ROOT_ORIG': '', + 'SUBIQUITY_ROOT': snap, + 'PYTHON_ORIG': '', + 'PYTHON': f'{snap}/usr/bin/python3.8', + 'PYTHONPATH_ORIG': '', + 'PYTHONPATH': f'{snap}/stuff/things', + 'PY3OR2_PYTHON_ORIG': '', + 'PY3OR2_PYTHON': f'{snap}/usr/bin/python3.8', + 'PATH_ORIG': '/usr/bin:/bin', + 'PATH': '/usr/bin:/bin:/snap/bin' + } + expected = { + 'TERM': 'linux', + 'PATH': '/usr/bin:/bin', + } + self.assertEqual(expected, orig_environ(env)) diff --git a/subiquitycore/utils.py b/subiquitycore/utils.py index 741fc9bc..9535d652 100644 --- a/subiquitycore/utils.py +++ b/subiquitycore/utils.py @@ -35,6 +35,21 @@ def _clean_env(env): return env +def orig_environ(env): + if env is None: + env = os.environ + ret = env.copy() + for key, val in env.items(): + if key.endswith('_ORIG'): + key_to_restore = key[:-len('_ORIG')] + if val: + ret[key_to_restore] = val + else: + del ret[key_to_restore] + del ret[key] + return ret + + def run_command(cmd: Sequence[str], *, input=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8', errors='replace', env=None, **kw) -> subprocess.CompletedProcess: