Skip to content

Commit f762752

Browse files
committed
Handle missing D-Bus property in pool listing
Signed-off-by: mulhern <amulhern@redhat.com>
1 parent b26ab06 commit f762752

1 file changed

Lines changed: 156 additions & 72 deletions

File tree

src/stratis_cli/_actions/_list_pool.py

Lines changed: 156 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
# isort: THIRDPARTY
3131
from justbytes import Range
3232

33+
# isort: FIRSTPARTY
34+
from dbus_client_gen import DbusClientMissingPropertyError
35+
3336
from .._alerts import (
3437
PoolAllocSpaceAlert,
3538
PoolDeviceSizeChangeAlert,
@@ -251,6 +254,8 @@ def metadata_version(mopool: Any) -> MetadataVersion | None:
251254
return MetadataVersion(int(mopool.MetadataVersion()))
252255
except ValueError: # pragma: no cover
253256
return None
257+
except DbusClientMissingPropertyError: # pragma: no cover
258+
return None
254259

255260
@staticmethod
256261
def _volume_key_loaded(mopool: Any) -> tuple[bool, bool] | tuple[bool, str]:
@@ -268,62 +273,86 @@ def alert_codes(
268273
mopool: Any,
269274
) -> list[PoolEncryptionAlert | PoolAllocSpaceAlert | PoolMaintenanceAlert]:
270275
"""
271-
Return alert code objects for a pool.
276+
Return alert code objects for a pool. If some D-Bus properties are
277+
missing, the information related to those D-Bus properties is simply
278+
omitted.
272279
273280
:param mopool: object to access pool properties
274281
275282
:returns: list of alerts obtainable from GetManagedObjects properties
276283
"""
277-
action_availability = PoolActionAvailability[str(mopool.AvailableActions())]
278-
availability_alerts = action_availability.pool_maintenance_alerts()
284+
try:
285+
action_availability = PoolActionAvailability[str(mopool.AvailableActions())]
286+
availability_alerts = action_availability.pool_maintenance_alerts()
279287

280-
no_alloc_space_alerts = (
281-
[PoolAllocSpaceAlert.NO_ALLOC_SPACE] if mopool.NoAllocSpace() else []
282-
)
288+
except DbusClientMissingPropertyError: # pragma: no cover
289+
availability_alerts = []
283290

284-
metadata_version = Default.metadata_version(mopool)
291+
try:
292+
no_alloc_space_alerts = (
293+
[PoolAllocSpaceAlert.NO_ALLOC_SPACE] if mopool.NoAllocSpace() else []
294+
)
295+
except DbusClientMissingPropertyError: # pragma: no cover
296+
no_alloc_space_alerts = []
285297

286-
(vkl_is_bool, volume_key_loaded) = Default._volume_key_loaded(mopool)
287-
288-
pool_encryption_alerts: list[PoolEncryptionAlert] = (
289-
[PoolEncryptionAlert.VOLUME_KEY_NOT_LOADED]
290-
if metadata_version is MetadataVersion.V2
291-
and mopool.Encrypted()
292-
and vkl_is_bool
293-
and not volume_key_loaded
294-
else []
295-
) + (
296-
[PoolEncryptionAlert.VOLUME_KEY_STATUS_UNKNOWN]
297-
if metadata_version is MetadataVersion.V2
298-
and mopool.Encrypted()
299-
and not vkl_is_bool
300-
else []
301-
)
298+
metadata_version = Default.metadata_version(mopool)
302299

300+
try:
301+
(vkl_is_bool, volume_key_loaded) = Default._volume_key_loaded(mopool)
302+
encrypted = bool(mopool.Encrypted())
303+
pool_encryption_alerts: list[PoolEncryptionAlert] = (
304+
[PoolEncryptionAlert.VOLUME_KEY_NOT_LOADED]
305+
if metadata_version is MetadataVersion.V2
306+
and encrypted
307+
and vkl_is_bool
308+
and not volume_key_loaded
309+
else []
310+
) + (
311+
[PoolEncryptionAlert.VOLUME_KEY_STATUS_UNKNOWN]
312+
if metadata_version is MetadataVersion.V2
313+
and encrypted
314+
and not vkl_is_bool
315+
else []
316+
)
317+
except DbusClientMissingPropertyError: # pragma: no cover
318+
pool_encryption_alerts = [PoolEncryptionAlert.VOLUME_KEY_STATUS_UNKNOWN]
303319
return availability_alerts + no_alloc_space_alerts + pool_encryption_alerts
304320

305321
@staticmethod
306322
def size_triple(mopool: Any) -> SizeTriple:
307323
"""
308324
Calculate SizeTriple from size information.
309325
"""
310-
return SizeTriple(
311-
Range(mopool.TotalPhysicalSize()),
312-
get_property(mopool.TotalPhysicalUsed(), Range, None),
313-
)
326+
try:
327+
size = Range(mopool.TotalPhysicalSize())
328+
except DbusClientMissingPropertyError: # pragma: no cover
329+
size = None
330+
331+
try:
332+
used = get_property(mopool.TotalPhysicalUsed(), Range, None)
333+
except DbusClientMissingPropertyError: # pragma: no cover
334+
used = None
335+
336+
return SizeTriple(size, used)
314337

315338
def uuid_str(self, mopool: Any) -> str:
316339
"""
317340
Return a string representation of UUID, correctly formatted.
318341
"""
319-
return self.uuid_formatter(mopool.Uuid())
342+
try:
343+
return self.uuid_formatter(mopool.Uuid())
344+
except DbusClientMissingPropertyError: # pragma: no cover
345+
return TABLE_UNKNOWN_STRING
320346

321347
@staticmethod
322348
def name_str(mopool: Any) -> str:
323349
"""
324350
Return a string representation of the pool name.
325351
"""
326-
return mopool.Name()
352+
try:
353+
return mopool.Name()
354+
except DbusClientMissingPropertyError: # pragma: no cover
355+
return TABLE_UNKNOWN_STRING
327356

328357

329358
class DefaultDetail(Default): # pylint: disable=too-few-public-methods
@@ -343,7 +372,7 @@ def __init__(self, uuid_formatter: Callable[[str | UUID], str], selection: PoolI
343372

344373
def _print_detail_view(
345374
self, pool_object_path: str, mopool: Any, alerts: DeviceSizeChangedAlerts
346-
): # pylint: disable=too-many-locals
375+
): # pylint: disable=too-many-locals,too-many-statements,too-many-branches
347376
"""
348377
Print the detailed view for a single pool.
349378
@@ -352,8 +381,6 @@ def _print_detail_view(
352381
:param MOPool mopool: properties of the pool
353382
:param DeviceSizeChangedAlerts alerts: pool alerts
354383
"""
355-
encrypted = mopool.Encrypted()
356-
357384
print(f"UUID: {self.uuid_str(mopool)}")
358385
print(f"Name: {Default.name_str(mopool)}")
359386

@@ -367,71 +394,128 @@ def _print_detail_view(
367394
print(f" {line}")
368395

369396
metadata_version = Default.metadata_version(mopool)
397+
metadata_version_str = (
398+
metadata_version if metadata_version is not None else TABLE_UNKNOWN_STRING
399+
)
400+
print(f"Metadata Version: {metadata_version_str}")
401+
402+
try:
403+
actions_allowed_str = PoolActionAvailability[
404+
str(mopool.AvailableActions())
405+
].name
406+
except DbusClientMissingPropertyError: # pragma: no cover
407+
actions_allowed_str = TABLE_UNKNOWN_STRING
408+
print(f"Actions Allowed: {actions_allowed_str}")
370409

371-
print(f"Metadata Version: {metadata_version}")
410+
try:
411+
cache_str = "Yes" if mopool.HasCache() else "No"
412+
except DbusClientMissingPropertyError: # pragma: no cover
413+
cache_str = TABLE_UNKNOWN_STRING
414+
print(f"Cache: {cache_str}")
372415

373-
print(
374-
f"Actions Allowed: "
375-
f"{PoolActionAvailability[str(mopool.AvailableActions())].name}"
376-
)
377-
print(f"Cache: {'Yes' if mopool.HasCache() else 'No'}")
378-
print(f"Filesystem Limit: {mopool.FsLimit()}")
379-
print(
380-
f"Allows Overprovisioning: "
381-
f"{'Yes' if mopool.Overprovisioning() else 'No'}"
382-
)
416+
try:
417+
fs_limit_str = mopool.FsLimit()
418+
except DbusClientMissingPropertyError: # pragma: no cover
419+
fs_limit_str = TABLE_UNKNOWN_STRING
420+
print(f"Filesystem Limit: {fs_limit_str}")
421+
422+
try:
423+
allow_overprovisioning_str = "Yes" if mopool.Overprovisioning() else "No"
424+
except DbusClientMissingPropertyError: # pragma: no cover
425+
allow_overprovisioning_str = TABLE_UNKNOWN_STRING
426+
print(f"Allows Overprovisioning: {allow_overprovisioning_str}")
383427

384-
if encrypted:
428+
try:
429+
encrypted = bool(mopool.Encrypted())
430+
except DbusClientMissingPropertyError: # pragma: no cover
431+
encrypted = None
432+
433+
if encrypted is None: # pragma: no cover
434+
print(f"Encryption Enabled: {TABLE_UNKNOWN_STRING}")
435+
elif encrypted is True:
385436
print("Encryption Enabled: Yes")
386437

387438
if metadata_version is MetadataVersion.V1: # pragma: no cover
388-
key_description_str = _non_existent_or_inconsistent_to_str(
389-
EncryptionInfoKeyDescription(mopool.KeyDescriptions())
390-
)
439+
try:
440+
key_description_str = _non_existent_or_inconsistent_to_str(
441+
EncryptionInfoKeyDescription(mopool.KeyDescriptions())
442+
)
443+
except DbusClientMissingPropertyError:
444+
key_description_str = TABLE_UNKNOWN_STRING
391445
print(f" Key Description: {key_description_str}")
392446

393-
clevis_info_str = _non_existent_or_inconsistent_to_str(
394-
EncryptionInfoClevis(mopool.ClevisInfos()),
395-
interp=_clevis_to_str,
396-
)
447+
try:
448+
clevis_info_str = _non_existent_or_inconsistent_to_str(
449+
EncryptionInfoClevis(mopool.ClevisInfos()),
450+
interp=_clevis_to_str,
451+
)
452+
except DbusClientMissingPropertyError:
453+
clevis_info_str = TABLE_UNKNOWN_STRING
397454
print(f" Clevis Configuration: {clevis_info_str}")
398455
elif metadata_version is MetadataVersion.V2:
399-
encryption_infos = sorted(
400-
[
456+
457+
try:
458+
free_str = get_property(
459+
mopool.FreeTokenSlots(),
460+
lambda x: str(int(x)),
461+
TABLE_UNKNOWN_STRING,
462+
)
463+
except DbusClientMissingPropertyError: # pragma: no cover
464+
free_str = TABLE_UNKNOWN_STRING
465+
print(f" Free Token Slots Remaining: {free_str}")
466+
467+
try:
468+
key_encryption_infos = [
401469
TokenSlotInfo(token_slot, key=str(description))
402470
for token_slot, description in mopool.KeyDescriptions()
403471
]
404-
+ [
472+
except DbusClientMissingPropertyError: # pragma: no cover
473+
key_encryption_infos = []
474+
475+
try:
476+
clevis_encryption_infos = [
405477
TokenSlotInfo(
406478
token_slot, clevis=(str(pin), json.loads(str(config)))
407479
)
408480
for token_slot, (pin, config) in mopool.ClevisInfos()
409-
],
410-
key=lambda x: x.token_slot,
411-
)
481+
]
482+
except DbusClientMissingPropertyError: # pragma: no cover
483+
clevis_encryption_infos = []
412484

413-
free_valid, free = mopool.FreeTokenSlots()
414-
print(
415-
f' Free Token Slots Remaining: {int(free) if free_valid else "<UNKNOWN>"}'
485+
encryption_infos = sorted(
486+
key_encryption_infos + clevis_encryption_infos,
487+
key=lambda x: x.token_slot,
416488
)
417-
418-
for info in encryption_infos:
419-
for line in str(info).split(os.linesep):
420-
print(f" {line}")
489+
if encryption_infos == []:
490+
print(" No token slot information available")
491+
else: # pragma: no cover
492+
for info in encryption_infos:
493+
for line in str(info).split(os.linesep):
494+
print(f" {line}")
421495
else: # pragma: no cover
422-
pass
496+
print(" No encryption information available")
423497
else:
424498
print("Encryption Enabled: No")
425499

426500
size_triple = Default.size_triple(mopool)
427501

428-
print(f"Fully Allocated: {'Yes' if mopool.NoAllocSpace() else 'No'}")
429-
print(f" Size: {size_triple.total()}")
430-
print(f" Allocated: {Range(mopool.AllocatedSize())}")
431-
print(
432-
" Used: "
433-
f"{TABLE_UNKNOWN_STRING if size_triple.used() is None else size_triple.used()}"
434-
)
502+
def size_str(value: Range | None) -> str:
503+
return TABLE_UNKNOWN_STRING if value is None else str(value)
504+
505+
try:
506+
fully_allocated_str = "Yes" if mopool.NoAllocSpace() else "No"
507+
except DbusClientMissingPropertyError: # pragma: no cover
508+
fully_allocated_str = TABLE_UNKNOWN_STRING
509+
print(f"Fully Allocated: {fully_allocated_str}")
510+
511+
print(f" Size: {size_str(size_triple.total())}")
512+
513+
try:
514+
allocated_size = Range(mopool.AllocatedSize())
515+
except DbusClientMissingPropertyError: # pragma: no cover
516+
allocated_size = None
517+
print(f" Allocated: {size_str(allocated_size)}")
518+
print(f" Used: {size_str(size_triple.used())}")
435519

436520
def display(self):
437521
"""

0 commit comments

Comments
 (0)