diff --git a/common-functions b/common-functions index 0b3b952..3d21ea2 100755 --- a/common-functions +++ b/common-functions @@ -810,79 +810,76 @@ service_root_password() { service_port_expose() { declare desc="wrapper for exposing service ports" - declare SERVICE="$1" - service_start "$SERVICE" "true" - service_port_unpause "$SERVICE" "true" "${@:2}" -} - -service_port_pause() { - declare desc="pause service exposure" - declare SERVICE="$1" LOG_FAIL="$2" - local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" - local EXPOSED_NAME="$(get_service_name "$SERVICE").ambassador" - local PORT_FILE="$SERVICE_ROOT/PORT" - - if [[ "$LOG_FAIL" == "true" ]]; then - [[ ! -f "$PORT_FILE" ]] && dokku_log_fail "Service not exposed" - else - [[ ! -f "$PORT_FILE" ]] && return 0 + declare SERVICE="$1" PORTS=(${@:2}) + if [[ ${#PORTS[@]} -eq 0 ]]; then + # shellcheck disable=SC2206 + PORTS=(${PORTS[@]:-$(get_random_ports ${#PLUGIN_DATASTORE_PORTS[@]})}) fi - local GREP_NAME="^/${EXPOSED_NAME}$" - local CONTAINER_NAME="$("$DOCKER_BIN" container ps -f name="$GREP_NAME" --format "{{.Names}}")" - if [[ -z "$CONTAINER_NAME" ]]; then - if [[ "$LOG_FAIL" == "true" ]]; then - dokku_log_info1 "Service $SERVICE unexposed" - fi + [[ "${#PORTS[@]}" != "${#PLUGIN_DATASTORE_PORTS[@]}" ]] && dokku_log_fail "${#PLUGIN_DATASTORE_PORTS[@]} ports to be exposed need to be provided in the following order: ${PLUGIN_DATASTORE_PORTS[*]}" - return + if [[ -s "$PORT_FILE" ]]; then + # shellcheck disable=SC2207 + PORTS=($(cat "$PORT_FILE")) + dokku_log_fail "Service $SERVICE already exposed on port(s) ${PORTS[*]}" fi - "$DOCKER_BIN" container stop "$EXPOSED_NAME" >/dev/null 2>&1 || true - "$DOCKER_BIN" container rm "$EXPOSED_NAME" >/dev/null 2>&1 || true - if [[ "$LOG_FAIL" == "true" ]]; then - dokku_log_info1 "Service $SERVICE unexposed" + if "$DOCKER_BIN" container inspect "$EXPOSED_NAME" &>/dev/null; then + dokku_log_warn "Service $SERVICE has an untracked expose container, removing" + "$DOCKER_BIN" container stop "$EXPOSED_NAME" >/dev/null 2>&1 || true + suppress_output "$DOCKER_BIN" container rm "$EXPOSED_NAME" + return $? fi + + echo "${PORTS[@]}" >"$PORT_FILE" + + service_start "$SERVICE" "true" + service_port_reconcile_status "$SERVICE" + dokku_log_info1 "Service $SERVICE exposed on port(s) [container->host]: $(service_exposed_ports "$SERVICE")" } + service_port_unexpose() { declare desc="wrapper for pausing exposed service ports" declare SERVICE="$1" local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" local PORT_FILE="$SERVICE_ROOT/PORT" - service_port_pause "$SERVICE" "true" + rm -rf "$PORT_FILE" + service_port_reconcile_status "$SERVICE" + if [[ "$LOG_FAIL" == "true" ]]; then + dokku_log_info1 "Service $SERVICE unexposed" + fi } -service_port_unpause() { - declare desc="start service exposure" - declare SERVICE="$1" LOG_FAIL="$2" +service_port_reconcile_status() { + declare SERVICE="$1" local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" - local SERVICE_NAME="$(get_service_name "$SERVICE")" - local EXPOSED_NAME="${SERVICE_NAME}.ambassador" local PORT_FILE="$SERVICE_ROOT/PORT" - # shellcheck disable=SC2068 - local PORTS=(${@:3}) - # shellcheck disable=SC2068 - PORTS=(${PORTS[@]:-$(get_random_ports ${#PLUGIN_DATASTORE_PORTS[@]})}) - local ID=$(cat "$SERVICE_ROOT/ID") + local EXPOSED_NAME="$(get_service_name "$SERVICE").ambassador" - [[ "${#PORTS[@]}" != "${#PLUGIN_DATASTORE_PORTS[@]}" ]] && dokku_log_fail "${#PLUGIN_DATASTORE_PORTS[@]} ports to be exposed need to be provided in the following order: ${PLUGIN_DATASTORE_PORTS[*]}" + if [[ ! -s "$PORT_FILE" ]]; then + if "$DOCKER_BIN" container inspect "$EXPOSED_NAME" &>/dev/null; then + "$DOCKER_BIN" container stop "$EXPOSED_NAME" >/dev/null 2>&1 || true + suppress_output "$DOCKER_BIN" container rm "$EXPOSED_NAME" + return $? + fi + return + fi - if [[ "$LOG_FAIL" == "true" ]]; then - [[ -f "$PORT_FILE" ]] && PORTS=($(cat "$PORT_FILE")) && dokku_log_fail "Service $SERVICE already exposed on port(s) ${PORTS[*]}" - else - [[ ! -f "$PORT_FILE" ]] && return 0 - PORTS=($(cat "$PORT_FILE")) + if is_container_status "$EXPOSED_NAME" "Running"; then + return fi - echo "${PORTS[@]}" >"$PORT_FILE" + if "$DOCKER_BIN" container inspect "$EXPOSED_NAME" &>/dev/null; then + suppress_output "$DOCKER_BIN" container start "$EXPOSED_NAME" + return $? + fi + # shellcheck disable=SC2207 + PORTS=($(cat "$PORT_FILE")) # shellcheck disable=SC2046 "$DOCKER_BIN" container run -d --link "$SERVICE_NAME:$PLUGIN_COMMAND_PREFIX" --name "$EXPOSED_NAME" $(docker_ports_options "${PORTS[@]}") --restart always --label dokku=ambassador --label "dokku.ambassador=$PLUGIN_COMMAND_PREFIX" "$PLUGIN_AMBASSADOR_IMAGE" >/dev/null - if [[ "$LOG_FAIL" == "true" ]]; then - dokku_log_info1 "Service $SERVICE exposed on port(s) [container->host]: $(service_exposed_ports "$SERVICE")" - fi } service_promote() { @@ -946,7 +943,7 @@ service_pause() { if [[ -n $ID ]]; then dokku_log_info2_quiet "Pausing container" "$DOCKER_BIN" container stop "$SERVICE_NAME" >/dev/null - service_port_pause "$SERVICE" + "$DOCKER_BIN" container stop "$(get_service_name "$SERVICE").ambassador" >/dev/null dokku_log_verbose_quiet "Container paused" else dokku_log_verbose_quiet "No container exists for $SERVICE" diff --git a/functions b/functions index 39a3531..298db09 100755 --- a/functions +++ b/functions @@ -210,7 +210,7 @@ service_start() { if [[ -n $PREVIOUS_ID ]]; then "$DOCKER_BIN" container start "$PREVIOUS_ID" >/dev/null - service_port_unpause "$SERVICE" + service_port_reconcile_status "$SERVICE" dokku_log_info2 "Container started" elif service_image_exists "$SERVICE" && [[ -n "$ROOTPASSWORD" ]] && [[ -n "$PASSWORD" ]]; then service_create_container "$SERVICE" diff --git a/tests/service_expose.bats b/tests/service_expose.bats index c18cc6c..b9c03f3 100755 --- a/tests/service_expose.bats +++ b/tests/service_expose.bats @@ -2,29 +2,65 @@ load test_helper setup() { - dokku "$PLUGIN_COMMAND_PREFIX:create" l + dokku "$PLUGIN_COMMAND_PREFIX:create" ls } teardown() { - dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l + dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" ls } @test "($PLUGIN_COMMAND_PREFIX:expose) error when there are no arguments" { run dokku "$PLUGIN_COMMAND_PREFIX:expose" + echo "output: $output" + echo "status: $status" + assert_failure assert_contains "${lines[*]}" "Please specify a valid name for the service" } @test "($PLUGIN_COMMAND_PREFIX:expose) error when service does not exist" { run dokku "$PLUGIN_COMMAND_PREFIX:expose" not_existing_service + echo "output: $output" + echo "status: $status" + assert_failure assert_contains "${lines[*]}" "service not_existing_service does not exist" } +@test "($PLUGIN_COMMAND_PREFIX:expose) error when already exposed" { + run dokku "$PLUGIN_COMMAND_PREFIX:expose" ls + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:expose" ls + echo "output: $output" + echo "status: $status" + assert_failure + assert_contains "${lines[*]}" "Service ls already exposed on port(s)" + + run sudo rm /var/lib/dokku/services/$PLUGIN_COMMAND_PREFIX/ls/PORT + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:expose" ls + echo "output: $output" + echo "status: $status" + assert_success + assert_contains "${lines[*]}" "Service ls has an untracked expose container, removing" +} + @test "($PLUGIN_COMMAND_PREFIX:expose) success when not providing custom ports" { - run dokku "$PLUGIN_COMMAND_PREFIX:expose" l + run dokku "$PLUGIN_COMMAND_PREFIX:expose" ls + echo "output: $output" + echo "status: $status" + assert_success [[ "${lines[*]}" =~ exposed\ on\ port\(s\)\ \[container\-\>host\]\:\ [[:digit:]]+ ]] } @test "($PLUGIN_COMMAND_PREFIX:expose) success when providing custom ports" { - run dokku "$PLUGIN_COMMAND_PREFIX:expose" l 4242 + run dokku "$PLUGIN_COMMAND_PREFIX:expose" ls 4242 + echo "output: $output" + echo "status: $status" + assert_success assert_contains "${lines[*]}" "exposed on port(s) [container->host]: 3306->4242" }