github.com/percona/percona-xtradb-cluster-operator@v1.14.0/e2e-tests/smart-update2/run (about) 1 #!/bin/bash 2 # CASES: 3 # - Check telemetry in minimal cluster with `upgradeOptions.apply: "disabled"` and `DISABLE_TELEMETRY=false` in the operator 4 # - Check telemetry in minimal cluster with custom `upgradeOptions.apply` and `DISABLE_TELEMETRY=true` in the operator 5 # - Check telemetry in minimal cluster with `upgradeOptions.apply: "disabled"` and `DISABLE_TELEMETRY=true` in the operator 6 # - Update cluster with version service offline 7 # - Update cluster with recommended image by version service 8 # - Update cluster with the latest image by version service 9 # - Update cluster with explicitly specified image inside version service 10 11 set -o errexit 12 13 test_dir=$(realpath $(dirname $0)) 14 . ${test_dir}/../functions 15 16 set_debug 17 18 API='pxc.percona.com/v9-9-9' 19 TARGET_IMAGE_PXC=${IMAGE_PXC} 20 CLUSTER="smart-update" 21 CLUSTER_SIZE=3 22 PROXY_SIZE=2 23 24 if [[ ${TARGET_IMAGE_PXC} == *"percona-xtradb-cluster-operator"* ]]; then 25 PXC_VER=$(echo -n "${TARGET_IMAGE_PXC}" | $sed -r 's/.*([0-9].[0-9])$/\1/') 26 else 27 PXC_VER=$(echo -n "${TARGET_IMAGE_PXC}" | $sed -r 's/.*:([0-9]+\.[0-9]+).*$/\1/') 28 fi 29 TARGET_IMAGE_PXC_VS="perconalab/percona-xtradb-cluster-operator:main-pxc${PXC_VER}" 30 VS_URL="http://version-service" 31 VS_PORT="11000" 32 VS_ENDPOINT="${VS_URL}:${VS_PORT}" 33 34 function get_pod_names_images { 35 local cluster=${1} 36 local type=${2:-pxc} 37 38 echo -e $(kubectl_bin get pods -l "app.kubernetes.io/instance=${cluster},app.kubernetes.io/component=${type}" \ 39 -o jsonpath="{range .items[*]}{.metadata.name}{\",\"}{.spec.containers[?(@.name == \"${type}\")].image}{\"\n\"}{end}") 40 } 41 42 function check_last_pod_to_update { 43 local cluster=${1} 44 local initial_primary=${2} 45 local pxc_size=${3} 46 local target_image=${4} 47 48 set +x 49 echo -n "Waiting for the last pod to update" 50 local i=0 51 local max=720 52 until [[ "$(kubectl_bin get pxc "${cluster}" -o jsonpath='{.status.state}')" == "ready" ]]; do 53 echo -n "." 54 updated_pods_count=0 55 for entry in $(get_pod_names_images "${cluster}"); do 56 if [[ -n "$(echo ${entry} | grep ${target_image})" ]]; then 57 ((updated_pods_count += 1)) 58 fi 59 done 60 61 if [[ ${updated_pods_count} == $((pxc_size - 1)) ]]; then 62 if [[ -n $(get_pod_names_images "${cluster}" | grep "${initial_primary}" | grep "${IMAGE_PXC}") ]]; then 63 echo 64 echo "${initial_primary} is REALLY the last one to update" 65 break 66 else 67 echo "${initial_primary} is not the last one to update. Exiting..." 68 exit 1 69 fi 70 fi 71 if [[ $i -ge $max ]]; then 72 echo "Something went wrong waiting for the last pod to update!" 73 exit 1 74 fi 75 let i+=1 76 sleep 1 77 done 78 set -x 79 } 80 81 function deploy_version_service { 82 desc 'install version service' 83 kubectl_bin create configmap versions \ 84 --from-file "${test_dir}/conf/operator.9.9.9.pxc-operator.dep.json" \ 85 --from-file "${test_dir}/conf/operator.9.9.9.pxc-operator.json" 86 kubectl_bin apply -f "${test_dir}/conf/vs.yml" 87 sleep 10 88 } 89 90 function check_telemetry_transfer() { 91 local cr_vs_uri=${1} 92 local cr_vs_channel=${2:-"disabled"} 93 local telemetry_state=${3:-"enabled"} 94 95 desc 'create PXC minimal cluster' 96 cluster="minimal-cluster" 97 98 kubectl_bin apply -f "${conf_dir}/client.yml" 99 yq "${conf_dir}/secrets.yml" \ 100 | yq eval "(. | select(.metadata.name == \"my-cluster-secrets\") | .metadata.name) = \"${cluster}\"" \ 101 | kubectl_bin apply -f - 102 103 yq "${src_dir}/deploy/cr-minimal.yaml" \ 104 | yq eval ".spec.upgradeOptions.versionServiceEndpoint=\"${cr_vs_uri}\"" \ 105 | yq eval ".spec.upgradeOptions.apply=\"${cr_vs_channel}\"" \ 106 | yq eval ".spec.initContainer.image=\"$IMAGE\"" \ 107 | yq eval '.spec.crVersion="9.9.9"' \ 108 | yq eval ".spec.pxc.image=\"$IMAGE_PXC\"" \ 109 | yq eval ".spec.haproxy.image=\"$IMAGE_HAPROXY\"" \ 110 | yq eval ".spec.logcollector.image=\"$IMAGE_LOGCOLLECTOR\"" \ 111 | kubectl_bin apply -f - 112 113 desc 'check if Pod is started' 114 wait_for_running "$cluster-pxc" "1" 115 sleep 20 116 local proxy 117 proxy=$(get_proxy "$cluster") 118 wait_for_running "$proxy" 1 119 120 desc 'write data' 121 if [[ $IMAGE_PXC =~ 5\.7 ]] && [[ "$(is_keyring_plugin_in_use "$cluster")" ]]; then 122 encrypt='ENCRYPTION=\"Y\"' 123 fi 124 run_mysql \ 125 "CREATE DATABASE IF NOT EXISTS myApp; use myApp; CREATE TABLE IF NOT EXISTS myApp (id int PRIMARY KEY) $encrypt;" \ 126 "-h $proxy -uroot -proot_password -P$port" 127 run_mysql \ 128 'INSERT myApp.myApp (id) VALUES (100500)' \ 129 "-h $proxy -uroot -proot_password -P$port" 130 131 kubectl_bin logs "$(kubectl get pods --selector=run=version-service-cr -o jsonpath='{.items[0].metadata.name}')" \ 132 | grep -E 'server request payload|unary call' \ 133 | grep -Eo '\{.*\}' \ 134 | jq 'del(."grpc.request.content".msg.customResourceUid)' \ 135 | jq 'del(."grpc.request.content".msg.kubeVersion)' \ 136 | jq 'del(."grpc.start_time")' \ 137 | jq 'del(."grpc.time_ms")' \ 138 >"${tmp_dir}/${telemetry_state}_telemetry.version-service-cr.log.json" 139 140 kubectl_bin logs "$(kubectl get pods --selector=run=version-service -o jsonpath='{.items[0].metadata.name}')" \ 141 | grep -E 'server request payload|unary call' \ 142 | grep -Eo '\{.*\}' \ 143 | jq 'del(."grpc.request.content".msg.customResourceUid)' \ 144 | jq 'del(."grpc.request.content".msg.kubeVersion)' \ 145 | jq 'del(."grpc.start_time")' \ 146 | jq 'del(."grpc.time_ms")' \ 147 >"${tmp_dir}/${telemetry_state}_telemetry.version-service.log.json" 148 149 local telemetry_log_file="${telemetry_state}_telemetry.version-service${OPERATOR_NS:+-cw}.log.json" 150 desc "telemetry was disabled in CR but in operator not" 151 if [ "${cr_vs_channel}" == 'disabled' -a "${telemetry_state}" == 'enabled' ]; then 152 desc "operator fallback VS should have telemetry" 153 diff "${test_dir}/compare/${telemetry_log_file}" <(grep -f "${tmp_dir}/${telemetry_state}_telemetry.version-service.log.json" "${test_dir}/compare/${telemetry_log_file}") 154 desc "CR VS should not have telemetry" 155 [[ -s "${tmp_dir}/enabled_telemetry.version-service-cr.log.json" ]] && exit 1 156 fi 157 158 local image_prefix=${cr_vs_channel%'-recommended'} 159 local telemetry_cr_log_file="${telemetry_state}_telemetry.version-service-cr-${image_prefix}${OPERATOR_NS:+-cw}.log.json" 160 desc "telemetry was disabled in operator but not in CR" 161 if [ "${cr_vs_channel}" == "${image_prefix}-recommended" -a "${telemetry_state}" == 'disabled' ]; then 162 desc "cr VS should have telemetry" 163 diff "${test_dir}/compare/${telemetry_cr_log_file}" <(grep -f "${tmp_dir}/${telemetry_state}_telemetry.version-service-cr.log.json" "${test_dir}/compare/${telemetry_cr_log_file}") 164 desc "operator VS should not have telemetry" 165 [[ -s ${tmp_dir}/disabled_telemetry.version-service.log.json ]] && exit 1 166 fi 167 168 desc "telemetry was disabled in CR as well as in operator" 169 if [ "${cr_vs_channel}" == 'disabled' -a "${telemetry_state}" == 'disabled' ]; then 170 desc "CR VS should not have telemetry" 171 [[ -s ${tmp_dir}/disabled_telemetry.version-service-cr.log.json ]] && exit 1 172 desc "operator VS should not have telemetry" 173 [[ -s ${tmp_dir}/disabled_telemetry.version-service.log.json ]] && exit 1 174 fi 175 176 kubectl_bin patch pxc minimal-cluster --type=merge -p '{"metadata":{"finalizers":["delete-pxc-pvc"]}}' 177 kubectl_bin delete pod ${OPERATOR_NS:+-n $OPERATOR_NS} "$(get_operator_pod)" 178 kubectl_bin delete pxc --all 179 kubectl_bin delete deploy pxc-client 180 sleep 30 181 } 182 183 function main() { 184 create_infra "${namespace}" 185 deploy_version_service 186 deploy_cert_manager 187 IMAGE_PXC=$(kubectl_bin exec -ti "$(get_operator_pod)" ${OPERATOR_NS:+-n $OPERATOR_NS} -- curl -s "${VS_URL}.${namespace}.svc.cluster.local:${VS_PORT}/versions/v1/pxc-operator/9.9.9" | jq -r '.versions[].matrix.pxc[].imagePath' | grep ":${PXC_VER}" | sort -V | tail -n3 | head -n1) 188 189 kubectl_bin patch crd perconaxtradbclusters.pxc.percona.com --type='json' -p '[{"op":"add","path":"/spec/versions/-", "value":{"name": "v9-9-9","schema": {"openAPIV3Schema": {"properties": {"spec": {"type": "object","x-kubernetes-preserve-unknown-fields": true},"status": {"type": "object", "x-kubernetes-preserve-unknown-fields": true}}, "type": "object" }}, "served": true, "storage": false, "subresources": { "status": {}}}}]' 190 kubectl_bin ${OPERATOR_NS:+-n $OPERATOR_NS} set env deploy/percona-xtradb-cluster-operator "PERCONA_VS_FALLBACK_URI=http://version-service.${namespace}.svc.cluster.local:11000" 191 192 ################################################ 193 desc 'Starting telemetry testing' 194 $sed 's/version-service/version-service-cr/g' "${test_dir}/conf/vs.yml" \ 195 | yq eval '(. | select(.kind == "Deployment") | .spec.template.spec.containers[0].image) = "'"$(yq 'select(.kind == "Deployment").spec.template.spec.containers[0].image' "${test_dir}/conf/vs.yml")"'"' \ 196 | kubectl_bin apply -f - 197 kubectl_bin delete pod -l run=version-service 198 IMAGE_PREFIX="$(echo -n "$IMAGE_PXC" | sed -r 's/^.*:([0-9]+.[0-9]+).*/\1/')" 199 ################################################ 200 desc 'Enable telemetry on operator level' 201 kubectl_bin get deployment/percona-xtradb-cluster-operator -o yaml ${OPERATOR_NS:+-n $OPERATOR_NS} \ 202 | yq '(.spec.template.spec.containers[0].env[] | select(.name == "DISABLE_TELEMETRY").value) = "false"' \ 203 | kubectl_bin apply ${OPERATOR_NS:+-n $OPERATOR_NS} -f - 204 sleep 30 205 206 wait_pod "$(get_operator_pod)" "480" "${OPERATOR_NS}" 207 208 check_telemetry_transfer "http://version-service-cr.${namespace}.svc.cluster.local:11000" "disabled" "enabled" 209 ################################################ 210 desc "Disabling telemetry on the operator level" 211 212 kubectl_bin delete pod -l run=version-service-cr 213 kubectl_bin delete pod -l run=version-service 214 kubectl_bin get deployment/percona-xtradb-cluster-operator -o yaml ${OPERATOR_NS:+-n $OPERATOR_NS} \ 215 | yq '(.spec.template.spec.containers[0].env[] | select(.name == "DISABLE_TELEMETRY").value) = "true"' \ 216 | kubectl_bin apply ${OPERATOR_NS:+-n $OPERATOR_NS} -f - 217 sleep 30 218 wait_pod "$(get_operator_pod)" "480" "${OPERATOR_NS}" 219 220 check_telemetry_transfer "http://version-service-cr.${namespace}.svc.cluster.local:11000" "${IMAGE_PREFIX}-recommended" "disabled" 221 kubectl_bin delete pod -l run=version-service-cr 222 kubectl_bin delete pod -l run=version-service 223 check_telemetry_transfer "http://version-service-cr.${namespace}.svc.cluster.local:11000" "disabled" "disabled" 224 ################################################# 225 kubectl_bin delete deployment version-service-cr 226 desc 'Telemetry testing finished' 227 ################################################## 228 desc 'PXC cluster with version service offline' 229 cp -f "${test_dir}/conf/${CLUSTER}-version-service-unreachable.yml" "${tmp_dir}/${CLUSTER}-version-service-unreachable.yml" 230 yq -i eval ".spec.initContainer.image = \"${IMAGE}\"" "${tmp_dir}/${CLUSTER}-version-service-unreachable.yml" 231 spinup_pxc "${CLUSTER}" "${tmp_dir}/${CLUSTER}-version-service-unreachable.yml" 232 233 wait_cluster_consistency "${CLUSTER}" "${CLUSTER_SIZE}" "${PROXY_SIZE}" 234 if [[ "$(kubectl_bin get pxc/${CLUSTER} -o jsonpath='{.spec.pxc.image}')" != "${IMAGE_PXC}" ]]; then 235 echo "ERROR: PXC image has been changed. Exiting..." 236 exit 1 237 fi 238 239 ################################################## 240 desc 'PXC cluster update with recommended image by version service' 241 vs_image="recommended" 242 initial_primary=$(run_mysql 'SELECT @@hostname hostname;' "-h ${CLUSTER}-haproxy -uroot -proot_password") 243 244 kubectl_bin patch pxc/"${CLUSTER}" --type=merge -p '{"spec":{"upgradeOptions":{"versionServiceEndpoint":"'${VS_ENDPOINT}'","apply":"'${vs_image}'","schedule": "* * * * *"}}}' 245 sleep 55 246 247 check_last_pod_to_update "${CLUSTER}" "${initial_primary}" "${CLUSTER_SIZE}" "${TARGET_IMAGE_PXC_VS}" 248 wait_cluster_consistency "${CLUSTER}" "${CLUSTER_SIZE}" "${PROXY_SIZE}" 249 for i in $(seq 0 $((CLUSTER_SIZE - 1))); do 250 compare_mysql_cmd "select-1" "SELECT * from myApp.myApp;" "-h ${CLUSTER}-pxc-${i}.${CLUSTER}-pxc -uroot -proot_password" 251 done 252 253 kubectl_bin delete -f "${tmp_dir}/${CLUSTER}-version-service-unreachable.yml" 254 kubectl_bin delete pvc --all 255 256 ################################################## 257 desc 'PXC cluster update with the latest image by version service' 258 spinup_pxc "${CLUSTER}" "${tmp_dir}/${CLUSTER}-version-service-unreachable.yml" 259 vs_image="latest" 260 initial_primary=$(run_mysql 'SELECT @@hostname hostname;' "-h ${CLUSTER}-haproxy -uroot -proot_password") 261 262 kubectl_bin patch pxc/"${CLUSTER}" --type=merge -p '{"spec":{"upgradeOptions":{"versionServiceEndpoint":"'${VS_ENDPOINT}'","apply":"'${vs_image}'","schedule": "* * * * *"}}}' 263 sleep 55 264 265 check_last_pod_to_update "${CLUSTER}" "${initial_primary}" "${CLUSTER_SIZE}" "${TARGET_IMAGE_PXC_VS}" 266 wait_cluster_consistency "${CLUSTER}" "${CLUSTER_SIZE}" "${PROXY_SIZE}" 267 for i in $(seq 0 $((CLUSTER_SIZE - 1))); do 268 compare_mysql_cmd "select-1" "SELECT * from myApp.myApp;" "-h ${CLUSTER}-pxc-${i}.${CLUSTER}-pxc -uroot -proot_password" 269 done 270 271 kubectl_bin delete -f "${tmp_dir}/${CLUSTER}-version-service-unreachable.yml" 272 kubectl_bin delete pvc --all 273 274 ################################################## 275 desc 'PXC cluster update with explicitly specified image inside version service' 276 spinup_pxc "${CLUSTER}" "${tmp_dir}/${CLUSTER}-version-service-unreachable.yml" 277 vs_image=$(kubectl_bin exec -ti "$(get_operator_pod)" ${OPERATOR_NS:+-n $OPERATOR_NS} -- curl -s "${VS_URL}.${namespace}.svc.cluster.local:${VS_PORT}/versions/v1/pxc-operator/9.9.9" | jq -r '.versions[].matrix.pxc[].imagePath' | grep ":${PXC_VER}" | sort -V | tail -n2 | head -n1) 278 initial_primary=$(run_mysql 'SELECT @@hostname hostname;' "-h ${CLUSTER}-haproxy -uroot -proot_password") 279 280 kubectl_bin patch pxc/"${CLUSTER}" --type=merge -p '{"spec":{"upgradeOptions":{"versionServiceEndpoint":"'${VS_ENDPOINT}'","apply":"'${vs_image}'","schedule": "* * * * *"}}}' 281 sleep 55 282 283 check_last_pod_to_update "${CLUSTER}" "${initial_primary}" "${CLUSTER_SIZE}" "percona/percona-xtradb-cluster:${vs_image}" 284 wait_cluster_consistency "${CLUSTER}" "${CLUSTER_SIZE}" "${PROXY_SIZE}" 285 for i in $(seq 0 $((CLUSTER_SIZE - 1))); do 286 compare_mysql_cmd "select-1" "SELECT * from myApp.myApp;" "-h ${CLUSTER}-pxc-${i}.${CLUSTER}-pxc -uroot -proot_password" 287 done 288 289 kubectl_bin delete -f "${tmp_dir}/${CLUSTER}-version-service-unreachable.yml" 290 kubectl_bin delete pvc --all 291 292 desc 'cleanup' 293 kubectl_bin delete -f "${test_dir}/conf/vs.yml" 294 destroy "${namespace}" 295 desc "test passed" 296 } 297 298 main