Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
a9efd96
feat(storage): add VBDiskResizer core functionality
balcsida Aug 22, 2025
d7b4567
feat(storage): add resize support to VBManagedDiskImage
balcsida Aug 22, 2025
0cf3496
feat(ui): add resize support to ManagedDiskImageEditor
balcsida Aug 22, 2025
aff5d26
feat(ui): add visual resize indicators and context menu
balcsida Aug 22, 2025
6c62ef1
fix(compilation): resolve build errors for disk resize feature
balcsida Aug 22, 2025
c89733e
fix(storage): use proper pattern matching in canBeResized property
balcsida Aug 22, 2025
d0718f2
feat(resize): integrate disk resize at VM startup
balcsida Aug 22, 2025
4337e75
fix(build): move disk resize methods to existing extension file
balcsida Sep 16, 2025
c9b8d0a
fix(build): resolve remaining compilation errors
balcsida Aug 22, 2025
380d70a
feat(resize): enable VBDiskResizer functionality
balcsida Sep 16, 2025
1f3b8fb
fix(resize): correct VBDiskResizer file handling for RAW images
balcsida Aug 22, 2025
fb4541a
feat(resize): add automatic partition expansion and UI progress indic…
balcsida Aug 22, 2025
ee7b728
fix(build): add resizingDisk case to exhaustive switch statements
balcsida Aug 22, 2025
8fcd764
fix(resize): prioritize main APFS container over ISC
balcsida Aug 22, 2025
df2bcbd
fix(resize): handle Apple_APFS_Recovery partitions blocking expansion
balcsida Aug 22, 2025
575c743
feat(resize): graceful handling of recovery partition constraints
balcsida Aug 22, 2025
99e5865
feat(resize): aggressive recovery partition handling strategy
balcsida Aug 22, 2025
091f213
fix(resize): proper recovery container detection for deletion
balcsida Aug 22, 2025
fc03820
feat(resize): handle SIP-protected recovery partitions gracefully
balcsida Aug 22, 2025
f745bfd
fix(resize): properly detect and resize APFS containers using diskuti…
balcsida Aug 23, 2025
35875b1
fix(resize): optimize disk space usage for raw image resizing
balcsida Aug 23, 2025
524b263
fix(resize): correct device name parsing for APFS container detection
balcsida Aug 23, 2025
fcf379d
feat(resize): add fallback strategies for VM disk APFS containers
balcsida Aug 23, 2025
5b6f85e
fix: resolve compiler warnings for unused variables and unreachable code
balcsida Aug 23, 2025
fc2be1e
fix(ui): remove redundant disk resize alert
balcsida Sep 17, 2025
30b0442
feat(resize): surface detailed disk resize progress
balcsida Sep 17, 2025
f469291
feat(resize): teach disk resizer about locked apfs volumes
balcsida Sep 17, 2025
0375c21
fix(resize): use explicit selection logic for main APFS container
balcsida Dec 2, 2025
6f8b5ae
feat(resize): add FileVault detection before disk resize
balcsida Dec 6, 2025
d63de25
feat(resize): expose FileVault check for managed disk images
balcsida Dec 6, 2025
78d6c94
feat(ui): block disk resize when FileVault is enabled
balcsida Dec 6, 2025
c83d3ae
Apply suggestion from @tonyarnold
balcsida Dec 6, 2025
ee00a6a
Apply suggestion from @tonyarnold
balcsida Dec 6, 2025
a190ebb
chore: restore accidentally modified project files
balcsida Dec 6, 2025
b29258d
fix(build): add VBDiskResizer.swift to VirtualCore target
balcsida Dec 12, 2025
e7964c5
refactor(ui): remove unused @EnvironmentObject from StorageDeviceList…
balcsida Dec 12, 2025
7be4e5b
fix(disk): add guestType parameter to disk resizer
balcsida Dec 30, 2025
0539d9b
fix(disk): pass systemType to disk resizer
balcsida Dec 30, 2025
9960b8c
fix(disk): add guestType parameter to resize methods
balcsida Dec 30, 2025
13025d8
feat(disk): add Linux GPT partition resizing support
balcsida Dec 30, 2025
41bebd2
feat(linux): add Linux guest additions for automatic disk resize
balcsida Dec 30, 2025
27a2c7f
feat(linux): add LVM support to guest additions
balcsida Dec 31, 2025
b08c1de
fix(guest): add systemType check before attaching guest additions
balcsida Dec 31, 2025
c2adf77
feat(linux): add version tracking and autorun script for guest tools
balcsida Dec 31, 2025
55b60a0
feat(linux): add auto-mounting Linux guest tools ISO
balcsida Dec 31, 2025
093c849
fix(build): rename README.md to INSTALL.md to avoid resource conflict
balcsida Dec 31, 2025
f78563f
fix(build): update references from README.md to INSTALL.md
balcsida Dec 31, 2025
c466ac9
fix(build): resolve README.md resource conflict in project file
balcsida Jan 1, 2026
6cbcf88
fix(build): convert LinuxGuestAdditions to folder reference
balcsida Dec 31, 2025
414cd66
feat(linux-guest): add colored output to install scripts
balcsida Dec 31, 2025
69c801e
feat(linux-guest): add visual feedback to growfs script
balcsida Dec 31, 2025
5443ff1
feat(linux-guest): add desktop notification for resize operations
balcsida Dec 31, 2025
5410df0
docs(linux-guest): document desktop notifications and visual improvem…
balcsida Dec 31, 2025
bf9b632
fix(linux-guest): handle LVM resize when partition already at max size
balcsida Jan 1, 2026
dd2903b
fix(linux-guest): handle LUKS-without-LVM filesystem resize
balcsida Jan 1, 2026
a413717
fix(linux-guest): add timeout to notify-send to prevent sudo hang
balcsida Jan 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
307 changes: 307 additions & 0 deletions LinuxGuestAdditions/DESIGN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,307 @@
# Linux Guest Tools - Phase 2 Design

## Overview

This document describes the implementation of auto-mountable Linux guest tools for VirtualBuddy, following the same pattern as VMware Tools, VirtualBox Guest Additions, and Parallels Tools.

## Goals

1. **Zero-copy installation** - User doesn't need to download or transfer files
2. **One-command install** - Single command to install all guest tools
3. **Update detection** - Guest can detect when newer tools are available
4. **Cross-distro support** - Works on Fedora, Ubuntu, Debian, Arch, etc.
5. **Offline operation** - No network required for installation

## Architecture

```
┌─────────────────────────────────────────────────────────────────┐
│ VirtualBuddy Host │
├─────────────────────────────────────────────────────────────────┤
│ LinuxGuestAdditionsDiskImage.swift │
│ ├── Monitors LinuxGuestAdditions/ directory │
│ ├── Generates ISO image on app launch (if needed) │
│ └── Stores ISO in ~/Library/Application Support/VirtualBuddy/ │
├─────────────────────────────────────────────────────────────────┤
│ LinuxVirtualMachineConfigurationHelper.swift │
│ └── Attaches ISO as virtio block device when VM starts │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ Linux Guest VM │
├─────────────────────────────────────────────────────────────────┤
│ /dev/vdX (VirtualBuddy Tools ISO) │
│ └── Mount and run install.sh │
├─────────────────────────────────────────────────────────────────┤
│ Installed Components: │
│ ├── /usr/local/bin/virtualbuddy-growfs │
│ ├── /etc/systemd/system/virtualbuddy-growfs.service │
│ └── /etc/virtualbuddy/version │
└─────────────────────────────────────────────────────────────────┘
```

## Disk Image Format

**ISO 9660 with Joliet extensions** (recommended)
- Universal read support across all Linux distributions
- Read-only by design (prevents accidental modifications)
- Standard pattern used by VMware, VirtualBox, Parallels
- Can be created on macOS using `hdiutil makehybrid`

Volume label: `VBTOOLS`

## ISO Contents

```
VirtualBuddyLinuxTools.iso (VBTOOLS)
├── autorun.sh # Quick-start script
├── install.sh # Full installer (existing)
├── uninstall.sh # Uninstaller (existing)
├── virtualbuddy-growfs # Main resize script (existing)
├── virtualbuddy-growfs.service # systemd service (existing)
├── README.md # Documentation (existing)
├── VERSION # Version string for update detection
└── extras/
└── 99-virtualbuddy.rules # Optional udev rule
```

## Implementation Components

### 1. Host-Side: LinuxGuestAdditionsDiskImage.swift

New file similar to `GuestAdditionsDiskImage.swift`:

```swift
public final class LinuxGuestAdditionsDiskImage: ObservableObject {
public static let current = LinuxGuestAdditionsDiskImage()

// Source directory within VirtualCore bundle
private var embeddedToolsURL: URL {
Bundle.virtualCore.url(forResource: "LinuxGuestAdditions", withExtension: nil)
}

// Destination for generated ISO
public var installedImageURL: URL {
GuestAdditionsDiskImage.imagesRootURL
.appendingPathComponent("VirtualBuddyLinuxTools")
.appendingPathExtension("iso")
}

// Generate ISO using CreateLinuxGuestImage.sh
public func installIfNeeded() async throws { ... }
}
```

### 2. Host-Side: CreateLinuxGuestImage.sh

```bash
#!/bin/sh
# Creates ISO from LinuxGuestAdditions directory

SOURCE_DIR="$1"
DEST_PATH="$2"
VERSION="$3"

# Write version file
echo "$VERSION" > "$SOURCE_DIR/VERSION"

# Create ISO with hdiutil
hdiutil makehybrid \
-iso \
-joliet \
-joliet-volume-name "VBTOOLS" \
-o "$DEST_PATH" \
"$SOURCE_DIR"
```

### 3. Host-Side: LinuxVirtualMachineConfigurationHelper Changes

Add `createAdditionalBlockDevices()` override:

```swift
func createAdditionalBlockDevices() async throws -> [VZVirtioBlockDeviceConfiguration] {
var devices = try storageDeviceContainer.additionalBlockDevices(guestType: .linux)

// Attach Linux guest tools ISO if enabled
if vm.configuration.guestAdditionsEnabled,
let disk = try? VZVirtioBlockDeviceConfiguration.linuxGuestToolsDisk {
devices.append(disk)
}

return devices
}
```

### 4. Guest-Side: autorun.sh

Simple entry point for users:

```bash
#!/bin/bash
# VirtualBuddy Linux Guest Tools - Quick Start
#
# Run this script with: sudo /mnt/autorun.sh
# Or use the full installer: sudo /mnt/install.sh

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

echo "VirtualBuddy Linux Guest Tools"
echo "=============================="
echo ""
echo "This will install:"
echo " - Automatic disk resize on boot (virtualbuddy-growfs)"
echo ""

# Check if already installed and compare versions
if [[ -f /etc/virtualbuddy/version ]]; then
INSTALLED_VERSION=$(cat /etc/virtualbuddy/version)
NEW_VERSION=$(cat "$SCRIPT_DIR/VERSION")

if [[ "$INSTALLED_VERSION" == "$NEW_VERSION" ]]; then
echo "Guest tools v$INSTALLED_VERSION already installed and up to date."
exit 0
else
echo "Updating from v$INSTALLED_VERSION to v$NEW_VERSION..."
fi
fi

# Run the full installer
exec "$SCRIPT_DIR/install.sh"
```

### 5. Guest-Side: Enhanced install.sh

Update existing install.sh to:
1. Create `/etc/virtualbuddy/` directory
2. Write version file after successful install
3. Support `--quiet` flag for non-interactive install

```bash
# Add to install.sh after successful installation:
mkdir -p /etc/virtualbuddy
cp "$SCRIPT_DIR/VERSION" /etc/virtualbuddy/version
```

## User Experience

### First Boot Flow

1. User creates new Linux VM in VirtualBuddy
2. VM boots with install ISO + guest tools ISO attached
3. After OS installation completes, user sees guest tools disk
4. User runs one command:

```bash
# Option 1: If disk is auto-mounted (most distros with desktop)
sudo /run/media/$USER/VBTOOLS/install.sh

# Option 2: Manual mount
sudo mount -L VBTOOLS /mnt
sudo /mnt/install.sh
sudo umount /mnt

# Option 3: One-liner
sudo sh -c 'mkdir -p /mnt/vbtools && mount -L VBTOOLS /mnt/vbtools && /mnt/vbtools/install.sh; umount /mnt/vbtools 2>/dev/null; rmdir /mnt/vbtools 2>/dev/null'
```

### Update Flow

1. User updates VirtualBuddy (new guest tools included)
2. On next VM boot, new ISO is attached
3. User can check for updates:

```bash
# Check if update available
INSTALLED=$(cat /etc/virtualbuddy/version 2>/dev/null || echo "none")
AVAILABLE=$(cat /run/media/$USER/VBTOOLS/VERSION 2>/dev/null || echo "none")
echo "Installed: $INSTALLED, Available: $AVAILABLE"
```

4. Re-run install.sh to update

## Configuration

### VM Settings

Add new configuration option in VBMacConfiguration:

```swift
/// Whether to attach Linux guest tools ISO to Linux VMs.
/// Defaults to true for Linux VMs.
@DecodableDefault.True
public var linuxGuestToolsEnabled = true
```

This is separate from `guestAdditionsEnabled` which controls macOS guest tools.

### UI Integration

Add toggle in VM settings:
- "Attach guest tools disk" (checkbox, default: on)
- Tooltip: "Attaches VirtualBuddy guest tools ISO for easy installation"

## File Locations

### Host (macOS)

| File | Location |
|------|----------|
| Source scripts | `VirtualCore/Resources/LinuxGuestAdditions/` |
| Generated ISO | `~/Library/Application Support/VirtualBuddy/_GuestImage/VirtualBuddyLinuxTools.iso` |
| Version digest | `~/Library/Application Support/VirtualBuddy/_GuestImage/.VirtualBuddyLinuxTools.digest` |

### Guest (Linux)

| File | Location |
|------|----------|
| Resize script | `/usr/local/bin/virtualbuddy-growfs` |
| systemd service | `/etc/systemd/system/virtualbuddy-growfs.service` |
| Version file | `/etc/virtualbuddy/version` |
| Config (future) | `/etc/virtualbuddy/config` |

## Implementation Phases

### Phase 2a: Basic ISO Attachment (MVP)
1. Create `CreateLinuxGuestImage.sh`
2. Create `LinuxGuestAdditionsDiskImage.swift`
3. Modify `LinuxVirtualMachineConfigurationHelper` to attach ISO
4. Update `install.sh` to write version file
5. Add `autorun.sh` convenience script

### Phase 2b: Polish
1. Add UI toggle for guest tools attachment
2. Add version checking in guest
3. Desktop notification on mount (optional udev rule)
4. Update documentation

### Phase 2c: Future Enhancements
1. virtio-vsock communication channel
2. Host-triggered resize signal
3. Clipboard integration (if virtio-clipboard becomes available)
4. Time synchronization helper

## Testing Checklist

- [ ] ISO generates correctly on app launch
- [ ] ISO attaches to Linux VMs
- [ ] ISO does NOT attach to macOS VMs
- [ ] Install works on Fedora (LUKS+LVM+Btrfs)
- [ ] Install works on Ubuntu (ext4)
- [ ] Install works on Debian (ext4/LVM)
- [ ] Version detection works
- [ ] Update flow works
- [ ] Resize works after reboot

## Security Considerations

1. **ISO is read-only** - Prevents tampering from guest
2. **Scripts run as root** - Required for system modifications
3. **No network required** - Reduces attack surface
4. **Version verification** - Ensures tools match host version

## References

- [VirtualBox Guest Additions](https://www.virtualbox.org/manual/ch04.html)
- [VMware Tools](https://docs.vmware.com/en/VMware-Tools/index.html)
- [cloud-init NoCloud](https://cloudinit.readthedocs.io/en/latest/reference/datasources/nocloud.html)
Loading