From 4d069f2d7404b7c16a5d81f9c486fb85d2764a14 Mon Sep 17 00:00:00 2001 From: Michael Uvarov Date: Wed, 28 Feb 2018 14:19:17 +0100 Subject: [PATCH 1/2] Run riak in a docker container for CI Add healthcheck for Docker MySQL container --- .travis.yml | 1 - src/mongoose_riak.erl | 2 +- test.disabled/ejabberd_tests/test.config | 6 + tools/db_configs/riak/riak.conf | 683 ----------------------- tools/db_configs/riak/riak.conf.ssl | 22 + tools/setup_riak | 34 +- tools/travis-setup-db.sh | 73 ++- tools/wait_for_healthcheck.sh | 47 ++ 8 files changed, 160 insertions(+), 708 deletions(-) delete mode 100644 tools/db_configs/riak/riak.conf create mode 100644 tools/db_configs/riak/riak.conf.ssl create mode 100755 tools/wait_for_healthcheck.sh diff --git a/.travis.yml b/.travis.yml index f4de2aef40..23f94594a1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,7 +38,6 @@ after_script: services: - redis-server - docker - - riak branches: only: diff --git a/src/mongoose_riak.erl b/src/mongoose_riak.erl index 666a3558ff..1cb4387eb8 100644 --- a/src/mongoose_riak.erl +++ b/src/mongoose_riak.erl @@ -58,7 +58,7 @@ start() -> {_, RiakAddr} = get_riak_opt(address, RiakOpts), {_, RiakPort} = get_riak_opt(port, RiakOpts), {_, Workers} = get_riak_opt(pool_size, RiakOpts, {pool_size, 20}), - SecurityOptsKeys = [credentials, cacertfile], + SecurityOptsKeys = [credentials, cacertfile, ssl_opts], SecurityOpts = [get_riak_opt(OptKey, RiakOpts) || OptKey <- SecurityOptsKeys], RiakPBOpts = [auto_reconnect, keepalive], diff --git a/test.disabled/ejabberd_tests/test.config b/test.disabled/ejabberd_tests/test.config index 6a4f342b37..b73b3a65c3 100644 --- a/test.disabled/ejabberd_tests/test.config +++ b/test.disabled/ejabberd_tests/test.config @@ -258,7 +258,13 @@ {riak_mnesia, [{sm_backend, "{mnesia, []}"}, {auth_method, "riak"}, + %% Specify a list of ciphers to avoid + %% "no function clause matching tls_v1:enum_to_oid(28)" error + %% on Riak's side running with Erlang R16. + %% https://github.com/basho/riak-erlang-client/issues/232#issuecomment-178612129 + %% We also set ciphers in tools/setup_riak on the server side. {riak_server, "{riak_server, [{pool_size, 5}, {address, \"127.0.0.1\"},{port, 8087}, + {ssl_opts, [{ciphers, [\"AES256-SHA\", \"DHE-RSA-AES128-SHA256\"]}]}, {credentials, \"ejabberd\", \"mongooseim_secret\"}, {cacertfile, \"priv/ssl/cacert.pem\"}]}."}, {mod_roster, "{mod_roster, [{backend, riak}]},"}, diff --git a/tools/db_configs/riak/riak.conf b/tools/db_configs/riak/riak.conf deleted file mode 100644 index 42f754cfae..0000000000 --- a/tools/db_configs/riak/riak.conf +++ /dev/null @@ -1,683 +0,0 @@ -## Where to emit the default log messages (typically at 'info' -## severity): -## off: disabled -## file: the file specified by log.console.file -## console: to standard output (seen when using `riak attach-direct`) -## both: log.console.file and standard out. -## -## Default: file -## -## Acceptable values: -## - one of: off, file, console, both -log.console = file - -## The severity level of the console log, default is 'info'. -## -## Default: info -## -## Acceptable values: -## - one of: debug, info, notice, warning, error, critical, alert, emergency, none -log.console.level = info - -## When 'log.console' is set to 'file' or 'both', the file where -## console messages will be logged. -## -## Default: $(platform_log_dir)/console.log -## -## Acceptable values: -## - the path to a file -log.console.file = $(platform_log_dir)/console.log - -## The file where error messages will be logged. -## -## Default: $(platform_log_dir)/error.log -## -## Acceptable values: -## - the path to a file -log.error.file = $(platform_log_dir)/error.log - -## When set to 'on', enables log output to syslog. -## -## Default: off -## -## Acceptable values: -## - on or off -log.syslog = off - -## Whether to enable the crash log. -## -## Default: on -## -## Acceptable values: -## - on or off -log.crash = on - -## If the crash log is enabled, the file where its messages will -## be written. -## -## Default: $(platform_log_dir)/crash.log -## -## Acceptable values: -## - the path to a file -log.crash.file = $(platform_log_dir)/crash.log - -## Maximum size in bytes of individual messages in the crash log -## -## Default: 64KB -## -## Acceptable values: -## - a byte size with units, e.g. 10GB -log.crash.maximum_message_size = 64KB - -## Maximum size of the crash log in bytes, before it is rotated -## -## Default: 10MB -## -## Acceptable values: -## - a byte size with units, e.g. 10GB -log.crash.size = 10MB - -## The schedule on which to rotate the crash log. For more -## information see: -## https://github.com/basho/lager/blob/master/README.md#internal-log-rotation -## -## Default: $D0 -## -## Acceptable values: -## - text -log.crash.rotation = $D0 - -## The number of rotated crash logs to keep. When set to -## 'current', only the current open log file is kept. -## -## Default: 5 -## -## Acceptable values: -## - an integer -## - the text "current" -log.crash.rotation.keep = 5 - -## Name of the Erlang node -## -## Default: riak@127.0.0.1 -## -## Acceptable values: -## - text -nodename = riak@127.0.0.1 - -## Cookie for distributed node communication. All nodes in the -## same cluster should use the same cookie or they will not be able to -## communicate. -## -## Default: riak -## -## Acceptable values: -## - text -distributed_cookie = riak - -## Sets the number of threads in async thread pool, valid range -## is 0-1024. If thread support is available, the default is 64. -## More information at: http://erlang.org/doc/man/erl.html -## -## Default: 64 -## -## Acceptable values: -## - an integer -erlang.async_threads = 64 - -## The number of concurrent ports/sockets -## Valid range is 1024-134217727 -## -## Default: 262144 -## -## Acceptable values: -## - an integer -erlang.max_ports = 262144 - -## Set scheduler forced wakeup interval. All run queues will be -## scanned each Interval milliseconds. While there are sleeping -## schedulers in the system, one scheduler will be woken for each -## non-empty run queue found. An Interval of zero disables this -## feature, which also is the default. -## This feature is a workaround for lengthy executing native code, and -## native code that do not bump reductions properly. -## More information: http://www.erlang.org/doc/man/erl.html#+sfwi -## -## Default: 500 -## -## Acceptable values: -## - an integer -## erlang.schedulers.force_wakeup_interval = 500 - -## Enable or disable scheduler compaction of load. By default -## scheduler compaction of load is enabled. When enabled, load -## balancing will strive for a load distribution which causes as many -## scheduler threads as possible to be fully loaded (i.e., not run out -## of work). This is accomplished by migrating load (e.g. runnable -## processes) into a smaller set of schedulers when schedulers -## frequently run out of work. When disabled, the frequency with which -## schedulers run out of work will not be taken into account by the -## load balancing logic. -## More information: http://www.erlang.org/doc/man/erl.html#+scl -## -## Default: false -## -## Acceptable values: -## - one of: true, false -## erlang.schedulers.compaction_of_load = false - -## Enable or disable scheduler utilization balancing of load. By -## default scheduler utilization balancing is disabled and instead -## scheduler compaction of load is enabled which will strive for a -## load distribution which causes as many scheduler threads as -## possible to be fully loaded (i.e., not run out of work). When -## scheduler utilization balancing is enabled the system will instead -## try to balance scheduler utilization between schedulers. That is, -## strive for equal scheduler utilization on all schedulers. -## More information: http://www.erlang.org/doc/man/erl.html#+sub -## -## Acceptable values: -## - one of: true, false -## erlang.schedulers.utilization_balancing = true - -## Number of partitions in the cluster (only valid when first -## creating the cluster). Must be a power of 2, minimum 8 and maximum -## 1024. -## -## Default: 64 -## -## Acceptable values: -## - an integer -## ring_size = 64 - -## Number of concurrent node-to-node transfers allowed. -## -## Default: 2 -## -## Acceptable values: -## - an integer -## transfer_limit = 2 - -## Default cert location for https can be overridden -## with the ssl config variable, for example: -## -## Acceptable values: -## - the path to a file -ssl.certfile = $(platform_etc_dir)/cert.pem - -## Default key location for https can be overridden with the ssl -## config variable, for example: -## -## Acceptable values: -## - the path to a file -ssl.keyfile = $(platform_etc_dir)/key.pem - -## Default signing authority location for https can be overridden -## with the ssl config variable, for example: -## -## Acceptable values: -## - the path to a file -ssl.cacertfile = $(platform_etc_dir)/cacertfile.pem - -## DTrace support Do not enable 'dtrace' unless your Erlang/OTP -## runtime is compiled to support DTrace. DTrace is available in -## R15B01 (supported by the Erlang/OTP official source package) and in -## R14B04 via a custom source repository & branch. -## -## Default: off -## -## Acceptable values: -## - on or off -dtrace = off - -## Platform-specific installation paths (substituted by rebar) -## -## Default: /usr/sbin -## -## Acceptable values: -## - the path to a directory -platform_bin_dir = /usr/sbin - -## -## Default: /var/lib/riak -## -## Acceptable values: -## - the path to a directory -platform_data_dir = /var/lib/riak - -## -## Default: /etc/riak -## -## Acceptable values: -## - the path to a directory -platform_etc_dir = /etc/riak - -## -## Default: /usr/lib/riak/lib -## -## Acceptable values: -## - the path to a directory -platform_lib_dir = /usr/lib/riak/lib - -## -## Default: /var/log/riak -## -## Acceptable values: -## - the path to a directory -platform_log_dir = /var/log/riak - -## Enable consensus subsystem. Set to 'on' to enable the -## consensus subsystem used for strongly consistent Riak operations. -## -## Default: off -## -## Acceptable values: -## - on or off -## strong_consistency = on - -## listener.http. is an IP address and TCP port that the Riak -## HTTP interface will bind. -## -## Default: 127.0.0.1:8098 -## -## Acceptable values: -## - an IP/port pair, e.g. 127.0.0.1:10011 -listener.http.internal = 127.0.0.1:8098 - -## listener.protobuf. is an IP address and TCP port that the Riak -## Protocol Buffers interface will bind. -## -## Default: 127.0.0.1:8087 -## -## Acceptable values: -## - an IP/port pair, e.g. 127.0.0.1:10011 -listener.protobuf.internal = 127.0.0.1:8087 - -## The maximum length to which the queue of pending connections -## may grow. If set, it must be an integer > 0. If you anticipate a -## huge number of connections being initialized *simultaneously*, set -## this number higher. -## -## Default: 128 -## -## Acceptable values: -## - an integer -## protobuf.backlog = 128 - -## listener.https. is an IP address and TCP port that the Riak -## HTTPS interface will bind. -## -## Acceptable values: -## - an IP/port pair, e.g. 127.0.0.1:10011 -## listener.https.internal = 127.0.0.1:8098 - -## How Riak will repair out-of-sync keys. Some features require -## this to be set to 'active', including search. -## * active: out-of-sync keys will be repaired in the background -## * passive: out-of-sync keys are only repaired on read -## * active-debug: like active, but outputs verbose debugging -## information -## -## Default: active -## -## Acceptable values: -## - one of: active, passive, active-debug -anti_entropy = active - -## Specifies the storage engine used for Riak's key-value data -## and secondary indexes (if supported). -## -## Default: bitcask -## -## Acceptable values: -## - one of: bitcask, leveldb, memory, multi, prefix_multi -storage_backend = leveldb - -## Simplify prefix_multi configuration for Riak CS. Keep this -## commented out unless Riak is configured for Riak CS. -## -## Acceptable values: -## - an integer -## cs_version = 20000 - -## Controls which binary representation of a riak value is stored -## on disk. -## * 0: Original erlang:term_to_binary format. Higher space overhead. -## * 1: New format for more compact storage of small values. -## -## Default: 1 -## -## Acceptable values: -## - the integer 1 -## - the integer 0 -object.format = 1 - -## Reading or writing objects bigger than this size will write a -## warning in the logs. -## -## Default: 5MB -## -## Acceptable values: -## - a byte size with units, e.g. 10GB -object.size.warning_threshold = 5MB - -## Writing an object bigger than this will send a failure to the -## client. -## -## Default: 50MB -## -## Acceptable values: -## - a byte size with units, e.g. 10GB -object.size.maximum = 50MB - -## Writing an object with more than this number of siblings will -## generate a warning in the logs. -## -## Default: 25 -## -## Acceptable values: -## - an integer -object.siblings.warning_threshold = 25 - -## Writing an object with more than this number of siblings will -## send a failure to the client. -## -## Default: 100 -## -## Acceptable values: -## - an integer -object.siblings.maximum = 100 - -## Whether to allow list buckets. -## -## Default: enabled -## -## Acceptable values: -## - enabled or disabled -## cluster.job.riak_kv.list_buckets = enabled - -## Whether to allow streaming list buckets. -## -## Default: enabled -## -## Acceptable values: -## - enabled or disabled -## cluster.job.riak_kv.stream_list_buckets = enabled - -## Whether to allow list keys. -## -## Default: enabled -## -## Acceptable values: -## - enabled or disabled -## cluster.job.riak_kv.list_keys = enabled - -## Whether to allow streaming list keys. -## -## Default: enabled -## -## Acceptable values: -## - enabled or disabled -## cluster.job.riak_kv.stream_list_keys = enabled - -## Whether to allow secondary index queries. -## -## Default: enabled -## -## Acceptable values: -## - enabled or disabled -## cluster.job.riak_kv.secondary_index = enabled - -## Whether to allow streaming secondary index queries. -## -## Default: enabled -## -## Acceptable values: -## - enabled or disabled -## cluster.job.riak_kv.stream_secondary_index = enabled - -## Whether to allow term-based map-reduce. -## -## Default: enabled -## -## Acceptable values: -## - enabled or disabled -## cluster.job.riak_kv.map_reduce = enabled - -## Whether to allow JavaScript map-reduce. -## -## Default: enabled -## -## Acceptable values: -## - enabled or disabled -## cluster.job.riak_kv.map_reduce_js = enabled - -## A path under which bitcask data files will be stored. -## -## Default: $(platform_data_dir)/bitcask -## -## Acceptable values: -## - the path to a directory -bitcask.data_root = $(platform_data_dir)/bitcask - -## Configure how Bitcask writes data to disk. -## erlang: Erlang's built-in file API -## nif: Direct calls to the POSIX C API -## The NIF mode provides higher throughput for certain -## workloads, but has the potential to negatively impact -## the Erlang VM, leading to higher worst-case latencies -## and possible throughput collapse. -## -## Default: erlang -## -## Acceptable values: -## - one of: erlang, nif -bitcask.io_mode = erlang - -## Set to 'off' to disable the admin panel. -## -## Default: off -## -## Acceptable values: -## - on or off -riak_control = off - -## Authentication mode used for access to the admin panel. -## -## Default: off -## -## Acceptable values: -## - one of: off, userlist -riak_control.auth.mode = off - -## If riak control's authentication mode (riak_control.auth.mode) -## is set to 'userlist' then this is the list of usernames and -## passwords for access to the admin panel. -## To create users with given names, add entries of the format: -## riak_control.auth.user.USERNAME.password = PASSWORD -## replacing USERNAME with the desired username and PASSWORD with the -## desired password for that user. -## -## Acceptable values: -## - text -## riak_control.auth.user.admin.password = pass - -## This parameter defines the percentage of total server memory -## to assign to LevelDB. LevelDB will dynamically adjust its internal -## cache sizes to stay within this size. The memory size can -## alternately be assigned as a byte count via leveldb.maximum_memory -## instead. -## -## Default: 70 -## -## Acceptable values: -## - an integer -leveldb.maximum_memory.percent = 70 - -## Enables or disables the compression of data on disk. -## Enabling (default) saves disk space. Disabling may reduce read -## latency but increase overall disk activity. Option can be -## changed at any time, but will not impact data on disk until -## next time a file requires compaction. -## -## Default: on -## -## Acceptable values: -## - on or off -leveldb.compression = on - -## Selection of compression algorithms. snappy is -## original compression supplied for leveldb. lz4 is new -## algorithm that compresses to similar volume but averages twice -## as fast on writes and four times as fast on reads. -## -## Acceptable values: -## - one of: snappy, lz4 -leveldb.compression.algorithm = lz4 - -## -## Default: on -## -## Acceptable values: -## - on or off -## multi_backend.name.leveldb.compression = on - -## -## Acceptable values: -## - one of: snappy, lz4 -## multi_backend.name.leveldb.compression.algorithm = lz4 - -## Whether to allow search queries. -## -## Default: enabled -## -## Acceptable values: -## - enabled or disabled -## cluster.job.riak_search.query = enabled - -## To enable Search set this 'on'. -## -## Default: off -## -## Acceptable values: -## - on or off -search = on - -## How long Riak will wait for Solr to start. The start sequence -## will be tried twice. If both attempts timeout, then the Riak node -## will be shutdown. This may need to be increased as more data is -## indexed and Solr takes longer to start. Values lower than 1s will -## be rounded up to the minimum 1s. -## -## Default: 30s -## -## Acceptable values: -## - a time duration with units, e.g. '10s' for 10 seconds -search.solr.start_timeout = 30s - -## The port number which Solr binds to. -## NOTE: Binds on every interface. -## -## Default: 8093 -## -## Acceptable values: -## - an integer -search.solr.port = 18093 - -## The port number which Solr JMX binds to. -## NOTE: Binds on every interface. -## -## Default: 8985 -## -## Acceptable values: -## - an integer -search.solr.jmx_port = 8985 - -## The options to pass to the Solr JVM. Non-standard options, -## i.e. -XX, may not be portable across JVM implementations. -## E.g. -XX:+UseCompressedStrings -## -## Default: -d64 -Xms1g -Xmx1g -XX:+UseStringCache -XX:+UseCompressedOops -## -## Acceptable values: -## - text -search.solr.jvm_options = -d64 -Xms1g -Xmx1g -XX:+UseStringCache -XX:+UseCompressedOops - -## The minimum batch size, in number of Riak objects. Any batches that -## are smaller than this amount will not be immediately flushed to Solr, -## but are guaranteed to be flushed within the -## "search.queue.batch.flush_interval". -## -## Default: 10 -## -## Acceptable values: -## - an integer -## search.queue.batch.minimum = 10 - -## The maximum batch size, in number of Riak objects. Any batches that are -## larger than this amount will be split, where the first -## search.queue.batch.maximum set of objects will be flushed to Solr, and -## the remaining objects enqueued for that index will be retained until the -## next batch is delivered. This parameter ensures that at most -## "search.queue.batch.maximum object" will be delivered into Solr in any -## given request. -## -## Default: 500 -## -## Acceptable values: -## - an integer -## search.queue.batch.maximum = 500 - -## The maximum delay between notification to flush batches to Solr. This -## setting is used to increase or decrease the frequency of batch delivery -## into Solr, specifically for relatively low-volume input into Riak. This -## setting ensures that data will be delivered into Solr in accordance with -## the "search.queue.batch.minimum" and "search.queue.batch.maximum" -## settings within the specified interval. Batches that are smaller than -## "search.queue.batch.minimum" will be delivered to Solr within this -## interval. This setting will generally hav no effect on heavily loaded -## systems. -## -## Default: 500ms -## -## Acceptable values: -## - a time duration with units, e.g. '10s' for 10 seconds -## - the text "infinity" -## search.queue.batch.flush_interval = 500ms - -## The queue high watermark. If the total number of queued messages in a -## Solr Queue Worker instance exceeds this limit, then the calling vnode -## will be blocked until the total number falls below this limit. This -## parameter exercises flow control between Riak and the Riak -## Search batching subsystem if writes into Solr start to fall behind. -## -## Default: 1000 -## -## Acceptable values: -## - an integer -## search.queue.high_watermark = 1000 - -## The strategy for how we handle purging when we hit the -## search.queue.high_watermark. -## - purge_one -> Removes the oldest item on the queue from an -## erroring (references to fuses blown in the code) index in -## order to get below the search.queue.high_watermark. -## - purge_index -> Removes all items associated with one random -## erroring (references to fuses blown in the code) index in -## order to get below the search.queue.high_watermark. -## - off -> purging is disabled -## -## Default: purge_one -## -## Acceptable values: -## - one of: purge_one, purge_index, off -## search.queue.high_watermark.purge_strategy = purge_one - -## Whether to allow Yokozuna queries on this node -## -## Default: enabled -## -## Acceptable values: -## - enabled or disabled -## cluster.job.yokozuna.query = enabled - diff --git a/tools/db_configs/riak/riak.conf.ssl b/tools/db_configs/riak/riak.conf.ssl new file mode 100644 index 0000000000..44a16efac0 --- /dev/null +++ b/tools/db_configs/riak/riak.conf.ssl @@ -0,0 +1,22 @@ +## Contains a part of riak.conf, that enables SSL connections + +## Default cert location for https can be overridden +## with the ssl config variable, for example: +## +## Acceptable values: +## - the path to a file +ssl.certfile = $(platform_etc_dir)/cert.pem + +## Default key location for https can be overridden with the ssl +## config variable, for example: +## +## Acceptable values: +## - the path to a file +ssl.keyfile = $(platform_etc_dir)/key.pem + +## Default signing authority location for https can be overridden +## with the ssl config variable, for example: +## +## Acceptable values: +## - the path to a file +ssl.cacertfile = $(platform_etc_dir)/cacertfile.pem diff --git a/tools/setup_riak b/tools/setup_riak index 665d2a9a04..f1a0b20260 100755 --- a/tools/setup_riak +++ b/tools/setup_riak @@ -1,16 +1,23 @@ #!/bin/bash +# Optional env variables: +# - RIAK_ADMIN - riak admin command +# - RIAK_HOST +# - RIAK_PORT +# - RIAK_PASSWORD -sleep 20 +set -e RIAK_HOST=${RIAK_HOST:-"localhost"} RIAK_PORT=${RIAK_PORT:-"8098"} RIAK_HOST="http://${RIAK_HOST}:${RIAK_PORT}" +RIAK_PASSWORD="${RIAK_PASSWORD:-mongooseim_secret}" RIAK_VCARD_SCHEMA_PATH=${RIAK_VCARD_SCHEMA_PATH:-"tools/vcard_search_schema.xml"} RIAK_MAM_SCHEMA_PATH=${RIAK_MAM_SCHEMA_PATH:-"tools/mam_search_schema.xml"} RIAK_CONTAINER_NAME=${RIAK_CONTAINER_NAME:-"mongooseim-riak"} + curl -v -XPUT $RIAK_HOST/search/schema/vcard \ -H 'Content-Type:application/xml' \ --data-binary @${RIAK_VCARD_SCHEMA_PATH} @@ -31,9 +38,9 @@ curl -v -XPUT $RIAK_HOST/search/index/mam \ -H 'Content-Type: application/json' \ -d '{"schema":"mam"}' -sleep 20 - -RIAK_ADMIN="riak-admin" +# Allow to pass RIAK_ADMIN as an env variable. +# Use riak-admin as a default command. +RIAK_ADMIN="${RIAK_ADMIN:-riak-admin}" RIAK_USER_PERMISSIONS=riak_kv.get,riak_kv.put,riak_kv.delete,riak_kv.index, RIAK_USER_PERMISSIONS+=riak_kv.list_keys,riak_kv.list_buckets,riak_kv.mapreduce, @@ -42,7 +49,7 @@ RIAK_USER_PERMISSIONS+=riak_core.get_bucket_type,search.admin,search.query $RIAK_ADMIN security enable -$RIAK_ADMIN security add-user ejabberd password=$1 +$RIAK_ADMIN security add-user ejabberd password="$RIAK_PASSWORD" $RIAK_ADMIN security add-source all 127.0.0.1/32 password @@ -80,3 +87,20 @@ $RIAK_ADMIN bucket-type activate privacy_lists_names $RIAK_ADMIN bucket-type create privacy_lists '{"props":{"last_write_wins":true,"dvv_enabled":false}}' $RIAK_ADMIN bucket-type activate privacy_lists + +# Specify a list of ciphers to avoid +# "no function clause matching tls_v1:enum_to_oid(28)" error +# on Riak's side running with Erlang R16. +# https://github.com/basho/riak-erlang-client/issues/232#issuecomment-178612129 +# We also set ciphers in ejabberd.cfg +# (see test.config presets in the big test directory). +$RIAK_ADMIN security ciphers "AES256-SHA:DHE-RSA-AES128-SHA256" + +# Allow connections from ejabberd, otherwise you will get +# a hidden "Authentication failed" error. +# +# If you see "disconnected" error, than trace riakc_pb_socket +# recon_trace:calls({riakc_pb_socket, start_auth, '_'}, 50, [{scope, local}]). +# +# In the process state of riakc process there is an orddict with a list of errors. +$RIAK_ADMIN security add-source ejabberd "0.0.0.0/0" password diff --git a/tools/travis-setup-db.sh b/tools/travis-setup-db.sh index 0d9a610905..5c3406d969 100755 --- a/tools/travis-setup-db.sh +++ b/tools/travis-setup-db.sh @@ -1,8 +1,11 @@ -#!/bin/bash +#!/usr/bin/env bash -TOOLS=`dirname $0` +# Environment variable DB is used by this script. +# If DB is undefined, than this script does nothing. + +set -e -echo $DB +TOOLS=`dirname $0` source tools/travis-common-vars.sh @@ -16,12 +19,11 @@ MYSQL_DIR=/etc/mysql/conf.d PGSQL_ODBC_CERT_DIR=~/.postgresql -RIAK_DIR=/etc/riak - SSLDIR=${BASE}/${TOOLS}/ssl -if [ $DB = 'mysql' ]; then +if [ "$DB" = 'mysql' ]; then echo "Configuring mysql" + # TODO We should not use sudo sudo -n service mysql stop || echo "Failed to stop mysql" mkdir -p ${SQL_TEMP_DIR} cp ${SSLDIR}/fake_cert.pem ${SQL_TEMP_DIR}/. @@ -36,9 +38,10 @@ if [ $DB = 'mysql' ]; then -v ${MIM_PRIV_DIR}/mysql.sql:/docker-entrypoint-initdb.d/mysql.sql:ro \ -v ${BASE}/${TOOLS}/docker-setup-mysql.sh:/docker-entrypoint-initdb.d/docker-setup-mysql.sh \ -v ${SQL_TEMP_DIR}:${SQL_TEMP_DIR} \ + --health-cmd='mysqladmin ping --silent' \ -p 3306:3306 --name=mongooseim-mysql mysql -elif [ $DB = 'pgsql' ]; then +elif [ "$DB" = 'pgsql' ]; then echo "Configuring postgres with SSL" sudo service postgresql stop || echo "Failed to stop psql" mkdir ${SQL_TEMP_DIR} @@ -68,18 +71,50 @@ Debug = 1 ByteaAsLongVarBinary = 1 EOL -elif [ $DB = 'riak' ]; then +elif [ "$DB" = 'riak' ]; then echo "Configuring Riak with SSL" - sudo cp ${SSLDIR}/fake_cert.pem ${RIAK_DIR}/cert.pem - sudo cp ${SSLDIR}/fake_key.pem ${RIAK_DIR}/key.pem - sudo cp ${SSLDIR}/ca/cacert.pem ${RIAK_DIR}/cacertfile.pem - sudo cp ${DB_CONF_DIR}/advanced.config ${RIAK_DIR}/advanced.config - sudo cp ${DB_CONF_DIR}/riak.conf ${RIAK_DIR}/riak.conf - sudo service riak restart - echo "Setup Riak" - sudo tools/setup_riak mongooseim_secret - -elif [ $DB = 'cassandra' ]; then + # Instead of docker run, use "docker create" + "docker start". + # So we can prepare our container. + # We use HEALTHCHECK here, check "docker ps" to get healthcheck status. + # We can't use volumes for riak.conf, because: + # - we want to change it + # - container starting code runs sed on it and gets IO error, + # if it's a volume + time docker create -p 8087:8087 -p 8098:8098 \ + -e DOCKER_RIAK_BACKEND=leveldb \ + -e DOCKER_RIAK_CLUSTER_SIZE=1 \ + --name=mongooseim-riak \ + -v "${DB_CONF_DIR}/advanced.config:/etc/riak/advanced.config:ro" \ + -v "${SSLDIR}/fake_cert.pem:/etc/riak/cert.pem:ro" \ + -v "${SSLDIR}/fake_key.pem:/etc/riak/key.pem:ro" \ + -v "${SSLDIR}/ca/cacert.pem:/etc/riak/ca/cacertfile.pem:ro" \ + --health-cmd='riak-admin status' \ + "michalwski/docker-riak:1.0.6" + # Use a temporary file to store config + TEMP_RIAK_CONF=$(mktemp) + # Export config from a container + docker cp "mongooseim-riak:/etc/riak/riak.conf" "$TEMP_RIAK_CONF" + # Enable search + sed -i "s/^search = \(.*\)/search = on/" "$TEMP_RIAK_CONF" + # Enable ssl by appending settings from riak.conf.ssl + cat "${DB_CONF_DIR}/riak.conf.ssl" >> "$TEMP_RIAK_CONF" + # Import config back into container + docker cp "$TEMP_RIAK_CONF" "mongooseim-riak:/etc/riak/riak.conf" + # Erase temporary config file + rm "$TEMP_RIAK_CONF" + docker start mongooseim-riak + echo "Waiting for docker healthcheck" + echo "" + time tools/wait_for_healthcheck.sh mongooseim-riak + echo "Waiting for a listener to appear" + tools/wait_for_service.sh mongooseim-riak 8098 + # Use riak-admin from inside the container + export RIAK_ADMIN="docker exec mongooseim-riak riak-admin" + tools/setup_riak + # Use this command to read Riak's logs if something goes wrong + # docker exec -it mongooseim-riak bash -c 'tail -f /var/log/riak/*' + +elif [ "$DB" = 'cassandra' ]; then docker image pull cassandra:${CASSANDRA_VERSION} opts="$(docker inspect -f '{{range .Config.Entrypoint}}{{println}}{{.}}{{end}}' cassandra:${CASSANDRA_VERSION})" @@ -108,4 +143,6 @@ elif [ $DB = 'cassandra' ]; then --link cassandra:cassandra \ cassandra:${CASSANDRA_VERSION} \ sh -c 'exec cqlsh "$CASSANDRA_PORT_9042_TCP_ADDR" --ssl -f /cassandra.cql' +else + echo "Skip setting up database" fi diff --git a/tools/wait_for_healthcheck.sh b/tools/wait_for_healthcheck.sh new file mode 100755 index 0000000000..7406964df2 --- /dev/null +++ b/tools/wait_for_healthcheck.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# Waiting for a running container to become healthy. +# Waits if no container was found with reason "no such object". +# Waits if the container does not healthcheck configured. +# Fails if this script runs for too long with the reason "Killed by timeout". +# +# Usage example: +# ./tools/wait_for_healthcheck.sh mongooseim-riak +# or +# ./tools/wait_for_healthcheck.sh "$CONTAINER" +# +# with 5 seconds timeout: +# TIMEOUT=5 ./tools/wait_for_healthcheck.sh "$CONTAINER" + +set -e + +if [ "$#" -ne 1 ]; then + exit "Illegal number of parameters" +fi +CONTAINER="$1" + +# Default timeout is 1 minute +TIMEOUT="${TIMEOUT:-60}" + +# Stop waiting after timeout using a background task +MAIN_PID=$BASHPID +(sleep "$TIMEOUT"; echo ""; echo "Killed by timeout"; kill $MAIN_PID) & +# Get pid of a background task +KILLER_PID=$! +# Kill the process on exit +trap "kill $KILLER_PID" EXIT + +# Gets a health check of a container +# Usage example: +# health_status "$CONTAINER" +function health_status +{ + docker inspect --format '{{json .State.Health.Status }}' "$1" +} + +while [ $(health_status "$CONTAINER")"" != "\"healthy\"" ] +do + printf "." + sleep 1 +done +echo "" +echo "Waiting is done" From 41b91f7804507b49f96007e18024309e7be05db1 Mon Sep 17 00:00:00 2001 From: Michael Uvarov Date: Thu, 1 Mar 2018 13:42:16 +0100 Subject: [PATCH 2/2] Update wait_for_healthcheck.sh code and docs --- tools/travis-setup-db.sh | 2 +- tools/wait_for_healthcheck.sh | 41 ++++++++++++++++++++++++----------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/tools/travis-setup-db.sh b/tools/travis-setup-db.sh index 5c3406d969..c896c46192 100755 --- a/tools/travis-setup-db.sh +++ b/tools/travis-setup-db.sh @@ -105,7 +105,7 @@ elif [ "$DB" = 'riak' ]; then docker start mongooseim-riak echo "Waiting for docker healthcheck" echo "" - time tools/wait_for_healthcheck.sh mongooseim-riak + tools/wait_for_healthcheck.sh mongooseim-riak echo "Waiting for a listener to appear" tools/wait_for_service.sh mongooseim-riak 8098 # Use riak-admin from inside the container diff --git a/tools/wait_for_healthcheck.sh b/tools/wait_for_healthcheck.sh index 7406964df2..117743bd9d 100755 --- a/tools/wait_for_healthcheck.sh +++ b/tools/wait_for_healthcheck.sh @@ -9,8 +9,28 @@ # or # ./tools/wait_for_healthcheck.sh "$CONTAINER" # +# TIMEOUT argument documentation +# ------------------------------ +# +# TIMEOUT is number of times we try to get healthcheck status. +# Because we wait one second between tries, it can be interpreted as +# number of seconds we wait. +# # with 5 seconds timeout: # TIMEOUT=5 ./tools/wait_for_healthcheck.sh "$CONTAINER" +# +# If call to docker daemon gets blocked for a long time +# (for example, if docker daemon is down), +# that TIMEOUT would not work as expected. +# +# If "docker inspect" takes some time to execute, than TIMEOUT does not work +# as expected. +# +# This command always fails: +# TIMEOUT=0 ./tools/wait_for_healthcheck.sh "$CONTAINER" +# +# This command would try to get healthcheck status once: +# TIMEOUT=1 ./tools/wait_for_healthcheck.sh "$CONTAINER" set -e @@ -22,14 +42,6 @@ CONTAINER="$1" # Default timeout is 1 minute TIMEOUT="${TIMEOUT:-60}" -# Stop waiting after timeout using a background task -MAIN_PID=$BASHPID -(sleep "$TIMEOUT"; echo ""; echo "Killed by timeout"; kill $MAIN_PID) & -# Get pid of a background task -KILLER_PID=$! -# Kill the process on exit -trap "kill $KILLER_PID" EXIT - # Gets a health check of a container # Usage example: # health_status "$CONTAINER" @@ -38,10 +50,13 @@ function health_status docker inspect --format '{{json .State.Health.Status }}' "$1" } -while [ $(health_status "$CONTAINER")"" != "\"healthy\"" ] -do - printf "." +for i in $(seq 0 ${TIMEOUT}); do + if [ $(health_status "$CONTAINER")"" = "\"healthy\"" ]; then + echo -e "\nWaiting is done after $i seconds" + exit 0 + fi + echo -n "." sleep 1 done -echo "" -echo "Waiting is done" +echo -e "\nKilled by timeout" +exit 1