portacode 1.4.16.dev2__tar.gz → 1.4.16.dev4__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.
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/PKG-INFO +1 -1
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/_version.py +2 -2
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/WEBSOCKET_PROTOCOL.md +28 -16
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/proxmox_infra.py +193 -44
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode.egg-info/PKG-INFO +1 -1
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/.claude/agents/communication-manager.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/.claude/settings.local.json +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/.gitignore +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/.gitmodules +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/LICENSE +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/MANIFEST.in +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/Makefile +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/backup.sh +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/connect.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/connect.sh +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/docker-compose.yaml +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/docs/images/device-transfer-button.png +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/docs/images/device-transfer-modal.png +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/docs/images/pair-device-button.png +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/docs/images/pairing-request.png +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/docs/images/student-workspace.png +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/simple_device/Dockerfile +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/simple_device/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/simple_device/data/device-01/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/simple_device/data/device-01/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/simple_device/docker-compose.yaml +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/Dockerfile +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/.local/share/portacode/run/gateway.pid +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/.gitignore +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/db.sqlite3 +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/__init__.cpython-311.pyc +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/settings.cpython-311.pyc +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/urls.cpython-311.pyc +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/wsgi.cpython-311.pyc +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/manage.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/requirements.txt +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/templates/treats/home.html +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/__init__.cpython-311.pyc +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/admin.cpython-311.pyc +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/apps.cpython-311.pyc +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/menu.cpython-311.pyc +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/models.cpython-311.pyc +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/urls.cpython-311.pyc +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/views.cpython-311.pyc +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/admin.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/apps.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/menu.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/migrations/__pycache__/__init__.cpython-311.pyc +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/models.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/tests.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/views.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/workspace/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/workspace/manage.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/workspace/requirements.txt +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/workspace/templates/treats/home.html +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/workspace/treats/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/workspace/treats/admin.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/workspace/treats/apps.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/workspace/treats/menu.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/workspace/treats/models.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/workspace/treats/tests.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/workspace/treats/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-02/workspace/treats/views.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/workspace/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/workspace/manage.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/workspace/requirements.txt +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/workspace/templates/treats/home.html +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/workspace/treats/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/workspace/treats/admin.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/workspace/treats/apps.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/workspace/treats/menu.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/workspace/treats/models.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/workspace/treats/tests.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/workspace/treats/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-03/workspace/treats/views.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/workspace/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/workspace/manage.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/workspace/requirements.txt +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/workspace/templates/treats/home.html +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/workspace/treats/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/workspace/treats/admin.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/workspace/treats/apps.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/workspace/treats/menu.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/workspace/treats/models.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/workspace/treats/tests.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/workspace/treats/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-04/workspace/treats/views.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/workspace/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/workspace/manage.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/workspace/requirements.txt +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/workspace/templates/treats/home.html +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/workspace/treats/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/workspace/treats/admin.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/workspace/treats/apps.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/workspace/treats/menu.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/workspace/treats/models.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/workspace/treats/tests.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/workspace/treats/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-05/workspace/treats/views.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/workspace/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/workspace/manage.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/workspace/requirements.txt +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/workspace/templates/treats/home.html +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/workspace/treats/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/workspace/treats/admin.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/workspace/treats/apps.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/workspace/treats/menu.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/workspace/treats/models.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/workspace/treats/tests.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/workspace/treats/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-06/workspace/treats/views.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/workspace/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/workspace/manage.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/workspace/requirements.txt +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/workspace/templates/treats/home.html +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/workspace/treats/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/workspace/treats/admin.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/workspace/treats/apps.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/workspace/treats/menu.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/workspace/treats/models.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/workspace/treats/tests.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/workspace/treats/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-07/workspace/treats/views.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/workspace/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/workspace/manage.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/workspace/requirements.txt +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/workspace/templates/treats/home.html +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/workspace/treats/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/workspace/treats/admin.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/workspace/treats/apps.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/workspace/treats/menu.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/workspace/treats/models.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/workspace/treats/tests.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/workspace/treats/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-08/workspace/treats/views.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/workspace/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/workspace/manage.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/workspace/requirements.txt +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/workspace/templates/treats/home.html +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/workspace/treats/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/workspace/treats/admin.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/workspace/treats/apps.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/workspace/treats/menu.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/workspace/treats/models.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/workspace/treats/tests.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/workspace/treats/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-09/workspace/treats/views.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/workspace/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/workspace/manage.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/workspace/requirements.txt +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/workspace/templates/treats/home.html +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/workspace/treats/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/workspace/treats/admin.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/workspace/treats/apps.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/workspace/treats/menu.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/workspace/treats/models.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/workspace/treats/tests.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/workspace/treats/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/data/student-10/workspace/treats/views.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/docker-compose.yaml +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/initial_content/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/initial_content/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/initial_content/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/initial_content/galactic_bakeshop/settings.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/initial_content/galactic_bakeshop/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/initial_content/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/initial_content/manage.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/initial_content/requirements.txt +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/initial_content/templates/treats/home.html +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/initial_content/treats/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/initial_content/treats/admin.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/initial_content/treats/apps.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/initial_content/treats/menu.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/initial_content/treats/migrations/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/initial_content/treats/models.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/initial_content/treats/tests.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/initial_content/treats/urls.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/initial_content/treats/views.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/examples/workshop_fleet/instructions/WELCOME.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/__main__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/cli.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/client.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/base.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/chunked_content.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/diff_handlers.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/file_handlers.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/project_aware_file_handlers.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/project_state/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/project_state/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/project_state/file_system_watcher.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/project_state/git_manager.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/project_state/handlers.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/project_state/manager.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/project_state/models.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/project_state/utils.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/project_state_handlers.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/registry.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/session.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/system_handlers.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/tab_factory.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/terminal_handlers.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/test_proxmox_infra.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/update_handler.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/multiplex.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/terminal.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/data.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/keypair.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/__pycache__/__init__.cpython-311.pyc +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/bin/__pycache__/link_capture_wrapper.cpython-311.pyc +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/bin/elinks +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/bin/gio-open +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/bin/gnome-open +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/bin/gvfs-open +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/bin/kde-open +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/bin/kfmclient +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/bin/link_capture_exec.sh +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/bin/link_capture_wrapper.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/bin/links +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/bin/links2 +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/bin/lynx +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/bin/mate-open +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/bin/netsurf +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/bin/sensible-browser +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/bin/w3m +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/bin/x-www-browser +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/link_capture/bin/xdg-open +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/logging_categories.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/pairing.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/service.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/static/js/test-ntp-clock.html +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/static/js/utils/ntp-clock.js +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/utils/NTP_ARCHITECTURE.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/utils/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/utils/diff_apply.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/utils/diff_renderer.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/utils/ntp_clock.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode.egg-info/SOURCES.txt +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode.egg-info/dependency_links.txt +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode.egg-info/entry_points.txt +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode.egg-info/requires.txt +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode.egg-info/top_level.txt +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/pyproject.toml +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/restore.sh +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/run_tests.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/setup.cfg +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/setup.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/test.sh +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/test_modules/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/test_modules/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/test_modules/test_device_online.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/test_modules/test_file_operations.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/test_modules/test_git_status_ui.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/test_modules/test_login_flow.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/test_modules/test_navigate_testing_folder.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/test_modules/test_play_store_screenshots.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/test_modules/test_terminal_buffer_performance.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/test_modules/test_terminal_interaction.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/test_modules/test_terminal_loading_race_condition.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/test_modules/test_terminal_start.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/test_request_id.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/testing_framework/.env.example +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/testing_framework/README.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/testing_framework/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/testing_framework/cli.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/testing_framework/core/__init__.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/testing_framework/core/base_test.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/testing_framework/core/cli_manager.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/testing_framework/core/hierarchical_runner.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/testing_framework/core/playwright_manager.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/testing_framework/core/runner.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/testing_framework/core/shared_cli_manager.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/testing_framework/core/test_discovery.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/testing_framework/requirements.txt +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/todo/UI_UX/opening_a_file_on_desktop_results_in_nothing.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/todo/agent_context_management.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/todo/django_server_time_sync.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/todo/issues/device_performance_degradation.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/todo/issues/git_data_not_captured_in_proxmox.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/todo/issues/indefinite_resource_loading.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/todo/issues/portacode_service_silently_down.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/todo/issues/premature_terminal_exit.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/todo/issues/project_cpu_hotspots.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/todo/issues/terminals_exit_upon_starting.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/todo/issues/wrong_item_classification_on_client_side.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/todo/smartphone_terminal_input_frustrations.md +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/tools/generate_play_store_assets.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/tools/pairing_tester.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/tools/run_screenshot_suite.sh +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/tools/test_python_ntp_clock.py +0 -0
- {portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/validate.sh +0 -0
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '1.4.16.
|
|
32
|
-
__version_tuple__ = version_tuple = (1, 4, 16, '
|
|
31
|
+
__version__ = version = '1.4.16.dev4'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 4, 16, 'dev4')
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
{portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/WEBSOCKET_PROTOCOL.md
RENAMED
|
@@ -1136,22 +1136,34 @@ Provides system information in response to a `system_info` action. Handled by [`
|
|
|
1136
1136
|
* `bridge` (string): The bridge interface configured (typically `vmbr1`).
|
|
1137
1137
|
* `health` (string|null): `"healthy"` when the connectivity verification succeeded.
|
|
1138
1138
|
* `node_status` (object|null): Status response returned by the Proxmox API when validating the token.
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1139
|
+
* `managed_containers` (object): Cached summary of the Portacode-managed containers:
|
|
1140
|
+
* `updated_at` (string): ISO timestamp when this snapshot was last refreshed.
|
|
1141
|
+
* `count` (integer): Number of managed containers.
|
|
1142
|
+
* `total_ram_mib` (integer): RAM footprint summed across all containers.
|
|
1143
|
+
* `total_disk_gib` (integer): Disk footprint summed across all containers.
|
|
1144
|
+
* `total_cpu_share` (number): CPU shares requested across all containers.
|
|
1145
|
+
* `containers` (array[object]): Container summaries with the following fields:
|
|
1146
|
+
* `vmid` (string|null): Numeric CT ID.
|
|
1147
|
+
* `hostname` (string|null): Hostname configured in the CT.
|
|
1148
|
+
* `template` (string|null): Template identifier used.
|
|
1149
|
+
* `storage` (string|null): Storage pool backing the rootfs.
|
|
1150
|
+
* `disk_gib` (integer): Rootfs size in GiB.
|
|
1151
|
+
* `ram_mib` (integer): Memory size in MiB.
|
|
1152
|
+
* `cpu_share` (number): vCPU-equivalent share requested at creation.
|
|
1153
|
+
* `status` (string): Lowercase lifecycle status (e.g., `running`, `stopped`, `deleted`).
|
|
1154
|
+
* `created_at` (string|null): ISO timestamp recorded when the CT was provisioned.
|
|
1155
|
+
* `managed` (boolean): `true` for Portacode-managed entries.
|
|
1156
|
+
* `unmanaged_containers` (array[object]): Facts about containers Portacode did not provision; fields mirror the managed list but are marked `managed=false`.
|
|
1157
|
+
* `unmanaged_count` (integer): Number of unmanaged containers detected on the node.
|
|
1158
|
+
* `allocated_ram_mib` (integer): Total RAM reserved by both managed and unmanaged containers.
|
|
1159
|
+
* `allocated_disk_gib` (integer): Total disk reserved by both managed and unmanaged containers.
|
|
1160
|
+
* `allocated_cpu_share` (number): Total CPU shares requested by both managed and unmanaged containers.
|
|
1161
|
+
* `available_ram_mib` (integer|null): Remaining RAM after subtracting all reservations from the host total (null when unavailable).
|
|
1162
|
+
* `available_disk_gib` (integer|null): Remaining disk GB after subtracting allocations from the host total.
|
|
1163
|
+
* `available_cpu_share` (number|null): Remaining CPU shares after allocations.
|
|
1164
|
+
* `host_total_ram_mib` (integer|null): Host memory capacity observed via Proxmox.
|
|
1165
|
+
* `host_total_disk_gib` (integer|null): Host disk capacity observed via Proxmox.
|
|
1166
|
+
* `host_total_cpu_cores` (integer|null): Number of CPU cores reported by Proxmox.
|
|
1155
1167
|
* `portacode_version` (string): Installed CLI version returned by `portacode.__version__`.
|
|
1156
1168
|
|
|
1157
1169
|
### `proxmox_infra_configured`
|
{portacode-1.4.16.dev2 → portacode-1.4.16.dev4}/portacode/connection/handlers/proxmox_infra.py
RENAMED
|
@@ -7,6 +7,7 @@ import json
|
|
|
7
7
|
import logging
|
|
8
8
|
import math
|
|
9
9
|
import os
|
|
10
|
+
import re
|
|
10
11
|
import secrets
|
|
11
12
|
import shlex
|
|
12
13
|
import shutil
|
|
@@ -18,7 +19,7 @@ import time
|
|
|
18
19
|
import threading
|
|
19
20
|
from datetime import datetime, timezone
|
|
20
21
|
from pathlib import Path
|
|
21
|
-
from typing import Any, Callable, Dict, Iterable, List, Optional, Sequence, Tuple
|
|
22
|
+
from typing import Any, Callable, Dict, Iterable, List, Optional, Sequence, Set, Tuple
|
|
22
23
|
|
|
23
24
|
import platformdirs
|
|
24
25
|
|
|
@@ -201,6 +202,70 @@ def _current_time_iso() -> str:
|
|
|
201
202
|
return datetime.now(timezone.utc).isoformat()
|
|
202
203
|
|
|
203
204
|
|
|
205
|
+
def _to_int(value: Any, default: int = 0) -> int:
|
|
206
|
+
try:
|
|
207
|
+
return int(value)
|
|
208
|
+
except (TypeError, ValueError):
|
|
209
|
+
return default
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def _to_float(value: Any, default: float = 0.0) -> float:
|
|
213
|
+
try:
|
|
214
|
+
return float(value)
|
|
215
|
+
except (TypeError, ValueError):
|
|
216
|
+
return default
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def _calculate_available(total: Optional[float], used: float) -> Optional[float]:
|
|
220
|
+
if total is None:
|
|
221
|
+
return None
|
|
222
|
+
delta = total - used
|
|
223
|
+
return delta if delta >= 0 else 0.0
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def _normalize_bytes(value: Any) -> float:
|
|
227
|
+
if isinstance(value, (int, float)):
|
|
228
|
+
return float(value)
|
|
229
|
+
text = str(value or "").strip()
|
|
230
|
+
if not text:
|
|
231
|
+
return 0.0
|
|
232
|
+
match = re.match(r"(?i)^\s*([0-9]*\.?[0-9]+)\s*([kmgtp]?i?b?)?\s*$", text)
|
|
233
|
+
if not match:
|
|
234
|
+
return 0.0
|
|
235
|
+
number = match.group(1)
|
|
236
|
+
unit = (match.group(2) or "").lower()
|
|
237
|
+
try:
|
|
238
|
+
value = float(number)
|
|
239
|
+
except ValueError:
|
|
240
|
+
return 0.0
|
|
241
|
+
if unit.startswith("k"):
|
|
242
|
+
return value * 1024
|
|
243
|
+
if unit.startswith("m"):
|
|
244
|
+
return value * 1024**2
|
|
245
|
+
if unit.startswith("g"):
|
|
246
|
+
return value * 1024**3
|
|
247
|
+
if unit.startswith("t"):
|
|
248
|
+
return value * 1024**4
|
|
249
|
+
if unit.startswith("p"):
|
|
250
|
+
return value * 1024**5
|
|
251
|
+
return value
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def _bytes_to_mib(value: Any) -> int:
|
|
255
|
+
return int(round(_normalize_bytes(value) / (1024**2)))
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def _bytes_to_gib(value: Any) -> int:
|
|
259
|
+
return int(round(_normalize_bytes(value) / (1024**3)))
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def _parse_bool_flag(value: Any) -> bool:
|
|
263
|
+
if isinstance(value, bool):
|
|
264
|
+
return value
|
|
265
|
+
text = str(value or "").strip().lower()
|
|
266
|
+
return text in {"1", "true", "yes", "on"}
|
|
267
|
+
|
|
268
|
+
|
|
204
269
|
def _parse_iso_timestamp(value: str) -> Optional[datetime]:
|
|
205
270
|
if not value:
|
|
206
271
|
return None
|
|
@@ -381,35 +446,68 @@ def _load_managed_container_records() -> List[Dict[str, Any]]:
|
|
|
381
446
|
return records
|
|
382
447
|
|
|
383
448
|
|
|
384
|
-
def
|
|
449
|
+
def _extract_host_totals(node_status: Dict[str, Any] | None) -> Tuple[Optional[int], Optional[int], Optional[int]]:
|
|
450
|
+
if not node_status:
|
|
451
|
+
return None, None, None
|
|
452
|
+
memory_total = node_status.get("memory", {}).get("total")
|
|
453
|
+
disk_total = node_status.get("disk", {}).get("total")
|
|
454
|
+
cpu_cores = node_status.get("cpuinfo", {}).get("cores")
|
|
455
|
+
host_ram = _bytes_to_mib(memory_total) if memory_total is not None else None
|
|
456
|
+
host_disk = _bytes_to_gib(disk_total) if disk_total is not None else None
|
|
457
|
+
host_cpu = _to_int(cpu_cores) if cpu_cores is not None else None
|
|
458
|
+
return host_ram, host_disk, host_cpu
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
def _build_unmanaged_container_entry(ct: Dict[str, Any], cfg: Dict[str, Any], vmid: str) -> Dict[str, Any]:
|
|
462
|
+
ram_mib = _to_int(cfg.get("memory")) or _bytes_to_mib(ct.get("maxmem"))
|
|
463
|
+
disk_gib = _bytes_to_gib(ct.get("maxdisk"))
|
|
464
|
+
cpu_share = _to_float(
|
|
465
|
+
cfg.get("cpulimit")
|
|
466
|
+
or cfg.get("cpus")
|
|
467
|
+
or cfg.get("cores")
|
|
468
|
+
or ct.get("cpus")
|
|
469
|
+
or ct.get("cpu")
|
|
470
|
+
)
|
|
471
|
+
hostname = ct.get("name") or cfg.get("hostname") or f"ct{vmid}"
|
|
472
|
+
storage = cfg.get("storage") or ct.get("storage")
|
|
473
|
+
status = (ct.get("status") or "unknown").lower()
|
|
474
|
+
reserved = _parse_bool_flag(cfg.get("onboot"))
|
|
475
|
+
return {
|
|
476
|
+
"vmid": vmid,
|
|
477
|
+
"hostname": hostname,
|
|
478
|
+
"template": cfg.get("ostemplate"),
|
|
479
|
+
"storage": storage,
|
|
480
|
+
"disk_gib": disk_gib,
|
|
481
|
+
"ram_mib": ram_mib,
|
|
482
|
+
"cpu_share": cpu_share,
|
|
483
|
+
"reserve_on_boot": reserved,
|
|
484
|
+
"status": status,
|
|
485
|
+
"managed": False,
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
def _build_managed_containers_summary(
|
|
491
|
+
records: List[Dict[str, Any]],
|
|
492
|
+
unmanaged_records: List[Dict[str, Any]],
|
|
493
|
+
node_status: Dict[str, Any] | None,
|
|
494
|
+
) -> Dict[str, Any]:
|
|
495
|
+
managed_containers: List[Dict[str, Any]] = []
|
|
385
496
|
total_ram = 0
|
|
386
497
|
total_disk = 0
|
|
387
498
|
total_cpu_share = 0.0
|
|
388
|
-
containers: List[Dict[str, Any]] = []
|
|
389
|
-
|
|
390
|
-
def _as_int(value: Any) -> int:
|
|
391
|
-
try:
|
|
392
|
-
return int(value)
|
|
393
|
-
except (TypeError, ValueError):
|
|
394
|
-
return 0
|
|
395
499
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
return 0.0
|
|
401
|
-
|
|
402
|
-
for record in sorted(records, key=lambda entry: _as_int(entry.get("vmid"))):
|
|
403
|
-
ram_mib = _as_int(record.get("ram_mib"))
|
|
404
|
-
disk_gib = _as_int(record.get("disk_gib"))
|
|
405
|
-
cpu_share = _as_float(record.get("cpus"))
|
|
500
|
+
for record in sorted(records, key=lambda entry: _to_int(entry.get("vmid"))):
|
|
501
|
+
ram_mib = _to_int(record.get("ram_mib"))
|
|
502
|
+
disk_gib = _to_int(record.get("disk_gib"))
|
|
503
|
+
cpu_share = _to_float(record.get("cpus"))
|
|
406
504
|
total_ram += ram_mib
|
|
407
505
|
total_disk += disk_gib
|
|
408
506
|
total_cpu_share += cpu_share
|
|
409
507
|
status = (record.get("status") or "unknown").lower()
|
|
410
|
-
|
|
508
|
+
managed_containers.append(
|
|
411
509
|
{
|
|
412
|
-
"vmid": str(
|
|
510
|
+
"vmid": str(_to_int(record.get("vmid"))) if record.get("vmid") is not None else None,
|
|
413
511
|
"device_id": record.get("device_id"),
|
|
414
512
|
"hostname": record.get("hostname"),
|
|
415
513
|
"template": record.get("template"),
|
|
@@ -419,44 +517,84 @@ def _build_managed_containers_summary(records: List[Dict[str, Any]]) -> Dict[str
|
|
|
419
517
|
"cpu_share": cpu_share,
|
|
420
518
|
"created_at": record.get("created_at"),
|
|
421
519
|
"status": status,
|
|
520
|
+
"managed": True,
|
|
422
521
|
}
|
|
423
522
|
)
|
|
424
523
|
|
|
524
|
+
unmanaged_total_ram = sum(
|
|
525
|
+
_to_int(entry.get("ram_mib"))
|
|
526
|
+
for entry in unmanaged_records
|
|
527
|
+
if entry.get("reserve_on_boot")
|
|
528
|
+
)
|
|
529
|
+
unmanaged_total_disk = sum(_to_int(entry.get("disk_gib")) for entry in unmanaged_records)
|
|
530
|
+
unmanaged_total_cpu = sum(
|
|
531
|
+
_to_float(entry.get("cpu_share"))
|
|
532
|
+
for entry in unmanaged_records
|
|
533
|
+
if entry.get("reserve_on_boot")
|
|
534
|
+
)
|
|
535
|
+
|
|
536
|
+
allocated_ram = total_ram + unmanaged_total_ram
|
|
537
|
+
allocated_disk = total_disk + unmanaged_total_disk
|
|
538
|
+
allocated_cpu = total_cpu_share + unmanaged_total_cpu
|
|
539
|
+
|
|
540
|
+
host_ram, host_disk, host_cpu = _extract_host_totals(node_status)
|
|
541
|
+
|
|
425
542
|
return {
|
|
426
543
|
"updated_at": datetime.utcnow().isoformat() + "Z",
|
|
427
|
-
"count": len(
|
|
544
|
+
"count": len(managed_containers),
|
|
428
545
|
"total_ram_mib": total_ram,
|
|
429
546
|
"total_disk_gib": total_disk,
|
|
430
547
|
"total_cpu_share": round(total_cpu_share, 2),
|
|
431
|
-
"containers":
|
|
548
|
+
"containers": managed_containers,
|
|
549
|
+
"unmanaged_containers": unmanaged_records,
|
|
550
|
+
"unmanaged_count": len(unmanaged_records),
|
|
551
|
+
"allocated_ram_mib": allocated_ram,
|
|
552
|
+
"allocated_disk_gib": allocated_disk,
|
|
553
|
+
"allocated_cpu_share": round(allocated_cpu, 2),
|
|
554
|
+
"available_ram_mib": _calculate_available(host_ram, allocated_ram) if host_ram is not None else None,
|
|
555
|
+
"available_disk_gib": _calculate_available(host_disk, allocated_disk) if host_disk is not None else None,
|
|
556
|
+
"available_cpu_share": _calculate_available(host_cpu, allocated_cpu) if host_cpu is not None else None,
|
|
557
|
+
"host_total_ram_mib": host_ram,
|
|
558
|
+
"host_total_disk_gib": host_disk,
|
|
559
|
+
"host_total_cpu_cores": host_cpu,
|
|
432
560
|
}
|
|
433
561
|
|
|
434
562
|
|
|
435
563
|
def _get_managed_containers_summary(force: bool = False) -> Dict[str, Any]:
|
|
436
|
-
def _refresh_container_statuses(
|
|
437
|
-
|
|
438
|
-
|
|
564
|
+
def _refresh_container_statuses(
|
|
565
|
+
records: List[Dict[str, Any]],
|
|
566
|
+
config: Dict[str, Any] | None,
|
|
567
|
+
managed_vmids: Set[str],
|
|
568
|
+
) -> Tuple[Dict[str, str], List[Dict[str, Any]], Dict[str, Any] | None]:
|
|
569
|
+
statuses: Dict[str, str] = {}
|
|
570
|
+
unmanaged: List[Dict[str, Any]] = []
|
|
571
|
+
node_status: Dict[str, Any] | None = None
|
|
572
|
+
if not config:
|
|
573
|
+
return statuses, unmanaged, node_status
|
|
439
574
|
try:
|
|
440
575
|
proxmox = _connect_proxmox(config)
|
|
441
576
|
node = _get_node_from_config(config)
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
577
|
+
node_status = proxmox.nodes(node).status.get()
|
|
578
|
+
for ct in proxmox.nodes(node).lxc.get():
|
|
579
|
+
vmid_val = ct.get("vmid")
|
|
580
|
+
if vmid_val is None:
|
|
581
|
+
continue
|
|
582
|
+
vmid_key = str(_to_int(vmid_val))
|
|
583
|
+
statuses[vmid_key] = (ct.get("status") or "unknown").lower()
|
|
584
|
+
if vmid_key in managed_vmids:
|
|
585
|
+
continue
|
|
586
|
+
cfg: Dict[str, Any] = {}
|
|
587
|
+
try:
|
|
588
|
+
cfg = proxmox.nodes(node).lxc(vmid_key).config.get() or {}
|
|
589
|
+
except Exception as exc: # pragma: no cover - best effort
|
|
590
|
+
logger.debug("Failed to read config for container %s: %s", vmid_key, exc)
|
|
591
|
+
description = (cfg.get("description") or "")
|
|
592
|
+
if MANAGED_MARKER in description:
|
|
593
|
+
continue
|
|
594
|
+
unmanaged.append(_build_unmanaged_container_entry(ct, cfg, vmid_key))
|
|
446
595
|
except Exception as exc: # pragma: no cover - best effort
|
|
447
596
|
logger.debug("Failed to refresh container statuses: %s", exc)
|
|
448
|
-
|
|
449
|
-
for record in records:
|
|
450
|
-
vmid = record.get("vmid")
|
|
451
|
-
if vmid is None:
|
|
452
|
-
continue
|
|
453
|
-
try:
|
|
454
|
-
vmid_key = str(int(vmid))
|
|
455
|
-
except (ValueError, TypeError):
|
|
456
|
-
continue
|
|
457
|
-
status = statuses.get(vmid_key)
|
|
458
|
-
if status:
|
|
459
|
-
record["status"] = status
|
|
597
|
+
return statuses, unmanaged, node_status
|
|
460
598
|
|
|
461
599
|
now = time.monotonic()
|
|
462
600
|
with _MANAGED_CONTAINERS_CACHE_LOCK:
|
|
@@ -466,8 +604,19 @@ def _get_managed_containers_summary(force: bool = False) -> Dict[str, Any]:
|
|
|
466
604
|
return cached
|
|
467
605
|
config = _load_config()
|
|
468
606
|
records = _load_managed_container_records()
|
|
469
|
-
|
|
470
|
-
|
|
607
|
+
managed_vmids: Set[str] = {
|
|
608
|
+
str(_to_int(record.get("vmid"))) for record in records if record.get("vmid") is not None
|
|
609
|
+
}
|
|
610
|
+
statuses, unmanaged, node_status = _refresh_container_statuses(records, config, managed_vmids)
|
|
611
|
+
for record in records:
|
|
612
|
+
vmid = record.get("vmid")
|
|
613
|
+
if vmid is None:
|
|
614
|
+
continue
|
|
615
|
+
vmid_key = str(_to_int(vmid))
|
|
616
|
+
status = statuses.get(vmid_key)
|
|
617
|
+
if status:
|
|
618
|
+
record["status"] = status
|
|
619
|
+
summary = _build_managed_containers_summary(records, unmanaged, node_status)
|
|
471
620
|
with _MANAGED_CONTAINERS_CACHE_LOCK:
|
|
472
621
|
_MANAGED_CONTAINERS_CACHE["timestamp"] = now
|
|
473
622
|
_MANAGED_CONTAINERS_CACHE["summary"] = summary
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|