mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-10-25 06:56:32 +08:00
feat: 优化 PHP 运行环境扩展安装 (#6401)
Some checks failed
sync2gitee / repo-sync (push) Failing after -8m45s
Some checks failed
sync2gitee / repo-sync (push) Failing after -8m45s
This commit is contained in:
parent
1af83c1aeb
commit
7aefd0df1a
8 changed files with 106 additions and 46 deletions
|
|
@ -12,6 +12,7 @@ import (
|
|||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -536,10 +537,7 @@ func (r *RuntimeService) OperateRuntime(req request.RuntimeOperate) error {
|
|||
}
|
||||
runtime.Status = constant.RuntimeStopped
|
||||
case constant.RuntimeRestart:
|
||||
if err = runComposeCmdWithLog(constant.RuntimeDown, runtime.GetComposePath(), runtime.GetLogPath()); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = runComposeCmdWithLog(constant.RuntimeUp, runtime.GetComposePath(), runtime.GetLogPath()); err != nil {
|
||||
if err = restartRuntime(runtime); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = SyncRuntimeContainerStatus(runtime); err != nil {
|
||||
|
|
@ -659,27 +657,29 @@ func (r *RuntimeService) GetPHPExtensions(runtimeID uint) (response.PHPExtension
|
|||
return res, err
|
||||
}
|
||||
extensions := strings.Split(out, "\n")
|
||||
var cleanExtensions []string
|
||||
exitExtensions := make(map[string]string)
|
||||
for _, ext := range extensions {
|
||||
extStr := strings.TrimSpace(ext)
|
||||
if extStr != "" && extStr != "[Zend Modules]" && extStr != "[PHP Modules]" {
|
||||
cleanExtensions = append(cleanExtensions, extStr)
|
||||
exitExtensions[strings.ToLower(extStr)] = extStr
|
||||
}
|
||||
}
|
||||
res.Extensions = cleanExtensions
|
||||
var phpExtensions []response.SupportExtension
|
||||
if err = json.Unmarshal(nginx_conf.PHPExtensionsJson, &phpExtensions); err != nil {
|
||||
return res, err
|
||||
}
|
||||
for _, ext := range phpExtensions {
|
||||
for _, cExt := range cleanExtensions {
|
||||
if ext.Check == cExt {
|
||||
ext.Installed = true
|
||||
break
|
||||
}
|
||||
if _, ok := exitExtensions[strings.ToLower(ext.Check)]; ok {
|
||||
ext.Installed = true
|
||||
}
|
||||
res.SupportExtensions = append(res.SupportExtensions, ext)
|
||||
}
|
||||
for _, name := range exitExtensions {
|
||||
res.Extensions = append(res.Extensions, name)
|
||||
}
|
||||
sort.Slice(res.Extensions, func(i, j int) bool {
|
||||
return strings.ToLower(res.Extensions[i]) < strings.ToLower(res.Extensions[j])
|
||||
})
|
||||
return res, nil
|
||||
}
|
||||
|
||||
|
|
@ -688,7 +688,7 @@ func (r *RuntimeService) InstallPHPExtension(req request.PHPExtensionInstallReq)
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
installTask, err := task.NewTaskWithOps(req.Name, task.TaskInstall, task.TaskScopeRuntime, req.TaskID, runtime.ID)
|
||||
installTask, err := task.NewTaskWithOps(req.Name, task.TaskInstall, task.TaskScopeRuntimeExtension, req.TaskID, runtime.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -698,6 +698,27 @@ func (r *RuntimeService) InstallPHPExtension(req request.PHPExtensionInstallReq)
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, err := docker.NewClient()
|
||||
defer client.Close()
|
||||
if err == nil {
|
||||
oldImageID, err := client.GetImageIDByName(runtime.Image)
|
||||
commitCmd := fmt.Sprintf("docker commit %s %s", runtime.ContainerName, runtime.Image)
|
||||
err = cmd2.ExecWithLogFile(commitCmd, 15*time.Minute, t.Task.LogFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newImageID, err := client.GetImageIDByName(runtime.Image)
|
||||
if err == nil && newImageID != oldImageID {
|
||||
if err := client.DeleteImage(oldImageID); err != nil {
|
||||
t.Log(fmt.Sprintf("delete old image error %v", err))
|
||||
} else {
|
||||
t.Log("delete old image success")
|
||||
}
|
||||
}
|
||||
}
|
||||
if err = restartRuntime(runtime); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}, nil)
|
||||
go func() {
|
||||
|
|
@ -745,7 +766,10 @@ func (r *RuntimeService) UnInstallPHPExtension(req request.PHPExtensionInstallRe
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := unInstallPHPExtension(runtime, []string{req.Name}); err != nil {
|
||||
if err = unInstallPHPExtension(runtime, []string{req.Name}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = restartRuntime(runtime); err != nil {
|
||||
return err
|
||||
}
|
||||
return runtimeRepo.Save(runtime)
|
||||
|
|
@ -858,10 +882,7 @@ func (r *RuntimeService) UpdatePHPConfig(req request.PHPConfigUpdate) (err error
|
|||
return err
|
||||
}
|
||||
|
||||
err = r.OperateRuntime(request.RuntimeOperate{
|
||||
Operate: constant.RuntimeRestart,
|
||||
ID: req.ID,
|
||||
})
|
||||
err = restartRuntime(runtime)
|
||||
if err != nil {
|
||||
_ = fileOp.WriteFile(phpConfigPath, strings.NewReader(string(contentBytes)), 0755)
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
|
@ -135,7 +136,7 @@ func runComposeCmdWithLog(operate string, composePath string, logPath string) er
|
|||
if operate == "up" {
|
||||
cmd = exec.Command("docker", "compose", "-f", composePath, operate, "-d")
|
||||
}
|
||||
logFile, err := os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
|
||||
logFile, err := os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("Failed to open log file: %v", err)
|
||||
return err
|
||||
|
|
@ -149,7 +150,7 @@ func runComposeCmdWithLog(operate string, composePath string, logPath string) er
|
|||
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return errors.New(buserr.New(constant.ErrRuntimeStart).Error() + ":" + stderrBuf.String())
|
||||
return errors.New(buserr.New(constant.ErrRuntimeStart).Error() + ":" + err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -206,21 +207,6 @@ func getRuntimeEnv(envStr, key string) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func getFileEnv(filePath, key string) (string, error) {
|
||||
envContent, err := files.NewFileOp().GetContent(filePath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
env, err := gotenv.Unmarshal(string(envContent))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if v, ok := env[key]; ok {
|
||||
return v, nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func buildRuntime(runtime *model.Runtime, oldImageID string, oldEnv string, rebuild bool) {
|
||||
runtimePath := runtime.GetPath()
|
||||
composePath := runtime.GetComposePath()
|
||||
|
|
@ -249,6 +235,9 @@ func buildRuntime(runtime *model.Runtime, oldImageID string, oldEnv string, rebu
|
|||
runtime.Message = buserr.New(constant.ErrImageBuildErr).Error() + ":" + err.Error()
|
||||
}
|
||||
} else {
|
||||
if err = runComposeCmdWithLog(constant.RuntimeDown, runtime.GetComposePath(), runtime.GetLogPath()); err != nil {
|
||||
return
|
||||
}
|
||||
runtime.Message = ""
|
||||
if oldImageID != "" {
|
||||
client, err := docker.NewClient()
|
||||
|
|
@ -500,6 +489,7 @@ func unInstallPHPExtension(runtime *model.Runtime, delExtensions []string) error
|
|||
delMap[ext.Check] = struct{}{}
|
||||
_ = fileOP.DeleteFile(path.Join(dir, "extensions", ext.File))
|
||||
_ = fileOP.DeleteFile(path.Join(dir, "conf", "conf.d", "docker-php-ext-"+ext.Check+".ini"))
|
||||
_ = removePHPIniExt(path.Join(dir, "conf", "php.ini"), ext.File)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -531,3 +521,48 @@ func unInstallPHPExtension(runtime *model.Runtime, delExtensions []string) error
|
|||
runtime.Env = envContent
|
||||
return nil
|
||||
}
|
||||
|
||||
func removePHPIniExt(filePath, extensionName string) error {
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
targetLine1 := `extension="` + extensionName + `"`
|
||||
targetLine2 := `zend_extension="` + extensionName + `"`
|
||||
|
||||
tempFile, err := os.CreateTemp(path.Dir(filePath), "temp_*.txt")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tempFile.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
writer := bufio.NewWriter(tempFile)
|
||||
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if !strings.Contains(line, targetLine1) && !strings.Contains(line, targetLine2) {
|
||||
_, err := writer.WriteString(line + "\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.Rename(tempFile.Name(), filePath)
|
||||
}
|
||||
|
||||
func restartRuntime(runtime *model.Runtime) (err error) {
|
||||
if err = runComposeCmdWithLog(constant.RuntimeDown, runtime.GetComposePath(), runtime.GetLogPath()); err != nil {
|
||||
return
|
||||
}
|
||||
if err = runComposeCmdWithLog(constant.RuntimeUp, runtime.GetComposePath(), runtime.GetLogPath()); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,11 +54,12 @@ const (
|
|||
)
|
||||
|
||||
const (
|
||||
TaskScopeWebsite = "Website"
|
||||
TaskScopeApp = "App"
|
||||
TaskScopeRuntime = "Runtime"
|
||||
TaskScopeDatabase = "Database"
|
||||
TaskScopeAppStore = "AppStore"
|
||||
TaskScopeWebsite = "Website"
|
||||
TaskScopeApp = "App"
|
||||
TaskScopeRuntime = "Runtime"
|
||||
TaskScopeDatabase = "Database"
|
||||
TaskScopeAppStore = "AppStore"
|
||||
TaskScopeRuntimeExtension = "RuntimeExtension"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
},
|
||||
{
|
||||
"name": "opcache",
|
||||
"check": "opcache",
|
||||
"check": "Zend OPcache",
|
||||
"file": "opcache.so",
|
||||
"versions": ["56", "70", "71", "72", "73", "74", "80", "81", "82", "83"],
|
||||
"installed": false
|
||||
|
|
|
|||
|
|
@ -243,4 +243,5 @@ AppStore: "App Store"
|
|||
TaskSync: "Sync"
|
||||
LocalApp: "Local App"
|
||||
SubTask: "Subtask"
|
||||
RuntimeExtension: "Runtime Extension"
|
||||
|
||||
|
|
|
|||
|
|
@ -245,4 +245,5 @@ AppStore: "應用商店"
|
|||
TaskSync: "同步"
|
||||
LocalApp: "本地應用"
|
||||
SubTask: "子任務"
|
||||
RuntimeExtension: "運行環境擴展"
|
||||
|
||||
|
|
|
|||
|
|
@ -246,4 +246,5 @@ EnableSSL: "开启 HTTPS"
|
|||
AppStore: "应用商店"
|
||||
TaskSync: "同步"
|
||||
LocalApp: "本地应用"
|
||||
SubTask: "子任务"
|
||||
SubTask: "子任务"
|
||||
RuntimeExtension: "运行环境扩展"
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
<div class="mt-5">
|
||||
<el-text>{{ $t('runtime.popularExtension') }}</el-text>
|
||||
</div>
|
||||
<ComplexTable :data="supportExtensions" @search="search()" :heightDiff="350" :loading="loading">
|
||||
<ComplexTable :data="supportExtensions" @search="search()" :heightDiff="350" v-loading="loading">
|
||||
<el-table-column prop="name" :label="$t('commons.table.name')" />
|
||||
<el-table-column prop="installed" :label="$t('commons.table.status')">
|
||||
<template #default="{ row }">
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
/>
|
||||
</ComplexTable>
|
||||
</DrawerPro>
|
||||
<TaskLog ref="taskLogRef" @clos="search()" />
|
||||
<TaskLog ref="taskLogRef" @close="search()" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
|
@ -76,7 +76,7 @@ const installExtension = async (row: Runtime.SupportExtension) => {
|
|||
}).then(async () => {
|
||||
const req = {
|
||||
id: runtime.value.id,
|
||||
name: row.check,
|
||||
name: row.name,
|
||||
taskID: newUUID(),
|
||||
};
|
||||
loading.value = true;
|
||||
|
|
@ -96,7 +96,7 @@ const unInstallPHPExtension = async (row: Runtime.SupportExtension) => {
|
|||
}).then(async () => {
|
||||
const req = {
|
||||
id: runtime.value.id,
|
||||
name: row.check,
|
||||
name: row.name,
|
||||
};
|
||||
loading.value = true;
|
||||
try {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue