src.nth.io/

summaryrefslogtreecommitdiff
path: root/openhop/repeater/tasks/main.yaml
blob: 3d47ef430d714e1234e1162729452ae0ffab897a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
---

- name: load board pin preset
  include_vars: "boards/{{repeater_board}}.yaml"

- name: load RF region preset
  include_vars: "rf/{{repeater_rf_preset}}.yaml"

- name: enable SPI for the LoRa HAT
  become: yes
  lineinfile:
    path: "/boot/firmware/config.txt"
    line: "dtparam=spi=on"
    regexp: "^#?dtparam=spi="
  register: spi_result

- name: remind to reboot for SPI to take effect
  debug:
    msg: "config.txt updated  reboot {{inventory_hostname}} for dtparam=spi=on to take effect"
  when: spi_result.changed

- name: apt install openhop repeater dependencies
  become: yes
  apt:
    name:
      - "git"
      - "python3-venv"
      - "python3-dev"
      - "build-essential"

# Raspberry Pi OS ships the spi/gpio groups and udev rules via
# raspberrypi-sys-mods; Ubuntu images have neither, so create them here.
- name: create spi and gpio device access groups
  become: yes
  group:
    name: "{{item}}"
    system: "yes"
  loop:
    - "spi"
    - "gpio"

- name: grant spi and gpio groups access to their devices
  become: yes
  copy:
    dest: "/etc/udev/rules.d/90-spi-gpio-groups.rules"
    content: |
      SUBSYSTEM=="spidev", GROUP="spi", MODE="0660"
      SUBSYSTEM=="gpio", GROUP="gpio", MODE="0660"
    mode: "0644"
  register: udev_result

- name: apply udev rules to existing devices
  become: yes
  shell: "udevadm control --reload-rules && udevadm trigger --subsystem-match=spidev --subsystem-match=gpio"
  when: udev_result.changed

- name: add openhop repeater user
  become: yes
  user:
    name: "{{repeater_user}}"
    system: "yes"
    shell: "/bin/false"
    home: "{{repeater_data_dir}}"
    create_home: "no"
    groups: "spi,gpio"
    append: "yes"

- name: create openhop repeater directories
  become: yes
  file:
    path: "{{item.path}}"
    state: "directory"
    owner: "{{item.owner}}"
    group: "{{item.owner}}"
    mode: "{{item.mode}}"
  loop:
    - { path: "/opt/openhop_repeater", owner: "root", mode: "0755" }
    - { path: "{{repeater_config_dir}}", owner: "root", mode: "0755" }
    - { path: "{{repeater_data_dir}}", owner: "{{repeater_user}}", mode: "0750" }

- name: check installed openhop_repeater version
  become: yes
  stat:
    path: "{{repeater_venv_dir}}/.installed-{{repeater_version}}"
  register: repeater_installed

- name: install openhop_repeater into venv
  become: yes
  pip:
    name: "git+{{repeater_repo}}@{{repeater_version}}"
    virtualenv: "{{repeater_venv_dir}}"
    virtualenv_command: "python3 -m venv"
  when: not repeater_installed.stat.exists
  notify: restart openhop-repeater

# The pip package does not ship these repo-root files, but the web UI's setup
# wizard reads them from the storage dir; without them the hardware step lists
# no options and cannot proceed.
- name: install web UI radio settings and presets
  become: yes
  get_url:
    url: "{{repeater_repo}}/raw/{{repeater_version}}/{{item}}"
    dest: "{{repeater_data_dir}}/{{item}}"
    owner: "{{repeater_user}}"
    group: "{{repeater_user}}"
    mode: "0644"
    force: "{{not repeater_installed.stat.exists}}"
  loop:
    - "radio-settings.json"
    - "radio-presets.json"

- name: stamp installed openhop_repeater version
  become: yes
  copy:
    dest: "{{repeater_venv_dir}}/.installed-{{repeater_version}}"
    content: "{{repeater_version}}\n"
    mode: "0644"
  when: not repeater_installed.stat.exists

# Group-writable so the daemon can persist its generated jwt_secret and the
# setup-wizard credentials back into the config. Note the trade-off: every
# re-template wipes those daemon-written keys and restarts the service.
- name: configure openhop repeater
  become: yes
  template:
    src: "config.yaml.j2"
    dest: "{{repeater_config_dir}}/config.yaml"
    owner: "root"
    group: "{{repeater_user}}"
    mode: "0660"
  notify: restart openhop-repeater

# The web UI restarts the daemon after config changes via
# "sudo --non-interactive systemctl restart openhop-repeater"; the daemon's
# code expects exactly this sudoers file to exist.
- name: allow repeater user to restart its own service
  become: yes
  copy:
    dest: "/etc/sudoers.d/openhop-repeater"
    content: |
      {{repeater_user}} ALL=(root) NOPASSWD: /usr/bin/systemctl restart openhop-repeater
      {{repeater_user}} ALL=(root) NOPASSWD: /usr/bin/systemctl restart openhop-repeater.service
    mode: "0440"
    validate: "visudo -cf %s"

- name: install openhop-repeater systemd service
  become: yes
  template:
    src: "openhop-repeater.service.j2"
    dest: "/lib/systemd/system/openhop-repeater.service"
    mode: "0644"
  notify: restart openhop-repeater

- name: ensure openhop-repeater service is started
  become: yes
  systemd:
    name: "openhop-repeater.service"
    enabled: "yes"
    state: "started"
    daemon_reload: "yes"