Compare commits
2 Commits
main
...
feat/etap-
| Author | SHA1 | Date | |
|---|---|---|---|
| 887c39a676 | |||
| 5df142d47a |
31
ansible/group_vars/sol_rpc.yml
Normal file
31
ansible/group_vars/sol_rpc.yml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
solana_user: solana
|
||||||
|
solana_group: solana
|
||||||
|
solana_home: /var/lib/solana
|
||||||
|
|
||||||
|
solana_validator_bin: /opt/solana/bin/agave-validator
|
||||||
|
solana_rpc_service_name: solana-rpc
|
||||||
|
|
||||||
|
solana_identity_path: /var/lib/solana/identity.json
|
||||||
|
solana_ledger_dir: /var/lib/solana/ledger
|
||||||
|
solana_accounts_dir: /var/lib/solana/accounts
|
||||||
|
solana_log_dir: /var/log/solana
|
||||||
|
|
||||||
|
solana_rpc_bind_address: 10.10.0.2
|
||||||
|
solana_rpc_port: 8899
|
||||||
|
solana_rpc_pubsub_port: 8900
|
||||||
|
solana_dynamic_port_range: "8000-8020"
|
||||||
|
|
||||||
|
solana_entrypoints:
|
||||||
|
- entrypoint.mainnet-beta.solana.com:8001
|
||||||
|
solana_known_validators: []
|
||||||
|
|
||||||
|
solana_geyser_enabled: false
|
||||||
|
solana_geyser_plugin_config_path: /etc/solana/yellowstone-geyser.json
|
||||||
|
|
||||||
|
solana_rpc_extra_args:
|
||||||
|
- --full-rpc-api
|
||||||
|
- --limit-ledger-size
|
||||||
|
|
||||||
|
solana_rpc_manage_service: true
|
||||||
|
solana_rpc_enable_on_boot: true
|
||||||
|
solana_rpc_start_now: true
|
||||||
@@ -3,6 +3,8 @@
|
|||||||
hosts: sol_rpc
|
hosts: sol_rpc
|
||||||
gather_facts: true
|
gather_facts: true
|
||||||
become: true
|
become: true
|
||||||
|
vars_files:
|
||||||
|
- ../group_vars/sol_rpc.yml
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: Install operator packages (Debian/Ubuntu)
|
- name: Install operator packages (Debian/Ubuntu)
|
||||||
@@ -16,6 +18,32 @@
|
|||||||
update_cache: true
|
update_cache: true
|
||||||
when: ansible_facts.os_family == "Debian"
|
when: ansible_facts.os_family == "Debian"
|
||||||
|
|
||||||
|
- name: Install Solana host base packages (Debian/Ubuntu)
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- chrony
|
||||||
|
- curl
|
||||||
|
- jq
|
||||||
|
- smartmontools
|
||||||
|
- nvme-cli
|
||||||
|
- prometheus-node-exporter
|
||||||
|
state: present
|
||||||
|
update_cache: true
|
||||||
|
when: ansible_facts.os_family == "Debian"
|
||||||
|
|
||||||
|
- name: Ensure solana group exists
|
||||||
|
ansible.builtin.group:
|
||||||
|
name: "{{ solana_group }}"
|
||||||
|
system: true
|
||||||
|
|
||||||
|
- name: Ensure solana user exists
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ solana_user }}"
|
||||||
|
group: "{{ solana_group }}"
|
||||||
|
home: "{{ solana_home }}"
|
||||||
|
system: true
|
||||||
|
create_home: true
|
||||||
|
|
||||||
- name: Ensure root config directories exist
|
- name: Ensure root config directories exist
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: "{{ item }}"
|
path: "{{ item }}"
|
||||||
@@ -29,6 +57,20 @@
|
|||||||
- /root/.config/nvim
|
- /root/.config/nvim
|
||||||
- /root/.config/nvim/lua
|
- /root/.config/nvim/lua
|
||||||
|
|
||||||
|
- name: Ensure Solana directories exist
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item.path }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ item.owner }}"
|
||||||
|
group: "{{ item.group }}"
|
||||||
|
mode: "{{ item.mode }}"
|
||||||
|
loop:
|
||||||
|
- { path: "/etc/solana", owner: "root", group: "root", mode: "0755" }
|
||||||
|
- { path: "{{ solana_home }}", owner: "{{ solana_user }}", group: "{{ solana_group }}", mode: "0750" }
|
||||||
|
- { path: "{{ solana_ledger_dir }}", owner: "{{ solana_user }}", group: "{{ solana_group }}", mode: "0750" }
|
||||||
|
- { path: "{{ solana_accounts_dir }}", owner: "{{ solana_user }}", group: "{{ solana_group }}", mode: "0750" }
|
||||||
|
- { path: "{{ solana_log_dir }}", owner: "{{ solana_user }}", group: "{{ solana_group }}", mode: "0750" }
|
||||||
|
|
||||||
- name: Deploy tmux config (Ctrl+a prefix)
|
- name: Deploy tmux config (Ctrl+a prefix)
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
src: ../files/operator-dotfiles/tmux.conf
|
src: ../files/operator-dotfiles/tmux.conf
|
||||||
@@ -64,6 +106,50 @@
|
|||||||
- { src: "lua/utils.lua", dest: "lua/utils.lua" }
|
- { src: "lua/utils.lua", dest: "lua/utils.lua" }
|
||||||
- { src: "lua/hazard3_dap.lua", dest: "lua/hazard3_dap.lua" }
|
- { src: "lua/hazard3_dap.lua", dest: "lua/hazard3_dap.lua" }
|
||||||
|
|
||||||
|
- name: Deploy solana-rpc systemd unit (runs as solana user)
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: ../templates/solana-rpc.service.j2
|
||||||
|
dest: /etc/systemd/system/{{ solana_rpc_service_name }}.service
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0644"
|
||||||
|
register: solana_rpc_unit
|
||||||
|
|
||||||
|
- name: Reload systemd after unit change
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
daemon_reload: true
|
||||||
|
when: solana_rpc_unit.changed
|
||||||
|
|
||||||
|
- name: Check validator binary exists
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "{{ solana_validator_bin }}"
|
||||||
|
register: solana_validator_bin_stat
|
||||||
|
|
||||||
|
- name: Check identity key exists
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "{{ solana_identity_path }}"
|
||||||
|
register: solana_identity_stat
|
||||||
|
|
||||||
|
- name: Ensure solana-rpc service state when prerequisites exist
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "{{ solana_rpc_service_name }}"
|
||||||
|
enabled: "{{ solana_rpc_enable_on_boot | bool }}"
|
||||||
|
state: "{{ 'started' if (solana_rpc_start_now | bool) else 'stopped' }}"
|
||||||
|
when:
|
||||||
|
- solana_rpc_manage_service | bool
|
||||||
|
- solana_validator_bin_stat.stat.exists
|
||||||
|
- solana_identity_stat.stat.exists
|
||||||
|
|
||||||
|
- name: Report skipped solana-rpc start due to missing prerequisites
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg:
|
||||||
|
- "solana-rpc start skipped: missing prerequisites"
|
||||||
|
- "validator_bin={{ solana_validator_bin }} exists={{ solana_validator_bin_stat.stat.exists }}"
|
||||||
|
- "identity={{ solana_identity_path }} exists={{ solana_identity_stat.stat.exists }}"
|
||||||
|
when:
|
||||||
|
- solana_rpc_manage_service | bool
|
||||||
|
- not (solana_validator_bin_stat.stat.exists and solana_identity_stat.stat.exists)
|
||||||
|
|
||||||
- name: Validate Ansible transport
|
- name: Validate Ansible transport
|
||||||
ansible.builtin.ping:
|
ansible.builtin.ping:
|
||||||
|
|
||||||
|
|||||||
35
ansible/templates/solana-rpc.service.j2
Normal file
35
ansible/templates/solana-rpc.service.j2
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Solana RPC node (Agave)
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User={{ solana_user }}
|
||||||
|
Group={{ solana_group }}
|
||||||
|
WorkingDirectory={{ solana_home }}
|
||||||
|
Environment=RUST_LOG=info
|
||||||
|
LimitNOFILE=1048576
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
TimeoutStopSec=120
|
||||||
|
ExecStart={{ solana_validator_bin }} \
|
||||||
|
--identity {{ solana_identity_path }} \
|
||||||
|
--ledger {{ solana_ledger_dir }} \
|
||||||
|
--accounts {{ solana_accounts_dir }} \
|
||||||
|
--rpc-bind-address {{ solana_rpc_bind_address }} \
|
||||||
|
--rpc-port {{ solana_rpc_port }} \
|
||||||
|
--rpc-pubsub-port {{ solana_rpc_pubsub_port }} \
|
||||||
|
--dynamic-port-range {{ solana_dynamic_port_range }}{% for ep in solana_entrypoints %} \
|
||||||
|
--entrypoint {{ ep }}{% endfor %}{% for kv in solana_known_validators %} \
|
||||||
|
--known-validator {{ kv }}{% endfor %}{% if solana_geyser_enabled | bool %} \
|
||||||
|
--geyser-plugin-config {{ solana_geyser_plugin_config_path }}{% endif %}{% for arg in solana_rpc_extra_args %} \
|
||||||
|
{{ arg }}{% endfor %} \
|
||||||
|
--log {{ solana_log_dir }}/validator.log
|
||||||
|
NoNewPrivileges=true
|
||||||
|
PrivateTmp=true
|
||||||
|
ProtectSystem=full
|
||||||
|
ReadWritePaths={{ solana_ledger_dir }} {{ solana_accounts_dir }} {{ solana_log_dir }} /var/lib/solana
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
22
doc/etap-005-solana-rpc-user-svc.md
Normal file
22
doc/etap-005-solana-rpc-user-svc.md
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Etap 005: Solana RPC jako usługa użytkownika `solana`
|
||||||
|
|
||||||
|
Cel etapu: przygotować i wdrożyć baseline pod `solana-rpc`, uruchamiany jako dedykowany użytkownik systemowy `solana` (nie `root`).
|
||||||
|
|
||||||
|
## Zakres
|
||||||
|
|
||||||
|
1. Rozszerzyć playbook o:
|
||||||
|
- pakiety bazowe dla hosta RPC,
|
||||||
|
- utworzenie użytkownika i katalogów `solana`,
|
||||||
|
- deployment unitu `systemd` `solana-rpc.service` z `User=solana`.
|
||||||
|
2. Dodać zmienne grupowe `sol_rpc` (ścieżki, porty, opcje startu).
|
||||||
|
3. Dodać bezpieczną logikę startu:
|
||||||
|
- unit jest wdrażany zawsze,
|
||||||
|
- start usługi tylko gdy istnieją wymagane artefakty (`agave-validator`, identity keypair).
|
||||||
|
4. Wdrożyć na `mevnode` i zweryfikować stan.
|
||||||
|
|
||||||
|
## Kryteria akceptacji
|
||||||
|
|
||||||
|
- `id solana` istnieje na `mevnode`.
|
||||||
|
- `/etc/systemd/system/solana-rpc.service` istnieje i zawiera `User=solana`.
|
||||||
|
- Playbook kończy się bez błędów.
|
||||||
|
- Jeśli binarka/identity nie istnieją, playbook raportuje to jawnie i nie wymusza startu.
|
||||||
Reference in New Issue
Block a user