def configure(server, features, parent, partition, memory, cpu, disk): """Create, get or modify server configuration""" if parent: path = parent.split('/') bucket = None for bucket, bucket_parent in zip(path, [None] + path[:-1]): masterapi.create_bucket(context.GLOBAL.zk.conn, bucket, bucket_parent) assert bucket is not None, 'server topology missing.' masterapi.create_server(context.GLOBAL.zk.conn, server, bucket, partition=partition) features = cli.combine(features) if features: # This is special case - reset features to empty. if features == ['-']: features = [] masterapi.update_server_features(context.GLOBAL.zk.conn, server, features) if memory or cpu or disk: masterapi.update_server_capacity(context.GLOBAL.zk.conn, server, memory=memory, cpu=cpu, disk=disk) server_obj = masterapi.get_server(context.GLOBAL.zk.conn, server) server_obj['name'] = server cli.out(formatter(server_obj))
def sync_server_topology(): """Sync servers into buckets in the masterapi. """ admin_srv = admin.Server(context.GLOBAL.ldap.conn) servers = admin_srv.list({'cell': context.GLOBAL.cell}) zkclient = context.GLOBAL.zk.conn # Cells are composed of buckets. The topology is ~1000 servers per pod # with each pod composed of racks, each ~40 servers. def _server_pod_rack(servername): # In the absence of any information about the server and topology, we # simply hash the servername and use the value to place the server in # a fictive topology of at most 4 pods, each with 16 racks. svr_hash = hashlib.md5(servername.encode()).hexdigest() svr_id = int(svr_hash, 16) # That is a 128 bit number pod = (svr_id >> (128 - 2)) # First 2 bits -> pod # below the first 2 bits, we take the rest, modulo 16 rack = (svr_id % (1 << (128 - 2))) % 16 return (pod, rack) for server in servers: servername = server['_id'] partition = server.get('partition') (pod, rack) = _server_pod_rack(servername) pod_bucket = 'pod:{:04X}'.format(pod) rack_bucket = 'rack:{:04X}'.format(rack) _LOGGER.info('Update: %r(partition:%r) -> %r, %r', servername, partition, pod_bucket, rack_bucket) masterapi.create_bucket(zkclient, pod_bucket, parent_id=None) masterapi.cell_insert_bucket(zkclient, pod_bucket) masterapi.create_bucket(zkclient, rack_bucket, parent_id=pod_bucket) masterapi.create_server( zkclient, servername, rack_bucket, partition=partition ) ldap_servers = set(server['_id'] for server in servers) zk_servers = set(masterapi.list_servers(zkclient)) zk_server_presence = set(zkclient.get_children(z.SERVER_PRESENCE)) for servername in zk_servers - ldap_servers: if servername in zk_server_presence: _LOGGER.warning('%s not in LDAP but node still present, skipping.', servername) else: _LOGGER.info('Delete: %s', servername) masterapi.delete_server(zkclient, servername)
def sync_servers(): """Sync servers and buckets.""" admin_srv = admin.Server(context.GLOBAL.ldap.conn) servers = admin_srv.list({'cell': context.GLOBAL.cell}) for server in servers: servername = server['_id'] rack = 'rack:unknown' building = 'building:unknown' traits = [] partition = None masterapi.create_bucket(context.GLOBAL.zk.conn, building, None) masterapi.cell_insert_bucket(context.GLOBAL.zk.conn, building) masterapi.create_bucket(context.GLOBAL.zk.conn, rack, building) masterapi.create_server(context.GLOBAL.zk.conn, servername, rack, partition=partition)