Building disk images (i.e. preloading) with GitHub Action fails

Hi Balena folks,

We’re in the process of resurrecting Screenly OSE (with a new full time hire). Part of this work is to restore the Balena support that partially broke some time back.

We’ve been successful with getting deployments to Hub to work (currently the 3rd most popular project).

For the next step, we’re looking to automatically build Balena disk images on GitHub Actions. Unfortunately, there seem to be some issues doing this (at least for 32bit images). The steps are heavily inspired by this article.

Here’s the current script that we are using:

However, it just keeps failing with:

Application architecture (aarch64) and image architecture (armv7hf) are not compatible. (BalenaError)

We even tried running it with Docker’s Buildx (cross compilation) but no go:

Anyone from the Balena team that could help with this?

Hi,

Great to hear about projects on the hub, thanks for sharing the update.

On the preloading, have you tried the community CLI action?

There is a post here with more info:

There are also some example implementations here, in particular this one may be of interest.

1 Like

Good shout. I tested it, but it unfortunately yields the exact same result:

Application architecture (aarch64) and image architecture (armv7hf) are not compatible. (BalenaError)

If I am looking at the right file, then it looks like you have a pi3 and pi4 matrix but your conditional statements are puling pi1, pi2 and pi3?

        board: ['pi3', 'pi4']
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2.3.4

      - name: Get base board
        run: |
          # Logic for Raspberry Pi 1
          if [ "${{ matrix.board }}" == 'pi1' ]; then
            echo "BALENA_IMAGE=raspberry-pi" >> $GITHUB_ENV
          # Logic for Raspberry Pi 2
          elif [ "${{ matrix.board }}" == 'pi2' ]; then
            echo "BALENA_IMAGE=raspberry-pi2" >> $GITHUB_ENV
          else
            echo "BALENA_IMAGE=raspberrypi3" >> $GITHUB_ENV
          fi
1 Like

By the way, if the intent is to release preloaded images that will join your fleet automatically when flashed, then I think you will also need to add in an os configure command.

# untested
          balena_cli_commands: |
            preload \
              "$BALENA_IMAGE.img" \
              --fleet screenly_ose/screenly-ose-${{ matrix.board }} \
              --commit latest
            os configure \
              "$BALENA_IMAGE.img" \
              --config-network=ethernet  \
              --fleet screenly_ose/screenly-ose-${{ matrix.board }}

Preloading will fetch the code from your fleet and add it to the image, and the configure will insert the instruction to join the fleet when it boots for future updates.

If I am looking at the right file, then it looks like you have a pi3 and pi4 matrix but your conditional statements are puling pi1, pi2 and pi3?

Yes, I intentionally disabled pi1 and pi2 to speed up the tests in this branch.

I mean it looks like there isn’t a Pi4 option. It is trying to flash your Pi4 fleet to a pi3 image:

        board: ['pi3', 'pi4']

...


          if [ "${{ matrix.board }}" == 'pi1' ]; then
            echo "BALENA_IMAGE=raspberry-pi" >> $GITHUB_ENV
          # Logic for Raspberry Pi 2
          elif [ "${{ matrix.board }}" == 'pi2' ]; then
            echo "BALENA_IMAGE=raspberry-pi2" >> $GITHUB_ENV
          else
            echo "BALENA_IMAGE=raspberrypi3" >> $GITHUB_ENV  <-- where is the pi4?
          fi

Right. Good catch. I was just thinking that the pi3 and pi4 use the same docker image, but they are using different disk images.

Ahh I see. Yes, Pi 4 has it’s own image. So perhaps something like:

# untested
          if [ "${{ matrix.board }}" == 'pi1' ]; then
            echo "BALENA_IMAGE=raspberry-pi" >> $GITHUB_ENV
          # Logic for Raspberry Pi 2
          elif [ "${{ matrix.board }}" == 'pi2' ]; then
            echo "BALENA_IMAGE=raspberry-pi2" >> $GITHUB_ENV
          elif [ "${{ matrix.board }}" == 'pi3' ]; then
            echo "BALENA_IMAGE=raspberrypi3" >> $GITHUB_ENV 
          else
            echo "BALENA_IMAGE=raspberrypi4-64" >> $GITHUB_ENV 
          fi

Or to catch problems in the future:

#untested
          if [ "${{ matrix.board }}" == 'pi1' ]; then
            echo "BALENA_IMAGE=raspberry-pi" >> $GITHUB_ENV
          # Logic for Raspberry Pi 2
          elif [ "${{ matrix.board }}" == 'pi2' ]; then
            echo "BALENA_IMAGE=raspberry-pi2" >> $GITHUB_ENV
          elif [ "${{ matrix.board }}" == 'pi3' ]; then
            echo "BALENA_IMAGE=raspberrypi3" >> $GITHUB_ENV 
          elif [ "${{ matrix.board }}" == 'pi4' ]; then
            echo "BALENA_IMAGE=raspberrypi4-64" >> $GITHUB_ENV 
          else
           echo "Could not find an image that matches this fleet."
           exit 1
          fi
1 Like

Yep, just pushed those changes.

Fingers crossed:

Success! Thanks @maggie0002. So what happened was that the pi4 job ‘failed’ first, cancelling all other runs. Everything seems to be working fine now.

2 Likes

Great news.

You could combine these two by the way, the action takes multiple commands per run, like in the example above:

      - name: balena CLI Action - preload
        uses: balena-labs-research/community-cli-action@1.0.0
        with:
          balena_token: ${{secrets.BALENA_TOKEN}}
          balena_cli_commands: |
            preload \
              "$BALENA_IMAGE.img" \
              --fleet screenly_ose/screenly-ose-${{ matrix.board }} \
              --commit latest
          balena_cli_version: 13.7.1

      - name: balena CLI Action - configure
        uses: balena-labs-research/community-cli-action@1.0.0
        with:
          balena_token: ${{secrets.BALENA_TOKEN}}
          balena_cli_commands: |
            os configure \
              "$BALENA_IMAGE.img" \
              --config-network=ethernet  \
              --fleet screenly_ose/screenly-ose-${{ matrix.board }}
          balena_cli_version: 13.7.1

Becomes:

          balena_cli_commands: |
            preload \
              "$BALENA_IMAGE.img" \
              --fleet screenly_ose/screenly-ose-${{ matrix.board }} \
              --commit latest
            os configure \
              "$BALENA_IMAGE.img" \
              --config-network=ethernet  \
              --fleet screenly_ose/screenly-ose-${{ matrix.board }}
          balena_cli_version: 13.7.1

It would save the action having to build itself twice, and cut the build time down a bit. But it’s not going to be a big different, mostly just reduces lines of code and just thought I would note it.

Actually, it is really just built once. The second time it is invoked, it is fully cached.

I decided to split them apart just to make debugging easier in the case one step failed.

That makes a lot of sense, thanks for the feedback. Great to know for looking at development of the CLI action in the future.

Best of luck with the project.

1 Like