Skip to content

Commit

Permalink
feat: provide script to build your own Geometry Service Docker image (#…
Browse files Browse the repository at this point in the history
…943)

Co-authored-by: Alex Fernandez <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Jan 22, 2024
1 parent 26877d3 commit 7f08be9
Show file tree
Hide file tree
Showing 4 changed files with 213 additions and 3 deletions.
3 changes: 3 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ repos:
rev: v0.2.8
hooks:
- id: add-license-headers
files: '(src|examples|tests|docker)/.*\.(py)|\.(proto)'
args:
- --start_year=2023

# this validates our github workflow files
- repo: https://github.com/python-jsonschema/check-jsonschema
Expand Down
45 changes: 42 additions & 3 deletions doc/source/getting_started/docker/windows_container.rst
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,55 @@ machine, either one or the other has to be built.

This guide focuses on building the ``Dockerfile.windows`` image.

There are two build modes:

* **Build from available Ansys installation**: This mode builds the Docker image
using the Ansys installation available in the machine where the Docker image
is being built.

* **Build from available binaries**: This mode builds the Docker image using
the binaries available in the ``ansys/pyansys-geometry-binaries`` repository.
If you do not have access to this repository, you can only use the first mode.
Link to the binaries repository: https://github.com/ansys/pyansys-geometry-binaries/

Prerequisites
~~~~~~~~~~~~~

* Ensure that Docker is installed in your machine.
If you do not have Docker available, see
:ref:`Docker for Windows containers <ref_running_windows_containers>`.

Build from available Ansys installation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To build your own image based on your own Ansys installation, follow these instructions:

* Download the `Python Docker build script <https://github.com/ansys/pyansys-geometry/blob/main/docker/build_docker_windows.py>`.

* Execute the script with the following command (no specific location needed):

.. code:: bash
python build_docker_windows.py
Check that the image has been created successfully. You should see output similar
to this:

.. code:: bash
docker images
>>> REPOSITORY TAG IMAGE ID CREATED SIZE
>>> ghcr.io/ansys/geometry windows-****** ............ X seconds ago Y.ZZGB
>>> ...... ...... ............ .............. ......
Build the Docker image from available binaries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Prior to building your image, follow these steps:

* Download the `latest Windows Dockerfile <https://github.com/ansys/pyansys-geometry/blob/main/docker/Dockerfile.windows>`_.

* Download the `latest release artifacts for the Windows
Expand All @@ -123,9 +165,6 @@ Prerequisites

* Move this ZIP file to the location of the Windows Dockerfile previously downloaded.

Build the Docker image
~~~~~~~~~~~~~~~~~~~~~~

To build your image, follow these instructions:

#. Navigate to the folder where the ZIP file and Dockerfile are located.
Expand Down
9 changes: 9 additions & 0 deletions docker/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,13 @@ see these topics:
.. * `Guide to building the Linux Docker container <https://geometry.docs.pyansys.com/version/dev/getting_started/docker/linux_container.html#building-the-geometry-service-linux-container>`_.
* `Guide to building the Windows Docker container <https://geometry.docs.pyansys.com/version/dev/getting_started/docker/windows_container.html#building-the-geometry-service-windows-container>`_.

If you have your own Ansys installation, you can build a Docker container
that uses your installation. In order to do this, download the
Python script `build_docker_windows.py <https://github.com/ansys/pyansys-geometry/blob/main/docker/build_docker_windows.py>`_
and run it from the command line:

.. code-block:: bash
python build_docker_windows.py
If you have any problems, open a `GitHub Issue <https://github.com/ansys/pyansys-geometry/issues/new?assignees=&labels=bug&projects=&template=bug.yml&title=Bug+located+in+...>`_.
159 changes: 159 additions & 0 deletions docker/build_docker_windows.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
# SPDX-License-Identifier: MIT
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""Script to build docker image for the project."""

import os
import shutil
import subprocess
import tempfile
import urllib.request

# First, get all environment variables that start with AWP_ROOT
awp_root = {}
for env_key, env_val in os.environ.items():
if env_key.startswith("AWP_ROOT"):
# There is an Ansys installation... Check that the version is at
# least 2023R2. Environment variables are in the form
# AWP_ROOT232=/path/to/2023R2
#
# Get the version number
version = env_key.split("AWP_ROOT")[1]
if version < "232":
# This version is too old, so we will ignore it
continue
else:
# This version is new enough, so we will add it to the list
awp_root[version] = env_val

if len(awp_root) == 0:
# There are no Ansys installations
print("XXXXXXX No Ansys compatible installations found.. exiting process. XXXXXXX")
print("XXXXXXX Please install Ansys 2023R2 or newer. XXXXXXX")
exit(0)

# Request the user to select the version of Ansys to use
print(">>> Select the version of Ansys to use:")
for i, (env_key, _) in enumerate(awp_root.items()):
print(f"{i+1}: {env_key}")
selection = input("Selection [default - last option]: ")

# If no selection is made, use the first version
if selection == "":
print("... No selection made, using default")
selection = len(awp_root)
else:
selection = int(selection)
ANSYS_VER = list(awp_root.keys())[selection - 1]
print(f">>> Using {ANSYS_VER}")

# Get the path to the Ansys installation
ANSYS_PATH = awp_root[ANSYS_VER]

# Verify that the Geometry Service is installed
if not os.path.exists(os.path.join(ANSYS_PATH, "GeometryService")):
print("XXXXXXX Geometry Service not installed.. exiting process. XXXXXXX")
exit(0)

# Create a temporary directory to copy the Geometry Service files to
print(">>> Creating temporary directory for building docker image")
TMP_DIR = tempfile.mkdtemp(prefix="docker_geometry_service_")

# Copy the Geometry Service files to the temporary directory
print(f">>> Copying Geometry Service files to temporary directory to {TMP_DIR}")
BIN_DIR = os.path.join(TMP_DIR, "bins", "DockerWindows", "bin", "x64", "Release_Headless", "net472")

# Create the directory structure
shutil.copytree(
os.path.join(ANSYS_PATH, "GeometryService"),
BIN_DIR,
)

# ZIP the temporary directory and delete it
print(">>> Zipping temporary directory. This might take some time...")
zip_file = shutil.make_archive(
"windows-binaries",
"zip",
root_dir=os.path.join(TMP_DIR, "bins"),
)

# Move the ZIP file to the docker directory
print(">>> Moving ZIP file to temporary directory")
shutil.move(zip_file, TMP_DIR)

# Remove the temporary directory
print(">>> Removing Geometry Service files")
shutil.rmtree(os.path.join(TMP_DIR, "bins"))

# Download the Dockerfile from the repository
print(">>> Downloading Dockerfile")
urllib.request.urlretrieve(
"https://raw.githubusercontent.com/ansys/pyansys-geometry/main/docker/Dockerfile.windows",
os.path.join(TMP_DIR, "Dockerfile"),
)

# Search for the AWP_ROOT* env variables and replace them with the correct
# value
print(">>> Updating Dockerfile")
with open(os.path.join(TMP_DIR, "Dockerfile"), "r") as f:
dockerfile = f.read()

# Find environment variables that start with AWP_ROOT
# inside the Dockerfile and replace them with the correct value
LENGTH_NO_VER = 12
LENGTH_VER = LENGTH_NO_VER + 3
line = dockerfile.find("ENV AWP_ROOT")
if line != -1:
# Get the environment variable name
env_var = dockerfile[line : LENGTH_NO_VER + line] + ANSYS_VER
# Replace the environment variable with the correct value
dockerfile = dockerfile.replace(
dockerfile[line : LENGTH_VER + line],
env_var,
)
else:
print("XXXXXXX No AWP_ROOT environment variable found in Dockerfile.. exiting process. XXXXXXX")
exit(0)

# Check if Docker is installed on the system
print(">>> Checking if Docker is installed")
if shutil.which("docker") is None:
print("XXXXXXX Docker is not installed.. exiting process. XXXXXXX")
exit(0)

# Build the docker image
print(">>> Building docker image. This might take some time...")
out = subprocess.run(
["docker", "build", "-t", "ghcr.io/ansys/geometry:windows-latest", "."],
cwd=TMP_DIR,
capture_output=True,
)

if out.returncode != 0:
print(out.stdout.decode())
print(out.stderr.decode())
print("XXXXXXX Docker build failed.. exiting process. XXXXXXX")
exit(0)
else:
print(">>> Docker image built successfully")
print(">>> Cleaning up temporary directory")
shutil.rmtree(TMP_DIR)
print(">>> Docker image is ready to use")

0 comments on commit 7f08be9

Please sign in to comment.