What is a Che-Theia plug-in

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, code formatting, and syntax highlighting: Enhance comfort of use with supported programming languages.

  • Keybindings: Add new keyboard mapping 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:

client server side plug ins
Figure 1. Client and server-side Che-Theia plug-ins

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. In most cases, 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.

Task plug-in

Che Extended Terminal

Allows to provide terminal for any of the containers of the workspace.

Extended Terminal extension

Che Factory

Handles the Eclipse Che Factories

Workspace plug-in

Che Container

Provides a container view that shows all the containers that are running in the workspace and allows to interact with them.

Containers plug-in

Dashboard

Integrates the IDE with the Dashboard and facilitate the navigation.

Che-Theia Dashbord extension

Che APIs

Extends the IDE APIs to allow interacting with Che-specific components (workspaces, preferences).

Che-Theia API extension

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 Adding a VS Code extension to a workspace.

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. These files can be referenced in a devfile to include Che-Theia plug-ins in a workspace.

Here is an overview of all fields that can be available in plugin meta YAML files. This document represents the plugin meta YAML structure (version 3).

The che-plugin-registry repository generates meta.yaml files at build time, from a che-theia-plugins.yaml file. This file contains a list of all Che-Theia plug-ins in the registry.

Table 1. meta.yml

apiVersion

Version 2 and higher where version is 1 supported for backwards compatibility

category

Available: Category must be set to one of the followings: Editor, Debugger, Formatter, Language, Linter, Snippet, Theme, Other

description

Short description of plugin’s purpose

displayName

Name shown in user dashboard

deprecate

Optional; section for deprecating plugins in favor of others

* autoMigrate - boolean

* migrateTo - new org/plugin-id/version, for example redhat/vscode-apache-camel/latest

firstPublicationDate

Not required to be present in YAML, as if not present, it will be generated during Plugin Registry dockerimage build

latestUpdateDate

Not required to be present in YAML, as if not present, it will be generated during Plugin Registry dockerimage build

icon

URL of an SVG or PNG icon

name

Name (no spaces allowed), must match [-a-z0-9]

publisher

Name of the publisher, must match [-a-z0-9]

repository

URL for plugin repository, for example, GitHub

title

Plugin title (long)

type

Che Plugin, VS Code extension

version

Version information, for example: 7.5.1, [-.a-z0-9]

spec

Specifications (see below)

Table 2. spec attributes

endpoints

Optional; plugin endpoint. See configuring-a-workspace-using-a-devfile.adoc#endpoints_che

containers

Optional; sidecar containers for the plug-in. Che Plugin and VS Code extension supports only one container

initContainers

Optional; sidecar init containers for the plug-in

workspaceEnv

Optional; environment variables for the workspace

extensions

Optional; Attribute that is required for VS Code and Che-Theia plug-ins in a form list of URLs to plug-in artefacts, such as .vsix or .theia files

Table 3. spec.containers. Notice: spec.initContainers has absolutely the same container definition.

name

Sidecar container name

image

Absolute or relative container image URL

memoryLimit

OpenShift memory limit string, for example 512Mi

memoryRequest

OpenShift memory request string, for example 512Mi

cpuLimit

OpenShift CPU limit string, for example 2500m

cpuRequest

OpenShift CPU request string, for example 125m

env

List of environment variables to set in the sidecar

command

String array definition of the root process command in the container

args

String array arguments for the root process command in the container

volumes

Volumes required by the plug-in

ports

Ports exposed by the plug-in (on the container)

commands

Development commands available to the plug-in container

mountSources

Boolean flag to bound volume with source code /projects to the plug-in container

initContainers

Optional; init containers for sidecar plugin

Lifecycle

Container lifecycle hooks. See lifecycle description

Table 4. spec.containers.env and spec.initContainers.env attributes. Notice: workspaceEnv has absolutely the same attributes

name

Environment variable name

value

Environment variable value

Table 5. spec.containers.volumes and spec.initContainers.volumes attributes

mountPath

Path to the volume in the container

name

Volume name

ephemeral

If true, the volume is ephemeral, otherwise the volume is persisted

Table 6. spec.containers.ports and spec.initContainers.ports attributes

exposedPort

Exposed port

Table 7. spec.containers.commands and spec.initContainers.commands attributes

name

Command name

workingDir

Command working directory

command

String array that defines the development command

Table 8. spec.endpoints attributes

name

Name (no spaces allowed), must match [-a-z0-9]

public

true, false

targetPort

Target port

attributes

Endpoint attributes

Table 9. spec.endpoints.attributes attributes

protocol

Protocol, example: ws

type

ide, ide-dev

discoverable

true, false

secure

true, false. If true, then the endpoint is assumed to listen solely on 127.0.0.1 and is exposed using a JWT proxy

cookiesAuthEnabled

true, false

requireSubdomain

true, false. If true, the endpoint is exposed on subdomain in single-host mode.

Table 10. spec.containers.lifecycle and spec.initContainers.lifecycle attributes

postStart

The postStart event that runs immediately after a Container is started. See postStart and preStop handlers

* exec: Executes a specific command, resources consumed by the command are counted against the Container

* command: ["/bin/sh", "-c", "/bin/post-start.sh"]

preStop

The preStop event that runs before a Container is terminated. See postStart and preStop handlers

* exec: Executes a specific command, resources consumed by the command are counted against the Container

* command: ["/bin/sh", "-c", "/bin/post-start.sh"]

Example meta.yaml for a Che-Theia plug-in: the Che machine-exec Service
  apiVersion: v2
  publisher: eclipse
  name: che-machine-exec-plugin
  version: 7.9.2
  type: Che Plugin
  displayName: Che machine-exec Service
  title: Che machine-exec Service Plugin
  description: Che Plug-in with che-machine-exec service to provide creation terminal
    or tasks for Eclipse CHE workspace containers.
  icon: https://www.eclipse.org/che/images/logo-eclipseche.svg
  repository: https://github.com/eclipse/che-machine-exec/
  firstPublicationDate: "2020-03-18"
  category: Other
  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.9.2"
       ports:
         - exposedPort: 4444
       command: ['/go/bin/che-machine-exec', '--static', '/cloud-shell', '--url', '127.0.0.1:4444']
Example meta.yaml for a VisualStudio Code extension: the AsciiDoc support extension
apiVersion: 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

Every time a user starts a Che workspace, a Che-Theia plug-in life cycle process starts. The steps of this process are as follows:

  1. Che server checks for plug-ins to start from the workspace definition.

  2. Che server retrieves plug-in metadata, recognizes each plug-in type, and stores them in memory.

  3. Che server selects a broker according to the plug-in type.

  4. The broker processes the installation and deployment of the plug-in. The installation process of the plug-in differs for each specific broker.

Plug-ins exist in various types. A broker ensures the success of a plug-in deployment by meeting all installation requirements.
che theia plug in lifecycle
Figure 2. Che-Theia plug-in lifecycle

Before a Che workspace is launched, Che server starts the workspace containers:

  1. The Che-Theia plug-in broker extracts the information about sidecar containers that a particular plug-in needs from the .theia file.

  2. The broker sends the appropriate container information to Che server.

  3. The broker copies the Che-Theia plug-in to a volume to have it available for the Che-Theia editor container.

  4. Che server then starts all the containers of the workspace.

  5. Che-Theia starts in its container and checks the correct folder to load the plug-ins.

A user experience with Che-Theia plug-in lifecycle
  1. When a user opens a browser tab with Che-Theia, Che-Theia starts a new plug-in session with:

    • Web Worker for frontend

    • Node.js for backend

  2. Che-Theia notifies all Che-Theia plug-ins with the start of the new session by calling the start() function for each triggered plug-in.

  3. A Che-Theia plug-in session runs and interacts with the Che-Theia backend and frontend.

  4. When the user closes the Che-Theia browser tab, or the session ended on a timeout limit, Che-Theia notifies all plug-ins with the stop() function for each triggered plug-in.

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.

Based on the required dependencies, Che-Theia plug-in can run as:

  • Embedded, also know as local

  • Remote

Embedded (local) plug-ins

The Embedded plug-ins are plug-ins without specific dependencies that are injected into the Che-Theia IDE. These plug-ins use the Node.js runtime, which runs in the IDE container.

Examples:

  • Code linting

  • New set of commands

  • New UI components

To include a Che-Theia plug-in or VS Code extension, define a URL to the plug-in .theia archive binary in the meta.yaml file. See Adding a VS Code extension to a workspace

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.yaml file 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

  • Embedded plug-ins are those Che-Theia plug-ins or VS Code extensions that do not require extra dependencies inside its container.

  • Remote plug-ins are containers that contain a plug-in with all required dependencies.

Table 11. Che-Theia plug-in comparison matrix: embedded vs remote
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 rather than 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.yaml file. 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, set the PLUGIN_REMOTE_ENDPOINT_EXECUTABLE environment variable in the Dockerfile.

Procedure
  • Start a remote plug-in endpoint using the CMD command in the Dockerfile:

    Dockerfile example
    FROM 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 ENTRYPOINT command in the Dockerfile:

    Dockerfile example
    FROM 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 inside the container. The Dockertfile ENTRYPOINT command defines this script, which executes the main process defined in the CMD command of the Dockerfile.

Eclipse Che uses images with a wrapper script to provide permission configurations to different infrastructures protected by advanced security. OpenShift Container Platform is an example of such an infrastructure.

  • 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:

    Dockerfile example
    FROM 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}
    Explanation:
    • The container launches the /entrypoint.sh script defined in the ENTRYPOINT command of the Dockerfile.

    • The script configures the permissions and executes the command using exec $@.

    • CMD is the argument for ENTRYPOINT, and the exec $@ command calls ${PLUGIN_REMOTE_ENDPOINT_EXECUTABLE}.

    • The 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 for starting a remote plug-in endpoint without any modifications.

Procedure

Modify the plug-in meta.yaml file properties command and args:

  • command - Eclipse Che uses the command properties to override the Dockerfile#ENTRYPOINT value.

  • args - Eclipse Che uses uses the args properties to override the Dockerfile#CMD value.

  • Example of a YAML file with the command and args properties 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 args instead of command to use an image with a wrapper script pattern and to keep a call of the entrypoint.sh script:

    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.sh wrapper script defined in the ENTRYPOINT command of the Dockerfile. The script executes [ ‘sh’, ‘-c”, ‘ ${PLUGIN_REMOTE_ENDPOINT_EXECUTABLE}’ ] using the exec “$@” command.

By modifying the command and args properties of the meta.yaml file, a user can:
  • Execute a service at a container start

  • Start a remote plug-in endpoint

To make these actions run at the same time:
  1. Start the service.

  2. Detach the process.

  3. Start the remote plug-in endpoint.