Don't allow multiple devices to be bootable
- Update filesystem model to check if we have an existing device that's marked bootable. - Update look at all disk mount points, not just the current one Signed-off-by: Ryan Harper <ryan.harper@canonical.com>
This commit is contained in:
parent
a0b3471084
commit
ee8e25818a
|
@ -102,8 +102,13 @@ class FilesystemController(ControllerPolicy):
|
||||||
log.debug('disk.freespace: {}'.format(current_disk.freespace))
|
log.debug('disk.freespace: {}'.format(current_disk.freespace))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
''' create a gpt boot partition if one doesn't exist '''
|
''' create a gpt boot partition if one doesn't exist, only
|
||||||
if current_disk.parttype == 'gpt' and \
|
one one disk'''
|
||||||
|
|
||||||
|
system_bootable = self.model.bootable()
|
||||||
|
log.debug('model has bootable device? {}'.format(system_bootable))
|
||||||
|
if system_bootable is False and \
|
||||||
|
current_disk.parttype == 'gpt' and \
|
||||||
len(current_disk.disk.partitions) == 0:
|
len(current_disk.disk.partitions) == 0:
|
||||||
if self.is_uefi():
|
if self.is_uefi():
|
||||||
log.debug('Adding EFI partition first')
|
log.debug('Adding EFI partition first')
|
||||||
|
|
|
@ -194,18 +194,12 @@ class Blockdev():
|
||||||
space += int(action.offset)
|
space += int(action.offset)
|
||||||
space += int(action.size)
|
space += int(action.size)
|
||||||
|
|
||||||
log.debug('{} usedspace: {}'.format(self.disk.devpath, space))
|
|
||||||
return space
|
return space
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def freespace(self, unit='B'):
|
def freespace(self, unit='B'):
|
||||||
''' return amount of free space '''
|
''' return amount of free space '''
|
||||||
used = self.usedspace
|
return self.size - self.usedspace
|
||||||
size = self.size
|
|
||||||
log.debug('{} freespace: {} - {} = {}'.format(self.disk.devpath,
|
|
||||||
size, used,
|
|
||||||
size - used))
|
|
||||||
return size - used
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def lastpartnumber(self):
|
def lastpartnumber(self):
|
||||||
|
@ -289,19 +283,14 @@ class Blockdev():
|
||||||
# dict to uniq the list of devices mounted
|
# dict to uniq the list of devices mounted
|
||||||
mounted_devs = {}
|
mounted_devs = {}
|
||||||
for mnt in re.findall('/dev/.*', mounts):
|
for mnt in re.findall('/dev/.*', mounts):
|
||||||
log.debug('mnt={}'.format(mnt))
|
|
||||||
(devpath, mount, *_) = mnt.split()
|
(devpath, mount, *_) = mnt.split()
|
||||||
# resolve any symlinks
|
# resolve any symlinks
|
||||||
mounted_devs.update(
|
mounted_devs.update(
|
||||||
{os.path.realpath(devpath): mount})
|
{os.path.realpath(devpath): mount})
|
||||||
|
|
||||||
log.debug('mounted_devs: {}'.format(mounted_devs))
|
|
||||||
matches = [dev for dev in mounted_devs.keys()
|
matches = [dev for dev in mounted_devs.keys()
|
||||||
if dev.startswith(self.disk.devpath)]
|
if dev.startswith(self.disk.devpath)]
|
||||||
log.debug('Checking if {} is in {}'.format(
|
|
||||||
self.disk.devpath, matches))
|
|
||||||
if len(matches) > 0:
|
if len(matches) > 0:
|
||||||
log.debug('Device is mounted: {}'.format(matches))
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -29,6 +29,7 @@ class AttrDict(dict):
|
||||||
__getattr__ = dict.__getitem__
|
__getattr__ = dict.__getitem__
|
||||||
__setattr__ = dict.__setitem__
|
__setattr__ = dict.__setitem__
|
||||||
|
|
||||||
|
|
||||||
class FilesystemModel(ModelPolicy):
|
class FilesystemModel(ModelPolicy):
|
||||||
""" Model representing storage options
|
""" Model representing storage options
|
||||||
"""
|
"""
|
||||||
|
@ -151,18 +152,27 @@ class FilesystemModel(ModelPolicy):
|
||||||
self.info[disk] = self.prober.get_storage_info(disk)
|
self.info[disk] = self.prober.get_storage_info(disk)
|
||||||
|
|
||||||
def get_disk(self, disk):
|
def get_disk(self, disk):
|
||||||
log.debug('probe_storage: get_disk()')
|
log.debug('probe_storage: get_disk({})'.format(disk))
|
||||||
if disk not in self.devices:
|
if disk not in self.devices:
|
||||||
self.devices[disk] = Blockdev(disk, self.info[disk].serial,
|
self.devices[disk] = Blockdev(disk, self.info[disk].serial,
|
||||||
self.info[disk].model,
|
self.info[disk].model,
|
||||||
size=self.info[disk].size)
|
size=self.info[disk].size)
|
||||||
return self.devices[disk]
|
return self.devices[disk]
|
||||||
|
|
||||||
def get_disks(self):
|
def get_available_disks(self):
|
||||||
|
''' currently only returns available disks '''
|
||||||
|
disks = [d for d in self.get_all_disks() if d.available]
|
||||||
|
log.debug('get_available_disks -> {}'.format(
|
||||||
|
",".join([d.devpath for d in disks])))
|
||||||
|
return disks
|
||||||
|
|
||||||
|
def get_all_disks(self):
|
||||||
possible_devices = list(set(list(self.devices.keys()) +
|
possible_devices = list(set(list(self.devices.keys()) +
|
||||||
list(self.info.keys())))
|
list(self.info.keys())))
|
||||||
possible_disks = [self.get_disk(d) for d in sorted(possible_devices)]
|
possible_disks = [self.get_disk(d) for d in sorted(possible_devices)]
|
||||||
return [d for d in possible_disks if d.available]
|
log.debug('get_all_disks -> {}'.format(",".join([d.devpath for d in
|
||||||
|
possible_disks])))
|
||||||
|
return possible_disks
|
||||||
|
|
||||||
def calculate_raid_size(self, raid_level, raid_devices, spare_devices):
|
def calculate_raid_size(self, raid_level, raid_devices, spare_devices):
|
||||||
'''
|
'''
|
||||||
|
@ -290,20 +300,39 @@ class FilesystemModel(ModelPolicy):
|
||||||
''' one or more disks has used space
|
''' one or more disks has used space
|
||||||
and has "/" as a mount
|
and has "/" as a mount
|
||||||
'''
|
'''
|
||||||
for disk in self.get_disks():
|
for disk in self.get_all_disks():
|
||||||
if disk.usedspace > 0 and "/" in disk.mounts:
|
if disk.usedspace > 0 and "/" in disk.mounts:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_available_disks(self):
|
def bootable(self):
|
||||||
return [dev.disk.devpath for dev in self.get_disks()]
|
''' true if one disk has a boot partition '''
|
||||||
|
log.debug('bootable check')
|
||||||
|
for disk in self.get_all_disks():
|
||||||
|
for (num, action) in disk.partitions.items():
|
||||||
|
if action.flags in ['bios_grub']:
|
||||||
|
log.debug('bootable check: we\'ve got boot!')
|
||||||
|
return True
|
||||||
|
|
||||||
def get_used_disks(self):
|
log.debug('bootable check: no disks have been marked bootable')
|
||||||
return [dev.disk.devpath for dev in self.devices.values()
|
return False
|
||||||
|
|
||||||
|
def get_available_disk_names(self):
|
||||||
|
return [dev.disk.devpath for dev in self.get_available_disks()]
|
||||||
|
|
||||||
|
def get_used_disk_names(self):
|
||||||
|
return [dev.disk.devpath for dev in self.get_all_disks()
|
||||||
if dev.available is False]
|
if dev.available is False]
|
||||||
|
|
||||||
def get_disk_info(self, disk):
|
def get_disk_info(self, disk):
|
||||||
return self.info.get(disk, {})
|
return self.info.get(disk, {})
|
||||||
|
|
||||||
|
def get_mounts(self):
|
||||||
|
mounts = []
|
||||||
|
for dev in self.get_all_disks():
|
||||||
|
mounts += dev.mounts
|
||||||
|
|
||||||
|
return mounts
|
||||||
|
|
||||||
def get_disk_action(self, disk):
|
def get_disk_action(self, disk):
|
||||||
return self.devices[disk].get_actions()
|
return self.devices[disk].get_actions()
|
||||||
|
|
||||||
|
|
|
@ -241,9 +241,10 @@ class AddPartitionView(WidgetWrap):
|
||||||
self.selected_disk)
|
self.selected_disk)
|
||||||
return
|
return
|
||||||
# Validate mountpoint input
|
# Validate mountpoint input
|
||||||
if self.mountpoint.value in self.selected_disk.mounts:
|
all_mounts = self.model.get_mounts()
|
||||||
|
if self.mountpoint.value in all_mounts:
|
||||||
log.error('provided mountpoint already allocated'
|
log.error('provided mountpoint already allocated'
|
||||||
' ({}'.format(self.mountpoint.value))
|
' ({})'.format(self.mountpoint.value))
|
||||||
# FIXME: update the error message widget instead
|
# FIXME: update the error message widget instead
|
||||||
self.mountpoint.set_error('ERROR: already mounted')
|
self.mountpoint.set_error('ERROR: already mounted')
|
||||||
self.signal.emit_signal(
|
self.signal.emit_signal(
|
||||||
|
@ -398,7 +399,7 @@ class FilesystemView(ViewPolicy):
|
||||||
def _build_used_disks(self):
|
def _build_used_disks(self):
|
||||||
log.debug('FileSystemView: building used disks')
|
log.debug('FileSystemView: building used disks')
|
||||||
pl = []
|
pl = []
|
||||||
for disk in self.model.get_used_disks():
|
for disk in self.model.get_used_disk_names():
|
||||||
log.debug('used disk: {}'.format(disk))
|
log.debug('used disk: {}'.format(disk))
|
||||||
pl.append(Text(disk))
|
pl.append(Text(disk))
|
||||||
if len(pl):
|
if len(pl):
|
||||||
|
@ -440,7 +441,7 @@ class FilesystemView(ViewPolicy):
|
||||||
buttons = []
|
buttons = []
|
||||||
|
|
||||||
# don't enable done botton if we can't install
|
# don't enable done botton if we can't install
|
||||||
if self.model.installable:
|
if self.model.installable():
|
||||||
buttons.append(
|
buttons.append(
|
||||||
Color.button(done_btn(on_press=self.done),
|
Color.button(done_btn(on_press=self.done),
|
||||||
focus_map='button focus'))
|
focus_map='button focus'))
|
||||||
|
@ -464,7 +465,7 @@ class FilesystemView(ViewPolicy):
|
||||||
col_1 = []
|
col_1 = []
|
||||||
col_2 = []
|
col_2 = []
|
||||||
|
|
||||||
avail_disks = self.model.get_available_disks()
|
avail_disks = self.model.get_available_disk_names()
|
||||||
if len(avail_disks) == 0:
|
if len(avail_disks) == 0:
|
||||||
return Pile([Color.info_minor(Text("No available disks."))])
|
return Pile([Color.info_minor(Text("No available disks."))])
|
||||||
|
|
||||||
|
|
|
@ -47,9 +47,8 @@ class RaidView(ViewPolicy):
|
||||||
items = [
|
items = [
|
||||||
Text("DISK SELECTION")
|
Text("DISK SELECTION")
|
||||||
]
|
]
|
||||||
avail_disks = self.model.get_available_disks()
|
avail_disks = self.model.get_available_disk_names()
|
||||||
if len(avail_disks) == 0:
|
if len(avail_disks) == 0:
|
||||||
self.installable = False
|
|
||||||
return items.append(
|
return items.append(
|
||||||
[Color.info_minor(Text("No available disks."))])
|
[Color.info_minor(Text("No available disks."))])
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue