secubox-openwrt/package/secubox/luci-app-rezapp/root/usr/libexec/rpcd/luci.rezapp
CyberMind-FR 66b58c74d6 feat(catalog): Add Streamlit Forge and RezApp Forge to KISS Apps
- luci-app-streamlit-forge: Streamlit app publishing platform
  - Category: productivity, runtime: lxc
  - Templates, SSL exposure, mesh publishing

- luci-app-rezapp: Docker to LXC app converter
  - Category: system, runtime: native
  - Catalog browsing, package generation

- Updated new_releases section
- Total plugins: 37 → 39

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-11 09:44:08 +01:00

266 lines
6.3 KiB
Bash

#!/bin/sh
# RPCD backend for RezApp Forge LuCI app
. /lib/functions.sh
. /usr/share/libubox/jshn.sh
APPS_DIR="/srv/rezapp/apps"
CACHE_DIR="/srv/rezapp/cache"
OUTPUT_DIR="/srv/rezapp/generated"
# Get status overview
get_status() {
local apps=0
local catalogs=0
local docker_status="unknown"
# Count converted apps
[ -d "$APPS_DIR" ] && apps=$(ls -1 "$APPS_DIR" 2>/dev/null | wc -l)
# Count enabled catalogs
config_load rezapp
config_foreach count_catalog catalog
catalogs=$_catalog_count
# Check Docker status
if pgrep dockerd >/dev/null 2>&1; then
docker_status="running"
else
docker_status="stopped"
fi
json_init
json_add_int "apps" "$apps"
json_add_int "catalogs" "$catalogs"
json_add_string "docker_status" "$docker_status"
json_dump
}
_catalog_count=0
count_catalog() {
local enabled
config_get enabled "$1" enabled '0'
[ "$enabled" = "1" ] && _catalog_count=$((_catalog_count + 1))
}
# Get enabled catalogs
get_catalogs() {
json_init
json_add_array "catalogs"
config_load rezapp
config_foreach add_catalog catalog
json_close_array
json_dump
}
add_catalog() {
local section="$1"
local name type url namespace enabled
config_get name "$section" name "$section"
config_get type "$section" type 'dockerhub'
config_get url "$section" url ''
config_get namespace "$section" namespace ''
config_get enabled "$section" enabled '0'
[ "$enabled" = "1" ] || return
json_add_object ""
json_add_string "id" "$section"
json_add_string "name" "$name"
json_add_string "type" "$type"
json_add_string "url" "$url"
json_add_string "namespace" "$namespace"
json_close_object
}
# Get converted apps
get_apps() {
json_init
json_add_array "apps"
[ -d "$APPS_DIR" ] || { json_close_array; json_dump; return; }
for app_dir in "$APPS_DIR"/*/; do
[ -d "$app_dir" ] || continue
local name=$(basename "$app_dir")
local source_image=""
local converted_at=""
if [ -f "$app_dir/metadata.json" ]; then
source_image=$(jsonfilter -i "$app_dir/metadata.json" -e '@.source_image' 2>/dev/null)
converted_at=$(jsonfilter -i "$app_dir/metadata.json" -e '@.converted_at' 2>/dev/null)
fi
# Check if package exists
local packaged="no"
[ -d "$OUTPUT_DIR/secubox-app-$name" ] && packaged="yes"
# Check if LXC container exists
local lxc_status="none"
if [ -d "/srv/lxc/$name" ]; then
if lxc-info -n "$name" 2>/dev/null | grep -q "RUNNING"; then
lxc_status="running"
else
lxc_status="stopped"
fi
fi
json_add_object ""
json_add_string "name" "$name"
json_add_string "source_image" "$source_image"
json_add_string "converted_at" "$converted_at"
json_add_string "packaged" "$packaged"
json_add_string "lxc_status" "$lxc_status"
json_close_object
done
json_close_array
json_dump
}
# Search Docker Hub
do_search() {
local query="$1"
[ -z "$query" ] && { echo '{"error":"Query required"}'; return; }
local output
output=$(rezappctl search "$query" 2>&1)
local rc=$?
# Parse output into JSON
json_init
json_add_int "code" "$rc"
json_add_array "results"
echo "$output" | grep -E "^\s+" | while read -r line; do
local image=$(echo "$line" | awk '{print $1}')
local stars=$(echo "$line" | awk '{print $2}' | tr -d '*')
local desc=$(echo "$line" | cut -d' ' -f3-)
[ -n "$image" ] || continue
json_add_object ""
json_add_string "image" "$image"
json_add_string "stars" "$stars"
json_add_string "description" "$desc"
json_close_object
done
json_close_array
json_dump
}
# Get image info
get_info() {
local image="$1"
[ -z "$image" ] && { echo '{"error":"Image required"}'; return; }
local output
output=$(rezappctl info "$image" 2>&1)
local rc=$?
# Extract tags
local tags=""
tags=$(echo "$output" | grep -A100 "Available Tags:" | grep "^\s*-" | sed 's/^\s*-\s*//' | head -10 | tr '\n' ',')
json_init
json_add_int "code" "$rc"
json_add_string "image" "$image"
json_add_string "tags" "$tags"
json_add_string "raw_output" "$output"
json_dump
}
# Convert Docker image
do_convert() {
local image="$1"
local name="$2"
local tag="$3"
local memory="$4"
[ -z "$image" ] && { echo '{"error":"Image required"}'; return; }
local cmd="rezappctl convert $image"
[ -n "$name" ] && cmd="$cmd --name $name"
[ -n "$tag" ] && cmd="$cmd --tag $tag"
[ -n "$memory" ] && cmd="$cmd --memory $memory"
local output
output=$(eval "$cmd" 2>&1)
local rc=$?
json_init
json_add_int "code" "$rc"
json_add_string "output" "$output"
json_dump
}
# Generate package
do_package() {
local name="$1"
[ -z "$name" ] && { echo '{"error":"App name required"}'; return; }
local output
output=$(rezappctl package "$name" 2>&1)
local rc=$?
json_init
json_add_int "code" "$rc"
json_add_string "output" "$output"
json_dump
}
# Publish to catalog
do_publish() {
local name="$1"
[ -z "$name" ] && { echo '{"error":"App name required"}'; return; }
local output
output=$(rezappctl publish "$name" 2>&1)
local rc=$?
json_init
json_add_int "code" "$rc"
json_add_string "output" "$output"
json_dump
}
# Delete converted app
do_delete() {
local name="$1"
[ -z "$name" ] && { echo '{"error":"App name required"}'; return; }
# Remove app directory
rm -rf "$APPS_DIR/$name"
rm -rf "$OUTPUT_DIR/secubox-app-$name"
rm -rf "$OUTPUT_DIR/luci-app-$name"
json_init
json_add_int "code" 0
json_add_string "message" "Deleted $name"
json_dump
}
case "$1" in
list)
echo '{"status":{},"catalogs":{},"apps":{},"search":{"query":"String"},"info":{"image":"String"},"convert":{"image":"String","name":"String","tag":"String","memory":"String"},"package":{"name":"String"},"publish":{"name":"String"},"delete":{"name":"String"}}'
;;
call)
case "$2" in
status) get_status ;;
catalogs) get_catalogs ;;
apps) get_apps ;;
search) read input; json_load "$input"; json_get_var query query; do_search "$query" ;;
info) read input; json_load "$input"; json_get_var image image; get_info "$image" ;;
convert) read input; json_load "$input"; json_get_var image image; json_get_var name name; json_get_var tag tag; json_get_var memory memory; do_convert "$image" "$name" "$tag" "$memory" ;;
package) read input; json_load "$input"; json_get_var name name; do_package "$name" ;;
publish) read input; json_load "$input"; json_get_var name name; do_publish "$name" ;;
delete) read input; json_load "$input"; json_get_var name name; do_delete "$name" ;;
esac
;;
esac