make annotations a functools.singledispatch
This commit is contained in:
parent
5b7409750e
commit
55191bafb5
|
@ -34,6 +34,7 @@ subiquity/common/api/tests/test_server.py
|
||||||
subiquity/common/errorreport.py
|
subiquity/common/errorreport.py
|
||||||
subiquity/common/filesystem/actions.py
|
subiquity/common/filesystem/actions.py
|
||||||
subiquity/common/filesystem/__init__.py
|
subiquity/common/filesystem/__init__.py
|
||||||
|
subiquity/common/filesystem/labels.py
|
||||||
subiquity/common/filesystem/manipulator.py
|
subiquity/common/filesystem/manipulator.py
|
||||||
subiquity/common/filesystem/tests/__init__.py
|
subiquity/common/filesystem/tests/__init__.py
|
||||||
subiquity/common/filesystem/tests/test_actions.py
|
subiquity/common/filesystem/tests/test_actions.py
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
# Copyright 2021 Canonical, Ltd.
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import functools
|
||||||
|
|
||||||
|
from subiquity.models.filesystem import (
|
||||||
|
Disk,
|
||||||
|
LVM_VolGroup,
|
||||||
|
Partition,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _annotations_generic(device):
|
||||||
|
preserve = getattr(device, 'preserve', None)
|
||||||
|
if preserve is None:
|
||||||
|
return []
|
||||||
|
elif preserve:
|
||||||
|
# A pre-existing device such as a partition or RAID
|
||||||
|
return [_("existing")]
|
||||||
|
else:
|
||||||
|
# A newly created device such as a partition or RAID
|
||||||
|
return [_("new")]
|
||||||
|
|
||||||
|
|
||||||
|
@functools.singledispatch
|
||||||
|
def annotations(device):
|
||||||
|
return _annotations_generic(device)
|
||||||
|
|
||||||
|
|
||||||
|
@annotations.register(Disk)
|
||||||
|
def _annotations_disk(disk):
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
@annotations.register(Partition)
|
||||||
|
def _annotations_partition(partition):
|
||||||
|
r = _annotations_generic(partition)
|
||||||
|
if partition.flag == "prep":
|
||||||
|
r.append("PReP")
|
||||||
|
if partition.preserve:
|
||||||
|
if partition.grub_device:
|
||||||
|
# boot loader partition
|
||||||
|
r.append(_("configured"))
|
||||||
|
else:
|
||||||
|
# boot loader partition
|
||||||
|
r.append(_("unconfigured"))
|
||||||
|
elif partition.is_esp:
|
||||||
|
if partition.fs() and partition.fs().mount():
|
||||||
|
r.append(_("primary ESP"))
|
||||||
|
elif partition.grub_device:
|
||||||
|
r.append(_("backup ESP"))
|
||||||
|
else:
|
||||||
|
r.append(_("unused ESP"))
|
||||||
|
elif partition.flag == "bios_grub":
|
||||||
|
if partition.preserve:
|
||||||
|
if partition.device.grub_device:
|
||||||
|
r.append(_("configured"))
|
||||||
|
else:
|
||||||
|
r.append(_("unconfigured"))
|
||||||
|
r.append("bios_grub")
|
||||||
|
elif partition.flag == "extended":
|
||||||
|
# extended partition
|
||||||
|
r.append(_("extended"))
|
||||||
|
elif partition.flag == "logical":
|
||||||
|
# logical partition
|
||||||
|
r.append(_("logical"))
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
@annotations.register(LVM_VolGroup)
|
||||||
|
def _annotations_vg(vg):
|
||||||
|
r = _annotations_generic(vg)
|
||||||
|
member = next(iter(vg.devices))
|
||||||
|
if member.type == "dm_crypt":
|
||||||
|
# Flag for a LVM volume group
|
||||||
|
r.append(_("encrypted"))
|
||||||
|
return r
|
|
@ -429,18 +429,6 @@ class _Formattable(ABC):
|
||||||
def label(self):
|
def label(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@property
|
|
||||||
def annotations(self):
|
|
||||||
preserve = getattr(self, 'preserve', None)
|
|
||||||
if preserve is None:
|
|
||||||
return []
|
|
||||||
elif preserve:
|
|
||||||
# A pre-existing device such as a partition or RAID
|
|
||||||
return [_("existing")]
|
|
||||||
else:
|
|
||||||
# A newly created device such as a partition or RAID
|
|
||||||
return [_("new")]
|
|
||||||
|
|
||||||
# Filesystem
|
# Filesystem
|
||||||
_fs = attributes.backlink()
|
_fs = attributes.backlink()
|
||||||
# Raid or LVM_VolGroup for now, but one day ZPool, BCache...
|
# Raid or LVM_VolGroup for now, but one day ZPool, BCache...
|
||||||
|
@ -668,10 +656,6 @@ class Disk(_Device):
|
||||||
def size(self):
|
def size(self):
|
||||||
return align_down(self._info.size)
|
return align_down(self._info.size)
|
||||||
|
|
||||||
@property
|
|
||||||
def annotations(self):
|
|
||||||
return []
|
|
||||||
|
|
||||||
def desc(self):
|
def desc(self):
|
||||||
if self.multipath:
|
if self.multipath:
|
||||||
return _("multipath device")
|
return _("multipath device")
|
||||||
|
@ -749,40 +733,6 @@ class Partition(_Formattable):
|
||||||
name = attr.ib(default=None)
|
name = attr.ib(default=None)
|
||||||
multipath = attr.ib(default=None)
|
multipath = attr.ib(default=None)
|
||||||
|
|
||||||
@property
|
|
||||||
def annotations(self):
|
|
||||||
r = super().annotations
|
|
||||||
if self.flag == "prep":
|
|
||||||
r.append("PReP")
|
|
||||||
if self.preserve:
|
|
||||||
if self.grub_device:
|
|
||||||
# boot loader partition
|
|
||||||
r.append(_("configured"))
|
|
||||||
else:
|
|
||||||
# boot loader partition
|
|
||||||
r.append(_("unconfigured"))
|
|
||||||
elif self.is_esp:
|
|
||||||
if self.fs() and self.fs().mount():
|
|
||||||
r.append(_("primary ESP"))
|
|
||||||
elif self.grub_device:
|
|
||||||
r.append(_("backup ESP"))
|
|
||||||
else:
|
|
||||||
r.append(_("unused ESP"))
|
|
||||||
elif self.flag == "bios_grub":
|
|
||||||
if self.preserve:
|
|
||||||
if self.device.grub_device:
|
|
||||||
r.append(_("configured"))
|
|
||||||
else:
|
|
||||||
r.append(_("unconfigured"))
|
|
||||||
r.append("bios_grub")
|
|
||||||
elif self.flag == "extended":
|
|
||||||
# extended partition
|
|
||||||
r.append(_("extended"))
|
|
||||||
elif self.flag == "logical":
|
|
||||||
# logical partition
|
|
||||||
r.append(_("logical"))
|
|
||||||
return r
|
|
||||||
|
|
||||||
def usage_labels(self):
|
def usage_labels(self):
|
||||||
if self.flag == "prep" or self.flag == "bios_grub":
|
if self.flag == "prep" or self.flag == "bios_grub":
|
||||||
return []
|
return []
|
||||||
|
@ -867,11 +817,12 @@ class Partition(_Formattable):
|
||||||
ok_for_lvm_vg = ok_for_raid
|
ok_for_lvm_vg = ok_for_raid
|
||||||
|
|
||||||
def for_client(self):
|
def for_client(self):
|
||||||
|
from subiquity.common.filesystem.labels import annotations
|
||||||
from subiquity.common.types import Partition
|
from subiquity.common.types import Partition
|
||||||
return Partition(
|
return Partition(
|
||||||
size=self.size,
|
size=self.size,
|
||||||
number=self._number,
|
number=self._number,
|
||||||
annotations=self.annotations + self.usage_labels())
|
annotations=annotations(self) + self.usage_labels())
|
||||||
|
|
||||||
|
|
||||||
@fsobj("raid")
|
@fsobj("raid")
|
||||||
|
@ -946,15 +897,6 @@ class LVM_VolGroup(_Device):
|
||||||
def available_for_partitions(self):
|
def available_for_partitions(self):
|
||||||
return self.size
|
return self.size
|
||||||
|
|
||||||
@property
|
|
||||||
def annotations(self):
|
|
||||||
r = super().annotations
|
|
||||||
member = next(iter(self.devices))
|
|
||||||
if member.type == "dm_crypt":
|
|
||||||
# Flag for a LVM volume group
|
|
||||||
r.append(_("encrypted"))
|
|
||||||
return r
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def label(self):
|
def label(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
|
@ -17,6 +17,9 @@ import unittest
|
||||||
|
|
||||||
import attr
|
import attr
|
||||||
|
|
||||||
|
from subiquity.common.filesystem.labels import (
|
||||||
|
annotations,
|
||||||
|
)
|
||||||
from subiquity.models.filesystem import (
|
from subiquity.models.filesystem import (
|
||||||
Bootloader,
|
Bootloader,
|
||||||
dehumanize_size,
|
dehumanize_size,
|
||||||
|
@ -216,68 +219,68 @@ class TestFilesystemModel(unittest.TestCase):
|
||||||
def test_disk_annotations(self):
|
def test_disk_annotations(self):
|
||||||
# disks never have annotations
|
# disks never have annotations
|
||||||
model, disk = make_model_and_disk()
|
model, disk = make_model_and_disk()
|
||||||
self.assertEqual(disk.annotations, [])
|
self.assertEqual(annotations(disk), [])
|
||||||
disk.preserve = True
|
disk.preserve = True
|
||||||
self.assertEqual(disk.annotations, [])
|
self.assertEqual(annotations(disk), [])
|
||||||
|
|
||||||
def test_partition_annotations(self):
|
def test_partition_annotations(self):
|
||||||
model = make_model()
|
model = make_model()
|
||||||
part = make_partition(model)
|
part = make_partition(model)
|
||||||
self.assertEqual(part.annotations, ['new'])
|
self.assertEqual(annotations(part), ['new'])
|
||||||
part.preserve = True
|
part.preserve = True
|
||||||
self.assertEqual(part.annotations, ['existing'])
|
self.assertEqual(annotations(part), ['existing'])
|
||||||
|
|
||||||
model = make_model()
|
model = make_model()
|
||||||
part = make_partition(model, flag="bios_grub")
|
part = make_partition(model, flag="bios_grub")
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
part.annotations, ['new', 'bios_grub'])
|
annotations(part), ['new', 'bios_grub'])
|
||||||
part.preserve = True
|
part.preserve = True
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
part.annotations, ['existing', 'unconfigured', 'bios_grub'])
|
annotations(part), ['existing', 'unconfigured', 'bios_grub'])
|
||||||
part.device.grub_device = True
|
part.device.grub_device = True
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
part.annotations, ['existing', 'configured', 'bios_grub'])
|
annotations(part), ['existing', 'configured', 'bios_grub'])
|
||||||
|
|
||||||
model = make_model()
|
model = make_model()
|
||||||
part = make_partition(model, flag="boot", grub_device=True)
|
part = make_partition(model, flag="boot", grub_device=True)
|
||||||
self.assertEqual(part.annotations, ['new', 'backup ESP'])
|
self.assertEqual(annotations(part), ['new', 'backup ESP'])
|
||||||
fs = model.add_filesystem(part, fstype="fat32")
|
fs = model.add_filesystem(part, fstype="fat32")
|
||||||
model.add_mount(fs, "/boot/efi")
|
model.add_mount(fs, "/boot/efi")
|
||||||
self.assertEqual(part.annotations, ['new', 'primary ESP'])
|
self.assertEqual(annotations(part), ['new', 'primary ESP'])
|
||||||
|
|
||||||
model = make_model()
|
model = make_model()
|
||||||
part = make_partition(model, flag="boot", preserve=True)
|
part = make_partition(model, flag="boot", preserve=True)
|
||||||
self.assertEqual(part.annotations, ['existing', 'unused ESP'])
|
self.assertEqual(annotations(part), ['existing', 'unused ESP'])
|
||||||
part.grub_device = True
|
part.grub_device = True
|
||||||
self.assertEqual(part.annotations, ['existing', 'backup ESP'])
|
self.assertEqual(annotations(part), ['existing', 'backup ESP'])
|
||||||
fs = model.add_filesystem(part, fstype="fat32")
|
fs = model.add_filesystem(part, fstype="fat32")
|
||||||
model.add_mount(fs, "/boot/efi")
|
model.add_mount(fs, "/boot/efi")
|
||||||
self.assertEqual(part.annotations, ['existing', 'primary ESP'])
|
self.assertEqual(annotations(part), ['existing', 'primary ESP'])
|
||||||
|
|
||||||
model = make_model()
|
model = make_model()
|
||||||
part = make_partition(model, flag="prep", grub_device=True)
|
part = make_partition(model, flag="prep", grub_device=True)
|
||||||
self.assertEqual(part.annotations, ['new', 'PReP'])
|
self.assertEqual(annotations(part), ['new', 'PReP'])
|
||||||
|
|
||||||
model = make_model()
|
model = make_model()
|
||||||
part = make_partition(model, flag="prep", preserve=True)
|
part = make_partition(model, flag="prep", preserve=True)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
part.annotations, ['existing', 'PReP', 'unconfigured'])
|
annotations(part), ['existing', 'PReP', 'unconfigured'])
|
||||||
part.grub_device = True
|
part.grub_device = True
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
part.annotations, ['existing', 'PReP', 'configured'])
|
annotations(part), ['existing', 'PReP', 'configured'])
|
||||||
|
|
||||||
def test_vg_default_annotations(self):
|
def test_vg_default_annotations(self):
|
||||||
model, disk = make_model_and_disk()
|
model, disk = make_model_and_disk()
|
||||||
vg = model.add_volgroup('vg-0', {disk})
|
vg = model.add_volgroup('vg-0', {disk})
|
||||||
self.assertEqual(vg.annotations, ['new'])
|
self.assertEqual(annotations(vg), ['new'])
|
||||||
vg.preserve = True
|
vg.preserve = True
|
||||||
self.assertEqual(vg.annotations, ['existing'])
|
self.assertEqual(annotations(vg), ['existing'])
|
||||||
|
|
||||||
def test_vg_encrypted_annotations(self):
|
def test_vg_encrypted_annotations(self):
|
||||||
model, disk = make_model_and_disk()
|
model, disk = make_model_and_disk()
|
||||||
dm_crypt = model.add_dm_crypt(disk, key='passw0rd')
|
dm_crypt = model.add_dm_crypt(disk, key='passw0rd')
|
||||||
vg = model.add_volgroup('vg-0', {dm_crypt})
|
vg = model.add_volgroup('vg-0', {dm_crypt})
|
||||||
self.assertEqual(vg.annotations, ['new', 'encrypted'])
|
self.assertEqual(annotations(vg), ['new', 'encrypted'])
|
||||||
|
|
||||||
def _test_ok_for_xxx(self, model, make_new_device, attr,
|
def _test_ok_for_xxx(self, model, make_new_device, attr,
|
||||||
test_partitions=True):
|
test_partitions=True):
|
||||||
|
|
|
@ -63,6 +63,9 @@ from subiquitycore.view import BaseView
|
||||||
from subiquity.common.filesystem.actions import (
|
from subiquity.common.filesystem.actions import (
|
||||||
DeviceAction,
|
DeviceAction,
|
||||||
)
|
)
|
||||||
|
from subiquity.common.filesystem.labels import (
|
||||||
|
annotations,
|
||||||
|
)
|
||||||
from subiquity.models.filesystem import (
|
from subiquity.models.filesystem import (
|
||||||
humanize_size,
|
humanize_size,
|
||||||
)
|
)
|
||||||
|
@ -104,10 +107,10 @@ class MountInfo:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def desc(self):
|
def desc(self):
|
||||||
annotations = self.mount.device.volume.annotations
|
anns = annotations(self.mount.device.volume)
|
||||||
desc = self.mount.device.volume.desc()
|
desc = self.mount.device.volume.desc()
|
||||||
if annotations:
|
if anns:
|
||||||
desc = annotations[0] + " " + desc
|
desc = anns[0] + " " + desc
|
||||||
return desc
|
return desc
|
||||||
|
|
||||||
def startswith(self, other):
|
def startswith(self, other):
|
||||||
|
|
|
@ -44,6 +44,9 @@ from subiquitycore.ui.utils import (
|
||||||
)
|
)
|
||||||
from subiquitycore.view import BaseView
|
from subiquitycore.view import BaseView
|
||||||
|
|
||||||
|
from subiquity.common.filesystem.labels import (
|
||||||
|
annotations,
|
||||||
|
)
|
||||||
from subiquity.common.types import GuidedChoice
|
from subiquity.common.types import GuidedChoice
|
||||||
from subiquity.models.filesystem import humanize_size
|
from subiquity.models.filesystem import humanize_size
|
||||||
|
|
||||||
|
@ -90,7 +93,7 @@ def summarize_device(disk):
|
||||||
])]
|
])]
|
||||||
if disk.partitions:
|
if disk.partitions:
|
||||||
for part in disk.partitions:
|
for part in disk.partitions:
|
||||||
details = ", ".join(part.annotations)
|
details = ", ".join(annotations(part))
|
||||||
rows.append((part, [
|
rows.append((part, [
|
||||||
Text(_("partition {number}").format(number=part.number)),
|
Text(_("partition {number}").format(number=part.number)),
|
||||||
(2, Text(details)),
|
(2, Text(details)),
|
||||||
|
|
|
@ -19,6 +19,9 @@ from subiquitycore.ui.utils import (
|
||||||
Color,
|
Color,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from subiquity.common.filesystem.labels import (
|
||||||
|
annotations,
|
||||||
|
)
|
||||||
from subiquity.models.filesystem import (
|
from subiquity.models.filesystem import (
|
||||||
humanize_size,
|
humanize_size,
|
||||||
)
|
)
|
||||||
|
@ -34,8 +37,8 @@ def summarize_device(device, part_filter=lambda p: True):
|
||||||
out by looking at the uses of this function.
|
out by looking at the uses of this function.
|
||||||
"""
|
"""
|
||||||
label = device.label
|
label = device.label
|
||||||
if device.annotations:
|
if annotations(device):
|
||||||
label = "{} ({})".format(label, ", ".join(device.annotations))
|
label = "{} ({})".format(label, ", ".join(annotations(device)))
|
||||||
rows = [(device, [
|
rows = [(device, [
|
||||||
(2, Text(label)),
|
(2, Text(label)),
|
||||||
Text(device.desc()),
|
Text(device.desc()),
|
||||||
|
@ -46,7 +49,7 @@ def summarize_device(device, part_filter=lambda p: True):
|
||||||
for part in device.partitions():
|
for part in device.partitions():
|
||||||
if not part_filter(part):
|
if not part_filter(part):
|
||||||
continue
|
continue
|
||||||
details = ", ".join(part.annotations + part.usage_labels())
|
details = ", ".join(annotations(part) + part.usage_labels())
|
||||||
rows.append((part, [
|
rows.append((part, [
|
||||||
Text(part.short_label),
|
Text(part.short_label),
|
||||||
(2, Text(details)),
|
(2, Text(details)),
|
||||||
|
|
Loading…
Reference in New Issue