Saltstack Official Home Assistant Formula
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

run_tests.sh 7.7KB

il y a 6 ans
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. #!/usr/bin/env bash
  2. ###
  3. # Script requirments:
  4. # apt-get install -y python-yaml virtualenv git
  5. set -e
  6. [ -n "$DEBUG" ] && set -x
  7. CURDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
  8. METADATA=${CURDIR}/../metadata.yml
  9. FORMULA_NAME=$(cat $METADATA | python -c "import sys,yaml; print yaml.load(sys.stdin)['name']")
  10. FORMULA_META_DIR=${CURDIR}/../${FORMULA_NAME}/meta
  11. ## Overrideable parameters
  12. PILLARDIR=${PILLARDIR:-${CURDIR}/pillar}
  13. BUILDDIR=${BUILDDIR:-${CURDIR}/build}
  14. VENV_DIR=${VENV_DIR:-${BUILDDIR}/virtualenv}
  15. MOCK_BIN_DIR=${MOCK_BIN_DIR:-${CURDIR}/mock_bin}
  16. DEPSDIR=${BUILDDIR}/deps
  17. SCHEMARDIR=${SCHEMARDIR:-"${CURDIR}/../${FORMULA_NAME}/schemas/"}
  18. SALT_FILE_DIR=${SALT_FILE_DIR:-${BUILDDIR}/file_root}
  19. SALT_PILLAR_DIR=${SALT_PILLAR_DIR:-${BUILDDIR}/pillar_root}
  20. SALT_CONFIG_DIR=${SALT_CONFIG_DIR:-${BUILDDIR}/salt}
  21. SALT_CACHE_DIR=${SALT_CACHE_DIR:-${SALT_CONFIG_DIR}/cache}
  22. SALT_CACHE_EXTMODS_DIR=${SALT_CACHE_EXTMODS_DIR:-${SALT_CONFIG_DIR}/cache_master_extmods}
  23. SALT_OPTS="${SALT_OPTS} --retcode-passthrough --local -c ${SALT_CONFIG_DIR} --log-file=/dev/null"
  24. if [ "x${SALT_VERSION}" != "x" ]; then
  25. PIP_SALT_VERSION="==${SALT_VERSION}"
  26. fi
  27. ## Functions
  28. log_info() {
  29. echo -e "[INFO] $*"
  30. }
  31. log_err() {
  32. echo -e "[ERROR] $*" >&2
  33. }
  34. setup_virtualenv() {
  35. log_info "Setting up Python virtualenv"
  36. virtualenv $VENV_DIR
  37. source ${VENV_DIR}/bin/activate
  38. pip install salt${PIP_SALT_VERSION}
  39. if [[ -f ${CURDIR}/pip_requirements.txt ]]; then
  40. pip install -r ${CURDIR}/pip_requirements.txt
  41. fi
  42. }
  43. setup_mock_bin() {
  44. # If some state requires a binary, a lightweight replacement for
  45. # such binary can be put into MOCK_BIN_DIR for test purposes
  46. if [ -d "${MOCK_BIN_DIR}" ]; then
  47. PATH="${MOCK_BIN_DIR}:$PATH"
  48. export PATH
  49. fi
  50. }
  51. setup_pillar() {
  52. [ ! -d ${SALT_PILLAR_DIR} ] && mkdir -p ${SALT_PILLAR_DIR}
  53. echo "base:" > ${SALT_PILLAR_DIR}/top.sls
  54. for pillar in ${PILLARDIR}/*; do
  55. grep ${FORMULA_NAME}: ${pillar} &>/dev/null || continue
  56. state_name=$(basename ${pillar%.sls})
  57. echo -e " ${state_name}:\n - ${state_name}" >> ${SALT_PILLAR_DIR}/top.sls
  58. done
  59. }
  60. setup_salt() {
  61. [ ! -d ${SALT_FILE_DIR} ] && mkdir -p ${SALT_FILE_DIR}
  62. [ ! -d ${SALT_CONFIG_DIR} ] && mkdir -p ${SALT_CONFIG_DIR}
  63. [ ! -d ${SALT_CACHE_DIR} ] && mkdir -p ${SALT_CACHE_DIR}
  64. [ ! -d ${SALT_CACHE_EXTMODS_DIR} ] && mkdir -p ${SALT_CACHE_EXTMODS_DIR}
  65. echo "base:" > ${SALT_FILE_DIR}/top.sls
  66. for pillar in ${PILLARDIR}/*.sls; do
  67. grep ${FORMULA_NAME}: ${pillar} &>/dev/null || continue
  68. state_name=$(basename ${pillar%.sls})
  69. echo -e " ${state_name}:\n - ${FORMULA_NAME}" >> ${SALT_FILE_DIR}/top.sls
  70. done
  71. cat << EOF > ${SALT_CONFIG_DIR}/minion
  72. file_client: local
  73. cachedir: ${SALT_CACHE_DIR}
  74. extension_modules: ${SALT_CACHE_EXTMODS_DIR}
  75. verify_env: False
  76. minion_id_caching: False
  77. file_roots:
  78. base:
  79. - ${SALT_FILE_DIR}
  80. - ${CURDIR}/..
  81. pillar_roots:
  82. base:
  83. - ${SALT_PILLAR_DIR}
  84. - ${PILLARDIR}
  85. EOF
  86. }
  87. fetch_dependency() {
  88. # example: fetch_dependency "linux:https://github.com/salt-formulas/salt-formula-linux"
  89. dep_name="$(echo $1|cut -d : -f 1)"
  90. dep_source="$(echo $1|cut -d : -f 2-)"
  91. dep_root="${DEPSDIR}/$(basename $dep_source .git)"
  92. dep_metadata="${dep_root}/metadata.yml"
  93. [ -d $dep_root ] && { log_info "Dependency $dep_name already fetched"; return 0; }
  94. log_info "Fetching dependency $dep_name"
  95. [ ! -d ${DEPSDIR} ] && mkdir -p ${DEPSDIR}
  96. git clone $dep_source ${DEPSDIR}/$(basename $dep_source .git)
  97. ln -s ${dep_root}/${dep_name} ${SALT_FILE_DIR}/${dep_name}
  98. METADATA="${dep_metadata}" install_dependencies
  99. }
  100. link_modules(){
  101. # Link modules *.py files to temporary salt-root
  102. local SALT_ROOT=${1:-$SALT_FILE_DIR}
  103. local SALT_ENV=${2:-$DEPSDIR}
  104. mkdir -p "${SALT_ROOT}/_modules/"
  105. # from git, development versions
  106. find ${SALT_ENV} -maxdepth 3 -mindepth 3 -path '*_modules*' -iname "*.py" -type f -print0 | while read -d $'\0' file; do
  107. ln -fs $(readlink -e ${file}) "$SALT_ROOT"/_modules/$(basename ${file}) ;
  108. done
  109. salt_run saltutil.sync_all
  110. }
  111. install_dependencies() {
  112. grep -E "^dependencies:" ${METADATA} >/dev/null || return 0
  113. (python - | while read dep; do fetch_dependency "$dep"; done) << EOF
  114. import sys,yaml
  115. for dep in yaml.load(open('${METADATA}', 'ro'))['dependencies']:
  116. print '%s:%s' % (dep["name"], dep["source"])
  117. EOF
  118. }
  119. clean() {
  120. log_info "Cleaning up ${BUILDDIR}"
  121. [ -d ${BUILDDIR} ] && rm -rf ${BUILDDIR} || exit 0
  122. }
  123. salt_run() {
  124. [ -e ${VENV_DIR}/bin/activate ] && source ${VENV_DIR}/bin/activate
  125. salt-call ${SALT_OPTS} $*
  126. }
  127. prepare() {
  128. [ -d ${BUILDDIR} ] && mkdir -p ${BUILDDIR}
  129. [[ ! -f "${VENV_DIR}/bin/activate" ]] && setup_virtualenv
  130. setup_mock_bin
  131. setup_pillar
  132. setup_salt
  133. install_dependencies
  134. }
  135. lint_releasenotes() {
  136. [[ ! -f "${VENV_DIR}/bin/activate" ]] && setup_virtualenv
  137. source ${VENV_DIR}/bin/activate
  138. pip install reno
  139. reno lint ${CURDIR}/../
  140. }
  141. lint() {
  142. # lint_releasenotes
  143. log_err "TODO: lint_releasenotes"
  144. }
  145. run() {
  146. for pillar in ${PILLARDIR}/*.sls; do
  147. grep ${FORMULA_NAME}: ${pillar} &>/dev/null || continue
  148. state_name=$(basename ${pillar%.sls})
  149. salt_run grains.set 'noservices' False force=True
  150. echo "Checking state ${FORMULA_NAME}.${state_name} ..."
  151. salt_run --id=${state_name} state.show_sls ${FORMULA_NAME} || (log_err "Execution of ${FORMULA_NAME}.${state_name} failed"; exit 1)
  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. real_run() {
  163. for pillar in ${PILLARDIR}/*.sls; do
  164. state_name=$(basename ${pillar%.sls})
  165. salt_run --id=${state_name} state.sls ${FORMULA_NAME} || { log_err "Execution of ${FORMULA_NAME}.${state_name} failed"; exit 1; }
  166. done
  167. }
  168. run_model_validate(){
  169. [[ -d ${SCHEMARDIR} ]] || { log_err "${SCHEMARDIR} not found!"; return 1; }
  170. # model validator require py modules
  171. fetch_dependency "salt:https://github.com/salt-formulas/salt-formula-salt"
  172. link_modules
  173. # Rendered Example:
  174. # salt-call --local -c /test1/maas/tests/build/salt --id=maas_cluster modelschema.model_validate maas cluster
  175. for role in ${SCHEMARDIR}/*.yaml; do
  176. state_name=$(basename "${role%*.yaml}")
  177. minion_id="${state_name}"
  178. # in case debug-reruns, usefull to make cleanup
  179. [ -n "$DEBUG" ] && { salt_run saltutil.clear_cache; salt_run saltutil.refresh_pillar; salt_run saltutil.sync_all; }
  180. salt_run -m ${DEPSDIR}/salt-formula-salt --id=${minion_id} modelschema.model_validate ${FORMULA_NAME} ${state_name} || { log_err "Execution of ${FORMULA_NAME}.${state_name} failed"; exit 1 ; }
  181. done
  182. }
  183. _atexit() {
  184. RETVAL=$?
  185. trap true INT TERM EXIT
  186. if [ $RETVAL -ne 0 ]; then
  187. log_err "Execution failed"
  188. else
  189. log_info "Execution successful"
  190. fi
  191. return $RETVAL
  192. }
  193. ## Main
  194. trap _atexit INT TERM EXIT
  195. case $1 in
  196. clean)
  197. clean
  198. ;;
  199. prepare)
  200. prepare
  201. ;;
  202. lint)
  203. lint
  204. ;;
  205. run)
  206. run
  207. ;;
  208. real-run)
  209. real_run
  210. ;;
  211. model-validate)
  212. prepare
  213. run_model_validate
  214. ;;
  215. *)
  216. prepare
  217. # lint
  218. run
  219. run_model_validate
  220. ;;
  221. esac