There is exciting news for those who develop FlexDeploy plugins. So exciting, we’re adding another post to our FlexDeploy Loves Containers Blog series.

Want to follow along in FlexDeploy? Check out our JumpStart Demo Lab configured with Docker and Kubernetes. This is a pre-configured, friction-free environment in the cloud for you to try FlexDeploy with no set up, installation, or configuration.

Try the FlexDeploy Demo Lab

From now in addition to the regular Java implementation, a plugin can be implemented as a custom Docker Image. While executing a workflow, FlexDeploy creates a Docker container out of the image, invokes the plugin’s operation, returns the result and removes the container from the endpoint. The endpoint can be a simple Docker host (having just Docker runtime installed) or it can be a Kubernetes cluster.

This concept, “Plugin as a Container” (PaaC), gives plugin developers a real freedom in terms of tools and technologies they can use to enrich FlexDeploy with their custom functionality. Furthermore, in a way it makes them independent from the infrastructure. A plugin container can be packaged with all necessary tools, libraries and drivers, meaning that it can run everywhere, on any endpoint having Docker engine installed, so there is no need to install anything else.

FlexDeploy comes with two containerized plugins today – Oracle ADF Builder and SOAP UI Docker. Oracle ADF Builder plugin has preinstalled JDeveloper 12.1.3 so it can  build ADF applications everywhere, even in the cloud on a K8s cluster. Same is true about SOAP UI Docker plugin which has SOAP UI in the plugin container installed and capable of running SOAP tests from any endpoint with Docker engine.

In this post we’re going to create a new FlexDeploy plugin to build Oracle Jet applications. The key point is that it is extremely easy.

Let’s name our new plugin OJetBuilder. First of all, I am going to create a Docker image having OJet CLI installed and serving as an actual builder. The Dockerfile for the image looks like this:

FROM node
RUN npm install -g @oracle/ojet-cli
COPY buildWeb.sh /usr/local/bin/buildWeb

So, we are building our image on top of node.js Docker image, installing OJet CLI and adding buildWeb.sh that actually does the job:

#!/bin/bash

cd /fd_working_dir/temp/$FDOJETBUILD_WORKSPACE
ojet restore
ojet build web $FDOJETBUILD_OPTION
cp -r web/* /fd_working_dir/artifacts/

The script goes to the folder with source code, execute OJet CLI commands building the application and returns the result web folder to the artifact directory. FlexDeploy will pick up everything from that directory and it will put it to the artifact repository.

Let’s build the image with name flexdeploy/plugin-ojetbuilder:5.0.1 and push it to Docker Hub:

docker build . -t flexdeploy/plugin-ojetbuilder:5.0.1
docker push flexdeploy/plugin-ojetbuilder:5.0.1

Having done that I am going to create a descriptor of our plugin:

<?xml version="1.0" encoding="UTF-8"?>
<PluginDefinition xmlns="https://flexagon.com/deploy/plugin">
  <Name>FlexagonOJetBuilderPlugin</Name>
  <PluginDisplayName>Oracle Jet Builder</PluginDisplayName>
  <Description>A plugin to build Jet applications.</Description>
  <TechnologyGroup>Build</TechnologyGroup>
  <SubTechnologyGroup>Jet</SubTechnologyGroup>
  <MaxConcurrentThreads>3</MaxConcurrentThreads>
  <Type>docker</Type>    
  <ImageName>flexdeploy/plugin-ojetbuilder</ImageName>    
  <Vendor>Flexagon</Vendor>
  <Version>5.0.1</Version>
  <Operations>
    <Operation>
      <Name>buildWeb</Name>
      <Description>Build Ojet Web application</Description>
      <Target>buildWeb</Target>
      <ProducesArtifacts>true</ProducesArtifacts>
      <ConsumesArtifacts>false</ConsumesArtifacts>
      <Outputs>
        <AllowsUserDefined>false</AllowsUserDefined>
      </Outputs>
      <Inputs>
        <AllowsUserDefined>false</AllowsUserDefined>
        <Input>
          <Name>FDOJETBUILD_WORKSPACE</Name>
          <DisplayName>Workspace Name</DisplayName>
          <IsDefaultValueExpression>false</IsDefaultValueExpression>
          <DataType>String</DataType>
          <DisplayRows>1</DisplayRows>
          <DisplayColumns>100</DisplayColumns>
          <Description>Specify workspace name.</Description>
          <IsRequired>false</IsRequired>
          <IsEncrypted>false</IsEncrypted>
        </Input>
        <Input>
          <Name>FDOJETBUILD_OPTION</Name>
          <DisplayName>Options</DisplayName>
          <IsDefaultValueExpression>false</IsDefaultValueExpression>
          <DataType>String</DataType>
          <DisplayRows>1</DisplayRows>
          <DisplayColumns>100</DisplayColumns>
          <Description>Options to pass to ojet build</Description>
          <IsRequired>false</IsRequired>
          <IsEncrypted>false</IsEncrypted>
        </Input>
      </Inputs>
      <EndPointSpecification>
        <Selection>
          <All/>
        </Selection>
        <Execution>
          <Any/>
        </Execution>
      </EndPointSpecification>
    </Operation>
  </Operations>
</PluginDefinition>

It looks like a regular plugin.xml file. The only thing is that plugin type is docker and there is a reference to Docker image in the ImageName tag. As in case with a regular Java-based plugin we are going to create a jar file to upload the plugin to FlexDeploy. The jar file contains a single plugin.xml file. So, in folder with plugin.xml we are executing the following:

jar cvfM0 FlexagonOJetBuilderPlugin-5.0.1.jar *

This will create a jar file that FlexDeploy is capable to download as a plugin:

Ok, it looks like the plugin is in place. Let’s use it in FlexDeploy. Plugins of this type can run on either “Docker Host” or “K8s cluster” endpoints:

  • Docker Host. An endpoint with Docker engine installed.
  • K8s cluster. An endpoint with kubectl installed and configured to communicate with a K8s cluster.

For example I have an endpoint with kubectl talking to a K8s cluster in Oracle Cloud Infrastructure:

When FlexDeploy is invoking a plugin operation on this endpoint the job will be actually done in a Docker container running in a K8s cluster.

The workflow with our new plugin looks like this one:

Where the buildWeb step is invoking the buildWeb operation of Oracle Jet Builder plugin:

I told you that would be easy.

That’s it!

Previous Post: FlexDeploy is a Container: Run FlexDeploy as a Docker Container

Eugene Fedorenko

I have over 16 years of progressive experience in information technology with software design and development, testing and deployment of enterprise banking software. Graduated from Kharkiv Aviation Institute (Ukraine) in 1999 with a master's degree in computer science. I previously worked for CS Integra in Ukraine and for eProseed in the Netherlands, focusing on building enterprise solutions with Oracle ADF. Recently, I joined Flexagon and hold a position of Senior Architect. I have been recognized as an Oracle Certified Professional (OCP) and I am considered to be an expert in Oracle Fusion Middleware. I have been a speaker at various local and international IT conferences such as Oracle Day, Oracle OpenWorld, ODTUG Kscope, RMOUG Training Days, UKOUG and DOAG. I am an author at the ADF practice blog and a member of ADF Enterprise Methodology Group.

More posts by Eugene Fedorenko
  

Leave a Reply

Your email address will not be published. Required fields are marked *