mirror of
https://github.com/dredx/prole.git
synced 2026-09-24 17:44:33 +00:00
- Bumped Prole-DB image version to 17.7-053 in scripts, Dockerfile, and manifests. - Replaced `prole-scan` with `prole-agent` throughout scripts and tests. - Refined Kubernetes setup for Supabase to use namespace 'supabase'. - Introduced conversion of Supabase Docker Compose to Kubernetes manifests with `kompose`. - Added support for Kerberos toggle via environment variables in `init_kerberos.sh`. - Improved error handling and logging in scripts for better maintainability.
309 lines
7.7 KiB
Markdown
309 lines
7.7 KiB
Markdown
# Embedded Resources in Prole Installer
|
|
|
|
## Overview
|
|
|
|
The Prole Installer package includes several embedded resources that must be accessible both when running from source and when packaged as a standalone binary.
|
|
|
|
## Embedded Resources
|
|
|
|
### 1. Images (img/)
|
|
- **proleIcon.png** (1.5 MB) - Application icon
|
|
- **proleLogo.png** (2.2 MB) - Main logo
|
|
- **proleLogoSepia.png** (2.7 MB) - Sepia background for GUI
|
|
- **proleLogoBlueprint.png** (3.1 MB) - Blueprint variant
|
|
- **proleIconblueprint.png** (1.6 MB) - Blueprint icon variant
|
|
|
|
### 2. Binary Executables
|
|
- **prole-net/prole-agent** (6.8 MB) - Network scanner
|
|
- Universal binary (x86_64 + arm64)
|
|
- Used by network scan screen
|
|
- Detects Kerberos, Active Directory, etc.
|
|
|
|
### 3. Application Bundles
|
|
- **prole-app/dist/Prole Tools.app** (~12 MB) - Pre-built Prole Tools
|
|
- Complete macOS .app bundle
|
|
- Used by installer creation screen
|
|
- Can be copied to DMG or USB installer
|
|
|
|
## How Embedding Works
|
|
|
|
### Resource Path Resolution
|
|
|
|
All resources use the `get_resource_path()` helper function:
|
|
|
|
```python
|
|
def get_resource_path(relative_path):
|
|
"""Get absolute path to resource, works for dev and for PyInstaller."""
|
|
try:
|
|
# PyInstaller creates a temp folder and stores path in _MEIPASS
|
|
base_path = Path(sys._MEIPASS)
|
|
except AttributeError:
|
|
# Running from source
|
|
base_path = PROJECT_ROOT
|
|
return base_path / relative_path
|
|
```
|
|
|
|
### Usage Examples
|
|
|
|
**Image Loading:**
|
|
```python
|
|
bg_path = get_resource_path('img/proleLogoSepia.png')
|
|
if bg_path.exists():
|
|
image = Image.open(str(bg_path))
|
|
```
|
|
|
|
**Binary Execution:**
|
|
```python
|
|
scan_binary = get_resource_path("prole-net/prole-agent")
|
|
if scan_binary.exists():
|
|
process = subprocess.Popen([str(scan_binary)], ...)
|
|
```
|
|
|
|
**App Bundle Access:**
|
|
```python
|
|
app_src = get_resource_path('prole-app/dist/Prole Tools.app')
|
|
if app_src.exists():
|
|
# Copy to destination
|
|
shutil.copytree(app_src, dest)
|
|
```
|
|
|
|
## PyInstaller Configuration
|
|
|
|
### Spec File (scripts/generate_spec.py)
|
|
|
|
**Data Files:**
|
|
```python
|
|
datas = [
|
|
('installer', 'installer'),
|
|
('conf', 'conf'),
|
|
('etc', 'etc'),
|
|
('img', 'img'),
|
|
('docs', 'docs'),
|
|
('prole-app/dist/Prole Tools.app', 'prole-app/dist/Prole Tools.app'),
|
|
]
|
|
```
|
|
|
|
**Binaries:**
|
|
```python
|
|
binaries = [
|
|
('prole-net/prole-agent', 'prole-net'),
|
|
]
|
|
```
|
|
|
|
The `binaries` list ensures executable permissions are preserved.
|
|
|
|
## File Sizes
|
|
|
|
Total embedded resources: ~30-35 MB
|
|
|
|
Breakdown:
|
|
- Images: ~11 MB
|
|
- prole-agent: 6.8 MB
|
|
- Prole Tools.app: ~12 MB
|
|
- Other resources: ~5-10 MB
|
|
|
|
Final installer bundle: ~50-100 MB (includes Python runtime)
|
|
|
|
## Usage in Installer
|
|
|
|
### Network Scan Screen
|
|
|
|
The network scan screen uses `prole-agent` to detect services:
|
|
|
|
```python
|
|
scan_binary = get_resource_path("prole-net/prole-agent")
|
|
process = subprocess.Popen([str(scan_binary)],
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.STDOUT,
|
|
text=True)
|
|
```
|
|
|
|
Output is captured in real-time and displayed in the scan results text widget.
|
|
|
|
### Installer Creation Screen
|
|
|
|
The installer creation screen copies Prole Tools.app to DMG:
|
|
|
|
```python
|
|
app_src = get_resource_path('prole-app/dist/Prole Tools.app')
|
|
if app_src.exists():
|
|
shutil.copytree(app_src, staging / 'Prole Tools.app')
|
|
```
|
|
|
|
## Testing
|
|
|
|
### Verify Resources from Source
|
|
|
|
```bash
|
|
python3 test_embedded_resources.sh
|
|
```
|
|
|
|
This tests:
|
|
- ✓ All image files exist
|
|
- ✓ prole-agent binary exists and is executable
|
|
- ✓ Prole Tools.app bundle exists
|
|
- ✓ Spec file includes all resources
|
|
- ✓ Resource sizes
|
|
|
|
### Verify Resources in Built Package
|
|
|
|
After building:
|
|
|
|
```bash
|
|
# Check extracted resources
|
|
./dist/prole-installer --help
|
|
|
|
# In another terminal, while installer is running:
|
|
ls -la /tmp/_MEI*/prole-net/
|
|
ls -la /tmp/_MEI*/img/
|
|
ls -la "/tmp/_MEI*/prole-app/dist/Prole Tools.app"
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Binary Not Found Error
|
|
|
|
**Error:** `Scan binary not found at /var/folders/.../prole-net/prole-agent`
|
|
|
|
**Cause:** Binary not included in package or path not using `get_resource_path()`
|
|
|
|
**Solution:**
|
|
1. Verify spec includes binary: `grep prole-agent installer.spec`
|
|
2. Check code uses `get_resource_path()`: `grep "get_resource_path.*prole-agent" install.py`
|
|
3. Rebuild: `make clean && make package`
|
|
|
|
### Binary Not Executable
|
|
|
|
**Error:** `Permission denied` when running prole-agent
|
|
|
|
**Cause:** Binary permissions not preserved in package
|
|
|
|
**Solution:**
|
|
Ensure binary is in `binaries` list (not `datas`) in spec file:
|
|
```python
|
|
binaries = [
|
|
('prole-net/prole-agent', 'prole-net'), # Correct - preserves +x
|
|
]
|
|
# NOT in datas:
|
|
# datas = [('prole-net/prole-agent', 'prole-net')] # Wrong - loses +x
|
|
```
|
|
|
|
### App Bundle Not Found
|
|
|
|
**Error:** `Prole Tools.app not found`
|
|
|
|
**Cause:** App not built before packaging installer
|
|
|
|
**Solution:**
|
|
1. Build Prole Tools.app first (in prole-app directory)
|
|
2. Verify it exists: `ls "prole-app/dist/Prole Tools.app"`
|
|
3. Then build installer: `make package`
|
|
|
|
### Large Bundle Size
|
|
|
|
**Cause:** Including large binary files significantly increases bundle size
|
|
|
|
**Optimization Options:**
|
|
1. **Compress app bundle:**
|
|
```bash
|
|
cd prole-app/dist
|
|
zip -r "Prole Tools.zip" "Prole Tools.app"
|
|
# Include zip instead of .app
|
|
```
|
|
|
|
2. **Download on demand:**
|
|
Instead of embedding, download from server when needed
|
|
|
|
3. **Exclude debug symbols:**
|
|
Strip binaries before packaging:
|
|
```bash
|
|
strip prole-net/prole-agent
|
|
```
|
|
|
|
## Build Process
|
|
|
|
When running `make package`:
|
|
|
|
1. **Icon conversion:** PNG → ICNS
|
|
2. **Spec generation:** Creates installer.spec with all resources
|
|
3. **PyInstaller:**
|
|
- Analyzes install.py
|
|
- Collects dependencies
|
|
- Copies data files (preserves directory structure)
|
|
- Copies binaries (preserves execute permissions)
|
|
- Creates single-file executable
|
|
4. **Bundle creation:** Packages into .app with icon
|
|
|
|
### Resource Extraction at Runtime
|
|
|
|
When the packaged installer runs:
|
|
|
|
1. PyInstaller extracts resources to `/tmp/_MEI<random>/`
|
|
2. Sets `sys._MEIPASS` to extraction directory
|
|
3. `get_resource_path()` uses `_MEIPASS` to find resources
|
|
4. Resources deleted automatically when installer exits
|
|
|
|
## Security Considerations
|
|
|
|
### Code Signing
|
|
|
|
Embedded binaries should be code signed:
|
|
|
|
```bash
|
|
codesign --force --sign "Developer ID Application: Your Name" prole-net/prole-agent
|
|
```
|
|
|
|
Then build the installer - the signed binary will be included.
|
|
|
|
### Verification
|
|
|
|
Users can verify embedded binaries:
|
|
|
|
```bash
|
|
# Check signature of prole-agent after extraction
|
|
codesign --verify --verbose /tmp/_MEI*/prole-net/prole-agent
|
|
|
|
# Check installer bundle signature
|
|
codesign --verify --verbose "dist/Prole Installer.app"
|
|
```
|
|
|
|
## Future Enhancements
|
|
|
|
### Lazy Loading
|
|
|
|
For large resources, consider lazy loading:
|
|
|
|
```python
|
|
def get_prole_tools_app():
|
|
"""Download or extract Prole Tools.app only when needed."""
|
|
app_path = get_resource_path('prole-app/dist/Prole Tools.app')
|
|
if not app_path.exists():
|
|
# Download from server
|
|
download_prole_tools(app_path)
|
|
return app_path
|
|
```
|
|
|
|
### Compression
|
|
|
|
Compress large resources:
|
|
|
|
```python
|
|
# In spec file
|
|
datas = [
|
|
('prole-app/dist/Prole Tools.zip', 'prole-app/dist'), # Compressed
|
|
]
|
|
|
|
# In code
|
|
def extract_prole_tools():
|
|
zip_path = get_resource_path('prole-app/dist/Prole Tools.zip')
|
|
extract_dir = Path(tempfile.mkdtemp())
|
|
shutil.unpack_archive(zip_path, extract_dir)
|
|
return extract_dir / 'Prole Tools.app'
|
|
```
|
|
|
|
## References
|
|
|
|
- [PyInstaller Data Files](https://pyinstaller.org/en/stable/spec-files.html#adding-data-files)
|
|
- [PyInstaller Binaries](https://pyinstaller.org/en/stable/spec-files.html#adding-binaries)
|
|
- [macOS App Bundle Structure](https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html)
|