prole/docs/PROLE-HOME-DIRECTORY.md

321 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Knoe Home Directory Structure
## Overview
The Knoe Installer uses `$KNOE_HOME/` (defaulting to `$HOME/.knoe/`) for writable storage when running from a packaged binary. This is necessary because PyInstaller extracts resources to a read-only temporary directory.
## Directory Structure
```
$KNOE_HOME/
├── build/ # Docker build contexts
│ └── knoe-db/ # PostgreSQL Docker build
│ ├── Dockerfile
│ ├── conf/
│ └── ...
└── scan/ # Network scan output and cache
└── (scan results, temporary files)
```
## Purpose of Each Directory
### build/
**Purpose:** Writable location for Docker build contexts
**Why:** PyInstaller extracts resources to `/tmp/_MEIxxxxxx/` which is read-only. Docker requires a writable build context directory to create images.
**Usage:**
```python
knoe_home = resolve_knoe_home()
build_dir = knoe_home / "build" / "knoe-db"
build_dir.mkdir(parents=True, exist_ok=True)
# Copy build context from embedded resources
source_dir = get_resource_path("knoe-db")
shutil.copytree(source_dir, build_dir)
# Docker build
subprocess.Popen(['docker', 'build', '-t', 'knoe-db:TAG', '.'], cwd=build_dir)
```
**Contents:**
- Complete copy of `knoe-db/` directory
- Dockerfile and all dependencies
- Refreshed on each build (old content removed)
**Size:** ~1-5 MB
### scan/
**Purpose:** Writable working directory for network scan operations
**Why:** The `knoe-agent` binary may need to write output files, cache data, or store temporary results. Running from a read-only directory causes failures.
**Usage:**
```python
knoe_home = resolve_knoe_home()
scan_dir = knoe_home / "scan"
scan_dir.mkdir(parents=True, exist_ok=True)
# Run scan with writable cwd
subprocess.Popen([str(scan_binary)], cwd=str(scan_dir))
```
**Contents:**
- Network scan results (temporary)
- Ollama API interaction cache
- Any intermediate files created by knoe-agent
**Size:** Varies, typically < 1 MB
## Creation and Cleanup
### Automatic Creation
All directories are created automatically when needed:
```python
# Build directory
(resolve_knoe_home() / "build" / "knoe-db").mkdir(parents=True, exist_ok=True)
# Scan directory
(resolve_knoe_home() / "scan").mkdir(parents=True, exist_ok=True)
```
### Manual Cleanup
To remove all Knoe working directories:
```bash
rm -rf ~/.knoe
```
Or from Python:
```python
import shutil
from pathlib import Path
knoe_home = resolve_knoe_home()
if knoe_home.exists():
shutil.rmtree(knoe_home)
```
### Automatic Cleanup (Future)
Consider adding cleanup options to the installer:
```python
def cleanup_knoe_home():
"""Clean up .knoe working directories."""
knoe_home = Path.home() / ".knoe"
if knoe_home.exists():
# Keep or remove based on user preference
if messagebox.askyesno("Cleanup", "Remove temporary files?"):
shutil.rmtree(knoe_home)
```
## Disk Space
### Expected Usage
| Directory | Size | When Created | Persistent |
|-----------|------|--------------|------------|
| `build/knoe-db/` | 1-5 MB | First Docker build | Yes |
| `scan/` | < 1 MB | First network scan | Yes |
| **Total** | **~2-6 MB** | On first use | Yes |
### Growth
- **build/** – Overwritten on each build, doesn't grow
- **scan/** – May accumulate cache files over time
## Troubleshooting
### Permission Errors
**Error:** `Permission denied` creating `.knoe` directory
**Cause:** Home directory not writable
**Solution:**
```bash
ls -ld ~
chmod u+w ~
```
### Disk Space Issues
**Error:** `No space left on device`
**Cause:** Disk full
**Solution:**
```bash
df -h ~
rm -rf ~/.knoe # Free up space
```
### Stale Build Context
**Issue:** Docker build uses old files
**Solution:**
```python
# Build directory is refreshed automatically
if build_dir.exists():
shutil.rmtree(build_dir)
shutil.copytree(source_dir, build_dir)
```
## Security Considerations
### File Permissions
The `.knoe` directory inherits user's home directory permissions:
```bash
ls -ld ~/.knoe
# drwxr-xr-x user group ~/.knoe
```
Only the user should have write access.
### Sensitive Data
Avoid storing sensitive data in `.knoe/`:
- ✓ Build contexts (public)
- ✓ Scan results (network info, semi-sensitive)
- ✗ Passwords, keys, credentials
### Cleanup on Uninstall
If distributing the installer, consider:
1. **Document cleanup:**
```
To completely remove Knoe:
1. Delete the app: rm -rf /Applications/Knoe\ Installer.app
2. Clean up data: rm -rf ~/.knoe
```
2. **Provide uninstall script:**
```bash
#!/bin/bash
# uninstall-knoe.sh
rm -rf /Applications/Knoe\ Installer.app
rm -rf ~/.knoe
echo "Knoe uninstalled"
```
## Related Issues
### Docker Build Hang
**Problem:** Docker build hangs when running from packaged binary
**Solution:** Copy build context to `~/.knoe/build/knoe-db/`
**See:** [DOCKER-BUILD-FIX.md](DOCKER-BUILD-FIX.md)
### Network Scan Failure
**Problem:** Network scan fails to make API calls from packaged binary
**Solution:** Run scan with `cwd=~/.knoe/scan`
**Reason:** Scan binary needs writable directory for output/cache
## Implementation Details
### Code Location
**Build directory creation:** `install.py`, `run_db_build()` method (line ~1791)
```python
knoe_home = Path.home() / ".knoe"
build_dir = knoe_home / "build" / "knoe-db"
build_dir.mkdir(parents=True, exist_ok=True)
```
**Scan directory creation:** `install.py`, network scan worker (line ~1102)
```python
knoe_home = Path.home() / ".knoe"
scan_dir = knoe_home / "scan"
scan_dir.mkdir(parents=True, exist_ok=True)
```
### Resource Path Resolution
Both use `get_resource_path()` to find embedded resources:
```python
def get_resource_path(relative_path):
"""Get absolute path to resource, works for dev and for PyInstaller."""
try:
base_path = Path(sys._MEIPASS) # PyInstaller temp dir
except AttributeError:
base_path = PROJECT_ROOT # Running from source
return base_path / relative_path
```
## Future Enhancements
### Persistent Cache
Store network scan results between runs:
```python
scan_cache = Path.home() / ".knoe" / "scan" / "cache.json"
if scan_cache.exists():
# Load previous scan
results = json.loads(scan_cache.read_text())
else:
# Run new scan
results = run_scan()
scan_cache.write_text(json.dumps(results))
```
### Build Artifacts
Store built Docker images as tarballs:
```python
image_cache = Path.home() / ".knoe" / "build" / "knoe-db-TAG.tar"
if not image_cache.exists():
# Build and save
subprocess.run(['docker', 'build', '-t', 'knoe-db:TAG', '.'])
subprocess.run(['docker', 'save', '-o', str(image_cache), 'knoe-db:TAG'])
else:
# Load cached image
subprocess.run(['docker', 'load', '-i', str(image_cache)])
```
### Configuration Storage
Store user preferences:
```python
config_file = Path.home() / ".knoe" / "config.json"
config = {
'cluster_env': 'development',
'kerberos_enabled': False,
'last_scan': '2025-01-19',
}
config_file.write_text(json.dumps(config, indent=2))
```
## Summary
The `~/.knoe/` directory provides:
- ✓ Writable storage for packaged binary operations
- ✓ Separate from extracted read-only resources
- ✓ User-specific, secure location
- ✓ Easy to clean up manually
- ✓ Small disk footprint (< 10 MB)
This architecture ensures the installer works correctly whether running from source or from a PyInstaller package.