From 30289f527ed022fc44bd16088db9740e4148149b Mon Sep 17 00:00:00 2001 From: Igor Duarte Date: Mon, 4 Dec 2023 16:19:21 -0300 Subject: [PATCH] ansible-scylla-node: Use Scylla API for getting existent tokens instead of nodetool ring Currently we're using nodetool ring to get the current tokens and iterating over its output in order to create an ansible fact with all the tokens. This might be a problem when using ansible verbose mode since nodetool ring prints one token per line and every time we append a value to the ansible fact the whole fact will be printed resulting in a very big number of lines printed, specially for big clusters. This patch fixes this problem by using the API to get the current tokens and by writing them to a file instead of to an ansible fact. This patch also removes the task validating that all nodes are in UN state, since the nodes don't have to be up in order for us to be able to retrieve existent tokens and generate the new ones. --- ansible-scylla-node/tasks/generate_tokens.yml | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/ansible-scylla-node/tasks/generate_tokens.yml b/ansible-scylla-node/tasks/generate_tokens.yml index 74e6ddd7..bf1103fd 100644 --- a/ansible-scylla-node/tasks/generate_tokens.yml +++ b/ansible-scylla-node/tasks/generate_tokens.yml @@ -16,18 +16,6 @@ loop: "{{ wait_for_cql_port_output.results }}" when: bootstrapped_node is not defined and item.failed == False -- name: Validate that all nodes are in UN state and save token lists - block: - - shell: | - nodetool ring | grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' - register: _nodetool_ring_output - - set_fact: - token_list: "{{ token_list | default({}) | combine( {item.split()[0]: (token_list | default({}))[item.split()[0]] | default([]) + [item.split()[7]]} ) }}" - failed_when: item.split()[2] != 'Up' or item.split()[3] != 'Normal' - loop: "{{ _nodetool_ring_output.stdout_lines }}" - delegate_to: "{{ bootstrapped_node }}" - when: bootstrapped_node is defined - - name: Prepare script arguments set_fact: node_list: "{{ node_list | default([]) + [hostvars[item]['broadcast_address']] }}" @@ -35,19 +23,41 @@ dc_list: "{{ dc_list | default([]) + [hostvars[item]['dc']] }}" loop: "{{ groups['scylla'] }}" -- name: Prepare old tokens list - set_fact: - token_list_str: "{{ token_list.keys() | zip(token_list.values()) | map('join', '=') | join('\n') | replace('[','') | replace(']','') | replace(\"'\", '') | replace(' ', '') }}" - when: token_list is defined +- name: Create an empty tokens file + copy: + content: "" + dest: /tmp/tokens_file + delegate_to: localhost + +- name: Get existent tokens + block: + - name: Get tokens + uri: + url: "http://{{ scylla_api_address }}:{{ scylla_api_port }}/storage_service/tokens/{{ item }}" + method: GET + register: _existent_tokens + until: _existent_tokens.status == 200 + retries: 5 + delay: 1 + delegate_to: "{{ bootstrapped_node }}" + loop: "{{ groups['scylla'] }}" + + - name: copy output to file + lineinfile: + path: "/tmp/tokens_file" + line: "{{ item.item }}={{ item.json | map('int') | join(',') }}" + create: yes + when: item.json|length > 0 + delegate_to: localhost + loop: "{{ _existent_tokens.results }}" + when: bootstrapped_node is defined - name: Generate and save tokens for the new nodes delegate_to: localhost become: false environment: PYTHONPATH: "{{ token_distributor.path }}" - shell: "{{ token_distributor.path }}/token_distributor.py --node={{ node_list | join(',') }} --rack={{ rack_list | join(',') }} --dc={{ dc_list | join(',') }} --rf={{ token_distributor.rf }}" - args: - stdin: "{% if token_list_str is defined %}{{ token_list_str }}{% endif %}" + shell: "{{ token_distributor.path }}/token_distributor.py --node={{ node_list | join(',') }} --rack={{ rack_list | join(',') }} --dc={{ dc_list | join(',') }} --rf={{ token_distributor.rf }} --tokens-file /tmp/tokens_file" register: _new_tokens - name: Set initial tokens in scylla.yaml