Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

Support for mutliple installed versions - 3.13 #3605

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
210 changes: 163 additions & 47 deletions igniter/bootstrap_repos.py

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions igniter/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ class OpenPypeVersionNotFound(Exception):
pass


class OpenPypeVersionIncompatible(Exception):
"""OpenPype version is not compatible with the installed one (build)."""
pass


def should_add_certificate_path_to_mongo_url(mongo_url):
"""Check if should add ca certificate to mongo url.

Expand Down
23 changes: 23 additions & 0 deletions openpype/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,3 +443,26 @@ def interactive():
__version__, sys.version, sys.platform
)
code.interact(banner)


@main.command()
@click.option("--build", help="Print only build version",
is_flag=True, default=False)
def version(build):
"""Print OpenPype version."""

from openpype.version import __version__
from igniter.bootstrap_repos import BootstrapRepos, OpenPypeVersion
from pathlib import Path
import os

if getattr(sys, 'frozen', False):
local_version = BootstrapRepos.get_version(
Path(os.getenv("OPENPYPE_ROOT")))
else:
local_version = OpenPypeVersion.get_installed_version_str()

if build:
print(local_version)
return
print(f"{__version__} (booted: {local_version})")
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ def get_job_info(self):
"AVALON_TASK",
"AVALON_APP_NAME",
"OPENPYPE_DEV",
"OPENPYPE_LOG_NO_COLORS"
"OPENPYPE_LOG_NO_COLORS",
"OPENPYPE_VERSION"
]
# Add mongo url if it's enabled
if self._instance.context.data.get("deadlinePassMongoUrl"):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,8 @@ def get_job_info(self):
"AVALON_TASK",
"AVALON_APP_NAME",
"OPENPYPE_DEV",
"OPENPYPE_LOG_NO_COLORS"
"OPENPYPE_LOG_NO_COLORS",
"OPENPYPE_VERSION"
]
# Add mongo url if it's enabled
if self._instance.context.data.get("deadlinePassMongoUrl"):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ def submit_job(self, context, payload, instances, deadline):
# this application with so the Render Slave can build its own
# similar environment using it, e.g. "houdini17.5;pluginx2.3"
"AVALON_TOOLS",
"OPENPYPE_VERSION"
]
# Add mongo url if it's enabled
if context.data.get("deadlinePassMongoUrl"):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def process(self, instance):
# this application with so the Render Slave can build its own
# similar environment using it, e.g. "maya2018;vray4.x;yeti3.1.9"
"AVALON_TOOLS",
"OPENPYPE_VERSION"
]
# Add mongo url if it's enabled
if context.data.get("deadlinePassMongoUrl"):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,8 @@ def process(self, instance):
"AVALON_TASK",
"AVALON_APP_NAME",
"OPENPYPE_DEV",
"OPENPYPE_LOG_NO_COLORS"
"OPENPYPE_LOG_NO_COLORS",
"OPENPYPE_VERSION"
]
# Add mongo url if it's enabled
if instance.context.data.get("deadlinePassMongoUrl"):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ def process(self, instance):
keys = [
"FTRACK_API_USER",
"FTRACK_API_KEY",
"FTRACK_SERVER"
"FTRACK_SERVER",
"OPENPYPE_VERSION"
]
environment = dict({key: os.environ[key] for key in keys
if key in os.environ}, **legacy_io.Session)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,8 @@ def payload_submit(
"PYBLISHPLUGINPATH",
"NUKE_PATH",
"TOOL_ENV",
"FOUNDRY_LICENSE"
"FOUNDRY_LICENSE",
"OPENPYPE_VERSION"
]
# Add mongo url if it's enabled
if instance.context.data.get("deadlinePassMongoUrl"):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
"OPENPYPE_USERNAME",
"OPENPYPE_RENDER_JOB",
"OPENPYPE_PUBLISH_JOB",
"OPENPYPE_MONGO"
"OPENPYPE_MONGO",
"OPENPYPE_VERSION"
]

# custom deadline attributes
Expand Down
132 changes: 122 additions & 10 deletions openpype/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,52 @@
import json
import platform
import uuid
from Deadline.Scripting import RepositoryUtils, FileUtils
import re
from Deadline.Scripting import RepositoryUtils, FileUtils, DirectoryUtils


def get_openpype_version_from_path(path, build=True):
"""Get OpenPype version from provided path.
path (str): Path to scan.
build (bool, optional): Get only builds, not sources

Returns:
str or None: version of OpenPype if found.

"""
# fix path for application bundle on macos
if platform.system().lower() == "darwin":
path = os.path.join(path, "Contents", "MacOS", "lib", "Python")

version_file = os.path.join(path, "openpype", "version.py")
if not os.path.isfile(version_file):
return None

# skip if the version is not build
exe = os.path.join(path, "openpype_console.exe")
if platform.system().lower() in ["linux", "darwin"]:
exe = os.path.join(path, "openpype_console")

# if only builds are requested
if build and not os.path.isfile(exe): # noqa: E501
print(f" ! path is not a build: {path}")
return None

version = {}
with open(version_file, "r") as vf:
exec(vf.read(), version)

version_match = re.search(r"(\d+\.\d+.\d+).*", version["__version__"])
return version_match[1]


def get_openpype_executable():
"""Return OpenPype Executable from Event Plug-in Settings"""
config = RepositoryUtils.GetPluginConfig("OpenPype")
return config.GetConfigEntryWithDefault("OpenPypeExecutable", "")
exe_list = config.GetConfigEntryWithDefault("OpenPypeExecutable", "")
dir_list = config.GetConfigEntryWithDefault(
"OpenPypeInstallationDirs", "")
return exe_list, dir_list


def inject_openpype_environment(deadlinePlugin):
Expand All @@ -25,16 +64,89 @@ def inject_openpype_environment(deadlinePlugin):
print(">>> Injecting OpenPype environments ...")
try:
print(">>> Getting OpenPype executable ...")
exe_list = get_openpype_executable()
openpype_app = FileUtils.SearchFileList(exe_list)
if openpype_app == "":
exe_list, dir_list = get_openpype_executable()
openpype_versions = []
# if the job requires specific OpenPype version,
# lets go over all available and find compatible build.
requested_version = job.GetJobEnvironmentKeyValue("OPENPYPE_VERSION")
if requested_version:
print((">>> Scanning for compatible requested "
f"version {requested_version}"))
install_dir = DirectoryUtils.SearchDirectoryList(dir_list)
if install_dir:
print(f"--- Looking for OpenPype at: {install_dir}")
sub_dirs = [
f.path for f in os.scandir(install_dir)
if f.is_dir()
]
for subdir in sub_dirs:
version = get_openpype_version_from_path(subdir)
if not version:
continue
print(f" - found: {version} - {subdir}")
openpype_versions.append((version, subdir))

exe = FileUtils.SearchFileList(exe_list)
if openpype_versions:
# if looking for requested compatible version,
# add the implicitly specified to the list too.
print(f"Looking for OpenPype at: {os.path.dirname(exe)}")
version = get_openpype_version_from_path(
os.path.dirname(exe))
if version:
print(f" - found: {version} - {os.path.dirname(exe)}")
openpype_versions.append((version, os.path.dirname(exe)))

if requested_version:
# sort detected versions
if openpype_versions:
# use natural sorting
openpype_versions.sort(
key=lambda ver: [
int(t) if t.isdigit() else t.lower()
for t in re.split(r"(\d+)", ver[0])
])
print(("*** Latest available version found is "
f"{openpype_versions[-1][0]}"))
requested_major, requested_minor, _ = requested_version.split(".")[:3] # noqa: E501
compatible_versions = []
for version in openpype_versions:
v = version[0].split(".")[:3]
if v[0] == requested_major and v[1] == requested_minor:
compatible_versions.append(version)
if not compatible_versions:
raise RuntimeError(
("Cannot find compatible version available "
"for version {} requested by the job. "
"Please add it through plugin configuration "
"in Deadline or install it to configured "
"directory.").format(requested_version))
# sort compatible versions nad pick the last one
compatible_versions.sort(
key=lambda ver: [
int(t) if t.isdigit() else t.lower()
for t in re.split(r"(\d+)", ver[0])
])
print(("*** Latest compatible version found is "
f"{compatible_versions[-1][0]}"))
# create list of executables for different platform and let
# Deadline decide.
exe_list = [
os.path.join(
compatible_versions[-1][1], "openpype_console.exe"),
os.path.join(
compatible_versions[-1][1], "openpype_console")
]
exe = FileUtils.SearchFileList(";".join(exe_list))
if exe == "":
raise RuntimeError(
"OpenPype executable was not found " +
"in the semicolon separated list \"" + exe_list + "\". " +
"in the semicolon separated list " +
"\"" + ";".join(exe_list) + "\". " +
"The path to the render executable can be configured " +
"from the Plugin Configuration in the Deadline Monitor.")

print("--- OpenPype executable: {}".format(openpype_app))
print("--- OpenPype executable: {}".format(exe))

# tempfile.TemporaryFile cannot be used because of locking
temp_file_name = "{}_{}.json".format(
Expand All @@ -45,7 +157,7 @@ def inject_openpype_environment(deadlinePlugin):
print(">>> Temporary path: {}".format(export_url))

args = [
openpype_app,
exe,
"--headless",
'extractenvironments',
export_url
Expand Down Expand Up @@ -75,9 +187,9 @@ def inject_openpype_environment(deadlinePlugin):
env["OPENPYPE_HEADLESS_MODE"] = "1"
env["AVALON_TIMEOUT"] = "5000"

print(">>> Executing: {}".format(args))
print(">>> Executing: {}".format(" ".join(args)))
std_output = subprocess.check_output(args,
cwd=os.path.dirname(openpype_app),
cwd=os.path.dirname(exe),
env=env)
print(">>> Process result {}".format(std_output))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,20 @@ Index=0
Default=OpenPype Plugin for Deadline
Description=Not configurable

[OpenPypeInstallationDirs]
Type=multilinemultifolder
Label=Directories where OpenPype versions are installed
Category=OpenPype Installation Directories
CategoryOrder=0
Index=0
Default=C:\Program Files (x86)\OpenPype
Description=Path or paths to directories where multiple versions of OpenPype might be installed. Enter every such path on separate lines.

[OpenPypeExecutable]
Type=multilinemultifilename
Label=OpenPype Executable
Category=OpenPype Executables
CategoryOrder=0
CategoryOrder=1
Index=0
Default=
Description=The path to the OpenPype executable. Enter alternative paths on separate lines.
Expand Down
Loading