raspberrypi / cmprovision

Provisioning system for CM4 products
BSD 3-Clause "New" or "Revised" License
97 stars 14 forks source link

How to boot installed image immediately after provisioning #46

Closed djr-spectrummfg closed 5 months ago

djr-spectrummfg commented 5 months ago

I would like the CM4 system to boot the newly-installed image immediately after provisioning is complete. I have attempted to add a postinstall script that calls the reboot command, however this does not appear to work.

maxnet commented 5 months ago

By default (when invoked without options) "reboot" only sends a signal to an init process such as systemd to nudge it to reboot. In environments in which there is no init process, you may need to make sure the reboot() syscall is invoked instead.

sync
reboot -f

Do keep in mind rebooting to your OS is not possible if USB booting, only when Ethernet booting.

djr-spectrummfg commented 5 months ago

Thanks, using reboot -f is working (even though the CM4 was connected to USB to boot)

maxnet commented 5 months ago

Meant rpiboot USB booting, not USB MSD ("usb stick") booting. If jumper is set for rpiboot, it will not do a normal boot, making reboot to normal OS difficult.

djr-spectrummfg commented 5 months ago

Right, I was using rpiboot but I have a momentary switch rather than a jumper.

djr-spectrummfg commented 5 months ago

One remaining issue is that while using sync + reboot -f works, it also results in the CM remaining with "Provisioning complete" as "No" in the web interface, which is not ideal.

However this issue can be avoided by checking the Run in background option and adding delays to the script (which I already had to be sure the sync was complete).

I ended up going with the script below:

#!/bin/sh
set -e
sync
sleep 2
sync
sleep 2
reboot -f
maxnet commented 5 months ago

One remaining issue is that while using sync + reboot -f works, it also results in the CM remaining with "Provisioning complete" as "No" in the web interface, which is not ideal.

If there is stuff left to do on first boot, you typically let your first boot script phone home completion.

How such things are done best is very dependent on the OS you are installing though. E.g. if you are using Ubuntu Core or Ubuntu Server, and let cmprovision generate the cloud-init user-data file (with a little bit of extra code, support for that is not in the stock cmprovision version), you typically add a section to your template among the lines of:

phone_home:
  url: http://{{ $server }}/scriptexecute?serial={{ $cm->serial }}&alldone=1&verify={{ $project->verify }}
  tries: 10

(Making a HTTP request with serial set and alldone=1 is what it takes to get the server to mark it as completed. phone_home is a standard cloud-init module, but you can also use curl, wget, Python or anything else that can make a HTTP call for that)