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

2059 lines
98 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.
__version__ = "2.2.9"
__app__ = "calculate-install"
import os
import re
import sys
import traceback
from os import path
from cl_utils import runOsCommand,appendProgramToEnvFile, \
removeProgramToEnvFile,pathJoin, \
scanDirectory,process,getTupleVersion, \
detectDeviceForPartition,listDirectory
from cl_kernel_utils import KernelConfig,InitRamFs
import cl_overriding
from StringIO import StringIO
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
cl_overriding.exit = installExit
cl_overriding.printERROR = overprintERROR
from cl_lang import lang
from cl_fill import clLocale
from cl_template import template
from cl_datavars import DataVars
from cl_print import color_print
from cl_distr import PartitionDistributive,DistributiveRepository,\
DistributiveError, ScratchPartitionDistributive, \
MultiPartitions, Spinner, FlashDistributive, SignalInterrupt,\
Distributive
from cl_string import tableReport
from time import sleep
from subprocess import PIPE,STDOUT
from server.utils import dialogYesNo
from cl_migrate_users import migrate, currentUsers
from cl_utils import getUserPassword
from encrypt import encrypt
from shutil import copy2
from cl_lang import lang
lang().setLanguage(sys.modules[__name__])
class InstallError(Exception):
"""Installation Error"""
pass
class printNoColor:
def colorPrint(self,attr,fg,bg,string):
sys.stdout.write(string)
class DataVarsInstall(DataVars):
"""Variable class for installation"""
def importInstall(self, **args):
'''Заполнить конфигурацию переменных, для десктопа'''
# Имя секции в calculate.env
envSection = "install"
# заполнить переменные окружения алгоритмом по умолнанию
self.importData(envSection, ('cl_vars_install','cl_fill_install'))
class convertDictOpt:
"""Convert dict install option"""
_defaultFS = "reiserfs"
_defaultFlashFS = "vfat"
_diskDefaultMountPoints = { "default":{"fileSystem":_defaultFS,
"isFormat":False,
"options":["noatime"]},
"/":{"fileSystem":_defaultFS,
"isFormat":True,
"options":["noatime"]},
"none":{"fileSystem":"",
"isFormat":False,
"options":[""]},}
#"/boot":{"fileSystem":"ext2",
# "isFormat":True,
# "options":["noatime"]}}
_bindDefaultMountPoint = {"fileSystem":"none",
"isFormat":False,
"options":["bind"]}
_swapDefaultMountPoint = {"fileSystem":"swap",
"isFormat":False,
"options":["sw"]}
_propertiesFileSystem = {"default": {"fileSystem":_defaultFS,
"isFormat":True,
"options":["noatime"]},
"noformat":{"fileSystem":"",
"isFormat":False,
"options":["noatime"]},
"defaultflash":{"fileSystem":_defaultFlashFS,
"isFormat":True,
"options":["noatime"]}}
_ext2Options = {"options":["acl", "noacl", "bsddf", "minixdf", "check",
"debug", "errors", "grpid", "bsdgroups",
"nogrpid", "sysvgroups", "grpquota", "noquota",
"quota", "usrquota","nobh", "nouid32",
"oldalloc", "orlov", "resgid","resuid", "sb",
"user_xattr", "nouser_xattr"],
"pair":{"check":{"options":["none", "nocheck"],
"incompatible":["none", "nocheck"]},
"errors":{"options":["continue", "remount-ro",
"panic"],
"incompatible":["continue","remount-ro",
"panic"]},
"resgid":{"options":re.compile("\d+"),
"incompatible":[]},
"resuid":{"options":re.compile("\d+"),
"incompatible":[]},
"sb":{"options":re.compile("\d+"),
"incompatible":[]}},
"incompatible":[["acl","noacl"],
["bsddf", "minixdf"],
["grpid","bsdgroups"],
["grpid","nogrpid"],
["bsdgroups","sysvgroups"],
["nogrpid","sysvgroups"],
["grpquota","noquota","quota",
"usrquota"],
["oldalloc","orlov"],
["user_xattr","nouser_xattr"]],
"makefs":"/sbin/mkfs.ext2"}
_ext3Options = _ext2Options.copy()
_ext3Options.update({"makefs":"/sbin/mkfs.ext3"})
_ext3Options["options"] += ["journal", "noload", "data", "barrier",
"commit", "data_err"]
_ext3Options["pair"].update({"journal":{"options":["update", "inum"],
"incompatible":["update", "inum"]},
"data":{"options":["journal", "ordered",
"writeback"],
"incompatible":["journal", "ordered",
"writeback"]},
"data_err":{"options":["abort", "ordered",
"ignore"],
"incompatible":["abort", "ordered",
"ignore"]},
"barrier":{"options":["0","1"],
"incompatible":["0","1"]},
"commit":{"options":re.compile("\d+"),
"incompatible":[]}})
_fileSystemOpt = {"_all":{"options":["async", "atime", "noatime", "auto",
"noauto", "defaults", "dev", "nodev",
"diratime", "nodiratime", "dirsync",
"exec", "noexec", "group", "iversion",
"noiversion", "mand", "nomand",
"_netdev", "nofail", "relatime",
"norelatime", "strictatime",
"nostrictatime", "suid", "nosuid",
"owner", "remount", "ro", "rw", "sync",
"user", "nouser", "users"],
"pair": {},
"incompatible":[["sync", "async"],
["atime", "noatime"],
["auto", "noauto"],
["dev", "nodev"],
["diratime", "nodiratime"],
["exec", "noexec"],
["iversion", "noiversion"],
["mand", "nomand"],
["relatime", "norelatime"],
["strictatime", "nostrictatime"],
["suid", "nosuid"],
["ro", "rw"],
["user", "nouser"]]},
"ext2":_ext2Options,
"ext3":_ext3Options,
"ext4":{"options":["journal_dev", "noload", "data",
"commit", "orlov", "oldalloc",
"user_xattr", "nouser_xattr", "acl",
"noacl", "bsddf", "minixdf", "debug",
"errors", "data_err", "grpid",
"bsdgroups", "nogrpid", "sysvgroups",
"resgid", "resuid", "sb", "quota",
"noquota", "grpquota", "usrquota",
"bh", "nobh", "journal_checksum",
"journal_async_commit", "journal",
"barrier", "nobarrier",
"inode_readahead", "stripe",
"delalloc", "nodelalloc",
"max_batch_time", "journal_ioprio",
"auto_da_alloc", "noauto_da_alloc"],
"pair": {"journal_dev":{\
"options":re.compile(".+"),
"incompatible":[]},
"data":{"options":["journal", "ordered",
"writeback"],
"incompatible":["journal",
"ordered",
"writeback"]},
"commit":{"options":re.compile("\d+"),
"incompatible":[]},
"errors":{"options":["continue",
"remount-ro",
"panic"],
"incompatible":["continue",
"remount-ro",
"panic"]},
"data_err":{"options":["abort",
"ordered",
"ignore"],
"incompatible":["abort",
"ordered",
"ignore"]},
"resgid":{"options":re.compile("\d+"),
"incompatible":[]},
"resuid":{"options":re.compile("\d+"),
"incompatible":[]},
"sb":{"options":re.compile("\d+"),
"incompatible":[]},
"journal":{"options":["update"],
"incompatible":[]},
"inode_readahead":{"options":\
re.compile("\d+"),
"incompatible":[]},
"stripe":{"options":re.compile("\d+"),
"incompatible":[]},
"max_batch_time":{"options":\
re.compile("\d+"),
"incompatible":[]},
"journal_ioprio":{"options":\
re.compile("[1-7]"),
"incompatible":[]}},
"incompatible":[["oldalloc", "orlov"],
["user_xattr","nouser_xattr"],
["acl", "noacl"],
["bsddf", "minixdf"],
["grpid","bsdgroups"],
["grpid","nogrpid"],
["bsdgroups","sysvgroups"],
["nogrpid","sysvgroups"],
["grpquota","noquota","quota",
"usrquota"],
["bh","nobh"],
["delalloc", "nodelalloc"],
["auto_da_alloc",
"noauto_da_alloc"]],
"makefs":"/sbin/mkfs.ext4"},
"reiserfs":{"options":["conv","hash","hashed_relocation",
"no_unhashed_relocation",
"noborder", "nolog", "notail",
"replayonly", "resize",
"user_xattr", "acl"],
"pair":{"hash":{"options":["rupasov", "tea",
"r5", "detect"],
"incompatible":["rupasov",
"tea",
"r5",
"detect"]},
"resize":{"options":re.compile("\d+"),
"incompatible":[]}},
"incompatible":[],
"makefs":"/sbin/mkfs.reiserfs"},
"vfat":{"options":["uni_xlate","posix","nonumtail",
"utf8","shortname"],
"pair":{"shortname":{"options":
re.compile("lower|win95|winnt|mixed"),
"incompatible":[]},
"utf8":{"options":
re.compile("0|1|no|false|true|yes"),
"incompatible":["uni_xlate"]}},
"incompatible":[],
"makefs":"/usr/sbin/mkfs.vfat"},
"ntfs":{"options":["uni_xlate","posix","nls",
"utf8","iocharset",
"uid","gid","umask"],
"pair":{"utf8":{"options":
re.compile("0|1|no|false|true|yes"),
"incompatible":["uni_xlate"]},
"iocharset":{"options":re.compile(".+"),
"incompatible":["nls"]},
"uni_xlate":{"options":
re.compile("0|1|2"),
"incompatible":[]},
"posix":{"options":
re.compile("0|1"),
"incompatible":[]},
"uid":{"options":re.compile(".+"),
"incompatible":[]},
"gid":{"options":re.compile(".+"),
"incompatible":[]},
"umask":{"options":re.compile(".+"),
"incompatible":[]},
},
"incompatible":[],
"makefs":"/usr/sbin/mkfs.ntfs"},
"ntfs-3g":{"options":["uid","gid","umask","fmask",
"dmask","usermapping",
"default_permissions",
"inherit","locale",
"force","remove_hiberfile",
"show_sys_files","allow_other",
"max_read","silent","no_def_opts",
"streams_interface","user_xattr",
"efs_raw","debug","no_detach"],
"pair":{"uid":{"options":re.compile(".+"),
"incompatible":[]},
"gid":{"options":re.compile(".+"),
"incompatible":[]},
"umask":{"options":re.compile(".+"),
"incompatible":[]},
"fmask":{"options":re.compile(".+"),
"incompatible":[]},
"dmask":{"options":re.compile(".+"),
"incompatible":[]},
"usermapping":{"options":re.compile(".+"),
"incompatible":[]},
"default_permissions":{
"options":re.compile(".+"),
"incompatible":[]},
"locale":{"options":re.compile(".+"),
"incompatible":[]},
"max_read":{"options":re.compile(".+"),
"incompatible":[]},
"streams_interface":{
"options":re.compile(".+"),
"incompatible":[]}},
"incompatible":[],
"makefs":"/usr/sbin/mkfs.ntfs"},
"xfs":{"options":["allocsize", "attr2", "noattr2",
"barrier", "dmapi", "grpid",
"bsdgroups", "nogrpid", "sysvgroups",
"ihashsize", "ikeep", "noikeep",
"inode64", "largeio","nolargeio",
"logbufs", "logbsize", "logdev",
"rtdev", "mtpt", "noalign", "noatime",
"norecovery", "nouuid", "osyncisosync",
"uquota", "usrquota", "uqnoenforce",
"quota", "pquota", "prjquota",
"pqnoenforce", "sunit", "swidth",
"swalloc"],
"pair":{"allocsize":{"options":re.compile("\d+"),
"incompatible":[]},
"ihashsize":{"options":re.compile("\d+"),
"incompatible":[]},
"logbufs":{"options":re.compile("\d+"),
"incompatible":[]},
"logbsize":{"options":re.compile("\d+"),
"incompatible":[]},
"logdev":{"options":re.compile(".+"),
"incompatible":[]},
"rtdev":{"options":re.compile(".+"),
"incompatible":[]},
"mtpt":{"options":re.compile(".+"),
"incompatible":[]},
"sunit":{"options":re.compile("\d+"),
"incompatible":[]},
"swidth":{"options":re.compile("\d+"),
"incompatible":[]}},
"incompatible":[["attr2", "noattr2"],
["grpid", "bsdgroups"],
["grpid", "nogrpid"],
["bsdgroups", "sysvgroups"],
["nogrpid", "sysvgroups"],
["ikeep", "noikeep"],
["largeio","nolargeio"],
["uquota", "usrquota",
"uqnoenforce", "quota"],
["pquota", "prjquota",
"pqnoenforce"]],
"makefs":"/sbin/mkfs.xfs"}}
listFileSystemCorrupted = []
def __init__(self, clVars):
self.clVars = clVars
self.varDiskData = self._zipVars('os_disk_dev', 'os_disk_format',
'os_disk_mount', 'os_disk_options',
'os_disk_part', 'os_disk_size')
def addFileSystemCorrupted(self, fileSystem):
"""Add file system with error"""
if not fileSystem in self.listFileSystemCorrupted:
self.listFileSystemCorrupted.append(fileSystem)
def getAllSupportFileSystemOpt(self):
"""Get list all file system"""
return filter(lambda x: not x.startswith("_"),
self._fileSystemOpt.keys()) +\
self._propertiesFileSystem.keys()
def getAllAvailableFileSystemOpt(self):
return filter(lambda x: x in ("default","noformat","defaultflash") or
(not "makefs" in self._fileSystemOpt[x] or
path.exists(self._fileSystemOpt[x]["makefs"])),
self.getAllSupportFileSystemOpt())
def _getFileSystemData(self, realFileSystem):
"""Get data in _fileSystemOpt"""
return self._fileSystemOpt.get(realFileSystem)
def _getFileSystemAllOpt(self, realFileSystem):
"""Get all options from file system"""
data = self._getFileSystemData(realFileSystem)
if data:
return list(set(data["options"])|\
set(self._fileSystemOpt["_all"]["options"]))
else:
return []
def _checkExistsOptions(self, realFileSystem, realOptions):
"""Check exists options"""
allOptions = self._getFileSystemAllOpt(realFileSystem)
if not allOptions:
raise InstallError(_("Unsupported file system %s")%realFileSystem)
for opt in realOptions:
if opt and not opt in allOptions:
self.addFileSystemCorrupted(realFileSystem)
raise InstallError(_("Incorrect option %s")%opt)
def _checkFileSystemIncompatibleOpt(self, realFileSystem, realOptions):
"""Check incompatible options from realOptions"""
# detect duplicate options
dupOptions = filter(lambda x: realOptions.count(x)>1, set(realOptions))
if dupOptions:
raise InstallError(_("Duplicate options %s")%", ".join(dupOptions))
realOptions = map(lambda x: x.split("=")[0], realOptions)
self._checkExistsOptions(realFileSystem, realOptions)
data = self._getFileSystemData(realFileSystem)
if data:
defIncompatibleOpt = self._fileSystemOpt["_all"]["incompatible"]
defIncompatibleOpt = map(lambda x: map(lambda y: y, x),
defIncompatibleOpt)
listDefIncompatibleOpt = reduce(lambda x,y: x+y,
defIncompatibleOpt, [])
incompatibleOpt = data["incompatible"]
for listOpt in incompatibleOpt:
for opt in listOpt:
if opt in listDefIncompatibleOpt:
defIncompatibleOpt = filter(lambda x: not opt in x,
defIncompatibleOpt)
incompatibleOpt = defIncompatibleOpt + incompatibleOpt
listIncompatibleOpt = reduce(lambda x,y: x+y, incompatibleOpt, [])
for option in realOptions:
if option in listIncompatibleOpt:
dataOpt = filter(lambda x: option in x, incompatibleOpt)
if dataOpt:
listOpt = filter(lambda x: x!=option, dataOpt[0])
twoOptList = list(set(listOpt)&set(realOptions))
if twoOptList:
self.addFileSystemCorrupted(realFileSystem)
raise InstallError(_("Incompatible options") + ":"+\
" " + option + " " + _("and") +\
" " + ",".join(twoOptList))
def _checkPairOpt(self, realFileSystem, realOptions):
"""Check options from realOptions (option=value)"""
# detect duplicate options
dupOptions = filter(lambda x: realOptions.count(x)>1, set(realOptions))
if dupOptions:
raise InstallError(_("Duplicate options %s")%", ".join(dupOptions))
splOptions = map(lambda x: x.split("=")[0], realOptions)
self._checkExistsOptions(realFileSystem, splOptions)
dictOpt = {}
notPairOpt = []
for opt in realOptions:
dataOpt = opt.split("=")
if len(dataOpt)==2:
nameOpt, valueOpt = dataOpt
if not nameOpt in dictOpt:
dictOpt[nameOpt] = []
dictOpt[nameOpt].append(valueOpt)
elif len(dataOpt)>2:
self.addFileSystemCorrupted(realFileSystem)
raise InstallError(_("Incorrect option %s")%opt)
else:
notPairOpt.append(opt)
data = self._getFileSystemData(realFileSystem)
if data:
pairData = {}
pairData.update(self._fileSystemOpt["_all"]["pair"])
pairData.update(data["pair"])
allPairOpt = pairData.keys()
wrongOpt = list(set(allPairOpt)&set(notPairOpt))
if wrongOpt:
self.addFileSystemCorrupted(realFileSystem)
raise InstallError(_("Incorrect options %s")\
%", ".join(wrongOpt))
for nameOpt in dictOpt.keys():
if not nameOpt in allPairOpt:
self.addFileSystemCorrupted(realFileSystem)
raise InstallError(_("Incorrect option %s")\
%"%s=%s"%(nameOpt,valueOpt))
checkValues = pairData[nameOpt]
checkValuesOpt = checkValues["options"]
# check options
listValues = dictOpt[nameOpt]
if type(checkValuesOpt)!=list:
if len(listValues)>1:
wrongOpt = ",".join(map(lambda x: "%s=%s"%(nameOpt,x),
listValues))
self.addFileSystemCorrupted(realFileSystem)
raise InstallError(_("Incorrect option %s")\
%wrongOpt)
if not checkValuesOpt.search(listValues[0]):
self.addFileSystemCorrupted(realFileSystem)
raise InstallError(_("Incorrect option %s")\
%"%s=%s"%(nameOpt,listValues[0]))
else:
wrongValues = list(set(listValues)-set(checkValuesOpt))
if wrongValues:
wrongOpt = ",".join(map(lambda x: "%s=%s"%(nameOpt,x),
wrongValues))
self.addFileSystemCorrupted(realFileSystem)
raise InstallError(_("Incorrect option %s")\
%wrongOpt)
checkValuesIncompOpt = checkValues["incompatible"]
if checkValuesIncompOpt:
incompValues = list(set(listValues)&\
set(checkValuesIncompOpt))
if len(incompValues)>1:
wrongOpt = map(lambda x: "%s=%s"%(nameOpt,x),
incompValues)
self.addFileSystemCorrupted(realFileSystem)
raise InstallError(_("Incompatible options") + ":"+\
" " + wrongOpt[0] + " " + \
_("and") + " " +\
",".join(wrongOpt[1:]))
def _zipVars(self, *argvVarNames):
"""Get zip() the value of the variable name"""
return zip(*map(self.clVars.Get, argvVarNames))
def getDefaultOptFileSystem(self, fileSystem, devicetype="hdd"):
"""Get default properties for fileSystem"""
if not fileSystem in self._propertiesFileSystem:
fileSystem="default"
if devicetype == "flash" and fileSystem=="default":
fileSystem="defaultflash"
if devicetype != "flash" and fileSystem=="defaultflash":
fileSystem="default"
propertiesFileSystem = self._propertiesFileSystem.copy()
return propertiesFileSystem[fileSystem]
def getDefaultOptMountPoint(self, mountPoint):
"""Get default properties for mount point disk"""
if not mountPoint in self._diskDefaultMountPoints:
if mountPoint.startswith('/'):
mountPoint = "default"
else:
raise InstallError(_("Incorrect mount point %s")%mountPoint)
propertiesMountPoints = self._diskDefaultMountPoints.copy()
return propertiesMountPoints[mountPoint]
def getDefaultOptSwap(self):
"""Get default properties for swap"""
return self._swapDefaultMountPoint
def getDefaultOptBind(self):
"""Get default properties for swap"""
return self._bindDefaultMountPoint
def _getDeviceType(self,dev):
"""Get device type, considing given by user param"""
oldRootDev = self.clVars.Get('os_install_root_dev')
self.clVars.Set('os_install_root_dev',dev,True)
rootType = self.clVars.Get('os_install_root_type')
self.clVars.Set('os_install_root_dev',oldRootDev,True)
return rootType
def __call__(self, optionsDict={}):
"""Convert dict options (bind options, swap options or disk options)"""
optProperties = optionsDict.copy()
# bind options
if "srcMountPoint" in optProperties:
# bind options
dictOptions = self.getDefaultOptBind().copy()
dictOptions.update(optProperties)
return dictOptions
optDevice = optProperties["dev"]
dataPart = filter(lambda x: x[0]==optDevice, self.varDiskData)
if not dataPart:
dataPart = [["",False,"","","",""]]
dev, format, mount, options, part, size = dataPart[0]
dictUpdateProperty = {}
if "mountPoint" in optProperties:
# Disk options
dictOptions = {}
optFileSystem = optProperties["fileSystem"]
if optProperties["mountPoint"]:
optMountPoint = path.normpath(optProperties["mountPoint"])
else:
optMountPoint = optProperties["mountPoint"]
# if specified mount point empty of default - it is /
if not optMountPoint or optMountPoint=="default":
optMountPoint = "/"
dictUpdateProperty["mountPoint"] = optMountPoint
supportedFS = self.getAllSupportFileSystemOpt()
reRootDirectories = re.compile("^/[^/]*/?$",re.S)
if reRootDirectories.match(path.normpath(optMountPoint)):
# check install type (flash or hdd)
if self._getDeviceType(dev) != "flash":
excludeFS = set(["vfat","ntfs","ntfs-3g"])
else:
excludeFS = set(supportedFS) - \
set(["vfat","noformat","default"])
else:
excludeFS = set([])
availableFS = self.getAllAvailableFileSystemOpt()
# if fs not specified and current fs not supported
if not optFileSystem:
if not (format and format in set(supportedFS)-excludeFS):
optFileSystem = "default"
else:
dictUpdateProperty["fileSystem"] = format
# if specified fs
if optFileSystem:
# if specified wrong fs
if not optFileSystem in supportedFS:
raise InstallError(_("Wrong file system options '%s'")\
%optFileSystem)
if not optFileSystem in availableFS:
raise InstallError(_("File system '%s' is not available")\
%optFileSystem)
if optFileSystem in excludeFS:
mp = optMountPoint
if reRootDirectories.match(path.normpath(mp)) \
and self._getDeviceType(dev) == "flash":
mp = "flash"
raise InstallError(
_("File system for '%(mp)s' should not be '%(opt)s'")
%{'mp':mp, 'opt':optFileSystem})
if not "fileSystem" in dictOptions or optFileSystem == "default":
dictOptions.update(
self.getDefaultOptFileSystem(optFileSystem,
self._getDeviceType(dev)))
if optFileSystem == "noformat":
if not format:
raise InstallError(\
_("Partition %s is not formatted")%dev)
elif format in excludeFS:
mp = optMountPoint
if reRootDirectories.match(path.normpath(mp)) \
and self._getDeviceType(dev) == "flash":
mp = "flash"
raise InstallError(\
_("File system for '%(mp)s' should not be '%(format)s'")\
%{'mp':mp,'format':format})
if not options:
options = ["noatime"]
dictOptions["fileSystem"] = format
dictOptions["options"] = []
if optFileSystem in self._propertiesFileSystem:
dictUpdateProperty["fileSystem"] = dictOptions["fileSystem"]
optOptions = optProperties["options"]
flagCheckOptOptions = True
if optOptions:
if optMountPoint != "/":
dictUpdateProperty["options"] = optOptions
else:
flagCheckOptOptions = True
optProperties = dict(filter(lambda x: x[1], optProperties.items()))
optProperties.update(dictUpdateProperty)
if dictOptions:
dictDefault = dictOptions.copy()
else:
dictDefault = self.getDefaultOptMountPoint(optMountPoint).copy()
dictDefault.update(optProperties)
if flagCheckOptOptions:
# Check mount options
self._checkFileSystemIncompatibleOpt(dictDefault["fileSystem"],
dictDefault["options"])
self._checkPairOpt(dictDefault["fileSystem"],
dictDefault["options"])
return dictDefault
else:
# Swap options
dictOptions = {}
optFileSystem = "swap"
if optFileSystem != format:
dictUpdateProperty["isFormat"] = True
dictOptions = self.getDefaultOptSwap().copy()
dictOptions.update(optProperties)
dictOptions.update(dictUpdateProperty)
return dictOptions
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(_("Can not 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(_("Can not copy '%(src)s' to '%(dst)s'")%
{'src':pathname,'dst':pathJoin(self.target,pathname)})
return True
class cl_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)
def setNoColor(self):
self.color = False
def initVars(self):
"""Primary initialization of variables"""
self.clVars = DataVarsInstall()
self.clVars.importInstall()
self.clVars.flIniFile()
def applyTemplatesLive(self):
"""Apply templates for root of system."""
#self.clVars.Set("cl_root_path","/", True)
self.clVars.Set("cl_chroot_path","/", True)
self.clTempl = template(self.clVars,cltFilter=False)
dirsFiles = self.clTempl.applyTemplates()
if self.clTempl.getError():
self.printERROR(self.clTempl.getError())
return False
else:
return dirsFiles
def printInfo(self):
self.printSUCCESS(_("Installation") + " Calculate Linux")
self.defaultPrint("%s\n"%_("System information"))
self.printSUCCESS(_("Computer name")+": %s"%
self.clVars.Get('os_install_net_hostname'))
self.printSUCCESS(_("Domain name")+": %s"%
self.clVars.Get('os_install_net_domain'))
self.printSUCCESS(_("Network devices")+": %s"%
self.clVars.Get("os_net_interfaces_info"))
self.printSUCCESS(_("Installed system")+": %s %s"%
(self.clVars.Get('os_linux_name'),
self.clVars.Get('os_linux_ver')))
self.defaultPrint("%s\n"%_("Hardware"))
self.printSUCCESS(_("Machine hardware name")+": %s"%
self.clVars.Get('os_install_arch_machine'))
self.printSUCCESS(_("Quantity processors")+": %s"%
self.clVars.Get('hr_cpu_num'))
self.printSUCCESS(_("Videocard vendor")+": %s"%
self.clVars.Get('hr_video'))
self.printSUCCESS(_("Screen resolution")+": %s"%
self.clVars.Get('os_install_x11_resolution'))
self.defaultPrint("%s\n"%_("Localization"))
self.printSUCCESS(_("Language")+": %s"%
self.clVars.Get('os_install_locale_lang'))
self.printSUCCESS(_("Keymap")+": %s"%
self.clVars.Get('os_install_locale_xkbname'))
self.printSUCCESS(_("Timezone")+": %s"%
self.clVars.Get('os_install_clock_timezone'))
self.defaultPrint("%s\n"%_("Location"))
mbrDevice = self.clVars.Get('os_install_mbr')
addonMbrInfo = ""
if not mbrDevice in ("","off"):
pathVendor = "/sys/block/%s/device/vendor"%mbrDevice
pathModel = "/sys/block/%s/device/model"%mbrDevice
if path.exists(pathVendor) and path.exists(pathModel):
addonMbrInfo = " (%s %s)"% \
(open(pathVendor,'r').read().strip(),
open(pathModel,'r').read().strip())
self.printSUCCESS(_("Master boot record")+" (MBR): /dev/%s%s"%
(self.clVars.Get('os_install_mbr'),addonMbrInfo))
else:
self.printSUCCESS(_("Master boot record")+
" (MBR): %s"%_("not changed"))
title, headerList, dataList = self.generateTableData()
tableObj = tableReport("", headerList, dataList)
tableObj.printReport(False)
title, headerList, dataList = self.generateTableBindData()
if dataList:
tableObj = tableReport(title, headerList, dataList)
tableObj.printReport(False)
self.defaultPrint("%s\n"%_("Network services"))
#self.printSUCCESS(_("Authentification")+": %s"%
# "<needed>")
self.printSUCCESS(_("PROXY")+": %s"%
(self.clVars.Get('os_install_proxy') or _("none")))
self.printSUCCESS(_("NTP")+": %s"%
(self.clVars.Get('os_install_ntp') or _("none")))
self.defaultPrint("%s\n"%_("Perform pre-install 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 self.clVars.Get('cl_image'):
self.printSUCCESS(_("Found update")+": %s %s%s%s\n"%
(self.clVars.Get('os_install_linux_name'),
self.clVars.Get('os_install_linux_ver'),
subname,build))
else:
self.printWARNING(_("No update available."))
def prepareBoot(self,targetDistr):
"""Prepare system for boot"""
if self.clVars.Get('os_install_root_type') == "flash":
self.installSyslinuxBootloader(targetDistr)
else:
self.installGrubBootloader(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'))
mapDevice = self.clVars.Get('os_device_hash')
mapPartPT = dict(
map(lambda x:[x,mapDevice.get(detectDeviceForPartition(x),
{'table':None})['table']],
self.clVars.Get('os_disk_dev')))
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 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_root_path",directory, True)
self.clTempl = template(self.clVars,cltObj=False)
dirsFiles = self.clTempl.applyTemplates()
if self.clTempl.getError():
raise InstallError(self.clTempl.getError())
else:
return dirsFiles
def applyTemplates(self,directory):
"""Apply templates for root of system."""
#self.clVars.Set("cl_root_path",directory, True)
self.clVars.Set("cl_chroot_path",directory, 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 = template(self.clVars,cltFilter=False)
dirsFiles = self.clTempl.applyTemplates()
if self.clTempl.getError():
raise InstallError(self.clTempl.getError())
else:
return dirsFiles
def setDisks(self,listDisks,listBinds,listSwaps):
"""Set data for installation partitions"""
convObj = convertDictOpt(self.clVars)
try:
listDisks = map(convObj, listDisks)
# detect previous system if not specified root partition
if not filter(lambda x: x['mountPoint'] == '/',listDisks):
prevRootDev = self.clVars.Get('os_install_dev_from')
if prevRootDev:
listDisks += map(convObj, [{'mountPoint': '',
'options': ['noatime'],
'dev': prevRootDev,
'fileSystem': ''}])
listBinds = map(convObj, listBinds)
listSwaps = map(convObj, listSwaps)
except InstallError,e:
self.printERROR(str(e))
if convObj.listFileSystemCorrupted:
self.printWARNING(_("See 'man mount' for file system") + " "+\
", ".join(convObj.listFileSystemCorrupted))
return False
# break perform if disk params empty and os_install_dev_from empty
if not (listDisks or listSwaps or listBinds):
return True
usedDevicesOnlyDisks = map(lambda x:x['dev'],listDisks)
usedDevicesOnlySwap = map(lambda x:x['dev'],listSwaps)
usedDevices = map(lambda x:x['dev'],listSwaps)+usedDevicesOnlyDisks
usedMP = map(lambda x:x['mountPoint'],listDisks) + \
map(lambda x:x['destMountPoint'],listBinds)
# check mount options for scratch and flash
if filter(lambda x: x != '/', usedMP):
if self.clVars.Get('os_install_scratch') == "on":
self.printERROR(
_("Builder mode is not support multipartition"))
return False
# check specified devices
wrongDevices = list(set(usedDevicesOnlyDisks) - \
set(self.clVars.Get('os_disk_dev')))
wrongDevices = wrongDevices + list(set(usedDevicesOnlySwap) - \
set(self.clVars.Get('os_disk_dev')+["none"]))
if wrongDevices:
self.printERROR(_("Incorrect device '%s'")%wrongDevices[0])
return False
# detect using extended partition
extendedPartitions = map(lambda x: x[1],
filter(lambda x: x[0]=="extended",
zip(self.clVars.Get('os_disk_part'),
self.clVars.Get('os_disk_dev'))))
usingExtPart = list(set(usedDevices)&set(extendedPartitions))
if usingExtPart:
self.printERROR(_("Can not use extended partition %s")%
usingExtPart[0])
return False
srcMountPoints = map(lambda x:x['srcMountPoint'],listBinds)
destMountPoints = map(lambda x:x['destMountPoint'],listBinds)
wrongBind = filter(lambda x:x in destMountPoints,srcMountPoints)
if wrongBind:
incompBind = filter(lambda x:x[1]==wrongBind[0],
zip(srcMountPoints,destMountPoints))
self.printERROR(_("Source directory %(src)s already use "\
"for bind '%(bindSrc)s' to '%(bindDst)s'")\
%{'src':wrongBind[0],
'bindSrc':incompBind[0][0],
'bindDst':incompBind[0][1]})
return False
# Check bind params
wrongBind = filter(lambda x:not x[0].startswith("/") or
not x[1].startswith("/") and
x[1] != "none",
zip(srcMountPoints,destMountPoints))
if wrongBind:
self.printERROR(_("Incorrect mount point (bind '%(bindSrc)s' to "\
"'%(bindDst)s')")\
%{'bindSrc':wrongBind[0][0],
'bindDst':wrongBind[0][1]})
return False
# Check '/' in start path
wrongMP = filter(lambda x: not x.startswith("/") and x!="none",
usedMP) + \
filter(lambda x: not x.startswith("/"),
map(lambda x:x['srcMountPoint'],listBinds))
if wrongMP:
self.printERROR(_("Incorrect mount point '%s'")%wrongMP[0])
return False
# detect duplicate devices
dupDevices = list(set(filter(lambda x:usedDevices.count(x)>1,
usedDevices)))
if dupDevices:
self.printERROR(_("Device '%s' is used twice")%dupDevices[0])
return False
# detect duplicate mount points
dupMP = list(set(filter(lambda x:usedMP.count(x)>1 and x != "none",
usedMP)))
if dupMP:
self.printERROR(_("Mount point '%s' is used twice")%dupMP[0])
return False
def clearParam(data,isswap):
if builderMode:
if len(listSwaps) == 0 and isswap == "swap":
return data
else:
if len(listSwaps) == 0 or isswap != "swap":
return data
return ""
builderMode = self.clVars.Get('os_install_scratch') == "on"
clearBuilder = lambda data,isswap: "" if builderMode and isswap != "swap" else data
# get hash from current variables
devMount = dict(map(lambda x:(x[0],
{'mountPoint':clearParam(x[1],x[1]),
'fileSystem':x[2],
'options':clearParam(x[3],x[1]),
'isFormat':""}),
zip(self.clVars.Get('os_disk_dev'),
self.clVars.Get('os_install_disk_mount'),
self.clVars.Get('os_install_disk_format'),
self.clVars.Get('os_install_disk_options'))))
curDevMount = dict(zip(self.clVars.Get('os_disk_dev'),
self.clVars.Get('os_disk_mount')))
dictMountDev = dict(zip(self.clVars.Get('os_install_disk_mount'),
self.clVars.Get('os_disk_dev')))
# update current variable by cmd params
for diskData in listDisks+listSwaps:
dev = diskData['dev']
# skip none swap device
if dev == "none":
continue
mountPoint = diskData.get('mountPoint','swap')
isFormat = diskData['isFormat']
if mountPoint == "none":
mountPoint = ""
curMP = curDevMount[dev]
if curMP and ( curMP != mountPoint and isFormat or curMP == '/' ):
self.printERROR(_("Specified disk '%s' mounted to")\
%dev + " " + _("'%s' in current system")\
%curMP)
return False
else:
if mountPoint and mountPoint in dictMountDev and \
mountPoint != "swap":
devMount[dictMountDev[mountPoint]]['mountPoint'] = ''
devMount[dev]['mountPoint'] = mountPoint
devMount[dev]['options'] = ",".join(diskData['options'])
devMount[dev]['fileSystem'] = diskData['fileSystem']
if isFormat:
devMount[dev]['isFormat'] = "yes"
if builderMode:
bindDestSrc = {}
bindSrcDest = {}
else:
bindDestSrc =dict(zip(self.clVars.Get('os_install_bind_mountpoint'),
self.clVars.Get('os_install_bind_path')))
bindSrcDest = dict(zip(self.clVars.Get('os_install_bind_path'),
self.clVars.Get('os_install_bind_mountpoint')))
for bindData in listBinds:
srcMountPoint = bindData['srcMountPoint']
destMountPoint = bindData['destMountPoint']
if destMountPoint in dictMountDev:
devMount[dictMountDev[destMountPoint]]['mountPoint'] = ''
if destMountPoint == "none" and srcMountPoint in bindSrcDest and \
bindSrcDest[srcMountPoint] in bindDestSrc:
bindDestSrc.pop(bindSrcDest[srcMountPoint])
bindSrcDest.pop(srcMountPoint)
else:
bindDestSrc[destMountPoint] = srcMountPoint
if destMountPoint in bindSrcDest:
bindDestSrc.pop(bindSrcDest[destMountPoint])
bindSrcDest[srcMountPoint] = destMountPoint
# update install root dev
rootDev = filter(lambda x:x[1]['mountPoint']=='/',devMount.items())
if not rootDev:
self.printERROR(_("Need specify root partition"))
return False
self.clVars.Set('os_install_root_dev',rootDev[0][0],True)
osInstallRootType = self.clVars.Get('os_install_root_type')
# update bind variables by new hash
if osInstallRootType != "flash":
new_bind_dest, new_bind_src = \
reduce(lambda x,y:[x[0]+[y[0]],x[1]+[y[1]]],
sorted(bindDestSrc.items()) ,
[[]]*2)
# discard all bind point for flash installation
else:
new_bind_dest = []
new_bind_src = []
if filter(lambda x: x != '/', usedMP):
self.printERROR(
_("Installation to flash disk is not support multipartition"))
return False
if filter(lambda x:x['dev']!="none",listSwaps):
self.printERROR(
_("Installation to flash disk is not support swap disks"))
return False
if builderMode:
self.printERROR(
_("Installation to flash disk is not support builder mode"))
return False
# receive substitution func. Discard all mp, exclude '/' for flash
if osInstallRootType != "flash":
substitution = lambda data,mp: data
else:
substitution = lambda data,mp: data if mp == '/' else ""
separateDevice = lambda device: map(
lambda x: int(x) if x.isdigit() else x,
re.findall('\d+|\D+',device))
# update variables by new hash
new_mount, new_format, new_isformat, new_options= \
reduce(lambda x,y:[x[0]+[substitution(devMount[y]['mountPoint'],
devMount[y]['mountPoint'])],
x[1]+[substitution(devMount[y]['fileSystem'],
devMount[y]['mountPoint'])],
x[2]+[substitution(devMount[y]['isFormat'],
devMount[y]['mountPoint'])],
x[3]+[substitution(devMount[y]['options'],
devMount[y]['mountPoint'])]],
sorted(devMount.keys(),key=separateDevice),[[]]*4)
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)))
return True
def setUsers(self,listUsers):
"""Set users data (migration)"""
if listUsers:
migrateUsers = list(set(listUsers))
migrateUsers.sort()
migrateUsers = ["root"] + filter(lambda x: x!="root", migrateUsers)
self.clVars.Set('cl_migrate_user', migrateUsers, force=True)
return True
def setMBR(self, mbrDisk):
"""Set mbr by param or get from variables"""
bootDiskGrub = ""
if mbrDisk == "off":
self.clVars.Set('os_install_mbr',"",force=True)
elif mbrDisk:
listbootDiskGrub = map(lambda x: x[0],
filter(lambda x: "/dev/"+x[0]==mbrDisk,
zip(self.clVars.Get('os_device_dev'),
self.clVars.Get('os_device_map'))))
if filter(lambda x: "/dev/%s"%x == mbrDisk,
self.clVars.Get('os_device_dev')):
self.clVars.Set('os_install_mbr',mbrDisk[5:], force=True)
else:
self.printERROR(_("Cann't found disk '%s'")%mbrDisk)
return False
return True
def createListOptions(self):
"""Create listDisksOptions, listSwapsOptions and listBindOptions
by variables"""
diskData = zip(self.clVars.Get('os_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] == "yes" else False}
listToOptDictBind = lambda x:{'srcMountPoint':x[0],
'destMountPoint':x[1],
'options':['bind'],
'isFormat':False,
'fileSystem':'none'}
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')
updateIdDict = dict(map(lambda x:(x[0],x[2]),filter(lambda x:x[1]!=x[2],
zip(self.clVars.Get('os_disk_dev'),
self.clVars.Get('os_disk_id'),
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,
mbrDisk):
"""Set install options (set users, disks and mbr"""
try:
if self.setUsers(listUsers) and \
self.setDisks(listDisks,listBinds,listSwaps) and \
self.setMBR(mbrDisk):
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):
reActive = re.compile('^%s\s*[*]'%partition)
device = filter(lambda x:x in partition,
self.clVars.Get('os_device_dev'))
if not device:
raise DistributiveError(_("Cann't get parent device"))
device = device[0]
fdiskProcess = process("/sbin/fdisk","-l","/dev/%s"%device)
if fdiskProcess.failed():
raise DistributiveError(_("Cann't 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", "/dev/%s"%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","/dev/%s"%device)):
return True
raise DistributiveError(_("Cann't set 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=/dev/%s"%self.clVars.Get('os_install_mbr'),
stderr=STDOUT)
if ddProcess.failed():
raise DistributiveError(_("Cann't write 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(_("Cann't install syslinux\n%s")%
syslinuxProcess.read())
# is partition active
return self.setActivePartition(self.clVars.Get('os_install_root_dev'))
def installGrubBootloader(self,target):
"""Install boot loader
Perform grub installation to disk, which has root partition
"""
grubProcess = process("/sbin/grub",
"--device-map=%s/boot/grub/device.map"%target.getDirectory(),
"--batch",stderr=STDOUT)
bootDisk = self.getFieldByField("grub","mount","/boot",
secondPrefix="os_install_disk")
if not bootDisk:
bootDisk = self.getFieldByField("grub","mount","/",
secondPrefix="os_install_disk")
mbrDisk = self.clVars.Get('os_install_mbr')
mbrDiskNum = filter(lambda x:x[0]==mbrDisk,
zip(self.clVars.Get('os_device_dev'),
self.clVars.Get('os_device_map')))
if not mbrDiskNum:
raise DistributiveError(_("Cann't determine mbr disk"))
grubProcess.write("root (hd%s)\n" %bootDisk)
grubProcess.write("setup (hd%d)\n"%mbrDiskNum[0][1])
grubProcess.write("quit\n")
if grubProcess.failed():
raise DistributiveError(_("Cann't install bootloader"))
def generateTableData(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,
self.clVars.Get('os_disk_part'),
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 getPwdHashUser(self, userName, stdinRead=False):
if stdinRead:
try:
userPwd = sys.stdin.readline().rstrip()
except EOFError:
raise KeyboardInterrupt()
else:
cl_overriding.printSUCCESS(_("Enter password for user %s")%userName)
try:
userPwd = getUserPassword()
while userPwd is False:
if get_install_errors():
for line in filter(lambda x:x,
pop_install_errors().split('\n')):
self.printERROR(line)
userPwd = getUserPassword()
except EOFError:
raise KeyboardInterrupt()
encryptObj = encrypt()
if not userPwd:
raise InstallError(_("Unable to find the password for user %s")\
%userName)
return False
pwdHash = encryptObj.getHashPasswd(userPwd, "shadow_ssha256")
if pwdHash is False:
raise InstallError()
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):
"""configure current system"""
configureMessage = _("Configure system")
error = None
keyInter = None
try:
try:
# install this package
self.installPackage()
self.printMessageForTest(configureMessage)
self.printByResult(self.applyTemplatesLive())
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(
_("Link calculate-desktop to package configuration"))
self.hideStdout()
objDesktop = desktop()
objDesktop.createClVars()
res = objDesktop.installProg()
self.showStdout()
self.printByResult(res)
# 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(
_("Link calculate-client to 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)
objUsers = currentUsers()
if self.clVars.Get('os_root_type') == "livecd":
if not objUsers.hasUsers("guest"):
self.printMessageForTest(_("Adding guest user"))
self.printByResult(objUsers.addUsers("guest","guest"))
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())
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(_("Interrupting the configuration"))
error = _("Configuration manually interrupt")
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-...)
initrdPath = path.join(self.clVars.Get('cl_chroot_path'),
'boot',self.clVars.Get('os_install_initrd'))
initrdInstallPath = path.join(self.clVars.Get('cl_chroot_path'),
'boot',self.clVars.Get('os_install_initrd_install'))
# section which must contains equealent modules and kernel buildins
importantSections = ['File systems','Pseudo filesystems',
'CDROM.*Filesystems', 'DOS.*Filesystems',
'SCSI Transport']
curConfig = dict(KernelConfig().getSectionParams(*importantSections))
if not self.clVars.Get('os_install_kernel_config'):
copy2(initrdInstallPath,initrdPath);
return True
newConfig = KernelConfig( configFile=
path.join(self.clVars.Get('cl_chroot_path'),
'boot',self.clVars.Get('os_install_kernel_config')))
newConfig = newConfig.getSectionParams(*importantSections)
conflictOptions = filter(lambda x: x[1]=="M" and
x[0] in curConfig and
curConfig[x[0]]=="Y",
newConfig)
if conflictOptions:
copy2(initrdInstallPath,initrdPath);
return True
return InitRamFs(initrdInstallPath).cleanInitRamFs(initrdPath)
def afterCopyHDDinstall(self,targetDistr, addUsers, changePwdUsers,
migrateUsers):
"""Action performed after distributive copy for hdd install"""
# copy clt files from current system
self.printMessageForTest(_("Coping clt templates to new system"))
cltCpy = cltCopy(target=targetDistr.getDirectory())
for directory in self.clVars.Get('cl_template_clt_path'):
cltCpy.performCopy(directory)
self.printByResult(True)
self.printMessageForTest(_("Coping configuration files to 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.printByResult(True)
# join templates
self.printMessageForTest(_("Updating config"))
self.applyTemplates(targetDistr.getDirectory())
# mount bind mount points
self.printByResult(True)
# optimize initrd
self.printMessageForTest(_("Creating new initrd file"))
self.printByResult(self.cleanInitrd())
self.printMessageForTest(_("Post-install configuration"))
targetDistr.postinstallMountBind()
self.printByResult(True)
# migrate users
self.printMessageForTest(_("Migrate users"))
objMigrate = migrate(targetDistr.getDirectory())
if not objMigrate.migrate(addUsers,changePwdUsers,migrateUsers):
raise InstallError(_("Can not migrate users to new system"))
self.printByResult(True)
def installSystem(self, force=False, bootDisk=None, stdinReadPwd=False,
builder=False, flagSpinner=True):
"""install System by current variable enviroment"""
sourceDistr = None
targetDistr = None
error = None
distrCopy = False
try:
rootPartdev = self.clVars.Get('os_install_root_dev')
rootPartCmdList = filter(lambda x: x['dev']==rootPartdev,
self.listDisksOptions)
rootPartCmdDict = rootPartCmdList[0]
rootPartFileSystem = self.getFieldByField("format","dev",
rootPartdev,
firstPrefix="os_install_disk")
rootPartIsFormat=rootPartCmdDict['isFormat']
rootPartSystemId=rootPartCmdDict['systemId']
self.printInfo()
targetDistr = self.getTargetDistributive(rootPartdev,
buildermode=builder,
fileSystem=rootPartFileSystem,
isFormat=rootPartIsFormat,
systemId=rootPartSystemId)
distRep = DistributiveRepository()
minver = "10.8"
instver = \
getTupleVersion(self.clVars.Get('os_install_linux_ver'))
distName = self.clVars.Get('cl_image')
if distName and instver < getTupleVersion(minver):
self.printERROR(
_("Installation is supported for system not less version"
" %s")%minver)
distName = ""
if distName:
# print info
sourceDistr = distRep.getDistributiveByFile(distName)
if not force:
dialogMessage = _("Continue with the installation of \
the system") + " (yes/no)"
try:
dialogRes = dialogYesNo(dialogMessage)
except KeyboardInterrupt:
self.setSignalInterrupt()
self.defaultPrint("\n")
raise KeyboardInterrupt
if dialogRes in (None,False):
self.printERROR(_("Interrupting the installation"))
return False
# set Users passwords
if self.clVars.Get('os_install_root_type') != "flash":
changePwdUsers = \
self.generateHashRoot(stdinRead=stdinReadPwd)
addUsers = self.generateHashUsers(stdinRead=stdinReadPwd)
migrateUsers = self.getNamesMigrateUsers()
mntpath = '/mnt'
if not os.access(mntpath,os.W_OK):
raise InstallError(
_("Impossible create directory in '%s'")%mntpath)
# cmd options
self.printMessageForTest(_("Formating partitions"))
targetDistr.performFormat()
self.printByResult(True)
# install distributive
self.printMessageForTest(
_("Unpacking system image into target"))
self.defaultPrint(" ")
self.lenStartMessage += 1
self.clVars.Get('os_grub_conf')
# set spinner flag
Distributive.flagSpinner = flagSpinner
targetDistr.installFrom(sourceDistr)
self.printByResult(True)
if self.clVars.Get('os_install_root_type') != "flash":
self.afterCopyHDDinstall(targetDistr, addUsers,
changePwdUsers, migrateUsers)
else:
# join templates
self.printMessageForTest(
_("Configure of flash installation"))
self.applyTemplatesFlash(targetDistr.getDirectory())
self.printByResult(True)
self.closeClTemplate()
# change boot config
if self.clVars.Get('os_install_mbr'):
self.printMessageForTest(_("Preparing system for reboot"))
self.prepareBoot(targetDistr)
self.printByResult(True)
else:
return False
except (EOFError), e:
error = e
except (InstallError,DistributiveError),e:
error = e
#for i in apply(traceback.format_exception, sys.exc_info()):
# print i
except (Exception),e:
error = ""
for i in apply(traceback.format_exception, sys.exc_info()):
error += i
except KeyboardInterrupt,e:
self.setSignalInterrupt()
self.printByResult(False)
self.printWARNING(_("Interrupting the installation"))
error = _("Installation manually interrupt")
if error:
self.printByResult(False)
try:
self.closeClTemplate()
if sourceDistr and sourceDistr.childs:
self.printMessageForTest(_("Releasing source distributive"))
sourceDistr.close()
self.printByResult(True)
if targetDistr and targetDistr.childs:
self.printMessageForTest(_("Unmount target system volume"))
targetDistr.close()
self.printByResult(True)
except (InstallError,DistributiveError),e:
error = "%s\n%s" % (str(error),_("Unmounting error"))
except KeyboardInterrupt,e:
self.setSignalInterrupt()
pass
if error:
self.printByResult(False)
if error:
for line in filter(lambda x: x,str(error).split('\n')):
self.printERROR(line)
self.printERROR(_("System installation failed"))
return False
self.printSUCCESS(_("System successfully installed"))
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 = clLocale()
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 installation'))
try:
self.printMessageForTest(
_("Link calculate-install to package configuration"))
self.printByResult(appendProgramToEnvFile(__app__, self.clVars),
failMessage= _("Can not 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 manually interrupt")
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 installation failed"))
return False
return True
def uninstallPackage(self):
"""Uninstall this package. Convert Calculate system to Gentoo"""
error = None
self.printSUCCESS(_('Package uninstallation'))
try:
self.printMessageForTest(
_("Unlink calculate-install from package configuration"))
self.printByResult(removeProgramToEnvFile(__app__, self.clVars),
failMessage = _("Can not 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 manually interrupt")
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