diff --git a/ansible/roles/distribute-validators/README.md b/ansible/roles/distribute-validators/README.md index 7266b0a..5fbd43d 100644 --- a/ansible/roles/distribute-validators/README.md +++ b/ansible/roles/distribute-validators/README.md @@ -2,6 +2,12 @@ This role copies secrets and validators required for testnets to which Nimbus beacon nodes contribute. +# Warning + +__This role does not take into account the currently existing layout of validators and secrets!__ + +Take into account what is already in place and which nodes are running and in what order you run this role to avoid a case in which validators on two or more nodes overlap. + # Details You can read about validators and secrets here: diff --git a/ansible/roles/distribute-validators/defaults/main.yml b/ansible/roles/distribute-validators/defaults/main.yml index a00d9df..58a39ae 100644 --- a/ansible/roles/distribute-validators/defaults/main.yml +++ b/ansible/roles/distribute-validators/defaults/main.yml @@ -4,6 +4,7 @@ dist_validators_repo_rev: 'master' dist_validators_repo_user: 'admin' dist_validators_repo_path: '/home/{{ dist_validators_repo_user }}/distribute-validators' +dist_validators_cont_name: ~ dist_validators_data_path: ~ dist_validators_name: ~ dist_validators_path: '{{ dist_validators_repo_path }}/{{ dist_validators_name | mandatory }}/validators' diff --git a/ansible/roles/distribute-validators/tasks/check.yml b/ansible/roles/distribute-validators/tasks/check.yml new file mode 100644 index 0000000..36c2e0b --- /dev/null +++ b/ansible/roles/distribute-validators/tasks/check.yml @@ -0,0 +1,31 @@ +--- +- name: Verify number of validators and secrets matches + assert: + that: '{{ (found_validators|length) == (found_secrets|length) }}' + fail_msg: 'Number of total validators and secrets does not match!' + +- name: Extract slice for host + set_fact: + new_validators: '{{ found_validators[dist_validators_range["start"]:dist_validators_range["end"]] }}' + new_secrets: '{{ found_secrets[dist_validators_range["start"]:dist_validators_range["end"]] }}' + +- name: Verify that validators and secrets overlap + assert: + that: '{{ (new_validators|intersect(new_secrets)|length) == (new_validators|length) }}' + fail_msg: 'List of validators and their secrets does not overlap!' + +- debug: var=new_validators[0:10] +- debug: var=old_validators[0:10] + +- name: Check compare existing validators + set_fact: + secrets_diff: '{{ new_secrets|difference(old_secrets) }}' + validators_diff: '{{ new_validators|difference(old_validators) }}' + +- debug: var=secrets_diff[0:10] +- debug: var=validators_diff[0:10] + +- name: Check if validators changed + set_fact: + secrets_changed: '{{ secrets_diff|length > 0 }}' + validators_changed: '{{ validators_diff|length > 0 }}' diff --git a/ansible/roles/distribute-validators/tasks/main.yml b/ansible/roles/distribute-validators/tasks/main.yml index 09ae57e..c2f13f8 100644 --- a/ansible/roles/distribute-validators/tasks/main.yml +++ b/ansible/roles/distribute-validators/tasks/main.yml @@ -1,91 +1,8 @@ ---- -- name: Clone repo with secrets/validators - git: - repo: '{{ dist_validators_repo_url }}' - dest: '{{ dist_validators_repo_path }}' - version: '{{ dist_validators_repo_rev }}' - update: true - force: true - accept_hostkey: true - become_user: '{{ dist_validators_repo_user }}' - -- name: Find all validators - find: - paths: '{{ dist_validators_path }}' - file_type: directory - recurse: true - depth: 1 - register: found_validators_raw - -- name: Find all secrets - find: - paths: '{{ dist_validators_secrets_path }}' - file_type: file - recurse: true - depth: 1 - register: found_secrets_raw - -- name: Extract file paths - set_fact: - found_validators: '{{ found_validators_raw.files | map(attribute="path") | map("basename") | list | sort }}' - found_secrets: '{{ found_secrets_raw.files | map(attribute="path") | map("basename") | list | sort }}' - -- name: Verify number of validators and secrets matches - assert: - that: '{{ (found_validators|length) == (found_secrets|length) }}' - fail_msg: 'Number of total validators and secrets does not match!' - -- name: Extract slice for host - set_fact: - host_validators: '{{ found_validators[dist_validators_range["start"]:dist_validators_range["end"]] }}' - host_secrets: '{{ found_secrets[dist_validators_range["start"]:dist_validators_range["end"]] }}' - -- name: Verify that validators and secrets overlap - assert: - that: '{{ (host_validators|intersect(host_secrets)|length) == (host_validators|length) }}' - fail_msg: 'List of validators and their secrets does not overlap!' - -- name: Create validators/secrets folders - file: - path: '{{ item }}' - state: 'directory' - owner: dockremap - group: docker - mode: 0700 - with_items: - - '{{ dist_validators_data_path }}/validators' - - '{{ dist_validators_data_path }}/secrets' - -- name: Copy over validators - command: | - rsync -ru --delete --exclude="slashing_protection.sqlite3*" \ - {{ host_validators | join(" ") }} '{{ dist_validators_data_path }}/validators/' - args: - chdir: '{{ dist_validators_path }}' - -- name: Copy over secrets - command: | - rsync -ru \ - {{ host_secrets | join(" ") }} '{{ dist_validators_data_path }}/secrets/' - args: - chdir: '{{ dist_validators_secrets_path }}' - -- name: Adjust folder owner and group - command: chown dockremap:docker -R {{ dist_validators_data_path }} - args: - warn: false - -- name: Adjust validators dir permissions - shell: chmod 0700 -R {{ dist_validators_data_path }}/validators/* - args: - warn: false - -- name: Adjust validators file permissions - shell: find '{{ dist_validators_data_path }}/validators/' -type f -exec chmod 0600 {} \; - args: - warn: false - -- name: Adjust secrets permissions - shell: chmod 0600 -R {{ dist_validators_data_path }}/secrets/* - args: - warn: false +--- +- name: Find new and old validators + include_tasks: read.yml +- name: Verify if validators changed + include_tasks: check.yml +- name: Copy over validators and secrets + include_tasks: write.yml + when: secrets_changed or validators_changed diff --git a/ansible/roles/distribute-validators/tasks/read.yml b/ansible/roles/distribute-validators/tasks/read.yml new file mode 100644 index 0000000..4af087d --- /dev/null +++ b/ansible/roles/distribute-validators/tasks/read.yml @@ -0,0 +1,49 @@ +--- +- name: Clone repo with secrets/validators + git: + repo: '{{ dist_validators_repo_url }}' + dest: '{{ dist_validators_repo_path }}' + version: '{{ dist_validators_repo_rev }}' + update: true + force: true + accept_hostkey: true + become_user: '{{ dist_validators_repo_user }}' + +- name: Find all validators + find: + paths: '{{ dist_validators_path }}' + file_type: directory + recurse: true + depth: 1 + register: found_validators_raw + +- name: Find all secrets + find: + paths: '{{ dist_validators_secrets_path }}' + file_type: file + recurse: true + depth: 1 + register: found_secrets_raw + +- name: Find old validators + find: + paths: '{{ dist_validators_data_path }}/validators' + file_type: directory + recurse: true + depth: 1 + register: old_validators_raw + +- name: Find old secrets + find: + paths: '{{ dist_validators_data_path }}/secrets' + file_type: file + recurse: true + depth: 1 + register: old_secrets_raw + +- name: Extract file paths + set_fact: + found_validators: '{{ found_validators_raw.files | map(attribute="path") | map("basename") | list | sort }}' + found_secrets: '{{ found_secrets_raw.files | map(attribute="path") | map("basename") | list | sort }}' + old_validators: '{{ old_validators_raw.files | map(attribute="path") | map("basename") | list | sort }}' + old_secrets: '{{ old_secrets_raw.files | map(attribute="path") | map("basename") | list | sort }}' diff --git a/ansible/roles/distribute-validators/tasks/write.yml b/ansible/roles/distribute-validators/tasks/write.yml new file mode 100644 index 0000000..8881759 --- /dev/null +++ b/ansible/roles/distribute-validators/tasks/write.yml @@ -0,0 +1,61 @@ +--- +- name: Stop container if running + command: docker-compose stop + args: + chdir: '/docker/{{ dist_validators_cont_name }}' + ignore_errors: true + +- name: Remove validators/secrets folders + file: + path: '{{ item }}' + state: 'absent' + with_items: + - '{{ dist_validators_data_path }}/validators' + - '{{ dist_validators_data_path }}/secrets' + +- name: Create validators/secrets folders + file: + path: '{{ item }}' + state: 'directory' + owner: dockremap + group: docker + mode: 0700 + with_items: + - '{{ dist_validators_data_path }}/validators' + - '{{ dist_validators_data_path }}/secrets' + +- name: Copy over validators + command: | + rsync -ru --delete --exclude="slashing_protection.sqlite3*" \ + {{ new_validators | join(" ") }} '{{ dist_validators_data_path }}/validators/' + args: + chdir: '{{ dist_validators_path }}' + +- name: Copy over secrets + command: | + rsync -ru \ + {{ new_secrets | join(" ") }} '{{ dist_validators_data_path }}/secrets/' + args: + chdir: '{{ dist_validators_secrets_path }}' + +- name: Adjust folder owner and group + command: chown dockremap:docker -R {{ dist_validators_data_path }} + args: { warn: false } + +- name: Adjust validators dir permissions + shell: chmod 0700 -R {{ dist_validators_data_path }}/validators/* + args: { warn: false } + +- name: Adjust validators file permissions + shell: find '{{ dist_validators_data_path }}/validators/' -type f -exec chmod 0600 {} \; + args: { warn: false } + +- name: Adjust secrets permissions + shell: chmod 0600 -R {{ dist_validators_data_path }}/secrets/* + args: { warn: false } + +- name: Restart container + command: docker-compose start + args: + chdir: '/docker/{{ dist_validators_cont_name }}' + ignore_errors: true