mirror of
https://github.com/balena-io/open-balena.git
synced 2025-06-24 18:25:16 +00:00
Compare commits
47 Commits
Author | SHA1 | Date | |
---|---|---|---|
b92a3c8092 | |||
6250c85551 | |||
3898342a5b | |||
ab0b7467fd | |||
7cdce1a1c7 | |||
da4c1678ec | |||
6fdc700806 | |||
e6d0be1c74 | |||
a0ef371621 | |||
cd98a0df3f | |||
296a746e96 | |||
b3d184c13c | |||
3b9433e9cc | |||
763da0eb45 | |||
bfce474ff0 | |||
308322f774 | |||
c2077e5037 | |||
7790290d0e | |||
857e6b3bd7 | |||
cbee20731b | |||
eec16b843d | |||
a3126359e0 | |||
6438da8498 | |||
1f7ed769c0 | |||
41b1800166 | |||
77e3cfcdb6 | |||
d3f11819ce | |||
3816f09bc4 | |||
7154c5903f | |||
71a692b28b | |||
feeb830405 | |||
eb262fe9a2 | |||
6db5e59958 | |||
d33560755f | |||
f427982714 | |||
b99e497ac9 | |||
de0293563f | |||
17419557a5 | |||
c58ee37f17 | |||
d67e29223f | |||
08a990d32d | |||
d70c2177ff | |||
2a7d0687a2 | |||
e6c865e383 | |||
617209dc9e | |||
853ffb33e8 | |||
a029160caf |
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@ -1,2 +1,2 @@
|
||||
# Main repo owners:
|
||||
* @dfunckt @richbayliss
|
||||
* @dfunckt
|
||||
|
7
.gitignore
vendored
7
.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
.DS_Store
|
||||
.project
|
||||
.vagrant/
|
||||
config/
|
||||
src/
|
||||
package-lock.json
|
||||
|
||||
/config
|
||||
/docker-compose.yml
|
||||
/package-lock.json
|
||||
|
File diff suppressed because it is too large
Load Diff
1139
CHANGELOG.md
1139
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
90
README.md
90
README.md
@ -25,42 +25,25 @@ To learn more about openBalena, visit [balena.io/open][open-balena-website].
|
||||
- **Built-in VPN**: Access your devices regardless of their network environment
|
||||
|
||||
|
||||
## Roadmap
|
||||
|
||||
OpenBalena is currently in beta. While fully functional, it lacks features we
|
||||
consider important before we can comfortably call it production-ready. During
|
||||
this phase, don’t be alarmed if things don’t work as expected just yet (and
|
||||
please let us know about any bugs or errors you encounter!). The following
|
||||
improvements and new functionality is planned:
|
||||
|
||||
- Full documentation
|
||||
- Full test suite
|
||||
- Simplified deployment
|
||||
- Remote host OS updates
|
||||
- Support for custom device types
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
Everyone is welcome to contribute to openBalena. There are many different ways
|
||||
to get involved apart from submitting pull requests, including helping other
|
||||
users on the [forums][forums], reporting or triaging [issues][issue-tracker],
|
||||
reviewing and discussing [pull requests][pulls], or just spreading the word.
|
||||
|
||||
All of openBalena is hosted on GitHub. Apart from its constituent components,
|
||||
which are the [API][open-balena-api], [VPN][open-balena-vpn], [Registry][open-balena-registry],
|
||||
[S3 storage service][open-balena-s3], and [Database][open-balena-db], contributions
|
||||
are also welcome to its client-side software such as the [balena CLI][balena-cli],
|
||||
the [balena SDK][balena-sdk], [balenaOS][balena-os] and [balenaEngine][balena-engine].
|
||||
|
||||
|
||||
## Getting Started
|
||||
|
||||
Our [Getting Started][getting-started] guide is the most direct path to getting
|
||||
Our [Getting Started guide][getting-started] is the most direct path to getting
|
||||
an openBalena installation up and running and successfully deploying your
|
||||
application to your device(s).
|
||||
|
||||
|
||||
## Compatibility
|
||||
|
||||
The current release of openBalena has the following minimum version requirements:
|
||||
|
||||
- balenaOS v2.58.3
|
||||
- balena CLI v12.38.5
|
||||
|
||||
If you are updating from previous openBalena versions, ensure you update the balena
|
||||
CLI and reprovision any devices to at least the minimum required versions in order
|
||||
for them to be fully compatible with this release, as some features may not work.
|
||||
|
||||
|
||||
## Documentation
|
||||
|
||||
While we're still working on the project documentation, please refer to the
|
||||
@ -89,6 +72,53 @@ for help, or contribute by answering questions posted by fellow openBalena users
|
||||
Please do not use the issue tracker for support-related questions.
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
Everyone is welcome to contribute to openBalena. There are many different ways
|
||||
to get involved apart from submitting pull requests, including helping other
|
||||
users on the [forums][forums], reporting or triaging [issues][issue-tracker],
|
||||
reviewing and discussing [pull requests][pulls], or just spreading the word.
|
||||
|
||||
All of openBalena is hosted on GitHub. Apart from its constituent components,
|
||||
which are the [API][open-balena-api], [VPN][open-balena-vpn], [Registry][open-balena-registry],
|
||||
[S3 storage service][open-balena-s3], and [Database][open-balena-db], contributions
|
||||
are also welcome to its client-side software such as the [balena CLI][balena-cli],
|
||||
the [balena SDK][balena-sdk], [balenaOS][balena-os] and [balenaEngine][balena-engine].
|
||||
|
||||
|
||||
## Roadmap
|
||||
|
||||
OpenBalena is currently in beta. While fully functional, it lacks features we
|
||||
consider important before we can comfortably call it production-ready. During
|
||||
this phase, don’t be alarmed if things don’t work as expected just yet (and
|
||||
please let us know about any bugs or errors you encounter!). The following
|
||||
improvements and new functionality is planned:
|
||||
|
||||
- Full documentation
|
||||
- Full test suite
|
||||
- Simplified deployment
|
||||
- Remote host OS updates
|
||||
- Support for custom device types
|
||||
|
||||
|
||||
## Differences between openBalena and balenaCloud
|
||||
|
||||
| openBalena | balenaCloud |
|
||||
| ----- | ---- |
|
||||
| Device updates using full images | Device updates using [delta images](https://www.balena.io/docs/learn/deploy/delta/) |
|
||||
| Support for a single user | Support for [multiple users](https://www.balena.io/docs/learn/manage/account/#application-members) |
|
||||
| Self-hosted deployment and scaling | balena-managed scaling and deployment |
|
||||
| Community support via [forums][forums] | Private support on [paid plans](https://www.balena.io/pricing/) |
|
||||
| Deploy via `balena deploy` only | Build remotely with native builders using [`balena push`](https://www.balena.io/docs/learn/deploy/deployment/#balena-push) or [`git push`](https://www.balena.io/docs/learn/deploy/deployment/#git-push) |
|
||||
| No support for building via `git push` | Use the same CI workflow with [`git push`](https://www.balena.io/docs/learn/deploy/deployment/#git-push) |
|
||||
| No public URL support | Serve websites directly from device with [public device URLs](https://www.balena.io/docs/learn/manage/actions/#enable-public-device-url) |
|
||||
| Management via `balena-cli` only | Cloud-based device management dashboard |
|
||||
| Download images from [balena.io][balena-os-website] | Download preconfigured images directly from the dashboard |
|
||||
| No supported remote diagnostics | Remote device diagnostics |
|
||||
|
||||
Additionally, refer back to the [roadmap](#roadmap) above for planned but not yet implemented features.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
OpenBalena is licensed under the terms of AGPL v3. See [LICENSE](LICENSE) for details.
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: '2.1'
|
||||
version: "2.0"
|
||||
|
||||
services:
|
||||
component:
|
||||
|
31
compose/mdns.yml
Normal file
31
compose/mdns.yml
Normal file
@ -0,0 +1,31 @@
|
||||
version: "2.0"
|
||||
|
||||
services:
|
||||
balena-mdns-publisher:
|
||||
image: balena/balena-mdns-publisher:${OPENBALENA_MDNS_PUBLISHER_VERSION_TAG}
|
||||
network_mode: "host"
|
||||
cap_add:
|
||||
- SYS_RESOURCE
|
||||
- SYS_ADMIN
|
||||
security_opt:
|
||||
- apparmor:unconfined
|
||||
tmpfs:
|
||||
- /run
|
||||
- /sys/fs/cgroup
|
||||
# balenaOS - Required for host DBus comms. Not required for standalone Linux
|
||||
labels:
|
||||
io.balena.features.dbus: '1'
|
||||
io.balena.features.supervisor-api: '1'
|
||||
environment:
|
||||
CONFD_BACKEND: ENV
|
||||
# The name of the TLD to use. This *must* match certificates used for the rest of
|
||||
# the resin backend (eg. that for BALENA_ROOT_CA if present).
|
||||
MDNS_TLD: ${OPENBALENA_HOST_NAME}
|
||||
# List of subdomains to advertise. This must include all required hosts.
|
||||
MDNS_SUBDOMAINS: '["api", "db", "registry", "s3", "tunnel", "vpn"]'
|
||||
# The expectation is the DBus socket to use is always at the following location.
|
||||
DBUS_SESSION_BUS_ADDRESS: "unix:path=/host/run/dbus/system_bus_socket"
|
||||
# Selects the interface used for incoming connections from the wider subnet.
|
||||
# For NUCs, this is `eno1`. If running natively, pick the appropriate interface.
|
||||
# Alternatively, keep the default commented out to autoselect.
|
||||
#INTERFACE: "eno1"
|
@ -1,4 +1,4 @@
|
||||
version: "2.1"
|
||||
version: "2.0"
|
||||
|
||||
volumes:
|
||||
certs: {}
|
||||
@ -13,7 +13,7 @@ services:
|
||||
extends:
|
||||
file: ./common.yml
|
||||
service: component
|
||||
image: balena/open-balena-api:${OPENBALENA_API_VERSION_TAG:-master}
|
||||
image: balena/open-balena-api:${OPENBALENA_API_VERSION_TAG}
|
||||
depends_on:
|
||||
- db
|
||||
- s3
|
||||
@ -32,7 +32,7 @@ services:
|
||||
HOST: api.${OPENBALENA_HOST_NAME}
|
||||
IMAGE_MAKER_URL: img.${OPENBALENA_HOST_NAME}
|
||||
IMAGE_STORAGE_BUCKET: resin-production-img-cloudformation
|
||||
IMAGE_STORAGE_PREFIX: resinos
|
||||
IMAGE_STORAGE_PREFIX: images
|
||||
IMAGE_STORAGE_ENDPOINT: s3.amazonaws.com
|
||||
JSON_WEB_TOKEN_EXPIRY_MINUTES: 10080
|
||||
JSON_WEB_TOKEN_SECRET: ${OPENBALENA_JWT_SECRET}
|
||||
@ -44,7 +44,7 @@ services:
|
||||
REDIS_PORT: 6379
|
||||
REGISTRY2_HOST: registry.${OPENBALENA_HOST_NAME}
|
||||
REGISTRY_HOST: registry.${OPENBALENA_HOST_NAME}
|
||||
SENTRY_DSN:
|
||||
SENTRY_DSN: ""
|
||||
TOKEN_AUTH_BUILDER_TOKEN: ${OPENBALENA_TOKEN_AUTH_BUILDER_TOKEN}
|
||||
TOKEN_AUTH_CERT_ISSUER: api.${OPENBALENA_HOST_NAME}
|
||||
TOKEN_AUTH_CERT_KEY: ${OPENBALENA_TOKEN_AUTH_KEY}
|
||||
@ -61,7 +61,7 @@ services:
|
||||
extends:
|
||||
file: ./common.yml
|
||||
service: component
|
||||
image: balena/open-balena-registry:${OPENBALENA_REGISTRY_VERSION_TAG:-master}
|
||||
image: balena/open-balena-registry:${OPENBALENA_REGISTRY_VERSION_TAG}
|
||||
depends_on:
|
||||
- s3
|
||||
- redis
|
||||
@ -73,15 +73,16 @@ services:
|
||||
BALENA_ROOT_CA: ${OPENBALENA_ROOT_CA}
|
||||
BALENA_TOKEN_AUTH_ISSUER: api.${OPENBALENA_HOST_NAME}
|
||||
BALENA_TOKEN_AUTH_REALM: https://api.${OPENBALENA_HOST_NAME}/auth/v1/token
|
||||
COMMON_REGION:
|
||||
COMMON_REGION: ${OPENBALENA_S3_REGION}
|
||||
REGISTRY2_CACHE_ENABLED: "false"
|
||||
REGISTRY2_CACHE_ADDR: 127.0.0.1:6379
|
||||
REGISTRY2_CACHE_DB: 0
|
||||
REGISTRY2_CACHE_MAXMEMORY_MB: 1024 # megabytes
|
||||
REGISTRY2_CACHE_MAXMEMORY_POLICY: allkeys-lru
|
||||
REGISTRY2_S3_BUCKET:
|
||||
REGISTRY2_S3_KEY:
|
||||
REGISTRY2_S3_SECRET:
|
||||
REGISTRY2_S3_REGION_ENDPOINT: ${OPENBALENA_S3_ENDPOINT}
|
||||
REGISTRY2_S3_BUCKET: ${OPENBALENA_REGISTRY2_S3_BUCKET}
|
||||
REGISTRY2_S3_KEY: ${OPENBALENA_S3_ACCESS_KEY}
|
||||
REGISTRY2_S3_SECRET: ${OPENBALENA_S3_SECRET_KEY}
|
||||
REGISTRY2_SECRETKEY: ${OPENBALENA_REGISTRY_SECRET_KEY}
|
||||
REGISTRY2_STORAGEPATH: /data
|
||||
|
||||
@ -89,7 +90,7 @@ services:
|
||||
extends:
|
||||
file: ./common.yml
|
||||
service: component
|
||||
image: balena/open-balena-vpn:${OPENBALENA_VPN_VERSION_TAG:-master}
|
||||
image: balena/open-balena-vpn:${OPENBALENA_VPN_VERSION_TAG}
|
||||
depends_on:
|
||||
- api
|
||||
cap_add:
|
||||
@ -101,7 +102,7 @@ services:
|
||||
BALENA_VPN_PORT: 443
|
||||
PRODUCTION_MODE: "${OPENBALENA_PRODUCTION_MODE}"
|
||||
RESIN_VPN_GATEWAY: 10.2.0.1
|
||||
SENTRY_DSN:
|
||||
SENTRY_DSN: ""
|
||||
VPN_HAPROXY_USEPROXYPROTOCOL: "true"
|
||||
VPN_OPENVPN_CA_CRT: ${OPENBALENA_VPN_CA}
|
||||
VPN_OPENVPN_SERVER_CRT: ${OPENBALENA_VPN_SERVER_CRT}
|
||||
@ -113,7 +114,7 @@ services:
|
||||
extends:
|
||||
file: ./common.yml
|
||||
service: system
|
||||
image: balena/open-balena-db:${OPENBALENA_DB_VERSION_TAG:-master}
|
||||
image: balena/open-balena-db:${OPENBALENA_DB_VERSION_TAG}
|
||||
volumes:
|
||||
- db:/var/lib/postgresql/data
|
||||
|
||||
@ -121,12 +122,13 @@ services:
|
||||
extends:
|
||||
file: ./common.yml
|
||||
service: component
|
||||
image: balena/open-balena-s3:${OPENBALENA_S3_VERSION_TAG:-master}
|
||||
image: balena/open-balena-s3:${OPENBALENA_S3_VERSION_TAG}
|
||||
volumes:
|
||||
- s3:/export
|
||||
environment:
|
||||
S3_MINIO_ACCESS_KEY: abcdef1234
|
||||
S3_MINIO_SECRET_KEY: "1234567890"
|
||||
S3_MINIO_ACCESS_KEY: ${OPENBALENA_S3_ACCESS_KEY}
|
||||
S3_MINIO_SECRET_KEY: ${OPENBALENA_S3_SECRET_KEY}
|
||||
BUCKETS: ${OPENBALENA_S3_BUCKETS}
|
||||
|
||||
redis:
|
||||
extends:
|
||||
@ -140,7 +142,7 @@ services:
|
||||
extends:
|
||||
file: ./common.yml
|
||||
service: system
|
||||
build: ../haproxy
|
||||
build: ../src/haproxy
|
||||
depends_on:
|
||||
- api
|
||||
- cert-provider
|
||||
@ -152,9 +154,9 @@ services:
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "3128:3128"
|
||||
expose:
|
||||
- "222"
|
||||
- "3128"
|
||||
- "5432"
|
||||
- "6379"
|
||||
networks:
|
||||
@ -166,6 +168,7 @@ services:
|
||||
- db.${OPENBALENA_HOST_NAME}
|
||||
- s3.${OPENBALENA_HOST_NAME}
|
||||
- redis.${OPENBALENA_HOST_NAME}
|
||||
- tunnel.${OPENBALENA_HOST_NAME}
|
||||
environment:
|
||||
BALENA_HAPROXY_CRT: ${OPENBALENA_ROOT_CRT}
|
||||
BALENA_HAPROXY_KEY: ${OPENBALENA_ROOT_KEY}
|
||||
@ -175,11 +178,11 @@ services:
|
||||
- certs:/certs:ro
|
||||
|
||||
cert-provider:
|
||||
build: ../cert-provider
|
||||
build: ../src/cert-provider
|
||||
volumes:
|
||||
- certs:/certs
|
||||
- cert-provider:/usr/src/app/certs
|
||||
environment:
|
||||
ACTIVE: ${OPENBALENA_ACME_CERT_ENABLED}
|
||||
DOMAINS: "api.${OPENBALENA_HOST_NAME},registry.${OPENBALENA_HOST_NAME},s3.${OPENBALENA_HOST_NAME},vpn.${OPENBALENA_HOST_NAME}"
|
||||
DOMAINS: "api.${OPENBALENA_HOST_NAME},registry.${OPENBALENA_HOST_NAME},s3.${OPENBALENA_HOST_NAME},vpn.${OPENBALENA_HOST_NAME},tunnel.${OPENBALENA_HOST_NAME}"
|
||||
OUTPUT_PEM: /certs/open-balena.pem
|
||||
|
@ -7,4 +7,4 @@
|
||||
# `compose/services.yml` as the "base" config.
|
||||
#
|
||||
# You may view the effective config with `scripts/compose config`.
|
||||
version: '2.1'
|
||||
version: "2.0"
|
||||
|
@ -1,5 +1,6 @@
|
||||
export OPENBALENA_API_VERSION_TAG=v0.19.5
|
||||
export OPENBALENA_DB_VERSION_TAG=v2.0.3
|
||||
export OPENBALENA_REGISTRY_VERSION_TAG=v2.7.0
|
||||
export OPENBALENA_S3_VERSION_TAG=v2.6.2
|
||||
export OPENBALENA_VPN_VERSION_TAG=v8.10.0
|
||||
export OPENBALENA_API_VERSION_TAG=v0.119.5
|
||||
export OPENBALENA_DB_VERSION_TAG=v4.1.0
|
||||
export OPENBALENA_MDNS_PUBLISHER_VERSION_TAG=v1.9.2
|
||||
export OPENBALENA_REGISTRY_VERSION_TAG=v2.14.4
|
||||
export OPENBALENA_S3_VERSION_TAG=v2.9.9
|
||||
export OPENBALENA_VPN_VERSION_TAG=v9.17.4
|
||||
|
2
repo.yml
2
repo.yml
@ -11,3 +11,5 @@ upstream:
|
||||
url: https://github.com/balena-io/open-balena-db
|
||||
- repo: open-balena-s3
|
||||
url: https://github.com/balena-io/open-balena-s3
|
||||
- repo: balena-mdns-publisher
|
||||
url: https://github.com/balena-io/balena-mdns-publisher
|
||||
|
@ -22,7 +22,7 @@ done
|
||||
if [ -z "${REALPATH}" ]; then
|
||||
echo_error 'Unable to find suitable command for realpath.'
|
||||
if [ $(uname) == 'Darwin' ]; then
|
||||
echo 'GNU coreutils are required to build openBalena on MacOS. To install with brew, run'
|
||||
echo 'GNU coreutils are required to build openBalena on macOS. To install with brew, run'
|
||||
echo ''
|
||||
echo ' brew install coreutils'
|
||||
echo ''
|
||||
|
@ -11,6 +11,10 @@ echo_bold() {
|
||||
printf "\\033[1m%s\\033[0m\\n" "$@"
|
||||
}
|
||||
|
||||
echo_bold_stderr() {
|
||||
printf "\\033[1m%s\\033[0m\\n" "$@" 1>&2
|
||||
}
|
||||
|
||||
VERSIONS_FILE="${BASE_DIR}/compose/versions"
|
||||
if [ ! -f "$VERSIONS_FILE" ]; then
|
||||
echo_bold "No service versions defined in ${VERSIONS_FILE}"
|
||||
@ -24,9 +28,20 @@ if [ ! -f "$ENV_FILE" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
source "${ENV_FILE}"
|
||||
|
||||
# only include the MDNS publisher IF the domain is valid...
|
||||
if [ ${OPENBALENA_HOST_NAME: -6} == ".local" ]; then
|
||||
INCLUDE_MDNS="-f ${BASE_DIR}/compose/mdns.yml"
|
||||
fi
|
||||
|
||||
# show a warning to update your balena CLI tool...
|
||||
echo_bold_stderr "IMPORTANT: Please update your Balena CLI installation to version v12.38.5"
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
source "${VERSIONS_FILE}"; source "${ENV_FILE}"; docker-compose \
|
||||
source "${VERSIONS_FILE}"; docker-compose \
|
||||
--project-name 'openbalena' \
|
||||
-f "${BASE_DIR}/compose/services.yml" \
|
||||
${INCLUDE_MDNS} \
|
||||
-f "${CONFIG_DIR}/docker-compose.yml" \
|
||||
"$@"
|
||||
|
62
scripts/logger.sh
Normal file
62
scripts/logger.sh
Normal file
@ -0,0 +1,62 @@
|
||||
#!/bin/sh
|
||||
|
||||
BLACK=`tput setaf 0`
|
||||
RED=`tput setaf 1`
|
||||
GREEN=`tput setaf 2`
|
||||
YELLOW=`tput setaf 3`
|
||||
BLUE=`tput setaf 4`
|
||||
MAGENTA=`tput setaf 5`
|
||||
CYAN=`tput setaf 6`
|
||||
WHITE=`tput setaf 7`
|
||||
|
||||
BOLD=`tput bold`
|
||||
RESET=`tput sgr0`
|
||||
|
||||
log_raw () {
|
||||
local COLOR="${WHITE}"
|
||||
local LEVEL="${1}"
|
||||
local MESSAGE="${2}"
|
||||
case "${LEVEL}" in
|
||||
info)
|
||||
COLOR="${BLUE}"
|
||||
;;
|
||||
warn)
|
||||
COLOR="${YELLOW}"
|
||||
;;
|
||||
fatal)
|
||||
COLOR="${RED}"
|
||||
;;
|
||||
*)
|
||||
LEVEL="debug"
|
||||
;;
|
||||
esac
|
||||
LEVEL="${LEVEL} "
|
||||
echo "[$(date +%T)] ${COLOR}$(echo "${LEVEL:0:5}" | tr '[:lower:]' '[:upper:]')${RESET} ${MESSAGE}";
|
||||
}
|
||||
|
||||
log () {
|
||||
log_raw "debug" "${1}"
|
||||
}
|
||||
|
||||
info () {
|
||||
log_raw "info" "${1}";
|
||||
}
|
||||
|
||||
warn () {
|
||||
log_raw "warn" "${1}";
|
||||
}
|
||||
|
||||
die () {
|
||||
log_raw "fatal" "${1}";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
die_unless_forced () {
|
||||
if [ ! -z "$1" ]; then
|
||||
log_raw "warn" "$2";
|
||||
return;
|
||||
fi
|
||||
|
||||
log_raw "fatal" "$2";
|
||||
die "Use -f to forcibly upgrade.";
|
||||
}
|
@ -40,11 +40,15 @@ b64file() {
|
||||
b64encode "$(cat "$@")"
|
||||
}
|
||||
|
||||
# buckets to create in the S3 service...
|
||||
REGISTRY2_S3_BUCKET="registry-data"
|
||||
|
||||
cat <<STR
|
||||
export OPENBALENA_PRODUCTION_MODE=false
|
||||
export OPENBALENA_COOKIE_SESSION_SECRET=$(randstr 32)
|
||||
export OPENBALENA_HOST_NAME=$DOMAIN
|
||||
export OPENBALENA_JWT_SECRET=$(randstr 32)
|
||||
export OPENBALENA_REGISTRY2_S3_BUCKET=${REGISTRY2_S3_BUCKET}
|
||||
export OPENBALENA_RESINOS_REGISTRY_CODE=$(randstr 32)
|
||||
export OPENBALENA_ROOT_CA=$(b64file "${ROOT_CA}")
|
||||
export OPENBALENA_ROOT_CRT=$(b64file "${ROOT_CRT}")
|
||||
@ -61,6 +65,11 @@ export OPENBALENA_VPN_SERVER_DH=$(b64file "$VPN_DH")
|
||||
export OPENBALENA_VPN_SERVICE_API_KEY=$(randstr 32)
|
||||
export OPENBALENA_API_VPN_SERVICE_API_KEY=$(randstr 32)
|
||||
export OPENBALENA_REGISTRY_SECRET_KEY=$(randstr 32)
|
||||
export OPENBALENA_S3_ACCESS_KEY=$(randstr 32)
|
||||
export OPENBALENA_S3_BUCKETS="${REGISTRY2_S3_BUCKET}"
|
||||
export OPENBALENA_S3_ENDPOINT="https://s3.${DOMAIN}"
|
||||
export OPENBALENA_S3_REGION=us-east-1
|
||||
export OPENBALENA_S3_SECRET_KEY=$(randstr 32)
|
||||
export OPENBALENA_SSH_AUTHORIZED_KEYS=
|
||||
export OPENBALENA_SUPERUSER_EMAIL=$SUPERUSER_EMAIL
|
||||
export OPENBALENA_SUPERUSER_PASSWORD=$(printf "%q" "${SUPERUSER_PASSWORD}")
|
||||
|
29
scripts/migrate-registry-storage
Executable file
29
scripts/migrate-registry-storage
Executable file
@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
|
||||
migrate_data_to_s3 () {
|
||||
BUCKET="${1:-registry-data}"
|
||||
|
||||
if [ -z "${BUCKET}" ]; then return 1; fi
|
||||
|
||||
if [ -n "${DOCKER_HOST}" ]; then
|
||||
log "Using docker host: ${DOCKER_HOST}"
|
||||
export DOCKER_HOST="${DOCKER_HOST}"
|
||||
fi
|
||||
|
||||
REGISTRY_CONTAINER="$(docker ps | grep registry_ | awk '{print $1}')"
|
||||
S3_CONTAINER="$(docker ps | grep s3_ | awk '{print $1}')"
|
||||
|
||||
if [ -z "${REGISTRY_CONTAINER}" ] || [ -z "${S3_CONTAINER}" ]; then return 2; fi
|
||||
|
||||
REGISTRY_VOLUME="$(docker inspect "${REGISTRY_CONTAINER}" | jq -r '.[].Mounts | map(select(.Destination=="/data")) | .[0].Source')"
|
||||
S3_VOLUME=$(docker inspect "${S3_CONTAINER}" | jq -r '.[].Mounts | map(select(.Destination=="/export")) | .[0].Source')
|
||||
|
||||
if [ -z "${REGISTRY_VOLUME}" ] || [ -z "${S3_VOLUME}" ]; then return 3; fi
|
||||
|
||||
# run the S3 container image, and copy the data partition into S3...
|
||||
docker run -it --rm \
|
||||
-v "${REGISTRY_VOLUME}:/data" \
|
||||
-v "${S3_VOLUME}:/s3" \
|
||||
--name "migrate-registry" alpine \
|
||||
sh -c "mkdir -p /s3/${BUCKET}/data && cp -r /data/docker /s3/${BUCKET}/data/"
|
||||
}
|
@ -16,6 +16,12 @@ RESET=`tput sgr0`
|
||||
OPENSSL_VERSION=$(openssl version -v)
|
||||
if [[ "${OPENSSL_VERSION}" =~ ^LibreSSL.*$ ]]; then
|
||||
echo -e "${RED}ERROR: You may not have a compatible OpenSSL version (${OPENSSL_VERSION}). Please install OpenSSL version 1.0.2q or above.${RESET}"
|
||||
if [ $(uname) == 'Darwin' ]; then
|
||||
echo 'OpenSSL is required to build openBalena on macOS. To install with brew, run'
|
||||
echo ''
|
||||
echo ' brew install openssl'
|
||||
echo ''
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@ -125,7 +131,25 @@ fi
|
||||
echo_bold "==> Success!"
|
||||
echo ' - Start the instance with: ./scripts/compose up -d'
|
||||
echo ' - Stop the instance with: ./scripts/compose stop'
|
||||
echo ' - To create a single, flat, docker-compose.yml file, run:'
|
||||
echo ''
|
||||
echo ' ./scripts/compose config > docker-compose.yml'
|
||||
echo ''
|
||||
|
||||
if [ -z "${ACME_CERT_ENABLED}" ]; then
|
||||
echo " - Use the following certificate with Balena CLI: ${CERTS_DIR}/root/ca.crt"
|
||||
|
||||
case $(uname) in
|
||||
Darwin)
|
||||
echo ''
|
||||
printf ' On macOS:\n\n'
|
||||
printf ' sudo security add-trusted-cert -d -r trustRoot -k "/Library/Keychains/System.keychain" "%s/root/ca.crt"\n' "${CERTS_DIR}"
|
||||
echo ''
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -e " ${YELLOW}IMPORTANT:${RESET} You will need to restart your Docker daemon after trusting this certificate to allow your workstation to push images to the registry."
|
||||
echo ''
|
||||
fi
|
||||
|
78
scripts/upgrade-1.x-to-2.0
Executable file
78
scripts/upgrade-1.x-to-2.0
Executable file
@ -0,0 +1,78 @@
|
||||
#!/bin/sh
|
||||
|
||||
source "${BASH_SOURCE%/*}/logger.sh"
|
||||
source "${BASH_SOURCE%/*}/migrate-registry-storage"
|
||||
|
||||
# This script takes a v1.x.x install and updates the compose stack to use S3 as your
|
||||
# registry storage.
|
||||
|
||||
source "${BASH_SOURCE%/*}/_realpath"
|
||||
|
||||
DIR="$(dirname $(realpath "$0"))"
|
||||
BASE_DIR="$(dirname "${DIR}")"
|
||||
CONFIG_DIR="${BASE_DIR}/config"
|
||||
CONFIG_FILE="${CONFIG_DIR}/activate"
|
||||
|
||||
# Step 1. Make sure a config exists...
|
||||
[ -f "${CONFIG_FILE}" ] || die "Unable to find existing config!";
|
||||
|
||||
info "Preparing to upgrade..."
|
||||
source "${CONFIG_FILE}"
|
||||
|
||||
while getopts "f" opt; do
|
||||
case "${opt}" in
|
||||
f)
|
||||
warn "Forcing upgrade! I hope you know what you're doing..."
|
||||
FORCE_UPGRADE=1
|
||||
;;
|
||||
*)
|
||||
echo "Invalid argument: ${OPTARG}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
# Step 2. Check if the S3 configuration already exists...
|
||||
upgrade_required () {
|
||||
[ -z "${OPENBALENA_REGISTRY2_S3_BUCKET}" ] || return 1;
|
||||
[ -z "${OPENBALENA_S3_ACCESS_KEY}" ] || return 1;
|
||||
[ -z "${OPENBALENA_S3_ENDPOINT}" ] || return 1;
|
||||
[ -z "${OPENBALENA_S3_REGION}" ] || return 1;
|
||||
[ -z "${OPENBALENA_S3_SECRET_KEY}" ] || return 1;
|
||||
}
|
||||
upgrade_required || die_unless_forced "${FORCE_UPGRADE}" "Configuration may already be using S3 for Registry storage!"
|
||||
|
||||
# Step 3. Create missing S3 configuration...
|
||||
randstr() {
|
||||
LC_CTYPE=C tr -dc A-Za-z0-9 < /dev/urandom | fold -w "${1:-32}" | head -n 1
|
||||
}
|
||||
|
||||
upsert_config () {
|
||||
var="${1}"
|
||||
value="${2}"
|
||||
|
||||
if [ -z "${!var}" ]; then
|
||||
echo "export ${1}=${2}" >> "${CONFIG_FILE}"
|
||||
else
|
||||
sed -i '' "s~export ${1}=.*~export ${1}=${2}~" "${CONFIG_FILE}"
|
||||
fi
|
||||
}
|
||||
|
||||
upsert_config "OPENBALENA_REGISTRY2_S3_BUCKET" "registry-data" || warn "Failed to update config value OPENBALENA_REGISTRY2_S3_BUCKET"
|
||||
upsert_config "OPENBALENA_S3_ACCESS_KEY" "$(randstr 32)" || warn "Failed to update config value OPENBALENA_S3_ACCESS_KEY"
|
||||
upsert_config "OPENBALENA_S3_ENDPOINT" "https://s3.${OPENBALENA_HOST_NAME}" || warn "Failed to update config value OPENBALENA_S3_ENDPOINT"
|
||||
upsert_config "OPENBALENA_S3_REGION" "us-east-1" || warn "Failed to update config value OPENBALENA_S3_REGION"
|
||||
upsert_config "OPENBALENA_S3_SECRET_KEY" "$(randstr 32)" || warn "Failed to update config value OPENBALENA_S3_SECRET_KEY"
|
||||
|
||||
# Step 4. Migrate Registry data to S3...
|
||||
info "Copying data from the Registry volume to the S3 volume..."
|
||||
migrate_data_to_s3 "registry-data"
|
||||
case $? in
|
||||
1) die "Invalid bucket name";;
|
||||
2) die "Unable to find the running Registry or S3 containers";;
|
||||
3) die "Unable to determine the data volumes for the Registry or S3 containers";;
|
||||
*) info "Registry data copied"
|
||||
;;
|
||||
esac
|
||||
info "Upgrade complete"
|
@ -6,9 +6,11 @@ VOLUME [ "/usr/src/app/certs" ]
|
||||
|
||||
RUN apk add --update bash curl git openssl ncurses socat
|
||||
|
||||
# from https://github.com/Neilpang/acme.sh/releases/tag/2.8.5
|
||||
RUN git clone https://github.com/Neilpang/acme.sh.git && \
|
||||
cd acme.sh && \
|
||||
git checkout 08357e3cb0d80c84bdaf3e42ce0e439665387f57 . && \
|
||||
git fetch && git fetch --tags && \
|
||||
git checkout 2.8.5 . && \
|
||||
./acme.sh --install \
|
||||
--cert-home /usr/src/app/certs
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# the acme.sh client script, installed via Git in the Dockerfile...
|
||||
ACME_BIN="$(realpath ~/.acme.sh/acme.sh)"
|
||||
@ -45,14 +45,20 @@ retryWithDelay() {
|
||||
DELAY=${3:-5}
|
||||
|
||||
local ATTEMPT=0
|
||||
while [ $RETRIES -gt $ATTEMPT ]; do
|
||||
let "ATTEMPT++"
|
||||
while [ "$RETRIES" -gt "$ATTEMPT" ]; do
|
||||
(( ATTEMPT++ ))
|
||||
logInfo "($ATTEMPT/$RETRIES) Connecting..."
|
||||
if $1; then
|
||||
logInfo "($ATTEMPT/$RETRIES) Success!"
|
||||
return $?
|
||||
fi
|
||||
|
||||
echo "($ATTEMPT/$RETRIES) Retrying in ${DELAY} seconds..."
|
||||
sleep $DELAY
|
||||
if [ "$RETRIES" -gt "$ATTEMPT" ]; then
|
||||
logInfo "($ATTEMPT/$RETRIES) Failed. Retrying in ${DELAY} seconds..."
|
||||
sleep "$DELAY"
|
||||
else
|
||||
logInfo "($ATTEMPT/$RETRIES) Failed!"
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
@ -62,7 +68,7 @@ waitForOnline() {
|
||||
ADDRESS="${1,,}"
|
||||
|
||||
logInfo "Waiting for ${ADDRESS} to be available via HTTP..."
|
||||
retryWithDelay "curl --output /dev/null --silent --head --fail http://${ADDRESS}" 6 5
|
||||
retryWithDelay "curl --output /dev/null --silent --head --fail --max-time 5 http://${ADDRESS}"
|
||||
}
|
||||
|
||||
isUsingStagingCert() {
|
||||
@ -167,7 +173,10 @@ acquireCertificate() {
|
||||
|
||||
pre-flight || logErrorAndStop "Unable to continue due to misconfiguration. See errors above."
|
||||
|
||||
waitForOnline "${ACME_DOMAINS[0]}" || logErrorAndStop "Unable to access ${ACME_DOMAINS[0]} on port 80. This is needed for certificate validation."
|
||||
while ! waitForOnline "${ACME_DOMAINS[0]}"; do
|
||||
logInfo "Unable to access ${ACME_DOMAINS[0]} on port 80. This is needed for certificate validation. Retrying in 30 seconds..."
|
||||
sleep 30
|
||||
done
|
||||
|
||||
if ! lastAcquiredCertFor "production"; then
|
||||
acquireCertificate "staging" || logErrorAndStop "Unable to acquire a staging certificate."
|
@ -2,9 +2,9 @@ global
|
||||
tune.ssl.default-dh-param 1024
|
||||
|
||||
defaults
|
||||
timeout connect 5000
|
||||
timeout client 50000
|
||||
timeout server 50000
|
||||
timeout connect 5s
|
||||
timeout client 50s
|
||||
timeout server 50s
|
||||
|
||||
frontend http-in
|
||||
mode http
|
||||
@ -34,6 +34,10 @@ frontend ssl-in
|
||||
tcp-request content accept if { req.ssl_hello_type 1 }
|
||||
|
||||
acl is_ssl req.ssl_ver 2:3.4
|
||||
|
||||
acl host_tunnel req_ssl_sni -i "tunnel.${HAPROXY_HOSTNAME}"
|
||||
use_backend redirect-to-tunnel-in if host_tunnel
|
||||
|
||||
use_backend redirect-to-https-in if is_ssl
|
||||
use_backend vpn-devices if !is_ssl
|
||||
|
||||
@ -42,6 +46,11 @@ backend redirect-to-https-in
|
||||
balance roundrobin
|
||||
server localhost 127.0.0.1:444 send-proxy-v2
|
||||
|
||||
backend redirect-to-tunnel-in
|
||||
mode tcp
|
||||
balance roundrobin
|
||||
server localhost 127.0.0.1:3129
|
||||
|
||||
frontend https-in
|
||||
mode http
|
||||
option forwardfor
|
||||
@ -64,34 +73,35 @@ backend backend_api
|
||||
mode http
|
||||
option forwardfor
|
||||
balance roundrobin
|
||||
server resin_api_1 api:80 check port 80
|
||||
server balena_api_1 api:80 check port 80
|
||||
|
||||
backend backend_registry
|
||||
mode http
|
||||
option forwardfor
|
||||
balance roundrobin
|
||||
server resin_registry_1 registry:80 check port 80
|
||||
server balena_registry_1 registry:80 check port 80
|
||||
|
||||
backend backend_vpn
|
||||
mode http
|
||||
option forwardfor
|
||||
balance roundrobin
|
||||
server resin_vpn_1 vpn:80 check port 80
|
||||
server balena_vpn_1 vpn:80 check port 80
|
||||
|
||||
backend backend_s3
|
||||
mode http
|
||||
option forwardfor
|
||||
balance roundrobin
|
||||
server balena_s3_1 s3:80 check port 80
|
||||
|
||||
backend cert-provider
|
||||
mode http
|
||||
option forwardfor
|
||||
balance roundrobin
|
||||
server resin_cert-provider_1 cert-provider:80 no-check
|
||||
server balena_cert-provider_1 cert-provider:80 no-check
|
||||
|
||||
backend vpn-devices
|
||||
mode tcp
|
||||
server resin_vpn_1 vpn:443 send-proxy-v2 check-send-proxy port 443
|
||||
server balena_vpn_1 vpn:443 send-proxy-v2 check-send-proxy port 443
|
||||
|
||||
frontend db
|
||||
mode tcp
|
||||
@ -101,7 +111,7 @@ frontend db
|
||||
|
||||
backend backend_db
|
||||
mode tcp
|
||||
server resin_db_1 db:5432 check port 5432
|
||||
server balena_db_1 db:5432 check port 5432
|
||||
|
||||
frontend redis
|
||||
mode tcp
|
||||
@ -111,9 +121,14 @@ frontend redis
|
||||
|
||||
backend backend_redis
|
||||
mode tcp
|
||||
server resin_redis_1 redis:6379 check port 6379
|
||||
server balena_redis_1 redis:6379 check port 6379
|
||||
|
||||
listen vpn-tunnel
|
||||
mode tcp
|
||||
bind *:3128
|
||||
server balena_vpn vpn:3128 check port 3128
|
||||
|
||||
listen vpn-tunnel-tls
|
||||
mode tcp
|
||||
bind *:3129 ssl crt /etc/ssl/private/open-balena.pem
|
||||
server balena_vpn vpn:3128 check port 3128
|
Reference in New Issue
Block a user