Add a dedicated primary key to keep master selection consistent

This commit is contained in:
Joshua Boniface 2018-09-29 01:45:23 -04:00
parent fa1e3591cb
commit a4bece898e
2 changed files with 27 additions and 7 deletions

View File

@ -201,6 +201,14 @@ else:
transaction.create('/routers/{}/ipmipassword'.format(myhostname), config['ipmi_password'].encode('ascii')) transaction.create('/routers/{}/ipmipassword'.format(myhostname), config['ipmi_password'].encode('ascii'))
transaction.commit() transaction.commit()
# Check that the primary key exists, and create it with us as master if not
current_primary = zkhandler.readdata(zk_conn, '/routers')
if current_primary:
print('Current primary router is {}"{}"{}.'.format(ansiiprint.blue(), current_primary, ansiiprint.end()))
else:
print('No primary router key found; creating with us as primary.')
zkhandler.writedata(zk_conn, { '/routers': myhostname })
zkhandler.writedata(zk_conn, { '/routers/{}/daemonstate'.format(myhostname): 'init' }) zkhandler.writedata(zk_conn, { '/routers/{}/daemonstate'.format(myhostname): 'init' })
t_router = dict() t_router = dict()
@ -224,6 +232,13 @@ this_router = t_router[myhostname]
update_zookeeper = this_router.update_zookeeper update_zookeeper = this_router.update_zookeeper
update_zookeeper() update_zookeeper()
@zk_conn.DataWatch('/routers')
def updateprimary(data, meta):
if data == myhostname:
this_router.set_primary()
else:
this_router.set_secondary()
@zk_conn.ChildrenWatch('/networks') @zk_conn.ChildrenWatch('/networks')
def updatenetworks(new_network_list): def updatenetworks(new_network_list):
global network_list global network_list
@ -239,10 +254,6 @@ def updatenetworks(new_network_list):
network_list = new_network_list network_list = new_network_list
print(ansiiprint.blue() + 'Network list: ' + ansiiprint.end() + '{}'.format(' '.join(network_list))) print(ansiiprint.blue() + 'Network list: ' + ansiiprint.end() + '{}'.format(' '.join(network_list)))
# Ensure we force startup of interfaces if we're primary
if this_router.getnetworkstate() == 'primary':
this_router.become_primary()
# Create timer to update this router in Zookeeper # Create timer to update this router in Zookeeper
def createKeepaliveTimer(): def createKeepaliveTimer():
interval = int(config['keepalive_interval']) interval = int(config['keepalive_interval'])

View File

@ -107,8 +107,12 @@ class RouterInstance():
self.s_network[network].removeAddress() self.s_network[network].removeAddress()
def set_secondary(self): def set_secondary(self):
zkhandler.writedata(self.zk_conn, { '/routers/{}/networkstate'.format(self.name): 'secondary' }) result = zkhandler.writedata(self.zk_conn, {
'/routers/{}/networkstate'.format(self.name): 'secondary'
})
if not result:
time.sleep(1)
def become_primary(self): def become_primary(self):
ansiiprint.echo('Setting router {} to primary state.'.format(self.name), '', 'i') ansiiprint.echo('Setting router {} to primary state.'.format(self.name), '', 'i')
ansiiprint.echo('Network list: {}'.format(', '.join(self.network_list)), '', 'c') ansiiprint.echo('Network list: {}'.format(', '.join(self.network_list)), '', 'c')
@ -120,7 +124,12 @@ class RouterInstance():
zkhandler.writedata(self.zk_conn, { '/routers/{}/networkstate'.format(self.t_router[router].getname()): 'secondary' }) zkhandler.writedata(self.zk_conn, { '/routers/{}/networkstate'.format(self.t_router[router].getname()): 'secondary' })
def set_primary(self): def set_primary(self):
zkhandler.writedata(self.zk_conn, { '/routers/{}/networkstate'.format(self.name): 'primary' }) result = zkhandler.writedata(self.zk_conn, {
'/routers/primary': self.name,
'/routers/{}/networkstate'.format(self.name): 'primary',
})
if not result:
time.sleep(1)
def update_zookeeper(self): def update_zookeeper(self):