Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 48 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,54 @@ on:
- master
pull_request:

env:
REGISTRY: registry.v0l.io
HOST_INFO_IMAGE: registry.v0l.io/lnvps-host-info

jobs:
# Build host-info for multiple architectures first
build-host-info:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- platform: linux/amd64
tag_suffix: amd64
- platform: linux/arm64
tag_suffix: arm64

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to Docker Registry
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: registry
password: ${{ secrets.REGISTRY_TOKEN }}

- name: Build and push lnvps-host-info (${{ matrix.tag_suffix }})
uses: docker/build-push-action@v5
with:
context: .
file: lnvps_host_util/Dockerfile
platforms: ${{ matrix.platform }}
push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
tags: ${{ env.HOST_INFO_IMAGE }}:latest-${{ matrix.tag_suffix }}

# Build main images after host-info is ready
build:
runs-on: ubuntu-latest
needs: build-host-info
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -37,7 +82,7 @@ jobs:
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: docker/login-action@v3
with:
registry: registry.v0l.io
registry: ${{ env.REGISTRY }}
username: registry
password: ${{ secrets.REGISTRY_TOKEN }}

Expand All @@ -48,3 +93,5 @@ jobs:
file: ${{ matrix.file }}
push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
tags: ${{ matrix.image }}
build-args: |
HOST_INFO_IMAGE=${{ env.HOST_INFO_IMAGE }}
59 changes: 56 additions & 3 deletions ADMIN_API_ENDPOINTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ Admin API request/response format reference for LLM consumption.
**SubscriptionPaymentType**: `"purchase"`, `"renewal"`
**SubscriptionType**: `"ip_range"`, `"asn_sponsoring"`, `"dns_hosting"`
**InternetRegistry**: `"arin"`, `"ripe"`, `"apnic"`, `"lacnic"`, `"afrinic"`
**CpuMfg**: `"unknown"`, `"intel"`, `"amd"`, `"apple"`, `"nvidia"`, `"arm"`
**CpuArch**: `"unknown"`, `"x86_64"`, `"arm64"`
**CpuFeature**: `"SSE"`, `"SSE2"`, `"SSE3"`, `"SSSE3"`, `"SSE4_1"`, `"SSE4_2"`, `"AVX"`, `"AVX2"`, `"FMA"`, `"F16C"`,
`"AVX512F"`, `"AVX512VNNI"`, `"AVX512BF16"`, `"AVXVNNI"`, `"NEON"`, `"SVE"`, `"SVE2"`, `"AES"`, `"SHA"`, `"SHA512"`,
`"PCLMULQDQ"`, `"RNG"`, `"GFNI"`, `"VAES"`, `"VPCLMULQDQ"`, `"VMX"`, `"NestedVirt"`, `"AMX"`, `"SME"`, `"SGX"`, `"SEV"`,
`"TDX"`, `"EncodeH264"`, `"EncodeHEVC"`, `"EncodeAV1"`, `"EncodeVP9"`, `"EncodeJPEG"`, `"DecodeH264"`, `"DecodeHEVC"`,
`"DecodeAV1"`, `"DecodeVP9"`, `"DecodeJPEG"`, `"DecodeMPEG2"`, `"DecodeVC1"`, `"VideoScaling"`, `"VideoDeinterlace"`,
`"VideoCSC"`, `"VideoComposition"`
**GpuMfg**: `"none"`, `"nvidia"`, `"amd"`

## Authentication

Expand Down Expand Up @@ -807,7 +816,13 @@ Body (all optional):
"enabled": boolean,
"load_cpu": number,
"load_memory": number,
"load_disk": number
"load_disk": number,
"ssh_user": "string",
// SSH username for host utilities (default: root)
"ssh_key": "string"
|
null
// SSH private key (PEM format) - use null to clear
}
```

Expand Down Expand Up @@ -846,8 +861,12 @@ Body:
// Optional - default 1.0
"load_memory": number,
// Optional - default 1.0
"load_disk": number
"load_disk": number,
// Optional - default 1.0
"ssh_user": "string",
// Optional - SSH username for host utilities (default: root)
"ssh_key": "string"
// Optional - SSH private key (PEM format)
}
```

Expand Down Expand Up @@ -1123,6 +1142,12 @@ Body:
// optional
"cpu": number,
// CPU cores
"cpu_mfg": "string",
// optional - CpuMfg enum, default "unknown" (matches any host)
"cpu_arch": "string",
// optional - CpuArch enum, default "unknown" (matches any host)
"cpu_features": ["string"],
// optional - array of CpuFeature enum values, default [] (matches any host)
"memory": number,
// Memory in bytes
"disk_size": number,
Expand Down Expand Up @@ -1168,6 +1193,12 @@ Body (all optional):
"enabled": boolean,
"expires": "string (ISO 8601) | null",
"cpu": number,
"cpu_mfg": "string",
// CpuMfg enum - filter hosts by CPU manufacturer
"cpu_arch": "string",
// CpuArch enum - filter hosts by CPU architecture
"cpu_features": ["string"],
// array of CpuFeature enum values - filter hosts by required CPU features
"memory": number,
"disk_size": number,
"disk_type": "string",
Expand Down Expand Up @@ -1344,6 +1375,12 @@ Body:
"region_id": number,
"currency": "string",
// e.g., "USD", "EUR", "BTC"
"cpu_mfg": "string",
// optional - CpuMfg enum, default "unknown" (matches any host)
"cpu_arch": "string",
// optional - CpuArch enum, default "unknown" (matches any host)
"cpu_features": ["string"],
// optional - array of CpuFeature enum values, default [] (matches any host)
"cpu_cost": number,
// Cost per CPU core per month in smallest currency units (cents/millisats)
"memory_cost": number,
Expand Down Expand Up @@ -1395,6 +1432,12 @@ Body (all optional):
"expires": "string (ISO 8601) | null",
"region_id": number,
"currency": "string",
"cpu_mfg": "string",
// CpuMfg enum - filter hosts by CPU manufacturer
"cpu_arch": "string",
// CpuArch enum - filter hosts by CPU architecture
"cpu_features": ["string"],
// array of CpuFeature enum values - filter hosts by required CPU features
"cpu_cost": number,
// Cost per CPU core in smallest currency units (cents/millisats)
"memory_cost": number,
Expand Down Expand Up @@ -2740,6 +2783,12 @@ The RBAC system uses the following permission format: `resource::action`
},
"ip": "string",
"cpu": number,
"cpu_mfg": "string",
// CpuMfg enum - detected CPU manufacturer
"cpu_arch": "string",
// CpuArch enum - detected CPU architecture
"cpu_features": ["string"],
// array of CpuFeature enum values - detected CPU features
"memory": number,
"enabled": boolean,
"load_cpu": number,
Expand Down Expand Up @@ -2773,7 +2822,11 @@ The RBAC system uses the following permission format: `resource::action`
// Available memory in bytes
"active_vms": number
// Number of active VMs on this host
}
},
"ssh_user": "string | null",
// SSH username for host utilities (null if not configured)
"ssh_key_configured": boolean
// Whether SSH key is configured (key itself is not exposed)
}
```

Expand Down
22 changes: 22 additions & 0 deletions API_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,28 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased]

### Added
- **2026-02-20** - Added CPU-aware host filtering to VM Templates, Custom Pricing, and Hosts (Admin API)
- New enums: `CpuMfg`, `CpuArch`, `CpuFeature`, `GpuMfg`
- `POST /api/admin/v1/vm_templates` — Added optional `cpu_mfg`, `cpu_arch`, `cpu_features` fields
- `PATCH /api/admin/v1/vm_templates/{id}` — Added optional `cpu_mfg`, `cpu_arch`, `cpu_features` fields
- `POST /api/admin/v1/custom_pricing` — Added optional `cpu_mfg`, `cpu_arch`, `cpu_features` fields
- `PATCH /api/admin/v1/custom_pricing/{id}` — Added optional `cpu_mfg`, `cpu_arch`, `cpu_features` fields
- `AdminHostInfo` response now includes `cpu_mfg`, `cpu_arch`, `cpu_features` (detected via lnvps-host-info)
- When `cpu_mfg`/`cpu_arch` is "unknown" or `cpu_features` is empty, no filtering is applied (matches any host)

- **2026-02-20** - Added SSH credentials for host utilities to Admin Host API
- `POST /api/admin/v1/hosts` — Added optional `ssh_user` and `ssh_key` fields for host creation
- `PATCH /api/admin/v1/hosts/{id}` — Added optional `ssh_user` and `ssh_key` fields for host update
- `AdminHostInfo` response now includes `ssh_user` (string or null) and `ssh_key_configured` (boolean)
- SSH key itself is never exposed in responses for security (only a boolean indicator)
- SSH credentials are used by the PatchHosts worker to run `lnvps-host-info` utility for CPU/GPU detection

- **2026-02-20** - Added CPU feature requirements to custom VM requests (User API)
- `POST /api/v1/vm/custom` — `cpu_mfg`, `cpu_arch`, `cpu_feature` fields now accept strings instead of enums
- Valid `cpu_mfg` values: "intel", "amd", "apple", "nvidia", "unknown"
- Valid `cpu_arch` values: "x86_64", "arm64", "unknown"
- CPU features are parsed from strings (e.g. "AVX2", "AES", "VMX"); invalid values are silently ignored

- **2026-02-17** - Added embedded API documentation served at root path (both User and Admin APIs)
- `GET /` or `GET /index.html` - Renders API documentation with markdown viewer
- `GET /docs/endpoints.md` - Raw markdown content of API endpoints documentation
Expand Down
23 changes: 23 additions & 0 deletions API_DOCUMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,23 @@ This document provides comprehensive API specifications for generating TypeScrip
- **Error Response Format**: `{ "error": "Error message" }`
- **Success Response Format**: `{ "data": <response_data> }`

## Enums

**DiskType**: `"hdd"`, `"ssd"`
**DiskInterface**: `"sata"`, `"scsi"`, `"pcie"`
**VmState**: `"running"`, `"stopped"`, `"pending"`, `"error"`, `"unknown"`
**CostPlanIntervalType**: `"day"`, `"month"`, `"year"`
**OsDistribution**: `"ubuntu"`, `"debian"`, `"centos"`, `"fedora"`, `"freebsd"`, `"opensuse"`, `"archlinux"`,
`"redhatenterprise"`
**CpuMfg**: `"unknown"`, `"intel"`, `"amd"`, `"apple"`, `"nvidia"`, `"arm"`
**CpuArch**: `"unknown"`, `"x86_64"`, `"arm64"`
**CpuFeature**: `"SSE"`, `"SSE2"`, `"SSE3"`, `"SSSE3"`, `"SSE4_1"`, `"SSE4_2"`, `"AVX"`, `"AVX2"`, `"FMA"`, `"F16C"`,
`"AVX512F"`, `"AVX512VNNI"`, `"AVX512BF16"`, `"AVXVNNI"`, `"NEON"`, `"SVE"`, `"SVE2"`, `"AES"`, `"SHA"`, `"SHA512"`,
`"PCLMULQDQ"`, `"RNG"`, `"GFNI"`, `"VAES"`, `"VPCLMULQDQ"`, `"VMX"`, `"NestedVirt"`, `"AMX"`, `"SME"`, `"SGX"`, `"SEV"`,
`"TDX"`, `"EncodeH264"`, `"EncodeHEVC"`, `"EncodeAV1"`, `"EncodeVP9"`, `"EncodeJPEG"`, `"DecodeH264"`, `"DecodeHEVC"`,
`"DecodeAV1"`, `"DecodeVP9"`, `"DecodeJPEG"`, `"DecodeMPEG2"`, `"DecodeVC1"`, `"VideoScaling"`, `"VideoDeinterlace"`,
`"VideoCSC"`, `"VideoComposition"`

## Authentication Types

```typescript
Expand Down Expand Up @@ -69,6 +86,9 @@ interface VmTemplate {
created: string; // ISO 8601 datetime
expires?: string; // ISO 8601 datetime
cpu: number; // Number of CPU cores
cpu_mfg?: string; // CPU manufacturer (e.g. "intel", "amd"; omitted if unknown)
cpu_arch?: string; // CPU architecture (e.g. "x86_64", "arm64"; omitted if unknown)
cpu_features?: string[]; // Required CPU features (e.g. ["AVX2", "AES"]; omitted if empty)
memory: number; // Memory in bytes
disk_size: number; // Disk size in bytes
disk_type: 'hdd' | 'ssd';
Expand Down Expand Up @@ -120,6 +140,9 @@ interface CustomTemplateParams {
id: number;
name: string;
region: VmHostRegion;
cpu_mfg?: string; // CPU manufacturer (e.g. "intel", "amd"; omitted if unknown)
cpu_arch?: string; // CPU architecture (e.g. "x86_64", "arm64"; omitted if unknown)
cpu_features?: string[]; // Required CPU features (e.g. ["AVX2", "AES"]; omitted if empty)
max_cpu: number;
min_cpu: number;
min_memory: number; // In bytes
Expand Down
Loading
Loading