Изменена установка системы с EFI загрузчиком

master-3.5
parent 2b1868217d
commit e9674b84c9

@ -301,16 +301,20 @@ class Distributive(object):
def getEfiDirectory(self): def getEfiDirectory(self):
"""Get directory which contains boot/efi""" """Get directory which contains boot/efi"""
return path.join(self.getDirectory(), "boot/efi") return self.getEfiDirectories()[0]
def _makeDirectory(self, pathname): def getEfiDirectories(self):
return [path.join(self.getDirectory(), "boot/efi")]
@classmethod
def _makeDirectory(cls, pathname):
"""Make directory and parent. """Make directory and parent.
If directory exists then return False else True""" If directory exists then return False else True"""
try: try:
parent = path.split(path.normpath(pathname))[0] parent = path.split(path.normpath(pathname))[0]
if not path.exists(parent): if not path.exists(parent):
self._makeDirectory(parent) cls._makeDirectory(parent)
else: else:
if path.exists(pathname): if path.exists(pathname):
return False return False
@ -331,7 +335,8 @@ class Distributive(object):
raise DistributiveError(_("Squash size unsupported for %s") % raise DistributiveError(_("Squash size unsupported for %s") %
str(self.__class__.__name__)) str(self.__class__.__name__))
def _removeDirectory(self, directory): @classmethod
def _removeDirectory(cls, directory):
"""Remove directory and files contained in it""" """Remove directory and files contained in it"""
try: try:
if path.exists(directory): if path.exists(directory):
@ -444,8 +449,10 @@ class Distributive(object):
return max(squashfiles, key=self._getSquashNum).group() return max(squashfiles, key=self._getSquashNum).group()
return None return None
def _mountToDirectory(self, file, directory, mountopts="", count=2): @classmethod
def _mountToDirectory(cls, file, directory, mountopts="", count=2):
"""Mount squashfs to directory""" """Mount squashfs to directory"""
# 2816 code return by mount if device is absent (update /dev by udev)
NO_SUCH_DEVICE = 2816 NO_SUCH_DEVICE = 2816
if isMount(directory): if isMount(directory):
raise DistributiveError( raise DistributiveError(
@ -458,21 +465,21 @@ class Distributive(object):
if mountProcess.success(): if mountProcess.success():
return True return True
else: else:
# 2816 code return by mount if device is absent (update /dev by udev)
# try mount 3 times with interval 0.5 second # try mount 3 times with interval 0.5 second
if mountProcess.returncode() == NO_SUCH_DEVICE and count: if mountProcess.returncode() == NO_SUCH_DEVICE and count:
sleep(0.5) sleep(0.5)
mountProcess.close() mountProcess.close()
return self._mountToDirectory(file, directory, mountopts, return cls._mountToDirectory(file, directory, mountopts,
count - 1) count - 1)
try: try:
self._removeDirectory(directory) cls._removeDirectory(directory)
except Exception: except Exception:
pass pass
raise DistributiveError( raise DistributiveError(
self.mountError % (file, mountProcess.read())) cls.mountError % (file, mountProcess.read()))
def _umountDirectory(self, directory): @classmethod
def _umountDirectory(cls, directory):
"""Umount directory""" """Umount directory"""
if isMount(directory): if isMount(directory):
processUmount = None processUmount = None
@ -1050,6 +1057,12 @@ class PartitionDistributive(Distributive):
parent=dirObj) parent=dirObj)
DirectoryDistributive(realDestDir, parent=partObj) DirectoryDistributive(realDestDir, parent=partObj)
def getEfiDirectories(self):
return [path.join(self.getDirectory(), x)
for x in self.multipartition.getMountPoints()
if x.startswith("/boot/efi")
]
def getMultipartData(self): def getMultipartData(self):
"""Get multipartition data""" """Get multipartition data"""
mulipartData = zip(self.multipartition.getPartitions(), mulipartData = zip(self.multipartition.getPartitions(),
@ -1133,15 +1146,17 @@ class PartitionDistributive(Distributive):
self.changeSystemID(dev, systemid, partTable) self.changeSystemID(dev, systemid, partTable)
return True return True
def _checkMount(self, dev): @classmethod
def _checkMount(cls, dev):
"""Checking mount point""" """Checking mount point"""
if isMount(dev): if isMount(dev):
raise DistributiveError( raise DistributiveError(
_("Failed to format %s: this partition is mounted") % dev) _("Failed to format %s: this partition is mounted") % dev)
def formatPartition(self, dev, format="ext4", label=""): @classmethod
def formatPartition(cls, dev, format="ext4", label=""):
"""Format partition""" """Format partition"""
if not format in self.format_map: if not format in cls.format_map:
raise DistributiveError( raise DistributiveError(
_("The specified format of '%s' is not supported") % format) _("The specified format of '%s' is not supported") % format)
if dev in map(lambda y: y.split(" ")[0], if dev in map(lambda y: y.split(" ")[0],
@ -1149,12 +1164,12 @@ class PartitionDistributive(Distributive):
open("/proc/swaps"))): open("/proc/swaps"))):
raise DistributiveError( raise DistributiveError(
_("Failed to format %s: this partition is used as swap") % dev) _("Failed to format %s: this partition is used as swap") % dev)
self._checkMount(dev) cls._checkMount(dev)
if not os.access(dev, os.W_OK): if not os.access(dev, os.W_OK):
raise DistributiveError(_("Failed to format the partition") + raise DistributiveError(_("Failed to format the partition") +
" %s:\n%s" % (dev, _("Permission denied"))) " %s:\n%s" % (dev, _("Permission denied")))
format_process = self.format_map[format](dev, label) format_process = cls.format_map[format](dev, label)
if format_process.failed(): if format_process.failed():
raise DistributiveError( raise DistributiveError(
_("Failed to format the partition") + _("Failed to format the partition") +

@ -167,7 +167,7 @@ class FileSystemManager(object):
@classmethod @classmethod
def checkFSForTypeMount(cls, fs, roottype, mp): def checkFSForTypeMount(cls, fs, roottype, mp):
if mp == '/boot/efi': if mp.startswith('/boot/efi'):
if fs not in ('uefi', 'vfat'): if fs not in ('uefi', 'vfat'):
return False return False
else: else:

@ -28,7 +28,7 @@ from calculate.core.server.func import MethodsInterface
from calculate.core.server.admin import Admins from calculate.core.server.admin import Admins
from calculate.lib.utils.mount import isMount from calculate.lib.utils.mount import isMount
from calculate.lib.utils.files import (pathJoin, from calculate.lib.utils.files import (pathJoin,
process, listDirectory, process, listDirectory, writeFile,
checkUtils, readFile, find, copyWithPath, checkUtils, readFile, find, copyWithPath,
readLinesFile, getProgPath) readLinesFile, getProgPath)
from collections import deque from collections import deque
@ -38,7 +38,7 @@ from calculate.lib.utils.device import (detectDeviceForPartition,
from calculate.lib.utils.partition import DiskFactory from calculate.lib.utils.partition import DiskFactory
from datavars import DataVarsInstall from datavars import DataVarsInstall
from distr import DistributiveError from distr import DistributiveError, PartitionDistributive
from subprocess import Popen, PIPE, STDOUT from subprocess import Popen, PIPE, STDOUT
from itertools import * from itertools import *
@ -236,6 +236,9 @@ class Install(MethodsInterface):
self.install_grub_uefi(cmd_grub_install, prefix_boot, target) self.install_grub_uefi(cmd_grub_install, prefix_boot, target)
# не UEFI установка # не UEFI установка
else: else:
if self.clVars.Get('os_uefi'):
self.update_efi_fstab()
self.mount_efi_fstab()
self.install_grub_biosboot(cmd_grub_install, prefix_boot, target) self.install_grub_biosboot(cmd_grub_install, prefix_boot, target)
def install_grub_biosboot(self, cmd_grub_install, prefix_boot, target): def install_grub_biosboot(self, cmd_grub_install, prefix_boot, target):
@ -272,7 +275,88 @@ class Install(MethodsInterface):
raise DistributiveError( raise DistributiveError(
_("Failed to install the bootloader")) _("Failed to install the bootloader"))
def update_efi_fstab(self):
fstab_fn = pathJoin(self.clVars.Get('cl_chroot_path'), "/etc/fstab")
re_efi_record = re.compile("^(# /boot/efi|\S+\s/boot/efi).*\n",
flags=re.M)
efidata = self.clVars.Get('os_install_fstab_efi_conf')
if path.exists(fstab_fn):
data = readFile(fstab_fn)
m = re_efi_record.search(data)
newdata = re_efi_record.sub("", data)
if efidata:
if m:
newdata = "%s%s\n%s" % (newdata[:m.start()],
efidata, newdata[m.start():])
else:
newdata = "%s%s\n" % (newdata, efidata)
if data != newdata:
with writeFile(fstab_fn) as f:
f.write(newdata)
def format_efi(self):
formatdisk = [(dev, fs)
for dev, mp, fs, make in self.clVars.ZipVars(
'os_install_disk_dev',
'os_install_disk_mount',
'os_install_disk_format',
'os_install_disk_perform_format')
if mp.startswith('/boot/efi') and make == 'on'
]
if formatdisk:
self.startTask(_("Formatting the partitions"), progress=True,
num=len(formatdisk))
i = 1
for dev, fs in formatdisk:
PartitionDistributive.formatPartition(dev, format="vfat")
self.setProgress(i)
i += 1
self.endTask(True)
def mount_efi_fstab(self):
oldmp_efi = self.clVars.select('os_disk_mount',
os_disk_mount__startswith="/boot/efi")
for dev, mp in self.clVars.ZipVars('os_install_disk_dev',
'os_install_disk_mount'):
if mp.startswith("/boot/efi"):
curdev = isMount(mp)
if curdev != dev:
if curdev:
PartitionDistributive._umountDirectory(mp)
PartitionDistributive._makeDirectory(mp)
PartitionDistributive._mountToDirectory(dev, mp)
if mp in oldmp_efi:
oldmp_efi.remove(mp)
for mp in oldmp_efi:
PartitionDistributive._umountDirectory(mp)
def install_grub_uefi(self, cmd_grub_install, prefix_boot, target): def install_grub_uefi(self, cmd_grub_install, prefix_boot, target):
if self.clVars.Get('cl_action') != "system":
self.format_efi()
self.update_efi_fstab()
self.mount_efi_fstab()
efidirs = [x for x in self.clVars.Get('os_install_disk_mount')
if x.startswith('/boot/efi')]
if len(efidirs) > 1:
labels = ["calculate%d" % i for i in range(1, len(efidirs) + 1)]
else:
labels = ["calculate"]
for efiname, efidir in reversed(zip(labels, reversed(efidirs))):
efidir = pathJoin(target.getDirectory(), efidir)
self._install_grub_uefi(cmd_grub_install, prefix_boot, target,
efidir, efiname)
# удаляем устаревшие
efi_boot_mgr = getProgPath('/usr/sbin/efibootmgr')
p_efibootmgr = process(efi_boot_mgr, "-v")
data = p_efibootmgr.read()
for num, label in re.findall(r"Boot(\d+).*(calculate\d*)", data):
if label not in labels:
process(efi_boot_mgr, "-b", num, "-B").success()
def _install_grub_uefi(
self, cmd_grub_install, prefix_boot, target, efidir, efiname):
""" """
Установить grub с UEFI загрузчиком Установить grub с UEFI загрузчиком
""" """
@ -280,9 +364,9 @@ class Install(MethodsInterface):
"--boot-directory=%s" % pathJoin( "--boot-directory=%s" % pathJoin(
prefix_boot, prefix_boot,
target.getBootDirectory()), target.getBootDirectory()),
"--bootloader-id=%s" % efiname,
"--target=x86_64-efi", "--target=x86_64-efi",
"--efi-directory=%s" % "--efi-directory=%s" % efidir,
target.getEfiDirectory(),
"--force"] "--force"]
# проверяем наличие в nv-ram нужной нам записи для исключения повтора # проверяем наличие в nv-ram нужной нам записи для исключения повтора
efi_boot_mgr = getProgPath('/usr/sbin/efibootmgr') efi_boot_mgr = getProgPath('/usr/sbin/efibootmgr')
@ -295,19 +379,16 @@ class Install(MethodsInterface):
if efi_uuid: if efi_uuid:
p_efibootmgr = process(efi_boot_mgr, "-v") p_efibootmgr = process(efi_boot_mgr, "-v")
data = p_efibootmgr.read() data = p_efibootmgr.read()
if re.search(r"Boot.*calculate.*GPT,{uuid}.*{efipath}".format( if re.search(r"Boot.*{label}\s.*GPT,{uuid}.*{efipath}".format(
label=efiname,
uuid=efi_uuid, uuid=efi_uuid,
efipath=r"\\EFI\\calculate\\grubx64.efi"), efipath=r"\\EFI\\%s\\grubx64.efi" % efiname),
data, flags=re.M | re.I): data, flags=re.M | re.I):
grub_params.append("--no-nvram") grub_params.append("--no-nvram")
# в случае установки на usb-hdd EFI загрузчик не прописывается # в случае установки на usb-hdd EFI загрузчик не прописывается
# в efivars # в efivars
if self.clVars.Get('os_install_root_type') == 'usb-hdd': if self.clVars.Get('os_install_root_type') == 'usb-hdd':
grub_params.append("--removable") grub_params.append("--removable")
if self.clVars.Get('cl_action') != "system" and \
not isMount('/boot/efi'):
raise DistributiveError(_("Failed to install the bootloader. "
"/boot/efi is not mounted."))
grub_process = process(cmd_grub_install, grub_process = process(cmd_grub_install,
*grub_params, stderr=STDOUT, *grub_params, stderr=STDOUT,
envdict=os.environ) envdict=os.environ)
@ -319,7 +400,7 @@ class Install(MethodsInterface):
# запись создать не удалось # запись создать не удалось
dmesg = getProgPath('/bin/dmesg') dmesg = getProgPath('/bin/dmesg')
if efi_boot_mgr and dmesg: if efi_boot_mgr and dmesg:
if not re.search('Boot.*calculate', if not re.search('Boot.*%s\s' % efiname,
process(efi_boot_mgr).read(), re.M) and \ process(efi_boot_mgr).read(), re.M) and \
re.search('efivars.*set_variable.*failed', re.search('efivars.*set_variable.*failed',
process(dmesg).read(), re.M): process(dmesg).read(), re.M):

@ -208,8 +208,8 @@ class VariableOsDeviceType(ReadonlyVariable):
return info["MD_LEVEL"] return info["MD_LEVEL"]
device_name = path.basename(dev) device_name = path.basename(dev)
if device_name in self.usbdevices: if device_name in self.usbdevices:
if device.sysfs.read(device.sysfs.Path.Block,device_name, if device.sysfs.read(device.sysfs.Path.Block, device_name,
"removable").strip() == 1: "removable").strip() == "1":
return "flash" return "flash"
else: else:
return "usb-hdd" return "usb-hdd"
@ -219,13 +219,12 @@ class VariableOsDeviceType(ReadonlyVariable):
def get(self): def get(self):
# get usb device by '/dev/disk/by-id'(usb devices contain 'usb' in name) # get usb device by '/dev/disk/by-id'(usb devices contain 'usb' in name)
diskIdPath = '/dev/disk/by-id' diskIdPath = '/dev/disk/by-id'
if path.exists(diskIdPath): if device.devfs.exists(diskIdPath):
self.usbdevices = \ self.usbdevices = \
map(lambda x: \ map(lambda x: \
os.readlink(path.join(diskIdPath, x)).rpartition('/')[ device.devfs.readlink(diskIdPath, x).rpartition('/')[2],
2],
filter(lambda x: x.startswith('usb-'), filter(lambda x: x.startswith('usb-'),
listDirectory(diskIdPath))) device.devfs.listdir(diskIdPath, fullpath=False)))
else: else:
self.usbdevices = [] self.usbdevices = []
return map(self.getType, return map(self.getType,
@ -946,7 +945,9 @@ class VariableOsLocationSource(LocationHelper, DeviceHelper, Variable):
return [ return [
disk_dev for disk_dev, disk_mount in self.ZipVars( disk_dev for disk_dev, disk_mount in self.ZipVars(
"os_disk_dev", "os_disk_mount") "os_disk_dev", "os_disk_mount")
if disk_mount not in ("", "/") or disk_dev == dev_from if ((disk_mount not in ("", "/")
or disk_dev == dev_from) and
not disk_mount.startswith("/boot/efi"))
] + self.Get('os_bind_path') ] + self.Get('os_bind_path')
def get(self): def get(self):
@ -1077,13 +1078,7 @@ class VariableOsLocationDest(LocationHelper, Variable):
return path.normpath(val) return path.normpath(val)
return val return val
def eficonvert(val): value = map(normpath, value)
if val.lower() in ("efi", "uefi"):
return "/boot/efi"
else:
return val
value = map(normpath, map(eficonvert, value))
return map(lambda x: x or "/", value) return map(lambda x: x or "/", value)
def choice(self): def choice(self):
@ -1091,7 +1086,7 @@ class VariableOsLocationDest(LocationHelper, Variable):
return ["/", ""] return ["/", ""]
else: else:
return ['/', '/boot', '/var/calculate', '/home', return ['/', '/boot', '/var/calculate', '/home',
'/usr', '/var', '/tmp', 'swap', '/boot/efi', ''] '/usr', '/var', '/tmp', 'swap', '']
def check(self, value): def check(self, value):
"""Check set location source""" """Check set location source"""
@ -1126,6 +1121,12 @@ class VariableOsLocationDest(LocationHelper, Variable):
binds = filter(lambda x: not x[0].startswith('/dev/') and x[1], binds = filter(lambda x: not x[0].startswith('/dev/') and x[1],
zip(source, value)) zip(source, value))
########################## ##########################
# detect efi specifing
##########################
if "/boot/efi" in value or "efi" in value:
raise VariableError(
_("Please specify EFI partition by UEFI option"))
##########################
# detect duplicate mps # detect duplicate mps
########################## ##########################
dupMP = list(set(filter(lambda x: value.count(x) > 1, dupMP = list(set(filter(lambda x: value.count(x) > 1,
@ -1180,17 +1181,6 @@ class VariableOsLocationDest(LocationHelper, Variable):
if cdromPartitions: if cdromPartitions:
raise VariableError(_("Unable to use CDROM %s for installation") % raise VariableError(_("Unable to use CDROM %s for installation") %
cdromPartitions) cdromPartitions)
#############################
# detect right part for uefi#
#############################
efiDisks = map(lambda x: device.udev.get_devname(name=x[0]),
filter(lambda x: x[1] == '/boot/efi',
zip(source, value)))
wrongPart = self.Select('os_install_disk_dev',
where='os_install_disk_type',
ne='disk-partition')
if set(efiDisks) & set(wrongPart):
raise VariableError(_("UEFI partition must be a disk partition"))
############################### ###############################
# check cross bind mount points # check cross bind mount points
############################### ###############################
@ -1521,24 +1511,6 @@ class VariableOsInstallDiskData(ReadonlyTableVariable):
"os_install_disk_parent"] "os_install_disk_parent"]
class VariableOsInstallDiskEfi(ReadonlyVariable):
type = "list"
def get(self):
if self.Get('os_install_root_type') == 'usb-hdd':
validParent = self.Select('os_install_disk_parent_base',
where='os_install_disk_mount_base',
eq='/')
efi_partitions = self.select('os_device_efi',
os_device_dev__in=validParent)
else:
efi_partitions = self.select('os_device_efi',
os_device_type="hdd")
return list({x for x in efi_partitions if x}
- set(self.Get('os_location_source')))
class VariableOsInstallDiskParent(SourceReadonlyVariable): class VariableOsInstallDiskParent(SourceReadonlyVariable):
""" """
Partition parent devices using for install Partition parent devices using for install
@ -1558,59 +1530,6 @@ class VariableOsInstallDiskParent(SourceReadonlyVariable):
humanReadable = Variable.humanReadable humanReadable = Variable.humanReadable
class VariableOsAddonDiskDev(DeviceHelper, ReadonlyVariable):
type = "list"
def get(self):
if self.Get('os_install_uefi_set') == 'on':
if "/boot/efi" not in self.Get('os_location_dest'):
efiPartition = self.Get('os_install_disk_efi')
if efiPartition:
return efiPartition[:1]
return []
class VariableOsAddonDiskMount(DeviceHelper, ReadonlyVariable):
type = "list"
def get(self):
if self.Get('os_install_uefi_set') == 'on':
if "/boot/efi" not in self.Get('os_location_dest'):
efiPartition = self.Get('os_install_disk_efi')
if efiPartition:
return ['/boot/efi']
return []
class VariableOsAddonDiskFormat(DeviceHelper, ReadonlyVariable):
type = "list"
def get(self):
if self.Get('os_install_uefi_set') == 'on':
if "/boot/efi" not in self.Get('os_location_dest'):
efiPartition = self.Get('os_install_disk_efi')
if efiPartition:
return ['vfat']
return []
class VariableOsAddonDiskPerformFormat(DeviceHelper, ReadonlyVariable):
type = "list"
def get(self):
if self.Get('os_install_uefi_set') == 'on':
if "/boot/efi" not in self.Get('os_location_dest'):
efiPartition = self.Get('os_install_disk_efi')
if efiPartition:
fsPart = self.Select('os_disk_format', where='os_disk_dev',
eq=efiPartition[0], limit=1)
if fsPart != "vfat":
return ['on']
else:
return ['off']
return []
class VariableOsInstallDiskDevBase(DeviceHelper, ReadonlyVariable): class VariableOsInstallDiskDevBase(DeviceHelper, ReadonlyVariable):
""" """
Variable using for resolv cyclic deps Variable using for resolv cyclic deps
@ -1624,9 +1543,11 @@ class VariableOsInstallDiskDevBase(DeviceHelper, ReadonlyVariable):
return [device.udev.get_devname(name=disk)] return [device.udev.get_devname(name=disk)]
return [] return []
return [source for source, dest in self.ZipVars("os_location_source", return [dev
"os_location_dest") for dev, mount in self.ZipVars('os_location_source',
if dest and source.startswith("/dev/")] 'os_location_dest')
if (dev.startswith("/dev") and mount and
not mount.startswith("/boot/efi"))]
class VariableOsInstallDiskParentBase(VariableOsInstallDiskParent): class VariableOsInstallDiskParentBase(VariableOsInstallDiskParent):
@ -1645,7 +1566,7 @@ class VariableOsInstallDiskDev(ReadonlyVariable, DeviceHelper):
type = "list" type = "list"
def get(self): def get(self):
return (self.Get('os_addon_disk_dev') + return (self.Get('os_install_uefi') +
self.Get('os_install_disk_dev_base')) self.Get('os_install_disk_dev_base'))
def humanReadable(self): def humanReadable(self):
@ -1679,10 +1600,11 @@ class VariableOsInstallDiskMountBase(ReadonlyVariable):
if disk: if disk:
return ["/"] return ["/"]
return [] return []
return map(lambda x: x[1], return [mount
filter(lambda x: x[0].startswith('/dev/') and x[1], for dev, mount in self.ZipVars('os_location_source',
zip(self.Get('os_location_source'), 'os_location_dest')
self.Get('os_location_dest')))) if (dev.startswith("/dev") and mount and
not mount.startswith("/boot/efi"))]
class VariableOsInstallDiskMount(ReadonlyVariable): class VariableOsInstallDiskMount(ReadonlyVariable):
@ -1691,10 +1613,16 @@ class VariableOsInstallDiskMount(ReadonlyVariable):
""" """
type = "list" type = "list"
def generate_uefi_mountpoints(self):
yield "/boot/efi"
for i in range(2, 20):
yield "/boot/efi%d" % i
def get(self): def get(self):
"""Get install disk dest""" """Get install disk dest"""
return self.Get('os_addon_disk_mount') + \ mps = self.generate_uefi_mountpoints()
self.Get('os_install_disk_mount_base') return ([next(mps) for x in self.Get('os_install_uefi')] +
self.Get('os_install_disk_mount_base'))
class VariableOsInstallDiskUse(ReadonlyVariable): class VariableOsInstallDiskUse(ReadonlyVariable):
@ -1753,12 +1681,12 @@ class VariableOsInstallDiskFormat(ReadonlyVariable):
type = "choice-list" type = "choice-list"
def get(self): def get(self):
_format = map(lambda x: x[2], _format = [fs for dev, mp, fs in self.ZipVars('os_location_source',
filter(lambda x: x[0].startswith('/dev/') and x[1], 'os_location_dest',
zip(self.Get('os_location_source'), 'os_location_format')
self.Get('os_location_dest'), if dev.startswith('/dev/') and mp]
self.Get('os_location_format')))) efiformat = ['vfat' for x in self.Get('os_install_uefi')]
return self.Get('os_addon_disk_format') + _format return efiformat + _format
class VariableOsInstallDiskPerformFormat(ReadonlyVariable): class VariableOsInstallDiskPerformFormat(ReadonlyVariable):
@ -1773,7 +1701,14 @@ class VariableOsInstallDiskPerformFormat(ReadonlyVariable):
zip(self.Get('os_location_source'), zip(self.Get('os_location_source'),
self.Get('os_location_dest'), self.Get('os_location_dest'),
self.Get('os_location_perform_format')))) self.Get('os_location_perform_format'))))
return self.Get('os_addon_disk_perform_format') + _format if self.GetBool('cl_autopartition_set'):
efiformat = ['on' for x in self.Get('os_install_uefi')]
res = efiformat + _format
else:
vfatdevs = self.select('os_disk_dev', os_disk_format="vfat")
res = ["off" if dv in vfatdevs else "on"
for dv in self.Get('os_install_uefi')] + _format
return res
class VariableOsInstallDiskId(ReadonlyVariable): class VariableOsInstallDiskId(ReadonlyVariable):
@ -1834,11 +1769,20 @@ class VariableOsInstallDiskSize(SourceReadonlyVariable):
indexField = 'os_install_disk_dev' indexField = 'os_install_disk_dev'
def getMap(self): def getMap(self):
return { if self.GetBool("cl_autopartition_set"):
dev: size for dev, size in chain( return {
dev: size for dev, size in chain(
self.ZipVars('os_disk_dev', 'os_disk_size'), self.ZipVars('os_disk_dev', 'os_disk_size'),
self.ZipVars('cl_autopartition_disk_dev_full',
'cl_autopartition_disk_size_full'),
self.ZipVars('os_location_source', 'os_location_size')) self.ZipVars('os_location_source', 'os_location_size'))
} }
else:
return {
dev: size for dev, size in chain(
self.ZipVars('os_disk_dev', 'os_disk_size'),
self.ZipVars('os_location_source', 'os_location_size'))
}
def getMapHumanReadable(self): def getMapHumanReadable(self):
return { return {
@ -1959,10 +1903,16 @@ class VariableOsInstallBootDevices(ReadonlyVariable):
if mbr and dev in devices] if mbr and dev in devices]
return [] return []
class VariableOsUefi(ReadonlyVariable):
"""
UEFI partitions from fstab
"""
def get(self):
return self.select('os_disk_dev', os_disk_mount__startswith="/boot/efi")
class VariableOsInstallUefi(LocationHelper, Variable): class VariableOsInstallUefi(LocationHelper, Variable):
""" """
Disks for boot mbr UEFI partitions for install
""" """
type = "choiceedit-list" type = "choiceedit-list"
element = "selecttable" element = "selecttable"
@ -1997,8 +1947,7 @@ class VariableOsInstallUefi(LocationHelper, Variable):
return [] return []
# если происходит обновление загрузчика текущей системы # если происходит обновление загрузчика текущей системы
# для определения используем /etc/fstab # для определения используем /etc/fstab
fstabefidevs = self.select('os_disk_dev', fstabefidevs = self.Get('os_uefi')
os_disk_mount__startswith="/boot/efi")
if self.Get('cl_action') != 'system': if self.Get('cl_action') != 'system':
return fstabefidevs return fstabefidevs
rootdev = self.Get('os_install_root_dev') rootdev = self.Get('os_install_root_dev')
@ -2037,6 +1986,11 @@ class VariableOsInstallUefi(LocationHelper, Variable):
def check(self, value): def check(self, value):
if value: if value:
efi_boot_mgr = getProgPath('/usr/sbin/efibootmgr')
if not efi_boot_mgr:
raise VariableError(
_("UEFI installation is unavailable, because '%s' command "
"not found") % efi_boot_mgr)
if self.install_without_uefiboot: if self.install_without_uefiboot:
raise VariableError( raise VariableError(
_("Your system must be loaded in UEFI for using this " _("Your system must be loaded in UEFI for using this "
@ -2050,6 +2004,31 @@ class VariableOsInstallUefi(LocationHelper, Variable):
raise VariableError( raise VariableError(
_("Wrong EFI device %s") % badefi[0]) _("Wrong EFI device %s") % badefi[0])
fstab_disks = [dev
for dev, mp in self.ZipVars('os_disk_dev', 'os_disk_mount')
if mp and not mp.startswith("/boot/efi")
]
for disk in value:
if disk in fstab_disks:
raise VariableError(
_("Partition {disk} already used by "
"the current system").format(disk=disk))
not_fat_efi = self.select('os_disk_dev',
os_disk_format__ne="vfat")
for efipart in value:
if efipart in not_fat_efi and isMount(efipart):
raise VariableError(
_("Please unmount {device}, as it will be used for "
"installation").format(device=efipart))
for efipart in value:
if efipart in self.select('os_location_source',
os_location_dest__ne=""):
raise VariableError(
_("Partition {disk} already used for "
"installation").format(disk=efipart))
def uncompatible(self): def uncompatible(self):
""" """
Uncompatible with autopartition Uncompatible with autopartition
@ -2273,32 +2252,36 @@ class VariableOsInstallFstabMountConf(DeviceHelper, ReadonlyVariable):
else: else:
return s return s
def formatFstab(self, used, dev, mp, fs, opts, spec):
ret = "{dev}\t{mp}\t{fs}\t{opts}\t{spec}".format(
dev=used, mp=mp, fs=fs, opts=opts, spec=spec
)
if used.startswith("UUID"):
return "# %s was on %s during installation\n%s" % (mp, dev, ret)
return ret
def get(self): def get(self):
devicesForFstab = self.Select([
'os_install_disk_use',
'os_install_disk_mount',
'os_install_disk_format',
'os_install_disk_options',
'os_install_disk_dev'],
where='os_install_disk_mount',
func=lambda x: x[0] != "" and x[0] != "swap")
devicesForFstab = sorted( devicesForFstab = sorted(
self.Select(['os_install_disk_use', devicesForFstab, key=lambda x: self.separateDevice(x[1]))
'os_install_disk_mount',
'os_install_disk_format', rootLine = "\n".join(
'os_install_disk_options', self.formatFstab(used, dev, mp, fs, opts, "0 1")
'os_install_disk_dev'], for used, mp, fs, opts, dev in devicesForFstab[:1]
where='os_install_disk_mount', )
func=lambda x: x[0] != "" and x[0] != "swap"),
lambda x, y: cmp(self.separateDevice(x[1]), otherLines = "\n".join(
self.separateDevice(y[1]))) self.formatFstab(used, dev, mp, fs, opts, "0 0")
if self.Get('os_install_scratch') == "on": for used, mp, fs, opts, dev in devicesForFstab[1:]
devicesForFstab = filter(lambda x: x[1] != "/", devicesForFstab) )
# rootLine one string, but it correct work if devicesForFstab is empty
rootLine = "\n".join(map(lambda x: "%s\t%s\t%s\t%s\t0 1" %
(
self._commentFstab(x[0], x[1],
x[4]),
x[1], x[2], x[3]),
devicesForFstab[:1]))
otherLines = "\n".join(map(lambda x: "%s\t%s\t%s\t%s\t0 0" %
(self._commentFstab(x[0], x[1],
x[4]), x[1],
x[2], x[3]),
devicesForFstab[1:]))
bindData = self.ZipVars('os_install_bind_path', bindData = self.ZipVars('os_install_bind_path',
'os_install_bind_mountpoint') 'os_install_bind_mountpoint')
@ -2308,6 +2291,28 @@ class VariableOsInstallFstabMountConf(DeviceHelper, ReadonlyVariable):
return "\n".join(filter(lambda x: x, [rootLine, otherLines, bindLines])) return "\n".join(filter(lambda x: x, [rootLine, otherLines, bindLines]))
class VariableOsInstallFstabEfiConf(VariableOsInstallFstabMountConf):
def get(self):
devicesForFstab = self.Select([
'os_install_disk_use',
'os_install_disk_mount',
'os_install_disk_format',
'os_install_disk_options',
'os_install_disk_dev'],
where='os_install_disk_mount',
func=lambda x: x[0].startswith("/boot/efi"))
devicesForFstab = sorted(
devicesForFstab, key=lambda x: self.separateDevice(x[1]))
efiLines = "\n".join(
self.formatFstab(used, dev, mp, fs, opts, "0 0")
for used, mp, fs, opts, dev in devicesForFstab
)
return "\n".join(filter(lambda x: x, [efiLines]))
class VariableOsInstallFstabSwapConf(VariableOsInstallFstabMountConf): class VariableOsInstallFstabSwapConf(VariableOsInstallFstabMountConf):
""" """
FStab.conf contains swap partition FStab.conf contains swap partition

Loading…
Cancel
Save