A simple command-line tool to start NetBSD virtual machines using QEMU with sensible defaults.
- π₯οΈ Easy NetBSD VM setup: Launch NetBSD virtual machines with a single command
- π₯ Automatic ISO download: Downloads NetBSD ISO images from official CDN
- π·οΈ Version-aware: Specify NetBSD versions and automatically construct download URLs
- π Flexible input: Support for local ISO files, URLs, version numbers, or OCI registry images
- βοΈ Configurable VM settings: Customize CPU, memory, cores, and disk options via CLI or configuration file
- β‘ KVM acceleration: Automatically enables hardware virtualization for better performance
- π Port forwarding: Customizable port forwarding rules for network access
- π» Serial console: No GUI required - works entirely in terminal
- π§ VM Management: Start, stop, restart, inspect, remove, and list virtual machines
- π VM Logging: Centralized logging with follow support for real-time monitoring
- π Background execution: Run VMs in detached mode for long-running tasks
- πΎ Persistent storage: SQLite database to track VM states and configurations
- π·οΈ Auto-naming: Automatic generation of unique VM names
- π Bridge networking: Support for custom network bridges
- π¦ OCI Registry Support: Pull, push, and tag VM images to/from OCI-compliant registries (GitHub Container Registry, Docker Hub, etc.)
- πΌοΈ Image Management: List and remove local VM images
- π Configuration File: Initialize and use
vmconfig.tomlfor persistent VM settings - π½ Volume Management: Create, list, inspect, and remove persistent volumes
- π Volume Attachment: Attach persistent volumes to VMs for data storage
- π HTTP API: RESTful API for managing machines, images, and volumes programmatically
- π¦ Deno runtime
- π₯οΈ QEMU with KVM support
- π₯
curlfor downloading ISO images
# Clone the repository
git clone https://github.com/tsirysndr/netbsd-up.git
cd netbsd-up
# Make it executable
chmod +x main.tsRun the following command to install the CLI:
deno install -A -g -r -f jsr:@tsiry/netbsd-upStart a NetBSD 10.1 VM with default settings:
netbsd-upnetbsd-up 10.1
netbsd-up 9.3netbsd-up /path/to/netbsd.isonetbsd-up https://cdn.netbsd.org/pub/NetBSD/images/10.1/NetBSD-10.1-amd64.iso# Pull from GitHub Container Registry
netbsd-up ghcr.io/tsirysndr/netbsd:10.1
# Pull from Docker Hub
netbsd-up docker.io/username/netbsd:10.1Create a vmconfig.toml file with default settings:
netbsd-up initThen customize the file and start the VM:
netbsd-upList all running VMs:
netbsd-up psList all VMs (including stopped):
netbsd-up ps --allStart a stopped VM:
netbsd-up start <vm-name>Start a VM in the background (detached):
netbsd-up start <vm-name> --detachStop a running VM:
netbsd-up stop <vm-name>Restart a VM:
netbsd-up restart <vm-name>Remove a VM:
netbsd-up rm <vm-name>View VM logs:
netbsd-up logs <vm-name>Follow VM logs in real-time:
netbsd-up logs <vm-name> --followInspect VM details:
netbsd-up inspect <vm-name>Login to a registry:
netbsd-up login ghcr.io -u username
# Or with Docker Hub
netbsd-up login docker.io -u usernamePull a VM image:
netbsd-up pull ghcr.io/tsirysndr/netbsd:10.1Push a VM image:
netbsd-up push ghcr.io/username/netbsd:10.1Tag a VM:
netbsd-up tag my-vm ghcr.io/username/netbsd:customRun a VM from an image:
netbsd-up run ghcr.io/tsirysndr/netbsd:10.1 --detachList local images:
netbsd-up imagesRemove a local image:
netbsd-up rmi ghcr.io/tsirysndr/netbsd:10.1Logout from a registry:
netbsd-up logout ghcr.ioWhen NetBSD boots, you'll see the boot menu. For the best experience with the serial console:
-
π§ Select option
3. Drop to boot prompt -
βοΈ Configure console output:
consdev com0 boot
This enables proper console redirection to your terminal.
# Custom CPU, memory, and cores
netbsd-up --cpu host --memory 4G --cpus 4
# Save downloaded ISO to specific location
netbsd-up --output netbsd-10.1.iso
# Use existing disk image
netbsd-up --image vm-disk.img --disk-format qcow2
# Run VM in the background
netbsd-up --detach
# Custom port forwarding (SSH on port 2222, HTTP on port 8080)
netbsd-up --port-forward "2222:22,8080:80"
# Attach a volume to the VM
netbsd-up start my-vm --volume my-data-volume
# Combine multiple options
netbsd-up --memory 8G --cpus 4 --detach --port-forward "3000:3000"| Option | Short | Description | Default |
|---|---|---|---|
--output |
-o |
Output path for downloaded ISO | Auto-generated |
--cpu |
-c |
CPU type to emulate | host |
--cpus |
-C |
Number of CPU cores | 2 |
--memory |
-m |
Amount of VM memory | 2G |
--image |
-i |
Path to VM disk image | None |
--disk-format |
Disk image format | raw |
|
--size |
-s |
Size of the disk image to create if it doesn't exist | 20G |
--bridge |
-b |
Name of the network bridge to use for networking (e.g., br0) | None |
--detach |
-d |
Run VM in the background and print VM name | false |
--port-forward |
-p |
Port forwarding rules (format: hostPort:guestPort) | None |
--install |
Persist changes to the VM disk image | false |
|
--volume |
-v |
Name of the volume to attach to the VM | None |
| Command | Description |
|---|---|
netbsd-up init |
Initialize a default VM configuration file |
netbsd-up ps |
List all running virtual machines |
netbsd-up ps --all |
List all virtual machines (including stopped) |
netbsd-up start <name> |
Start a stopped virtual machine |
netbsd-up start <name> -d |
Start a virtual machine in background (detached) |
netbsd-up start <name> -v <vol> |
Start a VM and attach a volume |
netbsd-up stop <name> |
Stop a running virtual machine |
netbsd-up restart <name> |
Restart a virtual machine |
netbsd-up inspect <name> |
Show detailed information about a VM |
netbsd-up rm <name> |
Remove a virtual machine from database |
netbsd-up logs <name> |
View logs for a virtual machine |
netbsd-up logs <name> -f |
Follow logs in real-time |
netbsd-up pull <image> |
Pull VM image from OCI registry |
netbsd-up push <image> |
Push VM image to OCI registry |
netbsd-up tag <vm-name> <image> |
Tag a VM with an image name |
netbsd-up run <image> |
Create and run a VM from an image |
netbsd-up run <image> -v <vol> |
Run a VM from an image with an attached volume |
netbsd-up images |
List all local VM images |
netbsd-up rmi <image> |
Remove a local VM image |
netbsd-up login <registry> |
Authenticate to an OCI registry |
netbsd-up logout <registry> |
Logout from an OCI registry |
netbsd-up volumes |
List all volumes |
netbsd-up volume rm <name> |
Remove a volume |
netbsd-up volume inspect <name> |
Inspect a volume |
netbsd-up serve |
Start the HTTP API server |
netbsd-up serve -p <port> |
Start the HTTP API server on a specific port |
netbsd-upStarts NetBSD 10.1 with 2 CPU cores and 2GB RAM.
netbsd-up --cpus 8 --memory 8G --cpu host --detach# SSH on port 2222, web server on port 8080
netbsd-up --port-forward "2222:22,8080:80"
# Development setup with multiple ports
netbsd-up --port-forward "3000:3000,5432:5432" --detach# Create a disk image first
qemu-img create -f qcow2 netbsd-dev.qcow2 20G
# Start VM with the disk
./main.ts --image netbsd-dev.qcow2 --disk-format qcow2netbsd-up 10.1
netbsd-up 9.4# Pull and start a VM from GitHub Container Registry
netbsd-up ghcr.io/tsirysndr/netbsd:10.1
# Login to GitHub Container Registry
netbsd-up login ghcr.io -u username
# Tag an existing VM
netbsd-up tag my-vm ghcr.io/username/netbsd:custom
# Push the tagged VM to registry
netbsd-up push ghcr.io/username/netbsd:custom
# Run a VM from an image with custom settings
netbsd-up run ghcr.io/tsirysndr/netbsd:10.1 --memory 4G --cpus 4 --detach# Initialize a VM configuration file
netbsd-up init
# Edit vmconfig.toml to customize settings
# Then start the VM using the config
netbsd-upExample vmconfig.toml:
[vm]
iso = "https://cdn.netbsd.org/pub/NetBSD/images/10.1/NetBSD-10.1-amd64.iso"
cpu = "host"
cpus = 4
memory = "4G"
[network]
port_forward = "2222:22,8080:80"
[options]
detach = true# Start VM in background
netbsd-up --detach
# Start existing VM in background
netbsd-up start my-vm --detach
# Monitor VM logs
netbsd-up logs my-vm --follow# List all running VMs
netbsd-up ps
# List all VMs including stopped ones
netbsd-up ps --all
# Start a specific VM by name
netbsd-up start my-netbsd-vm
# Start a VM in the background
netbsd-up start my-netbsd-vm --detach
# Stop a running VM
netbsd-up stop my-netbsd-vm
# Restart a VM
netbsd-up restart my-netbsd-vm
# Get detailed information about a VM
netbsd-up inspect my-netbsd-vm
# Remove a VM from the database
netbsd-up rm my-netbsd-vm
# View VM logs
netbsd-up logs my-netbsd-vm
# Follow VM logs in real-time
netbsd-up logs my-netbsd-vm --follow# List all local VM images
netbsd-up images
# Remove a local VM image
netbsd-up rmi ghcr.io/tsirysndr/netbsd:10.1
# Pull a VM image from registry
netbsd-up pull ghcr.io/tsirysndr/netbsd:10.1
# Tag a VM for pushing to registry
netbsd-up tag my-vm ghcr.io/username/netbsd:custom
# Push a VM image to registry
netbsd-up push ghcr.io/username/netbsd:custom
# Logout from registry
netbsd-up logout ghcr.io# List all volumes
netbsd-up volumes
# Start a VM with a volume attached
netbsd-up start my-vm --volume my-data-volume
# Run a VM from an image with a volume
netbsd-up run ghcr.io/tsirysndr/netbsd:10.1 --volume db-storage
# Inspect a volume
netbsd-up volume inspect my-data-volume
# Remove a volume
netbsd-up volume rm my-data-volume# Start the API server
netbsd-up serve
# Start on custom port
netbsd-up serve --port 9000
# List all machines via API
curl -H "Authorization: Bearer your-token" http://localhost:8892/machines
# Start a machine via API
curl -X POST -H "Authorization: Bearer your-token" \
http://localhost:8892/machines/my-vm/start
# List all volumes via API
curl -H "Authorization: Bearer your-token" http://localhost:8892/volumesThe VM supports flexible networking configurations:
- π QEMU's user-mode networking (no special privileges required)
- π No default port forwarding (use
--port-forwardfor specific needs)
Use the --port-forward option to map host ports to guest ports:
# SSH access on port 2222
netbsd-up --port-forward "2222:22"
# Multiple port mappings
netbsd-up --port-forward "2222:22,8080:80,3000:3000"For advanced networking, use bridge mode (requires sudo):
netbsd-up --bridge br0NetBSD-UP recognizes version strings in the format:
- π’
MAJOR.MINOR(e.g.,10.1,9.3)
β‘ The tool automatically constructs the download URL for the official NetBSD release ISO.
- π·οΈ NetBSD Version: 10.1
- π₯οΈ CPU: host (uses host CPU features)
- πΎ Memory: 2GB
- β‘ CPU Cores: 2
- πΏ Disk Format: raw
- πΎ Disk Size: 20GB (when creating new disk images)
- π Network: User-mode with SSH forwarding
- π·οΈ VM Names: Auto-generated unique names using random words
NetBSD-UP uses a SQLite database (~/.netbsd-up/state.sqlite) to track virtual
machine states, configurations, and volumes. The database stores:
- VM names and unique identifiers
- CPU, memory, and disk configurations
- Network settings (bridge, MAC addresses, port forwarding)
- Current status (RUNNING, STOPPED) with timestamps
- Creation and update timestamps
- Process IDs for running VMs
- Log file locations for each VM
- Volume information and attachments
All VM output is automatically logged to ~/.netbsd-up/logs/<vm-name>.log. You
can:
- View logs:
netbsd-up logs <vm-name> - Follow logs in real-time:
netbsd-up logs <vm-name> --follow - Access logs directly from the filesystem
NetBSD-UP supports pulling and pushing VM images to OCI-compliant registries such as GitHub Container Registry (ghcr.io), Docker Hub (docker.io), and others. This enables sharing and distributing pre-configured NetBSD VMs.
# Login to GitHub Container Registry
netbsd-up login ghcr.io -u username
# Login to Docker Hub
netbsd-up login docker.io -u username
# Logout from a registry
netbsd-up logout ghcr.io# Pull from GitHub Container Registry
netbsd-up pull ghcr.io/tsirysndr/netbsd:10.1
# Start a VM directly from registry
netbsd-up ghcr.io/tsirysndr/netbsd:10.1
# Run a VM from an image with custom settings
netbsd-up run ghcr.io/tsirysndr/netbsd:10.1 --memory 4G --cpus 4# Tag an existing VM
netbsd-up tag my-vm ghcr.io/username/netbsd:custom
# Push the tagged VM to registry
netbsd-up push ghcr.io/username/netbsd:custom# List local images
netbsd-up images
# Remove a local image
netbsd-up rmi ghcr.io/tsirysndr/netbsd:10.1NetBSD-UP supports using a vmconfig.toml file for persistent VM configuration.
This is useful for reproducible VM setups.
netbsd-up initThis creates a vmconfig.toml file with default settings:
[vm]
iso = "https://cdn.netbsd.org/pub/NetBSD/images/10.1/NetBSD-10.1-amd64.iso"
cpu = "host"
cpus = 2
memory = "2G"
[network]
[options]Simply run netbsd-up in the directory containing vmconfig.toml:
netbsd-upCLI options will override configuration file settings.
NetBSD-UP supports persistent volumes that can be attached to VMs for data
storage. Volumes are stored as disk images in ~/.netbsd-up/volumes/ and
persist independently of VM lifecycles.
Volumes are automatically created when you attach them to a VM:
# Start a VM with a volume (volume is created if it doesn't exist)
netbsd-up start my-vm --volume my-data-volume
# Run a new VM from an image with an attached volume
netbsd-up run ghcr.io/tsirysndr/netbsd:10.1 --volume db-storage# List all volumes
netbsd-up volumes
# Inspect a volume
netbsd-up volume inspect my-data-volume
# Remove a volume
netbsd-up volume rm my-data-volume- π¦ Persistent Storage: Volumes persist independently of VMs
- π Reusable: Attach the same volume to different VMs
- πΎ Automatic Creation: Volumes are created on first use
- π Tracking: All volumes are tracked in the SQLite database
NetBSD-UP includes a RESTful HTTP API for programmatic management of machines, images, and volumes. The API is protected by bearer token authentication.
# Start on default port (8892)
netbsd-up serve
# Start on custom port
netbsd-up serve --port 9000
# Set API token via environment variable
export NETBSD_UP_API_TOKEN="your-secure-token"
netbsd-up serveIf no NETBSD_UP_API_TOKEN is set, a random token will be generated and
displayed.
The API provides the following endpoints:
GET /machines- List all machinesGET /machines/:id- Get machine detailsPOST /machines- Create a new machinePOST /machines/:id/start- Start a machinePOST /machines/:id/stop- Stop a machinePOST /machines/:id/restart- Restart a machineDELETE /machines/:id- Remove a machine
GET /images- List all imagesGET /images/:name- Get image detailsPOST /images/pull- Pull an image from registryPOST /images/push- Push an image to registryDELETE /images/:name- Remove an image
GET /volumes- List all volumesGET /volumes/:name- Get volume detailsPOST /volumes- Create a volumeDELETE /volumes/:name- Remove a volume
All API endpoints require bearer token authentication:
# Example API request
curl -H "Authorization: Bearer your-token" http://localhost:8892/machinesNETBSD_UP_API_TOKEN- Set the API authentication tokenNETBSD_UP_PORT- Set the default API server port
See LICENSE file for details.
Contributions are welcome! Please feel free to submit issues and pull requests.
Note
This tool is designed for development and testing purposes. For production NetBSD deployments, consider using proper installation methods.
