working mode
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -27,3 +27,6 @@ go.work.sum
|
|||||||
nannyagent*
|
nannyagent*
|
||||||
nanny-agent*
|
nanny-agent*
|
||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
|
# Build directory
|
||||||
|
build/
|
||||||
|
|||||||
67
Makefile
67
Makefile
@@ -1,16 +1,21 @@
|
|||||||
.PHONY: build run clean test install
|
.PHONY: build run clean test install build-prod build-release install-system fmt lint help
|
||||||
|
|
||||||
|
VERSION := 0.0.1
|
||||||
|
BUILD_DIR := ./build
|
||||||
|
BINARY_NAME := nannyagent
|
||||||
|
|
||||||
# Build the application
|
# Build the application
|
||||||
build:
|
build:
|
||||||
go build -o nanny-agent .
|
go build -o $(BINARY_NAME) .
|
||||||
|
|
||||||
# Run the application
|
# Run the application
|
||||||
run: build
|
run: build
|
||||||
./nanny-agent
|
./$(BINARY_NAME)
|
||||||
|
|
||||||
# Clean build artifacts
|
# Clean build artifacts
|
||||||
clean:
|
clean:
|
||||||
rm -f nanny-agent
|
rm -f $(BINARY_NAME)
|
||||||
|
rm -rf $(BUILD_DIR)
|
||||||
|
|
||||||
# Run tests
|
# Run tests
|
||||||
test:
|
test:
|
||||||
@@ -21,14 +26,34 @@ install:
|
|||||||
go mod tidy
|
go mod tidy
|
||||||
go mod download
|
go mod download
|
||||||
|
|
||||||
# Build for production with optimizations
|
# Build for production with optimizations (current architecture)
|
||||||
build-prod:
|
build-prod:
|
||||||
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-w -s' -o nanny-agent .
|
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo \
|
||||||
|
-ldflags '-w -s -X main.Version=$(VERSION)' \
|
||||||
|
-o $(BINARY_NAME) .
|
||||||
|
|
||||||
|
# Build release binaries for both architectures
|
||||||
|
build-release: clean
|
||||||
|
@echo "Building release binaries for version $(VERSION)..."
|
||||||
|
@mkdir -p $(BUILD_DIR)
|
||||||
|
@echo "Building for linux/amd64..."
|
||||||
|
@CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo \
|
||||||
|
-ldflags '-w -s -X main.Version=$(VERSION)' \
|
||||||
|
-o $(BUILD_DIR)/$(BINARY_NAME)-linux-amd64 .
|
||||||
|
@echo "Building for linux/arm64..."
|
||||||
|
@CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -a -installsuffix cgo \
|
||||||
|
-ldflags '-w -s -X main.Version=$(VERSION)' \
|
||||||
|
-o $(BUILD_DIR)/$(BINARY_NAME)-linux-arm64 .
|
||||||
|
@echo "Generating checksums..."
|
||||||
|
@cd $(BUILD_DIR) && sha256sum $(BINARY_NAME)-linux-amd64 > $(BINARY_NAME)-linux-amd64.sha256
|
||||||
|
@cd $(BUILD_DIR) && sha256sum $(BINARY_NAME)-linux-arm64 > $(BINARY_NAME)-linux-arm64.sha256
|
||||||
|
@echo "Build complete! Artifacts in $(BUILD_DIR)/"
|
||||||
|
@ls -lh $(BUILD_DIR)/
|
||||||
|
|
||||||
# Install system-wide (requires sudo)
|
# Install system-wide (requires sudo)
|
||||||
install-system: build-prod
|
install-system: build-prod
|
||||||
sudo cp nanny-agent /usr/local/bin/
|
sudo cp $(BINARY_NAME) /usr/local/bin/
|
||||||
sudo chmod +x /usr/local/bin/nanny-agent
|
sudo chmod +x /usr/local/bin/$(BINARY_NAME)
|
||||||
|
|
||||||
# Format code
|
# Format code
|
||||||
fmt:
|
fmt:
|
||||||
@@ -40,14 +65,18 @@ lint:
|
|||||||
|
|
||||||
# Show help
|
# Show help
|
||||||
help:
|
help:
|
||||||
@echo "Available commands:"
|
@echo "NannyAgent Makefile - Available commands:"
|
||||||
@echo " build - Build the application"
|
@echo ""
|
||||||
@echo " run - Build and run the application"
|
@echo " make build - Build the application for current platform"
|
||||||
@echo " clean - Clean build artifacts"
|
@echo " make run - Build and run the application"
|
||||||
@echo " test - Run tests"
|
@echo " make clean - Clean build artifacts"
|
||||||
@echo " install - Install dependencies"
|
@echo " make test - Run tests"
|
||||||
@echo " build-prod - Build for production"
|
@echo " make install - Install Go dependencies"
|
||||||
@echo " install-system- Install system-wide (requires sudo)"
|
@echo " make build-prod - Build for production (optimized, current arch)"
|
||||||
@echo " fmt - Format code"
|
@echo " make build-release - Build release binaries for amd64 and arm64"
|
||||||
@echo " lint - Run linter"
|
@echo " make install-system - Install system-wide (requires sudo)"
|
||||||
@echo " help - Show this help"
|
@echo " make fmt - Format code"
|
||||||
|
@echo " make lint - Run linter"
|
||||||
|
@echo " make help - Show this help"
|
||||||
|
@echo ""
|
||||||
|
@echo "Version: $(VERSION)"
|
||||||
|
|||||||
246
README.md
246
README.md
@@ -1,96 +1,135 @@
|
|||||||
# Linux Diagnostic Agent
|
# NannyAgent - Linux Diagnostic Agent
|
||||||
|
|
||||||
A Go-based AI agent that diagnoses Linux system issues using the NannyAPI gateway with OpenAI-compatible SDK.
|
A Go-based AI agent that diagnoses Linux system issues using eBPF-powered deep monitoring and TensorZero AI integration.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Interactive command-line interface for submitting system issues
|
- 🤖 **AI-Powered Diagnostics** - Intelligent issue analysis and resolution planning
|
||||||
- **Automatic system information gathering** - Includes OS, kernel, CPU, memory, network info
|
- 🔍 **eBPF Deep Monitoring** - Real-time kernel-level tracing for network, processes, files, and security events
|
||||||
- **eBPF-powered deep system monitoring** - Advanced tracing for network, processes, files, and security events
|
- 🛡️ **Safe Command Execution** - Validates and executes diagnostic commands with timeouts
|
||||||
- Integrates with NannyAPI using OpenAI-compatible Go SDK
|
- 📊 **Automatic System Information Gathering** - Comprehensive OS, kernel, CPU, memory, and network metrics
|
||||||
- Executes diagnostic commands safely and collects output
|
- 🔄 **WebSocket Integration** - Real-time communication with backend investigation system
|
||||||
- Provides step-by-step resolution plans
|
- 🔐 **OAuth Device Flow Authentication** - Secure agent registration and authentication
|
||||||
- **Comprehensive integration tests** with realistic Linux problem scenarios
|
- ✅ **Comprehensive Integration Tests** - Realistic Linux problem scenarios
|
||||||
|
|
||||||
## Setup
|
## Requirements
|
||||||
|
|
||||||
1. Clone this repository
|
- **Operating System**: Linux only (no containers/LXC support)
|
||||||
2. Copy `.env.example` to `.env` and configure your NannyAPI endpoint:
|
- **Architecture**: amd64 (x86_64) or arm64 (aarch64)
|
||||||
|
- **Kernel Version**: Linux kernel 5.x or higher
|
||||||
|
- **Privileges**: Root/sudo access required for eBPF functionality
|
||||||
|
- **Dependencies**: bpftrace and bpfcc-tools (automatically installed by installer)
|
||||||
|
- **Network**: Connectivity to Supabase backend
|
||||||
|
|
||||||
|
## Quick Installation
|
||||||
|
|
||||||
|
### One-Line Install (Recommended)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Download and run the installer
|
||||||
|
curl -fsSL https://your-domain.com/install.sh | sudo bash
|
||||||
|
```
|
||||||
|
|
||||||
|
Or download first, then install:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Download the installer
|
||||||
|
wget https://your-domain.com/install.sh
|
||||||
|
|
||||||
|
# Make it executable
|
||||||
|
chmod +x install.sh
|
||||||
|
|
||||||
|
# Run the installer
|
||||||
|
sudo ./install.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Manual Installation
|
||||||
|
|
||||||
|
1. Clone this repository:
|
||||||
```bash
|
```bash
|
||||||
cp .env.example .env
|
git clone https://github.com/yourusername/nannyagent.git
|
||||||
|
cd nannyagent
|
||||||
```
|
```
|
||||||
3. Install dependencies:
|
|
||||||
|
2. Run the installer script:
|
||||||
```bash
|
```bash
|
||||||
go mod tidy
|
sudo ./install.sh
|
||||||
```
|
|
||||||
4. Build and run:
|
|
||||||
```bash
|
|
||||||
make build
|
|
||||||
./nanny-agent
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The installer will:
|
||||||
|
- ✅ Verify system requirements (OS, architecture, kernel version)
|
||||||
|
- ✅ Check for existing installations
|
||||||
|
- ✅ Install eBPF tools (bpftrace, bpfcc-tools)
|
||||||
|
- ✅ Build the nannyagent binary
|
||||||
|
- ✅ Test connectivity to Supabase
|
||||||
|
- ✅ Install to `/usr/local/bin/nannyagent`
|
||||||
|
- ✅ Create configuration in `/etc/nannyagent/config.env`
|
||||||
|
- ✅ Create secure data directory `/var/lib/nannyagent`
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
The agent can be configured using environment variables:
|
After installation, configure your Supabase URL:
|
||||||
|
|
||||||
- `NANNYAPI_ENDPOINT`: The NannyAPI endpoint (default: `http://tensorzero.netcup.internal:3000/openai/v1`)
|
```bash
|
||||||
- `NANNYAPI_MODEL`: The model identifier (default: `nannyapi::function_name::diagnose_and_heal`)
|
# Edit the configuration file
|
||||||
|
sudo nano /etc/nannyagent/config.env
|
||||||
|
```
|
||||||
|
|
||||||
## Installation on Linux VM
|
Required configuration:
|
||||||
|
|
||||||
### Direct Installation
|
```bash
|
||||||
|
# Supabase Configuration
|
||||||
|
SUPABASE_PROJECT_URL=https://your-project.supabase.co
|
||||||
|
|
||||||
1. **Install Go** (if not already installed):
|
# Optional Configuration
|
||||||
```bash
|
TOKEN_PATH=/var/lib/nannyagent/token.json
|
||||||
# For Ubuntu/Debian
|
DEBUG=false
|
||||||
sudo apt update
|
```
|
||||||
sudo apt install golang-go
|
|
||||||
|
|
||||||
# For RHEL/CentOS/Fedora
|
## Command-Line Options
|
||||||
sudo dnf install golang
|
|
||||||
# or
|
|
||||||
sudo yum install golang
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Clone and build the agent**:
|
```bash
|
||||||
```bash
|
# Show version (no sudo required)
|
||||||
git clone <your-repo-url>
|
nannyagent --version
|
||||||
cd nannyagentv2
|
nannyagent -v
|
||||||
go mod tidy
|
|
||||||
make build
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Install as system service** (optional):
|
# Show help (no sudo required)
|
||||||
```bash
|
nannyagent --help
|
||||||
sudo cp nanny-agent /usr/local/bin/
|
nannyagent -h
|
||||||
sudo chmod +x /usr/local/bin/nanny-agent
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Set environment variables**:
|
# Run the agent (requires sudo)
|
||||||
```bash
|
sudo nannyagent
|
||||||
export NANNYAPI_ENDPOINT="http://your-nannyapi-endpoint:3000/openai/v1"
|
```
|
||||||
export NANNYAPI_MODEL="your-model-identifier"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
1. Start the agent:
|
1. **First-time Setup** - Authenticate the agent:
|
||||||
```bash
|
```bash
|
||||||
./nanny-agent
|
sudo nannyagent
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The agent will display a verification URL and code. Visit the URL and enter the code to authorize the agent.
|
||||||
|
|
||||||
2. Enter a system issue description when prompted:
|
2. **Interactive Diagnostics** - After authentication, enter system issues:
|
||||||
```
|
```
|
||||||
> On /var filesystem I cannot create any file but df -h shows 30% free space available.
|
> On /var filesystem I cannot create any file but df -h shows 30% free space available.
|
||||||
```
|
```
|
||||||
|
|
||||||
3. The agent will:
|
3. **The agent will**:
|
||||||
- Send the issue to the AI via NannyAPI using OpenAI SDK
|
- Gather comprehensive system information automatically
|
||||||
- Execute diagnostic commands as suggested by the AI
|
- Send the issue to AI for analysis via TensorZero
|
||||||
- Provide command outputs back to the AI
|
- Execute diagnostic commands safely
|
||||||
- Display the final diagnosis and resolution plan
|
- Run eBPF traces for deep kernel-level monitoring
|
||||||
|
- Provide AI-generated root cause analysis and resolution plan
|
||||||
|
|
||||||
4. Type `quit` or `exit` to stop the agent
|
4. **Exit the agent**:
|
||||||
|
```
|
||||||
|
> quit
|
||||||
|
```
|
||||||
|
or
|
||||||
|
```
|
||||||
|
> exit
|
||||||
|
```
|
||||||
|
|
||||||
## How It Works
|
## How It Works
|
||||||
|
|
||||||
@@ -119,14 +158,87 @@ The agent includes comprehensive integration tests that simulate realistic Linux
|
|||||||
|
|
||||||
### Run Integration Tests:
|
### Run Integration Tests:
|
||||||
```bash
|
```bash
|
||||||
# Interactive test scenarios
|
# Run unit tests
|
||||||
./test-examples.sh
|
make test
|
||||||
|
|
||||||
# Automated integration tests
|
# Run integration tests
|
||||||
./integration-tests.sh
|
./tests/test_ebpf_integration.sh
|
||||||
|
```
|
||||||
|
|
||||||
# Function discovery (find valid NannyAPI functions)
|
## Installation Exit Codes
|
||||||
./discover-functions.sh
|
|
||||||
|
The installer uses specific exit codes for different failure scenarios:
|
||||||
|
|
||||||
|
| Exit Code | Description |
|
||||||
|
|-----------|-------------|
|
||||||
|
| 0 | Success |
|
||||||
|
| 1 | Not running as root |
|
||||||
|
| 2 | Unsupported operating system (non-Linux) |
|
||||||
|
| 3 | Unsupported architecture (not amd64/arm64) |
|
||||||
|
| 4 | Container/LXC environment detected |
|
||||||
|
| 5 | Kernel version < 5.x |
|
||||||
|
| 6 | Existing installation detected |
|
||||||
|
| 7 | eBPF tools installation failed |
|
||||||
|
| 8 | Go not installed |
|
||||||
|
| 9 | Binary build failed |
|
||||||
|
| 10 | Directory creation failed |
|
||||||
|
| 11 | Binary installation failed |
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Installation Issues
|
||||||
|
|
||||||
|
**Error: "Kernel version X.X is not supported"**
|
||||||
|
- NannyAgent requires Linux kernel 5.x or higher
|
||||||
|
- Upgrade your kernel or use a different system
|
||||||
|
|
||||||
|
**Error: "Another instance may already be installed"**
|
||||||
|
- Check if `/var/lib/nannyagent` exists
|
||||||
|
- Remove it if you're sure: `sudo rm -rf /var/lib/nannyagent`
|
||||||
|
- Then retry installation
|
||||||
|
|
||||||
|
**Warning: "Cannot connect to Supabase"**
|
||||||
|
- Check your network connectivity
|
||||||
|
- Verify firewall settings allow HTTPS connections
|
||||||
|
- Ensure SUPABASE_PROJECT_URL is correctly configured in `/etc/nannyagent/config.env`
|
||||||
|
|
||||||
|
### Runtime Issues
|
||||||
|
|
||||||
|
**Error: "This program must be run as root"**
|
||||||
|
- eBPF requires root privileges
|
||||||
|
- Always run with: `sudo nannyagent`
|
||||||
|
|
||||||
|
**Error: "Cannot determine kernel version"**
|
||||||
|
- Ensure `uname` command is available
|
||||||
|
- Check system integrity
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Building from Source
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone repository
|
||||||
|
git clone https://github.com/yourusername/nannyagent.git
|
||||||
|
cd nannyagent
|
||||||
|
|
||||||
|
# Install Go dependencies
|
||||||
|
go mod tidy
|
||||||
|
|
||||||
|
# Build binary
|
||||||
|
make build
|
||||||
|
|
||||||
|
# Run locally (requires sudo)
|
||||||
|
sudo ./nannyagent
|
||||||
|
```
|
||||||
|
|
||||||
|
### Running Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run unit tests
|
||||||
|
make test
|
||||||
|
|
||||||
|
# Test eBPF capabilities
|
||||||
|
./tests/test_ebpf_integration.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
## Safety
|
## Safety
|
||||||
|
|||||||
22
agent.go
22
agent.go
@@ -54,18 +54,13 @@ func NewLinuxDiagnosticAgent() *LinuxDiagnosticAgent {
|
|||||||
supabaseURL := os.Getenv("SUPABASE_PROJECT_URL")
|
supabaseURL := os.Getenv("SUPABASE_PROJECT_URL")
|
||||||
if supabaseURL == "" {
|
if supabaseURL == "" {
|
||||||
logging.Warning("SUPABASE_PROJECT_URL not set, TensorZero integration will not work")
|
logging.Warning("SUPABASE_PROJECT_URL not set, TensorZero integration will not work")
|
||||||
supabaseURL = "https://gpqzsricripnvbrpsyws.supabase.co" // fallback
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model := os.Getenv("NANNYAPI_MODEL")
|
// Default model for diagnostic and healing
|
||||||
if model == "" {
|
model := "tensorzero::function_name::diagnose_and_heal"
|
||||||
model = "tensorzero::function_name::diagnose_and_heal"
|
|
||||||
logging.Warning("Using default model '%s'. Set NANNYAPI_MODEL environment variable for your specific function", model)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: We don't use the OpenAI client anymore, we use direct HTTP to Supabase proxy
|
|
||||||
agent := &LinuxDiagnosticAgent{
|
agent := &LinuxDiagnosticAgent{
|
||||||
client: nil, // Not used anymore
|
client: nil, // Not used - we use direct HTTP to Supabase proxy
|
||||||
model: model,
|
model: model,
|
||||||
executor: executor.NewCommandExecutor(10 * time.Second), // 10 second timeout for commands
|
executor: executor.NewCommandExecutor(10 * time.Second), // 10 second timeout for commands
|
||||||
config: DefaultAgentConfig(), // Default concurrent execution config
|
config: DefaultAgentConfig(), // Default concurrent execution config
|
||||||
@@ -84,18 +79,13 @@ func NewLinuxDiagnosticAgentWithAuth(authManager interface{}) *LinuxDiagnosticAg
|
|||||||
supabaseURL := os.Getenv("SUPABASE_PROJECT_URL")
|
supabaseURL := os.Getenv("SUPABASE_PROJECT_URL")
|
||||||
if supabaseURL == "" {
|
if supabaseURL == "" {
|
||||||
logging.Warning("SUPABASE_PROJECT_URL not set, TensorZero integration will not work")
|
logging.Warning("SUPABASE_PROJECT_URL not set, TensorZero integration will not work")
|
||||||
supabaseURL = "https://gpqzsricripnvbrpsyws.supabase.co" // fallback
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model := os.Getenv("NANNYAPI_MODEL")
|
// Default model for diagnostic and healing
|
||||||
if model == "" {
|
model := "tensorzero::function_name::diagnose_and_heal"
|
||||||
model = "tensorzero::function_name::diagnose_and_heal"
|
|
||||||
logging.Warning("Using default model '%s'. Set NANNYAPI_MODEL environment variable for your specific function", model)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: We don't use the OpenAI client anymore, we use direct HTTP to Supabase proxy
|
|
||||||
agent := &LinuxDiagnosticAgent{
|
agent := &LinuxDiagnosticAgent{
|
||||||
client: nil, // Not used anymore
|
client: nil, // Not used - we use direct HTTP to Supabase proxy
|
||||||
model: model,
|
model: model,
|
||||||
executor: executor.NewCommandExecutor(10 * time.Second), // 10 second timeout for commands
|
executor: executor.NewCommandExecutor(10 * time.Second), // 10 second timeout for commands
|
||||||
config: DefaultAgentConfig(), // Default concurrent execution config
|
config: DefaultAgentConfig(), // Default concurrent execution config
|
||||||
|
|||||||
334
docs/INSTALLATION.md
Normal file
334
docs/INSTALLATION.md
Normal file
@@ -0,0 +1,334 @@
|
|||||||
|
# NannyAgent Installation Guide
|
||||||
|
|
||||||
|
## Quick Install
|
||||||
|
|
||||||
|
### One-Line Install (Recommended)
|
||||||
|
|
||||||
|
After uploading `install.sh` to your website:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://your-domain.com/install.sh | sudo bash
|
||||||
|
```
|
||||||
|
|
||||||
|
Or with wget:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wget -qO- https://your-domain.com/install.sh | sudo bash
|
||||||
|
```
|
||||||
|
|
||||||
|
### Two-Step Install (More Secure)
|
||||||
|
|
||||||
|
Download and inspect the installer first:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Download the installer
|
||||||
|
curl -fsSL https://your-domain.com/install.sh -o install.sh
|
||||||
|
|
||||||
|
# Inspect the script (recommended!)
|
||||||
|
less install.sh
|
||||||
|
|
||||||
|
# Make it executable
|
||||||
|
chmod +x install.sh
|
||||||
|
|
||||||
|
# Run the installer
|
||||||
|
sudo ./install.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Installation from GitHub
|
||||||
|
|
||||||
|
If you're hosting on GitHub:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/yourusername/nannyagent/main/install.sh | sudo bash
|
||||||
|
```
|
||||||
|
|
||||||
|
## System Requirements
|
||||||
|
|
||||||
|
Before installing, ensure your system meets these requirements:
|
||||||
|
|
||||||
|
### Operating System
|
||||||
|
- ✅ Linux (any distribution)
|
||||||
|
- ❌ Windows (not supported)
|
||||||
|
- ❌ macOS (not supported)
|
||||||
|
- ❌ Containers/Docker (not supported)
|
||||||
|
- ❌ LXC (not supported)
|
||||||
|
|
||||||
|
### Architecture
|
||||||
|
- ✅ amd64 (x86_64)
|
||||||
|
- ✅ arm64 (aarch64)
|
||||||
|
- ❌ i386/i686 (32-bit not supported)
|
||||||
|
- ❌ Other architectures (not supported)
|
||||||
|
|
||||||
|
### Kernel Version
|
||||||
|
- ✅ Linux kernel 5.x or higher
|
||||||
|
- ❌ Linux kernel 4.x or lower (not supported)
|
||||||
|
|
||||||
|
Check your kernel version:
|
||||||
|
```bash
|
||||||
|
uname -r
|
||||||
|
# Should show 5.x.x or higher
|
||||||
|
```
|
||||||
|
|
||||||
|
### Privileges
|
||||||
|
- Must have root/sudo access
|
||||||
|
- Will create system directories:
|
||||||
|
- `/usr/local/bin/nannyagent` (binary)
|
||||||
|
- `/etc/nannyagent` (configuration)
|
||||||
|
- `/var/lib/nannyagent` (data directory)
|
||||||
|
|
||||||
|
### Network
|
||||||
|
- Connectivity to Supabase backend required
|
||||||
|
- HTTPS access to your Supabase project URL
|
||||||
|
- No proxy support at this time
|
||||||
|
|
||||||
|
## What the Installer Does
|
||||||
|
|
||||||
|
The installer performs these steps automatically:
|
||||||
|
|
||||||
|
1. ✅ **System Checks**
|
||||||
|
- Verifies root privileges
|
||||||
|
- Detects OS and architecture
|
||||||
|
- Checks kernel version (5.x+)
|
||||||
|
- Detects container environments
|
||||||
|
- Checks for existing installations
|
||||||
|
|
||||||
|
2. ✅ **Dependency Installation**
|
||||||
|
- Installs `bpftrace` (eBPF tracing tool)
|
||||||
|
- Installs `bpfcc-tools` (BCC toolkit)
|
||||||
|
- Installs kernel headers if needed
|
||||||
|
- Uses your system's package manager (apt/dnf/yum)
|
||||||
|
|
||||||
|
3. ✅ **Build & Install**
|
||||||
|
- Verifies Go installation (required for building)
|
||||||
|
- Compiles the nannyagent binary
|
||||||
|
- Tests connectivity to Supabase
|
||||||
|
- Installs binary to `/usr/local/bin`
|
||||||
|
|
||||||
|
4. ✅ **Configuration**
|
||||||
|
- Creates `/etc/nannyagent/config.env`
|
||||||
|
- Creates `/var/lib/nannyagent` data directory
|
||||||
|
- Sets proper permissions (secure)
|
||||||
|
- Creates installation lock file
|
||||||
|
|
||||||
|
## Installation Exit Codes
|
||||||
|
|
||||||
|
The installer exits with specific codes for different scenarios:
|
||||||
|
|
||||||
|
| Exit Code | Meaning | Resolution |
|
||||||
|
|-----------|---------|------------|
|
||||||
|
| 0 | Success | Installation completed |
|
||||||
|
| 1 | Not root | Run with `sudo` |
|
||||||
|
| 2 | Unsupported OS | Use Linux |
|
||||||
|
| 3 | Unsupported architecture | Use amd64 or arm64 |
|
||||||
|
| 4 | Container detected | Install on bare metal or VM |
|
||||||
|
| 5 | Kernel too old | Upgrade to kernel 5.x+ |
|
||||||
|
| 6 | Existing installation | Remove `/var/lib/nannyagent` first |
|
||||||
|
| 7 | eBPF tools failed | Check package manager and repos |
|
||||||
|
| 8 | Go not installed | Install Go from golang.org |
|
||||||
|
| 9 | Build failed | Check Go installation and dependencies |
|
||||||
|
| 10 | Directory creation failed | Check permissions |
|
||||||
|
| 11 | Binary installation failed | Check disk space and permissions |
|
||||||
|
|
||||||
|
## Post-Installation
|
||||||
|
|
||||||
|
After successful installation:
|
||||||
|
|
||||||
|
### 1. Configure Supabase URL
|
||||||
|
|
||||||
|
Edit the configuration file:
|
||||||
|
```bash
|
||||||
|
sudo nano /etc/nannyagent/config.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Set your Supabase project URL:
|
||||||
|
```bash
|
||||||
|
SUPABASE_PROJECT_URL=https://your-project.supabase.co
|
||||||
|
TOKEN_PATH=/var/lib/nannyagent/token.json
|
||||||
|
DEBUG=false
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Test the Installation
|
||||||
|
|
||||||
|
Check version (no sudo needed):
|
||||||
|
```bash
|
||||||
|
nannyagent --version
|
||||||
|
```
|
||||||
|
|
||||||
|
Show help (no sudo needed):
|
||||||
|
```bash
|
||||||
|
nannyagent --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Run the Agent
|
||||||
|
|
||||||
|
Start the agent (requires sudo):
|
||||||
|
```bash
|
||||||
|
sudo nannyagent
|
||||||
|
```
|
||||||
|
|
||||||
|
On first run, you'll see authentication instructions:
|
||||||
|
```
|
||||||
|
Visit: https://your-app.com/device-auth
|
||||||
|
Enter code: ABCD-1234
|
||||||
|
```
|
||||||
|
|
||||||
|
## Uninstallation
|
||||||
|
|
||||||
|
To remove NannyAgent:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Remove binary
|
||||||
|
sudo rm /usr/local/bin/nannyagent
|
||||||
|
|
||||||
|
# Remove configuration
|
||||||
|
sudo rm -rf /etc/nannyagent
|
||||||
|
|
||||||
|
# Remove data directory (includes authentication tokens)
|
||||||
|
sudo rm -rf /var/lib/nannyagent
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### "Kernel version X.X is not supported"
|
||||||
|
|
||||||
|
Your kernel is too old. Check current version:
|
||||||
|
```bash
|
||||||
|
uname -r
|
||||||
|
```
|
||||||
|
|
||||||
|
Options:
|
||||||
|
1. Upgrade your kernel to 5.x or higher
|
||||||
|
2. Use a different system with a newer kernel
|
||||||
|
3. Check your distribution's documentation for kernel upgrades
|
||||||
|
|
||||||
|
### "Another instance may already be installed"
|
||||||
|
|
||||||
|
The installer detected an existing installation. Options:
|
||||||
|
|
||||||
|
**Option 1:** Remove the existing installation
|
||||||
|
```bash
|
||||||
|
sudo rm -rf /var/lib/nannyagent
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option 2:** Check if it's actually running
|
||||||
|
```bash
|
||||||
|
ps aux | grep nannyagent
|
||||||
|
```
|
||||||
|
|
||||||
|
If running, stop it first, then remove the data directory.
|
||||||
|
|
||||||
|
### "Cannot connect to Supabase"
|
||||||
|
|
||||||
|
This is a warning, not an error. The installation will complete, but the agent won't work without connectivity.
|
||||||
|
|
||||||
|
Check:
|
||||||
|
1. Is SUPABASE_PROJECT_URL set correctly?
|
||||||
|
```bash
|
||||||
|
cat /etc/nannyagent/config.env
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Can you reach the URL?
|
||||||
|
```bash
|
||||||
|
curl -I https://your-project.supabase.co
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Check firewall rules:
|
||||||
|
```bash
|
||||||
|
sudo iptables -L -n | grep -i drop
|
||||||
|
```
|
||||||
|
|
||||||
|
### "Go is not installed"
|
||||||
|
|
||||||
|
The installer requires Go to build the binary. Install Go:
|
||||||
|
|
||||||
|
**Ubuntu/Debian:**
|
||||||
|
```bash
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install golang-go
|
||||||
|
```
|
||||||
|
|
||||||
|
**RHEL/CentOS/Fedora:**
|
||||||
|
```bash
|
||||||
|
sudo dnf install golang
|
||||||
|
```
|
||||||
|
|
||||||
|
Or download from: https://golang.org/dl/
|
||||||
|
|
||||||
|
### "eBPF tools installation failed"
|
||||||
|
|
||||||
|
Check your package repositories:
|
||||||
|
|
||||||
|
**Ubuntu/Debian:**
|
||||||
|
```bash
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install bpfcc-tools bpftrace
|
||||||
|
```
|
||||||
|
|
||||||
|
**RHEL/Fedora:**
|
||||||
|
```bash
|
||||||
|
sudo dnf install bcc-tools bpftrace
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
### Permissions
|
||||||
|
|
||||||
|
The installer creates directories with restricted permissions:
|
||||||
|
- `/etc/nannyagent` - 755 (readable by all, writable by root)
|
||||||
|
- `/etc/nannyagent/config.env` - 600 (only root can read/write)
|
||||||
|
- `/var/lib/nannyagent` - 700 (only root can access)
|
||||||
|
|
||||||
|
### Authentication Tokens
|
||||||
|
|
||||||
|
Authentication tokens are stored securely in:
|
||||||
|
```
|
||||||
|
/var/lib/nannyagent/token.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Only root can access this file (permissions: 600).
|
||||||
|
|
||||||
|
### Network Communication
|
||||||
|
|
||||||
|
All communication with Supabase uses HTTPS (TLS encrypted).
|
||||||
|
|
||||||
|
## Manual Installation (Alternative)
|
||||||
|
|
||||||
|
If you prefer manual installation:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Clone repository
|
||||||
|
git clone https://github.com/yourusername/nannyagent.git
|
||||||
|
cd nannyagent
|
||||||
|
|
||||||
|
# 2. Install eBPF tools (Ubuntu/Debian)
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install bpfcc-tools bpftrace linux-headers-$(uname -r)
|
||||||
|
|
||||||
|
# 3. Build binary
|
||||||
|
go mod tidy
|
||||||
|
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-w -s' -o nannyagent .
|
||||||
|
|
||||||
|
# 4. Install
|
||||||
|
sudo cp nannyagent /usr/local/bin/
|
||||||
|
sudo chmod 755 /usr/local/bin/nannyagent
|
||||||
|
|
||||||
|
# 5. Create directories
|
||||||
|
sudo mkdir -p /etc/nannyagent
|
||||||
|
sudo mkdir -p /var/lib/nannyagent
|
||||||
|
sudo chmod 700 /var/lib/nannyagent
|
||||||
|
|
||||||
|
# 6. Create configuration
|
||||||
|
sudo cat > /etc/nannyagent/config.env <<EOF
|
||||||
|
SUPABASE_PROJECT_URL=https://your-project.supabase.co
|
||||||
|
TOKEN_PATH=/var/lib/nannyagent/token.json
|
||||||
|
DEBUG=false
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo chmod 600 /etc/nannyagent/config.env
|
||||||
|
```
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
For issues or questions:
|
||||||
|
- GitHub Issues: https://github.com/yourusername/nannyagent/issues
|
||||||
|
- Documentation: https://github.com/yourusername/nannyagent/docs
|
||||||
403
install.sh
Executable file
403
install.sh
Executable file
@@ -0,0 +1,403 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# NannyAgent Installer Script
|
||||||
|
# Version: 0.0.1
|
||||||
|
# Description: Installs NannyAgent Linux diagnostic tool with eBPF capabilities
|
||||||
|
|
||||||
|
VERSION="0.0.1"
|
||||||
|
INSTALL_DIR="/usr/local/bin"
|
||||||
|
CONFIG_DIR="/etc/nannyagent"
|
||||||
|
DATA_DIR="/var/lib/nannyagent"
|
||||||
|
BINARY_NAME="nannyagent"
|
||||||
|
LOCKFILE="${DATA_DIR}/.nannyagent.lock"
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Logging functions
|
||||||
|
log_info() {
|
||||||
|
echo -e "${BLUE}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_success() {
|
||||||
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_warning() {
|
||||||
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if running as root
|
||||||
|
check_root() {
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
log_error "This installer must be run as root"
|
||||||
|
log_info "Please run: sudo bash install.sh"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Detect OS and architecture
|
||||||
|
detect_platform() {
|
||||||
|
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
|
||||||
|
ARCH=$(uname -m)
|
||||||
|
|
||||||
|
log_info "Detected OS: $OS"
|
||||||
|
log_info "Detected Architecture: $ARCH"
|
||||||
|
|
||||||
|
# Check if OS is Linux
|
||||||
|
if [ "$OS" != "linux" ]; then
|
||||||
|
log_error "Unsupported operating system: $OS"
|
||||||
|
log_error "This installer only supports Linux"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if architecture is supported (amd64 or arm64)
|
||||||
|
case "$ARCH" in
|
||||||
|
x86_64|amd64)
|
||||||
|
ARCH="amd64"
|
||||||
|
;;
|
||||||
|
aarch64|arm64)
|
||||||
|
ARCH="arm64"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_error "Unsupported architecture: $ARCH"
|
||||||
|
log_error "Only amd64 (x86_64) and arm64 (aarch64) are supported"
|
||||||
|
exit 3
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Check if running in container/LXC
|
||||||
|
if [ -f /.dockerenv ] || grep -q docker /proc/1/cgroup 2>/dev/null; then
|
||||||
|
log_error "Container environment detected (Docker)"
|
||||||
|
log_error "NannyAgent does not support running inside containers or LXC"
|
||||||
|
exit 4
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f /proc/1/environ ] && grep -q "container=lxc" /proc/1/environ 2>/dev/null; then
|
||||||
|
log_error "LXC environment detected"
|
||||||
|
log_error "NannyAgent does not support running inside containers or LXC"
|
||||||
|
exit 4
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check kernel version (5.x or higher)
|
||||||
|
check_kernel_version() {
|
||||||
|
log_info "Checking kernel version..."
|
||||||
|
|
||||||
|
KERNEL_VERSION=$(uname -r)
|
||||||
|
KERNEL_MAJOR=$(echo "$KERNEL_VERSION" | cut -d. -f1)
|
||||||
|
|
||||||
|
log_info "Kernel version: $KERNEL_VERSION"
|
||||||
|
|
||||||
|
if [ "$KERNEL_MAJOR" -lt 5 ]; then
|
||||||
|
log_error "Kernel version $KERNEL_VERSION is not supported"
|
||||||
|
log_error "NannyAgent requires Linux kernel 5.x or higher"
|
||||||
|
log_error "Current kernel: $KERNEL_VERSION (major version: $KERNEL_MAJOR)"
|
||||||
|
exit 5
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_success "Kernel version $KERNEL_VERSION is supported"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if another instance is already installed
|
||||||
|
check_existing_installation() {
|
||||||
|
log_info "Checking for existing installation..."
|
||||||
|
|
||||||
|
# Check if lock file exists
|
||||||
|
if [ -f "$LOCKFILE" ]; then
|
||||||
|
log_error "An installation lock file exists at $LOCKFILE"
|
||||||
|
log_error "Another instance of NannyAgent may already be installed or running"
|
||||||
|
log_error "If you're sure no other instance exists, remove the lock file:"
|
||||||
|
log_error " sudo rm $LOCKFILE"
|
||||||
|
exit 6
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if data directory exists and has files
|
||||||
|
if [ -d "$DATA_DIR" ]; then
|
||||||
|
FILE_COUNT=$(find "$DATA_DIR" -type f 2>/dev/null | wc -l)
|
||||||
|
if [ "$FILE_COUNT" -gt 0 ]; then
|
||||||
|
log_error "Data directory $DATA_DIR already exists with $FILE_COUNT files"
|
||||||
|
log_error "Another instance of NannyAgent may already be installed"
|
||||||
|
log_error "To reinstall, please remove the data directory first:"
|
||||||
|
log_error " sudo rm -rf $DATA_DIR"
|
||||||
|
exit 6
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if binary already exists
|
||||||
|
if [ -f "$INSTALL_DIR/$BINARY_NAME" ]; then
|
||||||
|
log_warning "Binary $INSTALL_DIR/$BINARY_NAME already exists"
|
||||||
|
log_warning "It will be replaced with the new version"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_success "No conflicting installation found"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install required dependencies (eBPF tools)
|
||||||
|
install_dependencies() {
|
||||||
|
log_info "Installing eBPF dependencies..."
|
||||||
|
|
||||||
|
# Detect package manager
|
||||||
|
if command -v apt-get &> /dev/null; then
|
||||||
|
PKG_MANAGER="apt-get"
|
||||||
|
log_info "Detected Debian/Ubuntu system"
|
||||||
|
|
||||||
|
# Update package list
|
||||||
|
log_info "Updating package list..."
|
||||||
|
apt-get update -qq || {
|
||||||
|
log_error "Failed to update package list"
|
||||||
|
exit 7
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install bpfcc-tools and bpftrace
|
||||||
|
log_info "Installing bpfcc-tools and bpftrace..."
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq bpfcc-tools bpftrace linux-headers-$(uname -r) 2>&1 | grep -v "^Reading" | grep -v "^Building" || {
|
||||||
|
log_error "Failed to install eBPF tools"
|
||||||
|
exit 7
|
||||||
|
}
|
||||||
|
|
||||||
|
elif command -v dnf &> /dev/null; then
|
||||||
|
PKG_MANAGER="dnf"
|
||||||
|
log_info "Detected Fedora/RHEL 8+ system"
|
||||||
|
|
||||||
|
log_info "Installing bcc-tools and bpftrace..."
|
||||||
|
dnf install -y -q bcc-tools bpftrace kernel-devel 2>&1 | grep -v "^Last metadata" || {
|
||||||
|
log_error "Failed to install eBPF tools"
|
||||||
|
exit 7
|
||||||
|
}
|
||||||
|
|
||||||
|
elif command -v yum &> /dev/null; then
|
||||||
|
PKG_MANAGER="yum"
|
||||||
|
log_info "Detected CentOS/RHEL 7 system"
|
||||||
|
|
||||||
|
log_info "Installing bcc-tools and bpftrace..."
|
||||||
|
yum install -y -q bcc-tools bpftrace kernel-devel 2>&1 | grep -v "^Loaded plugins" || {
|
||||||
|
log_error "Failed to install eBPF tools"
|
||||||
|
exit 7
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
log_error "Unsupported package manager"
|
||||||
|
log_error "Please install 'bpfcc-tools' and 'bpftrace' manually"
|
||||||
|
exit 7
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify installations
|
||||||
|
if ! command -v bpftrace &> /dev/null; then
|
||||||
|
log_error "bpftrace installation failed or not in PATH"
|
||||||
|
exit 7
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for BCC tools (RedHat systems may have them in /usr/share/bcc/tools/)
|
||||||
|
if [ -d "/usr/share/bcc/tools" ]; then
|
||||||
|
log_info "BCC tools found at /usr/share/bcc/tools/"
|
||||||
|
# Add to PATH if not already there
|
||||||
|
if [[ ":$PATH:" != *":/usr/share/bcc/tools:"* ]]; then
|
||||||
|
export PATH="/usr/share/bcc/tools:$PATH"
|
||||||
|
log_info "Added /usr/share/bcc/tools to PATH"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_success "eBPF tools installed successfully"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check Go installation
|
||||||
|
check_go() {
|
||||||
|
log_info "Checking for Go installation..."
|
||||||
|
|
||||||
|
if ! command -v go &> /dev/null; then
|
||||||
|
log_error "Go is not installed"
|
||||||
|
log_error "Please install Go 1.23 or higher from https://golang.org/dl/"
|
||||||
|
exit 8
|
||||||
|
fi
|
||||||
|
|
||||||
|
GO_VERSION=$(go version | awk '{print $3}' | sed 's/go//')
|
||||||
|
log_info "Go version: $GO_VERSION"
|
||||||
|
log_success "Go is installed"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build the binary
|
||||||
|
build_binary() {
|
||||||
|
log_info "Building NannyAgent binary for $ARCH architecture..."
|
||||||
|
|
||||||
|
# Check if go.mod exists
|
||||||
|
if [ ! -f "go.mod" ]; then
|
||||||
|
log_error "go.mod not found. Are you in the correct directory?"
|
||||||
|
exit 9
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get Go dependencies
|
||||||
|
log_info "Downloading Go dependencies..."
|
||||||
|
go mod download || {
|
||||||
|
log_error "Failed to download Go dependencies"
|
||||||
|
exit 9
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build the binary for the current architecture
|
||||||
|
log_info "Compiling binary for $ARCH..."
|
||||||
|
CGO_ENABLED=0 GOOS=linux GOARCH="$ARCH" go build -a -installsuffix cgo \
|
||||||
|
-ldflags "-w -s -X main.Version=$VERSION" \
|
||||||
|
-o "$BINARY_NAME" . || {
|
||||||
|
log_error "Failed to build binary for $ARCH"
|
||||||
|
exit 9
|
||||||
|
}
|
||||||
|
|
||||||
|
# Verify binary was created
|
||||||
|
if [ ! -f "$BINARY_NAME" ]; then
|
||||||
|
log_error "Binary not found after build"
|
||||||
|
exit 9
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify binary is executable
|
||||||
|
chmod +x "$BINARY_NAME"
|
||||||
|
|
||||||
|
# Test the binary
|
||||||
|
if ./"$BINARY_NAME" --version &>/dev/null; then
|
||||||
|
log_success "Binary built and tested successfully for $ARCH"
|
||||||
|
else
|
||||||
|
log_error "Binary build succeeded but execution test failed"
|
||||||
|
exit 9
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check connectivity to Supabase
|
||||||
|
check_connectivity() {
|
||||||
|
log_info "Checking connectivity to Supabase..."
|
||||||
|
|
||||||
|
# Load SUPABASE_PROJECT_URL from .env if it exists
|
||||||
|
if [ -f ".env" ]; then
|
||||||
|
source .env 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$SUPABASE_PROJECT_URL" ]; then
|
||||||
|
log_warning "SUPABASE_PROJECT_URL not set in .env file"
|
||||||
|
log_warning "The agent may not work without proper configuration"
|
||||||
|
log_warning "Please configure $CONFIG_DIR/config.env after installation"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_info "Testing connection to $SUPABASE_PROJECT_URL..."
|
||||||
|
|
||||||
|
# Try to reach the Supabase endpoint
|
||||||
|
if command -v curl &> /dev/null; then
|
||||||
|
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 "$SUPABASE_PROJECT_URL" || echo "000")
|
||||||
|
|
||||||
|
if [ "$HTTP_CODE" = "000" ]; then
|
||||||
|
log_warning "Cannot connect to $SUPABASE_PROJECT_URL"
|
||||||
|
log_warning "Network connectivity issue detected"
|
||||||
|
log_warning "The agent will not work without connectivity to Supabase"
|
||||||
|
log_warning "Please check your network configuration and firewall settings"
|
||||||
|
elif [ "$HTTP_CODE" = "404" ] || [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "301" ] || [ "$HTTP_CODE" = "302" ]; then
|
||||||
|
log_success "Successfully connected to Supabase (HTTP $HTTP_CODE)"
|
||||||
|
else
|
||||||
|
log_warning "Received HTTP $HTTP_CODE from $SUPABASE_PROJECT_URL"
|
||||||
|
log_warning "The agent may not work correctly"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_warning "curl not found, skipping connectivity check"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create necessary directories
|
||||||
|
create_directories() {
|
||||||
|
log_info "Creating directories..."
|
||||||
|
|
||||||
|
# Create config directory
|
||||||
|
mkdir -p "$CONFIG_DIR" || {
|
||||||
|
log_error "Failed to create config directory: $CONFIG_DIR"
|
||||||
|
exit 10
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create data directory with restricted permissions
|
||||||
|
mkdir -p "$DATA_DIR" || {
|
||||||
|
log_error "Failed to create data directory: $DATA_DIR"
|
||||||
|
exit 10
|
||||||
|
}
|
||||||
|
chmod 700 "$DATA_DIR"
|
||||||
|
|
||||||
|
log_success "Directories created successfully"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install the binary
|
||||||
|
install_binary() {
|
||||||
|
log_info "Installing binary to $INSTALL_DIR..."
|
||||||
|
|
||||||
|
# Copy binary
|
||||||
|
cp "$BINARY_NAME" "$INSTALL_DIR/$BINARY_NAME" || {
|
||||||
|
log_error "Failed to copy binary to $INSTALL_DIR"
|
||||||
|
exit 11
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set permissions
|
||||||
|
chmod 755 "$INSTALL_DIR/$BINARY_NAME"
|
||||||
|
|
||||||
|
# Copy .env to config if it exists
|
||||||
|
if [ -f ".env" ]; then
|
||||||
|
log_info "Copying configuration to $CONFIG_DIR..."
|
||||||
|
cp .env "$CONFIG_DIR/config.env"
|
||||||
|
chmod 600 "$CONFIG_DIR/config.env"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create lock file
|
||||||
|
touch "$LOCKFILE"
|
||||||
|
echo "Installed at $(date)" > "$LOCKFILE"
|
||||||
|
|
||||||
|
log_success "Binary installed successfully"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Display post-installation information
|
||||||
|
post_install_info() {
|
||||||
|
echo ""
|
||||||
|
log_success "NannyAgent v$VERSION installed successfully!"
|
||||||
|
echo ""
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
echo " Configuration: $CONFIG_DIR/config.env"
|
||||||
|
echo " Data Directory: $DATA_DIR"
|
||||||
|
echo " Binary Location: $INSTALL_DIR/$BINARY_NAME"
|
||||||
|
echo ""
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
echo "Next steps:"
|
||||||
|
echo ""
|
||||||
|
echo " 1. Configure your Supabase URL in $CONFIG_DIR/config.env"
|
||||||
|
echo " 2. Run the agent: sudo $BINARY_NAME"
|
||||||
|
echo " 3. Check version: $BINARY_NAME --version"
|
||||||
|
echo " 4. Get help: $BINARY_NAME --help"
|
||||||
|
echo ""
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main installation flow
|
||||||
|
main() {
|
||||||
|
echo ""
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo " NannyAgent Installer v$VERSION"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
check_root
|
||||||
|
detect_platform
|
||||||
|
check_kernel_version
|
||||||
|
check_existing_installation
|
||||||
|
install_dependencies
|
||||||
|
check_go
|
||||||
|
build_binary
|
||||||
|
check_connectivity
|
||||||
|
create_directories
|
||||||
|
install_binary
|
||||||
|
post_install_info
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run main installation
|
||||||
|
main
|
||||||
@@ -37,16 +37,40 @@ var DefaultConfig = Config{
|
|||||||
func LoadConfig() (*Config, error) {
|
func LoadConfig() (*Config, error) {
|
||||||
config := DefaultConfig
|
config := DefaultConfig
|
||||||
|
|
||||||
// Try to load .env file from current directory or parent directories
|
// Priority order for loading configuration:
|
||||||
envFile := findEnvFile()
|
// 1. /etc/nannyagent/config.env (system-wide installation)
|
||||||
if envFile != "" {
|
// 2. Current directory .env file (development)
|
||||||
if err := godotenv.Load(envFile); err != nil {
|
// 3. Parent directory .env file (development)
|
||||||
logging.Warning("Could not load .env file from %s: %v", envFile, err)
|
|
||||||
|
configLoaded := false
|
||||||
|
|
||||||
|
// Try system-wide config first
|
||||||
|
if _, err := os.Stat("/etc/nannyagent/config.env"); err == nil {
|
||||||
|
if err := godotenv.Load("/etc/nannyagent/config.env"); err != nil {
|
||||||
|
logging.Warning("Could not load /etc/nannyagent/config.env: %v", err)
|
||||||
} else {
|
} else {
|
||||||
logging.Info("Loaded configuration from %s", envFile)
|
logging.Info("Loaded configuration from /etc/nannyagent/config.env")
|
||||||
|
configLoaded = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If system config not found, try local .env file
|
||||||
|
if !configLoaded {
|
||||||
|
envFile := findEnvFile()
|
||||||
|
if envFile != "" {
|
||||||
|
if err := godotenv.Load(envFile); err != nil {
|
||||||
|
logging.Warning("Could not load .env file from %s: %v", envFile, err)
|
||||||
|
} else {
|
||||||
|
logging.Info("Loaded configuration from %s", envFile)
|
||||||
|
configLoaded = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !configLoaded {
|
||||||
|
logging.Warning("No configuration file found. Using environment variables only.")
|
||||||
|
}
|
||||||
|
|
||||||
// Load from environment variables
|
// Load from environment variables
|
||||||
if url := os.Getenv("SUPABASE_PROJECT_URL"); url != "" {
|
if url := os.Getenv("SUPABASE_PROJECT_URL"); url != "" {
|
||||||
config.SupabaseProjectURL = url
|
config.SupabaseProjectURL = url
|
||||||
|
|||||||
81
main.go
81
main.go
@@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
@@ -19,7 +20,48 @@ import (
|
|||||||
"nannyagentv2/internal/websocket"
|
"nannyagentv2/internal/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
const Version = "v2.0.0"
|
const Version = "0.0.1"
|
||||||
|
|
||||||
|
// showVersion displays the version information
|
||||||
|
func showVersion() {
|
||||||
|
fmt.Printf("nannyagent version %s\n", Version)
|
||||||
|
fmt.Println("Linux diagnostic agent with eBPF capabilities")
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// showHelp displays the help information
|
||||||
|
func showHelp() {
|
||||||
|
fmt.Println("NannyAgent - Linux Diagnostic Agent with eBPF Monitoring")
|
||||||
|
fmt.Printf("Version: %s\n\n", Version)
|
||||||
|
fmt.Println("USAGE:")
|
||||||
|
fmt.Printf(" sudo %s [OPTIONS]\n\n", os.Args[0])
|
||||||
|
fmt.Println("OPTIONS:")
|
||||||
|
fmt.Println(" --version, -v Show version information")
|
||||||
|
fmt.Println(" --help, -h Show this help message")
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("DESCRIPTION:")
|
||||||
|
fmt.Println(" NannyAgent is an AI-powered Linux diagnostic tool that uses eBPF")
|
||||||
|
fmt.Println(" for deep system monitoring and analysis. It requires root privileges")
|
||||||
|
fmt.Println(" to run for eBPF functionality.")
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("REQUIREMENTS:")
|
||||||
|
fmt.Println(" - Linux kernel 5.x or higher")
|
||||||
|
fmt.Println(" - Root privileges (sudo)")
|
||||||
|
fmt.Println(" - bpftrace and bpfcc-tools installed")
|
||||||
|
fmt.Println(" - Network connectivity to Supabase")
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("CONFIGURATION:")
|
||||||
|
fmt.Println(" Configuration file: /etc/nannyagent/config.env")
|
||||||
|
fmt.Println(" Data directory: /var/lib/nannyagent")
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("EXAMPLES:")
|
||||||
|
fmt.Printf(" # Run the agent\n")
|
||||||
|
fmt.Printf(" sudo %s\n\n", os.Args[0])
|
||||||
|
fmt.Printf(" # Show version (no sudo required)\n")
|
||||||
|
fmt.Printf(" %s --version\n\n", os.Args[0])
|
||||||
|
fmt.Println("For more information, visit: https://github.com/yourusername/nannyagent")
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
// checkRootPrivileges ensures the program is running as root
|
// checkRootPrivileges ensures the program is running as root
|
||||||
func checkRootPrivileges() {
|
func checkRootPrivileges() {
|
||||||
@@ -31,7 +73,7 @@ func checkRootPrivileges() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkKernelVersionCompatibility ensures kernel version is 4.4 or higher
|
// checkKernelVersionCompatibility ensures kernel version is 5.x or higher
|
||||||
func checkKernelVersionCompatibility() {
|
func checkKernelVersionCompatibility() {
|
||||||
output, err := exec.Command("uname", "-r").Output()
|
output, err := exec.Command("uname", "-r").Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -54,18 +96,12 @@ func checkKernelVersionCompatibility() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
minor, err := strconv.Atoi(parts[1])
|
// Check if kernel is 5.x or higher
|
||||||
if err != nil {
|
if major < 5 {
|
||||||
logging.Error("Cannot parse minor kernel version: %s", parts[1])
|
logging.Error("Kernel version %s is not supported", kernelVersion)
|
||||||
os.Exit(1)
|
logging.Error("Required: Linux kernel 5.x or higher")
|
||||||
}
|
logging.Error("Current: %s (major version: %d)", kernelVersion, major)
|
||||||
|
logging.Error("Reason: NannyAgent requires modern kernel features:\n - Advanced eBPF capabilities\n - BTF (BPF Type Format) support\n - Enhanced security and stability")
|
||||||
// Check if kernel is 4.4 or higher
|
|
||||||
if major < 4 || (major == 4 && minor < 4) {
|
|
||||||
logging.Error("Kernel version %s is too old for eBPF", kernelVersion)
|
|
||||||
logging.Error("Required: Linux kernel 4.4 or higher")
|
|
||||||
logging.Error("Current: %s", kernelVersion)
|
|
||||||
logging.Error("Reason: eBPF requires kernel features introduced in 4.4+:\n - BPF system call support\n - eBPF program types (kprobe, tracepoint)\n - BPF maps and helper functions")
|
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,6 +162,23 @@ func runInteractiveDiagnostics(agent *LinuxDiagnosticAgent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
// Define flags with both long and short versions
|
||||||
|
versionFlag := flag.Bool("version", false, "Show version information")
|
||||||
|
versionFlagShort := flag.Bool("v", false, "Show version information (short)")
|
||||||
|
helpFlag := flag.Bool("help", false, "Show help information")
|
||||||
|
helpFlagShort := flag.Bool("h", false, "Show help information (short)")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
// Handle --version or -v flag (no root required)
|
||||||
|
if *versionFlag || *versionFlagShort {
|
||||||
|
showVersion()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle --help or -h flag (no root required)
|
||||||
|
if *helpFlag || *helpFlagShort {
|
||||||
|
showHelp()
|
||||||
|
}
|
||||||
|
|
||||||
logging.Info("NannyAgent v%s starting...", Version)
|
logging.Info("NannyAgent v%s starting...", Version)
|
||||||
|
|
||||||
// Perform system compatibility checks first
|
// Perform system compatibility checks first
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Test the current script generation
|
|
||||||
echo "Testing tracepoint script generation..."
|
|
||||||
|
|
||||||
# Simulate what the failing test does
|
|
||||||
echo "Target: syscalls:sys_enter_openat"
|
|
||||||
echo "ProbeType: t"
|
|
||||||
echo ""
|
|
||||||
echo "Generated bpftrace script would be:"
|
|
||||||
echo "tracepoint:syscalls:sys_enter_openat {"
|
|
||||||
echo " printf(\"TRACE|%d|%d|%d|%s|syscalls:sys_enter_openat|file access\\n\", nsecs, pid, tid, comm, arg2@user);"
|
|
||||||
echo "}"
|
|
||||||
echo ""
|
|
||||||
echo "This is INVALID - should be:"
|
|
||||||
echo "tracepoint:syscalls:sys_enter_openat {"
|
|
||||||
echo " printf(\"TRACE|%d|%d|%d|%s|openat|file access\\n\", nsecs, pid, tid, comm);"
|
|
||||||
echo "}"
|
|
||||||
|
|
||||||
@@ -1,141 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Test the eBPF-enhanced NannyAgent
|
|
||||||
# This script demonstrates the new eBPF integration capabilities
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "🔬 Testing eBPF-Enhanced NannyAgent"
|
|
||||||
echo "=================================="
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
AGENT="./nannyagent-ebpf"
|
|
||||||
|
|
||||||
if [ ! -f "$AGENT" ]; then
|
|
||||||
echo "Building agent..."
|
|
||||||
go build -o nannyagent-ebpf .
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "1. Checking eBPF Capabilities"
|
|
||||||
echo "-----------------------------"
|
|
||||||
./ebpf_helper.sh check
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "2. Testing eBPF Manager Initialization"
|
|
||||||
echo "-------------------------------------"
|
|
||||||
echo "Starting agent in test mode..."
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Create a test script that will send a predefined issue to test eBPF
|
|
||||||
cat > /tmp/test_ebpf_issue.txt << 'EOF'
|
|
||||||
Network connection timeouts to external services. Applications report intermittent failures when trying to connect to remote APIs. The issue occurs randomly and affects multiple processes.
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo "Test Issue: Network connection timeouts"
|
|
||||||
echo "Expected eBPF Programs: Network tracing, syscall monitoring"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "3. Demonstration of eBPF Program Suggestions"
|
|
||||||
echo "-------------------------------------------"
|
|
||||||
|
|
||||||
# Show what eBPF programs would be suggested for different issues
|
|
||||||
echo "For NETWORK issues - Expected eBPF programs:"
|
|
||||||
echo "- tracepoint:syscalls/sys_enter_connect (network connections)"
|
|
||||||
echo "- kprobe:tcp_connect (TCP connection attempts)"
|
|
||||||
echo "- kprobe:tcp_sendmsg (network send operations)"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "For PROCESS issues - Expected eBPF programs:"
|
|
||||||
echo "- tracepoint:syscalls/sys_enter_execve (process execution)"
|
|
||||||
echo "- tracepoint:sched/sched_process_exit (process termination)"
|
|
||||||
echo "- kprobe:do_fork (process creation)"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "For FILE issues - Expected eBPF programs:"
|
|
||||||
echo "- tracepoint:syscalls/sys_enter_openat (file opens)"
|
|
||||||
echo "- kprobe:vfs_read (file reads)"
|
|
||||||
echo "- kprobe:vfs_write (file writes)"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "For PERFORMANCE issues - Expected eBPF programs:"
|
|
||||||
echo "- tracepoint:syscalls/sys_enter_* (syscall frequency analysis)"
|
|
||||||
echo "- kprobe:schedule (CPU scheduling events)"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "4. eBPF Integration Features"
|
|
||||||
echo "---------------------------"
|
|
||||||
echo "✓ Cilium eBPF library integration"
|
|
||||||
echo "✓ bpftrace-based program execution"
|
|
||||||
echo "✓ Dynamic program generation based on issue type"
|
|
||||||
echo "✓ Parallel execution with regular diagnostic commands"
|
|
||||||
echo "✓ Structured JSON event collection"
|
|
||||||
echo "✓ AI-driven eBPF program selection"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "5. Example AI Response with eBPF"
|
|
||||||
echo "-------------------------------"
|
|
||||||
cat << 'EOF'
|
|
||||||
{
|
|
||||||
"response_type": "diagnostic",
|
|
||||||
"reasoning": "Network timeout issues require monitoring TCP connections and system calls to identify bottlenecks",
|
|
||||||
"commands": [
|
|
||||||
{"id": "net_status", "command": "ss -tulpn", "description": "Current network connections"},
|
|
||||||
{"id": "net_config", "command": "ip route show", "description": "Network configuration"}
|
|
||||||
],
|
|
||||||
"ebpf_programs": [
|
|
||||||
{
|
|
||||||
"name": "tcp_connect_monitor",
|
|
||||||
"type": "kprobe",
|
|
||||||
"target": "tcp_connect",
|
|
||||||
"duration": 15,
|
|
||||||
"description": "Monitor TCP connection attempts"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "syscall_network",
|
|
||||||
"type": "tracepoint",
|
|
||||||
"target": "syscalls/sys_enter_connect",
|
|
||||||
"duration": 15,
|
|
||||||
"filters": {"comm": "curl"},
|
|
||||||
"description": "Monitor network-related system calls"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "6. Security and Safety"
|
|
||||||
echo "--------------------"
|
|
||||||
echo "✓ eBPF programs are read-only and time-limited"
|
|
||||||
echo "✓ No system modification capabilities"
|
|
||||||
echo "✓ Automatic cleanup after execution"
|
|
||||||
echo "✓ Safe execution in containers and restricted environments"
|
|
||||||
echo "✓ Graceful fallback when eBPF is not available"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "7. Next Steps"
|
|
||||||
echo "------------"
|
|
||||||
echo "To test the full eBPF integration:"
|
|
||||||
echo ""
|
|
||||||
echo "a) Run with root privileges for full eBPF access:"
|
|
||||||
echo " sudo $AGENT"
|
|
||||||
echo ""
|
|
||||||
echo "b) Try these test scenarios:"
|
|
||||||
echo " - 'Network connection timeouts'"
|
|
||||||
echo " - 'High CPU usage and slow performance'"
|
|
||||||
echo " - 'File permission errors'"
|
|
||||||
echo " - 'Process hanging or not responding'"
|
|
||||||
echo ""
|
|
||||||
echo "c) Install additional eBPF tools:"
|
|
||||||
echo " sudo ./ebpf_helper.sh install"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "🎯 eBPF Integration Complete!"
|
|
||||||
echo ""
|
|
||||||
echo "The agent now supports:"
|
|
||||||
echo "- Dynamic eBPF program compilation and execution"
|
|
||||||
echo "- AI-driven selection of appropriate tracepoints and kprobes"
|
|
||||||
echo "- Real-time system event monitoring during diagnosis"
|
|
||||||
echo "- Integration with Cilium eBPF library for professional-grade monitoring"
|
|
||||||
echo ""
|
|
||||||
echo "This provides unprecedented visibility into system behavior"
|
|
||||||
echo "for accurate root cause analysis and issue resolution."
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# NannyAPI Function Discovery Script
|
|
||||||
# This script helps you find the correct function name for your NannyAPI setup
|
|
||||||
|
|
||||||
echo "🔍 NannyAPI Function Discovery"
|
|
||||||
echo "=============================="
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
ENDPOINT="${NANNYAPI_ENDPOINT:-http://tensorzero.netcup.internal:3000/openai/v1}"
|
|
||||||
|
|
||||||
echo "Testing endpoint: $ENDPOINT/chat/completions"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Test common function name patterns
|
|
||||||
test_functions=(
|
|
||||||
"nannyapi::function_name::diagnose"
|
|
||||||
"nannyapi::function_name::diagnose_and_heal"
|
|
||||||
"nannyapi::function_name::linux_diagnostic"
|
|
||||||
"nannyapi::function_name::system_diagnostic"
|
|
||||||
"nannyapi::model_name::gpt-4"
|
|
||||||
"nannyapi::model_name::claude"
|
|
||||||
)
|
|
||||||
|
|
||||||
for func in "${test_functions[@]}"; do
|
|
||||||
echo "Testing function: $func"
|
|
||||||
|
|
||||||
response=$(curl -s -X POST "$ENDPOINT/chat/completions" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "{\"model\":\"$func\",\"messages\":[{\"role\":\"user\",\"content\":\"test\"}]}")
|
|
||||||
|
|
||||||
if echo "$response" | grep -q "Unknown function"; then
|
|
||||||
echo " ❌ Function not found"
|
|
||||||
elif echo "$response" | grep -q "error"; then
|
|
||||||
echo " ⚠️ Error: $(echo "$response" | jq -r '.error' 2>/dev/null || echo "$response")"
|
|
||||||
else
|
|
||||||
echo " ✅ Function exists and responding!"
|
|
||||||
echo " Use this in your environment: export NANNYAPI_MODEL=\"$func\""
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "💡 If none of the above work, check your NannyAPI configuration file"
|
|
||||||
echo " for the correct function names and update NANNYAPI_MODEL accordingly."
|
|
||||||
echo ""
|
|
||||||
echo "Example NannyAPI config snippet:"
|
|
||||||
echo "```yaml"
|
|
||||||
echo "functions:"
|
|
||||||
echo " diagnose_and_heal: # This becomes 'nannyapi::function_name::diagnose_and_heal'"
|
|
||||||
echo " # function definition"
|
|
||||||
echo "```"
|
|
||||||
@@ -1,296 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# eBPF Helper Scripts for NannyAgent
|
|
||||||
# This script contains various eBPF programs and helpers for system monitoring
|
|
||||||
|
|
||||||
# Check if running as root (required for most eBPF operations)
|
|
||||||
check_root() {
|
|
||||||
if [ "$EUID" -ne 0 ]; then
|
|
||||||
echo "Warning: Many eBPF operations require root privileges"
|
|
||||||
echo "Consider running with sudo for full functionality"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Install eBPF tools if not present
|
|
||||||
install_ebpf_tools() {
|
|
||||||
echo "Installing eBPF tools..."
|
|
||||||
|
|
||||||
# Detect package manager and install appropriate packages
|
|
||||||
if command -v apt-get >/dev/null 2>&1; then
|
|
||||||
# Ubuntu/Debian
|
|
||||||
echo "Detected Ubuntu/Debian system"
|
|
||||||
apt-get update
|
|
||||||
apt-get install -y bpftrace linux-tools-generic linux-tools-$(uname -r) || true
|
|
||||||
apt-get install -y bcc-tools python3-bcc || true
|
|
||||||
elif command -v yum >/dev/null 2>&1; then
|
|
||||||
# RHEL/CentOS 7
|
|
||||||
echo "Detected RHEL/CentOS system"
|
|
||||||
yum install -y bpftrace perf || true
|
|
||||||
elif command -v dnf >/dev/null 2>&1; then
|
|
||||||
# RHEL/CentOS 8+/Fedora
|
|
||||||
echo "Detected Fedora/RHEL 8+ system"
|
|
||||||
dnf install -y bpftrace perf bcc-tools python3-bcc || true
|
|
||||||
elif command -v zypper >/dev/null 2>&1; then
|
|
||||||
# openSUSE
|
|
||||||
echo "Detected openSUSE system"
|
|
||||||
zypper install -y bpftrace perf || true
|
|
||||||
else
|
|
||||||
echo "Unknown package manager. Please install eBPF tools manually:"
|
|
||||||
echo "- bpftrace"
|
|
||||||
echo "- perf (linux-tools)"
|
|
||||||
echo "- BCC tools (optional)"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check eBPF capabilities of the current system
|
|
||||||
check_ebpf_capabilities() {
|
|
||||||
echo "Checking eBPF capabilities..."
|
|
||||||
|
|
||||||
# Check kernel version
|
|
||||||
kernel_version=$(uname -r)
|
|
||||||
echo "Kernel version: $kernel_version"
|
|
||||||
|
|
||||||
# Check if eBPF is enabled in kernel
|
|
||||||
if [ -f /proc/config.gz ]; then
|
|
||||||
if zcat /proc/config.gz | grep -q "CONFIG_BPF=y"; then
|
|
||||||
echo "✓ eBPF support enabled in kernel"
|
|
||||||
else
|
|
||||||
echo "✗ eBPF support not found in kernel config"
|
|
||||||
fi
|
|
||||||
elif [ -f "/boot/config-$(uname -r)" ]; then
|
|
||||||
if grep -q "CONFIG_BPF=y" "/boot/config-$(uname -r)"; then
|
|
||||||
echo "✓ eBPF support enabled in kernel"
|
|
||||||
else
|
|
||||||
echo "✗ eBPF support not found in kernel config"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "? Unable to check kernel eBPF config"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check available tools
|
|
||||||
echo ""
|
|
||||||
echo "Available eBPF tools:"
|
|
||||||
|
|
||||||
tools=("bpftrace" "perf" "execsnoop" "opensnoop" "tcpconnect" "biotop")
|
|
||||||
for tool in "${tools[@]}"; do
|
|
||||||
if command -v "$tool" >/dev/null 2>&1; then
|
|
||||||
echo "✓ $tool"
|
|
||||||
else
|
|
||||||
echo "✗ $tool"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Check debugfs mount
|
|
||||||
if mount | grep -q debugfs; then
|
|
||||||
echo "✓ debugfs mounted"
|
|
||||||
else
|
|
||||||
echo "✗ debugfs not mounted (required for ftrace)"
|
|
||||||
echo " To mount: sudo mount -t debugfs none /sys/kernel/debug"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if we can load eBPF programs
|
|
||||||
echo ""
|
|
||||||
echo "Testing eBPF program loading..."
|
|
||||||
if bpftrace -e 'BEGIN { print("eBPF test successful"); exit(); }' >/dev/null 2>&1; then
|
|
||||||
echo "✓ eBPF program loading works"
|
|
||||||
else
|
|
||||||
echo "✗ eBPF program loading failed (may need root privileges)"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create simple syscall monitoring script
|
|
||||||
create_syscall_monitor() {
|
|
||||||
cat > /tmp/nannyagent_syscall_monitor.bt << 'EOF'
|
|
||||||
#!/usr/bin/env bpftrace
|
|
||||||
|
|
||||||
BEGIN {
|
|
||||||
printf("Monitoring syscalls... Press Ctrl-C to stop\n");
|
|
||||||
printf("[\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
tracepoint:syscalls:sys_enter_* {
|
|
||||||
printf("{\"timestamp\":%llu,\"event_type\":\"syscall_enter\",\"process_id\":%d,\"process_name\":\"%s\",\"syscall\":\"%s\",\"user_id\":%d},\n",
|
|
||||||
nsecs, pid, comm, probe, uid);
|
|
||||||
}
|
|
||||||
|
|
||||||
END {
|
|
||||||
printf("]\n");
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
chmod +x /tmp/nannyagent_syscall_monitor.bt
|
|
||||||
echo "Syscall monitor created: /tmp/nannyagent_syscall_monitor.bt"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create network activity monitor
|
|
||||||
create_network_monitor() {
|
|
||||||
cat > /tmp/nannyagent_network_monitor.bt << 'EOF'
|
|
||||||
#!/usr/bin/env bpftrace
|
|
||||||
|
|
||||||
BEGIN {
|
|
||||||
printf("Monitoring network activity... Press Ctrl-C to stop\n");
|
|
||||||
printf("[\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
kprobe:tcp_sendmsg,
|
|
||||||
kprobe:tcp_recvmsg,
|
|
||||||
kprobe:udp_sendmsg,
|
|
||||||
kprobe:udp_recvmsg {
|
|
||||||
$action = (probe =~ /send/ ? "send" : "recv");
|
|
||||||
$protocol = (probe =~ /tcp/ ? "tcp" : "udp");
|
|
||||||
printf("{\"timestamp\":%llu,\"event_type\":\"network_%s\",\"protocol\":\"%s\",\"process_id\":%d,\"process_name\":\"%s\"},\n",
|
|
||||||
nsecs, $action, $protocol, pid, comm);
|
|
||||||
}
|
|
||||||
|
|
||||||
END {
|
|
||||||
printf("]\n");
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
chmod +x /tmp/nannyagent_network_monitor.bt
|
|
||||||
echo "Network monitor created: /tmp/nannyagent_network_monitor.bt"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create file access monitor
|
|
||||||
create_file_monitor() {
|
|
||||||
cat > /tmp/nannyagent_file_monitor.bt << 'EOF'
|
|
||||||
#!/usr/bin/env bpftrace
|
|
||||||
|
|
||||||
BEGIN {
|
|
||||||
printf("Monitoring file access... Press Ctrl-C to stop\n");
|
|
||||||
printf("[\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
tracepoint:syscalls:sys_enter_openat {
|
|
||||||
printf("{\"timestamp\":%llu,\"event_type\":\"file_open\",\"process_id\":%d,\"process_name\":\"%s\",\"filename\":\"%s\",\"flags\":%d},\n",
|
|
||||||
nsecs, pid, comm, str(args->pathname), args->flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
tracepoint:syscalls:sys_enter_unlinkat {
|
|
||||||
printf("{\"timestamp\":%llu,\"event_type\":\"file_delete\",\"process_id\":%d,\"process_name\":\"%s\",\"filename\":\"%s\"},\n",
|
|
||||||
nsecs, pid, comm, str(args->pathname));
|
|
||||||
}
|
|
||||||
|
|
||||||
END {
|
|
||||||
printf("]\n");
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
chmod +x /tmp/nannyagent_file_monitor.bt
|
|
||||||
echo "File monitor created: /tmp/nannyagent_file_monitor.bt"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create process monitor
|
|
||||||
create_process_monitor() {
|
|
||||||
cat > /tmp/nannyagent_process_monitor.bt << 'EOF'
|
|
||||||
#!/usr/bin/env bpftrace
|
|
||||||
|
|
||||||
BEGIN {
|
|
||||||
printf("Monitoring process activity... Press Ctrl-C to stop\n");
|
|
||||||
printf("[\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
tracepoint:syscalls:sys_enter_execve {
|
|
||||||
printf("{\"timestamp\":%llu,\"event_type\":\"process_exec\",\"process_id\":%d,\"process_name\":\"%s\",\"filename\":\"%s\"},\n",
|
|
||||||
nsecs, pid, comm, str(args->filename));
|
|
||||||
}
|
|
||||||
|
|
||||||
tracepoint:sched:sched_process_exit {
|
|
||||||
printf("{\"timestamp\":%llu,\"event_type\":\"process_exit\",\"process_id\":%d,\"process_name\":\"%s\",\"exit_code\":%d},\n",
|
|
||||||
nsecs, args->pid, args->comm, args->code);
|
|
||||||
}
|
|
||||||
|
|
||||||
END {
|
|
||||||
printf("]\n");
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
chmod +x /tmp/nannyagent_process_monitor.bt
|
|
||||||
echo "Process monitor created: /tmp/nannyagent_process_monitor.bt"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Performance monitoring setup
|
|
||||||
setup_performance_monitoring() {
|
|
||||||
echo "Setting up performance monitoring..."
|
|
||||||
|
|
||||||
# Create performance monitoring script
|
|
||||||
cat > /tmp/nannyagent_perf_monitor.sh << 'EOF'
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
DURATION=${1:-10}
|
|
||||||
OUTPUT_FILE=${2:-/tmp/nannyagent_perf_output.json}
|
|
||||||
|
|
||||||
echo "Running performance monitoring for $DURATION seconds..."
|
|
||||||
echo "[" > "$OUTPUT_FILE"
|
|
||||||
|
|
||||||
# Sample system performance every second
|
|
||||||
for i in $(seq 1 $DURATION); do
|
|
||||||
timestamp=$(date +%s)000000000
|
|
||||||
cpu_percent=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
|
|
||||||
memory_percent=$(free | grep Mem | awk '{printf "%.1f", $3/$2 * 100.0}')
|
|
||||||
load_avg=$(uptime | awk -F'load average:' '{print $2}' | xargs)
|
|
||||||
|
|
||||||
echo "{\"timestamp\":$timestamp,\"event_type\":\"performance_sample\",\"cpu_percent\":\"$cpu_percent\",\"memory_percent\":\"$memory_percent\",\"load_avg\":\"$load_avg\"}," >> "$OUTPUT_FILE"
|
|
||||||
|
|
||||||
[ $i -lt $DURATION ] && sleep 1
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "]" >> "$OUTPUT_FILE"
|
|
||||||
echo "Performance data saved to $OUTPUT_FILE"
|
|
||||||
EOF
|
|
||||||
|
|
||||||
chmod +x /tmp/nannyagent_perf_monitor.sh
|
|
||||||
echo "Performance monitor created: /tmp/nannyagent_perf_monitor.sh"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main function
|
|
||||||
main() {
|
|
||||||
check_root
|
|
||||||
|
|
||||||
case "${1:-help}" in
|
|
||||||
"install")
|
|
||||||
install_ebpf_tools
|
|
||||||
;;
|
|
||||||
"check")
|
|
||||||
check_ebpf_capabilities
|
|
||||||
;;
|
|
||||||
"setup")
|
|
||||||
echo "Setting up eBPF monitoring scripts..."
|
|
||||||
create_syscall_monitor
|
|
||||||
create_network_monitor
|
|
||||||
create_file_monitor
|
|
||||||
create_process_monitor
|
|
||||||
setup_performance_monitoring
|
|
||||||
echo "All eBPF monitoring scripts created in /tmp/"
|
|
||||||
;;
|
|
||||||
"test")
|
|
||||||
echo "Testing eBPF functionality..."
|
|
||||||
check_ebpf_capabilities
|
|
||||||
if command -v bpftrace >/dev/null 2>&1; then
|
|
||||||
echo "Running quick eBPF test..."
|
|
||||||
timeout 5s bpftrace -e 'BEGIN { print("eBPF is working!"); } tracepoint:syscalls:sys_enter_openat { @[comm] = count(); } END { print(@); clear(@); }'
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
"help"|*)
|
|
||||||
echo "eBPF Helper Script for NannyAgent"
|
|
||||||
echo ""
|
|
||||||
echo "Usage: $0 [command]"
|
|
||||||
echo ""
|
|
||||||
echo "Commands:"
|
|
||||||
echo " install - Install eBPF tools on the system"
|
|
||||||
echo " check - Check eBPF capabilities"
|
|
||||||
echo " setup - Create eBPF monitoring scripts"
|
|
||||||
echo " test - Test eBPF functionality"
|
|
||||||
echo " help - Show this help message"
|
|
||||||
echo ""
|
|
||||||
echo "Examples:"
|
|
||||||
echo " $0 check # Check what eBPF tools are available"
|
|
||||||
echo " $0 install # Install eBPF tools (requires root)"
|
|
||||||
echo " $0 setup # Create monitoring scripts"
|
|
||||||
echo " $0 test # Test eBPF functionality"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Run main function with all arguments
|
|
||||||
main "$@"
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Linux Diagnostic Agent Installation Script
|
|
||||||
# This script installs the nanny-agent on a Linux system
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "🔧 Linux Diagnostic Agent Installation Script"
|
|
||||||
echo "=============================================="
|
|
||||||
|
|
||||||
# Check if Go is installed
|
|
||||||
if ! command -v go &> /dev/null; then
|
|
||||||
echo "❌ Go is not installed. Please install Go first:"
|
|
||||||
echo ""
|
|
||||||
echo "For Ubuntu/Debian:"
|
|
||||||
echo " sudo apt update && sudo apt install golang-go"
|
|
||||||
echo ""
|
|
||||||
echo "For RHEL/CentOS/Fedora:"
|
|
||||||
echo " sudo dnf install golang"
|
|
||||||
echo " # or"
|
|
||||||
echo " sudo yum install golang"
|
|
||||||
echo ""
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ Go is installed: $(go version)"
|
|
||||||
|
|
||||||
# Build the application
|
|
||||||
echo "🔨 Building the application..."
|
|
||||||
go mod tidy
|
|
||||||
make build
|
|
||||||
|
|
||||||
# Check if build was successful
|
|
||||||
if [ ! -f "./nanny-agent" ]; then
|
|
||||||
echo "❌ Build failed! nanny-agent binary not found."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ Build successful!"
|
|
||||||
|
|
||||||
# Ask for installation preference
|
|
||||||
echo ""
|
|
||||||
echo "Installation options:"
|
|
||||||
echo "1. Install system-wide (/usr/local/bin) - requires sudo"
|
|
||||||
echo "2. Keep in current directory"
|
|
||||||
echo ""
|
|
||||||
read -p "Choose option (1 or 2): " choice
|
|
||||||
|
|
||||||
case $choice in
|
|
||||||
1)
|
|
||||||
echo "📦 Installing system-wide..."
|
|
||||||
sudo cp nanny-agent /usr/local/bin/
|
|
||||||
sudo chmod +x /usr/local/bin/nanny-agent
|
|
||||||
echo "✅ Agent installed to /usr/local/bin/nanny-agent"
|
|
||||||
echo ""
|
|
||||||
echo "You can now run the agent from anywhere with:"
|
|
||||||
echo " nanny-agent"
|
|
||||||
;;
|
|
||||||
2)
|
|
||||||
echo "✅ Agent ready in current directory"
|
|
||||||
echo ""
|
|
||||||
echo "Run the agent with:"
|
|
||||||
echo " ./nanny-agent"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "❌ Invalid choice. Agent is available in current directory."
|
|
||||||
echo "Run with: ./nanny-agent"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Configuration
|
|
||||||
echo ""
|
|
||||||
echo "📝 Configuration:"
|
|
||||||
echo "Set these environment variables to configure the agent:"
|
|
||||||
echo ""
|
|
||||||
echo "export NANNYAPI_ENDPOINT=\"http://your-nannyapi-host:3000/openai/v1\""
|
|
||||||
echo "export NANNYAPI_MODEL=\"your-model-identifier\""
|
|
||||||
echo ""
|
|
||||||
echo "Or create a .env file in the working directory."
|
|
||||||
echo ""
|
|
||||||
echo "🎉 Installation complete!"
|
|
||||||
echo ""
|
|
||||||
echo "Example usage:"
|
|
||||||
echo " ./nanny-agent"
|
|
||||||
echo " > On /var filesystem I cannot create any file but df -h shows 30% free space available."
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Linux Diagnostic Agent - Integration Tests
|
|
||||||
# This script creates realistic Linux problem scenarios for testing
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
AGENT_BINARY="./nanny-agent"
|
|
||||||
TEST_DIR="/tmp/nanny-agent-tests"
|
|
||||||
TEST_LOG="$TEST_DIR/integration_test.log"
|
|
||||||
|
|
||||||
# Color codes for output
|
|
||||||
RED='\033[0;31m'
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
YELLOW='\033[1;33m'
|
|
||||||
BLUE='\033[0;34m'
|
|
||||||
NC='\033[0m' # No Color
|
|
||||||
|
|
||||||
# Ensure test directory exists
|
|
||||||
mkdir -p "$TEST_DIR"
|
|
||||||
|
|
||||||
echo -e "${BLUE}🧪 Linux Diagnostic Agent - Integration Tests${NC}"
|
|
||||||
echo "================================================="
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Check if agent binary exists
|
|
||||||
if [[ ! -f "$AGENT_BINARY" ]]; then
|
|
||||||
echo -e "${RED}❌ Agent binary not found at $AGENT_BINARY${NC}"
|
|
||||||
echo "Please run: make build"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Function to run a test scenario
|
|
||||||
run_test() {
|
|
||||||
local test_name="$1"
|
|
||||||
local scenario="$2"
|
|
||||||
local expected_keywords="$3"
|
|
||||||
|
|
||||||
echo -e "${YELLOW}📋 Test: $test_name${NC}"
|
|
||||||
echo "Scenario: $scenario"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Run the agent with the scenario
|
|
||||||
echo "$scenario" | timeout 120s "$AGENT_BINARY" > "$TEST_LOG" 2>&1 || true
|
|
||||||
|
|
||||||
# Check if any expected keywords are found in the output
|
|
||||||
local found_keywords=0
|
|
||||||
IFS=',' read -ra KEYWORDS <<< "$expected_keywords"
|
|
||||||
for keyword in "${KEYWORDS[@]}"; do
|
|
||||||
keyword=$(echo "$keyword" | xargs) # trim whitespace
|
|
||||||
if grep -qi "$keyword" "$TEST_LOG"; then
|
|
||||||
echo -e "${GREEN} ✅ Found expected keyword: $keyword${NC}"
|
|
||||||
((found_keywords++))
|
|
||||||
else
|
|
||||||
echo -e "${RED} ❌ Missing keyword: $keyword${NC}"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Show summary
|
|
||||||
if [[ $found_keywords -gt 0 ]]; then
|
|
||||||
echo -e "${GREEN} ✅ Test PASSED ($found_keywords keywords found)${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${RED} ❌ Test FAILED (no expected keywords found)${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "Full output saved to: $TEST_LOG"
|
|
||||||
echo "----------------------------------------"
|
|
||||||
echo ""
|
|
||||||
}
|
|
||||||
|
|
||||||
# Test Scenario 1: Disk Space Issues (Inode Exhaustion)
|
|
||||||
run_test "Disk Space - Inode Exhaustion" \
|
|
||||||
"I cannot create new files in /home directory even though df -h shows plenty of space available. Getting 'No space left on device' error when trying to touch new files." \
|
|
||||||
"inode,df -i,filesystem,inodes,exhausted"
|
|
||||||
|
|
||||||
# Test Scenario 2: Memory Issues
|
|
||||||
run_test "Memory Issues - OOM Killer" \
|
|
||||||
"My applications keep getting killed randomly and I see 'killed' messages in logs. The system becomes unresponsive for a few seconds before recovering. This happens especially when running memory-intensive tasks." \
|
|
||||||
"memory,oom,killed,dmesg,free,swap"
|
|
||||||
|
|
||||||
# Test Scenario 3: Network Connectivity Issues
|
|
||||||
run_test "Network Connectivity - DNS Resolution" \
|
|
||||||
"I can ping IP addresses directly (like 8.8.8.8) but cannot resolve domain names. Web browsing fails with DNS resolution errors, but ping 8.8.8.8 works fine." \
|
|
||||||
"dns,resolv.conf,nslookup,nameserver,dig"
|
|
||||||
|
|
||||||
# Test Scenario 4: Service/Process Issues
|
|
||||||
run_test "Service Issues - High Load" \
|
|
||||||
"System load average is consistently above 10.0 even when CPU usage appears normal. Applications are responding slowly and I notice high wait times. The server feels sluggish overall." \
|
|
||||||
"load,average,cpu,iostat,vmstat,processes"
|
|
||||||
|
|
||||||
# Test Scenario 5: File System Issues
|
|
||||||
run_test "Filesystem Issues - Permission Problems" \
|
|
||||||
"Web server returns 403 Forbidden errors for all pages. Files exist and seem readable, but nginx logs show permission denied errors. SELinux is disabled and file permissions look correct." \
|
|
||||||
"permission,403,nginx,chmod,chown,selinux"
|
|
||||||
|
|
||||||
# Test Scenario 6: Boot/System Issues
|
|
||||||
run_test "Boot Issues - Kernel Module" \
|
|
||||||
"System boots but some hardware devices are not working. Network interface shows as down, USB devices are not recognized, and dmesg shows module loading failures." \
|
|
||||||
"module,lsmod,dmesg,hardware,interface,usb"
|
|
||||||
|
|
||||||
# Test Scenario 7: Performance Issues
|
|
||||||
run_test "Performance Issues - I/O Bottleneck" \
|
|
||||||
"Database queries are extremely slow, taking 30+ seconds for simple SELECT statements. Disk activity LED is constantly on and system feels unresponsive during database operations." \
|
|
||||||
"iostat,iotop,disk,database,slow,performance"
|
|
||||||
|
|
||||||
echo -e "${BLUE}🏁 Integration Tests Complete${NC}"
|
|
||||||
echo ""
|
|
||||||
echo "Check individual test logs in: $TEST_DIR"
|
|
||||||
echo ""
|
|
||||||
echo -e "${YELLOW}💡 Tips:${NC}"
|
|
||||||
echo "- Tests use realistic scenarios that could occur on production systems"
|
|
||||||
echo "- Each test expects the AI to suggest relevant diagnostic commands"
|
|
||||||
echo "- Review the full logs to see the complete diagnostic conversation"
|
|
||||||
echo "- Tests timeout after 120 seconds to prevent hanging"
|
|
||||||
echo "- Make sure NANNYAPI_ENDPOINT and NANNYAPI_MODEL are set correctly"
|
|
||||||
Reference in New Issue
Block a user