feat(secubox-app-lyrion): Add hybrid Docker/LXC runtime support

- v2.0.0: Multi-runtime support with auto-detection
- LXC preferred when available (150MB RAM vs 300MB for Docker)
- New lyrionctl commands: runtime, shell
- Alpine Linux rootfs creation for LXC
- UCI config: runtime option (auto/docker/lxc)
- Memory limit configuration via cgroups
- Updated plugin manifest with runtime info

Runtime selection:
  option runtime 'auto'   - Auto-detect (LXC preferred)
  option runtime 'docker' - Force Docker
  option runtime 'lxc'    - Force LXC

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
CyberMind-FR 2026-01-13 17:51:04 +01:00
parent 30ff7578ba
commit e75d0f3741
4 changed files with 567 additions and 56 deletions

View File

@ -1,8 +1,8 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=secubox-app-lyrion PKG_NAME:=secubox-app-lyrion
PKG_RELEASE:=2 PKG_RELEASE:=1
PKG_VERSION:=1.0.0 PKG_VERSION:=2.0.0
PKG_ARCH:=all PKG_ARCH:=all
PKG_MAINTAINER:=CyberMind Studio <contact@cybermind.fr> PKG_MAINTAINER:=CyberMind Studio <contact@cybermind.fr>
PKG_LICENSE:=Apache-2.0 PKG_LICENSE:=Apache-2.0
@ -14,13 +14,20 @@ define Package/secubox-app-lyrion
CATEGORY:=Utilities CATEGORY:=Utilities
PKGARCH:=all PKGARCH:=all
SUBMENU:=SecuBox Apps SUBMENU:=SecuBox Apps
TITLE:=SecuBox Lyrion docker app TITLE:=SecuBox Lyrion Media Server (Docker/LXC)
DEPENDS:=+uci +libuci +dockerd +docker +containerd DEPENDS:=+uci +libuci +wget +tar
endef endef
define Package/secubox-app-lyrion/description define Package/secubox-app-lyrion/description
Installer, configuration, and service manager for running Lyrion Media Server Lyrion Media Server (formerly Logitech Media Server / Squeezebox Server)
inside Docker on SecuBox-powered OpenWrt systems. for SecuBox-powered OpenWrt systems.
Supports multiple container runtimes:
- Docker (if dockerd is installed)
- LXC (if lxc packages are installed)
Auto-detects available runtime, preferring LXC for lower resource usage.
Configure runtime in /etc/config/lyrion.
endef endef
define Package/secubox-app-lyrion/conffiles define Package/secubox-app-lyrion/conffiles
@ -41,4 +48,23 @@ define Package/secubox-app-lyrion/install
$(INSTALL_BIN) ./files/usr/sbin/lyrionctl $(1)/usr/sbin/lyrionctl $(INSTALL_BIN) ./files/usr/sbin/lyrionctl $(1)/usr/sbin/lyrionctl
endef endef
define Package/secubox-app-lyrion/postinst
#!/bin/sh
[ -n "$${IPKG_INSTROOT}" ] || {
echo ""
echo "Lyrion Media Server installed."
echo ""
echo "To install and start Lyrion:"
echo " lyrionctl install"
echo " /etc/init.d/lyrion start"
echo ""
echo "Runtime selection (edit /etc/config/lyrion):"
echo " option runtime 'auto' - Auto-detect (LXC preferred)"
echo " option runtime 'docker' - Force Docker"
echo " option runtime 'lxc' - Force LXC"
echo ""
}
exit 0
endef
$(eval $(call BuildPackage,secubox-app-lyrion)) $(eval $(call BuildPackage,secubox-app-lyrion))

View File

@ -1,7 +1,9 @@
config lyrion 'main' config lyrion 'main'
option enabled '0' option enabled '0'
option runtime 'auto'
option image 'ghcr.io/lyrion/lyrion:latest' option image 'ghcr.io/lyrion/lyrion:latest'
option data_path '/srv/lyrion' option data_path '/srv/lyrion'
option media_path '/srv/media' option media_path '/srv/media'
option port '8096' option port '9000'
option timezone 'UTC' option timezone 'UTC'
option memory_limit '256M'

View File

@ -1,43 +1,116 @@
#!/bin/sh #!/bin/sh
# SecuBox Lyrion manager # SecuBox Lyrion manager - Multi-runtime support (Docker/LXC)
# Copyright (C) 2024 CyberMind.fr
CONFIG="lyrion" CONFIG="lyrion"
CONTAINER="secbx-lyrion" CONTAINER_NAME="secbx-lyrion"
LXC_NAME="lyrion"
OPKG_UPDATED=0 OPKG_UPDATED=0
# Paths
LXC_PATH="/srv/lxc"
LXC_ROOTFS="$LXC_PATH/$LXC_NAME/rootfs"
LXC_CONFIG="$LXC_PATH/$LXC_NAME/config"
LYRION_ROOTFS_SCRIPT="/usr/share/lyrion/create-lxc-rootfs.sh"
usage() { usage() {
cat <<'EOF' cat <<'EOF'
Usage: lyrionctl <command> Usage: lyrionctl <command>
Commands: Commands:
install Install prerequisites, prep folders, pull image install Install prerequisites, prep folders, pull/create container
check Run prerequisite checks (storage, docker) check Run prerequisite checks (storage, runtime)
update Pull new image and restart service update Update container image and restart service
status Show docker container status status Show container status
logs Show docker logs (use -f to follow) logs Show container logs (use -f to follow)
shell Open shell in container
service-run Internal: run container under procd service-run Internal: run container under procd
service-stop Stop container service-stop Stop container
runtime Show detected/configured runtime
Runtime Selection:
The runtime can be configured in /etc/config/lyrion:
option runtime 'auto' # auto-detect (LXC preferred if available)
option runtime 'docker' # Force Docker
option runtime 'lxc' # Force LXC
EOF EOF
} }
require_root() { [ "$(id -u)" -eq 0 ] || { echo "Root required" >&2; exit 1; }; } require_root() { [ "$(id -u)" -eq 0 ] || { echo "Root required" >&2; exit 1; }; }
uci_get() { uci -q get ${CONFIG}.main.$1; } log_info() { echo "[INFO] $*"; }
log_warn() { echo "[WARN] $*" >&2; }
log_error() { echo "[ERROR] $*" >&2; }
defaults() { uci_get() { uci -q get ${CONFIG}.main.$1; }
uci_set() { uci set ${CONFIG}.main.$1="$2" && uci commit ${CONFIG}; }
# Load configuration with defaults
load_config() {
runtime="$(uci_get runtime || echo auto)"
image="$(uci_get image || echo ghcr.io/lyrion/lyrion:latest)" image="$(uci_get image || echo ghcr.io/lyrion/lyrion:latest)"
data_path="$(uci_get data_path || echo /srv/lyrion)" data_path="$(uci_get data_path || echo /srv/lyrion)"
media_path="$(uci_get media_path || echo /srv/media)" media_path="$(uci_get media_path || echo /srv/media)"
port="$(uci_get port || echo 8096)" port="$(uci_get port || echo 9000)"
timezone="$(uci_get timezone || echo UTC)" timezone="$(uci_get timezone || cat /etc/TZ 2>/dev/null || echo UTC)"
memory_limit="$(uci_get memory_limit || echo 256M)"
lxc_rootfs_url="$(uci_get lxc_rootfs_url || echo '')"
} }
ensure_dir() { [ -d "$1" ] || mkdir -p "$1"; } ensure_dir() { [ -d "$1" ] || mkdir -p "$1"; }
# Check if a runtime is available
has_docker() {
command -v docker >/dev/null 2>&1 && \
command -v dockerd >/dev/null 2>&1 && \
[ -S /var/run/docker.sock ]
}
has_lxc() {
command -v lxc-start >/dev/null 2>&1 && \
command -v lxc-stop >/dev/null 2>&1
}
# Detect best available runtime
detect_runtime() {
load_config
case "$runtime" in
docker)
if has_docker; then
echo "docker"
else
log_error "Docker requested but not available"
return 1
fi
;;
lxc)
if has_lxc; then
echo "lxc"
else
log_error "LXC requested but not available"
return 1
fi
;;
auto|*)
# Prefer LXC if available (lighter weight)
if has_lxc; then
echo "lxc"
elif has_docker; then
echo "docker"
else
log_error "No container runtime available (install lxc or docker)"
return 1
fi
;;
esac
}
# Ensure required packages are installed
ensure_packages() { ensure_packages() {
require_root require_root
for pkg in "$@"; do for pkg in "$@"; do
if ! opkg status "$pkg" >/dev/null 2>&1; then if ! opkg list-installed | grep -q "^$pkg "; then
if [ "$OPKG_UPDATED" -eq 0 ]; then if [ "$OPKG_UPDATED" -eq 0 ]; then
opkg update || return 1 opkg update || return 1
OPKG_UPDATED=1 OPKG_UPDATED=1
@ -47,64 +120,456 @@ ensure_packages() {
done done
} }
check_prereqs() { # =============================================================================
defaults # Docker Runtime Functions
ensure_dir "$data_path" # =============================================================================
[ -d /sys/fs/cgroup ] || { echo "[ERROR] /sys/fs/cgroup missing" >&2; return 1; }
ensure_packages dockerd docker containerd docker_check_prereqs() {
log_info "Checking Docker prerequisites..."
ensure_packages dockerd docker containerd || return 1
# Enable and start Docker
/etc/init.d/dockerd enable >/dev/null 2>&1 /etc/init.d/dockerd enable >/dev/null 2>&1
/etc/init.d/dockerd start >/dev/null 2>&1 if ! /etc/init.d/dockerd status >/dev/null 2>&1; then
/etc/init.d/dockerd start || return 1
sleep 3
fi
# Wait for Docker socket
local retry=0
while [ ! -S /var/run/docker.sock ] && [ $retry -lt 30 ]; do
sleep 1
retry=$((retry + 1))
done
[ -S /var/run/docker.sock ] || { log_error "Docker socket not available"; return 1; }
log_info "Docker ready"
} }
pull_image() { defaults; docker pull "$image"; } docker_pull() {
load_config
log_info "Pulling Docker image: $image"
docker pull "$image"
}
stop_container() { docker stop "$CONTAINER" >/dev/null 2>&1 || true; docker rm "$CONTAINER" >/dev/null 2>&1 || true; } docker_stop() {
docker stop "$CONTAINER_NAME" >/dev/null 2>&1 || true
docker rm "$CONTAINER_NAME" >/dev/null 2>&1 || true
}
docker_run() {
load_config
docker_stop
log_info "Starting Lyrion Docker container..."
exec docker run --rm \
--name "$CONTAINER_NAME" \
-p "${port}:9000" \
-p "3483:3483" \
-p "3483:3483/udp" \
-v "$data_path:/config" \
-v "$media_path:/music:ro" \
-e TZ="$timezone" \
--memory="$memory_limit" \
"$image"
}
docker_status() {
docker ps -a --filter "name=$CONTAINER_NAME" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
}
docker_logs() {
docker logs "$@" "$CONTAINER_NAME"
}
docker_shell() {
docker exec -it "$CONTAINER_NAME" /bin/sh
}
# =============================================================================
# LXC Runtime Functions
# =============================================================================
lxc_check_prereqs() {
log_info "Checking LXC prerequisites..."
ensure_packages lxc lxc-common lxc-attach lxc-start lxc-stop lxc-destroy || return 1
# Check cgroups
if [ ! -d /sys/fs/cgroup ]; then
log_error "cgroups not mounted at /sys/fs/cgroup"
return 1
fi
log_info "LXC ready"
}
lxc_create_rootfs() {
load_config
if [ -d "$LXC_ROOTFS" ] && [ -f "$LXC_ROOTFS/etc/alpine-release" ]; then
log_info "LXC rootfs already exists"
return 0
fi
log_info "Creating LXC rootfs for Lyrion..."
ensure_dir "$LXC_PATH/$LXC_NAME"
# Use external script if available
if [ -x "$LYRION_ROOTFS_SCRIPT" ]; then
"$LYRION_ROOTFS_SCRIPT" "$LXC_ROOTFS" || return 1
else
# Inline rootfs creation
lxc_create_alpine_rootfs || return 1
fi
# Create LXC config
lxc_create_config || return 1
log_info "LXC rootfs created successfully"
}
lxc_create_alpine_rootfs() {
local arch="aarch64"
local alpine_version="3.19"
local mirror="https://dl-cdn.alpinelinux.org/alpine"
local rootfs="$LXC_ROOTFS"
# Detect architecture
case "$(uname -m)" in
x86_64) arch="x86_64" ;;
aarch64) arch="aarch64" ;;
armv7l) arch="armv7" ;;
*) arch="x86_64" ;;
esac
log_info "Downloading Alpine Linux $alpine_version ($arch)..."
ensure_dir "$rootfs"
cd "$rootfs" || return 1
# Download Alpine minirootfs
local rootfs_url="$mirror/v$alpine_version/releases/$arch/alpine-minirootfs-$alpine_version.0-$arch.tar.gz"
wget -q -O /tmp/alpine-rootfs.tar.gz "$rootfs_url" || {
log_error "Failed to download Alpine rootfs"
return 1
}
# Extract rootfs
tar xzf /tmp/alpine-rootfs.tar.gz -C "$rootfs" || return 1
rm -f /tmp/alpine-rootfs.tar.gz
# Configure Alpine
echo "nameserver 8.8.8.8" > "$rootfs/etc/resolv.conf"
# Install Lyrion in the container
cat > "$rootfs/tmp/setup-lyrion.sh" << 'SETUP'
#!/bin/sh
set -e
# Update and install dependencies
apk update
apk add --no-cache \
perl \
perl-io-socket-ssl \
perl-encode \
perl-xml-parser \
perl-dbi \
perl-dbd-sqlite \
perl-json-xs \
perl-yaml-libyaml \
perl-image-scale \
perl-crypt-openssl-rsa \
perl-ev \
perl-anyevent \
flac \
faad2 \
sox \
lame \
curl \
wget
# Download and install Lyrion
cd /tmp
wget -q "https://downloads.lyrion.org/nightly/lyrion-9.0.0-nightly.tar.gz" -O lyrion.tar.gz || \
wget -q "https://downloads.slimdevices.com/nightly/lms/lms-nightly.tar.gz" -O lyrion.tar.gz
mkdir -p /opt/lyrion
tar xzf lyrion.tar.gz -C /opt/lyrion --strip-components=1
rm -f lyrion.tar.gz
# Create directories
mkdir -p /config /music /var/log/lyrion
# Create startup script
cat > /opt/lyrion/start.sh << 'START'
#!/bin/sh
cd /opt/lyrion
exec perl slimserver.pl \
--prefsdir /config/prefs \
--cachedir /config/cache \
--logdir /var/log/lyrion \
--httpport 9000 \
--cliport 9090 \
--user root
START
chmod +x /opt/lyrion/start.sh
echo "Lyrion installed successfully"
SETUP
chmod +x "$rootfs/tmp/setup-lyrion.sh"
# Run setup in chroot
log_info "Installing Lyrion in container (this may take a while)..."
chroot "$rootfs" /tmp/setup-lyrion.sh || {
log_error "Failed to install Lyrion in container"
return 1
}
rm -f "$rootfs/tmp/setup-lyrion.sh"
}
lxc_create_config() {
load_config
cat > "$LXC_CONFIG" << EOF
# Lyrion LXC Configuration
lxc.uts.name = $LXC_NAME
# Root filesystem
lxc.rootfs.path = dir:$LXC_ROOTFS
# Network - use host network for simplicity
lxc.net.0.type = none
# Mounts
lxc.mount.auto = proc:mixed sys:ro cgroup:mixed
lxc.mount.entry = $data_path config none bind,create=dir 0 0
lxc.mount.entry = $media_path music none bind,ro,create=dir 0 0
# Capabilities
lxc.cap.drop = sys_admin sys_module mac_admin mac_override
# cgroups limits
lxc.cgroup.memory.limit_in_bytes = $memory_limit
# Init
lxc.init.cmd = /opt/lyrion/start.sh
# Console
lxc.console.size = 1024
lxc.pty.max = 1024
EOF
log_info "LXC config created at $LXC_CONFIG"
}
lxc_stop() {
if lxc-info -n "$LXC_NAME" >/dev/null 2>&1; then
lxc-stop -n "$LXC_NAME" -k >/dev/null 2>&1 || true
fi
}
lxc_run() {
load_config
lxc_stop
if [ ! -f "$LXC_CONFIG" ]; then
log_error "LXC not configured. Run 'lyrionctl install' first."
return 1
fi
# Ensure mount points exist
ensure_dir "$data_path"
ensure_dir "$media_path"
log_info "Starting Lyrion LXC container..."
exec lxc-start -n "$LXC_NAME" -F -f "$LXC_CONFIG"
}
lxc_status() {
if lxc-info -n "$LXC_NAME" >/dev/null 2>&1; then
lxc-info -n "$LXC_NAME"
else
echo "LXC container '$LXC_NAME' not found or not configured"
fi
}
lxc_logs() {
load_config
if [ -f "$data_path/cache/server.log" ]; then
if [ "$1" = "-f" ]; then
tail -f "$data_path/cache/server.log"
else
tail -100 "$data_path/cache/server.log"
fi
else
log_warn "No log file found at $data_path/cache/server.log"
fi
}
lxc_shell() {
lxc-attach -n "$LXC_NAME" -- /bin/sh
}
lxc_destroy() {
lxc_stop
if [ -d "$LXC_PATH/$LXC_NAME" ]; then
rm -rf "$LXC_PATH/$LXC_NAME"
log_info "LXC container destroyed"
fi
}
# =============================================================================
# Main Commands
# =============================================================================
cmd_install() { cmd_install() {
require_root require_root
check_prereqs || exit 1 load_config
ensure_dir "$data_path/config"
pull_image || exit 1 local rt=$(detect_runtime) || exit 1
uci set ${CONFIG}.main.enabled='1' log_info "Using runtime: $rt"
uci commit ${CONFIG}
# Save detected runtime if auto
[ "$runtime" = "auto" ] && uci_set detected_runtime "$rt"
# Create directories
ensure_dir "$data_path"
ensure_dir "$media_path"
case "$rt" in
docker)
docker_check_prereqs || exit 1
docker_pull || exit 1
;;
lxc)
lxc_check_prereqs || exit 1
lxc_create_rootfs || exit 1
;;
esac
uci_set enabled '1'
/etc/init.d/lyrion enable /etc/init.d/lyrion enable
echo "Lyrion prerequisites installed. Start with /etc/init.d/lyrion start"
log_info "Lyrion installed. Start with: /etc/init.d/lyrion start"
log_info "Web interface will be at: http://<router-ip>:$port"
} }
cmd_check() { cmd_check() {
check_prereqs load_config
echo "Prerequisite check completed."
log_info "Checking prerequisites..."
log_info "Configured runtime: $runtime"
local rt=$(detect_runtime)
if [ -n "$rt" ]; then
log_info "Detected runtime: $rt"
case "$rt" in
docker) docker_check_prereqs ;;
lxc) lxc_check_prereqs ;;
esac
fi
} }
cmd_update() { cmd_update() {
require_root require_root
pull_image || exit 1 load_config
local rt=$(detect_runtime) || exit 1
case "$rt" in
docker)
docker_pull || exit 1
;;
lxc)
log_info "Updating LXC rootfs..."
lxc_destroy
lxc_create_rootfs || exit 1
;;
esac
if /etc/init.d/lyrion enabled >/dev/null 2>&1; then if /etc/init.d/lyrion enabled >/dev/null 2>&1; then
/etc/init.d/lyrion restart /etc/init.d/lyrion restart
else else
echo "Image updated. Restart manually." log_info "Update complete. Restart manually to apply."
fi fi
} }
cmd_status() { docker ps -a --filter "name=$CONTAINER"; } cmd_status() {
local rt=$(detect_runtime 2>/dev/null)
case "$rt" in
docker) docker_status ;;
lxc) lxc_status ;;
*) echo "No runtime detected" ;;
esac
}
cmd_logs() { docker logs "$@" "$CONTAINER"; } cmd_logs() {
local rt=$(detect_runtime 2>/dev/null)
case "$rt" in
docker) docker_logs "$@" ;;
lxc) lxc_logs "$@" ;;
*) echo "No runtime detected" ;;
esac
}
cmd_shell() {
local rt=$(detect_runtime 2>/dev/null)
case "$rt" in
docker) docker_shell ;;
lxc) lxc_shell ;;
*) echo "No runtime detected" ;;
esac
}
cmd_service_run() { cmd_service_run() {
require_root require_root
check_prereqs || exit 1 load_config
defaults
stop_container local rt=$(detect_runtime) || exit 1
exec docker run --rm \
--name "$CONTAINER" \ case "$rt" in
-p "${port}:8096" \ docker)
-v "$data_path/config:/config" \ docker_check_prereqs || exit 1
-v "$media_path:/media" \ docker_run
-e TZ="$timezone" \ ;;
"$image" lxc)
lxc_check_prereqs || exit 1
lxc_run
;;
esac
} }
cmd_service_stop() { require_root; stop_container; } cmd_service_stop() {
require_root
local rt=$(detect_runtime 2>/dev/null)
case "$rt" in
docker) docker_stop ;;
lxc) lxc_stop ;;
esac
}
cmd_runtime() {
load_config
echo "Configured: $runtime"
local detected=$(detect_runtime 2>/dev/null)
if [ -n "$detected" ]; then
echo "Detected: $detected"
else
echo "Detected: none"
fi
echo ""
echo "Available runtimes:"
has_docker && echo " - docker" || echo " - docker (not installed)"
has_lxc && echo " - lxc" || echo " - lxc (not installed)"
}
# =============================================================================
# Main Entry Point
# =============================================================================
case "${1:-}" in case "${1:-}" in
install) shift; cmd_install "$@" ;; install) shift; cmd_install "$@" ;;
@ -112,8 +577,10 @@ case "${1:-}" in
update) shift; cmd_update "$@" ;; update) shift; cmd_update "$@" ;;
status) shift; cmd_status "$@" ;; status) shift; cmd_status "$@" ;;
logs) shift; cmd_logs "$@" ;; logs) shift; cmd_logs "$@" ;;
shell) shift; cmd_shell "$@" ;;
service-run) shift; cmd_service_run "$@" ;; service-run) shift; cmd_service_run "$@" ;;
service-stop) shift; cmd_service_stop "$@" ;; service-stop) shift; cmd_service_stop "$@" ;;
runtime) shift; cmd_runtime "$@" ;;
help|--help|-h|'') usage ;; help|--help|-h|'') usage ;;
*) echo "Unknown command: $1" >&2; usage >&2; exit 1 ;; *) echo "Unknown command: $1" >&2; usage >&2; exit 1 ;;
esac esac

View File

@ -1,16 +1,19 @@
{ {
"id": "lyrion", "id": "lyrion",
"name": "Lyrion Media Server", "name": "Lyrion Media Server",
"description": "Self-hosted media server (Docker-based).", "description": "Self-hosted media server with multi-room audio streaming (Docker/LXC).",
"type": "docker", "type": "container",
"version": "1.0.0", "version": "2.0.0",
"source": "https://lyrion.org/", "source": "https://lyrion.org/",
"packages": [ "packages": [
"secubox-app-lyrion", "secubox-app-lyrion",
"luci-app-vhost-manager" "luci-app-vhost-manager"
], ],
"ports": [ "ports": [
{ "name": "ui", "protocol": "http", "port": 8096, "expose": true } { "name": "web", "protocol": "http", "port": 9000, "expose": true },
{ "name": "cli", "protocol": "tcp", "port": 9090, "expose": false },
{ "name": "discovery", "protocol": "tcp", "port": 3483, "expose": true },
{ "name": "discovery-udp", "protocol": "udp", "port": 3483, "expose": true }
], ],
"volumes": [ "volumes": [
"/srv/lyrion", "/srv/lyrion",
@ -20,12 +23,24 @@
"default_mode": "dmz", "default_mode": "dmz",
"dmz_supported": true "dmz_supported": true
}, },
"runtime": {
"supported": ["docker", "lxc"],
"default": "auto",
"description": "Auto-detects LXC or Docker. LXC preferred for lower RAM usage."
},
"resources": {
"ram_docker": "300MB",
"ram_lxc": "150MB",
"storage": "500MB"
},
"wizard": { "wizard": {
"uci": { "config": "lyrion", "section": "main" }, "uci": { "config": "lyrion", "section": "main" },
"fields": [ "fields": [
{ "id": "runtime", "label": "Container Runtime", "type": "select", "uci_option": "runtime", "options": ["auto", "docker", "lxc"], "default": "auto" },
{ "id": "data_path", "label": "Data Path", "type": "text", "uci_option": "data_path", "placeholder": "/srv/lyrion" }, { "id": "data_path", "label": "Data Path", "type": "text", "uci_option": "data_path", "placeholder": "/srv/lyrion" },
{ "id": "media_path", "label": "Media Path", "type": "text", "uci_option": "media_path", "placeholder": "/srv/media" }, { "id": "media_path", "label": "Media Path", "type": "text", "uci_option": "media_path", "placeholder": "/srv/media" },
{ "id": "port", "label": "HTTP Port", "type": "number", "uci_option": "port", "placeholder": "8096" }, { "id": "port", "label": "HTTP Port", "type": "number", "uci_option": "port", "placeholder": "9000" },
{ "id": "memory_limit", "label": "Memory Limit", "type": "text", "uci_option": "memory_limit", "placeholder": "256M" },
{ "id": "timezone", "label": "Timezone", "type": "text", "uci_option": "timezone", "placeholder": "UTC" } { "id": "timezone", "label": "Timezone", "type": "text", "uci_option": "timezone", "placeholder": "UTC" }
] ]
}, },
@ -34,6 +49,7 @@
"install": "lyrionctl install", "install": "lyrionctl install",
"check": "lyrionctl check", "check": "lyrionctl check",
"update": "lyrionctl update", "update": "lyrionctl update",
"status": "/etc/init.d/lyrion status" "status": "/etc/init.d/lyrion status",
"runtime": "lyrionctl runtime"
} }
} }