mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-12-16 03:59:29 +08:00
feat: 增加创建 WORDPRESS 之前创建数据库功能
This commit is contained in:
parent
dc70d7cfc1
commit
ad50907158
25 changed files with 427 additions and 201 deletions
|
|
@ -39,7 +39,7 @@
|
||||||
"author": "Nginx",
|
"author": "Nginx",
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"required": [""],
|
"required": [""],
|
||||||
"limit": 0,
|
"limit": 1,
|
||||||
"crossVersionUpdate": true,
|
"crossVersionUpdate": true,
|
||||||
"source": "http://nginx.org/"
|
"source": "http://nginx.org/"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,11 @@ services:
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
TZ: ${TZ}
|
TZ: ${TZ}
|
||||||
MYSQL_DATABASE: ${DATABASE}
|
MYSQL_ROOT_PASSWORD: ${PANEL_DB_ROOT_PASSWORD}
|
||||||
MYSQL_USER: ${USER}
|
|
||||||
MYSQL_PASSWORD: ${PASSWORD}
|
|
||||||
MYSQL_ROOT_PASSWORD: ${ROOT_PASSWORD}
|
|
||||||
networks:
|
networks:
|
||||||
- 1panel
|
- 1panel
|
||||||
ports:
|
ports:
|
||||||
- ${PORT}:3306
|
- ${PANEL_APP_PORT}:3306
|
||||||
volumes:
|
volumes:
|
||||||
- ./data/:/var/lib/mysql
|
- ./data/:/var/lib/mysql
|
||||||
- ./conf/my.cnf:/etc/mysql/my.cnf
|
- ./conf/my.cnf:/etc/mysql/my.cnf
|
||||||
|
|
|
||||||
|
|
@ -1,44 +1,12 @@
|
||||||
{
|
{
|
||||||
"formFields": [
|
"formFields": [
|
||||||
{
|
|
||||||
"type": "text",
|
|
||||||
"labelZh": "时区",
|
|
||||||
"labelEn": "TimeZone",
|
|
||||||
"required": true,
|
|
||||||
"default": "Asia/Shanghai",
|
|
||||||
"envKey": "TZ"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "text",
|
|
||||||
"labelZh": "数据库",
|
|
||||||
"labelEn": "Database",
|
|
||||||
"required": true,
|
|
||||||
"default": "db",
|
|
||||||
"envKey": "DATABASE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "text",
|
|
||||||
"labelZh": "普通用户",
|
|
||||||
"labelEn": "User",
|
|
||||||
"required": true,
|
|
||||||
"default": "mysql",
|
|
||||||
"envKey": "USER"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "text",
|
|
||||||
"labelZh": "普通用户密码",
|
|
||||||
"labelEn": "Password",
|
|
||||||
"required": true,
|
|
||||||
"default": "1qaz@WSX",
|
|
||||||
"envKey": "PASSWORD"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"labelZh": "Root用户密码",
|
"labelZh": "Root用户密码",
|
||||||
"labelEn": "RootPassword",
|
"labelEn": "RootPassword",
|
||||||
"required": true,
|
"required": true,
|
||||||
"default": "1panel@mysql",
|
"default": "1panel@mysql",
|
||||||
"envKey": "ROOT_PASSWORD"
|
"envKey": "PANEL_DB_ROOT_PASSWORD"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "number",
|
"type": "number",
|
||||||
|
|
@ -46,7 +14,7 @@
|
||||||
"labelEn": "Port",
|
"labelEn": "Port",
|
||||||
"required": true,
|
"required": true,
|
||||||
"default": 3306,
|
"default": 3306,
|
||||||
"envKey": "PORT"
|
"envKey": "PANEL_APP_PORT"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -7,14 +7,11 @@ services:
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
TZ: ${TZ}
|
TZ: ${TZ}
|
||||||
MYSQL_DATABASE: ${DATABASE}
|
MYSQL_ROOT_PASSWORD: ${PANEL_DB_ROOT_PASSWORD}
|
||||||
MYSQL_USER: ${USER}
|
|
||||||
MYSQL_PASSWORD: ${PASSWORD}
|
|
||||||
MYSQL_ROOT_PASSWORD: ${ROOT_PASSWORD}
|
|
||||||
networks:
|
networks:
|
||||||
- 1panel
|
- 1panel
|
||||||
ports:
|
ports:
|
||||||
- ${PORT}:3306
|
- ${PANEL_APP_PORT}:3306
|
||||||
volumes:
|
volumes:
|
||||||
- ./data/:/var/lib/mysql
|
- ./data/:/var/lib/mysql
|
||||||
- ./conf/my.cnf:/etc/my.cnf
|
- ./conf/my.cnf:/etc/my.cnf
|
||||||
|
|
|
||||||
|
|
@ -1,44 +1,12 @@
|
||||||
{
|
{
|
||||||
"formFields": [
|
"formFields": [
|
||||||
{
|
|
||||||
"type": "text",
|
|
||||||
"labelZh": "时区",
|
|
||||||
"labelEn": "TimeZone",
|
|
||||||
"required": true,
|
|
||||||
"default": "Asia/Shanghai",
|
|
||||||
"envKey": "TZ"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "text",
|
|
||||||
"labelZh": "数据库",
|
|
||||||
"labelEn": "Database",
|
|
||||||
"required": true,
|
|
||||||
"default": "db",
|
|
||||||
"envKey": "DATABASE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "text",
|
|
||||||
"labelZh": "普通用户",
|
|
||||||
"labelEn": "User",
|
|
||||||
"required": true,
|
|
||||||
"default": "mysql",
|
|
||||||
"envKey": "USER"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "text",
|
|
||||||
"labelZh": "普通用户密码",
|
|
||||||
"labelEn": "Password",
|
|
||||||
"required": true,
|
|
||||||
"default": "1qaz@WSX",
|
|
||||||
"envKey": "PASSWORD"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"labelZh": "Root用户密码",
|
"labelZh": "Root用户密码",
|
||||||
"labelEn": "RootPassword",
|
"labelEn": "RootPassword",
|
||||||
"required": true,
|
"required": true,
|
||||||
"default": "1panel@mysql",
|
"default": "1panel@mysql",
|
||||||
"envKey": "ROOT_PASSWORD"
|
"envKey": "PANEL_DB_ROOT_PASSWORD"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "number",
|
"type": "number",
|
||||||
|
|
@ -46,7 +14,7 @@
|
||||||
"labelEn": "Port",
|
"labelEn": "Port",
|
||||||
"required": true,
|
"required": true,
|
||||||
"default": 3306,
|
"default": 3306,
|
||||||
"envKey": "PORT"
|
"envKey": "PANEL_APP_PORT"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -4,10 +4,10 @@ services:
|
||||||
image: nginx:1.23.1
|
image: nginx:1.23.1
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- ${PORT}:80
|
- ${PANEL_APP_PORT}:80
|
||||||
volumes:
|
volumes:
|
||||||
- ./conf/nginx.conf:/etc/nginx/nginx.conf
|
- ./conf/nginx.conf:/etc/nginx/nginx.conf
|
||||||
- ./www:/home/www
|
- ./www:/home/www
|
||||||
- ./log:/var/log/nginx
|
- ./log:/var/log/nginx
|
||||||
- ./conf/conf.d/default.conf:/etc/nginx/conf.d/default.conf
|
- ./conf/conf.d:/etc/nginx/conf.d/
|
||||||
- ./html:/usr/share/nginx/html
|
- ./html:/usr/share/nginx/html
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
"labelEn": "Port",
|
"labelEn": "Port",
|
||||||
"required": true,
|
"required": true,
|
||||||
"default": 80,
|
"default": 80,
|
||||||
"envKey": "PORT"
|
"envKey": "PANEL_APP_PORT"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -2,19 +2,19 @@ version: '3'
|
||||||
services:
|
services:
|
||||||
1panel_wordpress:
|
1panel_wordpress:
|
||||||
image: wordpress:6.0.1
|
image: wordpress:6.0.1
|
||||||
container_name: 1panel_wordpress
|
container_name: ${CONTAINER_NAME}
|
||||||
ports:
|
ports:
|
||||||
- ${PORT}:80
|
- ${PANEL_APP_PORT}:80
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
- 1panel
|
- 1panel
|
||||||
volumes:
|
volumes:
|
||||||
- ./data:/var/www/html
|
- ./data:/var/www/html
|
||||||
environment:
|
environment:
|
||||||
WORDPRESS_DB_HOST: ${WORDPRESS_DB_HOST}
|
WORDPRESS_DB_HOST: ${PANEL_DB_HOST}
|
||||||
WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME}
|
WORDPRESS_DB_NAME: ${PANEL_DB_NAME}
|
||||||
WORDPRESS_DB_USER: ${WORDPRESS_DB_USER}
|
WORDPRESS_DB_USER: ${PANEL_DB_USER}
|
||||||
WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD}
|
WORDPRESS_DB_PASSWORD: ${PANEL_DB_USER_PASSWORD}
|
||||||
WORDPRESS_DEBUG: 1
|
WORDPRESS_DEBUG: 1
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
|
|
|
||||||
|
|
@ -6,32 +6,32 @@
|
||||||
"labelZh": "数据库服务",
|
"labelZh": "数据库服务",
|
||||||
"labelEn": "Database Service",
|
"labelEn": "Database Service",
|
||||||
"required": true,
|
"required": true,
|
||||||
"default": "1Panel-mysql",
|
"default": "",
|
||||||
"envKey": "WORDPRESS_DB_HOST"
|
"envKey": "PANEL_DB_HOST"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"labelZh": "数据库名",
|
"labelZh": "数据库名",
|
||||||
"labelEn": "Database",
|
"labelEn": "Database",
|
||||||
"required": true,
|
"required": true,
|
||||||
"default": "db",
|
"default": "random",
|
||||||
"envKey": "WORDPRESS_DB_NAME"
|
"envKey": "PANEL_DB_NAME"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"labelZh": "数据库用户",
|
"labelZh": "数据库用户",
|
||||||
"labelEn": "User",
|
"labelEn": "User",
|
||||||
"required": true,
|
"required": true,
|
||||||
"default": "wordpress_user",
|
"default": "random",
|
||||||
"envKey": "WORDPRESS_DB_USER"
|
"envKey": "PANEL_DB_USER"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"labelZh": "数据库用户密码",
|
"labelZh": "数据库用户密码",
|
||||||
"labelEn": "Password",
|
"labelEn": "Password",
|
||||||
"required": true,
|
"required": true,
|
||||||
"default": "1qaz@WSX",
|
"default": "random",
|
||||||
"envKey": "WORDPRESS_DB_PASSWORD"
|
"envKey": "PANEL_DB_USER_PASSWORD"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "number",
|
"type": "number",
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
"labelEn": "Port",
|
"labelEn": "Port",
|
||||||
"required": true,
|
"required": true,
|
||||||
"default": 8080,
|
"default": 8080,
|
||||||
"envKey": "PORT"
|
"envKey": "PANEL_APP_PORT"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -111,3 +111,20 @@ type AppService struct {
|
||||||
Label string `json:"label"`
|
Label string `json:"label"`
|
||||||
Value string `json:"value"`
|
Value string `json:"value"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AppDatabase struct {
|
||||||
|
ServiceName string `json:"PANEL_DB_HOST"`
|
||||||
|
DbName string `json:"PANEL_DB_NAME"`
|
||||||
|
DbUser string `json:"PANEL_DB_USER"`
|
||||||
|
Password string `json:"PANEL_DB_USER_PASSWORD"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuthParam struct {
|
||||||
|
RootPassword string `json:"PANEL_DB_ROOT_PASSWORD"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ContainerExec struct {
|
||||||
|
ContainerName string `json:"containerName"`
|
||||||
|
DbParam AppDatabase `json:"dbParam"`
|
||||||
|
Auth AuthParam `json:"auth"`
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ type AppContainer struct {
|
||||||
BaseModel
|
BaseModel
|
||||||
ServiceName string `json:"serviceName" gorm:"type:varchar(64);not null"`
|
ServiceName string `json:"serviceName" gorm:"type:varchar(64);not null"`
|
||||||
ContainerName string `json:"containerName" gorm:"type:varchar(64);not null"`
|
ContainerName string `json:"containerName" gorm:"type:varchar(64);not null"`
|
||||||
AppInstallId uint `json:"appInstallId" gorm:"type:integer;not null"`
|
AppInstallID uint `json:"appInstallId" gorm:"type:integer;not null"`
|
||||||
Port int `json:"port" gorm:"type:integer;not null"`
|
Port int `json:"port" gorm:"type:integer;not null"`
|
||||||
|
Auth string `json:"auth" gorm:"type:longtext;not null"`
|
||||||
|
AppInstall AppInstall `gorm:"-"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ func (i *AppInstall) GetComposePath() string {
|
||||||
|
|
||||||
func (i *AppInstall) BeforeDelete(tx *gorm.DB) (err error) {
|
func (i *AppInstall) BeforeDelete(tx *gorm.DB) (err error) {
|
||||||
|
|
||||||
if err = tx.Where("app_install_id = ?", i.ID).Delete(&AppContainer{}).Error; err != nil {
|
if err = tx.Model(AppContainer{}).Debug().Where("app_install_id = ?", i.ID).Delete(AppContainer{}).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
10
backend/app/model/database.go
Normal file
10
backend/app/model/database.go
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
type Database struct {
|
||||||
|
BaseModel
|
||||||
|
AppContainerId uint `json:"appContainerId" gorm:"type:integer;not null"`
|
||||||
|
Key string `json:"key" gorm:"type:varchar(64);not null"`
|
||||||
|
Dbname string `json:"dbname" gorm:"type:varchar(256);not null"`
|
||||||
|
Username string `json:"username" gorm:"type:varchar(256);not null"`
|
||||||
|
Password string `json:"password" gorm:"type:varchar(256);not null"`
|
||||||
|
}
|
||||||
|
|
@ -35,7 +35,7 @@ func (a AppRepo) GetFirst(opts ...DBOption) (model.App, error) {
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
db = opt(db)
|
db = opt(db)
|
||||||
}
|
}
|
||||||
if err := db.First(&app).Error; err != nil {
|
if err := db.Preload("AppTags").First(&app).Error; err != nil {
|
||||||
return app, err
|
return app, err
|
||||||
}
|
}
|
||||||
return app, nil
|
return app, nil
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,12 @@ func (a AppContainerRepo) WithAppId(appId uint) DBOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a AppContainerRepo) WithServiceName(serviceName string) DBOption {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Where("service_name = ?", serviceName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (a AppContainerRepo) GetBy(opts ...DBOption) ([]model.AppContainer, error) {
|
func (a AppContainerRepo) GetBy(opts ...DBOption) ([]model.AppContainer, error) {
|
||||||
db := global.DB.Model(&model.AppContainer{})
|
db := global.DB.Model(&model.AppContainer{})
|
||||||
var appContainers []model.AppContainer
|
var appContainers []model.AppContainer
|
||||||
|
|
@ -26,6 +32,16 @@ func (a AppContainerRepo) GetBy(opts ...DBOption) ([]model.AppContainer, error)
|
||||||
return appContainers, err
|
return appContainers, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a AppContainerRepo) GetFirst(opts ...DBOption) (model.AppContainer, error) {
|
||||||
|
db := global.DB.Model(&model.AppContainer{})
|
||||||
|
var appContainer model.AppContainer
|
||||||
|
for _, opt := range opts {
|
||||||
|
db = opt(db)
|
||||||
|
}
|
||||||
|
err := db.Find(&appContainer).Error
|
||||||
|
return appContainer, err
|
||||||
|
}
|
||||||
|
|
||||||
func (a AppContainerRepo) Create(container *model.AppContainer) error {
|
func (a AppContainerRepo) Create(container *model.AppContainer) error {
|
||||||
db := global.DB.Model(&model.AppContainer{})
|
db := global.DB.Model(&model.AppContainer{})
|
||||||
return db.Create(&container).Error
|
return db.Create(&container).Error
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package repo
|
package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"github.com/1Panel-dev/1Panel/app/model"
|
"github.com/1Panel-dev/1Panel/app/model"
|
||||||
"github.com/1Panel-dev/1Panel/global"
|
"github.com/1Panel-dev/1Panel/global"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
|
@ -44,8 +45,8 @@ func (a AppInstallRepo) GetFirst(opts ...DBOption) (model.AppInstall, error) {
|
||||||
return install, err
|
return install, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppInstallRepo) Create(install *model.AppInstall) error {
|
func (a AppInstallRepo) Create(ctx context.Context, install *model.AppInstall) error {
|
||||||
db := global.DB.Model(&model.AppInstall{})
|
db := ctx.Value("db").(*gorm.DB).Model(&model.AppInstall{})
|
||||||
return db.Create(&install).Error
|
return db.Create(&install).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,7 +55,7 @@ func (a AppInstallRepo) Save(install model.AppInstall) error {
|
||||||
return db.Save(&install).Error
|
return db.Save(&install).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppInstallRepo) Delete(opts ...DBOption) error {
|
func (a AppInstallRepo) DeleteBy(opts ...DBOption) error {
|
||||||
db := global.DB.Model(&model.AppInstall{})
|
db := global.DB.Model(&model.AppInstall{})
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
db = opt(db)
|
db = opt(db)
|
||||||
|
|
@ -62,6 +63,11 @@ func (a AppInstallRepo) Delete(opts ...DBOption) error {
|
||||||
return db.Delete(&model.AppInstall{}).Error
|
return db.Delete(&model.AppInstall{}).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a AppInstallRepo) Delete(install model.AppInstall) error {
|
||||||
|
db := global.DB
|
||||||
|
return db.Delete(&install).Error
|
||||||
|
}
|
||||||
|
|
||||||
func (a AppInstallRepo) Page(page, size int, opts ...DBOption) (int64, []model.AppInstall, error) {
|
func (a AppInstallRepo) Page(page, size int, opts ...DBOption) (int64, []model.AppInstall, error) {
|
||||||
var apps []model.AppInstall
|
var apps []model.AppInstall
|
||||||
db := global.DB.Model(&model.AppInstall{})
|
db := global.DB.Model(&model.AppInstall{})
|
||||||
|
|
|
||||||
47
backend/app/repo/database.go
Normal file
47
backend/app/repo/database.go
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
package repo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/1Panel-dev/1Panel/app/model"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DatabaseRepo struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d DatabaseRepo) Create(ctx context.Context, database *model.Database) error {
|
||||||
|
db := ctx.Value("db").(*gorm.DB).Model(&model.Database{})
|
||||||
|
return db.Create(&database).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
//func (a DatabaseRepo) BatchCreate(ctx context.Context, tags []*model.AppTag) error {
|
||||||
|
// db := ctx.Value("db").(*gorm.DB)
|
||||||
|
// return db.Create(&tags).Error
|
||||||
|
//}
|
||||||
|
|
||||||
|
//func (d DatabaseRepo) DeleteBy(ctx context.Context, appIds []uint) error {
|
||||||
|
// db := ctx.Value("db").(*gorm.DB)
|
||||||
|
// return db.Where("app_id in (?)", appIds).Delete(&model.AppTag{}).Error
|
||||||
|
//}
|
||||||
|
|
||||||
|
//
|
||||||
|
//func (a AppTagRepo) DeleteAll(ctx context.Context) error {
|
||||||
|
// db := ctx.Value("db").(*gorm.DB)
|
||||||
|
// return db.Where("1 = 1").Delete(&model.AppTag{}).Error
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func (a AppTagRepo) GetByAppId(appId uint) ([]model.AppTag, error) {
|
||||||
|
// var appTags []model.AppTag
|
||||||
|
// if err := global.DB.Where("app_id = ?", appId).Find(&appTags).Error; err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// return appTags, nil
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func (a AppTagRepo) GetByTagIds(tagIds []uint) ([]model.AppTag, error) {
|
||||||
|
// var appTags []model.AppTag
|
||||||
|
// if err := global.DB.Where("tag_id in (?)", tagIds).Find(&appTags).Error; err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// return appTags, nil
|
||||||
|
//}
|
||||||
|
|
@ -15,6 +15,7 @@ type RepoGroup struct {
|
||||||
AppDetailRepo
|
AppDetailRepo
|
||||||
AppInstallRepo
|
AppInstallRepo
|
||||||
AppContainerRepo
|
AppContainerRepo
|
||||||
|
DatabaseRepo
|
||||||
}
|
}
|
||||||
|
|
||||||
var RepoGroupApp = new(RepoGroup)
|
var RepoGroupApp = new(RepoGroup)
|
||||||
|
|
|
||||||
|
|
@ -43,3 +43,11 @@ func (t TagRepo) GetByKeys(keys []string) ([]model.Tag, error) {
|
||||||
}
|
}
|
||||||
return tags, nil
|
return tags, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t TagRepo) GetByAppId(appId uint) ([]model.Tag, error) {
|
||||||
|
var tags []model.Tag
|
||||||
|
if err := global.DB.Where("id in (select tag_id from app_tags where app_id = ?)", appId).Find(&tags).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return tags, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/1Panel-dev/1Panel/app/repo"
|
"github.com/1Panel-dev/1Panel/app/repo"
|
||||||
"github.com/1Panel-dev/1Panel/constant"
|
"github.com/1Panel-dev/1Panel/constant"
|
||||||
"github.com/1Panel-dev/1Panel/global"
|
"github.com/1Panel-dev/1Panel/global"
|
||||||
|
"github.com/1Panel-dev/1Panel/utils/cmd"
|
||||||
"github.com/1Panel-dev/1Panel/utils/common"
|
"github.com/1Panel-dev/1Panel/utils/common"
|
||||||
"github.com/1Panel-dev/1Panel/utils/compose"
|
"github.com/1Panel-dev/1Panel/utils/compose"
|
||||||
"github.com/1Panel-dev/1Panel/utils/docker"
|
"github.com/1Panel-dev/1Panel/utils/docker"
|
||||||
|
|
@ -19,6 +20,7 @@ import (
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
@ -179,7 +181,7 @@ func (a AppService) Operate(req dto.AppInstallOperate) error {
|
||||||
appDir := install.GetPath()
|
appDir := install.GetPath()
|
||||||
dir, _ := os.Stat(appDir)
|
dir, _ := os.Stat(appDir)
|
||||||
if dir == nil {
|
if dir == nil {
|
||||||
return appInstallRepo.Delete(commonRepo.WithByID(install.ID))
|
return appInstallRepo.Delete(install)
|
||||||
}
|
}
|
||||||
out, err := compose.Down(dockerComposePath)
|
out, err := compose.Down(dockerComposePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -188,7 +190,7 @@ func (a AppService) Operate(req dto.AppInstallOperate) error {
|
||||||
if err := op.DeleteDir(appDir); err != nil {
|
if err := op.DeleteDir(appDir); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return appInstallRepo.Delete(commonRepo.WithByID(install.ID))
|
return appInstallRepo.Delete(install)
|
||||||
case dto.Sync:
|
case dto.Sync:
|
||||||
if err := a.SyncInstalled(install.ID); err != nil {
|
if err := a.SyncInstalled(install.ID); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -214,7 +216,7 @@ func handleErr(install model.AppInstall, err error, out string) error {
|
||||||
|
|
||||||
func (a AppService) Install(name string, appDetailId uint, params map[string]interface{}) error {
|
func (a AppService) Install(name string, appDetailId uint, params map[string]interface{}) error {
|
||||||
|
|
||||||
port, ok := params["PORT"]
|
port, ok := params["PANEL_APP_PORT"]
|
||||||
if ok {
|
if ok {
|
||||||
portStr := strconv.FormatFloat(port.(float64), 'f', -1, 32)
|
portStr := strconv.FormatFloat(port.(float64), 'f', -1, 32)
|
||||||
if common.ScanPort(portStr) {
|
if common.ScanPort(portStr) {
|
||||||
|
|
@ -230,6 +232,7 @@ func (a AppService) Install(name string, appDetailId uint, params map[string]int
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if app.Required != "" {
|
if app.Required != "" {
|
||||||
var requiredArray []string
|
var requiredArray []string
|
||||||
if err := json.Unmarshal([]byte(app.Required), &requiredArray); err != nil {
|
if err := json.Unmarshal([]byte(app.Required), &requiredArray); err != nil {
|
||||||
|
|
@ -301,6 +304,41 @@ func (a AppService) Install(name string, appDetailId uint, params map[string]int
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
auth string
|
||||||
|
dbConfig dto.AppDatabase
|
||||||
|
)
|
||||||
|
tags, err := tagRepo.GetByAppId(app.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, tag := range tags {
|
||||||
|
if tag.Key == "Database" {
|
||||||
|
var authParam dto.AuthParam
|
||||||
|
paramByte, err := json.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(paramByte, &authParam); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
authByte, err := json.Marshal(authParam)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
auth = string(authByte)
|
||||||
|
}
|
||||||
|
if tag.Key == "WebSite" {
|
||||||
|
paramByte, err := json.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(paramByte, &dbConfig); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
composeMap := make(map[string]interface{})
|
composeMap := make(map[string]interface{})
|
||||||
if err := yaml.Unmarshal([]byte(appDetail.DockerCompose), &composeMap); err != nil {
|
if err := yaml.Unmarshal([]byte(appDetail.DockerCompose), &composeMap); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -335,6 +373,7 @@ func (a AppService) Install(name string, appDetailId uint, params map[string]int
|
||||||
ServiceName: serviceName,
|
ServiceName: serviceName,
|
||||||
ContainerName: containerName,
|
ContainerName: containerName,
|
||||||
Port: servicePort,
|
Port: servicePort,
|
||||||
|
Auth: auth,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
for k, v := range changeKeys {
|
for k, v := range changeKeys {
|
||||||
|
|
@ -349,35 +388,64 @@ func (a AppService) Install(name string, appDetailId uint, params map[string]int
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := appInstallRepo.Create(&appInstall); err != nil {
|
tx := global.DB.Begin()
|
||||||
|
ctx := context.WithValue(context.Background(), "db", tx)
|
||||||
|
|
||||||
|
if err := appInstallRepo.Create(ctx, &appInstall); err != nil {
|
||||||
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, c := range appContainers {
|
for _, c := range appContainers {
|
||||||
c.AppInstallId = appInstall.ID
|
c.AppInstallID = appInstall.ID
|
||||||
}
|
}
|
||||||
if err := appContainerRepo.BatchCreate(context.WithValue(context.Background(), "db", global.DB), appContainers); err != nil {
|
if err := appContainerRepo.BatchCreate(ctx, appContainers); err != nil {
|
||||||
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if !reflect.DeepEqual(dbConfig, dto.AppDatabase{}) {
|
||||||
|
container, err := appContainerRepo.GetFirst(appContainerRepo.WithServiceName(dbConfig.ServiceName))
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
install, err := appInstallRepo.GetFirst(commonRepo.WithByID(container.AppInstallID))
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
app, err := appRepo.GetFirst(commonRepo.WithByID(install.ID))
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var database model.Database
|
||||||
|
database.AppContainerId = container.ID
|
||||||
|
database.Dbname = dbConfig.DbName
|
||||||
|
database.Username = dbConfig.DbUser
|
||||||
|
database.Password = dbConfig.Password
|
||||||
|
if err := dataBaseRepo.Create(ctx, &database); err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var auth dto.AuthParam
|
||||||
|
json.Unmarshal([]byte(container.Auth), &auth)
|
||||||
|
execConfig := dto.ContainerExec{
|
||||||
|
ContainerName: container.ContainerName,
|
||||||
|
Auth: auth,
|
||||||
|
DbParam: dbConfig,
|
||||||
|
}
|
||||||
|
_, err = cmd.Exec(getSqlStr(app.Key, execConfig))
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tx.Commit()
|
||||||
go upApp(composeFilePath, appInstall)
|
go upApp(composeFilePath, appInstall)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func upApp(composeFilePath string, appInstall model.AppInstall) {
|
|
||||||
out, err := compose.Up(composeFilePath)
|
|
||||||
if err != nil {
|
|
||||||
if out != "" {
|
|
||||||
appInstall.Message = out
|
|
||||||
} else {
|
|
||||||
appInstall.Message = err.Error()
|
|
||||||
}
|
|
||||||
appInstall.Status = constant.Error
|
|
||||||
_ = appInstallRepo.Save(appInstall)
|
|
||||||
} else {
|
|
||||||
appInstall.Status = constant.Running
|
|
||||||
_ = appInstallRepo.Save(appInstall)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a AppService) SyncAllInstalled() error {
|
func (a AppService) SyncAllInstalled() error {
|
||||||
allList, err := appInstallRepo.GetBy()
|
allList, err := appInstallRepo.GetBy()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -405,13 +473,9 @@ func (a AppService) GetServices(key string) ([]dto.AppService, error) {
|
||||||
var res []dto.AppService
|
var res []dto.AppService
|
||||||
for _, install := range installs {
|
for _, install := range installs {
|
||||||
for _, container := range install.Containers {
|
for _, container := range install.Containers {
|
||||||
value := container.ServiceName
|
|
||||||
if container.Port > 0 {
|
|
||||||
value = value + ":" + string(rune(container.Port))
|
|
||||||
}
|
|
||||||
res = append(res, dto.AppService{
|
res = append(res, dto.AppService{
|
||||||
Label: install.Name,
|
Label: install.Name,
|
||||||
Value: value,
|
Value: container.ServiceName,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -505,53 +569,6 @@ func (a AppService) SyncInstalled(installId uint) error {
|
||||||
return appInstallRepo.Save(appInstall)
|
return appInstallRepo.Save(appInstall)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getApps(oldApps []model.App, items []dto.AppDefine) map[string]model.App {
|
|
||||||
apps := make(map[string]model.App, len(oldApps))
|
|
||||||
for _, old := range oldApps {
|
|
||||||
old.Status = constant.AppTakeDown
|
|
||||||
apps[old.Key] = old
|
|
||||||
}
|
|
||||||
for _, item := range items {
|
|
||||||
app, ok := apps[item.Key]
|
|
||||||
if !ok {
|
|
||||||
app = model.App{}
|
|
||||||
}
|
|
||||||
app.Name = item.Name
|
|
||||||
app.Key = item.Key
|
|
||||||
app.ShortDesc = item.ShortDesc
|
|
||||||
app.Author = item.Author
|
|
||||||
app.Source = item.Source
|
|
||||||
app.Type = item.Type
|
|
||||||
app.CrossVersionUpdate = item.CrossVersionUpdate
|
|
||||||
app.Required = item.GetRequired()
|
|
||||||
app.Status = constant.AppNormal
|
|
||||||
apps[item.Key] = app
|
|
||||||
}
|
|
||||||
return apps
|
|
||||||
}
|
|
||||||
|
|
||||||
func getAppDetails(details []model.AppDetail, versions []string) map[string]model.AppDetail {
|
|
||||||
appDetails := make(map[string]model.AppDetail, len(details))
|
|
||||||
for _, old := range details {
|
|
||||||
old.Status = constant.AppTakeDown
|
|
||||||
appDetails[old.Version] = old
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range versions {
|
|
||||||
detail, ok := appDetails[v]
|
|
||||||
if ok {
|
|
||||||
detail.Status = constant.AppNormal
|
|
||||||
appDetails[v] = detail
|
|
||||||
} else {
|
|
||||||
appDetails[v] = model.AppDetail{
|
|
||||||
Version: v,
|
|
||||||
Status: constant.AppNormal,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return appDetails
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a AppService) SyncAppList() error {
|
func (a AppService) SyncAppList() error {
|
||||||
//TODO 从 oss 拉取最新列表
|
//TODO 从 oss 拉取最新列表
|
||||||
|
|
||||||
|
|
@ -770,3 +787,78 @@ func syncCanUpdate() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getApps(oldApps []model.App, items []dto.AppDefine) map[string]model.App {
|
||||||
|
apps := make(map[string]model.App, len(oldApps))
|
||||||
|
for _, old := range oldApps {
|
||||||
|
old.Status = constant.AppTakeDown
|
||||||
|
apps[old.Key] = old
|
||||||
|
}
|
||||||
|
for _, item := range items {
|
||||||
|
app, ok := apps[item.Key]
|
||||||
|
if !ok {
|
||||||
|
app = model.App{}
|
||||||
|
}
|
||||||
|
app.Name = item.Name
|
||||||
|
app.Key = item.Key
|
||||||
|
app.ShortDesc = item.ShortDesc
|
||||||
|
app.Author = item.Author
|
||||||
|
app.Source = item.Source
|
||||||
|
app.Type = item.Type
|
||||||
|
app.CrossVersionUpdate = item.CrossVersionUpdate
|
||||||
|
app.Required = item.GetRequired()
|
||||||
|
app.Status = constant.AppNormal
|
||||||
|
apps[item.Key] = app
|
||||||
|
}
|
||||||
|
return apps
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAppDetails(details []model.AppDetail, versions []string) map[string]model.AppDetail {
|
||||||
|
appDetails := make(map[string]model.AppDetail, len(details))
|
||||||
|
for _, old := range details {
|
||||||
|
old.Status = constant.AppTakeDown
|
||||||
|
appDetails[old.Version] = old
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range versions {
|
||||||
|
detail, ok := appDetails[v]
|
||||||
|
if ok {
|
||||||
|
detail.Status = constant.AppNormal
|
||||||
|
appDetails[v] = detail
|
||||||
|
} else {
|
||||||
|
appDetails[v] = model.AppDetail{
|
||||||
|
Version: v,
|
||||||
|
Status: constant.AppNormal,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return appDetails
|
||||||
|
}
|
||||||
|
|
||||||
|
func upApp(composeFilePath string, appInstall model.AppInstall) {
|
||||||
|
out, err := compose.Up(composeFilePath)
|
||||||
|
if err != nil {
|
||||||
|
if out != "" {
|
||||||
|
appInstall.Message = out
|
||||||
|
} else {
|
||||||
|
appInstall.Message = err.Error()
|
||||||
|
}
|
||||||
|
appInstall.Status = constant.Error
|
||||||
|
_ = appInstallRepo.Save(appInstall)
|
||||||
|
} else {
|
||||||
|
appInstall.Status = constant.Running
|
||||||
|
_ = appInstallRepo.Save(appInstall)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSqlStr(key string, exec dto.ContainerExec) string {
|
||||||
|
var str string
|
||||||
|
param := exec.DbParam
|
||||||
|
switch key {
|
||||||
|
case "mysql":
|
||||||
|
str = fmt.Sprintf("docker exec -i %s mysql -uroot -p%s -e \"CREATE USER '%s'@'%%' IDENTIFIED BY '%s';\" -e \"create database %s;\" -e \"GRANT ALL ON %s.* TO '%s'@'%%';\"",
|
||||||
|
exec.ContainerName, exec.Auth.RootPassword, param.DbUser, param.Password, param.DbName, param.DbName, param.DbUser)
|
||||||
|
}
|
||||||
|
fmt.Println(str)
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,4 +32,5 @@ var (
|
||||||
tagRepo = repo.RepoGroupApp.TagRepo
|
tagRepo = repo.RepoGroupApp.TagRepo
|
||||||
appInstallRepo = repo.RepoGroupApp.AppInstallRepo
|
appInstallRepo = repo.RepoGroupApp.AppInstallRepo
|
||||||
appContainerRepo = repo.RepoGroupApp.AppContainerRepo
|
appContainerRepo = repo.RepoGroupApp.AppContainerRepo
|
||||||
|
dataBaseRepo = repo.RepoGroupApp.DatabaseRepo
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,6 @@ var AddTableCronjob = &gormigrate.Migration{
|
||||||
var AddTableApp = &gormigrate.Migration{
|
var AddTableApp = &gormigrate.Migration{
|
||||||
ID: "20200921-add-table-app",
|
ID: "20200921-add-table-app",
|
||||||
Migrate: func(tx *gorm.DB) error {
|
Migrate: func(tx *gorm.DB) error {
|
||||||
return tx.AutoMigrate(&model.App{}, &model.AppDetail{}, &model.Tag{}, &model.AppTag{}, &model.AppInstall{}, &model.AppContainer{}, &model.AppContainer{})
|
return tx.AutoMigrate(&model.App{}, &model.AppDetail{}, &model.Tag{}, &model.AppTag{}, &model.AppInstall{}, &model.AppContainer{}, &model.Database{})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
50
backend/utils/cmd/cmd.go
Normal file
50
backend/utils/cmd/cmd.go
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
"os/exec"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Exec(cmdStr string) (out string, err error) {
|
||||||
|
command := exec.CommandContext(context.Background(), "bash", "-c", cmdStr)
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
stdout, err := command.StdoutPipe()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
readout := bufio.NewReader(stdout)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
out = getOutput(readout)
|
||||||
|
}()
|
||||||
|
|
||||||
|
err = command.Run()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getOutput(reader *bufio.Reader) string {
|
||||||
|
var sumOutput string
|
||||||
|
outputBytes := make([]byte, 200)
|
||||||
|
for {
|
||||||
|
n, err := reader.Read(outputBytes)
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
sumOutput += err.Error()
|
||||||
|
}
|
||||||
|
output := string(outputBytes[:n])
|
||||||
|
sumOutput += output
|
||||||
|
}
|
||||||
|
return sumOutput
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
package docker
|
package docker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
|
|
@ -47,3 +49,30 @@ func (c Client) ListContainersByName(names []string) ([]types.Container, error)
|
||||||
}
|
}
|
||||||
return containers, nil
|
return containers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c Client) ExecCommand(context context.Context, name string, command []string) {
|
||||||
|
execConfig := types.ExecConfig{Tty: true, AttachStdout: true, AttachStderr: false, Cmd: command}
|
||||||
|
respIdExecCreate, err := c.cli.ContainerExecCreate(context, name, execConfig)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
respId, err := c.cli.ContainerExecAttach(context, respIdExecCreate.ID, types.ExecStartCheck{})
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
//text, _ := respId.Reader.ReadString('\n')
|
||||||
|
//fmt.Printf("%s\n", text)
|
||||||
|
scanner := bufio.NewScanner(respId.Reader)
|
||||||
|
//text, _ := resp.Reader.ReadString('\n')
|
||||||
|
//log.Print(text)
|
||||||
|
for scanner.Scan() {
|
||||||
|
fmt.Println(scanner.Text())
|
||||||
|
}
|
||||||
|
//
|
||||||
|
//respId, err := c.cli.ContainerExecAttach(context, respIdExecCreate.ID, types.ExecStartCheck{})
|
||||||
|
//if err != nil {
|
||||||
|
// fmt.Println(err)
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="open" :title="$t('app.install')" width="40%">
|
<el-dialog v-model="open" :title="$t('app.install')" width="40%" :before-close="handleClose" @opened="opened">
|
||||||
<el-form ref="paramForm" label-position="left" :model="form" label-width="150px" :rules="rules">
|
<el-form ref="paramForm" label-position="left" :model="form" label-width="150px" :rules="rules">
|
||||||
<el-form-item :label="$t('app.name')" prop="NAME">
|
<el-form-item :label="$t('app.name')" prop="NAME">
|
||||||
<el-input v-model="form['NAME']"></el-input>
|
<el-input v-model="form['NAME']"></el-input>
|
||||||
|
|
@ -40,8 +40,9 @@
|
||||||
import { App } from '@/api/interface/app';
|
import { App } from '@/api/interface/app';
|
||||||
import { InstallApp, GetAppService } from '@/api/modules/app';
|
import { InstallApp, GetAppService } from '@/api/modules/app';
|
||||||
import { Rules } from '@/global/form-rules';
|
import { Rules } from '@/global/form-rules';
|
||||||
|
import { getRandomStr } from '@/utils/util';
|
||||||
import { FormInstance, FormRules } from 'element-plus';
|
import { FormInstance, FormRules } from 'element-plus';
|
||||||
import { reactive, ref } from 'vue';
|
import { nextTick, reactive, ref } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
|
@ -68,10 +69,22 @@ const req = reactive({
|
||||||
let services = ref();
|
let services = ref();
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
|
open.value = false;
|
||||||
|
resetForm();
|
||||||
|
};
|
||||||
|
|
||||||
|
const opened = () => {
|
||||||
|
nextTick(() => {
|
||||||
|
if (paramForm.value) {
|
||||||
|
paramForm.value.clearValidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetForm = () => {
|
||||||
if (paramForm.value) {
|
if (paramForm.value) {
|
||||||
paramForm.value.resetFields();
|
paramForm.value.resetFields();
|
||||||
}
|
}
|
||||||
open.value = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const acceptParams = (props: InstallRrops): void => {
|
const acceptParams = (props: InstallRrops): void => {
|
||||||
|
|
@ -79,24 +92,28 @@ const acceptParams = (props: InstallRrops): void => {
|
||||||
const params = installData.value.params;
|
const params = installData.value.params;
|
||||||
if (params?.formFields != undefined) {
|
if (params?.formFields != undefined) {
|
||||||
for (const p of params?.formFields) {
|
for (const p of params?.formFields) {
|
||||||
|
if (p.default == 'random') {
|
||||||
|
form[p.envKey] = getRandomStr(6);
|
||||||
|
} else {
|
||||||
form[p.envKey] = p.default;
|
form[p.envKey] = p.default;
|
||||||
|
}
|
||||||
if (p.required) {
|
if (p.required) {
|
||||||
rules[p.envKey] = [Rules.requiredInput];
|
rules[p.envKey] = [Rules.requiredInput];
|
||||||
}
|
}
|
||||||
if (p.key) {
|
if (p.key) {
|
||||||
form[p.envKey] = '';
|
form[p.envKey] = '';
|
||||||
getServices(form[p.envKey], p.key);
|
getServices(p.envKey, p.key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
open.value = true;
|
open.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getServices = (value: any, key: string | undefined) => {
|
const getServices = async (envKey: string, key: string | undefined) => {
|
||||||
GetAppService(key).then((res) => {
|
await GetAppService(key).then((res) => {
|
||||||
services.value = res.data;
|
services.value = res.data;
|
||||||
if (services.value != null) {
|
if (services.value != null) {
|
||||||
value = services.value[0].value;
|
form[envKey] = services.value[0].value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue