Skip to content
This repository was archived by the owner on May 29, 2024. It is now read-only.

Creator: HOWTO Create a Language Generator

Tako Schotanus edited this page Jul 29, 2019 · 6 revisions

As we already read in the page about Runtime Generators, HOWTO Create a Runtime Generator, they are meant as a basis for other Generators to build on. They provide all the necessary files (code, configuration, build etc) to create a project for a certain framework. But that's all about the code and files, and as you can imagine there are lots of different ways to write code and lots of different frameworks to choose from. You could write Runtime Generators for Vert.x, Wildfly, Spring Boot, etc, all very different, but they still have one thing in common: they all run on the JVM platform. That's where Language Generators come in.

A Language Generator is the thing that takes care of taking the code in your project and getting it compiled and running on Kubernetes or OpenShift.

⚠️ Kubernetes is mentioned here, but right now only OpenShift support has been implemented. Support for Kubernetes is currently in development.

So let's go through the steps of what it takes to create a Language Generator (this is starting to look very familiar, right?):

  1. Choose a name - First we need to choose a name for our new Language Generator. Language Generators generally start with the text language-, so let's go with the very original language-example.
  2. Create a folder - And like before all the Language Generator's files need to live in a folder with the name of the Generator
$ mkdir creator/src/main/resources/META-INF/catalog/generators/language-example
  1. Files - Language Generators don't generally need many files, but they follow the same pattern as all Generators:
language-example/
   files/
      gap

The important file here is a shell script called gap. It's a script that's used to build and deploy code. The easiest thing to do is to just copy the gap script from one of the existing Language Generators and adapt it to your specific language/platform. It's normally a simple 2-line change.

Show code

gap

#!/usr/bin/env bash

APP_NAME={{.application}}
SERVICE_NAME={{.serviceName}}

SCRIPT_DIR=$(cd "$(dirname "$BASH_SOURCE")" ; pwd -P)
OPENSHIFTIO_DIR=${SCRIPT_DIR}/.openshiftio
SOURCE_DIR=${SCRIPT_DIR}
if [[ ! -z "{{.subFolderName}}" ]]; then
    SOURCE_DIR=${SOURCE_DIR}/..
    SUB_DIR=/{{.subFolderName}}
fi

function do_deploy() {
    PARAMS=""
    REPO_URL=$(git config --get remote.origin.url || echo "")
    if [[ ! -z "${REPO_URL}" ]]; then
        PARAMS="$PARAMS -p=SOURCE_REPOSITORY_URL=${REPO_URL}"
    fi
    if [[ ! -z "${OPENSHIFT_CONSOLE_URL}" ]]; then
        PARAMS="$PARAMS -p=OPENSHIFT_CONSOLE_URL=${OPENSHIFT_CONSOLE_URL}"
    fi
    if [[ -f ${OPENSHIFTIO_DIR}/application.yaml ]]; then
        oc process -f ${OPENSHIFTIO_DIR}/application.yaml --ignore-unknown-parameters ${PARAMS} | oc apply -f -
    fi
    if [[ -f ${OPENSHIFTIO_DIR}/service.welcome.yaml ]]; then
        oc process -f ${OPENSHIFTIO_DIR}/service.welcome.yaml --ignore-unknown-parameters ${PARAMS} | oc apply -f -
    fi
}

function do_build() {
    mvn package
}

function do_clean() {
    mvn clean
}

function do_push() {
    if [[ "$1" == "--source" || "$1" == "-s" || "$1" == "--binary" || "$1" == "-b" ]]; then
        shift
        oc start-build ${SERVICE_NAME} --from-dir ${SOURCE_DIR} "$@"
    elif [[ "$1" == "--git" || "$1" == "-g" ]]; then
        shift
        oc start-build ${SERVICE_NAME} "$@"
    else
        oc start-build ${SERVICE_NAME} --from-dir ${SOURCE_DIR} "$@"
    fi
}

function do_delete() {
    oc delete all,secrets -l app=${APP_NAME}
}

while [[ $# > 0 ]]; do
    CMD=$1
    shift
    ARGS=()
    while [[ "$1" == -* ]]; do ARGS+=($1); shift; done
    case "$CMD" in
        "deploy")
            do_deploy $ARGS
            ;;
        "build")
            do_build $ARGS
            ;;
        "clean")
            do_clean $ARGS
            ;;
        "push")
            do_push $ARGS
            ;;
        "delete")
            do_delete $ARGS
            ;;
    esac
    RES=$?
    if [[ $RES > 0 ]]; then
        exit $RES
    fi
done
  1. Create metadata - Our Generator also needs an info.yaml in the root of our folder that contains some important metadata. For our example we will use the following:
type: generator
config:
  image: "registry.access.redhat.com/redhat-openjdk-18/openjdk18-openshift"

For Language Generators the most important information is the builder image specified by the image property. It's the name of a special Docker image, a so-called S2I builder image, that was created specifically to compile and run the code for your language / platform. In this case we chose a RedHat provided S2I builder image for the Java platform.

⚠️ Language Generators need an S2I Builder Image to do their work. Creating an S2I Builder Image does not fall within the scope of this documentation. See the S2I GitHub repository and the OpenShift S2I Documentation for more information.

  1. Register the image - We now need to register this image in the list of images. Just add a item to the end of the list with the exact same name we used in the image property. It would look something like this:
- id: nodeshift/centos7-s2i-nodejs
  name: Generic Node.js Code Builder
  metadata:
    language: nodejs
    isBuilder: true
    suggestedEnv:
      PORT: '8080'
- id: nodeshift/centos7-s2i-web-app
  name: Web App Node.js Code Builder
  metadata:
    language: nodejs
    isBuilder: true
- id: registry.access.redhat.com/redhat-openjdk-18/openjdk18-openshift
  name: Java Code Builder
  metadata:
    language: java
    isBuilder: true
  1. Register the Generator - Finally we need to register our Generator in the GeneratorInfo list just as explained in the basic HOWTO Create a Generator.

And that's it! As you can see Language Generators are basically still Generators, but they do need a bit more work and knowledge to make work. Good thing we made them reusable!

Clone this wiki locally