Compare commits
336 Commits
merge-logg
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
552abdd980 | ||
|
935007dd86 | ||
|
2cd1d053f0 | ||
|
a1c8620cc0 | ||
|
39a7fc04fb | ||
|
a8b5fb5c1e | ||
|
18e22b24ea | ||
|
b53a3ed3f7 | ||
|
112787b3aa | ||
|
4f46ff7ee6 | ||
|
845de093ba | ||
|
65e83ed885 | ||
|
b98d69b33e | ||
|
d159b98c3c | ||
|
1ef5c3980d | ||
|
ffc569e275 | ||
|
0e28af9eb1 | ||
|
4aec218719 | ||
|
07a9b3bd81 | ||
|
78b9b8589e | ||
|
be3fd59c8c | ||
|
6480f5e5ff | ||
|
280238d95d | ||
|
44b378abba | ||
|
a6d7972bef | ||
|
625d9848a5 | ||
|
3bcb9ea13a | ||
|
72a30b9144 | ||
|
f0019ea983 | ||
|
d15aad7bcf | ||
|
e351615a69 | ||
|
2296ef52fa | ||
|
850c4894e7 | ||
|
edf443bed5 | ||
|
6cb6ee6952 | ||
|
762d12b61e | ||
|
0e6aa957a4 | ||
|
150c54da40 | ||
|
75bd599a33 | ||
|
f0c80ee5b8 | ||
|
41573c3260 | ||
|
037e08a41a | ||
|
f1b76d4313 | ||
|
c19c4db897 | ||
|
31fdbccfad | ||
|
208b11af0a | ||
|
5649730446 | ||
|
90eda1dfc1 | ||
|
fd97d41524 | ||
|
abbe6ddd1a | ||
|
acdfa20b2b | ||
|
34dc33a01d | ||
|
4747d9b7fb | ||
|
35f553ae5a | ||
|
8f2fadb3c4 | ||
|
8e6b620e8c | ||
|
523fc2850c | ||
|
968d3809a5 | ||
|
2ccef8948d | ||
|
08de1e0676 | ||
|
b2e66a01fc | ||
|
23f8cfc8dd | ||
|
878a26a411 | ||
|
656dd829ca | ||
|
10bcb68c9d | ||
|
e0c9c4e5b3 | ||
|
d936080393 | ||
|
809ee6e68b | ||
|
e0b185b5ef | ||
|
9815230eba | ||
|
8cb556275f | ||
|
48a7bb8c2d | ||
|
a26a0d27d7 | ||
|
028c7dbde5 | ||
|
103a4941c7 | ||
|
a261114bbc | ||
|
e2640fac08 | ||
|
33280f90b3 | ||
|
8b60ece3d4 | ||
|
47efae4e6c | ||
|
25d15c9596 | ||
|
515bd7789d | ||
|
6abb5db6ee | ||
|
699c4e76d5 | ||
|
703889d4ea | ||
|
05cf00d272 | ||
|
c531faec52 | ||
|
4e9aefcafd | ||
|
fb338b414b | ||
|
f1bdbf21c2 | ||
|
c3e3f0a1f8 | ||
|
df4e5045be | ||
|
4a0889138f | ||
|
f717c53e8b | ||
|
0206279894 | ||
|
fbb1081ed5 | ||
|
aad6f1db6e | ||
|
2599cff4cb | ||
|
25b916d969 | ||
|
37600727a4 | ||
|
f4860ec662 | ||
|
20e56a755e | ||
|
c60265791e | ||
|
2e159050e9 | ||
|
25090a8129 | ||
|
be5383b164 | ||
|
3720ef838d | ||
|
071fcbb96b | ||
|
abfb1c6404 | ||
|
0369a18c6e | ||
|
57f74b0d46 | ||
|
93142ba305 | ||
|
f289f79ec3 | ||
|
6b0f8a3d45 | ||
|
6f776a8c51 | ||
|
55dc3a1d2a | ||
|
91ccc819d5 | ||
|
bf0ed8fd1c | ||
|
8a54fa3f27 | ||
|
26f9e1747f | ||
|
4a3c4ce0c5 | ||
|
903b286d3f | ||
|
f4ab771e2a | ||
|
cd647f090b | ||
|
85670538c6 | ||
|
90780eab91 | ||
|
1fabae0f48 | ||
|
75af48bc5d | ||
|
0323fbe1c8 | ||
|
dbb61b9a46 | ||
|
3a40d27778 | ||
|
1d1329b77e | ||
|
d9374dc48e | ||
|
a760ef7869 | ||
|
3b9d6a7eb2 | ||
|
663ba19c8b | ||
|
70b2a68f34 | ||
|
2b0f691d5f | ||
|
18f8ea982e | ||
|
d6cec2ff1a | ||
|
29e0077edb | ||
|
73c1290c52 | ||
|
26e839ea7b | ||
|
e881f8007e | ||
|
6f3f4b6779 | ||
|
a5274f123c | ||
|
fc12634fbb | ||
|
a5ce75a29b | ||
|
701784930b | ||
|
aa717c2323 | ||
|
9836d27052 | ||
|
e361b493b1 | ||
|
b28460cf84 | ||
|
07e3678c78 | ||
|
c315ebe319 | ||
|
36dd6b5eff | ||
|
2f1f51bad1 | ||
|
bada24f3f6 | ||
|
2d5afd8149 | ||
|
dfb949eecc | ||
|
49771980a6 | ||
|
7e31184bd6 | ||
|
49226f1640 | ||
|
4251c32b30 | ||
|
ece5385a38 | ||
|
35d5df14aa | ||
|
1c437b99eb | ||
|
9580b2dd7d | ||
|
f382765f29 | ||
|
f5951add54 | ||
|
2b4efc2c61 | ||
|
8ab854c822 | ||
|
005323ff3c | ||
|
390e918417 | ||
|
c5ccfa0fa1 | ||
|
87b71cb9d4 | ||
|
89bd18a76b | ||
|
6e61c08b2c | ||
|
54b6acc46c | ||
|
e5e98d536a | ||
|
8df91de3af | ||
|
7557966c98 | ||
|
fa5d3ae3a1 | ||
|
d68444be9e | ||
|
f7bc8efabe | ||
|
f5284ba725 | ||
|
293d3ff558 | ||
|
c00319ab01 | ||
|
8b4141670c | ||
|
23c852125d | ||
|
b4eae2e5e5 | ||
|
9e953319cf | ||
|
0814fa9146 | ||
|
0e1b6c858b | ||
|
28618bd3ac | ||
|
b04bfea1c7 | ||
|
bc0ef0d6fc | ||
|
16c91fedd1 | ||
|
9f5945094c | ||
|
76513a1f35 | ||
|
86eb8d7fde | ||
|
e31b3d3173 | ||
|
58b13d7528 | ||
|
b0fca49ecb | ||
|
79dacf557e | ||
|
d6caf03301 | ||
|
9b90712d28 | ||
|
1dd3fe6fcd | ||
|
29953c17d9 | ||
|
3b59adfe34 | ||
|
00c8a988e1 | ||
|
524fb6a44c | ||
|
e99bedf9e4 | ||
|
0d98c442a2 | ||
|
bcc15ecdb0 | ||
|
a617629a7a | ||
|
f7ae400eb3 | ||
|
7141d364e1 | ||
|
057ce223f1 | ||
|
7511b25e47 | ||
|
62b447d61f | ||
|
88d2a75575 | ||
|
8cb6617a0f | ||
|
1a649c56cb | ||
|
fd655274f8 | ||
|
946d1a068d | ||
|
e8651976ca | ||
|
af52ba1fec | ||
|
499c08c374 | ||
|
08281891a1 | ||
|
5bce042922 | ||
|
3276c9fe47 | ||
|
040374e781 | ||
|
621c8cd5c4 | ||
|
7434b67c34 | ||
|
17306a753b | ||
|
2e3f4cabd8 | ||
|
cf2308cdd7 | ||
|
eec49d6dd1 | ||
|
d6195ad6d7 | ||
|
fd04c5a6e9 | ||
|
1c9d7282b2 | ||
|
dd9c485c66 | ||
|
99ab5bf369 | ||
|
25a0afed65 | ||
|
44e22db11b | ||
|
3321010089 | ||
|
e04c4626f2 | ||
|
65ce949e03 | ||
|
5931cbd791 | ||
|
0bbff91722 | ||
|
7f5e753dfd | ||
|
d3776f4424 | ||
|
544c4e86ba | ||
|
516309b478 | ||
|
dfd7e29a30 | ||
|
bb30fa28da | ||
|
044de5824b | ||
|
00cdce7bd2 | ||
|
f163d4b0fa | ||
|
e0032fb74a | ||
|
152dfe9349 | ||
|
5a95ae97a0 | ||
|
98e674b8e8 | ||
|
b655cf20be | ||
|
5bc702bf96 | ||
|
4bd842db66 | ||
|
a8f7faddb9 | ||
|
e5b2a426f0 | ||
|
29b22fe162 | ||
|
c082645da0 | ||
|
156d5d8fba | ||
|
d2cdb11fcc | ||
|
cef06a82a6 | ||
|
9a630a0440 | ||
|
1c6651b18b | ||
|
5f7df4694f | ||
|
7feeab24ec | ||
|
1a6688cfbf | ||
|
f90e1d154c | ||
|
6cc265e931 | ||
|
854ae23f60 | ||
|
43e7672725 | ||
|
4e913c426d | ||
|
8a08de51e4 | ||
1c7a51bce1 | |||
|
5d84cef63c | ||
|
eda5198904 | ||
|
a4a3dccd66 | ||
|
a2d249e3a1 | ||
|
dc83baea12 | ||
|
d6b4a4744f | ||
|
6ba2657dc1 | ||
|
ac6b805cbf | ||
|
d4e52a9de3 | ||
|
aa59c1ad43 | ||
|
36f1d679ae | ||
|
f5c8ee1136 | ||
|
9a17817cc8 | ||
|
b2e3292453 | ||
|
13fafb5929 | ||
|
114f99ae2e | ||
|
fff4b10a41 | ||
|
ab1353603d | ||
|
1600b6277f | ||
b79e35f982 | |||
703dbe0a0f | |||
|
7abb0191e1 | ||
|
886ae5b7f2 | ||
|
5411c85793 | ||
|
caa315e361 | ||
|
e6b24fe65c | ||
|
81782bb5f0 | ||
|
406b9e374e | ||
|
ce0e0e893c | ||
|
fac45f276e | ||
|
44d3ac3a1c | ||
|
5da9f26076 | ||
|
4e99cf1ded | ||
|
55324524ca | ||
|
b6928959cb | ||
|
8ddb290683 | ||
|
2cb1134a54 | ||
|
c4b1ac482e | ||
|
29cc392dff | ||
|
8839bd4595 | ||
|
0179f600f5 | ||
|
15f0233351 | ||
|
bbaacb7b9f | ||
|
6761574d74 | ||
|
8384af8b95 | ||
|
b9e97688d6 | ||
|
1055805c8d | ||
|
678906cb39 | ||
|
11c50ae98d | ||
|
e911ab246b |
28
.drone.yml
28
.drone.yml
@ -6,28 +6,44 @@ steps:
|
|||||||
image: koalaman/shellcheck-alpine:v0.7.1
|
image: koalaman/shellcheck-alpine:v0.7.1
|
||||||
commands:
|
commands:
|
||||||
- shellcheck abra
|
- shellcheck abra
|
||||||
|
- shellcheck bin/*.sh
|
||||||
|
|
||||||
|
- name: run flake8
|
||||||
|
image: alpine/flake8:3.9.0
|
||||||
|
commands:
|
||||||
|
- flake8 --max-line-length 100 bin/app-json.py
|
||||||
|
|
||||||
- name: run unit tests
|
- name: run unit tests
|
||||||
image: docker:dind
|
image: decentral1se/docker-dind-bats-kcov
|
||||||
commands:
|
commands:
|
||||||
- apk add bats git bash
|
|
||||||
- bats tests
|
- bats tests
|
||||||
|
|
||||||
- name: collect code coverage
|
- name: collect code coverage
|
||||||
failure: ignore # until we fix this
|
failure: ignore # until we fix this
|
||||||
image: kcov/kcov:38
|
image: decentral1se/docker-dind-bats-kcov
|
||||||
commands:
|
commands:
|
||||||
- apt update && apt install -y bats git bash
|
|
||||||
- kcov . bats tests || true
|
- kcov . bats tests || true
|
||||||
|
|
||||||
- name: send code coverage report to codecov
|
- name: send code coverage report to codecov
|
||||||
failure: ignore # until we fix this
|
failure: ignore # until we fix this
|
||||||
image: plugins/codecov
|
image: plugins/codecov
|
||||||
settings:
|
settings:
|
||||||
token:
|
token:
|
||||||
from_secret: codecov_token
|
from_secret: codecov_token
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
|
- name: notify rocket chat
|
||||||
|
image: plugins/slack
|
||||||
|
settings:
|
||||||
|
webhook:
|
||||||
|
from_secret: rc_builds_url
|
||||||
|
username: comradebritney
|
||||||
|
channel: "internal.builds"
|
||||||
|
template: "{{repo.owner}}/{{repo.name}} build failed: {{build.link}}"
|
||||||
|
when:
|
||||||
|
status:
|
||||||
|
- failure
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
branch:
|
branch:
|
||||||
- main
|
- main
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,2 @@
|
|||||||
coverage/
|
|
||||||
/.venv
|
/.venv
|
||||||
|
coverage/
|
||||||
|
97
CHANGELOG.md
97
CHANGELOG.md
@ -1,10 +1,103 @@
|
|||||||
|
> 🔥 🔥 🔥 Please note, while we are still in
|
||||||
|
> [public alpha](https://docs.cloud.autonomic.zone/roadmap/), the `abra` release
|
||||||
|
> versioning scheme is not following [semver](https://semver.org/) conventions
|
||||||
|
> because we are still in the exploratory phases of building this tool. Please
|
||||||
|
> read the changes before upgrading your `abra` installation as there are
|
||||||
|
> **most likely** breaking changes coming each release. Sorry for any
|
||||||
|
> inconvenience caused, we're working hard to make this tool stable. Semver
|
||||||
|
> will be respected when we reach public beta. 🔥 🔥 🔥
|
||||||
|
|
||||||
# abra x.x.x (UNRELEASED)
|
# abra x.x.x (UNRELEASED)
|
||||||
|
|
||||||
|
- Sort `apps.json` when publishing ([39a7fc0](https://git.autonomic.zone/coop-cloud/abra/commit/39a7fc04fb5df1a6d78b84f51838530ab3eb76db))
|
||||||
|
- Fix publishing of rating for new apps ([0e28af9](https://git.autonomic.zone/coop-cloud/abra/commit/0e28af9eb1af6c6da705b4614ddd173c60576629))
|
||||||
|
- Detect compose filenames in `n+1` release generation ([ffc569e](https://git.autonomic.zone/coop-cloud/abra/commit/ffc569e275df7ca784a4db1a3331e17975fd8c87))
|
||||||
|
|
||||||
|
# abra 0.7.3 (2021-04-28)
|
||||||
|
|
||||||
|
- Only check for pw(q)gen if we're actually trying to use them ([#147](https://git.autonomic.zone/coop-cloud/abra/issues/147))
|
||||||
|
- Use apps.coopcloud.tech for app data hosting & download ([75bd599](https://git.autonomic.zone/coop-cloud/abra/commit/75bd599))
|
||||||
|
- Choose latest commit messages for new tags ([#144](https://git.autonomic.zone/coop-cloud/abra/issues/144))
|
||||||
|
- Handle recipes without an `app` service in `recipe .. release` ([#151](https://git.autonomic.zone/coop-cloud/abra/issues/151))
|
||||||
|
|
||||||
|
# abra 0.7.2 (2021-04-07)
|
||||||
|
|
||||||
|
- Fix installation script development installs (again! Thanks Bash!) ([4747d9b7](https://git.autonomic.zone/coop-cloud/abra/commit/4747d9b7fb5fba914f210b6570bfe2db0b53da23))
|
||||||
|
|
||||||
|
# abra 0.7.1 (2021-04-07)
|
||||||
|
|
||||||
|
- Fix installation script development installs ([8f2fadb3c](https://git.autonomic.zone/coop-cloud/abra/commit/8f2fadb3c43c5915520f5ea531ea3815c2ba8531))
|
||||||
|
|
||||||
|
# abra 0.7.0 (2021-04-07)
|
||||||
|
|
||||||
|
- Add `--force` to the `deploy` command to allow overriding deployment logic ([#105](https://git.autonomic.zone/coop-cloud/abra/issues/105))
|
||||||
|
- Handle undeployed apps in version summaries when deploying ([#104](https://git.autonomic.zone/coop-cloud/abra/issues/104))
|
||||||
|
- Add `--force` to `undeploy` command ([e5e98d5](https://git.autonomic.zone/coop-cloud/abra/commit/e5e98d5))
|
||||||
|
- Rename "app type" back to "stack" in the deployment overview ([54b6acc](https://git.autonomic.zone/coop-cloud/abra/commit/54b6acc))
|
||||||
|
- Show context connection details on `abra server ls` ([#110](https://git.autonomic.zone/coop-cloud/abra/issues/110))
|
||||||
|
- Allow to debug the SSH connection details on swarm init ([#109](https://git.autonomic.zone/coop-cloud/abra/issues/109))
|
||||||
|
- Show correct status for apps deployed on servers with missing context ([#99](https://git.autonomic.zone/coop-cloud/abra/issues/99))
|
||||||
|
- Search for subcommands in descending order of how many components there are ([#108](https://git.autonomic.zone/coop-cloud/abra/issues/108))
|
||||||
|
- Add specific app version checking command (`abra app <app> version`) ([#108](https://git.autonomic.zone/coop-cloud/abra/issues/108))
|
||||||
|
- Add docker version check (guestimating < v19 is a bad idea) ([#15](https://git.autonomic.zone/coop-cloud/abra/issues/15))
|
||||||
|
- Fix git branch handling when not passing `-b <branch>` ([#122](https://git.autonomic.zone/coop-cloud/abra/issues/122))
|
||||||
|
- Add work-around to correctly git clone non-master default branch app repositories ([#122](https://git.autonomic.zone/coop-cloud/abra/issues/122))
|
||||||
|
- Replace `--force` (except for the `deploy` command) with a global `--no-prompt` for avoiding interactive questions ([#118](https://git.autonomic.zone/coop-cloud/abra/issues/118))
|
||||||
|
- Use [docker-stack-wait-deploy](https://github.com/vitalets/docker-stack-wait-deploy) inspired logic to deploy apps ([#116](https://git.autonomic.zone/coop-cloud/abra/issues/116))
|
||||||
|
- Add a domain polling check when deploying apps ([#113](https://git.autonomic.zone/coop-cloud/abra/issues/113))
|
||||||
|
- Recognise when apps are already undeployed with `abra app <app> undeploy` ([#123](https://git.autonomic.zone/coop-cloud/abra/issues/123))
|
||||||
|
- Add `abra doctor` command to help diagnose setup issues ([#119](https://git.autonomic.zone/coop-cloud/abra/issues/119))
|
||||||
|
- Add apps version and feature catalogue generation script ([#121](https://git.autonomic.zone/coop-cloud/abra/issues/121))
|
||||||
|
- New `--skip-version-check` option to `deploy` ([df4e504](https://git.autonomic.zone/coop-cloud/abra/commit/df4e504))
|
||||||
|
- Look up local available version from compose files instead of `abra.sh` ([#131](https://git.autonomic.zone/coop-cloud/abra/issues/131))
|
||||||
|
- Improve domain polling logging and allow to skip the check altogether with `--no-domain-poll` ([#140](https://git.autonomic.zone/coop-cloud/abra/issues/140), [#141](https://git.autonomic.zone/coop-cloud/abra/issues/141))
|
||||||
|
- Support `ABRA_DIR` in the installer script ([4e94a424e94a42](https://git.autonomic.zone/coop-cloud/abra/commit/4e94a424e94a42))
|
||||||
|
- Support [abra-hetzner](https://git.autonomic.zone/coop-cloud/abra-hetzner) plugin ([#88](https://git.autonomic.zone/coop-cloud/abra/issues/88))
|
||||||
|
|
||||||
|
# abra 0.6.0 (2021-03-17)
|
||||||
|
|
||||||
|
- Show version and digest of app if labelled ([98e674b8e8](https://git.autonomic.zone/coop-cloud/abra/commit/98e674b8e83458a83dcbf331e8e34c7188559c4a))
|
||||||
|
- Implement basic version checking on deployment ([#82](https://git.autonomic.zone/coop-cloud/abra/issues/82))
|
||||||
|
- New `app-catalogue.sh` script to auto-generate app list for documentation ([f163d4b](https://git.autonomic.zone/coop-cloud/abra/commit/f163d4b0fa920232e9d995a22d20fe78b174b3a9))
|
||||||
|
- Support app service rollbacks with `abra <app> rollback <service>` ([#76](https://git.autonomic.zone/coop-cloud/abra/issues/76))
|
||||||
|
- Detect when latest version is deployed and perform a no-op ([#87](https://git.autonomic.zone/coop-cloud/abra/issues/87))
|
||||||
|
- Allow cloning of app repos with different main branches using `-b, --branch=<branch>` ([#80](https://git.autonomic.zone/coop-cloud/abra/issues/80))
|
||||||
|
- Protect against lengthy app names which gives Docker trouble later on ([#83](https://git.autonomic.zone/coop-cloud/abra/issues/83))
|
||||||
|
- Support removal of secrets and volumes when `rm`'ing apps ([#44](https://git.autonomic.zone/coop-cloud/abra/issues/44))
|
||||||
|
- Always choose the default IPv4 address with `abra server <host> init` ([#91](https://git.autonomic.zone/coop-cloud/abra/issues/91))
|
||||||
|
- Add `--type=<type>` filtering option to `abra <app> ls` ([0828189](https://git.autonomic.zone/coop-cloud/abra/commit/0828189))
|
||||||
|
- Check for bash 4+ ([#96](https://git.autonomic.zone/coop-cloud/abra/commit/0828189))
|
||||||
|
- Add `--dev` option to installer using `git clone` ([88d2a75](https://git.autonomic.zone/coop-cloud/abra/commit/88d2a75))
|
||||||
|
- Support `--dev` on the `abra upgrade` command also ([bcc15ec](https://git.autonomic.zone/coop-cloud/abra/commit/bcc15ec))
|
||||||
|
- Vendor [yq](https://github.com/mikefarah/yq/releases) automatically ([3b59adf](https://git.autonomic.zone/coop-cloud/abra/commit/3b59adf))
|
||||||
|
- Extend version handling logic to support all underlying services ([#90](https://git.autonomic.zone/coop-cloud/abra/issues/90))
|
||||||
|
- Fix development installation script symlink issue ([#98](https://git.autonomic.zone/coop-cloud/abra/issues/98))
|
||||||
|
- Add `app-version.sh` script to help packagers version apps ([28618bd](https://git.autonomic.zone/coop-cloud/abra/commit/28618bd))
|
||||||
|
- Add git digest to `abra version` output ([8b41416](https://git.autonomic.zone/coop-cloud/abra/commit/8b41416))
|
||||||
|
|
||||||
|
# abra 0.5.0 (2021-03-01)
|
||||||
|
|
||||||
|
- `secret auto` merged into `secret generate` and `app new --auto` is now `app new --secrets` ([#64](https://git.autonomic.zone/coop-cloud/abra/pulls/64))
|
||||||
|
- Avoid outputting length during secret generation when not in use ([#67](https://git.autonomic.zone/coop-cloud/abra/issues/67))
|
||||||
|
- Support graceful failure when missing secret generation commands ([44d3ac3](https://git.autonomic.zone/coop-cloud/abra/commit/44d3ac3a1cb86edc9b9e91eea1a00e70eae14965))
|
||||||
|
- Fix secret detection when using new `.env` file format in apps ([5532452](https://git.autonomic.zone/coop-cloud/abra/commit/55324524ca77141666ffe6cc41b62cc71cf89ace))
|
||||||
|
- Support choosing an `$EDITOR` when editing configs ([29cc392](https://git.autonomic.zone/coop-cloud/abra/commit/29cc392dff3e93e48e0e2edd3ce11b405c66a95a))
|
||||||
|
- "server" shell completion fixed ([8839bd4](https://git.autonomic.zone/coop-cloud/abra/commit/8839bd45951d00dccf4ef81ece445bcc49e13ee6))
|
||||||
- Drop `multilogs` command ([#56](https://git.autonomic.zone/coop-cloud/abra/pulls/56))
|
- Drop `multilogs` command ([#56](https://git.autonomic.zone/coop-cloud/abra/pulls/56))
|
||||||
- Remove `server use` command ([#51](https://git.autonomic.zone/coop-cloud/abra/issues/51))
|
- Remove `server use` command ([#51](https://git.autonomic.zone/coop-cloud/abra/issues/51))
|
||||||
- `new <app>` becomes `new <type>` ([#48](https://git.autonomic.zone/coop-cloud/abra/issues/48))
|
- `new <app>` becomes `new <type>` ([#48](https://git.autonomic.zone/coop-cloud/abra/issues/48))
|
||||||
- `check` is run on `deploy` now and configurable ([77ba5652b2fe15820f5edfa0f642636f7b8eae7e](https://git.autonomic.zone/coop-cloud/abra/commit/77ba5652b2fe15820f5edfa0f642636f7b8eae7e))
|
- `check` is run on `deploy` now and configurable ([77ba565](https://git.autonomic.zone/coop-cloud/abra/commit/77ba5652b2fe15820f5edfa0f642636f7b8eae7e))
|
||||||
- App configurations are always updated now ([#42](https://git.autonomic.zone/coop-cloud/abra/issues/42))
|
- App configurations are always updated now ([#42](https://git.autonomic.zone/coop-cloud/abra/issues/42))
|
||||||
|
- We use docker format `.env` files (no "export" syntax) from now now ([#55](https://git.autonomic.zone/coop-cloud/abra/pulls/55))
|
||||||
|
- Rename `<domain>` option to `<app>` and `APP` variable to `TYPE`, see ([#47](https://git.autonomic.zone/coop-cloud/abra/issues/47))
|
||||||
|
- Use Docker-in-Docker (dind), and `dind-bats-kcov` Docker image, for `make test` ([1600b62](https://git.autonomic.zone/coop-cloud/abra/commit/1600b6277fbbffc4c6de1e4ba799c7bbe72ec6a0))
|
||||||
|
- Add built-in documentation using `abra help <subcommand>...`, see ([#50](https://git.autonomic.zone/coop-cloud/abra/issues/50))
|
||||||
|
- `version` subcommand ([e6b24fe](https://git.autonomic.zone/coop-cloud/abra/commit/e6b24fe))
|
||||||
|
- Use `# length=x` comments to generate passwords with `pwgen` and drop `KEY`/`PASSWORD` logic ([#68](https://git.autonomic.zone/coop-cloud/abra/issues/68))
|
||||||
|
- Global `--skip-update|-U` / `--skip-check|-C` options to make things quicker ([37e8b00](https://git.autonomic.zone/coop-cloud/abra/commit/37e8b00))
|
||||||
|
- `app backup` and `app restore` commands; requires per-app definition ([#70](https://git.autonomic.zone/coop-cloud/abra/issues/70))
|
||||||
|
- Rename per-type `abra-commands.sh` to `abra.sh`, and include config versions as type-level instead of app-level config ([#43](https://git.autonomic.zone/coop-cloud/abra/issues/43))
|
||||||
|
- Show per-subcommand help by adding `-h/--help` to a command line ([#38](https://git.autonomic.zone/coop-cloud/abra/issues/78))
|
||||||
|
|
||||||
# abra 0.4.1 (2020-12-24)
|
# abra 0.4.1 (2020-12-24)
|
||||||
|
|
||||||
@ -14,7 +107,7 @@
|
|||||||
# abra 0.4.0 (2020-12-24)
|
# abra 0.4.0 (2020-12-24)
|
||||||
|
|
||||||
- New command-line interface based on docopt
|
- New command-line interface based on docopt
|
||||||
- ~/.abra directory instead of expecting local .env files
|
- `~/.abra` directory instead of expecting local `.env` files
|
||||||
- Integration tests & code coverage
|
- Integration tests & code coverage
|
||||||
|
|
||||||
# abra 0.3.1 (2020-09-27)
|
# abra 0.3.1 (2020-09-27)
|
||||||
|
38
Makefile
38
Makefile
@ -1,38 +0,0 @@
|
|||||||
.PHONY: test shellcheck docopt kcov codecov
|
|
||||||
|
|
||||||
test:
|
|
||||||
@DOCKER_CONTEXT=default docker run \
|
|
||||||
-it \
|
|
||||||
--rm \
|
|
||||||
-v $$(pwd):/workdir \
|
|
||||||
docker:dind \
|
|
||||||
sh -c "apk add bats git bash && cd /workdir && bats /workdir/test.bats"
|
|
||||||
|
|
||||||
shellcheck:
|
|
||||||
@docker run \
|
|
||||||
-it \
|
|
||||||
--rm \
|
|
||||||
-v $$(pwd):/workdir \
|
|
||||||
koalaman/shellcheck-alpine \
|
|
||||||
shellcheck /workdir/abra
|
|
||||||
|
|
||||||
docopt:
|
|
||||||
@if [ ! -d ".venv" ]; then \
|
|
||||||
python3 -m venv .venv && \
|
|
||||||
.venv/bin/pip install -U pip setuptools wheel && \
|
|
||||||
.venv/bin/pip install docopt-sh; \
|
|
||||||
fi
|
|
||||||
.venv/bin/docopt.sh abra
|
|
||||||
|
|
||||||
kcov:
|
|
||||||
@docker run \
|
|
||||||
-it \
|
|
||||||
--rm \
|
|
||||||
-v $$(pwd):/workdir \
|
|
||||||
kcov/kcov:latest \
|
|
||||||
sh -c "kcov /workdir/coverage /workdir/abra || true"
|
|
||||||
|
|
||||||
codecov: SHELL:=/bin/bash
|
|
||||||
codecov:
|
|
||||||
@bash <(curl -s https://codecov.io/bash) \
|
|
||||||
-s coverage -t $$(pass show hosts/swarm.autonomic.zone/drone/codecov/token)
|
|
79
README.md
79
README.md
@ -3,16 +3,91 @@
|
|||||||
[![Build Status](https://drone.autonomic.zone/api/badges/coop-cloud/abra/status.svg)](https://drone.autonomic.zone/coop-cloud/abra)
|
[![Build Status](https://drone.autonomic.zone/api/badges/coop-cloud/abra/status.svg)](https://drone.autonomic.zone/coop-cloud/abra)
|
||||||
[![codecov](https://codecov.io/gh/Autonomic-Cooperative/abra/branch/main/graph/badge.svg?token=aX3I5NMRsj)](undefined)
|
[![codecov](https://codecov.io/gh/Autonomic-Cooperative/abra/branch/main/graph/badge.svg?token=aX3I5NMRsj)](undefined)
|
||||||
|
|
||||||
> https://cloud.autonomic.zone
|
> https://coopcloud.tech
|
||||||
|
|
||||||
The cooperative cloud utility belt 🎩🐇
|
The cooperative cloud utility belt 🎩🐇
|
||||||
|
|
||||||
|
`abra` is a command-line tool for managing your own [Co-op Cloud](https://coopcloud.tech). It can provision new servers, create applications, deploy them, run backup and restore operations and a whole lot of other things. It is the go-to tool for day-to-day operations when managing a Co-op Cloud instance.
|
||||||
|
|
||||||
|
## Change log
|
||||||
|
|
||||||
|
> 🔥 🔥 🔥 Please note, while we are still in [public
|
||||||
|
> alpha](https://docs.coopcloud.tech/roadmap/), the `abra` release
|
||||||
|
> versioning scheme is not following [semver](https://semver.org/) conventions
|
||||||
|
> because we are still in the exploratory phases of building this tool. Please
|
||||||
|
> read the changes before upgrading your `abra` installation as there are
|
||||||
|
> **most likely** breaking changes coming each release. Sorry for any
|
||||||
|
> inconvenience caused, we're working hard to make this tool stable. Semver
|
||||||
|
> will be respected when we reach public beta. 🔥 🔥 🔥
|
||||||
|
|
||||||
|
See [CHANGELOG.md](./CHANGELOG.md).
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
> [docs.cloud.autonomic.zone](https://docs.cloud.autonomic.zone/)
|
> [docs.coopcloud.tech](https://docs.coopcloud.tech)
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
|
Install the latest stable release:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
curl https://install.abra.autonomic.zone | bash
|
curl https://install.abra.autonomic.zone | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
|
or the bleeding-edge development version:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl https://install.abra.autonomic.zone | bash -s -- --dev
|
||||||
|
```
|
||||||
|
|
||||||
|
The source for this script is [here](./deploy/install.abra.autonomic.zone/installer).
|
||||||
|
|
||||||
|
## Update
|
||||||
|
|
||||||
|
Run `abra upgrade` to automatically download and install the latest release
|
||||||
|
version.
|
||||||
|
|
||||||
|
To update the development version, run `abra upgrade --dev`.
|
||||||
|
|
||||||
|
## Hack
|
||||||
|
|
||||||
|
It's written in Bash version 4 or greater!
|
||||||
|
|
||||||
|
Install it via `curl https://install.abra.autonomic.zone | bash -s -- --dev`, then you can hack on the source in `~/.abra/src`.
|
||||||
|
|
||||||
|
The command-line interface is generated via [docopt](http://docopt.org/). If you add arguments then you need to run `make docopt` ro regenerate the parser.
|
||||||
|
|
||||||
|
Please remember to update the [CHANGELOG](./CHANGELOG.md) when you make a change.
|
||||||
|
|
||||||
|
## Generating a new apps.json
|
||||||
|
|
||||||
|
You'll need to install the following requirements:
|
||||||
|
|
||||||
|
- [requests](https://docs.python-requests.org/en/master/) (`apt install python3-requests` / `pip install requests`)
|
||||||
|
- [skopeo](https://github.com/containers/skopeo) (check [the install docs](https://github.com/containers/skopeo/blob/master/install.md))
|
||||||
|
- [jq](https://stedolan.github.io/jq/tutorial/) (`sudo apt-get install jq` or see [the install docs](https://stedolan.github.io/jq/download/))
|
||||||
|
- [yq](https://mikefarah.gitbook.io/yq/) (see [the install docs](https://mikefarah.gitbook.io/yq/#install))
|
||||||
|
|
||||||
|
Then run `./bin/app-json.py` ([source](./bin/app-json.py)) and it will spit out the JSON file into [deploy/apps.coopcloud.tech/apps.json](./deploy/apps.coopcloud.tech/apps.json).
|
||||||
|
|
||||||
|
## Releasing
|
||||||
|
|
||||||
|
### `abra`
|
||||||
|
|
||||||
|
> [install.abra.autonomic.zone](https://install.abra.autonomic.zone)
|
||||||
|
|
||||||
|
- Change the `x.x.x` header in [CHANGELOG.md](./CHANGELOG.md) to reflect new version and mark date
|
||||||
|
- Update the version in [abra](./abra)
|
||||||
|
- Update the version in [deploy/install.abra.autonomic.zone/installer](./deploy/install.abra.autonomic.zone/installer)
|
||||||
|
- `git commit` the above changes and then tag it with `git tag <your-new-version>`
|
||||||
|
- `git push` and `git push --tags`
|
||||||
|
- Deploy a new installer script `make release-installer`
|
||||||
|
- Tell the world (CoTech forum, Matrix public channel, Autonomic mastodon, etc.)
|
||||||
|
|
||||||
|
### apps.coopcloud.tech
|
||||||
|
|
||||||
|
> [apps.coopcloud.tech](https://apps.coopcloud.tech)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ make release-apps
|
||||||
|
```
|
||||||
|
103
bin/app-catalogue.sh
Executable file
103
bin/app-catalogue.sh
Executable file
@ -0,0 +1,103 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# shellcheck disable=SC2119
|
||||||
|
|
||||||
|
# Usage: ./app-catalogue.sh
|
||||||
|
#
|
||||||
|
# Gather metadata from Co-op Cloud apps in $ABRA_DIR/apps (default
|
||||||
|
# ~/.abra/apps), and format it as a Markdown table for this page:
|
||||||
|
# https://docs.cloud.autonomic.zone/apps/
|
||||||
|
|
||||||
|
stack_dir="${ABRA_DIR:-$HOME/.abra}/apps/"
|
||||||
|
|
||||||
|
cd "$stack_dir" || exit
|
||||||
|
|
||||||
|
# load all README files into ENV_FILES array
|
||||||
|
mapfile -t readmes < <(find -L . -name "README.md")
|
||||||
|
# FIXME 3wc: requires bash 4, use for loop instead
|
||||||
|
|
||||||
|
base_url="https://git.autonomic.zone/coop-cloud"
|
||||||
|
|
||||||
|
cat_apps=()
|
||||||
|
cat_development=()
|
||||||
|
cat_utilities=()
|
||||||
|
cat_graveyard=()
|
||||||
|
|
||||||
|
get_var() {
|
||||||
|
echo "$1" | grep "$2" | sed 's/^[^:]*: //'
|
||||||
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2120
|
||||||
|
trim() {
|
||||||
|
# accept input as argument or from STDIN, see here:
|
||||||
|
# https://zwbetz.com/passing-input-to-a-bash-function-via-arguments-or-stdin/
|
||||||
|
# shellcheck disable=SC2155
|
||||||
|
local input="$([[ -p /dev/stdin ]] && cat - || echo "$@")"
|
||||||
|
[[ -z "$input" ]] && return 1
|
||||||
|
echo "$input" | tr -d ' '
|
||||||
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2120
|
||||||
|
prettify() {
|
||||||
|
# as above
|
||||||
|
# shellcheck disable=SC2155
|
||||||
|
local input="$([[ -p /dev/stdin ]] && cat - || echo "$@")"
|
||||||
|
[[ -z "$input" ]] && return 1
|
||||||
|
|
||||||
|
echo "$input" | sed -e 's/Yes/✅/' -e 's/No/❌/' -e 's/N\/A/⛔/'
|
||||||
|
}
|
||||||
|
|
||||||
|
for readme in "${readmes[@]}"; do
|
||||||
|
type="$(basename "${readme%README.md}")"
|
||||||
|
if [ "$type" = "example" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
title="$(grep '^# ' "$type/README.md" | sed 's/^# //' )"
|
||||||
|
# find section between 'metadata' and 'endmetadata' comments
|
||||||
|
metadata="$(awk '/-- metadata --/,/-- endmetadata --/' "$type/README.md")"
|
||||||
|
status="$(get_var "$metadata" "Status")"
|
||||||
|
category="$(get_var "$metadata" "Category" | cut -d',' -f2 | trim)"
|
||||||
|
|
||||||
|
if [ -z "$category" ]; then
|
||||||
|
echo "ERROR: missing category for $type"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
image="$(get_var "$metadata" "Image" | cut -d',' -f2 | trim)"
|
||||||
|
healthcheck="$(get_var "$metadata" "Healthcheck" | prettify)"
|
||||||
|
backups="$(get_var "$metadata" "Backups" | prettify)"
|
||||||
|
email="$(get_var "$metadata" "Email" | prettify)"
|
||||||
|
tests="$(get_var "$metadata" "Tests" | prettify)"
|
||||||
|
sso="$(get_var "$metadata" "SSO" | prettify)"
|
||||||
|
|
||||||
|
row="| [$title]($base_url/$type) | $status | $image | $healthcheck | $backups | $email | $tests | $sso |"
|
||||||
|
|
||||||
|
category_lower="$(echo "$category" | tr '[:upper:]' '[:lower:]')"
|
||||||
|
eval "cat_$category_lower+=( '$row' )"
|
||||||
|
done
|
||||||
|
|
||||||
|
headers="
|
||||||
|
| **Name** | **Status** | **Image** | **Healtcheck** | **Backups** | **Email** | **CI** | **Single-Sign-On** |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- | --- |"
|
||||||
|
|
||||||
|
echo "## Applications"
|
||||||
|
echo "$headers"
|
||||||
|
printf '%s\n' "${cat_apps[@]}" | sort
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo "## Developer tools"
|
||||||
|
echo "$headers"
|
||||||
|
printf '%s\n' "${cat_development[@]}" | sort
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo "## Utilities"
|
||||||
|
echo "$headers"
|
||||||
|
printf '%s\n' "${cat_utilities[@]}" | sort
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo "## Graveyard"
|
||||||
|
echo "$headers"
|
||||||
|
printf '%s\n' "${cat_graveyard[@]}" | sort
|
298
bin/app-json.py
Executable file
298
bin/app-json.py
Executable file
@ -0,0 +1,298 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Usage: ./app-json.py
|
||||||
|
#
|
||||||
|
# Gather metadata from Co-op Cloud apps in $ABRA_DIR/apps (default
|
||||||
|
# ~/.abra/apps), and format it as JSON so that it can be hosted here:
|
||||||
|
# https://apps.coopcloud.tech
|
||||||
|
|
||||||
|
from json import dump
|
||||||
|
from logging import DEBUG, basicConfig, getLogger
|
||||||
|
from os import chdir, listdir, mkdir
|
||||||
|
from os.path import basename, exists, expanduser
|
||||||
|
from pathlib import Path
|
||||||
|
from re import findall, search
|
||||||
|
from shlex import split
|
||||||
|
from subprocess import DEVNULL, check_output
|
||||||
|
from sys import exit
|
||||||
|
|
||||||
|
from requests import get
|
||||||
|
|
||||||
|
HOME_PATH = expanduser("~/")
|
||||||
|
CLONES_PATH = Path(f"{HOME_PATH}/.abra/apps").absolute()
|
||||||
|
YQ_PATH = Path(f"{HOME_PATH}/.abra/vendor/yq")
|
||||||
|
SCRIPT_PATH = Path(__file__).absolute().parent
|
||||||
|
REPOS_TO_SKIP = (
|
||||||
|
"abra",
|
||||||
|
"abra-apps",
|
||||||
|
"abra-gandi",
|
||||||
|
"abra-hetzner",
|
||||||
|
"backup-bot",
|
||||||
|
"coopcloud.tech",
|
||||||
|
"coturn",
|
||||||
|
"docker-cp-deploy",
|
||||||
|
"docker-dind-bats-kcov",
|
||||||
|
"docs.coopcloud.tech",
|
||||||
|
"example",
|
||||||
|
"gardening",
|
||||||
|
"organising",
|
||||||
|
"pyabra",
|
||||||
|
"radicle-seed-node",
|
||||||
|
"stack-ssh-deploy",
|
||||||
|
"swarm-cronjob",
|
||||||
|
)
|
||||||
|
|
||||||
|
log = getLogger(__name__)
|
||||||
|
basicConfig()
|
||||||
|
log.setLevel(DEBUG)
|
||||||
|
|
||||||
|
|
||||||
|
def _run_cmd(cmd, shell=False, **kwargs):
|
||||||
|
"""Run a shell command."""
|
||||||
|
args = [split(cmd)]
|
||||||
|
|
||||||
|
if shell:
|
||||||
|
args = [cmd]
|
||||||
|
kwargs = {"shell": shell}
|
||||||
|
|
||||||
|
try:
|
||||||
|
return check_output(*args, **kwargs).decode("utf-8").strip()
|
||||||
|
except Exception as exception:
|
||||||
|
log.error(f"Failed to run {cmd}, saw {str(exception)}")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def get_repos_json():
|
||||||
|
""" Retrieve repo list from Gitea """
|
||||||
|
|
||||||
|
url = "https://git.autonomic.zone/api/v1/orgs/coop-cloud/repos"
|
||||||
|
|
||||||
|
log.info(f"Retrieving {url}")
|
||||||
|
|
||||||
|
repos = []
|
||||||
|
response = True
|
||||||
|
page = 1
|
||||||
|
|
||||||
|
try:
|
||||||
|
while response:
|
||||||
|
log.info(f"Trying to fetch page {page}")
|
||||||
|
response = get(url + f"?page={page}", timeout=10).json()
|
||||||
|
repos.extend(response)
|
||||||
|
page += 1
|
||||||
|
|
||||||
|
return repos
|
||||||
|
except Exception as exception:
|
||||||
|
log.error(f"Failed to retrieve {url}, saw {str(exception)}")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def get_published_apps_json():
|
||||||
|
"""Retrieve already published apps json."""
|
||||||
|
url = "https://apps.coopcloud.tech"
|
||||||
|
|
||||||
|
log.info(f"Retrieving {url}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
return get(url, timeout=5).json()
|
||||||
|
except Exception as exception:
|
||||||
|
log.error(f"Failed to retrieve {url}, saw {str(exception)}")
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
def clone_all_apps(repos_json):
|
||||||
|
"""Clone all Co-op Cloud apps to ~/.abra/apps."""
|
||||||
|
if not exists(CLONES_PATH):
|
||||||
|
mkdir(CLONES_PATH)
|
||||||
|
|
||||||
|
repos = [[p["name"], p["ssh_url"]] for p in repos_json]
|
||||||
|
|
||||||
|
for name, url in repos:
|
||||||
|
if name in REPOS_TO_SKIP:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not exists(f"{CLONES_PATH}/{name}"):
|
||||||
|
log.info(f"Retrieving {url}")
|
||||||
|
_run_cmd(f"git clone {url} {CLONES_PATH}/{name}")
|
||||||
|
|
||||||
|
chdir(f"{CLONES_PATH}/{name}")
|
||||||
|
if not int(_run_cmd("git branch --list | wc -l", shell=True)):
|
||||||
|
log.info(f"Guessing main branch is HEAD for {name}")
|
||||||
|
_run_cmd("git checkout main")
|
||||||
|
else:
|
||||||
|
log.info(f"Updating {name}")
|
||||||
|
chdir(f"{CLONES_PATH}/{name}")
|
||||||
|
_run_cmd("git fetch -a")
|
||||||
|
|
||||||
|
|
||||||
|
def generate_apps_json(repos_json):
|
||||||
|
"""Generate the abra-apps.json application versions file."""
|
||||||
|
apps_json = {}
|
||||||
|
cached_apps_json = get_published_apps_json()
|
||||||
|
|
||||||
|
for app in listdir(CLONES_PATH):
|
||||||
|
if app in REPOS_TO_SKIP:
|
||||||
|
log.info(f"Skipping {app}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
repo_details = next(filter(lambda x: x["name"] == app, repos_json), {})
|
||||||
|
|
||||||
|
app_path = f"{CLONES_PATH}/{app}"
|
||||||
|
chdir(app_path)
|
||||||
|
|
||||||
|
metadata = get_app_metadata(app_path)
|
||||||
|
name = metadata.pop("name", "")
|
||||||
|
|
||||||
|
log.info(f"Processing {app}")
|
||||||
|
apps_json[app] = {
|
||||||
|
"name": name,
|
||||||
|
"category": metadata.get("category", ""),
|
||||||
|
"repository": repo_details.get("clone_url", ""),
|
||||||
|
"default_branch": repo_details.get("default_branch", ""),
|
||||||
|
"description": repo_details.get("description", ""),
|
||||||
|
"website": repo_details.get("website", ""),
|
||||||
|
"features": metadata,
|
||||||
|
"versions": get_app_versions(app_path, cached_apps_json),
|
||||||
|
"icon": repo_details.get("avatar_url", ""),
|
||||||
|
}
|
||||||
|
|
||||||
|
return apps_json
|
||||||
|
|
||||||
|
|
||||||
|
def get_app_metadata(app_path):
|
||||||
|
"""Parse metadata from app repo README files."""
|
||||||
|
metadata = {}
|
||||||
|
|
||||||
|
chdir(app_path)
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(f"{app_path}/README.md", "r") as handle:
|
||||||
|
log.info(f"{app_path}/README.md")
|
||||||
|
contents = handle.read()
|
||||||
|
except Exception:
|
||||||
|
log.info(f"No {app_path}/README.md discovered, moving on")
|
||||||
|
return {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
for match in findall(r"\*\*.*\s\*", contents):
|
||||||
|
title = search(r"(?<=\*\*).*(?=\*\*)", match).group().lower()
|
||||||
|
|
||||||
|
if title == "image":
|
||||||
|
value = {
|
||||||
|
"image": search(r"(?<=`).*(?=`)", match).group(),
|
||||||
|
"url": search(r"(?<=\().*(?=\))", match).group(),
|
||||||
|
"rating": match.split(",")[1].strip(),
|
||||||
|
"source": match.split(",")[-1].replace("*", "").strip(),
|
||||||
|
}
|
||||||
|
elif title == "status":
|
||||||
|
value = {"❶💚": 1, "❷💛": 2, "❸🍎": 3, "❹💣": 4, "?": 5, "": 5}[
|
||||||
|
match.split(":")[-1].replace("*", "").strip()
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
value = match.split(":")[-1].replace("*", "").strip()
|
||||||
|
|
||||||
|
metadata[title] = value
|
||||||
|
metadata["name"] = findall(r"^# (.*)", contents)[0]
|
||||||
|
except (IndexError, AttributeError):
|
||||||
|
log.info(f"Can't parse {app_path}/README.md")
|
||||||
|
return {}
|
||||||
|
finally:
|
||||||
|
_run_cmd("git checkout HEAD")
|
||||||
|
|
||||||
|
log.info(f"Parsed {metadata}")
|
||||||
|
|
||||||
|
return metadata
|
||||||
|
|
||||||
|
|
||||||
|
def get_app_versions(app_path, cached_apps_json):
|
||||||
|
versions = {}
|
||||||
|
|
||||||
|
chdir(app_path)
|
||||||
|
|
||||||
|
tags = _run_cmd("git tag --list").split()
|
||||||
|
|
||||||
|
if not tags:
|
||||||
|
log.info("No tags discovered, moving on")
|
||||||
|
return {}
|
||||||
|
|
||||||
|
initial_branch = _run_cmd("git rev-parse --abbrev-ref HEAD")
|
||||||
|
|
||||||
|
app_name = basename(app_path)
|
||||||
|
|
||||||
|
try:
|
||||||
|
existing_tags = cached_apps_json[app_name]["versions"].keys()
|
||||||
|
except KeyError:
|
||||||
|
existing_tags = []
|
||||||
|
|
||||||
|
for tag in tags:
|
||||||
|
_run_cmd(f"git checkout {tag}", stderr=DEVNULL)
|
||||||
|
|
||||||
|
services_cmd = f"{YQ_PATH} e '.services | keys | .[]' compose*.yml"
|
||||||
|
services = _run_cmd(services_cmd, shell=True).split()
|
||||||
|
|
||||||
|
parsed_services = []
|
||||||
|
service_versions = {}
|
||||||
|
for service in services:
|
||||||
|
if service in ("null", "---"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if (
|
||||||
|
tag in existing_tags
|
||||||
|
and service in cached_apps_json[app_name]["versions"][tag]
|
||||||
|
):
|
||||||
|
log.info(f"Skipping {tag} because we've already processed it")
|
||||||
|
existing_versions = cached_apps_json[app_name]["versions"][tag][service]
|
||||||
|
service_versions[service] = existing_versions
|
||||||
|
_run_cmd(f"git checkout {initial_branch}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
if service in parsed_services:
|
||||||
|
log.info(f"Skipped {service}, we've already parsed it locally")
|
||||||
|
continue
|
||||||
|
|
||||||
|
services_cmd = f"{YQ_PATH} e '.services.{service}.image' compose*.yml"
|
||||||
|
images = _run_cmd(services_cmd, shell=True).split()
|
||||||
|
|
||||||
|
for image in images:
|
||||||
|
if image in ("null", "---"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
images_cmd = f"skopeo inspect docker://{image} | jq '.Digest'"
|
||||||
|
output = _run_cmd(images_cmd, shell=True)
|
||||||
|
|
||||||
|
service_version_info = {
|
||||||
|
"image": image.split(":")[0],
|
||||||
|
"tag": image.split(":")[-1],
|
||||||
|
"digest": output.split(":")[-1][:8],
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info(f"Parsed {service_version_info}")
|
||||||
|
service_versions[service] = service_version_info
|
||||||
|
|
||||||
|
parsed_services.append(service)
|
||||||
|
|
||||||
|
versions[tag] = service_versions
|
||||||
|
|
||||||
|
_run_cmd(f"git checkout {initial_branch}")
|
||||||
|
|
||||||
|
return versions
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Run the script."""
|
||||||
|
repos_json = get_repos_json()
|
||||||
|
clone_all_apps(repos_json)
|
||||||
|
|
||||||
|
target = f"{SCRIPT_PATH}/../deploy/apps.coopcloud.tech/apps.json"
|
||||||
|
with open(target, "w", encoding="utf-8") as handle:
|
||||||
|
dump(
|
||||||
|
generate_apps_json(repos_json),
|
||||||
|
handle,
|
||||||
|
ensure_ascii=False,
|
||||||
|
indent=4,
|
||||||
|
sort_keys=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
log.info(f"Successfully generated {target}")
|
||||||
|
|
||||||
|
|
||||||
|
main()
|
@ -91,7 +91,7 @@ _abra_complete()
|
|||||||
case "$cmd" in
|
case "$cmd" in
|
||||||
server)
|
server)
|
||||||
# Offer exactly one server name completion.
|
# Offer exactly one server name completion.
|
||||||
if (( COMP_CWORD == cmd_index + 2 )); then
|
if (( COMP_CWORD == cmd_index + 1 )); then
|
||||||
_abra_complete_servers "$cur"
|
_abra_complete_servers "$cur"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
1740
deploy/apps.coopcloud.tech/apps.json
Normal file
1740
deploy/apps.coopcloud.tech/apps.json
Normal file
File diff suppressed because it is too large
Load Diff
41
deploy/apps.coopcloud.tech/compose.yml
Normal file
41
deploy/apps.coopcloud.tech/compose.yml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
version: "3.8"
|
||||||
|
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: "nginx:stable"
|
||||||
|
configs:
|
||||||
|
- source: abra_conf
|
||||||
|
target: /etc/nginx/conf.d/abra.conf
|
||||||
|
- source: abra_apps_json
|
||||||
|
target: /var/www/abra-apps/apps.json
|
||||||
|
volumes:
|
||||||
|
- "public:/var/www/abra-apps"
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
deploy:
|
||||||
|
update_config:
|
||||||
|
failure_action: rollback
|
||||||
|
order: start-first
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.services.abra-apps.loadbalancer.server.port=80"
|
||||||
|
- "traefik.http.routers.abra-apps.rule=Host(`apps.coopcloud.tech`, `abra-apps.cloud.autonomic.zone`)"
|
||||||
|
- "traefik.http.routers.abra-apps.entrypoints=web-secure"
|
||||||
|
- "traefik.http.routers.abra-apps.tls.certresolver=production"
|
||||||
|
- "traefik.http.routers.abra-apps.middlewares=abra-apps-redirect"
|
||||||
|
- "traefik.http.middlewares.abra-apps-redirect.headers.SSLForceHost=true"
|
||||||
|
- "traefik.http.middlewares.abra-apps-redirect.headers.SSLHost=apps.coopcloud.tech"
|
||||||
|
|
||||||
|
configs:
|
||||||
|
abra_apps_json:
|
||||||
|
file: apps.json
|
||||||
|
abra_conf:
|
||||||
|
file: nginx.conf
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
public:
|
10
deploy/apps.coopcloud.tech/nginx.conf
Normal file
10
deploy/apps.coopcloud.tech/nginx.conf
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
server_name apps.coopcloud.tech;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /var/www/abra-apps;
|
||||||
|
add_header Content-Type application/json;
|
||||||
|
index apps.json;
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
version: "3.8"
|
version: "3.8"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
abra_installer:
|
app:
|
||||||
image: "nginx:stable"
|
image: "nginx:stable"
|
||||||
configs:
|
configs:
|
||||||
- source: abra_conf
|
- source: abra_conf
|
||||||
@ -26,10 +26,8 @@ services:
|
|||||||
|
|
||||||
configs:
|
configs:
|
||||||
abra_installer:
|
abra_installer:
|
||||||
name: abra_installer_v1
|
|
||||||
file: installer
|
file: installer
|
||||||
abra_conf:
|
abra_conf:
|
||||||
name: abra_conf_v1
|
|
||||||
file: nginx.conf
|
file: nginx.conf
|
||||||
|
|
||||||
networks:
|
networks:
|
35
deploy/install.abra.autonomic.zone/installer
Executable file
35
deploy/install.abra.autonomic.zone/installer
Executable file
@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
ABRA_VERSION="0.7.3"
|
||||||
|
GIT_URL="https://git.autonomic.zone/coop-cloud/abra"
|
||||||
|
ABRA_SRC="$GIT_URL/raw/tag/$ABRA_VERSION/abra"
|
||||||
|
ABRA_DIR="${ABRA_DIR:-$HOME/.abra/}"
|
||||||
|
|
||||||
|
function install_abra_release {
|
||||||
|
mkdir -p "$HOME/.local/bin"
|
||||||
|
curl "$ABRA_SRC" > "$HOME/.local/bin/abra"
|
||||||
|
chmod +x "$HOME/.local/bin/abra"
|
||||||
|
echo "abra installed to $HOME/.local/bin/abra"
|
||||||
|
}
|
||||||
|
|
||||||
|
function install_abra_dev {
|
||||||
|
mkdir -p "$ABRA_DIR/"
|
||||||
|
if [[ ! -d "$ABRA_DIR/src" ]]; then
|
||||||
|
git clone "$GIT_URL" "$ABRA_DIR/src"
|
||||||
|
fi
|
||||||
|
(cd "$ABRA_DIR/src" && git pull origin main && cd - || exit)
|
||||||
|
mkdir -p "$HOME/.local/bin"
|
||||||
|
ln -sf "$ABRA_DIR/src/abra" "$HOME/.local/bin/abra"
|
||||||
|
echo "abra installed to $HOME/.local/bin/abra (development bleeding edge)"
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_installation {
|
||||||
|
if [ "$1" = "--dev" ]; then
|
||||||
|
install_abra_dev
|
||||||
|
else
|
||||||
|
install_abra_release
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
run_installation "$@"
|
||||||
|
exit 0
|
@ -1,18 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
ABRA_VERSION="0.4.1"
|
|
||||||
ABRA_SRC="https://git.autonomic.zone/coop-cloud/abra/raw/tag/$ABRA_VERSION/abra"
|
|
||||||
|
|
||||||
function install_abra {
|
|
||||||
mkdir -p "$HOME/.local/bin"
|
|
||||||
curl "$ABRA_SRC" > "$HOME/.local/bin/abra"
|
|
||||||
chmod +x "$HOME/.local/bin/abra"
|
|
||||||
echo "abra installed to $HOME/.loca/bin/abra"
|
|
||||||
}
|
|
||||||
|
|
||||||
function run_installation {
|
|
||||||
install_abra
|
|
||||||
}
|
|
||||||
|
|
||||||
run_installation
|
|
||||||
exit 0
|
|
58
makefile
Normal file
58
makefile
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
.PHONY: test shellcheck docopt kcov codecov release-installer
|
||||||
|
|
||||||
|
test:
|
||||||
|
@sudo DOCKER_CONTEXT=default docker run \
|
||||||
|
-v $$(pwd):/workdir \
|
||||||
|
--privileged \
|
||||||
|
-d \
|
||||||
|
--name=abra-test-dind \
|
||||||
|
-e DOCKER_TLS_CERTDIR="" \
|
||||||
|
decentral1se/docker-dind-bats-kcov
|
||||||
|
@DOCKER_CONTEXT=default docker exec \
|
||||||
|
-it \
|
||||||
|
abra-test-dind \
|
||||||
|
sh -c "cd /workdir && bats /workdir/tests"
|
||||||
|
@DOCKER_CONTEXT=default docker stop abra-test-dind
|
||||||
|
@DOCKER_CONTEXT=default docker rm abra-test-dind
|
||||||
|
|
||||||
|
shellcheck:
|
||||||
|
@docker run \
|
||||||
|
-it \
|
||||||
|
--rm \
|
||||||
|
-v $$(pwd):/workdir \
|
||||||
|
koalaman/shellcheck-alpine \
|
||||||
|
shellcheck /workdir/abra && \
|
||||||
|
shellcheck /workdir/bin/*.sh
|
||||||
|
|
||||||
|
docopt:
|
||||||
|
@if [ ! -d ".venv" ]; then \
|
||||||
|
python3 -m venv .venv && \
|
||||||
|
.venv/bin/pip install -U pip setuptools wheel && \
|
||||||
|
.venv/bin/pip install docopt-sh; \
|
||||||
|
fi
|
||||||
|
.venv/bin/docopt.sh abra
|
||||||
|
|
||||||
|
kcov:
|
||||||
|
@docker run \
|
||||||
|
-it \
|
||||||
|
--rm \
|
||||||
|
-v $$(pwd):/workdir \
|
||||||
|
kcov/kcov:latest \
|
||||||
|
sh -c "kcov /workdir/coverage /workdir/abra || true"
|
||||||
|
|
||||||
|
codecov: SHELL:=/bin/bash
|
||||||
|
codecov:
|
||||||
|
@bash <(curl -s https://codecov.io/bash) \
|
||||||
|
-s coverage -t $$(pass show hosts/swarm.autonomic.zone/drone/codecov/token)
|
||||||
|
|
||||||
|
release-installer:
|
||||||
|
@DOCKER_CONTEXT=swarm.autonomic.zone \
|
||||||
|
docker stack rm abra-installer-script && \
|
||||||
|
cd deploy/install.abra.autonomic.zone && \
|
||||||
|
DOCKER_CONTEXT=swarm.autonomic.zone docker stack deploy -c compose.yml abra-installer-script
|
||||||
|
|
||||||
|
release-apps:
|
||||||
|
@DOCKER_CONTEXT=swarm.autonomic.zone \
|
||||||
|
docker stack rm abra-apps-json && \
|
||||||
|
cd deploy/apps.coopcloud.tech && \
|
||||||
|
DOCKER_CONTEXT=swarm.autonomic.zone docker stack deploy -c compose.yml abra-apps-json
|
@ -9,41 +9,48 @@ teardown() {
|
|||||||
rm -rf "$ABRA_DIR"
|
rm -rf "$ABRA_DIR"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "abra server add/rm works" {
|
abra() {
|
||||||
./abra server add swarm.test.com
|
./abra -d $@
|
||||||
docker context ls | grep swarm.test.com
|
|
||||||
[ -d $ABRA_DIR/servers/swarm.test.com ]
|
|
||||||
./abra server swarm.test.com rm
|
|
||||||
|
|
||||||
./abra server add swarm.test.com foobar 12345
|
|
||||||
[ -d $ABRA_DIR/servers/swarm.test.com ]
|
|
||||||
./abra server swarm.test.com rm
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "abra app new/rm works" {
|
@test "abra server (add|rm)" {
|
||||||
./abra app new --server default --domain traefik.test.com traefik
|
abra server add swarm.test.com
|
||||||
[ -f $ABRA_DIR/servers/default/traefik.test.com.env ]
|
docker context ls | grep swarm.test.com
|
||||||
|
[ -d $ABRA_DIR/servers/swarm.test.com ]
|
||||||
|
abra server swarm.test.com rm
|
||||||
|
|
||||||
|
abra server add swarm.test.com foobar 12345
|
||||||
|
[ -d $ABRA_DIR/servers/swarm.test.com ]
|
||||||
|
abra server swarm.test.com rm
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "abra server init" {
|
||||||
|
abra server default init
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "abra app (new|rm)" {
|
||||||
|
abra app new --server default --domain traefik.test.com --app-name traefik_test_com traefik
|
||||||
|
[ -f $ABRA_DIR/servers/default/traefik_test_com.env ]
|
||||||
|
|
||||||
# interactive prompt
|
# interactive prompt
|
||||||
echo "y" | ./abra app traefik.test.com delete
|
echo "y" | abra app traefik_test_com delete
|
||||||
[ ! -f $ABRA_DIR/servers/default/traefik.test.com.env ]
|
[ ! -f $ABRA_DIR/servers/default/traefik_test_com.env ]
|
||||||
|
|
||||||
# --force
|
# --no-prompt
|
||||||
./abra app new --server default --domain traefik.test.com traefik
|
abra app new --server default --domain traefik_test_com --app-name traefik_test_com traefik
|
||||||
./abra app traefik.test.com delete --force
|
abra --no-prompt app traefik_test_com delete
|
||||||
[ ! -f $ABRA_DIR/servers/default/traefik.test.com.env ]
|
[ ! -f $ABRA_DIR/servers/default/traefik_test_com.env ]
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "abra app <domain> secret (insert|generate|rm)" {
|
@test "abra app <domain> secret (insert|generate|rm)" {
|
||||||
# TODO 3wc: mock `server new` so we don't endlessly re-test it
|
abra app new --server default --domain traefik_test_com --app-name traefik_test_com traefik
|
||||||
./abra app new --server default --domain traefik.test.com traefik
|
|
||||||
|
|
||||||
./abra app traefik.test.com secret insert foobar v1 "foobar"
|
abra app traefik_test_com secret insert foobar v1 "foobar"
|
||||||
|
|
||||||
# interactive prompt
|
# interactive prompt
|
||||||
echo "y" | ./abra app traefik.test.com secret rm foobar
|
echo "y" | abra app traefik_test_com secret rm foobar
|
||||||
|
|
||||||
./abra app traefik.test.com secret insert foobar v1 "foobar"
|
abra app traefik_test_com secret insert foobar v1 "foobar"
|
||||||
# prompt
|
# prompt
|
||||||
./abra app traefik.test.com secret rm foobar --force
|
abra --no-prompt app traefik_test_com secret rm foobar
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user