mirror of
https://github.com/balena-io/open-balena.git
synced 2025-06-25 02:29:16 +00:00
Compare commits
67 Commits
Author | SHA1 | Date | |
---|---|---|---|
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 | |||
bb1328e27e | |||
395613af57 | |||
199d8eb4a4 | |||
6fdc554e43 | |||
f8b8a1589a | |||
3bf14a2140 | |||
fef145f993 | |||
e068f8058f | |||
c1ee146f0d | |||
9ad92596b9 | |||
56de2d20bb | |||
290c90c262 | |||
98b6100fed | |||
e1bfb7f7b0 | |||
35ab5300e6 | |||
fd031ad3a4 | |||
95d53993bc | |||
1721728794 | |||
061440f109 | |||
2f0fb27145 | |||
210bdcda37 | |||
fac66040c8 | |||
85a69c1ef1 | |||
e37a61e5f0 | |||
0fc85ff5b6 | |||
99dd615e55 |
2
.github/CODEOWNERS
vendored
Normal file
2
.github/CODEOWNERS
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Main repo owners:
|
||||||
|
* @dfunckt
|
7
.gitignore
vendored
7
.gitignore
vendored
@ -1,6 +1,7 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
.project
|
.project
|
||||||
.vagrant/
|
.vagrant/
|
||||||
config/
|
|
||||||
src/
|
/config
|
||||||
package-lock.json
|
/docker-compose.yml
|
||||||
|
/package-lock.json
|
||||||
|
1105
.versionbot/CHANGELOG.yml
Normal file
1105
.versionbot/CHANGELOG.yml
Normal file
File diff suppressed because it is too large
Load Diff
451
CHANGELOG.md
451
CHANGELOG.md
@ -4,6 +4,457 @@ All notable changes to this project will be documented in this file
|
|||||||
automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY!
|
automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY!
|
||||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
|
# v3.1.3
|
||||||
|
## (2021-01-26)
|
||||||
|
|
||||||
|
* Remove Rich from CODEOWNERS [Akis Kesoglou]
|
||||||
|
|
||||||
|
# v3.1.2
|
||||||
|
## (2021-01-22)
|
||||||
|
|
||||||
|
* tunnel: Expose tunnel service via TLS [Rich Bayliss]
|
||||||
|
|
||||||
|
# v3.1.1
|
||||||
|
## (2020-11-10)
|
||||||
|
|
||||||
|
* Update open-balena-api [Akis Kesoglou]
|
||||||
|
|
||||||
|
# v3.1.0
|
||||||
|
## (2020-11-03)
|
||||||
|
|
||||||
|
* Change S3 OS images folder from resinos to images [Stevche Radevski]
|
||||||
|
|
||||||
|
# v3.0.1
|
||||||
|
## (2020-10-29)
|
||||||
|
|
||||||
|
* Update the API fixing an issue with migrations [Akis Kesoglou]
|
||||||
|
|
||||||
|
# v3.0.0
|
||||||
|
## (2020-10-28)
|
||||||
|
|
||||||
|
* Update versions of services [Akis Kesoglou]
|
||||||
|
|
||||||
|
# v2.0.5
|
||||||
|
## (2020-10-09)
|
||||||
|
|
||||||
|
* docs: add table comparing features of openBalena and balenaCloud [Matthew McGinn]
|
||||||
|
|
||||||
|
# v2.0.4
|
||||||
|
## (2020-10-08)
|
||||||
|
|
||||||
|
* docs: note that balenaCLI is incompatible >12.2.2 [Matthew McGinn]
|
||||||
|
|
||||||
|
# v2.0.3
|
||||||
|
## (2020-06-01)
|
||||||
|
|
||||||
|
* docs: Add PSA about balenaOS version breakage [Rich Bayliss]
|
||||||
|
|
||||||
|
# v2.0.2
|
||||||
|
## (2020-04-03)
|
||||||
|
|
||||||
|
* Added units to haproxy.cfg default timeouts [Frederic Tausch]
|
||||||
|
|
||||||
|
# v2.0.1
|
||||||
|
## (2020-01-17)
|
||||||
|
|
||||||
|
* cert-provider: Update to support ACMEv2 on staging provider [Rich Bayliss]
|
||||||
|
|
||||||
|
# v2.0.0
|
||||||
|
## (2019-09-02)
|
||||||
|
|
||||||
|
* feature: Use S3 bucket for Registry service backend [Rich Bayliss]
|
||||||
|
|
||||||
|
# v1.3.0
|
||||||
|
## (2019-07-30)
|
||||||
|
|
||||||
|
* services: Update Registry service version [Rich Bayliss]
|
||||||
|
* feature: Support deployment via balena push to local-mode balenaOS devices [Rich Bayliss]
|
||||||
|
|
||||||
|
# v1.2.0
|
||||||
|
## (2019-05-21)
|
||||||
|
|
||||||
|
* tidy: Remove unused DEVICE_CONFIG_OPENVPN_CONFIG variable [Rich Bayliss]
|
||||||
|
* services: Update Registry service version [Akis Kesoglou]
|
||||||
|
* services: Update API service version [Rich Bayliss]
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary> View details </summary>
|
||||||
|
|
||||||
|
## open-balena-api-0.19.5
|
||||||
|
### (2019-05-20)
|
||||||
|
|
||||||
|
* Update typed-error to 3.1.0 [Pagan Gazzard]
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary> View details </summary>
|
||||||
|
|
||||||
|
### typed-error-3.1.0
|
||||||
|
#### (2019-04-01)
|
||||||
|
|
||||||
|
* dev: Enforce prettier coding standards [Will Boyce]
|
||||||
|
* npm: Update dependencies and remove `package-lock.json` [Will Boyce]
|
||||||
|
* codeowners: Add top contributors @wrboyce, @Page-, and @dfunckt [Will Boyce]
|
||||||
|
* versionbot: Add CHANGELOG.yml (for nested changelogs) [Will Boyce]
|
||||||
|
|
||||||
|
### typed-error-3.0.2
|
||||||
|
#### (2018-11-01)
|
||||||
|
|
||||||
|
* Update README with new import style [CameronDiver]
|
||||||
|
|
||||||
|
### typed-error-3.0.1
|
||||||
|
#### (2018-10-29)
|
||||||
|
|
||||||
|
* Update to typescript 3 [Pagan Gazzard]
|
||||||
|
* Update dev dependencies [Pagan Gazzard]
|
||||||
|
* Add node-10 to the circle test suite [Pagan Gazzard]
|
||||||
|
|
||||||
|
### typed-error-3.0.0
|
||||||
|
#### (2018-04-17)
|
||||||
|
|
||||||
|
* Distribute generated typescript declaration [Will Boyce]
|
||||||
|
* use circle for build/publish and add package-lock [Will Boyce]
|
||||||
|
* add lint scripts/requirements [Will Boyce]
|
||||||
|
* Remove `BaseError` class and directly subclass `Error` [Will Boyce]
|
||||||
|
* Update dependencies, clean up package/tsconfig [Will Boyce]
|
||||||
|
|
||||||
|
### typed-error-2.0.1
|
||||||
|
#### (2017-12-15)
|
||||||
|
|
||||||
|
* Add LICENSE [Akis Kesoglou]
|
||||||
|
</details>
|
||||||
|
|
||||||
|
|
||||||
|
## open-balena-api-0.19.4
|
||||||
|
### (2019-05-20)
|
||||||
|
|
||||||
|
* Some linting fixes for resin-lint 3 [Pagan Gazzard]
|
||||||
|
|
||||||
|
## open-balena-api-0.19.3
|
||||||
|
### (2019-05-17)
|
||||||
|
|
||||||
|
* Silence expected API key related rejections [Akis Kesoglou]
|
||||||
|
|
||||||
|
## open-balena-api-0.19.2
|
||||||
|
### (2019-05-17)
|
||||||
|
|
||||||
|
* Update dependencies [Pagan Gazzard]
|
||||||
|
|
||||||
|
## open-balena-api-0.19.1
|
||||||
|
### (2019-05-15)
|
||||||
|
|
||||||
|
* Make use of a prepared query for device state query [Pagan Gazzard]
|
||||||
|
* Update pinejs to 10.14.0 [Pagan Gazzard]
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary> View details </summary>
|
||||||
|
|
||||||
|
### pinejs-10.14.0
|
||||||
|
#### (2019-05-15)
|
||||||
|
|
||||||
|
* Update pinejs-client-core and make use of prepared queries [Pagan Gazzard]
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary> View details </summary>
|
||||||
|
|
||||||
|
#### odata-parser-1.0.3
|
||||||
|
##### (2019-05-08)
|
||||||
|
|
||||||
|
* Add .versionbot/CHANGELOG.yml for downstream changelogs [Pagan Gazzard]
|
||||||
|
|
||||||
|
#### odata-parser-1.0.2
|
||||||
|
##### (2019-04-15)
|
||||||
|
|
||||||
|
* Update dependencies [Pagan Gazzard]
|
||||||
|
|
||||||
|
#### abstract-sql-compiler-6.4.2
|
||||||
|
##### (2019-05-09)
|
||||||
|
|
||||||
|
* Update and fix lodash typings [Pagan Gazzard]
|
||||||
|
* Update husky/mocha dev dependencies [Pagan Gazzard]
|
||||||
|
|
||||||
|
#### abstract-sql-compiler-6.4.1
|
||||||
|
##### (2019-05-08)
|
||||||
|
|
||||||
|
* Fix typescript compilation [Pagan Gazzard]
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary> View details </summary>
|
||||||
|
|
||||||
|
##### sbvr-parser-0.2.2
|
||||||
|
###### (2019-05-08)
|
||||||
|
|
||||||
|
* Add .versionbot/CHANGELOG.yml for downstream changelogs [Pagan Gazzard]
|
||||||
|
</details>
|
||||||
|
|
||||||
|
* Add node 12 tests [Pagan Gazzard]
|
||||||
|
* Add repo.yml for upstream changelogs [Pagan Gazzard]
|
||||||
|
* Add .versionbot/CHANGELOG.yml for downstream changelogs [Pagan Gazzard]
|
||||||
|
|
||||||
|
#### pinejs-client-js-5.5.1
|
||||||
|
##### (2019-05-15)
|
||||||
|
|
||||||
|
* Fix downstream declaration creation errors due to `Dictionary` [Pagan Gazzard]
|
||||||
|
|
||||||
|
#### pinejs-client-js-5.5.0
|
||||||
|
##### (2019-05-15)
|
||||||
|
|
||||||
|
* Add a prepare method that prepares a query into a function [Pagan Gazzard]
|
||||||
|
|
||||||
|
#### pinejs-client-js-5.4.1
|
||||||
|
##### (2019-05-10)
|
||||||
|
|
||||||
|
* Add CODEOWNERS [Gergely Imreh]
|
||||||
|
|
||||||
|
#### pinejs-client-js-5.4.0
|
||||||
|
##### (2019-05-10)
|
||||||
|
|
||||||
|
* Add support for parameter aliases in resource ids [Pagan Gazzard]
|
||||||
|
|
||||||
|
#### pinejs-client-js-5.3.10
|
||||||
|
##### (2019-05-10)
|
||||||
|
|
||||||
|
* Deduplicate transformation of GET results [Pagan Gazzard]
|
||||||
|
|
||||||
|
#### pinejs-client-js-5.3.9
|
||||||
|
##### (2019-05-10)
|
||||||
|
|
||||||
|
* Simplify how we expose types, which means `subscribe` is now exposed [Pagan Gazzard]
|
||||||
|
|
||||||
|
#### pinejs-client-js-5.3.8
|
||||||
|
##### (2019-05-09)
|
||||||
|
|
||||||
|
* Add automatic formatting via prettier [Pagan Gazzard]
|
||||||
|
|
||||||
|
#### pinejs-client-js-5.3.7
|
||||||
|
##### (2019-05-08)
|
||||||
|
|
||||||
|
* Remove node 4 build, add node 12 [Pagan Gazzard]
|
||||||
|
* Add .versionbot/CHANGELOG.yml for downstream changelogs [Pagan Gazzard]
|
||||||
|
|
||||||
|
#### odata-to-abstract-sql-3.1.2
|
||||||
|
##### (2019-05-08)
|
||||||
|
|
||||||
|
* Add node 12 tests [Pagan Gazzard]
|
||||||
|
* Add repo.yml for upstream changelogs [Pagan Gazzard]
|
||||||
|
* Add .versionbot/CHANGELOG.yml for downstream changelogs [Pagan Gazzard]
|
||||||
|
|
||||||
|
#### sbvr-types-2.0.3
|
||||||
|
##### (2019-05-08)
|
||||||
|
|
||||||
|
* Add .versionbot/CHANGELOG.yml for downstream changelogs [Pagan Gazzard]
|
||||||
|
|
||||||
|
#### sbvr-parser-0.2.2
|
||||||
|
##### (2019-05-08)
|
||||||
|
|
||||||
|
* Add .versionbot/CHANGELOG.yml for downstream changelogs [Pagan Gazzard]
|
||||||
|
</details>
|
||||||
|
|
||||||
|
|
||||||
|
### pinejs-10.13.3
|
||||||
|
#### (2019-05-14)
|
||||||
|
|
||||||
|
* Fix possible null error when using a parameter alias with no value [Pagan Gazzard]
|
||||||
|
|
||||||
|
### pinejs-10.13.2
|
||||||
|
#### (2019-05-08)
|
||||||
|
|
||||||
|
* Add repo.yml for nested changelogs [Pagan Gazzard]
|
||||||
|
|
||||||
|
### pinejs-10.13.1
|
||||||
|
#### (2019-05-06)
|
||||||
|
|
||||||
|
* Add node 12 to the circle tests [Pagan Gazzard]
|
||||||
|
|
||||||
|
### pinejs-10.13.0
|
||||||
|
#### (2019-05-06)
|
||||||
|
|
||||||
|
* Expose odata-compiler as a bin script [Pagan Gazzard]
|
||||||
|
|
||||||
|
### pinejs-10.12.0
|
||||||
|
#### (2019-05-01)
|
||||||
|
|
||||||
|
* Expose sbvr-compiler as a bin script [Pagan Gazzard]
|
||||||
|
* Move odata-metadata-generator into odata-metadata directory [Pagan Gazzard]
|
||||||
|
|
||||||
|
### pinejs-10.11.3
|
||||||
|
#### (2019-05-01)
|
||||||
|
|
||||||
|
* Update @types/lodash, avoiding `_.isObject` where necessary [Pagan Gazzard]
|
||||||
|
|
||||||
|
### pinejs-10.11.2
|
||||||
|
#### (2019-04-22)
|
||||||
|
|
||||||
|
* Only validate the model if the query affected at least 1 row [Pagan Gazzard]
|
||||||
|
|
||||||
|
### pinejs-10.11.1
|
||||||
|
#### (2019-04-11)
|
||||||
|
|
||||||
|
* Switch odata-metadata-generator to using an abstract sql model [Pagan Gazzard]
|
||||||
|
</details>
|
||||||
|
|
||||||
|
|
||||||
|
## open-balena-api-0.19.0
|
||||||
|
### (2019-05-15)
|
||||||
|
|
||||||
|
* Update target to es2018 [Pagan Gazzard]
|
||||||
|
|
||||||
|
## open-balena-api-0.18.6
|
||||||
|
### (2019-05-10)
|
||||||
|
|
||||||
|
* bug: Resolve NPM dependency issues preventing startup [Rich Bayliss]
|
||||||
|
|
||||||
|
## open-balena-api-0.18.5
|
||||||
|
### (2019-05-08)
|
||||||
|
|
||||||
|
* Add typed-error upstream to repo.yml [Pagan Gazzard]
|
||||||
|
* Add open-balena-base upstream to repo.yml [Pagan Gazzard]
|
||||||
|
|
||||||
|
## open-balena-api-0.18.4
|
||||||
|
### (2019-05-06)
|
||||||
|
|
||||||
|
* Disable the service start limit [Pagan Gazzard]
|
||||||
|
* Update open-balena-base to v7.0.2 [Pagan Gazzard]
|
||||||
|
|
||||||
|
## open-balena-api-0.18.3
|
||||||
|
### (2019-05-01)
|
||||||
|
|
||||||
|
* tests: Add test framework [Rich Bayliss]
|
||||||
|
|
||||||
|
## open-balena-api-0.18.2
|
||||||
|
### (2019-04-29)
|
||||||
|
|
||||||
|
* Fix import ordering issue [Pagan Gazzard]
|
||||||
|
|
||||||
|
## open-balena-api-0.18.1
|
||||||
|
### (2019-04-29)
|
||||||
|
|
||||||
|
* versionbot: add machine readable changelog [Gergely Imreh]
|
||||||
|
|
||||||
|
## open-balena-api-0.18.0
|
||||||
|
### (2019-04-29)
|
||||||
|
|
||||||
|
* device-config: allow devices going back to v1.2.1 to use registry v2 [Gergely Imreh]
|
||||||
|
|
||||||
|
## open-balena-api-0.17.4
|
||||||
|
### (2019-04-26)
|
||||||
|
|
||||||
|
* Handle requesting registry scopes with explicit indices above 20 [Pagan Gazzard]
|
||||||
|
|
||||||
|
## open-balena-api-0.17.3
|
||||||
|
### (2019-04-26)
|
||||||
|
|
||||||
|
* Use more accurate `BadRequestError`s for invalid env var names [Pagan Gazzard]
|
||||||
|
* Remove unnecessary `nameProp` argument from `addEnvHooks` [Pagan Gazzard]
|
||||||
|
* Avoid unnecessary object creation on env var validation [Pagan Gazzard]
|
||||||
|
|
||||||
|
## open-balena-api-0.17.2
|
||||||
|
### (2019-04-24)
|
||||||
|
|
||||||
|
* os-config: disable client-initiated vpn tls key renegotiation [Will Boyce]
|
||||||
|
|
||||||
|
## open-balena-api-0.17.1
|
||||||
|
### (2019-04-19)
|
||||||
|
|
||||||
|
* Remove unused `DEVICE_CONFIG_OPENVPN_CONFIG` fron env backend [Pagan Gazzard]
|
||||||
|
|
||||||
|
## open-balena-api-0.17.0
|
||||||
|
### (2019-04-18)
|
||||||
|
|
||||||
|
* Rename `env_var_name` to `name` to match cloud [Pagan Gazzard]
|
||||||
|
|
||||||
|
## open-balena-api-0.16.1
|
||||||
|
### (2019-04-18)
|
||||||
|
|
||||||
|
* fix: Changes required to make `my_application` resource available [Rich Bayliss]
|
||||||
|
|
||||||
|
## open-balena-api-0.16.0
|
||||||
|
### (2019-04-17)
|
||||||
|
|
||||||
|
* Handle `my_applications` within pinejs [Pagan Gazzard]
|
||||||
|
|
||||||
|
## open-balena-api-0.15.2
|
||||||
|
### (2019-04-17)
|
||||||
|
|
||||||
|
* device-proxy: use `.balena` tld in favour of `.resin` [Will Boyce]
|
||||||
|
|
||||||
|
## open-balena-api-0.15.1
|
||||||
|
### (2019-04-17)
|
||||||
|
|
||||||
|
* Update method-override to 3.x [Pagan Gazzard]
|
||||||
|
|
||||||
|
## open-balena-api-0.15.0
|
||||||
|
### (2019-04-15)
|
||||||
|
|
||||||
|
* Rename `configPath` to `config` and make sure config.json is valid [Pagan Gazzard]
|
||||||
|
|
||||||
|
## open-balena-api-0.14.0
|
||||||
|
### (2019-04-11)
|
||||||
|
|
||||||
|
* Whitelist the new RESIN_SUPERVISOR_INSTANT_UPDATE_TRIGGER configuration variable [Pablo Carranza Velez]
|
||||||
|
|
||||||
|
## open-balena-api-0.13.3
|
||||||
|
### (2019-04-02)
|
||||||
|
|
||||||
|
* Fix `ResolvableReturnType` typing [Pagan Gazzard]
|
||||||
|
|
||||||
|
## open-balena-api-0.13.2
|
||||||
|
### (2019-04-01)
|
||||||
|
|
||||||
|
* Add CODEOWNERS file [Pagan Gazzard]
|
||||||
|
|
||||||
|
## open-balena-api-0.13.1
|
||||||
|
### (2019-04-01)
|
||||||
|
|
||||||
|
* Add an index for the vpn's service instance lookup [Pagan Gazzard]
|
||||||
|
|
||||||
|
## open-balena-api-0.13.0
|
||||||
|
### (2019-03-28)
|
||||||
|
|
||||||
|
* Use a readTransaction for device state [Pagan Gazzard]
|
||||||
|
* Remove runInTransaction wrapper to avoid unnecessary function creation [Pagan Gazzard]
|
||||||
|
* Avoid need to repeateadly check for `readTransaction` existence [Pagan Gazzard]
|
||||||
|
|
||||||
|
## open-balena-api-0.12.0
|
||||||
|
### (2019-03-19)
|
||||||
|
|
||||||
|
* Add build log to release resource [Stevche Radevski]
|
||||||
|
</details>
|
||||||
|
|
||||||
|
# v1.1.1
|
||||||
|
## (2019-05-07)
|
||||||
|
|
||||||
|
* docker: Update docker-compose version to latest [Heds Simons]
|
||||||
|
|
||||||
|
# v1.1.0
|
||||||
|
## (2019-05-07)
|
||||||
|
|
||||||
|
* s3: Update to latest version with credentials [Heds Simons]
|
||||||
|
|
||||||
|
# v1.0.2
|
||||||
|
## (2019-04-17)
|
||||||
|
|
||||||
|
* scripts: Handle missing coreutils on Mac [Roman Mazur]
|
||||||
|
|
||||||
|
# v1.0.1
|
||||||
|
## (2019-03-20)
|
||||||
|
|
||||||
|
* vpn: Remove BALENA_ROOT_CA from the VPN trust chain [Rich Bayliss]
|
||||||
|
|
||||||
|
# v1.0.0
|
||||||
|
## (2019-03-15)
|
||||||
|
|
||||||
|
* tags: Pin the image tags for the service stack [Rich Bayliss]
|
||||||
|
|
||||||
|
# v0.2.2
|
||||||
|
## (2019-03-08)
|
||||||
|
|
||||||
|
* codeowners: Add CODEOWNERS file [Rich Bayliss]
|
||||||
|
|
||||||
|
# v0.2.1
|
||||||
|
## (2019-03-08)
|
||||||
|
|
||||||
|
* certs: Add support for an ACME certificate provider [Rich Bayliss]
|
||||||
|
|
||||||
# v0.2.0
|
# v0.2.0
|
||||||
## (2019-01-25)
|
## (2019-01-25)
|
||||||
|
|
||||||
|
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
|
- **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
|
## 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
|
an openBalena installation up and running and successfully deploying your
|
||||||
application to your device(s).
|
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
|
## Documentation
|
||||||
|
|
||||||
While we're still working on the project documentation, please refer to the
|
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.
|
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
|
## License
|
||||||
|
|
||||||
OpenBalena is licensed under the terms of AGPL v3. See [LICENSE](LICENSE) for details.
|
OpenBalena is licensed under the terms of AGPL v3. See [LICENSE](LICENSE) for details.
|
||||||
|
8
Vagrantfile
vendored
8
Vagrantfile
vendored
@ -20,15 +20,21 @@ Vagrant.configure('2') do |config|
|
|||||||
config.ssh.forward_agent = true
|
config.ssh.forward_agent = true
|
||||||
|
|
||||||
config.vm.provision :docker
|
config.vm.provision :docker
|
||||||
config.vm.provision :docker_compose
|
|
||||||
|
|
||||||
$provision = <<-SCRIPT
|
$provision = <<-SCRIPT
|
||||||
|
DOCKER_COMPOSE_VERSION=1.24.0
|
||||||
|
|
||||||
touch /home/vagrant/.bashrc
|
touch /home/vagrant/.bashrc
|
||||||
grep -Fxq 'source /home/vagrant/openbalena/.openbalenarc' /home/vagrant/.bashrc || echo 'source /home/vagrant/openbalena/.openbalenarc' >> /home/vagrant/.bashrc
|
grep -Fxq 'source /home/vagrant/openbalena/.openbalenarc' /home/vagrant/.bashrc || echo 'source /home/vagrant/openbalena/.openbalenarc' >> /home/vagrant/.bashrc
|
||||||
|
|
||||||
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
|
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
|
||||||
source "/home/vagrant/.nvm/nvm.sh" # This loads nvm
|
source "/home/vagrant/.nvm/nvm.sh" # This loads nvm
|
||||||
nvm install 10.15.0 && nvm use 10.15.0
|
nvm install 10.15.0 && nvm use 10.15.0
|
||||||
|
|
||||||
|
# Install a newer version of docker-compose
|
||||||
|
(cd /usr/local/bin; \
|
||||||
|
sudo curl -o docker-compose --silent --location https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_VERSION/docker-compose-Linux-x86_64; \
|
||||||
|
sudo chmod a+x docker-compose)
|
||||||
SCRIPT
|
SCRIPT
|
||||||
|
|
||||||
config.vm.provision :shell, privileged: false, inline: $provision
|
config.vm.provision :shell, privileged: false, inline: $provision
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
version: '2.1'
|
version: "2.0"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
component:
|
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,17 +1,19 @@
|
|||||||
version: '2.1'
|
version: "2.0"
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
db:
|
certs: {}
|
||||||
registry:
|
cert-provider: {}
|
||||||
s3:
|
db: {}
|
||||||
redis:
|
redis: {}
|
||||||
|
registry: {}
|
||||||
|
s3: {}
|
||||||
|
|
||||||
services:
|
services:
|
||||||
api:
|
api:
|
||||||
extends:
|
extends:
|
||||||
file: ./common.yml
|
file: ./common.yml
|
||||||
service: component
|
service: component
|
||||||
image: balena/open-balena-api:${OPENBALENA_API_VERSION_TAG:-master}
|
image: balena/open-balena-api:${OPENBALENA_API_VERSION_TAG}
|
||||||
depends_on:
|
depends_on:
|
||||||
- db
|
- db
|
||||||
- s3
|
- s3
|
||||||
@ -20,36 +22,35 @@ services:
|
|||||||
API_VPN_SERVICE_API_KEY: ${OPENBALENA_API_VPN_SERVICE_API_KEY}
|
API_VPN_SERVICE_API_KEY: ${OPENBALENA_API_VPN_SERVICE_API_KEY}
|
||||||
BALENA_ROOT_CA: ${OPENBALENA_ROOT_CA}
|
BALENA_ROOT_CA: ${OPENBALENA_ROOT_CA}
|
||||||
COOKIE_SESSION_SECRET: ${OPENBALENA_COOKIE_SESSION_SECRET}
|
COOKIE_SESSION_SECRET: ${OPENBALENA_COOKIE_SESSION_SECRET}
|
||||||
DB_HOST: db.${OPENBALENA_HOST_NAME}
|
DB_HOST: db
|
||||||
DB_PASSWORD: docker
|
DB_PASSWORD: docker
|
||||||
DB_PORT: 5432
|
DB_PORT: 5432
|
||||||
DB_USER: docker
|
DB_USER: docker
|
||||||
DELTA_HOST: delta.${OPENBALENA_HOST_NAME}
|
DELTA_HOST: delta.${OPENBALENA_HOST_NAME}
|
||||||
DEVICE_CONFIG_OPENVPN_CONFIG: ${OPENBALENA_VPN_CONFIG}
|
|
||||||
DEVICE_CONFIG_OPENVPN_CA: ${OPENBALENA_VPN_CA_CHAIN}
|
DEVICE_CONFIG_OPENVPN_CA: ${OPENBALENA_VPN_CA_CHAIN}
|
||||||
DEVICE_CONFIG_SSH_AUTHORIZED_KEYS: ${OPENBALENA_SSH_AUTHORIZED_KEYS}
|
DEVICE_CONFIG_SSH_AUTHORIZED_KEYS: ${OPENBALENA_SSH_AUTHORIZED_KEYS}
|
||||||
HOST: api.${OPENBALENA_HOST_NAME}
|
HOST: api.${OPENBALENA_HOST_NAME}
|
||||||
IMAGE_MAKER_URL: img.${OPENBALENA_HOST_NAME}
|
IMAGE_MAKER_URL: img.${OPENBALENA_HOST_NAME}
|
||||||
IMAGE_STORAGE_BUCKET: resin-production-img-cloudformation
|
IMAGE_STORAGE_BUCKET: resin-production-img-cloudformation
|
||||||
IMAGE_STORAGE_PREFIX: resinos
|
IMAGE_STORAGE_PREFIX: images
|
||||||
IMAGE_STORAGE_ENDPOINT: s3.amazonaws.com
|
IMAGE_STORAGE_ENDPOINT: s3.amazonaws.com
|
||||||
JSON_WEB_TOKEN_EXPIRY_MINUTES: 10080
|
JSON_WEB_TOKEN_EXPIRY_MINUTES: 10080
|
||||||
JSON_WEB_TOKEN_SECRET: ${OPENBALENA_JWT_SECRET}
|
JSON_WEB_TOKEN_SECRET: ${OPENBALENA_JWT_SECRET}
|
||||||
MIXPANEL_TOKEN: __unused__
|
MIXPANEL_TOKEN: __unused__
|
||||||
PRODUCTION_MODE: '${OPENBALENA_PRODUCTION_MODE}'
|
PRODUCTION_MODE: "${OPENBALENA_PRODUCTION_MODE}"
|
||||||
PUBNUB_PUBLISH_KEY: __unused__
|
PUBNUB_PUBLISH_KEY: __unused__
|
||||||
PUBNUB_SUBSCRIBE_KEY: __unused__
|
PUBNUB_SUBSCRIBE_KEY: __unused__
|
||||||
REDIS_HOST: redis.${OPENBALENA_HOST_NAME}
|
REDIS_HOST: redis
|
||||||
REDIS_PORT: 6379
|
REDIS_PORT: 6379
|
||||||
REGISTRY2_HOST: registry.${OPENBALENA_HOST_NAME}
|
REGISTRY2_HOST: registry.${OPENBALENA_HOST_NAME}
|
||||||
REGISTRY_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_BUILDER_TOKEN: ${OPENBALENA_TOKEN_AUTH_BUILDER_TOKEN}
|
||||||
TOKEN_AUTH_CERT_ISSUER: api.${OPENBALENA_HOST_NAME}
|
TOKEN_AUTH_CERT_ISSUER: api.${OPENBALENA_HOST_NAME}
|
||||||
TOKEN_AUTH_CERT_KEY: ${OPENBALENA_TOKEN_AUTH_KEY}
|
TOKEN_AUTH_CERT_KEY: ${OPENBALENA_TOKEN_AUTH_KEY}
|
||||||
TOKEN_AUTH_CERT_KID: ${OPENBALENA_TOKEN_AUTH_KID}
|
TOKEN_AUTH_CERT_KID: ${OPENBALENA_TOKEN_AUTH_KID}
|
||||||
TOKEN_AUTH_CERT_PUB: ${OPENBALENA_TOKEN_AUTH_PUB}
|
TOKEN_AUTH_CERT_PUB: ${OPENBALENA_TOKEN_AUTH_PUB}
|
||||||
TOKEN_AUTH_JWT_ALGO: 'ES256'
|
TOKEN_AUTH_JWT_ALGO: "ES256"
|
||||||
VPN_HOST: vpn.${OPENBALENA_HOST_NAME}
|
VPN_HOST: vpn.${OPENBALENA_HOST_NAME}
|
||||||
VPN_PORT: 443
|
VPN_PORT: 443
|
||||||
VPN_SERVICE_API_KEY: ${OPENBALENA_VPN_SERVICE_API_KEY}
|
VPN_SERVICE_API_KEY: ${OPENBALENA_VPN_SERVICE_API_KEY}
|
||||||
@ -60,9 +61,8 @@ services:
|
|||||||
extends:
|
extends:
|
||||||
file: ./common.yml
|
file: ./common.yml
|
||||||
service: component
|
service: component
|
||||||
image: balena/open-balena-registry:${OPENBALENA_REGISTRY_VERSION_TAG:-master}
|
image: balena/open-balena-registry:${OPENBALENA_REGISTRY_VERSION_TAG}
|
||||||
depends_on:
|
depends_on:
|
||||||
- api
|
|
||||||
- s3
|
- s3
|
||||||
- redis
|
- redis
|
||||||
volumes:
|
volumes:
|
||||||
@ -73,10 +73,16 @@ services:
|
|||||||
BALENA_ROOT_CA: ${OPENBALENA_ROOT_CA}
|
BALENA_ROOT_CA: ${OPENBALENA_ROOT_CA}
|
||||||
BALENA_TOKEN_AUTH_ISSUER: api.${OPENBALENA_HOST_NAME}
|
BALENA_TOKEN_AUTH_ISSUER: api.${OPENBALENA_HOST_NAME}
|
||||||
BALENA_TOKEN_AUTH_REALM: https://api.${OPENBALENA_HOST_NAME}/auth/v1/token
|
BALENA_TOKEN_AUTH_REALM: https://api.${OPENBALENA_HOST_NAME}/auth/v1/token
|
||||||
COMMON_REGION:
|
COMMON_REGION: ${OPENBALENA_S3_REGION}
|
||||||
REGISTRY2_S3_BUCKET:
|
REGISTRY2_CACHE_ENABLED: "false"
|
||||||
REGISTRY2_S3_KEY:
|
REGISTRY2_CACHE_ADDR: 127.0.0.1:6379
|
||||||
REGISTRY2_S3_SECRET:
|
REGISTRY2_CACHE_DB: 0
|
||||||
|
REGISTRY2_CACHE_MAXMEMORY_MB: 1024 # megabytes
|
||||||
|
REGISTRY2_CACHE_MAXMEMORY_POLICY: allkeys-lru
|
||||||
|
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_SECRETKEY: ${OPENBALENA_REGISTRY_SECRET_KEY}
|
||||||
REGISTRY2_STORAGEPATH: /data
|
REGISTRY2_STORAGEPATH: /data
|
||||||
|
|
||||||
@ -84,7 +90,7 @@ services:
|
|||||||
extends:
|
extends:
|
||||||
file: ./common.yml
|
file: ./common.yml
|
||||||
service: component
|
service: component
|
||||||
image: balena/open-balena-vpn:${OPENBALENA_VPN_VERSION_TAG:-master}
|
image: balena/open-balena-vpn:${OPENBALENA_VPN_VERSION_TAG}
|
||||||
depends_on:
|
depends_on:
|
||||||
- api
|
- api
|
||||||
cap_add:
|
cap_add:
|
||||||
@ -94,10 +100,10 @@ services:
|
|||||||
BALENA_API_HOST: api.${OPENBALENA_HOST_NAME}
|
BALENA_API_HOST: api.${OPENBALENA_HOST_NAME}
|
||||||
BALENA_ROOT_CA: ${OPENBALENA_ROOT_CA}
|
BALENA_ROOT_CA: ${OPENBALENA_ROOT_CA}
|
||||||
BALENA_VPN_PORT: 443
|
BALENA_VPN_PORT: 443
|
||||||
PRODUCTION_MODE: '${OPENBALENA_PRODUCTION_MODE}'
|
PRODUCTION_MODE: "${OPENBALENA_PRODUCTION_MODE}"
|
||||||
RESIN_VPN_GATEWAY: 10.2.0.1
|
RESIN_VPN_GATEWAY: 10.2.0.1
|
||||||
SENTRY_DSN:
|
SENTRY_DSN: ""
|
||||||
VPN_HAPROXY_USEPROXYPROTOCOL: 'true'
|
VPN_HAPROXY_USEPROXYPROTOCOL: "true"
|
||||||
VPN_OPENVPN_CA_CRT: ${OPENBALENA_VPN_CA}
|
VPN_OPENVPN_CA_CRT: ${OPENBALENA_VPN_CA}
|
||||||
VPN_OPENVPN_SERVER_CRT: ${OPENBALENA_VPN_SERVER_CRT}
|
VPN_OPENVPN_SERVER_CRT: ${OPENBALENA_VPN_SERVER_CRT}
|
||||||
VPN_OPENVPN_SERVER_DH: ${OPENBALENA_VPN_SERVER_DH}
|
VPN_OPENVPN_SERVER_DH: ${OPENBALENA_VPN_SERVER_DH}
|
||||||
@ -108,17 +114,21 @@ services:
|
|||||||
extends:
|
extends:
|
||||||
file: ./common.yml
|
file: ./common.yml
|
||||||
service: system
|
service: system
|
||||||
image: balena/open-balena-db:${OPENBALENA_DB_VERSION_TAG:-master}
|
image: balena/open-balena-db:${OPENBALENA_DB_VERSION_TAG}
|
||||||
volumes:
|
volumes:
|
||||||
- db:/var/lib/postgresql/data
|
- db:/var/lib/postgresql/data
|
||||||
|
|
||||||
s3:
|
s3:
|
||||||
extends:
|
extends:
|
||||||
file: ./common.yml
|
file: ./common.yml
|
||||||
service: system
|
service: component
|
||||||
image: balena/open-balena-s3:${OPENBALENA_S3_VERSION_TAG:-master}
|
image: balena/open-balena-s3:${OPENBALENA_S3_VERSION_TAG}
|
||||||
volumes:
|
volumes:
|
||||||
- s3:/export
|
- s3:/export
|
||||||
|
environment:
|
||||||
|
S3_MINIO_ACCESS_KEY: ${OPENBALENA_S3_ACCESS_KEY}
|
||||||
|
S3_MINIO_SECRET_KEY: ${OPENBALENA_S3_SECRET_KEY}
|
||||||
|
BUCKETS: ${OPENBALENA_S3_BUCKETS}
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
extends:
|
extends:
|
||||||
@ -132,14 +142,15 @@ services:
|
|||||||
extends:
|
extends:
|
||||||
file: ./common.yml
|
file: ./common.yml
|
||||||
service: system
|
service: system
|
||||||
build: ../haproxy
|
build: ../src/haproxy
|
||||||
depends_on:
|
depends_on:
|
||||||
- api
|
- api
|
||||||
- registry
|
- cert-provider
|
||||||
- vpn
|
|
||||||
- db
|
- db
|
||||||
- s3
|
- s3
|
||||||
- redis
|
- redis
|
||||||
|
- registry
|
||||||
|
- vpn
|
||||||
ports:
|
ports:
|
||||||
- "80:80"
|
- "80:80"
|
||||||
- "443:443"
|
- "443:443"
|
||||||
@ -157,8 +168,21 @@ services:
|
|||||||
- db.${OPENBALENA_HOST_NAME}
|
- db.${OPENBALENA_HOST_NAME}
|
||||||
- s3.${OPENBALENA_HOST_NAME}
|
- s3.${OPENBALENA_HOST_NAME}
|
||||||
- redis.${OPENBALENA_HOST_NAME}
|
- redis.${OPENBALENA_HOST_NAME}
|
||||||
|
- tunnel.${OPENBALENA_HOST_NAME}
|
||||||
environment:
|
environment:
|
||||||
BALENA_HAPROXY_CRT: ${OPENBALENA_ROOT_CRT}
|
BALENA_HAPROXY_CRT: ${OPENBALENA_ROOT_CRT}
|
||||||
BALENA_HAPROXY_KEY: ${OPENBALENA_ROOT_KEY}
|
BALENA_HAPROXY_KEY: ${OPENBALENA_ROOT_KEY}
|
||||||
BALENA_ROOT_CA: ${OPENBALENA_ROOT_CA}
|
BALENA_ROOT_CA: ${OPENBALENA_ROOT_CA}
|
||||||
HAPROXY_HOSTNAME: ${OPENBALENA_HOST_NAME}
|
HAPROXY_HOSTNAME: ${OPENBALENA_HOST_NAME}
|
||||||
|
volumes:
|
||||||
|
- certs:/certs:ro
|
||||||
|
|
||||||
|
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},tunnel.${OPENBALENA_HOST_NAME}"
|
||||||
|
OUTPUT_PEM: /certs/open-balena.pem
|
||||||
|
@ -7,4 +7,4 @@
|
|||||||
# `compose/services.yml` as the "base" config.
|
# `compose/services.yml` as the "base" config.
|
||||||
#
|
#
|
||||||
# You may view the effective config with `scripts/compose config`.
|
# You may view the effective config with `scripts/compose config`.
|
||||||
version: '2.1'
|
version: "2.0"
|
||||||
|
6
compose/versions
Normal file
6
compose/versions
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export OPENBALENA_API_VERSION_TAG=v0.109.2
|
||||||
|
export OPENBALENA_DB_VERSION_TAG=v4.1.0
|
||||||
|
export OPENBALENA_MDNS_PUBLISHER_VERSION_TAG=v1.7.9
|
||||||
|
export OPENBALENA_REGISTRY_VERSION_TAG=v2.13.11
|
||||||
|
export OPENBALENA_S3_VERSION_TAG=v2.9.9
|
||||||
|
export OPENBALENA_VPN_VERSION_TAG=v9.16.1
|
@ -1,6 +0,0 @@
|
|||||||
FROM haproxy:1.8-alpine
|
|
||||||
|
|
||||||
COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg
|
|
||||||
COPY entry.sh /open-balena-entry
|
|
||||||
|
|
||||||
CMD /open-balena-entry
|
|
@ -1,11 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
set -e
|
|
||||||
|
|
||||||
HAPROXY_CHAIN=/etc/ssl/private/open-balena.pem
|
|
||||||
mkdir -p "$(dirname "${HAPROXY_CHAIN}")"
|
|
||||||
(
|
|
||||||
echo "${BALENA_HAPROXY_CRT}" | base64 -d
|
|
||||||
echo "${BALENA_HAPROXY_KEY}" | base64 -d
|
|
||||||
echo "${BALENA_ROOT_CA}" | base64 -d
|
|
||||||
) > "${HAPROXY_CHAIN}"
|
|
||||||
exec haproxy -f /usr/local/etc/haproxy/haproxy.cfg
|
|
15
repo.yml
15
repo.yml
@ -1,2 +1,15 @@
|
|||||||
type: 'generic'
|
type: "generic"
|
||||||
reviewers: 1
|
reviewers: 1
|
||||||
|
upstream:
|
||||||
|
- repo: open-balena-api
|
||||||
|
url: https://github.com/balena-io/open-balena-api
|
||||||
|
- repo: open-balena-vpn
|
||||||
|
url: https://github.com/balena-io/open-balena-vpn
|
||||||
|
- repo: open-balena-registry
|
||||||
|
url: https://github.com/balena-io/open-balena-registry
|
||||||
|
- repo: open-balena-db
|
||||||
|
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
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
#!/bin/bash -e
|
#!/bin/bash -e
|
||||||
|
|
||||||
|
echo_error() {
|
||||||
|
local RED=`tput setaf 1`
|
||||||
|
local RESET=`tput sgr0`
|
||||||
|
echo "${RED}ERROR: ${1}${RESET}"
|
||||||
|
}
|
||||||
|
|
||||||
REALPATH=
|
REALPATH=
|
||||||
REALPATHS=(
|
REALPATHS=(
|
||||||
'realpath'
|
'realpath'
|
||||||
@ -14,8 +20,13 @@ fi
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [ -z "${REALPATH}" ]; then
|
if [ -z "${REALPATH}" ]; then
|
||||||
local RED=`tput setaf 1`
|
echo_error 'Unable to find suitable command for realpath.'
|
||||||
echo "${RED}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 ''
|
||||||
|
echo ' brew install coreutils'
|
||||||
|
echo ''
|
||||||
|
fi
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -11,6 +11,16 @@ echo_bold() {
|
|||||||
printf "\\033[1m%s\\033[0m\\n" "$@"
|
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}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
ENV_FILE="${CONFIG_DIR}/activate"
|
ENV_FILE="${CONFIG_DIR}/activate"
|
||||||
if [ ! -f "$ENV_FILE" ]; then
|
if [ ! -f "$ENV_FILE" ]; then
|
||||||
echo_bold 'No configuration found; please create one first with: ./scripts/quickstart'
|
echo_bold 'No configuration found; please create one first with: ./scripts/quickstart'
|
||||||
@ -18,9 +28,20 @@ if [ ! -f "$ENV_FILE" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
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
|
# shellcheck source=/dev/null
|
||||||
source "${ENV_FILE}"; docker-compose \
|
source "${VERSIONS_FILE}"; docker-compose \
|
||||||
--project-name 'openbalena' \
|
--project-name 'openbalena' \
|
||||||
-f "${BASE_DIR}/compose/services.yml" \
|
-f "${BASE_DIR}/compose/services.yml" \
|
||||||
|
${INCLUDE_MDNS} \
|
||||||
-f "${CONFIG_DIR}/docker-compose.yml" \
|
-f "${CONFIG_DIR}/docker-compose.yml" \
|
||||||
"$@"
|
"$@"
|
||||||
|
@ -32,14 +32,9 @@ if [ ! -f $VPN_CA ] || [ ! -f $VPN_CRT ] || [ ! -f $VPN_KEY ] || [ ! -f $VPN_DH
|
|||||||
|
|
||||||
rm -f $VPN_CA $VPN_CRT $VPN_DH $VPN_KEY
|
rm -f $VPN_CA $VPN_CRT $VPN_DH $VPN_KEY
|
||||||
|
|
||||||
# generate VPN sub-CA
|
# generate VPN CA
|
||||||
"$easyrsa_bin" --pki-dir="${VPN_PKI}" init-pki &>/dev/null
|
"$easyrsa_bin" --pki-dir="${VPN_PKI}" init-pki &>/dev/null
|
||||||
"$easyrsa_bin" --pki-dir="${VPN_PKI}" --days="${CA_EXPIRY_DAYS}" --req-cn="vpn-ca.${CN}" build-ca nopass subca 2>/dev/null
|
"$easyrsa_bin" --pki-dir="${VPN_PKI}" --days="${CA_EXPIRY_DAYS}" --req-cn="vpn-ca.${CN}" build-ca nopass 2>/dev/null
|
||||||
|
|
||||||
# import sub-CA CSR into root PKI, sign, and copy back to vpn PKI
|
|
||||||
"$easyrsa_bin" --pki-dir="${ROOT_PKI}" import-req "${VPN_PKI}/reqs/ca.req" "vpn-ca" 2>/dev/null
|
|
||||||
"$easyrsa_bin" --pki-dir="${ROOT_PKI}" sign-req ca "vpn-ca" 2>/dev/null
|
|
||||||
cp "${ROOT_PKI}/issued/vpn-ca.crt" "${VPN_PKI}/ca.crt"
|
|
||||||
|
|
||||||
# generate and sign vpn server certificate
|
# generate and sign vpn server certificate
|
||||||
"$easyrsa_bin" --pki-dir="${VPN_PKI}" --days="${CRT_EXPIRY_DAYS}" build-server-full "vpn.${CN}" nopass 2>/dev/null
|
"$easyrsa_bin" --pki-dir="${VPN_PKI}" --days="${CRT_EXPIRY_DAYS}" build-server-full "vpn.${CN}" nopass 2>/dev/null
|
||||||
@ -48,8 +43,6 @@ if [ ! -f $VPN_CA ] || [ ! -f $VPN_CRT ] || [ ! -f $VPN_KEY ] || [ ! -f $VPN_DH
|
|||||||
"$easyrsa_bin" --pki-dir="${VPN_PKI}" --keysize=2048 gen-dh 2>/dev/null
|
"$easyrsa_bin" --pki-dir="${VPN_PKI}" --keysize=2048 gen-dh 2>/dev/null
|
||||||
|
|
||||||
# update indexes and generate CRLs
|
# update indexes and generate CRLs
|
||||||
"$easyrsa_bin" --pki-dir="${ROOT_PKI}" update-db 2>/dev/null
|
|
||||||
"$easyrsa_bin" --pki-dir="${VPN_PKI}" update-db 2>/dev/null
|
"$easyrsa_bin" --pki-dir="${VPN_PKI}" update-db 2>/dev/null
|
||||||
"$easyrsa_bin" --pki-dir="${ROOT_PKI}" gen-crl 2>/dev/null
|
|
||||||
"$easyrsa_bin" --pki-dir="${VPN_PKI}" gen-crl 2>/dev/null
|
"$easyrsa_bin" --pki-dir="${VPN_PKI}" gen-crl 2>/dev/null
|
||||||
fi
|
fi
|
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.";
|
||||||
|
}
|
@ -12,7 +12,7 @@ usage() {
|
|||||||
echo " JWT_CRT Path to Token Auth certificate"
|
echo " JWT_CRT Path to Token Auth certificate"
|
||||||
echo " JWT_KEY Path to Token Auth private key"
|
echo " JWT_KEY Path to Token Auth private key"
|
||||||
echo " JWT_KID Path to KeyID for the Token Auth certificate"
|
echo " JWT_KID Path to KeyID for the Token Auth certificate"
|
||||||
echo " VPN_CA Path to the VPN sub-CA certificate"
|
echo " VPN_CA Path to the VPN CA certificate"
|
||||||
echo " VPN_CRT Path to the VPN server certificate"
|
echo " VPN_CRT Path to the VPN server certificate"
|
||||||
echo " VPN_KEY Path to the VPN server private key"
|
echo " VPN_KEY Path to the VPN server private key"
|
||||||
echo " VPN_DH Path to the VPN server Diffie Hellman parameters"
|
echo " VPN_DH Path to the VPN server Diffie Hellman parameters"
|
||||||
@ -40,40 +40,15 @@ b64file() {
|
|||||||
b64encode "$(cat "$@")"
|
b64encode "$(cat "$@")"
|
||||||
}
|
}
|
||||||
|
|
||||||
VPN_CONFIG=$(cat <<STR
|
# buckets to create in the S3 service...
|
||||||
client
|
REGISTRY2_S3_BUCKET="registry-data"
|
||||||
remote vpn.$DOMAIN 443
|
|
||||||
resolv-retry infinite
|
|
||||||
|
|
||||||
remote-cert-tls server
|
|
||||||
ca /etc/openvpn/ca.crt
|
|
||||||
auth-user-pass /var/volatile/vpn-auth
|
|
||||||
auth-retry none
|
|
||||||
script-security 2
|
|
||||||
up /etc/openvpn-misc/upscript.sh
|
|
||||||
up-restart
|
|
||||||
down /etc/openvpn-misc/downscript.sh
|
|
||||||
|
|
||||||
comp-lzo
|
|
||||||
dev resin-vpn
|
|
||||||
dev-type tun
|
|
||||||
proto tcp
|
|
||||||
nobind
|
|
||||||
|
|
||||||
persist-key
|
|
||||||
persist-tun
|
|
||||||
verb 3
|
|
||||||
user openvpn
|
|
||||||
group openvpn
|
|
||||||
|
|
||||||
STR
|
|
||||||
)
|
|
||||||
|
|
||||||
cat <<STR
|
cat <<STR
|
||||||
export OPENBALENA_PRODUCTION_MODE=false
|
export OPENBALENA_PRODUCTION_MODE=false
|
||||||
export OPENBALENA_COOKIE_SESSION_SECRET=$(randstr 32)
|
export OPENBALENA_COOKIE_SESSION_SECRET=$(randstr 32)
|
||||||
export OPENBALENA_HOST_NAME=$DOMAIN
|
export OPENBALENA_HOST_NAME=$DOMAIN
|
||||||
export OPENBALENA_JWT_SECRET=$(randstr 32)
|
export OPENBALENA_JWT_SECRET=$(randstr 32)
|
||||||
|
export OPENBALENA_REGISTRY2_S3_BUCKET=${REGISTRY2_S3_BUCKET}
|
||||||
export OPENBALENA_RESINOS_REGISTRY_CODE=$(randstr 32)
|
export OPENBALENA_RESINOS_REGISTRY_CODE=$(randstr 32)
|
||||||
export OPENBALENA_ROOT_CA=$(b64file "${ROOT_CA}")
|
export OPENBALENA_ROOT_CA=$(b64file "${ROOT_CA}")
|
||||||
export OPENBALENA_ROOT_CRT=$(b64file "${ROOT_CRT}")
|
export OPENBALENA_ROOT_CRT=$(b64file "${ROOT_CRT}")
|
||||||
@ -83,15 +58,20 @@ export OPENBALENA_TOKEN_AUTH_PUB=$(b64file "$JWT_CRT")
|
|||||||
export OPENBALENA_TOKEN_AUTH_KEY=$(b64file "$JWT_KEY")
|
export OPENBALENA_TOKEN_AUTH_KEY=$(b64file "$JWT_KEY")
|
||||||
export OPENBALENA_TOKEN_AUTH_KID=$(b64file "$JWT_KID")
|
export OPENBALENA_TOKEN_AUTH_KID=$(b64file "$JWT_KID")
|
||||||
export OPENBALENA_VPN_CA=$(b64file "$VPN_CA")
|
export OPENBALENA_VPN_CA=$(b64file "$VPN_CA")
|
||||||
export OPENBALENA_VPN_CA_CHAIN=$(b64file "$ROOT_CA" "$VPN_CA")
|
export OPENBALENA_VPN_CA_CHAIN=$(b64file "$VPN_CA")
|
||||||
export OPENBALENA_VPN_CONFIG=$(b64encode "$VPN_CONFIG")
|
|
||||||
export OPENBALENA_VPN_SERVER_CRT=$(b64file "$VPN_CRT")
|
export OPENBALENA_VPN_SERVER_CRT=$(b64file "$VPN_CRT")
|
||||||
export OPENBALENA_VPN_SERVER_KEY=$(b64file "$VPN_KEY")
|
export OPENBALENA_VPN_SERVER_KEY=$(b64file "$VPN_KEY")
|
||||||
export OPENBALENA_VPN_SERVER_DH=$(b64file "$VPN_DH")
|
export OPENBALENA_VPN_SERVER_DH=$(b64file "$VPN_DH")
|
||||||
export OPENBALENA_VPN_SERVICE_API_KEY=$(randstr 32)
|
export OPENBALENA_VPN_SERVICE_API_KEY=$(randstr 32)
|
||||||
export OPENBALENA_API_VPN_SERVICE_API_KEY=$(randstr 32)
|
export OPENBALENA_API_VPN_SERVICE_API_KEY=$(randstr 32)
|
||||||
export OPENBALENA_REGISTRY_SECRET_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_SSH_AUTHORIZED_KEYS=
|
||||||
export OPENBALENA_SUPERUSER_EMAIL=$SUPERUSER_EMAIL
|
export OPENBALENA_SUPERUSER_EMAIL=$SUPERUSER_EMAIL
|
||||||
export OPENBALENA_SUPERUSER_PASSWORD=$(printf "%q" "${SUPERUSER_PASSWORD}")
|
export OPENBALENA_SUPERUSER_PASSWORD=$(printf "%q" "${SUPERUSER_PASSWORD}")
|
||||||
|
export OPENBALENA_ACME_CERT_ENABLED=${ACME_CERT_ENABLED:-false}
|
||||||
STR
|
STR
|
||||||
|
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,11 +16,21 @@ RESET=`tput sgr0`
|
|||||||
OPENSSL_VERSION=$(openssl version -v)
|
OPENSSL_VERSION=$(openssl version -v)
|
||||||
if [[ "${OPENSSL_VERSION}" =~ ^LibreSSL.*$ ]]; then
|
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}"
|
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
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
source "${BASH_SOURCE%/*}/_realpath"
|
source "${BASH_SOURCE%/*}/_realpath"
|
||||||
|
|
||||||
|
domainResolves() {
|
||||||
|
getent hosts "$1" > /dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
CMD="$(realpath "$0")"
|
CMD="$(realpath "$0")"
|
||||||
DIR="$(dirname "${CMD}")"
|
DIR="$(dirname "${CMD}")"
|
||||||
BASE_DIR="$(dirname "${DIR}")"
|
BASE_DIR="$(dirname "${DIR}")"
|
||||||
@ -30,8 +40,9 @@ CERTS_DIR="${CONFIG_DIR}/certs"
|
|||||||
DOMAIN=openbalena.local
|
DOMAIN=openbalena.local
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "usage: $0 [-h] [-p] [-d DOMAIN] -U EMAIL -P PASSWORD"
|
echo "usage: $0 [-c] [-h] [-p] [-d DOMAIN] -U EMAIL -P PASSWORD"
|
||||||
echo
|
echo
|
||||||
|
echo " -c enable the ACME certificate service in staging or production mode."
|
||||||
echo " -p patch hosts - patch the host /etc/hosts file"
|
echo " -p patch hosts - patch the host /etc/hosts file"
|
||||||
echo " -d DOMAIN the domain name this deployment will run as, eg. example.com. Default is 'openbalena.local'"
|
echo " -d DOMAIN the domain name this deployment will run as, eg. example.com. Default is 'openbalena.local'"
|
||||||
echo " -U EMAIL the email address of the superuser account, used to login to your install from the Balena CLI"
|
echo " -U EMAIL the email address of the superuser account, used to login to your install from the Balena CLI"
|
||||||
@ -41,7 +52,7 @@ usage() {
|
|||||||
|
|
||||||
show_help=false
|
show_help=false
|
||||||
patch_hosts=false
|
patch_hosts=false
|
||||||
while getopts ":hpxd:U:P:" opt; do
|
while getopts ":chpxd:U:P:" opt; do
|
||||||
case "${opt}" in
|
case "${opt}" in
|
||||||
h) show_help=true;;
|
h) show_help=true;;
|
||||||
p) patch_hosts=true;;
|
p) patch_hosts=true;;
|
||||||
@ -49,6 +60,7 @@ while getopts ":hpxd:U:P:" opt; do
|
|||||||
d) DOMAIN="${OPTARG}";;
|
d) DOMAIN="${OPTARG}";;
|
||||||
U) SUPERUSER_EMAIL="${OPTARG}";;
|
U) SUPERUSER_EMAIL="${OPTARG}";;
|
||||||
P) SUPERUSER_PASSWORD="${OPTARG}";;
|
P) SUPERUSER_PASSWORD="${OPTARG}";;
|
||||||
|
c) ACME_CERT_ENABLED="true";;
|
||||||
*)
|
*)
|
||||||
echo "Invalid argument: -${OPTARG}"
|
echo "Invalid argument: -${OPTARG}"
|
||||||
usage
|
usage
|
||||||
@ -68,8 +80,17 @@ if [ "$show_help" = "true" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ ! -z "$ACME_CERT_ENABLED" ]; then
|
||||||
|
echo "${BLUE}[INFO]${RESET} ACME Certificate request is ${BOLD}ENABLED${RESET}."
|
||||||
|
|
||||||
|
if ! domainResolves "api.${DOMAIN}"; then
|
||||||
|
echo "${YELLOW}[WARN]${RESET} Unable to resolve \"api.${DOMAIN}\"!"
|
||||||
|
echo "${YELLOW}[WARN]${RESET} This might mean that you cannot use an ACME issued certificate."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
echo_bold() {
|
echo_bold() {
|
||||||
printf "\\033[1m%s\\033[0m\\n" "${@}"
|
echo "${BOLD}${@}${RESET}"
|
||||||
}
|
}
|
||||||
|
|
||||||
echo_bold "==> Creating new configuration at: $CONFIG_DIR"
|
echo_bold "==> Creating new configuration at: $CONFIG_DIR"
|
||||||
@ -110,5 +131,25 @@ fi
|
|||||||
echo_bold "==> Success!"
|
echo_bold "==> Success!"
|
||||||
echo ' - Start the instance with: ./scripts/compose up -d'
|
echo ' - Start the instance with: ./scripts/compose up -d'
|
||||||
echo ' - Stop the instance with: ./scripts/compose stop'
|
echo ' - Stop the instance with: ./scripts/compose stop'
|
||||||
echo ' - To create the superuser, see: ./scripts/create-superuser -h'
|
echo ' - To create a single, flat, docker-compose.yml file, run:'
|
||||||
echo " - Use the following certificate with Balena CLI: ${CERTS_DIR}/root/ca.crt"
|
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"
|
22
src/cert-provider/Dockerfile
Normal file
22
src/cert-provider/Dockerfile
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
FROM alpine
|
||||||
|
|
||||||
|
EXPOSE 80
|
||||||
|
WORKDIR /usr/src/app
|
||||||
|
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 fetch && git fetch --tags && \
|
||||||
|
git checkout 2.8.5 . && \
|
||||||
|
./acme.sh --install \
|
||||||
|
--cert-home /usr/src/app/certs
|
||||||
|
|
||||||
|
COPY entry.sh /entry.sh
|
||||||
|
COPY cert-provider.sh ./cert-provider.sh
|
||||||
|
COPY fake-le-bundle.pem ./
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/entry.sh" ]
|
||||||
|
CMD [ "/usr/src/app/cert-provider.sh" ]
|
190
src/cert-provider/cert-provider.sh
Executable file
190
src/cert-provider/cert-provider.sh
Executable file
@ -0,0 +1,190 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# the acme.sh client script, installed via Git in the Dockerfile...
|
||||||
|
ACME_BIN="$(realpath ~/.acme.sh/acme.sh)"
|
||||||
|
|
||||||
|
# the path to a bundle of certs to verify a LetsEncrypt staging certificate until Apr 2036...
|
||||||
|
ACME_STAGING_CA="/usr/src/app/fake-le-bundle.pem"
|
||||||
|
|
||||||
|
# the path to a file which stores the last successful mode of certificate we acquired...
|
||||||
|
ACME_MODE_FILE="/usr/src/app/certs/last_run_mode"
|
||||||
|
|
||||||
|
# colour output helpers...
|
||||||
|
reset=$(tput -T xterm sgr0)
|
||||||
|
red=$(tput -T xterm setaf 1)
|
||||||
|
green=$(tput -T xterm setaf 2)
|
||||||
|
yellow=$(tput -T xterm setaf 3)
|
||||||
|
blue=$(tput -T xterm setaf 4)
|
||||||
|
|
||||||
|
logError() {
|
||||||
|
echo "${red}[Error]${reset} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
logWarn() {
|
||||||
|
echo "${yellow}[Warn]${reset} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
logInfo() {
|
||||||
|
echo "${blue}[Info]${reset} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
logSuccess() {
|
||||||
|
echo "${green}[Success]${reset} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
logErrorAndStop() {
|
||||||
|
logError "$1 [Stopping]"
|
||||||
|
while true; do
|
||||||
|
# do nothing forever...
|
||||||
|
sleep 60
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
retryWithDelay() {
|
||||||
|
RETRIES=${2:-3}
|
||||||
|
DELAY=${3:-5}
|
||||||
|
|
||||||
|
local ATTEMPT=0
|
||||||
|
while [ "$RETRIES" -gt "$ATTEMPT" ]; do
|
||||||
|
(( ATTEMPT++ ))
|
||||||
|
logInfo "($ATTEMPT/$RETRIES) Connecting..."
|
||||||
|
if $1; then
|
||||||
|
logInfo "($ATTEMPT/$RETRIES) Success!"
|
||||||
|
return $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$RETRIES" -gt "$ATTEMPT" ]; then
|
||||||
|
logInfo "($ATTEMPT/$RETRIES) Failed. Retrying in ${DELAY} seconds..."
|
||||||
|
sleep "$DELAY"
|
||||||
|
else
|
||||||
|
logInfo "($ATTEMPT/$RETRIES) Failed!"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
waitForOnline() {
|
||||||
|
ADDRESS="${1,,}"
|
||||||
|
|
||||||
|
logInfo "Waiting for ${ADDRESS} to be available via HTTP..."
|
||||||
|
retryWithDelay "curl --output /dev/null --silent --head --fail --max-time 5 http://${ADDRESS}"
|
||||||
|
}
|
||||||
|
|
||||||
|
isUsingStagingCert() {
|
||||||
|
HOST="${1,,}"
|
||||||
|
echo "" | openssl s_client -host "$HOST" -port 443 -showcerts 2>/dev/null | awk '/BEGIN CERT/ {p=1} ; p==1; /END CERT/ {p=0}' | openssl verify -CAfile "$ACME_STAGING_CA" > /dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
pre-flight() {
|
||||||
|
case "$ACTIVE" in
|
||||||
|
"true"|"yes")
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
logError "ACTIVE variable is not enabled. Value should be \"true\" or \"yes\" to continue."
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -z "$DOMAINS" ]; then
|
||||||
|
logError "DOMAINS must be set. Value should be a comma-delimited string of domains."
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
IFS=, read -r -a ACME_DOMAINS <<< "$DOMAINS"
|
||||||
|
IFS=' ' read -r -a ACME_DOMAIN_ARGS <<< "${ACME_DOMAINS[@]/#/-d }"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$VALIDATION" ]; then
|
||||||
|
logInfo "VALIDATION not set. Using default: http-01"
|
||||||
|
VALIDATION="http-01"
|
||||||
|
else
|
||||||
|
case "$VALIDATION" in
|
||||||
|
"http-01")
|
||||||
|
logInfo "Using validation method: $VALIDATION"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
logError "VALIDATION is invalid. Use a valid value: http-01"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$OUTPUT_PEM" ]; then
|
||||||
|
logError "OUTPUT_PEM must be set. Value should be the path to install your certificate to."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
waitToSeeStagingCert() {
|
||||||
|
logInfo "Waiting for ${ACME_DOMAINS[0]} to use a staging certificate..."
|
||||||
|
retryWithDelay "isUsingStagingCert ${ACME_DOMAINS[0]}" 3 5
|
||||||
|
}
|
||||||
|
|
||||||
|
lastAcquiredCertFor() {
|
||||||
|
ACME_MODE="${1:-none}"
|
||||||
|
ACME_LAST_MODE="$(cat $ACME_MODE_FILE || echo '')"
|
||||||
|
logInfo "Last acquired certificate for ${ACME_LAST_MODE^^}"
|
||||||
|
[ "${ACME_LAST_MODE,,}" == "${ACME_MODE,,}" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
acquireCertificate() {
|
||||||
|
ACME_MODE="${1:-staging}"
|
||||||
|
ACME_FORCE="${2:-false}"
|
||||||
|
ACME_OPTS=()
|
||||||
|
|
||||||
|
if [ "${ACME_FORCE,,}" == "true" ];then ACME_OPTS+=("--force"); fi
|
||||||
|
case "$ACME_MODE" in
|
||||||
|
"production")
|
||||||
|
logInfo "Using PRODUCTION mode"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
logInfo "Using STAGING mode"
|
||||||
|
ACME_OPTS+=("--staging")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$VALIDATION" in
|
||||||
|
"http-01")
|
||||||
|
ACME_OPTS+=("--standalone")
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
logError "VALIDATION is invalid. Use a valid value: http-01"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if ! waitForOnline "${ACME_DOMAINS[0]}"; then
|
||||||
|
logError "Unable to access site over HTTP"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
logInfo "Issuing certificates..."
|
||||||
|
"$ACME_BIN" --issue "${ACME_OPTS[@]}" "${ACME_DOMAIN_ARGS[@]}"
|
||||||
|
|
||||||
|
logInfo "Installing certificates..." && \
|
||||||
|
"$ACME_BIN" --install-cert "${ACME_DOMAIN_ARGS[@]}" \
|
||||||
|
--cert-file /tmp/cert.pem \
|
||||||
|
--key-file /tmp/key.pem \
|
||||||
|
--fullchain-file /tmp/fullchain.pem \
|
||||||
|
--reloadcmd "cat /tmp/fullchain.pem /tmp/key.pem > $OUTPUT_PEM" && \
|
||||||
|
|
||||||
|
echo "${ACME_MODE}" > "${ACME_MODE_FILE}"
|
||||||
|
}
|
||||||
|
|
||||||
|
pre-flight || logErrorAndStop "Unable to continue due to misconfiguration. See errors above."
|
||||||
|
|
||||||
|
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."
|
||||||
|
waitToSeeStagingCert || logErrorAndStop "Unable to detect certificate change over. Cannot issue a production certificate."
|
||||||
|
acquireCertificate "production" "true" || logErrorAndStop "Unable to acquire a production certificate."
|
||||||
|
fi
|
||||||
|
|
||||||
|
logSuccess "Done!"
|
||||||
|
|
||||||
|
logInfo "Running cron..."
|
||||||
|
crond -f -d 7
|
3
src/cert-provider/entry.sh
Executable file
3
src/cert-provider/entry.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
exec "$@"
|
56
src/cert-provider/fake-le-bundle.pem
Normal file
56
src/cert-provider/fake-le-bundle.pem
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFATCCAumgAwIBAgIRAKc9ZKBASymy5TLOEp57N98wDQYJKoZIhvcNAQELBQAw
|
||||||
|
GjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDMyMzIyNTM0NloXDTM2
|
||||||
|
MDMyMzIyNTM0NlowGjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMIICIjANBgkq
|
||||||
|
hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA+pYHvQw5iU3v2b3iNuYNKYgsWD6KU7aJ
|
||||||
|
diddtZQxSWYzUI3U0I1UsRPTxnhTifs/M9NW4ZlV13ZfB7APwC8oqKOIiwo7IwlP
|
||||||
|
xg0VKgyz+kT8RJfYr66PPIYP0fpTeu42LpMJ+CKo9sbpgVNDZN2z/qiXrRNX/VtG
|
||||||
|
TkPV7a44fZ5bHHVruAxvDnylpQxJobtCBWlJSsbIRGFHMc2z88eUz9NmIOWUKGGj
|
||||||
|
EmP76x8OfRHpIpuxRSCjn0+i9+hR2siIOpcMOGd+40uVJxbRRP5ZXnUFa2fF5FWd
|
||||||
|
O0u0RPI8HON0ovhrwPJY+4eWKkQzyC611oLPYGQ4EbifRsTsCxUZqyUuStGyp8oa
|
||||||
|
aoSKfF6X0+KzGgwwnrjRTUpIl19A92KR0Noo6h622OX+4sZiO/JQdkuX5w/HupK0
|
||||||
|
A0M0WSMCvU6GOhjGotmh2VTEJwHHY4+TUk0iQYRtv1crONklyZoAQPD76hCrC8Cr
|
||||||
|
IbgsZLfTMC8TWUoMbyUDgvgYkHKMoPm0VGVVuwpRKJxv7+2wXO+pivrrUl2Q9fPe
|
||||||
|
Kk055nJLMV9yPUdig8othUKrRfSxli946AEV1eEOhxddfEwBE3Lt2xn0hhiIedbb
|
||||||
|
Ftf/5kEWFZkXyUmMJK8Ra76Kus2ABueUVEcZ48hrRr1Hf1N9n59VbTUaXgeiZA50
|
||||||
|
qXf2bymE6F8CAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB
|
||||||
|
Af8wHQYDVR0OBBYEFMEmdKSKRKDm+iAo2FwjmkWIGHngMA0GCSqGSIb3DQEBCwUA
|
||||||
|
A4ICAQBCPw74M9X/Xx04K1VAES3ypgQYH5bf9FXVDrwhRFSVckria/7dMzoF5wln
|
||||||
|
uq9NGsjkkkDg17AohcQdr8alH4LvPdxpKr3BjpvEcmbqF8xH+MbbeUEnmbSfLI8H
|
||||||
|
sefuhXF9AF/9iYvpVNC8FmJ0OhiVv13VgMQw0CRKkbtjZBf8xaEhq/YqxWVsgOjm
|
||||||
|
dm5CAQ2X0aX7502x8wYRgMnZhA5goC1zVWBVAi8yhhmlhhoDUfg17cXkmaJC5pDd
|
||||||
|
oenZ9NVhW8eDb03MFCrWNvIh89DDeCGWuWfDltDq0n3owyL0IeSn7RfpSclpxVmV
|
||||||
|
/53jkYjwIgxIG7Gsv0LKMbsf6QdBcTjhvfZyMIpBRkTe3zuHd2feKzY9lEkbRvRQ
|
||||||
|
zbh4Ps5YBnG6CKJPTbe2hfi3nhnw/MyEmF3zb0hzvLWNrR9XW3ibb2oL3424XOwc
|
||||||
|
VjrTSCLzO9Rv6s5wi03qoWvKAQQAElqTYRHhynJ3w6wuvKYF5zcZF3MDnrVGLbh1
|
||||||
|
Q9ePRFBCiXOQ6wPLoUhrrbZ8LpFUFYDXHMtYM7P9sc9IAWoONXREJaO08zgFtMp4
|
||||||
|
8iyIYUyQAbsvx8oD2M8kRvrIRSrRJSl6L957b4AFiLIQ/GgV2curs0jje7Edx34c
|
||||||
|
idWw1VrejtwclobqNMVtG3EiPUIpJGpbMcJgbiLSmKkrvQtGng==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEqzCCApOgAwIBAgIRAIvhKg5ZRO08VGQx8JdhT+UwDQYJKoZIhvcNAQELBQAw
|
||||||
|
GjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDUyMzIyMDc1OVoXDTM2
|
||||||
|
MDUyMzIyMDc1OVowIjEgMB4GA1UEAwwXRmFrZSBMRSBJbnRlcm1lZGlhdGUgWDEw
|
||||||
|
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtWKySDn7rWZc5ggjz3ZB0
|
||||||
|
8jO4xti3uzINfD5sQ7Lj7hzetUT+wQob+iXSZkhnvx+IvdbXF5/yt8aWPpUKnPym
|
||||||
|
oLxsYiI5gQBLxNDzIec0OIaflWqAr29m7J8+NNtApEN8nZFnf3bhehZW7AxmS1m0
|
||||||
|
ZnSsdHw0Fw+bgixPg2MQ9k9oefFeqa+7Kqdlz5bbrUYV2volxhDFtnI4Mh8BiWCN
|
||||||
|
xDH1Hizq+GKCcHsinDZWurCqder/afJBnQs+SBSL6MVApHt+d35zjBD92fO2Je56
|
||||||
|
dhMfzCgOKXeJ340WhW3TjD1zqLZXeaCyUNRnfOmWZV8nEhtHOFbUCU7r/KkjMZO9
|
||||||
|
AgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw
|
||||||
|
HQYDVR0OBBYEFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHoGCCsGAQUFBwEBBG4wbDA0
|
||||||
|
BggrBgEFBQcwAYYoaHR0cDovL29jc3Auc3RnLXJvb3QteDEubGV0c2VuY3J5cHQu
|
||||||
|
b3JnLzA0BggrBgEFBQcwAoYoaHR0cDovL2NlcnQuc3RnLXJvb3QteDEubGV0c2Vu
|
||||||
|
Y3J5cHQub3JnLzAfBgNVHSMEGDAWgBTBJnSkikSg5vogKNhcI5pFiBh54DANBgkq
|
||||||
|
hkiG9w0BAQsFAAOCAgEABYSu4Il+fI0MYU42OTmEj+1HqQ5DvyAeyCA6sGuZdwjF
|
||||||
|
UGeVOv3NnLyfofuUOjEbY5irFCDtnv+0ckukUZN9lz4Q2YjWGUpW4TTu3ieTsaC9
|
||||||
|
AFvCSgNHJyWSVtWvB5XDxsqawl1KzHzzwr132bF2rtGtazSqVqK9E07sGHMCf+zp
|
||||||
|
DQVDVVGtqZPHwX3KqUtefE621b8RI6VCl4oD30Olf8pjuzG4JKBFRFclzLRjo/h7
|
||||||
|
IkkfjZ8wDa7faOjVXx6n+eUQ29cIMCzr8/rNWHS9pYGGQKJiY2xmVC9h12H99Xyf
|
||||||
|
zWE9vb5zKP3MVG6neX1hSdo7PEAb9fqRhHkqVsqUvJlIRmvXvVKTwNCP3eCjRCCI
|
||||||
|
PTAvjV+4ni786iXwwFYNz8l3PmPLCyQXWGohnJ8iBm+5nk7O2ynaPVW0U2W+pt2w
|
||||||
|
SVuvdDM5zGv2f9ltNWUiYZHJ1mmO97jSY/6YfdOUH66iRtQtDkHBRdkNBsMbD+Em
|
||||||
|
2TgBldtHNSJBfB3pm9FblgOcJ0FSWcUDWJ7vO0+NTXlgrRofRT6pVywzxVo6dND0
|
||||||
|
WzYlTWeUVsO40xJqhgUQRER9YLOLxJ0O6C8i0xFxAMKOtSdodMB3RIwt7RFQ0uyt
|
||||||
|
n5Z5MqkYhlMI3J1tPRTp1nEt9fyGspBOO05gi148Qasp+3N+svqKomoQglNoAxU=
|
||||||
|
-----END CERTIFICATE-----
|
10
src/haproxy/Dockerfile
Normal file
10
src/haproxy/Dockerfile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
FROM haproxy:1.9-alpine
|
||||||
|
|
||||||
|
VOLUME [ "/certs" ]
|
||||||
|
|
||||||
|
RUN apk add --update inotify-tools
|
||||||
|
|
||||||
|
COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg
|
||||||
|
COPY start-haproxy.sh /start-haproxy
|
||||||
|
|
||||||
|
CMD /start-haproxy
|
@ -2,9 +2,9 @@ global
|
|||||||
tune.ssl.default-dh-param 1024
|
tune.ssl.default-dh-param 1024
|
||||||
|
|
||||||
defaults
|
defaults
|
||||||
timeout connect 5000
|
timeout connect 5s
|
||||||
timeout client 50000
|
timeout client 50s
|
||||||
timeout server 50000
|
timeout server 50s
|
||||||
|
|
||||||
frontend http-in
|
frontend http-in
|
||||||
mode http
|
mode http
|
||||||
@ -12,6 +12,9 @@ frontend http-in
|
|||||||
bind *:80
|
bind *:80
|
||||||
reqadd X-Forwarded-Proto:\ http
|
reqadd X-Forwarded-Proto:\ http
|
||||||
|
|
||||||
|
acl is_cert_validation path -i -m beg "/.well-known/acme-challenge/"
|
||||||
|
use_backend cert-provider if is_cert_validation
|
||||||
|
|
||||||
acl host_api hdr_dom(host) -i "api.${HAPROXY_HOSTNAME}"
|
acl host_api hdr_dom(host) -i "api.${HAPROXY_HOSTNAME}"
|
||||||
use_backend backend_api if host_api
|
use_backend backend_api if host_api
|
||||||
|
|
||||||
@ -31,6 +34,10 @@ frontend ssl-in
|
|||||||
tcp-request content accept if { req.ssl_hello_type 1 }
|
tcp-request content accept if { req.ssl_hello_type 1 }
|
||||||
|
|
||||||
acl is_ssl req.ssl_ver 2:3.4
|
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 redirect-to-https-in if is_ssl
|
||||||
use_backend vpn-devices if !is_ssl
|
use_backend vpn-devices if !is_ssl
|
||||||
|
|
||||||
@ -39,6 +46,11 @@ backend redirect-to-https-in
|
|||||||
balance roundrobin
|
balance roundrobin
|
||||||
server localhost 127.0.0.1:444 send-proxy-v2
|
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
|
frontend https-in
|
||||||
mode http
|
mode http
|
||||||
option forwardfor
|
option forwardfor
|
||||||
@ -61,28 +73,35 @@ backend backend_api
|
|||||||
mode http
|
mode http
|
||||||
option forwardfor
|
option forwardfor
|
||||||
balance roundrobin
|
balance roundrobin
|
||||||
server resin_api_1 api:80 check port 80
|
server balena_api_1 api:80 check port 80
|
||||||
|
|
||||||
backend backend_registry
|
backend backend_registry
|
||||||
mode http
|
mode http
|
||||||
option forwardfor
|
option forwardfor
|
||||||
balance roundrobin
|
balance roundrobin
|
||||||
server resin_registry_1 registry:80 check port 80
|
server balena_registry_1 registry:80 check port 80
|
||||||
|
|
||||||
backend backend_vpn
|
backend backend_vpn
|
||||||
mode http
|
mode http
|
||||||
option forwardfor
|
option forwardfor
|
||||||
balance roundrobin
|
balance roundrobin
|
||||||
server resin_vpn_1 vpn:80 check port 80
|
server balena_vpn_1 vpn:80 check port 80
|
||||||
|
|
||||||
backend backend_s3
|
backend backend_s3
|
||||||
mode http
|
mode http
|
||||||
option forwardfor
|
option forwardfor
|
||||||
balance roundrobin
|
balance roundrobin
|
||||||
|
server balena_s3_1 s3:80 check port 80
|
||||||
|
|
||||||
|
backend cert-provider
|
||||||
|
mode http
|
||||||
|
option forwardfor
|
||||||
|
balance roundrobin
|
||||||
|
server balena_cert-provider_1 cert-provider:80 no-check
|
||||||
|
|
||||||
backend vpn-devices
|
backend vpn-devices
|
||||||
mode tcp
|
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
|
frontend db
|
||||||
mode tcp
|
mode tcp
|
||||||
@ -92,7 +111,7 @@ frontend db
|
|||||||
|
|
||||||
backend backend_db
|
backend backend_db
|
||||||
mode tcp
|
mode tcp
|
||||||
server resin_db_1 db:5432 check port 5432
|
server balena_db_1 db:5432 check port 5432
|
||||||
|
|
||||||
frontend redis
|
frontend redis
|
||||||
mode tcp
|
mode tcp
|
||||||
@ -102,9 +121,14 @@ frontend redis
|
|||||||
|
|
||||||
backend backend_redis
|
backend backend_redis
|
||||||
mode tcp
|
mode tcp
|
||||||
server resin_redis_1 redis:6379 check port 6379
|
server balena_redis_1 redis:6379 check port 6379
|
||||||
|
|
||||||
listen vpn-tunnel
|
listen vpn-tunnel
|
||||||
mode tcp
|
mode tcp
|
||||||
bind *:3128
|
bind *:3128
|
||||||
server balena_vpn vpn:3128 check port 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
|
32
src/haproxy/start-haproxy.sh
Executable file
32
src/haproxy/start-haproxy.sh
Executable file
@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
OPENBALENA_CERT=/etc/ssl/private/open-balena.pem
|
||||||
|
mkdir -p "$(dirname "${OPENBALENA_CERT}")"
|
||||||
|
|
||||||
|
if [ -f "/certs/open-balena.pem" ]; then
|
||||||
|
echo "Using certificate from cert-provider..."
|
||||||
|
cp /certs/open-balena.pem "${OPENBALENA_CERT}"
|
||||||
|
else
|
||||||
|
echo "Building certificate from environment variables..."
|
||||||
|
(
|
||||||
|
echo "${BALENA_HAPROXY_CRT}" | base64 -d
|
||||||
|
echo "${BALENA_HAPROXY_KEY}" | base64 -d
|
||||||
|
echo "${BALENA_ROOT_CA}" | base64 -d
|
||||||
|
) > "${OPENBALENA_CERT}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
haproxy -f /usr/local/etc/haproxy/haproxy.cfg -W &
|
||||||
|
HAPROXY_PID=$!
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
inotifywait -r -e create -e modify -e delete /certs
|
||||||
|
|
||||||
|
if [ -f "/certs/open-balena.pem" ]; then
|
||||||
|
echo "Updating certificate from cert-provider..."
|
||||||
|
cp /certs/open-balena.pem "${OPENBALENA_CERT}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Certificate change detected. Reloading..."
|
||||||
|
kill -SIGUSR2 $HAPROXY_PID
|
||||||
|
sleep 1;
|
||||||
|
done
|
Reference in New Issue
Block a user