diff --git a/qubes/app.py b/qubes/app.py index 2a00355b7..1ae5745ab 100644 --- a/qubes/app.py +++ b/qubes/app.py @@ -674,6 +674,27 @@ def _setter_default_netvm(app, prop, value): return value +def _validate_kernel(obj, name, kernel): + if not kernel: + return + dirname = os.path.join( + qubes.config.qubes_base_dir, + qubes.config.system_path['qubes_kernels_base_dir'], + kernel) + if not os.path.exists(dirname): + raise qubes.exc.QubesPropertyValueError( + obj, name, kernel, + 'Kernel {!r} not installed'.format( + kernel)) + for filename in ('vmlinuz',): + if not os.path.exists(os.path.join(dirname, filename)): + raise qubes.exc.QubesPropertyValueError( + obj, name, kernel, + 'Kernel {!r} not properly installed: ' + 'missing {!r} file'.format( + kernel, filename)) + + class Qubes(qubes.PropertyHolder): """Main Qubes application @@ -1593,3 +1614,10 @@ def on_property_set_default_dispvm(self, event, name, newvalue, # resetting dispvm to its default value vm.fire_event('property-reset:default_dispvm', name='default_dispvm', oldvalue=oldvalue) + + @qubes.events.handler('property-pre-set:default_kernel') + # pylint: disable-next=invalid-name + def on_property_pre_set_default_kernel(self, event, name, newvalue, + oldvalue=None): + # pylint: disable=unused-argument + _validate_kernel(self, 'default_kernel', newvalue) diff --git a/qubes/tests/api_admin.py b/qubes/tests/api_admin.py index ed0a04156..d0335042d 100644 --- a/qubes/tests/api_admin.py +++ b/qubes/tests/api_admin.py @@ -61,6 +61,9 @@ def setUp(self): self.base_dir_patch.start() self.base_dir_patch2.start() self.base_dir_patch3.start() + kernel_dir = '/tmp/qubes-test-dir/vm-kernels/1.0' + os.makedirs(kernel_dir, exist_ok=True) + open(os.path.join(kernel_dir, 'vmlinuz'), 'w').close() app = qubes.Qubes('/tmp/qubes-test.xml', load=False) app.vmm = unittest.mock.Mock(spec=qubes.app.VMMConnection) app.load_initial_values() diff --git a/run-tests b/run-tests index b0928686b..846b134e3 100755 --- a/run-tests +++ b/run-tests @@ -19,6 +19,13 @@ if sudo --non-interactive "$name/ci/lvm-manage" setup-lvm vg$$/pool; then CLEANUP_LVM=yes fi +CLEANUP_KERNEL_POOL= +if [ ! -d "/var/lib/qubes/vm-kernels" ]; then + sudo mkdir --parents /var/lib/qubes/vm-kernels/dummy + sudo touch /var/lib/qubes/vm-kernels/dummy/vmlinuz + CLEANUP_KERNEL_POOL=yes +fi + : "${PYTHON:=python3}" : "${TESTPYTHONPATH:=test-packages}" @@ -32,6 +39,10 @@ export PYTHONPATH "${PYTHON}" setup.py egg_info --egg-base "${TESTPYTHONPATH}" "${PYTHON}" -m coverage run --rcfile=ci/coveragerc -m qubes.tests.run "$@" retcode=$? +if [ -n "$CLEANUP_KERNEL_POOL" ]; then + sudo rm /var/lib/qubes/vm-kernels/dummy/vmlinuz + sudo rmdir /var/lib/qubes/vm-kernels/dummy +fi if [ -n "$CLEANUP_LVM" ]; then sudo --non-interactive $(dirname "$0")/ci/lvm-manage cleanup-lvm "$DEFAULT_LVM_POOL" fi