Chapter 7. Provisioning an RHMAP Build Farm

Note

This feature is a technical preview. The hosted Build Farm remains the default configuration. Red Hat recommends that you:

  1. Install RHMAP and verify your installation with the hosted {BuildFarmName}.
  2. Install {BuildFarmName} without changing the {BuildFarmName} configuration.
  3. 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:

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.

Note

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 openshift namespace 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 oc CLI 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.

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.

Warning

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}"
Important

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

HostnameProvides

https://github.com

Homebrew packages and Cocoapods

https://raw.githubusercontent.com

NVM - Node Version Manager

http://developer.apple.com

Apple Certificates and Xcode

https://npmjs.org

NPM packages

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

Note

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}

  1. Navigate to the /opt/rhmap/4.6/rhmap-installer/
  2. Create or update the inventory file

    Note

    Red Hat recommends that you review each variable values to avoid errors during installation.

  3. 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
  1. Complete the on-screen instructions.

    There are three points during the installation when the installer stops and manual steps required:

    1. Accept the Android SDK Licence.
    2. Copy the server’s public ssh key to Jenkins. The server is where ansible task are running.
    3. 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
Note

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 nameDescriptionDefault valueRequired

jenkins_route_protocol

Route protocol used to contact Jenkins

https

No

7.6.2. Android Inventory File Variables

Variable nameDescriptionDefault valueRequired

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 nameDescriptionDefault valueRequired

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 nameDescriptionDefault valueRequired

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 nameDescriptionDefault valueRequired

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.

admin@example.com

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 nameDescriptionDefault valueRequired

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 nameDescriptionDefault valueRequired

oc_user

OpenShift user to login to OpenShift.

 

Yes

oc_password

OpenShift user password.

 

Yes

login_url

Url used to log in.

https://localhost:8443

No. * Except if running the playbook locally against a remote server and using ansible_connection=local Otherwise allow to default.

7.6.8. Provisioning macOS Inventory File Variables

Variables below are used while provisioning an OSX node.

Variable nameDescriptionDefault valueRequired

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: <PACKAGE_NAME>, version: <PACKAGE_VERSION> }.

name: cordova, version: 7.0.1

No

homebrew_packages

The packages to install using Homebrew. Format: { name: <PACKAGE_NAME> }.

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).

https://github.com/Homebrew/brew

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 brew will be installed.

/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 fastlane spaceauth command (For accounts with 2FA enabled).

 

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 LANG environment variable to set on the macOS node. CocoaPods require this to en_US.UTF-8.

en_US.UTF-8

No

buildfarm_path_env_var

$PATH environment variable to use in the macOS node.

$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

  1. Log in to Nagios using the url and credentials outputted at the end of the installation.
  2. Navigate to the Services Link
  3. 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.