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.
2058 lines
87 KiB
2058 lines
87 KiB
#-*- coding: utf-8 -*-
|
|
|
|
# Copyright 2010 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 re
|
|
import sys
|
|
import time
|
|
import traceback
|
|
from os import path
|
|
from StringIO import StringIO
|
|
from time import sleep
|
|
from subprocess import PIPE,STDOUT
|
|
from shutil import copy2
|
|
from calculate.lib.utils.files import (runOsCommand,pathJoin,scanDirectory,
|
|
process,listDirectory,STDOUT)
|
|
from calculate.lib.utils.common import (appendProgramToEnvFile,
|
|
removeProgramToEnvFile, getTupleVersion,
|
|
cmpVersion,getUserPassword,
|
|
getSupportArch, getInstalledVideo )
|
|
from calculate.lib.utils.device import (detectDeviceForPartition,
|
|
getUdevDeviceInfo, getLvmPartitions, refreshLVM,
|
|
refreshUdev)
|
|
from calculate.lib.cl_vars_share import varsShare
|
|
from calculate.lib import cl_overriding
|
|
from calculate.lib.utils import ip
|
|
from datavars import DataVarsInstall, __version__,__app__
|
|
|
|
from cl_kernel_utils import KernelConfig,InitRamFs
|
|
|
|
install_errors = ""
|
|
def installExit(*args,**kwars):
|
|
raise InstallError(globals()["install_errors"])
|
|
|
|
def overprintERROR(s):
|
|
globals()["install_errors"] += str(s) +"\n"
|
|
|
|
def get_install_errors():
|
|
return globals()["install_errors"]
|
|
|
|
def pop_install_errors():
|
|
res = globals()["install_errors"]
|
|
globals()["install_errors"] = ""
|
|
return res
|
|
|
|
defaultExit = cl_overriding.exit
|
|
defaultPrintERROR = cl_overriding.printERROR
|
|
|
|
from calculate.lib.variables.locale import Locale
|
|
from calculate.lib.cl_template import Template,TemplatesError
|
|
from calculate.lib.datavars import DataVars
|
|
from calculate.lib.cl_print import color_print
|
|
from cl_distr import (PartitionDistributive,
|
|
DistributiveError, ScratchPartitionDistributive,
|
|
MultiPartitions, Spinner, FlashDistributive, SignalInterrupt,
|
|
Distributive)
|
|
from calculate.lib.utils.text import tableReport
|
|
from calculate.lib.server.utils import dialogYesNo
|
|
|
|
class InstallError(Exception):
|
|
"""Installation Error"""
|
|
def __init__(self,error,field=None):
|
|
self.field = field
|
|
Exception.__init__(self,error)
|
|
|
|
from cl_migrate_users import migrate, currentUsers, MigrationError
|
|
from calculate.lib.encrypt import encrypt
|
|
|
|
from calculate.lib.cl_lang import setLocalTranslate
|
|
setLocalTranslate('cl_install',sys.modules[__name__])
|
|
|
|
class printNoColor:
|
|
def colorPrint(self,attr,fg,bg,string):
|
|
sys.stdout.write(string)
|
|
|
|
class FileSystemManager:
|
|
"""Convert dict install option"""
|
|
|
|
defaultOpt = 'noatime'
|
|
defaultBindOpts = ['bind']
|
|
supportFS = {
|
|
'ext2': {'defaultopt': defaultOpt,
|
|
'format': '/sbin/mkfs.ext2',
|
|
'formatparam': '{labelparam} {device}',
|
|
'gpt': '0700',
|
|
'label': '-L {labelname}',
|
|
'msdos': '83',
|
|
'type':['hdd','usb-hdd']},
|
|
'ext3': {'defaultopt': defaultOpt,
|
|
'format': '/sbin/mkfs.ext3',
|
|
'formatparam': '{labelparam} {device}',
|
|
'gpt': '0700',
|
|
'label': '-L {labelname}',
|
|
'msdos': '83',
|
|
'type':['hdd','usb-hdd']},
|
|
'ext4': {'defaultopt': defaultOpt,
|
|
'format': '/sbin/mkfs.ext4',
|
|
'formatparam': '{labelparam} {device}',
|
|
'gpt': '0700',
|
|
'label': '-L {labelname}',
|
|
'msdos': '83',
|
|
'type':['hdd','usb-hdd']},
|
|
'reiserfs': {'defaultopt': defaultOpt,
|
|
'format': '/sbin/mkfs.reiserfs',
|
|
'formatparam': '{labelparam} -f {device}',
|
|
'gpt': '0700',
|
|
'label': '-l {labelname}',
|
|
'msdos': '83',
|
|
'type':['hdd','usb-hdd']},
|
|
'btrfs': {'defaultopt': defaultOpt,
|
|
'format': '/sbin/mkfs.btrfs',
|
|
'formatparam': '{labelparam} {device}',
|
|
'gpt': '0700',
|
|
'label': '-L {labelname}',
|
|
'msdos': '83',
|
|
'type':['hdd','usb-hdd']},
|
|
'jfs': {'defaultopt': defaultOpt,
|
|
'format': '/sbin/mkfs.jfs',
|
|
'formatparam': '{labelparam} -f {device}',
|
|
'gpt': '0700',
|
|
'label': '-L {labelname}',
|
|
'msdos': '83',
|
|
'type':['hdd','usb-hdd']},
|
|
'xfs': {'defaultopt': defaultOpt,
|
|
'format': '/sbin/mkfs.xfs',
|
|
'formatparam': '{labelparam} -f {device}',
|
|
'gpt': '0700',
|
|
'label': '-L {labelname}',
|
|
'msdos': '83',
|
|
'type':['hdd','usb-hdd']},
|
|
'nilfs2': {'defaultopt': defaultOpt,
|
|
'format': '/sbin/mkfs.nilfs2',
|
|
'formatparam': '{labelparam} {device}',
|
|
'gpt': '0700',
|
|
'label': '-L {labelname}',
|
|
'msdos': '83',
|
|
'type':['hdd','usb-hdd']},
|
|
'swap': {'defaultopt': 'sw',
|
|
'format': '/sbin/mkswap',
|
|
'formatparam': '{device}',
|
|
'gpt': '8200',
|
|
'label': '',
|
|
'msdos': '82'},
|
|
'vfat': {'defaultopt': defaultOpt,
|
|
'format': '/usr/sbin/mkfs.vfat',
|
|
'formatparam': '{labelparam} -F 32 {device}',
|
|
'gpt': '0700',
|
|
'label': '-n {labelname}',
|
|
'msdos': '0b',
|
|
'type':['flash']},
|
|
'ntfs': {'defaultopt': defaultOpt,
|
|
'format': '/sbin/mkfs.ntfs',
|
|
'formatparam': '{labelparam} -FQ {device}',
|
|
'gpt': '0700',
|
|
'label': '-L {labelname}',
|
|
'msdos': '7',
|
|
'compatible':['ntfs-3g']},
|
|
'ntfs-3g': {'defaultopt': defaultOpt,
|
|
'format': '/sbin/mkfs.ntfs',
|
|
'formatparam': '{labelparam} -FQ {device}',
|
|
'gpt': '0700',
|
|
'label': '-L {labelname}',
|
|
'msdos': '7',
|
|
'compatible':['ntfs']}}
|
|
@classmethod
|
|
def firstAvailable(cls,listFS):
|
|
for fs in listFS:
|
|
if path.exists(cls.supportFS['format']):
|
|
return fs
|
|
else:
|
|
return ""
|
|
|
|
defaultFS = {'hdd':"ext4" \
|
|
if path.exists(supportFS['ext4']['format']) else \
|
|
"reiserfs" \
|
|
if path.exists(supportFS['reiserfs']['format']) else \
|
|
"ext3",
|
|
'flash':"vfat",
|
|
'usb-hdd': "ext4" \
|
|
if path.exists(supportFS['ext4']['format']) else \
|
|
"reiserfs" \
|
|
if path.exists(supportFS['reiserfs']['format']) else \
|
|
"ext3"}
|
|
|
|
@classmethod
|
|
def getDefaultOpt(cls,fs):
|
|
return cls.supportFS.get(fs,{'defaultopt':''})['defaultopt']
|
|
|
|
@classmethod
|
|
def checkFSForType(cls,fs,roottype):
|
|
return roottype in cls.supportFS.get(fs,{}).get('type',[])
|
|
|
|
class cltCopy(scanDirectory):
|
|
"""Copy clt files
|
|
|
|
Example:
|
|
cltCopier = cltCopy(target="/targetdir")
|
|
# copy all clt files from etc directory to /targetdir/etc
|
|
cltCopier.performCopy('/etc')
|
|
"""
|
|
def __init__(self,target='/tmp'):
|
|
self.target = target
|
|
|
|
performCopy = scanDirectory.scanningDirectory
|
|
|
|
def processingFile(self,pathname,prefix):
|
|
try:
|
|
if pathname.endswith(".clt"):
|
|
targetDir = pathJoin(self.target,path.dirname(pathname))
|
|
if not path.exists(targetDir):
|
|
os.makedirs(targetDir)
|
|
copy2(pathname,pathJoin(self.target,pathname))
|
|
except Exception,e:
|
|
raise InstallError(_("Failed to copy '%(src)s' to '%(dst)s'")%
|
|
{'src':pathname,'dst':pathJoin(self.target,pathname)})
|
|
return True
|
|
|
|
class otherfilesCopy(scanDirectory):
|
|
"""Copy some files
|
|
|
|
Example:
|
|
otherfilesCopier = otherfilesCopy(target="/targetdir")
|
|
# copy need files from etc directory to /targetdir/etc
|
|
otherfilesCopier.performCopy('/etc')
|
|
"""
|
|
def __init__(self,target='/tmp',reTest=".*"):
|
|
self.target = target
|
|
self.reTest = re.compile(reTest,re.S)
|
|
|
|
performCopy = scanDirectory.scanningDirectory
|
|
|
|
def processingFile(self,pathname,prefix):
|
|
try:
|
|
if self.reTest.search(pathname):
|
|
targetDir = pathJoin(self.target,path.dirname(pathname))
|
|
if not path.exists(targetDir):
|
|
os.makedirs(targetDir)
|
|
copy2(pathname,pathJoin(self.target,pathname))
|
|
except Exception,e:
|
|
raise InstallError(_("Failed to copy '%(src)s' to '%(dst)s'")%
|
|
{'src':pathname,'dst':pathJoin(self.target,pathname)})
|
|
return True
|
|
|
|
class ProgressTemplate(Template):
|
|
def __init__(self, setValueCallback, *args, **kwargs):
|
|
Template.__init__(self, *args, **kwargs)
|
|
self.setValueCallback = setValueCallback
|
|
self.value = None
|
|
|
|
def numberAllTemplates(self, number):
|
|
self.maximum = number
|
|
return True
|
|
|
|
def numberProcessTemplates(self,number):
|
|
value = number * 100 / self.maximum;
|
|
if value != self.value:
|
|
self.setValueCallback(value)
|
|
self.value = value
|
|
return True
|
|
|
|
class Install(color_print, SignalInterrupt):
|
|
"""Primary class for templates appling and system installation"""
|
|
|
|
def __init__(self):
|
|
self.clVars = None
|
|
self.clTempl = None
|
|
self.listDisksOptions = []
|
|
self.listBindsOptions = []
|
|
self.listSwapsOptions = []
|
|
self.startMessage = ""
|
|
self.lenStartMessage = 0
|
|
self.stdoutHide = None
|
|
self.stderrHide = None
|
|
Spinner().setWriteFunc(self.defaultPrint)
|
|
cl_overriding.exit = installExit
|
|
cl_overriding.printERROR = overprintERROR
|
|
# refresh information about LVM
|
|
refreshLVM()
|
|
# refresh information about device in udevadm info
|
|
refreshUdev()
|
|
|
|
|
|
def setNoColor(self):
|
|
self.color = False
|
|
|
|
def initVars(self,datavars=None):
|
|
"""Primary initialization of variables"""
|
|
if not datavars:
|
|
self.clVars = DataVarsInstall()
|
|
self.clVars.importInstall()
|
|
self.clVars.flIniFile()
|
|
else:
|
|
self.clVars = datavars
|
|
|
|
def cmpInstallVersion(self):
|
|
"""Compare current and install version(build)
|
|
|
|
Return:
|
|
1 - new version above current and installed
|
|
0 - new version equal current or installed
|
|
-1 - new version less current or installed
|
|
-2 - installed versin above current and new
|
|
"""
|
|
rootdev = self.clVars.Get('os_install_root_dev')
|
|
d = DistributiveRepository()._getfromcontent(rootdev)
|
|
curver = self.clVars.Get('os_linux_ver')
|
|
curbuild = self.clVars.Get('os_linux_build')
|
|
curver = (getTupleVersion(curver),curbuild)
|
|
nextver = self.clVars.Get('os_install_linux_ver')
|
|
nextbuild = self.clVars.Get('os_install_linux_build')
|
|
nextver = (getTupleVersion(nextver),nextbuild)
|
|
curnextres = cmp(nextver,curver)
|
|
if d and "ver" in d:
|
|
installedver = (getTupleVersion(d["ver"]),
|
|
d["build"])
|
|
if installedver > curver:
|
|
instnextres = cmp(nextver,installedver)
|
|
if instnextres <= 0 and curnextres == 1:
|
|
return -2
|
|
return instnextres
|
|
return curnextres
|
|
|
|
def printAllPartitonsTable(self):
|
|
"""Print install report"""
|
|
title, headerList, dataList = self.generateTableAllPartitionData()
|
|
tableObj = tableReport("", headerList, dataList)
|
|
tableObj.printReport(False)
|
|
|
|
def printLocationTables(self):
|
|
"""Print install report"""
|
|
title, headerList, dataList = self.generateTableMountData()
|
|
tableObj = tableReport("", headerList, dataList)
|
|
tableObj.printReport(False)
|
|
title, headerList, dataList = self.generateTableBindData()
|
|
if dataList:
|
|
tableObj = tableReport(title, headerList, dataList)
|
|
tableObj.printReport(False)
|
|
|
|
def printNetworkTables(self):
|
|
"""Print install report"""
|
|
title, headerList, dataList = self.generateTableNetworkData()
|
|
tableObj = tableReport("", headerList, dataList)
|
|
tableObj.printReport(False)
|
|
|
|
def printRouteTables(self):
|
|
"""Print install report"""
|
|
title, headerList, dataList = self.generateTableRouteData()
|
|
tableObj = tableReport("", headerList, dataList)
|
|
tableObj.printReport(False)
|
|
|
|
def printInfo(self,update=False):
|
|
clGet = self.clVars.Get
|
|
installedSystem = "%s %s"%(clGet('os_linux_name'),
|
|
clGet('os_linux_ver'))
|
|
mbrDevice = self.clVars.Get('os_install_mbr')
|
|
if not mbrDevice in ("","off"):
|
|
syspath = getUdevDeviceInfo(name=mbrDevice).get('DEVPATH','')
|
|
if not syspath.startswith('/sys'):
|
|
syspath = pathJoin('/sys',syspath)
|
|
pathVendor = "%s/device/vendor"%syspath
|
|
pathModel = "%s/device/model"%syspath
|
|
if path.exists(pathVendor) and path.exists(pathModel):
|
|
addonMbrInfo = " (%s %s)"% \
|
|
(open(pathVendor,'r').read().strip(),
|
|
open(pathModel,'r').read().strip())
|
|
else:
|
|
addonMbrInfo = ""
|
|
mbrdisk = "%s%s"%(clGet('os_install_mbr'),addonMbrInfo)
|
|
else:
|
|
mbrdisk = _("will not be changed")
|
|
|
|
flash = clGet('os_install_root_type')=="flash"
|
|
usbhdd = clGet('os_install_root_type')=="usb-hdd"
|
|
hdd = clGet('os_install_root_type')=="hdd"
|
|
if not flash:
|
|
musers = ", ".join(set(clGet('cl_migrate_user'))-set(['root'])) \
|
|
or _("none")
|
|
else:
|
|
musers = _("none")
|
|
|
|
dnsNoValue = _("none")
|
|
dhcps = self.clVars.Get('os_install_net_dhcp_set')
|
|
if dhcps:
|
|
if dhcps[0] == "on":
|
|
dnsNoValue = _("DHCP")
|
|
|
|
self.printSUCCESS(_("Installation") + " Calculate Linux")
|
|
printData = [
|
|
[(_("System"),True),
|
|
(_("Computer name"),clGet('os_install_net_hostname'),not flash),
|
|
(_("Domain name"),clGet('os_install_net_domain'),not flash),
|
|
(_("Users"), musers,not flash),
|
|
(_("Installed system"),installedSystem,True)
|
|
],
|
|
[(_("Localization"),not flash),
|
|
(_("Language"),
|
|
clGet('os_install_locale_lang'),True),
|
|
(_("Keymap"),clGet('os_install_locale_xkbname'),True),
|
|
(_("Timezone"),clGet('os_install_clock_timezone'),True),
|
|
],
|
|
[(_("Network services"),hdd),
|
|
(_("Network manager"),clGet('os_install_net_conf'),True),
|
|
(_("PROXY"),
|
|
clGet('os_install_proxy') or _("none"),True),
|
|
(_("NTP"),clGet('os_install_ntp') or _("none"),True),
|
|
(_("DNS"),clGet('os_install_net_dns') or dnsNoValue,True)
|
|
],
|
|
[(_("Hardware"),True),
|
|
(_("Machine hardware name"),
|
|
clGet('os_install_arch_machine'),True),
|
|
(_("Number of processors"),clGet('hr_cpu_num'),hdd),
|
|
(_("Videocard"),clGet('hr_video_name'),hdd),
|
|
(_("{0} video driver").format("Xorg"),
|
|
clGet('os_install_x11_video_drv'),hdd),
|
|
(_("Screen resolution"),clGet('os_install_x11_resolution'),hdd)
|
|
],
|
|
[(_("Network devices"),not flash),
|
|
(self.printNetworkTables,None,True)
|
|
],
|
|
[(_("Routes"),not flash),
|
|
(self.printRouteTables,None,True)
|
|
],
|
|
[(_("Location"),True),
|
|
(_("Master boot record")+" (MBR)",mbrdisk,True),
|
|
(self.printLocationTables,None,True)
|
|
],
|
|
[(_("Perform pre-install checkups"),True)]
|
|
]
|
|
|
|
for section in printData:
|
|
sectionname,condition = section[0]
|
|
# skip section
|
|
if not (callable(condition) and condition() or \
|
|
not callable(condition) and condition ):
|
|
continue
|
|
self.defaultPrint("%s\n"%sectionname)
|
|
for label, data, cond in section[1:]:
|
|
if not (callable(cond) and cond() or \
|
|
not callable(cond) and cond ):
|
|
continue
|
|
if callable(label):
|
|
label()
|
|
else:
|
|
self.printSUCCESS(label+": %s"%data)
|
|
|
|
# preinstall checkups
|
|
subname = self.clVars.Get('os_install_linux_subname')
|
|
subname = (" %s"%subname) if subname else ""
|
|
buildvar = self.clVars.Get('os_install_linux_build')
|
|
build = ""
|
|
if buildvar:
|
|
build = " (build %s)"%buildvar
|
|
|
|
if update:
|
|
cmpres = self.cmpInstallVersion()
|
|
image = self.clVars.Get('cl_image')
|
|
if image and ( not update or cmpres > 0):
|
|
deviceName = ""
|
|
if image.startswith('/dev'):
|
|
deviceImage = \
|
|
map(lambda x:x[1].rpartition(" ")[2],
|
|
filter(lambda x:x[0]==image,
|
|
self.clVars.zipVars("os_disk_dev","os_disk_content")))
|
|
if deviceImage:
|
|
if deviceImage[0] == "livecd":
|
|
deviceName = " " + _("on")+" CDROM (%s)"%image
|
|
else:
|
|
deviceName = " " + _("on")+" USB Flash (%s)"%image
|
|
|
|
self.printSUCCESS(_("An update found")+deviceName+": %s %s%s%s\n"%
|
|
(self.clVars.Get('os_install_linux_name'),
|
|
self.clVars.Get('os_install_linux_ver'),
|
|
subname,build))
|
|
else:
|
|
if update and cmpres == -2:
|
|
self.printWARNING(_("Update already installed."))
|
|
else:
|
|
self.printWARNING(_("No update available."))
|
|
|
|
def canInstallGrub2(self,target):
|
|
"""Check that system has grub2 in current and installed system"""
|
|
if self.clVars.Get('os_grub2_path'):
|
|
return bool(
|
|
filter(lambda x:x.startswith('grub-1.99'),
|
|
listDirectory('/var/db/pkg/sys-boot')))
|
|
return False
|
|
|
|
def prepareBoot(self,targetDistr):
|
|
"""Prepare system for boot"""
|
|
if self.clVars.Get('os_install_root_type') == "flash":
|
|
self.installSyslinuxBootloader(targetDistr)
|
|
else:
|
|
if self.canInstallGrub2(targetDistr):
|
|
self.installGrub2Bootloader(targetDistr)
|
|
else:
|
|
self.installLegacyGrubBootloader(targetDistr)
|
|
|
|
def getTargetDistributive(self,disk,fileSystem="reiserfs",isFormat=False,
|
|
systemId=None,buildermode=False):
|
|
"""Get target distributive by params"""
|
|
rootLabelName = "%s-%s"%(self.clVars.Get('os_install_linux_shortname'),
|
|
self.clVars.Get('os_install_linux_ver'))
|
|
mapPartPT = dict(self.clVars.zipVars("os_install_disk_dev","os_install_disk_part"))
|
|
if buildermode:
|
|
return ScratchPartitionDistributive(disk,mdirectory="/mnt/install",
|
|
check=True, fileSystem=fileSystem,
|
|
isFormat=isFormat, systemId=systemId,
|
|
rootLabel=rootLabelName,
|
|
partitionTable=mapPartPT.get(disk,None))
|
|
elif self.clVars.Get('os_install_root_type')=="flash":
|
|
return FlashDistributive(disk,mdirectory="/mnt/install",
|
|
check=True, fileSystem=fileSystem,
|
|
isFormat=isFormat, systemId=systemId,
|
|
partitionTable=mapPartPT.get(disk,None))
|
|
else:
|
|
target = PartitionDistributive(disk,mdirectory="/mnt/install",
|
|
check=True, fileSystem=fileSystem,
|
|
isFormat=isFormat, systemId=systemId,
|
|
rootLabel=rootLabelName,
|
|
partitionTable=mapPartPT.get(disk,None))
|
|
noRootPartDisksOptions = filter(lambda x: x['mountPoint']!="/",
|
|
self.listDisksOptions)
|
|
flagMultipartition = False
|
|
objMultiPartitions = False
|
|
# Disk multipartitions
|
|
if noRootPartDisksOptions:
|
|
flagMultipartition = True
|
|
objMultiPartitions = MultiPartitions()
|
|
for diskOptions in noRootPartDisksOptions:
|
|
dev = diskOptions["dev"]
|
|
mountPoint = diskOptions["mountPoint"]
|
|
fileSystem = diskOptions["fileSystem"]
|
|
isFormat = diskOptions["isFormat"]
|
|
systemId = diskOptions["systemId"]
|
|
partitionTable = mapPartPT.get(dev,None)
|
|
objMultiPartitions.addPartition(dev=dev,
|
|
mountPoint=mountPoint,
|
|
fileSystem=fileSystem,
|
|
isFormat=isFormat,
|
|
systemId=systemId,
|
|
partitionTable=partitionTable)
|
|
# Swap multipartitions
|
|
if self.listSwapsOptions:
|
|
flagMultipartition = True
|
|
if not objMultiPartitions:
|
|
objMultiPartitions = MultiPartitions()
|
|
for diskOptions in self.listSwapsOptions:
|
|
dev = diskOptions["dev"]
|
|
mountPoint = "swap"
|
|
fileSystem = diskOptions["fileSystem"]
|
|
isFormat = diskOptions["isFormat"]
|
|
systemId = diskOptions["systemId"]
|
|
partitionTable = mapPartPT.get(dev,None)
|
|
objMultiPartitions.addPartition(dev=dev,
|
|
mountPoint=mountPoint,
|
|
fileSystem=fileSystem,
|
|
isFormat=isFormat,
|
|
systemId=systemId,
|
|
partitionTable=partitionTable)
|
|
# Bind multipartitions
|
|
if self.listBindsOptions:
|
|
flagMultipartition = True
|
|
if not objMultiPartitions:
|
|
objMultiPartitions = MultiPartitions()
|
|
for diskOptions in self.listBindsOptions:
|
|
dev = diskOptions["srcMountPoint"]
|
|
mountPoint = diskOptions["destMountPoint"]
|
|
fileSystem = "bind"
|
|
isFormat = diskOptions["isFormat"]
|
|
objMultiPartitions.addPartition(dev=dev,
|
|
mountPoint=mountPoint,
|
|
fileSystem=fileSystem,
|
|
isFormat=isFormat,
|
|
systemId=None,
|
|
partitionTable=None)
|
|
if flagMultipartition:
|
|
# Set Multipartition
|
|
target.multipartition=objMultiPartitions
|
|
return target
|
|
|
|
def closeClTemplate(self):
|
|
if self.clTempl:
|
|
if self.clTempl.cltObj:
|
|
self.clTempl.cltObj.closeFiles()
|
|
self.clTempl.closeFiles()
|
|
self.clTempl = None
|
|
|
|
def applyTemplatesStartup(self):
|
|
"""Apply templates for root of system."""
|
|
#self.clVars.Set("cl_root_path","/", True)
|
|
self.clVars.Set("cl_chroot_path","/", True)
|
|
self.clTempl = ProgressTemplate(self.setProgress,self.clVars,
|
|
cltFilter=False)
|
|
dirsFiles = self.clTempl.applyTemplates()
|
|
if self.clTempl.getError():
|
|
self.printERROR(self.clTempl.getError())
|
|
return False
|
|
else:
|
|
return dirsFiles
|
|
|
|
def applyTemplatesFlash(self,directory):
|
|
"""Apply templates for root of system."""
|
|
#self.clVars.Set("cl_root_path",directory, True)
|
|
self.clVars.Set("cl_chroot_path","/", True)
|
|
self.clVars.Set("cl_chroot_grub","/", True)
|
|
self.clVars.Set("cl_root_path",directory, True)
|
|
self.clTempl = ProgressTemplate(self.setProgress,self.clVars,
|
|
cltObj=False)
|
|
dirsFiles = self.clTempl.applyTemplates()
|
|
if self.clTempl.getError():
|
|
raise InstallError(self.clTempl.getError())
|
|
else:
|
|
return dirsFiles
|
|
|
|
def applyTemplates(self,directory,grubDirectory):
|
|
"""Apply templates for root of system."""
|
|
self.clVars.Set("cl_chroot_path",directory, True)
|
|
self.clVars.Set("cl_chroot_grub",grubDirectory, True)
|
|
clTemplateCltPath = \
|
|
filter(lambda x:path.exists(x),
|
|
map(lambda x:pathJoin(directory,x),
|
|
self.clVars.Get('cl_template_clt_path')))
|
|
self.clVars.Set('cl_template_clt_path',clTemplateCltPath,True)
|
|
self.clTempl = ProgressTemplate(self.setProgress,self.clVars,
|
|
cltFilter=False)
|
|
dirsFiles = self.clTempl.applyTemplates()
|
|
if self.clTempl.getError():
|
|
raise InstallError(self.clTempl.getError())
|
|
else:
|
|
return dirsFiles
|
|
|
|
def checkDuplicate(self,datalist,name,key=lambda x:x):
|
|
"""Check on duplicate and print error"""
|
|
keydata = map(key,datalist)
|
|
dupKey = set(filter(lambda x:keydata.count(x)>1, keydata))
|
|
if dupKey:
|
|
self.printERROR(_("Duplicated {keyname}: {keylist}").format(
|
|
keyname=name,keylist=",".join(dupKey)))
|
|
return False
|
|
return True
|
|
|
|
def setVarList(self,varsList,matrix):
|
|
"""Set matrix to vars"""
|
|
if not matrix:
|
|
map(lambda x:self.clVars.Set(x,[],True),varsList)
|
|
else:
|
|
map(lambda x:self.clVars.Set(x[0],list(x[1]),True),
|
|
zip(varsList,zip(*matrix)))
|
|
|
|
def setNetwork(self,ipaddrs,dhcps,routes):
|
|
"""Set network configuration"""
|
|
def changeIpData(ipdata):
|
|
iface,ipaddr,cidr,dhcpset = ipdata
|
|
if iface in dhcps:
|
|
if dhcpset == "off":
|
|
invalidRouteIface.append(iface)
|
|
dhcpset = "on"
|
|
cidr = ""
|
|
ipaddr = ""
|
|
elif iface in dictIpAddr:
|
|
newipaddr,op,newcidr = dictIpAddr[iface].partition('/')
|
|
if dhcpset == "on" or newipaddr != ipaddr or newcidr != cidr:
|
|
invalidRouteIface.append(iface)
|
|
ipaddr,cidr = newipaddr,newcidr
|
|
dhcpset = "off"
|
|
return (iface,ipaddr,cidr,dhcpset)
|
|
|
|
def removeInvalidRoutes(routedata):
|
|
"""Remove route for device with new ip"""
|
|
network,gw,dev,src = routedata
|
|
if dev in invalidRouteIface:
|
|
return False
|
|
return True
|
|
|
|
def removeSpecifiedRoutes(routedata):
|
|
"""Remove route for user specified"""
|
|
network,gw,dev,src = routedata
|
|
if network in specifedNet:
|
|
return False
|
|
return True
|
|
|
|
def specifedRoutes(routes,ipAddrs,routedata):
|
|
NET,GW,DEV,SRC=0,1,2,3
|
|
nets = filter(lambda net:net != "default",
|
|
map(lambda x:x[NET],routes)+map(lambda x:x[NET],routedata))
|
|
routes = filter(lambda x:x[GW] or x[SRC],routes)
|
|
wrongGws = map(lambda x:x[GW],
|
|
filter(lambda x:not ip.isIpInNet(x[GW],
|
|
*(set(nets)-set([x[NET]]))),
|
|
filter(lambda x:x[GW],
|
|
routes)))
|
|
if wrongGws:
|
|
raise InstallError(_("Gateways %s is unreachable")%
|
|
(",".join(wrongGws)))
|
|
wrongIps = map(lambda x:x[SRC],
|
|
filter(lambda x:not x[SRC] in ipAddrs,
|
|
filter(lambda x:x[SRC],routes)))
|
|
if wrongIps:
|
|
raise InstallError(_("Wrong ip addresse %s in source IP")%
|
|
(",".join(wrongIps)))
|
|
newroutes = []
|
|
for network,gw,dev,src in routedata+routes:
|
|
if not dev:
|
|
gwnetwork = ip.isIpInNet(gw,*nets)[0]
|
|
dev = filter(lambda x:x[NET]==gwnetwork,
|
|
routedata+newroutes)
|
|
if not dev:
|
|
raise InstallError(
|
|
_("Failed to determine the device for network %s")%
|
|
network)
|
|
dev = dev[0][DEV]
|
|
if not gw and not src:
|
|
continue
|
|
newroutes.append((network,gw,dev,src))
|
|
return newroutes
|
|
|
|
def standardRoutes(ipMatrix,needDev):
|
|
IFACE,IP,CIDR,DHCP = 0,1,2,3
|
|
return map(lambda x:(ip.getIpNet(x[IP],cidr=x[CIDR]),
|
|
"",x[IFACE],x[IP]),
|
|
filter(lambda x:x[DHCP] =="off" and x[IFACE] in needDev,
|
|
ipMatrix))
|
|
|
|
# check interfaces
|
|
getVar = self.clVars.Get
|
|
interfaces = getVar('os_install_net_interfaces')
|
|
if interfaces:
|
|
defaultIface = interfaces[0]
|
|
else:
|
|
defaultIface = ""
|
|
ipaddrs = map(lambda x: x if len(x)==2 else (defaultIface,x[0]),
|
|
ipaddrs)
|
|
specifiedIface = dhcps + map(lambda x:x[0],ipaddrs)
|
|
routeIface = filter(lambda x:x,
|
|
map(lambda x:x[2],filter(lambda x:len(x)>2,routes)))
|
|
wrongIface = set(specifiedIface+routeIface)-set(interfaces)
|
|
# check correct iface
|
|
if wrongIface:
|
|
self.printERROR(_("Wrong interface: %s")%",".join(wrongIface))
|
|
return False
|
|
# check dup iface
|
|
if not self.checkDuplicate(specifiedIface,_("interfaces")):
|
|
return False
|
|
# check dup ip
|
|
if not self.checkDuplicate(ipaddrs,_("addresses"),key=lambda x:x[1]):
|
|
return False
|
|
dictIpAddr = dict(ipaddrs)
|
|
|
|
# set user data to variables
|
|
ipVars = map(lambda x:'os_install_net_%s'%x,
|
|
('interfaces', 'ip', 'cidr', 'dhcp_set'))
|
|
invalidRouteIface = []
|
|
self.setVarList(ipVars, map(changeIpData, self.clVars.zipVars(*ipVars)))
|
|
specifedNet = map(lambda x:x[0],routes)
|
|
|
|
routeVars = map(lambda x:'os_install_net_route_%s'%x,
|
|
('network', 'gw', 'dev', 'src'))
|
|
try:
|
|
self.setVarList(routeVars,
|
|
specifedRoutes(routes,getVar('os_install_net_ip'),
|
|
filter(removeSpecifiedRoutes,
|
|
standardRoutes(self.clVars.zipVars(*ipVars),invalidRouteIface)+
|
|
filter(removeInvalidRoutes,
|
|
self.clVars.zipVars(*routeVars)))))
|
|
except InstallError,e:
|
|
self.printERROR(str(e))
|
|
return False
|
|
|
|
# check dup nets
|
|
if not self.checkDuplicate(routes,_("networks"),key=lambda x:x[0]):
|
|
return False
|
|
return True
|
|
|
|
def setDisks(self,listDisks):
|
|
"""Set data for installation partitions"""
|
|
lSwaps = []
|
|
lBinds = []
|
|
lDisks = []
|
|
DEVICE,MP,FS,FORMAT = 0,1,2,3
|
|
print "LD",listDisks
|
|
listDisks = map(lambda x:x + ['']*(4-len(x)),
|
|
listDisks)
|
|
for entry in listDisks:
|
|
if entry[DEVICE].startswith('/dev'):
|
|
if entry[MP] != "swap":
|
|
lDisks.append(entry)
|
|
else:
|
|
lSwaps.append(entry)
|
|
else:
|
|
lBinds.append(entry[:2])
|
|
|
|
error = lambda *args,**kw: self.errlist.append(InstallError(*args,**kw))
|
|
|
|
usedMP = list(zip(*(map(lambda x:x+[""],lDisks+lBinds)))[1])
|
|
|
|
mapCurrent = dict(map(lambda x:(x[DEVICE],(x[MP],x[FS])),
|
|
self.clVars.zipVars('os_disk_dev',
|
|
'os_disk_mount',
|
|
'os_disk_format')))
|
|
lDisks = lDisks + lSwaps
|
|
for diskData in lDisks:
|
|
# if fs not specified
|
|
curFS = mapCurrent[diskData[DEVICE]][1]
|
|
print diskData
|
|
if diskData[FS] == '':
|
|
# if current deivce has fs
|
|
if curFS:
|
|
# install filesystem is current
|
|
diskData[FS] = curFS
|
|
if diskData[MP] == '/':
|
|
diskData[FORMAT] = 'yes'
|
|
else:
|
|
# install filesystem is default
|
|
diskData[FS] = FileSystemManager.defaultFS[osInstallRootType]
|
|
if diskData[FORMAT] == 'no':
|
|
error(
|
|
_("Disk %s without filesystem should be formatted"%
|
|
diskData[DEVICE], field="disk"))
|
|
diskData[FORMAT] = 'yes'
|
|
else:
|
|
compatibleFS = \
|
|
FileSystemManager.supportFS.get(diskData[FS],{})
|
|
compatibleFS = compatibleFS.get('compatible',[]) + [curFS]
|
|
# if fs specified but format no specified
|
|
if diskData[FORMAT] == '':
|
|
# if fs equal current fs or
|
|
# current fs compatible with specified fs
|
|
if diskData[FS] in compatibleFS and diskData[MP] != '/':
|
|
diskData[FORMAT] = 'no'
|
|
else:
|
|
diskData[FORMAT] = 'yes'
|
|
print diskData
|
|
if not diskData[FS] in self.clVars.Get('os_format_type'):
|
|
error(_("Unsupported file system %s")%diskData[FS],
|
|
field="disk")
|
|
else:
|
|
if not diskData[FS] in map(lambda x:x[0],
|
|
filter(lambda x:x[1] == 'yes',
|
|
self.clVars.zipVars('os_format_type',
|
|
'os_format_use'))):
|
|
error(_("File system '%s' is not available")%diskData[FS],
|
|
field="disk")
|
|
if not FileSystemManager.checkFSForType(diskData[FS],
|
|
osInstallRootType):
|
|
error(
|
|
_("File system for '%(mp)s' should not be '%(opt)s'")
|
|
%{'mp':diskData[MP], 'opt':diskData[FS]},field="disk")
|
|
if curMP:
|
|
if diskData[FORMAT] == 'yes' and curMP != '/':
|
|
error(_("Disk {device} should be formatted, but can "
|
|
"not be formatted because mounted to "
|
|
"{mountpoint} in the current system").format(
|
|
device=diskData[DEVICE],mountpoint=curMP),
|
|
field="disk")
|
|
if diskData[FORMAT] == 'no':
|
|
if not diskData[FS] in compatibleFS:
|
|
error(_("Disk {device} should be formatted").format(
|
|
device=diskData[DEVICE]),field="disk")
|
|
|
|
diskDev = self.clVars.Get('os_disk_dev')
|
|
mapInstallData = dict(map(lambda x:(x[DEVICE],(x[MP],x[FS],x[FORMAT])),
|
|
lDisks))
|
|
new_mount = map(lambda x: mapInstallData.get(x,['']*3)[MP-1],diskDev)
|
|
new_format = map(lambda x: mapInstallData.get(x,['']*3)[FS-1],diskDev)
|
|
new_isformat = \
|
|
map(lambda x: mapInstallData.get(x,['']*3)[FORMAT-1],diskDev)
|
|
new_options = map(lambda x:FileSystemManager.getDefaultOpt(x[1]) \
|
|
if x[0] else '',
|
|
zip(new_mount,new_format))
|
|
|
|
new_bind_src = map(lambda x:x[0],
|
|
filter(lambda x: not x[1] in ("","none"),
|
|
lBinds))
|
|
new_bind_dest = map(lambda x:x[1],
|
|
filter(lambda x: not x[1] in ("","none"),
|
|
lBinds))
|
|
map(lambda x:self.clVars.Set(x[0],x[1],True),
|
|
(('os_install_disk_mount',new_mount),
|
|
('os_install_disk_mount',new_mount),
|
|
('os_install_disk_format',new_format),
|
|
('os_install_disk_perform_format',new_isformat),
|
|
('os_install_disk_options',new_options),
|
|
('os_install_bind_path',new_bind_src),
|
|
('os_install_bind_mountpoint',new_bind_dest)))
|
|
try:
|
|
if not self.clVars.Get('os_grub2_path'):
|
|
self.checkForLegacyGrub()
|
|
else:
|
|
self.checkForGrub2()
|
|
except InstallError,e:
|
|
error.append(e)
|
|
return True
|
|
|
|
def checkForGrub2(self):
|
|
"""Check current disk configuration for installation for install
|
|
GRUB2"""
|
|
bootDiskType = self.varSelect("os_disk_type",
|
|
where="os_install_disk_mount", eq="/boot")
|
|
rootDiskType = self.varSelect("os_disk_type",
|
|
where="os_install_disk_mount", eq="/")
|
|
grubDiskType = bootDiskType or rootDiskType
|
|
if "lvm-raid" in grubDiskType:
|
|
raise InstallError(
|
|
_("Grub does not support booting from a RAID assembled from LVM.")
|
|
+ " " +
|
|
_("Try to use a separate /boot partition"),field="disk")
|
|
if grubDiskType.count("raid")>1:
|
|
raise InstallError(
|
|
_("Grub does not support booting from a RAID assembled "
|
|
"from another RAID.")
|
|
+ " " +
|
|
_("Try to use a separate /boot partition"),field="disk")
|
|
return True
|
|
|
|
def checkForLegacyGrub(self):
|
|
"""Check current disk configuration for installation for install
|
|
legacy grub"""
|
|
bootDiskType = self.varSelect("os_disk_type",
|
|
where="os_install_disk_mount", eq="/boot")
|
|
rootDiskType = self.varSelect("os_disk_type",
|
|
where="os_install_disk_mount", eq="/")
|
|
bootDiskFormat = self.varSelect("os_install_disk_format",
|
|
where="os_install_disk_mount", eq="/boot")
|
|
rootDiskFormat = self.varSelect("os_install_disk_format",
|
|
where="os_install_disk_mount", eq="/")
|
|
bootDiskType = bootDiskType or rootDiskType
|
|
bootDiskFormat = bootDiskFormat or rootDiskFormat
|
|
if "lvm" in bootDiskType or "raid" in bootDiskType:
|
|
raise InstallError(
|
|
_("Legacy grub does not support boot from raid or lvm "
|
|
"without separate /boot partition"),
|
|
field="disk")
|
|
if bootDiskFormat in ("btrfs","nilfs2"):
|
|
raise InstallError(
|
|
_("Legacy grub does not support booting from %s without "
|
|
"separate /boot partition")%bootDiskFormat,
|
|
field="disk")
|
|
return True
|
|
|
|
def setUsers(self,listUsers,autologinUser):
|
|
"""Set users data (migration)"""
|
|
if autologinUser == "none":
|
|
autologinUser = ""
|
|
if autologinUser or autologinUser == "":
|
|
self.clVars.Set('cl_autologin', autologinUser, force=True)
|
|
else:
|
|
autologinUser = self.clVars.Get('cl_autologin')
|
|
autologinUser = [autologinUser] if autologinUser else []
|
|
listUsers = listUsers or []
|
|
if listUsers or autologinUser:
|
|
migrateUsers = list(set(listUsers+autologinUser))
|
|
migrateUsers.sort()
|
|
migrateUsers = ["root"] + filter(lambda x: x!="root", migrateUsers)
|
|
self.clVars.Set('cl_migrate_user', migrateUsers, force=True)
|
|
return True
|
|
|
|
def createListOptions(self):
|
|
"""Create listDisksOptions, listSwapsOptions and listBindOptions
|
|
by variables"""
|
|
diskData = zip(self.clVars.Get('os_install_disk_dev'),
|
|
self.clVars.Get('os_install_disk_mount'),
|
|
self.clVars.Get('os_install_disk_format'),
|
|
self.clVars.Get('os_install_disk_options'),
|
|
self.clVars.Get('os_install_disk_perform_format'))
|
|
bindData = zip(self.clVars.Get('os_install_bind_path'),
|
|
self.clVars.Get('os_install_bind_mountpoint'))
|
|
listToOptDict = lambda x: {'dev':x[0],
|
|
'mountPoint':x[1],
|
|
'fileSystem':x[2],
|
|
'options':x[3].split(','),
|
|
'isFormat':True if x[4] == "on" else False}
|
|
listToOptDictBind = lambda x:{'srcMountPoint':x[0],
|
|
'destMountPoint':x[1],
|
|
'options':['bind'],
|
|
'isFormat':False,
|
|
'fileSystem':'none'}
|
|
print diskData
|
|
self.listDisksOptions = map(listToOptDict,
|
|
filter(lambda x:x[1] and x[1] != "swap",
|
|
diskData))
|
|
self.listSwapsOptions = map(listToOptDict,
|
|
filter(lambda x: x[1] == "swap",
|
|
diskData))
|
|
|
|
self.listBindsOptions = map(listToOptDictBind,bindData)
|
|
|
|
# update system id
|
|
osDiskDevices = self.clVars.Get('os_disk_dev')
|
|
|
|
mapDiskId = dict(zip(self.clVars.Get('os_disk_dev'),
|
|
self.clVars.Get('os_disk_id')))
|
|
updateIdDict = dict(filter(lambda x:x[1]!=mapDiskId.get(x[0],''),
|
|
zip(self.clVars.Get('os_install_disk_dev'),
|
|
self.clVars.Get('os_install_disk_id'))))
|
|
for disk in self.listDisksOptions + self.listSwapsOptions:
|
|
if disk['dev'] in updateIdDict:
|
|
disk['systemId'] = updateIdDict[disk['dev']]
|
|
else:
|
|
disk['systemId'] = None
|
|
return True
|
|
|
|
def setInstallOptions(self, listDisks, listBinds, listSwaps, listUsers,
|
|
autologinUser, brDisk):
|
|
"""Set install options (set users, disks and boot record"""
|
|
try:
|
|
if self.setUsers(listUsers,autologinUser) and \
|
|
self.setDisks(listDisks,listBinds,listSwaps) and \
|
|
self.setBR(brDisk):
|
|
return self.createListOptions()
|
|
else:
|
|
return False
|
|
except InstallError,e:
|
|
self.printERROR(str(e).strip())
|
|
return False
|
|
|
|
def getDeviceByField(self,field,value, secondPrefix="os_disk"):
|
|
"""Get device by fields (install load format uuid grub part name)"""
|
|
return self.getFieldByField('dev',field,value,
|
|
secondPrefix=secondPrefix)
|
|
|
|
def getFieldByField(self,resField,field,value, firstPrefix="os_disk",
|
|
secondPrefix="os_disk"):
|
|
res = filter(lambda x: x[1] == value,
|
|
zip(self.clVars.Get('%s_%s'%(firstPrefix,resField)),
|
|
self.clVars.Get('%s_%s'%(secondPrefix,field)))) or\
|
|
[("","")]
|
|
return res[0][0]
|
|
|
|
def getFieldByDevice(self,field,device):
|
|
"""Get value of field by device"""
|
|
device_hash = self.clVars.Get('os_disk_hash')
|
|
if device in device_hash and field in device_hash[device]:
|
|
return device_hash[device][field]
|
|
else:
|
|
return ""
|
|
|
|
def setActivePartition(self,partition):
|
|
"""TODO: don't work with GPT. Don't work must be rewrite!!!!!"""
|
|
reActive = re.compile('^%s\s*[*]'%partition)
|
|
device = filter(lambda x:x in partition,
|
|
self.clVars.Get('os_device_dev'))
|
|
if not device:
|
|
raise DistributiveError(_("Failed to find the parent device"))
|
|
device = device[0]
|
|
|
|
fdiskProcess = process("/sbin/fdisk","-l",device)
|
|
if fdiskProcess.failed():
|
|
raise DistributiveError(_("Failed to get device information\n%s")%
|
|
fdiskProcess.read())
|
|
if not filter(reActive.search,fdiskProcess):
|
|
grubDisk = self.getFieldByField("grub","mount","/",
|
|
secondPrefix="os_install_disk")
|
|
if grubDisk and grubDisk.rpartition(',')[2].isdigit():
|
|
fdiskProcess = process("/sbin/fdisk", device)
|
|
fdiskProcess.write("a\n%d\nw\n"%
|
|
(int(grubDisk.rpartition(',')[2])+1))
|
|
if fdiskProcess.success():
|
|
return True
|
|
if filter(reActive.search,process("/sbin/fdisk",
|
|
"-l",device)):
|
|
return True
|
|
raise DistributiveError(_("Failed to set the active partition"))
|
|
else:
|
|
return True
|
|
|
|
def installSyslinuxBootloader(self,target):
|
|
"""Install boot loader by syslinux
|
|
|
|
Perform syslinux installation to flash.
|
|
"""
|
|
ddProcess = process("/bin/dd","if=/usr/share/syslinux/mbr.bin",
|
|
"of=%s"%self.clVars.Get('os_install_mbr'),
|
|
stderr=STDOUT)
|
|
if ddProcess.failed():
|
|
raise DistributiveError(
|
|
_("Failed to write the master boot record\n%s")%
|
|
ddProcess.read())
|
|
target.close()
|
|
installRootDev = self.clVars.Get('os_install_root_dev')
|
|
syslinuxProcess = process("/usr/bin/syslinux",
|
|
installRootDev, stderr=STDOUT)
|
|
if syslinuxProcess.failed():
|
|
raise DistributiveError(_("Failed to install syslinux\n%s")%
|
|
syslinuxProcess.read())
|
|
# is partition active
|
|
return self.setActivePartition(self.clVars.Get('os_install_root_dev'))
|
|
|
|
def varSelect(self,selField,where="os_disk_dev",eq=""):
|
|
"""Select value from os_disk/device matrix"""
|
|
res = filter(lambda x: x[1] == eq,
|
|
zip(self.clVars.Get(selField),
|
|
self.clVars.Get(where))) or\
|
|
[("","")]
|
|
return res[0][0]
|
|
|
|
def getPartitionForParted(self,partition):
|
|
"""Get partition info for parted exectution"""
|
|
# get disk num and partitin num
|
|
bootMap = \
|
|
self.varSelect("os_disk_grub",where="os_disk_dev",eq=partition)
|
|
# check valid numbers
|
|
deviceNumber,op,partitionNumber = bootMap.partition(',')
|
|
if not deviceNumber.isdigit() or \
|
|
not partitionNumber.isdigit():
|
|
return (False,False)
|
|
# get partition number
|
|
partitionNumber = int(partitionNumber)+1
|
|
# get device name
|
|
deviceName = self.varSelect("os_device_dev",where="os_device_map",
|
|
eq=int(deviceNumber))
|
|
if deviceName:
|
|
return (deviceName,partitionNumber)
|
|
return (False,False)
|
|
|
|
def setBiosGrubForBootPartition(self):
|
|
"""Set bios_grub flag for boot partition in gpt (WRONG)"""
|
|
for bootPath in ("/boot","/"):
|
|
# get grub disk by mount point
|
|
bootPart = self.varSelect(
|
|
"os_disk_part",where="os_install_disk_mount",eq=bootPath)
|
|
if bootPart:
|
|
if bootPart == "gpt":
|
|
bootPart = self.varSelect(
|
|
"os_disk_dev",where="os_install_disk_mount",eq=bootPath)
|
|
deviceName,partitionNumber = \
|
|
self.getPartitionForParted(bootPart)
|
|
cmdParted = varsShare().getProgPath('/usr/sbin/parted')
|
|
if not cmdParted:
|
|
return False
|
|
partedProcess = process(cmdParted,deviceName,
|
|
"set",str(partitionNumber),"bios_grub","on")
|
|
return partedProcess.success()
|
|
return True
|
|
return False
|
|
|
|
def installGrub2Bootloader(self,target):
|
|
"""
|
|
Install grub2 boot loader
|
|
"""
|
|
cmdGrubInstall = self.clVars.Get('os_grub2_path')
|
|
#if not self.setBiosGrubForBootPartition():
|
|
# raise DistributiveError(
|
|
# _("Failed to set bios_grub flag for the boot partition"))
|
|
if not cmdGrubInstall:
|
|
raise DistributiveError(_("Failed to install the bootloader"))
|
|
|
|
for mbrDisk in self.clVars.Get('os_install_mbr'):
|
|
process("sync").success()
|
|
grubProcess = process(cmdGrubInstall,
|
|
"--boot-directory=%s"%target.getBootDirectory(),
|
|
mbrDisk, "-f", stderr=STDOUT,envdict=os.environ)
|
|
if grubProcess.failed():
|
|
raise DistributiveError(_("Failed to install the bootloader"))
|
|
|
|
def installLegacyGrubBootloader(self,target):
|
|
"""
|
|
Install legecy grub boot loader
|
|
|
|
Perform grub installation to disk, which has root partition
|
|
"""
|
|
cmdGrub = varsShare().getProgPath('/sbin/grub')
|
|
if not cmdGrub:
|
|
raise DistributiveError(_("Failed to install the bootloader"))
|
|
grubProcess = process(cmdGrub,
|
|
"--device-map=%s/boot/grub/device.map"%target.getDirectory(),
|
|
"--batch",stderr=STDOUT)
|
|
for bootPath in ("/boot","/"):
|
|
# get grub disk by mount point
|
|
bootDisk = self.varSelect(
|
|
"os_disk_grub",where="os_install_disk_mount",eq=bootPath)
|
|
if bootDisk:
|
|
break
|
|
mbrDisk = self.clVars.Get('os_install_mbr')
|
|
mbrDiskNum = self.varSelect(
|
|
"os_device_map",where="os_device_dev",eq=mbrDisk)
|
|
if not mbrDiskNum and mbrDiskNum != 0:
|
|
raise DistributiveError(_("Failed to determine mbr"))
|
|
for line in ("root (hd%s)"%bootDisk,
|
|
"setup (hd%d)"%mbrDiskNum,
|
|
"quit"):
|
|
grubProcess.write("%s\n"%line)
|
|
if grubProcess.failed():
|
|
raise DistributiveError(_("Failed to install the bootloader"))
|
|
|
|
def convertTypeToScheme(self,data):
|
|
"""Convert os_disk_type to human readable names"""
|
|
if type(data) == tuple:
|
|
diskScheme, driveType = data
|
|
else:
|
|
diskScheme, driveType = data,""
|
|
res = ""
|
|
if diskScheme.endswith("raid-lvm"):
|
|
return _("LVM on RAID")
|
|
elif "disk-partition" == diskScheme and driveType == "flash":
|
|
return _("Partition on flash")
|
|
elif "disk-partition" == diskScheme and driveType == "usb-hdd":
|
|
return _("Partition on USB-HDD")
|
|
elif "disk-partition" == diskScheme:
|
|
return _("Partition on disk")
|
|
elif "raid-partition" == diskScheme:
|
|
return _("Partition on RAID")
|
|
elif "raidmember" in diskScheme:
|
|
diskScheme = diskScheme.rpartition("raidmember(")[2]
|
|
diskScheme = diskScheme.partition(")")[0]
|
|
return _("RAID %s member")%diskScheme
|
|
elif "lvmmember" in diskScheme:
|
|
lvms = []
|
|
while "lvmmember" in diskScheme:
|
|
diskScheme,op,data = diskScheme.rpartition("lvmmember(")
|
|
lvms.append(data.partition(")")[0])
|
|
return _("LVM %s member")%",".join(lvms)
|
|
elif "disk" == diskScheme:
|
|
return _("Disk without partitions")
|
|
elif "lvm" in diskScheme:
|
|
return _("LVM")
|
|
elif "raid" in diskScheme:
|
|
return _("RAID")
|
|
elif "cdrom" in diskScheme:
|
|
return _("CDROM")
|
|
else:
|
|
return _("Partition")
|
|
|
|
def generateTableAllPartitionData(self):
|
|
"""Generate table for all partitions"""
|
|
|
|
title = _("Available partitions")
|
|
headerList = [_("Size"),_("Device"),_("Label"),_("Mount point"),
|
|
_("File system"), _("Type"),_("OS")]
|
|
deviceHash = self.clVars.Get('os_device_hash')
|
|
diskHash = self.clVars.Get('os_disk_hash')
|
|
getTypeByDevice = lambda x: \
|
|
deviceHash.get(diskHash[x].get('parent',{}),{}).get('type','')
|
|
return title, headerList, zip(self.clVars.Get('os_disk_size'),
|
|
self.clVars.Get('os_disk_dev'),
|
|
self.clVars.Get('os_disk_name'),
|
|
self.clVars.Get('os_disk_mount'),
|
|
self.clVars.Get('os_disk_format'),
|
|
map(self.convertTypeToScheme,
|
|
zip(self.clVars.Get('os_disk_type'),
|
|
map(getTypeByDevice,self.clVars.Get('os_disk_dev')))),
|
|
self.clVars.Get('os_disk_content'))
|
|
|
|
def generateTableMountData(self):
|
|
"""Get data from print table"""
|
|
title = _("Location")
|
|
allDevicesOpt = self.listDisksOptions + self.listSwapsOptions
|
|
listIsFormat = []
|
|
for dev in self.clVars.Get('os_disk_dev'):
|
|
devCmdOpt = filter(lambda x: x['dev']==dev, allDevicesOpt)
|
|
if devCmdOpt:
|
|
if devCmdOpt[0]["isFormat"]:
|
|
listIsFormat.append(_("Yes"))
|
|
else:
|
|
listIsFormat.append("")
|
|
else:
|
|
listIsFormat.append("")
|
|
|
|
fileSystemData = zip(self.clVars.Get('os_install_disk_format'),
|
|
self.clVars.Get('os_disk_format'))
|
|
listFileSystem = map(lambda x: x[0] if x[0] else x[1], fileSystemData)
|
|
#fileSystemData = zip(listFileSystem,
|
|
#self.clVars.Get('os_disk_format'))
|
|
#listFileSystem = map(lambda x:\
|
|
#x[0] if x[0]==x[1] else "%s -> %s" %(x[1], x[0]),
|
|
#fileSystemData)
|
|
listMountPoint = map(lambda x: "" if x=="swap" else x,
|
|
self.clVars.Get('os_install_disk_mount'))
|
|
if self.clVars.Get('os_install_scratch') == "on":
|
|
listMountPoint = map(lambda x: "builder" if x == "/" else x,
|
|
listMountPoint)
|
|
partData = zip(self.clVars.Get('os_disk_size'),
|
|
self.clVars.Get('os_disk_part'))
|
|
listSize = map(lambda x: "" if x[1]=="extended" else x[0], partData)
|
|
|
|
if self.clVars.Get('os_install_root_type') == 'flash':
|
|
headerList = [_("Size"),_("Device"),_("File system"),
|
|
_("Format"), _("Partition")]
|
|
colnum = 2
|
|
else:
|
|
headerList = [_("Size"),_("Device"),_("Directory"),
|
|
_("File system"),_("Format"), _("Partition")]
|
|
colnum = 3
|
|
dataList = map(lambda x:x[:colnum]+x[3:-1],
|
|
filter(lambda x:x[-1] != "",
|
|
zip(listSize,
|
|
self.clVars.Get('os_disk_dev'),
|
|
listMountPoint,
|
|
listFileSystem,
|
|
listIsFormat,
|
|
map(lambda x:x[0] or x[1],
|
|
zip(self.clVars.Get('os_disk_part'),
|
|
map(self.convertTypeToScheme,
|
|
self.clVars.Get('os_disk_type')))),
|
|
self.clVars.Get('os_install_disk_mount'))))
|
|
return title, headerList, dataList
|
|
|
|
def generateTableBindData(self):
|
|
"""Get bind data for print table"""
|
|
title = _("Bind mounts")
|
|
headerList = [_("Source directory"),_("Mount point")]
|
|
return title, headerList, zip(self.clVars.Get('os_install_bind_path'),
|
|
self.clVars.Get('os_install_bind_mountpoint'))
|
|
|
|
def generateTableNetworkData(self):
|
|
"""Get bind data for print table"""
|
|
def ipInformation(listIpMaskDhcp):
|
|
ipaddr,cidr,dhcp = listIpMaskDhcp
|
|
if dhcp == "on":
|
|
return _("DHCP")
|
|
elif ipaddr:
|
|
return "{ip}/{cidr}".format(ip=ipaddr,cidr=cidr)
|
|
else:
|
|
return _("Off")
|
|
clGet = self.clVars.Get
|
|
title = _("Network devices")
|
|
headerList = [_("Device"),_("Name"),_("MAC address"),_("IP address")]
|
|
return title, headerList, zip(clGet('os_install_net_interfaces'),
|
|
clGet('os_install_net_name'),
|
|
clGet('os_install_net_mac'),
|
|
map(ipInformation,
|
|
zip(clGet('os_install_net_ip'),
|
|
clGet('os_install_net_cidr'),
|
|
clGet('os_install_net_dhcp_set'))))
|
|
|
|
def generateTableRouteData(self):
|
|
"""Get bind data for print table"""
|
|
clGet = self.clVars.Get
|
|
title = _("Routes")
|
|
headerList = [_("Device"),_("Network"),_("Gateway"),_("Source IP")]
|
|
return title, headerList, zip(clGet('os_install_net_route_dev'),
|
|
clGet('os_install_net_route_network'),
|
|
clGet('os_install_net_route_gw'),
|
|
clGet('os_install_net_route_src')) + \
|
|
map(lambda x:(x[0],_("DHCP"),_("DHCP"),_("DHCP")),
|
|
filter(lambda x:x[1]=='on',zip(clGet('os_install_net_interfaces'),
|
|
clGet('os_install_net_dhcp_set'))))
|
|
|
|
def getPwdHashUser(self, userName, stdinRead=False):
|
|
if stdinRead:
|
|
try:
|
|
userPwd = sys.stdin.readline().rstrip()
|
|
except EOFError:
|
|
raise KeyboardInterrupt()
|
|
else:
|
|
try:
|
|
userPwd = self.askPassword(_("Enter the password for user %s")%
|
|
userName)
|
|
while userPwd is False:
|
|
if get_install_errors():
|
|
for line in filter(lambda x:x,
|
|
pop_install_errors().split('\n')):
|
|
self.printERROR(line)
|
|
userPwd = self.askPassword(_("Enter the password for user %s")%
|
|
userName)
|
|
except EOFError:
|
|
raise KeyboardInterrupt()
|
|
encryptObj = encrypt()
|
|
if not userPwd:
|
|
raise InstallError(_("Failed to find the password for user %s")\
|
|
%userName)
|
|
return False
|
|
pwdHash = encryptObj.getHashPasswd(userPwd, "shadow_ssha256")
|
|
if pwdHash is False:
|
|
raise InstallError(_("Password encryption error"))
|
|
return pwdHash
|
|
|
|
def getNamesAddUsers(self):
|
|
"""Get names added users"""
|
|
return map(lambda x: x[0],
|
|
filter(lambda x: x[1]=="yes",\
|
|
zip(self.clVars.Get("cl_migrate_user"),
|
|
self.clVars.Get("cl_migrate_user_pwd"))))
|
|
|
|
def getNamesMigrateUsers(self):
|
|
"""Get names migrated users"""
|
|
return map(lambda x: x[0],
|
|
filter(lambda x: x[1]=="no",\
|
|
zip(self.clVars.Get("cl_migrate_user"),
|
|
self.clVars.Get("cl_migrate_user_pwd"))))
|
|
|
|
def generateHashUsers(self, stdinRead=False):
|
|
"""Generate pwd hash from users"""
|
|
addUsers = self.getNamesAddUsers()
|
|
users = filter(lambda x: x!="root", addUsers)
|
|
listAddUsers = []
|
|
for user in users:
|
|
hashPwd = self.getPwdHashUser(user, stdinRead)
|
|
listAddUsers.append((user, hashPwd))
|
|
return listAddUsers
|
|
|
|
def generateHashRoot(self, stdinRead=False):
|
|
"""Generate pwd hash from root"""
|
|
addUsers = self.getNamesAddUsers()
|
|
if filter(lambda x: x=="root", addUsers):
|
|
hashPwd = self.getPwdHashUser("root", stdinRead)
|
|
return [("root", hashPwd,"","")]
|
|
else:
|
|
return []
|
|
|
|
def printMessageForTest(self, message, lenMsg=False):
|
|
"""Print waiting message and OK or Error by func result"""
|
|
message = "%s ..." % message
|
|
self.printSUCCESS(message,printBR=False)
|
|
self.startMessage = message
|
|
if lenMsg:
|
|
self.lenStartMessage = lenMsg
|
|
else:
|
|
self.lenStartMessage = self.lenString(self.startMessage)
|
|
|
|
def printOnlyNotOK(self, string, offsetL=0, printBR=True):
|
|
"""Вывод на печать в случае сбоя"""
|
|
self._printSysOut = sys.stdout
|
|
self.printLine((('', string),),
|
|
(('blueBr','['),
|
|
('redBr',' !! '),
|
|
('blueBr',']'),
|
|
), offsetL, printBR)
|
|
|
|
def printByResult(self,result,failMessage=None):
|
|
if self.startMessage:
|
|
offset = 3
|
|
if result:
|
|
self.printOnlyOK(" ", self.lenStartMessage + offset)
|
|
else:
|
|
self.printOnlyNotOK(" ", self.lenStartMessage + offset)
|
|
if failMessage:
|
|
self.printERROR(failMessage)
|
|
self.startMessage = ""
|
|
self.lenStartMessage = 0
|
|
|
|
def setupOpenGL(self):
|
|
"""Setup opengl for current video driver"""
|
|
defaultGL = "xorg-x11"
|
|
pathGlModules = path.join(self.clVars.Get('cl_chroot_path'),
|
|
'usr/lib/opengl')
|
|
openGLenv = path.join(self.clVars.Get('cl_chroot_path'),
|
|
'etc/env.d/03opengl')
|
|
|
|
openGlMods = filter(lambda x:x != "global",
|
|
listDirectory(pathGlModules))
|
|
mapGL_drivers = {'fglrx':"ati" if "ati" in openGlMods
|
|
else defaultGL,
|
|
'nvidia':"nvidia" if "nvidia" in openGlMods
|
|
else defaultGL}
|
|
x11_driver = self.clVars.Get('os_install_x11_video_drv')
|
|
if x11_driver in mapGL_drivers:
|
|
newModuleName = mapGL_drivers[x11_driver]
|
|
else:
|
|
newModuleName = defaultGL
|
|
curModuleName = map(lambda x:x.strip().rpartition('=')[-1].strip('"\''),
|
|
filter(lambda x: x.startswith("OPENGL_PROFILE="),
|
|
open(openGLenv,'r')))
|
|
curModuleName = curModuleName[-1] if curModuleName else ""
|
|
if curModuleName == newModuleName:
|
|
return True
|
|
res,errmes = runOsCommand('eselect opengl set %s'%newModuleName)
|
|
if res == 0:
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
def checkVideoDriver(self):
|
|
"""Check video driver and install nvidia driver"""
|
|
binPackages = '/usr/portage/packages'
|
|
nvidiaBinDrivers = path.join(binPackages,'x11-drivers')
|
|
if self.clVars.Get('hr_video') != 'nvidia' or \
|
|
not path.exists(nvidiaBinDrivers):
|
|
return True
|
|
maskFile = '/etc/portage/package.mask'
|
|
nvidiaMaskFile = path.join(maskFile,'nvidia-drivers')
|
|
# convert file package.mask to directory package mask
|
|
if path.isfile(maskFile):
|
|
os.rename(maskFile,maskFile+"2")
|
|
os.mkdir(maskFile,mode=0755)
|
|
os.rename(maskFile+"2",path.join(maskFile,"default"))
|
|
if path.exists(nvidiaMaskFile):
|
|
curNvidiaMask = open(nvidiaMaskFile,'r').read().strip()
|
|
else:
|
|
curNvidiaMask = ""
|
|
|
|
maskNvidia = self.clVars.Get('os_nvidia_mask')
|
|
if maskNvidia == curNvidiaMask:
|
|
return True
|
|
self.printByResult(True)
|
|
self.printMessageForTest(_("Driver installation for %s")%
|
|
self.clVars.Get('hr_video'))
|
|
open(nvidiaMaskFile,'w').write(maskNvidia)
|
|
try:
|
|
envDict = {'PKGDIR':binPackages}
|
|
envDict.update(os.environ)
|
|
processEmerge = process('/usr/bin/emerge','-k','nvidia-drivers',
|
|
envdict=envDict,stdout=PIPE,stderr=PIPE)
|
|
res = processEmerge.success()
|
|
except KeyboardInterrupt:
|
|
self.setSignalInterrupt()
|
|
os.unlink(nvidiaMaskFile)
|
|
return False
|
|
if not res:
|
|
os.unlink(nvidiaMaskFile)
|
|
return res
|
|
|
|
def hideStdout(self):
|
|
if not self.stdoutHide:
|
|
self.stdoutHide = sys.stdout
|
|
self.stderrHide = sys.stderr
|
|
sys.stdout = StringIO()
|
|
sys.stderr = StringIO()
|
|
sys.stdout.fileno = self.stdoutHide.fileno
|
|
sys.stderr.fileno = self.stderrHide.fileno
|
|
|
|
def showStdout(self):
|
|
if self.stdoutHide:
|
|
sys.stdout = self.stdoutHide
|
|
sys.stderr = self.stderrHide
|
|
self.stdoutHide = None
|
|
self.stderrHide = None
|
|
|
|
def configureSystem(self,autologin):
|
|
"""configuring the current system"""
|
|
configureMessage = _("Configure the system")
|
|
error = None
|
|
keyInter = None
|
|
try:
|
|
try:
|
|
if autologin:
|
|
objUsers = currentUsers()
|
|
if not objUsers.hasUsers(autologin):
|
|
self.printERROR(_("User %s does not exist")%autologin)
|
|
else:
|
|
self.setUsers([],autologin)
|
|
# install this package
|
|
self.installPackage()
|
|
self.printMessageForTest(configureMessage)
|
|
self.printByResult(self.applyTemplatesStartup())
|
|
|
|
linuxShortname = self.clVars.Get('os_install_linux_shortname')
|
|
# install desktop package
|
|
if linuxShortname in ("CLD","CLS","CLDG","CLDX"):
|
|
desktopLib = '/usr/lib/calculate-2.2/calculate-desktop/pym'
|
|
if path.exists(desktopLib):
|
|
sys.path.insert(0, path.abspath(desktopLib))
|
|
from cl_desktop import desktop
|
|
self.printMessageForTest(
|
|
_("Enable calculate-desktop "
|
|
"for package configuration"))
|
|
self.hideStdout()
|
|
objDesktop = desktop()
|
|
objDesktop.createClVars()
|
|
res = objDesktop.installProg()
|
|
self.showStdout()
|
|
|
|
# install client package
|
|
if linuxShortname in ("CLD","CLDG","CLDX"):
|
|
clientLib = '/usr/lib/calculate-2.2/calculate-client/pym'
|
|
if path.exists(clientLib):
|
|
sys.path.insert(0, path.abspath(clientLib))
|
|
from cl_client import client
|
|
self.printMessageForTest(
|
|
_("Enable calculate-client for package configuration"))
|
|
objClient = client()
|
|
objClient.createClVars()
|
|
self.hideStdout()
|
|
if hasattr(objClient,"updateEnvFiles") and \
|
|
objClient.updateEnvFiles():
|
|
objClient.clVars.flIniFile()
|
|
res = objClient.installProg()
|
|
self.showStdout()
|
|
self.printByResult(res)
|
|
|
|
pathGlModules = path.join(self.clVars.Get('cl_chroot_path'),
|
|
'usr/lib/opengl')
|
|
self.printMessageForTest(_("Check the video driver"))
|
|
self.printByResult(self.checkVideoDriver())
|
|
if path.exists(pathGlModules):
|
|
self.printMessageForTest(_("Configure OpenGL"))
|
|
self.printByResult(self.setupOpenGL())
|
|
# if change video driver, then restore initramfs
|
|
installDrv = self.clVars.Get('os_install_x11_video_drv')
|
|
if self.clVars.Get('os_x11_video_drv') != installDrv:
|
|
initrdPath = path.join('/boot',
|
|
self.clVars.Get('os_install_initrd'))
|
|
initrdInstallPath = path.join('/boot',
|
|
self.clVars.Get('os_install_initrd_install'))
|
|
needMod = {'radeon':'radeon',
|
|
'intel':'i915',
|
|
'nouveau':'nouveau'}.get(installDrv,'uvesafb')
|
|
if not InitRamFs(initrdPath).isModuleInside(needMod):
|
|
self.printMessageForTest(_("Restoring initramfs"))
|
|
self.printByResult(InitRamFs(initrdInstallPath)\
|
|
.cleanInitRamFs(initrdPath))
|
|
oldXdrv = self.clVars.Get('os_x11_video_drv')
|
|
newXdrv = self.clVars.Get('os_install_x11_video_drv')
|
|
if oldXdrv != newXdrv:
|
|
kmsDrv = ("radeon","i915","intel","nouveau","ati")
|
|
self.defaultPrint("\n")
|
|
if oldXdrv in kmsDrv or newXdrv in kmsDrv:
|
|
self.defaultPrint(
|
|
_("To apply the changes, reboot the system")
|
|
+".\n")
|
|
else:
|
|
self.defaultPrint(
|
|
_("To apply the changes, restart the X server")
|
|
+".\n")
|
|
except (InstallError,DistributiveError),e:
|
|
error = e
|
|
except Exception,e:
|
|
error = ""
|
|
for i in apply(traceback.format_exception, sys.exc_info()):
|
|
error += i
|
|
except KeyboardInterrupt:
|
|
self.setSignalInterrupt()
|
|
keyInter = True
|
|
except KeyboardInterrupt:
|
|
self.setSignalInterrupt()
|
|
keyInter = True
|
|
self.showStdout()
|
|
if keyInter:
|
|
if self.startMessage:
|
|
self.printByResult(False)
|
|
self.defaultPrint("\n")
|
|
self.printWARNING(_("System configuration interrupted"))
|
|
error = _("Configuration manually interrupted")
|
|
if self.startMessage:
|
|
self.printByResult(False)
|
|
if error:
|
|
for line in filter(lambda x: x,str(error).split('\n')):
|
|
self.printERROR(line)
|
|
self.printERROR(_("System configuration failed"))
|
|
return False
|
|
return True
|
|
|
|
def cleanInitrd(self):
|
|
"""Clean initrd from needless modules"""
|
|
# get path to initrd and initrd-install in new system
|
|
# (/boot/initramfs-...-install,/boot/initramfs-...)
|
|
chrootPath = path.join(self.clVars.Get('cl_chroot_path'),'boot')
|
|
initrdPath = path.join(chrootPath,self.clVars.Get('os_install_initrd'))
|
|
initrdInstallPath = path.join(chrootPath,
|
|
self.clVars.Get('os_install_initrd_install'))
|
|
copy2(initrdInstallPath,initrdPath);
|
|
return True
|
|
|
|
def afterCopyHDDinstall(self,targetDistr, addUsers, changePwdUsers,
|
|
migrateUsers):
|
|
"""Action performed after distributive copy for hdd install"""
|
|
# copy clt files from current system
|
|
self.startTask(_("Coping clt templates to the new system"))
|
|
cltCpy = cltCopy(target=targetDistr.getDirectory())
|
|
for directory in self.clVars.Get('cl_template_clt_path'):
|
|
cltCpy.performCopy(directory)
|
|
self.endTask()
|
|
|
|
self.startTask(_("Coping configuration files to the new system"))
|
|
fileMask = r"/etc/udev/rules\.d/70-persistent-net\.rules"
|
|
if self.clVars.Get('os_root_type') != "livecd":
|
|
fileMask = "(%s|/etc/ssh/ssh_host_.*)"%fileMask
|
|
fileCpy = otherfilesCopy(target=targetDistr.getDirectory(),
|
|
reTest=fileMask)
|
|
fileCpy.performCopy('/etc')
|
|
self.endTask()
|
|
|
|
# optimize initrd
|
|
#self.clVars.Set("cl_chroot_path",targetDistr.getDirectory(), True)
|
|
#self.startTask(_("Creating a new initrd file"))
|
|
#self.cleanInitrd()
|
|
#self.endTask("")
|
|
|
|
# join templates
|
|
self.startTask(_("Updating configuration"),progress=True)
|
|
self.applyTemplates(targetDistr.getDirectory(),
|
|
targetDistr.getBootDirectory()[:-4])
|
|
# mount bind mount points
|
|
|
|
self.endTask()
|
|
|
|
self.startTask(_("Post-install configuration"))
|
|
targetDistr.postinstallMountBind()
|
|
self.endTask()
|
|
|
|
# migrate users
|
|
self.startTask(_("Migrate users"))
|
|
objMigrate = migrate(targetDistr.getDirectory())
|
|
if not objMigrate.migrate(self.clVars.Get('cl_migrate_data'),[],[]):
|
|
raise InstallError(_("Failed to migrate users to the new system"))
|
|
self.endTask()
|
|
|
|
def setBR(self, mbrDisks):
|
|
"""Set boot record on disk by param or get from variables"""
|
|
bootDiskGrub = ""
|
|
for mbrDisk in mbrDisks:
|
|
if mbrDisk == "off":
|
|
self.clVars.Set('os_install_mbr',"",force=True)
|
|
return True
|
|
elif mbrDisk:
|
|
if not filter(lambda x: x == mbrDisk,
|
|
self.clVars.Get('os_device_dev')):
|
|
self.errlist.append(InstallError(
|
|
_("Failed to find disk '%s'")%mbrDisk,
|
|
field="mbr"))
|
|
return False
|
|
tableOnBootDisk = self.varSelect('os_device_table',
|
|
where="os_device_dev",eq=mbr)
|
|
if not tableOnBootDisk:
|
|
self.errlist.append(
|
|
_("Disk '%s' without partition table "
|
|
"contains no boot record")%mbrDisk,field="mbr")
|
|
self.clVars.Set('os_install_mbr', mbrDisks, force=True)
|
|
return True
|
|
|
|
def setBuilder(self,builder):
|
|
if builder:
|
|
self.logicObj.clVars.Set('os_install_scratch',"on",True)
|
|
else:
|
|
self.logicObj.clVars.Set('os_install_scratch',"off",True)
|
|
|
|
def setDiskType(self,disktype):
|
|
trueType = FileSystemManager.defaultFS.keys()
|
|
if not disktype in trueType:
|
|
self.errlist.append(
|
|
InstallError(
|
|
_("Disk type should be {head} or {tail}").format(
|
|
head=trueType[:-1],tail=trueType[-1]),
|
|
field="type"))
|
|
return False
|
|
else:
|
|
self.logicObj.clVars.Set('os_install_root_type',disktype,True)
|
|
return True
|
|
|
|
def _convertErrors(self,errlist):
|
|
errors = []
|
|
for err in errlist:
|
|
if err.field:
|
|
errors.append([err.field,str(err)])
|
|
else:
|
|
errors.append(["",str(err)])
|
|
return errors
|
|
|
|
def checkInstallParam(self,disks=None,mbr=None,builder=None,typeDisk=None):
|
|
self.errlist = []
|
|
try:
|
|
if typeDisk:
|
|
self.setDiskType(typeDisk)
|
|
if not builder is None:
|
|
self.setBuilder(builder)
|
|
if disks:
|
|
self.setDisks(disks)
|
|
if mbr:
|
|
self.setBR(mbr)
|
|
except InstallError,e:
|
|
self.errlist.append(e)
|
|
return self._convertErrors(self.errlist)
|
|
|
|
def getCurrentPartitioning(self):
|
|
MOUNTPOINT,DEVICE,MAKEFORMAT,FORMAT,LABLE,SIZE = 0,1,2,3,4,5
|
|
body = filter(lambda x:x[MOUNTPOINT],
|
|
self.clVars.zipVars('os_install_disk_mount',
|
|
'os_disk_dev',
|
|
'os_install_disk_perform_format',
|
|
'os_install_disk_format',
|
|
'os_disk_name',
|
|
'os_disk_size'))
|
|
table = {'head':[_("Partition"),_("Mount point"),
|
|
_("Filesystem"),_("Perform format"),
|
|
_("Label"),_("Size")],
|
|
'body':body}
|
|
return table
|
|
|
|
|
|
def installSystem(self,variables):
|
|
"""install System by current variable enviroment"""
|
|
error = None
|
|
if variables:
|
|
self.clVars = variables
|
|
else:
|
|
self.initVars()
|
|
try:
|
|
results = []
|
|
self.writeFile()
|
|
# Помещение данных в словарь процессов
|
|
self.briefParams('install_view')
|
|
#self.beginFrame()
|
|
targetDistr = None
|
|
sourceDistr = None
|
|
try:
|
|
self.clVars.printVars()
|
|
self.createListOptions()
|
|
rootPartdev = self.clVars.Get('os_install_root_dev')
|
|
rootPartCmdList = filter(lambda x: x['dev']==rootPartdev,
|
|
self.listDisksOptions)
|
|
print self.listDisksOptions
|
|
rootPartCmdDict = rootPartCmdList[0]
|
|
rootPartFileSystem = rootPartCmdDict['fileSystem']
|
|
rootPartIsFormat = rootPartCmdDict['isFormat']
|
|
rootPartSystemId = rootPartCmdDict['systemId']
|
|
builder = self.clVars.Get('os_install_scratch') == 'on'
|
|
|
|
if self.clVars.Get('os_install_root_type') != "flash":
|
|
#self.clVars.Get('os_install_pxe') != 'on':
|
|
changePwdUsers = \
|
|
self.generateHashRoot(stdinRead=False)
|
|
addUsers = self.generateHashUsers(stdinRead=False)
|
|
migrateUsers = self.getNamesMigrateUsers()
|
|
|
|
targetDistr = self.getTargetDistributive(rootPartdev,
|
|
buildermode=builder,
|
|
fileSystem=rootPartFileSystem,
|
|
isFormat=rootPartIsFormat,
|
|
systemId=rootPartSystemId)
|
|
sourceDistr = self.clVars.Get('cl_image')
|
|
# cmd options
|
|
self.startTask(_("Formating partitions"),progress=True)
|
|
targetDistr.performFormat()
|
|
self.endTask()
|
|
# install distributive
|
|
self.startTask(
|
|
_("Unpacking the system image into target"),progress=True)
|
|
self.clVars.Get('os_grub_conf')
|
|
# set spinner flag
|
|
Distributive.flagSpinner = False
|
|
targetDistr.installFrom(sourceDistr,callbackProgress=self.setProgress)
|
|
targetDistr.convertToDirectory()
|
|
self.endTask()
|
|
|
|
if self.clVars.Get('os_install_root_type') != "flash":
|
|
self.afterCopyHDDinstall(targetDistr, addUsers,
|
|
changePwdUsers, migrateUsers)
|
|
else:
|
|
# join templates
|
|
self.startTask(
|
|
_("Configure flash installation"))
|
|
self.applyTemplatesFlash(targetDistr.getDirectory())
|
|
self.endTask()
|
|
self.closeClTemplate()
|
|
# change boot config
|
|
if self.clVars.Get('os_install_mbr'):
|
|
self.startTask(_("Preparing system for reboot"))
|
|
self.prepareBoot(targetDistr)
|
|
self.endTask()
|
|
except EOFError as e:
|
|
error = str(e)
|
|
except (MigrationError,
|
|
TemplatesError,
|
|
InstallError,
|
|
DistributiveError) as e:
|
|
error = str(e)
|
|
except Exception as e:
|
|
error = ""
|
|
for i in apply(traceback.format_exception, sys.exc_info()):
|
|
error += i
|
|
except KeyboardInterrupt,e:
|
|
self.setSignalInterrupt()
|
|
self.printWARNING(_("Installation interrupted"))
|
|
error = _("Installation manually interrupted")
|
|
if error:
|
|
self.printERROR(error)
|
|
try:
|
|
self.closeClTemplate()
|
|
if sourceDistr and sourceDistr.childs:
|
|
self.startTask(_("Releasing the source distribution"))
|
|
sourceDistr.close()
|
|
self.endTask()
|
|
if targetDistr and targetDistr.childs:
|
|
self.startTask(_("Unmount the target system volume"))
|
|
targetDistr.close()
|
|
self.endTask()
|
|
except (TemplatesError,InstallError,DistributiveError),e:
|
|
error = "%s\n%s" % (str(error),_("Unmounting error"))
|
|
self.printERROR(error)
|
|
except KeyboardInterrupt,e:
|
|
self.setSignalInterrupt()
|
|
pass
|
|
if error:
|
|
self.printERROR(_("System installation failed"))
|
|
return False
|
|
self.printSUCCESS(_("System successfully installed"))
|
|
self.endTask("Installation complete!")
|
|
self.endFrame()
|
|
# necessary for correct complete the process
|
|
return True
|
|
except (BaseException),e:
|
|
error = ""
|
|
for i in apply(traceback.format_exception, sys.exc_info()):
|
|
error += i
|
|
self.printERROR(error)
|
|
return False
|
|
finally:
|
|
try:
|
|
self.clVars.close()
|
|
except (BaseException),e:
|
|
error = ""
|
|
for i in apply(traceback.format_exception, sys.exc_info()):
|
|
error += i
|
|
self.printERROR(error)
|
|
return False
|
|
return True
|
|
|
|
def setLinuxName(self,shortname):
|
|
self.clVars.Set('os_install_linux_shortname',shortname,True)
|
|
|
|
def setAllLocaleByLang(self,lang):
|
|
"""Set all locale variable by specified lang"""
|
|
locale = Locale()
|
|
if not lang in self.clVars.Get('os_install_lang'):
|
|
return False
|
|
self.clVars.Set('os_install_locale_lang',lang, True)
|
|
self.clVars.Set('os_install_locale_locale',
|
|
locale.getFieldByLang('locale',lang), True)
|
|
self.clVars.Set('os_install_locale_language',
|
|
locale.getFieldByLang('language',lang), True)
|
|
self.clVars.Set('os_install_locale_keymap',
|
|
locale.getFieldByLang('keymap',lang), True)
|
|
self.clVars.Set('os_install_locale_dumpkeys',
|
|
locale.getFieldByLang('dumpkeys_charset',lang), True)
|
|
self.clVars.Set('os_install_locale_xkb',
|
|
locale.getFieldByLang('xkblayout',lang), True)
|
|
return True
|
|
|
|
def installOverlay(self):
|
|
return True
|
|
#res,mes = runOsCommand('layman -l -N')
|
|
#notempty = lambda x:x
|
|
|
|
#if res == 0:
|
|
#
|
|
# map(lambda x:x[0],
|
|
# filter(lambda x:x,
|
|
# map(lambda x:filter(lambda x:x,x.split())[1:2],
|
|
# mes)))
|
|
# return True
|
|
#else:
|
|
# raise InstallError(_("Cann't get list layman overlays"))
|
|
|
|
def installPackage(self):
|
|
"""Install this package. Convert Gentoo system to Calculate"""
|
|
error = None
|
|
self.printSUCCESS(_("Package installed"))
|
|
try:
|
|
self.printMessageForTest(
|
|
_("Enable calculate-install for package configuration"))
|
|
self.printByResult(appendProgramToEnvFile(__app__, self.clVars),
|
|
failMessage= _("Failed to save '%(app)s' to %(path)s")
|
|
%{'app':__app__,
|
|
'path':self.clVars.Get("cl_env_path")[0]})
|
|
except (InstallError,DistributiveError),e:
|
|
error = e
|
|
except (Exception),e:
|
|
error = ""
|
|
for i in apply(traceback.format_exception, sys.exc_info()):
|
|
error += i
|
|
except KeyboardInterrupt,e:
|
|
self.setSignalInterrupt()
|
|
if self.startMessage:
|
|
self.printByResult(False)
|
|
self.defaultPrint("\n")
|
|
error = _("Package installation interrupted manually")
|
|
if self.startMessage:
|
|
self.printByResult(False)
|
|
if error:
|
|
for line in filter(lambda x: x,str(error).split('\n')):
|
|
self.printERROR(line)
|
|
self.printERROR(_("Failed to install the package"))
|
|
return False
|
|
return True
|
|
|
|
def uninstallPackage(self):
|
|
"""Uninstall this package. Convert Calculate system to Gentoo"""
|
|
error = None
|
|
self.printSUCCESS(_('Package uninstallation'))
|
|
try:
|
|
self.printMessageForTest(
|
|
_("Disable calculate-install for package configuration"))
|
|
self.printByResult(removeProgramToEnvFile(__app__, self.clVars),
|
|
failMessage = _("Failed to remove '%(app)s' to %(path)s")\
|
|
%{'app':__app__,
|
|
'path':self.clVars.Get("cl_env_path")[0]})
|
|
except (InstallError,DistributiveError),e:
|
|
error = e
|
|
except (Exception),e:
|
|
error = ""
|
|
for i in apply(traceback.format_exception, sys.exc_info()):
|
|
error += i
|
|
except KeyboardInterrupt,e:
|
|
self.setSignalInterrupt()
|
|
if self.startMessage:
|
|
self.printByResult(False)
|
|
self.defaultPrint("\n")
|
|
error = _("Package uninstallation interrupted manually")
|
|
if self.startMessage:
|
|
self.printByResult(False)
|
|
if error:
|
|
for line in filter(lambda x: x,str(error).split('\n')):
|
|
self.printERROR(line)
|
|
self.printERROR(_("Package uninstallation failed"))
|
|
return False
|
|
return True
|
|
|
|
def setIso(self,isoimage):
|
|
"""Set iso image for installation"""
|
|
imageData = DistributiveRepository()._getfromcontent(isoimage)
|
|
if "name" in imageData and imageData.get('build','') and \
|
|
"march" in imageData:
|
|
self.clVars.Set('os_install_arch_machine',
|
|
imageData['march'],True)
|
|
self.clVars.Set('os_install_linux_build',
|
|
imageData['build'],True)
|
|
self.clVars.Set('os_install_linux_ver',
|
|
imageData['ver'],True)
|
|
self.setLinuxName(imageData['name'].upper())
|
|
self.clVars.Set('cl_image',isoimage,True)
|
|
return True
|
|
else:
|
|
self.printERROR(_("Wrong image file"))
|
|
return False
|
|
|
|
def setVideo(self,video,startup=False):
|
|
"""Set video driver"""
|
|
if startup:
|
|
if not video in getInstalledVideo(prefix="/") and \
|
|
not video in ("auto","other"):
|
|
self.printERROR(_("%s videodriver is unavailable")%video)
|
|
if video == "nvidia":
|
|
self.printERROR(_("Install %s driver with:")%"NVidia")
|
|
self.printERROR(" emerge x11-drivers/nvidia-drivers")
|
|
if video == "fglrx":
|
|
self.printERROR(_("Install %s driver with:")%"ATI")
|
|
self.printERROR(" emerge x11-drivers/ati-drivers")
|
|
return False
|
|
self.clVars.Set('os_install_x11_video_drv',video,force=True)
|
|
return True
|
|
|
|
def setTimezone(self,timezone):
|
|
"""Set timezone"""
|
|
if not path.exists(path.join("/usr/share/zoneinfo",timezone)) or \
|
|
timezone.startswith('/usr/share/zoneinfo'):
|
|
self.printERROR(_("%s timezone is wrong")%timezone)
|
|
return False
|
|
else:
|
|
self.clVars.Set('os_install_clock_timezone',timezone,force=True)
|
|
return True
|
|
|
|
def setArchitecture(self,march):
|
|
"""Set architecture by march (support auto keyword)"""
|
|
if march == "auto":
|
|
march = getSupportArch()[-1]
|
|
self.clVars.Set('os_install_arch_machine', march, True)
|