GeneralInnerloop versus outerloop

General

Innerloop versus outerloop

In a devfile spec, there are two scopes of deployment: innerloop and outerloop. Having these scopes is essential for a full development experience as well as ensuring proper integration of the full scope of development tools for Kubernetes and OpenShift projects.

Prerequisites

What is innerloop?

Innerloop deployments are actions the developer makes within their development environment, such as running tests, debugging, and local deployments before checking into the target source repository.

Procedure

  1. Add the runtime container component for running your project with the schemaVersion and metadata definitions

    • This example will use nodejs-18 UBI image
    schemaVersion: 2.3.0 metadata:  name: nodejs components:  - name: runtime  container:  image: registry.access.redhat.com/ubi8/nodejs-18:latest  args: ['tail', '-f', '/dev/null']  memoryLimit: 1024Mi  mountSources: true 
  2. If your project needs ports to be forwarded like in this example, define the endpoints required for your project

    • Note: If you are using odo v3, you need to create an additional endpoint for the debugging port. See Odo Spec Support for more information
    • The environment variable definition DEBUG_PORT is to set the debug port of the node application
    components:  - name: runtime  container:  image: registry.access.redhat.com/ubi8/nodejs-18:latest  args: ['tail', '-f', '/dev/null']  memoryLimit: 1024Mi  mountSources: true  env:  - name: DEBUG_PORT  value: '5858'  endpoints:  - name: http-node  targetPort: 3000  - exposure: none  name: debug  targetPort: 5858 
  3. Now the runtime component has been defined, we need a way of running our project

    1. Add a command to npm install our project packages and mark it as our projects build command
    2. Add another command to run the main process or the server process npm start in this example and mark it as our projects run command
    3. With these commands you should now be able to run a development deployment of your project, for example odo dev
    commands:  - id: install  exec:  component: runtime  commandLine: npm install  workingDir: ${PROJECT_SOURCE}  group:  kind: build  isDefault: true  - id: run  exec:  component: runtime  commandLine: npm start  workingDir: ${PROJECT_SOURCE}  group:  kind: run  isDefault: true 
  4. For testing and debugging we will also need to define commands for each with the shell commands used to debug and test your project

    • The kind of commands will be debug and test for running your debugging and testing respectively
    commands:  - id: install  exec:  component: runtime  commandLine: npm install  workingDir: ${PROJECT_SOURCE}  group:  kind: build  isDefault: true  - id: run  exec:  component: runtime  commandLine: npm start  workingDir: ${PROJECT_SOURCE}  group:  kind: run  isDefault: true  - id: debug  exec:  component: runtime  commandLine: npm run debug  workingDir: ${PROJECT_SOURCE}  group:  kind: debug  isDefault: true  - id: test  exec:  component: runtime  commandLine: npm test  workingDir: ${PROJECT_SOURCE}  group:  kind: test  isDefault: true 

Final innerloop devfile

devfile.yaml
schemaVersion: 2.3.0 metadata:  name: nodejs components:  - name: runtime  container:  image: registry.access.redhat.com/ubi8/nodejs-18:latest  args: ['tail', '-f', '/dev/null']  memoryLimit: 1024Mi  mountSources: true  env:  - name: DEBUG_PORT  value: '5858'  endpoints:  - name: http-node  targetPort: 3000  - exposure: none  name: debug  targetPort: 5858 commands:  - id: install  exec:  component: runtime  commandLine: npm install  workingDir: ${PROJECT_SOURCE}  group:  kind: build  isDefault: true  - id: run  exec:  component: runtime  commandLine: npm start  workingDir: ${PROJECT_SOURCE}  group:  kind: run  isDefault: true  - id: debug  exec:  component: runtime  commandLine: npm run debug  workingDir: ${PROJECT_SOURCE}  group:  kind: debug  isDefault: true  - id: test  exec:  component: runtime  commandLine: npm test  workingDir: ${PROJECT_SOURCE}  group:  kind: test  isDefault: true 

The component and commands here allow the developer to build, run, debug, and test their project within a local cluster using a devfile supported development tool (e.g. odo).

What is outerloop?

Outerloop deployments are ones done after the development stage once the source is checked into the source repository. Such deployments would include integration testing, full builds or deployments.

Procedure

  1. Add an image component to define the image building process

    1. Label your image tag with imageNameSelector
    2. Define your dockerfile with your file path, build context and if your build requires root privileges
    components:  - name: outerloop-build  image:  imageNameSelector: landingpage-image:latest  dockerfile:  uri: docker/Dockerfile  buildContext: .  rootRequired: false 
  2. Add a command which will instruct your deployment to build the docker image using the image component

    commands:  - id: build-image  apply:  component: outerloop-build 
  3. Add a deployment component that best suits your cluster’s runtime environment (kubernetes/openshift), in this case openshift

    • Provide the file path to your openshift template file with uri
    components:  - name: outerloop-build  image:  imageNameSelector: landingpage-image:latest  dockerfile:  uri: docker/Dockerfile  buildContext: .  rootRequired: false  - name: outerloop-deploy  openshift:  uri: landingpage-template.yaml 
  4. As with the image component, we will need to create a command for the openshift component

    commands:  - id: build-image  apply:  component: outerloop-build  - id: deploy-openshift  apply:  component: outerloop-deploy 
  5. To complete the deployment process, combine the two commands into a complete deploy command using composite

    commands:  - id: build-image  apply:  component: outerloop-build  - id: deploy-openshift  apply:  component: outerloop-deploy  - id: deploy  composite:  commands:  - build-image  - deploy-openshift  group:  kind: deploy  isDefault: true 

Final outerloop devfile

devfile.yaml
schemaVersion: 2.3.0 metadata:  name: nodejs components:  - name: outerloop-build  image:  imageNameSelector: landingpage-image:latest  dockerfile:  uri: docker/Dockerfile  buildContext: .  rootRequired: false  - name: outerloop-deploy  openshift:  uri: landingpage-template.yaml commands:  - id: build-image  apply:  component: outerloop-build  - id: deploy-openshift  apply:  component: outerloop-deploy  - id: deploy  composite:  commands:  - build-image  - deploy-openshift  group:  kind: deploy  isDefault: true 

With these components and commands, the developer can produce a full build and deployment. In this case, the project has an OpenShift deployment template landingpage-template.yaml for a full deploy and docker image build file docker/Dockerfile for a full build. These actions can also be used for the requirements of performing integration testing.

Support list of developer tools

Though the devfile spec does support both innerloop and outerloop deployments, not all developer tools will support these deployments in the same way. This section will list the devfile supported development tools and what deployment scopes they support.

Developer Tools

ToolInnerloop SupportOuterloop Support
Odo v2XX
Odo v3XX
Eclipse CheX
Amazon CodeCatalystX
JetBrains Space Cloud DevXX (image build only)
Red Hat OpenShift Dev SpacesX
OpenShift Dev ConsoleX
VSCode OpenShift ToolkitXX
IntelliJ OpenShift ToolkitXX

Odo Spec Support

Odo covers the features supported by the devfile 2.2.0 spec with minor requirements for version 3:

  1. In order to debug your project it is required to define a debug port: https://odo.dev/docs/user-guides/v3-migration-guide#changes-to-the-way-component-debugging-works
  2. By default, odo v3 sets up an underlying persistent volumes rather than setting up ephemeral volumes, this can be toggled back: https://odo.dev/docs/user-guides/v3-migration-guide#ephemeral-storage

More information on how odo treats lifecycle events can be found on the odo v2 page or on the odo v3 page.

OpenShift Toolkit for both VSCode and IntelliJ IDE use odo v3 to power the core commands, therefore the devfile support should be the same as odo v3.

Eclipse Che Spec Support

As shown in the previous table Eclipse Che only supports innerloop spec features and is currently working on support for outerloop. The Eclipse Che project provides an updated support list of Devfile 2.x in an issue: https://github.com/eclipse/che/issues/17883

Red Hat OpenShift Dev Spaces upstreams the Eclipse Che project and therefore should provide the same level of devfile support.

OpenShift Dev Console Spec Support

OpenShift Dev Console allows the deployment of samples and only supports devfiles defined for outerloop deployments. Additional information about this can be found: https://docs.openshift.com/container-platform/4.10/applications/creating_applications/odc-creating-applications-using-developer-perspective.html

Amazon CodeCatalyst Spec Support

Amazon CodeCatalyst uses devfile specification 2.1.0 and it therefore does not support features the latest devfile specification provides, such as outerloop deployments. More information about Amazon CodeCatalyst’s utilization of devfiles can be found on their documentation pages: https://docs.aws.amazon.com/codecatalyst/latest/userguide/devenvironment.html

JetBrains Space Cloud Dev Spec Support

JetBrains Space Cloud Dev uses the 2.2.0 devfile specification and supports the use of multiple devfiles in a single project. It uses a custom space field under the top level attributes to define the setup for the runtime environment to be set up on the platform. An example of a devfile you might see in this environment is shown below:

Example of JetBrains Space Cloud Dev devfile setup

devfile.yaml
schemaVersion: 2.2.0 metadata:  name: 'My custom dev env configuration' attributes:  space:  # regular, large, xlarge  instanceType: large  # a default IDE for the project  editor:  # (Required) IDE type: Idea, WebStorm, PyCharm,  # RubyMine, CLion, Fleet, GoLand, PhpStorm  type: Idea  version: '2022.1'  # Space uses JetBrains Toolbox App to install IDEs to a dev environment.  # updateChannel defines IDE version release stage: Release, EAP  updateChannel: EAP  # JVM configuration (appends to the default .vmoptions file)  vmoptions:  - '-Xms2048m'  - '-Xmx4096m'  # a warm-up snapshot  warmup:  # create a snapshot every Sunday (only for main branch)  startOn:  - type: schedule  cron: '0 0 0 ? * SUN *'  # run additional warmup script (IDE indexes will be built anyway)  script:  ./scripts/warmup.sh  # Parameters and secretes required by a dev environment  # e.g., credentials to an external service  requiredParameters:  # (Required) the name of the environment variable  # that will be available in the dev environment  - name: USERNAME  description: 'Space username'  requiredSecrets:  - name: PASSWORD  description: 'Space permanent token' components: - name: dev-container  # Dev environment container config  container:  # use image from a Space Packages registry  image: mycompany.registry.jetbrains.space/p/myprj/container/my-dev-image:27  # environment variables  env:  - name: API_URL  value: 'https://my-site/http_api'  - name: PATH_IMG  value: './img/' 

JetBrains Space Cloud Dev also partially supports outerloop via the image component to set up Dockerfile builds:

Example of JetBrains Space Cloud Dev image build devfile setup

devfile.yaml
schemaVersion: 2.2.0 attributes:  space:  instanceType: large  editor:  type: Idea components: - name: image-build  image:  # (Required)  imageName: my-image:latest  dockerfile:  # (Optional) path to Docker context relative to projectRoot  # by default, projectRoot is repository root  buildContext: docker  # (Required) path to Dockerfile relative to projectRoot  uri: docker/Dockerfile  args:  - 'ARG1=A'  - 'ARG2=B' 

The image component build process publishes the built image to a cluster image registry specific to your project workspace. More details about using devfiles with JetBrains Space Cloud Dev can be found here: https://www.jetbrains.com/help/space/set-up-a-dev-evnvironment.html

Additional Resources