Add udisks2 dbus support (#3848)

* Add udisks2 dbus support

* assert mountpoints

* Comment

* Add reference links

* docstring

* fix type

* fix type

* add typing extensions as import

* isort

* additional changes

* Simplify classes and conversions, fix bugs

* More simplification

* Fix imports

* fix pip

* Add additional properties and fix requirements

* fix tests maybe

* Handle optionality of certain configuration details

* black

* connect to devices before returning them

* Refactor for latest dbus work

* Not .items

* fix mountpoints logic

* use variants

* Use variants for options too

* isort

* Switch to dbus fast

* Move import to parent

* Add some fixture data

* Add another fixture and reduce the block devices list

* Implement changes discussed with mike

* Add property fixtures

* update object path

* Fix get_block_devices call

* Tests and refactor to minimize dbus reconnects

* Call super init in DBusInterfaceProxy

* Fix permissions on introspection files

---------

Co-authored-by: Mike Degatano <michael.degatano@gmail.com>
This commit is contained in:
Raman Gupta 2023-02-15 02:17:29 -05:00 committed by GitHub
parent 8ffd227849
commit 4c2d729646
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
87 changed files with 3914 additions and 74 deletions

View File

@ -23,3 +23,4 @@ securetar==2022.2.0
sentry-sdk==1.15.0
voluptuous==0.13.1
dbus-fast==1.84.1
typing_extensions==4.3.0

View File

@ -13,3 +13,4 @@ pytest-timeout==2.1.0
pytest==7.2.1
pyupgrade==3.3.1
time-machine==2.9.0
typing_extensions==4.3.0

View File

@ -9,33 +9,44 @@ CONTENT_TYPE_URL = "application/x-www-form-urlencoded"
COOKIE_INGRESS = "ingress_session"
ATTR_APPARMOR_VERSION = "apparmor_version"
ATTR_AGENT_VERSION = "agent_version"
ATTR_APPARMOR_VERSION = "apparmor_version"
ATTR_ATTRIBUTES = "attributes"
ATTR_AVAILABLE_UPDATES = "available_updates"
ATTR_BOOT_TIMESTAMP = "boot_timestamp"
ATTR_BOOTS = "boots"
ATTR_BROADCAST_LLMNR = "broadcast_llmnr"
ATTR_BROADCAST_MDNS = "broadcast_mdns"
ATTR_BY_ID = "by_id"
ATTR_CHILDREN = "children"
ATTR_CONNECTION_BUS = "connection_bus"
ATTR_DATA_DISK = "data_disk"
ATTR_DEVICE = "device"
ATTR_DEV_PATH = "dev_path"
ATTR_DISK_LED = "disk_led"
ATTR_DRIVES = "drives"
ATTR_DT_SYNCHRONIZED = "dt_synchronized"
ATTR_DT_UTC = "dt_utc"
ATTR_EJECTABLE = "ejectable"
ATTR_FALLBACK = "fallback"
ATTR_FILESYSTEMS = "filesystems"
ATTR_HEARTBEAT_LED = "heartbeat_led"
ATTR_IDENTIFIERS = "identifiers"
ATTR_LLMNR = "llmnr"
ATTR_LLMNR_HOSTNAME = "llmnr_hostname"
ATTR_MDNS = "mdns"
ATTR_MODEL = "model"
ATTR_MOUNT_POINTS = "mount_points"
ATTR_PANEL_PATH = "panel_path"
ATTR_POWER_LED = "power_led"
ATTR_REMOVABLE = "removable"
ATTR_REVISION = "revision"
ATTR_SEAT = "seat"
ATTR_SIGNED = "signed"
ATTR_STARTUP_TIME = "startup_time"
ATTR_UPDATE_TYPE = "update_type"
ATTR_USE_NTP = "use_ntp"
ATTR_BY_ID = "by_id"
ATTR_SUBSYSTEM = "subsystem"
ATTR_SYSFS = "sysfs"
ATTR_DEV_PATH = "dev_path"
ATTR_ATTRIBUTES = "attributes"
ATTR_CHILDREN = "children"
ATTR_TIME_DETECTED = "time_detected"
ATTR_UPDATE_TYPE = "update_type"
ATTR_USE_NTP = "use_ntp"
ATTR_VENDOR = "vendor"

View File

@ -4,16 +4,41 @@ from typing import Any
from aiohttp import web
from ..const import ATTR_AUDIO, ATTR_DEVICES, ATTR_INPUT, ATTR_NAME, ATTR_OUTPUT
from ..const import (
ATTR_AUDIO,
ATTR_DEVICES,
ATTR_ID,
ATTR_INPUT,
ATTR_NAME,
ATTR_OUTPUT,
ATTR_SERIAL,
ATTR_SIZE,
ATTR_SYSTEM,
)
from ..coresys import CoreSysAttributes
from ..dbus.udisks2 import UDisks2
from ..dbus.udisks2.block import UDisks2Block
from ..dbus.udisks2.drive import UDisks2Drive
from ..hardware.data import Device
from .const import (
ATTR_ATTRIBUTES,
ATTR_BY_ID,
ATTR_CHILDREN,
ATTR_CONNECTION_BUS,
ATTR_DEV_PATH,
ATTR_DEVICE,
ATTR_DRIVES,
ATTR_EJECTABLE,
ATTR_FILESYSTEMS,
ATTR_MODEL,
ATTR_MOUNT_POINTS,
ATTR_REMOVABLE,
ATTR_REVISION,
ATTR_SEAT,
ATTR_SUBSYSTEM,
ATTR_SYSFS,
ATTR_TIME_DETECTED,
ATTR_VENDOR,
)
from .utils import api_process
@ -21,7 +46,7 @@ _LOGGER: logging.Logger = logging.getLogger(__name__)
def device_struct(device: Device) -> dict[str, Any]:
"""Return a dict with information of a interface to be used in th API."""
"""Return a dict with information of a interface to be used in the API."""
return {
ATTR_NAME: device.name,
ATTR_SYSFS: device.sysfs,
@ -33,6 +58,42 @@ def device_struct(device: Device) -> dict[str, Any]:
}
def filesystem_struct(fs_block: UDisks2Block) -> dict[str, Any]:
"""Return a dict with information of a filesystem block device to be used in the API."""
return {
ATTR_DEVICE: str(fs_block.device),
ATTR_ID: fs_block.id,
ATTR_SIZE: fs_block.size,
ATTR_NAME: fs_block.id_label,
ATTR_SYSTEM: fs_block.hint_system,
ATTR_MOUNT_POINTS: [
str(mount_point) for mount_point in fs_block.filesystem.mount_points
],
}
def drive_struct(udisks2: UDisks2, drive: UDisks2Drive) -> dict[str, Any]:
"""Return a dict with information of a disk to be used in the API."""
return {
ATTR_VENDOR: drive.vendor,
ATTR_MODEL: drive.model,
ATTR_REVISION: drive.revision,
ATTR_SERIAL: drive.serial,
ATTR_ID: drive.id,
ATTR_SIZE: drive.size,
ATTR_TIME_DETECTED: drive.time_detected.isoformat(),
ATTR_CONNECTION_BUS: drive.connection_bus,
ATTR_SEAT: drive.seat,
ATTR_REMOVABLE: drive.removable,
ATTR_EJECTABLE: drive.ejectable,
ATTR_FILESYSTEMS: [
filesystem_struct(block)
for block in udisks2.block_devices
if block.filesystem and block.drive == drive.object_path
],
}
class APIHardware(CoreSysAttributes):
"""Handle RESTful API for hardware functions."""
@ -42,7 +103,11 @@ class APIHardware(CoreSysAttributes):
return {
ATTR_DEVICES: [
device_struct(device) for device in self.sys_hardware.devices
]
],
ATTR_DRIVES: [
drive_struct(self.sys_dbus.udisks2, drive)
for drive in self.sys_dbus.udisks2.drives
],
}
@api_process

View File

@ -35,7 +35,7 @@ class OSAgent(DBusInterfaceProxy):
def __init__(self) -> None:
"""Initialize Properties."""
self.properties: dict[str, Any] = {}
super().__init__()
self._apparmor: AppArmor = AppArmor()
self._board: BoardManager = BoardManager()

View File

@ -1,6 +1,5 @@
"""AppArmor object for OS-Agent."""
from pathlib import Path
from typing import Any
from awesomeversion import AwesomeVersion
@ -21,10 +20,6 @@ class AppArmor(DBusInterfaceProxy):
object_path: str = DBUS_OBJECT_HAOS_APPARMOR
properties_interface: str = DBUS_IFACE_HAOS_APPARMOR
def __init__(self) -> None:
"""Initialize Properties."""
self.properties: dict[str, Any] = {}
@property
@dbus_property
def version(self) -> AwesomeVersion:

View File

@ -1,6 +1,5 @@
"""Board management for OS Agent."""
import logging
from typing import Any
from dbus_fast.aio.message_bus import MessageBus
@ -30,8 +29,9 @@ class BoardManager(DBusInterfaceProxy):
def __init__(self) -> None:
"""Initialize properties."""
super().__init__()
self._board_proxy: BoardProxy | None = None
self.properties: dict[str, Any] = {}
@property
@dbus_property

View File

@ -1,7 +1,5 @@
"""Board dbus proxy interface."""
from typing import Any
from ...const import DBUS_IFACE_HAOS_BOARDS, DBUS_NAME_HAOS, DBUS_OBJECT_HAOS_BOARDS
from ...interface import DBusInterfaceProxy
@ -13,10 +11,11 @@ class BoardProxy(DBusInterfaceProxy):
def __init__(self, name: str) -> None:
"""Initialize properties."""
super().__init__()
self._name: str = name
self.object_path: str = f"{DBUS_OBJECT_HAOS_BOARDS}/{name}"
self.properties_interface: str = f"{DBUS_IFACE_HAOS_BOARDS}.{name}"
self.properties: dict[str, Any] = {}
@property
def name(self) -> str:

View File

@ -1,6 +1,5 @@
"""DataDisk object for OS-Agent."""
from pathlib import Path
from typing import Any
from ..const import (
DBUS_ATTR_CURRENT_DEVICE,
@ -19,10 +18,6 @@ class DataDisk(DBusInterfaceProxy):
object_path: str = DBUS_OBJECT_HAOS_DATADISK
properties_interface: str = DBUS_IFACE_HAOS_DATADISK
def __init__(self) -> None:
"""Initialize Properties."""
self.properties: dict[str, Any] = {}
@property
@dbus_property
def current_device(self) -> Path:

View File

@ -10,12 +10,16 @@ DBUS_NAME_RAUC = "de.pengutronix.rauc"
DBUS_NAME_RESOLVED = "org.freedesktop.resolve1"
DBUS_NAME_SYSTEMD = "org.freedesktop.systemd1"
DBUS_NAME_TIMEDATE = "org.freedesktop.timedate1"
DBUS_NAME_UDISKS2 = "org.freedesktop.UDisks2"
DBUS_IFACE_ACCESSPOINT = "org.freedesktop.NetworkManager.AccessPoint"
DBUS_IFACE_BLOCK = "org.freedesktop.UDisks2.Block"
DBUS_IFACE_CONNECTION_ACTIVE = "org.freedesktop.NetworkManager.Connection.Active"
DBUS_IFACE_DEVICE = "org.freedesktop.NetworkManager.Device"
DBUS_IFACE_DEVICE_WIRELESS = "org.freedesktop.NetworkManager.Device.Wireless"
DBUS_IFACE_DNS = "org.freedesktop.NetworkManager.DnsManager"
DBUS_IFACE_DRIVE = "org.freedesktop.UDisks2.Drive"
DBUS_IFACE_FILESYSTEM = "org.freedesktop.UDisks2.Filesystem"
DBUS_IFACE_HAOS = "io.hass.os"
DBUS_IFACE_HAOS_APPARMOR = "io.hass.os.AppArmor"
DBUS_IFACE_HAOS_BOARDS = "io.hass.os.Boards"
@ -26,11 +30,13 @@ DBUS_IFACE_HOSTNAME = "org.freedesktop.hostname1"
DBUS_IFACE_IP4CONFIG = "org.freedesktop.NetworkManager.IP4Config"
DBUS_IFACE_IP6CONFIG = "org.freedesktop.NetworkManager.IP6Config"
DBUS_IFACE_NM = "org.freedesktop.NetworkManager"
DBUS_IFACE_PARTITION_TABLE = "org.freedesktop.UDisks2.PartitionTable"
DBUS_IFACE_RAUC_INSTALLER = "de.pengutronix.rauc.Installer"
DBUS_IFACE_RESOLVED_MANAGER = "org.freedesktop.resolve1.Manager"
DBUS_IFACE_SETTINGS_CONNECTION = "org.freedesktop.NetworkManager.Settings.Connection"
DBUS_IFACE_SYSTEMD_MANAGER = "org.freedesktop.systemd1.Manager"
DBUS_IFACE_TIMEDATE = "org.freedesktop.timedate1"
DBUS_IFACE_UDISKS2_MANAGER = "org.freedesktop.UDisks2.Manager"
DBUS_SIGNAL_NM_CONNECTION_ACTIVE_CHANGED = (
"org.freedesktop.NetworkManager.Connection.Active.StateChanged"
@ -52,6 +58,7 @@ DBUS_OBJECT_RESOLVED = "/org/freedesktop/resolve1"
DBUS_OBJECT_SETTINGS = "/org/freedesktop/NetworkManager/Settings"
DBUS_OBJECT_SYSTEMD = "/org/freedesktop/systemd1"
DBUS_OBJECT_TIMEDATE = "/org/freedesktop/timedate1"
DBUS_OBJECT_UDISKS2 = "/org/freedesktop/UDisks2/Manager"
DBUS_ATTR_ACTIVE_ACCESSPOINT = "ActiveAccessPoint"
DBUS_ATTR_ACTIVE_CONNECTION = "ActiveConnection"
@ -64,6 +71,7 @@ DBUS_ATTR_CHASSIS = "Chassis"
DBUS_ATTR_COMPATIBLE = "Compatible"
DBUS_ATTR_CONFIGURATION = "Configuration"
DBUS_ATTR_CONNECTION = "Connection"
DBUS_ATTR_CONNECTION_BUS = "ConnectionBus"
DBUS_ATTR_CONNECTION_ENABLED = "ConnectivityCheckEnabled"
DBUS_ATTR_CONNECTIVITY = "Connectivity"
DBUS_ATTR_CURRENT_DEVICE = "CurrentDevice"
@ -71,7 +79,9 @@ DBUS_ATTR_CURRENT_DNS_SERVER = "CurrentDNSServer"
DBUS_ATTR_CURRENT_DNS_SERVER_EX = "CurrentDNSServerEx"
DBUS_ATTR_DEFAULT = "Default"
DBUS_ATTR_DEPLOYMENT = "Deployment"
DBUS_ATTR_DEVICE = "Device"
DBUS_ATTR_DEVICE_INTERFACE = "Interface"
DBUS_ATTR_DEVICE_NUMBER = "DeviceNumber"
DBUS_ATTR_DEVICE_TYPE = "DeviceType"
DBUS_ATTR_DEVICES = "Devices"
DBUS_ATTR_DIAGNOSTICS = "Diagnostics"
@ -85,7 +95,9 @@ DBUS_ATTR_DNSSEC_NEGATIVE_TRUST_ANCHORS = "DNSSECNegativeTrustAnchors"
DBUS_ATTR_DNSSEC_STATISTICS = "DNSSECStatistics"
DBUS_ATTR_DNSSEC_SUPPORTED = "DNSSECSupported"
DBUS_ATTR_DOMAINS = "Domains"
DBUS_ATTR_DRIVE = "Drive"
DBUS_ATTR_DRIVER = "Driver"
DBUS_ATTR_EJECTABLE = "Ejectable"
DBUS_ATTR_FALLBACK_DNS = "FallbackDNS"
DBUS_ATTR_FALLBACK_DNS_EX = "FallbackDNSEx"
DBUS_ATTR_FINISH_TIMESTAMP = "FinishTimestamp"
@ -93,8 +105,17 @@ DBUS_ATTR_FIRMWARE_TIMESTAMP_MONOTONIC = "FirmwareTimestampMonotonic"
DBUS_ATTR_FREQUENCY = "Frequency"
DBUS_ATTR_GATEWAY = "Gateway"
DBUS_ATTR_HEARTBEAT_LED = "HeartbeatLED"
DBUS_ATTR_HINT_AUTO = "HintAuto"
DBUS_ATTR_HINT_IGNORE = "HintIgnore"
DBUS_ATTR_HINT_NAME = "HintName"
DBUS_ATTR_HINT_SYSTEM = "HintSystem"
DBUS_ATTR_HWADDRESS = "HwAddress"
DBUS_ATTR_ID = "Id"
DBUS_ATTR_ID_LABEL = "IdLabel"
DBUS_ATTR_ID_ID_TYPE = "IdType"
DBUS_ATTR_ID_USAGE = "IdUsage"
DBUS_ATTR_ID_UUID = "IdUUID"
DBUS_ATTR_ID_VERSION = "IdVersion"
DBUS_ATTR_IP4CONFIG = "Ip4Config"
DBUS_ATTR_IP6CONFIG = "Ip6Config"
DBUS_ATTR_KERNEL_RELEASE = "KernelRelease"
@ -105,6 +126,8 @@ DBUS_ATTR_LLMNR_HOSTNAME = "LLMNRHostname"
DBUS_ATTR_LOADER_TIMESTAMP_MONOTONIC = "LoaderTimestampMonotonic"
DBUS_ATTR_MANAGED = "Managed"
DBUS_ATTR_MODE = "Mode"
DBUS_ATTR_MODEL = "Model"
DBUS_ATTR_MOUNT_POINTS = "MountPoints"
DBUS_ATTR_MULTICAST_DNS = "MulticastDNS"
DBUS_ATTR_NAMESERVER_DATA = "NameserverData"
DBUS_ATTR_NAMESERVERS = "Nameservers"
@ -113,16 +136,26 @@ DBUS_ATTR_NTPSYNCHRONIZED = "NTPSynchronized"
DBUS_ATTR_OPERATING_SYSTEM_PRETTY_NAME = "OperatingSystemPrettyName"
DBUS_ATTR_OPERATION = "Operation"
DBUS_ATTR_PARSER_VERSION = "ParserVersion"
DBUS_ATTR_PARTITIONS = "Partitions"
DBUS_ATTR_POWER_LED = "PowerLED"
DBUS_ATTR_PRIMARY_CONNECTION = "PrimaryConnection"
DBUS_ATTR_READ_ONLY = "ReadOnly"
DBUS_ATTR_REMOVABLE = "Removable"
DBUS_ATTR_RESOLV_CONF_MODE = "ResolvConfMode"
DBUS_ATTR_REVISION = "Revision"
DBUS_ATTR_RCMANAGER = "RcManager"
DBUS_ATTR_SEAT = "Seat"
DBUS_ATTR_SERIAL = "Serial"
DBUS_ATTR_SIZE = "Size"
DBUS_ATTR_SSID = "Ssid"
DBUS_ATTR_STATE = "State"
DBUS_ATTR_STATE_FLAGS = "StateFlags"
DBUS_ATTR_STATIC_HOSTNAME = "StaticHostname"
DBUS_ATTR_STATIC_OPERATING_SYSTEM_CPE_NAME = "OperatingSystemCPEName"
DBUS_ATTR_STRENGTH = "Strength"
DBUS_ATTR_SUPPORTED_FILESYSTEMS = "SupportedFilesystems"
DBUS_ATTR_SYMLINKS = "Symlinks"
DBUS_ATTR_TIME_DETECTED = "TimeDetected"
DBUS_ATTR_TIMEUSEC = "TimeUSec"
DBUS_ATTR_TIMEZONE = "Timezone"
DBUS_ATTR_TRANSACTION_STATISTICS = "TransactionStatistics"
@ -130,7 +163,9 @@ DBUS_ATTR_TYPE = "Type"
DBUS_ATTR_USERSPACE_TIMESTAMP_MONOTONIC = "UserspaceTimestampMonotonic"
DBUS_ATTR_UUID = "Uuid"
DBUS_ATTR_VARIANT = "Variant"
DBUS_ATTR_VENDOR = "Vendor"
DBUS_ATTR_VERSION = "Version"
DBUS_ATTR_WWN = "WWN"
class RaucState(str, Enum):

View File

@ -1,6 +1,5 @@
"""D-Bus interface for hostname."""
import logging
from typing import Any
from dbus_fast.aio.message_bus import MessageBus
@ -33,10 +32,6 @@ class Hostname(DBusInterfaceProxy):
object_path: str = DBUS_OBJECT_HOSTNAME
properties_interface: str = DBUS_IFACE_HOSTNAME
def __init__(self):
"""Initialize Properties."""
self.properties: dict[str, Any] = {}
async def connect(self, bus: MessageBus):
"""Connect to system's D-Bus."""
_LOGGER.info("Load dbus interface %s", self.name)

View File

@ -45,7 +45,22 @@ class DBusInterface(ABC):
async def connect(self, bus: MessageBus) -> None:
"""Connect to D-Bus."""
self.dbus = await DBus.connect(bus, self.bus_name, self.object_path)
await self.initialize(await DBus.connect(bus, self.bus_name, self.object_path))
async def initialize(self, connected_dbus: DBus) -> None:
"""Initialize object with already connected dbus object."""
if not connected_dbus.connected:
raise ValueError("must be a connected DBus object")
if (
connected_dbus.bus_name != self.bus_name
or connected_dbus.object_path != self.object_path
):
raise ValueError(
f"must be a DBus object connected to bus {self.bus_name} and object {self.object_path}"
)
self.dbus = connected_dbus
def disconnect(self) -> None:
"""Disconnect from D-Bus."""
@ -69,10 +84,18 @@ class DBusInterfaceProxy(DBusInterface):
properties: dict[str, Any] | None = None
sync_properties: bool = True
def __init__(self):
"""Initialize properties."""
self.properties = {}
async def connect(self, bus: MessageBus) -> None:
"""Connect to D-Bus."""
await super().connect(bus)
async def initialize(self, connected_dbus: DBus) -> None:
"""Initialize object with already connected dbus object."""
await super().initialize(connected_dbus)
if not self.dbus.properties:
self.disconnect()
raise DBusInterfaceError(

View File

@ -17,6 +17,7 @@ from .rauc import Rauc
from .resolved import Resolved
from .systemd import Systemd
from .timedate import TimeDate
from .udisks2 import UDisks2
_LOGGER: logging.Logger = logging.getLogger(__name__)
@ -36,6 +37,7 @@ class DBusManager(CoreSysAttributes):
self._agent: OSAgent = OSAgent()
self._timedate: TimeDate = TimeDate()
self._resolved: Resolved = Resolved()
self._udisks2: UDisks2 = UDisks2()
self._bus: MessageBus | None = None
@property
@ -78,6 +80,11 @@ class DBusManager(CoreSysAttributes):
"""Return the resolved interface."""
return self._resolved
@property
def udisks2(self) -> UDisks2:
"""Return the udisks2 interface."""
return self._udisks2
@property
def bus(self) -> MessageBus | None:
"""Return the message bus."""
@ -95,6 +102,7 @@ class DBusManager(CoreSysAttributes):
self.resolved,
self.systemd,
self.timedate,
self.udisks2,
]
async def load(self) -> None:

View File

@ -50,12 +50,12 @@ class NetworkManager(DBusInterfaceProxy):
def __init__(self) -> None:
"""Initialize Properties."""
super().__init__()
self._dns: NetworkManagerDNS = NetworkManagerDNS()
self._settings: NetworkManagerSettings = NetworkManagerSettings()
self._interfaces: dict[str, NetworkInterface] = {}
self.properties: dict[str, Any] = {}
@property
def dns(self) -> NetworkManagerDNS:
"""Return NetworkManager DNS interface."""

View File

@ -1,7 +1,5 @@
"""Connection object for Network Manager."""
from typing import Any
from ..const import (
DBUS_ATTR_FREQUENCY,
DBUS_ATTR_HWADDRESS,
@ -27,8 +25,9 @@ class NetworkWirelessAP(DBusInterfaceProxy):
def __init__(self, object_path: str) -> None:
"""Initialize NetworkWireless AP object."""
super().__init__()
self.object_path: str = object_path
self.properties: dict[str, Any] = {}
@property
@dbus_property

View File

@ -35,8 +35,9 @@ class NetworkConnection(DBusInterfaceProxy):
def __init__(self, object_path: str) -> None:
"""Initialize NetworkConnection object."""
super().__init__()
self.object_path: str = object_path
self.properties: dict[str, Any] = {}
self._ipv4: IpConfiguration | None = None
self._ipv6: IpConfiguration | None = None

View File

@ -40,10 +40,11 @@ class NetworkManagerDNS(DBusInterfaceProxy):
def __init__(self) -> None:
"""Initialize Properties."""
super().__init__()
self._mode: str | None = None
self._rc_manager: str | None = None
self._configuration: list[DNSConfiguration] = []
self.properties: dict[str, Any] = {}
@property
def mode(self) -> str | None:

View File

@ -35,8 +35,9 @@ class NetworkInterface(DBusInterfaceProxy):
def __init__(self, nm_dbus: DBus, object_path: str) -> None:
"""Initialize NetworkConnection object."""
super().__init__()
self.object_path: str = object_path
self.properties: dict[str, Any] = {}
self.primary: bool = False

View File

@ -8,7 +8,6 @@ from ipaddress import (
ip_address,
ip_interface,
)
from typing import Any
from ...const import ATTR_ADDRESS, ATTR_PREFIX
from ..const import (
@ -30,12 +29,13 @@ class IpConfiguration(DBusInterfaceProxy):
def __init__(self, object_path: str, ip4: bool = True) -> None:
"""Initialize properties."""
super().__init__()
self._ip4: bool = ip4
self.object_path: str = object_path
self.properties_interface: str = (
DBUS_IFACE_IP4CONFIG if ip4 else DBUS_IFACE_IP6CONFIG
)
self.properties: dict[str, Any] = {}
@property
@dbus_property

View File

@ -27,8 +27,9 @@ class NetworkWireless(DBusInterfaceProxy):
def __init__(self, object_path: str) -> None:
"""Initialize NetworkConnection object."""
super().__init__()
self.object_path: str = object_path
self.properties: dict[str, Any] = {}
self._active: NetworkWirelessAP | None = None

View File

@ -34,14 +34,14 @@ class Rauc(DBusInterfaceProxy):
def __init__(self):
"""Initialize Properties."""
super().__init__()
self._operation: str | None = None
self._last_error: str | None = None
self._compatible: str | None = None
self._variant: str | None = None
self._boot_slot: str | None = None
self.properties: dict[str, Any] = {}
async def connect(self, bus: MessageBus):
"""Connect to D-Bus."""
_LOGGER.info("Load dbus interface %s", self.name)

View File

@ -2,7 +2,6 @@
from __future__ import annotations
import logging
from typing import Any
from dbus_fast.aio.message_bus import MessageBus
@ -53,10 +52,6 @@ class Resolved(DBusInterfaceProxy):
object_path: str = DBUS_OBJECT_RESOLVED
properties_interface: str = DBUS_IFACE_RESOLVED_MANAGER
def __init__(self):
"""Initialize Properties."""
self.properties: dict[str, Any] = {}
async def connect(self, bus: MessageBus):
"""Connect to D-Bus."""
_LOGGER.info("Load dbus interface %s", self.name)

View File

@ -1,6 +1,5 @@
"""Interface to Systemd over D-Bus."""
import logging
from typing import Any
from dbus_fast.aio.message_bus import MessageBus
@ -34,10 +33,6 @@ class Systemd(DBusInterfaceProxy):
sync_properties: bool = False
properties_interface: str = DBUS_IFACE_SYSTEMD_MANAGER
def __init__(self) -> None:
"""Initialize Properties."""
self.properties: dict[str, Any] = {}
async def connect(self, bus: MessageBus):
"""Connect to D-Bus."""
_LOGGER.info("Load dbus interface %s", self.name)

View File

@ -1,7 +1,6 @@
"""Interface to systemd-timedate over D-Bus."""
from datetime import datetime
import logging
from typing import Any
from dbus_fast.aio.message_bus import MessageBus
@ -33,10 +32,6 @@ class TimeDate(DBusInterfaceProxy):
object_path: str = DBUS_OBJECT_TIMEDATE
properties_interface: str = DBUS_IFACE_TIMEDATE
def __init__(self) -> None:
"""Initialize Properties."""
self.properties: dict[str, Any] = {}
@property
@dbus_property
def timezone(self) -> str:

View File

@ -0,0 +1,146 @@
"""Interface to UDisks2 over D-Bus."""
import logging
from typing import Any
from awesomeversion import AwesomeVersion
from dbus_fast.aio import MessageBus
from ...exceptions import DBusError, DBusInterfaceError, DBusObjectError
from ..const import (
DBUS_ATTR_SUPPORTED_FILESYSTEMS,
DBUS_ATTR_VERSION,
DBUS_IFACE_UDISKS2_MANAGER,
DBUS_NAME_UDISKS2,
DBUS_OBJECT_BASE,
DBUS_OBJECT_UDISKS2,
)
from ..interface import DBusInterfaceProxy, dbus_property
from ..utils import dbus_connected
from .block import UDisks2Block
from .const import UDISKS2_DEFAULT_OPTIONS
from .data import DeviceSpecification
from .drive import UDisks2Drive
_LOGGER: logging.Logger = logging.getLogger(__name__)
class UDisks2(DBusInterfaceProxy):
"""Handle D-Bus interface for UDisks2.
http://storaged.org/doc/udisks2-api/latest/
"""
name: str = DBUS_NAME_UDISKS2
bus_name: str = DBUS_NAME_UDISKS2
object_path: str = DBUS_OBJECT_UDISKS2
properties_interface: str = DBUS_IFACE_UDISKS2_MANAGER
_block_devices: dict[str, UDisks2Block] = {}
_drives: dict[str, UDisks2Drive] = {}
async def connect(self, bus: MessageBus):
"""Connect to D-Bus."""
try:
await super().connect(bus)
except DBusError:
_LOGGER.warning("Can't connect to udisks2")
except DBusInterfaceError:
_LOGGER.warning(
"No udisks2 support on the host. Host control has been disabled."
)
@dbus_connected
async def update(self, changed: dict[str, Any] | None = None) -> None:
"""Update properties via D-Bus.
Also rebuilds cache of available block devices and drives.
"""
await super().update(changed)
if not changed:
# Cache block devices
block_devices = await self.dbus.Manager.call_get_block_devices(
UDISKS2_DEFAULT_OPTIONS
)
for removed in self._block_devices.keys() - set(block_devices):
self._block_devices[removed].shutdown()
await self._resolve_block_device_paths(block_devices)
# Cache drives
drives = {
device.drive
for device in self.block_devices
if device.drive != DBUS_OBJECT_BASE
}
for removed in self._drives.keys() - drives:
self._drives[removed].shutdown()
self._drives = {
drive: self._drives[drive]
if drive in self._drives
else await UDisks2Drive.new(drive, self.dbus.bus)
for drive in drives
}
@property
@dbus_property
def version(self) -> AwesomeVersion:
"""UDisks2 version."""
return AwesomeVersion(self.properties[DBUS_ATTR_VERSION])
@property
@dbus_property
def supported_filesystems(self) -> list[str]:
"""Return list of supported filesystems."""
return self.properties[DBUS_ATTR_SUPPORTED_FILESYSTEMS]
@property
def block_devices(self) -> list[UDisks2Block]:
"""List of available block devices."""
return list(self._block_devices.values())
@property
def drives(self) -> list[UDisks2Drive]:
"""List of available drives."""
return list(self._drives.values())
@dbus_connected
def get_drive(self, drive_path: str) -> UDisks2Drive:
"""Get additional info on drive from object path."""
if drive_path not in self._drives:
raise DBusObjectError(f"Drive {drive_path} not found")
return self._drives[drive_path]
@dbus_connected
def get_block_device(self, device_path: str) -> UDisks2Block:
"""Get additional info on block device from object path."""
if device_path not in self._block_devices:
raise DBusObjectError(f"Block device {device_path} not found")
return self._block_devices[device_path]
@dbus_connected
async def resolve_device(self, devspec: DeviceSpecification) -> list[UDisks2Block]:
"""Return list of device object paths for specification."""
return await self._resolve_block_device_paths(
await self.dbus.Manager.call_resolve_device(
devspec.to_dict(), UDISKS2_DEFAULT_OPTIONS
)
)
async def _resolve_block_device_paths(
self, block_devices: list[str]
) -> list[UDisks2Block]:
"""Resolve block device object paths to objects. Cache new ones if necessary."""
resolved = {
device: self._block_devices[device]
if device in self._block_devices
else await UDisks2Block.new(device, self.dbus.bus)
for device in block_devices
}
self._block_devices.update(resolved)
return list(resolved.values())

View File

@ -0,0 +1,206 @@
"""Interface to UDisks2 Block Device over D-Bus."""
from collections.abc import Callable
from pathlib import Path
from awesomeversion import AwesomeVersion
from dbus_fast.aio import MessageBus
from ..const import (
DBUS_ATTR_DEVICE,
DBUS_ATTR_DEVICE_NUMBER,
DBUS_ATTR_DRIVE,
DBUS_ATTR_HINT_AUTO,
DBUS_ATTR_HINT_IGNORE,
DBUS_ATTR_HINT_NAME,
DBUS_ATTR_HINT_SYSTEM,
DBUS_ATTR_ID,
DBUS_ATTR_ID_ID_TYPE,
DBUS_ATTR_ID_LABEL,
DBUS_ATTR_ID_USAGE,
DBUS_ATTR_ID_UUID,
DBUS_ATTR_ID_VERSION,
DBUS_ATTR_READ_ONLY,
DBUS_ATTR_SIZE,
DBUS_ATTR_SYMLINKS,
DBUS_IFACE_BLOCK,
DBUS_IFACE_FILESYSTEM,
DBUS_IFACE_PARTITION_TABLE,
DBUS_NAME_UDISKS2,
)
from ..interface import DBusInterfaceProxy, dbus_property
from ..utils import dbus_connected
from .const import UDISKS2_DEFAULT_OPTIONS, FormatType
from .data import FormatOptions
from .filesystem import UDisks2Filesystem
from .partition_table import UDisks2PartitionTable
ADDITIONAL_INTERFACES: dict[str, Callable[[str], DBusInterfaceProxy]] = {
DBUS_IFACE_FILESYSTEM: UDisks2Filesystem
}
class UDisks2Block(DBusInterfaceProxy):
"""Handle D-Bus interface for UDisks2 block device object.
http://storaged.org/doc/udisks2-api/latest/gdbus-org.freedesktop.UDisks2.Block.html
"""
name: str = DBUS_IFACE_BLOCK
bus_name: str = DBUS_NAME_UDISKS2
properties_interface: str = DBUS_IFACE_BLOCK
_filesystem: UDisks2Filesystem | None = None
_partition_table: UDisks2PartitionTable | None = None
def __init__(self, object_path: str, *, sync_properties: bool = True) -> None:
"""Initialize object."""
self.object_path = object_path
self.sync_properties = sync_properties
super().__init__()
async def connect(self, bus: MessageBus) -> None:
"""Connect to bus."""
await super().connect(bus)
if DBUS_IFACE_FILESYSTEM in self.dbus.proxies:
self._filesystem = UDisks2Filesystem(
self.object_path, sync_properties=self.sync_properties
)
await self._filesystem.initialize(self.dbus)
if DBUS_IFACE_PARTITION_TABLE in self.dbus.proxies:
self._partition_table = UDisks2PartitionTable(
self.object_path, sync_properties=self.sync_properties
)
await self._partition_table.initialize(self.dbus)
@staticmethod
async def new(
object_path: str, bus: MessageBus, *, sync_properties: bool = True
) -> "UDisks2Block":
"""Create and connect object."""
obj = UDisks2Block(object_path, sync_properties=sync_properties)
await obj.connect(bus)
return obj
@property
def filesystem(self) -> UDisks2Filesystem | None:
"""Filesystem interface if block device is one."""
return self._filesystem
@property
def partition_table(self) -> UDisks2PartitionTable | None:
"""Partition table interface if block device is one."""
return self._partition_table
@property
@dbus_property
def device(self) -> Path:
"""Return device file."""
return Path(bytes(self.properties[DBUS_ATTR_DEVICE]).decode())
@property
@dbus_property
def id(self) -> str:
"""Return unique identifer."""
return self.properties[DBUS_ATTR_ID]
@property
@dbus_property
def size(self) -> int:
"""Return size."""
return self.properties[DBUS_ATTR_SIZE]
@property
@dbus_property
def read_only(self) -> bool:
"""Return whether device is read only."""
return self.properties[DBUS_ATTR_READ_ONLY]
@property
@dbus_property
def symlinks(self) -> list[Path]:
"""Return list of symlinks."""
return [
Path(bytes(symlink).decode(encoding="utf-8"))
for symlink in self.properties[DBUS_ATTR_SYMLINKS]
]
@property
@dbus_property
def device_number(self) -> int:
"""Return device number."""
return self.properties[DBUS_ATTR_DEVICE_NUMBER]
@property
@dbus_property
def id_usage(self) -> str:
"""Return expected usage of structured data by probing signatures (if known)."""
return self.properties[DBUS_ATTR_ID_USAGE]
@property
@dbus_property
def id_type(self) -> str:
"""Return more specific usage information on structured data (if known)."""
return self.properties[DBUS_ATTR_ID_ID_TYPE]
@property
@dbus_property
def id_version(self) -> AwesomeVersion:
"""Return version of filesystem or other structured data."""
return AwesomeVersion(self.properties[DBUS_ATTR_ID_VERSION])
@property
@dbus_property
def id_label(self) -> str:
"""Return label of filesystem or other structured data."""
return self.properties[DBUS_ATTR_ID_LABEL]
@property
@dbus_property
def id_uuid(self) -> str:
"""Return uuid of filesystem or other structured data."""
return self.properties[DBUS_ATTR_ID_UUID]
@property
@dbus_property
def hint_auto(self) -> bool:
"""Return true if device should be automatically started (mounted, unlocked, etc)."""
return self.properties[DBUS_ATTR_HINT_AUTO]
@property
@dbus_property
def hint_ignore(self) -> bool:
"""Return true if device should be hidden from users."""
return self.properties[DBUS_ATTR_HINT_IGNORE]
@property
@dbus_property
def hint_name(self) -> str:
"""Return name that should be presented to users."""
return self.properties[DBUS_ATTR_HINT_NAME]
@property
@dbus_property
def hint_system(self) -> bool:
"""Return true if device is considered a system device.."""
return self.properties[DBUS_ATTR_HINT_SYSTEM]
@property
@dbus_property
def drive(self) -> str:
"""Return object path for drive.
Provide to UDisks2.get_drive for UDisks2Drive object.
"""
return self.properties[DBUS_ATTR_DRIVE]
@dbus_connected
async def format(
self, type_: FormatType = FormatType.GPT, options: FormatOptions | None = None
) -> None:
"""Format block device."""
options = options.to_dict() if options else {}
await self.dbus.Block.call_format(
type_.value, options | UDISKS2_DEFAULT_OPTIONS
)

View File

@ -0,0 +1,37 @@
"""Constants for UDisks2."""
from enum import Enum
UDISKS2_DEFAULT_OPTIONS = {"auth.no_user_interaction": True}
class EncryptType(str, Enum):
"""Encryption type."""
LUKS1 = "luks1"
LUKS2 = "luks2"
class EraseMode(str, Enum):
"""Erase mode."""
ZERO = "zero"
ATA_SECURE_ERASE = "ata-secure-erase"
ATA_SECURE_ERASE_ENHANCED = "ata-secure-erase-enhanced"
class FormatType(str, Enum):
"""Format type."""
EMPTY = "empty"
SWAP = "swap"
DOS = "dos"
GPT = "gpt"
class PartitionTableType(str, Enum):
"""Partition Table type."""
DOS = "dos"
GPT = "gpt"
UNKNOWN = ""

View File

@ -0,0 +1,294 @@
"""Data for UDisks2."""
from dataclasses import dataclass
from inspect import get_annotations
from pathlib import Path
from typing import Any, TypedDict
from dbus_fast import Variant
from typing_extensions import NotRequired
from .const import EncryptType, EraseMode
def _optional_variant(signature: str, value: Any | None) -> Variant | None:
"""Output variant if value is not none."""
return Variant(signature, value) if value is not None else None
UDisks2StandardOptionsDataType = TypedDict(
"UDisks2StandardOptionsDataType",
{"auth.no_user_interaction": NotRequired[bool]},
)
@dataclass(slots=True)
class UDisks2StandardOptions:
"""UDisks2 standard options.
http://storaged.org/doc/udisks2-api/latest/udisks-std-options.html
"""
auth_no_user_interaction: bool | None = None
@staticmethod
def from_dict(data: UDisks2StandardOptionsDataType) -> "UDisks2StandardOptions":
"""Create UDisks2StandardOptions from dict."""
return UDisks2StandardOptions(
auth_no_user_interaction=data.get("auth.no_user_interaction"),
)
def to_dict(self) -> dict[str, Variant]:
"""Return dict representation."""
data = {
"auth.no_user_interaction": _optional_variant(
"b", self.auth_no_user_interaction
),
}
return {k: v for k, v in data.items() if v}
_udisks2_standard_options_annotations = get_annotations(UDisks2StandardOptionsDataType)
class DeviceSpecificationDataType(TypedDict, total=False):
"""Device specification data type."""
path: str
label: str
uuid: str
@dataclass(slots=True)
class DeviceSpecification:
"""Device specification.
http://storaged.org/doc/udisks2-api/latest/gdbus-org.freedesktop.UDisks2.Manager.html#gdbus-method-org-freedesktop-UDisks2-Manager.ResolveDevice
"""
path: Path | None = None
label: str | None = None
uuid: str | None = None
@staticmethod
def from_dict(data: DeviceSpecificationDataType) -> "DeviceSpecification":
"""Create DeviceSpecification from dict."""
return DeviceSpecification(
path=Path(data.get("path")),
label=data.get("label"),
uuid=data.get("uuid"),
)
def to_dict(self) -> dict[str, Variant]:
"""Return dict representation."""
data = {
"path": Variant("s", str(self.path)) if self.path else None,
"label": _optional_variant("s", self.label),
"uuid": _optional_variant("s", self.uuid),
}
return {k: v for k, v in data.items() if v}
FormatOptionsDataType = TypedDict(
"FormatOptionsDataType",
{
"label": NotRequired[str],
"take-ownership": NotRequired[bool],
"encrypt.passphrase": NotRequired[bytearray],
"encrypt.type": NotRequired[str],
"erase": NotRequired[str],
"update-partition-type": NotRequired[bool],
"no-block": NotRequired[bool],
"dry-run-first": NotRequired[bool],
"no-discard": NotRequired[bool],
"tear-down": NotRequired[bool],
}
| _udisks2_standard_options_annotations,
)
@dataclass(slots=True)
class FormatOptions(UDisks2StandardOptions):
"""Options for formatting a block device.
http://storaged.org/doc/udisks2-api/latest/gdbus-org.freedesktop.UDisks2.Block.html#gdbus-method-org-freedesktop-UDisks2-Block.Format
"""
label: str | None = None
take_ownership: bool | None = None
encrypt_passpharase: str | None = None
encrypt_type: EncryptType | None = None
erase: EraseMode | None = None
update_partition_type: bool | None = None
no_block: bool | None = None
dry_run_first: bool | None = None
no_discard: bool | None = None
tear_down: bool | None = None
@staticmethod
def from_dict(data: FormatOptionsDataType) -> "FormatOptions":
"""Create FormatOptions from dict."""
return FormatOptions(
label=data.get("label"),
take_ownership=data.get("take-ownership"),
encrypt_passpharase=bytes(data["encrypt.passphrase"]).decode(
encoding="utf-8"
)
if "encrypt.passphrase" in data
else None,
encrypt_type=EncryptType(data["encrypt.type"])
if "encrypt.type" in data
else None,
erase=EncryptType(data["erase"]) if "erase" in data else None,
update_partition_type=data.get("update-partition-type"),
no_block=data.get("no-block"),
dry_run_first=data.get("dry-run-first"),
no_discard=data.get("no-discard"),
tear_down=data.get("tear-down"),
# UDisks2 standard options
auth_no_user_interaction=data.get("auth.no_user_interaction"),
)
def to_dict(self) -> dict[str, Variant]:
"""Return dict representation."""
data = {
"label": _optional_variant("s", self.label),
"take-ownership": _optional_variant("b", self.take_ownership),
"encrypt.passphrase": Variant(
"ay", bytearray(self.encrypt_passpharase, encoding="utf-8")
)
if self.encrypt_passpharase
else None,
"encrypt.type": Variant("s", self.encrypt_type.value)
if self.encrypt_type
else None,
"erase": Variant("s", self.erase.value) if self.erase else None,
"update-partition-type": _optional_variant("b", self.update_partition_type),
"no-block": _optional_variant("b", self.no_block),
"dry-run-first": _optional_variant("b", self.dry_run_first),
"no-discard": _optional_variant("b", self.no_discard),
"tear-down": _optional_variant("b", self.tear_down),
# UDisks2 standard options
"auth.no_user_interaction": _optional_variant(
"b", self.auth_no_user_interaction
),
}
return {k: v for k, v in data.items() if v}
MountOptionsDataType = TypedDict(
"MountOptionsDataType",
{
"fstype": NotRequired[str],
"options": NotRequired[str],
}
| _udisks2_standard_options_annotations,
)
@dataclass
class MountOptions(UDisks2StandardOptions):
"""Filesystem mount options.
http://storaged.org/doc/udisks2-api/latest/gdbus-org.freedesktop.UDisks2.Filesystem.html#gdbus-method-org-freedesktop-UDisks2-Filesystem.Mount
"""
fstype: str | None = None
options: list[str] | None = None
@staticmethod
def from_dict(data: MountOptionsDataType) -> "MountOptions":
"""Create MountOptions from dict."""
return MountOptions(
fstype=data.get("fstype"),
options=data["options"].split(",") if "options" in data else None,
# UDisks2 standard options
auth_no_user_interaction=data.get("auth.no_user_interaction"),
)
def to_dict(self) -> dict[str, Variant]:
"""Return dict representation."""
data = {
"fstype": _optional_variant("s", self.fstype),
"options": Variant("s", ",".join(self.options)) if self.options else None,
# UDisks2 standard options
"auth.no_user_interaction": _optional_variant(
"b", self.auth_no_user_interaction
),
}
return {k: v for k, v in data.items() if v is not None}
UnmountOptionsDataType = TypedDict(
"UnountOptionsDataType",
{
"force": NotRequired[bool],
}
| _udisks2_standard_options_annotations,
)
@dataclass
class UnmountOptions(UDisks2StandardOptions):
"""Filesystem unmount options.
http://storaged.org/doc/udisks2-api/latest/gdbus-org.freedesktop.UDisks2.Filesystem.html#gdbus-method-org-freedesktop-UDisks2-Filesystem.Unmount
"""
force: bool | None = None
@staticmethod
def from_dict(data: UnmountOptionsDataType) -> "UnmountOptions":
"""Create MountOptions from dict."""
return UnmountOptions(
force=data.get("force"),
# UDisks2 standard options
auth_no_user_interaction=data.get("auth.no_user_interaction"),
)
def to_dict(self) -> dict[str, Variant]:
"""Return dict representation."""
data = {
"force": _optional_variant("b", self.force),
# UDisks2 standard options
"auth.no_user_interaction": _optional_variant(
"b", self.auth_no_user_interaction
),
}
return {k: v for k, v in data.items() if v}
CreatePartitionOptionsDataType = TypedDict(
"CreatePartitionOptionsDataType",
{"partition-type": NotRequired[str]} | _udisks2_standard_options_annotations,
)
@dataclass
class CreatePartitionOptions(UDisks2StandardOptions):
"""Create partition options.
http://storaged.org/doc/udisks2-api/latest/gdbus-org.freedesktop.UDisks2.PartitionTable.html#gdbus-method-org-freedesktop-UDisks2-PartitionTable.CreatePartition
"""
partition_type: str | None = None
@staticmethod
def from_dict(data: CreatePartitionOptionsDataType) -> "CreatePartitionOptions":
"""Create CreatePartitionOptions from dict."""
return CreatePartitionOptions(
partition_type=data.get("partition-type"),
# UDisks2 standard options
auth_no_user_interaction=data.get("auth.no_user_interaction"),
)
def to_dict(self) -> dict[str, Variant]:
"""Return dict representation."""
data = {
"partition-type": _optional_variant("s", self.partition_type),
# UDisks2 standard options
"auth.no_user_interaction": _optional_variant(
"b", self.auth_no_user_interaction
),
}
return {k: v for k, v in data.items() if v}

View File

@ -0,0 +1,127 @@
"""Interface to UDisks2 Drive over D-Bus."""
from datetime import datetime, timezone
from dbus_fast.aio import MessageBus
from ..const import (
DBUS_ATTR_CONNECTION_BUS,
DBUS_ATTR_EJECTABLE,
DBUS_ATTR_ID,
DBUS_ATTR_MODEL,
DBUS_ATTR_REMOVABLE,
DBUS_ATTR_REVISION,
DBUS_ATTR_SEAT,
DBUS_ATTR_SERIAL,
DBUS_ATTR_SIZE,
DBUS_ATTR_TIME_DETECTED,
DBUS_ATTR_VENDOR,
DBUS_ATTR_WWN,
DBUS_IFACE_DRIVE,
DBUS_NAME_UDISKS2,
)
from ..interface import DBusInterfaceProxy, dbus_property
from ..utils import dbus_connected
from .const import UDISKS2_DEFAULT_OPTIONS
class UDisks2Drive(DBusInterfaceProxy):
"""Handle D-Bus interface for UDisks2 drive object.
http://storaged.org/doc/udisks2-api/latest/gdbus-org.freedesktop.UDisks2.Drive.html
"""
name: str = DBUS_IFACE_DRIVE
bus_name: str = DBUS_NAME_UDISKS2
properties_interface: str = DBUS_IFACE_DRIVE
def __init__(self, object_path: str) -> None:
"""Initialize object."""
self.object_path = object_path
super().__init__()
@staticmethod
async def new(object_path: str, bus: MessageBus) -> "UDisks2Drive":
"""Create and connect object."""
obj = UDisks2Drive(object_path)
await obj.connect(bus)
return obj
@property
@dbus_property
def vendor(self) -> str:
"""Return vendor name if known."""
return self.properties[DBUS_ATTR_VENDOR]
@property
@dbus_property
def model(self) -> str:
"""Return model name if known."""
return self.properties[DBUS_ATTR_MODEL]
@property
@dbus_property
def revision(self) -> str:
"""Return firmware revision."""
return self.properties[DBUS_ATTR_REVISION]
@property
@dbus_property
def serial(self) -> str:
"""Return serial number."""
return self.properties[DBUS_ATTR_SERIAL]
@property
@dbus_property
def wwn(self) -> str:
"""Return WWN (http://en.wikipedia.org/wiki/World_Wide_Name) if known."""
return self.properties[DBUS_ATTR_WWN]
@property
@dbus_property
def id(self) -> str:
"""Return unique and persistent id."""
return self.properties[DBUS_ATTR_ID]
@property
@dbus_property
def size(self) -> int:
"""Return drive size."""
return self.properties[DBUS_ATTR_SIZE]
@property
@dbus_property
def time_detected(self) -> datetime:
"""Return time drive first detected."""
return datetime.fromtimestamp(
self.properties[DBUS_ATTR_TIME_DETECTED] * 10**-6
).astimezone(timezone.utc)
@property
@dbus_property
def connection_bus(self) -> str:
"""Return physical connection bus used (usb, sdio, etc)."""
return self.properties[DBUS_ATTR_CONNECTION_BUS]
@property
@dbus_property
def seat(self) -> str:
"""Return seat drive is plugged into if any."""
return self.properties[DBUS_ATTR_SEAT]
@property
@dbus_property
def removable(self) -> bool:
"""Return true if drive is considered removable by user."""
return self.properties[DBUS_ATTR_REMOVABLE]
@property
@dbus_property
def ejectable(self) -> bool:
"""Return true if drive accepts an eject command."""
return self.properties[DBUS_ATTR_EJECTABLE]
@dbus_connected
async def eject(self) -> None:
"""Eject media from drive."""
await self.dbus.Drive.call_eject(UDISKS2_DEFAULT_OPTIONS)

View File

@ -0,0 +1,78 @@
"""Interface to UDisks2 Filesystem over D-Bus."""
from pathlib import Path
from ..const import (
DBUS_ATTR_MOUNT_POINTS,
DBUS_ATTR_SIZE,
DBUS_IFACE_FILESYSTEM,
DBUS_NAME_UDISKS2,
)
from ..interface import DBusInterfaceProxy, dbus_property
from ..utils import dbus_connected
from .const import UDISKS2_DEFAULT_OPTIONS
from .data import MountOptions, UnmountOptions
class UDisks2Filesystem(DBusInterfaceProxy):
"""Handle D-Bus interface for UDisks2 filesystem device object.
http://storaged.org/doc/udisks2-api/latest/gdbus-org.freedesktop.UDisks2.Filesystem.html
"""
name: str = DBUS_IFACE_FILESYSTEM
bus_name: str = DBUS_NAME_UDISKS2
properties_interface: str = DBUS_IFACE_FILESYSTEM
def __init__(self, object_path: str, *, sync_properties: bool = True) -> None:
"""Initialize object."""
self.object_path = object_path
self.sync_properties = sync_properties
super().__init__()
@property
@dbus_property
def mount_points(self) -> list[Path]:
"""Return mount points."""
return [
Path(bytes(mount_point).decode())
for mount_point in self.properties[DBUS_ATTR_MOUNT_POINTS]
]
@property
@dbus_property
def size(self) -> int:
"""Return size."""
return self.properties[DBUS_ATTR_SIZE]
@dbus_connected
async def mount(self, options: MountOptions | None = None) -> str:
"""Mount filesystem.
Caller cannot provide mountpoint. UDisks selects a folder within /run/media/$USER
if not overridden in /etc/fstab. Therefore unclear if this can be useful to supervisor.
http://storaged.org/doc/udisks2-api/latest/gdbus-org.freedesktop.UDisks2.Filesystem.html#gdbus-method-org-freedesktop-UDisks2-Filesystem.Mount
"""
options = options.to_dict() if options else {}
return await self.dbus.Filesystem.call_mount(options | UDISKS2_DEFAULT_OPTIONS)
@dbus_connected
async def unmount(self, options: UnmountOptions | None = None) -> None:
"""Unmount filesystem."""
options = options.to_dict() if options else {}
await self.dbus.Filesystem.call_unmount(options | UDISKS2_DEFAULT_OPTIONS)
@dbus_connected
async def set_label(self) -> None:
"""Set filesystem label."""
await self.dbus.Filesystem.call_set_label(UDISKS2_DEFAULT_OPTIONS)
@dbus_connected
async def check(self) -> bool:
"""Check filesystem for consistency. Returns true if it passed."""
return await self.dbus.Filesystem.call_check(UDISKS2_DEFAULT_OPTIONS)
@dbus_connected
async def repair(self) -> bool:
"""Attempt to repair filesystem. Returns true if repair was successful."""
return await self.dbus.Filesystem.call_repair(UDISKS2_DEFAULT_OPTIONS)

View File

@ -0,0 +1,63 @@
"""Interface to UDisks2 Partition Table over D-Bus."""
from ..const import (
DBUS_ATTR_PARTITIONS,
DBUS_ATTR_TYPE,
DBUS_IFACE_PARTITION_TABLE,
DBUS_NAME_UDISKS2,
)
from ..interface import DBusInterfaceProxy, dbus_property
from ..utils import dbus_connected
from .const import UDISKS2_DEFAULT_OPTIONS, PartitionTableType
from .data import CreatePartitionOptions
class UDisks2PartitionTable(DBusInterfaceProxy):
"""Handle D-Bus interface for UDisks2 partition table device object.
http://storaged.org/doc/udisks2-api/latest/gdbus-org.freedesktop.UDisks2.PartitionTable.html
"""
name: str = DBUS_IFACE_PARTITION_TABLE
bus_name: str = DBUS_NAME_UDISKS2
properties_interface: str = DBUS_IFACE_PARTITION_TABLE
def __init__(self, object_path: str, *, sync_properties: bool = True) -> None:
"""Initialize object."""
self.object_path = object_path
self.sync_properties = sync_properties
super().__init__()
@property
@dbus_property
def partitions(self) -> list[str]:
"""List of object paths of partitions that belong to this table.
Provide to UDisks2.get_block_device for UDisks2Block object.
"""
return self.properties[DBUS_ATTR_PARTITIONS]
@property
@dbus_property
def type(self) -> PartitionTableType:
"""Type of partition table."""
return PartitionTableType(self.properties[DBUS_ATTR_TYPE])
@dbus_connected
async def create_partition(
self,
offset: int = 0,
size: int = 0,
type_: PartitionTableType = PartitionTableType.UNKNOWN,
name: str = "",
options: CreatePartitionOptions | None = None,
) -> str:
"""Create a new partition and return object path of new block device.
'UNKNOWN' for type here means UDisks2 selects default based on partition table and OS.
Use with UDisks2Block.new to get block object. Or UDisks2.get_block_device after UDisks2.update.
"""
options = options.to_dict() if options else {}
return await self.dbus.PartitionTable.call_create_partition(
offset, size, type_, name, options | UDISKS2_DEFAULT_OPTIONS
)

View File

@ -42,16 +42,17 @@ class WifiMode(str, Enum):
class HostFeature(str, Enum):
"""Host feature."""
DISK = "disk"
HAOS = "haos"
HOSTNAME = "hostname"
JOURNAL = "journal"
NETWORK = "network"
OS_AGENT = "os_agent"
REBOOT = "reboot"
RESOLVED = "resolved"
SERVICES = "services"
SHUTDOWN = "shutdown"
OS_AGENT = "os_agent"
TIMEDATE = "timedate"
JOURNAL = "journal"
class LogFormat(str, Enum):

View File

@ -107,6 +107,9 @@ class HostManager(CoreSysAttributes):
if self.logs.available:
features.append(HostFeature.JOURNAL)
if self.sys_dbus.udisks2.is_connected:
features.append(HostFeature.DISK)
return features
async def reload(self):
@ -122,6 +125,9 @@ class HostManager(CoreSysAttributes):
if self.sys_dbus.agent.is_connected:
await self.sys_dbus.agent.update()
if self.sys_dbus.udisks2.is_connected:
await self.sys_dbus.udisks2.update()
with suppress(PulseAudioError):
await self.sound.update()

View File

@ -147,11 +147,21 @@ class DBus:
)
self._add_interfaces()
@property
def proxies(self) -> dict[str, ProxyInterface]:
"""Return all proxies."""
return self._proxies
@property
def bus(self) -> MessageBus:
"""Get message bus."""
return self._bus
@property
def connected(self) -> bool:
"""Is connected."""
return self._proxy_obj is not None
@property
def properties(self) -> DBusCallWrapper | None:
"""Get properties proxy interface."""

View File

@ -1,13 +1,15 @@
"""Test Docker API."""
from pathlib import Path
from aiohttp.test_utils import TestClient
import pytest
from supervisor.coresys import CoreSys
from supervisor.hardware.data import Device
@pytest.mark.asyncio
async def test_api_hardware_info(api_client):
async def test_api_hardware_info(api_client: TestClient):
"""Test docker info api."""
resp = await api_client.get("/hardware/info")
result = await resp.json()
@ -16,7 +18,7 @@ async def test_api_hardware_info(api_client):
@pytest.mark.asyncio
async def test_api_hardware_info_device(api_client, coresys):
async def test_api_hardware_info_device(api_client: TestClient, coresys: CoreSys):
"""Test docker info api."""
coresys.hardware.update_device(
Device(
@ -37,3 +39,26 @@ async def test_api_hardware_info_device(api_client, coresys):
assert result["result"] == "ok"
assert result["data"]["devices"][-1]["name"] == "sda"
assert result["data"]["devices"][-1]["by_id"] == "/dev/serial/by-id/test"
async def test_api_hardware_info_drives(api_client: TestClient, coresys: CoreSys):
"""Test drive info."""
await coresys.dbus.udisks2.connect(coresys.dbus.bus)
resp = await api_client.get("/hardware/info")
result = await resp.json()
assert result["result"] == "ok"
assert {
drive["id"]: {fs["id"] for fs in drive["filesystems"]}
for drive in result["data"]["drives"]
} == {
"BJTD4R-0x97cde291": {
"by-id-mmc-BJTD4R_0x97cde291-part1",
"by-id-mmc-BJTD4R_0x97cde291-part3",
},
"SSK-SSK-Storage-DF56419883D56": {
"by-id-usb-SSK_SSK_Storage_DF56419883D56-0:0-part1"
},
"Generic-Flash-Disk-61BCDDB6": {"by-uuid-2802-1EDE"},
}

View File

@ -48,6 +48,7 @@ async def test_api_host_features(
coresys.host.sys_dbus.timedate.is_connected = False
coresys.host.sys_dbus.agent.is_connected = False
coresys.host.sys_dbus.resolved.is_connected = False
coresys.host.sys_dbus.udisks2.is_connected = False
resp = await api_client.get("/host/info")
result = await resp.json()
@ -59,6 +60,7 @@ async def test_api_host_features(
assert "timedate" not in result["data"]["features"]
assert "os_agent" not in result["data"]["features"]
assert "resolved" not in result["data"]["features"]
assert "disk" not in result["data"]["features"]
coresys.host.sys_dbus.systemd.is_connected = True
coresys.host.supported_features.cache_clear()
@ -98,6 +100,12 @@ async def test_api_host_features(
result = await resp.json()
assert "resolved" in result["data"]["features"]
coresys.host.sys_dbus.udisks2.is_connected = True
coresys.host.supported_features.cache_clear()
resp = await api_client.get("/host/info")
result = await resp.json()
assert "disk" in result["data"]["features"]
async def test_api_llmnr_mdns_info(
api_client: TestClient, coresys_disk_info: CoreSys, dbus_is_connected

View File

@ -3,6 +3,7 @@ from functools import partial
from inspect import unwrap
from pathlib import Path
import re
from typing import Any
from unittest.mock import AsyncMock, MagicMock, Mock, PropertyMock, patch
from uuid import uuid4
@ -49,6 +50,7 @@ from supervisor.dbus.network import NetworkManager
from supervisor.dbus.resolved import Resolved
from supervisor.dbus.systemd import Systemd
from supervisor.dbus.timedate import TimeDate
from supervisor.dbus.udisks2 import UDisks2
from supervisor.docker.manager import DockerAPI
from supervisor.docker.monitor import DockerMonitor
from supervisor.host.logs import LogsControl
@ -118,15 +120,40 @@ async def dbus_bus() -> MessageBus:
yield bus
def _process_pseudo_variant(data: dict[str, Any]) -> Any:
"""Process pseudo variant into value."""
if data["_type"] == "ay":
return bytearray(data["_value"], encoding="utf-8")
if data["_type"] == "aay":
return [bytearray(i, encoding="utf-8") for i in data["_value"]]
# Unknown type, return as is
return data
def process_dbus_json(data: Any) -> Any:
"""Replace pseudo-variants with values of unsupported json types as necessary."""
if not isinstance(data, dict):
return data
if len(data.keys()) == 2 and "_type" in data and "_value" in data:
return _process_pseudo_variant(data)
return {k: process_dbus_json(v) for k, v in data.items()}
def mock_get_properties(object_path: str, interface: str) -> str:
"""Mock get dbus properties."""
latest = object_path.split("/")[-1]
base, _, latest = object_path.rpartition("/")
fixture = interface.replace(".", "_")
if latest.isnumeric():
if latest.isnumeric() or base in [
"/org/freedesktop/UDisks2/block_devices",
"/org/freedesktop/UDisks2/drives",
]:
fixture = f"{fixture}_{latest}"
return load_json_fixture(f"{fixture}.json")
return process_dbus_json(load_json_fixture(f"{fixture}.json"))
async def mock_init_proxy(self):
@ -226,7 +253,7 @@ def dbus(dbus_bus: MessageBus) -> list[str]:
)
if exists_fixture(f"{fixture}.json"):
return load_json_fixture(f"{fixture}.json")
return process_dbus_json(load_json_fixture(f"{fixture}.json"))
with patch("supervisor.utils.dbus.DBus.call_dbus", new=mock_call_dbus), patch(
"supervisor.utils.dbus.DBus._init_proxy", new=mock_init_proxy
@ -313,6 +340,12 @@ async def resolved(dbus: DBus, dbus_bus: MessageBus) -> Resolved:
yield await mock_dbus_interface(dbus, dbus_bus, Resolved())
@pytest.fixture
async def udisks2(dbus: DBus, dbus_bus: MessageBus) -> UDisks2:
"""Mock UDisks2."""
yield await mock_dbus_interface(dbus, dbus_bus, UDisks2())
@pytest.fixture
async def coresys(
event_loop, docker, network_manager, dbus_bus, aiohttp_client, run_dir

View File

@ -8,8 +8,9 @@ from dbus_fast.aio.message_bus import MessageBus
import pytest
from supervisor.dbus.const import DBUS_OBJECT_BASE
from supervisor.dbus.interface import DBusInterfaceProxy
from supervisor.dbus.interface import DBusInterface, DBusInterfaceProxy
from supervisor.exceptions import DBusInterfaceError
from supervisor.utils.dbus import DBus
from tests.common import fire_property_change_signal, fire_watched_signal
@ -120,3 +121,40 @@ async def test_proxy_missing_properties_interface(dbus_bus: MessageBus):
with pytest.raises(DBusInterfaceError):
await proxy.connect(dbus_bus)
assert proxy.is_connected is False
async def test_initialize(dbus_bus: MessageBus):
"""Test initialize for reusing connected dbus object."""
proxy = DBusInterface()
proxy.bus_name = "org.freedesktop.UDisks2"
proxy.object_path = "/org/freedesktop/UDisks2/block_devices/sda"
assert proxy.is_connected is False
with pytest.raises(ValueError, match="must be a connected DBus object"):
await proxy.initialize(
DBus(
dbus_bus,
"org.freedesktop.UDisks2",
"/org/freedesktop/UDisks2/block_devices/sda",
)
)
with pytest.raises(
ValueError,
match="must be a DBus object connected to bus org.freedesktop.UDisks2 and object /org/freedesktop/UDisks2/block_devices/sda",
):
await proxy.initialize(
await DBus.connect(
dbus_bus, "org.freedesktop.hostname1", "/org/freedesktop/hostname1"
)
)
await proxy.initialize(
await DBus.connect(
dbus_bus,
"org.freedesktop.UDisks2",
"/org/freedesktop/UDisks2/block_devices/sda",
)
)
assert proxy.is_connected is True

View File

@ -0,0 +1 @@
"""Tests for UDisks2."""

View File

@ -0,0 +1,70 @@
"""Test UDisks2 Block Device interface."""
import asyncio
from pathlib import Path
from dbus_fast.aio.message_bus import MessageBus
import pytest
from supervisor.dbus.udisks2.block import UDisks2Block
from supervisor.dbus.udisks2.const import FormatType, PartitionTableType
from supervisor.dbus.udisks2.data import FormatOptions
from tests.common import fire_property_change_signal
async def test_block_device_info(dbus: list[str], dbus_bus: MessageBus):
"""Test block device info."""
sda = UDisks2Block("/org/freedesktop/UDisks2/block_devices/sda")
sda1 = UDisks2Block(
"/org/freedesktop/UDisks2/block_devices/sda1", sync_properties=False
)
assert sda.drive is None
assert sda.device is None
assert sda.id_label is None
assert sda.partition_table is None
assert sda1.id_label is None
assert sda1.symlinks is None
assert sda1.filesystem is None
await sda.connect(dbus_bus)
await sda1.connect(dbus_bus)
assert sda.drive == "/org/freedesktop/UDisks2/drives/SSK_SSK_Storage_DF56419883D56"
assert sda.device == Path("/dev/sda")
assert sda.id_label == ""
assert sda.partition_table.type == PartitionTableType.GPT
assert sda.filesystem is None
assert sda1.id_label == "hassos-data"
assert sda1.symlinks == [
Path("/dev/disk/by-id/usb-SSK_SSK_Storage_DF56419883D56-0:0-part1"),
Path("/dev/disk/by-label/hassos-data"),
Path("/dev/disk/by-partlabel/hassos-data-external"),
Path("/dev/disk/by-partuuid/6f3f99f4-4d34-476b-b051-77886da57fa9"),
Path(
"/dev/disk/by-path/platform-xhci-hcd.1.auto-usb-0:1.4:1.0-scsi-0:0:0:0-part1"
),
Path("/dev/disk/by-uuid/b82b23cb-0c47-4bbb-acf5-2a2afa8894a2"),
]
assert sda1.partition_table is None
assert sda1.filesystem.mount_points == []
fire_property_change_signal(sda, {"IdLabel": "test"})
await asyncio.sleep(0)
assert sda.id_label == "test"
with pytest.raises(AssertionError):
fire_property_change_signal(sda1)
async def test_format(dbus: list[str], dbus_bus: MessageBus):
"""Test formatting block device."""
sda = UDisks2Block("/org/freedesktop/UDisks2/block_devices/sda")
await sda.connect(dbus_bus)
await sda.format(FormatType.GPT, FormatOptions(label="test"))
assert dbus == [
"/org/freedesktop/UDisks2/block_devices/sda-org.freedesktop.UDisks2.Block.Format"
]

View File

@ -0,0 +1,44 @@
"""Test UDisks2 Drive."""
import asyncio
from datetime import datetime, timezone
from dbus_fast.aio.message_bus import MessageBus
from supervisor.dbus.udisks2.drive import UDisks2Drive
from tests.common import fire_property_change_signal
async def test_drive_info(dbus: list[str], dbus_bus: MessageBus):
"""Test drive info."""
ssk = UDisks2Drive("/org/freedesktop/UDisks2/drives/SSK_SSK_Storage_DF56419883D56")
assert ssk.vendor is None
assert ssk.model is None
assert ssk.size is None
assert ssk.time_detected is None
assert ssk.ejectable is None
await ssk.connect(dbus_bus)
assert ssk.vendor == "SSK"
assert ssk.model == "SSK Storage"
assert ssk.size == 250059350016
assert ssk.time_detected == datetime(2023, 2, 8, 23, 1, 44, 240492, timezone.utc)
assert ssk.ejectable is False
fire_property_change_signal(ssk, {"Ejectable": True})
await asyncio.sleep(0)
assert ssk.ejectable is True
async def test_eject(dbus: list[str], dbus_bus: MessageBus):
"""Test eject."""
flash = UDisks2Drive("/org/freedesktop/UDisks2/drives/Generic_Flash_Disk_61BCDDB6")
await flash.connect(dbus_bus)
await flash.eject()
assert dbus == [
"/org/freedesktop/UDisks2/drives/Generic_Flash_Disk_61BCDDB6-org.freedesktop.UDisks2.Drive.Eject"
]

View File

@ -0,0 +1,84 @@
"""Test UDisks2 Filesystem."""
import asyncio
from pathlib import Path
from dbus_fast.aio.message_bus import MessageBus
import pytest
from supervisor.dbus.udisks2.data import MountOptions, UnmountOptions
from supervisor.dbus.udisks2.filesystem import UDisks2Filesystem
from tests.common import fire_property_change_signal
@pytest.fixture(name="sda1")
async def fixture_sda1(dbus: list[str], dbus_bus: MessageBus) -> UDisks2Filesystem:
"""Return connected sda1 filesystem object."""
filesystem = UDisks2Filesystem("/org/freedesktop/UDisks2/block_devices/sda1")
await filesystem.connect(dbus_bus)
return filesystem
async def test_filesystem_info(dbus: list[str], dbus_bus: MessageBus):
"""Test filesystem info."""
sda1 = UDisks2Filesystem("/org/freedesktop/UDisks2/block_devices/sda1")
sdb1 = UDisks2Filesystem(
"/org/freedesktop/UDisks2/block_devices/sdb1", sync_properties=False
)
assert sda1.size is None
assert sda1.mount_points is None
assert sdb1.size is None
assert sdb1.mount_points is None
await sda1.connect(dbus_bus)
await sdb1.connect(dbus_bus)
assert sda1.size == 250058113024
assert sda1.mount_points == []
assert sdb1.size == 67108864
assert sdb1.mount_points == [Path("/mnt/data/supervisor/media/ext")]
fire_property_change_signal(
sda1, {"MountPoints": [bytearray("/mnt/media", encoding="utf-8")]}
)
await asyncio.sleep(0)
assert sda1.mount_points == [Path("/mnt/media")]
with pytest.raises(AssertionError):
fire_property_change_signal(
sdb1, {"MountPoints": [bytearray("/mnt/media", encoding="utf-8")]}
)
async def test_mount(dbus: list[str], sda1: UDisks2Filesystem):
"""Test mount."""
assert await sda1.mount(MountOptions(fstype="gpt")) == "/run/media/dev/hassos_data"
assert dbus == [
"/org/freedesktop/UDisks2/block_devices/sda1-org.freedesktop.UDisks2.Filesystem.Mount"
]
async def test_unmount(dbus: list[str], sda1: UDisks2Filesystem):
"""Test unmount."""
await sda1.unmount(UnmountOptions(force=True))
assert dbus == [
"/org/freedesktop/UDisks2/block_devices/sda1-org.freedesktop.UDisks2.Filesystem.Unmount"
]
async def test_check(dbus: list[str], sda1: UDisks2Filesystem):
"""Test check."""
assert await sda1.check() is True
assert dbus == [
"/org/freedesktop/UDisks2/block_devices/sda1-org.freedesktop.UDisks2.Filesystem.Check"
]
async def test_repair(dbus: list[str], sda1: UDisks2Filesystem):
"""Test repair."""
assert await sda1.repair() is True
assert dbus == [
"/org/freedesktop/UDisks2/block_devices/sda1-org.freedesktop.UDisks2.Filesystem.Repair"
]

View File

@ -0,0 +1,111 @@
"""Test UDisks2 Manager interface."""
import asyncio
from awesomeversion import AwesomeVersion
import pytest
from supervisor.coresys import CoreSys
from supervisor.dbus.udisks2.data import DeviceSpecification
from supervisor.exceptions import DBusNotConnectedError, DBusObjectError
from tests.common import fire_property_change_signal
async def test_udisks2_manager_info(coresys: CoreSys, dbus: list[str]):
"""Test udisks2 manager dbus connection."""
dbus.clear()
assert coresys.dbus.udisks2.supported_filesystems is None
await coresys.dbus.udisks2.connect(coresys.dbus.bus)
assert coresys.dbus.udisks2.supported_filesystems == [
"ext4",
"vfat",
"ntfs",
"exfat",
"swap",
]
assert coresys.dbus.udisks2.version == AwesomeVersion("2.9.2")
assert {block.object_path for block in coresys.dbus.udisks2.block_devices} == {
"/org/freedesktop/UDisks2/block_devices/loop0",
"/org/freedesktop/UDisks2/block_devices/mmcblk1",
"/org/freedesktop/UDisks2/block_devices/mmcblk1p1",
"/org/freedesktop/UDisks2/block_devices/mmcblk1p2",
"/org/freedesktop/UDisks2/block_devices/mmcblk1p3",
"/org/freedesktop/UDisks2/block_devices/sda",
"/org/freedesktop/UDisks2/block_devices/sda1",
"/org/freedesktop/UDisks2/block_devices/sdb",
"/org/freedesktop/UDisks2/block_devices/sdb1",
"/org/freedesktop/UDisks2/block_devices/zram1",
}
assert {drive.object_path for drive in coresys.dbus.udisks2.drives} == {
"/org/freedesktop/UDisks2/drives/BJTD4R_0x97cde291",
"/org/freedesktop/UDisks2/drives/SSK_SSK_Storage_DF56419883D56",
"/org/freedesktop/UDisks2/drives/Generic_Flash_Disk_61BCDDB6",
}
assert dbus == [
"/org/freedesktop/UDisks2/Manager-org.freedesktop.UDisks2.Manager.GetBlockDevices"
]
dbus.clear()
fire_property_change_signal(
coresys.dbus.udisks2, {"SupportedFilesystems": ["ext4"]}
)
await asyncio.sleep(0)
assert coresys.dbus.udisks2.supported_filesystems == ["ext4"]
assert dbus == []
async def test_get_block_device(coresys: CoreSys):
"""Test get block device by object path."""
with pytest.raises(DBusNotConnectedError):
coresys.dbus.udisks2.get_block_device(
"/org/freedesktop/UDisks2/block_devices/sda1"
)
await coresys.dbus.udisks2.connect(coresys.dbus.bus)
block_device = coresys.dbus.udisks2.get_block_device(
"/org/freedesktop/UDisks2/block_devices/sda1"
)
assert block_device.id_label == "hassos-data"
with pytest.raises(DBusObjectError):
coresys.dbus.udisks2.get_block_device("non_existent")
async def test_get_drive(coresys: CoreSys):
"""Test get drive by object path."""
with pytest.raises(DBusNotConnectedError):
coresys.dbus.udisks2.get_drive(
"/org/freedesktop/UDisks2/drives/BJTD4R_0x97cde291"
)
await coresys.dbus.udisks2.connect(coresys.dbus.bus)
drive = coresys.dbus.udisks2.get_drive(
"/org/freedesktop/UDisks2/drives/BJTD4R_0x97cde291"
)
assert drive.id == "BJTD4R-0x97cde291"
with pytest.raises(DBusObjectError):
coresys.dbus.udisks2.get_drive("non_existent")
async def test_resolve_device(coresys: CoreSys, dbus: list[str]):
"""Test resolve device."""
with pytest.raises(DBusNotConnectedError):
await coresys.dbus.udisks2.resolve_device(DeviceSpecification(path="/dev/sda1"))
await coresys.dbus.udisks2.connect(coresys.dbus.bus)
dbus.clear()
devices = await coresys.dbus.udisks2.resolve_device(
DeviceSpecification(path="/dev/sda1")
)
assert len(devices) == 1
assert devices[0].id_label == "hassos-data"
assert dbus == [
"/org/freedesktop/UDisks2/Manager-org.freedesktop.UDisks2.Manager.ResolveDevice"
]

View File

@ -0,0 +1,79 @@
"""Test UDisks2 Partition Table."""
import asyncio
from dbus_fast.aio.message_bus import MessageBus
import pytest
from supervisor.dbus.udisks2.const import PartitionTableType
from supervisor.dbus.udisks2.data import CreatePartitionOptions
from supervisor.dbus.udisks2.partition_table import UDisks2PartitionTable
from tests.common import fire_property_change_signal
async def test_partition_table_info(dbus: list[str], dbus_bus: MessageBus):
"""Test partition table info."""
sda = UDisks2PartitionTable("/org/freedesktop/UDisks2/block_devices/sda")
sdb = UDisks2PartitionTable(
"/org/freedesktop/UDisks2/block_devices/sdb", sync_properties=False
)
assert sda.type is None
assert sda.partitions is None
assert sdb.type is None
assert sdb.partitions is None
await sda.connect(dbus_bus)
await sdb.connect(dbus_bus)
assert sda.type == PartitionTableType.GPT
assert sda.partitions == ["/org/freedesktop/UDisks2/block_devices/sda1"]
assert sdb.type == PartitionTableType.GPT
assert sdb.partitions == ["/org/freedesktop/UDisks2/block_devices/sdb1"]
fire_property_change_signal(
sda,
{
"Partitions": [
"/org/freedesktop/UDisks2/block_devices/sda1",
"/org/freedesktop/UDisks2/block_devices/sda2",
]
},
)
await asyncio.sleep(0)
assert sda.partitions == [
"/org/freedesktop/UDisks2/block_devices/sda1",
"/org/freedesktop/UDisks2/block_devices/sda2",
]
with pytest.raises(AssertionError):
fire_property_change_signal(
sdb,
{
"MountPoints": [
"/org/freedesktop/UDisks2/block_devices/sdb",
"/org/freedesktop/UDisks2/block_devices/sdb",
]
},
)
async def test_create_partition(dbus: list[str], dbus_bus: MessageBus):
"""Test create partition."""
sda = UDisks2PartitionTable("/org/freedesktop/UDisks2/block_devices/sda")
await sda.connect(dbus_bus)
assert (
await sda.create_partition(
offset=0,
size=1000000,
type_=PartitionTableType.DOS,
name="hassos-data",
options=CreatePartitionOptions(partition_type="primary"),
)
== "/org/freedesktop/UDisks2/block_devices/sda2"
)
assert dbus == [
"/org/freedesktop/UDisks2/block_devices/sda-org.freedesktop.UDisks2.PartitionTable.CreatePartition"
]

View File

@ -0,0 +1,27 @@
{
"Device": { "_type": "ay", "_value": "/dev/loop0" },
"PreferredDevice": { "_type": "ay", "_value": "/dev/loop0" },
"Symlinks": [],
"DeviceNumber": 1792,
"Id": "",
"Size": 0,
"ReadOnly": false,
"Drive": "/",
"MDRaid": "/",
"MDRaidMember": "/",
"IdUsage": "",
"IdType": "",
"IdVersion": "",
"IdLabel": "",
"IdUUID": "",
"Configuration": [],
"CryptoBackingDevice": "/",
"HintPartitionable": true,
"HintSystem": true,
"HintIgnore": false,
"HintAuto": false,
"HintName": "",
"HintIconName": "",
"HintSymbolicIconName": "",
"UserspaceMountOptions": []
}

View File

@ -0,0 +1,33 @@
{
"Device": { "_type": "ay", "_value": "/dev/mmcblk1" },
"PreferredDevice": { "_type": "ay", "_value": "/dev/mmcblk1" },
"Symlinks": {
"_type": "aay",
"_value": [
"/dev/disk/by-id/mmc-BJTD4R_0x97cde291",
"/dev/disk/by-path/platform-ffe07000.mmc"
]
},
"DeviceNumber": 45824,
"Id": "by-id-mmc-BJTD4R_0x97cde291",
"Size": 31268536320,
"ReadOnly": false,
"Drive": "/org/freedesktop/UDisks2/drives/BJTD4R_0x97cde291",
"MDRaid": "/",
"MDRaidMember": "/",
"IdUsage": "",
"IdType": "",
"IdVersion": "",
"IdLabel": "",
"IdUUID": "",
"Configuration": [],
"CryptoBackingDevice": "/",
"HintPartitionable": true,
"HintSystem": true,
"HintIgnore": false,
"HintAuto": false,
"HintName": "",
"HintIconName": "",
"HintSymbolicIconName": "",
"UserspaceMountOptions": []
}

View File

@ -0,0 +1,37 @@
{
"Device": { "_type": "ay", "_value": "/dev/mmcblk1p1" },
"PreferredDevice": { "_type": "ay", "_value": "/dev/mmcblk1p1" },
"Symlinks": {
"_type": "aay",
"_value": [
"/dev/disk/by-id/mmc-BJTD4R_0x97cde291-part1",
"/dev/disk/by-label/hassos-boot",
"/dev/disk/by-partlabel/hassos-boot",
"/dev/disk/by-partuuid/48617373-01",
"/dev/disk/by-path/platform-ffe07000.mmc-part1",
"/dev/disk/by-uuid/16DD-EED4"
]
},
"DeviceNumber": 45825,
"Id": "by-id-mmc-BJTD4R_0x97cde291-part1",
"Size": 25165824,
"ReadOnly": false,
"Drive": "/org/freedesktop/UDisks2/drives/BJTD4R_0x97cde291",
"MDRaid": "/",
"MDRaidMember": "/",
"IdUsage": "filesystem",
"IdType": "vfat",
"IdVersion": "FAT16",
"IdLabel": "hassos-boot",
"IdUUID": "16DD-EED4",
"Configuration": [],
"CryptoBackingDevice": "/",
"HintPartitionable": true,
"HintSystem": true,
"HintIgnore": false,
"HintAuto": false,
"HintName": "",
"HintIconName": "",
"HintSymbolicIconName": "",
"UserspaceMountOptions": []
}

View File

@ -0,0 +1,34 @@
{
"Device": { "_type": "ay", "_value": "/dev/mmcblk1p2" },
"PreferredDevice": { "_type": "ay", "_value": "/dev/mmcblk1p2" },
"Symlinks": {
"_type": "aay",
"_value": [
"/dev/disk/by-id/mmc-BJTD4R_0x97cde291-part2",
"/dev/disk/by-partuuid/48617373-02",
"/dev/disk/by-path/platform-ffe07000.mmc-part2"
]
},
"DeviceNumber": 45826,
"Id": "by-id-mmc-BJTD4R_0x97cde291-part2",
"Size": 1024,
"ReadOnly": false,
"Drive": "/org/freedesktop/UDisks2/drives/BJTD4R_0x97cde291",
"MDRaid": "/",
"MDRaidMember": "/",
"IdUsage": "",
"IdType": "",
"IdVersion": "",
"IdLabel": "",
"IdUUID": "",
"Configuration": [],
"CryptoBackingDevice": "/",
"HintPartitionable": true,
"HintSystem": true,
"HintIgnore": false,
"HintAuto": false,
"HintName": "",
"HintIconName": "",
"HintSymbolicIconName": "",
"UserspaceMountOptions": []
}

View File

@ -0,0 +1,36 @@
{
"Device": { "_type": "ay", "_value": "/dev/mmcblk1p3" },
"PreferredDevice": { "_type": "ay", "_value": "/dev/mmcblk1p3" },
"Symlinks": {
"_type": "aay",
"_value": [
"/dev/disk/by-id/mmc-BJTD4R_0x97cde291-part3",
"/dev/disk/by-label/hassos-overlay",
"/dev/disk/by-partuuid/48617373-03",
"/dev/disk/by-path/platform-ffe07000.mmc-part3",
"/dev/disk/by-uuid/0cd0d026-8c69-484e-bbf1-8197019fa7df"
]
},
"DeviceNumber": 45827,
"Id": "by-id-mmc-BJTD4R_0x97cde291-part3",
"Size": 100663296,
"ReadOnly": false,
"Drive": "/org/freedesktop/UDisks2/drives/BJTD4R_0x97cde291",
"MDRaid": "/",
"MDRaidMember": "/",
"IdUsage": "filesystem",
"IdType": "ext4",
"IdVersion": "1.0",
"IdLabel": "hassos-overlay",
"IdUUID": "0cd0d026-8c69-484e-bbf1-8197019fa7df",
"Configuration": [],
"CryptoBackingDevice": "/",
"HintPartitionable": true,
"HintSystem": true,
"HintIgnore": false,
"HintAuto": false,
"HintName": "",
"HintIconName": "",
"HintSymbolicIconName": "",
"UserspaceMountOptions": []
}

View File

@ -0,0 +1,39 @@
{
"Device": {
"_type": "ay",
"_value": "/dev/sda"
},
"PreferredDevice": {
"_type": "ay",
"_value": "/dev/sda"
},
"Symlinks": {
"_type": "aay",
"_value": [
"/dev/disk/by-id/usb-SSK_SSK_Storage_DF56419883D56-0:0",
"/dev/disk/by-path/platform-xhci-hcd.1.auto-usb-0:1.4:1.0-scsi-0:0:0:0"
]
},
"DeviceNumber": 2048,
"Id": "by-id-usb-SSK_SSK_Storage_DF56419883D56-0:0",
"Size": 250059350016,
"ReadOnly": false,
"Drive": "/org/freedesktop/UDisks2/drives/SSK_SSK_Storage_DF56419883D56",
"MDRaid": "/",
"MDRaidMember": "/",
"IdUsage": "",
"IdType": "",
"IdVersion": "",
"IdLabel": "",
"IdUUID": "",
"Configuration": [],
"CryptoBackingDevice": "/",
"HintPartitionable": true,
"HintSystem": false,
"HintIgnore": false,
"HintAuto": true,
"HintName": "",
"HintIconName": "",
"HintSymbolicIconName": "",
"UserspaceMountOptions": []
}

View File

@ -0,0 +1,37 @@
{
"Device": { "_type": "ay", "_value": "/dev/sda1" },
"PreferredDevice": { "_type": "ay", "_value": "/dev/sda1" },
"Symlinks": {
"_type": "aay",
"_value": [
"/dev/disk/by-id/usb-SSK_SSK_Storage_DF56419883D56-0:0-part1",
"/dev/disk/by-label/hassos-data",
"/dev/disk/by-partlabel/hassos-data-external",
"/dev/disk/by-partuuid/6f3f99f4-4d34-476b-b051-77886da57fa9",
"/dev/disk/by-path/platform-xhci-hcd.1.auto-usb-0:1.4:1.0-scsi-0:0:0:0-part1",
"/dev/disk/by-uuid/b82b23cb-0c47-4bbb-acf5-2a2afa8894a2"
]
},
"DeviceNumber": 2049,
"Id": "by-id-usb-SSK_SSK_Storage_DF56419883D56-0:0-part1",
"Size": 250058113024,
"ReadOnly": false,
"Drive": "/org/freedesktop/UDisks2/drives/SSK_SSK_Storage_DF56419883D56",
"MDRaid": "/",
"MDRaidMember": "/",
"IdUsage": "filesystem",
"IdType": "ext4",
"IdVersion": "1.0",
"IdLabel": "hassos-data",
"IdUUID": "b82b23cb-0c47-4bbb-acf5-2a2afa8894a2",
"Configuration": [],
"CryptoBackingDevice": "/",
"HintPartitionable": true,
"HintSystem": false,
"HintIgnore": false,
"HintAuto": true,
"HintName": "",
"HintIconName": "",
"HintSymbolicIconName": "",
"UserspaceMountOptions": []
}

View File

@ -0,0 +1,33 @@
{
"Device": { "_type": "ay", "_value": "/dev/sdb" },
"PreferredDevice": { "_type": "ay", "_value": "/dev/sdb" },
"Symlinks": {
"_type": "aay",
"_value": [
"/dev/disk/by-id/usb-Generic_Flash_Disk_61BCDDB6-0:0",
"/dev/disk/by-path/platform-xhci-hcd.1.auto-usb-0:1.2:1.0-scsi-0:0:0:0"
]
},
"DeviceNumber": 2064,
"Id": "",
"Size": 8054112256,
"ReadOnly": false,
"Drive": "/org/freedesktop/UDisks2/drives/Generic_Flash_Disk_61BCDDB6",
"MDRaid": "/",
"MDRaidMember": "/",
"IdUsage": "",
"IdType": "",
"IdVersion": "",
"IdLabel": "",
"IdUUID": "",
"Configuration": [],
"CryptoBackingDevice": "/",
"HintPartitionable": true,
"HintSystem": false,
"HintIgnore": false,
"HintAuto": true,
"HintName": "",
"HintIconName": "",
"HintSymbolicIconName": "",
"UserspaceMountOptions": []
}

View File

@ -0,0 +1,34 @@
{
"Device": { "_type": "ay", "_value": "/dev/sdb1" },
"PreferredDevice": { "_type": "ay", "_value": "/dev/sdb1" },
"Symlinks": {
"_type": "aay",
"_value": [
"/dev/disk/by-id/usb-Generic_Flash_Disk_61BCDDB6-0:0-part1",
"/dev/disk/by-path/platform-xhci-hcd.1.auto-usb-0:1.2:1.0-scsi-0:0:0:0-part1",
"/dev/disk/by-uuid/2802-1EDE"
]
},
"DeviceNumber": 2065,
"Id": "by-uuid-2802-1EDE",
"Size": 67108864,
"ReadOnly": false,
"Drive": "/org/freedesktop/UDisks2/drives/Generic_Flash_Disk_61BCDDB6",
"MDRaid": "/",
"MDRaidMember": "/",
"IdUsage": "filesystem",
"IdType": "vfat",
"IdVersion": "FAT16",
"IdLabel": "",
"IdUUID": "2802-1EDE",
"Configuration": [],
"CryptoBackingDevice": "/",
"HintPartitionable": true,
"HintSystem": false,
"HintIgnore": false,
"HintAuto": true,
"HintName": "",
"HintIconName": "",
"HintSymbolicIconName": "",
"UserspaceMountOptions": []
}

View File

@ -0,0 +1,27 @@
{
"Device": { "_type": "ay", "_value": "/dev/zram1" },
"PreferredDevice": { "_type": "ay", "_value": "/dev/zram1" },
"Symlinks": [],
"DeviceNumber": 64769,
"Id": "",
"Size": 33554432,
"ReadOnly": false,
"Drive": "/",
"MDRaid": "/",
"MDRaidMember": "/",
"IdUsage": "",
"IdType": "",
"IdVersion": "",
"IdLabel": "",
"IdUUID": "",
"Configuration": [],
"CryptoBackingDevice": "/",
"HintPartitionable": true,
"HintSystem": true,
"HintIgnore": false,
"HintAuto": false,
"HintName": "",
"HintIconName": "",
"HintSymbolicIconName": "",
"UserspaceMountOptions": []
}

View File

@ -0,0 +1,31 @@
{
"Vendor": "",
"Model": "BJTD4R",
"Revision": "",
"Serial": "0x97cde291",
"WWN": "",
"Id": "BJTD4R-0x97cde291",
"Configuration": {},
"Media": "flash_mmc",
"MediaCompatibility": ["flash_mmc"],
"MediaRemovable": false,
"MediaAvailable": true,
"MediaChangeDetected": true,
"Size": 31268536320,
"TimeDetected": 1673981760067475,
"TimeMediaDetected": 1673981760067475,
"Optical": false,
"OpticalBlank": false,
"OpticalNumTracks": 0,
"OpticalNumAudioTracks": 0,
"OpticalNumDataTracks": 0,
"OpticalNumSessions": 0,
"RotationRate": 0,
"ConnectionBus": "sdio",
"Seat": "seat0",
"Removable": false,
"Ejectable": false,
"SortKey": "00coldplug/00fixed/mmcblk1",
"CanPowerOff": false,
"SiblingId": ""
}

View File

@ -0,0 +1,31 @@
{
"Vendor": "Generic",
"Model": "Flash Disk",
"Revision": "8.07",
"Serial": "61BCDDB6",
"WWN": "",
"Id": "Generic-Flash-Disk-61BCDDB6",
"Configuration": {},
"Media": "",
"MediaCompatibility": [],
"MediaRemovable": true,
"MediaAvailable": true,
"MediaChangeDetected": true,
"Size": 8054112256,
"TimeDetected": 1675972756688073,
"TimeMediaDetected": 1675972756688073,
"Optical": false,
"OpticalBlank": false,
"OpticalNumTracks": 0,
"OpticalNumAudioTracks": 0,
"OpticalNumDataTracks": 0,
"OpticalNumSessions": 0,
"RotationRate": -1,
"ConnectionBus": "usb",
"Seat": "seat0",
"Removable": true,
"Ejectable": true,
"SortKey": "01hotplug/1675972756688073",
"CanPowerOff": true,
"SiblingId": "/sys/devices/platform/soc/ffe09000.usb/ff500000.usb/xhci-hcd.1.auto/usb1/1-1/1-1.2/1-1.2:1.0"
}

View File

@ -0,0 +1,31 @@
{
"Vendor": "SSK",
"Model": "SSK Storage",
"Revision": "0206",
"Serial": "DF56419883D56",
"WWN": "",
"Id": "SSK-SSK-Storage-DF56419883D56",
"Configuration": {},
"Media": "",
"MediaCompatibility": [],
"MediaRemovable": false,
"MediaAvailable": true,
"MediaChangeDetected": true,
"Size": 250059350016,
"TimeDetected": 1675897304240492,
"TimeMediaDetected": 1675897304240492,
"Optical": false,
"OpticalBlank": false,
"OpticalNumTracks": 0,
"OpticalNumAudioTracks": 0,
"OpticalNumDataTracks": 0,
"OpticalNumSessions": 0,
"RotationRate": 0,
"ConnectionBus": "usb",
"Seat": "seat0",
"Removable": true,
"Ejectable": false,
"SortKey": "01hotplug/1675897304240492",
"CanPowerOff": true,
"SiblingId": "/sys/devices/platform/soc/ffe09000.usb/ff500000.usb/xhci-hcd.1.auto/usb2/2-1/2-1.4/2-1.4:1.0"
}

View File

@ -0,0 +1 @@
{ "MountPoints": { "_type": "aay", "_value": ["/mnt/boot"] }, "Size": 0 }

View File

@ -0,0 +1,22 @@
{
"MountPoints": {
"_type": "aay",
"_value": [
"/etc/NetworkManager/system-connections",
"/etc/dropbear",
"/etc/hostname",
"/etc/hosts",
"/etc/modprobe.d",
"/etc/modules-load.d",
"/etc/systemd/timesyncd.conf",
"/etc/udev/rules.d",
"/mnt/overlay",
"/root/.docker",
"/root/.ssh",
"/var/lib/NetworkManager",
"/var/lib/bluetooth",
"/var/lib/systemd"
]
},
"Size": 100663296
}

View File

@ -0,0 +1 @@
{ "MountPoints": [], "Size": 250058113024 }

View File

@ -0,0 +1,7 @@
{
"MountPoints": {
"_type": "aay",
"_value": ["/mnt/data/supervisor/media/ext"]
},
"Size": 67108864
}

View File

@ -0,0 +1 @@
{ "MountPoints": { "_type": "aay", "_value": ["/var"] }, "Size": 0 }

View File

@ -0,0 +1,12 @@
[
"/org/freedesktop/UDisks2/block_devices/loop0",
"/org/freedesktop/UDisks2/block_devices/mmcblk1",
"/org/freedesktop/UDisks2/block_devices/mmcblk1p1",
"/org/freedesktop/UDisks2/block_devices/mmcblk1p2",
"/org/freedesktop/UDisks2/block_devices/mmcblk1p3",
"/org/freedesktop/UDisks2/block_devices/sda",
"/org/freedesktop/UDisks2/block_devices/sda1",
"/org/freedesktop/UDisks2/block_devices/sdb",
"/org/freedesktop/UDisks2/block_devices/sdb1",
"/org/freedesktop/UDisks2/block_devices/zram1"
]

View File

@ -0,0 +1 @@
["/org/freedesktop/UDisks2/block_devices/sda1"]

View File

@ -0,0 +1,6 @@
{
"Version": "2.9.2",
"SupportedFilesystems": ["ext4", "vfat", "ntfs", "exfat", "swap"],
"SupportedEncryptionTypes": ["luks1", "luks2"],
"DefaultEncryptionType": "luks1"
}

View File

@ -0,0 +1,89 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- GDBus 2.70.4 -->
<node>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="out"/>
</method>
<method name="GetAll">
<arg type="s" name="interface_name" direction="in"/>
<arg type="a{sv}" name="properties" direction="out"/>
</method>
<method name="Set">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="in"/>
</method>
<signal name="PropertiesChanged">
<arg type="s" name="interface_name"/>
<arg type="a{sv}" name="changed_properties"/>
<arg type="as" name="invalidated_properties"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" name="xml_data" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping"/>
<method name="GetMachineId">
<arg type="s" name="machine_uuid" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.UDisks2.Manager">
<method name="CanFormat">
<arg type="s" name="type" direction="in"/>
<arg type="(bs)" name="available" direction="out"/>
</method>
<method name="CanResize">
<arg type="s" name="type" direction="in"/>
<arg type="(bts)" name="available" direction="out"/>
</method>
<method name="CanCheck">
<arg type="s" name="type" direction="in"/>
<arg type="(bs)" name="available" direction="out"/>
</method>
<method name="CanRepair">
<arg type="s" name="type" direction="in"/>
<arg type="(bs)" name="available" direction="out"/>
</method>
<method name="LoopSetup">
<arg type="h" name="fd" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="o" name="resulting_device" direction="out"/>
</method>
<method name="MDRaidCreate">
<arg type="ao" name="blocks" direction="in"/>
<arg type="s" name="level" direction="in"/>
<arg type="s" name="name" direction="in"/>
<arg type="t" name="chunk" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="o" name="resulting_array" direction="out"/>
</method>
<method name="EnableModules">
<annotation name="org.freedesktop.DBus.Deprecated" value="true"/>
<arg type="b" name="enable" direction="in"/>
</method>
<method name="EnableModule">
<arg type="s" name="name" direction="in"/>
<arg type="b" name="enable" direction="in"/>
</method>
<method name="GetBlockDevices">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="ao" name="block_objects" direction="out"/>
</method>
<method name="ResolveDevice">
<arg type="a{sv}" name="devspec" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="ao" name="devices" direction="out"/>
</method>
<property type="s" name="Version" access="read"/>
<property type="as" name="SupportedFilesystems" access="read"/>
<property type="as" name="SupportedEncryptionTypes" access="read"/>
<property type="s" name="DefaultEncryptionType" access="read"/>
</interface>
</node>

View File

@ -0,0 +1,8 @@
{
"Partitions": [
"/org/freedesktop/UDisks2/block_devices/mmcblk1p1",
"/org/freedesktop/UDisks2/block_devices/mmcblk1p2",
"/org/freedesktop/UDisks2/block_devices/mmcblk1p3"
],
"Type": "dos"
}

View File

@ -0,0 +1,4 @@
{
"Partitions": ["/org/freedesktop/UDisks2/block_devices/sda1"],
"Type": "gpt"
}

View File

@ -0,0 +1,4 @@
{
"Partitions": ["/org/freedesktop/UDisks2/block_devices/sdb1"],
"Type": "gpt"
}

View File

@ -0,0 +1,117 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- GDBus 2.70.4 -->
<node>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="out"/>
</method>
<method name="GetAll">
<arg type="s" name="interface_name" direction="in"/>
<arg type="a{sv}" name="properties" direction="out"/>
</method>
<method name="Set">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="in"/>
</method>
<signal name="PropertiesChanged">
<arg type="s" name="interface_name"/>
<arg type="a{sv}" name="changed_properties"/>
<arg type="as" name="invalidated_properties"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" name="xml_data" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping"/>
<method name="GetMachineId">
<arg type="s" name="machine_uuid" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.UDisks2.Loop">
<method name="Delete">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="SetAutoclear">
<arg type="b" name="value" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="ay" name="BackingFile" access="read"/>
<property type="b" name="Autoclear" access="read"/>
<property type="u" name="SetupByUID" access="read"/>
</interface>
<interface name="org.freedesktop.UDisks2.Block">
<method name="AddConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="RemoveConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="UpdateConfigurationItem">
<arg type="(sa{sv})" name="old_item" direction="in"/>
<arg type="(sa{sv})" name="new_item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="GetSecretConfiguration">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="a(sa{sv})" name="configuration" direction="out"/>
</method>
<method name="Format">
<arg type="s" name="type" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="OpenForBackup">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForRestore">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForBenchmark">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenDevice">
<arg type="s" name="mode" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="Rescan">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="ay" name="Device" access="read"/>
<property type="ay" name="PreferredDevice" access="read"/>
<property type="aay" name="Symlinks" access="read"/>
<property type="t" name="DeviceNumber" access="read"/>
<property type="s" name="Id" access="read"/>
<property type="t" name="Size" access="read"/>
<property type="b" name="ReadOnly" access="read"/>
<property type="o" name="Drive" access="read"/>
<property type="o" name="MDRaid" access="read"/>
<property type="o" name="MDRaidMember" access="read"/>
<property type="s" name="IdUsage" access="read"/>
<property type="s" name="IdType" access="read"/>
<property type="s" name="IdVersion" access="read"/>
<property type="s" name="IdLabel" access="read"/>
<property type="s" name="IdUUID" access="read"/>
<property type="a(sa{sv})" name="Configuration" access="read"/>
<property type="o" name="CryptoBackingDevice" access="read"/>
<property type="b" name="HintPartitionable" access="read"/>
<property type="b" name="HintSystem" access="read"/>
<property type="b" name="HintIgnore" access="read"/>
<property type="b" name="HintAuto" access="read"/>
<property type="s" name="HintName" access="read"/>
<property type="s" name="HintIconName" access="read"/>
<property type="s" name="HintSymbolicIconName" access="read"/>
<property type="as" name="UserspaceMountOptions" access="read"/>
</interface>
</node>

View File

@ -0,0 +1,127 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- GDBus 2.70.4 -->
<node>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="out"/>
</method>
<method name="GetAll">
<arg type="s" name="interface_name" direction="in"/>
<arg type="a{sv}" name="properties" direction="out"/>
</method>
<method name="Set">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="in"/>
</method>
<signal name="PropertiesChanged">
<arg type="s" name="interface_name"/>
<arg type="a{sv}" name="changed_properties"/>
<arg type="as" name="invalidated_properties"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" name="xml_data" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping"/>
<method name="GetMachineId">
<arg type="s" name="machine_uuid" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.UDisks2.PartitionTable">
<method name="CreatePartition">
<arg type="t" name="offset" direction="in"/>
<arg type="t" name="size" direction="in"/>
<arg type="s" name="type" direction="in"/>
<arg type="s" name="name" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="o" name="created_partition" direction="out"/>
</method>
<method name="CreatePartitionAndFormat">
<arg type="t" name="offset" direction="in"/>
<arg type="t" name="size" direction="in"/>
<arg type="s" name="type" direction="in"/>
<arg type="s" name="name" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="s" name="format_type" direction="in"/>
<arg type="a{sv}" name="format_options" direction="in"/>
<arg type="o" name="created_partition" direction="out"/>
</method>
<property type="ao" name="Partitions" access="read"/>
<property type="s" name="Type" access="read"/>
</interface>
<interface name="org.freedesktop.UDisks2.Block">
<method name="AddConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="RemoveConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="UpdateConfigurationItem">
<arg type="(sa{sv})" name="old_item" direction="in"/>
<arg type="(sa{sv})" name="new_item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="GetSecretConfiguration">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="a(sa{sv})" name="configuration" direction="out"/>
</method>
<method name="Format">
<arg type="s" name="type" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="OpenForBackup">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForRestore">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForBenchmark">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenDevice">
<arg type="s" name="mode" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="Rescan">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="ay" name="Device" access="read"/>
<property type="ay" name="PreferredDevice" access="read"/>
<property type="aay" name="Symlinks" access="read"/>
<property type="t" name="DeviceNumber" access="read"/>
<property type="s" name="Id" access="read"/>
<property type="t" name="Size" access="read"/>
<property type="b" name="ReadOnly" access="read"/>
<property type="o" name="Drive" access="read"/>
<property type="o" name="MDRaid" access="read"/>
<property type="o" name="MDRaidMember" access="read"/>
<property type="s" name="IdUsage" access="read"/>
<property type="s" name="IdType" access="read"/>
<property type="s" name="IdVersion" access="read"/>
<property type="s" name="IdLabel" access="read"/>
<property type="s" name="IdUUID" access="read"/>
<property type="a(sa{sv})" name="Configuration" access="read"/>
<property type="o" name="CryptoBackingDevice" access="read"/>
<property type="b" name="HintPartitionable" access="read"/>
<property type="b" name="HintSystem" access="read"/>
<property type="b" name="HintIgnore" access="read"/>
<property type="b" name="HintAuto" access="read"/>
<property type="s" name="HintName" access="read"/>
<property type="s" name="HintIconName" access="read"/>
<property type="s" name="HintSymbolicIconName" access="read"/>
<property type="as" name="UserspaceMountOptions" access="read"/>
</interface>
</node>

View File

@ -0,0 +1,166 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- GDBus 2.70.4 -->
<node>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="out"/>
</method>
<method name="GetAll">
<arg type="s" name="interface_name" direction="in"/>
<arg type="a{sv}" name="properties" direction="out"/>
</method>
<method name="Set">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="in"/>
</method>
<signal name="PropertiesChanged">
<arg type="s" name="interface_name"/>
<arg type="a{sv}" name="changed_properties"/>
<arg type="as" name="invalidated_properties"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" name="xml_data" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping"/>
<method name="GetMachineId">
<arg type="s" name="machine_uuid" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.UDisks2.Filesystem">
<method name="SetLabel">
<arg type="s" name="label" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Mount">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="s" name="mount_path" direction="out"/>
</method>
<method name="Unmount">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Resize">
<arg type="t" name="size" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Check">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="b" name="consistent" direction="out"/>
</method>
<method name="Repair">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="b" name="repaired" direction="out"/>
</method>
<method name="TakeOwnership">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="aay" name="MountPoints" access="read"/>
<property type="t" name="Size" access="read"/>
</interface>
<interface name="org.freedesktop.UDisks2.Partition">
<method name="SetType">
<arg type="s" name="type" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="SetName">
<arg type="s" name="name" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="SetFlags">
<arg type="t" name="flags" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Resize">
<arg type="t" name="size" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Delete">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="u" name="Number" access="read"/>
<property type="s" name="Type" access="read"/>
<property type="t" name="Flags" access="read"/>
<property type="t" name="Offset" access="read"/>
<property type="t" name="Size" access="read"/>
<property type="s" name="Name" access="read"/>
<property type="s" name="UUID" access="read"/>
<property type="o" name="Table" access="read"/>
<property type="b" name="IsContainer" access="read"/>
<property type="b" name="IsContained" access="read"/>
</interface>
<interface name="org.freedesktop.UDisks2.Block">
<method name="AddConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="RemoveConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="UpdateConfigurationItem">
<arg type="(sa{sv})" name="old_item" direction="in"/>
<arg type="(sa{sv})" name="new_item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="GetSecretConfiguration">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="a(sa{sv})" name="configuration" direction="out"/>
</method>
<method name="Format">
<arg type="s" name="type" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="OpenForBackup">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForRestore">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForBenchmark">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenDevice">
<arg type="s" name="mode" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="Rescan">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="ay" name="Device" access="read"/>
<property type="ay" name="PreferredDevice" access="read"/>
<property type="aay" name="Symlinks" access="read"/>
<property type="t" name="DeviceNumber" access="read"/>
<property type="s" name="Id" access="read"/>
<property type="t" name="Size" access="read"/>
<property type="b" name="ReadOnly" access="read"/>
<property type="o" name="Drive" access="read"/>
<property type="o" name="MDRaid" access="read"/>
<property type="o" name="MDRaidMember" access="read"/>
<property type="s" name="IdUsage" access="read"/>
<property type="s" name="IdType" access="read"/>
<property type="s" name="IdVersion" access="read"/>
<property type="s" name="IdLabel" access="read"/>
<property type="s" name="IdUUID" access="read"/>
<property type="a(sa{sv})" name="Configuration" access="read"/>
<property type="o" name="CryptoBackingDevice" access="read"/>
<property type="b" name="HintPartitionable" access="read"/>
<property type="b" name="HintSystem" access="read"/>
<property type="b" name="HintIgnore" access="read"/>
<property type="b" name="HintAuto" access="read"/>
<property type="s" name="HintName" access="read"/>
<property type="s" name="HintIconName" access="read"/>
<property type="s" name="HintSymbolicIconName" access="read"/>
<property type="as" name="UserspaceMountOptions" access="read"/>
</interface>
</node>

View File

@ -0,0 +1,136 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- GDBus 2.70.4 -->
<node>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="out"/>
</method>
<method name="GetAll">
<arg type="s" name="interface_name" direction="in"/>
<arg type="a{sv}" name="properties" direction="out"/>
</method>
<method name="Set">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="in"/>
</method>
<signal name="PropertiesChanged">
<arg type="s" name="interface_name"/>
<arg type="a{sv}" name="changed_properties"/>
<arg type="as" name="invalidated_properties"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" name="xml_data" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping"/>
<method name="GetMachineId">
<arg type="s" name="machine_uuid" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.UDisks2.Partition">
<method name="SetType">
<arg type="s" name="type" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="SetName">
<arg type="s" name="name" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="SetFlags">
<arg type="t" name="flags" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Resize">
<arg type="t" name="size" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Delete">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="u" name="Number" access="read"/>
<property type="s" name="Type" access="read"/>
<property type="t" name="Flags" access="read"/>
<property type="t" name="Offset" access="read"/>
<property type="t" name="Size" access="read"/>
<property type="s" name="Name" access="read"/>
<property type="s" name="UUID" access="read"/>
<property type="o" name="Table" access="read"/>
<property type="b" name="IsContainer" access="read"/>
<property type="b" name="IsContained" access="read"/>
</interface>
<interface name="org.freedesktop.UDisks2.Block">
<method name="AddConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="RemoveConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="UpdateConfigurationItem">
<arg type="(sa{sv})" name="old_item" direction="in"/>
<arg type="(sa{sv})" name="new_item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="GetSecretConfiguration">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="a(sa{sv})" name="configuration" direction="out"/>
</method>
<method name="Format">
<arg type="s" name="type" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="OpenForBackup">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForRestore">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForBenchmark">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenDevice">
<arg type="s" name="mode" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="Rescan">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="ay" name="Device" access="read"/>
<property type="ay" name="PreferredDevice" access="read"/>
<property type="aay" name="Symlinks" access="read"/>
<property type="t" name="DeviceNumber" access="read"/>
<property type="s" name="Id" access="read"/>
<property type="t" name="Size" access="read"/>
<property type="b" name="ReadOnly" access="read"/>
<property type="o" name="Drive" access="read"/>
<property type="o" name="MDRaid" access="read"/>
<property type="o" name="MDRaidMember" access="read"/>
<property type="s" name="IdUsage" access="read"/>
<property type="s" name="IdType" access="read"/>
<property type="s" name="IdVersion" access="read"/>
<property type="s" name="IdLabel" access="read"/>
<property type="s" name="IdUUID" access="read"/>
<property type="a(sa{sv})" name="Configuration" access="read"/>
<property type="o" name="CryptoBackingDevice" access="read"/>
<property type="b" name="HintPartitionable" access="read"/>
<property type="b" name="HintSystem" access="read"/>
<property type="b" name="HintIgnore" access="read"/>
<property type="b" name="HintAuto" access="read"/>
<property type="s" name="HintName" access="read"/>
<property type="s" name="HintIconName" access="read"/>
<property type="s" name="HintSymbolicIconName" access="read"/>
<property type="as" name="UserspaceMountOptions" access="read"/>
</interface>
</node>

View File

@ -0,0 +1,166 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- GDBus 2.70.4 -->
<node>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="out"/>
</method>
<method name="GetAll">
<arg type="s" name="interface_name" direction="in"/>
<arg type="a{sv}" name="properties" direction="out"/>
</method>
<method name="Set">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="in"/>
</method>
<signal name="PropertiesChanged">
<arg type="s" name="interface_name"/>
<arg type="a{sv}" name="changed_properties"/>
<arg type="as" name="invalidated_properties"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" name="xml_data" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping"/>
<method name="GetMachineId">
<arg type="s" name="machine_uuid" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.UDisks2.Filesystem">
<method name="SetLabel">
<arg type="s" name="label" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Mount">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="s" name="mount_path" direction="out"/>
</method>
<method name="Unmount">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Resize">
<arg type="t" name="size" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Check">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="b" name="consistent" direction="out"/>
</method>
<method name="Repair">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="b" name="repaired" direction="out"/>
</method>
<method name="TakeOwnership">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="aay" name="MountPoints" access="read"/>
<property type="t" name="Size" access="read"/>
</interface>
<interface name="org.freedesktop.UDisks2.Partition">
<method name="SetType">
<arg type="s" name="type" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="SetName">
<arg type="s" name="name" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="SetFlags">
<arg type="t" name="flags" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Resize">
<arg type="t" name="size" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Delete">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="u" name="Number" access="read"/>
<property type="s" name="Type" access="read"/>
<property type="t" name="Flags" access="read"/>
<property type="t" name="Offset" access="read"/>
<property type="t" name="Size" access="read"/>
<property type="s" name="Name" access="read"/>
<property type="s" name="UUID" access="read"/>
<property type="o" name="Table" access="read"/>
<property type="b" name="IsContainer" access="read"/>
<property type="b" name="IsContained" access="read"/>
</interface>
<interface name="org.freedesktop.UDisks2.Block">
<method name="AddConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="RemoveConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="UpdateConfigurationItem">
<arg type="(sa{sv})" name="old_item" direction="in"/>
<arg type="(sa{sv})" name="new_item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="GetSecretConfiguration">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="a(sa{sv})" name="configuration" direction="out"/>
</method>
<method name="Format">
<arg type="s" name="type" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="OpenForBackup">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForRestore">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForBenchmark">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenDevice">
<arg type="s" name="mode" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="Rescan">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="ay" name="Device" access="read"/>
<property type="ay" name="PreferredDevice" access="read"/>
<property type="aay" name="Symlinks" access="read"/>
<property type="t" name="DeviceNumber" access="read"/>
<property type="s" name="Id" access="read"/>
<property type="t" name="Size" access="read"/>
<property type="b" name="ReadOnly" access="read"/>
<property type="o" name="Drive" access="read"/>
<property type="o" name="MDRaid" access="read"/>
<property type="o" name="MDRaidMember" access="read"/>
<property type="s" name="IdUsage" access="read"/>
<property type="s" name="IdType" access="read"/>
<property type="s" name="IdVersion" access="read"/>
<property type="s" name="IdLabel" access="read"/>
<property type="s" name="IdUUID" access="read"/>
<property type="a(sa{sv})" name="Configuration" access="read"/>
<property type="o" name="CryptoBackingDevice" access="read"/>
<property type="b" name="HintPartitionable" access="read"/>
<property type="b" name="HintSystem" access="read"/>
<property type="b" name="HintIgnore" access="read"/>
<property type="b" name="HintAuto" access="read"/>
<property type="s" name="HintName" access="read"/>
<property type="s" name="HintIconName" access="read"/>
<property type="s" name="HintSymbolicIconName" access="read"/>
<property type="as" name="UserspaceMountOptions" access="read"/>
</interface>
</node>

View File

@ -0,0 +1 @@
"/org/freedesktop/UDisks2/block_devices/sda2"

View File

@ -0,0 +1,127 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- GDBus 2.70.4 -->
<node>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="out"/>
</method>
<method name="GetAll">
<arg type="s" name="interface_name" direction="in"/>
<arg type="a{sv}" name="properties" direction="out"/>
</method>
<method name="Set">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="in"/>
</method>
<signal name="PropertiesChanged">
<arg type="s" name="interface_name"/>
<arg type="a{sv}" name="changed_properties"/>
<arg type="as" name="invalidated_properties"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" name="xml_data" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping"/>
<method name="GetMachineId">
<arg type="s" name="machine_uuid" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.UDisks2.PartitionTable">
<method name="CreatePartition">
<arg type="t" name="offset" direction="in"/>
<arg type="t" name="size" direction="in"/>
<arg type="s" name="type" direction="in"/>
<arg type="s" name="name" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="o" name="created_partition" direction="out"/>
</method>
<method name="CreatePartitionAndFormat">
<arg type="t" name="offset" direction="in"/>
<arg type="t" name="size" direction="in"/>
<arg type="s" name="type" direction="in"/>
<arg type="s" name="name" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="s" name="format_type" direction="in"/>
<arg type="a{sv}" name="format_options" direction="in"/>
<arg type="o" name="created_partition" direction="out"/>
</method>
<property type="ao" name="Partitions" access="read"/>
<property type="s" name="Type" access="read"/>
</interface>
<interface name="org.freedesktop.UDisks2.Block">
<method name="AddConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="RemoveConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="UpdateConfigurationItem">
<arg type="(sa{sv})" name="old_item" direction="in"/>
<arg type="(sa{sv})" name="new_item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="GetSecretConfiguration">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="a(sa{sv})" name="configuration" direction="out"/>
</method>
<method name="Format">
<arg type="s" name="type" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="OpenForBackup">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForRestore">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForBenchmark">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenDevice">
<arg type="s" name="mode" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="Rescan">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="ay" name="Device" access="read"/>
<property type="ay" name="PreferredDevice" access="read"/>
<property type="aay" name="Symlinks" access="read"/>
<property type="t" name="DeviceNumber" access="read"/>
<property type="s" name="Id" access="read"/>
<property type="t" name="Size" access="read"/>
<property type="b" name="ReadOnly" access="read"/>
<property type="o" name="Drive" access="read"/>
<property type="o" name="MDRaid" access="read"/>
<property type="o" name="MDRaidMember" access="read"/>
<property type="s" name="IdUsage" access="read"/>
<property type="s" name="IdType" access="read"/>
<property type="s" name="IdVersion" access="read"/>
<property type="s" name="IdLabel" access="read"/>
<property type="s" name="IdUUID" access="read"/>
<property type="a(sa{sv})" name="Configuration" access="read"/>
<property type="o" name="CryptoBackingDevice" access="read"/>
<property type="b" name="HintPartitionable" access="read"/>
<property type="b" name="HintSystem" access="read"/>
<property type="b" name="HintIgnore" access="read"/>
<property type="b" name="HintAuto" access="read"/>
<property type="s" name="HintName" access="read"/>
<property type="s" name="HintIconName" access="read"/>
<property type="s" name="HintSymbolicIconName" access="read"/>
<property type="as" name="UserspaceMountOptions" access="read"/>
</interface>
</node>

View File

@ -0,0 +1 @@
true

View File

@ -0,0 +1 @@
"/run/media/dev/hassos_data"

View File

@ -0,0 +1 @@
true

View File

@ -0,0 +1,166 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- GDBus 2.70.4 -->
<node>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="out"/>
</method>
<method name="GetAll">
<arg type="s" name="interface_name" direction="in"/>
<arg type="a{sv}" name="properties" direction="out"/>
</method>
<method name="Set">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="in"/>
</method>
<signal name="PropertiesChanged">
<arg type="s" name="interface_name"/>
<arg type="a{sv}" name="changed_properties"/>
<arg type="as" name="invalidated_properties"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" name="xml_data" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping"/>
<method name="GetMachineId">
<arg type="s" name="machine_uuid" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.UDisks2.Filesystem">
<method name="SetLabel">
<arg type="s" name="label" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Mount">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="s" name="mount_path" direction="out"/>
</method>
<method name="Unmount">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Resize">
<arg type="t" name="size" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Check">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="b" name="consistent" direction="out"/>
</method>
<method name="Repair">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="b" name="repaired" direction="out"/>
</method>
<method name="TakeOwnership">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="aay" name="MountPoints" access="read"/>
<property type="t" name="Size" access="read"/>
</interface>
<interface name="org.freedesktop.UDisks2.Partition">
<method name="SetType">
<arg type="s" name="type" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="SetName">
<arg type="s" name="name" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="SetFlags">
<arg type="t" name="flags" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Resize">
<arg type="t" name="size" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Delete">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="u" name="Number" access="read"/>
<property type="s" name="Type" access="read"/>
<property type="t" name="Flags" access="read"/>
<property type="t" name="Offset" access="read"/>
<property type="t" name="Size" access="read"/>
<property type="s" name="Name" access="read"/>
<property type="s" name="UUID" access="read"/>
<property type="o" name="Table" access="read"/>
<property type="b" name="IsContainer" access="read"/>
<property type="b" name="IsContained" access="read"/>
</interface>
<interface name="org.freedesktop.UDisks2.Block">
<method name="AddConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="RemoveConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="UpdateConfigurationItem">
<arg type="(sa{sv})" name="old_item" direction="in"/>
<arg type="(sa{sv})" name="new_item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="GetSecretConfiguration">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="a(sa{sv})" name="configuration" direction="out"/>
</method>
<method name="Format">
<arg type="s" name="type" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="OpenForBackup">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForRestore">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForBenchmark">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenDevice">
<arg type="s" name="mode" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="Rescan">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="ay" name="Device" access="read"/>
<property type="ay" name="PreferredDevice" access="read"/>
<property type="aay" name="Symlinks" access="read"/>
<property type="t" name="DeviceNumber" access="read"/>
<property type="s" name="Id" access="read"/>
<property type="t" name="Size" access="read"/>
<property type="b" name="ReadOnly" access="read"/>
<property type="o" name="Drive" access="read"/>
<property type="o" name="MDRaid" access="read"/>
<property type="o" name="MDRaidMember" access="read"/>
<property type="s" name="IdUsage" access="read"/>
<property type="s" name="IdType" access="read"/>
<property type="s" name="IdVersion" access="read"/>
<property type="s" name="IdLabel" access="read"/>
<property type="s" name="IdUUID" access="read"/>
<property type="a(sa{sv})" name="Configuration" access="read"/>
<property type="o" name="CryptoBackingDevice" access="read"/>
<property type="b" name="HintPartitionable" access="read"/>
<property type="b" name="HintSystem" access="read"/>
<property type="b" name="HintIgnore" access="read"/>
<property type="b" name="HintAuto" access="read"/>
<property type="s" name="HintName" access="read"/>
<property type="s" name="HintIconName" access="read"/>
<property type="s" name="HintSymbolicIconName" access="read"/>
<property type="as" name="UserspaceMountOptions" access="read"/>
</interface>
</node>

View File

@ -0,0 +1,127 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- GDBus 2.70.4 -->
<node>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="out"/>
</method>
<method name="GetAll">
<arg type="s" name="interface_name" direction="in"/>
<arg type="a{sv}" name="properties" direction="out"/>
</method>
<method name="Set">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="in"/>
</method>
<signal name="PropertiesChanged">
<arg type="s" name="interface_name"/>
<arg type="a{sv}" name="changed_properties"/>
<arg type="as" name="invalidated_properties"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" name="xml_data" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping"/>
<method name="GetMachineId">
<arg type="s" name="machine_uuid" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.UDisks2.PartitionTable">
<method name="CreatePartition">
<arg type="t" name="offset" direction="in"/>
<arg type="t" name="size" direction="in"/>
<arg type="s" name="type" direction="in"/>
<arg type="s" name="name" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="o" name="created_partition" direction="out"/>
</method>
<method name="CreatePartitionAndFormat">
<arg type="t" name="offset" direction="in"/>
<arg type="t" name="size" direction="in"/>
<arg type="s" name="type" direction="in"/>
<arg type="s" name="name" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="s" name="format_type" direction="in"/>
<arg type="a{sv}" name="format_options" direction="in"/>
<arg type="o" name="created_partition" direction="out"/>
</method>
<property type="ao" name="Partitions" access="read"/>
<property type="s" name="Type" access="read"/>
</interface>
<interface name="org.freedesktop.UDisks2.Block">
<method name="AddConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="RemoveConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="UpdateConfigurationItem">
<arg type="(sa{sv})" name="old_item" direction="in"/>
<arg type="(sa{sv})" name="new_item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="GetSecretConfiguration">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="a(sa{sv})" name="configuration" direction="out"/>
</method>
<method name="Format">
<arg type="s" name="type" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="OpenForBackup">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForRestore">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForBenchmark">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenDevice">
<arg type="s" name="mode" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="Rescan">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="ay" name="Device" access="read"/>
<property type="ay" name="PreferredDevice" access="read"/>
<property type="aay" name="Symlinks" access="read"/>
<property type="t" name="DeviceNumber" access="read"/>
<property type="s" name="Id" access="read"/>
<property type="t" name="Size" access="read"/>
<property type="b" name="ReadOnly" access="read"/>
<property type="o" name="Drive" access="read"/>
<property type="o" name="MDRaid" access="read"/>
<property type="o" name="MDRaidMember" access="read"/>
<property type="s" name="IdUsage" access="read"/>
<property type="s" name="IdType" access="read"/>
<property type="s" name="IdVersion" access="read"/>
<property type="s" name="IdLabel" access="read"/>
<property type="s" name="IdUUID" access="read"/>
<property type="a(sa{sv})" name="Configuration" access="read"/>
<property type="o" name="CryptoBackingDevice" access="read"/>
<property type="b" name="HintPartitionable" access="read"/>
<property type="b" name="HintSystem" access="read"/>
<property type="b" name="HintIgnore" access="read"/>
<property type="b" name="HintAuto" access="read"/>
<property type="s" name="HintName" access="read"/>
<property type="s" name="HintIconName" access="read"/>
<property type="s" name="HintSymbolicIconName" access="read"/>
<property type="as" name="UserspaceMountOptions" access="read"/>
</interface>
</node>

View File

@ -0,0 +1,166 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- GDBus 2.70.4 -->
<node>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="out"/>
</method>
<method name="GetAll">
<arg type="s" name="interface_name" direction="in"/>
<arg type="a{sv}" name="properties" direction="out"/>
</method>
<method name="Set">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="in"/>
</method>
<signal name="PropertiesChanged">
<arg type="s" name="interface_name"/>
<arg type="a{sv}" name="changed_properties"/>
<arg type="as" name="invalidated_properties"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" name="xml_data" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping"/>
<method name="GetMachineId">
<arg type="s" name="machine_uuid" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.UDisks2.Filesystem">
<method name="SetLabel">
<arg type="s" name="label" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Mount">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="s" name="mount_path" direction="out"/>
</method>
<method name="Unmount">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Resize">
<arg type="t" name="size" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Check">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="b" name="consistent" direction="out"/>
</method>
<method name="Repair">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="b" name="repaired" direction="out"/>
</method>
<method name="TakeOwnership">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="aay" name="MountPoints" access="read"/>
<property type="t" name="Size" access="read"/>
</interface>
<interface name="org.freedesktop.UDisks2.Partition">
<method name="SetType">
<arg type="s" name="type" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="SetName">
<arg type="s" name="name" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="SetFlags">
<arg type="t" name="flags" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Resize">
<arg type="t" name="size" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Delete">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="u" name="Number" access="read"/>
<property type="s" name="Type" access="read"/>
<property type="t" name="Flags" access="read"/>
<property type="t" name="Offset" access="read"/>
<property type="t" name="Size" access="read"/>
<property type="s" name="Name" access="read"/>
<property type="s" name="UUID" access="read"/>
<property type="o" name="Table" access="read"/>
<property type="b" name="IsContainer" access="read"/>
<property type="b" name="IsContained" access="read"/>
</interface>
<interface name="org.freedesktop.UDisks2.Block">
<method name="AddConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="RemoveConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="UpdateConfigurationItem">
<arg type="(sa{sv})" name="old_item" direction="in"/>
<arg type="(sa{sv})" name="new_item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="GetSecretConfiguration">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="a(sa{sv})" name="configuration" direction="out"/>
</method>
<method name="Format">
<arg type="s" name="type" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="OpenForBackup">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForRestore">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForBenchmark">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenDevice">
<arg type="s" name="mode" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="Rescan">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="ay" name="Device" access="read"/>
<property type="ay" name="PreferredDevice" access="read"/>
<property type="aay" name="Symlinks" access="read"/>
<property type="t" name="DeviceNumber" access="read"/>
<property type="s" name="Id" access="read"/>
<property type="t" name="Size" access="read"/>
<property type="b" name="ReadOnly" access="read"/>
<property type="o" name="Drive" access="read"/>
<property type="o" name="MDRaid" access="read"/>
<property type="o" name="MDRaidMember" access="read"/>
<property type="s" name="IdUsage" access="read"/>
<property type="s" name="IdType" access="read"/>
<property type="s" name="IdVersion" access="read"/>
<property type="s" name="IdLabel" access="read"/>
<property type="s" name="IdUUID" access="read"/>
<property type="a(sa{sv})" name="Configuration" access="read"/>
<property type="o" name="CryptoBackingDevice" access="read"/>
<property type="b" name="HintPartitionable" access="read"/>
<property type="b" name="HintSystem" access="read"/>
<property type="b" name="HintIgnore" access="read"/>
<property type="b" name="HintAuto" access="read"/>
<property type="s" name="HintName" access="read"/>
<property type="s" name="HintIconName" access="read"/>
<property type="s" name="HintSymbolicIconName" access="read"/>
<property type="as" name="UserspaceMountOptions" access="read"/>
</interface>
</node>

View File

@ -0,0 +1,135 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- GDBus 2.70.4 -->
<node>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="out"/>
</method>
<method name="GetAll">
<arg type="s" name="interface_name" direction="in"/>
<arg type="a{sv}" name="properties" direction="out"/>
</method>
<method name="Set">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="in"/>
</method>
<signal name="PropertiesChanged">
<arg type="s" name="interface_name"/>
<arg type="a{sv}" name="changed_properties"/>
<arg type="as" name="invalidated_properties"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" name="xml_data" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping"/>
<method name="GetMachineId">
<arg type="s" name="machine_uuid" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.UDisks2.Filesystem">
<method name="SetLabel">
<arg type="s" name="label" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Mount">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="s" name="mount_path" direction="out"/>
</method>
<method name="Unmount">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Resize">
<arg type="t" name="size" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="Check">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="b" name="consistent" direction="out"/>
</method>
<method name="Repair">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="b" name="repaired" direction="out"/>
</method>
<method name="TakeOwnership">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="aay" name="MountPoints" access="read"/>
<property type="t" name="Size" access="read"/>
</interface>
<interface name="org.freedesktop.UDisks2.Block">
<method name="AddConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="RemoveConfigurationItem">
<arg type="(sa{sv})" name="item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="UpdateConfigurationItem">
<arg type="(sa{sv})" name="old_item" direction="in"/>
<arg type="(sa{sv})" name="new_item" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="GetSecretConfiguration">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="a(sa{sv})" name="configuration" direction="out"/>
</method>
<method name="Format">
<arg type="s" name="type" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="OpenForBackup">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForRestore">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenForBenchmark">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="OpenDevice">
<arg type="s" name="mode" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="h" name="fd" direction="out"/>
</method>
<method name="Rescan">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="ay" name="Device" access="read"/>
<property type="ay" name="PreferredDevice" access="read"/>
<property type="aay" name="Symlinks" access="read"/>
<property type="t" name="DeviceNumber" access="read"/>
<property type="s" name="Id" access="read"/>
<property type="t" name="Size" access="read"/>
<property type="b" name="ReadOnly" access="read"/>
<property type="o" name="Drive" access="read"/>
<property type="o" name="MDRaid" access="read"/>
<property type="o" name="MDRaidMember" access="read"/>
<property type="s" name="IdUsage" access="read"/>
<property type="s" name="IdType" access="read"/>
<property type="s" name="IdVersion" access="read"/>
<property type="s" name="IdLabel" access="read"/>
<property type="s" name="IdUUID" access="read"/>
<property type="a(sa{sv})" name="Configuration" access="read"/>
<property type="o" name="CryptoBackingDevice" access="read"/>
<property type="b" name="HintPartitionable" access="read"/>
<property type="b" name="HintSystem" access="read"/>
<property type="b" name="HintIgnore" access="read"/>
<property type="b" name="HintAuto" access="read"/>
<property type="s" name="HintName" access="read"/>
<property type="s" name="HintIconName" access="read"/>
<property type="s" name="HintSymbolicIconName" access="read"/>
<property type="as" name="UserspaceMountOptions" access="read"/>
</interface>
</node>

View File

@ -0,0 +1,78 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- GDBus 2.70.4 -->
<node>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="out"/>
</method>
<method name="GetAll">
<arg type="s" name="interface_name" direction="in"/>
<arg type="a{sv}" name="properties" direction="out"/>
</method>
<method name="Set">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="in"/>
</method>
<signal name="PropertiesChanged">
<arg type="s" name="interface_name"/>
<arg type="a{sv}" name="changed_properties"/>
<arg type="as" name="invalidated_properties"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" name="xml_data" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping"/>
<method name="GetMachineId">
<arg type="s" name="machine_uuid" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.UDisks2.Drive">
<method name="Eject">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="SetConfiguration">
<arg type="a{sv}" name="value" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="PowerOff">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="s" name="Vendor" access="read"/>
<property type="s" name="Model" access="read"/>
<property type="s" name="Revision" access="read"/>
<property type="s" name="Serial" access="read"/>
<property type="s" name="WWN" access="read"/>
<property type="s" name="Id" access="read"/>
<property type="a{sv}" name="Configuration" access="read"/>
<property type="s" name="Media" access="read"/>
<property type="as" name="MediaCompatibility" access="read"/>
<property type="b" name="MediaRemovable" access="read"/>
<property type="b" name="MediaAvailable" access="read"/>
<property type="b" name="MediaChangeDetected" access="read"/>
<property type="t" name="Size" access="read"/>
<property type="t" name="TimeDetected" access="read"/>
<property type="t" name="TimeMediaDetected" access="read"/>
<property type="b" name="Optical" access="read"/>
<property type="b" name="OpticalBlank" access="read"/>
<property type="u" name="OpticalNumTracks" access="read"/>
<property type="u" name="OpticalNumAudioTracks" access="read"/>
<property type="u" name="OpticalNumDataTracks" access="read"/>
<property type="u" name="OpticalNumSessions" access="read"/>
<property type="i" name="RotationRate" access="read"/>
<property type="s" name="ConnectionBus" access="read"/>
<property type="s" name="Seat" access="read"/>
<property type="b" name="Removable" access="read"/>
<property type="b" name="Ejectable" access="read"/>
<property type="s" name="SortKey" access="read"/>
<property type="b" name="CanPowerOff" access="read"/>
<property type="s" name="SiblingId" access="read"/>
</interface>
</node>

View File

@ -0,0 +1,78 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- GDBus 2.70.4 -->
<node>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="out"/>
</method>
<method name="GetAll">
<arg type="s" name="interface_name" direction="in"/>
<arg type="a{sv}" name="properties" direction="out"/>
</method>
<method name="Set">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="in"/>
</method>
<signal name="PropertiesChanged">
<arg type="s" name="interface_name"/>
<arg type="a{sv}" name="changed_properties"/>
<arg type="as" name="invalidated_properties"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" name="xml_data" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping"/>
<method name="GetMachineId">
<arg type="s" name="machine_uuid" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.UDisks2.Drive">
<method name="Eject">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="SetConfiguration">
<arg type="a{sv}" name="value" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="PowerOff">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="s" name="Vendor" access="read"/>
<property type="s" name="Model" access="read"/>
<property type="s" name="Revision" access="read"/>
<property type="s" name="Serial" access="read"/>
<property type="s" name="WWN" access="read"/>
<property type="s" name="Id" access="read"/>
<property type="a{sv}" name="Configuration" access="read"/>
<property type="s" name="Media" access="read"/>
<property type="as" name="MediaCompatibility" access="read"/>
<property type="b" name="MediaRemovable" access="read"/>
<property type="b" name="MediaAvailable" access="read"/>
<property type="b" name="MediaChangeDetected" access="read"/>
<property type="t" name="Size" access="read"/>
<property type="t" name="TimeDetected" access="read"/>
<property type="t" name="TimeMediaDetected" access="read"/>
<property type="b" name="Optical" access="read"/>
<property type="b" name="OpticalBlank" access="read"/>
<property type="u" name="OpticalNumTracks" access="read"/>
<property type="u" name="OpticalNumAudioTracks" access="read"/>
<property type="u" name="OpticalNumDataTracks" access="read"/>
<property type="u" name="OpticalNumSessions" access="read"/>
<property type="i" name="RotationRate" access="read"/>
<property type="s" name="ConnectionBus" access="read"/>
<property type="s" name="Seat" access="read"/>
<property type="b" name="Removable" access="read"/>
<property type="b" name="Ejectable" access="read"/>
<property type="s" name="SortKey" access="read"/>
<property type="b" name="CanPowerOff" access="read"/>
<property type="s" name="SiblingId" access="read"/>
</interface>
</node>

View File

@ -0,0 +1,78 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- GDBus 2.70.4 -->
<node>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="out"/>
</method>
<method name="GetAll">
<arg type="s" name="interface_name" direction="in"/>
<arg type="a{sv}" name="properties" direction="out"/>
</method>
<method name="Set">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="in"/>
</method>
<signal name="PropertiesChanged">
<arg type="s" name="interface_name"/>
<arg type="a{sv}" name="changed_properties"/>
<arg type="as" name="invalidated_properties"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" name="xml_data" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping"/>
<method name="GetMachineId">
<arg type="s" name="machine_uuid" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.UDisks2.Drive">
<method name="Eject">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="SetConfiguration">
<arg type="a{sv}" name="value" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
</method>
<method name="PowerOff">
<arg type="a{sv}" name="options" direction="in"/>
</method>
<property type="s" name="Vendor" access="read"/>
<property type="s" name="Model" access="read"/>
<property type="s" name="Revision" access="read"/>
<property type="s" name="Serial" access="read"/>
<property type="s" name="WWN" access="read"/>
<property type="s" name="Id" access="read"/>
<property type="a{sv}" name="Configuration" access="read"/>
<property type="s" name="Media" access="read"/>
<property type="as" name="MediaCompatibility" access="read"/>
<property type="b" name="MediaRemovable" access="read"/>
<property type="b" name="MediaAvailable" access="read"/>
<property type="b" name="MediaChangeDetected" access="read"/>
<property type="t" name="Size" access="read"/>
<property type="t" name="TimeDetected" access="read"/>
<property type="t" name="TimeMediaDetected" access="read"/>
<property type="b" name="Optical" access="read"/>
<property type="b" name="OpticalBlank" access="read"/>
<property type="u" name="OpticalNumTracks" access="read"/>
<property type="u" name="OpticalNumAudioTracks" access="read"/>
<property type="u" name="OpticalNumDataTracks" access="read"/>
<property type="u" name="OpticalNumSessions" access="read"/>
<property type="i" name="RotationRate" access="read"/>
<property type="s" name="ConnectionBus" access="read"/>
<property type="s" name="Seat" access="read"/>
<property type="b" name="Removable" access="read"/>
<property type="b" name="Ejectable" access="read"/>
<property type="s" name="SortKey" access="read"/>
<property type="b" name="CanPowerOff" access="read"/>
<property type="s" name="SiblingId" access="read"/>
</interface>
</node>

View File

@ -1,15 +1,18 @@
"""Test host manager."""
from unittest.mock import PropertyMock, patch
from awesomeversion import AwesomeVersion
import pytest
from supervisor.coresys import CoreSys
from supervisor.dbus.agent import OSAgent
from supervisor.dbus.const import MulticastProtocolEnabled
from supervisor.dbus.hostname import Hostname
from supervisor.dbus.manager import DBusManager
from supervisor.dbus.resolved import Resolved
from supervisor.dbus.systemd import Systemd
from supervisor.dbus.timedate import TimeDate
from supervisor.dbus.udisks2 import UDisks2
@pytest.fixture(name="coresys_dbus")
@ -20,13 +23,15 @@ async def fixture_coresys_dbus(
timedate: TimeDate,
os_agent: OSAgent,
resolved: Resolved,
udisks2: UDisks2,
) -> CoreSys:
"""Coresys with all dbus interfaces mock loaded."""
type(coresys.dbus).hostname = PropertyMock(return_value=hostname)
type(coresys.dbus).systemd = PropertyMock(return_value=systemd)
type(coresys.dbus).timedate = PropertyMock(return_value=timedate)
type(coresys.dbus).agent = PropertyMock(return_value=os_agent)
type(coresys.dbus).resolved = PropertyMock(return_value=resolved)
DBusManager.hostname = PropertyMock(return_value=hostname)
DBusManager.systemd = PropertyMock(return_value=systemd)
DBusManager.timedate = PropertyMock(return_value=timedate)
DBusManager.agent = PropertyMock(return_value=os_agent)
DBusManager.resolved = PropertyMock(return_value=resolved)
DBusManager.udisks2 = PropertyMock(return_value=udisks2)
yield coresys
@ -47,6 +52,7 @@ async def test_load(coresys_dbus: CoreSys, dbus: list[str]):
assert coresys.dbus.resolved.multicast_dns == MulticastProtocolEnabled.RESOLVE
assert coresys.dbus.agent.apparmor.version == "2.13.2"
assert len(coresys.host.logs.default_identifiers) > 0
assert coresys.dbus.udisks2.version == AwesomeVersion("2.9.2")
sound_update.assert_called_once()