Skip to content

Commit

Permalink
ansible-scylla-node: Use Scylla API for getting existent tokens inste…
Browse files Browse the repository at this point in the history
…ad 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.
  • Loading branch information
igorribeiroduarte committed Dec 6, 2023
1 parent bba5385 commit 30289f5
Showing 1 changed file with 29 additions and 19 deletions.
48 changes: 29 additions & 19 deletions ansible-scylla-node/tasks/generate_tokens.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,38 +16,48 @@
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']] }}"
rack_list: "{{ rack_list | default([]) + [hostvars[item]['rack']] }}"
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
Expand Down

0 comments on commit 30289f5

Please sign in to comment.