A convenient CLI tool to quickly spin up DragonflyBSD virtual machines using QEMU with sensible defaults.
1# dflybsd-up ≽༏≼
2
3[](https://github.com/tsirysndr/dragonflybsd-up/actions/workflows/release.yml)
4[](https://jsr.io/@tsiry/dflybsd-up)
5[](https://deno.land/x/dflybsdup)
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
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.