mirror of
https://github.com/balena-io/open-balena.git
synced 2025-04-20 00:31:02 +00:00
Compare commits
No commits in common. "master" and "v4.0.20" have entirely different histories.
8
.github/actionlint.yaml
vendored
8
.github/actionlint.yaml
vendored
@ -1,8 +0,0 @@
|
||||
self-hosted-runner:
|
||||
# Labels of self-hosted runner in array of strings.
|
||||
labels:
|
||||
- "distro:jammy"
|
||||
# Configuration variables in array of strings defined in your repository or
|
||||
# organization. `null` means disabling configuration variables check.
|
||||
# Empty array means no configuration variable is allowed.
|
||||
config-variables: null
|
27
.github/renovate.json
vendored
27
.github/renovate.json
vendored
@ -1,27 +0,0 @@
|
||||
{
|
||||
"extends": ["github>balena-io/renovate-config"],
|
||||
"ignorePaths": [
|
||||
"**/node_modules/**",
|
||||
"**/bower_components/**",
|
||||
"**/vendor/**",
|
||||
"**/examples/**",
|
||||
"**/__tests__/**",
|
||||
"**/test/**",
|
||||
"**/tests/suites/**",
|
||||
"**/__fixtures__/**",
|
||||
"**/Dockerfile.template"
|
||||
],
|
||||
"customManagers": [
|
||||
{
|
||||
"customType": "regex",
|
||||
"fileMatch": [
|
||||
".*"
|
||||
],
|
||||
"matchStrings": [
|
||||
".*amiFilter=(?<packageName>.*?)\n(.*currentImageName=(?<currentDigest>.*?)\n)?(.*\n)?.*?(?<depName>[a-zA-Z0-9-_:]*)[ ]*?[:|=][ ]*?[\"|']?(?<currentValue>ami-[a-z0-9]{17})[\"|']?.*"
|
||||
],
|
||||
"datasourceTemplate": "aws-machine-image",
|
||||
"versioningTemplate": "aws-machine-image"
|
||||
}
|
||||
]
|
||||
}
|
19
.github/workflows/flowzone.yml
vendored
19
.github/workflows/flowzone.yml
vendored
@ -8,11 +8,6 @@ on:
|
||||
types: [opened, synchronize, closed]
|
||||
branches: [main, master]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: "write" # AWS GitHub OIDC required: write
|
||||
packages: read
|
||||
|
||||
jobs:
|
||||
flowzone:
|
||||
name: Flowzone
|
||||
@ -30,6 +25,15 @@ jobs:
|
||||
with:
|
||||
jobs_timeout_minutes: 60
|
||||
cloudflare_website: open-balena
|
||||
custom_runs_on: |
|
||||
[
|
||||
[
|
||||
"self-hosted",
|
||||
"Linux",
|
||||
"X64"
|
||||
]
|
||||
]
|
||||
|
||||
balena_slugs: |
|
||||
balena/open-balena
|
||||
|
||||
@ -46,3 +50,8 @@ jobs:
|
||||
github.event_name == 'pull_request_target'
|
||||
)) && github.event.action != 'closed'
|
||||
secrets: inherit
|
||||
with:
|
||||
environment: balena-cloud.com
|
||||
fleet: balena/open-balena
|
||||
# https://dash.cloudflare.com/001b3ed2352612aaa068aca1b0022736/balena-devices.com/dns
|
||||
dns_tld: balena-devices.com
|
||||
|
15
.github/workflows/renovate.json
vendored
15
.github/workflows/renovate.json
vendored
@ -1,15 +0,0 @@
|
||||
{
|
||||
"customManagers": [
|
||||
{
|
||||
"customType": "regex",
|
||||
"fileMatch": [
|
||||
".*"
|
||||
],
|
||||
"matchStrings": [
|
||||
".*amiFilter=(?<packageName>.*?)\n(.*currentImageName=(?<currentDigest>.*?)\n)?(.*\n)?.*?(?<depName>[a-zA-Z0-9-_:]*)[ ]*?[:|=][ ]*?[\"|']?(?<currentValue>ami-[a-z0-9]{17})[\"|']?.*"
|
||||
],
|
||||
"datasourceTemplate": "aws-machine-image",
|
||||
"versioningTemplate": "aws-machine-image"
|
||||
}
|
||||
]
|
||||
}
|
834
.github/workflows/tests.yml
vendored
834
.github/workflows/tests.yml
vendored
File diff suppressed because it is too large
Load Diff
@ -1,17 +0,0 @@
|
||||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
exclude: ^(.versionbot/|CHANGELOG.md|VERSION|README.md)
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
- id: check-yaml
|
||||
args: [--allow-multiple-documents]
|
||||
- id: check-added-large-files
|
||||
|
||||
- repo: https://github.com/shellcheck-py/shellcheck-py
|
||||
rev: v0.10.0.1
|
||||
hooks:
|
||||
- id: shellcheck
|
File diff suppressed because it is too large
Load Diff
2142
CHANGELOG.md
2142
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
56
Makefile
56
Makefile
@ -3,17 +3,15 @@ SHELL := bash
|
||||
# export all variables to child processes by default
|
||||
export
|
||||
|
||||
# include the .env file if it exists
|
||||
-include .env
|
||||
# Include the .env file
|
||||
include .env
|
||||
|
||||
BALENARC_NO_ANALYTICS ?= 1
|
||||
DNS_TLD ?= $(error DNS_TLD not set)
|
||||
ORG_UNIT ?= openBalena
|
||||
PRODUCTION_MODE ?= true
|
||||
STAGING_PKI ?= /usr/local/share/ca-certificates
|
||||
SUPERUSER_EMAIL ?= admin@$(DNS_TLD)
|
||||
TMPKI := $(shell mktemp)
|
||||
VERBOSE ?= false
|
||||
STAGING_PKI ?= /usr/local/share/ca-certificates
|
||||
PRODUCTION_MODE ?= true
|
||||
ORG_UNIT ?= openBalena
|
||||
SUPERUSER_EMAIL ?= admin@$(DNS_TLD)
|
||||
|
||||
.NOTPARALLEL: $(DOCKERCOMPOSE)
|
||||
|
||||
@ -41,45 +39,23 @@ ifneq ($(GANDI_API_TOKEN),)
|
||||
endif
|
||||
endif
|
||||
@rm -f .env
|
||||
@echo "BALENARC_NO_ANALYTICS=$(BALENARC_NO_ANALYTICS)" > .env
|
||||
@echo "DNS_TLD=$(DNS_TLD)" >> .env
|
||||
@echo "ORG_UNIT=$(ORG_UNIT)" >> .env
|
||||
@echo "PRODUCTION_MODE=$(PRODUCTION_MODE)" >> .env
|
||||
@echo "SUPERUSER_EMAIL=$(SUPERUSER_EMAIL)" >> .env
|
||||
@echo "VERBOSE=$(VERBOSE)" >> .env
|
||||
ifneq ($(ACME_EMAIL),)
|
||||
@echo "ACME_EMAIL=$(ACME_EMAIL)" >> .env
|
||||
endif
|
||||
ifneq ($(CLOUDFLARE_API_TOKEN),)
|
||||
@echo "CLOUDFLARE_API_TOKEN=$(CLOUDFLARE_API_TOKEN)" >> .env
|
||||
endif
|
||||
ifneq ($(GANDI_API_TOKEN),)
|
||||
@echo "PRODUCTION_MODE=$(PRODUCTION_MODE)" >> .env
|
||||
@echo "GANDI_API_TOKEN=$(GANDI_API_TOKEN)" >> .env
|
||||
endif
|
||||
ifneq ($(HAPROXY_CRT),)
|
||||
@echo "CLOUDFLARE_API_TOKEN=$(CLOUDFLARE_API_TOKEN)" >> .env
|
||||
@echo "ACME_EMAIL=$(ACME_EMAIL)" >> .env
|
||||
@echo "HAPROXY_CRT=$(HAPROXY_CRT)" >> .env
|
||||
endif
|
||||
ifneq ($(HAPROXY_KEY),)
|
||||
@echo "HAPROXY_KEY=$(HAPROXY_KEY)" >> .env
|
||||
endif
|
||||
ifneq ($(ROOT_CA),)
|
||||
@echo "ROOT_CA=$(ROOT_CA)" >> .env
|
||||
endif
|
||||
@$(MAKE) showenv
|
||||
|
||||
.PHONY: wait
|
||||
wait: ## Wait for service
|
||||
@until [[ $$(docker compose ps $(SERVICE) --format json | jq -r '.Health') =~ ^healthy$$ ]]; do printf '.'; sleep 3; done
|
||||
@printf '\n'
|
||||
|
||||
.PHONY: waitlog
|
||||
waitlog: ## Wait for log line
|
||||
@until docker compose logs $(SERVICE) | grep -Eq "$(LOG_STRING)"; do printf '.'; sleep 3; done
|
||||
|
||||
.PHONY: up
|
||||
up: config ## Start all services
|
||||
@docker compose up --build -d
|
||||
@$(MAKE) wait SERVICE=api
|
||||
@until [[ $$(docker compose ps api --format json | jq -r '.Health') =~ healthy ]]; do printf '.'; sleep 3; done
|
||||
@printf '\n'
|
||||
@$(MAKE) showenv
|
||||
@$(MAKE) showpass
|
||||
|
||||
@ -107,7 +83,6 @@ stop: down ## Alias for 'make down'
|
||||
.PHONY: restart
|
||||
restart: ## Restart all services
|
||||
@docker compose restart
|
||||
@$(MAKE) wait SERVICE=api
|
||||
|
||||
.PHONY: update
|
||||
update: # Pull and deploy latest changes from git
|
||||
@ -143,10 +118,11 @@ self-signed: ## Install self-signed CA certificates
|
||||
auto-pki: config # Start all services using LetsEncrypt and ACME
|
||||
@docker compose exec cert-manager rm -f /certs/export/chain.pem
|
||||
@docker compose up -d
|
||||
@$(MAKE) waitlog SERVICE=cert-manager LOG_STRING="/certs/export/chain.pem Certificate will not expire in [0-9] days"
|
||||
@$(MAKE) waitlog SERVICE=cert-manager LOG_STRING="subject=CN = ${DNS_TLD}"
|
||||
@$(MAKE) waitlog SERVICE=cert-manager LOG_STRING="issuer=C = US, O = Let's Encrypt, CN = .*"
|
||||
@$(MAKE) wait SERVICE=haproxy
|
||||
@until docker compose logs cert-manager | grep -Eq "/certs/export/chain.pem Certificate will not expire in [0-9] days"; do printf '.'; sleep 3; done
|
||||
@until docker compose logs cert-manager | grep -q "subject=CN = ${DNS_TLD}"; do printf '.'; sleep 3; done
|
||||
@until docker compose logs cert-manager | grep -q "issuer=C = US, O = Let's Encrypt, CN = R3"; do printf '.'; sleep 3; done
|
||||
@until [[ $$(docker compose ps haproxy --format json | jq -r '.Health') =~ healthy ]]; do printf '.'; sleep 3; done
|
||||
@printf '\n'
|
||||
@$(MAKE) showenv
|
||||
@$(MAKE) showpass
|
||||
|
||||
|
19
README.md
19
README.md
@ -16,23 +16,6 @@ images to your devices.
|
||||
|
||||
To learn more about openBalena, visit [balena.io/open][open-balena-website].
|
||||
|
||||
- [Features](#features)
|
||||
- [Getting Started](#getting-started)
|
||||
- [Compatibility](#compatibility)
|
||||
- [Documentation](#documentation)
|
||||
- [Getting Help](#getting-help)
|
||||
- [Contributing](#contributing)
|
||||
- [Roadmap](#roadmap)
|
||||
- [Differences between openBalena and balenaCloud](#differences-between-openbalena-and-balenacloud)
|
||||
- [License](#license)
|
||||
- [FAQ](#faq)
|
||||
- [How do you ensure continuity of openBalena? Are there security patches on openBalena?](#how-do-you-ensure-continuity-of-openbalena-are-there-security-patches-on-openbalena)
|
||||
- [How do you ensure the "Join" command actually works between openBalena and](#how-do-you-ensure-the-join-command-actually-works-between-openbalena-and)
|
||||
- [Is it "production ready"?](#is-it-production-ready)
|
||||
- [Can a new device type be added to openBalena?](#can-a-new-device-type-be-added-to-openbalena)
|
||||
- [Are there open-source UI dashboards from the community for openBalena?](#are-there-open-source-ui-dashboards-from-the-community-for-openbalena)
|
||||
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
@ -176,7 +159,7 @@ While we actually have some rather large fleets using openBalena, we consider it
|
||||
perpetually in "beta". This means potentially introducing breaking changes between
|
||||
releases.
|
||||
|
||||
### Can a new device type be added to openBalena?
|
||||
### Can new device type be added to openBalena?
|
||||
openBalena imports the following public [device-types] "out of the box". You can specify
|
||||
your own contracts repository by overriding `CONTRACTS_PUBLIC_REPO_NAME`,
|
||||
`CONTRACTS_PUBLIC_REPO_OWNER` and `IMAGE_STORAGE_BUCKET` environment variables on the API
|
||||
|
@ -23,4 +23,4 @@ data:
|
||||
- generic-amd64
|
||||
- genericx86-64-ext
|
||||
- intel-nuc
|
||||
version: 4.1.390
|
||||
version: 4.0.20
|
||||
|
@ -26,7 +26,7 @@ x-default-environment: &default-environment
|
||||
DB_PASSWORD: docker
|
||||
DB_USER: docker
|
||||
LOG_LEVEL: DEBUG
|
||||
PRODUCTION_MODE: 'true'
|
||||
PRODUCTION_MODE: 'false'
|
||||
|
||||
x-default-healthcheck-trait: &with-default-healthcheck
|
||||
healthcheck:
|
||||
@ -64,11 +64,11 @@ x-network-privileges-trait: &with-network-privileges
|
||||
- SYS_RESOURCE
|
||||
|
||||
x-base-service-definition: &base-service
|
||||
restart: 'unless-stopped'
|
||||
restart: unless-stopped
|
||||
# for docker-compose only, no effect on balenaCloud
|
||||
env_file:
|
||||
- .env
|
||||
tty: true # send syastemd logs from containers to stdout
|
||||
tty: 'true' # send syastemd logs from containers to stdout
|
||||
|
||||
services:
|
||||
# https://github.com/balena-io/open-balena-api
|
||||
@ -79,7 +79,7 @@ services:
|
||||
*with-default-privileges,
|
||||
*with-default-volumes,
|
||||
]
|
||||
image: balena/open-balena-api:35.0.0
|
||||
image: balena/open-balena-api:v23.3.0
|
||||
depends_on:
|
||||
- db
|
||||
- redis
|
||||
@ -110,7 +110,7 @@ services:
|
||||
TRUST_PROXY: 172.16.0.0/12
|
||||
VPN_PORT: 443
|
||||
WEBRESOURCES_S3_BUCKET: web-resources
|
||||
WEBRESOURCES_S3_REGION: 'us-east-1' # this is required for minio
|
||||
WEBRESOURCES_S3_REGION: "us-east-1" # this is required for minio
|
||||
|
||||
# https://github.com/balena-io/open-balena-registry
|
||||
registry:
|
||||
@ -119,7 +119,7 @@ services:
|
||||
*with-default-healthcheck,
|
||||
*with-default-privileges,
|
||||
]
|
||||
image: balena/open-balena-registry:2.41.25
|
||||
image: balena/open-balena-registry:v2.39.57
|
||||
volumes:
|
||||
- certs-data:/certs
|
||||
- resin-data:/balena
|
||||
@ -146,7 +146,7 @@ services:
|
||||
*with-network-privileges,
|
||||
*with-default-privileges,
|
||||
]
|
||||
image: balena/open-balena-vpn:11.32.6
|
||||
image: balena/open-balena-vpn:v11.30.22
|
||||
depends_on:
|
||||
- api
|
||||
environment:
|
||||
@ -156,13 +156,11 @@ services:
|
||||
VPN_PORT: 443
|
||||
# ensure correct service instance IP is registered with the API
|
||||
VPN_SERVICE_REGISTER_INTERFACE: eth0
|
||||
devices:
|
||||
- /dev/net/tun
|
||||
|
||||
# https://github.com/balena-io/open-balena-db
|
||||
db:
|
||||
<<: *base-service
|
||||
image: balena/open-balena-db:6.0.0
|
||||
image: balena/open-balena-db:v5.2.2
|
||||
volumes:
|
||||
- db-data:/var/lib/postgresql/data
|
||||
environment:
|
||||
@ -177,7 +175,7 @@ services:
|
||||
*with-default-healthcheck,
|
||||
*with-default-privileges,
|
||||
]
|
||||
image: balena/open-balena-s3:2.28.68
|
||||
image: balena/open-balena-s3:v2.28.44
|
||||
volumes:
|
||||
- s3-data:/export
|
||||
- certs-data:/certs
|
||||
@ -191,7 +189,7 @@ services:
|
||||
redis:
|
||||
<<: *base-service
|
||||
# https://redis.io/blog/what-redis-license-change-means-for-our-managed-service-providers/
|
||||
image: redis:7.4-alpine
|
||||
image: redis:7.2-alpine
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
healthcheck:
|
||||
@ -214,11 +212,11 @@ services:
|
||||
test: true | openssl s_client -connect localhost:443
|
||||
ports:
|
||||
# haproxy/http
|
||||
- '80:80/tcp'
|
||||
- "80:80/tcp"
|
||||
# haproxy/tcp-router
|
||||
- '443:443/tcp'
|
||||
- "443:443/tcp"
|
||||
# haproxy/stats
|
||||
- '1936:1936/tcp'
|
||||
- "1936:1936/tcp"
|
||||
environment:
|
||||
LOGLEVEL: info
|
||||
|
||||
@ -235,7 +233,7 @@ services:
|
||||
ALIASES: api,ca,cloudlink,db,delta,logs,redis,registry2,s3,stats,tunnel
|
||||
labels:
|
||||
io.balena.features.balena-socket: 1
|
||||
io.balena.features.supervisor-api: 1
|
||||
io.balena.features.supervisor-api : 1
|
||||
|
||||
# https://github.com/balena-io/cert-manager
|
||||
# https://certbot.eff.org/docs/using.html
|
||||
@ -261,7 +259,7 @@ services:
|
||||
# https://github.com/cloudflare/cfssl/blob/master/doc/api/intro.txt
|
||||
balena-ca:
|
||||
<<: *base-service
|
||||
image: balena/ca-private:0.0.15
|
||||
image: balena/ca-private:v0.0.14
|
||||
volumes:
|
||||
- pki-data:/pki
|
||||
- certs-data:/certs
|
||||
@ -283,7 +281,7 @@ services:
|
||||
# only relevant when running in AWS/EC2
|
||||
tag-sidecar:
|
||||
build: src/tag-sidecar
|
||||
restart: 'no'
|
||||
restart: no
|
||||
environment:
|
||||
ENABLED: 'true'
|
||||
labels:
|
||||
@ -310,7 +308,7 @@ services:
|
||||
labels:
|
||||
io.balena.features.balena-api: 1
|
||||
io.balena.features.supervisor-api: 1
|
||||
restart: 'no'
|
||||
restart: no
|
||||
|
||||
# virtual Device Under Test (DUT)
|
||||
dut:
|
||||
@ -335,7 +333,7 @@ services:
|
||||
- resin-data:/balena
|
||||
devices:
|
||||
- /dev/net/tun
|
||||
restart: 'no'
|
||||
restart: no
|
||||
|
||||
# https://hub.docker.com/_/docker
|
||||
# pseudo(builder) service for balena-tests
|
||||
@ -346,23 +344,11 @@ services:
|
||||
*with-network-privileges,
|
||||
]
|
||||
image: docker:dind
|
||||
entrypoint:
|
||||
- /bin/sh
|
||||
- -c
|
||||
command:
|
||||
- |
|
||||
set -x
|
||||
|
||||
cp /certs/root-ca.pem /certs/server-ca.pem /usr/local/share/ca-certificates/ \
|
||||
&& update-ca-certificates
|
||||
|
||||
exec /usr/local/bin/dockerd-entrypoint.sh
|
||||
volumes:
|
||||
- /sys:/sys
|
||||
- builder-data:/var/lib/docker
|
||||
- builder-certs-ca:/docker-pki/ca
|
||||
- builder-certs-client:/docker-pki/client
|
||||
- builder-data:/var/lib/docker
|
||||
- certs-data:/certs
|
||||
- /sys:/sys
|
||||
environment:
|
||||
DOCKER_TLS_CERTDIR: /docker-pki
|
||||
healthcheck:
|
||||
|
@ -82,7 +82,7 @@ name and configure records.
|
||||
|
||||
```bash
|
||||
sudo useradd -s /bin/bash -m -G docker,sudo balena
|
||||
echo 'balena ALL=(ALL) NOPASSWD: ALL' | sudo tee /etc/sudoers.d/balena
|
||||
echo 'balena ALL=(ALL) NOPASSWD: ALL' | tee >/etc/sudoers.d/balena
|
||||
```
|
||||
|
||||
6. Switch user:
|
||||
|
@ -1,7 +1,7 @@
|
||||
FROM ubuntu:24.04
|
||||
|
||||
# renovate: datasource=github-releases depName=balena-io/balena-cli
|
||||
ARG BALENA_CLI_VERSION=v21.1.0
|
||||
ARG BALENA_CLI_VERSION=v18.2.2
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
bash \
|
||||
|
@ -1,24 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# shellcheck disable=SC2034,SC1090
|
||||
set -aeu
|
||||
# shellcheck disable=SC2154,SC2034,SC1090
|
||||
set -ae
|
||||
|
||||
read -ra curl_opts <<<'--retry 3 --fail'
|
||||
curl_opts="--retry 3 --fail"
|
||||
if [[ $VERBOSE =~ on|On|Yes|yes|true|True ]]; then
|
||||
set -x
|
||||
curl_opts+=('--verbose')
|
||||
curl_opts="${curl_opts} --verbose"
|
||||
else
|
||||
curl_opts+=('--silent')
|
||||
curl_opts="${curl_opts} --silent"
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
source /usr/sbin/functions
|
||||
|
||||
function remove_test_assets() {
|
||||
rm -rf /balena/config.json \
|
||||
"${GUEST_IMAGE}" \
|
||||
"${GUEST_IMAGE%.*}.ready" \
|
||||
"${tmpbuild:-}" \
|
||||
"${tmpbuild}" \
|
||||
/tmp/*.img
|
||||
}
|
||||
|
||||
@ -40,20 +39,18 @@ function shutdown_dut() {
|
||||
local balena_device_uuid
|
||||
balena_device_uuid="$(cat </balena/config.json | jq -r .uuid)"
|
||||
|
||||
if [[ -n "${balena_device_uuid:-}" ]]; then
|
||||
if [[ -n $balena_device_uuid ]]; then
|
||||
with_backoff balena device "${balena_device_uuid}"
|
||||
if ! with_backoff balena device shutdown -f "${balena_device_uuid}"; then
|
||||
echo 'DUT failed to shutdown properly'
|
||||
fi
|
||||
balena device shutdown -f "${balena_device_uuid}" || true
|
||||
fi
|
||||
}
|
||||
|
||||
function set_update_lock {
|
||||
if [[ -n "${BALENA_SUPERVISOR_ADDRESS:-}" ]] && [[ -n "${BALENA_SUPERVISOR_API_KEY:-}" ]]; then
|
||||
while [[ $(curl "${curl_opts[@]}" "${BALENA_SUPERVISOR_ADDRESS}/v1/device?apikey=${BALENA_SUPERVISOR_API_KEY}" \
|
||||
if [[ -n "$BALENA_SUPERVISOR_ADDRESS" ]] && [[ -n "$BALENA_SUPERVISOR_API_KEY" ]]; then
|
||||
while [[ $(curl ${curl_opts} "${BALENA_SUPERVISOR_ADDRESS}/v1/device?apikey=${BALENA_SUPERVISOR_API_KEY}" \
|
||||
-H "Content-Type: application/json" | jq -r '.update_pending') == 'true' ]]; do
|
||||
|
||||
curl "${curl_opts[@]}" "${BALENA_SUPERVISOR_ADDRESS}/v1/device?apikey=${BALENA_SUPERVISOR_API_KEY}" \
|
||||
curl ${curl_opts} "${BALENA_SUPERVISOR_ADDRESS}/v1/device?apikey=${BALENA_SUPERVISOR_API_KEY}" \
|
||||
-H "Content-Type: application/json" | jq -r
|
||||
|
||||
sleep "$(( (RANDOM % 3) + 3 ))s"
|
||||
@ -90,8 +87,7 @@ function update_ca_certificates() {
|
||||
}
|
||||
|
||||
function wait_for_api() {
|
||||
while ! curl "${curl_opts[@]}" "https://api.${DNS_TLD}/ping"; do
|
||||
echo 'waiting for API...'
|
||||
while ! curl ${curl_opts} "https://api.${DNS_TLD}/ping"; do
|
||||
sleep "$(( (RANDOM % 5) + 5 ))s"
|
||||
done
|
||||
}
|
||||
@ -100,7 +96,6 @@ function open_balena_login() {
|
||||
while ! balena login --credentials \
|
||||
--email "${SUPERUSER_EMAIL}" \
|
||||
--password "${SUPERUSER_PASSWORD}"; do
|
||||
echo 'waiting for auth...'
|
||||
sleep "$(( (RANDOM % 5) + 5 ))s"
|
||||
done
|
||||
}
|
||||
@ -109,7 +104,6 @@ function create_fleet() {
|
||||
if ! balena fleet "${TEST_FLEET}"; then
|
||||
# wait for API to load DT contracts
|
||||
while ! balena fleet create "${TEST_FLEET}" --type "${DEVICE_TYPE}"; do
|
||||
echo 'waiting for device types...'
|
||||
sleep "$(( (RANDOM % 5) + 5 ))s"
|
||||
done
|
||||
|
||||
@ -164,7 +158,7 @@ function check_device_status() {
|
||||
balena_device_uuid="$(cat </balena/config.json | jq -r .uuid)"
|
||||
|
||||
if [[ -n $balena_device_uuid ]]; then
|
||||
is_online="$(balena device list --json --fleet "${TEST_FLEET}" \
|
||||
is_online="$(balena devices --json --fleet "${TEST_FLEET}" \
|
||||
| jq -r --arg uuid "${balena_device_uuid}" '.[] | select(.uuid==$uuid).is_online == true')"
|
||||
|
||||
if [[ $is_online =~ true ]]; then
|
||||
@ -181,10 +175,9 @@ function wait_for_device() {
|
||||
}
|
||||
|
||||
function registry_auth() {
|
||||
if [[ -n "${REGISTRY_USER:-}" ]] && [[ -n "${REGISTRY_PASS:-}" ]]; then
|
||||
if [[ -n $REGISTRY_USER ]] && [[ -n $REGISTRY_PASS ]]; then
|
||||
with_backoff docker login -u "${REGISTRY_USER}" -p "${REGISTRY_PASS}"
|
||||
|
||||
# shellcheck disable=SC2016
|
||||
printf '{"https://index.docker.io/v1/": {"username":"%s", "password":"$s"}}' \
|
||||
"${REGISTRY_USER}" "${REGISTRY_PASS}" | jq -r > ~/.balena/secrets.json
|
||||
fi
|
||||
@ -208,29 +201,31 @@ function deploy_release() {
|
||||
}
|
||||
|
||||
function get_releases() {
|
||||
with_backoff balena release list --json "${TEST_FLEET}"
|
||||
with_backoff balena releases --json "${TEST_FLEET}"
|
||||
}
|
||||
|
||||
function get_release_commit() {
|
||||
get_releases | jq -re \
|
||||
'[.[] | select((.status=="success")
|
||||
and (.is_invalidated==false)
|
||||
and (.is_final==true))][0].commit'
|
||||
echo "$(get_releases)" | jq -re \
|
||||
'select((.[].status=="success")
|
||||
and (.[].is_invalidated==false)
|
||||
and (.[].is_final==true)
|
||||
and (.[].release_type=="final"))[0].commit'
|
||||
}
|
||||
|
||||
function get_release_id() {
|
||||
get_releases | jq -re \
|
||||
'[.[] | select((.status=="success")
|
||||
and (.is_invalidated==false)
|
||||
and (.is_final==true))][0].id'
|
||||
echo "$(get_releases)" | jq -re \
|
||||
'select((.[].status=="success")
|
||||
and (.[].is_invalidated==false)
|
||||
and (.[].is_final==true)
|
||||
and (.[].release_type=="final"))[0].id'
|
||||
}
|
||||
|
||||
function supervisor_update_target_state() {
|
||||
local balena_device_uuid
|
||||
balena_device_uuid="$(cat </balena/config.json | jq -r .uuid)"
|
||||
|
||||
if [[ -n "${balena_device_uuid:-}" ]]; then
|
||||
while ! curl "${curl_opts[@]}" "https://api.${DNS_TLD}/supervisor/v1/update" \
|
||||
if [[ -n $balena_device_uuid ]]; then
|
||||
while ! curl ${curl_opts} "https://api.${DNS_TLD}/supervisor/v1/update" \
|
||||
--header "Content-Type: application/json" \
|
||||
--header "Authorization: Bearer $(cat <~/.balena/token)" \
|
||||
--data "{\"uuid\": \"${balena_device_uuid}\", \"data\": {\"force\": true}}"; do
|
||||
@ -246,14 +241,14 @@ function check_running_release() {
|
||||
|
||||
local should_be_running_release
|
||||
should_be_running_release="$(get_release_commit)"
|
||||
[[ -z "$should_be_running_release" ]] && false
|
||||
[[ -z $should_be_running_release ]] && false
|
||||
|
||||
if [[ -n "${balena_device_uuid:-}" ]]; then
|
||||
if [[ -n $balena_device_uuid ]]; then
|
||||
while ! [[ $(balena device "${balena_device_uuid}" | grep -E ^COMMIT | awk '{print $2}') =~ ${should_be_running_release} ]]; do
|
||||
running_release_id="$(balena device "${balena_device_uuid}" | grep -E ^COMMIT | awk '{print $2}')"
|
||||
printf 'please wait, device %s should be running %s, but is still running %s...\n' \
|
||||
"${balena_device_uuid}" \
|
||||
"${should_be_running_release}" \
|
||||
"${1}" \
|
||||
"${running_release_id}"
|
||||
|
||||
sleep "$(( (RANDOM % 5) + 5 ))s"
|
||||
@ -263,7 +258,7 @@ function check_running_release() {
|
||||
|
||||
function get_os_version() {
|
||||
local BALENARC_BALENA_URL
|
||||
BALENARC_BALENA_URL="${BALENA_API_URL//https:\/\/api\./}"
|
||||
BALENARC_BALENA_URL="$(echo "${BALENA_API_URL}" | sed 's#https://api\.##g')"
|
||||
|
||||
local os_version
|
||||
os_version=${OS_VERSION:-$(with_backoff balena os versions "${DEVICE_TYPE}" | head -n 1)}
|
||||
@ -271,27 +266,27 @@ function get_os_version() {
|
||||
}
|
||||
|
||||
function upload_release_asset() {
|
||||
if [[ "${RELEASE_ASSETS_T:-}" =~ true ]]; then
|
||||
if [[ "$RELEASE_ASSETS_TEST" =~ true ]]; then
|
||||
local release_id
|
||||
release_id=${1:-1}
|
||||
release_asset="$(find / -type f -name '*.png' | head -n 1)"
|
||||
|
||||
curl "${curl_opts[@]}" "https://api.${DNS_TLD}/resin/release_asset" \
|
||||
curl ${curl_opts} "https://api.${DNS_TLD}/resin/release_asset" \
|
||||
--header "Authorization: Bearer $(cat <~/.balena/token)" \
|
||||
--form "asset=@${release_asset}" \
|
||||
--form "release=${release_id}" \
|
||||
--form "asset_key=$((RANDOM))-$(basename "${release_asset}")" \
|
||||
--form "asset_key=$((RANDOM))-$(basename ${release_asset})" \
|
||||
| jq -re .asset.href \
|
||||
| xargs curl "${curl_opts[@]}" -o "/tmp/$((RANDOM))-$(basename "${release_asset}")"
|
||||
| xargs curl ${curl_opts} -o "/tmp/$((RANDOM))-$(basename ${release_asset})"
|
||||
fi
|
||||
}
|
||||
|
||||
# --- main
|
||||
if [[ "${PRODUCTION_MODE:-}" =~ true ]]; then
|
||||
if [[ "$PRODUCTION_MODE" =~ true ]]; then
|
||||
exit
|
||||
fi
|
||||
|
||||
if [[ -n "${BALENA_DEVICE_UUID:-}" ]]; then
|
||||
if [[ -n "${BALENA_DEVICE_UUID}" ]]; then
|
||||
# prepend the device UUID if running on balenaOS
|
||||
TLD="${BALENA_DEVICE_UUID}.${DNS_TLD}"
|
||||
else
|
||||
@ -308,19 +303,7 @@ GUEST_IMAGE=${GUEST_IMAGE:-/balena/balena.img}
|
||||
OS_VERSION="$(get_os_version)"
|
||||
TEST_FLEET=${TEST_FLEET:-test-fleet}
|
||||
|
||||
# wait here until global config is ready
|
||||
until [[ -s "$CONF" ]]; do
|
||||
echo 'waiting for config...'
|
||||
sleep "$(( (RANDOM % 5) + 5 ))s"
|
||||
done
|
||||
source "${CONF}"
|
||||
|
||||
# wait her until we have valid login credentials
|
||||
until [[ -n "${SUPERUSER_EMAIL:-}" ]] && [[ -n "${SUPERUSER_PASSWORD:-}" ]]; do
|
||||
echo 'waiting for credentials...'
|
||||
sleep "$(( (RANDOM % 5) + 5 ))s"
|
||||
source "${CONF}"
|
||||
done
|
||||
[[ -f "$CONF" ]] && source "${CONF}"
|
||||
|
||||
update_ca_certificates # ensure self-signed root CA certificate(s) trust
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# https://github.com/balena-io/cert-manager
|
||||
FROM balena/cert-manager:0.3.2
|
||||
FROM balena/cert-manager:v0.2.2
|
||||
|
||||
COPY *.json /opt/
|
||||
|
@ -1,6 +1,6 @@
|
||||
# https://hub.docker.com/r/qemux/qemu-docker
|
||||
# https://github.com/qemus/qemu-docker
|
||||
FROM qemux/qemu-docker:6.20
|
||||
FROM qemux/qemu-docker:5.11
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
minicom \
|
||||
|
Loading…
x
Reference in New Issue
Block a user