Comment ne pas «tirer et oublier» lors d'un déclenchement à distance d'une génération Jenkins?

13

J'essaie de déclencher une génération Jenkins paramétrée à partir de Bamboo, en procédant comme suit:

PUBLIER - http://jenkins-url.com/job/jobname/buildWithParameters?ENVIRONMENT=dev&APPLICATION=hello-world

Mais j'obtiendrai un 201 instantanément qui me dit que la construction a été créée. Comment puis-je faire attendre cette demande et renvoyer le statut de réussite de la génération au lieu de l'incendie et oublier?

Il est apparemment possible selon le plugin paramétré de déclenchement à distance :

entrez la description de l'image ici

Edit: créé cela à la fin si vous en avez besoin. https://github.com/owenmorgan/jenkins-remote-builder

osmorgan
la source

Réponses:

5

Lors de la configuration du déclencheur distant, vous devez cliquer sur "Bloquer jusqu'à ce que les projets déclenchés à distance terminent leurs builds".

Travail paramétré à distance

Travis Thompson
la source
merci, j'ai peut-être la mauvaise extrémité du stick .. ce plug-in semble être pour déclencher des builds à distance à partir de jenkins lui-même? Dans mon scénario, la génération est déclenchée à partir d'une demande de Bamboo, mais nous aimerions que cette demande soit maintenue jusqu'à la fin de la génération et retourne l'état de la génération.
osmorgan
Ah, je comprends maintenant. Malheureusement, je ne pense pas que l'API fonctionne de cette façon, si vous regardez comment ce plugin pour Jenkins est développé, vous verrez qu'il déclenche le travail à distance, puis interroge l'état jusqu'à ce qu'il soit terminé.
Travis Thompson
1
Merci, j'ai fini par faire ce github.com/owenmorgan/jenkins-remote-builder
osmorgan
1
@osmorgan: vous devez décrire cela dans une réponse (avec un peu de résumé, pas seulement le lien) et l'accepter.
Dan Cornilescu
sheesh .. c'est dans la question .. et il y a une description dans le lien. rendez-vous à stackoverflow.
osmorgan
5

J'ai créé le script jenkins-remote-builder qui suivra votre compilation à distance jusqu'à son terme.

Quelques détails supplémentaires (à partir de son fichier README.md ):

Exemple

jenkins=https://user:[email protected]:8080
jenkins_job=MyApp-Deploy

environment=dev
application=myapp
revision=9fd71f63b351b8208264daf86d292ced580a2f60

./jenkins_remote_trigger.sh \
            -h ${jenkins} \
            -j ${jenkins_job} \
            -p "ENVIRONMENT=${environment}&APPLICATION=${application}&REVISION=${revision}"

Usage:

-h HOST     | --host=HOST                       Jenkins host
-j JOBNAME  | --jobname=test-build-job          The name of the jenkins job to trigger
-p JOBPARAM | --jobparam=environment=uat&test=1 Jenkins job paramiters
-q          | --quiet                           Don't output any status messages
osmorgan
la source
4
Un petit résumé sur la façon dont cela fonctionne serait mieux;)
Tensibai
Veuillez revoir la modification que j'ai appliquée à votre (intéressante!) Réponse, mais qui, je pense, avait un risque d'être supprimée (via la modération) car il s'agissait à peu près d'une réponse uniquement liée à un lien (comme l'indique en quelque sorte le commentaire de @Tensibai également ).
Pierre.Vriens
1

Si vous devez déclencher un travail à partir de CLI et attendre sa fin, vous pouvez utiliser "Jenkins CLI" (voir ici ).

Cependant, jenkins CLI ne prend pas en charge les promotions. Pour eux, j'ai proposé le script suivant:

#!/bin/bash
# Trigger a promotion and wait for its completion
#
# For triggering jobs jenkins cli is sufficient: https://support.cloudbees.com/hc/en-us/articles/228392127-How-to-wait-for-build-to-finish-when-triggering-from-CLI-
#
# The script is dependent on the current jenkins implementation of:
# - the promotion web page (links for triggering/re-executing the promotions)
# - the behaviour of the XML of the promotion status
#
# The behaviour of the job run status XML is:
#   - if the the promotion is not yet been triggered than the response is 404 not found
#   - is the the promotion has been triggered
#     - ... but it's still waiting for an executor:  the response is 404 not found or <duration> is empty
#     - ... and has started:                         <duration> is empty or 0
#     - ... and it's finished:                       <duration> is a non-zero number
#
#
#  run syntax:
#    ./trigger_promotion_and_wait_for_completion.sh \
#       <job_name> \
#       <job_run_number_to_promote> \
#       <promotion_name> \
#       <jenkins_user> \
#       <jenkins_pwd> \
#       <jenkins_url> \
#       <script_workspace_folder> \
#       '{"name": "prom_param_1", "value": "stringvalue" } , {"name": "prom_param_2", "value": true }'
#
#   example:
#    ./trigger_promotion_and_wait_for_completion.sh \
#       job1 \
#       22 \
#       promotion1 \
#       admin \
#       password \
#       http://localhost:8080/jenkins/ \
#       . \
#       '{"name": "prom_param_1", "value": "stringvalue" } , {"name": "prom_param_2", "value": true }'



set -uexo pipefail

#other debug options:
#PS4='+\t '
#set -v

JOB_NAME="${1}"
JOB_RUN_NUMBER="${2}"
DEPLOY_PROMOTION_NAME="${3}"
BUILDER_USER="${4}"
BUILDER_PASSWORD="${5}"
JENKINS_URL="${6}"
WORKSPACE_FOLDER="${7}"
PROMOTION_ARGUMENTS="${8}"

TIMEOUT=900


echo "retrieving the promotion nextBuildNumber (so we can poll the promotion status and check if it's finished)..."
PROMOTION_RUN_NUMBER="$( curl -s  -u${BUILDER_USER}:${BUILDER_PASSWORD} "${JENKINS_URL}job/${JOB_NAME}/promotion/process/${DEPLOY_PROMOTION_NAME}/api/xml"  | grep -P  '<nextBuildNumber>(.*)</nextBuildNumber'   | sed -re 's/.*<nextBuildNumber>(.*)<\/nextBuildNumber.*/\1/g' )"




echo "running the promotion..."
echo 'only the first promotion can be triggered with "Approve", while subsequent promotions are triggered with "Re-execute promotion"'
echo 'so we check in the web page if the approve link is present'

#the link to search in the web page
PROMOTION_APPROVE_STRING="promotionProcess/${DEPLOY_PROMOTION_NAME}/promotionCondition/hudson.plugins.promoted_builds.conditions.ManualCondition/approve"

PROM_STATUS_URL="${JENKINS_URL}job/${JOB_NAME}/${JOB_RUN_NUMBER}/promotion/"

if curl -s -vvv -u${BUILDER_USER}:${BUILDER_PASSWORD}  "${PROM_STATUS_URL}" | grep "${PROMOTION_APPROVE_STRING}" ; then
    echo "The job has not yet been promoted, triggering it with 'Approve'"
    WEB_PATH="job/${JOB_NAME}/${JOB_RUN_NUMBER}/promotion/promotionProcess/${DEPLOY_PROMOTION_NAME}/promotionCondition/hudson.plugins.promoted_builds.conditions.ManualCondition/approve"
    SUBMIT="Approve"
else
    echo "The job has already been promoted, triggering it with 'Re-execute promotion'"
    WEB_PATH="job/${JOB_NAME}/${JOB_RUN_NUMBER}/promotion/${DEPLOY_PROMOTION_NAME}/build"
    SUBMIT="Re-execute+promotion"
fi


#note for the troubleshooting: in case the following curl fails then the error cause can be found near the string "stack trace"
CURL_OUTPUT="$(  curl -s -vvv -XPOST -u${BUILDER_USER}:${BUILDER_PASSWORD} "${JENKINS_URL}${WEB_PATH}"  \
                       --data 'json={
                                 "parameter": [
                                                '"${PROMOTION_ARGUMENTS}"'
                                              ]
                                    }&Submit='"${SUBMIT}" 2>&1 )"

if ( echo "${CURL_OUTPUT}" |  grep -P "< HTTP/1.1 5\d\d" ) || ( echo "${CURL_OUTPUT}" |  grep -P "< HTTP/1.1 4\d\d" ) ; then
  echo  'error in triggering the job/promotion! exiting...'
  exit 1
else
  echo  'curl good'
fi



echo "checking promotion status until promotion is finished"
FINISHED=no


INITIAL_TIME="$(date +%s)"
while [ "${FINISHED}" != "ok" ]
do
    sleep 2


    #checking if promotion is finished (we check the value of <duration> XML element in the job run status)
    ERROR="" ; DURATION="$(curl -s  -u${BUILDER_USER}:${BUILDER_PASSWORD} "${JENKINS_URL}job/${JOB_NAME}/${JOB_RUN_NUMBER}/promotion/${DEPLOY_PROMOTION_NAME}/promotionBuild/${PROMOTION_RUN_NUMBER}/api/xml"    | grep -Po  '<duration>.*</duration>'   | sed -re  's/<duration>(.*)<\/duration>/\1/g' )"   || ERROR="yes"
    if [[ $ERROR == "yes" ]] ; then
      echo " the promotion has been queued but not yet started, waiting for it to start..."
      curl -s  -u${BUILDER_USER}:${BUILDER_PASSWORD} "${JENKINS_URL}job/${JOB_NAME}/${JOB_RUN_NUMBER}/promotion/${DEPLOY_PROMOTION_NAME}/promotionBuild/${PROMOTION_RUN_NUMBER}/api/xml"
      ERROR=""
      continue
    fi  ;   ERROR=""




    #we interrupt the polling of the job/promotion status if the promotion
    #  - is terminated
    #  - is taking too long (there is some problem)
    #(in the XML of the job run status the <duration> XML element value is initially empty, than it is 0, and eventually is the number of seconds of the run duration )

    POLLING_TIME="$(date +%s)"
    let "ELAPSED_TIME=POLLING_TIME-INITIAL_TIME"
    echo "ELAPSED_TIME=${ELAPSED_TIME}"

    if  (( ${ELAPSED_TIME} \> $TIMEOUT ))  ; then
      echo "error: the promotion has taken too long... exiting"
      exit 1
    fi

    if  [[ "${DURATION}" != "" ]] ; then
      re='^[0-9]+$'
      if [[ $DURATION =~ $re ]] ; then
        if (( "${DURATION}" \> "0" )) ; then
          FINISHED=ok
        else
          : #do nothing (the value of <duration> is 0 , that is the job/promotion has been started in a slave and is still running)
        fi
      else
        echo "error: the promotion duration is not a number. exiting..."
        exit 1
      fi
    else
      :  # the job/promotion has not yet started
    fi

    echo "waiting for the promotion to finish..."
done

echo "Promotion finished"



echo "Promotion output:"
curl -s  -u${BUILDER_USER}:${BUILDER_PASSWORD} "${JENKINS_URL}job/${JOB_NAME}/${JOB_RUN_NUMBER}/promotion/${DEPLOY_PROMOTION_NAME}/promotionBuild/${PROMOTION_RUN_NUMBER}/consoleText" > ${WORKSPACE_FOLDER}/promotionOutput

cat ${WORKSPACE_FOLDER}/promotionOutput

if [[ ! "$(tail -n1 ${WORKSPACE_FOLDER}/promotionOutput)" =~ "SUCCESS"  ]] ; then
      echo "Promotion did not successfully terminate"
      exit 1
else
      echo "Promotion successfully terminated"
fi
Giuliano
la source