|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
# Copyright 2008-2016 Mir Calculate. http://www.calculate-linux.org
|
|
|
|
|
#
|
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
|
|
# You may obtain a copy of the License at
|
|
|
|
|
#
|
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
#
|
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
# See the License for the specific language governing permissions and
|
|
|
|
|
# limitations under the License.
|
|
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
import sys
|
|
|
|
|
import re
|
|
|
|
|
import pty
|
|
|
|
|
import fcntl
|
|
|
|
|
from subprocess import Popen
|
|
|
|
|
from os import path
|
|
|
|
|
from itertools import *
|
|
|
|
|
from calculate.install.distr import (FlashDistributive, DistributiveError,
|
|
|
|
|
IsoDistributive)
|
|
|
|
|
from calculate.lib.datavars import (TableVariable, Variable, VariableError,
|
|
|
|
|
ReadonlyVariable, ReadonlyTableVariable,
|
|
|
|
|
SourceReadonlyVariable, VariableInterface,
|
|
|
|
|
HumanReadable)
|
|
|
|
|
import calculate.lib.utils.device as device
|
|
|
|
|
from calculate.lib.utils.device import (getPartitionSize,
|
|
|
|
|
humanreadableSize,
|
|
|
|
|
getUUIDDict)
|
|
|
|
|
from calculate.install.variables.autopartition import Sizes
|
|
|
|
|
from calculate.lib.utils.files import getProgPath
|
|
|
|
|
from calculate.lib.utils.mount import isMount, FStab, DiskSpace
|
|
|
|
|
from calculate.install.fs_manager import FileSystemManager
|
|
|
|
|
|
|
|
|
|
from calculate.lib.cl_lang import setLocalTranslate, _
|
|
|
|
|
from calculate.lib.variables.system import RootType
|
|
|
|
|
|
|
|
|
|
setLocalTranslate('cl_install3', sys.modules[__name__])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DeviceHelper(VariableInterface):
|
|
|
|
|
rePassDevice = re.compile("^/block/(?!%s)" % "|".join(['sr', 'fd',
|
|
|
|
|
'ram', 'loop']))
|
|
|
|
|
|
|
|
|
|
def getBlockDevices(self):
|
|
|
|
|
"""Get interest devices from sys block path"""
|
|
|
|
|
return filter(self.rePassDevice.search,
|
|
|
|
|
device.udev.get_block_devices())
|
|
|
|
|
|
|
|
|
|
def separateDevice(self, dev):
|
|
|
|
|
"""
|
|
|
|
|
Separate device word and number on tuple
|
|
|
|
|
|
|
|
|
|
Using for sort. (Example: sda2 ("sda",2), md5p1 ("md",5,"p",1)
|
|
|
|
|
"""
|
|
|
|
|
return map(lambda x: int(x) if x.isdigit() else x,
|
|
|
|
|
re.findall('\d+|\D+', dev))
|
|
|
|
|
|
|
|
|
|
def mapUdevProperty(self, var, prop, default):
|
|
|
|
|
"""Get each element from var through udev [prop]"""
|
|
|
|
|
return [device.udev.get_device_info(name=x).get(prop, default)
|
|
|
|
|
for x in self.Get(var)]
|
|
|
|
|
|
|
|
|
|
def getPerfectName(self, dev, defaultValue=None):
|
|
|
|
|
"""
|
|
|
|
|
Get dev name or human-readable lvm name
|
|
|
|
|
"""
|
|
|
|
|
info = device.udev.get_device_info(name=dev)
|
|
|
|
|
if 'DM_VG_NAME' in info and 'DM_LV_NAME' in info:
|
|
|
|
|
lvmDeviceName = '/dev/{vg}/{lv}'.format(vg=info['DM_VG_NAME'],
|
|
|
|
|
lv=info['DM_LV_NAME'])
|
|
|
|
|
if path.exists(lvmDeviceName):
|
|
|
|
|
return lvmDeviceName
|
|
|
|
|
if defaultValue is None:
|
|
|
|
|
return info.get('DEVNAME', '')
|
|
|
|
|
else:
|
|
|
|
|
return defaultValue
|
|
|
|
|
|
|
|
|
|
def getLvmName(self, dev):
|
|
|
|
|
"""
|
|
|
|
|
Get lvm name
|
|
|
|
|
"""
|
|
|
|
|
return self.getPerfectName(dev, defaultValue="")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#######################################################
|
|
|
|
|
# Devices variables
|
|
|
|
|
#######################################################
|
|
|
|
|
class VariableOsDeviceData(ReadonlyTableVariable):
|
|
|
|
|
"""
|
|
|
|
|
Information about disk devices
|
|
|
|
|
"""
|
|
|
|
|
type = 'table'
|
|
|
|
|
source = ['os_device_dev',
|
|
|
|
|
'os_device_table',
|
|
|
|
|
'os_device_type',
|
|
|
|
|
'os_device_parent',
|
|
|
|
|
'os_device_ssd_set',
|
|
|
|
|
'os_device_virtual_set',
|
|
|
|
|
'os_device_map',
|
|
|
|
|
'os_device_syspath',
|
|
|
|
|
'os_device_name',
|
|
|
|
|
'os_device_size',
|
|
|
|
|
'os_device_mbr',
|
|
|
|
|
'os_device_efi',
|
|
|
|
|
'os_device_fulltype']
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDeviceInvalidator(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Переменная используемая для автоматического сброса значений переменных
|
|
|
|
|
если во время работы программы произошли изменения среди блочных устройств
|
|
|
|
|
"""
|
|
|
|
|
master = None
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get device /dev name"""
|
|
|
|
|
if self.master is None and not self.Get('cl_ebuild_phase'):
|
|
|
|
|
try:
|
|
|
|
|
self.master, slave = pty.openpty()
|
|
|
|
|
except OSError:
|
|
|
|
|
raise VariableError('Failed to create PTY')
|
|
|
|
|
udevAdm = getProgPath('/sbin/udevadm')
|
|
|
|
|
self.monitor = Popen([udevAdm, "monitor", "--kernel",
|
|
|
|
|
"--subsystem-match=block"], stdout=slave,
|
|
|
|
|
close_fds=True)
|
|
|
|
|
os.close(slave)
|
|
|
|
|
fl = fcntl.fcntl(self.master, fcntl.F_GETFL)
|
|
|
|
|
fcntl.fcntl(self.master, fcntl.F_SETFL, fl | os.O_NONBLOCK)
|
|
|
|
|
return "Device invalidator"
|
|
|
|
|
|
|
|
|
|
def close(self):
|
|
|
|
|
try:
|
|
|
|
|
if self.monitor:
|
|
|
|
|
self.monitor.kill()
|
|
|
|
|
self.monitor.wait()
|
|
|
|
|
except Exception:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def refresh(self):
|
|
|
|
|
try:
|
|
|
|
|
if self.monitor:
|
|
|
|
|
res = os.read(self.master, 65535)
|
|
|
|
|
if res:
|
|
|
|
|
while len(res) == 65535:
|
|
|
|
|
res = os.read(self.master, 65535)
|
|
|
|
|
self.parent.Invalidate(self.name)
|
|
|
|
|
self.parent.Invalidate('os_install_disk_uuid')
|
|
|
|
|
self.parent.Invalidate('os_disk_dev')
|
|
|
|
|
device.udev.clear_cache()
|
|
|
|
|
except OSError as e:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDeviceDev(DeviceHelper, ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Disk devices
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
re_disk_raid = re.compile("^disk-.*-raid\d+$", re.I)
|
|
|
|
|
|
|
|
|
|
def init(self):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get device /dev name"""
|
|
|
|
|
self.Get('os_device_invalidator')
|
|
|
|
|
|
|
|
|
|
# get devices from block sys directories(discard mem,sr,loop and other)
|
|
|
|
|
devices = (x for x in self.getBlockDevices() if x.count('/') == 2)
|
|
|
|
|
devnames = device.udev.syspath_to_devname(
|
|
|
|
|
x for x in devices
|
|
|
|
|
if device.udev.is_device(device.udev.get_device_info(x)) or
|
|
|
|
|
self.re_disk_raid.match(device.udev.get_device_type(path=x)))
|
|
|
|
|
|
|
|
|
|
return list(sorted((x for x in devnames),
|
|
|
|
|
key=self.separateDevice))
|
|
|
|
|
|
|
|
|
|
class VariableOsDeviceFulltype(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Полный тип
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get device /dev name"""
|
|
|
|
|
return [
|
|
|
|
|
device.udev.get_device_type(x)
|
|
|
|
|
for x in self.Get('os_device_syspath')
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDeviceType(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Device type (hdd,cdrom,usb-flash)
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def getType(self, dev):
|
|
|
|
|
info = device.udev.get_device_info(name=dev)
|
|
|
|
|
if device.udev.is_raid(info):
|
|
|
|
|
return info["MD_LEVEL"]
|
|
|
|
|
device_name = path.basename(dev)
|
|
|
|
|
if device_name in self.usbdevices:
|
|
|
|
|
if device.sysfs.read(device.sysfs.Path.Block, device_name,
|
|
|
|
|
"removable").strip() == "1":
|
|
|
|
|
return "flash"
|
|
|
|
|
else:
|
|
|
|
|
return "usb-hdd"
|
|
|
|
|
else:
|
|
|
|
|
return "hdd"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
# get usb device by '/dev/disk/by-id'(usb devices contain 'usb' in name)
|
|
|
|
|
diskIdPath = '/dev/disk/by-id'
|
|
|
|
|
if device.devfs.exists(diskIdPath):
|
|
|
|
|
self.usbdevices = \
|
|
|
|
|
map(lambda x: \
|
|
|
|
|
device.devfs.realpath(diskIdPath, x).rpartition('/')[2],
|
|
|
|
|
filter(lambda x: x.startswith('usb-'),
|
|
|
|
|
device.devfs.listdir(diskIdPath, fullpath=False)))
|
|
|
|
|
else:
|
|
|
|
|
self.usbdevices = []
|
|
|
|
|
return map(self.getType,
|
|
|
|
|
self.Get('os_device_dev'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDeviceParent(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Базовые устройства RAID массива
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get disk parent"""
|
|
|
|
|
return [",".join(device.udev.get_all_base_devices(name=dev))
|
|
|
|
|
if "raid" in _type
|
|
|
|
|
else ""
|
|
|
|
|
for dev, _type in self.ZipVars(
|
|
|
|
|
'os_device_dev', 'os_device_type')]
|
|
|
|
|
|
|
|
|
|
class MbrEfiHelper(VariableInterface):
|
|
|
|
|
boottype = ""
|
|
|
|
|
|
|
|
|
|
def get_boot_partition(self, sysdevice):
|
|
|
|
|
basename = path.basename(sysdevice)
|
|
|
|
|
for devname in device.udev.syspath_to_devname(
|
|
|
|
|
device.sysfs.glob(sysdevice, "%s*" % basename),
|
|
|
|
|
dropempty=True):
|
|
|
|
|
partid = self.select('os_disk_id', os_disk_dev=devname,
|
|
|
|
|
limit=1)
|
|
|
|
|
if partid.upper() == self.boottype:
|
|
|
|
|
return devname
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDeviceMbr(MbrEfiHelper, ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Разделы на устройстве, которые могут быть bios_boot
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
boottype = "EF02"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
def generator():
|
|
|
|
|
for dev, sysdevice, _type, table in self.ZipVars(
|
|
|
|
|
'os_device_dev', 'os_device_syspath', 'os_device_type',
|
|
|
|
|
'os_device_table'):
|
|
|
|
|
if "raid" in _type:
|
|
|
|
|
yield ""
|
|
|
|
|
elif table == "dos":
|
|
|
|
|
yield dev
|
|
|
|
|
else:
|
|
|
|
|
if self.get_boot_partition(sysdevice):
|
|
|
|
|
yield dev
|
|
|
|
|
else:
|
|
|
|
|
yield ""
|
|
|
|
|
return list(generator())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDeviceEfi(MbrEfiHelper, ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Разделы на устройстве, которые могут быть EFI
|
|
|
|
|
"""
|
|
|
|
|
boottype = "EF00"
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
def generator():
|
|
|
|
|
for dev, sysdevice, _type, table in self.ZipVars(
|
|
|
|
|
'os_device_dev', 'os_device_syspath', 'os_device_type',
|
|
|
|
|
'os_device_table'):
|
|
|
|
|
if "raid" in _type or table == "dos":
|
|
|
|
|
yield ""
|
|
|
|
|
else:
|
|
|
|
|
yield self.get_boot_partition(sysdevice) or ""
|
|
|
|
|
return list(generator())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDeviceMap(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Map number for grub
|
|
|
|
|
|
|
|
|
|
Using for legecy grub (DEPRECATATED)
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
return map(lambda x: str(x[0]),
|
|
|
|
|
enumerate(self.Get('os_device_dev')))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDeviceArraySet(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Диски массивы (при создании разделов на таких дисках перед
|
|
|
|
|
номером раздела добавляется "p": nvme0n1p1 вместо nvme0n11
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
devnames = ("nvme", "mmcblk")
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get device partition table"""
|
|
|
|
|
|
|
|
|
|
def isArray(device, name):
|
|
|
|
|
if any(x in device for x in self.devnames):
|
|
|
|
|
return "on"
|
|
|
|
|
else:
|
|
|
|
|
return "off"
|
|
|
|
|
|
|
|
|
|
return map(lambda x: isArray(*x),
|
|
|
|
|
zip(self.Get('os_device_dev'),
|
|
|
|
|
self.Get('os_device_name')))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDeviceSsdSet(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Ssd property
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
ssd_names = ("SSD", "OCZ", "PLEXTOR")
|
|
|
|
|
udev_property = 'ID_ATA_ROTATION_RATE_RPM'
|
|
|
|
|
# считаем, что nvme диски - SSD
|
|
|
|
|
devnames = ("nvme",)
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get device partition table"""
|
|
|
|
|
|
|
|
|
|
def isSsd(dev, name):
|
|
|
|
|
prop = device.udev.get_device_info(name=dev)
|
|
|
|
|
rpm = prop.get(self.udev_property, None)
|
|
|
|
|
if (any(x in dev for x in self.devnames)
|
|
|
|
|
or rpm == "0" or any(x in name for x in self.ssd_names)):
|
|
|
|
|
return "on"
|
|
|
|
|
else:
|
|
|
|
|
return "off"
|
|
|
|
|
|
|
|
|
|
return map(lambda x: isSsd(*x),
|
|
|
|
|
zip(self.Get('os_device_dev'),
|
|
|
|
|
self.Get('os_device_name')))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDeviceSyspath(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Table on device
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
udev_property = 'DEVPATH'
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get device partition table"""
|
|
|
|
|
|
|
|
|
|
def getSysPath(dev):
|
|
|
|
|
prop = device.udev.get_device_info(name=dev)
|
|
|
|
|
syspath = prop.get(self.udev_property, "")
|
|
|
|
|
return syspath
|
|
|
|
|
|
|
|
|
|
return [getSysPath(x) for x in self.Get('os_device_dev')]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDeviceVirtualSet(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Table on device
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
virtual_names = ("VBOX", "VMWare")
|
|
|
|
|
virtual_syspath = ("virtio",)
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get device partition table"""
|
|
|
|
|
|
|
|
|
|
def isVirtual(device, name, syspath):
|
|
|
|
|
if any(x in name for x in self.virtual_names):
|
|
|
|
|
return "on"
|
|
|
|
|
elif any(x in syspath for x in self.virtual_syspath):
|
|
|
|
|
return "on"
|
|
|
|
|
else:
|
|
|
|
|
return "off"
|
|
|
|
|
|
|
|
|
|
return map(lambda x: isVirtual(*x),
|
|
|
|
|
zip(self.Get('os_device_dev'),
|
|
|
|
|
self.Get('os_device_name'),
|
|
|
|
|
self.Get('os_device_syspath')))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDeviceTable(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Table on device
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def getTableByChild(self, dev):
|
|
|
|
|
"""Get table by child partitions"""
|
|
|
|
|
syspath = device.udev.get_syspath(name=dev)
|
|
|
|
|
shortname = path.basename(dev)
|
|
|
|
|
for child in device.sysfs.glob(syspath, "%s*" % shortname):
|
|
|
|
|
udevinfo = device.udev.get_device_info(path=child)
|
|
|
|
|
map_names = {'mbr': 'dos',
|
|
|
|
|
'msdos': 'dos'}
|
|
|
|
|
table = (udevinfo.get('ID_PART_ENTRY_SCHEME', '') or
|
|
|
|
|
udevinfo.get('UDISKS_PARTITION_SCHEME', ''))
|
|
|
|
|
return map_names.get(table, table)
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get device partition table"""
|
|
|
|
|
autopartition = self.Get('cl_autopartition_set') == 'on'
|
|
|
|
|
autoDevice = self.Get('cl_autopartition_device')
|
|
|
|
|
|
|
|
|
|
def getTable(dev):
|
|
|
|
|
prop = device.udev.get_device_info(name=dev)
|
|
|
|
|
return prop.get('ID_PART_TABLE_TYPE',
|
|
|
|
|
self.getTableByChild(dev))
|
|
|
|
|
|
|
|
|
|
def getByAutopartition(dev):
|
|
|
|
|
if autopartition and autoDevice == dev:
|
|
|
|
|
return self.Get('cl_autopartition_table')
|
|
|
|
|
else:
|
|
|
|
|
return getTable(dev)
|
|
|
|
|
|
|
|
|
|
return map(getByAutopartition,
|
|
|
|
|
self.Get('os_device_dev'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDeviceName(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Name of device
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
nameless_devices = {
|
|
|
|
|
'nvme': 'NVME',
|
|
|
|
|
'mmcblk': 'Multimedia Card'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def getName(self, dev):
|
|
|
|
|
devicepath = device.udev.get_syspath(name=dev)
|
|
|
|
|
if devicepath:
|
|
|
|
|
vendor = device.sysfs.read(devicepath, "device/vendor").strip()
|
|
|
|
|
model = device.sysfs.read(devicepath, "device/model").strip()
|
|
|
|
|
if vendor or model:
|
|
|
|
|
return ("%s %s" %
|
|
|
|
|
(vendor, model)).strip()
|
|
|
|
|
else:
|
|
|
|
|
for k, v in self.nameless_devices.items():
|
|
|
|
|
if k in devicepath:
|
|
|
|
|
return v
|
|
|
|
|
return ""
|
|
|
|
|
else:
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
return map(self.getName,
|
|
|
|
|
self.Get('os_device_dev'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDeviceSize(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Name of device
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get device size"""
|
|
|
|
|
return map(lambda x: getPartitionSize(name=x, inBytes=True),
|
|
|
|
|
self.Get('os_device_dev'))
|
|
|
|
|
|
|
|
|
|
def humanReadable(self):
|
|
|
|
|
return map(humanreadableSize,
|
|
|
|
|
self.Get())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#############################################
|
|
|
|
|
# Disk variables
|
|
|
|
|
#############################################
|
|
|
|
|
class VariableOsDiskData(ReadonlyTableVariable):
|
|
|
|
|
"""
|
|
|
|
|
Information about current system partition and mounts
|
|
|
|
|
"""
|
|
|
|
|
source = ['os_disk_dev',
|
|
|
|
|
'os_disk_uuid',
|
|
|
|
|
'os_disk_name',
|
|
|
|
|
'os_disk_size',
|
|
|
|
|
'os_disk_part',
|
|
|
|
|
'os_disk_format',
|
|
|
|
|
'os_disk_type',
|
|
|
|
|
'os_disk_raid',
|
|
|
|
|
'os_disk_lvm',
|
|
|
|
|
'os_disk_parent',
|
|
|
|
|
'os_disk_id',
|
|
|
|
|
'os_disk_grub']
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDiskDev(DeviceHelper, ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
List of available partition devices
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
# получить блочные утсройства, в списке устройства с таблицей раздела
|
|
|
|
|
# разделены '/'
|
|
|
|
|
re_parent = re.compile("^/block/[^/]+")
|
|
|
|
|
disks = self.getBlockDevices()
|
|
|
|
|
parents = {re_parent.search(x).group()
|
|
|
|
|
for x in disks if x.count("/") > 2}
|
|
|
|
|
dev_names = device.udev.syspath_to_devname(
|
|
|
|
|
(x for x in disks if x not in parents),
|
|
|
|
|
dropempty=False)
|
|
|
|
|
return list(sorted((x for x in dev_names), key=self.separateDevice))
|
|
|
|
|
|
|
|
|
|
def humanReadable(self):
|
|
|
|
|
return map(self.getPerfectName,
|
|
|
|
|
self.Get())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDiskMount(DeviceHelper, ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
List mounted points for current operation system
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
disk_hash = self.Get('os_disk_dev')
|
|
|
|
|
fstab = FStab('/etc/fstab', devs=disk_hash)
|
|
|
|
|
rootdev = self.Get('os_root_dev')
|
|
|
|
|
return map(lambda x: '/' if x == rootdev else fstab.getBy(eq=x) or "",
|
|
|
|
|
self.Get('os_disk_dev'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDiskContent(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Partition content
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""
|
|
|
|
|
TODO: need to write
|
|
|
|
|
"""
|
|
|
|
|
return map(lambda x: "",
|
|
|
|
|
self.Get('os_disk_dev'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDiskFormat(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Filesystem on device partitions
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get current disk filesystem"""
|
|
|
|
|
fstab = FStab('/etc/fstab', devs=self.Get('os_disk_dev'))
|
|
|
|
|
|
|
|
|
|
def getFormat(dev):
|
|
|
|
|
prop = device.udev.get_device_info(name=dev)
|
|
|
|
|
return prop.get('FSTAB_TYPE') or \
|
|
|
|
|
fstab.getBy(what=fstab.TYPE, eq=dev) or \
|
|
|
|
|
prop.get('ID_FS_TYPE', '')
|
|
|
|
|
|
|
|
|
|
return map(getFormat,
|
|
|
|
|
self.Get('os_disk_dev'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDiskType(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
List type (lvm,raid,partition,disk)
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
re_raid = re.compile("-raid\d+$")
|
|
|
|
|
re_raid_partition = re.compile("-raid\d+-partition$")
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get partition scheme"""
|
|
|
|
|
types = map(lambda x: (x, device.udev.get_device_type(name=x)),
|
|
|
|
|
self.Get('os_disk_dev'))
|
|
|
|
|
lvmUsedDisks = {}
|
|
|
|
|
raidUsedDisks = {}
|
|
|
|
|
|
|
|
|
|
def forMember(typeInfo):
|
|
|
|
|
diskName, diskType = typeInfo
|
|
|
|
|
if diskName in raidUsedDisks:
|
|
|
|
|
diskType = "%s-raidmember(%s)" % (diskType,
|
|
|
|
|
raidUsedDisks[diskName])
|
|
|
|
|
if diskName in lvmUsedDisks:
|
|
|
|
|
diskType = "%s-lvmmember(%s)" % (diskType,
|
|
|
|
|
",".join(
|
|
|
|
|
lvmUsedDisks[diskName]))
|
|
|
|
|
return diskName, diskType
|
|
|
|
|
|
|
|
|
|
for dev, diskType in types:
|
|
|
|
|
prop = device.udev.get_device_info(name=dev)
|
|
|
|
|
if self.re_raid.search(diskType):
|
|
|
|
|
raiddevice = prop.get('DEVPATH', '')
|
|
|
|
|
elif self.re_raid_partition.search(diskType):
|
|
|
|
|
raiddevice = path.dirname(prop.get('DEVPATH', ''))
|
|
|
|
|
else:
|
|
|
|
|
raiddevice = None
|
|
|
|
|
if raiddevice:
|
|
|
|
|
raiddev = device.udev.get_devname(raiddevice)
|
|
|
|
|
for x in device.raid.devices(raiddevice):
|
|
|
|
|
raidUsedDisks[x] = raiddev
|
|
|
|
|
if diskType.endswith("lvm"):
|
|
|
|
|
for x in device.lvm.used_partitions(prop.get('DM_VG_NAME', ''),
|
|
|
|
|
prop.get('DM_LV_NAME', '')):
|
|
|
|
|
if x in lvmUsedDisks:
|
|
|
|
|
lvmUsedDisks[x].append(dev)
|
|
|
|
|
else:
|
|
|
|
|
lvmUsedDisks[x] = [dev]
|
|
|
|
|
return map(lambda x: x[1],
|
|
|
|
|
map(forMember,
|
|
|
|
|
types))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDiskRaid(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Raids which this partition constructed
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def generateRaid(self):
|
|
|
|
|
for disktype in self.Get('os_disk_type'):
|
|
|
|
|
if "raidmember" in disktype:
|
|
|
|
|
yield disktype.rpartition('(')[2][:-1]
|
|
|
|
|
else:
|
|
|
|
|
yield ""
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
return list(self.generateRaid())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDiskLvm(DeviceHelper, ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
LVM vgname and lvname
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get each element from var through udev [prop]"""
|
|
|
|
|
return map(self.getLvmName,
|
|
|
|
|
self.Get('os_disk_dev'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDiskUuid(DeviceHelper, ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
List uudi for partition devices
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
return self.mapUdevProperty('os_disk_dev', 'ID_FS_UUID', '')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDiskParent(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
List parent deivces for partition
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get disk parent"""
|
|
|
|
|
return [",".join(device.udev.get_disk_devices(name=x))
|
|
|
|
|
for x in self.Get('os_disk_dev')]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDiskId(DeviceHelper, ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Partition's system id
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get disk id"""
|
|
|
|
|
mapTypeUUID = {'ebd0a0a2-b9e5-4433-87c0-68b6b72699c7': '0700',
|
|
|
|
|
'0657fd6d-a4ab-43c4-84e5-0933c84b4f4f': '8200',
|
|
|
|
|
'a19d880f-05fc-4d3b-a006-743f0f84911e': 'FD00',
|
|
|
|
|
'21686148-6449-6e6f-744e-656564454649': 'EF02',
|
|
|
|
|
'c12a7328-f81f-11d2-ba4b-00a0c93ec93b': 'EF00',
|
|
|
|
|
'0fc63daf-8483-4772-8e79-3d69d8477de4': '8300'}
|
|
|
|
|
return map(lambda x: mapTypeUUID.get(x, x),
|
|
|
|
|
map(lambda x: x.rpartition("x")[2],
|
|
|
|
|
self.mapUdevProperty('os_disk_dev', 'ID_PART_ENTRY_TYPE',
|
|
|
|
|
'')))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDiskGrub(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
List grub id for partition devices
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get disk grub map"""
|
|
|
|
|
devicesMap = dict(zip(self.Get('os_device_dev'),
|
|
|
|
|
self.Get('os_device_map')))
|
|
|
|
|
|
|
|
|
|
def getGrubMap(devParent):
|
|
|
|
|
dev, disktype, parent = devParent
|
|
|
|
|
# grub id вычисляем только для разделов расположенных на диске
|
|
|
|
|
# (исключаются lvm, raid и прочие абстракции)
|
|
|
|
|
if disktype != "disk-partition":
|
|
|
|
|
return ""
|
|
|
|
|
prop = device.udev.get_device_info(name=dev)
|
|
|
|
|
partnum = int(prop.get('ID_PART_ENTRY_NUMBER', 0))
|
|
|
|
|
if parent in devicesMap.keys() and partnum:
|
|
|
|
|
return "%s,%d" % (devicesMap[parent], partnum - 1)
|
|
|
|
|
else:
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
return map(getGrubMap,
|
|
|
|
|
zip(self.Get('os_disk_dev'),
|
|
|
|
|
self.Get('os_disk_type'),
|
|
|
|
|
self.Get('os_disk_parent')))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDiskPart(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Type of partition devices
|
|
|
|
|
If msdos then(primary, extended or logical)
|
|
|
|
|
If gpt then gpt
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
def generator():
|
|
|
|
|
for disk_dev, disk_type in self.ZipVars(
|
|
|
|
|
'os_disk_dev', 'os_disk_type'):
|
|
|
|
|
if disk_type.endswith("-partition"):
|
|
|
|
|
yield device.udev.get_partition_type(name=disk_dev)
|
|
|
|
|
else:
|
|
|
|
|
yield ""
|
|
|
|
|
return list(generator())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDiskSize(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Partition size
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get disk size"""
|
|
|
|
|
return map(lambda x: getPartitionSize(name=x, inBytes=True),
|
|
|
|
|
self.Get('os_disk_dev'))
|
|
|
|
|
|
|
|
|
|
def humanReadable(self):
|
|
|
|
|
return map(humanreadableSize,
|
|
|
|
|
self.Get())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDiskName(DeviceHelper, ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Label of partitions
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get disk label"""
|
|
|
|
|
return self.mapUdevProperty('os_disk_dev', 'ID_FS_LABEL', '')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsDiskOptions(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
List mount options
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
fstab = FStab('/etc/fstab', devs=self.Get('os_disk_dev'))
|
|
|
|
|
|
|
|
|
|
def getFormat(dev):
|
|
|
|
|
return fstab.getBy(what=fstab.OPTS, eq=dev)
|
|
|
|
|
|
|
|
|
|
return map(getFormat,
|
|
|
|
|
self.Get('os_disk_dev'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
################################################
|
|
|
|
|
# Bind mount points
|
|
|
|
|
################################################
|
|
|
|
|
class VariableOsBindData(ReadonlyTableVariable):
|
|
|
|
|
"""
|
|
|
|
|
Table of bind mount points
|
|
|
|
|
"""
|
|
|
|
|
source = ['os_bind_path',
|
|
|
|
|
'os_bind_mountpoint']
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsBindPath(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
List source bind path
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
fstab = FStab('/etc/fstab', devs=self.Get('os_disk_dev'))
|
|
|
|
|
return fstab.getBy(what=fstab.NAME, where=fstab.OPTS,
|
|
|
|
|
contains="bind", allentry=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsBindMountpoint(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Mountpoints for directories bind
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
fstab = FStab('/etc/fstab', devs=self.Get('os_disk_dev'))
|
|
|
|
|
return fstab.getBy(what=fstab.DIR, where=fstab.OPTS,
|
|
|
|
|
contains="bind", allentry=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
######################################################################
|
|
|
|
|
# Userselect partion parameters
|
|
|
|
|
######################################################################
|
|
|
|
|
class LocationHelper(VariableInterface):
|
|
|
|
|
"""
|
|
|
|
|
Location variable
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def uncompatible(self):
|
|
|
|
|
"""
|
|
|
|
|
Network setting up unavailable for flash installation
|
|
|
|
|
"""
|
|
|
|
|
if self.Get('cl_autopartition_set') == "on":
|
|
|
|
|
return \
|
|
|
|
|
_("The layout is not available with autopartitioning")
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsLocationBriefData(LocationHelper, TableVariable):
|
|
|
|
|
source = ["os_location_source",
|
|
|
|
|
"os_location_dest",
|
|
|
|
|
"os_location_format",
|
|
|
|
|
"os_location_perform_format",
|
|
|
|
|
"os_location_size"]
|
|
|
|
|
|
|
|
|
|
orig_source = [('os_install_disk_dev',
|
|
|
|
|
'os_install_disk_mount',
|
|
|
|
|
'os_install_disk_format',
|
|
|
|
|
'os_install_disk_perform_format',
|
|
|
|
|
'os_install_disk_size'),
|
|
|
|
|
('os_install_bind_path',
|
|
|
|
|
'os_install_bind_mountpoint', '', '', '')]
|
|
|
|
|
|
|
|
|
|
def init(self):
|
|
|
|
|
self.label = _("Layout")
|
|
|
|
|
|
|
|
|
|
def get(self, hr=HumanReadable.No):
|
|
|
|
|
for varname, value in ifilter(lambda x: type(x[1]) != list,
|
|
|
|
|
imap(lambda x: (x, self.Get(x)),
|
|
|
|
|
ifilter(None,
|
|
|
|
|
chain(*self.orig_source)))):
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Source variable %s does not contain a list") % varname)
|
|
|
|
|
return list(
|
|
|
|
|
chain(*
|
|
|
|
|
map(lambda k: map(list,
|
|
|
|
|
izip_longest(
|
|
|
|
|
*map(lambda x: self.Get(x,
|
|
|
|
|
humanreadable=hr) if x else '',
|
|
|
|
|
k), fillvalue='')),
|
|
|
|
|
self.orig_source))) or [[]]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsLocationData(LocationHelper, TableVariable):
|
|
|
|
|
"""
|
|
|
|
|
Select installation disk variable
|
|
|
|
|
"""
|
|
|
|
|
opt = ["--disk", "-d"]
|
|
|
|
|
metavalue = 'DISK[[:MP[:FS[:FORMAT]]]]'
|
|
|
|
|
untrusted = True
|
|
|
|
|
source = ["os_location_source",
|
|
|
|
|
"os_location_dest",
|
|
|
|
|
"os_location_format",
|
|
|
|
|
"os_location_perform_format",
|
|
|
|
|
"os_location_size"]
|
|
|
|
|
|
|
|
|
|
check_after = ["os_install_root_type"]
|
|
|
|
|
|
|
|
|
|
def init(self):
|
|
|
|
|
self.help = (_("DISK bound for installation will be mounted to the "
|
|
|
|
|
"MP directory. To create a bind mount point, you have "
|
|
|
|
|
"to specify the source directory as DISK") + ". " +
|
|
|
|
|
_("To change the filesystem, you have to specify it as FS. "
|
|
|
|
|
"FORMAT is used for the specifying the need to format "
|
|
|
|
|
"partition or not"))
|
|
|
|
|
self.label = _("Layout")
|
|
|
|
|
|
|
|
|
|
def set(self, value):
|
|
|
|
|
return sorted(value, key=lambda x: x and x[0])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsLocationSource(LocationHelper, DeviceHelper, Variable):
|
|
|
|
|
"""
|
|
|
|
|
Source disk or directory
|
|
|
|
|
"""
|
|
|
|
|
type = "choiceedit-list"
|
|
|
|
|
|
|
|
|
|
def init(self):
|
|
|
|
|
self.label = _("Disk or directory")
|
|
|
|
|
|
|
|
|
|
def availDevs(self, choice=False):
|
|
|
|
|
"""
|
|
|
|
|
Available devices
|
|
|
|
|
"""
|
|
|
|
|
if self.Get('cl_install_type') == 'flash':
|
|
|
|
|
flashes = self.Select('os_device_dev',
|
|
|
|
|
where='os_device_type',
|
|
|
|
|
eq="flash")
|
|
|
|
|
return [disk_dev for disk_dev, disk_parent, disk_type in
|
|
|
|
|
self.ZipVars("os_disk_dev", "os_disk_parent",
|
|
|
|
|
"os_disk_type")
|
|
|
|
|
if disk_type == "disk-partition" and disk_parent in flashes]
|
|
|
|
|
else:
|
|
|
|
|
if choice:
|
|
|
|
|
return self.Get('os_disk_dev') + self.Get('os_bind_path')
|
|
|
|
|
else:
|
|
|
|
|
dev_from = self.Get('cl_install_dev_from')
|
|
|
|
|
return [
|
|
|
|
|
disk_dev for disk_dev, disk_mount in self.ZipVars(
|
|
|
|
|
"os_disk_dev", "os_disk_mount")
|
|
|
|
|
if ((disk_mount not in ("", "/")
|
|
|
|
|
or disk_dev == dev_from) and
|
|
|
|
|
not disk_mount.startswith("/boot/efi"))
|
|
|
|
|
] + self.Get('os_bind_path')
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
if self.Get('cl_autopartition_set') == "on":
|
|
|
|
|
return ([device.udev.get_devname(name=x)
|
|
|
|
|
for x in self.Get('cl_autopartition_disk_dev')] +
|
|
|
|
|
self.Get('cl_autopartition_bind_path'))
|
|
|
|
|
else:
|
|
|
|
|
return self.availDevs()
|
|
|
|
|
|
|
|
|
|
def set(self, value):
|
|
|
|
|
def normpath(val):
|
|
|
|
|
if type(val) == str and val:
|
|
|
|
|
return path.normpath(val)
|
|
|
|
|
return val
|
|
|
|
|
|
|
|
|
|
return map(normpath, value)
|
|
|
|
|
|
|
|
|
|
def choice(self):
|
|
|
|
|
return map(lambda x: (x, self.getPerfectName(x) or x),
|
|
|
|
|
self.fixOsDiskDev(self.availDevs(choice=True))) + [("", "")]
|
|
|
|
|
|
|
|
|
|
def fixOsDiskDev(self, sourcelist=None):
|
|
|
|
|
"""
|
|
|
|
|
Fix os_disk_dev by autopartitions
|
|
|
|
|
"""
|
|
|
|
|
if not sourcelist:
|
|
|
|
|
sourcelist = self.Get('os_disk_dev')
|
|
|
|
|
scheme = self.Get('cl_autopartition_set') == "on"
|
|
|
|
|
if scheme:
|
|
|
|
|
autopartition_devices = self.Get('cl_autopartition_device')
|
|
|
|
|
exclude = {
|
|
|
|
|
disk_dev
|
|
|
|
|
for disk_dev, disk_parent in self.ZipVars("os_disk_dev",
|
|
|
|
|
"os_disk_parent")
|
|
|
|
|
if any(x in autopartition_devices
|
|
|
|
|
for x in disk_parent.split(','))
|
|
|
|
|
}
|
|
|
|
|
appendDisks = (self.Get('cl_autopartition_disk_dev') +
|
|
|
|
|
self.Get('cl_autopartition_bind_path'))
|
|
|
|
|
return [x for x in sourcelist if x not in exclude] + appendDisks
|
|
|
|
|
else:
|
|
|
|
|
return sourcelist
|
|
|
|
|
|
|
|
|
|
def check(self, value):
|
|
|
|
|
"""Check set location source"""
|
|
|
|
|
################################
|
|
|
|
|
# check of device specifing
|
|
|
|
|
################################
|
|
|
|
|
if not value:
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("To install the system, you need to specify the root device"))
|
|
|
|
|
###########################
|
|
|
|
|
# check wrong dev
|
|
|
|
|
###########################
|
|
|
|
|
disks = filter(lambda x: x.startswith('/dev/'), value)
|
|
|
|
|
# get original /dev names
|
|
|
|
|
cnDisks = (device.udev.get_device_info(name=x).get('DEVNAME', x)
|
|
|
|
|
for x in disks)
|
|
|
|
|
wrongDevices = list(set(cnDisks) -
|
|
|
|
|
set(self.fixOsDiskDev()))
|
|
|
|
|
if wrongDevices:
|
|
|
|
|
raise VariableError(_("Wrong device '%s'") % wrongDevices[0])
|
|
|
|
|
wrongSource = filter(lambda x: x and not x.startswith('/'), value)
|
|
|
|
|
if wrongSource:
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Wrong bind mount point '%s'") % wrongSource[0])
|
|
|
|
|
##########################
|
|
|
|
|
# detect duplicate devices
|
|
|
|
|
##########################
|
|
|
|
|
dupDevices = list(set(filter(lambda x: disks.count(x) > 1,
|
|
|
|
|
disks)))
|
|
|
|
|
if dupDevices:
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Device '%s' is used more than once") % dupDevices[0])
|
|
|
|
|
|
|
|
|
|
class VariableClRootSizeMin(Variable):
|
|
|
|
|
"""
|
|
|
|
|
Минимальнй размер root раздела
|
|
|
|
|
"""
|
|
|
|
|
value_format = "{cl_autopartition_root_size_min}"
|
|
|
|
|
|
|
|
|
|
class VariableOsLocationDest(LocationHelper, Variable):
|
|
|
|
|
"""
|
|
|
|
|
Desination directory of install disk data
|
|
|
|
|
"""
|
|
|
|
|
type = "choiceedit-list"
|
|
|
|
|
|
|
|
|
|
def init(self):
|
|
|
|
|
self.label = _("Mount point")
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
if self.Get('cl_autopartition_set') == "on":
|
|
|
|
|
return self.Get('cl_autopartition_disk_mount') + \
|
|
|
|
|
self.Get('cl_autopartition_bind_mountpoint')
|
|
|
|
|
else:
|
|
|
|
|
source = self.Get('os_location_source')
|
|
|
|
|
installFrom = self.Get('cl_install_dev_from')
|
|
|
|
|
singleDevice = self.Get('os_install_disk_single')
|
|
|
|
|
|
|
|
|
|
def installMountPoint(info):
|
|
|
|
|
dev, mount = info
|
|
|
|
|
if self.Get('cl_action') == 'system':
|
|
|
|
|
if self.Get('cl_install_type') == 'flash':
|
|
|
|
|
if dev == singleDevice:
|
|
|
|
|
return "/"
|
|
|
|
|
else:
|
|
|
|
|
return ""
|
|
|
|
|
else:
|
|
|
|
|
if dev == installFrom:
|
|
|
|
|
return "/"
|
|
|
|
|
elif mount == "/":
|
|
|
|
|
return ""
|
|
|
|
|
return mount
|
|
|
|
|
|
|
|
|
|
return map(installMountPoint,
|
|
|
|
|
filter(lambda x: x[0] in source,
|
|
|
|
|
zip(self.Get('os_disk_dev'),
|
|
|
|
|
self.Get('os_disk_mount')) + \
|
|
|
|
|
zip(self.Get('os_bind_path'),
|
|
|
|
|
self.Get('os_bind_mountpoint'))))
|
|
|
|
|
|
|
|
|
|
def set(self, value):
|
|
|
|
|
"""Add abilitiy not specify root"""
|
|
|
|
|
|
|
|
|
|
def normpath(val):
|
|
|
|
|
if type(val) == str and val:
|
|
|
|
|
return path.normpath(val)
|
|
|
|
|
return val
|
|
|
|
|
|
|
|
|
|
value = map(normpath, value)
|
|
|
|
|
return map(lambda x: x or "/", value)
|
|
|
|
|
|
|
|
|
|
def choice(self):
|
|
|
|
|
if self.Get('cl_install_type') == 'flash':
|
|
|
|
|
return ["/", ""]
|
|
|
|
|
else:
|
|
|
|
|
return ['/', '/boot', '/var/calculate', '/home',
|
|
|
|
|
'/usr', '/var', '/tmp', 'swap', '']
|
|
|
|
|
|
|
|
|
|
def check(self, value):
|
|
|
|
|
"""Check set location source"""
|
|
|
|
|
if self.Get('cl_autopartition_set') == "on":
|
|
|
|
|
return
|
|
|
|
|
################################
|
|
|
|
|
# check size for root device
|
|
|
|
|
################################
|
|
|
|
|
minroot = int(self.Get('cl_root_size_min'))
|
|
|
|
|
osInstallRootType = self.Get('os_install_root_type')
|
|
|
|
|
if osInstallRootType != "flash" and \
|
|
|
|
|
not "/usr" in value:
|
|
|
|
|
for mp, size in filter(lambda x: x[0] == '/' and x[1].isdigit() and \
|
|
|
|
|
int(x[1]) < minroot,
|
|
|
|
|
izip(value,
|
|
|
|
|
self.Get("os_location_size"))):
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("The root partition should be at least %s") % "7 Gb")
|
|
|
|
|
source = self.Get("os_location_source")
|
|
|
|
|
################################
|
|
|
|
|
# check of root device specifing
|
|
|
|
|
################################
|
|
|
|
|
if not source:
|
|
|
|
|
return
|
|
|
|
|
if not filter(lambda x: x == "/", value):
|
|
|
|
|
raise VariableError(_("To install the system, you need to "
|
|
|
|
|
"specify the root device"))
|
|
|
|
|
################################
|
|
|
|
|
disks = filter(lambda x: x[0].startswith('/dev/') and x[1],
|
|
|
|
|
zip(source, value))
|
|
|
|
|
disksDevs = map(lambda x: x[0], disks)
|
|
|
|
|
binds = filter(lambda x: not x[0].startswith('/dev/') and x[1],
|
|
|
|
|
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
|
|
|
|
|
##########################
|
|
|
|
|
dupMP = list(set(filter(lambda x: value.count(x) > 1,
|
|
|
|
|
filter(lambda x: x and x != "swap",
|
|
|
|
|
value))))
|
|
|
|
|
if dupMP:
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Mount point '%s' is used more than once") % dupMP[0])
|
|
|
|
|
#########################
|
|
|
|
|
# detect wrong bind
|
|
|
|
|
#########################
|
|
|
|
|
wrongBind = filter(lambda x: not x[0].startswith("/") or
|
|
|
|
|
not x[1].startswith("/"),
|
|
|
|
|
binds)
|
|
|
|
|
if wrongBind:
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Incorrect mount point (bind '%(bindSrc)s' to "
|
|
|
|
|
"'%(bindDst)s')") \
|
|
|
|
|
% {'bindSrc': wrongBind[0][0],
|
|
|
|
|
'bindDst': wrongBind[0][1]})
|
|
|
|
|
#########################################
|
|
|
|
|
# Check '/' in start path of dest pointst
|
|
|
|
|
#########################################
|
|
|
|
|
wrongMP = filter(lambda x: x and not x.startswith("/") and x != "swap",
|
|
|
|
|
value)
|
|
|
|
|
if wrongMP:
|
|
|
|
|
raise VariableError(_("Wrong mount point '%s'") % wrongMP[0])
|
|
|
|
|
#########################################
|
|
|
|
|
# Check using current root
|
|
|
|
|
#########################################
|
|
|
|
|
rootDev = self.Get('os_root_dev')
|
|
|
|
|
if rootDev in self.Get('os_install_disk_dev'):
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("You may not use the current root partition %s for "
|
|
|
|
|
"installation") % rootDev)
|
|
|
|
|
#################################
|
|
|
|
|
# detect using extended partition
|
|
|
|
|
#################################
|
|
|
|
|
extendedPartitions = self.Select('os_install_disk_dev',
|
|
|
|
|
where='os_install_disk_part',
|
|
|
|
|
eq='extended', limit=1)
|
|
|
|
|
if extendedPartitions:
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Unable to use extended partition %s for installation") %
|
|
|
|
|
extendedPartitions)
|
|
|
|
|
##########################
|
|
|
|
|
# detect using CDROM disks
|
|
|
|
|
##########################
|
|
|
|
|
cdromPartitions = self.Select('os_install_disk_dev',
|
|
|
|
|
where='os_install_disk_type',
|
|
|
|
|
like='cdrom', limit=1)
|
|
|
|
|
if cdromPartitions:
|
|
|
|
|
raise VariableError(_("Unable to use CDROM %s for installation") %
|
|
|
|
|
cdromPartitions)
|
|
|
|
|
###############################
|
|
|
|
|
# check cross bind mount points
|
|
|
|
|
###############################
|
|
|
|
|
DEVICE, MP = 0, 1
|
|
|
|
|
srcMountPoints = map(lambda x: x[DEVICE], binds)
|
|
|
|
|
destMountPoints = map(lambda x: x[MP], binds)
|
|
|
|
|
wrongBind = filter(lambda x: x in destMountPoints, srcMountPoints)
|
|
|
|
|
if wrongBind:
|
|
|
|
|
incompBind = filter(lambda x: x[1] == wrongBind[0],
|
|
|
|
|
zip(srcMountPoints, destMountPoints))
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Source directory %(src)s is already used "
|
|
|
|
|
"for binding '%(bindSrc)s' to '%(bindDst)s'") \
|
|
|
|
|
% {'src': wrongBind[0],
|
|
|
|
|
'bindSrc': incompBind[0][0],
|
|
|
|
|
'bindDst': incompBind[0][1]})
|
|
|
|
|
#######################################
|
|
|
|
|
# check multipart for flash and builder
|
|
|
|
|
#######################################
|
|
|
|
|
osInstallRootType = self.Get('os_install_root_type')
|
|
|
|
|
if osInstallRootType == "flash":
|
|
|
|
|
if filter(lambda x: x and x != '/', value):
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Flash install does not support multipartition mode"))
|
|
|
|
|
if filter(lambda x: x == "swap", value):
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Flash install does not support swap disks"))
|
|
|
|
|
########################################
|
|
|
|
|
# check install on member of RAID or LVM
|
|
|
|
|
########################################
|
|
|
|
|
installTypes = zip(self.Get('os_install_disk_dev'),
|
|
|
|
|
self.Get('os_install_disk_type'))
|
|
|
|
|
for checkType in ("raid", "lvm"):
|
|
|
|
|
memberData = filter(lambda x: checkType + "member" in x[1],
|
|
|
|
|
installTypes)
|
|
|
|
|
if memberData:
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Unable to use {part} partition used by active "
|
|
|
|
|
"{typepart} for installation").format(
|
|
|
|
|
typepart=checkType.upper(),
|
|
|
|
|
part=memberData[0][0]))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsLocationFormat(LocationHelper, Variable):
|
|
|
|
|
type = "choice-list"
|
|
|
|
|
|
|
|
|
|
def init(self):
|
|
|
|
|
self.label = _("Filesystem")
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
if self.Get('cl_autopartition_set') == "on":
|
|
|
|
|
return self.Get('cl_autopartition_disk_format') + \
|
|
|
|
|
map(lambda x: "", self.Get('cl_autopartition_bind_path'))
|
|
|
|
|
else:
|
|
|
|
|
mount = self.Get("os_location_dest")
|
|
|
|
|
source = self.Get("os_location_source")
|
|
|
|
|
value = [""] * len(source)
|
|
|
|
|
return map(self.defaultFormat(),
|
|
|
|
|
zip(source, mount, value))
|
|
|
|
|
|
|
|
|
|
def choice(self):
|
|
|
|
|
if self.Get('cl_install_type') == "flash":
|
|
|
|
|
return ["", "vfat"]
|
|
|
|
|
else:
|
|
|
|
|
return [""] + self.Get('os_format_type')
|
|
|
|
|
|
|
|
|
|
def defaultFormat(self):
|
|
|
|
|
"""Describe default value for filesystem"""
|
|
|
|
|
diskFormat = dict(zip(self.Get('os_disk_dev'),
|
|
|
|
|
(self.Get('os_disk_format'))))
|
|
|
|
|
osInstallRootType = self.Get('os_install_root_type')
|
|
|
|
|
availFS = set(self.Select('os_format_type',
|
|
|
|
|
where='os_format_use',
|
|
|
|
|
eq='yes'))
|
|
|
|
|
|
|
|
|
|
def wrap(info):
|
|
|
|
|
dev, mount, fs = info
|
|
|
|
|
if mount and not fs and dev.startswith('/dev/'):
|
|
|
|
|
if mount == "swap":
|
|
|
|
|
return "swap"
|
|
|
|
|
elif mount.startswith('/boot/efi'):
|
|
|
|
|
return "vfat"
|
|
|
|
|
if dev in diskFormat and diskFormat[dev] in availFS:
|
|
|
|
|
if mount.count('/') == 1:
|
|
|
|
|
if FileSystemManager.checkFSForTypeMount(
|
|
|
|
|
diskFormat[dev],
|
|
|
|
|
osInstallRootType, mount):
|
|
|
|
|
return diskFormat[dev]
|
|
|
|
|
else:
|
|
|
|
|
return diskFormat[dev]
|
|
|
|
|
return FileSystemManager.defaultFS.get(osInstallRootType,
|
|
|
|
|
"ext4")
|
|
|
|
|
return fs
|
|
|
|
|
|
|
|
|
|
return wrap
|
|
|
|
|
|
|
|
|
|
def set(self, value):
|
|
|
|
|
value = map(lambda x: "vfat" if x == "uefi" else x, value)
|
|
|
|
|
mount = self.Get("os_location_dest")
|
|
|
|
|
source = self.Get("os_location_source")
|
|
|
|
|
return map(self.defaultFormat(),
|
|
|
|
|
zip(source, mount, value))
|
|
|
|
|
|
|
|
|
|
def check(self, value):
|
|
|
|
|
osInstallRootType = self.Get('os_install_root_type')
|
|
|
|
|
devMpFs = zip(self.Get('os_location_source'),
|
|
|
|
|
self.Get('os_location_dest'), value)
|
|
|
|
|
for dev, mp, fs in devMpFs:
|
|
|
|
|
if dev.startswith('/') and not dev.startswith('/dev/') and fs:
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("The bind mount point does not use filesystem"))
|
|
|
|
|
# check compatible fs for mount point only root dirs
|
|
|
|
|
if dev.startswith('/dev/') and mp and (mp.count('/') == 1 or
|
|
|
|
|
mp in (
|
|
|
|
|
'/var/calculate',
|
|
|
|
|
'/boot/efi')):
|
|
|
|
|
if not FileSystemManager.checkFSForTypeMount(fs,
|
|
|
|
|
osInstallRootType,
|
|
|
|
|
mp):
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("The filesystem for '%(mp)s' should not be '%(opt)s'")
|
|
|
|
|
% {'mp': mp, 'opt': fs} + " " +
|
|
|
|
|
_("for {typedisk} install").format(
|
|
|
|
|
typedisk=osInstallRootType))
|
|
|
|
|
if mp == "swap" and fs != "swap":
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_(
|
|
|
|
|
"The swap partition {dev} must be formatted as swap").format(
|
|
|
|
|
dev=dev))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsLocationPerformFormat(LocationHelper, Variable):
|
|
|
|
|
type = "boolauto-list"
|
|
|
|
|
|
|
|
|
|
def init(self):
|
|
|
|
|
self.label = _("Format")
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
if self.Get('cl_autopartition_set') == "on":
|
|
|
|
|
return map(lambda x: "on",
|
|
|
|
|
self.Get('cl_autopartition_disk_format')) + \
|
|
|
|
|
map(lambda x: "",
|
|
|
|
|
self.Get('cl_autopartition_bind_path'))
|
|
|
|
|
else:
|
|
|
|
|
mount = self.Get("os_location_dest")
|
|
|
|
|
source = self.Get("os_location_source")
|
|
|
|
|
fs = self.Get("os_location_format")
|
|
|
|
|
value = [""] * len(source)
|
|
|
|
|
return map(self.defaultPerformFormat(),
|
|
|
|
|
zip(source, mount, fs, value))
|
|
|
|
|
|
|
|
|
|
fixNtfs = lambda self, x: {'ntfs-3g': 'ntfs'}.get(x, x)
|
|
|
|
|
|
|
|
|
|
def check(self, value):
|
|
|
|
|
"""Check perform format
|
|
|
|
|
|
|
|
|
|
Check what format will perform for need partition.
|
|
|
|
|
At example on change filesystem on partition.
|
|
|
|
|
"""
|
|
|
|
|
DEV, MP, FS, FORMAT = 0, 1, 2, 3
|
|
|
|
|
info = zip(self.Get('os_location_source'),
|
|
|
|
|
self.Get('os_location_dest'),
|
|
|
|
|
self.Get('os_location_format'),
|
|
|
|
|
value)
|
|
|
|
|
diskFormat = dict(zip(self.Get('os_disk_dev'),
|
|
|
|
|
(self.Get('os_disk_format'))))
|
|
|
|
|
diskMount = dict(zip(self.Get('os_disk_dev'),
|
|
|
|
|
(self.Get('os_disk_mount'))))
|
|
|
|
|
unavailFS = set(self.Select('os_format_type',
|
|
|
|
|
where='os_format_use',
|
|
|
|
|
eq="no"))
|
|
|
|
|
fixNtfs = self.fixNtfs
|
|
|
|
|
for dev, mp, fs, isformat in info:
|
|
|
|
|
# should format if change fs or partition is root, but non flash
|
|
|
|
|
partitionMustFormat = \
|
|
|
|
|
fixNtfs(diskFormat.get(dev, fs)) != fixNtfs(fs) or \
|
|
|
|
|
(mp == '/' and
|
|
|
|
|
self.Get('os_install_root_type') != 'flash')
|
|
|
|
|
# if entry has mount point AND
|
|
|
|
|
# partition must was formated
|
|
|
|
|
if mp and partitionMustFormat:
|
|
|
|
|
# partition use in current system
|
|
|
|
|
if diskMount.get(dev, ''):
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("{device} must but cannot be formatted, as it is "
|
|
|
|
|
"mounted to {mountpoint} on the current system").format(
|
|
|
|
|
device=dev, mountpoint=diskMount.get(dev, '')))
|
|
|
|
|
if isMount(dev):
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Please unmount {device}, as it will be used for "
|
|
|
|
|
"installation").format(device=dev))
|
|
|
|
|
# but user select non-format
|
|
|
|
|
if not self.isTrue(isformat):
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("{device} must be formatted").format(
|
|
|
|
|
device=dev))
|
|
|
|
|
if self.isTrue(isformat):
|
|
|
|
|
if not mp:
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("No need to format unused device {dev}").format(
|
|
|
|
|
dev=dev))
|
|
|
|
|
if fs in unavailFS:
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Filesystem '%s' is not available") % fs)
|
|
|
|
|
if not dev.startswith('/dev/'):
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Bind mount points should not be formatted"))
|
|
|
|
|
elif diskMount.get(dev, "") and isformat:
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_(
|
|
|
|
|
"{device} must but cannot be formatted, as it is mounted to {mountpoint} on the current system"
|
|
|
|
|
).format(
|
|
|
|
|
device=dev, mountpoint=diskMount.get(dev, '')))
|
|
|
|
|
elif isMount(dev):
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Please unmount disk {device} to "
|
|
|
|
|
"use it for install").format(device=dev))
|
|
|
|
|
|
|
|
|
|
def defaultPerformFormat(self):
|
|
|
|
|
diskFormat = dict(zip(self.Get('os_disk_dev'),
|
|
|
|
|
(self.Get('os_disk_format'))))
|
|
|
|
|
|
|
|
|
|
def wrap(info):
|
|
|
|
|
source, dest, fs, isformat = info
|
|
|
|
|
fixNtfs = self.fixNtfs
|
|
|
|
|
if not isformat and source.startswith('/dev/'):
|
|
|
|
|
if dest == '/':
|
|
|
|
|
return "on"
|
|
|
|
|
if dest and fixNtfs(diskFormat.get(source, fs)) != fixNtfs(fs):
|
|
|
|
|
return "on"
|
|
|
|
|
return isformat or ("off" if source.startswith('/dev/') else "")
|
|
|
|
|
|
|
|
|
|
return wrap
|
|
|
|
|
|
|
|
|
|
def set(self, value):
|
|
|
|
|
"""Default values for perform format"""
|
|
|
|
|
value = Variable.set(self, value)
|
|
|
|
|
DEV, MP, FS, FORMAT = 0, 1, 2, 3
|
|
|
|
|
info = zip(self.Get('os_location_source'),
|
|
|
|
|
self.Get('os_location_dest'),
|
|
|
|
|
self.Get('os_location_format'),
|
|
|
|
|
value)
|
|
|
|
|
return map(self.defaultPerformFormat(),
|
|
|
|
|
map(lambda x: [x[DEV], x[MP], x[FS], ""] \
|
|
|
|
|
if x[FORMAT] == "off" and not x[DEV].startswith("/dev/")
|
|
|
|
|
else x,
|
|
|
|
|
info))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsLocationSize(LocationHelper, SourceReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Location size
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
indexField = "os_location_source"
|
|
|
|
|
|
|
|
|
|
def init(self):
|
|
|
|
|
self.label = _("Size")
|
|
|
|
|
|
|
|
|
|
def getMap(self):
|
|
|
|
|
mapDevSize = dict(self.ZipVars('os_disk_dev', 'os_disk_size'))
|
|
|
|
|
mapDevSize.update(
|
|
|
|
|
zip(self.Get('cl_autopartition_disk_dev'),
|
|
|
|
|
self.Get('cl_autopartition_disk_size')))
|
|
|
|
|
return mapDevSize
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
return self.get_sizes(self.getMap().get)
|
|
|
|
|
|
|
|
|
|
def get_sizes(self, method):
|
|
|
|
|
devices = (device.udev.get_devname(name=x)
|
|
|
|
|
for x in self.Get(self.indexField))
|
|
|
|
|
mapped = (method(x) for x in devices)
|
|
|
|
|
return [x or "" for x in mapped]
|
|
|
|
|
|
|
|
|
|
def getMapHumanReadable(self):
|
|
|
|
|
mapDevSize = dict(zip(self.Get('os_disk_dev'),
|
|
|
|
|
self.Get('os_disk_size', humanreadable=True)))
|
|
|
|
|
mapDevSize.update(
|
|
|
|
|
zip(self.Get('cl_autopartition_disk_dev'),
|
|
|
|
|
self.Get('cl_autopartition_disk_size', humanreadable=True)))
|
|
|
|
|
return mapDevSize
|
|
|
|
|
|
|
|
|
|
def humanReadable(self):
|
|
|
|
|
return self.get_sizes(self.getMapHumanReadable().get)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableClUuidSet(Variable):
|
|
|
|
|
"""
|
|
|
|
|
Use or not UUID for /etc/fstab
|
|
|
|
|
"""
|
|
|
|
|
type = "bool"
|
|
|
|
|
opt = ["--uuid"]
|
|
|
|
|
value = "on"
|
|
|
|
|
|
|
|
|
|
def init(self):
|
|
|
|
|
self.label = _("Use UUID")
|
|
|
|
|
self.help = _("use UUID")
|
|
|
|
|
|
|
|
|
|
def uncompatible(self):
|
|
|
|
|
"""
|
|
|
|
|
Unavailable for flash installation
|
|
|
|
|
"""
|
|
|
|
|
if self.Get('os_install_root_type') == 'flash':
|
|
|
|
|
return _("Impossible to use UUID for Flash install")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#############################################################
|
|
|
|
|
# Install disk parameters
|
|
|
|
|
#############################################################
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallDiskData(ReadonlyTableVariable):
|
|
|
|
|
"""
|
|
|
|
|
Table of install disk params
|
|
|
|
|
"""
|
|
|
|
|
source = ["os_install_disk_dev",
|
|
|
|
|
"os_install_disk_mount",
|
|
|
|
|
"os_install_disk_format",
|
|
|
|
|
"os_install_disk_perform_format",
|
|
|
|
|
"os_install_disk_options",
|
|
|
|
|
"os_install_disk_id",
|
|
|
|
|
"os_install_disk_uuid",
|
|
|
|
|
"os_install_disk_use",
|
|
|
|
|
"os_install_disk_name",
|
|
|
|
|
"os_install_disk_size",
|
|
|
|
|
"os_install_disk_type",
|
|
|
|
|
"os_install_disk_part",
|
|
|
|
|
"os_install_disk_parent"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallDiskParent(SourceReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Partition parent devices using for install
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
indexField = "os_install_disk_dev"
|
|
|
|
|
|
|
|
|
|
def getMap(self):
|
|
|
|
|
diskParent = dict(self.ZipVars('os_disk_dev', 'os_disk_parent'))
|
|
|
|
|
# replace value for autopartition
|
|
|
|
|
if self.Get('cl_autopartition_set') == 'on':
|
|
|
|
|
disk_parent = self.Get('cl_autopartition_parent')
|
|
|
|
|
for disk_dev in self.Get('cl_autopartition_disk_dev'):
|
|
|
|
|
diskParent[disk_dev] = disk_parent
|
|
|
|
|
return diskParent
|
|
|
|
|
|
|
|
|
|
humanReadable = Variable.humanReadable
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallDiskDevBase(DeviceHelper, ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Variable using for resolv cyclic deps
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
if self.Get('cl_install_type') == 'flash':
|
|
|
|
|
disk = self.Get('os_install_disk_single')
|
|
|
|
|
if disk:
|
|
|
|
|
return [device.udev.get_devname(name=disk)]
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
return [dev
|
|
|
|
|
for dev, mount in self.ZipVars('os_location_source',
|
|
|
|
|
'os_location_dest')
|
|
|
|
|
if (dev.startswith("/dev") and mount and
|
|
|
|
|
not mount.startswith("/boot/efi"))]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallDiskParentBase(VariableOsInstallDiskParent):
|
|
|
|
|
"""
|
|
|
|
|
Partition parent devices using for install
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
indexField = "os_install_disk_dev_base"
|
|
|
|
|
humanReadable = Variable.humanReadable
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallDiskDev(ReadonlyVariable, DeviceHelper):
|
|
|
|
|
"""
|
|
|
|
|
Disks for installation
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
return (self.Get('os_install_uefi') +
|
|
|
|
|
self.Get('os_install_disk_dev_base'))
|
|
|
|
|
|
|
|
|
|
def humanReadable(self):
|
|
|
|
|
return map(lambda x: self.getPerfectName(x, defaultValue=x),
|
|
|
|
|
self.Get())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallDiskUuid(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Uudi for install
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
diskDev = self.Get('os_install_disk_dev')
|
|
|
|
|
hashUUID = getUUIDDict(revers=True)
|
|
|
|
|
return map(lambda x: hashUUID.get(x, "")[5:], diskDev)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallDiskMountBase(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
List mounted points for installed system
|
|
|
|
|
|
|
|
|
|
Variable use for resolv cyclic deps by UEFI vars
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
if self.Get('cl_install_type') == 'flash':
|
|
|
|
|
disk = self.Get('os_install_disk_single')
|
|
|
|
|
if disk:
|
|
|
|
|
return ["/"]
|
|
|
|
|
return []
|
|
|
|
|
return [mount
|
|
|
|
|
for dev, mount in self.ZipVars('os_location_source',
|
|
|
|
|
'os_location_dest')
|
|
|
|
|
if (dev.startswith("/dev") and mount and
|
|
|
|
|
not mount.startswith("/boot/efi"))]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallDiskMount(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
List mounted points for installed system
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def generate_uefi_mountpoints(self):
|
|
|
|
|
yield "/boot/efi"
|
|
|
|
|
for i in range(2, 20):
|
|
|
|
|
yield "/boot/efi%d" % i
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get install disk dest"""
|
|
|
|
|
mps = self.generate_uefi_mountpoints()
|
|
|
|
|
return ([next(mps) for x in self.Get('os_install_uefi')] +
|
|
|
|
|
self.Get('os_install_disk_mount_base'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallDiskUse(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
/dev/sd or UUID= list (by cl_uuid_set)
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get real id (by cl_uuid_set) device"""
|
|
|
|
|
if self.Get('cl_uuid_set') == "on":
|
|
|
|
|
return map(lambda x: "UUID=%s" % x[0] if x[0] else x[1],
|
|
|
|
|
zip(self.Get('os_install_disk_uuid'),
|
|
|
|
|
self.Get('os_install_disk_dev')))
|
|
|
|
|
else:
|
|
|
|
|
return self.Get('os_install_disk_dev')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallDiskOptions(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
List mount options of installed os
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
ssd_devices = {
|
|
|
|
|
dev for dev, ssd in self.ZipVars('install.os_device_dev',
|
|
|
|
|
'install.os_device_ssd_set')
|
|
|
|
|
if ssd == 'on'
|
|
|
|
|
}
|
|
|
|
|
old_options = {
|
|
|
|
|
dev: options for dev, options in self.ZipVars('os_disk_dev',
|
|
|
|
|
'os_disk_options')
|
|
|
|
|
if options
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def generator():
|
|
|
|
|
for disk_dev, disk_format, disk_parent in self.ZipVars(
|
|
|
|
|
'os_install_disk_dev',
|
|
|
|
|
'os_install_disk_format',
|
|
|
|
|
'os_install_disk_parent'):
|
|
|
|
|
if disk_dev in old_options:
|
|
|
|
|
yield old_options[disk_dev]
|
|
|
|
|
else:
|
|
|
|
|
all_ssd = all(x in ssd_devices
|
|
|
|
|
for x in disk_parent.split(','))
|
|
|
|
|
yield FileSystemManager.getDefaultOpt(disk_format, all_ssd)
|
|
|
|
|
|
|
|
|
|
return list(generator())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallDiskFormat(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Install list filesystem for partition devices
|
|
|
|
|
"""
|
|
|
|
|
type = "choice-list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
_format = [fs for dev, mp, fs in self.ZipVars('os_location_source',
|
|
|
|
|
'os_location_dest',
|
|
|
|
|
'os_location_format')
|
|
|
|
|
if dev.startswith('/dev/') and mp]
|
|
|
|
|
efiformat = ['vfat' for x in self.Get('os_install_uefi')]
|
|
|
|
|
return efiformat + _format
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallDiskPerformFormat(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
List need for format
|
|
|
|
|
"""
|
|
|
|
|
type = "bool-list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
_format = map(lambda x: x[2],
|
|
|
|
|
filter(lambda x: x[0].startswith('/dev/') and x[1],
|
|
|
|
|
zip(self.Get('os_location_source'),
|
|
|
|
|
self.Get('os_location_dest'),
|
|
|
|
|
self.Get('os_location_perform_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):
|
|
|
|
|
"""
|
|
|
|
|
Install partition's system id
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
def generator():
|
|
|
|
|
for (disk_dev, disk_part, disk_mount,
|
|
|
|
|
disk_format) in self.ZipVars('os_install_disk_dev',
|
|
|
|
|
'os_install_disk_part',
|
|
|
|
|
'os_install_disk_mount',
|
|
|
|
|
'os_install_disk_format'):
|
|
|
|
|
if disk_part in ("gpt", "primary", "extended", "logical"):
|
|
|
|
|
if disk_part == "gpt":
|
|
|
|
|
if disk_mount.startswith("/boot/efi"):
|
|
|
|
|
disk_format = "uefi"
|
|
|
|
|
else:
|
|
|
|
|
disk_part = "msdos"
|
|
|
|
|
fsinfo = FileSystemManager.supportFS.get(
|
|
|
|
|
disk_format, FileSystemManager.default_param)
|
|
|
|
|
yield fsinfo.get(disk_part)
|
|
|
|
|
else:
|
|
|
|
|
yield ""
|
|
|
|
|
|
|
|
|
|
return list(generator())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallDiskName(Variable):
|
|
|
|
|
"""
|
|
|
|
|
New labels for disk
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
diskLabel = dict(self.ZipVars('os_disk_dev', 'os_disk_name'))
|
|
|
|
|
|
|
|
|
|
def changeLabel(info):
|
|
|
|
|
dev, mount = info
|
|
|
|
|
if mount == '/':
|
|
|
|
|
return "%s-%s" % (self.Get('os_install_linux_shortname'),
|
|
|
|
|
self.Get('os_install_linux_ver'))
|
|
|
|
|
else:
|
|
|
|
|
return diskLabel.get(dev, '')
|
|
|
|
|
|
|
|
|
|
return map(changeLabel,
|
|
|
|
|
self.ZipVars('os_install_disk_dev',
|
|
|
|
|
'os_install_disk_mount'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallDiskSize(SourceReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
New partition sizes (for feature change partition)
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
indexField = 'os_install_disk_dev'
|
|
|
|
|
|
|
|
|
|
def getMap(self):
|
|
|
|
|
if self.GetBool("cl_autopartition_set"):
|
|
|
|
|
return {
|
|
|
|
|
dev: size for dev, size in chain(
|
|
|
|
|
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'))
|
|
|
|
|
}
|
|
|
|
|
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):
|
|
|
|
|
return {
|
|
|
|
|
device.udev.get_devname(name=dev): size
|
|
|
|
|
for dev, size in chain(
|
|
|
|
|
zip(self.Get('os_disk_dev'),
|
|
|
|
|
self.Get('os_disk_size', humanreadable=True)),
|
|
|
|
|
zip(self.Get('os_location_source'),
|
|
|
|
|
self.Get('os_location_size', humanreadable=True)))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallDiskType(SourceReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
New partition scheme (for feature change partition)
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
indexField = "os_install_disk_dev"
|
|
|
|
|
|
|
|
|
|
def getMap(self):
|
|
|
|
|
diskType = dict(self.ZipVars('os_disk_dev', 'os_disk_type'))
|
|
|
|
|
diskType.update(self.ZipVars('cl_autopartition_disk_dev',
|
|
|
|
|
'cl_autopartition_disk_type'))
|
|
|
|
|
return diskType
|
|
|
|
|
|
|
|
|
|
humanReadable = Variable.humanReadable
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallDiskPart(SourceReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Get new type partitions using for install
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
indexField = "os_install_disk_dev"
|
|
|
|
|
|
|
|
|
|
def getMap(self):
|
|
|
|
|
diskPart = dict(self.ZipVars('os_disk_dev', 'os_disk_part'))
|
|
|
|
|
diskPart.update(self.ZipVars('cl_autopartition_disk_dev',
|
|
|
|
|
'cl_autopartition_disk_part'))
|
|
|
|
|
return diskPart
|
|
|
|
|
|
|
|
|
|
humanReadable = Variable.humanReadable
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallBindData(ReadonlyTableVariable):
|
|
|
|
|
"""
|
|
|
|
|
Table of install bind mount points
|
|
|
|
|
"""
|
|
|
|
|
source = ['os_install_bind_path',
|
|
|
|
|
'os_install_bind_mountpoint']
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallBindPath(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Install directories for bind
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get install bind source"""
|
|
|
|
|
return self.Select('os_location_source',
|
|
|
|
|
where='os_location_dest',
|
|
|
|
|
func=lambda x: not x[1].startswith('/dev/') and x[0])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallBindMountpoint(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Mountpoint for install directories bind
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
return self.Select('os_location_dest',
|
|
|
|
|
where='os_location_source',
|
|
|
|
|
func=lambda x: not x[0].startswith('/dev/') and x[1])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallBootloader(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Bootloader for brief information
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def init(self):
|
|
|
|
|
self.label = _("Bootloader")
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
if self.Get('os_install_uefi_set') == 'on':
|
|
|
|
|
return "uefi"
|
|
|
|
|
else:
|
|
|
|
|
return ",".join(self.Get('os_install_mbr'))
|
|
|
|
|
|
|
|
|
|
def humanReadable(self):
|
|
|
|
|
if self.Get('os_install_uefi_set') == 'on':
|
|
|
|
|
return _("UEFI")
|
|
|
|
|
else:
|
|
|
|
|
return ",".join(self.Get('os_install_mbr', humanreadable=True))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallBootDevices(ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
Физическое устройство с которого будет производиться загрузка системы на
|
|
|
|
|
котором находится /boot или /, т.е. если / находится на RAID, расположенном
|
|
|
|
|
на двух дисках - будет эти диски
|
|
|
|
|
"""
|
|
|
|
|
type = "list"
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
bootDev = (self.Select('os_install_disk_parent',
|
|
|
|
|
where='os_install_disk_mount',
|
|
|
|
|
_in=('/', '/boot'), sort="DESC", limit=1) or
|
|
|
|
|
self.select('os_disk_parent',
|
|
|
|
|
os_disk_dev=self.Get('os_install_root_dev'),
|
|
|
|
|
limit=1))
|
|
|
|
|
if bootDev:
|
|
|
|
|
devices = bootDev.split(',')
|
|
|
|
|
return [mbr
|
|
|
|
|
for dev, mbr in self.ZipVars('os_device_dev',
|
|
|
|
|
'os_device_mbr')
|
|
|
|
|
if mbr and dev in devices]
|
|
|
|
|
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):
|
|
|
|
|
"""
|
|
|
|
|
UEFI partitions for install
|
|
|
|
|
"""
|
|
|
|
|
type = "choiceedit-list"
|
|
|
|
|
element = "selecttable"
|
|
|
|
|
opt = ["--uefi"]
|
|
|
|
|
metavalue = "EFI"
|
|
|
|
|
|
|
|
|
|
re_not0_raid = re.compile("-raid[1-9]")
|
|
|
|
|
|
|
|
|
|
def init(self):
|
|
|
|
|
self.label = _("UEFI boot")
|
|
|
|
|
self.help = _("set UEFI boot disks")
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def install_to_not_x86_64(self):
|
|
|
|
|
return self.Get('os_install_arch_machine') != 'x86_64'
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def install_without_uefiboot(self):
|
|
|
|
|
return self.Get('os_uefi_set') == 'off'
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def install_to_flash(self):
|
|
|
|
|
return self.Get('os_install_root_type') == 'flash'
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
# если используется авторазметка список разделов находится в ней
|
|
|
|
|
if self.GetBool('cl_autopartition_set'):
|
|
|
|
|
return self.Get('cl_autopartition_efi')
|
|
|
|
|
# исключаем определение UEFI если оно не может быть использовано
|
|
|
|
|
if (self.install_to_flash or self.install_to_not_x86_64 or
|
|
|
|
|
self.install_without_uefiboot):
|
|
|
|
|
return []
|
|
|
|
|
# если происходит обновление загрузчика текущей системы
|
|
|
|
|
# для определения используем /etc/fstab
|
|
|
|
|
fstabefidevs = self.Get('os_uefi')
|
|
|
|
|
if self.Get('cl_action') != 'system':
|
|
|
|
|
return fstabefidevs
|
|
|
|
|
rootdev = self.Get('os_install_root_dev')
|
|
|
|
|
rootscheme = self.select('os_disk_type',
|
|
|
|
|
os_disk_dev=rootdev, limit=1)
|
|
|
|
|
# определяем список физических дисков на которых находится rootdev
|
|
|
|
|
parents = set(self.select('os_disk_parent',
|
|
|
|
|
os_disk_dev=rootdev, limit=1).split(','))
|
|
|
|
|
efidev = [x for x in self.select('os_device_efi',
|
|
|
|
|
os_device_dev__in=parents) if x]
|
|
|
|
|
allefi = [x for x in self.select('os_device_efi',
|
|
|
|
|
os_device_type="hdd") if x]
|
|
|
|
|
# если корневое устройство расположено на ненулевом RAID - возвращаем
|
|
|
|
|
# полный список иначе только первое устройство
|
|
|
|
|
# если диски для установки не содержат EFI - берём efi из /etc/fstab
|
|
|
|
|
# если и там нет, то берём первый попавшийся EFI на любом из HDD
|
|
|
|
|
if self.re_not0_raid.search(rootscheme):
|
|
|
|
|
return efidev or fstabefidevs or allefi[:1]
|
|
|
|
|
# возвращаем первое найденное устройство
|
|
|
|
|
else:
|
|
|
|
|
return efidev[:1] or fstabefidevs or allefi[:1]
|
|
|
|
|
|
|
|
|
|
def set(self, value):
|
|
|
|
|
def transform(efidev):
|
|
|
|
|
if efidev not in self.Get('os_device_efi'):
|
|
|
|
|
return self.select('os_device_efi',
|
|
|
|
|
os_device_dev=efidev, limit=1) or efidev
|
|
|
|
|
return efidev
|
|
|
|
|
return filter(lambda x: x != "off", map(transform, value))
|
|
|
|
|
|
|
|
|
|
def choice(self):
|
|
|
|
|
deviceParentMap = self.ZipVars('os_device_dev',
|
|
|
|
|
'os_device_efi', 'os_device_name')
|
|
|
|
|
return [(efidisk, "%s (%s)" % (dev, name or _("Unknown")))
|
|
|
|
|
for dev, efidisk, name in deviceParentMap
|
|
|
|
|
if efidisk]
|
|
|
|
|
|
|
|
|
|
def check(self, 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:
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Your system must be loaded in UEFI for using this "
|
|
|
|
|
"bootloader"))
|
|
|
|
|
if self.install_to_not_x86_64:
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Architecture of the target system must be x86_64"))
|
|
|
|
|
efidevs = self.Get('os_device_efi')
|
|
|
|
|
badefi = [x for x in value if x not in efidevs]
|
|
|
|
|
if badefi:
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("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):
|
|
|
|
|
"""
|
|
|
|
|
Uncompatible with autopartition
|
|
|
|
|
"""
|
|
|
|
|
if self.Get('cl_autopartition_set') == "on":
|
|
|
|
|
return \
|
|
|
|
|
_("The layout is not available with autopartitioning")
|
|
|
|
|
if self.Get('os_install_root_type') == 'flash':
|
|
|
|
|
return \
|
|
|
|
|
_("This option not used for Flash install")
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallMbr(LocationHelper, Variable):
|
|
|
|
|
"""
|
|
|
|
|
Disks for boot mbr
|
|
|
|
|
"""
|
|
|
|
|
type = "choiceedit-list"
|
|
|
|
|
element = "selecttable"
|
|
|
|
|
opt = ["--mbr"]
|
|
|
|
|
metavalue = "MBR"
|
|
|
|
|
untrusted = True
|
|
|
|
|
check_after = ["os_install_uefi"]
|
|
|
|
|
|
|
|
|
|
def init(self):
|
|
|
|
|
self.label = _("Boot disk")
|
|
|
|
|
self.help = _("boot disk for the system bound for install")
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get default Master boot record install"""
|
|
|
|
|
if self.Get('os_install_uefi_set') == 'on':
|
|
|
|
|
return []
|
|
|
|
|
if self.Get('cl_autopartition_set') == 'on':
|
|
|
|
|
return self.Get('cl_autopartition_mbr')
|
|
|
|
|
if self.Get('os_install_root_type') in ("flash", "usb-hdd"):
|
|
|
|
|
rootdev = self.Get('os_install_root_dev')
|
|
|
|
|
device = filter(lambda x: x in rootdev,
|
|
|
|
|
self.Get('os_device_dev'))
|
|
|
|
|
if device:
|
|
|
|
|
return [device[0]]
|
|
|
|
|
else:
|
|
|
|
|
return []
|
|
|
|
|
bootdevices = self.Get('os_install_boot_devices')
|
|
|
|
|
# при установке с HDD также устанавливаем загрузчик на первый диск
|
|
|
|
|
# если есть возможность
|
|
|
|
|
if self.Get('os_root_type') == "hdd":
|
|
|
|
|
first_hdd = self.Select(
|
|
|
|
|
'os_device_dev', where='os_device_type', eq='hdd', limit=1)
|
|
|
|
|
if self.select('os_device_mbr', os_device_dev=first_hdd, limit=1):
|
|
|
|
|
bootdevices.append(first_hdd)
|
|
|
|
|
return sorted(set(bootdevices))
|
|
|
|
|
|
|
|
|
|
def choice(self):
|
|
|
|
|
deviceParentMap = self.ZipVars('os_device_mbr', 'os_device_name')
|
|
|
|
|
return [(mbrdisk, "%s (%s)" % (mbrdisk, name or _("Unknown")))
|
|
|
|
|
for mbrdisk, name in deviceParentMap
|
|
|
|
|
if mbrdisk]
|
|
|
|
|
|
|
|
|
|
def set(self, value):
|
|
|
|
|
# support off value
|
|
|
|
|
return filter(lambda x: x != "off", value)
|
|
|
|
|
|
|
|
|
|
def check(self, value):
|
|
|
|
|
if self.GetBool('cl_autopartition_set'):
|
|
|
|
|
return
|
|
|
|
|
rootType = self.Get('os_install_root_type')
|
|
|
|
|
if rootType == "flash":
|
|
|
|
|
if len(value) > 1:
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("For Flash install, you need only one disk"))
|
|
|
|
|
if value and self.Get('os_install_uefi_set') == "on":
|
|
|
|
|
raise VariableError(_("MBR is not used with the UEFI bootloader"))
|
|
|
|
|
useBtrfs = "btrfs" in self.Select('os_install_disk_format',
|
|
|
|
|
where='os_install_disk_mount',
|
|
|
|
|
_in=('/', '/boot'),
|
|
|
|
|
sort="DESC")[:1]
|
|
|
|
|
for mbrDisk in value:
|
|
|
|
|
if self.Get('cl_autopartition_set') == 'on':
|
|
|
|
|
tableOnBootDisk = self.Get('cl_autopartition_table')
|
|
|
|
|
else:
|
|
|
|
|
tableOnBootDisk = self.Select('os_device_table',
|
|
|
|
|
where="os_device_dev", eq=mbrDisk,
|
|
|
|
|
limit=1)
|
|
|
|
|
if not tableOnBootDisk:
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Disk '%s' needs a partition table for the boot record") %
|
|
|
|
|
mbrDisk)
|
|
|
|
|
if rootType == "flash":
|
|
|
|
|
if tableOnBootDisk == "gpt":
|
|
|
|
|
raise VariableError(_("You need a disk with a dos "
|
|
|
|
|
"table for Flash install"))
|
|
|
|
|
if rootType in ("usb-hdd", "hdd") and tableOnBootDisk == "gpt":
|
|
|
|
|
bbsizes = (
|
|
|
|
|
size
|
|
|
|
|
for size, disk_id, disk_parent in self.ZipVars(
|
|
|
|
|
'os_disk_size', 'os_disk_id', 'os_disk_parent'
|
|
|
|
|
)
|
|
|
|
|
if disk_id == 'EF02' and mbrDisk in disk_parent
|
|
|
|
|
)
|
|
|
|
|
bios_grub_size = self.Get('cl_autopartition_bios_grub_size')
|
|
|
|
|
for bbsize in bbsizes:
|
|
|
|
|
minsize = "%dMb" % (int(bios_grub_size) / Sizes.M)
|
|
|
|
|
if not bbsize:
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Your boot device must have a "
|
|
|
|
|
"BIOS Boot partition ({minsize})").format(
|
|
|
|
|
minsize=minsize))
|
|
|
|
|
# проверка размера EF02 при установке на btrfs
|
|
|
|
|
elif useBtrfs:
|
|
|
|
|
if (bbsize.isdigit() and bios_grub_size.isdigit() and
|
|
|
|
|
int(bbsize) < int(bios_grub_size)):
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Your boot device must have a BIOS Boot "
|
|
|
|
|
"partition ({minsize})").format(
|
|
|
|
|
minsize=minsize))
|
|
|
|
|
if mbrDisk not in self.Get('os_device_mbr'):
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Device {device} has not BIOS Boot partition").format(
|
|
|
|
|
device=mbrDisk))
|
|
|
|
|
if value:
|
|
|
|
|
if not self.Get('os_grub2_path'):
|
|
|
|
|
self.checkForLegacyGrub()
|
|
|
|
|
|
|
|
|
|
def checkForLegacyGrub(self):
|
|
|
|
|
"""Check current disk configuration for installation for install
|
|
|
|
|
legacy grub"""
|
|
|
|
|
bootDiskType, bootDiskFormat = \
|
|
|
|
|
self.Select(['os_install_disk_type',
|
|
|
|
|
'os_install_disk_format'],
|
|
|
|
|
where='os_install_disk_mount',
|
|
|
|
|
_in=('/', '/boot'),
|
|
|
|
|
sort="DESC", limit=1)
|
|
|
|
|
if "lvm" in bootDiskType or "raid" in bootDiskType:
|
|
|
|
|
raise ValueError(
|
|
|
|
|
_("Legacy grub requires a separate /boot partition "
|
|
|
|
|
"to support boot from a RAID or a LVM"))
|
|
|
|
|
if bootDiskFormat in ("btrfs", "nilfs2"):
|
|
|
|
|
raise ValueError(
|
|
|
|
|
_("To support booting from %s, legacy grub needs a "
|
|
|
|
|
"separate /boot partition") % bootDiskFormat)
|
|
|
|
|
|
|
|
|
|
def uncompatible(self):
|
|
|
|
|
"""
|
|
|
|
|
Опция несовместима с использованием UEFI
|
|
|
|
|
"""
|
|
|
|
|
if self.Get('cl_autopartition_set') == "on":
|
|
|
|
|
return \
|
|
|
|
|
_("The layout is not available with autopartitioning")
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallRootType(LocationHelper, Variable):
|
|
|
|
|
"""
|
|
|
|
|
Type of installation
|
|
|
|
|
"""
|
|
|
|
|
opt = ["--type"]
|
|
|
|
|
metavalue = "DISKTYPE"
|
|
|
|
|
type = "choice"
|
|
|
|
|
|
|
|
|
|
def init(self):
|
|
|
|
|
self.help = _("device type for the system bound for install")
|
|
|
|
|
self.label = _("Installation type")
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
selectRootType = self.Get('cl_install_type')
|
|
|
|
|
if not selectRootType:
|
|
|
|
|
return self.Get('os_root_type')
|
|
|
|
|
if selectRootType == "flash":
|
|
|
|
|
return "flash"
|
|
|
|
|
else:
|
|
|
|
|
rootdev = self.Get('os_install_root_dev')
|
|
|
|
|
devs = list(device.udev.get_disk_devices(name=rootdev))
|
|
|
|
|
if not devs:
|
|
|
|
|
return "hdd"
|
|
|
|
|
device_type = self.Select(
|
|
|
|
|
'os_device_type', where='os_device_dev', eq=devs[0], limit=1)
|
|
|
|
|
if device_type in ("usb-hdd", "flash"):
|
|
|
|
|
return "usb-hdd"
|
|
|
|
|
return "hdd"
|
|
|
|
|
|
|
|
|
|
def choice(self):
|
|
|
|
|
return [("hdd", _("Hard disk")),
|
|
|
|
|
("flash", _("USB Flash")),
|
|
|
|
|
("usb-hdd", _("USB Hard Disk"))]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallRootDev(ReadonlyVariable):
|
|
|
|
|
def get(self):
|
|
|
|
|
"""Get install root device"""
|
|
|
|
|
if self.Get('cl_action') == 'system':
|
|
|
|
|
return self.Select('os_install_disk_dev_base',
|
|
|
|
|
where='os_install_disk_mount_base',
|
|
|
|
|
eq="/", limit=1) or ''
|
|
|
|
|
else:
|
|
|
|
|
return self.Get('os_root_dev')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallRootUuid(ReadonlyVariable):
|
|
|
|
|
def get(self):
|
|
|
|
|
"""UUID корневого устройства"""
|
|
|
|
|
if self.Get('cl_action') == 'system':
|
|
|
|
|
root_dev = self.Get('os_install_root_dev')
|
|
|
|
|
return self.Select('os_install_disk_uuid',
|
|
|
|
|
where='os_install_disk_dev',
|
|
|
|
|
eq=root_dev, limit=1) or ''
|
|
|
|
|
else:
|
|
|
|
|
root_dev = self.Get('os_root_dev')
|
|
|
|
|
return self.Select('os_disk_uuid',
|
|
|
|
|
where='os_disk_dev',
|
|
|
|
|
eq=root_dev, limit=1) or ''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallFstabMountConf(DeviceHelper, ReadonlyVariable):
|
|
|
|
|
"""
|
|
|
|
|
FStab.conf contains for mount and bind points
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def _commentFstab(self, s, mp, dev):
|
|
|
|
|
"""Generate comment for /etc/fstab each line"""
|
|
|
|
|
if s.startswith("UUID"):
|
|
|
|
|
return "# %s was on %s during installation\n%s" % (mp, dev, s)
|
|
|
|
|
else:
|
|
|
|
|
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):
|
|
|
|
|
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, key=lambda x: self.separateDevice(x[1]))
|
|
|
|
|
|
|
|
|
|
rootLine = "\n".join(
|
|
|
|
|
self.formatFstab(used, dev, mp, fs, opts, "0 1")
|
|
|
|
|
for used, mp, fs, opts, dev in devicesForFstab[:1]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
otherLines = "\n".join(
|
|
|
|
|
self.formatFstab(used, dev, mp, fs, opts, "0 0")
|
|
|
|
|
for used, mp, fs, opts, dev in devicesForFstab[1:]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
bindData = self.ZipVars('os_install_bind_path',
|
|
|
|
|
'os_install_bind_mountpoint')
|
|
|
|
|
|
|
|
|
|
bindLines = "\n".join(map(lambda x: "%s\t%s\tnone\tbind\t0 0" \
|
|
|
|
|
% (x[0], x[1]), bindData))
|
|
|
|
|
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):
|
|
|
|
|
"""
|
|
|
|
|
FStab.conf contains swap partition
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
return "\n".join(map(lambda x: "%s\tnone\tswap\tsw\t0 0" % \
|
|
|
|
|
self._commentFstab(x[0], "swap", x[2]),
|
|
|
|
|
self.Select(['os_install_disk_use',
|
|
|
|
|
'os_install_disk_mount',
|
|
|
|
|
'os_install_disk_dev'],
|
|
|
|
|
where='os_install_disk_mount',
|
|
|
|
|
eq='swap')))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableClInstallType(Variable):
|
|
|
|
|
"""
|
|
|
|
|
Installation type (extension variable describe, that
|
|
|
|
|
install must be to flash or hdd
|
|
|
|
|
"""
|
|
|
|
|
type = "choice"
|
|
|
|
|
value = ""
|
|
|
|
|
|
|
|
|
|
def choice(self):
|
|
|
|
|
return ["", "flash", "hdd"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallDiskSingle(Variable):
|
|
|
|
|
"""
|
|
|
|
|
Installation disk
|
|
|
|
|
"""
|
|
|
|
|
type = "choiceedit"
|
|
|
|
|
opt = ["--disk", "-d"]
|
|
|
|
|
metavalue = 'DISK'
|
|
|
|
|
untrusted = True
|
|
|
|
|
value = ""
|
|
|
|
|
|
|
|
|
|
def init(self):
|
|
|
|
|
self.label = _("Installation disk")
|
|
|
|
|
self.help = _("set the USB Flash device")
|
|
|
|
|
|
|
|
|
|
def choice(self):
|
|
|
|
|
def generator():
|
|
|
|
|
device_names = dict(self.ZipVars('os_device_dev',
|
|
|
|
|
'os_device_name'))
|
|
|
|
|
for disk_dev, disk_type, disk_parent in self.ZipVars(
|
|
|
|
|
'os_disk_dev', 'os_disk_type', 'os_disk_parent'):
|
|
|
|
|
if disk_type == "disk-partition":
|
|
|
|
|
device_name = device_names.get(disk_parent, _("Unknown"))
|
|
|
|
|
yield disk_dev, device_name
|
|
|
|
|
return list(generator())
|
|
|
|
|
|
|
|
|
|
def check(self, value):
|
|
|
|
|
# проверить, чтобы был выбран именно раздел
|
|
|
|
|
if value not in self.Get('os_disk_dev'):
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Wrong device '%s'" % value)
|
|
|
|
|
)
|
|
|
|
|
# проверить, чтобы раздел не использовался системой (не описан в fstab)
|
|
|
|
|
mp = self.select('os_disk_mount', os_disk_dev=value, limit=1)
|
|
|
|
|
if mp:
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("The partition {dev} is already in use as {mp}").format(
|
|
|
|
|
dev=value, mp=mp))
|
|
|
|
|
# если система загружена с флешки (не iso) - нельзя переустановить
|
|
|
|
|
# эту систему
|
|
|
|
|
root_type = self.Get('os_root_type_ext')
|
|
|
|
|
if root_type in RootType.LiveFlash:
|
|
|
|
|
if value == self.Get('os_root_flash_dev'):
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("You cannot install the new system instead current"))
|
|
|
|
|
# detect using extended partition
|
|
|
|
|
disk_part = self.select('os_disk_part', os_disk_dev=value, limit=1)
|
|
|
|
|
if disk_part == 'extended':
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Unable to use extended partition %s for installation") %
|
|
|
|
|
value)
|
|
|
|
|
if "cdrom" in disk_part:
|
|
|
|
|
raise VariableError(_("Unable to use CDROM %s for installation") %
|
|
|
|
|
value)
|
|
|
|
|
if disk_part == 'gpt':
|
|
|
|
|
raise VariableError(_("You need a disk with a dos "
|
|
|
|
|
"table for Flash install"))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableOsInstallFormatSingleSet(Variable):
|
|
|
|
|
"""
|
|
|
|
|
Форматировать Flash
|
|
|
|
|
"""
|
|
|
|
|
type = "bool"
|
|
|
|
|
opt = ["--format"]
|
|
|
|
|
untrusted = True
|
|
|
|
|
value = "off"
|
|
|
|
|
|
|
|
|
|
def init(self):
|
|
|
|
|
self.label = _("Format the USB Flash")
|
|
|
|
|
self.help = _("perform the formatting of the USB Flash drive")
|
|
|
|
|
|
|
|
|
|
def must_be_formatted(self, dev):
|
|
|
|
|
fs = self.select('os_disk_format', os_disk_dev=dev, limit=1)
|
|
|
|
|
if fs != "vfat":
|
|
|
|
|
return True
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def cannot_be_formatted(self, dev):
|
|
|
|
|
flash_dev = self.Get('os_root_flash_dev')
|
|
|
|
|
return flash_dev and dev == flash_dev
|
|
|
|
|
|
|
|
|
|
def check(self, value):
|
|
|
|
|
devs = self.Get('os_disk_dev')
|
|
|
|
|
dev = self.Get('os_install_disk_single')
|
|
|
|
|
if dev not in devs:
|
|
|
|
|
return
|
|
|
|
|
if value == "on":
|
|
|
|
|
if self.cannot_be_formatted(dev):
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("You cannot format the USB Flash which "
|
|
|
|
|
"contains the current system"))
|
|
|
|
|
else:
|
|
|
|
|
if self.must_be_formatted(dev):
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("{device} must be formatted").format(device=dev))
|
|
|
|
|
if dev:
|
|
|
|
|
try:
|
|
|
|
|
with FlashDistributive(dev) as f:
|
|
|
|
|
dn = f.getDirectory()
|
|
|
|
|
df = DiskSpace()
|
|
|
|
|
free_size = df.get_free(dev)
|
|
|
|
|
squash_fn = path.join(dn, "livecd.squashfs")
|
|
|
|
|
if not path.exists(squash_fn):
|
|
|
|
|
source = self.Get('cl_image')
|
|
|
|
|
if isinstance(source, IsoDistributive):
|
|
|
|
|
image_size = source.get_squash_size()
|
|
|
|
|
if image_size > free_size:
|
|
|
|
|
raise VariableError(
|
|
|
|
|
_("Not enough free space on the "
|
|
|
|
|
"USB Flash"))
|
|
|
|
|
except DistributiveError:
|
|
|
|
|
pass
|