feat: implement first-pass at networking plugin

Implements help, `rebuild`, and `rebuildall` command.

Refs #2403
This commit is contained in:
Jose Diaz-Gonzalez
2017-04-21 01:51:32 -06:00
committed by Michael Hobbs
parent 8be92d9739
commit ec9b8be5f8
8 changed files with 242 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
# Network Management
> New as of 0.10.0
```
network:rebuild <app> # Rebuilds network settings for an app
network:rebuildall # Rebuild network settings for all apps
```
The Network plugin allows developers to abstract the concept of container network management, allowing developers to both change what networks a given container is attached to as well as rebuild the configuration on the fly.
## Usage
### Rebuilding network settings
There are cases where you may need to rebuild the network configuration for an app, such as on app boot or container restart. In these cases, you can use the `network:rebuild` command:
```shell
dokku network:rebuild node-js-app
```
> This command will exit a non-zero number that depends on the number of containers for which configuration could not be built
### Rebuilding all network settings
In some cases, a docker upgrade may reset container IPs or Ports. In both cases, you can quickly rewrite those files by using the `network:rebuildall` command:
```shell
dokku network:rebuildall
```
> This command will exit a non-zero number that depends on the number of containers for which configuration could not be built

15
plugins/network/commands Executable file
View File

@@ -0,0 +1,15 @@
#!/usr/bin/env bash
[[ " help network:help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
source "$PLUGIN_AVAILABLE_PATH/network/internal-functions"
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
case "$1" in
help | network:help)
network_help_cmd "$@"
;;
*)
exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
;;
esac

132
plugins/network/functions Executable file
View File

@@ -0,0 +1,132 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
network-write-config() {
declare desc="writes the network config files out"
declare APP="$1"; verify_app_name "$APP"
local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE"
dokku_log_info1 "Ensuring network configuration is in sync for ${APP}"
local line; local PROC_TYPE; local PROC_COUNT; local CONTAINER_INDEX
while read -r line || [[ -n "$line" ]]; do
[[ "$line" =~ ^#.* ]] && continue
line="$(strip_inline_comments "$line")"
PROC_TYPE=${line%%=*}
PROC_COUNT=${line#*=}
CONTAINER_INDEX=1
while [[ $CONTAINER_INDEX -le $PROC_COUNT ]]; do
local CID="" p="" port="" ipaddr="" CONTAINER_STATUS
local DOKKU_CONTAINER_ID_FILE="$DOKKU_ROOT/$APP/CONTAINER.$PROC_TYPE.$CONTAINER_INDEX"
local DOKKU_IP_FILE="$DOKKU_ROOT/$APP/IP.$PROC_TYPE.$CONTAINER_INDEX"
local DOKKU_PORT_FILE="$DOKKU_ROOT/$APP/PORT.$PROC_TYPE.$CONTAINER_INDEX"
local CONTAINER_INDEX=$(( CONTAINER_INDEX + 1 ))
[[ -f "$DOKKU_CONTAINER_ID_FILE" ]] || continue
CID="$(cat "$DOKKU_CONTAINER_ID_FILE")"
[[ -n "$CID" ]] || continue
CONTAINER_RUNNING="$(docker inspect -f '{{.State.Running}}' "$CID" 2>/dev/null || true)"
[[ "$CONTAINER_RUNNING" == "true" ]] || continue
ipaddr=$(network-get-container-ipaddr "$APP" "PROC_TYPE" "$CID")
port=$(network-get-container-port "$APP" "PROC_TYPE" "$CID")
[[ -n "$ipaddr" ]] && echo "$ipaddr" > "$DOKKU_IP_FILE"
[[ -n "$port" ]] && echo "$port" > "$DOKKU_PORT_FILE"
done
done < "$DOKKU_SCALE_FILE"
}
network-compute-container-ports() {
declare desc="Return the ipaddr for a given app container"
declare APP="$1" PROC_TYPE="$2"
local PORTS
if [[ "$PROC_TYPE" != "web" ]]; thren
return
fi
is_image_herokuish_based "$IMAGE" && local DOKKU_HEROKUISH=true
if [[ -z "$DOKKU_HEROKUISH" ]]; then
local DOKKU_DOCKERFILE_PORTS=($(config_get "$APP" DOKKU_DOCKERFILE_PORTS || true))
fi
if [[ -z "${DOKKU_DOCKERFILE_PORTS[*]}" ]]; then
local PORTS=5000
else
local p
for p in ${DOKKU_DOCKERFILE_PORTS[*]};do
if [[ ! "$p" =~ .*udp.* ]]; then
# set port to first non-udp port
local p=${p//\/tcp}
local PORT=${PORT:="$p"}
fi
PORTS+=" $PORT "
done
fi
echo "$PORTS"
}
network-get-container-ipaddr() {
declare desc="Return the ipaddr for a given app container"
declare APP="$1" PROC_TYPE="$2" CONTAINER_ID="$3"
local DOKKU_IS_APP_PROXY_ENABLED
local IP_ADDRESS=127.0.0.1
if [[ "$PROC_TYPE" != "web" ]]; thren
return
fi
local DOKKU_IS_APP_PROXY_ENABLED="$(is_app_proxy_enabled "$APP")"
if [[ "$DOKKU_IS_APP_PROXY_ENABLED" == "true" ]]; then
IP_ADDRESS="$(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$CID")"
# Docker < 1.9 compatibility
if [[ -z $ipaddr ]]; then
IP_ADDRESS=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' "$CID")
fi
fi
echo "$IP_ADDRESS"
}
network-get-container-port() {
declare desc="Return the ipaddr for a given app container"
declare APP="$1" PROC_TYPE="$2" CID="$3"
local DOKKU_IS_APP_PROXY_ENABLED
local PORT=5000
if [[ "$PROC_TYPE" != "web" ]]; thren
return
fi
local IMAGE_TAG="$(get_running_image_tag "$APP")"
local IMAGE=$(get_deploying_app_image_name "$APP" "$IMAGE_TAG")
is_image_herokuish_based "$IMAGE" && local DOKKU_HEROKUISH=true
if [[ -z "$DOKKU_HEROKUISH" ]]; then
local DOKKU_DOCKERFILE_PORTS=($(config_get "$APP" DOKKU_DOCKERFILE_PORTS || true))
fi
if [[ -n "${DOKKU_DOCKERFILE_PORTS[*]}" ]]; then
for p in ${DOKKU_DOCKERFILE_PORTS[*]};do
if [[ ! "$p" =~ .*udp.* ]]; then
# set port to first non-udp port
p=${p//\/tcp}
PORT=${port:="$p"}
fi
done
fi
if [[ "$DOKKU_IS_APP_PROXY_ENABLED" != "true" ]]; then
PORT="$(docker port "$CID" "$PORT" | sed 's/[0-9.]*://')"
fi
echo "$PORT"
}

View File

@@ -0,0 +1,27 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
network_help_content_func() {
declare desc="return network plugin help content"
cat<<help_content
network:rebuild <app>, Rebuilds network settings for an app
network:rebuildall, Rebuild network settings for all apps
help_content
}
network_help_cmd() {
if [[ $1 = "network:help" ]] ; then
echo -e 'Usage: dokku network[:COMMAND]'
echo ''
echo 'Rebuilds network settings for an app.'
echo ''
echo 'Additional commands:'
network_help_content_func | sort | column -c2 -t -s,
elif [[ $(ps -o command= $PPID) == *"--all"* ]]; then
network_help_content_func
else
cat<<help_desc
network, Manage network configuration for applications
help_desc
fi
}

View File

@@ -0,0 +1,4 @@
[plugin]
description = "dokku core network plugin"
version = "0.9.4"
[plugin.config]

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_AVAILABLE_PATH/network/internal-functions"
network_help_cmd "network:help"

View File

@@ -0,0 +1,13 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_AVAILABLE_PATH/network/functions"
network_rebuild_cmd() {
declare desc="rebuilds network settings for an app"
local cmd="network:rebuild"
local APP="$2"
dokku_write_network_config "$APP"
}
network_rebuild_cmd "$@"

View File

@@ -0,0 +1,14 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/network/functions"
network_rebuildall_cmd() {
declare desc="rebuilds network settings for all apps"
local cmd="network:rebuildall"
for app in $(dokku_apps); do
(is_deployed "$app") && dokku_write_network_config "$app"
done
}
network_rebuildall_cmd "$@"