little update
This commit is contained in:
98
README.md
Normal file
98
README.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# Kernel NATS consumer
|
||||
|
||||
Consumes JSON `StartGameRequest` messages. `kernel.proto` is used only as field schema reference; no protobuf runtime or encoding is used.
|
||||
|
||||
Expected message shape:
|
||||
|
||||
```json
|
||||
{
|
||||
"team_count": 2,
|
||||
"services": [],
|
||||
"teams": [{"team_name": "red", "team_id": "red-1"}, {"team_name": "blue", "team_id": "blue-1"}],
|
||||
"game_starts_at": 1730000000,
|
||||
"rounds": 10,
|
||||
"network_opens_at": 1729999900
|
||||
}
|
||||
```
|
||||
|
||||
Run from `kernel/`:
|
||||
|
||||
```sh
|
||||
python -m pip install -e .
|
||||
init-nats
|
||||
NATS_URL=nats://127.0.0.1:4222 kernel-consumer
|
||||
```
|
||||
|
||||
`init-nats` idempotently creates stream `GAME` and its `game.start` channel. It also adds configured `NATS_SUBJECT` to existing configured `NATS_STREAM`.
|
||||
|
||||
Environment variables: `NATS_URL`, `NATS_STREAM` (`GAME`), `NATS_SUBJECT` (`game.start`), `NATS_CONSUMER` (`kernel-consumer`).
|
||||
|
||||
## Cloud.ru Evolution VPC
|
||||
|
||||
`VPCNetworkManager` is a synchronous client for documented Evolution VPC API operations. Pass a Cloud.ru Bearer JWT directly; do not commit it.
|
||||
|
||||
```python
|
||||
from cloud import CreateVPCRequest, VPCNetworkManager
|
||||
|
||||
manager = VPCNetworkManager(token="<jwt>")
|
||||
operation = manager.create_vpc(
|
||||
CreateVPCRequest(projectId="<project-id>", name="game-vpc")
|
||||
)
|
||||
vpcs = manager.list_vpcs(project_id="<project-id>")
|
||||
```
|
||||
|
||||
It supports VPC CRUD, operation lookup, and static-route read/create/delete. Evolution VPC public API does not expose endpoints for listing or creating subnets.
|
||||
|
||||
## Cloud.ru Virtual Machines
|
||||
|
||||
`VMManager` is a synchronous client for documented Evolution Virtual Machines API methods. Pass a Cloud.ru Bearer JWT directly; do not commit it.
|
||||
|
||||
```python
|
||||
from cloud import VMCreateRequest, VMManager
|
||||
|
||||
manager = VMManager(token="<jwt>")
|
||||
vms = manager.list_vms(project_id="<project-id>")
|
||||
vms = manager.create_vm(VMCreateRequest(
|
||||
project_id="<project-id>",
|
||||
name="game-vm",
|
||||
disks=[{"disk_id": "<disk-id>"}],
|
||||
))
|
||||
manager.start_vm(vms[0].id)
|
||||
```
|
||||
|
||||
It supports VM list/create/read/update/delete, batch creation, start/stop, power actions, rebuild, VNC and remote-console creation, password management, and guest-agent checks. Managers accept Pydantic request models and return validated Pydantic response models. `VMCreateRequest` requires `project_id`, `name`, and non-empty `disks`.
|
||||
|
||||
## Network Pool
|
||||
|
||||
Copy environment template and set Cloud.ru credentials:
|
||||
|
||||
```sh
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Run database migrations before starting consumer:
|
||||
|
||||
```sh
|
||||
DATABASE_URL="sqlite:///$PWD/kernel.db" PYTHONPATH=src alembic upgrade head
|
||||
```
|
||||
|
||||
`.env` loads automatically for consumer and Alembic. Shell environment variables override `.env`. Set `DATABASE_URL`, `CLOUD_PROJECT_ID`, `CLOUD_KEY_ID`, and `CLOUD_SECRET`. Consumer requests fresh Cloud.ru JWT from IAM at startup; it uses `CLOUD_TOKEN` only when IAM credentials are absent. Set `CLOUD_VPC_ID` and `CLOUD_AVAILABILITY_ZONE_ID` (UUID) or `CLOUD_AVAILABILITY_ZONE_NAME` (resolved to an ID via `GET /api/v1/availability-zones`) when project defaults do not select VPC and availability zone. The subnet API expects the zone as a flat `availability_zone_id` UUID. Without `DATABASE_URL`, consumer uses absolute `kernel/kernel.db`, independent of launch folder. Alembic uses `DATABASE_URL` when set. For every valid game message, consumer creates UUID and allocates network through `NetworkingManager`. Free pool networks are verified using Cloud.ru subnet API before allocation. Missing cloud subnet records are removed and recreated as `10.N.0.0/20`, where `N` ranges from `0` to `240` in steps of 16. `NetworkPoolExhaustedError` stops allocation when all CIDRs are used.
|
||||
|
||||
For each valid game event, the consumer creates `team_count + 1` Ubuntu VMs. Every VM is attached to the allocated game subnet; the extra VM receives a new public IPv4 address. Configure `CLOUD_VM_PASSWORD` or `CLOUD_VM_PUBLIC_KEY` for Ubuntu authentication, plus optional `CLOUD_VM_FLAVOR_NAME`, `CLOUD_VM_IMAGE_NAME`, and `CLOUD_VM_DISK_TYPE_NAME` overrides.
|
||||
|
||||
## Game Cleanup
|
||||
|
||||
Initialize both JetStream subjects with `init-nats`, then queue cleanup for a game:
|
||||
|
||||
```sh
|
||||
init-nats
|
||||
fire-game-cleanup 4bc5200f-09ba-4e18-8da4-64f3950d342e
|
||||
```
|
||||
|
||||
The cleanup message is published to `NATS_CLEANUP_SUBJECT` (`game.cleanup` by default):
|
||||
|
||||
```json
|
||||
{"game_id": "4bc5200f-09ba-4e18-8da4-64f3950d342e"}
|
||||
```
|
||||
|
||||
The consumer finds VMs named for that game, deletes them, waits until Cloud.ru removes them, and only then releases the game subnet back to the pool. Cleanup is idempotent if the VMs or network were already removed.
|
||||
Reference in New Issue
Block a user