Use balena CLI for pushing to balenaCloud

Updates the circle CI configuration to use the balena CLI to build the
supervisor image and deploy directly to the related balenaCloud app on merge
to master. This allows to build the supervisor as any other app,
including the posibility of creating a contract and a docker-compose

Change-type: patch
This commit is contained in:
Felipe Lalanne 2021-09-23 14:45:36 +00:00
parent 191e47344d
commit 458e2a16cf
2 changed files with 104 additions and 34 deletions

View File

@ -9,7 +9,6 @@
# * TAG: The default will be the current branch name
# * PUSH_IMAGES
# * CLEANUP
# * MIXPANEL_TOKEN: default key to inject in the supervisor image
# * EXTRA_TAG: when PUSH_IMAGES is true, additional tag to push to the registries
#
# Builds the supervisor for the architecture defined by $ARCH.
@ -45,12 +44,12 @@ if ! [ -x "$(command -v npx)" ]; then
exit 1
fi
PROJECT_NAME="${PROJECT_NAME:-${ARCH}-supervisor}"
SERVICE_NAME="${SERVICE_NAME:-main}"
# This is the supervisor image we will produce
TARGET_IMAGE=balena/$ARCH-supervisor:$TAG
TARGET_BUILD_IMAGE=balena/$ARCH-supervisor:$TAG-build
MASTER_IMAGE=balena/$ARCH-supervisor:master
MASTER_BUILD_IMAGE=balena/$ARCH-supervisor:master-build
CACHE_FROM=""
function useCache() {
@ -88,25 +87,50 @@ function processDockerfile() {
fi
}
function deviceType() {
case ${ARCH} in
aarch64)
echo "raspberrypi4-64"
;;
armv7hf)
echo "raspberrypi3"
;;
rpi)
echo "raspberry-pi"
;;
i386)
echo "qemux86"
;;
amd64)
echo "intel-nuc"
;;
*)
echo "unrecognized architecture ${ARCH}"
exit 1
;;
esac
}
export ARCH
useCache "${TARGET_IMAGE}"
useCache "${TARGET_BUILD_IMAGE}"
useCache "${MASTER_IMAGE}"
useCache "${MASTER_BUILD_IMAGE}"
# Wait for our cache to be downloaded
wait
BUILD_ARGS="$CACHE_FROM --build-arg ARCH=${ARCH}"
# Try to build the first stage
processDockerfile | docker build -f - -t "${TARGET_BUILD_IMAGE}" --target BUILD ${BUILD_ARGS} .
BUILD_ARGS="$CACHE_FROM --buildArg ARCH=$ARCH"
# Now try to build the final stage
processDockerfile | docker build -f - -t "${TARGET_IMAGE}" ${BUILD_ARGS} .
# Make a copy of the file to match the architecture
processDockerfile > Dockerfile.${ARCH}
# Build the image
balena build --deviceType $(deviceType) --arch ${ARCH} --dockerfile ./Dockerfile.${ARCH} \
--projectName ${PROJECT_NAME} --tag ${TAG} ${BUILD_ARGS}
if [ "${PUSH_IMAGES}" == "true" ]; then
retryImagePush "${TARGET_BUILD_IMAGE}" &
# Tag the CLI generated image with the target
docker tag "${PROJECT_NAME}_${SERVICE_NAME}:${TAG}" ${TARGET_IMAGE}
retryImagePush "${TARGET_IMAGE}" &
if [ -n "${EXTRA_TAG}" ]; then
@ -121,7 +145,6 @@ wait
if [ "$CLEANUP" = "true" ]; then
docker rmi \
"${TARGET_IMAGE}" \
"${TARGET_BUILD_IMAGE}" \
"${MASTER_IMAGE}" \
"${MASTER_BUILD_IMAGE}"
"${MASTER_IMAGE}"
fi

View File

@ -8,7 +8,7 @@ defaults: &defaults
version: 18.09.3
docker_layer_caching: true
- run:
name: Check docker is running and install git
name: Check docker is running and install dependencies
command: |
docker info
apk update && apk upgrade && apk add --no-cache \
@ -19,9 +19,15 @@ defaults: &defaults
nodejs \
nodejs-npm \
openssh-client
- run:
name: Install balena CLI and test it
command: |
apk add --no-cache curl python3 g++ linux-headers && \
npm install balena-cli -g --production --unsafe-perm && \
balena version -v
- checkout
- run:
name: Initialize the submodules (yocto layers)
name: Initialize the submodules
command: |
git submodule update --init --recursive
git clean -fxd base-image
@ -43,15 +49,41 @@ defaults: &defaults
else
export PUSH_IMAGES=false
fi
# start the build for this architecture
if [ "$PRODUCTION_API_TOKEN" != "" ]; then
balena login --token $PRODUCTION_API_TOKEN
export DEPLOY_TO_PRODUCTION=${DEPLOY_TO_PRODUCTION}
else
export DEPLOY_TO_PRODUCTION=false
fi
if [ "$STAGING_API_TOKEN" != "" ]; then
export DEPLOY_TO_PRODUCTION=${DEPLOY_TO_STAGING}
else
export DEPLOY_TO_STAGING=false
fi
# Create required env vars
export TAG=$(echo ${CIRCLE_BRANCH} | sed 's/[^a-z0-9A-Z_.-]/-/g')
export ARCH=${ARCH}
bash automation/build.sh
if [ "${CIRCLE_BRANCH}" = "master" ] && [ "${DEPLOY_TO_BALENA}" = "true" ]; then
export PROJECT_NAME=${ARCH}-supervisor
export SERVICE_NAME=main
# start the build for this architecture
bash -x automation/build.sh
if [ "${CIRCLE_BRANCH}" = "master" ] && [ "${DEPLOY_TO_STAGING}" = "true" ]; then
echo "Deploying to balena API (staging)"
ARCH=${ARCH} TAG=$VERSION_TAG API_KEY=$STAGING_API_KEY API_ENDPOINT=$STAGING_API_ENDPOINT node automation/deploy-to-balena-cloud.js
BALENARC_BALENA_URL=$STAGING_API_ENDPOINT balena login --token $STAGING_API_TOKEN
BALENARC_BALENA_URL=$STAGING_API_ENDPOINT balena deploy ${BALENA_OS_ORG}/${PROJECT_NAME} \
--projectName ${PROJECT_NAME} --tag ${TAG} \
--release-tag gh_branch ${TAG} version ${VERSION_TAG}
# Cleanup credentials just in case
rm ~/.balena/token
fi
if [ "${CIRCLE_BRANCH}" = "master" ] && [ "${DEPLOY_TO_PRODUCTION}" = "true" ]; then
echo "Deploying to balena API (production)"
ARCH=${ARCH} TAG=$VERSION_TAG API_KEY=$PRODUCTION_API_KEY API_ENDPOINT=$PRODUCTION_API_ENDPOINT node automation/deploy-to-balena-cloud.js
BALENARC_BALENA_URL=$PRODUCTION_API_ENDPOINT balena login --token $PRODUCTION_API_TOKEN
BALENARC_BALENA_URL=$PRODUCTION_API_ENDPOINT balena deploy ${BALENA_OS_ORG}/${PROJECT_NAME} \
--projectName ${PROJECT_NAME} --tag ${TAG} \
--release-tag gh_branch ${TAG} version ${VERSION_TAG}
# Cleanup credentials just in case
rm ~/.balena/token
fi
version: 2
@ -74,8 +106,8 @@ jobs:
DOCKER_USERNAME: travisciresin
ARCH: amd64
PUSH_IMAGES: 'true'
STAGING_API_ENDPOINT: https://api.balena-staging.com
PRODUCTION_API_ENDPOINT: https://api.balena-cloud.com
STAGING_API_ENDPOINT: balena-staging.com
PRODUCTION_API_ENDPOINT: balena-cloud.com
DEBUG: ''
amd64:
<<: *defaults
@ -83,8 +115,11 @@ jobs:
DOCKER_USERNAME: travisciresin
ARCH: amd64
PUSH_IMAGES: 'true'
STAGING_API_ENDPOINT: https://api.balena-staging.com
PRODUCTION_API_ENDPOINT: https://api.balena-cloud.com
STAGING_API_ENDPOINT: balena-staging.com
PRODUCTION_API_ENDPOINT: balena-cloud.com
DEPLOY_TO_PRODUCTION: 'false'
DEPLOY_TO_STAGING: 'false'
BALENA_OS_ORG: 'balena_os'
DEBUG: ''
i386:
<<: *defaults
@ -92,8 +127,11 @@ jobs:
DOCKER_USERNAME: travisciresin
ARCH: i386
PUSH_IMAGES: 'true'
STAGING_API_ENDPOINT: https://api.balena-staging.com
PRODUCTION_API_ENDPOINT: https://api.balena-cloud.com
STAGING_API_ENDPOINT: balena-staging.com
PRODUCTION_API_ENDPOINT: balena-cloud.com
DEPLOY_TO_PRODUCTION: 'false'
DEPLOY_TO_STAGING: 'false'
BALENA_OS_ORG: 'balena_os'
DEBUG: ''
armv7hf:
<<: *defaults
@ -101,8 +139,11 @@ jobs:
DOCKER_USERNAME: travisciresin
ARCH: armv7hf
PUSH_IMAGES: 'true'
STAGING_API_ENDPOINT: https://api.balena-staging.com
PRODUCTION_API_ENDPOINT: https://api.balena-cloud.com
STAGING_API_ENDPOINT: balena-staging.com
PRODUCTION_API_ENDPOINT: balena-cloud.com
DEPLOY_TO_PRODUCTION: 'false'
DEPLOY_TO_STAGING: 'false'
BALENA_OS_ORG: 'balena_os'
DEBUG: ''
aarch64:
<<: *defaults
@ -110,8 +151,11 @@ jobs:
DOCKER_USERNAME: travisciresin
ARCH: aarch64
PUSH_IMAGES: 'true'
STAGING_API_ENDPOINT: https://api.balena-staging.com
PRODUCTION_API_ENDPOINT: https://api.balena-cloud.com
STAGING_API_ENDPOINT: balena-staging.com
PRODUCTION_API_ENDPOINT: balena-cloud.com
DEPLOY_TO_PRODUCTION: 'false'
DEPLOY_TO_STAGING: 'false'
BALENA_OS_ORG: 'balena_os'
DEBUG: ''
rpi:
<<: *defaults
@ -119,8 +163,11 @@ jobs:
DOCKER_USERNAME: travisciresin
ARCH: rpi
PUSH_IMAGES: 'true'
STAGING_API_ENDPOINT: https://api.balena-staging.com
PRODUCTION_API_ENDPOINT: https://api.balena-cloud.com
STAGING_API_ENDPOINT: balena-staging.com
PRODUCTION_API_ENDPOINT: balena-cloud.com
DEPLOY_TO_PRODUCTION: 'false'
DEPLOY_TO_STAGING: 'false'
BALENA_OS_ORG: 'balena_os'
DEBUG: ''
workflows: