├── tests ├── terraform-sanity.bats ├── run_bats.sh ├── install-docker.bats ├── README.md ├── helpers.bash ├── load-image.bats └── container-runtest.sh ├── .gitignore ├── scripts ├── common │ ├── version-specific.sh │ ├── docker-user.sh │ └── prereqs.sh └── boot-master │ ├── start_install.sh │ ├── get-args.sh │ ├── copy_cluster_skel.sh │ ├── parse-hostgroups.py │ ├── functions.sh │ ├── load-config.py │ ├── scaleworkers.sh │ ├── load-image.sh │ ├── generate_hostsfiles.sh │ └── install-docker.sh ├── outputs.tf ├── CONTRIBUTING.md ├── variables.tf ├── hooks.tf ├── main.tf └── README.md /tests/terraform-sanity.bats: -------------------------------------------------------------------------------- 1 | 2 | @test "Sanity test terraform" { 3 | 4 | run bash -c 'cd .. ; terraform init' 5 | [ $status -eq 0 ] 6 | } 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # .tfstate files 5 | *.tfstate 6 | *.tfstate.* 7 | 8 | # .tfvars files 9 | *.tfvars 10 | 11 | # generated key files 12 | *.pem 13 | -------------------------------------------------------------------------------- /scripts/common/version-specific.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ver=$1 4 | SCRIPT=$(realpath -s $0) 5 | SCRIPTPATH=$(dirname $SCRIPT) 6 | 7 | for SCRIPT in ${SCRIPTPATH}/${ver}-* 8 | do 9 | if [ -f $SCRIPT -a -x $SCRIPT ] 10 | then 11 | source $SCRIPT 12 | fi 13 | done 14 | 15 | exit 0 16 | -------------------------------------------------------------------------------- /scripts/common/docker-user.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Some RHEL based installations may not have docker installed yet. 4 | # Only aattempt to add user to group if docker is installed and the user is not root 5 | if grep -q docker /etc/group 6 | then 7 | iam=$(whoami) 8 | 9 | if [[ $iam != "root" ]] 10 | then 11 | sudo usermod -a -G docker $iam 12 | fi 13 | fi 14 | -------------------------------------------------------------------------------- /tests/run_bats.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | test_file=$1 3 | 4 | if [[ -z "${test_file}" ]]; then 5 | echo "Usage: $0 " 6 | exit 1 7 | fi 8 | 9 | export SCRIPT_PATH="$(pwd | sed 's/tests/scripts/g')" 10 | export TEST_DIR="$(pwd)" 11 | # Build a test matrix 12 | 13 | # Operating systems and versions that should be suppported 14 | images=("ubuntu:16.04" "centos:centos7.6.1810") 15 | 16 | if [[ "${test_file}" == "all" ]] ; then 17 | bats_files=(./*.bats) 18 | else 19 | bats_files=($test_file) 20 | fi 21 | 22 | for bats_file in ${bats_files[@]}; do 23 | echo "=> $bats_file" 24 | 25 | for image in ${images[@]} ; do 26 | echo "==> $image" 27 | export IMAGE=${image} 28 | bats "$bats_file" 29 | done 30 | done 31 | -------------------------------------------------------------------------------- /scripts/boot-master/start_install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source /tmp/icp-bootmaster-scripts/get-args.sh 3 | source /tmp/icp-bootmaster-scripts/functions.sh 4 | 5 | # If loaded from tarball, icp version may not be specified in terraform 6 | if [[ -z "${icp_version}" ]]; then 7 | icp_version=$(get_inception_image) 8 | fi 9 | 10 | # Figure out the version 11 | # This will populate $org $repo and $tag 12 | parse_icpversion ${icp_version} 13 | echo "registry=${registry:-not specified} org=$org repo=$repo tag=$tag" 14 | 15 | docker run -e LICENSE=accept -e ANSIBLE_CALLBACK_WHITELIST=profile_tasks,timer --net=host -t -v ${cluster_dir}:/installer/cluster ${registry}${registry:+/}${org}/${repo}:${tag} ${install_command} ${log_verbosity} |& tee /tmp/icp-${install_command}-log.txt 16 | 17 | exit ${PIPESTATUS[0]} 18 | -------------------------------------------------------------------------------- /scripts/boot-master/get-args.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while getopts ":i:d:v:c:l:u:p:o:k:s:" arg; do 4 | case "${arg}" in 5 | i) 6 | icp_inception=${OPTARG} 7 | ;; 8 | d) 9 | cluster_dir=${OPTARG} 10 | ;; 11 | v) 12 | log_verbosity=${OPTARG} 13 | ;; 14 | c) 15 | install_command=${OPTARG} 16 | ;; 17 | l) 18 | locations+=( ${OPTARG} ) 19 | ;; 20 | u) 21 | username=${OPTARG} 22 | ;; 23 | p) 24 | password=${OPTARG} 25 | ;; 26 | o) 27 | docker_package_location=${OPTARG} 28 | ;; 29 | k) 30 | docker_image=${OPTARG} 31 | ;; 32 | s) 33 | docker_version=${OPTARG} 34 | ;; 35 | \?) 36 | echo "Invalid option : -$OPTARG in commmand $0 $*" >&2 37 | exit 1 38 | ;; 39 | :) 40 | echo "Missing option argument for -$OPTARG in command $0 $*" >&2 41 | exit 1 42 | ;; 43 | esac 44 | done -------------------------------------------------------------------------------- /tests/install-docker.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | # These variables are used by the run_in_docker function 4 | export APT_PREREQS="sudo:curl:lsb-release:dialog" 5 | export YUM_PREREQS="sudo:curl:subscription-manager" 6 | 7 | load helpers 8 | 9 | @test "Install latest docker on ${IMAGE}" { 10 | run run_in_docker \ 11 | -i ${IMAGE} \ 12 | -s "/tmp/icp-bootmaster-scripts/install-docker.sh" \ 13 | -p "-k docker-ce -s latest" \ 14 | -t "docker --version" 15 | [ $status -eq 0 ] 16 | } 17 | 18 | @test "Install version pinned docker on ${IMAGE}" { 19 | run run_in_docker \ 20 | -i ${IMAGE} \ 21 | -s "/tmp/icp-bootmaster-scripts/install-docker.sh" \ 22 | -p "-k docker-ce -s 18.06.1" \ 23 | -t "docker --version" 24 | [ $status -eq 0 ] 25 | } 26 | 27 | 28 | @test "Install invalid docker version on ${IMAGE} should fail" { 29 | run run_in_docker \ 30 | -i ${IMAGE} \ 31 | -s "/tmp/icp-bootmaster-scripts/install-docker.sh" \ 32 | -p "-k docker-ce -s 3.1.1" \ 33 | -t "docker --version" 34 | [ $status -gt 0 ] 35 | } 36 | -------------------------------------------------------------------------------- /outputs.tf: -------------------------------------------------------------------------------- 1 | 2 | output "icp_public_key" { 3 | description = "The public key used for boot master to connect via ssh for cluster setup" 4 | value = "${var.generate_key ? tls_private_key.icpkey.public_key_openssh : var.icp_pub_key}" 5 | } 6 | 7 | output "icp_private_key" { 8 | description = "The public key used for boot master to connect via ssh for cluster setup" 9 | value = "${var.generate_key ? tls_private_key.icpkey.private_key_pem : var.icp_priv_key}" 10 | } 11 | 12 | output "install_complete" { 13 | depends_on = ["null_resource.icp-install"] 14 | description = "Boolean value that is set to true when ICP installation process is completed" 15 | value = "true" 16 | } 17 | 18 | output "icp_version" { 19 | value = "${var.icp-inception}" 20 | } 21 | 22 | output "cluster_ips" { 23 | value = "${local.icp-ips}" 24 | } 25 | 26 | locals { 27 | default_admin_password = "${lookup(var.icp_configuration, "default_admin_password", random_string.generated_password.result)}" 28 | } 29 | 30 | output "default_admin_password" { 31 | value = "${local.default_admin_password != "" ? local.default_admin_password : random_string.generated_password.result}" 32 | } 33 | -------------------------------------------------------------------------------- /scripts/boot-master/copy_cluster_skel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | LOGFILE=/tmp/copyclusterskel.log 3 | exec 3>&1 4 | exec > >(tee -a ${LOGFILE} >/dev/null) 2> >(tee -a ${LOGFILE} >&3) 5 | 6 | echo "Script started with inputs $@" 7 | 8 | source /tmp/icp-bootmaster-scripts/functions.sh 9 | source /tmp/icp-bootmaster-scripts/get-args.sh 10 | 11 | # If loaded from tarball, icp version may not be specified in terraform 12 | if [[ -z "${icp_version}" ]]; then 13 | icp_version=$(get_inception_image) 14 | fi 15 | 16 | # Figure out the version 17 | # This will populate $org $repo and $tag 18 | parse_icpversion ${icp_version} 19 | echo "registry=${registry:-not specified} org=$org repo=$repo tag=$tag" 20 | 21 | # Copy the default data to the cluster directory 22 | docker run -e LICENSE=accept -v /tmp/icp:/data ${registry}${registry:+/}${org}/${repo}:${tag} cp -r cluster /data 23 | sudo chown $(whoami):$(whoami) -R /tmp/icp 24 | ensure_directory_reachable ${cluster_dir} 25 | sudo mv /tmp/icp/cluster/* ${cluster_dir} 26 | 27 | # Take a backup of original config file, to keep a record of original settings and comments 28 | cp ${cluster_dir}/config.yaml ${cluster_dir}/config.yaml-original 29 | -------------------------------------------------------------------------------- /tests/README.md: -------------------------------------------------------------------------------- 1 | # Tests for the deploy module 2 | 3 | Various unit and validation tests for the module. 4 | 5 | Most tests run individual scripts in containers to validate expected behavior. 6 | This allows the scripts to easily be validated in a number of linux distributions and versions. 7 | 8 | There is a helper script `container-runtest.sh` which will run inside the test container. 9 | The script will setup the directory structure, install pre-requisites and run validation tests. 10 | `container-runtest.sh` will return the sum of tested script exit code + validation code exit code. 11 | 12 | ## Pre-requisits 13 | 14 | To run the tests you'll need the following installed 15 | 16 | - [BATS](https://github.com/bats-core/bats-core) 17 | - [Terraform](https://www.terraform.io/) 18 | - Docker (it must be running) 19 | 20 | ## Running tests 21 | 22 | To run all existing tests 23 | ``` 24 | ./run_bats.sh all 25 | ``` 26 | 27 | To run single test, for example load-image 28 | ``` 29 | ./run_bats.sh load-image.bats 30 | ``` 31 | 32 | 33 | Most tests are run in docker containers, so you can monitor the tests by running 34 | `docker logs -f ` on the active container 35 | -------------------------------------------------------------------------------- /scripts/boot-master/parse-hostgroups.py: -------------------------------------------------------------------------------- 1 | import os, sys, json, ConfigParser 2 | 3 | hgfile = '/tmp/icp-host-groups.json' 4 | hostfile = None 5 | ipfile = '/tmp/cluster-ips.txt' 6 | 7 | supplied_cluster_dir = "" 8 | if len(sys.argv) > 1: 9 | supplied_cluster_dir = sys.argv[1] 10 | hostfile = os.path.join(supplied_cluster_dir,"hosts") 11 | if not os.path.isdir(supplied_cluster_dir): 12 | hostfile = None 13 | 14 | if hostfile is None: 15 | raise Exception("Invalid cluster directory provided: {}".format(supplied_cluster_dir)) 16 | 17 | # Exit if we don't need to do anything 18 | if os.stat(hgfile).st_size == 0: 19 | exit(1) 20 | 21 | # Load the hostgroup info from file if provided 22 | with open(hgfile, 'r') as stream: 23 | hostgroups = json.load(stream) 24 | 25 | # Create the hostfile 26 | hf = open(hostfile, 'w') 27 | h = ConfigParser.ConfigParser(allow_no_value=True) 28 | 29 | ips = [] 30 | for group in hostgroups.keys(): 31 | h.add_section(group) 32 | for host in hostgroups[group]: 33 | ips.append(host) 34 | h.set(group, host) 35 | 36 | h.write(hf) 37 | hf.close() 38 | 39 | # Write a list of ip addresses, removing duplicates 40 | i = open(ipfile, 'w') 41 | i.write(",".join(list(set(ips)))) 42 | i.close() 43 | -------------------------------------------------------------------------------- /tests/helpers.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ################################ 3 | ## Simple common helper 4 | ## functions for BATS tests 5 | ## 6 | ################################ 7 | 8 | 9 | ##################################### 10 | ## Function to run a script in docker 11 | ## Inputs 12 | ## -i Docker image to run scipt in, i.e. ubuntu:16.04 13 | ## -s