Create A VirtualBox Guest with Grub and XFS

From Alpine Linux
Jump to: navigation, search

How to create a VirtualBox guest image using Alpine Linux, Grub and XFS

The intention of this article is to create a VirtualBox image that has a single combined partition for root, boot and home using the XFS file system. The created image can then be used as a template to clone others.

Separate root and boot partitions for Alpine Linux running as a VirtualBox guest seems to me to be overkill. On low disk space guest you can easily find a boot partition running out of space.

The procedure has been checked for both the standard and vanilla x86_64 version 3.6.1 ISOs.

Create a VirtualBox guest using your typical features but using network bridging, as we’re going to use sshd later. Don’t add any guest additions, such as shared folders, as we are not going to add the VirtualBox guest additions.

Boot the image and log in as root with no password.

Run the setup-alpine script as an easy way of of doing the initial setup, but quit the script with cntrl-C when you reach the hard disk setup options. A DHCP network is fine here.

Add the nano editor, # apk add nano

Edit the openssh configuration,# nano /etc/ssh/sshd_config and set to allow password root access by adding these two lines to the end of the file.

PermitRootLogin yes
PasswordAuthentication yes

Do not reboot! Restart the sshd daemon with, # rc-service sshd restart

Use your sshd client to access the VM image. I use Xshell 5 as I have a Window 10 host, and I use this so I have Copy&Paste available. The rest of this document does assume you have Copy&Paste, but of course you could still continue on the VM’s console but you’d need to type everything manually.

Now add grub, parted and the xfs filesystem, # apk add grub grub-bios parted xfsprogs-extra

Run parted now and it will find /dev/sda. Create a gpt label with the following at the parted prompt, (parted) mklabel gpt

We now create two partitions, the first small partition will be for the grub bios image, and the second the remaining space for Alpine Linux, including the Linux boot directory.

For convenience, we set the size reporting to be MegaBytes with, (parted) unit MB

In the commands shown below, “p” is for a primary, “s” indicates sectors, and 2048 is the first that will not give the alignment error. Ignore the esp for partition 2 as it is an alias for boot.

(parted) mkpart p 2048s 4095s
(parted) mkpart p 4096s 100%
(parted) set 1 bios_grub on  
(parted) set 2 boot on      
(parted) print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 32212MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 
Number  Start   End      Size     File system  Name  Flags
 1      1.05MB  2.10MB   1.05MB                      bios_grub
 2      2.10MB  32211MB  32209MB                     boot, esp

Once we have the partitions we can format the second to XFS and mount it, whereas partition 1 does not need to be formatted.

alpinevc:~# mkfs.xfs /dev/sda2
meta-data=/dev/sda2              isize=512    agcount=4, agsize=1965888 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=0
data     =                       bsize=4096   blocks=7863552, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=3839, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
alpinevc:~# 
alpinevc:~# mount -t xfs /dev/sda2 /mnt
alpinevc:~# df -h
Filesystem                Size      Used Available Use% Mounted on
devtmpfs                 10.0M         0     10.0M   0% /dev
shm                    1002.1M         0   1002.1M   0% /dev/shm
/dev/sr0                 85.0M     85.0M         0 100% /media/cdrom
tmpfs                  1002.1M     44.2M    957.8M   4% /
tmpfs                   200.4M    116.0K    200.3M   0% /run
/dev/loop0               59.8M     59.8M         0 100% /.modloop
cgroup_root              10.0M         0     10.0M   0% /sys/fs/cgroup
/dev/sda2                30.0G     62.8M     29.9G   0% /mnt
alpinevc:~# 

To populate the root partition we use the Alpine script, setup-disk. This will use the packages we have already installed so far. If there are other packages you know you’ll need use apk to install them now, such as #apk add shadow

alpinevc:~# setup-disk -m sys /mnt
Installing system on /dev/sda2:
extlinux: Not a directory: /mnt/boot
100% [##################################################################################################################################]
==> initramfs: creating /boot/initramfs-vanilla
You might need fix the MBR to be able to boot
alpinevc:~# 

A /mnt/boot folder is created containing the vlinuz and initrd images. (Note that the Vanilla Linux is created as vmlinuz, whereas the Hardened Linux is created as vmlinuz-hardened)

alpinevc:~# ls -al /mnt/boot/
total 16396
drwxr-xr-x    2 root     root           203 Jun  7 19:42 .
drwxr-xr-x   19 root     root           200 Jun  7 19:42 ..
-rw-r--r--    1 root     root       2729449 May 31 12:16 System.map
lrwxrwxrwx    1 root     root             1 Jun  7 19:42 boot -> /
-rw-r--r--    1 root     root        165304 May 31 12:16 config
-rw-r--r--    1 root     root           410 Jun  7 19:42 extlinux.conf
-rw-r--r--    1 root     root       9349413 Jun  7 19:42 initramfs-vanilla
-rw-r--r--    1 root     root        181996 Jun  7 19:42 libcom32.c32
-rw-r--r--    1 root     root         23616 Jun  7 19:42 libutil.c32
-rw-r--r--    1 root     root         11712 Jun  7 19:42 mboot.c32
-rw-r--r--    1 root     root         26568 Jun  7 19:42 menu.c32
-rw-r--r--    1 root     root         27020 Jun  7 19:42 vesamenu.c32
-rw-r--r--    1 root     root       4252752 May 31 12:16 vmlinuz
alpinevc:~# 

Use blkid to find the UUID of the /dev/sda2 partition.

alpinevc:~# blkid
/dev/loop0: TYPE="squashfs"
/dev/sda2: UUID="6934943f-c45e-454e-befa-4375e773d4de" TYPE="xfs" 
           PARTUUID="6f290d8a-8ab8-49a7-aad8-4105a74d5588"
/dev/sr0: UUID="2017-06-01-19-22-54-00" LABEL="alpine-vanilla 3.6.1 x86_64" 
          TYPE="iso9660" PTUUID="58b3b8ce" PTTYPE="dos"
/dev/sda1: PARTUUID="7a2967a1-d311-4536-af2a-f0c3b05c0889"

Create /mnt/boot/grub with,

alpinevc:~# mkdir -p /mnt/boot/grub

We can try to generate the grub.cfg with grub-mkconfig as there is no update-grub for Alpine Linux, but it fails.

alpinevc:~# grub-mkconfig -o /mnt/boot/grub/grub.cfg
/usr/sbin/grub-probe: error: failed to get canonical path of `tmpfs'.

Alas, it doesn’t work because grub-mkconfig uses grub-probe and it is looking in the wrong places. Furthermore, the grub-mkconfig helper scripts in /mnt/etc/grub.d are expecting usage on the booted version.

We solve this issue by manually creating a /mnt/boot/grub/grub.cfg, with the following content,

set timeout=10
menuentry "Alpine Linux XFS" {
 insmod part_gpt
 insmod xfs
 set root=(hd0,2)
 linux /boot/vmlinuz root=UUID=6934943f-c45e-454e-befa-4375e773d4de  modules=sd-mod,usb-storage,xfs quiet
 initrd /boot/initramfs-vanilla
}

Change the UUID to your own from blkid, and the root partition is /dev/sda2, so the grub uses root=(hd0,2)

Now load the gpt boot image into the first partition. The error message can be ignored as Alpine Linux does not have a locale.

alpinevc:~# grub-install –root-directory=/mnt  --boot-directory=/mnt/boot /dev/sda
installing for i396-pc platform.
Cannot open directory ‘/usr/share/locale’: No such file or directory.
Installation finished. No errors reported.

This should should now boot. Poweroff the VM and remove the ISO in the cdrom. If you wish you can create a /etc/default/grub and use grub-mkconfig to generate a new /boot/grub/grub.cfg when the VM is running. The file extlinux.conf contains the menu info that will make the Grub menus.


Troubleshooting

If the VM won’t boot at all, you’ll need to add back the ISO, remount the second partition, ensure you created the first partition correctly and ran grub-install.

If you arrive at the grub prompt, the following might help you repair grub.

This will do a directory listing of the root partition, grub> ls (hd0,2)/

Add these commands to boot the VM,

grub> set root=(hd0,2)
grub> linux /boot/vmlinuz root=/dev/sda2
grub> initrd /boot/initramfs-vanilla
grub> boot

If the booting fails at a single user linux prompt, you can manually mount the root partition and continue to the boot with cntl-D.

# mount -t xfs /dev/sda2 /sysroot

Once you have access to the booted image, you can check for mistypings and try again. You will probably need to use grub-mkconfig in this case, to commit your changes.

Try this article for additional information, How to Rescue a Non-Booting Grub2 Linux

Document version: 10th June 2017