From f10037152b6d4e29359e16cbb2f0f0674624e2f3 Mon Sep 17 00:00:00 2001 From: Katya Ryazantseva Date: Wed, 7 Jan 2026 00:39:29 +0100 Subject: [PATCH 1/2] fix: add clean-data playbook to prevent storage issues --- ansible/playbooks/clean-data.yml | 114 ++++++++++++++++++++++++ ansible/playbooks/site.yml | 15 +++- ansible/roles/lantern/tasks/main.yml | 13 ++- ansible/roles/lighthouse/tasks/main.yml | 13 ++- ansible/roles/qlean/tasks/main.yml | 13 ++- ansible/roles/ream/tasks/main.yml | 13 ++- ansible/roles/zeam/tasks/main.yml | 13 ++- 7 files changed, 186 insertions(+), 8 deletions(-) create mode 100644 ansible/playbooks/clean-data.yml diff --git a/ansible/playbooks/clean-data.yml b/ansible/playbooks/clean-data.yml new file mode 100644 index 0000000..84d2857 --- /dev/null +++ b/ansible/playbooks/clean-data.yml @@ -0,0 +1,114 @@ +--- +# Clean data playbook: Clean node data directories + +- name: Parse and validate node names + hosts: localhost + connection: local + gather_facts: no + vars: + validator_config_file: "{{ genesis_dir }}/validator-config.yaml" + tags: + - zeam + - ream + - qlean + - lantern + - lighthouse + - deploy + + tasks: + - name: Validate validator-config.yaml exists + stat: + path: "{{ validator_config_file }}" + register: validator_config_stat + + - name: Fail if validator-config.yaml missing + fail: + msg: "validator-config.yaml not found at {{ validator_config_file }}" + when: not validator_config_stat.stat.exists + + - name: Extract all node names + shell: | + yq eval '.validators[].name' {{ validator_config_file }} + register: all_node_names_raw + changed_when: false + + - name: Set all node names + set_fact: + all_node_names: "{{ all_node_names_raw.stdout_lines }}" + + - name: Fail if node_names is not specified + fail: + msg: "node_names must be specified. Provide one or more node names (comma or space separated)." + when: node_names is not defined or node_names == "" + + - name: Handle "all" node names - expand to all nodes + set_fact: + clean_nodes: "{{ all_node_names }}" + when: + - node_names is defined + - node_names == "all" + + - name: Parse node names if provided as comma-separated string + set_fact: + clean_nodes: "{{ node_names.split(',') | map('trim') | list }}" + when: + - node_names is defined + - node_names is string + - node_names != "all" + - '("," in node_names)' + + - name: Parse node names if provided as space-separated string + set_fact: + clean_nodes: "{{ node_names.split(' ') | map('trim') | select('length') | list }}" + when: + - node_names is defined + - node_names is string + - node_names != "all" + - '("," not in node_names)' + - '(" " in node_names)' + + - name: Handle single node name + set_fact: + clean_nodes: "{{ [node_names] }}" + when: + - node_names is defined + - node_names is string + - node_names != "all" + - '"," not in node_names' + - '" " not in node_names' + + - name: Display nodes to clean + debug: + msg: "Cleaning data directories for nodes: {{ clean_nodes | join(', ') }}" + + - name: Add nodes to clean_targets group + add_host: + name: "{{ item }}" + groups: clean_targets + loop: "{{ clean_nodes }}" + +- name: Clean node data directories on remote hosts + hosts: clean_targets + gather_facts: no + vars: + # Use remote paths on remote hosts + data_dir: "{{ remote_data_dir | default('/opt/lean-quickstart/data') }}" + node_name: "{{ inventory_hostname }}" + tags: + - zeam + - ream + - qlean + - lantern + - lighthouse + - deploy + + tasks: + - name: Clean node data directory + file: + path: "{{ data_dir }}/{{ node_name }}" + state: absent + become: yes + + - name: Display cleaned directory + debug: + msg: "Cleaned data directory: {{ data_dir }}/{{ node_name }}" diff --git a/ansible/playbooks/site.yml b/ansible/playbooks/site.yml index c62bf91..27b7bdb 100644 --- a/ansible/playbooks/site.yml +++ b/ansible/playbooks/site.yml @@ -1,8 +1,9 @@ --- # Main site playbook: Complete deployment workflow -# 1. Generate genesis files locally (including .key files) -# 2. Copy genesis files to remote hosts -# 3. Deploy nodes +# 1. Clean data directories (if clean_data=true) +# 2. Generate genesis files locally (including .key files) +# 3. Copy genesis files to remote hosts +# 4. Deploy nodes # # Usage: # ansible-playbook -i inventory/hosts.yml playbooks/site.yml \ @@ -13,9 +14,17 @@ # network_dir - Path to network directory (genesis_dir derived from this) # genesis_dir - Path to genesis directory (required) # node_names - Nodes to deploy: "all" or comma-separated names +# clean_data - Set to true to clean data directories before deployment (default: false) # skip_genesis - Set to true to skip genesis generation (default: false) # genesis_offset - Seconds to add to current time for genesis (default: 360 for ansible mode) +- name: Clean Data Directories + import_playbook: clean-data.yml + vars: + genesis_dir: "{{ network_dir }}/genesis" + node_names: "{{ node_names }}" + when: clean_data | default(false) | bool + - name: Generate Genesis Files import_playbook: generate-genesis.yml vars: diff --git a/ansible/roles/lantern/tasks/main.yml b/ansible/roles/lantern/tasks/main.yml index 9932194..34fbeec 100644 --- a/ansible/roles/lantern/tasks/main.yml +++ b/ansible/roles/lantern/tasks/main.yml @@ -60,11 +60,22 @@ msg: "Node key file {{ node_name }}.key not found in {{ genesis_dir }}" when: not (node_key_stat.stat.exists | default(false)) +- name: Check if node data directory has contents + find: + paths: "{{ data_dir }}/{{ node_name }}" + file_type: any + hidden: yes + register: node_data_contents + failed_when: false + when: clean_data | default(false) | bool + - name: Clean node data directory file: path: "{{ data_dir }}/{{ node_name }}" state: absent - when: clean_data | default(false) | bool + when: + - clean_data | default(false) | bool + - node_data_contents.matched | default(0) > 0 - name: Create node data directory file: diff --git a/ansible/roles/lighthouse/tasks/main.yml b/ansible/roles/lighthouse/tasks/main.yml index feed56c..88d3fbf 100644 --- a/ansible/roles/lighthouse/tasks/main.yml +++ b/ansible/roles/lighthouse/tasks/main.yml @@ -58,11 +58,22 @@ msg: "Node key file {{ node_name }}.key not found in {{ genesis_dir }}" when: not (node_key_stat.stat.exists | default(false)) +- name: Check if node data directory has contents + find: + paths: "{{ data_dir }}/{{ node_name }}" + file_type: any + hidden: yes + register: node_data_contents + failed_when: false + when: clean_data | default(false) | bool + - name: Clean node data directory file: path: "{{ data_dir }}/{{ node_name }}" state: absent - when: clean_data | default(false) | bool + when: + - clean_data | default(false) | bool + - node_data_contents.matched | default(0) > 0 - name: Create node data directory file: diff --git a/ansible/roles/qlean/tasks/main.yml b/ansible/roles/qlean/tasks/main.yml index eaf1c5a..b6911bf 100644 --- a/ansible/roles/qlean/tasks/main.yml +++ b/ansible/roles/qlean/tasks/main.yml @@ -72,11 +72,22 @@ msg: "Node key file {{ node_name }}.key not found in {{ genesis_dir }}" when: not (node_key_stat.stat.exists | default(false)) +- name: Check if node data directory has contents + find: + paths: "{{ data_dir }}/{{ node_name }}" + file_type: any + hidden: yes + register: node_data_contents + failed_when: false + when: clean_data | default(false) | bool + - name: Clean node data directory file: path: "{{ data_dir }}/{{ node_name }}" state: absent - when: clean_data | default(false) | bool + when: + - clean_data | default(false) | bool + - node_data_contents.matched | default(0) > 0 - name: Create node data directory file: diff --git a/ansible/roles/ream/tasks/main.yml b/ansible/roles/ream/tasks/main.yml index 1ed3326..385731a 100644 --- a/ansible/roles/ream/tasks/main.yml +++ b/ansible/roles/ream/tasks/main.yml @@ -60,11 +60,22 @@ msg: "Node key file {{ node_name }}.key not found in {{ genesis_dir }}" when: not (node_key_stat.stat.exists | default(false)) +- name: Check if node data directory has contents + find: + paths: "{{ data_dir }}/{{ node_name }}" + file_type: any + hidden: yes + register: node_data_contents + failed_when: false + when: clean_data | default(false) | bool + - name: Clean node data directory file: path: "{{ data_dir }}/{{ node_name }}" state: absent - when: clean_data | default(false) | bool + when: + - clean_data | default(false) | bool + - node_data_contents.matched | default(0) > 0 - name: Create node data directory file: diff --git a/ansible/roles/zeam/tasks/main.yml b/ansible/roles/zeam/tasks/main.yml index a0936c9..bdc0f39 100644 --- a/ansible/roles/zeam/tasks/main.yml +++ b/ansible/roles/zeam/tasks/main.yml @@ -65,11 +65,22 @@ msg: "Node key file {{ node_name }}.key not found in {{ genesis_dir }}" when: not (node_key_stat.stat.exists | default(false)) +- name: Check if node data directory has contents + find: + paths: "{{ data_dir }}/{{ node_name }}" + file_type: any + hidden: yes + register: node_data_contents + failed_when: false + when: clean_data | default(false) | bool + - name: Clean node data directory file: path: "{{ data_dir }}/{{ node_name }}" state: absent - when: clean_data | default(false) | bool + when: + - clean_data | default(false) | bool + - node_data_contents.matched | default(0) > 0 - name: Create node data directory file: From 8a0129f99df3ac9fb3d2a97e6507baa285d48c07 Mon Sep 17 00:00:00 2001 From: Katya Ryazantseva Date: Tue, 13 Jan 2026 23:36:31 +0100 Subject: [PATCH 2/2] fix: use raw module for cleaning --- ansible/playbooks/clean-data.yml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/ansible/playbooks/clean-data.yml b/ansible/playbooks/clean-data.yml index 84d2857..a2a8368 100644 --- a/ansible/playbooks/clean-data.yml +++ b/ansible/playbooks/clean-data.yml @@ -26,6 +26,18 @@ msg: "validator-config.yaml not found at {{ validator_config_file }}" when: not validator_config_stat.stat.exists + - name: Verify yq is available + command: yq --version + register: yq_version + changed_when: false + failed_when: false + ignore_errors: true + + - name: Fail if yq is not available + fail: + msg: "yq is required but not installed. Install on macOS: brew install yq, or see https://github.com/mikefarah/yq" + when: yq_version.rc != 0 + - name: Extract all node names shell: | yq eval '.validators[].name' {{ validator_config_file }} @@ -104,10 +116,7 @@ tasks: - name: Clean node data directory - file: - path: "{{ data_dir }}/{{ node_name }}" - state: absent - become: yes + raw: rm -rf {{ data_dir }}/{{ node_name }} - name: Display cleaned directory debug: