diff --git a/test/docker/README.md b/test/docker/README.md new file mode 100644 index 000000000..01bdeb832 --- /dev/null +++ b/test/docker/README.md @@ -0,0 +1,26 @@ +# Docker database images to run ejabberd tests + +You can start the Docker environment with Docker Compose, from ejabberd repository root. + +The following command will launch MySQL, PostgreSQL, Redis and Riak, and keep the console +attached to it. + +``` +mkdir test/docker/db/mysql/data +mkdir test/docker/db/postgres/data +mkdir test/docker/db/riak/data +(cd test/docker; docker-compose up) +``` + +You can stop all the databases with CTRL-C. + +You can fully clean up the environment with: + +``` +(cd test/docker; docker-compose down) +``` + +## TODO + +- Document how to fully clean the test data. + diff --git a/test/docker/db/mysql/initdb/mysql.sql b/test/docker/db/mysql/initdb/mysql.sql new file mode 100644 index 000000000..a05f8c86c --- /dev/null +++ b/test/docker/db/mysql/initdb/mysql.sql @@ -0,0 +1,465 @@ +-- +-- ejabberd, Copyright (C) 2002-2019 ProcessOne +-- +-- This program is free software; you can redistribute it and/or +-- modify it under the terms of the GNU General Public License as +-- published by the Free Software Foundation; either version 2 of the +-- License, or (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-- General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License along +-- with this program; if not, write to the Free Software Foundation, Inc., +-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +-- + +CREATE TABLE users ( + username varchar(191) PRIMARY KEY, + password text NOT NULL, + serverkey varchar(64) NOT NULL DEFAULT '', + salt varchar(64) NOT NULL DEFAULT '', + iterationcount integer NOT NULL DEFAULT 0, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- Add support for SCRAM auth to a database created before ejabberd 16.03: +-- ALTER TABLE users ADD COLUMN serverkey varchar(64) NOT NULL DEFAULT ''; +-- ALTER TABLE users ADD COLUMN salt varchar(64) NOT NULL DEFAULT ''; +-- ALTER TABLE users ADD COLUMN iterationcount integer NOT NULL DEFAULT 0; + +CREATE TABLE last ( + username varchar(191) PRIMARY KEY, + seconds text NOT NULL, + state text NOT NULl +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + + +CREATE TABLE rosterusers ( + username varchar(191) NOT NULL, + jid varchar(191) NOT NULL, + nick text NOT NULL, + subscription character(1) NOT NULL, + ask character(1) NOT NULL, + askmessage text NOT NULL, + server character(1) NOT NULL, + subscribe text NOT NULL, + type text, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE UNIQUE INDEX i_rosteru_user_jid ON rosterusers(username(75), jid(75)); +CREATE INDEX i_rosteru_username ON rosterusers(username); +CREATE INDEX i_rosteru_jid ON rosterusers(jid); + +CREATE TABLE rostergroups ( + username varchar(191) NOT NULL, + jid varchar(191) NOT NULL, + grp text NOT NULL +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE INDEX pk_rosterg_user_jid ON rostergroups(username(75), jid(75)); + +CREATE TABLE sr_group ( + name varchar(191) NOT NULL, + opts text NOT NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE TABLE sr_user ( + jid varchar(191) NOT NULL, + grp varchar(191) NOT NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE UNIQUE INDEX i_sr_user_jid_group ON sr_user(jid(75), grp(75)); +CREATE INDEX i_sr_user_jid ON sr_user(jid); +CREATE INDEX i_sr_user_grp ON sr_user(grp); + +CREATE TABLE spool ( + username varchar(191) NOT NULL, + xml mediumtext NOT NULL, + seq BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE INDEX i_despool USING BTREE ON spool(username); +CREATE INDEX i_spool_created_at USING BTREE ON spool(created_at); + +CREATE TABLE archive ( + username varchar(191) NOT NULL, + timestamp BIGINT UNSIGNED NOT NULL, + peer varchar(191) NOT NULL, + bare_peer varchar(191) NOT NULL, + xml mediumtext NOT NULL, + txt mediumtext, + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE, + kind varchar(10), + nick varchar(191), + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE FULLTEXT INDEX i_text ON archive(txt); +CREATE INDEX i_username_timestamp USING BTREE ON archive(username(191), timestamp); +CREATE INDEX i_username_peer USING BTREE ON archive(username(191), peer(191)); +CREATE INDEX i_username_bare_peer USING BTREE ON archive(username(191), bare_peer(191)); +CREATE INDEX i_timestamp USING BTREE ON archive(timestamp); + +CREATE TABLE archive_prefs ( + username varchar(191) NOT NULL PRIMARY KEY, + def text NOT NULL, + always text NOT NULL, + never text NOT NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE TABLE vcard ( + username varchar(191) PRIMARY KEY, + vcard mediumtext NOT NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE TABLE vcard_search ( + username varchar(191) NOT NULL, + lusername varchar(191) PRIMARY KEY, + fn text NOT NULL, + lfn varchar(191) NOT NULL, + family text NOT NULL, + lfamily varchar(191) NOT NULL, + given text NOT NULL, + lgiven varchar(191) NOT NULL, + middle text NOT NULL, + lmiddle varchar(191) NOT NULL, + nickname text NOT NULL, + lnickname varchar(191) NOT NULL, + bday text NOT NULL, + lbday varchar(191) NOT NULL, + ctry text NOT NULL, + lctry varchar(191) NOT NULL, + locality text NOT NULL, + llocality varchar(191) NOT NULL, + email text NOT NULL, + lemail varchar(191) NOT NULL, + orgname text NOT NULL, + lorgname varchar(191) NOT NULL, + orgunit text NOT NULL, + lorgunit varchar(191) NOT NULL +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE INDEX i_vcard_search_lfn ON vcard_search(lfn); +CREATE INDEX i_vcard_search_lfamily ON vcard_search(lfamily); +CREATE INDEX i_vcard_search_lgiven ON vcard_search(lgiven); +CREATE INDEX i_vcard_search_lmiddle ON vcard_search(lmiddle); +CREATE INDEX i_vcard_search_lnickname ON vcard_search(lnickname); +CREATE INDEX i_vcard_search_lbday ON vcard_search(lbday); +CREATE INDEX i_vcard_search_lctry ON vcard_search(lctry); +CREATE INDEX i_vcard_search_llocality ON vcard_search(llocality); +CREATE INDEX i_vcard_search_lemail ON vcard_search(lemail); +CREATE INDEX i_vcard_search_lorgname ON vcard_search(lorgname); +CREATE INDEX i_vcard_search_lorgunit ON vcard_search(lorgunit); + +CREATE TABLE privacy_default_list ( + username varchar(191) PRIMARY KEY, + name varchar(191) NOT NULL +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE TABLE privacy_list ( + username varchar(191) NOT NULL, + name varchar(191) NOT NULL, + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE INDEX i_privacy_list_username USING BTREE ON privacy_list(username); +CREATE UNIQUE INDEX i_privacy_list_username_name USING BTREE ON privacy_list (username(75), name(75)); + +CREATE TABLE privacy_list_data ( + id bigint, + t character(1) NOT NULL, + value text NOT NULL, + action character(1) NOT NULL, + ord NUMERIC NOT NULL, + match_all boolean NOT NULL, + match_iq boolean NOT NULL, + match_message boolean NOT NULL, + match_presence_in boolean NOT NULL, + match_presence_out boolean NOT NULL +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE INDEX i_privacy_list_data_id ON privacy_list_data(id); + +CREATE TABLE private_storage ( + username varchar(191) NOT NULL, + namespace varchar(191) NOT NULL, + data text NOT NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE INDEX i_private_storage_username USING BTREE ON private_storage(username); +CREATE UNIQUE INDEX i_private_storage_username_namespace USING BTREE ON private_storage(username(75), namespace(75)); + +-- Not tested in mysql +CREATE TABLE roster_version ( + username varchar(191) PRIMARY KEY, + version text NOT NULL +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- To update from 1.x: +-- ALTER TABLE rosterusers ADD COLUMN askmessage text AFTER ask; +-- UPDATE rosterusers SET askmessage = ''; +-- ALTER TABLE rosterusers ALTER COLUMN askmessage SET NOT NULL; + +CREATE TABLE pubsub_node ( + host text NOT NULL, + node text NOT NULL, + parent VARCHAR(191) NOT NULL DEFAULT '', + plugin text NOT NULL, + nodeid bigint auto_increment primary key +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +CREATE INDEX i_pubsub_node_parent ON pubsub_node(parent(120)); +CREATE UNIQUE INDEX i_pubsub_node_tuple ON pubsub_node(host(71), node(120)); + +CREATE TABLE pubsub_node_option ( + nodeid bigint, + name text NOT NULL, + val text NOT NULL +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +CREATE INDEX i_pubsub_node_option_nodeid ON pubsub_node_option(nodeid); +ALTER TABLE `pubsub_node_option` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE; + +CREATE TABLE pubsub_node_owner ( + nodeid bigint, + owner text NOT NULL +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +CREATE INDEX i_pubsub_node_owner_nodeid ON pubsub_node_owner(nodeid); +ALTER TABLE `pubsub_node_owner` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE; + +CREATE TABLE pubsub_state ( + nodeid bigint, + jid text NOT NULL, + affiliation character(1), + subscriptions VARCHAR(191) NOT NULL DEFAULT '', + stateid bigint auto_increment primary key +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +CREATE INDEX i_pubsub_state_jid ON pubsub_state(jid(60)); +CREATE UNIQUE INDEX i_pubsub_state_tuple ON pubsub_state(nodeid, jid(60)); +ALTER TABLE `pubsub_state` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE; + +CREATE TABLE pubsub_item ( + nodeid bigint, + itemid text NOT NULL, + publisher text NOT NULL, + creation varchar(32) NOT NULL, + modification varchar(32) NOT NULL, + payload mediumtext NOT NULL +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +CREATE INDEX i_pubsub_item_itemid ON pubsub_item(itemid(36)); +CREATE UNIQUE INDEX i_pubsub_item_tuple ON pubsub_item(nodeid, itemid(36)); +ALTER TABLE `pubsub_item` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE; + +CREATE TABLE pubsub_subscription_opt ( + subid text NOT NULL, + opt_name varchar(32), + opt_value text NOT NULL +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +CREATE UNIQUE INDEX i_pubsub_subscription_opt ON pubsub_subscription_opt(subid(32), opt_name(32)); + +CREATE TABLE muc_room ( + name text NOT NULL, + host text NOT NULL, + opts mediumtext NOT NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE UNIQUE INDEX i_muc_room_name_host USING BTREE ON muc_room(name(75), host(75)); + +CREATE TABLE muc_registered ( + jid text NOT NULL, + host text NOT NULL, + nick text NOT NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE INDEX i_muc_registered_nick USING BTREE ON muc_registered(nick(75)); +CREATE UNIQUE INDEX i_muc_registered_jid_host USING BTREE ON muc_registered(jid(75), host(75)); + +CREATE TABLE muc_online_room ( + name text NOT NULL, + host text NOT NULL, + node text NOT NULL, + pid text NOT NULL +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE UNIQUE INDEX i_muc_online_room_name_host USING BTREE ON muc_online_room(name(75), host(75)); + +CREATE TABLE muc_online_users ( + username text NOT NULL, + server text NOT NULL, + resource text NOT NULL, + name text NOT NULL, + host text NOT NULL, + node text NOT NULL +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE UNIQUE INDEX i_muc_online_users USING BTREE ON muc_online_users(username(75), server(75), resource(75), name(75), host(75)); +CREATE INDEX i_muc_online_users_us USING BTREE ON muc_online_users(username(75), server(75)); + +CREATE TABLE muc_room_subscribers ( + room varchar(191) NOT NULL, + host varchar(191) NOT NULL, + jid varchar(191) NOT NULL, + nick text NOT NULL, + nodes text NOT NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + UNIQUE KEY i_muc_room_subscribers_host_room_jid (host, room, jid) +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE INDEX i_muc_room_subscribers_host_jid USING BTREE ON muc_room_subscribers(host, jid); + +CREATE TABLE motd ( + username varchar(191) PRIMARY KEY, + xml text, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE TABLE caps_features ( + node varchar(191) NOT NULL, + subnode varchar(191) NOT NULL, + feature text, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE INDEX i_caps_features_node_subnode ON caps_features(node(75), subnode(75)); + +CREATE TABLE sm ( + usec bigint NOT NULL, + pid text NOT NULL, + node text NOT NULL, + username varchar(191) NOT NULL, + resource varchar(191) NOT NULL, + priority text NOT NULL, + info text NOT NULL +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE UNIQUE INDEX i_sid ON sm(usec, pid(75)); +CREATE INDEX i_node ON sm(node(75)); +CREATE INDEX i_username ON sm(username); + +CREATE TABLE oauth_token ( + token varchar(191) NOT NULL PRIMARY KEY, + jid text NOT NULL, + scope text NOT NULL, + expire bigint NOT NULL +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE TABLE route ( + domain text NOT NULL, + server_host text NOT NULL, + node text NOT NULL, + pid text NOT NULL, + local_hint text NOT NULL +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE UNIQUE INDEX i_route ON route(domain(75), server_host(75), node(75), pid(75)); +CREATE INDEX i_route_domain ON route(domain(75)); + +CREATE TABLE bosh ( + sid text NOT NULL, + node text NOT NULL, + pid text NOT NULL +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE UNIQUE INDEX i_bosh_sid ON bosh(sid(75)); + +CREATE TABLE proxy65 ( + sid text NOT NULL, + pid_t text NOT NULL, + pid_i text NOT NULL, + node_t text NOT NULL, + node_i text NOT NULL, + jid_i text NOT NULL +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE UNIQUE INDEX i_proxy65_sid ON proxy65 (sid(191)); +CREATE INDEX i_proxy65_jid ON proxy65 (jid_i(191)); + +CREATE TABLE push_session ( + username text NOT NULL, + timestamp bigint NOT NULL, + service text NOT NULL, + node text NOT NULL, + xml text NOT NULL +); + +CREATE UNIQUE INDEX i_push_usn ON push_session (username(191), service(191), node(191)); +CREATE UNIQUE INDEX i_push_ut ON push_session (username(191), timestamp); + +CREATE TABLE mix_channel ( + channel text NOT NULL, + service text NOT NULL, + username text NOT NULL, + domain text NOT NULL, + jid text NOT NULL, + hidden boolean NOT NULL, + hmac_key text NOT NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE UNIQUE INDEX i_mix_channel ON mix_channel (channel(191), service(191)); +CREATE INDEX i_mix_channel_serv ON mix_channel (service(191)); + +CREATE TABLE mix_participant ( + channel text NOT NULL, + service text NOT NULL, + username text NOT NULL, + domain text NOT NULL, + jid text NOT NULL, + id text NOT NULL, + nick text NOT NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE UNIQUE INDEX i_mix_participant ON mix_participant (channel(191), service(191), username(191), domain(191)); +CREATE INDEX i_mix_participant_chan_serv ON mix_participant (channel(191), service(191)); + +CREATE TABLE mix_subscription ( + channel text NOT NULL, + service text NOT NULL, + username text NOT NULL, + domain text NOT NULL, + node text NOT NULL, + jid text NOT NULL +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE UNIQUE INDEX i_mix_subscription ON mix_subscription (channel(153), service(153), username(153), domain(153), node(153)); +CREATE INDEX i_mix_subscription_chan_serv_ud ON mix_subscription (channel(191), service(191), username(191), domain(191)); +CREATE INDEX i_mix_subscription_chan_serv_node ON mix_subscription (channel(191), service(191), node(191)); +CREATE INDEX i_mix_subscription_chan_serv ON mix_subscription (channel(191), service(191)); + +CREATE TABLE mix_pam ( + username text NOT NULL, + channel text NOT NULL, + service text NOT NULL, + id text NOT NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +CREATE UNIQUE INDEX i_mix_pam ON mix_pam (username(191), channel(191), service(191)); +CREATE INDEX i_mix_pam_u ON mix_pam (username(191)); + +CREATE TABLE mqtt_pub ( + username varchar(191) NOT NULL, + resource varchar(191) NOT NULL, + topic text NOT NULL, + qos tinyint NOT NULL, + payload blob NOT NULL, + payload_format tinyint NOT NULL, + content_type text NOT NULL, + response_topic text NOT NULL, + correlation_data blob NOT NULL, + user_properties blob NOT NULL, + expiry int unsigned NOT NULL, + UNIQUE KEY i_mqtt_topic (topic(191)) +); diff --git a/test/docker/db/postgres/initdb/pg.sql b/test/docker/db/postgres/initdb/pg.sql new file mode 100644 index 000000000..eae98d3f0 --- /dev/null +++ b/test/docker/db/postgres/initdb/pg.sql @@ -0,0 +1,470 @@ +-- +-- ejabberd, Copyright (C) 2002-2019 ProcessOne +-- +-- This program is free software; you can redistribute it and/or +-- modify it under the terms of the GNU General Public License as +-- published by the Free Software Foundation; either version 2 of the +-- License, or (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-- General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License along +-- with this program; if not, write to the Free Software Foundation, Inc., +-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +-- + +CREATE TABLE users ( + username text PRIMARY KEY, + "password" text NOT NULL, + serverkey text NOT NULL DEFAULT '', + salt text NOT NULL DEFAULT '', + iterationcount integer NOT NULL DEFAULT 0, + created_at TIMESTAMP NOT NULL DEFAULT now() +); + +-- Add support for SCRAM auth to a database created before ejabberd 16.03: +-- ALTER TABLE users ADD COLUMN serverkey text NOT NULL DEFAULT ''; +-- ALTER TABLE users ADD COLUMN salt text NOT NULL DEFAULT ''; +-- ALTER TABLE users ADD COLUMN iterationcount integer NOT NULL DEFAULT 0; + +CREATE TABLE last ( + username text PRIMARY KEY, + seconds text NOT NULL, + state text NOT NULL +); + + +CREATE TABLE rosterusers ( + username text NOT NULL, + jid text NOT NULL, + nick text NOT NULL, + subscription character(1) NOT NULL, + ask character(1) NOT NULL, + askmessage text NOT NULL, + server character(1) NOT NULL, + subscribe text NOT NULL, + "type" text, + created_at TIMESTAMP NOT NULL DEFAULT now() +); + +CREATE UNIQUE INDEX i_rosteru_user_jid ON rosterusers USING btree (username, jid); +CREATE INDEX i_rosteru_username ON rosterusers USING btree (username); +CREATE INDEX i_rosteru_jid ON rosterusers USING btree (jid); + + +CREATE TABLE rostergroups ( + username text NOT NULL, + jid text NOT NULL, + grp text NOT NULL +); + +CREATE INDEX pk_rosterg_user_jid ON rostergroups USING btree (username, jid); + +CREATE TABLE sr_group ( + name text NOT NULL, + opts text NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT now() +); + +CREATE TABLE sr_user ( + jid text NOT NULL, + grp text NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT now() +); + +CREATE UNIQUE INDEX i_sr_user_jid_grp ON sr_user USING btree (jid, grp); +CREATE INDEX i_sr_user_jid ON sr_user USING btree (jid); +CREATE INDEX i_sr_user_grp ON sr_user USING btree (grp); + +CREATE TABLE spool ( + username text NOT NULL, + xml text NOT NULL, + seq SERIAL, + created_at TIMESTAMP NOT NULL DEFAULT now() +); + +CREATE INDEX i_despool ON spool USING btree (username); + +CREATE TABLE archive ( + username text NOT NULL, + timestamp BIGINT NOT NULL, + peer text NOT NULL, + bare_peer text NOT NULL, + xml text NOT NULL, + txt text, + id SERIAL, + kind text, + nick text, + created_at TIMESTAMP NOT NULL DEFAULT now() +); + +CREATE INDEX i_username_timestamp ON archive USING btree (username, timestamp); +CREATE INDEX i_username_peer ON archive USING btree (username, peer); +CREATE INDEX i_username_bare_peer ON archive USING btree (username, bare_peer); +CREATE INDEX i_timestamp ON archive USING btree (timestamp); + +CREATE TABLE archive_prefs ( + username text NOT NULL PRIMARY KEY, + def text NOT NULL, + always text NOT NULL, + never text NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT now() +); + +CREATE TABLE vcard ( + username text PRIMARY KEY, + vcard text NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT now() +); + +CREATE TABLE vcard_search ( + username text NOT NULL, + lusername text PRIMARY KEY, + fn text NOT NULL, + lfn text NOT NULL, + family text NOT NULL, + lfamily text NOT NULL, + given text NOT NULL, + lgiven text NOT NULL, + middle text NOT NULL, + lmiddle text NOT NULL, + nickname text NOT NULL, + lnickname text NOT NULL, + bday text NOT NULL, + lbday text NOT NULL, + ctry text NOT NULL, + lctry text NOT NULL, + locality text NOT NULL, + llocality text NOT NULL, + email text NOT NULL, + lemail text NOT NULL, + orgname text NOT NULL, + lorgname text NOT NULL, + orgunit text NOT NULL, + lorgunit text NOT NULL +); + +CREATE INDEX i_vcard_search_lfn ON vcard_search(lfn); +CREATE INDEX i_vcard_search_lfamily ON vcard_search(lfamily); +CREATE INDEX i_vcard_search_lgiven ON vcard_search(lgiven); +CREATE INDEX i_vcard_search_lmiddle ON vcard_search(lmiddle); +CREATE INDEX i_vcard_search_lnickname ON vcard_search(lnickname); +CREATE INDEX i_vcard_search_lbday ON vcard_search(lbday); +CREATE INDEX i_vcard_search_lctry ON vcard_search(lctry); +CREATE INDEX i_vcard_search_llocality ON vcard_search(llocality); +CREATE INDEX i_vcard_search_lemail ON vcard_search(lemail); +CREATE INDEX i_vcard_search_lorgname ON vcard_search(lorgname); +CREATE INDEX i_vcard_search_lorgunit ON vcard_search(lorgunit); + +CREATE TABLE privacy_default_list ( + username text PRIMARY KEY, + name text NOT NULL +); + +CREATE TABLE privacy_list ( + username text NOT NULL, + name text NOT NULL, + id SERIAL UNIQUE, + created_at TIMESTAMP NOT NULL DEFAULT now() +); + +CREATE INDEX i_privacy_list_username ON privacy_list USING btree (username); +CREATE UNIQUE INDEX i_privacy_list_username_name ON privacy_list USING btree (username, name); + +CREATE TABLE privacy_list_data ( + id bigint REFERENCES privacy_list(id) ON DELETE CASCADE, + t character(1) NOT NULL, + value text NOT NULL, + action character(1) NOT NULL, + ord NUMERIC NOT NULL, + match_all boolean NOT NULL, + match_iq boolean NOT NULL, + match_message boolean NOT NULL, + match_presence_in boolean NOT NULL, + match_presence_out boolean NOT NULL +); + +CREATE INDEX i_privacy_list_data_id ON privacy_list_data USING btree (id); + +CREATE TABLE private_storage ( + username text NOT NULL, + namespace text NOT NULL, + data text NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT now() +); + +CREATE INDEX i_private_storage_username ON private_storage USING btree (username); +CREATE UNIQUE INDEX i_private_storage_username_namespace ON private_storage USING btree (username, namespace); + + +CREATE TABLE roster_version ( + username text PRIMARY KEY, + version text NOT NULL +); + +-- To update from 0.9.8: +-- CREATE SEQUENCE spool_seq_seq; +-- ALTER TABLE spool ADD COLUMN seq integer; +-- ALTER TABLE spool ALTER COLUMN seq SET DEFAULT nextval('spool_seq_seq'); +-- UPDATE spool SET seq = DEFAULT; +-- ALTER TABLE spool ALTER COLUMN seq SET NOT NULL; + +-- To update from 1.x: +-- ALTER TABLE rosterusers ADD COLUMN askmessage text; +-- UPDATE rosterusers SET askmessage = ''; +-- ALTER TABLE rosterusers ALTER COLUMN askmessage SET NOT NULL; + +CREATE TABLE pubsub_node ( + host text NOT NULL, + node text NOT NULL, + parent text NOT NULL DEFAULT '', + plugin text NOT NULL, + nodeid SERIAL UNIQUE +); +CREATE INDEX i_pubsub_node_parent ON pubsub_node USING btree (parent); +CREATE UNIQUE INDEX i_pubsub_node_tuple ON pubsub_node USING btree (host, node); + +CREATE TABLE pubsub_node_option ( + nodeid bigint REFERENCES pubsub_node(nodeid) ON DELETE CASCADE, + name text NOT NULL, + val text NOT NULL +); +CREATE INDEX i_pubsub_node_option_nodeid ON pubsub_node_option USING btree (nodeid); + +CREATE TABLE pubsub_node_owner ( + nodeid bigint REFERENCES pubsub_node(nodeid) ON DELETE CASCADE, + owner text NOT NULL +); +CREATE INDEX i_pubsub_node_owner_nodeid ON pubsub_node_owner USING btree (nodeid); + +CREATE TABLE pubsub_state ( + nodeid bigint REFERENCES pubsub_node(nodeid) ON DELETE CASCADE, + jid text NOT NULL, + affiliation character(1), + subscriptions text NOT NULL DEFAULT '', + stateid SERIAL UNIQUE +); +CREATE INDEX i_pubsub_state_jid ON pubsub_state USING btree (jid); +CREATE UNIQUE INDEX i_pubsub_state_tuple ON pubsub_state USING btree (nodeid, jid); + +CREATE TABLE pubsub_item ( + nodeid bigint REFERENCES pubsub_node(nodeid) ON DELETE CASCADE, + itemid text NOT NULL, + publisher text NOT NULL, + creation varchar(32) NOT NULL, + modification varchar(32) NOT NULL, + payload text NOT NULL DEFAULT '' +); +CREATE INDEX i_pubsub_item_itemid ON pubsub_item USING btree (itemid); +CREATE UNIQUE INDEX i_pubsub_item_tuple ON pubsub_item USING btree (nodeid, itemid); + +CREATE TABLE pubsub_subscription_opt ( + subid text NOT NULL, + opt_name varchar(32), + opt_value text NOT NULL +); +CREATE UNIQUE INDEX i_pubsub_subscription_opt ON pubsub_subscription_opt USING btree (subid, opt_name); + +CREATE TABLE muc_room ( + name text NOT NULL, + host text NOT NULL, + opts text NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT now() +); + +CREATE UNIQUE INDEX i_muc_room_name_host ON muc_room USING btree (name, host); + +CREATE TABLE muc_registered ( + jid text NOT NULL, + host text NOT NULL, + nick text NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT now() +); + +CREATE INDEX i_muc_registered_nick ON muc_registered USING btree (nick); +CREATE UNIQUE INDEX i_muc_registered_jid_host ON muc_registered USING btree (jid, host); + +CREATE TABLE muc_online_room ( + name text NOT NULL, + host text NOT NULL, + node text NOT NULL, + pid text NOT NULL +); + +CREATE UNIQUE INDEX i_muc_online_room_name_host ON muc_online_room USING btree (name, host); + +CREATE TABLE muc_online_users ( + username text NOT NULL, + server text NOT NULL, + resource text NOT NULL, + name text NOT NULL, + host text NOT NULL, + node text NOT NULL +); + +CREATE UNIQUE INDEX i_muc_online_users ON muc_online_users USING btree (username, server, resource, name, host); +CREATE INDEX i_muc_online_users_us ON muc_online_users USING btree (username, server); + +CREATE TABLE muc_room_subscribers ( + room text NOT NULL, + host text NOT NULL, + jid text NOT NULL, + nick text NOT NULL, + nodes text NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT now() +); + +CREATE INDEX i_muc_room_subscribers_host_jid ON muc_room_subscribers USING btree (host, jid); +CREATE UNIQUE INDEX i_muc_room_subscribers_host_room_jid ON muc_room_subscribers USING btree (host, room, jid); + +CREATE TABLE motd ( + username text PRIMARY KEY, + xml text, + created_at TIMESTAMP NOT NULL DEFAULT now() +); + +CREATE TABLE caps_features ( + node text NOT NULL, + subnode text NOT NULL, + feature text, + created_at TIMESTAMP NOT NULL DEFAULT now() +); + +CREATE INDEX i_caps_features_node_subnode ON caps_features USING btree (node, subnode); + +CREATE TABLE sm ( + usec bigint NOT NULL, + pid text NOT NULL, + node text NOT NULL, + username text NOT NULL, + resource text NOT NULL, + priority text NOT NULL, + info text NOT NULL +); + +CREATE UNIQUE INDEX i_sm_sid ON sm USING btree (usec, pid); +CREATE INDEX i_sm_node ON sm USING btree (node); +CREATE INDEX i_sm_username ON sm USING btree (username); + +CREATE TABLE oauth_token ( + token text NOT NULL, + jid text NOT NULL, + scope text NOT NULL, + expire bigint NOT NULL +); + +CREATE UNIQUE INDEX i_oauth_token_token ON oauth_token USING btree (token); + +CREATE TABLE route ( + domain text NOT NULL, + server_host text NOT NULL, + node text NOT NULL, + pid text NOT NULL, + local_hint text NOT NULL +); + +CREATE UNIQUE INDEX i_route ON route USING btree (domain, server_host, node, pid); +CREATE INDEX i_route_domain ON route USING btree (domain); + +CREATE TABLE bosh ( + sid text NOT NULL, + node text NOT NULL, + pid text NOT NULL +); + +CREATE UNIQUE INDEX i_bosh_sid ON bosh USING btree (sid); + +CREATE TABLE proxy65 ( + sid text NOT NULL, + pid_t text NOT NULL, + pid_i text NOT NULL, + node_t text NOT NULL, + node_i text NOT NULL, + jid_i text NOT NULL +); + +CREATE UNIQUE INDEX i_proxy65_sid ON proxy65 USING btree (sid); +CREATE INDEX i_proxy65_jid ON proxy65 USING btree (jid_i); + +CREATE TABLE push_session ( + username text NOT NULL, + timestamp bigint NOT NULL, + service text NOT NULL, + node text NOT NULL, + xml text NOT NULL +); + +CREATE UNIQUE INDEX i_push_usn ON push_session USING btree (username, service, node); +CREATE UNIQUE INDEX i_push_ut ON push_session USING btree (username, timestamp); + +CREATE TABLE mix_channel ( + channel text NOT NULL, + service text NOT NULL, + username text NOT NULL, + domain text NOT NULL, + jid text NOT NULL, + hidden boolean NOT NULL, + hmac_key text NOT NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE UNIQUE INDEX i_mix_channel ON mix_channel (channel, service); +CREATE INDEX i_mix_channel_serv ON mix_channel (service); + +CREATE TABLE mix_participant ( + channel text NOT NULL, + service text NOT NULL, + username text NOT NULL, + domain text NOT NULL, + jid text NOT NULL, + id text NOT NULL, + nick text NOT NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE UNIQUE INDEX i_mix_participant ON mix_participant (channel, service, username, domain); +CREATE INDEX i_mix_participant_chan_serv ON mix_participant (channel, service); + +CREATE TABLE mix_subscription ( + channel text NOT NULL, + service text NOT NULL, + username text NOT NULL, + domain text NOT NULL, + node text NOT NULL, + jid text NOT NULL +); + +CREATE UNIQUE INDEX i_mix_subscription ON mix_subscription (channel, service, username, domain, node); +CREATE INDEX i_mix_subscription_chan_serv_ud ON mix_subscription (channel, service, username, domain); +CREATE INDEX i_mix_subscription_chan_serv_node ON mix_subscription (channel, service, node); +CREATE INDEX i_mix_subscription_chan_serv ON mix_subscription (channel, service); + +CREATE TABLE mix_pam ( + username text NOT NULL, + channel text NOT NULL, + service text NOT NULL, + id text NOT NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE UNIQUE INDEX i_mix_pam ON mix_pam (username, channel, service); +CREATE INDEX i_mix_pam_us ON mix_pam (username); + +CREATE TABLE mqtt_pub ( + username text NOT NULL, + resource text NOT NULL, + topic text NOT NULL, + qos smallint NOT NULL, + payload bytea NOT NULL, + payload_format smallint NOT NULL, + content_type text NOT NULL, + response_topic text NOT NULL, + correlation_data bytea NOT NULL, + user_properties bytea NOT NULL, + expiry bigint NOT NULL +); + +CREATE UNIQUE INDEX i_mqtt_topic ON mqtt_pub (topic); diff --git a/test/docker/db/riak/Dockerfile b/test/docker/db/riak/Dockerfile new file mode 100644 index 000000000..b0f539dc9 --- /dev/null +++ b/test/docker/db/riak/Dockerfile @@ -0,0 +1,53 @@ +# docker build -t ejabberd/riak . +# docker run --rm -it -p 8087:8087 -p 8098:8098 -v "`pwd`/ebin:/usr/lib/ejabberd/ebin" --name ejabberd-riak ejabberd/riak +# docker exec -it ejabberd-riak /bin/bash +# docker push ejabberd/riak:latest +FROM ubuntu:16.04 + +ENV DEBIAN_FRONTEND noninteractive +# ENV RIAK_VERSION 2.0.9-1 +# install riak=${RIAK_VERSION} to fallback to an older version + +RUN \ + apt-get update -qq && \ + apt-get install -y curl apt-utils iputils-ping && \ + curl -s https://packagecloud.io/install/repositories/basho/riak/script.deb.sh | bash && \ + apt-get install -y riak && \ + apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +# Expose default ports +EXPOSE 8087 +EXPOSE 8098 + +# Expose volumes for data and logs +VOLUME /var/log/riak +VOLUME /var/lib/riak + +# Expose volumes for ejabberd code for map/reduce in Riak. +# It can be overloaded to provide a new ejabberd_riak.beam file. +# Note that ejabberd_riak.beam needs to be compiled with Erlang/OTP R16 +# as this is the version of Erlang Basho has packaged with Riak. +COPY ejabberd_riak.beam /usr/lib/ejabberd/ebin/ejabberd_riak.beam +VOLUME /usr/lib/ejabberd/ebin + +# Install custom start script +COPY riak-cluster.sh /sbin/riak-cluster.sh +RUN chmod a+x /sbin/riak-cluster.sh + +# Change configuration to make it work with ejabberd +COPY advanced.config /etc/riak/advanced.config +COPY riak.conf /etc/riak/riak.conf + +# Install custom hooks +COPY prestart.d /etc/riak/prestart.d +# COPY poststart.d /etc/riak/poststart.d + +# Prepare for bootstrapping schemas +RUN mkdir -p /etc/riak/schemas + +# Clean up APT cache +RUN rm -rf /var/lib/apt/lists/* /tmp/* + +WORKDIR /var/lib/riak + +CMD ["/sbin/riak-cluster.sh"] diff --git a/test/docker/db/riak/advanced.config b/test/docker/db/riak/advanced.config new file mode 100644 index 000000000..e5d5f8743 --- /dev/null +++ b/test/docker/db/riak/advanced.config @@ -0,0 +1,27 @@ +%% Config file used to set advanced configuration options + +[{lager, + [ + {extra_sinks, + [ + {object_lager_event, + [{handlers, + [{lager_file_backend, + [{file, "/var/log/riak/object.log"}, + {level, info}, + {formatter_config, [date, " ", time," [",severity,"] ",message, "\n"]} + ] + }] + }, + {async_threshold, 500}, + {async_threshold_window, 50}] + } + ] + } + ]}, + + {riak_kv, [ + %% Other configs + {add_paths, ["/usr/lib/ejabberd/ebin"]} + ]} +]. diff --git a/test/docker/db/riak/ejabberd_riak.beam b/test/docker/db/riak/ejabberd_riak.beam new file mode 100644 index 000000000..3bebb297d Binary files /dev/null and b/test/docker/db/riak/ejabberd_riak.beam differ diff --git a/test/docker/db/riak/prestart.d/00-setup-networking.sh b/test/docker/db/riak/prestart.d/00-setup-networking.sh new file mode 100755 index 000000000..07ca617fb --- /dev/null +++ b/test/docker/db/riak/prestart.d/00-setup-networking.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# Add standard config items +cat <>$RIAK_CONF +nodename = riak@$HOST +distributed_cookie = $CLUSTER_NAME +listener.protobuf.internal = $HOST:$PB_PORT +listener.http.internal = $HOST:$HTTP_PORT +END diff --git a/test/docker/db/riak/riak-cluster.sh b/test/docker/db/riak/riak-cluster.sh new file mode 100644 index 000000000..11f344f0a --- /dev/null +++ b/test/docker/db/riak/riak-cluster.sh @@ -0,0 +1,56 @@ +#!/bin/bash +# +# Cluster start script to bootstrap a Riak cluster. +# +set -ex + +if [[ -x /usr/sbin/riak ]]; then + export RIAK=/usr/sbin/riak +else + export RIAK=$RIAK_HOME/bin/riak +fi +export RIAK_CONF=/etc/riak/riak.conf +export USER_CONF=/etc/riak/user.conf +export RIAK_ADVANCED_CONF=/etc/riak/advanced.config +if [[ -x /usr/sbin/riak-admin ]]; then + export RIAK_ADMIN=/usr/sbin/riak-admin +else + export RIAK_ADMIN=$RIAK_HOME/bin/riak-admin +fi +export SCHEMAS_DIR=/etc/riak/schemas/ + +# Set ports for PB and HTTP +export PB_PORT=${PB_PORT:-8087} +export HTTP_PORT=${HTTP_PORT:-8098} + +# Use ping to discover our HOSTNAME because it's easier and more reliable than other methods +export HOST=$(ping -c1 $HOSTNAME | awk '/^PING/ {print $3}' | sed 's/[()]//g')||'127.0.0.1' + +# CLUSTER_NAME is used to name the nodes and is the value used in the distributed cookie +export CLUSTER_NAME=${CLUSTER_NAME:-riak} + +# The COORDINATOR_NODE is the first node in a cluster to which other nodes will eventually join +export COORDINATOR_NODE=${COORDINATOR_NODE:-$HOSTNAME} +export COORDINATOR_NODE_HOST=$(ping -c1 $COORDINATOR_NODE | awk '/^PING/ {print $3}' | sed 's/[()]//g')||'127.0.0.1' + +# Run all prestart scripts +PRESTART=$(find /etc/riak/prestart.d -name *.sh -print | sort) +for s in $PRESTART; do + . $s +done + +# Start the node and wait until fully up +$RIAK start +$RIAK_ADMIN wait-for-service riak_kv + +# Run all poststart scripts +POSTSTART=$(find /etc/riak/poststart.d -name *.sh -print | sort) +for s in $POSTSTART; do + . $s +done + +# Trap SIGTERM and SIGINT and tail the log file indefinitely +tail -n 1024 -f /var/log/riak/console.log & +PID=$! +trap "$RIAK stop; kill $PID" SIGTERM SIGINT +wait $PID diff --git a/test/docker/db/riak/riak.conf b/test/docker/db/riak/riak.conf new file mode 100644 index 000000000..3c8c0c09e --- /dev/null +++ b/test/docker/db/riak/riak.conf @@ -0,0 +1,682 @@ +## 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 = off + +## 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 = 8093 + +## 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/test/docker/docker-compose.yml b/test/docker/docker-compose.yml new file mode 100644 index 000000000..e6026ac21 --- /dev/null +++ b/test/docker/docker-compose.yml @@ -0,0 +1,48 @@ +version: '3.7' + +services: + mysql: + image: mysql:latest + container_name: ejabberd-mysql + volumes: + - ./db/mysql/data:/var/lib/mysql + - ./db/mysql/initdb:/docker-entrypoint-initdb.d:ro + command: --default-authentication-plugin=mysql_native_password + restart: always + ports: + - 3306:3306 + environment: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: ejabberd_test + MYSQL_USER: ejabberd_test + MYSQL_PASSWORD: ejabberd_test + + postgres: + image: postgres:latest + container_name: ejabberd-postgres + volumes: + - ./db/postgres/data:/var/lib/postgresql/data + - ./db/postgres/initdb:/docker-entrypoint-initdb.d:ro + ports: + - 5432:5432 + environment: + POSTGRES_PASSWORD: ejabberd_test + POSTGRES_USER: ejabberd_test + POSTGRES_DB: ejabberd_test + + redis: + image: redis:latest + container_name: ejabberd-redis + ports: + - 6379:6379 + + riak: + image: ejabberd/riak:latest + container_name: ejabberd-riak + ports: + - 8087:8087 + - 8098:8098 + volumes: + - ./db/riak/data:/var/lib/riak + environment: + WAIT_FOR_ERLANG: 60