A Che-Theia plug-in is an extension of the development environment isolated from the IDE. Plug-ins can be packaged as files or containers to provide their own dependencies.
Extending Che-Theia using plug-ins can enable the following capabilities:
-
Language support: Extend the supported languages by relying on the Language Server Protocol.
-
Debuggers: Extend debugging capabilities with the Debug Adapter Protocol.
-
Development Tools: Integrate your favorite linters, and as testing and performance tools.
-
Menus, panels, and commands: Add your own items to the IDE components.
-
Themes: Build custom themes, extend the UI, or customize icon themes.
-
Snippets, formatters, and syntax highlighting: Enhance comfort of use with supported programming languages.
-
Keybindings: Add new keymaps and popular keybindings to make the environment feel natural.
Features and benefits of Che-Theia plug-ins
| Features | Description | Benefits |
|---|---|---|
Fast Loading |
Plug-ins are loaded at runtime and are already compiled. IDE is loading the plug-in code. |
Avoid any compilation time. Avoid post-installation steps. |
Secure Loading |
Plug-ins are loaded separately from the IDE. The IDE stays always in a usable state. |
Plug-ins do not break the whole IDE if it has bugs. Handle network issue. |
Tools Dependencies |
Dependencies for the plug-in are packaged with the plug-in in its own container. |
No-installation for tools. Dependencies running into container. |
Code Isolation |
Guarantee that plug-ins cannot block the main functions of the IDE like opening a file or typing |
Plug-ins are running into separate threads. Avoid dependencies mismatch. |
VS Code Extension Compatibility |
Extend the capabilities of the IDE with existing VS Code Extensions. |
Target multiple platform. Allow easy discovery of Visual Studio Code Extension with required installation. |
Che-Theia plug-in concept in detail
Eclipse Che provides a default web IDE for workspaces: Che-Theia. It is based on Eclipse Theia. It is a slightly different version than the plain Eclipse Theia one because there are functionalities that have been added based on the nature of the Eclipse Che workspaces. This version of Eclipse Theia for Che is called Che-Theia.
You can extend the IDE provided with Eclipse Che by building a Che-Theia plug-in. Che-Theia plug-ins are compatible with any other Eclipse Theia-based IDE.
Client-side and server-side Che-Theia plug-ins
The Che-Theia editor plug-ins let you add languages, debuggers, and tools to your installation to support your development workflow. Plug-ins run when the editor completes loading. If a Che-Theia plug-in fails, the main Che-Theia editor continues to work.
Che-Theia plug-ins run either on the client side or on the server side. This is a scheme of the client and server-side plug-in concept:
The same Che-Theia plug-in API is exposed to plug-ins running on the client side (Web Worker) or the server side (Node.js).
Che-Theia plug-in APIs
For the purpose of providing tool isolation and easy extensibility in Eclipse Che, the Che-Theia IDE has a set of plug-in APIs. The APIs are compatible with Visual Studio Code extension APIs. Usually, Che-Theia can run VS Code extensions as its own plug-ins.
When developing a plug-in that depends on or interacts with components of Che workspaces (containers, preferences, factories), use the Che APIs embedded in Che-Theia.
Che-Theia plug-in capabilities
Che-Theia plug-ins have the following capabilities:
| Plug-in | Description | Repository |
|---|---|---|
Che Extended Tasks |
Handles the Che commands and provides the ability to start those into a specific container of the workspace. |
|
Che Extended Terminal |
Allows to provide terminal for any of the containers of the workspace. |
|
Che Factory |
Handles the Eclipse Che Factories |
|
Che Container |
Provides a container view that shows all the containers that are running in the workspace and allows to interact with them. |
|
Dashboard |
Integrates the IDE with the Dashboard and facilitate the navigation. |
|
Che APIs |
Extends the IDE APIs to allow interacting with Che-specific components (workspaces, preferences). |
VS Code extensions and Eclipse Theia plug-ins
A Che-Theia plug-in can be based on a VS Code extension or an Eclipse Theia plug-in.
- A Visual Studio Code extension
-
To repackage a VS Code extension as a Che-Theia plug-in with its own set of dependencies, package the dependencies into a container. This ensures that Eclipse Che users do not need to install the dependencies when using the extension. See Using a Visual Studio Code extension in Che.
- An Eclipse Theia plug-in
-
You can build a Che-Theia plug-in by implementing an Eclipse Theia plug-in and packaging it to Eclipse Che.
Che-Theia plug-in metadata
Che-Theia plug-in metadata is information about individual plug-ins for the plug-in registry.
The Che-Theia plug-in metadata, for each specific plug-in, is defined in a meta.yaml file.
The che-plugin-registry repository contains .
|
API version (`v2`and higher) |
|
Available: |
|
Description (a phrase) |
|
Display name |
|
Date in the form |
|
URL of a svg icon |
|
Name (no spaces allowed) |
|
Name of the publisher |
|
URL of the source repository |
|
Title (long) |
|
|
|
Version information, for example: |
|
Specifications (see underneath) |
|
Plug-in endpoints |
|
Sidecar containers for the plug-in. |
|
Sidecar init containers for the plug-in |
|
Environment variables for the workspace |
|
Optional attribute required for VS Code and Che-Theia plug-ins. A list of URLs to plug-in artefacts, such as |
|
Sidecar container name |
|
Absolute or relative container image URL |
|
Kubernetes or OpenShift memory limit string, for example |
|
Kubernetes or OpenShift memory request string, for example |
|
Kubernetes or OpenShift CPU limit string, for example |
|
Kubernetes or OpenShift CPU request string, for example |
|
List of environment variables to set in the sidecar |
|
String array definition of the root process command in the container |
|
String array arguments for the root process command in the container |
|
Volumes required by the plug-in |
|
Ports exposed by the plug-in (on the container) |
|
Development commands available to the plug-in container |
|
Boolean flag to bound volume with source code |
|
Environment variable name |
|
Environment variable value |
|
Path to the volume in the container |
|
Volume name |
|
If true, the volume is ephemeral, otherwise the volume is persisted |
|
Exposed port |
|
Command name |
|
Command working directory |
|
String array that defines the development command |
|
Name (no spaces allowed) |
|
|
|
Target port |
|
Endpoint attributes |
|
Protocol, example: |
|
|
|
|
|
|
|
|
meta.yaml for a Che-Theia plug-in: the Che machine-exec ServiceapiVersion: v2
category: Other
description: Che Plugin with che-machine-exec service to provide creation terminal or tasks for Eclipse Che workspace containers
displayName: Che machine-exec Service
firstPublicationDate: "2019-12-02"
icon: https://www.eclipse.org/che/images/logo-eclipseche.svg
name: che-machine-exec-plug-in
publisher: eclipse
repository: https://github.com/eclipse/che-machine-exec/
title: Che machine-exec Service Plugin
type: Che Plugin
version: 7.5.1
spec:
endpoints:
- name: "che-machine-exec"
public: true
targetPort: 4444
attributes:
protocol: ws
type: terminal
discoverable: false
secure: true
cookiesAuthEnabled: true
containers:
- name: che-machine-exec
image: "quay.io/eclipse/che-machine-exec:7.5.1"
ports:
- exposedPort: 4444
meta.yaml for a VisualStudio Code extension: the AsciiDoc support extensionapiVersion: v2
category: Language
description: This extension provides a live preview, syntax highlighting and snippets for the AsciiDoc format using Asciidoctor flavor
displayName: AsciiDoc support
firstPublicationDate: "2019-12-02"
icon: https://www.eclipse.org/che/images/logo-eclipseche.svg
name: vscode-asciidoctor
publisher: joaompinto
repository: https://github.com/asciidoctor/asciidoctor-vscode
title: AsciiDoctor Plug-in
type: VS Code extension
version: 2.7.7
spec:
extensions:
- https://github.com/asciidoctor/asciidoctor-vscode/releases/download/v2.7.7/asciidoctor-vscode-2.7.7.vsix
Che-Theia plug-in lifecycle
When a user is starting a workspace, the following procedure is followed:
-
Che master checks for plug-ins to start from the workspace definition.
-
Plug-in metadata is retrieved, and the type of each plug-in is recognized.
-
A broker is selected according to the plug-in type.
-
The broker processes the installation and deployment of the plug-in (the installation process is different for each broker).
| There are different types of plug-ins. A broker ensures all installation requirements are met for a plug-in to deploy correctly. |
Before a Che workspace is launched, Che master starts containers for the workspace:
-
The Che-Theia plug-in broker extracts the plug-in (from the
.theiafile) to get the sidecar containers that the plug-in needs. -
The broker sends the appropriate container information to Che master.
-
The broker copies the Che-Theia plug-in to a volume to have it available for the Che-Theia editor container.
-
Che workspace master then starts all the containers of the workspace.
-
Che-Theia is started in its own container and checks the correct folder to load the plug-ins.
Che-Theia plug-in lifecycle:
-
When a user is opening a browser tab or window with Che-Theia, Che-Theia starts a new plug-in session (browser or remote TODO: 'what is remote in this context?'). Every Che-Theia plug-in is notified that a new session has been started (the
start()function of the plug-in triggered). -
A Che-Theia plug-in session is running and interacting with the Che-Theia back end and frontend.
-
When the user is closing the browser tab or there is a timeout, every plug-in is notified (the
stop()function of the plug-in triggered).
Embedded and remote Che-Theia plug-ins
Developer workspaces in Eclipse Che provide all dependencies needed to work on a project. The application includes the dependencies needed by all the tools and plug-ins used.
There are two different ways a Che-Theia plug-in can run. This is based on the dependencies that are needed for the plug-in: embedded (or local) and remote.
Embedded (or local) plug-ins
The plug-in does not have specific dependencies - it only uses a Node.js runtime, and it runs in the same container as the IDE. The plug-in is injected into the IDE.
Examples:
-
Code linting
-
New set of commands
-
New UI components
To include a Che-Theia plug-in as embedded, define a URL to the plug-in binary file (the .theia archive) in the meta.yaml file. In the case of a VS Code extension, provide the extension ID from the Visual Studio Code marketplace (see Using a Visual Studio Code extension in Che).
When starting a workspace, Che downloads and unpacks the plug-in binaries and includes them in the Che-Theia editor container. The Che-Theia editor initializes the plug-ins when it starts.
Remote plug-ins
The plug-in relies on dependencies or it has a back end. It runs in its own sidecar container, and all dependencies are packaged in the container.
A remote Che-Theia plug-in consist of two parts:
-
Che-Theia plug-in or VS Code extension binaries. The definition in the
meta.yamlfile is the same as for embedded plug-ins. -
Container image definition, for example,
eclipse/che-theia-dev:nightly. From this image, Che creates a separate container inside a workspace.
Examples:
-
Java Language Server
-
Python Language Server
When starting a workspace, Che creates a container from the plug-in image, downloads and unpacks the plug-in binaries, and includes them in the created container. The Che-Theia editor connects to the remote plug-ins when it starts.
Comparison matrix
When a Che-Theia plug-in (or a VS Code extension) does not need extra dependencies inside its container, it is an embedded plug-in. A container with extra dependencies that includes a plug-in is a remote plug-in.
| Configure RAM per plug-in | Environment dependencies | Create separated container | |
|---|---|---|---|
Remote |
TRUE |
Plug-in uses dependencies defined in the remote container. |
TRUE |
Embedded |
FALSE (users can configure RAM for the whole editor container, but not per plug-in) |
Plug-in uses dependencies from the editor container; if container does not include these dependencies, the plug-in fails or does not function as expected. |
FALSE |
Depending on your use case and the capabilities provided by your plug-in, select one of the described running modes.
Remote plug-in endpoint
Eclipse Che has a remote plug-in endpoint service to start VS Code Extensions and Che-Theia plug-ins in separate containers. Eclipse Che injects the remote plug-in endpoint binaries into each remote plug-in container. This service starts remote extensions and plug-ins defined in the plug-in meta.yaml file and connects them to the Che-Theia editor container.
The remote plug-in endpoint creates a plug-in API proxy between the remote plug-in container and the Che-Theia editor container. The remote plug-in endpoint is also an interceptor for some plug-in API parts, which it launches inside a remote sidecar container instead of an editor container. Examples: terminal API, debug API.
The remote plug-in endpoint executable command is stored in the environment variable of the remote plug-in container: PLUGIN_REMOTE_ENDPOINT_EXECUTABLE.
Eclipse Che provides two ways to start the remote plug-in endpoint with a sidecar image:
-
Defining a launch remote plug-in endpoint using a Dockerfile. To use this method, patch an original image and rebuild it.
-
Defining a launch remote plug-in endpoint in the plug-in
meta.yamlfile. Use this method to avoid patching an original image.
Defining a launch remote plug-in endpoint using Dockerfile
To start a remote plug-in endpoint, use the PLUGIN_REMOTE_ENDPOINT_EXECUTABLE environment variable in the Dockerfile.
-
Start a remote plug-in endpoint using the
CMDcommand in the Dockerfile:Dockerfile exampleFROM fedora:30 RUN dnf update -y && dnf install -y nodejs htop && node -v RUN mkdir /home/user ENV HOME=/home/user RUN mkdir /projects \ && chmod -R g+rwX /projects \ && chmod -R g+rwX "${HOME}" CMD ${PLUGIN_REMOTE_ENDPOINT_EXECUTABLE} -
Start a remote plug-in endpoint using the
ENTRYPOINTcommand in the Dockerfile:Dockerfile exampleFROM fedora:30 RUN dnf update -y && dnf install -y nodejs htop && node -v RUN mkdir /home/user ENV HOME=/home/user RUN mkdir /projects \ && chmod -R g+rwX /projects \ && chmod -R g+rwX "${HOME}" ENTRYPOINT ${PLUGIN_REMOTE_ENDPOINT_EXECUTABLE}
Using a wrapper script
Some images use a wrapper script to configure permissions. The script is defined it in the ENTRYPOINT command of the Dockerfile to configure permissions inside the container, and it script executes a main process defined in the CMD command of the Dockerfile.
Eclipse Che uses such images with a wrapper script to provide permission configurations on different infrastructures with advanced security, for example on OpenShift.
-
Example of a wrapper script:
#!/bin/sh set -e export USER_ID=$(id -u) export GROUP_ID=$(id -g) if ! whoami >/dev/null 2>&1; then echo "${USER_NAME:-user}:x:${USER_ID}:0:${USER_NAME:-user} user:${HOME}:/bin/sh" >> /etc/passwd fi # Grant access to projects volume in case of non root user with sudo rights if [ "${USER_ID}" -ne 0 ] && command -v sudo >/dev/null 2>&1 && sudo -n true > /dev/null 2>&1; then sudo chown "${USER_ID}:${GROUP_ID}" /projects fi exec "$@" -
Example of a Dockerfile with a wrapper script:
Dockefile exampleFROM alpine:3.10.2 ENV HOME=/home/theia RUN mkdir /projects ${HOME} && \ # Change permissions to let any arbitrary user for f in "${HOME}" "/etc/passwd" "/projects"; do \ echo "Changing permissions on ${f}" && chgrp -R 0 ${f} && \ chmod -R g+rwX ${f}; \ done ADD entrypoint.sh /entrypoint.sh ENTRYPOINT [ "/entrypoint.sh" ] CMD ${PLUGIN_REMOTE_ENDPOINT_EXECUTABLE}In this example, the container launches the
/entrypoint.shscript defined in theENTRYPOINTcommand of the Dockerfile. The script configures the permissions and executes the command usingexec $@.CMDis the argument forENTRYPOINT, and theexec $@command calls${PLUGIN_REMOTE_ENDPOINT_EXECUTABLE}. A remote plug-in endpoint then starts in the container after permission configuration.
Defining a launch remote plug-in endpoint in a meta.yaml file
Use this method to re-use images to start remote a plug-in endpoint without modifications.
Modify the plug-in meta.yaml file properties command and args:
-
command- Eclipse Che uses to overrideDockerfile#ENTRYPOINT. -
args- Eclipse Che uses to overrideDockerfile#CMD. -
Example of a YAML file with the
commandandargsproperties modified:apiVersion: v2 category: Language description: "Typescript language features" displayName: Typescript firstPublicationDate: "2019-10-28" icon: "https://www.eclipse.org/che/images/logo-eclipseche.svg" name: typescript publisher: che-incubator repository: "https://github.com/Microsoft/vscode" title: "Typescript language features" type: "VS Code extension" version: remote-bin-with-override-entrypoint spec: containers: - image: "example/fedora-for-ts-remote-plugin-without-endpoint:latest" memoryLimit: 512Mi name: vscode-typescript command: - sh - -c args: - ${PLUGIN_REMOTE_ENDPOINT_EXECUTABLE} extensions: - "https://github.com/che-incubator/ms-code.typescript/releases/download/v1.35.1/che-typescript-language-1.35.1.vsix" -
Modify
argsinstead ofcommandto use an image with a wrapper script pattern and to keep a call of theentrypoint.shscript:apiVersion: v2 category: Language description: "Typescript language features" displayName: Typescript firstPublicationDate: "2019-10-28" icon: "https://www.eclipse.org/che/images/logo-eclipseche.svg" name: typescript publisher: che-incubator repository: "https://github.com/Microsoft/vscode" title: "Typescript language features" type: "VS Code extension" version: remote-bin-with-override-entrypoint spec: containers: - image: "example/fedora-for-ts-remote-plugin-without-endpoint:latest" memoryLimit: 512Mi name: vscode-typescript args: - sh - -c - ${PLUGIN_REMOTE_ENDPOINT_EXECUTABLE} extensions: - "https://github.com/che-incubator/ms-code.typescript/releases/download/v1.35.1/che-typescript-language-1.35.1.vsix"Eclipse Che calls the
entrypoint.shwrapper script defined in theENTRYPOINTcommand of the Dockerfile. The script executes[ ‘sh’, ‘-c”, ‘ ${PLUGIN_REMOTE_ENDPOINT_EXECUTABLE}’ ]using theexec “$@”command.
|
To execute a service when starting the container and also to start a remote plug-in endpoint, use |
