From c801aef709630ad4024760cb987a9672bfdbc2ce Mon Sep 17 00:00:00 2001 From: xiexiaobao Date: Wed, 24 Jun 2026 14:54:44 +0800 Subject: [PATCH] feat: add custom packages - frpc-config: pre-configure frpc tunnels (SSH/Jellyfin/Navidrome) - navidrome-autoinit: auto-create Navidrome container on first boot - expand-overlay: auto-resize eMMC overlay partition --- package/diy/expand-overlay/Makefile | 45 ++++++++++++ .../expand-overlay/files/expand-overlay.init | 25 +++++++ .../expand-overlay/files/expand-overlay.sh | 19 +++++ package/diy/frpc-config/Makefile | 42 +++++++++++ package/diy/frpc-config/files/frpc | 32 +++++++++ package/diy/navidrome-autoinit/Makefile | 42 +++++++++++ .../navidrome-autoinit/files/navidrome.init | 70 +++++++++++++++++++ 7 files changed, 275 insertions(+) create mode 100644 package/diy/expand-overlay/Makefile create mode 100644 package/diy/expand-overlay/files/expand-overlay.init create mode 100644 package/diy/expand-overlay/files/expand-overlay.sh create mode 100644 package/diy/frpc-config/Makefile create mode 100644 package/diy/frpc-config/files/frpc create mode 100644 package/diy/navidrome-autoinit/Makefile create mode 100644 package/diy/navidrome-autoinit/files/navidrome.init diff --git a/package/diy/expand-overlay/Makefile b/package/diy/expand-overlay/Makefile new file mode 100644 index 0000000000..77abc3862d --- /dev/null +++ b/package/diy/expand-overlay/Makefile @@ -0,0 +1,45 @@ +# +# Copyright (C) 2026 xiexiaobao +# +# This is free software, licensed under the GPL 2.0 license. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=expand-overlay +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=xiexiaobao +PKG_LICENSE:=GPL-2.0 + +include $(INCLUDE_DIR)/package.mk + +define Package/expand-overlay + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Auto-expand overlay partition on first boot + DEPENDS:=+sfdisk +e2fsprogs + PKGARCH:=all +endef + +define Package/expand-overlay/description + Auto-resize the NanoPi R6C eMMC overlay partition (mmcblk2p3) + to fill all remaining unallocated space on first boot. + Two-stage: uci-defaults resizes partition table, init.d resizes filesystem. +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/expand-overlay/install + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/expand-overlay.sh $(1)/etc/uci-defaults/99-expand-overlay + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/expand-overlay.init $(1)/etc/init.d/expand-overlay +endef + +$(eval $(call BuildPackage,expand-overlay)) diff --git a/package/diy/expand-overlay/files/expand-overlay.init b/package/diy/expand-overlay/files/expand-overlay.init new file mode 100644 index 0000000000..8effac28e2 --- /dev/null +++ b/package/diy/expand-overlay/files/expand-overlay.init @@ -0,0 +1,25 @@ +#!/bin/sh /etc/rc.common +# /etc/init.d/expand-overlay +# Stage 2: Resize filesystem to match expanded partition. +# Runs at START=99, after overlay is mounted and most services started. + +START=99 + +boot() { + local flag="/etc/resize2fs.done" + [ -f "$flag" ] && return 0 + + # Wait for stage1 to finish (uci-defaults running before us) + local i=0 + while [ ! -f "/etc/expand-overlay.done" ] && [ $i -lt 30 ]; do + sleep 1 + i=$((i + 1)) + done + + [ ! -f "/etc/expand-overlay.done" ] && return 0 + + # Resize filesystem + resize2fs /dev/mmcblk2p3 2>/dev/null + touch "$flag" + return 0 +} diff --git a/package/diy/expand-overlay/files/expand-overlay.sh b/package/diy/expand-overlay/files/expand-overlay.sh new file mode 100644 index 0000000000..b64d4f3e49 --- /dev/null +++ b/package/diy/expand-overlay/files/expand-overlay.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# /etc/uci-defaults/99-expand-overlay +# Stage 1: Resize partition table to fill unallocated eMMC space. +# Auto-removed by uci-defaults after first run. + +FLAG_FILE="/etc/expand-overlay.done" + +[ -f "$FLAG_FILE" ] && exit 0 + +# Only run if root is on eMMC +ROOT_DEV=$(mount | grep ' / ' | awk '{print $1}' | sed 's/p[0-9]*$//') +[ "$ROOT_DEV" != "/dev/mmcblk2" ] && exit 0 + +# Save backup, resize partition 3 to fill remaining space +sfdisk -d /dev/mmcblk2 > /etc/sfdisk.bak 2>/dev/null +echo ",+" | sfdisk -N 3 /dev/mmcblk2 2>/dev/null + +touch "$FLAG_FILE" +exit 0 diff --git a/package/diy/frpc-config/Makefile b/package/diy/frpc-config/Makefile new file mode 100644 index 0000000000..0008e868a8 --- /dev/null +++ b/package/diy/frpc-config/Makefile @@ -0,0 +1,42 @@ +# +# Copyright (C) 2026 xiexiaobao +# +# This is free software, licensed under the GPL 2.0 license. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=frpc-config +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=xiexiaobao +PKG_LICENSE:=GPL-2.0 + +include $(INCLUDE_DIR)/package.mk + +define Package/frpc-config + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Pre-configured frpc tunnels (SSH + Jellyfin + Navidrome) + DEPENDS:=+frpc + PKGARCH:=all +endef + +define Package/frpc-config/description + Pre-configure frpc tunnels for VPS 43.134.64.107:7000. + Tunnels: SSH(:2222), Jellyfin(:8096), Navidrome(:4533). +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/frpc-config/install + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_DATA) ./files/frpc $(1)/etc/config/frpc +endef + +$(eval $(call BuildPackage,frpc-config)) diff --git a/package/diy/frpc-config/files/frpc b/package/diy/frpc-config/files/frpc new file mode 100644 index 0000000000..8c859aa98d --- /dev/null +++ b/package/diy/frpc-config/files/frpc @@ -0,0 +1,32 @@ +config init + option stdout '1' + option stderr '1' + option user 'frpc' + option group 'frpc' + option respawn '1' + +config conf 'common' + option server_addr '43.134.64.107' + option server_port '7000' + option token '@@xiefeng' + +config conf 'ssh' + option type 'tcp' + option local_ip '127.0.0.1' + option local_port '22' + option remote_port '2222' + option name 'ssh' + +config conf 'jellyfin' + option type 'tcp' + option local_ip '127.0.0.1' + option local_port '8096' + option remote_port '8096' + option name 'jellyfin' + +config conf 'navidrome' + option type 'tcp' + option local_ip '127.0.0.1' + option local_port '4533' + option remote_port '4533' + option name 'navidrome' diff --git a/package/diy/navidrome-autoinit/Makefile b/package/diy/navidrome-autoinit/Makefile new file mode 100644 index 0000000000..ee0dfdacbf --- /dev/null +++ b/package/diy/navidrome-autoinit/Makefile @@ -0,0 +1,42 @@ +# +# Copyright (C) 2026 xiexiaobao +# +# This is free software, licensed under the GPL 2.0 license. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=navidrome-autoinit +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=xiexiaobao +PKG_LICENSE:=GPL-2.0 + +include $(INCLUDE_DIR)/package.mk + +define Package/navidrome-autoinit + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Auto-create Navidrome container on first boot + DEPENDS:=+dockerd + PKGARCH:=all +endef + +define Package/navidrome-autoinit/description + Automatically pull and start the Navidrome music streaming container + on first boot after flashing. Music and data directories on /mnt/usb1-0. +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/navidrome-autoinit/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/navidrome.init $(1)/etc/init.d/navidrome-autoinit +endef + +$(eval $(call BuildPackage,navidrome-autoinit)) diff --git a/package/diy/navidrome-autoinit/files/navidrome.init b/package/diy/navidrome-autoinit/files/navidrome.init new file mode 100644 index 0000000000..98006f8729 --- /dev/null +++ b/package/diy/navidrome-autoinit/files/navidrome.init @@ -0,0 +1,70 @@ +#!/bin/sh /etc/rc.common +# /etc/init.d/navidrome-autoinit +# Auto-create Navidrome Docker container on first boot. +# Idempotent: skips if container or FLAG_FILE exists. +# Tolerates missing TF card: exits gracefully. + +START=97 +FLAG_FILE="/etc/navidrome-autoinit.done" +CONTAINER="navidrome" +IMAGE="deluan/navidrome:latest" +MUSIC_DIR="/mnt/usb1-0/music" +DATA_DIR="/mnt/usb1-0/navidrome" +PORT="4533" + +boot() { + [ -f "$FLAG_FILE" ] && return 0 + + # Verify Docker is installed + if ! command -v docker >/dev/null 2>&1; then + logger -t navidrome-autoinit "docker binary not found, skipping" + return 0 + fi + + # Wait up to 30s for dockerd to be ready + local i=0 + while ! docker info >/dev/null 2>&1 && [ $i -lt 10 ]; do + sleep 3 + i=$((i + 1)) + done + if ! docker info >/dev/null 2>&1; then + logger -t navidrome-autoinit "dockerd not ready after 30s, will retry next boot" + return 0 + fi + + # Container already exists (e.g. Docker data root restored from TF card) + if docker inspect "$CONTAINER" >/dev/null 2>&1; then + logger -t navidrome-autoinit "container $CONTAINER already exists, skipping" + touch "$FLAG_FILE" + return 0 + fi + + # Create music and data directories on TF card + mkdir -p "$MUSIC_DIR" "$DATA_DIR" + + # Pull the image (tolerate network failure — will retry next boot) + logger -t navidrome-autoinit "pulling $IMAGE..." + if ! docker pull "$IMAGE" 2>&1 | logger -t navidrome-autoinit; then + logger -t navidrome-autoinit "pull failed, will retry next boot" + return 0 + fi + + # Create and start the container + logger -t navidrome-autoinit "creating container $CONTAINER..." + docker run -d \ + --name "$CONTAINER" \ + --restart unless-stopped \ + -p ${PORT}:${PORT} \ + -v "$DATA_DIR":/data \ + -v "$MUSIC_DIR":/music:ro \ + "$IMAGE" 2>&1 | logger -t navidrome-autoinit + + if docker ps | grep -q "$CONTAINER"; then + logger -t navidrome-autoinit "$CONTAINER started successfully on port $PORT" + touch "$FLAG_FILE" + else + logger -t navidrome-autoinit "$CONTAINER failed to start, will retry next boot" + fi + + return 0 +}