Botspot / vdesktop

Run a second instance of Raspbian inside Raspbian.
GNU General Public License v3.0
125 stars 21 forks source link

Add an option to execute a script in booted img #9

Closed mtlynch closed 3 years ago

mtlynch commented 4 years ago

I'm interested in a scenario like the following:

sudo ~/vdesktop/vdesktop /home/pi/2019-09-26-raspbian-buster.img --script my-script.sh

Where vdesktop executes my-script.sh in a bash shell in the VM, shuts down, and saves the resulting .img file.

Botspot commented 4 years ago

I see some disadvantages to adding a CLI flag to run a script. First, where is the script located? Is my-script.sh already located on the guest, or does vdesktop have to copy it from host, into guest? How will vdesktop launch my-script.sh within the guest? What if my-script.sh needs a desktop to run? Or for RaspiOS Lite users, what if the desktop doesn't exist? Should vdesktop delete my-script.sh from within the guest when it completes? How will the user specify when in the boot process my-script.sh should launch? Too early, and it fails. In other words: simply adding a single CLI flag won't be flexible enough to suit 100% of use-cases.

Also, I'd consider this flag a niche application, as most vdesktop users want to manually run commands, or interact with the desktop using their mouse, not automatically launch a script on boot.

Here's what I plan to do instead: rearrange the directory structure a bit so that an entire folder is mounted to the guest's root filesystem (/). Vdesktop already does this on a file-by-file basis, most notably profile and shadow, but if it could overlay the entire root filesystem, then you could add in your own files, wherever you wanted to, anywhere. Places including ones that will be autostarted, like /etc/rc.local, /home/pi/.profile, /etc/xdg/lxsession/LXDE-pi/autostart, and others. I've already been experimenting with the idea, but now that there's definitely a good use-case for it, I'll continue development at a much faster rate. I'll keep you updated.

mtlynch commented 4 years ago

The critical thing I'm hoping for is to be able to script it. The blocker with the current implementation is that it requires an interactive user, whereas I'd love to script the whole workflow so that it requires no interactive typing.

Botspot commented 4 years ago

Working on it. Making progress on the overlay mount necessary for this.

mtlynch commented 4 years ago

Awesome, thanks for your continued work on this!

Botspot commented 4 years ago

Okay, this is taking way longer than I expected. In the meantime, here's a stopgap solution:

  1. Using a script, mount your .img.
  2. Copy in the necessary files/scripts you need. For autostart, simply place your script in one of the autostart locations. For example: /etc/rc.local.
  3. Unmount the img.
  4. Boot the img with vdesktop.

Example setup script that does 1-3 automatically: (untested)

#setup
img=$1 #must run this script with the full path to the img file as the first word.
mntpnt=/media/pi/vdesktop

#mount stage
LOOP="$(sudo losetup -fP --show $img)" #create loopback device
sudo mkdir "$mntpnt" 2>/dev/null
sudo mount -o rw "${LOOP}p2" "$mntpnt"
sudo mount -o rw "${LOOP}p1" "${mntpnt}/boot"

#do your file copying here & setup as an autostart. Example below:
cp -a /home/pi/myscript.sh ${mntpnt}/home/pi/myscript.sh
chmod +x ${mntpnt}/home/pi/myscript.sh
echo "/home/pi/myscript.sh" >> "${mntpnt}/etc/profile"

#unmount stage
sudo umount -fl "${mntpnt}/boot" &>/dev/null
sudo umount -fl "$mntpnt" &>/dev/null
sudo losetup -d "$LOOP" &>/dev/null #delete loopback device

And then the vdesktop command would be as follows:

sudo ~/vdesktop/vdesktop /path/to/my.img cli-login

A couple tips:

I'm still working on the merge-mount, but the deeper I get into it, the more complex it's getting. So for now, this should work good enough.

Botspot commented 4 years ago

@mtlynch Any updates? Have you tried the procedure outlined above?

mtlynch commented 4 years ago

Thanks! I think this is pretty close. I adapted your example a little to create this:

https://gist.github.com/mtlynch/1cf6b8145826709ec73f14cd59bef425

I call it like this:

./provision-img.sh /path/to/my.img /path/to/startup-script.sh
sudo ~/vdesktop/vdesktop /path/to/my.img cli-login

It starts executing the script on login, but it runs out of disk space because of this:

[FAILED] Failed to start LSB: Resize the root filesystem to fill partition.
See 'systemctl status resize2fs_once.service' for details.
● resize2fs_once.service - LSB: Resize the root filesystem to fill partition
   Loaded: loaded (/etc/init.d/resize2fs_once; generated)
   Active: failed (Result: exit-code) since Thu 2020-09-03 12:14:32 EDT; 44s ago
     Docs: man:systemd-sysv-generator(8)

Sep 03 12:14:32 raspberrypi systemd[1]: Starting LSB: Resize the root filesystem to fill partition...
Sep 03 12:14:32 raspberrypi resize2fs_once[111]: Starting resize2fs_once:resize2fs 1.44.5 (15-Dec-2018)
Sep 03 12:14:32 raspberrypi resize2fs_once[111]: open: No such file or directory while opening /dev/loop8p2
Sep 03 12:14:32 raspberrypi systemd[1]: resize2fs_once.service: Control process exited, code=exited, status=1/FAILURE
Sep 03 12:14:32 raspberrypi systemd[1]: resize2fs_once.service: Failed with result 'exit-code'.
Sep 03 12:14:32 raspberrypi systemd[1]: Failed to start LSB: Resize the root filesystem to fill partition.

Any idea how we can get the expand filesystem functionality working in the mounted image?

Botspot commented 4 years ago

Thanks! I think this is pretty close. I adapted your example a little to create this:

https://gist.github.com/mtlynch/1cf6b8145826709ec73f14cd59bef425

I call it like this:

./provision-img.sh /path/to/my.img /path/to/startup-script.sh
sudo ~/vdesktop/vdesktop /path/to/my.img cli-login

It starts executing the script on login, but it runs out of disk space because of this: Any idea how we can get the expand filesystem functionality working in the mounted image?

Yes, expanding your image is an easy fix, though the internal systemd service isn't involved. (as in it's meant to fail) Still have Pi-Power-Tools installed? Go to /home/pi/Pi-Power-Tools/functions/shrinkimage. To shrink your image to 0MB free, run this:

/home/pi/Pi-Power-Tools/functions/shrinkimage /path/to/my.img

To add 1GB of free space to the image, run this:

/home/pi/Pi-Power-Tools/functions/shrinkimage /path/to/my.img 1024
mtlynch commented 4 years ago

Thanks! That worked. Although now I'm stuck on #10.

mtlynch commented 4 years ago

Got everything up and running. Thanks!

Feel free to close, as my use-case is addressed, but it'd also be cool to have native support for the script injection.

Botspot commented 4 years ago

Thank you too for the generous donations! I plan to keep this issue open to keep the overlay-mount thing fresh on my mind.

Botspot commented 3 years ago

Update: I've abandoned the overlayfs efforts.

BTW @mtlynch, today I finally figured out how to auto-run a command in the guest - it may or may not be helpful to you. While vdesktop is running, open another terminal and run this:

sudo systemd-run --wait --machine=vdesktop --uid=pi /bin/bash -c '/path/to/my_script
another_script
sudo apt update'
mtlynch commented 3 years ago

Thanks! It unfortunately doesn't work in my scenario because I don't know of a way to coordinate two separate shells to run commands in sync. I could maybe start one script with screen and wait a set number of seconds before running the systemd-run command, but that's pretty brittle.

Botspot commented 3 years ago

@mtlynch I have been working for a while on vdesktop.

Now it's opengl hardware accelerated, there is a bind-mount folder, and it uses environment variables to change settings. This beta version can be found on this forum topic.

mtlynch commented 3 years ago

@Botspot I tried it but it's erroring out because it looks like nspawn hardcodes a /home/pi/vdesktop path specific to your system:

https://gist.github.com/mtlynch/abebb2590ced55e0163e0f41eb2699a5

I'm also noticing the logs mentioning chromium-browser. Is that expected for cli-login mode?

Also, what's the rationale for posting the repo on Google Drive? Would it be possible to do it in a regular Github branch? That way, I could just contribute fixes to you and see clean diffs between the current version and the new version. Github releases also lets you tag releases as "pre-release," and they support simple downloading with wget, which GDrive does not.

Botspot commented 3 years ago

@Botspot I tried it but it's erroring out because it looks like nspawn hardcodes a /home/pi/vdesktop path specific to your system:

https://gist.github.com/mtlynch/abebb2590ced55e0163e0f41eb2699a5

Excellent bug report! Thanks for bringing this to my attention.

I'm also noticing the logs mentioning chromium-browser. Is that expected for cli-login mode?

That is to be expected unless you disable the bind-mount. (rootmount) I created a chromium override file in rootmount that improves chromium performance. You can delete the file if you want to, or leave it there as it doesn't hurt anything.

Also, what's the rationale for posting the repo on Google Drive? Would it be possible to do it in a regular Github branch? That way, I could just contribute fixes to you and see clean diffs between the current version and the new version. Github releases also lets you tag releases as "pre-release," and they support simple downloading with wget, which GDrive does not.

In hindsight, it would have been much better to post it on a beta Github branch, but I had thought it would be in 'beta' status for a couple of days. (I expected lots of eager testers on that thread, and a quick ironing-out process for remaining bugs, but it hasn't worked out that way. Not a single reply to that thread and now the topic is buried.)

mtlynch commented 3 years ago

In hindsight, it would have been much better to post it on a beta Github branch, but I had thought it would be in 'beta' status for a couple of days. (I expected lots of eager testers on that thread, and a quick ironing-out process for remaining bugs, but it hasn't worked out that way. Not a single reply to that thread and now the topic is buried.)

If you're looking for beta testers for new versions, I think there needs to be a channel that lets you reach vdesktop users. I'm eager for new versions, but I never check the RasPi forums, so I never saw that notice. Maybe a mailing list or Google Group?

Botspot commented 3 years ago

Oh, why didn't I think of this before? I could simply change the "message from Botspot" to ask for beta users.

mtlynch commented 3 years ago

You can, but I also wouldn't see that because I run it unattended and don't check the logs unless something breaks.

Botspot commented 3 years ago

Okay. By the way, I've just upgraded vdesktop to a version that's OpenGL hardware accelerated. Now Chromium works.

This probably doesn't interest you, as you're just running an automated script. But I just wanted to give you a heads-up.

Botspot commented 3 years ago

Closed, as I've finally added the bind-mount feature. (and updated the docs)

To autostart your own script, simply copy it into the rootmount/ folder, and add a customized version of an autostarted file to run it. (/etc/rc.local for example)