def refresh(self, *args): self.pools.blockSignals(True) self.groups.blockSignals(True) self.pools.clear() self.groups.clear() self.pools.blockSignals(False) self.groups.blockSignals(False) exists = maya.lsattr("id", "avalon.renderglobals") assert len(exists) <= 1, ( "More than one renderglobal exists, this is a bug") if exists: render_globals = exists[0] else: render_globals = maya.create( "renderGlobals", api.Session["AVALON_ASSET"], "mindbender.renderglobals" ) # Store reference for editing self.render_globals = render_globals render_globals = maya.read(render_globals) current_pool = render_globals["pool"] or "none" current_group = render_globals["group"] or "none" url = api.Session["AVALON_DEADLINE"] + "/api/pools" module.log.debug("Requesting pools from %s.." % url) response = requests.get(url) pools = response.json() url = api.Session["AVALON_DEADLINE"] + "/api/groups" module.log.debug("Requesting groups from %s.." % url) response = requests.get(url) groups = response.json() valid_pool = False for index, pool in enumerate(pools): self.pools.insertItem(index, pool) if pool == current_pool: self.pools.setCurrentIndex(index) valid_pool = True valid_group = False for index, group in enumerate(groups): self.groups.insertItem(index, group) if group == current_group: self.groups.setCurrentIndex(index) valid_group = True if not valid_pool: cmds.warning("%s is not a valid pool" % current_pool) if not valid_group: cmds.warning("%s is not a valid pool" % current_group)
def __init__(self, *args, **kwargs): super(CreateRenderGlobals, self).__init__(*args, **kwargs) # We won't be publishing this one self.data["id"] = "avalon.renderglobals" # Get available Deadline pools AVALON_DEADLINE = api.Session["AVALON_DEADLINE"] argument = "{}/api/pools?NamesOnly=true".format(AVALON_DEADLINE) response = requests.get(argument) if not response.ok: self.log.warning("No pools retrieved") pools = [] else: pools = response.json() # We don't need subset or asset attributes self.data.pop("subset", None) self.data.pop("asset", None) self.data.pop("active", None) self.data["suspendPublishJob"] = False self.data["extendFrames"] = False self.data["overrideExistingFrame"] = True self.data["useLegacyRenderLayers"] = True self.data["priority"] = 50 self.data["framesPerTask"] = 1 self.data["whitelist"] = False self.data["machineList"] = "" self.data["useMayaBatch"] = True self.data["primaryPool"] = pools # We add a string "-" to allow the user to not set any secondary pools self.data["secondaryPool"] = ["-"] + pools self.options = {"useSelection": False} # Force no content
def process(self, context): AVALON_DEADLINE = api.Session.get("AVALON_DEADLINE") if AVALON_DEADLINE: # Testing Deadline web-service self.log.info("Testing Deadline Web Service: {}" "".format(AVALON_DEADLINE)) # Check response try: response = requests.get(AVALON_DEADLINE) except requests.ConnectionError: self.log.warning("Fail to connect Deadline Web Service.") else: if (response.ok and response.text.startswith("Deadline Web Service ")): self.log.info("Deadline Web Service on-line.") return else: self.log.warning("Web service did not respond.") else: self.log.warning("No available Deadline Web Service.") # Plan B AVALON_DEADLINE_APP = api.Session.get("AVALON_DEADLINE_APP") if AVALON_DEADLINE_APP: # Testing Deadline command application self.log.info("Testing Deadline Command App: {}" "".format(AVALON_DEADLINE_APP)) if not os.path.isfile(AVALON_DEADLINE_APP): raise Exception("Deadline Command App not exists.") test_cmd = AVALON_DEADLINE_APP + " GetRepositoryVersion" output = subprocess.check_output(test_cmd) if output.startswith(b"Repository Version:"): output = output.decode("utf-8") self.log.info("Deadline Command App on-line, repository " "version: {}".format(output.split("\n")[0])) context.data["USE_DEADLINE_APP"] = True return else: self.log.warning("No available Deadline Command App.") # Got non raise Exception("No available Deadline connection.")
def process(self, instance): AVALON_DEADLINE = api.Session.get("AVALON_DEADLINE", "http://localhost:8082") assert AVALON_DEADLINE is not None, "Requires AVALON_DEADLINE" # Check response response = requests.get(AVALON_DEADLINE) assert response.ok, "Response must be ok" assert response.text.startswith("Deadline Web Service "), \ "Web service did not respond with 'Deadline Web Service'"
def _requests_get(self, *args, **kwargs): """ Wrapper for requests, disabling SSL certificate validation if DONT_VERIFY_SSL environment variable is found. This is useful when Deadline or Muster server are running with self-signed certificates and their certificate is not added to trusted certificates on client machines. WARNING: disabling SSL certificate validation is defeating one line of defense SSL is providing and it is not recommended. """ if 'verify' not in kwargs: kwargs['verify'] = False if os.getenv("PYPE_DONT_VERIFY_SSL", True) else True # noqa return requests.get(*args, **kwargs)
def process(self, instance): from avalon import api from avalon.vendor import requests # From Deadline documentation # https://docs.thinkboxsoftware.com/products/deadline/8.0/ # 1_User%20Manual/manual/rest-jobs.html#job-property-values states = { 0: "Unknown", 1: "Active", 2: "Suspended", 3: "Completed", 4: "Failed", 6: "Pending", } assert "AVALON_DEADLINE" in api.Session, ("Environment variable " "missing: 'AVALON_DEADLINE") AVALON_DEADLINE = api.Session["AVALON_DEADLINE"] url = "{}/api/jobs?JobID=%s".format(AVALON_DEADLINE) for job in instance.data["metadata"]["jobs"]: response = requests.get(url % job["_id"]) if response.ok: data = response.json() assert data, ValueError("Can't find information about " "this Deadline job: " "{}".format(job["_id"])) state = states.get(data[0]["Stat"]) if state in (None, "Unknown"): raise Exception("State of this render is unknown") elif state == "Active": raise Exception("This render is still currently active") elif state == "Suspended": raise Exception("This render is suspended") elif state == "Failed": raise Exception("This render was not successful") elif state == "Pending": raise Exception("This render is pending") else: self.log.info("%s was rendered successfully" % instance) else: raise Exception("Could not determine the current status " " of this render")
def download(self, src, dst): """Download `src` to `dst` Arguments: src (str): URL to source file dst (str): Absolute path to destination file Yields tuple (progress, error): progress (int): Between 0-100 error (Exception): Any exception raised when first making connection """ try: response = requests.get( src, stream=True, auth=requests.auth.HTTPBasicAuth( self.Session["AVALON_USERNAME"], self.Session["AVALON_PASSWORD"] ) ) except requests.ConnectionError as e: yield None, e return with self.tempdir() as dirname: tmp = os.path.join(dirname, os.path.basename(src)) with open(tmp, "wb") as f: total_length = response.headers.get("content-length") if total_length is None: # no content length header f.write(response.content) else: downloaded = 0 total_length = int(total_length) for data in response.iter_content(chunk_size=4096): downloaded += len(data) f.write(data) yield int(100.0 * downloaded / total_length), None try: os.makedirs(os.path.dirname(dst)) except OSError as e: # An already existing destination directory is fine. if e.errno != errno.EEXIST: raise shutil.copy(tmp, dst)
def process(self, context): if not any(i.data.get("deadlineEnable") for i in context): self.log.debug("No instance require deadline.") return AVALON_DEADLINE = api.Session.get("AVALON_DEADLINE") assert AVALON_DEADLINE is not None, "Requires AVALON_DEADLINE" self.log.info("Testing connection: {}".format(AVALON_DEADLINE)) # Check response response = requests.get(AVALON_DEADLINE) assert response.ok, "Response must be ok" assert response.text.startswith("Deadline Web Service "), ( "Web service did not respond with 'Deadline Web Service'")
def process(self, context): # Workaround bug pyblish-base#250 if not contextplugin_should_run(self, context): return AVALON_DEADLINE = api.Session.get("AVALON_DEADLINE", "http://localhost:8082") assert AVALON_DEADLINE is not None, "Requires AVALON_DEADLINE" # Check response response = requests.get(AVALON_DEADLINE) assert response.ok, "Response must be ok" assert response.text.startswith("Deadline Web Service "), ( "Web service did not respond with 'Deadline Web Service'" )
def query(argument): """Lazy wrapper for request.get Args: argument(str): url argument, e.g '<HOST>/api/slaves?NameOnly=true' Returns: list """ response = requests.get(argument) if not response.ok: log.error("Non-script command is not available:'{}'".format(query)) log.error("Details: {}".format(response.text)) result = [] else: result = response.json() return result
def get_deadline_pools(): """Listing Deadline pools via Deadlin web service """ log = logging.getLogger("Deadline") pools = ["none"] AVALON_DEADLINE = avalon.api.Session["AVALON_DEADLINE"] argument = "{}/api/pools?NamesOnly=true".format(AVALON_DEADLINE) try: response = requests.get(argument) except Exception as e: log.warning(str(e)) else: if response.ok: pools = response.json() else: log.warning("No pools retrieved") return pools
def __init__(self, *args, **kwargs): super(CreateRenderGlobals, self).__init__(*args, **kwargs) # We won't be publishing this one self.data["id"] = "avalon.renderglobals" # get pools pools = [] deadline_url = os.environ.get('DEADLINE_REST_URL', None) if deadline_url is None: self.log.warning("Deadline REST API url not found.") else: argument = "{}/api/pools?NamesOnly=true".format(deadline_url) response = requests.get(argument) if not response.ok: self.log.warning("No pools retrieved") else: pools = response.json() self.data["primaryPool"] = pools # We add a string "-" to allow the user to not # set any secondary pools self.data["secondaryPool"] = ["-"] + pools # We don't need subset or asset attributes # self.data.pop("subset", None) # self.data.pop("asset", None) # self.data.pop("active", None) self.data["suspendPublishJob"] = False self.data["extendFrames"] = False self.data["overrideExistingFrame"] = True self.data["useLegacyRenderLayers"] = True self.data["priority"] = 50 self.data["framesPerTask"] = 1 self.data["whitelist"] = False self.data["machineList"] = "" self.data["useMayaBatch"] = True self.options = {"useSelection": False} # Force no content