blob: 990c8081bfe5c1fce0405d5a0a7db6c9ebb9ac5d [file] [log] [blame]
Petr Michalec1ed1b3c2017-08-08 19:19:01 +02001#!/bin/bash -e
2
3# bootstrap.sh
4
5# Installs Salt and configure minimal SaltMaster or Minion to be used with:
6# - http://github.com/salt-formulas-scripts
7# - http://github.com/salt-formulas/salt-formula-salt (salt.master sls)
8
9# TODO:
10# - use PPA repository as formula source
11# - support for spm/yum
12
13
14# Source specific env vars.
15# shopt -u dotglob
16export RECLASS_ROOT=${RECLASS_ROOT:-/srv/salt/reclass}
17function source_local_envs() {
18 for path in /tmp/kitchen /srv/salt . ${RECLASS_ROOT}/classes/cluster ${RECLASS_ROOT}/classes/cluster/${CLUSTER_NAME}; do
19 export $(find $path -maxdepth 1 -name '*.env' 2> /dev/null | xargs --no-run-if-empty cat ) > /dev/null
20 done;
21}
22source_local_envs
23
24##########################################
25# Set defaults env variables
26
27if [[ $DEBUG =~ ^(True|true|1|yes)$ ]]; then
28 set -x
29 SALT_LOG_LEVEL="--state-verbose=true -ldebug"
30fi
31
32export MAGENTA='\033[0;95m'
33export YELLOW='\033[1;33m'
34export BLUE='\033[0;35m'
35export CYAN='\033[0;96m'
36export RED='\033[0;31m'
37export NC='\033[0m' # No Color'
38
39export LC_ALL=C
40export SALT_LOG_LEVEL="--state-verbose=false -lerror"
41export SALT_OPTS="${SALT_OPTS:- --timeout=120 --state-output=changes --retcode-passthrough --force-color $SALT_LOG_LEVEL }"
42export SALT_STATE_RETRY=${SALT_STATE_RETRY:-3}
43export BOOTSTRAP_SALTSTACK=${BOOTSTRAP_SALTSTACK:-True}
44export BOOTSTRAP_SALTSTACK_OPTS=${BOOTSTRAP_SALTSTACK_OPTS:- -dX stable 2016.3 }
45
46
47# salt apt repository
48test -e /etc/lsb-release && eval $(cat /etc/lsb-release)
49which lsb_release && DISTRIB_CODENAME=${DISTRIB_CODENAME:-$(lsb_release -cs)}
50#
51export APT_REPOSITORY="deb [arch=amd64] http://apt-mk.mirantis.com/${DISTRIB_CODENAME} ${DISTRIB_REVISION:-stable} salt"
52export APT_REPOSITORY_GPG=${APT_REPOSITORY_GPG:-http://apt-mk.mirantis.com/public.gpg}
53
54# reclass
55export RECLASS_ADDRESS=${RECLASS_ADDRESS:-https://github.com/salt-formulas/openstack-salt.git} # https/git
56
57# formula
58export FORMULAS_BASE=${FORMULAS_BASE:-https://github.com/salt-formulas}
59export FORMULAS_PATH=${FORMULAS_PATH:-/usr/share/salt-formulas}
60export FORMULAS_BRANCH=${FORMULAS_BRANCH:-master}
61export FORMULAS_SOURCE=${FORMULAS_SOURCE:-pkg} # pkg/git
62# essential set of formulas (known to by used on cfg01 node for most setups)
63FORMULAS_SALT_MASTER=${FORMULAS_SALT_MASTER:- $EXTRA_FORMULAS memcached openssh ntp nginx collectd sensu heka sphinx mysql grafana libvirt rsyslog glusterfs postfix xtrabackup freeipa prometheus telegraf elasticsearch kibana rundeck devops-portal}
64# minimal set of formulas for salt-master bootstrap
65declare -a FORMULAS_SALT_MASTER=(linux reclass salt git $(echo $FORMULAS_SALT_MASTER))
66export FORMULAS_SALT_MASTER
67
68# system / host
69export HOSTNAME=${HOSTNAME:-cfg01}
70export DOMAIN=${DOMAIN:-bootstrap.local}
71
72# salt
73export SALT_MASTER=${SALT_MASTER:-127.0.0.1} # ip or fqdn
74export MINION_ID=${MINION_ID:-${HOSTNAME}.${DOMAIN}}
75
76# saltstack
77BOOTSTRAP_SALTSTACK=${BOOTSTRAP_SALTSTACK:-True}
78BOOTSTRAP_SALTSTACK_OPTS=${BOOTSTRAP_SALTSTACK_OPTS:- -dX stable 2016.3 }
79SALT_SOURCE=${SALT_SOURCE:-pkg}
80SALT_VERSION=${SALT_VERSION:-latest}
81
82# environment
83if [ "$FORMULAS_SOURCE" == "git" ]; then
84 SALT_ENV=${SALT_ENV:-dev}
85elif [ "$FORMULAS_SOURCE" == "pkg" ]; then
86 SALT_ENV=${SALT_ENV:-prd}
87fi
88eval $(cat /etc/*release 2> /dev/null)
89PLATFORM_FAMILY=$(echo ${ID_LIKE// */} | tr A-Z a-z)
90case $PLATFORM_FAMILY in
91 debian )
92 PKGTOOL="$SUDO apt-get"
93 test ${VERSION_ID//\.*/} -ge 16 && {
94 SVCTOOL=service
95 } || { SVCTOOL=service
96 }
97 ;;
98 rhel )
99 PKGTOOL="$SUDO yum"
100 test ${VERSION_ID//\.*/} -ge 7 && {
101 SVCTOOL=systemctl
102 } || { SVCTOOL=service
103 }
104 ;;
105esac
106
107export PLATFORM_FAMILY
108export PKGTOOL
109export SVCTOOL
110
111##########################################
112# FUNCTIONS
113
114log_info() {
115 echo -e "${YELLOW}[INFO] $* ${NC}"
116}
117
118log_warn() {
119 echo -e "${MAGENTA}[WARN] $* ${NC}"
120}
121
122log_err() {
123 echo -e "${RED}[ERROR] $* ${NC}" >&2
124}
125
126configure_pkg_repo()
127{
128
129 case $PLATFORM_FAMILY in
130 debian)
131 if [ -n "$APT_REPOSITORY_PPA" ]; then
132 which add-apt-repository || $SUDO apt-get install -y software-properties-common
133 $SUDO add-apt-repository -y ppa:${APT_REPOSITORY_PPA}
134 else
135 echo -e "$APT_REPOSITORY " | $SUDO tee /etc/apt/sources.list.d/bootstrap.list >/dev/null
136 curl -sL $APT_REPOSITORY_GPG | $SUDO apt-key add -
137 fi
138 $SUDO apt-get clean
139 $SUDO apt-get update
140 ;;
141 rhel)
142 $SUDO yum install -y https://repo.saltstack.com/yum/redhat/salt-repo-latest-1.el${VERSION_ID}.noarch.rpm
143 $SUDO yum clean all
144 ;;
145 esac
146
147}
148
149_atexit() {
150 RETVAL=$?
151 trap true INT TERM EXIT
152
153 if [ $RETVAL -ne 0 ]; then
154 log_err "Execution failed"
155 else
156 log_info "Execution successful"
157 fi
158 return $RETVAL
159}
160
161retry() {
162 local tries
163 if [[ $1 =~ ^[0-9]+$ ]]; then
164 tries=$1; shift
165 else
166 tries=3
167 fi
168 for i in $(seq 1 $tries); do
169 "$@" && return 0 || sleep $i
170 done
171 return 1
172}
173
174function clone_reclass() {
175 if [ ! -d ${RECLASS_ROOT} ]; then
176 # No reclass at all, clone from given address
177 ssh-keyscan -H github.com >> ~/.ssh/known_hosts || true
178 if echo ${RECLASS_BRANCH:-master} | egrep -q "^refs"; then
179 git clone ${RECLASS_ADDRESS} ${RECLASS_ROOT}
180 cd ${RECLASS_ROOT}
181 git fetch ${RECLASS_ADDRESS} ${RECLASS_BRANCH:-master} && git checkout FETCH_HEAD
182 cd -
183 else
184 git clone -b ${RECLASS_BRANCH:-master} ${RECLASS_ADDRESS} ${RECLASS_ROOT};
185 fi;
186 fi;
187}
188
189
190##########################################
191# Main calls
192
193system_config_minion() {
194 log_info "System configuration salt minion"
195}
196
197system_config_master() {
198 log_info "System configuration salt master"
199
200 # salt-formulas custom modules dependencies, etc:
201 $SUDO $PKGTOOL install -y iproute2 curl sudo apt-transport-https python-psutil python-apt python-m2crypto python-oauth python-pip &>/dev/null
202
203 $SUDO mkdir -p $RECLASS_ROOT/classes/service
204 $SUDO mkdir -p /root/.ssh
205 ssh-keyscan -H github.com >> ~/.ssh/known_hosts || true
206 echo -e "Host *\n\tStrictHostKeyChecking no\n" | $SUDO tee ~/.ssh/config >/dev/null
207 echo -e "Host *\n\tStrictHostKeyChecking no\n" | $SUDO tee /root/.ssh/config >/dev/null
208 echo "127.0.1.2 salt" | $SUDO tee -a /etc/hosts >/dev/null
209
210 which reclass || $SUDO $PKGTOOL install -y reclass
211
212 which reclass-salt || {
213 test -e /usr/share/reclass/reclass-salt && {
214 ln -fs /usr/share/reclass/reclass-salt /usr/bin
215 }
216 }
217}
218
219configure_salt_master()
220{
221
222 echo "Configuring salt-master ..."
223
224 [ ! -d /etc/salt/master.d ] && mkdir -p /etc/salt/master.d
225 cat <<-EOF > /etc/salt/master.d/master.conf
226 file_roots:
227 base:
228 - /usr/share/salt-formulas/env
229 prd:
230 - /srv/salt/env/prd
231 dev:
232 - /srv/salt/env/dev
233 pillar_opts: False
234 open_mode: True
235 reclass: &reclass
236 storage_type: yaml_fs
237 inventory_base_uri: ${RECLASS_ROOT}
238 ext_pillar:
239 - reclass: *reclass
240 master_tops:
241 reclass: *reclass
242EOF
243
244 echo "Configuring reclass ..."
245
246 [ ! -d /etc/reclass ] && mkdir /etc/reclass
247 cat <<-EOF > /etc/reclass/reclass-config.yml
248 storage_type: yaml_fs
249 pretty_print: True
250 output: yaml
251 inventory_base_uri: ${RECLASS_ROOT}
252EOF
253
254 clone_reclass
255 # override some envs from cluster level *.env, use with care
256 source_local_envs
257
258 cd ${RECLASS_ROOT}
259 if [ ! -d ${RECLASS_ROOT}/classes/system/linux ]; then
260 # Possibly subrepo checkout needed
261 git submodule update --init --recursive
262 fi
263
264 #sed -ie "s#\(reclass_data_revision.\).*#\1 $RECLASS_BRANCH#" $(find nodes -name ${MASTER_HOSTNAME}.yml|tail -n1)
265
266 mkdir -vp ${RECLASS_ROOT}/nodes
267 CONFIG=$(find ${RECLASS_ROOT}/nodes -name ${MINION_ID}.yml| grep yml | tail -n1)
268 CONFIG=${CONFIG:-${RECLASS_ROOT}/nodes/${MINION_ID}.yml}
269 if [[ $SALT_MASTER_BOOTSTRAP_MINIMIZED =~ ^(True|true|1|yes)$ || ! -f "${CONFIG}" ]]; then
270 cat <<-EOF > ${CONFIG}
271 classes:
272 - service.git.client
273 - system.linux.system.single
274 - system.salt.master.single
275 - system.salt.master.$FORMULAS_SOURCE
276 - system.reclass.storage.salt
277 parameters:
278 _param:
279 reclass_data_repository: "$RECLASS_ADDRESS"
280 reclass_data_revision: ${RECLASS_BRANCH:-master}
281 salt_formula_branch: ${SALT_FORMULAS_BRANCH:-master}
282 reclass_config_master: $SALT_MASTER
283 single_address: $SALT_MASTER
284 salt_master_host: $SALT_MASTER
285 salt_master_base_environment: $SALT_ENV
286 linux_system_codename: $DISTRIB_CODENAME
287 linux:
288 system:
289 name: $MINION_ID
290 domain: $DOMAIN
291 # ########
292EOF
293
294 if [ "$SALT_VERSION" == "latest" ]; then
295 VERSION=""
296 else
297 VERSION="version: $SALT_VERSION"
298 fi
299
300 cat <<-EOF >> ${CONFIG}
301 salt:
302 master:
303 accept_policy: open_mode
304 source:
305 engine: $SALT_SOURCE
306 $VERSION
307 minion:
308 source:
309 engine: $SALT_SOURCE
310 $VERSION
311 # ########
312 # vim: ft=yaml sw=2 ts=2 sts=2
313EOF
314 fi
315}
316
317configure_salt_minion()
318{
319 [ ! -d /etc/salt/minion.d ] && mkdir -p /etc/salt/minion.d
320 cat <<-EOF > /etc/salt/minion.d/minion.conf
321 master: $SALT_MASTER
322 id: $MINION_ID
323 EOF
324}
325
326
327install_salt_master_pkg()
328{
329 echo -e "\nPreparing base OS repository ...\n"
330
331 configure_pkg_repo
332
333 echo -e "\nInstalling salt master ...\n"
334
335 case $PLATFORM_FAMILY in
336 debian)
337 $SUDO apt-get install -y git
338 which reclass || $SUDO apt install -qqq -y reclass
339 curl -L https://bootstrap.saltstack.com | $SUDO sh -s -- -M ${BOOTSTRAP_SALTSTACK_OPTS} &>/dev/null || true
340 ;;
341 rhel)
342 yum install -y git
343 which reclass || $SUDO yum install -y reclass
344 curl -L https://bootstrap.saltstack.com | $SUDO sh -s -- -M ${BOOTSTRAP_SALTSTACK_OPTS} &>/dev/null || true
345 ;;
346 esac
347
348 which reclass-salt || {
349 test -e /usr/share/reclass/reclass-salt && {
350 ln -fs /usr/share/reclass/reclass-salt /usr/bin
351 }
352 }
353
354 configure_salt_master
355
356 echo -e "\nRestarting services ...\n"
357 [ -f /etc/salt/pki/minion/minion_master.pub ] && rm -f /etc/salt/pki/minion/minion_master.pub
358 $SVCTOOL salt-master restart
359}
360
361install_salt_master_pip()
362{
363 echo -e "\nPreparing base OS repository ...\n"
364
365 case $PLATFORM_FAMILY in
366 debian)
367 $SUDO apt-get install -y python-pip python-dev zlib1g-dev git
368 which reclass || $SUDO apt-get install -y reclass
369 ;;
370 rhel)
371 $SUDO yum install -y git
372 which reclass || $SUDO yum install -y reclass
373 ;;
374 esac
375
376 echo -e "\nInstalling salt master ...\n"
377 # TODO: replace with saltstack bootstrap script
378
379 if [ "$SALT_VERSION" == "latest" ]; then
380 pip install salt
381 else
382 pip install salt==$SALT_VERSION
383 fi
384
385 curl -Lo /etc/init.d/salt-master https://anonscm.debian.org/cgit/pkg-salt/salt.git/plain/debian/salt-master.init && chmod 755 /etc/init.d/salt-master
386 ln -s /usr/local/bin/salt-master /usr/bin/salt-master
387
388 which reclass-salt || {
389 test -e /usr/share/reclass/reclass-salt && {
390 ln -fs /usr/share/reclass/reclass-salt /usr/bin
391 }
392 }
393
394 configure_salt_master
395
396 echo -e "\nRestarting services ...\n"
397 [ -f /etc/salt/pki/minion/minion_master.pub ] && rm -f /etc/salt/pki/minion/minion_master.pub
398 $SVCTOOL salt-master restart
399}
400
401
402
403install_salt_minion_pkg()
404{
405
406 configure_pkg_repo
407
408 echo -e "\nInstalling salt minion ...\n"
409
410 case $PLATFORM_FAMILY in
411 debian)
412 curl -L https://bootstrap.saltstack.com | $SUDO sh -s -- ${BOOTSTRAP_SALTSTACK_OPTS} &>/dev/null || true
413 ;;
414 rhel)
415 curl -L https://bootstrap.saltstack.com | $SUDO sh -s -- ${BOOTSTRAP_SALTSTACK_OPTS} &>/dev/null || true
416 ;;
417 esac
418
419
420 configure_salt_minion
421
422 $SVCTOOL salt-minion restart
423}
424
425install_salt_minion_pip()
426{
427 echo -e "\nInstalling salt minion ...\n"
428
429 curl -Lo /etc/init.d/salt-minion https://anonscm.debian.org/cgit/pkg-salt/salt.git/plain/debian/salt-minion.init && chmod 755 /etc/init.d/salt-minion
430 ln -s /usr/local/bin/salt-minion /usr/bin/salt-minion
431
432 configure_salt_minion
433 $SVCTOOL salt-minion restart
434}
435
436
437install_salt_formula_pkg()
438{
439 configure_pkg_repo
440
441 case $PLATFORM_FAMILY in
442 debian)
443 echo "Configuring necessary formulas ..."
444
445 [ ! -d ${RECLASS_ROOT}/classes/service ] && mkdir -p ${RECLASS_ROOT}/classes/service
446 # Set essentials if FORMULAS_SALT_MASTER is not defined at all
447 [ -z ${FORMULAS_SALT_MASTER+x} ] && declare -a FORMULAS_SALT_MASTER=("linux" "reclass" "salt" "memcached")
448 for formula_service in "${FORMULAS_SALT_MASTER[@]}"; do
449 echo -e "\nConfiguring salt formula ${formula_service} ...\n"
450 [ ! -d "${FORMULAS_PATH}/env/${formula_service}" ] && \
451 if ! $SUDO apt-get install -y salt-formula-${formula_service}; then
452 echo -e "\nInstall salt-formula-${formula_service} failed.\n"
453 exit 1
454 fi
455 [ ! -L "${RECLASS_ROOT}/classes/service/${formula_service}" ] && \
456 ln -sf ${FORMULAS_PATH}/reclass/service/${formula_service} ${RECLASS_ROOT}/classes/service/${formula_service}
457 done
458 ;;
459 rhel)
460 # TODO
461 ;;
462 esac
463
464 [ ! -d /srv/salt/env ] && mkdir -p /srv/salt/env || echo ""
465 [ ! -L /srv/salt/env/prd ] && ln -s ${FORMULAS_PATH}/env /srv/salt/env/prd || echo ""
466}
467
468install_salt_formula_git()
469{
470 echo "Configuring necessary formulas ..."
471
472 [ ! -d ${RECLASS_ROOT}/classes/service ] && mkdir -p ${RECLASS_ROOT}/classes/service
473 # Set essentials if FORMULAS_SALT_MASTER is not defined at all
474 [ -z ${FORMULAS_SALT_MASTER+x} ] && declare -a FORMULAS_SALT_MASTER=("linux" "reclass" "salt" "memcached")
475 for formula_service in "${FORMULAS_SALT_MASTER[@]}"; do
476 echo -e "\nConfiguring salt formula ${formula_service} ...\n"
477 _BRANCH=${FORMULAS_BRANCH}
478 [ ! -d "${FORMULAS_PATH}/env/_formulas/${formula_service}" ] && {
479 if ! git ls-remote --exit-code --heads ${FORMULAS_BASE}/salt-formula-${formula_service}.git ${_BRANCH}; then
480 # Fallback to the master branch if the branch doesn't exist for this repository
481 _BRANCH=master
482 fi
483 if ! git clone ${FORMULAS_BASE}/salt-formula-${formula_service}.git ${FORMULAS_PATH}/env/_formulas/${formula_service} -b ${_BRANCH}; then
484 echo -e "\nCloning of ${FORMULAS_BASE}/salt-formula-${formula_service}.git failed.\n"
485 exit 1
486 fi
487 } || {
488 cd ${FORMULAS_PATH}/env/_formulas/${formula_service};
489 git fetch origin/${_BRANCH} || git fetch --all
490 git checkout ${_BRANCH} && git pull || git pull;
491 cd -
492 }
493 [ ! -L "/usr/share/salt-formulas/env/${formula_service}" ] && \
494 ln -sf ${FORMULAS_PATH}/env/_formulas/${formula_service}/${formula_service} /usr/share/salt-formulas/env/${formula_service}
495 [ ! -L "${RECLASS_ROOT}/classes/service/${formula_service}" ] && \
496 ln -sf ${FORMULAS_PATH}/env/_formulas/${formula_service}/metadata/service ${RECLASS_ROOT}/classes/service/${formula_service}
497 done
498
499 [ ! -d /srv/salt/env ] && mkdir -p /srv/salt/env || echo ""
500 [ ! -L /srv/salt/env/dev ] && ln -s /usr/share/salt-formulas/env /srv/salt/env/dev || echo ""
501}
502
503
504saltmaster_bootstrap() {
505
506 log_info "Salt master setup"
507 test -n "$MASTER_HOSTNAME" || exit 1
508
509 clone_reclass
510 # override some envs from cluster level *.env, use with care
511 source_local_envs
512
513 pgrep salt-master | sed /$$/d | xargs --no-run-if-empty -i{} $SUDO kill -9 {}
514 pkill -9 salt-minion
515 test -e ${SCRIPTS}/.salt-master-setup.sh.passed || {
516 export SALT_MASTER=localhost
517 export MINION_ID=${MASTER_HOSTNAME}
518 if ! [[ $DEBUG =~ ^(True|true|1|yes)$ ]]; then
519 SALT_MASTER_SETUP_OUTPUT='/dev/stdout'
520 fi
521 # call local "setup() master"
522 #if ! $SUDO ${SCRIPTS}/salt-master-setup.sh master &> ${SALT_MASTER_SETUP_OUTPUT:-/tmp/salt-master-setup.log}; then
523 if ! setup master; then
524 #cat /tmp/salt-master-setup.log
525 log_err "salt master setup() failed."
526 exit 1
527 else
528 $SUDO touch ${SCRIPTS}/.salt-master-setup.sh.passed
529 fi
530 }
531
532 log_info "Clean up generated"
533 cd $RECLASS_ROOT
534 $SUDO rm -rf $RECLASS_ROOT/nodes/_generated/*
535
536 log_info "Re/starting salt services"
537 pgrep salt-master | sed /$$/d | xargs --no-run-if-empty -i{} $SUDO kill -9 {}
538 pkill -9 salt-minion
539 sleep 1
540 $SUDO service salt-master restart
541 $SUDO service salt-minion restart
542 sleep 10
543}
544
545# Init salt master
546saltmaster_init() {
547
548 log_info "Runing saltmaster states"
549 test -n "$MASTER_HOSTNAME" || exit 1
550
551 set -e
552 $SUDO salt-call saltutil.sync_all >/dev/null
553
554 # TODO: Placeholder update saltmaster spec (nodes/FQDN.yml) to be able to bootstrap with minimal configuration
555 # (ie: with linux, git, salt formulas)
556
557 #log_info "Verify SaltMaster, before salt-master is fully initialized"
558 #if ! $SUDO reclass-salt -p ${MASTER_HOSTNAME} &> /tmp/${MASTER_HOSTNAME}.pillar;then
559 # log_warn "Node verification before initialization failed."; cat /tmp/${MASTER_HOSTNAME}.pillar;
560 #fi
561
562 log_info "State: salt.master.env"
563 if ! $SUDO salt-call ${SALT_OPTS} -linfo state.apply salt.master.env; then
564 log_err "State salt.master.env failed, keep your eyes wide open."
565 fi
566
567 log_info "State: salt.master.pillar"
568 retry ${SALT_STATE_RETRY} $SUDO salt-call ${SALT_OPTS} state.apply salt.master.pillar pillar='{"reclass":{"storage":{"data_source":{"engine":"local"}}}}'
569 # Note: sikp reclass data dir states
570 # in order to avoid pull from configured repo/branch
571
572 # Revert temporary SaltMaster minimal configuration, if any
573 pushd $RECLASS_ROOT
574 if [ $(git diff --name-only nodes | sort | uniq | wc -l) -ge 1 ]; then
575 git status || true
576 log_warn "Locally modified $RECLASS_ROOT/nodes found. (Possibly salt-master minimized setup from salt-master-setup.sh call)"
577 log_info "Checkout HEAD state of $RECLASS_ROOT/nodes/*."
578 git checkout -- $RECLASS_ROOT/nodes || true
579 log_info "Re-Run states: salt.master.env and salt.master.pillar according the HEAD state."
580 log_info "State: salt.master.env"
581 if ! $SUDO salt-call ${SALT_OPTS} -linfo state.apply salt.master.env; then
582 log_err "State salt.master.env failed, keep your eyes wide open."
583 fi
584 log_info "State: salt.master.pillar"
585 retry ${SALT_STATE_RETRY} $SUDO salt-call ${SALT_OPTS} state.apply salt.master.pillar pillar='{"reclass":{"storage":{"data_source":{"engine":"local"}}}}'
586 fi
587 popd
588
589 log_info "State: salt.master.storage.node"
590 set +e
591 $SUDO salt-call ${SALT_OPTS} state.apply reclass.storage.node
592 ret=$?
593 set -e
594
595 if [[ $ret -eq 2 ]]; then
596 log_err "State reclass.storage.node failed with exit code 2 but continuing."
597 elif [[ $ret -ne 0 ]]; then
598 log_err "State reclass.storage.node failed with exit code $ret"
599 exit 1
600 fi
601
602 log_info "Re/starting salt services"
603 $SUDO sed -i 's/^master:.*/master: localhost/' /etc/salt/minion.d/minion.conf
604 $SUDO service salt-minion restart >/dev/null
605 $SUDO salt-call ${SALT_OPTS} saltutil.sync_all >/dev/null
606
607 verify_salt_master
608 set +e
609
610}
611
612
613function verify_salt_master() {
614 set -e
615
616 log_info "Verify Salt master"
617 test -n "$MASTER_HOSTNAME" || exit 1
618
619 if [[ $VERIFY_SALT_CALL =~ ^(True|true|1|yes)$ ]]; then
620 $SUDO salt-call ${SALT_OPTS} --id=${MASTER_HOSTNAME} grains.item roles > /tmp/${MASTER_HOSTNAME}.grains.item.roles
621 $SUDO salt-call ${SALT_OPTS} --id=${MASTER_HOSTNAME} state.show_lowstate > /tmp/${MASTER_HOSTNAME}.state.show_state
622 $SUDO salt-call --no-color grains.items
623 $SUDO salt-call --no-color pillar.data
624 fi
625 if ! $SUDO reclass --nodeinfo ${MASTER_HOSTNAME} > /tmp/${MASTER_HOSTNAME}.reclass.nodeinfo; then
626 log_err "For more details see full log /tmp/${MASTER_HOSTNAME}.reclass.nodeinfo"
627 exit 1
628 fi
629}
630
631function verify_salt_minion() {
632 set -e
633 node=$1
634 log_info "Verifying ${node}"
635 if [[ $VERIFY_SALT_CALL =~ ^(True|true|1|yes)$ ]]; then
636 $SUDO salt-call ${SALT_OPTS} --id=${node} grains.item roles > /tmp/${node}.grains.item.roles
637 $SUDO salt-call ${SALT_OPTS} --id=${node} state.show_lowstate > /tmp/${node}.state.show_lowstate
638 fi
639 if ! $SUDO reclass --nodeinfo ${node} > /tmp/${node}.reclass.nodeinfo; then
640 log_err "For more details see full log /tmp/${node}.reclass.nodeinfo"
641 if [[ ${BREAK_ON_VERIFICATION_ERROR:-yes} =~ ^(True|true|1|yes)$ ]]; then
642 exit 1
643 fi
644 fi
645}
646
647function verify_salt_minions() {
648 #set -e
649 NODES=$(find $RECLASS_ROOT/nodes/ -name "*.yml" | grep -v "cfg")
650 log_info "Verifying minions: $(echo ${NODES}|xargs)"
651
652 # Parallel
653 #echo $NODES | parallel --no-notice -j 2 --halt 2 "verify_salt_minion \$(basename {} .yml) > {}.pillar_verify"
654 #ls -lrta *.pillar_verify | tail -n 1 | xargs -n1 tail -n30
655
656 function filterFails() {
657 grep -v '/grains' | tee -a $1 | tail -n20
658 }
659
660 log_info "Verify nodes"
661 passed=0
662 for node in ${NODES}; do
663 node=$(basename $node .yml)
664
665 # filter first in cluster.. ctl-01, mon-01, etc..
666 if [[ "${node//.*}" =~ 01 || "${node//.*}" =~ 02 ]] ;then
667 verify_salt_minion ${node} || continue
668 else
669 echo Skipped $node.
670 fi
671 passed=$(($passed+1))
672 done
673 # fail on failures
674 total=$(echo $NODES | xargs --no-run-if-empty -n1 echo |wc -l)
675 test ! $passed -lt $total || log_err "Results: $passed of $total passed."
676 test ! $passed -lt $total || {
677 tail -n50 /tmp/*.pillar_verify
678 return 1
679 }
680}
681
682
683
684##########################################
685# To install salt master/minon
686
687function install() {
688 setup $@
689}
690
691function setup() {
692 # CLI
693 while [ x"$1" != x"" ]; do
694 which curl &>/dev/null || $PKGTOOL -y install curl &>/dev/null
695
696 case $1 in
697 master )
698 install_salt_master_$SALT_SOURCE
699 install_salt_minion_$SALT_SOURCE
700 install_salt_formula_$FORMULAS_SOURCE
701 ;;
702 minion )
703 install_salt_minion_$SALT_SOURCE
704 ;;
705 esac
706 shift
707 done
708 echo DONE
709}
710
711function bootstrap() {
712 log_info "Bootstrap & verification of SaltMaster and configured minions."
713 trap _atexit INT TERM EXIT
714
715 system_config_master
716 saltmaster_bootstrap &&\
717 saltmaster_init &&\
718 verify_salt_minions
719}
720
721function default() {
722 bootstrap $@
723}
724
725
726##########################################
727[[ "$0" != "$BASH_SOURCE" ]] || {
728# unless file is being sourced
729 default $@
730}