def create_private(): data = request.get_json() pod, _, version = _get_instances(**data) ncore, nshare = pod.get_core_allocation(float(data['ncore'])) ports = data.get('ports', []) args = data.get('args', []) strategy = data.get('strategy', 'average') callback_url = data.get('callback_url', '') if callback_url and not is_strict_url(callback_url): abort(400, 'callback_url must start with http:// or https://') ncontainer = int(data['ncontainer']) if not ncontainer: abort(400, 'ncontainer must be > 0') networks = [ipam.get_pool(n) for n in data.get('networks', [])] spec_ips = data.get('spec_ips', []) appconfig = version.appconfig entrypoint = data['entrypoint'] if entrypoint not in appconfig.entrypoints: abort(400, 'Entrypoint %s not in app.yaml' % entrypoint) hostname = data.get('hostname', '') host = hostname and Host.get_by_name(hostname) or None task_ids, watch_keys = [], [] host_cores = _get_strategy(strategy)(pod, ncontainer, ncore, nshare, host) if not host_cores: abort(400, 'Not enough core resources') for (host, container_count), cores in host_cores.iteritems(): t = _create_task( version, host, container_count, cores, nshare, networks, ports, args, spec_ips, entrypoint, data['env'], image=data.get('image', ''), callback_url=callback_url, ) if not t: continue host.occupy_cores(cores, nshare) task_ids.append(t.id) watch_keys.append(t.result_key) return {'tasks': task_ids, 'watch_keys': watch_keys}
def check_addr(addr): """addr is like 10.20.0.1/16 or 10.100.3.12/24""" try: interface = IPNetwork(addr) except AddrFormatError: abort(400, 'Not valid interface') net = ipam.get_pool(str(interface.cidr)) if not net: abort(400, 'Interface not found') return {'available': interface.ip in net}
def create_public(): data = request.get_json() pod, _, version = _get_instances(**data) ports = data.get('ports', []) args = data.get('args', []) callback_url = data.get('callback_url', '') if callback_url and not is_strict_url(callback_url): abort(400, 'callback_url must starts with http:// or https://') networks = [ipam.get_pool(n) for n in data.get('networks', [])] spec_ips = data.get('spec_ips', []) appconfig = version.appconfig ncontainer = int(data['ncontainer']) if not ncontainer: abort(400, 'ncontainer must be > 0') entrypoint = data['entrypoint'] if entrypoint not in appconfig.entrypoints: abort(400, 'Entrypoint %s not in app.yaml' % entrypoint) task_ids, watch_keys = [], [] hosts = pod.get_free_public_hosts(ncontainer) for host in itertools.islice(itertools.cycle(hosts), ncontainer): t = _create_task( version, host, 1, {}, 0, networks, ports, args, spec_ips, data['entrypoint'], data['env'], image=data.get('image', ''), callback_url=callback_url, ) if not t: continue task_ids.append(t.id) watch_keys.append(t.result_key) return {'tasks': task_ids, 'watch_keys': watch_keys}
def macvlan(id_or_name): host = _get_host(id_or_name) if request.method == 'GET': return host.list_vlans(g.start, g.limit) data = request.get_json() netname = data.get('network', '') network = ipam.get_pool(netname) if not network: abort(404, 'Network not found') vg = VLanGateway.get_by_host_and_network(host.id, network.id) if request.method == 'POST': return vg or network.acquire_gateway_ip(host) elif request.method == 'DELETE': if vg: vg.release() return DEFAULT_RETURN_VALUE
def bind_network(id_or_cid): c = _get_container(id_or_cid) data = request.get_json() appname = data['appname'] if not c.is_alive: abort(404, 'Container %s not alive' % c.container_id) if c.appname != appname: abort(404, 'Container does not belong to app') if c.network_mode == 'host': abort(400, 'Container use host network mode') network_names = data.get('networks', []) networks = [ipam.get_pool(n) for n in network_names] if not networks: abort(400, 'network empty') cidrs = [n.cidr for n in networks if n] bind_container_ip(c, cidrs) return {'cidrs': cidrs}
def create_containers(task_id, ncontainer, nshare, cores, network_ids, spec_ips=None): """ 执行task_id的任务. 部署ncontainer个容器, 占用*_core_ids这些核, 绑定到networks这些子网 """ _log.info('Task<id=%s>: Started', task_id) task = Task.get(task_id) if not task: _log.error('Task (id=%s) not found, quit', task_id) return if spec_ips is None: spec_ips = [] need_network = bool(network_ids) networks = [ipam.get_pool(n) for n in network_ids] notifier = TaskNotifier(task) host = task.host version = task.version entrypoint = task.props['entrypoint'] env = task.props['env'] ports = task.props['ports'] args = task.props['args'] # use raw image = task.props['image'] callback_url = task.props['callback_url'] cpu_shares = int(float(nshare) / host.pod.core_share * 1024) if nshare else 1024 cids = [] backends = [] entry = version.appconfig.entrypoints[entrypoint] for fcores, pcores in _iter_cores(cores, ncontainer): cores_for_one_container = {'full': fcores, 'part': pcores} # 在宿主机上创建容器 try: cid, cname = dockerjob.create_one_container(host, version, entrypoint, env, fcores + pcores, ports=ports, args=args, cpu_shares=cpu_shares, image=image, need_network=need_network) except Exception as e: # 写给celery日志看 _log.exception(e) host.release_cores(cores_for_one_container, nshare) continue # 容器记录下来 c = Container.create(cid, host, version, cname, entrypoint, cores_for_one_container, env, nshare, callback_url) # 为容器创建网络栈 # 同时把各种信息都记录下来 # 如果失败, 清除掉所有记录和宿主机上的容器 # 循环下一次尝试 cidrs = [n.netspace for n in networks] if not ipam.allocate_ips(cidrs, cid, spec_ips): _clean_failed_containers(cid) continue notifier.notify_agent(c) add_container_for_agent(host, c) add_container_backends(c) cids.append(cid) backends.extend(c.get_backends()) c.callback_report(status='start') health_check = entry.get('health_check', '') if health_check and backends: urls = [b + health_check for b in backends] if not wait_health_check(urls): # TODO 这里要么回滚要么报警 _log.info('Task<id=%s>: Done, but something went error', task_id) return publish_to_service_discovery(version.name) task.finish(consts.TASK_SUCCESS) task.reason = 'ok' task.container_ids = cids notifier.pub_success() _log.info('Task<id=%s>: Done', task_id)
def create_containers(task_id, ncontainer, nshare, cores, network_ids, spec_ips=None): """ 执行task_id的任务. 部署ncontainer个容器, 占用*_core_ids这些核, 绑定到networks这些子网 """ _log.info('Task<id=%s>: Started', task_id) task = Task.get(task_id) if not task: _log.error('Task (id=%s) not found, quit', task_id) return if spec_ips is None: spec_ips = [] need_network = bool(network_ids) networks = [ipam.get_pool(n) for n in network_ids] notifier = TaskNotifier(task) host = task.host version = task.version entrypoint = task.props['entrypoint'] env = task.props['env'] ports = task.props['ports'] args = task.props['args'] # use raw image = task.props['image'] callback_url = task.props['callback_url'] cpu_shares = int(float(nshare) / host.pod.core_share * 1024) if nshare else 1024 cids = [] backends = [] entry = version.appconfig.entrypoints[entrypoint] for fcores, pcores in _iter_cores(cores, ncontainer): cores_for_one_container = {'full': fcores, 'part': pcores} # 在宿主机上创建容器 try: cid, cname = dockerjob.create_one_container( host, version, entrypoint, env, fcores + pcores, ports=ports, args=args, cpu_shares=cpu_shares, image=image, need_network=need_network) except Exception as e: # 写给celery日志看 _log.exception(e) host.release_cores(cores_for_one_container, nshare) continue # 容器记录下来 c = Container.create(cid, host, version, cname, entrypoint, cores_for_one_container, env, nshare, callback_url) # 为容器创建网络栈 # 同时把各种信息都记录下来 # 如果失败, 清除掉所有记录和宿主机上的容器 # 循环下一次尝试 cidrs = [n.netspace for n in networks] if not ipam.allocate_ips(cidrs, cid, spec_ips): _clean_failed_containers(cid) continue notifier.notify_agent(c) add_container_for_agent(host, c) add_container_backends(c) cids.append(cid) backends.extend(c.get_backends()) c.callback_report(status='start') health_check = entry.get('health_check', '') if health_check and backends: urls = [b + health_check for b in backends] if not wait_health_check(urls): # TODO 这里要么回滚要么报警 _log.info('Task<id=%s>: Done, but something went error', task_id) return publish_to_service_discovery(version.name) task.finish(consts.TASK_SUCCESS) task.reason = 'ok' task.container_ids = cids notifier.pub_success() _log.info('Task<id=%s>: Done', task_id)
def get_network(id_or_name): n = ipam.get_pool(id_or_name) if not n: abort(404, 'Network %s not found' % id_or_name) return n