|
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,114 @@ 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 | + ) |
| 941 | + self.env_sync_vm.clone_properties(self.app.domains[self.template]) |
| 942 | + self.env_sync_vm.features.update( |
| 943 | + self.app.domains[self.template].features |
| 944 | + ) |
| 945 | + self.loop.run_until_complete( |
| 946 | + self.env_sync_vm.clone_disk_files(self.app.domains[self.template]) |
| 947 | + ) |
| 948 | + self.env_sync_vm.provides_network = True |
| 949 | + self.app.save() |
| 950 | + |
| 951 | + # Create a user environment generator and profile script that will |
| 952 | + # both modify the same environment variable |
| 953 | + self.loop.run_until_complete(self.env_sync_vm.start()) |
| 954 | + self.assertEqual(self.env_sync_vm.get_power_state(), "Running") |
| 955 | + self.loop.run_until_complete(self.wait_for_session(self.env_sync_vm)) |
| 956 | + |
| 957 | + try: |
| 958 | + self.loop.run_until_complete( |
| 959 | + self.env_sync_vm.run_for_stdio( |
| 960 | + "printf '%s\\n' " |
| 961 | + + "'#!/bin/bash' " |
| 962 | + + "'echo QUBES_ENV_TEST=first' " |
| 963 | + + "| sudo tee " |
| 964 | + + "/usr/lib/systemd/user-environment-generators/90-test" |
| 965 | + ) |
| 966 | + ) |
| 967 | + except subprocess.CalledProcessError: |
| 968 | + self.fail("cannot create user environment generator") |
| 969 | + |
| 970 | + try: |
| 971 | + self.loop.run_until_complete( |
| 972 | + self.env_sync_vm.run_for_stdio( |
| 973 | + "printf '%s\\n' " |
| 974 | + + "'#!/bin/bash' " |
| 975 | + + "'QUBES_ENV_TEST=\"${QUBES_ENV_TEST}:second\"' " |
| 976 | + + "'export QUBES_ENV_TEST' " |
| 977 | + + "| sudo tee /etc/profile.d/ztest.sh" |
| 978 | + ) |
| 979 | + ) |
| 980 | + except subprocess.CalledProcessError: |
| 981 | + self.fail("cannot create profile.d script") |
| 982 | + |
| 983 | + try: |
| 984 | + self.loop.run_until_complete( |
| 985 | + self.env_sync_vm.run_for_stdio( |
| 986 | + "sudo chmod +x " |
| 987 | + + "/usr/lib/systemd/user-environment-generators/90-test " |
| 988 | + + "/etc/profile.d/ztest.sh" |
| 989 | + ) |
| 990 | + ) |
| 991 | + except subprocess.CalledProcessError: |
| 992 | + self.fail("cannot mark scripts executable") |
| 993 | + |
| 994 | + self.loop.run_until_complete(self.env_sync_vm.shutdown(wait=True)) |
| 995 | + self.assertEqual(self.env_sync_vm.get_power_state(), "Halted") |
| 996 | + |
| 997 | + # Get the value of QUBES_ENV_TEST from a user session and ensure it is |
| 998 | + # equal to 'first:second', indicating that the environment has been |
| 999 | + # synced from systemd into the session |
| 1000 | + self.loop.run_until_complete(self.env_sync_vm.start()) |
| 1001 | + self.assertEqual(self.env_sync_vm.get_power_state(), "Running") |
| 1002 | + self.loop.run_until_complete(self.wait_for_session(self.env_sync_vm)) |
| 1003 | + |
| 1004 | + try: |
| 1005 | + stdout, _ = self.loop.run_until_complete( |
| 1006 | + self.env_sync_vm.run_for_stdio( |
| 1007 | + 'printf "%s\\n" "$QUBES_ENV_TEST"' |
| 1008 | + ) |
| 1009 | + ) |
| 1010 | + except subprocess.CalledProcessError as e: |
| 1011 | + self.fail( |
| 1012 | + "could not get value of QUBES_ENV_TEST variable: {}".format( |
| 1013 | + e.stderr |
| 1014 | + ) |
| 1015 | + ) |
| 1016 | + if stdout != "first:second": |
| 1017 | + self.fail( |
| 1018 | + "unexpected QUBES_ENV_TEST value from session, " |
| 1019 | + + "got '{}', expected 'first:second'".format(stdout) |
| 1020 | + ) |
| 1021 | + |
| 1022 | + ## Make sure the systemd user manager has the variable set properly too |
| 1023 | + try: |
| 1024 | + stdout, _ = self.loop.run_until_complete( |
| 1025 | + self.env_sync_vm.run_for_stdio( |
| 1026 | + "systemctl --user show-environment " |
| 1027 | + + "| grep '^QUBES_ENV_TEST=' " |
| 1028 | + + "| cut -d'=' -f2" |
| 1029 | + ) |
| 1030 | + ) |
| 1031 | + except subprocess.CalledProcessError as e: |
| 1032 | + self.fail( |
| 1033 | + "could not get value of QUBES_ENV_TEST from systemd user " |
| 1034 | + + "manager: {}".format(e.stderr) |
| 1035 | + ) |
| 1036 | + if stdout != "first:second": |
| 1037 | + self.fail( |
| 1038 | + "unexpected QUBES_ENV_TEST value from systemd user manager, " |
| 1039 | + + "got '{}', expected 'first:second'".format(stdout) |
| 1040 | + ) |
| 1041 | + |
933 | 1042 |
|
934 | 1043 | class TC_10_Generic(qubes.tests.SystemTestCase): |
935 | 1044 | def setUp(self): |
|
0 commit comments