mirror of
https://github.com/dredx/prole.git
synced 2026-09-23 11:03:59 +00:00
350 lines
9.3 KiB
Markdown
350 lines
9.3 KiB
Markdown
# Knoe Installer Build System
|
|
|
|
## Overview
|
|
|
|
The Knoe Database Installer includes a comprehensive build system that creates self-contained, universal binaries for distribution. The build system produces a macOS application bundle (.app) that:
|
|
|
|
- **Double-click launch**: Opens the GUI installer when launched from Finder
|
|
- **Command-line capable**: Can be run from terminal with full argument support
|
|
- **Auto-detects display**: Automatically switches to ncurses mode when no GUI is available
|
|
- **Self-contained**: Includes all dependencies and resources
|
|
- **Icon embedded**: Uses the Knoe icon for the application bundle
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
# Install build dependencies
|
|
make install
|
|
|
|
# Build everything (creates .app bundle)
|
|
make package
|
|
|
|
# Test the build
|
|
make test
|
|
|
|
# Clean build artifacts
|
|
make clean
|
|
```
|
|
|
|
## Makefile Targets
|
|
|
|
### `make help` (default)
|
|
Display help information about available targets.
|
|
|
|
### `make install`
|
|
Install required build dependencies:
|
|
- PyInstaller (for creating standalone executables)
|
|
- Pillow (for image processing, if needed)
|
|
|
|
### `make build`
|
|
Build the static binary using PyInstaller:
|
|
1. Generates icon in .icns format
|
|
2. Creates PyInstaller spec file
|
|
3. Builds standalone executable
|
|
4. Creates macOS .app bundle
|
|
|
|
**Output:**
|
|
- `dist/knoe-installer` - Standalone executable
|
|
- `dist/Knoe Installer.app` - macOS application bundle
|
|
|
|
### `make package`
|
|
Alias for `make build` - creates the complete package.
|
|
|
|
### `make test`
|
|
Run basic tests on the built binary:
|
|
- Test `--help` output
|
|
- Verify app bundle structure
|
|
- Test executable within app bundle
|
|
|
|
### `make clean`
|
|
Remove all build artifacts:
|
|
- `build/` directory
|
|
- `dist/` directory
|
|
- `installer.spec` file
|
|
- Python cache files
|
|
|
|
### `make rebuild`
|
|
Clean and rebuild from scratch (`make clean build`).
|
|
|
|
### `make spec`
|
|
Generate only the PyInstaller spec file (intermediate step).
|
|
|
|
## Build Process Details
|
|
|
|
### 1. Icon Conversion
|
|
|
|
The build system converts `img/knoeIcon.png` to macOS `.icns` format with multiple resolutions:
|
|
|
|
- 16x16, 32x32 (standard and @2x)
|
|
- 128x128, 256x256 (standard and @2x)
|
|
- 512x512, 1024x1024 (standard and @2x)
|
|
|
|
**Tool:** macOS `sips` and `iconutil` commands
|
|
|
|
**Output:** `build/knoe.icns`
|
|
|
|
### 2. Spec File Generation
|
|
|
|
A Python script (`scripts/generate_spec.py`) creates the PyInstaller specification:
|
|
|
|
**Included Data Files:**
|
|
- `installer/` - Installer Python modules
|
|
- `conf/` - Configuration files
|
|
- `etc/` - Scripts and utilities
|
|
- `img/` - Images and icons (including knoeIcon.png, knoeLogoSepia.png, knoeLogo.png)
|
|
- `docs/` - Documentation
|
|
- `knoe-db/` - Docker build context for PostgreSQL database
|
|
- `knoe-app/dist/Knoe Tools.app` - Pre-built Knoe Tools application bundle (entire .app)
|
|
|
|
**Included Binaries:**
|
|
- `scan/network-agent` - Network scanner binary (universal: x86_64 + arm64, 6.8 MB)
|
|
|
|
**Resource Path Resolution:**
|
|
The installer uses a `get_resource_path()` helper function that automatically resolves paths correctly whether running from source or from a PyInstaller bundle:
|
|
- **From source**: Uses `PROJECT_ROOT / relative_path`
|
|
- **From bundle**: Uses `sys._MEIPASS / relative_path` (PyInstaller temp directory)
|
|
|
|
This ensures all images and resources are found correctly in both development and production.
|
|
|
|
**Docker Build Context:**
|
|
Docker builds require a writable directory. When running from a PyInstaller bundle, the extracted resources are in a read-only temporary directory. To solve this:
|
|
- Docker build context is copied to `$HOME/.knoe/build/knoe-db/`
|
|
- This provides a writable location for Docker to operate
|
|
- See [DOCKER-BUILD-FIX.md](DOCKER-BUILD-FIX.md) for details
|
|
|
|
**Hidden Imports:**
|
|
PyInstaller can't always auto-detect imports, so we explicitly include:
|
|
- All installer modules
|
|
- curses/ncurses libraries
|
|
|
|
**Output:** `installer.spec`
|
|
|
|
### 3. Binary Creation
|
|
|
|
PyInstaller processes the spec file to create:
|
|
|
|
**Single-file Executable:**
|
|
- All Python code and dependencies bundled
|
|
- Extracts to temporary directory at runtime
|
|
- Console-enabled (works with both GUI and ncurses)
|
|
|
|
**macOS App Bundle:**
|
|
- Standard `.app` directory structure
|
|
- Icon embedded in bundle
|
|
- Info.plist with metadata
|
|
- Executable in `Contents/MacOS/`
|
|
|
|
## Using the Built Application
|
|
|
|
### GUI Mode (Double-click)
|
|
|
|
Simply double-click `Knoe Installer.app` in Finder to launch the graphical installer.
|
|
|
|
### Command-line Mode
|
|
|
|
```bash
|
|
# Run with auto-detection (GUI if available, otherwise ncurses)
|
|
./dist/Knoe\ Installer.app/Contents/MacOS/knoe-installer
|
|
|
|
# Force ncurses mode
|
|
./dist/Knoe\ Installer.app/Contents/MacOS/knoe-installer --no-gui
|
|
|
|
# Force GUI mode
|
|
./dist/Knoe\ Installer.app/Contents/MacOS/knoe-installer --gui
|
|
|
|
# Show help
|
|
./dist/Knoe\ Installer.app/Contents/MacOS/knoe-installer --help
|
|
```
|
|
|
|
### Installation to /Applications
|
|
|
|
```bash
|
|
cp -r "dist/Knoe Installer.app" /Applications/
|
|
```
|
|
|
|
After installation, the app is available:
|
|
- In Finder under Applications
|
|
- Via Spotlight search
|
|
- From command line as `/Applications/Knoe\ Installer.app/Contents/MacOS/knoe-installer`
|
|
|
|
## Display Auto-detection
|
|
|
|
The installer automatically detects whether a GUI display is available:
|
|
|
|
1. **macOS**: Attempts to create a Tk root window
|
|
2. **Linux/Unix**: Checks for `DISPLAY` environment variable
|
|
3. **Fallback**: Uses ncurses mode if GUI unavailable
|
|
|
|
**Override behavior:**
|
|
- `--gui` flag: Force GUI mode (fails if no display)
|
|
- `--no-gui` flag: Force ncurses mode
|
|
|
|
## Architecture Support
|
|
|
|
The build system detects the host architecture:
|
|
- **Apple Silicon (arm64)**: Native ARM64 binary
|
|
- **Intel (x86_64)**: Native x86_64 binary
|
|
|
|
For universal binaries supporting both architectures, you would need to:
|
|
1. Build on arm64 machine
|
|
2. Build on x86_64 machine
|
|
3. Use `lipo` to combine binaries
|
|
|
|
## Build Requirements
|
|
|
|
### System Requirements
|
|
- macOS 10.13 or later
|
|
- Python 3.8 or later
|
|
- Make build system
|
|
|
|
### Python Dependencies
|
|
- pyinstaller >= 5.0
|
|
- pillow (optional, for advanced image processing)
|
|
- All runtime dependencies of install.py
|
|
|
|
### macOS Developer Tools
|
|
- Command Line Tools (for `sips`, `iconutil`, `codesign`)
|
|
|
|
Install with: `xcode-select --install`
|
|
|
|
## Troubleshooting
|
|
|
|
### Build Fails with "No module named 'installer'"
|
|
|
|
**Cause:** PyInstaller can't find the installer package.
|
|
|
|
**Solution:** Ensure you're running from project root and `installer/` directory exists.
|
|
|
|
### Icon Not Showing in App Bundle
|
|
|
|
**Cause:** Icon conversion failed or .icns file is invalid.
|
|
|
|
**Solution:**
|
|
```bash
|
|
make clean
|
|
make build/knoe.icns
|
|
file build/knoe.icns # Should say "Mac OS X icon"
|
|
```
|
|
|
|
### Binary Won't Run on Other Machines
|
|
|
|
**Cause:** PyInstaller doesn't include all dependencies, or architecture mismatch.
|
|
|
|
**Solutions:**
|
|
- Check target machine has same or newer macOS version
|
|
- Verify architecture matches (arm64 vs x86_64)
|
|
- Check Console.app for error messages
|
|
- Rebuild with `--debug` in spec file for verbose output
|
|
|
|
### GUI Doesn't Launch When Double-clicking
|
|
|
|
**Cause:** App not signed, or console mode preventing GUI launch.
|
|
|
|
**Solutions:**
|
|
- Right-click → Open (first time only, to bypass Gatekeeper)
|
|
- Check that `console=True` in spec allows both modes
|
|
- Run from Terminal to see error messages
|
|
|
|
### Ncurses Mode Garbled Output
|
|
|
|
**Cause:** Terminal doesn't support required features.
|
|
|
|
**Solution:** Use a modern terminal emulator (Terminal.app, iTerm2, etc.)
|
|
|
|
## Advanced Configuration
|
|
|
|
### Custom Icon
|
|
|
|
Replace `img/knoeIcon.png` with your icon (PNG format, preferably 1024x1024).
|
|
|
|
### Additional Data Files
|
|
|
|
Edit `scripts/generate_spec.py` and add to `datas` list:
|
|
```python
|
|
datas = [
|
|
('installer', 'installer'),
|
|
('your_data', 'your_data'), # Add this
|
|
]
|
|
```
|
|
|
|
### Code Signing
|
|
|
|
For distribution outside development:
|
|
|
|
1. Get Apple Developer certificate
|
|
2. Modify Makefile to add signing step:
|
|
```makefile
|
|
codesign --deep --force --verify --verbose \
|
|
--sign "Developer ID Application: Your Name" \
|
|
"dist/Knoe Installer.app"
|
|
```
|
|
|
|
### Notarization
|
|
|
|
For Gatekeeper approval on macOS 10.15+:
|
|
|
|
1. Sign the app
|
|
2. Create a DMG or ZIP
|
|
3. Submit to Apple:
|
|
```bash
|
|
xcrun notarytool submit knoe-installer.zip \
|
|
--apple-id your@email.com \
|
|
--password app-specific-password \
|
|
--team-id TEAMID
|
|
```
|
|
|
|
## Distribution
|
|
|
|
### DMG Creation
|
|
|
|
```bash
|
|
hdiutil create -volname "Knoe Installer" \
|
|
-srcfolder "dist/Knoe Installer.app" \
|
|
-ov -format UDZO \
|
|
knoe-installer.dmg
|
|
```
|
|
|
|
### ZIP Archive
|
|
|
|
```bash
|
|
cd dist
|
|
zip -r ../knoe-installer.zip "Knoe Installer.app"
|
|
```
|
|
|
|
## Performance Considerations
|
|
|
|
**Build Time:** 30-60 seconds typical
|
|
**Binary Size:** 50-100 MB (includes Python runtime + dependencies)
|
|
**Startup Time:** 1-3 seconds (PyInstaller extraction overhead)
|
|
|
|
To improve startup time, consider using PyInstaller's `--onedir` mode instead of `--onefile`, though this increases distribution complexity.
|
|
|
|
## CI/CD Integration
|
|
|
|
Example GitHub Actions workflow:
|
|
|
|
```yaml
|
|
name: Build Installer
|
|
on: [push]
|
|
jobs:
|
|
build:
|
|
runs-on: macos-latest
|
|
steps:
|
|
- uses: actions/checkout@v2
|
|
- uses: actions/setup-python@v2
|
|
with:
|
|
python-version: '3.11'
|
|
- run: make install
|
|
- run: make package
|
|
- uses: actions/upload-artifact@v2
|
|
with:
|
|
name: knoe-installer
|
|
path: dist/Knoe Installer.app
|
|
```
|
|
|
|
## References
|
|
|
|
- [PyInstaller Documentation](https://pyinstaller.org/)
|
|
- [macOS App Bundle Structure](https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html)
|
|
- [macOS Code Signing](https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution)
|