Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,11 @@ Every Ansible deployment automatically deploys an observability stack alongside
- `tmp/local-run-DD-MM-YYYY-HH-MM.log` for local deployments
- `tmp/ansible-run-DD-MM-YYYY-HH-MM.log` for Ansible deployments
- Example: `NETWORK_DIR=local-devnet ./spin-node.sh --node all --logs`
19. `--network` sets the network name label attached to every metric and log stream scraped by the observability stack (Ansible mode only).
- Default: `devnet-3`, set in `parse-env.sh` after argument parsing
- Propagated to Ansible as the `network_name` variable, which is used in `prometheus.yml.j2` and `promtail.yml.j2` templates
- Appears as the `network` label on all Prometheus scrape targets (app, node_exporter, cadvisor) and all Promtail log streams, so you can filter by network in Grafana across multiple environments
- Example: `--network devnet-x`

### Preparing remote servers

Expand Down
2 changes: 1 addition & 1 deletion ansible/playbooks/clean-node-data.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
connection: local
gather_facts: no
vars:
validator_config_file: "{{ genesis_dir }}/validator-config.yaml"
validator_config_file: "{{ local_validator_config_path | default(genesis_dir + '/validator-config.yaml') }}"
tags:
- zeam
- ream
Expand Down
7 changes: 2 additions & 5 deletions ansible/playbooks/deploy-nodes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
- deploy
- observability
vars:
validator_config_file: "{{ genesis_dir }}/validator-config.yaml"
validator_config_file: "{{ local_validator_config_path | default(genesis_dir + '/validator-config.yaml') }}"

tasks:
- name: Validate validator-config.yaml exists
Expand Down Expand Up @@ -122,10 +122,7 @@

- name: Sync validator-config.yaml to remote host
copy:
# Use the expanded subnet config when --subnets was specified; fall back
# to the standard validator-config.yaml otherwise. The destination is
# always validator-config.yaml so client roles don't need to change.
src: "{{ local_genesis_dir }}/{{ validator_config_basename | default('validator-config.yaml') }}"
src: "{{ local_validator_config_path | default(local_genesis_dir + '/validator-config.yaml') }}"
dest: "{{ genesis_dir }}/validator-config.yaml"
mode: '0644'
force: yes
Expand Down
14 changes: 12 additions & 2 deletions ansible/playbooks/generate-genesis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,19 @@
set_fact:
project_root: "{{ project_root_result.stdout }}"

- name: Copy custom validator config to genesis dir if different
copy:
src: "{{ local_validator_config_path }}"
dest: "{{ genesis_dir }}/validator-config.yaml"
mode: '0644'
when:
- local_validator_config_path is defined
- local_validator_config_path != genesis_dir + '/validator-config.yaml'

- name: Run generate-genesis.sh script
shell: |
cd "{{ project_root }}" && ./generate-genesis.sh "{{ genesis_dir }}" --mode ansible --offset {{ genesis_time_offset }}
cd "{{ project_root }}" && ./generate-genesis.sh "{{ genesis_dir }}" --mode ansible --offset {{ genesis_time_offset }}{% if local_validator_config_path is defined and local_validator_config_path != '' %} --validator-config "{{ local_validator_config_path }}"{% endif %}

register: genesis_result
args:
executable: /bin/bash
Expand All @@ -55,7 +65,7 @@

- name: Extract node names from validator-config.yaml
shell: |
yq eval '.validators[].name' "{{ genesis_dir }}/validator-config.yaml"
yq eval '.validators[].name' "{{ local_validator_config_path | default(genesis_dir + '/validator-config.yaml') }}"
register: node_names_raw
changed_when: false

Expand Down
2 changes: 1 addition & 1 deletion ansible/playbooks/helpers/deploy-single-node.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
- name: Set validator config file paths
set_fact:
actual_validator_config_file: "{{ genesis_dir }}/validator-config.yaml"
local_validator_config_file: "{{ hostvars['localhost']['local_genesis_dir_path'] }}/validator-config.yaml"
local_validator_config_file: "{{ local_validator_config_path }}"

- name: Extract node configuration (from local config)
shell: |
Expand Down
2 changes: 1 addition & 1 deletion ansible/playbooks/prepare.yml
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@

- name: Read all node entries for this host from the active validator config
vars:
_vc_file: "{{ _genesis_dir + '/' + (validator_config_basename | default('validator-config.yaml')) }}"
_vc_file: "{{ local_validator_config_path | default(_genesis_dir + '/validator-config.yaml') }}"
_vc: "{{ lookup('file', _vc_file) | from_yaml }}"
_entries: "{{ _vc.validators | selectattr('enrFields.ip', 'equalto', ansible_host) | list }}"
set_fact:
Expand Down
2 changes: 1 addition & 1 deletion ansible/playbooks/stop-nodes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
connection: local
gather_facts: yes
vars:
validator_config_file: "{{ genesis_dir }}/validator-config.yaml"
validator_config_file: "{{ local_validator_config_path | default(genesis_dir + '/validator-config.yaml') }}"

tasks:
- name: Validate validator-config.yaml exists
Expand Down
2 changes: 1 addition & 1 deletion ansible/roles/ethlambda/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

- name: Extract node configuration from validator-config.yaml
shell: |
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ hostvars['localhost']['local_genesis_dir_path'] }}/validator-config.yaml"
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ local_validator_config_path }}"
register: ethlambda_node_config
changed_when: false
delegate_to: localhost
Expand Down
2 changes: 1 addition & 1 deletion ansible/roles/gean/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

- name: Extract node configuration from validator-config.yaml
shell: |
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ hostvars['localhost']['local_genesis_dir_path'] }}/validator-config.yaml"
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ local_validator_config_path }}"
register: gean_node_config
changed_when: false
delegate_to: localhost
Expand Down
2 changes: 1 addition & 1 deletion ansible/roles/grandine/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

- name: Extract node configuration from validator-config.yaml
shell: |
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ hostvars['localhost']['local_genesis_dir_path'] }}/validator-config.yaml"
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ local_validator_config_path }}"
register: grandine_node_config
changed_when: false
delegate_to: localhost
Expand Down
2 changes: 1 addition & 1 deletion ansible/roles/lantern/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

- name: Extract node configuration from validator-config.yaml
shell: |
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ hostvars['localhost']['local_genesis_dir_path'] }}/validator-config.yaml"
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ local_validator_config_path }}"
register: lantern_node_config
changed_when: false
delegate_to: localhost
Expand Down
2 changes: 1 addition & 1 deletion ansible/roles/lighthouse/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

- name: Extract node configuration from validator-config.yaml
shell: |
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ hostvars['localhost']['local_genesis_dir_path'] }}/validator-config.yaml"
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ local_validator_config_path }}"
register: lighthouse_node_config
changed_when: false
delegate_to: localhost
Expand Down
2 changes: 1 addition & 1 deletion ansible/roles/nlean/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

- name: Extract node configuration from validator-config.yaml
shell: |
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ hostvars['localhost']['local_genesis_dir_path'] }}/validator-config.yaml"
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ local_validator_config_path }}"
register: nlean_node_config
changed_when: false
delegate_to: localhost
Expand Down
22 changes: 17 additions & 5 deletions ansible/roles/observability/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@
# Observability role: Deploy cadvisor, node_exporter, prometheus, and promtail
# alongside each lean node on remote hosts.

- name: Extract metricsPort from validator-config.yaml
- name: Find all nodes on this host
shell: |
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .metricsPort" "{{ local_genesis_dir }}/validator-config.yaml"
register: obs_metrics_port_raw
yq eval '[.validators[] | select(.enrFields.ip == "{{ ansible_host }}") | {"name": .name, "metricsPort": .metricsPort}]' \
"{{ local_validator_config_path }}" -o=json
register: colocated_nodes_raw
changed_when: false
delegate_to: localhost

- name: Set metricsPort fact
- name: Set colocated nodes fact
set_fact:
obs_metrics_port: "{{ obs_metrics_port_raw.stdout | trim }}"
colocated_nodes: "{{ colocated_nodes_raw.stdout | from_json }}"
is_primary_node: "{{ (colocated_nodes_raw.stdout | from_json)[0].name == node_name }}"

- name: Create observability config directory
file:
Expand All @@ -32,10 +34,13 @@
mode: '0644'

# --- cadvisor (always recreate to ensure correct flags) ---
# Only the first colocated node on each machine manages infra containers
# to avoid parallel rm+run races when multiple nodes share a host.

- name: Remove existing cadvisor container
command: docker rm -f cadvisor
failed_when: false
when: is_primary_node

- name: Start cadvisor container
command: >-
Expand All @@ -55,12 +60,14 @@
-v /var/lib/docker/:/var/lib/docker:ro
{{ cadvisor_image }}
--port={{ cadvisor_port }}
when: is_primary_node

# --- node_exporter (always recreate to ensure correct flags) ---

- name: Remove existing node_exporter container
command: docker rm -f node_exporter
failed_when: false
when: is_primary_node

- name: Start node_exporter container
command: >-
Expand All @@ -77,6 +84,7 @@
--path.sysfs=/host/sys
--path.rootfs=/rootfs
--web.listen-address=0.0.0.0:{{ node_exporter_port }}
when: is_primary_node

# --- prometheus (always recreate to pick up config/mount changes, data persists on host) ---

Expand All @@ -90,6 +98,7 @@
- name: Remove existing prometheus container
command: docker rm -f prometheus
failed_when: false
when: is_primary_node

- name: Start prometheus container
command: >-
Expand All @@ -103,12 +112,14 @@
--config.file=/etc/prometheus/prometheus.yml
--storage.tsdb.retention.time=15d
--web.listen-address=0.0.0.0:{{ prometheus_port }}
when: is_primary_node

# --- promtail (always recreate to pick up config/mount changes) ---

- name: Remove existing promtail container
command: docker rm -f promtail
failed_when: false
when: is_primary_node

- name: Start promtail container
command: >-
Expand All @@ -122,3 +133,4 @@
{{ promtail_image }}
-config.file=/etc/promtail/config.yml
-server.http-listen-port={{ promtail_port }}
when: is_primary_node
28 changes: 20 additions & 8 deletions ansible/roles/observability/templates/prometheus.yml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,34 @@ global:
scrape_interval: 15s

scrape_configs:
- job_name: '{{ node_name }}'
{% for node in colocated_nodes %}
- job_name: '{{ node.name }}'
static_configs:
- targets: ['172.17.0.1:{{ obs_metrics_port }}']
- targets: ['172.17.0.1:{{ node.metricsPort }}']
labels:
type: 'app'
node_id: '{{ node_name }}'
instance: '{{ ansible_host }}'
network: '{{ network_name }}'
client_type: '{{ node.name.split("_")[0] }}'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should always ensure that client names have just one "_" in them. Maybe add this to readme and integration.md?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It worked fine for client_0_test_1. Will look into this.

{% endfor %}
- job_name: 'node_exporter'
static_configs:
- targets: ['172.17.0.1:{{ node_exporter_port }}']
labels:
type: 'node'
node_id: '{{ node_name }}'
instance: '{{ ansible_host }}'
network: '{{ network_name }}'
- job_name: 'cadvisor'
static_configs:
- targets: ['172.17.0.1:{{ cadvisor_port }}']
labels:
type: 'docker'
node_id: '{{ node_name }}'
relabel_configs:
- source_labels: [node_id]
target_label: instance
instance: '{{ ansible_host }}'
network: '{{ network_name }}'
metric_relabel_configs:
- source_labels: [name]
regex: '([a-z]+)_.*'
target_label: client_type
replacement: '$1'
remote_write:
- url: {{ remote_write_url }}
15 changes: 10 additions & 5 deletions ansible/roles/observability/templates/promtail.yml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,25 @@ clients:
- url: {{ loki_push_url }}

scrape_configs:
- job_name: {{ node_name }}
- job_name: {{ ansible_host }}
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 5s
filters:
- name: name
values: ["{{ node_name }}"]
values:
{% for node in colocated_nodes %}
- "{{ node.name }}"
{% endfor %}
relabel_configs:
- source_labels: ['__meta_docker_container_name']
regex: '/(.*)'
target_label: 'container'
- source_labels: ['__meta_docker_container_log_stream']
target_label: 'stream'
- target_label: 'node'
replacement: '{{ node_name }}'
- target_label: 'host'
- source_labels: ['container']
target_label: 'node'
- target_label: 'instance'
replacement: '{{ ansible_host }}'
- target_label: 'network'
replacement: '{{ network_name }}'
8 changes: 4 additions & 4 deletions ansible/roles/peam/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

- name: Extract node configuration from validator-config.yaml
shell: |
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ hostvars['localhost']['local_genesis_dir_path'] }}/validator-config.yaml"
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ local_validator_config_path }}"
register: peam_node_config
changed_when: false
delegate_to: localhost
Expand All @@ -50,7 +50,7 @@

- name: Extract local validator index from validator-config ordering
shell: |
yq eval '.validators[].name' "{{ hostvars['localhost']['local_genesis_dir_path'] }}/validator-config.yaml" | nl -v0 | awk '$2=="{{ node_name }}" {print $1; exit}'
yq eval '.validators[].name' "{{ local_validator_config_path }}" | nl -v0 | awk '$2=="{{ node_name }}" {print $1; exit}'
register: peam_validator_index
changed_when: false
delegate_to: localhost
Expand All @@ -68,14 +68,14 @@

- name: Extract total validator count from validator-config.yaml
shell: |
yq eval '.validators[].count // 1' "{{ hostvars['localhost']['local_genesis_dir_path'] }}/validator-config.yaml" | awk '{sum += $1} END {print sum + 0}'
yq eval '.validators[].count // 1' "{{ local_validator_config_path }}" | awk '{sum += $1} END {print sum + 0}'
register: peam_total_validator_count
changed_when: false
delegate_to: localhost

- name: Extract attestation committee count from validator-config.yaml
shell: |
yq eval '.config.attestation_committee_count // 1' "{{ hostvars['localhost']['local_genesis_dir_path'] }}/validator-config.yaml"
yq eval '.config.attestation_committee_count // 1' "{{ local_validator_config_path }}"
register: peam_attestation_committee_count_raw
changed_when: false
delegate_to: localhost
Expand Down
2 changes: 1 addition & 1 deletion ansible/roles/qlean/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

- name: Extract node configuration from validator-config.yaml
shell: |
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ hostvars['localhost']['local_genesis_dir_path'] }}/validator-config.yaml"
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ local_validator_config_path }}"
register: qlean_node_config
changed_when: false
delegate_to: localhost
Expand Down
2 changes: 1 addition & 1 deletion ansible/roles/ream/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

- name: Extract node configuration from validator-config.yaml
shell: |
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ hostvars['localhost']['local_genesis_dir_path'] }}/validator-config.yaml"
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ local_validator_config_path }}"
register: ream_node_config
changed_when: false
delegate_to: localhost
Expand Down
8 changes: 2 additions & 6 deletions ansible/roles/zeam/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

- name: Extract node configuration from validator-config.yaml
shell: |
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ hostvars['localhost']['local_genesis_dir_path'] }}/validator-config.yaml"
yq eval ".validators[] | select(.name == \"{{ node_name }}\") | .{{ item }}" "{{ local_validator_config_path }}"
register: node_config
changed_when: false
delegate_to: localhost
Expand Down Expand Up @@ -76,10 +76,6 @@
state: directory
mode: '0755'

- name: Set validator config value
set_fact:
actual_validator_config: "{{ validator_config if validator_config is defined and validator_config != '' else 'genesis_bootnode' }}"

- name: Deploy Zeam node using Docker
block:
- name: Stop existing Zeam container (if any)
Expand All @@ -106,7 +102,7 @@
{{ zeam_global_flags }}
node
--custom_genesis /config
--validator_config {{ actual_validator_config }}
--validator_config /config
--data-dir /data
--node-id {{ node_name }}
--node-key /config/{{ node_name }}.key
Expand Down
Loading
Loading