12 KiB
BSP 통합 가이드 — Web Configurator v1.11.16
디바이스 이미지(Yocto/OE 등)에 포함하기 위한 커밋 히스토리 없는 클린 스냅샷입니다. 런타임 앱·systemd 유닛·샘플·문서와 optional nginx sample 설정만 들어 있고, 개발/내부 자료와 VCS 이력은 없습니다.
1. 런타임 구조
- Python 3 애플리케이션, stdlib 전용 — pip·virtualenv·외부 패키지 없음.
- 실행 진입점:
python3 /opt/web-configurator/src/server.py - 리슨 포트: 9090 (유닛의
Environment=PORT=로 변경 가능) - 앱은 기본적으로
:9090에서 직접 서비스됩니다. nginx:80reverse proxy는 optional이며,deploy/nginx.conf는 BSP가 필요할 때 쓰는 sample 설정입니다. - 영속 상태 — 패키지에 없음(런타임/다른 컴포넌트가 생성):
- DB:
/home/root/db/dynamic_data.db(DB_PATH) - 로그:
/opt/log/dpworldapp(LOG_DIR)
- DB:
nginx optional:
scripts/deploy.ps1는 nginx 설정을 설치하거나 수정하지 않습니다. BSP에서deploy/nginx.conf를 사용할 때만 이미지 레이아웃에 맞게 설치하고, Python 앱 단독 프록시라면proxy_pass를http://127.0.0.1:9090/로 맞추세요.
2. 설치 경로 (do_install)
| 소스 (이 패키지) | 디바이스 설치 위치 |
|---|---|
src/ |
/opt/web-configurator/src/ |
deploy/web-configurator.service |
${systemd_system_unitdir}/ |
deploy/dpworld-*.service |
${systemd_system_unitdir}/ (제품이 사용하는 유닛만) |
deploy/*.service.d/ |
${systemd_system_unitdir}/<unit>.service.d/ |
deploy/dpworld-*.sh |
각 유닛의 ExecStart= 가 가리키는 경로 |
deploy/dpworld-network-apply-ondemand.conf |
해당 유닛이 참조하는 경로 |
deploy/nginx.conf |
Optional nginx sample site config. BSP/firmware가 nginx를 별도로 소유하면 생략 가능 |
권장 전체 기능 설치 목록:
- 항상 설치:
src/,deploy/web-configurator.service - 네트워크 apply 사용 시 (권장 = 직접 교체):
deploy/dpworld-network-apply-hardened.sh의 내용을/usr/bin/dpworld-network-apply.sh원본 이름으로 설치(펌웨어 base 스크립트 교체)하고deploy/dpworld-network-apply-ondemand.conf를 함께 설치. firmware-native base 유닛(dpworld-network-apply.service/dpworld-network-seed.service)이 그 경로를 호출하므로 자동 적용됨. 이 방식에서는.service.d드롭인을 설치하지 않습니다 (드롭인은 라이브 후적용 fallback 전용 — §7,docs/firmware-boot-hardening.md) - Wi-Fi AP 사용 시:
deploy/dpworld-ap-apply.service,deploy/dpworld-ap-seed.service,deploy/dpworld-hostapd-ap0.service,deploy/dpworld-udhcpd-ap0.service,deploy/dpworld-ap-apply.sh를 함께 설치 - 복구 유닛 사용 시:
deploy/dpworld-net-recover.service설치 *.sh는0755실행 권한으로/usr/bin/에 설치 쓰기 가능 런타임 디렉토리 생성 (recipedo_install/ tmpfiles.d / 유닛의ExecStartPre중 택1):
/opt/web-configurator /opt/log/dpworldapp /opt/fw_staging /opt/fw_upload
/opt/config_backups /home/root/db /home/root/network
3. 런타임 의존성 (RDEPENDS)
stdlib 전용 — 앱이 import하는 python3 표준 모듈만 이미지에 포함하면 됩니다. (외부 패키지 없음) OE의 모듈형 python3 기준 예시:
python3-core python3-sqlite3 python3-json python3-netserver python3-netclient
python3-compression python3-crypt python3-logging python3-datetime python3-threading
python3-shell python3-io python3-mime python3-stringold python3-ctypes
실제 import: sqlite3, http(.server), socketserver, socket, urllib, json, gzip, tarfile, zipfile, hashlib, subprocess, shlex, logging, datetime, ipaddress, mimetypes, struct, tempfile, shutil, re, io, os, sys, time, copy, traceback — 사용하는 OE python3 분할 패키지에 맞춰 확인하세요.
추가로 유닛이 런타임에 쓰는 시스템 패키지: nginx reverse proxy를 이미지에서 제공할 때만 nginx.
네트워크/AP 유닛 사용 시 wpa-supplicant, hostapd, udhcpd/busybox, iproute2 등.
4. systemd
SYSTEMD_SERVICE:${PN} = "web-configurator.service"
SYSTEMD_AUTO_ENABLE = "enable"
제품에서 필요한 dpworld-* 유닛(network-apply, Wi-Fi AP, recovery)을 추가하세요. 전체 기능 이미지에서는 보통 다음처럼 함께 등록합니다:
SYSTEMD_SERVICE:${PN} = "web-configurator.service \
dpworld-ap-seed.service \
dpworld-hostapd-ap0.service \
dpworld-udhcpd-ap0.service"
dpworld-ap-apply.service와 dpworld-net-recover.service는 웹 설정기/watchdog이 on-demand로 systemctl start 하므로 [Install] 없이 설치만 하면 됩니다. dpworld-network-apply.service/dpworld-network-seed.service는 firmware-native base 유닛이며 /usr/bin/dpworld-network-apply.sh 를 호출합니다 — 본 패키지는 그 base 스크립트를 하드닝본으로 교체합니다(권장, §7). (펌웨어 원본을 교체할 수 없는 라이브 디바이스에서는 .service.d override 드롭인이 fallback.)
5. 샘플 레시피 — web-configurator_1.11.16.bb
SUMMARY = "DP World Smart Solutions — Web Configurator"
LICENSE = "CLOSED"
# 방법 A — 내부 git 서버의 태그 릴리스를 fetch (배포물이 repo 루트에 평탄 배치됨):
SRC_URI = "git://<internal-host>/<path>/NewWebConfigurator.git;branch=<branch>;protocol=ssh"
SRCREV = "<v1.11.16 의 sha 또는 tag>"
S = "${WORKDIR}/git"
# 방법 B — git archive 로 만든 스냅샷 tarball 사용:
# (git -C <repo> archive v1.11.16 | gzip > web-configurator-v1.11.16.tar.gz)
# SRC_URI = "file://web-configurator-v1.11.16.tar.gz"
# S = "${WORKDIR}"
inherit systemd
RDEPENDS:${PN} += "python3-core python3-sqlite3 python3-json python3-netserver \
python3-netclient python3-compression python3-crypt python3-logging \
python3-datetime python3-threading python3-shell python3-io \
python3-mime"
# Optional: add nginx only if this recipe installs/enables the nginx reverse proxy.
# RDEPENDS:${PN} += "nginx"
SYSTEMD_SERVICE:${PN} = "web-configurator.service"
SYSTEMD_AUTO_ENABLE = "enable"
do_install() {
# 애플리케이션
install -d ${D}/opt/web-configurator
cp -r ${S}/src ${D}/opt/web-configurator/
# systemd 유닛
install -d ${D}${systemd_system_unitdir}
install -m 0644 ${S}/deploy/web-configurator.service ${D}${systemd_system_unitdir}/
install -m 0644 ${S}/deploy/dpworld-ap-apply.service ${D}${systemd_system_unitdir}/
install -m 0644 ${S}/deploy/dpworld-ap-seed.service ${D}${systemd_system_unitdir}/
install -m 0644 ${S}/deploy/dpworld-hostapd-ap0.service ${D}${systemd_system_unitdir}/
install -m 0644 ${S}/deploy/dpworld-udhcpd-ap0.service ${D}${systemd_system_unitdir}/
install -m 0644 ${S}/deploy/dpworld-net-recover.service ${D}${systemd_system_unitdir}/
# 유닛 ExecStart 대상 스크립트
install -d ${D}${bindir}
install -m 0755 ${S}/deploy/dpworld-ap-apply.sh ${D}${bindir}/dpworld-ap-apply.sh
# 네트워크-적용 하드닝 (권장 = 직접 교체):
# 펌웨어 base 스크립트 /usr/bin/dpworld-network-apply.sh 를 하드닝본으로 교체한다.
# firmware-native 한 dpworld-network-apply.service / dpworld-network-seed.service 가
# 이 경로를 호출하므로 apply·--boot 모두 자동으로 하드닝 동작을 탄다. 드롭인은 설치하지 않는다.
# (파일 소유권은 BSP에서 조정 — firmware recipe의 base 파일을 이 패키지가 덮어쓰도록
# bbappend 또는 recipe 우선순위로 정리. 자세히 docs/firmware-boot-hardening.md)
install -m 0755 ${S}/deploy/dpworld-network-apply-hardened.sh \
${D}${bindir}/dpworld-network-apply.sh
install -m 0644 ${S}/deploy/dpworld-network-apply-ondemand.conf \
${D}${systemd_system_unitdir}/dpworld-network-apply-ondemand.conf
# Fallback (라이브 후적용 전용 — 베이킹 시 설치하지 않음):
# 펌웨어 원본을 교체할 수 없는 경우에만, 하드닝본을 원래 -hardened 이름으로 설치하고
# deploy/dpworld-network-{apply,seed}.service.d/20-hardened.conf 드롭인 2개로
# base 유닛의 ExecStart 를 override 한다.
# Optional nginx site config.
# scripts/deploy.ps1 does not use this file. Skip this block if firmware/BSP
# owns nginx, or if the device will access the app directly on :9090.
if [ -f ${S}/deploy/nginx.conf ]; then
install -d ${D}${sysconfdir}/nginx
install -m 0644 ${S}/deploy/nginx.conf ${D}${sysconfdir}/nginx/web-configurator.conf
fi
# 쓰기 가능 런타임 디렉토리
install -d ${D}/opt/log/dpworldapp ${D}/opt/fw_staging ${D}/opt/fw_upload \
${D}/opt/config_backups ${D}/home/root/db ${D}/home/root/network
}
FILES:${PN} += "/opt/web-configurator /opt/log ${systemd_system_unitdir} \
/opt/fw_staging /opt/fw_upload /opt/config_backups \
/home/root/db /home/root/network ${bindir}/dpworld-*.sh \
${sysconfdir}/nginx"
6. 부팅 후 동작 확인 (smoke test)
systemctl status web-configurator # active (running)
curl -fsS http://127.0.0.1:9090/ | head # 앱 응답
curl -fsS http://127.0.0.1/ | head # optional: nginx 경유 사용 시
7. firmware-native 전제 + 네트워크-적용 하드닝 통합
firmware가 제공하는 것 (이 패키지에 미포함)
- base 네트워크-적용 유닛 —
dpworld-network-apply.service,dpworld-network-seed.service. 이 유닛들은/usr/bin/dpworld-network-apply.sh를 호출합니다(no-arg /--boot). - dpworldapp(텔레메트리 바이너리), (전환기의 레거시
app-runner) — firmware-native. - nginx — 제품 이미지가
:80reverse proxy를 제공할 때만. 앱을:9090으로 직접 접근하면 불필요.
네트워크-적용 하드닝본 통합 — ① 직접 교체(권장) vs ② override(fallback)
펌웨어 base /usr/bin/dpworld-network-apply.sh 에는 WiFi country 변경 시 modprobe -r wlan
라이브 재로드 경로가 있어 QCA6490에서 PMU 워치독 재부팅 루프를 유발한 이력이 있습니다.
deploy/dpworld-network-apply-hardened.sh 가 이를 제거한 완전 대체본입니다.
| ① 직접 교체 (BSP 베이킹, 권장) | ② override (라이브 후적용, fallback) | |
|---|---|---|
| 대상 | 펌웨어 이미지를 빌드하는 협력사 | 이미 구워진 디바이스(우리 deploy.ps1) |
| 방법 | 하드닝본 내용을 /usr/bin/dpworld-network-apply.sh 원본 이름으로 설치(원본 교체) |
하드닝본을 …-hardened.sh 로 두고 .service.d/20-hardened.conf 드롭인 2개로 ExecStart 교체 |
| 드롭인 | 설치 안 함 | 설치함 |
| 효과 | base 유닛이 그대로 하드닝 스크립트를 실행 | base 유닛의 ExecStart가 하드닝본으로 바뀜 |
절차 상세: docs/firmware-boot-hardening.md "펌웨어 베이킹 (BSP) — 원본 교체 방법".
이 패키지가 소유·제공하는 스크립트 (모두 포함됨)
| 스크립트 | 설치 위치(권장 ①) | 호출 주체 |
|---|---|---|
deploy/dpworld-ap-apply.sh |
/usr/bin/dpworld-ap-apply.sh |
dpworld-ap-apply.service, dpworld-ap-seed.service |
deploy/dpworld-network-apply-hardened.sh |
/usr/bin/dpworld-network-apply.sh (원본 교체) |
firmware-native dpworld-network-apply.service / dpworld-network-seed.service |
fallback(②) 사용 시에는
…-hardened.sh이름으로 설치하고.service.d드롭인 2개(deploy/dpworld-network-apply.service.d/,deploy/dpworld-network-seed.service.d/)를 함께 둡니다.
웹 설정기 앱이 런타임에 호출하는 유닛
server.py 는 다음을 systemctl start 로 호출합니다:
dpworld-network-apply.service(firmware base 유닛 — 교체된 하드닝 스크립트 실행), dpworld-ap-apply.service, dpworld-hostapd-ap0.service, dpworld-udhcpd-ap0.service, dpworld-net-recover.service.
→ base 네트워크-적용 유닛(firmware-native)을 제외하면 모두 본 패키지에 포함됩니다.