Merge pull request #1710 from mwhudson/annotate-fsmodel

add annotations to storage model objects
This commit is contained in:
Michael Hudson-Doyle 2023-07-12 10:41:57 +12:00 committed by GitHub
commit 5af40f0b28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 95 additions and 86 deletions

View File

@ -26,6 +26,7 @@ import os
import pathlib import pathlib
import platform import platform
import tempfile import tempfile
from typing import List, Optional, Set, Union
import more_itertools import more_itertools
@ -140,7 +141,10 @@ def fsobj(typ):
c.type = attributes.const(typ) c.type = attributes.const(typ)
c.id = attr.ib(default=None) c.id = attr.ib(default=None)
c._m = attr.ib(repr=None, default=None) c._m = attr.ib(repr=None, default=None)
c = attr.s(eq=False, repr=False)(c) c.__annotations__['id'] = str
c.__annotations__['_m'] = "FilesystemModel"
c.__annotations__['type'] = str
c = attr.s(eq=False, repr=False, auto_attribs=True, kw_only=True)(c)
c.__repr__ = fsobj__repr c.__repr__ = fsobj__repr
_type_to_cls[typ] = c _type_to_cls[typ] = c
return c return c
@ -452,10 +456,8 @@ class _Formattable(ABC):
# Base class for anything that can be formatted and mounted, # Base class for anything that can be formatted and mounted,
# e.g. a disk or a RAID or a partition. # e.g. a disk or a RAID or a partition.
# Filesystem _fs: Optional["Filesystem"] = attributes.backlink()
_fs = attributes.backlink() _constructed_device: Optional["ConstructedDevice"] = attributes.backlink()
# Raid or LVM_VolGroup or ZPool for now, but one day BCache...
_constructed_device = attributes.backlink()
def _is_entirely_used(self): def _is_entirely_used(self):
return self._fs is not None or self._constructed_device is not None return self._fs is not None or self._constructed_device is not None
@ -519,7 +521,8 @@ class _Device(_Formattable, ABC):
pass pass
# [Partition] # [Partition]
_partitions = attributes.backlink(default=attr.Factory(list)) _partitions: List["Partition"] = attributes.backlink(
default=attr.Factory(list))
def dasd(self): def dasd(self):
return None return None
@ -593,28 +596,28 @@ class _Device(_Formattable, ABC):
@fsobj("dasd") @fsobj("dasd")
class Dasd: class Dasd:
device_id = attr.ib() device_id: str
blocksize = attr.ib() blocksize: int
disk_layout = attr.ib() disk_layout: str
label = attr.ib(default=None) label: Optional[str] = None
mode = attr.ib(default=None) mode: Optional[str] = None
preserve = attr.ib(default=False) preserve: bool = False
@fsobj("disk") @fsobj("disk")
class Disk(_Device): class Disk(_Device):
ptable = attributes.ptable() ptable: Optional[str] = attributes.ptable()
serial = attr.ib(default=None) serial: str = None
wwn = attr.ib(default=None) wwn: str = None
multipath = attr.ib(default=None) multipath: str = None
path = attr.ib(default=None) path: str = None
wipe = attr.ib(default=None) wipe: Optional[str] = None
preserve = attr.ib(default=False) preserve: str = False
name = attr.ib(default="") name: str = ""
grub_device = attr.ib(default=False) grub_device: bool = False
device_id = attr.ib(default=None) device_id: str = None
_info = attr.ib(default=None) _info: Optional[StorageInfo] = None
@property @property
def available_for_partitions(self): def available_for_partitions(self):
@ -709,21 +712,21 @@ class Disk(_Device):
@fsobj("partition") @fsobj("partition")
class Partition(_Formattable): class Partition(_Formattable):
device = attributes.ref(backlink="_partitions") # Disk device: _Device = attributes.ref(backlink="_partitions")
size = attributes.size() size: int = attributes.size()
wipe = attr.ib(default=None) wipe: Optional[str] = None
flag = attr.ib(default=None) flag: Optional[str] = None
number = attr.ib(default=None) number: Optional[int] = None
preserve = attr.ib(default=False) preserve: bool = False
grub_device = attr.ib(default=False) grub_device: bool = False
name = attr.ib(default=None) name: Optional[str] = None
multipath = attr.ib(default=None) multipath: Optional[str] = None
offset = attr.ib(default=None) offset: Optional[int] = None
resize = attr.ib(default=None) resize: Optional[bool] = None
partition_type = attr.ib(default=None) partition_type: Optional[str] = None
partition_name = attr.ib(default=None) partition_name: Optional[str] = None
path = attr.ib(default=None) path: Optional[str] = None
def __post_init__(self): def __post_init__(self):
if self.number is not None: if self.number is not None:
@ -813,9 +816,9 @@ class Partition(_Formattable):
@fsobj("raid") @fsobj("raid")
class Raid(_Device): class Raid(_Device):
name = attr.ib() name: str
raidlevel: str = attr.ib(converter=lambda x: raidlevels_by_value[x].value) raidlevel: str = attr.ib(converter=lambda x: raidlevels_by_value[x].value)
devices = attributes.reflist( devices: Set[Union[Disk, Partition, "Raid"]] = attributes.reflist(
backlink="_constructed_device", default=attr.Factory(set)) backlink="_constructed_device", default=attr.Factory(set))
def serialize_devices(self): def serialize_devices(self):
@ -824,16 +827,17 @@ class Raid(_Device):
# way get_raid_size does. # way get_raid_size does.
return {'devices': [d.id for d in raid_device_sort(self.devices)]} return {'devices': [d.id for d in raid_device_sort(self.devices)]}
spare_devices = attributes.reflist( spare_devices: Set[Union[Disk, Partition, "Raid"]] = attributes.reflist(
backlink="_constructed_device", default=attr.Factory(set)) backlink="_constructed_device", default=attr.Factory(set))
preserve = attr.ib(default=False) preserve: bool = False
wipe = attr.ib(default=None) wipe: Optional[str] = None
ptable = attributes.ptable() ptable: Optional[str] = attributes.ptable()
metadata = attr.ib(default=None) metadata: Optional[str] = None
_path = attr.ib(default=None) _path: Optional[str] = None
container = attributes.ref(backlink="_subvolumes", default=None) # Raid container: Optional["Raid"] = attributes.ref(
_subvolumes = attributes.backlink(default=attr.Factory(list)) backlink="_subvolumes", default=None)
_subvolumes: List["Raid"] = attributes.backlink(default=attr.Factory(list))
@property @property
def path(self): def path(self):
@ -897,10 +901,11 @@ class Raid(_Device):
@fsobj("lvm_volgroup") @fsobj("lvm_volgroup")
class LVM_VolGroup(_Device): class LVM_VolGroup(_Device):
name = attr.ib() name: str
devices = attributes.reflist(backlink="_constructed_device") devices: List[Union[Disk, Partition, Raid]] = attributes.reflist(
backlink="_constructed_device")
preserve = attr.ib(default=False) preserve: bool = False
@property @property
def size(self): def size(self):
@ -920,13 +925,13 @@ class LVM_VolGroup(_Device):
@fsobj("lvm_partition") @fsobj("lvm_partition")
class LVM_LogicalVolume(_Formattable): class LVM_LogicalVolume(_Formattable):
name = attr.ib() name: str
volgroup = attributes.ref(backlink="_partitions") # LVM_VolGroup volgroup: LVM_VolGroup = attributes.ref(backlink="_partitions")
size = attributes.size(default=None) size: int = attributes.size(default=None)
wipe = attr.ib(default=None) wipe: Optional[str] = None
preserve = attr.ib(default=False) preserve: bool = False
path = attr.ib(default=None) path: Optional[str] = None
def serialize_size(self): def serialize_size(self):
if self.size is None: if self.size is None:
@ -954,10 +959,10 @@ LUKS_OVERHEAD = 16*(2**20)
@fsobj("dm_crypt") @fsobj("dm_crypt")
class DM_Crypt: class DM_Crypt:
volume = attributes.ref(backlink="_constructed_device") # _Formattable volume: _Formattable = attributes.ref(backlink="_constructed_device")
key = attr.ib(metadata={'redact': True}, default=None) key: Optional[str] = attr.ib(metadata={'redact': True}, default=None)
keyfile = attr.ib(default=None) keyfile: Optional[str] = None
path = attr.ib(default=None) path: Optional[str] = None
def serialize_key(self): def serialize_key(self):
if self.key and not self.keyfile: if self.key and not self.keyfile:
@ -969,10 +974,10 @@ class DM_Crypt:
else: else:
return {} return {}
dm_name = attr.ib(default=None) dm_name: Optional[str] = None
preserve = attr.ib(default=False) preserve: bool = False
_constructed_device = attributes.backlink() _constructed_device: Optional["ConstructedDevice"] = attributes.backlink()
def constructed_device(self): def constructed_device(self):
return self._constructed_device return self._constructed_device
@ -984,8 +989,8 @@ class DM_Crypt:
@fsobj("device") @fsobj("device")
class ArbitraryDevice(_Device): class ArbitraryDevice(_Device):
ptable = attr.ib(default=None) ptable: Optional[str] = None
path = attr.ib(default=None) path: Optional[str] = None
@property @property
def size(self): def size(self):
@ -997,15 +1002,15 @@ class ArbitraryDevice(_Device):
@fsobj("format") @fsobj("format")
class Filesystem: class Filesystem:
fstype = attr.ib() fstype: str
volume = attributes.ref(backlink="_fs") # _Formattable volume: _Formattable = attributes.ref(backlink="_fs")
label = attr.ib(default=None) label: Optional[str] = None
uuid = attr.ib(default=None) uuid: Optional[str] = None
preserve = attr.ib(default=False) preserve: bool = False
extra_options = attr.ib(default=None) extra_options: Optional[List[str]] = None
_mount = attributes.backlink() _mount: Optional["Mount"] = attributes.backlink()
def mount(self): def mount(self):
return self._mount return self._mount
@ -1023,11 +1028,11 @@ class Filesystem:
@fsobj("mount") @fsobj("mount")
class Mount: class Mount:
path = attr.ib() path: str
device = attributes.ref(backlink="_mount", default=None) # Filesystem device: Filesystem = attributes.ref(backlink="_mount", default=None)
fstype = attr.ib(default=None) fstype: Optional[str] = None
options = attr.ib(default=None) options: Optional[str] = None
spec = attr.ib(default=None) spec: Optional[str] = None
def can_delete(self): def can_delete(self):
from subiquity.common.filesystem import boot from subiquity.common.filesystem import boot
@ -1046,16 +1051,17 @@ class Mount:
@fsobj("zpool") @fsobj("zpool")
class ZPool: class ZPool:
vdevs = attributes.reflist(backlink="_constructed_device") vdevs: List[Union[Disk, Partition]] = attributes.reflist(
pool: str = attr.ib() backlink="_constructed_device")
mountpoint: str = attr.ib() pool: str
mountpoint: str
_zfses = attributes.backlink(default=attr.Factory(list)) _zfses: List["ZFS"] = attributes.backlink(default=attr.Factory(list))
# storage options on the pool # storage options on the pool
pool_properties: dict = attr.ib(default=None) pool_properties: Optional[dict] = None
# default dataset options for the zfses in the pool # default dataset options for the zfses in the pool
fs_properties: dict = attr.ib(default=None) fs_properties: Optional[dict] = None
async def pre_shutdown(self, command_runner): async def pre_shutdown(self, command_runner):
await command_runner.run(['zpool', 'export', self.pool]) await command_runner.run(['zpool', 'export', self.pool])
@ -1063,10 +1069,13 @@ class ZPool:
@fsobj("zfs") @fsobj("zfs")
class ZFS: class ZFS:
pool = attributes.ref(backlink="_zfses") pool: ZPool = attributes.ref(backlink="_zfses")
volume: str = attr.ib() volume: str
# options to pass to zfs dataset creation # options to pass to zfs dataset creation
properties: dict = attr.ib(default=None) properties: Optional[dict] = None
ConstructedDevice = Union[Raid, LVM_VolGroup, ZPool]
def align_up(size, block_size=1 << 20): def align_up(size, block_size=1 << 20):