Skip to content

spiralhouse/vagrant-orbstack-provider

Repository files navigation

vagrant-orbstack-provider

A Vagrant provider plugin that enables OrbStack as a backend for managing Linux development environments on macOS.

Gem Version Build Status codecov License

Project Overview

OrbStack is a high-performance alternative to traditional VM solutions on macOS, offering:

  • Sub-3-second startup times
  • Near-zero idle resource consumption
  • Native macOS integration with excellent file sharing
  • First-class support for Apple Silicon and Intel Macs

This provider allows you to leverage OrbStack's performance while maintaining the familiar Vagrant workflow.

Development Status: This provider is under active development. Most features are not yet implemented. See Project Status for details.

Table of Contents

Requirements

System Requirements

  • Operating System: macOS 12 (Monterey) or later
  • Architecture: Apple Silicon (ARM64) or Intel (x86_64)
  • Vagrant: Version 2.2.0 or higher
  • Ruby: Version 2.6 or higher
  • OrbStack: Latest stable version with CLI tools installed

Installation

OrbStack must be installed and running on your system:

  1. Download and install OrbStack
  2. Verify OrbStack CLI is available: orb version

Installation

Install the plugin directly from RubyGems:

vagrant plugin install vagrant-orbstack

Verify the installation:

vagrant plugin list

You should see vagrant-orbstack (0.1.0) in the output.

Quick Start

Create a Vagrantfile in your project directory:

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu"

  config.vm.provider :orbstack do |os|
    os.distro = "ubuntu"
    os.version = "22.04"
  end
end

Basic commands:

# Create and start the machine
vagrant up --provider=orbstack

# Check machine status
vagrant status

# SSH into the machine
vagrant ssh

# Stop the machine
vagrant halt

# Destroy the machine
vagrant destroy

Usage

Creating a Machine

Create and start an OrbStack machine with Vagrant:

vagrant up --provider=orbstack

This will:

  • Create a new OrbStack machine with automatic naming
  • Start the machine immediately
  • Be idempotent (safe to run multiple times—existing machines are not recreated)

Machine Naming

Machines are automatically named using the convention:

  • Format: vagrant-<machine-name>-<short-id>
  • Example: vagrant-default-a3b2c1
  • The short ID ensures uniqueness for multi-machine setups

The machine name can be customized in your Vagrantfile:

Vagrant.configure("2") do |config|
  config.vm.provider :orbstack do |os|
    os.machine_name = "my-dev-env"
  end
end

With this configuration, your machine will be named vagrant-my-dev-env-<short-id>.

Halt and Resume

Stop a running machine:

vagrant halt

Resume a halted machine:

vagrant up  # Resumes existing machine

Check machine status:

vagrant status

Multi-Machine Support

Define multiple machines in your Vagrantfile:

Vagrant.configure("2") do |config|
  config.vm.define "web" do |web|
    web.vm.provider "orbstack" do |orbstack|
      orbstack.distro = "ubuntu"
      orbstack.version = "noble"
    end
  end

  config.vm.define "db" do |db|
    db.vm.provider "orbstack" do |orbstack|
      orbstack.distro = "debian"
    end
  end
end

Each machine gets a unique name (e.g., vagrant-web-a3b2c1, vagrant-db-d4e5f6). You can manage them individually:

# Create web machine
vagrant up web --provider=orbstack

# Create db machine
vagrant up db --provider=orbstack

# Check status of all machines
vagrant status

# SSH into web machine
vagrant ssh web

# Halt specific machine
vagrant halt web

SSH Access

The OrbStack provider supports SSH connectivity through OrbStack's built-in SSH proxy architecture.

Basic SSH Usage

Access your machine using standard Vagrant SSH commands:

# Interactive SSH session
vagrant ssh

# With multi-machine setup
vagrant ssh web

Understanding OrbStack's SSH User Model

Important: OrbStack machines use your macOS username (not "vagrant") for SSH connections.

When you SSH into an OrbStack machine, you'll be logged in as your macOS user (e.g., jburbridge), not the traditional vagrant user. This is OrbStack's intentional design and is the correct behavior.

Example:

vagrant ssh
# You are now: jburbridge@vagrant-default-a3b2c1

whoami
# Output: jburbridge (your macOS username)

Why This Works

OrbStack uses an SSH proxy architecture:

  1. SSH Proxy: OrbStack provides an SSH proxy at localhost:32222
  2. Machine ID Routing: The proxy uses the machine ID for routing to the correct VM
  3. Automatic Authentication: OrbStack manages SSH keys automatically at ~/.orbstack/ssh/id_ed25519
  4. User Mapping: The proxy maps connections to your macOS username inside the VM

This design provides:

  • Seamless authentication (no password required)
  • Automatic SSH key management
  • Secure localhost-only connections
  • Consistent username across macOS and Linux environments

User Permissions

Your macOS user inside the OrbStack VM has:

  • Passwordless sudo access
  • Membership in standard groups (adm, sudo, video, staff, orbstack)
  • Full administrative capabilities

SSH Configuration

You can view the SSH configuration Vagrant generates:

vagrant ssh-config

This shows:

  • Host: 127.0.0.1 (localhost)
  • Port: 32222 (OrbStack SSH proxy)
  • User: <machine-id> (used for routing by the proxy)
  • IdentityFile: ~/.orbstack/ssh/id_ed25519
  • ProxyCommand: OrbStack Helper for connection proxying

Known Limitations

Command Execution (vagrant ssh -c): Currently not supported. Use this workaround:

# Instead of: vagrant ssh -c "whoami"
# Use:
ssh -F <(vagrant ssh-config) default "whoami"

This limitation is tracked in issue SPI-1240.

Manual SSH: You can also connect directly using OrbStack's SSH syntax:

ssh <machine-name>@orb whoami

For more technical details about OrbStack's SSH architecture, see docs/DESIGN.md.

Configuration

The OrbStack provider supports several configuration options to customize your development environment. All configuration is optional—the provider uses sensible defaults following Vagrant's convention-over-configuration philosophy.

Basic Configuration

The minimal Vagrantfile requires no provider-specific configuration:

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu"  # Currently ignored - to be implemented

  config.vm.provider :orbstack do |os|
    # Uses defaults: Ubuntu distribution
  end
end

Configuration Options

Option Type Default Required Description
distro String "ubuntu" No Linux distribution to use
version String nil No Distribution version (e.g., "22.04")
machine_name String nil (auto-generated) No Custom OrbStack machine name

Validation Rules

  • distro: Cannot be empty or blank. The provider validates this at runtime.
  • machine_name: If specified, must contain only alphanumeric characters (a-z, A-Z, 0-9) and hyphens (-). Must start and end with an alphanumeric character. No consecutive hyphens allowed.
    • Valid examples: "my-dev-env", "project-1", "ubuntu-machine"
    • Invalid examples: "-invalid", "invalid-", "invalid--name", "invalid_name"

Configuration Examples

Default Configuration

The simplest configuration uses all defaults:

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu"  # Currently ignored - to be implemented

  config.vm.provider :orbstack do |os|
    # All options use defaults
    # distro: "ubuntu"
    # version: nil
    # machine_name: nil (auto-generated)
  end
end

Specify Distribution and Version

Choose a specific Linux distribution and version:

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu"  # Currently ignored - to be implemented

  config.vm.provider :orbstack do |os|
    os.distro = "ubuntu"
    os.version = "22.04"
  end
end

Custom Machine Name

Provide a custom name for your OrbStack machine:

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu"  # Currently ignored - to be implemented

  config.vm.provider :orbstack do |os|
    os.distro = "ubuntu"
    os.machine_name = "my-dev-machine"
  end
end

Complete Configuration

Specify all available options:

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu"  # Currently ignored - to be implemented

  config.vm.provider :orbstack do |os|
    os.distro = "ubuntu"
    os.version = "22.04"
    os.machine_name = "my-dev-environment"
  end
end

Different Distributions

Examples using various Linux distributions:

# Debian
Vagrant.configure("2") do |config|
  config.vm.box = "debian"  # Currently ignored - to be implemented

  config.vm.provider :orbstack do |os|
    os.distro = "debian"
    os.version = "12"
    os.machine_name = "debian-dev"
  end
end

# Fedora
Vagrant.configure("2") do |config|
  config.vm.box = "fedora"  # Currently ignored - to be implemented

  config.vm.provider :orbstack do |os|
    os.distro = "fedora"
    os.version = "39"
    os.machine_name = "fedora-dev"
  end
end

# Alpine Linux
Vagrant.configure("2") do |config|
  config.vm.box = "alpine"  # Currently ignored - to be implemented

  config.vm.provider :orbstack do |os|
    os.distro = "alpine"
    os.version = "3.19"
    os.machine_name = "alpine-dev"
  end
end

Supported Distributions

The provider supports the following Linux distributions available in OrbStack:

  • Ubuntu (default) - Popular Debian-based distribution
  • Debian - Stable, universal Linux distribution
  • Fedora - Cutting-edge features and latest packages
  • Arch Linux - Rolling release, minimalist distribution
  • Alpine Linux - Lightweight, security-oriented distribution

Note: Distribution availability depends on your OrbStack installation. Refer to the OrbStack documentation for the most current list of supported distributions and versions.

Known Limitations

The following features are not yet supported in v0.1.0:

  • Box Support: Box format is not implemented. You must use distribution-based creation with distro and version configuration.
  • Synced Folders: Shared folders between host and guest are not yet supported.
  • Networking: Configuration is limited to OrbStack defaults. Custom network settings are not available.
  • Command Execution: The vagrant ssh -c "command" syntax is not yet supported. Use the workaround documented in the SSH section.
  • Provisioners: While basic provisioner support exists, not all scenarios have been tested.
  • Platform: macOS-only due to OrbStack platform requirement.

These features are planned for future releases. See CHANGELOG.md for version history and the PRD for the complete roadmap.

Project Status

Implemented

  • Foundation (v0.1.0):

    • Plugin registration and gem structure (SPI-1130)
    • Configuration class with distro, version, machine_name attributes
    • Provider interface foundation
    • Test infrastructure (RSpec)
    • YARD documentation for public APIs
    • RuboCop clean (0 offenses)
  • State Management (v0.2.0-dev):

    • Machine state query implementation (SPI-1199)
    • Provider#state method returns accurate Vagrant::MachineState
    • StateCache utility with 5-second TTL for performance optimization
    • State mapping: OrbStack states (running, stopped) → Vagrant states (:running, :stopped, :not_created)
    • Cache invalidation support (per-key and global)
    • Graceful error handling for CLI failures and timeouts
  • Machine Creation and Naming (v0.2.0-dev):

    • Machine creation via vagrant up --provider=orbstack (SPI-1200)
    • Automatic machine naming with format vagrant-<name>-<short-id>
    • Idempotent operations (safe to run multiple times)
    • Multi-machine support with unique name generation
    • State-aware creation (checks if machine exists before creating)
    • MachineNamer utility for unique name generation
    • Create action middleware implementation
  • Machine Lifecycle Management (v0.2.0-dev):

    • Machine halt via vagrant halt (SPI-1201)
    • Machine resume via vagrant up on stopped machines (SPI-1201)
    • Halt and Start action middleware implementations
    • State cache invalidation for accurate status queries
    • Idempotent halt/start operations (safe to run multiple times)
    • User-friendly progress messages with machine IDs
  • SSH Connectivity (v0.2.0-dev):

    • SSH access via vagrant ssh (SPI-1225)
    • Provider#ssh_info implementation with OrbStack proxy support
    • Automatic SSH key management (~/.orbstack/ssh/id_ed25519)
    • macOS username mapping (OrbStack design)
    • Known limitation: vagrant ssh -c not yet supported (SPI-1240)
  • OrbStack CLI Integration (partial):

    • CLI wrapper with command execution and timeout support
    • Machine listing and info retrieval (SPI-1198)
    • Machine creation and lifecycle methods (SPI-1200)
    • Error handling (CommandTimeoutError, CommandExecutionError, MachineNameCollisionError)
    • Logging infrastructure throughout provider components
  • Test Coverage:

    • 363 passing tests with comprehensive coverage
    • 99.5% test pass rate
    • 100% coverage of implemented features

Planned (MVP - v0.2.0+)

  • Machine destroy operations
  • OrbStack CLI wrapper completion (delete command)
  • Provisioner support (Shell, Ansible, Chef, Puppet)
  • Synced folder configuration
  • Error handling and recovery mechanisms
  • Additional Linux distribution support

For complete roadmap, see docs/PRD.md.

Development

Setup

# Clone and setup
git clone https://github.com/spiralhouse/vagrant-orbstack-provider.git
cd vagrant-orbstack-provider
bundle install

Running Tests

# Run all tests
bundle exec rspec

# Run specific test file
bundle exec rspec spec/vagrant-orbstack/provider_spec.rb

# Run with documentation format
bundle exec rspec --format documentation

Code Quality

# Run RuboCop (linter)
bundle exec rubocop

# Auto-fix offenses
bundle exec rubocop -A

# Generate YARD documentation
yard doc

Local Testing

To test local changes before contributing:

# Build and install gem locally
gem build vagrant-orbstack.gemspec
vagrant plugin install pkg/vagrant-orbstack-0.1.0.gem

# Create test environment
mkdir test-env && cd test-env
cat > Vagrantfile <<EOF
Vagrant.configure("2") do |config|
  config.vm.provider :orbstack do |os|
    os.distro = "ubuntu"
    os.version = "22.04"
  end
end
EOF

# Test your changes
vagrant up --provider=orbstack
vagrant ssh
vagrant halt
vagrant destroy

Documentation

Contributing

This project follows Test-Driven Development (TDD). See CLAUDE.md for our development workflow and docs/TDD.md for TDD guidelines.

Development Workflow

  1. Create feature branch: git checkout -b feat/your-feature
  2. Write tests first (RED phase)
  3. Implement feature (GREEN phase)
  4. Refactor (REFACTOR phase)
  5. Ensure tests pass: bundle exec rspec
  6. Ensure RuboCop passes: bundle exec rubocop
  7. Commit with conventional commits: git commit -m "feat: add feature [SPI-XXX]"
  8. Create pull request

Conventions

  • Follow Ruby community style guide
  • Use 2-space indentation
  • Write YARD documentation for public methods
  • Follow conventional commits format (feat:, fix:, docs:, test:, refactor:, chore:)
  • Reference Linear issues in commits: [SPI-XXX]

Support

License

MIT License - see LICENSE file for details.

Acknowledgments

  • Vagrant - Development environment management
  • OrbStack - High-performance macOS virtualization
  • Vagrant provider implementations for architectural guidance

Changelog

See CHANGELOG.md for version history and release notes.


Made with ❤️ by the Vagrant OrbStack Provider community

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •