gubernator.sh 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. #!/usr/bin/env bash
  2. # Copyright 2016 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. # Make bucket and a folder for e2e-node test logs.
  16. # Populate the folder from the logs stored in /tmp/_artifacts/ in the same way as a
  17. # jenkins build would, and then print the URL to view the test results on Gubernator
  18. set -o errexit
  19. set -o nounset
  20. set -o pipefail
  21. KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/../..
  22. source "${KUBE_ROOT}/hack/lib/logging.sh"
  23. if [[ $# -eq 0 || ! $1 =~ ^[Yy]$ ]]; then
  24. read -r -p "Do you want to run gubernator.sh and upload logs publicly to GCS? [y/n]" yn
  25. echo
  26. if [[ ! $yn =~ ^[Yy]$ ]]; then
  27. exit 1
  28. fi
  29. fi
  30. # Check that user has gsutil
  31. if [[ $(which gsutil) == "" ]]; then
  32. echo "Could not find gsutil when running \`which gsutil\`"
  33. exit 1
  34. fi
  35. # Check that user has gcloud
  36. if [[ $(which gcloud) == "" ]]; then
  37. echo "Could not find gcloud when running: \`which gcloud\`"
  38. exit 1
  39. fi
  40. # Check that user has Credentialed Active account
  41. if ! gcloud auth list | grep -q "ACTIVE"; then
  42. echo "Could not find active account when running: \`gcloud auth list\`"
  43. exit 1
  44. fi
  45. readonly gcs_acl="public-read"
  46. bucket_name="${USER}-g8r-logs"
  47. echo ""
  48. V=2 kube::log::status "Using bucket ${bucket_name}"
  49. # Check if the bucket exists
  50. if ! gsutil ls gs:// | grep -q "gs://${bucket_name}/"; then
  51. V=2 kube::log::status "Creating public bucket ${bucket_name}"
  52. gsutil mb "gs://${bucket_name}/"
  53. # Make all files in the bucket publicly readable
  54. gsutil acl ch -u AllUsers:R "gs://${bucket_name}"
  55. else
  56. V=2 kube::log::status "Bucket already exists"
  57. fi
  58. # Path for e2e-node test results
  59. GCS_JOBS_PATH="gs://${bucket_name}/logs/e2e-node"
  60. ARTIFACTS=${ARTIFACTS:-"/tmp/_artifacts"}
  61. BUILD_LOG_PATH="${ARTIFACTS}/build-log.txt"
  62. if [[ ! -e $BUILD_LOG_PATH ]]; then
  63. echo "Could not find build-log.txt at ${BUILD_LOG_PATH}"
  64. exit 1
  65. fi
  66. # Get start and end timestamps based on build-log.txt file contents
  67. # Line where the actual tests start
  68. start_line=$(grep -n -m 1 "^=" "${BUILD_LOG_PATH}" | sed 's/\([0-9]*\).*/\1/')
  69. # Create text file starting where the tests start
  70. after_start=$(tail -n "+${start_line}" "${BUILD_LOG_PATH}")
  71. echo "${after_start}" >> build-log-cut.txt
  72. # Match the first timestamp
  73. start_time_raw=$(grep -m 1 -o '[0-9][0-9][0-9][0-9][[:blank:]][0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*' build-log-cut.txt)
  74. rm build-log-cut.txt
  75. # Make the date readable by date command (ex: 0101 00:00:00.000 -> 01/01 00:00:00.000)
  76. start_time=$(echo "${start_time_raw}" | sed 's/^.\{2\}/&\//')
  77. V=2 kube::log::status "Started at ${start_time}"
  78. # Match the last timestamp in the build-log file
  79. end_time=$(grep -o '[0-9][0-9][0-9][0-9][[:blank:]][0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*' "${BUILD_LOG_PATH}" | tail -1 | sed 's/^.\{2\}/&\//')
  80. # Convert to epoch time for Gubernator
  81. start_time_epoch=$(date -d "${start_time}" +%s)
  82. end_time_epoch=$(date -d "${end_time}" +%s)
  83. # Make folder name for build from timestamp
  84. BUILD_STAMP=$(echo "${start_time}" | sed 's/\///' | sed 's/ /_/')
  85. GCS_LOGS_PATH="${GCS_JOBS_PATH}/${BUILD_STAMP}"
  86. # Check if folder for same logs already exists
  87. if gsutil ls "${GCS_JOBS_PATH}" | grep -q "${BUILD_STAMP}"; then
  88. V=2 kube::log::status "Log files already uploaded"
  89. echo "Gubernator linked below:"
  90. echo "k8s-gubernator.appspot.com/build/${GCS_LOGS_PATH}?local=on"
  91. exit
  92. fi
  93. while IFS= read -r result; do
  94. if [[ $result != "" && $result != "${ARTIFACTS}/results" && $result != "${ARTIFACTS}" ]]; then
  95. mv "${result}/"* "${ARTIFACTS}"
  96. fi
  97. done < <(find "${ARTIFACTS}" -type d -name "results")
  98. # Upload log files
  99. for upload_attempt in $(seq 3); do
  100. if [[ -d "${ARTIFACTS}" && -n $(ls -A "${ARTIFACTS}") ]]; then
  101. V=2 kube::log::status "Uploading artifacts"
  102. gsutil -m -q -o "GSUtil:use_magicfile=True" cp -a "${gcs_acl}" -r -c \
  103. -z log,xml,json "${ARTIFACTS}" "${GCS_LOGS_PATH}/artifacts" || continue
  104. fi
  105. break
  106. done
  107. for upload_attempt in $(seq 3); do
  108. if [[ -e "${BUILD_LOG_PATH}" ]]; then
  109. V=2 kube::log::status "Uploading build log"
  110. gsutil -q cp -Z -a "${gcs_acl}" "${BUILD_LOG_PATH}" "${GCS_LOGS_PATH}" || continue
  111. fi
  112. break
  113. done
  114. # Find the k8s version for started.json
  115. version=""
  116. if [[ -e "version" ]]; then
  117. version=$(cat "version")
  118. elif [[ -e "hack/lib/version.sh" ]]; then
  119. source "hack/lib/version.sh"
  120. kube::version::get_version_vars
  121. version="${KUBE_GIT_VERSION-}"
  122. fi
  123. if [[ -n "${version}" ]]; then
  124. V=2 kube::log::status "Found Kubernetes version: ${version}"
  125. else
  126. V=2 kube::log::status "Could not find Kubernetes version"
  127. fi
  128. #Find build result from build-log.txt
  129. if grep -Fxq "Test Suite Passed" "${BUILD_LOG_PATH}"
  130. then
  131. build_result="SUCCESS"
  132. else
  133. build_result="FAILURE"
  134. fi
  135. V=4 kube::log::status "Build result is ${build_result}"
  136. if [[ -e "${ARTIFACTS}/started.json" ]]; then
  137. rm "${ARTIFACTS}/started.json"
  138. fi
  139. if [[ -e "${ARTIFACTS}/finished.json" ]]; then
  140. rm "${ARTIFACTS}/finished.json"
  141. fi
  142. V=2 kube::log::status "Constructing started.json and finished.json files"
  143. cat <<EOF >"${ARTIFACTS}/started.json"
  144. {
  145. "version": "${version}",
  146. "timestamp": ${start_time_epoch},
  147. "jenkins-node": "${NODE_NAME:-}"
  148. }
  149. EOF
  150. cat <<EOF >"${ARTIFACTS}/finished.json"
  151. {
  152. "result": "${build_result}",
  153. "timestamp": ${end_time_epoch}
  154. }
  155. EOF
  156. # Upload started.json
  157. V=2 kube::log::status "Uploading started.json and finished.json"
  158. V=2 kube::log::status "Run started at ${start_time}"
  159. json_file="${GCS_LOGS_PATH}/started.json"
  160. for upload_attempt in $(seq 3); do
  161. V=2 kube::log::status "Uploading started.json to ${json_file} (attempt ${upload_attempt})"
  162. gsutil -q -h "Content-Type:application/json" cp -a "${gcs_acl}" "${ARTIFACTS}/started.json" \
  163. "${json_file}" || continue
  164. break
  165. done
  166. # Upload finished.json
  167. for upload_attempt in $(seq 3); do
  168. V=2 kube::log::status "Uploading finished.json to ${GCS_LOGS_PATH} (attempt ${upload_attempt})"
  169. gsutil -q -h "Content-Type:application/json" cp -a "${gcs_acl}" "${ARTIFACTS}/finished.json" \
  170. "${GCS_LOGS_PATH}/finished.json" || continue
  171. break
  172. done
  173. echo "Gubernator linked below:"
  174. echo "k8s-gubernator.appspot.com/build/${bucket_name}/logs/e2e-node/${BUILD_STAMP}"