diff --git a/agent/app/service/app_utils.go b/agent/app/service/app_utils.go index 2f3fd9b6bc51..627624cbb78d 100644 --- a/agent/app/service/app_utils.go +++ b/agent/app/service/app_utils.go @@ -612,6 +612,7 @@ func upgradeInstall(req request.AppInstallUpgrade) error { if err != nil { return err } + dockerCLi, err := docker.NewClient() if req.PullImage { images, err := composeV2.GetDockerComposeImagesV2(content, []byte(detail.DockerCompose)) if err != nil { @@ -619,10 +620,7 @@ func upgradeInstall(req request.AppInstallUpgrade) error { } for _, image := range images { t.Log(i18n.GetWithName("PullImageStart", image)) - if out, err := cmd.ExecWithTimeOut("docker pull "+image, 20*time.Minute); err != nil { - if out != "" { - err = errors.New(out) - } + if err = dockerCLi.PullImageWithProcess(t, image); err != nil { err = buserr.WithNameAndErr("ErrDockerPullImage", "", err) return err } @@ -1046,6 +1044,10 @@ func upApp(task *task.Task, appInstall *model.AppInstall, pullImages bool) error return err } imagePrefix := xpack.GetImagePrefix() + dockerCLi, err := docker.NewClient() + if err != nil { + return err + } for _, image := range images { if imagePrefix != "" { lastSlashIndex := strings.LastIndex(image, "/") @@ -1054,17 +1056,19 @@ func upApp(task *task.Task, appInstall *model.AppInstall, pullImages bool) error } image = imagePrefix + "/" + image } + task.Log(i18n.GetWithName("PullImageStart", image)) - if out, err = cmd.ExecWithTimeOut("docker pull "+image, 20*time.Minute); err != nil { - if out != "" { - if strings.Contains(out, "no such host") { + if err = dockerCLi.PullImageWithProcess(task, image); err != nil { + errOur := err.Error() + if errOur != "" { + if strings.Contains(errOur, "no such host") { errMsg = i18n.GetMsgByKey("ErrNoSuchHost") + ":" } - if strings.Contains(out, "timeout") { + if strings.Contains(errOur, "timeout") { errMsg = i18n.GetMsgByKey("ErrImagePullTimeOut") + ":" } } - appInstall.Message = errMsg + out + appInstall.Message = errMsg + errOur installErr := errors.New(appInstall.Message) task.LogFailedWithErr(i18n.GetMsgByKey("PullImage"), installErr) return installErr diff --git a/agent/app/service/website.go b/agent/app/service/website.go index b65623217e28..d49d17d55235 100644 --- a/agent/app/service/website.go +++ b/agent/app/service/website.go @@ -1375,7 +1375,7 @@ func (w WebsiteService) ChangePHPVersion(req request.WebsitePHPVersionReq) error return buserr.New("ErrPHPResource") } website.RuntimeID = req.RuntimeID - phpProxy := fmt.Sprintf("127.0.0.1:%d", runtime.Port) + phpProxy := fmt.Sprintf("127.0.0.1:%s", runtime.Port) website.Proxy = phpProxy server.UpdatePHPProxy([]string{website.Proxy}, "") website.Type = constant.Runtime diff --git a/agent/app/service/website_utils.go b/agent/app/service/website_utils.go index 1fafb5c511d6..cd1c60884de9 100644 --- a/agent/app/service/website_utils.go +++ b/agent/app/service/website_utils.go @@ -849,7 +849,7 @@ func opWebsite(website *model.Website, operate string) error { } server.UpdatePHPProxy([]string{website.Proxy}, localPath) } else { - proxy := fmt.Sprintf("http://127.0.0.1:%d", runtime.Port) + proxy := fmt.Sprintf("http://127.0.0.1:%s", runtime.Port) server.UpdateRootProxy([]string{proxy}) } } diff --git a/agent/app/task/task.go b/agent/app/task/task.go index 320db398c46d..815a71bca674 100644 --- a/agent/app/task/task.go +++ b/agent/app/task/task.go @@ -1,6 +1,7 @@ package task import ( + "bufio" "context" "fmt" "log" @@ -26,6 +27,7 @@ type Task struct { Name string TaskID string Logger *log.Logger + Writer *bufio.Writer SubTasks []*SubTask Rollbacks []RollbackFunc logFile *os.File @@ -111,6 +113,7 @@ func NewTask(name, operate, taskScope, taskID string, resourceID uint) (*Task, e if err != nil { return nil, fmt.Errorf("failed to open log file: %w", err) } + writer := bufio.NewWriter(file) logger := log.New(file, "", log.LstdFlags) taskModel := &model.Task{ ID: taskID, @@ -122,7 +125,7 @@ func NewTask(name, operate, taskScope, taskID string, resourceID uint) (*Task, e Operate: operate, } taskRepo := repo.NewITaskRepo() - task := &Task{Name: name, logFile: file, Logger: logger, taskRepo: taskRepo, Task: taskModel} + task := &Task{Name: name, logFile: file, Logger: logger, taskRepo: taskRepo, Task: taskModel, Writer: writer} return task, nil } diff --git a/agent/utils/docker/docker.go b/agent/utils/docker/docker.go index 290334044b2b..e781edb4019a 100644 --- a/agent/utils/docker/docker.go +++ b/agent/utils/docker/docker.go @@ -2,17 +2,21 @@ package docker import ( "context" - "github.com/docker/docker/api/types/network" - - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/image" - + "encoding/json" + "fmt" "github.com/1Panel-dev/1Panel/agent/app/model" + "github.com/1Panel-dev/1Panel/agent/app/task" "github.com/1Panel-dev/1Panel/agent/global" - "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/image" + "github.com/docker/docker/api/types/network" "github.com/docker/docker/client" + "io" + "os" + "strings" + "time" ) func NewDockerClient() (*client.Client, error) { @@ -28,10 +32,6 @@ func NewDockerClient() (*client.Client, error) { return cli, nil } -type Client struct { - cli *client.Client -} - func NewClient() (Client, error) { var settingItem model.Setting _ = global.DB.Where("key = ?", "DockerSockPath").First(&settingItem).Error @@ -48,10 +48,8 @@ func NewClient() (Client, error) { }, nil } -func NewClientWithCli(cli *client.Client) (Client, error) { - return Client{ - cli: cli, - }, nil +type Client struct { + cli *client.Client } func (c Client) Close() { @@ -142,6 +140,7 @@ func CreateDefaultDockerNetwork() error { global.LOG.Errorf("init docker client error %s", err.Error()) return err } + defer cli.Close() if !cli.NetworkExist("1panel-network") { if err := cli.CreateNetwork("1panel-network"); err != nil { @@ -151,3 +150,66 @@ func CreateDefaultDockerNetwork() error { } return nil } + +func setLog(id, newLastLine string, task *task.Task) error { + data, err := os.ReadFile(task.Task.LogFile) + if err != nil { + return fmt.Errorf("failed to read file: %v", err) + } + lines := strings.Split(string(data), "\n") + exist := false + for index, line := range lines { + if strings.Contains(line, id) { + lines[index] = newLastLine + exist = true + break + } + } + if !exist { + task.Log(newLastLine) + return nil + } + output := strings.Join(lines, "\n") + _ = os.WriteFile(task.Task.LogFile, []byte(output), os.ModePerm) + return nil +} + +func (c Client) PullImageWithProcess(task *task.Task, imageName string) error { + out, err := c.cli.ImagePull(context.Background(), imageName, image.PullOptions{}) + if err != nil { + return err + } + defer out.Close() + decoder := json.NewDecoder(out) + for { + var progress map[string]interface{} + if err = decoder.Decode(&progress); err != nil { + if err == io.EOF { + break + } + return err + } + timeStr := time.Now().Format("2006/01/02 15:04:05") + status, _ := progress["status"].(string) + if status == "Downloading" || status == "Extracting" { + id, _ := progress["id"].(string) + progressDetail, _ := progress["progressDetail"].(map[string]interface{}) + current, _ := progressDetail["current"].(float64) + progressStr := "" + total, ok := progressDetail["total"].(float64) + if ok { + progressStr = fmt.Sprintf("%s %s [%s] --- %.2f%%", timeStr, status, id, (current/total)*100) + } else { + progressStr = fmt.Sprintf("%s %s [%s] --- %.2f%%", timeStr, status, id, current) + } + + _ = setLog(id, progressStr, task) + } + if status == "Pull complete" || status == "Download complete" { + id, _ := progress["id"].(string) + progressStr := fmt.Sprintf("%s %s [%s] --- %.2f%%", timeStr, status, id, 100.0) + _ = setLog(id, progressStr, task) + } + } + return nil +} diff --git a/core/constant/common.go b/core/constant/common.go index d3f0bcebd5fa..bcf6a1132f3d 100644 --- a/core/constant/common.go +++ b/core/constant/common.go @@ -126,6 +126,7 @@ var WebUrlMap = map[string]struct{}{ "/xpack/waf/websites": {}, "/xpack/waf/log": {}, "/xpack/waf/block": {}, + "/xpack/waf/blackwhite": {}, "/xpack/monitor/dashboard": {}, "/xpack/monitor/setting": {}, "/xpack/monitor/rank": {}, diff --git a/frontend/src/views/log/task/index.vue b/frontend/src/views/log/task/index.vue index fe6c8049322c..2de767c878fa 100644 --- a/frontend/src/views/log/task/index.vue +++ b/frontend/src/views/log/task/index.vue @@ -85,7 +85,7 @@ const search = async () => { }; const openTaskLog = (row: Log.Task) => { - taskLogRef.value.openWithTaskID(row.id, !(row.status == 'Executing')); + taskLogRef.value.openWithTaskID(row.id, row.status == 'Executing'); }; onMounted(() => { diff --git a/frontend/src/views/login/components/login-form.vue b/frontend/src/views/login/components/login-form.vue index 9e7229c43ea3..7a3cb4c64dc8 100644 --- a/frontend/src/views/login/components/login-form.vue +++ b/frontend/src/views/login/components/login-form.vue @@ -1,5 +1,5 @@