简体   繁体   中英

How to install grub on image file WITHOUT root privilege?

I'm doing a project that needs to generate a vm image file which will then be used as qemu bootable disk image. Previously, our product is like an modified linux system and is made into a USB installation drive and then boot and install into an bare metal machine. But now we want to get rid of the hardware and run it in virtual machines, that's why we need an image file.

Instead of using the existing USB drive to install the system in qemu then shutdown the vm and get the image, we were asked to make an out-of-box image file directly, and skip all the booting and installing on real machine or virtual machine but still get a installed image, so that we can just deliver this image and people can load this image as a ready-to-use virtual machine image.

But during all the procedure, I can NOT use any command that requires root privilege! Don't ask why, there's a whole bunch of restrictions to our project, I just can't use root privilege, no sudo, no su, just anything only a regular user can do....

The part I already achieved is using the latest version of mke2fs -d command to populate a tree of folders and files into different partitions of this image file like this

suppose after the image is booted, we have these folder structure

$ ls /
$ bin dev boot  home lib32   mnt  proc  run srv  tmp var  boot  data   etc  lib lib64  opt  root  sbin  sys  usr  

some of the folders are mounted by different partitions

extract a single partition from image

dd if=image of=partitionN skip=offset_of_partition_N count=size_of_partition_N bs=512 conv=sparse

populate a folder into the partition

mke2fs -d root_dir/etc partitionN

put the partition back into image

dd if=partitionN of=image seek=offset_of_partition_N count=size_of_partition_N bs=512 conv=sparse,notrunc

We have the first partition in the image as the boot partition, which contains the 'boot' folder and will be mounted under /boot once it is booted.

And this boot partition is an EFI compatible partition(which actually seems to be a FAT32 format), since our project needs it to be this way.

BUT After get all partitions successfully populated into the image, I can not find a way to install grub for this bootable image. And that's the most damn important step that needed to make this image bootable.

All solutions I found on the web suggest loop mount the image's boot partition, which I can not do because without root privilege I can't loop mount the image.

So does any one have any idea how to do this?

I tried to understand how grub write raw values into mbr, and how to find stage1 and stage2 from the values inside mbr, and how to figure out the sector list at the end of stage2's first sector, but that's so crazy and I eventually failed to get this trick work.

Caveat: This is not a complete solution, however I'll post since nobody else answered.

I have never tried to do this and don't have a couple of hours spare to test it, however The OpenWrt project has standard x64 disk image files including Grub and kernel which you can find here:

https://downloads.openwrt.org/chaos_calmer/15.05.1/x86/64/openwrt-15.05.1-x86-64-combined-ext4.img.gz

Instructions tell you how to convert the images for VMWare, for Qemu it must be similar:

https://wiki.openwrt.org/doc/howto/vmware

The thing is, OpenWrt philosophy has always been that builds shouldn't be done as root, and it generally refuses to build as root, so I think you'll find they have ways of creating EXT4 filesystem images complete with MBR and Grub. I have only tested embedded platforms and never actually built from source for x86, but this is where you should start if you're stuck.

Of course, the OpenWrt disk has only a single partition, I'm unsure how you'd create a virtual disk with a more complex partition table, but perhaps there are some options in the tools used by OpenWrt.

Disclaimer: if facing this problem myself I would attack the problem directly by making a grub2-mbr-image installer myself. It's a true attack on the problem and would make a better answer, and more on topic for this site; however it's more hours of research than I'm willing to put into it for a stackverflow answer.

There's an extra trick here. We can get success/error code back by using a virtual floppy disk. There's no need to ship the floppy disk driver. You can build it as a module and include it only in the cpio image.

If we are willing to forgo the kqemu component and pay the 10x slowdown price, we can start qemu with -hda image.img , -kernel bzImage and -initrd initrd.cpio.gz and it will boot that. You need an X server (which you can provide with Xvnc) but no privileges a normal user doesn't have. Assuming / and /boot are the same, /linuxrc looks like this:

#!/bin/sh
insmod /lib/modules/kernel/floppy.ko
mount /dev/hda1 -t ext2 /mnt
PATH=/bin:/usr/bin:/usr/sbin:/sbin chroot /mnt grub2-install
RESULT=$?
umount /dev/hda1
mount /dev/fda -t fat /mnt
echo -n $RESULT > /mnt/errorcode
umount /mnt
poweroff

And you can get your error code back with mcopy to read the floppy disk image.

If qemu is not available, you can build a i586 compatible kernel and use dosbox-x instead and start the kernel using loadlin.exe . This actually works . If you try it with modern stuff it just dies because stuff demands i686 now; but you can build the grub install tool itself targeting i586 and just use an old kernel to boot to do the install. https://www.vogons.org/viewtopic.php?t=53531

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM