diff --git a/pym/cl_distr.py b/pym/cl_distr.py index 9609031..074497e 100644 --- a/pym/cl_distr.py +++ b/pym/cl_distr.py @@ -87,8 +87,8 @@ class DistributiveRepository: elif "Squashfs filesystem" in ftype: return SquashDistributive(filename) else: - raise DistributiveError("Wrong distributive '%s':\n%s"% - (filename,ftype)) + raise DistributiveError(_("Wrong distributive") + " '%s':\n%s"\ + %(filename,ftype)) def getBestDistributive(self,system=None,shortname=None,march=None, version=None): @@ -114,7 +114,7 @@ class DistributiveRepository: class Distributive(object): """Distributive object. Parent object for all distributive.""" - mountError = "Cann't mount %s:\n%s" + mountError = _("Cann't mount") + " %s:\n%s" def __init__(self, parent=None): self.childs = [] # if specified parent @@ -177,9 +177,9 @@ class Distributive(object): def convertToDirectory(self): """Default c raise error about impossible convert object""" - raise DistributiveError("Cann't convert '%s' to '%s'" % - (self.__class__.__name__, - "DirectoryDistributive")) + raise DistributiveError(_("Cann't convert") + " '%s' "\ + %self.__class__.__name__ + _("to") +\ + " '%s'" %"DirectoryDistributive") # def __del__(self): # """Uncomment this method for automaticaly release all distributive @@ -209,8 +209,8 @@ class Distributive(object): os.mkdir(path) return True except (Exception,KeyboardInterrupt),e: - raise DistributiveError("Cann't create directory '%s':\n%s"% - (path,str(e))) + raise DistributiveError(_("Cann't create directory") +" '%s':\n%s" + %(path,str(e))) def _removeDirectory(self,directory): """Remove directory and files contained in it""" @@ -218,15 +218,15 @@ class Distributive(object): try: removeDir(directory) except (Exception,KeyboardInterrupt),e: - raise DistributiveError("Unable remove directory from '%s':\n%s" - %(directory,str(e))) + raise DistributiveError(_("Unable remove directory from") +\ + " '%s':\n%s" %(directory,str(e))) def _copyfile(self,infile,outfile): try: copyfile(infile,outfile) except (Exception,KeyboardInterrupt),e: - raise DistributiveError("Cann't copy '%s' to '%s':\n%s"% - (infile,outfile,str(e))) + raise DistributiveError(_("Cann't copy") + " '%s' to '%s':\n%s"\ + %(infile,outfile,str(e))) def copy(self,fromdir,todir): """Copy files from 'fromdir' directory to 'todir' directory""" @@ -234,8 +234,9 @@ class Distributive(object): if res == 0: return True else: - raise DistributiveError("Cann't copy file from '%s' to '%s':\n%s"% - (fromdir,todir,errmes)) + raise DistributiveError(_("Cann't copy file from") +\ + " '%s' " %fromdir + _("to") +\ + " '%s':\n%s" %(todir,errmes)) def formatPartition(self,format=""): pass @@ -248,8 +249,8 @@ class Distributive(object): def _mountToDirectory(self,file,directory,mountopts=""): """Mount squashfs to directory""" if isMount(directory): - raise DistributiveError("Cann't mount to directory:\n"+ - "Directory already mounted") + raise DistributiveError(_("Cann't mount to directory: %s\n")\ + %directory+ _("Directory already mounted")) res,errmes = self.runOsCommand("/bin/mount %s %s %s"% (mountopts,file,directory)) if res == 0: @@ -265,11 +266,11 @@ class Distributive(object): """Umount directory""" if isMount(directory): for wait in [0,0.5,2,5]: - sleep(wait) + #sleep(wait) res,errmes = self.runOsCommand("/bin/umount %s"%directory) if res == 0: return True - raise DistributiveError("Cann't umount %s:\n%s"% + raise DistributiveError(_("Cann't umount") + " %s:\n%s"% (directory,errmes)) else: return True @@ -330,12 +331,12 @@ class MultiPartitions: if set(argv.keys()) != set(dictDataPart.keys()): notFoundAttr = set(dictDataPart.keys()) - set(argv.keys()) if notFoundAttr: - raise DistributiveError("Were not specified attributes (%s)"\ + raise DistributiveError(_("Were not specified attributes (%s)")\ %", ".join(map(lambda x:"DataPartition.%s"%x, notFoundAttr))) unnecessaryAttr = (set(dictDataPart.keys()) ^ set(argv.keys())) -\ set(dictDataPart.keys()) if unnecessaryAttr: - raise DistributiveError("Not used attributes (%s)"\ + raise DistributiveError(_("Not used attributes (%s)")\ %", ".join(map(lambda x:"DataPartition.%s"%x, unnecessaryAttr))) else: partObj = DataPartition() @@ -461,7 +462,6 @@ class PartitionDistributive(Distributive): self.multipartition.getFileSystems(), self.multipartition.getIsFormat()) return mulipartData - def convertToDirectory(self): """Convert partition to directory by mounting""" @@ -477,13 +477,15 @@ class PartitionDistributive(Distributive): mulipartDataNotBind = filter(lambda x: x[2]!="bind", self.getMultipartData()) for dev, mountPoint, fileSystem, isFormat in mulipartDataNotBind: - realMountPoint = pathJoin(mdirectory, mountPoint) - self._mountPartition(dev,realMountPoint) + if fileSystem!="swap": + realMountPoint = pathJoin(mdirectory, mountPoint) + self._mountPartition(dev,realMountPoint) partObj = PartitionDistributive(dev, flagRemoveDir=False, fileSystem=fileSystem, isFormat=isFormat, parent=dirObj) - DirectoryDistributive(realMountPoint,parent=partObj) + if fileSystem!="swap": + DirectoryDistributive(realMountPoint,parent=partObj) self.DirectoryObject = dirObj return dirObj @@ -499,30 +501,49 @@ class PartitionDistributive(Distributive): filter(lambda x: x[2] and x[0]!="bind", dataPartitions)) for fileSystem, dev in formatPartitions: - self.formatPartition(dev, format=fileSystem) + if fileSystem=="swap": + self.formatSwapPartition(dev) + else: + self.formatPartition(dev, format=fileSystem) return True def formatPartition(self, dev,format="reiserfs"): """Format partition""" if not format in self.formatUtilities: raise DistributiveError( - "Specified '%s' format inn't supported" % format) - # TODO: test - print dev, format - return True + _("Specified '%s' format inn't supported")%format) if isMount(dev): raise DistributiveError( - "Cann't format partition %s, because it is mounted" % dev) + _("Cann't format partition %s, because it is mounted")%dev) if not os.access(dev,os.W_OK): - raise DistributiveError("Cann't format partition %s:\n%s"% + raise DistributiveError(_("Cann't format partition") + " %s:\n%s"% (dev,_("Permission denied"))) - execStr = "%s %s"(self.formatUtilities[format],dev) + execStr = self.formatUtilities[format]%dev + res,errmes = self.runOsCommand(execStr) + if res == 0: + return True + else: + raise DistributiveError(_("Cann't format partition") + " %s:\n%s"% + (dev,errmes)) + + def formatSwapPartition(self, dev): + """Format swap partition""" + if dev in map(lambda y: y.split(" ")[0], + filter(lambda x: x.startswith("/"), + open("/proc/swaps"))): + raise DistributiveError(\ + _("Cann't 'mkswap %s', swap partition is used in the \ +current system") %dev) + if isMount(dev): + raise DistributiveError( + _("Cann't format partition %s, because it is mounted") %dev) + execStr = "mkswap %s"%dev res,errmes = self.runOsCommand(execStr) if res == 0: return True else: - raise DistributiveError("Cann't format partition %s:\n%s"% - (dev,errmes)) + raise DistributiveError(_("Cann't execute '%s'")%execStr +\ + "\n%s" %errmes) def installFrom(self, source): """Install distributive to partition from source distributive""" @@ -556,7 +577,7 @@ class ArchiveDistributive(Distributive): """Unpack archive""" # archive is exists if not pathexists(archfile): - raise DistributiveError("File '%s' not found"%archfile) + raise DistributiveError(_("File '%s' not found")%archfile) # detect type archive archiveType = self._detectArchive(archfile) # make directory if archive was detected normally @@ -573,9 +594,9 @@ class ArchiveDistributive(Distributive): res,mes = self.runOsCommand("tar xf %s -C %s/"% (archfile,directory)) else: - raise DistributiveError("Unknown archive type by '%s'"%file) + raise DistributiveError(_("Unknown archive type by '%s'")%file) if res != 0: - raise DistributiveError("Error during unpacking\n%s"%mes) + raise DistributiveError(_("Error during unpacking\n%s")%mes) def unpackTo(self,directory): """Unpack currect archive to directory""" @@ -604,7 +625,7 @@ class ArchiveDistributive(Distributive): def packToArchive(self,directory,file): res,errmes = self.runOsCommand("tar cf %s -C %s ."%(file,directory)) if res != 0: - raise DistributiveError("Cann't create archive '%s':\n%s"% + raise DistributiveError(_("Cann't create archive") + " '%s':\n%s"% (file,errmes)) def installFrom(self, source): @@ -649,7 +670,7 @@ class SquashDistributive(Distributive): res,errmes = self.runOsCommand("/usr/bin/mksquashfs %s/ %s"% (directory,file)) if res != 0: - raise DistributiveError("Cann't create squashfs '%s':\n%s"% + raise DistributiveError(_("Cann't create squashfs") + " '%s':\n%s"% (file,errmes)) def installFrom(self, source): @@ -702,7 +723,7 @@ class IsoDistributive(Distributive): self._mountIso(self.file,mdirectory) fileLive = self._getLastLive(mdirectory) if not fileLive: - raise DistributiveError("Iso %s doesn't contain live image" % + raise DistributiveError(_("Iso %s doesn't contain live image") % self.file) return SquashDistributive(pathjoin(mdirectory,fileLive), parent=self) @@ -717,7 +738,7 @@ class IsoDistributive(Distributive): return self.convertToSquash().convertToDirectory() def prepareIso(self,directory): - print("apply iso templates to %s/"%directory) + print(_("apply iso templates to %s/")%directory) self._makeDirectory(pathjoin(directory,"isolinux")) self._copyfile("/usr/share/syslinux/isolinux.bin", pathjoin(directory,"isolinux/isolinux.bin")) @@ -728,7 +749,8 @@ class IsoDistributive(Distributive): if pathexists(file): os.unlink(file) except (Exception,KeyboardInterrupt),e: - raise DistributiveError("Cann't remove %s:\n%s"%(file,str(e))) + raise DistributiveError(_("Cann't remove") +\ + " %s:\n%s"%(file,str(e))) res,errmes = self.runOsCommand( "%(progname)s %(params)s -o %(target)s %(source)s/"% @@ -741,7 +763,7 @@ class IsoDistributive(Distributive): if res == 0: return True else: - raise DistributiveError("Cann't create iso image %s:\n%s"% + raise DistributiveError(_("Cann't create iso image") + " %s:\n%s"% (file,errmes)) def installFrom(self, source): @@ -773,7 +795,7 @@ class IsoDistributive(Distributive): raise e except KeyboardInterrupt,e: self._removeDirectory(isoDirectory) - raise DistributiveError("Keyboard interrupt") + raise DistributiveError(_("Keyboard interrupt")) class ScratchDistributive(Distributive): def __init__(self,directory,parent=None,mdirectory="/mnt/install", @@ -843,7 +865,8 @@ class ScratchPartitionDistributive(PartitionDistributive): if check and not partition is None and \ (not self.reRightPartition.match(partition) or \ not pathexists(partition)): - raise DistributiveError("Wrong partition name '%s'"%partition) + raise DistributiveError(_("Wrong partition name") +\ + " '%s'"%partition) def _mountPartition(self,partition,directory): """Mount partition to directory""" @@ -868,7 +891,7 @@ class ScratchPartitionDistributive(PartitionDistributive): if res == 0: return True else: - raise DistributiveError("Cann't format partition %s:\n%s"% + raise DistributiveError(_("Cann't format partition") + " %s:\n%s"% (self.partition,errmes)) def convertToDirectory(self): @@ -912,4 +935,4 @@ class ScratchPartitionDistributive(PartitionDistributive): raise e except KeyboardInterrupt,e: self._removeDirectory(scratchDirectory) - raise DistributiveError("Keyboard interrupt") + raise DistributiveError(_("Keyboard interrupt")) diff --git a/pym/cl_fill_install.py b/pym/cl_fill_install.py index 40361cc..1fa887b 100644 --- a/pym/cl_fill_install.py +++ b/pym/cl_fill_install.py @@ -278,7 +278,7 @@ class fillVars(object, glob_attr): devicesForFstab = sorted(filter(lambda x: x[1] != "" and x[1] != "swap", zip(self.Get('os_disk_dev'), self.Get('os_install_disk_mount'), - self.Get('os_disk_format'), + self.Get('os_install_disk_format'), self.Get('os_install_disk_options'))), lambda x,y: cmp(x[1],y[1])) # rootLine one string, but it correct work if devicesForFstab is empty diff --git a/pym/cl_install.py b/pym/cl_install.py index 7ea7664..e6cb67e 100644 --- a/pym/cl_install.py +++ b/pym/cl_install.py @@ -28,7 +28,7 @@ def installExit(*args,**kwars): raise InstallError(globals()["install_errors"]) def overprintERROR(s): - globals()["install_errors"] += s +"\n" + globals()["install_errors"] += str(s) +"\n" cl_overriding.exit = installExit cl_overriding.printERROR = overprintERROR @@ -39,9 +39,11 @@ from cl_template import template from cl_datavars import DataVars from cl_print import color_print from cl_distr import PartitionDistributive,DistributiveRepository,\ - DistributiveError, ScratchDistributive + DistributiveError, ScratchDistributive, MultiPartitions +from cl_string import tableReport from time import sleep from subprocess import Popen,PIPE +from server.utils import dialogYesNo tr = lang() tr.setGlobalDomain('cl_install') @@ -160,78 +162,134 @@ class convertDictOpt: ["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", + "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", - "ignore"], - "incompatible":["abort", - "ordered", - "ignore"]}, - "resgid":{"options":re.compile("\d+"), + "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"]]}, + "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":[]}, + "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":[]}, - "resuid":{"options":re.compile("\d+"), + "ihashsize":{"options":re.compile("\d+"), "incompatible":[]}, - "sb":{"options":re.compile("\d+"), + "logbufs":{"options":re.compile("\d+"), + "incompatible":[]}, + "logbsize":{"options":re.compile("\d+"), + "incompatible":[]}, + "logdev":{"options":re.compile(".+"), + "incompatible":[]}, + "rtdev":{"options":re.compile(".+"), "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"]]} - } + "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"]]}} + listFileSystemCorrupted = [] def __init__(self, clVars): self.clVars = clVars @@ -239,6 +297,11 @@ class convertDictOpt: '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("_"), @@ -265,6 +328,7 @@ class convertDictOpt: raise InstallError(_("Unsupported file system %s")%realFileSystem) for opt in realOptions: if not opt in allOptions: + self.addFileSystemCorrupted(realFileSystem) raise InstallError(_("Incorrect option %s")%opt) def _checkFileSystemIncompatibleOpt(self, realFileSystem, realOptions): @@ -297,6 +361,7 @@ class convertDictOpt: 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)) @@ -319,6 +384,7 @@ class convertDictOpt: dictOpt[nameOpt] = [] dictOpt[nameOpt].append(valueOpt) elif len(dataOpt)>2: + self.addFileSystemCorrupted(realFileSystem) raise InstallError(_("Incorrect option %s")%opt) else: notPairOpt.append(opt) @@ -330,10 +396,12 @@ class convertDictOpt: 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] @@ -344,9 +412,11 @@ class convertDictOpt: 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: @@ -354,6 +424,7 @@ class convertDictOpt: if wrongValues: wrongOpt = ",".join(map(lambda x: "%s=%s"%(nameOpt,x), wrongValues)) + self.addFileSystemCorrupted(realFileSystem) raise InstallError(_("Incorrect option %s")\ %wrongOpt) checkValuesIncompOpt = checkValues["incompatible"] @@ -363,6 +434,7 @@ class convertDictOpt: if len(incompValues)>1: wrongOpt = map(lambda x: "%s=%s"%(nameOpt,x), incompValues) + self.addFileSystemCorrupted(realFileSystem) raise InstallError(_("Incompatible options") + ":"+\ " " + wrongOpt[0] + " " + \ _("and") + " " +\ @@ -403,8 +475,10 @@ class convertDictOpt: optProperties = optionsDict.copy() if "srcMountPoint" in optProperties: # bind options - optProperties.update(self.getDefaultOptBind()) - return optProperties + dictOptions = {} + dictOptions.update(self.getDefaultOptBind()) + dictOptions.update(optProperties) + return dictOptions optDevice = optProperties["dev"] dataPart = filter(lambda x: x[0]==optDevice, self.varDiskData) dev, format, mount, options, part, size = dataPart[0] @@ -419,7 +493,8 @@ class convertDictOpt: dictUpdateProperty["mountPoint"] = optMountPoint if optFileSystem: if not optFileSystem in self.getAllSupportFileSystemOpt(): - raise InstallError(_("Wrong options '%s'")%optFileSystem) + raise InstallError(_("Wrong file system options '%s'")\ + %optFileSystem) dictOptions.update(self.getDefaultOptFileSystem(optFileSystem)) if optFileSystem == "noformat": if not format: @@ -429,7 +504,6 @@ class convertDictOpt: options = ["noatime"] dictOptions["fileSystem"] = format dictOptions["options"] = options.split(",") - if optFileSystem in self._propertiesFileSystem: dictUpdateProperty["fileSystem"] = dictOptions["fileSystem"] optOptions = optProperties["options"] @@ -455,10 +529,13 @@ class convertDictOpt: return dictDefault else: # Swap options + dictOptions = {} optFileSystem = "swap" if optFileSystem != format: dictUpdateProperty["isFormat"] = True - return self.getDefaultOptSwap() + dictOptions.update(self.getDefaultOptSwap()) + dictOptions.update(optProperties) + return dictOptions class cl_install(color_print): """Primary class for templates appling and system installation""" @@ -468,6 +545,10 @@ class cl_install(color_print): self.clVars = None self.clTempl = None self.color = True + self.listDisksOptions = [] + self.listBindsOptions = [] + self.listSwapsOptions = [] + def colorPrint(self,*argv,**kwarg): if self.color: @@ -536,6 +617,7 @@ class cl_install(color_print): self.clVars.Get('os_root_dev')) self.printSUCCESS(_("File system")+": %s"% self.getFieldByField("format","mount","/", + firstPrefix="os_install_disk", secondPrefix="os_install_disk")) self.printSUCCESS(_("Swap disk")+": %s"% self.getFieldByField("dev","mount","swap", @@ -566,16 +648,17 @@ class cl_install(color_print): sleep(1) self.defaultPrint("\b\b \n") - def prepareBoot(self,targetDistr): - self.installBootloader(targetDistr) + def prepareBoot(self,targetDistr, bootDisk="0"): + self.installBootloader(targetDistr, bootDisk="0") - def getTargetDistributive(self, disk): + def getTargetDistributive(self,disk,fileSystem="reiserfs",isFormat=False): #if buildermode: #return ScratchDistributive(disk,mdirectory="/mnt/install", #check=True) #else: return PartitionDistributive(disk,mdirectory="/mnt/install", - check=True) + check=True, fileSystem=fileSystem, + isFormat=isFormat) def applyTemplates(self,directory): """Apply templates for root of system.""" @@ -597,8 +680,14 @@ class cl_install(color_print): 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 - print "LD", listDisks + # cmd options + self.listDisksOptions = listDisks + self.listBindsOptions = listBinds + self.listSwapsOptions = listSwaps installAllDevices = map(lambda x: x['dev'],listSwaps) +\ map(lambda x: x['dev'],listDisks) # detect duplicate partition @@ -820,7 +909,7 @@ class cl_install(color_print): else: return "" - def installBootloader(self,target): + def installBootloader(self,target, grubDisk="0"): """Install boot loader Perform grub installation to disk, which has root partition @@ -828,25 +917,78 @@ class cl_install(color_print): pipe = Popen(["/sbin/grub", "--device-map=%s/boot/grub/device.map"%target.getDirectory(), "--batch"], stdin=PIPE, stdout=PIPE,stderr=PIPE) - pipe.stdin.write("root (hd%s)\n"% - self.getFieldByField("grub","install","/")) + bootDisk = self.getFieldByField("grub","mount","/boot", + secondPrefix="os_install_disk") + if not bootDisk: + bootDisk = self.getFieldByField("grub","mount","/", + secondPrefix="os_install_disk") + pipe.stdin.write("root (hd%s)\n" %bootDisk) # TODO: change hd0 for bootloader install to other disks # may be another parameters - pipe.stdin.write("setup (hd0)\n") + pipe.stdin.write("setup (hd%s)\n"%grubDisk) pipe.stdin.write("quit\n") pipe.stdin.close() # TODO: break if command is hang (KeyboardInterrupt is supported) if pipe.wait() != 0: raise DistributiveError("Cann't install bootloader") - def installSystem(self): + def generateTableData(self): + """Get data from print table""" + title = _("New partition table") + 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')) + 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) + + headerList = [_("Size"),_("Device"),_("Directory"),_("File system"), + _("Format"), _("Partition")] + dataList = zip(listSize, + self.clVars.Get('os_disk_dev'), + listMountPoint, + listFileSystem, + listIsFormat, + self.clVars.Get('os_disk_part')) + return title, headerList, dataList + + def installSystem(self, force=False, bootDisk=None): """install System by current variable enviroment""" sourceDistr = None targetDistr = None error = None try: - targetDistr = self.getTargetDistributive(\ - self.clVars.Get('os_install_root_dev')) + 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'] + + targetDistr = self.getTargetDistributive(rootPartdev, + fileSystem=rootPartFileSystem, + isFormat=rootPartIsFormat) distRep = DistributiveRepository() distName = self.clVars.Get('cl_image') if distName: @@ -854,15 +996,94 @@ class cl_install(color_print): sourceDistr = distRep.getDistributiveByFile(distName) self.printInfo(sourceDistr,targetDistr) # wait 10 sec - waittime = 3 - self.printSUCCESS(_("Installation will start pass %d seconds.") - %waittime) - self.wait(waittime) - # format partition if needed - return True + #waittime = 3 + #self.printSUCCESS(_("Installation will start pass %d seconds.") + #%waittime) + bootDiskGrub = "" + if bootDisk: + listbootDiskGrub = map(lambda x: x[1], + filter(lambda x: "/dev/"+x[0]==bootDisk, + zip(self.clVars.Get('os_device_dev'), + self.clVars.Get('os_device_map')))) + if listbootDiskGrub: + bootDiskGrub=listbootDiskGrub[0] + else: + raise InstallError(_("Cann't found disk %s")%bootDisk) + if not force: + title, headerList, dataList = self.generateTableData() + tableObj = tableReport(title, headerList, dataList) + cl_overriding.printSUCCESS("") + tableObj.printReport() + cl_overriding.printSUCCESS("") + dialogMessage = _("Continue with the installation of \ +the system") + " (yes/no)" + dialogRes = dialogYesNo(dialogMessage) + if dialogRes is None: + return True + elif dialogRes is False: + return True + #self.wait(waittime) + # cmd options + #self.listDisksOptions + #self.listBindsOptions + #self.listSwapsOptions + + 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"] + objMultiPartitions.addPartition(dev=dev, + mountPoint=mountPoint, + fileSystem=fileSystem, + isFormat=isFormat) + # 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"] + objMultiPartitions.addPartition(dev=dev, + mountPoint=mountPoint, + fileSystem=fileSystem, + isFormat=isFormat) + # 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) + if flagMultipartition: + # Set Multipartition + targetDistr.multipartition=objMultiPartitions + # Format all partitions + targetDistr.formatAllPartitions() + else: + # Format root partition + if targetDistr.isFormat: + targetDistr.formatPartition(targetDistr.partition, + format=targetDistr.fileSystem) self.printSUCCESS(_("Formating partition")) - targetDistr.formatPartition( - self.getFieldByField("format","install","/") or "reiserfs") # install distributive self.printSUCCESS(_("Unpacking system image into target")) targetDistr.installFrom(sourceDistr) @@ -870,9 +1091,14 @@ class cl_install(color_print): # join templates self.printSUCCESS(_("Update config")) self.applyTemplates(targetDistr.getDirectory()) + # mount bind mount points + targetDistr.postinstallMountBind() # change boot config self.printSUCCESS(_("Prepare system for reboot")) - self.prepareBoot(targetDistr) + if bootDiskGrub: + self.prepareBoot(targetDistr, bootDiskGrub) + else: + self.prepareBoot(targetDistr) else: self.printWARNING("No update available.") return False @@ -901,7 +1127,7 @@ class cl_install(color_print): self.printERROR(line) return False self.printSUCCESS(_("System successfully installed")) - return False + return True def setLinuxName(self,shortname): self.clVars.Set('os_install_linux_shortname',shortname,True) diff --git a/pym/cl_install_cmd.py b/pym/cl_install_cmd.py index 209ee4c..0a5f187 100644 --- a/pym/cl_install_cmd.py +++ b/pym/cl_install_cmd.py @@ -22,7 +22,7 @@ import sys from cl_lang import lang lang().setLanguage(sys.modules[__name__]) -DESCRIPTION = _("Utility for installation and configuration of Calculate Linux") +DESCRIPTION = _("The Calculate Linux installation and configuration utility") CMD_OPTIONS = [{'shortOption':"T", 'longOption':"template", 'optVal':"TEMPLATE", 'help':_("process template") @@ -44,12 +44,21 @@ CMD_OPTIONS = [{'shortOption':"T", 'action':'append', 'help':_("bind mount point for instalation") }, + {'longOption':"mbr", + 'optVal':"DEVICE", + 'help':_("boot disk for the installed system \ +(to be recorded MBR)") + }, {'shortOption':"w", 'longOption':"swap", 'optVal':"SWAP_DISK", 'action':'append', 'help':_("the SWAP_DISK for installation") }, + {'shortOption':"f", + 'longOption':"force", + 'help':_("no questions during the install process") + }, {'shortOption':"s", 'longOption':"os", 'optVal':"SYSTEM", @@ -115,6 +124,13 @@ class install_cmd(cl_install,opt,share_cmd): " " + _("mount bind specifing error: '%s'")\ %", ".join(wrongValue)) + #check boot device + if values.mbr: + bootDisk = values.mbr + reBootDisk = re.compile("^/dev/.+[^\d]$") + if not reBootDisk.match(bootDisk): + self.error(_("option %s:") %"mbr" + " " +\ + _("disk specifing error: '%s'")%bootDisk) if not values.T in [None,"all"]: self.error( @@ -255,9 +271,8 @@ class install_cmd(cl_install,opt,share_cmd): else: return False - def installSystem(self): - if cl_install.installSystem(self): - print _("installation complete") + def installSystem(self, force=False, bootDisk=None): + if cl_install.installSystem(self, force=force, bootDisk=bootDisk): return True else: return False diff --git a/pym/cl_vars_install.py b/pym/cl_vars_install.py index 228cc7b..fa4c998 100644 --- a/pym/cl_vars_install.py +++ b/pym/cl_vars_install.py @@ -1,4 +1,4 @@ -##-*- coding: utf-8 -*- +#-*- coding: utf-8 -*- # Copyright 2010 Mir Calculate Ltd. http://www.calculate-linux.org # diff --git a/scripts/cl-install b/scripts/cl-install index 1291544..fb5e2d3 100644 --- a/scripts/cl-install +++ b/scripts/cl-install @@ -57,7 +57,7 @@ if __name__ == "__main__": #if not install.applyTemplatesForSystem(): #sys.exit(1) #else: - if not install.installSystem(): + if not install.installSystem(force=options.f, bootDisk=options.mbr): sys.exit(1) if not install.writeVars(options): sys.exit(1)