mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-10-09 08:00:27 +00:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d548c7df9 | ||
|
|
8ec5a5bd4b | ||
|
|
2e8bcc09e6 | ||
|
|
29a304e2c8 | ||
|
|
b1adc37920 | ||
|
|
03fac3ec06 |
@@ -76,7 +76,7 @@ func (b *BaseApi) CheckRepoStatus(c *gin.Context) {
|
||||
// @Tags Container Image-repo
|
||||
// @Summary Create image repo
|
||||
// @Accept json
|
||||
// @Param request body dto.ImageRepoDelete true "request"
|
||||
// @Param request body dto.ImageRepoCreate true "request"
|
||||
// @Produce json
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
@@ -99,20 +99,20 @@ func (b *BaseApi) CreateRepo(c *gin.Context) {
|
||||
// @Tags Container Image-repo
|
||||
// @Summary Delete image repo
|
||||
// @Accept json
|
||||
// @Param request body dto.ImageRepoDelete true "request"
|
||||
// @Param request body dto.OperateByID true "request"
|
||||
// @Produce json
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /containers/repo/del [post]
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"image_repos","output_column":"name","output_value":"names"}],"formatZH":"删除镜像仓库 [names]","formatEN":"delete image repo [names]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"image_repos","output_column":"name","output_value":"name"}],"formatZH":"删除镜像仓库 [name]","formatEN":"delete image repo [name]"}
|
||||
func (b *BaseApi) DeleteRepo(c *gin.Context) {
|
||||
var req dto.ImageRepoDelete
|
||||
var req dto.OperateByID
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := imageRepoService.BatchDelete(req); err != nil {
|
||||
if err := imageRepoService.Delete(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -442,17 +442,14 @@ func deleteLink(ctx context.Context, install *model.AppInstall, deleteDB bool, f
|
||||
return appInstallResourceRepo.DeleteBy(ctx, appInstallResourceRepo.WithAppInstallId(install.ID))
|
||||
}
|
||||
|
||||
func getUpgradeCompose(install model.AppInstall, detail model.AppDetail) (string, error) {
|
||||
if detail.DockerCompose == "" {
|
||||
return "", nil
|
||||
}
|
||||
func handleUpgradeCompose(install model.AppInstall, detail model.AppDetail) (map[string]interface{}, error) {
|
||||
composeMap := make(map[string]interface{})
|
||||
if err := yaml.Unmarshal([]byte(detail.DockerCompose), &composeMap); err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
value, ok := composeMap["services"]
|
||||
if !ok || value == nil {
|
||||
return "", buserr.New(constant.ErrFileParse)
|
||||
return nil, buserr.New("ErrFileParse")
|
||||
}
|
||||
servicesMap := value.(map[string]interface{})
|
||||
if len(servicesMap) == 1 {
|
||||
@@ -470,6 +467,34 @@ func getUpgradeCompose(install model.AppInstall, detail model.AppDetail) (string
|
||||
delete(servicesMap, oldServiceName)
|
||||
}
|
||||
}
|
||||
serviceValue := servicesMap[install.ServiceName].(map[string]interface{})
|
||||
|
||||
oldComposeMap := make(map[string]interface{})
|
||||
if err := yaml.Unmarshal([]byte(install.DockerCompose), &oldComposeMap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
oldValue, ok := oldComposeMap["services"]
|
||||
if !ok || oldValue == nil {
|
||||
return nil, buserr.New("ErrFileParse")
|
||||
}
|
||||
oldValueMap := oldValue.(map[string]interface{})
|
||||
oldServiceValue := oldValueMap[install.ServiceName].(map[string]interface{})
|
||||
if oldServiceValue["deploy"] != nil {
|
||||
serviceValue["deploy"] = oldServiceValue["deploy"]
|
||||
}
|
||||
servicesMap[install.ServiceName] = serviceValue
|
||||
composeMap["services"] = servicesMap
|
||||
return composeMap, nil
|
||||
}
|
||||
|
||||
func getUpgradeCompose(install model.AppInstall, detail model.AppDetail) (string, error) {
|
||||
if detail.DockerCompose == "" {
|
||||
return "", nil
|
||||
}
|
||||
composeMap, err := handleUpgradeCompose(install, detail)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
envs := make(map[string]interface{})
|
||||
if err := json.Unmarshal([]byte(install.Env), &envs); err != nil {
|
||||
return "", err
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/systemctl"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -27,7 +26,7 @@ type IImageRepoService interface {
|
||||
Login(req dto.OperateByID) error
|
||||
Create(req dto.ImageRepoCreate) error
|
||||
Update(req dto.ImageRepoUpdate) error
|
||||
BatchDelete(req dto.ImageRepoDelete) error
|
||||
Delete(req dto.OperateByID) error
|
||||
}
|
||||
|
||||
func NewIImageRepoService() IImageRepoService {
|
||||
@@ -90,30 +89,7 @@ func (u *ImageRepoService) Create(req dto.ImageRepoCreate) error {
|
||||
if err := u.handleRegistries(req.DownloadUrl, "", "create"); err != nil {
|
||||
return fmt.Errorf("create registry %s failed, err: %v", req.DownloadUrl, err)
|
||||
}
|
||||
if err := validateDockerConfig(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := restartDocker(); err != nil {
|
||||
return err
|
||||
}
|
||||
ticker := time.NewTicker(3 * time.Second)
|
||||
defer ticker.Stop()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
|
||||
if err := func() error {
|
||||
for range ticker.C {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
cancel()
|
||||
return errors.New("the docker service cannot be restarted")
|
||||
default:
|
||||
if ok, _ := systemctl.IsActive("docker"); ok {
|
||||
global.LOG.Info("docker restart with new conf successful!")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}(); err != nil {
|
||||
if err := stopBeforeUpdateRepo(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -131,15 +107,32 @@ func (u *ImageRepoService) Create(req dto.ImageRepoCreate) error {
|
||||
return imageRepoRepo.Create(&imageRepo)
|
||||
}
|
||||
|
||||
func (u *ImageRepoService) BatchDelete(req dto.ImageRepoDelete) error {
|
||||
for _, id := range req.Ids {
|
||||
if id == 1 {
|
||||
return errors.New("The default value cannot be edit !")
|
||||
}
|
||||
func (u *ImageRepoService) Delete(req dto.OperateByID) error {
|
||||
if req.ID == 1 {
|
||||
return errors.New("The default value cannot be edit !")
|
||||
}
|
||||
if err := imageRepoRepo.Delete(commonRepo.WithIdsIn(req.Ids)); err != nil {
|
||||
itemRepo, _ := imageRepoRepo.Get(commonRepo.WithByID(req.ID))
|
||||
if itemRepo.ID == 0 {
|
||||
return buserr.New("ErrRecordNotFound")
|
||||
}
|
||||
if itemRepo.Auth {
|
||||
_, _ = cmd.Execf("docker logout -i %s", itemRepo.DownloadUrl)
|
||||
}
|
||||
if itemRepo.Protocol == "https" {
|
||||
return imageRepoRepo.Delete(commonRepo.WithByID(req.ID))
|
||||
}
|
||||
if err := u.handleRegistries("", itemRepo.DownloadUrl, "delete"); err != nil {
|
||||
return fmt.Errorf("delete registry %s failed, err: %v", itemRepo.DownloadUrl, err)
|
||||
}
|
||||
if err := validateDockerConfig(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := imageRepoRepo.Delete(commonRepo.WithByID(req.ID)); err != nil {
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
_ = restartDocker()
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -154,37 +147,39 @@ func (u *ImageRepoService) Update(req dto.ImageRepoUpdate) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
needRestart := false
|
||||
if repo.Protocol == "http" && req.Protocol == "https" {
|
||||
if err := u.handleRegistries("", repo.DownloadUrl, "delete"); err != nil {
|
||||
return fmt.Errorf("delete registry %s failed, err: %v", repo.DownloadUrl, err)
|
||||
}
|
||||
needRestart = true
|
||||
}
|
||||
if repo.Protocol == "http" && req.Protocol == "http" {
|
||||
if err := u.handleRegistries(req.DownloadUrl, repo.DownloadUrl, "update"); err != nil {
|
||||
return fmt.Errorf("update registry %s => %s failed, err: %v", repo.DownloadUrl, req.DownloadUrl, err)
|
||||
if repo.DownloadUrl != req.DownloadUrl {
|
||||
if err := u.handleRegistries(req.DownloadUrl, repo.DownloadUrl, "update"); err != nil {
|
||||
return fmt.Errorf("update registry %s => %s failed, err: %v", repo.DownloadUrl, req.DownloadUrl, err)
|
||||
}
|
||||
needRestart = true
|
||||
}
|
||||
}
|
||||
if repo.Protocol == "https" && req.Protocol == "http" {
|
||||
if err := u.handleRegistries(req.DownloadUrl, "", "create"); err != nil {
|
||||
return fmt.Errorf("create registry %s failed, err: %v", req.DownloadUrl, err)
|
||||
}
|
||||
needRestart = true
|
||||
}
|
||||
if repo.Auth != req.Auth || repo.DownloadUrl != req.DownloadUrl {
|
||||
if repo.Auth {
|
||||
_, _ = cmd.ExecWithCheck("docker", "logout", repo.DownloadUrl)
|
||||
}
|
||||
if req.Auth {
|
||||
if err := u.CheckConn(req.DownloadUrl, req.Username, req.Password); err != nil {
|
||||
return err
|
||||
}
|
||||
if needRestart {
|
||||
if err := stopBeforeUpdateRepo(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := validateDockerConfig(); err != nil {
|
||||
return err
|
||||
if repo.Auth {
|
||||
_, _ = cmd.Execf("docker logout -i %s", repo.DownloadUrl)
|
||||
}
|
||||
if err := restartDocker(); err != nil {
|
||||
return err
|
||||
if req.Auth {
|
||||
if err := u.CheckConn(req.DownloadUrl, req.Username, req.Password); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
upMap := make(map[string]interface{})
|
||||
@@ -256,3 +251,34 @@ func (u *ImageRepoService) handleRegistries(newHost, delHost, handle string) err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func stopBeforeUpdateRepo() error {
|
||||
if err := validateDockerConfig(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := restartDocker(); err != nil {
|
||||
return err
|
||||
}
|
||||
ticker := time.NewTicker(3 * time.Second)
|
||||
defer ticker.Stop()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
|
||||
if err := func() error {
|
||||
for range ticker.C {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
cancel()
|
||||
return errors.New("the docker service cannot be restarted")
|
||||
default:
|
||||
stdout, err := cmd.Exec("systemctl is-active docker")
|
||||
if string(stdout) == "active\n" && err == nil {
|
||||
global.LOG.Info("docker restart with new conf successful!")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -109,6 +109,8 @@ func Init() {
|
||||
|
||||
migrations.AddMcpServer,
|
||||
migrations.AddPbootCMSPHPExtensions,
|
||||
migrations.DeleteV2Openresty,
|
||||
migrations.UpdateOnedrive,
|
||||
})
|
||||
if err := m.Migrate(); err != nil {
|
||||
global.LOG.Error(err)
|
||||
|
||||
@@ -485,3 +485,27 @@ var AddPbootCMSPHPExtensions = &gormigrate.Migration{
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var DeleteV2Openresty = &gormigrate.Migration{
|
||||
ID: "20250701-delete-v2-openresty",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
return tx.Where("version = '1.27.1.2-0-1-focal'").Delete(&model.AppDetail{}).Error
|
||||
},
|
||||
}
|
||||
|
||||
var UpdateOnedrive = &gormigrate.Migration{
|
||||
ID: "20250704-update-onedrive",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
if err := tx.Model(&model.Setting{}).
|
||||
Where("key = ?", "OneDriveID").
|
||||
Update("value", "NTQ0NmNmZTMtNGM3OS00N2EwLWFlMjUtZmM2NDU0NzhlMmQ5").Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Model(&model.Setting{}).
|
||||
Where("key = ?", "OneDriveSc").
|
||||
Update("value", "bGRlOFF+WEVrR1M0b25Vb1VsRWpMYzE2MW9rTXZEM25KdnZ1MGN6MA==").Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
@@ -212,9 +212,6 @@ export namespace Container {
|
||||
password: string;
|
||||
auth: boolean;
|
||||
}
|
||||
export interface RepoDelete {
|
||||
ids: Array<number>;
|
||||
}
|
||||
export interface RepoInfo {
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
|
||||
@@ -135,8 +135,8 @@ export const createImageRepo = (params: Container.RepoCreate) => {
|
||||
export const updateImageRepo = (params: Container.RepoUpdate) => {
|
||||
return http.post(`/containers/repo/update`, params, TimeoutEnum.T_40S);
|
||||
};
|
||||
export const deleteImageRepo = (params: Container.RepoDelete) => {
|
||||
return http.post(`/containers/repo/del`, params, TimeoutEnum.T_40S);
|
||||
export const deleteImageRepo = (id: Number) => {
|
||||
return http.post(`/containers/repo/del`, { id: id }, TimeoutEnum.T_40S);
|
||||
};
|
||||
|
||||
// composeTemplate
|
||||
|
||||
@@ -333,6 +333,7 @@ const message = {
|
||||
ssl: 'Certificate | Certificates',
|
||||
database: 'Database | Databases',
|
||||
ai_tools: 'AI',
|
||||
mcp: 'MCP',
|
||||
container: 'Container | Containers',
|
||||
cronjob: 'Cron Job | Cron Jobs',
|
||||
host: 'Host | Hosts',
|
||||
@@ -833,7 +834,7 @@ const message = {
|
||||
|
||||
repo: 'Registries',
|
||||
createRepo: 'Add',
|
||||
createRepoHelper: 'Adding an HTTP-type repository requires restarting the Docker service.',
|
||||
httpRepoHelper: 'Operating an HTTP-type repository requires restarting the Docker service.',
|
||||
httpRepo: 'Choosing HTTP protocol requires restarting the Docker service to add it into insecure registries.',
|
||||
delInsecure: 'Deletion of credit',
|
||||
delInsecureHelper:
|
||||
|
||||
@@ -333,6 +333,7 @@ const message = {
|
||||
ssl: '証明書|証明書',
|
||||
database: 'データベース|データベース',
|
||||
ai_tools: 'AI',
|
||||
mcp: 'MCP',
|
||||
container: 'コンテナ|コンテナ',
|
||||
cronjob: 'クロンジョブ|クロンの仕事',
|
||||
host: 'ホスト|ホスト',
|
||||
@@ -829,7 +830,7 @@ const message = {
|
||||
|
||||
repo: 'レジストリ',
|
||||
createRepo: '追加',
|
||||
createRepoHelper: 'HTTPタイプのリポジトリを追加するにはDockerサービスの再起動が必要です。',
|
||||
httpRepoHelper: 'HTTPタイプのリポジトリを操作するにはDockerサービスの再起動が必要です。',
|
||||
httpRepo:
|
||||
'HTTPプロトコルを選択するには、Dockerサービスを再起動して不安定なレジストリに追加する必要があります。',
|
||||
delInsecure: 'クレジットの削除',
|
||||
|
||||
@@ -334,6 +334,7 @@ const message = {
|
||||
ssl: '인증서 | 인증서들',
|
||||
database: '데이터베이스 | 데이터베이스들',
|
||||
ai_tools: 'AI',
|
||||
mcp: 'MCP',
|
||||
container: '컨테이너 | 컨테이너들',
|
||||
cronjob: '크론 작업 | 크론 작업들',
|
||||
host: '호스트 | 호스트들',
|
||||
@@ -819,7 +820,7 @@ const message = {
|
||||
|
||||
repo: '레지스트리',
|
||||
createRepo: '추가',
|
||||
createRepoHelper: 'HTTP 타입 저장소 추가 시 Docker 서비스 재시작이 필요합니다.',
|
||||
httpRepoHelper: 'HTTP 타입 저장소 작업 시 Docker 서비스 재시작이 필요합니다.',
|
||||
httpRepo: 'HTTP 프로토콜을 선택하면 Docker 서비스를 재시작하여 불안정한 레지스트리에 추가해야 합니다.',
|
||||
delInsecure: '신뢰할 수 없는 항목 삭제',
|
||||
delInsecureHelper:
|
||||
|
||||
@@ -340,6 +340,7 @@ const message = {
|
||||
ssl: 'Certificate | Certificates',
|
||||
database: 'Database | Databases',
|
||||
ai_tools: 'AI',
|
||||
mcp: 'MCP',
|
||||
container: 'Container | Containers',
|
||||
cronjob: 'Cron Job | Cron Jobs',
|
||||
host: 'Host | Hosts',
|
||||
@@ -845,7 +846,7 @@ const message = {
|
||||
|
||||
repo: 'Pendaftaran',
|
||||
createRepo: 'Tambah',
|
||||
createRepoHelper: 'Menambah repositori jenis HTTP memerlukan mulakan semula perkhidmatan Docker.',
|
||||
httpRepoHelper: 'Mengoperasikan repositori jenis HTTP memerlukan mulakan semula perkhidmatan Docker.',
|
||||
httpRepo:
|
||||
'Memilih protokol HTTP memerlukan memulakan semula perkhidmatan Docker untuk menambahkannya ke pendaftaran tidak selamat.',
|
||||
delInsecure: 'Padamkan pendaftaran tidak selamat',
|
||||
|
||||
@@ -338,6 +338,7 @@ const message = {
|
||||
ssl: 'Certificado | Certificados',
|
||||
database: 'Banco de Dados | Bancos de Dados',
|
||||
ai_tools: 'AI',
|
||||
mcp: 'MCP',
|
||||
container: 'Container | Containers',
|
||||
cronjob: 'Tarefa Cron | Tarefas Cron',
|
||||
host: 'Host | Hosts',
|
||||
@@ -841,7 +842,7 @@ const message = {
|
||||
|
||||
repo: 'Registries',
|
||||
createRepo: 'Adicionar',
|
||||
createRepoHelper: 'Adicionar um repositório do tipo HTTP requer reinicialização do serviço Docker.',
|
||||
httpRepoHelper: 'Operar um repositório do tipo HTTP requer reinicialização do serviço Docker.',
|
||||
httpRepo:
|
||||
'Escolher o protocolo HTTP requer reiniciar o serviço Docker para adicioná-lo a registries inseguros.',
|
||||
delInsecure: 'Remover da lista de segurança',
|
||||
|
||||
@@ -334,6 +334,7 @@ const message = {
|
||||
ssl: 'Сертификат | Сертификаты',
|
||||
database: 'База данных | Базы данных',
|
||||
ai_tools: 'AI',
|
||||
mcp: 'MCP',
|
||||
container: 'Контейнер | Контейнеры',
|
||||
cronjob: 'Cron | Задачи Cron',
|
||||
host: 'Хост | Хосты',
|
||||
@@ -843,7 +844,7 @@ const message = {
|
||||
|
||||
repo: 'Реестры',
|
||||
createRepo: 'Добавить',
|
||||
createRepoHelper: 'Добавление репозитория HTTP-типа требует перезапуска службы Docker.',
|
||||
httpRepoHelper: 'Работа с репозиторием HTTP-типа требует перезапуска службы Docker.',
|
||||
httpRepo: 'Выбор HTTP протокола требует перезапуска службы Docker для добавления в небезопасные реестры.',
|
||||
delInsecure: 'Удаление учетных данных',
|
||||
delInsecureHelper: 'Это перезапустит службу Docker для удаления из небезопасных реестров. Хотите продолжить?',
|
||||
|
||||
@@ -327,6 +327,7 @@ const message = {
|
||||
ssl: '證書',
|
||||
database: '資料庫',
|
||||
ai_tools: 'AI',
|
||||
mcp: 'MCP',
|
||||
container: '容器',
|
||||
cronjob: '計劃任務',
|
||||
host: '主機',
|
||||
@@ -804,7 +805,7 @@ const message = {
|
||||
|
||||
repo: '倉庫',
|
||||
createRepo: '新增倉庫',
|
||||
createRepoHelper: '添加 HTTP 類型倉庫需要重啟 Docker 服務。',
|
||||
httpRepoHelper: '操作 HTTP 類型倉庫需要重啟 Docker 服務。',
|
||||
downloadUrl: '下載網址',
|
||||
imageRepo: '鏡像倉庫',
|
||||
repoHelper: '是否包含鏡像倉庫/組織/項目?',
|
||||
|
||||
@@ -326,6 +326,7 @@ const message = {
|
||||
ssl: '证书',
|
||||
database: '数据库',
|
||||
ai_tools: 'AI',
|
||||
mcp: 'MCP',
|
||||
container: '容器',
|
||||
cronjob: '计划任务',
|
||||
host: '主机',
|
||||
@@ -806,7 +807,7 @@ const message = {
|
||||
|
||||
repo: '仓库',
|
||||
createRepo: '添加仓库',
|
||||
createRepoHelper: '添加 http 类型仓库需要重启 Docker 服务。',
|
||||
httpRepoHelper: '操作 http 类型仓库需要重启 Docker 服务。',
|
||||
downloadUrl: '下载地址',
|
||||
imageRepo: '镜像仓库',
|
||||
repoHelper: '是否包含镜像仓库/组织/项目?',
|
||||
|
||||
@@ -24,7 +24,7 @@ const databaseRouter = {
|
||||
name: 'MCPServer',
|
||||
component: () => import('@/views/ai/mcp/server/index.vue'),
|
||||
meta: {
|
||||
title: 'MCP',
|
||||
title: 'menu.mcp',
|
||||
requiresAuth: true,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -61,8 +61,9 @@
|
||||
</template>
|
||||
</LayoutContent>
|
||||
|
||||
<OpDialog ref="opRef" @search="search" />
|
||||
<OpDialog ref="opRef" @search="search" @submit="submitDelete" />
|
||||
<OperatorDialog @search="search" ref="dialogRef" />
|
||||
<ConfirmDialog ref="confirmDialog" @confirm="submitDelete" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -87,6 +88,8 @@ const paginationConfig = reactive({
|
||||
const searchName = ref();
|
||||
|
||||
const opRef = ref();
|
||||
const confirmDialog = ref();
|
||||
const currentRepo = ref();
|
||||
|
||||
const dockerStatus = ref('Running');
|
||||
const loadStatus = async () => {
|
||||
@@ -141,7 +144,16 @@ const onOpenDialog = async (
|
||||
};
|
||||
|
||||
const onDelete = async (row: Container.RepoInfo) => {
|
||||
let ids = [row.id];
|
||||
currentRepo.value = row.id;
|
||||
if (row.protocol === 'http') {
|
||||
let params = {
|
||||
header: i18n.global.t('container.repo'),
|
||||
operationInfo: i18n.global.t('container.httpRepoHelper'),
|
||||
submitInputInfo: i18n.global.t('database.restartNow'),
|
||||
};
|
||||
confirmDialog.value!.acceptParams(params);
|
||||
return;
|
||||
}
|
||||
opRef.value.acceptParams({
|
||||
title: i18n.global.t('commons.button.delete'),
|
||||
names: [row.name],
|
||||
@@ -149,11 +161,23 @@ const onDelete = async (row: Container.RepoInfo) => {
|
||||
i18n.global.t('container.repo'),
|
||||
i18n.global.t('commons.button.delete'),
|
||||
]),
|
||||
api: deleteImageRepo,
|
||||
params: { ids: ids },
|
||||
api: null,
|
||||
params: null,
|
||||
});
|
||||
};
|
||||
|
||||
const submitDelete = async () => {
|
||||
loading.value = true;
|
||||
await deleteImageRepo(currentRepo.value)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
search();
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const onCheckConn = async (row: Container.RepoInfo) => {
|
||||
loading.value = true;
|
||||
await checkRepoStatus(row.id)
|
||||
|
||||
@@ -108,9 +108,13 @@ const dialogData = ref<DialogProps>({
|
||||
title: '',
|
||||
});
|
||||
const confirmDialog = ref();
|
||||
const oldUrl = ref();
|
||||
const oldProto = ref();
|
||||
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
dialogData.value = params;
|
||||
oldUrl.value = params.rowData.downloadUrl;
|
||||
oldProto.value = params.rowData.protocol;
|
||||
title.value = i18n.global.t('commons.button.' + dialogData.value.title);
|
||||
drawerVisible.value = true;
|
||||
};
|
||||
@@ -147,13 +151,23 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
if (dialogData.value.rowData.protocol === 'https') {
|
||||
let newProto = dialogData.value.rowData.protocol;
|
||||
if (newProto === 'https' && dialogData.value.title === 'add') {
|
||||
submit();
|
||||
return;
|
||||
}
|
||||
if (newProto === oldProto.value) {
|
||||
if (
|
||||
(oldProto.value === 'http' && dialogData.value.rowData.downloadUrl === oldUrl.value) ||
|
||||
oldProto.value === 'https'
|
||||
) {
|
||||
submit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
let params = {
|
||||
header: i18n.global.t('container.imageRepo'),
|
||||
operationInfo: i18n.global.t('container.createRepoHelper'),
|
||||
header: i18n.global.t('container.repo'),
|
||||
operationInfo: i18n.global.t('container.httpRepoHelper'),
|
||||
submitInputInfo: i18n.global.t('database.restartNow'),
|
||||
};
|
||||
confirmDialog.value!.acceptParams(params);
|
||||
|
||||
@@ -289,6 +289,7 @@ const chartOption = ref('network');
|
||||
let timer: NodeJS.Timer | null = null;
|
||||
let isInit = ref<boolean>(true);
|
||||
let isActive = ref(true);
|
||||
let isCurrentActive = ref(true);
|
||||
|
||||
const ioReadBytes = ref<Array<number>>([]);
|
||||
const ioWriteBytes = ref<Array<number>>([]);
|
||||
@@ -426,12 +427,20 @@ const onLoadBaseInfo = async (isInit: boolean, range: string) => {
|
||||
currentInfo.value.uptime = resData.uptime;
|
||||
|
||||
loadAppCurrentInfo();
|
||||
statusRef.value.acceptParams(currentInfo.value, baseInfo.value);
|
||||
appRef.value.acceptParams();
|
||||
statusRef.value?.acceptParams(currentInfo.value, baseInfo.value);
|
||||
appRef.value?.acceptParams();
|
||||
if (isInit) {
|
||||
timer = setInterval(async () => {
|
||||
if (isActive.value && !globalStore.isOnRestart) {
|
||||
loadAppCurrentInfo();
|
||||
try {
|
||||
if (!isCurrentActive.value) {
|
||||
throw new Error('jump out');
|
||||
}
|
||||
if (isActive.value && !globalStore.isOnRestart) {
|
||||
await loadAppCurrentInfo();
|
||||
}
|
||||
} catch {
|
||||
clearInterval(Number(timer));
|
||||
timer = null;
|
||||
}
|
||||
}, 3000);
|
||||
}
|
||||
@@ -439,7 +448,7 @@ const onLoadBaseInfo = async (isInit: boolean, range: string) => {
|
||||
|
||||
const loadAppCurrentInfo = async () => {
|
||||
await Promise.all([onLoadCurrentInfo('gpu'), onLoadCurrentInfo('basic'), onLoadCurrentInfo('ioNet')]);
|
||||
statusRef.value.acceptParams(currentInfo.value, baseInfo.value);
|
||||
statusRef.value?.acceptParams(currentInfo.value, baseInfo.value);
|
||||
};
|
||||
|
||||
const onLoadCurrentInfo = async (scope: string) => {
|
||||
@@ -661,6 +670,7 @@ onMounted(() => {
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('focus', onFocus);
|
||||
window.removeEventListener('blur', onBlur);
|
||||
isCurrentActive.value = false;
|
||||
clearInterval(Number(timer));
|
||||
timer = null;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user