A JBoss Project
Red Hat

Latest posts

Introduction

The JBoss Tools OpenShift tooling uses rsync between your local workstation and running pods on an OpenShift cluster. This is used by the OpenShift server adapter to provide hot deploy and debugging features to the developer.

If you’re running JBoss Tools and/or Red Hat JBoss Developer Studio on a Linux or MacOSX platform, you’re not concerned by this article. If you’re running on Windows platform, you may be aware that there are some permission relation issues that are painful. The aim of this article is to explain the root cause and how to fix it.

The problem

The OpenShift tooling is using rsync to synchronize local changes to your project to remote pods running on an OpenShift cluster. The problem on Windows is that rsync is very Linux/UNIX based and by default, it tries to may users/permissions of files between the two platforms. As Windows user and permission management is totally different from the Linux one, it leads to strange permissions being set on your local files, this causing some failures when trying to update those files.

It’s possible to prevent rsync to map this user/permission through some rsync flag. Unfortunately, rsync is not launched by the OpenShift tooling but through the help of the OpenShift oc client which does not allow to pass this flags.

The solution

On Windows, rsync is provided by several providers. The well known ones are Cygwin and cwRsync.

The last one is based on Cygwin and both of them use a mapping between Windows paths (C: based) and Linux/UNIX ones. This mapping can be controlled through a file called etc/fstab. The solution that we are proposing here is to instruct not to map user and permissions at this level. Please note that this file may not be present, so may need to create one in this case.

How to locate the file

The fstab file is located into the rsync distribution your are using (Cygwin or cwRsync). In order to get the installation path, open a Windows command shell and type the following command:

where rsync.exe

This will give you the path of the rsync.exe executable that is used by default. It has the general form of $MY_RSYNC_DIST_DIR\bin\rsync.exe where $MY_RSYNC_DIST_DIR is the folder where your rsync distribution is installed.

The fstab file is located at $MY_RSYNC_DIST_DIR/etc/fstab.

Updating the file

If you don’t find the file at the proper location (cwRsync case), then it’s very simple. Create the file at $MY_RSYNC_DIST_DIR/etc/fstab and paste the following content:

# /etc/fstab
#
#    This file is read once by the first process in a Cygwin process tree.
#    To pick up changes, restart all Cygwin processes.  For a description
#    see https://cygwin.com/cygwin-ug-net/using.html#mount-table

# This is default anyway:
none /cygdrive cygdrive binary,posix=0,user,noacl 0 0

If the file already exists, then it’s likely that you have a line like:

none /cygdrive cygdrive binary,posix=0,user 0 0

So, just add the noacl flag to the list of options:

none /cygdrive cygdrive binary,posix=0,user,noacl 0 0

Save the file, you’re done and you should not have anymore permission errors during rsync operations !!!.

Jeff Maury

JBoss Tools 4.5.2 and Red Hat JBoss Developer Studio 11.2 for Eclipse Oxygen.2 are here waiting for you. Check it out!

devstudio11

Installation

JBoss Developer Studio comes with everything pre-bundled in its installer. Simply download it from our JBoss Products page and run it like this:

java -jar jboss-devstudio-<installername>.jar

JBoss Tools or Bring-Your-Own-Eclipse (BYOE) JBoss Developer Studio require a bit more:

This release requires at least Eclipse 4.7 (Oxygen) but we recommend using the latest Eclipse 4.7.2 Oxygen JEE Bundle since then you get most of the dependencies preinstalled.

Once you have installed Eclipse, you can either find us on the Eclipse Marketplace under "JBoss Tools" or "Red Hat JBoss Developer Studio".

For JBoss Tools, you can also use our update site directly.

http://download.jboss.org/jbosstools/oxygen/stable/updates/

What is new?

Our main focus for this release was on adoption of Java9, improvements for container based development and bug fixing. Eclipse Oxygen itself has a lot of new cool stuff but let me highlight just a few updates in both Eclipse Oxygen and JBoss Tools plugins that I think are worth mentioning.

OpenShift 3

Spring Boot applications support in OpenShift server adapter

The OpenShift server adapter allowed hotdeploy and debugging for JEE and NodeJS based applications. It now supports Spring Boot applications with some limitations: the Spring Boot devtools module must be added to your application as it monitors code changes and as the application must be launched in exploded mode, you must use the upstream image (docker.io/fabric8/s2i-java) rather than the downstream image builder fis-java-openshift.

As an example, we’ve provided an OpenShift template that will create an OpenShift application based on the upstream application and a Git repository that added the Spring Boot devtools to the Fabric8 Spring Boot quickstart.

{
  "apiVersion": "v1",
  "kind": "Template",
  "metadata": {
    "annotations": {
      "description": "Spring-Boot and CXF JAXRS QuickStart. This example demonstrates how you can use Apache CXF JAXRS with Spring Boot on Openshift. The quickstart uses Spring Boot to configure a little application that includes a CXF JAXRS endpoint with Swagger enabled.",
      "tags": "quickstart,java,springboot,fis",
      "iconClass": "icon-jboss",
      "version": "2.0"
    },
    "name": "s2i-spring-boot-cxf-jaxrs"
  },
  "labels": {
    "template": "s2i-spring-boot-cxf-jaxrs"
  },
  "parameters": [
    {
      "name": "APP_NAME",
      "displayName": "Application Name",
      "required": true,
      "value": "s2i-spring-boot-cxf-jaxrs",
      "description": "The name assigned to the application."
    },
    {
      "name": "GIT_REPO",
      "displayName": "Git Repository URL",
      "required": true,
      "value": "https://github.com/jeffmaury/spring-boot-cxf-jaxrs.git",
      "description": "The URL of the repository with your application source code."
    },
    {
      "name": "GIT_REF",
      "displayName": "Git Reference",
      "value": "hotdeploy",
      "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch."
    },
    {
      "name": "SERVICE_NAME",
      "displayName": "Service Name",
      "value": "cxf-jaxrs",
      "description": "Exposed service name."
    },
    {
      "name": "BUILDER_VERSION",
      "displayName": "Builder version",
      "value": "2.0",
      "description": "The version of the FIS S2I builder image to use."
    },
    {
      "name": "APP_VERSION",
      "displayName": "Application Version",
      "value": "1.0.0.redhat-000014",
      "description": "The application version."
    },
    {
      "name": "MAVEN_ARGS",
      "displayName": "Maven Arguments",
      "value": "package -DskipTests -Dfabric8.skip -e -B",
      "description": "Arguments passed to mvn in the build."
    },
    {
      "name": "MAVEN_ARGS_APPEND",
      "displayName": "Extra Maven Arguments",
      "description": "Extra arguments passed to mvn, e.g. for multi-module builds."
    },
    {
      "name": "ARTIFACT_DIR",
      "displayName": "Maven build directory",
      "description": "Directory of the artifact to be built, e.g. for multi-module builds."
    },
    {
      "name": "IMAGE_STREAM_NAMESPACE",
      "displayName": "Image Stream Namespace",
      "value": "openshift",
      "required": true,
      "description": "Namespace in which the Fuse ImageStreams are installed. These ImageStreams are normally installed in the openshift namespace. You should only need to modify this if you've installed the ImageStreams in a different namespace/project."
    },
    {
      "name": "BUILD_SECRET",
      "displayName": "Git Build Secret",
      "generate": "expression",
      "description": "The secret needed to trigger a build.",
      "from": "[a-zA-Z0-9]{40}"
    },
    {
      "name": "CPU_REQUEST",
      "displayName": "CPU request",
      "value": "0.2",
      "required": true,
      "description": "The amount of CPU to requests."
    },
    {
      "name": "CPU_LIMIT",
      "displayName": "CPU limit",
      "value": "1.0",
      "required": true,
      "description": "The amount of CPU the container is limited to use."
    }
  ],
  "objects": [
    {
      "apiVersion": "v1",
      "kind": "Route",
      "metadata": {
        "labels": {
          "component": "${APP_NAME}",
          "provider": "s2i",
          "project": "${APP_NAME}",
          "version": "${APP_VERSION}",
          "group": "quickstarts"
        },
        "name": "${SERVICE_NAME}-route"
      },
      "spec": {
        "to": {
          "kind": "Service",
          "name": "${SERVICE_NAME}"
        }
      }
    },
    {
      "apiVersion": "v1",
      "kind": "Service",
      "metadata": {
        "annotations": {
        },
        "labels": {
          "component": "${APP_NAME}",
          "provider": "s2i",
          "project": "${APP_NAME}",
          "version": "${APP_VERSION}",
          "group": "quickstarts"
        },
        "name": "${SERVICE_NAME}"
      },
      "spec": {
        "clusterIP": "None",
        "deprecatedPublicIPs": [],
        "ports": [
          {
            "port": 9413,
            "protocol": "TCP",
            "targetPort": 8080
          }
        ],
        "selector": {
          "project": "${APP_NAME}",
          "component": "${APP_NAME}",
          "provider": "s2i",
          "group": "quickstarts"
        }
      }
    },
    {
      "kind": "ImageStream",
      "apiVersion": "v1",
      "metadata": {
        "name": "${APP_NAME}",
        "creationTimestamp": null,
        "labels": {
          "component": "${APP_NAME}",
          "group": "quickstarts",
          "project": "${APP_NAME}",
          "provider": "s2i",
          "version": "${APP_VERSION}"
        }
      },
      "spec": {},
      "status": {
        "dockerImageRepository": ""
      }
    },
    {
      "kind": "BuildConfig",
      "apiVersion": "v1",
      "metadata": {
        "name": "${APP_NAME}",
        "creationTimestamp": null,
        "labels": {
          "component": "${APP_NAME}",
          "group": "quickstarts",
          "project": "${APP_NAME}",
          "provider": "s2i",
          "version": "${APP_VERSION}"
        }
      },
      "spec": {
        "triggers": [
          {
            "type": "GitHub",
            "github": {
              "secret": "${BUILD_SECRET}"
            }
          },
          {
            "type": "Generic",
            "generic": {
              "secret": "${BUILD_SECRET}"
            }
          },
          {
            "type": "ConfigChange"
          },
          {
            "type": "ImageChange",
            "imageChange": {}
          }
        ],
        "source": {
          "type": "Git",
          "git": {
            "uri": "${GIT_REPO}",
            "ref": "${GIT_REF}"
          }
        },
        "strategy": {
          "type": "Source",
          "sourceStrategy": {
            "from": {
              "kind": "DockerImage",
              "name": "fabric8/s2i-java:${BUILDER_VERSION}"
            },
            "forcePull": true,
            "incremental": true,
            "env": [
              {
                "name": "BUILD_LOGLEVEL",
                "value": "5"
              },
              {
                "name": "ARTIFACT_DIR",
                "value": "${ARTIFACT_DIR}"
              },
              {
                "name": "MAVEN_ARGS",
                "value": "${MAVEN_ARGS}"
              },
              {
                "name": "MAVEN_ARGS_APPEND",
                "value": "${MAVEN_ARGS_APPEND}"
              }
            ]
          }
        },
        "output": {
          "to": {
            "kind": "ImageStreamTag",
            "name": "${APP_NAME}:latest"
          }
        },
        "resources": {}
      },
      "status": {
        "lastVersion": 0
      }
    },
    {
      "kind": "DeploymentConfig",
      "apiVersion": "v1",
      "metadata": {
        "name": "${APP_NAME}",
        "creationTimestamp": null,
        "labels": {
          "component": "${APP_NAME}",
          "group": "quickstarts",
          "project": "${APP_NAME}",
          "provider": "s2i",
          "version": "${APP_VERSION}"
        }
      },
      "spec": {
        "strategy": {
          "resources": {}
        },
        "triggers": [
          {
            "type": "ConfigChange"
          },
          {
            "type": "ImageChange",
            "imageChangeParams": {
              "automatic": true,
              "containerNames": [
                "${APP_NAME}"
              ],
              "from": {
                "kind": "ImageStreamTag",
                "name": "${APP_NAME}:latest"
              }
            }
          }
        ],
        "replicas": 1,
        "selector": {
          "component": "${APP_NAME}",
          "deploymentconfig": "${APP_NAME}",
          "group": "quickstarts",
          "project": "${APP_NAME}",
          "provider": "s2i",
          "version": "${APP_VERSION}"
        },
        "template": {
          "metadata": {
            "creationTimestamp": null,
            "labels": {
              "component": "${APP_NAME}",
              "deploymentconfig": "${APP_NAME}",
              "group": "quickstarts",
              "project": "${APP_NAME}",
              "provider": "s2i",
              "version": "${APP_VERSION}"
            }
          },
          "spec": {
            "containers": [
              {
                "name": "${APP_NAME}",
                "image": "library/${APP_NAME}:latest",
                "readinessProbe" : {
                  "httpGet" : {
                    "path" : "/health",
                    "port" : 8081
                  },
                  "initialDelaySeconds" : 10
                },
                "livenessProbe" : {
                  "httpGet" : {
                    "path" : "/health",
                    "port" : 8081
                  },
                  "initialDelaySeconds" : 180
                },
                "ports": [
                  {
                    "containerPort": 8778,
                    "name": "jolokia"
                  }
                ],
                "env" : [ {
                  "name" : "KUBERNETES_NAMESPACE",
                  "valueFrom" : {
                    "fieldRef" : {
                      "fieldPath" : "metadata.namespace"
                    }
                  }
                } ],
                "resources": {
                  "requests": {
                    "cpu": "${CPU_REQUEST}"
                  },
                  "limits": {
                    "cpu": "${CPU_LIMIT}"
                  }
                }
              }
            ]
          }
        }
      },
      "status": {}
    }
  ]
}

You can see a demo of the OpenShift server adapter for Spring Boot application here:

Support for route timeouts and liveness probe for OpenShift Server Adapter debugging configurations

While debugging your OpenShift deployment, you may face two different issues:

  • if you launch your test through a Web browser, then it’s likely that you will access your OpenShift deployment through an OpenShift route. The problem is that, by default, OpenShift routes have a 30 seconds timeout for each request. So if you’re stepping through one of your breakpoints, you will get a timeout error message in the browser window even if you can still debug your OpenShift deployment. And you’re now stuck will the navigation of your OpenShift application.

  • if your OpenShift deployment has a liveness probe configured, depending on your virtual machine capabilities or how your debugger is configured, if your stepping into one of your breakpoints, the liveness probe may fail thus OpenShift so OpenShift will restart your container and your debugging session will be destroyed.

So, from now, when the OpenShift server adapter is started in debug mode, the following action are being performed:

  • if an OpenShift route is found that is linked to the OpenShift deployment you want to debug, the route timeout will be set or increased to 1 hour. The original or default value will be restored when the OpenShift server adapter will be restarted in run mode.

  • if your OpenShift deployment has a liveness probe configured, the initialDelay field will be increased to 1 hour if the defined value for this field is lower than 1 hour. If the value of this field is defined to a value greater than 1 hour, it is left intact. The original value will be restored when the OpenShift server adapter will be restarted in run mode

Enhanced command to delete resource(s)

When it comes to delete OpenShift resources, you had two different choices:

  • individually delete each resource but as some resources are hidden by the OpenShift explorer, it may become troublesome

  • delete the containing OpenShift project but you are then deleting more resources than required

There is now a new enhanced command to delete resources. It is available at the OpenShift project level and it will first list all the available OpenShift resources for the selected OpenShift project. You can now select the ones you want to delete and you can also filter the list using a filter that will be applied to the labels for each retrieved OpenShift resource.

So if you have two different deployments in a single OpenShift project (if you using OpenShift Online Starter for example) or if you have different kind of resources in a single deployment, you can now distinct them.

Let’s see this in action:

In this example, I have deployed an EAP6.4 based application and an EAP7.0 based one. Here is what you can see from the OpenShift explorer:

new delete resources explorer

Now, let’s invoke the new delete command on the eap OpenShift project: right click the OpenShift project and select Delete Resources…​:

new delete resources dialog

Let suppose that we want to delete the EAP6.4 deployement. Enter eap=6.4 in the filter field:

new delete resources dialog1

Push the Select All button:

new delete resources dialog2

Close this dialog by pushing the OK button. The resources will be deleted and the OpenShift explorer will be updated accordingly:

new delete resources explorer1

Server tools

EAP 7.1 Server Adapter

A server adapter has been added to work with EAP 7.1 and Wildfly 11. It’s based on WildFly 11. This new server adapter includes support for incremental management deployment like it’s upstream WildFly 11 counterpart.

Fuse Tooling

Fuse 7 Karaf-based runtime Server adapter

Fuse 7 is cooking and preliminary versions are already available on early-access repository. Fuse Tooling is ready to leverage them so that you can try the upcoming major Fuse version.

Fuse 7 Server Adapter

Classical functionalities with server adapters are available: automatic redeploy, Java debug, Graphical Camel debug through created JMX connection. Please note: - you can’t retrieve the Fuse 7 Runtime yet directly from Fuse tooling, it is required to download it on your machine and point to it when creating the Server adapter. - the provided templates requires some modifications to have them working with Fuse 7, mainly adapting the bom. Please see work related to it in this JIRA task and its children.

Display routes defined inside "routeContext" in Camel Graphical Editor (Design tab)

"routeContext" tag is a special tag used in Camel to provide the ability to reuse routes and to split them across different files. This is very useful on large projects. See Camel documentation for more information. Since this version, the Design of the routes defined in "routeContext" tags are now displayed.

Usability improvement: Progress bar when "Changing the Camel version"

Since Fuse Tooling 10.1.0, it is possible to change the Camel version. In case the Camel version was not cached locally yet and for slow internet connections, this operation can take a while. There is now a progress bar to see the progress.

Switch Camel Version with Progress Bar

Support for creating Fuse Ignite Technical Extensions

We are happy to announce the addition of support for creating Technical Extension projects for Fuse Ignite*. That includes the creation of the project using the "New Fuse Ignite Extension Project" wizard as well as support for building the deployable artifact directly from inside the Eclipse environment.

*Fuse Ignite is a JBoss Fuse feature that provides a web interface for integrating applications. Without writing code, a business expert can use Ignite to connect to applications and optionally operate on data between connections to different applications. In Ignite, a data operation is referred to as a step in an integration. Ignite provides steps for operations such as filtering and mapping data. To operate on data in ways that are not provided by Ignite built-in steps, you can develop an Ignite extension to define one or more custom steps. Fuse Ignite comes as part of Fuse and Fuse Online. Please refer to the online documentation for more information on how to create and configure technical extensions for Fuse Ignite.

Fuse Ignite Technical Extension Wizard

The provided project template allows you to define an Apache Camel route as the base flow of your new technical extension.

Fuse Ignite Technical Extension Route

To configure your new technical extension you can use the JSON file created with the new project.

Fuse Ignite Technical Extension Configuration

Forge Tools

Forge Runtime updated to 3.8.1.Final

The included Forge runtime is now 3.8.1.Final. Read the official announcement here.

And more…​

You can find more noteworthy updates in on this page.

What is next?

Having JBoss Tools 4.5.2 and Developer Studio 11.2 out we are already working on the next maintenance release for Eclipse Oxygen.

Enjoy!

Jeff Maury

Looking for older posts ? See the Archived entries.
back to top