def allocate_ip(skip=[]): global IP_CACHE global CACHE_LOCK docker_nodes = [h for h in Sense.docker_hosts() if h['status'] == 'passing'] network_settings = Sense.network_settings() subnet = network_settings['subnet'] gateway_ip = network_settings['gateway_ip'] if gateway_ip: skip += [gateway_ip] if not subnet: raise RuntimeError("Subnet is not specified in settings") invalidate_cache() with CACHE_LOCK: allocated_ips = set(IP_CACHE.keys()) # collect instances from blueprints for blueprint in Sense.blueprints().values(): for instance in blueprint['instances'].values(): allocated_ips.add(instance['addr']) net = ipaddress.ip_network(subnet) except_list = allocated_ips.union(set(skip)) for addr in net: if str(addr) not in except_list and\ not str(addr).endswith('.0'): IP_CACHE[str(addr)] = datetime.datetime.now() return str(addr) raise RuntimeError('IP Address range exhausted')
def blueprint(self): blueprints = Sense.blueprints() if self.group_id in blueprints: self._blueprint = blueprints[self.group_id] return self._blueprint
def allocate(memory, anti_affinity = []): docker_hosts = [h for h in Sense.docker_hosts() if (h['status'] == 'passing' and 'im' in h['tags'])] if not docker_hosts: raise RuntimeError("There are no healthy docker nodes") blueprints = Sense.blueprints() allocations = Sense.allocations() memory_used = {h['addr'].split(':')[0]: 0 for h in docker_hosts} for group_id, blueprint in blueprints.items(): if group_id not in allocations: continue memsize = blueprint['memsize'] for instance in allocations[group_id]['instances'].values(): host = instance['host'].split(':')[0] memory_used[host] = memory_used.get(host, 0) + memsize scores = [] for docker_host in docker_hosts: addr = docker_host['addr'].split(':')[0] free_mem = docker_host['memory'] - memory_used[addr] affinity = 0 if addr in anti_affinity else 1 scores.append((affinity, free_mem, docker_host)) sorted_scores = sorted(scores, reverse=True, key=lambda k: k[0:2]) for score in sorted_scores: docker_host = score[2] addr = docker_host['addr'].split(':')[0] free_mem = docker_host['memory'] - memory_used[addr] if free_mem > memory: logging.info("Allocating new instance with %d MiB memory at '%s'", memory, addr) return addr docker_host = sorted_scores[0][2] addr = docker_host['addr'].split(':')[0] logging.info("There were no hosts with %d MiB of free memory, " + "so allocating instance on '%s'", memory, addr) return addr
def allocate(memory, anti_affinity=[]): docker_hosts = [ h for h in Sense.docker_hosts() if (h['status'] == 'passing' and 'im' in h['tags']) ] if not docker_hosts: raise RuntimeError("There are no healthy docker nodes") blueprints = Sense.blueprints() allocations = Sense.allocations() memory_used = {h['addr'].split(':')[0]: 0 for h in docker_hosts} for group_id, blueprint in blueprints.items(): if group_id not in allocations: continue memsize = blueprint['memsize'] for instance in allocations[group_id]['instances'].values(): host = instance['host'].split(':')[0] memory_used[host] = memory_used.get(host, 0) + memsize scores = [] for docker_host in docker_hosts: addr = docker_host['addr'].split(':')[0] free_mem = docker_host['memory'] - memory_used[addr] affinity = 0 if addr in anti_affinity else 1 scores.append((affinity, free_mem, docker_host)) sorted_scores = sorted(scores, reverse=True, key=lambda k: k[0:2]) for score in sorted_scores: docker_host = score[2] addr = docker_host['addr'].split(':')[0] free_mem = docker_host['memory'] - memory_used[addr] if free_mem > memory: logging.info("Allocating new instance with %d MiB memory at '%s'", memory, addr) return addr docker_host = sorted_scores[0][2] addr = docker_host['addr'].split(':')[0] logging.info( "There were no hosts with %d MiB of free memory, " + "so allocating instance on '%s'", memory, addr) return addr
def __init__(self, consul_host, group_id): self.consul_host = consul_host self.consul = consul.Consul(host=consul_host, token=global_env.consul_acl_token) self.group_id = group_id blueprints = Sense.blueprints() if not group_id in blueprints: raise GroupNotFoundError("No such blueprint: '%s'", group_id) self._blueprint = blueprints[group_id]