feat: add comprehensive module validation tooling
Add validate-modules.sh script that validates critical naming conventions and module structure to prevent common RPC and HTTP 404 errors. New validation checks: - RPCD script names must match ubus object names (luci.* prefix) - Menu paths must match view file locations - View files must have corresponding menu entries - RPCD scripts must be executable - JSON files must have valid syntax - ubus objects must follow naming convention Updated CLAUDE.md documentation with: - Critical naming conventions section with examples - Common error patterns and solutions - Updated development workflow to include validation - Enhanced troubleshooting guide for RPC and 404 errors - Updated package structure diagram with correct RPCD naming Added secubox-tools/README.md: - Detailed usage instructions for validation script - Common fixes for naming issues - CI/CD integration examples - Quick reference for critical naming rules This tooling prevents deployment of modules with naming mismatches that cause runtime errors like: - RPC call failed with error -32000: Object not found - HTTP error 404 while loading view files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
16ad6d6a43
commit
92f3318729
163
CLAUDE.md
163
CLAUDE.md
@ -38,6 +38,9 @@ opkg install /tmp/luci-app-*.ipk
|
||||
### Validation
|
||||
|
||||
```bash
|
||||
# Run comprehensive module validation (RECOMMENDED)
|
||||
./secubox-tools/validate-modules.sh
|
||||
|
||||
# Validate shell scripts (RPCD backends)
|
||||
shellcheck luci-app-*/root/usr/libexec/rpcd/*
|
||||
|
||||
@ -71,7 +74,8 @@ luci-app-<module-name>/
|
||||
└── root/
|
||||
├── etc/config/<module-name> # UCI configuration (optional)
|
||||
└── usr/
|
||||
├── libexec/rpcd/<module-name> # RPCD backend script
|
||||
├── libexec/rpcd/
|
||||
│ └── luci.<module-name> # RPCD backend script (MUST use luci. prefix!)
|
||||
└── share/
|
||||
├── luci/menu.d/ # Menu JSON definition
|
||||
│ └── luci-app-<module-name>.json
|
||||
@ -99,6 +103,93 @@ luci-app-<module-name>/
|
||||
- Defines access control for ubus methods
|
||||
- Maps read/write permissions to user groups
|
||||
|
||||
### Critical Naming Conventions
|
||||
|
||||
**IMPORTANT**: The following naming rules are MANDATORY for modules to work correctly:
|
||||
|
||||
#### 1. RPCD Script Must Match ubus Object Name
|
||||
|
||||
The RPCD script filename MUST exactly match the ubus object name used in JavaScript:
|
||||
|
||||
```javascript
|
||||
// In JavaScript (htdocs/luci-static/resources/view/*/):
|
||||
var callStatus = rpc.declare({
|
||||
object: 'luci.cdn-cache', // ← This object name
|
||||
method: 'status'
|
||||
});
|
||||
```
|
||||
|
||||
```bash
|
||||
# RPCD script filename MUST match:
|
||||
root/usr/libexec/rpcd/luci.cdn-cache # ← Must be exactly 'luci.cdn-cache'
|
||||
```
|
||||
|
||||
**Common Error**: If the names don't match, you'll get:
|
||||
- `RPC call to luci.cdn-cache/status failed with error -32000: Object not found`
|
||||
- `Command failed: Method not found`
|
||||
|
||||
**Solution**: All RPCD scripts MUST use the `luci.` prefix:
|
||||
- ✅ Correct: `luci.cdn-cache`, `luci.system-hub`, `luci.wireguard-dashboard`
|
||||
- ❌ Wrong: `cdn-cache`, `system-hub`, `wireguard-dashboard`
|
||||
|
||||
#### 2. Menu Paths Must Match View File Locations
|
||||
|
||||
Menu JSON path entries MUST correspond to actual view files:
|
||||
|
||||
```json
|
||||
// In menu.d/luci-app-netifyd-dashboard.json:
|
||||
{
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "netifyd-dashboard/overview" // ← Must match file location
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
# View file MUST exist at:
|
||||
htdocs/luci-static/resources/view/netifyd-dashboard/overview.js
|
||||
# ↑ Same path as menu ↑
|
||||
```
|
||||
|
||||
**Common Error**: If paths don't match:
|
||||
- `HTTP error 404 while loading class file '/luci-static/resources/view/netifyd/overview.js'`
|
||||
|
||||
**Solution**: Ensure menu paths match directory structure:
|
||||
- ✅ Correct: Menu path `netifyd-dashboard/overview` → file `view/netifyd-dashboard/overview.js`
|
||||
- ❌ Wrong: Menu path `netifyd/overview` → file `view/netifyd-dashboard/overview.js`
|
||||
|
||||
#### 3. ubus Object Naming Convention
|
||||
|
||||
All ubus objects MUST start with `luci.` prefix:
|
||||
|
||||
```javascript
|
||||
// ✅ Correct:
|
||||
object: 'luci.cdn-cache'
|
||||
object: 'luci.system-hub'
|
||||
object: 'luci.wireguard-dashboard'
|
||||
|
||||
// ❌ Wrong:
|
||||
object: 'cdn-cache'
|
||||
object: 'systemhub'
|
||||
```
|
||||
|
||||
#### 4. Validation Before Deployment
|
||||
|
||||
**ALWAYS** run validation before deploying:
|
||||
|
||||
```bash
|
||||
./secubox-tools/validate-modules.sh
|
||||
```
|
||||
|
||||
This script checks:
|
||||
- RPCD script names match ubus objects
|
||||
- Menu paths match view file locations
|
||||
- View files have corresponding menu entries
|
||||
- RPCD scripts are executable
|
||||
- JSON files are valid syntax
|
||||
- ubus objects follow naming convention
|
||||
|
||||
### Makefile Structure
|
||||
|
||||
Each package Makefile must define:
|
||||
@ -244,11 +335,49 @@ x86: x86-64, x86-generic
|
||||
|
||||
## Common Issues and Solutions
|
||||
|
||||
### RPC Errors: "Object not found" or "Method not found"
|
||||
|
||||
**Error**: `RPC call to luci.cdn-cache/status failed with error -32000: Object not found`
|
||||
|
||||
**Cause**: RPCD script name doesn't match ubus object name in JavaScript
|
||||
|
||||
**Solution**:
|
||||
1. Check JavaScript files for ubus object name:
|
||||
```bash
|
||||
grep -r "object:" luci-app-*/htdocs --include="*.js"
|
||||
```
|
||||
2. Rename RPCD script to match exactly (including `luci.` prefix):
|
||||
```bash
|
||||
mv root/usr/libexec/rpcd/cdn-cache root/usr/libexec/rpcd/luci.cdn-cache
|
||||
```
|
||||
3. Restart RPCD on router:
|
||||
```bash
|
||||
/etc/init.d/rpcd restart
|
||||
```
|
||||
|
||||
### HTTP 404 Errors: View Files Not Found
|
||||
|
||||
**Error**: `HTTP error 404 while loading class file '/luci-static/resources/view/netifyd/overview.js'`
|
||||
|
||||
**Cause**: Menu path doesn't match actual view file location
|
||||
|
||||
**Solution**:
|
||||
1. Check menu JSON for path:
|
||||
```bash
|
||||
grep '"path":' root/usr/share/luci/menu.d/*.json
|
||||
```
|
||||
2. Verify view file exists at matching location:
|
||||
```bash
|
||||
ls htdocs/luci-static/resources/view/
|
||||
```
|
||||
3. Update menu path to match file location OR move file to match menu path
|
||||
|
||||
### RPCD Not Responding
|
||||
|
||||
After installing/updating a package:
|
||||
```bash
|
||||
/etc/init.d/rpcd restart
|
||||
/etc/init.d/uhttpd restart
|
||||
```
|
||||
|
||||
### Menu Not Appearing
|
||||
@ -257,30 +386,46 @@ Check that:
|
||||
1. Menu JSON is valid: `jsonlint root/usr/share/luci/menu.d/*.json`
|
||||
2. ACL grants access: Check `root/usr/share/rpcd/acl.d/*.json`
|
||||
3. Dependencies are installed: Check Makefile `LUCI_DEPENDS`
|
||||
4. Menu path matches view file location (see above)
|
||||
|
||||
### Build Failures
|
||||
|
||||
Common causes:
|
||||
1. Missing fields in Makefile (PKG_NAME, LUCI_TITLE, etc.)
|
||||
2. Invalid JSON syntax in menu.d or acl.d
|
||||
3. RPCD script not executable
|
||||
3. RPCD script not executable (chmod +x needed)
|
||||
4. Wrong include path (should be `include ../../luci.mk`)
|
||||
5. RPCD script name doesn't match ubus object (must use `luci.` prefix)
|
||||
|
||||
Use repair tool: `./secubox-tools/secubox-repair.sh`
|
||||
|
||||
### Quick Diagnosis
|
||||
|
||||
Run the validation script to check all naming conventions:
|
||||
```bash
|
||||
./secubox-tools/validate-modules.sh
|
||||
```
|
||||
|
||||
## Development Workflow
|
||||
|
||||
1. Make changes to module files
|
||||
2. Test JSON syntax: `jsonlint <file>.json`
|
||||
3. Test shell scripts: `shellcheck <script>`
|
||||
4. Build package: `make package/luci-app-<name>/compile V=s`
|
||||
5. Install on test router and verify functionality
|
||||
6. Run repair tool if needed: `./secubox-tools/secubox-repair.sh`
|
||||
7. Commit changes and push (triggers CI validation)
|
||||
8. Create tag for release: `git tag -a v1.0.0 -m "Release 1.0.0"`
|
||||
2. **Run validation checks** (CRITICAL):
|
||||
```bash
|
||||
./secubox-tools/validate-modules.sh
|
||||
```
|
||||
3. Test JSON syntax: `jsonlint <file>.json`
|
||||
4. Test shell scripts: `shellcheck <script>`
|
||||
5. Build package: `make package/luci-app-<name>/compile V=s`
|
||||
6. Install on test router and verify functionality
|
||||
7. Run repair tool if needed: `./secubox-tools/secubox-repair.sh`
|
||||
8. Commit changes and push (triggers CI validation)
|
||||
9. Create tag for release: `git tag -a v1.0.0 -m "Release 1.0.0"`
|
||||
|
||||
## Important Notes
|
||||
|
||||
- **CRITICAL**: RPCD script names MUST match ubus object names (use `luci.` prefix)
|
||||
- **CRITICAL**: Menu paths MUST match view file directory structure
|
||||
- **CRITICAL**: Always run `./secubox-tools/validate-modules.sh` before committing
|
||||
- All modules use Apache-2.0 license
|
||||
- RPCD backends must be executable (chmod +x)
|
||||
- JavaScript files use strict mode: `'use strict';`
|
||||
|
||||
130
secubox-tools/README.md
Normal file
130
secubox-tools/README.md
Normal file
@ -0,0 +1,130 @@
|
||||
# SecuBox Development Tools
|
||||
|
||||
This directory contains utilities for validating, debugging, and maintaining SecuBox modules.
|
||||
|
||||
## Tools
|
||||
|
||||
### validate-modules.sh
|
||||
|
||||
Comprehensive validation script that checks all critical naming conventions and module structure.
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
./secubox-tools/validate-modules.sh
|
||||
```
|
||||
|
||||
**Checks performed:**
|
||||
1. **RPCD script names vs ubus objects** - Ensures RPCD script filenames match JavaScript ubus object declarations
|
||||
2. **Menu paths vs view files** - Verifies menu.d JSON paths correspond to actual view files
|
||||
3. **View files have menu entries** - Checks that all view files are referenced in menus
|
||||
4. **RPCD script permissions** - Ensures scripts are executable
|
||||
5. **JSON syntax validation** - Validates all menu.d and acl.d JSON files
|
||||
6. **ubus naming convention** - Verifies all ubus objects use the `luci.` prefix
|
||||
|
||||
**Exit codes:**
|
||||
- `0` - All checks passed (or only warnings)
|
||||
- `1` - Critical errors found
|
||||
|
||||
**Example output:**
|
||||
```
|
||||
✓ luci-app-cdn-cache: RPCD script 'luci.cdn-cache' matches ubus object 'luci.cdn-cache'
|
||||
✓ luci-app-cdn-cache: Menu path 'cdn-cache/overview' → file exists
|
||||
❌ ERROR: luci-app-example: RPCD script 'example' does not match ubus object 'luci.example'
|
||||
```
|
||||
|
||||
### secubox-repair.sh
|
||||
|
||||
Auto-repair tool that fixes common issues in Makefiles and RPCD scripts.
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
./secubox-tools/secubox-repair.sh
|
||||
```
|
||||
|
||||
### secubox-debug.sh
|
||||
|
||||
Validates individual package structure and dependencies.
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
./secubox-tools/secubox-debug.sh luci-app-<module-name>
|
||||
```
|
||||
|
||||
## Recommended Workflow
|
||||
|
||||
Before committing changes:
|
||||
|
||||
1. **Run validation** (CRITICAL):
|
||||
```bash
|
||||
./secubox-tools/validate-modules.sh
|
||||
```
|
||||
|
||||
2. Fix any errors reported
|
||||
|
||||
3. Run shellcheck on RPCD scripts:
|
||||
```bash
|
||||
shellcheck luci-app-*/root/usr/libexec/rpcd/*
|
||||
```
|
||||
|
||||
4. Commit changes
|
||||
|
||||
## Common Fixes
|
||||
|
||||
### Fix RPCD naming mismatch
|
||||
|
||||
If validation reports RPCD script name doesn't match ubus object:
|
||||
|
||||
```bash
|
||||
# Rename the script to include luci. prefix
|
||||
cd luci-app-example/root/usr/libexec/rpcd
|
||||
mv example luci.example
|
||||
```
|
||||
|
||||
### Fix menu path mismatch
|
||||
|
||||
If validation reports menu path doesn't match view file:
|
||||
|
||||
```bash
|
||||
# Option 1: Update menu.d JSON to match file location
|
||||
# Edit: root/usr/share/luci/menu.d/luci-app-example.json
|
||||
# Change: "path": "example/view" → "path": "example-dashboard/view"
|
||||
|
||||
# Option 2: Move view files to match menu path
|
||||
mv htdocs/luci-static/resources/view/example-dashboard \
|
||||
htdocs/luci-static/resources/view/example
|
||||
```
|
||||
|
||||
### Fix non-executable RPCD script
|
||||
|
||||
```bash
|
||||
chmod +x luci-app-example/root/usr/libexec/rpcd/luci.example
|
||||
```
|
||||
|
||||
## Integration with CI/CD
|
||||
|
||||
The validation script can be integrated into GitHub Actions workflows:
|
||||
|
||||
```yaml
|
||||
- name: Validate modules
|
||||
run: |
|
||||
chmod +x secubox-tools/validate-modules.sh
|
||||
./secubox-tools/validate-modules.sh
|
||||
```
|
||||
|
||||
## Critical Naming Rules
|
||||
|
||||
**These rules are MANDATORY** - violations will cause runtime errors:
|
||||
|
||||
1. **RPCD scripts** must be named `luci.<module-name>`
|
||||
- ✅ `luci.cdn-cache`
|
||||
- ❌ `cdn-cache`
|
||||
|
||||
2. **Menu paths** must match view file locations
|
||||
- Menu: `"path": "cdn-cache/overview"`
|
||||
- File: `view/cdn-cache/overview.js`
|
||||
|
||||
3. **ubus objects** must use `luci.` prefix
|
||||
- ✅ `object: 'luci.cdn-cache'`
|
||||
- ❌ `object: 'cdn-cache'`
|
||||
|
||||
See `CLAUDE.md` for complete documentation.
|
||||
255
secubox-tools/validate-modules.sh
Executable file
255
secubox-tools/validate-modules.sh
Executable file
@ -0,0 +1,255 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# SecuBox Module Validation Script
|
||||
# Validates RPCD naming, menu paths, and module structure
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
ERRORS=0
|
||||
WARNINGS=0
|
||||
|
||||
echo "========================================"
|
||||
echo "SecuBox Module Validation"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
# Function to print error
|
||||
error() {
|
||||
echo -e "${RED}❌ ERROR: $1${NC}"
|
||||
((ERRORS++))
|
||||
}
|
||||
|
||||
# Function to print warning
|
||||
warn() {
|
||||
echo -e "${YELLOW}⚠️ WARNING: $1${NC}"
|
||||
((WARNINGS++))
|
||||
}
|
||||
|
||||
# Function to print success
|
||||
success() {
|
||||
echo -e "${GREEN}✓ $1${NC}"
|
||||
}
|
||||
|
||||
# Check 1: RPCD script names must match ubus object names
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "1. Validating RPCD script names vs ubus objects"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
for module_dir in luci-app-*/; do
|
||||
module_name=$(basename "$module_dir")
|
||||
echo "Checking $module_name..."
|
||||
|
||||
# Find RPCD script
|
||||
rpcd_dir="$module_dir/root/usr/libexec/rpcd"
|
||||
if [ -d "$rpcd_dir" ]; then
|
||||
rpcd_script=$(find "$rpcd_dir" -type f ! -name "*.md" 2>/dev/null | head -1)
|
||||
|
||||
if [ -n "$rpcd_script" ]; then
|
||||
rpcd_name=$(basename "$rpcd_script")
|
||||
|
||||
# Extract ubus object names from JavaScript files
|
||||
js_objects=$(find "$module_dir/htdocs" -name "*.js" -type f 2>/dev/null | \
|
||||
xargs grep -h "object:" 2>/dev/null | \
|
||||
grep -o "'[^']*'" | sort -u | tr -d "'")
|
||||
|
||||
if [ -n "$js_objects" ]; then
|
||||
# Check if RPCD script name matches any ubus object
|
||||
match_found=false
|
||||
for obj in $js_objects; do
|
||||
if [ "$rpcd_name" = "$obj" ]; then
|
||||
match_found=true
|
||||
success "$module_name: RPCD script '$rpcd_name' matches ubus object '$obj'"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$match_found" = false ]; then
|
||||
error "$module_name: RPCD script '$rpcd_name' does not match any ubus object(s): $js_objects"
|
||||
echo " → Rename $rpcd_script to one of: $js_objects"
|
||||
fi
|
||||
else
|
||||
warn "$module_name: No ubus object declarations found in JavaScript files"
|
||||
fi
|
||||
else
|
||||
warn "$module_name: No RPCD script found in $rpcd_dir"
|
||||
fi
|
||||
else
|
||||
warn "$module_name: No RPCD directory found"
|
||||
fi
|
||||
echo ""
|
||||
done
|
||||
|
||||
# Check 2: Menu paths must match actual view file locations
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "2. Validating menu paths vs view file locations"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
for module_dir in luci-app-*/; do
|
||||
module_name=$(basename "$module_dir")
|
||||
menu_file="$module_dir/root/usr/share/luci/menu.d/${module_name}.json"
|
||||
|
||||
if [ -f "$menu_file" ]; then
|
||||
echo "Checking $module_name menu paths..."
|
||||
|
||||
# Extract all view paths from menu JSON
|
||||
menu_paths=$(grep -o '"path":\s*"[^"]*"' "$menu_file" | cut -d'"' -f4)
|
||||
|
||||
for path in $menu_paths; do
|
||||
# Convert menu path to file path
|
||||
view_file="$module_dir/htdocs/luci-static/resources/view/${path}.js"
|
||||
|
||||
if [ -f "$view_file" ]; then
|
||||
success "$module_name: Menu path '$path' → file exists"
|
||||
else
|
||||
error "$module_name: Menu path '$path' → file NOT found at $view_file"
|
||||
|
||||
# Suggest possible matches
|
||||
view_dir=$(dirname "$view_file")
|
||||
if [ -d "$view_dir" ]; then
|
||||
echo " → Possible files in $(dirname $path):"
|
||||
find "$view_dir" -name "*.js" -type f | while read -r f; do
|
||||
echo " - $(basename $f)"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
|
||||
# Check 3: View files must have corresponding menu entries
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "3. Validating view files have menu entries"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
for module_dir in luci-app-*/; do
|
||||
module_name=$(basename "$module_dir")
|
||||
view_dir="$module_dir/htdocs/luci-static/resources/view"
|
||||
menu_file="$module_dir/root/usr/share/luci/menu.d/${module_name}.json"
|
||||
|
||||
if [ -d "$view_dir" ] && [ -f "$menu_file" ]; then
|
||||
echo "Checking $module_name view files..."
|
||||
|
||||
# Find all .js view files
|
||||
find "$view_dir" -name "*.js" -type f | while read -r view_file; do
|
||||
# Convert file path to menu path
|
||||
rel_path=$(echo "$view_file" | sed "s|$module_dir/htdocs/luci-static/resources/view/||" | sed 's|.js$||')
|
||||
|
||||
# Check if path exists in menu
|
||||
if grep -q "\"path\":\s*\"$rel_path\"" "$menu_file"; then
|
||||
success "$module_name: View '$rel_path.js' has menu entry"
|
||||
else
|
||||
warn "$module_name: View file '$rel_path.js' exists but has no menu entry"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
|
||||
# Check 4: RPCD scripts must be executable
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "4. Validating RPCD script permissions"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
for module_dir in luci-app-*/; do
|
||||
module_name=$(basename "$module_dir")
|
||||
rpcd_dir="$module_dir/root/usr/libexec/rpcd"
|
||||
|
||||
if [ -d "$rpcd_dir" ]; then
|
||||
find "$rpcd_dir" -type f ! -name "*.md" 2>/dev/null | while read -r script; do
|
||||
if [ -x "$script" ]; then
|
||||
success "$module_name: RPCD script $(basename $script) is executable"
|
||||
else
|
||||
error "$module_name: RPCD script $(basename $script) is NOT executable"
|
||||
echo " → Run: chmod +x $script"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
|
||||
# Check 5: JSON files must be valid
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "5. Validating JSON syntax"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
for module_dir in luci-app-*/; do
|
||||
module_name=$(basename "$module_dir")
|
||||
|
||||
# Check menu JSON
|
||||
menu_file="$module_dir/root/usr/share/luci/menu.d/${module_name}.json"
|
||||
if [ -f "$menu_file" ]; then
|
||||
if python3 -m json.tool "$menu_file" > /dev/null 2>&1; then
|
||||
success "$module_name: menu.d JSON is valid"
|
||||
else
|
||||
error "$module_name: menu.d JSON is INVALID"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check ACL JSON
|
||||
acl_file="$module_dir/root/usr/share/rpcd/acl.d/${module_name}.json"
|
||||
if [ -f "$acl_file" ]; then
|
||||
if python3 -m json.tool "$acl_file" > /dev/null 2>&1; then
|
||||
success "$module_name: acl.d JSON is valid"
|
||||
else
|
||||
error "$module_name: acl.d JSON is INVALID"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
|
||||
# Check 6: Verify ubus object naming convention
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "6. Validating ubus object naming convention"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
for module_dir in luci-app-*/; do
|
||||
module_name=$(basename "$module_dir")
|
||||
|
||||
# Extract ubus object names from JavaScript
|
||||
js_objects=$(find "$module_dir/htdocs" -name "*.js" -type f 2>/dev/null | \
|
||||
xargs grep -h "object:" 2>/dev/null | \
|
||||
grep -o "'[^']*'" | sort -u | tr -d "'")
|
||||
|
||||
if [ -n "$js_objects" ]; then
|
||||
for obj in $js_objects; do
|
||||
# Check if object starts with 'luci.'
|
||||
if [[ $obj == luci.* ]]; then
|
||||
success "$module_name: ubus object '$obj' follows naming convention (luci.* prefix)"
|
||||
else
|
||||
error "$module_name: ubus object '$obj' does NOT follow naming convention (missing luci. prefix)"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
|
||||
# Summary
|
||||
echo "========================================"
|
||||
echo "Validation Summary"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
if [ $ERRORS -eq 0 ] && [ $WARNINGS -eq 0 ]; then
|
||||
echo -e "${GREEN}✓ All checks passed!${NC}"
|
||||
exit 0
|
||||
elif [ $ERRORS -eq 0 ]; then
|
||||
echo -e "${YELLOW}✓ All critical checks passed with $WARNINGS warning(s)${NC}"
|
||||
exit 0
|
||||
else
|
||||
echo -e "${RED}✗ Found $ERRORS error(s) and $WARNINGS warning(s)${NC}"
|
||||
echo ""
|
||||
echo "Please fix the errors listed above before deploying."
|
||||
exit 1
|
||||
fi
|
||||
Loading…
Reference in New Issue
Block a user