refactor: move code for fetching an available port to the ports plugin

Also translate the code to golang.
This commit is contained in:
Jose Diaz-Gonzalez
2023-07-09 02:45:36 -04:00
parent 121e4737a8
commit 192f7cf768
9 changed files with 59 additions and 16 deletions

View File

@@ -8,6 +8,7 @@
- Users no longer need to clear the `source-image` git property when transitioning from image-based deploys (`git:from-image` and `git:load-image`) to other deployment methods (git push, `git:from-archive`, `git:sync`).
- For deploys via the `git:from-image` and `git:load-image` commands, the `CHECKS` file is now extracted from the configured `WORKDIR` property of the image. For all other deploys - git push, `git:from-archive`, `git:sync` - will have the `CHECKS` extracted directly from the source code. The filename in both cases is `CHECKS` and cannot be modified.
- The `common#get_app_raw_tcp_ports()` function has been deprecated and will be removed in the next release. Users should avoid interacting with this function for dockerfile ports and instead use the `ports-get` plugin trigger for fetching ports for an app.
- The `common#get_available_port()` function has been deprecated and will be removed in the next release. Users should avoid interacting with this function and instead use the `ports-get-available` plugin trigger for fetching an available port.
## Deprecations

View File

@@ -1288,6 +1288,21 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
# TODO
```
### `ports-get-available`
- Description: Prints out an available port greater than 1024
- Invoked by: Various networking plugins
- Arguments `$APP`
- Example:
```shell
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
# TODO
```
### `post-app-clone`
- Description: Allows you to run commands after an app was cloned.

View File

@@ -0,0 +1 @@
hook

View File

@@ -699,15 +699,8 @@ docker_cleanup() {
get_available_port() {
declare desc="returns first currently unused port > 1024"
while true; do
local port=$(shuf -i 1025-65535 -n 1)
if ! nc -z 0.0.0.0 "$port"; then
echo "$port"
return 0
else
continue
fi
done
dokku_log_warn "Deprecated: please use the 'ports-get-available' plugin trigger instead"
plugn trigger ports-get-available
}
dokku_auth() {

View File

@@ -1,5 +1,5 @@
SUBCOMMANDS = subcommands/list subcommands/add subcommands/clear subcommands/remove subcommands/set subcommands/report
TRIGGERS = triggers/ports-clear triggers/ports-dockerfile-raw-tcp-ports triggers/ports-get triggers/post-certs-remove triggers/post-certs-update triggers/report
TRIGGERS = triggers/ports-clear triggers/ports-dockerfile-raw-tcp-ports triggers/ports-get triggers/ports-get-available triggers/post-certs-remove triggers/post-certs-update triggers/report
BUILD = commands subcommands triggers
PLUGIN_NAME = ports

View File

@@ -3,6 +3,7 @@ package ports
import (
"errors"
"fmt"
"net"
"os"
"sort"
"strconv"
@@ -38,6 +39,26 @@ func filterAppPortMaps(appName string, scheme string, hostPort int) []PortMap {
return filteredPortMaps
}
func getAvailablePort() int {
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
if err != nil {
return 0
}
for {
l, err := net.ListenTCP("tcp", addr)
if err != nil {
return 0
}
defer l.Close()
port := l.Addr().(*net.TCPAddr).Port
if port >= 1025 && port <= 65535 {
return port
}
}
}
func getDockerfileRawTCPPorts(appName string) []int {
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_DOCKERFILE_PORTS"}...)
dockerfilePorts := strings.TrimSpace(string(b[:]))

View File

@@ -8,7 +8,7 @@ trigger-ports-proxy-configure-ports() {
declare desc="ports proxy-configure-ports plugin trigger"
declare trigger="proxy-configure-ports"
declare APP="$1"
local RAW_TCP_PORTS="$(get_app_raw_tcp_ports "$APP")"
local RAW_TCP_PORTS="$(plugn trigger ports-dockerfile-raw-tcp-ports "$APP" | xargs)"
local DOKKU_PROXY_PORT=$(config_get "$APP" DOKKU_PROXY_PORT)
local DOKKU_PROXY_SSL_PORT=$(config_get "$APP" DOKKU_PROXY_SSL_PORT)
local DOKKU_PROXY_PORT_MAP=$(config_get "$APP" DOKKU_PROXY_PORT_MAP)
@@ -20,7 +20,7 @@ trigger-ports-proxy-configure-ports() {
if [[ -z "$DOKKU_PROXY_PORT" ]] && [[ -z "$RAW_TCP_PORTS" ]]; then
if [[ "$IS_APP_VHOST_ENABLED" == "false" ]]; then
dokku_log_info1 "No port set, setting to random open high port"
local PROXY_PORT=$(get_available_port)
local PROXY_PORT=$(plugn trigger ports-get-available)
else
local PROXY_PORT=$(config_get --global DOKKU_PROXY_PORT)
PROXY_PORT=${PROXY_PORT:=80}
@@ -33,7 +33,7 @@ trigger-ports-proxy-configure-ports() {
PROXY_SSL_PORT=${PROXY_SSL_PORT:=443}
if [[ -z "$RAW_TCP_PORTS" ]] && [[ "$IS_APP_VHOST_ENABLED" == "false" ]]; then
dokku_log_info1 "No ssl port set, setting to random open high port"
PROXY_SSL_PORT=$(get_available_port)
PROXY_SSL_PORT=$(plugn trigger ports-get-available)
fi
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" DOKKU_PROXY_SSL_PORT="$PROXY_SSL_PORT"
fi

View File

@@ -18,15 +18,17 @@ func main() {
var err error
switch trigger {
case "ports-get":
appName := flag.Arg(0)
err = ports.TriggerPortsGet(appName)
case "ports-clear":
appName := flag.Arg(0)
err = ports.TriggerPortsClear(appName)
case "ports-dockerfile-raw-tcp-ports":
appName := flag.Arg(0)
err = ports.TriggerPortsDockerfileRawTCPPorts(appName)
case "ports-get":
appName := flag.Arg(0)
err = ports.TriggerPortsGet(appName)
case "ports-get-available":
err = ports.TriggerPortsGetAvailable()
case "post-certs-remove":
appName := flag.Arg(0)
err = ports.TriggerPostCertsRemove(appName)

View File

@@ -35,6 +35,16 @@ func TriggerPortsGet(appName string) error {
return nil
}
// TriggerPortsGetAvailable prints out an available port greater than 1024
func TriggerPortsGetAvailable() error {
port := getAvailablePort()
if port > 0 {
common.Log(fmt.Sprint(port))
}
return nil
}
// TriggerPostCertsRemove unsets port config vars after SSL cert is added
func TriggerPostCertsRemove(appName string) error {
keys := []string{"DOKKU_PROXY_SSL_PORT"}