diff --git a/install/cl_distr.py b/install/cl_distr.py index 556262f..59ea106 100644 --- a/install/cl_distr.py +++ b/install/cl_distr.py @@ -95,6 +95,7 @@ class Distributive(object): mountError = _("Failed to mount") + " %s:\n%s" reLive = re.compile(r"^live[^.]*\.squashfs(\.(\d+))?$",re.S) contentCache = {} + needFormat = True def __init__(self, parent=None): self.childs = [] @@ -1379,3 +1380,30 @@ class ScratchPartitionDistributive(PartitionDistributive): raise e except KeyboardInterrupt,e: raise DistributiveError(_("Keyboard interruption")) + +class PxeDistributive(Distributive): + needFormat = False + + def __init__(self,directory,parent=None): + Distributive.__init__(self,parent=parent) + self.directory = path.join(directory,"calculate") + self.origdir = directory + + def getDirectory(self): + return self.origdir + + def installFrom(self,source, **kwargs): + # make temporary directory for creating iso image + distrTo = self.directory + # getting squash from source + if isinstance(source,IsoDistributive): + if path.exists(self.directory): + removeDir(self.directory) + self._makeDirectory(self.directory) + self.rsync(source.getIsoContentDirectory(),distrTo, + byfile=lambda x:x.startswith('livecd.'), + **kwargs) + else: + raise DistributiveError( + _("Installation for PXE does not support %s"% + source.__class__.__name__)) diff --git a/install/cl_install.py b/install/cl_install.py index 0d3c01d..ba7dce3 100644 --- a/install/cl_install.py +++ b/install/cl_install.py @@ -701,9 +701,10 @@ class Install(color_print): sourceDistr = self.clVars.Get('cl_image') self.setTaskNumber(25) # cmd options - self.startTask(_("Formating partitions"),progress=True) - targetDistr.performFormat() - self.endTask() + if targetDistr.needFormat: + self.startTask(_("Formating partitions"),progress=True) + targetDistr.performFormat() + self.endTask() # install distributive #raise InstallError("Manual stop") self.startTask(_("Unpacking the system image into target"), @@ -718,21 +719,30 @@ class Install(color_print): targetDistr.installFrom(sourceDistr, callbackProgress=self.setProgress, filesnum=filesnum) - targetDistr.convertToDirectory() + if self.clVars.Get('os_install_pxe') == 'off': + targetDistr.convertToDirectory() self.endTask() self.clVars.processRefresh() - if self.clVars.Get('os_install_root_type') != "flash": + if self.clVars.Get('os_install_root_type') != "flash" and \ + self.clVars.Get('os_install_pxe') == 'off': self.afterCopyHDDinstall(targetDistr) else: # join templates - self.startTask( - _("Configure flash installation")) - self.applyTemplatesFlash(targetDistr.getDirectory()) + if self.clVars.Get('os_install_pxe') == 'on': + self.startTask( + _("Configure PXE installation"),progress=True) + self.applyTemplatesFlash('/') + else: + self.startTask( + _("Configure flash installation")) + self.applyTemplatesFlash(targetDistr.getDirectory(), + progress=True) self.endTask() self.closeClTemplate() # change boot config - if self.clVars.Get('os_install_mbr'): + if self.clVars.Get('os_install_mbr') and \ + self.clVars.Get('os_install_pxe') == "off": self.startTask(_("Preparing system for reboot")) self.prepareBoot(targetDistr) self.endTask() diff --git a/install/cl_wsdl_install.py b/install/cl_wsdl_install.py index e80ed56..dddbe6a 100644 --- a/install/cl_wsdl_install.py +++ b/install/cl_wsdl_install.py @@ -73,6 +73,9 @@ class InstallInfo(ClassSerializer): cl_autopartition_table = String cl_autopartition_root_size = String + os_install_pxe = Boolean + os_install_pxe_path = String + Default = Array(String) CheckOnly = Boolean @@ -105,7 +108,8 @@ class Wsdl: from calculate.core.server.baseClass import Basic from calculate.core.server.decorators import Dec - def installCommon(self,sid,info,methodname,initfunc): + def installCommon(self,sid,info,methodname,initfunc, + installFunc="installSystem",humanName=""): """ Install common method """ @@ -131,8 +135,9 @@ class Wsdl: install_meth = type("CommonInstall",(self.Common, cl_install.Install, object), {}) pid = self.startprocess(sid, target=install_meth, - method="installSystem",\ - args_proc = (dv,)) + method=installFunc,\ + method_name=humanName or _("System installing"), + args_proc = (dv,)) returnmess = ReturnedMessage(type = 'pid', message = pid) returnmess.type = "pid" returnmess.message = pid @@ -256,3 +261,42 @@ class Wsdl: brief=params.brief) self.set_cache(sid, 'install_flash', "vars",dv,smart=False) return view + + def install_pxe_vars(self): + dv = cl_install.DataVarsInstall() + dv.importInstall() + dv.flIniFile() + dv.Set('cl_action','system',True) + dv.Set('os_install_pxe','on',True) + dv.addGroup(None, + normal=('cl_image_filename',), + expert=('os_install_pxe_path',), + next_label=_("Install")) + return dv + + @rpc(Integer, InstallInfo, _returns = Array(ReturnedMessage)) + @core_method(category=__('Installation'),title=__('PXE install'), + image='network-server', + gui=True, rights=['installpxe']) + def install_pxe ( self, sid, info): + """ + Install to flash + """ + return self.installCommon(sid,info,'install_pxe', + self.install_pxe_vars, + humanName=_('PXE install')) + + @rpc(Integer, ViewParams,_returns = ViewInfo) + @catchExcept + def install_pxe_view (self, sid, params): + dv = self.get_cache(sid,"install_pxe","vars") + if not dv: + dv = self.install_pxe_vars() + else: + dv.processRefresh() + view = ViewInfo(dv,step=params.step, + expert=params.expert, + brief=params.brief) + self.set_cache(sid, 'install_pxe', "vars",dv,smart=False) + return view + diff --git a/install/variables/action.py b/install/variables/action.py index 710f278..04583b7 100644 --- a/install/variables/action.py +++ b/install/variables/action.py @@ -73,10 +73,9 @@ class VariableAcInstallPxe(ReadonlyVariable): """ Action variable which has value "up" for PXE installation """ - def get_ac_install_pxe(self): + def get(self): + clAction = self.Get('cl_action') + if clAction == 'system' and self.Get('os_install_pxe') == 'on': + return "up" return "" - #clAction = self.Get('cl_action') - #if clAction == 'system' and self.Get('os_install_pxe') == 'on': - # return "up" - #return "" diff --git a/install/variables/distr.py b/install/variables/distr.py index f539b17..41029cd 100644 --- a/install/variables/distr.py +++ b/install/variables/distr.py @@ -27,7 +27,7 @@ from calculate.lib.utils.files import readLinesFile, listDirectory from calculate.lib.variables.linux import Linux from calculate.install.cl_distr import (Distributive,PartitionDistributive, ScratchPartitionDistributive,DistributiveError,FlashDistributive, - MultiPartitions) + MultiPartitions,PxeDistributive) from calculate.lib.cl_lang import setLocalTranslate setLocalTranslate('cl_install3',sys.modules[__name__]) @@ -457,6 +457,8 @@ class VariableClTarget(ReadonlyVariable): isFormat=self.isTrue(isFormat), systemId=systemId, partitionTable=partTable) + elif self.Get('os_install_pxe') == "on": + return PxeDistributive(self.Get('os_install_pxe_path')) elif self.Get('os_install_root_type')=="flash": return FlashDistributive(disk,mdirectory="/mnt/install", check=True, fileSystem=fileSystem, diff --git a/install/variables/system.py b/install/variables/system.py index 420b22c..4e01339 100644 --- a/install/variables/system.py +++ b/install/variables/system.py @@ -418,3 +418,38 @@ class VariableOsGrub2Path(Variable): process(grubInstall,'-v')): return grubInstall return "" + +class VariableOsInstallPxe(ReadonlyVariable): + """ + Installation for PXE loading + """ + type = "boot" + value = "off" + + def check(self,value): + if value == "on": + if self.Get('os_linux_system') != "server": + raise VariableError( + _("PXE installation is available for server only")) + try: + config = cl_template.iniParser('/etc/calculate/calculate.env') + val = config.getVar('server','sr_dhcp_set') + if val.encode('utf-8') == "on": + return + except: + pass + raise VariableError( + _("PXE installation is available with " + "DHCP service configured only")) + +class VariableOsInstallPxePath(Variable): + """ + Path to PXE installation + """ + value = "/var/calculate/pxe" + + opt = ['--pxe-path'] + + def init(self): + self.label = _("Path for installation") + self.help = _("path for PXE installation")