Balena push openBalena alternative

Haha - this is ok. I was excited to create guide too.
Github Actions (GA) is very powerfull tools, you can use GithubApi to trigger builds, and so on.
Like a “one ring to rule them all”, GA give opportunity to recreate part of functionality provided by balenaCloud!
My next step will be something like OS configurer for apps, which upload your customized system image to specified S3 storage, or just publish it directly in repo as artifact

1 Like

@teslov any thoughts on how we might use the action steps to update the application environment variables in openbalena?

I’m interested updating the app’s envs with info about the release/commit automatically, so that downstream we can see that the device is running the correct commit in the logs.

This is kinda what I was thinking:

  1. Set up first env for the application manually in CLI:
    balena env add commit null --application testing

  2. Retrieve the env ID with
    balena envs --application testing

ID NAME       VALUE           APPLICATION SERVICE
1  COMMIT     null            testing     *
  1. On each deployment (where GITHUB_SHA is the commit id)
    balena env rename 1 $GITHUB_SHA

  2. Confirm the change with
    balena envs --application testing

ID NAME       VALUE           APPLICATION SERVICE
1  COMMIT     123abc456def    testing     *

You would know better than myself, but can we just add that as another command to the action yml?

      balena_api_token: ${{secrets.BALENA_API_TOKEN}}
      balena_command: "deploy github-action-test --logs"
      balena_command: "balena env rename 1 $GITHUB_SHA"
      open_balena_address: ${{secrets.OPEN_BALENA_ADDRESS}}
      root_cert: ${{secrets.OPEN_BALENA_ROOT_CERT}}

I imagine this could basically be an openbalena version of balena clouds commit id.

Screen Shot 2021-03-14 at 7.57.12 AM

1 Like

I think you have a posibility to use && in balena command to combine it.
Like deploy && balena env rename 1 ${SHA VARIABLE HERE}
Or using pipe to use output in another command like devices | grep ....
Part of commands running in sh script, so you are not limited to expand it with your custom logic.
With using key --output json you can try jq tool, for processing it as json
The best way to implement your logic - just add new workflow to repo, with another purpose - dividing workflow by functions - is better.
If you are depends on success of your build - just add it as new job in workflow tree.

If you need so, i will provide possibility to use docker secrets in actions due to using custom docker registries and images.
And in next versions I will add Json as variable functionality with custom logic
Maybe at this, or next week

Managed to get it working… It requires an additional job at the end of the action. Also, pay attention to the openbalena env id (env rename 4 ${{ github.sha }}, you need to retrieve the correct ID from the CLI).
This adds the entire SHA which is pretty long, so there is the optional job (#2) to shorten it - to use just uncomment.

name: OpenBalena Deploy

on:
  push:
    branches:
      - master

jobs:
  balena-deploy:
    runs-on: self-hosted
    steps:
      - name: git-checkout
        uses: actions/checkout@v2

      # - name: Add SHORT_SHA env property with commit short sha
      #   run: echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> $GITHUB_ENV

      - name: balena-deploy
        uses: Solar-Control/open-balena-cli-action@v2.0.0
        if: success()
        with:
          balena_api_token: ${{secrets.BALENA_API_TOKEN}}
          open_balena_address: ${{secrets.OPEN_BALENA_ADDRESS}}
          root_cert: ${{secrets.OPEN_BALENA_ROOT_CERT}}
          balena_command: "deploy ${{secrets.BALENA_APPLICATION}} --logs"

      - name: balena-env-rename 
        uses: Solar-Control/open-balena-cli-action@v2.0.0
        if: success()
        with:
          balena_api_token: ${{secrets.BALENA_API_TOKEN}}
          open_balena_address: ${{secrets.OPEN_BALENA_ADDRESS}}
          root_cert: ${{secrets.OPEN_BALENA_ROOT_CERT}}
          balena_command: "env rename 4 ${{ github.sha }}"
1 Like

Ideally, in setting up your openbalena project, the first environment variable you would create with the CLI would be the one that will receive the SHA (or any other job id you want) that way it would be given a env ID of 1 so you’re action can remain the same, always updating a known env ID.

You are free to expand basic functionality of action by pull requests into the repo!
You are welcome :slight_smile:

I can add injection of github SHA every time of build action is done - it will be more logical at this way - implement some like release tags for your env

This is great, thanks for sharing this, it’s going to be a real help. Think I will try and implement it as a dev environment so commits get pushed out to a development device.

Not sure I entirely understand the workflow. Is the idea you commit built images to GitHub and then this just deploys them to OpenBalena, or do you push the code and the it builds the images and pushes them? I see the CLI is installed in a container, does it then build from there? I’m surprised it is able to connect to docker to perform the build process. All these questions emerge as I am wondering if it is in fact building the images too, how does caching work when it is run from inside a container? Will it cache my app layers on the server to improve the build time next time around?

Using guide - you can use it at your own cloud.

  1. Idea is encapsulate Balena CLI as Docker image with custom commands.
  2. Yes, it build directly in container
  3. Yes, it using native docker at your self-hosted runner, which allow you to cache your image for faster building.

Using this CLI - you can create your custom OS images too, and create preloaded OS images as artifacts directly in Github

1 Like

@maggie0002 I’ve got this working like a charm. All you do from a dev perspective after its up and running is commit to master. No need to build locally.
The action can be configured any way you like, if for example you want to kick off when a commit is made to another branch.

How about multiple commands on the same image file? Looking to do a preload with it, can you then run ‘config generate‘ by including a second ‘command’ line?

You can use different commands with the same image like mentioned by @barryjump

Also you can chain commands with pipe or && at command section

1 Like

Is there a need for the CRT to be created twice like this?

if [[ "${INPUT_ROOT_CERT}" != "" ]]; then
  echo -e ${INPUT_ROOT_CERT} > ca.crt
  cp ca.crt /usr/local/share/ca-certificates/ca.crt
  chmod 644 /usr/local/share/ca-certificates/ca.crt
  chmod 644 ca.crt
  update-ca-certificates
fi

If it is a permission issue, you could try (with or without sudo):

  sudo bash -c 'echo -e ${INPUT_ROOT_CERT} > /usr/local/share/ca-certificates/ca.crt'
  sudo chmod 644 /usr/local/share/ca-certificates/ca.crt
  sudo update-ca-certificates

At the moment at the top of the file it does cd ${GITHUB_WORKSPACE} to point to the checked out repo. Then echo -e ${INPUT_ROOT_CERT} > ca.crt is placing my super private .crt key into my repo. Which means any commit actions or packaging of assets I do later may contain my .crt key?

Just wanted to mention that balena-cli is now publishing Docker images so there’s no need to manually wrap it. Would love to hear your feedback and how it works for you. You can find out more here: balena-cli/DOCKER.md at master · balena-io/balena-cli · GitHub

3 Likes

Awesome, need some time to reimplement it at my side to use balena-cli as base image :slight_smile:

You are welcome to create pull requests into repo!

I had begun just that. But I ended up basing my workflow off yours but building it into the GitHub runner so it works a little different. Which means I don’t have a way to test right now :frowning:

1 Like