Although grub support in libguestfs is currently on hold because of an unfortunate situation, the latest libguestfs now supports SYSLINUX and EXTLINUX, which is (let’s be frank about this) a much simpler and more sane bootloader than grub/grub2.
In fact, you can make a bootable Linux guest real easily now. Here’s a script:
#!/usr/bin/perl # Copyright (C) 2013 Red Hat Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # This ambitious script creates a complete, bootable guest. use strict; use warnings; use Sys::Guestfs; my $disk = "syslinux-guest.img"; # Find prerequisites. my $mbr = "/usr/share/syslinux/mbr.bin"; unless (-f $mbr) { $mbr = "/usr/lib/syslinux/mbr.bin"; unless (-f $mbr) { die "$0: mbr.bin (from SYSLINUX) not found\n"; } } print "mbr: $mbr\n"; my $mbr_data; { local $/ = undef; open MBR, "$mbr" or die "$mbr: $!"; $mbr_data = <MBR>; } die "invalid mbr.bin" unless length ($mbr_data) == 440; my $kernel = `ls -1rv /boot/vmlinuz* | head -1`; chomp $kernel; unless ($kernel) { die "$0: kernel could not be found\n"; } print "kernel: $kernel\n"; print "writing to: $disk ...\n"; # Create the disk. unlink "$disk"; open DISK, ">$disk" or die "$disk: $!"; truncate DISK, 100*1024*1024; close DISK; my $g = Sys::Guestfs->new (); $g->add_drive ($disk, format => "raw"); $g->launch (); unless ($g->feature_available (["syslinux"])) { die "$0: 'syslinux' feature not available in this version of libguestfs\n"; } # Format the disk. $g->part_disk ("/dev/sda", "mbr"); $g->mkfs ("msdos", "/dev/sda1"); $g->mount ("/dev/sda1", "/"); # Install the kernel. $g->upload ($kernel, "/vmlinuz"); # Install the SYSLINUX configuration file. $g->write ("/syslinux.cfg", <<_END); DEFAULT linux LABEL linux SAY Booting the kernel from /vmlinuz KERNEL vmlinuz APPEND ro root=/dev/sda1 _END $g->umount_all (); # Install the bootloader. $g->pwrite_device ("/dev/sda", $mbr_data, 0); $g->syslinux ("/dev/sda1"); $g->part_set_bootable ("/dev/sda", 1, 1); # Finish off. $g->shutdown ();
After running the script, you can try booting the minimal “guest” (note it only contains a kernel, not any userspace):
$ qemu-kvm -hda syslinux-guest.img