You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

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.1 nginx.conf 제거를 반영했습니다.


0. 한눈에 — 핵심 3가지

  1. 웹 설정기 앱 자체는 네트워크/AP 파일 없이도 단독으로 동작합니다 (:9090). 앱은 src/(파이썬) + web-configurator.service 두 가지만 있으면 기동·설정 저장이 됩니다.
  2. "충돌"의 실체는 단 3개 파일(네트워크 드롭인)이 펌웨어가 소유한 유닛을 덮어쓰는 것뿐입니다. 그 외 모든 파일은 **새로 추가(additive)**되는 것이라 기존 자원을 전혀 건드리지 않습니다 — 크래시·에러를 내지 않습니다.
  3. 따라서 원하는 기능만 골라 설치하면 충돌 없이 통합됩니다. (§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.serviceExecStart를 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)을 권장

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. ① 또는 ②를 택하면 이 접점도 사라집니다.