diff --git a/openpype/hosts/maya/plugins/create/create_render.py b/openpype/hosts/maya/plugins/create/create_render.py index 76cac5fe25..98ad3114d1 100644 --- a/openpype/hosts/maya/plugins/create/create_render.py +++ b/openpype/hosts/maya/plugins/create/create_render.py @@ -5,6 +5,7 @@ import json import appdirs import requests import six +import sys from maya import cmds import maya.app.renderSetup.model.renderSetup as renderSetup @@ -90,12 +91,20 @@ class CreateRender(plugin.Creator): def __init__(self, *args, **kwargs): """Constructor.""" super(CreateRender, self).__init__(*args, **kwargs) + deadline_settings = get_system_settings()["modules"]["deadline"] + if not deadline_settings["enabled"]: + self.deadline_servers = {} + return project_settings = get_project_settings(Session["AVALON_PROJECT"]) try: - self.deadline_servers = ( + default_servers = deadline_settings["deadline_urls"] + project_servers = ( project_settings["deadline"] ["deadline_servers"] ) + self.deadline_servers = dict( + (k, default_servers[k]) + for k in project_servers if k in default_servers) except AttributeError: # Handle situation were we had only one url for deadline. manager = ModulesManager() @@ -131,11 +140,12 @@ class CreateRender(plugin.Creator): namespace = cmds.namespace(add=namespace_name) # add Deadline server selection list - cmds.scriptJob( - attributeChange=[ - "{}.deadlineServers".format(self.instance), - self._deadline_webservice_changed - ]) + if self.deadline_servers: + cmds.scriptJob( + attributeChange=[ + "{}.deadlineServers".format(self.instance), + self._deadline_webservice_changed + ]) cmds.setAttr("{}.machineList".format(self.instance), lock=True) self._rs = renderSetup.instance() @@ -170,6 +180,7 @@ class CreateRender(plugin.Creator): def _deadline_webservice_changed(self): """Refresh Deadline server dependent options.""" # get selected server + from maya import cmds webservice = self.deadline_servers[ self.server_aliases[ cmds.getAttr("{}.deadlineServers".format(self.instance)) @@ -194,7 +205,7 @@ class CreateRender(plugin.Creator): list: Pools. Throws: RuntimeError: If deadline webservice is unreachable. - + """ argument = "{}/api/pools?NamesOnly=true".format(webservice) try: @@ -202,7 +213,10 @@ class CreateRender(plugin.Creator): except requests.exceptions.ConnectionError as exc: msg = 'Cannot connect to deadline web service' self.log.error(msg) - six.reraise(exc, RuntimeError('{} - {}'.format(msg, exc))) + six.reraise( + RuntimeError, + RuntimeError('{} - {}'.format(msg, exc)), + sys.exc_info()[2]) if not response.ok: self.log.warning("No pools retrieved") return [] @@ -268,6 +282,9 @@ class CreateRender(plugin.Creator): pool_names.append(pool["name"]) self.data["primaryPool"] = pool_names + # We add a string "-" to allow the user to not + # set any secondary pools + self.data["secondaryPool"] = ["-"] + pool_names self.options = {"useSelection": False} # Force no content def _load_credentials(self): @@ -388,6 +405,7 @@ class CreateRender(plugin.Creator): if renderer == "arnold": # set format to exr + cmds.setAttr( "defaultArnoldDriver.ai_translator", "exr", type="string") # enable animation diff --git a/openpype/hosts/maya/plugins/publish/collect_render.py b/openpype/hosts/maya/plugins/publish/collect_render.py index 647a46e240..85afd971c6 100644 --- a/openpype/hosts/maya/plugins/publish/collect_render.py +++ b/openpype/hosts/maya/plugins/publish/collect_render.py @@ -51,6 +51,12 @@ import pyblish.api from avalon import maya, api from openpype.hosts.maya.api.expected_files import ExpectedFiles from openpype.hosts.maya.api import lib +from openpype.api import ( + get_system_settings, + get_project_settings +) + +from avalon.api import Session class CollectMayaRender(pyblish.api.ContextPlugin): @@ -86,6 +92,10 @@ class CollectMayaRender(pyblish.api.ContextPlugin): asset = api.Session["AVALON_ASSET"] workspace = context.data["workspaceDir"] + deadline_settings = get_system_settings()["modules"]["deadline"] + + if deadline_settings["enabled"]: + deadline_url = self._collect_deadline_url(render_instance) self._rs = renderSetup.instance() current_layer = self._rs.getVisibleRenderLayer() maya_render_layers = { @@ -263,6 +273,9 @@ class CollectMayaRender(pyblish.api.ContextPlugin): "vrayUseReferencedAovs") or False } + if deadline_url: + data["deadlineUrl"] = deadline_url + if self.sync_workfile_version: data["version"] = context.data["version"] @@ -392,11 +405,13 @@ class CollectMayaRender(pyblish.api.ContextPlugin): rset = self.maya_layers[layer].renderSettingsCollectionInstance() return rset.getOverrides() - def get_render_attribute(self, attr, layer): + @staticmethod + def get_render_attribute(attr, layer): """Get attribute from render options. Args: - attr (str): name of attribute to be looked up. + attr (str): name of attribute to be looked up + layer (str): name of render layer Returns: Attribute value @@ -405,3 +420,45 @@ class CollectMayaRender(pyblish.api.ContextPlugin): return lib.get_attr_in_layer( "defaultRenderGlobals.{}".format(attr), layer=layer ) + + @staticmethod + def _collect_deadline_url(render_instance): + # type: (pyblish.api.Instance) -> str + """Get Deadline Webservice URL from render instance. + + This will get all configured Deadline Webservice URLs and create + subset of them based upon project configuration. It will then take + `deadlineServers` from render instance that is now basically `int` + index of that list. + + Args: + render_instance (pyblish.api.Instance): Render instance created + by Creator in Maya. + + Returns: + str: Selected Deadline Webservice URL. + + """ + + deadline_settings = get_system_settings()["modules"]["deadline"] + project_settings = get_project_settings(Session["AVALON_PROJECT"]) + try: + default_servers = deadline_settings["deadline_urls"] + project_servers = ( + project_settings["deadline"] + ["deadline_servers"] + ) + deadline_servers = dict( + (k, default_servers[k]) + for k in project_servers if k in default_servers) + except AttributeError: + # Handle situation were we had only one url for deadline. + deadline_url = render_instance.context.data["defaultDeadline"] + deadline_servers = {"default": deadline_url} + + deadline_url = deadline_servers[ + list(deadline_servers.keys())[ + int(render_instance.data.get("deadlineServers")) + ] + ] + return deadline_url diff --git a/openpype/lib/abstract_submit_deadline.py b/openpype/lib/abstract_submit_deadline.py index 4a052a4ee2..5b6e1743e0 100644 --- a/openpype/lib/abstract_submit_deadline.py +++ b/openpype/lib/abstract_submit_deadline.py @@ -415,13 +415,11 @@ class AbstractSubmitDeadline(pyblish.api.InstancePlugin): """Plugin entry point.""" self._instance = instance context = instance.context - self._deadline_url = ( - context.data["system_settings"] - ["modules"] - ["deadline"] - ["DEADLINE_REST_URL"] - ) - assert self._deadline_url, "Requires DEADLINE_REST_URL" + self._deadline_url = context.data.get("defaultDeadline") + self._deadline_url = instance.data.get( + "deadlineUrl", self._deadline_url) + + assert self._deadline_url, "Requires Deadline Webservice URL" file_path = None if self.use_published: diff --git a/openpype/modules/deadline/plugins/publish/collect_default_deadline_server.py b/openpype/modules/deadline/plugins/publish/collect_default_deadline_server.py new file mode 100644 index 0000000000..2bb18486ff --- /dev/null +++ b/openpype/modules/deadline/plugins/publish/collect_default_deadline_server.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +"""Collect default Deadline server.""" +from openpype.modules import ModulesManager +import pyblish.api + + +class CollectDefaultDeadlineServer(pyblish.api.ContextPlugin): + """Collect default Deadline Webservice URL.""" + + order = pyblish.api.CollectorOrder + 0.01 + label = "Default Deadline Webservice" + + def process(self, context): + manager = ModulesManager() + deadline_module = manager.modules_by_name["deadline"] + # get default deadline webservice url from deadline module + context.data["defaultDeadline"] = deadline_module.deadline_url diff --git a/openpype/modules/deadline/plugins/publish/submit_maya_deadline.py b/openpype/modules/deadline/plugins/publish/submit_maya_deadline.py index f8577e24fa..898a257112 100644 --- a/openpype/modules/deadline/plugins/publish/submit_maya_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_maya_deadline.py @@ -36,7 +36,6 @@ from avalon import api import pyblish.api from openpype.hosts.maya.api import lib -from openpype.modules import ModulesManager # Documentation for keys available at: # https://docs.thinkboxsoftware.com @@ -266,10 +265,8 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): self._instance = instance self.payload_skeleton = copy.deepcopy(payload_skeleton_template) - manager = ModulesManager() - deadline_module = manager.modules_by_name["deadline"] # get default deadline webservice url from deadline module - self.deadline_url = deadline_module.deadline_url + self.deadline_url = instance.context.data.get("defaultDeadline") # if custom one is set in instance, use that if instance.data.get("deadlineUrl"): self.deadline_url = instance.data.get("deadlineUrl") @@ -291,8 +288,6 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): "pluginInfo", {}) ) - assert self._deadline_url, "Requires DEADLINE_REST_URL" - context = instance.context workspace = context.data["workspaceDir"] anatomy = context.data['anatomy'] @@ -674,7 +669,7 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): self.log.info( "Submitting tile job(s) [{}] ...".format(len(frame_payloads))) - url = "{}/api/jobs".format(self._deadline_url) + url = "{}/api/jobs".format(self.deadline_url) tiles_count = instance.data.get("tilesX") * instance.data.get("tilesY") # noqa: E501 for tile_job in frame_payloads: @@ -758,7 +753,7 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): self.log.debug(json.dumps(payload, indent=4, sort_keys=True)) # E.g. http://192.168.0.1:8082/api/jobs - url = "{}/api/jobs".format(self._deadline_url) + url = "{}/api/jobs".format(self.deadline_url) response = self._requests_post(url, json=payload) if not response.ok: raise Exception(response.text) @@ -968,7 +963,7 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): payload = self._get_arnold_export_payload(data) self.log.info("Submitting ass export job.") - url = "{}/api/jobs".format(self._deadline_url) + url = "{}/api/jobs".format(self.deadline_url) response = self._requests_post(url, json=payload) if not response.ok: self.log.error("Submition failed!") diff --git a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py b/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py index 1624423715..1baef5c297 100644 --- a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py @@ -4,7 +4,6 @@ import getpass from avalon import api from avalon.vendor import requests -from openpype.modules import ModulesManager import re import pyblish.api import nuke @@ -43,14 +42,12 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin): node = instance[0] context = instance.context - manager = ModulesManager() - deadline_module = manager.modules_by_name["deadline"] # get default deadline webservice url from deadline module - self.deadline_url = deadline_module.deadline_url + deadline_url = instance.context.data["defaultDeadline"] # if custom one is set in instance, use that if instance.data.get("deadlineUrl"): - self.deadline_url = instance.data.get("deadlineUrl") - assert self.deadline_url, "Requires Deadline Webservice URL" + deadline_url = instance.data.get("deadlineUrl") + assert deadline_url, "Requires Deadline Webservice URL" self.deadline_url = "{}/api/jobs".format(deadline_url) self._comment = context.data.get("comment", "") diff --git a/openpype/modules/deadline/plugins/publish/submit_publish_job.py b/openpype/modules/deadline/plugins/publish/submit_publish_job.py index ed838e64ed..19e3174384 100644 --- a/openpype/modules/deadline/plugins/publish/submit_publish_job.py +++ b/openpype/modules/deadline/plugins/publish/submit_publish_job.py @@ -5,7 +5,6 @@ import os import json import re from copy import copy, deepcopy -from openpype.modules import ModulesManager import openpype.api from avalon import api, io @@ -910,10 +909,8 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): } if submission_type == "deadline": - manager = ModulesManager() - deadline_module = manager.modules_by_name["deadline"] # get default deadline webservice url from deadline module - self.deadline_url = deadline_module.deadline_url + self.deadline_url = instance.context.data["defaultDeadline"] # if custom one is set in instance, use that if instance.data.get("deadlineUrl"): self.deadline_url = instance.data.get("deadlineUrl") diff --git a/openpype/modules/deadline/plugins/publish/validate_deadline_connection.py b/openpype/modules/deadline/plugins/publish/validate_deadline_connection.py index 1dba94d822..ff664d9f83 100644 --- a/openpype/modules/deadline/plugins/publish/validate_deadline_connection.py +++ b/openpype/modules/deadline/plugins/publish/validate_deadline_connection.py @@ -1,7 +1,6 @@ import pyblish.api from avalon.vendor import requests -from openpype.modules import ModulesManager import os @@ -14,11 +13,8 @@ class ValidateDeadlineConnection(pyblish.api.InstancePlugin): families = ["renderlayer"] def process(self, instance): - - manager = ModulesManager() - deadline_module = manager.modules_by_name["deadline"] # get default deadline webservice url from deadline module - deadline_url = deadline_module.deadline_url + deadline_url = instance.context.data["defaultDeadline"] # if custom one is set in instance, use that if instance.data.get("deadlineUrl"): deadline_url = instance.data.get("deadlineUrl") diff --git a/openpype/modules/deadline/plugins/publish/validate_expected_and_rendered_files.py b/openpype/modules/deadline/plugins/publish/validate_expected_and_rendered_files.py index ca82c54fb8..2d16bc965d 100644 --- a/openpype/modules/deadline/plugins/publish/validate_expected_and_rendered_files.py +++ b/openpype/modules/deadline/plugins/publish/validate_expected_and_rendered_files.py @@ -6,7 +6,6 @@ from avalon.vendor import requests from openpype.lib.abstract_submit_deadline import requests_get from openpype.lib.delivery import collect_frames -from openpype.modules import ModulesManager class ValidateExpectedFiles(pyblish.api.InstancePlugin): @@ -22,6 +21,7 @@ class ValidateExpectedFiles(pyblish.api.InstancePlugin): allow_user_override = True def process(self, instance): + self.instance = instance frame_list = self._get_frame_list(instance.data["render_job_id"]) for repre in instance.data["representations"]: @@ -129,13 +129,11 @@ class ValidateExpectedFiles(pyblish.api.InstancePlugin): Might be different than job info saved in metadata.json if user manually changes job pre/during rendering. """ - manager = ModulesManager() - deadline_module = manager.modules_by_name["deadline"] # get default deadline webservice url from deadline module - deadline_url = deadline_module.deadline_url + deadline_url = self.instance.context.data["defaultDeadline"] # if custom one is set in instance, use that - if instance.data.get("deadlineUrl"): - deadline_url = instance.data.get("deadlineUrl") + if self.instance.data.get("deadlineUrl"): + deadline_url = self.instance.data.get("deadlineUrl") assert deadline_url, "Requires Deadline Webservice URL" url = "{}/api/jobs?JobID={}".format(deadline_url, job_id)