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.
915 lines
37 KiB
915 lines
37 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 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 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 setDisks(self):
|
|
"""
|
|
TODO: remove check grub2_path in disk variables
|
|
"""
|
|
try:
|
|
if not self.clVars.Get('os_grub2_path'):
|
|
self.checkForLegacyGrub()
|
|
else:
|
|
self.checkForGrub2()
|
|
except InstallError,e:
|
|
error.append(e)
|
|
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 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.
|
|
"""
|
|
if not self.clVars.Get('os_install_mbr'):
|
|
return
|
|
ddProcess = process("/bin/dd","if=/usr/share/syslinux/mbr.bin",
|
|
"of=%s"%self.clVars.Get('os_install_mbr')[0],
|
|
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 installGrub2Bootloader(self,target):
|
|
"""
|
|
Install grub2 boot loader
|
|
"""
|
|
cmdGrubInstall = self.clVars.Get('os_grub2_path')
|
|
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)
|
|
bootDisk = self.Select('os_install_disk_grub',
|
|
where='os_install_disk_mount',
|
|
_in=('/','/boot'),
|
|
sort='DESC',limit=1)
|
|
if not bootDisk:
|
|
raise DistributiveError(_("Failed to determine boot disk"))
|
|
for mbrDisk in self.clVars.Get('os_install_mbr'):
|
|
mbrDiskNum = self.Select("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 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 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):
|
|
"""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 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()
|
|
if self.Get('cl_autopartition_scheme'):
|
|
raise InstallError(_('Autopartitioning is not supported'))
|
|
targetDistr = self.clVars.Get('cl_target')
|
|
sourceDistr = self.clVars.Get('cl_image')
|
|
# cmd options
|
|
self.startTask(_("Formating partitions"),progress=True)
|
|
targetDistr.performFormat()
|
|
self.endTask()
|
|
# install distributive
|
|
#raise InstallError("Manual stop")
|
|
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)
|
|
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()
|
|
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
|