From 377166d822507b5f23478063e6688e09334c82f7 Mon Sep 17 00:00:00 2001 From: fzerorubigd Date: Wed, 21 Aug 2019 22:59:11 +0200 Subject: [PATCH 01/39] nginx-vhost: add support for grpc/grpcs port forward --- plugins/nginx-vhosts/functions | 27 +++++++++++++- .../nginx-vhosts/templates/nginx.conf.sigil | 35 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/plugins/nginx-vhosts/functions b/plugins/nginx-vhosts/functions index 5319879af..c04530ace 100755 --- a/plugins/nginx-vhosts/functions +++ b/plugins/nginx-vhosts/functions @@ -259,6 +259,29 @@ is_http2_enabled() { echo $HAS_SUPPORT } +is_grpc_enabled() { + declare desc="detects whether the installed nginx version has grpc support" + local NGINX_VERSION="$1" + local MAJOR_VERSION MINOR_VERSION PATCH_VERSION + local HAS_SUPPORT=false + + MAJOR_VERSION=$(echo "$NGINX_VERSION" | awk '{split($0,a,"."); print a[1]}') + MINOR_VERSION=$(echo "$NGINX_VERSION" | awk '{split($0,a,"."); print a[2]}') + PATCH_VERSION=$(echo "$NGINX_VERSION" | awk '{split($0,a,"."); print a[3]}') + if [[ "$MAJOR_VERSION" -ge "2" ]]; then + HAS_SUPPORT=true + elif [[ "$MAJOR_VERSION" -eq "1" ]]; then + if [[ "$MINOR_VERSION" -eq "13" ]] && [[ "$PATCH_VERSION" -ge "10" ]]; then + HAS_SUPPORT=true + elif [[ "$MINOR_VERSION" -ge "14" ]]; then + HAS_SUPPORT=true + fi + fi + + echo $HAS_SUPPORT +} + + nginx_build_config() { declare desc="build nginx config to proxy app containers using sigil" local APP="$1" @@ -337,7 +360,7 @@ nginx_build_config() { done fi - local NGINX_LOCATION NGINX_VERSION SPDY_SUPPORTED HTTP2_SUPPORTED HTTP2_PUSH_SUPPORTED + local NGINX_LOCATION NGINX_VERSION SPDY_SUPPORTED HTTP2_SUPPORTED HTTP2_PUSH_SUPPORTED GRPC_SUPPORTED NGINX_LOCATION=$(get_nginx_location) if [[ -z "$NGINX_LOCATION" ]]; then exit 1 @@ -346,6 +369,7 @@ nginx_build_config() { SPDY_SUPPORTED="$(is_spdy_enabled "$NGINX_VERSION")" HTTP2_SUPPORTED="$(is_http2_enabled "$NGINX_VERSION")" HTTP2_PUSH_SUPPORTED="$(is_http2_push_enabled "$NGINX_VERSION")" + GRPC_SUPPORTED="$(is_grpc_enabled "$NGINX_VERSION")" PROXY_PORT_MAP=$(echo "$PROXY_PORT_MAP" | xargs) # trailing spaces mess up default template @@ -358,6 +382,7 @@ nginx_build_config() { SPDY_SUPPORTED="$SPDY_SUPPORTED" HTTP2_SUPPORTED="$HTTP2_SUPPORTED" HTTP2_PUSH_SUPPORTED="$HTTP2_PUSH_SUPPORTED" + GRPC_SUPPORTED="$GRPC_SUPPORTED" DOKKU_APP_LISTEN_PORT="$DOKKU_APP_LISTEN_PORT" DOKKU_APP_LISTEN_IP="$DOKKU_APP_LISTEN_IP" APP_SSL_PATH="$APP_SSL_PATH" SSL_INUSE="$SSL_INUSE" SSL_SERVER_NAME="$SSL_SERVER_NAME" # @TODO: Remove this after a few versions diff --git a/plugins/nginx-vhosts/templates/nginx.conf.sigil b/plugins/nginx-vhosts/templates/nginx.conf.sigil index 7ad4595a5..3d1557cf4 100644 --- a/plugins/nginx-vhosts/templates/nginx.conf.sigil +++ b/plugins/nginx-vhosts/templates/nginx.conf.sigil @@ -117,7 +117,42 @@ server { internal; } } +{{ else if eq $scheme "grpc"}} +{{ if eq $.GRPC_SUPPORTED "true"}}{{ if eq $.HTTP2_SUPPORTED "true"}} +server { + listen [::]:{{ $listen_port }} http2; + listen {{ $listen_port }} http2; + {{ if $.NOSSL_SERVER_NAME }}server_name {{ $.NOSSL_SERVER_NAME }}; {{ end }} + access_log /var/log/nginx/{{ $.APP }}-access.log; + error_log /var/log/nginx/{{ $.APP }}-error.log; + location / { + grpc_pass grpc://{{ $.APP }}-{{ $upstream_port }}; + } + include {{ $.DOKKU_ROOT }}/{{ $.APP }}/nginx.conf.d/*.conf; +} {{ end }}{{ end }} +{{ else if eq $scheme "grpcs"}} +{{ if eq $.GRPC_SUPPORTED "true"}}{{ if eq $.HTTP2_SUPPORTED "true"}} +server { + listen [::]:{{ $listen_port }} ssl http2; + listen {{ $listen_port }} ssl http2; + {{ if $.NOSSL_SERVER_NAME }}server_name {{ $.NOSSL_SERVER_NAME }}; {{ end }} + access_log /var/log/nginx/{{ $.APP }}-access.log; + error_log /var/log/nginx/{{ $.APP }}-error.log; + + ssl_certificate {{ $.APP_SSL_PATH }}/server.crt; + ssl_certificate_key {{ $.APP_SSL_PATH }}/server.key; + ssl_protocols TLSv1.2; + ssl_prefer_server_ciphers on; + + location / { + grpc_pass grpc://{{ $.APP }}-{{ $upstream_port }}; + } + include {{ $.DOKKU_ROOT }}/{{ $.APP }}/nginx.conf.d/*.conf; +} +{{ end }}{{ end }} +{{ end }} +{{ end }} {{ if $.DOKKU_APP_LISTENERS }} {{ range $upstream_port := $.PROXY_UPSTREAM_PORTS | split " " }} From 180a5e79c9e935a74212259f699ac407c3926c57 Mon Sep 17 00:00:00 2001 From: Alexey Zagarin Date: Fri, 23 Aug 2019 13:59:47 +0700 Subject: [PATCH 02/39] Improve nginx ciphers compatibility Closes #3661. --- plugins/nginx-vhosts/install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/nginx-vhosts/install b/plugins/nginx-vhosts/install index c48e451b0..c4759671d 100755 --- a/plugins/nginx-vhosts/install +++ b/plugins/nginx-vhosts/install @@ -48,7 +48,7 @@ ssl_session_timeout 1d; ssl_session_tickets on; ssl_dhparam /etc/nginx/dhparam.pem; -ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384; +ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; EOF From 346e8284c8aa2ca64990c2c89b9ab3f98ccc21b6 Mon Sep 17 00:00:00 2001 From: fzerorubigd Date: Thu, 22 Aug 2019 20:23:52 +0200 Subject: [PATCH 03/39] nginx-vhost: adding some test for the grpc --- tests/apps/gogrpc/Dockerfile | 9 + tests/apps/gogrpc/go.mod | 21 ++ tests/apps/gogrpc/go.sum | 143 +++++++++++++ tests/apps/gogrpc/greeter_client/main.go | 56 +++++ tests/apps/gogrpc/greeter_server/main.go | 56 +++++ tests/apps/gogrpc/helloworld/helloworld.pb.go | 198 ++++++++++++++++++ tests/apps/gogrpc/helloworld/helloworld.proto | 37 ++++ tests/unit/40_nginx-vhosts_3.bats | 26 +++ 8 files changed, 546 insertions(+) create mode 100644 tests/apps/gogrpc/Dockerfile create mode 100644 tests/apps/gogrpc/go.mod create mode 100644 tests/apps/gogrpc/go.sum create mode 100644 tests/apps/gogrpc/greeter_client/main.go create mode 100644 tests/apps/gogrpc/greeter_server/main.go create mode 100644 tests/apps/gogrpc/helloworld/helloworld.pb.go create mode 100644 tests/apps/gogrpc/helloworld/helloworld.proto create mode 100644 tests/unit/40_nginx-vhosts_3.bats diff --git a/tests/apps/gogrpc/Dockerfile b/tests/apps/gogrpc/Dockerfile new file mode 100644 index 000000000..855e9ddce --- /dev/null +++ b/tests/apps/gogrpc/Dockerfile @@ -0,0 +1,9 @@ +FROM golang:1.12 + +RUN mkdir /app +WORKDIR /app + +ADD . /app +RUN go install ./... + +CMD /go/bin/greeter_server diff --git a/tests/apps/gogrpc/go.mod b/tests/apps/gogrpc/go.mod new file mode 100644 index 000000000..17be0c8fe --- /dev/null +++ b/tests/apps/gogrpc/go.mod @@ -0,0 +1,21 @@ +module github.com/dokku/dokko/tests/apps/gorpc + +go 1.12 + +require ( + cloud.google.com/go v0.44.3 // indirect + github.com/golang/protobuf v1.3.2 + github.com/google/go-cmp v0.3.1 // indirect + github.com/google/pprof v0.0.0-20190723021845-34ac40c74b70 // indirect + github.com/hashicorp/golang-lru v0.5.3 // indirect + github.com/kr/pty v1.1.8 // indirect + golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 // indirect + golang.org/x/mobile v0.0.0-20190814143026-e8b3e6111d02 // indirect + golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 + golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a // indirect + golang.org/x/tools v0.0.0-20190822000311-fc82fb2afd64 // indirect + google.golang.org/api v0.9.0 // indirect + google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 // indirect + google.golang.org/grpc v1.23.0 + honnef.co/go/tools v0.0.1-2019.2.2 // indirect +) diff --git a/tests/apps/gogrpc/go.sum b/tests/apps/gogrpc/go.sum new file mode 100644 index 000000000..02004b956 --- /dev/null +++ b/tests/apps/gogrpc/go.sum @@ -0,0 +1,143 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190723021845-34ac40c74b70/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190814143026-e8b3e6111d02/go.mod h1:z5wpDCy2wbnXyFdvEuY3LhY9gBUL86/IOILm+Hsjx+E= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190808195139-e713427fea3f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190822000311-fc82fb2afd64/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.2/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/tests/apps/gogrpc/greeter_client/main.go b/tests/apps/gogrpc/greeter_client/main.go new file mode 100644 index 000000000..613d402bc --- /dev/null +++ b/tests/apps/gogrpc/greeter_client/main.go @@ -0,0 +1,56 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * 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. + * + */ + +// Package main implements a client for Greeter service. +package main + +import ( + "context" + "flag" + "fmt" + "log" + "time" + + "google.golang.org/grpc" + pb "google.golang.org/grpc/examples/helloworld/helloworld" +) + +var ( + address = flag.String("address", "", "address to call") + name = flag.String("name", "world", "the name") +) + +func main() { + flag.Parse() + // Set up a connection to the server. + conn, err := grpc.Dial(*address, grpc.WithInsecure()) + if err != nil { + log.Fatalf("did not connect: %v", err) + } + defer conn.Close() + c := pb.NewGreeterClient(conn) + + // Contact the server and print out its response. + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + r, err := c.SayHello(ctx, &pb.HelloRequest{Name: *name}) + if err != nil { + log.Fatalf("could not greet: %v", err) + } + fmt.Printf("Greeting: %s", r.Message) +} diff --git a/tests/apps/gogrpc/greeter_server/main.go b/tests/apps/gogrpc/greeter_server/main.go new file mode 100644 index 000000000..e99fb26a3 --- /dev/null +++ b/tests/apps/gogrpc/greeter_server/main.go @@ -0,0 +1,56 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * 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. + * + */ + +//go:generate protoc -I ../helloworld --go_out=plugins=grpc:../helloworld ../helloworld/helloworld.proto + +// Package main implements a server for Greeter service. +package main + +import ( + "context" + "log" + "net" + + "google.golang.org/grpc" + pb "google.golang.org/grpc/examples/helloworld/helloworld" +) + +const ( + port = ":50051" +) + +// server is used to implement helloworld.GreeterServer. +type server struct{} + +// SayHello implements helloworld.GreeterServer +func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { + log.Printf("Received: %v", in.Name) + return &pb.HelloReply{Message: "Hello " + in.Name}, nil +} + +func main() { + lis, err := net.Listen("tcp", port) + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + s := grpc.NewServer() + pb.RegisterGreeterServer(s, &server{}) + if err := s.Serve(lis); err != nil { + log.Fatalf("failed to serve: %v", err) + } +} diff --git a/tests/apps/gogrpc/helloworld/helloworld.pb.go b/tests/apps/gogrpc/helloworld/helloworld.pb.go new file mode 100644 index 000000000..11383d740 --- /dev/null +++ b/tests/apps/gogrpc/helloworld/helloworld.pb.go @@ -0,0 +1,198 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: helloworld.proto + +package helloworld + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// The request message containing the user's name. +type HelloRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *HelloRequest) Reset() { *m = HelloRequest{} } +func (m *HelloRequest) String() string { return proto.CompactTextString(m) } +func (*HelloRequest) ProtoMessage() {} +func (*HelloRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_helloworld_71e208cbdc16936b, []int{0} +} +func (m *HelloRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_HelloRequest.Unmarshal(m, b) +} +func (m *HelloRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_HelloRequest.Marshal(b, m, deterministic) +} +func (dst *HelloRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_HelloRequest.Merge(dst, src) +} +func (m *HelloRequest) XXX_Size() int { + return xxx_messageInfo_HelloRequest.Size(m) +} +func (m *HelloRequest) XXX_DiscardUnknown() { + xxx_messageInfo_HelloRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_HelloRequest proto.InternalMessageInfo + +func (m *HelloRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +// The response message containing the greetings +type HelloReply struct { + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *HelloReply) Reset() { *m = HelloReply{} } +func (m *HelloReply) String() string { return proto.CompactTextString(m) } +func (*HelloReply) ProtoMessage() {} +func (*HelloReply) Descriptor() ([]byte, []int) { + return fileDescriptor_helloworld_71e208cbdc16936b, []int{1} +} +func (m *HelloReply) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_HelloReply.Unmarshal(m, b) +} +func (m *HelloReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_HelloReply.Marshal(b, m, deterministic) +} +func (dst *HelloReply) XXX_Merge(src proto.Message) { + xxx_messageInfo_HelloReply.Merge(dst, src) +} +func (m *HelloReply) XXX_Size() int { + return xxx_messageInfo_HelloReply.Size(m) +} +func (m *HelloReply) XXX_DiscardUnknown() { + xxx_messageInfo_HelloReply.DiscardUnknown(m) +} + +var xxx_messageInfo_HelloReply proto.InternalMessageInfo + +func (m *HelloReply) GetMessage() string { + if m != nil { + return m.Message + } + return "" +} + +func init() { + proto.RegisterType((*HelloRequest)(nil), "helloworld.HelloRequest") + proto.RegisterType((*HelloReply)(nil), "helloworld.HelloReply") +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// GreeterClient is the client API for Greeter service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type GreeterClient interface { + // Sends a greeting + SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) +} + +type greeterClient struct { + cc *grpc.ClientConn +} + +func NewGreeterClient(cc *grpc.ClientConn) GreeterClient { + return &greeterClient{cc} +} + +func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) { + out := new(HelloReply) + err := c.cc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// GreeterServer is the server API for Greeter service. +type GreeterServer interface { + // Sends a greeting + SayHello(context.Context, *HelloRequest) (*HelloReply, error) +} + +func RegisterGreeterServer(s *grpc.Server, srv GreeterServer) { + s.RegisterService(&_Greeter_serviceDesc, srv) +} + +func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HelloRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GreeterServer).SayHello(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/helloworld.Greeter/SayHello", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Greeter_serviceDesc = grpc.ServiceDesc{ + ServiceName: "helloworld.Greeter", + HandlerType: (*GreeterServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "SayHello", + Handler: _Greeter_SayHello_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "helloworld.proto", +} + +func init() { proto.RegisterFile("helloworld.proto", fileDescriptor_helloworld_71e208cbdc16936b) } + +var fileDescriptor_helloworld_71e208cbdc16936b = []byte{ + // 175 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xc8, 0x48, 0xcd, 0xc9, + 0xc9, 0x2f, 0xcf, 0x2f, 0xca, 0x49, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x42, 0x88, + 0x28, 0x29, 0x71, 0xf1, 0x78, 0x80, 0x78, 0x41, 0xa9, 0x85, 0xa5, 0xa9, 0xc5, 0x25, 0x42, 0x42, + 0x5c, 0x2c, 0x79, 0x89, 0xb9, 0xa9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x60, 0xb6, 0x92, + 0x1a, 0x17, 0x17, 0x54, 0x4d, 0x41, 0x4e, 0xa5, 0x90, 0x04, 0x17, 0x7b, 0x6e, 0x6a, 0x71, 0x71, + 0x62, 0x3a, 0x4c, 0x11, 0x8c, 0x6b, 0xe4, 0xc9, 0xc5, 0xee, 0x5e, 0x94, 0x9a, 0x5a, 0x92, 0x5a, + 0x24, 0x64, 0xc7, 0xc5, 0x11, 0x9c, 0x58, 0x09, 0xd6, 0x25, 0x24, 0xa1, 0x87, 0xe4, 0x02, 0x64, + 0xcb, 0xa4, 0xc4, 0xb0, 0xc8, 0x14, 0xe4, 0x54, 0x2a, 0x31, 0x38, 0x19, 0x70, 0x49, 0x67, 0xe6, + 0xeb, 0xa5, 0x17, 0x15, 0x24, 0xeb, 0xa5, 0x56, 0x24, 0xe6, 0x16, 0xe4, 0xa4, 0x16, 0x23, 0xa9, + 0x75, 0xe2, 0x07, 0x2b, 0x0e, 0x07, 0xb1, 0x03, 0x40, 0x5e, 0x0a, 0x60, 0x4c, 0x62, 0x03, 0xfb, + 0xcd, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x0f, 0xb7, 0xcd, 0xf2, 0xef, 0x00, 0x00, 0x00, +} diff --git a/tests/apps/gogrpc/helloworld/helloworld.proto b/tests/apps/gogrpc/helloworld/helloworld.proto new file mode 100644 index 000000000..d79a6a0d1 --- /dev/null +++ b/tests/apps/gogrpc/helloworld/helloworld.proto @@ -0,0 +1,37 @@ +// Copyright 2015 gRPC authors. +// +// 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. + +syntax = "proto3"; + +option java_multiple_files = true; +option java_package = "io.grpc.examples.helloworld"; +option java_outer_classname = "HelloWorldProto"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} diff --git a/tests/unit/40_nginx-vhosts_3.bats b/tests/unit/40_nginx-vhosts_3.bats new file mode 100644 index 000000000..5257fbc67 --- /dev/null +++ b/tests/unit/40_nginx-vhosts_3.bats @@ -0,0 +1,26 @@ +#!/usr/bin/env bats + +load test_helper +source "$PLUGIN_CORE_AVAILABLE_PATH/config/functions" + +setup() { + global_setup + [[ -f "$DOKKU_ROOT/VHOST" ]] && cp -fp "$DOKKU_ROOT/VHOST" "$DOKKU_ROOT/VHOST.bak" + [[ -f "$DOKKU_ROOT/HOSTNAME" ]] && cp -fp "$DOKKU_ROOT/HOSTNAME" "$DOKKU_ROOT/HOSTNAME.bak" + create_app + docker build "${BATS_TEST_DIRNAME}/../../tests/apps/gogrpc" -t ${TEST_APP}-docker-image +} + +teardown() { + destroy_app 0 $TEST_APP + [[ -f "$DOKKU_ROOT/VHOST.bak" ]] && mv "$DOKKU_ROOT/VHOST.bak" "$DOKKU_ROOT/VHOST" && chown dokku:dokku "$DOKKU_ROOT/VHOST" + [[ -f "$DOKKU_ROOT/HOSTNAME.bak" ]] && mv "$DOKKU_ROOT/HOSTNAME.bak" "$DOKKU_ROOT/HOSTNAME" && chown dokku:dokku "$DOKKU_ROOT/HOSTNAME" + global_teardown +} + +@test "(nginx-vhosts) grpc endpoint" { + deploy_app gogrpc + dokku proxy:ports-add "$TEST_APP" "grpc:80:50051" + docker run --rm ${TEST_APP}-docker-image /go/bin/greeter_client -address ${TEST_APP}.dokku.me:80 -name grpc + assert_output "Greeting: Hello grpc" +} From 3457844687ba35a1be91d4053c28089bfd138262 Mon Sep 17 00:00:00 2001 From: Forud Date: Fri, 23 Aug 2019 14:28:01 +0200 Subject: [PATCH 04/39] nginx-vhost: add test for grpcs --- tests/apps/gogrpc/go.mod | 2 ++ tests/apps/gogrpc/greeter_client/main.go | 16 +++++++++++++--- tests/unit/40_nginx-vhosts_3.bats | 10 +++++++++- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/tests/apps/gogrpc/go.mod b/tests/apps/gogrpc/go.mod index 17be0c8fe..0f08a07e1 100644 --- a/tests/apps/gogrpc/go.mod +++ b/tests/apps/gogrpc/go.mod @@ -19,3 +19,5 @@ require ( google.golang.org/grpc v1.23.0 honnef.co/go/tools v0.0.1-2019.2.2 // indirect ) + +replace google.golang.org/grpc/examples/helloworld/helloworld => ./helloworld diff --git a/tests/apps/gogrpc/greeter_client/main.go b/tests/apps/gogrpc/greeter_client/main.go index 613d402bc..7274c1088 100644 --- a/tests/apps/gogrpc/greeter_client/main.go +++ b/tests/apps/gogrpc/greeter_client/main.go @@ -21,24 +21,34 @@ package main import ( "context" + "crypto/tls" "flag" "fmt" "log" "time" "google.golang.org/grpc" + "google.golang.org/grpc/credentials" pb "google.golang.org/grpc/examples/helloworld/helloworld" ) var ( - address = flag.String("address", "", "address to call") - name = flag.String("name", "world", "the name") + address = flag.String("address", "", "address to call") + name = flag.String("name", "world", "the name") + selfSignedTLS = flag.Bool("tls", false, "use self signed tls") ) func main() { flag.Parse() // Set up a connection to the server. - conn, err := grpc.Dial(*address, grpc.WithInsecure()) + var opts []grpc.DialOption + if *selfSignedTLS { + creds := credentials.NewTLS(&tls.Config{InsecureSkipVerify: true}) + opts = append(opts, grpc.WithTransportCredentials(creds)) + } else { + opts = append(opts, grpc.WithInsecure()) + } + conn, err := grpc.Dial(*address, opts...) if err != nil { log.Fatalf("did not connect: %v", err) } diff --git a/tests/unit/40_nginx-vhosts_3.bats b/tests/unit/40_nginx-vhosts_3.bats index 5257fbc67..6336da6ea 100644 --- a/tests/unit/40_nginx-vhosts_3.bats +++ b/tests/unit/40_nginx-vhosts_3.bats @@ -21,6 +21,14 @@ teardown() { @test "(nginx-vhosts) grpc endpoint" { deploy_app gogrpc dokku proxy:ports-add "$TEST_APP" "grpc:80:50051" - docker run --rm ${TEST_APP}-docker-image /go/bin/greeter_client -address ${TEST_APP}.dokku.me:80 -name grpc + run /bin/bash -c "docker run --rm ${TEST_APP}-docker-image /go/bin/greeter_client -address ${TEST_APP}.dokku.me:80 -name grpc" assert_output "Greeting: Hello grpc" } + +@test "(nginx-vhosts) grpcs endpoint" { + setup_test_tls + deploy_app gogrpc + dokku proxy:ports-add "$TEST_APP" "grpcs:443:50051" + run /bin/bash -c "docker run --rm ${TEST_APP}-docker-image /go/bin/greeter_client -address ${TEST_APP}.dokku.me:443 -name grpcs -tls" + assert_output "Greeting: Hello grpcs" +} From 5ca3ca518949c4b337a657983990734ad61b67b1 Mon Sep 17 00:00:00 2001 From: Forud Date: Fri, 23 Aug 2019 15:34:34 +0200 Subject: [PATCH 05/39] nginx-vhosts: add a note in the proxy management docs about grpc [ci skip] --- docs/networking/proxy-management.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/networking/proxy-management.md b/docs/networking/proxy-management.md index 869c706bf..3162704b0 100644 --- a/docs/networking/proxy-management.md +++ b/docs/networking/proxy-management.md @@ -69,7 +69,8 @@ The proxy port scheme is as follows: - `SCHEME:HOST_PORT:CONTAINER_PORT` -The scheme metadata can be used by proxy implementations in order to properly handle proxying of requests. For example, the built-in `nginx-vhosts` proxy implementation supports both the `http` and `https` schemes. +The scheme metadata can be used by proxy implementations in order to properly handle proxying of requests. For example, the built-in `nginx-vhosts` proxy implementation supports the `http`, `https`, `grpc` and `grpcs` schemes. +For the `grpc` and `grpcs` see [nginx blog post on grpc](https://www.nginx.com/blog/nginx-1-13-10-grpc/). Developers of proxy implementations are encouraged to use whatever schemes make the most sense, and ignore configurations which they do not support. For instance, a `udp` proxy implementation can safely ignore `http` and `https` port mappings. From c4838b4af9b698fd9bafde15834db6a9217a8a5e Mon Sep 17 00:00:00 2001 From: fzerorubigd Date: Sat, 24 Aug 2019 10:58:34 +0200 Subject: [PATCH 06/39] add test for grpc on a port other than 80 fix docs a bout supporting only HTTP remove extra spaces --- docs/networking/port-management.md | 2 +- plugins/nginx-vhosts/functions | 1 - tests/unit/40_nginx-vhosts_3.bats | 7 +++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/networking/port-management.md b/docs/networking/port-management.md index 27431dd73..7e4629905 100644 --- a/docs/networking/port-management.md +++ b/docs/networking/port-management.md @@ -126,7 +126,7 @@ For buildpack deployments, your application *must* respect the `PORT` environmen > Changed as of 0.5.0 -Dokku's default proxy implementation - nginx - only supports HTTP request proxying. At this time, we do not support proxying plain TCP or UDP ports. UDP ports can be exposed by disabling the nginx proxy with `dokku proxy:disable myapp`. If you would like to investigate alternative proxy methods, please refer to our [proxy management documentation](/docs/advanced-usage/proxy-management.md). +Dokku's default proxy implementation - nginx - supports HTTP and GRPC request proxying. At this time, we do not support proxying plain TCP or UDP ports. UDP ports can be exposed by disabling the nginx proxy with `dokku proxy:disable myapp`. If you would like to investigate alternative proxy methods, please refer to our [proxy management documentation](/docs/advanced-usage/proxy-management.md). #### Applications using EXPOSE diff --git a/plugins/nginx-vhosts/functions b/plugins/nginx-vhosts/functions index c04530ace..03ab8637c 100755 --- a/plugins/nginx-vhosts/functions +++ b/plugins/nginx-vhosts/functions @@ -281,7 +281,6 @@ is_grpc_enabled() { echo $HAS_SUPPORT } - nginx_build_config() { declare desc="build nginx config to proxy app containers using sigil" local APP="$1" diff --git a/tests/unit/40_nginx-vhosts_3.bats b/tests/unit/40_nginx-vhosts_3.bats index 6336da6ea..65e184986 100644 --- a/tests/unit/40_nginx-vhosts_3.bats +++ b/tests/unit/40_nginx-vhosts_3.bats @@ -25,6 +25,13 @@ teardown() { assert_output "Greeting: Hello grpc" } +@test "(nginx-vhosts) grpc endpoint on a port other than 80" { + deploy_app gogrpc + dokku proxy:ports-add "$TEST_APP" "grpc:8080:50051" + run /bin/bash -c "docker run --rm ${TEST_APP}-docker-image /go/bin/greeter_client -address ${TEST_APP}.dokku.me:8080 -name grpc8080" + assert_output "Greeting: Hello grpc8080" +} + @test "(nginx-vhosts) grpcs endpoint" { setup_test_tls deploy_app gogrpc From 1be6ace7b55fd95f9922f4510b5123a8758af9c5 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 6 Sep 2019 21:06:33 -0400 Subject: [PATCH 07/39] feat: release latest docker image on release Also, always build a docker image for local testing. --- contrib/release-dokku | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/contrib/release-dokku b/contrib/release-dokku index d4ac927d5..75339bc66 100755 --- a/contrib/release-dokku +++ b/contrib/release-dokku @@ -323,7 +323,6 @@ fn-build-docker-image() { declare desc="Builds the dokku docker image and tags it with the given version" declare VERSION="$1" docker build -t "dokku/dokku:$VERSION" . - docker push "dokku/dokku:$VERSION" } main() { @@ -365,10 +364,15 @@ 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 + if [[ "$RELEASE" == "build" ]]; then + fn-build-docker-image "latest" || log-fail "Error building docker image" + else 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" + docker tag "dokku/dokku:$VERSION" "dokku/dokku:latest" + docker push "dokku/dokku:$VERSION" + docker push "dokku/dokku:latest" fn-repo-push-tags "$IS_RELEASE" fi From 53c8f61ffcce92eb28fa515a3b7412281a0fc3a6 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 6 Sep 2019 21:21:25 -0400 Subject: [PATCH 08/39] docs: fix reference to CHECKS file location Closes #3664 --- docs/deployment/zero-downtime-deploys.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/deployment/zero-downtime-deploys.md b/docs/deployment/zero-downtime-deploys.md index 7ebee5124..8c9465579 100644 --- a/docs/deployment/zero-downtime-deploys.md +++ b/docs/deployment/zero-downtime-deploys.md @@ -123,7 +123,7 @@ To specify checks, add a `CHECKS` file to the root of your project directory. Th - comments (lines starting with #) - empty lines -> For Dockerfile-based deploys, the file *must* be in `/app/CHECKS` within the container. `/app` is used by default as the root container directory for buildpack-based deploys. +> For Dockerfile and Docker Image based deploys, the file *must* be in the `WORKDIR` directory of the built image. `/app` is used by default as the root container directory for buildpack-based deploys. ### Check instructions From a36ebd130dc3c084e708332e218a26716310f374 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 6 Sep 2019 21:26:32 -0400 Subject: [PATCH 09/39] fix: upgrade all python test deps --- tests/apps/multi/requirements.txt | 4 ++-- tests/apps/python-flask/requirements.txt | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/apps/multi/requirements.txt b/tests/apps/multi/requirements.txt index f4154234b..93d7fd192 100644 --- a/tests/apps/multi/requirements.txt +++ b/tests/apps/multi/requirements.txt @@ -1,2 +1,2 @@ -Flask==0.10.1 -gunicorn==18.0 +Flask==1.1.1 +gunicorn==19.9.0 diff --git a/tests/apps/python-flask/requirements.txt b/tests/apps/python-flask/requirements.txt index 7299a1046..46d297b21 100644 --- a/tests/apps/python-flask/requirements.txt +++ b/tests/apps/python-flask/requirements.txt @@ -1,5 +1,5 @@ -Flask==0.9 -Jinja2==2.6 -Werkzeug==0.8.3 -gunicorn==0.17.2 +Flask==1.1.1 +Jinja2==2.10.1 +Werkzeug==0.15.6 +gunicorn==19.9.0 From 8cbaf1e004a30324a9e613bc1662107506d90a9e Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 9 Sep 2019 17:47:12 -0400 Subject: [PATCH 10/39] feat: allow overriding checks doc url --- docs/configuration/environment-variables.md | 1 + plugins/scheduler-docker-local/check-deploy | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/configuration/environment-variables.md b/docs/configuration/environment-variables.md index ce6ea8096..976259b19 100644 --- a/docs/configuration/environment-variables.md +++ b/docs/configuration/environment-variables.md @@ -90,6 +90,7 @@ The following list config variables have special meaning and can be set in a var | `DOKKU_EVENTS_LOGFILE` | `$DOKKU_LOGS_DIR/events.log` | `/etc/environment`
`~dokku/.dokkurc`
`~dokku/.dokkurc/*` | Where the events log file is written to. | | `DOKKU_APP_NAME` | none | `--app APP` flag | Name of application to work on. Respected by core plugins. | | `DOKKU_APPS_FORCE_DELETE` | none | `--force` flag | Whether to force delete an application. Also used by other plugins for destructive actions. | +| `DOKKU_CHECKS_URL` | `http://dokku.viewdocs.io/dokku/deployment/zero-downtime-deploys/` | `/etc/environment`
`~dokku/.dokkurc`
`~dokku/.dokkurc/*` | Url displayed during deployment when no CHECKS file exists. | | `DOKKU_DETACH_CONTAINER` | none | `--detach` flag | Whether to detach a container started via `dokku run`. | | `DOKKU_QUIET_OUTPUT` | none | `--quiet` flag | Silences certain header output for `dokku` commands. | | `DOKKU_RM_CONTAINER` | none | `dokku config:set`
`--rm-container` flag
`--rm` flag | Whether to keep `dokku run` containers around or not. | diff --git a/plugins/scheduler-docker-local/check-deploy b/plugins/scheduler-docker-local/check-deploy index 57321ff1e..2414aca8c 100755 --- a/plugins/scheduler-docker-local/check-deploy +++ b/plugins/scheduler-docker-local/check-deploy @@ -79,6 +79,7 @@ scheduler-docker-local-check-deploy() { local TIMEOUT="${DOKKU_CHECKS_TIMEOUT:-30}" # use this number of retries for checks local ATTEMPTS="${DOKKU_CHECKS_ATTEMPTS:-5}" + local CHECKS_URL="${DOKKU_CHECKS_URL:-http://dokku.viewdocs.io/dokku/deployment/zero-downtime-deploys/}" local CHECK_DEPLOY_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX") local CHECKS_FILENAME=${CHECK_DEPLOY_TMP_WORK_DIR}/CHECKS @@ -101,9 +102,8 @@ scheduler-docker-local-check-deploy() { if [[ ! -s "${CHECKS_FILENAME}" ]] || [[ "$DOKKU_APP_CONTAINER_TYPE" != "web" ]]; then # We allow custom check for web instances only if [[ "$DOKKU_APP_CONTAINER_TYPE" == "web" ]]; then - dokku_log_verbose "For more efficient zero downtime deployments, create a file CHECKS." - dokku_log_verbose "See http://dokku.viewdocs.io/dokku/deployment/zero-downtime-deploys/ for examples" dokku_log_verbose "CHECKS file not found in container: Running simple container check..." + dokku_log_verbose "For more efficient zero downtime deployments, create a file CHECKS. See ${CHECKS_URL} for examples" else dokku_log_verbose "Non web container detected: Running default container check..." fi From 92d2895d99d5f6f7a463d7e6adedb414ce8e477b Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 15 Sep 2019 17:17:56 -0400 Subject: [PATCH 11/39] feat: add container-type to run and deploy containers --- plugins/scheduler-docker-local/scheduler-deploy | 6 +++--- plugins/scheduler-docker-local/scheduler-run | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/scheduler-docker-local/scheduler-deploy b/plugins/scheduler-docker-local/scheduler-deploy index 9a5dc70f3..130609825 100755 --- a/plugins/scheduler-docker-local/scheduler-deploy +++ b/plugins/scheduler-docker-local/scheduler-deploy @@ -98,16 +98,16 @@ scheduler-docker-local-scheduler-deploy() { START_CMD=$(fn-scheduler-docker-local-extract-start-cmd "$APP" "$PROC_TYPE" "$START_CMD" "$DOKKU_HEROKUISH" "$DOKKU_PORT") if [[ "$DOKKU_NETWORK_BIND_ALL" == "false" ]]; then # shellcheck disable=SC2086 - cid=$("$DOCKER_BIN" run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -d -e PORT=$DOKKU_PORT "${ARG_ARRAY[@]}" $IMAGE $START_CMD) + cid=$("$DOCKER_BIN" run --label=com.dokku.container-type=deploy "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -d -e PORT=$DOKKU_PORT "${ARG_ARRAY[@]}" $IMAGE $START_CMD) else # shellcheck disable=SC2086 - cid=$("$DOCKER_BIN" run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -d $DOKKU_DOCKER_PORT_ARGS -e PORT=$DOKKU_PORT "${ARG_ARRAY[@]}" $IMAGE $START_CMD) + cid=$("$DOCKER_BIN" run --label=com.dokku.container-type=deploy "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -d $DOKKU_DOCKER_PORT_ARGS -e PORT=$DOKKU_PORT "${ARG_ARRAY[@]}" $IMAGE $START_CMD) fi else START_CMD=$(fn-scheduler-docker-local-extract-start-cmd "$APP" "$PROC_TYPE" "$START_CMD" "$DOKKU_HEROKUISH") # shellcheck disable=SC2086 - cid=$("$DOCKER_BIN" run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -d "${ARG_ARRAY[@]}" $IMAGE $START_CMD) + cid=$("$DOCKER_BIN" run --label=com.dokku.container-type=deploy "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -d "${ARG_ARRAY[@]}" $IMAGE $START_CMD) fi ipaddr=$(plugn trigger network-get-ipaddr "$APP" "$PROC_TYPE" "$cid") diff --git a/plugins/scheduler-docker-local/scheduler-run b/plugins/scheduler-docker-local/scheduler-run index d72d1f30b..2d4b045a8 100755 --- a/plugins/scheduler-docker-local/scheduler-run +++ b/plugins/scheduler-docker-local/scheduler-run @@ -67,7 +67,7 @@ scheduler-docker-local-scheduler-run() { fi # shellcheck disable=SC2086 - "$DOCKER_BIN" run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS "${DOCKER_ARGS_ARRAY[@]}" $IMAGE $EXEC_CMD "$@" + "$DOCKER_BIN" run --label=com.dokku.container-type=run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS "${DOCKER_ARGS_ARRAY[@]}" $IMAGE $EXEC_CMD "$@" } scheduler-docker-local-scheduler-run "$@" From 44fcea0ffa77d1d6eddf15655d3c48dc0d94f701 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Wed, 29 May 2019 04:05:24 -0400 Subject: [PATCH 12/39] refactor: use new-style docker management commands This PR uses the new syntax for commands introduced in Docker 1.13, making it a bit easier to understand just what a particular command is trying to do. This also pushes the long-form syntax for docker command flags, which are also easier to understand at a glance. --- debian/control | 2 +- docs/development/plugin-creation.md | 8 ++-- plugins/00_dokku-standard/subcommands/report | 4 +- plugins/app-json/internal-functions | 6 +-- plugins/apps/post-delete | 2 +- plugins/apps/subcommands/clone | 2 +- plugins/apps/subcommands/rename | 2 +- plugins/builder-dockerfile/builder-build | 2 +- plugins/builder-herokuish/builder-build | 14 +++---- plugins/builder-herokuish/builder-release | 12 +++--- plugins/builder-herokuish/pre-build-buildpack | 12 +++--- plugins/common/common.go | 2 +- plugins/common/functions | 42 +++++++++---------- plugins/enter/subcommands/default | 2 +- plugins/network/network.go | 2 +- plugins/ps/internal-functions | 2 +- plugins/ps/subcommands/default | 2 +- plugins/repo/repo.go | 3 +- plugins/scheduler-docker-local/check-deploy | 4 +- .../scheduler-docker-local/core-post-deploy | 10 ++--- .../scheduler-docker-local/internal-functions | 12 +++--- plugins/scheduler-docker-local/post-delete | 6 +-- plugins/scheduler-docker-local/pre-deploy | 2 +- plugins/scheduler-docker-local/pre-restore | 2 +- .../scheduler-docker-local/scheduler-deploy | 16 +++---- .../scheduler-docker-cleanup | 12 +++--- .../scheduler-docker-local/scheduler-inspect | 2 +- .../scheduler-logs-failed | 2 +- .../scheduler-docker-local/scheduler-retire | 6 +-- plugins/scheduler-docker-local/scheduler-run | 2 +- plugins/scheduler-docker-local/scheduler-stop | 4 +- .../scheduler-tags-create | 2 +- .../scheduler-tags-destroy | 2 +- plugins/tags/subcommands/default | 2 +- 34 files changed, 104 insertions(+), 103 deletions(-) diff --git a/debian/control b/debian/control index 3437b3a05..e883b4f8d 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Version: 0.18.3 Section: web Priority: optional Architecture: amd64 -Depends: locales, git, curl, man-db, netcat, sshcommand (>= 0.6.0), gliderlabs-sigil, docker-engine-cs (>= 1.7.1) | docker-engine (>= 1.7.1) | docker-io (>= 1.7.1) | docker.io (>= 1.7.1) | docker-ce | docker-ee, net-tools, software-properties-common, procfile-util, python-software-properties | python3-software-properties, rsyslog, dos2unix +Depends: locales, git, curl, man-db, netcat, sshcommand (>= 0.6.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 Recommends: herokuish (>= 0.3.4), parallel, dokku-update Pre-Depends: nginx (>= 1.8.0) | openresty, dnsutils, cgroupfs-mount | cgroup-lite, plugn (>= 0.3.0), sudo, python2.7, debconf Maintainer: Jose Diaz-Gonzalez diff --git a/docs/development/plugin-creation.md b/docs/development/plugin-creation.md index 642655163..162389ac1 100644 --- a/docs/development/plugin-creation.md +++ b/docs/development/plugin-creation.md @@ -159,7 +159,7 @@ Certain systems may require a wrapper function around the `docker` binary for pr ```shell # good -"$DOCKER_BIN" run -d $IMAGE /bin/bash -e -c "$COMMAND" +"$DOCKER_BIN" container run -d $IMAGE /bin/bash -e -c "$COMMAND" # bad docker run -d $IMAGE /bin/bash -e -c "$COMMAND" @@ -175,16 +175,16 @@ Note that where possible, a label `com.dokku.app-name=$APP` - where `$APP` is th ```shell # `docker build` example -"$DOCKER_BIN" build "--label=com.dokku.app-name=${APP}" $DOKKU_GLOBAL_BUILD_ARGS ... +"$DOCKER_BIN" image build "--label=com.dokku.app-name=${APP}" $DOKKU_GLOBAL_BUILD_ARGS ... # `docker commit` example # Note that the arguments must be set as a local array # as arrays cannot be exported in shell local DOKKU_COMMIT_ARGS=("--change" "LABEL org.label-schema.schema-version=1.0" "--change" "LABEL org.label-schema.vendor=dokku" "--change" "LABEL $DOKKU_CONTAINER_LABEL=") -"$DOCKER_BIN" commit --change "LABEL com.dokku.app-name=$APP" "${DOKKU_COMMIT_ARGS[@]}" ... +"$DOCKER_BIN" container commit --change "LABEL com.dokku.app-name=$APP" "${DOKKU_COMMIT_ARGS[@]}" ... # `docker run` example -"$DOCKER_BIN" run "--label=com.dokku.app-name=${APP}" $DOKKU_GLOBAL_RUN_ARGS ... +"$DOCKER_BIN" container run "--label=com.dokku.app-name=${APP}" $DOKKU_GLOBAL_RUN_ARGS ... ``` ## Copy files from the built image using `copy_from_image` diff --git a/plugins/00_dokku-standard/subcommands/report b/plugins/00_dokku-standard/subcommands/report index cc3975a77..a8751baf3 100755 --- a/plugins/00_dokku-standard/subcommands/report +++ b/plugins/00_dokku-standard/subcommands/report @@ -14,10 +14,10 @@ dokku_report_cmd() { dokku_log_info1 "docker version: " "$DOCKER_BIN" version | sed "s/^/ /" dokku_log_info1 "docker daemon info: " - "$DOCKER_BIN" -D info | sed "s/^/ /" + "$DOCKER_BIN" -D system info | sed "s/^/ /" dokku_log_info1 "sigil version: $(sigil -v)" dokku_log_info1 "herokuish version: " - "$DOCKER_BIN" run $DOKKU_GLOBAL_RUN_ARGS --rm "$DOKKU_IMAGE" herokuish version | sed "s/^/ /" + "$DOCKER_BIN" container run $DOKKU_GLOBAL_RUN_ARGS --rm "$DOKKU_IMAGE" herokuish version | sed "s/^/ /" dokku_log_info1 "dokku version: $(dokku version)" dokku_log_info1 "dokku plugins: " dokku plugin:list | sed "s/^/ /" diff --git a/plugins/app-json/internal-functions b/plugins/app-json/internal-functions index fe2aca3f7..b5adb2c6c 100755 --- a/plugins/app-json/internal-functions +++ b/plugins/app-json/internal-functions @@ -98,8 +98,8 @@ execute_script() { DOKKU_APP_SHELL="$(config_get "$APP" DOKKU_APP_SHELL || echo "$DOKKU_APP_SHELL")" [[ -z "$DOKKU_APP_SHELL" ]] && DOKKU_APP_SHELL="/bin/bash" - id=$("$DOCKER_BIN" run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -e DOKKU_TRACE="$DOKKU_TRACE" --label=dokku_phase_script="${PHASE_SCRIPT_KEY}" -d -v "$CACHE_HOST_DIR:/cache" "${ARG_ARRAY[@]}" "$IMAGE" "$DOKKU_APP_SHELL" -c "$COMMAND") - if test "$("$DOCKER_BIN" wait "$id")" -ne 0; then + id=$("$DOCKER_BIN" container run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS --env DOKKU_TRACE="$DOKKU_TRACE" --label=dokku_phase_script="${PHASE_SCRIPT_KEY}" -d -v "$CACHE_HOST_DIR:/cache" "${ARG_ARRAY[@]}" "$IMAGE" "$DOKKU_APP_SHELL" -c "$COMMAND") + if test "$("$DOCKER_BIN" container wait "$id")" -ne 0; then dokku_container_log_verbose_quiet "$id" dokku_log_fail "execution of '$SCRIPT_CMD' failed!" fi @@ -121,5 +121,5 @@ execute_script() { local DOCKER_COMMIT_ARGS="$DOCKER_COMMIT_ENTRYPOINT_CHANGE_ARG $DOCKER_COMMIT_CMD_CHANGE_ARG" fi - eval "$DOCKER_BIN" commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "${DOCKER_COMMIT_ARGS[@]}" "$id" "$IMAGE" >/dev/null + eval "$DOCKER_BIN" container commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "${DOCKER_COMMIT_ARGS[@]}" "$id" "$IMAGE" >/dev/null } diff --git a/plugins/apps/post-delete b/plugins/apps/post-delete index 8efe6e80d..1a5d60dd7 100755 --- a/plugins/apps/post-delete +++ b/plugins/apps/post-delete @@ -16,7 +16,7 @@ app_post_delete() { fi # shellcheck disable=SC2046 - "$DOCKER_BIN" rmi $("$DOCKER_BIN" images -q "$IMAGE_REPO" | xargs) &>/dev/null || true + "$DOCKER_BIN" image rm $("$DOCKER_BIN" image list --quiet "$IMAGE_REPO" | xargs) &>/dev/null || true } app_post_delete "$@" diff --git a/plugins/apps/subcommands/clone b/plugins/apps/subcommands/clone index 9bcecbca4..8ab7ec1a3 100755 --- a/plugins/apps/subcommands/clone +++ b/plugins/apps/subcommands/clone @@ -46,7 +46,7 @@ apps_clone_cmd() { plugn trigger post-app-clone-setup "$OLD_APP" "$NEW_APP" if [[ -d "$NEW_CACHE_DIR" ]] && ! rmdir "$NEW_CACHE_DIR"; then - "$DOCKER_BIN" run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS --rm -v "$NEW_CACHE_HOST_DIR:/cache" "dokku/$OLD_APP" chmod 777 -R /cache + "$DOCKER_BIN" container run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS --rm --volume "$NEW_CACHE_HOST_DIR:/cache" "dokku/$OLD_APP" chmod 777 -R /cache fi rm -rf "$NEW_CACHE_DIR" diff --git a/plugins/apps/subcommands/rename b/plugins/apps/subcommands/rename index ade93e38a..ed94cb1dc 100755 --- a/plugins/apps/subcommands/rename +++ b/plugins/apps/subcommands/rename @@ -18,7 +18,7 @@ apps_rename_cmd() { local DOCKER_RUN_LABEL_ARGS="--label=com.dokku.app-name=$OLD_APP" if [[ -d "$OLD_CACHE_DIR" ]] && ! rmdir "$OLD_CACHE_DIR" >/dev/null 2>&1; then - "$DOCKER_BIN" run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS --rm -v "$OLD_CACHE_HOST_DIR:/cache" "dokku/$OLD_APP" chmod 777 -R /cache + "$DOCKER_BIN" container run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS --rm --volume "$OLD_CACHE_HOST_DIR:/cache" "dokku/$OLD_APP" chmod 777 -R /cache fi rm -rf "$OLD_CACHE_DIR" apps_create "$NEW_APP" diff --git a/plugins/builder-dockerfile/builder-build b/plugins/builder-dockerfile/builder-build index 79563ac31..ccf27252f 100755 --- a/plugins/builder-dockerfile/builder-build +++ b/plugins/builder-dockerfile/builder-build @@ -37,7 +37,7 @@ trigger-builder-build-builder-dockerfile() { declare -a ARG_ARRAY eval "ARG_ARRAY=($DOCKER_ARGS)" - "$DOCKER_BIN" build "${DOCKER_BUILD_LABEL_ARGS[@]}" $DOKKU_GLOBAL_BUILD_ARGS "${ARG_ARRAY[@]}" "${DOKKU_DOCKER_BUILD_OPTS[@]}" -t $IMAGE . + "$DOCKER_BIN" image build "${DOCKER_BUILD_LABEL_ARGS[@]}" $DOKKU_GLOBAL_BUILD_ARGS "${ARG_ARRAY[@]}" "${DOKKU_DOCKER_BUILD_OPTS[@]}" -t $IMAGE . plugn trigger post-build-dockerfile "$APP" } diff --git a/plugins/builder-herokuish/builder-build b/plugins/builder-herokuish/builder-build index f881eb86c..602edb498 100755 --- a/plugins/builder-herokuish/builder-build +++ b/plugins/builder-herokuish/builder-build @@ -28,13 +28,13 @@ trigger-builder-build-builder-herokuish() { NEW_DOKKU_IMAGE=$(plugn trigger builder-dokku-image "$BUILDER_TYPE" "$APP" "$SOURCECODE_WORK_DIR" "$DOKKU_IMAGE") [[ -n "$NEW_DOKKU_IMAGE" ]] && DOKKU_IMAGE="$NEW_DOKKU_IMAGE" - CID=$(tar -c . | "$DOCKER_BIN" run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -i -a stdin "$DOKKU_IMAGE" /bin/bash -c "mkdir -p /app && tar -xC /app") - if test "$("$DOCKER_BIN" wait "$CID")" -ne 0; then + CID=$(tar -c . | "$DOCKER_BIN" container run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -i -a stdin "$DOKKU_IMAGE" /bin/bash -c "mkdir -p /app && tar -xC /app") + if test "$("$DOCKER_BIN" container wait "$CID")" -ne 0; then dokku_log_warn "Failure extracting app code" return 1 fi - "$DOCKER_BIN" commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "$CID" "$IMAGE" >/dev/null + "$DOCKER_BIN" container commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "$CID" "$IMAGE" >/dev/null [[ -d $DOKKU_APP_CACHE_DIR ]] || mkdir -p "$DOKKU_APP_CACHE_DIR" plugn trigger pre-build-buildpack "$APP" "$SOURCECODE_WORK_DIR" @@ -45,14 +45,14 @@ trigger-builder-build-builder-herokuish() { declare -a ARG_ARRAY eval "ARG_ARRAY=($DOCKER_ARGS)" # shellcheck disable=SC2086 - CID=$("$DOCKER_BIN" run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -d -v $DOKKU_APP_HOST_CACHE_DIR:/cache -e CACHE_PATH=/cache "${ARG_ARRAY[@]}" $IMAGE /build) - "$DOCKER_BIN" attach "$CID" - if test "$("$DOCKER_BIN" wait "$CID")" -ne 0; then + CID=$("$DOCKER_BIN" container run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -d -v $DOKKU_APP_HOST_CACHE_DIR:/cache -e CACHE_PATH=/cache "${ARG_ARRAY[@]}" $IMAGE /build) + "$DOCKER_BIN" container attach "$CID" + if test "$("$DOCKER_BIN" container wait "$CID")" -ne 0; then dokku_log_warn "Failure during app build" return 1 fi - "$DOCKER_BIN" commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "$CID" "$IMAGE" >/dev/null + "$DOCKER_BIN" container commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "$CID" "$IMAGE" >/dev/null plugn trigger post-build-buildpack "$APP" "$SOURCECODE_WORK_DIR" } diff --git a/plugins/builder-herokuish/builder-release b/plugins/builder-herokuish/builder-release index 2292c7a22..952e6de92 100755 --- a/plugins/builder-herokuish/builder-release +++ b/plugins/builder-herokuish/builder-release @@ -19,22 +19,22 @@ trigger-builder-release-builder-herokuish() { plugn trigger pre-release-buildpack "$APP" "$IMAGE_TAG" if [[ -n $(config_export global) ]]; then - CID=$(config_export global | "$DOCKER_BIN" run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/00-global-env.sh") - if test "$("$DOCKER_BIN" wait "$CID")" -ne 0; then + CID=$(config_export global | "$DOCKER_BIN" container run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/00-global-env.sh") + if test "$("$DOCKER_BIN" container wait "$CID")" -ne 0; then dokku_log_warn "Failure injecting global environment variables" return 1 fi - "$DOCKER_BIN" commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "$CID" "$IMAGE" >/dev/null + "$DOCKER_BIN" container commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "$CID" "$IMAGE" >/dev/null fi if [[ -n $(config_export app "$APP") ]]; then - CID=$(config_export app "$APP" | "$DOCKER_BIN" run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/01-app-env.sh") - if test "$("$DOCKER_BIN" wait "$CID")" -ne 0; then + CID=$(config_export app "$APP" | "$DOCKER_BIN" container run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/01-app-env.sh") + if test "$("$DOCKER_BIN" container wait "$CID")" -ne 0; then dokku_log_warn "Failure injecting app environment variables" return 1 fi - "$DOCKER_BIN" commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "$CID" "$IMAGE" >/dev/null + "$DOCKER_BIN" container commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "$CID" "$IMAGE" >/dev/null fi plugn trigger post-release-buildpack "$APP" "$IMAGE_TAG" } diff --git a/plugins/builder-herokuish/pre-build-buildpack b/plugins/builder-herokuish/pre-build-buildpack index e82b5cc1e..e0f2ff6e3 100755 --- a/plugins/builder-herokuish/pre-build-buildpack +++ b/plugins/builder-herokuish/pre-build-buildpack @@ -22,22 +22,22 @@ trigger-pre-build-buildpack-builder-herokuish() { dokku_log_info1 "Adding BUILD_ENV to build environment..." # create build env files for use in buildpacks like this: # https://github.com/niteoweb/heroku-buildpack-buildout/blob/5879fa3418f7d8e079f1aa5816ba1adde73f4948/bin/compile#L34 - CID=$(config_bundle --merged "$APP" | "$DOCKER_BIN" run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /tmp/env; cat | tar -x -C /tmp/env") - if test "$("$DOCKER_BIN" wait "$CID")" -ne 0; then + CID=$(config_bundle --merged "$APP" | "$DOCKER_BIN" container run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /tmp/env; cat | tar -x -C /tmp/env") + if test "$("$DOCKER_BIN" container wait "$CID")" -ne 0; then dokku_log_warn "Failure injecting BUILD_ENV into build environment" return 1 fi - "$DOCKER_BIN" commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "$CID" "$IMAGE" >/dev/null + "$DOCKER_BIN" container commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "$CID" "$IMAGE" >/dev/null # create build env for 'old style' buildpacks and dokku plugins - CID=$(config_export app "$APP" --format envfile --merged | "$DOCKER_BIN" run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -i -a stdin "$IMAGE" /bin/bash -c "cat >> /app/.env") - if test "$("$DOCKER_BIN" wait "$CID")" -ne 0; then + CID=$(config_export app "$APP" --format envfile --merged | "$DOCKER_BIN" container run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -i -a stdin "$IMAGE" /bin/bash -c "cat >> /app/.env") + if test "$("$DOCKER_BIN" container wait "$CID")" -ne 0; then dokku_log_warn "Failure injecting old-style BUILD_ENV" return 1 fi - "$DOCKER_BIN" commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "$CID" "$IMAGE" >/dev/null + "$DOCKER_BIN" container commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "$CID" "$IMAGE" >/dev/null } trigger-pre-build-buildpack-builder-herokuish "$@" diff --git a/plugins/common/common.go b/plugins/common/common.go index 0f70f8d59..23038b960 100644 --- a/plugins/common/common.go +++ b/plugins/common/common.go @@ -325,7 +325,7 @@ func VerifyAppName(appName string) (err error) { // VerifyImage returns true if docker image exists in local repo func VerifyImage(image string) bool { - imageCmd := NewShellCmd(strings.Join([]string{DockerBin(), "inspect", image}, " ")) + imageCmd := NewShellCmd(strings.Join([]string{DockerBin(), "image", "inspect", image}, " ")) imageCmd.ShowOutput = false return imageCmd.Execute() } diff --git a/plugins/common/functions b/plugins/common/functions index ebf714ab8..374f2f58d 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -171,7 +171,7 @@ dokku_container_log_verbose_quiet() { OIFS=$IFS IFS=$'\n' local line - for line in $("$DOCKER_BIN" logs "$CID" 2>&1); do + for line in $("$DOCKER_BIN" container logs "$CID" 2>&1); do dokku_log_verbose_quiet "$line" done IFS=$OIFS @@ -203,7 +203,7 @@ verify_app_name() { verify_image() { declare desc="verify image existence" local IMAGE="$1" - if "$DOCKER_BIN" inspect "$IMAGE" &>/dev/null; then + if "$DOCKER_BIN" image inspect "$IMAGE" &>/dev/null; then return 0 else return 1 @@ -286,7 +286,7 @@ get_running_image_tag() { verify_app_name "$APP" local CIDS=($(get_app_container_ids "$APP")) - local RUNNING_IMAGE_TAG=$("$DOCKER_BIN" inspect -f '{{ .Config.Image }}' "${CIDS[0]}" 2>/dev/null | awk -F: '{ print $2 }' || echo '') + local RUNNING_IMAGE_TAG=$("$DOCKER_BIN" container inspect --format '{{ .Config.Image }}' "${CIDS[0]}" 2>/dev/null | awk -F: '{ print $2 }' || echo '') echo "$RUNNING_IMAGE_TAG" } @@ -300,13 +300,13 @@ is_image_herokuish_based() { fi # due to how the build process works, all herokuish images have the Environment variable USER=herokuishuser - USER_VALUE="$("$DOCKER_BIN" inspect -f '{{range .Config.Env}}{{if eq . "USER=herokuishuser" }}{{println .}}{{end}}{{end}}' "$IMAGE")" + USER_VALUE="$("$DOCKER_BIN" image inspect --format '{{range .Config.Env}}{{if eq . "USER=herokuishuser" }}{{println .}}{{end}}{{end}}' "$IMAGE")" [[ "$USER_VALUE" == "" ]] && return 1 return 0 } get_docker_version() { - CLIENT_VERSION_STRING="$("$DOCKER_BIN" version -f="{{ .Client.Version }}")" + CLIENT_VERSION_STRING="$("$DOCKER_BIN" version --format "{{ .Client.Version }}")" echo "$CLIENT_VERSION_STRING" } @@ -382,7 +382,7 @@ copy_from_image() { if is_image_herokuish_based "$IMAGE"; then WORKDIR="/app" else - WORKDIR="$("$DOCKER_BIN" inspect -f '{{.Config.WorkingDir}}' "$IMAGE")" + WORKDIR="$("$DOCKER_BIN" image inspect --format '{{.Config.WorkingDir}}' "$IMAGE")" fi if [[ -n "$WORKDIR" ]]; then @@ -393,9 +393,9 @@ copy_from_image() { TMP_FILE_COMMAND_OUTPUT=$(mktemp "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX") trap "rm -rf '$TMP_FILE_COMMAND_OUTPUT' >/dev/null 2>&1 || true" RETURN - local CID=$("$DOCKER_BIN" create "${DOCKER_CREATE_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS "$IMAGE") - "$DOCKER_BIN" cp "$CID:$SRC_FILE" "$TMP_FILE_COMMAND_OUTPUT" 2>/dev/null || true - "$DOCKER_BIN" rm -f "$CID" &>/dev/null + local CID=$("$DOCKER_BIN" container create "${DOCKER_CREATE_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS "$IMAGE") + "$DOCKER_BIN" container cp "$CID:$SRC_FILE" "$TMP_FILE_COMMAND_OUTPUT" 2>/dev/null || true + "$DOCKER_BIN" container rm --force "$CID" &>/dev/null # docker cp exits with status 1 when run as non-root user when it tries to chown the file # after successfully copying the file. Thus, we suppress stderr. @@ -492,7 +492,7 @@ is_container_running() { local CONTAINER_STATUS dokku_log_warn "Deprecated: common#is_container_status" - CONTAINER_STATUS=$("$DOCKER_BIN" inspect -f '{{.State.Running}}' "$CID" || true) + CONTAINER_STATUS=$("$DOCKER_BIN" container inspect --format '{{.State.Running}}' "$CID" || true) if [[ "$CONTAINER_STATUS" == "true" ]]; then return 0 @@ -505,7 +505,7 @@ is_container_status() { declare desc="return 0 if given docker container id is in given state" local CID=$1 local TEMPLATE="{{.State.$2}}" - local CONTAINER_STATUS=$("$DOCKER_BIN" inspect -f "$TEMPLATE" "$CID" 2>/dev/null || true) + local CONTAINER_STATUS=$("$DOCKER_BIN" container inspect --format "$TEMPLATE" "$CID" 2>/dev/null || true) if [[ "$CONTAINER_STATUS" == "true" ]]; then return 0 @@ -641,30 +641,30 @@ docker_cleanup() { if [[ -n "$APP" ]]; then # delete all non-running containers # shellcheck disable=SC2046 - "$DOCKER_BIN" rm $("$DOCKER_BIN" ps -a -f "status=exited" -f "label=$DOKKU_CONTAINER_LABEL" -f "label=com.dokku.app-name=$APP" -q) &>/dev/null || true + "$DOCKER_BIN" container rm $("$DOCKER_BIN" container list --all --filter "status=exited" --filter "label=$DOKKU_CONTAINER_LABEL" --filter "label=com.dokku.app-name=$APP" --quiet) &>/dev/null || true # delete all dead containers # shellcheck disable=SC2046 - "$DOCKER_BIN" rm $("$DOCKER_BIN" ps -a -f "status=dead" -f "label=$DOKKU_CONTAINER_LABEL" -f "label=com.dokku.app-name=$APP" -q) &>/dev/null || true + "$DOCKER_BIN" container rm $("$DOCKER_BIN" container list --all --filter "status=dead" --filter "label=$DOKKU_CONTAINER_LABEL" --filter "label=com.dokku.app-name=$APP" --quiet) &>/dev/null || true # delete danging images # shellcheck disable=SC2046 - "$DOCKER_BIN" rmi $("$DOCKER_BIN" images -f 'dangling=true' -f "label=com.dokku.app-name=$APP" -q) &>/dev/null || true + "$DOCKER_BIN" image rm $("$DOCKER_BIN" image list --filter 'dangling=true' --filter "label=com.dokku.app-name=$APP" --quiet) &>/dev/null || true # delete unused images "$DOCKER_BIN" image prune --all --filter "label=com.dokku.app-name=$APP" --force &>/dev/null || true else # delete all non-running containers # shellcheck disable=SC2046 - "$DOCKER_BIN" rm $("$DOCKER_BIN" ps -a -f "status=exited" -f "label=$DOKKU_CONTAINER_LABEL" -q) &>/dev/null || true + "$DOCKER_BIN" container rm $("$DOCKER_BIN" container list --all --filter "status=exited" --filter "label=$DOKKU_CONTAINER_LABEL" --quiet) &>/dev/null || true # delete all dead containers # shellcheck disable=SC2046 - "$DOCKER_BIN" rm $("$DOCKER_BIN" ps -a -f "status=dead" -f "label=$DOKKU_CONTAINER_LABEL" -q) &>/dev/null || true + "$DOCKER_BIN" container rm $("$DOCKER_BIN" container list --all --filter "status=dead" --filter "label=$DOKKU_CONTAINER_LABEL" --quiet) &>/dev/null || true # delete danging images # shellcheck disable=SC2046 - "$DOCKER_BIN" rmi $("$DOCKER_BIN" images -f 'dangling=true' -q) &>/dev/null || true + "$DOCKER_BIN" image rm $("$DOCKER_BIN" image list --filter 'dangling=true' --quiet) &>/dev/null || true fi } @@ -747,7 +747,7 @@ get_exposed_ports_from_image() { local IMAGE="$1" verify_image "$IMAGE" # shellcheck disable=SC2016 - local DOCKER_IMAGE_EXPOSED_PORTS="$("$DOCKER_BIN" inspect -f '{{range $key, $value := .Config.ExposedPorts}}{{$key}} {{end}}' "$IMAGE")" + local DOCKER_IMAGE_EXPOSED_PORTS="$("$DOCKER_BIN" image inspect --format '{{range $key, $value := .Config.ExposedPorts}}{{$key}} {{end}}' "$IMAGE")" echo "$DOCKER_IMAGE_EXPOSED_PORTS" } @@ -755,7 +755,7 @@ get_entrypoint_from_image() { declare desc="return .Config.Entrypoint from passed image name" local IMAGE="$1" verify_image "$IMAGE" - local DOCKER_IMAGE_ENTRYPOINT="$("$DOCKER_BIN" inspect --format '{{range .Config.Entrypoint}}{{.}} {{end}}' "$IMAGE")" + local DOCKER_IMAGE_ENTRYPOINT="$("$DOCKER_BIN" image inspect --format '{{range .Config.Entrypoint}}{{.}} {{end}}' "$IMAGE")" echo "ENTRYPOINT $DOCKER_IMAGE_ENTRYPOINT" } @@ -763,7 +763,7 @@ get_cmd_from_image() { declare desc="return .Config.Cmd from passed image name" local IMAGE="$1" verify_image "$IMAGE" - local DOCKER_IMAGE_CMD="$("$DOCKER_BIN" inspect --format '{{range .Config.Cmd}}{{.}} {{end}}' "$IMAGE")" + local DOCKER_IMAGE_CMD="$("$DOCKER_BIN" image inspect --format '{{range .Config.Cmd}}{{.}} {{end}}' "$IMAGE")" DOCKER_IMAGE_CMD="${DOCKER_IMAGE_CMD/\/bin\/sh -c/}" echo "CMD $DOCKER_IMAGE_CMD" } @@ -801,7 +801,7 @@ get_container_ports() { local cid for cid in $APP_CIDS; do - local container_ports="$("$DOCKER_BIN" port "$cid" | awk '{ print $3 "->" $1}' | awk -F ":" '{ print $2 }')" + local container_ports="$("$DOCKER_BIN" container port "$cid" | awk '{ print $3 "->" $1}' | awk -F ":" '{ print $2 }')" done echo "$container_ports" diff --git a/plugins/enter/subcommands/default b/plugins/enter/subcommands/default index 5eb6ffbc3..35e8b06bb 100755 --- a/plugins/enter/subcommands/default +++ b/plugins/enter/subcommands/default @@ -60,7 +60,7 @@ enter_default_cmd() { has_tty && local DOKKU_RUN_OPTS+=" -i -t" is_image_herokuish_based "$IMAGE" && local EXEC_CMD="/exec" # shellcheck disable=SC2086 - "$DOCKER_BIN" exec $DOKKU_RUN_OPTS $ID $EXEC_CMD "${@:-$DOKKU_APP_SHELL}" + "$DOCKER_BIN" container exec $DOKKU_RUN_OPTS $ID $EXEC_CMD "${@:-$DOKKU_APP_SHELL}" } enter_default_cmd "$@" diff --git a/plugins/network/network.go b/plugins/network/network.go index c561986a8..eab00bb06 100644 --- a/plugins/network/network.go +++ b/plugins/network/network.go @@ -132,7 +132,7 @@ func GetContainerPort(appName, processType string, isHerokuishContainer bool, co break } } - cmd := sh.Command(common.DockerBin(), "port", containerID, port) + cmd := sh.Command(common.DockerBin(), "container", "port", containerID, port) cmd.Stderr = ioutil.Discard b, err := cmd.Output() if err == nil { diff --git a/plugins/ps/internal-functions b/plugins/ps/internal-functions index dc816f641..ca775b8f9 100755 --- a/plugins/ps/internal-functions +++ b/plugins/ps/internal-functions @@ -62,7 +62,7 @@ cmd-ps-report-single() { local APP_CONTAINER_STATUS for CONTAINER_FILE in $CONTAINER_FILES; do CID=$(<"$DOKKU_ROOT/$APP/$CONTAINER_FILE") - APP_CONTAINER_STATUS=$("$DOCKER_BIN" inspect -f '{{.State.Status}}' "$CID" 2>/dev/null || true) + APP_CONTAINER_STATUS=$("$DOCKER_BIN" container inspect --format '{{.State.Status}}' "$CID" 2>/dev/null || true) [[ -z "$APP_CONTAINER_STATUS" ]] && APP_CONTAINER_STATUS="missing" STATUSES+=("${CONTAINER_FILE#*.}:$APP_CONTAINER_STATUS#${CID:0:12}") done diff --git a/plugins/ps/subcommands/default b/plugins/ps/subcommands/default index 8fc9f35c2..cd34876e1 100755 --- a/plugins/ps/subcommands/default +++ b/plugins/ps/subcommands/default @@ -21,7 +21,7 @@ ps_main_cmd() { has_tty && local DOKKU_RUN_OPTS="-i -t" dokku_log_info1_quiet "running processes in container: $CID" # shellcheck disable=SC2086 - "$DOCKER_BIN" exec $DOKKU_RUN_OPTS $CID /bin/sh -c "ps auxwww" + "$DOCKER_BIN" container exec $DOKKU_RUN_OPTS $CID /bin/sh -c "ps auxwww" done } diff --git a/plugins/repo/repo.go b/plugins/repo/repo.go index 8474d6482..ce7813cd8 100644 --- a/plugins/repo/repo.go +++ b/plugins/repo/repo.go @@ -24,7 +24,8 @@ func PurgeCache(appName string) error { dockerLabelArgs := fmt.Sprintf("--label=com.dokku.app-name=%s", appName) purgeCacheCmd := common.NewShellCmd(strings.Join([]string{ common.DockerBin(), - "run --rm", dockerLabelArgs, dokkuGlobalRunArgs, + "container", + "run", "--rm", dockerLabelArgs, dokkuGlobalRunArgs, "-v", strings.Join([]string{cacheHostDir, ":/cache"}, ""), image, `find /cache -depth -mindepth 1 -maxdepth 1 -exec rm -Rf {} ;`}, " ")) purgeCacheCmd.Execute() diff --git a/plugins/scheduler-docker-local/check-deploy b/plugins/scheduler-docker-local/check-deploy index 2414aca8c..52eca560b 100755 --- a/plugins/scheduler-docker-local/check-deploy +++ b/plugins/scheduler-docker-local/check-deploy @@ -116,10 +116,10 @@ scheduler-docker-local-check-deploy() { sleep "$DOKKU_DEFAULT_CHECKS_WAIT" ! (is_container_status "$DOKKU_APP_CONTAINER_ID" "Running") && dokku_log_fail "App container failed to start!!" - local container_restarts="$("$DOCKER_BIN" inspect -f "{{ .RestartCount }}" "$DOKKU_APP_CONTAINER_ID")" + local container_restarts="$("$DOCKER_BIN" container inspect --format "{{ .RestartCount }}" "$DOKKU_APP_CONTAINER_ID")" if [[ $container_restarts -ne 0 ]]; then "$DOCKER_BIN" container update --restart=no "$DOKKU_APP_CONTAINER_ID" &>/dev/null || true - "$DOCKER_BIN" stop "$DOKKU_APP_CONTAINER_ID" || true + "$DOCKER_BIN" container stop "$DOKKU_APP_CONTAINER_ID" || true dokku_log_fail "App container failed to start!!" fi diff --git a/plugins/scheduler-docker-local/core-post-deploy b/plugins/scheduler-docker-local/core-post-deploy index f6733ade8..c2bb39db5 100755 --- a/plugins/scheduler-docker-local/core-post-deploy +++ b/plugins/scheduler-docker-local/core-post-deploy @@ -37,26 +37,26 @@ scheduler-docker-local-core-post-deploy() { local NAME="$APP.$DYNO" local CURRENT_CONTAINER_ID="$(<"$container")" # TODO: Ensure these are from the current service - local PREVIOUS_CIDS=$("$DOCKER_BIN" ps -a -q -f name="^.?$NAME\$" | xargs) || true + local PREVIOUS_CIDS=$("$DOCKER_BIN" container list --all --quiet --filter name="^.?$NAME\$" | xargs) || true if [[ -n $PREVIOUS_CIDS ]]; then dokku_log_verbose_quiet "Found previous container(s) ($PREVIOUS_CIDS) named $NAME" # in case $PREVIOUS_CIDS has more than one entry local cid for cid in $PREVIOUS_CIDS; do - local PREVIOUS_CONTAINER_STATUS=$("$DOCKER_BIN" inspect -f '{{.State.Status}}' "$cid" || echo "dead") + local PREVIOUS_CONTAINER_STATUS=$("$DOCKER_BIN" container inspect --format '{{.State.Status}}' "$cid" || echo "dead") # dead containers cannot be renamed if [[ "$PREVIOUS_CONTAINER_STATUS" != "dead" ]]; then local CONTAINER_DATE_NAME="$NAME.$(date +%s)" dokku_log_verbose_quiet "Renaming container ($cid) ${NAME} to $CONTAINER_DATE_NAME" - "$DOCKER_BIN" rename "$NAME" "$CONTAINER_DATE_NAME" >/dev/null 2>&1 || dokku_log_warn "Unable to rename container" + "$DOCKER_BIN" container rename "$NAME" "$CONTAINER_DATE_NAME" >/dev/null 2>&1 || dokku_log_warn "Unable to rename container" fi done fi local ID=$(cat "$container") - local CURRENT_NAME=$("$DOCKER_BIN" inspect -f '{{.Name}}' "$ID" | tr -d /) + local CURRENT_NAME=$("$DOCKER_BIN" container inspect --format '{{.Name}}' "$ID" | tr -d /) if [[ -n "$CURRENT_NAME" ]]; then dokku_log_verbose_quiet "Renaming container (${ID:0:12}) $CURRENT_NAME to $NAME" - "$DOCKER_BIN" rename "$CURRENT_NAME" "$NAME" >/dev/null + "$DOCKER_BIN" container rename "$CURRENT_NAME" "$NAME" >/dev/null fi done shopt -u nullglob diff --git a/plugins/scheduler-docker-local/internal-functions b/plugins/scheduler-docker-local/internal-functions index b787a067d..955f9b5df 100755 --- a/plugins/scheduler-docker-local/internal-functions +++ b/plugins/scheduler-docker-local/internal-functions @@ -95,7 +95,7 @@ fn-scheduler-docker-local-retire-container() { declare APP="$1" CID="$2" DEAD_TIME="$3" local STATE - STATE="$("$DOCKER_BIN" inspect -f "{{ .State.Status }}" "$CID" 2>/dev/null || true)" + STATE="$("$DOCKER_BIN" container inspect --format "{{ .State.Status }}" "$CID" 2>/dev/null || true)" if [[ -z "$STATE" ]]; then return fi @@ -104,7 +104,7 @@ fn-scheduler-docker-local-retire-container() { [[ $DOKKU_DOCKER_STOP_TIMEOUT ]] && DOCKER_STOP_TIME_ARG="--time=${DOKKU_DOCKER_STOP_TIMEOUT}" if [[ "$STATE" == "restarting" ]]; then - "$DOCKER_BIN" update --restart=no "$CID" >/dev/null 2>&1 + "$DOCKER_BIN" container update --restart=no "$CID" >/dev/null 2>&1 fi if [[ "$STATE" != "dead" ]] && [[ "$STATE" != "exited" ]]; then @@ -112,18 +112,18 @@ fn-scheduler-docker-local-retire-container() { # to not send SIGKILL as the docs would indicate. If that fails, move # on to the next. # shellcheck disable=SC2086 - "$DOCKER_BIN" stop $DOCKER_STOP_TIME_ARG "$CID" \ - || "$DOCKER_BIN" kill "$CID" \ + "$DOCKER_BIN" container stop $DOCKER_STOP_TIME_ARG "$CID" \ + || "$DOCKER_BIN" container kill "$CID" \ || dokku_log_warn "Unable to kill container ${CID}" fi - STATE="$("$DOCKER_BIN" inspect -f "{{ .State.Status }}" "$CID" 2>/dev/null || true)" + STATE="$("$DOCKER_BIN" container inspect --format "{{ .State.Status }}" "$CID" 2>/dev/null || true)" if [[ -z "$STATE" ]]; then return fi if [[ "$STATE" != "dead" ]] && [[ "$STATE" != "exited" ]]; then - if ! "$DOCKER_BIN" kill "$CID"; then + if ! "$DOCKER_BIN" container kill "$CID"; then dokku_log_warn "Unable to kill container ${CID}" fi fi diff --git a/plugins/scheduler-docker-local/post-delete b/plugins/scheduler-docker-local/post-delete index 405ecde4f..75df108a9 100755 --- a/plugins/scheduler-docker-local/post-delete +++ b/plugins/scheduler-docker-local/post-delete @@ -18,14 +18,14 @@ scheduler-docker-local-post-delete() { # remove all application containers & images # shellcheck disable=SC2046 - local DOKKU_APP_CIDS=$("$DOCKER_BIN" ps -a --no-trunc | egrep "dokku/${APP}:" | awk '{ print $1 }' | xargs) + local DOKKU_APP_CIDS=$("$DOCKER_BIN" container list --all --no-trunc | egrep "dokku/${APP}:" | awk '{ print $1 }' | xargs) if [[ -n "$DOKKU_APP_CIDS" ]]; then # shellcheck disable=SC2086 - "$DOCKER_BIN" rm -f $DOKKU_APP_CIDS >/dev/null 2>&1 || true + "$DOCKER_BIN" container rm --force $DOKKU_APP_CIDS >/dev/null 2>&1 || true fi # shellcheck disable=SC2046 - "$DOCKER_BIN" rmi $("$DOCKER_BIN" images -q "$IMAGE_REPO" | xargs) &>/dev/null || true + "$DOCKER_BIN" image rm $("$DOCKER_BIN" image list --quiet "$IMAGE_REPO" | xargs) &>/dev/null || true } scheduler-docker-local-post-delete "$@" diff --git a/plugins/scheduler-docker-local/pre-deploy b/plugins/scheduler-docker-local/pre-deploy index 1e89b0d07..6dbb97b67 100755 --- a/plugins/scheduler-docker-local/pre-deploy +++ b/plugins/scheduler-docker-local/pre-deploy @@ -44,7 +44,7 @@ scheduler-docker-local-pre-deploy() { fi # shellcheck disable=SC2086 - "$DOCKER_BIN" run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS "${ARG_ARRAY[@]}" $IMAGE /bin/bash -c "find $CONTAINER_PATHS -not -user $DOKKU_APP_USER -print0 | xargs -0 -r chown -R $DOKKU_APP_USER" || true + "$DOCKER_BIN" container run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS "${ARG_ARRAY[@]}" $IMAGE /bin/bash -c "find $CONTAINER_PATHS -not -user $DOKKU_APP_USER -print0 | xargs -0 -r chown -R $DOKKU_APP_USER" || true } scheduler-docker-local-pre-deploy "$@" diff --git a/plugins/scheduler-docker-local/pre-restore b/plugins/scheduler-docker-local/pre-restore index 802167ffb..a2a427c9b 100755 --- a/plugins/scheduler-docker-local/pre-restore +++ b/plugins/scheduler-docker-local/pre-restore @@ -14,7 +14,7 @@ scheduler-docker-local-pre-restore() { # delete all "old" containers # shellcheck disable=SC2046 - "$DOCKER_BIN" rm $("$DOCKER_BIN" ps --format "{{.Names}}" -a -f "label=$DOKKU_CONTAINER_LABEL" -q | grep -E '(.+\..+\.[0-9]+\.[0-9]+$)') &>/dev/null || true + "$DOCKER_BIN" container rm $("$DOCKER_BIN" container list --all --format "{{.Names}}" --filter "label=$DOKKU_CONTAINER_LABEL" --quiet | grep -E '(.+\..+\.[0-9]+\.[0-9]+$)') &>/dev/null || true } scheduler-docker-local-pre-restore "$@" diff --git a/plugins/scheduler-docker-local/scheduler-deploy b/plugins/scheduler-docker-local/scheduler-deploy index 130609825..f0e8cbe2d 100755 --- a/plugins/scheduler-docker-local/scheduler-deploy +++ b/plugins/scheduler-docker-local/scheduler-deploy @@ -58,7 +58,7 @@ scheduler-docker-local-scheduler-deploy() { "$DOCKER_BIN" container update --restart=no "$cid" &>/dev/null || true # shellcheck disable=SC2086 - "$DOCKER_BIN" stop $DOCKER_STOP_TIME_ARG "$cid" &>/dev/null + "$DOCKER_BIN" container stop $DOCKER_STOP_TIME_ARG "$cid" &>/dev/null # remove cid from oldids to skip the old container finish processing oldids="$(remove_val_from_list "$cid" "$oldids" " ")" done @@ -98,16 +98,16 @@ scheduler-docker-local-scheduler-deploy() { START_CMD=$(fn-scheduler-docker-local-extract-start-cmd "$APP" "$PROC_TYPE" "$START_CMD" "$DOKKU_HEROKUISH" "$DOKKU_PORT") if [[ "$DOKKU_NETWORK_BIND_ALL" == "false" ]]; then # shellcheck disable=SC2086 - cid=$("$DOCKER_BIN" run --label=com.dokku.container-type=deploy "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -d -e PORT=$DOKKU_PORT "${ARG_ARRAY[@]}" $IMAGE $START_CMD) + cid=$("$DOCKER_BIN" container run --label=com.dokku.container-type=deploy "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS --detach --env PORT=$DOKKU_PORT "${ARG_ARRAY[@]}" $IMAGE $START_CMD) else # shellcheck disable=SC2086 - cid=$("$DOCKER_BIN" run --label=com.dokku.container-type=deploy "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -d $DOKKU_DOCKER_PORT_ARGS -e PORT=$DOKKU_PORT "${ARG_ARRAY[@]}" $IMAGE $START_CMD) + cid=$("$DOCKER_BIN" container run --label=com.dokku.container-type=deploy "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS --detach $DOKKU_DOCKER_PORT_ARGS --env PORT=$DOKKU_PORT "${ARG_ARRAY[@]}" $IMAGE $START_CMD) fi else START_CMD=$(fn-scheduler-docker-local-extract-start-cmd "$APP" "$PROC_TYPE" "$START_CMD" "$DOKKU_HEROKUISH") # shellcheck disable=SC2086 - cid=$("$DOCKER_BIN" run --label=com.dokku.container-type=deploy "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -d "${ARG_ARRAY[@]}" $IMAGE $START_CMD) + cid=$("$DOCKER_BIN" container run --label=com.dokku.container-type=deploy "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS --detach "${ARG_ARRAY[@]}" $IMAGE $START_CMD) fi ipaddr=$(plugn trigger network-get-ipaddr "$APP" "$PROC_TYPE" "$cid") @@ -118,10 +118,10 @@ scheduler-docker-local-scheduler-deploy() { declare CID="$1" PROC_TYPE="$2" CONTAINER_INDEX="$3" mkdir -p "${DOKKU_LIB_ROOT}/data/scheduler-docker-local/$APP" echo "${CID} ${PROC_TYPE}.${CONTAINER_INDEX}" >>"${DOKKU_LIB_ROOT}/data/scheduler-docker-local/$APP/failed-containers" - "$DOCKER_BIN" inspect "$CID" &>/dev/null && { + "$DOCKER_BIN" container inspect "$CID" &>/dev/null && { # Disable the container restart policy "$DOCKER_BIN" container update --restart=no "$CID" &>/dev/null || true - "$DOCKER_BIN" stop "$CID" >/dev/null && "$DOCKER_BIN" kill "$CID" &>/dev/null + "$DOCKER_BIN" container stop "$CID" >/dev/null && "$DOCKER_BIN" container kill "$CID" &>/dev/null } trap - INT TERM EXIT kill -9 $$ @@ -191,8 +191,8 @@ scheduler-docker-local-scheduler-deploy() { # to not send SIGKILL as the docs would indicate. If that fails, move # on to the next. # shellcheck disable=SC2086 - "$DOCKER_BIN" stop $DOCKER_STOP_TIME_ARG "$oldid" \ - || "$DOCKER_BIN" kill "$oldid" \ + "$DOCKER_BIN" container stop $DOCKER_STOP_TIME_ARG "$oldid" \ + || "$DOCKER_BIN" container kill "$oldid" \ || plugn trigger retire-container-failed "$APP" "$oldid" # plugin trigger for event logging done ) & diff --git a/plugins/scheduler-docker-local/scheduler-docker-cleanup b/plugins/scheduler-docker-local/scheduler-docker-cleanup index 7d9325bc5..6c041d1a5 100755 --- a/plugins/scheduler-docker-local/scheduler-docker-cleanup +++ b/plugins/scheduler-docker-local/scheduler-docker-cleanup @@ -15,30 +15,30 @@ scheduler-docker-local-scheduler-docker-cleanup() { if [[ -n "$APP" ]]; then # delete all non-running containers # shellcheck disable=SC2046 - "$DOCKER_BIN" rm $("$DOCKER_BIN" ps -a -f "status=exited" -f "label=$DOKKU_CONTAINER_LABEL" -f "label=com.dokku.app-name=$APP" -q) &>/dev/null || true + "$DOCKER_BIN" container rm $("$DOCKER_BIN" container list --all --filter "status=exited" --filter "label=$DOKKU_CONTAINER_LABEL" --filter "label=com.dokku.app-name=$APP" --quiet) &>/dev/null || true # delete all dead containers # shellcheck disable=SC2046 - "$DOCKER_BIN" rm $("$DOCKER_BIN" ps -a -f "status=dead" -f "label=$DOKKU_CONTAINER_LABEL" -f "label=com.dokku.app-name=$APP" -q) &>/dev/null || true + "$DOCKER_BIN" container rm $("$DOCKER_BIN" container list --all --filter "status=dead" --filter "label=$DOKKU_CONTAINER_LABEL" --filter "label=com.dokku.app-name=$APP" --quiet) &>/dev/null || true # delete danging images # shellcheck disable=SC2046 - "$DOCKER_BIN" rmi $("$DOCKER_BIN" images -f 'dangling=true' -f "label=com.dokku.app-name=$APP" -q) &>/dev/null || true + "$DOCKER_BIN" image rm $("$DOCKER_BIN" image list --filter 'dangling=true' --filter "label=com.dokku.app-name=$APP" --quiet) &>/dev/null || true # delete unused images "$DOCKER_BIN" image prune --all --filter "label=com.dokku.app-name=$APP" --force &>/dev/null || true else # delete all non-running containers # shellcheck disable=SC2046 - "$DOCKER_BIN" rm $("$DOCKER_BIN" ps -a -f "status=exited" -f "label=$DOKKU_CONTAINER_LABEL" -q) &>/dev/null || true + "$DOCKER_BIN" container rm $("$DOCKER_BIN" container list --all --filter "status=exited" --filter "label=$DOKKU_CONTAINER_LABEL" --quiet) &>/dev/null || true # delete all dead containers # shellcheck disable=SC2046 - "$DOCKER_BIN" rm $("$DOCKER_BIN" ps -a -f "status=dead" -f "label=$DOKKU_CONTAINER_LABEL" -q) &>/dev/null || true + "$DOCKER_BIN" container rm $("$DOCKER_BIN" container list --all --filter "status=dead" --filter "label=$DOKKU_CONTAINER_LABEL" --quiet) &>/dev/null || true # delete danging images # shellcheck disable=SC2046 - "$DOCKER_BIN" rmi $("$DOCKER_BIN" images -f 'dangling=true' -q) &>/dev/null || true + "$DOCKER_BIN" image rm $("$DOCKER_BIN" image list --filter 'dangling=true' --quiet) &>/dev/null || true fi } diff --git a/plugins/scheduler-docker-local/scheduler-inspect b/plugins/scheduler-docker-local/scheduler-inspect index 5fd7e8e2e..19708c3f5 100755 --- a/plugins/scheduler-docker-local/scheduler-inspect +++ b/plugins/scheduler-docker-local/scheduler-inspect @@ -48,7 +48,7 @@ EOF for CONTAINER_FILE in $CONTAINER_FILES; do CIDS+="$(<"$DOKKU_ROOT/$APP/$CONTAINER_FILE")" done - "$DOCKER_BIN" inspect "${CIDS[@]}" | python2.7 "$TMP_INSPECT_CMD" + "$DOCKER_BIN" container inspect "${CIDS[@]}" | python2.7 "$TMP_INSPECT_CMD" } diff --git a/plugins/scheduler-docker-local/scheduler-logs-failed b/plugins/scheduler-docker-local/scheduler-logs-failed index 476e91b72..f231b9bdc 100755 --- a/plugins/scheduler-docker-local/scheduler-logs-failed +++ b/plugins/scheduler-docker-local/scheduler-logs-failed @@ -24,7 +24,7 @@ scheduler-docker-local-scheduler-logs-failed() { while read -r LINE || [[ -n "$LINE" ]]; do CID="$(echo "$LINE" | cut -d ' ' -f1)" PREFIX="$(echo "$LINE" | cut -d ' ' -f2)" - if "$DOCKER_BIN" inspect "${CID}" >/dev/null 2>&1; then + if "$DOCKER_BIN" container inspect "${CID}" >/dev/null 2>&1; then RUNNING_CONTAINERS+=("$CID") else DEAD_CONTAINERS+=("$CID") diff --git a/plugins/scheduler-docker-local/scheduler-retire b/plugins/scheduler-docker-local/scheduler-retire index af24e75ad..d60d8f8e2 100755 --- a/plugins/scheduler-docker-local/scheduler-retire +++ b/plugins/scheduler-docker-local/scheduler-retire @@ -27,7 +27,7 @@ scheduler-docker-local-scheduler-retire() { fi fn-scheduler-docker-local-retire-container "$APP" "$CID" "$DEAD_TIME" - STATE="$("$DOCKER_BIN" inspect -f "{{ .State.Status }}" "$CID" 2>/dev/null || true)" + STATE="$("$DOCKER_BIN" container inspect --format "{{ .State.Status }}" "$CID" 2>/dev/null || true)" if [[ -z "$STATE" ]]; then DEAD_CONTAINERS+=("$CID") continue @@ -38,8 +38,8 @@ scheduler-docker-local-scheduler-retire() { continue fi - "$DOCKER_BIN" rm -f "$CID" >/dev/null 2>&1 || true - if "$DOCKER_BIN" inspect "${CID}" >/dev/null 2>&1; then + "$DOCKER_BIN" container rm --force "$CID" >/dev/null 2>&1 || true + if "$DOCKER_BIN" container inspect "${CID}" >/dev/null 2>&1; then dokku_log_warn "Container ${CID} still running" continue fi diff --git a/plugins/scheduler-docker-local/scheduler-run b/plugins/scheduler-docker-local/scheduler-run index 2d4b045a8..a6105fbc0 100755 --- a/plugins/scheduler-docker-local/scheduler-run +++ b/plugins/scheduler-docker-local/scheduler-run @@ -67,7 +67,7 @@ scheduler-docker-local-scheduler-run() { fi # shellcheck disable=SC2086 - "$DOCKER_BIN" run --label=com.dokku.container-type=run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS "${DOCKER_ARGS_ARRAY[@]}" $IMAGE $EXEC_CMD "$@" + "$DOCKER_BIN" container run --label=com.dokku.container-type=run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS "${DOCKER_ARGS_ARRAY[@]}" $IMAGE $EXEC_CMD "$@" } scheduler-docker-local-scheduler-run "$@" diff --git a/plugins/scheduler-docker-local/scheduler-stop b/plugins/scheduler-docker-local/scheduler-stop index 553b950bd..f696509a0 100755 --- a/plugins/scheduler-docker-local/scheduler-stop +++ b/plugins/scheduler-docker-local/scheduler-stop @@ -24,7 +24,7 @@ scheduler-docker-local-scheduler-stop() { "$DOCKER_BIN" container update --restart=no $DOKKU_APP_RUNNING_CONTAINER_IDS &>/dev/null || true # shellcheck disable=SC2086 - "$DOCKER_BIN" stop $DOCKER_STOP_TIME_ARG $DOKKU_APP_RUNNING_CONTAINER_IDS >/dev/null || true + "$DOCKER_BIN" container stop $DOCKER_STOP_TIME_ARG $DOKKU_APP_RUNNING_CONTAINER_IDS >/dev/null || true fi if [[ "$REMOVE_CONTAINERS" == "true" ]]; then @@ -32,7 +32,7 @@ scheduler-docker-local-scheduler-stop() { if [[ -n "$DOKKU_APP_CIDS" ]]; then # shellcheck disable=SC2086 - "$DOCKER_BIN" rm -f $DOKKU_APP_CIDS >/dev/null 2>&1 || true + "$DOCKER_BIN" container rm --force $DOKKU_APP_CIDS >/dev/null 2>&1 || true fi fi } diff --git a/plugins/scheduler-docker-local/scheduler-tags-create b/plugins/scheduler-docker-local/scheduler-tags-create index 5d04aa6f7..128d499da 100755 --- a/plugins/scheduler-docker-local/scheduler-tags-create +++ b/plugins/scheduler-docker-local/scheduler-tags-create @@ -15,7 +15,7 @@ scheduler-docker-local-scheduler-tags-create() { local TAG_OPTS="" [[ $(is_tag_force_available) ]] && TAG_OPTS="-f" # shellcheck disable=SC2086 - "$DOCKER_BIN" tag $TAG_OPTS "$SOURCE_IMAGE" "$TARGET_IMAGE" + "$DOCKER_BIN" image tag $TAG_OPTS "$SOURCE_IMAGE" "$TARGET_IMAGE" } is_tag_force_available() { diff --git a/plugins/scheduler-docker-local/scheduler-tags-destroy b/plugins/scheduler-docker-local/scheduler-tags-destroy index 0fbaeab2f..078905659 100755 --- a/plugins/scheduler-docker-local/scheduler-tags-destroy +++ b/plugins/scheduler-docker-local/scheduler-tags-destroy @@ -12,7 +12,7 @@ scheduler-docker-local-scheduler-tags-destroy() { return fi - "$DOCKER_BIN" rmi "$IMAGE_REPO:$IMAGE_TAG" + "$DOCKER_BIN" image rm "$IMAGE_REPO:$IMAGE_TAG" } scheduler-docker-local-scheduler-tags-destroy "$@" diff --git a/plugins/tags/subcommands/default b/plugins/tags/subcommands/default index 7ccecf21e..fd9272e1e 100755 --- a/plugins/tags/subcommands/default +++ b/plugins/tags/subcommands/default @@ -12,7 +12,7 @@ tags_main_cmd() { verify_app_name "$APP" dokku_log_info2_quiet "Image tags for $IMAGE_REPO" - "$DOCKER_BIN" images "$IMAGE_REPO" + "$DOCKER_BIN" image list "$IMAGE_REPO" } tags_main_cmd "$@" From 6a7d2e52527ce691dca79fb46ce397378fa8a2c4 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sat, 7 Sep 2019 04:47:18 -0400 Subject: [PATCH 13/39] refactor: decrease compile time for golang plugins This change refactors the compiled golang plugins into 3 distinct binaries: - commands: already existing - subcommands/subcommands: entrypoint into all subcommands - triggers: entrypoint into all triggers It then further symlinks triggers and subcommands to the built binaries. This results in both a much faster build process as well as smaller package size. --- common.mk | 37 ++++ plugins/buildpacks/.gitignore | 1 + plugins/buildpacks/Makefile | 37 +--- plugins/buildpacks/src/subcommands/add/add.go | 19 -- .../buildpacks/src/subcommands/clear/clear.go | 18 -- .../buildpacks/src/subcommands/list/list.go | 14 -- .../src/subcommands/remove/remove.go | 19 -- .../src/subcommands/report/report.go | 34 ---- plugins/buildpacks/src/subcommands/set/set.go | 19 -- .../buildpacks/src/subcommands/subcommands.go | 55 ++++++ .../src/triggers/install/install.go | 14 -- .../src/triggers/post-delete/post-delete.go | 18 -- .../buildpacks/src/triggers/report/report.go | 15 -- plugins/buildpacks/src/triggers/triggers.go | 35 ++++ plugins/buildpacks/subcommands.go | 22 +++ .../post-extract.go => triggers.go} | 26 ++- plugins/config/.gitignore | 2 + plugins/config/Makefile | 29 +-- .../config/src/subcommands/bundle/bundle.go | 16 -- plugins/config/src/subcommands/clear/clear.go | 17 -- .../config/src/subcommands/export/export.go | 20 -- plugins/config/src/subcommands/get/get.go | 17 -- plugins/config/src/subcommands/keys/keys.go | 16 -- plugins/config/src/subcommands/set/set.go | 18 -- plugins/config/src/subcommands/subcommands.go | 67 +++++++ plugins/config/src/subcommands/unset/unset.go | 17 -- plugins/network/.gitignore | 1 + plugins/network/Makefile | 37 +--- .../src/subcommands/rebuild/rebuild.go | 15 -- .../src/subcommands/rebuildall/rebuildall.go | 17 -- .../network/src/subcommands/report/report.go | 34 ---- plugins/network/src/subcommands/set/set.go | 22 --- .../network/src/subcommands/subcommands.go | 37 ++++ .../network/src/triggers/install/install.go | 36 ---- .../network-build-config.go | 15 -- .../network-compute-ports.go | 46 ----- .../network-config-exists.go | 22 --- .../network-get-ipaddr/network-get-ipaddr.go | 20 -- .../network-get-listeners.go | 19 -- .../network-get-port/network-get-port.go | 22 --- .../network-get-property.go | 21 --- .../network-write-ipaddr.go | 41 ---- .../network-write-port/network-write-port.go | 41 ---- .../post-app-clone-setup.go | 19 -- .../src/triggers/post-create/post-create.go | 18 -- .../src/triggers/post-delete/post-delete.go | 18 -- plugins/network/src/triggers/report/report.go | 15 -- plugins/network/src/triggers/triggers.go | 78 ++++++++ plugins/network/subcommands.go | 48 +++++ plugins/network/triggers.go | 178 ++++++++++++++++++ plugins/repo/.gitignore | 2 + plugins/repo/Makefile | 37 +--- plugins/repo/pre-delete | 1 + .../subcommands/purge-cache/purge-cache.go | 22 --- plugins/repo/src/subcommands/subcommands.go | 35 ++++ .../src/triggers/pre-delete/pre-delete.go | 19 -- plugins/repo/src/triggers/triggers.go | 31 +++ .../subcommands/gc/gc.go => subcommands.go} | 24 ++- plugins/resource/.gitignore | 1 + plugins/resource/Makefile | 38 +--- .../subcommands/limit-clear/limit-clear.go | 20 -- .../resource/src/subcommands/limit/limit.go | 35 ---- .../resource/src/subcommands/report/report.go | 33 ---- .../reserve-clear/reserve-clear.go | 20 -- .../src/subcommands/reserve/reserve.go | 35 ---- .../resource/src/subcommands/subcommands.go | 84 +++++++++ .../resource/src/triggers/install/install.go | 14 -- .../src/triggers/post-delete/post-delete.go | 18 -- .../resource/src/triggers/report/report.go | 15 -- .../resource-get-property.go | 26 --- plugins/resource/src/triggers/triggers.go | 46 +++++ plugins/resource/subcommands.go | 23 +++ ...ker-args-process-deploy.go => triggers.go} | 43 +++-- 73 files changed, 865 insertions(+), 1179 deletions(-) delete mode 100644 plugins/buildpacks/src/subcommands/add/add.go delete mode 100644 plugins/buildpacks/src/subcommands/clear/clear.go delete mode 100644 plugins/buildpacks/src/subcommands/list/list.go delete mode 100644 plugins/buildpacks/src/subcommands/remove/remove.go delete mode 100644 plugins/buildpacks/src/subcommands/report/report.go delete mode 100644 plugins/buildpacks/src/subcommands/set/set.go create mode 100644 plugins/buildpacks/src/subcommands/subcommands.go delete mode 100644 plugins/buildpacks/src/triggers/install/install.go delete mode 100644 plugins/buildpacks/src/triggers/post-delete/post-delete.go delete mode 100644 plugins/buildpacks/src/triggers/report/report.go create mode 100644 plugins/buildpacks/src/triggers/triggers.go rename plugins/buildpacks/{src/triggers/post-extract/post-extract.go => triggers.go} (55%) delete mode 100644 plugins/config/src/subcommands/bundle/bundle.go delete mode 100644 plugins/config/src/subcommands/clear/clear.go delete mode 100644 plugins/config/src/subcommands/export/export.go delete mode 100644 plugins/config/src/subcommands/get/get.go delete mode 100644 plugins/config/src/subcommands/keys/keys.go delete mode 100644 plugins/config/src/subcommands/set/set.go create mode 100644 plugins/config/src/subcommands/subcommands.go delete mode 100644 plugins/config/src/subcommands/unset/unset.go delete mode 100644 plugins/network/src/subcommands/rebuild/rebuild.go delete mode 100644 plugins/network/src/subcommands/rebuildall/rebuildall.go delete mode 100644 plugins/network/src/subcommands/report/report.go delete mode 100644 plugins/network/src/subcommands/set/set.go create mode 100644 plugins/network/src/subcommands/subcommands.go delete mode 100644 plugins/network/src/triggers/install/install.go delete mode 100644 plugins/network/src/triggers/network-build-config/network-build-config.go delete mode 100644 plugins/network/src/triggers/network-compute-ports/network-compute-ports.go delete mode 100644 plugins/network/src/triggers/network-config-exists/network-config-exists.go delete mode 100644 plugins/network/src/triggers/network-get-ipaddr/network-get-ipaddr.go delete mode 100644 plugins/network/src/triggers/network-get-listeners/network-get-listeners.go delete mode 100644 plugins/network/src/triggers/network-get-port/network-get-port.go delete mode 100644 plugins/network/src/triggers/network-get-property/network-get-property.go delete mode 100644 plugins/network/src/triggers/network-write-ipaddr/network-write-ipaddr.go delete mode 100644 plugins/network/src/triggers/network-write-port/network-write-port.go delete mode 100644 plugins/network/src/triggers/post-app-clone-setup/post-app-clone-setup.go delete mode 100644 plugins/network/src/triggers/post-create/post-create.go delete mode 100644 plugins/network/src/triggers/post-delete/post-delete.go delete mode 100644 plugins/network/src/triggers/report/report.go create mode 100644 plugins/network/src/triggers/triggers.go create mode 100644 plugins/network/subcommands.go create mode 100644 plugins/network/triggers.go create mode 120000 plugins/repo/pre-delete delete mode 100644 plugins/repo/src/subcommands/purge-cache/purge-cache.go create mode 100644 plugins/repo/src/subcommands/subcommands.go delete mode 100644 plugins/repo/src/triggers/pre-delete/pre-delete.go create mode 100644 plugins/repo/src/triggers/triggers.go rename plugins/repo/{src/subcommands/gc/gc.go => subcommands.go} (52%) delete mode 100644 plugins/resource/src/subcommands/limit-clear/limit-clear.go delete mode 100644 plugins/resource/src/subcommands/limit/limit.go delete mode 100644 plugins/resource/src/subcommands/report/report.go delete mode 100644 plugins/resource/src/subcommands/reserve-clear/reserve-clear.go delete mode 100644 plugins/resource/src/subcommands/reserve/reserve.go create mode 100644 plugins/resource/src/subcommands/subcommands.go delete mode 100644 plugins/resource/src/triggers/install/install.go delete mode 100644 plugins/resource/src/triggers/post-delete/post-delete.go delete mode 100644 plugins/resource/src/triggers/report/report.go delete mode 100644 plugins/resource/src/triggers/resource-get-property/resource-get-property.go create mode 100644 plugins/resource/src/triggers/triggers.go rename plugins/resource/{src/triggers/docker-args-process-deploy/docker-args-process-deploy.go => triggers.go} (59%) diff --git a/common.mk b/common.mk index 82b9edaeb..d2841ffca 100644 --- a/common.mk +++ b/common.mk @@ -1,4 +1,41 @@ +GO_ARGS ?= -a GO_REPO_ROOT := /go/src/github.com/dokku/dokku BUILD_IMAGE := golang:1.12 .PHONY: build-in-docker build clean src-clean + +build: $(BUILD) + +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 \ + -e PLUGIN_NAME=$(PLUGIN_NAME) \ + -w $(GO_REPO_ROOT)/plugins/$(PLUGIN_NAME) \ + $(BUILD_IMAGE) \ + bash -c "GO_ARGS='$(GO_ARGS)' make -j4 build" || exit $$? + +clean: + rm -rf commands subcommands triggers + find . -xtype l -delete + +commands: **/**/commands.go + go build $(GO_ARGS) -o commands src/commands/commands.go + +subcommands: + go build $(GO_ARGS) -o subcommands/subcommands src/subcommands/subcommands.go + $(MAKE) $(SUBCOMMANDS) + +subcommands/%: + ln -sf subcommands $@ + +src-clean: + rm -rf .gitignore src vendor Makefile *.go glide.* + +triggers: + go build $(GO_ARGS) -o triggers src/triggers/triggers.go + $(MAKE) $(TRIGGERS) + +triggers/%: + ln -sf triggers $(shell echo $@ | cut -d '/' -f2) diff --git a/plugins/buildpacks/.gitignore b/plugins/buildpacks/.gitignore index cd4903d6f..053d0cfd9 100644 --- a/plugins/buildpacks/.gitignore +++ b/plugins/buildpacks/.gitignore @@ -1,6 +1,7 @@ /commands /subcommands/* /triggers/* +/triggers /install /post-delete /post-extract diff --git a/plugins/buildpacks/Makefile b/plugins/buildpacks/Makefile index 889c22529..74a13c23e 100644 --- a/plugins/buildpacks/Makefile +++ b/plugins/buildpacks/Makefile @@ -1,37 +1,6 @@ -include ../../common.mk - -GO_ARGS ?= -a - SUBCOMMANDS = subcommands/add subcommands/clear subcommands/list subcommands/remove subcommands/report subcommands/set TRIGGERS = triggers/install triggers/post-delete triggers/post-extract triggers/report -build-in-docker: clean - docker run --rm \ - -v $$PWD/../..:$(GO_REPO_ROOT) \ - -w $(GO_REPO_ROOT)/plugins/buildpacks \ - $(BUILD_IMAGE) \ - bash -c "GO_ARGS='$(GO_ARGS)' make -j4 build" || exit $$? +BUILD = commands subcommands triggers +PLUGIN_NAME = buildpacks -build: commands subcommands triggers - $(MAKE) triggers-copy - -commands: **/**/commands.go - go build $(GO_ARGS) -o commands src/commands/commands.go - -subcommands: $(SUBCOMMANDS) - -subcommands/%: src/subcommands/*/%.go - go build $(GO_ARGS) -o $@ $< - -clean: - rm -rf commands subcommands triggers install post-delete post-extract report - -src-clean: - rm -rf .gitignore src triggers vendor Makefile *.go glide.* - -triggers: $(TRIGGERS) - -triggers/%: src/triggers/*/%.go - go build $(GO_ARGS) -o $@ $< - -triggers-copy: - cp triggers/* . +include ../../common.mk diff --git a/plugins/buildpacks/src/subcommands/add/add.go b/plugins/buildpacks/src/subcommands/add/add.go deleted file mode 100644 index 8aa71e01b..000000000 --- a/plugins/buildpacks/src/subcommands/add/add.go +++ /dev/null @@ -1,19 +0,0 @@ -package main - -import ( - "flag" - "os" - - "github.com/dokku/dokku/plugins/buildpacks" - "github.com/dokku/dokku/plugins/common" -) - -func main() { - args := flag.NewFlagSet("buildpacks:add", flag.ExitOnError) - index := args.Int("index", 0, "--index: the 1-based index of the URL in the list of URLs") - args.Parse(os.Args[2:]) - err := buildpacks.CommandAdd(args.Args(), *index) - if err != nil { - common.LogFail(err.Error()) - } -} diff --git a/plugins/buildpacks/src/subcommands/clear/clear.go b/plugins/buildpacks/src/subcommands/clear/clear.go deleted file mode 100644 index 32b60ba10..000000000 --- a/plugins/buildpacks/src/subcommands/clear/clear.go +++ /dev/null @@ -1,18 +0,0 @@ -package main - -import ( - "flag" - "os" - - "github.com/dokku/dokku/plugins/buildpacks" - "github.com/dokku/dokku/plugins/common" -) - -func main() { - args := flag.NewFlagSet("buildpacks:clear", flag.ExitOnError) - args.Parse(os.Args[2:]) - err := buildpacks.CommandClear(args.Args()) - if err != nil { - common.LogFail(err.Error()) - } -} diff --git a/plugins/buildpacks/src/subcommands/list/list.go b/plugins/buildpacks/src/subcommands/list/list.go deleted file mode 100644 index 44d56967e..000000000 --- a/plugins/buildpacks/src/subcommands/list/list.go +++ /dev/null @@ -1,14 +0,0 @@ -package main - -import ( - "flag" - "os" - - "github.com/dokku/dokku/plugins/buildpacks" -) - -func main() { - args := flag.NewFlagSet("buildpacks:list", flag.ExitOnError) - args.Parse(os.Args[2:]) - buildpacks.CommandList(args.Args()) -} diff --git a/plugins/buildpacks/src/subcommands/remove/remove.go b/plugins/buildpacks/src/subcommands/remove/remove.go deleted file mode 100644 index b10875caa..000000000 --- a/plugins/buildpacks/src/subcommands/remove/remove.go +++ /dev/null @@ -1,19 +0,0 @@ -package main - -import ( - "flag" - "os" - - "github.com/dokku/dokku/plugins/buildpacks" - "github.com/dokku/dokku/plugins/common" -) - -func main() { - args := flag.NewFlagSet("buildpacks:remove", flag.ExitOnError) - index := args.Int("index", 0, "--index: the 1-based index of the URL in the list of URLs") - args.Parse(os.Args[2:]) - err := buildpacks.CommandRemove(args.Args(), *index) - if err != nil { - common.LogFail(err.Error()) - } -} diff --git a/plugins/buildpacks/src/subcommands/report/report.go b/plugins/buildpacks/src/subcommands/report/report.go deleted file mode 100644 index 507ae416d..000000000 --- a/plugins/buildpacks/src/subcommands/report/report.go +++ /dev/null @@ -1,34 +0,0 @@ -package main - -import ( - "flag" - "strings" - - "github.com/dokku/dokku/plugins/buildpacks" - "github.com/dokku/dokku/plugins/common" -) - -// displays a buildpacks report for one or more apps -func main() { - flag.Parse() - appName := flag.Arg(1) - infoFlag := flag.Arg(2) - - if strings.HasPrefix(appName, "--") { - infoFlag = appName - appName = "" - } - - if len(appName) == 0 { - apps, err := common.DokkuApps() - if err != nil { - return - } - for _, appName := range apps { - buildpacks.ReportSingleApp(appName, infoFlag) - } - return - } - - buildpacks.ReportSingleApp(appName, infoFlag) -} diff --git a/plugins/buildpacks/src/subcommands/set/set.go b/plugins/buildpacks/src/subcommands/set/set.go deleted file mode 100644 index cf97ca5ce..000000000 --- a/plugins/buildpacks/src/subcommands/set/set.go +++ /dev/null @@ -1,19 +0,0 @@ -package main - -import ( - "flag" - "os" - - "github.com/dokku/dokku/plugins/buildpacks" - "github.com/dokku/dokku/plugins/common" -) - -func main() { - args := flag.NewFlagSet("buildpacks:set", flag.ExitOnError) - index := args.Int("index", 0, "--index: the 1-based index of the URL in the list of URLs") - args.Parse(os.Args[2:]) - err := buildpacks.CommandSet(args.Args(), *index) - if err != nil { - common.LogFail(err.Error()) - } -} diff --git a/plugins/buildpacks/src/subcommands/subcommands.go b/plugins/buildpacks/src/subcommands/subcommands.go new file mode 100644 index 000000000..212898cfe --- /dev/null +++ b/plugins/buildpacks/src/subcommands/subcommands.go @@ -0,0 +1,55 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + "github.com/dokku/dokku/plugins/buildpacks" + "github.com/dokku/dokku/plugins/common" +) + +// main entrypoint to all subcommands +func main() { + parts := strings.Split(os.Args[0], "/") + subcommand := parts[len(parts)-1] + + var err error + switch subcommand { + case "add": + args := flag.NewFlagSet("buildpacks:add", flag.ExitOnError) + index := args.Int("index", 0, "--index: the 1-based index of the URL in the list of URLs") + args.Parse(os.Args[2:]) + err = buildpacks.CommandAdd(args.Args(), *index) + case "clear": + args := flag.NewFlagSet("buildpacks:clear", flag.ExitOnError) + args.Parse(os.Args[2:]) + err = buildpacks.CommandClear(args.Args()) + case "list": + args := flag.NewFlagSet("buildpacks:list", flag.ExitOnError) + args.Parse(os.Args[2:]) + buildpacks.CommandList(args.Args()) + case "remove": + args := flag.NewFlagSet("buildpacks:remove", flag.ExitOnError) + index := args.Int("index", 0, "--index: the 1-based index of the URL in the list of URLs") + args.Parse(os.Args[2:]) + err = buildpacks.CommandRemove(args.Args(), *index) + case "report": + flag.Parse() + appName := flag.Arg(1) + infoFlag := flag.Arg(2) + buildpacks.CommandReport(appName, infoFlag) + case "set": + args := flag.NewFlagSet("buildpacks:set", flag.ExitOnError) + index := args.Int("index", 0, "--index: the 1-based index of the URL in the list of URLs") + args.Parse(os.Args[2:]) + err = buildpacks.CommandSet(args.Args(), *index) + default: + common.LogFail(fmt.Sprintf("Invalid plugin subcommand call: %s", subcommand)) + } + + if err != nil { + common.LogFail(err.Error()) + } +} diff --git a/plugins/buildpacks/src/triggers/install/install.go b/plugins/buildpacks/src/triggers/install/install.go deleted file mode 100644 index 9c3a8e092..000000000 --- a/plugins/buildpacks/src/triggers/install/install.go +++ /dev/null @@ -1,14 +0,0 @@ -package main - -import ( - "fmt" - - "github.com/dokku/dokku/plugins/common" -) - -// runs the install step for the buildpacks plugin -func main() { - if err := common.PropertySetup("buildpacks"); err != nil { - common.LogFail(fmt.Sprintf("Unable to install the buildpacks plugin: %s", err.Error())) - } -} diff --git a/plugins/buildpacks/src/triggers/post-delete/post-delete.go b/plugins/buildpacks/src/triggers/post-delete/post-delete.go deleted file mode 100644 index 3535d48bf..000000000 --- a/plugins/buildpacks/src/triggers/post-delete/post-delete.go +++ /dev/null @@ -1,18 +0,0 @@ -package main - -import ( - "flag" - - "github.com/dokku/dokku/plugins/common" -) - -// destroys the buildpacks property for a given app container -func main() { - flag.Parse() - appName := flag.Arg(0) - - err := common.PropertyDestroy("buildpacks", appName) - if err != nil { - common.LogFail(err.Error()) - } -} diff --git a/plugins/buildpacks/src/triggers/report/report.go b/plugins/buildpacks/src/triggers/report/report.go deleted file mode 100644 index 7f1e74440..000000000 --- a/plugins/buildpacks/src/triggers/report/report.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - "flag" - - "github.com/dokku/dokku/plugins/buildpacks" -) - -// displays a buildpacks report for one or more apps -func main() { - flag.Parse() - appName := flag.Arg(0) - - buildpacks.ReportSingleApp(appName, "") -} diff --git a/plugins/buildpacks/src/triggers/triggers.go b/plugins/buildpacks/src/triggers/triggers.go new file mode 100644 index 000000000..83e01740b --- /dev/null +++ b/plugins/buildpacks/src/triggers/triggers.go @@ -0,0 +1,35 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + "github.com/dokku/dokku/plugins/buildpacks" + "github.com/dokku/dokku/plugins/common" +) + +// main entrypoint to all triggers +func main() { + parts := strings.Split(os.Args[0], "/") + trigger := parts[len(parts)-1] + flag.Parse() + + switch trigger { + case "install": + buildpacks.TriggerInstall() + case "post-delete": + appName := flag.Arg(0) + buildpacks.TriggerPostDelete(appName) + case "post-extract": + appName := flag.Arg(0) + sourceWorkDir := flag.Arg(1) + buildpacks.TriggerPostExtract(appName, sourceWorkDir) + case "report": + appName := flag.Arg(0) + buildpacks.ReportSingleApp(appName, "") + default: + common.LogFail(fmt.Sprintf("Invalid plugin trigger call: %s", trigger)) + } +} diff --git a/plugins/buildpacks/subcommands.go b/plugins/buildpacks/subcommands.go index 88a3e0856..060a9f32f 100644 --- a/plugins/buildpacks/subcommands.go +++ b/plugins/buildpacks/subcommands.go @@ -3,6 +3,7 @@ package buildpacks import ( "errors" "fmt" + "strings" "github.com/dokku/dokku/plugins/common" ) @@ -115,6 +116,27 @@ func CommandRemove(args []string, index int) (err error) { return } +// CommandReport displays a buildpacks report for one or more apps +func CommandReport(appName string, infoFlag string) { + if strings.HasPrefix(appName, "--") { + infoFlag = appName + appName = "" + } + + if len(appName) == 0 { + apps, err := common.DokkuApps() + if err != nil { + return + } + for _, appName := range apps { + ReportSingleApp(appName, infoFlag) + } + return + } + + ReportSingleApp(appName, infoFlag) +} + // CommandSet implements buildpacks:set func CommandSet(args []string, index int) (err error) { var appName string diff --git a/plugins/buildpacks/src/triggers/post-extract/post-extract.go b/plugins/buildpacks/triggers.go similarity index 55% rename from plugins/buildpacks/src/triggers/post-extract/post-extract.go rename to plugins/buildpacks/triggers.go index 495a34855..50f95da98 100644 --- a/plugins/buildpacks/src/triggers/post-extract/post-extract.go +++ b/plugins/buildpacks/triggers.go @@ -1,8 +1,7 @@ -package main +package buildpacks import ( "bufio" - "flag" "fmt" "os" "path" @@ -10,12 +9,23 @@ import ( "github.com/dokku/dokku/plugins/common" ) -// writes a .buildpacks file into the app -func main() { - flag.Parse() - appName := flag.Arg(0) - tmpWorkDir := flag.Arg(1) +// runs the install step for the buildpacks plugin +func TriggerInstall() { + if err := common.PropertySetup("buildpacks"); err != nil { + common.LogFail(fmt.Sprintf("Unable to install the buildpacks plugin: %s", err.Error())) + } +} +// destroys the buildpacks property for a given app container +func TriggerPostDelete(appName string) { + err := common.PropertyDestroy("buildpacks", appName) + if err != nil { + common.LogFail(err.Error()) + } +} + +// writes a .buildpacks file into the app +func TriggerPostExtract(appName string, sourceWorkDir string) { buildpacks, err := common.PropertyListGet("buildpacks", appName, "buildpacks") if err != nil { return @@ -25,7 +35,7 @@ func main() { return } - buildpacksPath := path.Join(tmpWorkDir, ".buildpacks") + buildpacksPath := path.Join(sourceWorkDir, ".buildpacks") file, err := os.OpenFile(buildpacksPath, os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0600) if err != nil { common.LogFail(fmt.Sprintf("Error writing .buildpacks file: %s", err.Error())) diff --git a/plugins/config/.gitignore b/plugins/config/.gitignore index 0f6770b1e..cc45caec7 100644 --- a/plugins/config/.gitignore +++ b/plugins/config/.gitignore @@ -1,2 +1,4 @@ /commands /subcommands/* +/triggers/* +/triggers diff --git a/plugins/config/Makefile b/plugins/config/Makefile index 5e65eb98e..fcc94b7d9 100644 --- a/plugins/config/Makefile +++ b/plugins/config/Makefile @@ -1,28 +1,5 @@ -include ../../common.mk - -GO_ARGS ?= -a - SUBCOMMANDS = subcommands/export subcommands/get subcommands/set subcommands/unset subcommands/keys subcommands/bundle +BUILD = commands subcommands +PLUGIN_NAME = config -build-in-docker: clean - docker run --rm \ - -v $$PWD/../..:$(GO_REPO_ROOT) \ - -w $(GO_REPO_ROOT)/plugins/config \ - $(BUILD_IMAGE) \ - bash -c "GO_ARGS='$(GO_ARGS)' make -j4 build" || exit $$? - -build: commands subcommands - -commands: **/**/commands.go - go build $(GO_ARGS) -o commands src/commands/commands.go - -subcommands: $(SUBCOMMANDS) - -subcommands/%: src/subcommands/*/%.go - go build $(GO_ARGS) -o $@ $< - -clean: - rm -rf commands subcommands - -src-clean: - rm -rf .gitignore src triggers vendor Makefile *.go glide.* +include ../../common.mk diff --git a/plugins/config/src/subcommands/bundle/bundle.go b/plugins/config/src/subcommands/bundle/bundle.go deleted file mode 100644 index e00238177..000000000 --- a/plugins/config/src/subcommands/bundle/bundle.go +++ /dev/null @@ -1,16 +0,0 @@ -package main - -import ( - "flag" - "os" - - "github.com/dokku/dokku/plugins/config" -) - -func main() { - args := flag.NewFlagSet("config:bundle", flag.ExitOnError) - global := args.Bool("global", false, "--global: use the global environment") - merged := args.Bool("merged", false, "--merged: merge app environment and global environment") - args.Parse(os.Args[2:]) - config.CommandBundle(args.Args(), *global, *merged) -} diff --git a/plugins/config/src/subcommands/clear/clear.go b/plugins/config/src/subcommands/clear/clear.go deleted file mode 100644 index 8fe985330..000000000 --- a/plugins/config/src/subcommands/clear/clear.go +++ /dev/null @@ -1,17 +0,0 @@ -package main - -import ( - "flag" - "os" - - "github.com/dokku/dokku/plugins/config" -) - -//clear all entries from the given environment -func main() { - args := flag.NewFlagSet("config:clear", flag.ExitOnError) - global := args.Bool("global", false, "--global: use the global environment") - noRestart := args.Bool("no-restart", false, "--no-restart: no restart") - args.Parse(os.Args[2:]) - config.CommandClear(args.Args(), *global, *noRestart) -} diff --git a/plugins/config/src/subcommands/export/export.go b/plugins/config/src/subcommands/export/export.go deleted file mode 100644 index c83f8a6f6..000000000 --- a/plugins/config/src/subcommands/export/export.go +++ /dev/null @@ -1,20 +0,0 @@ -package main - -import ( - "flag" - "os" - - "github.com/dokku/dokku/plugins/config" -) - -// print the environment to stdout -func main() { - const defaultPrefix = "export " - const defaultSeparator = "\n" - args := flag.NewFlagSet("config:export", flag.ExitOnError) - global := args.Bool("global", false, "--global: use the global environment") - merged := args.Bool("merged", false, "--merged: merge app environment and global environment") - format := args.String("format", "exports", "--format: [ exports | envfile | docker-args | shell | pretty | json | json-list ] which format to export as)") - args.Parse(os.Args[2:]) - config.CommandExport(args.Args(), *global, *merged, *format) -} diff --git a/plugins/config/src/subcommands/get/get.go b/plugins/config/src/subcommands/get/get.go deleted file mode 100644 index 52840b3fa..000000000 --- a/plugins/config/src/subcommands/get/get.go +++ /dev/null @@ -1,17 +0,0 @@ -package main - -import ( - "flag" - "os" - - "github.com/dokku/dokku/plugins/config" -) - -// get the given entries from the specified environment -func main() { - args := flag.NewFlagSet("config:get", flag.ExitOnError) - global := args.Bool("global", false, "--global: use the global environment") - quoted := args.Bool("quoted", false, "--quoted: get the value quoted") - args.Parse(os.Args[2:]) - config.CommandGet(args.Args(), *global, *quoted) -} diff --git a/plugins/config/src/subcommands/keys/keys.go b/plugins/config/src/subcommands/keys/keys.go deleted file mode 100644 index 4f1bbbbc8..000000000 --- a/plugins/config/src/subcommands/keys/keys.go +++ /dev/null @@ -1,16 +0,0 @@ -package main - -import ( - "flag" - "os" - - "github.com/dokku/dokku/plugins/config" -) - -func main() { - args := flag.NewFlagSet("config:keys", flag.ExitOnError) - global := args.Bool("global", false, "--global: use the global environment") - merged := args.Bool("merged", false, "--merged: merge app environment and global environment") - args.Parse(os.Args[2:]) - config.CommandKeys(args.Args(), *global, *merged) -} diff --git a/plugins/config/src/subcommands/set/set.go b/plugins/config/src/subcommands/set/set.go deleted file mode 100644 index cb6c8f4ff..000000000 --- a/plugins/config/src/subcommands/set/set.go +++ /dev/null @@ -1,18 +0,0 @@ -package main - -import ( - "flag" - "os" - - "github.com/dokku/dokku/plugins/config" -) - -// set the given entries to the specified environment -func main() { - args := flag.NewFlagSet("config:set", flag.ExitOnError) - global := args.Bool("global", false, "--global: use the global environment") - encoded := args.Bool("encoded", false, "--encoded: interpret VALUEs as base64") - noRestart := args.Bool("no-restart", false, "--no-restart: no restart") - args.Parse(os.Args[2:]) - config.CommandSet(args.Args(), *global, *noRestart, *encoded) -} diff --git a/plugins/config/src/subcommands/subcommands.go b/plugins/config/src/subcommands/subcommands.go new file mode 100644 index 000000000..9f9eeae7a --- /dev/null +++ b/plugins/config/src/subcommands/subcommands.go @@ -0,0 +1,67 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + "github.com/dokku/dokku/plugins/common" + "github.com/dokku/dokku/plugins/config" +) + +// main entrypoint to all subcommands +func main() { + parts := strings.Split(os.Args[0], "/") + subcommand := parts[len(parts)-1] + + switch subcommand { + case "bundle": + args := flag.NewFlagSet("config:bundle", flag.ExitOnError) + global := args.Bool("global", false, "--global: use the global environment") + merged := args.Bool("merged", false, "--merged: merge app environment and global environment") + args.Parse(os.Args[2:]) + config.CommandBundle(args.Args(), *global, *merged) + case "clear": + args := flag.NewFlagSet("config:clear", flag.ExitOnError) + global := args.Bool("global", false, "--global: use the global environment") + noRestart := args.Bool("no-restart", false, "--no-restart: no restart") + args.Parse(os.Args[2:]) + config.CommandClear(args.Args(), *global, *noRestart) + case "export": + args := flag.NewFlagSet("config:export", flag.ExitOnError) + global := args.Bool("global", false, "--global: use the global environment") + merged := args.Bool("merged", false, "--merged: merge app environment and global environment") + format := args.String("format", "exports", "--format: [ exports | envfile | docker-args | shell | pretty | json | json-list ] which format to export as)") + args.Parse(os.Args[2:]) + config.CommandExport(args.Args(), *global, *merged, *format) + case "get": + args := flag.NewFlagSet("config:get", flag.ExitOnError) + global := args.Bool("global", false, "--global: use the global environment") + quoted := args.Bool("quoted", false, "--quoted: get the value quoted") + args.Parse(os.Args[2:]) + config.CommandGet(args.Args(), *global, *quoted) + case "keys": + args := flag.NewFlagSet("config:keys", flag.ExitOnError) + global := args.Bool("global", false, "--global: use the global environment") + merged := args.Bool("merged", false, "--merged: merge app environment and global environment") + args.Parse(os.Args[2:]) + config.CommandKeys(args.Args(), *global, *merged) + case "set": + args := flag.NewFlagSet("config:set", flag.ExitOnError) + global := args.Bool("global", false, "--global: use the global environment") + encoded := args.Bool("encoded", false, "--encoded: interpret VALUEs as base64") + noRestart := args.Bool("no-restart", false, "--no-restart: no restart") + args.Parse(os.Args[2:]) + config.CommandSet(args.Args(), *global, *noRestart, *encoded) + case "unset": + args := flag.NewFlagSet("config:unset", flag.ExitOnError) + global := args.Bool("global", false, "--global: use the global environment") + noRestart := args.Bool("no-restart", false, "--no-restart: no restart") + args.Parse(os.Args[2:]) + config.CommandUnset(args.Args(), *global, *noRestart) + default: + common.LogFail(fmt.Sprintf("Invalid plugin subcommand call: %s", subcommand)) + } + +} diff --git a/plugins/config/src/subcommands/unset/unset.go b/plugins/config/src/subcommands/unset/unset.go deleted file mode 100644 index c6c4ee814..000000000 --- a/plugins/config/src/subcommands/unset/unset.go +++ /dev/null @@ -1,17 +0,0 @@ -package main - -import ( - "flag" - "os" - - "github.com/dokku/dokku/plugins/config" -) - -//unset the given entries from the given environment -func main() { - args := flag.NewFlagSet("config:unset", flag.ExitOnError) - global := args.Bool("global", false, "--global: use the global environment") - noRestart := args.Bool("no-restart", false, "--no-restart: no restart") - args.Parse(os.Args[2:]) - config.CommandUnset(args.Args(), *global, *noRestart) -} diff --git a/plugins/network/.gitignore b/plugins/network/.gitignore index 7674a1147..6385eaf1e 100644 --- a/plugins/network/.gitignore +++ b/plugins/network/.gitignore @@ -1,6 +1,7 @@ /commands /subcommands/* /triggers/* +/triggers /network-* /install /post-app-clone-setup diff --git a/plugins/network/Makefile b/plugins/network/Makefile index 813234501..7dd901ccf 100644 --- a/plugins/network/Makefile +++ b/plugins/network/Makefile @@ -1,37 +1,6 @@ -include ../../common.mk - -GO_ARGS ?= -a - SUBCOMMANDS = subcommands/rebuild subcommands/rebuildall subcommands/report subcommands/set TRIGGERS = triggers/install triggers/network-build-config triggers/network-compute-ports triggers/network-config-exists triggers/network-get-ipaddr triggers/network-get-listeners triggers/network-get-port triggers/network-get-property triggers/network-write-ipaddr triggers/network-write-port triggers/post-app-clone-setup triggers/post-create triggers/post-delete triggers/report -build-in-docker: clean - docker run --rm \ - -v $$PWD/../..:$(GO_REPO_ROOT) \ - -w $(GO_REPO_ROOT)/plugins/network \ - $(BUILD_IMAGE) \ - bash -c "GO_ARGS='$(GO_ARGS)' make -j4 build" || exit $$? +BUILD = commands subcommands triggers +PLUGIN_NAME = network -build: commands subcommands triggers - $(MAKE) triggers-copy - -commands: **/**/commands.go - go build $(GO_ARGS) -o commands src/commands/commands.go - -subcommands: $(SUBCOMMANDS) - -subcommands/%: src/subcommands/*/%.go - go build $(GO_ARGS) -o $@ $< - -clean: - rm -rf commands subcommands triggers network-* install post-app-clone-setup post-create post-delete report - -src-clean: - rm -rf .gitignore src triggers vendor Makefile *.go glide.* - -triggers: $(TRIGGERS) - -triggers/%: src/triggers/*/%.go - go build $(GO_ARGS) -o $@ $< - -triggers-copy: - cp triggers/* . +include ../../common.mk diff --git a/plugins/network/src/subcommands/rebuild/rebuild.go b/plugins/network/src/subcommands/rebuild/rebuild.go deleted file mode 100644 index b2d129532..000000000 --- a/plugins/network/src/subcommands/rebuild/rebuild.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - "flag" - - "github.com/dokku/dokku/plugins/network" -) - -// rebuilds network settings for an app -func main() { - flag.Parse() - appName := flag.Arg(1) - - network.BuildConfig(appName) -} diff --git a/plugins/network/src/subcommands/rebuildall/rebuildall.go b/plugins/network/src/subcommands/rebuildall/rebuildall.go deleted file mode 100644 index 01c09c670..000000000 --- a/plugins/network/src/subcommands/rebuildall/rebuildall.go +++ /dev/null @@ -1,17 +0,0 @@ -package main - -import ( - "github.com/dokku/dokku/plugins/common" - "github.com/dokku/dokku/plugins/network" -) - -// rebuilds network settings for all apps -func main() { - apps, err := common.DokkuApps() - if err != nil { - common.LogFail(err.Error()) - } - for _, appName := range apps { - network.BuildConfig(appName) - } -} diff --git a/plugins/network/src/subcommands/report/report.go b/plugins/network/src/subcommands/report/report.go deleted file mode 100644 index b3e3111fa..000000000 --- a/plugins/network/src/subcommands/report/report.go +++ /dev/null @@ -1,34 +0,0 @@ -package main - -import ( - "flag" - "strings" - - "github.com/dokku/dokku/plugins/common" - "github.com/dokku/dokku/plugins/network" -) - -// displays a network report for one or more apps -func main() { - flag.Parse() - appName := flag.Arg(1) - infoFlag := flag.Arg(2) - - if strings.HasPrefix(appName, "--") { - infoFlag = appName - appName = "" - } - - if len(appName) == 0 { - apps, err := common.DokkuApps() - if err != nil { - return - } - for _, appName := range apps { - network.ReportSingleApp(appName, infoFlag) - } - return - } - - network.ReportSingleApp(appName, infoFlag) -} diff --git a/plugins/network/src/subcommands/set/set.go b/plugins/network/src/subcommands/set/set.go deleted file mode 100644 index cd8eb73ef..000000000 --- a/plugins/network/src/subcommands/set/set.go +++ /dev/null @@ -1,22 +0,0 @@ -package main - -import ( - "flag" - - "github.com/dokku/dokku/plugins/common" - "github.com/dokku/dokku/plugins/network" -) - -// set or clear a network property for an app -func main() { - flag.Parse() - appName := flag.Arg(1) - property := flag.Arg(2) - value := flag.Arg(3) - - if property == "bind-all-interfaces" && value == "" { - value = "false" - } - - common.CommandPropertySet("network", appName, property, value, network.DefaultProperties) -} diff --git a/plugins/network/src/subcommands/subcommands.go b/plugins/network/src/subcommands/subcommands.go new file mode 100644 index 000000000..75e88ba89 --- /dev/null +++ b/plugins/network/src/subcommands/subcommands.go @@ -0,0 +1,37 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + "github.com/dokku/dokku/plugins/common" + "github.com/dokku/dokku/plugins/network" +) + +// main entrypoint to all subcommands +func main() { + parts := strings.Split(os.Args[0], "/") + subcommand := parts[len(parts)-1] + flag.Parse() + + switch subcommand { + case "rebuild": + appName := flag.Arg(1) + network.BuildConfig(appName) + case "rebuildall": + network.CommandRebuildall() + case "report": + appName := flag.Arg(1) + infoFlag := flag.Arg(2) + network.CommandReport(appName, infoFlag) + case "set": + appName := flag.Arg(1) + property := flag.Arg(2) + value := flag.Arg(3) + network.CommandSet(appName, property, value) + default: + common.LogFail(fmt.Sprintf("Invalid plugin subcommand call: %s", subcommand)) + } +} diff --git a/plugins/network/src/triggers/install/install.go b/plugins/network/src/triggers/install/install.go deleted file mode 100644 index 6b595c833..000000000 --- a/plugins/network/src/triggers/install/install.go +++ /dev/null @@ -1,36 +0,0 @@ -package main - -import ( - "fmt" - - "github.com/dokku/dokku/plugins/common" - "github.com/dokku/dokku/plugins/proxy" -) - -// runs the install step for the network plugin -func main() { - if err := common.PropertySetup("network"); err != nil { - common.LogFail(fmt.Sprintf("Unable to install the network plugin: %s", err.Error())) - } - - apps, err := common.DokkuApps() - if err != nil { - return - } - for _, appName := range apps { - if common.PropertyExists("network", appName, "bind-all-interfaces") { - continue - } - if proxy.IsAppProxyEnabled(appName) { - common.LogVerboseQuiet("Setting network property 'bind-all-interfaces' to false") - if err := common.PropertyWrite("network", appName, "bind-all-interfaces", "false"); err != nil { - common.LogWarn(err.Error()) - } - } else { - common.LogVerboseQuiet("Setting network property 'bind-all-interfaces' to true") - if err := common.PropertyWrite("network", appName, "bind-all-interfaces", "true"); err != nil { - common.LogWarn(err.Error()) - } - } - } -} diff --git a/plugins/network/src/triggers/network-build-config/network-build-config.go b/plugins/network/src/triggers/network-build-config/network-build-config.go deleted file mode 100644 index 6c2bc2af8..000000000 --- a/plugins/network/src/triggers/network-build-config/network-build-config.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - "flag" - - "github.com/dokku/dokku/plugins/network" -) - -// rebuilds network settings for an app -func main() { - flag.Parse() - appName := flag.Arg(0) - - network.BuildConfig(appName) -} diff --git a/plugins/network/src/triggers/network-compute-ports/network-compute-ports.go b/plugins/network/src/triggers/network-compute-ports/network-compute-ports.go deleted file mode 100644 index b981c59b0..000000000 --- a/plugins/network/src/triggers/network-compute-ports/network-compute-ports.go +++ /dev/null @@ -1,46 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "os" - "strings" - "unicode/utf8" - - "github.com/dokku/dokku/plugins/common" - "github.com/dokku/dokku/plugins/config" -) - -// computes the ports for a given app container -func main() { - flag.Parse() - appName := flag.Arg(0) - processType := flag.Arg(1) - isHerokuishContainer := common.ToBool(flag.Arg(2)) - - if processType != "web" { - return - } - - var dockerfilePorts []string - if !isHerokuishContainer { - dokkuDockerfilePorts := strings.Trim(config.GetWithDefault(appName, "DOKKU_DOCKERFILE_PORTS", ""), " ") - if utf8.RuneCountInString(dokkuDockerfilePorts) > 0 { - dockerfilePorts = strings.Split(dokkuDockerfilePorts, " ") - } - } - - var ports []string - if len(dockerfilePorts) == 0 { - ports = append(ports, "5000") - } else { - for _, port := range dockerfilePorts { - port = strings.TrimSuffix(strings.TrimSpace(port), "/tcp") - if port == "" || strings.HasSuffix(port, "/udp") { - continue - } - ports = append(ports, port) - } - } - fmt.Fprint(os.Stdout, strings.Join(ports, " ")) -} diff --git a/plugins/network/src/triggers/network-config-exists/network-config-exists.go b/plugins/network/src/triggers/network-config-exists/network-config-exists.go deleted file mode 100644 index b604fb5de..000000000 --- a/plugins/network/src/triggers/network-config-exists/network-config-exists.go +++ /dev/null @@ -1,22 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "os" - - "github.com/dokku/dokku/plugins/network" -) - -// writes true or false to stdout whether a given app has network config -func main() { - flag.Parse() - appName := flag.Arg(0) - - if network.HasNetworkConfig(appName) { - fmt.Fprintln(os.Stdout, "true") - return - } - - fmt.Fprintln(os.Stdout, "false") -} diff --git a/plugins/network/src/triggers/network-get-ipaddr/network-get-ipaddr.go b/plugins/network/src/triggers/network-get-ipaddr/network-get-ipaddr.go deleted file mode 100644 index 237526b64..000000000 --- a/plugins/network/src/triggers/network-get-ipaddr/network-get-ipaddr.go +++ /dev/null @@ -1,20 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "os" - - "github.com/dokku/dokku/plugins/network" -) - -// write the ipaddress to stdout for a given app container -func main() { - flag.Parse() - appName := flag.Arg(0) - processType := flag.Arg(1) - containerID := flag.Arg(2) - - ipAddress := network.GetContainerIpaddress(appName, processType, containerID) - fmt.Fprintln(os.Stdout, ipAddress) -} diff --git a/plugins/network/src/triggers/network-get-listeners/network-get-listeners.go b/plugins/network/src/triggers/network-get-listeners/network-get-listeners.go deleted file mode 100644 index 9c999fe4e..000000000 --- a/plugins/network/src/triggers/network-get-listeners/network-get-listeners.go +++ /dev/null @@ -1,19 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "os" - "strings" - - "github.com/dokku/dokku/plugins/network" -) - -// returns the listeners (host:port combinations) for a given app container -func main() { - flag.Parse() - appName := flag.Arg(0) - - listeners := network.GetListeners(appName) - fmt.Fprint(os.Stdout, strings.Join(listeners, " ")) -} diff --git a/plugins/network/src/triggers/network-get-port/network-get-port.go b/plugins/network/src/triggers/network-get-port/network-get-port.go deleted file mode 100644 index 389265da7..000000000 --- a/plugins/network/src/triggers/network-get-port/network-get-port.go +++ /dev/null @@ -1,22 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "os" - - "github.com/dokku/dokku/plugins/common" - network "github.com/dokku/dokku/plugins/network" -) - -// write the port to stdout for a given app container -func main() { - flag.Parse() - appName := flag.Arg(0) - processType := flag.Arg(1) - isHerokuishContainer := common.ToBool(flag.Arg(2)) - containerID := flag.Arg(3) - - port := network.GetContainerPort(appName, processType, isHerokuishContainer, containerID) - fmt.Fprintln(os.Stdout, port) -} diff --git a/plugins/network/src/triggers/network-get-property/network-get-property.go b/plugins/network/src/triggers/network-get-property/network-get-property.go deleted file mode 100644 index 9da6f0ba1..000000000 --- a/plugins/network/src/triggers/network-get-property/network-get-property.go +++ /dev/null @@ -1,21 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "os" - - "github.com/dokku/dokku/plugins/common" - network "github.com/dokku/dokku/plugins/network" -) - -// writes the network property to stdout for a given app container -func main() { - flag.Parse() - appName := flag.Arg(0) - property := flag.Arg(1) - - defaultValue := network.GetDefaultValue(property) - value := common.PropertyGetDefault("network", appName, property, defaultValue) - fmt.Fprintln(os.Stdout, value) -} diff --git a/plugins/network/src/triggers/network-write-ipaddr/network-write-ipaddr.go b/plugins/network/src/triggers/network-write-ipaddr/network-write-ipaddr.go deleted file mode 100644 index 3cf618120..000000000 --- a/plugins/network/src/triggers/network-write-ipaddr/network-write-ipaddr.go +++ /dev/null @@ -1,41 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "os" - "strings" - - "github.com/dokku/dokku/plugins/common" -) - -// writes the ip to disk -func main() { - flag.Parse() - appName := flag.Arg(0) - processType := flag.Arg(1) - containerIndex := flag.Arg(2) - ip := flag.Arg(3) - - if appName == "" { - common.LogFail("Please specify an app to run the command on") - } - err := common.VerifyAppName(appName) - if err != nil { - common.LogFail(err.Error()) - } - - appRoot := strings.Join([]string{common.MustGetEnv("DOKKU_ROOT"), appName}, "/") - filename := fmt.Sprintf("%v/IP.%v.%v", appRoot, processType, containerIndex) - f, err := os.Create(filename) - if err != nil { - common.LogFail(err.Error()) - } - defer f.Close() - - ipBytes := []byte(ip) - _, err = f.Write(ipBytes) - if err != nil { - common.LogFail(err.Error()) - } -} diff --git a/plugins/network/src/triggers/network-write-port/network-write-port.go b/plugins/network/src/triggers/network-write-port/network-write-port.go deleted file mode 100644 index e263cd786..000000000 --- a/plugins/network/src/triggers/network-write-port/network-write-port.go +++ /dev/null @@ -1,41 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "os" - "strings" - - "github.com/dokku/dokku/plugins/common" -) - -// writes the port to disk -func main() { - flag.Parse() - appName := flag.Arg(0) - processType := flag.Arg(1) - containerIndex := flag.Arg(2) - port := flag.Arg(3) - - if appName == "" { - common.LogFail("Please specify an app to run the command on") - } - err := common.VerifyAppName(appName) - if err != nil { - common.LogFail(err.Error()) - } - - appRoot := strings.Join([]string{common.MustGetEnv("DOKKU_ROOT"), appName}, "/") - filename := fmt.Sprintf("%v/PORT.%v.%v", appRoot, processType, containerIndex) - f, err := os.Create(filename) - if err != nil { - common.LogFail(err.Error()) - } - defer f.Close() - - portBytes := []byte(port) - _, err = f.Write(portBytes) - if err != nil { - common.LogFail(err.Error()) - } -} diff --git a/plugins/network/src/triggers/post-app-clone-setup/post-app-clone-setup.go b/plugins/network/src/triggers/post-app-clone-setup/post-app-clone-setup.go deleted file mode 100644 index 70adb14ce..000000000 --- a/plugins/network/src/triggers/post-app-clone-setup/post-app-clone-setup.go +++ /dev/null @@ -1,19 +0,0 @@ -package main - -import ( - "flag" - "os" - - "github.com/dokku/dokku/plugins/network" -) - -// cleanup network files for a new app clone -func main() { - flag.Parse() - appName := flag.Arg(1) - - success := network.PostAppCloneSetup(appName) - if !success { - os.Exit(1) - } -} diff --git a/plugins/network/src/triggers/post-create/post-create.go b/plugins/network/src/triggers/post-create/post-create.go deleted file mode 100644 index c71d07b9c..000000000 --- a/plugins/network/src/triggers/post-create/post-create.go +++ /dev/null @@ -1,18 +0,0 @@ -package main - -import ( - "flag" - - "github.com/dokku/dokku/plugins/common" -) - -// set bind-all-interfaces to false by default -func main() { - flag.Parse() - appName := flag.Arg(0) - - err := common.PropertyWrite("network", appName, "bind-all-interfaces", "false") - if err != nil { - common.LogWarn(err.Error()) - } -} diff --git a/plugins/network/src/triggers/post-delete/post-delete.go b/plugins/network/src/triggers/post-delete/post-delete.go deleted file mode 100644 index 7d29808b5..000000000 --- a/plugins/network/src/triggers/post-delete/post-delete.go +++ /dev/null @@ -1,18 +0,0 @@ -package main - -import ( - "flag" - - "github.com/dokku/dokku/plugins/common" -) - -// destroys the network property for a given app container -func main() { - flag.Parse() - appName := flag.Arg(0) - - err := common.PropertyDestroy("network", appName) - if err != nil { - common.LogFail(err.Error()) - } -} diff --git a/plugins/network/src/triggers/report/report.go b/plugins/network/src/triggers/report/report.go deleted file mode 100644 index 780ecf065..000000000 --- a/plugins/network/src/triggers/report/report.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - "flag" - - "github.com/dokku/dokku/plugins/network" -) - -// displays a network report for one or more apps -func main() { - flag.Parse() - appName := flag.Arg(0) - - network.ReportSingleApp(appName, "") -} diff --git a/plugins/network/src/triggers/triggers.go b/plugins/network/src/triggers/triggers.go new file mode 100644 index 000000000..0f34ca578 --- /dev/null +++ b/plugins/network/src/triggers/triggers.go @@ -0,0 +1,78 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + "github.com/dokku/dokku/plugins/common" + "github.com/dokku/dokku/plugins/network" +) + +// main entrypoint to all triggers +func main() { + parts := strings.Split(os.Args[0], "/") + trigger := parts[len(parts)-1] + flag.Parse() + + switch trigger { + case "install": + network.TriggerInstall() + case "network-build-config": + appName := flag.Arg(0) + network.BuildConfig(appName) + case "network-compute-ports": + appName := flag.Arg(0) + processType := flag.Arg(1) + isHerokuishContainer := common.ToBool(flag.Arg(2)) + network.TriggerNetworkComputePorts(appName, processType, isHerokuishContainer) + case "network-config-exists": + appName := flag.Arg(0) + network.TriggerNetworkConfigExists(appName) + case "network-get-ipaddr": + appName := flag.Arg(0) + processType := flag.Arg(1) + containerID := flag.Arg(2) + network.TriggerNetworkGetIppaddr(appName, processType, containerID) + case "network-get-listeners": + appName := flag.Arg(0) + network.TriggerNetworkGetListeners(appName) + case "network-get-port": + appName := flag.Arg(0) + processType := flag.Arg(1) + isHerokuishContainer := common.ToBool(flag.Arg(2)) + containerID := flag.Arg(3) + network.TriggerNetworkGetPort(appName, processType, isHerokuishContainer, containerID) + case "network-get-property": + appName := flag.Arg(0) + property := flag.Arg(1) + network.TriggerNetworkGetProperty(appName, property) + case "network-write-ipaddr": + appName := flag.Arg(0) + processType := flag.Arg(1) + containerIndex := flag.Arg(2) + ip := flag.Arg(3) + network.TriggerNetworkWriteIpaddr(appName, processType, containerIndex, ip) + case "network-write-port": + appName := flag.Arg(0) + processType := flag.Arg(1) + containerIndex := flag.Arg(2) + port := flag.Arg(3) + network.TriggerNetworkWritePort(appName, processType, containerIndex, port) + case "post-app-clone-setup": + appName := flag.Arg(1) + network.TriggerPostAppCloneSetup(appName) + case "post-create": + appName := flag.Arg(0) + network.TriggerPostCreate(appName) + case "post-delete": + appName := flag.Arg(0) + network.TriggerPostDelete(appName) + case "report": + appName := flag.Arg(0) + network.ReportSingleApp(appName, "") + default: + common.LogFail(fmt.Sprintf("Invalid plugin trigger call: %s", trigger)) + } +} diff --git a/plugins/network/subcommands.go b/plugins/network/subcommands.go new file mode 100644 index 000000000..74449c6f6 --- /dev/null +++ b/plugins/network/subcommands.go @@ -0,0 +1,48 @@ +package network + +import ( + "strings" + + "github.com/dokku/dokku/plugins/common" +) + +// rebuilds network settings for all apps +func CommandRebuildall() { + apps, err := common.DokkuApps() + if err != nil { + common.LogFail(err.Error()) + } + for _, appName := range apps { + BuildConfig(appName) + } +} + +// displays a network report for one or more apps +func CommandReport(appName string, infoFlag string) { + if strings.HasPrefix(appName, "--") { + infoFlag = appName + appName = "" + } + + if len(appName) == 0 { + apps, err := common.DokkuApps() + if err != nil { + return + } + for _, appName := range apps { + ReportSingleApp(appName, infoFlag) + } + return + } + + ReportSingleApp(appName, infoFlag) +} + +// set or clear a network property for an app +func CommandSet(appName string, property string, value string) { + if property == "bind-all-interfaces" && value == "" { + value = "false" + } + + common.CommandPropertySet("network", appName, property, value, DefaultProperties) +} diff --git a/plugins/network/triggers.go b/plugins/network/triggers.go new file mode 100644 index 000000000..46796b50e --- /dev/null +++ b/plugins/network/triggers.go @@ -0,0 +1,178 @@ +package network + +import ( + "fmt" + "os" + "strings" + "unicode/utf8" + + "github.com/dokku/dokku/plugins/common" + "github.com/dokku/dokku/plugins/config" + "github.com/dokku/dokku/plugins/proxy" +) + +// runs the install step for the network plugin +func TriggerInstall() { + if err := common.PropertySetup("network"); err != nil { + common.LogFail(fmt.Sprintf("Unable to install the network plugin: %s", err.Error())) + } + + apps, err := common.DokkuApps() + if err != nil { + return + } + for _, appName := range apps { + if common.PropertyExists("network", appName, "bind-all-interfaces") { + continue + } + if proxy.IsAppProxyEnabled(appName) { + common.LogVerboseQuiet("Setting network property 'bind-all-interfaces' to false") + if err := common.PropertyWrite("network", appName, "bind-all-interfaces", "false"); err != nil { + common.LogWarn(err.Error()) + } + } else { + common.LogVerboseQuiet("Setting network property 'bind-all-interfaces' to true") + if err := common.PropertyWrite("network", appName, "bind-all-interfaces", "true"); err != nil { + common.LogWarn(err.Error()) + } + } + } +} + +// computes the ports for a given app container +func TriggerNetworkComputePorts(appName string, processType string, isHerokuishContainer bool) { + if processType != "web" { + return + } + + var dockerfilePorts []string + if !isHerokuishContainer { + dokkuDockerfilePorts := strings.Trim(config.GetWithDefault(appName, "DOKKU_DOCKERFILE_PORTS", ""), " ") + if utf8.RuneCountInString(dokkuDockerfilePorts) > 0 { + dockerfilePorts = strings.Split(dokkuDockerfilePorts, " ") + } + } + + var ports []string + if len(dockerfilePorts) == 0 { + ports = append(ports, "5000") + } else { + for _, port := range dockerfilePorts { + port = strings.TrimSuffix(strings.TrimSpace(port), "/tcp") + if port == "" || strings.HasSuffix(port, "/udp") { + continue + } + ports = append(ports, port) + } + } + fmt.Fprint(os.Stdout, strings.Join(ports, " ")) +} + +// writes true or false to stdout whether a given app has network config +func TriggerNetworkConfigExists(appName string) { + if HasNetworkConfig(appName) { + fmt.Fprintln(os.Stdout, "true") + return + } + + fmt.Fprintln(os.Stdout, "false") +} + +// write the ipaddress to stdout for a given app container +func TriggerNetworkGetIppaddr(appName string, processType string, containerID string) { + ipAddress := GetContainerIpaddress(appName, processType, containerID) + fmt.Fprintln(os.Stdout, ipAddress) +} + +// returns the listeners (host:port combinations) for a given app container +func TriggerNetworkGetListeners(appName string) { + listeners := GetListeners(appName) + fmt.Fprint(os.Stdout, strings.Join(listeners, " ")) +} + +// write the port to stdout for a given app container +func TriggerNetworkGetPort(appName string, processType string, isHerokuishContainer bool, containerID string) { + port := GetContainerPort(appName, processType, isHerokuishContainer, containerID) + fmt.Fprintln(os.Stdout, port) +} + +// writes the network property to stdout for a given app container +func TriggerNetworkGetProperty(appName string, property string) { + defaultValue := GetDefaultValue(property) + value := common.PropertyGetDefault("network", appName, property, defaultValue) + fmt.Fprintln(os.Stdout, value) +} + +// writes the ip to disk +func TriggerNetworkWriteIpaddr(appName string, processType string, containerIndex string, ip string) { + if appName == "" { + common.LogFail("Please specify an app to run the command on") + } + err := common.VerifyAppName(appName) + if err != nil { + common.LogFail(err.Error()) + } + + appRoot := strings.Join([]string{common.MustGetEnv("DOKKU_ROOT"), appName}, "/") + filename := fmt.Sprintf("%v/IP.%v.%v", appRoot, processType, containerIndex) + f, err := os.Create(filename) + if err != nil { + common.LogFail(err.Error()) + } + defer f.Close() + + ipBytes := []byte(ip) + _, err = f.Write(ipBytes) + if err != nil { + common.LogFail(err.Error()) + } +} + +// writes the port to disk +func TriggerNetworkWritePort(appName string, processType string, containerIndex string, port string) { + if appName == "" { + common.LogFail("Please specify an app to run the command on") + } + err := common.VerifyAppName(appName) + if err != nil { + common.LogFail(err.Error()) + } + + appRoot := strings.Join([]string{common.MustGetEnv("DOKKU_ROOT"), appName}, "/") + filename := fmt.Sprintf("%v/PORT.%v.%v", appRoot, processType, containerIndex) + f, err := os.Create(filename) + if err != nil { + common.LogFail(err.Error()) + } + defer f.Close() + + portBytes := []byte(port) + _, err = f.Write(portBytes) + if err != nil { + common.LogFail(err.Error()) + } +} + +// cleanup network files for a new app clone +func TriggerPostAppCloneSetup(appName string) { + success := PostAppCloneSetup(appName) + if !success { + os.Exit(1) + } +} + +// set bind-all-interfaces to false by default +func TriggerPostCreate(appName string) { + err := common.PropertyWrite("network", appName, "bind-all-interfaces", "false") + if err != nil { + common.LogWarn(err.Error()) + } +} + +// destroys the network property for a given app container +func TriggerPostDelete(appName string) { + err := common.PropertyDestroy("network", appName) + if err != nil { + common.LogFail(err.Error()) + } +} diff --git a/plugins/repo/.gitignore b/plugins/repo/.gitignore index 0f6770b1e..cc45caec7 100644 --- a/plugins/repo/.gitignore +++ b/plugins/repo/.gitignore @@ -1,2 +1,4 @@ /commands /subcommands/* +/triggers/* +/triggers diff --git a/plugins/repo/Makefile b/plugins/repo/Makefile index 706a28900..2dd00e389 100644 --- a/plugins/repo/Makefile +++ b/plugins/repo/Makefile @@ -1,37 +1,6 @@ -include ../../common.mk - -GO_ARGS ?= -a - SUBCOMMANDS = subcommands/gc subcommands/purge-cache TRIGGERS = triggers/pre-delete -build-in-docker: clean - docker run --rm \ - -v $$PWD/../..:$(GO_REPO_ROOT) \ - -w $(GO_REPO_ROOT)/plugins/repo \ - $(BUILD_IMAGE) \ - bash -c "GO_ARGS='$(GO_ARGS)' make -j4 build" || exit $$? +BUILD = commands subcommands triggers +PLUGIN_NAME = repo -build: commands subcommands triggers - $(MAKE) triggers-copy - -commands: **/**/commands.go - go build $(GO_ARGS) -o commands src/commands/commands.go - -subcommands: $(SUBCOMMANDS) - -subcommands/%: src/subcommands/*/%.go - go build $(GO_ARGS) -o $@ $< - -clean: - rm -rf commands subcommands triggers pre-delete - -src-clean: - rm -rf .gitignore src triggers vendor Makefile *.go glide.* - -triggers: $(TRIGGERS) - -triggers/%: src/triggers/*/%.go - go build $(GO_ARGS) -o $@ $< - -triggers-copy: - cp triggers/* . +include ../../common.mk diff --git a/plugins/repo/pre-delete b/plugins/repo/pre-delete new file mode 120000 index 000000000..fa05d2b3e --- /dev/null +++ b/plugins/repo/pre-delete @@ -0,0 +1 @@ +triggers \ No newline at end of file diff --git a/plugins/repo/src/subcommands/purge-cache/purge-cache.go b/plugins/repo/src/subcommands/purge-cache/purge-cache.go deleted file mode 100644 index 63665ca18..000000000 --- a/plugins/repo/src/subcommands/purge-cache/purge-cache.go +++ /dev/null @@ -1,22 +0,0 @@ -package main - -import ( - "flag" - - "github.com/dokku/dokku/plugins/common" - "github.com/dokku/dokku/plugins/repo" -) - -// deletes the contents of the build cache stored in the repository -func main() { - flag.Parse() - appName := flag.Arg(1) - if appName == "" { - common.LogFail("Please specify an app to run the command on") - } - - err := repo.PurgeCache(appName) - if err != nil { - common.LogWarn(err.Error()) - } -} diff --git a/plugins/repo/src/subcommands/subcommands.go b/plugins/repo/src/subcommands/subcommands.go new file mode 100644 index 000000000..4194cb147 --- /dev/null +++ b/plugins/repo/src/subcommands/subcommands.go @@ -0,0 +1,35 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + "github.com/dokku/dokku/plugins/common" + "github.com/dokku/dokku/plugins/repo" +) + +// main entrypoint to all subcommands +func main() { + parts := strings.Split(os.Args[0], "/") + subcommand := parts[len(parts)-1] + flag.Parse() + + var err error + switch subcommand { + case "gc": + flag.Parse() + appName := flag.Arg(1) + err = repo.CommandGc(appName) + case "purge-cache": + appName := flag.Arg(1) + err = repo.CommandPurgeCache(appName) + default: + common.LogFail(fmt.Sprintf("Invalid plugin subcommand call: %s", subcommand)) + } + + if err != nil { + common.LogFail(err.Error()) + } +} diff --git a/plugins/repo/src/triggers/pre-delete/pre-delete.go b/plugins/repo/src/triggers/pre-delete/pre-delete.go deleted file mode 100644 index c43f5fba0..000000000 --- a/plugins/repo/src/triggers/pre-delete/pre-delete.go +++ /dev/null @@ -1,19 +0,0 @@ -package main - -import ( - "flag" - - "github.com/dokku/dokku/plugins/common" - "github.com/dokku/dokku/plugins/repo" -) - -// destroys the buildpacks property for a given app container -func main() { - flag.Parse() - appName := flag.Arg(0) - - err := repo.PurgeCache(appName) - if err != nil { - common.LogFail(err.Error()) - } -} diff --git a/plugins/repo/src/triggers/triggers.go b/plugins/repo/src/triggers/triggers.go new file mode 100644 index 000000000..b0dbd6eff --- /dev/null +++ b/plugins/repo/src/triggers/triggers.go @@ -0,0 +1,31 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + "github.com/dokku/dokku/plugins/common" + "github.com/dokku/dokku/plugins/repo" +) + +// main entrypoint to all triggers +func main() { + parts := strings.Split(os.Args[0], "/") + trigger := parts[len(parts)-1] + flag.Parse() + + var err error + switch trigger { + case "pre-delete": + appName := flag.Arg(0) + err = repo.PurgeCache(appName) + default: + common.LogFail(fmt.Sprintf("Invalid plugin trigger call: %s", trigger)) + } + + if err != nil { + common.LogFail(err.Error()) + } +} diff --git a/plugins/repo/src/subcommands/gc/gc.go b/plugins/repo/subcommands.go similarity index 52% rename from plugins/repo/src/subcommands/gc/gc.go rename to plugins/repo/subcommands.go index 1edcc741a..238c0b8fc 100644 --- a/plugins/repo/src/subcommands/gc/gc.go +++ b/plugins/repo/subcommands.go @@ -1,22 +1,20 @@ -package main +package repo import ( - "flag" + "errors" "strings" "github.com/dokku/dokku/plugins/common" ) -// runs 'git gc --aggressive' against the application's repo -func main() { - flag.Parse() - appName := flag.Arg(1) +// CommandGc runs 'git gc --aggressive' against the application's repo +func CommandGc(appName string) error { if appName == "" { - common.LogFail("Please specify an app to run the command on") + return errors.New("Please specify an app to run the command on") } err := common.VerifyAppName(appName) if err != nil { - common.LogFail(err.Error()) + return err } appRoot := strings.Join([]string{common.MustGetEnv("DOKKU_ROOT"), appName}, "/") @@ -26,4 +24,14 @@ func main() { gitGcCmd := common.NewShellCmd("git gc --aggressive") gitGcCmd.Env = cmdEnv gitGcCmd.Execute() + return nil +} + +// CommandPurgeCache deletes the contents of the build cache stored in the repository +func CommandPurgeCache(appName string) error { + if appName == "" { + common.LogFail("Please specify an app to run the command on") + } + + return PurgeCache(appName) } diff --git a/plugins/resource/.gitignore b/plugins/resource/.gitignore index bdb6a1395..a34683d35 100644 --- a/plugins/resource/.gitignore +++ b/plugins/resource/.gitignore @@ -1,6 +1,7 @@ /commands /subcommands/* /triggers/* +/triggers /install /post-delete /report diff --git a/plugins/resource/Makefile b/plugins/resource/Makefile index 3a2bf7315..ea16485f9 100644 --- a/plugins/resource/Makefile +++ b/plugins/resource/Makefile @@ -1,38 +1,6 @@ -include ../../common.mk - -GO_ARGS ?= -a - SUBCOMMANDS = subcommands/limit subcommands/limit-clear subcommands/report subcommands/reserve subcommands/reserve-clear TRIGGERS = triggers/docker-args-process-deploy triggers/install triggers/post-delete triggers/report triggers/resource-get-property -build-in-docker: clean - docker run --rm \ - -v $$PWD/../..:$(GO_REPO_ROOT) \ - -w $(GO_REPO_ROOT)/plugins/resource \ - $(BUILD_IMAGE) \ - bash -c "GO_ARGS='$(GO_ARGS)' make -j4 build" || exit $$? +BUILD = commands subcommands triggers +PLUGIN_NAME = resource -build: commands subcommands triggers - $(MAKE) triggers-copy - -commands: **/**/commands.go - go build $(GO_ARGS) -o commands src/commands/commands.go - -subcommands: $(SUBCOMMANDS) - -subcommands/%: src/subcommands/*/%.go - go build $(GO_ARGS) -o $@ $< - -clean: - rm -rf commands subcommands triggers docker-args-process-deploy docker-args-process-run install post-delete report resource-get-property - -src-clean: - rm -rf .gitignore src triggers vendor Makefile *.go glide.* - -triggers: $(TRIGGERS) - -triggers/%: src/triggers/*/%.go - go build $(GO_ARGS) -o $@ $< - -triggers-copy: - cp triggers/* . - ln -sf docker-args-process-deploy docker-args-process-run +include ../../common.mk diff --git a/plugins/resource/src/subcommands/limit-clear/limit-clear.go b/plugins/resource/src/subcommands/limit-clear/limit-clear.go deleted file mode 100644 index b794dfc30..000000000 --- a/plugins/resource/src/subcommands/limit-clear/limit-clear.go +++ /dev/null @@ -1,20 +0,0 @@ -package main - -import ( - "flag" - "os" - - "github.com/dokku/dokku/plugins/common" - "github.com/dokku/dokku/plugins/resource" -) - -func main() { - args := flag.NewFlagSet("resource:limit-clear", flag.ExitOnError) - processType := args.String("process-type", "", "process-type: A process type to clear") - args.Parse(os.Args[2:]) - - err := resource.CommandLimitClear(args.Args(), *processType) - if err != nil { - common.LogFail(err.Error()) - } -} diff --git a/plugins/resource/src/subcommands/limit/limit.go b/plugins/resource/src/subcommands/limit/limit.go deleted file mode 100644 index d45438e3a..000000000 --- a/plugins/resource/src/subcommands/limit/limit.go +++ /dev/null @@ -1,35 +0,0 @@ -package main - -import ( - "flag" - "os" - - "github.com/dokku/dokku/plugins/common" - "github.com/dokku/dokku/plugins/resource" -) - -func main() { - args := flag.NewFlagSet("resource:limit", flag.ExitOnError) - processType := args.String("process-type", "", "process-type: A process type to manage") - cpu := args.String("cpu", "", "cpu: The amount of cpu to limit processes by") - memory := args.String("memory", "", "memory: The amount of memory to limit processes by") - memorySwap := args.String("memory-swap", "", "memory-swap: The amount of swap memory to limit processes by") - network := args.String("network", "", "network: The amount of network bandwidth to limit processes by") - networkIngress := args.String("network-ingress", "", "network-ingress: The amount of ingress network bandwidth to limit processes by") - networkEgress := args.String("network-egress", "", "network-egress: The amount of egress network bandwidth to limit processes by") - args.Parse(os.Args[2:]) - - resources := resource.Resource{ - CPU: *cpu, - Memory: *memory, - MemorySwap: *memorySwap, - Network: *network, - NetworkIngress: *networkIngress, - NetworkEgress: *networkEgress, - } - - err := resource.CommandLimit(args.Args(), *processType, resources) - if err != nil { - common.LogFail(err.Error()) - } -} diff --git a/plugins/resource/src/subcommands/report/report.go b/plugins/resource/src/subcommands/report/report.go deleted file mode 100644 index f8385c3bd..000000000 --- a/plugins/resource/src/subcommands/report/report.go +++ /dev/null @@ -1,33 +0,0 @@ -package main - -import ( - "flag" - "strings" - - "github.com/dokku/dokku/plugins/common" - "github.com/dokku/dokku/plugins/resource" -) - -// displays a resource report for one or more apps -func main() { - flag.Parse() - appName := flag.Arg(1) - infoFlag := flag.Arg(2) - - if strings.HasPrefix(appName, "--") { - common.LogFail("The resource:report command does not support flags without an app name") - } - - if len(appName) == 0 { - apps, err := common.DokkuApps() - if err != nil { - return - } - for _, appName := range apps { - resource.ReportSingleApp(appName, infoFlag) - } - return - } - - resource.ReportSingleApp(appName, infoFlag) -} diff --git a/plugins/resource/src/subcommands/reserve-clear/reserve-clear.go b/plugins/resource/src/subcommands/reserve-clear/reserve-clear.go deleted file mode 100644 index 4f882388d..000000000 --- a/plugins/resource/src/subcommands/reserve-clear/reserve-clear.go +++ /dev/null @@ -1,20 +0,0 @@ -package main - -import ( - "flag" - "os" - - "github.com/dokku/dokku/plugins/common" - "github.com/dokku/dokku/plugins/resource" -) - -func main() { - args := flag.NewFlagSet("resource:reserve-clear", flag.ExitOnError) - processType := args.String("process-type", "", "process-type: A process type to clear") - args.Parse(os.Args[2:]) - - err := resource.CommandReserveClear(args.Args(), *processType) - if err != nil { - common.LogFail(err.Error()) - } -} diff --git a/plugins/resource/src/subcommands/reserve/reserve.go b/plugins/resource/src/subcommands/reserve/reserve.go deleted file mode 100644 index afeccb551..000000000 --- a/plugins/resource/src/subcommands/reserve/reserve.go +++ /dev/null @@ -1,35 +0,0 @@ -package main - -import ( - "flag" - "os" - - "github.com/dokku/dokku/plugins/common" - "github.com/dokku/dokku/plugins/resource" -) - -func main() { - args := flag.NewFlagSet("resource:reserve", flag.ExitOnError) - processType := args.String("process-type", "", "process-type: A process type to manage") - cpu := args.String("cpu", "", "cpu: The amount of cpu to reserve for processes") - memory := args.String("memory", "", "memory: The amount of memory to reserve for processes") - memorySwap := args.String("memory-swap", "", "memory-swap: The amount of swap memory to reserve for processes") - network := args.String("network", "", "network: The amount of network bandwidth to reserve for processes") - networkIngress := args.String("network-ingress", "", "network-ingress: The amount of ingress network bandwidth to reserve for processes") - networkEgress := args.String("network-egress", "", "network-egress: The amount of egress network bandwidth to reserve for processes") - args.Parse(os.Args[2:]) - - resources := resource.Resource{ - CPU: *cpu, - Memory: *memory, - MemorySwap: *memorySwap, - Network: *network, - NetworkIngress: *networkIngress, - NetworkEgress: *networkEgress, - } - - err := resource.CommandReserve(args.Args(), *processType, resources) - if err != nil { - common.LogFail(err.Error()) - } -} diff --git a/plugins/resource/src/subcommands/subcommands.go b/plugins/resource/src/subcommands/subcommands.go new file mode 100644 index 000000000..c3b105fa9 --- /dev/null +++ b/plugins/resource/src/subcommands/subcommands.go @@ -0,0 +1,84 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + "github.com/dokku/dokku/plugins/common" + "github.com/dokku/dokku/plugins/resource" +) + +// main entrypoint to all subcommands +func main() { + parts := strings.Split(os.Args[0], "/") + subcommand := parts[len(parts)-1] + + var err error + switch subcommand { + case "limit": + args := flag.NewFlagSet("resource:limit", flag.ExitOnError) + processType := args.String("process-type", "", "process-type: A process type to manage") + cpu := args.String("cpu", "", "cpu: The amount of cpu to limit processes by") + memory := args.String("memory", "", "memory: The amount of memory to limit processes by") + memorySwap := args.String("memory-swap", "", "memory-swap: The amount of swap memory to limit processes by") + network := args.String("network", "", "network: The amount of network bandwidth to limit processes by") + networkIngress := args.String("network-ingress", "", "network-ingress: The amount of ingress network bandwidth to limit processes by") + networkEgress := args.String("network-egress", "", "network-egress: The amount of egress network bandwidth to limit processes by") + args.Parse(os.Args[2:]) + + resources := resource.Resource{ + CPU: *cpu, + Memory: *memory, + MemorySwap: *memorySwap, + Network: *network, + NetworkIngress: *networkIngress, + NetworkEgress: *networkEgress, + } + + err = resource.CommandLimit(args.Args(), *processType, resources) + case "limit-clear": + args := flag.NewFlagSet("resource:limit-clear", flag.ExitOnError) + processType := args.String("process-type", "", "process-type: A process type to clear") + args.Parse(os.Args[2:]) + err = resource.CommandLimitClear(args.Args(), *processType) + case "report": + flag.Parse() + appName := flag.Arg(1) + infoFlag := flag.Arg(2) + resource.CommandReport(appName, infoFlag) + case "reserve": + args := flag.NewFlagSet("resource:reserve", flag.ExitOnError) + processType := args.String("process-type", "", "process-type: A process type to manage") + cpu := args.String("cpu", "", "cpu: The amount of cpu to reserve for processes") + memory := args.String("memory", "", "memory: The amount of memory to reserve for processes") + memorySwap := args.String("memory-swap", "", "memory-swap: The amount of swap memory to reserve for processes") + network := args.String("network", "", "network: The amount of network bandwidth to reserve for processes") + networkIngress := args.String("network-ingress", "", "network-ingress: The amount of ingress network bandwidth to reserve for processes") + networkEgress := args.String("network-egress", "", "network-egress: The amount of egress network bandwidth to reserve for processes") + args.Parse(os.Args[2:]) + + resources := resource.Resource{ + CPU: *cpu, + Memory: *memory, + MemorySwap: *memorySwap, + Network: *network, + NetworkIngress: *networkIngress, + NetworkEgress: *networkEgress, + } + + err = resource.CommandReserve(args.Args(), *processType, resources) + case "reserve-clear": + args := flag.NewFlagSet("resource:reserve-clear", flag.ExitOnError) + processType := args.String("process-type", "", "process-type: A process type to clear") + args.Parse(os.Args[2:]) + err = resource.CommandReserveClear(args.Args(), *processType) + default: + common.LogFail(fmt.Sprintf("Invalid plugin subcommand call: %s", subcommand)) + } + + if err != nil { + common.LogFail(err.Error()) + } +} diff --git a/plugins/resource/src/triggers/install/install.go b/plugins/resource/src/triggers/install/install.go deleted file mode 100644 index 77f7d14ed..000000000 --- a/plugins/resource/src/triggers/install/install.go +++ /dev/null @@ -1,14 +0,0 @@ -package main - -import ( - "fmt" - - "github.com/dokku/dokku/plugins/common" -) - -// runs the install step for the resource plugin -func main() { - if err := common.PropertySetup("resource"); err != nil { - common.LogFail(fmt.Sprintf("Unable to install the resource plugin: %s", err.Error())) - } -} diff --git a/plugins/resource/src/triggers/post-delete/post-delete.go b/plugins/resource/src/triggers/post-delete/post-delete.go deleted file mode 100644 index d22ceccea..000000000 --- a/plugins/resource/src/triggers/post-delete/post-delete.go +++ /dev/null @@ -1,18 +0,0 @@ -package main - -import ( - "flag" - - "github.com/dokku/dokku/plugins/common" -) - -// destroys the resource property for a given app container -func main() { - flag.Parse() - appName := flag.Arg(0) - - err := common.PropertyDestroy("resource", appName) - if err != nil { - common.LogFail(err.Error()) - } -} diff --git a/plugins/resource/src/triggers/report/report.go b/plugins/resource/src/triggers/report/report.go deleted file mode 100644 index b34ad49e0..000000000 --- a/plugins/resource/src/triggers/report/report.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - "flag" - - "github.com/dokku/dokku/plugins/resource" -) - -// displays a resource report for one or more apps -func main() { - flag.Parse() - appName := flag.Arg(0) - - resource.ReportSingleApp(appName, "") -} diff --git a/plugins/resource/src/triggers/resource-get-property/resource-get-property.go b/plugins/resource/src/triggers/resource-get-property/resource-get-property.go deleted file mode 100644 index cacd856d9..000000000 --- a/plugins/resource/src/triggers/resource-get-property/resource-get-property.go +++ /dev/null @@ -1,26 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "os" - - "github.com/dokku/dokku/plugins/common" - "github.com/dokku/dokku/plugins/resource" -) - -// writes the resource key to stdout for a given app container -func main() { - flag.Parse() - appName := flag.Arg(0) - processType := flag.Arg(1) - resourceType := flag.Arg(2) - key := flag.Arg(3) - - value, err := resource.GetResourceValue(appName, processType, resourceType, key) - if err != nil { - common.LogFail(err.Error()) - } - - fmt.Fprintln(os.Stdout, value) -} diff --git a/plugins/resource/src/triggers/triggers.go b/plugins/resource/src/triggers/triggers.go new file mode 100644 index 000000000..2bdf6d362 --- /dev/null +++ b/plugins/resource/src/triggers/triggers.go @@ -0,0 +1,46 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + "github.com/dokku/dokku/plugins/common" + "github.com/dokku/dokku/plugins/resource" +) + +// main entrypoint to all triggers +func main() { + parts := strings.Split(os.Args[0], "/") + trigger := parts[len(parts)-1] + flag.Parse() + + var err error + switch trigger { + case "docker-args-process-deploy": + appName := flag.Arg(0) + processType := flag.Arg(3) + err = resource.TriggerDockerArgsProcessDeploy(appName, processType) + case "install": + err = resource.TriggerInstall() + case "post-delete": + appName := flag.Arg(0) + err = resource.TriggerPostDelete(appName) + case "report": + appName := flag.Arg(0) + resource.ReportSingleApp(appName, "") + case "resource-get-property": + appName := flag.Arg(0) + processType := flag.Arg(1) + resourceType := flag.Arg(2) + key := flag.Arg(3) + err = resource.TriggerResourceGetProperty(appName, processType, resourceType, key) + default: + common.LogFail(fmt.Sprintf("Invalid plugin trigger call: %s", trigger)) + } + + if err != nil { + common.LogFail(err.Error()) + } +} diff --git a/plugins/resource/subcommands.go b/plugins/resource/subcommands.go index b607a4609..e705d3016 100644 --- a/plugins/resource/subcommands.go +++ b/plugins/resource/subcommands.go @@ -2,6 +2,8 @@ package resource import ( "fmt" + "strings" + "github.com/dokku/dokku/plugins/common" ) @@ -26,6 +28,27 @@ func CommandLimitClear(args []string, processType string) error { return nil } +// CommandReport displays a resource report for one or more apps +func CommandReport(appName string, infoFlag string) { + if strings.HasPrefix(appName, "--") { + infoFlag = appName + appName = "" + } + + if len(appName) == 0 { + apps, err := common.DokkuApps() + if err != nil { + return + } + for _, appName := range apps { + ReportSingleApp(appName, infoFlag) + } + return + } + + ReportSingleApp(appName, infoFlag) +} + // CommandReserve implements resource:reserve func CommandReserve(args []string, processType string, r Resource) error { appName, err := getAppName(args) diff --git a/plugins/resource/src/triggers/docker-args-process-deploy/docker-args-process-deploy.go b/plugins/resource/triggers.go similarity index 59% rename from plugins/resource/src/triggers/docker-args-process-deploy/docker-args-process-deploy.go rename to plugins/resource/triggers.go index c8f8da8f9..e8e7027f6 100644 --- a/plugins/resource/src/triggers/docker-args-process-deploy/docker-args-process-deploy.go +++ b/plugins/resource/triggers.go @@ -1,7 +1,7 @@ -package main +package resource import ( - "flag" + "errors" "fmt" "io/ioutil" "os" @@ -10,26 +10,22 @@ import ( "github.com/dokku/dokku/plugins/common" ) -// outputs the process-specific docker options -func main() { +// TriggerDockerArgsProcessDeploy outputs the process-specific docker options +func TriggerDockerArgsProcessDeploy(appName string, processType string) error { stdin, err := ioutil.ReadAll(os.Stdin) if err != nil { - common.LogFail(err.Error()) + return err } - flag.Parse() - appName := flag.Arg(0) - processType := flag.Arg(3) - if os.Getenv("DOKKU_OMIT_RESOURCE_ARGS") == "1" { fmt.Print(string(stdin)) - return + return nil } resources, err := common.PropertyGetAll("resource", appName) if err != nil { fmt.Print(string(stdin)) - return + return nil } limits := make(map[string]string) @@ -86,4 +82,29 @@ func main() { } fmt.Print(string(stdin)) + return nil +} + +// TriggerInstall runs the install step for the resource plugin +func TriggerInstall() error { + if err := common.PropertySetup("resource"); err != nil { + return errors.New(fmt.Sprintf("Unable to install the resource plugin: %s", err.Error())) + } + return nil +} + +// TriggerPostDelete destroys the resource property for a given app container +func TriggerPostDelete(appName string) error { + return common.PropertyDestroy("resource", appName) +} + +// writes the resource key to stdout for a given app container +func TriggerResourceGetProperty(appName string, processType string, resourceType string, key string) error { + value, err := GetResourceValue(appName, processType, resourceType, key) + if err != nil { + return err + } + + fmt.Fprintln(os.Stdout, value) + return nil } From ccbe0b087728228a4e97df9e70f6202108150562 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 15 Sep 2019 16:20:19 -0400 Subject: [PATCH 14/39] fix: correct bash-completion comment --- contrib/bash-completion | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/bash-completion b/contrib/bash-completion index 8923244f1..ca4b0b09a 100644 --- a/contrib/bash-completion +++ b/contrib/bash-completion @@ -1,4 +1,4 @@ -# bash completion for dd -*- shell-script -*- +# bash completion for dokku -*- shell-script -*- _dokku_complete_verify() { declare desc="shows bash completion" From 68de42163091569ec334b1fc1b70bc8b73d75e85 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 15 Sep 2019 16:25:40 -0400 Subject: [PATCH 15/39] fix: correct lintian overrides --- debian/lintian-overrides | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/lintian-overrides b/debian/lintian-overrides index 52a34c0e4..b659deeeb 100644 --- a/debian/lintian-overrides +++ b/debian/lintian-overrides @@ -1,5 +1,5 @@ -dokku: command-with-path-in-maintainer-script postinst:16 /usr/bin/sshcommand -dokku: maintainer-script-calls-systemctl postinst:87 +dokku: command-with-path-in-maintainer-script postinst:22 /usr/bin/sshcommand +dokku: maintainer-script-calls-systemctl postinst:98 dokku: changelog-file-missing-in-native-package dokku: statically-linked-binary dokku: unstripped-binary-or-object From 76911a7dc892620339b178af1454ec760978e848 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 15 Sep 2019 16:26:06 -0400 Subject: [PATCH 16/39] fix: drop executable perm on trace/plugin.toml --- plugins/trace/plugin.toml | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 plugins/trace/plugin.toml diff --git a/plugins/trace/plugin.toml b/plugins/trace/plugin.toml old mode 100755 new mode 100644 From 78dba3be3cb19abe7853bbe9002f7572afc9cbca Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 15 Sep 2019 17:20:49 -0400 Subject: [PATCH 17/39] fix: correct comments on go functions --- plugins/buildpacks/triggers.go | 6 +++--- plugins/network/subcommands.go | 6 +++--- plugins/network/triggers.go | 24 ++++++++++++------------ plugins/resource/triggers.go | 2 +- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/plugins/buildpacks/triggers.go b/plugins/buildpacks/triggers.go index 50f95da98..d06e387e4 100644 --- a/plugins/buildpacks/triggers.go +++ b/plugins/buildpacks/triggers.go @@ -9,14 +9,14 @@ import ( "github.com/dokku/dokku/plugins/common" ) -// runs the install step for the buildpacks plugin +// TriggerInstall runs the install step for the buildpacks plugin func TriggerInstall() { if err := common.PropertySetup("buildpacks"); err != nil { common.LogFail(fmt.Sprintf("Unable to install the buildpacks plugin: %s", err.Error())) } } -// destroys the buildpacks property for a given app container +// TriggerPostDelete destroys the buildpacks property for a given app container func TriggerPostDelete(appName string) { err := common.PropertyDestroy("buildpacks", appName) if err != nil { @@ -24,7 +24,7 @@ func TriggerPostDelete(appName string) { } } -// writes a .buildpacks file into the app +// TriggerPostExtract writes a .buildpacks file into the app func TriggerPostExtract(appName string, sourceWorkDir string) { buildpacks, err := common.PropertyListGet("buildpacks", appName, "buildpacks") if err != nil { diff --git a/plugins/network/subcommands.go b/plugins/network/subcommands.go index 74449c6f6..3e5cdc7d2 100644 --- a/plugins/network/subcommands.go +++ b/plugins/network/subcommands.go @@ -6,7 +6,7 @@ import ( "github.com/dokku/dokku/plugins/common" ) -// rebuilds network settings for all apps +// CommandRebuildall rebuilds network settings for all apps func CommandRebuildall() { apps, err := common.DokkuApps() if err != nil { @@ -17,7 +17,7 @@ func CommandRebuildall() { } } -// displays a network report for one or more apps +// CommandReport displays a network report for one or more apps func CommandReport(appName string, infoFlag string) { if strings.HasPrefix(appName, "--") { infoFlag = appName @@ -38,7 +38,7 @@ func CommandReport(appName string, infoFlag string) { ReportSingleApp(appName, infoFlag) } -// set or clear a network property for an app +// CommandSet set or clear a network property for an app func CommandSet(appName string, property string, value string) { if property == "bind-all-interfaces" && value == "" { value = "false" diff --git a/plugins/network/triggers.go b/plugins/network/triggers.go index 46796b50e..22f8f3956 100644 --- a/plugins/network/triggers.go +++ b/plugins/network/triggers.go @@ -11,7 +11,7 @@ import ( "github.com/dokku/dokku/plugins/proxy" ) -// runs the install step for the network plugin +// TriggerInstall runs the install step for the network plugin func TriggerInstall() { if err := common.PropertySetup("network"); err != nil { common.LogFail(fmt.Sprintf("Unable to install the network plugin: %s", err.Error())) @@ -39,7 +39,7 @@ func TriggerInstall() { } } -// computes the ports for a given app container +// TriggerNetworkComputePorts computes the ports for a given app container func TriggerNetworkComputePorts(appName string, processType string, isHerokuishContainer bool) { if processType != "web" { return @@ -68,7 +68,7 @@ func TriggerNetworkComputePorts(appName string, processType string, isHerokuishC fmt.Fprint(os.Stdout, strings.Join(ports, " ")) } -// writes true or false to stdout whether a given app has network config +// TriggerNetworkConfigExists writes true or false to stdout whether a given app has network config func TriggerNetworkConfigExists(appName string) { if HasNetworkConfig(appName) { fmt.Fprintln(os.Stdout, "true") @@ -78,32 +78,32 @@ func TriggerNetworkConfigExists(appName string) { fmt.Fprintln(os.Stdout, "false") } -// write the ipaddress to stdout for a given app container +// TriggerNetworkGetIppaddr writes the ipaddress to stdout for a given app container func TriggerNetworkGetIppaddr(appName string, processType string, containerID string) { ipAddress := GetContainerIpaddress(appName, processType, containerID) fmt.Fprintln(os.Stdout, ipAddress) } -// returns the listeners (host:port combinations) for a given app container +// TriggerNetworkGetListeners returns the listeners (host:port combinations) for a given app container func TriggerNetworkGetListeners(appName string) { listeners := GetListeners(appName) fmt.Fprint(os.Stdout, strings.Join(listeners, " ")) } -// write the port to stdout for a given app container +// TriggerNetworkGetPort writes the port to stdout for a given app container func TriggerNetworkGetPort(appName string, processType string, isHerokuishContainer bool, containerID string) { port := GetContainerPort(appName, processType, isHerokuishContainer, containerID) fmt.Fprintln(os.Stdout, port) } -// writes the network property to stdout for a given app container +// TriggerNetworkGetProperty writes the network property to stdout for a given app container func TriggerNetworkGetProperty(appName string, property string) { defaultValue := GetDefaultValue(property) value := common.PropertyGetDefault("network", appName, property, defaultValue) fmt.Fprintln(os.Stdout, value) } -// writes the ip to disk +// TriggerNetworkWriteIpaddr writes the ip to disk func TriggerNetworkWriteIpaddr(appName string, processType string, containerIndex string, ip string) { if appName == "" { common.LogFail("Please specify an app to run the command on") @@ -128,7 +128,7 @@ func TriggerNetworkWriteIpaddr(appName string, processType string, containerInde } } -// writes the port to disk +// TriggerNetworkWritePort writes the port to disk func TriggerNetworkWritePort(appName string, processType string, containerIndex string, port string) { if appName == "" { common.LogFail("Please specify an app to run the command on") @@ -153,7 +153,7 @@ func TriggerNetworkWritePort(appName string, processType string, containerIndex } } -// cleanup network files for a new app clone +// TriggerPostAppCloneSetup cleans up network files for a new app clone func TriggerPostAppCloneSetup(appName string) { success := PostAppCloneSetup(appName) if !success { @@ -161,7 +161,7 @@ func TriggerPostAppCloneSetup(appName string) { } } -// set bind-all-interfaces to false by default +// TriggerPostCreate sets bind-all-interfaces to false by default func TriggerPostCreate(appName string) { err := common.PropertyWrite("network", appName, "bind-all-interfaces", "false") if err != nil { @@ -169,7 +169,7 @@ func TriggerPostCreate(appName string) { } } -// destroys the network property for a given app container +// TriggerPostDelete destroys the network property for a given app container func TriggerPostDelete(appName string) { err := common.PropertyDestroy("network", appName) if err != nil { diff --git a/plugins/resource/triggers.go b/plugins/resource/triggers.go index e8e7027f6..530f5a1a0 100644 --- a/plugins/resource/triggers.go +++ b/plugins/resource/triggers.go @@ -98,7 +98,7 @@ func TriggerPostDelete(appName string) error { return common.PropertyDestroy("resource", appName) } -// writes the resource key to stdout for a given app container +// TriggerResourceGetProperty writes the resource key to stdout for a given app container func TriggerResourceGetProperty(appName string, processType string, resourceType string, key string) error { value, err := GetResourceValue(appName, processType, resourceType, key) if err != nil { From 8662f4550fcd738b8d300f3a628f60e697a5f666 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 15 Sep 2019 18:09:26 -0400 Subject: [PATCH 18/39] fix: Should replace errors.New(fmt.Sprintf(...)) with fmt.Errorf(...) --- plugins/resource/triggers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/resource/triggers.go b/plugins/resource/triggers.go index 530f5a1a0..caf7aca4d 100644 --- a/plugins/resource/triggers.go +++ b/plugins/resource/triggers.go @@ -88,7 +88,7 @@ func TriggerDockerArgsProcessDeploy(appName string, processType string) error { // TriggerInstall runs the install step for the resource plugin func TriggerInstall() error { if err := common.PropertySetup("resource"); err != nil { - return errors.New(fmt.Sprintf("Unable to install the resource plugin: %s", err.Error())) + return fmt.Errorf("Unable to install the resource plugin: %v", err) } return nil } From 6b6b1c2aa4175a964ac64746316e54edf1a9bdeb Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 15 Sep 2019 18:52:15 -0400 Subject: [PATCH 19/39] fix: drop pre-delete link --- plugins/repo/.gitignore | 1 + plugins/repo/pre-delete | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 120000 plugins/repo/pre-delete diff --git a/plugins/repo/.gitignore b/plugins/repo/.gitignore index cc45caec7..2983228bd 100644 --- a/plugins/repo/.gitignore +++ b/plugins/repo/.gitignore @@ -2,3 +2,4 @@ /subcommands/* /triggers/* /triggers +/pre-delete diff --git a/plugins/repo/pre-delete b/plugins/repo/pre-delete deleted file mode 120000 index fa05d2b3e..000000000 --- a/plugins/repo/pre-delete +++ /dev/null @@ -1 +0,0 @@ -triggers \ No newline at end of file From 14838de344a74efdb4ee83352b5a1799884e798b Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 15 Sep 2019 19:06:38 -0400 Subject: [PATCH 20/39] feat: allow keeping the git directory during builds It may be desirable to keep the contents of the git directory for the build process. Certain build tools can extract extra information from the .git directory, and some workflows may require that the shipped artifact has the entire source code available locally for later usage. --- docs/deployment/methods/git.md | 25 +++++++++++++++++++++++++ plugins/git/functions | 5 ++++- plugins/git/internal-functions | 3 ++- plugins/git/subcommands/set | 4 ++-- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/docs/deployment/methods/git.md b/docs/deployment/methods/git.md index dd5e4d4bb..a13af5c15 100644 --- a/docs/deployment/methods/git.md +++ b/docs/deployment/methods/git.md @@ -76,3 +76,28 @@ This behavior can be disabled entirely on a per-app basis by setting the `rev-en # override for a specific app dokku git:set node-js-app rev-env-var "" ``` + +### Keeping the `.git` directory + +By default, Dokku will remove the contents of the `.git` before triggering a build for a given app. This is generally a safe default as shipping the entire source code history of your app in the deployed image artifact is unnecessary as it increases bloat and potentially can leak information if there are any security issues with your app code. + +To enable the `.git` directory, run the `git:set` command as follows: + +```shell +# on the Dokku host + +# keep the .git directory during builds +dokku git:set node-js-app keep-git-dir true +``` + +The default behavior is to delete this directory and it's contents. To revert to the default behavior, the `keep-git-dir` value can be set to either an empty string or `false`. + +```shell +# on the Dokku host + +# delete the .git directory during builds (default) +dokku git:set node-js-app keep-git-dir false + +# delete the .git directory during builds (default) +dokku git:set node-js-app keep-git-dir "" +``` diff --git a/plugins/git/functions b/plugins/git/functions index c980841aa..d1cf3ef62 100755 --- a/plugins/git/functions +++ b/plugins/git/functions @@ -67,7 +67,10 @@ git_build_app_repo() { fi suppress_output env -u GIT_QUARANTINE_PATH git submodule update --init --recursive - find . -name .git -prune -exec rm -rf {} \; >/dev/null + local DOKKU_KEEP_GIT_DIR="$(fn-plugin-property-get "git" "$APP" "keep-git-dir" "")" + if [[ "$DOKKU_KEEP_GIT_DIR" != "true" ]]; then + find . -name .git -prune -exec rm -rf {} \; >/dev/null + fi if use_git_worktree; then pushd "$DOKKU_ROOT/$APP" >/dev/null diff --git a/plugins/git/internal-functions b/plugins/git/internal-functions index 09e8d76d6..5f87ab0fd 100755 --- a/plugins/git/internal-functions +++ b/plugins/git/internal-functions @@ -35,9 +35,10 @@ cmd-git-report-single() { fi verify_app_name "$APP" local flag_map=( - "--git-rev-env-var: $(fn-plugin-property-get "git" "$APP" "rev-env-var" "GIT_REV")" "--git-deploy-branch: $(fn-plugin-property-get "git" "$APP" "deploy-branch" "master")" "--git-global-deploy-branch: $(fn-plugin-property-get "git" "--global" "deploy-branch" "master")" + "--git-keep-git-dir: $(fn-plugin-property-get "git" "$APP" "keep-git-dir" "false")" + "--git-rev-env-var: $(fn-plugin-property-get "git" "$APP" "rev-env-var" "GIT_REV")" ) if [[ -z "$INFO_FLAG" ]]; then diff --git a/plugins/git/subcommands/set b/plugins/git/subcommands/set index 127ff03ca..aa01be113 100755 --- a/plugins/git/subcommands/set +++ b/plugins/git/subcommands/set @@ -19,12 +19,12 @@ git-set-cmd() { local cmd="git:set" argv=("$@") [[ ${argv[0]} == "$cmd" ]] && shift 1 declare APP="$1" KEY="$2" VALUE="$3" - local VALID_KEYS=("deploy-branch" "rev-env-var") + local VALID_KEYS=("deploy-branch" "keep-git-dir" "rev-env-var") [[ -z "$APP" ]] && dokku_log_fail "Please specify an app to run the command on" [[ -z "$KEY" ]] && dokku_log_fail "No key specified" if ! fn-in-array "$KEY" "${VALID_KEYS[@]}"; then - dokku_log_fail "Invalid key specified, valid keys include: deploy-branch, rev-env-var" + dokku_log_fail "Invalid key specified, valid keys include: deploy-branch, keep-git-dir, rev-env-var" fi if [[ -n "$VALUE" ]]; then From a4ac67a1e0c530bc9e9c4f9268fd9cec9e492c64 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 15 Sep 2019 19:43:34 -0400 Subject: [PATCH 21/39] fix: drop unused import --- plugins/resource/triggers.go | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/resource/triggers.go b/plugins/resource/triggers.go index caf7aca4d..4b9469a79 100644 --- a/plugins/resource/triggers.go +++ b/plugins/resource/triggers.go @@ -1,7 +1,6 @@ package resource import ( - "errors" "fmt" "io/ioutil" "os" From 5f80cd3c2048dd5f9262cbf1303543998985755a Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 15 Sep 2019 22:24:37 -0400 Subject: [PATCH 22/39] feat: follow updated intermediate recommendations from the Mozilla SSL Config Generator --- plugins/nginx-vhosts/install | 4 ++-- plugins/nginx-vhosts/templates/nginx.conf.sigil | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/nginx-vhosts/install b/plugins/nginx-vhosts/install index c4759671d..02cdc8c25 100755 --- a/plugins/nginx-vhosts/install +++ b/plugins/nginx-vhosts/install @@ -43,9 +43,9 @@ include $DOKKU_ROOT/*/nginx.conf; server_tokens off; # Settings from https://mozilla.github.io/server-side-tls/ssl-config-generator/ -ssl_session_cache shared:SSL:20m; +ssl_session_cache shared:SSL:20m; ssl_session_timeout 1d; -ssl_session_tickets on; +ssl_session_tickets off; ssl_dhparam /etc/nginx/dhparam.pem; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; diff --git a/plugins/nginx-vhosts/templates/nginx.conf.sigil b/plugins/nginx-vhosts/templates/nginx.conf.sigil index 3d1557cf4..04db4383c 100644 --- a/plugins/nginx-vhosts/templates/nginx.conf.sigil +++ b/plugins/nginx-vhosts/templates/nginx.conf.sigil @@ -63,10 +63,10 @@ server { access_log /var/log/nginx/{{ $.APP }}-access.log; error_log /var/log/nginx/{{ $.APP }}-error.log; - ssl_certificate {{ $.APP_SSL_PATH }}/server.crt; - ssl_certificate_key {{ $.APP_SSL_PATH }}/server.key; - ssl_protocols TLSv1.2; - ssl_prefer_server_ciphers on; + ssl_certificate {{ $.APP_SSL_PATH }}/server.crt; + ssl_certificate_key {{ $.APP_SSL_PATH }}/server.key; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers off; keepalive_timeout 70; {{ if and (eq $.SPDY_SUPPORTED "true") (ne $.HTTP2_SUPPORTED "true") }}add_header Alternate-Protocol {{ $.PROXY_SSL_PORT }}:npn-spdy/2;{{ end }} @@ -140,10 +140,10 @@ server { access_log /var/log/nginx/{{ $.APP }}-access.log; error_log /var/log/nginx/{{ $.APP }}-error.log; - ssl_certificate {{ $.APP_SSL_PATH }}/server.crt; - ssl_certificate_key {{ $.APP_SSL_PATH }}/server.key; - ssl_protocols TLSv1.2; - ssl_prefer_server_ciphers on; + ssl_certificate {{ $.APP_SSL_PATH }}/server.crt; + ssl_certificate_key {{ $.APP_SSL_PATH }}/server.key; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers off; location / { grpc_pass grpc://{{ $.APP }}-{{ $upstream_port }}; From 692bfa7cde240d44758dc387a16577dbd8ac9733 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 16 Sep 2019 03:00:11 -0400 Subject: [PATCH 23/39] feat: speed up docker image build by copying tmp dhparam file into place --- Dockerfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Dockerfile b/Dockerfile index 3dc52667a..916e23002 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,12 +15,15 @@ COPY ./build/dokku.deb /tmp/dokku.deb RUN addgroup --gid $DOKKU_GID dokku \ && adduser --uid $DOKKU_UID --gid $DOKKU_GID --disabled-password --gecos "" "dokku" +COPY ./tests/dhparam.pem /tmp/dhparam.pem RUN echo "dokku dokku/hostname string $DOKKU_HOSTNAME" | debconf-set-selections \ && echo "dokku dokku/skip_key_file boolean $DOKKU_SKIP_KEY_FILE" | debconf-set-selections \ && echo "dokku dokku/vhost_enable boolean $DOKKU_VHOST_ENABLE" | debconf-set-selections \ && echo "dokku dokku/web_config boolean $DOKKU_WEB_CONFIG" | debconf-set-selections \ && curl -sSL https://packagecloud.io/dokku/dokku/gpgkey | apt-key add - \ && echo "deb https://packagecloud.io/dokku/dokku/ubuntu/ bionic main" | tee /etc/apt/sources.list.d/dokku.list \ + && mkdir -p /etc/nginx/ \ + && cp /tmp/dhparam.pem /etc/nginx/dhparam.pem \ && apt-get update -qq \ && apt-get install --no-install-recommends --only-upgrade -y -qq openssl openssh-server \ && apt --no-install-recommends -qq -y install rsync /tmp/dokku.deb \ From 43e7ee06fb53fee11eec47d07e7454bbfc65e0da Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 16 Sep 2019 03:00:34 -0400 Subject: [PATCH 24/39] feat: rework layer to slightly speed up builds --- Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 916e23002..5c29340f4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,12 +10,11 @@ ARG DOKKU_SKIP_KEY_FILE=true ARG DOKKU_VHOST_ENABLE=false ARG DOKKU_WEB_CONFIG=false -COPY ./build/dokku.deb /tmp/dokku.deb - RUN addgroup --gid $DOKKU_GID dokku \ && adduser --uid $DOKKU_UID --gid $DOKKU_GID --disabled-password --gecos "" "dokku" COPY ./tests/dhparam.pem /tmp/dhparam.pem +COPY ./build/dokku.deb /tmp/dokku.deb RUN echo "dokku dokku/hostname string $DOKKU_HOSTNAME" | debconf-set-selections \ && echo "dokku dokku/skip_key_file boolean $DOKKU_SKIP_KEY_FILE" | debconf-set-selections \ && echo "dokku dokku/vhost_enable boolean $DOKKU_VHOST_ENABLE" | debconf-set-selections \ From 0d1952592e05d29248c98952d60f9e470a0022ce Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 16 Sep 2019 03:01:34 -0400 Subject: [PATCH 25/39] chore: standardize arguments to apt --- Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5c29340f4..dfc5ca59d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,10 +24,10 @@ RUN echo "dokku dokku/hostname string $DOKKU_HOSTNAME" | debconf-set-selections && mkdir -p /etc/nginx/ \ && cp /tmp/dhparam.pem /etc/nginx/dhparam.pem \ && apt-get update -qq \ - && apt-get install --no-install-recommends --only-upgrade -y -qq openssl openssh-server \ - && apt --no-install-recommends -qq -y install rsync /tmp/dokku.deb \ - && apt-get purge -y -q syslog-ng-core \ - && apt-get autoremove -y -q \ + && apt-get install --no-install-recommends --only-upgrade -qq -y openssl openssh-server \ + && apt install --no-install-recommends -qq -y rsync /tmp/dokku.deb \ + && apt-get purge -qq -y syslog-ng-core \ + && apt-get autoremove -qq -y \ && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* WORKDIR /tmp From ea9cf024d52eb39cae79024ad30015a4c637e5c5 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 16 Sep 2019 03:01:46 -0400 Subject: [PATCH 26/39] feat: always upgrade packages before further installation --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index dfc5ca59d..9cc5ac180 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,6 +24,7 @@ RUN echo "dokku dokku/hostname string $DOKKU_HOSTNAME" | debconf-set-selections && mkdir -p /etc/nginx/ \ && cp /tmp/dhparam.pem /etc/nginx/dhparam.pem \ && apt-get update -qq \ + && apt-get upgrade -qq -y \ && apt-get install --no-install-recommends --only-upgrade -qq -y openssl openssh-server \ && apt install --no-install-recommends -qq -y rsync /tmp/dokku.deb \ && apt-get purge -qq -y syslog-ng-core \ From 0e219b05e9c0b4214dd44bca1651fc728c101577 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 16 Sep 2019 03:02:01 -0400 Subject: [PATCH 27/39] fest: handle both openresty and nginx in docker image builds --- Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9cc5ac180..c87e78ae0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -50,6 +50,7 @@ RUN \ && ln -sf /mnt/dokku/var/lib/dokku/config /var/lib/dokku/config \ && ln -sf /mnt/dokku/var/lib/dokku/data /var/lib/dokku/data \ && mv /etc/my_init.d/00_regen_ssh_host_keys.sh /etc/my_init.d/15_regen_ssh_host_keys \ - && rm /etc/nginx/sites-enabled/default /usr/share/nginx/html/index.html /etc/my_init.d/10_syslog-ng.init \ + && rm -f /etc/nginx/sites-enabled/default /usr/share/nginx/html/index.html /etc/my_init.d/10_syslog-ng.init \ + && rm -f /usr/local/openresty/nginx/conf/sites-enabled/default /usr/share/openresty/html/index.html \ && sed -i '/imklog/d' /etc/rsyslog.conf \ - && rm /var/log/btmp /var/log/wtmp /var/log/*log /var/log/apt/* /var/log/dokku/* /var/log/nginx/* + && rm -f /var/log/btmp /var/log/wtmp /var/log/*log /var/log/apt/* /var/log/dokku/* /var/log/nginx/* /var/log/openresty/* From a9ce738f685ce81515fb0f7f506a4db75faa6e25 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 16 Sep 2019 03:03:20 -0400 Subject: [PATCH 28/39] feat: add openresty and runit support to packaging Our docker image uses runit instead of init/systemd, hence the added sv support on Ubuntu operating systems. --- contrib/dokku-installer.py | 17 +++++++-- debian/postinst | 5 ++- debian/postrm | 2 ++ debian/preinst | 74 ++++++++++++++++++++++---------------- 4 files changed, 63 insertions(+), 35 deletions(-) diff --git a/contrib/dokku-installer.py b/contrib/dokku-installer.py index e7e27f784..741ce51d3 100755 --- a/contrib/dokku-installer.py +++ b/contrib/dokku-installer.py @@ -47,12 +47,23 @@ except subprocess.CalledProcessError: ufw_display = 'none' +nginx_dir = '/etc/nginx' +nginx_init = '/etc/init.d/nginx' +try: + command = "test -x /usr/bin/openresty" + subprocess.check_output(command, shell=True).strip() + nginx_dir = '/usr/local/openresty/nginx/conf' + nginx_init = '/etc/init.d/openresty' +except subprocess.CalledProcessError: + pass + + def check_boot(): if 'onboot' not in sys.argv: return init_dir = os.getenv('INIT_DIR', '/etc/init') systemd_dir = os.getenv('SYSTEMD_DIR', '/etc/systemd/system') - nginx_dir = os.getenv('NGINX_DIR', '/etc/nginx/conf.d') + nginx_conf_dir = os.getenv('NGINX_CONF_DIR', '{0}/conf.d'.format(nginx_dir)) if os.path.exists(init_dir): with open('{0}/dokku-installer.conf'.format(init_dir), 'w') as f: @@ -79,7 +90,7 @@ def check_boot(): f.write(" }\n") f.write("}\n") - subprocess.call('rm -f /etc/nginx/sites-enabled/*', shell=True) + subprocess.call('rm -f {0}/sites-enabled/*'.format(nginx_dir), shell=True) sys.exit(0) @@ -203,7 +214,7 @@ class DeleteInstallerThread(object): thread.start() def run(self): - command = "rm /etc/nginx/conf.d/dokku-installer.conf && /etc/init.d/nginx stop && /etc/init.d/nginx start" + command = "rm {0}/conf.d/dokku-installer.conf && {1} stop && {1} start".format(nginx_dir, nginx_init) try: subprocess.call(command, shell=True) except: diff --git a/debian/postinst b/debian/postinst index 43c659402..de453d037 100755 --- a/debian/postinst +++ b/debian/postinst @@ -89,7 +89,10 @@ setup-sshcommand() { } setup-dokku-installer() { - if [[ -f /etc/nginx/conf.d/dokku-installer.conf ]]; then + NGINX_ROOT="/etc/nginx" + [[ -x /usr/bin/openresty ]] && NGINX_ROOT="/usr/local/openresty/nginx/conf" + + if [[ -f "$NGINX_ROOT/conf.d/dokku-installer.conf" ]]; then echo "Setting up dokku-installer" /usr/share/dokku/contrib/dokku-installer.py onboot diff --git a/debian/postrm b/debian/postrm index b37c0578d..f58c4869a 100755 --- a/debian/postrm +++ b/debian/postrm @@ -28,6 +28,8 @@ main() { fi if [[ "$1" == "purge" ]]; then + rm -f /usr/local/openresty/nginx/conf/conf.d/dokku.conf + 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 diff --git a/debian/preinst b/debian/preinst index c9a055344..3baaba9aa 100755 --- a/debian/preinst +++ b/debian/preinst @@ -7,41 +7,53 @@ if [[ -e /usr/share/debconf/confmodule ]]; then . /usr/share/debconf/confmodule fi +setup_dokku_installer() { + NGINX_BASE_PATH="$1" + NGINX_INIT_NAME="$2" + + NGINX_CONF="${NGINX_BASE_PATH}/conf.d/dokku-installer.conf" + + rm -f $NGINX_CONF + touch $NGINX_CONF + + { + echo 'upstream dokku-installer { server 127.0.0.1:2000; }' + echo 'server {' + echo ' listen 80;' + echo ' location / {' + echo ' proxy_pass http://dokku-installer;' + echo ' }' + echo '}' + } >>$NGINX_CONF + + rm -f $NGINX_BASE_PATH/sites-enabled/* + DOKKU_DISTRO="$( + . /etc/os-release >/dev/null 2>&1 || true + echo "$ID" + )" + case "$DOKKU_DISTRO" in + debian) + /usr/sbin/invoke-rc.d "$NGINX_INIT_NAME" reload || /usr/sbin/invoke-rc.d "$NGINX_INIT_NAME" start + ;; + ubuntu) + if [[ -x /usr/bin/sv ]]; then + /usr/bin/sv reload "$NGINX_INIT_NAME" || /usr/bin/sv start "$NGINX_INIT_NAME" + else + "/etc/init.d/$NGINX_INIT_NAME" reload || "/etc/init.d/$NGINX_INIT_NAME" start + fi + ;; + esac +} + case "$1" in install) db_get "dokku/web_config" if [ "$RET" = "true" ]; then - NGINX_CONF="/etc/nginx/conf.d/dokku-installer.conf" - - rm -f $NGINX_CONF - touch $NGINX_CONF - - { - echo 'upstream dokku-installer { server 127.0.0.1:2000; }' - echo 'server {' - echo ' listen 80;' - echo ' location / {' - echo ' proxy_pass http://dokku-installer;' - echo ' }' - echo '}' - } >>$NGINX_CONF - - rm -f /etc/nginx/sites-enabled/* - DOKKU_DISTRO="$( - . /etc/os-release >/dev/null 2>&1 || true - echo "$ID" - )" - case "$DOKKU_DISTRO" in - debian) - NGINX_INIT="/usr/sbin/invoke-rc.d" - "$NGINX_INIT" nginx reload || "$NGINX_INIT" nginx start - ;; - ubuntu) - NGINX_INIT="/etc/init.d/nginx" - "$NGINX_INIT" reload || "$NGINX_INIT" start - ;; - esac - exit 0 + if [[ -x /usr/bin/openresty ]]; then + setup_dokku_installer "/usr/local/openresty/nginx/conf" "openresty" + else + setup_dokku_installer "/etc/nginx" "nginx" + fi fi db_get "dokku/skip_key_file" From dd2bbc7722126991cfba8d07abfdc0810650b676 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 16 Sep 2019 03:04:42 -0400 Subject: [PATCH 29/39] fix: allow test dhparam.pem to be copied into docker image --- .dockerignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.dockerignore b/.dockerignore index 977ed7878..29683e292 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,6 +7,7 @@ build docs tests !build/dokku.deb +!tests/dhparam.pem !contrib/dokku-installer.py !contrib/dokku-update !contrib/bash-completion From 6e3fddb544282ddf8f84f0d207aa4d368fe93b24 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 16 Sep 2019 03:05:35 -0400 Subject: [PATCH 30/39] feat: add proper openresty support This change allows supporting the openresty package as installed on Ubuntu 18.04 from the official openresty package repository, while also returning general nginx support. Closes #3675 --- docker/etc/my_init.d/10_dokku_init | 23 ++++-- .../etc/runit/runsvdir/default/openresty/run | 7 ++ .../usr/local/openresty/nginx/conf/nginx.conf | 30 +++++++ plugins/nginx-vhosts/functions | 47 +++-------- plugins/nginx-vhosts/install | 79 ++++++++++--------- plugins/nginx-vhosts/internal-functions | 66 ++++++++++++++++ plugins/nginx-vhosts/post-delete | 2 +- .../nginx-vhosts/templates/nginx.conf.sigil | 16 ++-- 8 files changed, 183 insertions(+), 87 deletions(-) create mode 100755 docker/etc/runit/runsvdir/default/openresty/run create mode 100644 docker/usr/local/openresty/nginx/conf/nginx.conf diff --git a/docker/etc/my_init.d/10_dokku_init b/docker/etc/my_init.d/10_dokku_init index 7caff134b..d60ad507c 100755 --- a/docker/etc/my_init.d/10_dokku_init +++ b/docker/etc/my_init.d/10_dokku_init @@ -13,6 +13,8 @@ log-fail() { } main() { + local NGINX_ROOT + if [[ ! -d /mnt/dokku ]]; then log-info "Creating missing /mnt/dokku" mkdir -p /mnt/dokku @@ -49,14 +51,23 @@ main() { echo "export DOCKER_BIN=/usr/local/bin/docker" >"/home/dokku/.dokkurc/DOCKER_BIN" fi - if [[ ! -f /mnt/dokku/etc/nginx/dhparam.pem ]]; then - mkdir -p /mnt/dokku/etc/nginx - openssl dhparam -out /mnt/dokku/etc/nginx/dhparam.pem 2048 + NGINX_ROOT="/etc/nginx" + if [[ -x /usr/bin/openresty ]]; then + NGINX_ROOT="/usr/local/openresty/nginx/conf" + rm -rf /etc/runit/runsvdir/default/nginx + else + rm -rf /etc/runit/runsvdir/default/openresty fi - cp -f /mnt/dokku/etc/nginx/dhparam.pem /etc/nginx/dhparam.pem - chown root:root /etc/nginx/dhparam.pem - chown root:root /etc/nginx/conf.d + if [[ ! -f "/mnt/dokku${NGINX_ROOT}/dhparam.pem" ]]; then + mkdir -p "/mnt/dokku${NGINX_ROOT}" + openssl dhparam -out "/mnt/dokku${NGINX_ROOT}/dhparam.pem" 2048 + fi + + mkdir -p "${NGINX_ROOT}/conf.d" + cp -f "/mnt/dokku${NGINX_ROOT}/dhparam.pem" "${NGINX_ROOT}/dhparam.pem" + chown root:root "${NGINX_ROOT}/dhparam.pem" + chown root:root "${NGINX_ROOT}/conf.d" } main "$@" diff --git a/docker/etc/runit/runsvdir/default/openresty/run b/docker/etc/runit/runsvdir/default/openresty/run new file mode 100755 index 000000000..66cd2211e --- /dev/null +++ b/docker/etc/runit/runsvdir/default/openresty/run @@ -0,0 +1,7 @@ +#!/bin/bash + +exec >>/var/log/services/openresty +exec 2>&1 + +echo "Running openresty" +exec /usr/bin/openresty -c /usr/local/openresty/nginx/conf/nginx.conf -g "daemon off;" diff --git a/docker/usr/local/openresty/nginx/conf/nginx.conf b/docker/usr/local/openresty/nginx/conf/nginx.conf new file mode 100644 index 000000000..d465e846b --- /dev/null +++ b/docker/usr/local/openresty/nginx/conf/nginx.conf @@ -0,0 +1,30 @@ +user www-data; +worker_processes auto; +pid /run/openresty.pid; +include /usr/local/openresty/nginx/conf/modules-enabled/*.conf; + +events { + worker_connections 768; +} + +http { + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + include /usr/local/openresty/nginx/conf/mime.types; + default_type application/octet-stream; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_prefer_server_ciphers on; + + access_log /var/log/openresty/access.log; + error_log /var/log/openresty/error.log; + + gzip on; + + include /usr/local/openresty/nginx/conf/conf.d/*.conf; + include /usr/local/openresty/nginx/conf/sites-enabled/*; +} diff --git a/plugins/nginx-vhosts/functions b/plugins/nginx-vhosts/functions index 03ab8637c..1aa1562bc 100755 --- a/plugins/nginx-vhosts/functions +++ b/plugins/nginx-vhosts/functions @@ -11,18 +11,7 @@ source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/internal-functions" get_nginx_location() { declare desc="check that nginx is at the expected location and return it" - local NGINX_LOCATION - - NGINX_LOCATION=$(which nginx 2>/dev/null) - if [[ -z "$NGINX_LOCATION" ]]; then - NGINX_LOCATION="/usr/sbin/nginx" - fi - - if [[ ! -x "$NGINX_LOCATION" ]]; then - dokku_log_fail "Could not find nginx binary in \$PATH or at '${NGINX_LOCATION}'." - fi - - echo "$NGINX_LOCATION" + fn-nginx-vhosts-nginx-location } validate_nginx() { @@ -69,32 +58,18 @@ validate_nginx() { restart_nginx() { declare desc="restart nginx for given distros" - case "$DOKKU_DISTRO" in - debian) - sudo /usr/sbin/invoke-rc.d nginx reload >/dev/null - ;; - - ubuntu) - sudo /etc/init.d/nginx reload >/dev/null - ;; - - opensuse) - sudo /sbin/service nginx reload >/dev/null - ;; - - arch | centos | rhel) - sudo /usr/bin/systemctl reload nginx - ;; - esac + fn-nginx-vhosts-nginx-init-cmd "reload" } nginx_logs() { declare desc="display app nginx logs" - local APP="$2" + declare NGINX_LOGS_TYPE="${1#nginx:}" APP="$2" + local NGINX_LOG_ROOT="/var/log/nginx" verify_app_name "$APP" - local NGINX_LOGS_TYPE=${1#nginx:} + + fn-nginx-vhosts-uses-openresty && NGINX_LOG_ROOT="/var/log/openresty" local NGINX_LOGS_TYPE=${NGINX_LOGS_TYPE%-logs} - local NGINX_LOGS_PATH="/var/log/nginx/$APP-$NGINX_LOGS_TYPE.log" + local NGINX_LOGS_PATH="$NGINX_LOG_ROOT/$APP-$NGINX_LOGS_TYPE.log" if [[ $3 == "-t" ]]; then local NGINX_LOGS_ARGS="-F" @@ -372,6 +347,9 @@ nginx_build_config() { PROXY_PORT_MAP=$(echo "$PROXY_PORT_MAP" | xargs) # trailing spaces mess up default template + local NGINX_LOG_ROOT="/var/log/nginx" + fn-nginx-vhosts-uses-openresty && NGINX_LOG_ROOT="/var/log/openresty" + eval "$(config_export app "$APP")" local SIGIL_PARAMS=(-f "$NGINX_TEMPLATE" APP="$APP" DOKKU_ROOT="$DOKKU_ROOT" NOSSL_SERVER_NAME="$NOSSL_SERVER_NAME" @@ -380,6 +358,7 @@ nginx_build_config() { PASSED_LISTEN_IP_PORT="$PASSED_LISTEN_IP_PORT" SPDY_SUPPORTED="$SPDY_SUPPORTED" HTTP2_SUPPORTED="$HTTP2_SUPPORTED" + NGINX_LOG_ROOT="$NGINX_LOG_ROOT" HTTP2_PUSH_SUPPORTED="$HTTP2_PUSH_SUPPORTED" GRPC_SUPPORTED="$GRPC_SUPPORTED" DOKKU_APP_LISTEN_PORT="$DOKKU_APP_LISTEN_PORT" DOKKU_APP_LISTEN_IP="$DOKKU_APP_LISTEN_IP" @@ -403,7 +382,7 @@ nginx_build_config() { plugn trigger nginx-pre-reload "$APP" "$DOKKU_APP_LISTEN_PORT" "$DOKKU_APP_LISTEN_IP" dokku_log_verbose "Reloading nginx" - validate_nginx && restart_nginx + validate_nginx && restart_nginx >/dev/null fi if ([[ -n "$NONSSL_VHOSTS" ]] || [[ -n "$SSL_VHOSTS" ]]) && [[ "$IS_APP_VHOST_ENABLED" == "true" ]]; then @@ -419,7 +398,7 @@ nginx_build_config() { if (is_deployed "$APP"); then dokku_log_info1 "reloading nginx after nginx.conf deletion" - validate_nginx && restart_nginx + validate_nginx && restart_nginx >/dev/null fi fi fi diff --git a/plugins/nginx-vhosts/install b/plugins/nginx-vhosts/install index 02cdc8c25..6ff611a04 100755 --- a/plugins/nginx-vhosts/install +++ b/plugins/nginx-vhosts/install @@ -3,41 +3,58 @@ set -eo pipefail [[ $DOKKU_TRACE ]] && set -x source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_AVAILABLE_PATH/config/functions" +source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/internal-functions" + +NGINX_BIN="$(fn-nginx-vhosts-nginx-location)" +NGINX_ROOT="/etc/nginx" +NGINX_LOG_ROOT="/var/log/nginx" +NGINX_INIT_NAME="nginx" +NGINX_SUDOERS_FILE="/etc/sudoers.d/dokku-nginx" +if fn-nginx-vhosts-uses-openresty; then + NGINX_ROOT="/usr/local/openresty/nginx/conf" + NGINX_LOG_ROOT="/var/log/openresty" + NGINX_INIT_NAME="openresty" + NGINX_SUDOERS_FILE="/etc/sudoers.d/dokku-openresty" +fi case "$DOKKU_DISTRO" in debian) - echo "%dokku ALL=(ALL) NOPASSWD:/usr/sbin/invoke-rc.d nginx reload, /usr/sbin/nginx -t, /usr/sbin/nginx -t -c *" >/etc/sudoers.d/dokku-nginx + echo "%dokku ALL=(ALL) NOPASSWD:/usr/sbin/invoke-rc.d $NGINX_INIT_NAME reload, $NGINX_BIN -t, ${NGINX_BIN} -t -c *" >"$NGINX_SUDOERS_FILE" ;; ubuntu) - echo "%dokku ALL=(ALL) NOPASSWD:/etc/init.d/nginx reload, /usr/sbin/nginx -t, /usr/sbin/nginx -t -c *" >/etc/sudoers.d/dokku-nginx + if [[ -x /usr/bin/sv ]]; then + echo "%dokku ALL=(ALL) NOPASSWD:/usr/bin/sv reload $NGINX_INIT_NAME, $NGINX_BIN -t, $NGINX_BIN -t -c *" >"$NGINX_SUDOERS_FILE" + else + echo "%dokku ALL=(ALL) NOPASSWD:/etc/init.d/$NGINX_INIT_NAME reload, $NGINX_BIN -t, $NGINX_BIN -t -c *" >"$NGINX_SUDOERS_FILE" + fi ;; opensuse) - echo "%dokku ALL=(ALL) NOPASSWD:/sbin/service nginx reload, /usr/sbin/nginx -t, /usr/sbin/nginx -t -c *" >/etc/sudoers.d/dokku-nginx + echo "%dokku ALL=(ALL) NOPASSWD:/sbin/service $NGINX_INIT_NAME reload, $NGINX_BIN -t, $NGINX_BIN -t -c *" >"$NGINX_SUDOERS_FILE" ;; arch) - echo "%dokku ALL=(ALL) NOPASSWD:/usr/bin/systemctl reload nginx, /usr/sbin/nginx -t, /usr/sbin/nginx -t -c *" >/etc/sudoers.d/dokku-nginx + echo "%dokku ALL=(ALL) NOPASSWD:/usr/bin/systemctl reload $NGINX_INIT_NAME, $NGINX_BIN -t, $NGINX_BIN -t -c *" >"$NGINX_SUDOERS_FILE" ;; centos | rhel) - echo "%dokku ALL=(ALL) NOPASSWD:/usr/bin/systemctl reload nginx, /usr/sbin/nginx -t, /usr/sbin/nginx -t -c *" >/etc/sudoers.d/dokku-nginx - echo "Defaults:dokku !requiretty" >>/etc/sudoers.d/dokku-nginx + echo "%dokku ALL=(ALL) NOPASSWD:/usr/bin/systemctl reload $NGINX_INIT_NAME, $NGINX_BIN -t, $NGINX_BIN -t -c *" >"$NGINX_SUDOERS_FILE" + echo "Defaults:dokku !requiretty" >>"$NGINX_SUDOERS_FILE" ;; esac -chmod 0440 /etc/sudoers.d/dokku-nginx +chmod 0440 "$NGINX_SUDOERS_FILE" # if dhparam.pem has not been created, create it the first time -if [[ ! -f /etc/nginx/dhparam.pem ]]; then - openssl dhparam -out /etc/nginx/dhparam.pem 2048 +if [[ ! -f "$NGINX_ROOT/dhparam.pem" ]]; then + openssl dhparam -out "$NGINX_ROOT/dhparam.pem" 2048 fi -mkdir -p /etc/nginx/conf.d -chown root:root /etc/nginx/dhparam.pem -chown root:root /etc/nginx/conf.d -cat </etc/nginx/conf.d/dokku.conf +mkdir -p "$NGINX_ROOT/conf.d" +chown root:root "$NGINX_ROOT/dhparam.pem" +chown root:root "$NGINX_ROOT/conf.d" +cat <"$NGINX_ROOT/conf.d/dokku.conf" include $DOKKU_ROOT/*/nginx.conf; server_tokens off; @@ -47,19 +64,20 @@ ssl_session_cache shared:SSL:20m; ssl_session_timeout 1d; ssl_session_tickets off; -ssl_dhparam /etc/nginx/dhparam.pem; +ssl_dhparam $NGINX_ROOT/dhparam.pem; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; EOF # allow users to override their server_names_hash_bucket_size -if [[ ! -f /etc/nginx/conf.d/server_names_hash_bucket_size.conf ]]; then - echo 'server_names_hash_bucket_size 512;' >|/etc/nginx/conf.d/server_names_hash_bucket_size.conf +if [[ ! -f "$NGINX_ROOT/conf.d/server_names_hash_bucket_size.conf" ]]; then + echo 'server_names_hash_bucket_size 512;' >|"$NGINX_ROOT/conf.d/server_names_hash_bucket_size.conf" fi # revert dokku group changes +mkdir -p "$NGINX_LOG_ROOT" gpasswd -a dokku adm -chgrp --quiet -R adm /var/log/nginx +chgrp --quiet -R adm "$NGINX_LOG_ROOT" gpasswd -M "$(egrep ^dokku: /etc/group | awk -F ":" '{ print $4 }')" dokku [[ -f /etc/logrotate.d/nginx ]] && sed -i -e 's/create 0640 www-data dokku/create 0640 www-data adm/g' /etc/logrotate.d/nginx @@ -93,24 +111,9 @@ for app in $(dokku_apps); do fi done -case "$DOKKU_DISTRO" in - debian) - NGINX_INIT="/usr/sbin/invoke-rc.d" - "$NGINX_INIT" nginx start || "$NGINX_INIT" nginx reload - ;; - - ubuntu) - NGINX_INIT="/etc/init.d/nginx" - "$NGINX_INIT" start || "$NGINX_INIT" reload - ;; - - opensuse) - NGINX_INIT="/sbin/service" - "$NGINX_INIT" nginx start || "$NGINX_INIT" nginx reload - ;; - - arch | centos | rhel) - NGINX_INIT="/usr/bin/systemctl" - "$NGINX_INIT" start nginx || "$NGINX_INIT" reload nginx - ;; -esac +# avoid failing runit init calls on install +# the runit binaries are not yet available during dockerfile building +# and therefore both these calls will fail +if [[ ! -x /usr/bin/sv ]]; then + fn-nginx-vhosts-nginx-init-cmd start || fn-nginx-vhosts-nginx-init-cmd reload +fi diff --git a/plugins/nginx-vhosts/internal-functions b/plugins/nginx-vhosts/internal-functions index 576db3504..451f7bbe0 100755 --- a/plugins/nginx-vhosts/internal-functions +++ b/plugins/nginx-vhosts/internal-functions @@ -1,6 +1,72 @@ #!/usr/bin/env bash set -eo pipefail [[ $DOKKU_TRACE ]] && set -x +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" + +fn-nginx-vhosts-uses-openresty() { + declare desc="returns whether openresty is in use or not" + + if [[ -x /usr/bin/openresty ]]; then + return + fi + + return 1 +} + +fn-nginx-vhosts-nginx-location() { + declare desc="check that nginx is at the expected location and return it" + local NGINX_LOCATION + + NGINX_LOCATION=$(which nginx 2>/dev/null) + if [[ -z "$NGINX_LOCATION" ]]; then + NGINX_LOCATION="/usr/sbin/nginx" + fi + + if fn-nginx-vhosts-uses-openresty; then + NGINX_LOCATION="/usr/bin/openresty" + fi + + if [[ ! -x "$NGINX_LOCATION" ]]; then + dokku_log_fail "Could not find nginx binary in \$PATH or at '${NGINX_LOCATION}'." + fi + + echo "$NGINX_LOCATION" +} + +fn-nginx-vhosts-nginx-init-cmd() { + declare desc="start nginx for given distros" + declare CMD="$1" + local NGINX_INIT_NAME + + + NGINX_INIT_NAME=nginx + if fn-nginx-vhosts-uses-openresty; then + NGINX_INIT_NAME=openresty + fi + + case "$DOKKU_DISTRO" in + debian) + sudo /usr/sbin/invoke-rc.d "$NGINX_INIT_NAME" "$CMD" + ;; + + ubuntu) + # support docker-based installations + if [[ -x /usr/bin/sv ]]; then + sudo /usr/bin/sv "$CMD" "$NGINX_INIT_NAME" + else + sudo "/etc/init.d/$NGINX_INIT_NAME" "$CMD" + fi + ;; + + opensuse) + sudo /sbin/service "$NGINX_INIT_NAME" "$CMD" + ;; + + arch | centos | rhel) + sudo /usr/bin/systemctl "$CMD" "$NGINX_INIT_NAME" + ;; + esac +} nginx_vhosts_validate_single_func() { declare APP="$1" FLAG="$2" diff --git a/plugins/nginx-vhosts/post-delete b/plugins/nginx-vhosts/post-delete index 115723393..f857dc99c 100755 --- a/plugins/nginx-vhosts/post-delete +++ b/plugins/nginx-vhosts/post-delete @@ -3,4 +3,4 @@ set -eo pipefail [[ $DOKKU_TRACE ]] && set -x source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions" -restart_nginx "$@" +restart_nginx "$@" >/dev/null diff --git a/plugins/nginx-vhosts/templates/nginx.conf.sigil b/plugins/nginx-vhosts/templates/nginx.conf.sigil index 04db4383c..7a0c04b9d 100644 --- a/plugins/nginx-vhosts/templates/nginx.conf.sigil +++ b/plugins/nginx-vhosts/templates/nginx.conf.sigil @@ -9,8 +9,8 @@ server { listen [::]:{{ $listen_port }}; listen {{ $listen_port }}; {{ if $.NOSSL_SERVER_NAME }}server_name {{ $.NOSSL_SERVER_NAME }}; {{ end }} - access_log /var/log/nginx/{{ $.APP }}-access.log; - error_log /var/log/nginx/{{ $.APP }}-error.log; + access_log {{ $.NGINX_LOG_ROOT }}/{{ $.APP }}-access.log; + error_log {{ $.NGINX_LOG_ROOT }}/{{ $.APP }}-error.log; {{ if (and (eq $listen_port "80") ($.SSL_INUSE)) }} return 301 https://$host:{{ $.PROXY_SSL_PORT }}$request_uri; {{ else }} @@ -60,8 +60,8 @@ server { listen {{ $listen_port }} ssl {{ if eq $.HTTP2_SUPPORTED "true" }}http2{{ else if eq $.SPDY_SUPPORTED "true" }}spdy{{ end }}; {{ if $.SSL_SERVER_NAME }}server_name {{ $.SSL_SERVER_NAME }}; {{ end }} {{ if $.NOSSL_SERVER_NAME }}server_name {{ $.NOSSL_SERVER_NAME }}; {{ end }} - access_log /var/log/nginx/{{ $.APP }}-access.log; - error_log /var/log/nginx/{{ $.APP }}-error.log; + access_log {{ $.NGINX_LOG_ROOT }}/{{ $.APP }}-access.log; + error_log {{ $.NGINX_LOG_ROOT }}/{{ $.APP }}-error.log; ssl_certificate {{ $.APP_SSL_PATH }}/server.crt; ssl_certificate_key {{ $.APP_SSL_PATH }}/server.key; @@ -123,8 +123,8 @@ server { listen [::]:{{ $listen_port }} http2; listen {{ $listen_port }} http2; {{ if $.NOSSL_SERVER_NAME }}server_name {{ $.NOSSL_SERVER_NAME }}; {{ end }} - access_log /var/log/nginx/{{ $.APP }}-access.log; - error_log /var/log/nginx/{{ $.APP }}-error.log; + access_log {{ $.NGINX_LOG_ROOT }}/{{ $.APP }}-access.log; + error_log {{ $.NGINX_LOG_ROOT }}/{{ $.APP }}-error.log; location / { grpc_pass grpc://{{ $.APP }}-{{ $upstream_port }}; } @@ -137,8 +137,8 @@ server { listen [::]:{{ $listen_port }} ssl http2; listen {{ $listen_port }} ssl http2; {{ if $.NOSSL_SERVER_NAME }}server_name {{ $.NOSSL_SERVER_NAME }}; {{ end }} - access_log /var/log/nginx/{{ $.APP }}-access.log; - error_log /var/log/nginx/{{ $.APP }}-error.log; + access_log {{ $.NGINX_LOG_ROOT }}/{{ $.APP }}-access.log; + error_log {{ $.NGINX_LOG_ROOT }}/{{ $.APP }}-error.log; ssl_certificate {{ $.APP_SSL_PATH }}/server.crt; ssl_certificate_key {{ $.APP_SSL_PATH }}/server.key; From cd28fe69a5c7778c49c09545b2209f1152c992e7 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 16 Sep 2019 21:48:31 -0400 Subject: [PATCH 31/39] fix: do not push betafish releases to docker hub --- contrib/release-dokku | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/contrib/release-dokku b/contrib/release-dokku index 75339bc66..c8dd76fd0 100755 --- a/contrib/release-dokku +++ b/contrib/release-dokku @@ -370,9 +370,12 @@ main() { 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" - docker tag "dokku/dokku:$VERSION" "dokku/dokku:latest" - docker push "dokku/dokku:$VERSION" - docker push "dokku/dokku:latest" + + if [[ "$IS_RELEASE" == "true" ]]; then + docker tag "dokku/dokku:$VERSION" "dokku/dokku:latest" + docker push "dokku/dokku:$VERSION" + docker push "dokku/dokku:latest" + fi fn-repo-push-tags "$IS_RELEASE" fi From 798725bb54bb64103a14e4fabf01704c19c8c6e0 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 16 Sep 2019 23:07:01 -0400 Subject: [PATCH 32/39] feat: allow passing labels to one-off dokku containers This feature is allows users to add extra label metadata to one-off containers. As this can interfere with Dokku internals if they shadow labels used by plugins, care should be taken to avoid the `com.dokku` or `org.label-schema` namespace. Also proper name run containers so they don't get random names from docker... --- docs/deployment/one-off-processes.md | 6 ++++++ plugins/common/functions | 16 ++++++++++++++++ plugins/scheduler-docker-local/scheduler-run | 13 +++++++++++-- tests/unit/30_core_1.bats | 7 ++++++- 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/docs/deployment/one-off-processes.md b/docs/deployment/one-off-processes.md index 79dfb5a16..45d9895c6 100644 --- a/docs/deployment/one-off-processes.md +++ b/docs/deployment/one-off-processes.md @@ -46,6 +46,12 @@ dokku --rm-container run node-js-app ls -lah dokku --rm run node-js-app ls -lah ``` +Containers may have specific labels attached. In order to avoid issues with dokku internals, do not use any labels beginning with either `com.dokku` or `org.label-schema`. + +```shell +dokku --label=com.example.test-label=value run node-js-app ls -lah +``` + Finally, you may wish to run a container in "detached" mode via the `--detach` Dokku flag. Running a process in detached mode will immediately return a `CONTAINER_ID`. It is up to the user to then further manage this container in whatever manner they see fit, as Dokku will *not* automatically terminate the container. ```shell diff --git a/plugins/common/functions b/plugins/common/functions index 374f2f58d..b3aee81bd 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -336,6 +336,8 @@ parse_args() { local next_index=1 local skip=false local args=("$@") + local flags + for arg in "$@"; do if [[ "$skip" == "true" ]]; then next_index=$((next_index + 1)) @@ -364,8 +366,22 @@ parse_args() { skip=true ;; esac + + if [[ "$skip" == "true" ]]; then + flags="${flags} ${arg}" + elif [[ "$arg" == "--app" ]]; then + flags="${flags} ${arg}=${args[$next_index]}" + elif [[ "$arg" =~ ^--.* ]]; then + flags="${flags} ${arg}" + fi + next_index=$((next_index + 1)) done + + if [[ -z "$DOKKU_GLOBAL_FLAGS" ]]; then + export DOKKU_GLOBAL_FLAGS="$(echo -e "${flags}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" + fi + return 0 } diff --git a/plugins/scheduler-docker-local/scheduler-run b/plugins/scheduler-docker-local/scheduler-run index a6105fbc0..2ef1a89f5 100755 --- a/plugins/scheduler-docker-local/scheduler-run +++ b/plugins/scheduler-docker-local/scheduler-run @@ -31,15 +31,15 @@ scheduler-docker-local-scheduler-run() { local DOCKER_ARGS=$(: | plugn trigger docker-args-run "$APP" "$IMAGE_TAG") [[ "$DOKKU_TRACE" ]] && DOCKER_ARGS+=" -e TRACE=true " + local DYNO_NUMBER="$RANDOM" local IMAGE_SOURCE_TYPE="dockerfile" is_image_herokuish_based "$IMAGE" && IMAGE_SOURCE_TYPE="herokuish" DOCKER_ARGS+=$(: | plugn trigger docker-args-process-run "$APP" "$IMAGE_TAG" "$IMAGE_SOURCE_TYPE") - DOCKER_ARGS+=" -e DYNO=run.$RANDOM" + DOCKER_ARGS+=" -e DYNO=run.$DYNO_NUMBER --name $APP.run.$DYNO_NUMBER" declare -a ARG_ARRAY eval "ARG_ARRAY=($DOCKER_ARGS)" - local DOKKU_RUN_OPTS=" -e DYNO=run.$RANDOM" if [[ "$DOKKU_RM_CONTAINER" ]]; then DOCKER_ARGS+=" --rm" elif [[ "$DOKKU_DETACH_CONTAINER" ]]; then @@ -53,6 +53,15 @@ scheduler-docker-local-scheduler-run() { DOCKER_ARGS_ARRAY+=("--env=$env_pair") done + if [[ -n "$DOKKU_GLOBAL_FLAGS" ]]; then + read -ra flags <<<"$DOKKU_GLOBAL_FLAGS" + for flag in "${flags[@]}"; do + if [[ "$flag" =~ ^--label.* ]]; then + DOCKER_ARGS_ARRAY+=("$flag") + fi + done + fi + [[ "$IMAGE_SOURCE_TYPE" == "herokuish" ]] && local EXEC_CMD="/exec" DOKKU_QUIET_OUTPUT=1 extract_procfile "$APP" diff --git a/tests/unit/30_core_1.bats b/tests/unit/30_core_1.bats index edb22b6ce..26746d0eb 100644 --- a/tests/unit/30_core_1.bats +++ b/tests/unit/30_core_1.bats @@ -111,12 +111,17 @@ assert_urls() { @test "(core) run (detached)" { deploy_app - RANDOM_RUN_CID="$(dokku --detach run $TEST_APP sleep 300)" + RANDOM_RUN_CID="$(dokku --label=com.dokku.test-label=value --detach run $TEST_APP sleep 300)" run /bin/bash -c "docker inspect -f '{{ .State.Status }}' $RANDOM_RUN_CID" echo "output: $output" echo "status: $status" assert_output "running" + run /bin/bash -c "docker inspect $RANDOM_RUN_CID --format '{{ index .Config.Labels \"com.dokku.test-label\" }}'" + echo "output: $output" + echo "status: $status" + assert_output "value" + run /bin/bash -c "docker stop $RANDOM_RUN_CID" echo "output: $output" echo "status: $status" From cb281e17e6e8147a856b06c954baf673e12de2f2 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Sep 2019 02:22:41 -0400 Subject: [PATCH 33/39] fix: correct shfmt issues --- plugins/git/functions | 3 ++- plugins/nginx-vhosts/internal-functions | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/git/functions b/plugins/git/functions index d1cf3ef62..db4ab4837 100755 --- a/plugins/git/functions +++ b/plugins/git/functions @@ -241,7 +241,8 @@ fn-git-create-hook() { cat >"$PRERECEIVE_HOOK" < Date: Tue, 17 Sep 2019 23:47:30 -0400 Subject: [PATCH 34/39] chore: silence trigger logging Logging that a trigger is about to be performed is a bit... extra. If folks want to know that a trigger is running, they can check the event logs. --- docs/deployment/methods/images.md | 1 - docs/deployment/zero-downtime-deploys.md | 1 - docs/networking/port-management.md | 2 -- plugins/nginx-vhosts/functions | 1 - 4 files changed, 5 deletions(-) diff --git a/docs/deployment/methods/images.md b/docs/deployment/methods/images.md index ce6408161..076a70862 100644 --- a/docs/deployment/methods/images.md +++ b/docs/deployment/methods/images.md @@ -92,7 +92,6 @@ dokku tags:deploy node-js-app v1 -----> Running post-deploy -----> Configuring node-js-app.dokku.me... -----> Creating http nginx.conf ------> Running nginx-pre-reload Reloading nginx -----> Shutting down old containers in 60 seconds =====> 025eec3fa3b442fded90933d58d8ed8422901f0449f5ea0c23d00515af5d3137 diff --git a/docs/deployment/zero-downtime-deploys.md b/docs/deployment/zero-downtime-deploys.md index 8c9465579..d02a896df 100644 --- a/docs/deployment/zero-downtime-deploys.md +++ b/docs/deployment/zero-downtime-deploys.md @@ -327,7 +327,6 @@ curl: (7) Failed to connect to 172.17.0.155 port 5000: Connection refused -----> Running post-deploy -----> Configuring myapp.dokku.me... -----> Creating http nginx.conf ------> Running nginx-pre-reload Reloading nginx -----> Shutting down old container in 60 seconds =====> Application deployed: diff --git a/docs/networking/port-management.md b/docs/networking/port-management.md index 7e4629905..276926b7f 100644 --- a/docs/networking/port-management.md +++ b/docs/networking/port-management.md @@ -65,7 +65,6 @@ dokku proxy:ports-add node-js-app http:8080:5000 DOKKU_PROXY_PORT_MAP: http:80:5000 http:8080:5000 -----> Configuring node-js-app.dokku.me...(using built-in template) -----> Creating http nginx.conf ------> Running nginx-pre-reload Reloading nginx ``` @@ -100,7 +99,6 @@ dokku proxy:ports-set node-js-app http:8080:5000 DOKKU_PROXY_PORT_MAP: http:80:5000 http:8080:5000 -----> Configuring node-js-app.dokku.me...(using built-in template) -----> Creating http nginx.conf ------> Running nginx-pre-reload Reloading nginx ``` diff --git a/plugins/nginx-vhosts/functions b/plugins/nginx-vhosts/functions index 1aa1562bc..f81e6baef 100755 --- a/plugins/nginx-vhosts/functions +++ b/plugins/nginx-vhosts/functions @@ -378,7 +378,6 @@ nginx_build_config() { dokku_log_info1 "Creating $SCHEME nginx.conf" mv "$NGINX_CONF" "$DOKKU_ROOT/$APP/nginx.conf" - dokku_log_info1 "Running nginx-pre-reload" plugn trigger nginx-pre-reload "$APP" "$DOKKU_APP_LISTEN_PORT" "$DOKKU_APP_LISTEN_IP" dokku_log_verbose "Reloading nginx" From b4e95fe0d5a48210a34094033de9807298731979 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Sep 2019 03:06:00 -0400 Subject: [PATCH 35/39] feat: add support for python3 - Use jq where possible - Drop unused function (no usage across entire codebase nor in any github repository Closes #3689 --- contrib/copy-packages | 2 +- contrib/dokku-installer.py | 12 ++++++++---- debian/control | 4 ++-- debian/lintian-overrides | 3 +++ plugins/app-json/internal-functions | 2 +- plugins/common/functions | 18 ++---------------- .../scheduler-docker-local/scheduler-inspect | 2 +- rpm.mk | 1 + tests/ci/setup.sh | 2 +- 9 files changed, 20 insertions(+), 26 deletions(-) diff --git a/contrib/copy-packages b/contrib/copy-packages index 69282e35b..24ad42482 100644 --- a/contrib/copy-packages +++ b/contrib/copy-packages @@ -42,7 +42,7 @@ def main(): download_urls['downloads/' + version['filename']] = version['download_url'] for filename, download_url in download_urls.items(): - print "downloading", filename + print("downloading {0}".format(filename)) download_file(filename, download_url) upload_file(filename) diff --git a/contrib/dokku-installer.py b/contrib/dokku-installer.py index 741ce51d3..20765781c 100755 --- a/contrib/dokku-installer.py +++ b/contrib/dokku-installer.py @@ -1,11 +1,15 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python import cgi import json import os import re -import SimpleHTTPServer -import SocketServer +try: + import SimpleHTTPServer + import SocketServer +except ImportError: + import http.server as SimpleHTTPServer + import socketserver as SocketServer import subprocess import sys import threading @@ -232,7 +236,7 @@ def main(): port = int(os.getenv('PORT', 2000)) httpd = SocketServer.TCPServer(("", port), GetHandler) - print "Listening on 0.0.0.0:{0}, CTRL+C to stop".format(port) + print("Listening on 0.0.0.0:{0}, CTRL+C to stop".format(port)) httpd.serve_forever() diff --git a/debian/control b/debian/control index e883b4f8d..7686d27e8 100644 --- a/debian/control +++ b/debian/control @@ -3,9 +3,9 @@ Version: 0.18.3 Section: web Priority: optional Architecture: amd64 -Depends: locales, git, curl, man-db, netcat, sshcommand (>= 0.6.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 +Depends: locales, git, curl, man-db, netcat, sshcommand (>= 0.6.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 Recommends: herokuish (>= 0.3.4), parallel, dokku-update -Pre-Depends: nginx (>= 1.8.0) | openresty, dnsutils, cgroupfs-mount | cgroup-lite, plugn (>= 0.3.0), sudo, python2.7, debconf +Pre-Depends: nginx (>= 1.8.0) | openresty, dnsutils, cgroupfs-mount | cgroup-lite, plugn (>= 0.3.0), sudo, python | python2.7 | python3, debconf Maintainer: Jose Diaz-Gonzalez Description: Docker-powered PaaS that helps build and manage the lifecycle of applications Dokku is an extensible, open source Platform as a Service diff --git a/debian/lintian-overrides b/debian/lintian-overrides index b659deeeb..31e14eb7e 100644 --- a/debian/lintian-overrides +++ b/debian/lintian-overrides @@ -10,3 +10,6 @@ dokku: hardening-no-relro # Built golang binaries link to libc dokku: missing-dependency-on-libc + +# Temporary python dependency until #2247 is resolved +dokku: python-script-but-no-python-dep usr/share/dokku/contrib/dokku-installer.py diff --git a/plugins/app-json/internal-functions b/plugins/app-json/internal-functions index b5adb2c6c..cdb8ff68c 100755 --- a/plugins/app-json/internal-functions +++ b/plugins/app-json/internal-functions @@ -17,7 +17,7 @@ get_phase_script() { return 0 fi - get_json_value "scripts.dokku.${PHASE_SCRIPT_KEY}" <"$APP_JSON_FILE" + get_json_value ".scripts.dokku.${PHASE_SCRIPT_KEY}" <"$APP_JSON_FILE" } get_release_cmd() { diff --git a/plugins/common/functions b/plugins/common/functions index b3aee81bd..65daac823 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -923,24 +923,10 @@ internal_get_app_urls() { get_json_value() { declare desc="return value of provided json key from a json stream on stdin" # JSON_NODE should be expresses as either a top-level object that has no children - # or in the format of json.node.path + # or in the format of .json.node.path local JSON_NODE="$1" - local JSON_NODE=${JSON_NODE//\./\"][\"} - local JSON_NODE="[\"${JSON_NODE}\"]" - cat | python2.7 -c 'import json,sys;obj=json.load(sys.stdin);print json.dumps(obj'"${JSON_NODE}"').strip("\"")' -} -get_json_keys() { - declare desc="return space-separated list of json keys from json provided on stdin" - # JSON_NODE should be expressed as json.node.path and is expected to have children - local JSON_NODE="$1" - local JSON_NODE=${JSON_NODE//\./\"][\"} - local JSON_NODE="[\"${JSON_NODE}\"]" - if [[ "$JSON_NODE" == "[\"\"]" ]]; then - cat | python2.7 -c 'import json,sys;obj=json.load(sys.stdin);print " ".join(obj.keys())' - else - cat | python2.7 -c 'import json,sys;obj=json.load(sys.stdin);print " ".join(obj'"${JSON_NODE}"'.keys())' - fi + cat | jq -r "${JSON_NODE} | select (.!=null)" 2>/dev/null } strip_inline_comments() { diff --git a/plugins/scheduler-docker-local/scheduler-inspect b/plugins/scheduler-docker-local/scheduler-inspect index 19708c3f5..c6ef49d06 100755 --- a/plugins/scheduler-docker-local/scheduler-inspect +++ b/plugins/scheduler-docker-local/scheduler-inspect @@ -40,7 +40,7 @@ for container in data: container['Config']['Env'] = env output.append(container) -print json.dumps(data, sort_keys=True, indent=4) +print(json.dumps(data, sort_keys=True, indent=4)) EOF local CONTAINER_FILES="$(find "$DOKKU_ROOT/$APP" -maxdepth 1 -name "CONTAINER.*" -printf "%f\n" 2>/dev/null | sort -t . -k 2 -n | xargs)" diff --git a/rpm.mk b/rpm.mk index ccc0ca9af..fb5cdbe86 100644 --- a/rpm.mk +++ b/rpm.mk @@ -65,6 +65,7 @@ endif --depends 'dos2unix' \ --depends 'git' \ --depends 'gliderlabs-sigil' \ + --depends 'jq' \ --depends 'man-db' \ --depends 'nc' \ --depends 'nginx >= 1.8.0' \ diff --git a/tests/ci/setup.sh b/tests/ci/setup.sh index 01951d58d..eb888f58c 100755 --- a/tests/ci/setup.sh +++ b/tests/ci/setup.sh @@ -29,7 +29,7 @@ install_dependencies() { sudo add-apt-repository -y ppa:nginx/stable sudo apt-get update - sudo apt-get -qq -y install cgroupfs-mount dos2unix nginx + sudo apt-get -qq -y install cgroupfs-mount dos2unix jq nginx sudo cp "${ROOT_DIR}/tests/dhparam.pem" /etc/nginx/dhparam.pem sudo dpkg -i "${ROOT_DIR}/build/$HEROKUISH_PACKAGE_NAME" \ From 9c68cd53fce6c30573aca286babf7889ba824a7f Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 20 Sep 2019 01:25:42 -0400 Subject: [PATCH 36/39] refactor: remove ssh-keys user-auth trigger in favor of direct check in dokku binary --- dokku | 4 ++-- plugins/ssh-keys/user-auth | 14 -------------- 2 files changed, 2 insertions(+), 16 deletions(-) delete mode 100755 plugins/ssh-keys/user-auth diff --git a/dokku b/dokku index 80a902e88..1cf34149d 100755 --- a/dokku +++ b/dokku @@ -87,13 +87,13 @@ if [[ "${args[0]}" =~ ^--.* ]]; then fi ! has_tty && DOKKU_QUIET_OUTPUT=1 -if [[ $(id -un) != "dokku" ]] && [[ ! $1 =~ plugin:* ]] && [[ ! $1 == "ssh-keys:add" ]]; then +if [[ $(id -un) != "dokku" ]] && [[ ! $1 =~ plugin:* ]] && [[ $1 != "ssh-keys:add" ]] && [[ $1 != "ssh-keys:remove" ]]; then export SSH_USER=$(id -un) sudo -u dokku -E -H "$0" "$@" exit $? fi -if [[ $1 =~ ^plugin:.* && $1 != "plugin:help" && $1 != "plugin:list" ]] || [[ $1 == "ssh-keys:add" ]]; then +if [[ $1 =~ ^plugin:.* && $1 != "plugin:help" && $1 != "plugin:list" ]] || [[ $1 == "ssh-keys:add" ]] || [[ $1 == "ssh-keys:remove" ]]; then if [[ $(id -un) != "root" ]]; then dokku_log_fail "This command must be run as root" else diff --git a/plugins/ssh-keys/user-auth b/plugins/ssh-keys/user-auth deleted file mode 100755 index 6fea1dca8..000000000 --- a/plugins/ssh-keys/user-auth +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -set -eo pipefail -[[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" - -check_ssh_keys_user() { - declare desc="check user passed by user-auth for ssh-keys plugin" - local SSH_USER=$1 SSH_NAME=$2 - [[ "$SSH_USER" == "root" || "$SSH_NAME" == *admin* ]] || dokku_log_fail "You must be root, or a dokku admin, to execute this command" -} - -if [[ "$3" =~ (ssh-keys:add|ssh-keys:remove) ]]; then - check_ssh_keys_user "$@" -fi From 498bdd04918420076f059126a93b4dc8c4d9a39c Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 20 Sep 2019 12:31:12 -0400 Subject: [PATCH 37/39] chore: cleanup build and destroy logging output --- plugins/apps/functions | 2 +- plugins/common/functions | 2 +- plugins/ps/subcommands/default | 2 +- plugins/scheduler-docker-local/scheduler-deploy | 2 +- plugins/scheduler-docker-local/scheduler-stop | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/apps/functions b/plugins/apps/functions index b891675b9..abd9521b1 100755 --- a/plugins/apps/functions +++ b/plugins/apps/functions @@ -34,7 +34,7 @@ apps_destroy() { fi fi - echo "Destroying $APP (including all add-ons)" + dokku_log_info1 "Destroying $APP (including all add-ons)" plugn trigger pre-delete "$APP" "$IMAGE_TAG" local DOKKU_SCHEDULER=$(get_app_scheduler "$APP") diff --git a/plugins/common/functions b/plugins/common/functions index 65daac823..66cf890ae 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -538,7 +538,7 @@ is_app_running() { dokku_log_warn "Deprecated: ps#fn-is-app-running" verify_app_name "$APP" - local APP_RUNNING_CONTAINER_IDS=$(get_app_running_container_ids "$APP") + local APP_RUNNING_CONTAINER_IDS=$(get_app_running_container_ids "$APP" 2>/dev/null) if [[ -n "$APP_RUNNING_CONTAINER_IDS" ]]; then return 0 diff --git a/plugins/ps/subcommands/default b/plugins/ps/subcommands/default index cd34876e1..3f136c8d1 100755 --- a/plugins/ps/subcommands/default +++ b/plugins/ps/subcommands/default @@ -14,7 +14,7 @@ ps_main_cmd() { verify_app_name "$APP" ! (is_deployed "$APP") && dokku_log_warn "App $APP has not been deployed" && exit 0 - local DOKKU_APP_RUNNING_CONTAINER_IDS=$(get_app_running_container_ids "$APP") + local DOKKU_APP_RUNNING_CONTAINER_IDS=$(get_app_running_container_ids "$APP" 2>/dev/null) local CID for CID in $DOKKU_APP_RUNNING_CONTAINER_IDS; do diff --git a/plugins/scheduler-docker-local/scheduler-deploy b/plugins/scheduler-docker-local/scheduler-deploy index f0e8cbe2d..6138f081f 100755 --- a/plugins/scheduler-docker-local/scheduler-deploy +++ b/plugins/scheduler-docker-local/scheduler-deploy @@ -50,7 +50,7 @@ scheduler-docker-local-scheduler-deploy() { if [[ "$(is_app_proctype_checks_disabled "$APP" "$PROC_TYPE")" == "true" ]]; then dokku_log_info1 "zero downtime is disabled for app ($APP.$PROC_TYPE). stopping currently running containers" - local cid proctype_oldids="$(get_app_running_container_ids "$APP" "$PROC_TYPE")" + local cid proctype_oldids="$(get_app_running_container_ids "$APP" "$PROC_TYPE" 2>/dev/null)" for cid in $proctype_oldids; do dokku_log_info2 "stopping $APP.$PROC_TYPE ($cid)" diff --git a/plugins/scheduler-docker-local/scheduler-stop b/plugins/scheduler-docker-local/scheduler-stop index f696509a0..f5a8787ca 100755 --- a/plugins/scheduler-docker-local/scheduler-stop +++ b/plugins/scheduler-docker-local/scheduler-stop @@ -13,7 +13,7 @@ scheduler-docker-local-scheduler-stop() { return fi - local DOKKU_APP_RUNNING_CONTAINER_IDS=$(get_app_running_container_ids "$APP") + local DOKKU_APP_RUNNING_CONTAINER_IDS=$(get_app_running_container_ids "$APP" 2>/dev/null) local DOKKU_DOCKER_STOP_TIMEOUT="$(config_get "$APP" DOKKU_DOCKER_STOP_TIMEOUT || true)" [[ -n "$DOKKU_DOCKER_STOP_TIMEOUT" ]] && DOCKER_STOP_TIME_ARG="--time=${DOKKU_DOCKER_STOP_TIMEOUT}" From 9ed22eafea861df5f85e330a63494c022d22404b Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Fri, 27 Sep 2019 12:50:16 -0700 Subject: [PATCH 38/39] Add `dokku cleanup` to help output Fixes #3698 --- plugins/00_dokku-standard/commands | 5 +++-- tests/unit/40_core_2.bats | 7 +++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/plugins/00_dokku-standard/commands b/plugins/00_dokku-standard/commands index 871a2854b..7e830763a 100755 --- a/plugins/00_dokku-standard/commands +++ b/plugins/00_dokku-standard/commands @@ -1,14 +1,15 @@ #!/usr/bin/env bash -[[ " help help:help run:help trace:help url:help urls:help version:help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT" +[[ " help help:help cleanup:help run:help trace:help url:help urls:help version:help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x case "$1" in - help | run:help | trace:help | url:help | urls:help | version:help) + help | cleanup:help | run:help | trace:help | url:help | urls:help | version:help) [[ $(echo "$1" | sed '/.*:help/!d') ]] && help_topic="${1%\:help}" help_content_func() { declare desc="return standard plugin help content" cat <], Cleans up exited/dead Docker containers and removes dangling images run [--env KEY=VALUE] , Run a command in a new container using the current application image url , Show the first URL for an application (compatibility) urls , Show all URLs for an application diff --git a/tests/unit/40_core_2.bats b/tests/unit/40_core_2.bats index ffd74ff6b..f237a56c5 100644 --- a/tests/unit/40_core_2.bats +++ b/tests/unit/40_core_2.bats @@ -31,6 +31,13 @@ assert_url() { assert_output "${url}" } +@test "(core) cleanup:help" { + run /bin/bash -c "dokku cleanup:help" + echo "output: $output" + echo "status: $status" + assert_output_contains "Cleans up exited/dead Docker containers and removes dangling image" +} + @test "(core) run (with --options)" { deploy_app run /bin/bash -c "dokku --force --quiet run $TEST_APP node --version" From 34b5234e2fff6e4d5524b92225e4815bb227872a Mon Sep 17 00:00:00 2001 From: Linus Metzler Date: Wed, 2 Oct 2019 11:03:41 +0200 Subject: [PATCH 39/39] Use HTTPS instead of SSH for clone If the user has not yet added their public key to GitHub, using SSH for clone results in an error message due to permission denied. --- docs/deployment/application-deployment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/deployment/application-deployment.md b/docs/deployment/application-deployment.md index 0ccc37cef..6a86785bd 100644 --- a/docs/deployment/application-deployment.md +++ b/docs/deployment/application-deployment.md @@ -9,7 +9,7 @@ Once you have configured Dokku with at least one user, you can deploy applicatio ```shell # from your local machine # SSH access to github must be enabled on this host -git clone git@github.com:heroku/ruby-getting-started.git +git clone https://github.com/heroku/ruby-getting-started ``` ### Create the app