running_project_model
This commit is contained in:
parent
b1ab2df214
commit
b45ddb291f
23
API.md
23
API.md
|
|
@ -64,6 +64,7 @@ type Model struct {
|
||||||
```
|
```
|
||||||
|
|
||||||
数据结构中包含的Comment字段为该数据的简单描述,Doc字段为该数据的详细文档,文档应支持Markdown格式保存和渲染。
|
数据结构中包含的Comment字段为该数据的简单描述,Doc字段为该数据的详细文档,文档应支持Markdown格式保存和渲染。
|
||||||
|
在所有创建对象的请求(POST)中,ID字段将被忽略,创建成功后自动分配ID。
|
||||||
|
|
||||||
## 镜像管理
|
## 镜像管理
|
||||||
|
|
||||||
|
|
@ -90,7 +91,7 @@ CURD:
|
||||||
+ GET /images?UserName=cg_wmj # 查询某用户的镜像
|
+ GET /images?UserName=cg_wmj # 查询某用户的镜像
|
||||||
+ GET /images?IsPublish=1 # 查询所有公开镜像
|
+ GET /images?IsPublish=1 # 查询所有公开镜像
|
||||||
|
|
||||||
## 数据集管理 (尚未实现)
|
## 数据集管理
|
||||||
|
|
||||||
训练数据,数据结构:
|
训练数据,数据结构:
|
||||||
```go
|
```go
|
||||||
|
|
@ -118,7 +119,7 @@ CURD:
|
||||||
+ GET /data?UserName=cg_wmj
|
+ GET /data?UserName=cg_wmj
|
||||||
+ GET /data?IsPublish=1
|
+ GET /data?IsPublish=1
|
||||||
|
|
||||||
## 项目管理 (尚未实现)
|
## 项目管理
|
||||||
|
|
||||||
数据结构
|
数据结构
|
||||||
```go
|
```go
|
||||||
|
|
@ -132,9 +133,8 @@ type ProjectModel struct {
|
||||||
Doc string
|
Doc string
|
||||||
IsPublic bool
|
IsPublic bool
|
||||||
|
|
||||||
ImageID int
|
Image ImageModel
|
||||||
Image ImageModel
|
TrainData []*ProjectTrainDataModel `gorm:"foreignKey:ProjectID"`
|
||||||
TrainData []*DataModel `gorm:"many2many:projects_data"`
|
|
||||||
|
|
||||||
|
|
||||||
UserPath string // 用户目录挂载位置
|
UserPath string // 用户目录挂载位置
|
||||||
|
|
@ -143,6 +143,14 @@ type ProjectModel struct {
|
||||||
|
|
||||||
Running bool `gorm:"-:all"`
|
Running bool `gorm:"-:all"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type ProjectTrainDataModel struct {
|
||||||
|
BaseModel[ProjectTrainDataModel]
|
||||||
|
Project *ProjectModel
|
||||||
|
Data *DataModel
|
||||||
|
MountPath string
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
其中`Type`字段为项目的类型,可选值为`jupyter`、`jupyterlab`、`jupyternotebook`、`novnc`、`vscode`、`http`。
|
其中`Type`字段为项目的类型,可选值为`jupyter`、`jupyterlab`、`jupyternotebook`、`novnc`、`vscode`、`http`。
|
||||||
|
|
@ -161,6 +169,7 @@ CURD:
|
||||||
数据结构
|
数据结构
|
||||||
```go
|
```go
|
||||||
type RunningProject struct {
|
type RunningProject struct {
|
||||||
|
ID int
|
||||||
Project *ProjectModel
|
Project *ProjectModel
|
||||||
StartTime *time.Time
|
StartTime *time.Time
|
||||||
UserName string
|
UserName string
|
||||||
|
|
@ -177,9 +186,7 @@ type RunningProject struct {
|
||||||
运行一个项目,前端发送POST请求时URL可留空,若该项目成功启动,则POST的返回内容中将包含正确的URL。
|
运行一个项目,前端发送POST请求时URL可留空,若该项目成功启动,则POST的返回内容中将包含正确的URL。
|
||||||
通过此URL即可访问项目服务。ControlURL为容器服务客户端连接地址,可通过本地客户端提供更多功能。
|
通过此URL即可访问项目服务。ControlURL为容器服务客户端连接地址,可通过本地客户端提供更多功能。
|
||||||
|
|
||||||
此数据结构中没有ID字段,删除时使用其对应的ProjectModel的ID。
|
|
||||||
|
|
||||||
CURD:
|
CURD:
|
||||||
+ POST:/running_project
|
+ POST:/running_project
|
||||||
+ DELETE: /running_project?ProjectID=1
|
+ DELETE: /running_project?ID=1
|
||||||
+ GET /running_projects?UserName=cg_wmj
|
+ GET /running_projects?UserName=cg_wmj
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package controller
|
||||||
|
|
||||||
|
import "k8s-manager/src/model"
|
||||||
|
|
||||||
|
func CreateRunningProject(r *model.RunningProject) (*model.RunningProject, error) {
|
||||||
|
|
||||||
|
return r, nil
|
||||||
|
}
|
||||||
|
|
@ -1,197 +0,0 @@
|
||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"k8s-manager/src"
|
|
||||||
v1 "k8s.io/api/core/v1"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
"unicode"
|
|
||||||
)
|
|
||||||
|
|
||||||
type AppModel struct {
|
|
||||||
Id int
|
|
||||||
AppName string
|
|
||||||
UserName string
|
|
||||||
Image string
|
|
||||||
Command string
|
|
||||||
Comment string
|
|
||||||
Env string
|
|
||||||
SvcName string
|
|
||||||
SvcRemovePrefix bool
|
|
||||||
Ports string
|
|
||||||
PersistentPath string
|
|
||||||
OriginId int
|
|
||||||
CreateTime time.Time
|
|
||||||
UpdateTime time.Time
|
|
||||||
IsPublished bool
|
|
||||||
AppType string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*AppModel) TableName() string {
|
|
||||||
return "app"
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetApps(username string) []AppModel {
|
|
||||||
db := k8s_manager.DB()
|
|
||||||
ans := make([]AppModel, 0)
|
|
||||||
db.Where("user_name = ?", username).Find(&ans)
|
|
||||||
return ans
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) Fill() error {
|
|
||||||
db := k8s_manager.DB()
|
|
||||||
res := db.First(a, a.Id)
|
|
||||||
return res.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) fillDefaults() {
|
|
||||||
if a.SvcName == "" {
|
|
||||||
a.SvcName = "svc"
|
|
||||||
}
|
|
||||||
a.SvcName = strings.TrimPrefix(a.SvcName, a.NamePrefix()+"-")
|
|
||||||
if a.PersistentPath == "" {
|
|
||||||
a.PersistentPath = "/data/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) Update() error {
|
|
||||||
a.fillDefaults()
|
|
||||||
a.UpdateTime = time.Now()
|
|
||||||
db := k8s_manager.DB()
|
|
||||||
db.Save(a)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) Create() error {
|
|
||||||
a.fillDefaults()
|
|
||||||
a.CreateTime = time.Now()
|
|
||||||
a.UpdateTime = time.Now()
|
|
||||||
db := k8s_manager.DB()
|
|
||||||
db.Create(a)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) Delete() error {
|
|
||||||
db := k8s_manager.DB()
|
|
||||||
db.Delete(a, a.Id)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) NamePrefix() string {
|
|
||||||
t := "app"
|
|
||||||
if a.OriginId > 0 {
|
|
||||||
t = "fork"
|
|
||||||
}
|
|
||||||
prefix := fmt.Sprintf("%s-%s-%s-%d", t, a.UserName, a.AppName, a.Id)
|
|
||||||
ans := strings.Builder{}
|
|
||||||
for _, c := range prefix {
|
|
||||||
if (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-' {
|
|
||||||
ans.WriteRune(c)
|
|
||||||
} else {
|
|
||||||
ans.WriteString(fmt.Sprintf("-%d-", c))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ans.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) PodName() string {
|
|
||||||
return fmt.Sprintf("%s-pod", a.NamePrefix())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) ContainerName() string {
|
|
||||||
return fmt.Sprintf("%s-container", a.NamePrefix())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) ServiceName() string {
|
|
||||||
if len(a.GetPorts()) == 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
if strings.TrimSpace(a.SvcName) != "" {
|
|
||||||
return fmt.Sprintf("%s-%s", a.NamePrefix(), a.SvcName)
|
|
||||||
}
|
|
||||||
return a.DefaultServiceName()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) DefaultServiceName() string {
|
|
||||||
return fmt.Sprintf("%s-svc", a.NamePrefix())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) DeploymentName() string {
|
|
||||||
return fmt.Sprintf("%s-deployment", a.NamePrefix())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) GetCommandOrBlack() []string {
|
|
||||||
if strings.TrimSpace(a.Command) != "" {
|
|
||||||
t := a.Command
|
|
||||||
t = strings.ReplaceAll(t, "$URL_PREFIX", "svc/"+a.URLPrefix())
|
|
||||||
return []string{"/bin/sh", "-c", t}
|
|
||||||
} else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) GetLabel() (string, string) {
|
|
||||||
return "cg-label", fmt.Sprintf("%s-label", a.NamePrefix())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) GetEnv() []v1.EnvVar {
|
|
||||||
if strings.TrimSpace(a.Env) == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
sep1 := strings.Split(a.Env, " ")
|
|
||||||
ans := make([]v1.EnvVar, len(sep1))
|
|
||||||
for i, v := range sep1 {
|
|
||||||
kv := strings.SplitN(v, "=", 2)
|
|
||||||
ans[i].Name = kv[0]
|
|
||||||
if len(kv) == 2 {
|
|
||||||
ans[i].Value = kv[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ans
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) GetPorts() []int32 {
|
|
||||||
ans := make([]int32, 0)
|
|
||||||
var cur int32 = 0
|
|
||||||
for _, c := range a.Ports {
|
|
||||||
if unicode.IsNumber(c) {
|
|
||||||
cur = cur*10 + (c - '0')
|
|
||||||
} else if cur > 0 {
|
|
||||||
ans = append(ans, cur)
|
|
||||||
cur = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if cur > 0 {
|
|
||||||
ans = append(ans, cur)
|
|
||||||
}
|
|
||||||
return ans
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) IngressName() string {
|
|
||||||
return fmt.Sprintf("%s-ingress", a.NamePrefix())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) URLPrefix() string {
|
|
||||||
return a.ServiceName()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) PersistentVolumeName() string {
|
|
||||||
return a.UserName + "-pv"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) NFSPath() string {
|
|
||||||
return k8s_manager.GetConfig().NFSPath + "/" + a.UserName + "/" + a.AppName
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) PersistentVolumeClaimName() string {
|
|
||||||
return a.NamePrefix() + "-pvc"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) StorageClassName() string {
|
|
||||||
return a.NamePrefix() + "-storage-class"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AppModel) PersistentVolumeMountName() string {
|
|
||||||
return a.NamePrefix() + "-pvm"
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
k8s_manager "k8s-manager/src"
|
k8s_manager "k8s-manager/src"
|
||||||
"k8s-manager/src/utils"
|
"k8s-manager/src/utils"
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
"unicode"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ProjectModel struct {
|
type ProjectModel struct {
|
||||||
|
|
@ -105,4 +109,164 @@ type RunningProject struct {
|
||||||
GpuMemory int
|
GpuMemory int
|
||||||
URL string
|
URL string
|
||||||
ControlURL string
|
ControlURL string
|
||||||
|
|
||||||
|
ID int
|
||||||
|
SvcRemovePrefix bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RunningProject) NamePrefix() string {
|
||||||
|
t := "app"
|
||||||
|
prefix := fmt.Sprintf("%s-%s-%s-%d", t, a.UserName, a.Project.ProjectName, a.ID)
|
||||||
|
ans := strings.Builder{}
|
||||||
|
for _, c := range prefix {
|
||||||
|
if (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-' {
|
||||||
|
ans.WriteRune(c)
|
||||||
|
} else {
|
||||||
|
ans.WriteString(fmt.Sprintf("-%d-", c))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ans.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RunningProject) PodName() string {
|
||||||
|
return fmt.Sprintf("%s-pod", a.NamePrefix())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RunningProject) ContainerName() string {
|
||||||
|
return fmt.Sprintf("%s-container", a.NamePrefix())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RunningProject) ServiceName() string {
|
||||||
|
if len(a.GetPorts()) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return a.DefaultServiceName()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RunningProject) DefaultServiceName() string {
|
||||||
|
return fmt.Sprintf("%s-svc", a.NamePrefix())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RunningProject) DeploymentName() string {
|
||||||
|
return fmt.Sprintf("%s-deployment", a.NamePrefix())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RunningProject) GetCommandOrBlack() []string {
|
||||||
|
if strings.TrimSpace(a.Project.Image.Command) != "" {
|
||||||
|
t := a.Project.Image.Command
|
||||||
|
t = strings.ReplaceAll(t, "$URL_PREFIX", "svc/"+a.URLPrefix())
|
||||||
|
return []string{"/bin/sh", "-c", t}
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RunningProject) GetLabel() (string, string) {
|
||||||
|
return "cg-label", fmt.Sprintf("%s-label", a.NamePrefix())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RunningProject) GetEnv() []v1.EnvVar {
|
||||||
|
if strings.TrimSpace(a.Project.Image.Env) == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
sep1 := strings.Split(a.Project.Image.Env, " ")
|
||||||
|
ans := make([]v1.EnvVar, len(sep1))
|
||||||
|
for i, v := range sep1 {
|
||||||
|
kv := strings.SplitN(v, "=", 2)
|
||||||
|
ans[i].Name = kv[0]
|
||||||
|
if len(kv) == 2 {
|
||||||
|
ans[i].Value = kv[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ans
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RunningProject) GetPorts() []int32 {
|
||||||
|
ans := make([]int32, 0)
|
||||||
|
var cur int32 = 0
|
||||||
|
for _, c := range a.Project.Image.Port {
|
||||||
|
if unicode.IsNumber(c) {
|
||||||
|
cur = cur*10 + (c - '0')
|
||||||
|
} else if cur > 0 {
|
||||||
|
ans = append(ans, cur)
|
||||||
|
cur = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if cur > 0 {
|
||||||
|
ans = append(ans, cur)
|
||||||
|
}
|
||||||
|
return ans
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RunningProject) IngressName() string {
|
||||||
|
return fmt.Sprintf("%s-ingress", a.NamePrefix())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RunningProject) URLPrefix() string {
|
||||||
|
return a.ServiceName()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RunningProject) PersistentVolumeName() string {
|
||||||
|
return a.UserName + "-pv"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RunningProject) NFSPath() string {
|
||||||
|
return k8s_manager.GetConfig().NFSPath + "/" + a.UserName + "/" + a.Project.ProjectName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RunningProject) PersistentVolumeClaimName() string {
|
||||||
|
return a.NamePrefix() + "-pvc"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RunningProject) StorageClassName() string {
|
||||||
|
return a.NamePrefix() + "-storage-class"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RunningProject) PersistentVolumeMountName() string {
|
||||||
|
return a.NamePrefix() + "-pvm"
|
||||||
|
}
|
||||||
|
|
||||||
|
type NFSMount struct {
|
||||||
|
Name string
|
||||||
|
From string
|
||||||
|
To string
|
||||||
|
ReadOnly bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RunningProject) createNFSMount(name string, from string, to string, readonly bool) NFSMount {
|
||||||
|
return NFSMount{
|
||||||
|
Name: fmt.Sprintf("%s-nfs-%s", a.NamePrefix(), name),
|
||||||
|
From: from,
|
||||||
|
To: to,
|
||||||
|
ReadOnly: readonly,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RunningProject) GetNFSMounts() []NFSMount {
|
||||||
|
var ans []NFSMount
|
||||||
|
if a.Project.UserPath != "" {
|
||||||
|
ans = append(ans, a.createNFSMount("user",
|
||||||
|
fmt.Sprintf("/users/%s/home", a.UserName), a.Project.UserPath, false))
|
||||||
|
}
|
||||||
|
if a.Project.CodePath != "" {
|
||||||
|
ans = append(ans, a.createNFSMount("code",
|
||||||
|
fmt.Sprintf("/users/%s/code/%s", a.UserName, a.Project.ProjectName), a.Project.CodePath, false))
|
||||||
|
}
|
||||||
|
if a.Project.CodePath != "" {
|
||||||
|
ans = append(ans, a.createNFSMount("model",
|
||||||
|
fmt.Sprintf("/users/%s/model/%s", a.UserName, a.Project.ProjectName), a.Project.ModelPath, false))
|
||||||
|
}
|
||||||
|
for i, m := range a.Project.TrainData {
|
||||||
|
if m.Data.Type != "dir" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ans = append(ans, a.createNFSMount(
|
||||||
|
fmt.Sprintf("%s-%d", m.Data.Name, i),
|
||||||
|
m.Data.AccessInfo,
|
||||||
|
m.MountPath,
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return ans
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,24 +73,53 @@ func (c *K8sClient) DeploymentExists(deploymentName string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *K8sClient) UpdateDeployment(app *model.AppModel) {
|
func checkDirs(mounts []model.NFSMount) {
|
||||||
labelKey, labelValue := app.GetLabel()
|
for _, n := range mounts {
|
||||||
l := map[string]string{labelKey: labelValue}
|
if _, err := os.Stat(n.From); os.IsNotExist(err) {
|
||||||
if _, err := os.Stat(app.NFSPath()); os.IsNotExist(err) {
|
err := os.MkdirAll(n.From, 0777)
|
||||||
err := os.MkdirAll(app.NFSPath(), 0777)
|
if err != nil {
|
||||||
if err != nil {
|
log.WithError(err).Error("Make nfs dir error")
|
||||||
log.WithError(err).Error("Make nfs dir error")
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *K8sClient) UpdateDeployment(app *model.RunningProject) {
|
||||||
|
labelKey, labelValue := app.GetLabel()
|
||||||
|
l := map[string]string{labelKey: labelValue}
|
||||||
|
nfsDirs := app.GetNFSMounts()
|
||||||
|
checkDirs(nfsDirs)
|
||||||
|
var volumeMounts []v1.VolumeMount
|
||||||
|
var volumes []v1.Volume
|
||||||
|
for _, n := range nfsDirs {
|
||||||
|
volumeMounts = append(volumeMounts, v1.VolumeMount{
|
||||||
|
Name: n.Name,
|
||||||
|
MountPath: n.To,
|
||||||
|
ReadOnly: n.ReadOnly,
|
||||||
|
})
|
||||||
|
volumes = append(volumes, v1.Volume{
|
||||||
|
Name: n.Name,
|
||||||
|
VolumeSource: v1.VolumeSource{
|
||||||
|
NFS: &v1.NFSVolumeSource{
|
||||||
|
Server: k8s_manager.GetConfig().NFSPath,
|
||||||
|
Path: n.From,
|
||||||
|
ReadOnly: n.ReadOnly,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
podLabels := map[string]string{
|
podLabels := map[string]string{
|
||||||
labelKey: labelValue,
|
labelKey: labelValue,
|
||||||
"cg-deployment": app.DeploymentName(),
|
"cg-deployment": app.DeploymentName(),
|
||||||
}
|
}
|
||||||
|
|
||||||
containerPorts := funk.Map(app.GetPorts(), func(port int32) v1.ContainerPort {
|
containerPorts := funk.Map(app.GetPorts(), func(port int32) v1.ContainerPort {
|
||||||
return v1.ContainerPort{
|
return v1.ContainerPort{
|
||||||
ContainerPort: port,
|
ContainerPort: port,
|
||||||
}
|
}
|
||||||
}).([]v1.ContainerPort)
|
}).([]v1.ContainerPort)
|
||||||
|
|
||||||
deployment := &appv1.Deployment{
|
deployment := &appv1.Deployment{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: app.DeploymentName(),
|
Name: app.DeploymentName(),
|
||||||
|
|
@ -108,36 +137,19 @@ func (c *K8sClient) UpdateDeployment(app *model.AppModel) {
|
||||||
Spec: v1.PodSpec{
|
Spec: v1.PodSpec{
|
||||||
Containers: []v1.Container{{
|
Containers: []v1.Container{{
|
||||||
Name: app.ContainerName(),
|
Name: app.ContainerName(),
|
||||||
Image: app.Image,
|
Image: app.Project.Image.Image,
|
||||||
Command: app.GetCommandOrBlack(),
|
Command: app.GetCommandOrBlack(),
|
||||||
Env: append(app.GetEnv(), v1.EnvVar{
|
Env: append(app.GetEnv(), v1.EnvVar{
|
||||||
Name: "URL_PREFIX",
|
Name: "URL_PREFIX",
|
||||||
Value: app.URLPrefix(),
|
Value: app.URLPrefix(),
|
||||||
}),
|
}),
|
||||||
VolumeMounts: []v1.VolumeMount{
|
VolumeMounts: volumeMounts,
|
||||||
{
|
Ports: containerPorts,
|
||||||
Name: app.PersistentVolumeMountName(),
|
|
||||||
ReadOnly: false,
|
|
||||||
MountPath: app.PersistentPath,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Ports: containerPorts,
|
|
||||||
SecurityContext: &v1.SecurityContext{
|
SecurityContext: &v1.SecurityContext{
|
||||||
RunAsUser: utils.UnnamedPointer(int64(0)),
|
RunAsUser: utils.UnnamedPointer(int64(0)),
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
Volumes: []v1.Volume{
|
Volumes: volumes,
|
||||||
{
|
|
||||||
Name: app.PersistentVolumeMountName(),
|
|
||||||
VolumeSource: v1.VolumeSource{
|
|
||||||
NFS: &v1.NFSVolumeSource{
|
|
||||||
Server: k8s_manager.GetConfig().NFSHost,
|
|
||||||
Path: app.NFSPath(),
|
|
||||||
ReadOnly: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -166,7 +178,7 @@ func (c *K8sClient) ServiceExists(servername string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *K8sClient) UpdateService(app *model.AppModel) {
|
func (c *K8sClient) UpdateService(app *model.RunningProject) {
|
||||||
ports := app.GetPorts()
|
ports := app.GetPorts()
|
||||||
if len(ports) == 0 {
|
if len(ports) == 0 {
|
||||||
return
|
return
|
||||||
|
|
@ -210,19 +222,19 @@ func (c *K8sClient) UpdateService(app *model.AppModel) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *K8sClient) CreateApp(app *model.AppModel) {
|
func (c *K8sClient) CreateApp(app *model.RunningProject) {
|
||||||
c.UpdateDeployment(app)
|
c.UpdateDeployment(app)
|
||||||
c.UpdateService(app)
|
c.UpdateService(app)
|
||||||
c.UpdateIngress(app)
|
c.UpdateIngress(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *K8sClient) DeleteApp(app *model.AppModel) {
|
func (c *K8sClient) DeleteApp(app *model.RunningProject) {
|
||||||
c.DeleteDeployment(app.DeploymentName())
|
c.DeleteDeployment(app.DeploymentName())
|
||||||
c.DeleteAppService(app)
|
c.DeleteAppService(app)
|
||||||
c.DeleteIngress(app.IngressName())
|
c.DeleteIngress(app.IngressName())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *K8sClient) DeleteAppService(app *model.AppModel) {
|
func (c *K8sClient) DeleteAppService(app *model.RunningProject) {
|
||||||
k, v := app.GetLabel()
|
k, v := app.GetLabel()
|
||||||
label := labels.FormatLabels(map[string]string{k: v})
|
label := labels.FormatLabels(map[string]string{k: v})
|
||||||
svcs, err := c.CoreV1().Services(c.Namespace).List(context.Background(), metav1.ListOptions{
|
svcs, err := c.CoreV1().Services(c.Namespace).List(context.Background(), metav1.ListOptions{
|
||||||
|
|
@ -294,7 +306,7 @@ func (c *K8sClient) IngressExists(name string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *K8sClient) UpdateIngress(a *model.AppModel) {
|
func (c *K8sClient) UpdateIngress(a *model.RunningProject) {
|
||||||
ports := a.GetPorts()
|
ports := a.GetPorts()
|
||||||
if len(ports) == 0 {
|
if len(ports) == 0 {
|
||||||
return
|
return
|
||||||
|
|
@ -363,7 +375,7 @@ func (c *K8sClient) DeleteIngress(name string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
func (c *K8sClient) PersistentVolumeExists(app *AppModel) bool {
|
func (c *K8sClient) PersistentVolumeExists(app *RunningProject) bool {
|
||||||
_, err := c.CoreV1().PersistentVolumes().Get(context.Background(), app.PersistentVolumeName(), metav1.GetOptions{})
|
_, err := c.CoreV1().PersistentVolumes().Get(context.Background(), app.PersistentVolumeName(), metav1.GetOptions{})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return true
|
return true
|
||||||
|
|
@ -374,7 +386,7 @@ func (c *K8sClient) PersistentVolumeExists(app *AppModel) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *K8sClient) CreatePersistentVolume(app *AppModel) {
|
func (c *K8sClient) CreatePersistentVolume(app *RunningProject) {
|
||||||
cap1, _ := resource.ParseQuantity("1Gi")
|
cap1, _ := resource.ParseQuantity("1Gi")
|
||||||
pv := &v1.PersistentVolume{
|
pv := &v1.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
|
@ -404,7 +416,7 @@ func (c *K8sClient) CreatePersistentVolume(app *AppModel) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *K8sClient) PersistentVolumeClaimExists(app *AppModel) bool {
|
func (c *K8sClient) PersistentVolumeClaimExists(app *RunningProject) bool {
|
||||||
_, err := c.CoreV1().PersistentVolumeClaims(c.Namespace).Get(context.Background(), app.PersistentVolumeClaimName(), metav1.GetOptions{})
|
_, err := c.CoreV1().PersistentVolumeClaims(c.Namespace).Get(context.Background(), app.PersistentVolumeClaimName(), metav1.GetOptions{})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return true
|
return true
|
||||||
|
|
@ -415,7 +427,7 @@ func (c *K8sClient) PersistentVolumeClaimExists(app *AppModel) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *K8sClient) CreatePersistentVolumeClaim(app *AppModel) {
|
func (c *K8sClient) CreatePersistentVolumeClaim(app *RunningProject) {
|
||||||
pvc := &v1.PersistentVolumeClaim{
|
pvc := &v1.PersistentVolumeClaim{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: app.PersistentVolumeClaimName(),
|
Name: app.PersistentVolumeClaimName(),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue