I have read through the various documentation/blog posts on provisioning and pre-provisioning, as well as some of the posts here on the forum but struggling to identify the best approach for my scenario. I want people to be able to download an image and flash their own devices with it. But I also want the option for those flashed devices to be able to join my openBalena instance for updates. My understanding is each image needs its own API key in the config file and therefore flashing more than one device with the same image would cause conflicts?
Alternatively, I would like to build in a function so that people can flash the device with an image that doesn’t have a key in the config file, and then from the device interface add an individual key that I provide, but I can’t see an option for that via the supervisor.
There are 3 kinds of OS images that you will encounter in the balena world:
Unconfigured balenaOS images that you can get from https://www.balena.io/os/. These do not contain the typical config.json and will not connect to balenaCloud or to an openBalena instance by default
Fully configured images, typically obtained through the Balena CLI. These images have a balena instance, an app name, and a device UUID embedded into the configuration file and thus no 2 devices can be provisioned with the same image
Partially configured images, which you typically obtain through the balena UI. These images have the balena instance and app id embedded into the configuration, but the device configuration is left blank. When the device first boots, it will generate things like a device UUID and register itself against the balena instance on the specified application. This means that you can flash the image over and over again and you will always get a new device on the same application
I believe that the partially configured images I described above fit your needs. Would something like that work for you?
That does indeed sound like partially configured fits the bill. I am surprised I didn’t come across it in the guides. Or perhaps did see the guide but misunderstood it. Could you link me to the guide on how to provision partially configured images for openBalena/the CLI?
This will create a partially configured image for you that can be reused at will. Do note however that due to changes in balenaOS, only versions up to and including 2.49.0 are currently supported.
Please let us know if you have any further questions!
Can’t say I fully understood that is what would have happened, or how it happens though. It highlights the command to execute:
balena os configure ~/Downloads/balenaos-raspberrypi3-2.22.1+rev1-dev-v7.25.3.img --app myApp
Then suggests the image contains a UUID as configured with the openBalena server:
UUID: 59d7700755ec5de06783eda8034c9d3d
What then happens when I flash this image to two devices and boot them up? Does one of them identify the conflict and generate a new UUID? Presumably there can’t be two devices with one UUID?
This command will configure the image with network credentials and keys to connect to openBalena server so it will be the partially configured image as my colleague mentioned above and there won’t be a UUID conflict if you flash the image to two devices.
Thanks for the clarification, I see now that the guide notes to boot the device up, and then look for the UUID, telling me that the UUID is added on first connect rather than injected into the config file in the image.
You will leak certain metadata about your openBalena instance and the application e.g. the fact that the openBalena server even exists, URL, app ID, …
Anybody with access to both the image and your openBalena instance will be able to provision as many devices as they want at their own will
The image will contain a key which it uses to reach out to the API/DB and provision a “device” resource in the API/DB to correspond to the device which has just booted for the first time. This is also when it receives its UUID.
Are there mechanisms built into OpenBalena to stop a flood of requests? I had considered something with Fail2Ban, but would have thought there are some mechanisms already built in as part of its security?
Can this config file then still be used for flashing to multiple cards, or would it now have a fixed UUID that would create a conflict?
I am now trying to achieve two things, maintain an image that can be flashed to multiple devices, and set a hostname for the device. To set the hostname, I must specify it in the config file, but not sure how to generate a config file with a custom hostname that can still be flashed to multiple devices.
A config file created as above does not have a uuid yet. I have been using files created in the dashboard or with the cli to initialize multiple devices.