From dc6a8f9c629dca09f934a17b0a12b2ad4810a2ae Mon Sep 17 00:00:00 2001 From: CyberMind-FR Date: Wed, 4 Feb 2026 12:31:02 +0100 Subject: [PATCH] fix(streamlit): Auto-install requirements from ZIP uploads and support non-standard filenames The install_requirements() function only matched requirements.txt exactly, missing files like requirements_bazi.txt shipped in user ZIP uploads. Now falls back to any requirements*.txt file. RPCD upload handlers (upload_zip, upload_finalize) also trigger pip install inside the container at deploy time. Co-Authored-By: Claude Opus 4.5 --- .../root/usr/libexec/rpcd/luci.streamlit | 25 +++++++++++++++++++ .../files/usr/sbin/streamlitctl | 23 ++++++++++++----- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/package/secubox/luci-app-streamlit/root/usr/libexec/rpcd/luci.streamlit b/package/secubox/luci-app-streamlit/root/usr/libexec/rpcd/luci.streamlit index 34d38dd1..5967b1b3 100755 --- a/package/secubox/luci-app-streamlit/root/usr/libexec/rpcd/luci.streamlit +++ b/package/secubox/luci-app-streamlit/root/usr/libexec/rpcd/luci.streamlit @@ -622,6 +622,18 @@ upload_finalize() { local main_py main_py=$(find "$app_dir" -maxdepth 2 -name "*.py" -type f | head -1) if [ -n "$main_py" ]; then + # Install requirements if found (requirements.txt or requirements*.txt) + if lxc_running; then + local req_file="" + if [ -f "$app_dir/requirements.txt" ]; then + req_file="requirements.txt" + else + req_file=$(ls -1 "$app_dir"/requirements*.txt 2>/dev/null | head -1 | xargs basename 2>/dev/null) + fi + if [ -n "$req_file" ]; then + lxc-attach -n "$LXC_NAME" -- pip3 install --break-system-packages -r "/srv/apps/${name}/${req_file}" >/dev/null 2>&1 & + fi + fi uci set "${CONFIG}.${name}=app" uci set "${CONFIG}.${name}.name=$name" uci set "${CONFIG}.${name}.path=$main_py" @@ -932,6 +944,19 @@ upload_zip() { main_py=$(find "$app_dir" -maxdepth 2 -name "*.py" -type f | head -1) if [ -n "$main_py" ]; then + # Install requirements if found (requirements.txt or requirements*.txt) + if lxc_running; then + local req_file="" + if [ -f "$app_dir/requirements.txt" ]; then + req_file="requirements.txt" + else + req_file=$(ls -1 "$app_dir"/requirements*.txt 2>/dev/null | head -1 | xargs basename 2>/dev/null) + fi + if [ -n "$req_file" ]; then + lxc-attach -n "$LXC_NAME" -- pip3 install --break-system-packages -r "/srv/apps/${name}/${req_file}" >/dev/null 2>&1 & + fi + fi + # Register in UCI uci set "${CONFIG}.${name}=app" uci set "${CONFIG}.${name}.name=$name" diff --git a/package/secubox/secubox-app-streamlit/files/usr/sbin/streamlitctl b/package/secubox/secubox-app-streamlit/files/usr/sbin/streamlitctl index 49e5cb27..93938269 100644 --- a/package/secubox/secubox-app-streamlit/files/usr/sbin/streamlitctl +++ b/package/secubox/secubox-app-streamlit/files/usr/sbin/streamlitctl @@ -257,13 +257,20 @@ find_app_file() { install_requirements() { local app_dir="$1" local app_name=$(basename "$app_dir") - local req_file="$app_dir/requirements.txt" - if [ -f "$req_file" ]; then + # Find requirements file: requirements.txt first, then any requirements*.txt + local req_file="" + if [ -f "$app_dir/requirements.txt" ]; then + req_file="$app_dir/requirements.txt" + else + req_file=$(ls -1 "$app_dir"/requirements*.txt 2>/dev/null | head -1) + fi + + if [ -n "$req_file" ] && [ -f "$req_file" ]; then REQ_HASH=$(md5sum "$req_file" 2>/dev/null | cut -d' ' -f1) REQ_MARKER="/opt/.req_${app_name}_${REQ_HASH}" if [ ! -f "$REQ_MARKER" ]; then - echo "Installing requirements for $app_name..." + echo "Installing requirements from $(basename $req_file) for $app_name..." pip3 install --break-system-packages -r "$req_file" 2>/dev/null || \ pip3 install -r "$req_file" 2>/dev/null || true touch "$REQ_MARKER" @@ -505,9 +512,10 @@ cmd_app_list() { done [ -z "$main_file" ] && main_file=$(ls -1 "$app_dir"/*.py 2>/dev/null | head -1 | xargs basename 2>/dev/null) - # Check for requirements + # Check for requirements (requirements.txt or any requirements*.txt) local has_req="no" [ -f "$app_dir/requirements.txt" ] && has_req="yes" + [ "$has_req" = "no" ] && ls -1 "$app_dir"/requirements*.txt >/dev/null 2>&1 && has_req="yes" # Check for git repo local has_git="no" @@ -823,8 +831,11 @@ cmd_instance_start() { done [ -z \"\$APP_FILE\" ] && APP_FILE=\$(ls -1 *.py 2>/dev/null | head -1) - # Install requirements - [ -f requirements.txt ] && pip3 install --break-system-packages -r requirements.txt 2>/dev/null + # Install requirements (requirements.txt or any requirements*.txt) + REQ_FILE='' + [ -f requirements.txt ] && REQ_FILE='requirements.txt' + [ -z \"\$REQ_FILE\" ] && REQ_FILE=\$(ls -1 requirements*.txt 2>/dev/null | head -1) + [ -n \"\$REQ_FILE\" ] && pip3 install --break-system-packages -r \"\$REQ_FILE\" 2>/dev/null elif [ -f /srv/apps/${app}.py ]; then WORK_DIR='/srv/apps' APP_FILE='${app}.py'