<?xml version="1.0" encoding="UTF-8"?><project>
  <actions/>
  <description>&lt;!-- Managed by Jenkins Job Builder --&gt;</description>
  <keepDependencies>false</keepDependencies>
  <disabled>false</disabled>
  <displayName>TCWG CCC Update bmk containers</displayName>
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <concurrentBuild>true</concurrentBuild>
  <customWorkspace>workspace/tcwg-update-bmk-containers_$EXECUTOR_NUMBER/$NODE_NAME</customWorkspace>
  <assignedNode>tcwg-coordinator</assignedNode>
  <canRoam>false</canRoam>
  <properties>
    <hudson.security.AuthorizationMatrixProperty>
      <permission>hudson.model.Item.Read:anonymous</permission>
      <permission>hudson.model.Item.ExtendedRead:anonymous</permission>
      <permission>hudson.model.Item.Build:everyone-flat</permission>
      <permission>hudson.model.Item.Cancel:everyone-flat</permission>
    </hudson.security.AuthorizationMatrixProperty>
    <jenkins.model.BuildDiscarderProperty>
      <strategy class="hudson.tasks.LogRotator">
        <daysToKeep>30</daysToKeep>
        <numToKeep>100</numToKeep>
        <artifactDaysToKeep>-1</artifactDaysToKeep>
        <artifactNumToKeep>-1</artifactNumToKeep>
      </strategy>
    </jenkins.model.BuildDiscarderProperty>
    <hudson.plugins.throttleconcurrents.ThrottleJobProperty>
      <maxConcurrentPerNode>1</maxConcurrentPerNode>
      <maxConcurrentTotal>0</maxConcurrentTotal>
      <throttleEnabled>true</throttleEnabled>
      <throttleOption>project</throttleOption>
      <configVersion>1</configVersion>
      <limitOneJobWithMatchingParams>false</limitOneJobWithMatchingParams>
      <matrixOptions>
        <throttleMatrixBuilds>true</throttleMatrixBuilds>
        <throttleMatrixConfigurations>false</throttleMatrixConfigurations>
      </matrixOptions>
      <paramsToUseForLimit/>
    </hudson.plugins.throttleconcurrents.ThrottleJobProperty>
    <hudson.model.ParametersDefinitionProperty>
      <parameterDefinitions>
        <org.jvnet.jenkins.plugins.nodelabelparameter.LabelParameterDefinition>
          <name>nodes</name>
          <description>Machines to run on</description>
          <defaultValue>tcwg-bmk-pool</defaultValue>
          <allNodesMatchingLabel>true</allNodesMatchingLabel>
          <triggerIfResult>allCases</triggerIfResult>
          <nodeEligibility class="org.jvnet.jenkins.plugins.nodelabelparameter.node.AllNodeEligibility"/>
        </org.jvnet.jenkins.plugins.nodelabelparameter.LabelParameterDefinition>
        <hudson.model.StringParameterDefinition>
          <name>distro</name>
          <description>Distro version to use.</description>
          <defaultValue>default</defaultValue>
        </hudson.model.StringParameterDefinition>
        <hudson.model.BooleanParameterDefinition>
          <name>force</name>
          <description>Whether to force update even with no changes in image</description>
          <defaultValue>false</defaultValue>
        </hudson.model.BooleanParameterDefinition>
        <hudson.model.BooleanParameterDefinition>
          <name>verbose</name>
          <description>Whether to be verbose</description>
          <defaultValue>true</defaultValue>
        </hudson.model.BooleanParameterDefinition>
        <hudson.model.StringParameterDefinition>
          <name>scripts_branch</name>
          <description>Scripts revision to use</description>
          <defaultValue>master</defaultValue>
        </hudson.model.StringParameterDefinition>
      </parameterDefinitions>
    </hudson.model.ParametersDefinitionProperty>
  </properties>
  <scm class="hudson.plugins.git.GitSCM">
    <configVersion>2</configVersion>
    <userRemoteConfigs>
      <hudson.plugins.git.UserRemoteConfig>
        <name>origin</name>
        <refspec>+refs/heads/*:refs/remotes/origin/* +refs/changes/*:refs/changes/*</refspec>
        <url>https://gitlab.com/LinaroLtd/tcwg/jenkins-scripts.git</url>
      </hudson.plugins.git.UserRemoteConfig>
    </userRemoteConfigs>
    <branches>
      <hudson.plugins.git.BranchSpec>
        <name>$scripts_branch</name>
      </hudson.plugins.git.BranchSpec>
    </branches>
    <disableSubmodules>false</disableSubmodules>
    <recursiveSubmodules>false</recursiveSubmodules>
    <doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
    <remotePoll>false</remotePoll>
    <gitTool>Default</gitTool>
    <submoduleCfg class="list"/>
    <reference>/home/tcwg-buildslave/snapshots-ref/jenkins-scripts.git</reference>
    <gitConfigName/>
    <gitConfigEmail/>
    <extensions>
      <hudson.plugins.git.extensions.impl.RelativeTargetDirectory>
        <relativeTargetDir>jenkins-scripts</relativeTargetDir>
      </hudson.plugins.git.extensions.impl.RelativeTargetDirectory>
      <hudson.plugins.git.extensions.impl.CleanBeforeCheckout/>
      <hudson.plugins.git.extensions.impl.CloneOption>
        <shallow>false</shallow>
        <depth>1</depth>
        <reference>/home/tcwg-buildslave/snapshots-ref/jenkins-scripts.git</reference>
      </hudson.plugins.git.extensions.impl.CloneOption>
      <hudson.plugins.git.extensions.impl.PruneStaleBranch/>
    </extensions>
  </scm>
  <triggers class="vector">
    <hudson.triggers.TimerTrigger>
      <spec>@daily</spec>
    </hudson.triggers.TimerTrigger>
  </triggers>
  <builders>
    <hudson.tasks.Shell>
      <command>#!/bin/bash
set -ex

# See: LABEL_SED below
set -o pipefail

rm -rf artifacts
mkdir artifacts

echo "$BUILD_URL" &gt; artifacts/mail-body.txt
echo "maxim.kuvyrkov@linaro.org, laurent.alfonsi@linaro.org" &gt; artifacts/mail-recipients.txt

declare -A pids
for lock in $(set +f; ls -tr $HOME/boards/$NODE_NAME-*.lock \
                             $HOME/boards/$NODE_NAME-*.bak*); do
  (
    flock -e 9
    touch $lock
    board=$(cat &lt;&amp;9)

    # Start the jenkins container so that it can process
    # all the queued cleanup and maintenance tasks.
    node=$(basename "$board" .tcwglab)

    ./jenkins-scripts/tcwg-update-bmk-containers.sh \
      --board "$board" \
      --distro "$distro" \
      --force "$force" \
      --node "$node" \
      --verbose "$verbose"

    # Wait for jenkins container to become idle
    while sleep 60; do
      n_busy=$(source jenkins-scripts/jenkins-helpers.sh
               print_number_of_busy_executors "$node")

      if [ "$n_busy" = "0" ]; then
        break
      fi
    done

    # Now stop the jenkins container so that it's not terminated
    # midway some other build by a starting benchmarking job.
    ssh -Snone $board docker stop "$node"
  ) 9&lt;$lock 2&gt;&amp;1 | sed -e "s/^/$(basename $lock): /" &amp;

  # LABEL_SED: We need pipefail to get correct result of sub-shell
  # "( foo ) | sed" instead of always-succeeding "sed".
  pids[$(basename "$lock")]=$!
done

n_good_boards=0
for lock in "${!pids[@]}"; do
  res=0 &amp;&amp; wait "${pids[$lock]}" || res=$?
  case "$res:$lock" in
    "0":*".lock")
      n_good_boards=$(($n_good_boards + 1))
      echo "$lock: SUCCESS" &gt;&gt; artifacts/mail-body.txt
      ;;
    "0":*".bak")
      n_good_boards=$(($n_good_boards + 1))
      echo "$lock: UNEXPECTED SUCCESS" &gt;&gt; artifacts/mail-body.txt
      # Move boards with no STG ticket (e.g., no ".bak.STG-1234")
      # back into service.
      mv "$HOME/boards/$lock" "$HOME/boards/${lock%.bak}.lock"
      ;;
    "0":*)
      # The board appears fine, but it has STG ticket assigned
      # to it (e.g., ".bak.STG-1234").
      echo "$lock: UNEXPECTED SUCCESS" &gt;&gt; artifacts/mail-body.txt
      ;;
    *:*".lock")
      echo "$lock: UNEXPECTED FAILURE" &gt;&gt; artifacts/mail-body.txt
      # Move offline boards out of service.
      mv "$HOME/boards/$lock" "$HOME/boards/${lock%.lock}.bak"
      ;;
    *:*)
      echo "$lock: EXPECTED FAILURE" &gt;&gt; artifacts/mail-body.txt
      ;;
  esac
done

# tcwg-benchmark doesn't have ssh access to $JENKINS_SSH_SERVER,
# so use tcwg-buildslave's credentials.
n_executors=$(ssh -p$JENKINS_SSH_PORT -l $JENKINS_SSH_USER \
                  $JENKINS_SSH_SERVER get-node "$NODE_NAME" \
                  | grep "numExecutors")
n_executors=$(echo "$n_executors" \
              | sed -e "s#.*&lt;numExecutors&gt;\([0-9]\+\)&lt;/numExecutors&gt;.*#\1#")
if [ x"$n_executors" != x"$n_good_boards" ]; then
  echo "UNEXPECTED: Updating number of executors on $NODE_NAME from $n_executors to $n_good_boards" \
    &gt;&gt; artifacts/mail-body.txt
  if [ "$n_good_boards" = "0" ]; then
    # Setting executors to "0" will mightily confuse jenkins;
    # the node with 0 executors will be stuck in limbo.
    n_good_boards=1
  fi
  ssh -p$JENKINS_SSH_PORT -l $JENKINS_SSH_USER \
      $JENKINS_SSH_SERVER get-node "$NODE_NAME" \
    | sed -e "s#&lt;numExecutors&gt;\([0-9]\+\)&lt;/numExecutors&gt;#&lt;numExecutors&gt;$n_good_boards&lt;/numExecutors&gt;#" \
    | ssh -p$JENKINS_SSH_PORT -l $JENKINS_SSH_USER \
          $JENKINS_SSH_SERVER update-node "$NODE_NAME"
fi

if ! grep -q UNEXPECTED artifacts/mail-body.txt; then
  exit 0
fi

exit 1
</command>
      <unstableReturn>0</unstableReturn>
    </hudson.tasks.Shell>
  </builders>
  <publishers>
    <hudson.plugins.emailext.ExtendedEmailPublisher>
      <recipientList>${FILE,path="artifacts/mail-recipients.txt"}
</recipientList>
      <configuredTriggers>
        <hudson.plugins.emailext.plugins.trigger.AbortedTrigger>
          <email>
            <recipientList/>
            <subject>$PROJECT_DEFAULT_SUBJECT</subject>
            <body>$PROJECT_DEFAULT_CONTENT</body>
            <sendToDevelopers>false</sendToDevelopers>
            <sendToRequester>false</sendToRequester>
            <includeCulprits>false</includeCulprits>
            <sendToRecipientList>true</sendToRecipientList>
          </email>
        </hudson.plugins.emailext.plugins.trigger.AbortedTrigger>
        <hudson.plugins.emailext.plugins.trigger.FailureTrigger>
          <email>
            <recipientList/>
            <subject>$PROJECT_DEFAULT_SUBJECT</subject>
            <body>$PROJECT_DEFAULT_CONTENT</body>
            <sendToDevelopers>false</sendToDevelopers>
            <sendToRequester>false</sendToRequester>
            <includeCulprits>false</includeCulprits>
            <sendToRecipientList>true</sendToRecipientList>
          </email>
        </hudson.plugins.emailext.plugins.trigger.FailureTrigger>
      </configuredTriggers>
      <contentType>text/plain</contentType>
      <defaultSubject>$DEFAULT_SUBJECT</defaultSubject>
      <defaultContent>${FILE,path="artifacts/mail-body.txt"}
</defaultContent>
      <attachmentsPattern/>
      <presendScript/>
      <postsendScript/>
      <attachBuildLog>false</attachBuildLog>
      <compressBuildLog>false</compressBuildLog>
      <saveOutput>false</saveOutput>
      <disabled>false</disabled>
      <replyTo>$DEFAULT_REPLYTO</replyTo>
    </hudson.plugins.emailext.ExtendedEmailPublisher>
  </publishers>
  <buildWrappers>
    <hudson.plugins.build__timeout.BuildTimeoutWrapper>
      <strategy class="hudson.plugins.build_timeout.impl.AbsoluteTimeOutStrategy">
        <timeoutMinutes>600</timeoutMinutes>
      </strategy>
      <operationList>
        <hudson.plugins.build__timeout.operations.AbortOperation/>
      </operationList>
    </hudson.plugins.build__timeout.BuildTimeoutWrapper>
    <hudson.plugins.timestamper.TimestamperBuildWrapper/>
    <com.cloudbees.jenkins.plugins.sshagent.SSHAgentBuildWrapper>
      <credentialIds>
        <string>tcwg-benchmark</string>
        <string>tcwg-buildslave-rsa</string>
        <ignoreMissing>false</ignoreMissing>
      </credentialIds>
    </com.cloudbees.jenkins.plugins.sshagent.SSHAgentBuildWrapper>
    <org.jenkinsci.plugins.buildnamesetter.BuildNameSetter>
      <template>#${BUILD_NUMBER}-${NODE_NAME}</template>
    </org.jenkinsci.plugins.buildnamesetter.BuildNameSetter>
  </buildWrappers>
</project>