diff --git a/docs/faq.md b/docs/faq.md index 1c1d57c..bb3e53f 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -26,7 +26,7 @@ You can start *Gantry* as a docker swarm service and use [`swarm-cronjob`](https As discussed [here](https://github.com/docker/cli/issues/627), it will lead the CLI hanging by running `docker service update` on a service with no running tasks. We must add `--detach=true` option to the `docker service update`. -*Gantry* will check if there are running tasks in a services and automatically add the option `--detach=true`. You don't need to add the option manually. +*Gantry* will check whether there are running tasks in a services. If there is no running task, *Gantry* automatically adds the option `--detach=true`. In addition to the detach option, *Gantry* also adds `--replicas=0` for services in replicated mode. You don't need to add these options manually. ### When to set `GANTRY_MANIFEST_USE_MANIFEST_CMD`? diff --git a/src/lib-gantry.sh b/src/lib-gantry.sh index 2a779ce..a10ecba 100755 --- a/src/lib-gantry.sh +++ b/src/lib-gantry.sh @@ -249,19 +249,38 @@ service_is_self() { [ "${SERVICE_NAME}" = "${SELF}" ] } +get_service_mode() { + local SERVICE_NAME="${1}" + local MODE= + if ! MODE=$(docker service ls --filter "name=${SERVICE_NAME}" --format '{{.Mode}}' 2>&1); then + log ERROR "Failed to obtain the mode of the service ${SERVICE_NAME}: ${MODE}" + return 1 + fi + echo "${MODE}" +} + # echo the mode when the service is replicated job or global job # return whether a service is replicated job or global job service_is_job() { local SERVICE_NAME="${1}" local MODE= - if ! MODE=$(docker service ls --filter "name=${SERVICE_NAME}" --format '{{.Mode}}' 2>&1); then - log ERROR "Failed to obtain the mode of the service ${SERVICE_NAME}: ${MODE}" + if ! MODE=$(get_service_mode "${SERVICE_NAME}"); then return 1 fi # Looking for replicated-job or global-job echo "${MODE}" | grep "job" } +service_is_replicated() { + local SERVICE_NAME="${1}" + local MODE= + if ! MODE=$(get_service_mode "${SERVICE_NAME}"); then + return 1 + fi + # Looking for replicated + echo "${MODE}" | grep "replicated" +} + get_config_from_service() { local SERVICE_NAME="${1}" local AUTH_CONFIG_LABEL="gantry.auth.config" @@ -344,17 +363,22 @@ get_number_of_running_tasks() { get_service_update_additional_option() { local SERVICE_NAME="${1}" - local OPTION="--detach=true" local NUM_RUNS= NUM_RUNS=$(get_number_of_running_tasks "${SERVICE_NAME}") if ! is_number "${NUM_RUNS}"; then return 1 fi + local OPTIONS= if [ "${NUM_RUNS}" -eq 0 ]; then # Add "--detach=true" when there is no running tasks. # https://github.com/docker/cli/issues/627 - echo -n "${OPTION}" + OPTIONS="${OPTIONS} --detach=true" + # Do not start a new task. Only works for replicated, not global. + if service_is_replicated "${SERVICE_NAME}"; then + OPTIONS="${OPTIONS} --replicas=0" + fi fi + echo "${OPTIONS}" } rollback_service() {