Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save TyrfingMjolnir/e9f857a73ea605ee6be6c910aad63f69 to your computer and use it in GitHub Desktop.
Save TyrfingMjolnir/e9f857a73ea605ee6be6c910aad63f69 to your computer and use it in GitHub Desktop.
WIP Work in Progress, not yet PoC MacOS X template for SmartOS Bhyve and MacOS X xHyve

MacOS X

Disclaimer it's illegal to run MacOS X virtualize on non-Apple hardware supposedly.

Prior art

... and inspiration: https://gist.github.com/onnet/39f436921db688d9a087f3f11738746b

MacOS X High Sierra

This is how to create a MacOS X ISO image Mojave edition below

Download the image from Apple's AppStore or use any other preferred way; I hear rumours that if you do not have the desired version of MacOS in your Apple account, you may be able to download this using dosdude1's patch application, then follow the "curses" in the code block below:

hdiutil create -o /tmp/Mojave -size 8500m -volname Mojave -layout SPUD -fs HFS+J
hdiutil attach /tmp/Mojave.dmg -noverify -mountpoint /Volumes/Mojave
sudo /Applications/Install\ macOS\ Mojave.app/Contents/Resources/createinstallmedia --volume /Volumes/Mojave --nointeraction
hdiutil detach /volumes/Install\ macOS\ Mojave
hdiutil convert /tmp/Mojave.dmg -format UDTO -o ~/Desktop/Mojave.cdr
mv ~/Desktop/Mojave.cdr ~/Desktop/Mojave.iso

Save the created image on your MacPro anywhere you'd like.

scp ~/Desktop/Mojave.iso /opt/local/artifacts/Mojave.iso

If you are lucky enough to have SmartOS running on your MacPro scp the image you created on your Mac desktop above to your SmartOS global zone:

scp ~/Desktop/Mojave.iso smartnode:/zones/

Virtio driver

Download latest stable Virtio driver ISO from https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/ and save it in the global zone.

# cd /zones
# wget --no-check-certificate https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.185-2/virtio-win-0.1.185.iso

Create a new filesystem to install MacOS X

All virtual machines created from this image will have this size. Choose a size that fits your needs.

# zfs create -V 20G zones/mosx

Install MacOS X Mojave

For the purpose of install only you may be better off with 1 CPU aka -c 1 as shown in the initial paramater for bhyve below

# export MOSX_INSTALL_CD=/zones/Mojave.iso
# export VIRTIO_DRIVER_CD=/zones/virtio-win-0.1.185.iso

# pfexec /usr/sbin/bhyve -c 1 -m 3G -H \
    -l com1,stdio \
    -l bootrom,/usr/share/bhyve/uefi-rom.bin \
    -s 2,ahci-cd,$MOSX_INSTALL_CD \
    -s 3,virtio-blk,/dev/zvol/rdsk/zones/mosx \
    -s 4,ahci-cd,$VIRTIO_DRIVER_CD \
    -s 28,fbuf,vga=off,tcp=0.0.0.0:5900,w=1024,h=768,wait \
    -s 29,xhci,tablet \
    -s 31,lpc \
    mosx

Below serves as a template from forked source.

Bhyve will wait until you connect with VNC to port 5900 of your global zone. After you connect you have a few seconds to press any key to boot from CD.

Select the install now option and answer that you don't have a product key (license). Pick the Windows version you want to create the image for (Windows 10 Pro).

When asked where to install it to, load the Virtio SCSI driver from this location E:\amd64\w10\viostor.inf.

Whenever Windows wants to reboot the bhyve command terminates. Run the same ommand again but don't press any key. These times we want to boot from the hard disk.

Repeat this until Windows starts to ask you questions. Press Ctrl + Shift + F3 to reboot to audit mode (run the same bhyve command again). Audit mode logs you automatically into the Administrator account. (This takes forever, twice, to log you in. Just be patient.) Keep the window from sysprep open, do not click OK as this will reboot out of audit mode.

Run E:\virtio-win-gt-x64.msi and install all the Virtio drivers - or at least the networking one.

Click OK in the window from the sysprep tool and wait for the system to automatically shut down.

Create the image and its imgmanifest

# zfs send zones/mosx | tee /zones/mosx.zvol | digest -a sha1
5989a20371dbb29ab7e04d32f124eccfe5749a4b
# zfs destroy zones/mosx
# /usr/sbin/bhyvectl --destroy --vm=mosx
# ls -l /zones/mosx.zvol
-rw-r--r--   1 root     root     10891713416 Jan 16 14:25 /zones/mosx.zvol

Generate a random GUID with uuidgen(1) and create the mosx.imgmanifest file. Make sure you overwrite the size with the size from the ls -l above, no ls -lAh in this case! This also goes for the digest files -> sha, output from above.

{
    "v": 2,
    "uuid": "47e05f5c-a9c3-4779-b01a-a94d16f3a404",
    "name": "mosx-10.14.6-x86",
    "version": "10.14.6",
    "type": "zvol",
    "os": "mosx",
    "files": [ {
        "sha1": "5989a20371dbb29ab7e04d32f124eccfe5749a4b",
        "size": 10891713416,
        "compression": "none"
    } ]
}

Note that you would use "OS":"windows" if you would like to build a hackintosh style install, however as long as there is UEFI, native should work.

I'm not sure how one would compress an install image the "compression": "none" appears a bit strange to me.

A more automated approach; yet totally unrelated:

cat > /opt/image/my-kvm.dsmanifest << EOF
{
  "uuid": "`uuid -v4`",
  "name": "my-kvm",
  "version": "0.10.12",
  "v": 1,
  "description": "My custom KVM zone.",
  "os": "linux",
  "type": "zvol",
  "published_at": "`date '+%Y-%m-%dT%H:%M:%SZ'`",
  "creator_name": "pagoda-ops",
  "creator_uuid": "28cf9d27-9891-45d9-8af6-0df133c3aca0",
  "vendor_uuid": "5acc1983-1cc2-48ae-9ef0-db3264a6b190",
  "files": [
    {
      "path": "mykvm.zfs.gz",
      "sha1": "`digest -a sha1 /opt/image/mykvm.zfs.gz`",
      "size": `ls -l /opt/image/mykvm.zfs.gz | awk '{print $5}'`,
      "compression": "gzip"
    }
  ],
  "requirements": {
    "networks": [
        {
            "name": "net0",
            "description": "public"
        }
    ],
    "ssh_key": true
  },
  "nic_driver": "virtio",
  "disk_driver": "virtio",
  "cpu_type": "qemu64",
  "image_size": `vmadm get <uuid_of_original_kvm> | json disks.0.size`
}
EOF

Import the image.

# imgadm install -m /zones/mosx.imgmanifest -f /zones/mosx.zvol

We're done, you can now create virtual machines from this image.

Create a MacOS X 'VM'

The vcpus option from bhyve creates that number of CPUs, not cores. You can configure multiple cores and threads with the bhyve_extra_opts option.

The nics options should be adjusted to match your needs. The example works with an external DHCP server to automatically configure networking.

I believe in configuring the guest OS for the OS itself( 8-12 GB estimate ) + app[s]( 2 GB estimate ) + scratch disk( 115 GB ) only. Data will be mounted CIFS, NFS, or otherwise. I'm setting this one up for Affinity Photo only, hence some scratch disk.

{
  "alias": "mosxtest",
  "brand": "bhyve",
  "vcpus": 2,
  "bhyve_extra_opts": "-c sockets=1,cores=4,threads=2",
  "autoboot": false,
  "ram": 262144,
  "bootrom": "uefi",
  "disks": [ {
    "boot": true,
    "model": "virtio",
    "image_uuid": "47e05f5c-a9c3-4779-b01a-a94d16f3a404",
    "image_size": 131072
  } ],
  "nics": [
    {
      "nic_tag": "admin",
      "vlan_id": 133,
      "ip": "dhcp",
      "primary": "true",
      "model": "virtio"
    }
  ]
}

The case for memory is debatable thing I prefer to do productivty apps 32GB, and pixel intens stuff at 256GB, FileMaker will run as low as 4GB, yet it's not pleasant. Actually it claims to run on as low as 2, but then we are reaching for disgusting.

Now we create and start the VM.

# time vmadm create < mosxtest.json
Successfully created VM 3f23f273-f4dc-4cab-bd8d-8aeac66fe79e
# vmadm start 3f23f273-f4dc-4cab-bd8d-8aeac66fe79e
# vmadm info 3f23f273-f4dc-4cab-bd8d-8aeac66fe79e vnc

Connect with VNC and answer the questions.

After complete the install and configured your account[s], enable the remote desktop and enjoy.

You can also make a new image after this install to have quicker deployment down the line. for example a pre installed empty OS with user admin and password admin for the admin account. Only thing required to get a new 'VM' up and running would be to create the zone and change the password.

The obvious benefit of running this in ZFS is the snapshot feature. Not to mention deployment in which means one can have a MacOS X preinstalled in about the time your server loads 5-8GB from one place in ZFS to the other.

If everything worked fine you should have been brought to something like this

# imgadm list
UUID                                  NAME                    VERSION       OS       TYPE          PUB
3dbbdcca-2eab-11e8-b925-23bf77789921  centos-7                20180323      linux    lx-dataset    2018-03-23
54797266-696e-674d-6a6f-6c6e69101406  mosx                    10.14.6       mosx     zvol          2022-01-04
54797266-696e-674d-6a6f-6c6e69101507  mosx                    10.15.7       mosx     zvol          2022-01-05
064508d4-73fa-11ea-84d8-b3f1f91c535e  base-64                 20.1.0        smartos  zone-dataset  2020-04-01
d504c2d2-830d-11ea-9fb5-337396d92f38  base-64-trunk           20200420      smartos  zone-dataset  2020-04-20
ad6f47f2-c691-11ea-a6a5-cf0776f07bb7  base-64                 20.2.0        smartos  zone-dataset  2020-07-15
1d05e788-5409-11eb-b12f-037bd7fee4ee  base-64-lts             20.4.0        smartos  zone-dataset  2021-01-11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment