#-*- 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 cl_builder, __app__, __version__ from cl_opt import opt from cl_share_cmd import share_cmd from cl_vars_share import varsShare,clLocale from cl_utils import _toUNICODE, getSquashList import os from os import path from os import access,R_OK import re import sys from types import ListType from cl_template import iniParser from cl_lang import lang lang().setLanguage(sys.modules[__name__]) OSSYSTEM_LIST=sorted(varsShare.dictNameSystem.keys()) COMPRESS_METHODS=getSquashList() DEFAULT_COMPRESS="xz" if "xz" in COMPRESS_METHODS else "gzip" DESCRIPTION = _("Calculate Linux image builder") CMD_OPTIONS = [{'shortOption':"p", 'longOption':"profile", 'optVal':"PROFILE", 'help':_("system profile") }, {'longOption':"compress", 'optVal':"COMPRESS", 'type':'choice', 'choices':COMPRESS_METHODS, 'default':DEFAULT_COMPRESS, 'help':_("squashfs compress method. " "{varname} may be {values}.")\ .format(varname="COMPRESS", values=_("{list} or {last}. %default by default")\ .format( list=", ".join(COMPRESS_METHODS[:-1]), last=COMPRESS_METHODS[-1]) if len(COMPRESS_METHODS)>1 else _("only {0}").format(COMPRESS_METHODS[0])) }, {'longOption':'live', 'help':_("use only live templates on startup") }, {'longOption':'noisohybrid', 'help':_("create the iso image without isohybrid") }, {'longOption':'lang', 'shortOption':'l', 'optVal':"LANG", 'help':_("language by default") }, {'longOption':'timezone', 'optVal':"TIMEZONE", 'help':_("timezone by default") }, {'longOption':'keep-tree', 'help':_("keep portage tree in image") }, {'longOption':"set"}, {'shortOption':"f", 'longOption':"force", 'help':_("no questions during assemble") }] USAGE = _("%prog [options] iso|squash") class image_cmd(share_cmd): """Class for work with cl_builder 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, usage=USAGE, option_list= CMD_OPTIONS + opt.variable_view + opt.color_control, check_values=self.checkOpts) self.logicObj = cl_builder() self.commands = ["iso","squash"] self.envFile = "/etc/calculate/assemble.env" #self.optionsInitrdIncompatible = ["o","no_clean","m","mdadm","lvm", # "k", "e","dmraid","c","ebuild", # "symlink"] def __sectionName(self): """Get section name of assemble.env by shortname and arch""" return self.logicObj.clVars.Get('os_builder_profile') def isScratch(self,showError=True): """Detect scartch system""" if not os.access(self.envFile,os.R_OK) \ or not self.logicObj.clVars.Get('cl_builder_path'): if self.logicObj.clVars.Get('os_scratch') == 'on': return True else: if showError: self.printERROR( _("You should boot the system in Builder mode") + " " + _("or build the system")) return False return False def isAssemble(self,showError=True): """Detect system assembling""" if self.logicObj.clVars.Get('cl_builder_distro') \ and self.logicObj.clVars.Get('cl_builder_path'): inidata = iniParser(self.envFile) res = inidata.getVar(self.__sectionName(),"cl_assemble_step_world", checkExistVar=True) if not res[0] or not "finish" in _toUNICODE(res[1]).encode('utf-8'): if showError: self.printERROR(_("System assemble not completed.")) return False return True else: return False def checkOpts(self, values, args): """Check values all specified options.""" if len(args) > 1: self.optobj.error(_("unrecognized option") + ": %s"% "".join(args)) if len(args) < 1 and not values.v: self.optobj.error(_("missing command argument")) if args and not args[0] in self.commands: self.optobj.error(_("invalid command: '%(cmd)s' " "(choose from %(variants)s)")% {'cmd':args[0], 'variants':", ".join(map(lambda x:"'%s'"%x,self.commands))}) # for work with v param if args: self.logicObj.clVars.Set('cl_action',args[0],True) if values.p: if self.isScratch(False): self.optobj.error(_("'--profile' not used in scratch mode")) # set compression for squashfs if values.compress: if not self.logicObj.setCompression(values.compress): sys.exit(1) if values.live: self.logicObj.setLive(values.live) if not self.isScratch(False) \ and self.logicObj.clVars.Get('cl_builder_distro'): if not self.logicObj.setAssembleData(values.p,values.v): sys.exit(1) if not self.logicObj.clVars.Get('cl_builder_distro'): if not self.isRoot() or not self.isScratch(True): sys.exit(1) if values.noisohybrid: self.logicObj.clVars.Set('cl_builder_isohybrid_set','off',True) if values.keep_tree: self.logicObj.clVars.Set('cl_builder_tree','on',True) if args and args[0] == "squash": self.logicObj.clVars.Set('cl_builder_iso_path','/mnt/flash',True) if values.timezone and not self.logicObj.setTimezone(values.timezone): sys.exit(1) if values.l and not self.logicObj.setLang(values.l): sys.exit(1) self.optobj.checkVarSyntax(values) return (values, args) def performActionByCommand(self,options,args): action = {'iso':self.makeIso, 'squash':self.makeSquash} action[args[0]](options) def makeIso(self,options): """Make iso""" if not self.logicObj.makeIsoImage(options.f): return False return True def makeSquash(self,options): """Make squash (rescratch)""" if not self.logicObj.makeRescratch(options.f): return False return True def createImagePaths(self): """Create path, which contains images""" imagepath = self.logicObj.clVars.Get('cl_builder_image_path') if type(imagepath) != ListType: imagepath = [imagepath] for pathname in imagepath: try: if not path.lexists(pathname): os.makedirs(pathname,mode=0755) except: pass def checkChrootStatus(self): if self.logicObj.clVars.Get('cl_chroot_status') == 'off': return True else: self.printERROR(_("This program cannot be run from Scratch layer")) return False