As you remember from the previous posts, our goal was to install three OSes; Raspian, RetroPie, and Openlec, move all root filesystem to a fast USB key and install a script that will magically reboot into an OS of our choice. In this final blog post of the series, I will wrap up the triple-boot Raspberry Pi install by showing how to remotely run a script — located on the Raspberry Pi — from another system.
If you missed Part 1 and Part 2, I suggest clicking the links and following the series in order. Meet me back here to complete this project.
Overview
To accomplish this feat, the following will need to be done.
- Generate SSH Keys (make a passwordless SSH Connection between your desktop and the Raspberry Pi)
- Upload the public key to the user’s home directory (Yes, for each OS)
- Copy the script to the user’s home directory (again, needs to be done for each OS)
- Grant sudo no password permission for the Pi user
I will be using the Mac OS as my desktop for this example. Generating the keys should be similar on Linux and probably quite different on Windows (quite frankly, don’t do it on Windows — find a Linux box or install one via VirtualBox. I’ll leave that to you…
Create SSH Keys
cd ~/ mkdir .ssh chmod go-rwx .ssh cd .ssh ssh-keygen -b 1024 -t rsa -f id_rsa -P "" cd .ssh ; ls -la
You should now see yours SSH keys, the private key is id_rsa and the public key is id_rsa.pub. Important thing to note is that the private key will need to stay where it is.
-rw------- 1 bobby staff 887B Mar 1 11:35 id_rsa -rw-r--r-- 1 bobby staff 239B Mar 1 11:35 id_rsa.pub
Copy SSH Keys
Firstly, copy the contents of id_rsa.pub file to a temporary location. This is a sample.
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC5IBdipImrYb0jm4i9BlSiim7SnkvW/6K6eSHP+OH1o2Aesg82EaLwE8mTayn7ftrAdEi4zc+UMK3APex0STfxZ8VPABvSj0+7H0LX1hCeyGIS+ing8CEKMS70j8ItJV2EUSlDs91K17+/6VI91e5pjVI3CFkI228bb8cmNhuE6w== bobby@desktop.localdomain
With that done, will we need to boot into each OS and copy this public key into a file called authorized_keys in the user’s ~/.ssh directory. Consult the guide below for the login details of each OS (assuming you haven’t change the default passwords).
OS | Username | Default Password |
---|---|---|
Raspbian | pi | raspberry |
RetroPie | pi | raspberry |
OpenELEC | root | openelec |
So login into the first OS, pick Raspbian.
cd ~/.ssh touch authorized_keys nano authorized_keys (Copy contents of id_rsa.pub) cd ~ chmod 700 .ssh chmod 600 .ssh/authorized_keys
Repeat for RetroPie and OpenELEC. Keep in mind that OpenELEC does not have a Pi user, instead uses root and you will have to enable the SSH daemon via the welcome wizard on first boot up of OpenELEC.
You can test whether the keys are working by simply attempting to login via ssh from your desktop. If it doesn’t prompt you for a password, success!
ssh pi@<IP_ADDRESS_OF_RPI>
One more thing, if you have a problem logging into OpenELEC without a password, as I did, do the following from within the OpenELEC SSH shell (after logging in with a password).
chown root:root /storage chmod go-w /storage
Copy Script
If the above works, all that’s left to do is copy the below script to each OS. I chose to simply copy it to the user’s home directory as change_boot.sh.
If you did not follow Step 2 of Part 2 (i.e.: did not move the boot partitions to a smaller SD card) then use this file.
#!/bin/bash DEVICE="/dev/mmcblk0p3" MOUNT_POINT="/tmp/noobs" NOOBS_CONF="noobs.conf" SUDO='' if [ "$#" -ne 1 ]; then echo "Usage: $0 <raspbian|retropie|openelec>" exit 1 else PARTITION=$1 fi if [ "$(id -u)" != "0" ]; then echo "Not root user, using sudo" SUDO='sudo' fi case $PARTITION in raspbian) PARTITION=5 ;; retropie) PARTITION=7 ;; openelec) PARTITION=9 ;; *) echo "Invalid partition, exiting..." exit 1 esac if [ ! -d "$MOUNT_POINT" ]; then echo "Creating mount point $MOUNT_POINT" $SUDO mkdir "$MOUNT_POINT" fi if mount | grep "$MOUNT_POINT" > /dev/null; then echo "${MOUNT_POINT} is already mounted" else echo "${MOUNT_POINT} is not mounted, mounting..." $SUDO mount $DEVICE "${MOUNT_POINT}" fi if [ ! -f "${MOUNT_POINT}/${NOOBS_CONF}" ]; then echo "${MOUNT_POINT}/${NOOBS_CONF} does not exist, exiting..." else echo "${MOUNT_POINT}/${NOOBS_CONF} exists, good..." $SUDO sed -i.bak "s,^\(default_partition_to_boot\s*=\s*\).*$,\1${PARTITION}," ${MOUNT_POINT}/${NOOBS_CONF} fi if mount | grep "$MOUNT_POINT" > /dev/null; then $SUDO umount "${MOUNT_POINT}" $SUDO rmdir "${MOUNT_POINT}" fi $SUDO reboot
Else, use this file.
#!/bin/bash DEVICE="/dev/mmcblk0p3" MOUNT_POINT="/tmp/noobs" NOOBS_CONF="noobs.conf" SUDO='' if [ "$#" -ne 1 ]; then echo "Usage: $0 <raspbian|retropie|openelec>" exit 1 else PARTITION=$1 fi if [ "$(id -u)" != "0" ]; then echo "Not root user, using sudo" SUDO='sudo' fi case $PARTITION in raspbian) PARTITION=5 ;; retropie) PARTITION=6 ;; openelec) PARTITION=7 ;; *) echo "Invalid partition, exiting..." exit 1 esac if [ ! -d "$MOUNT_POINT" ]; then echo "Creating mount point $MOUNT_POINT" $SUDO mkdir "$MOUNT_POINT" fi if mount | grep "$MOUNT_POINT" > /dev/null; then echo "${MOUNT_POINT} is already mounted" else echo "${MOUNT_POINT} is not mounted, mounting..." $SUDO mount $DEVICE "${MOUNT_POINT}" fi if [ ! -f "${MOUNT_POINT}/${NOOBS_CONF}" ]; then echo "${MOUNT_POINT}/${NOOBS_CONF} does not exist, exiting..." else echo "${MOUNT_POINT}/${NOOBS_CONF} exists, good..." $SUDO sed -i.bak "s,^\(default_partition_to_boot\s*=\s*\).*$,\1${PARTITION}," ${MOUNT_POINT}/${NOOBS_CONF} fi if mount | grep "$MOUNT_POINT" > /dev/null; then $SUDO umount "${MOUNT_POINT}" $SUDO rmdir "${MOUNT_POINT}" fi $SUDO reboot
The difference between the two files is simply where the boot partition lies.
Sudo No Password Permission
Because the script needs root access (sudo) to do its thing, and since sudo prompts for a password, we must relax this restriction. The following must be done with both Raspbian and RetroPie and NOT OpenELEC (as the default user is already root).
sudo visudo
If not already there, add the following at the end of the file.
pi ALL=(ALL) NOPASSWD: ALL
Save and close.
All that remains now is how to use the script. Actually that’s quite easy. Assume the Raspberry Pi is running and currently in Raspbian, and assume you’d like to now use RetroPie. From your desktop, do the following.
ssh pi@<IP_ADDRESS_OF_RPI> "./change_boot.sh retropie"
Boot to OpenELEC.
ssh pi@<IP_ADDRESS_OF_RPI> "./change_boot.sh openelec"
Remember, if OpenELEC is currently running, the user is root.
ssh root@<IP_ADDRESS_OF_RPI> "./change_boot.sh raspbian"
Oh, every subsequent reboot will always boot into the last OS selected.
Conclusion
Well, I hope you truly enjoyed this series and invite you to leave a comment if you have questions. Thanks for reading!
Do you have an already established SD card image that you can share?
Sorry, at this point I do not.
Hi, superb guide and written in a way to keep the reader engaged throughout.
I want to try this with an rpi1 b that I have. Do you think these steps would work? Or is there something in rpi2 that is different?
Hi Chalky,
Appreciate the compliments!
Don’t see why this can’t be applied to the rpi1. Although versions may have changed since the time of writing, the process should be generic enough to work on any Pi.
Thanks for visiting my site!
Many thanks for this excellent article, very helpful and easy to follow.
Thanks for stopping by!
Wow, have to say, Great writeup. 3 questions though:
1. I’M done with part one, moving on to part two. Can i use a SSD hard drive?
2. If I can use the drive, the majority of the storage would be for Retropie Roms that I own. Should I just make that partition larger or create another partition strictly for ROMS.?
3. In part three do you have any idea if there is an easier way to reboot without typing in the ssh commands, for people less technical, or maybe something than can run from an android phone when clicked (I may need to make an app for that) ? Although I may just add a reset button via the GPIO pins. Which would simplify it I guess.
Thank you for your hard work.
PS, IMO this looks much nicer and work better than berry boot. 🙂
.
Hi Casey,
I’m really glad you enjoyed the write-up.
Concerning your questions, I’m assuming you can utilize an SSD via the USB port but in all honestly I don’t see the point. The speed of the SSD will be severely impacted by the throughput of the USB 2 bus on the Pi. You’re better off finding yourself a fast USB 2/3 flash key and migrating all the root partitions to that. And based on the size of the USB, you are free to allocate as much free space as you would like for your ROMs.
At the time of writing, I couldn’t think of a way to reboot to another partition without using SSH. Maybe there is, I don’t know. It shouldn’t be all that technical if you’re able to get through the first two parts to figure it out. More so, you can download an App (that has SSH capabilities) from the App Store that would allow you to trigger SSH commands all through your phone.
Hope that helps.
Thanks
Hell yeah! Very nice guide!
I will try to follow it for my purpose, Raspbian lite + Libreelec on a 2 TB external usb hard drive
I hope it is valid for that.
And I would like to know, if you can, after succeeding, substitute that big microSD card used at the beginning, for a smaller one, for example a 2gb microsd card, because from now on that card only needs to hosts some files, not whole operative systems.
How can I do that?
Thanks in advance