@seasoncloud/libvirt-api
v1.0.0
Published
TypeScript library for libvirt virtualization management with per-hypervisor support
Readme
@libvirt/api
TypeScript library para manipulação do libvirt via CLI (virsh), com tipagem forte, API async/await e suporte a múltiplos hypervisors.
Features
- 🖥️ Multi-hypervisor — QEMU, KVM, Xen, LXC, VirtualBox, VMware
- 🔌 Conexão remota via SSH — suporte nativo a tunneling SSH
- 📦 Dual format — ESM + CJS com type declarations
- 🛡️ Type-safe — tipagem completa para todas as operações
- ⚡ Zero native deps — sem compilação nativa, usa
virshCLI - 🎛️ Modular — Domains, Networks, Storage, Snapshots, Node
Pré-requisitos
- Node.js >= 18
libvirtinstalado no host (virshdisponível no PATH)
# Ubuntu/Debian
sudo apt install libvirt-daemon-system libvirt-clients
# RHEL/CentOS
sudo yum install libvirt libvirt-client
# Arch Linux
sudo pacman -S libvirtInstalação
pnpm add @libvirt/apiQuick Start
import { LibvirtClient, HypervisorType } from "@libvirt/api";
// Conectar ao QEMU/KVM local
const client = await LibvirtClient.connect({
hypervisor: HypervisorType.QEMU,
});
// Listar todas as VMs
const vms = await client.domains.list();
console.log(vms);
// Informações do host
const nodeInfo = await client.node.getInfo();
console.log(`Host: ${nodeInfo.hostname}, CPUs: ${nodeInfo.cpus}`);Uso por Hypervisor
QEMU/KVM
const client = await LibvirtClient.connect({
hypervisor: HypervisorType.QEMU,
// URI padrão: qemu:///system
});Xen
const client = await LibvirtClient.connect({
hypervisor: HypervisorType.XEN,
// URI padrão: xen:///
});LXC
const client = await LibvirtClient.connect({
hypervisor: HypervisorType.LXC,
// URI padrão: lxc:///
});Conexão Remota (SSH)
const client = await LibvirtClient.connect({
hypervisor: HypervisorType.KVM,
ssh: {
host: "192.168.1.100",
user: "root",
keyFile: "/home/user/.ssh/id_rsa",
},
// URI gerada: qemu+ssh://[email protected]/system
});Test Driver (desenvolvimento)
const client = await LibvirtClient.connect({
hypervisor: HypervisorType.TEST,
// URI: test:///default
});API Reference
Domains (VMs)
// Listar
const vms = await client.domains.list();
const vmInfo = await client.domains.getInfo("my-vm");
// Lifecycle
await client.domains.start("my-vm");
await client.domains.shutdown("my-vm");
await client.domains.destroy("my-vm");
await client.domains.reboot("my-vm");
await client.domains.suspend("my-vm");
await client.domains.resume("my-vm");
await client.domains.reset("my-vm");
// Configuração
await client.domains.define({
name: "new-vm",
memory: 2048,
vcpus: 2,
disk: "/var/lib/libvirt/images/vm.qcow2",
cdrom: "/path/to/install.iso",
network: "network",
graphics: "vnc",
});
await client.domains.setAutostart("my-vm", true);
await client.domains.setMemory("my-vm", 4194304);
await client.domains.setVcpus("my-vm", 4, { config: true });
await client.domains.rename("my-vm", "new-name");
await client.domains.undefine("my-vm", { removeAllStorage: true });
// Stats e recursos
const stats = await client.domains.getStats("my-vm");
const blocks = await client.domains.getBlockList("my-vm");
const ifaces = await client.domains.getInterfaceList("my-vm");Networks
// Listar
const nets = await client.networks.list();
const netInfo = await client.networks.getInfo("default");
// Criar rede NAT com DHCP
await client.networks.define({
name: "my-network",
mode: "nat",
bridge: "virbr1",
gateway: "192.168.100.1",
subnet: "192.168.100.0/24",
dhcpRange: { start: "192.168.100.100", end: "192.168.100.254" },
autostart: true,
});
// Lifecycle
await client.networks.start("my-network");
await client.networks.destroy("my-network");
await client.networks.setAutostart("my-network", true);
// DHCP leases
const leases = await client.networks.getDhcpLeases("default");Storage
// Pools
const pools = await client.storage.listPools();
const poolInfo = await client.storage.getPoolInfo("default");
await client.storage.definePool({
name: "my-pool",
type: StoragePoolType.DIR,
targetPath: "/var/lib/libvirt/images/my-pool",
});
await client.storage.buildPool("my-pool");
await client.storage.startPool("my-pool");
// Volumes
const volumes = await client.storage.listVolumes("default");
await client.storage.createVolume({
pool: "default",
name: "new-disk.qcow2",
capacity: "20G",
format: "qcow2",
});
await client.storage.resizeVolume("disk.qcow2", "default", "40G");
await client.storage.cloneVolume("disk.qcow2", "disk-clone.qcow2", "default");
await client.storage.deleteVolume("old-disk.qcow2", "default");Snapshots
// Listar
const snaps = await client.snapshots.list("my-vm");
const current = await client.snapshots.getCurrent("my-vm");
// Criar
await client.snapshots.create({
domain: "my-vm",
name: "before-update",
description: "Snapshot before system update",
});
// Reverter
await client.snapshots.revert({
domain: "my-vm",
name: "before-update",
running: true,
});
// Deletar
await client.snapshots.delete("my-vm", "old-snapshot", { children: true });Node (Host)
const info = await client.node.getInfo();
const memory = await client.node.getMemoryStats();
const cpu = await client.node.getCpuStats();
const freeMemory = await client.node.getFreeMemory();
const capabilities = await client.node.getCapabilities();
const version = await client.node.getVersion();Error Handling
import {
LibvirtError,
ConnectionError,
DomainError,
ExecutionError,
} from "@libvirt/api";
try {
await client.domains.start("nonexistent-vm");
} catch (err) {
if (err instanceof DomainError) {
console.error(`Domain error: ${err.message} (domain: ${err.domain})`);
} else if (err instanceof ConnectionError) {
console.error(`Connection lost: ${err.message}`);
} else if (err instanceof ExecutionError) {
console.error(`Command failed: ${err.command}`);
console.error(`Exit code: ${err.exitCode}`);
console.error(`Stderr: ${err.stderr}`);
}
}Custom URI
const client = await LibvirtClient.connect({
hypervisor: HypervisorType.QEMU,
uri: "qemu+tcp://[email protected]/system",
timeout: 60000,
virshPath: "/usr/local/bin/virsh",
});License
MIT
