- name: Nillion deployment playbook hosts: all become: true vars: ansible_python_interpreter: /usr/bin/python3.11 tasks: - name: Append command to .bash_history blockinfile: path: "~/.bash_history" create: yes block: | #1724983098 cd node/ ; docker compose logs -f #1724983099 docker logs worker -f marker: "" - name: Set locale to C.UTF-8 ansible.builtin.command: cmd: localectl set-locale LANG=C.UTF-8 changed_when: false - name: Create APT configuration file to assume yes ansible.builtin.copy: dest: /etc/apt/apt.conf.d/90forceyes content: | APT::Get::Assume-Yes "true"; mode: '0644' - name: Update /etc/bash.bashrc ansible.builtin.blockinfile: path: /etc/bash.bashrc block: | export HISTTIMEFORMAT='%F, %T ' export HISTSIZE=10000 export HISTFILESIZE=10000 shopt -s histappend export PROMPT_COMMAND='history -a' export HISTCONTROL=ignoredups export LANG=C.UTF-8 export LC_ALL=C.UTF-8 alias ls='ls --color=auto' shopt -s cmdhist - name: Ensure ~/.inputrc exists ansible.builtin.file: path: /root/.inputrc state: touch mode: '0644' - name: Update ~/.inputrc ansible.builtin.blockinfile: path: ~/.inputrc block: | "\e[A": history-search-backward "\e[B": history-search-forward - name: Ensure ~/.nanorc exists ansible.builtin.file: path: /root/.nanorc state: touch mode: '0644' - name: Update ~/.nanorc ansible.builtin.blockinfile: path: ~/.nanorc block: | set nohelp set tabsize 4 set tabstospaces set autoindent set positionlog set backup set backupdir /tmp/ set locking include /usr/share/nano/*.nanorc - name: Set hostname ansible.builtin.shell: | hostnamectl set-hostname {{ serverid }} echo "127.0.1.1 {{ serverid }}" >> /etc/hosts changed_when: false - name: Update and upgrade apt ansible.builtin.apt: update_cache: true upgrade: dist force_apt_get: true autoremove: true register: apt_update_result retries: 5 delay: 50 until: apt_update_result is succeeded async: "{{ 60 * 20 }}" poll: 30 - name: Install packages ansible.builtin.apt: name: - ca-certificates - zlib1g-dev - libncurses5-dev - libgdbm-dev - libnss3-dev - curl - jq - git - zip - wget - make - python3 - python3-pip - iftop state: present update_cache: true async: "{{ 60 * 20 }}" poll: 30 - name: Install Docker ansible.builtin.shell: curl -fsSL https://get.docker.com | bash changed_when: false async: "{{ 60 * 5 }}" poll: 30 - name: Update Docker daemon journald logging ansible.builtin.copy: dest: /etc/docker/daemon.json content: | { "log-driver": "journald" } mode: '0644' - name: Restart Docker ansible.builtin.service: name: docker state: restarted - name: Update journald log SystemMaxUse=2G configuration ansible.builtin.lineinfile: path: /etc/systemd/journald.conf line: 'SystemMaxUse=2G' insertafter: EOF create: true mode: '0644' - name: Restart journald ansible.builtin.service: name: systemd-journald state: restarted - name: Docker login ansible.builtin.shell: docker login -u "{{ docker_username }}" -p "{{ docker_password }}" register: docker_login_result changed_when: false failed_when: "'Login Succeeded' not in docker_login_result.stdout" - name: Clone repository ansible.builtin.git: repo: https://gitea.vvzvlad.xyz/vvzvlad/nillion dest: "{{ ansible_env.HOME }}/node" version: "{{ git_version }}" force: true async: "{{ 60 * 15 }}" poll: 30 - name: Make update.sh executable ansible.builtin.shell: | chmod +x ./update.sh args: chdir: "{{ ansible_env.HOME }}/node" changed_when: false - name: Update environment variables ansible.builtin.shell: | ./update.sh ADDRESS "{{ address }}" ./update.sh PRIVATE "{{ private_key }}" ./update.sh PUBLIC "{{ public_key }}" ./update.sh RPC_URL "{{ rpc_url }}" args: chdir: "{{ ansible_env.HOME }}/node" changed_when: false - name: Download dockers images ansible.builtin.command: docker compose pull args: chdir: "{{ ansible_env.HOME }}/node" environment: COMPOSE_INTERACTIVE_NO_CLI: 'true' changed_when: false async: "{{ 60 * 45 }}" poll: "{{ 60 * 5 }}" - name: Check external IP before ansible.builtin.command: curl https://ifconfig.me register: ip_before changed_when: false - name: Validate IP address ansible.builtin.assert: that: - ip_before.stdout | ansible.utils.ipaddr fail_msg: "The returned value is not a valid IP address." success_msg: "The returned value is a valid IP address." - name: Download tun2socks ansible.builtin.get_url: url: https://github.com/xjasonlyu/tun2socks/releases/download/v2.5.2/tun2socks-linux-amd64.zip dest: /tmp/tun2socks-linux-amd64.zip mode: '0644' async: "{{ 60 * 5 }}" poll: 30 - name: Unzip tun2socks ansible.builtin.unarchive: src: /tmp/tun2socks-linux-amd64.zip dest: /usr/local/sbin/ remote_src: true mode: '0755' - name: Create proxy file ansible.builtin.copy: content: "{{ proxy }}" dest: /root/proxy mode: '0644' - name: Create tun2socks systemd service ansible.builtin.copy: dest: /etc/systemd/system/tun2socks.service content: | [Unit] Description=Tun2Socks gateway After=network.target Wants=network.target [Service] User=root Type=simple RemainAfterExit=true ExecStartPre=/bin/sh -c 'ip route add $(cat /root/proxy | grep -oP "(?<=@)[0-9.]+(?=:)" )/32 via $(ip route | grep -oP "(?<=default via )[0-9.]+")' ExecStart=/bin/sh -c '/usr/local/sbin/tun2socks-linux-amd64 --device tun0 --proxy $(cat /root/proxy)' ExecStopPost=/bin/sh -c 'ip route del $(cat /root/proxy | grep -oP "(?<=@)[0-9.]+(?=:)" )/32 via $(ip route | grep -oP "(?<=default via )[0-9.]+")' Restart=always [Install] WantedBy=multi-user.target mode: '0644' - name: Create network configuration for tun0 ansible.builtin.copy: dest: /etc/systemd/network/10-proxy.network content: | [Match] Name=tun0 [Network] Address=10.20.30.1/24 [Route] Gateway=0.0.0.0 mode: '0644' - name: Enable and start tun2socks service ansible.builtin.systemd: name: tun2socks enabled: true state: started - name: Reload network configuration ansible.builtin.command: networkctl reload changed_when: false - name: Restart tun2socks service ansible.builtin.systemd: name: tun2socks state: restarted - name: Check API availability for RPC URL ansible.builtin.uri: url: "{{ rpc_url }}/health?" method: GET return_content: true timeout: 30 register: rpc_url_response retries: 3 delay: 60 failed_when: - rpc_url_response.status != 200 - rpc_url_response.json is not none and rpc_url_response.json is not defined - name: Check external IP after ansible.builtin.command: curl https://ifconfig.me register: ip_after changed_when: false - name: Validate IP address ansible.builtin.assert: that: - ip_after.stdout | ansible.utils.ipaddr fail_msg: "The returned value is not a valid IP address." success_msg: "The returned value is a valid IP address." - name: Show IPs ansible.builtin.debug: msg: "External IP before: {{ ip_before.stdout }}, External IP after: {{ ip_after.stdout }}" - name: Compare external IPs ansible.builtin.fail: msg: "External IP before and after should not be the same" when: ip_before.stdout == ip_after.stdout - name: Up docker compose stack ansible.builtin.command: docker compose up -d args: chdir: "{{ ansible_env.HOME }}/node" environment: COMPOSE_INTERACTIVE_NO_CLI: 'true' changed_when: false async: "{{ 60 * 80 }}" poll: "{{ 60 * 5 }}" # - name: Check "not have enough balance" # ansible.builtin.command: docker logs {{ item }} 2>&1 # register: docker_logs_check # changed_when: false # failed_when: '"not have enough balance" in docker_logs_check.stdout' # with_items: # - worker # - worker-1 # - worker-2 # # - name: Wait send to chain success # ansible.builtin.shell: | # python3 logs_parser.py 130 # args: # chdir: "{{ ansible_env.HOME }}/basic-coin-prediction-node" # register: docker_logs_check # changed_when: false # failed_when: docker_logs_check.rc != 0 # # - name: Check updater endpoint # ansible.builtin.shell: | # response=$(curl --silent --location --request GET http://localhost:8000/update) && \ # if [ "$response" != "0" ]; then # echo "Updater endpoint check failed: $response != 0" # exit 1 # fi # register: updater_shell_response # retries: 2 # delay: 60 # until: updater_shell_response.rc == 0 # changed_when: false # # - name: Check inference endpoint # ansible.builtin.shell: | # response=$(curl --silent --location --request GET http://localhost:8000/inference/{{ token }}) && \ # status=$(curl -o /dev/null -s -w "%{http_code}\\n" http://localhost:8000/inference/{{ token }}) && \ # if [ "$status" -ne 200 ] || ! echo "$response" | grep -qE '^[0-9]+(\.[0-9]+)?$'; then # echo "Inference endpoint check failed: status $status, response $response" # exit 1 # fi # register: inference_shell_response # retries: 2 # delay: 60 # failed_when: inference_shell_response.rc != 0 # changed_when: false - name: Remove docker login credentials ansible.builtin.file: path: /root/.docker/config.json state: absent