Compare commits
	
		
			273 Commits
		
	
	
		
			checkout
			...
			add-bump-l
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 0655c03434 | |||
| f6bdf596f5 | |||
| 6c6e6808c9 | |||
| a3ffd7f239 | |||
| a019417fd2 | |||
| 743600b94e | |||
| f4c2da894b | |||
| 4ef433312d | |||
| 9f69532dca | |||
| 3a97358f30 | |||
| 1e19805757 | |||
| 389ad9d049 | |||
| 93ffc633f3 | |||
| b61c9410a0 | |||
| bbab900ebc | |||
| 36d4dbc5cf | |||
| a4ade1463f | |||
| 20af4666c6 | |||
| d15b031f33 | |||
| a7f0bbde62 | |||
| 76d5a1026a | |||
| 7b0fb50e7f | |||
| f92364af80 | |||
| ca2a3c8b58 | |||
| a5c5526948 | |||
| d16eb0e309 | |||
| 3cff8aaada | |||
| 4ff4c83154 | |||
| f953743a7c | |||
| e84062e67c | |||
| e573794367 | |||
| 87f9c16db4 | |||
| 9fadc430a7 | |||
| 53cec2469b | |||
| a1de7f10cb | |||
| ece968478d | |||
| 3759bcd641 | |||
| 0ff08b5d34 | |||
| 8b541623ad | |||
| f24259dbfc | |||
| 40259f5e97 | |||
| fd471eb3f1 | |||
| a4633f06bd | |||
| 0d6031fef9 | |||
| 64d578cf91 | |||
| e216fe290b | |||
| 207278af75 | |||
| ff309182ea | |||
| 542cf793d2 | |||
| ad1fe2b8d7 | |||
| 0771d58b69 | |||
| b24cdce354 | |||
| 499cc46583 | |||
| 0af0ea096f | |||
| 925df196fc | |||
| efad71c470 | |||
| cac13fb64e | |||
| 42923ced55 | |||
| 6a12955649 | |||
| ceccb28380 | |||
| b033fe9450 | |||
| 0e29e78144 | |||
| c92f80cf7e | |||
| a7f7c965c4 | |||
| e04c5228de | |||
| 6c9dff0eed | |||
| c45598d7b4 | |||
| 4e1c3bfe2f | |||
| 615c6b0614 | |||
| b14219b492 | |||
| 8c93d1ae88 | |||
| cf2ae05dfd | |||
| 70974690f9 | |||
| a4f3fc5ce2 | |||
| 8a4f82ba84 | |||
| a1534a244a | |||
| fccd7865f5 | |||
| 4e84664310 | |||
| 047c0e6d47 | |||
| fc2d770099 | |||
| 1b85bf3d37 | |||
| 2d6a08a671 | |||
| 316bcd5a68 | |||
| 1a4cf9be17 | |||
| eadb353c2e | |||
| f374b1bfa1 | |||
| 0e6b0e0879 | |||
| 3a353f4062 | |||
| e0258d397b | |||
| e8ac353453 | |||
| 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 | 
							
								
								
									
										73
									
								
								.drone.yml
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								.drone.yml
									
									
									
									
									
								
							| @ -6,38 +6,73 @@ 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: decentral1se/docker-dind-bats-kcov |     image: decentral1se/docker-dind-bats-kcov | ||||||
|     commands: |     commands: | ||||||
|       - bats tests |       - bats tests | ||||||
|  |  | ||||||
|   - name: collect code coverage |   - name: publish image | ||||||
|     failure: ignore # until we fix this |     image: plugins/docker | ||||||
|     image: decentral1se/docker-dind-bats-kcov |  | ||||||
|     commands: |  | ||||||
|       - kcov . bats tests || true |  | ||||||
|  |  | ||||||
|   - name: send code coverage report to codecov |  | ||||||
|     failure: ignore # until we fix this |  | ||||||
|     image: plugins/codecov |  | ||||||
|     settings: |     settings: | ||||||
|  |       auto_tag: true | ||||||
|  |       username: | ||||||
|  |         from_secret: docker_reg_username | ||||||
|  |       password: | ||||||
|  |         from_secret: docker_reg_passwd | ||||||
|  |       repo: decentral1se/abra | ||||||
|  |       tags: latest | ||||||
|  |     depends_on: | ||||||
|  |       - run shellcheck | ||||||
|  |       - run flake8 | ||||||
|  |       - run unit tests | ||||||
|  |     when: | ||||||
|  |       event: | ||||||
|  |         exclude: | ||||||
|  |           - pull_request | ||||||
|  |  | ||||||
|  |   - name: trigger downstream builds | ||||||
|  |     image: plugins/downstream | ||||||
|  |     settings: | ||||||
|  |       server: https://drone.autonomic.zone | ||||||
|       token: |       token: | ||||||
|         from_secret: codecov_token |         from_secret: decentral1se_token | ||||||
|         required: true |       fork: true | ||||||
|  |       repositories: | ||||||
|  |         - coop-cloud/drone-abra | ||||||
|  |     depends_on: | ||||||
|  |       - run shellcheck | ||||||
|  |       - run flake8 | ||||||
|  |       - run unit tests | ||||||
|  |       - publish image | ||||||
|  |     when: | ||||||
|  |       event: | ||||||
|  |         exclude: | ||||||
|  |           - pull_request | ||||||
|  |  | ||||||
|   - name: notify rocket chat |   - name: notify on failure | ||||||
|     image: plugins/slack |     image: plugins/matrix | ||||||
|     settings: |     settings: | ||||||
|       webhook: |       homeserver: https://matrix.autonomic.zone | ||||||
|         from_secret: rc_builds_url |       roomid: "IFazIpLtxiScqbHqoa:autonomic.zone" | ||||||
|       username: comradebritney |       userid: "@autono-bot:autonomic.zone" | ||||||
|       channel: "internal.builds" |       accesstoken: | ||||||
|       template: "{{repo.owner}}/{{repo.name}} build failed: {{build.link}}" |         from_secret: autono_bot_access_token | ||||||
|  |     depends_on: | ||||||
|  |       - run shellcheck | ||||||
|  |       - run flake8 | ||||||
|  |       - run unit tests | ||||||
|  |       - publish image | ||||||
|  |       - trigger downstream builds | ||||||
|     when: |     when: | ||||||
|       status: |       status: | ||||||
|         - failure |         - failure | ||||||
|  |  | ||||||
| trigger: | trigger: | ||||||
|   branch: |   branch: | ||||||
|     - main |     - main | ||||||
|  | |||||||
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,2 +1,5 @@ | |||||||
| coverage/ | *.json | ||||||
|  | *.pyc | ||||||
| /.venv | /.venv | ||||||
|  | __pycache__ | ||||||
|  | coverage/ | ||||||
|  | |||||||
							
								
								
									
										89
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										89
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @ -1,5 +1,94 @@ | |||||||
|  | > 🔥 🔥 🔥 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) | ||||||
|  |  | ||||||
|  | - Add `--bump` to `deploy` command to allow packagers to make minor package related releases ([#173](https://git.autonomic.zone/coop-cloud/abra/issues/173)) | ||||||
|  |  | ||||||
|  | # abra 9.0.0 (2021-06-10) | ||||||
|  |  | ||||||
|  | - Add Docker image for `abra` ([64d578cf91](https://git.autonomic.zone/coop-cloud/abra/commit/64d578cf914bd2bad378ea4ef375747d10b33191)) | ||||||
|  | - Support unattended mode for recipe releasing ([3759bcd641](https://git.autonomic.zone/coop-cloud/abra/commit/3759bcd641cf60611c13927e83425e773d2bb629)) | ||||||
|  | - Add Renovate bot configuraiton script ([9fadc430a7](https://git.autonomic.zone/coop-cloud/abra/commit/9fadc430a7bb2d554c0ee26c0f9b6c51dc5b0475)) | ||||||
|  | - Add release automation via [drone-abra](https://git.autonomic.zone/coop-cloud/drone-abra) ([#56](https://git.autonomic.zone/coop-cloud/organising/issues/56)) | ||||||
|  | - Move `apps.json` generation to [auto-apps-json](https://git.autonomic.zone/coop-cloud/auto-apps-json) ([#125](https://git.autonomic.zone/coop-cloud/abra/issues/125)) | ||||||
|  | - Add Github mirroring script ([4ef433312d](https://git.autonomic.zone/coop-cloud/abra/commit/4ef433312dd0b0ace91b3c285f82f3973093d92d)) | ||||||
|  | - Add `--chaos` flag to deploy (always choose latest Git commit) ([#178](https://git.autonomic.zone/coop-cloud/abra/issues/178)) | ||||||
|  |  | ||||||
|  | # abra 8.0.1 (2021-05-31) | ||||||
|  |  | ||||||
|  | - Fix help for `... app ... volume ls` ([efad71c470](https://git.autonomic.zone/coop-cloud/abra/commits/branch/main)) | ||||||
|  | - Only output secrets warnings once ([#143](https://git.autonomic.zone/coop-cloud/abra/issues/143)) | ||||||
|  | - Migrate `abra` installation script to `coopcloud.tech` domain ([#150](https://git.autonomic.zone/coop-cloud/abra/issues/150)) | ||||||
|  | - Add `--no-state-poll` to avoid success/failure forecasting on deployment ([#165](https://git.autonomic.zone/coop-cloud/abra/issues/165)) | ||||||
|  |  | ||||||
|  | # abra 8.0.0 (2021-05-30) | ||||||
|  |  | ||||||
|  | - Fix secret length generation ([f537417](https://git.autonomic.zone/coop-cloud/abra/commit/1b85bf3d37280e9632c315d759c0f2d09c039fef)) | ||||||
|  | - Fix checking out new apps ([#164](https://git.autonomic.zone/coop-cloud/abra/issues/164) | ||||||
|  | - Give up if YAML is invalid ([#154](https://git.autonomic.zone/coop-cloud/abra/issues/154)) | ||||||
|  | - Switch from wget to cURL ([fc0caaa](https://git.autonomic.zone/coop-cloud/abra/commit/fc0caaa)) | ||||||
|  | - Add Bash completion for `recipe ..` ([8c93d1a](https://git.autonomic.zone/coop-cloud/abra/commit/8c93d1a)) | ||||||
|  | - Tweak README parsing in `app-json.py` ([b14219b](https://git.autonomic.zone/coop-cloud/abra/commit/b14219b)) | ||||||
|  | - Add fallback names to `app.json` ([#157](https://git.autonomic.zone/coop-cloud/abra/issues/157)) | ||||||
|  | - Remove duplicate message ([#155](https://git.autonomic.zone/coop-cloud/abra/issues/155)) | ||||||
|  | - Add `deploy --fast` ([a7f7c96](https://git.autonomic.zone/coop-cloud/abra/commit/a7f7c96)) | ||||||
|  | - Add `app .. volume` commands, fix volume deletion with `app .. delete --volumes` ([#161](https://git.autonomic.zone/coop-cloud/abra/issues/161)) | ||||||
|  |  | ||||||
|  | # abra 0.7.4 (2021-05-10) | ||||||
|  |  | ||||||
|  | - 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)) | ||||||
|  | - Fix secret generation when specifying length ([3a353f4](https://git.autonomic.zone/coop-cloud/abra/commit/3a353f4062baccde2c9f175b03afb2db6d462ae4)) | ||||||
|  |  | ||||||
|  | # 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) | # 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)) | - Show version and digest of app if labelled ([98e674b8e8](https://git.autonomic.zone/coop-cloud/abra/commit/98e674b8e83458a83dcbf331e8e34c7188559c4a)) | ||||||
|  | |||||||
							
								
								
									
										33
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | FROM alpine:latest | ||||||
|  |  | ||||||
|  | RUN apk add --upgrade --no-cache \ | ||||||
|  |   bash \ | ||||||
|  |   curl \ | ||||||
|  |   git \ | ||||||
|  |   grep \ | ||||||
|  |   openssh-client \ | ||||||
|  |   py3-requests \ | ||||||
|  |   skopeo \ | ||||||
|  |   util-linux | ||||||
|  |  | ||||||
|  | RUN mkdir -p ~./local/bin | ||||||
|  | RUN mkdir -p ~/.abra/apps | ||||||
|  | RUN mkdir -p ~/.abra/vendor | ||||||
|  | RUN mkdir -p ~/.ssh/ | ||||||
|  |  | ||||||
|  | RUN ssh-keyscan -p 2222 git.autonomic.zone > ~/.ssh/known_hosts | ||||||
|  |  | ||||||
|  | RUN curl -L https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 --output ~/.abra/vendor/jq | ||||||
|  | RUN chmod +x ~/.abra/vendor/jq | ||||||
|  |  | ||||||
|  | RUN curl -L https://github.com/mikefarah/yq/releases/download/v4.9.3/yq_linux_amd64 --output ~/.abra/vendor/yq | ||||||
|  | RUN chmod +x ~/.abra/vendor/yq | ||||||
|  |  | ||||||
|  | # Note(decentral1se): it is fine to always use the development branch because | ||||||
|  | # our Drone CI docker auto-tagger will publish official release tags and | ||||||
|  | # otherwise give us the latest abra on the latest tag | ||||||
|  | RUN curl https://install.abra.coopcloud.tech | bash -s -- --dev | ||||||
|  |  | ||||||
|  | COPY bin/* /root/.local/bin/ | ||||||
|  |  | ||||||
|  | ENTRYPOINT ["/root/.local/bin/abra"] | ||||||
							
								
								
									
										58
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								README.md
									
									
									
									
									
								
							| @ -1,37 +1,61 @@ | |||||||
| # abra | # abra | ||||||
|  |  | ||||||
| [](https://drone.autonomic.zone/coop-cloud/abra) | [](https://drone.autonomic.zone/coop-cloud/abra) | ||||||
| [](undefined) |  | ||||||
|  |  | ||||||
| > https://cloud.autonomic.zone | > https://coopcloud.tech | ||||||
|  |  | ||||||
| The cooperative cloud utility belt 🎩🐇 | The Co-op Cloud utility belt 🎩🐇 | ||||||
|  |  | ||||||
| `abra` is a command-line tool for managing your own [Co-op Cloud](https://cloud.autonomic.zone). 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. | `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 | ## 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). | 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 | ||||||
|  |  | ||||||
|  | Requirements: | ||||||
|  |  | ||||||
|  | - `pwqgen` (optional) | ||||||
|  | - `pwgen` (optional) | ||||||
|  | - `curl` | ||||||
|  | - `docker` | ||||||
|  | - `bash` >= 4 | ||||||
|  |  | ||||||
| Install the latest stable release: | Install the latest stable release: | ||||||
|  |  | ||||||
| ```sh | ```sh | ||||||
| curl https://install.abra.autonomic.zone | bash | curl https://install.abra.coopcloud.tech | bash | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| or the bleeding-edge development version: | or the bleeding-edge development version: | ||||||
|  |  | ||||||
| ```sh | ```sh | ||||||
| curl https://install.abra.autonomic.zone | bash -s -- --dev | curl https://install.abra.coopcloud.tech | bash -s -- --dev | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| The source for this script is [here](./installer/installer). | The source for this script is [here](./deploy/install.abra.coopcloud.tech/installer). | ||||||
|  |  | ||||||
|  | ## Container | ||||||
|  |  | ||||||
|  | An [image](https://hub.docker.com/r/decentral1se/abra) is also provided. | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | docker run decentral1se/abra app ls | ||||||
|  | ``` | ||||||
|  |  | ||||||
| ## Update | ## Update | ||||||
|  |  | ||||||
| @ -44,14 +68,22 @@ To update the development version, run `abra upgrade --dev`. | |||||||
|  |  | ||||||
| It's written in Bash version 4 or greater! | 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`. | Install it via `curl https://install.abra.coopcloud.tech | 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. | 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. | Please remember to update the [CHANGELOG](./CHANGELOG.md) when you make a change. | ||||||
|  |  | ||||||
| To deploy a new version of the installer scripts: | ## Releasing | ||||||
|  |  | ||||||
| ```sh | ### `abra` | ||||||
| make release-installer |  | ||||||
| ``` | > [install.abra.coopcloud.tech](https://install.abra.coopcloud.tech) | ||||||
|  |  | ||||||
|  | - 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.coopcloud.tech/installer](./deploy/install.abra.coopcloud.tech/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.) | ||||||
|  | |||||||
| @ -1,42 +0,0 @@ | |||||||
| #!/bin/bash |  | ||||||
|  |  | ||||||
| # Usage: ./app-version.sh <image> <service> |  | ||||||
| # Example: ./app-version.sh drone/drone:1.10.1 app |  | ||||||
| # |  | ||||||
| # Accepts a full format hub.docker.com image tag which it pulls locally and |  | ||||||
| # generates output which can be used to put in the abra.sh for app packaging. |  | ||||||
| # Requires the yq program https://mikefarah.gitbook.io/yq/ |  | ||||||
|  |  | ||||||
| error() { |  | ||||||
|   echo "$(tput setaf 1)ERROR: $*$(tput sgr0)" |  | ||||||
|   exit 1 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| IMAGE="$1" |  | ||||||
| SERVICE="$2" |  | ||||||
|  |  | ||||||
| if ! docker pull -q "$IMAGE" > /dev/null 2>&1; then |  | ||||||
| 	error "Failed to download image, is the tag correct?" |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| version=$(echo "$IMAGE" | cut -d ':' -f2) |  | ||||||
| digest=$(docker image inspect -f "{{.Id}}" "$IMAGE" | cut -d ':' -f2- | cut -c 1-8) |  | ||||||
|  |  | ||||||
| echo "--- Add the following to your abra.sh ---" |  | ||||||
| echo "export ABRA_TYPE_${SERVICE^^}_VERSION=${version}" |  | ||||||
| echo "export ABRA_TYPE_${SERVICE^^}_DIGEST=${digest}" |  | ||||||
|  |  | ||||||
| version_lookup="ABRA_TYPE_${SERVICE^^}_VERSION" |  | ||||||
| digest_lookup="ABRA_TYPE_${SERVICE^^}_DIGEST" |  | ||||||
|  |  | ||||||
| label='- "coop-cloud.${STACK_NAME}.' |  | ||||||
| label+="${SERVICE}" |  | ||||||
| label+='.version=${' |  | ||||||
| label+="${version_lookup}" |  | ||||||
| label+='}-${' |  | ||||||
| label+="${digest_lookup}" |  | ||||||
| label+='}"' |  | ||||||
|  |  | ||||||
| echo |  | ||||||
| echo "--- And don't forget to label the actual service in the compose file ---" |  | ||||||
| echo "$label" |  | ||||||
							
								
								
									
										108
									
								
								bin/abralib.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								bin/abralib.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,108 @@ | |||||||
|  | """Shared utilities for bin/*.py scripts.""" | ||||||
|  |  | ||||||
|  | from logging import DEBUG, basicConfig, getLogger | ||||||
|  | from os import chdir, mkdir | ||||||
|  | from os.path import exists, expanduser | ||||||
|  | from pathlib import Path | ||||||
|  | from shlex import split | ||||||
|  | from subprocess import check_output | ||||||
|  | from sys import exit | ||||||
|  |  | ||||||
|  | from requests import get | ||||||
|  |  | ||||||
|  | HOME_PATH = expanduser("~/") | ||||||
|  | CLONES_PATH = Path(f"{HOME_PATH}/.abra/apps").absolute() | ||||||
|  | REPOS_TO_SKIP = ( | ||||||
|  |     "abra", | ||||||
|  |     "abra-apps", | ||||||
|  |     "abra-gandi", | ||||||
|  |     "abra-hetzner", | ||||||
|  |     "auto-apps-json", | ||||||
|  |     "auto-mirror", | ||||||
|  |     "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", | ||||||
|  | ) | ||||||
|  | YQ_PATH = Path(f"{HOME_PATH}/.abra/vendor/yq") | ||||||
|  | JQ_PATH = Path(f"{HOME_PATH}/.abra/vendor/jq") | ||||||
|  |  | ||||||
|  | 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 clone_all_apps(repos_json, ssh=False): | ||||||
|  |     """Clone all Co-op Cloud apps to ~/.abra/apps.""" | ||||||
|  |     if not exists(CLONES_PATH): | ||||||
|  |         mkdir(CLONES_PATH) | ||||||
|  |  | ||||||
|  |     if ssh: | ||||||
|  |         repos = [[p["name"], p["ssh_url"]] for p in repos_json] | ||||||
|  |     else: | ||||||
|  |         repos = [[p["name"], p["clone_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") | ||||||
| @ -1,4 +1,7 @@ | |||||||
| #!/bin/bash | #!/bin/bash | ||||||
|  | 
 | ||||||
|  | # shellcheck disable=SC2119 | ||||||
|  | 
 | ||||||
| # Usage: ./app-catalogue.sh | # Usage: ./app-catalogue.sh | ||||||
| # | # | ||||||
| # Gather metadata from Co-op Cloud apps in $ABRA_DIR/apps (default | # Gather metadata from Co-op Cloud apps in $ABRA_DIR/apps (default | ||||||
| @ -7,7 +10,7 @@ | |||||||
| 
 | 
 | ||||||
| stack_dir="${ABRA_DIR:-$HOME/.abra}/apps/" | stack_dir="${ABRA_DIR:-$HOME/.abra}/apps/" | ||||||
| 
 | 
 | ||||||
| cd "$stack_dir" | cd "$stack_dir" || exit | ||||||
| 
 | 
 | ||||||
| # load all README files into ENV_FILES array | # load all README files into ENV_FILES array | ||||||
| mapfile -t readmes < <(find -L . -name "README.md") | mapfile -t readmes < <(find -L . -name "README.md") | ||||||
							
								
								
									
										214
									
								
								bin/app-json.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										214
									
								
								bin/app-json.py
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,214 @@ | |||||||
|  | #!/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 os import chdir, getcwd, listdir | ||||||
|  | from os.path import basename | ||||||
|  | from re import findall, search | ||||||
|  | from subprocess import DEVNULL | ||||||
|  |  | ||||||
|  | from requests import get | ||||||
|  |  | ||||||
|  | from abralib import ( | ||||||
|  |     CLONES_PATH, | ||||||
|  |     JQ_PATH, | ||||||
|  |     REPOS_TO_SKIP, | ||||||
|  |     YQ_PATH, | ||||||
|  |     _run_cmd, | ||||||
|  |     clone_all_apps, | ||||||
|  |     get_repos_json, | ||||||
|  |     log, | ||||||
|  | ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 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 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", app) | ||||||
|  |  | ||||||
|  |         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"\*\*.*", 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_PATH} '.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"{getcwd()}/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() | ||||||
							
								
								
									
										16
									
								
								bin/clone-all-apps.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										16
									
								
								bin/clone-all-apps.py
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | #!/usr/bin/env python3 | ||||||
|  |  | ||||||
|  | # Usage: ./clone-all-apps.py | ||||||
|  | # | ||||||
|  | # Clone all available apps into ~/.abra/apps using ssh:// URLs | ||||||
|  |  | ||||||
|  | from abralib import clone_all_apps, get_repos_json | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def main(): | ||||||
|  |     """Run the script.""" | ||||||
|  |     repos_json = get_repos_json() | ||||||
|  |     clone_all_apps(repos_json, ssh=True) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | main() | ||||||
							
								
								
									
										47
									
								
								bin/github-sync.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										47
									
								
								bin/github-sync.py
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,47 @@ | |||||||
|  | #!/usr/bin/env python3 | ||||||
|  |  | ||||||
|  | # Usage: ./github-sync.py | ||||||
|  | # | ||||||
|  | # Mirror repositories to Github (Fuck M$, get it straight) | ||||||
|  |  | ||||||
|  | from os import chdir, environ, listdir | ||||||
|  |  | ||||||
|  | from abralib import ( | ||||||
|  |     CLONES_PATH, | ||||||
|  |     REPOS_TO_SKIP, | ||||||
|  |     _run_cmd, | ||||||
|  |     clone_all_apps, | ||||||
|  |     get_repos_json, | ||||||
|  |     log, | ||||||
|  | ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def main(): | ||||||
|  |     """Run the script.""" | ||||||
|  |     repos_json = get_repos_json() | ||||||
|  |     clone_all_apps(repos_json) | ||||||
|  |  | ||||||
|  |     for app in listdir(CLONES_PATH): | ||||||
|  |         if app in REPOS_TO_SKIP: | ||||||
|  |             log.info(f"Skipping {app}") | ||||||
|  |             continue | ||||||
|  |  | ||||||
|  |         app_path = f"{CLONES_PATH}/{app}" | ||||||
|  |         chdir(app_path) | ||||||
|  |  | ||||||
|  |         log.info(f"Mirroring {app}...") | ||||||
|  |  | ||||||
|  |         token = environ.get("GITHUB_ACCESS_TOKEN") | ||||||
|  |         remote = ( | ||||||
|  |             f"https://decentral1se:{token}@github.com/Autonomic-Cooperative/{app}.git" | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         _run_cmd( | ||||||
|  |             f"git remote add github {remote} || true", | ||||||
|  |             shell=True, | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         _run_cmd("git push github --all") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | main() | ||||||
							
								
								
									
										20
									
								
								bin/renovate-ls-apps.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										20
									
								
								bin/renovate-ls-apps.py
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,20 @@ | |||||||
|  | #!/usr/bin/env python3 | ||||||
|  |  | ||||||
|  | # Usage: ./renovate-ls-apps.py | ||||||
|  | # | ||||||
|  | # Output list of apps for Renovate bot configuration | ||||||
|  |  | ||||||
|  | from abralib import REPOS_TO_SKIP, get_repos_json | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def main(): | ||||||
|  |     """Run the script.""" | ||||||
|  |     repos = [p["full_name"] for p in get_repos_json()] | ||||||
|  |     repos.sort() | ||||||
|  |     for repo in repos: | ||||||
|  |         if repo.split("/")[-1] in REPOS_TO_SKIP: | ||||||
|  |             continue | ||||||
|  |         print(f'"{repo}",') | ||||||
|  |  | ||||||
|  |  | ||||||
|  | main() | ||||||
| @ -38,6 +38,22 @@ _abra_complete_apps() | |||||||
|     mapfile -t COMPREPLY < <(compgen -W "$(_abra_apps)" -- "$1") |     mapfile -t COMPREPLY < <(compgen -W "$(_abra_apps)" -- "$1") | ||||||
| } | } | ||||||
|  |  | ||||||
|  | _abra_recipes() | ||||||
|  | { | ||||||
|  |     shopt -s nullglob dotglob | ||||||
|  |     local RECIPES=(~/.abra/apps/*) | ||||||
|  |     shopt -u nullglob dotglob | ||||||
|  |  | ||||||
|  |     for RECIPE in "${RECIPES[@]}"; do | ||||||
|  |         _abra_basename "${RECIPE%.env}" | ||||||
|  |     done | ||||||
|  | } | ||||||
|  |  | ||||||
|  | _abra_complete_recipes() | ||||||
|  | { | ||||||
|  |     mapfile -t COMPREPLY < <(compgen -W "$(_abra_recipes)" -- "$1") | ||||||
|  | } | ||||||
|  |  | ||||||
| _abra_complete() | _abra_complete() | ||||||
| { | { | ||||||
|     compopt +o default +o nospace |     compopt +o default +o nospace | ||||||
| @ -46,6 +62,7 @@ _abra_complete() | |||||||
|     local -r cmds=' |     local -r cmds=' | ||||||
|         app |         app | ||||||
|         server |         server | ||||||
|  |         recipe | ||||||
|     ' |     ' | ||||||
|     local -r short_opts='-e      -h     -s      -v' |     local -r short_opts='-e      -h     -s      -v' | ||||||
|     local -r long_opts='--env --help --stack --version' |     local -r long_opts='--env --help --stack --version' | ||||||
| @ -101,6 +118,12 @@ _abra_complete() | |||||||
|                     _abra_complete_apps "$cur" |                     _abra_complete_apps "$cur" | ||||||
|                 fi |                 fi | ||||||
|                 ;; |                 ;; | ||||||
|  |             recipe) | ||||||
|  |                 # Offer exactly one app completion. | ||||||
|  |                 if (( COMP_CWORD == cmd_index + 1 )); then | ||||||
|  |                     _abra_complete_recipes "$cur" | ||||||
|  |                 fi | ||||||
|  |                 ;; | ||||||
|             #help) |             #help) | ||||||
|             #    # Offer exactly one command name completion. |             #    # Offer exactly one command name completion. | ||||||
|             #    if (( COMP_CWORD == cmd_index + 1 )); then |             #    if (( COMP_CWORD == cmd_index + 1 )); then | ||||||
|  | |||||||
| @ -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 | ||||||
| @ -20,7 +20,7 @@ services: | |||||||
|       labels: |       labels: | ||||||
|         - "traefik.enable=true" |         - "traefik.enable=true" | ||||||
|         - "traefik.http.services.abra-installer.loadbalancer.server.port=80" |         - "traefik.http.services.abra-installer.loadbalancer.server.port=80" | ||||||
|         - "traefik.http.routers.abra-installer.rule=Host(`install.abra.autonomic.zone`)" |         - "traefik.http.routers.abra-installer.rule=Host(`install.abra.autonomic.zone`,`install.abra.coopcloud.tech`)" | ||||||
|         - "traefik.http.routers.abra-installer.entrypoints=web-secure" |         - "traefik.http.routers.abra-installer.entrypoints=web-secure" | ||||||
|         - "traefik.http.routers.abra-installer.tls.certresolver=production" |         - "traefik.http.routers.abra-installer.tls.certresolver=production" | ||||||
| 
 | 
 | ||||||
| @ -1,8 +1,9 @@ | |||||||
| #!/bin/bash | #!/bin/bash | ||||||
| 
 | 
 | ||||||
| ABRA_VERSION="0.6.0" | ABRA_VERSION="9.0.0" | ||||||
| GIT_URL="https://git.autonomic.zone/coop-cloud/abra" | GIT_URL="https://git.autonomic.zone/coop-cloud/abra" | ||||||
| ABRA_SRC="$GIT_URL/raw/tag/$ABRA_VERSION/abra" | ABRA_SRC="$GIT_URL/raw/tag/$ABRA_VERSION/abra" | ||||||
|  | ABRA_DIR="${ABRA_DIR:-$HOME/.abra}" | ||||||
| 
 | 
 | ||||||
| function install_abra_release { | function install_abra_release { | ||||||
|   mkdir -p "$HOME/.local/bin" |   mkdir -p "$HOME/.local/bin" | ||||||
| @ -12,13 +13,13 @@ function install_abra_release { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function install_abra_dev { | function install_abra_dev { | ||||||
|   mkdir -p "$HOME/.abra/" |   mkdir -p "$ABRA_DIR/" | ||||||
|   if [[ ! -d "$HOME/.abra/src" ]]; then |   if [[ ! -d "$ABRA_DIR/src" ]]; then | ||||||
|     git clone "$GIT_URL" "$HOME/.abra/src" |     git clone "$GIT_URL" "$ABRA_DIR/src" | ||||||
|   fi |   fi | ||||||
|   ( cd "$HOME/.abra/src" && git pull origin main && cd -) |   (cd "$ABRA_DIR/src" && git pull origin main && cd - || exit) | ||||||
|   mkdir -p "$HOME/.local/bin" |   mkdir -p "$HOME/.local/bin" | ||||||
|   ln -sf "$HOME/.abra/src/abra" "$HOME/.local/bin/abra" |   ln -sf "$ABRA_DIR/src/abra" "$HOME/.local/bin/abra" | ||||||
|   echo "abra installed to $HOME/.local/bin/abra (development bleeding edge)" |   echo "abra installed to $HOME/.local/bin/abra (development bleeding edge)" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -1,6 +1,6 @@ | |||||||
| server { | server { | ||||||
|   listen         80 default_server; |   listen         80 default_server; | ||||||
|   server_name    install.abra.autonomic.zone; |   server_name    install.abra.autonomic.zone install.abra.coopcloud.tech; | ||||||
| 
 | 
 | ||||||
|   location / { |   location / { | ||||||
|     root /var/www/abra-installer; |     root /var/www/abra-installer; | ||||||
							
								
								
									
										39
									
								
								makefile
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								makefile
									
									
									
									
									
								
							| @ -1,4 +1,4 @@ | |||||||
| .PHONY: test shellcheck docopt kcov codecov release-installer | .PHONY: test shellcheck docopt release-installer build push | ||||||
|  |  | ||||||
| test: | test: | ||||||
| 	@sudo DOCKER_CONTEXT=default docker run \ | 	@sudo DOCKER_CONTEXT=default docker run \ | ||||||
| @ -7,13 +7,13 @@ test: | |||||||
| 		-d \ | 		-d \ | ||||||
| 		--name=abra-test-dind \ | 		--name=abra-test-dind \ | ||||||
| 		-e DOCKER_TLS_CERTDIR="" \ | 		-e DOCKER_TLS_CERTDIR="" \ | ||||||
| 		decentral1se/docker-dind-bats-kcov | 		decentral1se/docker-dind-bats-kcov \ | ||||||
| 	@DOCKER_CONTEXT=default docker exec \ | 	@DOCKER_CONTEXT=default sudo docker exec \ | ||||||
| 		-it \ | 		-it \ | ||||||
| 		abra-test-dind \ | 		abra-test-dind \ | ||||||
| 		sh -c "cd /workdir && bats /workdir/tests" | 		sh -c "cd /workdir && bats /workdir/tests" | ||||||
| 	@DOCKER_CONTEXT=default docker stop abra-test-dind | 	@DOCKER_CONTEXT=default sudo docker stop abra-test-dind | ||||||
| 	@DOCKER_CONTEXT=default docker rm abra-test-dind | 	@DOCKER_CONTEXT=default sudo docker rm abra-test-dind | ||||||
|  |  | ||||||
| shellcheck: | shellcheck: | ||||||
| 	@docker run \ | 	@docker run \ | ||||||
| @ -21,7 +21,8 @@ shellcheck: | |||||||
| 		--rm \ | 		--rm \ | ||||||
| 		-v $$(pwd):/workdir \ | 		-v $$(pwd):/workdir \ | ||||||
| 		koalaman/shellcheck-alpine \ | 		koalaman/shellcheck-alpine \ | ||||||
| 		shellcheck /workdir/abra | 		shellcheck /workdir/abra && \ | ||||||
|  | 		shellcheck /workdir/bin/*.sh | ||||||
|  |  | ||||||
| docopt: | docopt: | ||||||
| 	@if [ ! -d ".venv" ]; then \ | 	@if [ ! -d ".venv" ]; then \ | ||||||
| @ -31,20 +32,14 @@ docopt: | |||||||
| 	fi | 	fi | ||||||
| 	.venv/bin/docopt.sh abra | 	.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: | release-installer: | ||||||
| 	@docker stack rm abra-installer-script && \ | 	@DOCKER_CONTEXT=swarm.autonomic.zone \ | ||||||
| 		cd installer && \ | 		docker stack rm abra-installer-script && \ | ||||||
| 		docker stack deploy -c compose.yml abra-installer-script | 		cd deploy/install.abra.coopcloud.tech && \ | ||||||
|  | 		DOCKER_CONTEXT=swarm.autonomic.zone docker stack deploy -c compose.yml abra-installer-script | ||||||
|  |  | ||||||
|  | build: | ||||||
|  | 	@docker build -t decentral1se/abra . | ||||||
|  |  | ||||||
|  | push: build | ||||||
|  | 	@docker push decentral1se/abra | ||||||
|  | |||||||
| @ -9,44 +9,48 @@ teardown() { | |||||||
|     rm -rf "$ABRA_DIR" |     rm -rf "$ABRA_DIR" | ||||||
| } | } | ||||||
|  |  | ||||||
|  | abra() { | ||||||
|  |     ./abra -d $@ | ||||||
|  | } | ||||||
|  |  | ||||||
| @test "abra server (add|rm)" { | @test "abra server (add|rm)" { | ||||||
|     ./abra server add swarm.test.com |     abra server add swarm.test.com | ||||||
|     docker context ls | grep swarm.test.com |     docker context ls | grep swarm.test.com | ||||||
|     [ -d $ABRA_DIR/servers/swarm.test.com ] |     [ -d $ABRA_DIR/servers/swarm.test.com ] | ||||||
|     ./abra server swarm.test.com rm |     abra server swarm.test.com rm | ||||||
|  |  | ||||||
|     ./abra server add swarm.test.com foobar 12345 |     abra server add swarm.test.com foobar 12345 | ||||||
|     [ -d $ABRA_DIR/servers/swarm.test.com ] |     [ -d $ABRA_DIR/servers/swarm.test.com ] | ||||||
|     ./abra server swarm.test.com rm |     abra server swarm.test.com rm | ||||||
| } | } | ||||||
|  |  | ||||||
| @test "abra server init" { | @test "abra server init" { | ||||||
|     ./abra server default init |     abra server default init | ||||||
| } | } | ||||||
|  |  | ||||||
| @test "abra app (new|rm)" { | @test "abra app (new|rm)" { | ||||||
|     ./abra app new --server default --domain traefik.test.com --app-name traefik_test_com traefik |     abra app new --server default --domain traefik.test.com --app-name traefik_test_com traefik | ||||||
|     [ -f $ABRA_DIR/servers/default/traefik_test_com.env ] |     [ -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 --app-name 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)" { | ||||||
|     ./abra app new --server default --domain traefik_test_com --app-name traefik_test_com traefik |     abra app new --server default --domain traefik_test_com --app-name 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 | ||||||
| } | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	