Using the CloudBees Flow Groovy API

The CloudBees Flow Groovy API is a client-side Apache Groovy library for the CloudBees Flow REST APIs. When CloudBees Flow is installed—Server, Agent, or Tools (using the express or advanced installation type)—the client-side Groovy library for the CloudBees Flow REST APIs is installed along with ec-groovy, which is a small wrapper program that can be used to run Groovy scripts.

Default Location of ec-groovy

  • The default location for ec-groovy on Linux is

  • The default location for ec-groovy on Windows is

    C:\Program Files\Electric Cloud\ElectricCommander\bin\ec-groovy

On Windows hosts, the CloudBees Flow installation process automatically adds ec-groovy to your path. On Linux hosts, you need to add $INSTAL_DIE/bin to the path manually:

export PATH=$PATH:/opt/electriccloud/electriccommander/bin

Running ec-groovy

To run ec-groovy from the command line:

  1. Set COMMANDER_HOME and COMMANDER_DATA as environment variables.

    If you are running ec-groovy within a CloudBees Flow job context, these environment variables are automatically set.

  2. Enter ec-groovy <yourGroovyOptions> <GroovyScriptName>.groovy on the command line.


In multizone CloudBees Flow deployments, CloudBees Flow agents that are in a different zone than the CloudBees Flow server must be running version 9.2 or later for the ec-groovy job step to run successfully on those agents. If you have any other zones in between that lead back to the server, you must also upgrade their gateway agents to version 9.2 or later.

For details about multiple zones and gateway agents, see Zones and Gateways.


If you encounter this error while running ec_groovy from the command line, PKIX path building failed

then perform the following steps to resolve the issue.

  • Obtain the CloudBees Flow server’s certificate.

    • Windows platforms:

      • Issue the following on a command line to display the server certificate contents.

        openssl s_client -connect <replace-cloudbees-flow-server-name-here>:8443
      • Copy the server certificate contents after Server certificate into a file, say ef-server.crt. Here is an example of the content that needs to be copied.

        -----BEGIN CERTIFICATE-----
        -----END CERTIFICATE-----
    • UNIX platforms:

      Issue the following on a command line; this gets the certificate and saves it to the file, ef-server.crt (newlines added for readability).

      COMMANDER_HOME=/opt/electriccloud/electriccommander &&
         OPENSSL_CONF="$COMMANDER_HOME/conf/agentssl.cnf" && echo -e "quit\n" |
         $COMMANDER_HOME/bin/openssl s_client -connect replace-electricflow-server-name-here:8443
         | \sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ef-server.crt
  • Verify the certificate contents saved in ef-server.crt (newlines added for readability).

    COMMANDER_HOME=/opt/electriccloud/electriccommander &&   LD_LIBRARY_PATH=$COMMANDER_HOME/lib &&      OPENSSL_CONF="$COMMANDER_HOME/conf/agentssl.cnf" && echo -e "quit\n" |     $COMMANDER_HOME/bin/openssl x509 -in ef-server.crt -text
  • Import the certificate into the Java keystore (newlines added for readability).

    COMMANDER_HOME=/opt/electriccloud/electriccommander &&
       $COMMANDER_HOME/jre/bin/keytool -import -trustcacerts
                                       -keystore $COMMANDER_HOME/jre/lib/security/cacerts -storepass changeit
                                       -noprompt -alias myEFcert -file ef-server.crt

Confirm that ec-groovy successfully runs from the command line.

Running Groovy Scripts using Third-Party Libraries

In addition to the CloudBees Flow Groovy APIs, ec-groovy can be used to run any Groovy script using third-party libraries. Consider the following Groovy script:


def client = new RESTClient('\')

client.get( path : '/search', query : [q:'Groovy'] ) { response, data ->

  println "Response Status: ${response.statusLine}"
  println data


Example: Groovy GET Script 1

def http = new HTTPBuilder('\')
def html = http.get( path : '/search', query : [q:'Groovy'] )

Example: Groovy GET Script 2

def http = new HTTPBuilder('\')

http.get( path : '/search',
          contentType : TEXT,
          query : [q:'Groovy'] ) { resp, reader ->

  println "response status: ${resp.statusLine}"
  println 'Headers: -----------'
  resp.headers.each { h ->
    println " ${} : ${h.value}"
  println 'Response data: -----'
  System.out << reader
  println '\n--------------------'

Example: Groovy POST Script

import static

def http = new HTTPBuilder( '\' )
def postBody = [name: 'bob', title: 'construction worker'] // will be url-encoded path: '/', body: postBody,
           requestContentType: URLENC ) { resp ->

  println "POST Success: ${resp.statusLine}"
  assert resp.statusLine.statusCode == 201

Example of a grapeConfig.xml File Without Internet Repositories

Groovy also allows runtime resolution of artifacts that can download themselves across the internet. To disable this ability or to whitelist only trusted repositories to download, write a grapeConfig.xml file and put it in the $COMMANDER_DATA/grape directory. This is an example of a grapeConfig.xml file without internet repositories:

Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.

    <settings defaultResolver="downloadGrapes"/>
        <chain name="downloadGrapes" returnFirst="true">
            <filesystem name="cachedGrapes">
                <ivy pattern="${user.home}/.groovy/grapes
                <artifact pattern="${user.home}/.groovy/grapes/[organisation]
            <ibiblio name="localm2" root="file:${user.home}/.m2/repository/" checkmodified="true"
                    changingPattern=".*" changingMatcher="regexp" m2compatible="true"/>