mirror of
https://github.com/zalando/postgres-operator.git
synced 2026-10-18 03:28:00 +02:00
Merge branch 'master' into observed-generation
This commit is contained in:
+22
-7
@@ -7,23 +7,36 @@ set -o pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
readonly cluster_name="postgres-operator-e2e-tests"
|
||||
readonly kubeconfig_path="/tmp/kind-config-${cluster_name}"
|
||||
readonly spilo_image="registry.opensource.zalan.do/acid/spilo-17-e2e:0.3"
|
||||
readonly kubeconfig_path="${HOME}/kind-config-${cluster_name}"
|
||||
readonly spilo_image="ghcr.io/zalando/spilo-18:4.1-p1"
|
||||
readonly e2e_test_runner_image="ghcr.io/zalando/postgres-operator-e2e-tests-runner:latest"
|
||||
|
||||
export GOPATH=${GOPATH-~/go}
|
||||
export PATH=${GOPATH}/bin:$PATH
|
||||
|
||||
# detect system architecture for pulling the correct Spilo image
|
||||
case "$(uname -m)" in
|
||||
x86_64) readonly PLATFORM="linux/amd64" ;;
|
||||
aarch64|arm64) readonly PLATFORM="linux/arm64" ;;
|
||||
*) echo "Unsupported architecture: $(uname -m)"; exit 1 ;;
|
||||
esac
|
||||
|
||||
echo "Clustername: ${cluster_name}"
|
||||
echo "Kubeconfig path: ${kubeconfig_path}"
|
||||
|
||||
function pull_images(){
|
||||
operator_tag=$(git describe --tags --always --dirty)
|
||||
if [[ -z $(docker images -q ghcr.io/zalando/postgres-operator:${operator_tag}) ]]
|
||||
image_name="ghcr.io/zalando/postgres-operator:${operator_tag}"
|
||||
if [[ -z $(docker images -q "${image_name}") ]]
|
||||
then
|
||||
docker pull ghcr.io/zalando/postgres-operator:latest
|
||||
if ! docker pull "${image_name}"
|
||||
then
|
||||
echo "Failed to pull operator image: ${image_name}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
operator_image=$(docker images --filter=reference="ghcr.io/zalando/postgres-operator" --format "{{.Repository}}:{{.Tag}}" | head -1)
|
||||
operator_image="${image_name}"
|
||||
echo "Using operator image: ${operator_image}"
|
||||
}
|
||||
|
||||
function start_kind(){
|
||||
@@ -36,7 +49,9 @@ function start_kind(){
|
||||
|
||||
export KUBECONFIG="${kubeconfig_path}"
|
||||
kind create cluster --name ${cluster_name} --config kind-cluster-postgres-operator-e2e-tests.yaml
|
||||
docker pull "${spilo_image}"
|
||||
|
||||
echo "Pulling Spilo image for platform ${PLATFORM}"
|
||||
docker pull --platform ${PLATFORM} "${spilo_image}"
|
||||
kind load docker-image "${spilo_image}" --name ${cluster_name}
|
||||
}
|
||||
|
||||
@@ -52,7 +67,7 @@ function set_kind_api_server_ip(){
|
||||
# but update the IP address of the API server to the one from the Docker 'bridge' network
|
||||
readonly local kind_api_server_port=6443 # well-known in the 'kind' codebase
|
||||
readonly local kind_api_server=$(docker inspect --format "{{ .NetworkSettings.Networks.kind.IPAddress }}:${kind_api_server_port}" "${cluster_name}"-control-plane)
|
||||
sed -i "s/server.*$/server: https:\/\/$kind_api_server/g" "${kubeconfig_path}"
|
||||
sed "s/server.*$/server: https:\/\/$kind_api_server/g" "${kubeconfig_path}" > "${kubeconfig_path}".tmp && mv "${kubeconfig_path}".tmp "${kubeconfig_path}"
|
||||
}
|
||||
|
||||
function generate_certificate(){
|
||||
|
||||
+24
-23
@@ -12,9 +12,9 @@ from kubernetes import client
|
||||
from tests.k8s_api import K8s
|
||||
from kubernetes.client.rest import ApiException
|
||||
|
||||
SPILO_CURRENT = "registry.opensource.zalan.do/acid/spilo-17-e2e:0.3"
|
||||
SPILO_LAZY = "registry.opensource.zalan.do/acid/spilo-17-e2e:0.4"
|
||||
SPILO_FULL_IMAGE = "ghcr.io/zalando/spilo-17:4.0-p3"
|
||||
SPILO_CURRENT = "ghcr.io/zalando/spilo-e2e:dev-18.3"
|
||||
SPILO_LAZY = "ghcr.io/zalando/spilo-e2e:dev-18.4"
|
||||
SPILO_FULL_IMAGE = "ghcr.io/zalando/spilo-18:4.1-p1"
|
||||
|
||||
def to_selector(labels):
|
||||
return ",".join(["=".join(lbl) for lbl in labels.items()])
|
||||
@@ -164,6 +164,7 @@ class EndToEndTestCase(unittest.TestCase):
|
||||
'default', label_selector='name=postgres-operator').items[0].spec.containers[0].image
|
||||
print("Tested operator image: {}".format(actual_operator_image)) # shows up after tests finish
|
||||
|
||||
# load minimal Postgres manifest and wait for cluster to be up and running
|
||||
result = k8s.create_with_kubectl("manifests/minimal-postgres-manifest.yaml")
|
||||
print('stdout: {}, stderr: {}'.format(result.stdout, result.stderr))
|
||||
try:
|
||||
@@ -1224,25 +1225,25 @@ class EndToEndTestCase(unittest.TestCase):
|
||||
k8s.create_with_kubectl("manifests/minimal-postgres-lowest-version-manifest.yaml")
|
||||
self.eventuallyEqual(lambda: k8s.count_running_pods(labels=cluster_label), 2, "No 2 pods running")
|
||||
self.eventuallyEqual(lambda: k8s.get_operator_state(), {"0": "idle"}, "Operator does not get in sync")
|
||||
self.eventuallyEqual(check_version, 13, "Version is not correct")
|
||||
self.eventuallyEqual(check_version, 14, "Version is not correct")
|
||||
|
||||
master_nodes, _ = k8s.get_cluster_nodes(cluster_labels=cluster_label)
|
||||
# should upgrade immediately
|
||||
pg_patch_version_14 = {
|
||||
pg_patch_version_higher_version = {
|
||||
"spec": {
|
||||
"postgresql": {
|
||||
"version": "14"
|
||||
"version": "15"
|
||||
}
|
||||
}
|
||||
}
|
||||
k8s.api.custom_objects_api.patch_namespaced_custom_object(
|
||||
"acid.zalan.do", "v1", "default", "postgresqls", "acid-upgrade-test", pg_patch_version_14)
|
||||
"acid.zalan.do", "v1", "default", "postgresqls", "acid-upgrade-test", pg_patch_version_higher_version)
|
||||
self.eventuallyEqual(lambda: k8s.get_operator_state(), {"0": "idle"}, "Operator does not get in sync")
|
||||
|
||||
k8s.wait_for_pod_failover(master_nodes, 'spilo-role=replica,' + cluster_label)
|
||||
k8s.wait_for_pod_start('spilo-role=master,' + cluster_label)
|
||||
k8s.wait_for_pod_start('spilo-role=replica,' + cluster_label)
|
||||
self.eventuallyEqual(check_version, 14, "Version should be upgraded from 13 to 14")
|
||||
self.eventuallyEqual(check_version, 15, "Version should be upgraded from 14 to 15")
|
||||
|
||||
# check if annotation for last upgrade's success is set
|
||||
annotations = get_annotations()
|
||||
@@ -1251,10 +1252,10 @@ class EndToEndTestCase(unittest.TestCase):
|
||||
# should not upgrade because current time is not in maintenanceWindow
|
||||
current_time = datetime.now()
|
||||
maintenance_window_future = f"{(current_time+timedelta(minutes=60)).strftime('%H:%M')}-{(current_time+timedelta(minutes=120)).strftime('%H:%M')}"
|
||||
pg_patch_version_15_outside_mw = {
|
||||
pg_patch_version_higher_version_outside_mw = {
|
||||
"spec": {
|
||||
"postgresql": {
|
||||
"version": "15"
|
||||
"version": "16"
|
||||
},
|
||||
"maintenanceWindows": [
|
||||
maintenance_window_future
|
||||
@@ -1262,23 +1263,23 @@ class EndToEndTestCase(unittest.TestCase):
|
||||
}
|
||||
}
|
||||
k8s.api.custom_objects_api.patch_namespaced_custom_object(
|
||||
"acid.zalan.do", "v1", "default", "postgresqls", "acid-upgrade-test", pg_patch_version_15_outside_mw)
|
||||
"acid.zalan.do", "v1", "default", "postgresqls", "acid-upgrade-test", pg_patch_version_higher_version_outside_mw)
|
||||
self.eventuallyEqual(lambda: k8s.get_operator_state(), {"0": "idle"}, "Operator does not get in sync")
|
||||
|
||||
# no pod replacement outside of the maintenance window
|
||||
k8s.wait_for_pod_start('spilo-role=master,' + cluster_label)
|
||||
k8s.wait_for_pod_start('spilo-role=replica,' + cluster_label)
|
||||
self.eventuallyEqual(check_version, 14, "Version should not be upgraded")
|
||||
self.eventuallyEqual(check_version, 15, "Version should not be upgraded")
|
||||
|
||||
second_annotations = get_annotations()
|
||||
self.assertIsNone(second_annotations.get("last-major-upgrade-failure"), "Annotation for last upgrade's failure should not be set")
|
||||
|
||||
# change maintenanceWindows to current
|
||||
maintenance_window_current = f"{(current_time-timedelta(minutes=30)).strftime('%H:%M')}-{(current_time+timedelta(minutes=30)).strftime('%H:%M')}"
|
||||
pg_patch_version_15_in_mw = {
|
||||
pg_patch_version_higher_version_in_mw = {
|
||||
"spec": {
|
||||
"postgresql": {
|
||||
"version": "15"
|
||||
"version": "16"
|
||||
},
|
||||
"maintenanceWindows": [
|
||||
maintenance_window_current
|
||||
@@ -1287,13 +1288,13 @@ class EndToEndTestCase(unittest.TestCase):
|
||||
}
|
||||
|
||||
k8s.api.custom_objects_api.patch_namespaced_custom_object(
|
||||
"acid.zalan.do", "v1", "default", "postgresqls", "acid-upgrade-test", pg_patch_version_15_in_mw)
|
||||
"acid.zalan.do", "v1", "default", "postgresqls", "acid-upgrade-test", pg_patch_version_higher_version_in_mw)
|
||||
self.eventuallyEqual(lambda: k8s.get_operator_state(), {"0": "idle"}, "Operator does not get in sync")
|
||||
|
||||
k8s.wait_for_pod_failover(master_nodes, 'spilo-role=master,' + cluster_label)
|
||||
k8s.wait_for_pod_start('spilo-role=master,' + cluster_label)
|
||||
k8s.wait_for_pod_start('spilo-role=replica,' + cluster_label)
|
||||
self.eventuallyEqual(check_version, 15, "Version should be upgraded from 14 to 15")
|
||||
self.eventuallyEqual(check_version, 16, "Version should be upgraded from 15 to 16")
|
||||
|
||||
# check if annotation for last upgrade's success is updated after second upgrade
|
||||
third_annotations = get_annotations()
|
||||
@@ -1301,7 +1302,7 @@ class EndToEndTestCase(unittest.TestCase):
|
||||
self.assertNotEqual(annotations.get("last-major-upgrade-success"), third_annotations.get("last-major-upgrade-success"), "Annotation for last upgrade's success is not updated")
|
||||
|
||||
# test upgrade with failed upgrade annotation
|
||||
pg_patch_version_17 = {
|
||||
pg_patch_version_highest_version = {
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"last-major-upgrade-failure": "2024-01-02T15:04:05Z"
|
||||
@@ -1309,28 +1310,28 @@ class EndToEndTestCase(unittest.TestCase):
|
||||
},
|
||||
"spec": {
|
||||
"postgresql": {
|
||||
"version": "17"
|
||||
"version": "18"
|
||||
},
|
||||
},
|
||||
}
|
||||
k8s.api.custom_objects_api.patch_namespaced_custom_object(
|
||||
"acid.zalan.do", "v1", "default", "postgresqls", "acid-upgrade-test", pg_patch_version_17)
|
||||
"acid.zalan.do", "v1", "default", "postgresqls", "acid-upgrade-test", pg_patch_version_highest_version)
|
||||
self.eventuallyEqual(lambda: k8s.get_operator_state(), {"0": "idle"}, "Operator does not get in sync")
|
||||
|
||||
k8s.wait_for_pod_failover(master_nodes, 'spilo-role=replica,' + cluster_label)
|
||||
k8s.wait_for_pod_start('spilo-role=master,' + cluster_label)
|
||||
k8s.wait_for_pod_start('spilo-role=replica,' + cluster_label)
|
||||
self.eventuallyEqual(check_version, 15, "Version should not be upgraded because annotation for last upgrade's failure is set")
|
||||
self.eventuallyEqual(check_version, 16, "Version should not be upgraded because annotation for last upgrade's failure is set")
|
||||
|
||||
# change the version back to 15 and should remove failure annotation
|
||||
# change the version back to 16 and should remove failure annotation
|
||||
k8s.api.custom_objects_api.patch_namespaced_custom_object(
|
||||
"acid.zalan.do", "v1", "default", "postgresqls", "acid-upgrade-test", pg_patch_version_15_in_mw)
|
||||
"acid.zalan.do", "v1", "default", "postgresqls", "acid-upgrade-test", pg_patch_version_higher_version_in_mw)
|
||||
self.eventuallyEqual(lambda: k8s.get_operator_state(), {"0": "idle"}, "Operator does not get in sync")
|
||||
|
||||
k8s.wait_for_pod_start('spilo-role=master,' + cluster_label)
|
||||
k8s.wait_for_pod_start('spilo-role=replica,' + cluster_label)
|
||||
|
||||
self.eventuallyEqual(check_version, 15, "Version should not be upgraded from 15")
|
||||
self.eventuallyEqual(check_version, 16, "Version should not be upgraded from 16")
|
||||
fourth_annotations = get_annotations()
|
||||
self.assertIsNone(fourth_annotations.get("last-major-upgrade-failure"), "Annotation for last upgrade's failure is not removed")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user