From 6d520ea36a000b317a310491acdde56f197ff8c9 Mon Sep 17 00:00:00 2001 From: Matthieu Huguet Date: Thu, 23 Jan 2020 16:30:09 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(apps)=20add=20elasticsearch=20applica?= =?UTF-8?q?tion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- .circleci/config.yml | 87 +++++++++++++------ CHANGELOG.md | 1 + .../services/app/configs/elasticsearch.yml.j2 | 7 ++ .../app/configs/readiness-probe.sh.j2 | 52 +++++++++++ .../app/configs/set-index-template.sh.j2 | 29 +++++++ .../templates/services/app/dc.yml.j2 | 78 +++++++++++++++++ .../app/job_set_index_template.yml.j2 | 40 +++++++++ .../services/app/svc-discovery.yml.j2 | 25 ++++++ .../templates/services/app/svc.yml.j2 | 18 ++++ apps/elasticsearch/tray.yml | 3 + apps/elasticsearch/vars/all/main.yml | 43 +++++++++ apps/elasticsearch/vars/settings.yml | 1 + bin/ci-test-route | 39 +++++++++ bin/ci-test-service | 36 +++++--- .../customer/eugene/development/main.yml | 1 + group_vars/customer/eugene/main.yml | 5 ++ group_vars/env_type/ci.yml | 1 + group_vars/env_type/development.yml | 1 + 18 files changed, 428 insertions(+), 39 deletions(-) create mode 100644 apps/elasticsearch/templates/services/app/configs/elasticsearch.yml.j2 create mode 100644 apps/elasticsearch/templates/services/app/configs/readiness-probe.sh.j2 create mode 100644 apps/elasticsearch/templates/services/app/configs/set-index-template.sh.j2 create mode 100644 apps/elasticsearch/templates/services/app/dc.yml.j2 create mode 100644 apps/elasticsearch/templates/services/app/job_set_index_template.yml.j2 create mode 100644 apps/elasticsearch/templates/services/app/svc-discovery.yml.j2 create mode 100644 apps/elasticsearch/templates/services/app/svc.yml.j2 create mode 100644 apps/elasticsearch/tray.yml create mode 100644 apps/elasticsearch/vars/all/main.yml create mode 100644 apps/elasticsearch/vars/settings.yml create mode 100755 bin/ci-test-route diff --git a/.circleci/config.yml b/.circleci/config.yml index 3531615ce..c6ca67a4a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -201,7 +201,7 @@ 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 @@ -209,7 +209,7 @@ jobs: # 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 @@ -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: @@ -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. @@ -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. @@ -303,7 +303,7 @@ 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 @@ -311,7 +311,7 @@ jobs: # 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. @@ -336,7 +336,7 @@ 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 @@ -344,7 +344,7 @@ jobs: # 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. @@ -369,8 +369,8 @@ 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 @@ -378,8 +378,8 @@ jobs: # 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. @@ -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. @@ -436,7 +436,7 @@ 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 @@ -444,7 +444,7 @@ jobs: # 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 @@ -468,7 +468,7 @@ 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 @@ -476,7 +476,30 @@ jobs: # 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. @@ -501,7 +524,7 @@ 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) @@ -509,7 +532,7 @@ jobs: # 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 @@ -544,7 +567,7 @@ 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 @@ -552,9 +575,9 @@ jobs: # 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 @@ -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 @@ -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 diff --git a/CHANGELOG.md b/CHANGELOG.md index 80651a08c..51d616cd9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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` diff --git a/apps/elasticsearch/templates/services/app/configs/elasticsearch.yml.j2 b/apps/elasticsearch/templates/services/app/configs/elasticsearch.yml.j2 new file mode 100644 index 000000000..0234b93ed --- /dev/null +++ b/apps/elasticsearch/templates/services/app/configs/elasticsearch.yml.j2 @@ -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 diff --git a/apps/elasticsearch/templates/services/app/configs/readiness-probe.sh.j2 b/apps/elasticsearch/templates/services/app/configs/readiness-probe.sh.j2 new file mode 100644 index 000000000..52d5f27a9 --- /dev/null +++ b/apps/elasticsearch/templates/services/app/configs/readiness-probe.sh.j2 @@ -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 diff --git a/apps/elasticsearch/templates/services/app/configs/set-index-template.sh.j2 b/apps/elasticsearch/templates/services/app/configs/set-index-template.sh.j2 new file mode 100644 index 000000000..604d90a8e --- /dev/null +++ b/apps/elasticsearch/templates/services/app/configs/set-index-template.sh.j2 @@ -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}}" + } +} +' diff --git a/apps/elasticsearch/templates/services/app/dc.yml.j2 b/apps/elasticsearch/templates/services/app/dc.yml.j2 new file mode 100644 index 000000000..af2ee0cc6 --- /dev/null +++ b/apps/elasticsearch/templates/services/app/dc.yml.j2 @@ -0,0 +1,78 @@ +apiVersion: v1 +kind: DeploymentConfig +metadata: + labels: + app: elasticsearch + service: elasticsearch + version: "{{ elasticsearch_image_tag }}" + type: es-node + name: "elasticsearch-node" + namespace: "{{ project_name }}" +spec: + replicas: {{ elasticsearch_nodes }} + template: + metadata: + labels: + app: elasticsearch + service: elasticsearch + type: es-node + spec: + strategy: + type: Rolling + rollingParams: + maxUnavailable: 0 + maxSurge: 1 + timeoutSeconds: 3600 + # Prefer running pods on different nodes for redundancy + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: deploymentconfig + operator: In + values: + - "elasticsearch-node" + topologyKey: kubernetes.io/hostname + containers: + - image: {{ elasticsearch_image_name }}:{{ elasticsearch_image_tag }} + name: elasticsearch + ports: + - containerPort: {{ elasticsearch_api_port }} + protocol: TCP + name: "http-port" + - containerPort: {{ elasticsearch_communication_port }} + protocol: TCP + name: "comm-port" + volumeMounts: + - name: elasticsearch-config + mountPath: /usr/share/elasticsearch/config/elasticsearch.yml + subPath: elasticsearch.yml + - name: readiness-probe + mountPath: /usr/local/bin/readiness-probe.sh + subPath: readiness-probe.sh + env: + - name: ES_JAVA_OPTS + value: "{{ elasticsearch_java_opts }}" + readinessProbe: + exec: + command: + - /usr/local/bin/readiness-probe.sh + initialDelaySeconds: 20 + periodSeconds: 5 + volumes: + - name: elasticsearch-config + configMap: + name: elasticsearch-app-{{ deployment_stamp }} + items: + - key: elasticsearch.yml + path: elasticsearch.yml + - name: readiness-probe + configMap: + name: elasticsearch-app-{{ deployment_stamp }} + defaultMode: 0755 + items: + - key: readiness-probe.sh + path: readiness-probe.sh diff --git a/apps/elasticsearch/templates/services/app/job_set_index_template.yml.j2 b/apps/elasticsearch/templates/services/app/job_set_index_template.yml.j2 new file mode 100644 index 000000000..b0d0e4b48 --- /dev/null +++ b/apps/elasticsearch/templates/services/app/job_set_index_template.yml.j2 @@ -0,0 +1,40 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: "es-index-tpl-{{ job_stamp }}" + namespace: "{{ project_name }}" + labels: + app: elasticsearch + service: elasticsearch + version: "{{ elasticsearch_image_tag }}" + job_stamp: "{{ job_stamp }}" + job_type: "post" + deployment_stamp: "{{ deployment_stamp }}" +spec: + template: + metadata: + name: "es-index-tpl-{{ job_stamp }}" + labels: + app: elasticsearch + service: elasticsearch + version: "{{ elasticsearch_image_tag }}" + deployment_stamp: "{{ deployment_stamp }}" + job_stamp: "{{ job_stamp }}" + spec: + containers: + - name: es-index-tpl + image: "{{ elasticsearch_image_name }}:{{ elasticsearch_image_tag }}" + command: [ "/usr/local/bin/set-index-template.sh" ] + volumeMounts: + - name: set-index-template + mountPath: /usr/local/bin/set-index-template.sh + subPath: set-index-template.sh + restartPolicy: Never + volumes: + - name: set-index-template + configMap: + name: elasticsearch-app-{{ deployment_stamp }} + defaultMode: 0755 + items: + - key: set-index-template.sh + path: set-index-template.sh diff --git a/apps/elasticsearch/templates/services/app/svc-discovery.yml.j2 b/apps/elasticsearch/templates/services/app/svc-discovery.yml.j2 new file mode 100644 index 000000000..16ce9369b --- /dev/null +++ b/apps/elasticsearch/templates/services/app/svc-discovery.yml.j2 @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: elasticsearch + service: elasticsearch + version: "{{ elasticsearch_image_tag }}" + name: elasticsearch-discovery + namespace: "{{ project_name }}" + annotations: + # Deprecated annotation replaced by publishNotReadyAddresses + # Needed to be compatible with openshift < 3.11 + service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" +spec: + clusterIP: None + # Required for peer discovery. + # It allows ES nodes to join the cluster and start data synchronization before being declared ready. + publishNotReadyAddresses: true + selector: + app: elasticsearch + service: elasticsearch + type: es-node + ports: + - name: transport + port: {{ elasticsearch_communication_port }} diff --git a/apps/elasticsearch/templates/services/app/svc.yml.j2 b/apps/elasticsearch/templates/services/app/svc.yml.j2 new file mode 100644 index 000000000..1dcfea5de --- /dev/null +++ b/apps/elasticsearch/templates/services/app/svc.yml.j2 @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: elasticsearch + service: elasticsearch + version: "{{ elasticsearch_image_tag }}" + name: elasticsearch + namespace: "{{ project_name }}" +spec: + selector: + app: elasticsearch + service: elasticsearch + type: es-node + ports: + - name: http + port: {{ elasticsearch_api_port }} + type: ClusterIP diff --git a/apps/elasticsearch/tray.yml b/apps/elasticsearch/tray.yml new file mode 100644 index 000000000..dc0117a7a --- /dev/null +++ b/apps/elasticsearch/tray.yml @@ -0,0 +1,3 @@ +metadata: + name: elasticsearch + version: 6.6.2 diff --git a/apps/elasticsearch/vars/all/main.yml b/apps/elasticsearch/vars/all/main.yml new file mode 100644 index 000000000..03d70faf5 --- /dev/null +++ b/apps/elasticsearch/vars/all/main.yml @@ -0,0 +1,43 @@ +# -- Docker related configuration + +elasticsearch_image_name: "fundocker/openshift-elasticsearch" +elasticsearch_image_tag: "6.6.2" + +# -- Node specific configuration + +elasticsearch_java_opts: "-Xms512m -Xmx512m" + +# -- Cluster configuration + +# cluster size (number of pods to start) +elasticsearch_nodes: 3 + +# minimum number of master eligible nodes a node should "see" in order to win a master election +# (see discovery.zen.minimum_master_nodes setting in ES documentation) +elasticsearch_minimum_master_nodes: 2 + +elasticsearch_cluster_name: "elasticsearch-cluster" +elasticsearch_api_port: 9200 +elasticsearch_communication_port: 9300 + +# -- Default index template +# The values in this section will only affect future creation of indexes. +# If you modify them, they will not have any effect on existing indexes. + +# Number of shards per index +elasticsearch_index_default_shards: 2 + +# Number of replica of each shard +elasticsearch_index_default_replicas: 2 + +# If a node is disconnected, the cluster will wait (default is 1m) before re-assigning shards to other nodes. +# This has an impact on the rolling upgrade process, it will take at least : +# (elasticsearch_nodes * elasticsearch_index_node_left_delayed_timeout) + data synchronization time +# (see index.unassigned.node_left.delayed_timeout setting in ES documentation) +elasticsearch_index_node_left_delayed_timeout: "30s" + + +# Index storage type +# (see index.store.type in ES documentation) +elasticsearch_index_store_type: "niofs" + diff --git a/apps/elasticsearch/vars/settings.yml b/apps/elasticsearch/vars/settings.yml new file mode 100644 index 000000000..ca6144665 --- /dev/null +++ b/apps/elasticsearch/vars/settings.yml @@ -0,0 +1 @@ +is_blue_green_compatible: False diff --git a/bin/ci-test-route b/bin/ci-test-route new file mode 100755 index 000000000..022cf78a3 --- /dev/null +++ b/bin/ci-test-route @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# +# usage: ci-test-route [SERVICE] [CONTENT] [PATH] [PREFIX] + +# First script argument is the application's service name. It defaults to +# 'hello' +service="${1:-hello}" + +# Second script argument is the message to look for in the application's service +# HTTP response. If this message has been found, it means that the application's +# service is up and running, thus validating deployment. It defaults to the +# expected 'hello' service message. +content="${2:-Hello OpenShift! by Arnold}" + +# Third script argument is the url path. It defaults to: "/" +path="${3:-"/"}" + +# Fourth script argument is the prefix used in the url. It defaults to "current". +prefix="${4:-"current"}" + +# Current URL has by definition no prefix, while next and previous URLs are +# sub-domains. Hence, we add the sub-domain dot for next and previous prefixes +# and remove the current prefix for the current URL. +if [[ "${prefix}" != "current" ]]; then + prefix="${prefix}." +else + prefix="" +fi + +# Wait for the application to respond +for try in $(seq 5); do + echo "Testing ${service} application http response ($try)" + curl -vLk --header "Accept: text/html" "https://${prefix}${service}.ci-eugene.${OPENSHIFT_DOMAIN}.nip.io${path}" 2> "/tmp/${service}.err" > "/tmp/${service}.out" + if grep "HTTP/1.1 200 OK" "/tmp/${service}.err" && grep "${content}" "/tmp/${service}.out"; then + exit 0 + fi + sleep 10 +done +exit 1 diff --git a/bin/ci-test-service b/bin/ci-test-service index b8d06f407..f2ec073ad 100755 --- a/bin/ci-test-service +++ b/bin/ci-test-service @@ -1,37 +1,49 @@ #!/usr/bin/env bash # -# usage: ci-test-service [SERVICE] [CONTENT] [PATH] [PREFIX] +# usage: ci-test-service [SERVICE] [PORT] [CONTENT] [PATH] [PREFIX] [PROTOCOL] # First script argument is the application's service name. It defaults to # 'hello' service="${1:-hello}" +# Second script argument is the port number of the service to test +port="${2:-8080}" + # Second script argument is the message to look for in the application's service # HTTP response. If this message has been found, it means that the application's # service is up and running, thus validating deployment. It defaults to the # expected 'hello' service message. -content="${2:-Hello OpenShift! by Arnold}" +content="${3:-Hello OpenShift! by Arnold}" # Third script argument is the url path. It defaults to: "/" -path="${3:-"/"}" +path="${4:-"/"}" # Fourth script argument is the prefix used in the url. It defaults to "current". -prefix="${4:-"current"}" +prefix="${5}" + +# Fifth script argument is the protocol to use with curl (http or https) +protocol=${6-http} # Current URL has by definition no prefix, while next and previous URLs are # sub-domains. Hence, we add the sub-domain dot for next and previous prefixes # and remove the current prefix for the current URL. -if [[ "${prefix}" != "current" ]]; then - prefix="${prefix}." -else - prefix="" +if [[ -n "${prefix}" ]]; then + service="${service}-${prefix}" +fi + +echo -n "Getting ClusterIP for service ${service}..." +service_ip=$(oc get "svc/${service}" -o jsonpath='{.spec.clusterIP}') +if [ -z "$service_ip" ]; then + echo "ERROR : Unable to get service IP" + exit 1 fi +echo "[${service_ip}]"; -# Wait for the application to respond +# Wait for the service to respond for try in $(seq 5); do - echo "Testing ${service} application http response ($try)" - curl -vLk --header "Accept: text/html" "https://${prefix}${service}.ci-eugene.${OPENSHIFT_DOMAIN}.nip.io${path}" 2> "/tmp/${service}.err" > "/tmp/${service}.out" - if grep "HTTP/1.1 200 OK" "/tmp/${service}.err" && grep "${content}" "/tmp/${service}.out"; then + echo "Testing ${service_ip} on port ${port} ($try)" + curl -vLk --header "Accept: text/html" "${protocol}://${service_ip}:${port}${path}" 2> "/tmp/svc-${service}.err" > "/tmp/svc-${service}.out" + if grep "HTTP/1.1 200 OK" "/tmp/svc-${service}.err" && grep "${content}" "/tmp/svc-${service}.out"; then exit 0 fi sleep 10 diff --git a/group_vars/customer/eugene/development/main.yml b/group_vars/customer/eugene/development/main.yml index 0ac57857f..4e5f42082 100644 --- a/group_vars/customer/eugene/development/main.yml +++ b/group_vars/customer/eugene/development/main.yml @@ -23,6 +23,7 @@ apps: - name: redis - name: hello - name: edxec + - name: elasticsearch # Install a custom theme for edxapp-lms edxapp_theme_url: "https://github.com/raccoongang/themes_for_themex.io" diff --git a/group_vars/customer/eugene/main.yml b/group_vars/customer/eugene/main.yml index b31cb2112..937afc326 100644 --- a/group_vars/customer/eugene/main.yml +++ b/group_vars/customer/eugene/main.yml @@ -9,3 +9,8 @@ apps: # Marsha # We don't want to require an AWS SSH key for testing marsha_should_sign_requests: false + + +# Elasticsearch +# Limit memory usage +elasticsearch_java_opts: "-Xms64m -Xmx64m" diff --git a/group_vars/env_type/ci.yml b/group_vars/env_type/ci.yml index 26425cad2..d5c1d3137 100644 --- a/group_vars/env_type/ci.yml +++ b/group_vars/env_type/ci.yml @@ -11,6 +11,7 @@ internal_docker_registry: "172.30.1.1:5000" apps: - name: edxapp - name: edxec + - name: elasticsearch - name: forum - name: hello - name: learninglocker diff --git a/group_vars/env_type/development.yml b/group_vars/env_type/development.yml index 00a1001a5..a6f0fb4d8 100644 --- a/group_vars/env_type/development.yml +++ b/group_vars/env_type/development.yml @@ -10,6 +10,7 @@ internal_docker_registry: "172.30.1.1:5000" apps: - name: edxapp - name: edxec + - name: elasticsearch - name: hello - name: learninglocker - name: mailcatcher