# FreeBSD-Up 🚀 [![release](https://github.com/tsirysndr/freebsd-up/actions/workflows/release.yml/badge.svg)](https://github.com/tsirysndr/freebsd-up/actions/workflows/release.yml) [![JSR](https://jsr.io/badges/@tsiry/freebsd-up)](https://jsr.io/@tsiry/freebsd-up) [![deno module](https://shield.deno.dev/x/freebsdup)](https://deno.land/x/freebsdup) ![deno compatibility](https://shield.deno.dev/deno/^2.5.6) A comprehensive FreeBSD virtual machine management tool built with Deno and QEMU. Effortlessly create, manage, and run FreeBSD VMs with persistent state tracking, network bridging support, and zero-configuration defaults. ![Preview](./preview.png) ## ✨ Features ### Core VM Management - 🏗️ **Full VM lifecycle management**: Create, start, stop, restart, inspect, and remove VMs - 💾 **Persistent state tracking**: SQLite database stores VM configurations and state - 📊 **VM listing and monitoring**: View running and stopped VMs with detailed information - 🔍 **VM inspection**: Get detailed information about any managed VM - 📋 **VM logging**: View and follow VM logs with built-in log management - 🔄 **VM restart**: Gracefully restart VMs with preserved configuration - 🗑️ **VM removal**: Clean removal of VMs from the database - 🏷️ **Auto-generated VM names**: Unique identifiers for easy VM management - 🏛️ **Cross-platform support**: Works on both x86_64 and aarch64 architectures - 🔧 **Background mode**: Run VMs in detached mode for headless operation - 🚀 **Run from images**: Create and run VMs directly from OCI registry images - 💾 **Install mode**: Persist changes to VM disk images with `--install` flag ### Network & Storage - 🌐 **Flexible networking**: Support for both user-mode and bridge networking - 🔗 **Network bridge support**: Automatic bridge creation and management with `--bridge` - 🖧 **MAC address management**: Persistent MAC addresses for each VM - 📍 **Port forwarding**: Custom port mapping for network services with `--port-forward` - 💾 **Persistent storage support**: Attach and auto-create disk images - 🗂️ **Multiple disk formats**: Support for qcow2, raw, and other disk formats - 📏 **Configurable disk sizes**: Specify disk image size on creation - 🗄️ **Volume management**: Create, list, inspect, and remove persistent volumes - 🔗 **Volume attachment**: Attach volumes to VMs with `--volume` flag ### Convenience Features ### Image Management & OCI Registry Support - 📦 **OCI Registry Integration**: Pull and push VM disk images to OCI-compatible registries - 🗂️ **Image Management**: List, tag, and remove VM disk images with `images`, `tag`, and `rmi` commands - 🔐 **Registry Authentication**: Login and logout from OCI registries with `login` and `logout` commands - 🔄 **Image Sharing**: Share VM configurations and disk images across teams and environments - 📥 **Pull from Registry**: Download pre-configured VM images from remote registries - 📤 **Push to Registry**: Upload VM disk images to remote registries for distribution ### Configuration Management - 📄 **Configuration Files**: Support for TOML-based VM configuration files with `vmconfig.toml` - ⚙️ **Declarative VM Setup**: Define VM settings in configuration files for reproducible environments - 🔧 **Init Command**: Generate default configuration files with `freebsd-up init` - 🔀 **Config Merging**: Command-line options override configuration file settings ### HTTP API Server - 🌐 **RESTful API**: Built-in HTTP API server for remote VM management - 🔐 **Bearer Token Authentication**: Secure API access with token authentication - 🖥️ **Machine Management API**: Create, start, stop, and manage VMs via HTTP - 🗂️ **Image Management API**: List, pull, push, and manage VM images via HTTP - 💾 **Volume Management API**: Create, list, inspect, and remove volumes via HTTP - 🔧 **Configurable Port**: Customize API server port with `--port` or environment variable - 📊 **CORS Support**: Built-in CORS support for web-based clients - 🔗 **Download and boot from URLs**: Automatically downloads ISO images from remote URLs - 📁 **Local file support**: Boot from local ISO files - 🏷️ **Version shortcuts**: Simply specify a version like `14.3-RELEASE` to auto-download - 🎯 **Smart defaults**: Run without arguments to boot the latest stable release (FreeBSD 14.3-RELEASE) - ⚡ **Zero configuration**: Works out of the box with sensible defaults - 🖥️ **Serial console**: Configured for headless operation with stdio console - 💾 **Smart caching**: Automatically skips re-downloading existing ISO files - 🆘 **Help support**: Built-in help with `--help` or `-h` flags - ⚙️ **Configurable VM options**: Customize CPU type, core count, memory allocation - 📝 **Enhanced CLI**: Powered by [Cliffy](http://cliffy.io/) for robust command-line parsing ## 📋 Prerequisites Before using FreeBSD-Up, make sure you have: - **[Deno](https://deno.com)** - Modern JavaScript/TypeScript runtime - **[QEMU](https://www.qemu.org/)** - Hardware virtualization - **KVM support** (Linux) - For hardware acceleration (optional but recommended) ### Installation on Common Systems **Ubuntu/Debian:** ```bash sudo apt-get update sudo apt-get install qemu-system-x86 qemu-kvm curl -fsSL https://deno.land/install.sh | sh ``` **Fedora:** ```bash sudo dnf install qemu qemu-kvm curl -fsSL https://deno.land/install.sh | sh ``` **macOS:** ```bash brew install qemu deno ``` Run the following command to install the CLI: ```bash deno install -A -g -r -f jsr:@tsiry/freebsd-up ``` ## 🚀 Quick Start ### Default Usage (Easiest) Simply run without any arguments to boot the latest stable FreeBSD release: ```bash freebsd-up ``` This will automatically download and boot FreeBSD 14.3-RELEASE. ### Boot with Version Shortcut Specify just a version to auto-download and boot: ```bash freebsd-up 14.3-RELEASE freebsd-up 15.0-BETA3 freebsd-up 13.4-RELEASE ``` ### Boot from URL Download and boot from a specific URL: ```bash freebsd-up https://download.freebsd.org/ftp/releases/amd64/amd64/ISO-IMAGES/15.0/FreeBSD-15.0-BETA3-amd64-disc1.iso ``` ### Boot from Local File ```bash freebsd-up /path/to/your/freebsd.iso ``` ### VM Management Commands List all running VMs: ```bash freebsd-up ps ``` List all VMs (including stopped): ```bash freebsd-up ps --all ``` Start a specific VM: ```bash freebsd-up start vm-name ``` Stop a specific VM: ```bash freebsd-up stop vm-name ``` Inspect VM details: ```bash freebsd-up inspect vm-name ``` Remove a VM: ```bash freebsd-up rm vm-name ``` Restart a VM: ```bash freebsd-up restart vm-name ``` View VM logs: ```bash freebsd-up logs vm-name ``` Follow VM logs in real-time: ```bash freebsd-up logs vm-name --follow ``` ### Image Management Commands List VM disk images: ```bash freebsd-up images ``` Tag a VM disk image: ```bash freebsd-up tag vm-name ghcr.io/tsirysndr/freebsd:15.0-BETA4 ``` Remove a VM disk image: ```bash freebsd-up rmi image-id ``` Login to OCI registry: ```bash freebsd-up login -u tsirysndr ghcr.io ``` Logout from OCI registry: ```bash freebsd-up logout ghcr.io ``` Pull an image from OCI registry: ```bash freebsd-up pull ghcr.io/tsirysndr/freebsd:15.0-BETA4 ``` Push an image to OCI registry: ```bash freebsd-up push ghcr.io/tsirysndr/freebsd:15.0-BETA4 ``` Run a VM from an OCI registry image: ```bash freebsd-up run ghcr.io/tsirysndr/freebsd:15.0-BETA4 ``` ### Volume Management Commands List all volumes: ```bash freebsd-up volumes ``` Remove a volume: ```bash freebsd-up volume rm volume-name ``` Inspect a volume: ```bash freebsd-up volume inspect volume-name ``` Attach a volume to a VM: ```bash freebsd-up start vm-name --volume my-volume ``` ### Starting the API Server Start the HTTP API server: ```bash freebsd-up serve ``` Start the API server on a custom port: ```bash freebsd-up serve --port 9000 ``` Set a custom API token via environment variable: ```bash export FREEBSD_UP_API_TOKEN=your-secret-token freebsd-up serve ``` The API server provides RESTful endpoints for managing VMs, images, and volumes remotely. It includes bearer token authentication for security and supports CORS for web-based clients. ### Using Configuration Files Initialize a configuration file in your project: ```bash freebsd-up init ``` This creates a `vmconfig.toml` file with default settings. Example configuration: ```toml [vm] iso = "https://download.freebsd.org/releases/amd64/amd64/ISO-IMAGES/14.3/FreeBSD-14.3-RELEASE-amd64-disc1.iso" cpu = "host" cpus = 2 memory = "2G" image = "./freebsd-disk.qcow2" disk_format = "qcow2" size = "20G" [network] bridge = "br0" port_forward = "8080:80,2222:22" [options] detach = false ``` Command-line options will override configuration file settings, allowing you to customize VMs on a per-run basis while maintaining defaults in the config file. Specify custom CPU type, core count, memory allocation, persistent storage, networking, and port forwarding: ```bash # Custom CPU and memory freebsd-up --cpu host --memory 4G 14.3-RELEASE # Specify number of CPU cores freebsd-up --cpus 4 --memory 8G 15.0-BETA3 # Attach a disk image for persistent storage freebsd-up --image ./freebsd-disk.img --disk-format qcow2 14.3-RELEASE # Create disk image with specific size freebsd-up --image ./freebsd-disk.qcow2 --disk-format qcow2 --size 50G 14.3-RELEASE # Use bridge networking (requires sudo) freebsd-up --bridge br0 14.3-RELEASE # Configure port forwarding for specific services freebsd-up --port-forward 8080:80,2222:22 14.3-RELEASE # Run VM in background (detached mode) freebsd-up --detach 14.3-RELEASE # Persist changes to disk (install mode) freebsd-up --install 14.3-RELEASE # Attach a volume to the VM freebsd-up --volume my-data 14.3-RELEASE # Download to specific location freebsd-up --output ./downloads/freebsd.iso 15.0-BETA3 # Combine all options freebsd-up --cpu qemu64 --cpus 2 --memory 1G --image ./my-disk.qcow2 --disk-format qcow2 --size 30G --bridge br0 --port-forward 8080:80,2222:22 --detach --volume my-data --install --output ./my-freebsd.iso ``` ### Get Help ```bash freebsd-up --help # or freebsd-up -h ``` ### Alternative Execution Methods If you haven't installed via deno install, you can run it directly with Deno: ```bash deno run --allow-run --allow-read --allow-env -g -r -f main.ts -n freebsd-up ``` ## 🔧 Command Line Options FreeBSD-Up supports several command-line options for customization: ### VM Configuration Options - `-c, --cpu ` - CPU type to emulate (default: `host`) - `-C, --cpus ` - Number of CPU cores (default: `2`) - `-m, --memory ` - Amount of memory for the VM (default: `2G`) - `-i, --image ` - Path to VM disk image for persistent storage - `--disk-format ` - Disk image format: qcow2, raw, etc. (default: `raw`) - `-s, --size ` - Size of disk image to create if it doesn't exist (default: `20G`) ### Network Options ### Network Options - `-b, --bridge ` - Name of the network bridge to use (e.g., br0) - `-p, --port-forward ` - Port forwarding rules in the format hostPort:guestPort (comma-separated for multiple) ### Storage Options - `-v, --volume ` - Name of the volume to attach to the VM (will be created if it doesn't exist) ### Execution Options - `-d, --detach` - Run VM in the background and print VM name - `--install` - Persist changes to the VM disk image ### File Options - `-o, --output ` - Output path for downloaded ISO files ### Management Commands - `init` - Initialize a VM configuration file (`vmconfig.toml`) in the current directory - `ps [--all]` - List running VMs (use --all to include stopped VMs) - `start [--detach] [-v, --volume ]` - Start a specific VM by name (optionally in background, optionally attach a volume) - `stop ` - Stop a specific VM by name - `restart ` - Restart a specific VM by name - `inspect ` - Show detailed information about a VM - `logs [--follow]` - View VM logs (optionally follow in real-time) - `rm ` - Remove a VM and its configuration from the database - `run [options]` - Create and run a VM from an OCI registry image - `images` - List all VM disk images - `tag ` - Tag a VM disk image for pushing to a registry - `rmi ` - Remove a VM disk image - `login -u -p ` - Login to an OCI registry - `logout ` - Logout from an OCI registry - `pull ` - Pull a VM disk image from an OCI registry - `push ` - Push a VM disk image to an OCI registry - `volumes` - List all volumes - `volume rm ` - Remove a volume - `volume inspect ` - Inspect a volume - `serve [--port ]` - Start the HTTP API server (default port: 8890) ### Help Options - `-h, --help` - Show help information - `-V, --version` - Show version information ### Examples ```bash # Use different CPU type freebsd-up --cpu qemu64 14.3-RELEASE # Allocate more memory freebsd-up --memory 4G 15.0-BETA3 # Use more CPU cores freebsd-up --cpus 4 14.3-RELEASE # Attach a persistent disk image freebsd-up --image ./freebsd-storage.qcow2 --disk-format qcow2 14.3-RELEASE # Create a larger disk image automatically freebsd-up --image ./freebsd-big.qcow2 --disk-format qcow2 --size 100G 14.3-RELEASE # Use bridge networking for better network performance freebsd-up --bridge br0 14.3-RELEASE # Configure port forwarding for web and SSH access freebsd-up --port-forward 8080:80,2222:22 14.3-RELEASE # Run VM in background mode freebsd-up --detach 14.3-RELEASE # Persist changes to disk (install mode) freebsd-up --install 14.3-RELEASE # Attach a volume to the VM freebsd-up --volume my-data 14.3-RELEASE # Save ISO to specific location freebsd-up --output ./isos/freebsd.iso https://example.com/freebsd.iso # Combine multiple options with bridge networking, port forwarding, persistent storage, and volumes freebsd-up --cpu host --cpus 4 --memory 8G --image ./vm-disk.qcow2 --disk-format qcow2 --size 50G --bridge br0 --port-forward 8080:80,2222:22 --detach --volume my-data --install --output ./downloads/ 14.3-RELEASE # List all VMs (including stopped ones) freebsd-up ps --all # Start a previously created VM freebsd-up start my-freebsd-vm # Start a VM in background mode with volume freebsd-up start my-freebsd-vm --detach --volume my-data # Stop a running VM freebsd-up stop my-freebsd-vm # Restart a VM freebsd-up restart my-freebsd-vm # Get detailed information about a VM freebsd-up inspect my-freebsd-vm # View VM logs freebsd-up logs my-freebsd-vm # Follow VM logs in real-time freebsd-up logs my-freebsd-vm --follow # Remove a VM freebsd-up rm my-freebsd-vm # Run a VM from an OCI registry image freebsd-up run ghcr.io/tsirysndr/freebsd:15.0-BETA4 # List all volumes freebsd-up volumes # Remove a volume freebsd-up volume rm my-volume # Inspect a volume freebsd-up volume inspect my-volume # Start the HTTP API server freebsd-up serve # Start API server on custom port freebsd-up serve --port 9000 ``` ## 🖥️ Console Setup When FreeBSD boots, you'll see the boot menu. For the best experience with the serial console: 1. **Select option `3. Escape to loader prompt`** 2. **Configure console output:** ```sh set console="comconsole" boot ``` This enables proper console redirection to your terminal. ## ⚙️ VM Configuration The script creates a VM with the following default specifications: - **CPU**: Host CPU with KVM acceleration (configurable with `--cpu`) - **Memory**: 2GB RAM (configurable with `--memory`) - **Cores**: 2 virtual CPUs (configurable with `--cpus`) - **Storage**: ISO-only by default; optional persistent disk (configurable with `--image`) - **Network**: User mode networking with SSH forwarding (host:2222 → guest:22) or bridge networking with `--bridge` - **Port Forwarding**: Configurable port mappings with `--port-forward` - **Console**: Enhanced serial console via stdio with proper signal handling - **Default Version**: FreeBSD 14.3-RELEASE (when no arguments provided) - **State Management**: Persistent VM state stored in SQLite database - **Auto-naming**: VMs get unique names for easy management - **Background Mode**: Support for detached execution with `--detach` ### Networking Modes FreeBSD-Up supports two networking modes: 1. **User Mode (Default)**: Port forwarding for SSH access (host:2222 → guest:22) 2. **Bridge Mode**: Direct network access via bridge interface (requires `--bridge` and sudo) ### VM State Management All VMs are tracked in a local SQLite database with the following information: - VM name and unique ID - Hardware configuration (CPU, memory, cores) - Network settings (bridge, MAC address) - Storage configuration - Current status (RUNNING, STOPPED) - Process ID (when running) - Creation timestamp ### Available CPU Types Common CPU types you can specify with `--cpu`: - `host` (default) - Use host CPU features for best performance - `qemu64` - Generic 64-bit CPU for maximum compatibility - `Broadwell` - Intel Broadwell CPU - `Skylake-Client` - Intel Skylake CPU - `max` - Enable all supported CPU features ### Available Disk Formats Common disk formats you can specify with `--disk-format`: - `raw` (default) - Raw disk image format for maximum compatibility - `qcow2` - QEMU Copy On Write format with compression and snapshots - `vmdk` - VMware disk format - `vdi` - VirtualBox disk format ## 🔧 Customization ### Modifying VM Settings via Command Line The easiest way to customize VM settings is through command-line options: ```bash # Increase memory to 4GB freebsd-up --memory 4G # Use a different CPU type freebsd-up --cpu qemu64 # Increase CPU cores to 4 freebsd-up --cpus 4 # Add persistent storage freebsd-up --image ./freebsd-data.qcow2 --disk-format qcow2 14.3-RELEASE # Configure port forwarding for web server and SSH freebsd-up --port-forward 8080:80,2222:22 14.3-RELEASE # Run in background mode freebsd-up --detach 14.3-RELEASE # Combine options with persistent storage and port forwarding freebsd-up --cpu host --cpus 4 --memory 8G --image ./vm-storage.qcow2 --disk-format qcow2 --port-forward 8080:80,2222:22 --detach 14.3-RELEASE ``` ### Creating Disk Images Before using the `--image` option, you may need to create a disk image. FreeBSD-Up can automatically create disk images for you: ```bash # Automatically create a 20GB qcow2 disk image (default size) freebsd-up --image ./freebsd-data.qcow2 --disk-format qcow2 14.3-RELEASE # Create a larger 50GB disk image freebsd-up --image ./freebsd-large.qcow2 --disk-format qcow2 --size 50G 14.3-RELEASE # Manually create disk images with qemu-img qemu-img create -f qcow2 freebsd-data.qcow2 20G qemu-img create -f raw freebsd-data.img 10G ``` ### Setting up Bridge Networking For bridge networking, you need to set up a bridge interface first: ```bash # Create a bridge interface (requires root) sudo ip link add br0 type bridge sudo ip link set br0 up # Add your network interface to the bridge sudo ip link set eth0 master br0 # Then use FreeBSD-Up with bridge networking freebsd-up --bridge br0 14.3-RELEASE ``` Note: Bridge networking requires sudo privileges and FreeBSD-Up will automatically create the bridge if it doesn't exist. ### Advanced Customization To modify VM settings beyond command-line options, you can edit the QEMU arguments in the relevant functions in `src/utils.ts` (for VM creation) or `src/subcommands/start.ts` (for VM startup). The main.ts file serves as the CLI entry point with subcommand routing. Key architecture components: - **Modular design**: Core functionality split into separate modules in `src/` - **Database integration**: SQLite database for persistent VM state management (see `src/db.ts`) - **Image management**: OCI registry integration for sharing and distributing VM images (see `src/images.ts`, `src/oras.ts`) - **Volume management**: Persistent volume support for VM storage (see `src/volumes.ts`) - **HTTP API**: RESTful API server for remote VM management (see `src/api/`) - **Configuration files**: TOML-based configuration for declarative VM setups (see `src/config.ts`) - **Effect-based error handling**: Functional error handling and async operations using the Effect library for robust error management - **Subcommand structure**: Dedicated commands for VM lifecycle operations in `src/subcommands/` - **Network management**: Automatic bridge setup and MAC address assignment in `src/network.ts` - **State tracking**: Comprehensive VM state persistence across restarts in `src/state.ts` ### Supported Version Formats The script automatically recognizes and handles these version formats: - `14.3-RELEASE` - Stable releases - `15.0-BETA3` - Beta versions - `13.4-RC1` - Release candidates - Any format matching: `X.Y-RELEASE|BETAX|RCX` To change the default version when no arguments are provided, modify the `DEFAULT_VERSION` constant in `main.ts`. ## 📁 Project Structure ```ini freebsd-up/ ├── main.ts # CLI entry point with Cliffy command routing ├── deno.json # Deno configuration with dependencies ├── deno.lock # Dependency lock file ├── README.md # This file └── src/ # Core functionality modules ├── config.ts # Configuration file parsing and management ├── constants.ts # Configuration constants ├── context.ts # Application context and database setup ├── db.ts # Database schema and migrations ├── images.ts # Image management functions ├── migrations.ts # Database migration utilities ├── network.ts # Network bridge management ├── oras.ts # OCI registry operations via ORAS ├── state.ts # VM state management functions ├── types.ts # TypeScript type definitions ├── utils.ts # Core VM utilities and QEMU interface ├── volumes.ts # Volume management functions ├── api/ # HTTP API server │ ├── images.ts # Image management API endpoints │ ├── machines.ts # VM management API endpoints │ ├── volumes.ts # Volume management API endpoints │ ├── utils.ts # API utilities and helpers │ └── mod.ts # API server entry point └── subcommands/ # CLI subcommand implementations ├── images.ts # List images command ├── inspect.ts # VM inspection command ├── login.ts # OCI registry login command ├── logout.ts # OCI registry logout command ├── logs.ts # VM logging command ├── ps.ts # VM listing command ├── pull.ts # Pull image from registry command ├── push.ts # Push image to registry command ├── restart.ts # VM restart command ├── rm.ts # VM removal command ├── rmi.ts # Remove image command ├── run.ts # Run VM command ├── serve.ts # HTTP API server command ├── start.ts # VM start command ├── stop.ts # VM stop command ├── tag.ts # Tag image command └── volume.ts # Volume management commands ``` ### Dependencies The project uses the following key dependencies: - **[@paralleldrive/cuid2](https://www.npmjs.com/package/@paralleldrive/cuid2)** - Unique ID generation for VMs - **[@cliffy/command](https://jsr.io/@cliffy/command)** - Modern command-line argument parsing and subcommands - **[@cliffy/flags](https://jsr.io/@cliffy/flags)** - Command-line flag parsing - **[@cliffy/prompt](https://jsr.io/@cliffy/prompt)** - Interactive prompts for CLI - **[@cliffy/table](https://jsr.io/@cliffy/table)** - Formatted table output for VM listings - **[@db/sqlite](https://jsr.io/@db/sqlite)** - SQLite database for VM state persistence - **[@soapbox/kysely-deno-sqlite](https://jsr.io/@soapbox/kysely-deno-sqlite)** - SQLite dialect for Kysely - **[@es-toolkit/es-toolkit](https://jsr.io/@es-toolkit/es-toolkit)** - Modern utility functions (replacing lodash) - **[@std/io](https://jsr.io/@std/io)** - Standard I/O utilities - **[@std/path](https://jsr.io/@std/path)** - Path manipulation utilities - **[@std/toml](https://jsr.io/@std/toml)** - TOML configuration file parsing - **[@zod/zod](https://jsr.io/@zod/zod)** - TypeScript-first schema validation - **[kysely](https://www.npmjs.com/package/kysely)** - Type-safe SQL query builder - **[chalk](https://www.npmjs.com/package/chalk)** - Terminal styling and colors - **[dayjs](https://www.npmjs.com/package/dayjs)** - Date formatting and manipulation - **[effect](https://www.npmjs.com/package/effect)** - Functional effect system for error handling and async operations - **[moniker](https://www.npmjs.com/package/moniker)** - Unique name generation for VMs - **[hono](https://www.npmjs.com/package/hono)** - Fast and lightweight web framework for the HTTP API server ## 🤝 Contributing Contributions are welcome! Feel free to: - Report bugs - Suggest features - Submit pull requests - Improve documentation ## 📝 License This project is licensed under the Mozilla Public License 2.0. See the LICENSE file for details. ## 🔗 Useful Links - [FreeBSD Downloads](https://www.freebsd.org/where/) - [QEMU Documentation](https://www.qemu.org/docs/master/) - [Deno Manual](https://docs.deno.com/runtime/) - [Cliffy Command Documentation](https://cliffy.io/docs@v1.0.0-rc.8/command/) --- > [!NOTE] > > This tool is designed for development and testing purposes. For production > FreeBSD deployments, consider using proper installation methods.