Feature/fleet control #1
@@ -1,47 +1,59 @@
|
|||||||
# fleet
|
# fleet
|
||||||
|
|
||||||
Идемпотентный провижнинг парка приёмников пеленгации (Raspberry Pi + HackRF).
|
Плейбуки ansible, которые приводят любую малинку парка (Raspberry Pi +
|
||||||
Один прогон приводит новую или старую малинку в рабочее состояние: обновление
|
HackRF) в рабочее состояние и обслуживают её дальше: домашний Wi-Fi ради
|
||||||
системы, зависимости сборки, общий deploy-ключ до Gitea, клон и сборка
|
интернета, пакеты, код `hackrf-scanner` со сборкой на месте, выключение.
|
||||||
`hackrf-scanner`.
|
Управление идёт по проводной сети 11.0.0.0/24 (`ansible_host` в инвентаре),
|
||||||
|
Wi-Fi нужен только на время установки пакетов и перед работой выключается,
|
||||||
Гоняется дома, пока узлы в сети с интернетом. После переноса в изолированную
|
потому что адаптер сидит в 2,4 ГГц рядом с приёмником.
|
||||||
сеть (коммутатор, статические IP) на карте уже есть всё; правки кода дальше
|
|
||||||
идут `rsync` + сборка на месте. Статические IP playbook не трогает.
|
|
||||||
|
|
||||||
## Требования
|
## Требования
|
||||||
|
|
||||||
- на управляющей машине: `ansible` (Arch: `pacman -S ansible`), доступ по ssh
|
- управляющая машина: `ansible` с коллекциями `community.general` и
|
||||||
к узлам под `pi` по ключу;
|
`ansible.posix`, `rsync`, `sshpass` (только для `bootstrap.yml`),
|
||||||
- на узлах: Raspberry Pi OS (Debian 13), `pi` с sudo без пароля, интернет.
|
рядом лежит каталог `../hackrf-scanner` (переменная `scanner_src`);
|
||||||
|
- узлы: Raspberry Pi OS Lite (Debian 13, NetworkManager), пользователь `pi`
|
||||||
|
с sudo без пароля, статический адрес 11.0.0.x на eth0; на полном образе
|
||||||
|
с рабочим столом первый `full-upgrade` по Wi-Fi идёт больше часа;
|
||||||
|
- `vars/wifi.yml` (в `.gitignore`) по образцу `vars/wifi.yml.example`.
|
||||||
|
|
||||||
## Первый запуск
|
## Новый узел
|
||||||
|
|
||||||
scripts/gen-key.sh # пара keys/gitea_deploy (в .gitignore)
|
```bash
|
||||||
# добавить keys/gitea_deploy.pub как deploy key (read-only)
|
nmap -sn 11.0.0.0/24 # какие узлы в сети
|
||||||
# в Gitea: IU9/hackrf-scanner
|
ansible-playbook bootstrap.yml -l node107 # ключ по паролю pi/raspberry
|
||||||
ansible-playbook playbook.yml # весь парк
|
ansible-playbook wifi-on.yml # Wi-Fi и проверка интернета
|
||||||
|
ansible-playbook playbook.yml # пакеты, права, имя, паспорт
|
||||||
|
ansible-playbook wifi-off.yml # Wi-Fi выключен до следующего раза
|
||||||
|
ansible-playbook deploy.yml # код с этой машины, сборка на узле
|
||||||
|
```
|
||||||
|
|
||||||
## Теги
|
Новый узел сначала вписывается в `inventory/hosts.yml`. Смена роутера: правка
|
||||||
|
`vars/wifi.yml` и `wifi-on.yml`, профиль на узлах обновится.
|
||||||
|
|
||||||
base apt upgrade, зависимости, pi в plugdev
|
## Плейбуки
|
||||||
hostname имя узла из инвентаря
|
|
||||||
key deploy-ключ, ssh config, known_hosts
|
|
||||||
repo clone/pull ветки scanner_branch (stash локальных правок)
|
|
||||||
build cmake configure + build
|
|
||||||
|
|
||||||
ansible-playbook playbook.yml -l node106 --tags repo,build
|
| Плейбук | Что делает |
|
||||||
|
|---|---|
|
||||||
|
| `bootstrap.yml` | ключ управляющей машины в `authorized_keys`, вход по паролю |
|
||||||
|
| `wifi-on.yml` | радио включено, профиль `fleet-wifi` с кредами из `vars/wifi.yml`, подключение, проверка DNS и HTTPS |
|
||||||
|
| `playbook.yml` | теги `base` (apt, зависимости, plugdev, udev для HackRF, fish), `hostname`, `key` (deploy-ключ Gitea), `env` (`~/node.env`, только засев) |
|
||||||
|
| `wifi-off.yml` | радио выключено, NetworkManager помнит это через перезагрузку |
|
||||||
|
| `deploy.yml` | `rsync` исходников без `.git` и `build`, ревизия в `~/hackrf-scanner/DEPLOYED`, `cmake` сборка, проверка бинарников |
|
||||||
|
| `poweroff.yml` | штатное выключение и ожидание, пока узел пропадёт из сети |
|
||||||
|
|
||||||
|
Ограничение по узлам и тегам как обычно: `-l node106`, `--tags base`.
|
||||||
|
|
||||||
## Инвентарь
|
## Инвентарь
|
||||||
|
|
||||||
`inventory/hosts.yml`: адреса узлов в домашней сети (транзитные), а также
|
`inventory/hosts.yml`: адрес узла в проводной сети, `sdr_id`, серийник HackRF,
|
||||||
справочно -- статический IP для поля, серийник HackRF и координаты x, y (м).
|
координаты x, y в метрах. Координаты и `server_ip` засеваются в `~/node.env`
|
||||||
Ветка репозитория -- переменная `scanner_branch`.
|
один раз, полевые правки на узле плейбук не перетирает.
|
||||||
|
|
||||||
## Приёмка
|
## Приёмка
|
||||||
|
|
||||||
1. Прогон без `failed`.
|
1. Все плейбуки без `failed`, второй прогон подряд `changed=0`.
|
||||||
2. Второй прогон подряд -- `changed=0` на всех узлах.
|
2. После `wifi-on.yml` каждый узел печатает адрес в домашней сети и
|
||||||
3. На узле: `hackrf_info` видит устройство, `~/hackrf-scanner/build/` собран,
|
"интернет есть", после `wifi-off.yml` у `wlan0` нет адреса.
|
||||||
`git rev-parse --abbrev-ref HEAD` = `scanner_branch`, `hostname` = имя узла.
|
3. На узле `~/hackrf-scanner/build/peleng` и `scan` собраны, `DEPLOYED`
|
||||||
4. `ssh -T git@monitor.yss.su` с узла отвечает Gitea.
|
совпадает с `git describe` на управляющей машине, `hostname` = имя узла.
|
||||||
|
|||||||
+6
-46
@@ -1,3 +1,5 @@
|
|||||||
|
# Базовый провижнинг: пакеты, права на HackRF, имя узла, deploy-ключ, паспорт.
|
||||||
|
# Нужен интернет на узлах (wifi-on.yml). Код на узлы кладёт deploy.yml.
|
||||||
- name: Провижнинг приёмников пеленгации
|
- name: Провижнинг приёмников пеленгации
|
||||||
hosts: all
|
hosts: all
|
||||||
tasks:
|
tasks:
|
||||||
@@ -16,10 +18,10 @@
|
|||||||
upgrade: full
|
upgrade: full
|
||||||
tags: [base]
|
tags: [base]
|
||||||
|
|
||||||
- name: Зависимости сборки и утилиты HackRF
|
- name: Зависимости сборки, утилиты HackRF, python для node.py
|
||||||
become: true
|
become: true
|
||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
name: [cmake, g++, pkg-config, git, rsync, libhackrf-dev, libusb-1.0-0-dev, libfftw3-dev, hackrf, fish]
|
name: [cmake, g++, pkg-config, git, rsync, libhackrf-dev, libusb-1.0-0-dev, libfftw3-dev, hackrf, python3, fish]
|
||||||
state: present
|
state: present
|
||||||
tags: [base]
|
tags: [base]
|
||||||
|
|
||||||
@@ -76,7 +78,7 @@
|
|||||||
- name: Ключа нет
|
- name: Ключа нет
|
||||||
run_once: true
|
run_once: true
|
||||||
ansible.builtin.fail:
|
ansible.builtin.fail:
|
||||||
msg: "[!] нет keys/gitea_deploy -- запустите scripts/gen-key.sh"
|
msg: "[!] нет keys/gitea_deploy, запустите scripts/gen-key.sh"
|
||||||
when: not deploy_key.stat.exists
|
when: not deploy_key.stat.exists
|
||||||
tags: [key]
|
tags: [key]
|
||||||
|
|
||||||
@@ -109,7 +111,7 @@
|
|||||||
StrictHostKeyChecking accept-new
|
StrictHostKeyChecking accept-new
|
||||||
tags: [key]
|
tags: [key]
|
||||||
|
|
||||||
- name: ~/node.env для обёртки node.sh (только засев, полевые правки не трогаем)
|
- name: ~/node.env для node.py (только засев, полевые правки не трогаем)
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
dest: ~/node.env
|
dest: ~/node.env
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
@@ -120,45 +122,3 @@
|
|||||||
Y={{ y }}
|
Y={{ y }}
|
||||||
SERVER={{ server_ip }}
|
SERVER={{ server_ip }}
|
||||||
tags: [env]
|
tags: [env]
|
||||||
|
|
||||||
- name: Репозиторий уже клонирован?
|
|
||||||
ansible.builtin.stat:
|
|
||||||
path: ~/hackrf-scanner/.git
|
|
||||||
register: repo_dir
|
|
||||||
tags: [repo]
|
|
||||||
|
|
||||||
- name: Локальные правки в репо (rsync-разработка)?
|
|
||||||
ansible.builtin.command: git status --porcelain
|
|
||||||
args:
|
|
||||||
chdir: ~/hackrf-scanner
|
|
||||||
register: dirty
|
|
||||||
changed_when: false
|
|
||||||
when: repo_dir.stat.exists
|
|
||||||
tags: [repo]
|
|
||||||
|
|
||||||
- name: Stash локальных правок перед обновлением
|
|
||||||
ansible.builtin.command: git stash push -m fleet-provision
|
|
||||||
args:
|
|
||||||
chdir: ~/hackrf-scanner
|
|
||||||
when: repo_dir.stat.exists and dirty.stdout != ""
|
|
||||||
tags: [repo]
|
|
||||||
|
|
||||||
- name: Репозиторий hackrf-scanner
|
|
||||||
ansible.builtin.git:
|
|
||||||
repo: "{{ scanner_repo }}"
|
|
||||||
dest: ~/hackrf-scanner
|
|
||||||
version: "{{ scanner_branch }}"
|
|
||||||
update: true
|
|
||||||
force: true
|
|
||||||
register: repo
|
|
||||||
tags: [repo]
|
|
||||||
|
|
||||||
- name: Сборка
|
|
||||||
ansible.builtin.shell: |
|
|
||||||
cmake -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo >/dev/null
|
|
||||||
cmake --build build -j4
|
|
||||||
args:
|
|
||||||
chdir: ~/hackrf-scanner
|
|
||||||
register: build
|
|
||||||
changed_when: "'Building CXX' in build.stdout or 'Linking' in build.stdout"
|
|
||||||
tags: [build]
|
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# run.sh [аргументы ansible-playbook] примеры:
|
|
||||||
# ./run.sh весь парк, все теги
|
|
||||||
# ./run.sh --tags base -l node106
|
|
||||||
# ./run.sh --check --diff сухой прогон
|
|
||||||
set -e
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
[ -f keys/gitea_deploy ] || { echo "[!] нет keys/gitea_deploy -- запустите scripts/gen-key.sh"; exit 1; }
|
|
||||||
exec ansible-playbook playbook.yml "$@"
|
|
||||||
Reference in New Issue
Block a user