Skip to content

Commit

Permalink
Init Maya install
Browse files Browse the repository at this point in the history
  • Loading branch information
LucaScheller committed Mar 21, 2024
1 parent 960075d commit 4881a77
Showing 1 changed file with 378 additions and 0 deletions.
378 changes: 378 additions & 0 deletions .github/scripts/maya.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,378 @@
import argparse
import hashlib
import glob
import logging
import os
import pathlib
import platform
import re
import requests
import shutil
import sidefx
import subprocess
import tarfile
import zipfile


SIDEFX_CLIENT_ID = os.environ.get("SIDEFX_CLIENT_ID", "")
SIDEFX_CLIENT_SECRET_KEY = os.environ.get("SIDEFX_CLIENT_SECRET_KEY", "")


logging.basicConfig(format="%(asctime)s %(message)s", datefmt="%m/%d/%Y %I:%M:%S %p")


def create_github_service(client_id, client_secret_key):
"""Get the GitHub API service
Args:
client_id (str): The client id
client_secret_key (str): The client secret key
Returns:
sidefx.Service: The service
"""
return sidefx.service(
access_token_url="https://www.sidefx.com/oauth2/application_token",
client_id=client_id,
client_secret_key=client_secret_key,
endpoint_url="https://www.sidefx.com/api/",
)


def get_autodesk_platform():
"""Get the active platform usable for SideFX platform API calls
Returns:
str: The active platform
"""
current_platform = platform.system()
if current_platform == "Windows" or current_platform.startswith("CYGWIN"):
return "Windows"
elif current_platform == "Darwin":
return "MacOS"
elif current_platform == "Linux":
return "Linux"
else:
return ""


def download_sidefx_product_release(dir_path, release):
"""Download the release to the directory
Args:
dir_path (str): The target directory
release (dict): The download build release dict
Returns:
str: The file path of the downloaded file
"""
# Download file
download_file_name = release["filename"]
download_file_path = os.path.join(dir_path, download_file_name)
request = requests.get(release["download_url"], stream=True)
if request.status_code == 200:
with open(download_file_path, "wb") as download_file:
request.raw.decode_content = True
shutil.copyfileobj(request.raw, download_file)
else:
raise Exception("Error downloading file!")
# Verify file checksum
# 10.12.23 -> SideFX Bug, this currently fails on Linux
# download_file_hash = hashlib.md5()
# with open(download_file_path, "rb") as download_file:
# for chunk in iter(lambda: download_file.read(4096), b""):
# download_file_hash.update(chunk)
# if download_file_hash.hexdigest() != release["hash"]:
# raise Exception("Checksum does not match!")
return download_file_path


def install_autodesk_product(product, version):
"""Install the latest production release of Houdini
Args:
product (str): The target product name (e.g. houdini, houdini-py39, etc.)
version (str|None): The target product version (e.g. 20.0, 19.5, etc.)
"""
# Connect to SideFX API
logging.info("Connecting to SideFX API")
sidefx_service = create_sidefx_service(SIDEFX_CLIENT_ID, SIDEFX_CLIENT_SECRET_KEY)
sidefx_platform = get_sidefx_platform()
sidefx_product_name = product
sidefx_product_version = version

# Get release data
releases_list = sidefx_service.download.get_daily_builds_list(
product=sidefx_product_name,
version=sidefx_product_version,
platform=sidefx_platform,
only_production=True,
)
target_release = None
if sidefx_platform == "linux":
for release in releases_list:
# Switch to new gcc version starting with H20
if release["version"] == "20.0":
if not release["platform"].endswith("gcc11.2"):
continue
target_release = release
break
else:
for release in releases_list:
target_release = release
break

if not target_release:
raise Exception(
"No Houdini version found for requested version | {}".format(
houdini_version
)
)

target_release_download = sidefx_service.download.get_daily_build_download(
product="houdini",
version=target_release["version"],
build=target_release["build"],
platform=sidefx_platform,
)

# Download latest production release
logging.info(
"Downloading Houdini build {version}.{build}".format(
version=target_release["version"], build=target_release["build"]
)
)
downloads_dir_path = os.path.join(os.path.expanduser("~"), "Downloads")
if not os.path.isdir(downloads_dir_path):
os.makedirs(downloads_dir_path)
houdini_installer_file_path = download_sidefx_product_release(
downloads_dir_path, target_release_download
)
# Install latest production release
logging.info(
"Installing Houdini build {version}.{build}".format(
version=target_release["version"], build=target_release["build"]
)
)
hfs_dir_path = ""
if sidefx_platform == "linux":
# Unpack tar file
with tarfile.open(houdini_installer_file_path) as tar_file:
tar_file.extractall(downloads_dir_path)
os.remove(houdini_installer_file_path)
# Get folder name
houdini_installer_dir_name = target_release_download["filename"]
houdini_installer_dir_name = houdini_installer_dir_name.replace(".tar", "")
houdini_installer_dir_name = houdini_installer_dir_name.replace(".gz", "")
houdini_installer_dir_path = os.path.join(
downloads_dir_path, houdini_installer_dir_name
)
cmd = [
os.path.join(houdini_installer_dir_path, "houdini.install"),
"--auto-install",
"--accept-EULA",
"2021-10-13",
"--install-houdini",
"--no-install-license",
"--no-install-avahi",
"--no-install-hqueue-server",
"--no-install-hqueue-client",
"--no-install-menus",
"--no-install-bin-symlink",
"--no-install-engine-maya",
"--no-install-engine-unity",
"--no-install-engine-unreal",
"--no-install-sidefxlabs",
]
status = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if status.returncode != 0:
raise Exception(
"Failed to install Houdini, ran into the following error:\n {error}".format(
error=status.stderr
)
)
hfs_dir_path = os.path.join(
"/opt",
"hfs{}.{}".format(target_release["version"], target_release["build"]),
)
hfs_symlink_dir_path = os.path.join(os.path.dirname(hfs_dir_path), "hfs")
elif sidefx_platform == "win64":
cmd = [
houdini_installer_file_path,
"/S",
"/AcceptEULA=2021-10-13",
"/MainApp",
"/LicenseServer=No",
"/StartMenu=No",
"/HQueueServer=No",
"/HQueueClient=No",
"/EngineMaya=No",
"/Engine3dsMax",
"/EngineUnity",
"/EngineUnreal=No",
"/SideFXLabs=No",
]
status = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if status.returncode != 0:
raise Exception(
"Failed to install Houdini, ran into the following error:\n {error}".format(
error=status.stderr
)
)
hfs_dir_path = os.path.join(
"C:\Program Files\Side Effects Software",
"Houdini {}.{}".format(target_release["version"], target_release["build"]),
)
hfs_symlink_dir_path = os.path.join(
os.path.dirname(hfs_dir_path), "Houdini"
)
else:
raise Exception(
"Platform {platform} is currently not"
"supported!".format(platform=platform)
)
# Create version-less symlink
logging.info(
"Creating symlink Houdini build {src} -> {dst}".format(
src=hfs_dir_path, dst=hfs_symlink_dir_path
)
)
os.symlink(hfs_dir_path, hfs_symlink_dir_path)


def create_sidefx_houdini_artifact(artifact_src, artifact_dst, artifact_prefix, artifact_product_name):
"""Create a .zip artifact based on the source directory content.
The output name will have will end in the houdini build name.
Args:
artifact_src (str): The source directory
artifact_dst (str): The target directory
artifact_prefix (str): The file name prefix, the suffix will be the Houdini build name
artifact_product_name (str): The file name product name.
This defines the Houdini product name, e.g. like houdini-py39
Returns:
str: The artifact file path
"""
re_digitdot = re.compile("[^0-9.]")
sidefx_platform = get_sidefx_platform()
if sidefx_platform == "linux":
hfs_build_name = os.path.basename(pathlib.Path("/opt/hfs").resolve())
elif sidefx_platform == "win64":
hfs_build_name = os.path.basename(
pathlib.Path("C:\Program Files\Side Effects Software\Houdini").resolve()
)
else:
raise Exception(
"Platform {platform} is currently not"
"supported!".format(platform=platform)
)
hfs_build_name = re_digitdot.sub("", hfs_build_name)
artifact_file_path = os.path.join(
artifact_dst, f"{artifact_prefix}_{artifact_product_name}-{hfs_build_name}-{sidefx_platform}"
)
artifact_dir_path = os.path.dirname(artifact_file_path)
if not os.path.exists(artifact_dir_path):
os.makedirs(artifact_dir_path)
shutil.make_archive(artifact_file_path, "zip", artifact_src)


if __name__ == "__main__":


MAYA_PYTHON_VERSION_MAPPING = {
"2022.5": "3.9",
"2023.3": "3.9",
"2024.2": "3.9"
}


# Workspace directory
workspace_dir_path = "/home/lucsch/Desktop/Maya"
download_dir_path = os.path.join(workspace_dir_path, "download")
dependency_dir_path = os.path.join(workspace_dir_path, "dependency")
tmp_dir_path = os.path.join(workspace_dir_path, "tmp")
#if os.path.exists(download_dir_path):
# shutil.rmtree(download_dir_path)
#if os.path.exists(tmp_dir_path):
# shutil.rmtree(tmp_dir_path)
if os.path.exists(dependency_dir_path):
shutil.rmtree(dependency_dir_path)
#os.makedirs(download_dir_path)
#os.makedirs(tmp_dir_path)
os.makedirs(dependency_dir_path)
# Download
maya_usd_sdk_source_file_path = os.path.join(download_dir_path, "maya-usd-0.27.0.zip")
maya_usd_sdk_compiled_file_path = os.path.join(download_dir_path, "MayaUSD_0.27.0_Maya2024.2_Linux.run")

# maya_usd_sdk_source_extracted_dir_path = os.path.join(tmp_dir_path, "usd_sdk_source")
# maya_usd_sdk_source_dependency_dir_path = os.path.join(dependency_dir_path, "usd_sdk_source")
maya_usd_sdk_compiled_extracted_dir_path = os.path.join(tmp_dir_path, "usd_sdk_compiled")
maya_usd_sdk_compiled_dependency_dir_path = os.path.join(dependency_dir_path, "usd_sdk_compiled")
maya_usd_sdk_devkit_dependency_dir_path = os.path.join(dependency_dir_path, "usd_sdk_devkit")

autodesk_platform = get_autodesk_platform()
if autodesk_platform == "Linux":
# Maya USD SDK source
# with zipfile.ZipFile(maya_usd_sdk_source_file_path, 'r') as zip_file:
# zip_file.extractall(maya_usd_sdk_source_extracted_dir_path)
# maya_usd_sdk_source_extracted_dir_path = os.path.join(maya_usd_sdk_source_extracted_dir_path, os.listdir(maya_usd_sdk_source_extracted_dir_path)[0])
# os.rename(maya_usd_sdk_source_extracted_dir_path, maya_usd_sdk_source_dependency_dir_path)
# Maya USD SDK compiled
os.chmod(maya_usd_sdk_compiled_file_path, 777)
command = [maya_usd_sdk_compiled_file_path, "--tar", "xvf", "--directory", maya_usd_sdk_compiled_extracted_dir_path]
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
process.communicate()
maya_usd_sdk_compiled_extracted_rpm_file_name = [f for f in os.listdir(maya_usd_sdk_compiled_extracted_dir_path) if f.endswith(".rpm")][0]
maya_usd_sdk_compiled_extracted_rpm_file_path = os.path.join(maya_usd_sdk_compiled_extracted_dir_path, maya_usd_sdk_compiled_extracted_rpm_file_name)
command = ["rpm", "-e", maya_usd_sdk_compiled_extracted_rpm_file_name.replace(".rpm", "")]
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
process.communicate()
command = ["rpm", "-i", "--prefix", maya_usd_sdk_compiled_extracted_dir_path, maya_usd_sdk_compiled_extracted_rpm_file_path]
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
process.communicate()
maya_usd_sdk_compiled_extracted_usd_dir_path = glob.glob("**{sep}mayausd{sep}USD".format(sep=os.path.sep), root_dir=maya_usd_sdk_compiled_extracted_dir_path, recursive=True)[0]
maya_usd_sdk_compiled_extracted_usd_dir_path = os.path.join(maya_usd_sdk_compiled_extracted_dir_path, maya_usd_sdk_compiled_extracted_usd_dir_path)
os.rename(maya_usd_sdk_compiled_extracted_usd_dir_path, maya_usd_sdk_compiled_dependency_dir_path)
os.chmod(dependency_dir_path, 0o777)
for root_dir_path, dir_names, file_names in os.walk(maya_usd_sdk_compiled_dependency_dir_path):
for dir_name in dir_names:
try:
os.chmod(os.path.join(root_dir_path, dir_name), 0o777)
except:
pass
for file_name in file_names:
try:
os.chmod(os.path.join(root_dir_path, file_name), 0o777)
except:
pass
# Maya USD SDK devkit
maya_usd_devkit_zip_file_path = glob.glob("**{}devkit.zip".format(os.path.sep), root_dir=maya_usd_sdk_compiled_dependency_dir_path, recursive=True)
maya_usd_devkit_zip_file_path = os.path.join(maya_usd_sdk_compiled_dependency_dir_path, maya_usd_devkit_zip_file_path[0])
with zipfile.ZipFile(maya_usd_devkit_zip_file_path, 'r') as zip_file:
zip_file.extractall(maya_usd_sdk_devkit_dependency_dir_path)
# Python


'''
# Parse args
parser = argparse.ArgumentParser()
parser.add_argument("--install", action="store_true", help="Install Houdini")
parser.add_argument(
"--install_houdini_product_name",
help="Houdini product name to install. If not provided, fallback to the default.",
)
parser.add_argument(
"--install_houdini_product_version",
help="Houdini product version to install. If not provided, fallback to the latest version.",
)
parser.add_argument("--artifact", action="store_true", help="Create artifact")
parser.add_argument("--artifact_src", help="Artifact source directory")
parser.add_argument("--artifact_dst", help="Artifact target directory")
parser.add_argument("--artifact_prefix", help="Artifact name prefix")
parser.add_argument("--artifact_product_name", help="Artifact product name")
args = parser.parse_args()
# Execute
# Install Houdini
if args.install:
install_sidefx_product(args.install_houdini_product_name,
args.install_houdini_product_version)
# Create artifact tagged with Houdini build name (expects Houdini to be installed via the above install command)
if args.artifact:
create_sidefx_houdini_artifact(
args.artifact_src, args.artifact_dst, args.artifact_prefix, args.artifact_product_name
)
'''

0 comments on commit 4881a77

Please sign in to comment.