raspberrypi / rpi-imager

The home of Raspberry Pi Imager, a user-friendly tool for creating bootable media for Raspberry Pi devices.
https://www.raspberrypi.com/software
Other
1.67k stars 254 forks source link

Augmenting firstboot.sh with our own scripts #554

Closed JonTheNiceGuy closed 8 months ago

JonTheNiceGuy commented 1 year ago

Hi! Thanks for creating this tool, it's incredibly useful!

I've recently been trying to document how to automate the provisioning of my raspberry pi on first boot. My initial sketch of this ended up using a lot of Ansible to deploy code onto the SDCard, but while recently working on a talk for a conference, I discovered firstrun.sh.

Now, while I'd dearly love to tinker with that script, the layout of the script makes it a bit dangerous to mess with it too much HOWEVER, I don't think it would be too hard to add an additional "run your own custom scripts" blob at the end of that.

I currently manually add the following code block just before the line rm -f /boot/firstrun.sh:

if [ -e /boot/firstrun ]
then
  printf '%s\n' /boot/firstrun/* | grep -v '*' | sh
  rm -Rf /boot/firstrun
fi

(Note that this is injected in this line of OptionsPopup.qml)

Now, why haven't I just submitted this as a PR? Well... I don't know how to do something similar in the cloud-init, short of populating the variable cloudinitwrite earlier on, and I don't want to provide a patch that works for 1 variant, but not the other.

So; does this seem interesting and useful? If so, I'm happy to create a PR for the firstrun.sh variant, and then try and figure out how to do the same thing for cloud-init, unless of course, someone wants to just write it for me? ;)

For context, this is what I'm personally doing this for: https://jon.sprig.gs/blog/post/category/computers/raspberry-pi-otg-usb-gadget

maxnet commented 1 year ago

Not sure if this is functionality we should offer to the average end-user.

Keep in mind that if the user finds some custom script online, attempts to use it, but the code no longer works with whatever RPI OS version is currently out, and errors out, the lines that disable running the firstboot script and booting normally will not run. User may then come here for support complaining Imager created a SD card that does not boot...

There are other solution that do support integrating your own custom scripts. Like rolling your own .img with pi-gen: https://github.com/RPi-Distro/pi-gen Or using cmprovision: https://github.com/raspberrypi/cmprovision

petermoo commented 1 year ago

I have a similar requirement and investigated firstrun.sh. I wanted to add stuff to the new user. I am adding using a new name for the user which means /home/pi/ is renamed and becomes the base for my user. I decided to insert stuff in /home/pi. I have not worked out the equivalent for those occasions when new user is created by the other code in firstrun.sh.

I create /home/pi/.config/autostart/autostart.desktop when I need something run at first login. Insert the following settings. [Desktop Entry] Version=1.0 Comment=Automatically start a terminal running a command inside it on user login. Exec=lxterminal -e ~/autostart.sh Icon=lxterminal Type=Application

I could not get the autostart to open a terminal window so the user could see what is happening or to leave the window open so they could read the result. autostart.sh contains the following to open install.sh. install.sh contains the actual changes. #!/bin/bash lxterminal -e "bash -c ~/install.sh;exec bash"

firstrun.sh may not rename /home/pi which would require a different approach. There would also be differences if you do not want the user to see the changes or you want them to run before the first login.

I think the options would be something like:

An alternative for my use case might be to have directory /home/firstlogin then let us copy scripts into there with the firstrun code moving everything into the user after the user is created.

An improvement to to firstrun.sh code. Firstrun has $FIRSTUSER representing pi or whatever and it, in my firstrun, renamed the user to "peter". That hard coded "peter" makes changing the code harder. If "peter" was defined as NEWUSER="peter" then used as $NEWUSER, I could add code to firstrun.sh to insert stuff into /home/$NEWUSER. That might make it easier for JonTheNiceGuy and others to insert scripts.

I do not know where to insert a patch to create NEWUSER="peter".

maxnet commented 1 year ago

I think the options would be something like:

first boot first login of the first user first login of every user For each, select a script for upload.

Sorry, but this is really outside the scope of Imager.

And for multi-user setups (which you are hinting at with "of every user") you typically also want others things changed. Like centralized authentication using LDAP or similar. (Something the piserver project does offer, but that never gained any popularity).

petermoo commented 1 year ago

"of every user" When looking at my "first login" options, there was something about setting up /etc/skel as the template for new users. Anything there would be copied into a new user and could be an autostart. I did not test that in detail as my tests showed firstrun.sh was renaming pi instead of creating a new user. I think the option would just be creating /etc/skel then preloading it the same as preloading pi.

"The /etc/skel directory holds copies of various initialization and other files that may be copied to the new user's home directory when the /usr/sbin/useradd program adds the new user."

Thinking about it, the /etc/skel option would not be used when pi is renamed. To handle both, you would have to put first-login-for-every-user in /etc/skel then copy it to pi if pi is to be renamed. A bit complicated.

I still think the code change to put the new user name in a variable would make it easier for us to modify firstrun.sh in ways that target the new user. It might not help JonTheNiceGuy with his current project. Should I make it a new issue?

maxnet commented 1 year ago

I still think the code change to put the new user name in a variable would make it easier for us to modify firstrun.sh in ways that target the new user.

I don't think that's Imager's task. Note that you can also just look it up yourself by userid.

FIRSTUSERNAME=`getent passwd 1000 | cut -d: -f1`

Or if it's actually the home directory instead of username you are after:

FIRSTUSERHOME=`getent passwd 1000 | cut -d: -f6`
tdewey-rpi commented 8 months ago

Feature request rejected.

@maxnet has laid out the rationale, and I agree with their position. For the OP's case, I'd strongly recommend using pi-gen or another OS image creation flow.

Closing as 'Won't fix'.

anttiryt commented 3 months ago

I think the firstboot.sh is saved on the boot partition, it's quite easy to modify after creating the image, even automatically with sed. Just copy your own firstboot-user.sh into boot partition and add it just before the final exit 0 in the firstboot.sh

lurch commented 3 months ago

I think the firstboot.sh is saved on the boot partition, it's quite easy to modify after creating the image, even automatically with sed. Just copy your own firstboot-user.sh into boot partition and add it just before the final exit 0 in the firstboot.sh

You might find that such a simple approach doesn't work, due to the automatic-changes that https://github.com/RPi-Distro/raspberrypi-sys-mods/blob/bookworm/initramfs-tools/scripts/local-bottom/imager_fixup makes to the firstrun.sh file. (I discovered this the hard way :wink: )