1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-03-01 03:24:14 +08:00

feat: 应用安装、升级、卸载之前支持执行脚本 (#2042)

This commit is contained in:
zhengkunwang 2023-08-23 22:48:14 +08:00 committed by GitHub
parent 63ae17372d
commit 59eff6e27f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 16 deletions

View File

@ -402,7 +402,7 @@ func (a AppService) Install(ctx context.Context, req request.AppInstallCreate) (
_ = appInstallRepo.Save(context.Background(), appInstall) _ = appInstallRepo.Save(context.Background(), appInstall)
return return
} }
if err = upAppPre(app, appInstall); err != nil { if err = runScript(appInstall, "init"); err != nil {
return return
} }
upApp(appInstall) upApp(appInstall)

View File

@ -5,6 +5,7 @@ import (
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
"math" "math"
"net/http" "net/http"
"os" "os"
@ -188,6 +189,10 @@ func deleteAppInstall(install model.AppInstall, deleteBackup bool, forceDelete b
if err != nil && !forceDelete { if err != nil && !forceDelete {
return handleErr(install, err, out) return handleErr(install, err, out)
} }
if err = runScript(&install, "uninstall"); err != nil {
_, _ = compose.Up(install.GetComposePath())
return err
}
} }
tx, ctx := helper.GetTxAndContext() tx, ctx := helper.GetTxAndContext()
defer tx.Rollback() defer tx.Rollback()
@ -288,10 +293,19 @@ func upgradeInstall(installId uint, detailId uint, backup bool) error {
detailDir = path.Join(constant.ResourceDir, "apps", "local", strings.TrimPrefix(install.App.Key, "local"), detail.Version) detailDir = path.Join(constant.ResourceDir, "apps", "local", strings.TrimPrefix(install.App.Key, "local"), detail.Version)
} }
cmd := exec.Command("/bin/bash", "-c", fmt.Sprintf("cp -rn %s/* %s || true", detailDir, install.GetPath())) command := exec.Command("/bin/bash", "-c", fmt.Sprintf("cp -rn %s/* %s || true", detailDir, install.GetPath()))
stdout, _ := cmd.CombinedOutput() stdout, _ := command.CombinedOutput()
if stdout != nil { if stdout != nil {
global.LOG.Errorf("upgrade app [%s] [%s] cp file log : %s ", install.App.Key, install.Name, string(stdout)) global.LOG.Infof("upgrade app [%s] [%s] cp file log : %s ", install.App.Key, install.Name, string(stdout))
}
fileOp := files.NewFileOp()
sourceScripts := path.Join(detailDir, "scripts")
if fileOp.Stat(sourceScripts) {
dstScripts := path.Join(install.GetPath(), "scripts")
_ = fileOp.DeleteDir(dstScripts)
_ = fileOp.CreateDir(dstScripts, 0755)
scriptCmd := exec.Command("cp", "-rf", sourceScripts+"/.", dstScripts+"/")
_, _ = scriptCmd.CombinedOutput()
} }
composeMap := make(map[string]interface{}) composeMap := make(map[string]interface{})
@ -370,12 +384,16 @@ func upgradeInstall(installId uint, detailId uint, backup bool) error {
} }
return return
} }
fileOp := files.NewFileOp()
envParams := make(map[string]string, len(envs)) envParams := make(map[string]string, len(envs))
handleMap(envs, envParams) handleMap(envs, envParams)
if err = env.Write(envParams, install.GetEnvPath()); err != nil { if err = env.Write(envParams, install.GetEnvPath()); err != nil {
return return
} }
if err = runScript(&install, "upgrade"); err != nil {
return
}
if upErr = fileOp.WriteFile(install.GetComposePath(), strings.NewReader(install.DockerCompose), 0775); upErr != nil { if upErr = fileOp.WriteFile(install.GetComposePath(), strings.NewReader(install.DockerCompose), 0775); upErr != nil {
return return
} }
@ -578,17 +596,27 @@ func copyData(app model.App, appDetail model.AppDetail, appInstall *model.AppIns
return return
} }
// 处理文件夹权限等问题 func runScript(appInstall *model.AppInstall, operate string) error {
func upAppPre(app model.App, appInstall *model.AppInstall) error { workDir := appInstall.GetPath()
dataPath := path.Join(appInstall.GetPath(), "data") scriptPath := ""
fileOp := files.NewFileOp() switch operate {
switch app.Key { case "init":
case "nexus": scriptPath = path.Join(workDir, "scripts", "init.sh")
return fileOp.ChownR(dataPath, "200", "0", true) case "upgrade":
case "sftpgo": scriptPath = path.Join(workDir, "scripts", "upgrade.sh")
return fileOp.ChownR(dataPath, "1000", "1000", true) case "uninstall":
case "pgadmin4": scriptPath = path.Join(workDir, "scripts", "uninstall.sh")
return fileOp.ChownR(dataPath, "5050", "5050", true) }
if !files.NewFileOp().Stat(scriptPath) {
return nil
}
out, err := cmd.ExecScript(scriptPath, workDir)
if err != nil {
if out != "" {
global.LOG.Errorf("run script %s error %s", scriptPath, out)
return errors.New(out)
}
return err
} }
return nil return nil
} }

View File

@ -141,6 +141,35 @@ func ExecWithCheck(name string, a ...string) (string, error) {
return stdout.String(), nil return stdout.String(), nil
} }
func ExecScript(scriptPath, workDir string) (string, error) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
defer cancel()
cmd := exec.Command("/bin/sh", scriptPath)
cmd.Dir = workDir
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
if ctx.Err() == context.DeadlineExceeded {
return "", buserr.New(constant.ErrCmdTimeout)
}
if err != nil {
errMsg := ""
if len(stderr.String()) != 0 {
errMsg = fmt.Sprintf("stderr: %s", stderr.String())
}
if len(stdout.String()) != 0 {
if len(errMsg) != 0 {
errMsg = fmt.Sprintf("%s; stdout: %s", errMsg, stdout.String())
} else {
errMsg = fmt.Sprintf("stdout: %s", stdout.String())
}
}
return errMsg, err
}
return stdout.String(), nil
}
func CheckIllegal(args ...string) bool { func CheckIllegal(args ...string) bool {
if args == nil { if args == nil {
return false return false