@@ -41,23 +41,53 @@ def discover_peers(service_record):
41
41
max_tries = 10
42
42
)
43
43
def connect_the_dots (names ):
44
- creds = (os .getenv ("COUCHDB_USER" ), os .getenv ("COUCHDB_PASSWORD" ))
44
+
45
+ # Ordinal Index: For a StatefulSet with N replicas, each Pod in the StatefulSet
46
+ # will be assigned an integer ordinal, from 0 up through N-1, that is unique over the Set.
47
+ # Approach: get the Ordinal index of this pod and make sure that the list of name
48
+ # include all those ordinals.
49
+ # By looking at this pods Ordinal, make sure that all DNS records for
50
+ # pods having lesser Ordinal are found before adding any nodes to CouchDB.
51
+ # This is done to PREVENT the following case:
52
+ # (1) POD with ordnial 1 get DNS records for ordinal 1 and 2.
53
+ # (2) POD with ordinal 2 get DNS records for ordinal 1 and 2.
54
+ # (3) The are_nodes_in_sync function will give green light and
55
+ # no further discovery is taken place.
56
+ # (4) Pod with ordinal 0 will get are_nodes_in_sync=true and cluster
57
+ # setup will fail.
58
+
59
+ ordinal_of_this_pod = int (os .getenv ("HOSTNAME" ).split ("-" )[- 1 ])
60
+ expected_ordinals = set (range (0 , ordinal_of_this_pod ))
61
+ found_ordinals = Set ()
45
62
for name in names :
46
- uri = "http://127.0.0.1:5986/_nodes/couchdb@{0}" .format (name )
47
- doc = {}
48
- if creds [0 ] and creds [1 ]:
49
- resp = requests .put (uri , data = json .dumps (doc ), auth = creds )
50
- else :
51
- resp = requests .put (uri , data = json .dumps (doc ))
52
- while resp .status_code != 201 and resp .status_code != 409 :
53
- print ('Waiting for _nodes DB to be created.' ,uri ,'returned' , resp .status_code , resp .json (), flush = True )
54
- time .sleep (5 )
63
+ # Get the podname, get the stuff after last - and convert to int
64
+ found_ordinals .add (int (name .split ("." ,1 )[0 ].split ("-" )[- 1 ]));
65
+
66
+ print ("expected_ordinals" ,expected_ordinals )
67
+ print ("found ordnials" ,found_ordinals )
68
+
69
+ # Are all expected_ordinals are part of found_ordinals?
70
+ if ( expected_ordinals - found_ordinals ):
71
+ print ('Expected to get at least pod(s)' , expected_ordinals - found_ordinals , 'among the DNS records. Will retry.' )
72
+ else :
73
+ creds = (os .getenv ("COUCHDB_USER" ), os .getenv ("COUCHDB_PASSWORD" ))
74
+ for name in names :
75
+ uri = "http://127.0.0.1:5986/_nodes/couchdb@{0}" .format (name )
76
+ doc = {}
77
+
55
78
if creds [0 ] and creds [1 ]:
56
79
resp = requests .put (uri , data = json .dumps (doc ), auth = creds )
57
80
else :
58
81
resp = requests .put (uri , data = json .dumps (doc ))
59
- if resp .status_code == 201 :
60
- print ('Adding CouchDB cluster node' , name , "to this pod's CouchDB. Response code:" , resp .status_code ,flush = True )
82
+ while resp .status_code != 201 and resp .status_code != 409 :
83
+ print ('Waiting for _nodes DB to be created.' ,uri ,'returned' , resp .status_code , resp .json (), flush = True )
84
+ time .sleep (5 )
85
+ if creds [0 ] and creds [1 ]:
86
+ resp = requests .put (uri , data = json .dumps (doc ), auth = creds )
87
+ else :
88
+ resp = requests .put (uri , data = json .dumps (doc ))
89
+ if resp .status_code == 201 :
90
+ print ('Adding CouchDB cluster node' , name , "to this pod's CouchDB. Response code:" , resp .status_code ,flush = True )
61
91
62
92
# Compare (json) objects - order does not matter. Credits to:
63
93
# https://stackoverflow.com/a/25851972
0 commit comments