Recipe: Set up an Arch Linux virtual workstation with UTM on an Apple x86_64
computer
/docs/other/developer-workstation/arch-x86_64/utm/
Install UTM
- Download and install UTM if you have not done so already.
Obtain an Arch Linux x86_64
image
- Download an ISO from a mirror listed on https://archlinux.org/download/
(e.g.
archlinux-2024.03.01-x86_64.iso
)
Warning
Do not use the UTM-provided Arch Linux ARM image. It would run slowly in emulation mode
on an x86_64
computer, and in our experience, has reliability issues.
Run the downloaded Arch Linux VM as the virtual machine to create the development VM with
-
In UTM, create a new virtual machine:
-
Click “Create a New Virtual Machine”.
-
Select “Virtualize” (not “Emulate”).
-
In “Operating System”, select “Linux”.
-
In “Linux”, in the section “Boot ISO Image”, browse to your downloaded ISO file and select that. Leave the options unchecked. Click “Continue”.
-
In “Hardware”, accept the default and click “Continue.”
-
In “Storage”, enter 60GB as the “size of the drive”. Click “Continue”.
-
In “Shared Directory”, click “Continue”.
-
In “Summary”:
-
Change the “Name” to something suitable, such as “ubosdev”.
-
Select “Open VM Settings”
-
Click “Save”.
-
-
In the now-open settings dialog:
-
In the outline on the left, select the second “IDE Drive” (the one whose Image Type is “Disk Image”, not “CD/DVD”) and in the popup you get by clicking right, click “Delete”. The wizard creates a virtual IDE drive, but we want something else.
-
In the outline on the left, section “Drives”, click “New”, and then Interface “VirtIO” and a size suitable for your needs, such as 60GB. Click “Create”.
-
Click “Save”.
-
-
-
Now select your VM in the sidebar, and start it by clicking the run icon (">"). Accept the defaults in the boot loader (or just wait) and wait until the boot sequence ends and the root shell appears.
Install Arch on the empty disk and configure it
-
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
-
Zero out the first bytes on the disk for extra robustness:
# dd if=/dev/zero of=/dev/vda bs=1M count=8 conv=notrunc
-
Clear the partition table:
# sgdisk --clear /dev/vda
-
Create the partitions (UEFI, /boot and /) and change them to the right types:
# sgdisk --new=1::+1M /dev/vda # sgdisk --new=2::+512M /dev/vda # sgdisk --new=3:: /dev/vda # sgdisk --typecode=1:EF02 /dev/vda # sgdisk --typecode=2:EF00 /dev/vda
-
Make sure changes are in effect:
# sync # partprobe /dev/vda
-
Create filesystems for partitions other than the UEFI partition:
# mkfs.vfat /dev/vda2 # mkfs.btrfs /dev/vda3
-
Mount the partitions so we can install:
# mount /dev/vda3 /mnt # mkdir /mnt/boot # mount /dev/vda2 /mnt/boot
-
Perform the actual install:
# pacstrap /mnt base
-
Generate the right
fstab
:# genfstab -U -p /mnt >> /mnt/etc/fstab
-
Chroot into your future root disk and continue the installation:
# arch-chroot /mnt
-
Install more packages:
# pacman -Sy # pacman -S linux grub mkinitcpio sudo vim btrfs-progs spice-vdagent qemu-guest-agent \ gdm gnome-console gnome-control-center gnome-session gnome-settings-daemon \ gnome-shell gnome-keyring nautilus
If asked which alternatives to install, choose the defaults.
-
Check that the auto-generated content of
/etc/pacman.d/mirrorlist
makes sense. Edit accordingly. -
Create a ramdisk:
# mkinitcpio -p linux
-
Configure the UEFI boot loader:
# bootctl --path /boot install
-
Configure grub. This is redundant given we also have a UEFI boot loader, but some people prefer a setup in which to boot from legacy BIOS.
# grub-install --target=i386-pc --boot-directory=/boot --recheck /dev/sda # grub-mkconfig -o /boot/grub/grub.cfg
-
Install a locale:
# perl -pi -e 's!#en_US.UTF-8 UTF-8!en_US.UTF-8 UTF-8!' /etc/locale.gen # locale-gen
-
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 'IPForwarding=1' >> /etc/systemd/network/wired.network # systemctl enable systemd-networkd systemd-resolved systemd-timesyncd
-
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
-
No root password:
# passwd -d root
-
Exit from the
arch-chroot
shell with^D
.
-
-
Remainder of networking setup:
# rm /mnt/etc/resolv.conf # ln -s /run/systemd/resolve/stub-resolv.conf /mnt/etc/resolv.conf
-
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 /vmlinuz-linux >> /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/vda3 | tail -1 ) rw >> /mnt/boot/loader/entries/arch.conf
-
-
Power off the virtual machine:
# systemctl poweroff
-
Select VM “ubosdev” in the outline, and the at the bottom in the right pane, in the CD/DVD popup menu, select “Clear”.
Remaining configuration
-
Start the VM again and wait until the login prompt appears.
-
At the console, log in as
ubosdev
. There is no password. -
Fix the locale (command won’t run earlier)
% sudo localectl set-locale LANG=en_US.UTF-8
-
Enable Gnome:
% sudo systemctl enable gdm
-
Power off the virtual machine:
% sudo systemctl poweroff
Add virtual graphics for the VM
-
In UTM, select the VM, and in the popup, “Edit”.
-
Under “Devices”, click “New…” and “Display”.
-
Click “Save”.