Skip to content

Add macOS disk resize support#678

Open
balcsida wants to merge 5 commits into
insidegui:mainfrom
balcsida:feat/macos-disk-resize-compact
Open

Add macOS disk resize support#678
balcsida wants to merge 5 commits into
insidegui:mainfrom
balcsida:feat/macos-disk-resize-compact

Conversation

@balcsida

@balcsida balcsida commented May 23, 2026

Copy link
Copy Markdown

What the resize feature does is that when a guest VM starts the next time, before the guest OS boots, VirtualBuddy inspects the guest disk image by temporarily attaching it on the host with hdiutil and reading the partition layout. If it finds an APFS-on-GPT layout, it treats it as a macOS guest disk and checks for locked APFS volumes / FileVault first:

  • If the disk is encrypted, the resize is blocked. I couldn't find a reliable way to resize FileVault-protected APFS offline, even after trying the recovery key in multiple formats. I may revisit this later.
  • If the disk is not encrypted, the disk image is expanded to the requested size. Then diskutil expands the GPT layout and the APFS container to match. If APFS does not pick up the new ceiling on the first pass, which sometimes happens, the resizer applies a small shrink-and-grow nudge to force APFS to recompute the available space.

@balcsida balcsida force-pushed the feat/macos-disk-resize-compact branch 2 times, most recently from f5ac0a5 to 2cfd5fe Compare May 23, 2026 21:28
@balcsida balcsida mentioned this pull request May 23, 2026
@balcsida balcsida force-pushed the feat/macos-disk-resize-compact branch from 2cfd5fe to 5e9a160 Compare May 23, 2026 21:45

@insidegui insidegui left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some comments about the code, mostly just nitpicks.

I couldn't test it yet though, as I couldn't figure out how to access the disk resizing feature. At first I thought the resizing arrow icon was a button, but it's just an indicator, and the ellipsis button that gives access to the disk settings remains disabled for the boot disk, even when it indicates that it's resizable.

Image

Comment thread VirtualCore/Source/Models/Configuration/ConfigurationModels.swift
Comment thread VirtualCore/Source/Models/Configuration/ConfigurationModels.swift
Comment thread VirtualCore/Source/Models/VBVirtualMachine+Metadata.swift Outdated
Comment thread VirtualCore/Source/Virtualization/VMController.swift Outdated
Comment thread VirtualCore/Source/Virtualization/VMController.swift Outdated
Comment thread VirtualUI/Source/VM Configuration/Sections/Storage/ManagedDiskImageEditor.swift Outdated
Comment thread VirtualUI/Source/VM Configuration/Sections/Storage/ManagedDiskImageEditor.swift Outdated
@balcsida

Copy link
Copy Markdown
Author

Strange, it works for me:

Cap.2026-05-25.at.22.11.41.mp4

@insidegui

Copy link
Copy Markdown
Owner

Strange, it works for me

I think it didn't work for me because that VM had an ASIF boot disk image.

This can be done later, but we should probably move the disk image format option into the managed disk image editor UI, with information about the differences in resizability between the two formats.

Currently that is a global setting in the app:

image

There are significant tradeoffs between the choices, so informing the user about those tradeoffs would help them decide 😄

@insidegui

Copy link
Copy Markdown
Owner

One more nitpick. The resizable indicator should probably use a secondary foreground style. Using the accent color makes it look like a button.

image

@balcsida balcsida requested a review from insidegui May 26, 2026 21:46
@balcsida

Copy link
Copy Markdown
Author

Thanks for the feedback @insidegui !
How does it look now?

@insidegui

Copy link
Copy Markdown
Owner

I think I found a bug.

It's trying to resize every VM I boot up, even if I haven't changed the boot disk size.

In one case, I saw an Expanding Boot to 128 GB (1/1).... message, but 128 GB has always been the size of the disk for that VM. Then after that I get the Unlock FileVault to Finish Resizing message.

I think the checkAndResizeDiskImages method needs to be hardened so that there's no possibility that it will ever attempt to touch any disk image unless the user has explicitly chosen to resize the disk, otherwise this adds an appreciable amount of friction every time the user clicks the button to start a VM.

My suggestion would be to add a flag to the VM metadata indicating that there are disk resizes pending, then bail early in checkAndResizeDiskImages unless that flag is present.

Other than that, I tested resizing a virtual machine using an ASIF disk image from 64GB to 128GB and it worked flawlessly 👌🏻

@balcsida

Copy link
Copy Markdown
Author

Interesting... let me check that

@balcsida balcsida force-pushed the feat/macos-disk-resize-compact branch from 0c2bdc6 to 6b78500 Compare May 28, 2026 17:03
@balcsida

Copy link
Copy Markdown
Author

I was able to fix it and improved the disk resize UX a little bit as well

@balcsida

balcsida commented Jun 6, 2026

Copy link
Copy Markdown
Author

@insidegui sorry to ping you like this, but we are so close

@insidegui

Copy link
Copy Markdown
Owner

Sorry, I'm very busy right now and next week is WWDC, so it will take a while. I haven't forgotten though, so don't worry 😉

@balcsida

balcsida commented Jun 7, 2026

Copy link
Copy Markdown
Author

Right, WWDC is tomorrow! Can't wait!

@balcsida balcsida force-pushed the feat/macos-disk-resize-compact branch from e0aab36 to 461f528 Compare June 30, 2026 13:07
@balcsida

balcsida commented Jul 7, 2026

Copy link
Copy Markdown
Author

@insidegui , maybe now? 🥺

@insidegui

Copy link
Copy Markdown
Owner

After further reviewing the code, I'm once again uncertain about merging this 😔

  • Cost: this is a lot of code that touches several aspects of the app, so even just reviewing it was a lot of work and there are probably issues I didn't catch.
  • Benefit: the feature only works if FileVault is disabled and support level varies depending on disk image format, limiting the number of users who would benefit from it.

I'm ultimately responsible for maintaining every single line of code that gets merged into this project, even if the original contributor promises to do it themselves, so adding this amount of complexity for a feature that I'm not interested in is hard to justify. Having to keep supporting it going forward would mean delaying more important/requested features, and I always hate it when that happens 😅

Since most of the work for disk resizing is done by running command-line tools under the hood, I wonder if we could offer a bunch of shell scripts that power users can run themselves instead of shipping this as a user-facing feature. These could be shipped in the app with instructions for how to run them, or placed in the repository with documentation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@balcsida balcsida force-pushed the feat/macos-disk-resize-compact branch from 461f528 to 5954bf4 Compare July 9, 2026 00:10
@balcsida

balcsida commented Jul 9, 2026

Copy link
Copy Markdown
Author

Thanks for the honest feedback @insidegui, totally fair 🙇

I took one more pass at it and cut it down hard — the diff is now ~650 lines across 9 files (was ~2,200 across 18). The big change: VirtualBuddy now only grows the disk image itself, and the guest claims the space with one command (diskutil apfs resizeContainer disk0s2 0 — the app shows it in an alert after expanding).

That let me delete the part I suspect you'd hate maintaining the most:

  • all the host-side hdiutil attach / diskutil apfs container hunting and retry logic is gone
  • the FileVault limitation is gone with it — claiming space in the guest works even with FileVault on, since you're logged in there
  • no more FileVault probing before resize, so two UI files reverted to main entirely

What's left is basically: hdiutil resize for sparse images, ftruncate + a GPT fixup for raw ones, and a slider in the storage settings.

If this is still more than you want to own, no hard feelings — I'll happily convert it to the shell-script approach you suggested, most of what's left would translate pretty directly. But I figured it was worth one try at a version you can review in one sitting 😅

@insidegui

Copy link
Copy Markdown
Owner

That sounds a lot more manageable 😄

I'm a bit busy this week, but I'll check it out again soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants