pyinfra-orbstack


Namepyinfra-orbstack JSON
Version 0.9.0 PyPI version JSON
download
home_pageNone
SummaryPyInfra connector for OrbStack VM and container management
upload_time2025-11-01 18:19:31
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseMIT
keywords automation container infrastructure orbstack pyinfra vm
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # PyInfra OrbStack Connector

[![CI](https://github.com/elazar/pyinfra-orbstack/workflows/CI/badge.svg)](https://github.com/elazar/pyinfra-orbstack/actions)
[![codecov](https://codecov.io/gh/elazar/pyinfra-orbstack/branch/main/graph/badge.svg)](https://codecov.io/gh/elazar/pyinfra-orbstack)
[![PyPI version](https://badge.fury.io/py/pyinfra-orbstack.svg)](https://badge.fury.io/py/pyinfra-orbstack)
[![Python versions](https://img.shields.io/pypi/pyversions/pyinfra-orbstack.svg)](https://pypi.org/project/pyinfra-orbstack/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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[![CI](https://github.com/elazar/pyinfra-orbstack/workflows/CI/badge.svg)](https://github.com/elazar/pyinfra-orbstack/actions)\n[![codecov](https://codecov.io/gh/elazar/pyinfra-orbstack/branch/main/graph/badge.svg)](https://codecov.io/gh/elazar/pyinfra-orbstack)\n[![PyPI version](https://badge.fury.io/py/pyinfra-orbstack.svg)](https://badge.fury.io/py/pyinfra-orbstack)\n[![Python versions](https://img.shields.io/pypi/pyversions/pyinfra-orbstack.svg)](https://pypi.org/project/pyinfra-orbstack/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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"
}
        
Elapsed time: 1.19700s