#-*- coding: utf-8 -*- # Copyright 2010 Mir 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.0.0" __app__ = "calculate-install" import os import re import sys import cl_overriding install_errors = "" def installExit(*args,**kwars): raise InstallError(globals()["install_errors"]) def overprintERROR(s): globals()["install_errors"] += s +"\n" 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, ScratchDistributive from time import sleep from subprocess import Popen,PIPE tr = lang() tr.setGlobalDomain('cl_install') tr.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 flInstall(self, **args): '''Заполнить конфигурацию переменных, для десктопа''' # Имя секции в calculate.env envSection = "calculate-install" # заполнить переменные окружения алгоритмом по умолнанию self.importData(envSection, ('cl_vars_install','cl_fill_install')) class cl_install(color_print): """Primary class for templates appling and system installation""" def __init__(self): self.clVars = None self.clTempl = None self.color = True def colorPrint(self,*argv,**kwarg): if self.color: color_print.colorPrint(self,*argv,**kwarg) else: sys.stdout.write(argv[-1]) sys.stdout.flush() def setNoColor(self): self.color = False def initVars(self): """Primary initialization of variables""" self.clVars = DataVarsInstall() self.clVars.flInstall() self.clVars.flIniFile() def applyTemplatesForSystem(self): """Apply templates for root of system.""" self.clVars.Set("cl_root_path","/", True) self.clTempl = template(self.clVars) dirsFiles = self.clTempl.applyTemplates() if self.clTempl.getError(): self.printERROR(self.clTempl.getError()) return False else: return dirsFiles def printInfo(self,sourceDistr,targetDistr): self.printSUCCESS(_("Installation %s %s")% (self.clVars.Get('os_linux_name'), self.clVars.Get('os_linux_subname'))) self.defaultPrint(_("System information\n")) self.printSUCCESS(_("Computer name")+": %s"% self.clVars.Get('os_net_hostname')) self.printSUCCESS(_("Domain name")+": %s"% self.clVars.Get('os_net_domain')) self.printSUCCESS(_("Network devices")+": %s"% self.clVars.Get("os_net_interfaces_info")) self.printSUCCESS(_("Installed system")+": %s %s"% (self.old_os_linux_name, self.old_os_linux_ver)) self.defaultPrint(_("Hardware\n")) self.printSUCCESS(_("Machine hardware name")+": %s"% self.clVars.Get('os_arch_machine')) self.printSUCCESS(_("Quantity processors")+": %s(var name)"% self.clVars.Get('hr_cpus')) self.printSUCCESS(_("Videocard")+": %s"% '') self.printSUCCESS(_("Screen resolution")+": %s"% '') self.defaultPrint(_("Localization\n")) self.printSUCCESS(_("Language")+": %s"% self.clVars.Get('os_locale_lang')) self.printSUCCESS(_("Keymap")+": %s"% self.clVars.Get('os_locale_xkbname')) self.printSUCCESS(_("Timezone")+": %s"% self.clVars.Get('os_clock_timezone')) self.defaultPrint(_("Location\n")) self.printSUCCESS(_("Working volume")+": %s"% self.getDeviceByField("load",'/') or "unknown" ) self.printSUCCESS(_("Installation volume")+": %s"% self.clVars.Get('os_root_dev')) self.printSUCCESS(_("File system")+": %s"% "") self.printSUCCESS(_("Swap disk")+": %s"% "") self.printSUCCESS(_("Mounted disks")+": %s"% "") self.defaultPrint(_("Network services\n")) self.printSUCCESS(_("PROXY")+": %s"% "") self.printSUCCESS(_("NTP")+": %s"% "") self.printSUCCESS(_("Authentification")+": %s"% "") self.printSUCCESS("Found update: %s %s %s"% (self.clVars.Get('os_linux_name'), self.clVars.Get('os_linux_subname'), self.clVars.Get('os_linux_ver'))) def wait(self,sec=10): self.printSUCCESS(_("Press %s to cancel")%"Ctrl+C"+"... %d"%sec, printBR=False) for i in xrange(sec,0,-1): self.defaultPrint("\a\b\b %d" % i) sleep(1) self.defaultPrint("\b\b \n") def prepareBoot(self,targetDistr): self.installBootloader(targetDistr) def getTargetDistributive(self,disk,buildermode): if buildermode: return ScratchDistributive(disk,mdirectory="/mnt/install", check=True) else: return PartitionDistributive(disk,mdirectory="/mnt/install", check=True) def applyTemplates(self,directory): """Apply templates for root of system.""" self.clVars.Set("cl_root_path",directory, True) self.clTempl = template(self.clVars) dirsFiles = self.clTempl.applyTemplates() if self.clTempl.getError(): raise InstallError(self.clTempl.getError()) else: return dirsFiles def setInstallDisk(self,disk): if not disk in self.clVars.Get('os_disk_dev'): raise InstallError(_("Wrong target drive name %s"%disk)) else: osdiskload = \ filter(lambda x: (x[1] or x[2] == "extended") and x[0] == disk, zip(self.clVars.Get('os_disk_dev'), self.clVars.Get('os_disk_load'), self.clVars.Get('os_disk_part'))) if len(osdiskload) > 0: if osdiskload[0][2] == "extended": raise InstallError( _("Specified drive '%s' is extended"%disk)) else: raise InstallError( _("Specified drive '%s' mounted to '%s'")% (disk,osdiskload[0][1])) else: self.clVars.Set('os_root_dev',disk,True) def getDeviceByField(self,field,value): """Get device by fields (install load format uuid grub part name)""" return self.getFieldByField('dev',field,value) def getFieldByField(self,resfield,field,value): res = filter(lambda x: x[1] == value, zip(self.clVars.Get('os_disk_%s'%resfield), self.clVars.Get('os_disk_%s'%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 installBootloader(self,target): """Install boot loader Perform grub installation to disk, which has root partition """ 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","/")) # TODO: change hd0 for bootloader install to other disks # may be another parameters pipe.stdin.write("setup (hd0)\n") 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,buildermode=False): """install System by current variable enviroment""" sourceDistr = None targetDistr = None error = None try: targetDistr = self.getTargetDistributive( self.clVars.Get('os_root_dev'),buildermode) distRep = DistributiveRepository('/usr/calculate/share/linux') sourceDistr = distRep.getLastDistributive( march=self.clVars.Get('os_arch_machine'), shortname=self.clVars.Get('os_linux_shortname').lower()) if sourceDistr: # print info 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 self.printSUCCESS(_("Formating partition")) targetDistr.formatPartition( self.getFieldByField("format","install","/") or "reiserfs") # install distributive self.printSUCCESS(_("Unpacking system image into target")) targetDistr.installFrom(sourceDistr) self.printOK("Unpacking complete") # join templates self.printSUCCESS(_("Update config")) self.applyTemplates(targetDistr.getDirectory()) # change boot config self.printSUCCESS(_("Prepare system for reboot")) self.prepareBoot(targetDistr) else: self.printWARNING("No update available.") return False except (InstallError,DistributiveError),e: error = e except KeyboardInterrupt,e: self.defaultPrint("\n") self.printWARNING("Interrupting the installation") error = _("Installation manually interrupt") try: if self.clTempl: self.clTempl.closeFiles() if sourceDistr: self.printSUCCESS(_("Releasing source distributive")) sourceDistr.close() if targetDistr: self.printSUCCESS(_("Unmount target system volume")) targetDistr.close() except (InstallError,DistributiveError),e: error = "%s\n%s" % (str(error),_("Unmouting error")) except KeyboardInterrupt,e: pass if error: for line in filter(lambda x: x,str(error).split('\n')): self.printERROR(line) return False self.printSUCCESS(_("System successfully installed")) return False def setAllLocaleByLang(self,lang): """Set all locale variable by specified lang""" locale = clLocale() if not locale.isLangExists(lang): return False self.clVars.Set('os_locale_lang',lang, True) self.clVars.Set('os_locale_locale', locale.getFieldByLang('locale',lang), True) self.clVars.Set('os_locale_language', locale.getFieldByLang('language',lang), True) self.clVars.Set('os_locale_keymap', locale.getFieldByLang('keymap',lang), True) self.clVars.Set('os_locale_dumpkeys', locale.getFieldByLang('dumpkeys_charset',lang), True) self.clVars.Set('os_locale_xkb', locale.getFieldByLang('xkblayout',lang), True) return True