Merge pull request 'Feature/fleet control' (#1) from feature/fleet-control into master
Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
keys/
|
||||
vars/wifi.yml
|
||||
*.retry
|
||||
|
||||
@@ -1,47 +1,93 @@
|
||||
# fleet
|
||||
|
||||
Идемпотентный провижнинг парка приёмников пеленгации (Raspberry Pi + HackRF).
|
||||
Один прогон приводит новую или старую малинку в рабочее состояние: обновление
|
||||
системы, зависимости сборки, общий deploy-ключ до Gitea, клон и сборка
|
||||
`hackrf-scanner`.
|
||||
|
||||
Гоняется дома, пока узлы в сети с интернетом. После переноса в изолированную
|
||||
сеть (коммутатор, статические IP) на карте уже есть всё; правки кода дальше
|
||||
идут `rsync` + сборка на месте. Статические IP playbook не трогает.
|
||||
Плейбуки ansible, которые приводят любую малинку парка (Raspberry Pi +
|
||||
HackRF) в рабочее состояние и управляют ею дальше: домашний Wi-Fi ради
|
||||
интернета, пакеты, код `hackrf-scanner` со сборкой на месте, паспорт узла,
|
||||
запуск и остановка сканера, перезагрузка и выключение.
|
||||
Управление идёт по проводной сети 11.0.0.0/24 (`ansible_host` в инвентаре),
|
||||
Wi-Fi нужен только на время установки пакетов и перед работой выключается,
|
||||
потому что адаптер сидит в 2,4 ГГц рядом с приёмником.
|
||||
|
||||
## Требования
|
||||
|
||||
- на управляющей машине: `ansible` (Arch: `pacman -S ansible`), доступ по ssh
|
||||
к узлам под `pi` по ключу;
|
||||
- на узлах: Raspberry Pi OS (Debian 13), `pi` с sudo без пароля, интернет.
|
||||
- управляющая машина: `ansible` с коллекциями `community.general` и
|
||||
`ansible.posix`, `rsync`, `sshpass` (только для `bootstrap.yml`),
|
||||
рядом лежит каталог `../hackrf-scanner` (переменная `scanner_src`);
|
||||
Alt Linux p11 и Sisyphus: `apt-get install ansible
|
||||
python3-module-ansible-collections-ansible-posix sshpass rsync openssh-clients`;
|
||||
на p10 пакет `ansible` 2.9 не подходит, нужны `ansible-core
|
||||
python3-module-packaging glibc-locales` и `ansible-galaxy collection install
|
||||
community.general ansible.posix`;
|
||||
- узлы: 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)
|
||||
# добавить keys/gitea_deploy.pub как deploy key (read-only)
|
||||
# в Gitea: IU9/hackrf-scanner
|
||||
ansible-playbook playbook.yml # весь парк
|
||||
```bash
|
||||
nmap -sn 11.0.0.0/24 # какие узлы в сети
|
||||
ansible-playbook bootstrap.yml -l node107 # ключ по паролю pi/raspberry
|
||||
ansible-playbook wifi-on.yml # Wi-Fi и проверка интернета
|
||||
ansible-playbook playbook.yml # пакеты, права, имя
|
||||
ansible-playbook wifi-off.yml # Wi-Fi выключен до следующего раза
|
||||
ansible-playbook deploy.yml # код с этой машины, сборка на узле
|
||||
ansible-playbook env.yml # паспорт ~/node.env из инвентаря
|
||||
```
|
||||
|
||||
## Теги
|
||||
## Работа
|
||||
|
||||
base apt upgrade, зависимости, pi в plugdev
|
||||
hostname имя узла из инвентаря
|
||||
key deploy-ключ, ssh config, known_hosts
|
||||
repo clone/pull ветки scanner_branch (stash локальных правок)
|
||||
build cmake configure + build
|
||||
```bash
|
||||
# 1. расстановка: x, y узлов и server_ip в inventory/hosts.yml
|
||||
ansible-playbook env.yml --diff # 2. паспорта на узлы
|
||||
# 3. частота и усиления: inventory/group_vars/all/scanner.yml
|
||||
ansible-playbook scanner-start.yml # 4. peleng на всех узлах
|
||||
ansible-playbook scanner-start.yml -e scanner_args="--freq 2437" # разово поверх
|
||||
ansible-playbook scanner-stop.yml # HackRF свободен (scan, калибровка)
|
||||
```
|
||||
|
||||
ansible-playbook playbook.yml -l node106 --tags repo,build
|
||||
`scanner-start.yml` на каждом узле зовёт `node.py start <профиль> <флаги>`:
|
||||
останавливает прежний peleng и любой процесс, держащий HackRF, переинициализирует
|
||||
USB и запускает peleng в фоне с логом `/tmp/peleng.log`. Профиль и флаги лежат в
|
||||
`inventory/group_vars/all/scanner.yml` (`scanner_profile`, `scanner_args`); узлу
|
||||
можно задать своё значение в `inventory/hosts.yml`, разовый запуск поверх всего
|
||||
через `-e`. peleng читает паспорт
|
||||
только при старте, поэтому после `env.yml` нужен повторный `scanner-start.yml`.
|
||||
|
||||
Новый узел сначала вписывается в `inventory/hosts.yml`. Смена роутера: правка
|
||||
`vars/wifi.yml` и `wifi-on.yml`, профиль на узлах обновится.
|
||||
|
||||
## Плейбуки
|
||||
|
||||
| Плейбук | Что делает |
|
||||
|---|---|
|
||||
| `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) |
|
||||
| `wifi-off.yml` | радио выключено, NetworkManager помнит это через перезагрузку |
|
||||
| `deploy.yml` | `rsync` исходников без `.git` и `build`, ревизия в `~/hackrf-scanner/DEPLOYED`, `cmake` сборка, проверка бинарников |
|
||||
| `env.yml` | `~/node.env` (`SDR_ID`, `X`, `Y`, `SERVER`) из инвентаря, перезаписывается целиком |
|
||||
| `scanner-start.yml` | `node.py start`: освободить HackRF, переинициализировать USB, peleng в фоне, `status` |
|
||||
| `scanner-stop.yml` | `node.py stop`: peleng и любой процесс с HackRF остановлены, проверка `status` |
|
||||
| `reboot.yml` | перезагрузка с ожиданием возврата, печатает ядро |
|
||||
| `poweroff.yml` | штатное выключение и ожидание, пока узел пропадёт из сети |
|
||||
|
||||
Ограничение по узлам и тегам как обычно: `-l node106`, `--tags base`.
|
||||
|
||||
## Инвентарь
|
||||
|
||||
`inventory/hosts.yml`: адреса узлов в домашней сети (транзитные), а также
|
||||
справочно -- статический IP для поля, серийник HackRF и координаты x, y (м).
|
||||
Ветка репозитория -- переменная `scanner_branch`.
|
||||
`inventory/hosts.yml`: адрес узла в проводной сети, `sdr_id`, серийник HackRF,
|
||||
координаты x, y в метрах. Общие переменные: `server_ip` (куда узлы шлют замеры),
|
||||
`scanner_dir` (каталог сканера на узле). Параметры запуска сканера - в
|
||||
`inventory/group_vars/all/scanner.yml`. Инвентарь главный: `env.yml` перезаписывает паспорт узла,
|
||||
правки руками на узле до следующего прогона.
|
||||
|
||||
## Приёмка
|
||||
|
||||
1. Прогон без `failed`.
|
||||
2. Второй прогон подряд -- `changed=0` на всех узлах.
|
||||
3. На узле: `hackrf_info` видит устройство, `~/hackrf-scanner/build/` собран,
|
||||
`git rev-parse --abbrev-ref HEAD` = `scanner_branch`, `hostname` = имя узла.
|
||||
4. `ssh -T git@monitor.yss.su` с узла отвечает Gitea.
|
||||
1. Все плейбуки без `failed`, второй прогон подряд `changed=0`.
|
||||
2. После `wifi-on.yml` каждый узел печатает адрес в домашней сети и
|
||||
"интернет есть", после `wifi-off.yml` у `wlan0` нет адреса.
|
||||
3. На узле `~/hackrf-scanner/build/peleng` и `scan` собраны, `DEPLOYED`
|
||||
совпадает с `git describe` на управляющей машине, `hostname` = имя узла.
|
||||
4. После `scanner-start.yml` каждый узел печатает "peleng запущен" и строку
|
||||
замера, после `scanner-stop.yml` статус "не запущен".
|
||||
|
||||
@@ -3,6 +3,8 @@ inventory = inventory/hosts.yml
|
||||
remote_user = pi
|
||||
host_key_checking = False
|
||||
interpreter_python = auto_silent
|
||||
# Все узлы парка одновременно: старт сканера ждёт USB и первый замер ~15 с на узел
|
||||
forks = 16
|
||||
|
||||
[ssh_connection]
|
||||
pipelining = True
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# Голый узел: вход по паролю pi/raspberry, кладём ключ управляющей машины.
|
||||
# После этого остальные плейбуки ходят по ключу.
|
||||
# ansible-playbook bootstrap.yml -l node107
|
||||
- name: Ключ управляющей машины на узел
|
||||
hosts: all
|
||||
gather_facts: false
|
||||
vars:
|
||||
ansible_password: raspberry
|
||||
tasks:
|
||||
- name: Публичный ключ в authorized_keys пользователя pi
|
||||
ansible.posix.authorized_key:
|
||||
user: pi
|
||||
key: "{{ lookup('file', control_pubkey) }}"
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
# Исходники hackrf-scanner с управляющей машины (scanner_src) на узлы и сборка
|
||||
# на месте. Интернет не нужен, зависимости ставит playbook.yml (тег base).
|
||||
# Что уехало, видно в ~/hackrf-scanner/DEPLOYED (git describe).
|
||||
- name: Код hackrf-scanner на узлы и сборка
|
||||
hosts: all
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Ревизия исходников на управляющей машине
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
ansible.builtin.command: git -C {{ scanner_src }} describe --always --dirty
|
||||
register: rev
|
||||
changed_when: false
|
||||
|
||||
- name: Исходники на узле (без .git и build), лишние файлы удаляются
|
||||
ansible.posix.synchronize:
|
||||
src: "{{ scanner_src }}/"
|
||||
dest: "{{ scanner_dir }}/"
|
||||
delete: true
|
||||
rsync_opts:
|
||||
- "--exclude=.git"
|
||||
- "--exclude=build*"
|
||||
- "--exclude=.cache"
|
||||
- "--exclude=__pycache__"
|
||||
- "--exclude=DEPLOYED"
|
||||
|
||||
- name: След клона прежнего провижнинга не нужен
|
||||
ansible.builtin.file:
|
||||
path: "{{ scanner_dir }}/.git"
|
||||
state: absent
|
||||
|
||||
- name: Метка ревизии
|
||||
ansible.builtin.copy:
|
||||
content: "{{ rev.stdout }}\n"
|
||||
dest: "{{ scanner_dir }}/DEPLOYED"
|
||||
mode: "0644"
|
||||
|
||||
- name: Сборка
|
||||
ansible.builtin.shell: |
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo >/dev/null
|
||||
cmake --build build -j"$(nproc)"
|
||||
args:
|
||||
chdir: "{{ scanner_dir }}"
|
||||
register: build
|
||||
changed_when: "'Building CXX' in build.stdout or 'Linking' in build.stdout"
|
||||
|
||||
- name: Бинарники на месте
|
||||
ansible.builtin.stat:
|
||||
path: "{{ scanner_dir }}/build/{{ item }}"
|
||||
register: bins
|
||||
failed_when: not bins.stat.exists
|
||||
loop: [peleng, scan]
|
||||
|
||||
- name: Итог по узлу
|
||||
ansible.builtin.debug:
|
||||
msg: "[+] {{ inventory_hostname }}: {{ rev.stdout }} собран"
|
||||
@@ -0,0 +1,22 @@
|
||||
# Паспорт узла ~/node.env из инвентаря: SDR_ID, X, Y, SERVER. Инвентарь главный,
|
||||
# файл на узле перезаписывается целиком. peleng читает паспорт только при
|
||||
# старте, поэтому после смены расстановки нужен scanner-start.yml.
|
||||
# ansible-playbook env.yml --diff
|
||||
- name: Паспорт узла из инвентаря
|
||||
hosts: all
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: ~/node.env
|
||||
ansible.builtin.copy:
|
||||
dest: ~/node.env
|
||||
mode: "0644"
|
||||
content: |
|
||||
SDR_ID={{ sdr_id }}
|
||||
X={{ x }}
|
||||
Y={{ y }}
|
||||
SERVER={{ server_ip }}
|
||||
register: env
|
||||
|
||||
- name: Итог по узлу
|
||||
ansible.builtin.debug:
|
||||
msg: "[{{ '+' if env.changed else 'i' }}] {{ inventory_hostname }}: SDR_ID={{ sdr_id }} X={{ x }} Y={{ y }} SERVER={{ server_ip }}{{ ' (обновлён)' if env.changed else '' }}"
|
||||
@@ -0,0 +1,3 @@
|
||||
apt-get install ansible-core python3-module-packaging glibc-locales sshpass rsync openssh-clients
|
||||
export LANG=en_US.UTF-8
|
||||
ansible-galaxy collection install community.general ansible.posix
|
||||
@@ -0,0 +1,12 @@
|
||||
# Как запускать сканер: scanner-start.yml берёт эти значения на всех узлах.
|
||||
# Правка тут, затем ansible-playbook scanner-start.yml.
|
||||
#
|
||||
# Узлу можно задать своё значение в inventory/hosts.yml (например, другой
|
||||
# --lna у PortaPack node104), оно перекроет этот файл. Разовый запуск поверх
|
||||
# всего: ansible-playbook scanner-start.yml -e scanner_args="--freq 2437".
|
||||
#
|
||||
# Профили node.py: dji24, vtx58, lte, pp24, pn24. Флаги peleng переопределяют
|
||||
# профиль; калибровка сервера должна быть снята с теми же --lna и --vga.
|
||||
|
||||
scanner_profile: dji24
|
||||
scanner_args: "--freq 2422 --lna 8"
|
||||
+34
-18
@@ -1,37 +1,53 @@
|
||||
# Координаты x, y в метрах, замер 27.09.2026 (комната).
|
||||
all:
|
||||
vars:
|
||||
scanner_repo: ssh://git@monitor.yss.su:2222/IU9/hackrf-scanner.git
|
||||
scanner_branch: feature/scanner-v2
|
||||
scanner_src: "{{ playbook_dir }}/../hackrf-scanner"
|
||||
control_pubkey: ~/.ssh/id_ed25519.pub
|
||||
gitea_host: monitor.yss.su
|
||||
gitea_port: 2222
|
||||
server_ip: 11.0.0.100
|
||||
scanner_dir: /home/pi/hackrf-scanner
|
||||
hosts:
|
||||
node102:
|
||||
ansible_host: 192.168.1.45
|
||||
ansible_host: 11.0.0.102
|
||||
sdr_id: 1
|
||||
static_ip: 11.0.0.102
|
||||
sdr_serial: a32868dc35944247
|
||||
x: -0.68
|
||||
y: -1.28
|
||||
x: 0.34
|
||||
y: 0.47
|
||||
node103:
|
||||
ansible_host: 11.0.0.103
|
||||
sdr_id: 6
|
||||
sdr_serial: d63861dc2d9b4353
|
||||
x: 0.77
|
||||
y: 0.60
|
||||
node104:
|
||||
ansible_host: 192.168.1.50
|
||||
ansible_host: 11.0.0.104
|
||||
sdr_id: 2
|
||||
static_ip: 11.0.0.104
|
||||
sdr_serial: 42a068dc377ab507
|
||||
note: PortaPack
|
||||
x: 2.28
|
||||
y: 0.45
|
||||
node105:
|
||||
ansible_host: 192.168.1.87
|
||||
ansible_host: 11.0.0.105
|
||||
sdr_id: 3
|
||||
static_ip: 11.0.0.105
|
||||
sdr_serial: a32868dc33894f47
|
||||
x: 3.77
|
||||
y: -0.74
|
||||
node106:
|
||||
ansible_host: 192.168.1.42
|
||||
sdr_id: 4
|
||||
static_ip: 11.0.0.106
|
||||
sdr_serial: a32868dc346d2847
|
||||
x: 0.00
|
||||
y: 0.50
|
||||
y: -1.02
|
||||
node106:
|
||||
ansible_host: 11.0.0.106
|
||||
sdr_id: 4
|
||||
sdr_serial: a32868dc346d2847
|
||||
x: 3.77
|
||||
y: -0.78
|
||||
node107:
|
||||
ansible_host: 11.0.0.107
|
||||
sdr_id: 5
|
||||
sdr_serial: b25062dc2242970b
|
||||
x: 3.77
|
||||
y: 0.00
|
||||
node108:
|
||||
ansible_host: 11.0.0.108
|
||||
sdr_id: 7
|
||||
sdr_serial: a32868dc33324c47
|
||||
x: -0.74
|
||||
y: 0.47
|
||||
|
||||
+5
-57
@@ -1,3 +1,5 @@
|
||||
# Базовый провижнинг: пакеты, права на HackRF, имя узла, deploy-ключ.
|
||||
# Нужен интернет на узлах (wifi-on.yml). Код на узлы кладёт deploy.yml.
|
||||
- name: Провижнинг приёмников пеленгации
|
||||
hosts: all
|
||||
tasks:
|
||||
@@ -16,10 +18,10 @@
|
||||
upgrade: full
|
||||
tags: [base]
|
||||
|
||||
- name: Зависимости сборки и утилиты HackRF
|
||||
- name: Зависимости сборки, утилиты HackRF, python для node.py
|
||||
become: true
|
||||
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
|
||||
tags: [base]
|
||||
|
||||
@@ -76,7 +78,7 @@
|
||||
- name: Ключа нет
|
||||
run_once: true
|
||||
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
|
||||
tags: [key]
|
||||
|
||||
@@ -108,57 +110,3 @@
|
||||
IdentitiesOnly yes
|
||||
StrictHostKeyChecking accept-new
|
||||
tags: [key]
|
||||
|
||||
- name: ~/node.env для обёртки node.sh (только засев, полевые правки не трогаем)
|
||||
ansible.builtin.copy:
|
||||
dest: ~/node.env
|
||||
mode: "0644"
|
||||
force: false
|
||||
content: |
|
||||
SDR_ID={{ sdr_id }}
|
||||
X={{ x }}
|
||||
Y={{ y }}
|
||||
SERVER={{ server_ip }}
|
||||
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]
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# Штатное выключение всех узлов перед снятием питания.
|
||||
# Плейбук ждёт, пока ssh каждого узла перестанет отвечать.
|
||||
- name: Выключение узлов
|
||||
hosts: all
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: poweroff
|
||||
become: true
|
||||
community.general.shutdown:
|
||||
delay: 0
|
||||
|
||||
- name: Узел ушёл из сети
|
||||
delegate_to: localhost
|
||||
ansible.builtin.wait_for:
|
||||
host: "{{ ansible_host }}"
|
||||
port: 22
|
||||
state: stopped
|
||||
timeout: 90
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
# Перезагрузка узлов с ожиданием возврата по ssh (например, после обновления
|
||||
# ядра). В конце каждый узел печатает ядро, на котором поднялся.
|
||||
- name: Перезагрузка узлов
|
||||
hosts: all
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: reboot и ожидание возврата
|
||||
become: true
|
||||
ansible.builtin.reboot:
|
||||
reboot_timeout: 300
|
||||
|
||||
- name: Ядро после перезагрузки
|
||||
ansible.builtin.command: uname -r
|
||||
register: kernel
|
||||
changed_when: false
|
||||
|
||||
- name: Итог по узлу
|
||||
ansible.builtin.debug:
|
||||
msg: "[+] {{ inventory_hostname }}: поднялся, ядро {{ kernel.stdout }}"
|
||||
@@ -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 "$@"
|
||||
@@ -0,0 +1,23 @@
|
||||
# Запуск peleng на всех узлах одной командой node.py start: остановить прежний
|
||||
# peleng и любой процесс, держащий HackRF, переинициализировать USB, запустить
|
||||
# в фоне (лог /tmp/peleng.log). Профиль и флаги в inventory/group_vars/all/scanner.yml,
|
||||
# разово поверх: ansible-playbook scanner-start.yml -e scanner_args="--freq 2437"
|
||||
- name: Запуск сканера на узлах
|
||||
hosts: all
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: node.py start {{ scanner_profile }} {{ scanner_args }}
|
||||
ansible.builtin.command:
|
||||
argv: "{{ ['python3', scanner_dir + '/scripts/node.py', 'start', scanner_profile] + scanner_args.split() }}"
|
||||
register: start
|
||||
changed_when: true
|
||||
|
||||
- name: node.py status
|
||||
ansible.builtin.command:
|
||||
argv: ["python3", "{{ scanner_dir }}/scripts/node.py", "status"]
|
||||
register: status
|
||||
changed_when: false
|
||||
|
||||
- name: Итог по узлу
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ start.stdout_lines + status.stdout_lines }}"
|
||||
@@ -0,0 +1,22 @@
|
||||
# Остановка peleng на всех узлах: node.py stop останавливает свой peleng и любой
|
||||
# процесс, держащий HackRF. После этого HackRF свободен для scan или калибровки.
|
||||
- name: Остановка сканера на узлах
|
||||
hosts: all
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: node.py stop
|
||||
ansible.builtin.command:
|
||||
argv: ["python3", "{{ scanner_dir }}/scripts/node.py", "stop"]
|
||||
register: stop
|
||||
changed_when: stop.stdout | length > 0
|
||||
|
||||
- name: node.py status
|
||||
ansible.builtin.command:
|
||||
argv: ["python3", "{{ scanner_dir }}/scripts/node.py", "status"]
|
||||
register: status
|
||||
changed_when: false
|
||||
failed_when: "'работает' in status.stdout"
|
||||
|
||||
- name: Итог по узлу
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ stop.stdout_lines + status.stdout_lines }}"
|
||||
@@ -0,0 +1,4 @@
|
||||
# Домашняя сеть для провижнинга (apt, обновления). Скопировать в vars/wifi.yml,
|
||||
# он в .gitignore. Смена роутера - смена этих двух строк и прогон wifi-on.yml.
|
||||
wifi_ssid: Keenetic-6852
|
||||
wifi_psk: пароль
|
||||
@@ -0,0 +1,19 @@
|
||||
# Перед работой Wi-Fi узлов выключается: адаптер сидит в 2,4 ГГц рядом
|
||||
# с приёмником. Состояние радио NetworkManager помнит через перезагрузку,
|
||||
# обратно включает только wifi-on.yml.
|
||||
- name: Wi-Fi выключить
|
||||
hosts: all
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Радио Wi-Fi выключено
|
||||
become: true
|
||||
ansible.builtin.shell: |
|
||||
if [ "$(nmcli radio wifi)" = disabled ]; then echo OK; else nmcli radio wifi off && echo CHANGED; fi
|
||||
register: radio
|
||||
changed_when: "'CHANGED' in radio.stdout"
|
||||
|
||||
- name: wlan0 без адреса
|
||||
ansible.builtin.command: ip -4 -o addr show wlan0
|
||||
register: wlan
|
||||
changed_when: false
|
||||
failed_when: wlan.stdout != ""
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
# Узлы подключаются к домашней сети (vars/wifi.yml) ради интернета для apt.
|
||||
# Проводная сеть 11.0.0.0/24 без шлюза, поэтому маршрут по умолчанию
|
||||
# и DNS приходят от Wi-Fi. В конце каждый узел обязан достучаться до интернета.
|
||||
- name: Wi-Fi включить и подключить к домашней сети
|
||||
hosts: all
|
||||
gather_facts: false
|
||||
vars_files:
|
||||
- vars/wifi.yml
|
||||
vars:
|
||||
wifi_con: fleet-wifi
|
||||
tasks:
|
||||
- name: Радио Wi-Fi включено
|
||||
become: true
|
||||
ansible.builtin.shell: |
|
||||
if [ "$(nmcli radio wifi)" = enabled ]; then echo OK; else nmcli radio wifi on && echo CHANGED; fi
|
||||
register: radio
|
||||
changed_when: "'CHANGED' in radio.stdout"
|
||||
|
||||
- name: Профиль {{ wifi_con }} с актуальными SSID и паролем
|
||||
become: true
|
||||
community.general.nmcli:
|
||||
conn_name: "{{ wifi_con }}"
|
||||
ifname: wlan0
|
||||
type: wifi
|
||||
ssid: "{{ wifi_ssid }}"
|
||||
wifi_sec:
|
||||
key-mgmt: wpa-psk
|
||||
psk: "{{ wifi_psk }}"
|
||||
autoconnect: true
|
||||
state: present
|
||||
register: profile
|
||||
|
||||
- name: Переподключение после смены SSID или пароля
|
||||
become: true
|
||||
ansible.builtin.command: nmcli con down {{ wifi_con }}
|
||||
when: profile.changed
|
||||
failed_when: false
|
||||
|
||||
- name: Подключение активно
|
||||
become: true
|
||||
ansible.builtin.shell: |
|
||||
state=$(nmcli -t -f GENERAL.STATE con show {{ wifi_con }} | cut -d: -f2)
|
||||
if [ "$state" = activated ]; then echo OK; else nmcli con up {{ wifi_con }} >/dev/null && echo CHANGED; fi
|
||||
register: up
|
||||
changed_when: "'CHANGED' in up.stdout"
|
||||
|
||||
- name: Интернет доступен (DNS и HTTPS)
|
||||
ansible.builtin.uri:
|
||||
url: https://deb.debian.org/
|
||||
register: inet
|
||||
retries: 6
|
||||
delay: 5
|
||||
until: inet.status == 200
|
||||
|
||||
- name: Адрес в домашней сети
|
||||
ansible.builtin.command: nmcli -t -f IP4.ADDRESS con show {{ wifi_con }}
|
||||
register: addr
|
||||
changed_when: false
|
||||
|
||||
- name: Итог по узлу
|
||||
ansible.builtin.debug:
|
||||
msg: "[+] {{ inventory_hostname }}: {{ addr.stdout | regex_replace('^IP4.ADDRESS\\[1\\]:', '') }}, интернет есть"
|
||||
Reference in New Issue
Block a user