Skip to content

Latest commit

 

History

History
 
 

ansible

Ansible playbooks to download and install dependencies for OpenJDK build and test on various platforms

Quickstart guide

The ansible playbooks under the playbook directory are used to set up all of the adoptopenjdk machines to be able to run building and testing of the openjdk and related projects.

The main playbooks should be run from this directory using, for example, the following command (the skipped tags are one that aren't needed on most user's machines, but are needed if you're setting up a machine for the official AdoptOpenJDK infrastructure):

ansible-playbook -i inventory_file --skip-tags adoptopenjdk,jenkins playbooks/AdoptOpenJDK_Unix_Playbook/main.yml

If you are interesting in running the playbooks within a virtual machine on your host, checkout the section on Vagrant later in this readme

Do I need to be a superuser on the target machine to run the playbooks?

Yes, in order to access the package repositories (we will perform either yum install or apt-get commands)

How do I run the playbooks?

  1. Install Ansible 2.4 or later (

    • On RHEL 7.x
    yum install epel-release
    yum install ansible
    • For Ubuntu
    sudo apt-add-repository ppa:ansible/ansible
    sudo apt update
    sudo apt install ansible
    • On another system with pip available:
    sudo pip install ansible
  2. Ensure that you have edited the hosts in /etc/ansible/ or in the project root directory. For running locally hosts file should contain something as simple as localhost ansible_connection=local.

  3. Run a playbook to install dependencies, e.g. for Ubuntu 14.x on x86:

    ansible-playbook -s playbooks/AdoptOpenJDK_Unix_Playbook/main.yml --skip-tags=adoptopenjdk,jenkins
    
    # Or to use a custom hosts file:
    ansible-playbook -i /path/to/hosts -s AdoptOpenJDK_Unix_Playbook/main.yml --skip-tags=adoptopenjdk,jenkins
  4. The Ansible playbook will download and install any dependencies needed to build OpenJDK

How do I run the playbooks on a remote Windows host?

Ansible can't be installed locally on a Windows machine, therefore the playbook has to be ran on a seperate system and then pointed at a Windows Machine.

This can be done by doing the following:

  1. In playbooks/AdoptOpenJDK_Windows_Playbook/main.yml change - hosts: {{ groups['Vendor_groups'] ... to - hosts: all
  2. Alter playbooks/AdoptOpenJDK_Windows_Playbook/group_vars/all/adoptopenjdk_variables.yml to add ansible_winrm_transport: credssp. Uncomment and set ansible_password to your admin user's password.
  3. Create a hosts file containing the IP address of the Windows machine.

The playbook can then be run by executing the following, from the openjdk-infrastructure/ansible directory:

ansible-playbook -i hosts -u ADMIN_USER --skip-tags adoptopenjdk,jenkins playbooks/AdoptOpenJDK_Windows_Playbook/main.yml

Due to the time taken to execute some of the roles on the playbook, such as the cygwin and MSVS installations, a ConnectTimeout error could occur.

ConnectTimeout: HTTPSConnectionPool(host='x.xx.xxx.xxx', port=5986): Max retries exceeded with url: /wsman (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x7f1f31ef2d10>, 'Connection to x.xx.xxx.xxx timed out. (connect timeout=30)'))
fatal: [x.xx.xxx.xxx]: FAILED! => {"msg": "Unexpected failure during module execution.", "stdout": ""}

In certain cases, this can be fixed by increasing a couple of timeout variables in playbooks/AdoptOpenJDK_Windows_Playbook/group_vars/all/adoptopenjdk_variables.yml

ansible_winrm_operation_timeout_sec: 600
ansible_winrm_read_timeout_sec: 630

Additional information about winrm variables can be found here

If running from a Mac, you may encounter a python related error

objc[39516]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called.
objc[39516]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
ERROR! A worker was found in a dead state

In which case, running the following should fix it export no_proxy="*"

Which playbook do I run?

Our playbooks are named according to the operating system they are supported for, keep in mind that package availability may differ between operating system releases.

The main ones are as follows:

  • AdoptOpenJDK_Unix_Playbook/main.yml (For all *IX machines including macOS)
  • AdoptOpenJDK_Windows_Playbook/main.yml (Windows systems)
  • AdoptOpenJDK_AIX_Playbook/main.yml (For AIX systems)
  • AdoptOpenJDK_ITW_Playbooks (CentOS or Red Hat only - IcedTea-WEB setup)

There are also various playbooks used to set up other machines in the adoptopenjdk infrastructure - generally most end users won't need these but I'll include them for completeness:

  • vagrant.yml (Used to set up an Ubuntu machine to run Vagrant playbook testing)

Where can I run the playbooks?

On any machine you have SSH access to: in the playbooks here we are using hosts: local, our playbook will run on the hosts defined in the Ansible install directory's hosts file. To run on the local machine, we will have the following text in our /etc/ansible/hosts file:

[local]
127.0.0.1

Running ansible --version will display your Ansible configuration folder that contains the hosts file you can modify

Skipping one or more tags via CLI when running Ansible playbooks

In general skipping adoptopenjdk and jenkins as per all of the examples above will be all that's needed - those tags are in place for all roles that will probe problematic on a non-AdoptOpenJDK owned machine. Most of the roles have their own tags you can use to skip them if required, but one that might be useful is dont_remove_system. We have one or two roles such as GIT_source in the *IX playbook which can potentially remove any system installed version of the tool after building a later one from source into /usr/local. For maximum safety you can use that too, but you should consider whether that's really what you want to do if you add that to your skip list.

Passing in extra variables from the command line

The below example is appropriate to run playbook by skipping tasks by using a combination of conditionals and tags (linked and dependent tasks will not be executed):

ansible-playbook -i [/path/to/hosts] -b AdoptOpenJDK_Unix_Playbook/main.yml --extra-vars "Jenkins_Username=jenkins Jenkins_User_SSHKey=[/path/to/id_rsa.pub] Nagios_Plugins=Disabled Slack_Notification=Disabled Superuser_Account=Disabled" --skip-tags="adoptopenjdk,jenkins,dont_remove_system"

Note that when running from inside a vagrant instance:

  • the [/path/to/hosts] can be replace with /vagrant/playbooks/hosts
  • the [/path/to/id_rsa.pub] can be replaced with /home/vagrant/.ssh/id_rsa.pub

This is useful if one or more tasks are failing to execute successfully or if they need to be skipped due to not deemed to be executed in the right environment.

Verbose mode, debugging Ansible playbooks

Below are the levels of verbosity available with using ansible scripts:

ansible-playbook -v -b playbooks/AdoptOpenJDK_Unix_Playbook/main.yml
ansible-playbook -vv -b playbooks/AdoptOpenJDK_Unix_Playbook/main.yml
ansible-playbook -vvv -b playbooks/AdoptOpenJDK_Unix_Playbook/main.yml
ansible-playbook -vvvv -b playbooks/AdoptOpenJDK_Unix_Playbook/main.yml

A snippet from the man pages of Ansible:

-v, --verbose
      verbose mode (-vvv for more, -vvvv to enable connection debugging)

Expected output of a successful Ansible build

When the above ansible-playbook commands succeed, we should get something like this:

PLAY RECAP *********************************************************************
172.28.128.134             : ok=131  changed=96   unreachable=0    failed=0   

Running via Vagrant and VirtualBox

We have some automation for running under Vagrant which we use to validate playbook changes before they are merged. See the pbTestScripts folder for more info. The scripts from there are run on jenkins in the VagrantPlaybookCheck job

Any additional help in setting up Vagrant with Virtualbox can be found here

Vagrant setup guide - macOS

To test the ansible scripts, you'll need to install the following programs.

  1. Install Homebrew 2.1.7 or later
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  1. Install Vagrant 2.2.5 or later
brew cask install vagrant
  1. Install Virtualbox 6.0.8 or later:
brew cask install virtualbox

Note: export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES is required before running the playbook on macOS.

Vagrant setup guide - Ubuntu (other Linuxes are similar)

If you're on Ubuntu we have a playbook that can be used to set up your machine to run vagrant in playbooks/vagrant.yml but it simply installs Vagrant from https://releases.hashicorp.com/vagrant/2.2.5/vagrant_2.2.5_x86_64.deb and also virtualbox from their web site

Vagrant setup guide - Windows

To test the ansible scripts, you'll need to install Vagrant and Virtualbox from here

Executing under vagrant (Linux/MacOS X)

To test the ansible scripts you can set up a Virtual Machine isolated from your own host system. Several Vagrantfiles have been provided and the usual vagrant commands should get it up and running.

The following method runs the ansible playbooks on the local connection. Normally you will be running ansible on your development machine, and using it to modify remote hosts.

NOTE The /vagrant/ directory maps to the directory on your host that you launched the VagrantFile from e.g. ~/workspace/adoptium/infrastructure/ansible

Within the openjdk-infrastructure/ansible directory:

ln -sf Vagrantfile.Centos6 Vagrantfile

vagrant up

vagrant ssh # Uses default ssh login, user=vagrant, password=vagrant

cd /vagrant/playbooks

Note when using our Vagrantfiles:

  • A hosts file containing localhost ansible_connection=local will already be present in the directory with the playbook scripts (/vagrant/playbooks).
  • A public key file id_rsa.pub will already be present in the /home/vagrant/.ssh/ folder
  1. Run a playbook to install dependencies, for Linux on x86:

ansible-playbook -b AdoptOpenJDK_Unix_Playbook/main.yml --skip-tags=adoptopenjdk,jenkins

In case one or more tasks fail or should not be run in the local environment, see Skipping one or more tags via CLI when running Ansible playbooks for further details. Ideally, the below can be run for smooth execution in the vagrant box:

ansible-playbook -b AdoptOpenJDK_Unix_Playbook/main.yml --skip-tags="install_zulu,jenkins_authorized_key,nagios_add_key,add_zeus_user_key"

Executing under vagrant (Windows)

Ansible cannot be installed on a Windows machine, so you should boot a Linux VM using Vagrant and install it there instead.

Within the openjdk-infrastructure/ansible directory:

  1. Copy a Linux Vagrantfile from the openjdk-infrastructure/ansible/vagrant directory into the openjdk-infrastructure/ansible directory, and save it without an extension, for example:
copy .\vagrant\Vagrantfile.CentOS7 .

ren Vagrantfile.CentOS7 Vagrantfile
  1. Start up and use the VM:
vagrant up

vagrant ssh # Uses default ssh login, user=vagrant, password=vagrant
  1. Install Ansible 2.4 or later (see beginning of the README).

You should now be able to navigate to the correct directory using:

cd /vagrant/playbooks

and run a playbook using Vagrant.

Using Ansible to modify Vagrant VM remote hosts (linux)

The following method runs the ansible playbooks against a Vagrant VM remotely.

ln -sf Vagrantfile.CentOS6 Vagrantfile

ssh-keygen -q -f id_rsa -t rsa -N '' # Generate a keypair for use between host and VM

vagrant up

After starting the vagrant machine, several files need to be edited to allow ansible to make the connection.

  1. In playbooks/AdoptOpenJDK_Unix_Playbook/main.yml change - hosts: {{ groups['Vendor_groups'] ... to - hosts: all
  2. Add timeout=30 and private_key_file=id_rsa under the [defaults] section in ansible.cfg
  3. Alter the playbooks/AdoptOpenJDK_Unix_Playbook/hosts.tmp file generated by the Vagrantfile to only contain the larger IP Address

To start running the playbook against the VM, from the openjdk-infrastructure/ansible directory:

ansible-playbook -i playbooks/AdoptOpenJDK_Unix_Playbook/hosts.tmp -u vagrant -b --skip-tags adoptopenjdk,jenkins playbooks/AdoptOpenJDK_Unix_Playbook/main.yml

Using Ansible to modify Vagrant VM remote hosts (Windows)

To run the playbook against a Windows Vagrant VM remotely, the follow steps can be taken:

vagrant plugin install vagrant-disksize

pip install pywinrm requests-credssp	# Pre-reqs for using winrm

ln -sf Vagrantfile.Win2012 Vagrantfile

vagrant up

Note: If the machine running this only has 8G of memory, the windows VM may go into an aborted state on bootup. This is due to assigning the VM too much memory. To stop this, halve the memory to the VM by changing the following line in the Windows vagrantfile: v.memory = 5120

Several files will also need to be edited for Windows:

  1. In playbooks/AdoptOpenJDK_Windows_Playbook/main.yml change - hosts: {{ groups['Vendor_groups'] ... to - hosts: all
  2. Alter the playbooks/AdoptOpenJDK_Windows_Playbook/hosts.tmp file generated by the Vagrantfile to remove the CRs and only contain the larger IP Address
  3. Alter playbooks/AdoptOpenJDK_Windows_Playbook/group_vars/all/adoptopenjdk_variables.yml to add ansible_winrm_transport: credssp. Uncomment and set ansible_password to vagrant

To run the playbook against the VM, from the openjdk-infrastructure/ansible directory:

ansible-playbook -i playbooks/AdoptOpenJDK_Windows_playbook/hosts.tmp -u vagrant --skip-tags jenkins,adoptopenjdk,MSVS_2013 playbooks/AdoptOpenJDK_Windows_Playbook/main.yml

Note: it is recommended to skip the MSVS_2013 CE installation role (MSVS_2013) as it is no longer globally available, and is expected to be removed at some point, and replaced with a later version of MSVS.

Alternatively, pbTestScripts/vagrantPlaybookCheck.sh will do this for you when executing ./vagrantPlaybookCheck.sh -v Win2012 -u https://github.com/adoptopenjdk/openjdk-infrastructure --retainVM

Can I have multiple VMs on different OSs?

As vagrant uses Virtualbox to create VMs, multiple VMs on different OSs can be setup. You can do this by following these steps:

  1. Make a copy of the existing directory you have.
  2. The Vagrantfile is a symlink or copy of the Vagrantfile that is labelled with the desired OS (e.g. VagrantFile.Ubuntu1804)
  3. Continue the vagrant functions as normal.

To access each vagrant VM, you'll need to be in the correct directory to vagrant ssh into, or the ID of the machine can be used:

vagrant ssh 1a2b3c4d

Use vagrant-global-status --prune to find the directory the vagrant VM is in and the ID of the machine.