Saltstack Official Linux Formula
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

run_tests.sh 8.9KB

9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
9年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. #!/usr/bin/env bash
  2. ###
  3. # Script requirments:
  4. #apt-get install -y python-yaml virtualenv git
  5. __ScriptVersion="2018.08.16"
  6. __ScriptName="run_tests.sh"
  7. __ScriptFullName="$0"
  8. __ScriptArgs="$*"
  9. set -e
  10. [ -n "$DEBUG" ] && set -x
  11. CURDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
  12. METADATA=${CURDIR}/../metadata.yml
  13. FORMULA_NAME=$(cat $METADATA | python -c "import sys,yaml; print yaml.load(sys.stdin)['name']")
  14. FORMULA_META_DIR=${CURDIR}/../${FORMULA_NAME}/meta
  15. ## Overrideable parameters
  16. PILLARDIR=${PILLARDIR:-${CURDIR}/pillar}
  17. BUILDDIR=${BUILDDIR:-${CURDIR}/build}
  18. VENV_DIR=${VENV_DIR:-${BUILDDIR}/virtualenv}
  19. MOCK_BIN_DIR=${MOCK_BIN_DIR:-${CURDIR}/mock_bin}
  20. DEPSDIR=${BUILDDIR}/deps
  21. SCHEMARDIR=${SCHEMARDIR:-"${CURDIR}/../${FORMULA_NAME}/schemas/"}
  22. SALT_FILE_DIR=${SALT_FILE_DIR:-${BUILDDIR}/file_root}
  23. SALT_PILLAR_DIR=${SALT_PILLAR_DIR:-${BUILDDIR}/pillar_root}
  24. SALT_CONFIG_DIR=${SALT_CONFIG_DIR:-${BUILDDIR}/salt}
  25. SALT_CACHE_DIR=${SALT_CACHE_DIR:-${SALT_CONFIG_DIR}/cache}
  26. SALT_CACHE_EXTMODS_DIR=${SALT_CACHE_EXTMODS_DIR:-${SALT_CONFIG_DIR}/cache_master_extmods}
  27. SALT_OPTS="${SALT_OPTS} --retcode-passthrough --local -c ${SALT_CONFIG_DIR} --log-file=/dev/null"
  28. IGNORE_MODELVALIDATE_MASK=${IGNORE_MODELVALIDATE_MASK:-"novalidate"}
  29. if [ "x${SALT_VERSION}" != "x" ]; then
  30. PIP_SALT_VERSION="==${SALT_VERSION}"
  31. fi
  32. ## Functions
  33. log_info() {
  34. echo -e "[INFO] $*"
  35. }
  36. log_err() {
  37. echo -e "[ERROR] $*" >&2
  38. }
  39. setup_virtualenv() {
  40. log_info "Setting up Python virtualenv"
  41. dependency_check virtualenv
  42. virtualenv $VENV_DIR
  43. source ${VENV_DIR}/bin/activate
  44. python -m pip install salt${PIP_SALT_VERSION}
  45. if [[ -f ${CURDIR}/test-requirements.txt ]]; then
  46. python -m pip install -r ${CURDIR}/test-requirements.txt
  47. fi
  48. }
  49. setup_mock_bin() {
  50. # If some state requires a binary, a lightweight replacement for
  51. # such binary can be put into MOCK_BIN_DIR for test purposes
  52. if [ -d "${MOCK_BIN_DIR}" ]; then
  53. PATH="${MOCK_BIN_DIR}:$PATH"
  54. export PATH
  55. fi
  56. }
  57. setup_pillar() {
  58. [ ! -d ${SALT_PILLAR_DIR} ] && mkdir -p ${SALT_PILLAR_DIR}
  59. echo "base:" > ${SALT_PILLAR_DIR}/top.sls
  60. for pillar in ${PILLARDIR}/*; do
  61. grep ${FORMULA_NAME}: ${pillar} &>/dev/null || continue
  62. state_name=$(basename ${pillar%.sls})
  63. echo -e " ${state_name}:\n - ${state_name}" >> ${SALT_PILLAR_DIR}/top.sls
  64. done
  65. }
  66. setup_salt() {
  67. [ ! -d ${SALT_FILE_DIR} ] && mkdir -p ${SALT_FILE_DIR}
  68. [ ! -d ${SALT_CONFIG_DIR} ] && mkdir -p ${SALT_CONFIG_DIR}
  69. [ ! -d ${SALT_CACHE_DIR} ] && mkdir -p ${SALT_CACHE_DIR}
  70. [ ! -d ${SALT_CACHE_EXTMODS_DIR} ] && mkdir -p ${SALT_CACHE_EXTMODS_DIR}
  71. echo "base:" > ${SALT_FILE_DIR}/top.sls
  72. for pillar in ${PILLARDIR}/*.sls; do
  73. grep ${FORMULA_NAME}: ${pillar} &>/dev/null || continue
  74. state_name=$(basename ${pillar%.sls})
  75. echo -e " ${state_name}:\n - ${FORMULA_NAME}" >> ${SALT_FILE_DIR}/top.sls
  76. done
  77. cat << EOF > ${SALT_CONFIG_DIR}/minion
  78. file_client: local
  79. cachedir: ${SALT_CACHE_DIR}
  80. extension_modules: ${SALT_CACHE_EXTMODS_DIR}
  81. verify_env: False
  82. minion_id_caching: False
  83. file_roots:
  84. base:
  85. - ${SALT_FILE_DIR}
  86. - ${CURDIR}/..
  87. pillar_roots:
  88. base:
  89. - ${SALT_PILLAR_DIR}
  90. - ${PILLARDIR}
  91. EOF
  92. }
  93. fetch_dependency() {
  94. # example: fetch_dependency "linux:https://github.com/salt-formulas/salt-formula-linux"
  95. dep_name="$(echo $1|cut -d : -f 1)"
  96. dep_source="$(echo $1|cut -d : -f 2-)"
  97. dep_root="${DEPSDIR}/$(basename $dep_source .git)"
  98. dep_metadata="${dep_root}/metadata.yml"
  99. dependency_check git
  100. [ -d $dep_root ] && { log_info "Dependency $dep_name already fetched"; return 0; }
  101. log_info "Fetching dependency $dep_name"
  102. [ ! -d ${DEPSDIR} ] && mkdir -p ${DEPSDIR}
  103. git clone $dep_source ${DEPSDIR}/$(basename $dep_source .git)
  104. ln -s ${dep_root}/${dep_name} ${SALT_FILE_DIR}/${dep_name}
  105. METADATA="${dep_metadata}" install_dependencies
  106. }
  107. link_modules(){
  108. # Link modules *.py files to temporary salt-root
  109. local SALT_ROOT=${1:-$SALT_FILE_DIR}
  110. local SALT_ENV=${2:-$DEPSDIR}
  111. mkdir -p "${SALT_ROOT}/_modules/"
  112. # from git, development versions
  113. find ${SALT_ENV} -maxdepth 3 -mindepth 3 -path '*_modules*' -iname "*.py" -type f -print0 | while read -d $'\0' file; do
  114. ln -fs $(readlink -e ${file}) "$SALT_ROOT"/_modules/$(basename ${file}) ;
  115. done
  116. salt_run saltutil.sync_all
  117. }
  118. install_dependencies() {
  119. grep -E "^dependencies:" ${METADATA} >/dev/null || return 0
  120. (python - | while read dep; do fetch_dependency "$dep"; done) << EOF
  121. import sys,yaml
  122. for dep in yaml.load(open('${METADATA}', 'ro'))['dependencies']:
  123. print '%s:%s' % (dep["name"], dep["source"])
  124. EOF
  125. }
  126. clean() {
  127. log_info "Cleaning up ${BUILDDIR}"
  128. [ -d ${BUILDDIR} ] && rm -rf ${BUILDDIR} || exit 0
  129. }
  130. salt_run() {
  131. [ -e ${VENV_DIR}/bin/activate ] && source ${VENV_DIR}/bin/activate
  132. python $(which salt-call) ${SALT_OPTS} $*
  133. }
  134. prepare() {
  135. if [[ -f ${BUILDDIR}/.prepare_done ]]; then
  136. log_info "${BUILDDIR}/.prepare_done exist, not rebuilding BUILDDIR"
  137. return
  138. fi
  139. [[ -d ${BUILDDIR} ]] && mkdir -p ${BUILDDIR}
  140. [[ ! -f "${VENV_DIR}/bin/activate" ]] && setup_virtualenv
  141. setup_mock_bin
  142. setup_pillar
  143. setup_salt
  144. install_dependencies
  145. link_modules
  146. touch ${BUILDDIR}/.prepare_done
  147. }
  148. lint_releasenotes() {
  149. [[ ! -f "${VENV_DIR}/bin/activate" ]] && setup_virtualenv
  150. source ${VENV_DIR}/bin/activate
  151. reno lint ${CURDIR}/../
  152. }
  153. lint() {
  154. # lint_releasenotes
  155. log_err "TODO: lint_releasenotes"
  156. }
  157. run() {
  158. for pillar in ${PILLARDIR}/*.sls; do
  159. grep ${FORMULA_NAME}: ${pillar} &>/dev/null || continue
  160. state_name=$(basename ${pillar%.sls})
  161. salt_run grains.set 'noservices' False force=True
  162. echo "Checking state ${FORMULA_NAME}.${state_name} ..."
  163. salt_run --id=${state_name} state.show_sls ${FORMULA_NAME} || (log_err "Execution of ${FORMULA_NAME}.${state_name} failed"; exit 1)
  164. # Check that all files in 'meta' folder can be rendered using any valid pillar
  165. for meta in `find ${FORMULA_META_DIR} -type f`; do
  166. meta_name=$(basename ${meta})
  167. echo "Checking meta ${meta_name} ..."
  168. salt_run --out=quiet --id=${state_name} cp.get_template ${meta} ${SALT_CACHE_DIR}/${meta_name} \
  169. || { log_err "Failed to render meta ${meta} using pillar ${FORMULA_NAME}.${state_name}"; exit 1; }
  170. cat ${SALT_CACHE_DIR}/${meta_name}
  171. done
  172. done
  173. }
  174. real_run() {
  175. for pillar in ${PILLARDIR}/*.sls; do
  176. state_name=$(basename ${pillar%.sls})
  177. salt_run --id=${state_name} state.sls ${FORMULA_NAME} || { log_err "Execution of ${FORMULA_NAME}.${state_name} failed"; exit 1; }
  178. done
  179. }
  180. run_model_validate(){
  181. # Run modelschema.model_validate validation.
  182. # TEST iterateble, run for `each formula ROLE against each ROLE_PILLARNAME`
  183. # Pillars should be named in conviend ROLE_XXX.sls or ROLE.sls
  184. # Example:
  185. # client.sls client_auth.sls server.sls server_auth.sls
  186. if [ -d ${SCHEMARDIR} ]; then
  187. # model validator require py modules
  188. fetch_dependency "salt:https://github.com/salt-formulas/salt-formula-salt"
  189. link_modules
  190. salt_run saltutil.clear_cache; salt_run saltutil.refresh_pillar; salt_run saltutil.sync_all;
  191. for role in ${SCHEMARDIR}/*.yaml; do
  192. role_name=$(basename "${role%*.yaml}")
  193. for pillar in $(ls pillar/${role_name}*.sls | grep -v ${IGNORE_MODELVALIDATE_MASK} ); do
  194. pillar_name=$(basename "${pillar%*.sls}")
  195. local _message="FORMULA:${FORMULA_NAME} ROLE:${role_name} against PILLAR:${pillar_name}"
  196. log_info "model_validate ${_message}"
  197. # Rendered Example:
  198. # python $(which salt-call) --local -c /test1/maas/tests/build/salt --id=maas_cluster modelschema.model_validate maas cluster
  199. salt_run -m ${DEPSDIR}/salt-formula-salt --id=${pillar_name} modelschema.model_validate ${FORMULA_NAME} ${role_name} || { log_err "Execution of model_validate ${_message} failed"; exit 1 ; }
  200. done
  201. done
  202. else
  203. log_info "${SCHEMARDIR} not found!";
  204. fi
  205. }
  206. dependency_check() {
  207. local DEPENDENCY_COMMANDS=$*
  208. for DEPENDENCY_COMMAND in $DEPENDENCY_COMMANDS; do
  209. which $DEPENDENCY_COMMAND > /dev/null || ( log_err "Command \"$DEPENDENCY_COMMAND\" can not be found in default path."; exit 1; )
  210. done
  211. }
  212. _atexit() {
  213. RETVAL=$?
  214. trap true INT TERM EXIT
  215. if [ $RETVAL -ne 0 ]; then
  216. log_err "Execution failed"
  217. else
  218. log_info "Execution successful"
  219. fi
  220. return $RETVAL
  221. }
  222. ## Main
  223. log_info "Running version: ${__ScriptVersion}"
  224. log_info "Command line: '${__ScriptFullName} ${__ScriptArgs}'"
  225. trap _atexit INT TERM EXIT
  226. case $1 in
  227. clean)
  228. clean
  229. ;;
  230. prepare)
  231. prepare
  232. ;;
  233. lint)
  234. lint
  235. ;;
  236. run)
  237. run
  238. ;;
  239. real-run)
  240. real_run
  241. ;;
  242. model-validate)
  243. prepare
  244. run_model_validate
  245. ;;
  246. *)
  247. prepare
  248. # lint
  249. run
  250. run_model_validate
  251. ;;
  252. esac