Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions qubes/device_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,14 @@
from typing import TYPE_CHECKING

import qubes.utils
from qubes.exc import ProtocolError, QubesValueError
from qubes.exc import ProtocolError, QubesValueError, UnexpectedDeviceProperty

if TYPE_CHECKING:
from qubes.vm.qubesvm import QubesVM
else:
QubesVM = "qubes.vm.qubesvm.QubesVM"


class UnexpectedDeviceProperty(qubes.exc.QubesException, ValueError):
"""
Device has unexpected property such as backend_domain, devclass etc.
"""


def qbool(value):
return qubes.property.bool(None, None, value)

Expand Down
31 changes: 6 additions & 25 deletions qubes/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,31 +71,12 @@
VirtualDevice,
AssignmentMode,
)
from qubes.exc import ProtocolError


class DeviceNotAssigned(qubes.exc.QubesException, KeyError):
"""
Trying to unassign not assigned device.
"""


class DeviceAlreadyAttached(qubes.exc.QubesException, KeyError):
"""
Trying to attach already attached device.
"""


class DeviceAlreadyAssigned(qubes.exc.QubesException, KeyError):
"""
Trying to assign already assigned device.
"""


class UnrecognizedDevice(qubes.exc.QubesException, ValueError):
"""
Device identity is not as expected.
"""
from qubes.exc import (
ProtocolError,
DeviceNotAssigned,
DeviceAlreadyAttached,
DeviceAlreadyAssigned,
)


class DeviceCollection:
Expand Down
34 changes: 34 additions & 0 deletions qubes/exc.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,3 +269,37 @@ class ProtocolError(AssertionError):

class PermissionDenied(Exception):
"""Raised deliberately by handlers when we decide not to cooperate"""


class DeviceNotAssigned(QubesException, KeyError):
"""
Trying to unassign not assigned device.
"""


class DeviceAlreadyAttached(QubesException, KeyError):
"""
Trying to attach already attached device.
"""


class DeviceAlreadyAssigned(QubesException, KeyError):
"""
Trying to assign already assigned device.
"""


class UnrecognizedDevice(QubesException, ValueError):
"""
Device identity is not as expected.
"""


class UnexpectedDeviceProperty(QubesException, ValueError):
"""
Device has unexpected property such as backend_domain, devclass etc.
"""


class StoragePoolException(QubesException):
"""A general storage exception"""
5 changes: 3 additions & 2 deletions qubes/ext/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

import qubes.device_protocol
import qubes.devices
import qubes.exc
import qubes.ext
from qubes.ext import utils
from qubes.storage import Storage
Expand Down Expand Up @@ -514,7 +515,7 @@ def pre_attachment_internal(
"not available, skipping.",
file=sys.stderr,
)
raise qubes.devices.UnrecognizedDevice()
raise qubes.exc.UnrecognizedDevice()

# validate options
for option, value in options.items():
Expand Down Expand Up @@ -561,7 +562,7 @@ def pre_attachment_internal(
return

if device.attachment and device.attachment != expected_attachment:
raise qubes.devices.DeviceAlreadyAttached(
raise qubes.exc.DeviceAlreadyAttached(
"Device {!s} already attached to {!s}".format(
device, device.attachment
)
Expand Down
5 changes: 1 addition & 4 deletions qubes/storage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import qubes
import qubes.exc
import qubes.utils
from qubes.exc import StoragePoolException

STORAGE_ENTRY_POINT = "qubes.storage"
_am_root = os.getuid() == 0
Expand All @@ -46,10 +47,6 @@
_big_buffer = b"\0" * BYTES_TO_ZERO


class StoragePoolException(qubes.exc.QubesException):
"""A general storage exception"""


class BlockDevice:
"""Represents a storage block device."""

Expand Down
16 changes: 9 additions & 7 deletions qubes/storage/callback.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@
import asyncio
import locale
from shlex import quote

import qubes.exc
from qubes.utils import coro_maybe

import qubes.storage


class UnhandledSignalException(qubes.storage.StoragePoolException):
class UnhandledSignalException(qubes.exc.StoragePoolException):
def __init__(self, pool, signal):
super().__init__(
"The pool %s failed to handle the signal %s, likely because it was run from synchronous code."
Expand Down Expand Up @@ -204,7 +206,7 @@ def __init__(self, *, name, conf_id):
"qubes.storage.callback"
) #: Logger instance.
if not isinstance(conf_id, str):
raise qubes.storage.StoragePoolException(
raise qubes.exc.StoragePoolException(
"conf_id is no String. VM attack?!"
)
self._cb_conf_id = (
Expand All @@ -215,7 +217,7 @@ def __init__(self, *, name, conf_id):
with open(config_path, encoding="utf-8") as json_file:
conf_all = json.load(json_file)
if not isinstance(conf_all, dict):
raise qubes.storage.StoragePoolException(
raise qubes.exc.StoragePoolException(
"The file %s is supposed to define a dict." % config_path
)

Expand All @@ -225,15 +227,15 @@ def __init__(self, *, name, conf_id):
] #: Dictionary holding all configuration for the given _cb_conf_id.
except KeyError:
# we cannot throw KeyErrors as we'll otherwise generate incorrect error messages @qubes.app._get_pool()
raise qubes.storage.StoragePoolException(
raise qubes.exc.StoragePoolException(
"The specified conf_id %s could not be found inside %s."
% (self._cb_conf_id, config_path)
)

try:
bdriver = self._cb_conf["bdriver"]
except KeyError:
raise qubes.storage.StoragePoolException(
raise qubes.exc.StoragePoolException(
"Missing bdriver for the conf_id %s inside %s."
% (self._cb_conf_id, config_path)
)
Expand All @@ -247,12 +249,12 @@ def __init__(self, *, name, conf_id):
qubes.storage.STORAGE_ENTRY_POINT, bdriver
)
except KeyError:
raise qubes.storage.StoragePoolException(
raise qubes.exc.StoragePoolException(
"The driver %s was not found on your system." % bdriver
)

if not issubclass(cls, qubes.storage.Pool):
raise qubes.storage.StoragePoolException(
raise qubes.exc.StoragePoolException(
"The class %s must be a subclass of qubes.storage.Pool." % cls
)

Expand Down
21 changes: 11 additions & 10 deletions qubes/storage/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import subprocess
from contextlib import suppress

import qubes.exc
import qubes.storage
import qubes.utils

Expand Down Expand Up @@ -350,7 +351,7 @@ def resize(self, size): # pylint: disable=invalid-overridden-method
"""
if not self.rw:
msg = "Can not resize readonly volume {!s}".format(self)
raise qubes.storage.StoragePoolException(msg)
raise qubes.exc.StoragePoolException(msg)

if self.snap_on_start:
# this theoretically could be supported, but it's unusual
Expand All @@ -359,10 +360,10 @@ def resize(self, size): # pylint: disable=invalid-overridden-method
"Cannot resize volume based on a template - resize"
"the template instead"
)
raise qubes.storage.StoragePoolException(msg)
raise qubes.exc.StoragePoolException(msg)

if size < self.size:
raise qubes.storage.StoragePoolException(
raise qubes.exc.StoragePoolException(
"For your own safety, shrinking of %s is"
" disabled. If you really know what you"
" are doing, use `truncate` on %s manually."
Expand Down Expand Up @@ -407,11 +408,11 @@ def export(self): # pylint: disable=invalid-overridden-method
assert (
self._export_lock is FileVolume._marker_running
), "nested calls to export()"
raise qubes.storage.StoragePoolException(
raise qubes.exc.StoragePoolException(
"file pool cannot export running volumes"
)
if self.is_dirty():
raise qubes.storage.StoragePoolException(
raise qubes.exc.StoragePoolException(
"file pool cannot export dirty volumes"
)
self._export_lock = FileVolume._marker_exported
Expand All @@ -425,7 +426,7 @@ async def export_end(self, path):

async def import_volume(self, src_volume):
if src_volume.snap_on_start:
raise qubes.storage.StoragePoolException(
raise qubes.exc.StoragePoolException(
"Can not import snapshot volume {!s} in to pool {!s} ".format(
src_volume, self
)
Expand All @@ -441,7 +442,7 @@ async def import_volume(self, src_volume):

def import_data(self, size): # pylint: disable=invalid-overridden-method
if not self.save_on_stop:
raise qubes.storage.StoragePoolException(
raise qubes.exc.StoragePoolException(
"Can not import into save_on_stop=False volume {!s}".format(
self
)
Expand Down Expand Up @@ -476,7 +477,7 @@ async def start(self):
assert (
self._export_lock is FileVolume._marker_exported
), "nested calls to start()"
raise qubes.storage.StoragePoolException(
raise qubes.exc.StoragePoolException(
"file pool cannot start a VM with an exported volume"
)
self._export_lock = FileVolume._marker_running
Expand Down Expand Up @@ -559,7 +560,7 @@ def verify(self): # pylint: disable=invalid-overridden-method
self.snap_on_start or self.save_on_stop
):
msg = "Missing image file: {!s}.".format(self.path)
raise qubes.storage.StoragePoolException(msg)
raise qubes.exc.StoragePoolException(msg)
return True

@property
Expand Down Expand Up @@ -722,4 +723,4 @@ def _check_path(path):
"""Raise an StoragePoolException if ``path`` does not exist"""
if not os.path.exists(path):
msg = "Missing image file: %s" % path
raise qubes.storage.StoragePoolException(msg)
raise qubes.exc.StoragePoolException(msg)
3 changes: 2 additions & 1 deletion qubes/storage/kernels.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@

import qubes.exc
import qubes.storage
from qubes.storage import Pool, StoragePoolException, Volume
from qubes.storage import Pool, Volume
from qubes.exc import StoragePoolException


class LinuxModules(Volume):
Expand Down
Loading