blob: 976158582d91be1e42605aef36c41fc38dc06dcf [file] [log] [blame]
jan kaufman0648db72016-01-26 11:34:37 +01001#!/usr/bin/env bash
2
3set -e
4[ -n "$DEBUG" ] && set -x
5
6CURDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
7METADATA=${CURDIR}/../metadata.yml
8FORMULA_NAME=$(cat $METADATA | python -c "import sys,yaml; print yaml.load(sys.stdin)['name']")
Dennis Dmitrievba33a7e2017-07-06 21:07:27 +03009FORMULA_META_DIR=${CURDIR}/../${FORMULA_NAME}/meta
jan kaufman0648db72016-01-26 11:34:37 +010010
11## Overrideable parameters
12PILLARDIR=${PILLARDIR:-${CURDIR}/pillar}
13BUILDDIR=${BUILDDIR:-${CURDIR}/build}
14VENV_DIR=${VENV_DIR:-${BUILDDIR}/virtualenv}
Dennis Dmitrievba33a7e2017-07-06 21:07:27 +030015MOCK_BIN_DIR=${MOCK_BIN_DIR:-${CURDIR}/mock_bin}
jan kaufman0648db72016-01-26 11:34:37 +010016DEPSDIR=${BUILDDIR}/deps
17
18SALT_FILE_DIR=${SALT_FILE_DIR:-${BUILDDIR}/file_root}
19SALT_PILLAR_DIR=${SALT_PILLAR_DIR:-${BUILDDIR}/pillar_root}
20SALT_CONFIG_DIR=${SALT_CONFIG_DIR:-${BUILDDIR}/salt}
21SALT_CACHE_DIR=${SALT_CACHE_DIR:-${SALT_CONFIG_DIR}/cache}
22
Dennis Dmitrievba33a7e2017-07-06 21:07:27 +030023SALT_OPTS="${SALT_OPTS} --retcode-passthrough --local -c ${SALT_CONFIG_DIR} --log-file=/dev/null"
jan kaufman0648db72016-01-26 11:34:37 +010024
25if [ "x${SALT_VERSION}" != "x" ]; then
26 PIP_SALT_VERSION="==${SALT_VERSION}"
27fi
28
29## Functions
30log_info() {
31 echo "[INFO] $*"
32}
33
34log_err() {
35 echo "[ERROR] $*" >&2
36}
37
38setup_virtualenv() {
39 log_info "Setting up Python virtualenv"
40 virtualenv $VENV_DIR
41 source ${VENV_DIR}/bin/activate
Jakub Josefd1e9ae82018-02-08 13:22:16 +010042 python -m pip install salt${PIP_SALT_VERSION}
jan kaufman0648db72016-01-26 11:34:37 +010043}
44
Dennis Dmitrievba33a7e2017-07-06 21:07:27 +030045setup_mock_bin() {
46 # If some state requires a binary, a lightweight replacement for
47 # such binary can be put into MOCK_BIN_DIR for test purposes
48 if [ -d "${MOCK_BIN_DIR}" ]; then
49 PATH="${MOCK_BIN_DIR}:$PATH"
50 export PATH
51 fi
52}
53
jan kaufman0648db72016-01-26 11:34:37 +010054setup_pillar() {
55 [ ! -d ${SALT_PILLAR_DIR} ] && mkdir -p ${SALT_PILLAR_DIR}
56 echo "base:" > ${SALT_PILLAR_DIR}/top.sls
57 for pillar in ${PILLARDIR}/*; do
Dennis Dmitrievba33a7e2017-07-06 21:07:27 +030058 grep ${FORMULA_NAME}: ${pillar} &>/dev/null || continue
jan kaufman0648db72016-01-26 11:34:37 +010059 state_name=$(basename ${pillar%.sls})
60 echo -e " ${state_name}:\n - ${state_name}" >> ${SALT_PILLAR_DIR}/top.sls
61 done
62}
63
64setup_salt() {
65 [ ! -d ${SALT_FILE_DIR} ] && mkdir -p ${SALT_FILE_DIR}
66 [ ! -d ${SALT_CONFIG_DIR} ] && mkdir -p ${SALT_CONFIG_DIR}
67 [ ! -d ${SALT_CACHE_DIR} ] && mkdir -p ${SALT_CACHE_DIR}
68
69 echo "base:" > ${SALT_FILE_DIR}/top.sls
70 for pillar in ${PILLARDIR}/*.sls; do
Dennis Dmitrievba33a7e2017-07-06 21:07:27 +030071 grep ${FORMULA_NAME}: ${pillar} &>/dev/null || continue
jan kaufman0648db72016-01-26 11:34:37 +010072 state_name=$(basename ${pillar%.sls})
73 echo -e " ${state_name}:\n - ${FORMULA_NAME}" >> ${SALT_FILE_DIR}/top.sls
74 done
75
76 cat << EOF > ${SALT_CONFIG_DIR}/minion
77file_client: local
78cachedir: ${SALT_CACHE_DIR}
79verify_env: False
Dennis Dmitrievba33a7e2017-07-06 21:07:27 +030080minion_id_caching: False
jan kaufman0648db72016-01-26 11:34:37 +010081
82file_roots:
83 base:
84 - ${SALT_FILE_DIR}
85 - ${CURDIR}/..
Filip Pytloun9154b6b2016-04-14 11:51:09 +020086 - /usr/share/salt-formulas/env
jan kaufman0648db72016-01-26 11:34:37 +010087
88pillar_roots:
89 base:
90 - ${SALT_PILLAR_DIR}
91 - ${PILLARDIR}
92EOF
93}
94
95fetch_dependency() {
Filip Pytloun9154b6b2016-04-14 11:51:09 +020096 dep_name="$(echo $1|cut -d : -f 1)"
Filip Pytlounb76b4112016-04-14 16:39:07 +020097 dep_source="$(echo $1|cut -d : -f 2-)"
Filip Pytloun9154b6b2016-04-14 11:51:09 +020098 dep_root="${DEPSDIR}/$(basename $dep_source .git)"
jan kaufman0648db72016-01-26 11:34:37 +010099 dep_metadata="${dep_root}/metadata.yml"
100
Filip Pytloun9154b6b2016-04-14 11:51:09 +0200101 [ -d /usr/share/salt-formulas/env/${dep_name} ] && log_info "Dependency $dep_name already present in system-wide salt env" && return 0
102 [ -d $dep_root ] && log_info "Dependency $dep_name already fetched" && return 0
jan kaufman0648db72016-01-26 11:34:37 +0100103
Filip Pytloun9154b6b2016-04-14 11:51:09 +0200104 log_info "Fetching dependency $dep_name"
jan kaufman0648db72016-01-26 11:34:37 +0100105 [ ! -d ${DEPSDIR} ] && mkdir -p ${DEPSDIR}
Filip Pytloun1915fd02016-04-14 12:46:30 +0200106 git clone $dep_source ${DEPSDIR}/$(basename $dep_source .git)
jan kaufman0648db72016-01-26 11:34:37 +0100107 ln -s ${dep_root}/${dep_name} ${SALT_FILE_DIR}/${dep_name}
108
109 METADATA="${dep_metadata}" install_dependencies
110}
111
112install_dependencies() {
113 grep -E "^dependencies:" ${METADATA} >/dev/null || return 0
114 (python - | while read dep; do fetch_dependency "$dep"; done) << EOF
115import sys,yaml
116for dep in yaml.load(open('${METADATA}', 'ro'))['dependencies']:
Filip Pytloun9154b6b2016-04-14 11:51:09 +0200117 print '%s:%s' % (dep["name"], dep["source"])
jan kaufman0648db72016-01-26 11:34:37 +0100118EOF
119}
120
121clean() {
122 log_info "Cleaning up ${BUILDDIR}"
123 [ -d ${BUILDDIR} ] && rm -rf ${BUILDDIR} || exit 0
124}
125
126salt_run() {
Jakub Josef8227efb2017-12-15 16:58:29 +0100127 [ -e ${VENV_DIR}/bin/activate ] && source ${VENV_DIR}/bin/activate
Jakub Josefd1e9ae82018-02-08 13:22:16 +0100128 python $(which salt-call) ${SALT_OPTS} $*
jan kaufman0648db72016-01-26 11:34:37 +0100129}
130
131prepare() {
132 [ -d ${BUILDDIR} ] && mkdir -p ${BUILDDIR}
133
Filip Pytloun9154b6b2016-04-14 11:51:09 +0200134 which salt-call || setup_virtualenv
Dennis Dmitrievba33a7e2017-07-06 21:07:27 +0300135 setup_mock_bin
jan kaufman0648db72016-01-26 11:34:37 +0100136 setup_pillar
137 setup_salt
138 install_dependencies
139}
140
141run() {
142 for pillar in ${PILLARDIR}/*.sls; do
Dennis Dmitrievba33a7e2017-07-06 21:07:27 +0300143 grep ${FORMULA_NAME}: ${pillar} &>/dev/null || continue
jan kaufman0648db72016-01-26 11:34:37 +0100144 state_name=$(basename ${pillar%.sls})
Dennis Dmitrievba33a7e2017-07-06 21:07:27 +0300145 salt_run grains.set 'noservices' False force=True
146
147 echo "Checking state ${FORMULA_NAME}.${state_name} ..."
jan kaufman0648db72016-01-26 11:34:37 +0100148 salt_run --id=${state_name} state.show_sls ${FORMULA_NAME} || (log_err "Execution of ${FORMULA_NAME}.${state_name} failed"; exit 1)
Dennis Dmitrievba33a7e2017-07-06 21:07:27 +0300149
150 # Check that all files in 'meta' folder can be rendered using any valid pillar
151 for meta in `find ${FORMULA_META_DIR} -type f`; do
152 meta_name=$(basename ${meta})
153 echo "Checking meta ${meta_name} ..."
154 salt_run --out=quiet --id=${state_name} cp.get_template ${meta} ${SALT_CACHE_DIR}/${meta_name} \
155 || (log_err "Failed to render meta ${meta} using pillar ${FORMULA_NAME}.${state_name}"; exit 1)
156 cat ${SALT_CACHE_DIR}/${meta_name}
157 done
158 done
159}
160
161real_run() {
162 for pillar in ${PILLARDIR}/*.sls; do
163 state_name=$(basename ${pillar%.sls})
164 salt_run --id=${state_name} state.sls ${FORMULA_NAME} || (log_err "Execution of ${FORMULA_NAME}.${state_name} failed"; exit 1)
jan kaufman0648db72016-01-26 11:34:37 +0100165 done
166}
167
168_atexit() {
169 RETVAL=$?
170 trap true INT TERM EXIT
171
172 if [ $RETVAL -ne 0 ]; then
173 log_err "Execution failed"
174 else
175 log_info "Execution successful"
176 fi
177 return $RETVAL
178}
179
180## Main
181trap _atexit INT TERM EXIT
182
183case $1 in
184 clean)
185 clean
186 ;;
187 prepare)
188 prepare
189 ;;
190 run)
191 run
192 ;;
Dennis Dmitrievba33a7e2017-07-06 21:07:27 +0300193 real-run)
194 real_run
195 ;;
jan kaufman0648db72016-01-26 11:34:37 +0100196 *)
197 prepare
198 run
199 ;;
200esac