Tagged: template
- This topic has 5 replies, 2 voices, and was last updated 6 years ago by
Leonardo Bernardini.
-
Posted in: Python template system
-
14th September 2019 at 11:31 am #21837
I can’t seem to get the maximum licenses part of the template working. And It’s probably just me screwing up.
I copied over the below lines from the default nuke template into our custom one and set the number of licenses:
self.setMaximumLicenses(4)
self.setLicensesGroup(‘Nuke-licensing’)
but it’s still being run on all nodes.Am I missing something?
14th September 2019 at 1:19 pm #21841Seems fine. Could you post the complete template constructor ?
Also does it works for you on the stock template ? Are you on 9.0.14 right ?14th September 2019 at 1:44 pm #21844I haven’t tried it with the stock template yet. I’ll give that a go, and yes we’re on 9.0.14.
Here’s our custom template (Hope the code inject works):
import os import re import MClientAPI import MTemplateAPI manager = MTemplateAPI.MManager.getUniqueClass() class STUDIO_nuke_template(MTemplateAPI.MTemplate): def __init__(self): MTemplateAPI.MTemplate.__init__(self) self.setID(1100) self.setName('STUDIO_nuke') self.setIconFilename('nuke.png') self.setDescription('Nuke render') self.setMaximumLicenses(4) self.setLicensesGroup('Nuke-licensing') self.setTemplateLogic(MTemplateAPI.kTemplateMultiframe) self.setDefaultPriority(70) self.setDefaultPools('2D_NUKE') ''' Multiframe template specific settings ''' self.multiframe.setEnableFrameCheck(True) self.multiframe.setEnableMovieAssembler(False) self.multiframe.setCanProvideFramesMask(True) self.multiframe.setSupportsRenderLayerFlag(False) ''' Submission form items allocation ''' filePath = MTemplateAPI.MTemplateItemFile('FILEPATH','Nuke script','Specifies the nuke script to render','',0,1,1,'*.nk') envPath = MTemplateAPI.MTemplateItemFile('ENVPATH','Environment file','Specifies the environment file to use','',0,1,1,'*.env') writeNode = MTemplateAPI.MTemplateItemString('WRITENODE','WriteNode','WriteNode','',0,1,1) outputPath = MTemplateAPI.MTemplateItemFolder('OUTPUTPATH','Frames destination','Specifies the frames destination','',0,1,1) self.addSubmissionItem(filePath) self.addSubmissionItem(envPath) self.addSubmissionItem(writeNode) self.addSubmissionItem(outputPath) ''' items mapping to Muster default tags ''' self.addMapping('FILEPATH','job_file') self.addMapping('ENVPATH','job_env') self.addMapping('WRITENODE','job_writeNode') self.addMapping('OUTPUTPATH','output_folder') ''' Windows support ''' self.platformWindows.setPlatformEnabled(True) self.platformWindows.setEnableErrorCheck(True) self.platformWindows.setEnabledByDefault(True) self.platformWindows.setFramesFloating(3) self.platformWindows.setDetectionLogic(MTemplateAPI.kProcessChild) self.platformWindows.setDetectionLogicProcessName('nuke.exe') applicationPath = MTemplateAPI.MTemplateItemFile('EXEPATH','Nuke executable','Path to Nuke render.exe application batch render','C:\\Program Files\\Nuke11.3v5\\Nuke11.3.exe',0,0,1,'*.exe') self.platformWindows.addClientConfigurationItem(applicationPath) startingFolderPath = MTemplateAPI.MTemplateItemFolder('SOFTWAREPATH','Starting folder','Specify the starting folder for the nuke','C:\\Program Files\\Nuke11.3v5',0,0,1) self.platformWindows.addClientConfigurationItem(startingFolderPath) ''' virtual functions overrides ''' def onBuildEnvironment(self, job, chunk, clientTemplatePreferences, existingEnvironment): environment = existingEnvironment envFile = job.attributeGetString(manager.resolveMappingToJob(self.getID(),'ENVPATH')) if os.path.exists(envFile): FILE = open(envFile, 'r') for line in FILE: if '=' in line: envVar = line.rstrip('\n').rstrip('\r').split('=')[0] value = line.rstrip('\n').rstrip('\r').split('=')[1] environment.setValue(envVar, value) FILE.close() return environment def onBuildCommandLine(self, platform, job, chunk, clientTemplatePreferences,instanceNum): renderCmd = ' -F ' + '%.0f' % chunk.getStartFrame() + '-' + '%.0f' % chunk.getEndFrame() renderCmd += ' -X \"' + job.attributeGetString(manager.resolveMappingToJob(self.getID(),'WRITENODE')) + '\"' renderCmd += ' \"' + job.attributeGetString(manager.resolveMappingToJob(self.getID(),'FILEPATH')) + '\"' return renderCmd def onGetApplicationPath(self,job,chunk,clientTemplatePreferences,pathOut): pathOut.setString(clientTemplatePreferences['EXEPATH']) return MTemplateAPI.MTemplateError() def onGetApplicationStartingFolder(self,job,chunk,clientTemplatePreferences,pathOut): pathOut.setString(clientTemplatePreferences['SOFTWAREPATH']) return MTemplateAPI.MTemplateError() def onCheckForSubframeAdvancingString(self,job,chunk,line): return 0 def onCheckForSubframeProgress(self,job,chunk,line, progressOut): return 0 def onCheckForFramesMask(self,job,chunk,line,prefixOut): return 0 def onCheckForFramesMaskForLayer(self,job,chunk,line, prefixOut,layerOut): return 0 def onGetFlagForRenderLayers(self,job,layers): return "" def onCheckLogLine(self,job,chunk,clientTemplatePreferences,line,lineNum,warnings,errors,silencedWarnings,silencedErrors): return MTemplateAPI.MTemplateError() def onCheckLog(self,job,chunk,clientTemplatePreferences,log,warnings,errors,silencedWarnings,silencedErrors): lines = log.split("\n") for idx, val in enumerate(lines): marker = manager.checkForLineParsingOverrides(job,chunk,val,idx) if marker.getType() == MClientAPI.MTextFileMarker.kFileMarkerError: errors.append(marker) elif marker.getType() == MClientAPI.MTextFileMarker.kFileMarkerWarning: warnings.append(marker) elif marker.getType() == MClientAPI.MTextFileMarker.kFileMarkerSilenceError: ''' The builtin parser has a skip rule for this line, do not include it in the warnings/errors but in the silenced errors''' silencedErrors.append(marker) elif marker.getType() == MClientAPI.MTextFileMarker.kFileMarkerSilenceWarning: ''' The builtin parser has a skip rule for this line, do not include it in the warnings/errors but in the silenced warnings''' silencedWarnings.append(marker) else: ''' We have no fixed rule , parse the line according to the template logic ''' baseError = -1 baseWarning = -1 length = -1 baseError = val.lower().find('error') baseWarning = val.lower().find('warning') if baseError != -1: length = len(val)-baseError; marker = MClientAPI.MTextFileMarker(MClientAPI.MTextFileMarker.kFileMarkerError,idx,baseError,length) errors.append(marker) if baseWarning != -1: length = len(val)-baseWarning; marker = MClientAPI.MTextFileMarker(MClientAPI.MTextFileMarker.kFileMarkerWarning,idx,baseWarning,length) warnings.append(marker) if len(errors) > 0 and len(warnings) > 0: return MTemplateAPI.MTemplateError(2,'Errors and warnings reported in the log. Please check the chunk details for a detailed list',MTemplateAPI.MTemplateError.kTemplateErrorTypeError) elif len(errors) > 0: return MTemplateAPI.MTemplateError(2,'Errors reported in the log. Please check the chunk details for a detailed list',MTemplateAPI.MTemplateError.kTemplateErrorTypeError) elif len(warnings) > 0: return MTemplateAPI.MTemplateError(1,'Warning reported in the log. Please check the chunk details for a detailed list',MTemplateAPI.MTemplateError.kTemplateErrorTypeWarning) return MTemplateAPI.MTemplateError() def onCheckExitCode(self,job,chunk,clientTemplatePreferences,exitCode): if exitCode != 0: return MTemplateAPI.MTemplateError(exitCode, 'Exit code %d different from expected 0 value' % exitCode,MTemplateAPI.MTemplateError.kTemplateErrorTypeWarning) return MTemplateAPI.MTemplateError() def onApplicationFinder(self,moduleRegExp,moduleTag): ''' Search nuke ''' moduleTag.setString('Nuke') platform = MClientAPI.GetPlatform() moduleRegExp.setString('Nuke\d+\.\dv\d+.*?') return MTemplateAPI.kTemplateScanModule def onFindApplication(self,basePath,clientTemplatePreferences): pass def onModuleFound(self,moduleExec,modulePath,clientTemplatePreferences): platform = MClientAPI.GetPlatform() basePath = modulePath.getString() baseModule = moduleExec.getString() clientTemplatePreferences['SOFTWAREPATH'] = basePath clientTemplatePreferences['EXEPATH'] = os.path.join(basePath,baseModule) return 1 ''' Create an instance of the template class and install it into the template manager context ''' temp = STUDIO_nuke_template() manager.installPyTemplate(temp)
14th September 2019 at 3:43 pm #21849I tired the stock nuke template and it has the same issue.
Even though I set the maximum licenses to 4 it still renders on all machines in the pool.16th September 2019 at 9:47 am #21930We are checking if there’s a regression bug in the current 9.0.14 , I’ll let you know during the day or tomorrow, but I’m suspecting so.
16th September 2019 at 10:39 am #21933I confirm a regression bug we just fixed, we uploaded a new build for 9.0.14, you can just re-download it from the web site (linux and windows installers are fixed, mac and rasp will come later). You need to reinstall the Dispatcher (or instead of doing a full installation, install it on another machine and replace the MDispatcherCore.dll file after stopping the service).
Thanks for reporting the bug!
-
You must be logged in to reply to this topic.