Add boot process assessment doc and service file validation script
Comprehensive assessment of init boot phases, service schema validation, and 14-package audit table covering all hardened boot-critical packages.
This commit is contained in:
Executable
+118
@@ -0,0 +1,118 @@
|
||||
#!/bin/bash
|
||||
# Validate all generated init service files from Red Bear OS config TOMLs.
|
||||
# Checks for:
|
||||
# 1. Valid TOML syntax
|
||||
# 2. Required [unit] section in .service/.target files
|
||||
# 3. Required [service] section with cmd field in .service files
|
||||
# 4. Non-empty data
|
||||
#
|
||||
# Usage: ./local/scripts/validate-service-files.sh [config_dir ...]
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
RB_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
CONFIG_DIR="${1:-$RB_ROOT/config}"
|
||||
|
||||
PASS=0
|
||||
FAIL=0
|
||||
ERRORS=""
|
||||
|
||||
# Use a Python helper to extract [[files]] entries from TOML
|
||||
extract_service_files() {
|
||||
local toml_file="$1"
|
||||
python3 -c "
|
||||
import sys
|
||||
try:
|
||||
import tomllib
|
||||
except ImportError:
|
||||
import tomli as tomllib
|
||||
|
||||
try:
|
||||
with open('${toml_file}', 'rb') as f:
|
||||
data = tomllib.load(f)
|
||||
except Exception as e:
|
||||
print(f'PARSE_ERROR: {e}', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
for entry in data.get('files', []):
|
||||
path = entry.get('path', '')
|
||||
content = entry.get('data', '')
|
||||
if path.endswith('.service') or path.endswith('.target'):
|
||||
safe_content = content.replace('\\\\n', '\\\\\\\\n').replace(chr(10), '\\\\n')
|
||||
print(f'{path}\t{safe_content}')
|
||||
" 2>&1
|
||||
}
|
||||
|
||||
for toml_file in "$CONFIG_DIR"/redbear-*.toml; do
|
||||
[ -f "$toml_file" ] || continue
|
||||
|
||||
BASENAME="$(basename "$toml_file")"
|
||||
|
||||
while IFS=$'\t' read -r file_path file_data_escaped; do
|
||||
[ -n "$file_path" ] || continue
|
||||
|
||||
# Handle TOML parse errors from Python extractor
|
||||
if [[ "$file_path" == PARSE_ERROR:* ]]; then
|
||||
ERRORS="${ERRORS}FAIL: $BASENAME: TOML parse error: ${file_path#PARSE_ERROR:}\n"
|
||||
FAIL=$((FAIL + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
# Decode newlines
|
||||
file_data="$(echo "$file_data_escaped" | sed 's/\\n/\n/g')"
|
||||
|
||||
# Only check .service and .target files
|
||||
case "$file_path" in
|
||||
*.service|*.target) ;;
|
||||
*) continue ;;
|
||||
esac
|
||||
|
||||
# Check 1: No empty data (would cause parse errors)
|
||||
if [ -z "$file_data" ]; then
|
||||
ERRORS="${ERRORS}FAIL: $BASENAME → $file_path: empty data\n"
|
||||
FAIL=$((FAIL + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check 2: Must have [unit] section
|
||||
if ! echo "$file_data" | grep -q '\[unit\]'; then
|
||||
ERRORS="${ERRORS}FAIL: $BASENAME → $file_path: missing [unit] section\n"
|
||||
FAIL=$((FAIL + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check 3: .service files must have [service] section with cmd field
|
||||
case "$file_path" in
|
||||
*.service)
|
||||
if ! echo "$file_data" | grep -q '\[service\]'; then
|
||||
ERRORS="${ERRORS}FAIL: $BASENAME → $file_path: missing [service] section\n"
|
||||
FAIL=$((FAIL + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
if ! echo "$file_data" | grep -q 'cmd[[:space:]]*='; then
|
||||
ERRORS="${ERRORS}FAIL: $BASENAME → $file_path: [service] missing cmd field\n"
|
||||
FAIL=$((FAIL + 1))
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
PASS=$((PASS + 1))
|
||||
done < <(extract_service_files "$toml_file")
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "=== Service File Validation ==="
|
||||
echo "PASS: $PASS"
|
||||
echo "FAIL: $FAIL"
|
||||
|
||||
if [ -n "$ERRORS" ]; then
|
||||
echo ""
|
||||
echo "Errors:"
|
||||
echo -e "$ERRORS"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "All service files valid."
|
||||
exit 0
|
||||
Reference in New Issue
Block a user