blob: a7c642f58ee816db8878c9558c37a9320fc539c2 [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}
15
16declare -a CONTAINERS
17
18## Functions
19log_info() {
20 echo "[INFO] $*"
21}
22
23log_err() {
24 echo "[ERROR] $*" >&2
25}
26
27docker_exec() {
28 if [[ $DETACH =~ ^(True|true|1|yes)$ ]]; then
29 exec_opts="-d"
30 else
31 exec_opts=""
32 fi
33
34 docker exec ${exec_opts} ${CONTAINER} /bin/bash -c "$*"
35}
36
37_atexit() {
38 RETVAL=$?
39 trap true INT TERM EXIT
40 if [ $SKIP_CLEANUP -eq 1 ]; then
41 return $RETVAL
42 fi
43
44 log_info "Cleaning up"
45
46 for container in ${CONTAINERS[@]}; do
47 CONTAINER=$container docker_exec "chown -R $(id -u):$(id -g) /srv/salt/reclass" || true
48 docker rm -f $container >/dev/null || true
49 done
50
51 if [ $RETVAL -ne 0 ]; then
52 log_err "Execution failed"
53 else
54 log_info "Execution successful"
55 fi
56
57 return $RETVAL
58}
59
60run_container() {
61 MASTER_HOSTNAME=$1
Martin Polreich441229f2017-03-31 16:20:16 +020062 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 +010063 echo $CONTAINER
64}
65
66test_master() {
67 MASTER_HOSTNAME=$1
68 log_info "Installing packages"
69 docker_exec "which wget >/dev/null || (apt-get update; apt-get install -y wget)"
70 docker_exec "echo 'deb [arch=amd64] http://apt-mk.mirantis.com/${DIST}/ nightly salt salt-latest' > /etc/apt/sources.list.d/apt-mk.list"
71 docker_exec "wget -O - http://apt-mk.mirantis.com/public.gpg | apt-key add -"
72
73 docker_exec "apt-get update"
74 docker_exec "apt-get install -y salt-master python-psutil iproute2 curl reclass salt-formula-*"
75
76 log_info "Setting up Salt master"
77 # TODO: remove grains.d hack when fixed in formula
78 docker_exec "mkdir -p /etc/salt/grains.d && touch /etc/salt/grains.d/dummy"
79 docker_exec "[ ! -d /etc/salt/pki/minion ] && mkdir -p /etc/salt/pki/minion"
80 docker_exec "[ ! -d /etc/salt/master.d ] && mkdir -p /etc/salt/master.d || true"
81 docker_exec "cat << 'EOF' >> /etc/salt/master.d/master.conf
82file_roots:
83 base:
84 - /usr/share/salt-formulas/env
85pillar_opts: False
86open_mode: True
87reclass: &reclass
88 storage_type: yaml_fs
89 inventory_base_uri: /srv/salt/reclass
90ext_pillar:
91 - reclass: *reclass
92master_tops:
93 reclass: *reclass
94EOF"
95
96 log_info "Setting up reclass"
97 docker_exec "[ -d /srv/salt/reclass/classes/service ] || mkdir -p /srv/salt/reclass/classes/service || true"
98 docker_exec "for i in /usr/share/salt-formulas/reclass/service/*; do
99 [ -e /srv/salt/reclass/classes/service/\$(basename \$i) ] || ln -s \$i /srv/salt/reclass/classes/service/\$(basename \$i)
100 done"
101
102 docker_exec "[ ! -d /etc/reclass ] && mkdir /etc/reclass || true"
103 docker_exec "cat << 'EOF' >> /etc/reclass/reclass-config.yml
104storage_type: yaml_fs
105pretty_print: True
106output: yaml
107inventory_base_uri: /srv/salt/reclass
108EOF"
109
110 log_info "Setting up Salt minion"
111 docker_exec "apt-get install -y salt-minion"
112 docker_exec "[ ! -d /etc/salt/minion.d ] && mkdir -p /etc/salt/minion.d || true"
113 docker_exec "cat << EOF >> /etc/salt/minion.d/minion.conf
114id: ${MASTER_HOSTNAME}
115master: localhost
116EOF"
117
118 log_info "Starting Salt master service"
119 DETACH=1 docker_exec "/usr/bin/salt-master"
120 sleep 3
121
122 docker_exec "salt-call saltutil.sync_all"
123 log_info "Running states to finish Salt master setup"
124 docker_exec "reclass --nodeinfo ${MASTER_HOSTNAME} >/dev/null"
125 docker_exec "salt-call ${SALT_OPTS} state.show_top"
126
127 if [[ $SALT_MASTER_FULL =~ ^(True|true|1|yes)$ ]]; then
128 # TODO: can fail on "hostname: you must be root to change the host name"
129 docker_exec "salt-call ${SALT_OPTS} state.sls linux,openssh" || true
130 docker_exec "salt-call ${SALT_OPTS} state.sls salt,reclass"
131 else
132 docker_exec "salt-call ${SALT_OPTS} state.sls reclass.storage.node" || true
133 fi
134
135 NODES=$(docker_exec "find /srv/salt/reclass/nodes -type f -name *.yml ! -name cfg*")
136 for node in ${NODES}; do
137 node=$(basename $node .yml)
138 log_info "Testing node ${node}"
139 docker_exec "reclass --nodeinfo ${node} >/dev/null"
140 docker_exec "salt-call ${SALT_OPTS} --id=${node} state.show_top"
141 docker_exec "salt-call ${SALT_OPTS} --id=${node} state.show_lowstate >/dev/null"
142 done
143}
144
145
146## Main
147trap _atexit INT TERM EXIT
148
149masters=$(find nodes -type f -name cfg*.yml)
150for master in ${masters[@]}; do
151 master=$(basename $master .yml)
152 log_info "Testing Salt master ${master}"
153 log_info "Creating docker container from image ${DOCKER_IMAGE}"
154 CONTAINER=$(run_container $master)
155 CONTAINERS+=(${CONTAINER})
156 test_master $master
157done