# PyInfra OrbStack Connector
[](https://github.com/elazar/pyinfra-orbstack/actions)
[](https://codecov.io/gh/elazar/pyinfra-orbstack)
[](https://badge.fury.io/py/pyinfra-orbstack)
[](https://pypi.org/project/pyinfra-orbstack/)
[](https://opensource.org/licenses/MIT)
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 `@orbstack` connector 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
```bash
# Using uv (recommended)
uv add pyinfra-orbstack
# Using pip
pip install pyinfra-orbstack
```
### Development Installation
```bash
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
```python
# inventory.py
from pyinfra import inventory
# Use @orbstack connector to automatically discover VMs
inventory.add_group("@orbstack", {
"orbstack_vm": True,
})
```
```python
# 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
```python
# inventory.py
inventory.add_host("@orbstack/my-vm", {
"vm_name": "my-vm",
"vm_image": "ubuntu:22.04",
"vm_arch": "arm64",
})
```
## Operations
### VM Lifecycle Operations
```python
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
```python
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
```python
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:
```python
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
```python
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 OrbStack
- `memory_mib`: Total memory allocated to OrbStack
- `network.subnet4`: Network subnet for all VMs
- These are shared resources, not per-VM limits
- **Per-VM Settings**: Only `machine.<vm-name>.username` is per-VM:
```python
# 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 subnet
- `rosetta` - Rosetta translation (true/false)
- `docker.expose_ports_to_lan` - Expose Docker ports to LAN
- `machines.forward_ports` - Enable port forwarding
- `network.https` - Enable HTTPS support
- **Effect of Changes**: Some configuration changes may require restarting OrbStack to take effect
### Logging and Diagnostics Operations
```python
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=True` for detailed debugging information
- **In-VM Logs**: To get logs from services inside the VM, use standard PyInfra operations:
```python
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
```python
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.local` domain names
- Format: `vm-name.orb.local`
- Enables easy cross-VM communication without IP addresses
- Works for all connectivity tests (ping, curl, nc)
- **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 address
- `CNAME`: Canonical name
- `MX`: Mail exchange records
- Other standard DNS record types supported
- **Cross-VM Communication**:
```python
# 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:
```python
# 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
```
```python
# 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 VMs
- `orbstack_running`: Running VMs only
- `orbstack_arm64`: ARM64 architecture VMs
- `orbstack_amd64`: AMD64 architecture VMs
### Command Execution
Execute commands inside VMs with full PyInfra integration:
```python
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:
```python
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:
```python
# 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
```python
# 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
```python
# 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"])
```
```python
# 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:
```python
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](docs/user-guide/timing-guide.md) for details.
## Development
For detailed development information, standards, and guidelines, see the [Documentation Index](docs/README.md).
### Quick Development Setup
```bash
# 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](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](docs/README.md).
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Support
- **Issues**: [GitHub Issues](https://github.com/matttu/pyinfra-orbstack/issues)
- **Documentation**: [GitHub README](https://github.com/matttu/pyinfra-orbstack#readme)
- **PyInfra Documentation**: [pyinfra.com](https://pyinfra.com)
## Changelog
See [CHANGELOG.md](CHANGELOG.md) for a list of changes and version history.
Raw data
{
"_id": null,
"home_page": null,
"name": "pyinfra-orbstack",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": "Matthew Turland <me@matthewturland.com>",
"keywords": "automation, container, infrastructure, orbstack, pyinfra, vm",
"author": null,
"author_email": "Matthew Turland <me@matthewturland.com>",
"download_url": "https://files.pythonhosted.org/packages/44/3b/cb68147e0e5d6e123e8368aa528d0a02696c67827cbfa6bf8ffe46297f89/pyinfra_orbstack-0.9.0.tar.gz",
"platform": null,
"description": "# PyInfra OrbStack Connector\n\n[](https://github.com/elazar/pyinfra-orbstack/actions)\n[](https://codecov.io/gh/elazar/pyinfra-orbstack)\n[](https://badge.fury.io/py/pyinfra-orbstack)\n[](https://pypi.org/project/pyinfra-orbstack/)\n[](https://opensource.org/licenses/MIT)\n\nA PyInfra connector for managing OrbStack VMs and containers with native integration.\n\n## Overview\n\nThe PyInfra OrbStack Connector provides seamless integration between PyInfra\nand OrbStack, allowing you to manage VMs and containers using PyInfra's\ndeclarative infrastructure automation framework.\n\n## Features\n\n- **Native PyInfra Integration**: Use the `@orbstack` connector for seamless VM management\n- **VM Lifecycle Management**: Create, start, stop, restart, clone, rename, and delete VMs\n- **VM Export/Import**: Backup and restore VMs with export/import operations\n- **Command Execution**: Run commands inside VMs with proper user and working directory support\n- **File Transfer**: Upload and download files to/from VMs\n- **Information Retrieval**: Get VM status, IP addresses, and network information\n- **SSH Configuration**: Get SSH connection details and connection strings\n- **Cross-VM Communication**: Test connectivity between VMs\n\n## Installation\n\n### Prerequisites\n\n- Python 3.9 or higher\n- PyInfra 2.0.0 or higher\n- OrbStack installed and configured\n- uv (recommended) or pip for package management\n\n### Install the Connector\n\n```bash\n# Using uv (recommended)\nuv add pyinfra-orbstack\n\n# Using pip\npip install pyinfra-orbstack\n```\n\n### Development Installation\n\n```bash\ngit clone https://github.com/elazar/pyinfra-orbstack.git\ncd pyinfra-orbstack\n\n# Using uv (recommended)\nuv sync --dev\n\n# Using pip\npip install -e \".[dev]\"\n```\n\n## Quick Start\n\n### Basic Usage\n\n```python\n# inventory.py\nfrom pyinfra import inventory\n\n# Use @orbstack connector to automatically discover VMs\ninventory.add_group(\"@orbstack\", {\n \"orbstack_vm\": True,\n})\n```\n\n```python\n# deploy.py\nfrom pyinfra import host\nfrom pyinfra.operations import server\nfrom pyinfra_orbstack.operations.vm import vm_info, vm_status\n\n# Operations will automatically use the connector\nif host.data.orbstack_vm:\n # Get VM information\n vm_data = vm_info()\n status = vm_status()\n\n print(f\"VM Status: {status}\")\n print(f\"VM IP: {vm_data.get('ip4', 'unknown')}\")\n\n # Install packages\n server.packages(\n name=\"Install nginx\",\n packages=[\"nginx\"],\n )\n\n # Start services\n server.service(\n name=\"Start nginx\",\n service=\"nginx\",\n running=True,\n )\n```\n\n### Manual VM Configuration\n\n```python\n# inventory.py\ninventory.add_host(\"@orbstack/my-vm\", {\n \"vm_name\": \"my-vm\",\n \"vm_image\": \"ubuntu:22.04\",\n \"vm_arch\": \"arm64\",\n})\n```\n\n## Operations\n\n### VM Lifecycle Operations\n\n```python\nfrom pyinfra_orbstack.operations.vm import (\n vm_create, vm_delete, vm_start, vm_stop, vm_restart,\n vm_clone, vm_export, vm_import, vm_rename\n)\n\n# Create a new VM\nvm_create(\n name=\"test-vm\",\n image=\"ubuntu:22.04\",\n arch=\"arm64\",\n user=\"ubuntu\",\n)\n\n# Start a VM\nvm_start(\"test-vm\")\n\n# Clone a VM\nvm_clone(\n source_name=\"test-vm\",\n new_name=\"test-vm-clone\",\n)\n\n# Export a VM\nvm_export(\n name=\"test-vm\",\n output_path=\"/tmp/test-vm-backup.tar.zst\",\n)\n\n# Import a VM\nvm_import(\n input_path=\"/tmp/test-vm-backup.tar.zst\",\n name=\"test-vm-restored\",\n)\n\n# Rename a VM\nvm_rename(\n old_name=\"test-vm\",\n new_name=\"production-vm\",\n)\n\n# Stop a VM\nvm_stop(\"test-vm\", force=True)\n\n# Restart a VM\nvm_restart(\"test-vm\")\n\n# Delete a VM\nvm_delete(\"test-vm\", force=True)\n```\n\n### VM Information Operations\n\n```python\nfrom pyinfra_orbstack.operations.vm import (\n vm_info, vm_list, vm_status, vm_ip, vm_network_info\n)\n\n# Get detailed VM information\nvm_data = vm_info()\nprint(f\"VM Status: {vm_data.get('record', {}).get('state')}\")\n\n# List all VMs\nall_vms = vm_list()\nfor vm in all_vms:\n print(f\"VM: {vm['name']}, Status: {vm['state']}\")\n\n# Get VM status\nstatus = vm_status()\nprint(f\"Current VM Status: {status}\")\n\n# Get VM IP address\nip = vm_ip()\nprint(f\"VM IP: {ip}\")\n\n# Get network information\nnetwork_info = vm_network_info()\nprint(f\"IPv4: {network_info['ip4']}\")\nprint(f\"IPv6: {network_info['ip6']}\")\n```\n\n### SSH Configuration Operations\n\n```python\nfrom pyinfra_orbstack.operations.vm import (\n ssh_info, ssh_connect_string\n)\n\n# Get SSH connection information\nssh_details = ssh_info(\"my-vm\")\nprint(f\"SSH Details: {ssh_details}\")\n\n# Get SSH connection string\nconn_str = ssh_connect_string(\"my-vm\")\nprint(f\"Connect with: {conn_str}\")\n```\n\n## VM Backup and Export\n\nFor backing up VMs, use the built-in export/import operations:\n\n```python\nfrom pyinfra_orbstack.operations.vm import vm_export, vm_import, vm_clone\n\n# Quick snapshot (instant)\nvm_clone(\"my-vm\", \"my-vm-backup\")\n\n# Export to file (for sharing or archival)\nfrom datetime import datetime\ntimestamp = datetime.now().strftime(\"%Y%m%d-%H%M%S\")\nvm_export(\"my-vm\", f\"/backups/my-vm-{timestamp}.tar.zst\")\n\n# Restore from export\nvm_import(\"/backups/my-vm-20251028.tar.zst\", \"my-vm-restored\")\n```\n\n**For automated backup workflows:** Users can easily script around `vm_export()` if needed.\n\n### Configuration Management Operations\n\n```python\nfrom pyinfra_orbstack.operations.vm import (\n orbstack_config_get, orbstack_config_set,\n orbstack_config_show, vm_username_set\n)\n\n# Get global OrbStack configuration\ncpu_count = orbstack_config_get(\"cpu\")\nprint(f\"CPU cores allocated to OrbStack: {cpu_count}\")\n\nmemory_mib = orbstack_config_get(\"memory_mib\")\nprint(f\"Memory allocated to OrbStack: {memory_mib} MiB\")\n\n# Show all configuration\nall_config = orbstack_config_show()\nprint(all_config)\n\n# Set global configuration (affects all VMs)\norbstack_config_set(\"memory_mib\", \"24576\") # Set to 24GB\n\n# Set per-VM username (only per-VM setting available)\nvm_username_set(\"web-server\", \"nginx\")\nvm_username_set(\"db-server\", \"postgres\")\n```\n\n**Important Notes about Configuration:**\n\n- **Global vs. Per-VM Settings**: Most OrbStack settings are **global** (affect all VMs):\n - `cpu`: Total CPU cores allocated to OrbStack\n - `memory_mib`: Total memory allocated to OrbStack\n - `network.subnet4`: Network subnet for all VMs\n - These are shared resources, not per-VM limits\n\n- **Per-VM Settings**: Only `machine.<vm-name>.username` is per-VM:\n\n ```python\n # This is the ONLY per-VM configuration available\n vm_username_set(\"my-vm\", \"ubuntu\")\n ```\n\n- **Common Configuration Keys**:\n - `cpu` - Number of CPU cores (global)\n - `memory_mib` - Memory in MiB (global)\n - `network.subnet4` - IPv4 subnet\n - `rosetta` - Rosetta translation (true/false)\n - `docker.expose_ports_to_lan` - Expose Docker ports to LAN\n - `machines.forward_ports` - Enable port forwarding\n - `network.https` - Enable HTTPS support\n\n- **Effect of Changes**: Some configuration changes may require restarting OrbStack to take effect\n\n### Logging and Diagnostics Operations\n\n```python\nfrom pyinfra_orbstack.operations.vm import (\n vm_logs, vm_status_detailed\n)\n\n# Get VM system logs\nlogs = vm_logs()\nprint(logs)\n\n# Get detailed logs including debug information\ndetailed_logs = vm_logs(all_logs=True)\nprint(detailed_logs)\n\n# Get comprehensive VM status information\nstatus = vm_status_detailed()\nprint(f\"VM State: {status.get('state')}\")\nprint(f\"VM IP: {status.get('ip4')}\")\nprint(f\"VM Image: {status.get('image')}\")\n```\n\n**Important Notes about Logging and Diagnostics:**\n\n- **VM System Logs**: `vm_logs()` retrieves OrbStack's unified logs for the VM\n - These are OrbStack-level logs (VM startup, system errors, OrbStack events)\n - NOT logs from services running inside the VM\n - Use `all_logs=True` for detailed debugging information\n\n- **In-VM Logs**: To get logs from services inside the VM, use standard PyInfra operations:\n\n ```python\n from pyinfra.operations import server\n\n # Get logs from a service inside the VM\n server.shell(\n name=\"Get nginx logs\",\n commands=[\"journalctl -u nginx -n 50\"],\n )\n ```\n\n- **Status Monitoring**: `vm_status_detailed()` provides comprehensive information:\n - Running state (running, stopped, etc.)\n - Network configuration (IP addresses)\n - Resource information\n - Image details\n\n### VM Networking Information Operations\n\n```python\nfrom pyinfra_orbstack.operations.vm import (\n vm_network_details, vm_test_connectivity, vm_dns_lookup\n)\n\n# Get comprehensive network information for current VM\nnetwork_info = vm_network_details()\nprint(f\"IPv4: {network_info.get('ip4')}\")\nprint(f\"IPv6: {network_info.get('ip6')}\")\nprint(f\"Hostname: {network_info.get('hostname')}\")\n\n# Test connectivity to another VM using .orb.local domain\n# Ping test (default)\nconnectivity_result = vm_test_connectivity(\"backend-vm.orb.local\")\nprint(connectivity_result)\n\n# Test with custom ping count\nconnectivity_result = vm_test_connectivity(\n \"backend-vm.orb.local\", method=\"ping\", count=5\n)\n\n# Test HTTP endpoint availability\nhttp_status = vm_test_connectivity(\n \"http://backend-vm.orb.local:8080\", method=\"curl\"\n)\nprint(f\"HTTP Status: {http_status}\")\n\n# Test specific port connectivity with netcat\nport_check = vm_test_connectivity(\n \"database-vm.orb.local:5432\", method=\"nc\"\n)\n\n# Perform DNS lookups\n# A record (IPv4) - default\nip_address = vm_dns_lookup(\"backend-vm.orb.local\")\nprint(f\"Resolved IP: {ip_address}\")\n\n# AAAA record (IPv6)\nipv6_address = vm_dns_lookup(\"backend-vm.orb.local\", lookup_type=\"AAAA\")\n\n# MX record\nmx_records = vm_dns_lookup(\"example.com\", lookup_type=\"MX\")\n\n# External DNS lookup\nexternal_ip = vm_dns_lookup(\"google.com\")\n```\n\n**Important Notes about Networking Operations:**\n\n- **OrbStack .orb.local Domains**: VMs automatically get `.orb.local` domain names\n - Format: `vm-name.orb.local`\n - Enables easy cross-VM communication without IP addresses\n - Works for all connectivity tests (ping, curl, nc)\n\n- **Connectivity Test Methods**:\n - `ping`: Basic ICMP connectivity (default, requires ICMP enabled)\n - `curl`: HTTP/HTTPS endpoint testing (returns HTTP status code)\n - `nc` (netcat): Port-specific connectivity checks\n\n- **DNS Lookup Types**:\n - `A`: IPv4 address (default)\n - `AAAA`: IPv6 address\n - `CNAME`: Canonical name\n - `MX`: Mail exchange records\n - Other standard DNS record types supported\n\n- **Cross-VM Communication**:\n\n ```python\n # Example: Test if backend VM is accessible\n from pyinfra.operations import server\n from pyinfra_orbstack.operations.vm import vm_test_connectivity\n\n # Test basic connectivity\n vm_test_connectivity(\"backend.orb.local\", method=\"ping\")\n\n # Test service availability\n vm_test_connectivity(\"http://backend.orb.local:8080\", method=\"curl\")\n\n # Then configure services using standard PyInfra operations\n server.shell(\n name=\"Configure app to use backend\",\n commands=[\"echo 'BACKEND_URL=http://backend.orb.local:8080' >> /etc/app.conf\"],\n )\n ```\n\n## Connector Features\n\n### Automatic VM Discovery\n\nThe connector automatically discovers all OrbStack VMs and makes them available as PyInfra hosts:\n\n```python\n# inventory.py\nfrom pyinfra import inventory\n\n# Automatically discover and add all running OrbStack VMs\ninventory.add_group(\"@orbstack\")\n\n# Now you can use them in your deployment\n```\n\n```python\n# deploy.py\nfrom pyinfra import host\nfrom pyinfra.operations import server\n\n# This will run on all discovered OrbStack VMs\nserver.shell(\n name=\"Check hostname\",\n commands=[\"hostname\"],\n)\n\n# Access VM properties\nprint(f\"Deploying to: {host.name}\")\nprint(f\"VM IP: {host.data.get('vm_ip', 'unknown')}\")\n```\n\n### VM Groups\n\nVMs are automatically grouped based on their characteristics:\n\n- `orbstack`: All OrbStack VMs\n- `orbstack_running`: Running VMs only\n- `orbstack_arm64`: ARM64 architecture VMs\n- `orbstack_amd64`: AMD64 architecture VMs\n\n### Command Execution\n\nExecute commands inside VMs with full PyInfra integration:\n\n```python\nfrom pyinfra.operations import server\n\n# Commands run inside the VM automatically\nserver.shell(\n name=\"Check system info\",\n commands=[\"uname -a\", \"cat /etc/os-release\"],\n)\n```\n\n### File Transfer\n\nUpload and download files to/from VMs:\n\n```python\nfrom pyinfra.operations import files\n\n# Upload a file to the VM\nfiles.put(\n name=\"Upload config file\",\n src=\"local_config.conf\",\n dest=\"/etc/myapp/config.conf\",\n)\n\n# Download a file from the VM\nfiles.get(\n name=\"Download log file\",\n src=\"/var/log/myapp.log\",\n dest=\"local_log.log\",\n)\n```\n\n## Configuration\n\n### VM Configuration\n\nConfigure VM properties in your inventory:\n\n```python\n# inventory.py\ninventory.add_host(\"@orbstack/my-vm\", {\n \"vm_name\": \"my-vm\",\n \"vm_image\": \"ubuntu:22.04\",\n \"vm_arch\": \"arm64\",\n \"vm_username\": \"ubuntu\",\n \"ssh_user\": \"ubuntu\",\n \"ssh_key\": \"/path/to/ssh/key\",\n})\n```\n\n### SSH Configuration\n\nThe connector uses OrbStack's built-in SSH configuration:\n\n- SSH keys are automatically managed by OrbStack\n- Default location: `~/.orbstack/ssh/id_ed25519`\n- SSH connection strings are automatically generated\n\n## Examples\n\n### Complete VM Setup\n\n```python\n# deploy.py\nfrom pyinfra import host\nfrom pyinfra.operations import server, files\nfrom pyinfra_orbstack.operations.vm import vm_create, vm_start\n\n# Create and start a VM\nvm_create(\n name=\"web-server\",\n image=\"ubuntu:22.04\",\n arch=\"arm64\",\n user=\"ubuntu\",\n)\n\nvm_start(\"web-server\")\n\n# Install and configure nginx\nserver.packages(\n name=\"Install nginx\",\n packages=[\"nginx\"],\n)\n\nfiles.put(\n name=\"Upload nginx config\",\n src=\"nginx.conf\",\n dest=\"/etc/nginx/sites-available/default\",\n)\n\nserver.service(\n name=\"Start nginx\",\n service=\"nginx\",\n running=True,\n enabled=True,\n)\n```\n\n### Multi-VM Deployment\n\n```python\n# inventory.py\nfrom pyinfra import inventory\n\n# Define multiple VMs\ninventory.add_host(\"@orbstack/web-server\", {\n \"vm_name\": \"web-server\",\n \"vm_image\": \"ubuntu:22.04\",\n})\n\ninventory.add_host(\"@orbstack/db-server\", {\n \"vm_name\": \"db-server\",\n \"vm_image\": \"ubuntu:22.04\",\n})\n\n# Group them\ninventory.add_group(\"web_servers\", [\"@orbstack/web-server\"])\ninventory.add_group(\"db_servers\", [\"@orbstack/db-server\"])\n```\n\n```python\n# deploy.py\nfrom pyinfra import host\nfrom pyinfra.operations import server\n\n# Deploy to web servers\nif host in inventory.get_group(\"web_servers\"):\n server.packages(\n name=\"Install nginx\",\n packages=[\"nginx\"],\n )\n\n# Deploy to database servers\nif host in inventory.get_group(\"db_servers\"):\n server.packages(\n name=\"Install PostgreSQL\",\n packages=[\"postgresql\"],\n )\n```\n\n## Operation Timing (Optional)\n\nFor debugging and performance analysis, enable operation timing:\n\n```python\nimport logging\nfrom pyinfra_orbstack.timing import timed_operation\n\n# Enable timing logs\nlogging.basicConfig(level=logging.INFO)\n\nwith timed_operation(\"vm_deployment\"):\n vm_create(name=\"web-server\", image=\"ubuntu:22.04\")\n # ... other operations\n```\n\nSee [Timing Guide](docs/user-guide/timing-guide.md) for details.\n\n## Development\n\nFor detailed development information, standards, and guidelines, see the [Documentation Index](docs/README.md).\n\n### Quick Development Setup\n\n```bash\n# Install development dependencies\nuv sync --dev\n\n# Run tests\nuv run pytest\n\n# Format and lint code\nuv run black src/ tests/\nuv run flake8 src/ tests/\n```\n\n## Contributing\n\nWe welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines on:\n\n- Setting up your development environment\n- Code style and conventions\n- Testing requirements\n- Submitting pull requests\n- Documentation standards\n\nFor architectural decisions and development history, see the [Documentation Index](docs/README.md).\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Support\n\n- **Issues**: [GitHub Issues](https://github.com/matttu/pyinfra-orbstack/issues)\n- **Documentation**: [GitHub README](https://github.com/matttu/pyinfra-orbstack#readme)\n- **PyInfra Documentation**: [pyinfra.com](https://pyinfra.com)\n\n## Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for a list of changes and version history.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "PyInfra connector for OrbStack VM and container management",
"version": "0.9.0",
"project_urls": {
"Changelog": "https://github.com/elazar/pyinfra-orbstack/blob/main/CHANGELOG.md",
"Documentation": "https://github.com/elazar/pyinfra-orbstack#readme",
"Homepage": "https://github.com/elazar/pyinfra-orbstack",
"Issues": "https://github.com/elazar/pyinfra-orbstack/issues",
"Repository": "https://github.com/elazar/pyinfra-orbstack"
},
"split_keywords": [
"automation",
" container",
" infrastructure",
" orbstack",
" pyinfra",
" vm"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "4d9f3bec36b16478eb74cebb0c930c70674f1473600e61eadb886fcb6d76fc0a",
"md5": "e987c7d8e0318f6497b477500a7baf9e",
"sha256": "d58bf452322db9f9e86ad01a334edc719d3342c621b0e0e42b84bc308e7c2068"
},
"downloads": -1,
"filename": "pyinfra_orbstack-0.9.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "e987c7d8e0318f6497b477500a7baf9e",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 20003,
"upload_time": "2025-11-01T18:19:30",
"upload_time_iso_8601": "2025-11-01T18:19:30.380746Z",
"url": "https://files.pythonhosted.org/packages/4d/9f/3bec36b16478eb74cebb0c930c70674f1473600e61eadb886fcb6d76fc0a/pyinfra_orbstack-0.9.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "443bcb68147e0e5d6e123e8368aa528d0a02696c67827cbfa6bf8ffe46297f89",
"md5": "1cbcf612f3eb493acac8fcb31582256b",
"sha256": "389f6964d756513f5a47f3dddebfdc150bdcd6fd285ba6c7a6b1c54a7381524d"
},
"downloads": -1,
"filename": "pyinfra_orbstack-0.9.0.tar.gz",
"has_sig": false,
"md5_digest": "1cbcf612f3eb493acac8fcb31582256b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 347603,
"upload_time": "2025-11-01T18:19:31",
"upload_time_iso_8601": "2025-11-01T18:19:31.696320Z",
"url": "https://files.pythonhosted.org/packages/44/3b/cb68147e0e5d6e123e8368aa528d0a02696c67827cbfa6bf8ffe46297f89/pyinfra_orbstack-0.9.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-11-01 18:19:31",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "elazar",
"github_project": "pyinfra-orbstack",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "pyinfra-orbstack"
}