raspberrypi / cmprovision

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

Check for device provision is ready and not restart flashing #48

Open jayjayseal opened 2 months ago

jayjayseal commented 2 months ago

Hi,

This might be a feature request. Though i don't know if this works for RPI. I'm using the CMprovisioner with success and provisioning works (thanks for this).

The default setting (first SD/MMC/USB etc then PXE boot) of the Pi's is kind of strange as you would need to wipe the SD card or remove the /boot/ partition to get it going again. For example the CM/RPI could detect that it can boot from SD but later in the process somehow still fails to boot due to a config error. The provisioning becomes unusable in this case as it detects dat it can boot from the SD card and to overcome this you will have to clear the SD card manually or remotely (if you still can).

You can set the RPI to first try to PXE boot and if this fails then boot from the SD card (and this works on a pi4 for example) It would be nice if the boot process on the server would be aware if a device is already provisioned and skip PXE/netbooting when the status Provisioning complete is set to a date. This will require adjusting the PXE/netboot routine.

You would also need to be able to set the device to status provisioning complete to "no" manually for it to be provisioned again instead of always blindly copy the SD card whenever a boot request is made. Setting a RPI4 to first PXE/Netboot leaves you in a loop of always booting from the network and recopying the image to the device.

jayjayseal commented 1 month ago

Probably defer the netboot to a different TFTP server?

I'm now just blocking access to the TFTP server in the firewall (that works too)

maxnet commented 1 month ago

Note that there are other options to reprovision already provisioned devices. Ranging from using USB (rpiboot), to adding a push button to your board design and using an alternative boot option when that is pressed. (Can configure that in EEPROM settings).

jayjayseal commented 1 month ago

This option does not really work. As if the device is unreachable it will not work to set options. The devices i want to manage are in different locations and most of them high in the ceiling where someone would need to get a ladder to reach them. Rebooting is possible because i just power cycle the network port on the switch.

maxnet commented 1 month ago

The devices i want to manage are in different locations and most of them high in the ceiling

Would be more tempted to ditch the SD card and network boot the whole OS in such cases. (similar to what Piserver does)

.

If you really want to use cmprovision and sabotage network boot after initial installation you can probably do some hackery with a CmProvisioningComplete event listener hook though.

E.g.:

<?php
namespace App\Listeners;

use App\Events\CmProvisioningComplete;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use App\Models\Cm;

class BreakNetworkBoot implements ShouldQueue
{
    use InteractsWithQueue;

    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
    }

    /**
     * Handle the event.
     *
     * @param  App\Events\CmProvisioningComplete  $event
     * @return void
     */
    public function handle(CmProvisioningComplete $event)
    {
        $cm = $event->cm;
        $mac_with_dashes = str_replace(":", "-", $cm->mac);
        /* Creating an empty directory in the form /var/lib/cmprovision/scriptexecute/11-22-33-44-55-66 to break network boot for the MAC address that just finished provisioning */
        mkdir("/var/lib/cmprovision/scriptexecute/".$mac_with_dashes);
    }
}

(untested)

jayjayseal commented 1 month ago

I'll try this! Thanks!

jayjayseal commented 1 month ago

This works beautifully!! wow! :dancers: Now to get rid of the folder when you delete a device.... if one can point me to the files of the web interface i can probably tell what to insert there.

rm("/var/lib/cmprovision/scriptexecute/".$mac_with_dashes);

maxnet commented 1 month ago

Now to get rid of the folder when you delete a device.... if one can point me to the files of the web interface i can probably tell what to insert there.

https://github.com/raspberrypi/cmprovision/blob/main/app/Http/Livewire/Cms.php#L56

$cm = Cm::findOrFail($id);

(And make sure you do so, before the CM is destroy()'ed.)

jayjayseal commented 1 month ago

You are a star! :)

replace the delete function in: /var/lib/cmprovision/app/Http/Livewire\Cms.php With the following:

    public function delete($id)
    {
        $cm = Cm::findOrFail($id);
        $mac_with_dashes = str_replace(":", "-", $cm->mac);
        /* Removing directory in /var/lib/cmprovision/scriptexecute/11-22-33-44-55-66 (MAC) to resume network boot for the MAC address address that was deleted */
        rmdir("/var/lib/cmprovision/scriptexecute/".$mac_with_dashes);
        Cm::destroy($id);
        session()->flash('message', 'Cm deleted.');
    }
    Sorry for the multiple edits.... my vscode messed up in excitement :)
jayjayseal commented 1 month ago

It works perfectly still. Though there is one weird thing. Once you select "Verify that image was written correctly" in the projects tab. It suddenly set's strange values (like the wrong MAC address, it forgets the pre/post-logs, temperatures etc in the CM's list. It also creates a wrong folder for DNSMasq). If you do not check if the image was written successfully it just works normally.