--- | |||||
driver: | |||||
name: docker | |||||
hostname: mongodb.ci.local | |||||
use_sudo: false | |||||
provisioner: | |||||
name: salt_solo | |||||
salt_install: bootstrap | |||||
salt_bootstrap_url: https://bootstrap.saltstack.com | |||||
salt_version: latest | |||||
require_chef: false | |||||
log_level: error | |||||
formula: mongodb | |||||
grains: | |||||
noservices: True | |||||
state_top: | |||||
base: | |||||
"*": | |||||
- mongodb | |||||
pillars: | |||||
top.sls: | |||||
base: | |||||
"*": | |||||
- mongodb | |||||
verifier: | |||||
name: inspec | |||||
sudo: true | |||||
platforms: | |||||
- name: <%=ENV['PLATFORM'] || 'ubuntu-xenial'%> | |||||
driver_config: | |||||
image: <%=ENV['PLATFORM'] || 'trevorj/salty-whales:xenial'%> | |||||
platform: ubuntu | |||||
suites: | |||||
- name: cluster | |||||
provisioner: | |||||
pillars-from-files: | |||||
mongodb.sls: tests/pillar/cluster.sls | |||||
- name: single | |||||
provisioner: | |||||
pillars-from-files: | |||||
mongodb.sls: tests/pillar/single.sls | |||||
# vim: ft=yaml sw=2 ts=2 sts=2 tw=125 |
sudo: required | |||||
services: | |||||
- docker | |||||
install: | |||||
- pip install PyYAML | |||||
- pip install virtualenv | |||||
- | | |||||
test -e Gemfile || cat <<EOF > Gemfile | |||||
source 'https://rubygems.org' | |||||
gem 'rake' | |||||
gem 'test-kitchen' | |||||
gem 'kitchen-docker' | |||||
gem 'kitchen-inspec' | |||||
gem 'inspec' | |||||
gem 'kitchen-salt', :git => 'https://github.com/salt-formulas/kitchen-salt.git' | |||||
- bundle install | |||||
env: | |||||
- PLATFORM=trevorj/salty-whales:trusty | |||||
- PLATFORM=trevorj/salty-whales:xenial | |||||
before_script: | |||||
- set -o pipefail | |||||
- make test | tail | |||||
script: | |||||
- test ! -e .kitchen.yml || bundle exec kitchen test -t tests/integration | |||||
notifications: | |||||
webhooks: | |||||
urls: | |||||
- https://webhooks.gitter.im/e/6123573504759330786b | |||||
on_success: change # options: [always|never|change] default: always | |||||
on_failure: never # options: [always|never|change] default: always | |||||
on_start: never # options: [always|never|change] default: always | |||||
on_cancel: never # options: [always|never|change] default: always | |||||
on_error: never # options: [always|never|change] default: always | |||||
email: false |
- user: mongodb | - user: mongodb | ||||
- require: | - require: | ||||
- pkg: mongodb_packages | - pkg: mongodb_packages | ||||
{%- if not grains.get('noservices', False) %} | |||||
- watch_in: | - watch_in: | ||||
- service: mongodb_service | - service: mongodb_service | ||||
{%- endif %} | |||||
{%- endif %} | {%- endif %} | ||||
file.directory: | file.directory: | ||||
- makedirs: true | - makedirs: true | ||||
{%- if not grains.get('noservices', False) %} | |||||
mongodb_service: | mongodb_service: | ||||
service.running: | service.running: | ||||
- name: {{ server.service }} | - name: {{ server.service }} | ||||
- watch: | - watch: | ||||
- file: /etc/mongodb.conf | - file: /etc/mongodb.conf | ||||
{%- endif %} | |||||
{%- if server.members is not defined or server.master == pillar.linux.system.name %} | {%- if server.members is not defined or server.master == pillar.linux.system.name %} | ||||
{# We are not a cluster or we are master #} | {# We are not a cluster or we are master #} | ||||
- mode: 600 | - mode: 600 | ||||
- user: root | - user: root | ||||
{%- if not grains.get('noservices', False) %} | |||||
mongodb_change_root_password: | mongodb_change_root_password: | ||||
cmd.run: | cmd.run: | ||||
- name: 'mongo localhost:27017/admin /var/tmp/mongodb_user.js && touch {{ server.lock_dir }}/mongodb_password_changed' | - name: 'mongo localhost:27017/admin /var/tmp/mongodb_user.js && touch {{ server.lock_dir }}/mongodb_password_changed' | ||||
- service: mongodb_service | - service: mongodb_service | ||||
- creates: {{ server.lock_dir }}/mongodb_password_changed | - creates: {{ server.lock_dir }}/mongodb_password_changed | ||||
{%- endif %} | |||||
{%- for database_name, database in server.get('database', {}).iteritems() %} | {%- for database_name, database in server.get('database', {}).iteritems() %} | ||||
/var/tmp/mongodb_user_{{ database_name }}.js: | /var/tmp/mongodb_user_{{ database_name }}.js: | ||||
- defaults: | - defaults: | ||||
database_name: {{ database_name }} | database_name: {{ database_name }} | ||||
{%- if not grains.get('noservices', False) %} | |||||
mongodb_{{ database_name }}_fix_role: | mongodb_{{ database_name }}_fix_role: | ||||
cmd.run: | cmd.run: | ||||
- name: 'mongo localhost:27017/admin -u admin -p {{ server.admin.password }} /var/tmp/mongodb_user_{{ database_name }}.js && touch {{ server.lock_dir }}/mongodb_user_{{ database_name }}_created' | - name: 'mongo localhost:27017/admin -u admin -p {{ server.admin.password }} /var/tmp/mongodb_user_{{ database_name }}.js && touch {{ server.lock_dir }}/mongodb_user_{{ database_name }}_created' | ||||
- require: | - require: | ||||
- file: /var/tmp/mongodb_user_{{ database_name }}.js | - file: /var/tmp/mongodb_user_{{ database_name }}.js | ||||
{%- if not grains.get('noservices', False) %} | |||||
- service: mongodb_service | - service: mongodb_service | ||||
{%- endif%} | |||||
- creates: {{ server.lock_dir }}/mongodb_user_{{ database_name }}_created | - creates: {{ server.lock_dir }}/mongodb_user_{{ database_name }}_created | ||||
{%- if server.members is defined %} | {%- if server.members is defined %} | ||||
require: | require: | ||||
- cmd: mongodb_setup_cluster | - cmd: mongodb_setup_cluster | ||||
{%- endif %} | {%- endif %} | ||||
{%- endif %} | |||||
{%- endfor %} | {%- endfor %} | ||||
{%- if server.members is defined %} | {%- if server.members is defined %} | ||||
- name: 'mongo localhost:27017/admin /var/tmp/mongodb_cluster.js && mongo localhost:27017/admin --quiet --eval "rs.conf()" | grep object -q' | - name: 'mongo localhost:27017/admin /var/tmp/mongodb_cluster.js && mongo localhost:27017/admin --quiet --eval "rs.conf()" | grep object -q' | ||||
- unless: 'mongo localhost:27017/admin -u admin -p {{ server.admin.password }} --quiet --eval "rs.conf()" | grep object -q' | - unless: 'mongo localhost:27017/admin -u admin -p {{ server.admin.password }} --quiet --eval "rs.conf()" | grep object -q' | ||||
- require: | - require: | ||||
{%- if not grains.get('noservices', False) %} | |||||
- service: mongodb_service | - service: mongodb_service | ||||
{%- endif %} | |||||
- file: /var/tmp/mongodb_cluster.js | - file: /var/tmp/mongodb_cluster.js | ||||
- require_in: | - require_in: | ||||
- cmd: mongodb_change_root_password | - cmd: mongodb_change_root_password |
mongodb: | |||||
server: | |||||
enabled: true | |||||
admin: | |||||
user: admin | |||||
password: magicunicorn | |||||
master: mongo01 | |||||
members: | |||||
- host: 192.168.1.11 | |||||
priority: 2 | |||||
- host: 192.168.1.12 | |||||
- host: 192.168.1.13 | |||||
replica_set: default | |||||
shared_key: magicunicorn | |||||
linux: | |||||
system: | |||||
name: name |
mongodb: | |||||
server: | |||||
enabled: true | |||||
bind: | |||||
address: 0.0.0.0 | |||||
port: 27017 | |||||
admin: | |||||
username: admin | |||||
password: magicunicorn | |||||
database: | |||||
dbname: | |||||
enabled: true | |||||
encoding: 'utf8' | |||||
users: | |||||
- name: 'username' | |||||
password: 'password' | |||||
ceilometer: | |||||
server: | |||||
database: | |||||
password: 'password' |
#!/usr/bin/env bash | |||||
set -e | |||||
[ -n "$DEBUG" ] && set -x | |||||
CURDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" | |||||
METADATA=${CURDIR}/../metadata.yml | |||||
FORMULA_NAME=$(cat $METADATA | python -c "import sys,yaml; print yaml.load(sys.stdin)['name']") | |||||
## Overrideable parameters | |||||
PILLARDIR=${PILLARDIR:-${CURDIR}/pillar} | |||||
BUILDDIR=${BUILDDIR:-${CURDIR}/build} | |||||
VENV_DIR=${VENV_DIR:-${BUILDDIR}/virtualenv} | |||||
DEPSDIR=${BUILDDIR}/deps | |||||
SALT_FILE_DIR=${SALT_FILE_DIR:-${BUILDDIR}/file_root} | |||||
SALT_PILLAR_DIR=${SALT_PILLAR_DIR:-${BUILDDIR}/pillar_root} | |||||
SALT_CONFIG_DIR=${SALT_CONFIG_DIR:-${BUILDDIR}/salt} | |||||
SALT_CACHE_DIR=${SALT_CACHE_DIR:-${SALT_CONFIG_DIR}/cache} | |||||
SALT_OPTS="${SALT_OPTS} --retcode-passthrough --local -c ${SALT_CONFIG_DIR}" | |||||
if [ "x${SALT_VERSION}" != "x" ]; then | |||||
PIP_SALT_VERSION="==${SALT_VERSION}" | |||||
fi | |||||
## Functions | |||||
log_info() { | |||||
echo "[INFO] $*" | |||||
} | |||||
log_err() { | |||||
echo "[ERROR] $*" >&2 | |||||
} | |||||
setup_virtualenv() { | |||||
log_info "Setting up Python virtualenv" | |||||
virtualenv $VENV_DIR | |||||
source ${VENV_DIR}/bin/activate | |||||
pip install salt${PIP_SALT_VERSION} | |||||
} | |||||
setup_pillar() { | |||||
[ ! -d ${SALT_PILLAR_DIR} ] && mkdir -p ${SALT_PILLAR_DIR} | |||||
echo "base:" > ${SALT_PILLAR_DIR}/top.sls | |||||
for pillar in ${PILLARDIR}/*; do | |||||
state_name=$(basename ${pillar%.sls}) | |||||
echo -e " ${state_name}:\n - ${state_name}" >> ${SALT_PILLAR_DIR}/top.sls | |||||
done | |||||
} | |||||
setup_salt() { | |||||
[ ! -d ${SALT_FILE_DIR} ] && mkdir -p ${SALT_FILE_DIR} | |||||
[ ! -d ${SALT_CONFIG_DIR} ] && mkdir -p ${SALT_CONFIG_DIR} | |||||
[ ! -d ${SALT_CACHE_DIR} ] && mkdir -p ${SALT_CACHE_DIR} | |||||
echo "base:" > ${SALT_FILE_DIR}/top.sls | |||||
for pillar in ${PILLARDIR}/*.sls; do | |||||
state_name=$(basename ${pillar%.sls}) | |||||
echo -e " ${state_name}:\n - ${FORMULA_NAME}" >> ${SALT_FILE_DIR}/top.sls | |||||
done | |||||
cat << EOF > ${SALT_CONFIG_DIR}/minion | |||||
file_client: local | |||||
cachedir: ${SALT_CACHE_DIR} | |||||
verify_env: False | |||||
file_roots: | |||||
base: | |||||
- ${SALT_FILE_DIR} | |||||
- ${CURDIR}/.. | |||||
- /usr/share/salt-formulas/env | |||||
pillar_roots: | |||||
base: | |||||
- ${SALT_PILLAR_DIR} | |||||
- ${PILLARDIR} | |||||
EOF | |||||
} | |||||
fetch_dependency() { | |||||
dep_name="$(echo $1|cut -d : -f 1)" | |||||
dep_source="$(echo $1|cut -d : -f 2-)" | |||||
dep_root="${DEPSDIR}/$(basename $dep_source .git)" | |||||
dep_metadata="${dep_root}/metadata.yml" | |||||
[ -d /usr/share/salt-formulas/env/${dep_name} ] && log_info "Dependency $dep_name already present in system-wide salt env" && return 0 | |||||
[ -d $dep_root ] && log_info "Dependency $dep_name already fetched" && return 0 | |||||
log_info "Fetching dependency $dep_name" | |||||
[ ! -d ${DEPSDIR} ] && mkdir -p ${DEPSDIR} | |||||
git clone $dep_source ${DEPSDIR}/$(basename $dep_source .git) | |||||
ln -s ${dep_root}/${dep_name} ${SALT_FILE_DIR}/${dep_name} | |||||
METADATA="${dep_metadata}" install_dependencies | |||||
} | |||||
install_dependencies() { | |||||
grep -E "^dependencies:" ${METADATA} >/dev/null || return 0 | |||||
(python - | while read dep; do fetch_dependency "$dep"; done) << EOF | |||||
import sys,yaml | |||||
for dep in yaml.load(open('${METADATA}', 'ro'))['dependencies']: | |||||
print '%s:%s' % (dep["name"], dep["source"]) | |||||
EOF | |||||
} | |||||
clean() { | |||||
log_info "Cleaning up ${BUILDDIR}" | |||||
[ -d ${BUILDDIR} ] && rm -rf ${BUILDDIR} || exit 0 | |||||
} | |||||
salt_run() { | |||||
[ -e ${VEN_DIR}/bin/activate ] && source ${VENV_DIR}/bin/activate | |||||
salt-call ${SALT_OPTS} $* | |||||
} | |||||
prepare() { | |||||
[ -d ${BUILDDIR} ] && mkdir -p ${BUILDDIR} | |||||
which salt-call || setup_virtualenv | |||||
setup_pillar | |||||
setup_salt | |||||
install_dependencies | |||||
} | |||||
run() { | |||||
for pillar in ${PILLARDIR}/*.sls; do | |||||
state_name=$(basename ${pillar%.sls}) | |||||
salt_run --id=${state_name} state.show_sls ${FORMULA_NAME} || (log_err "Execution of ${FORMULA_NAME}.${state_name} failed"; exit 1) | |||||
done | |||||
} | |||||
real_run() { | |||||
for pillar in ${PILLARDIR}/*.sls; do | |||||
state_name=$(basename ${pillar%.sls}) | |||||
salt_run --id=${state_name} state.sls ${FORMULA_NAME} || (log_err "Execution of ${FORMULA_NAME}.${state_name} failed"; exit 1) | |||||
done | |||||
} | |||||
_atexit() { | |||||
RETVAL=$? | |||||
trap true INT TERM EXIT | |||||
if [ $RETVAL -ne 0 ]; then | |||||
log_err "Execution failed" | |||||
else | |||||
log_info "Execution successful" | |||||
fi | |||||
return $RETVAL | |||||
} | |||||
## Main | |||||
trap _atexit INT TERM EXIT | |||||
case $1 in | |||||
clean) | |||||
clean | |||||
;; | |||||
prepare) | |||||
prepare | |||||
;; | |||||
run) | |||||
run | |||||
;; | |||||
real-run) | |||||
real_run | |||||
;; | |||||
*) | |||||
prepare | |||||
run | |||||
;; | |||||
esac |