Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
jayjayseal opened this issue Apr 16, 2024 · 9 comments
Open

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

jayjayseal opened this issue Apr 16, 2024 · 9 comments

Comments

@jayjayseal
Copy link

jayjayseal commented Apr 16, 2024

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
Copy link
Author

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
Copy link
Collaborator

maxnet commented May 13, 2024

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
Copy link
Author

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
Copy link
Collaborator

maxnet commented May 13, 2024

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.:

  • add to /var/lib/cmprovision/etc/dnsmasq.conf: "tftp-unique-root=mac". This setting causes dnsmasq's tftp server to look if a folder /var/lib/cmprovision/scriptexecute/mac-address exists. If it does it will look for the boot files there. If not it will take the files from the main /var/lib/cmprovision/scriptexecute folder.
  • "sudo systemctl restart cmprovision-dnsmasq"
  • "sudo chown www-data /var/lib/cmprovision/scriptexecute" so www-data can create folders there.
  • create a /var/lib/cmprovision/app/Listeners/BreakNetworkBoot.php among the lines:
<?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
Copy link
Author

I'll try this! Thanks!

@jayjayseal
Copy link
Author

jayjayseal commented May 14, 2024

This works beautifully!! wow! 👯 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
Copy link
Collaborator

maxnet commented May 14, 2024

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

  • Resolve the $id to a $cm model object with:
$cm = Cm::findOrFail($id);

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

  • Probably need rmdir() instead of rm()

@jayjayseal
Copy link
Author

jayjayseal commented May 14, 2024

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
Copy link
Author

jayjayseal commented May 23, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants