def post(): form, error = JsonParser( Argument('app_id', type=int), Argument('env_id', type=int), Argument('menu_id', type=int), Argument('message', default=''), Argument('host_ids', type=list) ).parse() if error is None: pro = App.query.get_or_404(form.app_id) env = Environment.query.get_or_404(form.env_id) menu = DeployMenu.query.get_or_404(form.menu_id) ctr_name = '%s.%s' % (pro.identify, env.identify) if menu.position == 2: cli = Host.query.get_or_404(form.host_ids[0]) ctr = Container(cli.docker_uri, ctr_name) if menu.display_type == 2: exec_code, _ = ctr.exec_command_with_base64(menu.command, form.message, with_exit_code=True) return json_response(exec_code) elif menu.display_type == 1: token = uuid.uuid4().hex queue = QueuePool.make_queue(token, 1) queue.containers = [ctr] Thread(target=do_exec_with_stream, args=(token, ctr, menu.command, form.message, 10 * 60)).start() return json_response(token) # 发布区自定义菜单只允许通知成功与否,固无需判断display_type elif menu.position == 1: token = uuid.uuid4().hex hosts = Host.query.filter(Host.id.in_(form.host_ids)).all() queue = QueuePool.make_queue(token, len(hosts)) for cli in hosts: ctr = Container(cli.docker_uri, ctr_name) Thread(target=do_exec, args=(queue, ctr, cli.name, menu.command, form.message)).start() return json_response({'token': token, 'data': [{'name': x.name} for x in hosts]})
def bind_hosts(app_id): form, error = JsonParser('ids', 'env_id').parse() if error is None: pro = App.query.get_or_404(app_id) env = Environment.query.get_or_404(form.env_id) old_relationships = AppHostRel.query.filter_by(env_id=form.env_id, app_id=app_id).all()[:] for host_id in form.ids: rel = AppHostRel(env_id=form.env_id, app_id=app_id, host_id=host_id) if rel in old_relationships: old_relationships.remove(rel) else: rel.add() for old_rel in old_relationships: host = Host.query.get_or_404(old_rel.host_id) try: app_process = Container(host.docker_uri, '%s.%s' % (pro.identify, env.identify)).info if app_process: return json_response( message='在主机 <%s> 上已经部署了该应用,请删除已部署的容器后再尝试解除关联!' % host.name) except DockerException: pass old_rel.delete(commit=False) db.session.commit() return json_response() return json_response(message=error)
def container_executor(info, user, command, target, callback): cli_id, pro_id, env_id = target.split('_') cli = info['hosts'][cli_id] ctr_name = '%s.%s' % (info['apps'][pro_id].identify, info['environments'][env_id].identify) ctr = Container(cli.docker_uri, ctr_name) exit_code, output = ctr.exec_command('sh -c %r' % command, with_exit_code=True, user=user) callback(target, exit_code, output, '')
def logs(): form, error = JsonParser(*args.values()).parse() if error is None: pro = App.query.get_or_404(form.app_id) env = Environment.query.get_or_404(form.env_id) cli = Host.query.get_or_404(form.cli_id) ctr = Container(cli.docker_uri, pro.identify + '.' + env.identify) str_logs = ctr.logs(timestamps=True, tail=20, since=int(time.time() - 300)) return json_response(str_logs) return json_response(message=error)
def do_exec(field_id): form, error = JsonParser(Argument('host_id', type=int), Argument('app_id', type=int), Argument('env_id', type=int)).parse() if error is None: field = DeployField.query.get_or_404(field_id) pro = App.query.get_or_404(form.app_id) cli = Host.query.get_or_404(form.host_id) env = Environment.query.get_or_404(form.env_id) try: ctr = Container(cli.docker_uri, '{}.{}'.format(pro.identify, env.identify)) output = ctr.exec_command_with_base64(field.command, timeout=5) except DockerException: output = 'N/A' return json_response(output.strip()) return json_response(message=error)
def post(): form, error = JsonParser( Argument('action', filter=lambda x: x in ['v_start', 'v_stop', 'v_remove'], help='无效的操作指令!'), *args.values()).parse() if error is None: pro = App.query.get_or_404(form.app_id) env = Environment.query.get_or_404(form.env_id) cli = Host.query.get_or_404(form.cli_id) ctr = Container(cli.docker_uri, pro.identify + '.' + env.identify) # ctr_info = ctr.info # if form.action != 'v_start': # if ctr_info.State != 'running': # ctr.start() # exec_code, exec_out = ctr.exec_command('/entrypoint.sh ' + form.action, True) # if exec_code != '0': # print('执行{0}钩子失败,返回状态码:{1}'.format(form.action, exec_code)) # # return json_response(message='执行{0}钩子失败,返回状态码:{1}'.format(form.action, exec_code)) getattr(ctr, form.action.lstrip('v_'))() return json_response(message=error)
def state(): form, error = JsonParser(*args.values()).parse() if error: return json_response(message=error) pro = App.query.get_or_404(form.app_id) env = Environment.query.get_or_404(form.env_id) cli = Host.query.get_or_404(form.cli_id) ctr_name = pro.identify + '.' + env.identify info = Container(cli.docker_uri, ctr_name).info if info: return json_response({ 'running': info.running, 'status': info.Status, 'image': info.Image }) else: return json_response({ 'running': False, 'status': 'N/A', 'image': 'N/A' })