Compare commits
273 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e2bd55fb5 | ||
|
|
4b36e2f3b7 | ||
|
|
ed94d326d4 | ||
|
|
17be38e532 | ||
|
|
3f09c82379 | ||
|
|
c2cb0486f4 | ||
|
|
b1b5a7fa11 | ||
|
|
3a9d88d175 | ||
|
|
a422c64153 | ||
|
|
c01767fade | ||
|
|
f59dbe4f63 | ||
|
|
2160a8b64e | ||
|
|
c66c85429e | ||
|
|
520bc94357 | ||
|
|
dea4251b2c | ||
|
|
7f64bb1255 | ||
|
|
831600d8c9 | ||
|
|
d42b046177 | ||
|
|
738bfb7446 | ||
|
|
a72c04ed65 | ||
|
|
3921cab2df | ||
|
|
a52dbafc5f | ||
|
|
d26eadfa21 | ||
|
|
321a310fe5 | ||
|
|
772f9d1b6a | ||
|
|
613dd3d1c4 | ||
|
|
aba5d03632 | ||
|
|
0403978ade | ||
|
|
da12a8c835 | ||
|
|
fc24ad965e | ||
|
|
736aa4c48d | ||
|
|
1de3651774 | ||
|
|
c4c0488339 | ||
|
|
bb05787ea7 | ||
|
|
d92502107e | ||
|
|
9ab224f3ce | ||
|
|
8bf5f398b1 | ||
|
|
be0ba28570 | ||
|
|
dbd86ad7a2 | ||
|
|
5f312d7347 | ||
|
|
6e9f21b1d5 | ||
|
|
a631505cd6 | ||
|
|
f36701206c | ||
|
|
42122a7540 | ||
|
|
996e2c7d92 | ||
|
|
64993a57eb | ||
|
|
eaf0d9af55 | ||
|
|
0c44656acf | ||
|
|
0d749b3e7a | ||
|
|
90b3528f6b | ||
|
|
07f0bf3a50 | ||
|
|
bcfa530056 | ||
|
|
3f4b0eccd8 | ||
|
|
591ecff646 | ||
|
|
7481943a9b | ||
|
|
16241b4ce1 | ||
|
|
9dbc352006 | ||
|
|
1a0c123823 | ||
|
|
45e3623ffd | ||
|
|
1eaa98d3e6 | ||
|
|
e75aadff15 | ||
|
|
d8cd5250a2 | ||
|
|
9e7b31b4e8 | ||
|
|
726d55f771 | ||
|
|
a4c67d50ee | ||
|
|
564de7434b | ||
|
|
59f1ba20db | ||
|
|
5ad7ece8d3 | ||
|
|
dabe90a0de | ||
|
|
1ecb9585ef | ||
|
|
36ceca7a94 | ||
|
|
42a46df51f | ||
|
|
008b362751 | ||
|
|
81717f67f3 | ||
|
|
b6bf22812b | ||
|
|
8557ec1226 | ||
|
|
570fcce2ee | ||
|
|
ef5a4b08d6 | ||
|
|
5fd04001d8 | ||
|
|
fb7bac4652 | ||
|
|
ef46db5d6b | ||
|
|
a9e130b090 | ||
|
|
f23413742a | ||
|
|
7ffe0c3b58 | ||
|
|
62e0ba6952 | ||
|
|
59910749b7 | ||
|
|
a5d53711ee | ||
|
|
9d747b7c82 | ||
|
|
3084ac098e | ||
|
|
f083561ee7 | ||
|
|
ae67f14f9b | ||
|
|
9d6746001e | ||
|
|
c632b6b358 | ||
|
|
9c300dc14b | ||
|
|
02d9c53520 | ||
|
|
ca5c9d6c45 | ||
|
|
90a5391252 | ||
|
|
cf113ecda2 | ||
|
|
0b9cecef4d | ||
|
|
52ea598ba4 | ||
|
|
f4bec4a1c8 | ||
|
|
293d7efe07 | ||
|
|
c9e24a055c | ||
|
|
e9ecc98b3d | ||
|
|
0932fd7f7c | ||
|
|
9ded7e176f | ||
|
|
1738009f6b | ||
|
|
bd3d8a54ad | ||
|
|
c97fd92fcf | ||
|
|
6d4d8a89ed | ||
|
|
7f9f289bd6 | ||
|
|
3c56a0c323 | ||
|
|
401ec40566 | ||
|
|
edf5d29213 | ||
|
|
03f8922ffd | ||
|
|
b9cc89e4d2 | ||
|
|
fb4a232537 | ||
|
|
cf35cedd1e | ||
|
|
2919415d7e | ||
|
|
ee083eb3c3 | ||
|
|
ca1e188e9a | ||
|
|
ef4fe2dbf9 | ||
|
|
6e7e7d35cc | ||
|
|
88e01d8a4b | ||
|
|
a8fd8d1b19 | ||
|
|
f47a267917 | ||
|
|
bf7e86fb13 | ||
|
|
1cab6acf69 | ||
|
|
75a2d3a1ba | ||
|
|
ca248a62ec | ||
|
|
b50590e2ad | ||
|
|
db253c15cc | ||
|
|
d60140dad8 | ||
|
|
5c17bcc710 | ||
|
|
d682bd52ff | ||
|
|
1ba874ea62 | ||
|
|
614ba66450 | ||
|
|
9451216606 | ||
|
|
ef91685596 | ||
|
|
dfaa20e449 | ||
|
|
d7b0d2a4d9 | ||
|
|
2b9e5bbaea | ||
|
|
8e0d288b2e | ||
|
|
75cdc585b6 | ||
|
|
a9d2610e34 | ||
|
|
e2eceb49ca | ||
|
|
e8eba15e49 | ||
|
|
4a8ebd8dee | ||
|
|
9dcf17be69 | ||
|
|
4aae0f1a1d | ||
|
|
f6a193935d | ||
|
|
46d4de261c | ||
|
|
b4b2c4301f | ||
|
|
bb2265a3c9 | ||
|
|
484f61fdd5 | ||
|
|
5aae49f1a0 | ||
|
|
ee7abe3098 | ||
|
|
981c5e1dd6 | ||
|
|
d9868a3862 | ||
|
|
c8edeb01e6 | ||
|
|
12e2b22ea8 | ||
|
|
a8008b8d33 | ||
|
|
7d539e5b03 | ||
|
|
2e2320ec73 | ||
|
|
676027caf6 | ||
|
|
2588bedcfe | ||
|
|
272c96b171 | ||
|
|
a1935687a2 | ||
|
|
6b25ab16b7 | ||
|
|
6b6518c699 | ||
|
|
88f661b6e7 | ||
|
|
aff0c1fc40 | ||
|
|
aa63e79aec | ||
|
|
a0cb7c560e | ||
|
|
68d1a04215 | ||
|
|
a4da6f67cc | ||
|
|
a93cec63be | ||
|
|
c22f78c913 | ||
|
|
a60467cb2d | ||
|
|
91a668ee8f | ||
|
|
94aa67d494 | ||
|
|
6636c48838 | ||
|
|
ce154aff09 | ||
|
|
6a8783e357 | ||
|
|
d6510ad936 | ||
|
|
c2c9671061 | ||
|
|
def0a2c0ee | ||
|
|
995ca5902f | ||
|
|
10d959501d | ||
|
|
d8cff6566e | ||
|
|
a5a06196b1 | ||
|
|
0f6d809aff | ||
|
|
2cbc850df3 | ||
|
|
7509c7adbf | ||
|
|
b1ac99c616 | ||
|
|
0c7ef180d0 | ||
|
|
4c59dcaea6 | ||
|
|
08b3a4b7a7 | ||
|
|
125c093ba5 | ||
|
|
891c3e5e59 | ||
|
|
ba9fa1d0b7 | ||
|
|
830c9006ca | ||
|
|
ec16aa92ac | ||
|
|
2dfb0ef3e6 | ||
|
|
03daa33d83 | ||
|
|
883bcd897f | ||
|
|
ba6cca4093 | ||
|
|
a1581bc963 | ||
|
|
2a26cd9d5a | ||
|
|
46eb092006 | ||
|
|
87dc7e39e6 | ||
|
|
9ed77ab6c1 | ||
|
|
46287cac0f | ||
|
|
b011a3a558 | ||
|
|
e3e430f4d7 | ||
|
|
b63a40d4fe | ||
|
|
41bc54879d | ||
|
|
269a254425 | ||
|
|
4c748f2b36 | ||
|
|
ee7d7f164f | ||
|
|
962aa66965 | ||
|
|
92621a3187 | ||
|
|
04b32efd54 | ||
|
|
0931d655f7 | ||
|
|
480425bfb9 | ||
|
|
49351227d1 | ||
|
|
d3263a45c3 | ||
|
|
4f77c88e0b | ||
|
|
722390475b | ||
|
|
3b248de306 | ||
|
|
7ff5e56dc7 | ||
|
|
67f113a818 | ||
|
|
4136f0274a | ||
|
|
61a306664f | ||
|
|
d35576302d | ||
|
|
cca008f140 | ||
|
|
5458d5b341 | ||
|
|
42db45d6f4 | ||
|
|
2c3cbc1708 | ||
|
|
5e065e71c7 | ||
|
|
50705890d8 | ||
|
|
c33b58a3e0 | ||
|
|
4d4971b171 | ||
|
|
05513ad75a | ||
|
|
ee69e1ee4a | ||
|
|
88bc04797f | ||
|
|
c06644af62 | ||
|
|
89787173af | ||
|
|
65403d1cf7 | ||
|
|
e56c69494a | ||
|
|
9e9aa75fbb | ||
|
|
14934a9479 | ||
|
|
9b48a386fc | ||
|
|
9d60b487e6 | ||
|
|
3e83b2836c | ||
|
|
72425cff84 | ||
|
|
3ae68213ff | ||
|
|
a9ff33f9a5 | ||
|
|
f6a6444e66 | ||
|
|
6901e9658f | ||
|
|
a8a6d0595b | ||
|
|
ee786e1962 | ||
|
|
74e147005b | ||
|
|
3e442e551d | ||
|
|
2628df06a3 | ||
|
|
ba8eb6f2e5 | ||
|
|
8a380e52c4 | ||
|
|
aa94dc7a7b | ||
|
|
a42261b2b3 | ||
|
|
7482762592 | ||
|
|
fffc283459 | ||
|
|
7e6107fd04 | ||
|
|
65897ca4cd |
@@ -1,40 +1,114 @@
|
||||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
machine:
|
||||
image: ubuntu-1604:201903-01
|
||||
parallelism: 4
|
||||
version: 2.1
|
||||
|
||||
commands:
|
||||
init-tests:
|
||||
description: "Setup dokku for testing"
|
||||
steps:
|
||||
- checkout
|
||||
- run: |
|
||||
make ci-dependencies
|
||||
- run: |
|
||||
./tests/ci/setup.sh
|
||||
- run: |
|
||||
echo 'export DOKKU_SKIP_CLEANUP=true' | sudo tee /home/dokku/.dokkurc/dokku_skip_cleanup
|
||||
- run: |
|
||||
# dokku.me now resolves to 10.0.0.2. add 10.0.0.2/24 to ens4
|
||||
sudo ip a a 10.0.0.2/24 broadcast 10.0.0.255 dev ens4
|
||||
- run: |
|
||||
case $CIRCLE_NODE_INDEX in
|
||||
0) sudo -E make -e lint-ci go-tests ci-go-coverage ;;
|
||||
1) sudo -E make -e deploy-test-checks-root deploy-test-config ;;
|
||||
2) sudo -E make -e deploy-test-multi ;;
|
||||
3) sudo -E make -e deploy-test-go-fail-predeploy deploy-test-go-fail-postdeploy ;;
|
||||
esac
|
||||
- attach_workspace:
|
||||
at: /home/circleci/project
|
||||
- run:
|
||||
name: resolve dokku.me
|
||||
command: |
|
||||
# dokku.me now resolves to 10.0.0.2. add 10.0.0.2/24 to ens4
|
||||
# this is maybe eth0 on github
|
||||
ifconfig
|
||||
sudo ip addr add 10.0.0.2/24 broadcast 10.0.0.255 dev ens4
|
||||
- run:
|
||||
name: install ci-dependencies
|
||||
command: make ci-dependencies
|
||||
- run:
|
||||
name: setup tests
|
||||
command: ./tests/ci/setup.sh
|
||||
- run:
|
||||
name: dokku cleanup:skip
|
||||
command: echo 'export DOKKU_SKIP_CLEANUP=true' | sudo tee /home/dokku/.dokkurc/dokku_skip_cleanup
|
||||
- run:
|
||||
name: dokku report
|
||||
command: dokku report
|
||||
|
||||
executors:
|
||||
default:
|
||||
machine:
|
||||
image: ubuntu-1604:201903-01
|
||||
working_directory: /home/circleci/project
|
||||
|
||||
jobs:
|
||||
build:
|
||||
executor: default
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: build package
|
||||
command: ./tests/ci/setup.sh build
|
||||
- persist_to_workspace:
|
||||
root: /home/circleci/project
|
||||
paths:
|
||||
- build
|
||||
- store_artifacts:
|
||||
path: /home/circleci/project/build/dokku.deb
|
||||
- store_artifacts:
|
||||
path: /home/circleci/project/build/dokku.rpm
|
||||
docker-deploy-tests:
|
||||
executor: default
|
||||
steps:
|
||||
- init-tests
|
||||
- run:
|
||||
name: run docker deploy tests
|
||||
shell: /bin/bash
|
||||
command: sudo -E make -e test-ci
|
||||
no_output_timeout: 60m
|
||||
- run: |
|
||||
if [ "${CIRCLE_NODE_INDEX}" == "0" ]; then
|
||||
no_output_timeout: 20
|
||||
command: |
|
||||
./tests/ci/setup.sh docker
|
||||
DOKKU_SSH_PORT=3022 sudo -E make -e test-ci-docker
|
||||
fi
|
||||
go-tests:
|
||||
executor: default
|
||||
parallelism: 4
|
||||
steps:
|
||||
- init-tests
|
||||
- run:
|
||||
name: run go tests
|
||||
command: |
|
||||
case $CIRCLE_NODE_INDEX in
|
||||
0) sudo -E make -e lint-ci go-tests ci-go-coverage ;;
|
||||
1) sudo -E make -e deploy-test-checks-root deploy-test-config ;;
|
||||
2) sudo -E make -e deploy-test-multi ;;
|
||||
3) sudo -E make -e deploy-test-go-fail-predeploy deploy-test-go-fail-postdeploy ;;
|
||||
esac
|
||||
- store_artifacts:
|
||||
path: ./coverage.out
|
||||
test:
|
||||
executor: default
|
||||
parallelism: 4
|
||||
steps:
|
||||
- init-tests
|
||||
- run:
|
||||
name: run bats tests
|
||||
command: |
|
||||
sudo -E make -e test-ci
|
||||
no_output_timeout: 60m
|
||||
shell: /bin/bash
|
||||
- run:
|
||||
name: output oomkills
|
||||
command: cat /var/log/syslog
|
||||
when: on_fail
|
||||
- store_artifacts:
|
||||
path: ./test-results
|
||||
destination: test-results
|
||||
- store_test_results:
|
||||
path: test-results
|
||||
|
||||
workflows:
|
||||
workflow:
|
||||
jobs:
|
||||
- build
|
||||
- docker-deploy-tests:
|
||||
requires:
|
||||
- build
|
||||
- test
|
||||
- go-tests:
|
||||
requires:
|
||||
- build
|
||||
- test:
|
||||
requires:
|
||||
- build
|
||||
- go-tests
|
||||
|
||||
154
HISTORY.md
154
HISTORY.md
@@ -1,5 +1,159 @@
|
||||
# History
|
||||
|
||||
## 0.21.2
|
||||
|
||||
Install/update via the bootstrap script:
|
||||
|
||||
```shell
|
||||
wget https://raw.githubusercontent.com/dokku/dokku/v0.21.2/bootstrap.sh
|
||||
sudo DOKKU_TAG=v0.21.2 bash bootstrap.sh
|
||||
```
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- #4072: @Schlepptop Fix deprecation warning in config_all
|
||||
|
||||
### New Features
|
||||
|
||||
- #4061: @josegonzalez Drop go sum and mod files from releases
|
||||
|
||||
### Refactors
|
||||
|
||||
- #4064: @hugopeixoto Use *_PATH consistently
|
||||
|
||||
### Documentation
|
||||
|
||||
- #4069: @josegonzalez Scheduler plugins are no longer beta
|
||||
- #4068: @josegonzalez Official plugins are no longer in beta
|
||||
- #4066: @ltalirz Add ansible as installation route
|
||||
- #4063: @josegonzalez Clarify why we stop/rebuild apps during upgrade
|
||||
- #4040: @fonsp Added link to the buildpack plugin docs
|
||||
- #4062: @hugopeixoto Rewrite upgrade instructions
|
||||
|
||||
## 0.21.1
|
||||
|
||||
Install/update via the bootstrap script:
|
||||
|
||||
```shell
|
||||
wget https://raw.githubusercontent.com/dokku/dokku/v0.21.1/bootstrap.sh
|
||||
sudo DOKKU_TAG=v0.21.1 bash bootstrap.sh
|
||||
```
|
||||
|
||||
### Documentation
|
||||
|
||||
- #4060: @josegonzalez Add warning about the 0.21.0 release
|
||||
|
||||
## 0.21.0
|
||||
|
||||
> Warning: Release is broken and will be pulled from upstream. Please use a newer version.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- #4058: @hugopeixoto Ensure web installer creates files with correct permissions
|
||||
- #4055: @hugopeixoto Delete dokkurc recursively during uninstall
|
||||
- #4057: @hugopeixoto Install sudo when installing from source
|
||||
- #4045: @josegonzalez Filter gpus instead of nvidia-gpus from resource arguments
|
||||
- #4029: @josegonzalez Filter args _after_ docker-args-process-deploy
|
||||
- #4026: @josegonzalez Filter resource args from deploy tasks
|
||||
- #4022: @josegonzalez Do not allow slashes in app names
|
||||
- #4020: @josegonzalez Properly handle multiple containers in ps:inspect
|
||||
- #3989: @josegonzalez Correct entering running containers
|
||||
- #3977: @josegonzalez Set default port for all run commands
|
||||
- #3969: @josegonzalez Do not logrotate all services files
|
||||
- #3964: @josegonzalez Remove all --force-yes usage throughout the codebase
|
||||
- #3955: @benwh Fix missing 502 error page
|
||||
- #3953: @josegonzalez Use correct function name for cmd-tar-in and update migration guide
|
||||
|
||||
### New Features
|
||||
|
||||
- #4041: @rvanlaar feat: Add download option to the certs plugin
|
||||
- #4043: @josegonzalez Allow controlling nginx proxy-read-timeout
|
||||
- #4038: @josegonzalez Create proxy:build-config command
|
||||
- #4021: @josegonzalez Depend on python3 binary for CentOS 8 support
|
||||
- #4004: @josegonzalez Add support for moby-engine
|
||||
- #3967: @josegonzalez Add Ubuntu 20.04 support
|
||||
- #3988: @josegonzalez Upgrade plugn to 0.5.0
|
||||
- #3987: @josegonzalez Upgrade sigil to 0.6.0
|
||||
- #3986: @josegonzalez Upgrade sshcommand to 0.11.0
|
||||
- #3985: @josegonzalez Upgrade go-procfile-util to 0.8.2
|
||||
- #3982: @josegonzalez Allow apps named tls
|
||||
- #3979: @josegonzalez Upgrade herokuish
|
||||
- #3971: @josegonzalez feat: allow users to customize the source of the dokku.conf nginx template
|
||||
- #3966: @josegonzalez Move domain manipulation into triggers
|
||||
- #3965: @josegonzalez Drop dokku references in logging output
|
||||
- #3954: @josegonzalez feat: upgrade herokuish to 0.5.12
|
||||
- #3940: @josegonzalez Expose last updated time in git:report
|
||||
- #3939: @josegonzalez Add support for outputting the last visited time
|
||||
|
||||
### Refactors
|
||||
|
||||
- #4035: @josegonzalez Switch to go mod
|
||||
- #4008: @josegonzalez Standardize golang command code
|
||||
|
||||
### Documentation
|
||||
|
||||
- #4056: @swrobel Remove invalid help entry for dokku ps commmand
|
||||
- #4039: @josegonzalez Break out bc-break and refactors in changelog
|
||||
- #4025: @alexjj Switch AUR helper to yay
|
||||
- #4019: @tdak Added one possible solution to an error
|
||||
- #4014: @rvanlaar Update dreamhost cloudinit script
|
||||
- #4003: @josegonzalez Add dokku.ai asset
|
||||
- #3999: @DavidLemayian Update URL for less than 1gb memory in bootstrap.sh [ci skip]
|
||||
- #3998: @josegonzalez Document the #dokku channel on slack
|
||||
- #3996: @josegonzalez Clarify network aliases and add section on tld management
|
||||
- #3980: @josegonzalez Clarify that the web installer is not supported in docker-based installs
|
||||
- #3970: @josegonzalez Clarify the 'see the docs' internal links
|
||||
- #3968: @josegonzalez Document access.conf issue
|
||||
- #3957: @swrobel Add official registry plugin
|
||||
- #3942: @scowalt Fix grammar in environment variables documentation
|
||||
|
||||
### Tests
|
||||
|
||||
- #4046: @rvanlaar Make `make test` pass on linting
|
||||
- #4037: @josegonzalez Try to output oomkill information
|
||||
- #4036: @josegonzalez Store the deb and rpm artifacts
|
||||
- #4034: @josegonzalez Teardown apps and containers in global teardown
|
||||
- #4031: @josegonzalez Delete old apps and ensure the test helper is quieter
|
||||
- #4030: @josegonzalez Update circleci workflow
|
||||
- #3947: @jayjun Scope init tests to container processes only
|
||||
|
||||
### Other
|
||||
|
||||
- #4051: @dependabot-preview[bot] chore(deps-dev): bump heroku/heroku-buildpack-php from 177 to 178 in /tests/apps/php
|
||||
- #4028: @dependabot-preview[bot] chore(deps-dev): bump heroku/heroku-buildpack-php from 176 to 177 in /tests/apps/php
|
||||
- #4016: @dependabot-preview[bot] chore(deps): bump jetty-servlet from 9.4.29.v20200521 to 9.4.30.v20200611 in /tests/apps/java
|
||||
- #4006: @dependabot-preview[bot] chore(deps-dev): bump heroku/heroku-buildpack-php from 174 to 176 in /tests/apps/php
|
||||
- #4001: @dependabot-preview[bot] chore(deps): bump jetty-servlet from 9.4.28.v20200408 to 9.4.29.v20200521 in /tests/apps/java
|
||||
- #4002: @dependabot-preview[bot] chore(deps): bump monolog/monolog from 1.25.3 to 1.25.4 in /tests/apps/php
|
||||
- #3993: @dependabot-preview[bot] chore(deps): bump github.com/golang/protobuf from 1.4.1 to 1.4.2 in /tests/apps/gogrpc
|
||||
- #3962: @dependabot-preview[bot] chore(deps): bump github.com/golang/protobuf from 1.4.0 to 1.4.1 in /tests/apps/gogrpc
|
||||
- #3959: @dependabot-preview[bot] chore(deps-dev): bump heroku/heroku-buildpack-php from 173 to 174 in /tests/apps/php
|
||||
- #3950: @dependabot-preview[bot] chore(deps): bump google.golang.org/grpc from 1.29.0 to 1.29.1 in /tests/apps/gogrpc
|
||||
- #3946: @dependabot-preview[bot] chore(deps): bump google.golang.org/grpc from 1.28.1 to 1.29.0 in /tests/apps/gogrpc
|
||||
|
||||
## 0.20.4
|
||||
|
||||
Install/update via the bootstrap script:
|
||||
|
||||
```shell
|
||||
wget https://raw.githubusercontent.com/dokku/dokku/v0.20.4/bootstrap.sh
|
||||
sudo DOKKU_TAG=v0.20.4 bash bootstrap.sh
|
||||
```
|
||||
|
||||
### New Features
|
||||
|
||||
- #3936: @josegonzalez Enable limiting and reserving gpu resources
|
||||
|
||||
### Documentation
|
||||
|
||||
- #3937: @josegonzalez Add minor documentation for the kubernetes and nomad schedulers
|
||||
|
||||
### Other
|
||||
|
||||
- #3935: @dependabot-preview[bot] chore(deps): bump jinja2 from 2.11.1 to 2.11.2 in /tests/apps/python-flask
|
||||
- #3934: @dependabot-preview[bot] chore(deps): bump github.com/golang/protobuf from 1.3.5 to 1.4.0 in /tests/apps/gogrpc
|
||||
- #3933: @dependabot-preview[bot] chore(deps): bump jetty-servlet from 9.4.27.v20200227 to 9.4.28.v20200408 in /tests/apps/java
|
||||
|
||||
## 0.20.3
|
||||
|
||||
Install/update via the bootstrap script:
|
||||
|
||||
9
Makefile
9
Makefile
@@ -1,12 +1,13 @@
|
||||
DOKKU_VERSION ?= master
|
||||
|
||||
PROCFILE_VERSION ?= 0.6.0
|
||||
PLUGN_VERSION ?= 0.3.2
|
||||
SSHCOMMAND_VERSION ?= 0.10.0
|
||||
PROCFILE_VERSION ?= 0.8.2
|
||||
PLUGN_VERSION ?= 0.5.0
|
||||
SIGIL_VERSION ?= 0.6.0
|
||||
SSHCOMMAND_VERSION ?= 0.11.0
|
||||
SSHCOMMAND_URL ?= https://github.com/dokku/sshcommand/releases/download/v${SSHCOMMAND_VERSION}/sshcommand_${SSHCOMMAND_VERSION}_linux_x86_64.tgz
|
||||
PROCFILE_UTIL_URL ?= https://github.com/josegonzalez/go-procfile-util/releases/download/v${PROCFILE_VERSION}/procfile-util_${PROCFILE_VERSION}_linux_x86_64.tgz
|
||||
PLUGN_URL ?= https://github.com/dokku/plugn/releases/download/v${PLUGN_VERSION}/plugn_${PLUGN_VERSION}_linux_x86_64.tgz
|
||||
SIGIL_URL ?= https://github.com/gliderlabs/sigil/releases/download/v0.4.0/sigil_0.4.0_Linux_x86_64.tgz
|
||||
SIGIL_URL ?= https://github.com/gliderlabs/sigil/releases/download/v${SIGIL_VERSION}/sigil_${SIGIL_VERSION}_Linux_x86_64.tgz
|
||||
STACK_URL ?= https://github.com/gliderlabs/herokuish.git
|
||||
PREBUILT_STACK_URL ?= gliderlabs/herokuish:latest
|
||||
DOKKU_LIB_ROOT ?= /var/lib/dokku
|
||||
|
||||
@@ -99,8 +99,8 @@ Otherwise, you will need to import the keypair manually after installation using
|
||||
To install the latest stable release, run the following commands as a user who has access to `sudo`:
|
||||
|
||||
```shell
|
||||
wget https://raw.githubusercontent.com/dokku/dokku/v0.20.3/bootstrap.sh
|
||||
sudo DOKKU_TAG=v0.20.3 bash bootstrap.sh
|
||||
wget https://raw.githubusercontent.com/dokku/dokku/v0.21.2/bootstrap.sh
|
||||
sudo DOKKU_TAG=v0.21.2 bash bootstrap.sh
|
||||
```
|
||||
|
||||
You can then proceed to the ip address or domain name associated with your server to complete the web-based installation.
|
||||
|
||||
12
bootstrap.sh
12
bootstrap.sh
@@ -3,7 +3,7 @@ set -eo pipefail
|
||||
[[ $TRACE ]] && set -x
|
||||
|
||||
# A script to bootstrap dokku.
|
||||
# It expects to be run on Ubuntu 16.04/18.04, or CentOS 7 via 'sudo'
|
||||
# It expects to be run on Ubuntu 16.04/18.04/20.04, or CentOS 7 via 'sudo'
|
||||
# If installing a tag higher than 0.3.13, it may install dokku via a package (so long as the package is higher than 0.3.13)
|
||||
# It checks out the dokku source code from Github into ~/dokku and then runs 'make install' from dokku source.
|
||||
|
||||
@@ -12,7 +12,7 @@ set -eo pipefail
|
||||
# That's good because it prevents our output overlapping with wget's.
|
||||
# It also means that we can't run a partially downloaded script.
|
||||
|
||||
SUPPORTED_VERSIONS="Debian [9, 10], CentOS [7], Ubuntu [16.04, 18.04]"
|
||||
SUPPORTED_VERSIONS="Debian [9, 10], CentOS [7], Ubuntu [16.04, 18.04, 20.04]"
|
||||
|
||||
log-fail() {
|
||||
declare desc="log fail formatter"
|
||||
@@ -31,7 +31,7 @@ ensure-environment() {
|
||||
FREE_MEMORY=$(grep MemTotal /proc/meminfo | awk '{print $2}')
|
||||
if [[ "$FREE_MEMORY" -lt 1003600 ]]; then
|
||||
echo "For dokku to build containers, it is strongly suggested that you have 1024 megabytes or more of free memory"
|
||||
echo "If necessary, please consult this document to setup swap: http://dokku.viewdocs.io/dokku/advanced-installation/#vms-with-less-than-1gb-of-memory"
|
||||
echo "If necessary, please consult this document to setup swap: http://dokku.viewdocs.io/dokku/getting-started/advanced-installation/#vms-with-less-than-1-gb-of-memory"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ install-dokku-from-source() {
|
||||
log-fail "This installation script requires apt-get. For manual installation instructions, consult http://dokku.viewdocs.io/dokku/advanced-installation/"
|
||||
fi
|
||||
|
||||
apt-get -qq -y install git make software-properties-common
|
||||
apt-get -qq -y install sudo git make software-properties-common
|
||||
cd /root
|
||||
if [[ ! -d /root/dokku ]]; then
|
||||
git clone "$DOKKU_REPO" /root/dokku
|
||||
@@ -141,7 +141,7 @@ install-dokku-from-deb-package() {
|
||||
local NO_INSTALL_RECOMMENDS=${DOKKU_NO_INSTALL_RECOMMENDS:=""}
|
||||
local OS_ID
|
||||
|
||||
if ! in-array "$DOKKU_DISTRO_VERSION" "16.04" "18.04" "9" "10"; then
|
||||
if ! in-array "$DOKKU_DISTRO_VERSION" "16.04" "18.04" "20.04" "9" "10"; then
|
||||
log-fail "Unsupported Linux distribution. Only the following versions are supported: $SUPPORTED_VERSIONS"
|
||||
fi
|
||||
|
||||
@@ -172,7 +172,7 @@ install-dokku-from-deb-package() {
|
||||
fi
|
||||
|
||||
if [[ "$DOKKU_DISTRO" == "ubuntu" ]]; then
|
||||
OS_IDS=("xenial" "bionic")
|
||||
OS_IDS=("xenial" "bionic" "focal")
|
||||
if ! in-array "$OS_ID" "${OS_IDS[@]}"; then
|
||||
OS_ID="bionic"
|
||||
fi
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
GO_ARGS ?= -a
|
||||
GO_REPO_ROOT := /go/src/github.com/dokku/dokku
|
||||
BUILD_IMAGE := golang:1.12
|
||||
BUILD_IMAGE := golang:1.14.4
|
||||
|
||||
.PHONY: build-in-docker build clean src-clean
|
||||
|
||||
@@ -10,8 +10,9 @@ build-in-docker: clean
|
||||
mkdir -p /tmp/dokku-go-build-cache
|
||||
docker run --rm \
|
||||
-v $$PWD/../..:$(GO_REPO_ROOT) \
|
||||
-v /tmp/dokku-go-build-cache:/root/.cache/go-build \
|
||||
-v /tmp/dokku-go-build-cache:/root/.cache \
|
||||
-e PLUGIN_NAME=$(PLUGIN_NAME) \
|
||||
-e GO111MODULE=on \
|
||||
-w $(GO_REPO_ROOT)/plugins/$(PLUGIN_NAME) \
|
||||
$(BUILD_IMAGE) \
|
||||
bash -c "GO_ARGS='$(GO_ARGS)' make -j4 build" || exit $$?
|
||||
@@ -31,7 +32,7 @@ subcommands/%:
|
||||
ln -sf subcommands $@
|
||||
|
||||
src-clean:
|
||||
rm -rf .gitignore src vendor Makefile *.go glide.*
|
||||
rm -rf .gitignore src vendor Makefile *.go glide.* go.sum go.mod
|
||||
|
||||
triggers:
|
||||
go build -ldflags="-s -w" $(GO_ARGS) -o triggers src/triggers/triggers.go
|
||||
|
||||
@@ -17,6 +17,7 @@ def download_file(filename, url):
|
||||
def upload_file(filename):
|
||||
versions = [
|
||||
"xenial"
|
||||
"focal"
|
||||
]
|
||||
cmd_template = "package_cloud push dokku/dokku/ubuntu/{0} {1}"
|
||||
for version in versions:
|
||||
|
||||
@@ -4,6 +4,7 @@ import cgi
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
try:
|
||||
import SimpleHTTPServer
|
||||
import SocketServer
|
||||
@@ -14,7 +15,7 @@ import subprocess
|
||||
import sys
|
||||
import threading
|
||||
|
||||
VERSION = 'v0.20.3'
|
||||
VERSION = 'v0.21.2'
|
||||
|
||||
def bytes_to_string(b):
|
||||
if type(b) == bytes:
|
||||
@@ -143,20 +144,31 @@ class GetHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
|
||||
'REQUEST_METHOD': 'POST',
|
||||
'CONTENT_TYPE': self.headers['Content-Type']})
|
||||
|
||||
vhost_enable = 'false'
|
||||
dokku_root = os.getenv('DOKKU_ROOT', '/home/dokku')
|
||||
dokku_user = os.getenv('DOKKU_SYSTEM_GROUP', 'dokku')
|
||||
dokku_group = os.getenv('DOKKU_SYSTEM_USER', 'dokku')
|
||||
|
||||
vhost_enable = 'false'
|
||||
vhost_filename = '{0}/VHOST'.format(dokku_root)
|
||||
|
||||
if 'vhost' in params and params['vhost'].value == 'true':
|
||||
vhost_enable = 'true'
|
||||
with open('{0}/VHOST'.format(dokku_root), 'w') as f:
|
||||
with open(vhost_filename, 'w') as f:
|
||||
f.write(params['hostname'].value)
|
||||
shutil.chown(vhost_filename, dokku_user, dokku_group)
|
||||
else:
|
||||
try:
|
||||
os.remove('{0}/VHOST'.format(dokku_root))
|
||||
os.remove(vhost_filename)
|
||||
except OSError:
|
||||
pass
|
||||
with open('{0}/HOSTNAME'.format(dokku_root), 'w') as f:
|
||||
|
||||
hostname_filename = '{0}/HOSTNAME'.format(dokku_root)
|
||||
|
||||
with open(hostname_filename, 'w') as f:
|
||||
f.write(params['hostname'].value)
|
||||
|
||||
shutil.chown(hostname_filename, dokku_user, dokku_group)
|
||||
|
||||
for (index, key) in enumerate(params['keys'].value.splitlines(), 1):
|
||||
user = 'admin'
|
||||
if self.admin_user_exists() is not None:
|
||||
|
||||
@@ -77,11 +77,11 @@ main() {
|
||||
dokku-log-info "Running system updates"
|
||||
case "$DOKKU_DISTRO" in
|
||||
arch)
|
||||
yaourt -Syyua
|
||||
yay -Syyua
|
||||
;;
|
||||
debian | ubuntu)
|
||||
apt-get update -qq >/dev/null
|
||||
apt-get -qq -y --force-yes dist-upgrade
|
||||
apt-get -qq -y dist-upgrade
|
||||
;;
|
||||
centos | opensuse | rhel)
|
||||
dokku-log-warn "Updating this operating system is not supported"
|
||||
|
||||
@@ -136,7 +136,7 @@ fn-publish-package() {
|
||||
[[ "$RELEASE_TYPE" == "rpm" ]] && DIST=el/7
|
||||
|
||||
if [[ "$DIST" == "ubuntu" ]]; then
|
||||
OS_IDS=("xenial" "bionic")
|
||||
OS_IDS=("xenial" "bionic" "focal")
|
||||
for OS_ID in "${OS_IDS[@]}"; do
|
||||
log-info "(release-dokku) pushing ${RELEASE_TYPE} to packagecloud.com/${REPOSITORY}/${DIST}"
|
||||
package_cloud push "${REPOSITORY}/${DIST}/${OS_ID}" "$PACKAGE_NAME"
|
||||
@@ -239,7 +239,7 @@ fn-repo-update-history-and-commit() {
|
||||
declare desc="Updates the history file and commits the changes"
|
||||
declare CURRENT_VERSION="$1" NEXT_VERSION="$2"
|
||||
local PULL_REQUEST_ID TITLE AUTHOR TYPE CHANGELOG_TEXT
|
||||
local COMMIT_MESSAGE HISTORY HISTORY_CONTENTS HISTORY_DOCUMENTATION HISTORY_ENHANCEMENT HISTORY_BUG HISTORY_OTHER HISTORY_TESTS ISSUE_FILE
|
||||
local COMMIT_MESSAGE HISTORY HISTORY_CONTENTS HISTORY_DOCUMENTATION HISTORY_ENHANCEMENT HISTORY_BC_BREAK HISTORY_REFACTOR HISTORY_BUG HISTORY_OTHER HISTORY_TESTS ISSUE_FILE
|
||||
|
||||
pushd "$ROOT_DIR" >/dev/null
|
||||
|
||||
@@ -256,12 +256,16 @@ fn-repo-update-history-and-commit() {
|
||||
TYPE="$(jq -r '.labels[] | select( .name | contains("type") ) | .name' "$ISSUE_FILE" | cut -d' ' -f2)"
|
||||
CHANGELOG_TEXT="- #${PULL_REQUEST_ID}: @${AUTHOR} ${TITLE}"
|
||||
|
||||
if [[ "$TYPE" == "bug" ]]; then
|
||||
if [[ "$TYPE" == "bc-break" ]]; then
|
||||
HISTORY_BC_BREAK="${HISTORY_BC_BREAK}"$'\n'"$CHANGELOG_TEXT"
|
||||
elif [[ "$TYPE" == "bug" ]]; then
|
||||
HISTORY_BUG="${HISTORY_BUG}"$'\n'"$CHANGELOG_TEXT"
|
||||
elif [[ "$TYPE" == "documentation" ]]; then
|
||||
HISTORY_DOCUMENTATION="${HISTORY_DOCUMENTATION}"$'\n'"$CHANGELOG_TEXT"
|
||||
elif [[ "$TYPE" == "enhancement" ]] || [[ "$TYPE" == "refactor" ]]; then
|
||||
elif [[ "$TYPE" == "enhancement" ]]; then
|
||||
HISTORY_ENHANCEMENT="${HISTORY_ENHANCEMENT}"$'\n'"$CHANGELOG_TEXT"
|
||||
elif [[ "$TYPE" == "refactor" ]]; then
|
||||
HISTORY_REFACTOR="${HISTORY_REFACTOR}"$'\n'"$CHANGELOG_TEXT"
|
||||
elif [[ "$TYPE" == "tests" ]]; then
|
||||
HISTORY_TESTS="${HISTORY_TESTS}"$'\n'"$CHANGELOG_TEXT"
|
||||
else
|
||||
@@ -277,6 +281,11 @@ fn-repo-update-history-and-commit() {
|
||||
HISTORY="${HISTORY}"$'\n'"sudo DOKKU_TAG=v${NEXT_VERSION} bash bootstrap.sh"
|
||||
HISTORY="${HISTORY}"$'\n'"\`\`\`"
|
||||
|
||||
if [[ "$HISTORY_BC_BREAK" ]]; then
|
||||
HISTORY="${HISTORY}"$'\n\n'"### Backwards Compatibility Breaks"
|
||||
HISTORY="${HISTORY}"$'\n'"$HISTORY_BC_BREAK"
|
||||
fi
|
||||
|
||||
if [[ "$HISTORY_BUG" ]]; then
|
||||
HISTORY="${HISTORY}"$'\n\n'"### Bug Fixes"
|
||||
HISTORY="${HISTORY}"$'\n'"$HISTORY_BUG"
|
||||
@@ -287,6 +296,11 @@ fn-repo-update-history-and-commit() {
|
||||
HISTORY="${HISTORY}"$'\n'"$HISTORY_ENHANCEMENT"
|
||||
fi
|
||||
|
||||
if [[ "$HISTORY_REFACTOR" ]]; then
|
||||
HISTORY="${HISTORY}"$'\n\n'"### Refactors"
|
||||
HISTORY="${HISTORY}"$'\n'"$HISTORY_REFACTOR"
|
||||
fi
|
||||
|
||||
if [[ "$HISTORY_DOCUMENTATION" ]]; then
|
||||
HISTORY="${HISTORY}"$'\n\n'"### Documentation"
|
||||
HISTORY="${HISTORY}"$'\n'"$HISTORY_DOCUMENTATION"
|
||||
@@ -364,9 +378,7 @@ main() {
|
||||
fn-extract-package "$IS_RELEASE" "dokku-${NEXT_VERSION}-1.x86_64.rpm" || log-fail "Error extracting rpm package"
|
||||
cp -f "build/dokku_${NEXT_VERSION}_amd64.deb" build/dokku.deb
|
||||
|
||||
if [[ "$RELEASE" == "build" ]]; then
|
||||
fn-build-docker-image "latest" || log-fail "Error building docker image"
|
||||
else
|
||||
if [[ "$RELEASE" != "build" ]]; then
|
||||
fn-publish-package "$IS_RELEASE" "deb" "build/dokku_${NEXT_VERSION}_amd64.deb" || log-fail "Error publishing deb package"
|
||||
fn-publish-package "$IS_RELEASE" "rpm" "build/dokku-${NEXT_VERSION}-1.x86_64.rpm" || log-fail "Error publishing rpm package"
|
||||
fn-build-docker-image "$NEXT_VERSION" || log-fail "Error building docker image"
|
||||
|
||||
@@ -61,7 +61,7 @@ fn-publish-package() {
|
||||
[[ "$RELEASE_TYPE" == "rpm" ]] && DIST=el/7
|
||||
|
||||
if [[ "$DIST" == "ubuntu" ]]; then
|
||||
OS_IDS=("xenial" "bionic")
|
||||
OS_IDS=("xenial" "bionic" "focal")
|
||||
for OS_ID in "${OS_IDS[@]}"; do
|
||||
log-info "(release-dokku-update) pushing ${RELEASE_TYPE} to packagecloud.com/${REPOSITORY}/${DIST}"
|
||||
package_cloud push "${REPOSITORY}/${DIST}/${OS_ID}" "$PACKAGE_NAME"
|
||||
|
||||
@@ -61,7 +61,7 @@ fn-publish-package() {
|
||||
[[ "$RELEASE_TYPE" == "rpm" ]] && DIST=el/7
|
||||
|
||||
if [[ "$DIST" == "ubuntu" ]]; then
|
||||
OS_IDS=("xenial" "bionic")
|
||||
OS_IDS=("xenial" "bionic" "focal")
|
||||
for OS_ID in "${OS_IDS[@]}"; do
|
||||
log-info "(release-herokuish) pushing ${RELEASE_TYPE} to packagecloud.com/${REPOSITORY}/${DIST}"
|
||||
package_cloud push "${REPOSITORY}/${DIST}/${OS_ID}" "$PACKAGE_NAME"
|
||||
|
||||
4
deb.mk
4
deb.mk
@@ -2,7 +2,7 @@ BUILD_DIRECTORY ?= /tmp
|
||||
|
||||
HEROKUISH_DESCRIPTION = 'Herokuish uses Docker and Buildpacks to build applications like Heroku'
|
||||
HEROKUISH_REPO_NAME ?= gliderlabs/herokuish
|
||||
HEROKUISH_VERSION ?= 0.5.11
|
||||
HEROKUISH_VERSION ?= 0.5.14
|
||||
HEROKUISH_ARCHITECTURE = amd64
|
||||
HEROKUISH_PACKAGE_NAME = herokuish_$(HEROKUISH_VERSION)_$(HEROKUISH_ARCHITECTURE).deb
|
||||
|
||||
@@ -80,7 +80,7 @@ deb-herokuish:
|
||||
--version $(HEROKUISH_VERSION) \
|
||||
--architecture $(HEROKUISH_ARCHITECTURE) \
|
||||
--package $(BUILD_DIRECTORY)/$(HEROKUISH_PACKAGE_NAME) \
|
||||
--deb-pre-depends 'docker-engine-cs (>= 1.9.1) | docker-engine (>= 1.9.1) | docker-ce | docker-ee' \
|
||||
--deb-pre-depends 'docker-engine-cs (>= 1.13.0) | docker-engine (>= 1.13.0) | docker-io (>= 1.13.0) | docker.io (>= 1.13.0) | docker-ce (>= 1.13.0) | docker-ee (>= 1.13.0) | moby-engine' \
|
||||
--deb-pre-depends sudo \
|
||||
--after-install /tmp/tmp/post-install \
|
||||
--url "https://github.com/$(HEROKUISH_REPO_NAME)" \
|
||||
|
||||
6
debian/control
vendored
6
debian/control
vendored
@@ -1,11 +1,11 @@
|
||||
Package: dokku
|
||||
Version: 0.20.3
|
||||
Version: 0.21.2
|
||||
Section: web
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
Depends: locales, git, cpio, curl, man-db, netcat, sshcommand (>= 0.10.0), gliderlabs-sigil, docker-engine-cs (>= 1.13.0) | docker-engine (>= 1.13.0) | docker-io (>= 1.13.0) | docker.io (>= 1.13.0) | docker-ce (>= 1.13.0) | docker-ee (>= 1.13.0), net-tools, software-properties-common, procfile-util, python-software-properties | python3-software-properties, rsyslog, dos2unix, jq
|
||||
Depends: locales, git, cpio, curl, man-db, netcat, sshcommand (>= 0.10.0), docker-engine-cs (>= 1.13.0) | docker-engine (>= 1.13.0) | docker-io (>= 1.13.0) | docker.io (>= 1.13.0) | docker-ce (>= 1.13.0) | docker-ee (>= 1.13.0) | moby-engine, net-tools, software-properties-common, procfile-util, python-software-properties | python3-software-properties, rsyslog, dos2unix, jq
|
||||
Recommends: herokuish (>= 0.3.4), parallel, dokku-update, dokku-event-listener
|
||||
Pre-Depends: nginx (>= 1.8.0) | openresty, dnsutils, cgroupfs-mount | cgroup-lite, plugn (>= 0.3.0), sudo, python3, debconf
|
||||
Pre-Depends: gliderlabs-sigil, nginx (>= 1.8.0) | openresty, dnsutils, cgroupfs-mount | cgroup-lite, plugn (>= 0.3.0), sudo, python3, debconf
|
||||
Maintainer: Jose Diaz-Gonzalez <dokku@josediazgonzalez.com>
|
||||
Description: Docker-powered PaaS that helps build and manage the lifecycle of applications
|
||||
Dokku is an extensible, open source Platform as a Service
|
||||
|
||||
2
debian/postrm
vendored
2
debian/postrm
vendored
@@ -32,7 +32,7 @@ main() {
|
||||
rm -f /usr/local/openresty/nginx/conf/conf.d/dokku-installer.conf
|
||||
rm -f /etc/nginx/conf.d/dokku.conf
|
||||
rm -f /etc/nginx/conf.d/dokku-installer.conf
|
||||
rm -f ${DOKKU_ROOT}/.dokkurc ${DOKKU_ROOT}/dokkurc ${DOKKU_ROOT}/tls
|
||||
rm -rf ${DOKKU_ROOT}/.dokkurc ${DOKKU_ROOT}/dokkurc ${DOKKU_ROOT}/tls
|
||||
rm -f ${DOKKU_ROOT}/.ssh/authorized_keys ${DOKKU_ROOT}/.sshcommand
|
||||
rm -f ${DOKKU_ROOT}/ENV ${DOKKU_ROOT}/HOSTNAME ${DOKKU_ROOT}/VERSION
|
||||
rm -rf ${DOKKU_ROOT}/.cache
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/var/log/services/* {
|
||||
/var/log/services/*[!0-9z] {
|
||||
daily
|
||||
missingok
|
||||
rotate 7
|
||||
|
||||
@@ -26,8 +26,7 @@ dokku postgres:import [db_name] < [db_name].dump
|
||||
|
||||
Dokku doesn't enforce a [300mb](https://devcenter.heroku.com/articles/slug-compiler#slug-size) limit on apps, but it's best practice to keep binary assets outside of git. Since containers are considered volatile in Dokku, external stores like s3 or storage mounts should be used for non-volatile items like user uploads. The Dokku storage core plugin can be used to mount local directories / volumes inside the docker container.
|
||||
|
||||
See the [persistent storage documentation](/docs/advanced-usage/persistent-storage.md) for more details.
|
||||
|
||||
See the [persistent storage documentation](/docs/advanced-usage/persistent-storage.md) for more information on how to attach persistent storage to your application.
|
||||
|
||||
## Disaster Recovery
|
||||
|
||||
|
||||
@@ -33,35 +33,35 @@ dokku plugin:list
|
||||
|
||||
```
|
||||
plugn: dev
|
||||
00_dokku-standard 0.20.3 enabled dokku core standard plugin
|
||||
20_events 0.20.3 enabled dokku core events logging plugin
|
||||
app-json 0.20.3 enabled dokku core app-json plugin
|
||||
apps 0.20.3 enabled dokku core apps plugin
|
||||
build-env 0.20.3 enabled dokku core build-env plugin
|
||||
buildpacks 0.20.3 enabled dokku core buildpacks plugin
|
||||
certs 0.20.3 enabled dokku core certificate management plugin
|
||||
checks 0.20.3 enabled dokku core checks plugin
|
||||
common 0.20.3 enabled dokku core common plugin
|
||||
config 0.20.3 enabled dokku core config plugin
|
||||
docker-options 0.20.3 enabled dokku core docker-options plugin
|
||||
domains 0.20.3 enabled dokku core domains plugin
|
||||
enter 0.20.3 enabled dokku core enter plugin
|
||||
git 0.20.3 enabled dokku core git plugin
|
||||
logs 0.20.3 enabled dokku core logs plugin
|
||||
network 0.20.3 enabled dokku core network plugin
|
||||
nginx-vhosts 0.20.3 enabled dokku core nginx-vhosts plugin
|
||||
plugin 0.20.3 enabled dokku core plugin plugin
|
||||
proxy 0.20.3 enabled dokku core proxy plugin
|
||||
ps 0.20.3 enabled dokku core ps plugin
|
||||
repo 0.20.3 enabled dokku core repo plugin
|
||||
resource 0.20.3 enabled dokku core resource plugin
|
||||
scheduler-docker-local 0.20.3 enabled dokku core scheduler-docker-local plugin
|
||||
shell 0.20.3 enabled dokku core shell plugin
|
||||
ssh-keys 0.20.3 enabled dokku core ssh-keys plugin
|
||||
storage 0.20.3 enabled dokku core storage plugin
|
||||
tags 0.20.3 enabled dokku core tags plugin
|
||||
tar 0.20.3 enabled dokku core tar plugin
|
||||
trace 0.20.3 enabled dokku core trace plugin
|
||||
00_dokku-standard 0.21.2 enabled dokku core standard plugin
|
||||
20_events 0.21.2 enabled dokku core events logging plugin
|
||||
app-json 0.21.2 enabled dokku core app-json plugin
|
||||
apps 0.21.2 enabled dokku core apps plugin
|
||||
build-env 0.21.2 enabled dokku core build-env plugin
|
||||
buildpacks 0.21.2 enabled dokku core buildpacks plugin
|
||||
certs 0.21.2 enabled dokku core certificate management plugin
|
||||
checks 0.21.2 enabled dokku core checks plugin
|
||||
common 0.21.2 enabled dokku core common plugin
|
||||
config 0.21.2 enabled dokku core config plugin
|
||||
docker-options 0.21.2 enabled dokku core docker-options plugin
|
||||
domains 0.21.2 enabled dokku core domains plugin
|
||||
enter 0.21.2 enabled dokku core enter plugin
|
||||
git 0.21.2 enabled dokku core git plugin
|
||||
logs 0.21.2 enabled dokku core logs plugin
|
||||
network 0.21.2 enabled dokku core network plugin
|
||||
nginx-vhosts 0.21.2 enabled dokku core nginx-vhosts plugin
|
||||
plugin 0.21.2 enabled dokku core plugin plugin
|
||||
proxy 0.21.2 enabled dokku core proxy plugin
|
||||
ps 0.21.2 enabled dokku core ps plugin
|
||||
repo 0.21.2 enabled dokku core repo plugin
|
||||
resource 0.21.2 enabled dokku core resource plugin
|
||||
scheduler-docker-local 0.21.2 enabled dokku core scheduler-docker-local plugin
|
||||
shell 0.21.2 enabled dokku core shell plugin
|
||||
ssh-keys 0.21.2 enabled dokku core ssh-keys plugin
|
||||
storage 0.21.2 enabled dokku core storage plugin
|
||||
tags 0.21.2 enabled dokku core tags plugin
|
||||
tar 0.21.2 enabled dokku core tar plugin
|
||||
trace 0.21.2 enabled dokku core trace plugin
|
||||
```
|
||||
|
||||
You can check if a plugin has been installed via the `plugin:installed` command:
|
||||
|
||||
@@ -26,6 +26,7 @@ Valid resource options include:
|
||||
- `--network`
|
||||
- `--network-ingress`
|
||||
- `--network-egress`
|
||||
- `--nvidia-gpu`
|
||||
|
||||
See the [Supported Resource Management Properties](/docs/advanced-usage/schedulers/docker-local.md#supported-resource-management-properties) section of the docker local scheduler documentation for more information on how each resource limit maps to Docker.
|
||||
|
||||
@@ -86,6 +87,7 @@ dokku resource:limit node-js-app
|
||||
network: 100
|
||||
network-ingress:
|
||||
network-egress:
|
||||
nvidia-gpu:
|
||||
```
|
||||
|
||||
This may also be combined with the `--process-type` flag to see app limits on a process-type level. Note that the displayed values are not merged with the defaults.
|
||||
@@ -103,6 +105,7 @@ dokku resource:limit --process-type web node-js-app
|
||||
network:
|
||||
network-ingress:
|
||||
network-egress:
|
||||
nvidia-gpu:
|
||||
```
|
||||
|
||||
#### Clearing Resource Limits
|
||||
@@ -182,6 +185,7 @@ dokku resource:reserve node-js-app
|
||||
network:
|
||||
network-ingress:
|
||||
network-egress:
|
||||
nvidia-gpu:
|
||||
```
|
||||
|
||||
This may also be combined with the `--process-type` flag to see app reservations on a process-type level. Note that the displayed values are not merged with the defaults.
|
||||
@@ -198,6 +202,7 @@ dokku resource:reserve --process-type web node-js-app
|
||||
network:
|
||||
network-ingress:
|
||||
network-egress:
|
||||
nvidia-gpu:
|
||||
```
|
||||
|
||||
#### Clearing Resource Reservations
|
||||
@@ -238,12 +243,14 @@ dokku resource:report
|
||||
web limit network: 10
|
||||
web limit network ingress:
|
||||
web limit network egress:
|
||||
web limit nvidia gpu:
|
||||
web reservation cpu:
|
||||
web reservation memory: 512
|
||||
web reservation memory swap:
|
||||
web reservation network: 8
|
||||
web reservation network ingress:
|
||||
web reservation network egress:
|
||||
web reservation nvidia gpu:
|
||||
=====> python-sample resource information
|
||||
web limit cpu:
|
||||
web limit memory:
|
||||
@@ -251,12 +258,14 @@ dokku resource:report
|
||||
web limit network:
|
||||
web limit network ingress:
|
||||
web limit network egress:
|
||||
web limit nvidia gpu:
|
||||
web reservation cpu:
|
||||
web reservation memory:
|
||||
web reservation memory swap:
|
||||
web reservation network:
|
||||
web reservation network ingress:
|
||||
web reservation network egress:
|
||||
web reservation nvidia gpu:
|
||||
=====> ruby-sample resource information
|
||||
web limit cpu:
|
||||
web limit memory:
|
||||
@@ -264,12 +273,14 @@ dokku resource:report
|
||||
web limit network:
|
||||
web limit network ingress:
|
||||
web limit network egress:
|
||||
web limit nvidia gpu:
|
||||
web reservation cpu:
|
||||
web reservation memory:
|
||||
web reservation memory swap:
|
||||
web reservation network:
|
||||
web reservation network ingress:
|
||||
web reservation network egress:
|
||||
web reservation nvidia gpu:
|
||||
```
|
||||
|
||||
You can run the command for a specific app also.
|
||||
@@ -286,12 +297,14 @@ dokku resource:report node-js-app
|
||||
web limit network: 10
|
||||
web limit network ingress:
|
||||
web limit network egress:
|
||||
web limit nvidia gpu:
|
||||
web reservation cpu:
|
||||
web reservation memory: 512
|
||||
web reservation memory swap:
|
||||
web reservation network: 8
|
||||
web reservation network ingress:
|
||||
web reservation network egress:
|
||||
web reservation nvidia gpu:
|
||||
```
|
||||
|
||||
You can pass flags which will output only the value of the specific information you want. For example:
|
||||
|
||||
10
docs/advanced-usage/schedulers/alternate-schedulers.md
Normal file
10
docs/advanced-usage/schedulers/alternate-schedulers.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Alternative Schedulers
|
||||
|
||||
In addition to the built-in [docker-local scheduler](/docs/advanced-usage/schedulers/docker-local.md), Dokku also supports two scheduler plugins:
|
||||
|
||||
- [Kubernetes](https://github.com/dokku/dokku-scheduler-kubernetes)
|
||||
- [Nomad](https://github.com/dokku/dokku-scheduler-nomad)
|
||||
|
||||
These scheduler implementations may not be complete, though provide enough functionality for a user to get an app deployed via the underlying scheduler.
|
||||
|
||||
For users that require additional functionality, please refer to the [Sponsoring Documentation](https://github.com/dokku/.github/blob/master/SPONSORING.md).
|
||||
@@ -44,15 +44,18 @@ This plugin implements various functionality through `plugn` triggers to integra
|
||||
- `check-deploy`
|
||||
- `core-post-deploy`
|
||||
- `post-app-clone-setup`
|
||||
- `post-app-rename-setup`
|
||||
- `post-create`
|
||||
- `post-delete`
|
||||
- `pre-deploy`
|
||||
- `pre-restore`
|
||||
- `scheduler-app-status`
|
||||
- `scheduler-deploy`
|
||||
- `scheduler-docker-cleanup`
|
||||
- `scheduler-inspect`
|
||||
- `scheduler-logs-failed`
|
||||
- `scheduler-is-deployed`
|
||||
- `scheduler-logs`
|
||||
- `scheduler-logs-failed`
|
||||
- `scheduler-retire`
|
||||
- `scheduler-run`
|
||||
- `scheduler-stop`
|
||||
@@ -65,14 +68,16 @@ The `docker-local` scheduler supports a minimal list of resource _limits_ and _r
|
||||
|
||||
### Resource Limits
|
||||
|
||||
- cpu: (docker option: `--cpus`), and is specified in number of CPUs a process can access.
|
||||
- cpu: (docker option: `--cpus`), is specified in number of CPUs a process can access.
|
||||
- See the ["CPU" section](https://docs.docker.com/config/containers/resource_constraints/#cpu) of the Docker Runtime Options documentation for more information.
|
||||
- memory: (docker option: `--memory`) and should be specified with a suffix of `b` (bytes), `k` (kilobytes), `m` (megabytes), `g` (gigabytes).
|
||||
- memory: (docker option: `--memory`) should be specified with a suffix of `b` (bytes), `k` (kilobytes), `m` (megabytes), `g` (gigabytes).
|
||||
- See the ["Memory" section](https://docs.docker.com/config/containers/resource_constraints/#memory) of the Docker Runtime Options documentation for more information.
|
||||
- memory-swap: (docker option: `--memory-swap`) and should be specified with a suffix of `b` (bytes), `k` (kilobytes), `m` (megabytes), `g` (gigabytes)
|
||||
- memory-swap: (docker option: `--memory-swap`) should be specified with a suffix of `b` (bytes), `k` (kilobytes), `m` (megabytes), `g` (gigabytes)
|
||||
- See the ["Memory" section](https://docs.docker.com/config/containers/resource_constraints/#memory) of the Docker Runtime Options documentation for more information.
|
||||
- nvidia-gpus: (docker option: `--gpus`), is specified in number of Nvidia GPUs a process can access.
|
||||
- See the ["GPU" section](https://docs.docker.com/config/containers/resource_constraints/#gpu) of the Docker Runtime Options documentation for more information.
|
||||
|
||||
### Resource Reservations
|
||||
|
||||
- memory: (docker option: `--memory-reservation`) and should be specified with a suffix of `b` (bytes), `k` (kilobytes), `m` (megabytes), `g` (gigabytes)
|
||||
- memory: (docker option: `--memory-reservation`) should be specified with a suffix of `b` (bytes), `k` (kilobytes), `m` (megabytes), `g` (gigabytes)
|
||||
- See the ["Memory" section](https://docs.docker.com/config/containers/resource_constraints/#memory) of the Docker Runtime Options documentation for more information.
|
||||
|
||||
@@ -28,6 +28,11 @@ The refactor of the proxy plugin removes the following functions from being sour
|
||||
|
||||
The informal policy is to allow removal of functions within a `functions` file if they are not used in OSS plugins. Should you be affected by any such removals, please file an issue to expose the functionality via a plugin trigger.
|
||||
|
||||
### Function renames
|
||||
|
||||
- `tar#tar_in_cmd` was renamed to `tar#cmd-tar-in`. Users should avoid using `cmd-*` commands directly, and instead file an issue to have them exposed via a plugin trigger.
|
||||
- `tar#tar_from_cmd` was renamed to `tar#cmd-tar-from`. Users should avoid using `cmd-*` commands directly, and instead file an issue to have them exposed via a plugin trigger.
|
||||
|
||||
### Remove support for Unsupported Operating Systems
|
||||
|
||||
Dokku will no longer distribute packages for Ubuntu versions that have reached either End of Life or End of Standard Support (for LTS releases). This currently includes the following releases:
|
||||
|
||||
18
docs/appendices/0.21.0-migration-guide.md
Normal file
18
docs/appendices/0.21.0-migration-guide.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# 0.21.0 Migration Guide
|
||||
|
||||
## Changes
|
||||
|
||||
The `tls` name is no longer a reserved app name, and can be used by applications. This was previously a reserved app name due to it's use as a place for global SSL certificate files; Dokku has not supported global SSL certificates for many releases, and thus there is no need to reserve the name.
|
||||
|
||||
## Deprecations
|
||||
|
||||
- `git#git_deploy_branch()` is deprecated in favor of `plugn trigger git-deploy-branch`.
|
||||
- The `config` command is deprecated in favor of `config:show`.
|
||||
- Usage of this command in conjunction with either the `--export` or `--shell` flag is deprecated in favor of `config:export --format` with the correct format value (`exports` or `shell`, respectively).
|
||||
- The `nginx:build-config` command is deprecated in favor of `proxy:build-config`.
|
||||
|
||||
## Removals
|
||||
|
||||
The `apps:destroy` command no longer takes a second argument `force`. Instead, this can be passed as the `--force` flag, either globally or as a flag to the command itself.
|
||||
|
||||
The `proxy:enable` and `proxy:disable` no longer restart apps when setting the `DOKKU_DISABLE_PROXY` environment variable. A future release will disable usage of `DOKKU_DISABLE_PROXY` altogether.
|
||||
3006
docs/assets/dokku.ai
Normal file
3006
docs/assets/dokku.ai
Normal file
File diff suppressed because one or more lines are too long
@@ -2,10 +2,10 @@
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square70x70logo src="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/mstile-70x70.png"/>
|
||||
<square150x150logo src="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/mstile-150x150.png"/>
|
||||
<square310x310logo src="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/mstile-310x310.png"/>
|
||||
<wide310x150logo src="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/mstile-310x150.png"/>
|
||||
<square70x70logo src="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/mstile-70x70.png"/>
|
||||
<square150x150logo src="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/mstile-150x150.png"/>
|
||||
<square310x310logo src="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/mstile-310x310.png"/>
|
||||
<wide310x150logo src="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/mstile-310x150.png"/>
|
||||
<TileColor>#da532c</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
|
||||
@@ -2,37 +2,37 @@
|
||||
"name": "Dokku",
|
||||
"icons": [
|
||||
{
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.20.3\/docs\/assets\/favicons\/android-chrome-36x36.png",
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.21.2\/docs\/assets\/favicons\/android-chrome-36x36.png",
|
||||
"sizes": "36x36",
|
||||
"type": "image\/png",
|
||||
"density": "0.75"
|
||||
},
|
||||
{
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.20.3\/docs\/assets\/favicons\/android-chrome-48x48.png",
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.21.2\/docs\/assets\/favicons\/android-chrome-48x48.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image\/png",
|
||||
"density": "1.0"
|
||||
},
|
||||
{
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.20.3\/docs\/assets\/favicons\/android-chrome-72x72.png",
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.21.2\/docs\/assets\/favicons\/android-chrome-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image\/png",
|
||||
"density": "1.5"
|
||||
},
|
||||
{
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.20.3\/docs\/assets\/favicons\/android-chrome-96x96.png",
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.21.2\/docs\/assets\/favicons\/android-chrome-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image\/png",
|
||||
"density": "2.0"
|
||||
},
|
||||
{
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.20.3\/docs\/assets\/favicons\/android-chrome-144x144.png",
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.21.2\/docs\/assets\/favicons\/android-chrome-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image\/png",
|
||||
"density": "3.0"
|
||||
},
|
||||
{
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.20.3\/docs\/assets\/favicons\/android-chrome-192x192.png",
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.21.2\/docs\/assets\/favicons\/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image\/png",
|
||||
"density": "4.0"
|
||||
|
||||
@@ -39,13 +39,13 @@ h1 {
|
||||
font-size: 1.6em;
|
||||
}
|
||||
.header .navbar-brand a {
|
||||
background-image: url(https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/dokku.png);
|
||||
background-image: url(https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/dokku.png);
|
||||
text-indent: 40px;
|
||||
}
|
||||
.blurb {
|
||||
color: #424242;
|
||||
background-color: #ededed;
|
||||
background-image: url(https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/gplaypattern.png);
|
||||
background-image: url(https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/gplaypattern.png);
|
||||
padding: 45px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"0.17.9",
|
||||
"0.18.5",
|
||||
"0.19.13",
|
||||
"0.20.3"
|
||||
"0.20.4",
|
||||
"0.21.2"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -18,9 +18,9 @@ Let's take a quick look at the current Dokku nginx plugin that's shipped with Do
|
||||
|
||||
[See the full documentation](/docs/development/plugin-creation.md).
|
||||
|
||||
## Official Plugins (Beta)
|
||||
## Official Plugins
|
||||
|
||||
The following plugins are available and provided by Dokku maintainers. Where noted, these plugins should be considered beta software and may not have been used as thoroughly as community plugins. Please file issues against their respective issue trackers.
|
||||
The following plugins are available and provided by Dokku maintainers. Please file issues against their respective issue trackers.
|
||||
|
||||
| Plugin | Author | Compatibility |
|
||||
| ------------------------------------------------------------------------------------------------- | --------------------- | --------------------- |
|
||||
@@ -41,6 +41,7 @@ The following plugins are available and provided by Dokku maintainers. Where not
|
||||
| [Let's Encrypt (beta)](https://github.com/dokku/dokku-letsencrypt) | [dokku][] | 0.4.0+ |
|
||||
| [Maintenance mode (beta)](https://github.com/dokku/dokku-maintenance) | [dokku][] | 0.4.0+ |
|
||||
| [Redirect (beta)](https://github.com/dokku/dokku-redirect) | [dokku][] | 0.4.0+ |
|
||||
| [Registry](https://github.com/dokku/dokku-registry) | [dokku][] | 0.12.0+
|
||||
|
||||
## Community plugins
|
||||
|
||||
@@ -182,9 +183,8 @@ The following plugins are available and provided by Dokku maintainers. Where not
|
||||
| [Docker Direct](https://github.com/josegonzalez/dokku-docker-direct) | [josegonzalez][] | 0.4.0+ |
|
||||
| [Dokku Clone](https://github.com/crisward/dokku-clone) | [crisward][] | 0.4.0+ |
|
||||
| [Dokku Copy App Config Files](https://github.com/josegonzalez/dokku-supply-config) | [josegonzalez][] | 0.4.0+ |
|
||||
| [Dockerfile custom path](https://github.com/mimischi/dokku-dockerfile) | [mimischi][] | 0.8.0+ |
|
||||
| [Dokku Registry](https://github.com/agco-adm/dokku-registry)<sup>1</sup> | [agco-adm][] | 0.4.0+ |
|
||||
| [Dokku Require](https://github.com/crisward/dokku-require)<sup>2</sup> | [crisward][] | 0.4.0+ |
|
||||
| [Dockerfile custom path](https://github.com/mimischi/dokku-dockerfile) | [mimischi][] | 0.8.0+ |
|
||||
| [Dokku Require](https://github.com/crisward/dokku-require)<sup>1</sup> | [crisward][] | 0.4.0+ |
|
||||
| [Global Certificates](https://github.com/josegonzalez/dokku-global-cert) | [josegonzalez][] | 0.5.0+ |
|
||||
| [Graduate (Environment Management)](https://github.com/glassechidna/dokku-graduate) | [Benjamin-Dobell][] | 0.4.0+ |
|
||||
| [Haproxy tcp load balancer](https://github.com/256dpi/dokku-haproxy) | [256dpi][] | 0.4.0+ |
|
||||
@@ -195,20 +195,18 @@ The following plugins are available and provided by Dokku maintainers. Where not
|
||||
| [Open App Ports](https://github.com/josegonzalez/dokku-ports) | [josegonzalez][] | 0.3.x |
|
||||
| [Proctype Filter](https://github.com/michaelshobbs/dokku-proctype-filter) | [michaelshobbs][] | 0.4.0+ |
|
||||
| [robots.txt](https://notabug.org/candlewaster/dokku-robots.txt) | [candlewaster][] | 0.4.x |
|
||||
| [SSH Deployment Keys](https://github.com/cedricziel/dokku-deployment-keys)<sup>3</sup> | [cedricziel][] | 0.4.0+ |
|
||||
| [SSH Hostkeys](https://github.com/cedricziel/dokku-hostkeys-plugin)<sup>4</sup> | [cedricziel][] | 0.3.x |
|
||||
| [SSH Deployment Keys](https://github.com/cedricziel/dokku-deployment-keys)<sup>2</sup> | [cedricziel][] | 0.4.0+ |
|
||||
| [SSH Hostkeys](https://github.com/cedricziel/dokku-hostkeys-plugin)<sup>3</sup> | [cedricziel][] | 0.3.x |
|
||||
| [Application build hook](https://github.com/fteychene/dokku-build-hook) | [fteychene][] | 0.4.0+ |
|
||||
| [Post Deploy Script](https://github.com/baikunz/dokku-post-deploy-script) | [baikunz][] | 0.4.0+ |
|
||||
|
||||
[217d00a]: https://github.com/dokku/dokku/commit/217d00a1bc47a7e24d8847617bb08a1633025fc7
|
||||
|
||||
<sup>1</sup> On Heroku similar functionality is offered by the [heroku-labs pipeline feature](https://devcenter.heroku.com/articles/labs-pipelines), which allows you to promote builds across multiple environments (staging -> production)
|
||||
<sup>1</sup> Extends app.json support to include creating volumes and creating / linking databases on push
|
||||
|
||||
<sup>2</sup> Extends app.json support to include creating volumes and creating / linking databases on push
|
||||
<sup>2</sup> Adds the possibility to add SSH deployment keys to receive private hosted packages
|
||||
|
||||
<sup>3</sup> Adds the possibility to add SSH deployment keys to receive private hosted packages
|
||||
|
||||
<sup>4</sup> Adds the ability to add custom hosts to the containers known_hosts file to be able to ssh them easily (useful with deployment keys)
|
||||
<sup>3</sup> Adds the ability to add custom hosts to the containers known_hosts file to be able to ssh them easily (useful with deployment keys)
|
||||
|
||||
### Other Plugins
|
||||
|
||||
@@ -300,6 +298,9 @@ The following plugins are no longer maintained by their developers.
|
||||
| [CouchDB (multi containers)](https://github.com/Flink/dokku-couchdb-multi-containers) | [Flink][] | 0.4.0+ |
|
||||
| [CouchDB](https://github.com/racehub/dokku-couchdb-plugin) | [RaceHub][] | Compatible with 0.2.0 |
|
||||
| [Dokku Copy App Config Files](https://github.com/alexkruegger/dokku-app-configfiles) | [alexkruegger][] | Compatible with 0.3.17+ |
|
||||
|
|
||||
| [Dokku Registry](https://github.com/agco-adm/dokku-registry) | [agco-adm][] | 0.4.0+
|
||||
|
|
||||
| [Elasticsearch](https://github.com/robv/dokku-elasticsearch) | [robv][] | Not compatible with >= 0.3.0 (still uses /home/git) |
|
||||
| [Elasticsearch](https://github.com/blag/dokku-elasticsearch-plugin)<sup>1</sup> | [blag][] | Compatible with 0.2.0 |
|
||||
| [Graphite/statsd](https://github.com/jlachowski/dokku-graphite-plugin) | [jlachowski][] | < 0.4.0 |
|
||||
|
||||
@@ -115,44 +115,4 @@ dokku domains:report node-js-app --domains-app-enabled
|
||||
|
||||
## Default site
|
||||
|
||||
By default, Dokku will route any received request with an unknown HOST header value to the lexicographically first site in the nginx config stack. If this is not the desired behavior, you may want to add the following configuration to the global nginx configuration.
|
||||
|
||||
Create the file at `/etc/nginx/conf.d/00-default-vhost.conf`:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
|
||||
server_name _;
|
||||
access_log off;
|
||||
return 410;
|
||||
}
|
||||
|
||||
# To handle HTTPS requests, you can uncomment the following section.
|
||||
#
|
||||
# Please note that in order to let this work as expected, you need a valid
|
||||
# SSL certificate for any domains being served. Browsers will show SSL
|
||||
# errors in all other cases.
|
||||
#
|
||||
# Note that the key and certificate files in the below example need to
|
||||
# be copied into /etc/nginx/ssl/ folder.
|
||||
#
|
||||
# server {
|
||||
# listen 443 ssl;
|
||||
# listen [::]:443 ssl;
|
||||
# server_name _;
|
||||
# ssl_certificate /etc/nginx/ssl/cert.crt;
|
||||
# ssl_certificate_key /etc/nginx/ssl/cert.key;
|
||||
# access_log off;
|
||||
# return 410;
|
||||
# }
|
||||
```
|
||||
|
||||
Make sure to reload nginx after creating this file by running `service nginx reload`.
|
||||
|
||||
This will catch all unknown HOST header values and return a `410 Gone` response. You can replace the `return 410;` with `return 444;` which will cause nginx to not respond to requests that do not match known domains (connection refused).
|
||||
|
||||
The configuration file must be loaded before `/etc/nginx/conf.d/dokku.conf`, so it can not be arranged as a vhost in `/etc/nginx/sites-enabled` that is only processed afterwards.
|
||||
|
||||
Alternatively, you may push an app to your Dokku host with a name like "00-default". As long as it lists first in `ls /home/dokku/*/nginx.conf | head`, it will be used as the default nginx vhost.
|
||||
This is specific to your proxy plugin of choice. See the [nginx documentation](/docs/configuration/nginx.md#default-site) for more information on how to configure this for the default nginx proxy implementation.
|
||||
|
||||
@@ -71,7 +71,7 @@ dokku config:export --format shell node-js-app
|
||||
|
||||
## Special Config Variables
|
||||
|
||||
The following list config variables have special meaning and can be set in a variety of ways.
|
||||
The following config variables have special meanings and can be set in a variety of ways.
|
||||
|
||||
> Warning: This list is not exhaustive, and may vary from version to version.
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ Dokku uses nginx as its server for routing requests to specific applications. By
|
||||
|
||||
```
|
||||
nginx:access-logs <app> [-t] # Show the nginx access logs for an application (-t follows)
|
||||
nginx:build-config <app> # (Re)builds nginx config for given app
|
||||
nginx:error-logs <app> [-t] # Show the nginx error logs for an application (-t follows)
|
||||
nginx:report [<app>] [<flag>] # Displays a nginx report for one or more apps
|
||||
nginx:set <app> <property> (<value>) # Set or clear an nginx property for an app
|
||||
@@ -107,14 +106,26 @@ dokku nginx:set node-js-app error-log-path
|
||||
|
||||
In all cases, the nginx config must be regenerated after setting the above values.
|
||||
|
||||
## Regenerating nginx config
|
||||
## Specifying a read timeout
|
||||
|
||||
In certain cases, your app nginx configs may drift from the correct config for your app. You may regenerate the config at any point via the `nginx:build-config` command. This may fail if there are no current web listeners for your app.
|
||||
> New as of 0.21.0
|
||||
|
||||
When proxying requests to your applications, it may be useful to specify a proxy read timeout. This can be done via the `nginx:set` command as follows:
|
||||
|
||||
```shell
|
||||
dokku nginx:build-config node-js-app
|
||||
dokku nginx:set node-js-app proxy-read-timeout 120s
|
||||
```
|
||||
|
||||
The default value is `60s`, and all numeric values _must_ have a trailing time value specified (`s` for seconds, `m` for minutes).
|
||||
|
||||
The default value may be set by passing an empty value for the option:
|
||||
|
||||
```shell
|
||||
dokku nginx:set node-js-app proxy-read-timeout
|
||||
```
|
||||
|
||||
In all cases, the nginx config must be regenerated after setting the above value.
|
||||
|
||||
## Showing the nginx config
|
||||
|
||||
For debugging purposes, it may be useful to show the nginx config. This can be achieved via the `nginx:show-config` command.
|
||||
@@ -225,34 +236,78 @@ By default, Dokku provides custom error pages for the following three categories
|
||||
|
||||
These are provided as an alternative to the generic Nginx error page, are shared for _all_ applications, and their contents are located on disk at `/var/lib/dokku/data/nginx-vhosts/dokku-errors`. To customize them for a specific app, create a custom `nginx.conf.sigil` as described above and change the paths to point elsewhere.
|
||||
|
||||
## Default site
|
||||
|
||||
By default, Dokku will route any received request with an unknown HOST header value to the lexicographically first site in the nginx config stack. If this is not the desired behavior, you may want to add the following configuration to the global nginx configuration.
|
||||
|
||||
Create the file at `/etc/nginx/conf.d/00-default-vhost.conf`:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
|
||||
server_name _;
|
||||
access_log off;
|
||||
return 410;
|
||||
}
|
||||
|
||||
# To handle HTTPS requests, you can uncomment the following section.
|
||||
#
|
||||
# Please note that in order to let this work as expected, you need a valid
|
||||
# SSL certificate for any domains being served. Browsers will show SSL
|
||||
# errors in all other cases.
|
||||
#
|
||||
# Note that the key and certificate files in the below example need to
|
||||
# be copied into /etc/nginx/ssl/ folder.
|
||||
#
|
||||
# server {
|
||||
# listen 443 ssl;
|
||||
# listen [::]:443 ssl;
|
||||
# server_name _;
|
||||
# ssl_certificate /etc/nginx/ssl/cert.crt;
|
||||
# ssl_certificate_key /etc/nginx/ssl/cert.key;
|
||||
# access_log off;
|
||||
# return 410;
|
||||
# }
|
||||
```
|
||||
|
||||
Make sure to reload nginx after creating this file by running `service nginx reload`.
|
||||
|
||||
This will catch all unknown HOST header values and return a `410 Gone` response. You can replace the `return 410;` with `return 444;` which will cause nginx to not respond to requests that do not match known domains (connection refused).
|
||||
|
||||
The configuration file must be loaded before `/etc/nginx/conf.d/dokku.conf`, so it can not be arranged as a vhost in `/etc/nginx/sites-enabled` that is only processed afterwards.
|
||||
|
||||
Alternatively, you may push an app to your Dokku host with a name like "00-default". As long as it lists first in `ls /home/dokku/*/nginx.conf | head`, it will be used as the default nginx vhost.
|
||||
|
||||
## Domains plugin
|
||||
|
||||
See the [domain configuration documentation](/docs/configuration/domains.md).
|
||||
See the [domain configuration documentation](/docs/configuration/domains.md) for more information on how to configure domains for your app.
|
||||
|
||||
## Customizing hostnames
|
||||
|
||||
See the [customizing hostnames documentation](/docs/configuration/domains.md#customizing-hostnames).
|
||||
See the [customizing hostnames documentation](/docs/configuration/domains.md#customizing-hostnames) for more information on how to configure domains for your app.
|
||||
|
||||
## Disabling VHOSTS
|
||||
|
||||
See the [disabling vhosts documentation](/docs/configuration/domains.md#disabling-vhosts).
|
||||
|
||||
## Default site
|
||||
|
||||
See the [default site documentation](/docs/configuration/domains.md#default-site).
|
||||
See the [disabling vhosts documentation](/docs/configuration/domains.md#disabling-vhosts) for more information on how to disable domain usage for your app.
|
||||
|
||||
## Running behind a load balancer
|
||||
|
||||
See the [load balancer documentation](/docs/configuration/ssl.md#running-behind-a-load-balancer).
|
||||
See the [load balancer documentation](/docs/configuration/ssl.md#running-behind-a-load-balancer) for more information on how to configure your nginx config for running behind a network load balancer.
|
||||
|
||||
## SSL Configuration
|
||||
|
||||
See the [ssl documentation](/docs/configuration/ssl.md).
|
||||
See the [ssl documentation](/docs/configuration/ssl.md) for more information on how to configure SSL certificates for your application.
|
||||
|
||||
## Disabling Nginx
|
||||
|
||||
See the [proxy documentation](/docs/advanced-usage/proxy-management.md).
|
||||
See the [proxy documentation](/docs/advanced-usage/proxy-management.md) for more information on how to disable nginx as the proxy implementation for your app.
|
||||
|
||||
## Managing Proxy Port mappings
|
||||
|
||||
See the [proxy documentation](/docs/advanced-usage/proxy-management.md#proxy-port-mapping).
|
||||
See the [proxy documentation](/docs/advanced-usage/proxy-management.md#proxy-port-mapping) for more information on how to manage ports proxied for your app.
|
||||
|
||||
## Regenerating nginx config
|
||||
|
||||
See the [proxy documentation](/docs/advanced-usage/proxy-management.md#regenerating-proxy-config) for more information on how to rebuild the nginx proxy configuration for your app.
|
||||
|
||||
@@ -9,6 +9,7 @@ certs:add <app> CRT KEY # Add an ssl endpoint to an app. Can al
|
||||
certs:generate <app> DOMAIN # Generate a key and certificate signing request (and self-signed certificate)
|
||||
certs:remove <app> # Remove an SSL Endpoint from an app.
|
||||
certs:report [<app>] [<flag>] # Displays an ssl report for one or more apps
|
||||
certs:show <app> <crt|key> # Show the server.crt or server.key on stdout
|
||||
certs:update <app> CRT KEY # Update an SSL Endpoint on an app. Can also import from a tarball on stdin
|
||||
```
|
||||
|
||||
@@ -56,6 +57,16 @@ If you decide to obtain a CA signed certificate, you can import that certificate
|
||||
|
||||
The `certs:remove` command only works on app-specific certificates. It will `rm` the app-specific tls directory, rebuild the nginx configuration, and reload nginx.
|
||||
|
||||
### Showing the certificate
|
||||
|
||||
The `certs:show` command can be used to show your configured certs for an app. The show command can be used for example to export Let's Encrypt certificates
|
||||
after they've been generated. You can export it as follows:
|
||||
|
||||
```shell
|
||||
dokku certs:show node-js-app crt > server.crt
|
||||
dokku certs:show node-js-app key > server.key
|
||||
```
|
||||
|
||||
### Displaying certificate reports for an app
|
||||
|
||||
> New as of 0.8.1
|
||||
@@ -113,9 +124,9 @@ dokku certs:report node-js-app --ssl-enabled
|
||||
|
||||
## HSTS Header
|
||||
|
||||
The [HSTS header](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) is an HTTP header that can inform browsers that all requests to a given site should be made via HTTPS. Dokku does not enables this header by default
|
||||
The [HSTS header](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) is an HTTP header that can inform browsers that all requests to a given site should be made via HTTPS. Dokku does enables this header by default for HTTPS requests.
|
||||
|
||||
See the [NGINX HSTS documentation](/docs/configuration/nginx.md#hsts-header) for more information.
|
||||
See the [NGINX HSTS documentation](/docs/configuration/nginx.md#hsts-header) for more information on how the HSTS configuration can be managed for your application.
|
||||
|
||||
## HTTP/2 support
|
||||
|
||||
|
||||
@@ -100,8 +100,11 @@ Total 231 (delta 93), reused 147 (delta 53)
|
||||
|
||||
Once the deploy is complete, the application's web URL will be generated as above.
|
||||
|
||||
Dokku supports deploying applications via [Heroku buildpacks](https://devcenter.heroku.com/articles/buildpacks) with [Herokuish](https://github.com/gliderlabs/herokuish#buildpacks), as well as by using a project's [Dockerfile](https://docs.docker.com/reference/builder/).
|
||||
Dokku supports deploying applications in a few ways:
|
||||
|
||||
- [Heroku buildpacks](https://devcenter.heroku.com/articles/buildpacks) via [Herokuish](https://github.com/gliderlabs/herokuish#buildpacks): See the [buildpacks documentation](/docs/deployment/methods/buildpacks.md) to learn about the different ways to specify a buildpack.
|
||||
- [Dockerfile](https://docs.docker.com/reference/builder/): See the [dockerfile documentation](/docs/deployment/methods/dockerfiles.md) to learn about the different ways to configure Dockerfile-based deploys.
|
||||
- [Docker Image](https://docs.docker.com/get-started/overview/#docker-objects): See the [docker image documentation](/docs/deployment/methods/images.md) to learn about how to deploy a Docker Image.
|
||||
|
||||
### Skipping deployment
|
||||
|
||||
@@ -121,7 +124,7 @@ If you need to redeploy or restart your app:
|
||||
dokku ps:rebuild ruby-getting-started
|
||||
```
|
||||
|
||||
See the [process scaling documentation](/docs/deployment/process-management.md) for more information.
|
||||
See the [process scaling documentation](/docs/deployment/process-management.md) for more information on how to manage your app processes.
|
||||
|
||||
### Deploying with private Git submodules
|
||||
|
||||
@@ -188,36 +191,36 @@ Prior to every deployment, Dokku will execute a cleanup function. As of 0.5.x, t
|
||||
|
||||
## Adding deploy users
|
||||
|
||||
See the [user management documentation](/docs/deployment/user-management.md).
|
||||
See the [user management documentation](/docs/deployment/user-management.md) for more information on how to manage users with access to your Dokku server.
|
||||
|
||||
## Default vhost
|
||||
|
||||
See the [nginx documentation](/docs/configuration/nginx.md#default-site).
|
||||
See the [domains documentation](/docs/configuration/domains.md#default-site) for more information on how to manage the default site.
|
||||
|
||||
## Deploying non-master branch
|
||||
|
||||
See the [Git documentation](/docs/deployment/methods/git.md#changing-the-deploy-branch).
|
||||
See the [Git documentation](/docs/deployment/methods/git.md#changing-the-deploy-branch) for more information on deploying a non-master branch to your application.
|
||||
|
||||
## Dockerfile deployment
|
||||
|
||||
See the [Dockerfile documentation](/docs/deployment/methods/dockerfiles.md).
|
||||
See the [Dockerfile documentation](/docs/deployment/methods/dockerfiles.md) for information Dokku's Dockerfile support.
|
||||
|
||||
## Image tagging
|
||||
|
||||
See the [image tagging documentation](/docs/deployment/methods/images.md).
|
||||
See the [image tagging documentation](/docs/deployment/methods/images.md) for more information on how Docker images can be tagged and deployed for a given application.
|
||||
|
||||
## Specifying a custom buildpack
|
||||
|
||||
See the [buildpack documentation](/docs/deployment/methods/buildpacks.md).
|
||||
See the [buildpack documentation](/docs/deployment/methods/buildpacks.md) for more information on how to specify a set of custom buildpacks for your application.
|
||||
|
||||
## Removing a deployed app
|
||||
|
||||
See the [application management documentation](/docs/deployment/application-management.md#removing-a-deployed-app).
|
||||
See the [application management documentation](/docs/deployment/application-management.md#removing-a-deployed-app) for more information on how to remove an application from your Dokku server.
|
||||
|
||||
## Renaming a deployed app
|
||||
|
||||
See the [application management documentation](/docs/deployment/application-management.md#renaming-a-deployed-app).
|
||||
See the [application management documentation](/docs/deployment/application-management.md#renaming-a-deployed-app) for more information on how an application can be renamed and the impact of doing so upon the application and associated resources.
|
||||
|
||||
## Zero downtime deploy
|
||||
|
||||
See the [zero-downtime deploy documentation](/docs/deployment/zero-downtime-deploys.md).
|
||||
See the [zero-downtime deploy documentation](/docs/deployment/zero-downtime-deploys.md) for more information on how Dokku enables zero-downtime deploys.
|
||||
|
||||
@@ -103,6 +103,16 @@ dokku --force apps:destroy node-js-app
|
||||
Destroying node-js-app (including all add-ons)
|
||||
```
|
||||
|
||||
The `--force` flag can also be specified on the command vs globally:
|
||||
|
||||
```shell
|
||||
dokku apps:destroy --force node-js-app
|
||||
```
|
||||
|
||||
```
|
||||
Destroying node-js-app (including all add-ons)
|
||||
```
|
||||
|
||||
Destroying an application will unlink all linked services and destroy any config related to the application. Note that linked services will retain their data for later use (or removal).
|
||||
|
||||
### Renaming a deployed app
|
||||
|
||||
@@ -224,4 +224,4 @@ dokku config:set --global CURL_CONNECT_TIMEOUT=180
|
||||
|
||||
### Clearing buildpack cache
|
||||
|
||||
See the [repository management documentation](/docs/advanced-usage/repository-management.md#clearing-app-cache).
|
||||
See the [repository management documentation](/docs/advanced-usage/repository-management.md#clearing-app-cache) for more information on how to clear buildpack build cache for an application.
|
||||
|
||||
@@ -116,4 +116,4 @@ in your `Procfile` will be passed as arguments to the `ENTRYPOINT` script instea
|
||||
|
||||
## Exposed ports
|
||||
|
||||
See the [port management documentation](/docs/networking/port-management.md).
|
||||
See the [port management documentation](/docs/networking/port-management.md) for more information on how Dokku exposes ports for applications and how you can configure these for your app.
|
||||
|
||||
@@ -22,7 +22,7 @@ The Dokku tags plugin allows you to add Docker image tags to the currently deplo
|
||||
|
||||
### Exposed ports
|
||||
|
||||
See the [port management documentation](/docs/networking/port-management.md).
|
||||
See the [port management documentation](/docs/networking/port-management.md) for more information on how Dokku exposes ports for applications and how you can configure these for your app.
|
||||
|
||||
### Listing tags for an application
|
||||
|
||||
|
||||
@@ -327,7 +327,7 @@ export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
case "$DOKKU_DISTRO" in
|
||||
debian|ubuntu)
|
||||
apt-get install --force-yes -qq -y nginx
|
||||
apt-get install -qq -y nginx
|
||||
;;
|
||||
|
||||
opensuse)
|
||||
@@ -531,6 +531,111 @@ verify_app_name "$APP"
|
||||
# TODO
|
||||
```
|
||||
|
||||
### `domains-add`
|
||||
|
||||
- Description: Adds a domain to an app
|
||||
- Invoked by:
|
||||
- Arguments: `$APP` `$DOMAIN`
|
||||
- Example:
|
||||
|
||||
```shell
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
# TODO
|
||||
```
|
||||
|
||||
### `domains-disable`
|
||||
|
||||
- Description: Disables domains for an app
|
||||
- Invoked by:
|
||||
- Arguments: `$APP` `$RESTART_APP`
|
||||
- Example:
|
||||
|
||||
```shell
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
# TODO
|
||||
```
|
||||
|
||||
### `domains-enable`
|
||||
|
||||
- Description: Enables domains for an app
|
||||
- Invoked by:
|
||||
- Arguments: `$APP` `$RESTART_APP`
|
||||
- Example:
|
||||
|
||||
```shell
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
# TODO
|
||||
```
|
||||
|
||||
### `domains-list`
|
||||
|
||||
- Description: Lists all domains for an app
|
||||
- Invoked by:
|
||||
- Arguments: `$APP`
|
||||
- Example:
|
||||
|
||||
```shell
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
# TODO
|
||||
```
|
||||
|
||||
### `domains-setup`
|
||||
|
||||
- Description: Initializes domains for an app if enabled
|
||||
- Invoked by:
|
||||
- Arguments: `$APP`
|
||||
- Example:
|
||||
|
||||
```shell
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
# TODO
|
||||
```
|
||||
|
||||
### `domains-vhost-enabled`
|
||||
|
||||
- Description: Checks if a virtual hosts are enabled for an app
|
||||
- Invoked by:
|
||||
- Arguments: `$APP`
|
||||
- Example:
|
||||
|
||||
```shell
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
# TODO
|
||||
```
|
||||
|
||||
### `git-deploy-branch`
|
||||
|
||||
- Description: Outputs the deploy branch for an app, inherited or not
|
||||
- Invoked by:
|
||||
- Arguments: `$APP`
|
||||
- Example:
|
||||
|
||||
```shell
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
# TODO
|
||||
```
|
||||
|
||||
### `git-post-pull`
|
||||
|
||||
- Description:
|
||||
@@ -749,6 +854,21 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
# TODO
|
||||
```
|
||||
|
||||
### `nginx-dokku-template-source`
|
||||
|
||||
- Description: Customize the source location of the `dokku.conf` nginx configuration file
|
||||
- Invoked by: `nginx-vhosts#install`
|
||||
- Arguments:
|
||||
- Example:
|
||||
|
||||
```shell
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
# TODO
|
||||
```
|
||||
|
||||
### `nginx-hostname`
|
||||
|
||||
- Description: Allows you to customize the hostname for a given app
|
||||
@@ -1563,6 +1683,25 @@ DOKKU_SCHEDULER="$1"; APP="$2"; FORCE_CLEANUP="$3";
|
||||
# TODO
|
||||
```
|
||||
|
||||
### `scheduler-enter`
|
||||
|
||||
> Warning: The scheduler plugin trigger apis are under development and may change
|
||||
> between minor releases until the 1.0 release.
|
||||
|
||||
- Description: Allows you to enter a running container for a given app
|
||||
- Invoked by: `dokku enter`
|
||||
- Arguments: `$DOKKU_SCHEDULER $APP $@`
|
||||
- Example:
|
||||
|
||||
```shell
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
DOKKU_SCHEDULER="$1"; APP="$2"; ARGS="$@"
|
||||
|
||||
# TODO
|
||||
```
|
||||
|
||||
### `scheduler-inspect`
|
||||
|
||||
> Warning: The scheduler plugin trigger apis are under development and may change
|
||||
@@ -1600,6 +1739,7 @@ DOKKU_SCHEDULER="$1"; APP="$2";
|
||||
|
||||
# TODO
|
||||
```
|
||||
|
||||
### `scheduler-logs`
|
||||
|
||||
> Warning: The scheduler plugin trigger apis are under development and may change
|
||||
|
||||
@@ -29,7 +29,7 @@ The workflow looks like this:
|
||||
```shell
|
||||
# having dokku-arch in ../dokku-arch
|
||||
vagrant up build-arch
|
||||
# wait for "==> build-arch: ==> Finished making: dokku 0.20.3-2 (Mon Feb 22 23:20:37 CET 2016)"
|
||||
# wait for "==> build-arch: ==> Finished making: dokku 0.21.2-2 (Mon Feb 22 23:20:37 CET 2016)"
|
||||
cd ../dokku-arch
|
||||
git add PKGBUILD .SRCINFO
|
||||
git commit -m 'Update to dokku 0.9.9'
|
||||
|
||||
@@ -13,7 +13,7 @@ wget -nv -O - https://get.docker.com/ | sh
|
||||
# install dokku
|
||||
wget -nv -O - https://packagecloud.io/dokku/dokku/gpgkey | apt-key add -
|
||||
OS_ID="$(lsb_release -cs 2>/dev/null || echo "bionic")"
|
||||
echo "xenial bionic" | grep -q "$OS_ID" || OS_ID="bionic"
|
||||
echo "xenial bionic focal" | grep -q "$OS_ID" || OS_ID="bionic"
|
||||
echo "deb https://packagecloud.io/dokku/dokku/ubuntu/ ${OS_ID} main" | sudo tee /etc/apt/sources.list.d/dokku.list
|
||||
sudo apt-get update -qq >/dev/null
|
||||
sudo apt-get install -qq -y dokku
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Pull the dokku/dokku image:
|
||||
|
||||
```shell
|
||||
docker pull dokku/dokku:0.20.3
|
||||
docker pull dokku/dokku:0.21.2
|
||||
```
|
||||
|
||||
Next, run the image.
|
||||
@@ -17,10 +17,10 @@ docker run \
|
||||
--publish 8443:443 \
|
||||
--volume /var/lib/dokku:/mnt/dokku \
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
dokku/dokku:0.20.3
|
||||
dokku/dokku:0.21.2
|
||||
```
|
||||
|
||||
Dokku is run with the following options:
|
||||
Dokku is run in the following configuration:
|
||||
|
||||
- The global hostname is set to `dokku.me` on boot.
|
||||
- The container name is dokku.
|
||||
@@ -29,6 +29,7 @@ Dokku is run with the following options:
|
||||
- Container HTTPS port 443 is exposed on the host as 8443.
|
||||
- Data within the container is stored on the host within the `/var/lib/dokku` directory.
|
||||
- The docker socket is mounted into container
|
||||
- The "web installer" is not supported.
|
||||
|
||||
Application repositories, plugin config, and plugin data is persisted to disk within the specified host directory for `/var/lib/dokku`.
|
||||
|
||||
|
||||
@@ -43,145 +43,155 @@ server:
|
||||
|
||||
```yaml
|
||||
#cloud-config
|
||||
apt_upgrade: true
|
||||
|
||||
apt_sources:
|
||||
- source: "deb https://packagecloud.io/dokku/dokku/ubuntu/ bionic main"
|
||||
key: |
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: SKS 1.1.5
|
||||
Comment: Hostname: pgpkeys.eu
|
||||
apt:
|
||||
sources:
|
||||
source_dokku:
|
||||
source: 'deb https://packagecloud.io/dokku/dokku/ubuntu/ $RELEASE main'
|
||||
key: |
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.11 (GNU/Linux)
|
||||
|
||||
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
|
||||
=H60S
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
filename: dokku.list
|
||||
- source: "deb https://apt.dockerproject.org/repo ubuntu-bionic main"
|
||||
key: |
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: SKS 1.1.5
|
||||
Comment: Hostname: pgpkeys.co.uk
|
||||
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
|
||||
=laU4
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
source_docker:
|
||||
source: 'deb [arch=amd64] https://download.docker.com/linux/ubuntu $RELEASE stable'
|
||||
key: |
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
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
|
||||
=Yhur
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
filename: docker.list
|
||||
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
|
||||
YT90qFF93M3v01BbxP+EIY2/9tiIPbrd
|
||||
=0YYh
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
package_upgrade: true
|
||||
|
||||
debconf_selections: |
|
||||
|
||||
dokku dokku/web_config boolean false
|
||||
dokku dokku/vhost_enable boolean true
|
||||
debconf_selections:
|
||||
web: dokku dokku/web_config boolean false
|
||||
vhost: dokku dokku/vhost_enable boolean true
|
||||
# set the domain name of the new Dokku server
|
||||
dokku dokku/hostname string $YOUR_FULL_QUALIFIED_DOMAIN
|
||||
hostname: dokku dokku/hostname string $YOUR_FULL_QUALIFIED_DOMAIN
|
||||
# this copies over the public SSH key assigned to the server
|
||||
dokku dokku/key_file string /home/ubuntu/.ssh/authorized_keys
|
||||
|
||||
key: dokku dokku/key_file string /home/ubuntu/.ssh/authorized_keys
|
||||
|
||||
packages:
|
||||
- dokku
|
||||
- dokku
|
||||
package_update: true
|
||||
package_upgrade: true
|
||||
package_reboot_if_required: true
|
||||
```
|
||||
|
||||
Shortly after running the create command you will get a confirmation that the
|
||||
|
||||
@@ -21,8 +21,8 @@ To install the latest stable version of Dokku, you can run the following shell c
|
||||
|
||||
```shell
|
||||
# for debian systems, installs Dokku via apt-get
|
||||
wget https://raw.githubusercontent.com/dokku/dokku/v0.20.3/bootstrap.sh;
|
||||
sudo DOKKU_TAG=v0.20.3 bash bootstrap.sh
|
||||
wget https://raw.githubusercontent.com/dokku/dokku/v0.21.2/bootstrap.sh;
|
||||
sudo DOKKU_TAG=v0.21.2 bash bootstrap.sh
|
||||
```
|
||||
|
||||
The installation process takes about 5-10 minutes, depending upon internet connection speed.
|
||||
@@ -58,6 +58,7 @@ As well, you may wish to customize your installation in some other fashion. or e
|
||||
- [RPM Package Installation Notes](/docs/getting-started/install/rpm.md)
|
||||
- [Vagrant Installation Notes](/docs/getting-started/install/vagrant.md)
|
||||
- [Advanced Install Customization](/docs/getting-started/advanced-installation.md)
|
||||
- [Automated deployment via ansible](https://github.com/dokku/ansible-dokku)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -76,6 +76,9 @@ __Solution:__
|
||||
|
||||
The `remote rejected` error does not give enough information. Anything could have failed. Enable trace mode and begin debugging. If this does not help you, create a [gist](https://gist.github.com) containing the full log, and create an issue.
|
||||
|
||||
One the reasons why you may get this error is because the command that is run in the container exited (without errors). For example, (in Procfile) when you define a new worker container to run Delayed Job and use the bin/delayed_job start command. This command deamonizes the process and exists. The container thinks it's done so it closes itself. The error you get is the one above. To fix the above problem for Delayed Job, you must define the worker to user rake jobs:work, which doesn't deamonize the process.
|
||||
|
||||
|
||||
***
|
||||
|
||||
__Symptom:__ I get the aforementioned error in the build phase (after turning on Dokku tracing).
|
||||
@@ -112,6 +115,18 @@ Please see https://github.com/dokku/dokku/issues/841 and https://github.com/dokk
|
||||
|
||||
***
|
||||
|
||||
__Symptom:__ After adding an SSH key, I still see the following error on deploy:
|
||||
|
||||
Connection closed by <host> port 22
|
||||
fatal: Could not read from remote repository.
|
||||
|
||||
Please make sure you have the correct access rights
|
||||
and the repository exists.
|
||||
|
||||
Certain systems may have access to the `dokku` user via SSH disabled. Please check that the `dokku` user is allowed access to the system in the file `/etc/security/access.conf`. As Dokku does not manage this file, please consult your Operating System's documentation for more information.
|
||||
|
||||
***
|
||||
|
||||
__Symptom:__ I want to deploy my app but I am getting asked for the password of the Git user and the error message.
|
||||
|
||||
fatal: 'NAME' does not appear to be a git repository
|
||||
|
||||
@@ -2,31 +2,31 @@
|
||||
|
||||
While we hate to see you go, if you need to uninstall Dokku, the following may help you out:
|
||||
|
||||
## Arch Installation
|
||||
## Arch Uninstallation
|
||||
|
||||
```shell
|
||||
# purge dokku from your system
|
||||
yaourt -Rsn dokku
|
||||
yay -Rsn dokku
|
||||
```
|
||||
|
||||
## CentOS Installation
|
||||
## CentOS Uninstallation
|
||||
|
||||
```shell
|
||||
# uninstall dokku
|
||||
yum remove dokku herokuish
|
||||
```
|
||||
|
||||
## Debian Installation
|
||||
## Debian Uninstallation
|
||||
|
||||
```shell
|
||||
# purge dokku from your system
|
||||
apt-get purge -y --force-yes dokku herokuish
|
||||
apt-get purge dokku herokuish
|
||||
|
||||
# remove any dependencies that are no longer necessary
|
||||
apt-get -y --force-yes autoremove
|
||||
apt-get autoremove
|
||||
```
|
||||
|
||||
## Makefile Installation
|
||||
## Makefile Uninstallation
|
||||
|
||||
This is a manual deletion process, and as it is not a recommended installation method, there is currently no automated uninstallation.
|
||||
|
||||
|
||||
@@ -15,67 +15,50 @@ Your operating system may occasionally provide security updates. We recommend se
|
||||
|
||||
Docker releases updates periodically to their engine. We recommend reading their release notes and upgrading accordingly. Please see the [Docker documentation](https://docs.docker.com/) for more details.
|
||||
|
||||
Finally, we provide a helpful binary called `dokku-update`. This is a recommended package that:
|
||||
|
||||
- Can be installed separately, so upgrading Dokku will not affect the running of this package.
|
||||
- Automates many of the upgrade instructions for you.
|
||||
- Provides a clean way for us to further enhance the upgrade process in the future.
|
||||
|
||||
When installing from source, this is available from `contrib/dokku-update`, and is also available on Debian and RPM-based systems from our package repositories under the name `dokku-update`.
|
||||
|
||||
## Migration Guides
|
||||
|
||||
Before upgrading, check the migration guides to get comfortable with new features and prepare your deployment to be upgraded.
|
||||
|
||||
### 0.5 Migration Guide
|
||||
- [Upgrading to 0.21](/docs/appendices/0.21.0-migration-guide.md)
|
||||
- [Upgrading to 0.20](/docs/appendices/0.20.0-migration-guide.md)
|
||||
- [Upgrading to 0.10](/docs/appendices/0.10.0-migration-guide.md)
|
||||
- [Upgrading to 0.9](/docs/appendices/0.9.0-migration-guide.md)
|
||||
- [Upgrading to 0.8](/docs/appendices/0.8.0-migration-guide.md)
|
||||
- [Upgrading to 0.7](/docs/appendices/0.7.0-migration-guide.md)
|
||||
- [Upgrading to 0.6](/docs/appendices/0.6.0-migration-guide.md)
|
||||
- [Upgrading to 0.5](/docs/appendices/0.5.0-migration-guide.md)
|
||||
|
||||
- [0.5 Migration Guide](/docs/appendices/0.5.0-migration-guide.md)
|
||||
## Before upgrading
|
||||
|
||||
### 0.6 Migration Guide
|
||||
If you'll be updating docker or the herokuish package simultaneously, it's recommended
|
||||
that you stop all applications before upgrading and rebuild afterwards. This is not
|
||||
required if the upgrade only impacts the `dokku` package.
|
||||
|
||||
- [0.6 Migration Guide](/docs/appendices/0.6.0-migration-guide.md)
|
||||
Why do we recommend stopping all apps?
|
||||
|
||||
### 0.7 Migration Guide
|
||||
|
||||
- [0.7 Migration Guide](/docs/appendices/0.7.0-migration-guide.md)
|
||||
|
||||
### 0.8 Migration Guide
|
||||
|
||||
- [0.8 Migration Guide](/docs/appendices/0.8.0-migration-guide.md)
|
||||
|
||||
### 0.9 Migration Guide
|
||||
|
||||
- [0.9 Migration Guide](/docs/appendices/0.9.0-migration-guide.md)
|
||||
|
||||
### 0.10 Migration Guide
|
||||
|
||||
- [0.10 Migration Guide](/docs/appendices/0.10.0-migration-guide.md)
|
||||
|
||||
### 0.20 Migration Guide
|
||||
|
||||
- [0.20 Migration Guide](/docs/appendices/0.20.0-migration-guide.md)
|
||||
|
||||
## Upgrade Instructions
|
||||
|
||||
If Dokku was installed via `apt-get install dokku` or `bootstrap.sh` (most common), upgrade with:
|
||||
- `docker`: Containers may be randomly reset during the upgrade process, resulting in
|
||||
requests being sent to the wrong containers. Acknowledging and scheduling downtime
|
||||
thus becomes much more important.
|
||||
- `herokuish`: While not required, it may be useful to take advantage of the
|
||||
|
||||
```shell
|
||||
# update your local apt cache
|
||||
sudo apt-get update
|
||||
|
||||
# stop each running app
|
||||
# for 0.11.4 and newer versions, use
|
||||
# for 0.11.4 and newer versions, use:
|
||||
dokku ps:stopall
|
||||
|
||||
# for versions between 0.8.1 and 0.11.3, use
|
||||
dokku --quiet apps:list | xargs -L1 dokku ps:stop
|
||||
|
||||
# for versions versions older than 0.8.1, use
|
||||
dokku --quiet apps | xargs -L1 dokku ps:stop
|
||||
```
|
||||
|
||||
# update dokku and its dependencies
|
||||
sudo apt-get install -qq -y dokku herokuish sshcommand plugn gliderlabs-sigil
|
||||
## After upgrading
|
||||
|
||||
# rebuild all of your applications
|
||||
dokku ps:rebuildall # rebuilds all applications
|
||||
After upgrading, you should rebuild the applications to take advantage of any
|
||||
new buildpacks that were released:
|
||||
|
||||
```shell
|
||||
dokku ps:rebuildall
|
||||
```
|
||||
|
||||
> If you have any applications deployed via the `tags` or `tar` commands, do not run the `ps:rebuildall` command,
|
||||
@@ -88,12 +71,36 @@ dokku ps:rebuildall # rebuilds all applications
|
||||
> Please see the [images documentation](/docs/deployment/methods/images.md) and [tar documentation](/docs/deployment/methods/tar.md)
|
||||
> for instructions on rebuilding applications deployed by those plugins.
|
||||
|
||||
### Upgrade From Source
|
||||
## Upgrading using `dokku-update`
|
||||
|
||||
We provide a helpful binary called `dokku-update`. This is a recommended package that:
|
||||
|
||||
- Can be installed separately, so upgrading Dokku will not affect the running of this package.
|
||||
- Automates many of the upgrade instructions for you.
|
||||
- Provides a clean way for us to further enhance the upgrade process in the future.
|
||||
|
||||
When installing from source, this is available from `contrib/dokku-update`, and is also available on Debian and RPM-based systems from our package repositories under the name `dokku-update`.
|
||||
|
||||
## Upgrading using `apt`
|
||||
|
||||
If Dokku was installed in a Debian or Ubuntu system, via `apt install dokku` or `bootstrap.sh`, you can upgrade with `apt`:
|
||||
|
||||
```shell
|
||||
# update your local apt cache
|
||||
sudo apt update
|
||||
|
||||
# update dokku and its dependencies
|
||||
sudo apt install -qq -y dokku herokuish sshcommand plugn gliderlabs-sigil
|
||||
|
||||
# or just upgrade every package:
|
||||
sudo apt upgrade
|
||||
```
|
||||
|
||||
## Upgrading from source
|
||||
|
||||
If you installed Dokku from source (less common), upgrade with:
|
||||
|
||||
```shell
|
||||
dokku --quiet apps | xargs -L1 dokku ps:stop # stops each running app
|
||||
cd ~/dokku
|
||||
git pull --tags origin master
|
||||
|
||||
@@ -102,7 +109,6 @@ sudo DOKKU_BRANCH=master make install
|
||||
|
||||
# upgrade to debian package-based installation
|
||||
sudo make install
|
||||
dokku ps:rebuildall # rebuilds all applications
|
||||
```
|
||||
|
||||
To upgrade Herokuish from source, upgrade with:
|
||||
|
||||
@@ -11,7 +11,7 @@ The Official Dokku website is always a great place to visit. It features links t
|
||||
## The IRC and Slack Channels
|
||||
|
||||
- [irc.freenode.net/#dokku](https://webchat.freenode.net/?channels=dokku)
|
||||
- [Gliderlabs Slack](https://glider-slackin.herokuapp.com/)
|
||||
- [Gliderlabs Slack](https://glider-slackin.herokuapp.com/) (Join the `#dokku` channel)
|
||||
|
||||
If you’re stumped, give us a holler in the Dokku IRC or Slack channels. Someone from the development team is usually there, especially during the daylight hours for North and South America users. We’d love to hear from you, whether you need some help, want to find users in your area, or would like to donate your brand new sports car.
|
||||
|
||||
|
||||
@@ -10,30 +10,30 @@
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet" type="text/css">
|
||||
<title>Dokku - The smallest PaaS implementation you've ever seen</title>
|
||||
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/apple-touch-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/apple-touch-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/apple-touch-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/apple-touch-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/apple-touch-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/apple-touch-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/apple-touch-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/android-chrome-192x192.png" sizes="192x192">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/favicon-16x16.png" sizes="16x16">
|
||||
<link rel="manifest" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/manifest.json">
|
||||
<link rel="shortcut icon" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/favicon.ico">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/apple-touch-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/apple-touch-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/apple-touch-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/apple-touch-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/apple-touch-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/apple-touch-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/apple-touch-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/android-chrome-192x192.png" sizes="192x192">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/favicon-16x16.png" sizes="16x16">
|
||||
<link rel="manifest" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/manifest.json">
|
||||
<link rel="shortcut icon" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/favicon.ico">
|
||||
<meta name="apple-mobile-web-app-title" content="Dokku">
|
||||
<meta name="application-name" content="Dokku">
|
||||
<meta name="msapplication-TileColor" content="#da532c">
|
||||
<meta name="msapplication-TileImage" content="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/mstile-144x144.png">
|
||||
<meta name="msapplication-config" content="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/browserconfig.xml">
|
||||
<meta name="msapplication-TileImage" content="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/mstile-144x144.png">
|
||||
<meta name="msapplication-config" content="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/browserconfig.xml">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.2/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/style.css" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/style.css" rel="stylesheet">
|
||||
<!-- <link href="/dokku/docs/assets/style.css" rel="stylesheet"> -->
|
||||
<style>
|
||||
.sponsors {
|
||||
@@ -127,12 +127,12 @@
|
||||
<p class="line">
|
||||
<span class="path"></span>
|
||||
<span class="prompt">$</span>
|
||||
<span class="command">wget https://raw.githubusercontent.com/dokku/dokku/v0.20.3/bootstrap.sh</span>
|
||||
<span class="command">wget https://raw.githubusercontent.com/dokku/dokku/v0.21.2/bootstrap.sh</span>
|
||||
</p>
|
||||
<p class="line">
|
||||
<span class="path"></span>
|
||||
<span class="prompt">$</span>
|
||||
<span class="command">sudo DOKKU_TAG=v0.20.3 bash bootstrap.sh</span>
|
||||
<span class="command">sudo DOKKU_TAG=v0.21.2 bash bootstrap.sh</span>
|
||||
</p>
|
||||
<p class="line">
|
||||
<span class="output"> # go to your server's IP and follow the web installer</span>
|
||||
@@ -169,7 +169,7 @@
|
||||
<p class="line">
|
||||
<span class="path"></span>
|
||||
<span class="prompt">$</span>
|
||||
<span class="command">echo "xenial bionic" | grep -q "$OS_ID" || OS_ID="bionic"</span>
|
||||
<span class="command">echo "xenial bionic focal" | grep -q "$OS_ID" || OS_ID="bionic"</span>
|
||||
</p>
|
||||
<p class="line">
|
||||
<span class="path"></span>
|
||||
@@ -201,12 +201,12 @@
|
||||
|
||||
<div class="shell shell-arch">
|
||||
<p class="line">
|
||||
<span class="output"> # install dokku via yaourt</span>
|
||||
<span class="output"> # install dokku via yay</span>
|
||||
</p>
|
||||
<p class="line">
|
||||
<span class="path"></span>
|
||||
<span class="prompt">$</span>
|
||||
<span class="command">yaourt -S dokku</span>
|
||||
<span class="command">yay -S dokku</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -144,7 +144,40 @@ dokku network:set node-js-app attach-post-create
|
||||
dokku network:set node-js-app attach-post-deploy
|
||||
```
|
||||
|
||||
When a container created for a deployment is being attached to a network - regardless of which `attach` property was used - a network alias of the pattern `APP.PROC_TYPE` will be added to all containers. This can be used to load-balance requests between containers.
|
||||
#### Network Aliases
|
||||
|
||||
When a container created for a deployment is being attached to a network - regardless of which `attach` property was used - a network alias of the pattern `APP.PROC_TYPE` will be added to all containers. This can be used to load-balance requests between containers. For an application named `node-js-app` with a process type of web, the network alias - or resolvable DNS record within the network - will be:
|
||||
|
||||
```
|
||||
node-js-app.web
|
||||
```
|
||||
|
||||
The fully-qualified URL for the resource will depend upon the `PORT` being listened to by the application. Applications built via buildpacks will have their `PORT` environment variable set to `5000`, and as such internal network requests for the above example should point to the following:
|
||||
|
||||
```
|
||||
http://node-js-app.web:5000
|
||||
```
|
||||
|
||||
Dockerfile-based applications may listen on other ports. For more information on how ports are specified for applications, please refer to the [port management documentation](/docs/networking/port-management.md).
|
||||
|
||||
#### Specifying a custom TLD
|
||||
|
||||
When attaching applications to networks, a custom TLD can be specified via the `network:set` command. This TLD is suffixed to the network alias for the application/process-type combination for _all_ networks to which the application is attached, and cannot be customized per network.
|
||||
|
||||
To specify a TLD of `svc.cluster.local` for your application, run the following command:
|
||||
|
||||
```shell
|
||||
# replace node-js-app with your application name
|
||||
dokku network:set node-js-app tld svc.cluster.local
|
||||
```
|
||||
|
||||
With an application named `node-js-app` and a process-type named `web`, the above command will turn the network alias into:
|
||||
|
||||
```shell
|
||||
node-js-app.web.svc.cluster.local
|
||||
```
|
||||
|
||||
Note that this has no impact on container port handling, and users must still specify the container port when making internal network requests.
|
||||
|
||||
#### When to attach containers to a network
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
> New as of 0.5.0, Enhanced in 0.6.0
|
||||
|
||||
```
|
||||
proxy:build-config <app> # (Re)builds config for given app
|
||||
proxy:disable <app> # Disable proxy for app
|
||||
proxy:enable <app> # Enable proxy for app
|
||||
proxy:report [<app>] [<flag>] # Displays a proxy report for one or more apps
|
||||
@@ -13,6 +14,14 @@ In Dokku 0.5.0, port proxying was decoupled from the `nginx-vhosts` plugin into
|
||||
|
||||
## Usage
|
||||
|
||||
### Regenerating proxy config
|
||||
|
||||
In certain cases, your app proxy configs may drift from the correct config for your app. You may regenerate the config at any point via the `proxy:build-config` command. This command will trigger a rebuild for the configured proxy implementation (default: nginx) for a given app. The command may fail if there are no current web listeners for your app.
|
||||
|
||||
```shell
|
||||
dokku proxy:build-config node-js-app
|
||||
```
|
||||
|
||||
### Container network interface binding
|
||||
|
||||
> Changed as of 0.11.0
|
||||
@@ -84,4 +93,4 @@ dokku proxy:set node-js-app nginx
|
||||
|
||||
### Proxy port mapping
|
||||
|
||||
See the [port management documentation](/docs/networking/port-management.md).
|
||||
See the [port management documentation](/docs/networking/port-management.md) for more information on how port mappings are managed for an application.
|
||||
|
||||
@@ -9,26 +9,26 @@
|
||||
<meta name="author" content="">
|
||||
<title>Dokku - The smallest PaaS implementation you've ever seen</title>
|
||||
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/apple-touch-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/apple-touch-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/apple-touch-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/apple-touch-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/apple-touch-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/apple-touch-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/apple-touch-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/android-chrome-192x192.png" sizes="192x192">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/favicon-16x16.png" sizes="16x16">
|
||||
<link rel="manifest" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/manifest.json">
|
||||
<link rel="shortcut icon" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/favicon.ico">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/apple-touch-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/apple-touch-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/apple-touch-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/apple-touch-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/apple-touch-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/apple-touch-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/apple-touch-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/android-chrome-192x192.png" sizes="192x192">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/favicon-16x16.png" sizes="16x16">
|
||||
<link rel="manifest" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/manifest.json">
|
||||
<link rel="shortcut icon" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/favicon.ico">
|
||||
<meta name="apple-mobile-web-app-title" content="Dokku">
|
||||
<meta name="application-name" content="Dokku">
|
||||
<meta name="msapplication-TileColor" content="#da532c">
|
||||
<meta name="msapplication-TileImage" content="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/mstile-144x144.png">
|
||||
<meta name="msapplication-config" content="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/favicons/browserconfig.xml">
|
||||
<meta name="msapplication-TileImage" content="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/mstile-144x144.png">
|
||||
<meta name="msapplication-config" content="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/favicons/browserconfig.xml">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<script>
|
||||
@@ -42,7 +42,7 @@
|
||||
</script>
|
||||
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.2/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.20.3/docs/assets/style.css" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.21.2/docs/assets/style.css" rel="stylesheet">
|
||||
<!-- <link href="/dokku/docs/assets/style.css" rel="stylesheet"> -->
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet">
|
||||
<style>
|
||||
@@ -162,6 +162,7 @@
|
||||
<a href="#" class="list-group-item disabled">Schedulers</a>
|
||||
|
||||
<a href="/{{NAME}}/advanced-usage/schedulers/docker-local/" class="list-group-item">Docker Local</a>
|
||||
<a href="/{{NAME}}/advanced-usage/schedulers/alternate-schedulers/" class="list-group-item">Alternate Schedulers</a>
|
||||
|
||||
<a href="#" class="list-group-item disabled">Development</a>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core standard plugin"
|
||||
version = "0.20.3"
|
||||
version = "0.21.2"
|
||||
[plugin.config]
|
||||
|
||||
1
plugins/20_events/domains-add
Symbolic link
1
plugins/20_events/domains-add
Symbolic link
@@ -0,0 +1 @@
|
||||
hook
|
||||
1
plugins/20_events/domains-disable
Symbolic link
1
plugins/20_events/domains-disable
Symbolic link
@@ -0,0 +1 @@
|
||||
hook
|
||||
1
plugins/20_events/domains-enable
Symbolic link
1
plugins/20_events/domains-enable
Symbolic link
@@ -0,0 +1 @@
|
||||
hook
|
||||
1
plugins/20_events/domains-list
Symbolic link
1
plugins/20_events/domains-list
Symbolic link
@@ -0,0 +1 @@
|
||||
hook
|
||||
1
plugins/20_events/domains-setup
Symbolic link
1
plugins/20_events/domains-setup
Symbolic link
@@ -0,0 +1 @@
|
||||
hook
|
||||
1
plugins/20_events/domains-vhost-enabled
Symbolic link
1
plugins/20_events/domains-vhost-enabled
Symbolic link
@@ -0,0 +1 @@
|
||||
hook
|
||||
1
plugins/20_events/git-deploy-branch
Symbolic link
1
plugins/20_events/git-deploy-branch
Symbolic link
@@ -0,0 +1 @@
|
||||
hook
|
||||
1
plugins/20_events/nginx-dokku-template-source
Symbolic link
1
plugins/20_events/nginx-dokku-template-source
Symbolic link
@@ -0,0 +1 @@
|
||||
hook
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core events logging plugin"
|
||||
version = "0.20.3"
|
||||
version = "0.21.2"
|
||||
[plugin.config]
|
||||
|
||||
1
plugins/20_events/scheduler-enter
Symbolic link
1
plugins/20_events/scheduler-enter
Symbolic link
@@ -0,0 +1 @@
|
||||
hook
|
||||
@@ -82,13 +82,16 @@ execute_script() {
|
||||
[[ -d $CACHE_DIR ]] || mkdir -p "$CACHE_DIR"
|
||||
|
||||
local DOCKER_ARGS=$(: | plugn trigger docker-args-deploy "$APP" "$IMAGE_TAG")
|
||||
# strip --restart args from DOCKER_ARGS
|
||||
local DOCKER_ARGS=$(sed -e "s/--restart=[[:graph:]]\+[[:blank:]]\?//g" <<<"$DOCKER_ARGS")
|
||||
|
||||
local IMAGE_SOURCE_TYPE="dockerfile"
|
||||
is_image_herokuish_based "$IMAGE" "$APP" && IMAGE_SOURCE_TYPE="herokuish"
|
||||
DOCKER_ARGS+=$(: | plugn trigger docker-args-process-deploy "$APP" "$IMAGE_SOURCE_TYPE" "$IMAGE_TAG")
|
||||
|
||||
# strip certain args from DOCKER_ARGS
|
||||
local filtered_args=("restart" "cpus" "memory" "memory-swap" "memory-reservation" "gpus")
|
||||
for filtered_arg in "${filtered_args[@]}"; do
|
||||
DOCKER_ARGS=$(sed -e "s/--${filtered_arg}=[[:graph:]]\+[[:blank:]]\?//g" <<<"$DOCKER_ARGS")
|
||||
done
|
||||
|
||||
# eval args as array to respect escapes
|
||||
declare -a ARG_ARRAY
|
||||
eval "ARG_ARRAY=($DOCKER_ARGS)"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core app-json plugin"
|
||||
version = "0.20.3"
|
||||
version = "0.21.2"
|
||||
[plugin.config]
|
||||
|
||||
@@ -86,26 +86,6 @@ func destroyApp(appName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getAppName(args []string) (appName string, err error) {
|
||||
if len(args) >= 1 {
|
||||
appName = args[0]
|
||||
} else {
|
||||
err = errors.New("Please specify an app to run the command on")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func getNewAppName(args []string) (appName string, err error) {
|
||||
if len(args) >= 2 {
|
||||
appName = args[1]
|
||||
} else {
|
||||
err = errors.New("Please specify an new app name")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func listImagesByAppLabel(appName string) ([]string, error) {
|
||||
command := []string{
|
||||
common.DockerBin(),
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
package: .
|
||||
import:
|
||||
- package: github.com/codeskyblue/go-sh
|
||||
- package: github.com/ryanuber/columnize
|
||||
11
plugins/apps/go.mod
Normal file
11
plugins/apps/go.mod
Normal file
@@ -0,0 +1,11 @@
|
||||
module github.com/dokku/dokku/plugins/apps
|
||||
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
|
||||
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
|
||||
github.com/ryanuber/columnize v1.1.2-0.20190319233515-9e6335e58db3 // indirect
|
||||
)
|
||||
|
||||
replace github.com/dokku/dokku/plugins/common => ../common
|
||||
6
plugins/apps/go.sum
Normal file
6
plugins/apps/go.sum
Normal file
@@ -0,0 +1,6 @@
|
||||
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
|
||||
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
|
||||
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 h1:HHUr4P/aKh4quafGxDT9LDasjGdlGkzLbfmmrlng3kA=
|
||||
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27/go.mod h1:VQx0hjo2oUeQkQUET7wRwradO6f+fN5jzXgB/zROxxE=
|
||||
github.com/ryanuber/columnize v1.1.2-0.20190319233515-9e6335e58db3 h1:utdYOikI1XjNtTFGCwSM6OmFJblU4ld4gACoJsbadJg=
|
||||
github.com/ryanuber/columnize v1.1.2-0.20190319233515-9e6335e58db3/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core apps plugin"
|
||||
version = "0.20.3"
|
||||
version = "0.21.2"
|
||||
[plugin.config]
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
columnize "github.com/ryanuber/columnize"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -61,11 +60,5 @@ func main() {
|
||||
}
|
||||
|
||||
func usage() {
|
||||
config := columnize.DefaultConfig()
|
||||
config.Delim = ","
|
||||
config.Prefix = " "
|
||||
config.Empty = ""
|
||||
content := strings.Split(helpContent, "\n")[1:]
|
||||
fmt.Println(helpHeader)
|
||||
fmt.Println(columnize.Format(content, config))
|
||||
common.CommandUsage(helpHeader, helpContent)
|
||||
}
|
||||
|
||||
6
plugins/apps/src/glide.lock
generated
6
plugins/apps/src/glide.lock
generated
@@ -1,6 +0,0 @@
|
||||
hash: 1ddab5de41d1514c2722bd7e24758ad4b60bf6956eb5b9b925fa071a1427f149
|
||||
updated: 2017-01-03T17:16:50.97156327-08:00
|
||||
imports:
|
||||
- name: github.com/ryanuber/columnize
|
||||
version: 0fbbb3f0e3fbdc5bae7c6cd5f6c1887ebfb76360
|
||||
testImports: []
|
||||
@@ -1,3 +0,0 @@
|
||||
package: .
|
||||
import:
|
||||
- package: github.com/ryanuber/columnize
|
||||
@@ -22,44 +22,57 @@ func main() {
|
||||
skipDeploy := args.Bool("skip-deploy", false, "--skip-deploy: skip deploy of the new app")
|
||||
ignoreExisting := args.Bool("ignore-existing", false, "--ignore-existing: exit 0 if new app already exists")
|
||||
args.Parse(os.Args[2:])
|
||||
err = apps.CommandClone(args.Args(), *skipDeploy, *ignoreExisting)
|
||||
oldAppName := args.Arg(0)
|
||||
newAppName := args.Arg(1)
|
||||
err = apps.CommandClone(oldAppName, newAppName, *skipDeploy, *ignoreExisting)
|
||||
case "create":
|
||||
args := flag.NewFlagSet("apps:create", flag.ExitOnError)
|
||||
args.Parse(os.Args[2:])
|
||||
err = apps.CommandCreate(args.Args())
|
||||
appName := args.Arg(0)
|
||||
err = apps.CommandCreate(appName)
|
||||
case "destroy":
|
||||
args := flag.NewFlagSet("apps:destroy", flag.ExitOnError)
|
||||
force := args.Bool("force", false, "--force: force destroy without confirmation")
|
||||
args.Parse(os.Args[2:])
|
||||
err = apps.CommandDestroy(args.Args())
|
||||
appName := args.Arg(0)
|
||||
err = apps.CommandDestroy(appName, *force)
|
||||
case "exists":
|
||||
args := flag.NewFlagSet("apps:exists", flag.ExitOnError)
|
||||
args.Parse(os.Args[2:])
|
||||
err = apps.CommandExists(args.Args())
|
||||
appName := args.Arg(0)
|
||||
err = apps.CommandExists(appName)
|
||||
case "list":
|
||||
args := flag.NewFlagSet("apps:list", flag.ExitOnError)
|
||||
args.Parse(os.Args[2:])
|
||||
err = apps.CommandList(args.Args())
|
||||
err = apps.CommandList()
|
||||
case "lock":
|
||||
args := flag.NewFlagSet("apps:lock", flag.ExitOnError)
|
||||
args.Parse(os.Args[2:])
|
||||
err = apps.CommandLock(args.Args())
|
||||
appName := args.Arg(0)
|
||||
err = apps.CommandLock(appName)
|
||||
case "locked":
|
||||
args := flag.NewFlagSet("apps:locked", flag.ExitOnError)
|
||||
args.Parse(os.Args[2:])
|
||||
err = apps.CommandLocked(args.Args())
|
||||
appName := args.Arg(0)
|
||||
err = apps.CommandLocked(appName)
|
||||
case "rename":
|
||||
args := flag.NewFlagSet("apps:rename", flag.ExitOnError)
|
||||
skipDeploy := args.Bool("skip-deploy", false, "--skip-deploy: skip deploy of the new app")
|
||||
args.Parse(os.Args[2:])
|
||||
err = apps.CommandRename(args.Args(), *skipDeploy)
|
||||
oldAppName := args.Arg(0)
|
||||
newAppName := args.Arg(1)
|
||||
err = apps.CommandRename(oldAppName, newAppName, *skipDeploy)
|
||||
case "report":
|
||||
args := flag.NewFlagSet("apps:report", flag.ExitOnError)
|
||||
args.Parse(os.Args[2:])
|
||||
err = apps.CommandReport(args.Args())
|
||||
appName := args.Arg(0)
|
||||
infoFlag := args.Arg(1)
|
||||
err = apps.CommandReport(appName, infoFlag)
|
||||
case "unlock":
|
||||
args := flag.NewFlagSet("apps:unlock", flag.ExitOnError)
|
||||
args.Parse(os.Args[2:])
|
||||
err = apps.CommandUnlock(args.Args())
|
||||
appName := args.Arg(0)
|
||||
err = apps.CommandUnlock(appName)
|
||||
default:
|
||||
common.LogFail(fmt.Sprintf("Invalid plugin subcommand call: %s", subcommand))
|
||||
}
|
||||
|
||||
3
plugins/apps/src/vendor/github.com/ryanuber/columnize/.travis.yml
generated
vendored
3
plugins/apps/src/vendor/github.com/ryanuber/columnize/.travis.yml
generated
vendored
@@ -1,3 +0,0 @@
|
||||
language: go
|
||||
go:
|
||||
- tip
|
||||
20
plugins/apps/src/vendor/github.com/ryanuber/columnize/LICENSE
generated
vendored
20
plugins/apps/src/vendor/github.com/ryanuber/columnize/LICENSE
generated
vendored
@@ -1,20 +0,0 @@
|
||||
Copyright (c) 2016 Ryan Uber
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
69
plugins/apps/src/vendor/github.com/ryanuber/columnize/README.md
generated
vendored
69
plugins/apps/src/vendor/github.com/ryanuber/columnize/README.md
generated
vendored
@@ -1,69 +0,0 @@
|
||||
Columnize
|
||||
=========
|
||||
|
||||
Easy column-formatted output for golang
|
||||
|
||||
[](https://travis-ci.org/ryanuber/columnize)
|
||||
[](https://godoc.org/github.com/ryanuber/columnize)
|
||||
|
||||
Columnize is a really small Go package that makes building CLI's a little bit
|
||||
easier. In some CLI designs, you want to output a number similar items in a
|
||||
human-readable way with nicely aligned columns. However, figuring out how wide
|
||||
to make each column is a boring problem to solve and eats your valuable time.
|
||||
|
||||
Here is an example:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/ryanuber/columnize"
|
||||
)
|
||||
|
||||
func main() {
|
||||
output := []string{
|
||||
"Name | Gender | Age",
|
||||
"Bob | Male | 38",
|
||||
"Sally | Female | 26",
|
||||
}
|
||||
result := columnize.SimpleFormat(output)
|
||||
fmt.Println(result)
|
||||
}
|
||||
```
|
||||
|
||||
As you can see, you just pass in a list of strings. And the result:
|
||||
|
||||
```
|
||||
Name Gender Age
|
||||
Bob Male 38
|
||||
Sally Female 26
|
||||
```
|
||||
|
||||
Columnize is tolerant of missing or empty fields, or even empty lines, so
|
||||
passing in extra lines for spacing should show up as you would expect.
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
Columnize is configured using a `Config`, which can be obtained by calling the
|
||||
`DefaultConfig()` method. You can then tweak the settings in the resulting
|
||||
`Config`:
|
||||
|
||||
```
|
||||
config := columnize.DefaultConfig()
|
||||
config.Delim = "|"
|
||||
config.Glue = " "
|
||||
config.Prefix = ""
|
||||
config.Empty = ""
|
||||
```
|
||||
|
||||
* `Delim` is the string by which columns of **input** are delimited
|
||||
* `Glue` is the string by which columns of **output** are delimited
|
||||
* `Prefix` is a string by which each line of **output** is prefixed
|
||||
* `Empty` is a string used to replace blank values found in output
|
||||
|
||||
You can then pass the `Config` in using the `Format` method (signature below) to
|
||||
have text formatted to your liking.
|
||||
|
||||
See the [godoc](https://godoc.org/github.com/ryanuber/columnize) page for usage.
|
||||
178
plugins/apps/src/vendor/github.com/ryanuber/columnize/columnize.go
generated
vendored
178
plugins/apps/src/vendor/github.com/ryanuber/columnize/columnize.go
generated
vendored
@@ -1,178 +0,0 @@
|
||||
package columnize
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Config can be used to tune certain parameters which affect the way
|
||||
// in which Columnize will format output text.
|
||||
type Config struct {
|
||||
// The string by which the lines of input will be split.
|
||||
Delim string
|
||||
|
||||
// The string by which columns of output will be separated.
|
||||
Glue string
|
||||
|
||||
// The string by which columns of output will be prefixed.
|
||||
Prefix string
|
||||
|
||||
// A replacement string to replace empty fields
|
||||
Empty string
|
||||
}
|
||||
|
||||
// DefaultConfig returns a *Config with default values.
|
||||
func DefaultConfig() *Config {
|
||||
return &Config{
|
||||
Delim: "|",
|
||||
Glue: " ",
|
||||
Prefix: "",
|
||||
Empty: "",
|
||||
}
|
||||
}
|
||||
|
||||
// MergeConfig merges two config objects together and returns the resulting
|
||||
// configuration. Values from the right take precedence over the left side.
|
||||
func MergeConfig(a, b *Config) *Config {
|
||||
var result Config = *a
|
||||
|
||||
// Return quickly if either side was nil
|
||||
if a == nil || b == nil {
|
||||
return &result
|
||||
}
|
||||
|
||||
if b.Delim != "" {
|
||||
result.Delim = b.Delim
|
||||
}
|
||||
if b.Glue != "" {
|
||||
result.Glue = b.Glue
|
||||
}
|
||||
if b.Prefix != "" {
|
||||
result.Prefix = b.Prefix
|
||||
}
|
||||
if b.Empty != "" {
|
||||
result.Empty = b.Empty
|
||||
}
|
||||
|
||||
return &result
|
||||
}
|
||||
|
||||
// stringFormat, given a set of column widths and the number of columns in
|
||||
// the current line, returns a sprintf-style format string which can be used
|
||||
// to print output aligned properly with other lines using the same widths set.
|
||||
func stringFormat(c *Config, widths []int, columns int) string {
|
||||
// Create the buffer with an estimate of the length
|
||||
buf := bytes.NewBuffer(make([]byte, 0, (6+len(c.Glue))*columns))
|
||||
|
||||
// Start with the prefix, if any was given. The buffer will not return an
|
||||
// error so it does not need to be handled
|
||||
buf.WriteString(c.Prefix)
|
||||
|
||||
// Create the format string from the discovered widths
|
||||
for i := 0; i < columns && i < len(widths); i++ {
|
||||
if i == columns-1 {
|
||||
buf.WriteString("%s\n")
|
||||
} else {
|
||||
fmt.Fprintf(buf, "%%-%ds%s", widths[i], c.Glue)
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// elementsFromLine returns a list of elements, each representing a single
|
||||
// item which will belong to a column of output.
|
||||
func elementsFromLine(config *Config, line string) []interface{} {
|
||||
seperated := strings.Split(line, config.Delim)
|
||||
elements := make([]interface{}, len(seperated))
|
||||
for i, field := range seperated {
|
||||
value := strings.TrimSpace(field)
|
||||
|
||||
// Apply the empty value, if configured.
|
||||
if value == "" && config.Empty != "" {
|
||||
value = config.Empty
|
||||
}
|
||||
elements[i] = value
|
||||
}
|
||||
return elements
|
||||
}
|
||||
|
||||
// runeLen calculates the number of visible "characters" in a string
|
||||
func runeLen(s string) int {
|
||||
l := 0
|
||||
for _ = range s {
|
||||
l++
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
// widthsFromLines examines a list of strings and determines how wide each
|
||||
// column should be considering all of the elements that need to be printed
|
||||
// within it.
|
||||
func widthsFromLines(config *Config, lines []string) []int {
|
||||
widths := make([]int, 0, 8)
|
||||
|
||||
for _, line := range lines {
|
||||
elems := elementsFromLine(config, line)
|
||||
for i := 0; i < len(elems); i++ {
|
||||
l := runeLen(elems[i].(string))
|
||||
if len(widths) <= i {
|
||||
widths = append(widths, l)
|
||||
} else if widths[i] < l {
|
||||
widths[i] = l
|
||||
}
|
||||
}
|
||||
}
|
||||
return widths
|
||||
}
|
||||
|
||||
// Format is the public-facing interface that takes a list of strings and
|
||||
// returns nicely aligned column-formatted text.
|
||||
func Format(lines []string, config *Config) string {
|
||||
conf := MergeConfig(DefaultConfig(), config)
|
||||
widths := widthsFromLines(conf, lines)
|
||||
|
||||
// Estimate the buffer size
|
||||
glueSize := len(conf.Glue)
|
||||
var size int
|
||||
for _, w := range widths {
|
||||
size += w + glueSize
|
||||
}
|
||||
size *= len(lines)
|
||||
|
||||
// Create the buffer
|
||||
buf := bytes.NewBuffer(make([]byte, 0, size))
|
||||
|
||||
// Create a cache for the string formats
|
||||
fmtCache := make(map[int]string, 16)
|
||||
|
||||
// Create the formatted output using the format string
|
||||
for _, line := range lines {
|
||||
elems := elementsFromLine(conf, line)
|
||||
|
||||
// Get the string format using cache
|
||||
numElems := len(elems)
|
||||
stringfmt, ok := fmtCache[numElems]
|
||||
if !ok {
|
||||
stringfmt = stringFormat(conf, widths, numElems)
|
||||
fmtCache[numElems] = stringfmt
|
||||
}
|
||||
|
||||
fmt.Fprintf(buf, stringfmt, elems...)
|
||||
}
|
||||
|
||||
// Get the string result
|
||||
result := buf.String()
|
||||
|
||||
// Remove trailing newline without removing leading/trailing space
|
||||
if n := len(result); n > 0 && result[n-1] == '\n' {
|
||||
result = result[:n-1]
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// SimpleFormat is a convenience function to format text with the defaults.
|
||||
func SimpleFormat(lines []string) string {
|
||||
return Format(lines, nil)
|
||||
}
|
||||
306
plugins/apps/src/vendor/github.com/ryanuber/columnize/columnize_test.go
generated
vendored
306
plugins/apps/src/vendor/github.com/ryanuber/columnize/columnize_test.go
generated
vendored
@@ -1,306 +0,0 @@
|
||||
package columnize
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
crand "crypto/rand"
|
||||
)
|
||||
|
||||
func TestListOfStringsInput(t *testing.T) {
|
||||
input := []string{
|
||||
"Column A | Column B | Column C",
|
||||
"x | y | z",
|
||||
}
|
||||
|
||||
config := DefaultConfig()
|
||||
output := Format(input, config)
|
||||
|
||||
expected := "Column A Column B Column C\n"
|
||||
expected += "x y z"
|
||||
|
||||
if output != expected {
|
||||
t.Fatalf("\nexpected:\n%s\n\ngot:\n%s", expected, output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmptyLinesOutput(t *testing.T) {
|
||||
input := []string{
|
||||
"Column A | Column B | Column C",
|
||||
"",
|
||||
"x | y | z",
|
||||
}
|
||||
|
||||
config := DefaultConfig()
|
||||
output := Format(input, config)
|
||||
|
||||
expected := "Column A Column B Column C\n"
|
||||
expected += "\n"
|
||||
expected += "x y z"
|
||||
|
||||
if output != expected {
|
||||
t.Fatalf("\nexpected:\n%s\n\ngot:\n%s", expected, output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLeadingSpacePreserved(t *testing.T) {
|
||||
input := []string{
|
||||
"| Column B | Column C",
|
||||
"x | y | z",
|
||||
}
|
||||
|
||||
config := DefaultConfig()
|
||||
output := Format(input, config)
|
||||
|
||||
expected := " Column B Column C\n"
|
||||
expected += "x y z"
|
||||
|
||||
if output != expected {
|
||||
t.Fatalf("\nexpected:\n%s\n\ngot:\n%s", expected, output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestColumnWidthCalculator(t *testing.T) {
|
||||
input := []string{
|
||||
"Column A | Column B | Column C",
|
||||
"Longer than A | Longer than B | Longer than C",
|
||||
"short | short | short",
|
||||
}
|
||||
|
||||
config := DefaultConfig()
|
||||
output := Format(input, config)
|
||||
|
||||
expected := "Column A Column B Column C\n"
|
||||
expected += "Longer than A Longer than B Longer than C\n"
|
||||
expected += "short short short"
|
||||
|
||||
if output != expected {
|
||||
printableProof := fmt.Sprintf("\nGot: %+q", output)
|
||||
printableProof += fmt.Sprintf("\nExpected: %+q", expected)
|
||||
t.Fatalf("\n%s", printableProof)
|
||||
}
|
||||
}
|
||||
|
||||
func TestColumnWidthCalculatorNonASCII(t *testing.T) {
|
||||
input := []string{
|
||||
"Column A | Column B | Column C",
|
||||
"⌘⌘⌘⌘⌘⌘⌘⌘ | Longer than B | Longer than C",
|
||||
"short | short | short",
|
||||
}
|
||||
|
||||
config := DefaultConfig()
|
||||
output := Format(input, config)
|
||||
|
||||
expected := "Column A Column B Column C\n"
|
||||
expected += "⌘⌘⌘⌘⌘⌘⌘⌘ Longer than B Longer than C\n"
|
||||
expected += "short short short"
|
||||
|
||||
if output != expected {
|
||||
printableProof := fmt.Sprintf("\nGot: %+q", output)
|
||||
printableProof += fmt.Sprintf("\nExpected: %+q", expected)
|
||||
t.Fatalf("\n%s", printableProof)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkColumnWidthCalculator(b *testing.B) {
|
||||
// Generate the input
|
||||
input := []string{
|
||||
"UUID A | UUID B | UUID C | Column D | Column E",
|
||||
}
|
||||
|
||||
format := "%s|%s|%s|%s"
|
||||
short := "short"
|
||||
|
||||
uuid := func() string {
|
||||
buf := make([]byte, 16)
|
||||
if _, err := crand.Read(buf); err != nil {
|
||||
panic(fmt.Errorf("failed to read random bytes: %v", err))
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%08x-%04x-%04x-%04x-%12x",
|
||||
buf[0:4],
|
||||
buf[4:6],
|
||||
buf[6:8],
|
||||
buf[8:10],
|
||||
buf[10:16])
|
||||
}
|
||||
|
||||
for i := 0; i < 1000; i++ {
|
||||
l := fmt.Sprintf(format, uuid()[:8], uuid()[:12], uuid(), short, short)
|
||||
input = append(input, l)
|
||||
}
|
||||
|
||||
config := DefaultConfig()
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
Format(input, config)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVariedInputSpacing(t *testing.T) {
|
||||
input := []string{
|
||||
"Column A |Column B| Column C",
|
||||
"x|y| z",
|
||||
}
|
||||
|
||||
config := DefaultConfig()
|
||||
output := Format(input, config)
|
||||
|
||||
expected := "Column A Column B Column C\n"
|
||||
expected += "x y z"
|
||||
|
||||
if output != expected {
|
||||
t.Fatalf("\nexpected:\n%s\n\ngot:\n%s", expected, output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmatchedColumnCounts(t *testing.T) {
|
||||
input := []string{
|
||||
"Column A | Column B | Column C",
|
||||
"Value A | Value B",
|
||||
"Value A | Value B | Value C | Value D",
|
||||
}
|
||||
|
||||
config := DefaultConfig()
|
||||
output := Format(input, config)
|
||||
|
||||
expected := "Column A Column B Column C\n"
|
||||
expected += "Value A Value B\n"
|
||||
expected += "Value A Value B Value C Value D"
|
||||
|
||||
if output != expected {
|
||||
t.Fatalf("\nexpected:\n%s\n\ngot:\n%s", expected, output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAlternateDelimiter(t *testing.T) {
|
||||
input := []string{
|
||||
"Column | A % Column | B % Column | C",
|
||||
"Value A % Value B % Value C",
|
||||
}
|
||||
|
||||
config := DefaultConfig()
|
||||
config.Delim = "%"
|
||||
output := Format(input, config)
|
||||
|
||||
expected := "Column | A Column | B Column | C\n"
|
||||
expected += "Value A Value B Value C"
|
||||
|
||||
if output != expected {
|
||||
t.Fatalf("\nexpected:\n%s\n\ngot:\n%s", expected, output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAlternateSpacingString(t *testing.T) {
|
||||
input := []string{
|
||||
"Column A | Column B | Column C",
|
||||
"x | y | z",
|
||||
}
|
||||
|
||||
config := DefaultConfig()
|
||||
config.Glue = " "
|
||||
output := Format(input, config)
|
||||
|
||||
expected := "Column A Column B Column C\n"
|
||||
expected += "x y z"
|
||||
|
||||
if output != expected {
|
||||
t.Fatalf("\nexpected:\n%s\n\ngot:\n%s", expected, output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSimpleFormat(t *testing.T) {
|
||||
input := []string{
|
||||
"Column A | Column B | Column C",
|
||||
"x | y | z",
|
||||
}
|
||||
|
||||
output := SimpleFormat(input)
|
||||
|
||||
expected := "Column A Column B Column C\n"
|
||||
expected += "x y z"
|
||||
|
||||
if output != expected {
|
||||
t.Fatalf("\nexpected:\n%s\n\ngot:\n%s", expected, output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAlternatePrefixString(t *testing.T) {
|
||||
input := []string{
|
||||
"Column A | Column B | Column C",
|
||||
"x | y | z",
|
||||
}
|
||||
|
||||
config := DefaultConfig()
|
||||
config.Prefix = " "
|
||||
output := Format(input, config)
|
||||
|
||||
expected := " Column A Column B Column C\n"
|
||||
expected += " x y z"
|
||||
|
||||
if output != expected {
|
||||
t.Fatalf("\nexpected:\n%s\n\ngot:\n%s", expected, output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmptyFieldReplacement(t *testing.T) {
|
||||
input := []string{
|
||||
"Column A | Column B | Column C",
|
||||
"x | | z",
|
||||
}
|
||||
|
||||
config := DefaultConfig()
|
||||
config.Empty = "<none>"
|
||||
output := Format(input, config)
|
||||
|
||||
expected := "Column A Column B Column C\n"
|
||||
expected += "x <none> z"
|
||||
|
||||
if output != expected {
|
||||
t.Fatalf("\nexpected:\n%s\n\ngot:\n%s", expected, output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmptyConfigValues(t *testing.T) {
|
||||
input := []string{
|
||||
"Column A | Column B | Column C",
|
||||
"x | y | z",
|
||||
}
|
||||
|
||||
config := Config{}
|
||||
output := Format(input, &config)
|
||||
|
||||
expected := "Column A Column B Column C\n"
|
||||
expected += "x y z"
|
||||
|
||||
if output != expected {
|
||||
t.Fatalf("\nexpected:\n%s\n\ngot:\n%s", expected, output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeConfig(t *testing.T) {
|
||||
conf1 := &Config{Delim: "a", Glue: "a", Prefix: "a", Empty: "a"}
|
||||
conf2 := &Config{Delim: "b", Glue: "b", Prefix: "b", Empty: "b"}
|
||||
conf3 := &Config{Delim: "c", Prefix: "c"}
|
||||
|
||||
m := MergeConfig(conf1, conf2)
|
||||
if m.Delim != "b" || m.Glue != "b" || m.Prefix != "b" || m.Empty != "b" {
|
||||
t.Fatalf("bad: %#v", m)
|
||||
}
|
||||
|
||||
m = MergeConfig(conf1, conf3)
|
||||
if m.Delim != "c" || m.Glue != "a" || m.Prefix != "c" || m.Empty != "a" {
|
||||
t.Fatalf("bad: %#v", m)
|
||||
}
|
||||
|
||||
m = MergeConfig(conf1, nil)
|
||||
if m.Delim != "a" || m.Glue != "a" || m.Prefix != "a" || m.Empty != "a" {
|
||||
t.Fatalf("bad: %#v", m)
|
||||
}
|
||||
|
||||
m = MergeConfig(conf1, &Config{})
|
||||
if m.Delim != "a" || m.Glue != "a" || m.Prefix != "a" || m.Empty != "a" {
|
||||
t.Fatalf("bad: %#v", m)
|
||||
}
|
||||
}
|
||||
@@ -10,30 +10,28 @@ import (
|
||||
)
|
||||
|
||||
// CommandClone clones an app
|
||||
func CommandClone(args []string, skipDeploy bool, ignoreExisting bool) error {
|
||||
oldAppName, err := getAppName(args)
|
||||
if err != nil {
|
||||
func CommandClone(oldAppName string, newAppName string, skipDeploy bool, ignoreExisting bool) error {
|
||||
if oldAppName == "" {
|
||||
return errors.New("Please specify an app to run the command on")
|
||||
}
|
||||
|
||||
if newAppName == "" {
|
||||
return errors.New("Please specify an new app name")
|
||||
}
|
||||
|
||||
if err := common.IsValidAppName(oldAppName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newAppName, err := getNewAppName(args)
|
||||
if err != nil {
|
||||
if err := common.IsValidAppName(newAppName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = common.IsValidAppName(oldAppName); err != nil {
|
||||
if err := appExists(oldAppName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = common.IsValidAppName(newAppName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = appExists(oldAppName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = appExists(newAppName); err == nil {
|
||||
if err := appExists(newAppName); err == nil {
|
||||
if ignoreExisting {
|
||||
common.LogWarn("Name is already taken")
|
||||
return nil
|
||||
@@ -43,11 +41,11 @@ func CommandClone(args []string, skipDeploy bool, ignoreExisting bool) error {
|
||||
}
|
||||
|
||||
common.LogInfo1Quiet(fmt.Sprintf("Cloning %s to %s", oldAppName, newAppName))
|
||||
if err = createApp(newAppName); err != nil {
|
||||
if err := createApp(newAppName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = common.PlugnTrigger("post-app-clone-setup", []string{oldAppName, newAppName}...); err != nil {
|
||||
if err := common.PlugnTrigger("post-app-clone-setup", []string{oldAppName, newAppName}...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -55,7 +53,7 @@ func CommandClone(args []string, skipDeploy bool, ignoreExisting bool) error {
|
||||
os.Setenv("SKIP_REBUILD", "true")
|
||||
}
|
||||
|
||||
if err = common.PlugnTrigger("post-app-clone", []string{oldAppName, newAppName}...); err != nil {
|
||||
if err := common.PlugnTrigger("post-app-clone", []string{oldAppName, newAppName}...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -63,48 +61,38 @@ func CommandClone(args []string, skipDeploy bool, ignoreExisting bool) error {
|
||||
}
|
||||
|
||||
// CommandCreate creates app via command line
|
||||
func CommandCreate(args []string) error {
|
||||
appName, err := getAppName(args)
|
||||
if err != nil {
|
||||
return err
|
||||
func CommandCreate(appName string) error {
|
||||
if appName == "" {
|
||||
return errors.New("Please specify an app to run the command on")
|
||||
}
|
||||
|
||||
return createApp(appName)
|
||||
}
|
||||
|
||||
// CommandDestroy destroys an app
|
||||
func CommandDestroy(args []string) error {
|
||||
appName, err := getAppName(args)
|
||||
if err != nil {
|
||||
return err
|
||||
func CommandDestroy(appName string, force bool) error {
|
||||
if appName == "" {
|
||||
return errors.New("Please specify an app to run the command on")
|
||||
}
|
||||
|
||||
if appName == "tls" {
|
||||
return errors.New("Unable to destroy tls directory")
|
||||
}
|
||||
|
||||
if len(args) >= 2 {
|
||||
force := args[1]
|
||||
if force == "force" {
|
||||
os.Setenv("DOKKU_APPS_FORCE_DELETE", "1")
|
||||
}
|
||||
if force {
|
||||
os.Setenv("DOKKU_APPS_FORCE_DELETE", "1")
|
||||
}
|
||||
|
||||
return destroyApp(appName)
|
||||
}
|
||||
|
||||
// CommandExists checks if an app exists
|
||||
func CommandExists(args []string) error {
|
||||
appName, err := getAppName(args)
|
||||
if err != nil {
|
||||
return err
|
||||
func CommandExists(appName string) error {
|
||||
if appName == "" {
|
||||
return errors.New("Please specify an app to run the command on")
|
||||
}
|
||||
|
||||
return appExists(appName)
|
||||
}
|
||||
|
||||
// CommandList lists all apps
|
||||
func CommandList(args []string) error {
|
||||
func CommandList() error {
|
||||
common.LogInfo2Quiet("My Apps")
|
||||
apps, err := common.DokkuApps()
|
||||
if err != nil {
|
||||
@@ -120,10 +108,9 @@ func CommandList(args []string) error {
|
||||
}
|
||||
|
||||
// CommandLock locks an app for deployment
|
||||
func CommandLock(args []string) error {
|
||||
appName, err := getAppName(args)
|
||||
if err != nil {
|
||||
return err
|
||||
func CommandLock(appName string) error {
|
||||
if appName == "" {
|
||||
return errors.New("Please specify an app to run the command on")
|
||||
}
|
||||
|
||||
if err := common.VerifyAppName(appName); err != nil {
|
||||
@@ -131,7 +118,7 @@ func CommandLock(args []string) error {
|
||||
}
|
||||
|
||||
lockfilePath := fmt.Sprintf("%v/.deploy.lock", common.AppRoot(appName))
|
||||
if _, err = os.Create(lockfilePath); err != nil {
|
||||
if _, err := os.Create(lockfilePath); err != nil {
|
||||
return errors.New("Unable to create deploy lock")
|
||||
}
|
||||
|
||||
@@ -140,10 +127,9 @@ func CommandLock(args []string) error {
|
||||
}
|
||||
|
||||
// CommandLocked checks if an app is locked for deployment
|
||||
func CommandLocked(args []string) error {
|
||||
appName, err := getAppName(args)
|
||||
if err != nil {
|
||||
return err
|
||||
func CommandLocked(appName string) error {
|
||||
if appName == "" {
|
||||
return errors.New("Please specify an app to run the command on")
|
||||
}
|
||||
|
||||
if err := common.VerifyAppName(appName); err != nil {
|
||||
@@ -159,44 +145,42 @@ func CommandLocked(args []string) error {
|
||||
}
|
||||
|
||||
// CommandRename renames an app
|
||||
func CommandRename(args []string, skipDeploy bool) error {
|
||||
oldAppName, err := getAppName(args)
|
||||
if err != nil {
|
||||
func CommandRename(oldAppName string, newAppName string, skipDeploy bool) error {
|
||||
if oldAppName == "" {
|
||||
return errors.New("Please specify an app to run the command on")
|
||||
}
|
||||
|
||||
if newAppName == "" {
|
||||
return errors.New("Please specify an new app name")
|
||||
}
|
||||
|
||||
if err := common.IsValidAppName(oldAppName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newAppName, err := getNewAppName(args)
|
||||
if err != nil {
|
||||
if err := common.IsValidAppName(newAppName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = common.IsValidAppName(oldAppName); err != nil {
|
||||
if err := appExists(oldAppName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = common.IsValidAppName(newAppName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = appExists(oldAppName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = appExists(newAppName); err == nil {
|
||||
if err := appExists(newAppName); err == nil {
|
||||
return errors.New("Name is already taken")
|
||||
}
|
||||
|
||||
common.LogInfo1Quiet(fmt.Sprintf("Renaming %s to %s", oldAppName, newAppName))
|
||||
if err = createApp(newAppName); err != nil {
|
||||
if err := createApp(newAppName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = common.PlugnTrigger("post-app-rename-setup", []string{oldAppName, newAppName}...); err != nil {
|
||||
if err := common.PlugnTrigger("post-app-rename-setup", []string{oldAppName, newAppName}...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
os.Setenv("DOKKU_APPS_FORCE_DELETE", "1")
|
||||
if err = destroyApp(oldAppName); err != nil {
|
||||
if err := destroyApp(oldAppName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -204,7 +188,7 @@ func CommandRename(args []string, skipDeploy bool) error {
|
||||
os.Setenv("SKIP_REBUILD", "true")
|
||||
}
|
||||
|
||||
if err = common.PlugnTrigger("post-app-rename", []string{oldAppName, newAppName}...); err != nil {
|
||||
if err := common.PlugnTrigger("post-app-rename", []string{oldAppName, newAppName}...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -212,15 +196,9 @@ func CommandRename(args []string, skipDeploy bool) error {
|
||||
}
|
||||
|
||||
// CommandReport displays an app report for one or more apps
|
||||
func CommandReport(args []string) error {
|
||||
appName, err := getAppName(args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
infoFlag := ""
|
||||
if len(args) > 1 {
|
||||
infoFlag = args[1]
|
||||
func CommandReport(appName string, infoFlag string) error {
|
||||
if appName == "" {
|
||||
return errors.New("Please specify an app to run the command on")
|
||||
}
|
||||
|
||||
if strings.HasPrefix(appName, "--") {
|
||||
@@ -245,10 +223,9 @@ func CommandReport(args []string) error {
|
||||
}
|
||||
|
||||
// CommandUnlock unlocks an app for deployment
|
||||
func CommandUnlock(args []string) error {
|
||||
appName, err := getAppName(args)
|
||||
if err != nil {
|
||||
return err
|
||||
func CommandUnlock(appName string) error {
|
||||
if appName == "" {
|
||||
return errors.New("Please specify an app to run the command on")
|
||||
}
|
||||
|
||||
if err := common.VerifyAppName(appName); err != nil {
|
||||
@@ -256,17 +233,15 @@ func CommandUnlock(args []string) error {
|
||||
}
|
||||
|
||||
lockfilePath := fmt.Sprintf("%v/.deploy.lock", common.AppRoot(appName))
|
||||
_, err = os.Stat(lockfilePath)
|
||||
if !os.IsNotExist(err) {
|
||||
if _, err := os.Stat(lockfilePath); !os.IsNotExist(err) {
|
||||
common.LogWarn("A deploy may be in progress.")
|
||||
common.LogWarn("Removing the app lock will not stop in progress deploys.")
|
||||
}
|
||||
|
||||
err = os.Remove(lockfilePath)
|
||||
if err == nil {
|
||||
common.LogInfo1("Deploy lock removed")
|
||||
return nil
|
||||
if err := os.Remove(lockfilePath); err != nil {
|
||||
return errors.New("Unable to remove deploy lock")
|
||||
}
|
||||
|
||||
return errors.New("Unable to remove deploy lock")
|
||||
common.LogInfo1("Deploy lock removed")
|
||||
return nil
|
||||
}
|
||||
|
||||
2
plugins/apps/vendor/github.com/codegangsta/inject/.gitignore
generated
vendored
2
plugins/apps/vendor/github.com/codegangsta/inject/.gitignore
generated
vendored
@@ -1,2 +0,0 @@
|
||||
inject
|
||||
inject.test
|
||||
20
plugins/apps/vendor/github.com/codegangsta/inject/LICENSE
generated
vendored
20
plugins/apps/vendor/github.com/codegangsta/inject/LICENSE
generated
vendored
@@ -1,20 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Jeremy Saenz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
92
plugins/apps/vendor/github.com/codegangsta/inject/README.md
generated
vendored
92
plugins/apps/vendor/github.com/codegangsta/inject/README.md
generated
vendored
@@ -1,92 +0,0 @@
|
||||
# inject
|
||||
--
|
||||
import "github.com/codegangsta/inject"
|
||||
|
||||
Package inject provides utilities for mapping and injecting dependencies in
|
||||
various ways.
|
||||
|
||||
Language Translations:
|
||||
* [简体中文](translations/README_zh_cn.md)
|
||||
|
||||
## Usage
|
||||
|
||||
#### func InterfaceOf
|
||||
|
||||
```go
|
||||
func InterfaceOf(value interface{}) reflect.Type
|
||||
```
|
||||
InterfaceOf dereferences a pointer to an Interface type. It panics if value is
|
||||
not an pointer to an interface.
|
||||
|
||||
#### type Applicator
|
||||
|
||||
```go
|
||||
type Applicator interface {
|
||||
// Maps dependencies in the Type map to each field in the struct
|
||||
// that is tagged with 'inject'. Returns an error if the injection
|
||||
// fails.
|
||||
Apply(interface{}) error
|
||||
}
|
||||
```
|
||||
|
||||
Applicator represents an interface for mapping dependencies to a struct.
|
||||
|
||||
#### type Injector
|
||||
|
||||
```go
|
||||
type Injector interface {
|
||||
Applicator
|
||||
Invoker
|
||||
TypeMapper
|
||||
// SetParent sets the parent of the injector. If the injector cannot find a
|
||||
// dependency in its Type map it will check its parent before returning an
|
||||
// error.
|
||||
SetParent(Injector)
|
||||
}
|
||||
```
|
||||
|
||||
Injector represents an interface for mapping and injecting dependencies into
|
||||
structs and function arguments.
|
||||
|
||||
#### func New
|
||||
|
||||
```go
|
||||
func New() Injector
|
||||
```
|
||||
New returns a new Injector.
|
||||
|
||||
#### type Invoker
|
||||
|
||||
```go
|
||||
type Invoker interface {
|
||||
// Invoke attempts to call the interface{} provided as a function,
|
||||
// providing dependencies for function arguments based on Type. Returns
|
||||
// a slice of reflect.Value representing the returned values of the function.
|
||||
// Returns an error if the injection fails.
|
||||
Invoke(interface{}) ([]reflect.Value, error)
|
||||
}
|
||||
```
|
||||
|
||||
Invoker represents an interface for calling functions via reflection.
|
||||
|
||||
#### type TypeMapper
|
||||
|
||||
```go
|
||||
type TypeMapper interface {
|
||||
// Maps the interface{} value based on its immediate type from reflect.TypeOf.
|
||||
Map(interface{}) TypeMapper
|
||||
// Maps the interface{} value based on the pointer of an Interface provided.
|
||||
// This is really only useful for mapping a value as an interface, as interfaces
|
||||
// cannot at this time be referenced directly without a pointer.
|
||||
MapTo(interface{}, interface{}) TypeMapper
|
||||
// Provides a possibility to directly insert a mapping based on type and value.
|
||||
// This makes it possible to directly map type arguments not possible to instantiate
|
||||
// with reflect like unidirectional channels.
|
||||
Set(reflect.Type, reflect.Value) TypeMapper
|
||||
// Returns the Value that is mapped to the current type. Returns a zeroed Value if
|
||||
// the Type has not been mapped.
|
||||
Get(reflect.Type) reflect.Value
|
||||
}
|
||||
```
|
||||
|
||||
TypeMapper represents an interface for mapping interface{} values based on type.
|
||||
187
plugins/apps/vendor/github.com/codegangsta/inject/inject.go
generated
vendored
187
plugins/apps/vendor/github.com/codegangsta/inject/inject.go
generated
vendored
@@ -1,187 +0,0 @@
|
||||
// Package inject provides utilities for mapping and injecting dependencies in various ways.
|
||||
package inject
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Injector represents an interface for mapping and injecting dependencies into structs
|
||||
// and function arguments.
|
||||
type Injector interface {
|
||||
Applicator
|
||||
Invoker
|
||||
TypeMapper
|
||||
// SetParent sets the parent of the injector. If the injector cannot find a
|
||||
// dependency in its Type map it will check its parent before returning an
|
||||
// error.
|
||||
SetParent(Injector)
|
||||
}
|
||||
|
||||
// Applicator represents an interface for mapping dependencies to a struct.
|
||||
type Applicator interface {
|
||||
// Maps dependencies in the Type map to each field in the struct
|
||||
// that is tagged with 'inject'. Returns an error if the injection
|
||||
// fails.
|
||||
Apply(interface{}) error
|
||||
}
|
||||
|
||||
// Invoker represents an interface for calling functions via reflection.
|
||||
type Invoker interface {
|
||||
// Invoke attempts to call the interface{} provided as a function,
|
||||
// providing dependencies for function arguments based on Type. Returns
|
||||
// a slice of reflect.Value representing the returned values of the function.
|
||||
// Returns an error if the injection fails.
|
||||
Invoke(interface{}) ([]reflect.Value, error)
|
||||
}
|
||||
|
||||
// TypeMapper represents an interface for mapping interface{} values based on type.
|
||||
type TypeMapper interface {
|
||||
// Maps the interface{} value based on its immediate type from reflect.TypeOf.
|
||||
Map(interface{}) TypeMapper
|
||||
// Maps the interface{} value based on the pointer of an Interface provided.
|
||||
// This is really only useful for mapping a value as an interface, as interfaces
|
||||
// cannot at this time be referenced directly without a pointer.
|
||||
MapTo(interface{}, interface{}) TypeMapper
|
||||
// Provides a possibility to directly insert a mapping based on type and value.
|
||||
// This makes it possible to directly map type arguments not possible to instantiate
|
||||
// with reflect like unidirectional channels.
|
||||
Set(reflect.Type, reflect.Value) TypeMapper
|
||||
// Returns the Value that is mapped to the current type. Returns a zeroed Value if
|
||||
// the Type has not been mapped.
|
||||
Get(reflect.Type) reflect.Value
|
||||
}
|
||||
|
||||
type injector struct {
|
||||
values map[reflect.Type]reflect.Value
|
||||
parent Injector
|
||||
}
|
||||
|
||||
// InterfaceOf dereferences a pointer to an Interface type.
|
||||
// It panics if value is not an pointer to an interface.
|
||||
func InterfaceOf(value interface{}) reflect.Type {
|
||||
t := reflect.TypeOf(value)
|
||||
|
||||
for t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
|
||||
if t.Kind() != reflect.Interface {
|
||||
panic("Called inject.InterfaceOf with a value that is not a pointer to an interface. (*MyInterface)(nil)")
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
// New returns a new Injector.
|
||||
func New() Injector {
|
||||
return &injector{
|
||||
values: make(map[reflect.Type]reflect.Value),
|
||||
}
|
||||
}
|
||||
|
||||
// Invoke attempts to call the interface{} provided as a function,
|
||||
// providing dependencies for function arguments based on Type.
|
||||
// Returns a slice of reflect.Value representing the returned values of the function.
|
||||
// Returns an error if the injection fails.
|
||||
// It panics if f is not a function
|
||||
func (inj *injector) Invoke(f interface{}) ([]reflect.Value, error) {
|
||||
t := reflect.TypeOf(f)
|
||||
|
||||
var in = make([]reflect.Value, t.NumIn()) //Panic if t is not kind of Func
|
||||
for i := 0; i < t.NumIn(); i++ {
|
||||
argType := t.In(i)
|
||||
val := inj.Get(argType)
|
||||
if !val.IsValid() {
|
||||
return nil, fmt.Errorf("Value not found for type %v", argType)
|
||||
}
|
||||
|
||||
in[i] = val
|
||||
}
|
||||
|
||||
return reflect.ValueOf(f).Call(in), nil
|
||||
}
|
||||
|
||||
// Maps dependencies in the Type map to each field in the struct
|
||||
// that is tagged with 'inject'.
|
||||
// Returns an error if the injection fails.
|
||||
func (inj *injector) Apply(val interface{}) error {
|
||||
v := reflect.ValueOf(val)
|
||||
|
||||
for v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
|
||||
if v.Kind() != reflect.Struct {
|
||||
return nil // Should not panic here ?
|
||||
}
|
||||
|
||||
t := v.Type()
|
||||
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
f := v.Field(i)
|
||||
structField := t.Field(i)
|
||||
if f.CanSet() && (structField.Tag == "inject" || structField.Tag.Get("inject") != "") {
|
||||
ft := f.Type()
|
||||
v := inj.Get(ft)
|
||||
if !v.IsValid() {
|
||||
return fmt.Errorf("Value not found for type %v", ft)
|
||||
}
|
||||
|
||||
f.Set(v)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Maps the concrete value of val to its dynamic type using reflect.TypeOf,
|
||||
// It returns the TypeMapper registered in.
|
||||
func (i *injector) Map(val interface{}) TypeMapper {
|
||||
i.values[reflect.TypeOf(val)] = reflect.ValueOf(val)
|
||||
return i
|
||||
}
|
||||
|
||||
func (i *injector) MapTo(val interface{}, ifacePtr interface{}) TypeMapper {
|
||||
i.values[InterfaceOf(ifacePtr)] = reflect.ValueOf(val)
|
||||
return i
|
||||
}
|
||||
|
||||
// Maps the given reflect.Type to the given reflect.Value and returns
|
||||
// the Typemapper the mapping has been registered in.
|
||||
func (i *injector) Set(typ reflect.Type, val reflect.Value) TypeMapper {
|
||||
i.values[typ] = val
|
||||
return i
|
||||
}
|
||||
|
||||
func (i *injector) Get(t reflect.Type) reflect.Value {
|
||||
val := i.values[t]
|
||||
|
||||
if val.IsValid() {
|
||||
return val
|
||||
}
|
||||
|
||||
// no concrete types found, try to find implementors
|
||||
// if t is an interface
|
||||
if t.Kind() == reflect.Interface {
|
||||
for k, v := range i.values {
|
||||
if k.Implements(t) {
|
||||
val = v
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Still no type found, try to look it up on the parent
|
||||
if !val.IsValid() && i.parent != nil {
|
||||
val = i.parent.Get(t)
|
||||
}
|
||||
|
||||
return val
|
||||
|
||||
}
|
||||
|
||||
func (i *injector) SetParent(parent Injector) {
|
||||
i.parent = parent
|
||||
}
|
||||
159
plugins/apps/vendor/github.com/codegangsta/inject/inject_test.go
generated
vendored
159
plugins/apps/vendor/github.com/codegangsta/inject/inject_test.go
generated
vendored
@@ -1,159 +0,0 @@
|
||||
package inject_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/codegangsta/inject"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type SpecialString interface {
|
||||
}
|
||||
|
||||
type TestStruct struct {
|
||||
Dep1 string `inject:"t" json:"-"`
|
||||
Dep2 SpecialString `inject`
|
||||
Dep3 string
|
||||
}
|
||||
|
||||
type Greeter struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (g *Greeter) String() string {
|
||||
return "Hello, My name is" + g.Name
|
||||
}
|
||||
|
||||
/* Test Helpers */
|
||||
func expect(t *testing.T, a interface{}, b interface{}) {
|
||||
if a != b {
|
||||
t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
|
||||
}
|
||||
}
|
||||
|
||||
func refute(t *testing.T, a interface{}, b interface{}) {
|
||||
if a == b {
|
||||
t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
|
||||
}
|
||||
}
|
||||
|
||||
func Test_InjectorInvoke(t *testing.T) {
|
||||
injector := inject.New()
|
||||
expect(t, injector == nil, false)
|
||||
|
||||
dep := "some dependency"
|
||||
injector.Map(dep)
|
||||
dep2 := "another dep"
|
||||
injector.MapTo(dep2, (*SpecialString)(nil))
|
||||
dep3 := make(chan *SpecialString)
|
||||
dep4 := make(chan *SpecialString)
|
||||
typRecv := reflect.ChanOf(reflect.RecvDir, reflect.TypeOf(dep3).Elem())
|
||||
typSend := reflect.ChanOf(reflect.SendDir, reflect.TypeOf(dep4).Elem())
|
||||
injector.Set(typRecv, reflect.ValueOf(dep3))
|
||||
injector.Set(typSend, reflect.ValueOf(dep4))
|
||||
|
||||
_, err := injector.Invoke(func(d1 string, d2 SpecialString, d3 <-chan *SpecialString, d4 chan<- *SpecialString) {
|
||||
expect(t, d1, dep)
|
||||
expect(t, d2, dep2)
|
||||
expect(t, reflect.TypeOf(d3).Elem(), reflect.TypeOf(dep3).Elem())
|
||||
expect(t, reflect.TypeOf(d4).Elem(), reflect.TypeOf(dep4).Elem())
|
||||
expect(t, reflect.TypeOf(d3).ChanDir(), reflect.RecvDir)
|
||||
expect(t, reflect.TypeOf(d4).ChanDir(), reflect.SendDir)
|
||||
})
|
||||
|
||||
expect(t, err, nil)
|
||||
}
|
||||
|
||||
func Test_InjectorInvokeReturnValues(t *testing.T) {
|
||||
injector := inject.New()
|
||||
expect(t, injector == nil, false)
|
||||
|
||||
dep := "some dependency"
|
||||
injector.Map(dep)
|
||||
dep2 := "another dep"
|
||||
injector.MapTo(dep2, (*SpecialString)(nil))
|
||||
|
||||
result, err := injector.Invoke(func(d1 string, d2 SpecialString) string {
|
||||
expect(t, d1, dep)
|
||||
expect(t, d2, dep2)
|
||||
return "Hello world"
|
||||
})
|
||||
|
||||
expect(t, result[0].String(), "Hello world")
|
||||
expect(t, err, nil)
|
||||
}
|
||||
|
||||
func Test_InjectorApply(t *testing.T) {
|
||||
injector := inject.New()
|
||||
|
||||
injector.Map("a dep").MapTo("another dep", (*SpecialString)(nil))
|
||||
|
||||
s := TestStruct{}
|
||||
err := injector.Apply(&s)
|
||||
expect(t, err, nil)
|
||||
|
||||
expect(t, s.Dep1, "a dep")
|
||||
expect(t, s.Dep2, "another dep")
|
||||
expect(t, s.Dep3, "")
|
||||
}
|
||||
|
||||
func Test_InterfaceOf(t *testing.T) {
|
||||
iType := inject.InterfaceOf((*SpecialString)(nil))
|
||||
expect(t, iType.Kind(), reflect.Interface)
|
||||
|
||||
iType = inject.InterfaceOf((**SpecialString)(nil))
|
||||
expect(t, iType.Kind(), reflect.Interface)
|
||||
|
||||
// Expecting nil
|
||||
defer func() {
|
||||
rec := recover()
|
||||
refute(t, rec, nil)
|
||||
}()
|
||||
iType = inject.InterfaceOf((*testing.T)(nil))
|
||||
}
|
||||
|
||||
func Test_InjectorSet(t *testing.T) {
|
||||
injector := inject.New()
|
||||
typ := reflect.TypeOf("string")
|
||||
typSend := reflect.ChanOf(reflect.SendDir, typ)
|
||||
typRecv := reflect.ChanOf(reflect.RecvDir, typ)
|
||||
|
||||
// instantiating unidirectional channels is not possible using reflect
|
||||
// http://golang.org/src/pkg/reflect/value.go?s=60463:60504#L2064
|
||||
chanRecv := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, typ), 0)
|
||||
chanSend := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, typ), 0)
|
||||
|
||||
injector.Set(typSend, chanSend)
|
||||
injector.Set(typRecv, chanRecv)
|
||||
|
||||
expect(t, injector.Get(typSend).IsValid(), true)
|
||||
expect(t, injector.Get(typRecv).IsValid(), true)
|
||||
expect(t, injector.Get(chanSend.Type()).IsValid(), false)
|
||||
}
|
||||
|
||||
func Test_InjectorGet(t *testing.T) {
|
||||
injector := inject.New()
|
||||
|
||||
injector.Map("some dependency")
|
||||
|
||||
expect(t, injector.Get(reflect.TypeOf("string")).IsValid(), true)
|
||||
expect(t, injector.Get(reflect.TypeOf(11)).IsValid(), false)
|
||||
}
|
||||
|
||||
func Test_InjectorSetParent(t *testing.T) {
|
||||
injector := inject.New()
|
||||
injector.MapTo("another dep", (*SpecialString)(nil))
|
||||
|
||||
injector2 := inject.New()
|
||||
injector2.SetParent(injector)
|
||||
|
||||
expect(t, injector2.Get(inject.InterfaceOf((*SpecialString)(nil))).IsValid(), true)
|
||||
}
|
||||
|
||||
func TestInjectImplementors(t *testing.T) {
|
||||
injector := inject.New()
|
||||
g := &Greeter{"Jeremy"}
|
||||
injector.Map(g)
|
||||
|
||||
expect(t, injector.Get(inject.InterfaceOf((*fmt.Stringer)(nil))).IsValid(), true)
|
||||
}
|
||||
85
plugins/apps/vendor/github.com/codegangsta/inject/translations/README_zh_cn.md
generated
vendored
85
plugins/apps/vendor/github.com/codegangsta/inject/translations/README_zh_cn.md
generated
vendored
@@ -1,85 +0,0 @@
|
||||
# inject
|
||||
--
|
||||
import "github.com/codegangsta/inject"
|
||||
|
||||
inject包提供了多种对实体的映射和依赖注入方式。
|
||||
|
||||
## 用法
|
||||
|
||||
#### func InterfaceOf
|
||||
|
||||
```go
|
||||
func InterfaceOf(value interface{}) reflect.Type
|
||||
```
|
||||
函数InterfaceOf返回指向接口类型的指针。如果传入的value值不是指向接口的指针,将抛出一个panic异常。
|
||||
|
||||
#### type Applicator
|
||||
|
||||
```go
|
||||
type Applicator interface {
|
||||
// 在Type map中维持对结构体中每个域的引用并用'inject'来标记
|
||||
// 如果注入失败将会返回一个error.
|
||||
Apply(interface{}) error
|
||||
}
|
||||
```
|
||||
|
||||
Applicator接口表示到结构体的依赖映射关系。
|
||||
|
||||
#### type Injector
|
||||
|
||||
```go
|
||||
type Injector interface {
|
||||
Applicator
|
||||
Invoker
|
||||
TypeMapper
|
||||
// SetParent用来设置父injector. 如果在当前injector的Type map中找不到依赖,
|
||||
// 将会继续从它的父injector中找,直到返回error.
|
||||
SetParent(Injector)
|
||||
}
|
||||
```
|
||||
|
||||
Injector接口表示对结构体、函数参数的映射和依赖注入。
|
||||
|
||||
#### func New
|
||||
|
||||
```go
|
||||
func New() Injector
|
||||
```
|
||||
New创建并返回一个Injector.
|
||||
|
||||
#### type Invoker
|
||||
|
||||
```go
|
||||
type Invoker interface {
|
||||
// Invoke尝试将interface{}作为一个函数来调用,并基于Type为函数提供参数。
|
||||
// 它将返回reflect.Value的切片,其中存放原函数的返回值。
|
||||
// 如果注入失败则返回error.
|
||||
Invoke(interface{}) ([]reflect.Value, error)
|
||||
}
|
||||
```
|
||||
|
||||
Invoker接口表示通过反射进行函数调用。
|
||||
|
||||
#### type TypeMapper
|
||||
|
||||
```go
|
||||
type TypeMapper interface {
|
||||
// 基于调用reflect.TypeOf得到的类型映射interface{}的值。
|
||||
Map(interface{}) TypeMapper
|
||||
// 基于提供的接口的指针映射interface{}的值。
|
||||
// 该函数仅用来将一个值映射为接口,因为接口无法不通过指针而直接引用到。
|
||||
MapTo(interface{}, interface{}) TypeMapper
|
||||
// 为直接插入基于类型和值的map提供一种可能性。
|
||||
// 它使得这一类直接映射成为可能:无法通过反射直接实例化的类型参数,如单向管道。
|
||||
Set(reflect.Type, reflect.Value) TypeMapper
|
||||
// 返回映射到当前类型的Value. 如果Type没被映射,将返回对应的零值。
|
||||
Get(reflect.Type) reflect.Value
|
||||
}
|
||||
```
|
||||
|
||||
TypeMapper接口用来表示基于类型到接口值的映射。
|
||||
|
||||
|
||||
## 译者
|
||||
|
||||
张强 (qqbunny@yeah.net)
|
||||
3
plugins/apps/vendor/github.com/codegangsta/inject/update_readme.sh
generated
vendored
3
plugins/apps/vendor/github.com/codegangsta/inject/update_readme.sh
generated
vendored
@@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
go get github.com/robertkrimen/godocdown/godocdown
|
||||
godocdown >README.md
|
||||
202
plugins/apps/vendor/github.com/codeskyblue/go-sh/LICENSE
generated
vendored
202
plugins/apps/vendor/github.com/codeskyblue/go-sh/LICENSE
generated
vendored
@@ -1,202 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
69
plugins/apps/vendor/github.com/codeskyblue/go-sh/OLD_README.md
generated
vendored
69
plugins/apps/vendor/github.com/codeskyblue/go-sh/OLD_README.md
generated
vendored
@@ -1,69 +0,0 @@
|
||||
## OLD README
|
||||
First give you a full example, I will explain every command below.
|
||||
|
||||
session := sh.NewSession()
|
||||
session.Env["PATH"] = "/usr/bin:/bin"
|
||||
session.Stdout = os.Stdout
|
||||
session.Stderr = os.Stderr
|
||||
session.Alias("ll", "ls", "-l")
|
||||
session.ShowCMD = true // enable for debug
|
||||
var err error
|
||||
err = session.Call("ll", "/")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ret, err := session.Capture("pwd", sh.Dir("/home")) # wraper of session.Call
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
# ret is "/home\n"
|
||||
fmt.Println(ret)
|
||||
|
||||
create a new Session
|
||||
|
||||
session := sh.NewSession()
|
||||
|
||||
use alias like this
|
||||
|
||||
session.Alias("ll", "ls", "-l") # like alias ll='ls -l'
|
||||
|
||||
set current env like this
|
||||
|
||||
session.Env["BUILD_ID"] = "123" # like export BUILD_ID=123
|
||||
|
||||
set current directory
|
||||
|
||||
session.Set(sh.Dir("/")) # like cd /
|
||||
|
||||
pipe is also supported
|
||||
|
||||
session.Command("echo", "hello\tworld").Command("cut", "-f2")
|
||||
// output should be "world"
|
||||
session.Run()
|
||||
|
||||
test, the build in command support
|
||||
|
||||
session.Test("d", "dir") // test dir
|
||||
session.Test("f", "file) // test regular file
|
||||
|
||||
with `Alias Env Set Call Capture Command` a shell scripts can be easily converted into golang program. below is a shell script.
|
||||
|
||||
#!/bin/bash -
|
||||
#
|
||||
export PATH=/usr/bin:/bin
|
||||
alias ll='ls -l'
|
||||
cd /usr
|
||||
if test -d "local"
|
||||
then
|
||||
ll local | awk '{print $1, $NF}'
|
||||
fi
|
||||
|
||||
convert to golang, will be
|
||||
|
||||
s := sh.NewSession()
|
||||
s.Env["PATH"] = "/usr/bin:/bin"
|
||||
s.Set(sh.Dir("/usr"))
|
||||
s.Alias("ll", "ls", "-l")
|
||||
if s.Test("d", "local") {
|
||||
s.Command("ll", "local").Command("awk", "{print $1, $NF}").Run()
|
||||
}
|
||||
85
plugins/apps/vendor/github.com/codeskyblue/go-sh/README.md
generated
vendored
85
plugins/apps/vendor/github.com/codeskyblue/go-sh/README.md
generated
vendored
@@ -1,85 +0,0 @@
|
||||
## go-sh
|
||||
[](https://app.wercker.com/project/bykey/009acbd4f00ccc6de7e2554e12a50d84)
|
||||
[](http://gowalker.org/github.com/codeskyblue/go-sh)
|
||||
|
||||
*If you depend on the old api, see tag: v.0.1*
|
||||
|
||||
install: `go get github.com/codeskyblue/go-sh`
|
||||
|
||||
Pipe Example:
|
||||
|
||||
package main
|
||||
|
||||
import "github.com/codeskyblue/go-sh"
|
||||
|
||||
func main() {
|
||||
sh.Command("echo", "hello\tworld").Command("cut", "-f2").Run()
|
||||
}
|
||||
|
||||
Because I like os/exec, `go-sh` is very much modelled after it. However, `go-sh` provides a better experience.
|
||||
|
||||
These are some of its features:
|
||||
|
||||
* keep the variable environment (e.g. export)
|
||||
* alias support (e.g. alias in shell)
|
||||
* remember current dir
|
||||
* pipe command
|
||||
* shell build-in commands echo & test
|
||||
* timeout support
|
||||
|
||||
Examples are important:
|
||||
|
||||
sh: echo hello
|
||||
go: sh.Command("echo", "hello").Run()
|
||||
|
||||
sh: export BUILD_ID=123
|
||||
go: s = sh.NewSession().SetEnv("BUILD_ID", "123")
|
||||
|
||||
sh: alias ll='ls -l'
|
||||
go: s = sh.NewSession().Alias('ll', 'ls', '-l')
|
||||
|
||||
sh: (cd /; pwd)
|
||||
go: sh.Command("pwd", sh.Dir("/")).Run()
|
||||
|
||||
sh: test -d data || mkdir data
|
||||
go: if ! sh.Test("dir", "data") { sh.Command("mkdir", "data").Run() }
|
||||
|
||||
sh: cat first second | awk '{print $1}'
|
||||
go: sh.Command("cat", "first", "second").Command("awk", "{print $1}").Run()
|
||||
|
||||
sh: count=$(echo "one two three" | wc -w)
|
||||
go: count, err := sh.Echo("one two three").Command("wc", "-w").Output()
|
||||
|
||||
sh(in ubuntu): timeout 1s sleep 3
|
||||
go: c := sh.Command("sleep", "3"); c.Start(); c.WaitTimeout(time.Second) # default SIGKILL
|
||||
go: out, err := sh.Command("sleep", "3").SetTimeout(time.Second).Output() # set session timeout and get output)
|
||||
|
||||
sh: echo hello | cat
|
||||
go: out, err := sh.Command("cat").SetInput("hello").Output()
|
||||
|
||||
sh: cat # read from stdin
|
||||
go: out, err := sh.Command("cat").SetStdin(os.Stdin).Output()
|
||||
|
||||
If you need to keep env and dir, it is better to create a session
|
||||
|
||||
session := sh.NewSession()
|
||||
session.SetEnv("BUILD_ID", "123")
|
||||
session.SetDir("/")
|
||||
# then call cmd
|
||||
session.Command("echo", "hello").Run()
|
||||
# set ShowCMD to true for easily debug
|
||||
session.ShowCMD = true
|
||||
|
||||
for more information, it better to see docs.
|
||||
[](http://gowalker.org/github.com/codeskyblue/go-sh)
|
||||
|
||||
### contribute
|
||||
If you love this project, starring it will encourage the coder. Pull requests are welcome.
|
||||
|
||||
support the author: [alipay](https://me.alipay.com/goskyblue)
|
||||
|
||||
### thanks
|
||||
this project is based on <http://github.com/codegangsta/inject>. thanks for the author.
|
||||
|
||||
# the reason to use Go shell
|
||||
Sometimes we need to write shell scripts, but shell scripts are not good at working cross platform, Go, on the other hand, is good at that. Is there a good way to use Go to write shell like scripts? Using go-sh we can do this now.
|
||||
41
plugins/apps/vendor/github.com/codeskyblue/go-sh/example/example1.go
generated
vendored
41
plugins/apps/vendor/github.com/codeskyblue/go-sh/example/example1.go
generated
vendored
@@ -1,41 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/codeskyblue/go-sh"
|
||||
)
|
||||
|
||||
func main() {
|
||||
sh.Command("echo", "hello").Run()
|
||||
out, err := sh.Command("echo", "hello").Output()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println("output is", string(out))
|
||||
|
||||
var a int
|
||||
sh.Command("echo", "2").UnmarshalJSON(&a)
|
||||
fmt.Println("a =", a)
|
||||
|
||||
s := sh.NewSession()
|
||||
s.Alias("hi", "echo", "hi")
|
||||
s.Command("hi", "boy").Run()
|
||||
|
||||
fmt.Print("pwd = ")
|
||||
s.Command("pwd", sh.Dir("/")).Run()
|
||||
|
||||
if !sh.Test("dir", "data") {
|
||||
sh.Command("echo", "mkdir", "data").Run()
|
||||
}
|
||||
|
||||
sh.Command("echo", "hello", "world").
|
||||
Command("awk", `{print "second arg is "$2}`).Run()
|
||||
s.ShowCMD = true
|
||||
s.Command("echo", "hello", "world").
|
||||
Command("awk", `{print "second arg is "$2}`).Run()
|
||||
|
||||
s.SetEnv("BUILD_ID", "123").Command("bash", "-c", "echo $BUILD_ID").Run()
|
||||
s.Command("bash", "-c", "echo current shell is $SHELL").Run()
|
||||
}
|
||||
7
plugins/apps/vendor/github.com/codeskyblue/go-sh/example/less/less.go
generated
vendored
7
plugins/apps/vendor/github.com/codeskyblue/go-sh/example/less/less.go
generated
vendored
@@ -1,7 +0,0 @@
|
||||
package main
|
||||
|
||||
import "github.com/codeskyblue/go-sh"
|
||||
|
||||
func main() {
|
||||
sh.Command("less", "less.go").Run()
|
||||
}
|
||||
17
plugins/apps/vendor/github.com/codeskyblue/go-sh/example/tail/tailf.go
generated
vendored
17
plugins/apps/vendor/github.com/codeskyblue/go-sh/example/tail/tailf.go
generated
vendored
@@ -1,17 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"github.com/codeskyblue/go-sh"
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
if flag.NArg() != 1 {
|
||||
fmt.Println("Usage: PROGRAM <file>")
|
||||
return
|
||||
}
|
||||
sh.Command("tail", "-f", flag.Arg(0)).Run()
|
||||
}
|
||||
23
plugins/apps/vendor/github.com/codeskyblue/go-sh/example/timeout/timeout.go
generated
vendored
23
plugins/apps/vendor/github.com/codeskyblue/go-sh/example/timeout/timeout.go
generated
vendored
@@ -1,23 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
sh "github.com/codeskyblue/go-sh"
|
||||
)
|
||||
|
||||
func main() {
|
||||
c := sh.Command("sleep", "3")
|
||||
c.Start()
|
||||
err := c.WaitTimeout(time.Second * 1)
|
||||
if err != nil {
|
||||
fmt.Printf("timeout should happend: %v\n", err)
|
||||
}
|
||||
// timeout should be a session
|
||||
out, err := sh.Command("sleep", "2").SetTimeout(time.Second).Output()
|
||||
fmt.Printf("output:(%s), err(%v)\n", string(out), err)
|
||||
|
||||
out, err = sh.Command("echo", "hello").SetTimeout(time.Second).Output()
|
||||
fmt.Printf("output:(%s), err(%v)\n", string(out), err)
|
||||
}
|
||||
28
plugins/apps/vendor/github.com/codeskyblue/go-sh/example_test.go
generated
vendored
28
plugins/apps/vendor/github.com/codeskyblue/go-sh/example_test.go
generated
vendored
@@ -1,28 +0,0 @@
|
||||
package sh_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/codeskyblue/go-sh"
|
||||
)
|
||||
|
||||
func ExampleCommand() {
|
||||
out, err := sh.Command("echo", "hello").Output()
|
||||
fmt.Println(string(out), err)
|
||||
}
|
||||
|
||||
func ExampleCommandPipe() {
|
||||
out, err := sh.Command("echo", "-n", "hi").Command("wc", "-c").Output()
|
||||
fmt.Println(string(out), err)
|
||||
}
|
||||
|
||||
func ExampleCommandSetDir() {
|
||||
out, err := sh.Command("pwd", sh.Dir("/")).Output()
|
||||
fmt.Println(string(out), err)
|
||||
}
|
||||
|
||||
func ExampleTest() {
|
||||
if sh.Test("dir", "mydir") {
|
||||
fmt.Println("mydir exists")
|
||||
}
|
||||
}
|
||||
148
plugins/apps/vendor/github.com/codeskyblue/go-sh/pipe.go
generated
vendored
148
plugins/apps/vendor/github.com/codeskyblue/go-sh/pipe.go
generated
vendored
@@ -1,148 +0,0 @@
|
||||
package sh
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
var ErrExecTimeout = errors.New("execute timeout")
|
||||
|
||||
// unmarshal shell output to decode json
|
||||
func (s *Session) UnmarshalJSON(data interface{}) (err error) {
|
||||
bufrw := bytes.NewBuffer(nil)
|
||||
s.Stdout = bufrw
|
||||
if err = s.Run(); err != nil {
|
||||
return
|
||||
}
|
||||
return json.NewDecoder(bufrw).Decode(data)
|
||||
}
|
||||
|
||||
// unmarshal command output into xml
|
||||
func (s *Session) UnmarshalXML(data interface{}) (err error) {
|
||||
bufrw := bytes.NewBuffer(nil)
|
||||
s.Stdout = bufrw
|
||||
if err = s.Run(); err != nil {
|
||||
return
|
||||
}
|
||||
return xml.NewDecoder(bufrw).Decode(data)
|
||||
}
|
||||
|
||||
// start command
|
||||
func (s *Session) Start() (err error) {
|
||||
s.started = true
|
||||
var rd *io.PipeReader
|
||||
var wr *io.PipeWriter
|
||||
var length = len(s.cmds)
|
||||
if s.ShowCMD {
|
||||
var cmds = make([]string, 0, 4)
|
||||
for _, cmd := range s.cmds {
|
||||
cmds = append(cmds, strings.Join(cmd.Args, " "))
|
||||
}
|
||||
s.writePrompt(strings.Join(cmds, " | "))
|
||||
}
|
||||
for index, cmd := range s.cmds {
|
||||
if index == 0 {
|
||||
cmd.Stdin = s.Stdin
|
||||
} else {
|
||||
cmd.Stdin = rd
|
||||
}
|
||||
if index != length {
|
||||
rd, wr = io.Pipe() // create pipe
|
||||
cmd.Stdout = wr
|
||||
cmd.Stderr = os.Stderr
|
||||
}
|
||||
if index == length-1 {
|
||||
cmd.Stdout = s.Stdout
|
||||
cmd.Stderr = s.Stderr
|
||||
}
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Should be call after Start()
|
||||
// only catch the last command error
|
||||
func (s *Session) Wait() (err error) {
|
||||
for _, cmd := range s.cmds {
|
||||
err = cmd.Wait()
|
||||
wr, ok := cmd.Stdout.(*io.PipeWriter)
|
||||
if ok {
|
||||
wr.Close()
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Session) Kill(sig os.Signal) {
|
||||
for _, cmd := range s.cmds {
|
||||
if cmd.Process != nil {
|
||||
cmd.Process.Signal(sig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Session) WaitTimeout(timeout time.Duration) (err error) {
|
||||
select {
|
||||
case <-time.After(timeout):
|
||||
s.Kill(syscall.SIGKILL)
|
||||
return ErrExecTimeout
|
||||
case err = <-Go(s.Wait):
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func Go(f func() error) chan error {
|
||||
ch := make(chan error)
|
||||
go func() {
|
||||
ch <- f()
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
|
||||
func (s *Session) Run() (err error) {
|
||||
if err = s.Start(); err != nil {
|
||||
return
|
||||
}
|
||||
if s.timeout != time.Duration(0) {
|
||||
return s.WaitTimeout(s.timeout)
|
||||
}
|
||||
return s.Wait()
|
||||
}
|
||||
|
||||
func (s *Session) Output() (out []byte, err error) {
|
||||
oldout := s.Stdout
|
||||
defer func() {
|
||||
s.Stdout = oldout
|
||||
}()
|
||||
stdout := bytes.NewBuffer(nil)
|
||||
s.Stdout = stdout
|
||||
err = s.Run()
|
||||
out = stdout.Bytes()
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Session) CombinedOutput() (out []byte, err error) {
|
||||
oldout := s.Stdout
|
||||
olderr := s.Stderr
|
||||
defer func() {
|
||||
s.Stdout = oldout
|
||||
s.Stderr = olderr
|
||||
}()
|
||||
stdout := bytes.NewBuffer(nil)
|
||||
s.Stdout = stdout
|
||||
s.Stderr = stdout
|
||||
|
||||
err = s.Run()
|
||||
out = stdout.Bytes()
|
||||
return
|
||||
}
|
||||
126
plugins/apps/vendor/github.com/codeskyblue/go-sh/pipe_test.go
generated
vendored
126
plugins/apps/vendor/github.com/codeskyblue/go-sh/pipe_test.go
generated
vendored
@@ -1,126 +0,0 @@
|
||||
package sh
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestUnmarshalJSON(t *testing.T) {
|
||||
var a int
|
||||
s := NewSession()
|
||||
s.ShowCMD = true
|
||||
err := s.Command("echo", []string{"1"}).UnmarshalJSON(&a)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if a != 1 {
|
||||
t.Errorf("expect a tobe 1, but got %d", a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalXML(t *testing.T) {
|
||||
s := NewSession()
|
||||
xmlSample := `<?xml version="1.0" encoding="utf-8"?>
|
||||
<server version="1" />`
|
||||
type server struct {
|
||||
XMLName xml.Name `xml:"server"`
|
||||
Version string `xml:"version,attr"`
|
||||
}
|
||||
data := &server{}
|
||||
s.Command("echo", xmlSample).UnmarshalXML(data)
|
||||
if data.Version != "1" {
|
||||
t.Error(data)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPipe(t *testing.T) {
|
||||
s := NewSession()
|
||||
s.ShowCMD = true
|
||||
s.Call("echo", "hello")
|
||||
err := s.Command("echo", "hi").Command("cat", "-n").Start()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
err = s.Wait()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
out, err := s.Command("echo", []string{"hello"}).Output()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if string(out) != "hello\n" {
|
||||
t.Error("capture wrong output:", out)
|
||||
}
|
||||
s.Command("echo", []string{"hello\tworld"}).Command("cut", []string{"-f2"}).Run()
|
||||
}
|
||||
|
||||
func TestPipeCommand(t *testing.T) {
|
||||
c1 := exec.Command("echo", "good")
|
||||
rd, wr := io.Pipe()
|
||||
c1.Stdout = wr
|
||||
c2 := exec.Command("cat", "-n")
|
||||
c2.Stdout = os.Stdout
|
||||
c2.Stdin = rd
|
||||
c1.Start()
|
||||
c2.Start()
|
||||
|
||||
c1.Wait()
|
||||
wc, ok := c1.Stdout.(io.WriteCloser)
|
||||
if ok {
|
||||
wc.Close()
|
||||
}
|
||||
c2.Wait()
|
||||
}
|
||||
|
||||
func TestPipeInput(t *testing.T) {
|
||||
s := NewSession()
|
||||
s.ShowCMD = true
|
||||
s.SetInput("first line\nsecond line\n")
|
||||
out, err := s.Command("grep", "second").Output()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if string(out) != "second line\n" {
|
||||
t.Error("capture wrong output:", out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimeout(t *testing.T) {
|
||||
s := NewSession()
|
||||
err := s.Command("sleep", "2").Start()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = s.WaitTimeout(time.Second)
|
||||
if err != ErrExecTimeout {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetTimeout(t *testing.T) {
|
||||
s := NewSession()
|
||||
s.SetTimeout(time.Second)
|
||||
defer s.SetTimeout(0)
|
||||
err := s.Command("sleep", "2").Run()
|
||||
if err != ErrExecTimeout {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCombinedOutput(t *testing.T) {
|
||||
s := NewSession()
|
||||
bytes, err := s.Command("sh", "-c", "echo stderr >&2 ; echo stdout").CombinedOutput()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
stringOutput := string(bytes)
|
||||
if !(strings.Contains(stringOutput, "stdout") && strings.Contains(stringOutput, "stderr")) {
|
||||
t.Errorf("expect output from both output streams, got '%s'", strings.TrimSpace(stringOutput))
|
||||
}
|
||||
}
|
||||
200
plugins/apps/vendor/github.com/codeskyblue/go-sh/sh.go
generated
vendored
200
plugins/apps/vendor/github.com/codeskyblue/go-sh/sh.go
generated
vendored
@@ -1,200 +0,0 @@
|
||||
/*
|
||||
Package go-sh is intented to make shell call with golang more easily.
|
||||
Some usage is more similar to os/exec, eg: Run(), Output(), Command(name, args...)
|
||||
|
||||
But with these similar function, pipe is added in and this package also got shell-session support.
|
||||
|
||||
Why I love golang so much, because the usage of golang is simple, but the power is unlimited. I want to make this pakcage got the sample style like golang.
|
||||
|
||||
// just like os/exec
|
||||
sh.Command("echo", "hello").Run()
|
||||
|
||||
// support pipe
|
||||
sh.Command("echo", "hello").Command("wc", "-c").Run()
|
||||
|
||||
// create a session to store dir and env
|
||||
sh.NewSession().SetDir("/").Command("pwd")
|
||||
|
||||
// shell buildin command - "test"
|
||||
sh.Test("dir", "mydir")
|
||||
|
||||
// like shell call: (cd /; pwd)
|
||||
sh.Command("pwd", sh.Dir("/")) same with sh.Command(sh.Dir("/"), "pwd")
|
||||
|
||||
// output to json and xml easily
|
||||
v := map[string] int {}
|
||||
err = sh.Command("echo", `{"number": 1}`).UnmarshalJSON(&v)
|
||||
*/
|
||||
package sh
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/codegangsta/inject"
|
||||
)
|
||||
|
||||
type Dir string
|
||||
|
||||
type Session struct {
|
||||
inj inject.Injector
|
||||
alias map[string][]string
|
||||
cmds []*exec.Cmd
|
||||
dir Dir
|
||||
started bool
|
||||
Env map[string]string
|
||||
Stdin io.Reader
|
||||
Stdout io.Writer
|
||||
Stderr io.Writer
|
||||
ShowCMD bool // enable for debug
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
func (s *Session) writePrompt(args ...interface{}) {
|
||||
var ps1 = fmt.Sprintf("[golang-sh]$")
|
||||
args = append([]interface{}{ps1}, args...)
|
||||
fmt.Fprintln(s.Stderr, args...)
|
||||
}
|
||||
|
||||
func NewSession() *Session {
|
||||
env := make(map[string]string)
|
||||
for _, key := range []string{"PATH"} {
|
||||
env[key] = os.Getenv(key)
|
||||
}
|
||||
s := &Session{
|
||||
inj: inject.New(),
|
||||
alias: make(map[string][]string),
|
||||
dir: Dir(""),
|
||||
Stdin: strings.NewReader(""),
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stderr,
|
||||
Env: env,
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func InteractiveSession() *Session {
|
||||
s := NewSession()
|
||||
s.SetStdin(os.Stdin)
|
||||
return s
|
||||
}
|
||||
|
||||
func Command(name string, a ...interface{}) *Session {
|
||||
s := NewSession()
|
||||
return s.Command(name, a...)
|
||||
}
|
||||
|
||||
func Echo(in string) *Session {
|
||||
s := NewSession()
|
||||
return s.SetInput(in)
|
||||
}
|
||||
|
||||
func (s *Session) Alias(alias, cmd string, args ...string) {
|
||||
v := []string{cmd}
|
||||
v = append(v, args...)
|
||||
s.alias[alias] = v
|
||||
}
|
||||
|
||||
func (s *Session) Command(name string, a ...interface{}) *Session {
|
||||
var args = make([]string, 0)
|
||||
var sType = reflect.TypeOf("")
|
||||
|
||||
// init cmd, args, dir, envs
|
||||
// if not init, program may panic
|
||||
s.inj.Map(name).Map(args).Map(s.dir).Map(map[string]string{})
|
||||
for _, v := range a {
|
||||
switch reflect.TypeOf(v) {
|
||||
case sType:
|
||||
args = append(args, v.(string))
|
||||
default:
|
||||
s.inj.Map(v)
|
||||
}
|
||||
}
|
||||
if len(args) != 0 {
|
||||
s.inj.Map(args)
|
||||
}
|
||||
s.inj.Invoke(s.appendCmd)
|
||||
return s
|
||||
}
|
||||
|
||||
// combine Command and Run
|
||||
func (s *Session) Call(name string, a ...interface{}) error {
|
||||
return s.Command(name, a...).Run()
|
||||
}
|
||||
|
||||
/*
|
||||
func (s *Session) Exec(cmd string, args ...string) error {
|
||||
return s.Call(cmd, args)
|
||||
}
|
||||
*/
|
||||
|
||||
func (s *Session) SetEnv(key, value string) *Session {
|
||||
s.Env[key] = value
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Session) SetDir(dir string) *Session {
|
||||
s.dir = Dir(dir)
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Session) SetInput(in string) *Session {
|
||||
s.Stdin = strings.NewReader(in)
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Session) SetStdin(r io.Reader) *Session {
|
||||
s.Stdin = r
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Session) SetTimeout(d time.Duration) *Session {
|
||||
s.timeout = d
|
||||
return s
|
||||
}
|
||||
|
||||
func newEnviron(env map[string]string, inherit bool) []string { //map[string]string {
|
||||
environ := make([]string, 0, len(env))
|
||||
if inherit {
|
||||
for _, line := range os.Environ() {
|
||||
for k, _ := range env {
|
||||
if strings.HasPrefix(line, k+"=") {
|
||||
goto CONTINUE
|
||||
}
|
||||
}
|
||||
environ = append(environ, line)
|
||||
CONTINUE:
|
||||
}
|
||||
}
|
||||
for k, v := range env {
|
||||
environ = append(environ, k+"="+v)
|
||||
}
|
||||
return environ
|
||||
}
|
||||
|
||||
func (s *Session) appendCmd(cmd string, args []string, cwd Dir, env map[string]string) {
|
||||
if s.started {
|
||||
s.started = false
|
||||
s.cmds = make([]*exec.Cmd, 0)
|
||||
}
|
||||
for k, v := range s.Env {
|
||||
if _, ok := env[k]; !ok {
|
||||
env[k] = v
|
||||
}
|
||||
}
|
||||
environ := newEnviron(s.Env, true) // true: inherit sys-env
|
||||
v, ok := s.alias[cmd]
|
||||
if ok {
|
||||
cmd = v[0]
|
||||
args = append(v[1:], args...)
|
||||
}
|
||||
c := exec.Command(cmd, args...)
|
||||
c.Env = environ
|
||||
c.Dir = string(cwd)
|
||||
s.cmds = append(s.cmds, c)
|
||||
}
|
||||
106
plugins/apps/vendor/github.com/codeskyblue/go-sh/sh_test.go
generated
vendored
106
plugins/apps/vendor/github.com/codeskyblue/go-sh/sh_test.go
generated
vendored
@@ -1,106 +0,0 @@
|
||||
package sh
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAlias(t *testing.T) {
|
||||
s := NewSession()
|
||||
s.Alias("gr", "echo", "hi")
|
||||
out, err := s.Command("gr", "sky").Output()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if string(out) != "hi sky\n" {
|
||||
t.Errorf("expect 'hi sky' but got:%s", string(out))
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleSession_Command() {
|
||||
s := NewSession()
|
||||
out, err := s.Command("echo", "hello").Output()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println(string(out))
|
||||
// Output: hello
|
||||
}
|
||||
|
||||
func ExampleSession_Command_pipe() {
|
||||
s := NewSession()
|
||||
out, err := s.Command("echo", "hello", "world").Command("awk", "{print $2}").Output()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println(string(out))
|
||||
// Output: world
|
||||
}
|
||||
|
||||
func ExampleSession_Alias() {
|
||||
s := NewSession()
|
||||
s.Alias("alias_echo_hello", "echo", "hello")
|
||||
out, err := s.Command("alias_echo_hello", "world").Output()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println(string(out))
|
||||
// Output: hello world
|
||||
}
|
||||
|
||||
func TestEcho(t *testing.T) {
|
||||
out, err := Echo("one two three").Command("wc", "-w").Output()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if strings.TrimSpace(string(out)) != "3" {
|
||||
t.Errorf("expect '3' but got:%s", string(out))
|
||||
}
|
||||
}
|
||||
|
||||
func TestSession(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Log("ignore test on windows")
|
||||
return
|
||||
}
|
||||
session := NewSession()
|
||||
session.ShowCMD = true
|
||||
err := session.Call("pwd")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
out, err := session.SetDir("/").Command("pwd").Output()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if string(out) != "/\n" {
|
||||
t.Errorf("expect /, but got %s", string(out))
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
#!/bin/bash -
|
||||
#
|
||||
export PATH=/usr/bin:/bin
|
||||
alias ll='ls -l'
|
||||
cd /usr
|
||||
if test -d "local"
|
||||
then
|
||||
ll local | awk '{print $1, $NF}' | grep bin
|
||||
fi
|
||||
*/
|
||||
func Example(t *testing.T) {
|
||||
s := NewSession()
|
||||
//s.ShowCMD = true
|
||||
s.Env["PATH"] = "/usr/bin:/bin"
|
||||
s.SetDir("/bin")
|
||||
s.Alias("ll", "ls", "-l")
|
||||
|
||||
if s.Test("d", "local") {
|
||||
//s.Command("ll", []string{"local"}).Command("awk", []string{"{print $1, $NF}"}).Command("grep", []string{"bin"}).Run()
|
||||
s.Command("ll", "local").Command("awk", "{print $1, $NF}").Command("grep", "bin").Run()
|
||||
}
|
||||
}
|
||||
64
plugins/apps/vendor/github.com/codeskyblue/go-sh/test.go
generated
vendored
64
plugins/apps/vendor/github.com/codeskyblue/go-sh/test.go
generated
vendored
@@ -1,64 +0,0 @@
|
||||
package sh
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func filetest(name string, modemask os.FileMode) (match bool, err error) {
|
||||
fi, err := os.Stat(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
match = (fi.Mode() & modemask) == modemask
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Session) pwd() string {
|
||||
dir := string(s.dir)
|
||||
if dir == "" {
|
||||
dir, _ = os.Getwd()
|
||||
}
|
||||
return dir
|
||||
}
|
||||
|
||||
func (s *Session) abspath(name string) string {
|
||||
if filepath.IsAbs(name) {
|
||||
return name
|
||||
}
|
||||
return filepath.Join(s.pwd(), name)
|
||||
}
|
||||
|
||||
func init() {
|
||||
//log.SetFlags(log.Lshortfile | log.LstdFlags)
|
||||
}
|
||||
|
||||
// expression can be dir, file, link
|
||||
func (s *Session) Test(expression string, argument string) bool {
|
||||
var err error
|
||||
var fi os.FileInfo
|
||||
fi, err = os.Lstat(s.abspath(argument))
|
||||
switch expression {
|
||||
case "d", "dir":
|
||||
return err == nil && fi.IsDir()
|
||||
case "f", "file":
|
||||
return err == nil && fi.Mode().IsRegular()
|
||||
case "x", "executable":
|
||||
/*
|
||||
fmt.Println(expression, argument)
|
||||
if err == nil {
|
||||
fmt.Println(fi.Mode())
|
||||
}
|
||||
*/
|
||||
return err == nil && fi.Mode()&os.FileMode(0100) != 0
|
||||
case "L", "link":
|
||||
return err == nil && fi.Mode()&os.ModeSymlink != 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// expression can be d,dir, f,file, link
|
||||
func Test(exp string, arg string) bool {
|
||||
s := NewSession()
|
||||
return s.Test(exp, arg)
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user