How to create a UBOS development VM for Parallels Desktop on Apple Silicon computers

/docs/linux/developer/create-developer-vm/apple-silicon-parallels/

Install Parallels Desktop for Apple Silicon computers

  1. This is a paid product that can be obtained from https://www.parallels.com/products/desktop/.

Obtain an Arch Linux ARM image

  1. Download an ISO with the string “latest” in it from https://release.archboot.com/aarch64/latest/iso/.

Run the Arch Linux ARM image as the virtual machine to create the development VM with

  1. Run Parallels Desktop. If it asks you to install add-on’s, decline. If it asks you to Install Windows, select “Option Options” instead.

  2. In Parallels Desktop, create a new virtual machine:

    • From the menu, select “File / New”.

    • Select “Install Windows, Linux or macOS from an image file”, and “Continue”.

    • Click “select a file” and choose the downloaded ISO.

    • Ignore “Unable to detect operating system” and “Continue”.

    • Select “Other Linux” and “OK”.

    • Enter name: “ubosdev_aarch64-parallels-YYYYMMDD-I” where YYYYMMDD is the date, and I is a number starting with 1.

    • Check “Customize settings before installation”, accept the other defaults, and “Create”.

    • In the “Hardware” tab, enter 8192 MB for “Memory”. (4096 produces a very strange error message later in the boot.) Leave all other defaults.

    • Close the popup and click “Continue”.

  3. The VM automatically starts. Accept all defaults until you get to “Hit ENTER for login routine or CTRL-C for bash prompt”; that will take a 5-10 minutes. Then hit ^C to get the bash shell. (If you find yourself in the Archboot Arch Linux Installation with its blue background: cancel, and select “Exit Program”.)

Install Arch on the empty disk and configure it

  1. Wait for the shell to appear.

  2. Update the bootstrap VM and install some packages we need:

    # pacman -Sy
    # pacman -S archlinux-keyring
    # pacman -Su
    # pacman -S btrfs-progs gptfdisk parted dosfstools arch-install-scripts vi
    
  3. Zero out the first bytes on the disk for extra robustness:

    # dd if=/dev/zero of=/dev/sda bs=1M count=8 conv=notrunc
    
  4. Clear the partition table:

    # sgdisk --clear /dev/sda
    
  5. Create the partitions (UEFI, /boot and /) and change them to the right types.

    # sgdisk --new=1::+1M /dev/sda
    # sgdisk --new=2::+512M /dev/sda
    # sgdisk --new=3:: /dev/sda
    # sgdisk --typecode=1:EF02 /dev/sda
    # sgdisk --typecode=2:EF00 /dev/sda
    
  6. Make sure changes are in effect:

    # sync
    # partprobe /dev/sda
    
  7. Create filesystems for partitions other than the UEFI partition:

    # mkfs.vfat  /dev/sda2
    # mkfs.btrfs /dev/sda3
    
  8. Mount the partitions so we can install:

    # mount /dev/sda3 /mnt
    # mkdir /mnt/boot
    # mount /dev/sda2 /mnt/boot
    
  9. Perform the actual install of the base packages:

    # pacstrap /mnt base
    
  10. Generate the right fstab:

    # genfstab -U -p /mnt >> /mnt/etc/fstab
    
  11. Chroot into your future root disk and finish the installation:

    # arch-chroot /mnt
    
    1. Add the Arch Linux ARM keyring:

      # pacman -S archlinuxarm-keyring
      
    2. Add the UBOS keyring so we can install our own packages:

      # curl -O https://depot.ubosfiles.net/yellow/$(uname -m)/os/ubos-keyring-0.9-2-any.pkg.tar.xz
      # pacman -U ubos-keyring-0.9-2-any.pkg.tar.xz
      # rm ubos-keyring-0.9-2-any.pkg.tar.xz
      
    3. Add the UBOS tools repo:

      # echo '' >> /etc/pacman.conf
      # echo '[ubos-tools-arch]' >> /etc/pacman.conf
      # echo 'Server = https://depot.ubosfiles.net/yellow/$arch/ubos-tools-arch' >> /etc/pacman.conf
      
    4. Install more packages:

      # pacman -Sy
      # pacman -S linux-aarch64 mkinitcpio amd-ucode sudo vim btrfs-progs \
        gdm gnome-console gnome-control-center gnome-session gnome-settings-daemon \
        gnome-shell gnome-keyring nautilus \
        ubos-tools-arch
      

      If asked which alternatives to install, choose the defaults.

    5. Create a ramdisk:

      # mkinitcpio -p linux-aarch64
      
    6. Configure the boot loader:

      # bootctl --path /boot install
      
    7. Install a locale:

      # perl -pi -e 's!#en_US.UTF-8 UTF-8!en_US.UTF-8 UTF-8!' /etc/locale.gen
      # locale-gen
      
    8. Set up networking:

      # echo '[Match]' > /etc/systemd/network/wired.network
      # echo 'Name=en*' >> /etc/systemd/network/wired.network
      # echo '' >> /etc/systemd/network/wired.network
      # echo '[Network]' >> /etc/systemd/network/wired.network
      # echo 'DHCP=ipv4' >> /etc/systemd/network/wired.network
      # echo 'IPv4Forwarding=1' >> /etc/systemd/network/wired.network
      # echo 'IPv6Forwarding=1' >> /etc/systemd/network/wired.network
      
      # systemctl enable systemd-networkd systemd-resolved systemd-timesyncd
      
    9. Create a user with the right permissions and no password:

      # useradd -m ubosdev
      # chmod 755 ~ubosdev
      # passwd -d ubosdev
      # echo ubosdev ALL = NOPASSWD: ALL > /etc/sudoers.d/ubosdev
      # chmod 600 /etc/sudoers.d/ubosdev
      
    10. No root password:

      # passwd -d root
      
    11. Exit from the arch-chroot shell with ^D.

  12. Remainder of networking setup:

    # rm /mnt/etc/resolv.conf
    # ln -s /run/systemd/resolve/stub-resolv.conf /mnt/etc/resolv.conf
    
  13. Configure UEFI:

    • Loader configuration:

      # echo timeout 4 > /mnt/boot/loader/loader.conf
      # echo default arch >> /mnt/boot/loader/loader.conf
      
    • Boot entry configuration:

      # echo title Arch > /mnt/boot/loader/entries/arch.conf
      # echo linux /Image >> /mnt/boot/loader/entries/arch.conf
      # echo initrd /amd-ucode.img >> /mnt/boot/loader/entries/arch.conf
      # echo initrd /initramfs-linux.img >> /mnt/boot/loader/entries/arch.conf
      # echo options root=PARTUUID=$(lsblk -o PARTUUID /dev/sda3 | tail -1 ) rootfstype=btrfs rw cgroup_disable=memory add_efi_memmap >> /mnt/boot/loader/entries/arch.conf
      
  14. Power off the virtual machine:

    # systemctl poweroff
    
  15. Remove the ISO file from the VM:

    • In the Parallels Control Center, select the “ubosdev_aarch64-parallels-YYYYMMDD-I” VM, right-click, and select “Configure…”.
    • In the “Hardware” tab, select CD/DVD.
    • In the “Source” drop-down, select Disconnect.
    • Close the Configuration window.

Remaining configuration

  1. Start the VM again.

  2. At the console, log in as ubosdev. There is no password.

  3. Fix the locale (command won’t run earlier)

    % sudo localectl set-locale LANG=en_US.UTF-8
    
  4. Enable Gnome:

    % sudo systemctl enable gdm
    
  5. Power off the virtual machine:

    % sudo systemctl poweroff
    

Now your virtual machine is in the same state as the pre-configured development VM described in ../setup/.

Create a virtual appliance for distribution

  1. In the Parallels Control Center, right-click on the “ubosdev_aarch64-utm-YYYYMMDD-I” VM and select “Prepare for transfer”.

  2. Click “Continue” and wait for the “Packing” process to finish. The VM now has subtitle “Package” and the gears icon has disappeared.

  3. Right-click on the VM again, and select “Show in Finder”.

  4. Copy the file with a name that also contains the processor architecture, the current date and an index: ubosdev_aarch64-parallels-YYYYMMDD-I.pvmp, e.g. ubosdev_aarch64-parallels-20240405-1.pvmp. (Don’t add a UBOS channel to the name, as this is Arch.)