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.

il y a 6 ans
il y a 6 ans
il y a 6 ans
il y a 6 ans
il y a 6 ans
il y a 6 ans
il y a 6 ans
il y a 6 ans
il y a 6 ans
il y a 6 ans
il y a 6 ans
il y a 6 ans
il y a 6 ans
il y a 6 ans
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  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. dependency_check virtualenv
  37. virtualenv $VENV_DIR
  38. source ${VENV_DIR}/bin/activate
  39. pip install salt${PIP_SALT_VERSION}
  40. pip install jsonschema
  41. if [[ -f ${CURDIR}/pip_requirements.txt ]]; then
  42. pip install -r ${CURDIR}/pip_requirements.txt
  43. fi
  44. }
  45. setup_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. setup_pillar() {
  54. [ ! -d ${SALT_PILLAR_DIR} ] && mkdir -p ${SALT_PILLAR_DIR}
  55. echo "base:" > ${SALT_PILLAR_DIR}/top.sls
  56. for pillar in ${PILLARDIR}/*; do
  57. grep ${FORMULA_NAME}: ${pillar} &>/dev/null || continue
  58. state_name=$(basename ${pillar%.sls})
  59. echo -e " ${state_name}:\n - ${state_name}" >> ${SALT_PILLAR_DIR}/top.sls
  60. done
  61. }
  62. setup_salt() {
  63. [ ! -d ${SALT_FILE_DIR} ] && mkdir -p ${SALT_FILE_DIR}
  64. [ ! -d ${SALT_CONFIG_DIR} ] && mkdir -p ${SALT_CONFIG_DIR}
  65. [ ! -d ${SALT_CACHE_DIR} ] && mkdir -p ${SALT_CACHE_DIR}
  66. [ ! -d ${SALT_CACHE_EXTMODS_DIR} ] && mkdir -p ${SALT_CACHE_EXTMODS_DIR}
  67. echo "base:" > ${SALT_FILE_DIR}/top.sls
  68. for pillar in ${PILLARDIR}/*.sls; do
  69. grep ${FORMULA_NAME}: ${pillar} &>/dev/null || continue
  70. state_name=$(basename ${pillar%.sls})
  71. echo -e " ${state_name}:\n - ${FORMULA_NAME}" >> ${SALT_FILE_DIR}/top.sls
  72. done
  73. cat << EOF > ${SALT_CONFIG_DIR}/minion
  74. file_client: local
  75. cachedir: ${SALT_CACHE_DIR}
  76. extension_modules: ${SALT_CACHE_EXTMODS_DIR}
  77. verify_env: False
  78. minion_id_caching: False
  79. file_roots:
  80. base:
  81. - ${SALT_FILE_DIR}
  82. - ${CURDIR}/..
  83. pillar_roots:
  84. base:
  85. - ${SALT_PILLAR_DIR}
  86. - ${PILLARDIR}
  87. EOF
  88. }
  89. fetch_dependency() {
  90. # example: fetch_dependency "linux:https://github.com/salt-formulas/salt-formula-linux"
  91. dep_name="$(echo $1|cut -d : -f 1)"
  92. dep_source="$(echo $1|cut -d : -f 2-)"
  93. dep_root="${DEPSDIR}/$(basename $dep_source .git)"
  94. dep_metadata="${dep_root}/metadata.yml"
  95. dependency_check git
  96. [ -d $dep_root ] && { log_info "Dependency $dep_name already fetched"; return 0; }
  97. log_info "Fetching dependency $dep_name"
  98. [ ! -d ${DEPSDIR} ] && mkdir -p ${DEPSDIR}
  99. git clone $dep_source ${DEPSDIR}/$(basename $dep_source .git)
  100. ln -s ${dep_root}/${dep_name} ${SALT_FILE_DIR}/${dep_name}
  101. METADATA="${dep_metadata}" install_dependencies
  102. }
  103. link_modules(){
  104. # Link modules *.py files to temporary salt-root
  105. local SALT_ROOT=${1:-$SALT_FILE_DIR}
  106. local SALT_ENV=${2:-$DEPSDIR}
  107. mkdir -p "${SALT_ROOT}/_modules/"
  108. # from git, development versions
  109. find ${SALT_ENV} -maxdepth 3 -mindepth 3 -path '*_modules*' -iname "*.py" -type f -print0 | while read -d $'\0' file; do
  110. ln -fs $(readlink -e ${file}) "$SALT_ROOT"/_modules/$(basename ${file}) ;
  111. done
  112. salt_run saltutil.sync_all
  113. }
  114. install_dependencies() {
  115. grep -E "^dependencies:" ${METADATA} >/dev/null || return 0
  116. (python - | while read dep; do fetch_dependency "$dep"; done) << EOF
  117. import sys,yaml
  118. for dep in yaml.load(open('${METADATA}', 'ro'))['dependencies']:
  119. print '%s:%s' % (dep["name"], dep["source"])
  120. EOF
  121. }
  122. clean() {
  123. log_info "Cleaning up ${BUILDDIR}"
  124. [ -d ${BUILDDIR} ] && rm -rf ${BUILDDIR} || exit 0
  125. }
  126. salt_run() {
  127. [ -e ${VENV_DIR}/bin/activate ] && source ${VENV_DIR}/bin/activate
  128. salt-call ${SALT_OPTS} $*
  129. }
  130. prepare() {
  131. [ -d ${BUILDDIR} ] && mkdir -p ${BUILDDIR}
  132. [[ ! -f "${VENV_DIR}/bin/activate" ]] && setup_virtualenv
  133. setup_mock_bin
  134. setup_pillar
  135. setup_salt
  136. install_dependencies
  137. }
  138. lint_releasenotes() {
  139. [[ ! -f "${VENV_DIR}/bin/activate" ]] && setup_virtualenv
  140. source ${VENV_DIR}/bin/activate
  141. pip install reno
  142. reno lint ${CURDIR}/../
  143. }
  144. lint() {
  145. # lint_releasenotes
  146. log_err "TODO: lint_releasenotes"
  147. }
  148. run() {
  149. for pillar in ${PILLARDIR}/*.sls; do
  150. grep ${FORMULA_NAME}: ${pillar} &>/dev/null || continue
  151. state_name=$(basename ${pillar%.sls})
  152. salt_run grains.set 'noservices' False force=True
  153. echo "Checking state ${FORMULA_NAME}.${state_name} ..."
  154. salt_run --id=${state_name} state.show_sls ${FORMULA_NAME} || (log_err "Execution of ${FORMULA_NAME}.${state_name} failed"; exit 1)
  155. # Check that all files in 'meta' folder can be rendered using any valid pillar
  156. for meta in `find ${FORMULA_META_DIR} -type f`; do
  157. meta_name=$(basename ${meta})
  158. echo "Checking meta ${meta_name} ..."
  159. salt_run --out=quiet --id=${state_name} cp.get_template ${meta} ${SALT_CACHE_DIR}/${meta_name} \
  160. || { log_err "Failed to render meta ${meta} using pillar ${FORMULA_NAME}.${state_name}"; exit 1; }
  161. cat ${SALT_CACHE_DIR}/${meta_name}
  162. done
  163. done
  164. }
  165. real_run() {
  166. for pillar in ${PILLARDIR}/*.sls; do
  167. state_name=$(basename ${pillar%.sls})
  168. salt_run --id=${state_name} state.sls ${FORMULA_NAME} || { log_err "Execution of ${FORMULA_NAME}.${state_name} failed"; exit 1; }
  169. done
  170. }
  171. run_model_validate(){
  172. if [ -d ${SCHEMARDIR} ]; then
  173. # model validator require py modules
  174. fetch_dependency "salt:https://github.com/salt-formulas/salt-formula-salt"
  175. link_modules
  176. # Rendered Example:
  177. # salt-call --local -c /test1/maas/tests/build/salt --id=maas_cluster modelschema.model_validate maas cluster
  178. for role in ${SCHEMARDIR}/*.yaml; do
  179. state_name=$(basename "${role%*.yaml}")
  180. minion_id="${state_name}"
  181. # in case debug-reruns, usefull to make cleanup
  182. [ -n "$DEBUG" ] && { salt_run saltutil.clear_cache; salt_run saltutil.refresh_pillar; salt_run saltutil.sync_all; }
  183. 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 ; }
  184. done
  185. else
  186. log_info "${SCHEMARDIR} not found!";
  187. fi
  188. }
  189. dependency_check() {
  190. local DEPENDENCY_COMMANDS=$*
  191. for DEPENDENCY_COMMAND in $DEPENDENCY_COMMANDS; do
  192. which $DEPENDENCY_COMMAND > /dev/null || ( log_err "Command \"$DEPENDENCY_COMMAND\" can not be found in default path."; exit 1; )
  193. done
  194. }
  195. _atexit() {
  196. RETVAL=$?
  197. trap true INT TERM EXIT
  198. if [ $RETVAL -ne 0 ]; then
  199. log_err "Execution failed"
  200. else
  201. log_info "Execution successful"
  202. fi
  203. return $RETVAL
  204. }
  205. ## Main
  206. trap _atexit INT TERM EXIT
  207. case $1 in
  208. clean)
  209. clean
  210. ;;
  211. prepare)
  212. prepare
  213. ;;
  214. lint)
  215. lint
  216. ;;
  217. run)
  218. run
  219. ;;
  220. real-run)
  221. real_run
  222. ;;
  223. model-validate)
  224. prepare
  225. run_model_validate
  226. ;;
  227. *)
  228. prepare
  229. # lint
  230. run
  231. run_model_validate
  232. ;;
  233. esac