blob: 34eb3c595f507e64b395d37327ccd22d43b957e0 [file] [log] [blame]
Tomáš Kukrál2c7026a2017-03-08 18:19:53 +01001#!/usr/bin/env bash
2
3set -e
4if [[ $DEBUG =~ ^(True|true|1|yes)$ ]]; then
5 set -x
6fi
7
8## Overrideable options
9DOCKER_IMAGE=${DOCKER_IMAGE:-"ubuntu:16.04"}
10DIST=${DIST:-xenial}
11RECLASS_ROOT=${RECLASS_ROOT:-$(pwd)}
12SALT_OPTS="${SALT_OPTS} --retcode-passthrough --force-color"
13DOCKER_OPTS="${DOCKER_OPTS} -e DEBIAN_FRONTEND=noninteractive"
14SKIP_CLEANUP=${SKIP_CLEANUP:-0}
Jakub Josef5ec16552017-05-05 17:58:54 +020015USER_ID=$(id -u)
16GROUP_ID=$(id -g)
Tomáš Kukrál2c7026a2017-03-08 18:19:53 +010017
18declare -a CONTAINERS
19
20## Functions
21log_info() {
22 echo "[INFO] $*"
23}
24
25log_err() {
26 echo "[ERROR] $*" >&2
27}
28
29docker_exec() {
30 if [[ $DETACH =~ ^(True|true|1|yes)$ ]]; then
31 exec_opts="-d"
32 else
33 exec_opts=""
34 fi
35
36 docker exec ${exec_opts} ${CONTAINER} /bin/bash -c "$*"
37}
38
39_atexit() {
40 RETVAL=$?
41 trap true INT TERM EXIT
42 if [ $SKIP_CLEANUP -eq 1 ]; then
43 return $RETVAL
44 fi
45
46 log_info "Cleaning up"
47
48 for container in ${CONTAINERS[@]}; do
Jakub Josef5ec16552017-05-05 17:58:54 +020049 CONTAINER=$container docker_exec "chown -R ${USER_ID}:${GROUP_ID} /srv/salt/reclass" || true
Tomáš Kukrál2c7026a2017-03-08 18:19:53 +010050 docker rm -f $container >/dev/null || true
51 done
52
53 if [ $RETVAL -ne 0 ]; then
54 log_err "Execution failed"
55 else
56 log_info "Execution successful"
57 fi
58
59 return $RETVAL
60}
61
62run_container() {
63 MASTER_HOSTNAME=$1
Martin Polreich441229f2017-03-31 16:20:16 +020064 CONTAINER=$(docker run ${DOCKER_OPTS} --name ${MASTER_HOSTNAME}-$(date +%s) -h $(echo ${MASTER_HOSTNAME}|cut -d . -f 1) -v ${RECLASS_ROOT}:/srv/salt/reclass -i -t -d ${DOCKER_IMAGE})
Tomáš Kukrál2c7026a2017-03-08 18:19:53 +010065 echo $CONTAINER
66}
67
68test_master() {
Ilya Kharin83bd6382017-06-27 11:12:23 +040069 local MASTER_HOSTNAME=$1 CLUSTER_DOMAIN
70 CLUSTER_DOMAIN=${MASTER_HOSTNAME#*.}
Tomáš Kukrál2c7026a2017-03-08 18:19:53 +010071 log_info "Installing packages"
72 docker_exec "which wget >/dev/null || (apt-get update; apt-get install -y wget)"
73 docker_exec "echo 'deb [arch=amd64] http://apt-mk.mirantis.com/${DIST}/ nightly salt salt-latest' > /etc/apt/sources.list.d/apt-mk.list"
74 docker_exec "wget -O - http://apt-mk.mirantis.com/public.gpg | apt-key add -"
75
76 docker_exec "apt-get update"
Matthew Mosesohn79b90b82017-05-24 17:12:18 +030077 docker_exec "apt-get install -y salt-master python-psutil iproute2 curl python-dev python-pip reclass salt-formula-*"
78 # FIXME: Use master reclass to debug undefined vars. Remove when reclass is updated
79 docker_exec "pip install -U https://github.com/madduck/reclass/archive/master.zip"
Tomáš Kukrál2c7026a2017-03-08 18:19:53 +010080
81 log_info "Setting up Salt master"
82 # TODO: remove grains.d hack when fixed in formula
83 docker_exec "mkdir -p /etc/salt/grains.d && touch /etc/salt/grains.d/dummy"
84 docker_exec "[ ! -d /etc/salt/pki/minion ] && mkdir -p /etc/salt/pki/minion"
85 docker_exec "[ ! -d /etc/salt/master.d ] && mkdir -p /etc/salt/master.d || true"
86 docker_exec "cat << 'EOF' >> /etc/salt/master.d/master.conf
87file_roots:
88 base:
89 - /usr/share/salt-formulas/env
90pillar_opts: False
91open_mode: True
92reclass: &reclass
93 storage_type: yaml_fs
94 inventory_base_uri: /srv/salt/reclass
95ext_pillar:
96 - reclass: *reclass
97master_tops:
98 reclass: *reclass
99EOF"
100
101 log_info "Setting up reclass"
102 docker_exec "[ -d /srv/salt/reclass/classes/service ] || mkdir -p /srv/salt/reclass/classes/service || true"
103 docker_exec "for i in /usr/share/salt-formulas/reclass/service/*; do
104 [ -e /srv/salt/reclass/classes/service/\$(basename \$i) ] || ln -s \$i /srv/salt/reclass/classes/service/\$(basename \$i)
105 done"
Jakub Josef5ec16552017-05-05 17:58:54 +0200106 docker_exec "chown -R ${USER_ID}:${GROUP_ID} /srv/salt/reclass/classes/service"
Tomáš Kukrál2c7026a2017-03-08 18:19:53 +0100107 docker_exec "[ ! -d /etc/reclass ] && mkdir /etc/reclass || true"
108 docker_exec "cat << 'EOF' >> /etc/reclass/reclass-config.yml
109storage_type: yaml_fs
110pretty_print: True
111output: yaml
112inventory_base_uri: /srv/salt/reclass
113EOF"
114
115 log_info "Setting up Salt minion"
116 docker_exec "apt-get install -y salt-minion"
117 docker_exec "[ ! -d /etc/salt/minion.d ] && mkdir -p /etc/salt/minion.d || true"
118 docker_exec "cat << EOF >> /etc/salt/minion.d/minion.conf
119id: ${MASTER_HOSTNAME}
120master: localhost
121EOF"
122
123 log_info "Starting Salt master service"
124 DETACH=1 docker_exec "/usr/bin/salt-master"
125 sleep 3
126
127 docker_exec "salt-call saltutil.sync_all"
128 log_info "Running states to finish Salt master setup"
129 docker_exec "reclass --nodeinfo ${MASTER_HOSTNAME} >/dev/null"
130 docker_exec "salt-call ${SALT_OPTS} state.show_top"
131
132 if [[ $SALT_MASTER_FULL =~ ^(True|true|1|yes)$ ]]; then
133 # TODO: can fail on "hostname: you must be root to change the host name"
134 docker_exec "salt-call ${SALT_OPTS} state.sls linux,openssh" || true
135 docker_exec "salt-call ${SALT_OPTS} state.sls salt,reclass"
136 else
137 docker_exec "salt-call ${SALT_OPTS} state.sls reclass.storage.node" || true
138 fi
139
Ilya Kharin83bd6382017-06-27 11:12:23 +0400140 NODES=$(docker_exec "find /srv/salt/reclass/nodes -type f -name *${CLUSTER_DOMAIN}.yml ! -name cfg*")
Tomáš Kukrál2c7026a2017-03-08 18:19:53 +0100141 for node in ${NODES}; do
142 node=$(basename $node .yml)
143 log_info "Testing node ${node}"
144 docker_exec "reclass --nodeinfo ${node} >/dev/null"
145 docker_exec "salt-call ${SALT_OPTS} --id=${node} state.show_top"
146 docker_exec "salt-call ${SALT_OPTS} --id=${node} state.show_lowstate >/dev/null"
147 done
148}
149
Ilya Kharin83bd6382017-06-27 11:12:23 +0400150run_tests() {
151 local master=$1
Tomáš Kukrál2c7026a2017-03-08 18:19:53 +0100152
Tomáš Kukrál2c7026a2017-03-08 18:19:53 +0100153 log_info "Testing Salt master ${master}"
154 log_info "Creating docker container from image ${DOCKER_IMAGE}"
155 CONTAINER=$(run_container $master)
156 CONTAINERS+=(${CONTAINER})
157 test_master $master
Ilya Kharin83bd6382017-06-27 11:12:23 +0400158}
159
160find_all_and_run_tests() {
161 local masters
162
163 masters=$(find nodes -type f -name cfg*.yml)
164 for master in ${masters[@]}; do
165 master=$(basename $master .yml)
166 echo "$master"
Ilya Kharin83bd6382017-06-27 11:12:23 +0400167 run_tests $master
168 done
169}
170
171## Main
172trap _atexit INT TERM EXIT
173
174case $1 in
175 "" | all)
176 find_all_and_run_tests
177 ;;
178 *)
179 for master; do
180 run_tests $master
181 done
182 ;;
183esac