A convenient CLI tool to quickly spin up DragonflyBSD virtual machines using QEMU with sensible defaults.
at main 600 lines 18 kB view raw view rendered
1# dflybsd-up ≽༏≼ 2 3[![release](https://github.com/tsirysndr/dragonflybsd-up/actions/workflows/release.yml/badge.svg)](https://github.com/tsirysndr/dragonflybsd-up/actions/workflows/release.yml) 4[![JSR](https://jsr.io/badges/@tsiry/dflybsd-up)](https://jsr.io/@tsiry/dflybsd-up) 5[![deno module](https://shield.deno.dev/x/dflybsdup)](https://deno.land/x/dflybsdup) 6![deno compatibility](https://shield.deno.dev/deno/^2.5.6) 7 8A convenient CLI tool to quickly spin up DragonflyBSD virtual machines using 9QEMU with sensible defaults. Includes comprehensive VM management capabilities 10with database tracking, background execution, and flexible networking options. 11 12![Preview](./preview.png) 13 14## ✨ Features 15 16- **⚡ Quick Start**: Launch DragonflyBSD with a single command 17- **📥 Automatic ISO Download**: Fetches DragonflyBSD ISO images automatically 18 from official mirrors 19- **🔢 Version Support**: Specify any DragonflyBSD version (defaults to 6.4.2) 20- **🎯 Flexible Input**: Accepts version numbers, local ISO paths, or download 21 URLs 22- **💾 Smart Caching**: Skips re-downloading already downloaded ISOs 23- **🚀 KVM Acceleration**: Leverages KVM for optimal performance 24- **🔌 SSH Port Forwarding**: Automatically forwards port 2222 to guest port 22 25- **💻 Serial Console**: Direct terminal access without graphical overhead 26- **💿 Persistent Storage**: Optional disk image support for persistent 27 installations 28- **⚙️ Customizable Resources**: Configure CPU, memory, and disk settings 29- **🗃️ VM Management**: Track and manage multiple virtual machines with database 30 storage 31- **🌐 Bridge Networking**: Support for bridge networking configurations 32- **🔍 VM Inspection**: List, start, stop, restart, and inspect virtual machines 33- **📋 VM Operations**: Remove VMs, view logs with follow mode, and background 34 execution 35- **🏷️ Automatic MAC Assignment**: Unique MAC addresses generated for each VM 36- **🔧 Custom Port Forwarding**: Flexible port mapping with multiple forwards 37 support 38- **🔄 Background Mode**: Run VMs detached from terminal with logging support 39- **🐳 OCI Registry Support**: Push and pull VM images to/from OCI-compliant 40 registries (Docker Hub, GitHub Container Registry, etc.) 41- **📦 Image Management**: Tag, list, and remove local VM images 42- **⚙️ Configuration Files**: Define VM settings in a `vmconfig.toml` file for 43 reproducible setups 44- **🚀 Image-based VMs**: Run VMs directly from saved or pulled images 45- **🌐 HTTP API**: RESTful API for programmatic VM, image, and volume management 46 with bearer token authentication 47 48## 📋 Prerequisites 49 50- [Deno](https://deno.com) runtime 51- QEMU with KVM support (`qemu-system-x86_64`) 52- KVM kernel modules enabled 53 54## 📦 Installation 55 56```bash 57deno install -A -g -r -f jsr:@tsiry/dflybsd-up 58``` 59 60## 🚀 Usage 61 62### Basic Usage 63 64```bash 65# Launch with defaults (DragonflyBSD 6.4.2, 2 CPUs, 2GB RAM) 66dflybsd-up 67 68# Specify a version (automatically downloads the RELEASE ISO) 69dflybsd-up 6.4.2 70 71# Use a local ISO file 72dflybsd-up /path/to/dragonflybsd.iso 73 74# Download from a specific URL 75dflybsd-up https://mirror-master.dragonflybsd.org/iso-images/dfly-x86_64-6.4.2_REL.iso 76``` 77 78### Advanced Options 79 80```bash 81# Custom CPU and memory configuration 82dflybsd-up --cpu host --cpus 4 --memory 4G 83 84# Specify output path for downloaded ISO 85dflybsd-up 6.4.2 --output ~/isos/dragonfly.iso 86 87# Use a persistent disk image with custom size 88dflybsd-up --image dragonfly.img --disk-format raw --size 30G 89 90# Use bridge networking 91dflybsd-up --bridge br0 92 93# Run VM in background (detached mode) 94dflybsd-up --detach 95 96# Custom port forwarding (forward host port 8080 to guest port 80) 97dflybsd-up --port-forward 8080:80 98 99# Multiple port forwards 100dflybsd-up --port-forward 8080:80,3000:3000 101 102# Combine options 103dflybsd-up 6.4.2 \ 104 --cpus 4 \ 105 --memory 8G \ 106 --image dragonfly.qcow2 \ 107 --disk-format qcow2 \ 108 --size 50G \ 109 --detach \ 110 --port-forward 2222:22,8080:80 111``` 112 113### VM Management Commands 114 115```bash 116# List running virtual machines 117dflybsd-up ps 118 119# List all virtual machines (including stopped) 120dflybsd-up ps --all 121 122# Start a previously created VM 123dflybsd-up start my-vm 124 125# Start a VM in background (detached mode) 126dflybsd-up start my-vm --detach 127 128# Stop a running VM 129dflybsd-up stop my-vm 130 131# Restart a VM 132dflybsd-up restart my-vm 133 134# Remove a VM (delete from database) 135dflybsd-up rm my-vm 136 137# View VM logs 138dflybsd-up logs my-vm 139 140# Follow VM logs in real-time 141dflybsd-up logs my-vm --follow 142 143# Inspect VM details 144dflybsd-up inspect my-vm 145``` 146 147### Configuration File Management 148 149```bash 150# Create a default VM configuration file (vmconfig.toml) 151dflybsd-up init 152 153# Edit the configuration file to customize VM settings 154# Then start the VM using the configuration 155dflybsd-up 156``` 157 158### OCI Registry Operations 159 160```bash 161# Login to a registry (e.g., Docker Hub, GitHub Container Registry) 162dflybsd-up login ghcr.io --username your-username 163# or pipe password 164echo $GITHUB_TOKEN | dflybsd-up login ghcr.io --username your-username 165 166# Tag a VM's disk image 167dflybsd-up tag my-vm ghcr.io/username/my-dragonfly-vm:latest 168 169# Push VM image to registry 170dflybsd-up push ghcr.io/username/my-dragonfly-vm:latest 171 172# Pull VM image from registry 173dflybsd-up pull ghcr.io/username/my-dragonfly-vm:latest 174 175# List local VM images 176dflybsd-up images 177 178# Remove a local VM image 179dflybsd-up rmi ghcr.io/username/my-dragonfly-vm:latest 180 181# Run a VM from a pulled image 182dflybsd-up run ghcr.io/username/my-dragonfly-vm:latest 183 184# Run with custom options 185dflybsd-up run ghcr.io/username/my-dragonfly-vm:latest --cpus 4 --memory 8G --detach 186 187# Logout from registry 188dflybsd-up logout ghcr.io 189``` 190 191### HTTP API Server 192 193```bash 194# Start the HTTP API server (default port: 8893) 195dflybsd-up serve 196 197# Start on a custom port 198dflybsd-up serve --port 9000 199 200# Set a custom API token via environment variable 201export DFLYBSD_UP_API_TOKEN="your-secure-token" 202dflybsd-up serve 203 204# If no token is set, a random UUID will be generated and displayed 205``` 206 207The HTTP API provides RESTful endpoints for: 208 209- **Machines**: List, create, start, stop, restart, inspect, and remove VMs 210- **Images**: Create, list and remove VM images 211- **Volumes**: List, create, inspect, and remove volumes 212 213All endpoints require bearer token authentication. See the API documentation 214section below for detailed endpoint information. 215 216## 🌐 HTTP API 217 218The HTTP API server provides programmatic access to all dflybsd-up functionality 219through RESTful endpoints. 220 221### Starting the API Server 222 223```bash 224# Start with default settings (port 8893) 225dflybsd-up serve 226 227# Custom port 228dflybsd-up serve --port 9000 229 230# Set custom token via environment variable 231export DFLYBSD_UP_API_TOKEN="your-secure-token" 232dflybsd-up serve 233``` 234 235### Authentication 236 237All API endpoints require bearer token authentication. Include the token in the 238`Authorization` header: 239 240```bash 241curl -H "Authorization: Bearer your-token" http://localhost:8893/machines 242``` 243 244### API Endpoints 245 246#### Machines 247 248- **GET `/machines`** - List all machines 249 - Query params: `?all=true` to include stopped machines 250- **POST `/machines`** - Create a new machine 251 - Body: 252 `{ "image": "ghcr.io/tsirysndr/dragonflybsd:6.4.2", "cpus": 4, "memory": "4G", "bridge": "br0", "portForward": ["2222:22"], "volume": "volume-name" }` 253- **GET `/machines/:id`** - Get machine details 254- **POST `/machines/:id/start`** - Start a machine 255 - Body (optional): 256 `{ "cpus": 4, "memory": "4G", "cpu": "host", "portForward": ["2222:22"] }` 257- **POST `/machines/:id/stop`** - Stop a machine 258- **POST `/machines/:id/restart`** - Restart a machine 259 - Body (optional): 260 `{ "cpus": 4, "memory": "4G", "cpu": "host", "portForward": ["2222:22"] }` 261- **DELETE `/machines/:id`** - Remove a machine (must be stopped) 262 263#### Images 264 265- **GET `/images`** - List all local images 266- **POST `/images/pull`** - Pull an image from registry 267 - Body: `{ "image": "ghcr.io/user/image:tag" }` 268- **POST `/images/push`** - Push an image to registry 269 - Body: `{ "image": "ghcr.io/user/image:tag" }` 270- **POST `/images/tag`** - Tag a machine's image 271 - Body: `{ "vmName": "machine-name", "image": "ghcr.io/user/image:tag" }` 272- **DELETE `/images/:ref`** - Remove an image 273 - Path param: URL-encoded image reference 274 275#### Volumes 276 277- **GET `/volumes`** - List all volumes 278- **POST `/volumes`** - Create a new volume 279 - Body: `{ "name": "volume-name", "size": "20G", "format": "qcow2" }` 280- **GET `/volumes/:name`** - Get volume details 281- **DELETE `/volumes/:name`** - Remove a volume 282 283### Example API Usage 284 285```bash 286# List all machines 287curl -H "Authorization: Bearer your-token" \ 288 http://localhost:8893/machines?all=true 289 290# Create a new machine 291curl -X POST \ 292 -H "Authorization: Bearer your-token" \ 293 -H "Content-Type: application/json" \ 294 -d '{"image":"ghcr.io/tsirysndr/dragonflybsd:6.4.2","cpus":4,"memory":"8G"}' \ 295 http://localhost:8893/machines 296 297# Start a machine 298curl -X POST \ 299 -H "Authorization: Bearer your-token" \ 300 -H "Content-Type: application/json" \ 301 -d '{"cpus":8,"memory":"16G"}' \ 302 http://localhost:8893/machines/clxy1234567890/start 303 304# Pull an image 305curl -X POST \ 306 -H "Authorization: Bearer your-token" \ 307 -H "Content-Type: application/json" \ 308 -d '{"image":"ghcr.io/tsirysndr/dragonfly:latest"}' \ 309 http://localhost:8893/images/pull 310 311# Create a volume 312curl -X POST \ 313 -H "Authorization: Bearer your-token" \ 314 -H "Content-Type: application/json" \ 315 -d '{"name":"data-volume","size":"50G","format":"qcow2"}' \ 316 http://localhost:8893/volumes 317``` 318 319## ⚙️ Options 320 321| Option | Short | Description | Default | 322| ---------------- | ----- | ------------------------------------------- | ----------------------- | 323| `--output` | `-o` | Output path for downloaded ISO | Auto-generated from URL | 324| `--cpu` | `-c` | CPU type to emulate | `host` | 325| `--cpus` | `-C` | Number of CPU cores | `2` | 326| `--memory` | `-m` | Amount of memory for VM | `2G` | 327| `--image` | `-i` | Path to VM disk image | None | 328| `--disk-format` | | Disk image format (qcow2, raw, etc.) | `raw` | 329| `--size` | | Size of disk image to create | `20G` | 330| `--bridge` | `-b` | Network bridge name for networking | None (uses NAT) | 331| `--detach` | `-d` | Run VM in the background | `false` | 332| `--port-forward` | `-p` | Custom port forwarding (hostPort:guestPort) | `2222:22` | 333| `--install` | | Persist changes to the VM disk image | `false` | 334 335## 📝 Configuration File 336 337You can create a `vmconfig.toml` file to define default VM settings: 338 339```bash 340# Initialize a configuration file 341dflybsd-up init 342``` 343 344This creates a configuration file with the following structure: 345 346```toml 347[vm] 348iso = "https://mirror-master.dragonflybsd.org/iso-images/dfly-x86_64-6.4.2_REL.iso" 349# output = "./dfly-x86_64-6.4.2_REL.iso" 350cpu = "host" 351cpus = 2 352memory = "2G" 353# image = "dragonfly.qcow2" 354disk_format = "qcow2" 355size = "20G" 356 357[network] 358# bridge = "br0" 359port_forward = "2222:22" 360 361[options] 362detach = false 363``` 364 365When you run `dflybsd-up` without arguments, it will use the settings from this 366file. Command-line options override configuration file settings. 367 368## 🔢 Version Format 369 370Simply provide the version number (e.g., `6.4.2` or `6.2`), and the tool will 371automatically construct the download URL for the corresponding RELEASE ISO. 372 373Examples: 374 375- `6.4.2` → downloads `dfly-x86_64-6.4.2_REL.iso` 376- `6.2` → downloads `dfly-x86_64-6.2_REL.iso` 377- `7.0` → downloads `dfly-x86_64-7.0_REL.iso` 378 379## 🖥️ Console Setup 380 381When DragonflyBSD boots, you'll see the boot menu. For the best experience with 382the serial console: 383 3841. **Select option `9. Escape to loader prompt (also ESC)`** 3852. **Configure console output:** 386 387 ``` 388 set console=comconsole 389 boot 390 ``` 391 392This enables proper console redirection to your terminal. 393 394## 🔍 VM Management & Background Execution 395 396### Background Mode (Detached) 397 398Run VMs in the background without blocking your terminal: 399 400```bash 401# Create and run VM in background 402dflybsd-up --detach 403 404# Start existing VM in background 405dflybsd-up start my-vm --detach 406 407# When running in background, you can: 408dflybsd-up logs my-vm --follow # View real-time logs 409dflybsd-up stop my-vm # Stop the VM 410dflybsd-up restart my-vm # Restart the VM 411``` 412 413### VM Lifecycle Management 414 415- **Automatic Tracking**: Each VM is assigned a unique name and tracked in a 416 local SQLite database 417- **Persistent State**: VM configurations are preserved between sessions 418- **Status Monitoring**: Track running and stopped VMs with process IDs 419- **Resource Information**: View CPU, memory, disk, and network configurations 420 for each VM 421- **Log Management**: Each VM maintains its own log file for debugging and 422 monitoring 423 424## � OCI Registry Integration 425 426The tool supports pushing and pulling VM images to/from OCI-compliant registries 427like Docker Hub, GitHub Container Registry (ghcr.io), and others. 428 429### Workflow 430 4311. **Create and configure a VM** with desired settings 4322. **Tag the VM's disk image** to create a reference 4333. **Login to a registry** with your credentials 4344. **Push the image** to share it with others 4355. **Pull images** created by you or others to run pre-configured VMs 436 437### Example: Sharing a VM Image 438 439```bash 440# Create a VM with persistent storage 441dflybsd-up 6.4.2 --image dragonfly.qcow2 --size 30G 442 443# Configure your DragonflyBSD installation as desired 444# (install packages, configure services, etc.) 445 446# Stop the VM and tag it 447dflybsd-up stop <vm-name> 448dflybsd-up tag <vm-name> ghcr.io/username/my-dragonfly-setup:v1 449 450# Login to GitHub Container Registry 451echo $GITHUB_TOKEN | dflybsd-up login ghcr.io --username username 452 453# Push the image 454dflybsd-up push ghcr.io/username/my-dragonfly-setup:v1 455 456# Others can now pull and run your image 457dflybsd-up pull ghcr.io/username/my-dragonfly-setup:v1 458dflybsd-up run ghcr.io/username/my-dragonfly-setup:v1 459``` 460 461### Supported Registries 462 463- **GitHub Container Registry**: `ghcr.io` 464- **Docker Hub**: `docker.io` or just the image name (e.g., 465 `username/image:tag`) 466- Any OCI-compliant registry that supports the OCI Distribution Specification 467 468## �🗃️ Virtual Machine Management 469 470The tool now includes database-backed VM management, allowing you to track and 471manage multiple virtual machines: 472 473### VM Lifecycle 474 475- **Automatic Tracking**: Each VM is assigned a unique name and tracked in a 476 local SQLite database 477- **Persistent State**: VM configurations are preserved between sessions 478- **Status Monitoring**: Track running and stopped VMs with process IDs 479- **Resource Information**: View CPU, memory, and disk configurations for each 480 VM 481 482### VM Commands 483 484- `ps` - List virtual machines (use `--all` to include stopped VMs) 485- `start <vm-name>` - Start a previously created VM (use `--detach` to run in 486 background) 487- `stop <vm-name>` - Stop a running VM 488- `restart <vm-name>` - Restart a VM (stop and start again) 489- `rm <vm-name>` - Remove a VM from the database (does not delete disk images) 490- `logs <vm-name>` - View VM logs (use `--follow` for real-time logs) 491- `inspect <vm-name>` - View detailed VM information 492 493## 🌐 Networking Options 494 495### Default NAT Networking 496 497By default, VMs use QEMU's user-mode networking with port forwarding: 498 499- Host port 2222 → Guest port 22 (SSH) by default 500- Custom port forwarding available with `--port-forward` option 501- No additional configuration required 502- Works without root privileges 503 504#### Custom Port Forwarding 505 506You can specify custom port forwarding rules: 507 508```bash 509# Forward host port 8080 to guest port 80 510dflybsd-up --port-forward 8080:80 511 512# Multiple port forwards (comma-separated) 513dflybsd-up --port-forward 8080:80,3000:3000,2222:22 514 515# Use with other options 516dflybsd-up 6.4.2 --port-forward 8080:80 --memory 4G 517``` 518 519### Advanced Bridge Networking 520 521For more advanced networking scenarios, use bridge networking: 522 523```bash 524# Use an existing bridge 525dflybsd-up --bridge br0 526 527# The tool will create the bridge if it doesn't exist (requires sudo) 528``` 529 530Benefits of bridge networking: 531 532- VMs get IP addresses on your local network 533- Direct network access without port forwarding 534- Better performance for network-intensive applications 535- Supports multiple VMs on the same network segment 536 537## 💿 Creating a Persistent Disk 538 539To install DragonflyBSD persistently: 540 541```bash 542# Create a disk image (done automatically with --image if image doesn't exist) 543dflybsd-up 6.4.2 --image dragonfly.qcow2 --disk-format qcow2 --size 30G 544 545# Use --install flag to persist changes to the disk image 546dflybsd-up 6.4.2 --image dragonfly.qcow2 --disk-format qcow2 --install 547 548# Or manually create with qemu-img 549qemu-img create -f qcow2 dragonfly.qcow2 20G 550 551# Launch with the disk attached 552dflybsd-up 6.4.2 --image dragonfly.qcow2 --disk-format qcow2 553``` 554 555The `--install` option ensures that changes made during the VM session are 556written to the disk image, making them persistent across reboots. 557 558## 🔐 SSH Access 559 560### NAT Networking (Default) 561 562The VM automatically forwards host port 2222 to guest port 22 by default. You 563can customize port forwarding with the `--port-forward` option. After 564configuring SSH in your DragonflyBSD installation: 565 566```bash 567# Default SSH access (2222:22 forwarding) 568ssh -p 2222 user@localhost 569 570# Custom port forwarding 571dflybsd-up --port-forward 2200:22 572ssh -p 2200 user@localhost 573 574# Access other services with custom forwarding 575dflybsd-up --port-forward 2222:22,8080:80 576# SSH: ssh -p 2222 user@localhost 577# HTTP: http://localhost:8080 578``` 579 580### Bridge Networking 581 582With bridge networking, the VM gets its own IP address on your network. You can 583SSH directly to the VM's IP: 584 585```bash 586ssh user@<vm-ip-address> 587``` 588 589## 📄 License 590 591See [LICENSE](LICENSE) file for details. 592 593## 🤝 Contributing 594 595Contributions are welcome! Please feel free to submit issues or pull requests. 596 597> [!NOTE] 598> 599> This tool is designed for development and testing purposes. For production 600> DragonflyBSD deployments, consider using proper installation methods.