mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-02-04 08:13:38 +00:00
storage: Use DBus directly for listing disks
Bring us closer to avoiding the use of two different methods to access UDisks DBus API: UDisks2 client library and direct DBus access with GDBus. Perform formatting of the bytes outside of udisks2 module to avoid depending on Django. Tests performed: - Visit the storage page. Disks are listed properly. - Sizes are formatted to be human readable. - Filesystem type is show properly: ext4, btrfs - Labels for disks are shown as set by tune2fs etc. - Device paths are shown properly. - Mount point is shown properly. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
parent
34a28e35c9
commit
225d86e344
@ -13,7 +13,7 @@ from django.utils.translation import ugettext_noop
|
||||
|
||||
from plinth import actions
|
||||
from plinth import app as app_module
|
||||
from plinth import cfg, glib, menu, utils
|
||||
from plinth import cfg, glib, menu
|
||||
from plinth.errors import ActionError, PlinthError
|
||||
from plinth.utils import format_lazy, import_from_gi
|
||||
|
||||
@ -77,50 +77,19 @@ def init():
|
||||
def get_disks():
|
||||
"""Returns list of disks by combining information from df and udisks."""
|
||||
disks = _get_disks_from_df()
|
||||
disks_from_udisks = _get_disks_from_udisks()
|
||||
disks_from_udisks = udisks2.get_disks()
|
||||
for disk in disks_from_udisks:
|
||||
disk['size'] = format_bytes(disk['size'])
|
||||
|
||||
# Add info from udisks to the disks from df based on mount point.
|
||||
for disk_from_df in disks:
|
||||
for disk_from_udisks in disks_from_udisks:
|
||||
if disk_from_udisks['mount_point'] == disk_from_df['mount_point']:
|
||||
if disk_from_df['mount_point'] in disk_from_udisks['mount_points']:
|
||||
disk_from_df.update(disk_from_udisks)
|
||||
|
||||
return sorted(disks, key=lambda disk: disk['device'])
|
||||
|
||||
|
||||
def _get_disks_from_udisks():
|
||||
"""List devices that can be ejected."""
|
||||
udisks = utils.import_from_gi('UDisks', '2.0')
|
||||
client = udisks.Client.new_sync()
|
||||
object_manager = client.get_object_manager()
|
||||
devices = []
|
||||
|
||||
for obj in object_manager.get_objects():
|
||||
|
||||
if not obj.get_block():
|
||||
continue
|
||||
|
||||
block = obj.get_block()
|
||||
|
||||
if block.props.id_usage != 'filesystem':
|
||||
continue
|
||||
|
||||
device = {
|
||||
'device': block.props.device,
|
||||
'label': block.props.id_label,
|
||||
'size': format_bytes(block.props.size),
|
||||
'filesystem_type': block.props.id_type,
|
||||
'is_removable': not block.props.hint_system
|
||||
}
|
||||
try:
|
||||
device['mount_point'] = obj.get_filesystem().props.mount_points[0]
|
||||
except Exception:
|
||||
continue
|
||||
devices.append(device)
|
||||
|
||||
return devices
|
||||
|
||||
|
||||
def _get_disks_from_df():
|
||||
"""Return the list of disks and free space available using 'df'."""
|
||||
try:
|
||||
|
||||
@ -79,7 +79,7 @@ class Proxy:
|
||||
if signature == 'aay':
|
||||
return [bytes(value_item).decode()[:-1] for value_item in value]
|
||||
|
||||
if signature in ('s', 'b', 'o', 'u'):
|
||||
if signature in ('s', 'b', 'o', 'u', 't'):
|
||||
return glib.Variant.unpack(value)
|
||||
|
||||
raise ValueError('Unhandled type')
|
||||
@ -100,7 +100,11 @@ class BlockDevice(Proxy):
|
||||
'hint_ignore': ('b', 'HintIgnore'),
|
||||
'hint_system': ('b', 'HintSystem'),
|
||||
'id': ('s', 'Id'),
|
||||
'id_label': ('s', 'IdLabel'),
|
||||
'id_type': ('s', 'IdType'),
|
||||
'id_usage': ('s', 'IdUsage'),
|
||||
'preferred_device': ('ay', 'PreferredDevice'),
|
||||
'size': ('t', 'Size'),
|
||||
'symlinks': ('aay', 'Symlinks'),
|
||||
}
|
||||
|
||||
@ -119,6 +123,38 @@ class Filesystem(Proxy):
|
||||
properties = {'mount_points': ('aay', 'MountPoints')}
|
||||
|
||||
|
||||
def get_disks():
|
||||
"""List devices that can be ejected."""
|
||||
devices = []
|
||||
|
||||
manager = _get_dbus_proxy(_OBJECTS['UDisks2'],
|
||||
_INTERFACES['ObjectManager'])
|
||||
objects = manager.GetManagedObjects()
|
||||
for object_, interface_and_properties in objects.items():
|
||||
if _INTERFACES['Block'] not in interface_and_properties:
|
||||
continue
|
||||
|
||||
block = BlockDevice(object_)
|
||||
if block.id_usage != 'filesystem':
|
||||
continue
|
||||
|
||||
device = {
|
||||
'device': block.device,
|
||||
'label': block.id_label,
|
||||
'size': block.size,
|
||||
'filesystem_type': block.id_type,
|
||||
'is_removable': not block.hint_system
|
||||
}
|
||||
try:
|
||||
file_system = Filesystem(object_)
|
||||
device['mount_points'] = file_system.mount_points
|
||||
except Exception:
|
||||
continue
|
||||
devices.append(device)
|
||||
|
||||
return devices
|
||||
|
||||
|
||||
def _mount(object_path):
|
||||
"""Start the mount operation on an block device.
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user