# Update device\_type for Yocto rootfs-image

**URL:** <https://hub.mender.io/t/update-device-type-for-yocto-rootfs-image/5697>\
**Category:** General Discussions\
**Tags:** yocto, beaglebone\
**Created:** [March 20, 2023, 3:08pm UTC](https://hub.mender.io/t/update-device-type-for-yocto-rootfs-image/5697 "2023-03-20T15:08:32Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![BGSD](https://avatars.discourse-cdn.com/v4/letter/b/aca169/32.png) [@BGSD](https://hub.mender.io/u/BGSD)\
**Post date:** [March 20, 2023, 3:08pm UTC](https://hub.mender.io/t/update-device-type-for-yocto-rootfs-image/5697/1 "2023-03-20T15:08:33Z")

</div>

# Problem

Previously, we were using the `beaglebone-yocto` machine type in our Yocto build for both BeagleBone Green and BeagleBoneGreen Gateway boards. At some point we were forced to override the machine type and instead create a separate machine configuration for each of these boards. This was done using the `MACHINE_OVERRIDES` configuration variable so now we have `bbg-beaglebone-yocto` and `bbgg-beaglebone-yocto` machine types.

We then build our images using bitbake

```auto
bitbake mc:bbg-beaglebone-yocto:core-image-base
bitbake mc:bbgg-beaglebone-yocto:core-image-base

```

Then artifacts are generated for each

```auto
mender-artifact write rootfs-image \
  --artifact-name bbg-os \
  --device-type bbg-beaglebone-yocto \
  --file tmp/deploy/images/bbg-beaglebone-yocto/out.ext4

mender-artifact write rootfs-image \
  --artifact-name bbgg-os \
  --device-type bbgg-beaglebone-yocto \
  --file tmp/deploy/images/bbgg-beaglebone-yocto/out.ext4

```

The problem is that our artifacts were previously generated with the `device-type` of `beaglebone-yocto` but we want to update our devices with their machine-specific artifact.

# Expected Outcome

What we need is some way to generate these new artifacts such that we can deploy `bbg-beaglebone-yocto` to a device that currently has the device type of `beaglebone-yocto`. This deployment should also update the device’s `Device Type` in Mender to reflect the device type of the artifact.

We have attempted to solve this problem by adding `beaglebone-yocto` as an additional `--device-type` when generating our new artifacts (see command below). This allows us to install the new rootfs-image to our device however it does not actually update the `device-type` of the device in Mender.

```auto
mender-artifact write rootfs-image \
  --artifact-name bbgg-os \
  --device-type bbgg-beaglebone-yocto \
  --device-type beaglebone-yocto \
  --file tmp/deploy/images/bbgg-beaglebone-yocto/out.ext4

```

The `MENDER_DEVICE_TYPE` variable in our Yocto configuration is reporting the correct new value so that shouldn’t be the issue. (Found this using `bitbake -e`)

`/var/lib/mender/device_type` on the device itself is also still reporting `beaglebone-yocto` instead of the new device type.

Is there any way to solve this problem without having to manually update `/var/lib/mender/device_type` on the boards after deploying the new rootfs-image artifact?

---

<div class="post-metadata">

**Author:** ![TheYoctoJester](https://yyz2.discourse-cdn.com/flex036/user_avatar/hub.mender.io/theyoctojester/32/1444_2.png) [@TheYoctoJester](https://hub.mender.io/u/TheYoctoJester)\
**Post date:** [March 22, 2023, 3:08pm UTC](https://hub.mender.io/t/update-device-type-for-yocto-rootfs-image/5697/2 "2023-03-22T15:08:57Z")

</div>

Hi @BGSD,

this is in fact a use case that I had on my personal wish list for some time, so took the opportunity to dig into it 🙂

The easiest and most robust way is using the `script` update module. This is present by default on the device if you are using the generic Mender client installation. To be certain, check the device inventory, item `update_modules`.

In a nutshell, this enables you to run a mostly arbitrary script upon installation. I used this as the script file named `change_device_type`:

```auto
#!/bin/sh

echo -n "device_type=fancy_new_rpi4" > /data/mender/device_type

```

and created an artifact like this:

```auto
mender-artifact write module-image \
--type script \
--device-type raspberrypi4 \
-n fancy-new-rpi4 \
-f change_device_type \
-o change_device_type2.mender

```

After deployment, the device changed its type in the dashboard from `raspberrypi4` to `fancy_new_rpi4` 🎉

Take with a pinch of salt and test properly for your use case, but should be a neat solution.

Greetz,  
Josef

---

<div class="post-metadata">

**Author:** ![BGSD](https://avatars.discourse-cdn.com/v4/letter/b/aca169/32.png) [@BGSD](https://hub.mender.io/u/BGSD)\
**Post date:** [March 27, 2023, 8:10pm UTC](https://hub.mender.io/t/update-device-type-for-yocto-rootfs-image/5697/3 "2023-03-27T20:10:50Z")

</div>

I had to use a slightly different approach to your solution to get this to work for my use case.

Since we currently have a `rootfs-image` deployed to our board with the `device_type=beaglebone-yocto`, I needed to generate two different artifacts to get this to work.

So first off I have a recipe in my Yocto build for Mender update modules. The recipe looks like this:

```auto
recipes-update-modules
└── update-modules
    ├── files
    │ └── update-module
    └── update-modules_0.1.bb

```

`update-modules_0.1.bb`

```auto
RDEPENDS_${PN}_append = " bash"

SRC_URI = "file://update-module"

S = "${WORKDIR}"

FILES_${PN} += "\
    ${datadir}/mender/modules/v3/update-module \
"

do_install() {
    install -d ${D}${datadir}/mender/modules/v3
    install -m 0755 update-module ${D}${datadir}/mender/modules/v3
}

```

`files/update-module` handles updating our application files and does not change anything else in our OS.

So then I tried adding a new update module like you described named `update-device-type` then updated the `update-modules_0.1.bb` file to include this new script in the `SRC_URI`, the `FILES_${PN}` and the `do_install()` sections.

I then generated an artifact using this new update module as follows:

```bash
mender-artifact write module-image \
    --type update-device-type \
    -n test_update_device_type \
    -t beaglebone-yocto \
    -f bbgg.ext4 \
    -o test_update_device_type.mender

```

However when I went to deploy this module-image artifact to my device, it failed to deploy due to the `/usr/share/mender/modules/v3/update-module` file not existing on the current image.

So to work around this issue, I had to take the following approach.

1. Created three scripts in the `recipes-update-modules` recipe.
  - `device-type-bbg-beaglebone-yocto`
  - `device-type-bbgg-beaglebone-yocto`
  - `device-type-beaglebone-yocto`

> These scripts just echo their respective `device_type` into `/data/mender/device_type`.

2. Changed permissions on each of the scripts to make them executable.

```bash
chmod +x recipes-update-modules/update-modules/files/device-type*

```

3. Added each of these scripts to the `update-modules_0.1.bb` file as described previously.

```auto
RDEPENDS_${PN}_append = " bash"
  
SRC_URI = "\
    file://update-module \
    file://device-type-bbg-beaglebone-yocto \
    file://device-type-bbgg-beaglebone-yocto \
    file://device-type-beaglebone-yocto \
"
  
S = "${WORKDIR}"
  
FILES_${PN} += "\
    ${datadir}/mender/modules/v3/update-module \
    ${datadir}/mender/modules/v3/device-type-bbg-beaglebone-yocto \
    ${datadir}/mender/modules/v3/device-type-bbgg-beaglebone-yocto \
    ${datadir}/mender/modules/v3/device-type-beaglebone-yocto \
"
  
do_install() {
    install -d ${D}${datadir}/mender/modules/v3
    install -m 0755 update-module ${D}${datadir}/mender/modules/v3
    install -m 0755 device-type-bbg-beaglebone-yocto ${D}${datadir}/mender/modules/v3
    install -m 0755 device-type-bbgg-beaglebone-yocto ${D}${datadir}/mender/modules/v3
    install -m 0755 device-type-beaglebone-yocto ${D}${datadir}/mender/modules/v3

```

> Looking back, I wonder if I even needed to do step #2 since I am installing these files with `0755` in the `do_install()` section here. Not really sure…

4. Build my base images.

```bash
bitbake mc:bbg-beaglebone-yocto:core-image-base
bitbake mc:bbgg-beaglebone-yocto:core-image-base

```

5. Generate the `rootfs-image` artifacts for each device.

```bash
mender-artifact write rootfs-image \
  -n device-type-upgrade:bbg-part-1-of-2 \
  -t beaglebone-yocto \
  -t bbg-beaglebone-yocto \
  -f core-image-base-bbg-beaglebone-yocto.ext4 \
  -o device-type-upgrade-bbg-part-1-of-2.mender \

```

> Same command repeated but replaced `bbg` with `bbgg`

6. Generate the `module-image` artifacts for each device.

```bash
mender-artifact write module-image \
  -T device-type-bbg-beaglebone-yocto \
  -n device-type-upgrade:bbg-part-2-of-2 \
  -t beaglebone-yocto \
  -f core-image-base-bbg-beaglebone-yocto.ext4 \
  -o device-type-upgrade-bbg-part-2-of-2.mender

```

> Same command repeated but replaced `bbg` with `bbgg`

7. Upload artifacts to Mender.
8. Deploy part 1 of artifacts to respective boards.
  - Board will now have the Mender module update scripts in `/usr/share/mender/modules/v3`
  - At this point `/data/mender/device_type` is still `beaglebone-yocto`.

9. Deploy part 2 of artifacts to respective boards.
  - This update actually runs the module update scripts to change `/data/mender/device_type`.

At this point I can now deploy the new `rootfs-image` artifacts using the new device types.

I feel like I may have overcomplicated much of this process so if there is anything that you think I did wrong then let me know.

I also notice that `mender-artifact write rootfs-image` has a parameter `--script` used to specify a “state script” however I haven’t looked into those at all so I don’t know how they differ from module update scripts.
