class DeletedTemplate(JobTemplate, TemplateMixin): type = TemplateArgument(type="text", hidden=True, value="deleted_template") name = TemplateArgument(label=u"模版名称", type="text", readonly=True) info = TemplateArgument(label=u"信息", type="textarea", value=notice_info, readonly=True) __order__ = [ "type", "name", "info", "exclude_offline", "servers", "concurrence_idc", "concurrence_server", "pause_after_first_fail", "script_path" ] @property def template_name(self): return "deleted_template" @JobTemplate.dashboard_form_hook("info") def change_dashboard_form_info(self, value): value["value"] = u"此任务模板原型 %s 已被删除" % self.type return value def send_deploy_request(self, *args, **kwargs): raise OperationNotAllowed( "job type deleted_template can't been deployed")
class NginxServer(JobTemplate, TemplateMixin): __templatename__ = "nginx_server" name = TemplateArgument(label=u"模版名称", type="text") run_path = TemplateArgument(label=u"运行路径", placeholder=u"默认为运行帐号Home目录", type="text", value="/home/work", required=False) user = TemplateArgument(label=u"运行账号", type="text", value="work", required=False) timeout = TemplateArgument(label=u"超时时间", type="number", value=10) script_path = TemplateArgument(label=u"脚本路径", type="text", value="/usr/local/bin/op/nginx_server.py", required=True, hidden=True) product = DeployArgument(label=u"产品线", type="select", items=make_items(["ag", "apps", "happiness", "public", "search"])) tp = DeployArgument(label=u"内网,外网", type="select", items=make_items(["internal", "external"])) idc = DeployArgument(label=u"机房", type="select", items=make_items(["common", "hy", "hlg", "db"])) nm = DeployArgument(label=u"文件名", type="text", required=True, placeholder="loki_DOMAIN") server_names = DeployArgument(label=u"域名", type="text", required=True, placeholder="loki.DOMAIN.com") log_format = DeployArgument(label=u"日志格式", type="text", value="main", required=True) upstream_node = DeployArgument(label=u"upstream node名称", type="text", required=True, placeholder="loki_nodes") __order__ = [ "type", "name", "timeout", "product", "tp", "idc", "nm", "server_names", "log_format", "upstream_node", "exclude_offline", "servers", "concurrence_idc", "concurrence_server", "pause_after_first_fail", "script_path" ] def send_deploy_request(self, node_id, confs=None, shelx=False): log_name = self.nm arguments = [] arguments.extend(["-p", self.product]) arguments.extend(["-t", self.tp]) arguments.extend(["-i", self.idc]) arguments.extend(["-n", self.nm]) arguments.extend(["-s", self.server_names]) arguments.extend(["-a", log_name]) arguments.extend(["-o", self.log_format]) arguments.extend(["-u", self.upstream_node]) confs = { "run_path": self.run_path, "script_path": self.script_path, "arguments": arguments, "timeout": self.timeout, "user": self.user, } super(NginxServer, self).send_deploy_request(node_id, confs, shelx=shelx)
class StandardScript(JobTemplate, TemplateMixin): __templatename__ = "standard_script" name = TemplateArgument(label=u"模版名称", type="text") script_path = TemplateArgument(label=u"脚本路径", type="text") run_path = TemplateArgument(label=u"运行路径", type="text") user = TemplateArgument(label=u"运行账号", type="text") timeout = TemplateArgument(label=u"超时时间", type="number") arguments = TemplateArgument(label=u"脚本参数", type="arrayinput", required=False) __order__ = [ "type", "name", "script_path", "run_path", "user", "timeout", "arguments", "contacters", "exclude_offline", "servers", "concurrence_idc", "concurrence_server", "pause_after_first_fail" ] def send_deploy_request(self, node_id, confs=None, shelx=True): confs = { "run_path": self.run_path, "script_path": self.script_path, "arguments": self.arguments, "timeout": self.timeout, "user": self.user, } super(StandardScript, self).send_deploy_request(node_id, confs, shelx=shelx)
class NginxUpstreamDelete(JobTemplate, TemplateMixin): __templatename__ = "nginx_upstream_delete" name = TemplateArgument(label=u"模版名称", type="text") run_path = TemplateArgument(label=u"运行路径", placeholder=u"默认为运行帐号Home目录", type="text", value="/home/work", required=False) user = TemplateArgument(label=u"运行账号", type="text", value="work", required=False) timeout = TemplateArgument(label=u"超时时间", type="number", value=10) action = TemplateArgument(label=u"执行动作", type="text", value="delete", required=True, hidden=True) script_path = TemplateArgument(label=u"脚本路径", type="text", value="/usr/local/bin/op/nginx_upstream.py", required=True, hidden=True) upstream_name = DeployArgument(label=u"upstream node名称", type="text", required=True) __order__ = [ "type", "name", "timeout", "upstream_name", "exclude_offline", "servers", "concurrence_idc", "concurrence_server", "pause_after_first_fail", ] def send_deploy_request(self, node_id, confs=None, shelx=False): arguments = [self.action] arguments.extend(["-n", self.upstream_name]) confs = { "run_path": self.run_path, "script_path": self.script_path, "arguments": arguments, "timeout": self.timeout, "user": self.user, } super(NginxUpstreamDelete, self).send_deploy_request(node_id, confs, shelx=shelx)
class DockerBuilder(JobTemplate, TemplateMixin): __templatename__ = "docker_builder" name = TemplateArgument(label=u"模版名称", type="text") timeout = TemplateArgument(label=u"超时时间", type="number", value=600) repo = TemplateArgument(label=u"Dockerfile目录", type="text") env = TemplateArgument(label=u"环境", type="select", items=ENVS) packing_host = TemplateArgument(label=u"打包所在机器", type="text", required=False) packing_xml = TemplateArgument(label=u"打包xml文件", type="text", required=False) __order__ = [ 'type', 'name', 'timeout', 'repo', 'env', 'packing_host', 'packing_xml', 'contacters', 'exclude_offline', 'servers', 'concurrence_idc', 'concurrence_server', 'pause_after_first_fail' ] def send_deploy_request(self, node_id, confs=None, shelx=True): run_path = '/home/work/Dockerfiles/' arguments = ['--repo', self.repo] if self.env and self.env != 'base': arguments.extend(['--env', self.env]) if self.packing_host: arguments.extend(['--packing-host', self.packing_host]) if self.packing_xml: arguments.extend(['--packing-xml', self.packing_xml]) confs = { "run_path": run_path, "script_path": path.join(run_path, 'image_builder.py'), "arguments": arguments, "timeout": int(self.timeout), "user": "******", } super(DockerBuilder, self).send_deploy_request(node_id, confs, shelx)
class StandardDeploy(JobTemplate, TemplateMixin): __templatename__ = "standard_java_deploy" name = TemplateArgument(label=u"模版名称", type="text") package_name = TemplateArgument(label=u"软件包名", type="select") dst = TemplateArgument(label=u"目标目录", type="text") pre_command = TemplateArgument(label=u"预先执行", type="text", value="", required=False) stop_command = TemplateArgument(label=u"停止脚本", type="text") start_command = TemplateArgument(label=u"启动脚本", type="text") test_commands = TemplateArgument(label=u"检测命令", type="arrayinput", required=False) post_command = TemplateArgument(label=u"最后执行", type="text", value="", required=False) timeout = TemplateArgument(label=u"超时秒数", type="number", value=600) http_check = TemplateArgument(label=u"7层检测", type="checkbox", value=True, required=False) default_servers = TemplateOnlyArgument(label=u"默认发布机器", type="servers_checkbox", value=(), required=False) default_concurrence_idc = TemplateOnlyArgument(label=u"默认机房间是否并发", type="checkbox", value=False, required=False) default_concurrence_server = TemplateOnlyArgument(label=u"默认机器间并发度", type="number", value=1, required=False) branch = DeployArgument(label=u"分支名称", type="select") script_path = DeployArgument(label=u"发布脚本", type="text", readonly=True, value='/usr/local/bin/op/deploy.py') sleep = DeployArgument(label=u"暂停秒数", type="number", value=10, required=False) __order__ = [ "type", "name", "package_name", "script_path", "dst", "pre_command", "stop_command", "start_command", "test_commands", "post_command", "timeout", "http_check", "contacters", "sleep", "branch", "servers", "exclude_offline", "default_concurrence_idc", "default_concurrence_server", "default_servers", "concurrence_idc", "concurrence_server", "pause_after_first_fail", ] @JobTemplate.template_form_hook("package_name") def change_template_package_name(self, value): names = [i[0] for i in Package.distinct(Package.name).all()] value['items'] = make_items(names) return value @JobTemplate.contexts_hook((Context.deploy_form, Context.dashboard_form), "package_name") def change_deploy_package_name(self, value): value.pop('items', None) value['type'] = "text" return value @JobTemplate.dashboard_form_hook("branch") def change_dashboard_branch(self, value): value.pop('items', None) value['type'] = "text" return value @JobTemplate.deploy_form_hook("branch") def change_deploy_branch(self, value): subq = Package.query.with_entities(Package.branch.label("branch"), func.max(Package.ctime).label("max_ctime"))\ .filter_by(name=self.package_name)\ .group_by(Package.branch).subquery() branches = [ i[0] for i in Package.subquery(subq.c.branch).order_by( subq.c.max_ctime.desc()).limit(20).all() ] value['items'] = make_items(branches) return value @JobTemplate.template_form_hook("default_servers") def change_template_form_default_servers(self, value): value['value'] = self._get_servers_from_node_id( self.node_id, selected_servers=value['value']) return value @JobTemplate.deploy_form_hook("servers") def change_deploy_form_servers(self, value): value['value'] = self._get_servers_from_node_id( self.node_id, selected_servers=self.default_servers) return value @JobTemplate.deploy_form_hook("concurrence_idc") def change_deploy_form_concurrence_idc(self, value): value['value'] = self.default_concurrence_idc return value @JobTemplate.deploy_form_hook("concurrence_server") def change_deploy_form_concurrence_server(self, value): value['value'] = self.default_concurrence_server return value def send_deploy_request(self, node_id, confs=None, shelx=True): arguments = [] arguments_dict = {} arguments.extend(['-d', self.dst]) arguments.extend(['--stop-command', '"%s"' % self.stop_command]) arguments.extend(['--start-command', '"%s"' % self.start_command]) arguments.extend(['--sleep', '"%s"' % self.sleep]) # noinspection PyTypeChecker for cmd in self.test_commands: arguments.extend(['--test-command', '"%s"' % cmd]) if self.pre_command: arguments.extend(['--pre-command', '"%s"' % self.pre_command]) if self.post_command: arguments.extend(['--post-command', '"%s"' % self.post_command]) if self.verbose: arguments.append('--verbose') if self.http_check: arguments.append('--http-check') # Retrieve the most recently added Package record for each idc having certain # package_name and branch, split into 2 steps refrain from using complex sql idcs = [ r[0] for r in Package.distinct(Package.idc).filter_by( name=self.package_name, branch=self.branch).all() ] for idc in idcs: url, target_filename = \ Package.query.with_entities(Package.url, Package.target_filename) \ .filter_by(name=self.package_name, branch=self.branch, idc=idc) \ .order_by(Package.ctime.desc()) \ .first() arguments_dict[idc] = copy.deepcopy(arguments) # url here is a file name, ebooks-webapp-hy-20140506000000.war e.g. arguments_dict[idc].append('-s%s/%s' % (DOWNLOAD_URL, url)) arguments_dict[idc].append('--target-filename "%s"' % target_filename) if not arguments_dict: raise ValueError("can't get package url from databases") confs = { "run_path": self.dst, "script_path": self.script_path, "arguments": arguments_dict, "timeout": int(self.timeout), "user": "******", } super(StandardDeploy, self).send_deploy_request(node_id, confs, shelx=shelx)
class NginxUpstreamAddOrUpdate(JobTemplate, TemplateMixin): __templatename__ = "nginx_upstream_add_or_update" name = TemplateArgument(label=u"模版名称", type="text") run_path = TemplateArgument(label=u"运行路径", placeholder=u"默认为运行帐号Home目录", type="text", value="/home/work", required=False) user = TemplateArgument(label=u"运行账号", type="text", value="work", required=False) timeout = TemplateArgument(label=u"超时时间", type="number", value=10) script_path = TemplateArgument(label=u"脚本路径", type="text", value="/usr/local/bin/op/nginx_upstream.py", required=True, hidden=True) action = DeployArgument(label=u"执行动作", type="select", items=make_items_by_dict(ACTIONS), required=True) upstream_name = DeployArgument(label=u"upstream node名称", type="text", required=True) loki_id = DeployArgument(label="loki id", type="number", required=True) port = DeployArgument(label=u"端口", type="number", required=True) ip_hash = DeployArgument(label=u"是否开启ip_bash", type="checkbox", value=False, required=True) online = DeployArgument(label=u"是否在线", type="checkbox", value=True, required=False) __order__ = [ "type", "name", "timeout", "action", "upstream_name", "loki_id", "port", "ip_hash", "exclude_offline", "servers", "concurrence_idc", "concurrence_server", "pause_after_first_fail", "script_path" ] def send_deploy_request(self, node_id, confs=None, shelx=False): arguments = [] arguments.extend([self.action]) arguments.extend(["-n", self.upstream_name]) arguments.extend(["-l", str(self.loki_id)]) arguments.extend(["-p", str(self.port)]) if self.ip_hash: arguments.extend(["-i", "1"]) else: arguments.extend(["-i", "0"]) if self.online: arguments.extend(["-o", "1"]) else: arguments.extend(["-o", "0"]) confs = { "run_path": self.run_path, "script_path": self.script_path, "arguments": arguments, "timeout": self.timeout, "user": self.user, } super(NginxUpstreamAddOrUpdate, self).send_deploy_request(node_id, confs, shelx=shelx)
class DockerDeploy(JobTemplate, TemplateMixin): __templatename__ = "docker_deploy" # name = TemplateArgument(label=u"服务名", type="text") name = TemplateArgument(label=u"name", type="select") hlg_replic = TemplateArgument(label=u"HLG 实例数量", type="number", value=1, required=False) db_replic = TemplateArgument(label=u"DB 实例数量", type="number", value=1, required=False) inner_port = TemplateArgument(label=u"内部端口", type="text", required=False) desire_stat = TemplateArgument(label=u"期望状态", type="text", value="running") reserve_cpu = TemplateArgument(label=u"CPU 核数", type="number", value=1) reserve_mem = TemplateArgument(label=u"内存", type="text", value="1G") branch = DeployArgument(label=u"tag名称", type="select") opt = TemplateArgument(label=u"附加选项,支持 swarm 所有的选项", type="text", value="", required=False) __order__ = [ "type", "name", # "image", "hlg_replic", "db_replic", "inner_port", "reserve_cpu", "reserve_mem", "desire_stat", "branch", "opt", "hlg_select", "db_select" ] @JobTemplate.template_form_hook("name") def change_template_package_name(self, value): # names = ["hub.internal.DOMAIN.com/apps/mms-webapp-read"] # value['items'] = make_items(names) try: raw = asyncrequest("GET", "http://docker.internal.DOMAIN.com/image/services", timeout=2) images = raw.json() except Exception as e: raise FatalError( "get image error") value['items'] = make_items(images) return value @JobTemplate.contexts_hook((Context.deploy_form, Context.dashboard_form), "name") def change_deploy_package_name(self, value): value.pop('items', None) value['type'] = "text" return value @JobTemplate.deploy_form_hook("branch") def change_deploy_branch(self, value): try: img = asyncrequest("GET", "http://docker.internal.DOMAIN.com/image/services/" + str(self.name), timeout=2) except Exception as e: raise FatalError( "get branch error") branches = [{"label":item["branch"], "value":item["runImage"]} for item in img.json()] value['items'] = branches return value def send_deploy_request(self, node_id, confs=None, shelx=False): # img = asyncrequest("GET", # "http://docker.internal.DOMAIN.com/image/services/" + str(self.image), # timeout=2) # imgs = img.json() arguments = {} # self.limit_memory = str(int(1.5*int(re.sub("[^0123456789\.]","",self.reserve_mem)))) + re.sub("[^A-Za-z\.]","",self.reserve_mem) arguments['name'] = self.name + '_' + str(node_id) arguments['image'] = self.branch arguments['reserve_cpu'] = self.reserve_cpu arguments['reserve_memory'] = self.reserve_mem if self.inner_port: arguments['inner_port'] = self.inner_port if self.desire_stat: arguments['desire_stat'] = self.desire_stat if self.opt: arguments['opt'] = self.opt # if hlg_select confs = { "hlg_replic": self.hlg_replic, "db_replic": self.db_replic, "arguments": arguments, } super(DockerDeploy, self).send_docker_deploy_request( confs )
class TemplateMixin(object): __metaclass__ = TemplateMeta type = TemplateArgument(type="text", hidden=True, value=lambda self: self.__templatename__) concurrence_idc = DeployArgument(label=u"机房间是否并发", type="checkbox",required=False) concurrence_server = DeployArgument(label=u"机器间并发度", type="number", value=1,required=False) contacters = TemplateArgument(label=u"通知邮箱", type="arrayinput", required=False, value=[]) # required by set_servers_from_node exclude_offline = TemplateArgument( label=u'是否排除 traffic_ratio 为 0 机器', notice=u'若勾选,则发布中 traffic_ratio 为 0 机器不可见', type="checkbox", value=False) servers = DeployArgument(label=u"发布机器", type="servers_checkbox", null=False, required=False) verbose = DeployArgument(label=u"详细输出", type="checkbox", value=True, required=False) pause_after_first_fail = DeployArgument(label=u'失败后立即暂停', type="checkbox", value=True, required=False) hlg_select = DeployArgument(label=u"hlg", type="checkbox",null=False, required=False) db_select = DeployArgument(label=u"db", type="checkbox",null=False, required=False) # noinspection PyAttributeOutsideInit @property def jobset_id(self): if not getattr(self, "_jobset_id", None): self._jobset_id = generate_deploy_id() return self._jobset_id @property def node_id(self): if not getattr(self, "_node_id", None): raise ValueError("Template/Deployment node_id not set") return self._node_id # noinspection PyAttributeOutsideInit @node_id.setter def node_id(self, num): assert isinstance(num, int), "node_id should be type int" self._node_id = num @JobTemplate.deploy_form_hook("servers") def change_deploy_form_servers(self, value): value['value'] = self._get_servers_from_node_id(self.node_id) return value def _get_servers_from_node_id(self, node_id, selected_servers=()): """ set template servers from a tree_node :param int node_id: node'id which servers belongs to """ tree_node = getattr(greenlet_local, str(node_id), None) if not tree_node: tree_node = TreeNode(node_id) setattr(greenlet_local, str(node_id), tree_node) nodes = [] node_ids = [] for n in tree_node.dfs_generator(): node_ids.append(n) if n.id == tree_node.id: parent = "#" else: parent = n.parent nodes.append({"type": "node", "text": n.name, "id": n.id, "parent": parent}) if hasattr(self, 'exclude_offline') and self.exclude_offline: node_servers = {i for i in tree_node.offspring_nodeservers if i.traffic_ratio != 0} else: node_servers = tree_node.offspring_nodeservers for node_server in node_servers: ratio_percent = "{}%".format(node_server.traffic_ratio * 100) \ if isinstance(node_server.traffic_ratio, Number) else "auto" selected = True if node_server.server.hostname in selected_servers else False nodes.append({ "type": "server", "text": "{0} ({1})".format(node_server.server.hostname, ratio_percent), # NOTE never use `node_server.id` as server type's id because it may collide with node type's id "id": '%s:%s' % (node_server.node_id, node_server.server.hostname), "hostname": node_server.server.hostname, # "idc": tree_node.node_dict[node.node_id]['name'], "parent": node_server.node_id, "state" : { "selected": selected, } }) return nodes def _send_docker_request(self, confs): url = 'http://docker.internal.DOMAIN.com/deploy/api/v1/service/create' post_data = {} post_data = confs['arguments'] post_data["idcs"] = confs["idcs"] post_data["jobid"] = self.jobset_id print post_data body = post_data req = tornado.httpclient.HTTPRequest( url=url, method='POST', body=json.dumps(body), validate_cert=False) http_client = tornado.httpclient.HTTPClient() response = http_client.fetch(req) # client = tornado.httpclient.AsyncHTTPClient() # url = 'docker.DOMAIN.com/api/v1/service/create' # post_data = { 'data': 'test data' } # body = urllib.urlencode(post_data) # def set_deploy_status_watcher(self): # def watcher(event): # if event.type in (EventType.CREATED, EventType.CHANGED): # _d, _ = zk.without_expire.get(job_status_path, watch=watcher) # _s = get_jobset_status(_d) # Deployment.set_status(self.jobset_id, _s) # # job_status_path = path.join(ZK_JOB_STATUS_PATH, str(self.jobset_id)) # if zk.without_expire.exists(job_status_path, watch=watcher): # _data, _ = zk.without_expire.get(job_status_path, watch=watcher) # status = get_jobset_status(_data) # Deployment.set_status(self.jobset_id, status) def send_deploy_request(self, node_id, new_confs, shelx=True): confs = { "jobset_id": self.jobset_id, "servers": self.servers, "concurrence_idc": self.concurrence_idc, "concurrence_server": self.concurrence_server, "pause_after_first_fail": self.pause_after_first_fail, "verbose": self.verbose, } confs.update(new_confs) _servers = set(confs['servers']) # get all node ids belong to this deployed node. # get idc name from hostname temporary servers = defaultdict(set) for s in _servers: idc = s.split(".")[1].rstrip('0123456790') servers[idc].add(s) jobs = {} for idc, hostnames in servers.iteritems(): if isinstance(confs["arguments"], dict): arguments = confs["arguments"].get(idc, None) elif isinstance(confs["arguments"], list): arguments = confs["arguments"] else: raise ValidationError("!!! arguments for idc %s is not list or dict !!!" % idc) if arguments is None: raise ValidationError("!!! arguments for idc %s not exists !!!" % idc) if not all([isinstance(a, basestring) for a in arguments]): raise ValidationError("!!! arguments for idc %s contains no-string parameters: %s" % (idc, arguments)) if shelx: try: arguments = shlex.split(" ".join(arguments)) except ValueError as e: raise ValidationError("arguments %s illegal, error: %s" % (arguments, e)) job = { "rundir": confs["run_path"], "command": confs["script_path"], "argument": arguments, "timeout": confs["timeout"], "runuser": confs["user"], "servers": hostnames } jobs[idc] = job request = { "job_set_id": confs["jobset_id"], "concurrence_idc": 1 if confs["concurrence_idc"] else 0, "concurrence_server": confs["concurrence_server"], "jobs": jobs, "pause_after_first_fail": confs["pause_after_first_fail"], } job_path = path.join(ZK_NEW_JOB_PATH, str(confs["jobset_id"])) try: zk.create(job_path, json.dumps(request), makepath=True) except NodeExistsError: raise FatalError("!!! job_path %s already exists, attention !!!" % job_path) except KazooException, e: raise FatalError("!!! %s !!!" % str(e))
class NginxDeploy(JobTemplate, TemplateMixin): __templatename__ = "nginx_deploy" name = TemplateArgument(label=u"模版名称", type="text") run_path = TemplateArgument(label=u"运行路径", placeholder=u"默认为运行帐号Home目录", type="text", value="/home/work", required=False) user = TemplateArgument(label=u"运行账号", type="text", value="work", required=False) timeout = TemplateArgument(label=u"超时时间", type="number", value=120) script_path = TemplateArgument(label=u"脚本路径", type="text", value="/usr/local/bin/op/nginx_deploy.py", required=True, hidden=True) branch = DeployArgument(label=u"Git分支", type="select", items=DEFAULT_BRANCH) _reload = DeployArgument(label=u"是否通过reload发布, 紧急发布时使用", type="checkbox", value=False, required=True) __order__ = [ "type", "name", "timeout", "contacters", "exclude_offline", "branch", "_reload", "servers", "concurrence_idc", "concurrence_server", "pause_after_first_fail" ] @JobTemplate.deploy_form_hook("branch") def change_deploy_branch(self, value): try: raw = asyncrequest( "GET", "http://access.hy01.nosa.me/api/v1/nginx/branches", timeout=2) git_branches = raw.json() except Exception as e: raise FatalError( "get git branch from http://access.hy01.nosa.me/api/v1/nginx/branches failed as %s" % e) value['items'] = make_items(git_branches) return value @JobTemplate.dashboard_form_hook("branch") def change_dashboard_branch(self, value): del value['items'] value['type'] = "text" value['value'] = self.branch return value def send_deploy_request(self, node_id, confs=None, shelx=False): arguments = ["-b", self.branch] arguments.extend(["-r", str(self._reload)]) confs = { "run_path": self.run_path, "script_path": self.script_path, "arguments": arguments, "timeout": self.timeout, "user": self.user, } super(NginxDeploy, self).send_deploy_request(node_id, confs, shelx=shelx)
class SimpleScript(JobTemplate, TemplateMixin): __templatename__ = "simple_script" name = TemplateArgument(label=u"模版名称", type="text") run_path = TemplateArgument(label=u"运行路径", placeholder=u"默认为运行帐号Home目录", type="text", value="", required=False, null=True) interpreter = TemplateArgument(label=u"解释器", type="select", items=make_items_by_dict(INTERPRETERS)) user = TemplateArgument(label=u"运行账号", type="text") timeout = TemplateArgument(label=u"超时时间", type="number") content = TemplateArgument(label=u"脚本内容", type="textarea") default_servers = TemplateOnlyArgument(label=u"默认发布机器", type="servers_checkbox", value=(), required=False) default_concurrence_idc = TemplateOnlyArgument(label=u"默认机房间是否并发", type="checkbox", value=False, required=False) default_concurrence_server = TemplateOnlyArgument(label=u"默认机器间并发度", type="number", value=1, required=False) debug = DeployArgument(label=u"调试开关", type="checkbox", notice=u"勾选此项且解释器为 bash, 以 bash -x 模式运行脚本", value=False, required=False) __order__ = [ "type", "name", "user", "timeout", "interpreter", "run_path", "content", "contacters", "exclude_offline", "debug", "pause_after_first_fail", "default_concurrence_idc", "default_concurrence_server", "default_servers", "concurrence_idc", "concurrence_server", "servers", ] @JobTemplate.contexts_hook((Context.deploy_form, Context.dashboard_form), "interpreter") def remove_interpreter_items(self, value): del value['items'] value['type'] = "text" return value @JobTemplate.template_form_hook("default_servers") def change_template_form_default_servers(self, value): value['value'] = self._get_servers_from_node_id( self.node_id, selected_servers=value['value']) return value @JobTemplate.deploy_form_hook("servers") def change_deploy_form_servers(self, value): value['value'] = self._get_servers_from_node_id( self.node_id, selected_servers=self.default_servers) return value @JobTemplate.deploy_form_hook("concurrence_idc") def change_deploy_form_concurrence_idc(self, value): value['value'] = self.default_concurrence_idc return value @JobTemplate.deploy_form_hook("concurrence_server") def change_deploy_form_concurrence_server(self, value): value['value'] = self.default_concurrence_server return value def send_deploy_request(self, node_id, confs=None, shelx=False): arguments = [] if isinstance(self.content, unicode): self.content = self.content.decode("utf8") if self.debug and self.interpreter == INTERPRETERS['bash']: arguments.extend(["-x"]) arguments.extend(["-c", r"""%s""" % self.content]) if not self.run_path: self.run_path = "/root" if str( self.user) == "root" else "/home/%s" % self.user confs = { "run_path": self.run_path, "script_path": self.interpreter, "arguments": arguments, "timeout": self.timeout, "user": self.user, } super(SimpleScript, self).send_deploy_request(node_id, confs, shelx=shelx)