12 KiB
Web Configurator — deploy/ 통합 가이드 (협력사 전달용)
목적:
deploy/폴더의 구성요소 중 꼭 필요한 것과 그 기능을 정리하고, 기존dpworldapp/펌웨어와의 "충돌" 오해를 해소합니다. 대상 버전: v1.12.1 · 검증:deploy/통합 의미론은 v1.11.15 기준 소스 코드 + 실디바이스(192.168.55.54, 펌웨어 원본 상태) 대조 완료. v1.12.0 설치 경로 이전(/usr/lib)과 v1.12.1nginx.conf제거를 반영했습니다.
0. 한눈에 — 핵심 3가지
- 웹 설정기 앱 자체는 네트워크/AP 파일 없이도 단독으로 동작합니다 (
:9090). 앱은src/(파이썬) +web-configurator.service두 가지만 있으면 기동·설정 저장이 됩니다. - "충돌"의 실체는 단 3개 파일(네트워크 드롭인)이 펌웨어가 소유한 유닛을 덮어쓰는 것뿐입니다. 그 외 모든 파일은 **새로 추가(additive)**되는 것이라 기존 자원을 전혀 건드리지 않습니다 — 크래시·에러를 내지 않습니다.
- 따라서 원하는 기능만 골라 설치하면 충돌 없이 통합됩니다. (§3에 3가지 통합 방식)
경로 표준 (v1.12.0~, 협력사 협의 반영): 앱 코드는
/usr/lib/web-configurator에 설치합니다 — FHS상/usr/lib가 read-only program code 자리이며, BSP가 이미지에 굽는 read-only rootfs에 적합합니다. 쓰기 런타임 데이터(로그·펌웨어 staging/upload·설정 백업)는/usr/lib(read-only)가 아니라 쓰기 가능한 영속 파티션(/opt,/home/root) 에 둡니다(§4).신규 텔레메트리 Uplink (v1.12.1) 는 런타임에 OS 호스트 라우트(/32)만 조작하므로
deploy/추가 구성요소가 필요 없습니다 — 새 유닛/스크립트 없이 기존web-configurator.service(root 권한) 만으로 동작합니다.
1. 기능 그룹과 필요한 파일
deploy/의 구성요소는 3개 기능 그룹으로 나뉩니다. 그룹 단위로 켜고 끌 수 있습니다.
A. 웹 설정기 (필수 — 항상 설치)
| 파일 | 기능 | 설치 위치 |
|---|---|---|
(앱 본체 src/) |
파이썬 stdlib HTTP 서버. 웹 UI + 설정 API. :9090 리슨 |
/usr/lib/web-configurator/src (표준 — read-only rootfs 가능; 쓰기 데이터는 §4) |
web-configurator.service |
위 앱을 부팅 자동기동 + 크래시 시 재시작하는 systemd 유닛 | ${systemd_system_unitdir} |
이 그룹만으로 웹 설정기가 동작합니다(설정은 DB /home/root/db에 저장). dpworldapp과 충돌하지 않습니다.
B. 네트워크 즉시(라이브) 적용 — 선택
왜 필요한가:
dpworldapp은 재기동 시에만 네트워크/설정을 OS에 반영합니다. 이 그룹은 웹 UI에서 IP·Wi-Fi(SSID/비밀번호)를 바꾸면 재부팅·dpworldapp 재기동 없이 즉시 반영하기 위한 보완 구성입니다.동작 메커니즘: 웹이 렌더 파일을
/home/root/network/에 기록 → 적용 스크립트가 그것을/run/systemd/network/로 동기화 +networkctl/wpa_cli재구성. (※networkctl은/home/root/network를 직접 읽지 않으므로 이 동기화 스크립트가 있어야 라이브 적용이 됩니다.)
| 파일 | 기능 | 설치 위치 |
|---|---|---|
dpworld-network-apply-hardened.sh |
네트워크 적용 스크립트. 펌웨어 원본의 안전 버전 — Wi-Fi country 변경 시 modprobe -r wlan(QCA6490 워치독 리부팅 루프 유발)을 제거하고 country를 **재부팅 시 적용(reboot-deferred)**으로 처리 |
/usr/bin/ (0755) |
dpworld-net-recover.service (옵션) |
wlan 모듈이 완전히 내려갔을 때 복구(modprobe + wpa 재시작). 웹/워치독이 on-demand로 호출 |
${systemd_system_unitdir} |
위 스크립트를 어떻게 펌웨어 적용 경로에 연결할지(드롭인 vs 전용 유닛 vs 미사용)는 §3에서 선택합니다. 드롭인 3종은 §3 옵션 ③에서만 사용합니다.
C. Wi-Fi AP 모드 — 선택
기능: 장치를 Wi-Fi AP로 띄워 작업자가 휴대폰/노트북으로 직접 접속(현장 provisioning).
wlan0(STA)은 건드리지 않고ap0가상 인터페이스를 추가해 사용. hostapd + udhcpd + ap0 전용 방화벽(INPUT 전체 개방·WPA2 PSK가 접근 게이트 / FORWARD 차단 = AP 클라이언트의 내부망·PLC(eth1) 경유 차단).
| 파일 | 기능 | 설치 위치 |
|---|---|---|
dpworld-ap-apply.sh |
AP 기동/해제 스크립트(ap0 생성·IP·방화벽·hostapd/udhcpd 시작) | /usr/bin/ (0755) |
dpworld-ap-apply.service |
웹이 on-demand로 호출하는 AP 적용 유닛 ([Install] 없음 = 부팅 자동기동 안 함) |
${systemd_system_unitdir} |
dpworld-hostapd-ap0.service |
ap0에서 hostapd 실행 ([Install] 없음, ap-apply.sh가 기동) |
${systemd_system_unitdir} |
dpworld-udhcpd-ap0.service |
ap0에서 DHCP 서버 실행 ([Install] 없음, ap-apply.sh가 기동) |
${systemd_system_unitdir} |
dpworld-ap-seed.service (옵션) |
재부팅 후 AP를 자동 재기동(복구). 없으면 재부팅 후 AP 수동 재활성 필요 | ${systemd_system_unitdir} |
AP 그룹은 전적으로 신규 구성입니다.
dpworldapp/펌웨어 자원을 건드리지 않으며,ap0전용이라 STA·eth·dpworldapp과 충돌하지 않습니다.
2. 제외 / 참고
| 파일 | 사유 |
|---|---|
deploy/nginx.conf |
v1.12.1에서 패키지에서 제거됨. 앱은 :9090에서 직접 서비스되므로 reverse proxy 없이 동작합니다. 협력사가 자체 nginx로 :80 프런트할 경우, 협력사 설정에서 proxy_pass http://127.0.0.1:9090/만 잡으면 됩니다(앱 포트는 :9090 — 레거시 :8080 Java app-runner 아님). |
scripts/board_trace*.sh |
(deploy/ 밖이지만 참고) board_config를 폴링해 /tmp에 기록하는 개발 진단용 스크립트 — 운영 배포물에서 제거 권장 |
3. "충돌" 해소 — 네트워크 적용 통합 3가지 방식
"충돌"은 §1-B의 라이브 적용을 펌웨어 유닛을 빌려서 수행하기 때문에 발생합니다. 웹은 적용을 dpworld-network-apply.service(펌웨어 소유 유닛) 이름으로 호출하므로, 그 유닛이 우리 스크립트를 실행하게 하려면 유닛을 건드려야 합니다. 아래 3가지 중 선택하세요.
| 방식 | 설치 파일 | 펌웨어 유닛 접촉 | 라이브 적용 | 비고 |
|---|---|---|---|---|
| ① 저장 전용 | 네트워크 파일 0개 | 없음(무접촉) | ✗ (dpworldapp 재기동 시 반영) | 웹은 설정 편집·저장만. 충돌 0. 가장 단순 |
| ② 전용 유닛 (권장) | dpworld-network-apply-hardened.sh + 신규 웹 전용 유닛 |
없음(무접촉) | ✓ | 웹이 펌웨어 유닛 대신 자체 유닛으로 적용. 웹 소규모 코드 변경 필요(적용 유닛명을 NET_APPLY_SERVICE env로 분리 — 현재는 dpworld-network-apply.service로 하드코딩) |
| ③ 드롭인 override (현재 패키지) | dpworld-network-apply-hardened.sh + 드롭인 3종 |
있음(override) | ✓ | 펌웨어 유닛의 ExecStart/의존성을 우리 것으로 교체. 이것이 협력사가 본 "충돌" |
드롭인 3종(③에서만 사용):
dpworld-network-apply.service.d/20-hardened.conf— 펌웨어dpworld-network-apply.service의ExecStart를 hardened.sh로 교체dpworld-network-seed.service.d/20-hardened.conf— 펌웨어dpworld-network-seed.service(부팅 seed)를hardened.sh --boot로 교체dpworld-network-apply-ondemand.conf— 위 유닛의Requires=(boot-only seed 의존)를 비워 on-demand 기동 허용
권장: 펌웨어 베이킹(BSP)에서는 하드닝본을
/usr/bin/dpworld-network-apply.sh원본 이름으로 직접 교체하는 방식이 1차입니다(드롭인 미설치 —BSP-INTEGRATION.md§7 ①). 펌웨어 유닛을 못 건드리는 라이브 디바이스에서만 드롭인 override(③)를 fallback으로 씁니다. 라이브 적용이 불필요하면 ① 저장 전용. (③/직접교체 시 §1-B 동작 차이 — Wi-Fi country는 재부팅 시 적용 — 만 합의하면 됨).
4. 설치 시 주의 (부분배포 사고 방지)
- 드롭인(③)을 설치하면
dpworld-network-apply-hardened.sh도 반드시 함께 설치하세요. 드롭인만 있고 스크립트가 없으면 ExecStart가 없는 파일을 가리켜 펌웨어 네트워크 유닛이 EXEC 실패합니다(멀쩡하던 적용이 깨짐). web-configurator.service를 설치하면 앱 본체src/도 함께 설치하세요. 앱이 없으면 서비스가 재시작 루프에 빠집니다.- 쓰기 가능 경로: 앱 코드는 read-only rootfs(
/usr/lib/web-configurator)에 두지만, 아래 런타임 경로는 쓰기 가능한 영속 파티션(/opt,/home/root)에 있어야 합니다.- DB
/home/root/db· 네트워크 렌더/home/root/network(dpworldapp과 공유 — 그대로) - 로그
/opt/log/dpworldapp(유닛LOG_DIR) · 펌웨어 staging/upload/opt/fw_staging·/opt/fw_upload· 설정 백업/opt/config_backups(유닛ReadWritePaths참조) - hardened.sh 상태/로그
STATE_DIR=/opt/dpworld-network(펌웨어 원본엔 없던 신규 경로 —/opt가 늦게 마운트되면 로그/reboot 마커만 유실, 적용 자체는 진행)./opt마운트 보장(RequiresMountsFor=/opt)을 권장
- DB
5. 전체 파일 분류표 (요약)
deploy/ 파일 |
그룹 | 필요성 | 펌웨어 유닛 접촉 |
|---|---|---|---|
web-configurator.service |
A 코어 | 필수 | 무접촉(신규 유닛) |
dpworld-network-apply-hardened.sh |
B 네트워크 | 라이브 적용 시 필요 | 무접촉(파일) |
dpworld-network-apply.service.d/20-hardened.conf |
B 네트워크 | ③에서만 | ★ override |
dpworld-network-seed.service.d/20-hardened.conf |
B 네트워크 | ③에서만 | ★ override |
dpworld-network-apply-ondemand.conf |
B 네트워크 | ③에서만 | ★ override |
dpworld-net-recover.service |
B 네트워크 | 옵션(복구 안전망) | 무접촉(신규 유닛) |
dpworld-ap-apply.sh |
C AP | AP 시 필수 | 무접촉(파일) |
dpworld-ap-apply.service |
C AP | AP 시 필수 | 무접촉(신규 유닛) |
dpworld-hostapd-ap0.service |
C AP | AP 시 필수 | 무접촉(신규 유닛) |
dpworld-udhcpd-ap0.service |
C AP | AP 시 필수 | 무접촉(신규 유닛) |
dpworld-ap-seed.service |
C AP | 옵션(재부팅 후 AP 자동복구) | 무접촉(신규 유닛) |
★ 표시(드롭인 3종)만이 펌웨어 소유 유닛을 건드립니다 = "충돌"의 전부. 이 3개를 빼면 펌웨어/
dpworldapp자원은 0개 건드리지 않습니다.nginx.conf는 v1.12.1에서 패키지에서 제거됨(§2) — deploy/ 구성요소 아님.
부록: dpworldapp과의 공유·격리 요약
- 공유(의도된 연동): DB
/home/root/db, 네트워크 렌더/home/root/network— 웹과dpworldapp이 동일 파일 계약(byte 호환)을 공유. 웹이 편집·저장하고dpworldapp이 소비하는 구조(충돌 아님). - 격리(신규, 무접촉): 웹 앱(
:9090), AP(ap0전용 + 방화벽), 복구 유닛, 텔레메트리 Uplink(OS 호스트 라우트만) — 전부 신규 자원. - 유일한 접점:
dpworld-network-apply.service/-seed.service(펌웨어 소유) — 라이브 적용을 위해 ③ 방식에서만 override. ① 또는 ②를 택하면 이 접점도 사라집니다.