From 5d7cf04611e28cd36e4bf17af55a5264e9f1eaa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Pud=C5=82owski?= Date: Wed, 24 Feb 2021 12:27:26 +0100 Subject: [PATCH 1/2] Zookeeper upgraded to 3.5.8 version --- CHANGELOG-0.7.md | 1 + .../centos-7/requirements.txt | 2 +- .../redhat-7/requirements.txt | 2 +- .../ubuntu-18.04/requirements.txt | 2 +- .../roles/upgrade/tasks/zookeeper.yml | 50 +++++++++++ .../tasks/zookeeper/install-upgrade.yml | 79 ++++++++++++++++++ .../tasks/zookeeper/preflight-check.yml | 14 ++++ .../roles/zookeeper/defaults/main.yml | 3 + .../roles/zookeeper/files/snapshot.0 | Bin 0 -> 424 bytes .../playbooks/roles/zookeeper/tasks/main.yml | 22 ++--- .../zookeeper/templates/zookeeper.service.j2 | 2 +- .../playbooks/roles/zookeeper/vars/main.yml | 0 .../data/common/ansible/playbooks/upgrade.yml | 10 +++ .../defaults/configuration/zookeeper.yml | 4 +- docs/home/COMPONENTS.md | 2 +- 15 files changed, 171 insertions(+), 22 deletions(-) create mode 100644 core/src/epicli/data/common/ansible/playbooks/roles/upgrade/tasks/zookeeper.yml create mode 100644 core/src/epicli/data/common/ansible/playbooks/roles/upgrade/tasks/zookeeper/install-upgrade.yml create mode 100644 core/src/epicli/data/common/ansible/playbooks/roles/upgrade/tasks/zookeeper/preflight-check.yml create mode 100644 core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/files/snapshot.0 delete mode 100644 core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/vars/main.yml diff --git a/CHANGELOG-0.7.md b/CHANGELOG-0.7.md index e52c497024..484395c3be 100644 --- a/CHANGELOG-0.7.md +++ b/CHANGELOG-0.7.md @@ -9,6 +9,7 @@ ### Updated - [#1965](https://github.com/epiphany-platform/epiphany/issues/1965) - Upgrade Elasticsearch Curator to v5.8.3 +- [#1927](https://github.com/epiphany-platform/epiphany/issues/1927) - Upgrade Zookeeper to v3.5.8 ## [0.7.2] 2020-10-07 diff --git a/core/src/epicli/data/common/ansible/playbooks/roles/repository/files/download-requirements/centos-7/requirements.txt b/core/src/epicli/data/common/ansible/playbooks/roles/repository/files/download-requirements/centos-7/requirements.txt index 63483c9446..87ddeace3a 100644 --- a/core/src/epicli/data/common/ansible/playbooks/roles/repository/files/download-requirements/centos-7/requirements.txt +++ b/core/src/epicli/data/common/ansible/playbooks/roles/repository/files/download-requirements/centos-7/requirements.txt @@ -153,7 +153,7 @@ https://github.com/danielqsj/kafka_exporter/releases/download/v1.2.0/kafka_expor https://github.com/prometheus/node_exporter/releases/download/v0.16.0/node_exporter-0.16.0.linux-amd64.tar.gz https://github.com/prometheus/prometheus/releases/download/v2.10.0/prometheus-2.10.0.linux-amd64.tar.gz https://github.com/prometheus/alertmanager/releases/download/v0.17.0/alertmanager-0.17.0.linux-amd64.tar.gz -https://archive.apache.org/dist/zookeeper/zookeeper-3.4.12/zookeeper-3.4.12.tar.gz +https://archive.apache.org/dist/zookeeper/zookeeper-3.5.8/apache-zookeeper-3.5.8-bin.tar.gz https://archive.apache.org/dist/ignite/2.7.6/apache-ignite-2.7.6-bin.zip https://releases.hashicorp.com/vault/1.4.0/vault_1.4.0_linux_amd64.zip https://get.helm.sh/helm-v3.2.0-linux-amd64.tar.gz diff --git a/core/src/epicli/data/common/ansible/playbooks/roles/repository/files/download-requirements/redhat-7/requirements.txt b/core/src/epicli/data/common/ansible/playbooks/roles/repository/files/download-requirements/redhat-7/requirements.txt index 0b61924aaf..2918213be8 100644 --- a/core/src/epicli/data/common/ansible/playbooks/roles/repository/files/download-requirements/redhat-7/requirements.txt +++ b/core/src/epicli/data/common/ansible/playbooks/roles/repository/files/download-requirements/redhat-7/requirements.txt @@ -150,7 +150,7 @@ https://github.com/danielqsj/kafka_exporter/releases/download/v1.2.0/kafka_expor https://github.com/prometheus/node_exporter/releases/download/v0.16.0/node_exporter-0.16.0.linux-amd64.tar.gz https://github.com/prometheus/prometheus/releases/download/v2.10.0/prometheus-2.10.0.linux-amd64.tar.gz https://github.com/prometheus/alertmanager/releases/download/v0.17.0/alertmanager-0.17.0.linux-amd64.tar.gz -https://archive.apache.org/dist/zookeeper/zookeeper-3.4.12/zookeeper-3.4.12.tar.gz +https://archive.apache.org/dist/zookeeper/zookeeper-3.5.8/apache-zookeeper-3.5.8-bin.tar.gz https://archive.apache.org/dist/ignite/2.7.6/apache-ignite-2.7.6-bin.zip https://releases.hashicorp.com/vault/1.4.0/vault_1.4.0_linux_amd64.zip https://get.helm.sh/helm-v3.2.0-linux-amd64.tar.gz diff --git a/core/src/epicli/data/common/ansible/playbooks/roles/repository/files/download-requirements/ubuntu-18.04/requirements.txt b/core/src/epicli/data/common/ansible/playbooks/roles/repository/files/download-requirements/ubuntu-18.04/requirements.txt index 4d37434118..e6afb55ae8 100644 --- a/core/src/epicli/data/common/ansible/playbooks/roles/repository/files/download-requirements/ubuntu-18.04/requirements.txt +++ b/core/src/epicli/data/common/ansible/playbooks/roles/repository/files/download-requirements/ubuntu-18.04/requirements.txt @@ -169,7 +169,7 @@ kubernetes-cni 0.8.6-00 [files] https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.12.0/jmx_prometheus_javaagent-0.12.0.jar https://archive.apache.org/dist/kafka/2.3.1/kafka_2.12-2.3.1.tgz -https://archive.apache.org/dist/zookeeper/zookeeper-3.4.12/zookeeper-3.4.12.tar.gz +https://archive.apache.org/dist/zookeeper/zookeeper-3.5.8/apache-zookeeper-3.5.8-bin.tar.gz https://github.com/danielqsj/kafka_exporter/releases/download/v1.2.0/kafka_exporter-1.2.0.linux-amd64.tar.gz https://github.com/prometheus/alertmanager/releases/download/v0.17.0/alertmanager-0.17.0.linux-amd64.tar.gz https://github.com/prometheus/haproxy_exporter/releases/download/v0.10.0/haproxy_exporter-0.10.0.linux-amd64.tar.gz diff --git a/core/src/epicli/data/common/ansible/playbooks/roles/upgrade/tasks/zookeeper.yml b/core/src/epicli/data/common/ansible/playbooks/roles/upgrade/tasks/zookeeper.yml new file mode 100644 index 0000000000..d30a6e60ba --- /dev/null +++ b/core/src/epicli/data/common/ansible/playbooks/roles/upgrade/tasks/zookeeper.yml @@ -0,0 +1,50 @@ +--- +- name: Include defaults from zookeeper role + include_vars: + file: roles/zookeeper/defaults/main.yml + name: zookeeper_defaults + +- name: Include pre-flight checks + include_tasks: zookeeper/preflight-check.yml + +- name: Get installed Zookeeper's version + stat: + path: /opt/zookeeper + get_attributes: false + get_checksum: false + get_mime: false + register: linked_zookeeper + +- name: Set installed Zookeeper version as fact + set_fact: + before_upgrade_zookeeper_version: "{{ linked_zookeeper.stat.lnk_target | regex_search('\\d+\\.\\d+\\.\\d+') }}" + +- name: Check for upgrade flag file + stat: + path: "{{ lock_file }}" + get_attributes: false + get_checksum: false + get_mime: false + register: lock_file_status + +- name: Upgrade Zookeeper if newer version is available + block: + - name: Create upgrade flag file + file: + path: "{{ lock_file }}" + state: touch + + - name: Stop Zookeeper service + service: + name: zookeeper + state: stopped + + - name: Include upgrade Zookeeper task + include_tasks: zookeeper/install-upgrade.yml + when: + - lock_file_status.stat.exists or before_upgrade_zookeeper_version is version( zookeeper_defaults.zookeeper_version, '<' ) + +- name: Remove Zookeeper upgrade flag file + file: + path: "{{ lock_file }}" + state: absent diff --git a/core/src/epicli/data/common/ansible/playbooks/roles/upgrade/tasks/zookeeper/install-upgrade.yml b/core/src/epicli/data/common/ansible/playbooks/roles/upgrade/tasks/zookeeper/install-upgrade.yml new file mode 100644 index 0000000000..af8791484c --- /dev/null +++ b/core/src/epicli/data/common/ansible/playbooks/roles/upgrade/tasks/zookeeper/install-upgrade.yml @@ -0,0 +1,79 @@ +--- + +# Some tasks in this file are the same as in zookeeper role. It should be refactored (with splitting code into separate files) in order to reuse common tasks here. +- name: Download Zookeeper binaries + include_role: + name: download + tasks_from: download_file + vars: + file_name: "{{ zookeeper_defaults.zookeeper_bin_filename }}" + +- name: Create Zookeeper directories + become: yes + file: + path: "/opt/zookeeper-{{ zookeeper_defaults.zookeeper_version }}" + recurse: yes + owner: "{{ zookeeper_defaults.zookeeper_user }}" + group: "{{ zookeeper_defaults.zookeeper_group }}" + mode: u=rwx,g=rx,o=rx + state: directory + +- name: Uncompress Zookeeper installation file + unarchive: + remote_src: yes + src: "{{ download_directory }}/{{ zookeeper_defaults.zookeeper_bin_filename }}" + dest: /opt/zookeeper-{{ zookeeper_defaults.zookeeper_version }} + creates: "/opt/zookeeper-{{ zookeeper_defaults.zookeeper_version }}/bin" + extra_opts: [--strip-components=1] + mode: u=rwx,g=rx,o=rx + owner: "{{ zookeeper_defaults.zookeeper_user }}" + group: "{{ zookeeper_defaults.zookeeper_group }}" + +- name: Copy configuration from previous version + copy: + remote_src: yes + src: /opt/zookeeper/conf/ + dest: /opt/zookeeper-{{ zookeeper_defaults.zookeeper_version }}/conf + mode: preserve + +- name: Link /opt/zookeeper to recently installed version + file: + dest: /opt/zookeeper + state: link + src: /opt/zookeeper-{{ zookeeper_defaults.zookeeper_version }} + force: yes + +- name: Reconfigure Zookeeper service to use symbolic link + lineinfile: + path: /lib/systemd/system/zookeeper.service + state: present + regexp: '^ExecStart=/opt/zookeeper-.*' + line: "ExecStart=/opt/zookeeper/bin/zkServer.sh start-foreground" + +- name: Check if any snapshots exists in data dir what is necessary in order to run zookeeper after upgrade + find: + paths: "{{ zookeeper_defaults.zookeeper_data_dir }}/version-2" + patterns: "snapshot.*" + register: snapshot_exists + +# From 3.5.5 version, ZooKeeper is not able to start when no snapshot files present, what is valid scenario in 3.4.X version. Empty snapshot downloaded from Zookeeper's Jira ticket. +- name: Copy empty snapshot if not exists + copy: + dest: "{{ zookeeper_defaults.zookeeper_data_dir }}/version-2" + src: roles/zookeeper/files/snapshot.0 + mode: u=rw,g=r,o=r + owner: "{{ zookeeper_defaults.zookeeper_user }}" + group: "{{ zookeeper_defaults.zookeeper_group }}" + when: snapshot_exists.matched == 0 + +- name: Start Zookeeper service + systemd: + name: zookeeper + state: started + daemon-reload: yes + +- name: Remove previous version binaries + file: + path: /opt/zookeeper-{{ before_upgrade_zookeeper_version }} + state: absent + when: before_upgrade_zookeeper_version != zookeeper_defaults.zookeeper_version diff --git a/core/src/epicli/data/common/ansible/playbooks/roles/upgrade/tasks/zookeeper/preflight-check.yml b/core/src/epicli/data/common/ansible/playbooks/roles/upgrade/tasks/zookeeper/preflight-check.yml new file mode 100644 index 0000000000..b5c9cb6cc6 --- /dev/null +++ b/core/src/epicli/data/common/ansible/playbooks/roles/upgrade/tasks/zookeeper/preflight-check.yml @@ -0,0 +1,14 @@ +--- + - name: Check if Zookeeper is installed in default location + stat: + path: /opt/zookeeper/bin/zkServer.sh + get_attributes: false + get_checksum: false + get_mime: false + register: zookeeper_exec_file + + - name: Assert Zookeeper location + assert: + that: + - zookeeper_exec_file.stat.exists + fail_msg: Zookeeper not found in /opt/zookeeper (Epiphany default) - check your configuration diff --git a/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/defaults/main.yml b/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/defaults/main.yml index be778b2aa0..b537b0d395 100644 --- a/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/defaults/main.yml +++ b/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/defaults/main.yml @@ -1,5 +1,8 @@ --- +zookeeper_version: 3.5.8 +zookeeper_bin_filename: "apache-zookeeper-3.5.8-bin.tar.gz" + zookeeper_hosts: "{{ groups['zookeeper'] }}" zookeeper_data_dir: /var/lib/zookeeper diff --git a/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/files/snapshot.0 b/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/files/snapshot.0 new file mode 100644 index 0000000000000000000000000000000000000000..3e6deee02b83966e6e933ea33a686a7c11223515 GIT binary patch literal 424 zcma#@4)$YUU|{+W1wb|kFhVFW4Pt{ZYk7WAP7090mY7$WpO*?%!hog~CQK^LrC*hw zpPiaokXi)NN+nYT5vJ-V=jWwmrX#rv=1U|Y>`ahju*e7?8D3bLUy=w?LnVhZ>Vpj1 MvB=sJNHOXI0LqX(R{#J2 literal 0 HcmV?d00001 diff --git a/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/tasks/main.yml b/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/tasks/main.yml index ce4f14de98..b2086d6ece 100644 --- a/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/tasks/main.yml +++ b/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/tasks/main.yml @@ -1,5 +1,4 @@ --- -# Zookeeper tasks - resides on masters - name: Create Zookeeper group group: @@ -30,19 +29,18 @@ path: "{{ prometheus_jmx_path }}" register: exporter -- name: Set zookeeper variable with version name +- name: Set Zookeeper variable with version name set_fact: - zookeeper_name: "zookeeper-{{ specification.version }}" + zookeeper_name: "zookeeper-{{ zookeeper_version }}" changed_when: false -- name: Set zookeeper install dir for {{ zookeeper_name }} +- name: Set Zookeeper install dir for {{ zookeeper_name }} set_fact: zookeeper_install_dir: "/opt/{{ zookeeper_name }}" - changed_when: false - name: Set Zookeeper file name to install set_fact: - zookeeper_file_name: "{{ specification.file_name }}" + zookeeper_file_name: "{{ zookeeper_bin_filename }}" - name: Download Zookeeper binaries include_role: @@ -58,7 +56,7 @@ recurse: yes owner: "{{ zookeeper_user }}" group: "{{ zookeeper_group }}" - mode: 0750 + mode: u=rwx,g=rx,o= state: directory with_items: - "{{ zookeeper_install_dir }}" @@ -71,7 +69,7 @@ dest: "{{ zookeeper_install_dir }}" creates: "{{ zookeeper_install_dir }}/bin" extra_opts: [--strip-components=1] - mode: 0755 + mode: u=rwx,g=rx,o=rx owner: "{{ zookeeper_user }}" group: "{{ zookeeper_group }}" check_mode: false @@ -88,7 +86,7 @@ - "{{ zookeeper_install_dir }}/conf" - "/etc/zookeeper/conf" -- name: Create zookeeper service +- name: Create Zookeeper service template: src: zookeeper.service.j2 dest: /lib/systemd/system/zookeeper.service @@ -116,14 +114,11 @@ - name: Link /opt/zookeeper to the right version file: path=/opt/zookeeper state=link src="{{ zookeeper_install_dir }}" -# - name: Link /etc/zookeeper/conf to /opt/zookeeper/config -# file: path=/etc/zookeeper/conf state=link src=/opt/zookeeper/conf - - name: Add Zookeeper's bin dir to the PATH copy: content: "export PATH=$PATH:/opt/zookeeper/bin" dest: "/etc/profile.d/zookeeper_path.sh" - mode: 0755 + mode: u=rwx,g=rx,o=rx - name: Update the log4j config with saner production values template: @@ -145,4 +140,3 @@ - include_tasks: metrics.yml when: exporter.stat.exists - diff --git a/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/templates/zookeeper.service.j2 b/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/templates/zookeeper.service.j2 index 72d557c448..22361e803d 100644 --- a/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/templates/zookeeper.service.j2 +++ b/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/templates/zookeeper.service.j2 @@ -10,7 +10,7 @@ Group={{ zookeeper_group }} {% if exporter.stat.exists %} Environment="SERVER_JVMFLAGS=-javaagent:{{ prometheus_jmx_path }}={{ prometheus_jmx_exporter_web_listen_port }}:{{ prometheus_jmx_config }}" {% endif %} -ExecStart={{zookeeper_install_dir}}/bin/zkServer.sh start-foreground +ExecStart=/opt/zookeeper/bin/zkServer.sh start-foreground Restart=always RestartSec=3 diff --git a/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/vars/main.yml b/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/vars/main.yml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/core/src/epicli/data/common/ansible/playbooks/upgrade.yml b/core/src/epicli/data/common/ansible/playbooks/upgrade.yml index 393ad690b5..f41e55f609 100644 --- a/core/src/epicli/data/common/ansible/playbooks/upgrade.yml +++ b/core/src/epicli/data/common/ansible/playbooks/upgrade.yml @@ -98,6 +98,16 @@ # name: upgrade # tasks_from: filebeat +- hosts: zookeeper + serial: 1 + become: true + become_method: sudo + tasks: + - import_role: + name: upgrade + tasks_from: zookeeper + vars: { lock_file: /var/tmp/zookeeper-upgrade-in-progress.flag } + - hosts: kafka serial: 1 become: true diff --git a/core/src/epicli/data/common/defaults/configuration/zookeeper.yml b/core/src/epicli/data/common/defaults/configuration/zookeeper.yml index 2cd6157f35..3023ca2258 100644 --- a/core/src/epicli/data/common/defaults/configuration/zookeeper.yml +++ b/core/src/epicli/data/common/defaults/configuration/zookeeper.yml @@ -1,6 +1,4 @@ kind: configuration/zookeeper title: "Zookeeper" name: default -specification: - version: 3.4.12 - file_name: "zookeeper-3.4.12.tar.gz" \ No newline at end of file +specification: {} diff --git a/docs/home/COMPONENTS.md b/docs/home/COMPONENTS.md index 7b827e9972..a4eb392101 100644 --- a/docs/home/COMPONENTS.md +++ b/docs/home/COMPONENTS.md @@ -12,7 +12,7 @@ Note that versions are default versions and can be changed in certain cases thro | Flannel | 0.12.0 | https://github.com/coreos/flannel/ | [Apache License](https://www.apache.org/licenses/LICENSE-1.0) | | Canal | 3.15.0 | https://github.com/projectcalico/calico | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) | | Kafka | 2.3.1 | https://github.com/apache/kafka | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) | -| Zookeeper | 3.4.12 | https://github.com/apache/zookeeper | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) | +| Zookeeper | 3.5.8 | https://github.com/apache/zookeeper | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) | | RabbitMQ | 3.8.3 | https://github.com/rabbitmq/rabbitmq-server | [Mozilla Public License](https://www.mozilla.org/en-US/MPL/) | | Docker-ce | 18.09 | https://github.com/docker/docker-ce/ | [Apache License](https://www.apache.org/licenses/LICENSE-1.0) | | KeyCloak | 9.0.0 | https://github.com/keycloak/keycloak | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) | From 9cf23996e865f897982f5eb56489034143506323 Mon Sep 17 00:00:00 2001 From: rpudlowski93 Date: Wed, 24 Feb 2021 13:27:17 +0000 Subject: [PATCH 2/2] Zookeeper upgrade tests added --- .../playbooks/roles/zookeeper/tasks/main.yml | 2 +- .../roles/zookeeper/templates/zoo.cfg.j2 | 35 +++++++++++ .../roles/zookeeper/templates/zoo.j2 | 20 ------ .../defaults/configuration/zookeeper.yml | 16 ++++- .../common/tests/spec/kafka/kafka_spec.rb | 47 ++++++++------ .../tests/spec/zookeeper/zookeeper_helpers.rb | 16 +++++ .../tests/spec/zookeeper/zookeeper_spec.rb | 62 ++++++++++--------- 7 files changed, 129 insertions(+), 69 deletions(-) create mode 100644 core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/templates/zoo.cfg.j2 delete mode 100644 core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/templates/zoo.j2 create mode 100644 core/src/epicli/data/common/tests/spec/zookeeper/zookeeper_helpers.rb diff --git a/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/tasks/main.yml b/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/tasks/main.yml index b2086d6ece..9fae5309c0 100644 --- a/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/tasks/main.yml +++ b/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/tasks/main.yml @@ -105,7 +105,7 @@ - name: Configure Zookeeper template: - src: zoo.j2 + src: zoo.cfg.j2 dest: "{{ zookeeper_install_dir }}/conf/zoo.cfg" owner: "{{ zookeeper_user }}" group: "{{ zookeeper_group }}" diff --git a/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/templates/zoo.cfg.j2 b/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/templates/zoo.cfg.j2 new file mode 100644 index 0000000000..191da26220 --- /dev/null +++ b/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/templates/zoo.cfg.j2 @@ -0,0 +1,35 @@ +# {{ ansible_managed }} + +# ========================= Epiphany built-in settings ========================= + +# --- Based on zoo_sample.cfg --- + +# The number of milliseconds of each tick +tickTime=2000 +# The number of ticks that the initial +# synchronization phase can take +initLimit=10 +# The number of ticks that can pass between +# sending a request and getting an acknowledgement +syncLimit=5 +# The directory where the snapshot is stored +dataDir={{ zookeeper_data_dir }} +# The port at which the clients will connect +clientPort=2181 + +# --- Added by Epiphany team --- + +# The directory where the transaction logs are stored +dataLogDir={{ zookeeper_log_dir }} + +{% for host in zookeeper_hosts %} +server.{{loop.index}}={{ host }}:2888:3888 +{% endfor %} + +{% if specification.static_config_file.configurable_block is defined + and specification.static_config_file.configurable_block is string + and specification.static_config_file.configurable_block | length > 0 %} +# =============== Settings from Epiphany configuration/zookeeper =============== + +{{ specification.static_config_file.configurable_block }} +{% endif %} diff --git a/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/templates/zoo.j2 b/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/templates/zoo.j2 deleted file mode 100644 index f4f41f0fb5..0000000000 --- a/core/src/epicli/data/common/ansible/playbooks/roles/zookeeper/templates/zoo.j2 +++ /dev/null @@ -1,20 +0,0 @@ -# 0 is unlimited -maxClientCnxns=0 -# The number of milliseconds of each tick -tickTime=2000 -# The number of ticks that the initial -# synchronization phase can take -initLimit=10 -# The number of ticks that can pass between -# sending a request and getting an acknowledgement -syncLimit=5 -# the directory where the snapshot is stored. -dataDir={{ zookeeper_data_dir }} -# the port at which the clients will connect -clientPort=2181 -# the directory where the transaction logs are stored. -dataLogDir={{ zookeeper_log_dir }} - -{% for host in zookeeper_hosts %} -server.{{loop.index}}={{ host }}:2888:3888 -{% endfor %} diff --git a/core/src/epicli/data/common/defaults/configuration/zookeeper.yml b/core/src/epicli/data/common/defaults/configuration/zookeeper.yml index 3023ca2258..5f006c6874 100644 --- a/core/src/epicli/data/common/defaults/configuration/zookeeper.yml +++ b/core/src/epicli/data/common/defaults/configuration/zookeeper.yml @@ -1,4 +1,18 @@ kind: configuration/zookeeper title: "Zookeeper" name: default -specification: {} +specification: + static_config_file: + # This block is injected to $ZOOCFGDIR/zoo.cfg + configurable_block: | + # Limits the number of concurrent connections (at the socket level) that a single client, identified by IP address, + # may make to a single member of the ZooKeeper ensemble. This is used to prevent certain classes of DoS attacks, + # including file descriptor exhaustion. The default is 60. Setting this to 0 removes the limit. + maxClientCnxns=0 + # --- AdminServer configuration --- + # By default the AdminServer is enabled. Disabling it will cause automated test failures. + admin.enableServer=true + # The address the embedded Jetty server listens on. Defaults to 0.0.0.0. + admin.serverAddress=127.0.0.1 + # The port the embedded Jetty server listens on. Defaults to 8080. + admin.serverPort=8008 diff --git a/core/src/epicli/data/common/tests/spec/kafka/kafka_spec.rb b/core/src/epicli/data/common/tests/spec/kafka/kafka_spec.rb index ccb6d51300..a77b290a19 100644 --- a/core/src/epicli/data/common/tests/spec/kafka/kafka_spec.rb +++ b/core/src/epicli/data/common/tests/spec/kafka/kafka_spec.rb @@ -1,18 +1,20 @@ require 'spec_helper' +require_relative '../zookeeper/zookeeper_helpers' kafka_host = '$(hostname)' kafka_port = 9092 zookeeper_host = 'localhost' zookeeper_client_port = 2181 +zookeeper_admin_server_port = get_zookeeper_admin_server_port -describe 'Checking if Kafka service is running' do +describe 'Check if Kafka service is running' do describe service('kafka') do it { should be_enabled } it { should be_running } end end -describe 'Checking if Kafka user exists' do +describe 'Check if Kafka user exists' do describe group('kafka') do it { should exist } end @@ -24,30 +26,39 @@ end end -describe 'Checking if the ports are open' do +describe 'Check if the ports are open' do describe port(kafka_port) do let(:disable_sudo) { false } it { should be_listening } end -end -describe 'Listing down all the active brokers' do + describe port(zookeeper_admin_server_port) do + let(:disable_sudo) { false } # required for RHEL + it { should be_listening } + end +end + +describe 'Check if it is possible to list down all active brokers' do describe command("echo 'ls /brokers/ids' | /opt/kafka/bin/zookeeper-shell.sh #{zookeeper_host}:#{zookeeper_client_port}") do its(:stdout) { should match /Welcome to ZooKeeper!/ } - its(:stdout) { should match /\[(\d+(\,\s)?)+\]/ } # pattern: [0, 1, 2, 3 ...] + its(:stdout) { should match /\[(\d+(\,\s)?)+\]/ } # pattern: [0, 1, 2, 3 ...] + its(:exit_status) { should eq 0 } + end + describe command("curl -s http://localhost:#{zookeeper_admin_server_port}/commands/dump | grep brokers") do + its(:stdout) { should match /\/brokers\/ids\/\d+/ } # pattern: /brokers/ids/0 its(:exit_status) { should eq 0 } end end -describe 'Checking if the number of Kafka brokers is the same as indicated in the inventory file' do - describe command("echo 'dump' | curl -s telnet://#{zookeeper_host}:#{zookeeper_client_port} | grep -c brokers") do +describe 'Check if the number of Kafka brokers is the same as indicated in the inventory file' do + describe command("curl -s http://localhost:#{zookeeper_admin_server_port}/commands/dump | grep -c brokers") do it "is expected to be equal" do expect(subject.stdout.to_i).to eq countInventoryHosts("kafka") end end end -describe 'Checking the possibility of creating a topic, producing and consuming messages' do +describe 'Check the possibility of creating a topic, producing and consuming messages' do kafka_brokers_count = countInventoryHosts("kafka") timestamp = DateTime.now.to_time.to_i.to_s @@ -55,7 +66,7 @@ partitions = kafka_brokers_count*3 message = 'test message' - describe 'Checking if the topic was created' do + describe 'Check if the topic was created' do describe command("/opt/kafka/bin/kafka-topics.sh --create --zookeeper #{zookeeper_host}:#{zookeeper_client_port} --replication-factor #{kafka_brokers_count} \ --partitions #{partitions} --topic #{topic_name}") do its(:stdout) { should match /Created topic "?#{topic_name}"?\./ } @@ -63,14 +74,14 @@ end end - describe 'Starting consumer process' do + describe 'Start consumer process' do describe command("/opt/kafka/bin/kafka-console-consumer.sh --bootstrap-server #{kafka_host}:#{kafka_port} --topic #{topic_name} --consumer-property group.id=TESTGROUP \ >> /tmp/#{topic_name}.txt 2>&1 &") do its(:exit_status) { should eq 0 } end end - describe 'Checking if consumer process is ready' do + describe 'Check if consumer process is ready' do describe command("for i in {1..10}; do if /opt/kafka/bin/kafka-consumer-groups.sh --bootstrap-server #{kafka_host}:#{kafka_port} --group TESTGROUP --describe \ | grep #{topic_name}; then echo 'READY'; break; else echo 'WAITING'; sleep 0.5; fi; done;") do its(:stdout) { should match /#{topic_name}/ } @@ -79,25 +90,25 @@ end 10.times do |i| - describe "Sending message #{i+1} from producer" do + describe "Send message #{i+1} from producer" do describe command("echo '#{message} #{i+1}' | /opt/kafka/bin/kafka-console-producer.sh --broker-list #{kafka_host}:#{kafka_port} --topic #{topic_name}") do its(:exit_status) { should eq 0 } end end - describe 'Checking if the consumer output contains the message that was produced' do + describe 'Check if the consumer output contains the message that was produced' do describe command("cat /tmp/#{topic_name}.txt") do its(:stdout) { should match /^#{message} #{i+1}$/ } end end end - describe 'Checking if the created topic is on the list with all available topics in Kafka' do + describe 'Check if the created topic is on the list with all available topics in Kafka' do describe command("/opt/kafka/bin/kafka-topics.sh --list --zookeeper #{zookeeper_host}:#{zookeeper_client_port}") do its(:stdout) { should match /#{topic_name}/ } end - end + end - describe 'Cleaning up' do + describe 'Clean up' do describe command("/opt/kafka/bin/kafka-topics.sh --delete --zookeeper #{zookeeper_host}:#{zookeeper_client_port} --topic #{topic_name}") do its(:stdout) { should match /Topic #{topic_name} is marked for deletion./ } its(:exit_status) { should eq 0 } @@ -111,5 +122,5 @@ describe command("kill -9 $(ps aux | grep -i 'kafka.tools.ConsoleConsumer' | grep '#{topic_name}' | grep -v 'grep' | awk '{print $2}')") do its(:exit_status) { should eq 0 } end - end + end end diff --git a/core/src/epicli/data/common/tests/spec/zookeeper/zookeeper_helpers.rb b/core/src/epicli/data/common/tests/spec/zookeeper/zookeeper_helpers.rb new file mode 100644 index 0000000000..b14fb411ee --- /dev/null +++ b/core/src/epicli/data/common/tests/spec/zookeeper/zookeeper_helpers.rb @@ -0,0 +1,16 @@ +require 'net/ssh' + +def get_zookeeper_admin_server_port + default_port = 8080 + config_file = "/opt/zookeeper/conf/zoo.cfg" + grep_cmd = "sudo -u zookeeper grep -Po '(?<=^admin\\.serverPort=)\\d+' #{config_file}" + port = "" + + Net::SSH.start(ENV['TARGET_HOST'], ENV['user'], keys: [ENV['keypath']], :keys_only => true) do |ssh| + ssh.exec!(grep_cmd) do |channel, stream, data| + port << data if stream == :stdout && /^[0-9]+$/.match(data) + end + end + + return port.empty? ? default_port : port.to_i +end diff --git a/core/src/epicli/data/common/tests/spec/zookeeper/zookeeper_spec.rb b/core/src/epicli/data/common/tests/spec/zookeeper/zookeeper_spec.rb index c45ada3aef..bd7a4454f0 100644 --- a/core/src/epicli/data/common/tests/spec/zookeeper/zookeeper_spec.rb +++ b/core/src/epicli/data/common/tests/spec/zookeeper/zookeeper_spec.rb @@ -1,4 +1,5 @@ require 'spec_helper' +require_relative 'zookeeper_helpers' kafka_host = 'localhost' kafka_port = 9092 @@ -6,36 +7,45 @@ zookeeper_client_port = 2181 zookeeper_peer_port = 2888 zookeeper_leader_port = 3888 +zookeeper_admin_server_port = get_zookeeper_admin_server_port -describe 'Checking if ZooKeeper service is running' do +describe 'Check if ZooKeeper service is running' do describe service('zookeeper') do it { should be_enabled } it { should be_running } end end -describe 'Checking if the ports are open' do +describe 'Check if the ports are open' do - # checking port for client connections - describe port(zookeeper_client_port) do - let(:disable_sudo) { false } + # check port for client connections + describe port(zookeeper_client_port) do + let(:disable_sudo) { false } # required for RHEL it { should be_listening } end - - # checking port for follower connections to the leader + + # check port for follower connections to the leader describe command("if /opt/zookeeper/bin/zkServer.sh status | grep 'Mode: leader'; then netstat -tunl | grep #{zookeeper_peer_port}; else echo 'not leader'; fi") do + let(:disable_sudo) { false } its(:stdout) { should match /#{zookeeper_peer_port}|not leader/ } its(:exit_status) { should eq 0 } end - # checking port for leader election + # check port for leader election describe command("if /opt/zookeeper/bin/zkServer.sh status | grep 'Mode: standalone'; then echo 'standalone'; else netstat -tunl | grep #{zookeeper_leader_port}; fi") do + let(:disable_sudo) { false } its(:stdout) { should match /#{zookeeper_leader_port}|standalone/ } its(:exit_status) { should eq 0 } end -end -describe 'Checking if ZooKeeper user exists' do + # check port for AdminServer + describe port(zookeeper_admin_server_port) do + let(:disable_sudo) { false } # required for RHEL + it { should be_listening } + end +end + +describe 'Check if ZooKeeper user exists' do describe group('zookeeper') do it { should exist } end @@ -51,35 +61,29 @@ end end -describe 'Checking if ZooKeeper is healthy' do - describe command("echo 'stat' | curl -s telnet://#{zookeeper_host}:#{zookeeper_client_port}") do - its(:stdout) { should match /Zookeeper version/ } +describe 'Check if ZooKeeper is healthy' do + describe command("curl http://localhost:#{zookeeper_admin_server_port}/commands/stat") do + its(:stdout_as_json) { should include('error' => nil) } end - describe command("echo 'ruok' | curl -s telnet://#{zookeeper_host}:#{zookeeper_client_port}") do - its(:stdout) { should match /imok/ } + describe command("curl http://localhost:#{zookeeper_admin_server_port}/commands/ruok") do + its(:stdout_as_json) { should include('error' => nil) } end end -describe 'Checking ZooKeeper status' do +describe 'Check ZooKeeper status' do describe command('/opt/zookeeper/bin/zkServer.sh status 2>&1') do + let(:disable_sudo) { false } + let(:sudo_options) { '-u zookeeper' } its(:stdout) { should match /Mode: leader|Mode: follower|Mode: standalone/ } its(:stdout) { should_not match /Error contacting service. It is probably not running./ } end -end +end -describe 'Checking if it is possible to list down and count all the active brokers' do - describe command("echo 'ls /brokers/ids' | /opt/zookeeper/bin/zkCli.sh -server #{zookeeper_host}:#{zookeeper_client_port}") do +describe 'Check ZooKeeper client' do + describe command("echo 'quit' | /opt/zookeeper/bin/zkCli.sh -server #{zookeeper_host}:#{zookeeper_client_port}") do + let(:disable_sudo) { false } + let(:sudo_options) { '-u zookeeper' } its(:stdout) { should match /Welcome to ZooKeeper!/ } - its(:stdout) { should match /\[(\d+(\,\s)?)+\]/ } # pattern: [0, 1, 2, 3 ...] - its(:exit_status) { should eq 0 } - end - describe command("echo 'dump' | curl -s telnet://#{zookeeper_host}:#{zookeeper_client_port} | grep brokers") do - its(:stdout) { should match /\/brokers\/ids\/\d+/ } # pattern: /brokers/ids/0 its(:exit_status) { should eq 0 } - end - describe command("echo 'dump' | curl -s telnet://#{zookeeper_host}:#{zookeeper_client_port} | grep -c brokers") do - it "is expected to be equal" do - expect(subject.stdout.to_i).to eq countInventoryHosts("kafka") - end end end