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/install/variables/autopartition.py

439 lines
13 KiB

#-*- coding: utf-8 -*-
# Copyright 2008-2012 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 Variable,VariableError,ReadonlyVariable
from calculate.lib.utils.device import (getUdevDeviceInfo,getDeviceType,
getPartitionType,getPartitionDevice,getRaidPartitions,
getLvmPartitions,getPartitionSize,getUUIDDict,
humanreadableSize)
from calculate.lib.utils.files import (listDirectory,pathJoin,readFile,FStab,
readLinesFile,process,getProgPath)
from calculate.install.cl_distr import PartitionDistributive
from calculate.install.fs_manager import FileSystemManager
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_install',sys.modules[__name__])
class AutopartitionError(Exception):
"""
Autopartition error
"""
pass
class AutoPartition:
"""
Autopartition maker
"""
schemes = [("",
_("Manual partition")),
("{rootsize}:/;{rootsize}:;{allsize}:/var/calculate;"
"/var/calculate:/home",
_("Whole disk for double root, data, /home from data")),
("{memory}:swap;{rootsize}:/;"
"{rootsize}:;{allsize}:/var/calculate",
_("Whole disk for swap,double root and data")),
("{memory}:swap;{allsize}:/",
_("Whole disk for swap and root"))]
def recreatePartitionTable(self,device,scheme,table="dos"):
"""
"""
def recreatePartitionTableDos(self,device,scheme,memory,rootsize):
"""
"""
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)
fdisk.write(NEW_PARTITION_TABLE)
scheme = scheme.format(memory=memory,
rootsize=rootsize,
allsize="allsize")
num = 1
for entry in scheme.split(';'):
size,mount = entry.split(':')
if size.startswith('/'):
continue
if num == 4:
fdisk.write(NEW_EXTENDED_PARTITION+MAX_SIZE)
num += 1
size = MAX_SIZE if size == "allsize" 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()
for waittime in (0.1,0.2,0.5,1,2,4):
if path.exists(device+str(num-1)):
return True
else:
sleep(waittime)
raise AutoPartitionError(
_("Failed to found partition %s after creating partition table")
%dev)
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))*1024
if size < 1024*1024*1024:
size = 1024*1024*1024
return str(size)
return "0"
def humanReadable(self):
return map(humanreadableSize,self.Get())
class VariableClAutopartitionDevice(Variable):
"""
Device for autopartition
"""
type = "choice"
value = ""
opt = ["-D"]
metavalue = "DEVICE"
def init(self):
self.help = _("set autopartition device")
self.label = _("Install device")
def choice(self):
return [""]+self.Get('os_device_dev')
def check(self,value):
if self.Get('cl_autopartition_scheme'):
if not value:
raise VariableError(_("For autopartition need select install"
" device"))
useDisks = self.Select('os_disk_parent',
where='os_disk_mount',
eq=value)
if value in useDisks:
raise VariableError(
_("Device already is used by current system"))
class VariableClAutopartitionScheme(Variable,AutoPartition):
"""
Autopartition scheme
"""
type = "choice"
value = ""
element = "radio"
opt = ["--autopart"]
metavalue = "AUTOPARTMODE"
def init(self):
self.help = _("autopartition scheme")
self.label = _("Install scheme")
def choice(self):
return self.schemes
class VariableClAutopartitionRootSize(Variable):
"""
Root partition size for autopartition
"""
type = "int"
opt = ["--root-size"]
metavalue = "SIZE"
def init(self):
self.label = _("Root partition size")
self.help = _("set root partition size for autopartition")
def get(self):
if self.Get('os_install_linux_system') == 'server':
return str(1024*20)
else:
return str(1024*10)
def set(self,value):
sizeMap = {'kB':1/1000.0,
'K':1/1024.0,
'M':1.0,
'Mb':1000/1024.0,
'G':1024,
'Gb':1000,
'T':1024*1024,
'Tb':1000*1000}
value = value.strip()
reSizeValue = re.compile('^(\d+)\s*(%s)?'%"|".join(sizeMap.keys()))
res = reSizeValue.search(value)
intValue = int(res.group(1))
if res.group(2):
intValue = intValue / sizeMap[res.group(2)]
return str(intValue)
def check(self,value):
if self.Get('cl_autopartition_device') and \
self.Get('cl_autopartition_scheme') and \
self.Get('cl_autopartition_free_size') <= 0:
raise VariableError(_("Selected size is too large"))
class VariableClAutopartitionTable(Variable):
"""
Partition table for autopartition
"""
type = "choice"
value = "dos"
opt = ["--partition-table"]
metavalue = "TABLE"
def init(self):
self.label = _("Partition table")
self.help = _("set partition table for autopartition")
def choice(self):
return ["dos","gpt"]
class VariableClAutopartitionDiskData(ReadonlyVariable):
"""
New partition data for autopart device
"""
type = "table"
source = ['cl_autopartition_disk_dev',
'cl_autopartition_disk_mount',
'cl_autopartition_disk_format',
'cl_autopartition_disk_size',
'cl_autopartition_disk_part']
class VariableClAutopartitionDiskDev(ReadonlyVariable):
"""
Autopartition virtual disk on device
"""
type = "list"
def generateDisks(self,dos,device,scheme,number=0):
"""
Generate disks for automount scheme
"""
number = 1
for line in scheme.split(';'):
if dos and number == 4:
number += 1
sizeOrBind, mp = line.split(':')
if not sizeOrBind.startswith('/'):
yield "%s%d"%(device,number)
number += 1
def get(self):
scheme = self.Get('cl_autopartition_scheme')
device = self.Get('cl_autopartition_device')
if scheme and device:
res = list(self.generateDisks(
self.Get('cl_autopartition_table')=='dos',
device,scheme))
return res
return []
class VariableClAutopartitionDiskMount(ReadonlyVariable):
"""
Autopartition mount points
"""
type = "list"
def generateMounts(self,scheme):
"""
Generate mount points for automount scheme
"""
for line in scheme.split(';'):
if not line.startswith('/'):
source, mp = line.split(':')
yield mp
def get(self):
scheme = self.Get('cl_autopartition_scheme')
device = self.Get('cl_autopartition_device')
if scheme and device:
return list(self.generateMounts(scheme))
return []
class VariableClAutopartitionDiskFormat(ReadonlyVariable):
"""
Autopartition disk file system
"""
type = "list"
def generateFormat(self,scheme):
"""
Generate filesystems for automount scheme
"""
for line in scheme.split(';'):
source,mp = line.split(':')
if not source.startswith('/'):
if mp == "swap": yield "swap"
else: yield FileSystemManager.defaultFS['hdd']
def get(self):
scheme = self.Get('cl_autopartition_scheme')
device = self.Get('cl_autopartition_device')
if scheme and device:
return list(self.generateFormat(scheme))
return []
class VariableClAutopartitionDiskPart(ReadonlyVariable):
"""
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 scheme.split(';'):
sizeOrBind, mp = line.split(':')
if not sizeOrBind.startswith('/'):
if dos:
if number < 4: yield "primary"
else: yield "logical"
number += 1
else:
yield "gpt"
def get(self):
scheme = self.Get('cl_autopartition_scheme')
table = self.Get('cl_autopartition_table')
if scheme:
return list(self.generatePart(scheme,
self.Get('cl_autopartition_table')=='dos'))
return []
class VariableClAutopartitionDiskType(ReadonlyVariable):
"""
Autopartition partition scheme (simple - disk-partition)
"""
type = "list"
def get(self):
return map(lambda x:"disk-partition",
self.Get('cl_autopartition_disk_dev'))
class VariableClAutopartitionDiskSize(ReadonlyVariable):
"""
Autopartition disk size
"""
type = "list"
def generateSize(self,scheme,memory,rootsize):
args = {'memory':memory,
'rootsize': rootsize,
'allsize':"allfree"
}
for line in scheme.split(';'):
size,mp = line.split(':')
if not size.startswith('/'):
yield size.format(**args)
def get(self):
scheme = self.Get('cl_autopartition_scheme')
device = self.Get('cl_autopartition_device')
if scheme and device:
return list(self.generateSize(scheme,self.Get('hr_memory_size'),
str(int(self.Get('cl_autopartition_root_size'))
*1024*1024)))
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 VariableClAutopartitionFreeSize(ReadonlyVariable):
"""
Freesize of device with current root_size and memory
"""
type = "int"
def get(self):
device = self.Get('cl_autopartition_device')
if not device:
return 0
sizeDevice = self.Select('os_device_size',
where='os_device_dev',
eq=device,limit=1)
sizes = self.Get('cl_autopartition_disk_size')
return reduce(lambda x,y: x - int(y) if y.isdigit() else x,
sizes,int(sizeDevice))
class VariableClAutopartitionBindData(ReadonlyVariable):
"""
Autopartition bind data
"""
type = "table"
source = ['cl_autopartition_bind_path',
'cl_autopartition_bind_mountpoint']
class VariableClAutopartitionBindPath(ReadonlyVariable):
"""
Autopartition bind points
"""
type = "list"
def generatePath(self,scheme):
for line in scheme.split(';'):
source,mp = line.split(':')
if source.startswith('/'):
yield source
def get(self):
scheme = self.Get('cl_autopartition_scheme')
device = self.Get('cl_autopartition_device')
return list(self.generatePath(scheme))
class VariableClAutopartitionBindMountpoint(ReadonlyVariable):
"""
Autopartition bind points
"""
type = "list"
def generateMountPoint(self,scheme):
for line in scheme.split(';'):
source,mp = line.split(':')
if source.startswith('/'):
yield mp
def get(self):
scheme = self.Get('cl_autopartition_scheme')
device = self.Get('cl_autopartition_device')
return list(self.generateMountPoint(scheme))