|
39 | 39 | this machine. |
40 | 40 | 2015 12 Aug - Tweaked to allow for the case where the host |
41 | 41 | isn't in DNS. |
| 42 | + 2015 27 Aug - Work around to recognize fqdn's |
42 | 43 | ------------------------------------------------------------------------------ |
43 | 44 |
|
44 | 45 | Algorithm |
|
99 | 100 | STDBY_FILE = ETCDIR + '/standby' |
100 | 101 | VERBOSE = 0 |
101 | 102 |
|
| 103 | +TEGUCONF_FILE = ETCDIR + '/tegu.cfg' |
| 104 | + |
102 | 105 | def logit(msg): |
103 | 106 | '''Log error message on stdout with timestamp''' |
104 | 107 | now = time.gmtime() |
@@ -136,37 +139,32 @@ def get_checkpoint(host=''): |
136 | 139 | warn("Could not sync chkpts from %s" % host) |
137 | 140 | return False |
138 | 141 |
|
139 | | -def my_aliases(): |
140 | | - ''' |
141 | | - returns a map (dictionary?) of alias names. if map[name] == true then |
142 | | - name is an alias for this host. |
143 | | -
|
144 | | - this works if hostname returns foo and aliases are some 'extension' |
145 | | - of foo (e.g. foo-ops), but if foo-ops is returned by host name |
146 | | - we won't find foo. |
147 | | - ''' |
148 | | - |
149 | | - p = subprocess.Popen( ["hostname", "-f"], stdout=subprocess.PIPE, shell=False ) |
150 | | - sout = p.communicate()[0] # get standard out buf |
151 | | - recs = str.split( sout, "\n" ) # split output into records |
152 | | - toks = str.split( recs[0], ".", 1 ) # host and domain tokens |
153 | | - |
154 | | - map = {} |
155 | | - if len( toks ) == 1: # odd case where -f returns just foo and not foo.domain |
156 | | - map[toks[0]] = True |
157 | | - else: |
158 | | - p1 = subprocess.Popen( ["dig", toks[1], "axfr"], stdout=subprocess.PIPE ) |
159 | | - p2 = subprocess.Popen( ["sed", "-r", "/^" + toks[0] + "[^a-zA-Z0-9]/! d; s/. .*//"], |
160 | | - stdin=p1.stdout, stdout=subprocess.PIPE ) |
161 | | - for a in str.split( p2.communicate()[0], "\n" ): |
162 | | - if not a == None and not a == "": |
163 | | - map[a] = True |
164 | | - |
165 | | - if len( map ) < 1: |
166 | | - map[recs[0]] = True # nothing back from dig, just use fqdn |
167 | | - |
168 | | - return map |
169 | | - |
| 142 | +def parse_teguconfig(): |
| 143 | + ''' This function reads the tegu config file and returns configuration |
| 144 | + attributes in key/value format ''' |
| 145 | + cdata = {} |
| 146 | + section = "default" |
| 147 | + cdata[section] = {} |
| 148 | + try: |
| 149 | + with open(TEGUCONF_FILE, "r") as tegufile: |
| 150 | + for line in tegufile.readlines(): |
| 151 | + if line.strip(" \t\r\n")[:1] == '#': |
| 152 | + continue |
| 153 | + elif line.lstrip(" \t")[:1] == ":": |
| 154 | + toks = line.lstrip(" \t").split(" ") |
| 155 | + section = toks[0][1:].strip("\n") |
| 156 | + cdata[section] = {} |
| 157 | + else: |
| 158 | + if line[:1] == '\n': |
| 159 | + continue |
| 160 | + toks = line.split("=") |
| 161 | + key = toks[0].strip(" \t") |
| 162 | + value = toks[1].strip(" \t\n\r") |
| 163 | + cdata[section][key] = value |
| 164 | + return cdata |
| 165 | + except OSError: |
| 166 | + logit("unable to open %s file for some reason" % TEGUCONF_FILE) |
| 167 | + return |
170 | 168 |
|
171 | 169 | def extract_dt(dt_str, dt_col, tm_col): |
172 | 170 | ''' |
@@ -345,35 +343,42 @@ def main(): |
345 | 343 |
|
346 | 344 | logit("tegu_ha v1.0 started") |
347 | 345 |
|
| 346 | + cdata = parse_teguconfig() |
| 347 | + if not cdata["fqmgr"]["phost_suffix"]: |
| 348 | + cdata["fqmgr"]["phost_suffix"] = "" |
348 | 349 |
|
| 350 | + fqdn_list = [] |
| 351 | + this_node = socket.getfqdn() |
| 352 | + fqdn_list.append(this_node) |
| 353 | + fqdn_list.append(this_node.split(".")[0] + cdata["fqmgr"]["phost_suffix"] \ |
| 354 | + + this_node[this_node.index("."):]) |
349 | 355 | ok = False |
350 | 356 | mcount = 0 # critical error after an hour of waiting |
351 | 357 | while not ok: # loop until we find us |
352 | | - alias_map = my_aliases() # generate each time round in case dns changes |
353 | | - |
354 | | - ok = False |
| 358 | + ok = True |
355 | 359 | # Read list of standby tegu nodes and find us |
356 | 360 | standby_list = [l.strip() for l in open(STDBY_LIST, 'r')] |
357 | 361 |
|
358 | | - for i in range( len( standby_list ) ): |
359 | | - if alias_map.has_key( standby_list[i] ): |
360 | | - priority = i |
361 | | - ok = True |
362 | | - this_node = standby_list[i] |
363 | | - break |
364 | | - |
365 | | - if not ok: |
| 362 | + try: |
| 363 | + for fqdn in fqdn_list: |
| 364 | + if fqdn in standby_list: |
| 365 | + priority = standby_list.index(fqdn) |
| 366 | + this_node = fqdn |
| 367 | + break |
| 368 | + standby_list.remove(this_node) |
| 369 | + except ValueError: |
366 | 370 | if mcount == 0: # dont flood the log |
367 | | - logit("Could not find this host in standby list: %s (waiting)" % STDBY_LIST) |
368 | | - logit( "aliases for this host: %s" % alias_map ) |
| 371 | + logit("Could not find host "+this_node+" in standby list: %s (waiting)" % STDBY_LIST) |
369 | 372 | else: |
370 | 373 | if mcount == 60: |
371 | | - crit("Could not find this host in standby list: %s" % STDBY_LIST) |
| 374 | + crit("Could not find host "+this_node+" in standby list: %s" % STDBY_LIST) |
372 | 375 | mcount = 0 # another message in about an hour |
373 | 376 | mcount += 1 |
| 377 | + ok = False |
374 | 378 | time.sleep( 60 ) |
375 | 379 |
|
376 | | - logit( "host matched in standby list: %s priority=%d" % (standby_list[priority], priority) ) |
| 380 | + if mcount > 0: |
| 381 | + logit( "finally found host "+this_node+" in standby list: %s" % STDBY_LIST) |
377 | 382 |
|
378 | 383 | # Loop forever listening to heartbeats |
379 | 384 | main_loop(standby_list, this_node, priority) |
|
0 commit comments