|
32 | 32 | import qubes.tests |
33 | 33 | import qubes.vm.appvm |
34 | 34 | import qubes.vm.templatevm |
| 35 | +import qubes.vm.standalonevm |
35 | 36 |
|
36 | 37 | in_qemu = os.path.exists("/sys/firmware/qemu_fw_cfg") |
37 | 38 |
|
@@ -930,6 +931,100 @@ async def _test_400_long_window_title(self, utf8=False): |
930 | 931 | except ProcessLookupError: # already dead |
931 | 932 | pass |
932 | 933 |
|
| 934 | + def test_500_gui_agent_env_sync(self): |
| 935 | + # Create a StandaloneVM so changes made to it will survive a reboot |
| 936 | + self.env_sync_vm = self.app.add_new_vm( |
| 937 | + qubes.vm.standalonevm.StandaloneVM, |
| 938 | + label="red", |
| 939 | + name=self.make_vm_name("envsync"), |
| 940 | + template=self.app.domains[self.template], |
| 941 | + ) |
| 942 | + self.loop.run_until_complete(self.env_sync_vm.create_on_disk()) |
| 943 | + self.env_sync_vm.provides_network = True |
| 944 | + self.app.save() |
| 945 | + |
| 946 | + # Create a user environment generator and profile script that will |
| 947 | + # both modify the same environment variable |
| 948 | + self.loop.run_until_complete(self.env_sync_vm.start()) |
| 949 | + self.assertEqual(self.env_sync_vm.get_power_state(), "Running") |
| 950 | + self.loop.run_until_complete(self.wait_for_session(self.env_sync_vm)) |
| 951 | + |
| 952 | + try: |
| 953 | + self.loop.run_until_complete( |
| 954 | + self.env_sync_vm.run_for_stdio( |
| 955 | + "printf '%s\\n' " |
| 956 | + + "'#!/bin/bash' " |
| 957 | + + "'QUBES_ENV_TEST=first' " |
| 958 | + + "'export QUBES_ENV_TEST' " |
| 959 | + + "| sudo tee " |
| 960 | + + "/usr/lib/systemd/user-environment-generators/90-test" |
| 961 | + ) |
| 962 | + ) |
| 963 | + except subprocess.CalledProcessError: |
| 964 | + self.fail("cannot create user environment generator") |
| 965 | + |
| 966 | + try: |
| 967 | + self.loop.run_until_complete( |
| 968 | + self.env_sync_vm.run_for_stdio( |
| 969 | + "printf '%s\\n' " |
| 970 | + + "'#!/bin/bash' " |
| 971 | + + "'QUBES_ENV_TEST=\"${QUBES_ENV_TEST}:second\"' " |
| 972 | + + "'export QUBES_ENV_TEST' " |
| 973 | + + "| sudo tee /etc/profile.d/ztest.sh" |
| 974 | + ) |
| 975 | + ) |
| 976 | + except subprocess.CalledProcessError: |
| 977 | + self.fail("cannot create profile.d script") |
| 978 | + |
| 979 | + try: |
| 980 | + self.loop.run_until_complete( |
| 981 | + self.env_sync_vm.run_for_stdio( |
| 982 | + "sudo chmod +x " |
| 983 | + + "/usr/lib/systemd/user-environment-generators/90-test " |
| 984 | + + "/etc/profile.d/ztest.sh" |
| 985 | + ) |
| 986 | + ) |
| 987 | + except subprocess.CalledProcessError: |
| 988 | + self.fail("cannot mark scripts executable") |
| 989 | + |
| 990 | + self.loop.run_until_complete(self.env_sync_vm.shutdown(wait=True)) |
| 991 | + self.assertEqual(self.env_sync_vm.get_power_state(), "Halted") |
| 992 | + |
| 993 | + # Get the value of QUBES_ENV_TEST from a user session and ensure it is |
| 994 | + # equal to 'first:second', indicating that the environment has been |
| 995 | + # synced from systemd into the session |
| 996 | + self.loop.run_until_complete(self.env_sync_vm.start()) |
| 997 | + self.assertEqual(self.env_sync_vm.get_power_state(), "Running") |
| 998 | + self.loop.run_until_complete(self.wait_for_session(self.env_sync_vm)) |
| 999 | + |
| 1000 | + try: |
| 1001 | + self.loop.run_until_complete( |
| 1002 | + self.env_sync_vm.run_for_stdio( |
| 1003 | + "test \"$(printf '%s\\n' \"$QUBES_ENV_TEST\")\" " |
| 1004 | + + "= 'first:second'" |
| 1005 | + ) |
| 1006 | + ) |
| 1007 | + except subprocess.CalledProcessError as e: |
| 1008 | + self.fail( |
| 1009 | + "environment was not synced to session properly, expected " |
| 1010 | + + "value 'first:second', got value: {}".format(e.stderr) |
| 1011 | + ) |
| 1012 | + |
| 1013 | + ## Make sure the systemd user manager has the variable set properly too |
| 1014 | + try: |
| 1015 | + self.loop.run_until_complete( |
| 1016 | + self.env_sync_vm.run_for_stdio( |
| 1017 | + "test \"$(systemctl --user show-environment " |
| 1018 | + + "| grep '^QUBES_ENV_TEST=' " |
| 1019 | + + "| cut -d'=' -f2)\" = 'first:second'" |
| 1020 | + ) |
| 1021 | + ) |
| 1022 | + except subprocess.CalledProcessError as e: |
| 1023 | + self.fail( |
| 1024 | + "environment was not synced to systemd properly, expected " |
| 1025 | + + "value 'first:second', got value: {}".format(e.stderr) |
| 1026 | + ) |
| 1027 | + |
933 | 1028 |
|
934 | 1029 | class TC_10_Generic(qubes.tests.SystemTestCase): |
935 | 1030 | def setUp(self): |
|
0 commit comments