eggpool 0.1.0__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {eggpool-0.1.0 → eggpool-0.1.2}/.github/workflows/ci.yml +5 -2
- {eggpool-0.1.0 → eggpool-0.1.2}/AGENTS.md +6 -2
- {eggpool-0.1.0 → eggpool-0.1.2}/CHANGELOG.md +21 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/PKG-INFO +42 -30
- {eggpool-0.1.0 → eggpool-0.1.2}/README.md +39 -28
- {eggpool-0.1.0 → eggpool-0.1.2}/architecture/README.md +1 -1
- eggpool-0.1.2/docs/deployment.md +235 -0
- eggpool-0.1.2/docs/raspberry-pi.md +93 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/pyproject.toml +5 -4
- {eggpool-0.1.0 → eggpool-0.1.2}/scripts/install.sh +5 -5
- eggpool-0.1.2/src/eggpool/__init__.py +10 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/api/proxy_request.py +2 -2
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/api/stats.py +10 -16
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/app.py +2 -1
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/catalog/cache.py +23 -32
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/cli.py +372 -37
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/routes.py +9 -15
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/deploy/__init__.py +105 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/onboard.py +18 -1
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/providers/connect.py +17 -23
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/providers/contract.py +8 -1
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/routing/provider.py +11 -4
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/stats/__init__.py +2 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/stats/service.py +21 -8
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/toml_edit.py +22 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/uv.lock +132 -4
- eggpool-0.1.0/docs/deployment.md +0 -322
- eggpool-0.1.0/docs/raspberry-pi.md +0 -356
- eggpool-0.1.0/src/eggpool/__init__.py +0 -5
- {eggpool-0.1.0 → eggpool-0.1.2}/.env.example +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/.github/workflows/release.yml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/.gitignore +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/LICENSE +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/config-examples/claude-code.env +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/config-examples/opencode.jsonc +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/config.example.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/deploy/eggpool-logrotate.conf +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/deploy/eggpool.service +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/deploy/env.example +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/docs/backup-restore.md +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/docs/filesystem-layout.md +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/docs/firewall.md +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/docs/model-limits.md +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/docs/providers.md +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/docs/proxy.md +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/scripts/__init__.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/scripts/check_database.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/scripts/install_prompt.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/scripts/smoke_test.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/scripts/verify_upstream_auth.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/__main__.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/_share/.env.example +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/_share/config.example.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/accounts/__init__.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/accounts/registry.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/accounts/state.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/api/__init__.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/api/chat_completions.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/api/errors.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/api/messages.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/api/models.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/auth.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/background/__init__.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/background/cleanup.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/catalog/__init__.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/catalog/fetcher.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/catalog/limits.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/catalog/normalizer.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/catalog/pricing.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/catalog/protocols.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/catalog/service.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/constants.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/__init__.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/_resources.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/escape.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/render.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/static/chart.umd.min.js +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/static/dashboard.css +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/static/favicon.svg +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/theme.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Booberry.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Catppuccin Latte.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Catppuccin Macchiato.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Catppuccin Mocha.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Cyber Red.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Cyberpunk.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Dark Green.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Discord (80_ Saturation).toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Discord.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Dracula.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Ferra Light.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Flexor Dark.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Gruvbox.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Halcyon Dark.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/IntelliJ Light.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Kanagawa.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Macaw Dark.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Macaw Light.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Matrix.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Noctis Lilac.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Nord.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Nostromo Terminal.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/One Dark.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Oxocarbon.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Rose Pine Dawn.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Rose Pine Moon.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Rose Pine.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Solarized Dark.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Sonokai.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Tokyo Night Storm.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/VESPER.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/Zenburn.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/acton.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/bam.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/base16-atelier-forest-light.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/berlin.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/black but with important highlights.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/broc.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/cork.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/ferra.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/forest.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/lisbon.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/midnight.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/oslo.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/plum.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/portland.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/sunset.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/tofino.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/vanimo.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/dashboard/themes/vik.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/__init__.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/connection.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/migrations.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/repositories.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0001_initial.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0002_indexes.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0003_request_attempts.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0004_integration_hardening.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0005_price_microdollars.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0006_correct_price_microdollars.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0007_price_cache_rates.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0008_proxy_request_identity.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0009_model_protocol_source.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0010_health_probe.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0011_model_resolution_status.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0012_drop_reservations_estimated_microdollars.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0013_request_attempts_account_id_index.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0014_bandwidth_tracking.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0015_multi_provider.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0016_requests_provider_id.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0017_price_snapshots_provider_id.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0018_provider_pings.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0019_client_ip.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0020_performance_indexes.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0021_provider_model_metadata.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/0022_dashboard_indexes.sql +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/db/schema/checksums.json +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/errors.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/health/__init__.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/health/circuit_breaker.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/health/health_manager.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/integrations/__init__.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/integrations/opencode.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/logging.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/models/__init__.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/models/api.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/models/config.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/models/database.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/models/domain.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/providers/__init__.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/providers/_templates.toml +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/providers/client_pool.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/providers/pproxy_transport.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/proxy/__init__.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/proxy/client.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/proxy/sse_observer.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/proxy/usage.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/py.typed +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/quota/__init__.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/quota/estimation.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/quota/reservation.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/quota/scorer.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/request/__init__.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/request/attempt_finalizer.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/request/body.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/request/coordinator.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/request/finalizer.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/request/limits.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/retry/__init__.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/retry/classification.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/routing/__init__.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/routing/eligibility.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/routing/router.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/security/__init__.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/security/redaction.py +0 -0
- {eggpool-0.1.0 → eggpool-0.1.2}/src/eggpool/stats/queries.py +0 -0
|
@@ -36,12 +36,15 @@ jobs:
|
|
|
36
36
|
|
|
37
37
|
test:
|
|
38
38
|
runs-on: ubuntu-latest
|
|
39
|
+
strategy:
|
|
40
|
+
matrix:
|
|
41
|
+
python-version: ["3.11", "3.12"]
|
|
39
42
|
steps:
|
|
40
43
|
- uses: actions/checkout@v4
|
|
41
44
|
- uses: astral-sh/setup-uv@v4
|
|
42
45
|
- uses: actions/setup-python@v5
|
|
43
46
|
with:
|
|
44
|
-
python-version:
|
|
47
|
+
python-version: ${{ matrix.python-version }}
|
|
45
48
|
- run: uv sync --frozen --extra dev
|
|
46
49
|
- name: Verify coverage plugin is present
|
|
47
50
|
run: uv run pytest --help | grep -- --cov
|
|
@@ -55,5 +58,5 @@ jobs:
|
|
|
55
58
|
if: always()
|
|
56
59
|
uses: actions/upload-artifact@v4
|
|
57
60
|
with:
|
|
58
|
-
name: coverage-report
|
|
61
|
+
name: coverage-report-py${{ matrix.python-version }}
|
|
59
62
|
path: coverage.xml
|
|
@@ -27,7 +27,7 @@ All four must pass with zero errors.
|
|
|
27
27
|
|
|
28
28
|
## Code Style
|
|
29
29
|
|
|
30
|
-
- Python 3.
|
|
30
|
+
- Python 3.11+ with `from __future__ import annotations` in ALL files
|
|
31
31
|
- Type hints on all function signatures and return types
|
|
32
32
|
- Ruff: E, F, W, I, N, UP, B, A, SIM, TCH rules
|
|
33
33
|
- Pyright strict mode — covers `src/` AND `scripts/` (not tests)
|
|
@@ -92,19 +92,23 @@ Use the hierarchy in `errors.py`. Chain exceptions with `raise ... from err` or
|
|
|
92
92
|
|
|
93
93
|
| Command | Description |
|
|
94
94
|
|---------|-------------|
|
|
95
|
+
| `eggpool help` | Show help message and available commands |
|
|
96
|
+
| `eggpool version` | Print the installed version |
|
|
95
97
|
| `eggpool serve` | Start the aggregation proxy server (default command) |
|
|
96
98
|
| `eggpool check-config` | Validate the configuration file |
|
|
97
99
|
| `eggpool migrate` | Run database migrations |
|
|
98
|
-
| `eggpool onboard` | Run the interactive onboarding setup |
|
|
100
|
+
| `eggpool onboard` | Run the interactive onboarding setup (connect providers, start server) |
|
|
99
101
|
| `eggpool connect` | Connect to a new provider interactively |
|
|
100
102
|
| `eggpool connect list` | List available providers |
|
|
101
103
|
| `eggpool logout` | Remove a configured provider account |
|
|
102
104
|
| `eggpool rehash` | Restart to apply config changes |
|
|
105
|
+
| `eggpool croncheck` | Lightweight check: exit 0 if server is running, exit 1 if not |
|
|
103
106
|
| `eggpool models refresh` | Refresh model catalog from upstream |
|
|
104
107
|
| `eggpool configsetup opencode` | Print OpenCode provider config JSON with model limits |
|
|
105
108
|
| `eggpool db vacuum` | Reclaim SQLite space |
|
|
106
109
|
|
|
107
110
|
All commands accept `--config /path/to/config.toml` (defaults to `config.toml`).
|
|
111
|
+
Running `eggpool` with no arguments prints the help message.
|
|
108
112
|
|
|
109
113
|
## Git Workflow
|
|
110
114
|
|
|
@@ -5,6 +5,27 @@ All notable changes to EggPool are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.1.2] - 2026-06-23
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Create minimal config when `config.toml` is missing during `eggpool
|
|
13
|
+
onboard`, so fresh installs no longer fail with "Failed to update config".
|
|
14
|
+
- Fix `update` command misidentifying source installs as pipx (causing
|
|
15
|
+
wrong upgrade method).
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- Add `--install` flag to `deploy` subcommands for automated setup.
|
|
20
|
+
- Rewrite deployment docs with personal-use and production sections.
|
|
21
|
+
|
|
22
|
+
## [0.1.1] - 2026-06-23
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- `eggpool deploy` subcommands: `systemd`, `logrotate`, `cron`, `all`.
|
|
27
|
+
- Dynamic deploy snippets based on detected install paths.
|
|
28
|
+
|
|
8
29
|
## [0.1.0] - 2026-06-23
|
|
9
30
|
|
|
10
31
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: eggpool
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: A lightweight proxy that aggregates multiple LLM provider accounts behind one OpenAI-compatible endpoint
|
|
5
5
|
Project-URL: Homepage, https://github.com/eggstack/eggpool
|
|
6
6
|
Project-URL: Repository, https://github.com/eggstack/eggpool
|
|
@@ -19,10 +19,11 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
19
19
|
Classifier: Operating System :: POSIX :: Linux
|
|
20
20
|
Classifier: Programming Language :: Python :: 3
|
|
21
21
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
23
|
Classifier: Programming Language :: Python :: 3.12
|
|
23
24
|
Classifier: Topic :: System :: Monitoring
|
|
24
25
|
Classifier: Typing :: Typed
|
|
25
|
-
Requires-Python: >=3.
|
|
26
|
+
Requires-Python: >=3.11
|
|
26
27
|
Requires-Dist: aiosqlite
|
|
27
28
|
Requires-Dist: click
|
|
28
29
|
Requires-Dist: fastapi
|
|
@@ -42,7 +43,7 @@ Requires-Dist: ruff; extra == 'dev'
|
|
|
42
43
|
Description-Content-Type: text/markdown
|
|
43
44
|
|
|
44
45
|
[](https://pypi.org/project/eggpool/)
|
|
45
|
-
[](https://www.python.org/)
|
|
46
47
|
[](LICENSE)
|
|
47
48
|
[](https://github.com/eggstack/eggpool/actions/workflows/ci.yml)
|
|
48
49
|
|
|
@@ -65,7 +66,7 @@ behind one OpenAI/Anthropic-compatible endpoint.
|
|
|
65
66
|
|
|
66
67
|
## Requirements
|
|
67
68
|
|
|
68
|
-
- Python 3.
|
|
69
|
+
- Python 3.11+
|
|
69
70
|
- [uv](https://docs.astral.sh/uv/) for dependency management
|
|
70
71
|
|
|
71
72
|
## Quick Start
|
|
@@ -74,25 +75,16 @@ behind one OpenAI/Anthropic-compatible endpoint.
|
|
|
74
75
|
|
|
75
76
|
```bash
|
|
76
77
|
pipx install eggpool
|
|
77
|
-
|
|
78
|
+
eggpool help
|
|
79
|
+
eggpool onboard
|
|
78
80
|
```
|
|
79
81
|
|
|
80
|
-
`
|
|
81
|
-
`eggpool`
|
|
82
|
-
provider templates ship inside the package — no extra files
|
|
83
|
-
required to start.
|
|
82
|
+
`eggpool onboard` lets you add several providers at once, does a config check, then runs the server. You can also run `eggpool connect` for each provider you want to add and `eggpool serve` to start the server.
|
|
83
|
+
`eggpool configsetup` will help setup config for opencode.
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
To get the server to run on startup, run `eggpool deploy` for options, see docs/deployment.md for more info and configs.
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
cp /path/to/your/eggpool-venv/lib/python*/site-packages/eggpool/_share/config.example.toml ~/.config/eggpool/config.toml
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
Or use the built-in helper:
|
|
92
|
-
|
|
93
|
-
```bash
|
|
94
|
-
eggpool init-config
|
|
95
|
-
```
|
|
87
|
+
`pipx` installs `eggpool` into its own venv and exposes the `eggpool` command on your PATH.
|
|
96
88
|
|
|
97
89
|
### Option 2: Automated install
|
|
98
90
|
|
|
@@ -104,13 +96,14 @@ The script:
|
|
|
104
96
|
|
|
105
97
|
- Downloads the repository if not running from a clone
|
|
106
98
|
- Installs `uv` if missing
|
|
107
|
-
- Verifies Python 3.
|
|
99
|
+
- Verifies Python 3.11+
|
|
108
100
|
- Installs dependencies
|
|
109
101
|
- Copies example configuration files
|
|
110
102
|
- Attempts configuration validation
|
|
111
103
|
|
|
112
|
-
|
|
113
|
-
|
|
104
|
+
The script will ask if you want to continue with onboarding. if you select no, make sure you `cd eggpool`, then you can run `uv run eggpool onboard` to get started. `uv run eggpool connect` for one off provider adds, `uv run eggpool serve` to start server. `uv run eggpool help` for other commands.
|
|
105
|
+
|
|
106
|
+
Run `uv run eggpool deploy` for options on running the server on startup. See docs/deployment.md for more info and configs.
|
|
114
107
|
|
|
115
108
|
### Option 3: Manual install
|
|
116
109
|
|
|
@@ -127,19 +120,20 @@ cp .env.example .env
|
|
|
127
120
|
|
|
128
121
|
# Validate configuration
|
|
129
122
|
set -a; source .env; set +a
|
|
130
|
-
uv run eggpool
|
|
123
|
+
uv run eggpool check-config
|
|
131
124
|
|
|
132
125
|
# Run database migrations
|
|
133
|
-
uv run eggpool
|
|
126
|
+
uv run eggpool migrate
|
|
134
127
|
|
|
135
128
|
# Start the server
|
|
136
|
-
uv run eggpool
|
|
129
|
+
uv run eggpool serve
|
|
137
130
|
```
|
|
138
131
|
|
|
139
132
|
### Option 4: Interactive setup
|
|
140
133
|
|
|
141
134
|
```bash
|
|
142
|
-
# Run the interactive onboarding wizard
|
|
135
|
+
# Run the interactive onboarding wizard — connects one or more
|
|
136
|
+
# providers, validates configuration, and starts the server.
|
|
143
137
|
uv run eggpool onboard
|
|
144
138
|
|
|
145
139
|
# Or connect to a specific provider
|
|
@@ -151,10 +145,12 @@ uv run eggpool connect list
|
|
|
151
145
|
|
|
152
146
|
| Command | Description |
|
|
153
147
|
|---------|-------------|
|
|
148
|
+
| `eggpool help` | Show help message and available commands |
|
|
149
|
+
| `eggpool version` | Print the installed version |
|
|
154
150
|
| `eggpool serve` | Start the aggregation proxy server (default command) |
|
|
155
151
|
| `eggpool check-config` | Validate the configuration file |
|
|
156
152
|
| `eggpool migrate` | Run database migrations |
|
|
157
|
-
| `eggpool onboard` | Run the interactive onboarding setup |
|
|
153
|
+
| `eggpool onboard` | Run the interactive onboarding setup (connect providers, start server) |
|
|
158
154
|
| `eggpool connect` | Connect to a new provider interactively |
|
|
159
155
|
| `eggpool connect list` | List available providers for connection |
|
|
160
156
|
| `eggpool logout` | Remove a configured provider account |
|
|
@@ -169,6 +165,7 @@ uv run eggpool connect list
|
|
|
169
165
|
| `eggpool configsetup opencode` | Print OpenCode provider config JSON with model limits |
|
|
170
166
|
| `eggpool configsetup claude-code` | Print Claude Code config snippet |
|
|
171
167
|
| `eggpool update` | Check for updates and reinstall if newer |
|
|
168
|
+
| `eggpool croncheck` | Lightweight check: exit 0 if server is running, exit 1 if not |
|
|
172
169
|
| `eggpool models refresh` | Refresh the model catalog from upstream |
|
|
173
170
|
| `eggpool accounts status` | Show configured account status |
|
|
174
171
|
| `eggpool accounts list` | List configured provider accounts |
|
|
@@ -181,6 +178,7 @@ uv run eggpool connect list
|
|
|
181
178
|
| `eggpool deploy all` | Print every deployment snippet in sequence |
|
|
182
179
|
|
|
183
180
|
All commands accept `--config /path/to/config.toml` (defaults to `config.toml`).
|
|
181
|
+
Running `eggpool` with no arguments prints the help message.
|
|
184
182
|
Configuration changes require a service restart; live reload is intentionally
|
|
185
183
|
not supported.
|
|
186
184
|
|
|
@@ -492,14 +490,28 @@ MIT
|
|
|
492
490
|
|
|
493
491
|
## Deployment
|
|
494
492
|
|
|
495
|
-
See `docs/deployment.md` for
|
|
493
|
+
See `docs/deployment.md` for full deployment instructions.
|
|
496
494
|
|
|
497
|
-
|
|
495
|
+
### Quick start (personal use)
|
|
498
496
|
|
|
499
497
|
```bash
|
|
500
|
-
|
|
498
|
+
pipx install eggpool
|
|
499
|
+
eggpool onboard
|
|
500
|
+
sudo eggpool deploy systemd --install
|
|
501
501
|
```
|
|
502
502
|
|
|
503
|
+
The `--install` flag writes the systemd unit, enables the service,
|
|
504
|
+
and starts it — all in one command. It detects your install method
|
|
505
|
+
and config paths automatically.
|
|
506
|
+
|
|
507
|
+
### Production (separate user, hardened)
|
|
508
|
+
|
|
509
|
+
For public-facing deployments, see the Production Deployment section
|
|
510
|
+
in `docs/deployment.md`. This creates a dedicated `eggpool` system
|
|
511
|
+
user with proper file permissions.
|
|
512
|
+
|
|
513
|
+
### Configuration changes
|
|
514
|
+
|
|
503
515
|
Configuration changes require a service restart; the unit
|
|
504
516
|
intentionally does not advertise any reload action:
|
|
505
517
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
[](https://pypi.org/project/eggpool/)
|
|
2
|
-
[](https://www.python.org/)
|
|
3
3
|
[](LICENSE)
|
|
4
4
|
[](https://github.com/eggstack/eggpool/actions/workflows/ci.yml)
|
|
5
5
|
|
|
@@ -22,7 +22,7 @@ behind one OpenAI/Anthropic-compatible endpoint.
|
|
|
22
22
|
|
|
23
23
|
## Requirements
|
|
24
24
|
|
|
25
|
-
- Python 3.
|
|
25
|
+
- Python 3.11+
|
|
26
26
|
- [uv](https://docs.astral.sh/uv/) for dependency management
|
|
27
27
|
|
|
28
28
|
## Quick Start
|
|
@@ -31,25 +31,16 @@ behind one OpenAI/Anthropic-compatible endpoint.
|
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
33
|
pipx install eggpool
|
|
34
|
-
|
|
34
|
+
eggpool help
|
|
35
|
+
eggpool onboard
|
|
35
36
|
```
|
|
36
37
|
|
|
37
|
-
`
|
|
38
|
-
`eggpool`
|
|
39
|
-
provider templates ship inside the package — no extra files
|
|
40
|
-
required to start.
|
|
38
|
+
`eggpool onboard` lets you add several providers at once, does a config check, then runs the server. You can also run `eggpool connect` for each provider you want to add and `eggpool serve` to start the server.
|
|
39
|
+
`eggpool configsetup` will help setup config for opencode.
|
|
41
40
|
|
|
42
|
-
|
|
41
|
+
To get the server to run on startup, run `eggpool deploy` for options, see docs/deployment.md for more info and configs.
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
cp /path/to/your/eggpool-venv/lib/python*/site-packages/eggpool/_share/config.example.toml ~/.config/eggpool/config.toml
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Or use the built-in helper:
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
eggpool init-config
|
|
52
|
-
```
|
|
43
|
+
`pipx` installs `eggpool` into its own venv and exposes the `eggpool` command on your PATH.
|
|
53
44
|
|
|
54
45
|
### Option 2: Automated install
|
|
55
46
|
|
|
@@ -61,13 +52,14 @@ The script:
|
|
|
61
52
|
|
|
62
53
|
- Downloads the repository if not running from a clone
|
|
63
54
|
- Installs `uv` if missing
|
|
64
|
-
- Verifies Python 3.
|
|
55
|
+
- Verifies Python 3.11+
|
|
65
56
|
- Installs dependencies
|
|
66
57
|
- Copies example configuration files
|
|
67
58
|
- Attempts configuration validation
|
|
68
59
|
|
|
69
|
-
|
|
70
|
-
|
|
60
|
+
The script will ask if you want to continue with onboarding. if you select no, make sure you `cd eggpool`, then you can run `uv run eggpool onboard` to get started. `uv run eggpool connect` for one off provider adds, `uv run eggpool serve` to start server. `uv run eggpool help` for other commands.
|
|
61
|
+
|
|
62
|
+
Run `uv run eggpool deploy` for options on running the server on startup. See docs/deployment.md for more info and configs.
|
|
71
63
|
|
|
72
64
|
### Option 3: Manual install
|
|
73
65
|
|
|
@@ -84,19 +76,20 @@ cp .env.example .env
|
|
|
84
76
|
|
|
85
77
|
# Validate configuration
|
|
86
78
|
set -a; source .env; set +a
|
|
87
|
-
uv run eggpool
|
|
79
|
+
uv run eggpool check-config
|
|
88
80
|
|
|
89
81
|
# Run database migrations
|
|
90
|
-
uv run eggpool
|
|
82
|
+
uv run eggpool migrate
|
|
91
83
|
|
|
92
84
|
# Start the server
|
|
93
|
-
uv run eggpool
|
|
85
|
+
uv run eggpool serve
|
|
94
86
|
```
|
|
95
87
|
|
|
96
88
|
### Option 4: Interactive setup
|
|
97
89
|
|
|
98
90
|
```bash
|
|
99
|
-
# Run the interactive onboarding wizard
|
|
91
|
+
# Run the interactive onboarding wizard — connects one or more
|
|
92
|
+
# providers, validates configuration, and starts the server.
|
|
100
93
|
uv run eggpool onboard
|
|
101
94
|
|
|
102
95
|
# Or connect to a specific provider
|
|
@@ -108,10 +101,12 @@ uv run eggpool connect list
|
|
|
108
101
|
|
|
109
102
|
| Command | Description |
|
|
110
103
|
|---------|-------------|
|
|
104
|
+
| `eggpool help` | Show help message and available commands |
|
|
105
|
+
| `eggpool version` | Print the installed version |
|
|
111
106
|
| `eggpool serve` | Start the aggregation proxy server (default command) |
|
|
112
107
|
| `eggpool check-config` | Validate the configuration file |
|
|
113
108
|
| `eggpool migrate` | Run database migrations |
|
|
114
|
-
| `eggpool onboard` | Run the interactive onboarding setup |
|
|
109
|
+
| `eggpool onboard` | Run the interactive onboarding setup (connect providers, start server) |
|
|
115
110
|
| `eggpool connect` | Connect to a new provider interactively |
|
|
116
111
|
| `eggpool connect list` | List available providers for connection |
|
|
117
112
|
| `eggpool logout` | Remove a configured provider account |
|
|
@@ -126,6 +121,7 @@ uv run eggpool connect list
|
|
|
126
121
|
| `eggpool configsetup opencode` | Print OpenCode provider config JSON with model limits |
|
|
127
122
|
| `eggpool configsetup claude-code` | Print Claude Code config snippet |
|
|
128
123
|
| `eggpool update` | Check for updates and reinstall if newer |
|
|
124
|
+
| `eggpool croncheck` | Lightweight check: exit 0 if server is running, exit 1 if not |
|
|
129
125
|
| `eggpool models refresh` | Refresh the model catalog from upstream |
|
|
130
126
|
| `eggpool accounts status` | Show configured account status |
|
|
131
127
|
| `eggpool accounts list` | List configured provider accounts |
|
|
@@ -138,6 +134,7 @@ uv run eggpool connect list
|
|
|
138
134
|
| `eggpool deploy all` | Print every deployment snippet in sequence |
|
|
139
135
|
|
|
140
136
|
All commands accept `--config /path/to/config.toml` (defaults to `config.toml`).
|
|
137
|
+
Running `eggpool` with no arguments prints the help message.
|
|
141
138
|
Configuration changes require a service restart; live reload is intentionally
|
|
142
139
|
not supported.
|
|
143
140
|
|
|
@@ -449,14 +446,28 @@ MIT
|
|
|
449
446
|
|
|
450
447
|
## Deployment
|
|
451
448
|
|
|
452
|
-
See `docs/deployment.md` for
|
|
449
|
+
See `docs/deployment.md` for full deployment instructions.
|
|
453
450
|
|
|
454
|
-
|
|
451
|
+
### Quick start (personal use)
|
|
455
452
|
|
|
456
453
|
```bash
|
|
457
|
-
|
|
454
|
+
pipx install eggpool
|
|
455
|
+
eggpool onboard
|
|
456
|
+
sudo eggpool deploy systemd --install
|
|
458
457
|
```
|
|
459
458
|
|
|
459
|
+
The `--install` flag writes the systemd unit, enables the service,
|
|
460
|
+
and starts it — all in one command. It detects your install method
|
|
461
|
+
and config paths automatically.
|
|
462
|
+
|
|
463
|
+
### Production (separate user, hardened)
|
|
464
|
+
|
|
465
|
+
For public-facing deployments, see the Production Deployment section
|
|
466
|
+
in `docs/deployment.md`. This creates a dedicated `eggpool` system
|
|
467
|
+
user with proper file permissions.
|
|
468
|
+
|
|
469
|
+
### Configuration changes
|
|
470
|
+
|
|
460
471
|
Configuration changes require a service restart; the unit
|
|
461
472
|
intentionally does not advertise any reload action:
|
|
462
473
|
|
|
@@ -87,7 +87,7 @@ Legacy flat `[[accounts]]` configs auto-normalize to a default `opencode-go` pro
|
|
|
87
87
|
|
|
88
88
|
### Model ID Format
|
|
89
89
|
|
|
90
|
-
Models are exposed with provider-suffixed IDs: `model-id/provider-id` (e.g., `claude-sonnet-4/opencode-go`). `
|
|
90
|
+
Models are exposed with provider-suffixed IDs: `model-id/provider-id` (e.g., `claude-sonnet-4/opencode-go`). `parse_model_provider()` in `routing/provider.py` is the canonical suffix parser; `catalog/cache.py` retains a compatibility alias.
|
|
91
91
|
|
|
92
92
|
### Provider-Specific Paths
|
|
93
93
|
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Deployment Guide
|
|
2
|
+
|
|
3
|
+
Two deployment modes: **personal use** (quick, current user) and
|
|
4
|
+
**production** (separate user, hardened). Pick the one that fits.
|
|
5
|
+
|
|
6
|
+
## Personal Use (Recommended for LAN/Raspberry Pi)
|
|
7
|
+
|
|
8
|
+
Runs under your current user with your existing config. Not intended
|
|
9
|
+
for public-facing deployments.
|
|
10
|
+
|
|
11
|
+
### 1. Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pipx install eggpool
|
|
15
|
+
eggpool onboard
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Or from source:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
git clone https://github.com/eggstack/eggpool.git && cd eggpool
|
|
22
|
+
uv sync --no-dev
|
|
23
|
+
uv run eggpool onboard
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 2. Start on boot
|
|
27
|
+
|
|
28
|
+
The `--install` flag writes the systemd unit, enables the service,
|
|
29
|
+
and starts it — all in one command:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
sudo eggpool deploy systemd --install
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
This generates a unit file tailored to your system (correct binary
|
|
36
|
+
path, config path, data directory) and sets it up automatically.
|
|
37
|
+
|
|
38
|
+
Without `--install`, the command prints copy-paste instructions
|
|
39
|
+
instead.
|
|
40
|
+
|
|
41
|
+
### 3. Verify
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
sudo systemctl status eggpool
|
|
45
|
+
curl http://localhost:11300/v1/healthz
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Other deploy commands
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Set up logrotate
|
|
52
|
+
sudo eggpool deploy logrotate --install
|
|
53
|
+
|
|
54
|
+
# Set up daily backup cron (user cron, ~/backups/eggpool/)
|
|
55
|
+
sudo eggpool deploy cron --install
|
|
56
|
+
|
|
57
|
+
# Set up everything at once
|
|
58
|
+
sudo eggpool deploy all --install
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Without `--install`, each command prints the snippet and manual
|
|
62
|
+
instructions for you to copy-paste.
|
|
63
|
+
|
|
64
|
+
### Configuration changes
|
|
65
|
+
|
|
66
|
+
Live reload is not supported. Restart after any config change:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
sudo systemctl restart eggpool
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Logs
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
sudo journalctl -u eggpool -f
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Alternative: cron (no systemd)
|
|
79
|
+
|
|
80
|
+
For systems without systemd, `deploy cron` sets up a user cron
|
|
81
|
+
entry that checks if the server is running and restarts it:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Check every 5 minutes, restart if stopped
|
|
85
|
+
eggpool croncheck || eggpool serve &
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
This is a personal-use fallback — prefer systemd when available.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Production Deployment
|
|
93
|
+
|
|
94
|
+
For public-facing or multi-user deployments. Uses a dedicated
|
|
95
|
+
`eggpool` system user with proper file permissions and a hardened
|
|
96
|
+
systemd unit.
|
|
97
|
+
|
|
98
|
+
**Not recommended for personal LAN use** — the personal-use path
|
|
99
|
+
above is simpler and sufficient for single-user setups.
|
|
100
|
+
|
|
101
|
+
### 1. Create system user
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
sudo useradd -r -s /usr/sbin/nologin -d /var/lib/eggpool eggpool
|
|
105
|
+
sudo mkdir -p /var/lib/eggpool /var/log/eggpool /etc/eggpool
|
|
106
|
+
sudo chown eggpool:eggpool /var/lib/eggpool /var/log/eggpool
|
|
107
|
+
sudo chown root:eggpool /etc/eggpool
|
|
108
|
+
sudo chmod 750 /var/lib/eggpool /var/log/eggpool
|
|
109
|
+
sudo chmod 755 /etc/eggpool
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 2. Install application
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
cd /opt
|
|
116
|
+
sudo git clone https://github.com/eggstack/eggpool.git
|
|
117
|
+
sudo chown -R root:eggpool /opt/eggpool
|
|
118
|
+
cd /opt/eggpool
|
|
119
|
+
sudo uv sync --no-dev
|
|
120
|
+
sudo chown -R root:eggpool /opt/eggpool
|
|
121
|
+
sudo chmod -R o+rX /opt/eggpool
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 3. Configure
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
sudo cp config.example.toml /etc/eggpool/config.toml
|
|
128
|
+
sudo cp deploy/env.example /etc/eggpool/env
|
|
129
|
+
sudo chown root:eggpool /etc/eggpool/config.toml /etc/eggpool/env
|
|
130
|
+
sudo chmod 640 /etc/eggpool/config.toml /etc/eggpool/env
|
|
131
|
+
|
|
132
|
+
sudo nano /etc/eggpool/config.toml
|
|
133
|
+
sudo nano /etc/eggpool/env
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Minimal config:
|
|
137
|
+
|
|
138
|
+
```toml
|
|
139
|
+
[server]
|
|
140
|
+
host = "0.0.0.0"
|
|
141
|
+
port = 11300
|
|
142
|
+
|
|
143
|
+
[database]
|
|
144
|
+
path = "/var/lib/eggpool/usage.sqlite3"
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### 4. Validate and start
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
sudo -u eggpool bash -c 'set -a; source /etc/eggpool/env; set +a; /opt/eggpool/.venv/bin/eggpool check-config --config /etc/eggpool/config.toml'
|
|
151
|
+
sudo -u eggpool /opt/eggpool/.venv/bin/eggpool migrate --config /etc/eggpool/config.toml
|
|
152
|
+
|
|
153
|
+
# Install the hardened systemd unit
|
|
154
|
+
sudo cp deploy/eggpool.service /etc/systemd/system/
|
|
155
|
+
sudo systemctl daemon-reload
|
|
156
|
+
sudo systemctl enable eggpool
|
|
157
|
+
sudo systemctl start eggpool
|
|
158
|
+
sudo systemctl status eggpool
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 5. Logrotate
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
sudo cp deploy/eggpool-logrotate.conf /etc/logrotate.d/eggpool
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 6. Automated backup
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
sudo cp deploy/eggpool.service /etc/systemd/system/
|
|
171
|
+
# Or use the deploy command:
|
|
172
|
+
sudo eggpool deploy cron
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Filesystem layout
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
/etc/eggpool/
|
|
179
|
+
├── config.toml # Configuration
|
|
180
|
+
└── env # API keys
|
|
181
|
+
|
|
182
|
+
/var/lib/eggpool/
|
|
183
|
+
├── usage.sqlite3 # Database
|
|
184
|
+
├── usage.sqlite3-wal # WAL journal
|
|
185
|
+
└── usage.sqlite3-shm # Shared memory
|
|
186
|
+
|
|
187
|
+
/opt/eggpool/
|
|
188
|
+
├── .venv/ # Python virtual environment
|
|
189
|
+
└── src/ # Application source
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Systemd unit features
|
|
193
|
+
|
|
194
|
+
- `ProtectSystem=strict` — read-only system directories
|
|
195
|
+
- `ReadWritePaths=/var/lib/eggpool` — data directory writable
|
|
196
|
+
- `NoNewPrivileges`, `PrivateTmp`, `RestrictNamespaces` — hardened
|
|
197
|
+
- No `ExecReload` — config changes require `systemctl restart`
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Troubleshooting
|
|
202
|
+
|
|
203
|
+
### Service fails to start
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
sudo journalctl -u eggpool --since "5 minutes ago"
|
|
207
|
+
# or for personal use:
|
|
208
|
+
sudo journalctl -u eggpool -n 50 --no-pager
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Database locked errors
|
|
212
|
+
|
|
213
|
+
1. Ensure only one instance: `pgrep -f eggpool`
|
|
214
|
+
2. Confirm WAL mode in config
|
|
215
|
+
3. Increase `busy_timeout_ms` (try `10000` on Pi)
|
|
216
|
+
|
|
217
|
+
### Cannot connect from LAN
|
|
218
|
+
|
|
219
|
+
1. Verify `server.host = "0.0.0.0"` in config
|
|
220
|
+
2. Check firewall: `ss -tlnp | grep 11300`
|
|
221
|
+
3. See `docs/firewall.md`
|
|
222
|
+
|
|
223
|
+
### Deploy commands reference
|
|
224
|
+
|
|
225
|
+
| Command | Description |
|
|
226
|
+
|---------|-------------|
|
|
227
|
+
| `eggpool deploy systemd` | Print systemd unit + instructions |
|
|
228
|
+
| `eggpool deploy systemd --install` | Write unit, enable, start |
|
|
229
|
+
| `eggpool deploy logrotate` | Print logrotate config |
|
|
230
|
+
| `eggpool deploy logrotate --install` | Write logrotate config |
|
|
231
|
+
| `eggpool deploy cron` | Print backup cron entry |
|
|
232
|
+
| `eggpool deploy cron --install` | Write backup script + cron entry |
|
|
233
|
+
| `eggpool deploy all` | Print all snippets |
|
|
234
|
+
| `eggpool deploy all --install` | Install everything |
|
|
235
|
+
| `eggpool croncheck` | Check if server is running (exit 0/1) |
|