cube-studio/myapp/views/view_images.py
2021-09-07 18:09:47 +08:00

212 lines
7.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from flask import render_template,redirect
from flask_appbuilder.models.sqla.interface import SQLAInterface
from flask_appbuilder import ModelView, ModelRestApi
from flask_appbuilder import ModelView,AppBuilder,expose,BaseView,has_access
from importlib import reload
from flask_babel import gettext as __
from flask_babel import lazy_gettext as _
from flask_appbuilder.forms import GeneralModelConverter
import uuid
import re
from kfp import compiler
from sqlalchemy.exc import InvalidRequestError
# 将model添加成视图并控制在前端的显示
from myapp.models.model_job import Repository,Images
from myapp.views.view_team import Project_Filter
from myapp import app, appbuilder,db,event_logger
from wtforms import BooleanField, IntegerField,StringField, SelectField,FloatField,DateField,DateTimeField,SelectMultipleField,FormField,FieldList
from flask_appbuilder.fieldwidgets import BS3TextFieldWidget,BS3PasswordFieldWidget,DatePickerWidget,DateTimePickerWidget,Select2ManyWidget,Select2Widget
from myapp.forms import MyBS3TextAreaFieldWidget,MySelect2Widget,MyCodeArea,MyLineSeparatedListField,MyJSONField,MyBS3TextFieldWidget,MySelectMultipleField
from .baseApi import (
MyappModelRestApi
)
from flask import (
current_app,
abort,
flash,
g,
Markup,
make_response,
redirect,
render_template,
request,
send_from_directory,
Response,
url_for,
)
from myapp import security_manager
import kfp # 使用自定义的就要把pip安装的删除了
from werkzeug.datastructures import FileStorage
from kubernetes import client as k8s_client
from .base import (
api,
BaseMyappView,
check_ownership,
data_payload_response,
DeleteMixin,
generate_download_headers,
get_error_msg,
get_user_roles,
handle_api_exception,
json_error_response,
json_success,
MyappFilter,
MyappModelView,
)
from flask_appbuilder import CompactCRUDMixin, expose
import pysnooper,datetime,time,json
conf = app.config
logging = app.logger
# 定义数据库视图
class Repository_ModelView_Base():
datamodel = SQLAInterface(Repository)
label_title='仓库'
check_redirect_list_url = '/repository_modelview/list/'
base_permissions = ['can_add', 'can_edit', 'can_delete', 'can_list', 'can_show'] # 默认为这些
base_order = ('id', 'desc')
order_columns = ['id']
list_columns = ['name','hubsecret','creator','modified']
show_exclude_columns = ['password']
add_columns = ['name','server','user','password','hubsecret']
edit_columns = add_columns
add_form_extra_fields = {
"password": StringField(
_(datamodel.obj.lab('password')),
widget=BS3PasswordFieldWidget() # 传给widget函数的是外层的field对象以及widget函数的参数
)
}
edit_form_extra_fields = add_form_extra_fields
# @pysnooper.snoop()
def set_column(self):
self.add_form_extra_fields['name'] = StringField(
_(self.datamodel.obj.lab('name')),
default=g.user.username+"-",
widget=BS3TextFieldWidget() # 传给widget函数的是外层的field对象以及widget函数的参数
)
self.add_form_extra_fields['hubsecret'] = StringField(
_(self.datamodel.obj.lab('hubsecret')),
default=g.user.username + "-",
widget=BS3TextFieldWidget() # 传给widget函数的是外层的field对象以及widget函数的参数
)
pre_add_get = set_column
# 直接创建hubsecret
# @pysnooper.snoop()
def apply_hubsecret(self,hubsecret):
from myapp.utils.py.py_k8s import K8s
all_cluster=conf.get('CLUSTERS',{})
all_kubeconfig = [all_cluster[cluster]['KUBECONFIG'] for cluster in all_cluster]+['']
all_kubeconfig = list(set(all_kubeconfig))
for kubeconfig in all_kubeconfig:
k8s = K8s(kubeconfig)
namespaces = conf.get('HUBSECRET_NAMESPACE')
for namespace in namespaces:
k8s.apply_hubsecret(namespace=namespace,
name=hubsecret.hubsecret,
user=hubsecret.user,
password=hubsecret.password,
server=hubsecret.server
)
def post_add(self, item):
self.apply_hubsecret(item)
def post_update(self, item):
self.apply_hubsecret(item)
class Repository_ModelView(Repository_ModelView_Base,MyappModelView,DeleteMixin):
datamodel = SQLAInterface(Repository)
# 添加视图和菜单
appbuilder.add_view(Repository_ModelView,"仓库",icon = 'fa-shopping-basket',category = '训练',category_icon = 'fa-tasks')
# 添加api
class Repository_ModelView_Api(Repository_ModelView_Base,MyappModelRestApi):
datamodel = SQLAInterface(Repository)
route_base = '/repository_modelview/api'
appbuilder.add_api(Repository_ModelView_Api)
# 只能查看到自己归属的项目组的镜像
class Images_Filter(MyappFilter):
# @pysnooper.snoop(watch_explode=('result'))
def apply(self, query, func):
user_roles = [role.name.lower() for role in list(self.get_user_roles())]
if "admin" in user_roles:
return query
result = query.order_by(self.model.id.desc())
return result
# 定义数据库视图
class Images_ModelView_Base():
label_title='镜像'
datamodel = SQLAInterface(Images)
check_redirect_list_url = '/images_modelview/list/?_flt_2_name='
help_url = conf.get('HELP_URL', {}).get(datamodel.obj.__tablename__, '') if datamodel else ''
list_columns = ['images_url','creator','modified']
base_order = ('id', 'desc')
order_columns = ['id']
add_columns = ['repository', 'name', 'describe', 'dockerfile', 'gitpath']
edit_columns = add_columns
add_form_extra_fields = {
"dockerfile": StringField(
_(datamodel.obj.lab('dockerfile')),
description='镜像的构建Dockerfile全部内容',
widget=MyBS3TextAreaFieldWidget(rows=10), # 传给widget函数的是外层的field对象以及widget函数的参数
),
"name": StringField(
_(datamodel.obj.lab('name')),
description='镜像名称全称例如ubuntu:20.04',
widget=BS3TextFieldWidget(), # 传给widget函数的是外层的field对象以及widget函数的参数
),
"entrypoint": StringField(
_(datamodel.obj.lab('entrypoint')),
description='镜像的入口命令直接写成单行字符串例如python xx.py无需添加[]',
widget=BS3TextFieldWidget(), # 传给widget函数的是外层的field对象以及widget函数的参数
)
}
edit_form_extra_fields = add_form_extra_fields
base_filters = [["id", Images_Filter, lambda: []]] # 设置权限过滤器
class Images_ModelView(Images_ModelView_Base,MyappModelView,DeleteMixin):
datamodel = SQLAInterface(Images)
appbuilder.add_view(Images_ModelView,"模板镜像",href="/images_modelview/list/?_flt_2_name=",icon = 'fa-file-image-o',category = '训练',category_icon = 'fa-envelope')
# 添加api
class Images_ModelView_Api(Images_ModelView_Base,MyappModelRestApi):
datamodel = SQLAInterface(Images)
route_base = '/images_modelview/api'
list_columns = ['images_url', 'repository', 'name', 'describe', 'dockerfile', 'gitpath','modified','creator']
appbuilder.add_api(Images_ModelView_Api)
appbuilder.add_separator("训练") # 在指定菜单栏下面的每个子菜单中间添加一个分割线的显示。