Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deadline: webservice password #200

Merged
merged 57 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
3b70243
AY-745 - added Deadline credentials to Settings
kalisp Mar 19, 2024
3137d8e
AY-745 - added collector for DL user credentials
kalisp Mar 19, 2024
20d47e5
AY-745 - updated validator for DL connection
kalisp Mar 19, 2024
5ad0d4a
AY-745 - updated validator for DL pools
kalisp Mar 19, 2024
615e6ae
AY-745 - updated validator for expected files
kalisp Mar 19, 2024
28e5834
AY-745 - added authentication credentials to all calls to DL
kalisp Mar 19, 2024
0a9b88a
AY-745 - fix validation
kalisp Mar 19, 2024
56a5f42
Update client/ayon_core/modules/deadline/plugins/publish/help/validat…
kalisp Mar 19, 2024
543ffa9
Update client/ayon_core/modules/deadline/plugins/publish/collect_user…
kalisp Mar 19, 2024
6c6f123
Merge branch 'develop' of https://github.com/ynput/ayon-core into fea…
kalisp Mar 19, 2024
0693d80
Merge remote-tracking branch 'origin/feature/AY-745_Deadline-webservi…
kalisp Mar 19, 2024
209cad6
AY-745 - remove logging
kalisp Mar 19, 2024
7fae6d1
AY-745 - added new system wide Site settings
kalisp Mar 25, 2024
6b0568a
AY-745 - added version to client side
kalisp Mar 26, 2024
12d49cb
AY-745 - added field to carry over deadline info
kalisp Mar 26, 2024
6347e65
AY-745 - explicit cast to tuple
kalisp Mar 26, 2024
5c9fc4a
AY-745 - changed structure
kalisp Mar 26, 2024
68be4d7
AY-745 - changed aproach to get DL to use
kalisp Mar 26, 2024
eca34a9
AY-745 - update to Harmony collector
kalisp Mar 26, 2024
abfcd8b
AY-745 - explicit carry over of DL meta for AbstractCollectRender
kalisp Mar 26, 2024
50ade43
AY-745 - add user credentials to instance
kalisp Mar 26, 2024
7cf416d
AY-745 - refactored class variable
kalisp Mar 26, 2024
6faa5ac
AY-745 - refactored format of credentials
kalisp Mar 26, 2024
2ed1d0f
AY-745 - refactored format of credentials
kalisp Mar 26, 2024
2dac53a
AY-745 - added protection for older DL
kalisp Mar 26, 2024
e604c28
AY-745 - added version for client side
kalisp Mar 26, 2024
569d119
AY-745 - add local filtering
kalisp Mar 26, 2024
b4d5c02
AY-745 - fix retrieval of deadline url
kalisp Mar 26, 2024
1023497
AY-745 - merge develop
kalisp Mar 26, 2024
77c939b
AY-745 - remove unnecessary comment
kalisp Mar 26, 2024
466f940
AY-745 - added todo
kalisp Mar 26, 2024
6bbb956
AY-745 - renamed class
kalisp Mar 26, 2024
2dc3eec
AY-745 - renamed class
kalisp Mar 26, 2024
bef6855
AY-745 - fix passing DL credentials to metadata file
kalisp Mar 26, 2024
ab74098
AY-745 - provide default values for new Settings field
kalisp Apr 3, 2024
50127b9
Refactor name to denote multiple servers
kalisp Apr 4, 2024
766cbd9
Refactor change docstring
kalisp Apr 4, 2024
c4c56f8
AY-747- refactor name of variable
kalisp Apr 5, 2024
26a11a5
AY-747- refactor query default
kalisp Apr 5, 2024
cba1dae
Update client/ayon_core/modules/deadline/plugins/publish/help/validat…
kalisp Apr 5, 2024
4332c50
AY-747- refactor passing of auth
kalisp Apr 5, 2024
5b2a545
Merge branch 'develop' of https://github.com/ynput/ayon-core into fea…
kalisp Apr 5, 2024
f5e24b6
AY-747- update todo
kalisp Apr 5, 2024
70fe7ef
Merge remote-tracking branch 'origin/feature/AY-745_Deadline-webservi…
kalisp Apr 5, 2024
497ce6d
Update client/ayon_core/modules/deadline/plugins/publish/submit_celac…
kalisp Apr 16, 2024
f43fbc2
Use collected host name
kalisp Apr 16, 2024
48a1dc8
Add todo
kalisp Apr 16, 2024
ff2296d
Removed unneeded import
kalisp Apr 16, 2024
4bc5395
Refactor - updated names for default deadline url
kalisp Apr 18, 2024
1525443
Merge branch 'develop' of https://github.com/ynput/ayon-core into fea…
kalisp Apr 18, 2024
e8c48ce
Merge remote-tracking branch 'origin/feature/AY-745_Deadline-webservi…
kalisp Apr 18, 2024
090304a
Refactor - move deadline plugins later
kalisp Apr 18, 2024
fbc0ee6
Fix - get source_instance directly from instance
kalisp Apr 18, 2024
12f56ee
Merge develop
kalisp Apr 30, 2024
5fed3d7
AY-745 - added missed blender for credential collection
kalisp May 3, 2024
22d1837
AY-745 - fixe for cache submissions
kalisp May 3, 2024
004a4fe
Fix order of collect render
kalisp May 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ def get_instances(self, context):
if "review" in instance.families:
# to skip ExtractReview locally
instance.families.remove("review")
instance.deadline = inst.data.get("deadline")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why it has to be stored on the instance?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Theoretically you could use different Deadline servers (and credentials) per instance (one for render, one for cache). Theoretically.


instances.append(instance)
instances_to_remove.append(inst)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ def get_instances(self, context):
if "review" in instance.families:
# to skip ExtractReview locally
instance.families.remove("review")
instance.deadline = inst.data.get("deadline")

# add new instance to the list and remove the original
# instance since it is not needed anymore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,10 @@ def get_instances(self, context):
outputFormat=info[1],
outputStartFrame=info[3],
leadingZeros=info[2],
ignoreFrameHandleCheck=True
ignoreFrameHandleCheck=True,
#todo: inst is not available, must be determined, fix when
#reworking to Publisher
# deadline=inst.data.get("deadline")

)
render_instance.context = context
Expand Down
2 changes: 2 additions & 0 deletions client/ayon_core/modules/deadline/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from .deadline_module import DeadlineModule
from .version import __version__


__all__ = (
"DeadlineModule",
"__version__"
)
26 changes: 17 additions & 9 deletions client/ayon_core/modules/deadline/abstract_submit_deadline.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ def requests_post(*args, **kwargs):
if 'verify' not in kwargs:
kwargs['verify'] = False if os.getenv("OPENPYPE_DONT_VERIFY_SSL",
True) else True # noqa

auth = kwargs.get("auth")
if auth:
kwargs["auth"] = tuple(auth) # explicit cast to tuple
# add 10sec timeout before bailing out
kwargs['timeout'] = 10
return requests.post(*args, **kwargs)
Expand All @@ -70,6 +74,9 @@ def requests_get(*args, **kwargs):
if 'verify' not in kwargs:
kwargs['verify'] = False if os.getenv("OPENPYPE_DONT_VERIFY_SSL",
True) else True # noqa
auth = kwargs.get("auth")
if auth:
kwargs["auth"] = tuple(auth)
# add 10sec timeout before bailing out
kwargs['timeout'] = 10
return requests.get(*args, **kwargs)
Expand Down Expand Up @@ -434,9 +441,7 @@ def process(self, instance):
"""Plugin entry point."""
self._instance = instance
context = instance.context
self._deadline_url = context.data.get("defaultDeadline")
self._deadline_url = instance.data.get(
"deadlineUrl", self._deadline_url)
self._deadline_url = instance.data["deadline"]["url"]

assert self._deadline_url, "Requires Deadline Webservice URL"

Expand All @@ -460,7 +465,8 @@ def process(self, instance):
self.plugin_info = self.get_plugin_info()
self.aux_files = self.get_aux_files()

job_id = self.process_submission()
auth = instance.data["deadline"]["auth"]
job_id = self.process_submission(auth)
self.log.info("Submitted job to Deadline: {}.".format(job_id))

# TODO: Find a way that's more generic and not render type specific
Expand All @@ -473,10 +479,10 @@ def process(self, instance):
job_info=render_job_info,
plugin_info=render_plugin_info
)
render_job_id = self.submit(payload)
render_job_id = self.submit(payload, auth)
self.log.info("Render job id: %s", render_job_id)

def process_submission(self):
def process_submission(self, auth=None):
"""Process data for submission.

This takes Deadline JobInfo, PluginInfo, AuxFile, creates payload
Expand All @@ -487,7 +493,7 @@ def process_submission(self):

"""
payload = self.assemble_payload()
return self.submit(payload)
return self.submit(payload, auth)

@abstractmethod
def get_job_info(self):
Expand Down Expand Up @@ -577,14 +583,15 @@ def assemble_payload(
"AuxFiles": aux_files or self.aux_files
}

def submit(self, payload):
def submit(self, payload, auth):
"""Submit payload to Deadline API end-point.

This takes payload in the form of JSON file and POST it to
Deadline jobs end-point.

Args:
payload (dict): dict to become json in deadline submission.
auth (tuple): (username, password)

Returns:
str: resulting Deadline job id.
Expand All @@ -594,7 +601,8 @@ def submit(self, payload):

"""
url = "{}/api/jobs".format(self._deadline_url)
response = requests_post(url, json=payload)
response = requests_post(url, json=payload,
auth=auth)
if not response.ok:
self.log.error("Submission failed!")
self.log.error(response.status_code)
Expand Down
23 changes: 14 additions & 9 deletions client/ayon_core/modules/deadline/deadline_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,23 @@ class DeadlineModule(AYONAddon, IPluginPaths):

def initialize(self, studio_settings):
# This module is always enabled
deadline_urls = {}
deadline_servers_info = {}
enabled = self.name in studio_settings
if enabled:
deadline_settings = studio_settings[self.name]
deadline_urls = {
url_item["name"]: url_item["value"]
deadline_servers_info = {
url_item["name"]: url_item
for url_item in deadline_settings["deadline_urls"]
}

if enabled and not deadline_urls:
if enabled and not deadline_servers_info:
enabled = False
self.log.warning((
"Deadline Webservice URLs are not specified. Disabling addon."
))

self.enabled = enabled
self.deadline_urls = deadline_urls
self.deadline_servers_info = deadline_servers_info

def get_plugin_paths(self):
"""Deadline plugin paths."""
Expand All @@ -45,13 +45,15 @@ def get_plugin_paths(self):
}

@staticmethod
def get_deadline_pools(webservice, log=None):
def get_deadline_pools(webservice, auth=None, log=None):
"""Get pools from Deadline.
Args:
webservice (str): Server url.
log (Logger)
auth (Optional[Tuple[str, str]]): Tuple containing username,
password
log (Optional[Logger]): Logger to log errors to, if provided.
Returns:
list: Pools.
List[str]: Pools.
Throws:
RuntimeError: If deadline webservice is unreachable.

Expand All @@ -63,7 +65,10 @@ def get_deadline_pools(webservice, log=None):

argument = "{}/api/pools?NamesOnly=true".format(webservice)
try:
response = requests_get(argument)
kwargs = {}
if auth:
kwargs["auth"] = auth
response = requests_get(argument, **kwargs)
except requests.exceptions.ConnectionError as exc:
msg = 'Cannot connect to DL web service {}'.format(webservice)
log.error(msg)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"""
import pyblish.api
from ayon_core.pipeline.publish import KnownPublishError
from ayon_core.pipeline.context_tools import get_current_host_name
kalisp marked this conversation as resolved.
Show resolved Hide resolved


class CollectDeadlineServerFromInstance(pyblish.api.InstancePlugin):
Expand All @@ -15,15 +16,39 @@ class CollectDeadlineServerFromInstance(pyblish.api.InstancePlugin):
# Run before collect_render.
order = pyblish.api.CollectorOrder + 0.005
label = "Deadline Webservice from the Instance"
families = ["rendering", "renderlayer"]
hosts = ["maya"]
targets = ["local"]
families = ["render",
"rendering",
"render.farm",
"renderFarm",
"renderlayer",
"maxrender",
"usdrender",
"redshift_rop",
"arnold_rop",
"mantra_rop",
"karma_rop",
"vray_rop",
"publish.hou",
"image"] # for Fusion

def process(self, instance):
instance.data["deadlineUrl"] = self._collect_deadline_url(instance)
instance.data["deadlineUrl"] = \
instance.data["deadlineUrl"].strip().rstrip("/")
if not "deadline" in instance.data:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use more specific key? e.g. "deadlineServer"?

instance.data["deadline"] = {}

# todo: separate logic should be removed, all hosts should have same
host_name = get_current_host_name()
kalisp marked this conversation as resolved.
Show resolved Hide resolved
kalisp marked this conversation as resolved.
Show resolved Hide resolved
if host_name == "maya":
deadline_url = self._collect_deadline_url(instance)
else:
deadline_url = (instance.data.get("deadlineUrl") or # backwards
instance.data.get("deadline", {}).get("url"))
kalisp marked this conversation as resolved.
Show resolved Hide resolved
if deadline_url:
instance.data["deadline"]["url"] = deadline_url.strip().rstrip("/")
else:
instance.data["deadline"]["url"] = instance.context.data["deadline"]["defaultDeadline"] # noqa
self.log.debug(
"Using {} for submission.".format(instance.data["deadlineUrl"]))
"Using {} for submission".format(instance.data["deadline"]["url"]))

def _collect_deadline_url(self, render_instance):
# type: (pyblish.api.Instance) -> str
Expand All @@ -49,8 +74,8 @@ def _collect_deadline_url(self, render_instance):
["project_settings"]
["deadline"]
)

default_server = render_instance.context.data["defaultDeadline"]
default_server = (render_instance.context.data["deadline"]
["defaultDeadline"])
# QUESTION How and where is this is set? Should be removed?
instance_server = render_instance.data.get("deadlineServers")
if not instance_server:
Expand All @@ -66,7 +91,7 @@ def _collect_deadline_url(self, render_instance):

default_servers = {
url_item["name"]: url_item["value"]
for url_item in deadline_settings["deadline_urls"]
for url_item in deadline_settings["deadline_servers_info"]
}
project_servers = (
render_instance.context.data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ class CollectDefaultDeadlineServer(pyblish.api.ContextPlugin):
# Run before collect_deadline_server_instance.
order = pyblish.api.CollectorOrder + 0.0025
label = "Default Deadline Webservice"

pass_mongo_url = False
targets = ["local"]

def process(self, context):
try:
Expand All @@ -33,15 +32,17 @@ def process(self, context):
deadline_settings = context.data["project_settings"]["deadline"]
deadline_server_name = deadline_settings["deadline_server"]

deadline_webservice = None
dl_server_info = None
if deadline_server_name:
deadline_webservice = deadline_module.deadline_urls.get(
dl_server_info = deadline_module.deadline_servers_info.get(
deadline_server_name)

default_deadline_webservice = deadline_module.deadline_urls["default"]
deadline_webservice = (
deadline_webservice
or default_deadline_webservice
)
if dl_server_info:
deadline_url = dl_server_info["value"]
else:
default_dl_server_info = deadline_module.deadline_servers_info[0]
deadline_url = default_dl_server_info["value"]

context.data["defaultDeadline"] = deadline_webservice.strip().rstrip("/") # noqa
context.data["deadline"] = {}
context.data["deadline"]["defaultDeadline"] = (
kalisp marked this conversation as resolved.
Show resolved Hide resolved
deadline_url.strip().rstrip("/"))
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
"""Collect user credentials

Requires:
context -> project_settings
instance.data["deadline"]["url"]

Provides:
instance.data["deadline"] -> require_authentication (bool)
instance.data["deadline"] -> auth (tuple (str, str)) -
(username, password) or None
"""
import pyblish.api

from ayon_api import get_server_api_connection
from ayon_core.modules.deadline.deadline_module import DeadlineModule
from ayon_core.modules.deadline import __version__


class CollectDeadlineUserCredentials(pyblish.api.InstancePlugin):
"""Collects user name and password for artist if DL requires authentication
"""
order = pyblish.api.CollectorOrder + 0.200
label = "Collect Deadline User Credentials"

targets = ["local"]
hosts = ["aftereffects",
"fusion",
"harmony",
"nuke",
"maya",
"max",
"houdini"]

families = ["render",
"rendering",
"render.farm",
"renderFarm",
"renderlayer",
"maxrender",
"usdrender",
"redshift_rop",
"arnold_rop",
"mantra_rop",
"karma_rop",
"vray_rop",
"publish.hou"]

def process(self, instance):
collected_deadline_url = instance.data["deadline"]["url"]
if not collected_deadline_url:
raise ValueError("Instance doesn't have '[deadline][url]'.")
context_data = instance.context.data
deadline_settings = context_data["project_settings"]["deadline"]

deadline_server_name = None
# deadline url might be set directly from instance, need to find
# metadata for it
for deadline_info in deadline_settings["deadline_urls"]:
dl_settings_url = deadline_info["value"].strip().rstrip("/")
if dl_settings_url == collected_deadline_url:
deadline_server_name = deadline_info["name"]
break

if not deadline_server_name:
raise ValueError(f"Collected {collected_deadline_url} doesn't "
"match any site configured in Studio Settings")

instance.data["deadline"]["require_authentication"] = (
deadline_info["require_authentication"]
)
instance.data["deadline"]["auth"] = None

if not deadline_info["require_authentication"]:
return

kalisp marked this conversation as resolved.
Show resolved Hide resolved
local_settings = get_server_api_connection().get_addon_site_settings(
DeadlineModule.name, __version__)
local_settings = local_settings["local_settings"]
for server_info in local_settings:
if deadline_server_name == server_info["server_name"]:
instance.data["deadline"]["auth"] = (server_info["username"],
server_info["password"])
Loading
Loading