Skip to content

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

  Lictor

CI Go Reference Go Version Release

A minimal authenticated HTTP API for managing libvirt domains (VMs) on a host. It exposes two endpoints: read a VM's state and run a lifecycle action.

Requirements

  • Go 1.26+ (build only)
  • A running libvirt daemon, and permission for the server process to read/write its socket (/var/run/libvirt/libvirt-sock).

Configuration

The server is configured entirely via environment variables:

Variable Required Default Description
LICTOR_KEY yes — API key clients must send.
LICTOR_ADDR no 0.0.0.0:8080 Address the server listens on.
LICTOR_LOG_LEVEL no info Log level (debug, info, warn, error)

If LICTOR_KEY is unset the server exits at startup.

Running

export LICTOR_KEY=$(openssl rand -hex 16)
go run .
# or build a binary:
go build -o lictor . && ./lictor

The server speaks both HTTP/1.1 and HTTP/2 cleartext (h2c) on the same port.

The server itself does not terminate TLS, so the API key crosses the network unencrypted. Run it on localhost or a trusted network, or put it behind a TLS-terminating reverse proxy.

Authentication

Every request must include the API key:

x-api-key: <LICTOR_KEY>

Requests with a missing or incorrect key get 401 and {"error":"unauthorized"}.

API

Full specification: openapi.yaml.

GET /vm/{target}/state

Returns the libvirt state of {target}.

curl -H "x-api-key: $LICTOR_KEY" http://localhost:8080/vm/web/state
# 200 {"vm":"web","state":"running"}
Status When
200 State retrieved.
401 Missing/invalid API key.
404 The target domain does not exist.
500 libvirt failed for any other reason.

POST /vm/{target}/{action}

Runs {action} against {target}. Each action maps to a single libvirt operation from an exhaustive allowlist, nothing else can reach the daemon.

Action Effect
start Boot the domain.
shutdown Graceful shutdown.
suspend Pause to RAM.
resume Resume a suspended domain.
destroy Force off (hard stop).

A 200 means libvirt accepted the operation. shutdown in particular is asynchronous, the guest may take time to power off, or ignore the request entirely.

curl -X POST -H "x-api-key: $LICTOR_KEY" http://localhost:8080/vm/web/start
# 200 {"vm":"web","action":"start","ok":true}
Status When
200 Action applied.
400 Action not in the allowlist.
401 Missing/invalid API key.
404 The target domain does not exist.
500 libvirt failed for any other reason.

Errors are always JSON: {"error":"<message>"}.

About

A minimal authenticated HTTP API for managing libvirt domains on a host.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages