Chapter 14. Administering workspaces

14.1. Workspace

A workspace is usually termed as a local directory with projects and meta-information that the integrated development environment (IDE) uses to configure projects. In CodeReady Workspaces, a workspace is the developer environment. The developer environment contains Docker containers, Kubernetes pods, and a virtual machine or localhost. Environment variables and storage volumes are part of the workspace. The developer environment also contains projects, project commands, and resource allocation attributes.

14.2. Environment

The workspace runtime environment is a set of machines where each machine is defined by a recipe. The environment is healthy when all the machines successfully start and the installers execute jobs. The environment is defined by a recipe that can have different types. The environment and infrastructure validate a recipe.

14.3. Machine

The runtime environment has a minimum of one machine that can be a Docker-formatted container or a Kubernetes pod. You can create multi-machine environments with as many machines as your project infrastructure requires. Each machine has a configuration and start policy. Machine crashes and start failures are signs of an unhealthy environment. Machines communicate by using the internal network, service:port.

14.4. Recipe

A workspace environment is defined by a recipe. The recipe can be one of the following:

  • single container image
  • Dockerfile
  • Docker Compose file
  • Kubernetes list of objects with multiple pods and services

14.5. Bootstrapper

The bootstrapper starts the installer script after the first process is executed in the machine following the CMD or ENTRYPOINT. The role of the bootstrapper is to start the installer scripts with a set of parameters and a configuration file. The bootstrapper is a small binary compiled from Go code.

14.6. Installer

The purpose of the installer is to install software and services, start servers, and activate agents. The workspace agent, executive agent, and terminal servers are important to the IDE and workspace. The language servers, SSH installer, and other servers bring new functionality to a workspace. The bootstrapper executes installer scripts that prepare the environment and checks for dependencies. See an example of an installer script that prepares the environment and installs the C# language server.

14.7. Volume

A volume is a fixed amount of storage that is used to persist workspace data. Workspace projects are automatically mounted into a host file system by default. A user can define extra volumes for each machine in the environment. Docker volumes, Kubernetes persistent volumes (PVs), and persistent volumes claims (PVCs) are examples of volumes.

14.8. Environment variables

The environment variables are propagated into each individual machine. Depending on the infrastructure, environment variables are propagated to Docker containers or Kubernetes pods.

14.9. What is next?

14.10. Managing workspaces

14.10.1. Creating workspaces

Use the stacks in the Dashboard to create a workspace. Images and configuration in these stacks are certified both for Docker and OpenShift. These stacks are used in daily functional testing.

14.10.1.1. Creating a workspace from stacks in the dashboard

To create a workspace from stacks in the Dashboard, take the following steps:

  1. In the Dashboard, in the left panel, click Stacks.
  2. Click the Duplicate stack icon for the stack that you want to create a clone of. A page titled after the selected stack opens.
  3. Edit the fields that you want to edit.
  4. Click Save.
ready to go stacks

14.10.1.2. Duplicating an existing stack

Create a stack and then use the resulting stack to create a workspace.

To create a copy of an existing stack, take the following steps:

  1. In the Dashboard, in the left panel, click Stacks.
  2. Click the Duplicate stack icon for the stack that you want to clone.
  3. Edit the Name field.
  4. In the Machines field, edit the Source field.
  5. Click Save. The Stack is successfully updated message confirms that the stack is updated.
  6. In the Dashboard, click Workspaces > Add Workspace.
  7. In the SELECT STACK section, scroll through the list to locate the stack that you created in the preceding steps.
  8. Click Create to create the workspace based on this stack.
duplicate stack

14.10.1.3. Creating a custom stack from a custom recipe

Author a custom recipe and then create a stack. Use the resulting stack to create a workspace.

To create a custom stack from a custom recipe, take the following steps:

  1. In the Dashboard, click Workspaces > Add Workspace.
  2. From the SELECT STACK field, select the required stack.
  3. Click Add Stack.
  4. In the Create Stack dialog box, click Yes to confirm that you want to create the stack from a recipe.
  5. In the Build stack from recipe window, type the recipe name from which you want to build this stack (example: FROM: eclipse/new-stack).
  6. Click OK.
  7. In the Name field, type a name for the stack.
  8. In the Runtimes > Machines > Recipe section, click Show to ensure that the stack is being created using the recipe that you set in the preceding steps (eclipse/new-stack, in this case).
  9. Click Save.
custom recipe stack

14.10.2. Starting workspaces

You can start a workspace in one of the following ways:

  • The workspace starts automatically after it is created in the user’s Dashboard.
  • In the user’s Dashboard, use the Run or Open buttons in the Workspace Details view.
  • Click a workspace name from the recent workspaces displayed in the left panel.
  • Use the REST API.

The workspace may take time to start depending on factors like network conditions, container image availability, and configured installers attempting to install additional tools and software in the runtime. Track the progress of the workspace start operation in the Workspace Start tab. The tabs for each machine in the workspace environment stream logs from the installers (terminal, exec agent, ws agent, and language servers if any).

14.10.3. Managing a workspace

After a workspace is created or started, you can modify it by adding projects, installers, environment variables, and volumes.

Important

To edit a raw workspace configuration, back up the working configuration to avoid breaking your workspace.

Change the configuration of a running workspace and saving it restarts the workspace. To learn more about workspace configuration, see:

ws details

14.11. Commands and IDE Macros

A command is:

  • A set of instructions that is injected into the workspace machine for execution
  • A goal to organize commands for your workflow
  • A context to scope the command to particular projects
  • A preview URL to expose the URL of a running server

Commands are saved in the configuration storage of your workspace and are part of any workspace export operation.

14.11.1. Command goals

A developer executes a command to achieve a particular step in the development workflow. CodeReady Workspaces provides the ability to organize commands per goal:

  • Build: Commands that build the projects in a workspace.
  • Test: Commands related to test execution.
  • Run: Commands that run projects in a workspace.
  • Debug: Commands used to start a debugging session.
  • Deploy: Commands that are used to deploy projects in a workspace on specific servers or services.
  • Common: Commands used for general purpose.

14.11.2. Command context

The context of a command defines the projects that the command can be used with. For example: a maven build command is relevant only if the project uses Maven.

14.11.3. Managing commands

Workspace commands are available in the Commands Explorer view. This view is accessible from the left pane. The commands are organized in this view by goal.

command explorer

To create new commands, use the + icon next to a goal. Alternatively, you can select a command from the tree to edit, duplicate, or delete it.

command editor

The command editor is a distinct tab in the existing editor pane. Double-click the tab to use the full-screen edit mode. The editor can be split vertically or horizontally to display multiple editors at once.

  • Name: A unique command name in your workspace. The name is not restricted to CamelCase.
  • Intructions: To learn more about instructions and macros, see the Macros section.
  • Goal: Use the dropdown list to change the goal of the command.
  • Context: By default, the command is available with all the workspace projects. You can scope the command to be available only for selected projects.
  • Preview: To learn more about servers, see the Servers section.

CodeReady Workspaces provides macros that can be used within a command or preview URL to reference workspace objects. To learn more, see the Macros section.

14.11.4. Macros list

When editing a command, you can access all the macros that can be used in the command’s instructions or in the preview URL. To display a complete list of macros, click on the Macros link.

command macros list

14.11.5. Auto-completing macros

You can auto-complete all macros used in the editor. To activate the auto-complete feature, press Ctrl+Space. This displays a menu listing all the possible macros based on what is typed.

command macros autocompletion

14.11.6. Using commands

You can use commands from the following widgets:

  • Command Palette
  • Command toolbar
  • Contextual menu in the Project Explorer view

14.11.6.1. Using the Command Palette

Use the Shift+F10 keys to open the Command Palette. Use the arrow keys to navigate through the list of commands. Use Enter to execute a selected command.

command palette

14.11.6.2. Using the command toolbar

Using the command toolbar, you can execute the most common Run and Debug goals. The toolbar provides access to all the executed commands and previews.

command toolbar
14.11.6.2.1. Using the Run and Debug buttons

To trigger commands directly from the Run and Debug buttons, you must define the commands for the Run and Debug goals.

You are asked to choose the default command associated with a button when you use this button for the first time and this button has multiple commands defined for a goal. Consecutive clicks of this button trigger the previously selected command.

To select a command to execute from a goal, click and hold the button. This command becomes the default command associated with the button.

14.11.6.2.2. Using the command controller

Use the command controller to view the state of the workspace and the last command that was executed. You can see the time span since a command was started and decide if it should be stopped or relaunched.

To view the list of all the previously executed commands when multiple commands are executed, click on the widget.

command toolbar expanded

To clean the list, remove the process of the command from the list of processes.

command clean toolbar
14.11.6.2.3. Using the Preview button

For commands used to start servers, define the preview URL to access the running server. To learn more, see the Preview URLs section.

The Preview button provides quick access to all of fthe servers that are running in the machines of the workspace.

14.11.7. Authoring command instructions

A command may contain a single instruction or a succession of commands. For example:

cd /projects/spring				1
mvn clean install
1
Each command starts on a new line
cd /projects/spring; mvn clean install		1
1
A succession of several commands where ; stands for a new line
cd /projects/spring && mvn clean install	1
1
A succession of several commands where execution of a subsequent command depends on the execution of the preceeding one. If the /projects/spring directory is absent, the mvn clean install command is not executed.

To check for conditions, use loops and other bash syntax:

mvn -f ${current.project.path} clean install	1
  if [[ $? -eq 0 ]]; then
    cp /projects/kitchensink/target/*.war /home/user/wildfly-10.0.0.Beta2/standalone/deployments/ROOT.war
    echo "BUILD ARTIFACT SUCCESSFULLY DEPLOYED..."
else
    echo "FAILED TO DEPLOY NEW ARTIFACT DUE TO BUILD FAILURE..."
fi
1
Copy build artifact only if build is successful.

14.11.8. Macros

CodeReady Workspaces provides macros that can be used within a command or preview URL to reference workspace objects. Macros are translated into real values only when used in the IDE.

Note

You cannot use macros in commands that are launched from the server side.

The following table lists the macros and their descriptions.

MacroDetails

${current.project.path}

Absolute path to the project or module currently selected in the Project Explorer tree.

${current.project.eldest.parent.path}

Absolute path to a project root (for example, in the Maven-multi-module project).

${current.class.fqn}

The fully qualified package.class name of the Java class currently active in the editor panel.

${current.project.relpath}

The path to the currently selected project relative to /projects. Effectively removes the /projects path from any project reference.

${editor.current.file.name}

Currently selected file in the editor.

${editor.current.file.basename}

Currently selected file in the editor without extension.

${editor.current.file.path}

Absolute path to the selected file in the editor.

${editor.current.file.relpath}

Path relative to the /projects directory to the selected file in editor.

${editor.current.project.name}

Project name of the file currently selected in the editor.

${editor.current.project.type}

Project type of the file currently selected in the editor.

${explorer.current.file.name}

Currently selected file in the project tree.

${explorer.current.file.basename}

Currently selected file in the project tree without extension.

${explorer.current.file.path}

Absolute path to the selected file in the project tree.

${explorer.current.file.relpath}

Path relative to the /projects directory in the project tree.

${explorer.current.project.name}

Project name of the file currently selected in the explorer.

${java.main.class}

Path to the main class.

${machine.dev.hostname}

Current machine host name.

${project.java.classpath}

Project classpath.

${project.java.output.dir}

Path to the Java project output directory.

${project.java.sourcepath}

Path to the Java project source directory.

${explorer.current.project.type}

Project type of the file currently selected in the explorer.

${server.<serverName>}

Returns protocol, hostname, and port of an internal server. <port> is defined by the same internal port of the internal service that you have exposed in your workspace recipe.

  • Returns the hostname and port of a service or application you launch inside a machine.
  • The hostname resolves to the hostname or the IP address of the workspace machine. This name varies depending on where Docker is running and whether it is embedded within a VM.
  • The port returns the Docker ephemeral port that you can give to your external clients to connect to your internal service. Docker uses ephemeral port mapping to expose a range of ports that your clients may use to connect to your internal service. This port mapping is dynamic. In case of OpenShift, a route is returned.

Macro

Details

${workspace.name}

Returns the name of the workspace.

${workspace.namespace}

Workspace namespace (defaults to che in single-user CodeReady Workspaces).

14.11.9. Environment variables

The workspace machine has a set of system environment variables that have been exported. They are reachable from your command scripts using the bash syntax.

export					1

$TOMCAT_HOME/bin/catalina.sh run	2
1
List of all the available machine system environment variables.
2
Reference an environment variable, where $TOMCAT_HOME points to the /home/user/tomcat8 directory.

14.12. Stacks

14.12.1. Stack overview

A stack is a workspace configuration template. Stacks are used to create workspaces in the User Dashboard. The stack includes meta-information such as scope, tags, components, description, name, and identification. You can filter stacks by machine type and scope. The type is either single machine or multi machine. You can also search for a stack by keyword. Stacks are displayed in the User Dashboard on the Create a workspace page.

See the Creating and starting workspaces user guide for more information.

14.12.2. Importing community supported stacks and applications

CodeReady Workspaces includes some stacks and sample applications that are pre-configured and tested. Stacks that are contributed by the CodeReady Workspaces community are not tested. Community stacks are located in the community stacks GitHub repository.

Each directory has ${technology}-stack.json and ${technology}-samples.json.

To import a stack, follow these steps:

  1. Copy the content of the JSON files.
  2. Go to ${CHE_HOST}/swagger/#!/stack/createStack.
  3. Paste the content of the JSON file to the body field.
  4. Click the Try it out button.

You can choose a different name or ID when there is a conflict with the stack ID or name.

For a multi-user setup, you can make your stack available for a particular user or all users in the system. See stack sharing for more information.

To import sample applications, move *-stacks.json files to:

  • ${LOCAL_STORAGE}/instance/data/templates for Docker infrastructure.
  • ${mount-path-of-che-data-volume}/templates for OpenShift and Kubernetes infrastructure. You need administrator privileges to get the host path and to access the host directory. Also, the new JSON files have the same permissions as the original samples.json file.

You can find Dockerfiles for all stacks in the CodeReady Workspaces Dockerfiles repository.

14.12.3. Sharing stacks and system stacks

You can share stacks with selected users or with all users in the system if you have system privileges. You share stacks by making REST calls.

To share stacks with users:

  • Log in as administrator
  • Go to /swagger/#!/stack/searchStacks to get a list of all stacks. You may filter search by tags.
  • Find your stack by name and get its ID.
  • The next API to use is: /swagger/#!/permissions
  • Find the below POST method:
stack permissions
  • Use the following JSON file and replace ${STACK_ID} with an actual ID:
{
"userId": "*",
  "domainId": "stack",
  "instanceId": "${STACK_ID}",
  "actions": [
    "read",
    "search"
  ]
}

If you get 204, all the users in the system see the stack. To share a stack with a particular user, get the user’s ID and use it instead of * in the JSON file.

The administrator can remove pre-configured stacks and replace them with custom stacks. The administrator can also remove permissions from stacks. You can create stacks either in the user dashboard or by using any REST client. You can use Swagger ($CHE_HOST:$CHE_PORT/swagger) to bundle with CodeReady Workspaces.

14.12.4. Loading stacks

Stacks are loaded from a JSON file that is packaged into resources of a special component that is deployed with the workspace master. This JSON file is not exposed to users. You can perform stack management using REST APIs in the User Dashboard.

When a user first starts CodeReady Workspaces, stacks are loaded from a JSON file only when the database is initialized. This is the default policy that can be changed. To keep getting stack updates with the new CodeReady Workspaces stacks, set CHE_PREDEFINED_STACKS_RELOADONSTART=true in che.env. When set to true, stacks.json is used to update CodeReady Workspaces database each time the CodeReady Workspaces server starts. This means CodeReady Workspaces gets all the stacks in stacks.json and uploads the stacks to a database. This allows you to keep existing custom stacks and get stack updates from new CodeReady Workspaces releases. New and edited stacks that have fixes in the stack definition are merged in with the other stacks.

Name conflicts are possible. A name conflict happens when a new CodeReady Workspaces version provides a stack with a name that already exists in the database.

14.12.5. Creating stacks in CodeReady Workspaces

Every stack is based on a container image. The image is used in an OpenShift deployment when a workspace is started. The resulting container in a pod is used both as build and runtime for a user application. It is also used in CodeReady Workspaces agents that are installers that activate the terminal, workspace agent, and language servers.

Because all agents have their dependencies, the underlying images must have those dependencies available.

Agents are injected in the running containers. Therefore, the current container user must have write access to the ~/che directory. This is also a requirement for an image that can be used in a workspace stack definition.

14.12.5.1. Choosing a base image

For a base image of your custom stack, you can:

  • Inherit an image from one of the certified images
  • Use an existing Dockerfile or a container image
14.12.5.1.1. Using a certified CodeReady Workspaces image

To create a custom image and to satisfy all the CodeReady Workspaces agent dependencies, inherit the image from one of the certified CodeReady Workspaces images that are used in the provided stacks.

Example Dockerfile using a certified CodeReady Workspaces image

FROM registry.redhat.io/codeready-workspaces/stacks-java-rhel8
RUN sudo dnf install some-software

Table 14.1. List of certified CodeReady Workspaces images

LanguageImage

Java

registry.redhat.io/codeready-workspaces/stacks-java-rhel8

C++

registry.redhat.io/codeready-workspaces/stacks-cpp-rhel8

.NET

registry.redhat.io/codeready-workspaces/stacks-dotnet-rhel8

Golang

registry.redhat.io/codeready-workspaces/stacks-golang-rhel8

Node.js

registry.redhat.io/codeready-workspaces/stacks-node-rhel8

PHP

registry.redhat.io/codeready-workspaces/stacks-php-rhel8

Python

registry.redhat.io/codeready-workspaces/stacks-python-rhel8

Note

The images are available in the recipe blocks of the stacks.json file in the Red Hat CodeReady Workspaces repository.

14.12.5.1.2. Using a custom image

To use your own Dockerfile or a container image for a custom stack, ensure that you modify the Dockerfile, so that the image meets the following requirements:

  • Includes OpenJDK 1.8 or newer: Even for Node.js or PHP images, Java is required (the workspace agent is a Tomcat server that needs Java).
  • Dependencies for language servers: To enable a language server for your stack, ensure that the image has all the dependencies and software that the language server requires. To view the install scripts that agents use, see the particular page in the Eclipse Che repository. For example, a JSON language server requires Node.js.
  • Installed language servers: Use the following commands to install the language server:

    curl -s ${AGENT_BINARIES_URI} | tar xzf - -C ${LS_DIR}
    
    touch ${LS_LAUNCHER}
    chmod +x ${LS_LAUNCHER}
    echo "nodejs ${LS_DIR}/vscode-json-server/out/jsonServerMain.js --stdio" > ${LS_LAUNCHER}
  • Write access to the /home/jboss/ and /projects/ directories and to the /etc/passwd and /etc/group files: The user’s home directory must be writable for any user. By default, all containers in OpenShift are run with arbitrary users that do not have sudo privileges and write access to most of the directories in the container. To give users sudo privileges and write access, see, for example, lines 76 and 77 of the stacks-java-rhel8 Dockerfile (select the Dockerfile tab to see the code). Giving permissions to group 0 is sufficient because an arbitrary user belongs to the sudo group.
  • Non-terminating CMD instruction: CodeReady Workspaces workspace master creates a deployment and waits for a pod to acquire a RUNNING state. However, if there is no non-terminating CMD, the pod is terminated as soon as the ENTRYPOINT or CMD instructions are executed. Therefore, a non-terminating CMD instruction is added to all images (for example, CMD tail -f /dev/null).

Example Dockerfile using a custom image

FROM <myregistry/myimage>
USER root
RUN dnf install -y java-1.8.0-openjdk-devel [some-software]
CMD tail -f /dev/null

14.12.5.2. Building a custom stack

14.12.5.2.1. Building a Docker image

Procedure

To build a Docker image, see the docker build documentation.

14.12.5.2.2. Uploading an image to the registry

Procedure

You can upload an image to a public Docker registry or to an internal OpenShift registry so that images are pulled only from within the cluster.

14.12.5.2.3. Creating a custom stack

Procedure

For detailed steps to create a custom stack, see the Duplicate an existing stack and the Creating a custom stack sections in the Eclipse Che documentation chapter on managing workspaces.

Note

When duplicating an existing stack, ensure to use your custom image and add or remove the agents as required by your stack.

14.12.5.3. Sharing stacks

Procedure

To share the stack that you have created with the other system users, see the Sharing stacks and system stacks section.

14.13. Recipes

14.13.1. Supported Recipe Formats

Depending on the infrastructure, CodeReady Workspaces supports the following default recipe formats:

InfrastructureDocker-formatted container imageDockerfileComposefileKubernetes YAML

Docker

Supported

Supported

Supported

Not supported

OpenShift

Supported

Not supported

Not supported

Supported

14.13.2. Docker-formatted container image requirements and limitations

The Docker-formatted container image recipe pulls an image from a Docker registry or uses the local image. The recipe then runs the image and creates a pod that references this image in the container specification. The following are Docker-formatted container image requirements and limitations for a workspace machine:

  1. Use a non-terminating CMD or ENTRYPOINT. For a custom image, use, for example, tail -f /dev/null as one of the main processes.
  2. For OpenShift only:

    • Do not use any processes and operations with sudo in CMD. See Enable SSH and sudo for more information.
    • Use CodeReady Workspaces base stacks. You can also build your own image, but inherit from one of the base stacks.

14.13.3. Dockerfile definition and limitations

A Dockerfile is a set of instructions that Docker performs to build an image. After you provide a Dockerfile for your workspace machine, CodeReady Workspaces initiates a Docker build and runs the resulting image. The following are the limitations:

  1. The COPY and ADD instructions fail because there is no context in docker build.
  2. To avoid long build times with long Dockerfiles, build your image locally, push it to DockerHub, and then use the pushed image as a Docker-formatted container image recipe type. The start timeout for a workspace is five minutes.

14.13.4. Running multi-container workspaces using Compose files

You can run multi-container workspaces using Compose files on Docker. The following syntax is not supported: Local "build.context" and "build.dockerfile".

Because workspaces can be distributed, you cannot have host-local build and Dockerfile contexts. You can remotely host these aspects in a Git repository. CodeReady Workspaces sources the Compose file from the remote system and uses it as the build context.

You can run into a failure when the Dockerfile or build context requires you to ADD or COPY other files into the image. The local workspace generator cannot access these remote files.

14.13.4.1. Accessing remote files

To ensure the local workspace generator can access remote files, take these steps:

  1. Pre-package the build context or Dockerfile into an image.
  2. Push that image into a registry.
  3. Reference the pre-built image in your Compose file.

The following is an example of a remote context that works:

build:
  ## remote context will work
  context: https://github.com/eclipse/che-dockerfiles.git#master:recipes/stack-base/ubuntu

  ## local context will not work
  context: ./my/local/filesystem

14.13.4.2. Using private repositories

To use private repositories in a remote build context:

  1. Set up the SSH keys on your host machine.
  2. Add the remote repository hostname or IP to the list of known hosts.

The following is an example of a YAML file using a private repository:

## The following will use master branch and build in recipes/stack-base/ubuntu folder
build:
  context: git@github.com:eclipse/che-dockerfiles.git#master:recipes/stack-base/ubuntu

14.13.4.3. Configuring privileged access

The privileged Compose option does not support securing the underlying host system.

To configure the CodeReady Workspaces server to give all containers privileged access, set the CHE_PROPERTY_machine_docker_privilege__mode variable to true.

Important

Setting the CHE_PROPERTY_machine_docker_privilege_mode variable to true makes the host system vulnerable and gives all containers access to the host system.

14.13.4.4. Special considerations when using Compose files

Build images

When a Compose file includes both build instructions and a build image, the build instructions override the build image, if it exists.

Container names

The container_name is skipped during execution. Instead, CodeReady Workspaces generates container names based on its own internal patterns. Avoid naming conflicts. Many developers can be running the same Compose file on the same workspace node at the same time.

The following is an example of a YAML file using a container name:

container_name: my_container

Volumes

To define volumes for workspace machines, see Volumes. Volume instructions in a Compose file are not supported.

Networks

CodeReady Workspaces does not support Compose networks. The use of aliases is supported by the links command.

The following is an example of a YAML file using networks:

## Not supported
networks:
  internal:
  aliases: ['my.alias’]
## Not supported
networks:
  internal:
  driver: bridge

Hostname

Hostname is not supported. The machine’s name is used for the hostname. You can use links aliases syntax to add additional hostnames to a machine.

Binding ports

Binding ports to the host system is not supported to ensure that containers do not use already assigned host ports. Users can work around this limitation by adding servers to machines.

Environment file

The env_file Compose option is not supported. Environment variables can be manually entered in the Compose file or machine configuration. See Environment variables for more information.

14.13.5. Kubernetes YAML limitations and restrictions

When a workspace is starting, CodeReady Workspaces creates various Kubernetes resources to support the IDE and development tools. Workspaces primarily consist of a Deployment which runs a Kubernetes pod. The following are limitatons and restrictions:

  1. CodeReady Workspaces allows users specify Pods, Deployments, ConfigMaps, and Services in recipes

    • If a Pod is specified, it will be wrapped in a simple Deployment when running the workspace
  2. Other object kinds will be ignored (PVC and route) or a workspace fails to start with an exception from Kubernetes.
  3. CodeReady Workspaces performs some minimal validation of Kubernetes YAML, but invalid yaml in a recipe can cause workspaces to fail to run (e.g. referring to a non-existent configmap)
  4. You cannot use volumes in the container and pod definition. See Volumes for information about persisting and sharing data between pods.

The following is an example of a custom recipe with two containers, a simple config map, one deployment, and a service that is bound to port 8081:

kind: List
items:
  -
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          my-workspace-pod: dev
      template:
        metadata:
          name: dev-pod
          labels:
            my-workspace-pod: dev
        spec:
          containers:
            -
              image: eclipse/ubuntu_jdk8:latest
              name: main
              ports:
              -
                containerPort: 8081
                protocol: TCP
              env:
              -
                name: MY_ENV_VAR
                valueFrom:
                  configMapKeyRef:
                    name: my-configmap
                    key: my-key
            -
              image: eclipse/ubuntu_jdk8:latest
              name: main1
  -
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: my-configmap
    data:
      my-key: my-value
  -
    kind: Service
    apiVersion: v1
    metadata:
      name: my-service
    spec:
      selector:
        name: app
      ports:
      - protocol: TCP
        port: 8081
        targetPort: 8081

As a bare minimum, a Kubernetes YAML recipe must contain at least one Pod or Deployment, in which the main dev machine is run.

You can also specify multiple containers within the workspace pod. CodeReady Workspaces treats those containers as workspace machines. These containers can have machine names defined in annotations. PodName/Container Name is the default naming pattern for a machine.

The following is an example of using annotations:

kind: List
items:
-
  apiVersion: v1
  kind: Pod
  metadata:
    name: any123123
    annotations:
      org.eclipse.che.container.main.machine_name: myMachine
      org.eclipse.che.container.main1.machine_name: myMachine1
  spec:
    containers:
      -
        image: rhche/spring-boot:latest
        name: main
        ports:
          -
            containerPort: 8080
            protocol: TCP
        resources: {}

      -
        image: rhche/spring-boot:latest
        name: main1
        ports:
          -
            containerPort: 8080
            protocol: TCP
        resources: {}

14.14. Servers

14.14.1. What are servers?

A server defines the protocol port of a process that runs in a machine. It has a name, path, and attributes. The path defines the base path of the service that is used by the server. Attributes are optional and can be used to tune the server or for identification. You can add a server when you need to access a process in your workspace machine.

To add a server, use the User Dashboard or edit the workspace machine configuration YAML file.

The following is an example of the YAML file:

"node": {
    "port": "3000",
    "protocol": "http",
    "path": "/",
    "attributes": {}
}

The following is an example of the User Dashboard:

servers dashboard
Note

If your workspace is running, saving a new server restarts the workspace.

14.14.2. Preview URLs

Adding the server with port 3000 does not mean you can use this port to access a server. Each server is assigned a URL when a workspace is running.

  • On Docker, port 3000 is published to a random port from the ephemeral port range from 32768 to 65535. The server URLs change every time you start a workspace.
  • On OpenShift, a route bound to a service is created. Routes are persistent URLs.

14.14.3. Getting preview URLs

In this example, you added a server with port 3000 and started a workspace. The following are ways to get the server’s preview URL:

  • Use a macro command.
  • In the IDE, Click the + icon in the bottom panel under the editor.
servers
  • In the User Dashboard, click Workspaces > YourWorkspace > Servers.

You can also see internal server URLs. Internal servers launch when the workspace container or pod is available.

14.14.4. Exposing internal servers

To access a port internally within a workspace, expose it internally, but do not make it publicly accessible. For example, a database server is exposed only for the web application and because of security concerns, it should not be accessible publicly. The database server is exposed as internal.

To expose a server as internal, add the corresponding attribute into the server configuration YAML file:

"db": {
    "port": "3200",
    "protocol": "tcp",
    "attributes": {
        "internal": "true"
    }
}

The application is able to fetch the database URL from the workspace runtime and access the database. The database URL is not accessible publicly from the browser.

14.14.5. Exposing secure servers

Secure servers are exposed publicly but access is restricted only for users who have permissions to the workspace. The authentication proxy is set up as the exposed server and the machine token is required to request it.

To expose a server as secure, add the corresponding attributes into the server configuration YAML file:

"tooling": {
    "port": "4921",
    "protocol": "http",
    "attributes": {
        "secure": "true",
        "unsecuredPaths": "/liveness",
        "cookiesAuthEnabled": "true"
    }
}

The following describes the attributes:

secure
Indicates whether the server is exposed as secure. The default value is false.
unsecuredPaths
Configures the secure servers. It contains a comma-separated list of URLs that are considered non-secure on the given server and can be accessible without a token. It may be needed when the server provides any public APIs. The API endpoint for health checks is an example.
cookiesAuthEnabled
Indicates whether cookies should be searched for a token. By default, it is disabled. You can enable this attribute if you are sure that servers cannot be attacked by Cross-Site Request Forgery (CSRF) or have special protection from it.
Note

This is in the beta phase and disabled by default. See Secure servers for information on how to enable secure servers.

14.15. Installers

14.15.1. What are installers?

Installers are scripts that are added into machines in a runtime. Once running, installers:

  1. Prepare the environment and download dependencies for a particular software or tool.
  2. Install chosen software and dependencies.
  3. Launch software and tools with particular arguments and modes that provide extra functionality for a workspace.

Installers are typically language servers and tools that provide features such as SSH access to a workspace machine. You can find a complete list of available installers in the Workspace details > Installers tab.

The following is an example of installers:

"installers": [
    "org.eclipse.che.exec",
    "org.eclipse.che.terminal",
    "org.eclipse.che.ws-agent",
    "org.eclipse.che.ssh"
        ]

14.15.2. How installers work

Installers are saved in a configuration file that a bootstrapper uses to execute jobs. An installer script works exactly the same way as other shell scripts in Linux. The CodeReady Workspaces server checks if the launched process is running.

Some installers activate special agents, such as the workspace, terminal, and execution agents. If a workspace agent fails to start, the workspace is treated as if it has been started but the IDE is not usable. If the execution agent fails, the commands widget is unavailable.

14.15.3. What happens when enabling and disabling installers

You can enable or disable installers per machine by using the User Dashboard or by updating the workspace machine configuration. When an installer is enabled, the bootstrapper executes an installer script after the workspace has started.

The following shows installers that are enabled and disabled:

installers

14.15.4. Troubleshooting installer failures

14.15.4.1. Permission denied failure

Installers run as if a user in the container has sudoers privileges. If the user does not have the privileges, the installer fails with permission denied issues.

This problem can occur with OpenShift when a pod is run by a user with no permissions to use sudo or to access or modify resources on the file system.

In most cases, this problem can be solved by rebuilding the base image so that it already has all of the dependencies for particular agents that an installer activates.

14.15.4.2. Permission to files and directories failures

Another possible issue can be with permissions to files and directories. For example, an installer may need to write to the user home directory.

14.15.5. Installer registry and REST API

CodeReady Workspaces installers are stored in the Installer Registry. They can be viewed and edited through the Installer Registry REST API:

PathHTTP MethodDescription

/installer

GET

Get installers

/installer/{id}/version

GET

Get versions of installers by given id

/installer/orders

GET

Get installers, ordered by their dependencies

/installer/

POST

Add installer to the registry

/installer/{key}

PUT

Update installer in the registry

/installer/{key}

DELETE

Remove installer from the registry

14.16. Volumes

14.16.1. Default volumes for workspace containers

By default, workspace containers start with a default volume and have a minimum of one PVC that is located in the /projects directory.

Workspace projects are physically located in the /projects directory. When a workspace stops, the machines are destroyed, but the volumes persist.

14.16.2. Adding volumes

In order for your data to persist for a local Maven repository, the node_modules/ directory, Ruby gems, or the authorized_keys file for SSH connections, your workspace will need additional volumes. Each machine can add as many volumes as the underlying infrastructure can support. OpenShift may impose a limit on the number of volumes.

You can add volumes either by using the User Dashboard or by updating the machine configuration. The following is an example of the configuration file:

"volumes": {
  "myvolume": {
    "path": "/absolute/path/in/workspace"
  }
}

To avoid failures when updating the workspace configuration using REST APIs:

  • Use an absolute path.
  • The name and path cannot contain special characters, including dashes (-) or underscores (_).
Note

To allow machines to share the same volume, create a volume for each machine with an identical name.

14.16.3. Configuring workspaces

To configure workspaces on the OpenShift and Kubernetes infrastructure as ephemeral, set the persistVolumes attribute to false in the workspace configuration.

The following is an example of the configuration file:

"attributes": {
  "persistVolumes": "false"
}

In this case, regardless of the PVC strategy, all volumes would be created as emptyDir for the given workspace. When a workspace pod is removed for any reason, the data in the emptyDir volume is deleted forever.

14.17. Environment variables

Environment variables are defined per machine. Depending on the infrastructure, they are added either to the container or the Kubernetes pod definition. You can add, edit, and remove environment variables either in the User Dashboard or directly in the workspace machine configuration.

The following is an example of an environment variable:

"env": {
  "key": "value"
    }

You can use environment variables in applications running in a workspace, in commands, and in the terminal. The CodeReady Workspaces server also adds some environment variables that a user does not control, although they are available to use. For example, they can be used as an API endpoint or workspace ID.

The following shows how to add a new environment variable:

env variable

14.18. Projects

14.18.1. Creating projects in workspaces

Projects are always associated with a workspace and saved in a workspace configuration.

The following is an example of the project YAML file:

"projects": [
   {
     "description": "A basic example using Spring servlets. The app returns values entered into a submit form.",
     "source": {
       "location": "https://github.com/che-samples/web-java-spring.git",
       "type": "git",
       "parameters": {}
     },
     "links": [],
     "mixins": [],
     "problems": [],
     "name": "web-java-spring",
     "type": "maven",
     "path": "/web-java-spring",
     "attributes": {}
   }
 ]

Once a project is saved into a workspace configuration, the IDE checks if the project exists on a file system. Use the source.location URL to import projects that do yet exist on the file system. This happens during the IDE initialization stage.

You can add the following projects:

  • Git projects
  • remotely hosted archives
  • GitHub projects
  • example projects provided by CodeReady Workspaces

Project import tools can be found on the User Dashboard when you are creating a new workspace or editing an existing workspace in the IDE. Project import tools can also be found in the Workspace menu.

The following shows example projects:

projects

14.18.2. Defining project types

Plug-in developers can define their own project types. Since project types trigger certain behaviors within the IDE, the construction of the projects is important to understand.

  • A project type is defined as one primary type and zero or more mixin types.

    • A primary project type is one where the project is editable, buildable, and runnable.
    • A mixin project type defines additional restrictions and behaviors of the project, but it cannot be a primary project type by itself.

    The collection of primary and mixin types for a single project defines the aggregate set of attributes that will be stored as meta data within the project.

  • Project types describe different aspects of a project, such as:

    • the types of source files inside
    • the structure of the explorer tree
    • the way in which a command is executed
    • associated workflows
    • which plug-ins must be installed
  • A project defines a set of attributes. The attributes of a project can be mandatory or optional. Attributes that are optional can be dynamically set at runtime or during configuration.
  • Sub-projects may have different project types than their parents. Modules may physically exist within the tree structure of the parent. For example, subdirectories exist within the tree structure of the parent. Also, modules may physically exist outside the tree structure of the parent, such as when the parent is a soft link to the module project.

14.18.3. Creating a sub-project

A sub-project is a portion of a project that can have sets of commands run against it where the sub-directory is treated as the root working directory. Sub-projects make it possible to organize a single repository into multiple, independently buildable, and runnable units.

To create a module, right-click on a directory in the IDE explorer tree and select Convert to Project. You can then execute commands directly against this sub-project.

14.19. Troubleshooting failures in starting the workspace

Failures to start a workspace may be caused by the following factors:

  • Incorrect environment recipe
  • Restrictive network settings

14.19.1. Incorrect environment recipes

When a workspace is starting, an environment recipe is sent to Docker or to the OpenShift API. The CodeReady Workspaces server then listens to events provided by the given infrastructure. The CodeReady Workspaces server expects a running Docker container or an OpenShift pod. The server fails to start an environment and consequently the starting of the workspace fails if the infrastructure is unable to create and start a container or a pod from the provided recipe.

A recipe can be incorrect due to the following reasons:

  • The Docker build fails with the provided Dockerfile. This can be because of a broken Dockerfile or because of CodeReady Workspaces. If the Docker build in CodeReady Workspaces does not support context, consider editing the Docker recipe locally to ensure that it is a valid Dockerfile. Add or copy resources into an image locally on your machine, push the image to a registry, such as DockerHub, and use the resulting images in the recipe.
  • CodeReady Workspaces does not support certain Docker Compose syntax. Ensure that the Composefile is supported by CodeReady Workspaces.
  • Installing packages in your Dockerfile instructions can take time. This may be influenced by network settings.

14.19.1.1. Viewing logs from a failed workspace start

No installer logs are shown when a workspace fails to start because its container or pod are not launched. In most cases, only logs from infrastructure and image pull and build are shown. Analyse these logs to find the problem. The CodeReady Workspaces server also produces logs that are helpful in debugging the problem.

14.19.2. Restrictive network settings

The CodeReady Workspaces server and agents, which run in a workspace container or pod, and the user’s browser communicate with each other. Firewall, filtered ports, and other network restrictions may cause trouble when starting a workspace.

A workspace is considered to be in a RUNNING state after the CodeReady Workspaces server verifies that the workspace agent is up. The workspace agent also tries to reach the CodeReady Workspaces server. All this happens in separate containers or pods, and the user’s browser is not yet involved. The workspace started by user $userName message in the CodeReady Workspaces server logs indicates the following:

  • The workspace container or pod is up.
  • The workspace agent has successfully started.
  • The CodeReady Workspaces server can reach it.

14.19.2.1. Troubleshooting network setting when workspace agent cannot be reached

An error message saying that the IDE cannot be initialized indicates that the client (browser) cannot reach the workspace agent. This is caused by the CodeReady Workspaces server using an internal IP address to reach the workspace agent, while you are accessing the workspace from a machine that is located on a different network. To confirm this, open the browser developer console and check failed requests. The failed requests are to project and project-type API.

To access a workspace from a different network than the one on which the CodeReady Workspaces server is running, enable access to the ephemeral port range on the CodeReady Workspaces server network.

14.19.3. Failure in bootstrapping

When a workspace starts, the CodeReady Workspaces server creates and starts a container or a pod or a set of containers and pods as per the environment recipe. After the container or pod is running, a bootstrapping process begins - the bootstrapper binary is downloaded and launched. If the server logs show bootstrapping failures, or you do not see any output in the Machine tab of the Workspaces view, the reason is that bootstrapper is not downloaded. The following are possible the reasons for the bootstrapper download failure:

  • Network conditions (for example, firewall restrictions).
  • Incorrect bootstrapper binary URL that the CodeReady Workspaces server uses (often reproduced when deploying to OpenShift and missing necessary environment variables).

To work around the problem, download the bootstrapper binary manually. On OpenShift, access the pod on the command line (shell or the terminal in the web console) and run the following commands:

$ cd /tmp/bootstrapper
$ ls -la  1
$ curl ${CHE_URL}/agent-binaries/linux_amd64/bootstrapper/bootstrapper
1
to check for the existence of the bootstrapper binary

To prevent the curl command from failing, unblock port 80 on your network. On OpenShift with https routes, unblock port 443.

14.20. Workspace Data Model

The following table lists the data types and their description.

Data TypesDescription

environments: Map<String, getEnvironments>

Workspace environment variables. A workspace can have multiple environment variables.

defaultEnv: STRING

A workspace must have a default environment.

projects: []

Projects associated with a workspace.

commands: []

Commands associated with a workspace.

name: STRING

Workspace name that has to be unique in a namespace.

links: []

-

14.20.1. Environment recipes

ws data model

For recipe types of dockerfile, compose, or openshift, content, not location, is specified.

"recipe": {
  "type": "compose",
  "content": "services:\n db:\n  image: eclipse/mysql\n  environment:\n   MYSQL_ROOT_PASSWORD: password\n   MYSQL_DATABASE: petclinic\n   MYSQL_USER: petclinic\n   MYSQL_PASSWORD: password\n  mem_limit: 1073741824\n dev-machine:\n  image: eclipse/ubuntu_jdk8\n  mem_limit: 2147483648\n  depends_on:\n    - db",
  "contentType": "application/x-yaml"
}

14.20.2. Projects

ws projects

The project object structure has the source.location and source.type parameters. There are two importer types: git and zip. New location types can be provided by custom plugins, such as svn.

Incorrectly configured projects or projects missing sources are marked with error codes and messages explaining the error. In the example above, the project does not have errors and mixins.

A mixin adds additional behaviors to the project, the IDE panels, and menus. Mixins are reusable across any project type. To define the mixins to add to a project, specify an array of strings, with each string containing the identifier for the mixin.

Mixin IDDescription

git

Initiates the project with a Git repository. Adds Git-menu functionality to the IDE. To add a mixin to the project, create a new project and then initialize a Git repository.

pullrequest

Enables pull-request workflow where a server handles the local and remote branching, forking, and pull-request issuance. Pull requests generated from within the server have another Factory placed into the comments of pull requests that a PR reviewer can consume. Adds contribution panel to the IDE. Set this mixin to use attribute values for project.attributes.local_branch and project.attributes.contribute_to_branch.

The pullrequest mixin requires additional configuration from the attributes object of the project.

The project object can include source.parameters, which is a map that can contain additional parameters. Example: related to project importer.

Parameter nameDescription

skipFirstLevel

Used for projects with type zip. When value is 'true', the first directory inside ZIP will be omitted.

14.20.3. Commands

Commands can be both tied to a workspace and an individual project. In the example below, a command is saved to workspace configuration.

ws commands

The followling image shows ways to save commands in the project configuration.

project commands

14.20.4. Runtime

A runtime object is created when a workspace is in a running state. Runtime returns server URLs, internal or external, depending on the server configuration. Interested clients, like the User Dashboard and the IDE, use these URLs.

runtime

14.21. Getting started with factories

A factory is a template containing configuration to automate the generation of a new workspace using a factory identifier added to the IDE URL. Factories can be used to create replicas of existing workspaces or to automate the provisioning of statically or dynamically defined workspaces.

14.21.1. Trying a factory

Clone a public workspace on che.openshift.io by clicking try a factory.

14.21.2. Using factories

Factories can be invoked from a factory URL built in multiple ways. You can replace the localhost:8080 domain with the hostname of any CodeReady Workspaces installation.

Using factories on che.openshift.io requires the user to be authenticated. Users who are not authenticated see a login screen after they click on the factory URL. Users without an account can create one using the same dialog.

14.21.3. Invoking factories using their unique hashcodes

Format

/f?id={hashcode}
/factory?id={hashcode}

Sample

https://localhost:8080/f?id=factorymtyoro1y0qt8tq2j

14.21.4. Invoking a named factory

Format

/f?user={username}&name={factoryname}
/factory?user={username}&name={factoryname}

Sample

https://localhost:8080/f?user=che&name=starwars
https://localhost:8080/factory?user=che&name=starwars

14.21.5. Invoking a factory for a specific git repository

Once a factory is executed, it either loads an existing workspace or generates a new one, depending on the factory configuration. The name of the workspace is determined by the factory configuration, and its name becomes a part of the URL used to access the factory. The format is: {hostname}/{username}/{workspace}.

14.21.6. Next steps

You have just created your first developer workspace using factories. Read on to learn more about:

14.21.7. Creating Factories

14.21.7.1. Creating a factory in the dashboard

You can create a factory based on an existing workspace. You can also create factories based on a template or by pasting in a .factory.json file and then generating a factory URL using the CodeReady Workspaces CLI or API. To learn more about the JSON structure and options, see Factory JSON reference.

A factory created from the dashboard is persisted on CodeReady Workspaces and retained when upgrading to a newer version.

To create a factory on the dashboard:

  1. In the IDE, click Dashboard > Factories > Create Factory.

Sample factory: https://che.openshift.io/f?id=factorymtyoro1y0qt8tq2j.

14.21.7.2. Creating a factory in the IDE

Creating a factory in the IDE in a running workspace generates a factory to replicate that workspace including the runtime and project settings.

A factory created from the dashboard is persisted on CodeReady Workspaces and retained when upgrading to a newer version.

To create a factory in the IDE:

  1. In the IDE, click Workspace > Create Factory.

Sample factory: https://che.openshift.io/f?id=factorymtyoro1y0qt8tq2j.

14.21.7.3. Creating a factory based on a repository

URL factories work with GitHub and GitLab repositories. By using URL factories, the project referenced by the URL is automatically imported.

To create a factory based on a repository:

  1. Specify the repository URL. Ensure that you store the configuration in the repository.

Sample factories:

The factory URL can include a branch or a subdirectory. Following are examples of optional parameters:

  • ?url=https://github.com/eclipse/che CodeReady Workspaces is imported with the master branch.
  • ?url=https://github.com/eclipse/che/tree/5.0.0 CodeReady Workspaces is imported by using the 5.0.0 branch.
  • ?url=https://github.com/eclipse/che/tree/5.0.0/dashboard subdirectory dashboard/ is imported by using the 5.0.0 branch.
14.21.7.3.1. Customizing URL factories

The following are two ways to customize the runtime and configuration:

Customizing only the runtime
Providing a .factory.json file inside the repository signals to CodeReady Workspaces URL factory to configure the project and runtime according to this configuration file. When a .factory.json file is stored inside the repository, any Dockerfile content is ignored because the workspace runtime configuration is defined inside the JSON file.
Customizing the Dockerfile
(This only works on Docker infrastructure. On recent CodeReady Workspaces versions, support of this feature may be reduced or dropped.) Providing a .factory.dockerfile inside the repository signals to the URL factory to use this Dockerfile for the workspace agent runtime. By default, imported projects are set to a blank project type. You can also set the project type in the .factory.json file or in the workspace definition that the factory inherits from.

14.21.7.4. Configuring factory policies

Policies are a way to send instructions to the automation engine about the number of workspaces to create and their meta data such as lifespan and resource allocation.

14.21.7.4.1. Setting factory limitations
Referer
CodeReady Workspacescks the hostname of the acceptor and only allows the factory to execute if there is a match.
Since and Until
Defines the time window in which the factory can be activated. For example, instructors who want to create an exercise that can only be accessed for two hours should set these properties.
14.21.7.4.2. Setting factory multiplicity

Multiplicity defines the number of workspaces that can be created from the factory.

Multiple workspaces (perClick)
Every click of the factory URL generates a different workspace, each with its own identifier, name, and resources.
Single workspace (perUser)
Exactly one workspace is generated for each unique user that clicks on the factory URL. Existing workspaces are reopened.

To learn how to configure factory policies, see the JSON reference.

14.21.7.5. Customizing the IDE

You can instruct the factory to invoke a series of IDE actions based on events in the lifecycle of the workspace.

14.21.7.6. Lifecycle Events

The lifecycle of the workspace is defined by the following events:

  • onAppLoaded: Triggered when the IDE is loaded.
  • onProjectsLoaded: Triggered when the workspace and all projects have been activated.
  • onAppClosed: Triggered when the IDE is closed.

Each event type has a set of actions that can be triggered. There is no ordering of actions executed when you provide a list; CodeReady Workspaces asynchronously invokes multiple actions if appropriate.

14.21.7.7. Factory actions

The following is a list of all possible actions that can be configured with your factory.

Run Command
Specify the name of the command to invoke after the IDE is loaded.
Associated Event: onProjectsLoaded
Open File
Open project files in the editor. Optionally, define the line to be highlighted.
Associated Event: onProjectsLoaded
Open a Welcome Page
Customize content of a welcome panel displayed when the workspace is loaded.
Associated Event: onAppLoaded
Warn on Uncommitted Changes
Opens a warning pop-up window when the user closes the browser tab with a project that has uncommitted changes.
Associated Event: onAppClosed

To learn how to configure factory actions, see the Factory JSON reference.

14.21.7.8. Finding and replacing variables

Factories make it possible to replace variables or placeholders in the source code — used to avoid exposing sensitive information (passwords, URLs, account names, API keys) — with real values. To find and replace a value, you can use the run command during an onProjectsLoaded event. You can use sed, awk, or other tools available in your workspace environment.

For a sample of how to configure finding and replacing a value, see the Factory JSON reference section. Alternatively, you can add IDE actions in the Factory tab, on the user Dashboard.

Use regular expressions in sed, both in find-replace and file-file type patterns.

14.21.7.9. Pull request workflow

Factories can be configured with a dedicated pull request workflow. The PR workflow handles local and remote branching, forking, and issuing the pull request. Pull requests generated from within CodeReady Workspaces have another factory placed into the comments of the pull requests that a PR reviewer can use to quickly start the workspace.

When enabled, the pull request workflow adds a contribution panel to the IDE.

pr panel

14.21.7.10. Repository badging

If you have projects in GitHub or GitLab, you can help your contributors to get started by providing them ready-to-code developer workspaces. Create a factory and add the following badge on your repositories readme.md:

[![Developer Workspace](https://che.openshift.io/factory/resources/factory-contribute.svg)](your-factory-url)

14.21.7.11. Next steps

14.21.8. Factories JSON Reference

A factory configuration is a JSON snippet either stored within CodeReady Workspaces or as a .factory.json file. You can create factories within the IDE using the CodeReady Workspaces URL syntax, within the dashboard, or on the command line with the API and CLI.

factory : {
  "v"         : 4.0,            1
  "workspace" : {},             2
  "policies"  : {},             3
  "ide"       : {},             4
  "creator"   : {},             5
}
1
Version of the configuration format.
2
Identical to workspace:{} object for CodeReady Workspaces.
3
(Optional) Restrictions that limit behaviors.
4
(Optional) Trigger IDE UI actions tied to workspace events.
5
(Optional) Identifying information of author.

The factory.workspace is identical to the workspace:{} object for CodeReady Workspaces and contains the structure of the workspace. To learn more about the workspace JSON object, see Workspace Data Model.

You can export workspaces and then reuse the workspace definition within a factory. workspaces are composed of the following:

  • 0..n projects
  • 0..n environments that contain machines to run the code
  • 0..n commands to execute against the code and machines
  • a type

The factory.policies, factory.ide, and factory.creator objects are unique to factories. They provide meta information to the automation engine that alter the presentation of the factory URL or the behavior of the provisioning.

14.21.8.1. Mixins

A mixin adds additional behaviors to a project as a set of new project type attributes. Mixins are reusable across any project type. To define the mixins to add to a project, specify an array of strings, with each string containing the identifier for the mixin. For example, "mixins" : [ "pullrequest" ].

Mixin IDDescription

pullrequest

Enables pull request workflow where CodeReady Workspaces handles local and remote branching, forking, and pull request issuance. Pull requests generated from within CodeReady Workspaces have another factory placed into the comments of pull requests that a PR reviewer can consume. Adds contribution panel to the IDE. If this mixin is set, it uses attribute values for project.attributes.local_branch and project.attributes.contribute_to_branch

  • The pullrequest mixin requires additional configuration from the attributes object of the project. If present, {{ site.product_mini_name }} will use the project attributes as defined in the factory. If not provided, {{ site.product_mini_name }} will set defaults for the attributes.
  • Learn more about other link:TODO: link to project API docs[mixins]

14.21.8.2. Pull Request mixin attributes

Project attributes alter the behavior of the IDE or workspace.

Different CodeReady Workspaces plug-ins can add their own attributes to affect the behavior of the IDE or workspace. Attribute configuration is always optional and if not provided within a factory definition, the IDE or workspace sets it.

AttributeDescription

local_branch

Used in conjunction with the pullrequest mixin. If provided, the local branch for the project is set with this value. If not provided, the local branch is set with the value of project.source.parameters.branch (the name of the branch from the remote). If both local_branch and project.source.parameters.branch are not provided, the local branch is set to the name of the checked out branch.

contribute_to_branch

Name of the branch that a pull request will be contributed to. The value of project.source.parameters.branch is default. It is the name of the branch that this project was cloned from.

Following is a snippet that demonstrates full configuration of the contribution mixin.

factory.workspace.project : {
  "mixins"     : [ "pullrequest" ],

  "attributes" : {
    "local_branch"         : [ "timing" ],
    "contribute_to_branch" : [ "master" ]
  },

  "source" : {
    "type"       : "git",
    "location"   : "https://github.com/codenvy/che.git",
    "parameters" : {
      "keepVcs" : "true"
    }
  }
}

14.21.8.3. Policies

Following is an example of a factory policy.

factory.policies : {
  "referer"   : STRING,                 1
  "since"     : EPOCHTIME,              2
  "until"     : EPOCHTIME,              3
  "create"    : [perClick | perUser]    4
}
1
Works only for clients from a referrer.
2
Factory works only after this date.
3
Factory works only before this date.
4
Create one workpace per click, user, or account.

14.21.8.4. Limitations

You can use since : EPOCHTIME, until : EPOCHTIME, and referer as a way to prevent the factory from executing under certain conditions. since and until represent a valid time window that allows the factory to activate. The referrer checks the hostname of the acceptor and only allows the factory to execute if there is a match.

14.21.8.5. Multiplicity

Using create : perClick causes every click of the factory URL to generate a new workspace, each with its own identifier, name, and resources. Using create : perUser causes only one workspace to be generated for each unique user that clicks on the factory URL. If the workspace has previously been generated, the existing workspace is reopened.

14.21.8.6. Customizing the IDE

factory.ide.{event} : {                 1
  "actions" : [{}]                      2
}

factory.ide.{event}.actions : [{
  "id"         : String,                3
  properties : {}                       4
}]
1
event = onAppLoaded, onProjectsLoaded, onAppClosed.
2
List of IDE actions to be executed when the event is triggered.
3
Action for the IDE to perform when the event is triggered.
4
Properties to customize action behavior.

You can instruct the factory to invoke a series of IDE actions based on events in the lifecycle of the workspace.

onAppLoaded
Triggered when the IDE is loaded.
onProjectsLoaded
Triggered when the workspace and all projects have been activated or imported.
onAppClosed
Triggered when the IDE is closed.

Following is an example that associates a variety of actions with all of the events.

"ide" : {
  "onProjectsLoaded" : {                                               1
    "actions" : [{
      "id" : "openFile",                                               2
      "properties" : {                                                 3
        "file" : "/my-project/pom.xml"
      }
    },
    {
      "id" : "runCommand",                                             4
      "properties" : {
        "name" : "MCI"                                                 5
      }
    }
  ]},
  "onAppLoaded": {
     "actions": [
        {
           "properties:{
              "greetingTitle": "Getting Started",                      6
              "greetingContentUrl": "http://example.com/README.html"   7
           },
           "id": "openWelcomePage"
        }
     ]
  },
  "onAppClosed" : {                                                    8
    "actions" : [{
      "id" : "warnOnClose"                                             9
    }]
  }
}
1
Actions triggered when a project is opened.
2
Opens a file in the editor. Can add multiple.
3
The file to be opened (include project name).
4
Launch command after the IDE opens.
5
Command name.
6
Title of a Welcome tab.
7
HTML file to be loaded into a tab.
8
Actions to be triggered when the IDE is closed.
9
Show warning when closing a browser tab.

Each event type has a set of actions that can be triggered. There is no ordering of actions executed when you provide a list; {{ site.product_mini_name }} will asynchronously invoke multiple actions if appropriate. Some actions can be configured in how they perform and will have an associated properties : {} object.

onProjectsLoaded Event

ActionProperties?Description

runCommand

Yes

Specify the name of the command to invoke after the IDE is loaded. Specify the commands in the factory.workspace.commands : [] array.

openFile

Yes

Open project files as a tab in the editor.

onAppLoaded Event

ActionProperties?Description

openWelcomePage

Yes

Customize the content of the welcome panel when the workspace is loaded. Note that browsers block http resources that are loaded into https pages.

onAppClosed Event

ActionProperties?Description

warnOnClose

No

Opens a warning pop-up window when the user closes the browser tab with a project that has uncommitted changes. Requires project.parameters.keepVcs to be true.

14.21.8.7. Action: Open File

This action opens a file as a tab in the editor. You can provide this action multiple times to have multiple files open. The file property is a relative reference to a file in the project source tree. The file parameter is the relative path within the workspace to the file that should be opened by the editor. The line parameter is optional and can be used to move the editor cursor to a specific line when the file is opened. Projects are located in the /projects/ directory of a workspace.

{
  "id" : "openFile",
    "properties" : {
      "file" : "/my-project/pom.xml",
      "line" : "50"
  }
}

14.21.8.8. Action: Find and Replace

In projects created from a factory, CodeReady Workspaces can find and replace values in the source code after it is imported into the project tree. This lets you parameterize your source code. Find and replace can be run as a Run Command during onProjectsLoaded event. You can use sed, awk, or any other tools that are available in your workspace environment.

To define a command for your workspace in factory.workspace.workspaceConfig.commands:

{
  "commandLine": "sed -i 's/***/userId984hfy6/g' /projects/console-java-simple/README.md",
  "name": "replace",
  "attributes": {
    "goal": "Common",
    "previewUrl": ""
  },
  "type": "custom"
}

In the preceding example, a named command replace is created. The command replaces each occurrence of * with the string userId984hfy6 in the README.md file of the project.

Then register this command to the execution list linked to the onProjectsLoaded event. In this example, the replace command is executed after the project is imported into a workspace.

"ide": {
    "onProjectsLoaded": {
      "actions": [
        {
          "properties": {
            "name": "replace"
          },
          "id": "runCommand"
        }
      ]
    }
  }

Use regular expressions in sed, both in find-replace and file-file type patterns.

14.21.8.9. Creator

This object has meta information that you can embed within the factory. These attributes do not affect the automation behavior or the behavior of the generated workspace.

factory.creator : {
  "name"      : STRING,            1
  "email"     : STRING,            2
  "created"   : EPOCHTIME,         3
  "userId"    : STRING             4
}
1
The name of the author of this configuration file.
2
The author’s email address.
3
This value is set by the system.
4
This value is set by the system.