Chapter 7. Provisioning an RHMAP Build Farm
This feature is a technical preview. The hosted Build Farm remains the default configuration. Red Hat recommends that you:
- Install RHMAP and verify your installation with the hosted {BuildFarmName}.
- Install {BuildFarmName} without changing the {BuildFarmName} configuration.
- After verifying the {BuildFarmName} installation, run the {BuildFarmName} installation again with the option to change the configuration to point to the self-managed {BuildFarmName}.
For more information, see:
- Mobile Developer Guide for information required by mobile developers to build apps.
- Administrator’s Guide for information on administering the {BuildFarmName}, including specific information about Configuring a macOS Server for Customization.
7.1. Overview of Build Farm Installation
By default, RHMAP is configured to use the build farm hosted by Red Hat to create binary files for iOS and Android Client Apps as described in Section 5.2.3.3, “Configure Front End Components”. You can provision a self-managed build farm, this guide provides detailed steps to deploy the RHMAP build farm on an OpenShift Container Platform and a MacOS server. After provisioning, the build farm consists of:
An OpenShift project which includes:
- A Jenkins server pod which runs all the build jobs for creating Client App binaries.
- One or more pods with all the required tools to build Android apk files, dynamically provisioned as required to create the Android binaries.
- A nagios server for monitoring the {BuildFarmName} components
- An optional macOS Server with all the required tools to build iOS binaries
The {BuildFarmName} installation is completed by running an Ansible playbook which installs the components, including the tools required to build iOS apps on macOS servers.
The Client App templates included in this release contain Jenkins configuration files (Jenkinsfile) that enable you to use the self-managed build farm.
7.2. Prerequisites for {BuildFarmName}
This guide assumes several prerequisites are met before the installation:
- A working RHMAP 4.6 Self-Managed Core and MBaaS installation
- An optional macOS server if you need to build iOS Apps. You also require a user with sudo permissions and SSH access. See macOS Prerequisites for further details.
- Ansible version 2.2 is installed on a management node which has SSH access to the OpenShift cluster nodes. See Section 2.2, “Configure Ansible for installing RHMAP components.” for more information.
- Java is required for some configuration of Jenkins during the installation. The Ansible playbook installs Java if required.
- All nodes in the cluster must be registered with the Red Hat Subscription Manager. See Chapter 2, Preparing Infrastructure for Installation for detailed steps.
- The build farm requires outbound internet access to perform npm installations, make sure that all relevant nodes have outbound internet access before installation.
- As part of the technical preview, the Ansible playbook retrieves the Build Farm container images from https://hub.docker.com/. Make sure you have access to this site before attempting installation.
- An existing OpenShift Container Platform installation, version 3.3, 3.4 or 3.5 (A mininum of 2 cores and 6G RAM and 1G per concurrent build).
- The OpenShift Container Platform master and router must be accessible from the RHMAP Core.
- A wildcard DNS entry must be configured for the OpenShift Container Platform router IP address.
- A trusted wildcard certificate must be configured for the OpenShift Container Platform router. See Using Wildcard Certificates in OpenShift Container Platform documentation.
-
Image streams and images in the
openshiftnamespace must be updated to the latest version. Refer to sections Updating the Default Image Streams and Templates and Importing the Latest Images in the OpenShift Container Platform Installation and Configuration guide. You must have administrative access to the OpenShift cluster using the
ocCLI tool, enabling you to:- Create a project, and any resource typically found in a project (for example, deployment configuration, service, route).
- Edit a namespace definition.
- Create a security context constraint.
- Manage nodes, specifically labels.
For information on installation and management of an OpenShift Container Platform cluster and its users, see the official OpenShift documentation.
- Section 7.3, “macOS Specific Prerequisites”
- Set up persistent storage - you need to create Persistent Volumes with specific parameters in OpenShift Container Platform.
- Install the build farm from a template
- Verify the installation
7.3. macOS Specific Prerequisites
Red Hat recommends a single MacInCloud installation with the following specification:
- 4GB RAM
- 2 Cores
- macOS 10.12 Sierra
- 30GB minimum disk space and additional 20GB per XCode version
7.3.1. macOS and macOS Ansible Scripts Configuration
To configure your macOS server:
7.3.1.1. Create a SSH User
Ansible requires SSH access to the macOS server in order to correctly provision the machine to support iOS builds. To enable this, it is required that a user with sudo permissions and SSH access is created on the target machine. An example bash script is provided to achieve this.
The provided scripts helps with creating an OSX user. Do not use these scripts without reviewing their contents as it will allow access to your machine with a default password. Change the default PASSWORD and ensure USER_ID is not assigned.
By default, this script will create a user named jenkins with a UID of 550 and add the user to the the sudoers file. The users PASSWORD variable is set by default to Password1. To enable iOS builds, this user is added to the admin group.
If using the sample script (contents provided below) you should read it carefully, understand its implications and edit it as required. The script can be downloaded for convenience and run using the following commands:
curl -O https://raw.githubusercontent.com/aerogear/digger-jenkins/FH-v4.6/admin/create-osx-user.sh sudo bash create-osx-user.sh
#!/usr/bin/env bash
USERNAME="jenkins"
PASSWORD="Password1"
REAL_NAME="Jenkins Agent"
GROUP_NAME="staff"
# the first user's id is 500, second is 501 ...
# picking a big number to be on the safe side.
# You can run this one to list UIDs
# dscl . -list /Users UniqueID
USER_ID=550
# GID 20 is `staff`
GROUP_ID=20
############### end of parameters
. /etc/rc.common
dscl . create /Users/${USERNAME}
dscl . create /Users/${USERNAME} RealName ${REAL_NAME}
dscl . passwd /Users/${USERNAME} ${PASSWORD}
dscl . create /Users/${USERNAME} UniqueID ${USER_ID}
dscl . create /Users/${USERNAME} PrimaryGroupID ${GROUP_ID}
dscl . create /Users/${USERNAME} UserShell /bin/bash
dscl . create /Users/${USERNAME} NFSHomeDirectory /Users/${USERNAME}
dseditgroup -o edit -a ${USERNAME} -t user admin
cp -R /System/Library/User\ Template/English.lproj /Users/${USERNAME}
chown -R ${USERNAME}:${GROUP_NAME} /Users/${USERNAME}
echo "${USERNAME} ALL=(ALL:ALL) ALL" >> /etc/sudoers
echo "Done creating OSX user - you may need to restart the osx server to apply all changes for the user ${USERNAME}"Restart the server to implement the changes made above.
7.3.1.2. Configure Remote Login
You must enable the Ansible process running remotely to execute commands on the macOS server via SSH.
A sample script (contents provided below) is provided to achieve this. The USERNAME variable must match the user that was created in the previous step. It can be downloaded and executed by running the following:
curl -O https://raw.githubusercontent.com/aerogear/digger-jenkins/FH-v4.6/admin/enable-osx-remote-login.sh sudo bash enable-osx-remote-login.sh
#!/usr/bin/env bash
# This script helps with enabling SSH for given OSX user.
# This script is not meant to be run in an automation. Run it manually.
USERNAME="jenkins"
# com.apple.access_ssh is a special group name on OSX.
# any user part of that group can have SSH connections in.
OSX_SSH_GROUP_NAME="com.apple.access_ssh"
systemsetup -setremotelogin on
# in order to check what groups are are there:
# dscl . list /Groups PrimaryGroupID
# create a group for limiting SSH access
dseditgroup -o create -q ${OSX_SSH_GROUP_NAME}
# add user into this group
dseditgroup -o edit -a ${USERNAME} -t user ${OSX_SSH_GROUP_NAME}
# now, following should work ---> ssh username@localhost
This allows the USERNAME created previously to access the server via SSH.
7.3.2. Connecting Using Ansible
A number of tasks in the provision-osx Ansible role used in the installer require privilege escalation. This allows us to run commands as sudo user
The user created in the previous steps should be provided as a host variable to Ansible via ansible_ssh_user
Set ansible_sudo_pass variable or pass the --ask-sudo-pass flag when running the Ansible playbook to enable the installer to work with root permissions. This value should match the password set when creating the user.
7.3.3. Configuring Network access
The macOS server requires a network access to the following hosts. If you are using a proxy, configure it to allow access to these hosts.
Table 7.1. Required resources
| Hostname | Provides |
|---|---|
|
| |
|
| |
|
| |
|
|
Access to other external internet resources is required if you install other packages as described in the Administrator’s Guide.
7.4. Persistent Storage Setup
Ensure that the persistent volumes are configured according to the OpenShift documentation for configuring PersistentVolumes. If you are using NFS, see the Troubleshooting NFS Issues section for more information.
Some components of the Build Farm require persistent storage. For example, Nagios for storing historical monitoring data.
As a minimum, make sure your OpenShift Container Platform cluster has the following persistent volumes in an Available state, with at least the amount of free space listed below:
- 40GB for Jenkins
- 10GB for Android-sdk
- 1GB for Nagios
For detailed information on PersistentVolumes and how to create them, see Persistent Storage in the OpenShift Container Platform documentation.
7.5. Installing {BuildFarmName}
-
Navigate to the
/opt/rhmap/4.6/rhmap-installer/ Create or update the inventory file
NoteRed Hat recommends that you review each variable values to avoid errors during installation.
Run a variation of the following command and follow the instructions displayed:
ansible-playbook -i <inventory-file> buildfarm.yml [--skip-tags=<exclude-option>] [-e "core_project_name=<core-project-name>"]
The
-e "core_project_name=<core-project-name>"option allows you configure RHMAP to use the self-managed Build Farm.The
--skip-tags=<exclude-option>allows you skip tasks. For example, to install the buildfarm for Android Applications only:ansible-playbook -i your-inventory-copy buildfarm.yml --skip-tags=provision-osx -e "core_project_name=<core-project-name>"
In the following example, you install {BuildFarmName} for Android and iOS Applications, but do not configure RHMAP to use the self-managed {BuildFarmName}:
ansible-playbook -i your-inventory-copy buildfarm.yml -e "core_project_name=<core-project-name>"
After this installation is complete, you can run the following command to configure RHMAP to use the self-managed {BuildFarmName}:
ansible-playbook -i your-inventory-copy buildfarm.yml -e "core_project_name=<core-project-name" --tags=configure-millicore
Complete the on-screen instructions.
There are three points during the installation when the installer stops and manual steps required:
- Accept the Android SDK Licence.
- Copy the server’s public ssh key to Jenkins. The server is where ansible task are running.
Accept the Oracle Licence when installing Java on macOS server
All of these steps are required for the installation to complete successfully. At each step the Ansible Installer pauses and prompts with the required actions.
During the installation the Ansible playbook performs the following tasks:
- Verify and install (if required) the minimum Java version
- Create a project in OpenShift
- Install Jenkins
- Install Android SDK to a Persistent Volume
- Configure Jenkins
- Setup macOS Server(s) (optional depending on command used)
- Configure RHMAP Core to target the Self-Managed Buildfarm
- Install Nagios
- Display URL and credentials for Jenkins and Nagios
These tasks are idempotent. You can run them multiple times and produce the same results.
Once the installation is complete, verify the installation following the steps in Verify Installation Section
7.6. Setting Up an Inventory File for Build Farm
Installing {BuildFarmName} requires additional inventory file entries compared to the installation of Core and MBaaS. Use the information in this section to either edit your existing inventory file or create a new inventory file as described in the Section 2.2.1, “Setting Up an Inventory File.” section.
7.6.1. General Inventory File Variables
| Variable name | Description | Default value | Required |
|---|---|---|---|
| jenkins_route_protocol | Route protocol used to contact Jenkins | https | No |
7.6.2. Android Inventory File Variables
| Variable name | Description | Default value | Required |
|---|---|---|---|
| android_sdk_home | Location of Android SDK that is installed in the Android SDK container. | /opt/android-sdk-linux | No |
7.6.3. {BuildFarmName} Configuration Inventory File Variables
| Variable name | Description | Default value | Required |
|---|---|---|---|
| project_name | Name of the OpenShift project. | digger | No |
| concurrent_android_builds | Number of max number of concurrent Android builds that are allowed. | 5 | No |
7.6.4. Jenkins Inventory File Variables
| Variable name | Description | Default value | Required |
|---|---|---|---|
| project_name | Name of the OpenShift project. | digger | No |
| enable_oauth | Enable OAuth OpenShift integration. If false, a static account is initialized. | false | No |
| master_memory_limit | Maximum amount of memory for Jenkins master container. | 3Gi | No |
| master_volume_capacity | Space available for data. | 40Gi | No |
7.6.5. Nagios Inventory File Variables
These variables are used in Nagios when sending alert emails.
| Variable name | Description | Default value | Required |
|---|---|---|---|
| smtp_server | SMTP server to send alert emails. | localhost | No |
| smtp_username | SMTP username. | username | No |
| smtp_password | Password of the SMTP user. | password | No |
| smtp_from_address | SMTP from address. | No | |
| rhmap_admin_email | Destination address of alert emails. | root@localhost | No |
| jenkins_user | Jenkins user associated with nagios checks | admin | No |
| jenkins_pass | Password for jenkins_user | password | No |
7.6.6. Java Inventory File Variables
Variables below are to configure the JDK to install on the remote that runs Jenkins CLI commands.
| Variable name | Description | Default value | Required |
|---|---|---|---|
| repo | Repository to install JDK. | rhel-7-server-optional-rpms | No |
| java_version | JDK version to install. | 1.8.0 | No |
7.6.7. Login Inventory File Variables
Variables below are used to login to the OpenShift Cluster.
| Variable name | Description | Default value | Required |
|---|---|---|---|
| oc_user | OpenShift user to login to OpenShift. | Yes | |
| oc_password | OpenShift user password. | Yes | |
| login_url | Url used to log in. |
No. * Except if running the playbook locally against a remote server and using |
7.6.8. Provisioning macOS Inventory File Variables
Variables below are used while provisioning an OSX node.
| Variable name | Description | Default value | Required |
|---|---|---|---|
| ansible_become_pass | Sudo password for carrying out root priveledged actions on a macOS server | Yes/No if passing the value via the command line | |
| remote_tmp_dir | What directory to use when creating some temporary files. | /tmp | No |
| node_versions | A list of Node versions to install. | 6 | No |
| xcode_install_version | The version of the xcode-install tool to install on the node. | 2.2.1 | No |
| gem_packages | name: public_suffix, version: 2.0.5:name: xcode-install: <xcode_install_version> | No | |
| cocoapods_version | The version of the Cocoapods gem to install. | 1.1.1 | No |
| npm_packages |
A list of global NPM packages to install. Format: | name: cordova, version: 7.0.1 | No |
| homebrew_packages |
The packages to install using Homebrew. Format: | gpg, grep, jq | No |
| homebrew_version | The version of Homebrew to install (git tag). | 1.3.1 | No |
| homebrew_repo | The git repo where Homebrew resides (defaults to GitHub repo). | No | |
| homebrew_prefix | The parent directory of the directory where Homebrew resides. | /usr/local | No |
| homebrew_install_path | Where Homebrew will be installed. | <homebrew_prefix>/Homebrew | No |
| homebrew_brew_bin_path |
Where | /usr/local/bin | No |
| homebrew_paths | <homebrew_install_path>,<homebrew_brew_bin_path>,<homebrew_var_path>,/usr/local/Cellar,/usr/local/opt,/usr/local/share,/usr/local/etc,/usr/local/include | No | |
| homebrew_taps | A list of taps to add. | homebrew/core, caskroom/cask | No |
| xcode_install_user | Apple Developer Account username. If this is not set then Xcode will not be installed. | Yes (if xcode is required) | |
| xcode_install_password | Apple Developer Account password. If this is not set then Xcode will not be installed. | Yes (if xcode is required) | |
| xcode_install_session_token |
Apple Developer Account auth cookie from | Yes (if xcode is required) | |
| xcode_versions | A list of Xcode versions to install. These may take over 30 minutes each to install. | '8.3.3' | No |
| xcode_default_version | Teh default version of xcode to be used | <xcode_version>[0] | No |
| apple_wwdr_cert_url | Apple WWDR certificate URL. Defaults to Apple’s official URL. | http://developer.apple.com/certificationauthority/AppleWWDRCA.cer | No |
| apple_wwdr_cert_file_name | Output file name of the downloaded file. | AppleWWDRCA.cer | No |
| buildfarm_node_port | The port to connect to the macOS node on. | 22 | No |
| buildfarm_node_root_dir | Path to Jenkins root folder. | /Users/jenkins | No |
| buildfarm_credential_id | Identifier for the Jenkins credential object. | macOS_buildfarm_cred | No |
| buildfarm_credential_description | Description of the Jenkins credential object. | Shared credential for the macOS nodes in the buildfarm. | No |
| buildfarm_node_name | Name of the slave/node in Jenkins. | macOS (<node_host_address>) | No |
| buildfarm_node_labels | List of labels assigned to the macOS node. | ios | No |
| buildfarm_user_id | Jenkins user ID. | admin | No |
| buildfarm_node_executors | Number of executors (Jenkins configuration) on the macOS node. There is currently no build isolation with the macOS node meaning there is no guaranteed support for concurrent builds. This value should not be changed unless you are certain all apps will be built with the same signature credentials. | 1 | No |
| buildfarm_node_mode | How the macOS node should be utilised. The following options are available: | NORMAL | No. Can be set to EXCLUSIVE to set that only build jobs with labels matching this node will use this node. |
| buildfarm_node_description | Description of the macOS node in Jenkins. | macOS node for the buildfarm | No |
| project_name | The name of the {BuildFarmName} Project in OpenShift | digger | No |
| proxy_host | Proxy url/base hostname to be used. | No/Yes if the macOS server only has outbound internet access via proxy | |
| proxy_port | Proxy port to be used. | No/Yes if the macOS server only has outbound internet access via proxy | |
| proxy_device | The proxy network device to use the proxy config from the list of devices. | Ethernet | No |
| proxy_ctx | A list of proxies to be set. | webproxy, securewebproxy | No |
| buildfarm_lang_env_var |
Value of | en_US.UTF-8 | No |
| buildfarm_path_env_var |
| $PATH:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin | No |
| credential_private_key | Private key stored in Jenkins and used to SSH into the macOS node. If this is not set then a key pair will be generated. | No | |
| credential_public_key | Public key of the pair. If this is not set then a key pair will be generated. | No | |
| credential_passphrase | Passphrase of the private key. This is stored in Jenkins and used to SSH into the macOS node. If this is not set the private key will not be password protected. | No |
7.7. Verifying The {BuildFarmName} Installation
To monitor the status of the {BuildFarmName} components, the {BuildFarmName} installer will install Nagios and several Nagios checks. At the end of the installation Ansible will trigger each of the checks and output the status of these checks. To navigate to Nagios and manually verify that all checks are passing, follow the steps below.
To verify the installation
- Log in to Nagios using the url and credentials outputted at the end of the installation.
- Navigate to the Services Link
- Verify that all Nagios checks are passing.
The environment specific checks carried out by Nagios are:
- Container CPU Usage
- Container Memory Usage
- Container Resource Limits
- Pod Disk Storage
The {BuildFarmName} specific checks carried out by Nagios are:
- Availability of the Jenkins container (pod)
- Status of the network link between Jenkins and the macOS servers
- Status of the Android SDK PersistentVolumeClaim
After verifying that the {BuildFarmName} is installed correctly, you can use it to build applications as described in Using the Build Farm If you want to revert to using the hosted build farm, follow the instructions in the Using the RHMAP Hosted Build Farm section.

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.