feat: initialize managed portal
This commit is contained in:
40
managed/people_flow_project/scripts/docker-entrypoint.sh
Executable file
40
managed/people_flow_project/scripts/docker-entrypoint.sh
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env sh
|
||||
set -eu
|
||||
|
||||
PROJECT_DIR="/opt/people-flow"
|
||||
CONFIG_TEMPLATE="${PROJECT_DIR}/config/config.example.yaml"
|
||||
CONFIG_PATH="${CONFIG_PATH:-${PROJECT_DIR}/config/local.yaml}"
|
||||
OUTPUT_DIR="${OUTPUT_DIR:-${PROJECT_DIR}/outputs}"
|
||||
RTSP_URL="${RTSP_URL:-}"
|
||||
API_HOST="${API_HOST:-0.0.0.0}"
|
||||
API_PORT="${API_PORT:-18082}"
|
||||
|
||||
mkdir -p "${OUTPUT_DIR}" "$(dirname "${CONFIG_PATH}")"
|
||||
|
||||
if [ ! -f "${CONFIG_PATH}" ]; then
|
||||
cp "${CONFIG_TEMPLATE}" "${CONFIG_PATH}"
|
||||
fi
|
||||
|
||||
python - "$CONFIG_PATH" "$RTSP_URL" "$OUTPUT_DIR" <<'PY'
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import yaml
|
||||
|
||||
config_path = Path(sys.argv[1])
|
||||
rtsp_url = sys.argv[2]
|
||||
output_dir = sys.argv[3]
|
||||
|
||||
raw = yaml.safe_load(config_path.read_text(encoding="utf-8")) or {}
|
||||
runtime = raw.setdefault("runtime", {})
|
||||
if rtsp_url:
|
||||
runtime["rtsp_url"] = rtsp_url
|
||||
runtime["output_dir"] = output_dir
|
||||
yolo = raw.setdefault("yolo", {})
|
||||
yolo.setdefault("model_path", "weights/yolo11n.pt")
|
||||
config_path.write_text(
|
||||
yaml.safe_dump(raw, allow_unicode=True, sort_keys=False),
|
||||
encoding="utf-8",
|
||||
)
|
||||
PY
|
||||
|
||||
exec python main.py --config "${CONFIG_PATH}" manage-api --host "${API_HOST}" --port "${API_PORT}"
|
||||
60
managed/people_flow_project/scripts/install.sh
Executable file
60
managed/people_flow_project/scripts/install.sh
Executable file
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
SETUP_SCRIPT="${PROJECT_DIR}/setup_native_venv.sh"
|
||||
RUN_SCRIPT="${PROJECT_DIR}/scripts/run.sh"
|
||||
INSTALL_SERVICE_SCRIPT="${PROJECT_DIR}/scripts/install_service.sh"
|
||||
PROJECT_USER="${SUDO_USER:-$(id -un)}"
|
||||
|
||||
run_privileged() {
|
||||
if [[ "$(id -u)" -eq 0 ]]; then
|
||||
"$@"
|
||||
return
|
||||
fi
|
||||
sudo "$@"
|
||||
}
|
||||
|
||||
run_project_user() {
|
||||
if [[ "$(id -u)" -eq 0 && -n "${SUDO_USER:-}" ]]; then
|
||||
sudo -u "${PROJECT_USER}" -H "$@"
|
||||
return
|
||||
fi
|
||||
"$@"
|
||||
}
|
||||
|
||||
ensure_system_package() {
|
||||
local command_name="$1"
|
||||
local package_name="$2"
|
||||
if command -v "${command_name}" >/dev/null 2>&1; then
|
||||
return
|
||||
fi
|
||||
|
||||
echo "Installing missing package: ${package_name}"
|
||||
run_privileged apt-get -o Acquire::ForceIPv4=true update
|
||||
run_privileged apt-get -o Acquire::ForceIPv4=true install -y "${package_name}"
|
||||
}
|
||||
|
||||
ensure_system_package ffmpeg ffmpeg
|
||||
|
||||
if [[ ! -d "/usr/lib/python3.12/venv" && ! -d "/usr/lib/python3.12/ensurepip" ]]; then
|
||||
echo "Installing missing package: python3.12-venv"
|
||||
run_privileged apt-get -o Acquire::ForceIPv4=true update
|
||||
run_privileged apt-get -o Acquire::ForceIPv4=true install -y python3.12-venv
|
||||
fi
|
||||
|
||||
if ! command -v nvidia-smi >/dev/null 2>&1; then
|
||||
echo "nvidia-smi is required but not installed." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
run_project_user env PYTHON_BIN="${PYTHON_BIN:-python3.12}" bash "${SETUP_SCRIPT}"
|
||||
run_project_user bash "${RUN_SCRIPT}" --prepare-only
|
||||
bash "${INSTALL_SERVICE_SCRIPT}"
|
||||
run_privileged systemctl enable --now people-flow.service
|
||||
|
||||
cat <<EOF
|
||||
Offline install complete.
|
||||
Service started and enabled on boot: people-flow.service
|
||||
Runtime log: ${PROJECT_DIR}/outputs/rtsp_run.log
|
||||
EOF
|
||||
33
managed/people_flow_project/scripts/install_service.sh
Executable file
33
managed/people_flow_project/scripts/install_service.sh
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
TEMPLATE_PATH="${PROJECT_DIR}/deploy/people-flow.service.tpl"
|
||||
CONFIG_PATH="${CONFIG_PATH:-${PROJECT_DIR}/config/local.yaml}"
|
||||
SERVICE_NAME="${SERVICE_NAME:-people-flow.service}"
|
||||
OUTPUT_PATH="${PROJECT_DIR}/deploy/${SERVICE_NAME}"
|
||||
RUN_USER="${RUN_USER:-${SUDO_USER:-$(id -un)}}"
|
||||
RUN_GROUP="${RUN_GROUP:-$(id -gn "${RUN_USER}")}"
|
||||
|
||||
if [[ ! -f "${TEMPLATE_PATH}" ]]; then
|
||||
echo "Missing service template: ${TEMPLATE_PATH}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "${CONFIG_PATH}" ]]; then
|
||||
echo "Missing config file: ${CONFIG_PATH}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sed \
|
||||
-e "s|__PROJECT_DIR__|${PROJECT_DIR}|g" \
|
||||
-e "s|__CONFIG_PATH__|${CONFIG_PATH}|g" \
|
||||
-e "s|__RUN_USER__|${RUN_USER}|g" \
|
||||
-e "s|__RUN_GROUP__|${RUN_GROUP}|g" \
|
||||
"${TEMPLATE_PATH}" > "${OUTPUT_PATH}"
|
||||
|
||||
sudo cp "${OUTPUT_PATH}" "/etc/systemd/system/${SERVICE_NAME}"
|
||||
sudo systemctl daemon-reload
|
||||
|
||||
echo "Service installed to /etc/systemd/system/${SERVICE_NAME}"
|
||||
echo "Enable and start it with: sudo systemctl enable --now ${SERVICE_NAME}"
|
||||
41
managed/people_flow_project/scripts/run.sh
Executable file
41
managed/people_flow_project/scripts/run.sh
Executable file
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
VENV_PYTHON="${PROJECT_DIR}/.venv/bin/python"
|
||||
CONFIG_TEMPLATE="${PROJECT_DIR}/config/config.example.yaml"
|
||||
CONFIG_PATH="${PROJECT_DIR}/config/local.yaml"
|
||||
RTSP_URL="${RTSP_URL:-rtsp://user:password@camera-ip:554/h264/ch1/main/av_stream}"
|
||||
OUTPUT_DIR="${OUTPUT_DIR:-${PROJECT_DIR}/outputs}"
|
||||
PREPARE_ONLY=0
|
||||
|
||||
if [[ "${1:-}" == "--prepare-only" ]]; then
|
||||
PREPARE_ONLY=1
|
||||
shift
|
||||
fi
|
||||
|
||||
if [[ ! -x "${VENV_PYTHON}" ]]; then
|
||||
echo "Virtual environment is missing. Run scripts/install.sh first." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${RTSP_URL}" == "rtsp://user:password@camera-ip:554/h264/ch1/main/av_stream" ]]; then
|
||||
echo "Please edit scripts/run.sh and set RTSP_URL before starting." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "${OUTPUT_DIR}" "${PROJECT_DIR}/config"
|
||||
|
||||
cp "${CONFIG_TEMPLATE}" "${CONFIG_PATH}"
|
||||
sed -i.bak \
|
||||
-e "s|^ rtsp_url: .*| rtsp_url: \"${RTSP_URL}\"|" \
|
||||
-e "s|^ output_dir: .*| output_dir: \"${OUTPUT_DIR}\"|" \
|
||||
"${CONFIG_PATH}"
|
||||
rm -f "${CONFIG_PATH}.bak"
|
||||
|
||||
if [[ "${PREPARE_ONLY}" -eq 1 ]]; then
|
||||
echo "Prepared config at ${CONFIG_PATH}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
exec "${VENV_PYTHON}" "${PROJECT_DIR}/main.py" --config "${CONFIG_PATH}" rtsp "$@"
|
||||
26
managed/people_flow_project/scripts/run_rtsp_docker.sh
Normal file
26
managed/people_flow_project/scripts/run_rtsp_docker.sh
Normal file
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
if [[ $# -lt 2 ]]; then
|
||||
echo "Usage: $0 <rtsp_url> <host_output_dir>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
RTSP_URL="$1"
|
||||
HOST_OUTPUT_DIR="$2"
|
||||
|
||||
mkdir -p "$HOST_OUTPUT_DIR"
|
||||
|
||||
docker run -d \
|
||||
--name people-flow-rtsp \
|
||||
--restart unless-stopped \
|
||||
--network host \
|
||||
--gpus all \
|
||||
--shm-size 1g \
|
||||
-v "$HOST_OUTPUT_DIR:/opt/people-flow/output" \
|
||||
people-flow-rtsp:x86-cuda \
|
||||
--config /opt/people-flow/configs/docker_x86_config.yaml \
|
||||
--output-dir /opt/people-flow/output \
|
||||
--device cuda:0 \
|
||||
rtsp \
|
||||
--input "$RTSP_URL"
|
||||
Reference in New Issue
Block a user