This allows for some degree of parity as the network will now resolve the same for both linked and networked containers.
231 lines
10 KiB
Bash
Executable File
231 lines
10 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/config"
|
|
set -eo pipefail
|
|
[[ $DOKKU_TRACE ]] && set -x
|
|
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common-functions"
|
|
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
|
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
|
|
source "$PLUGIN_AVAILABLE_PATH/config/functions"
|
|
if [[ -f "$PLUGIN_AVAILABLE_PATH/docker-options/functions" ]]; then
|
|
source "$PLUGIN_AVAILABLE_PATH/docker-options/functions"
|
|
fi
|
|
|
|
service_connect() {
|
|
local SERVICE="$1"
|
|
local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE"
|
|
local SERVICE_NAME="$(get_service_name "$SERVICE")"
|
|
local PASSWORD="$(service_password "$SERVICE")"
|
|
local SERVICE_TTY_OPTS
|
|
has_tty && SERVICE_TTY_OPTS="-t"
|
|
|
|
"$DOCKER_BIN" container exec --env=LANG=C.UTF-8 --env=LC_ALL=C.UTF-8 -i $SERVICE_TTY_OPTS "$SERVICE_NAME" redis-cli -a "$PASSWORD"
|
|
}
|
|
|
|
service_create() {
|
|
local SERVICE="$1"
|
|
is_valid_service_name "$SERVICE" || dokku_log_fail "Please specify a valid name for the service. Valid characters are: [A-Za-z0-9_]+"
|
|
[[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service"
|
|
[[ ! -d "$PLUGIN_DATA_ROOT/$SERVICE" ]] || dokku_log_fail "$PLUGIN_SERVICE service $SERVICE already exists"
|
|
SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE"
|
|
LINKS_FILE="$SERVICE_ROOT/LINKS"
|
|
|
|
service_parse_args "${@:2}"
|
|
|
|
if ! service_image_exists "$SERVICE"; then
|
|
if [[ "$PLUGIN_DISABLE_PULL" == "true" ]]; then
|
|
dokku_log_warn "${PLUGIN_DISABLE_PULL_VARIABLE} environment variable detected. Not running pull command." 1>&2
|
|
dokku_log_warn " docker image pull ${IMAGE}" 1>&2
|
|
dokku_log_warn "$PLUGIN_SERVICE service creation failed"
|
|
exit 1
|
|
fi
|
|
"$DOCKER_BIN" image pull "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION" || dokku_log_fail "$PLUGIN_SERVICE image $PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION pull failed"
|
|
fi
|
|
|
|
plugn trigger service-action pre-create "$PLUGIN_COMMAND_PREFIX" "$SERVICE"
|
|
mkdir -p "$SERVICE_ROOT" || dokku_log_fail "Unable to create service directory"
|
|
mkdir -p "$SERVICE_ROOT/data" || dokku_log_fail "Unable to create service data directory"
|
|
mkdir -p "$SERVICE_ROOT/$PLUGIN_CONFIG_SUFFIX" || dokku_log_fail "Unable to create service config directory"
|
|
touch "$LINKS_FILE"
|
|
|
|
if [[ -z $REDIS_CONFIG_PATH ]]; then
|
|
curl -sSL "https://raw.githubusercontent.com/antirez/redis/${PLUGIN_IMAGE_VERSION:0:3}/redis.conf" >"$SERVICE_ROOT/$PLUGIN_CONFIG_SUFFIX/redis.conf" || dokku_log_fail "Unable to download the default redis.conf to the config directory"
|
|
else
|
|
cp "$REDIS_CONFIG_PATH" "$SERVICE_ROOT/$PLUGIN_CONFIG_SUFFIX/redis.conf" || dokku_log_fail "Unable to copy the ${REDIS_CONFIG_PATH} to the config directory"
|
|
fi
|
|
PASSWORD=$(openssl rand -hex 32)
|
|
if [[ -n "$SERVICE_PASSWORD" ]]; then
|
|
PASSWORD="$SERVICE_PASSWORD"
|
|
dokku_log_warn "Specified password may not be as secure as the auto-generated password"
|
|
fi
|
|
echo "$PASSWORD" >"$SERVICE_ROOT/PASSWORD"
|
|
chmod 640 "$SERVICE_ROOT/PASSWORD"
|
|
sed -i.bak "s/# requirepass.*/requirepass ${PASSWORD}/" "$SERVICE_ROOT/$PLUGIN_CONFIG_SUFFIX/redis.conf" && rm "$SERVICE_ROOT/$PLUGIN_CONFIG_SUFFIX/redis.conf.bak"
|
|
|
|
service_commit_config "$SERVICE"
|
|
write_database_name "$SERVICE"
|
|
plugn trigger service-action post-create "$PLUGIN_COMMAND_PREFIX" "$SERVICE"
|
|
service_create_container "$SERVICE"
|
|
plugn trigger service-action post-create-complete "$PLUGIN_COMMAND_PREFIX" "$SERVICE"
|
|
}
|
|
|
|
service_create_container() {
|
|
local SERVICE="$1"
|
|
local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE"
|
|
local SERVICE_HOST_ROOT="$PLUGIN_DATA_HOST_ROOT/$SERVICE"
|
|
local SERVICE_NAME="$(get_service_name "$SERVICE")"
|
|
|
|
if [[ -f "$SERVICE_ROOT/CONFIG_OPTIONS" ]]; then
|
|
export CONFIG_OPTIONS="$(cat "$SERVICE_ROOT/CONFIG_OPTIONS")"
|
|
fi
|
|
|
|
rm -f "$SERVICE_ROOT/ID"
|
|
declare -a DOCKER_ARGS
|
|
DOCKER_ARGS=()
|
|
DOCKER_ARGS+=("--cidfile=$SERVICE_ROOT/ID")
|
|
DOCKER_ARGS+=("--env-file=$SERVICE_ROOT/ENV")
|
|
DOCKER_ARGS+=("--hostname=$SERVICE_NAME")
|
|
DOCKER_ARGS+=("--label=dokku.service=$PLUGIN_COMMAND_PREFIX")
|
|
DOCKER_ARGS+=("--label=dokku=service")
|
|
DOCKER_ARGS+=("--name=$SERVICE_NAME")
|
|
DOCKER_ARGS+=("--restart=always")
|
|
DOCKER_ARGS+=("--volume=$SERVICE_HOST_ROOT/$PLUGIN_CONFIG_SUFFIX:/usr/local/etc/redis")
|
|
DOCKER_ARGS+=("--volume=$SERVICE_HOST_ROOT/data:/data")
|
|
|
|
declare -a LINK_CONTAINER_DOCKER_ARGS
|
|
LINK_CONTAINER_DOCKER_ARGS=()
|
|
LINK_CONTAINER_DOCKER_ARGS+=("--rm")
|
|
LINK_CONTAINER_DOCKER_ARGS+=("--link")
|
|
LINK_CONTAINER_DOCKER_ARGS+=("$SERVICE_NAME:$PLUGIN_COMMAND_PREFIX")
|
|
|
|
[[ -f "$SERVICE_ROOT/SERVICE_MEMORY" ]] && SERVICE_MEMORY="$(cat "$SERVICE_ROOT/SERVICE_MEMORY")"
|
|
if [[ -n "$SERVICE_MEMORY" ]]; then
|
|
DOCKER_ARGS+=("--memory=${SERVICE_MEMORY}m")
|
|
fi
|
|
|
|
[[ -f "$SERVICE_ROOT/SHM_SIZE" ]] && SERVICE_SHM_SIZE="$(cat "$SERVICE_ROOT/SHM_SIZE")"
|
|
if [[ -n "$SERVICE_SHM_SIZE" ]]; then
|
|
DOCKER_ARGS+=("--shm-size=${SERVICE_SHM_SIZE}")
|
|
fi
|
|
|
|
[[ -f "$SERVICE_ROOT/IMAGE" ]] && PLUGIN_IMAGE="$(cat "$SERVICE_ROOT/IMAGE")"
|
|
[[ -f "$SERVICE_ROOT/IMAGE_VERSION" ]] && PLUGIN_IMAGE_VERSION="$(cat "$SERVICE_ROOT/IMAGE_VERSION")"
|
|
|
|
local network_alias="$SERVICE_NAME"
|
|
local network="$(fn-plugin-property-get "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "initial-network")"
|
|
if [[ -n "$network" ]]; then
|
|
network_alias="dokku-$PLUGIN_COMMAND_PREFIX-$(get_database_name "$SERVICE")"
|
|
DOCKER_ARGS+=("--network=${network}")
|
|
DOCKER_ARGS+=("--network-alias=${network_alias}")
|
|
LINK_CONTAINER_DOCKER_ARGS+=("--network=${network}")
|
|
fi
|
|
|
|
# shellcheck disable=SC2086
|
|
suppress_output "$DOCKER_BIN" container create "${DOCKER_ARGS[@]}" "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION" redis-server /usr/local/etc/redis/redis.conf --bind 0.0.0.0 $CONFIG_OPTIONS
|
|
|
|
if [[ -n "$(fn-plugin-property-get "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "post-create-network")" ]]; then
|
|
dokku_log_verbose_quiet "Connecting to networks after container create"
|
|
while read -r line || [[ -n "$line" ]]; do
|
|
dokku_log_verbose_quiet "- $line"
|
|
"$DOCKER_BIN" network connect --alias "dokku-$PLUGIN_COMMAND_PREFIX-$(get_database_name "$SERVICE")" "$line" "$SERVICE_NAME"
|
|
done < <(fn-plugin-property-get "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "post-create-network" | tr "," "\n")
|
|
fi
|
|
suppress_output "$DOCKER_BIN" container start "$(cat "$SERVICE_ROOT/ID")"
|
|
if [[ -n "$(fn-plugin-property-get "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "post-start-network")" ]]; then
|
|
dokku_log_verbose_quiet "Connecting to networks after container start"
|
|
while read -r line || [[ -n "$line" ]]; do
|
|
dokku_log_verbose_quiet "- $line"
|
|
"$DOCKER_BIN" network connect --alias "dokku-$PLUGIN_COMMAND_PREFIX-$(get_database_name "$SERVICE")" "$line" "$SERVICE_NAME"
|
|
done < <(fn-plugin-property-get "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "post-start-network" | tr "," "\n")
|
|
fi
|
|
|
|
dokku_log_verbose_quiet "Waiting for container to be ready"
|
|
if ! suppress_output "$DOCKER_BIN" container run "${LINK_CONTAINER_DOCKER_ARGS[@]}" "$PLUGIN_WAIT_IMAGE" -c "$network_alias:$PLUGIN_DATASTORE_WAIT_PORT"; then
|
|
dokku_log_info2_quiet "Start of $SERVICE container output"
|
|
dokku_container_log_verbose_quiet "$SERVICE_NAME"
|
|
dokku_log_info2_quiet "End of $SERVICE container output"
|
|
return 1
|
|
fi
|
|
|
|
dokku_log_info2 "$PLUGIN_SERVICE container created: $SERVICE"
|
|
service_info "$SERVICE"
|
|
}
|
|
|
|
service_export() {
|
|
local SERVICE="$1"
|
|
local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE"
|
|
local SERVICE_NAME="$(get_service_name "$SERVICE")"
|
|
local PASSWORD="$(service_password "$SERVICE")"
|
|
|
|
[[ -n $SSH_TTY ]] && stty -opost
|
|
LASTSAVE1=$("$DOCKER_BIN" container exec "$SERVICE_NAME" bash -c "echo LASTSAVE | redis-cli -a ${PASSWORD}")
|
|
"$DOCKER_BIN" container exec "$SERVICE_NAME" bash -c "echo BGSAVE | redis-cli -a ${PASSWORD}" >/dev/null 2>&1
|
|
LASTSAVE2=$("$DOCKER_BIN" container exec "$SERVICE_NAME" bash -c "echo LASTSAVE | redis-cli -a ${PASSWORD}")
|
|
|
|
until [[ "$LASTSAVE1" != "$LASTSAVE2" ]]; do
|
|
LASTSAVE2=$("$DOCKER_BIN" container exec "$SERVICE_NAME" bash -c "echo LASTSAVE | redis-cli -a ${PASSWORD}")
|
|
sleep 5
|
|
done
|
|
|
|
"$DOCKER_BIN" container exec "$SERVICE_NAME" cat /data/dump.rdb
|
|
status=$?
|
|
[[ -n $SSH_TTY ]] && stty opost
|
|
exit $status
|
|
}
|
|
|
|
service_import() {
|
|
local SERVICE="$1"
|
|
SERVICE_HOST_ROOT="$PLUGIN_DATA_HOST_ROOT/$SERVICE"
|
|
SERVICE_NAME="$(get_service_name "$SERVICE")"
|
|
|
|
if [[ -t 0 ]]; then
|
|
dokku_log_fail "No data provided on stdin."
|
|
fi
|
|
suppress_output service_container_rm "$SERVICE"
|
|
"$DOCKER_BIN" container run --rm -v "$SERVICE_HOST_ROOT/data:/data" "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION" bash -c "rm -f /data/dump.rdb"
|
|
cat > "$SERVICE_HOST_ROOT/data/dump.rdb"
|
|
"$DOCKER_BIN" container run --rm -v "$SERVICE_HOST_ROOT/data:/data" "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION" bash -c "chown redis: /data/dump.rdb"
|
|
suppress_output service_start "$SERVICE"
|
|
}
|
|
|
|
service_start() {
|
|
local SERVICE="$1"
|
|
local QUIET="$2"
|
|
local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE"
|
|
local SERVICE_NAME="$(get_service_name "$SERVICE")"
|
|
local ID=$("$DOCKER_BIN" container ps -aq --no-trunc --filter "status=running" --filter "name=^/$SERVICE_NAME$" --format '{{ .ID }}') || true
|
|
if [[ -n $ID ]]; then
|
|
[[ -z $QUIET ]] && dokku_log_warn "Service is already started"
|
|
if [[ ! -f "$SERVICE_ROOT/ID" ]] || [[ "$(cat "$SERVICE_ROOT/ID")" != "$ID" ]]; then
|
|
[[ -z $QUIET ]] && dokku_log_warn "Updating local container ID"
|
|
echo "$ID" >"$SERVICE_ROOT/ID"
|
|
fi
|
|
return 0
|
|
fi
|
|
|
|
dokku_log_info2_quiet "Starting container"
|
|
local PREVIOUS_ID=$("$DOCKER_BIN" container ps -aq --no-trunc --filter "status=exited" --filter "name=^/$SERVICE_NAME$" --format '{{ .ID }}') || true
|
|
|
|
if [[ -n $PREVIOUS_ID ]]; then
|
|
"$DOCKER_BIN" container start "$PREVIOUS_ID" >/dev/null
|
|
service_port_unpause "$SERVICE"
|
|
dokku_log_info2 "Container started"
|
|
elif service_image_exists "$SERVICE"; then
|
|
service_create_container "$SERVICE"
|
|
else
|
|
if ! service_image_exists "$SERVICE"; then
|
|
[[ -f "$SERVICE_ROOT/IMAGE" ]] && PLUGIN_IMAGE="$(cat "$SERVICE_ROOT/IMAGE")"
|
|
[[ -f "$SERVICE_ROOT/IMAGE_VERSION" ]] && PLUGIN_IMAGE_VERSION="$(cat "$SERVICE_ROOT/IMAGE_VERSION")"
|
|
dokku_log_verbose_quiet "Missing image $PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION for $SERVICE"
|
|
else
|
|
dokku_log_verbose_quiet "Neither container nor valid configuration exists for $SERVICE"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
service_url() {
|
|
local SERVICE="$1"
|
|
local PASSWORD="$(service_password "$SERVICE")"
|
|
local SERVICE_DNS_HOSTNAME="$(service_dns_hostname "$SERVICE")"
|
|
echo "$PLUGIN_SCHEME://:$PASSWORD@$SERVICE_DNS_HOSTNAME:${PLUGIN_DATASTORE_PORTS[0]}"
|
|
}
|