#-*- coding: utf-8 -*- # Copyright 2008-2013 Calculate Ltd. 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 from os import path from time import sleep from calculate.lib.datavars import TableVariable,Variable,VariableError, \ ReadonlyVariable, ReadonlyTableVariable from calculate.lib.utils.device import (getUdevDeviceInfo,getDeviceType, getPartitionType,getPartitionDevice,getRaidPartitions, getLvmPartitions,getPartitionSize,getUUIDDict, humanreadableSize,refreshUdev) from calculate.lib.utils.files import (listDirectory,pathJoin,readFile,FStab, readLinesFile,process,getProgPath) from calculate.install.distr import PartitionDistributive from calculate.install.fs_manager import FileSystemManager from calculate.lib.utils.tools import Sizes from itertools import * import operator from calculate.lib.cl_lang import setLocalTranslate setLocalTranslate('cl_install3',sys.modules[__name__]) class SizeHelper: default_size = Sizes.M def set(self,value): # convert table from value to MB sizeMap = {'kB':Sizes.kB, 'K':Sizes.K, 'M':Sizes.M, 'Mb':Sizes.Mb, 'G':Sizes.G, 'Gb':Sizes.Gb, 'T':Sizes.T, 'Tb':Sizes.Tb} value = value.strip() reSizeValue = re.compile('^(\d+)\s*(%s)?'%"|".join(sizeMap.keys())) res = reSizeValue.search(value) if not res: return "0" intValue = int(res.group(1)) if res.group(2): intValue = intValue * sizeMap[res.group(2)] else: intValue = intValue * self.default_size return str(intValue) MINROOTSIZE=7*Sizes.G class AutopartitionError(Exception): """ Autopartition error """ pass class AutoPartition: """ Autopartition maker """ def recreateSpace(self,table,device,data,lvm,vgname,bios_grub,bios_grub_size): """ Recreate disk space by table device data lvm flag and vgname table (gpt,dos) device - list devices ['/dev/sda'] data - partitions data [['/dev/calculate/boot','/boot','ext4',534234234'gpt]...] lvm True or False vgname lvm Volume Group Name """ if lvm: self.recreateLvm(table,device,data,vgname,bios_grub,bios_grub_size) else: self.recreatePartitionTable(table,device,data,bios_grub,bios_grub_size) refreshUdev() def recreatePartitionTable(self,table,device,data,bios_grub,bios_grub_size): """ """ mapDispatch = {'dos':self.recreatePartitionTableDos, 'gpt':self.recreatePartitionTableGpt} if table in mapDispatch: mapDispatch[table](device,data,bios_grub,bios_grub_size) else: raise AutoPartitionError( _('Autopartitioning for %s is not supported')%table) def recreatePartitionTableDos(self,device,data,bios_grub,bios_grub_size): """ Create DOS partition table by /sbin/fdisk """ NEW_PARTITION_TABLE = "o\n" NEW_PRIMARY_PARTITION = "n\np\n\n\n" NEW_EXTENDED_PARTITION = "n\ne\n\n" NEW_LOGICAL_PARTITION = "n\n\n" MAX_SIZE = "\n" WRITE_AND_QUIT = "w\nq\n" fdiskProg = getProgPath('/sbin/fdisk') fdisk = process(fdiskProg,device[0]) fdisk.write(NEW_PARTITION_TABLE) num = 1 for size in map(lambda x:str(Sizes().to_K(int(x))) \ if x.isdigit() else x, map(operator.itemgetter(3),data)): if num == 4: fdisk.write(NEW_EXTENDED_PARTITION+MAX_SIZE) num += 1 size = MAX_SIZE if size == "allfree" else "+%sK\n"%size if num < 4: fdisk.write(NEW_PRIMARY_PARTITION+size) else: fdisk.write(NEW_LOGICAL_PARTITION+size) num +=1 fdisk.write(WRITE_AND_QUIT) fdisk.success() self._waitDevice(device[0]+str(num-1)) def recreatePartitionTableGpt(self,device,data,bios_grub=True, bios_grub_size=0): """ Create GPT partition table by /sbin/gdisk """ NEW_PARTITION_TABLE = "3\no\ny\n" NEW_PARTITION = "n\n\n\n" NEW_BIOSBOOT_PARTITION = "n\n\n\n%s\nef02\n" MAX_SIZE = "\n\n" WRITE_AND_QUIT = "w\ny\n" BIOS_BOOT_PART_NUM = 4 BIOS_BOOT_PART_SIZE = "%dM"%(int(bios_grub_size) / Sizes.M) fdiskProg = getProgPath('/usr/sbin/gdisk') fdisk = process(fdiskProg,device[0]) fdisk.write(NEW_PARTITION_TABLE) num = 1 biosBootCreated = not bios_grub for size in map(lambda x:str(Sizes().to_K(int(x))) \ if x.isdigit() else x, map(operator.itemgetter(3),data)): if num == BIOS_BOOT_PART_NUM and not biosBootCreated: fdisk.write(NEW_BIOSBOOT_PARTITION% ("+%s"%BIOS_BOOT_PART_SIZE)) biosBootCreated = True num += 1 if size == "allfree": if biosBootCreated: size = MAX_SIZE else: size = "-%s\n\n"%BIOS_BOOT_PART_SIZE else: size = "+%sK\n\n"%size fdisk.write(NEW_PARTITION+size) num +=1 if not biosBootCreated: fdisk.write(NEW_BIOSBOOT_PARTITION%"") fdisk.write(WRITE_AND_QUIT) fdisk.success() self._waitDevice(device[0]+str(num-1)) def _waitDevice(self,device): for waittime in (0.1,0.2,0.5,1,2,4): if path.exists(device): return True else: sleep(waittime) raise AutopartitionError( _("Failed to found partition %s after creating the partition table") %device) def _createPhisicalVolumes(self,devices): pvCreateProg = getProgPath('/sbin/pvcreate') return process(pvCreateProg,"-ff",*devices).success() def _createVolumesGroup(self,vgname,disks): vgCreateProg = getProgPath('/sbin/vgcreate') return process(vgCreateProg,vgname,*disks).success() def _createLogicalVolume(self,vgname,lvname,size): if size.isdigit(): size = str(Sizes().to_K(int(size))) if size == "allfree": sizeparam = "-l100%FREE" else: sizeparam = "-L%sK"%size lvCreateProg = getProgPath('/sbin/lvcreate') return process(lvCreateProg,sizeparam,vgname,"-n",lvname).success() def _removeVolumeGroup(self,vgname): vgRemoveProg = getProgPath('/sbin/vgremove') # double remove volume group return process(vgRemoveProg,vgname,"-f").success() or \ process(vgRemoveProg,vgname,"-f").success() def clearLvm(self,devices,dv): """ Remove lvm physical volumes from devices """ vgRemoveProg = getProgPath('/sbin/vgremove') pvRemoveProg = getProgPath('/sbin/pvremove') lvRemoveProg = getProgPath('/sbin/lvremove') disks = dv.Select('os_disk_dev',where='os_disk_parent',_in=devices) failed = False for group, pair in groupby(dv.Select(['os_lvm_vgname','os_lvm_lvname'], where='os_lvm_pvname',_in=disks, sort="ASC/1"), operator.itemgetter(0)): for vgname,lvname in pair: failed |= self.doubleExec(lvRemoveProg, "%s/%s"%(vgname,lvname),"-f") failed |= self.doubleExec(vgRemoveProg,group,"-f") for pvname in list(set(disks)&set(dv.Get('os_lvm_pvname'))): failed |= self.doubleExec(pvRemoveProg,pvname,"-ffy") return not failed def doubleExec(self,*args): """ Running double exec command with 2 seconds interval """ if process(*args).failed(): sleep(2) return process(*args).failed() return False def clearRaid(self,devices,dv): """ Remove raid from devices """ mdAdmProg = getProgPath('/sbin/mdadm') failed = False for disktype,grouped in groupby( dv.Select(['os_disk_type','os_disk_dev'], where='os_disk_parent', _in=['/dev/sda','/dev/sdb'], sort="ASC/1"), operator.itemgetter(0)): if disktype.endswith('-raid'): for disk_type, disk_dev in grouped: failed |= self.doubleExec(mdAdmProg,'-S',disk_dev) if "raidmember" in disktype: for disk_type, disk_dev in grouped: failed |= self.doubleExec(mdAdmProg, '--zero-superblock',disk_dev) return not failed def recreateLvm(self,table,devices,data,vgname,bios_grub,bios_grub_size): """ Create GPT partition table by /sbin/gdisk """ for i,device in enumerate(devices): if i == 0: DEV,MP,FS,SIZE,TABLE=0,1,2,3,4 notInLvm = filter(lambda x:"boot" in x[MP],data) self.recreatePartitionTable(table, [device],notInLvm+[['','','','allfree']],bios_grub, bios_grub_size) else: self.recreatePartitionTable(table, [device],[['','','','allfree']],bios_grub, bios_grub_size) lvmPartOffset = 1 + len(notInLvm) iPart = [lvmPartOffset]+[1]*(len(devices)-1) disks = map(lambda x:"%s%d"%x,zip(devices,iPart)) if not self._createPhisicalVolumes(disks): raise AutopartitionError( _("Failed to create physical volumes from %s") %",".join(devices)) if not self._createVolumesGroup(vgname,disks): raise AutopartitionError( _("Failed to create volume group {groupname} from {disks}") .format(groupname=vgname, disks=",".join(devices))) lvCreateProg = getProgPath('/sbin/lvcreate') for disk,size in map(operator.itemgetter(0,3), filter(lambda x:not "boot" in x[MP],data)): lvname = disk.rpartition('/')[2] if not self._createLogicalVolume(vgname,lvname,size): raise AutopartitionError( _("Failed to create logical volume {name}") .format(name=lvname)) self._waitDevice('/dev/%s/root'%vgname) class AutopartitionHelper: """ Helper for autopartiton device and mount point creating """ def deviceOpts(self,listvalue): for i in ("root","data"): if i in listvalue: beforeVal = i break else: beforeVal = "" for line in listvalue: if line in ("home","lvm","raid","grub"): continue if line == beforeVal: yield "root2" yield line if not beforeVal: yield "root2" def bindOpts(self,listvalue): return filter(lambda x:x in ("home",), listvalue) def mpByOpts(self,value): mapMp = {'swap':'swap', 'boot':'/boot', 'root2':'/', 'root':'', 'uefi':'/boot/efi', 'data':'/var/calculate'} return mapMp.get(value,'') def sourceMpByOpts(self,value): mapMp = {'home':'/var/calculate/home'} return mapMp.get(value,'') def targetMpByOpts(self,value): mapMp = {'home':'/home'} return mapMp.get(value,'') def getAutopartitionScheme(self): optOrder = {'uefi':0, 'boot':1, 'swap':2, 'root':3, 'data':4, 'home':5} return sorted(self.Get('cl_autopartition_scheme'),key=optOrder.get) def uncompatible(self): if self.Get('cl_autopartition_set') == "off": return \ _("Autopartition options are not available with manual " "partitioning") return "" class VariableHrMemorySize(ReadonlyVariable): """ Memory size in bytes """ type = "int" def get(self): reMemTotal = re.compile(r'^MemTotal:\s*(\d+)\s*kB$') totalMemList = filter(lambda x:x, map(reMemTotal.search, readLinesFile('/proc/meminfo'))) if totalMemList: size = int(totalMemList[0].group(1))*Sizes.K return str(size) return "0" def humanReadable(self): return humanreadableSize(self.Get()) class VariableClAutopartitionSwapSize(SizeHelper,AutopartitionHelper,Variable): """ Swap size """ type = "size-m" opt = ["--swap-size"] metavalue = "SIZE" untrusted = True def init(self): self.label = _("Swap partition size")+ " (MB)" self.help = _("set the swap partition size for autopartition") def get(self): size = int(self.Get('hr_memory_size')) if size < Sizes.G: size = Sizes.G return str(size) def humanReadable(self): return humanreadableSize(int(self.Get())) class VariableClAutopartitionDevice(AutopartitionHelper,Variable): """ Device for autopartition """ type = "choice-list" element = "selecttable" opt = ["-D"] metavalue = "DEVICE" untrusted = True def init(self): self.help = _("set the device for autopartition") self.label = _("Devices for install") def get(self): choiceVal = map(lambda x:x[0],self.choice()) if len(choiceVal) == 1: return [choiceVal[0]] return [] def choice(self): 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')) def checkNeeded(self,valuelist,usedDevices,agregationType): needDevices = list(set(usedDevices) - set(valuelist)) if needDevices: raise VariableError(_("Disks {selecteddisk} are part of " "{agrtype}\nYou need to use {needdisk} as well or " "clear {agrtype} manually") .format(selecteddisk=",".join( list(set(usedDevices)&set(valuelist))), needdisk=",".join(needDevices), agrtype=agregationType)) def checkOnLvm(self,valuelist): disks = self.Select('os_disk_dev', where='os_disk_parent',_in=valuelist) vgroups = self.Select('os_lvm_vgname', where='os_lvm_pvname',_in=disks) lvmDisks = self.Select('os_lvm_pvname', where='os_lvm_vgname',_in=vgroups) lvmDevices = self.Select('os_disk_parent',where='os_disk_dev', _in=lvmDisks) self.checkNeeded(valuelist,lvmDevices,"LVM") def checkOnRaid(self,valuelist): disks = self.Select('os_disk_dev', where='os_disk_parent',_in=valuelist) raids = filter(None,self.Select('os_disk_raid', where='os_disk_dev',_in=disks)) raidDisks = self.Select('os_disk_dev',where='os_disk_raid',_in=raids) raidDevices = self.Select('os_disk_parent', where='os_disk_dev', _in=raidDisks) self.checkNeeded(valuelist,raidDevices,"RAID") def check(self,valuelist): if self.Get('cl_autopartition_set') == "on": if not valuelist: raise VariableError(_("For autopartition, please select the device")) useDisks = self.Select('os_disk_parent', where='os_disk_mount',ne='') for value in valuelist: if value in useDisks: raise VariableError( _("Device %s is already in use by the current " "system")%value) self.checkOnLvm(valuelist) self.checkOnRaid(valuelist) if len(valuelist) > 1 and \ self.Get('cl_autopartition_lvm_set') == 'off': raise VariableError( _("You should use LVM to install on more that one device")) freeSize = int(self.Get('cl_autopartition_free_size')) if freeSize < 0 and (abs(freeSize))/(Sizes.M*100) > 0: availSize = int(self.Get('cl_autopartition_device_size')) raise VariableError( _("There is not enough space on this device")+"\n"+ _("{avail} available, {need} needed").format( avail=humanreadableSize(availSize), need=humanreadableSize(availSize-freeSize))) class VariableClAutopartitionSet(Variable): """ Using autopartition """ type = "bool" value = "off" element = "radio" opt = ["--autopartition"] def init(self): self.label = _("Partitions") self.help = _("autopartition") def choice(self): return [("off",_("Use the current partitions")), ("on",_("Autopartition"))] class VariableClAutopartitionBriefSet(VariableClAutopartitionSet): def get(self): return self.Get('cl_autopartition_set') def uncompatible(self): if self.Get('os_install_root_type') == 'flash': return \ _("This option not used for Flash install") class VariableClAutopartitionScheme(AutopartitionHelper,Variable,AutoPartition): """ Autopartition scheme """ type = "choice-list" element = "selecttable" opt = ["--auto-scheme"] metavalue = "AUTOPARTOPTS" check_after = ["cl_autopartition_table"] def init(self): self.help = _("autopartition options") self.label = _("Autopartition options") def get(self): if self.Get('os_uefi_set') == 'on': return ["uefi","swap","root","data","home"] elif self.Get('cl_autopartition_table') == 'gpt': return ["swap","root","data","home","grub"] else: return ["swap","root","data","home"] def choice(self): return [ ("swap",_("Swap partition")), ("root",_("Additional root partition")), ("data",_("/var/calculate partition")), ("home",_("Mount /var/calculate/home to /home")), ("boot",_("Separate boot partition")), ("uefi",_("Use the UEFI bootloader")), ("lvm",_("Use LVM")), ("grub",_("Create the bios_grub partition")), ] def check(self,value): if "uefi" in value: if self.Get('os_uefi_set') == 'off': raise VariableError( _("Your system must be loaded in UEFI for using this " "bootloader")) if self.Get('os_install_arch_machine') != 'x86_64': raise VariableError( _("Architecture of the target system must be x86_64 " "for using the UEFI bootloader")) if self.Get('cl_autopartition_table') != 'gpt': raise VariableError( _("The partition table must be GPT for using " "UEFI bootloader")) else: if self.Get('cl_autopartition_table') == 'gpt' and not "grub" in value: raise VariableError( _("A 'bios_grub' partition is needed to install grub")) if "grub" in value: if self.Get('cl_autopartition_table') != 'gpt': raise VariableError( _("The bios_grub partition need the partition table to be GPT")) class VariableClAutopartitionRootSizeDefault(Variable): """ Размер root раздела при авторазметке """ value = str(Sizes.G*15) class VariableClAutopartitionRootSizeMin(Variable): """ Минимальнй размер root раздела """ value = str(Sizes.G*7) class VariableClAutopartitionRootSize(SizeHelper,AutopartitionHelper,Variable): """ Root partition size for autopartition """ type = "size-m" opt = ["--root-size"] metavalue = "SIZE" untrusted = True def init(self): self.label = _("Root partition size")+ " (MB)" self.help = _("set the root partition size for autopartition") def get(self): size = int(self.Get('cl_autopartition_root_size_default')) deviceSize = int(self.Get('cl_autopartition_device_size')) minRootSize = int(self.Get('cl_autopartition_root_size_min')) if size >= deviceSize: size = max(deviceSize, minRootSize) return str(size) def check(self,value): minRootSize = int(self.Get('cl_autopartition_root_size_min')) if (self.Get('cl_autopartition_device') and self.Get('cl_autopartition_set') == "on"): if int(value) < minRootSize: raise VariableError( _("The root partition should be at least {size}").format( size="%s Gb"%(Sizes().to_G(minRootSize)))) def humanReadable(self): return humanreadableSize(int(self.Get())) class VariableClAutopartitionTable(AutopartitionHelper,Variable): """ Partition table for autopartition """ type = "choice" value = "gpt" opt = ["--partition-table"] metavalue = "TABLE" def init(self): self.label = _("Partition table") self.help = _("set the partition table for autopartition") def choice(self): return [("dos","DOS-type Partition Table"), ("gpt","GUID Partition Table (GPT)")] class VariableClAutopartitionDiskData(ReadonlyTableVariable): """ New partition data for autopart device """ source = ['cl_autopartition_disk_dev', 'cl_autopartition_disk_mount', 'cl_autopartition_disk_format', 'cl_autopartition_disk_size', 'cl_autopartition_disk_part', 'cl_autopartition_disk_scheme'] class VariableClAutopartitionBiosGrubSet(ReadonlyVariable): """ Create bios_grub partition """ type = "bool" def get(self): return "on" if "grub" in self.Get('cl_autopartition_scheme') else "off" class VariableClAutopartitionLvmSet(ReadonlyVariable): """ Using LVM for autopartition """ type = "bool" def get(self): return "on" if "lvm" in self.Get('cl_autopartition_scheme') else "off" class VariableClAutopartitionUefiSet(ReadonlyVariable): """ Using UEFI bootloader """ type = "bool" def get(self): return "on" if "uefi" in self.Get('cl_autopartition_scheme') else "off" class VariableClAutopartitionLvmVgname(Variable): """ Volume group name for LVM autopartition """ def get(self): def generateName(startName): yield startName for i in count(2): yield "%s%d"%(startName,i) for name in generateName("calculate"): disks = self.Select('os_lvm_pvname',where='os_lvm_vgname',eq=name) devices = self.Select('os_disk_parent', where='os_disk_dev',_in=disks) if set(devices) <= set(self.Get('cl_autopartition_device')): return name class VariableClAutopartitionDiskDev(ReadonlyVariable,AutopartitionHelper): """ Autopartition virtual disk on device """ type = "list" def generateDisks(self,dos=False,devices=[],scheme=[],number=0): """ Generate disks for automount scheme """ number = 1 for line in self.deviceOpts(scheme): # for dos 4 - extension # for gpt 4 - for bios_boot if number == 4 and ( self.Get('cl_autopartition_bios_grub_set')=='on' or dos): number += 1 yield "%s%d"%(devices[0],number) number += 1 def generateLvm(self,scheme=[],devices=[],**kwargs): vgname = self.Get('cl_autopartition_lvm_vgname') number = 1 for line in map(lambda x:{'root':'root2', 'root2':'root'}.get(x,x), self.deviceOpts(scheme)): if line in ("boot","uefi"): if number == 4 and \ self.Get('cl_autopartition_bios_grub_set')=='on': number += 1 yield "%s%d"%(devices[0],number) number += 1 else: yield "/dev/%s/%s"%(vgname,line) def diskGenerator(self): if self.Get('cl_autopartition_lvm_set') == 'on': return self.generateLvm else: return self.generateDisks def get(self): if self.Get('cl_autopartition_set') == "on": scheme = self.getAutopartitionScheme() devices = self.Get('cl_autopartition_device') if devices: res = list(self.diskGenerator()( devices=devices, scheme=scheme, dos=self.Get('cl_autopartition_table')=='dos')) return res return [] class VariableClAutopartitionDiskScheme(ReadonlyVariable,AutopartitionHelper): """ Назначение раздела относительно схемы авторазметки """ type = "list" def generateScheme(self,scheme): """ Generate mount points for automount scheme """ for line in self.deviceOpts(scheme): yield line def get(self): if self.Get('cl_autopartition_set') == "on": scheme = self.getAutopartitionScheme() device = self.Get('cl_autopartition_device') if device: return list(self.generateScheme(scheme)) return [] class VariableClAutopartitionDiskMount(ReadonlyVariable,AutopartitionHelper): """ Autopartition mount points """ type = "list" def generateMounts(self,scheme): """ Generate mount points for automount scheme """ for line in self.deviceOpts(scheme): yield self.mpByOpts(line) def get(self): if self.Get('cl_autopartition_set') == "on": scheme = self.getAutopartitionScheme() device = self.Get('cl_autopartition_device') if device: return list(self.generateMounts(scheme)) return [] class VariableClAutopartitionDiskFormat(ReadonlyVariable,AutopartitionHelper): """ Autopartition disk filesystem """ type = "list" def generateFormat(self,scheme): """ Generate filesystems for automount scheme """ for line in self.deviceOpts(scheme): if line == "swap": yield "swap" elif line == "uefi": yield "vfat" else: yield FileSystemManager.defaultFS['hdd'] def get(self): if self.Get('cl_autopartition_set') == "on": scheme = self.getAutopartitionScheme() device = self.Get('cl_autopartition_device') if device: return list(self.generateFormat(scheme)) return [] class VariableClAutopartitionDiskPart(ReadonlyVariable,AutopartitionHelper): """ Autopartition partition type (primary,extended,logical,gpt) """ type = "list" def generatePart(self,scheme,dos): """ Generate part type for automount scheme """ number = 1 for line in self.deviceOpts(scheme): if dos: if number < 4: yield "primary" else: yield "logical" number += 1 else: yield "gpt" def get(self): if self.Get('cl_autopartition_set') == "on": scheme = self.getAutopartitionScheme() table = self.Get('cl_autopartition_table') if scheme: return list(self.generatePart(scheme, self.Get('cl_autopartition_table')=='dos')) return [] class VariableClAutopartitionDiskType(ReadonlyVariable,AutopartitionHelper): """ Autopartition partition scheme (simple - disk-partition) """ type = "list" def get(self): if self.Get('cl_autopartition_set') == "on": if self.Get('cl_autopartition_lvm_set')=="on": diskType = "LVM" else: diskType = "disk-partition" return [diskType]*len(self.Get('cl_autopartition_disk_dev')) return [] class VariableClAutopartitionDiskSize(ReadonlyVariable,AutopartitionHelper): """ Autopartition disk size """ type = "list" def generateSize(self,scheme,memory,bootsize,uefisize,rootsize,availsize, minrootsize): args = {'swap':memory, 'root': rootsize, 'root2': rootsize, 'boot': bootsize, 'uefi': uefisize, } minrootsize = int(minrootsize) deviceOpts = list(self.deviceOpts(scheme)) for line in deviceOpts[:-1]: availsize -= int(args.get(line,0)) yield str(args.get(line,0)) if "root" in deviceOpts[-1] and availsize < minrootsize: yield str(minrootsize) elif availsize < 1*Sizes.G: yield str(1*Sizes.G) else: yield "allfree" def get(self): if self.Get('cl_autopartition_set') == "on": scheme = self.getAutopartitionScheme() device = self.Get('cl_autopartition_device') availSize = self.Get('cl_autopartition_device_size') if device: return list(self.generateSize(scheme, self.Get('cl_autopartition_swap_size'), self.Get('cl_autopartition_boot_size'), self.Get('cl_autopartition_uefi_size'), self.Get('cl_autopartition_root_size'), int(availSize), self.Get('cl_autopartition_root_size_min') )) return [] def humanReadable(self): allSize = self.Get('cl_autopartition_free_size') return map(humanreadableSize, map(lambda x:allSize if x == "allfree" else x, self.Get())) class VariableClAutopartitionUefiSize(Variable): """ Size of EF00 partition """ value = str(200*Sizes.M) class VariableClAutopartitionBootSize(Variable): """ Size of boot partition """ value = str(512*Sizes.M) class VariableClAutopartitionBiosGrubSize(Variable): """ Размер раздела bios_grub для авторазметки """ value = str(10*Sizes.M) class VariableClAutopartitionDeviceSize(ReadonlyVariable): """ Available devices size """ def get(self): devices = self.Get('cl_autopartition_device') if not devices: return '0' sizeDevice = map(int,self.Select('os_device_size', where='os_device_dev', _in=devices)) # TODO: remove set 10G #return str(1024*1024*1024*10) return str(reduce(operator.add,sizeDevice,0)) class VariableClAutopartitionFreeSize(ReadonlyVariable): """ Freesize of device with current root_size and memory """ type = "int" def get(self): sizeDevice = int(self.Get('cl_autopartition_device_size')) sizes = self.Get('cl_autopartition_disk_size') return str(reduce(lambda x,y: (x - int(y)) if y.isdigit() else x, sizes,int(sizeDevice))) class VariableClAutopartitionBindData(ReadonlyTableVariable): """ Autopartition bind data """ source = ['cl_autopartition_bind_path', 'cl_autopartition_bind_mountpoint'] class VariableClAutopartitionBindPath(ReadonlyVariable,AutopartitionHelper): """ Autopartition bind points """ type = "list" def generatePath(self,scheme): for line in self.bindOpts(scheme): yield self.sourceMpByOpts(line) def get(self): if self.Get('cl_autopartition_set') == "on": scheme = self.getAutopartitionScheme() device = self.Get('cl_autopartition_device') return list(self.generatePath(scheme)) return [] class VariableClAutopartitionBindMountpoint(ReadonlyVariable, AutopartitionHelper): """ Autopartition bind points """ type = "list" def generateMountPoint(self,scheme): for line in self.bindOpts(scheme): yield self.targetMpByOpts(line) def get(self): if self.Get('cl_autopartition_set') == "on": scheme = self.getAutopartitionScheme() device = self.Get('cl_autopartition_device') return list(self.generateMountPoint(scheme)) return []