From 27bbc65e4dea734238d4c8c24eb1011d3016dcb2 Mon Sep 17 00:00:00 2001 From: cdllp2 Date: Wed, 23 Nov 2022 17:01:10 +0800 Subject: [PATCH] update pre_add_web follow base --- myapp/views/view_dimension.py | 72 ++++++++++++++++++++++------ myapp/views/view_docker.py | 4 +- myapp/views/view_images.py | 2 +- myapp/views/view_inferenceserving.py | 21 ++++---- myapp/views/view_metadata.py | 9 ++-- myapp/views/view_nni.py | 4 +- myapp/views/view_notebook.py | 8 ++-- myapp/views/view_pipeline.py | 65 +++++++++++++++++++++++-- myapp/views/view_serving.py | 10 ++-- myapp/views/view_task.py | 15 +++--- myapp/views/view_team.py | 6 +-- myapp/views/view_train_model.py | 2 +- myapp/views/view_workflow.py | 9 ++-- 13 files changed, 168 insertions(+), 59 deletions(-) diff --git a/myapp/views/view_dimension.py b/myapp/views/view_dimension.py index 9bdd0680..8a0514bc 100644 --- a/myapp/views/view_dimension.py +++ b/myapp/views/view_dimension.py @@ -181,7 +181,7 @@ class Dimension_table_ModelView_Api(MyappModelRestApi): "sqllchemy_uri":StringField( _(datamodel.obj.lab('sqllchemy_uri')), default="", - description='链接串地址:
mysql+pymysql://root:admin@host.docker.internal:3306/db_name?charset=utf8
postgresql+psycopg2://root:admin@host.docker.internal:5432/db_name', + description='链接串地址:
示例:mysql+pymysql://$账号:$密码@$ip:$端口/$库名?charset=utf8
示例:postgresql+psycopg2://$账号:$密码@$ip:$端口/$库名', widget=BS3TextFieldWidget(), validators=[DataRequired(),Regexp("^(mysql\+pymysql|postgresql\+psycopg2)")] ), @@ -249,7 +249,8 @@ class Dimension_table_ModelView_Api(MyappModelRestApi): if not item.owner or g.user.username not in item.owner: item.owner = g.user.username if not item.owner else item.owner + "," + g.user.username - flash('添加或修改字段类型,需要点击创建远程表,已实现在远程数据库上建表','warning') + flash('添加或修改字段类型,需要点击创建远程表,以实现在远程数据库上建表','warning') + def pre_update(self, item): if not item.sqllchemy_uri: item.sqllchemy_uri=self.src_item_json.get('sqllchemy_uri','') @@ -257,7 +258,7 @@ class Dimension_table_ModelView_Api(MyappModelRestApi): # 转换为前端list - def pre_get(self,_response): + def pre_show_res(self,_response): data = _response['data'] columns=json.loads(data.get('columns','{}')) columns_list=[] @@ -268,8 +269,8 @@ class Dimension_table_ModelView_Api(MyappModelRestApi): data['columns']=columns_list - # 将前端columns list转化为字段存储 - def pre_json_load(self, req_json=None): + # 添加或者更新前将前端columns list转化为字段存储 + def pre_add_req(self, req_json=None): if req_json and 'columns' in req_json: columns={} for col in req_json.get('columns',[]): @@ -277,6 +278,8 @@ class Dimension_table_ModelView_Api(MyappModelRestApi): req_json['columns'] = json.dumps(columns,indent=4,ensure_ascii=False) return req_json + pre_update_req=pre_add_req + # 获取指定维表里面的数据 @staticmethod def get_dim_target_data(dim_id): @@ -324,7 +327,7 @@ class Dimension_table_ModelView_Api(MyappModelRestApi): sqllchemy_uri = item.sqllchemy_uri if sqllchemy_uri: # 创建数据库的sql(如果数据库存在就不创建,防止异常) - if 'postgresql' in item.sqllchemy_uri: + if 'postgresql' in sqllchemy_uri: # 创建pg表 import sqlalchemy.engine.url as url @@ -388,7 +391,7 @@ class Dimension_table_ModelView_Api(MyappModelRestApi): # 创建数据库的sql(如果数据库存在就不创建,防止异常) - if 'mysql' in item.sqllchemy_uri: + if 'mysql' in sqllchemy_uri: # 创建mysql表 import sqlalchemy.engine.url as url uri = url.make_url(sqllchemy_uri) @@ -454,6 +457,10 @@ class Dimension_table_ModelView_Api(MyappModelRestApi): dbsession.close() # 如果远程有表,就增加字段 + all_dimension = conf.get('all_dimension_instance', {}) + if "dimension_%s"%dim_id in all_dimension: + del all_dimension["dimension_%s"%dim_id] + url_path = conf.get('MODEL_URLS', {}).get("dimension")+'?targetId='+dim_id return redirect(url_path) @@ -511,10 +518,13 @@ class Dimension_remote_table_ModelView_Api(MyappModelRestApi): search_columns = [] label_columns={} add_columns=[] + edit_columns=[] show_columns=[] list_columns=[] description_columns={} add_form_extra_fields={} + add_form_query_rel_fields={} + validators_columns={} order_columns=[] cols_width = { } @@ -573,14 +583,16 @@ class Dimension_remote_table_ModelView_Api(MyappModelRestApi): label_columns[column_name]=columns[column_name]['describe'] description_columns[column_name] = columns[column_name]['describe'] - add_columns.append(column_name) + if not int(columns[column_name].get('primary_key',False)): + add_columns.append(column_name) show_columns.append(column_name) - list_columns.append(column_name) + if not int(columns[column_name].get('primary_key', False)): + list_columns.append(column_name) if column_type == 'string' or column_type=='text' or column_type=='int': if not int(columns[column_name].get('primary_key',False)): search_columns.append(column_name) - if column_type == 'int': - order_columns.append(column_name) + # if column_type == 'int': + order_columns.append(column_name) bind_key = 'dimension_%s' % dim.id # SQLALCHEMY_BINDS = conf.get('SQLALCHEMY_BINDS', {}) @@ -702,7 +714,7 @@ class Dimension_remote_table_ModelView_Api(MyappModelRestApi): elif cols.get(key,{}).get('column_type','text')=='double': data[key]=float(data[key]) if data[key] else None else: - data[key]=str(data[key]) + data[key]=str(data[key]).replace('\n',' ') except Exception as e: print(e) data[key] = None @@ -755,6 +767,36 @@ class Dimension_remote_table_ModelView_Api(MyappModelRestApi): ) + @action("copy_row", __("Copy"), __("复制所选记录 all Really?"), "fa-trash", single=False) + # @pysnooper.snoop(watch_explode=('items')) + def copy_row(self, items): + if not items: + abort(404) + success = [] + fail = [] + for item in items: + try: + req_json = item.to_json() + if 'id' in req_json: + del req_json["id"] + json_data = self.pre_add_req(req_json) + new_item = self.add_model_schema.load(json_data) + self.pre_add(new_item.data) + self.datamodel.add(new_item.data, raise_exception=True) + self.post_add(new_item.data) + result_data = self.add_model_schema.dump(new_item.data, many=False).data + success.append(item.to_json()) + except Exception as e: + flash(str(e), "danger") + fail.append(item.to_json()) + db.session.commit() + return json.dumps( + { + "success": success, + "fail": fail + }, indent=4, ensure_ascii=False + ) + view_class = type( "Dimension_%s_ModelView_Api"%dim.id, (MyappModelRestApi,), dict( @@ -765,12 +807,14 @@ class Dimension_remote_table_ModelView_Api(MyappModelRestApi): spec_label_columns=spec_label_columns, search_columns=search_columns, order_columns=order_columns, + add_columns=add_columns, label_title = dim.label, base_permissions = ['can_list','can_add','can_delete','can_edit','can_show'], pre_add=pre_add, pre_update=pre_update, upload=upload, muldelete=muldelete, + copy_row=copy_row, dim_id=dim_id, import_data=True, download_data=True, @@ -792,9 +836,9 @@ class Dimension_remote_table_ModelView_Api(MyappModelRestApi): @expose("//api/", methods=["GET"]) - def dim_api_get(self, dim_id,pk, **kwargs): + def dim_api_show(self, dim_id,pk, **kwargs): view_instance = self.set_model(dim_id) - return view_instance.api_get(pk,**kwargs) + return view_instance.api_show(pk,**kwargs) @expose("//api/", methods=["GET"]) def dim_api_list(self,dim_id, **kwargs): diff --git a/myapp/views/view_docker.py b/myapp/views/view_docker.py index 432fc4a2..7295145c 100644 --- a/myapp/views/view_docker.py +++ b/myapp/views/view_docker.py @@ -98,7 +98,7 @@ class Docker_ModelView_Base(): } edit_form_extra_fields=add_form_extra_fields # @pysnooper.snoop() - def pre_add_get(self,docker=None): + def pre_add_web(self,docker=None): self.add_form_extra_fields['target_image']=StringField( _(self.datamodel.obj.lab('target_image')), default=conf.get('REPOSITORY_ORG')+g.user.username+":"+datetime.datetime.now().strftime('%Y.%m.%d'+".1"), @@ -111,7 +111,7 @@ class Docker_ModelView_Base(): self.edit_form_extra_fields = self.add_form_extra_fields - pre_update_get=pre_add_get + pre_update_web=pre_add_web def pre_add(self,item): image_org=conf.get('REPOSITORY_ORG')+g.user.username+":" diff --git a/myapp/views/view_images.py b/myapp/views/view_images.py index 2c8aab32..61769979 100644 --- a/myapp/views/view_images.py +++ b/myapp/views/view_images.py @@ -79,7 +79,7 @@ class Repository_ModelView_Base(): validators=[Regexp("^[a-z][a-z0-9\-]*[a-z0-9]$"), Length(1, 54),DataRequired()] ) - pre_add_get = set_column + pre_add_web = set_column # create hubsecret # @pysnooper.snoop() diff --git a/myapp/views/view_inferenceserving.py b/myapp/views/view_inferenceserving.py index 322a0238..6d8833be 100644 --- a/myapp/views/view_inferenceserving.py +++ b/myapp/views/view_inferenceserving.py @@ -316,7 +316,7 @@ class InferenceService_ModelView_base(): edit_fieldsets = add_fieldsets - def pre_add_get(self): + def pre_add_web(self): self.default_filter = { "created_by": g.user.id } @@ -620,7 +620,7 @@ output %s # 修改了名称的话,要把之前的删掉 self.use_expand(item) - # 如果模型版本和名称变了,需要把之前的服务删除掉 + # 如果模型版本和模型名称变了,需要把之前的服务删除掉 if self.src_item_json.get('name','') and item.name!=self.src_item_json.get('name',''): self.delete_old_service(self.src_item_json.get('name',''), item.project.cluster) flash('发现模型服务变更,启动清理服务%s:%s'%(self.src_item_json.get('model_name',''),self.src_item_json.get('model_version','')),'success') @@ -782,14 +782,15 @@ output %s pod_env = service.env - pod_env+="\nKUBEFLOW_ENV="+env - pod_env+='\nKUBEFLOW_MODEL_PATH='+service.model_path if service.model_path else '' - pod_env+='\nKUBEFLOW_MODEL_VERSION='+service.model_version - pod_env+='\nKUBEFLOW_MODEL_IMAGES='+service.images - pod_env+='\nKUBEFLOW_MODEL_NAME='+service.model_name - pod_env += '\nKUBEFLOW_AREA=' + json.loads(service.project.expand).get('area','guangzhou') - pod_env=pod_env.strip(',') - + pod_env += "\nKUBEFLOW_ENV=" + env + pod_env += '\nKUBEFLOW_MODEL_PATH=' + service.model_path if service.model_path else '' + pod_env += '\nKUBEFLOW_MODEL_VERSION=' + service.model_version + pod_env += '\nKUBEFLOW_MODEL_IMAGES=' + service.images + pod_env += '\nKUBEFLOW_MODEL_NAME=' + service.model_name + pod_env += '\nKUBEFLOW_AREA=' + json.loads(service.project.expand).get('area', 'guangzhou') + pod_env += "\nRESOURCE_CPU=" + service.resource_cpu + pod_env += "\nRESOURCE_MEMORY=" + service.resource_memory + pod_env = pod_env.strip(',') if env=='test' or env =='debug': try: diff --git a/myapp/views/view_metadata.py b/myapp/views/view_metadata.py index ac9a13f9..cd7d5119 100644 --- a/myapp/views/view_metadata.py +++ b/myapp/views/view_metadata.py @@ -234,9 +234,7 @@ class Metadata_table_ModelView_base(): # @event_logger.log_this - @action( - "ddl", __("创建远程hive表"), __("ddl 保存修改"), "fa-save", multiple=False, single=True - ) + @action("ddl", __("更新到远程hive表"), __("ddl 保存修改"), "fa-save", multiple=False, single=True) def ddl(self, item): pass # 自己实现更新到hive表 @@ -249,18 +247,19 @@ class Metadata_table_ModelView_Api(Metadata_table_ModelView_base,MyappModelRestA # @pysnooper.snoop() - def pre_add_get(self): + def pre_add_web(self): self.default_filter = { "owner": g.user.username } # @pysnooper.snoop() - def pre_get_list(self,result): + def pre_list_res(self,result): data = result['data'] for item in data: storage_cost = item.get('storage_cost',0) if storage_cost: item['storage_cost']=round(float(storage_cost), 6) + return result # # 在info信息中添加特定参数 # @pysnooper.snoop() diff --git a/myapp/views/view_nni.py b/myapp/views/view_nni.py index 3fecaebb..e30b1b4f 100644 --- a/myapp/views/view_nni.py +++ b/myapp/views/view_nni.py @@ -323,8 +323,8 @@ class NNI_ModelView_Base(): - pre_add_get=set_column - pre_update_get=set_column + pre_add_web=set_column + pre_update_web=set_column # 处理form请求 def process_form(self, form, is_created): diff --git a/myapp/views/view_notebook.py b/myapp/views/view_notebook.py index c035d6b4..003e2774 100644 --- a/myapp/views/view_notebook.py +++ b/myapp/views/view_notebook.py @@ -15,14 +15,14 @@ from wtforms.validators import DataRequired, Length, Regexp from wtforms import SelectField, StringField from flask_appbuilder.fieldwidgets import BS3TextFieldWidget, Select2Widget from myapp.forms import MySelect2Widget, MyBS3TextFieldWidget - +from flask import Markup from myapp.utils.py.py_k8s import K8s from flask import ( abort, flash, g, redirect, - request, + request, make_response, ) from .baseApi import ( MyappModelRestApi @@ -264,8 +264,8 @@ class Notebook_ModelView_Base(): # self.add_template, title=self.add_title, widgets=widget # ) - pre_update_get=set_column - pre_add_get=set_column + pre_update_web=set_column + pre_add_web=set_column # @pysnooper.snoop(watch_explode=('notebook')) diff --git a/myapp/views/view_pipeline.py b/myapp/views/view_pipeline.py index 9382be16..f7130e76 100644 --- a/myapp/views/view_pipeline.py +++ b/myapp/views/view_pipeline.py @@ -3,6 +3,7 @@ from flask_babel import gettext as __ from flask_babel import lazy_gettext as _ import uuid import urllib.parse +from sqlalchemy.exc import InvalidRequestError from myapp.models.model_job import Task,Pipeline,Workflow, RunHistory from myapp.models.model_team import Project @@ -40,6 +41,7 @@ from flask import ( from myapp import security_manager from myapp.views.view_team import filter_join_org_project import kfp +import pysnooper from kubernetes import client from .base import ( DeleteMixin, @@ -574,7 +576,7 @@ class Pipeline_ModelView_Base(): cols_width={ "id":{"type": "ellip2", "width": 100}, "project": {"type": "ellip2", "width": 200}, - "pipeline_url":{"type": "ellip2", "width": 500}, + "pipeline_url":{"type": "ellip2", "width": 400}, "modified": {"type": "ellip2", "width": 150} } add_columns = ['project','name','describe'] @@ -698,6 +700,43 @@ class Pipeline_ModelView_Base(): related_views = [Task_ModelView, ] + def delete_task_run(self,task): + from myapp.utils.py.py_k8s import K8s + k8s_client = K8s(task.pipeline.project.cluster.get('KUBECONFIG','')) + namespace = conf.get('PIPELINE_NAMESPACE') + # 删除运行时容器 + pod_name = "run-" + task.pipeline.name.replace('_', '-') + "-" + task.name.replace('_', '-') + pod_name = pod_name.lower()[:60].strip('-') + pod = k8s_client.get_pods(namespace=namespace, pod_name=pod_name) + # print(pod) + if pod: + pod = pod[0] + # 有历史,直接删除 + if pod: + k8s_client.delete_pods(namespace=namespace,pod_name=pod['name']) + run_id = pod['labels'].get('run-id', '') + if run_id: + k8s_client.delete_workflow(all_crd_info = conf.get("CRD_INFO", {}), namespace=namespace,run_id=run_id) + k8s_client.delete_pods(namespace=namespace, labels={"run-id": run_id}) + time.sleep(2) + + + # 删除debug容器 + pod_name = "debug-" + task.pipeline.name.replace('_', '-') + "-" + task.name.replace('_', '-') + pod_name = pod_name.lower()[:60].strip('-') + pod = k8s_client.get_pods(namespace=namespace, pod_name=pod_name) + # print(pod) + if pod: + pod = pod[0] + # 有历史,直接删除 + if pod: + k8s_client.delete_pods(namespace=namespace, pod_name=pod['name']) + run_id = pod['labels'].get('run-id','') + if run_id: + k8s_client.delete_workflow(all_crd_info = conf.get("CRD_INFO", {}), namespace=namespace,run_id=run_id) + k8s_client.delete_pods(namespace=namespace, labels={"run-id":run_id}) + time.sleep(2) + # 检测是否具有编辑权限,只有creator和admin可以编辑 def check_edit_permission(self, item): @@ -835,12 +874,13 @@ class Pipeline_ModelView_Base(): flash('无法保障公共集群的稳定性,定时任务请选择专门的日更集群项目组','warning') - def pre_update_get(self,item): + def pre_update_web(self,item): item.dag_json = item.fix_dag_json() item.expand = json.dumps(item.fix_expand(),indent=4,ensure_ascii=False) db.session.commit() - # 删除前先把下面的task删除了 + + # 删除前先把下面的task删除了,把里面的运行实例也删除了 # @pysnooper.snoop() def pre_delete(self, pipeline): tasks = pipeline.get_tasks() @@ -854,6 +894,14 @@ class Pipeline_ModelView_Base(): pipeline.dag_json="{}" db.session.commit() + back_crds = pipeline.get_workflow() + self.delete_bind_crd(back_crds) + + # 删除task启动的所有实例 + for task in tasks: + self.delete_task_run(task) + + @expose("/my/list/") def my(self): @@ -942,7 +990,7 @@ class Pipeline_ModelView_Base(): return wraps - # # @event_logger.log_this + # @event_logger.log_this @expose("/run_pipeline/", methods=["GET", "POST"]) @check_pipeline_perms def run_pipeline(self,pipeline_id): @@ -986,6 +1034,13 @@ class Pipeline_ModelView_Base(): # not_running_crds = back_crds # [crd for crd in back_crds if 'running' not in crd['status'].lower()] self.delete_bind_crd(back_crds) + + + # 删除task启动的所有实例 + for task in tasks: + self.delete_task_run(task) + + # running_crds = [1 for crd in back_crds if 'running' in crd['status'].lower()] # if len(running_crds)>0: # flash("发现当前运行实例 %s 个,目前集群仅支持每个任务流1个运行实例,若要重新发起实例,请先stop旧实例"%len(running_crds),category='warning') @@ -1217,7 +1272,7 @@ class Pipeline_ModelView_Api(Pipeline_ModelView_Base,MyappModelRestApi): related_views = [Task_ModelView_Api,] - def pre_add_get(self): + def pre_add_web(self): self.default_filter = { "created_by": g.user.id } diff --git a/myapp/views/view_serving.py b/myapp/views/view_serving.py index dbc4d119..57651a90 100644 --- a/myapp/views/view_serving.py +++ b/myapp/views/view_serving.py @@ -49,7 +49,7 @@ class Service_Filter(MyappFilter): class Service_ModelView_base(): datamodel = SQLAInterface(Service) - show_columns = ['project','name', 'label','images','volume_mount','working_dir','command','env','resource_memory','resource_cpu','resource_gpu','replicas','ports','host_url'] + show_columns = ['project','name', 'label','images','volume_mount','working_dir','command','env','resource_memory','resource_cpu','resource_gpu','replicas','ports','host'] add_columns = ['project','name', 'label','images','working_dir','command','env','resource_memory','resource_cpu','resource_gpu','replicas','ports','host'] list_columns = ['project','name_url','host_url','ip','deploy','creator','modified'] cols_width={ @@ -70,7 +70,7 @@ class Service_ModelView_base(): "project": [["name", Project_Join_Filter, 'org']] } edit_form_query_rel_fields = add_form_query_rel_fields - host_rule = ",".join([cluster + "集群:*." + conf.get('CLUSTERS')[cluster].get("SERVICE_DOMAIN", conf.get('SERVICE_DOMAIN','')) for cluster in conf.get('CLUSTERS') if conf.get('CLUSTERS')[cluster].get("SERVICE_DOMAIN", conf.get('SERVICE_DOMAIN',''))]) + host_rule = ", ".join([cluster + "集群:*." + conf.get('CLUSTERS')[cluster].get("SERVICE_DOMAIN", conf.get('SERVICE_DOMAIN','')) for cluster in conf.get('CLUSTERS') if conf.get('CLUSTERS')[cluster].get("SERVICE_DOMAIN", conf.get('SERVICE_DOMAIN',''))]) add_form_extra_fields={ "project": QuerySelectField( _(datamodel.obj.lab('project')), @@ -156,6 +156,10 @@ class Service_ModelView_base(): volume_mount = service.volume_mount labels = {"app":service.name,"user":service.created_by.username,"pod-type":"service"} + env = service.env + env+="\nRESOURCE_CPU="+service.resource_cpu + env += "\nRESOURCE_MEMORY=" + service.resource_memory + k8s_client.create_deployment(namespace=namespace, name=service.name, replicas=service.replicas, @@ -172,7 +176,7 @@ class Service_ModelView_base(): image_pull_secrets=image_secrets, image=service.images, hostAliases=conf.get('HOSTALIASES',''), - env=service.env, + env=env, privileged=False, accounts=None, username=service.created_by.username, diff --git a/myapp/views/view_task.py b/myapp/views/view_task.py index 652df152..313865a8 100644 --- a/myapp/views/view_task.py +++ b/myapp/views/view_task.py @@ -361,6 +361,8 @@ class Task_ModelView_Base(): def pre_delete(self, item): self.check_redirect_list_url = '/pipeline_modelview/edit/' + str(item.pipeline.id) self.pipeline = item.pipeline + # 删除task启动的所有实例 + self.delete_task_run(item) widget_config = { @@ -647,15 +649,10 @@ class Task_ModelView_Base(): return redirect("/myapp/web/log/%s/%s/%s" % (task.pipeline.project.cluster['NAME'],namespace, pod_name)) - - - @expose("/clear/", methods=["GET", "POST"]) - def clear_task(self,task_id): - task = db.session.query(Task).filter_by(id=task_id).first() + def delete_task_run(self,task): from myapp.utils.py.py_k8s import K8s k8s_client = K8s(task.pipeline.project.cluster.get('KUBECONFIG','')) namespace = conf.get('PIPELINE_NAMESPACE') - # 删除运行时容器 pod_name = "run-" + task.pipeline.name.replace('_', '-') + "-" + task.name.replace('_', '-') pod_name = pod_name.lower()[:60].strip('-') @@ -688,6 +685,12 @@ class Task_ModelView_Base(): k8s_client.delete_workflow(all_crd_info = conf.get("CRD_INFO", {}), namespace=namespace,run_id=run_id) k8s_client.delete_pods(namespace=namespace, labels={"run-id":run_id}) time.sleep(2) + + + @expose("/clear/", methods=["GET", "POST"]) + def clear_task(self,task_id): + task = db.session.query(Task).filter_by(id=task_id).first() + self.delete_task_run(task) flash("删除完成",category='success') # self.update_redirect() return redirect('/pipeline_modelview/web/%s' % str(task.pipeline.id)) diff --git a/myapp/views/view_team.py b/myapp/views/view_team.py index 00036282..7ca47722 100644 --- a/myapp/views/view_team.py +++ b/myapp/views/view_team.py @@ -139,7 +139,7 @@ class Project_ModelView_Base(): # @pysnooper.snoop() - def pre_add_get(self): + def pre_add_web(self): self.edit_form_extra_fields['type'] = StringField( _(self.datamodel.obj.lab('type')), description="项目分组", @@ -162,8 +162,8 @@ class Project_ModelView_Base(): raise MyappException('just creator can add/edit') # before update, check permission - def pre_update_get(self, item): - self.pre_add_get() + def pre_update_web(self, item): + self.pre_add_web() self.check_item_permissions(item) if not self.user_permissions['edit']: flash('just creator can add/edit user','warning') diff --git a/myapp/views/view_train_model.py b/myapp/views/view_train_model.py index c19c6468..8f64206d 100644 --- a/myapp/views/view_train_model.py +++ b/myapp/views/view_train_model.py @@ -195,7 +195,7 @@ class Training_Model_ModelView_Base(): class Training_Model_ModelView(Training_Model_ModelView_Base,MyappModelView,DeleteMixin): datamodel = SQLAInterface(Training_Model) -appbuilder.add_view(Training_Model_ModelView,"模型管理",icon = 'fa-hdd-o',category = '服务化',category_icon = 'fa-tasks') +appbuilder.add_view_no_menu(Training_Model_ModelView) diff --git a/myapp/views/view_workflow.py b/myapp/views/view_workflow.py index ef6bc1b5..a8c4aed7 100644 --- a/myapp/views/view_workflow.py +++ b/myapp/views/view_workflow.py @@ -103,6 +103,9 @@ class Crd_ModelView_Base(): db.session.commit() + # 个性化删除操作 + def delete_more(self,item): + pass # 基础批量删除 # @pysnooper.snoop() @@ -110,6 +113,7 @@ class Crd_ModelView_Base(): if not items: abort(404) for item in items: + self.delete_more(item) if item: try: labels = json.loads(item.labels) if item.labels else {} @@ -200,7 +204,7 @@ class Workflow_ModelView_Base(Crd_ModelView_Base): # 删除之前的 workflow和相关容器 # @pysnooper.snoop() - def delete_workflow(self, workflow): + def delete_more(self, workflow): try: k8s_client = py_k8s.K8s(workflow.pipeline.project.cluster.get('KUBECONFIG','')) k8s_client.delete_workflow( @@ -214,11 +218,10 @@ class Workflow_ModelView_Base(Crd_ModelView_Base): except Exception as e: print(e) - @expose("/stop/") def stop(self, crd_id): workflow = db.session.query(self.datamodel.obj).filter_by(id=crd_id).first() - self.delete_workflow(workflow) + self.delete_more(workflow) flash('清理完成','success') url = conf.get('MODEL_URLS',{}).get('workflow','')