From eb3f7fcf1e2f432123242d42d9c62844715a0083 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Tue, 7 Apr 2020 08:53:55 +0200 Subject: [PATCH 01/15] exclude extra dir for generated code --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 991fe754f..4dab7c7b8 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ _testmain.go /vendor/ /build/ /docker/build/ +/github.com/ .idea scm-source.json From 8811dfd278235154e20f0732dfdfdc090f58d42c Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Tue, 7 Apr 2020 08:54:32 +0200 Subject: [PATCH 02/15] add a call to Patroni Api to fetch node state --- pkg/cluster/pod.go | 17 ++++++++++++ pkg/util/patroni/patroni.go | 53 ++++++++++++++++++++++++++++++++++++- 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/pkg/cluster/pod.go b/pkg/cluster/pod.go index 9991621cc..80e3e8235 100644 --- a/pkg/cluster/pod.go +++ b/pkg/cluster/pod.go @@ -294,6 +294,19 @@ func (c *Cluster) recreatePod(podName spec.NamespacedName) (*v1.Pod, error) { return pod, nil } +func (c *Cluster) isSafeToRecreatePods(pods *v1.PodList) bool { + + for _, pod := range pods.Items { + state, err := c.patroni.GetNodeState(&pod) + if err != nil || state != "running" { + c.logger.Warningf("cannot re-create pod %s: patroni not in 'running' state", pod.Name) + return false + } + + } + return true +} + func (c *Cluster) recreatePods() error { c.setProcessName("starting to recreate pods") ls := c.labelsSet(false) @@ -309,6 +322,10 @@ func (c *Cluster) recreatePods() error { } c.logger.Infof("there are %d pods in the cluster to recreate", len(pods.Items)) + if !c.isSafeToRecreatePods(pods) { + return fmt.Errorf("postpone pod recreation until next Sync: some pods are being initilalized and recreation is unsafe") + } + var ( masterPod, newMasterPod, newPod *v1.Pod ) diff --git a/pkg/util/patroni/patroni.go b/pkg/util/patroni/patroni.go index bdd96f048..76f0570c1 100644 --- a/pkg/util/patroni/patroni.go +++ b/pkg/util/patroni/patroni.go @@ -11,7 +11,7 @@ import ( "time" "github.com/sirupsen/logrus" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" ) const ( @@ -25,6 +25,31 @@ const ( type Interface interface { Switchover(master *v1.Pod, candidate string) error SetPostgresParameters(server *v1.Pod, options map[string]string) error + GetNodeState(pod *v1.Pod) (string, error) +} + +// HttpGetResponse contains data returned by Get to host/8008 +type HttpGetResponse struct { + State string `json:"type,omitempty"` + PostmasterStartTime string `json:"type,omitempty"` + Role string `json:"type,omitempty"` + ServerVersion int `json:"type,omitempty"` + ClusterUnlocked bool `json:"type,omitempty"` + Timeline int `json:"type,omitempty"` + Xlog Xlog `json:"type,omitempty"` + DatabaseSystemIdentifier string `json:"type,omitempty"` + patroniInfo Info `json:"type,omitempty"` +} + +// Xlog contains wal locaiton +type Xlog struct { + location int `json:"type,omitempty"` +} + +// Info cotains Patroni version and cluser scope +type Info struct { + version string `json:"type,omitempty"` + scope string `json:"type,omitempty"` } // Patroni API client @@ -123,3 +148,29 @@ func (p *Patroni) SetPostgresParameters(server *v1.Pod, parameters map[string]st } return p.httpPostOrPatch(http.MethodPatch, apiURLString+configPath, buf) } + +//GetNodeState returns node state reported by Patroni API call. +func (p *Patroni) GetNodeState(server *v1.Pod) (string, error) { + + var pResponse HttpGetResponse + + apiURLString, err := apiURL(server) + if err != nil { + return "", err + } + response, err := p.httpClient.Get(apiURLString) + if err != nil { + return "", fmt.Errorf("could not perform Get request: %v", err) + } + defer response.Body.Close() + + body, err := ioutil.ReadAll(response.Body) + + err = json.Unmarshal(body, &pResponse) + if err != nil { + return "", fmt.Errorf("could not unmarshal response: %v", err) + } + + return pResponse.State, nil + +} From af30a55efa27492791d6c5b71ebeb5c984b86608 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Tue, 7 Apr 2020 09:29:52 +0200 Subject: [PATCH 03/15] add comments --- pkg/cluster/pod.go | 12 ++++++++++-- pkg/util/patroni/patroni.go | 9 +++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/pkg/cluster/pod.go b/pkg/cluster/pod.go index 80e3e8235..41705968f 100644 --- a/pkg/cluster/pod.go +++ b/pkg/cluster/pod.go @@ -296,10 +296,18 @@ func (c *Cluster) recreatePod(podName spec.NamespacedName) (*v1.Pod, error) { func (c *Cluster) isSafeToRecreatePods(pods *v1.PodList) bool { + /* + Operator should not re-create pods if there is at least one replica being bootstrapped + because Patroni might use other replicas to take basebackup from (see Patroni's "clonefrom" tag). + + XXX operator cannot forbid replica re-init, so we might still fail if re-init is started + after this check succeeds but before a pod is re-created + */ + for _, pod := range pods.Items { state, err := c.patroni.GetNodeState(&pod) if err != nil || state != "running" { - c.logger.Warningf("cannot re-create pod %s: patroni not in 'running' state", pod.Name) + c.logger.Warningf("cannot re-create pod %s: patroni in %s state", pod.Name, state) return false } @@ -323,7 +331,7 @@ func (c *Cluster) recreatePods() error { c.logger.Infof("there are %d pods in the cluster to recreate", len(pods.Items)) if !c.isSafeToRecreatePods(pods) { - return fmt.Errorf("postpone pod recreation until next Sync: some pods are being initilalized and recreation is unsafe") + return fmt.Errorf("postpone pod recreation until next Sync: recreation is unsafe because pods are being initilalized") } var ( diff --git a/pkg/util/patroni/patroni.go b/pkg/util/patroni/patroni.go index 76f0570c1..1e2158f01 100644 --- a/pkg/util/patroni/patroni.go +++ b/pkg/util/patroni/patroni.go @@ -38,18 +38,18 @@ type HttpGetResponse struct { Timeline int `json:"type,omitempty"` Xlog Xlog `json:"type,omitempty"` DatabaseSystemIdentifier string `json:"type,omitempty"` - patroniInfo Info `json:"type,omitempty"` + PatroniInfo Info `json:"type,omitempty"` } // Xlog contains wal locaiton type Xlog struct { - location int `json:"type,omitempty"` + Location int `json:"type,omitempty"` } // Info cotains Patroni version and cluser scope type Info struct { - version string `json:"type,omitempty"` - scope string `json:"type,omitempty"` + Version string `json:"type,omitempty"` + Scope string `json:"type,omitempty"` } // Patroni API client @@ -170,6 +170,7 @@ func (p *Patroni) GetNodeState(server *v1.Pod) (string, error) { if err != nil { return "", fmt.Errorf("could not unmarshal response: %v", err) } + p.logger.Infof("http get response: %s", pResponse) return pResponse.State, nil From ac46c954636a79ff5575d58f0512fa866153b8e0 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Tue, 7 Apr 2020 09:54:00 +0200 Subject: [PATCH 04/15] fix logging format --- pkg/util/patroni/patroni.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/util/patroni/patroni.go b/pkg/util/patroni/patroni.go index 1e2158f01..32d7e01f9 100644 --- a/pkg/util/patroni/patroni.go +++ b/pkg/util/patroni/patroni.go @@ -170,7 +170,7 @@ func (p *Patroni) GetNodeState(server *v1.Pod) (string, error) { if err != nil { return "", fmt.Errorf("could not unmarshal response: %v", err) } - p.logger.Infof("http get response: %s", pResponse) + p.logger.Infof("http get response: %+v", pResponse) return pResponse.State, nil From 84dc06bfb755482c41ee1ca096f52436b92e0ac7 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Tue, 7 Apr 2020 16:50:56 +0200 Subject: [PATCH 05/15] fix json unmarshalling --- pkg/util/patroni/patroni.go | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/pkg/util/patroni/patroni.go b/pkg/util/patroni/patroni.go index 32d7e01f9..ca7bcd6bf 100644 --- a/pkg/util/patroni/patroni.go +++ b/pkg/util/patroni/patroni.go @@ -30,26 +30,26 @@ type Interface interface { // HttpGetResponse contains data returned by Get to host/8008 type HttpGetResponse struct { - State string `json:"type,omitempty"` - PostmasterStartTime string `json:"type,omitempty"` - Role string `json:"type,omitempty"` - ServerVersion int `json:"type,omitempty"` - ClusterUnlocked bool `json:"type,omitempty"` - Timeline int `json:"type,omitempty"` - Xlog Xlog `json:"type,omitempty"` - DatabaseSystemIdentifier string `json:"type,omitempty"` - PatroniInfo Info `json:"type,omitempty"` + State string `json:"state,omitempty"` + PostmasterStartTime string `json:"posmaster_start_time,omitempty"` + Role string `json:"role,omitempty"` + ServerVersion int `json:"server_version,omitempty"` + ClusterUnlocked bool `json:"cluster_unlocked,omitempty"` + Timeline int `json:"timeline,omitempty"` + Xlog Xlog `json:"xlog"` + DatabaseSystemIdentifier string `json:"database_system_indetifier,omitempty"` + PatroniInfo Info `json:"patroni"` } // Xlog contains wal locaiton type Xlog struct { - Location int `json:"type,omitempty"` + Location int `json:"location"` } // Info cotains Patroni version and cluser scope type Info struct { - Version string `json:"type,omitempty"` - Scope string `json:"type,omitempty"` + Version string `json:"version,omitempty"` + Scope string `json:"scope,omitempty"` } // Patroni API client @@ -164,13 +164,18 @@ func (p *Patroni) GetNodeState(server *v1.Pod) (string, error) { } defer response.Body.Close() + p.logger.Infof("http get response: %+v", response) + body, err := ioutil.ReadAll(response.Body) + if err != nil { + return "", fmt.Errorf("could not read response: %v", err) + } err = json.Unmarshal(body, &pResponse) if err != nil { return "", fmt.Errorf("could not unmarshal response: %v", err) } - p.logger.Infof("http get response: %+v", pResponse) + p.logger.Infof("parsed http get response: %+v", pResponse) return pResponse.State, nil From 7a37693c4dc313fc65f39cba0f0f14784af80398 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Wed, 8 Apr 2020 08:25:28 +0200 Subject: [PATCH 06/15] make check condition more specific --- pkg/cluster/pod.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/cluster/pod.go b/pkg/cluster/pod.go index 41705968f..3070f114b 100644 --- a/pkg/cluster/pod.go +++ b/pkg/cluster/pod.go @@ -306,7 +306,7 @@ func (c *Cluster) isSafeToRecreatePods(pods *v1.PodList) bool { for _, pod := range pods.Items { state, err := c.patroni.GetNodeState(&pod) - if err != nil || state != "running" { + if err != nil || state == "creating replica" { c.logger.Warningf("cannot re-create pod %s: patroni in %s state", pod.Name, state) return false } From 5ae17aae5e3d6b7fb053b1297904c1a9f0a1189d Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Wed, 8 Apr 2020 09:38:27 +0200 Subject: [PATCH 07/15] simplify json unmarshalling --- pkg/util/patroni/patroni.go | 42 +++++++++---------------------------- 1 file changed, 10 insertions(+), 32 deletions(-) diff --git a/pkg/util/patroni/patroni.go b/pkg/util/patroni/patroni.go index ca7bcd6bf..807d1ec36 100644 --- a/pkg/util/patroni/patroni.go +++ b/pkg/util/patroni/patroni.go @@ -3,6 +3,7 @@ package patroni import ( "bytes" "encoding/json" + "errors" "fmt" "io/ioutil" "net" @@ -28,30 +29,6 @@ type Interface interface { GetNodeState(pod *v1.Pod) (string, error) } -// HttpGetResponse contains data returned by Get to host/8008 -type HttpGetResponse struct { - State string `json:"state,omitempty"` - PostmasterStartTime string `json:"posmaster_start_time,omitempty"` - Role string `json:"role,omitempty"` - ServerVersion int `json:"server_version,omitempty"` - ClusterUnlocked bool `json:"cluster_unlocked,omitempty"` - Timeline int `json:"timeline,omitempty"` - Xlog Xlog `json:"xlog"` - DatabaseSystemIdentifier string `json:"database_system_indetifier,omitempty"` - PatroniInfo Info `json:"patroni"` -} - -// Xlog contains wal locaiton -type Xlog struct { - Location int `json:"location"` -} - -// Info cotains Patroni version and cluser scope -type Info struct { - Version string `json:"version,omitempty"` - Scope string `json:"scope,omitempty"` -} - // Patroni API client type Patroni struct { httpClient *http.Client @@ -152,8 +129,6 @@ func (p *Patroni) SetPostgresParameters(server *v1.Pod, parameters map[string]st //GetNodeState returns node state reported by Patroni API call. func (p *Patroni) GetNodeState(server *v1.Pod) (string, error) { - var pResponse HttpGetResponse - apiURLString, err := apiURL(server) if err != nil { return "", err @@ -164,19 +139,22 @@ func (p *Patroni) GetNodeState(server *v1.Pod) (string, error) { } defer response.Body.Close() - p.logger.Infof("http get response: %+v", response) - body, err := ioutil.ReadAll(response.Body) if err != nil { return "", fmt.Errorf("could not read response: %v", err) } - err = json.Unmarshal(body, &pResponse) + data := make(map[string]interface{}) + err = json.Unmarshal(body, &data) if err != nil { - return "", fmt.Errorf("could not unmarshal response: %v", err) + return "", err + } + + state, ok := data["state"].(string) + if !ok { + return "", errors.New("Patroni Get call rerturned wrong type for 'state' field") } - p.logger.Infof("parsed http get response: %+v", pResponse) - return pResponse.State, nil + return state, nil } From 3814e8983043a3d0c977d5e76742854cdfe37504 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Wed, 8 Apr 2020 09:41:52 +0200 Subject: [PATCH 08/15] fix log message --- pkg/cluster/pod.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/cluster/pod.go b/pkg/cluster/pod.go index 3070f114b..6ad1c051e 100644 --- a/pkg/cluster/pod.go +++ b/pkg/cluster/pod.go @@ -307,7 +307,7 @@ func (c *Cluster) isSafeToRecreatePods(pods *v1.PodList) bool { for _, pod := range pods.Items { state, err := c.patroni.GetNodeState(&pod) if err != nil || state == "creating replica" { - c.logger.Warningf("cannot re-create pod %s: patroni in %s state", pod.Name, state) + c.logger.Warningf("cannot re-create replica %s: it is currently being initialized", pod.Name) return false } From 3e639676c43a475f82056e452a57e951abe0fdd1 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Wed, 8 Apr 2020 09:44:01 +0200 Subject: [PATCH 09/15] fix error description --- pkg/util/patroni/patroni.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/util/patroni/patroni.go b/pkg/util/patroni/patroni.go index 807d1ec36..cc8cd9c18 100644 --- a/pkg/util/patroni/patroni.go +++ b/pkg/util/patroni/patroni.go @@ -152,7 +152,7 @@ func (p *Patroni) GetNodeState(server *v1.Pod) (string, error) { state, ok := data["state"].(string) if !ok { - return "", errors.New("Patroni Get call rerturned wrong type for 'state' field") + return "", errors.New("Patroni Get call response contains wrong type for 'state' field") } return state, nil From e9db2f07e10257390dae7fbbbf3a435773efe011 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Thu, 9 Apr 2020 10:40:11 +0200 Subject: [PATCH 10/15] add skeleton for e2e test --- e2e/tests/test_e2e.py | 72 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/e2e/tests/test_e2e.py b/e2e/tests/test_e2e.py index 445067d61..2534fec44 100644 --- a/e2e/tests/test_e2e.py +++ b/e2e/tests/test_e2e.py @@ -268,6 +268,66 @@ def test_logical_backup_cron_job(self): self.assertEqual(0, len(jobs), "Expected 0 logical backup jobs, found {}".format(len(jobs))) + + @timeout_decorator.timeout(TEST_TIMEOUT_SEC) + def test_safe_pod_recreation(self): + ''' + Operator skips pods re-creation if there is at least one pod for which patroni reports "creating replica" state + ''' + + k8s = self.k8s + nodes = self.get_pg_nodes() + + # get test data for re-init + master = nodes[0] + cmd = 'pgbench -i -s 30 -n' + k8s.exec_into_pod(master, cmd) + + # start reinit + replica = nodes[1][0] + cmd = 'patronictl reinit $SCOPE ' + replica + k8s.exec_into_pod(master, cmd) + + # force rolling upgrade + patch = { + "spec": { + "resources": { + "requests": { + "cpu": "100m", + "memory": "50Mi" + }, + "limits": { + "cpu": "200m", + "memory": "200Mi" + } + } + } + } + k8s.api.custom_objects_api.patch_namespaced_custom_object( + "acid.zalan.do", "v1", "default", "postgresqls", "acid-minimal-cluster", patch) + + replica_state = "" + while replica_state != "running": + replica_state = k8s.get_patroni_state(self, replica) + time.sleep(k8s.RETRY_TIMEOUT_SEC) + + # next Sync does the update + k8s.delete_operator_pod() + k8s.wait_for_pod_start('spilo-role=replica') + + cluster_label = 'application=spilo,cluster-name=acid-minimal-cluster' + labels = 'spilo-role=master,' + cluster_label + + pods = k8s.api.core_v1.list_namespaced_pod( + 'default', label_selector=labels).items + self.assert_master_is_unique() + masterPod = pods[0] + + self.assertEqual(masterPod.spec.containers[0].resources.requests['cpu'], "100m", + "Expected CPU requests {}, found {}" + .format("100cpu", masterPod.spec.containers[0].resources.requests['cpu'])) + + @timeout_decorator.timeout(TEST_TIMEOUT_SEC) def test_min_resource_limits(self): ''' @@ -709,20 +769,26 @@ def wait_for_logical_backup_job_deletion(self): def wait_for_logical_backup_job_creation(self): self.wait_for_logical_backup_job(expected_num_of_jobs=1) - def update_config(self, config_map_patch): - self.api.core_v1.patch_namespaced_config_map("postgres-operator", "default", config_map_patch) - + def delete_operator_pod(self): operator_pod = self.api.core_v1.list_namespaced_pod( 'default', label_selector="name=postgres-operator").items[0].metadata.name self.api.core_v1.delete_namespaced_pod(operator_pod, "default") # restart reloads the conf self.wait_for_operator_pod_start() + def update_config(self, config_map_patch): + self.api.core_v1.patch_namespaced_config_map("postgres-operator", "default", config_map_patch) + self.delete_operator_pod() + def create_with_kubectl(self, path): return subprocess.run( ["kubectl", "create", "-f", path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + def get_patroni_state(self, pod): + return pod.metadata.annotations["status"]["state"] + + if __name__ == '__main__': unittest.main() From db30ab390f8a83d84ed6236c78d45c042be9e32f Mon Sep 17 00:00:00 2001 From: Felix Kunde Date: Thu, 16 Apr 2020 09:41:18 +0200 Subject: [PATCH 11/15] disable e2e tests temporarliy --- e2e/tests/test_e2e.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/tests/test_e2e.py b/e2e/tests/test_e2e.py index 2534fec44..70821c267 100644 --- a/e2e/tests/test_e2e.py +++ b/e2e/tests/test_e2e.py @@ -268,7 +268,7 @@ def test_logical_backup_cron_job(self): self.assertEqual(0, len(jobs), "Expected 0 logical backup jobs, found {}".format(len(jobs))) - + """ @timeout_decorator.timeout(TEST_TIMEOUT_SEC) def test_safe_pod_recreation(self): ''' @@ -326,7 +326,7 @@ def test_safe_pod_recreation(self): self.assertEqual(masterPod.spec.containers[0].resources.requests['cpu'], "100m", "Expected CPU requests {}, found {}" .format("100cpu", masterPod.spec.containers[0].resources.requests['cpu'])) - + """ @timeout_decorator.timeout(TEST_TIMEOUT_SEC) def test_min_resource_limits(self): From 48c3d6ac88654f8f96c9374c2ac833057e422291 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Mon, 20 Apr 2020 14:01:13 +0200 Subject: [PATCH 12/15] remove test skeleton --- e2e/tests/test_e2e.py | 60 ------------------------------------------- 1 file changed, 60 deletions(-) diff --git a/e2e/tests/test_e2e.py b/e2e/tests/test_e2e.py index 70821c267..43cc2bbe4 100644 --- a/e2e/tests/test_e2e.py +++ b/e2e/tests/test_e2e.py @@ -268,66 +268,6 @@ def test_logical_backup_cron_job(self): self.assertEqual(0, len(jobs), "Expected 0 logical backup jobs, found {}".format(len(jobs))) - """ - @timeout_decorator.timeout(TEST_TIMEOUT_SEC) - def test_safe_pod_recreation(self): - ''' - Operator skips pods re-creation if there is at least one pod for which patroni reports "creating replica" state - ''' - - k8s = self.k8s - nodes = self.get_pg_nodes() - - # get test data for re-init - master = nodes[0] - cmd = 'pgbench -i -s 30 -n' - k8s.exec_into_pod(master, cmd) - - # start reinit - replica = nodes[1][0] - cmd = 'patronictl reinit $SCOPE ' + replica - k8s.exec_into_pod(master, cmd) - - # force rolling upgrade - patch = { - "spec": { - "resources": { - "requests": { - "cpu": "100m", - "memory": "50Mi" - }, - "limits": { - "cpu": "200m", - "memory": "200Mi" - } - } - } - } - k8s.api.custom_objects_api.patch_namespaced_custom_object( - "acid.zalan.do", "v1", "default", "postgresqls", "acid-minimal-cluster", patch) - - replica_state = "" - while replica_state != "running": - replica_state = k8s.get_patroni_state(self, replica) - time.sleep(k8s.RETRY_TIMEOUT_SEC) - - # next Sync does the update - k8s.delete_operator_pod() - k8s.wait_for_pod_start('spilo-role=replica') - - cluster_label = 'application=spilo,cluster-name=acid-minimal-cluster' - labels = 'spilo-role=master,' + cluster_label - - pods = k8s.api.core_v1.list_namespaced_pod( - 'default', label_selector=labels).items - self.assert_master_is_unique() - masterPod = pods[0] - - self.assertEqual(masterPod.spec.containers[0].resources.requests['cpu'], "100m", - "Expected CPU requests {}, found {}" - .format("100cpu", masterPod.spec.containers[0].resources.requests['cpu'])) - """ - @timeout_decorator.timeout(TEST_TIMEOUT_SEC) def test_min_resource_limits(self): ''' From 4b78ff5dabfa491a42df9dc574a7adaa1a3b7d20 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Mon, 20 Apr 2020 14:02:49 +0200 Subject: [PATCH 13/15] fix flake8 violations --- e2e/tests/test_e2e.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/e2e/tests/test_e2e.py b/e2e/tests/test_e2e.py index 43cc2bbe4..6364fa398 100644 --- a/e2e/tests/test_e2e.py +++ b/e2e/tests/test_e2e.py @@ -344,7 +344,6 @@ def test_node_readiness_label(self): ''' k8s = self.k8s cluster_label = 'application=spilo,cluster-name=acid-minimal-cluster' - labels = 'spilo-role=master,' + cluster_label readiness_label = 'lifecycle-status' readiness_value = 'ready' @@ -729,6 +728,5 @@ def get_patroni_state(self, pod): return pod.metadata.annotations["status"]["state"] - if __name__ == '__main__': unittest.main() From 0c5dfeab064e51228348d1b8cea68e4981aba256 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Mon, 20 Apr 2020 14:05:33 +0200 Subject: [PATCH 14/15] rename --- pkg/cluster/pod.go | 2 +- pkg/util/patroni/patroni.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/cluster/pod.go b/pkg/cluster/pod.go index 6ad1c051e..a734e4835 100644 --- a/pkg/cluster/pod.go +++ b/pkg/cluster/pod.go @@ -305,7 +305,7 @@ func (c *Cluster) isSafeToRecreatePods(pods *v1.PodList) bool { */ for _, pod := range pods.Items { - state, err := c.patroni.GetNodeState(&pod) + state, err := c.patroni.GetPatroniMemberState(&pod) if err != nil || state == "creating replica" { c.logger.Warningf("cannot re-create replica %s: it is currently being initialized", pod.Name) return false diff --git a/pkg/util/patroni/patroni.go b/pkg/util/patroni/patroni.go index cc8cd9c18..008dc3e58 100644 --- a/pkg/util/patroni/patroni.go +++ b/pkg/util/patroni/patroni.go @@ -26,7 +26,7 @@ const ( type Interface interface { Switchover(master *v1.Pod, candidate string) error SetPostgresParameters(server *v1.Pod, options map[string]string) error - GetNodeState(pod *v1.Pod) (string, error) + GetPatroniMemberState(pod *v1.Pod) (string, error) } // Patroni API client @@ -126,8 +126,8 @@ func (p *Patroni) SetPostgresParameters(server *v1.Pod, parameters map[string]st return p.httpPostOrPatch(http.MethodPatch, apiURLString+configPath, buf) } -//GetNodeState returns node state reported by Patroni API call. -func (p *Patroni) GetNodeState(server *v1.Pod) (string, error) { +//GetPatroniMemberState returns node state reported by Patroni API call. +func (p *Patroni) GetPatroniMemberState(server *v1.Pod) (string, error) { apiURLString, err := apiURL(server) if err != nil { From 5e35ea737e71ffb8400e71bef057b767274dbb83 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Mon, 20 Apr 2020 14:32:05 +0200 Subject: [PATCH 15/15] remove dead code --- e2e/tests/test_e2e.py | 3 --- pkg/util/patroni/patroni.go | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/e2e/tests/test_e2e.py b/e2e/tests/test_e2e.py index 6364fa398..f46c0577e 100644 --- a/e2e/tests/test_e2e.py +++ b/e2e/tests/test_e2e.py @@ -724,9 +724,6 @@ def create_with_kubectl(self, path): stdout=subprocess.PIPE, stderr=subprocess.PIPE) - def get_patroni_state(self, pod): - return pod.metadata.annotations["status"]["state"] - if __name__ == '__main__': unittest.main() diff --git a/pkg/util/patroni/patroni.go b/pkg/util/patroni/patroni.go index 008dc3e58..53065e599 100644 --- a/pkg/util/patroni/patroni.go +++ b/pkg/util/patroni/patroni.go @@ -126,7 +126,7 @@ func (p *Patroni) SetPostgresParameters(server *v1.Pod, parameters map[string]st return p.httpPostOrPatch(http.MethodPatch, apiURLString+configPath, buf) } -//GetPatroniMemberState returns node state reported by Patroni API call. +//GetPatroniMemberState returns a state of member of a Patroni cluster func (p *Patroni) GetPatroniMemberState(server *v1.Pod) (string, error) { apiURLString, err := apiURL(server)