Merge pull request #1710 from mwhudson/annotate-fsmodel
add annotations to storage model objects
This commit is contained in:
commit
5af40f0b28
|
@ -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):
|
||||||
|
|
Loading…
Reference in New Issue