9483118123b1c38aef07a64891db6e3844b3ea3d
[releng/global-jjb.git] / shell / jjb-verify-build-nodes.sh
1 #!/bin/bash -l
2 # SPDX-License-Identifier: EPL-1.0
3 ##############################################################################
4 # Copyright (c) 2020 The Linux Foundation and others.
5 #
6 # All rights reserved. This program and the accompanying materials
7 # are made available under the terms of the Eclipse Public License v1.0
8 # which accompanies this distribution, and is available at
9 # http://www.eclipse.org/legal/epl-v10.html
10 ##############################################################################
11 echo "---> jjb-verify-build-nodes.sh"
12
13 # Checks build-node labels used in ci-management templates and projects,
14 # and prints file names with invalid values.
15 #
16 # Uses -l to get $HOME/.local/bin on path, where pip puts yq
17 # Prereqs:
18 # - Bash version 3+
19 # - Python tool yq is installed; e.g., by python-tools-install.sh
20 # - Working directory is a ci-management repo with subdirs
21 #   jenkins-config/clouds/openstack and jjb
22 # Environment variable:
23 # - EXTERNAL_LABELS - a space-separated list of build-node labels
24 #   for nodes not managed in the jenkins-config area (optional)
25
26 set -eu -o pipefail
27
28 # function to search an array for a value
29 # $1 is value
30 # $2 is array, passed via ${array[@]}
31 isValueInArray () {
32   local e match="$1"
33   shift
34   for e; do [[ "$e" == "$match" ]] && return 0; done
35   return 1
36 }
37
38 # discover build node labels
39 declare -a labels=()
40 suffix=".cfg"
41 while IFS= read -r ; do
42     file="$REPLY"
43     # valid files contain IMAGE_NAME; skip the cloud config file
44     if grep -q "IMAGE_NAME" "$file" && ! grep -q "CLOUD_CREDENTIAL_ID" "$file"; then
45         # file name is a valid label, without path prefix and suffix
46         name=$(basename -s "$suffix" "$file")
47         labels+=("$name")
48         # a file can define custom labels
49         if custom=$(grep "LABELS=" "$file" | cut -d= -f2); then
50             # TODO: confirm separator for multiple labels
51             read -r -a customarray <<< "$custom"
52             for c in "${customarray[@]}"; do
53                 if ! isValueInArray "$c" "${labels[@]}"; then
54                     labels+=("$c")
55                 fi
56             done
57         fi
58     fi
59 done < <(find "jenkins-config/clouds/openstack" -name \*$suffix)
60 echo "Found ${#labels[@]} configured label(s):"
61 echo "${labels[@]}"
62 declare -a externals=()
63 if [[ -n ${EXTERNAL_LABELS:-} ]]; then
64     read -r -a externals <<< "$EXTERNAL_LABELS"
65     echo "Received ${#externals[@]} external label(s):"
66     echo "${externals[@]}"
67     labels=("${externals[@]}" "${labels[@]}")
68 fi
69
70 # check build node label uses
71 errs=0
72 while IFS= read -r ; do
73     file="$REPLY"
74     echo "Checking $file"
75     # this includes job-templates which may be annoying
76     nodes=$(yq 'recurse | ."build-node"? | values' "$file" | sort -u | tr -d '"')
77     for node in $nodes; do
78         # may be a yaml list; e.g., '[ foo, bar, baz ]'
79         node="${node//[\[\],]/}"
80         if [[ -n $node ]] && ! isValueInArray "$node" "${labels[@]}"; then
81             echo "ERROR: file $file uses unknown build-node $node"
82             errs=$((errs+1))
83         fi
84     done
85 done < <(find "jjb" -name '*.yaml')
86
87 echo "---> jjb-verify-build-nodes.sh ends"
88 exit $errs