PyInfra connector for OrbStack VM and container management
Project description
PyInfra OrbStack Connector
A PyInfra connector for managing OrbStack VMs and containers with native integration.
Overview
The PyInfra OrbStack Connector provides seamless integration between PyInfra and OrbStack, allowing you to manage VMs and containers using PyInfra's declarative infrastructure automation framework.
Features
- Native PyInfra Integration: Use the
@orbstackconnector for seamless VM management - VM Lifecycle Management: Create, start, stop, restart, clone, rename, and delete VMs
- VM Export/Import: Backup and restore VMs with export/import operations
- Command Execution: Run commands inside VMs with proper user and working directory support
- File Transfer: Upload and download files to/from VMs
- Information Retrieval: Get VM status, IP addresses, and network information
- SSH Configuration: Get SSH connection details and connection strings
- Cross-VM Communication: Test connectivity between VMs
Installation
Prerequisites
- Python 3.9 or higher
- PyInfra 2.0.0 or higher
- OrbStack installed and configured
- uv (recommended) or pip for package management
Install the Connector
# Using uv (recommended)
uv add pyinfra-orbstack
# Using pip
pip install pyinfra-orbstack
Development Installation
git clone https://github.com/elazar/pyinfra-orbstack.git
cd pyinfra-orbstack
# Using uv (recommended)
uv sync --dev
# Using pip
pip install -e ".[dev]"
Quick Start
Basic Usage
# inventory.py
from pyinfra import inventory
# Use @orbstack connector to automatically discover VMs
inventory.add_group("@orbstack", {
"orbstack_vm": True,
})
# deploy.py
from pyinfra import host
from pyinfra.operations import server
from pyinfra_orbstack.operations.vm import vm_info, vm_status
# Operations will automatically use the connector
if host.data.orbstack_vm:
# Get VM information
vm_data = vm_info()
status = vm_status()
print(f"VM Status: {status}")
print(f"VM IP: {vm_data.get('ip4', 'unknown')}")
# Install packages
server.packages(
name="Install nginx",
packages=["nginx"],
)
# Start services
server.service(
name="Start nginx",
service="nginx",
running=True,
)
Manual VM Configuration
# inventory.py
inventory.add_host("@orbstack/my-vm", {
"vm_name": "my-vm",
"vm_image": "ubuntu:22.04",
"vm_arch": "arm64",
})
Operations
VM Lifecycle Operations
from pyinfra_orbstack.operations.vm import (
vm_create, vm_delete, vm_start, vm_stop, vm_restart,
vm_clone, vm_export, vm_import, vm_rename
)
# Create a new VM
vm_create(
name="test-vm",
image="ubuntu:22.04",
arch="arm64",
user="ubuntu",
)
# Start a VM
vm_start("test-vm")
# Clone a VM
vm_clone(
source_name="test-vm",
new_name="test-vm-clone",
)
# Export a VM
vm_export(
name="test-vm",
output_path="/tmp/test-vm-backup.tar.zst",
)
# Import a VM
vm_import(
input_path="/tmp/test-vm-backup.tar.zst",
name="test-vm-restored",
)
# Rename a VM
vm_rename(
old_name="test-vm",
new_name="production-vm",
)
# Stop a VM
vm_stop("test-vm", force=True)
# Restart a VM
vm_restart("test-vm")
# Delete a VM
vm_delete("test-vm", force=True)
VM Information Operations
from pyinfra_orbstack.operations.vm import (
vm_info, vm_list, vm_status, vm_ip, vm_network_info
)
# Get detailed VM information
vm_data = vm_info()
print(f"VM Status: {vm_data.get('record', {}).get('state')}")
# List all VMs
all_vms = vm_list()
for vm in all_vms:
print(f"VM: {vm['name']}, Status: {vm['state']}")
# Get VM status
status = vm_status()
print(f"Current VM Status: {status}")
# Get VM IP address
ip = vm_ip()
print(f"VM IP: {ip}")
# Get network information
network_info = vm_network_info()
print(f"IPv4: {network_info['ip4']}")
print(f"IPv6: {network_info['ip6']}")
SSH Configuration Operations
from pyinfra_orbstack.operations.vm import (
ssh_info, ssh_connect_string
)
# Get SSH connection information
ssh_details = ssh_info("my-vm")
print(f"SSH Details: {ssh_details}")
# Get SSH connection string
conn_str = ssh_connect_string("my-vm")
print(f"Connect with: {conn_str}")
VM Backup and Export
For backing up VMs, use the built-in export/import operations:
from pyinfra_orbstack.operations.vm import vm_export, vm_import, vm_clone
# Quick snapshot (instant)
vm_clone("my-vm", "my-vm-backup")
# Export to file (for sharing or archival)
from datetime import datetime
timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
vm_export("my-vm", f"/backups/my-vm-{timestamp}.tar.zst")
# Restore from export
vm_import("/backups/my-vm-20251028.tar.zst", "my-vm-restored")
For automated backup workflows: Users can easily script around vm_export() if needed.
Configuration Management Operations
from pyinfra_orbstack.operations.vm import (
orbstack_config_get, orbstack_config_set,
orbstack_config_show, vm_username_set
)
# Get global OrbStack configuration
cpu_count = orbstack_config_get("cpu")
print(f"CPU cores allocated to OrbStack: {cpu_count}")
memory_mib = orbstack_config_get("memory_mib")
print(f"Memory allocated to OrbStack: {memory_mib} MiB")
# Show all configuration
all_config = orbstack_config_show()
print(all_config)
# Set global configuration (affects all VMs)
orbstack_config_set("memory_mib", "24576") # Set to 24GB
# Set per-VM username (only per-VM setting available)
vm_username_set("web-server", "nginx")
vm_username_set("db-server", "postgres")
Important Notes about Configuration:
-
Global vs. Per-VM Settings: Most OrbStack settings are global (affect all VMs):
cpu: Total CPU cores allocated to OrbStackmemory_mib: Total memory allocated to OrbStacknetwork.subnet4: Network subnet for all VMs- These are shared resources, not per-VM limits
-
Per-VM Settings: Only
machine.<vm-name>.usernameis per-VM:# This is the ONLY per-VM configuration available vm_username_set("my-vm", "ubuntu")
-
Common Configuration Keys:
cpu- Number of CPU cores (global)memory_mib- Memory in MiB (global)network.subnet4- IPv4 subnetrosetta- Rosetta translation (true/false)docker.expose_ports_to_lan- Expose Docker ports to LANmachines.forward_ports- Enable port forwardingnetwork.https- Enable HTTPS support
-
Effect of Changes: Some configuration changes may require restarting OrbStack to take effect
Logging and Diagnostics Operations
from pyinfra_orbstack.operations.vm import (
vm_logs, vm_status_detailed
)
# Get VM system logs
logs = vm_logs()
print(logs)
# Get detailed logs including debug information
detailed_logs = vm_logs(all_logs=True)
print(detailed_logs)
# Get comprehensive VM status information
status = vm_status_detailed()
print(f"VM State: {status.get('state')}")
print(f"VM IP: {status.get('ip4')}")
print(f"VM Image: {status.get('image')}")
Important Notes about Logging and Diagnostics:
-
VM System Logs:
vm_logs()retrieves OrbStack's unified logs for the VM- These are OrbStack-level logs (VM startup, system errors, OrbStack events)
- NOT logs from services running inside the VM
- Use
all_logs=Truefor detailed debugging information
-
In-VM Logs: To get logs from services inside the VM, use standard PyInfra operations:
from pyinfra.operations import server # Get logs from a service inside the VM server.shell( name="Get nginx logs", commands=["journalctl -u nginx -n 50"], )
-
Status Monitoring:
vm_status_detailed()provides comprehensive information:- Running state (running, stopped, etc.)
- Network configuration (IP addresses)
- Resource information
- Image details
VM Networking Information Operations
from pyinfra_orbstack.operations.vm import (
vm_network_details, vm_test_connectivity, vm_dns_lookup
)
# Get comprehensive network information for current VM
network_info = vm_network_details()
print(f"IPv4: {network_info.get('ip4')}")
print(f"IPv6: {network_info.get('ip6')}")
print(f"Hostname: {network_info.get('hostname')}")
# Test connectivity to another VM using .orb.local domain
# Ping test (default)
connectivity_result = vm_test_connectivity("backend-vm.orb.local")
print(connectivity_result)
# Test with custom ping count
connectivity_result = vm_test_connectivity(
"backend-vm.orb.local", method="ping", count=5
)
# Test HTTP endpoint availability
http_status = vm_test_connectivity(
"http://backend-vm.orb.local:8080", method="curl"
)
print(f"HTTP Status: {http_status}")
# Test specific port connectivity with netcat
port_check = vm_test_connectivity(
"database-vm.orb.local:5432", method="nc"
)
# Perform DNS lookups
# A record (IPv4) - default
ip_address = vm_dns_lookup("backend-vm.orb.local")
print(f"Resolved IP: {ip_address}")
# AAAA record (IPv6)
ipv6_address = vm_dns_lookup("backend-vm.orb.local", lookup_type="AAAA")
# MX record
mx_records = vm_dns_lookup("example.com", lookup_type="MX")
# External DNS lookup
external_ip = vm_dns_lookup("google.com")
Important Notes about Networking Operations:
-
OrbStack .orb.local Domains: VMs automatically get
.orb.localdomain names- Format:
vm-name.orb.local - Enables easy cross-VM communication without IP addresses
- Works for all connectivity tests (ping, curl, nc)
- Format:
-
Connectivity Test Methods:
ping: Basic ICMP connectivity (default, requires ICMP enabled)curl: HTTP/HTTPS endpoint testing (returns HTTP status code)nc(netcat): Port-specific connectivity checks
-
DNS Lookup Types:
A: IPv4 address (default)AAAA: IPv6 addressCNAME: Canonical nameMX: Mail exchange records- Other standard DNS record types supported
-
Cross-VM Communication:
# Example: Test if backend VM is accessible from pyinfra.operations import server from pyinfra_orbstack.operations.vm import vm_test_connectivity # Test basic connectivity vm_test_connectivity("backend.orb.local", method="ping") # Test service availability vm_test_connectivity("http://backend.orb.local:8080", method="curl") # Then configure services using standard PyInfra operations server.shell( name="Configure app to use backend", commands=["echo 'BACKEND_URL=http://backend.orb.local:8080' >> /etc/app.conf"], )
Connector Features
Automatic VM Discovery
The connector automatically discovers all OrbStack VMs and makes them available as PyInfra hosts:
# inventory.py
from pyinfra import inventory
# Automatically discover and add all running OrbStack VMs
inventory.add_group("@orbstack")
# Now you can use them in your deployment
# deploy.py
from pyinfra import host
from pyinfra.operations import server
# This will run on all discovered OrbStack VMs
server.shell(
name="Check hostname",
commands=["hostname"],
)
# Access VM properties
print(f"Deploying to: {host.name}")
print(f"VM IP: {host.data.get('vm_ip', 'unknown')}")
VM Groups
VMs are automatically grouped based on their characteristics:
orbstack: All OrbStack VMsorbstack_running: Running VMs onlyorbstack_arm64: ARM64 architecture VMsorbstack_amd64: AMD64 architecture VMs
Command Execution
Execute commands inside VMs with full PyInfra integration:
from pyinfra.operations import server
# Commands run inside the VM automatically
server.shell(
name="Check system info",
commands=["uname -a", "cat /etc/os-release"],
)
File Transfer
Upload and download files to/from VMs:
from pyinfra.operations import files
# Upload a file to the VM
files.put(
name="Upload config file",
src="local_config.conf",
dest="/etc/myapp/config.conf",
)
# Download a file from the VM
files.get(
name="Download log file",
src="/var/log/myapp.log",
dest="local_log.log",
)
Configuration
VM Configuration
Configure VM properties in your inventory:
# inventory.py
inventory.add_host("@orbstack/my-vm", {
"vm_name": "my-vm",
"vm_image": "ubuntu:22.04",
"vm_arch": "arm64",
"vm_username": "ubuntu",
"ssh_user": "ubuntu",
"ssh_key": "/path/to/ssh/key",
})
SSH Configuration
The connector uses OrbStack's built-in SSH configuration:
- SSH keys are automatically managed by OrbStack
- Default location:
~/.orbstack/ssh/id_ed25519 - SSH connection strings are automatically generated
Examples
Complete VM Setup
# deploy.py
from pyinfra import host
from pyinfra.operations import server, files
from pyinfra_orbstack.operations.vm import vm_create, vm_start
# Create and start a VM
vm_create(
name="web-server",
image="ubuntu:22.04",
arch="arm64",
user="ubuntu",
)
vm_start("web-server")
# Install and configure nginx
server.packages(
name="Install nginx",
packages=["nginx"],
)
files.put(
name="Upload nginx config",
src="nginx.conf",
dest="/etc/nginx/sites-available/default",
)
server.service(
name="Start nginx",
service="nginx",
running=True,
enabled=True,
)
Multi-VM Deployment
# inventory.py
from pyinfra import inventory
# Define multiple VMs
inventory.add_host("@orbstack/web-server", {
"vm_name": "web-server",
"vm_image": "ubuntu:22.04",
})
inventory.add_host("@orbstack/db-server", {
"vm_name": "db-server",
"vm_image": "ubuntu:22.04",
})
# Group them
inventory.add_group("web_servers", ["@orbstack/web-server"])
inventory.add_group("db_servers", ["@orbstack/db-server"])
# deploy.py
from pyinfra import host
from pyinfra.operations import server
# Deploy to web servers
if host in inventory.get_group("web_servers"):
server.packages(
name="Install nginx",
packages=["nginx"],
)
# Deploy to database servers
if host in inventory.get_group("db_servers"):
server.packages(
name="Install PostgreSQL",
packages=["postgresql"],
)
Operation Timing (Optional)
For debugging and performance analysis, enable operation timing:
import logging
from pyinfra_orbstack.timing import timed_operation
# Enable timing logs
logging.basicConfig(level=logging.INFO)
with timed_operation("vm_deployment"):
vm_create(name="web-server", image="ubuntu:22.04")
# ... other operations
See Timing Guide for details.
Development
For detailed development information, standards, and guidelines, see the Documentation Index.
Quick Development Setup
# Install development dependencies
uv sync --dev
# Run tests
uv run pytest
# Format and lint code
uv run black src/ tests/
uv run flake8 src/ tests/
Contributing
We welcome contributions! Please see CONTRIBUTING.md for detailed guidelines on:
- Setting up your development environment
- Code style and conventions
- Testing requirements
- Submitting pull requests
- Documentation standards
For architectural decisions and development history, see the Documentation Index.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
- Issues: GitHub Issues
- Documentation: GitHub README
- PyInfra Documentation: pyinfra.com
Changelog
See CHANGELOG.md for a list of changes and version history.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyinfra_orbstack-0.10.0.tar.gz.
File metadata
- Download URL: pyinfra_orbstack-0.10.0.tar.gz
- Upload date:
- Size: 349.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cc6d5eda020d4508739b74f677a0002ff44292d991f6f976207347e8e27db19e
|
|
| MD5 |
102d2cfe903a6b2bb8022ebc09b1786d
|
|
| BLAKE2b-256 |
e5e8a5f51de46097e9824b606d99ec5c214f693f2e3a1554f266d05c0755283b
|
Provenance
The following attestation bundles were made for pyinfra_orbstack-0.10.0.tar.gz:
Publisher:
publish.yml on elazar/pyinfra-orbstack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyinfra_orbstack-0.10.0.tar.gz -
Subject digest:
cc6d5eda020d4508739b74f677a0002ff44292d991f6f976207347e8e27db19e - Sigstore transparency entry: 661347131
- Sigstore integration time:
-
Permalink:
elazar/pyinfra-orbstack@fff68fa390ce494841c7e2c776e6807fd6367fda -
Branch / Tag:
refs/tags/v0.10.0 - Owner: https://github.com/elazar
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fff68fa390ce494841c7e2c776e6807fd6367fda -
Trigger Event:
release
-
Statement type:
File details
Details for the file pyinfra_orbstack-0.10.0-py3-none-any.whl.
File metadata
- Download URL: pyinfra_orbstack-0.10.0-py3-none-any.whl
- Upload date:
- Size: 20.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aec6ae49a832be94866f1c60eea1b7f08244e780922d5dcea62f03722fc2becd
|
|
| MD5 |
f08c258891b35aea53ad0b53d3b2eff8
|
|
| BLAKE2b-256 |
f48e61454c8fe4c263f3b9de4e5de0d5f40d5926665b09605e75f3b777076739
|
Provenance
The following attestation bundles were made for pyinfra_orbstack-0.10.0-py3-none-any.whl:
Publisher:
publish.yml on elazar/pyinfra-orbstack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyinfra_orbstack-0.10.0-py3-none-any.whl -
Subject digest:
aec6ae49a832be94866f1c60eea1b7f08244e780922d5dcea62f03722fc2becd - Sigstore transparency entry: 661347141
- Sigstore integration time:
-
Permalink:
elazar/pyinfra-orbstack@fff68fa390ce494841c7e2c776e6807fd6367fda -
Branch / Tag:
refs/tags/v0.10.0 - Owner: https://github.com/elazar
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fff68fa390ce494841c7e2c776e6807fd6367fda -
Trigger Event:
release
-
Statement type: