Skip to content

Commit

Permalink
✨(apps) add elasticsearch application
Browse files Browse the repository at this point in the history
Add  an  independant  elasticsearch   app  with  a  configurable  high
availability cluster. It is designed  to run without persistent volume
and it  supports rolling updates without  any data loss. On  the other
hand,  a full  restart  of  the ES  cluster  (without rolling  update)
results in data loss and requires to recreate indexes.
  • Loading branch information
madmatah committed Jan 27, 2020
1 parent 6e45ccb commit 6d520ea
Show file tree
Hide file tree
Showing 18 changed files with 428 additions and 39 deletions.
87 changes: 60 additions & 27 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -201,15 +201,15 @@ jobs:
# Bootstrap app
bin/ci-ansible-playbook bootstrap.yml "hello"
# Test service deployed with the next route
bin/ci-test-service "hello" "Hello OpenShift! by Arnold" "/" "next"
bin/ci-test-route "hello" "Hello OpenShift! by Arnold" "/" "next"
- run:
name: Test the "hello" application switch
command: |
# Switch next route to current
bin/ci-ansible-playbook switch.yml "hello"
# Test service switched to the current route
bin/ci-test-service "hello" "Hello OpenShift! by Arnold"
bin/ci-test-route "hello" "Hello OpenShift! by Arnold"
- run:
name: Test the "hello" application rollback
Expand All @@ -219,13 +219,13 @@ jobs:
# Switch next route to current and current to previous
bin/ci-ansible-playbook switch.yml "hello"
# Test service switched to the current/previous route
bin/ci-test-service "hello" "Hello OpenShift! by Arnold"
bin/ci-test-service "hello" "Hello OpenShift! by Arnold" "/" "previous"
bin/ci-test-route "hello" "Hello OpenShift! by Arnold"
bin/ci-test-route "hello" "Hello OpenShift! by Arnold" "/" "previous"
# Rollback previous to current and current to next
bin/ci-ansible-playbook rollback.yml "hello"
# Test service switched to the current/next route
bin/ci-test-service "hello" "Hello OpenShift! by Arnold"
bin/ci-test-service "hello" "Hello OpenShift! by Arnold" "/" "next"
bin/ci-test-route "hello" "Hello OpenShift! by Arnold"
bin/ci-test-route "hello" "Hello OpenShift! by Arnold" "/" "next"
# Test the redirect application
test-redirect:
Expand Down Expand Up @@ -255,7 +255,7 @@ jobs:
name: Test the "www" to root domain redirection
command: |
# Test service switched to the current route
bin/ci-test-service "hello" "Hello OpenShift! by Arnold" "/" "www"
bin/ci-test-route "hello" "Hello OpenShift! by Arnold" "/" "www"
# Test the bootstrap playbook on the "mailcatcher" application
# nota bene: we use a real OpenShift cluster installed in CircleCI's VM.
Expand All @@ -278,7 +278,7 @@ jobs:
name: Test the "mailcatcher" application bootstrapping
command: |
bin/ci-ansible-playbook bootstrap.yml "mailcatcher"
bin/ci-test-service "mailcatcher" "MailCatcher"
bin/ci-test-route "mailcatcher" "MailCatcher"
# Test the bootstrap playbook on the "richie" application
# nota bene: we use a real OpenShift cluster installed in CircleCI's VM.
Expand All @@ -303,15 +303,15 @@ jobs:
# Bootstrap app
bin/ci-ansible-playbook bootstrap.yml "richie"
# Test service deployed with the next route
bin/ci-test-service "richie" "Django administration" "/en/admin" "next"
bin/ci-test-route "richie" "Django administration" "/en/admin" "next"
- run:
name: Test the "richie" application switch
command: |
# Switch next route to current
bin/ci-ansible-playbook switch.yml "richie"
# Test service switched to the current route
bin/ci-test-service "richie" "Django administration" "/en/admin"
bin/ci-test-route "richie" "Django administration" "/en/admin"
# Test the bootstrap playbook on the "forum" application
# nota bene: we use a real OpenShift cluster installed in CircleCI's VM.
Expand All @@ -336,15 +336,15 @@ jobs:
# Bootstrap app
bin/ci-ansible-playbook bootstrap.yml "forum"
# Test service deployed with the next route
bin/ci-test-service "forum" "collection" "/api/v1/threads?api_key=thisisafakeapikey" "next"
bin/ci-test-route "forum" "collection" "/api/v1/threads?api_key=thisisafakeapikey" "next"
- run:
name: Test the "forum" application switch
command: |
# Switch next route to current
bin/ci-ansible-playbook switch.yml "forum"
# Test service switched to the current route
bin/ci-test-service "forum" "collection" "/api/v1/threads?api_key=thisisafakeapikey"
bin/ci-test-route "forum" "collection" "/api/v1/threads?api_key=thisisafakeapikey"
# Test the bootstrap playbook on the "edxapp" application
# nota bene: we use a real OpenShift cluster installed in CircleCI's VM.
Expand All @@ -369,17 +369,17 @@ jobs:
# Bootstrap app
bin/ci-ansible-playbook bootstrap.yml "edxapp,redis"
# Test services deployed with the next route
bin/ci-test-service "cms" "Welcome to Your Platform Studio" "/" "next"
bin/ci-test-service "lms" "It works! This is the default homepage for this Open edX instance." "/" "next"
bin/ci-test-route "cms" "Welcome to Your Platform Studio" "/" "next"
bin/ci-test-route "lms" "It works! This is the default homepage for this Open edX instance." "/" "next"
- run:
name: Test the "edxapp" application switch
command: |
# Switch next route to current
bin/ci-ansible-playbook switch.yml "edxapp"
# Test service switched to the current route
bin/ci-test-service "cms" "Welcome to Your Platform Studio"
bin/ci-test-service "lms" "It works! This is the default homepage for this Open edX instance."
bin/ci-test-route "cms" "Welcome to Your Platform Studio"
bin/ci-test-route "lms" "It works! This is the default homepage for this Open edX instance."
# Test the bootstrap playbook on the "edxec" application
# nota bene: we use a real OpenShift cluster installed in CircleCI's VM.
Expand All @@ -404,14 +404,14 @@ jobs:
# Bootstrap edxec
bin/ci-ansible-playbook bootstrap.yml "edxec"
# Test the service
bin/ci-test-service "edxec" "OK" "/health/" "next"
bin/ci-test-route "edxec" "OK" "/health/" "next"
- run:
name: Test the "edxec" application switch
command: |
# Switch next route to current
bin/ci-ansible-playbook switch.yml "edxec"
bin/ci-test-service "edxec" "OK" "/health/"
bin/ci-test-route "edxec" "OK" "/health/"
# Test the bootstrap playbook on the "marsha" application
# nota bene: we use a real OpenShift cluster installed in CircleCI's VM.
Expand All @@ -436,15 +436,15 @@ jobs:
# Bootstrap app
bin/ci-ansible-playbook bootstrap.yml "marsha"
# Test services deployed with the next route
bin/ci-test-service "marsha" "Api Root" "/api/" "next"
bin/ci-test-route "marsha" "Api Root" "/api/" "next"
- run:
name: Test the "marsha" application switch
command: |
# Switch next route to current
bin/ci-ansible-playbook switch.yml "marsha"
# Test service switched to the current route
bin/ci-test-service "marsha" "Api Root" "/api/"
bin/ci-test-route "marsha" "Api Root" "/api/"
# Test the bootstrap playbook on the "learninglocker" application.
# We also need redis and mailcatcher for this application
Expand All @@ -468,15 +468,38 @@ jobs:
name: Test the "learninglocker" application bootstrapping
command: |
bin/ci-ansible-playbook bootstrap.yml "redis,mailcatcher,learninglocker"
bin/ci-test-service "learninglocker" "OK" "/api" "next"
bin/ci-test-route "learninglocker" "OK" "/api" "next"
- run:
name: Test the "learninglocker" application switch
command: |
# Switch next route to current
bin/ci-ansible-playbook switch.yml "learninglocker"
# Test service switched to the current route
bin/ci-test-service "learninglocker" "OK" "/api"
bin/ci-test-route "learninglocker" "OK" "/api"
# Test the bootstrap playbook on the "elasticsearch" application.
test-bootstrap-elasticsearch:
machine:
docker_layer_caching: false

working_directory: ~/fun

steps:
- checkout
- *attach_workspace
- *docker_load
- *ci_env
- *install_openshift_cluster
- *configure_openshift_cluster
- *run_openshift_cluster

- run:
name: Test the "elasticsearch" application bootstrapping
command: |
bin/ci-ansible-playbook bootstrap.yml "elasticsearch"
oc project ci-eugene
bin/ci-test-service elasticsearch 9200 "green" /_cluster/health
# Test the delete_app tasks for blue-green applications
# nota bene: we use a real OpenShift cluster installed in CircleCI's VM.
Expand All @@ -501,15 +524,15 @@ jobs:
# Bootstrap app
bin/ci-ansible-playbook bootstrap.yml "richie"
# Test service deployed with the next route
bin/ci-test-service "richie" "Django administration" "/en/admin" "next"
bin/ci-test-route "richie" "Django administration" "/en/admin" "next"
- run:
name: Test "richie"'s next stack substitution (create + delete)
command: |
# Deploy the next stack a second time
bin/ci-ansible-playbook deploy.yml "richie"
# Test service re-deployed with the next route
bin/ci-test-service "richie" "Django administration" "/en/admin" "next"
bin/ci-test-route "richie" "Django administration" "/en/admin" "next"
- run:
name: Check that only one pod is running Richie's app
Expand Down Expand Up @@ -544,17 +567,17 @@ jobs:
# Bootstrap app
bin/ci-ansible-playbook bootstrap.yml "hello"
# Test service deployed with the next route
bin/ci-test-service "hello" "Hello OpenShift! by Arnold" "/" "next"
bin/ci-test-route "hello" "Hello OpenShift! by Arnold" "/" "next"
- run:
name: Test "hello"'s switch
command: |
# Switch next route to current
bin/ci-ansible-playbook switch.yml "hello"
# Test service on the current route
bin/ci-test-service "hello" "Hello OpenShift! by Arnold" "/" "current"
bin/ci-test-route "hello" "Hello OpenShift! by Arnold" "/" "current"
# Test that the service is not responding on next route
bin/ci-test-service "hello" "Hello OpenShift! by Arnold" "/" "next" && exit 1 || true
bin/ci-test-route "hello" "Hello OpenShift! by Arnold" "/" "next" && exit 1 || true
- run:
name: Test that a second switch fails to execute with an error
Expand Down Expand Up @@ -775,6 +798,15 @@ workflows:
filters:
tags:
only: /.*/
- test-bootstrap-elasticsearch:
requires:
- lint-bash
- lint-docker
- lint-ansible
- lint-plugins
filters:
tags:
only: /.*/
- test-delete-app:
requires:
- test-bootstrap-richie
Expand Down Expand Up @@ -812,6 +844,7 @@ workflows:
- test-bootstrap-marsha
- test-bootstrap-forum
- test-bootstrap-learninglocker
- test-bootstrap-elasticsearch
- test-redirect
- test-delete-app
- test-prevent-switch-to-nothing
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Versioning](http://semver.org/spec/v2.0.0.html).

### Added

- New application `elasticsearch` deployable _via_ Arnold
- Configured nginx cache for statics and media files for the following apps:
- `richie`
- `marsha`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
cluster.name: {{ elasticsearch_cluster_name }}
network.host: "0.0.0.0"
bootstrap.memory_lock: false
discovery.zen.ping.unicast.hosts: elasticsearch-discovery.{{ project_name }}.svc
discovery.zen.minimum_master_nodes: 2
xpack.security.enabled: false
xpack.monitoring.enabled: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env bash

set -eo pipefail

ES_HOST="127.0.0.1"
ES_PORT="{{ elasticsearch_api_port }}"
ES_STARTED="/tmp/es_started"


testStatus() {
status_to_test="${1}"
expected_status="${2}"

declare -A statuses=( ["red"]=1 ["yellow"]=2 ["green"]=3)

if [[ -z "$status_to_test" || -z "${statuses[$status_to_test]}" ]] ; then
echo "Error : unknown status_to_test [$status_to_test]" 1>&2
exit 1
fi

if [[ -z "$expected_status" || -z "${statuses[$expected_status]}" ]]; then
echo "Error : unknown expected_status [$expected_status]" 1>&2
exit 1
fi

if [ ${statuses[$status_to_test]} -lt ${statuses[$expected_status]} ]; then
echo "Assertion failed : $status_to_test < $expected_status"
exit 1
fi
}

if [ -f "$ES_STARTED" ]; then
echo "Elasticsearch is already running. Checking if API is alive"
curl -fsSL "http://${ES_HOST}:${ES_PORT}/" > /dev/null
echo "OK"
else
echo "Waiting for elasticsearch cluster to be running and in green state"
health_status=$(curl -fsSL "http://${ES_HOST}:${ES_PORT}/_cat/health?h=status" | sed -r 's/^[[:space:]]+|[[:space:]]+$//g')
testStatus "$health_status" "green"

echo "Waiting for initializing_shards to be 0"
init_shards=$(curl -fsSL "http://${ES_HOST}:${ES_PORT}/_cat/health?h=init" | sed -r 's/^[[:space:]]+|[[:space:]]+$//g')

if [ "${init_shards}" -gt 0 ]; then
echo "Synchronization not ready yet, initializing_shards = ${init_shards}"
exit 1
fi

touch "$ES_STARTED"

echo "Elasticsearch cluster is up (status = ${health_status})"
fi
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env bash

MAX_RETRY=20
RETRY_DELAY=5

while ! curl --output /dev/null --silent --max-time 1 --connect-timeout 1 --head --fail "http://elasticsearch.{{project_name}}.svc:{{ elasticsearch_api_port }}/"
do
echo "Waiting for ES service to be up..."
((c++)) && ((c==$MAX_RETRY)) && break
sleep $RETRY_DELAY
done

set -e

curl -fssL -X PUT "http://elasticsearch.{{project_name}}.svc:{{ elasticsearch_api_port }}/_template/default" -H 'Content-Type: application/json' -d'
{
{% if elasticsearch_image_tag is version('6.0', '<') %}
"template" : "*",
{% else %}
"index_patterns": ["*"],
{% endif %}
"settings" : {
"number_of_shards": {{ elasticsearch_index_default_shards }},
"number_of_replicas": {{ elasticsearch_index_default_replicas }},
"index.store.type": "{{elasticsearch_index_store_type}}",
"index.unassigned.node_left.delayed_timeout": "{{elasticsearch_index_node_left_delayed_timeout}}"
}
}
'
Loading

0 comments on commit 6d520ea

Please sign in to comment.