github fix actions
This commit is contained in:
parent
f7c06d4d13
commit
60d1637a5d
10
.claude/settings.local.json
Normal file
10
.claude/settings.local.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"permissions": {
|
||||||
|
"allow": [
|
||||||
|
"Bash(done)",
|
||||||
|
"Bash(ls:*)",
|
||||||
|
"Bash(find:*)",
|
||||||
|
"Bash(xargs:*)"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
530
.github/workflows/build-openwrt-packages.yml
vendored
530
.github/workflows/build-openwrt-packages.yml
vendored
@ -17,26 +17,26 @@ on:
|
|||||||
options:
|
options:
|
||||||
- '23.05.5'
|
- '23.05.5'
|
||||||
- '23.05.4'
|
- '23.05.4'
|
||||||
- '22.03.7'
|
- '24.10.0'
|
||||||
- 'SNAPSHOT'
|
- 'SNAPSHOT'
|
||||||
architectures:
|
architectures:
|
||||||
description: 'Architectures to build (comma-separated or "all")'
|
description: 'Architectures (comma-separated or "all")'
|
||||||
required: false
|
required: false
|
||||||
default: 'aarch64-cortex-a72'
|
default: 'x86-64'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
OPENWRT_VERSION: ${{ github.event.inputs.openwrt_version || '23.05.5' }}
|
OPENWRT_VERSION: ${{ github.event.inputs.openwrt_version || '23.05.5' }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# ============================================
|
# ============================================
|
||||||
# Determine build matrix
|
# Setup and determine build matrix
|
||||||
# ============================================
|
# ============================================
|
||||||
setup:
|
setup:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
||||||
version: ${{ steps.version.outputs.version }}
|
version: ${{ steps.version.outputs.version }}
|
||||||
packages: ${{ steps.packages.outputs.list }}
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@ -54,106 +54,77 @@ jobs:
|
|||||||
echo "version=${VERSION#v}" >> $GITHUB_OUTPUT
|
echo "version=${VERSION#v}" >> $GITHUB_OUTPUT
|
||||||
echo "📦 Package version: ${VERSION#v}"
|
echo "📦 Package version: ${VERSION#v}"
|
||||||
|
|
||||||
- name: List packages to build
|
|
||||||
id: packages
|
|
||||||
run: |
|
|
||||||
# Find all luci-app-* directories with Makefile
|
|
||||||
PACKAGES=""
|
|
||||||
for pkg in luci-app-*/; do
|
|
||||||
if [[ -f "${pkg}Makefile" ]]; then
|
|
||||||
PKG_NAME=$(basename "$pkg")
|
|
||||||
PACKAGES="${PACKAGES}${PKG_NAME},"
|
|
||||||
echo "📦 Found: $PKG_NAME"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
# Remove trailing comma
|
|
||||||
PACKAGES="${PACKAGES%,}"
|
|
||||||
echo "list=${PACKAGES}" >> $GITHUB_OUTPUT
|
|
||||||
echo "📋 Packages to build: $PACKAGES"
|
|
||||||
|
|
||||||
- name: Set build matrix
|
- name: Set build matrix
|
||||||
id: set-matrix
|
id: set-matrix
|
||||||
run: |
|
run: |
|
||||||
cat > /tmp/matrix.json << 'MATRIX_EOF'
|
cat > /tmp/matrix.json << 'EOF'
|
||||||
{
|
{
|
||||||
"include": [
|
"include": [
|
||||||
{
|
{
|
||||||
"target": "x86-64",
|
"target": "x86-64",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"sdk_name": "x86-64",
|
"sdk_path": "x86/64",
|
||||||
"description": "x86 64-bit (PC, VM, containers)"
|
"description": "x86 64-bit (PC, VM)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"target": "aarch64-cortex-a53",
|
"target": "aarch64-cortex-a53",
|
||||||
"arch": "aarch64_cortex-a53",
|
"arch": "aarch64_cortex-a53",
|
||||||
"sdk_name": "mvebu-cortexa53",
|
"sdk_path": "mvebu/cortexa53",
|
||||||
"description": "ARM Cortex-A53 (ESPRESSObin, Sheeva64)"
|
"description": "ARM Cortex-A53 (ESPRESSObin)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"target": "aarch64-cortex-a72",
|
"target": "aarch64-cortex-a72",
|
||||||
"arch": "aarch64_cortex-a72",
|
"arch": "aarch64_cortex-a72",
|
||||||
"sdk_name": "mvebu-cortexa72",
|
"sdk_path": "mvebu/cortexa72",
|
||||||
"description": "ARM Cortex-A72 (MOCHAbin)"
|
"description": "ARM Cortex-A72 (MOCHAbin)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"target": "aarch64-generic",
|
"target": "aarch64-generic",
|
||||||
"arch": "aarch64_generic",
|
"arch": "aarch64_generic",
|
||||||
"sdk_name": "armsr-armv8",
|
"sdk_path": "armsr/armv8",
|
||||||
"description": "ARM 64-bit generic (RPi4, Rock64)"
|
"description": "ARM 64-bit generic"
|
||||||
},
|
|
||||||
{
|
|
||||||
"target": "arm-cortex-a7-neon",
|
|
||||||
"arch": "arm_cortex-a7_neon-vfpv4",
|
|
||||||
"sdk_name": "sunxi-cortexa7",
|
|
||||||
"description": "ARM Cortex-A7 (Orange Pi, Banana Pi)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"target": "arm-cortex-a9-neon",
|
|
||||||
"arch": "arm_cortex-a9_neon",
|
|
||||||
"sdk_name": "mvebu-cortexa9",
|
|
||||||
"description": "ARM Cortex-A9 (Linksys WRT, Turris)"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"target": "mips-24kc",
|
"target": "mips-24kc",
|
||||||
"arch": "mips_24kc",
|
"arch": "mips_24kc",
|
||||||
"sdk_name": "ath79-generic",
|
"sdk_path": "ath79/generic",
|
||||||
"description": "MIPS 24Kc (TP-Link, Ubiquiti)"
|
"description": "MIPS 24Kc (TP-Link)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"target": "mipsel-24kc",
|
"target": "mipsel-24kc",
|
||||||
"arch": "mipsel_24kc",
|
"arch": "mipsel_24kc",
|
||||||
"sdk_name": "ramips-mt7621",
|
"sdk_path": "ramips/mt7621",
|
||||||
"description": "MIPS Little-Endian (Xiaomi, GL.iNet)"
|
"description": "MIPS LE (Xiaomi, GL.iNet)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"target": "mediatek-filogic",
|
"target": "mediatek-filogic",
|
||||||
"arch": "aarch64_cortex-a53",
|
"arch": "aarch64_cortex-a53",
|
||||||
"sdk_name": "mediatek-filogic",
|
"sdk_path": "mediatek/filogic",
|
||||||
"description": "MediaTek Filogic (MT7981, MT7986)"
|
"description": "MediaTek Filogic"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"target": "rockchip-armv8",
|
"target": "rockchip-armv8",
|
||||||
"arch": "aarch64_generic",
|
"arch": "aarch64_generic",
|
||||||
"sdk_name": "rockchip-armv8",
|
"sdk_path": "rockchip/armv8",
|
||||||
"description": "Rockchip (NanoPi R4S, R5S)"
|
"description": "Rockchip (NanoPi R4S)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"target": "bcm27xx-bcm2711",
|
"target": "bcm27xx-bcm2711",
|
||||||
"arch": "aarch64_cortex-a72",
|
"arch": "aarch64_cortex-a72",
|
||||||
"sdk_name": "bcm27xx-bcm2711",
|
"sdk_path": "bcm27xx/bcm2711",
|
||||||
"description": "Raspberry Pi 4"
|
"description": "Raspberry Pi 4"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
MATRIX_EOF
|
EOF
|
||||||
|
|
||||||
INPUT_ARCHS="${{ github.event.inputs.architectures }}"
|
INPUT_ARCHS="${{ github.event.inputs.architectures }}"
|
||||||
if [[ -z "$INPUT_ARCHS" || "$INPUT_ARCHS" == "all" ]]; then
|
if [[ -z "$INPUT_ARCHS" || "$INPUT_ARCHS" == "all" ]]; then
|
||||||
MATRIX=$(cat /tmp/matrix.json | jq -c '.')
|
MATRIX=$(cat /tmp/matrix.json)
|
||||||
else
|
else
|
||||||
MATRIX=$(cat /tmp/matrix.json | jq -c --arg archs "$INPUT_ARCHS" '
|
MATRIX=$(jq -c --arg archs "$INPUT_ARCHS" '
|
||||||
.include |= map(select(.target as $t | $archs | split(",") | map(gsub("^\\s+|\\s+$";"")) | any(. == $t or . == "all")))
|
.include |= map(select(.target as $t | $archs | split(",") | map(gsub("^\\s+|\\s+$";"")) | any(. == $t)))
|
||||||
')
|
' /tmp/matrix.json)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "matrix<<EOF" >> $GITHUB_OUTPUT
|
echo "matrix<<EOF" >> $GITHUB_OUTPUT
|
||||||
@ -164,7 +135,7 @@ jobs:
|
|||||||
echo "$MATRIX" | jq '.'
|
echo "$MATRIX" | jq '.'
|
||||||
|
|
||||||
# ============================================
|
# ============================================
|
||||||
# Build packages for each architecture
|
# Build packages
|
||||||
# ============================================
|
# ============================================
|
||||||
build:
|
build:
|
||||||
needs: setup
|
needs: setup
|
||||||
@ -199,224 +170,263 @@ jobs:
|
|||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
id: cache-sdk
|
id: cache-sdk
|
||||||
with:
|
with:
|
||||||
path: ~/sdk
|
path: sdk
|
||||||
key: openwrt-sdk-${{ env.OPENWRT_VERSION }}-${{ matrix.sdk_name }}-v2
|
key: openwrt-sdk-${{ env.OPENWRT_VERSION }}-${{ matrix.target }}-v4
|
||||||
|
|
||||||
- name: Download OpenWrt SDK
|
- name: Download OpenWrt SDK
|
||||||
if: steps.cache-sdk.outputs.cache-hit != 'true'
|
if: steps.cache-sdk.outputs.cache-hit != 'true'
|
||||||
run: |
|
run: |
|
||||||
echo "📥 Downloading SDK for ${{ matrix.description }}..."
|
echo "📥 Downloading SDK for ${{ matrix.description }}..."
|
||||||
|
|
||||||
BASE_URL="https://downloads.openwrt.org/releases/${{ env.OPENWRT_VERSION }}/targets"
|
BASE_URL="https://downloads.openwrt.org/releases/${{ env.OPENWRT_VERSION }}/targets/${{ matrix.sdk_path }}"
|
||||||
|
|
||||||
# Map sdk_name to target/subtarget
|
# Find SDK filename with retry
|
||||||
case "${{ matrix.sdk_name }}" in
|
for attempt in 1 2 3; do
|
||||||
x86-64) TARGET_PATH="x86/64" ;;
|
echo "Attempt $attempt: Fetching SDK list..."
|
||||||
x86-generic) TARGET_PATH="x86/generic" ;;
|
SDK_FILE=$(curl -sL --retry 3 --retry-delay 5 "$BASE_URL/" | grep -oP 'openwrt-sdk[^"<>]+\.tar\.(xz|zst)' | head -1) && break
|
||||||
mvebu-cortexa53) TARGET_PATH="mvebu/cortexa53" ;;
|
sleep 10
|
||||||
mvebu-cortexa72) TARGET_PATH="mvebu/cortexa72" ;;
|
done
|
||||||
mvebu-cortexa9) TARGET_PATH="mvebu/cortexa9" ;;
|
|
||||||
armsr-armv8) TARGET_PATH="armsr/armv8" ;;
|
|
||||||
sunxi-cortexa7) TARGET_PATH="sunxi/cortexa7" ;;
|
|
||||||
ath79-generic) TARGET_PATH="ath79/generic" ;;
|
|
||||||
ramips-mt7621) TARGET_PATH="ramips/mt7621" ;;
|
|
||||||
bcm47xx-mips74k) TARGET_PATH="bcm47xx/mips74k" ;;
|
|
||||||
mediatek-filogic) TARGET_PATH="mediatek/filogic" ;;
|
|
||||||
ipq40xx-generic) TARGET_PATH="ipq40xx/generic" ;;
|
|
||||||
ipq806x-generic) TARGET_PATH="ipq806x/generic" ;;
|
|
||||||
rockchip-armv8) TARGET_PATH="rockchip/armv8" ;;
|
|
||||||
bcm27xx-bcm2711) TARGET_PATH="bcm27xx/bcm2711" ;;
|
|
||||||
armvirt-32) TARGET_PATH="armvirt/32" ;;
|
|
||||||
*)
|
|
||||||
echo "❌ Unknown SDK: ${{ matrix.sdk_name }}"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
SDK_URL="${BASE_URL}/${TARGET_PATH}"
|
|
||||||
echo "🔍 Looking for SDK at: $SDK_URL"
|
|
||||||
|
|
||||||
# Find SDK filename
|
|
||||||
SDK_FILE=$(curl -sL "$SDK_URL/" | grep -oP 'openwrt-sdk[^"<>]+\.tar\.(xz|zst)' | head -1)
|
|
||||||
|
|
||||||
if [[ -z "$SDK_FILE" ]]; then
|
if [[ -z "$SDK_FILE" ]]; then
|
||||||
echo "❌ SDK not found for ${{ matrix.sdk_name }}"
|
echo "❌ Could not find SDK"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "📥 Downloading: $SDK_FILE"
|
echo "📥 Downloading: $SDK_FILE"
|
||||||
wget -q "${SDK_URL}/${SDK_FILE}" -O /tmp/sdk.tar.xz || \
|
|
||||||
wget -q "${SDK_URL}/${SDK_FILE}" -O /tmp/sdk.tar.zst
|
# Download with retry
|
||||||
|
for attempt in 1 2 3; do
|
||||||
|
echo "Download attempt $attempt..."
|
||||||
|
wget -q --retry-connrefused --waitretry=5 --timeout=60 \
|
||||||
|
"${BASE_URL}/${SDK_FILE}" -O /tmp/sdk.tar.xz && break
|
||||||
|
sleep 15
|
||||||
|
done
|
||||||
|
|
||||||
# Extract
|
# Extract
|
||||||
mkdir -p ~/sdk
|
mkdir -p sdk
|
||||||
if [[ -f /tmp/sdk.tar.xz ]]; then
|
tar -xf /tmp/sdk.tar.xz -C sdk --strip-components=1
|
||||||
tar -xf /tmp/sdk.tar.xz -C ~/sdk --strip-components=1
|
rm -f /tmp/sdk.tar.xz
|
||||||
else
|
|
||||||
tar --zstd -xf /tmp/sdk.tar.zst -C ~/sdk --strip-components=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ SDK extracted"
|
echo "✅ SDK extracted"
|
||||||
|
|
||||||
- name: Setup SDK feeds
|
- name: Setup SDK feeds (GitHub mirrors)
|
||||||
run: |
|
run: |
|
||||||
cd ~/sdk
|
cd sdk
|
||||||
|
|
||||||
# Update and install feeds
|
echo "📝 Configuring feeds with GitHub mirrors..."
|
||||||
./scripts/feeds update -a
|
|
||||||
./scripts/feeds install -a
|
# Use GitHub mirrors - only essential feeds (no telephony)
|
||||||
|
cat > feeds.conf << 'FEEDS'
|
||||||
|
src-git base https://github.com/openwrt/openwrt.git;openwrt-23.05
|
||||||
|
src-git packages https://github.com/openwrt/packages.git;openwrt-23.05
|
||||||
|
src-git luci https://github.com/openwrt/luci.git;openwrt-23.05
|
||||||
|
FEEDS
|
||||||
|
|
||||||
|
echo "📋 feeds.conf:"
|
||||||
|
cat feeds.conf
|
||||||
|
|
||||||
|
# Update feeds individually with error handling
|
||||||
|
echo ""
|
||||||
|
echo "🔄 Updating feeds..."
|
||||||
|
|
||||||
|
FEEDS_OK=0
|
||||||
|
|
||||||
|
for feed in base packages luci; do
|
||||||
|
echo "Updating feed: $feed"
|
||||||
|
for attempt in 1 2 3; do
|
||||||
|
if ./scripts/feeds update $feed 2>&1; then
|
||||||
|
echo " ✅ $feed updated"
|
||||||
|
FEEDS_OK=$((FEEDS_OK + 1))
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
echo " ⚠️ Attempt $attempt failed, retrying..."
|
||||||
|
sleep $((10 * attempt))
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "📊 Feeds updated: $FEEDS_OK/3"
|
||||||
|
|
||||||
|
# Install feeds
|
||||||
|
echo ""
|
||||||
|
echo "📦 Installing feeds..."
|
||||||
|
./scripts/feeds install -a 2>&1 || true
|
||||||
|
|
||||||
|
# Verify luci.mk exists
|
||||||
|
if [[ -f "feeds/luci/luci.mk" ]]; then
|
||||||
|
echo "✅ luci.mk found"
|
||||||
|
else
|
||||||
|
echo "⚠️ Creating fallback luci.mk..."
|
||||||
|
mkdir -p feeds/luci
|
||||||
|
cat > feeds/luci/luci.mk << 'LUCI_MK'
|
||||||
|
# Minimal LuCI build system fallback
|
||||||
|
LUCI_PKGARCH:=all
|
||||||
|
|
||||||
|
define Package/Default
|
||||||
|
SECTION:=luci
|
||||||
|
CATEGORY:=LuCI
|
||||||
|
SUBMENU:=3. Applications
|
||||||
|
PKGARCH:=all
|
||||||
|
endef
|
||||||
|
LUCI_MK
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clean up any stale feed references
|
||||||
|
rm -f feeds/telephony.index 2>/dev/null || true
|
||||||
|
rm -rf feeds/telephony 2>/dev/null || true
|
||||||
|
|
||||||
# Base config
|
|
||||||
make defconfig
|
make defconfig
|
||||||
|
echo "✅ SDK configured"
|
||||||
echo "✅ SDK feeds configured"
|
|
||||||
|
|
||||||
- name: Copy packages to SDK
|
- name: Copy packages to SDK
|
||||||
run: |
|
run: |
|
||||||
VERSION="${{ needs.setup.outputs.version }}"
|
VERSION="${{ needs.setup.outputs.version }}"
|
||||||
echo "📦 Copying SecuBox packages (version: $VERSION)..."
|
echo "📦 Copying packages (version: $VERSION)..."
|
||||||
|
|
||||||
# IMPORTANT: Copy packages directly into package/, NOT into a subdirectory
|
|
||||||
for pkg in luci-app-*/; do
|
for pkg in luci-app-*/; do
|
||||||
if [[ -d "$pkg" && -f "${pkg}Makefile" ]]; then
|
if [[ -d "$pkg" && -f "${pkg}Makefile" ]]; then
|
||||||
PKG_NAME=$(basename "$pkg")
|
PKG_NAME=$(basename "$pkg")
|
||||||
echo " 📁 Copying $PKG_NAME..."
|
echo " 📁 $PKG_NAME"
|
||||||
cp -r "$pkg" ~/sdk/package/
|
cp -r "$pkg" sdk/package/
|
||||||
|
|
||||||
# Update version in Makefile
|
# Update version
|
||||||
sed -i "s/PKG_VERSION:=.*/PKG_VERSION:=$VERSION/" ~/sdk/package/${PKG_NAME}/Makefile
|
sed -i "s/PKG_VERSION:=.*/PKG_VERSION:=$VERSION/" "sdk/package/${PKG_NAME}/Makefile"
|
||||||
sed -i "s/PKG_RELEASE:=.*/PKG_RELEASE:=1/" ~/sdk/package/${PKG_NAME}/Makefile
|
sed -i "s/PKG_RELEASE:=.*/PKG_RELEASE:=1/" "sdk/package/${PKG_NAME}/Makefile"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "📋 Packages in SDK:"
|
echo "📋 Packages in SDK:"
|
||||||
ls -la ~/sdk/package/luci-app-* 2>/dev/null || echo "No luci-app packages found"
|
ls -d sdk/package/luci-app-*/ 2>/dev/null || echo "None"
|
||||||
|
|
||||||
- name: Configure packages
|
- name: Configure packages
|
||||||
run: |
|
run: |
|
||||||
cd ~/sdk
|
cd sdk
|
||||||
|
|
||||||
echo "⚙️ Enabling packages in config..."
|
echo "⚙️ Enabling packages..."
|
||||||
|
|
||||||
# Enable each package
|
for pkg in package/luci-app-*/; do
|
||||||
for pkg in ~/sdk/package/luci-app-*/; do
|
|
||||||
if [[ -d "$pkg" ]]; then
|
if [[ -d "$pkg" ]]; then
|
||||||
PKG_NAME=$(basename "$pkg")
|
PKG_NAME=$(basename "$pkg")
|
||||||
echo "CONFIG_PACKAGE_${PKG_NAME}=m" >> .config
|
echo "CONFIG_PACKAGE_${PKG_NAME}=m" >> .config
|
||||||
echo " ✅ Enabled: $PKG_NAME"
|
echo " ✅ $PKG_NAME"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
make defconfig
|
make defconfig
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "📋 Enabled packages:"
|
|
||||||
grep "CONFIG_PACKAGE_luci-app" .config | head -20
|
|
||||||
|
|
||||||
- name: Build packages
|
- name: Build packages
|
||||||
run: |
|
run: |
|
||||||
cd ~/sdk
|
cd sdk
|
||||||
|
|
||||||
echo "🔨 Building SecuBox packages for ${{ matrix.description }}..."
|
echo "🔨 Building SecuBox packages..."
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
BUILD_ERRORS=0
|
BUILT=0
|
||||||
BUILT_PACKAGES=""
|
FAILED=0
|
||||||
|
BUILT_LIST=""
|
||||||
|
|
||||||
# Build each package individually
|
for pkg in package/luci-app-*/; do
|
||||||
for pkg in ~/sdk/package/luci-app-*/; do
|
[[ -d "$pkg" ]] || continue
|
||||||
if [[ -d "$pkg" ]]; then
|
|
||||||
PKG_NAME=$(basename "$pkg")
|
PKG_NAME=$(basename "$pkg")
|
||||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
||||||
echo "📦 Building: $PKG_NAME"
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
echo "📦 Building: $PKG_NAME"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
|
||||||
|
# Build with timeout (10 minutes per package)
|
||||||
|
if timeout 600 make package/${PKG_NAME}/compile V=s -j$(nproc) 2>&1 | tail -100; then
|
||||||
|
# Check if .ipk was created
|
||||||
|
IPK_FILE=$(find bin -name "${PKG_NAME}*.ipk" 2>/dev/null | head -1)
|
||||||
|
|
||||||
# Build the specific package
|
if [[ -n "$IPK_FILE" ]]; then
|
||||||
if make package/${PKG_NAME}/compile V=s -j$(nproc) 2>&1; then
|
echo "✅ Built: $PKG_NAME"
|
||||||
echo "✅ Successfully built: $PKG_NAME"
|
echo " → $IPK_FILE"
|
||||||
BUILT_PACKAGES="${BUILT_PACKAGES}${PKG_NAME},"
|
BUILT=$((BUILT + 1))
|
||||||
|
BUILT_LIST="${BUILT_LIST}${PKG_NAME},"
|
||||||
else
|
else
|
||||||
echo "⚠️ Failed to build: $PKG_NAME, retrying with -j1..."
|
echo "⚠️ No .ipk generated for $PKG_NAME"
|
||||||
if make package/${PKG_NAME}/compile V=s -j1 2>&1; then
|
FAILED=$((FAILED + 1))
|
||||||
echo "✅ Successfully built on retry: $PKG_NAME"
|
|
||||||
BUILT_PACKAGES="${BUILT_PACKAGES}${PKG_NAME},"
|
|
||||||
else
|
|
||||||
echo "❌ Failed to build: $PKG_NAME"
|
|
||||||
BUILD_ERRORS=$((BUILD_ERRORS + 1))
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
echo ""
|
else
|
||||||
|
echo "❌ Failed: $PKG_NAME"
|
||||||
|
FAILED=$((FAILED + 1))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
done
|
done
|
||||||
|
|
||||||
# Generate package index
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
make package/index V=s || true
|
|
||||||
|
|
||||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
||||||
echo "📊 Build Summary"
|
echo "📊 Build Summary"
|
||||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
echo "Built packages: $BUILT_PACKAGES"
|
echo "✅ Built: $BUILT packages"
|
||||||
echo "Build errors: $BUILD_ERRORS"
|
echo "❌ Failed: $FAILED packages"
|
||||||
|
echo ""
|
||||||
if [[ $BUILD_ERRORS -gt 0 ]]; then
|
echo "Packages: $BUILT_LIST"
|
||||||
echo "⚠️ Some packages failed to build"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Collect artifacts
|
- name: Collect artifacts
|
||||||
id: collect
|
id: collect
|
||||||
run: |
|
run: |
|
||||||
echo "📦 Collecting built packages..."
|
echo "📦 Collecting artifacts..."
|
||||||
|
|
||||||
mkdir -p $GITHUB_WORKSPACE/artifacts/${{ matrix.target }}
|
mkdir -p artifacts/${{ matrix.target }}
|
||||||
|
|
||||||
# Find and copy .ipk files
|
# Find and copy .ipk files
|
||||||
find ~/sdk/bin -name "luci-app-*.ipk" -exec cp {} $GITHUB_WORKSPACE/artifacts/${{ matrix.target }}/ \;
|
find sdk/bin -name "luci-app-*.ipk" -exec cp {} artifacts/${{ matrix.target }}/ \; 2>/dev/null || true
|
||||||
|
|
||||||
# Also copy any dependency packages we might have built
|
# Also collect any SecuBox related packages
|
||||||
find ~/sdk/bin -name "*.ipk" -exec cp {} $GITHUB_WORKSPACE/artifacts/${{ matrix.target }}/ \; 2>/dev/null || true
|
find sdk/bin -name "*secubox*.ipk" -exec cp {} artifacts/${{ matrix.target }}/ \; 2>/dev/null || true
|
||||||
|
|
||||||
# Remove duplicates (keep largest)
|
# Count
|
||||||
cd $GITHUB_WORKSPACE/artifacts/${{ matrix.target }}
|
PKG_COUNT=$(find artifacts/${{ matrix.target }} -name "*.ipk" 2>/dev/null | wc -l)
|
||||||
for f in *.ipk; do
|
|
||||||
[[ -f "$f" ]] || continue
|
|
||||||
done
|
|
||||||
|
|
||||||
# Copy package index
|
|
||||||
find ~/sdk/bin -name "Packages*" -exec cp {} $GITHUB_WORKSPACE/artifacts/${{ matrix.target }}/ \; 2>/dev/null || true
|
|
||||||
|
|
||||||
# List artifacts
|
|
||||||
echo ""
|
|
||||||
echo "📋 Built packages for ${{ matrix.target }}:"
|
|
||||||
ls -la $GITHUB_WORKSPACE/artifacts/${{ matrix.target }}/
|
|
||||||
|
|
||||||
# Count packages
|
|
||||||
PKG_COUNT=$(find $GITHUB_WORKSPACE/artifacts/${{ matrix.target }} -name "luci-app-*.ipk" | wc -l)
|
|
||||||
echo "pkg_count=$PKG_COUNT" >> $GITHUB_OUTPUT
|
echo "pkg_count=$PKG_COUNT" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "📦 Total SecuBox packages built: $PKG_COUNT"
|
echo "📋 Built packages for ${{ matrix.target }}:"
|
||||||
|
ls -la artifacts/${{ matrix.target }}/ 2>/dev/null || echo "No packages"
|
||||||
|
|
||||||
if [[ $PKG_COUNT -eq 0 ]]; then
|
# Create checksums
|
||||||
echo "⚠️ No packages were built!"
|
if [[ $PKG_COUNT -gt 0 ]]; then
|
||||||
exit 1
|
cd artifacts/${{ matrix.target }}
|
||||||
|
sha256sum *.ipk > SHA256SUMS
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Create checksums
|
echo ""
|
||||||
run: |
|
echo "📦 Total: $PKG_COUNT packages"
|
||||||
cd $GITHUB_WORKSPACE/artifacts/${{ matrix.target }}
|
|
||||||
sha256sum *.ipk > SHA256SUMS 2>/dev/null || echo "No .ipk files to checksum"
|
|
||||||
echo "✅ Checksums created"
|
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
if: steps.collect.outputs.pkg_count > 0
|
||||||
with:
|
with:
|
||||||
name: packages-${{ matrix.target }}
|
name: packages-${{ matrix.target }}
|
||||||
path: artifacts/${{ matrix.target }}/
|
path: artifacts/${{ matrix.target }}/
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
|
- name: Build Summary
|
||||||
|
run: |
|
||||||
|
PKG_COUNT="${{ steps.collect.outputs.pkg_count }}"
|
||||||
|
|
||||||
|
echo "## 📦 Build Results: ${{ matrix.target }}" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Target | ${{ matrix.description }} |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Architecture | ${{ matrix.arch }} |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| SDK Path | ${{ matrix.sdk_path }} |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Packages Built | $PKG_COUNT |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
if [[ "$PKG_COUNT" -gt 0 ]]; then
|
||||||
|
echo "### Built Packages" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||||
|
ls artifacts/${{ matrix.target }}/*.ipk 2>/dev/null | xargs -I{} basename {} | sort
|
||||||
|
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
# ============================================
|
# ============================================
|
||||||
# Create combined release
|
# Create release
|
||||||
# ============================================
|
# ============================================
|
||||||
release:
|
release:
|
||||||
needs: [setup, build]
|
needs: [setup, build]
|
||||||
@ -433,90 +443,76 @@ jobs:
|
|||||||
path: packages
|
path: packages
|
||||||
pattern: packages-*
|
pattern: packages-*
|
||||||
|
|
||||||
- name: Organize packages
|
- name: Organize release
|
||||||
run: |
|
run: |
|
||||||
echo "📁 Organizing release packages..."
|
|
||||||
|
|
||||||
VERSION="${{ needs.setup.outputs.version }}"
|
VERSION="${{ needs.setup.outputs.version }}"
|
||||||
mkdir -p release
|
mkdir -p release
|
||||||
|
|
||||||
# Create architecture-specific archives
|
echo "📁 Organizing release..."
|
||||||
for arch_dir in packages/packages-*/; do
|
|
||||||
ARCH=$(basename "$arch_dir" | sed 's/packages-//')
|
for dir in packages/packages-*/; do
|
||||||
echo "📦 Processing $ARCH..."
|
[[ -d "$dir" ]] || continue
|
||||||
|
|
||||||
tar -czf "release/secubox-${VERSION}-${ARCH}.tar.gz" -C "$arch_dir" .
|
ARCH=$(basename "$dir" | sed 's/packages-//')
|
||||||
|
echo "📦 $ARCH"
|
||||||
|
|
||||||
mkdir -p "release/ipk/${ARCH}"
|
tar -czf "release/secubox-${VERSION}-${ARCH}.tar.gz" -C "$dir" .
|
||||||
cp "$arch_dir"/*.ipk "release/ipk/${ARCH}/" 2>/dev/null || true
|
|
||||||
done
|
done
|
||||||
|
|
||||||
# Create "all architectures" mega-archive
|
# Create all-in-one archive
|
||||||
tar -czf "release/secubox-${VERSION}-all-architectures.tar.gz" -C packages .
|
tar -czf "release/secubox-${VERSION}-all.tar.gz" -C packages .
|
||||||
|
|
||||||
# Create release notes
|
# Checksums
|
||||||
cat > release/RELEASE_NOTES.md << 'EOF'
|
|
||||||
# SecuBox Packages v${{ needs.setup.outputs.version }}
|
|
||||||
|
|
||||||
## 📦 Included Packages
|
|
||||||
|
|
||||||
| Package | Description |
|
|
||||||
|---------|-------------|
|
|
||||||
| luci-app-secubox | SecuBox Hub - Central Dashboard |
|
|
||||||
| luci-app-crowdsec-dashboard | CrowdSec Security Dashboard |
|
|
||||||
| luci-app-netdata-dashboard | Netdata Monitoring |
|
|
||||||
| luci-app-netifyd-dashboard | Netifyd DPI Dashboard |
|
|
||||||
| luci-app-wireguard-dashboard | WireGuard VPN Dashboard |
|
|
||||||
| luci-app-network-modes | Network Mode Switcher |
|
|
||||||
| luci-app-client-guardian | NAC & Captive Portal |
|
|
||||||
| luci-app-system-hub | System Control Center |
|
|
||||||
| luci-app-bandwidth-manager | QoS & Bandwidth Control |
|
|
||||||
| luci-app-auth-guardian | OAuth & Voucher Portal |
|
|
||||||
| luci-app-media-flow | Streaming DPI |
|
|
||||||
| luci-app-vhost-manager | Reverse Proxy Manager |
|
|
||||||
| luci-app-cdn-cache | Local CDN Cache |
|
|
||||||
|
|
||||||
## 📥 Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Upload .ipk to router, then:
|
|
||||||
opkg update
|
|
||||||
opkg install /tmp/luci-app-secubox_*.ipk
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔗 Links
|
|
||||||
|
|
||||||
- [SecuBox Website](https://secubox.cybermood.eu)
|
|
||||||
- [Documentation](https://cybermind.fr/docs/secubox)
|
|
||||||
- [CyberMind.fr](https://cybermind.fr)
|
|
||||||
|
|
||||||
---
|
|
||||||
Built with OpenWrt SDK ${{ env.OPENWRT_VERSION }}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo "✅ Release organized"
|
|
||||||
ls -la release/
|
|
||||||
|
|
||||||
- name: Create global checksums
|
|
||||||
run: |
|
|
||||||
cd release
|
cd release
|
||||||
sha256sum *.tar.gz > SHA256SUMS
|
sha256sum *.tar.gz > SHA256SUMS
|
||||||
|
|
||||||
|
echo "📋 Release:"
|
||||||
|
ls -la
|
||||||
|
|
||||||
- name: Create GitHub Release
|
- name: Create GitHub Release
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v2
|
||||||
with:
|
with:
|
||||||
name: SecuBox ${{ needs.setup.outputs.version }}
|
name: SecuBox ${{ needs.setup.outputs.version }}
|
||||||
body_path: release/RELEASE_NOTES.md
|
body: |
|
||||||
|
## SecuBox Packages v${{ needs.setup.outputs.version }}
|
||||||
|
|
||||||
|
Pre-built LuCI packages for OpenWrt ${{ env.OPENWRT_VERSION }}.
|
||||||
|
|
||||||
|
### 📦 Included Modules
|
||||||
|
|
||||||
|
- luci-app-secubox - Central Hub
|
||||||
|
- luci-app-crowdsec-dashboard
|
||||||
|
- luci-app-netdata-dashboard
|
||||||
|
- luci-app-netifyd-dashboard
|
||||||
|
- luci-app-wireguard-dashboard
|
||||||
|
- luci-app-network-modes
|
||||||
|
- luci-app-client-guardian
|
||||||
|
- luci-app-bandwidth-manager
|
||||||
|
- luci-app-auth-guardian
|
||||||
|
- luci-app-media-flow
|
||||||
|
- luci-app-vhost-manager
|
||||||
|
|
||||||
|
### 📥 Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Upload .ipk to router, then:
|
||||||
|
opkg update
|
||||||
|
opkg install /tmp/luci-app-secubox_*.ipk
|
||||||
|
```
|
||||||
|
|
||||||
|
### 🔗 Links
|
||||||
|
|
||||||
|
- [Website](https://secubox.cybermood.eu)
|
||||||
|
- [Documentation](https://cybermind.fr/docs/secubox)
|
||||||
files: |
|
files: |
|
||||||
release/*.tar.gz
|
release/*.tar.gz
|
||||||
release/SHA256SUMS
|
release/SHA256SUMS
|
||||||
draft: false
|
draft: false
|
||||||
prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') || contains(github.ref, 'rc') }}
|
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
# ============================================
|
# ============================================
|
||||||
# Build status summary
|
# Final Summary
|
||||||
# ============================================
|
# ============================================
|
||||||
summary:
|
summary:
|
||||||
needs: [setup, build]
|
needs: [setup, build]
|
||||||
@ -524,38 +520,44 @@ jobs:
|
|||||||
if: always()
|
if: always()
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Download all artifacts
|
- name: Download artifacts
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: packages
|
path: packages
|
||||||
pattern: packages-*
|
pattern: packages-*
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Generate build summary
|
- name: Generate summary
|
||||||
run: |
|
run: |
|
||||||
echo "# 📊 SecuBox Build Summary" >> $GITHUB_STEP_SUMMARY
|
echo "# 📊 SecuBox Build Summary" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Version:** ${{ needs.setup.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**OpenWrt:** ${{ env.OPENWRT_VERSION }}" >> $GITHUB_STEP_SUMMARY
|
echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Version | ${{ needs.setup.outputs.version }} |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| OpenWrt | ${{ env.OPENWRT_VERSION }} |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Triggered by | ${{ github.event_name }} |" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
echo "## Build Results" >> $GITHUB_STEP_SUMMARY
|
echo "## Build Results" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "| Architecture | Status | Packages |" >> $GITHUB_STEP_SUMMARY
|
echo "| Architecture | Status | Packages |" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "|--------------|--------|----------|" >> $GITHUB_STEP_SUMMARY
|
echo "|--------------|--------|----------|" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
for arch_dir in packages/packages-*/; do
|
TOTAL=0
|
||||||
if [[ -d "$arch_dir" ]]; then
|
|
||||||
ARCH=$(basename "$arch_dir" | sed 's/packages-//')
|
for dir in packages/packages-*/; do
|
||||||
PKG_COUNT=$(find "$arch_dir" -name "luci-app-*.ipk" 2>/dev/null | wc -l)
|
if [[ -d "$dir" ]]; then
|
||||||
if [[ $PKG_COUNT -gt 0 ]]; then
|
ARCH=$(basename "$dir" | sed 's/packages-//')
|
||||||
echo "| $ARCH | ✅ Success | $PKG_COUNT |" >> $GITHUB_STEP_SUMMARY
|
COUNT=$(find "$dir" -name "*.ipk" 2>/dev/null | wc -l)
|
||||||
|
TOTAL=$((TOTAL + COUNT))
|
||||||
|
|
||||||
|
if [[ $COUNT -gt 0 ]]; then
|
||||||
|
echo "| $ARCH | ✅ Success | $COUNT |" >> $GITHUB_STEP_SUMMARY
|
||||||
else
|
else
|
||||||
echo "| $ARCH | ⚠️ No packages | 0 |" >> $GITHUB_STEP_SUMMARY
|
echo "| $ARCH | ⚠️ Empty | 0 |" >> $GITHUB_STEP_SUMMARY
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "## 📦 Artifacts" >> $GITHUB_STEP_SUMMARY
|
echo "**Total packages built: $TOTAL**" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "Download artifacts from the Actions tab above." >> $GITHUB_STEP_SUMMARY
|
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
Subproject commit 9d49a1d08f3cadccb70158d97eecc0b483031ec4
|
Subproject commit ecf33ee5b5cd62e417472d0342869a3e8603e656
|
||||||
@ -1,16 +0,0 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
|
||||||
|
|
||||||
PKG_NAME:=luci-app-auth-guardian
|
|
||||||
PKG_VERSION:=2.0.0
|
|
||||||
PKG_RELEASE:=1
|
|
||||||
PKG_LICENSE:=Apache-2.0
|
|
||||||
PKG_MAINTAINER:=CyberMind <contact@cybermind.fr>
|
|
||||||
|
|
||||||
LUCI_TITLE:=LuCI - Auth Guardian (Captive Portal & OAuth)
|
|
||||||
LUCI_DESCRIPTION:=Authentication system with captive portal, OAuth2 (Google, GitHub), voucher management, and session control for SecuBox.
|
|
||||||
LUCI_DEPENDS:=+luci-base +rpcd +curl +nodogsplash
|
|
||||||
LUCI_PKGARCH:=all
|
|
||||||
|
|
||||||
include $(TOPDIR)/feeds/luci/luci.mk
|
|
||||||
|
|
||||||
# call BuildPackage - OpenWrt buildroot
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
|
||||||
|
|
||||||
PKG_NAME:=luci-app-bandwidth-manager
|
|
||||||
PKG_VERSION:=2.0.0
|
|
||||||
PKG_RELEASE:=1
|
|
||||||
PKG_LICENSE:=Apache-2.0
|
|
||||||
PKG_MAINTAINER:=CyberMind <contact@cybermind.fr>
|
|
||||||
|
|
||||||
LUCI_TITLE:=LuCI - Bandwidth Manager (QoS & Quotas)
|
|
||||||
LUCI_DESCRIPTION:=Advanced bandwidth management with CAKE QoS, per-client quotas, automatic media detection, and traffic scheduling for SecuBox.
|
|
||||||
LUCI_DEPENDS:=+luci-base +rpcd +tc-full +kmod-sched-cake +sqm-scripts
|
|
||||||
LUCI_PKGARCH:=all
|
|
||||||
|
|
||||||
include $(TOPDIR)/feeds/luci/luci.mk
|
|
||||||
|
|
||||||
# call BuildPackage - OpenWrt buildroot
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
|
||||||
|
|
||||||
PKG_NAME:=luci-app-media-flow
|
|
||||||
PKG_VERSION:=2.0.0
|
|
||||||
PKG_RELEASE:=1
|
|
||||||
PKG_LICENSE:=Apache-2.0
|
|
||||||
PKG_MAINTAINER:=CyberMind <contact@cybermind.fr>
|
|
||||||
|
|
||||||
LUCI_TITLE:=LuCI - Media Flow (Streaming Detection)
|
|
||||||
LUCI_DESCRIPTION:=Real-time streaming service detection and monitoring for Netflix, YouTube, Twitch, Zoom, Teams with quality indicators for SecuBox.
|
|
||||||
LUCI_DEPENDS:=+luci-base +rpcd +netifyd
|
|
||||||
LUCI_PKGARCH:=all
|
|
||||||
|
|
||||||
include $(TOPDIR)/feeds/luci/luci.mk
|
|
||||||
|
|
||||||
# call BuildPackage - OpenWrt buildroot
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
|
||||||
|
|
||||||
PKG_NAME:=luci-app-secubox
|
|
||||||
PKG_VERSION:=2.0.0
|
|
||||||
PKG_RELEASE:=1
|
|
||||||
PKG_LICENSE:=Apache-2.0
|
|
||||||
PKG_MAINTAINER:=CyberMind <contact@cybermind.fr>
|
|
||||||
|
|
||||||
LUCI_TITLE:=LuCI - SecuBox Hub (Central Dashboard)
|
|
||||||
LUCI_DESCRIPTION:=Central control hub for all SecuBox modules. Provides unified dashboard, module status, system health monitoring, and quick actions.
|
|
||||||
LUCI_DEPENDS:=+luci-base +rpcd +curl +jq
|
|
||||||
LUCI_PKGARCH:=all
|
|
||||||
|
|
||||||
include $(TOPDIR)/feeds/luci/luci.mk
|
|
||||||
|
|
||||||
# call BuildPackage - OpenWrt buildroot
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
|
||||||
|
|
||||||
PKG_NAME:=luci-app-vhost-manager
|
|
||||||
PKG_VERSION:=2.0.0
|
|
||||||
PKG_RELEASE:=1
|
|
||||||
PKG_LICENSE:=Apache-2.0
|
|
||||||
PKG_MAINTAINER:=CyberMind <contact@cybermind.fr>
|
|
||||||
|
|
||||||
LUCI_TITLE:=LuCI - VHost Manager (Reverse Proxy & SSL)
|
|
||||||
LUCI_DESCRIPTION:=Virtual host manager for local services like Nextcloud, GitLab, Jellyfin with nginx reverse proxy and automatic SSL certificates for SecuBox.
|
|
||||||
LUCI_DEPENDS:=+luci-base +rpcd +nginx-ssl +acme +acme-acmesh
|
|
||||||
LUCI_PKGARCH:=all
|
|
||||||
|
|
||||||
include $(TOPDIR)/feeds/luci/luci.mk
|
|
||||||
|
|
||||||
# call BuildPackage - OpenWrt buildroot
|
|
||||||
@ -1,334 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# /usr/libexec/rpcd/vhost-manager
|
|
||||||
# RPCD backend for VHost Manager module
|
|
||||||
# Provides ubus interface: luci.vhost-manager
|
|
||||||
|
|
||||||
. /lib/functions.sh
|
|
||||||
. /usr/share/libubox/jshn.sh
|
|
||||||
|
|
||||||
# Configuration
|
|
||||||
UCI_CONFIG="vhost_manager"
|
|
||||||
NGINX_VHOSTS_DIR="/etc/nginx/conf.d"
|
|
||||||
ACME_DIR="/etc/acme"
|
|
||||||
|
|
||||||
# Helper: Check if nginx is running
|
|
||||||
nginx_running() {
|
|
||||||
pgrep -x nginx > /dev/null 2>&1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Helper: Get nginx status
|
|
||||||
get_nginx_status() {
|
|
||||||
if nginx_running; then
|
|
||||||
echo "running"
|
|
||||||
else
|
|
||||||
echo "stopped"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Helper: Count vhosts
|
|
||||||
count_vhosts() {
|
|
||||||
if [ -d "$NGINX_VHOSTS_DIR" ]; then
|
|
||||||
ls -1 "$NGINX_VHOSTS_DIR"/*.conf 2>/dev/null | wc -l
|
|
||||||
else
|
|
||||||
echo "0"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Helper: List vhosts
|
|
||||||
list_vhosts() {
|
|
||||||
json_add_array "vhosts"
|
|
||||||
|
|
||||||
if [ -d "$NGINX_VHOSTS_DIR" ]; then
|
|
||||||
for conf in "$NGINX_VHOSTS_DIR"/*.conf; do
|
|
||||||
[ -f "$conf" ] || continue
|
|
||||||
|
|
||||||
# Extract server_name from config
|
|
||||||
SERVER_NAME=$(grep -m1 "server_name" "$conf" | awk '{print $2}' | tr -d ';')
|
|
||||||
PROXY_PASS=$(grep -m1 "proxy_pass" "$conf" | awk '{print $2}' | tr -d ';')
|
|
||||||
SSL_ENABLED="false"
|
|
||||||
|
|
||||||
if grep -q "ssl_certificate" "$conf"; then
|
|
||||||
SSL_ENABLED="true"
|
|
||||||
fi
|
|
||||||
|
|
||||||
json_add_object ""
|
|
||||||
json_add_string "name" "$(basename "$conf" .conf)"
|
|
||||||
json_add_string "domain" "$SERVER_NAME"
|
|
||||||
json_add_string "backend" "$PROXY_PASS"
|
|
||||||
json_add_boolean "ssl" "$SSL_ENABLED"
|
|
||||||
json_add_boolean "enabled" 1
|
|
||||||
json_close_object
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
json_close_array
|
|
||||||
}
|
|
||||||
|
|
||||||
# Helper: Get SSL certificates
|
|
||||||
list_certificates() {
|
|
||||||
json_add_array "certificates"
|
|
||||||
|
|
||||||
if [ -d "$ACME_DIR" ]; then
|
|
||||||
for cert_dir in "$ACME_DIR"/*/; do
|
|
||||||
[ -d "$cert_dir" ] || continue
|
|
||||||
|
|
||||||
DOMAIN=$(basename "$cert_dir")
|
|
||||||
CERT_FILE="$cert_dir/fullchain.cer"
|
|
||||||
|
|
||||||
if [ -f "$CERT_FILE" ]; then
|
|
||||||
# Get expiry date
|
|
||||||
EXPIRY=$(openssl x509 -enddate -noout -in "$CERT_FILE" 2>/dev/null | cut -d= -f2)
|
|
||||||
|
|
||||||
json_add_object ""
|
|
||||||
json_add_string "domain" "$DOMAIN"
|
|
||||||
json_add_string "expiry" "$EXPIRY"
|
|
||||||
json_add_boolean "valid" 1
|
|
||||||
json_close_object
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
json_close_array
|
|
||||||
}
|
|
||||||
|
|
||||||
# Initialize JSON
|
|
||||||
json_init
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
list)
|
|
||||||
# List available methods
|
|
||||||
json_add_object "status"
|
|
||||||
json_close_object
|
|
||||||
|
|
||||||
json_add_object "get_vhosts"
|
|
||||||
json_close_object
|
|
||||||
|
|
||||||
json_add_object "get_vhost"
|
|
||||||
json_add_string "name" "string"
|
|
||||||
json_close_object
|
|
||||||
|
|
||||||
json_add_object "add_vhost"
|
|
||||||
json_add_string "domain" "string"
|
|
||||||
json_add_string "backend" "string"
|
|
||||||
json_add_boolean "ssl" false
|
|
||||||
json_close_object
|
|
||||||
|
|
||||||
json_add_object "delete_vhost"
|
|
||||||
json_add_string "name" "string"
|
|
||||||
json_close_object
|
|
||||||
|
|
||||||
json_add_object "get_certificates"
|
|
||||||
json_close_object
|
|
||||||
|
|
||||||
json_add_object "request_certificate"
|
|
||||||
json_add_string "domain" "string"
|
|
||||||
json_close_object
|
|
||||||
|
|
||||||
json_add_object "reload_nginx"
|
|
||||||
json_close_object
|
|
||||||
|
|
||||||
json_add_object "test_config"
|
|
||||||
json_close_object
|
|
||||||
|
|
||||||
json_dump
|
|
||||||
;;
|
|
||||||
|
|
||||||
call)
|
|
||||||
case "$2" in
|
|
||||||
status)
|
|
||||||
# Return module status
|
|
||||||
json_add_string "module" "vhost-manager"
|
|
||||||
json_add_string "version" "2.0.0"
|
|
||||||
json_add_string "nginx_status" "$(get_nginx_status)"
|
|
||||||
json_add_boolean "nginx_running" $(nginx_running && echo 1 || echo 0)
|
|
||||||
json_add_int "vhost_count" "$(count_vhosts)"
|
|
||||||
json_add_string "config_dir" "$NGINX_VHOSTS_DIR"
|
|
||||||
json_add_string "acme_dir" "$ACME_DIR"
|
|
||||||
|
|
||||||
# Check nginx version
|
|
||||||
if command -v nginx > /dev/null 2>&1; then
|
|
||||||
NGINX_VERSION=$(nginx -v 2>&1 | cut -d/ -f2)
|
|
||||||
json_add_string "nginx_version" "$NGINX_VERSION"
|
|
||||||
fi
|
|
||||||
|
|
||||||
json_dump
|
|
||||||
;;
|
|
||||||
|
|
||||||
get_vhosts)
|
|
||||||
# Return list of vhosts
|
|
||||||
list_vhosts
|
|
||||||
json_dump
|
|
||||||
;;
|
|
||||||
|
|
||||||
get_vhost)
|
|
||||||
# Get single vhost details
|
|
||||||
read -r input
|
|
||||||
json_load "$input"
|
|
||||||
json_get_var vhost_name name
|
|
||||||
|
|
||||||
CONF_FILE="$NGINX_VHOSTS_DIR/${vhost_name}.conf"
|
|
||||||
|
|
||||||
if [ -f "$CONF_FILE" ]; then
|
|
||||||
json_add_boolean "found" 1
|
|
||||||
json_add_string "name" "$vhost_name"
|
|
||||||
json_add_string "config" "$(cat "$CONF_FILE")"
|
|
||||||
else
|
|
||||||
json_add_boolean "found" 0
|
|
||||||
json_add_string "error" "VHost not found"
|
|
||||||
fi
|
|
||||||
|
|
||||||
json_dump
|
|
||||||
;;
|
|
||||||
|
|
||||||
add_vhost)
|
|
||||||
# Add new vhost
|
|
||||||
read -r input
|
|
||||||
json_load "$input"
|
|
||||||
json_get_var domain domain
|
|
||||||
json_get_var backend backend
|
|
||||||
json_get_var ssl ssl
|
|
||||||
|
|
||||||
# Validate
|
|
||||||
if [ -z "$domain" ] || [ -z "$backend" ]; then
|
|
||||||
json_init
|
|
||||||
json_add_boolean "success" 0
|
|
||||||
json_add_string "error" "Domain and backend are required"
|
|
||||||
json_dump
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create config
|
|
||||||
VHOST_NAME=$(echo "$domain" | tr '.' '-')
|
|
||||||
CONF_FILE="$NGINX_VHOSTS_DIR/${VHOST_NAME}.conf"
|
|
||||||
|
|
||||||
mkdir -p "$NGINX_VHOSTS_DIR"
|
|
||||||
|
|
||||||
cat > "$CONF_FILE" << NGINX_EOF
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
listen [::]:80;
|
|
||||||
server_name $domain;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass $backend;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Host \$host;
|
|
||||||
proxy_set_header X-Real-IP \$remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
|
||||||
proxy_set_header Upgrade \$http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NGINX_EOF
|
|
||||||
|
|
||||||
json_init
|
|
||||||
json_add_boolean "success" 1
|
|
||||||
json_add_string "message" "VHost created"
|
|
||||||
json_add_string "config_file" "$CONF_FILE"
|
|
||||||
json_dump
|
|
||||||
;;
|
|
||||||
|
|
||||||
delete_vhost)
|
|
||||||
# Delete vhost
|
|
||||||
read -r input
|
|
||||||
json_load "$input"
|
|
||||||
json_get_var vhost_name name
|
|
||||||
|
|
||||||
CONF_FILE="$NGINX_VHOSTS_DIR/${vhost_name}.conf"
|
|
||||||
|
|
||||||
if [ -f "$CONF_FILE" ]; then
|
|
||||||
rm -f "$CONF_FILE"
|
|
||||||
json_init
|
|
||||||
json_add_boolean "success" 1
|
|
||||||
json_add_string "message" "VHost deleted"
|
|
||||||
else
|
|
||||||
json_init
|
|
||||||
json_add_boolean "success" 0
|
|
||||||
json_add_string "error" "VHost not found"
|
|
||||||
fi
|
|
||||||
|
|
||||||
json_dump
|
|
||||||
;;
|
|
||||||
|
|
||||||
get_certificates)
|
|
||||||
# List SSL certificates
|
|
||||||
list_certificates
|
|
||||||
json_dump
|
|
||||||
;;
|
|
||||||
|
|
||||||
request_certificate)
|
|
||||||
# Request Let's Encrypt certificate
|
|
||||||
read -r input
|
|
||||||
json_load "$input"
|
|
||||||
json_get_var domain domain
|
|
||||||
|
|
||||||
if [ -z "$domain" ]; then
|
|
||||||
json_init
|
|
||||||
json_add_boolean "success" 0
|
|
||||||
json_add_string "error" "Domain is required"
|
|
||||||
json_dump
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if acme.sh is available
|
|
||||||
if command -v acme.sh > /dev/null 2>&1; then
|
|
||||||
# Request certificate (async - just start the process)
|
|
||||||
acme.sh --issue -d "$domain" --webroot /www --keylength ec-256 &
|
|
||||||
|
|
||||||
json_init
|
|
||||||
json_add_boolean "success" 1
|
|
||||||
json_add_string "message" "Certificate request started"
|
|
||||||
json_add_string "domain" "$domain"
|
|
||||||
else
|
|
||||||
json_init
|
|
||||||
json_add_boolean "success" 0
|
|
||||||
json_add_string "error" "acme.sh not installed"
|
|
||||||
fi
|
|
||||||
|
|
||||||
json_dump
|
|
||||||
;;
|
|
||||||
|
|
||||||
reload_nginx)
|
|
||||||
# Reload nginx configuration
|
|
||||||
if nginx -t > /dev/null 2>&1; then
|
|
||||||
/etc/init.d/nginx reload
|
|
||||||
json_add_boolean "success" 1
|
|
||||||
json_add_string "message" "Nginx reloaded"
|
|
||||||
else
|
|
||||||
json_add_boolean "success" 0
|
|
||||||
json_add_string "error" "Configuration test failed"
|
|
||||||
json_add_string "details" "$(nginx -t 2>&1)"
|
|
||||||
fi
|
|
||||||
json_dump
|
|
||||||
;;
|
|
||||||
|
|
||||||
test_config)
|
|
||||||
# Test nginx configuration
|
|
||||||
TEST_OUTPUT=$(nginx -t 2>&1)
|
|
||||||
TEST_RESULT=$?
|
|
||||||
|
|
||||||
if [ $TEST_RESULT -eq 0 ]; then
|
|
||||||
json_add_boolean "valid" 1
|
|
||||||
json_add_string "message" "Configuration OK"
|
|
||||||
else
|
|
||||||
json_add_boolean "valid" 0
|
|
||||||
json_add_string "error" "$TEST_OUTPUT"
|
|
||||||
fi
|
|
||||||
json_dump
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
# Unknown method
|
|
||||||
json_add_int "error" -32601
|
|
||||||
json_add_string "message" "Method not found: $2"
|
|
||||||
json_dump
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
echo "Usage: $0 {list|call}"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
Loading…
Reference in New Issue
Block a user