blob: 8f37b0cc3771d657486a64e4e0035ffd0cbcf52a [file] [log] [blame]
Jakub Pavlikffb8d482016-01-25 23:06:01 +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 Dmitriev3a1cbfa2017-07-06 21:07:27 +03009FORMULA_META_DIR=${CURDIR}/../${FORMULA_NAME}/meta
Jakub Pavlikffb8d482016-01-25 23:06:01 +010010
11## Overrideable parameters
12PILLARDIR=${PILLARDIR:-${CURDIR}/pillar}
13BUILDDIR=${BUILDDIR:-${CURDIR}/build}
14VENV_DIR=${VENV_DIR:-${BUILDDIR}/virtualenv}
Dennis Dmitriev3a1cbfa2017-07-06 21:07:27 +030015MOCK_BIN_DIR=${MOCK_BIN_DIR:-${CURDIR}/mock_bin}
Jakub Pavlikffb8d482016-01-25 23:06:01 +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 Dmitriev3a1cbfa2017-07-06 21:07:27 +030023SALT_OPTS="${SALT_OPTS} --retcode-passthrough --local -c ${SALT_CONFIG_DIR} --log-file=/dev/null"
Jakub Pavlikffb8d482016-01-25 23:06:01 +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
Michal Kobus66360272020-08-19 14:52:23 +020042 pip install -r test-requirements.txt
43 pip install salt${PIP_SALT_VERSION}
Jakub Pavlikffb8d482016-01-25 23:06:01 +010044}
45
Dennis Dmitriev3a1cbfa2017-07-06 21:07:27 +030046setup_mock_bin() {
47 # If some state requires a binary, a lightweight replacement for
48 # such binary can be put into MOCK_BIN_DIR for test purposes
49 if [ -d "${MOCK_BIN_DIR}" ]; then
50 PATH="${MOCK_BIN_DIR}:$PATH"
51 export PATH
52 fi
53}
54
Jakub Pavlikffb8d482016-01-25 23:06:01 +010055setup_pillar() {
56 [ ! -d ${SALT_PILLAR_DIR} ] && mkdir -p ${SALT_PILLAR_DIR}
57 echo "base:" > ${SALT_PILLAR_DIR}/top.sls
58 for pillar in ${PILLARDIR}/*; do
Dennis Dmitriev3a1cbfa2017-07-06 21:07:27 +030059 grep ${FORMULA_NAME}: ${pillar} &>/dev/null || continue
Jakub Pavlikffb8d482016-01-25 23:06:01 +010060 state_name=$(basename ${pillar%.sls})
61 echo -e " ${state_name}:\n - ${state_name}" >> ${SALT_PILLAR_DIR}/top.sls
62 done
63}
64
65setup_salt() {
66 [ ! -d ${SALT_FILE_DIR} ] && mkdir -p ${SALT_FILE_DIR}
67 [ ! -d ${SALT_CONFIG_DIR} ] && mkdir -p ${SALT_CONFIG_DIR}
68 [ ! -d ${SALT_CACHE_DIR} ] && mkdir -p ${SALT_CACHE_DIR}
69
70 echo "base:" > ${SALT_FILE_DIR}/top.sls
71 for pillar in ${PILLARDIR}/*.sls; do
Dennis Dmitriev3a1cbfa2017-07-06 21:07:27 +030072 grep ${FORMULA_NAME}: ${pillar} &>/dev/null || continue
Jakub Pavlikffb8d482016-01-25 23:06:01 +010073 state_name=$(basename ${pillar%.sls})
74 echo -e " ${state_name}:\n - ${FORMULA_NAME}" >> ${SALT_FILE_DIR}/top.sls
75 done
76
77 cat << EOF > ${SALT_CONFIG_DIR}/minion
78file_client: local
79cachedir: ${SALT_CACHE_DIR}
80verify_env: False
Dennis Dmitriev3a1cbfa2017-07-06 21:07:27 +030081minion_id_caching: False
Jakub Pavlikffb8d482016-01-25 23:06:01 +010082
83file_roots:
84 base:
85 - ${SALT_FILE_DIR}
86 - ${CURDIR}/..
Filip Pytloun10590692016-04-14 11:51:09 +020087 - /usr/share/salt-formulas/env
Jakub Pavlikffb8d482016-01-25 23:06:01 +010088
89pillar_roots:
90 base:
91 - ${SALT_PILLAR_DIR}
92 - ${PILLARDIR}
93EOF
94}
95
96fetch_dependency() {
Filip Pytloun10590692016-04-14 11:51:09 +020097 dep_name="$(echo $1|cut -d : -f 1)"
Filip Pytloun11926632016-04-14 16:39:00 +020098 dep_source="$(echo $1|cut -d : -f 2-)"
Filip Pytloun10590692016-04-14 11:51:09 +020099 dep_root="${DEPSDIR}/$(basename $dep_source .git)"
Jakub Pavlikffb8d482016-01-25 23:06:01 +0100100 dep_metadata="${dep_root}/metadata.yml"
101
Filip Pytloun10590692016-04-14 11:51:09 +0200102 [ -d /usr/share/salt-formulas/env/${dep_name} ] && log_info "Dependency $dep_name already present in system-wide salt env" && return 0
103 [ -d $dep_root ] && log_info "Dependency $dep_name already fetched" && return 0
Jakub Pavlikffb8d482016-01-25 23:06:01 +0100104
Filip Pytloun10590692016-04-14 11:51:09 +0200105 log_info "Fetching dependency $dep_name"
Jakub Pavlikffb8d482016-01-25 23:06:01 +0100106 [ ! -d ${DEPSDIR} ] && mkdir -p ${DEPSDIR}
Filip Pytloun49b9c492016-04-14 12:46:30 +0200107 git clone $dep_source ${DEPSDIR}/$(basename $dep_source .git)
Jakub Pavlikffb8d482016-01-25 23:06:01 +0100108 ln -s ${dep_root}/${dep_name} ${SALT_FILE_DIR}/${dep_name}
109
110 METADATA="${dep_metadata}" install_dependencies
111}
112
113install_dependencies() {
114 grep -E "^dependencies:" ${METADATA} >/dev/null || return 0
115 (python - | while read dep; do fetch_dependency "$dep"; done) << EOF
116import sys,yaml
117for dep in yaml.load(open('${METADATA}', 'ro'))['dependencies']:
Filip Pytloun10590692016-04-14 11:51:09 +0200118 print '%s:%s' % (dep["name"], dep["source"])
Jakub Pavlikffb8d482016-01-25 23:06:01 +0100119EOF
120}
121
122clean() {
123 log_info "Cleaning up ${BUILDDIR}"
124 [ -d ${BUILDDIR} ] && rm -rf ${BUILDDIR} || exit 0
125}
126
127salt_run() {
Jakub Josef7a729492017-12-15 16:58:29 +0100128 [ -e ${VENV_DIR}/bin/activate ] && source ${VENV_DIR}/bin/activate
Jakub Josefdf46f592018-02-08 13:22:15 +0100129 python $(which salt-call) ${SALT_OPTS} $*
Jakub Pavlikffb8d482016-01-25 23:06:01 +0100130}
131
132prepare() {
133 [ -d ${BUILDDIR} ] && mkdir -p ${BUILDDIR}
134
Filip Pytloun10590692016-04-14 11:51:09 +0200135 which salt-call || setup_virtualenv
Dennis Dmitriev3a1cbfa2017-07-06 21:07:27 +0300136 setup_mock_bin
Jakub Pavlikffb8d482016-01-25 23:06:01 +0100137 setup_pillar
138 setup_salt
139 install_dependencies
140}
141
142run() {
chnydab9971f72017-10-24 16:09:07 +0200143 salt_run grains.append 'ipv4' '0.0.0.0'
Jakub Pavlikffb8d482016-01-25 23:06:01 +0100144 for pillar in ${PILLARDIR}/*.sls; do
Dennis Dmitriev3a1cbfa2017-07-06 21:07:27 +0300145 grep ${FORMULA_NAME}: ${pillar} &>/dev/null || continue
Jakub Pavlikffb8d482016-01-25 23:06:01 +0100146 state_name=$(basename ${pillar%.sls})
Dennis Dmitriev3a1cbfa2017-07-06 21:07:27 +0300147 salt_run grains.set 'noservices' False force=True
148
149 echo "Checking state ${FORMULA_NAME}.${state_name} ..."
Jakub Pavlikffb8d482016-01-25 23:06:01 +0100150 salt_run --id=${state_name} state.show_sls ${FORMULA_NAME} || (log_err "Execution of ${FORMULA_NAME}.${state_name} failed"; exit 1)
Dennis Dmitriev3a1cbfa2017-07-06 21:07:27 +0300151
152 # Check that all files in 'meta' folder can be rendered using any valid pillar
153 for meta in `find ${FORMULA_META_DIR} -type f`; do
154 meta_name=$(basename ${meta})
155 echo "Checking meta ${meta_name} ..."
156 salt_run --out=quiet --id=${state_name} cp.get_template ${meta} ${SALT_CACHE_DIR}/${meta_name} \
157 || (log_err "Failed to render meta ${meta} using pillar ${FORMULA_NAME}.${state_name}"; exit 1)
158 cat ${SALT_CACHE_DIR}/${meta_name}
159 done
160 done
161}
162
163real_run() {
164 for pillar in ${PILLARDIR}/*.sls; do
165 state_name=$(basename ${pillar%.sls})
166 salt_run --id=${state_name} state.sls ${FORMULA_NAME} || (log_err "Execution of ${FORMULA_NAME}.${state_name} failed"; exit 1)
Jakub Pavlikffb8d482016-01-25 23:06:01 +0100167 done
168}
169
170_atexit() {
171 RETVAL=$?
172 trap true INT TERM EXIT
173
174 if [ $RETVAL -ne 0 ]; then
175 log_err "Execution failed"
176 else
177 log_info "Execution successful"
178 fi
179 return $RETVAL
180}
181
182## Main
183trap _atexit INT TERM EXIT
184
185case $1 in
186 clean)
187 clean
188 ;;
189 prepare)
190 prepare
191 ;;
192 run)
193 run
194 ;;
Dennis Dmitriev3a1cbfa2017-07-06 21:07:27 +0300195 real-run)
196 real_run
197 ;;
Jakub Pavlikffb8d482016-01-25 23:06:01 +0100198 *)
199 prepare
200 run
201 ;;
202esac