def perform_self_unregistration(cluster=None): """Attempt self removal during unit teardown.""" etcdctl = EtcdCtl() leader_address = leader_get("leader_address") unit_name = os.getenv("JUJU_UNIT_NAME").replace("/", "") members = etcdctl.member_list() # Self Unregistration etcdctl.unregister(members[unit_name]["unit_id"], leader_address)
def perform_self_unregistration(cluster=None): ''' Attempt self removal during unit teardown. ''' etcdctl = EtcdCtl() leader_address = leader_get('leader_address') unit_name = os.getenv('JUJU_UNIT_NAME').replace('/', '') members = etcdctl.member_list() # Self Unregistration etcdctl.unregister(members[unit_name]['unit_id'], leader_address)
def unregister(cluster): ''' The leader will process the departing event and attempt unregistration for the departing unit. If the leader is departing, it will unregister all units prior to termination. ''' etcdctl = EtcdCtl() peers = cluster.get_peers() members = etcdctl.member_list() for unit in peers: cluster_name = unit.replace('/', '') if cluster_name in members.keys(): log("Unregistering {0}".format(unit)) etcdctl.unregister(members[cluster_name]['unit_id']) else: log("Received removal for disconnected member {}".format(unit)) cluster.dismiss()
def dismantle_cluster(): """Disconnect other cluster members. This is a preparation step before restoring snapshot on the cluster. """ log('Disconnecting cluster members') etcdctl = EtcdCtl() etcd_conf = EtcdDatabag() my_name = etcd_conf.unit_name endpoint = 'https://{}:{}'.format(etcd_conf.cluster_address, etcd_conf.port) for name, data in etcdctl.member_list(endpoint).items(): if name != my_name: log('Disconnecting {}'.format(name), hookenv.DEBUG) etcdctl.unregister(data['unit_id'], endpoint) etcd_conf.cluster_state = 'new' conf_path = os.path.join(etcd_conf.etcd_conf_dir, "etcd.conf.yml") render('etcd3.conf', conf_path, etcd_conf.__dict__, owner='root', group='root')
def register_node_with_leader(cluster): ''' Control flow mechanism to perform self registration with the leader. Before executing self registration, we must adhere to the nature of offline static turnup rules. If we find a GUID in the member list without peering information the unit will enter a race condition and must wait for a clean status output before we can progress to self registration. ''' etcdctl = EtcdCtl() bag = EtcdDatabag() leader_address = leader_get('leader_address') bag.leader_address = leader_address try: # Check if we are already registered. Unregister ourselves if we are so # we can register from scratch. peer_url = 'https://%s:%s' % (bag.cluster_address, bag.management_port) members = etcdctl.member_list(leader_address) for member_name, member in members.items(): if member['peer_urls'] == peer_url: log('Found member that matches our peer URL. Unregistering...') etcdctl.unregister(member['unit_id'], leader_address) # Now register. resp = etcdctl.register(bag.__dict__) bag.cluster = resp['cluster'] except EtcdCtl.CommandFailed: log('etcdctl.register failed, will retry') msg = 'Waiting to retry etcd registration' status_set('waiting', msg) return render_config(bag) host.service_restart(bag.etcd_daemon) open_port(bag.port) set_state('etcd.registered')
def register_node_with_leader(cluster): """ Control flow mechanism to perform self registration with the leader. Before executing self registration, we must adhere to the nature of offline static turnup rules. If we find a GUID in the member list without peering information the unit will enter a race condition and must wait for a clean status output before we can progress to self registration. """ etcdctl = EtcdCtl() bag = EtcdDatabag() leader_address = leader_get("leader_address") bag.leader_address = leader_address try: # Check if we are already registered. Unregister ourselves if we are so # we can register from scratch. peer_url = "https://%s:%s" % (bag.cluster_address, bag.management_port) members = etcdctl.member_list(leader_address) for _, member in members.items(): if member["peer_urls"] == peer_url: log("Found member that matches our peer URL. Unregistering...") etcdctl.unregister(member["unit_id"], leader_address) # Now register. resp = etcdctl.register(bag.__dict__) bag.set_cluster(resp["cluster"]) except EtcdCtl.CommandFailed: log("etcdctl.register failed, will retry") msg = "Waiting to retry etcd registration" status.waiting(msg) return render_config(bag) host.service_restart(bag.etcd_daemon) open_port(bag.port) set_state("etcd.registered")
def register_node_with_leader(cluster): ''' Control flow mechanism to perform self registration with the leader. Before executing self registration, we must adhere to the nature of offline static turnup rules. If we find a GUID in the member list without peering information the unit will enter a race condition and must wait for a clean status output before we can progress to self registration. ''' # We're going to communicate with the leader, and we need our bootstrap # startup string once.. TBD after that. etcdctl = EtcdCtl() bag = EtcdDatabag() # Assume a hiccup during registration and attempt a retry if bag.cluster_unit_id: bag.cluster = bag.registration_peer_string # conf_path = '{}/etcd.conf'.format(bag.etcd_conf_dir) render_config(bag) time.sleep(2) try: peers = etcdctl.member_list(leader_get('leader_address')) except CalledProcessError: log("Etcd attempted to invoke registration before service ready") # This error state is transient, and does not imply the unit is broken. # Erroring at this stage can be resolved, and should not effect the # overall condition of unit turn-up. Return from the method and let the # charm re-invoke on next run return for unit in peers: if 'client_urls' not in peers[unit].keys(): msg = 'Waiting for unit to complete registration.' if ('peer_urls' in peers[unit].keys() and peers[unit]['peer_urls'] and get_ingress_address('cluster') in peers[unit]['peer_urls'] and # noqa not host.service_running(bag.etcd_daemon)): # We have a peer that is unstarted and it is this node. # We do not run etcd now. Instead of blocking everyone # try to self-unregister. try: leader_address = leader_get('leader_address') msg = 'Etcd service did not start. Will retry soon.' etcdctl.unregister(peers[unit]['unit_id'], leader_address) except CalledProcessError: log('Notice: Unit failed to unregister', 'WARNING') # we cannot register. State not attainable. status_set('waiting', msg) return if not bag.cluster_unit_id: bag.leader_address = leader_get('leader_address') resp = etcdctl.register(bag.__dict__) if resp and 'cluster_unit_id' in resp.keys() and 'cluster' in resp.keys(): # noqa bag.cache_registration_detail('cluster_unit_id', resp['cluster_unit_id']) bag.cache_registration_detail('registration_peer_string', resp['cluster']) bag.cluster_unit_id = resp['cluster_unit_id'] bag.cluster = resp['cluster'] else: log('etcdctl.register failed, will retry') msg = 'Waiting to retry etcd registration' status_set('waiting', msg) return render_config(bag) host.service_restart(bag.etcd_daemon) time.sleep(2) # Check health status before we say we are good etcdctl = EtcdCtl() status = etcdctl.cluster_health() if 'unhealthy' in status: status_set('blocked', 'Cluster not healthy.') return open_port(bag.port) set_state('etcd.registered')