diff --git a/.github/workflows/deploy-docker-images.yml b/.github/workflows/deploy-docker-images.yml index b07f4ac0..f10a7ea2 100644 --- a/.github/workflows/deploy-docker-images.yml +++ b/.github/workflows/deploy-docker-images.yml @@ -5,11 +5,11 @@ name: Build & push images on: push: pull_request: - branches: ["main"] + branches: ['main'] env: registry: ghcr.io/dsd-dbs/capella-dockerimages/ - images: capella/base capella/remote capella/ease capella/readonly + images: capella/base capella/remote jobs: lint: @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: '3.11' - name: Install pre-commit run: |- python -m pip install pre-commit @@ -32,16 +32,18 @@ jobs: strategy: matrix: capella_version: - - "5.0.0" - - "5.2.0" - - "6.0.0" - - "6.1.0" + - '5.0.0' + - '5.2.0' + - '6.0.0' + - '6.1.0' dropins: - - name: "without" # without dropins - dropins: "" - - name: "selected" - dropins: "CapellaXHTMLDocGen,DiagramStyler,PVMT,Filtering,Requirements,SubsystemTransition" # selected set of dropins - name: Capella ${{ matrix.capella_version }} with ${{ matrix.dropins.name }} dropins + - name: 'without' # without dropins + dropins: '' + - name: 'selected' + dropins: 'CapellaXHTMLDocGen,DiagramStyler,PVMT,Filtering,Requirements,SubsystemTransition' # selected set of dropins + name: + Capella ${{ matrix.capella_version }} with ${{ matrix.dropins.name }} + dropins steps: - name: Checkout repository uses: actions/checkout@v4 @@ -50,7 +52,7 @@ jobs: with: cache: pip cache-dependency-path: ./pyproject.toml - python-version: "3.11" + python-version: '3.11' - name: Login to github container registry uses: docker/login-action@v3 with: @@ -63,6 +65,7 @@ jobs: echo "branch=$(echo $GITHUB_REF_NAME | sed 's/[^a-zA-Z0-9.]/-/g')" >> "$GITHUB_OUTPUT" echo "sha=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" - name: Build + # prettier-ignore run: > make ${{ env.images }} CAPELLA_VERSIONS="${{ matrix.capella_version }}" @@ -71,17 +74,6 @@ jobs: CAPELLA_DROPINS="${{ matrix.dropins.dropins }}" DOCKER_TAG_SCHEMA=${{ matrix.capella_version }}-${{ matrix.dropins.name }}-dropins-${{ steps.tag.outputs.branch }} DOCKER_BUILD_FLAGS="--label git-short-sha=${{ steps.tag.outputs.sha }}" - - name: Install test dependencies - run: | - docker build $DOCKER_BUILD_ARGS -t local-git-server tests/local-git-server - pip install '.[test]' - - name: Run pytest - run: > - DOCKER_PREFIX="${{ env.registry }}" - DOCKER_TAG="${{ matrix.capella_version }}-${{ matrix.dropins.name }}-dropins-${{ steps.tag.outputs.branch }}" - CAPELLA_VERSION="${{ matrix.capella_version }}" - LOCAL_GIT_TAG="latest" - pytest -m "not (t4c_server or t4c)" tests - name: Push run: | for image in ${{ env.images }} diff --git a/.gitignore b/.gitignore index b87eeb2f..656a0019 100644 --- a/.gitignore +++ b/.gitignore @@ -22,11 +22,6 @@ t4c/server t4c/.dockerignore !t4c/updateSite/*/.gitkeep -# EASE -ease/debug/libs/* -ease/extensions/*/* -!ease/extensions/*/.gitkeep - # Pure::variants pure-variants/versions/*/* !pure-variants/versions/*/.gitkeep diff --git a/Makefile b/Makefile index 1d9afccd..fcfaf6c9 100644 --- a/Makefile +++ b/Makefile @@ -109,8 +109,6 @@ CAPELLA_BUILD_TYPE ?= online # Set the option to 'false' if you want to run it on arm architectures. INSTALL_OLD_GTK_VERSION ?= true -EASE_BUILD_TYPE ?= online - PURE_VARIANTS_LICENSE_SERVER ?= http://localhost:8080 # Inject libraries from the capella/libs directory @@ -131,10 +129,6 @@ DOCKER_REGISTRY ?= localhost:12345 # Log level when running Docker containers LOG_LEVEL ?= DEBUG -# Path to a JSON file, which is used as input for the -# make-run/capella/readonly target. -READONLY_JSON_PATH ?= local/readonly.json - # If this option is set to 1, all tests that require a running t4c server # will be executed. To run these tests, you need a Makefile in # t4c/server with a target t4c/server/server that builds the t4c server @@ -164,11 +158,7 @@ all: \ t4c/client/base \ t4c/client/remote \ t4c/client/remote/pure-variants \ - capella/remote/pure-variants \ - capella/ease \ - t4c/client/ease \ - capella/ease/remote \ - capella/readonly + capella/remote/pure-variants base: SHELL=/bin/bash base: @@ -276,26 +266,6 @@ capella/remote/pure-variants: capella/remote docker build $(DOCKER_BUILD_FLAGS) -t $(DOCKER_PREFIX)$@:$$DOCKER_TAG --build-arg BASE_IMAGE=$(DOCKER_PREFIX)$<:$$DOCKER_TAG pure-variants $(MAKE) PUSH_IMAGES=$(PUSH_IMAGES) IMAGENAME=$@ .push -capella/ease: SHELL=./capella_loop.sh -capella/ease: capella/base - docker build $(DOCKER_BUILD_FLAGS) -t $(DOCKER_PREFIX)$@:$$DOCKER_TAG --build-arg BASE_IMAGE=$(DOCKER_PREFIX)$<:$$DOCKER_TAG --build-arg BUILD_TYPE=$(EASE_BUILD_TYPE) ease - $(MAKE) PUSH_IMAGES=$(PUSH_IMAGES) IMAGENAME=$@ .push - -t4c/client/ease: SHELL=./capella_loop.sh -t4c/client/ease: t4c/client/base - docker build $(DOCKER_BUILD_FLAGS) -t $(DOCKER_PREFIX)$@:$$DOCKER_TAG --build-arg BASE_IMAGE=$(DOCKER_PREFIX)$<:$$DOCKER_TAG --build-arg BUILD_TYPE=$(EASE_BUILD_TYPE) ease - $(MAKE) PUSH_IMAGES=$(PUSH_IMAGES) IMAGENAME=$@ .push - -capella/ease/remote: SHELL=./capella_loop.sh -capella/ease/remote: capella/ease - docker build $(DOCKER_BUILD_FLAGS) -t $(DOCKER_PREFIX)$@:$$DOCKER_TAG --build-arg BASE_IMAGE=$(DOCKER_PREFIX)$<:$$DOCKER_TAG remote - $(MAKE) PUSH_IMAGES=$(PUSH_IMAGES) IMAGENAME=$@ .push - -capella/readonly: SHELL=./capella_loop.sh -capella/readonly: capella/ease/remote - docker build $(DOCKER_BUILD_FLAGS) -t $(DOCKER_PREFIX)$@:$$DOCKER_TAG --build-arg BASE_IMAGE=$(DOCKER_PREFIX)$<:$$DOCKER_TAG readonly - $(MAKE) PUSH_IMAGES=$(PUSH_IMAGES) IMAGENAME=$@ .push - capella/builder: docker build $(DOCKER_BUILD_FLAGS) -t $(DOCKER_PREFIX)$@:$(CAPELLA_DOCKERIMAGES_REVISION) builder docker run -it -e CAPELLA_VERSION=$(CAPELLA_VERSION) -v $$(pwd)/builder/output/$(CAPELLA_VERSION):/output -v $$(pwd)/builder/m2_cache:/root/.m2/repository $(DOCKER_PREFIX)$@:$(CAPELLA_DOCKERIMAGES_REVISION) @@ -313,10 +283,15 @@ run-jupyter-notebook: jupyter-notebook $(DOCKER_PREFIX)$<:$(JUPYTER_NOTEBOOK_REVISION) run-capella/remote: capella/remote + FLAGS=""; + if [ -n "$(WORKSPACE_NAME)" ]; then \ + FLAGS="-v $$(pwd)/volumes/workspaces/$(WORKSPACE_NAME):/workspace"; \ + fi docker run $(DOCKER_RUN_FLAGS) \ - -v $$(pwd)/volumes/workspaces/$(WORKSPACE_NAME):/workspace \ + $$FLAGS \ -e RMT_PASSWORD=$(RMT_PASSWORD) \ -e CONNECTION_METHOD=$(CONNECTION_METHOD) \ + -e AUTOSTART_CAPELLA=$(AUTOSTART_CAPELLA) \ -e XPRA_SUBPATH=$(XPRA_SUBPATH) \ -p $(RDP_PORT):3389 \ -p $(WEB_PORT):10000 \ @@ -362,31 +337,6 @@ run-eclipse/remote/pure-variants: eclipse/remote/pure-variants $(DOCKER_PREFIX)$<:$(DOCKER_TAG) -run-capella/readonly: capella/readonly - docker run $(DOCKER_RUN_FLAGS) \ - -e RMT_PASSWORD=$(RMT_PASSWORD) \ - -e GIT_URL=$(GIT_REPO_URL) \ - -e GIT_ENTRYPOINT=$(GIT_REPO_ENTRYPOINT) \ - -e GIT_REVISION=$(GIT_REPO_BRANCH) \ - -e GIT_DEPTH=$(GIT_REPO_DEPTH) \ - -e GIT_USERNAME="$(GIT_USERNAME)" \ - -e GIT_PASSWORD="$(GIT_PASSWORD)" \ - -e CONNECTION_METHOD=$(CONNECTION_METHOD) \ - -e XPRA_SUBPATH=$(XPRA_SUBPATH) \ - -p $(RDP_PORT):3389 \ - -p $(WEB_PORT):10000 \ - $(DOCKER_PREFIX)$<:$$(echo "$(DOCKER_TAG_SCHEMA)" | envsubst) - -run-capella/readonly-json: capella/readonly - docker run $(DOCKER_RUN_FLAGS) \ - -e RMT_PASSWORD=$(RMT_PASSWORD) \ - -e GIT_REPOS_JSON="$$(cat $(READONLY_JSON_PATH))" \ - -e CONNECTION_METHOD=$(CONNECTION_METHOD) \ - -e XPRA_SUBPATH=$(XPRA_SUBPATH) \ - -p $(RDP_PORT):3389 \ - -p $(WEB_PORT):10000 \ - $(DOCKER_PREFIX)$<:$$(echo "$(DOCKER_TAG_SCHEMA)" | envsubst) - run-t4c/client/remote-legacy: t4c/client/remote docker run $(DOCKER_RUN_FLAGS) \ -v $$(pwd)/volumes/workspaces/$(WORKSPACE_NAME):/workspace \ @@ -493,22 +443,6 @@ debug-t4c/client/remote/pure-variants: AUTOSTART_CAPELLA=0 debug-t4c/client/remote/pure-variants: DOCKER_RUN_FLAGS=-it --entrypoint="bash" debug-t4c/client/remote/pure-variants: run-t4c/client/remote/pure-variants -debug-capella/readonly: DOCKER_RUN_FLAGS=-it \ - -e DISPLAY=:0 \ - -v /tmp/.X11-unix:/tmp/.X11-unix \ - -v $$(pwd)/local/scripts:/opt/scripts/debug \ - -v $$(pwd)/readonly/load_models.py:/opt/scripts/load_models.py \ - --entrypoint="bash" -debug-capella/readonly: run-capella/readonly - -debug-capella/readonly-json: DOCKER_RUN_FLAGS=-it \ - -e DISPLAY=:0 \ - -v /tmp/.X11-unix:/tmp/.X11-unix \ - -v $$(pwd)/local/scripts:/opt/scripts/debug \ - -v $$(pwd)/readonly/load_models.py:/opt/scripts/load_models.py \ - --entrypoint="bash" -debug-capella/readonly-json: run-capella/readonly-json - t4c/server/server: SHELL=./capella_loop.sh t4c/server/server: $(MAKE) -C t4c/server PUSH_IMAGES=$(PUSH_IMAGES) CAPELLA_VERSION=$$CAPELLA_VERSION $@ @@ -532,7 +466,7 @@ test: t4c/client/remote endif test: SHELL=./capella_loop.sh -test: capella/readonly +test: export CAPELLA_VERSION=$$CAPELLA_VERSION source .venv/bin/activate cd tests diff --git a/README.md b/README.md index 836245b0..2110fd9e 100644 --- a/README.md +++ b/README.md @@ -12,34 +12,27 @@ SPDX-License-Identifier: Apache-2.0 [![REUSE status](https://api.reuse.software/badge/github.com/DSD-DBS/capella-dockerimages)](https://api.reuse.software/info/github.com/DSD-DBS/capella-dockerimages) -## Documentation - -The documentation has been moved to -[Github Pages](https://dsd-dbs.github.io/capella-dockerimages/). - ## Introduction -This repository provides Docker images for the followings tools: +This repository provides containerized clients for the followings tools: - [Capella](https://www.eclipse.org/capella/) - - [TeamForCapella client](https://www.obeosoft.com/en/team-for-capella) \ - Right now, we don't provide a Docker image for the server. - - [EASE](https://www.eclipse.org/ease/) \ - [SWT-Bot](https://www.eclipse.org/swtbot/) +- [TeamForCapella](https://www.obeosoft.com/en/team-for-capella) +- [Eclipse Papyrus](https://eclipse.dev/papyrus/) +- [Eclipse IDE](https://eclipseide.org/) +- [pure::variants](https://www.pure-systems.com/de/purevariants) - [Jupyter Notebook](https://jupyter.org/) -In general, we are providing images to run applications in a containerized -environment and to automate processes around the tools. - -This repository includes Docker files to build the following Docker images: - -| Name of the Docker image | Short description | -| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `base` | This is the base image that has the most important tools pre-installed. | -| `capella/base` | This is the Capella base image. It is a simple container with Capella and the required dependencies installed. No more. | -| `t4c/client/base` | This extends the Capella base image with the T4C client and the dependencies, as well as features to synchronize T4C and Git repositories. | -| `capella/ease`
`t4c/client/ease` | This extends the Capella or T4C client base image with EASE and SWTBot functionality. You can mount every Python script and execute it in a container environment. | -| `capella/remote`
`t4c/client/remote` | The remote image will add an RDP server on top of any other image. This will provide the user the possibility to connect and work inside the container. | -| `capella/readonly` | This image has capability to clone a Git repository, will load the project into the workspace and also offers RDP. | -| `capella/remote/pure-variants`
`t4c/client/remote/pure-variants` | This extends the remote image with pure::variants support. | -| `jupyter-notebook` | A Jupyter notebook image based on the base image. | +The main purposes for containerizing these tools are: + +- **Easy to use**: No need to install the tools on your local machine. +- **Reproducibility**: The same environment can be easily reproduced on + different machines. +- **Isolation**: The tools are isolated from the host machine. +- **Documentation**: All configuration options are documented in the + Dockerfiles. +- **Collaboration**: The containers can be used in the + [Collaboration Manager](https://github.com/DSD-DBS/capella-collab-manager) + +More information can be found in our +[documentation](https://dsd-dbs.github.io/capella-dockerimages/). diff --git a/builder/Dockerfile b/builder/Dockerfile index 0c1cda18..9908a4ee 100644 --- a/builder/Dockerfile +++ b/builder/Dockerfile @@ -10,7 +10,7 @@ ENV SHELL=/bin/bash RUN apt-get update && \ apt-get install -y maven -RUN pip install --break-system-packages --no-cache-dir lxml==4.9.3 +RUN pip install --no-cache-dir lxml==4.9.3 COPY inject_architecture_into_pom.py /opt/inject_architecture_into_pom.py COPY build_capella_from_source.sh /opt/build_capella_from_source.sh diff --git a/capella/Dockerfile b/capella/Dockerfile index 2ffd1365..c8259b6b 100644 --- a/capella/Dockerfile +++ b/capella/Dockerfile @@ -121,7 +121,7 @@ ARG MEMORY_LIMIT=5500m RUN echo '-Dorg.eclipse.equinox.p2.transport.ecf.retry=15' >> /opt/capella/capella.ini && \ echo '-Dorg.eclipse.ecf.provider.filetransfer.retrieve.readTimeout=10000' >> /opt/capella/capella.ini && \ sed -i "s/-Xmx[^ ]*/-Xmx$MEMORY_LIMIT/g" /opt/capella/capella.ini -RUN pip install --no-cache-dir PyYAML==6.0.1 && python install_dropins.py +RUN pip install --no-cache-dir lxml==4.9.3 PyYAML==6.0.1 && python install_dropins.py COPY ./versions/${CAPELLA_VERSION}/patches /opt/patches RUN PATCH_DIR=/opt/patches /opt/patch.sh @@ -143,8 +143,7 @@ RUN mkdir -p /opt/capella/configuration/.settings; \ chown techuser /opt /opt/capella/capella.ini RUN echo '-Dosgi.configuration.area=file:/opt/capella/configuration' >> /opt/capella/capella.ini -COPY setup_workspace.py /opt/setup/setup_welcome_screen.py -COPY replace_env_variables.sh /opt/setup/replace_env_variables.sh +COPY startup/* /opt/setup/ ENV AUTOSTART_CAPELLA=1 ENV RESTART_CAPELLA=1 diff --git a/capella/autostart b/capella/autostart index d1820de3..fc41979e 100755 --- a/capella/autostart +++ b/capella/autostart @@ -1,11 +1,13 @@ -#!/bin/sh +#!/bin/bash # SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors # SPDX-License-Identifier: Apache-2.0 -# Autostart script for OpenBox - +# Autostart script export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" +# Load environment variables from /etc/environment +source /etc/environment + nitrogen --restore & if [ "$AUTOSTART_CAPELLA" = "1" ]; diff --git a/readonly/load_models.py b/capella/startup/provisioning.py similarity index 62% rename from readonly/load_models.py rename to capella/startup/provisioning.py index 470c5d6a..7d2c12e5 100644 --- a/readonly/load_models.py +++ b/capella/startup/provisioning.py @@ -1,16 +1,7 @@ # SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors # SPDX-License-Identifier: Apache-2.0 -"""EASE script to prepare the workspace for read-only containers. +"""Prepare models in the $MODEL_INBOX_DIRECTORIES for Capella.""" -.. note: - The script can be invoked with - ``/opt/capella/capella --launcher.suppressErrors -consolelog -application org.eclipse.ease.runScript -script "file:/opt/scripts/load_models.py"`` - -.. seealso: - - The acronym EASE stands for "Eclipse Advanced Scripting Environment". - Further information: https://www.eclipse.org/ease/ -""" import enum import json import logging @@ -18,19 +9,14 @@ import pathlib import re import string -import subprocess -import tempfile import typing as t -from eclipse.system.resources import importProject from lxml import etree from lxml.builder import E -logging.basicConfig(level="DEBUG") +logging.basicConfig(level=os.getenv("LOG_LEVEL", "INFO")) log = logging.getLogger(__file__) -WORKSPACE_DIR = os.getenv("WORKSPACE_DIR", "/workspace") - class _ProjectNature(enum.Enum): LIBRARY = "org.polarsys.capella.library.nature" @@ -39,74 +25,21 @@ class _ProjectNature(enum.Enum): class _ProjectDict(t.TypedDict): name: t.NotRequired[str] - url: str revision: str - depth: int - entrypoint: str | pathlib.Path - username: str | None - password: str | None nature: t.NotRequired[str] - location: t.NotRequired[pathlib.Path] - etree: t.NotRequired[etree._Element] - + etree: t.NotRequired[etree._Element] # etree of the .project file + path: str # Directory the repository has been cloned into + entrypoint: ( + str | pathlib.Path + ) # Entrypoint relative from the root of the repository -def disable_welcome_screen() -> None: - prefs = "\n".join(["eclipse.preferences.version=1", "showIntro=false"]) - prefs_path = pathlib.Path( - f"{WORKSPACE_DIR}/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs" - ) - prefs_path.parent.mkdir(parents=True, exist_ok=True) - prefs_path.write_text(prefs, encoding="utf-8") - log.info("Disabled Welcome screen") + location: t.NotRequired[ + pathlib.Path + ] # Location resolved from path + entrypoint def fetch_projects_from_environment() -> list[_ProjectDict]: - projects: list[_ProjectDict] = [] - - git_repo_url = os.getenv("GIT_URL") - git_repo_revision = os.getenv("GIT_REVISION") - - if git_repo_url and git_repo_revision: - projects.append( - { - "url": git_repo_url, - "revision": git_repo_revision, - "depth": int(os.getenv("GIT_DEPTH", "0")), - "entrypoint": os.environ["GIT_ENTRYPOINT"], - "username": os.getenv("GIT_USERNAME", None), - "password": os.getenv("GIT_PASSWORD", None), - } - ) - - return projects + json.loads(os.getenv("GIT_REPOS_JSON", "[]")) - - -def clone_git_model(project: _ProjectDict) -> None: - log.info("Cloning git repository with url %s", project["url"]) - - project["location"] = pathlib.Path(tempfile.mkdtemp(prefix="model_")) - - flags = [] - - if revision := project["revision"]: - flags += ["--single-branch", "--branch", revision] - - git_depth = project["depth"] - if git_depth != 0: - flags += ["--depth", str(git_depth)] - - subprocess.run( - ["git", "clone", project["url"], str(project["location"])] + flags, - check=True, - env={ - "GIT_USERNAME": project.get("username", None) or "", - "GIT_PASSWORD": project.get("password", None) or "", - "GIT_ASKPASS": os.environ["GIT_ASKPASS"], - }, - ) - log.info( - "Clone of git repository with url %s was successful", project["url"] - ) + return json.loads(os.getenv("ECLIPSE_PROJECTS_TO_LOAD", "[]")) def resolve_entrypoint(project: _ProjectDict) -> None: @@ -120,6 +53,19 @@ def resolve_entrypoint(project: _ProjectDict) -> None: project["location"] = project["entrypoint"].parent +def check_that_location_exists(project: _ProjectDict) -> None: + if not project["location"].exists(): + raise FileNotFoundError( + f"Couldn't find project location '{project['location']}'" + ) + + log.debug( + "Found the following files in directory '%s': %s", + project["location"], + ", ".join([str(path) for path in project["location"].glob("*")]), + ) + + def derive_project_name_from_aird(project_location: pathlib.Path) -> str: return next(project_location.glob("*.aird")).stem @@ -165,12 +111,6 @@ def write_updated_project_file(project: _ProjectDict) -> None: project_description_file.write_bytes(etree.tostring(project["etree"])) -def import_project(project: _ProjectDict) -> None: - log.info("Loading project into workspace: %s", str(project["location"])) - importProject(str(project["location"])) - log.info("Loading of project was successful: %s", str(project["location"])) - - def resolve_duplicate_names(projects: list[_ProjectDict]) -> None: duplicated_projects_grouped = group_projects_by_name(projects) @@ -221,13 +161,27 @@ def append_revision_to_project_name(project: _ProjectDict) -> None: add_suffix_to_project_name(project, sanitized_revision) +def provide_project_dirs_to_capella_plugin( + projects: list[_ProjectDict], +) -> None: + locations = ":".join([str(project["location"]) for project in projects]) + pathlib.Path("/etc/environment").write_text( + f"export MODEL_INBOX_DIRECTORIES={locations}\n", encoding="utf-8" + ) + log.info( + "Set environment variable MODEL_INBOX_DIRECTORIES to '%s'", locations + ) + + def main() -> None: projects = fetch_projects_from_environment() print("---START_LOAD_MODEL---") + log.info("Found the following models: %s", projects) try: for project in projects: - clone_git_model(project) + project["location"] = pathlib.Path(project["path"]) resolve_entrypoint(project) + check_that_location_exists(project) load_or_generate_project_etree(project) derive_project_name(project) @@ -235,12 +189,13 @@ def main() -> None: for project in projects: write_updated_project_file(project) - import_project(project) - print("---FINISH_LOAD_MODEL---") + + provide_project_dirs_to_capella_plugin(projects) except Exception as e: print("---FAILURE_LOAD_MODEL---") raise e - disable_welcome_screen() + + print("---FINISH_LOAD_MODEL---") if __name__ == "__main__": diff --git a/capella/replace_env_variables.sh b/capella/startup/replace_env_variables.sh similarity index 100% rename from capella/replace_env_variables.sh rename to capella/startup/replace_env_variables.sh diff --git a/capella/setup_workspace.py b/capella/startup/setup_workspace.py similarity index 100% rename from capella/setup_workspace.py rename to capella/startup/setup_workspace.py diff --git a/ci-templates/gitlab/image-builder.yml b/ci-templates/gitlab/image-builder.yml index 62a6d9cf..5eff7e9b 100644 --- a/ci-templates/gitlab/image-builder.yml +++ b/ci-templates/gitlab/image-builder.yml @@ -3,88 +3,81 @@ variables: BASE: - value: "0" - description: "Build the base image?" + value: '0' + description: 'Build the base image?' CAPELLA_BASE: - value: "0" - description: "Build the capella/base image?" + value: '0' + description: 'Build the capella/base image?' CAPELLA_REMOTE: - value: "0" - description: "Build the capella/remote image?" + value: '0' + description: 'Build the capella/remote image?' T4C_CLIENT_BASE: - value: "0" - description: "Build the t4c/client/base image?" + value: '0' + description: 'Build the t4c/client/base image?' T4C_CLIENT_REMOTE: - value: "0" - description: "Build the t4c/client/remote image?" + value: '0' + description: 'Build the t4c/client/remote image?' T4C_CLIENT_REMOTE_PURE_VARIANTS: - value: "0" - description: "Build the t4c/client/remote/pure-variants image?" - CAPELLA_EASE: - value: "0" - description: "Build the capella/ease image?" - CAPELLA_EASE_REMOTE: - value: "0" - description: "Build the capella/ease/remote image?" - CAPELLA_READONLY: - value: "0" - description: "Build the capella/readonly image?" - T4C_CLIENT_EASE: - value: "0" - description: "Build the t4c/client/ease image?" - T4C_CLIENT_EASE_REMOTE: - value: "0" - description: "Build the t4c/client/ease/remote image?" - T4C_CLIENT_EASE_REMOTE_DEBUG: - value: "0" - description: "Build the t4c/client/ease/remote/debug image?" + value: '0' + description: 'Build the t4c/client/remote/pure-variants image?' JUPYTER: - value: "0" - description: "Build the jupyter-notebook image?" + value: '0' + description: 'Build the jupyter-notebook image?' PAPYRUS_BASE: - value: "0" - description: "Build the papyrus/base image?" + value: '0' + description: 'Build the papyrus/base image?' PAPYRUS_REMOTE: - value: "0" - description: "Build the papyrus/remote image?" + value: '0' + description: 'Build the papyrus/remote image?' ECLIPSE_BASE: - value: "0" - description: "Build the eclipse/base image?" + value: '0' + description: 'Build the eclipse/base image?' ECLIPSE_REMOTE: - value: "0" - description: "Build the eclipse/remote image?" + value: '0' + description: 'Build the eclipse/remote image?' ECLIPSE_REMOTE_PURE_VARIANTS: - value: "0" - description: "Build the eclipse/remote/pure-variants image?" + value: '0' + description: 'Build the eclipse/remote/pure-variants image?' CAPELLA_DOCKER_IMAGES_REVISION: - value: "main" - description: "Revision of the Capella Docker images Github repository (https://github.com/DSD-DBS/capella-dockerimages)" + value: 'main' + description: + 'Revision of the Capella Docker images Github repository + (https://github.com/DSD-DBS/capella-dockerimages)' CAPELLA_VERSION: - value: "6.0.0" - description: "Capella version. Please make sure that a subdirectory with the name of the value exists. The value must be valid ASCII and may contain lowercase and uppercase letters, digits, underscores, periods and dashes." + value: '6.0.0' + description: + 'Capella version. Please make sure that a subdirectory with the name of + the value exists. The value must be valid ASCII and may contain lowercase + and uppercase letters, digits, underscores, periods and dashes.' BUILD_FOR_LATEST_TAG: - value: "0" - description: "Fetch the latest tag for the image builder repository and use it as revision. If 0, '$CI_COMMIT_REF_NAME' will be used." + value: '0' + description: + "Fetch the latest tag for the image builder repository and use it as + revision. If 0, '$CI_COMMIT_REF_NAME' will be used." JUPYTER_VERSION: - value: "python-3.11" - description: "Python version for the jupyter notebook." + value: 'python-3.11' + description: 'Python version for the jupyter notebook.' PAPYRUS_VERSION: - value: "6.4.0" - description: "Semantic version of Papyrus." + value: '6.4.0' + description: 'Semantic version of Papyrus.' ECLIPSE_VERSION: - value: "4.27" - description: "Semantic version of Eclipse." + value: '4.27' + description: 'Semantic version of Eclipse.' ENVIRONMENT: - value: "staging" - description: "Specifies the environment. Make sure that all related environment variables are set on the repository level. More information in the documentation." - T4C_SERVER_REGISTRY: "" # Registry where you can find the t4c server image - T4C_SERVER_TAG: "$CAPELLA_VERSION-main" # Tag that is used for the t4c server image - T4C_SERVER_TEST_DATA_REPO: "" # Link to the t4c test data repo needed to run the backup tests - LOCAL_GIT_BASE_IMAGE: "debian:bookworm" # Specifies the base images used to build the local git server needed to run the tests - DOCKER_BUILD_ARGS: "--no-cache" + value: 'staging' + description: + 'Specifies the environment. Make sure that all related environment + variables are set on the repository level. More information in the + documentation.' + T4C_SERVER_REGISTRY: '' # Registry where you can find the t4c server image + T4C_SERVER_TAG: '$CAPELLA_VERSION-main' # Tag that is used for the t4c server image + T4C_SERVER_TEST_DATA_REPO: '' # Link to the t4c test data repo needed to run the backup tests + LOCAL_GIT_BASE_IMAGE: 'debian:bookworm' # Specifies the base images used to build the local git server needed to run the tests + DOCKER_BUILD_ARGS: '--no-cache' BUILD_ARCHITECTURE: amd64 - PURE_VARIANTS_VERSION: "6.0.1" - XPRA_REGISTRY: "https://xpra.org" + PURE_VARIANTS_VERSION: '6.0.1' + XPRA_REGISTRY: 'https://xpra.org' + ECLIPSE_REPOSITORY: 'https://download.eclipse.org' stages: - build @@ -103,15 +96,13 @@ default: - docker info - DOCKER_REGISTRY_USER_QUERY=DOCKER_REGISTRY_USER_${ENVIRONMENT_UPPERCASE} - DOCKER_REGISTRY_PASSWORD_QUERY=DOCKER_REGISTRY_PASSWORD_${ENVIRONMENT_UPPERCASE} + # prettier-ignore - echo ${!DOCKER_REGISTRY_PASSWORD_QUERY:?} | docker login -u ${!DOCKER_REGISTRY_USER_QUERY:?} --password-stdin $DOCKER_REGISTRY - docker pull $BASE_IMAGE .push: &push - docker push $IMAGE:$DOCKER_TAG -.ease: &ease - - cp -R ../ease/extensions/* ease/extensions/ - .prepare: &prepare - ENVIRONMENT_UPPERCASE=$(echo ${ENVIRONMENT:?} | tr '[:lower:]' '[:upper:]') - DOCKER_REGISTRY_QUERY=DOCKER_REGISTRY_${ENVIRONMENT_UPPERCASE} @@ -124,6 +115,7 @@ default: else IMAGE_BUILDER_REVISION="$CI_COMMIT_REF_NAME" fi + # prettier-ignore - GENERAL_IMAGE_TAG=$(echo $CAPELLA_DOCKER_IMAGES_REVISION | sed 's/[^a-zA-Z0-9.]/-/g')-$IMAGE_BUILDER_REVISION - IMAGE=${DOCKER_REGISTRY}/$IMAGE @@ -159,6 +151,7 @@ default: .prepare-eclipse-pv: &prepare-eclipse-pv - *prepare + # prettier-ignore - export DOCKER_TAG=$ECLIPSE_VERSION-$PURE_VARIANTS_VERSION-$GENERAL_IMAGE_TAG - BASE_IMAGE="${DOCKER_REGISTRY}/${BASE_IMAGE}:$ECLIPSE_VERSION-$GENERAL_IMAGE_TAG" - cd pure-variants @@ -176,6 +169,7 @@ default: - export DOCKER_PREFIX=${DOCKER_REGISTRY:?}/ - apt-get update && apt-get -y install jq # This command lists docker containers, identifies the current job and writes the network ID of the current container into the DOCKER_NETWORK variable. + # prettier-ignore - export DOCKER_NETWORK=$(docker inspect -f "{{json .NetworkSettings.Networks }}" $(docker ps -q -f "label=com.gitlab.gitlab-runner.job.id=$CI_JOB_ID" -f "label=com.gitlab.gitlab-runner.type=build") | jq -r 'keys[0]' | head -n 1) - *local-git-server - python -m venv .venv @@ -185,6 +179,7 @@ default: .prepare-t4c-server-tests: &prepare-t4c-server-tests - *prepare-tests-general + # prettier-ignore - GIT_PASSWORD=${T4C_SERVER_TEST_DATA_REPO_TOKEN:?} git clone ${T4C_SERVER_TEST_DATA_REPO:?} base: @@ -224,6 +219,7 @@ capella/base: script: - *prepare-capella - *docker + # prettier-ignore - mv ../capella.tar.gz ./capella/versions/$CAPELLA_VERSION/$BUILD_ARCHITECTURE/capella.tar.gz - > if [[ -n "$(find ../dropins -maxdepth 1 -type d)" ]]; then @@ -232,7 +228,8 @@ capella/base: echo "No files to move in dropins" fi - > - if [[ -n "$(find ../patches -maxdepth 1 -type f -not -path '*/\.*')" ]]; then + if [[ -n "$(find ../patches -maxdepth 1 -type f -not -path '*/\.*')" ]]; + then mv ../patches/* ./capella/versions/$CAPELLA_VERSION/patches/ else echo "No files to move in patches" @@ -293,6 +290,7 @@ t4c/client/base: --build-arg BASE_IMAGE=$BASE_IMAGE \ t4c - *prepare-t4c-server-tests + # prettier-ignore - pytest -o log_cli=true -s -m t4c_server test_backups.py test_exporter_local.py test_exporter_git.py || r=3 - *push - exit $r @@ -340,156 +338,17 @@ t4c/client/remote/pure-variants: script: - *prepare-capella - *docker - - mv ../../../../pure-variants/dependencies/* pure-variants/dependencies/ + # prettier-ignore - mv ../../../../pure-variants/updateSite/* pure-variants/versions/${PURE_VARIANTS_VERSION:?} - | docker build $DOCKER_BUILD_ARGS \ -t $DOCKER_REGISTRY/t4c/client/remote/pure-variants:$DOCKER_TAG \ - --build-arg BUILD_TYPE=offline \ + --build-arg ECLIPSE_REPOSITORY=${ECLIPSE_REPOSITORY} \ --build-arg BASE_IMAGE=$BASE_IMAGE \ --build-arg PURE_VARIANTS_VERSION="$PURE_VARIANTS_VERSION" \ pure-variants - *push -capella/ease: - stage: build - needs: - - job: capella/base - optional: true - rules: - - if: '$CAPELLA_EASE == "1"' - when: always - variables: - BASE_IMAGE: capella/base - IMAGE: capella/ease - script: - - *prepare-capella - - *docker - - *ease - - | - docker build $DOCKER_BUILD_ARGS \ - -t $DOCKER_REGISTRY/capella/ease:$DOCKER_TAG \ - --build-arg BUILD_TYPE=offline \ - --build-arg BASE_IMAGE=$BASE_IMAGE \ - ease - - *push - -capella/ease/remote: - stage: build - needs: - - job: capella/ease - optional: true - rules: - - if: '$CAPELLA_EASE_REMOTE == "1"' - when: always - variables: - BASE_IMAGE: capella/ease - IMAGE: capella/ease/remote - script: - - *prepare-capella - - *docker - - | - docker build $DOCKER_BUILD_ARGS \ - -t $DOCKER_REGISTRY/capella/ease/remote:$DOCKER_TAG \ - --build-arg BASE_IMAGE=$BASE_IMAGE \ - --build-arg XPRA_REGISTRY=$XPRA_REGISTRY \ - remote - - *push - -capella/readonly: - stage: build - needs: - - job: capella/ease/remote - optional: true - rules: - - if: '$CAPELLA_READONLY == "1"' - when: always - variables: - BASE_IMAGE: capella/ease/remote - IMAGE: capella/readonly - script: - - *prepare-capella - - *docker - - | - docker build $DOCKER_BUILD_ARGS \ - -t $DOCKER_REGISTRY/capella/readonly:$DOCKER_TAG \ - --build-arg BASE_IMAGE=$BASE_IMAGE \ - readonly - - *prepare-tests-general - - pytest -o log_cli=true -s test_read_only.py || r=3 - - *push - - exit $r - allow_failure: *allow_failure - -t4c/client/ease: - stage: build - needs: - - job: t4c/client/base - optional: true - rules: - - if: '$T4C_CLIENT_EASE == "1"' - when: always - variables: - BASE_IMAGE: t4c/client/base - IMAGE: t4c/client/ease - script: - - *prepare-capella - - *docker - - *ease - - | - docker build $DOCKER_BUILD_ARGS \ - -t $DOCKER_REGISTRY/t4c/client/ease:$DOCKER_TAG \ - --build-arg BUILD_TYPE=offline \ - --build-arg BASE_IMAGE=$BASE_IMAGE \ - ease - - *push - -t4c/client/ease/remote: - stage: build - needs: - - job: t4c/client/ease - optional: true - rules: - - if: '$T4C_CLIENT_EASE_REMOTE == "1"' - when: always - variables: - BASE_IMAGE: t4c/client/ease - IMAGE: t4c/client/ease/remote - script: - - *prepare-capella - - *docker - - | - docker build $DOCKER_BUILD_ARGS \ - -t $IMAGE:$DOCKER_TAG \ - --build-arg BASE_IMAGE=$BASE_IMAGE \ - --build-arg XPRA_REGISTRY=$XPRA_REGISTRY \ - remote - - *push - -t4c/client/ease/remote/debug: - stage: build - needs: - - job: t4c/client/ease/remote - optional: true - rules: - - if: '$T4C_CLIENT_EASE_REMOTE_DEBUG == "1"' - when: always - variables: - BASE_IMAGE: t4c/client/ease/remote - IMAGE: t4c/client/ease/remote/debug - script: - - *prepare-capella - - *docker - - mkdir -p ease/debug/libs - - mv ../ease/debug/code.deb ease/debug/libs/code.deb - - | - docker build $DOCKER_BUILD_ARGS \ - -t $IMAGE:$DOCKER_TAG \ - --build-arg NETWORK_ACCESS=restricted \ - --build-arg BASE_IMAGE=$BASE_IMAGE \ - ease/debug - - *push - eclipse/base: stage: build needs: @@ -504,14 +363,14 @@ eclipse/base: script: - *prepare-eclipse - *docker + # prettier-ignore - mv ../eclipse.tar.gz ./eclipse/versions/$ECLIPSE_VERSION/$BUILD_ARCHITECTURE/eclipse.tar.gz - - mv ../../../egit/* ./eclipse/egit/ - | docker build $DOCKER_BUILD_ARGS \ -t ${IMAGE}:${DOCKER_TAG} \ --build-arg ECLIPSE_VERSION=${ECLIPSE_VERSION} \ --build-arg BASE_IMAGE=${BASE_IMAGE} \ - --build-arg BUILD_TYPE=offline \ + --build-arg ECLIPSE_REPOSITORY=${ECLIPSE_REPOSITORY} \ eclipse - *push @@ -551,12 +410,11 @@ eclipse/remote/pure-variants: script: - *prepare-eclipse-pv - *docker - - mv ../dependencies/* pure-variants/dependencies/ - mv ../updateSite/* pure-variants/versions/${PURE_VARIANTS_VERSION:?} - | docker build $DOCKER_BUILD_ARGS \ -t ${IMAGE}:${DOCKER_TAG} \ - --build-arg BUILD_TYPE=offline \ + --build-arg ECLIPSE_REPOSITORY=${ECLIPSE_REPOSITORY} \ --build-arg BASE_IMAGE=${BASE_IMAGE} \ --build-arg PURE_VARIANTS_VERSION="$PURE_VARIANTS_VERSION" \ pure-variants diff --git a/ci-templates/gitlab/release-train.yml b/ci-templates/gitlab/release-train.yml index b5b1a9e6..cbd52e90 100644 --- a/ci-templates/gitlab/release-train.yml +++ b/ci-templates/gitlab/release-train.yml @@ -3,80 +3,84 @@ variables: # Revision of Github repository. If using a mirror, no change is needed. - CAPELLA_DOCKER_IMAGES_REVISION: "$CI_COMMIT_REF_NAME" + CAPELLA_DOCKER_IMAGES_REVISION: '$CI_COMMIT_REF_NAME' # Provide the path to image builder repository - IMAGE_BUILDER_GITLAB_REPOSITORY: "path/to/project" + IMAGE_BUILDER_GITLAB_REPOSITORY: 'path/to/project' + + IMAGE_BUILDER_GITLAB_BRANCH: + value: 'main' + description: 'Branch of the image builder Gitlab project' # The base image does not depend on the Capella version. # Therefore, we're building it once before building the dependent Capella images. .base: trigger: - project: "$IMAGE_BUILDER_GITLAB_REPOSITORY" + project: '$IMAGE_BUILDER_GITLAB_REPOSITORY' strategy: depend + branch: '$IMAGE_BUILDER_GITLAB_BRANCH' variables: CAPELLA_DOCKER_IMAGES_REVISION: $CAPELLA_DOCKER_IMAGES_REVISION - BUILD_FOR_LATEST_TAG: "1" + BUILD_FOR_LATEST_TAG: '1' # Only build base image - BASE: "1" + BASE: '1' .capella: trigger: - project: "$IMAGE_BUILDER_GITLAB_REPOSITORY" + project: '$IMAGE_BUILDER_GITLAB_REPOSITORY' strategy: depend + branch: '$IMAGE_BUILDER_GITLAB_BRANCH' parallel: matrix: - - CAPELLA_VERSION: ["5.0.0", "5.2.0", "6.0.0", "6.1.0"] + - CAPELLA_VERSION: ['5.0.0', '5.2.0', '6.0.0', '6.1.0'] variables: CAPELLA_DOCKER_IMAGES_REVISION: $CAPELLA_DOCKER_IMAGES_REVISION - BUILD_FOR_LATEST_TAG: "1" + BUILD_FOR_LATEST_TAG: '1' # Build all Capella images - CAPELLA_BASE: "1" - CAPELLA_CLI: "1" - CAPELLA_REMOTE: "1" - T4C_CLIENT_BASE: "1" - T4C_CLIENT_BACKUP: "1" - T4C_CLIENT_EXPORTER: "1" - T4C_CLIENT_REMOTE: "1" - T4C_CLIENT_REMOTE_PURE_VARIANTS: "1" - CAPELLA_EASE: "1" - CAPELLA_EASE_REMOTE: "1" - CAPELLA_READONLY: "1" + CAPELLA_BASE: '1' + CAPELLA_CLI: '1' + CAPELLA_REMOTE: '1' + T4C_CLIENT_BASE: '1' + T4C_CLIENT_REMOTE: '1' + T4C_CLIENT_REMOTE_PURE_VARIANTS: '1' .jupyter: trigger: - project: "$IMAGE_BUILDER_GITLAB_REPOSITORY" + project: '$IMAGE_BUILDER_GITLAB_REPOSITORY' strategy: depend + branch: '$IMAGE_BUILDER_GITLAB_BRANCH' variables: CAPELLA_DOCKER_IMAGES_REVISION: $CAPELLA_DOCKER_IMAGES_REVISION - BUILD_FOR_LATEST_TAG: "1" + BUILD_FOR_LATEST_TAG: '1' # Only build jupyter image - JUPYTER: "1" + JUPYTER: '1' .papyrus: trigger: - project: "$IMAGE_BUILDER_GITLAB_REPOSITORY" + project: '$IMAGE_BUILDER_GITLAB_REPOSITORY' strategy: depend + branch: '$IMAGE_BUILDER_GITLAB_BRANCH' variables: CAPELLA_DOCKER_IMAGES_REVISION: $CAPELLA_DOCKER_IMAGES_REVISION - BUILD_FOR_LATEST_TAG: "1" + BUILD_FOR_LATEST_TAG: '1' # Only build papyrus images - PAPYRUS_BASE: "1" - PAPYRUS_REMOTE: "1" + PAPYRUS_BASE: '1' + PAPYRUS_REMOTE: '1' .eclipse: trigger: - project: "$IMAGE_BUILDER_GITLAB_REPOSITORY" + project: '$IMAGE_BUILDER_GITLAB_REPOSITORY' strategy: depend + branch: '$IMAGE_BUILDER_GITLAB_BRANCH' variables: CAPELLA_DOCKER_IMAGES_REVISION: $CAPELLA_DOCKER_IMAGES_REVISION - BUILD_FOR_LATEST_TAG: "1" + BUILD_FOR_LATEST_TAG: '1' # Only build papyrus images - ECLIPSE_BASE: "1" - ECLIPSE_REMOTE: "1" - ECLIPSE_REMOTE_PURE_VARIANTS: "1" + ECLIPSE_BASE: '1' + ECLIPSE_REMOTE: '1' + ECLIPSE_REMOTE_PURE_VARIANTS: '1' diff --git a/docs/docs/capella/cli.md b/docs/docs/capella/cli.md deleted file mode 100644 index 7491516a..00000000 --- a/docs/docs/capella/cli.md +++ /dev/null @@ -1,10 +0,0 @@ - - -# Capella CLI - - -!!! warning - A separate CLI image is no longer built, instead use `capella/base` / `t4c/client/base` diff --git a/docs/docs/capella/provisioning.md b/docs/docs/capella/provisioning.md new file mode 100644 index 00000000..ebe06a89 --- /dev/null +++ b/docs/docs/capella/provisioning.md @@ -0,0 +1,53 @@ + + +# Load models to your workspace automatically + +!!! info "Migration from `v1.X.X` to `v2.X.X` and later" + + This feature replaces the read-only image of version `v1.X.X`. + Before starting the new image, you have to clone the Git repositories + that you've passed to the read-only image manually. The path with all + repositories can then be mounted to the new image as described below. + +To load models to your workspace automatically, you can mount a volume to the +container. + +``` +docker run -d \ + -v path/to/models/on/host:/models \ + -e ECLIPSE_PROJECTS_TO_LOAD='[]' \ + capella/base +``` + +The `ECLIPSE_PROJECTS_TO_LOAD` environment variable is a JSON array that +contains: + +```json +[ + { + "revision": "master", // (1) + "nature": "project", // (2) + "path": "/models/directory", // (3) + "entrypoint": "test.aird" // (4) + } +] +``` + +1. The revision of the Eclipse project. In case of duplicated project names, + the revision is added as suffix to the project name. +2. Optional: Can be either 'project' or 'library'. Defaults to 'project'. + Ignored if the the directory provided in the `path` attribute contains a + `.project` file. +3. Path to the directory where the project should be loaded from. +4. Path to the aird file, starting from the directory provided in the `path` + attribute. Required if the `.aird` is not placed directly in the directory + provided as `path`. If None, the aird is searched in the path directory + without recursion. + +All additional attributes are ignored. + +You can use all images that are based on the `capella/base` image for this +feature. diff --git a/docs/docs/capella/readonly.md b/docs/docs/capella/readonly.md deleted file mode 100644 index 7a019c56..00000000 --- a/docs/docs/capella/readonly.md +++ /dev/null @@ -1,120 +0,0 @@ - - -# Capella read-only - - -!!! info - The Docker image name for this image is `capella/readonly` - -The read-only image builds on top of the Capella EASE remote image and provides -support for the read-only use of models. - -It clones a git repositories and automatically injects the cloned models in the -workspace. - -## Use the prebuilt image - -``` -docker run ghcr.io/dsd-dbs/capella-dockerimages/capella/readonly:$TAG -``` - -where `$TAG` is the Docker tag. For more information, have a look at our -[tagging schema](introduction.md#tagging-schema-for-prebuilt-images). Please -check the [`Run the container`](#run-the-container) section to get an overview -over environment variables you have to set during startup. - -## Build it yourself - -### Build it manually with Docker - -To build the image, please run: - -```zsh -docker build -t capella/readonly \ - --build-arg BASE_IMAGE=capella/ease/remote \ - readonly -``` - -## Run the container - -There are two options available for read-only containers. The first option -supports multiple repositories, but you need to JSON-serizalize it. With the -second option, you can provide the details as environment variables directly. - -Running the Capella read-only container is analogous to the Capella base -container. Please run the -[instructions of the Capella base container](../base.md#run-the-container). - -Optionally, if you want to change the log location of EASE, add the -`$EASE_LOG_LOCATION` environment variable and provide a path to a file as value -during `docker run`. The value should be the absolute path to log file. -Defaults to `/proc/1/fd/1` (i.e., Docker container logs) if not provided. - -In addition, choose one of the following two options and consider the -differences. - -### Provide repository details as JSON - -With this option, any number of Git models can be loaded. These must first be -serialized to JSON in the following format: - -```json -[ - { - "url": "https://github.com/DSD-DBS/py-capellambse.git", # Path that is used by 'git clone' - "revision": "master", - "depth": 1, # Optional: If depth == 0, the whole history is cloned. Defaults to 0 - "entrypoint": "tests/data/melodymodel/5_2/Melody Model Test.aird", # Path to the aird file, starting from the root of the repository - "nature": "project", # Optional: Can be either 'project' or 'library'. Defaults to 'project' - "username": "testuser", # Optional: Only need if repository access is restricted - "password": "token" # Optional: Only need if repository access is restricted - } -] -``` - -The JSON string has to be provided as value to the environment variable with -the key `GIT_REPOS_JSON`: - -```zsh - -e GIT_REPOS_JSON=$GIT_REPOS_JSON -``` - -### Provide repository details in separate environment variables - -With this option, you can only provide details for exactly one repository at -time. If you want to make any number of models available, please use option -[`Provide repository details as JSON`](#provide-repository-details-as-json). - -Add this section to your `docker run` command: - -```zsh - -e GIT_URL=$GIT_URL \ - -e GIT_ENTRYPOINT=$GIT_ENTRYPOINT \ - -e GIT_REVISION=$GIT_REVISION \ - -e GIT_DEPTH=$GIT_DEPTH \ - -e GIT_USERNAME=$GIT_USERNAME \ - -e GIT_PASSWORD=$GIT_PASSWORD -``` - -Please replace the followings variables (in addition to the general variables): - -- `$GIT_URL` with the URL to the Git repository. All URI-formats supported by - the `git clone` command will work. Please do NOT include credentials in the - URL as they will be not cleaned after cloning the model. You can provide HTTP - credentials via the `GIT_USERNAME` and `GIT_PASSWORD` variables (see below). -- `$GIT_ENTRYPOINT` with the relative path from the root of your repository to - the `aird`-file of your model, e.g. `path/to/model.aird`. -- `$GIT_REVISION` with the desired revision of the git repository. The revision - is cloned with the `--single-branch` option, therefore only the specific - revision is accessible. Only tags and branches are supported, commit hashes - are NOT supported. If empty, the whole repository gets cloned. -- `$GIT_DEPTH` with the desired git depth. If not provided, the whole history - will be cloned. -- `$GIT_USERNAME` with the git username if the repository is access protected. - Leave empty, when no authentication is required. -- `$GIT_PASSWORD` with the git password if the repository is access protected. - Leave empty, when no authentication is required. The password gets cleaned - after cloning and is not accessible in the RDP connection. diff --git a/docs/docs/ease.md b/docs/docs/ease.md deleted file mode 100644 index 8f480f9b..00000000 --- a/docs/docs/ease.md +++ /dev/null @@ -1,146 +0,0 @@ - - - -!!! info - The Docker image name for this image is `capella/ease` or `t4c/client/ease` - -The EASE images build on top of Eclipse based images (the Capella base image or -the T4C base image) respectively. They extend the base image with support for -Python EASE scripts. These EASE scripts will run automatically during startup. - -## Use the prebuilt image - -``` -docker run ghcr.io/dsd-dbs/capella-dockerimages/capella/ease:$TAG -``` - -where `$TAG` is the Docker tag. For more information, have a look at our -[tagging schema](./capella/introduction.md#tagging-schema-for-prebuilt-images). - -Please check the [`Run the container`](#run-the-container) section to get an -overview over environment variables you have to set during startup. - -## Build it yourself - -### Preparation - -#### Optional: Download Eclipse packages manually - -If your network is restricted and doesn't have access to the public Eclipse -registries, you have to manually download and inject the packages. Luckily -capella is an application build within eclipse which offers a command line tool -for downloading resources from eclipse software repositories. Refer to -[this wiki article](https://wiki.eclipse.org/Equinox_p2_Repository_Mirroring#Running_the_Mirroring_Tools) -if you are interested to learn the capabilities of the eclipse mirroring tool. - -You have to run the following commands for each of these following urls to -download the metadata and artifact for the packages: - -- -- -- - -```zsh -capella -nosplash -verbose --application org.eclipse.equinox.p2.artifact.repository.mirrorApplication --source --destination (e.g. file:ease/extensions/)> -``` - -```zsh -capella -nosplash -verbose --application org.eclipse.equinox.p2.metadata.repository.mirrorApplication --source --destination (e.g. file:ease/extensions/)> -``` - -where `` is `py4j`, `ease` or `swtbot`. `capellac` is the path to -the capella executable laying in the capella directory -(capella.zip/capella/capella). If you have build an AppImage (linux) or a -shortcut for it you can also call this with the displayed options. - -Each directory `ease/extensions/` should have the following -structure: - -- `content.jar` -- `artifacts.jar` -- `plugins/` - - `*.jar` files -- `features/` - - `*.jar` files - -### Build it manually with Docker - -If your network is unrestricted, you can build an EASE image with the following -command, whereby you replace `$BASE` with `capella` or `t4c/client`. - -```zsh -docker build -t $BASE/ease \ - --build-arg BASE_IMAGE=$BASE/base \ - --build-arg BUILD_TYPE=online \ - ease -``` - -If your network is restricted, please execute the steps described in -[Download Eclipse Packages manually](#optional-download-eclipse-packages-manually). -When your extensions are located in `ease/extensions` and the right subfolders, -please run: - -```zsh -docker build -t $BASE/ease \ - --build-arg BASE_IMAGE=$BASE/base \ - --build-arg BUILD_TYPE=offline \ - ease -``` - -## Run the container - -Run the container with this command and provide EASE Python scripts as a -volume. The scripts have to be located in the `/opt/scripts` directory (inside -the container)! - -For more information refer to: -[How does a EASE Python Script look like?](#how-does-an-ease-python-script-look-like). - -To run the container, just execute: - -```zsh -docker run -v script.py:/opt/scripts/script.py $BASE/ease -``` - -where `$BASE` is again `capella` or `t4c/client`. - -### Miscellaneous - -#### How does an EASE Python script look like? - -In general, you can try to execute the Py4J in the Eclipse environment for -development purposes first. When the script is tested, you can use it in our -container. - -Please make sure that any EASE Python scripts have the `onStartup` comment in -the header. That can be the first line or the first line after the module -docstring. This is required, otherwise the scripts will not be auto-executed. - -```python -# onStartup: 0 -``` - -An example script using our PyEclipseEase library could look like: - -```python -# onStartup: 0 -import pyease.ease - -if __name__ == "__main__": - logger = ease.logger - ease.log_to_file(os.environ["EASE_LOG_LOCATION"]) - - pyease.ease.open_eclipse_perspective("Capella") - logger.info("Hello world!") - - pyease.ease.kill_capella_process(30) -``` diff --git a/docs/docs/eclipse/base.md b/docs/docs/eclipse/base.md index 6aa9551d..d4459c46 100644 --- a/docs/docs/eclipse/base.md +++ b/docs/docs/eclipse/base.md @@ -61,21 +61,6 @@ To customise the Eclipse client you can it, and 1. compress the modified folder to get a `eclipse.tar.gz` again. -#### Optional: Download the EGit Eclipse package manually - -Our `eclipse/base` image is shipped with EGit preinstalled. If you have access -to from your build environment, -we're fetching the package automatically and there is nothing to do here. - -If your build environment can not access the package registry, there is the -option to pre-download the package and inject it during the build. - -1. Download the registry - (analogous to - [Download Eclipse packages manually](../ease.md#optional-download-eclipse-packages-manually)) -2. Place the files into `/tmp/egit` -3. Pass `--build-arg BUILD_TYPE=offline` to the `docker build` command. - ### Build it manually with Docker ```zsh diff --git a/docs/docs/index.md b/docs/docs/index.md index cbeab589..9988b5dd 100644 --- a/docs/docs/index.md +++ b/docs/docs/index.md @@ -17,7 +17,6 @@ images at this time: - [`base`](base.md) - [`capella/base`](capella/base.md) (without dropins or plugins) -- [`capella/readonly`](capella/readonly.md) If you need another image, please follow the [`Build images locally`](#build-images-locally) or @@ -83,11 +82,8 @@ flowchart LR BASE(base) --> PAPYRUS_BASE(papyrus/base) --> PAPYRUS_REMOTE(papyrus/remote) BASE(base) --> ECLIPSE_BASE(eclipse/base) --> ECLIPSE_REMOTE(eclipse/remote) --> ECLIPSE_REMOTE_PURE_VARIANTS(eclipse/remote/pure-variants) CAPELLA_BASE(capella/base) --> T4C_CLIENT_BASE(t4c/client/base) - CAPELLA_BASE(capella/base) --> CAPELLA_EASE(capella/ease) - T4C_CLIENT_BASE(t4c/client/base) --> T4C_CLIENT_EASE(t4c/client/ease) CAPELLA_BASE(capella/base) --> CAPELLA_REMOTE(capella/remote) --> CAPELLA_REMOTE_PURE_VARIANTS(capella/remote/pure-variants) T4C_CLIENT_BASE(t4c/client/base) --> T4C_CLIENT_REMOTE(t4c/client/remote) --> T4C_CLIENT_REMOTE_PURE_VARIANTS(t4c/client/remote/pure-variants) - CAPELLA_EASE(capella/ease) --> CAPELLA_EASE_REMOTE(capella/ease/remote) --> CAPELLA_READONLY(capella/readonly) style BASE fill:#b22222,color:#000000 style CAPELLA_BASE fill:#8feb34,color:#000000 @@ -96,14 +92,8 @@ flowchart LR style ECLIPSE_BASE fill:#fafad2,color:#000000 style T4C_CLIENT_BASE fill:#1e90ff,color:#000000 - style CAPELLA_READONLY fill:#dda0dd,color:#000000 - - style CAPELLA_EASE fill:#f4a460,color:#000000 - style T4C_CLIENT_EASE fill:#f4a460,color:#000000 - style CAPELLA_REMOTE fill:#228b22,color:#000000 style T4C_CLIENT_REMOTE fill:#228b22,color:#000000 - style CAPELLA_EASE_REMOTE fill:#228b22,color:#000000 style ECLIPSE_REMOTE fill:#228b22,color:#000000 style PAPYRUS_REMOTE fill:#228b22,color:#000000 @@ -122,9 +112,7 @@ image: :material-checkbox-blank-circle:{ style="color: #fafad2 " } [Eclipse Base](eclipse/base.md)
:material-checkbox-blank-circle:{ style="color: #5f9ea0 " } [Papyrus Base](papyrus/base.md)
:material-checkbox-blank-circle:{ style="color: #1e90ff " } [T4C Client Base](capella/t4c/base.md)
-:material-checkbox-blank-circle:{ style="color: #f4a460 " } [EASE](ease.md)
:material-checkbox-blank-circle:{ style="color: #228b22 " } [Remote](remote.md)
-:material-checkbox-blank-circle:{ style="color: #dda0dd " } [Capella read-only](capella/readonly.md)
:material-checkbox-blank-circle:{ style="color: #62f5f2 " } [pure::variants](pure-variants.md)
:material-checkbox-blank-circle:{ style="color: #f5626c " } [Jupyter notebook](jupyter/index.md)
diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 85bb72e7..2057c314 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -11,6 +11,7 @@ theme: accent: light blue features: - content.code.copy + - content.code.annotate nav: - Introduction: index.md - Base: base.md @@ -31,9 +32,7 @@ nav: - Introduction: capella/introduction.md - Base: capella/base.md - Remote: remote.md - - CLI: capella/cli.md - - EASE: ease.md - - Read-only: capella/readonly.md + - Provisioning: capella/provisioning.md - 'pure::variants': pure-variants.md - Build from source: capella/build-from-source.md - Team4Capella client: @@ -42,7 +41,6 @@ nav: - Exporter: capella/t4c/exporter.md - Importer: capella/t4c/importer.md - Remote: remote.md - - EASE: ease.md - Papyrus: - Base: papyrus/base.md - Eclipse: diff --git a/ease/Dockerfile b/ease/Dockerfile deleted file mode 100644 index 2dc26a29..00000000 --- a/ease/Dockerfile +++ /dev/null @@ -1,115 +0,0 @@ -# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -ARG BUILD_TYPE=offline -ARG BASE_IMAGE=capella/base - -FROM $BASE_IMAGE as prebuild - -SHELL ["/bin/bash", "-euo", "pipefail", "-c"] -ENV SHELL=/bin/bash - -USER root - -# Somehow OpenJDK does not install in one shot due to a (cyclic?) dependency on -# package ca-certificates-java. Performing the install again fixes it. -RUN apt-get update && \ - # https://forums.debian.net/viewtopic.php?t=151997 - apt-get install -y openjdk-17-jre || apt-get install -y openjdk-17-jre && \ - rm -rf /var/lib/apt/lists/* - -ARG GIT_EMAIL=contact@example.com -ARG GIT_USERNAME=CCM-Bot - -RUN git config --global user.name $GIT_USERNAME && \ - git config --global user.email $GIT_EMAIL - -# Use Virtual Display -ENV DISPLAY :99 - -RUN pip install --no-cache-dir py4j==0.10.9.7 - -USER techuser - -# Offline build (fixed version) -FROM prebuild as build_offline -ONBUILD COPY extensions /tmp/extensions -ONBUILD ENV PY4J_REPOSITORY=file:/tmp/extensions/py4j -ONBUILD ENV EASE_REPOSITORY=file:/tmp/extensions/ease -ONBUILD ENV SWTBOT_REPOSITORY=file:/tmp/extensions/swtbot - -# Online build (latest version) -FROM prebuild as build_online -ONBUILD ENV PY4J_REPOSITORY=https://eclipse.py4j.org/ -ONBUILD ENV EASE_REPOSITORY=https://download.eclipse.org/ease/release/latest/ -ONBUILD ENV SWTBOT_REPOSITORY=https://download.eclipse.org/technology/swtbot/releases/latest/ - -FROM build_${BUILD_TYPE} - -# Install EASE Dependencies -# - org.py4j.feature.feature.group -RUN /opt/capella/capella \ - -consoleLog \ - -application org.eclipse.equinox.p2.director \ - -noSplash \ - -repository ${PY4J_REPOSITORY} \ - -installIU org.py4j.feature.feature.group - -# Install EASE -# Following Plugins will be installed: -# - EASE Core Framework (Incubation) org.eclipse.ease.feature.feature.group Eclipse.org -# - EASE UI Components (Incubation) org.eclipse.ease.ui.feature.feature.group Eclipse.org -# - EASE Py4J Support (Incubation) org.eclipse.ease.lang.python.py4j.feature.feature.group Eclipse.org -# - EASE Python Support (Incubation) org.eclipse.ease.lang.python.feature.feature.group Eclipse.org -# - EASE Git Feature (Incubation) org.eclipse.ease.modules.team.git.feature.feature.group Eclipse.org -# - EASE Modules (Incubation) org.eclipse.ease.modules.feature.feature.group Eclipse.org -RUN /opt/capella/capella \ - -consoleLog \ - -application org.eclipse.equinox.p2.director \ - -noSplash \ - -repository ${EASE_REPOSITORY} \ - -installIU org.eclipse.ease.feature.feature.group,org.eclipse.ease.ui.feature.feature.group,org.eclipse.ease.lang.python.py4j.feature.feature.group,org.eclipse.ease.lang.python.feature.feature.group,org.eclipse.ease.modules.team.git.feature.feature.group,org.eclipse.ease.modules.feature.feature.group - -# Install SWTBot -# Following Plugins will be installed: -# - SWTBot for Eclipse Forms Testing org.eclipse.swtbot.forms.feature.group Eclipse.org - SWTBot -# - SWTBot for Eclipse Testing org.eclipse.swtbot.eclipse.feature.group Eclipse.org - SWTBot -# - SWTBot for GEF Testing org.eclipse.swtbot.eclipse.gef.feature.group Eclipse.org - SWTBot -# - SWTBot for SWT Testing org.eclipse.swtbot.feature.group Eclipse.org - SWTBot -# - SWTBot IDE Features org.eclipse.swtbot.ide.feature.group Eclipse.org - SWTBot -# - SWTBot Test Recorder and Code Generator org.eclipse.swtbot.generator.feature.feature.group Eclipse.org - SWTBot -RUN /opt/capella/capella \ - -consoleLog \ - -application org.eclipse.equinox.p2.director \ - -noSplash \ - -repository ${SWTBOT_REPOSITORY} \ - -installIU org.eclipse.swtbot.forms.feature.group,org.eclipse.swtbot.eclipse.feature.group,org.eclipse.swtbot.eclipse.gef.feature.group,org.eclipse.swtbot.feature.group,org.eclipse.swtbot.ide.feature.group,org.eclipse.swtbot.generator.feature.feature.group - -USER root - -RUN rm -rf /tmp/extensions -RUN echo "-Dorg.eclipse.swtbot.search.timeout=1000" >> /opt/capella/capella.ini - -RUN pip install --no-cache-dir pyease==0.2.0 - -ENV EASE_WORKSPACE /workspace -ENV EASE_SCRIPTS_LOCATION /opt/scripts -ENV EASE_LOG_LOCATION=/proc/1/fd/1 - -RUN mkdir /opt/scripts && \ - chown techuser /opt/scripts - -# Clean Workspace and set it up for EASE -RUN python -m pyease.ease -RUN chown -R techuser /workspace - -WORKDIR /home/techuser - -ENV GIT_ASKPASS=/etc/git_askpass.py - -COPY startup.sh /opt/startup.sh -RUN chmod +x /opt/startup.sh - -USER techuser - -ENTRYPOINT [ "/opt/startup.sh" ] diff --git a/ease/debug/Dockerfile b/ease/debug/Dockerfile deleted file mode 100644 index e3fa79cb..00000000 --- a/ease/debug/Dockerfile +++ /dev/null @@ -1,29 +0,0 @@ -# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -ARG BASE_IMAGE=capella/ease/remote -FROM $BASE_IMAGE - -USER root - -SHELL ["/bin/bash", "-euo", "pipefail", "-c"] - -RUN apt-get update && apt-get install -y wget -ARG NETWORK_ACCESS=unrestricted - -COPY libs /tmp/libs -RUN if [ "$NETWORK_ACCESS" = "restricted" ]; then \ - apt-get update && \ - find /tmp/libs -iname "*.deb" -exec apt-get install -y {} \; ; \ - else \ - wget -qO - https://gitlab.com/paulcarroty/vscodium-deb-rpm-repo/raw/master/pub.gpg \ - | gpg --dearmor \ - | dd of=/usr/share/keyrings/vscodium-archive-keyring.gpg && \ - echo 'deb [ signed-by=/usr/share/keyrings/vscodium-archive-keyring.gpg ] https://download.vscodium.com/debs vscodium main' \ - | tee /etc/apt/sources.list.d/vscodium.list && \ - apt-get update && apt-get install -y codium; \ - fi && \ - rm -rf /var/lib/apt/lists/* && \ - rm -r /tmp/libs; - -USER techuser diff --git a/ease/debug/libs/.gitkeep b/ease/debug/libs/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/ease/extensions/ease/.gitkeep b/ease/extensions/ease/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/ease/extensions/py4j/.gitkeep b/ease/extensions/py4j/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/ease/extensions/swtbot/.gitkeep b/ease/extensions/swtbot/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/ease/startup.sh b/ease/startup.sh deleted file mode 100755 index 44f9ff49..00000000 --- a/ease/startup.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -# Wait until script is available -until [ "$(ls /opt/scripts)" ] -do - echo "No scripts are available. Retry in 5 seconds."; - sleep 5; -done -echo "Found the following scripts: $(ls /opt/scripts)" -sleep 5; -Xvfb :99 -screen 0 1920x1080x8 -nolisten tcp & -/opt/capella/capella -data $EASE_WORKSPACE || r=$? -if [[ -n "$r" ]] && [[ "$r" == 158 || "$r" == 0 ]]; then exit 0; else exit 1; fi diff --git a/eclipse/Dockerfile b/eclipse/Dockerfile index f3ff302c..5d9d057c 100644 --- a/eclipse/Dockerfile +++ b/eclipse/Dockerfile @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 ARG BASE_IMAGE=base -ARG BUILD_TYPE=online FROM $BASE_IMAGE as base ENV DEBIAN_FRONTEND=noninteractive @@ -10,17 +9,8 @@ ENV DEBIAN_FRONTEND=noninteractive SHELL ["/bin/bash", "-euo", "pipefail", "-c"] ENV SHELL=/bin/bash -FROM base as build_online -ONBUILD USER root -ONBUILD ENV EGIT_REPOSITORY=https://download.eclipse.org/egit/updates/ - -FROM base as build_offline -ONBUILD USER root -ONBUILD ENV EGIT_REPOSITORY=file:/tmp/egit -ONBUILD COPY ./egit /tmp/egit -ONBUILD RUN chown -R techuser /tmp/egit - -FROM build_${BUILD_TYPE} +USER root +ARG ECLIPSE_REPOSITORY=https://download.eclipse.org # https://forums.debian.net/viewtopic.php?t=151997 RUN apt-get update && apt-get install -y openjdk-17-jre || apt-get install -y openjdk-17-jre @@ -51,7 +41,7 @@ RUN /opt/eclipse/eclipse \ -consoleLog \ -application org.eclipse.equinox.p2.director \ -noSplash \ - -repository ${EGIT_REPOSITORY} \ + -repository ${ECLIPSE_REPOSITORY}/egit/updates/ \ -installIU "org.eclipse.egit,org.eclipse.egit.core,org.eclipse.egit.ui" USER root diff --git a/pure-variants/Dockerfile b/pure-variants/Dockerfile index 8914aad6..6a4f94b6 100644 --- a/pure-variants/Dockerfile +++ b/pure-variants/Dockerfile @@ -2,19 +2,9 @@ # SPDX-License-Identifier: Apache-2.0 ARG BASE_IMAGE=capella/remote -ARG BUILD_TYPE=online FROM ${BASE_IMAGE} as base -FROM base as build_online -ONBUILD ENV ECLIPSE_REPOSITORY=https://download.eclipse.org/releases/2020-06/ - -FROM base as build_offline -ONBUILD USER root -ONBUILD ENV ECLIPSE_REPOSITORY=file:/tmp/dependencies -ONBUILD COPY ./dependencies /tmp/dependencies -ONBUILD RUN chown -R techuser /tmp/dependencies - -FROM build_${BUILD_TYPE} +ARG ECLIPSE_REPOSITORY=https://download.eclipse.org SHELL ["/bin/bash", "-euo", "pipefail", "-c"] ENV SHELL=/bin/bash @@ -39,7 +29,7 @@ RUN installUI=com.ps.consul.eclipse.purevariants.emf.feature.mapping.feature.gro -consoleLog \ -application org.eclipse.equinox.p2.director \ -noSplash \ - -repository ${ECLIPSE_REPOSITORY} \ + -repository ${ECLIPSE_REPOSITORY}/releases/2020-06/ \ -repository file:///tmp/pure-variants \ -installIU "$installUI" diff --git a/readonly/Dockerfile b/readonly/Dockerfile deleted file mode 100644 index ba313fb8..00000000 --- a/readonly/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -ARG BASE_IMAGE=capella/ease/remote -FROM $BASE_IMAGE - -SHELL ["/bin/bash", "-euo", "pipefail", "-c"] -ENV SHELL=/bin/bash - -USER root - -RUN pip install --no-cache-dir lxml==4.9.3 -ENV EASE_LOG_LOCATION=/proc/1/fd/1 - -COPY load_models.py /opt/scripts/load_models.py -COPY prepare_workspace.sh /opt/setup/prepare_workspace.sh - -USER techuser diff --git a/readonly/prepare_workspace.sh b/readonly/prepare_workspace.sh deleted file mode 100755 index b14f6986..00000000 --- a/readonly/prepare_workspace.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -set -exuo pipefail - -echo "---START_PREPARE_WORKSPACE---" -xvfb-run /opt/capella/capella -clean -data ${WORKSPACE_DIR:-/workspace} --launcher.suppressErrors -nosplash -consolelog -application org.eclipse.ease.runScript -script "file:/opt/scripts/load_models.py"; -if [[ "$?" == 0 ]] -then - echo "---FINISH_PREPARE_WORKSPACE---" -else - echo "---FAILURE_PREPARE_WORKSPACE---" - exit 1; -fi - -unset GIT_USERNAME GIT_PASSWORD GIT_ASKPASS GIT_REPOS_JSON - -echo "---START_SESSION---" diff --git a/remote/Dockerfile b/remote/Dockerfile index 35842da6..36ba9019 100644 --- a/remote/Dockerfile +++ b/remote/Dockerfile @@ -72,7 +72,8 @@ RUN mkdir -p /run/xrdp/sockdir && \ chown -R techuser /etc/xrdp /run/xrdp /var/log/xrdp* && \ chown techuser /var/log && \ chown techuser /etc/supervisord.conf /var/log/nginx /var/log/nginx/* && \ - chown techuser /etc/nginx + chown techuser /etc/nginx && \ + touch /etc/environment && chown techuser /etc/environment WORKDIR /home/techuser diff --git a/remote/autostart b/remote/autostart deleted file mode 100755 index d1820de3..00000000 --- a/remote/autostart +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh -# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -# Autostart script for OpenBox - -export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - -nitrogen --restore & - -if [ "$AUTOSTART_CAPELLA" = "1" ]; -then - if [ "$RESTART_CAPELLA" = "1" ]; - then - # Run capella in a loop: - ( while true; do /opt/capella/capella -data ${WORKSPACE_DIR:-/workspace} > /var/log/capella.stdout.log 2> /var/log/capella.stderr.log; sleep 1; done ) & - else - /opt/capella/capella -data ${WORKSPACE_DIR:-/workspace} > /var/log/capella.stdout.log 2> /var/log/capella.stderr.log & - fi -fi diff --git a/remote/startup.sh b/remote/startup.sh index 3a6c2600..b5cb75d8 100755 --- a/remote/startup.sh +++ b/remote/startup.sh @@ -50,4 +50,6 @@ else cat /tmp/supervisord/supervisord.xrdp.conf >> /etc/supervisord.conf fi +echo "---START_SESSION---" + exec supervisord diff --git a/tests/test_read_only.py b/tests/test_read_only.py deleted file mode 100644 index 676b3c13..00000000 --- a/tests/test_read_only.py +++ /dev/null @@ -1,151 +0,0 @@ -# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -import io -import json -import logging -import typing as t - -import conftest -import pytest -from docker.models import containers - -log = logging.getLogger(__file__) -log.setLevel("DEBUG") - - -@pytest.fixture(name="mode_success", params=["json", "json2", "legacy"]) -def fixture_mode_success(request: pytest.FixtureRequest) -> str: - return request.param - - -@pytest.fixture( - name="container_success", -) -def fixture_container_success( - git_ip_addr: str, - init_git_server: None, # pylint: disable=unused-argument - mode_success: str, -) -> t.Generator[containers.Container, None, None]: - repo_url = f"http://{git_ip_addr}:80/git/git-test-repo.git" - entrypoint_without_leading_slash = ( - f"{conftest.CAPELLA_VERSION}/test-project.aird" - ) - - env: dict[str, str] = { # type: ignore - "json": { - "GIT_REPOS_JSON": json.dumps( - [ - { - "url": repo_url, - "revision": conftest.GIT_REPO_BRANCH, - "depth": 1, - "entrypoint": entrypoint_without_leading_slash, - }, - { - "url": repo_url, - "revision": conftest.GIT_REPO_BRANCH, - "depth": 5, - "entrypoint": entrypoint_without_leading_slash, - }, - ] - ), - }, - # Test with starting slash in entrypoint - "json2": { - "GIT_REPOS_JSON": json.dumps( - [ - { - "url": repo_url, - "revision": conftest.GIT_REPO_BRANCH, - "depth": 1, - "entrypoint": conftest.ENTRYPOINT, - }, - ] - ), - }, - "legacy": { - "GIT_URL": repo_url, - "GIT_REVISION": conftest.GIT_REPO_BRANCH, - "GIT_DEPTH": 0, - "GIT_ENTRYPOINT": entrypoint_without_leading_slash, - }, - }[mode_success] | {"RMT_PASSWORD": "password"} - with conftest.get_container( - image="capella/readonly", environment=env - ) as container: - yield container - - -@pytest.fixture(name="mode_failure", params=["json", "legacy"]) -def fixture_mode_failure(request: pytest.FixtureRequest) -> str: - return request.param - - -@pytest.fixture(name="container_failure") -def fixture_container_failure( - mode_failure: str, -) -> t.Generator[containers.Container, None, None]: - env: dict[str, str] = { # type: ignore - "json": { - "GIT_REPOS_JSON": json.dumps( - [ - { - "url": "https://example.com/invalid-repository", - "revision": "main", - "depth": 0, - "entrypoint": "invalid.aird", - }, - ] - ), - }, - "legacy": { - "GIT_URL": "https://example.com/invalid-repository", - "GIT_ENTRYPOINT": "invalid.aird", - "GIT_REVISION": "main", - "GIT_DEPTH": 0, - }, - }[mode_failure] - with conftest.get_container( - image="capella/readonly", environment=env - ) as container: - yield container - - -def lines(bytes: bytes) -> list[bytes]: - return io.BytesIO(bytes).readlines() - - -@pytest.fixture(name="workspace_result") -def fixture_workspace_result( - container_success: containers.Container, -) -> containers.ExecResult: - conftest.wait_for_container(container_success, "---START_SESSION---") - - return container_success.exec_run("ls -A1 /workspace") - - -@pytest.mark.parametrize("mode_success", ["legacy"]) -def test_model_loading_with_legacy_env( - workspace_result: containers.ExecResult, -) -> None: - assert len(lines(workspace_result.output)) == 2 - - -@pytest.mark.parametrize("mode_success", ["json"]) -def test_model_loading_with_json_env( - workspace_result: containers.ExecResult, -) -> None: - assert len(lines(workspace_result.output)) == 3 - - -@pytest.mark.parametrize("mode_success", ["json2"]) -def test_model_loading_with_json2_env( - workspace_result: containers.ExecResult, -) -> None: - assert len(lines(workspace_result.output)) == 2 - - -def test_invalid_url_fails(container_failure: containers.Container) -> None: - with pytest.raises(RuntimeError): - conftest.wait_for_container(container_failure, "---START_SESSION---")