You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
calculate-utils-3-install/pym/install/variables/disk.py

2303 lines
82 KiB

9 years ago
# -*- 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
9 years ago
import pty
import fcntl
from subprocess import Popen
from os import path
from itertools import *
from operator import itemgetter
from calculate.install.distr import FlashDistributive, DistributiveError, \
IsoDistributive
9 years ago
from calculate.lib.datavars import (TableVariable, Variable, VariableError,
ReadonlyVariable, ReadonlyTableVariable,
SourceReadonlyVariable, VariableInterface,
HumanReadable)
from calculate.lib.utils.device import (getUdevDeviceInfo, getDeviceType,
getPartitionType, getPartitionDevice,
getRaidPartitions,
getLvmPartitions, getPartitionSize,
humanreadableSize,
getUUIDDict, getCommonDeviceName)
from calculate.install.variables.autopartition import Sizes
9 years ago
from calculate.lib.utils.files import (listDirectory, pathJoin, readFile, FStab,
isMount, getProgPath, DiskSpace)
from calculate.install.fs_manager import FileSystemManager
9 years ago
from calculate.lib.cl_lang import setLocalTranslate, _
from calculate.lib.variables.system import RootType
9 years ago
setLocalTranslate('cl_install3', sys.modules[__name__])
class DeviceHelper(VariableInterface):
sysBlockPath = '/sys/block'
9 years ago
rePassDevice = re.compile("^(?!%s)" % "|".join(['sr', 'fd',
'ram', 'loop']))
def getDeviceFromSysPath(self):
"""Get interest devices from sys block path"""
return filter(self.rePassDevice.search,
9 years ago
listDirectory(self.sysBlockPath))
9 years ago
def separateDevice(self, device):
"""
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,
9 years ago
re.findall('\d+|\D+', device))
9 years ago
def mapUdevProperty(self, var, prop, default):
"""Get each element from var through udev [prop]"""
9 years ago
return map(lambda x: getUdevDeviceInfo(name=x).get(prop, default),
self.Get(var))
9 years ago
def getPerfectName(self, device, defaultValue=None):
"""
Get dev name or human-readable lvm name
"""
info = getUdevDeviceInfo(name=device)
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:
9 years ago
return info.get('DEVNAME', '')
else:
return defaultValue
9 years ago
def getLvmName(self, device):
"""
Get lvm name
"""
9 years ago
return self.getPerfectName(device, defaultValue="")
#######################################################
# Devices variables
#######################################################
class VariableOsDeviceData(ReadonlyTableVariable):
"""
Information about disk devices
"""
type = 'table'
source = ['os_device_dev',
'os_device_table',
'os_device_type',
'os_device_ssd_set',
'os_device_virtual_set',
'os_device_map',
'os_device_syspath',
'os_device_name',
'os_device_size']
9 years ago
class VariableOsDeviceDev(DeviceHelper, ReadonlyVariable):
"""
Disk devices
"""
type = "list"
master = None
def init(self):
pass
9 years ago
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')
9 years ago
self.monitor = Popen([udevAdm, "monitor", "--kernel",
"--subsystem-match=block"], stdout=slave,
close_fds=True)
os.close(slave)
9 years ago
fl = fcntl.fcntl(self.master, fcntl.F_GETFL)
fcntl.fcntl(self.master, fcntl.F_SETFL, fl | os.O_NONBLOCK)
def _getDiskName(devpath):
"""Get devname only for by udevadm that devpath is device (disk)"""
prop = getUdevDeviceInfo(devpath)
9 years ago
if (prop.get("ID_TYPE", "") == "disk" or
path.exists(path.join(devpath, "device"))) and \
prop.get("DEVTYPE", "") == "disk":
return prop.get('DEVNAME', '')
# get devices from /sys/block directories(discard mem,sr,loop and other)
return sorted(
9 years ago
filter(lambda x: x,
map(_getDiskName,
map(lambda x: path.join(self.sysBlockPath, x),
self.getDeviceFromSysPath()))),
key=self.separateDevice)
def close(self):
try:
if self.monitor:
self.monitor.kill()
self.monitor.wait()
9 years ago
except Exception:
pass
def refresh(self):
try:
if self.monitor:
9 years ago
res = os.read(self.master, 65535)
if res:
while len(res) == 65535:
9 years ago
res = os.read(self.master, 65535)
self.parent.Invalidate(self.name)
self.parent.Invalidate('os_install_disk_uuid')
self.parent.Invalidate('os_disk_dev')
getUdevDeviceInfo.clearCache()
except OSError as e:
pass
9 years ago
class VariableOsDeviceType(ReadonlyVariable):
"""
Device type (hdd,cdrom,usb-flash)
"""
type = "list"
9 years ago
def getType(self, device):
if path.basename(device) in self.usbdevices:
# check for usb flash (removeable fiel in sysfs contains "1")
9 years ago
removablePath = '/sys/block/%s/removable' % path.basename(device)
if readFile(removablePath).strip() == "1":
9 years ago
return "flash"
else:
9 years ago
return "usb-hdd"
else:
9 years ago
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 path.exists(diskIdPath):
self.usbdevices = \
9 years ago
map(lambda x: \
os.readlink(path.join(diskIdPath, x)).rpartition('/')[
2],
filter(lambda x: x.startswith('usb-'),
listDirectory(diskIdPath)))
else:
self.usbdevices = []
return map(self.getType,
9 years ago
self.Get('os_device_dev'))
class VariableOsDeviceMap(ReadonlyVariable):
"""
Map number for grub
Using for legecy grub (DEPRECATATED)
"""
type = "list"
def get(self):
9 years ago
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"""
9 years ago
def isSsd(device, name):
prop = getUdevDeviceInfo(name=device)
rpm = prop.get(self.udev_property, None)
if (any(x in device 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')))
9 years ago
class VariableOsDeviceSyspath(ReadonlyVariable):
"""
Table on device
"""
type = "list"
udev_property = 'DEVPATH'
def get(self):
"""Get device partition table"""
9 years ago
def getSysPath(device):
prop = getUdevDeviceInfo(name=device)
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"
9 years ago
virtual_names = ("VBOX", "VMWare")
virtual_syspath = ("virtio",)
def get(self):
"""Get device partition table"""
9 years ago
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"
9 years ago
def getTableByChild(self, device):
"""Get table by child partitions"""
9 years ago
syspath = getUdevDeviceInfo(name=device).get('DEVPATH', '')
if not syspath.startswith('/sys'):
9 years ago
syspath = pathJoin('/sys', syspath)
shortnameDevice = path.basename(device)
9 years ago
childs = filter(lambda x: x.startswith(shortnameDevice),
listDirectory(syspath))
if childs:
9 years ago
child = pathJoin(syspath, childs[0])
udevinfo = getUdevDeviceInfo(path=child)
9 years ago
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')
9 years ago
def getTable(device):
prop = getUdevDeviceInfo(name=device)
return prop.get('ID_PART_TABLE_TYPE',
9 years ago
self.getTableByChild(device))
def getByAutopartition(device):
if autopartition and autoDevice == device:
return self.Get('cl_autopartition_table')
else:
return getTable(device)
9 years ago
return map(getByAutopartition,
9 years ago
self.Get('os_device_dev'))
class VariableOsDeviceName(ReadonlyVariable):
"""
Name of device
"""
type = "list"
nameless_devices = {
'nvme': 'NVME',
'mmcblk': 'Multimedia Card'
}
9 years ago
def getName(self, device):
prop = getUdevDeviceInfo(name=device)
9 years ago
devicepath = prop.get("DEVPATH", "")
if devicepath:
if not devicepath.startswith("/sys"):
9 years ago
devicepath = pathJoin("/sys", devicepath)
pathVendor = "%s/device/vendor" % devicepath
pathModel = "%s/device/model" % devicepath
vendor = readFile(pathVendor).strip()
model = readFile(pathModel).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,
9 years ago
self.Get('os_device_dev'))
class VariableOsDeviceSize(ReadonlyVariable):
"""
Name of device
"""
type = "list"
def get(self):
"""Get device size"""
9 years ago
return map(lambda x: getPartitionSize(name=x, inBytes=True),
self.Get('os_device_dev'))
9 years ago
def humanReadable(self):
return map(humanreadableSize,
9 years ago
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']
9 years ago
class VariableOsDiskDev(DeviceHelper, ReadonlyVariable):
"""
List of available partition devices
"""
type = "list"
9 years ago
def selfOrPartition(self, devpath):
"""Return self device or partitions if it has them"""
# search partition in device
# get devices in sysfs which startswith devname
partitions = \
9 years ago
filter(lambda x: x.startswith(path.basename(devpath)),
listDirectory(devpath))
# if partition found then return them or partition on them
if partitions:
9 years ago
return filter(lambda x: x,
map(lambda x: self.selfOrPartition(
path.join(devpath, x)),
partitions))
else:
return devpath
def get(self):
# get device from syspath, then get partitions of this device or
# whole device, convert to single list,
# get for each name from udev
# remove empty
# sort by name and partition number
disks = self.getDeviceFromSysPath()
return list(sorted(
9 years ago
filter(lambda x: x,
map(lambda x: getUdevDeviceInfo(x).get('DEVNAME', ''),
reduce(lambda x, y: x + ([y] if type(y) == str else y),
map(lambda x: self.selfOrPartition(
path.join(self.sysBlockPath, x)),
disks), []))), key=self.separateDevice))
def humanReadable(self):
return map(self.getPerfectName,
9 years ago
self.Get())
9 years ago
class VariableOsDiskMount(DeviceHelper, ReadonlyVariable):
"""
List mounted points for current operation system
"""
type = "list"
def get(self):
disk_hash = self.Get('os_disk_dev')
9 years ago
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 "",
9 years ago
self.Get('os_disk_dev'))
class VariableOsDiskContent(ReadonlyVariable):
"""
Partition content
"""
type = "list"
def get(self):
"""
TODO: need to write
"""
9 years ago
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"""
9 years ago
fstab = FStab('/etc/fstab', devs=self.Get('os_disk_dev'))
def getFormat(device):
prop = getUdevDeviceInfo(name=device)
return prop.get('FSTAB_TYPE') or \
9 years ago
fstab.getBy(what=fstab.TYPE, eq=device) or \
prop.get('ID_FS_TYPE', '')
return map(getFormat,
9 years ago
self.Get('os_disk_dev'))
class VariableOsDiskType(ReadonlyVariable):
"""
List type (lvm,raid,partition,disk)
"""
type = "list"
def get(self):
"""Get partition scheme"""
9 years ago
types = map(lambda x: (x, getDeviceType(name=x)),
self.Get('os_disk_dev'))
lvmUsedDisks = {}
raidUsedDisks = {}
9 years ago
def forMember(typeInfo):
9 years ago
diskName, diskType = typeInfo
if diskName in raidUsedDisks:
9 years ago
diskType = "%s-raidmember(%s)" % (diskType,
raidUsedDisks[diskName])
if diskName in lvmUsedDisks:
9 years ago
diskType = "%s-lvmmember(%s)" % (diskType,
",".join(
lvmUsedDisks[diskName]))
return diskName, diskType
9 years ago
for device, diskType in types:
prop = getUdevDeviceInfo(name=device)
if "raid" in diskType:
9 years ago
for x in getRaidPartitions(prop.get('DEVPATH', '')):
raidUsedDisks[x] = device
if diskType.endswith("lvm"):
9 years ago
for x in getLvmPartitions(prop.get('DM_VG_NAME', ''),
prop.get('DM_LV_NAME', '')):
if x in lvmUsedDisks:
lvmUsedDisks[x].append(device)
else:
lvmUsedDisks[x] = [device]
9 years ago
return map(lambda x: x[1],
map(forMember,
types))
12 years ago
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())
9 years ago
class VariableOsDiskLvm(DeviceHelper, ReadonlyVariable):
"""
LVM vgname and lvname
"""
type = "list"
9 years ago
def get(self):
"""Get each element from var through udev [prop]"""
return map(self.getLvmName,
9 years ago
self.Get('os_disk_dev'))
9 years ago
class VariableOsDiskUuid(DeviceHelper, ReadonlyVariable):
"""
List uudi for partition devices
"""
12 years ago
type = "list"
def get(self):
9 years ago
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 map(getPartitionDevice,
9 years ago
map(lambda x: getUdevDeviceInfo(name=x).get('DEVPATH', ''),
self.Get('os_disk_dev')))
9 years ago
class VariableOsDiskId(DeviceHelper, ReadonlyVariable):
"""
Partition's system id
"""
type = "list"
def get(self):
"""Get disk id"""
9 years ago
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'),
9 years ago
self.Get('os_device_map')))
def getGrubMap(devParent):
9 years ago
device, parent = devParent
prop = getUdevDeviceInfo(name=device)
9 years ago
partnum = int(prop.get('ID_PART_ENTRY_NUMBER', 0))
if parent in devicesMap.keys() and partnum:
9 years ago
return "%s,%d" % (devicesMap[parent], partnum - 1)
else:
return ""
9 years ago
return map(getGrubMap,
9 years ago
zip(self.Get('os_disk_dev'),
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):
return \
9 years ago
map(lambda x: x[0] if x[1] else "",
map(lambda x: (
getPartitionType(getUdevDeviceInfo(name=x[0])), x[1]),
9 years ago
self.ZipVars('os_disk_dev', 'os_disk_parent')))
class VariableOsDiskSize(ReadonlyVariable):
"""
Partition size
"""
type = "list"
def get(self):
"""Get disk size"""
9 years ago
return map(lambda x: getPartitionSize(name=x, inBytes=True),
self.Get('os_disk_dev'))
def humanReadable(self):
return map(humanreadableSize,
9 years ago
self.Get())
9 years ago
class VariableOsDiskName(DeviceHelper, ReadonlyVariable):
"""
Label of partitions
"""
type = "list"
def get(self):
"""Get disk label"""
9 years ago
return self.mapUdevProperty('os_disk_dev', 'ID_FS_LABEL', '')
class VariableOsDiskOptions(ReadonlyVariable):
"""
List mount options
"""
type = "list"
def get(self):
9 years ago
fstab = FStab('/etc/fstab', devs=self.Get('os_disk_dev'))
def getFormat(device):
9 years ago
return fstab.getBy(what=fstab.OPTS, eq=device)
return map(getFormat,
9 years ago
self.Get('os_disk_dev'))
################################################
# Bind mount points
################################################
class VariableOsBindData(ReadonlyTableVariable):
"""
Table of bind mount points
"""
source = ['os_bind_path',
'os_bind_mountpoint']
9 years ago
class VariableOsBindPath(ReadonlyVariable):
"""
List source bind path
"""
type = "list"
def get(self):
9 years ago
fstab = FStab('/etc/fstab', devs=self.Get('os_disk_dev'))
return fstab.getBy(what=fstab.NAME, where=fstab.OPTS,
contains="bind", allentry=True)
9 years ago
class VariableOsBindMountpoint(ReadonlyVariable):
"""
Mountpoints for directories bind
"""
type = "list"
def get(self):
9 years ago
fstab = FStab('/etc/fstab', devs=self.Get('os_disk_dev'))
return fstab.getBy(what=fstab.DIR, where=fstab.OPTS,
contains="bind", allentry=True)
9 years ago
######################################################################
# Userselect partion parameters
######################################################################
9 years ago
class LocationHelper(VariableInterface):
"""
Location variable
"""
def uncompatible(self):
"""
Network setting up unavailable for flash installation
"""
if self.Get('cl_autopartition_set') == "on":
return \
12 years ago
_("The layout is not available with autopartitioning")
return ""
9 years ago
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',
9 years ago
'os_install_disk_mount',
'os_install_disk_format',
'os_install_disk_perform_format',
'os_install_disk_size'),
('os_install_bind_path',
9 years ago
'os_install_bind_mountpoint', '', '', '')]
def init(self):
self.label = _("Layout")
9 years ago
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(
9 years ago
_("Source variable %s does not contain a list") % varname)
return list(
9 years ago
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 [[]]
9 years ago
class VariableOsLocationData(LocationHelper, TableVariable):
"""
Select installation disk variable
"""
9 years ago
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"))
12 years ago
self.label = _("Layout")
9 years ago
def set(self, value):
return sorted(value, key=lambda x: x and x[0])
9 years ago
class VariableOsLocationSource(LocationHelper, DeviceHelper, Variable):
"""
Source disk or directory
"""
type = "choiceedit-list"
def init(self):
self.label = _("Disk or directory")
9 years ago
def availDevs(self, choice=False):
"""
Available devices
"""
if self.Get('cl_install_type') == 'flash':
flashDrives = self.Select('os_device_dev',
where='os_device_type',
eq="flash")
return self.Select('os_disk_dev',
where='os_disk_parent',
_in=flashDrives)
else:
if choice:
9 years ago
return self.Get('os_disk_dev') + self.Get('os_bind_path')
else:
devFrom = self.Get('cl_install_dev_from')
if self.Get('os_install_scratch') == 'on':
return self.Select('os_disk_dev',
where='os_disk_mount',
9 years ago
func=lambda x: x[0] == "swap" or
x[1] == devFrom)
else:
return self.Select('os_disk_dev',
where='os_disk_mount',
9 years ago
func=lambda x: not x[0] in ("", "/") or
x[1] == devFrom) + \
self.Get('os_bind_path')
def get(self):
if self.Get('cl_autopartition_set') == "on":
return map(getCommonDeviceName,
9 years ago
self.Get('cl_autopartition_disk_dev')) + \
self.Get('cl_autopartition_bind_path')
else:
return self.availDevs()
9 years ago
def set(self, value):
def normpath(val):
if type(val) == str and val:
return path.normpath(val)
return val
9 years ago
return map(normpath, value)
def choice(self):
9 years ago
return map(lambda x: (x, self.getPerfectName(x) or x),
self.fixOsDiskDev(self.availDevs(choice=True))) \
+ [("", "")]
9 years ago
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:
excludeDisks = self.Select('os_disk_dev',
9 years ago
where='os_disk_parent',
eq=self.Get('cl_autopartition_device'))
appendDisks = self.Get('cl_autopartition_disk_dev') + \
self.Get('cl_autopartition_bind_path')
return list(ifilterfalse(excludeDisks.__contains__,
9 years ago
sourcelist)) + appendDisks
else:
return sourcelist
9 years ago
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
###########################
9 years ago
disks = filter(lambda x: x.startswith('/dev/'), value)
12 years ago
# get original /dev names
9 years ago
cnDisks = map(lambda x: getUdevDeviceInfo(name=x).get('DEVNAME', x),
disks)
12 years ago
wrongDevices = list(set(cnDisks) - \
9 years ago
set(self.fixOsDiskDev()))
if wrongDevices:
9 years ago
raise VariableError(_("Wrong device '%s'") % wrongDevices[0])
wrongSource = filter(lambda x: x and not x.startswith('/'), value)
if wrongSource:
raise VariableError(
9 years ago
_("Wrong bind mount point '%s'") % wrongSource[0])
##########################
# detect duplicate devices
##########################
9 years ago
dupDevices = list(set(filter(lambda x: disks.count(x) > 1,
disks)))
if dupDevices:
raise VariableError(
9 years ago
_("Device '%s' is used more than once") % dupDevices[0])
9 years ago
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')
9 years ago
def installMountPoint(info):
9 years ago
dev, mount = info
if self.Get('cl_action') == 'system':
if self.Get('cl_install_type') == 'flash':
9 years ago
if dev == singleDevice:
return "/"
else:
return ""
else:
9 years ago
if dev == installFrom:
return "/"
elif mount == "/":
return ""
return mount
9 years ago
return map(installMountPoint,
9 years ago
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'))))
9 years ago
def set(self, value):
"""Add abilitiy not specify root"""
9 years ago
def normpath(val):
if type(val) == str and val:
return path.normpath(val)
return val
9 years ago
def eficonvert(val):
9 years ago
if val.lower() in ("efi", "uefi"):
return "/boot/efi"
else:
return val
9 years ago
value = map(normpath, map(eficonvert, value))
return map(lambda x: x or "/", value)
def choice(self):
9 years ago
if self.Get('cl_install_type') == 'flash':
return ["/", ""]
else:
return ['/', '/boot', '/var/calculate', '/home',
'/usr', '/var', '/tmp', 'swap', '/boot/efi', '']
9 years ago
def check(self, value):
"""Check set location source"""
if self.Get('cl_autopartition_set') == "on":
return
################################
# check size for root device
################################
osInstallRootType = self.Get('os_install_root_type')
if osInstallRootType != "flash" and \
9 years ago
not "/usr" in value:
for mp, size in filter(lambda x: x[0] == '/' and x[1].isdigit() and \
int(x[1]) < 7 * 1024 * 1024 * 1024,
izip(value,
self.Get("os_location_size"))):
raise VariableError(
9 years ago
_("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
9 years ago
if not filter(lambda x: x == "/", value):
raise VariableError(_("To install the system, you need to "
"specify the root device"))
################################
9 years ago
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 duplicate mps
##########################
9 years ago
dupMP = list(set(filter(lambda x: value.count(x) > 1,
filter(lambda x: x and x != "swap",
value))))
if dupMP:
raise VariableError(
9 years ago
_("Mount point '%s' is used more than once") % dupMP[0])
#########################
# detect wrong bind
#########################
9 years ago
wrongBind = filter(lambda x: not x[0].startswith("/") or
not x[1].startswith("/"),
binds)
if wrongBind:
raise VariableError(
9 years ago
_("Incorrect mount point (bind '%(bindSrc)s' to "
"'%(bindDst)s')") \
% {'bindSrc': wrongBind[0][0],
'bindDst': wrongBind[0][1]})
#########################################
# Check '/' in start path of dest pointst
#########################################
9 years ago
wrongMP = filter(lambda x: x and not x.startswith("/") and x != "swap",
value)
if wrongMP:
9 years ago
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 "
9 years ago
"installation") % rootDev)
#################################
# detect using extended partition
#################################
extendedPartitions = self.Select('os_install_disk_dev',
where='os_install_disk_part',
9 years ago
eq='extended', limit=1)
if extendedPartitions:
raise VariableError(
9 years ago
_("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',
9 years ago
like='cdrom', limit=1)
if cdromPartitions:
9 years ago
raise VariableError(_("Unable to use CDROM %s for installation") %
cdromPartitions)
#############################
# detect right part for uefi#
#############################
9 years ago
efiDisks = map(lambda x: getCommonDeviceName(x[0]),
filter(lambda x: x[1] == '/boot/efi',
zip(source, value)))
wrongPart = self.Select('os_install_disk_dev',
9 years ago
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
###############################
9 years ago
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:
9 years ago
incompBind = filter(lambda x: x[1] == wrongBind[0],
zip(srcMountPoints, destMountPoints))
raise VariableError(
12 years ago
_("Source directory %(src)s is already used "
9 years ago
"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(
12 years ago
_("Flash install does not support multipartition mode"))
9 years ago
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'))
9 years ago
for checkType in ("raid", "lvm"):
memberData = filter(lambda x: checkType + "member" in x[1],
installTypes)
if memberData:
raise VariableError(
9 years ago
_(
"Unable to use {part} partition used by active {typepart} for installation").format(
typepart=checkType.upper(),
part=memberData[0][0]))
9 years ago
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') + \
9 years ago
map(lambda x: "", self.Get('cl_autopartition_bind_path'))
else:
mount = self.Get("os_location_dest")
source = self.Get("os_location_source")
9 years ago
value = [""] * len(source)
return map(self.defaultFormat(),
zip(source, mount, value))
def choice(self):
if self.Get('cl_install_type') == "flash":
9 years ago
return ["", "vfat"]
else:
9 years ago
return [""] + self.Get('os_format_type')
def defaultFormat(self):
"""Describe default value for filesystem"""
diskFormat = dict(zip(self.Get('os_disk_dev'),
9 years ago
(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'))
9 years ago
def wrap(info):
9 years ago
dev, mount, fs = info
if mount and not fs and dev.startswith('/dev/'):
if mount == "swap":
return "swap"
elif mount == '/boot/efi':
return "vfat"
if dev in diskFormat and diskFormat[dev] in availFS:
if mount.count('/') == 1:
9 years ago
if FileSystemManager.checkFSForTypeMount(
diskFormat[dev],
osInstallRootType, mount):
return diskFormat[dev]
else:
return diskFormat[dev]
return FileSystemManager.defaultFS.get(osInstallRootType,
"ext4")
return fs
9 years ago
return wrap
9 years ago
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(),
9 years ago
zip(source, mount, value))
9 years ago
def check(self, value):
osInstallRootType = self.Get('os_install_root_type')
devMpFs = zip(self.Get('os_location_source'),
9 years ago
self.Get('os_location_dest'), value)
for dev, mp, fs in devMpFs:
if dev.startswith('/') and not dev.startswith('/dev/') and fs:
raise VariableError(
12 years ago
_("The bind mount point does not use filesystem"))
# check compatible fs for mount point only root dirs
9 years ago
if dev.startswith('/dev/') and mp and (mp.count('/') == 1 or
mp in (
'/var/calculate',
'/boot/efi')):
if not FileSystemManager.checkFSForTypeMount(fs,
9 years ago
osInstallRootType,
mp):
raise VariableError(
12 years ago
_("The filesystem for '%(mp)s' should not be '%(opt)s'")
9 years ago
% {'mp': mp, 'opt': fs} + " " +
12 years ago
_("for {typedisk} install").format(
typedisk=osInstallRootType))
if mp == "swap" and fs != "swap":
raise VariableError(
9 years ago
_(
"The swap partition {dev} must be formatted as swap").format(
dev=dev))
9 years ago
class VariableOsLocationPerformFormat(LocationHelper, Variable):
type = "boolauto-list"
def init(self):
self.label = _("Format")
def get(self):
if self.Get('cl_autopartition_set') == "on":
9 years ago
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")
9 years ago
value = [""] * len(source)
return map(self.defaultPerformFormat(),
zip(source, mount, fs, value))
9 years ago
fixNtfs = lambda self, x: {'ntfs-3g': 'ntfs'}.get(x, x)
12 years ago
9 years ago
def check(self, value):
"""Check perform format
Check what format will perform for need partition.
At example on change filesystem on partition.
"""
9 years ago
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'),
9 years ago
(self.Get('os_disk_format'))))
diskMount = dict(zip(self.Get('os_disk_dev'),
9 years ago
(self.Get('os_disk_mount'))))
unavailFS = set(self.Select('os_format_type',
where='os_format_use',
eq="no"))
12 years ago
fixNtfs = self.fixNtfs
9 years ago
for dev, mp, fs, isformat in info:
# should format if change fs or partition is root, but non flash
12 years ago
partitionMustFormat = \
9 years ago
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
9 years ago
if diskMount.get(dev, ''):
raise VariableError(
12 years ago
_("{device} must but cannot be formatted, as it is "
9 years ago
"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(
12 years ago
_("{device} must be formatted").format(
device=dev))
if self.isTrue(isformat):
if not mp:
raise VariableError(
12 years ago
_("No need to format unused device {dev}").format(
dev=dev))
if fs in unavailFS:
raise VariableError(
9 years ago
_("Filesystem '%s' is not available") % fs)
if not dev.startswith('/dev/'):
raise VariableError(
_("Bind mount points should not be formatted"))
9 years ago
elif diskMount.get(dev, "") and isformat:
raise VariableError(
9 years ago
_(
"{device} must but cannot be formatted, as it is mounted to {mountpoint} on the current system"
).format(
9 years ago
device=dev, mountpoint=diskMount.get(dev, '')))
elif isMount(dev):
raise VariableError(
12 years ago
_("Please unmount disk {device} to "
"use it for install").format(device=dev))
def defaultPerformFormat(self):
diskFormat = dict(zip(self.Get('os_disk_dev'),
9 years ago
(self.Get('os_disk_format'))))
def wrap(info):
9 years ago
source, dest, fs, isformat = info
12 years ago
fixNtfs = self.fixNtfs
if not isformat and source.startswith('/dev/'):
if dest == '/':
return "on"
9 years ago
if dest and fixNtfs(diskFormat.get(source, fs)) != fixNtfs(fs):
return "on"
return isformat or ("off" if source.startswith('/dev/') else "")
9 years ago
return wrap
9 years ago
def set(self, value):
"""Default values for perform format"""
9 years ago
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(),
9 years ago
map(lambda x: [x[DEV], x[MP], x[FS], ""] \
if x[FORMAT] == "off" and not x[DEV].startswith("/dev/")
else x,
info))
9 years ago
class VariableOsLocationSize(LocationHelper, SourceReadonlyVariable):
"""
Location size
"""
type = "list"
indexField = "os_location_source"
def init(self):
self.label = _("Size")
def getMap(self):
9 years ago
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):
9 years ago
return map(lambda x: x or "",
map(self.getMap().get,
map(getCommonDeviceName,
self.Get(self.indexField))))
def getMapHumanReadable(self):
9 years ago
# return map(lambda x:humanreadableSize(x) if x else "",
# self.Get())
mapDevSize = dict(zip(self.Get('os_disk_dev'),
9 years ago
self.Get('os_disk_size', humanreadable=True)))
mapDevSize.update(
zip(self.Get('cl_autopartition_disk_dev'),
9 years ago
self.Get('cl_autopartition_disk_size', humanreadable=True)))
return mapDevSize
def humanReadable(self):
9 years ago
return map(lambda x: x or "",
map(self.getMapHumanReadable().get,
map(getCommonDeviceName,
self.Get(self.indexField))))
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':
12 years ago
return _("Impossible to use UUID for Flash install")
9 years ago
#############################################################
# 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"]
9 years ago
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',
9 years ago
where='os_install_disk_mount_base',
eq='/')
else:
validParent = self.Select('os_device_dev',
9 years ago
where='os_device_type', eq='hdd')
efiPartitions = self.Select('os_disk_dev',
9 years ago
where=['os_disk_id', 'os_disk_parent'],
func=lambda x: x[0] == 'EF00' and x[
1] in validParent)
return list(set(efiPartitions) - set(self.Get('os_location_source')))
9 years ago
class VariableOsAddonDiskDev(DeviceHelper, ReadonlyVariable):
type = "list"
9 years ago
def get(self):
if self.Get('os_install_uefi_set') == 'on':
if not "/boot/efi" in self.Get('os_location_dest'):
efiPartition = self.Get('os_install_disk_efi')
if efiPartition:
return efiPartition[:1]
return []
9 years ago
class VariableOsAddonDiskMount(DeviceHelper, ReadonlyVariable):
type = "list"
9 years ago
def get(self):
if self.Get('os_install_uefi_set') == 'on':
if not "/boot/efi" in self.Get('os_location_dest'):
efiPartition = self.Get('os_install_disk_efi')
if efiPartition:
return ['/boot/efi']
return []
9 years ago
class VariableOsAddonDiskFormat(DeviceHelper, ReadonlyVariable):
type = "list"
9 years ago
def get(self):
if self.Get('os_install_uefi_set') == 'on':
if not "/boot/efi" in self.Get('os_location_dest'):
efiPartition = self.Get('os_install_disk_efi')
if efiPartition:
return ['vfat']
return []
9 years ago
class VariableOsAddonDiskPerformFormat(DeviceHelper, ReadonlyVariable):
type = "list"
9 years ago
def get(self):
if self.Get('os_install_uefi_set') == 'on':
if not "/boot/efi" in self.Get('os_location_dest'):
efiPartition = self.Get('os_install_disk_efi')
if efiPartition:
9 years ago
fsPart = self.Select('os_disk_format', where='os_disk_dev',
eq=efiPartition[0], limit=1)
if fsPart != "vfat":
return ['on']
else:
return ['off']
return []
9 years ago
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 [getCommonDeviceName(disk)]
return []
return map(getCommonDeviceName,
9 years ago
map(lambda x: x[0],
filter(lambda x: x[0].startswith('/dev/') and x[1],
zip(self.Get('os_location_source'),
self.Get('os_location_dest')))))
class VariableOsInstallDiskParentBase(SourceReadonlyVariable):
"""
Partition parent devices using for install
"""
type = "list"
indexField = "os_install_disk_dev_base"
def getMap(self):
9 years ago
diskParent = dict(self.ZipVars('os_disk_dev', 'os_disk_parent'))
# replace value for autopartition
if self.Get('cl_autopartition_set') == 'on':
diskParent.update(zip(self.Get('cl_autopartition_disk_dev'),
9 years ago
self.Get('cl_autopartition_device') *
len(self.Get('cl_autopartition_disk_dev'))))
return diskParent
humanReadable = Variable.humanReadable
9 years ago
class VariableOsInstallDiskDev(ReadonlyVariable, DeviceHelper):
"""
Disks for installation
"""
type = "list"
def get(self):
9 years ago
return self.Get('os_addon_disk_dev') + \
self.Get('os_install_disk_dev_base')
def humanReadable(self):
9 years ago
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)
9 years ago
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 []
9 years ago
return map(lambda x: x[1],
filter(lambda x: x[0].startswith('/dev/') and x[1],
zip(self.Get('os_location_source'),
self.Get('os_location_dest'))))
class VariableOsInstallDiskMount(ReadonlyVariable):
"""
List mounted points for installed system
"""
type = "list"
def get(self):
"""Get install disk dest"""
9 years ago
return self.Get('os_addon_disk_mount') + \
self.Get('os_install_disk_mount_base')
9 years ago
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":
9 years ago
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')
9 years ago
class VariableOsInstallDiskOptions(ReadonlyVariable):
"""
List mount options of installed os
"""
type = "list"
def get(self):
def postProcess(opt):
9 years ago
l_opt = filter(None, opt.split(','))
return ",".join(l_opt)
9 years ago
diskOpts = dict(filter(lambda x: x[1],
zip(self.Get('os_disk_dev'),
self.Get('os_disk_options'))))
ssdDisk = dict(self.ZipVars('install.os_device_dev',
'install.os_device_ssd_set'))
return map(postProcess,
9 years ago
map(lambda x: diskOpts.get(x[0], x[1]),
map(lambda x: (
x[0], FileSystemManager.getDefaultOpt(x[1],
ssd=ssdDisk.get(
x[2],
'off') == 'on')),
9 years ago
self.ZipVars('os_install_disk_dev',
'os_install_disk_format',
'os_install_disk_parent'))))
class VariableOsInstallDiskFormat(ReadonlyVariable):
"""
Install list filesystem for partition devices
"""
type = "choice-list"
def get(self):
9 years ago
_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_format'))))
return self.Get('os_addon_disk_format') + _format
class VariableOsInstallDiskPerformFormat(ReadonlyVariable):
"""
List need for format
"""
type = "bool-list"
def get(self):
9 years ago
_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'))))
return self.Get('os_addon_disk_perform_format') + _format
class VariableOsInstallDiskId(ReadonlyVariable):
"""
Install partition's system id
"""
type = "list"
def get(self):
diskId = dict(zip(self.Get('os_disk_dev'),
self.Get('os_disk_id')))
diskId.update(zip(self.Get('cl_autopartition_disk_dev'),
9 years ago
[""] * len(self.Get('cl_autopartition_disk_dev'))))
def getIdByFS(fs, parttable, oldid, mp):
if parttable == "gpt":
if mp == '/boot/efi':
fs = 'uefi'
9 years ago
fsinfo = FileSystemManager.supportFS.get(fs, {})
return fsinfo.get('gpt', '8300')
elif parttable in ("primary", "extended", "logical"):
fsinfo = FileSystemManager.supportFS.get(fs, {})
return fsinfo.get('msdos', '83')
return oldid
9 years ago
FORMAT, PART, DEV, MOUNT, PARENT = 0, 1, 2, 3, 4
return map(lambda x: getIdByFS(x[FORMAT],
x[PART], diskId.get(x[DEV], ''), x[MOUNT]
) if x[PARENT] else '',
self.ZipVars('os_install_disk_format',
'os_install_disk_part',
'os_install_disk_dev',
'os_install_disk_mount',
'os_install_disk_parent'))
class VariableOsInstallDiskName(Variable):
"""
New labels for disk
"""
type = "list"
9 years ago
def get(self):
9 years ago
diskLabel = dict(self.ZipVars('os_disk_dev', 'os_disk_name'))
def changeLabel(info):
9 years ago
dev, mount = info
if mount == '/':
9 years ago
return "%s-%s" % (self.Get('os_install_linux_shortname'),
self.Get('os_install_linux_ver'))
else:
9 years ago
return diskLabel.get(dev, '')
return map(changeLabel,
9 years ago
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):
9 years ago
retDict = dict(self.ZipVars('os_disk_dev', 'os_disk_size'))
retDict.update(
dict(self.ZipVars('os_location_source', 'os_location_size')))
return retDict
def getMapHumanReadable(self):
retDict = dict(zip(map(getCommonDeviceName,
9 years ago
self.Get('os_disk_dev')),
self.Get('os_disk_size', humanreadable=True)))
retDict.update(dict(zip(map(getCommonDeviceName,
9 years ago
self.Get('os_location_source')),
self.Get('os_location_size',
humanreadable=True))))
return retDict
9 years ago
class VariableOsInstallDiskType(SourceReadonlyVariable):
"""
New partition scheme (for feature change partition)
"""
type = "list"
indexField = "os_install_disk_dev"
def getMap(self):
9 years ago
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
9 years ago
class VariableOsInstallDiskParent(SourceReadonlyVariable):
"""
Partition parent devices using for install
"""
type = "list"
indexField = "os_install_disk_dev"
def getMap(self):
9 years ago
diskParent = dict(self.ZipVars('os_disk_dev', 'os_disk_parent'))
# replace value for autopartition
if self.Get('cl_autopartition_set') == 'on':
diskParent.update(zip(self.Get('cl_autopartition_disk_dev'),
9 years ago
self.Get('cl_autopartition_device') *
len(self.Get('cl_autopartition_disk_dev'))))
return diskParent
humanReadable = Variable.humanReadable
9 years ago
class VariableOsInstallDiskPart(SourceReadonlyVariable):
"""
Get new type partitions using for install
"""
type = "list"
indexField = "os_install_disk_dev"
def getMap(self):
9 years ago
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
9 years ago
class VariableOsInstallBindData(ReadonlyTableVariable):
"""
Table of install bind mount points
"""
source = ['os_install_bind_path',
'os_install_bind_mountpoint']
9 years ago
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',
9 years ago
func=lambda x: not x[1].startswith('/dev/') and x[0])
class VariableOsInstallBindMountpoint(ReadonlyVariable):
"""
Mountpoint for install directories bind
"""
9 years ago
def get(self):
return self.Select('os_location_dest',
where='os_location_source',
9 years ago
func=lambda x: not x[0].startswith('/dev/') and x[1])
class VariableOsInstallBootloader(ReadonlyVariable):
"""
Bootloader for brief information
"""
9 years ago
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:
9 years ago
return ",".join(self.Get('os_install_mbr', humanreadable=True))
class VariableOsInstallMbr(LocationHelper, Variable):
"""
Disks for boot mbr
"""
type = "choice-list"
element = "selecttable"
opt = ["--mbr"]
metavalue = "MBR"
untrusted = True
check_after = ["os_install_uefi_set"]
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_device')
9 years ago
if self.Get('os_install_root_type') in ("flash", "usb-hdd"):
rootdev = self.Get('os_install_root_dev')
9 years ago
device = filter(lambda x: x in rootdev,
self.Get('os_device_dev'))
if device:
return [device[0]]
else:
return []
bootDev = self.Select('os_install_disk_dev',
where='os_install_disk_mount',
9 years ago
_in=('/', '/boot'), sort="DESC", limit=1)
# if install on lvm detected
if self.Get('os_install_lvm_set') == "on":
if bootDev:
lvmDisk = self.Select('os_disk_lvm',
where='os_disk_dev',
9 years ago
eq=bootDev, limit=1)
if lvmDisk:
9 years ago
vgName, lvName = lvmDisk[5:].split('/')
disks = self.Select('os_lvm_pvname',
where='os_lvm_vgname',
eq=vgName)
devices = self.Select('os_disk_parent',
9 years ago
where='os_disk_dev',
_in=disks)
res = map(itemgetter(0),
9 years ago
filter(lambda x: x[0] in devices and x[1],
self.ZipVars('os_device_dev',
'os_device_table')))
if res:
return res
if self.Get('os_install_mdadm_set') == "on":
if bootDev:
disks = self.Select('os_disk_parent',
where='os_disk_type',
9 years ago
like='raidmember\(%s\)' % bootDev)
res = map(itemgetter(0),
9 years ago
filter(lambda x: x[0] in disks and x[1],
self.ZipVars('os_device_dev',
'os_device_table')))
if res:
return res
# if loaded system livecd
if self.Get('os_root_type') == "livecd":
9 years ago
bootDevice = self.Select('os_install_disk_parent',
where='os_install_disk_mount',
_in=('/', '/boot'),
sort="DESC")[:1]
# search /boot device or / device, by priority /boot,/
if bootDevice:
return bootDevice
9 years ago
return [self.Select('os_device_dev', where='os_device_type', eq='hdd',
limit=1)]
def choice(self):
9 years ago
deviceParentMap = dict(self.ZipVars('os_device_dev', 'os_device_name'))
return map(lambda x: (x, "%s (%s)" % (x,
deviceParentMap.get(x, _(
"Unknown")))),
self.Get('os_device_dev'))
9 years ago
def set(self, value):
# support off value
9 years ago
return filter(lambda x: x != "off", value)
9 years ago
def check(self, value):
if self.Get('cl_autopartition_set') == "on":
return
rootType = self.Get('os_install_root_type')
if rootType == "flash":
if len(value) > 1:
raise VariableError(
12 years ago
_("For Flash install, you need only one disk"))
if self.Get('os_install_uefi_set') == 'on':
return
useBtrfs = "btrfs" in self.Select('os_install_disk_format',
9 years ago
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',
9 years ago
where="os_device_dev", eq=mbrDisk,
limit=1)
if not tableOnBootDisk:
raise VariableError(
9 years ago
_("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"))
9 years ago
if rootType in ("usb-hdd", "hdd") and tableOnBootDisk == "gpt":
efisize = self.Select('os_disk_size',
9 years ago
where=['os_disk_id', 'os_disk_parent'],
func=lambda os_disk_id, os_disk_parent: (
os_disk_id == 'EF02' and os_disk_parent == mbrDisk),
limit=1)
bios_grub_size = self.Get('cl_autopartition_bios_grub_size')
minsize = "%dMb" % (int(bios_grub_size) / Sizes.M)
if not efisize:
raise VariableError(
10 years ago
_("Your boot device must have a BIOS Boot partition "
"({minsize})").format(minsize=minsize))
# проверка размера EF02 при установке на btrfs
elif useBtrfs:
if (efisize.isdigit() and bios_grub_size.isdigit() and
9 years ago
int(efisize) < int(bios_grub_size)):
raise VariableError(
10 years ago
_("Your boot device must have a BIOS Boot "
"partition ({minsize})").format(minsize=minsize))
if value:
if self.Get('os_grub2_path'):
self.checkForGrub2()
else:
self.checkForLegacyGrub()
def checkForGrub2(self):
"""
Проверить текущую конфигурацию диска для установки GRUB2
"""
9 years ago
grubDiskType = self.Select('os_install_disk_parent',
where='os_install_disk_mount',
_in=('/', '/boot'),
sort="DESC", limit=1)
if "lvm-raid" in grubDiskType:
raise VariableError(
9 years ago
_(
"Grub does not support booting from a RAID assembled from a LVM")
+ ". " +
_("Try to use a separate /boot partition"))
9 years ago
if grubDiskType.count("raid") > 1:
raise VariableError(
9 years ago
_("Grub does not support booting from a RAID assembled "
"from another RAID")
+ ". " +
_("Try to use a separate /boot partition"))
def checkForLegacyGrub(self):
"""Check current disk configuration for installation for install
legacy grub"""
9 years ago
bootDiskType, bootDiskFormat = \
self.Select(['os_install_disk_type',
'os_install_disk_format'],
where='os_install_disk_mount',
9 years ago
_in=('/', '/boot'),
sort="DESC", limit=1)
if "lvm" in bootDiskType or "raid" in bootDiskType:
raise ValueError(
9 years ago
_(
"Legacy grub requires a separate /boot partition to support boot from a RAID or a LVM"))
if bootDiskFormat in ("btrfs", "nilfs2"):
raise ValueError(
9 years ago
_("To support booting from %s, legacy grub needs a "
"separate /boot partition") % bootDiskFormat)
def uncompatible(self):
"""
Опция несовместима с использованием UEFI
"""
if self.Get('os_install_uefi_set') == "on" and self.Get():
return _("MBR is not used with the UEFI bootloader")
if self.Get('cl_autopartition_set') == "on":
return \
_("The layout is not available with autopartitioning")
return ""
9 years ago
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')
device = getPartitionDevice(
getUdevDeviceInfo(name=rootdev).get('DEVPATH', ''))
device_type = self.Select(
'os_device_type', where='os_device_dev', eq=device, limit=1)
if device_type in ("usb-hdd", "flash"):
return "usb-hdd"
return "hdd"
def choice(self):
9 years ago
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')
9 years ago
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',
9 years ago
eq=root_dev, limit=1) or ''
else:
root_dev = self.Get('os_root_dev')
return self.Select('os_disk_uuid',
where='os_disk_dev',
9 years ago
eq=root_dev, limit=1) or ''
9 years ago
class VariableOsInstallFstabMountConf(DeviceHelper, ReadonlyVariable):
"""
FStab.conf contains for mount and bind points
"""
9 years ago
def _commentFstab(self, s, mp, dev):
"""Generate comment for /etc/fstab each line"""
if s.startswith("UUID"):
9 years ago
return "# %s was on %s during installation\n%s" % (mp, dev, s)
else:
return s
def get(self):
devicesForFstab = sorted(
9 years ago
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"),
lambda x, y: cmp(self.separateDevice(x[1]),
self.separateDevice(y[1])))
if self.Get('os_install_scratch') == "on":
9 years ago
devicesForFstab = filter(lambda x: x[1] != "/", devicesForFstab)
# rootLine one string, but it correct work if devicesForFstab is empty
9 years ago
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]),
9 years ago
devicesForFstab[:1]))
otherLines = "\n".join(map(lambda x: "%s\t%s\t%s\t%s\t0 0" %
9 years ago
(self._commentFstab(x[0], x[1],
x[4]), x[1],
x[2], x[3]),
devicesForFstab[1:]))
bindData = self.ZipVars('os_install_bind_path',
'os_install_bind_mountpoint')
9 years ago
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 VariableOsInstallFstabSwapConf(VariableOsInstallFstabMountConf):
"""
FStab.conf contains swap partition
"""
9 years ago
def get(self):
9 years ago
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"]
9 years ago
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):
diskParentMap = dict(zip(self.Get('os_disk_dev'),
self.Get('os_disk_parent')))
9 years ago
deviceParentMap = dict(self.ZipVars('os_device_dev', 'os_device_name'))
disks = self.select('os_disk_dev', os_disk_part__ne="")
9 years ago
return map(lambda x: (x, "%s (%s)" % (x,
deviceParentMap.get(
diskParentMap.get(x, x),
_("Unknown")))),
disks)
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