can render actions now

This commit is contained in:
Michael Hudson-Doyle 2017-03-10 14:30:48 +13:00
parent df0a3cfad9
commit 52127d1997
5 changed files with 62 additions and 38 deletions

View File

@ -45,6 +45,7 @@ class FilesystemController(BaseController):
# self.iscsi_model = IscsiDiskModel()
# self.ceph_model = CephDiskModel()
self.raid_model = RaidModel()
self.model.probe() # probe before we complete
@view
def default(self, reset=False):
@ -76,17 +77,20 @@ class FilesystemController(BaseController):
self.ui.set_footer(footer, 30)
self.ui.set_body(ErrorView(self.signal, error_msg))
def finish(self, actions):
def finish(self):
log.info("Rendering curtin config from user choices")
try:
curtin_write_storage_actions(actions=actions)
curtin_write_storage_actions(actions=self.model.render())
except PermissionError:
log.exception('Failed to write storage actions')
self.filesystem_error('curtin_write_storage_actions')
return None
log.info("Rendering preserved config for post install")
preserved_actions = [preserve_action(a) for a in actions]
preserved_actions = []
for a in self.model.render():
a['preserve'] = True
preserved_actions.append(a)
try:
curtin_write_preserved_actions(actions=preserved_actions)
except PermissionError:

View File

@ -132,6 +132,12 @@ def curtin_write_storage_actions(actions):
conf.write(curtin_config)
conf.close()
from collections import OrderedDict
def setup_yaml():
""" http://stackoverflow.com/a/8661021 """
represent_dict_order = lambda self, data: self.represent_mapping('tag:yaml.org,2002:map', data.items())
yaml.add_representer(OrderedDict, represent_dict_order)
setup_yaml()
def curtin_write_network_actions(actions):
curtin_config = yaml.dump(actions, default_flow_style=False)

View File

@ -620,14 +620,17 @@ def id_factory(name):
return r
return attr.Factory(factory)
def filter_false(attr, val):
if attr.name.startswith('_'):
return False
return bool(val)
def asdict(inst):
return inst.asdict(
recurse=False, filter=filter_false, dict_factory=collections.OrderedDict)
r = collections.OrderedDict()
for field in attr.fields(type(inst)):
if field.name.startswith('_'):
continue
v = getattr(inst, field.name)
if v:
if hasattr(v, 'id'):
v = v.id
r[field.name] = v
return r
@attr.s
class Disk:
@ -655,7 +658,7 @@ class Disk:
@property
def available(self):
return self.used < self.size and self._fs is None
return self.used < self.size
@property
def next_partnum(self):
@ -678,9 +681,6 @@ class Disk:
def free(self):
return self.size - self.used
def render(self):
return asdict(self)
@attr.s
class Partition:
id = attr.ib(default=id_factory("part"))
@ -730,6 +730,11 @@ class Mount:
device = attr.ib(default=None) # validator=attr.validators.instance_of((Filesystem, type(None))),
path = attr.ib(default=None)
def render(self):
r = asdict(self)
r['device'] = self.device.id
return r
class FilesystemModel(object):
@ -760,13 +765,13 @@ class FilesystemModel(object):
def render(self):
r = []
for d in self._disks.values():
r.append(d.render())
r.append(asdict(d))
for p in self._partitions:
r.append(p.render())
for f in self._formats:
r.append(f.format())
r.append(asdict(p))
for f in self._filesystems:
r.append(asdict(f))
for m in self._mounts:
r.append(m.format())
r.append(asdict(m))
return r
def _get_system_mounted_disks(self):
@ -813,12 +818,15 @@ class FilesystemModel(object):
def add_partition(self, disk, partnum, size, flag=""):
## XXX check, round, maybe adjust size?
self._use_disk(disk)
if disk._fs is not None:
raise Exception("%s is already formatted" % (disk.path,))
p = Partition(device=disk, number=partnum, size=size, flag=flag)
disk._partitions.append(p)
self._partitions.append(p)
return p
def add_filesystem(self, volume, fstype):
log.debug("adding %s to %s", fstype, volume)
if not volume.available:
raise Exception("%s is not available", volume)
if isinstance(volume, Disk):
@ -843,8 +851,8 @@ class FilesystemModel(object):
return r
def can_install(self):
# Need to figure out stuff to do with grub & a boot partition
return '/' in self.get_mountpoint_to_devpath_mapping()
# Do we need to check that there is a disk with the boot flag?
return '/' in self.get_mountpoint_to_devpath_mapping() and self.bootable()
def validate_mount(self, mountpoint):
if mountpoint is None:

View File

@ -56,7 +56,7 @@ class DiskPartitionView(BaseView):
def _build_model_inputs(self):
partitioned_disks = []
for part in self.disk._partitions:
def format_volume(part):
path = part.path
size = _humanize_size(part.size)
if part._fs is None:
@ -68,20 +68,25 @@ class DiskPartitionView(BaseView):
else:
fstype = part._fs.fstype
mountpoint = part._fs._mount.path
partition_column = Columns([
return Columns([
(15, Text(path)),
Text(size),
Text(fstype),
Text(mountpoint),
], 4)
partitioned_disks.append(partition_column)
free_space = _humanize_size(self.disk.free)
partitioned_disks.append(Columns([
(15, Text("FREE SPACE")),
Text(free_space),
Text(""),
Text("")
], 4))
if self.disk._fs is not None:
partitioned_disks.append(format_volume(self.disk))
else:
for part in self.disk._partitions:
partitioned_disks.append(format_volume(part))
if self.disk.free > 0:
free_space = _humanize_size(self.disk.free)
partitioned_disks.append(Columns([
(15, Text("FREE SPACE")),
Text(free_space),
Text(""),
Text("")
], 4))
return BoxAdapter(SimpleList(partitioned_disks, is_selectable=False),
height=len(partitioned_disks))

View File

@ -43,7 +43,6 @@ class FilesystemView(BaseView):
self.model = model
self.controller = controller
self.items = []
self.model.probe() # probe before we complete
self.body = [
Padding.center_79(Text("FILE SYSTEM")),
Padding.center_79(self._build_filesystem_list()),
@ -88,10 +87,10 @@ class FilesystemView(BaseView):
pl = []
for m in mounts:
col = Columns([
(15, m.device.volume.path),
_humanize_size(m.device.volume.size),
m.device.fstype,
m.path,
(15, Text(m.device.volume.path)),
Text(_humanize_size(m.device.volume.size)),
Text(m.device.fstype),
Text(m.path),
], 4)
pl.append(col)
return Pile(pl)
@ -136,6 +135,9 @@ class FilesystemView(BaseView):
inputs.append(Columns([col1, col2]))
else:
inputs.append(disk_btn)
if len(inputs) == 0:
return Pile([Color.info_minor(
Text("No disks available."))])
return Pile(inputs)
def click_disk(self, sender, disk):
@ -172,5 +174,4 @@ class FilesystemView(BaseView):
self.controller.reset()
def done(self, button):
actions = self.model.get_actions()
self.controller.finish(actions)
self.controller.finish()