Compare commits
10 Commits
f0a706b2f6
...
f56196340f
| Author | SHA1 | Date | |
|---|---|---|---|
| f56196340f | |||
| 81716e223a | |||
| 4c22aa6351 | |||
| 33af395c8d | |||
| 43408fe9ce | |||
| 6e71002b9a | |||
| 8d12608d34 | |||
| f0d6ddf269 | |||
| 4beb3f9f78 | |||
| 5c27fdbd80 |
@@ -1,3 +1,2 @@
|
|||||||
keys/
|
keys/
|
||||||
specs/
|
|
||||||
*.retry
|
*.retry
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# fleet
|
||||||
|
|
||||||
|
Идемпотентный провижнинг парка приёмников пеленгации (Raspberry Pi + HackRF).
|
||||||
|
Один прогон приводит новую или старую малинку в рабочее состояние: обновление
|
||||||
|
системы, зависимости сборки, общий deploy-ключ до Gitea, клон и сборка
|
||||||
|
`hackrf-scanner`.
|
||||||
|
|
||||||
|
Гоняется дома, пока узлы в сети с интернетом. После переноса в изолированную
|
||||||
|
сеть (коммутатор, статические IP) на карте уже есть всё; правки кода дальше
|
||||||
|
идут `rsync` + сборка на месте. Статические IP playbook не трогает.
|
||||||
|
|
||||||
|
## Требования
|
||||||
|
|
||||||
|
- на управляющей машине: `ansible` (Arch: `pacman -S ansible`), доступ по ssh
|
||||||
|
к узлам под `pi` по ключу;
|
||||||
|
- на узлах: Raspberry Pi OS (Debian 13), `pi` с sudo без пароля, интернет.
|
||||||
|
|
||||||
|
## Первый запуск
|
||||||
|
|
||||||
|
scripts/gen-key.sh # пара keys/gitea_deploy (в .gitignore)
|
||||||
|
# добавить keys/gitea_deploy.pub как deploy key (read-only)
|
||||||
|
# в Gitea: IU9/hackrf-scanner
|
||||||
|
ansible-playbook playbook.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
|
||||||
|
|
||||||
|
## Инвентарь
|
||||||
|
|
||||||
|
`inventory/hosts.yml`: адреса узлов в домашней сети (транзитные), а также
|
||||||
|
справочно -- статический IP для поля, серийник HackRF и координаты x, y (м).
|
||||||
|
Ветка репозитория -- переменная `scanner_branch`.
|
||||||
|
|
||||||
|
## Приёмка
|
||||||
|
|
||||||
|
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.
|
||||||
+8
-3
@@ -4,15 +4,18 @@ all:
|
|||||||
scanner_branch: feature/scanner-v2
|
scanner_branch: feature/scanner-v2
|
||||||
gitea_host: monitor.yss.su
|
gitea_host: monitor.yss.su
|
||||||
gitea_port: 2222
|
gitea_port: 2222
|
||||||
|
server_ip: 11.0.0.100
|
||||||
hosts:
|
hosts:
|
||||||
node102:
|
node102:
|
||||||
ansible_host: 192.168.1.45
|
ansible_host: 192.168.1.45
|
||||||
|
sdr_id: 1
|
||||||
static_ip: 11.0.0.102
|
static_ip: 11.0.0.102
|
||||||
sdr_serial: a32868dc35944247
|
sdr_serial: a32868dc35944247
|
||||||
x: -0.68
|
x: -0.68
|
||||||
y: -1.28
|
y: -1.28
|
||||||
node104:
|
node104:
|
||||||
ansible_host: 192.168.1.50
|
ansible_host: 192.168.1.50
|
||||||
|
sdr_id: 2
|
||||||
static_ip: 11.0.0.104
|
static_ip: 11.0.0.104
|
||||||
sdr_serial: 42a068dc377ab507
|
sdr_serial: 42a068dc377ab507
|
||||||
note: PortaPack
|
note: PortaPack
|
||||||
@@ -20,13 +23,15 @@ all:
|
|||||||
y: 0.45
|
y: 0.45
|
||||||
node105:
|
node105:
|
||||||
ansible_host: 192.168.1.87
|
ansible_host: 192.168.1.87
|
||||||
|
sdr_id: 3
|
||||||
static_ip: 11.0.0.105
|
static_ip: 11.0.0.105
|
||||||
sdr_serial: a32868dc33894f47
|
sdr_serial: a32868dc33894f47
|
||||||
x: 2.60
|
x: 3.77
|
||||||
y: 0.00
|
y: -0.74
|
||||||
node106:
|
node106:
|
||||||
ansible_host: 192.168.1.42
|
ansible_host: 192.168.1.42
|
||||||
|
sdr_id: 4
|
||||||
static_ip: 11.0.0.106
|
static_ip: 11.0.0.106
|
||||||
sdr_serial: ""
|
sdr_serial: a32868dc346d2847
|
||||||
x: 0.00
|
x: 0.00
|
||||||
y: 0.50
|
y: 0.50
|
||||||
|
|||||||
+50
-11
@@ -2,27 +2,53 @@
|
|||||||
hosts: all
|
hosts: all
|
||||||
tasks:
|
tasks:
|
||||||
|
|
||||||
- name: apt update и full-upgrade
|
- name: Обновить кэш apt (не считается изменением)
|
||||||
become: true
|
become: true
|
||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
update_cache: true
|
update_cache: true
|
||||||
cache_valid_time: 3600
|
cache_valid_time: 3600
|
||||||
|
changed_when: false
|
||||||
|
tags: [base]
|
||||||
|
|
||||||
|
- name: apt full-upgrade
|
||||||
|
become: true
|
||||||
|
ansible.builtin.apt:
|
||||||
upgrade: full
|
upgrade: full
|
||||||
tags: [base]
|
tags: [base]
|
||||||
|
|
||||||
- name: Зависимости сборки и утилиты HackRF
|
- name: Зависимости сборки и утилиты HackRF
|
||||||
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]
|
name: [cmake, g++, pkg-config, git, rsync, libhackrf-dev, libusb-1.0-0-dev, libfftw3-dev, hackrf, fish]
|
||||||
state: present
|
state: present
|
||||||
tags: [base]
|
tags: [base]
|
||||||
|
|
||||||
- name: pi в группе plugdev (udev HackRF)
|
- name: pi в группе plugdev, login-shell fish
|
||||||
become: true
|
become: true
|
||||||
ansible.builtin.user:
|
ansible.builtin.user:
|
||||||
name: pi
|
name: pi
|
||||||
groups: plugdev
|
groups: plugdev
|
||||||
append: true
|
append: true
|
||||||
|
shell: /usr/bin/fish
|
||||||
|
tags: [base]
|
||||||
|
|
||||||
|
- name: Права udev на уже подключённый HackRF (устройство старше правил)
|
||||||
|
become: true
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
bad=0
|
||||||
|
for d in /sys/bus/usb/devices/*; do
|
||||||
|
[ -f "$d/idVendor" ] || continue
|
||||||
|
case "$(cat "$d/idVendor"):$(cat "$d/idProduct")" in 1d50:6089|1d50:604b) ;; *) continue;; esac
|
||||||
|
node=/dev/bus/usb/$(printf %03d "$(cat "$d/busnum")")/$(printf %03d "$(cat "$d/devnum")")
|
||||||
|
[ "$(stat -c %G "$node")" = plugdev ] || bad=1
|
||||||
|
done
|
||||||
|
if [ "$bad" = 1 ]; then
|
||||||
|
udevadm control --reload-rules && udevadm trigger --subsystem-match=usb && echo FIXED
|
||||||
|
else
|
||||||
|
echo OK
|
||||||
|
fi
|
||||||
|
register: usb
|
||||||
|
changed_when: "'FIXED' in usb.stdout"
|
||||||
tags: [base]
|
tags: [base]
|
||||||
|
|
||||||
- name: Имя узла
|
- name: Имя узла
|
||||||
@@ -80,29 +106,41 @@
|
|||||||
User git
|
User git
|
||||||
IdentityFile ~/.ssh/gitea_deploy
|
IdentityFile ~/.ssh/gitea_deploy
|
||||||
IdentitiesOnly yes
|
IdentitiesOnly yes
|
||||||
|
StrictHostKeyChecking accept-new
|
||||||
tags: [key]
|
tags: [key]
|
||||||
|
|
||||||
- name: Gitea в known_hosts
|
- name: ~/node.env для обёртки node.sh (только засев, полевые правки не трогаем)
|
||||||
ansible.builtin.known_hosts:
|
ansible.builtin.copy:
|
||||||
name: "[{{ gitea_host }}]:{{ gitea_port }}"
|
dest: ~/node.env
|
||||||
key: "{{ lookup('pipe', 'ssh-keyscan -p ' ~ gitea_port ~ ' -t ed25519 ' ~ gitea_host ~ ' 2>/dev/null') }}"
|
mode: "0644"
|
||||||
path: ~/.ssh/known_hosts
|
force: false
|
||||||
tags: [key]
|
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-разработка)?
|
- name: Локальные правки в репо (rsync-разработка)?
|
||||||
ansible.builtin.command: git status --porcelain
|
ansible.builtin.command: git status --porcelain
|
||||||
args:
|
args:
|
||||||
chdir: ~/hackrf-scanner
|
chdir: ~/hackrf-scanner
|
||||||
register: dirty
|
register: dirty
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
when: repo_dir.stat.exists
|
||||||
tags: [repo]
|
tags: [repo]
|
||||||
|
|
||||||
- name: Stash локальных правок перед обновлением
|
- name: Stash локальных правок перед обновлением
|
||||||
ansible.builtin.command: git stash push -m fleet-provision
|
ansible.builtin.command: git stash push -m fleet-provision
|
||||||
args:
|
args:
|
||||||
chdir: ~/hackrf-scanner
|
chdir: ~/hackrf-scanner
|
||||||
when: dirty.rc == 0 and dirty.stdout != ""
|
when: repo_dir.stat.exists and dirty.stdout != ""
|
||||||
tags: [repo]
|
tags: [repo]
|
||||||
|
|
||||||
- name: Репозиторий hackrf-scanner
|
- name: Репозиторий hackrf-scanner
|
||||||
@@ -111,6 +149,7 @@
|
|||||||
dest: ~/hackrf-scanner
|
dest: ~/hackrf-scanner
|
||||||
version: "{{ scanner_branch }}"
|
version: "{{ scanner_branch }}"
|
||||||
update: true
|
update: true
|
||||||
|
force: true
|
||||||
register: repo
|
register: repo
|
||||||
tags: [repo]
|
tags: [repo]
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#!/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