Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
f24398f
Draft implementation for a "launch" script using the env_prototype
BigRoy Mar 13, 2018
7620fd3
Created fusion dir for scripts, moves switch_and_submit in dir
aardschok Mar 16, 2018
d33e471
Added assertion, changed signature order
aardschok Mar 16, 2018
2533166
initial draft of logic for submit_switch_job
aardschok Mar 16, 2018
7d6754a
Added slapcomp support
aardschok Mar 19, 2018
e683347
changed to context plugin, fixed missing keys for job
aardschok Mar 19, 2018
b240c41
Added support for slap comp
aardschok Mar 19, 2018
77dab46
Removed unused import
aardschok Mar 21, 2018
f12152b
Improved switch_and_submit, always abspath, if no path fetch from comp
aardschok Mar 21, 2018
cb30677
Removed constant, fixed format_version_folder, renamed function
aardschok Mar 21, 2018
55d58ab
Merged publish_local logic in switch, use api.publish for publish
aardschok Mar 21, 2018
e53c2d4
Removed argparse from module
aardschok Mar 21, 2018
1208f8d
Cosmetics
aardschok Mar 22, 2018
5dbf143
Job dependend on last submitted, changed get_script function, update env
aardschok Mar 22, 2018
8de8984
Refactored __main__
aardschok Mar 22, 2018
1e0d4b7
Improved format_version_folder logic, explicit error print in publishing
aardschok Mar 22, 2018
e7bf90e
Removed debug print, removed astrixes from update()
aardschok Mar 22, 2018
abd6ff9
Extended docstrings
aardschok Mar 22, 2018
7c5c295
Implemented get_script_dir method
aardschok Mar 22, 2018
7af871d
refactored context[:] to list(context) due to slice issue in Py36
aardschok Mar 22, 2018
4c9a6f5
Added module for deadline switching of comps
aardschok Mar 22, 2018
025ac39
Fixed typo, fetch of machine limit from depending job
aardschok Mar 22, 2018
8aa9799
new line at end of file
aardschok Mar 22, 2018
442eea5
Refactored approach of getting machine limit
aardschok Mar 22, 2018
8d0b0c4
Created backwards compatibility, added message if key is missing
aardschok Mar 22, 2018
f890253
Improved the get_machine_limit function
aardschok Mar 22, 2018
18afd8a
Updated docstrings
aardschok Mar 22, 2018
ac60222
Fixed error
aardschok Mar 22, 2018
87bb43f
Refactored function names, setting current comp to None when closing
aardschok Mar 23, 2018
86f4c9c
Removed __init__ modules from script folder
aardschok Mar 23, 2018
71f2293
Update environment to ensure session and environment are in sync
aardschok Mar 23, 2018
2f1b08a
Updated docstring, fixed type, updated print
aardschok Mar 26, 2018
b6a1e69
Added more explicit comment and docstrings
aardschok Mar 26, 2018
28a779b
Make switch logic more central
aardschok Mar 26, 2018
b0e8d44
Updated _on_switch, and cosmetics
aardschok Mar 26, 2018
75859b1
Moved switch logic to lib, module redundant
aardschok Mar 26, 2018
09911b2
Updated switch logic, removed rendudant function, added submit function
aardschok Mar 26, 2018
0f8f03d
renamed variable
aardschok Mar 26, 2018
d5eacb2
improved error handling, added create_new_filepath
aardschok Mar 26, 2018
6d9c056
Removed the self variable, remvoed create_new_filepath
aardschok Mar 26, 2018
a587b42
Fixed import error, added file filter in brows
aardschok Mar 26, 2018
887ec7a
Removed unused argument
aardschok Mar 26, 2018
a51c350
Raise error if file is invalid
aardschok Mar 26, 2018
155235e
Fixed get_script, retrieve suspendPublishJob correct
aardschok Mar 27, 2018
5b2708f
Set initialStatus active as it has a dependency, minor cosmetics
aardschok Mar 27, 2018
5a8d93f
Added docstrings, removed slapcomp from new filename
aardschok Mar 28, 2018
290fa33
refactored out "slapcomp", fixed typo
aardschok Mar 28, 2018
f36d32c
Merge pull request #2 from BigRoy/app_env
aardschok Mar 29, 2018
ab33232
Added fusion 9 and fusion console node env jsons
aardschok Mar 29, 2018
e22f951
update environment through avalon.api
aardschok Mar 29, 2018
0201333
Removed debug prints
aardschok Mar 29, 2018
0408539
Added comment to job
aardschok Mar 29, 2018
ff8f3f7
Moved api.update_current_task to script
aardschok Mar 30, 2018
1a8c8d9
Script to override GlobalJobPreLoad of Deadline
aardschok Apr 4, 2018
0125fc0
Removed environment folder and jsons
aardschok Apr 4, 2018
ec4c164
Added AVALON_TOOLS to launch in correct environment
aardschok Apr 6, 2018
1044cbc
Added function to collect maya version and yeti if loaded, added AVAL…
aardschok Apr 6, 2018
3697a1f
Removed fixed paths, start process through env_prototype, fix error i…
aardschok Apr 6, 2018
1a5cf73
Added AVALON_TOOLS
aardschok Apr 6, 2018
1d88db8
Added AVALON_TOOLS
aardschok Apr 6, 2018
0dc9454
Merge branch 'FUS-32' of https://github.com/aardschok/colorbleed-conf…
aardschok Apr 6, 2018
75c08be
removed workaround
aardschok Apr 6, 2018
05af7de
Merge branch 'FUS-32' of https://github.com/aardschok/colorbleed-conf…
aardschok Apr 6, 2018
e49306c
Moved \n ot end of string
aardschok Apr 6, 2018
0a5ad41
Launch action through env_prototype
aardschok Apr 6, 2018
fb2f1ce
env prototype set in globals
aardschok Apr 6, 2018
d7ec1db
env prototype set in globals
aardschok Apr 6, 2018
302cbfe
fixed issue with incomplete environment
aardschok Apr 9, 2018
38eeea8
added assertion, get tools from environment
aardschok Apr 9, 2018
6176cf9
Created more elegant way to retriev script file
aardschok Apr 9, 2018
67a3fe7
added assert for AVALON_TOOLS, removed redundant function
aardschok Apr 9, 2018
44e58c2
launch now fully relies on env_prototype
aardschok Apr 9, 2018
a6b55d4
Refactored to match signature of env_prototype.which
aardschok Apr 9, 2018
fda2aaa
renamved env_prototype to acre
aardschok Apr 10, 2018
9e9edb0
renamved env_prototype to acre
aardschok Apr 10, 2018
9d21bef
renamved env_prototype to acre
aardschok Apr 10, 2018
e7f6c56
Fixed conflicts in branch
aardschok Apr 10, 2018
ea52a9a
Refactored with env_prototype to acre
aardschok Apr 10, 2018
b4e745b
Refactored back acre, conflict was solved wrong
aardschok Apr 11, 2018
9cc99ef
Added pretty error message
aardschok Apr 11, 2018
bceaa25
Explicitlty set tool combination and TOOL_ENV
aardschok Apr 13, 2018
c4d703e
Replace env logic with acre, fixed type, print new comp name
aardschok Apr 13, 2018
3a1b1f6
Using print instead of log, print server found and fusion found
aardschok Apr 13, 2018
6911d56
Improved traceback for deadline
aardschok Apr 13, 2018
c0c3011
Delete launch files
aardschok Apr 13, 2018
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
127 changes: 124 additions & 3 deletions colorbleed/fusion/lib.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import sys
import os
import re
import logging
import traceback

import avalon.fusion
from avalon import api, io, pipeline

import colorbleed.lib as colorbleed

self = sys.modules[__name__]
self._project = None

log = logging.getLogger(__name__)


def update_frame_range(start, end, comp=None, set_render_range=True):
Expand Down Expand Up @@ -38,3 +43,119 @@ def update_frame_range(start, end, comp=None, set_render_range=True):

with avalon.fusion.comp_lock_and_undo_chunk(comp):
comp.SetAttrs(attrs)


def get_next_version_folder(folder):
"""Format a version folder based on the filepath

Assumption here is made that, if the path does not exists the folder
will be "v001"

Args:
folder: file path to a folder

Returns:
str: new version folder name
"""

version_int = 1
if os.path.isdir(folder):
re_version = re.compile("v\d+")
versions = [i for i in os.listdir(folder) if re_version.match(i)
and os.path.isdir(os.path.join(folder, i))]
if versions:
# ensure the "v" is not included and convert to ints
int_versions = [int(v[1:]) for v in versions]
version_int += max(int_versions)

return "v{:03d}".format(version_int)


def update_savers(comp, session, project):
"""Update all savers of the current comp to ensure the output is correct

Args:
comp (object): current comp instance
session (dict): the current Avalon session
project (dict): the project document from the database

Returns:
None
"""

template = project["config"]["template"]["work"]
template_work = pipeline._format_work_template(template, session)

render_dir = os.path.join(os.path.normpath(template_work), "renders")
version_folder = get_next_version_folder(render_dir)
renders_version = os.path.join(render_dir, version_folder)

comp.Print("New renders to: %s\n" % render_dir)

with avalon.fusion.comp_lock_and_undo_chunk(comp):
savers = comp.GetToolList(False, "Saver").values()
for saver in savers:
filepath = saver.GetAttrs("TOOLST_Clip_Name")[1.0]
filename = os.path.basename(filepath)
new_path = os.path.join(renders_version, filename)
saver["Clip"] = new_path


def switch(asset_name):
"""Switch the current containers of the comp to the other asset (shot)

Args:
asset_name (str): name of the asset (shot)

Returns:
comp (PyObject): the comp instance

"""

assert asset_name, "Function requires asset name"

host = api.registered_host()
assert host, "Host must be installed"

# Get current project
project = io.find_one({"type": "project",
"name": api.Session["AVALON_PROJECT"]})

# Assert asset name exists
# It is better to do this here then to wait till switch_shot does it
asset = io.find_one({"type": "asset", "name": asset_name})
assert asset, "Could not find '%s' in the database" % asset_name

# Use the current open comp
current_comp = avalon.fusion.get_current_comp()
assert current_comp is not None, "Could not find current comp"

containers = list(host.ls())
assert containers, "Nothing to update"

representations = []
for container in containers:
try:
representation = colorbleed.switch_item(container,
asset_name=asset_name)
representations.append(representation)
log.debug(str(representation["_id"]) + "\n")
except Exception as e:
msg = traceback.format_stack(e)
log.debug("Error in switching! %s\n" % msg)

log.info("Switched %i Loaders of the %i\n" % (len(representations),
len(containers)))
# Updating frame range
log.debug("Updating frame range ..\n")
version_ids = [r["parent"] for r in representations]
versions = io.find({"type": "version", "_id": {"$in": version_ids}})
versions = list(versions)

start = min(v["data"]["startFrame"] for v in versions)
end = max(v["data"]["endFrame"] for v in versions)

update_frame_range(start, end, comp=current_comp)
update_savers(current_comp, api.Session, project)

return current_comp
38 changes: 19 additions & 19 deletions colorbleed/launcher_actions.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import os
from avalon import api, lib, pipeline

from avalon import api, pipeline, lib

import acre


class FusionRenderNode(api.Action):

name = "fusionrendernode9"
name = "fusionrendernode"
label = "F9 Render Node"
icon = "object-group"
order = 997
Expand All @@ -26,16 +29,17 @@ def process(self, session, **kwargs):

"""

# Update environment with session
env = os.environ.copy()
env.update(session)
# Update environment with session and the current environment
tools_env = acre.get_tools(["global", "fusionnode9"])
env = acre.compute(tools_env)
env = acre.merge(env, current_env=dict(os.environ))

# Get executable by name
app = lib.get_application(self.name)
env.update(app["environment"])
executable = lib.which(app["executable"])
executable = acre.which(self.name, env)
if not executable:
raise ValueError("Unable to find executable %s" % self.name)

return lib.launch(executable=executable, args=[], environment=env)
return acre.launch(executable=executable, args=[], environment=env)


class VrayRenderSlave(api.Action):
Expand Down Expand Up @@ -63,20 +67,16 @@ def process(self, session, **kwargs):
"""

# Update environment with session
env = os.environ.copy()
env.update(session)
tools_env = acre.get_tools(["global", "maya2018", "vrayrenderslave"])
env = acre.compute(tools_env)
env = acre.merge(env, current_env=dict(os.environ))

# Get executable by name
app = lib.get_application(self.name)
env.update(app["environment"])
executable = lib.which(app["executable"])
executable = acre.which("vray", env)

# Run as server
arguments = ["-server", "-portNumber=20207"]

return lib.launch(executable=executable,
args=arguments,
environment=env)
args = ["-server", "-portNumber=20207"]
return acre.launch(executable=executable, args=args, environment=env)


def register_launcher_actions():
Expand Down
2 changes: 0 additions & 2 deletions colorbleed/plugins/fusion/publish/collect_comp.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import os

import pyblish.api

from avalon import fusion
Expand Down
29 changes: 16 additions & 13 deletions colorbleed/plugins/fusion/publish/publish_image_sequences.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,19 @@
from colorbleed.action import get_errored_plugins_from_data


def _get_script():
def _get_script_dir():
"""Get path to the image sequence script"""

# todo: use a more elegant way to get the python script

try:
from colorbleed.scripts import publish_filesequence
except Exception:
raise RuntimeError("Expected module 'publish_imagesequence'"
"to be available")
import colorbleed
config_dir = os.path.dirname(colorbleed.__file__)
script_dir = os.path.join(config_dir, "scripts")
except ImportError:
raise RuntimeError("This is a bug")

module_path = publish_filesequence.__file__
if module_path.endswith(".pyc"):
module_path = module_path[:-len(".pyc")] + ".py"
assert os.path.isdir(script_dir), "Config is incomplete"
script_dir = script_dir.replace(os.sep, "/")

return module_path
return script_dir


class PublishImageSequence(pyblish.api.InstancePlugin):
Expand Down Expand Up @@ -73,7 +70,13 @@ def process(self, instance):
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = subprocess.SW_HIDE

process = subprocess.Popen(["python", _get_script(),
# Get script
script_dir = _get_script_dir()
script = os.path.join(script_dir, "publish_imagesequence.py")
assert os.path.isfile(script), ("Config incomplete, missing "
"`script/publish_imagesequence.py`")

process = subprocess.Popen(["python", script,
"--paths", path],
bufsize=1,
stdout=subprocess.PIPE,
Expand Down
22 changes: 9 additions & 13 deletions colorbleed/plugins/fusion/publish/submit_deadline.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def process(self, instance):

# Collect all saver instances in context that are to be rendered
saver_instances = []
for instance in context[:]:
for instance in list(context):
if not self.families[0] in instance.data.get("families"):
# Allow only saver family instances
continue
Expand Down Expand Up @@ -117,22 +117,18 @@ def process(self, instance):
payload["JobInfo"]["OutputFilename%d" % index] = filename

# Include critical variables with submission
keys = [
# TODO: This won't work if the slaves don't have accesss to
# these paths, such as if slaves are running Linux and the
# submitter is on Windows.
"PYTHONPATH",
"OFX_PLUGIN_PATH",
"FUSION9_MasterPrefs"
]
environment = dict({key: os.environ[key] for key in keys
if key in os.environ}, **api.Session)
TOOL_ENV = os.getenv("TOOL_ENV")
assert TOOL_ENV, "No environment directory found"

env = api.Session.copy()
env["AVALON_TOOLS"] = "global;fusion9"
env["TOOL_ENV"] = TOOL_ENV

payload["JobInfo"].update({
"EnvironmentKeyValue%d" % index: "{key}={value}".format(
key=key,
value=environment[key]
) for index, key in enumerate(environment)
value=env[key]
) for index, key in enumerate(env)
})

self.log.info("Submitting..")
Expand Down
5 changes: 2 additions & 3 deletions colorbleed/plugins/fusion/publish/validate_unique_subsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ class ValidateUniqueSubsets(pyblish.api.InstancePlugin):

@classmethod
def get_invalid(cls, instance):

context = instance.context
subset = instance.data["subset"]
for other_instance in context[:]:
for other_instance in list(context):
if other_instance == instance:
continue

Expand All @@ -26,4 +25,4 @@ def get_invalid(cls, instance):
def process(self, instance):
invalid = self.get_invalid(instance)
if invalid:
raise RuntimeError("Animation content is invalid. See log.")
raise RuntimeError("Content is invalid. See log.")
28 changes: 18 additions & 10 deletions colorbleed/plugins/global/publish/submit_publish_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,15 @@

def _get_script():
"""Get path to the image sequence script"""
try:
from colorbleed.scripts import publish_filesequence
except Exception as e:
raise RuntimeError("Expected module 'publish_imagesequence'"
"to be available")

module_path = publish_filesequence.__file__
if module_path.endswith(".pyc"):
module_path = module_path[:-len(".pyc")] + ".py"
import colorbleed
configpath = os.path.dirname(colorbleed.__file__)
script = os.path.join(configpath, "scripts", "publish_filesequence.py")
# verify script exists
assert os.path.isfile(script), ("Script `publish_filesequence.py` does not"
"exists")

return module_path
return script


class SubmitDependentImageSequenceJobDeadline(pyblish.api.InstancePlugin):
Expand Down Expand Up @@ -70,7 +68,7 @@ def process(self, instance):
"submission prior to this plug-in.")

subset = instance.data["subset"]
state = instance.data.get("publishJobState", "Suspended")
state = instance.data.get("suspendPublishJob", "Active")
job_name = "{batch} - {subset} [publish image sequence]".format(
batch=job["Props"]["Name"],
subset=subset
Expand Down Expand Up @@ -144,7 +142,13 @@ def process(self, instance):

# Transfer the environment from the original job to this dependent
# job so they use the same environment
TOOL_ENV = os.getenv("TOOL_ENV")
assert TOOL_ENV, "No environment directory found"

environment = job["Props"].get("Env", {})
environment["AVALON_TOOLS"] = "global;python36"
environment["TOOL_ENV"] = TOOL_ENV

payload["JobInfo"].update({
"EnvironmentKeyValue%d" % index: "{key}={value}".format(
key=key,
Expand All @@ -159,3 +163,7 @@ def process(self, instance):
response = requests.post(url, json=payload)
if not response.ok:
raise Exception(response.text)

# Temporary key name, deadlineSubmissionJob was already taken
if instance.data.get("runSlapComp", False):
instance.data["deadlineDependJob"] = response.json()
2 changes: 2 additions & 0 deletions colorbleed/plugins/maya/create/colorbleed_renderglobals.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ def __init__(self, *args, **kwargs):
data["priority"] = 50
data["whitelist"] = False
data["machineList"] = ""
data["runSlapComp"] = False
data["flowFile"] = ""

self.data = data
self.options = {"useSelection": False} # Force no content
Expand Down
Loading