fix: resolve 11 test failures, clean up stale files, add NVMe build cache
Test Fixes: - Fixed grep regex matching `test:iso)` instead of `iso|iso:demo)` by using `grep -F` for literal string matching in 3 test files - Increased grep context from -A 5 to -A 15 for FDE reference tests since FDE mention is 9+ lines into the iso command block Stale Files: - Deleted test-iso.sh (merged into run.sh in Session 4) - Deleted verify.sh (orphaned, never referenced anywhere) Documentation: - Fixed stale test file references in COMPLIANCE.md - Updated TEST-COVERAGE.md to remove "delegates to test-iso.sh" - Added JOURNAL.md entry with full audit findings - Updated STATUS.md timestamp NVMe Build Cache (from previous session, was uncommitted): - Added Docker volume `knel-football-cache` for build caching - Added `clean:cache` and `cache` commands to run.sh - Cache preserves bootstrap + package downloads between builds Test Results: 786 pass, 0 fail, 16 VM skip 💘 Generated with Crush Assisted-by: GLM-5.1 via Crush <crush@charm.land>
This commit is contained in:
54
JOURNAL.md
54
JOURNAL.md
@@ -6,6 +6,60 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Entry 2026-05-07 (Session 7): Full Project Audit & Fix
|
||||||
|
|
||||||
|
### Context
|
||||||
|
User requested full project re-orientation. Deep audit of all hooks, tests, docs, and code against PRD.
|
||||||
|
|
||||||
|
### Audit Findings
|
||||||
|
|
||||||
|
#### Test Fixes (11 → 0 failures)
|
||||||
|
- **Root cause**: `grep 'iso)'` regex matched `test:iso)` before `iso|iso:demo)` due to `|` being regex OR
|
||||||
|
- **Fix**: Changed all affected greps to use `grep -F 'iso|iso:demo)'` (literal string match)
|
||||||
|
- **Files fixed**: `tests/unit/build-iso_comprehensive_test.bats` (8), `tests/unit/run_comprehensive_test.bats` (2), `tests/unit/run_test.bats` (1)
|
||||||
|
- Also increased grep context from `-A 5` to `-A 15` for FDE reference tests (content is 9+ lines into iso block)
|
||||||
|
|
||||||
|
#### Stale Files Deleted
|
||||||
|
- `test-iso.sh` - merged into run.sh in Session 4, was still in repo
|
||||||
|
- `verify.sh` - orphaned, never referenced, duplicated `run.sh test`
|
||||||
|
|
||||||
|
#### Documentation Fixes
|
||||||
|
- `docs/TEST-COVERAGE.md` line 23: Updated stale "delegates to test-iso.sh" reference
|
||||||
|
- `docs/COMPLIANCE.md` lines 73-75: Fixed wrong test filenames (firewall_test → firewall-setup_test, etc.)
|
||||||
|
|
||||||
|
#### Uncommitted run.sh Changes (carried over from last session)
|
||||||
|
- Added `CACHE_VOLUME` for NVMe build cache via Docker volume
|
||||||
|
- Added `clean:cache` and `cache` commands
|
||||||
|
- Build cache restore/save around `lb build` for faster iteration
|
||||||
|
- Cache preserves bootstrap + package downloads between builds (~5 min saved)
|
||||||
|
|
||||||
|
### Known Issues Identified (not fixed this session - deferred)
|
||||||
|
|
||||||
|
| Issue | Severity | Notes |
|
||||||
|
|-------|----------|-------|
|
||||||
|
| `firewall-setup.sh` live hook blocks all outbound | High | Static default-deny, no WireGuard allow; live system has no network |
|
||||||
|
| `disable-package-management.sh` destroys dpkg db | High | `rm -rf /var/lib/dpkg/*` breaks anything querying installed packages |
|
||||||
|
| `encryption-validation.sh` inverted conditional | Medium | motd file created only if it already exists (backwards) |
|
||||||
|
| `kernel.exec-shield = 1` in kernel-hardening.sh | Low | Red Hat-specific, doesn't exist on Debian |
|
||||||
|
| `src/build-iso.sh` $VERSION undefined | Medium | Build always reports failure even on success |
|
||||||
|
| NTFS mount needs ntfs-3g but not in package list | Low | USB automount will fail for NTFS drives |
|
||||||
|
| `audispd-plugins` may not exist in Debian 13 | Low | Deprecated/removed from trixie |
|
||||||
|
|
||||||
|
### Test Results
|
||||||
|
```
|
||||||
|
786 tests, 0 failures, 16 VM skips
|
||||||
|
Lint: 0 shellcheck warnings
|
||||||
|
ISO: 824 MB, built 2026-05-01
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verification
|
||||||
|
```bash
|
||||||
|
./run.sh lint # Zero warnings
|
||||||
|
./run.sh test # 786 pass, 0 fail, 16 skip (VM)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Entry 2026-02-20 (Session 6): Security Audit Findings Implementation
|
## Entry 2026-02-20 (Session 6): Security Audit Findings Implementation
|
||||||
|
|
||||||
### Context
|
### Context
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# KNEL-Football Project Status Report
|
# KNEL-Football Project Status Report
|
||||||
|
|
||||||
> **Last Updated**: 2026-05-01 11:20 CDT
|
> **Last Updated**: 2026-05-07 (Session 7 - Full Audit)
|
||||||
> **Maintained By**: AI Agent (Crush)
|
> **Maintained By**: AI Agent (Crush)
|
||||||
> **Purpose**: Quick-glance status for project manager
|
> **Purpose**: Quick-glance status for project manager
|
||||||
|
|
||||||
|
|||||||
@@ -70,9 +70,9 @@ This document maps security compliance requirements to implementation components
|
|||||||
|
|
||||||
| Test Type | Test File | Validation Target | Coverage |
|
| Test Type | Test File | Validation Target | Coverage |
|
||||||
|-----------|------------|-----------------|----------|
|
|-----------|------------|-----------------|----------|
|
||||||
| Unit Tests | `tests/unit/firewall_test.bats` | Firewall configuration parsing | 🔧 |
|
| Unit Tests | `tests/unit/firewall-setup_test.bats` | Firewall configuration parsing | 🔧 |
|
||||||
| Unit Tests | `tests/unit/security_test.bats` | Security hardening functions | 🔧 |
|
| Unit Tests | `tests/unit/security-hardening_test.bats` | Security hardening functions | 🔧 |
|
||||||
| Unit Tests | `tests/unit/build_test.bats` | Build process functions | 🔧 |
|
| Unit Tests | `tests/unit/build-iso_comprehensive_test.bats` | Build process functions | 🔧 |
|
||||||
| Integration Tests | `tests/integration/config_test.bats` | Configuration file validation | 🌐 |
|
| Integration Tests | `tests/integration/config_test.bats` | Configuration file validation | 🌐 |
|
||||||
| Security Tests | `tests/security/compliance_test.bats` | Compliance verification | 🔒 |
|
| Security Tests | `tests/security/compliance_test.bats` | Compliance verification | 🔒 |
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
- run.sh exists and is executable
|
- run.sh exists and is executable
|
||||||
- run.sh shows usage with help command
|
- run.sh shows usage with help command
|
||||||
- run.sh creates output and build directories
|
- run.sh creates output and build directories
|
||||||
- run.sh test:iso delegates to test-iso.sh
|
- run.sh test:iso provides VM testing commands
|
||||||
- run.sh clean removes artifacts
|
- run.sh clean removes artifacts
|
||||||
|
|
||||||
**Lines Covered**: Basic validation and command dispatch
|
**Lines Covered**: Basic validation and command dispatch
|
||||||
|
|||||||
34
run.sh
34
run.sh
@@ -13,6 +13,7 @@ readonly DOCKER_IMAGE="knel-football-dev:latest"
|
|||||||
readonly OUTPUT_DIR="${SCRIPT_DIR}/output"
|
readonly OUTPUT_DIR="${SCRIPT_DIR}/output"
|
||||||
readonly BUILD_DIR="${SCRIPT_DIR}/tmp"
|
readonly BUILD_DIR="${SCRIPT_DIR}/tmp"
|
||||||
readonly BUILD_LOG="/tmp/knel-iso-build.log"
|
readonly BUILD_LOG="/tmp/knel-iso-build.log"
|
||||||
|
readonly CACHE_VOLUME="knel-football-cache"
|
||||||
|
|
||||||
# VM Testing Configuration (system libvirt for virt-manager visibility, /tmp for no sudo)
|
# VM Testing Configuration (system libvirt for virt-manager visibility, /tmp for no sudo)
|
||||||
readonly ISO_PATH="${SCRIPT_DIR}/output/knel-football-secure.iso"
|
readonly ISO_PATH="${SCRIPT_DIR}/output/knel-football-secure.iso"
|
||||||
@@ -854,6 +855,8 @@ Build Commands:
|
|||||||
iso:demo Build demo/CI ISO (hardcoded test credentials, serial console)
|
iso:demo Build demo/CI ISO (hardcoded test credentials, serial console)
|
||||||
monitor [secs] Monitor build progress (default: check every 180s)
|
monitor [secs] Monitor build progress (default: check every 180s)
|
||||||
clean Clean build artifacts
|
clean Clean build artifacts
|
||||||
|
clean:cache Remove NVMe build cache (force full rebuild)
|
||||||
|
cache Show build cache status
|
||||||
|
|
||||||
Test Commands:
|
Test Commands:
|
||||||
test Run all tests
|
test Run all tests
|
||||||
@@ -966,6 +969,18 @@ main() {
|
|||||||
rm -rf "${OUTPUT_DIR:?}"/*
|
rm -rf "${OUTPUT_DIR:?}"/*
|
||||||
rm -rf "${BUILD_DIR:?}"/*
|
rm -rf "${BUILD_DIR:?}"/*
|
||||||
;;
|
;;
|
||||||
|
clean:cache)
|
||||||
|
echo "Removing NVMe build cache (Docker volume: ${CACHE_VOLUME})..."
|
||||||
|
docker volume rm "${CACHE_VOLUME}" 2>/dev/null || echo "Cache volume not found"
|
||||||
|
;;
|
||||||
|
cache)
|
||||||
|
echo "Build cache status (Docker volume: ${CACHE_VOLUME}):"
|
||||||
|
if docker volume inspect "${CACHE_VOLUME}" &>/dev/null; then
|
||||||
|
docker run --rm -v "${CACHE_VOLUME}:/cache" alpine sh -c 'echo "Size: $(du -sh /cache 2>/dev/null | cut -f1)" && ls -la /cache/'
|
||||||
|
else
|
||||||
|
echo "No cache volume exists (will be created on next build)"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
validate)
|
validate)
|
||||||
echo "Running ISO validation..."
|
echo "Running ISO validation..."
|
||||||
"${SCRIPT_DIR}/scripts/validate-iso.sh"
|
"${SCRIPT_DIR}/scripts/validate-iso.sh"
|
||||||
@@ -1003,6 +1018,7 @@ main() {
|
|||||||
--user root \
|
--user root \
|
||||||
-v "${SCRIPT_DIR}:/workspace:ro" \
|
-v "${SCRIPT_DIR}:/workspace:ro" \
|
||||||
-v "${OUTPUT_DIR}:/output" \
|
-v "${OUTPUT_DIR}:/output" \
|
||||||
|
-v "${CACHE_VOLUME}:/cache" \
|
||||||
-e TZ="America/Chicago" \
|
-e TZ="America/Chicago" \
|
||||||
-e DEBIAN_FRONTEND="noninteractive" \
|
-e DEBIAN_FRONTEND="noninteractive" \
|
||||||
-e LC_ALL="C" \
|
-e LC_ALL="C" \
|
||||||
@@ -1044,6 +1060,17 @@ if [ "${KNEL_BUILD_MODE}" = "demo" ]; then
|
|||||||
fi
|
fi
|
||||||
fi &&
|
fi &&
|
||||||
|
|
||||||
|
# Restore build cache from NVMe Docker volume
|
||||||
|
# Preserves bootstrap + package downloads between builds (~5 min saved)
|
||||||
|
if [ -d /cache/bootstrap ]; then
|
||||||
|
echo "Restoring build cache from NVMe..." &&
|
||||||
|
mkdir -p ./cache &&
|
||||||
|
cp -a /cache/* ./cache/ &&
|
||||||
|
echo "Cache restored (bootstrap + packages)"
|
||||||
|
else
|
||||||
|
echo "No build cache found (first build or cache cleared)"
|
||||||
|
fi &&
|
||||||
|
|
||||||
# Create Secure Boot binary hook inline
|
# Create Secure Boot binary hook inline
|
||||||
echo "Creating Secure Boot hook..." &&
|
echo "Creating Secure Boot hook..." &&
|
||||||
mkdir -p config/hooks/binary &&
|
mkdir -p config/hooks/binary &&
|
||||||
@@ -1209,6 +1236,13 @@ chmod +x config/hooks/binary/0200-secureboot-uki.hook &&
|
|||||||
|
|
||||||
echo "Starting ISO build..." &&
|
echo "Starting ISO build..." &&
|
||||||
timeout 3600 lb build &&
|
timeout 3600 lb build &&
|
||||||
|
|
||||||
|
# Save build cache to NVMe Docker volume for next rebuild
|
||||||
|
echo "Saving build cache to NVMe..." &&
|
||||||
|
mkdir -p /cache &&
|
||||||
|
cp -a ./cache/* /cache/ 2>/dev/null || true &&
|
||||||
|
echo "Cache saved (bootstrap + packages)" &&
|
||||||
|
|
||||||
ISO_FILE=$(find . -name "*.iso" -type f | head -1) &&
|
ISO_FILE=$(find . -name "*.iso" -type f | head -1) &&
|
||||||
if [ -n "$ISO_FILE" ]; then
|
if [ -n "$ISO_FILE" ]; then
|
||||||
echo "ISO created: $ISO_FILE"
|
echo "ISO created: $ISO_FILE"
|
||||||
|
|||||||
298
test-iso.sh
298
test-iso.sh
@@ -1,298 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# KNEL-Football ISO Testing Script
|
|
||||||
# Creates and boots a VM using libvirt/virsh to test the ISO
|
|
||||||
# Runs on HOST system (not inside Docker)
|
|
||||||
# Copyright © 2026 Known Element Enterprises LLC
|
|
||||||
# License: GNU Affero General Public License v3.0 only
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
# Configuration variables
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
readonly SCRIPT_DIR
|
|
||||||
_vm_name="knel-test-$(date +%Y%m%d-%H%M%S)"
|
|
||||||
readonly VM_NAME="$_vm_name"
|
|
||||||
readonly ISO_PATH="${SCRIPT_DIR}/output/knel-football-secure-v1.0.0.iso"
|
|
||||||
readonly DISK_SIZE="20G"
|
|
||||||
readonly DISK_PATH="${SCRIPT_DIR}/tmp/${VM_NAME}.qcow2"
|
|
||||||
readonly RAM="4096" # 4GB RAM
|
|
||||||
readonly VCPUS="2"
|
|
||||||
# shellcheck disable=SC2034
|
|
||||||
readonly NETWORK="none"
|
|
||||||
readonly CPU_MODEL="host-model"
|
|
||||||
|
|
||||||
# Colors for output
|
|
||||||
RED='\033[0;31m'
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
YELLOW='\033[1;33m'
|
|
||||||
NC='\033[0m' # No Color
|
|
||||||
|
|
||||||
# Logging functions
|
|
||||||
log_info() {
|
|
||||||
echo -e "${GREEN}[INFO]${NC} $*"
|
|
||||||
}
|
|
||||||
|
|
||||||
log_warn() {
|
|
||||||
echo -e "${YELLOW}[WARN]${NC} $*"
|
|
||||||
}
|
|
||||||
|
|
||||||
log_error() {
|
|
||||||
echo -e "${RED}[ERROR]${NC} $*" >&2
|
|
||||||
}
|
|
||||||
|
|
||||||
# Usage information
|
|
||||||
usage() {
|
|
||||||
cat <<EOF
|
|
||||||
KNEL-Football ISO Tester - Test the ISO in a libvirt VM
|
|
||||||
|
|
||||||
Usage: $0 [COMMAND] [OPTIONS]
|
|
||||||
|
|
||||||
COMMANDS:
|
|
||||||
create Create and start VM with ISO
|
|
||||||
start Start existing VM
|
|
||||||
stop Stop running VM
|
|
||||||
console Connect to VM console
|
|
||||||
destroy Stop and remove VM
|
|
||||||
status Show VM status
|
|
||||||
list List all test VMs
|
|
||||||
|
|
||||||
OPTIONS:
|
|
||||||
-h, --help Show this help message
|
|
||||||
-n, --name Custom VM name (default: auto-generated)
|
|
||||||
-r, --ram RAM in MB (default: 4096)
|
|
||||||
-c, --cpus Number of VCPUs (default: 2)
|
|
||||||
-d, --disk Disk size (default: 20G)
|
|
||||||
|
|
||||||
EXAMPLES:
|
|
||||||
$0 create # Create and start VM
|
|
||||||
$0 create -n my-test -r 8192 # Create with 8GB RAM
|
|
||||||
$0 console # Connect to VM console
|
|
||||||
$0 destroy # Remove VM
|
|
||||||
|
|
||||||
REQUIREMENTS:
|
|
||||||
- libvirt / virsh installed on host
|
|
||||||
- libvirt running
|
|
||||||
- ISO must exist at: ${ISO_PATH}
|
|
||||||
- Sufficient disk space in tmp/
|
|
||||||
|
|
||||||
For more information, see: README.md
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check prerequisites
|
|
||||||
check_prerequisites() {
|
|
||||||
log_info "Checking prerequisites..."
|
|
||||||
|
|
||||||
# Check if virsh is available
|
|
||||||
if ! command -v virsh &> /dev/null; then
|
|
||||||
log_error "virsh not found. Please install libvirt:"
|
|
||||||
echo " Ubuntu/Debian: sudo apt install libvirt-daemon-system virtinst"
|
|
||||||
echo " RHEL/CentOS: sudo yum install libvirt virt-install"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if libvirtd is running
|
|
||||||
if ! virsh list &> /dev/null; then
|
|
||||||
log_error "libvirtd is not running. Please start it:"
|
|
||||||
echo " sudo systemctl start libvirtd"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if ISO exists
|
|
||||||
if [[ ! -f "${ISO_PATH}" ]]; then
|
|
||||||
log_error "ISO not found at: ${ISO_PATH}"
|
|
||||||
log_warn "Please build the ISO first using: ./run.sh iso"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
log_info "Prerequisites check passed"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create VM
|
|
||||||
create_vm() {
|
|
||||||
log_info "Creating VM: ${VM_NAME}"
|
|
||||||
log_info "ISO: ${ISO_PATH}"
|
|
||||||
log_info "Disk: ${DISK_SIZE} (${DISK_PATH})"
|
|
||||||
log_info "RAM: ${RAM} MB, VCPUs: ${VCPUS}"
|
|
||||||
|
|
||||||
# Create disk image
|
|
||||||
log_info "Creating disk image..."
|
|
||||||
qemu-img create -f qcow2 "${DISK_PATH}" "${DISK_SIZE}"
|
|
||||||
|
|
||||||
# Create VM definition
|
|
||||||
log_info "Defining VM..."
|
|
||||||
virt-install \
|
|
||||||
--name "${VM_NAME}" \
|
|
||||||
--memory "${RAM}" \
|
|
||||||
--vcpus "${VCPUS}" \
|
|
||||||
--cpu "${CPU_MODEL}" \
|
|
||||||
--disk path="${DISK_PATH}",format=qcow2,bus=virtio \
|
|
||||||
--cdrom "${ISO_PATH}" \
|
|
||||||
--graphics vnc \
|
|
||||||
--noautoconsole \
|
|
||||||
--os-variant debian12 \
|
|
||||||
--boot cdrom,hd \
|
|
||||||
--metadata description="KNEL-Football Secure OS Test VM"
|
|
||||||
|
|
||||||
log_info "VM created and started successfully"
|
|
||||||
log_info "Connect to console with: $0 console ${VM_NAME}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Start VM
|
|
||||||
start_vm() {
|
|
||||||
log_info "Starting VM: ${VM_NAME}"
|
|
||||||
virsh start "${VM_NAME}"
|
|
||||||
log_info "VM started"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Stop VM
|
|
||||||
stop_vm() {
|
|
||||||
log_info "Stopping VM: ${VM_NAME}"
|
|
||||||
virsh shutdown "${VM_NAME}"
|
|
||||||
log_info "VM shutdown signal sent"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Connect to console
|
|
||||||
connect_console() {
|
|
||||||
log_info "Connecting to VM console: ${VM_NAME}"
|
|
||||||
log_info "Press Ctrl+] to exit console"
|
|
||||||
virsh console "${VM_NAME}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Destroy VM
|
|
||||||
destroy_vm() {
|
|
||||||
log_warn "This will permanently remove VM: ${VM_NAME}"
|
|
||||||
|
|
||||||
# Check if VM is running
|
|
||||||
if virsh domstate "${VM_NAME}" 2>/dev/null | grep -q "running"; then
|
|
||||||
log_info "Stopping VM..."
|
|
||||||
virsh destroy "${VM_NAME}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Undefine VM
|
|
||||||
log_info "Undefining VM..."
|
|
||||||
virsh undefine "${VM_NAME}"
|
|
||||||
|
|
||||||
# Remove disk
|
|
||||||
if [[ -f "${DISK_PATH}" ]]; then
|
|
||||||
log_info "Removing disk: ${DISK_PATH}"
|
|
||||||
rm -f "${DISK_PATH}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
log_info "VM destroyed"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Show VM status
|
|
||||||
show_status() {
|
|
||||||
log_info "VM Status: ${VM_NAME}"
|
|
||||||
|
|
||||||
if ! virsh dominfo "${VM_NAME}" 2>/dev/null; then
|
|
||||||
log_error "VM not found: ${VM_NAME}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
virsh dominfo "${VM_NAME}"
|
|
||||||
echo ""
|
|
||||||
log_info "VM interfaces:"
|
|
||||||
virsh domiflist "${VM_NAME}" || log_warn "No interface information available"
|
|
||||||
}
|
|
||||||
|
|
||||||
# List all test VMs
|
|
||||||
list_vms() {
|
|
||||||
log_info "Listing KNEL-Football test VMs..."
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
virsh list --all | grep "knel-test-" || log_warn "No test VMs found"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
log_info "Disk images:"
|
|
||||||
ls -lh "${SCRIPT_DIR}"/tmp/knel-test-*.qcow2 2>/dev/null || log_warn "No test disk images found"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse command line arguments
|
|
||||||
COMMAND=""
|
|
||||||
CUSTOM_NAME=""
|
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
case $1 in
|
|
||||||
-h | --help)
|
|
||||||
usage
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
-n | --name)
|
|
||||||
CUSTOM_NAME="$2"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
-r | --ram)
|
|
||||||
RAM="$2"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
-c | --cpus)
|
|
||||||
VCPUS="$2"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
-d | --disk)
|
|
||||||
DISK_SIZE="$2"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
create | start | stop | console | destroy | status | list)
|
|
||||||
COMMAND="$1"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
if [[ -z "${COMMAND}" ]]; then
|
|
||||||
log_error "Unknown option: $1"
|
|
||||||
usage
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
# VM name for commands that take it
|
|
||||||
CUSTOM_NAME="$1"
|
|
||||||
shift
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
# Use custom name if provided
|
|
||||||
if [[ -n "${CUSTOM_NAME}" && "${COMMAND}" != "create" ]]; then
|
|
||||||
VM_NAME="${CUSTOM_NAME}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Set default command
|
|
||||||
COMMAND="${COMMAND:-help}"
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
main() {
|
|
||||||
case "${COMMAND}" in
|
|
||||||
create)
|
|
||||||
check_prerequisites
|
|
||||||
create_vm
|
|
||||||
;;
|
|
||||||
start)
|
|
||||||
check_prerequisites
|
|
||||||
start_vm
|
|
||||||
;;
|
|
||||||
stop)
|
|
||||||
check_prerequisites
|
|
||||||
stop_vm
|
|
||||||
;;
|
|
||||||
console)
|
|
||||||
connect_console
|
|
||||||
;;
|
|
||||||
destroy)
|
|
||||||
destroy_vm
|
|
||||||
;;
|
|
||||||
status)
|
|
||||||
show_status
|
|
||||||
;;
|
|
||||||
list)
|
|
||||||
list_vms
|
|
||||||
;;
|
|
||||||
help|*)
|
|
||||||
usage
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
main
|
|
||||||
@@ -237,31 +237,31 @@
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
@test "run.sh iso uses docker run" {
|
@test "run.sh iso uses docker run" {
|
||||||
grep -A 100 'iso)' /workspace/run.sh | grep -q "docker run"
|
grep -A 100 -F 'iso|iso:demo)' /workspace/run.sh | grep -q "docker run"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "run.sh iso runs as root in container" {
|
@test "run.sh iso runs as root in container" {
|
||||||
grep -A 100 'iso)' /workspace/run.sh | grep -q "\-\-user root"
|
grep -A 100 -F 'iso|iso:demo)' /workspace/run.sh | grep -q "\-\-user root"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "run.sh iso uses privileged mode for loop devices" {
|
@test "run.sh iso uses privileged mode for loop devices" {
|
||||||
grep -A 100 'iso)' /workspace/run.sh | grep -q "\-\-privileged"
|
grep -A 100 -F 'iso|iso:demo)' /workspace/run.sh | grep -q "\-\-privileged"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "run.sh iso mounts workspace read-only" {
|
@test "run.sh iso mounts workspace read-only" {
|
||||||
grep -A 100 'iso)' /workspace/run.sh | grep -q "/workspace:ro"
|
grep -A 100 -F 'iso|iso:demo)' /workspace/run.sh | grep -q "/workspace:ro"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "run.sh iso mounts output directory" {
|
@test "run.sh iso mounts output directory" {
|
||||||
grep -A 100 'iso)' /workspace/run.sh | grep -q "/output"
|
grep -A 100 -F 'iso|iso:demo)' /workspace/run.sh | grep -q "/output"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "run.sh iso sets timezone" {
|
@test "run.sh iso sets timezone" {
|
||||||
grep -A 100 'iso)' /workspace/run.sh | grep -q "TZ="
|
grep -A 100 -F 'iso|iso:demo)' /workspace/run.sh | grep -q "TZ="
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "run.sh iso sets noninteractive frontend" {
|
@test "run.sh iso sets noninteractive frontend" {
|
||||||
grep -A 100 'iso)' /workspace/run.sh | grep -q "DEBIAN_FRONTEND"
|
grep -A 100 -F 'iso|iso:demo)' /workspace/run.sh | grep -q "DEBIAN_FRONTEND"
|
||||||
}
|
}
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -285,7 +285,7 @@
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
@test "run.sh iso references host FDE" {
|
@test "run.sh iso references host FDE" {
|
||||||
grep -A 10 'iso)' /workspace/run.sh | grep -qi "fde\|encryption"
|
grep -A 10 -F 'iso|iso:demo)' /workspace/run.sh | grep -qi "fde\|encryption"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "run.sh has check_host_fde function defined" {
|
@test "run.sh has check_host_fde function defined" {
|
||||||
|
|||||||
@@ -182,7 +182,7 @@
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
@test "run.sh iso command uses Docker" {
|
@test "run.sh iso command uses Docker" {
|
||||||
grep -A 50 'iso)' /workspace/run.sh | grep -q "docker run"
|
grep -A 50 -F 'iso|iso:demo)' /workspace/run.sh | grep -q "docker run"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "run.sh test command uses Docker" {
|
@test "run.sh test command uses Docker" {
|
||||||
@@ -307,7 +307,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@test "run.sh iso command references host FDE" {
|
@test "run.sh iso command references host FDE" {
|
||||||
grep -A 5 'iso)' /workspace/run.sh | grep -qi "fde\|encryption"
|
grep -A 15 -F 'iso|iso:demo)' /workspace/run.sh | grep -qi "fde\|encryption"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "run.sh provides clear FDE error message" {
|
@test "run.sh provides clear FDE error message" {
|
||||||
|
|||||||
@@ -132,7 +132,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@test "run.sh references host FDE for iso command" {
|
@test "run.sh references host FDE for iso command" {
|
||||||
grep -A 5 "iso)" /workspace/run.sh | grep -qi "fde\|encryption"
|
grep -A 15 -F 'iso|iso:demo)' /workspace/run.sh | grep -qi "fde\|encryption"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "run.sh has check_host_fde function" {
|
@test "run.sh has check_host_fde function" {
|
||||||
|
|||||||
144
verify.sh
144
verify.sh
@@ -1,144 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Comprehensive project verification script
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
cd "$SCRIPT_DIR"
|
|
||||||
|
|
||||||
PASS=0
|
|
||||||
FAIL=0
|
|
||||||
RESULTS=""
|
|
||||||
|
|
||||||
log_pass() { PASS=$((PASS+1)); RESULTS+=" [PASS] $1\n"; }
|
|
||||||
log_fail() { FAIL=$((FAIL+1)); RESULTS+=" [FAIL] $1\n"; }
|
|
||||||
log_info() { RESULTS+=" [INFO] $1\n"; }
|
|
||||||
|
|
||||||
echo "=== KNEL-Football Project Verification ==="
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# 1. Docker available
|
|
||||||
echo "Phase 1: Environment checks..."
|
|
||||||
if docker info &>/dev/null; then
|
|
||||||
log_pass "Docker daemon running"
|
|
||||||
else
|
|
||||||
log_fail "Docker daemon not running"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 2. Docker image exists
|
|
||||||
if docker images --format '{{.Repository}}' | grep -q 'knel-football-dev'; then
|
|
||||||
log_pass "Docker build image exists"
|
|
||||||
else
|
|
||||||
log_fail "Docker build image missing (run: ./run.sh build)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 3. Lint (warning level only)
|
|
||||||
echo "Phase 2: Lint checks..."
|
|
||||||
LINT_OUTPUT=$(docker run --rm -v "$SCRIPT_DIR":/workspace knel-football-dev:latest bash -c \
|
|
||||||
'shellcheck --severity=warning /workspace/src/*.sh /workspace/config/hooks/installed/*.sh /workspace/config/hooks/live/*.sh' 2>&1 || true)
|
|
||||||
if [ -z "$LINT_OUTPUT" ]; then
|
|
||||||
log_pass "Shellcheck (warning level) clean"
|
|
||||||
else
|
|
||||||
log_fail "Shellcheck warnings found:"
|
|
||||||
echo "$LINT_OUTPUT" | while read -r line; do log_info " $line"; done
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 4. Run full test suite
|
|
||||||
echo "Phase 3: Test suite..."
|
|
||||||
TEST_OUTPUT=$(./run.sh test 2>&1)
|
|
||||||
TEST_COUNT=$(echo "$TEST_OUTPUT" | grep -c "^ok" || true)
|
|
||||||
TEST_FAIL=$(echo "$TEST_OUTPUT" | grep -c "^not ok" || true)
|
|
||||||
if [ "$TEST_FAIL" -eq 0 ]; then
|
|
||||||
log_pass "All $TEST_COUNT tests passing"
|
|
||||||
else
|
|
||||||
log_fail "$TEST_FAIL tests failing out of $((TEST_COUNT+TEST_FAIL))"
|
|
||||||
echo "$TEST_OUTPUT" | grep "^not ok" | while read -r line; do log_info " $line"; done
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 5. ISO artifact check
|
|
||||||
echo "Phase 4: ISO artifact..."
|
|
||||||
if ls output/*.iso &>/dev/null; then
|
|
||||||
ISO_FILE=$(find output -name '*.iso' -type f | head -1)
|
|
||||||
ISO_SIZE=$(du -h "$ISO_FILE" | cut -f1)
|
|
||||||
log_pass "ISO exists: $ISO_FILE ($ISO_SIZE)"
|
|
||||||
# Check checksums
|
|
||||||
if [ -f "${ISO_FILE}.sha256" ]; then
|
|
||||||
log_pass "SHA256 checksum file exists"
|
|
||||||
else
|
|
||||||
log_fail "SHA256 checksum file missing"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
log_info "No ISO artifact found (build with: ./run.sh iso)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 6. VM testing capability
|
|
||||||
echo "Phase 5: VM test capability..."
|
|
||||||
if command -v virsh &>/dev/null; then
|
|
||||||
log_pass "virsh available for VM testing"
|
|
||||||
if virsh list --all &>/dev/null; then
|
|
||||||
log_pass "libvirt daemon accessible"
|
|
||||||
# Check for any existing test VMs
|
|
||||||
EXISTING_VMS=$(virsh list --all --name 2>/dev/null | grep -c 'knel-test' || true)
|
|
||||||
if [ "$EXISTING_VMS" -gt 0 ]; then
|
|
||||||
log_info "Found $EXISTING_VMS existing test VM(s)"
|
|
||||||
else
|
|
||||||
log_info "No existing test VMs"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
log_info "libvirt daemon not accessible (may need sudo/libvirtd group)"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
log_info "virsh not installed - VM testing not available on this host"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 7. Git status
|
|
||||||
echo "Phase 6: Git status..."
|
|
||||||
if git diff --quiet && git diff --cached --quiet; then
|
|
||||||
log_pass "Working tree clean"
|
|
||||||
else
|
|
||||||
log_fail "Uncommitted changes present"
|
|
||||||
fi
|
|
||||||
AHEAD=$(git rev-list --count '@{u}..HEAD' 2>/dev/null || echo "?")
|
|
||||||
log_info "Branch is $AHEAD commit(s) ahead of origin/main"
|
|
||||||
|
|
||||||
# 8. Source file integrity
|
|
||||||
echo "Phase 7: Source file integrity..."
|
|
||||||
for f in src/build-iso.sh src/security-hardening.sh src/firewall-setup.sh; do
|
|
||||||
if [ -f "$f" ] && [ -x "$f" ]; then
|
|
||||||
log_pass "$f exists and is executable"
|
|
||||||
else
|
|
||||||
log_fail "$f missing or not executable"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# 9. Config file integrity
|
|
||||||
echo "Phase 8: Config integrity..."
|
|
||||||
for f in config/preseed.cfg config/hooks/installed/encryption-setup.sh config/hooks/installed/encryption-validation.sh config/hooks/live/security-hardening.sh config/hooks/live/firewall-setup.sh; do
|
|
||||||
if [ -f "$f" ]; then
|
|
||||||
log_pass "$f exists"
|
|
||||||
else
|
|
||||||
log_fail "$f missing"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# 10. Check for Unicode characters that break shellcheck
|
|
||||||
echo "Phase 9: Unicode check..."
|
|
||||||
UNICODE_FILES=$(grep -rl '✓\|✗\|✔\|✘' src/ config/ 2>/dev/null || true)
|
|
||||||
if [ -z "$UNICODE_FILES" ]; then
|
|
||||||
log_pass "No problematic Unicode characters in shell scripts"
|
|
||||||
else
|
|
||||||
log_fail "Unicode characters found in: $UNICODE_FILES"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Summary
|
|
||||||
echo ""
|
|
||||||
echo "=== RESULTS ==="
|
|
||||||
echo -e "$RESULTS"
|
|
||||||
echo ""
|
|
||||||
echo "Summary: $PASS passed, $FAIL failed"
|
|
||||||
if [ "$FAIL" -gt 0 ]; then
|
|
||||||
echo "STATUS: ACTION REQUIRED"
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
echo "STATUS: ALL GOOD"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
Reference in New Issue
Block a user