#-*- 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. from cl_builder import __app__, __version__ from cl_kernel import cl_kernel from cl_opt import opt from cl_share_cmd import share_cmd import os from os import path from os import access,R_OK import re import sys from cl_lang import lang lang().setLanguage(sys.modules[__name__]) DESCRIPTION = _("Calculate Linux kernel builder") CMD_OPTIONS = [{'shortOption':"o", 'longOption':"use-own-config", 'help':_("use configuration from the kernel directory") }, {'shortOption':"c", 'longOption':"kernel-config", 'optVal':"FILE", 'help':_("kernel configuration file to use for compilation") }, {'shortOption':"k", 'longOption':"kerneldir", 'optVal':"DIR", 'help':_("location of the kernel sources") }, {'shortOption':"m", 'longOption':"menuconfig", 'help':_("run menuconfig after oldconfig") }, {'longOption':"dmraid", 'help':_("include DMRAID support") }, {'longOption':"lvm", 'help':_("include LVM support") }, { 'longOption':"mdadm", 'help':_("copy /etc/mdadm.conf to initramfs") }, {'longOption':"mrproper", 'help':_("run make mrproper before compilation") }, {'longOption':"no-clean", 'help':_("do not run make clean before compilation") }, {'shortOption':"e", 'longOption':"extraversion", 'optVal':"VER", 'help':_("specify extraversion for the kernel") }, {'longOption':"ebuild", 'help': _("build kernel by ebuild phase (ebuild enviroment needed)")}, {'longOption':"set"}, {'longOption':"initrd", 'help':_("optimize the current initramfs")}, {'longOption':"symlink", 'help': _("set uid symlinks for the current kernel in the boot " "directory")}, {'shortOption':"q", 'help':_("do not display kernel compilation") }] class kernel_cmd(share_cmd): """Class for work with cl_install by console""" def __init__(self): setpos = \ filter(lambda x:x[1].get('longOption')=="set", enumerate(CMD_OPTIONS))[0][0] CMD_OPTIONS[setpos] = opt.variable_set[0] self.optobj = opt(package=__app__, version=__version__, description=DESCRIPTION, option_list= CMD_OPTIONS + opt.variable_view + opt.color_control, check_values=self.checkOpts) self.logicObj = cl_kernel() self.optionsInitrdIncompatible = ["o","no_clean","m", "k", "e","c","ebuild", "symlink"] self.optionsSymlinkIncompatible = ["o","no_clean","m","mdadm","lvm", "e","dmraid","c","ebuild","initrd" ] def checkEnviromentForEbuild(self): """Check current enviroment for ebuild enviroment variables""" missedEnvVar = filter(lambda x:not x in os.environ, ['S','T','D','ROOT','WORKDIR', 'EBUILD_PHASE']) if missedEnvVar: self.optobj.error(_("Failed to read ebuild variables: %s")% ", ".join(missedEnvVar)) def checkOpts(self, values, args): """Check values all specified options.""" if len(args) > 0: self.optobj.error(_("unrecognized option") + ": %s"% "".join(args)) self.logicObj.clVars.Set('cl_action',"kernel",True) if values.ebuild: self.checkEnviromentForEbuild() if values.initrd: self.checkIncompatibleParam("initrd") if values.symlink: self.checkIncompatibleParam("symlink") if values.k: if not self.logicObj._testKernelDirectory(values.k): self.optobj.error("%s:'%s'"% (_("wrong kernel source directory"),values.k)) elif not self.logicObj._testFullKernelDirectory(values.k): self.optobj.error(("%s:'%s'"% (_("in directory of kernel source not enough needed files"), values.k))+"\n"+ _("Probably calculate-sources was " "compiled with USE 'minimal'")) else: self.logicObj.clVars.Set('cl_kernel_src_path',values.k,True) else: if not self.logicObj._testFullKernelDirectory( self.logicObj.clVars.Get('cl_kernel_src_path')): self.optobj.error((_("in default directory of kernel source " "not enough needed files")+"\n"+ _("Probably calculate-sources was " "compiled with USE 'minimal'"))) if values.c and values.o: self.optobj.error("%s: %s"%(_("incompatible options"), self.getStringIncompatibleOptions(["c","o"]))) if values.c: if not path.exists(values.c): self.optobj.error(_("kernel configuration '%s' not found")% values.c) else: configFile = values.c self.logicObj.clVars.Set('cl_kernel_config',configFile,True) elif values.o: if path.exists( path.join(self.logicObj.clVars.Get('cl_kernel_src_path'), ".config")): self.logicObj.clVars.Set('cl_kernel_config', path.join(self.logicObj.clVars.Get('cl_kernel_src_path'), ".config"),True) self.optobj.checkVarSyntax(values) return (values, args) def cleanInitrd(self,options): if not self.logicObj.createInitrd(lvmOpt=options.lvm, dmraidOpt=options.dmraid, mdadmOpt=options.mdadm): self.printERROR(_("Failed to create initramfs")) return False else: self.printSUCCESS(_("Initramfs successfully created")) return True def checkEbuildParam(self,options,phase): return not options.ebuild or os.environ["EBUILD_PHASE"] == phase def makeKernel(self,options): """Run kernel compilation, installation, optimization""" # if set ebuild param check cur EBUILD_PHASE, run kernel compilation if self.checkEbuildParam(options,"compile"): if not self.logicObj.makeKernel(quiet=options.q, showMenuConfig=options.m, noClean=options.no_clean, lvmOpt=options.lvm, dmraidOpt=options.dmraid, mdadmOpt=options.mdadm, mrproper=options.mrproper): self.printERROR(_("Kernel compilation failed")) return False if not self.logicObj.prepareBoot(): self.printERROR(_("Failed to prepare the boot directory")) return False if self.checkEbuildParam(options,"postinst"): if not self.logicObj.installBootFiles(): self.printERROR(_("Failed to install the kernel")) return False if not self.logicObj.createUidSymlinks(): self.printERROR(_("Failed to create uid symlinks")) return False if not self.logicObj.versionMigrate(): self.printERROR(_("Kernel nomenclature update failed")) return False if not self.logicObj.cleanInitrd(): self.printWARNING(_("Initramfs optimization failed")) if not self.logicObj.setKernelForCurrent(): self.printWARNING(_("Failed to modify '%s'")%"/usr/scr/linux") if not options.ebuild: self.printWARNING("!!! "+" !!! ".join([_("WARNING")]*4)+" !!!") self.printWARNING( _("To update modules after kernel building, execute")+ ":") self.printWARNING(" module-rebuild -X rebuild") return True def makeSymlink(self,options): """Set specified kernel to default""" if not self.logicObj.createUidSymlinks(): self.printERROR(_("Failed to create uid symlinks")) return False if not self.logicObj.setKernelForCurrent(): self.printWARNING(_("Failed to modify '%s'")%"/usr/scr/linux") return False if not self.logicObj.versionMigrate(): self.printERROR(_("Kernel nomenclature update failed")) return False self.printSUCCESS(_("The kernel was changed to '%s'")% path.basename(self.logicObj._getNewName("vmlinuz"))) return True