initial commit
This commit is contained in:
78
api/config-examples.md
Normal file
78
api/config-examples.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Jagacloud Config Examples
|
||||
|
||||
## Agent config `/etc/jagacloud/agent.yaml`
|
||||
```yaml
|
||||
listen_addr: ":8000"
|
||||
libvirt_uri: "qemu:///system"
|
||||
lxc_path: "/etc/jagacloud/lxc"
|
||||
podman_socket: "/run/podman/podman.sock"
|
||||
auth_token: "replace-me"
|
||||
storage_pools:
|
||||
- name: local-dir
|
||||
type: dir
|
||||
path: /var/lib/jagacloud/images
|
||||
- name: local-lvm
|
||||
type: lvm
|
||||
path: /dev/vg0
|
||||
bridges:
|
||||
- name: vmbr0
|
||||
vlan_aware: true
|
||||
mtu: 1500
|
||||
```
|
||||
|
||||
## VM spec (persisted)
|
||||
`/etc/jagacloud/vm/100.yaml`
|
||||
```yaml
|
||||
id: "100"
|
||||
name: "vm-100"
|
||||
cpus: 4
|
||||
memory_mb: 8192
|
||||
disks:
|
||||
- name: root
|
||||
pool: local-lvm
|
||||
size_gb: 40
|
||||
bus: virtio
|
||||
nics:
|
||||
- bridge: vmbr0
|
||||
vlan: 10
|
||||
model: virtio
|
||||
cloud_init:
|
||||
user: debian
|
||||
ssh_keys:
|
||||
- "ssh-ed25519 AAA... user@host"
|
||||
```
|
||||
|
||||
## Container spec (persisted)
|
||||
`/etc/jagacloud/ct/200.yaml`
|
||||
```yaml
|
||||
id: "200"
|
||||
name: "ct-200"
|
||||
unprivileged: true
|
||||
limits:
|
||||
cpus: 2
|
||||
memory_mb: 2048
|
||||
template: "debian-bookworm"
|
||||
rootfs:
|
||||
pool: local-dir
|
||||
size_gb: 10
|
||||
nics:
|
||||
- bridge: vmbr0
|
||||
vlan: 20
|
||||
```
|
||||
|
||||
## Network bridge (systemd-networkd snippet)
|
||||
`/etc/jagacloud/network/vmbr0.netdev`
|
||||
```ini
|
||||
[NetDev]
|
||||
Name=vmbr0
|
||||
Kind=bridge
|
||||
```
|
||||
|
||||
`/etc/jagacloud/network/vmbr0.network`
|
||||
```ini
|
||||
[Match]
|
||||
Name=vmbr0
|
||||
|
||||
[Network]
|
||||
VLANFiltering=yes
|
||||
```
|
||||
219
api/openapi.yaml
Normal file
219
api/openapi.yaml
Normal file
@@ -0,0 +1,219 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Jagacloud Node Agent API
|
||||
version: 0.1.0
|
||||
description: Minimal single-node hypervisor API for VMs (libvirt), LXC containers, and Podman-in-LXC.
|
||||
servers:
|
||||
- url: http://{host}:{port}
|
||||
variables:
|
||||
host:
|
||||
default: 127.0.0.1
|
||||
port:
|
||||
default: "8000"
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerToken:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
schemas:
|
||||
Error:
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
NodeInfo:
|
||||
type: object
|
||||
properties:
|
||||
hostname: { type: string }
|
||||
version: { type: string }
|
||||
cpu: { type: object, properties: { cores: {type: integer}, model: {type: string}, load: {type: number} } }
|
||||
memory: { type: object, properties: { total_mb: {type: integer}, used_mb: {type: integer} } }
|
||||
storage_pools:
|
||||
type: array
|
||||
items: { $ref: '#/components/schemas/StoragePool' }
|
||||
bridges:
|
||||
type: array
|
||||
items: { $ref: '#/components/schemas/Bridge' }
|
||||
StoragePool:
|
||||
type: object
|
||||
properties:
|
||||
name: { type: string }
|
||||
type: { type: string, enum: [dir, lvm, zfs] }
|
||||
path: { type: string }
|
||||
free_gb: { type: number }
|
||||
total_gb: { type: number }
|
||||
Bridge:
|
||||
type: object
|
||||
properties:
|
||||
name: { type: string }
|
||||
vlan_aware: { type: boolean }
|
||||
mtu: { type: integer }
|
||||
VM:
|
||||
type: object
|
||||
properties:
|
||||
id: { type: string }
|
||||
name: { type: string }
|
||||
status: { type: string, enum: [running, stopped, paused, error] }
|
||||
cpus: { type: integer }
|
||||
memory_mb: { type: integer }
|
||||
disks: { type: array, items: { $ref: '#/components/schemas/VMDisk' } }
|
||||
nics: { type: array, items: { $ref: '#/components/schemas/VMNic' } }
|
||||
VMDisk:
|
||||
type: object
|
||||
properties:
|
||||
name: { type: string }
|
||||
pool: { type: string }
|
||||
size_gb: { type: integer }
|
||||
bus: { type: string, enum: [virtio, sata] }
|
||||
VMNic:
|
||||
type: object
|
||||
properties:
|
||||
bridge: { type: string }
|
||||
model: { type: string }
|
||||
vlan: { type: integer }
|
||||
VMCreate:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/VM'
|
||||
- type: object
|
||||
required: [name, cpus, memory_mb]
|
||||
properties:
|
||||
cloud_init:
|
||||
type: object
|
||||
properties:
|
||||
user: { type: string }
|
||||
ssh_keys: { type: array, items: {type: string} }
|
||||
user_data: { type: string }
|
||||
Container:
|
||||
type: object
|
||||
properties:
|
||||
id: { type: string }
|
||||
name: { type: string }
|
||||
status: { type: string, enum: [running, stopped, error] }
|
||||
unprivileged: { type: boolean }
|
||||
nics: { type: array, items: { $ref: '#/components/schemas/ContainerNic' } }
|
||||
limits: { type: object, properties: { cpus: {type: integer}, memory_mb: {type: integer} } }
|
||||
ContainerCreate:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Container'
|
||||
- type: object
|
||||
required: [name, template]
|
||||
properties:
|
||||
template: { type: string }
|
||||
rootfs: { type: object, properties: { pool: {type: string}, size_gb: {type: integer} }, required: [pool, size_gb] }
|
||||
ContainerNic:
|
||||
type: object
|
||||
properties:
|
||||
bridge: { type: string }
|
||||
vlan: { type: integer }
|
||||
OCIContainer:
|
||||
type: object
|
||||
properties:
|
||||
id: { type: string }
|
||||
image: { type: string }
|
||||
status: { type: string }
|
||||
OCICreate:
|
||||
type: object
|
||||
required: [image]
|
||||
properties:
|
||||
image: { type: string }
|
||||
cmd: { type: array, items: {type: string} }
|
||||
env: { type: object, additionalProperties: {type: string} }
|
||||
ports: { type: array, items: { type: object, properties: { host_port: {type: integer}, container_port: {type: integer} } } }
|
||||
volumes: { type: array, items: { type: string } }
|
||||
restart: { type: string }
|
||||
security:
|
||||
- bearerToken: []
|
||||
paths:
|
||||
/api/v1/node:
|
||||
get:
|
||||
summary: Node information
|
||||
responses:
|
||||
'200': { description: OK, content: { application/json: { schema: { $ref: '#/components/schemas/NodeInfo' } } } }
|
||||
default: { description: Error, content: { application/json: { schema: { $ref: '#/components/schemas/Error' } } } }
|
||||
/api/v1/vms:
|
||||
get:
|
||||
summary: List VMs
|
||||
responses:
|
||||
'200': { description: OK, content: { application/json: { schema: { type: array, items: { $ref: '#/components/schemas/VM' } } } } }
|
||||
post:
|
||||
summary: Create VM
|
||||
requestBody:
|
||||
required: true
|
||||
content: { application/json: { schema: { $ref: '#/components/schemas/VMCreate' } } }
|
||||
responses:
|
||||
'202': { description: Accepted, content: { application/json: { schema: { $ref: '#/components/schemas/VM' } } } }
|
||||
/api/v1/vms/{id}:
|
||||
get:
|
||||
summary: Get VM
|
||||
parameters: [{ name: id, in: path, required: true, schema: {type: string} }]
|
||||
responses:
|
||||
'200': { description: OK, content: { application/json: { schema: { $ref: '#/components/schemas/VM' } } } }
|
||||
post:
|
||||
summary: Update VM (reserved for future)
|
||||
responses:
|
||||
'501': { description: Not implemented }
|
||||
/api/v1/vms/{id}/{action}:
|
||||
post:
|
||||
summary: VM lifecycle action
|
||||
parameters:
|
||||
- { name: id, in: path, required: true, schema: {type: string} }
|
||||
- { name: action, in: path, required: true, schema: { type: string, enum: [start, stop, reboot, delete] } }
|
||||
responses:
|
||||
'202': { description: Accepted }
|
||||
/api/v1/containers:
|
||||
get:
|
||||
summary: List LXC containers
|
||||
responses:
|
||||
'200': { description: OK, content: { application/json: { schema: { type: array, items: { $ref: '#/components/schemas/Container' } } } } }
|
||||
post:
|
||||
summary: Create container
|
||||
requestBody:
|
||||
required: true
|
||||
content: { application/json: { schema: { $ref: '#/components/schemas/ContainerCreate' } } }
|
||||
responses:
|
||||
'202': { description: Accepted, content: { application/json: { schema: { $ref: '#/components/schemas/Container' } } } }
|
||||
/api/v1/containers/{id}:
|
||||
get:
|
||||
summary: Get container
|
||||
parameters: [{ name: id, in: path, required: true, schema: {type: string} }]
|
||||
responses:
|
||||
'200': { description: OK, content: { application/json: { schema: { $ref: '#/components/schemas/Container' } } } }
|
||||
/api/v1/containers/{id}/{action}:
|
||||
post:
|
||||
summary: Container lifecycle action
|
||||
parameters:
|
||||
- { name: id, in: path, required: true, schema: {type: string} }
|
||||
- { name: action, in: path, required: true, schema: { type: string, enum: [start, stop, delete] } }
|
||||
responses:
|
||||
'202': { description: Accepted }
|
||||
/api/v1/containers/{id}/oci:
|
||||
get:
|
||||
summary: List OCI containers inside CT
|
||||
parameters: [{ name: id, in: path, required: true, schema: {type: string} }]
|
||||
responses:
|
||||
'200': { description: OK, content: { application/json: { schema: { type: array, items: { $ref: '#/components/schemas/OCIContainer' } } } } }
|
||||
post:
|
||||
summary: Create OCI container inside CT
|
||||
requestBody:
|
||||
required: true
|
||||
content: { application/json: { schema: { $ref: '#/components/schemas/OCICreate' } } }
|
||||
responses:
|
||||
'202': { description: Accepted, content: { application/json: { schema: { $ref: '#/components/schemas/OCIContainer' } } } }
|
||||
/api/v1/containers/{id}/oci/{cid}:
|
||||
get:
|
||||
summary: Get OCI container
|
||||
parameters:
|
||||
- { name: id, in: path, required: true, schema: {type: string} }
|
||||
- { name: cid, in: path, required: true, schema: {type: string} }
|
||||
responses:
|
||||
'200': { description: OK, content: { application/json: { schema: { $ref: '#/components/schemas/OCIContainer' } } } }
|
||||
/api/v1/containers/{id}/oci/{cid}/{action}:
|
||||
post:
|
||||
summary: OCI lifecycle action
|
||||
parameters:
|
||||
- { name: id, in: path, required: true, schema: {type: string} }
|
||||
- { name: cid, in: path, required: true, schema: {type: string} }
|
||||
- { name: action, in: path, required: true, schema: { type: string, enum: [start, stop, delete] } }
|
||||
responses:
|
||||
'202': { description: Accepted }
|
||||
Reference in New Issue
Block a user