Commit e66faafe authored by Pedro Eduardo Trujillo's avatar Pedro Eduardo Trujillo
Browse files

Reescribe script relaunch

Revisa la lógica del script relaunch en profundidad, dividiendo el
código en diferentes ficheros y añadiendo detalles antes pasados por
alto, como respetar el ajuste de SWARM_RESOLVE_IMAGE a la hora de
aplicar el comando 'service update'.

Usa credenciales de registry de forma segura, como ya se hacía en
deploy.

Mejora la expresividad con nueva salida por consola.
parent a7431375
Loading
Loading
Loading
Loading
+47 −3
Original line number Diff line number Diff line
@@ -10,6 +10,14 @@ You can use it to deploy your own services, supporting **Docker Compose** (both

  Perform a service deployment at a Docker environment. Contains several stages:

  1. **definitions**:

     Set initial configuration values, getting environment values and with local defaults as fallback. Also prints the initial banner.

  1. **ssh-config**:

     Prepare connection to deployment target host environment. Set connection options, add identity and define functions to run commands at target.

  1. **check-env**:

     Check dependencies, version requirements and available modes at deployment target host environment.
@@ -42,6 +50,14 @@ You can use it to deploy your own services, supporting **Docker Compose** (both

  Prepare deployment target host environment creating Docker networks which are external to service definition. A network is external when it's not created by service deployment itself, because is defined as *external* in compose files. Contains several stages:

  1. **definitions**:

     Set initial configuration values, getting environment values and with local defaults as fallback. Also prints the initial banner.

  1. **ssh-config**:

     Prepare connection to deployment target host environment. Set connection options, add identity and define functions to run commands at target.

  1. **check-env**:

     Check dependencies, version requirements and available modes at deployment target host environment.
@@ -52,7 +68,35 @@ You can use it to deploy your own services, supporting **Docker Compose** (both

* **relaunch**:

  Force a previously deployed service to update, relaunching it with the same service configuration. Available only for *Swarm* mode.
  Force a previously deployed service to update, relaunching it with the same service configuration. Available only for *Swarm* mode. Contains several stages:

  1. **definitions**:

     Set initial configuration values, getting environment values and with local defaults as fallback. Also prints the initial banner.

  1. **ssh-config**:

     Prepare connection to deployment target host environment. Set connection options, add identity and define functions to run commands at target.

  1. **check-env**:

     Check dependencies, version requirements and available modes at deployment target host environment.

  1. **prepare-relaunch**:

     Obtain single service name to relaunch, because `SERVICE` value might be a prefix for several service names. Check if service exists at deployment target host environment.

  1. **prepare-registry**:

     Only when using `USE_IMAGE_DIGEST=1`. Perform login to registry when using credentials, to be able to get updated images.

  1. **prepare-digest**:

     Only when using `USE_IMAGE_DIGEST=1`. Before relaunching service, get updated image and its current digest data.

  1. **do-relaunch**:

     Run service relaunch at deployment target host environment.

## Usage

@@ -123,8 +167,8 @@ You may define these environment variables (**bold** are mandatory):
| *STATUS_CHECK_INTERVAL* | `20` | Seconds to wait between check iterations. |
| *STATUS_CHECK_MIN_HITS* | `3` | Minimum number of successful checks to consider deployment as successful. |
| *STATUS_CHECK_RETRIES* | `10` | Maximum number of checks before considering deployment as failed. |
| *SWARM_RESOLVE_IMAGE* | `always` | Allows to edit the behaviour of the registry query to resolve image digests and supported platforms (`always`, `changed` or `never`). |
| *USE_IMAGE_DIGEST* | `0` | Update service image using digest data when relaunching. Available only for *relaunch* action. |
| *SWARM_RESOLVE_IMAGE* | `always` | Allows to edit the behaviour of *deploy* and *relaunch* actions when querying registry, to resolve image digests and supported platforms or not. Supported values are `always`, `changed` or `never`. |
| *USE_IMAGE_DIGEST* | `0` | Update service image using digest data when relaunching. Useful when using images which receive updates under same tag and want to keep them updated with same version on all nodes. Available only for *relaunch* action. |

### Your services

script/_do-relaunch.sh

0 → 100755
+14 −0
Original line number Diff line number Diff line
#!/bin/sh

relaunchCmd="docker service update -q --force \
	${serviceUpdateAdditionalArgs} \
	${serviceToRelaunch}"

if runRemoteCmd "${relaunchCmd}"
then
	echo -e "\n${PASS_COLOR}Service ${DATA_COLOR}${serviceToRelaunch}${PASS_COLOR} relaunched successfully!${NULL_COLOR}"
else
	echo -e "\n${FAIL_COLOR}Service ${DATA_COLOR}${serviceToRelaunch}${FAIL_COLOR} relaunch failed!${NULL_COLOR}"
	eval "${closeSshCmd}"
	exit 1
fi
+32 −0
Original line number Diff line number Diff line
#!/bin/sh

echo -e "\n${INFO_COLOR}Using digest data to obtain updated image for relaunch ..${NULL_COLOR}"

getServiceImageCmd="docker service ls -f 'name=${serviceToRelaunch}' --format '{{.Image}}' | cut -d '@' -f 1"
serviceImageNameAndTag=$(runRemoteCmd "${getServiceImageCmd}")

if [ -z "${serviceImageNameAndTag}" ]
then
	echo -e "\n${FAIL_COLOR}Service image not found, needed to relaunch service using image digest!${NULL_COLOR}"
	eval "${closeSshCmd}"
	exit 1
fi

# Se obtiene la imagen actualizada.
getUpdatedServiceImageCmd="docker pull ${serviceImageNameAndTag}"

if runRemoteCmd "${getUpdatedServiceImageCmd}"
then
	echo -e "\n${PASS_COLOR}Image updated successfully!${NULL_COLOR}"
else
	echo -e "\n${FAIL_COLOR}Image update failed!${NULL_COLOR}"
fi

serviceImageName=$(echo "${serviceImageNameAndTag}" | cut -d ':' -f 1)

# Se obtiene el valor de digest de la imagen actualizada.
getServiceImageDigestCmd="docker images --digests --format '{{.Digest}}' ${serviceImageName})"
serviceImageDigest=$(runRemoteCmd "${getServiceImageDigestCmd}")

# Prepara variable usada desde el script principal
serviceUpdateAdditionalArgs="${serviceUpdateAdditionalArgs} --image ${serviceImageName}@${serviceImageDigest}"
+59 −0
Original line number Diff line number Diff line
#!/bin/sh

# Si existen credenciales para registry, se usan de manera segura.
if [ ! -z "${REGISTRY_USER}" ]
then
	serviceUpdateAdditionalArgs="${serviceUpdateAdditionalArgs} --with-registry-auth"

	echo -e "\n${INFO_COLOR}Login to registry ${DATA_COLOR}${REGISTRY_URL:-<default>}${INFO_COLOR} ..${NULL_COLOR}\n"

	# Se prepara la ruta de trabajo.
	randomValue="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)"
	relaunchHome="${DEPLOY_PATH}/docker-deploy/${randomValue}"
	createDirCmd="mkdir -p ${deployHome}"

	if ! runRemoteCmd "${createDirCmd}"
	then
		echo -e "${FAIL_COLOR}Relaunch path ${DATA_COLOR}${relaunchHome}${FAIL_COLOR} creation failed!${NULL_COLOR}"
		eval "${closeSshCmd}"
		exit 1
	fi

	# Se preparan las credenciales de forma segura.
	relaunchEnvFile=".env-relaunch"
	ddRegistryPassVarName=DOCKER_DEPLOY_REGISTRY_PASS
	moveToRelaunchDirCmd="cd ${relaunchHome} && "

	echo -e "${ddRegistryPassVarName}=${REGISTRY_PASS}" > "${relaunchEnvFile}"

	echo -e "\n${INFO_COLOR}Sending relaunch resources to host ${DATA_COLOR}${remoteHost}${INFO_COLOR} ..${NULL_COLOR}"
	echo -e "  ${INFO_COLOR}relaunch path [ ${DATA_COLOR}${relaunchHome}${INFO_COLOR} ]${NULL_COLOR}"

	if scp ${SSH_PARAMS} "${relaunchEnvFile}" "${SSH_REMOTE}:${relaunchHome}"
	then
		echo -e "\n${PASS_COLOR}Relaunch resources successfully sent!${NULL_COLOR}"
	else
		echo -e "\n${FAIL_COLOR}Relaunch resources sending failed!${NULL_COLOR}"
		eval "${closeSshCmd}"
		exit 1
	fi

	# Se realiza la identificación en el registry.
	loginCmd="\
		${GREP_BIN} \"^${ddRegistryPassVarName}=\" \"${relaunchEnvFile}\" | cut -d '=' -f 2- | \
		docker login -u \"${REGISTRY_USER}\" --password-stdin ${REGISTRY_URL}"

	if runRemoteCmd "${moveToRelaunchDirCmd}${loginCmd}"
	then
		echo -e "\n${PASS_COLOR}Login to registry was successful!${NULL_COLOR}"
	else
		echo -e "\n${FAIL_COLOR}Login to registry failed!${NULL_COLOR}"
	fi

	# Se limpian ficheros de credenciales.
	rmRelaunchEnvFileCmd="rm -f ${relaunchEnvFile}"
	eval "${rmRelaunchEnvFileCmd}"
	runRemoteCmd "${moveToRelaunchDirCmd}${rmRelaunchEnvFileCmd}"
else
	echo -e "\n${INFO_COLOR}Omitting login to registry${NULL_COLOR}"
fi
+27 −0
Original line number Diff line number Diff line
#!/bin/sh

servicesFoundByName=$(runRemoteCmd "docker service ls -f 'name=${SERVICE}' --format '{{.Name}}'")
servicesSeparatorCount=$(echo "${servicesFoundByName}" | grep -c ' ')

if [ "${servicesSeparatorCount}" -ne 0 ]
then
	serviceToRelaunch=$(echo "${servicesFoundByName}" | cut -d ' ' -f 1)

	echo -e "\n${INFO_COLOR}Found more than one service filtering by name ${DATA_COLOR}${SERVICE}${INFO_COLOR} ..${NULL_COLOR}"
	echo -e "  ${INFO_COLOR}services [ ${DATA_COLOR}${servicesFoundByName}${INFO_COLOR} ]${NULL_COLOR}"
	echo -e "  ${INFO_COLOR}will relaunch only ${DATA_COLOR}${serviceToRelaunch}${INFO_COLOR} service${NULL_COLOR}"
else
	serviceToRelaunch="${SERVICE}"
fi

if [ -z "${serviceToRelaunch}" ]
then
	echo -e "\n${FAIL_COLOR}Service to relaunch not found at remote!${NULL_COLOR}"
	eval "${closeSshCmd}"
	exit 1
fi

if [ "${SWARM_RESOLVE_IMAGE}" = "never" ]
then
	serviceUpdateAdditionalArgs="--no-resolve-image"
fi
Loading