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 "$@"