github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/test/integration/setup-prow-components.sh (about) 1 #!/usr/bin/env bash 2 # Copyright 2022 The Kubernetes Authors. 3 # 4 # Licensed under the Apache License, Version 2.0 (the "License"); 5 # you may not use this file except in compliance with the License. 6 # You may obtain a copy of the License at 7 # 8 # http://www.apache.org/licenses/LICENSE-2.0 9 # 10 # Unless required by applicable law or agreed to in writing, software 11 # distributed under the License is distributed on an "AS IS" BASIS, 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 # See the License for the specific language governing permissions and 14 # limitations under the License. 15 16 # Set up the KIND cluster. 17 18 set -o errexit 19 set -o nounset 20 set -o pipefail 21 22 SCRIPT_ROOT="$(cd "$(dirname "$0")" && pwd)" 23 # shellcheck disable=SC1091 24 source "${SCRIPT_ROOT}"/lib.sh 25 26 function usage() { 27 >&2 cat <<EOF 28 Build Prow components and deploy them into the KIND test cluster. 29 30 Usage: $0 [options] 31 32 Examples: 33 # Deploy all Prow components without building anything. This fails if the 34 # images the components rely on have not yet been built by ko. 35 $0 36 37 # Build all images required by Prow components, and deploy them. 38 $0 -build=ALL 39 40 # Build only the fakegitserver image and deploy it to Prow. 41 $0 -build=fakegitserver 42 43 # Build only the fakegitserver and fakegerritserver images and deploy them to 44 # Prow. 45 $0 -build=fakegitserver,fakegerritserver 46 47 # Redeploy fakegitserver to Prow, without building it, by deleting the current 48 # pods associated with it. This fails if this component has not been built 49 # yet. 50 $0 -delete=fakegitserver 51 52 # Delete all Prow components from the cluster, then deploy them all back 53 # again. This is useful if you want to force pods to restart from a blank 54 # slate. 55 $0 -delete=ALL 56 57 # Delete *ALL* components, recompile them all, and finally deploy everything 58 # again. 59 60 $0 -delete=ALL -build=ALL 61 62 Options: 63 -build='': 64 Build only the comma-separated list of Prow components with 65 "${REPO_ROOT}"/hack/prowimagebuilder. Useful when developing a fake 66 service that needs frequent recompilation. The images are a 67 comma-separated string. 68 69 The value "ALL" for this falg is an alias for all images (PROW_IMAGES in 70 lib.sh). 71 72 -delete='': 73 Force the deletion of the given (currently deployed) Prow components by 74 deleting their associated pods. The value "ALL" for this flag is an 75 alias for all components (PROW_COMPONENTS in lib.sh). 76 77 You only need to use this flag if you want to force the given components 78 to start from a blank state (e.g., you want to clear its memory for 79 whatever reason). Technically, you can delete pods manually with kubectl 80 to achieve the same effect; this flag is given here as a convenience. 81 82 -fakepubsub-node-port='': 83 Make the fakepubsub service use the provided node port (default 30303). 84 85 -help: 86 Display this help message. 87 EOF 88 } 89 90 function main() { 91 declare -a images 92 declare -a components 93 local images_val 94 local components_val 95 local fakepubsub_node_port 96 97 for arg in "$@"; do 98 case "${arg}" in 99 -build=*) 100 images_val="${arg#-build=}" 101 for image in ${images_val//,/ }; do 102 if [[ "${image}" == ALL ]]; then 103 images=("${!PROW_IMAGES[@]}") 104 break 105 else 106 images+=("${image}") 107 fi 108 done 109 ;; 110 -delete=*) 111 components_val="${arg#-delete=}" 112 for component in ${components_val//,/ }; do 113 if [[ "${component}" == ALL ]]; then 114 components=("${PROW_COMPONENTS[@]}") 115 break 116 else 117 components+=("${component}") 118 fi 119 done 120 ;; 121 -fakepubsub-node-port=*) 122 fakepubsub_node_port="${arg#-fakepubsub-node-port=}" 123 ;; 124 -help) 125 usage 126 return 127 ;; 128 --*) 129 echo >&2 "cannot use flags with two leading dashes ('--...'), use single dashes instead ('-...')" 130 return 1 131 ;; 132 esac 133 done 134 135 if [[ -n "${images[*]}" ]]; then 136 build_prow_images "${images[@]}" 137 fi 138 139 if [[ -n "${components[*]}" ]]; then 140 delete_components "${components[@]}" 141 fi 142 143 deploy_prow "${fakepubsub_node_port:-30303}" 144 145 wait_for_nginx 146 } 147 148 function build_prow_images() { 149 declare -a images 150 local prowimagebuilder_yaml 151 152 if (($#)); then 153 log "Building select Prow images" 154 for image in "${@}"; do 155 images+=("${image}") 156 done 157 else 158 log "Building *all* Prow images" 159 for image in "${!PROW_IMAGES[@]}"; do 160 images+=("${image}") 161 done 162 fi 163 164 prowimagebuilder_yaml="$(create_prowimagebuilder_yaml "${images[@]}")" 165 # shellcheck disable=SC2064 166 trap "rm -f ${prowimagebuilder_yaml}" EXIT SIGINT SIGTERM 167 168 >&2 cat <<EOF 169 ==> ${prowimagebuilder_yaml} contents: 170 171 \`\`\` 172 $(cat "${prowimagebuilder_yaml}") 173 \`\`\` 174 175 EOF 176 177 set -x 178 go run \ 179 "${REPO_ROOT}"/hack/prowimagebuilder \ 180 --ko-docker-repo="localhost:${LOCAL_DOCKER_REGISTRY_PORT}" \ 181 --prow-images-file="${prowimagebuilder_yaml}" \ 182 --push 183 set +x 184 185 build_extra_images 186 log "Finished building images" 187 } 188 189 function build_extra_images() { 190 log "Building extra images" 191 192 build_clonerefs_ssl_disabled 193 build_initupload_fakegcsserver 194 } 195 196 function build_clonerefs_ssl_disabled() { 197 echo >&2 "Building clonerefs-ssl-disabled" 198 local src 199 local dest 200 src="localhost:${LOCAL_DOCKER_REGISTRY_PORT}/clonerefs:latest" 201 dest="localhost:${LOCAL_DOCKER_REGISTRY_PORT}/clonerefs-ssl-disabled:latest" 202 203 docker build --tag "${dest}" - <<EOF 204 FROM ${src} 205 # Allow Git to accept traffic from HTTPS servers with self-signed certs. 206 ENV GIT_SSL_NO_VERIFY 1 207 EOF 208 209 docker push "${dest}" 210 211 } 212 213 function build_initupload_fakegcsserver() { 214 echo >&2 "Building initupload-fakegcsserver" 215 local src 216 local dest 217 src="localhost:${LOCAL_DOCKER_REGISTRY_PORT}/initupload:latest" 218 dest="localhost:${LOCAL_DOCKER_REGISTRY_PORT}/initupload-fakegcsserver:latest" 219 220 docker build --tag "${dest}" - <<EOF 221 FROM ${src} 222 # Create directory to hold all buckets. 223 RUN mkdir /gcs 224 # Force GCS client running in this image to always talk to fakegcsserver. 225 ENV STORAGE_EMULATOR_HOST http://fakegcsserver.default:80 226 EOF 227 228 docker push "${dest}" 229 } 230 231 function create_prowimagebuilder_yaml() { 232 # Create a definitive reference of valid prow components (images) that can be 233 # built by prowimagebuilder. 234 local tmpfile 235 tmpfile=$(mktemp /tmp/prowimagebuilder.XXXXXX.yaml) 236 237 local contents 238 239 echo "images:" >> "${tmpfile}" 240 241 for arg in "$@"; do 242 if [[ -v "PROW_IMAGES[${arg}]" ]]; then 243 contents+=" - dir: ${PROW_IMAGES[${arg}]} 244 " 245 else 246 echo >&2 "Unrecognized prow component \"${arg}\"" 247 return 1 248 fi 249 done 250 251 echo "${contents}" | sort >> "${tmpfile}" 252 echo "${tmpfile}" 253 } 254 255 function delete_components() { 256 local component 257 if ! (($#)); then 258 log "(Prow components) nothing to delete" 259 return 260 fi 261 262 log "Deleting Prow components: $*" 263 for component in "$@"; do 264 do_kubectl delete deployment -l app="${component}" 265 do_kubectl delete pods -l app="${component}" 266 done 267 } 268 269 # deploy_prow applies the full Kubernetes configuration for all components. If 270 # any component's images have changed (recompiled and republished to the logal 271 # registry by ko), then they will be picked up and Kubernetes will restart those 272 # affected pods. 273 function deploy_prow() { 274 local component 275 local fakepubsub_node_port 276 fakepubsub_node_port="${1}" 277 log "Deploying Prow components" 278 279 # Even though we apply the entire Prow configuration, Kubernetes is smart 280 # enough to only redeploy those components who configurations have changed as 281 # a result of newly built images (from build_prow_images()). 282 pushd "${SCRIPT_ROOT}/config/prow" 283 do_kubectl create configmap config --from-file=./config.yaml --dry-run=client -oyaml | do_kubectl apply -f - --namespace=default 284 do_kubectl create configmap plugins --from-file=./plugins.yaml --dry-run=client -oyaml | do_kubectl apply -f - --namespace=default 285 do_kubectl create configmap job-config --from-file=./jobs --dry-run=client -oyaml | do_kubectl apply -f - --namespace=default 286 popd 287 288 deploy_components "${fakepubsub_node_port}" 289 290 log "Prow components are ready" 291 } 292 293 function deploy_components() { 294 local item 295 local fakepubsub_node_port 296 fakepubsub_node_port="${1:-30303}" 297 for item in "${PROW_DEPLOYMENT_ORDER[@]}"; do 298 deploy_item "${item}" "${fakepubsub_node_port}" 299 done 300 } 301 302 function deploy_item() { 303 local item 304 local component 305 local fakepubsub_node_port 306 local wait_for_resource_args 307 local wait_for_crd_args 308 item="${1}" 309 fakepubsub_node_port="${2:-30303}" 310 311 case "${item}" in 312 WAIT_FOR_CRD_*) 313 wait_for_crd_args="${item#WAIT_FOR_CRD_}" 314 wait_for_crd "${wait_for_crd_args}" 315 ;; 316 WAIT_FOR_RESOURCE_*) 317 wait_for_resource_args="${item#WAIT_FOR_RESOURCE_}" 318 wait_for_resource "${wait_for_resource_args}" 319 ;; 320 WAIT_*) 321 component="${item#WAIT_}" 322 if ! wait_for_readiness "${component}"; then 323 # If a component fails to start up and we're in CI, record logs. 324 if [[ -n "${ARTIFACTS:-}" ]]; then 325 >&2 do_kubectl get pods 326 "${SCRIPT_ROOT}/teardown.sh" "-save-logs=${ARTIFACTS}/kind_logs" 327 fi 328 return 1 329 fi 330 ;; 331 # Special-case for fakepubsub which requires a sed-replacement for the 332 # randomized node port number. 333 fakepubsub.yaml) 334 sed "s/FAKEPUBSUB_RANDOM_NODE_PORT/${fakepubsub_node_port}/" "${SCRIPT_ROOT}"/config/prow/cluster/"${item}" | 335 do_kubectl apply --server-side=true -f - 336 ;; 337 *) 338 do_kubectl apply --server-side=true -f "${SCRIPT_ROOT}"/config/prow/cluster/"${item}" 339 ;; 340 esac 341 } 342 343 function wait_for_nginx() { 344 log "Waiting for nginx" 345 for _ in $(seq 1 180); do 346 if do_kubectl wait --namespace ingress-nginx \ 347 --for=condition=ready pod \ 348 --selector=app.kubernetes.io/component=controller \ 349 --timeout=180s 2>/dev/null; then 350 351 log "nginx is ready (Prow instance is ready!)" 352 353 return 354 else 355 echo >&2 "waiting..." 356 sleep 1 357 fi 358 done 359 } 360 361 main "$@"