From 59eff6e27f9325b86ee6cc4faf71d879a0e21212 Mon Sep 17 00:00:00 2001 From: zhengkunwang <31820853+zhengkunwang223@users.noreply.github.com> Date: Wed, 23 Aug 2023 22:48:14 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=BA=94=E7=94=A8=E5=AE=89=E8=A3=85?= =?UTF-8?q?=E3=80=81=E5=8D=87=E7=BA=A7=E3=80=81=E5=8D=B8=E8=BD=BD=E4=B9=8B?= =?UTF-8?q?=E5=89=8D=E6=94=AF=E6=8C=81=E6=89=A7=E8=A1=8C=E8=84=9A=E6=9C=AC?= =?UTF-8?q?=20(#2042)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/service/app.go | 2 +- backend/app/service/app_utils.go | 58 +++++++++++++++++++++++--------- backend/utils/cmd/cmd.go | 29 ++++++++++++++++ 3 files changed, 73 insertions(+), 16 deletions(-) diff --git a/backend/app/service/app.go b/backend/app/service/app.go index 6803ed5f3..54bc33e61 100644 --- a/backend/app/service/app.go +++ b/backend/app/service/app.go @@ -402,7 +402,7 @@ func (a AppService) Install(ctx context.Context, req request.AppInstallCreate) ( _ = appInstallRepo.Save(context.Background(), appInstall) return } - if err = upAppPre(app, appInstall); err != nil { + if err = runScript(appInstall, "init"); err != nil { return } upApp(appInstall) diff --git a/backend/app/service/app_utils.go b/backend/app/service/app_utils.go index 14ede64db..2094e602e 100644 --- a/backend/app/service/app_utils.go +++ b/backend/app/service/app_utils.go @@ -5,6 +5,7 @@ import ( "encoding/base64" "encoding/json" "fmt" + "github.com/1Panel-dev/1Panel/backend/utils/cmd" "math" "net/http" "os" @@ -188,6 +189,10 @@ func deleteAppInstall(install model.AppInstall, deleteBackup bool, forceDelete b if err != nil && !forceDelete { return handleErr(install, err, out) } + if err = runScript(&install, "uninstall"); err != nil { + _, _ = compose.Up(install.GetComposePath()) + return err + } } tx, ctx := helper.GetTxAndContext() 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) } - cmd := exec.Command("/bin/bash", "-c", fmt.Sprintf("cp -rn %s/* %s || true", detailDir, install.GetPath())) - stdout, _ := cmd.CombinedOutput() + command := exec.Command("/bin/bash", "-c", fmt.Sprintf("cp -rn %s/* %s || true", detailDir, install.GetPath())) + stdout, _ := command.CombinedOutput() 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{}) @@ -370,12 +384,16 @@ func upgradeInstall(installId uint, detailId uint, backup bool) error { } return } - fileOp := files.NewFileOp() envParams := make(map[string]string, len(envs)) handleMap(envs, envParams) if err = env.Write(envParams, install.GetEnvPath()); err != nil { return } + + if err = runScript(&install, "upgrade"); err != nil { + return + } + if upErr = fileOp.WriteFile(install.GetComposePath(), strings.NewReader(install.DockerCompose), 0775); upErr != nil { return } @@ -578,17 +596,27 @@ func copyData(app model.App, appDetail model.AppDetail, appInstall *model.AppIns return } -// 处理文件夹权限等问题 -func upAppPre(app model.App, appInstall *model.AppInstall) error { - dataPath := path.Join(appInstall.GetPath(), "data") - fileOp := files.NewFileOp() - switch app.Key { - case "nexus": - return fileOp.ChownR(dataPath, "200", "0", true) - case "sftpgo": - return fileOp.ChownR(dataPath, "1000", "1000", true) - case "pgadmin4": - return fileOp.ChownR(dataPath, "5050", "5050", true) +func runScript(appInstall *model.AppInstall, operate string) error { + workDir := appInstall.GetPath() + scriptPath := "" + switch operate { + case "init": + scriptPath = path.Join(workDir, "scripts", "init.sh") + case "upgrade": + scriptPath = path.Join(workDir, "scripts", "upgrade.sh") + case "uninstall": + scriptPath = path.Join(workDir, "scripts", "uninstall.sh") + } + 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 } diff --git a/backend/utils/cmd/cmd.go b/backend/utils/cmd/cmd.go index 74804d269..a3498b506 100644 --- a/backend/utils/cmd/cmd.go +++ b/backend/utils/cmd/cmd.go @@ -141,6 +141,35 @@ func ExecWithCheck(name string, a ...string) (string, error) { 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 { if args == nil { return false