diff --git a/builder/exector/export_app.go b/builder/exector/export_app.go index 0c9f78f51..287f6a573 100644 --- a/builder/exector/export_app.go +++ b/builder/exector/export_app.go @@ -252,16 +252,16 @@ func (i *ExportApp) parseApps() ([]gjson.Result, error) { return arr, nil } +//exportImage export image of app func (i *ExportApp) exportImage(serviceDir string, app gjson.Result) error { serviceName := app.Get("service_cname").String() serviceName = unicode2zh(serviceName) os.MkdirAll(serviceDir, 0755) - // 处理掉文件名中冒号等不合法字符 image := app.Get("share_image").String() tarFileName := buildToLinuxFileName(image) user := app.Get("service_image.hub_user").String() pass := app.Get("service_image.hub_password").String() - // 如果是runner镜像则跳过 + // ignore runner image if checkIsRunner(image) { logrus.Debug("Skip the runner image: ", image) return nil @@ -296,14 +296,14 @@ func (i *ExportApp) exportSlug(serviceDir string, app gjson.Result) error { _, err := os.Stat(shareSlugPath) if shareSlugPath != "" && err == nil { logrus.Debug("The slug file was exist already, direct copy to service dir: ", shareSlugPath) - err = exec.Command("cp", shareSlugPath, fmt.Sprintf("%s/%s", serviceDir, tarFileName)).Run() + err = util.CopyFile(shareSlugPath, fmt.Sprintf("%s/%s", serviceDir, tarFileName)) if err == nil { return nil } - // 如果copy失败则忽略,在下一步中下载该slug包 + // if local copy failure, try download it logrus.Debugf("Failed to copy the slug file to service dir %s: %v", shareSlugPath, err) } - // 提取tfp服务器信息 + // get slug save server (ftp) info ftpHost := app.Get("service_slug.ftp_host").String() ftpPort := app.Get("service_slug.ftp_port").String() ftpUsername := app.Get("service_slug.ftp_username").String() @@ -314,15 +314,14 @@ func (i *ExportApp) exportSlug(serviceDir string, app gjson.Result) error { logrus.Error("Failed to create ftp client: ", err) return err } - // 开始下载文件 - i.Logger.Info(fmt.Sprintf("获取应用源码:%s", serviceName), map[string]string{"step": "get-slug", "status": "failure"}) + // download slug file + i.Logger.Info(fmt.Sprintf("Download service %s slug file", serviceName), map[string]string{"step": "get-slug", "status": "failure"}) err = ftpClient.DownloadFile(shareSlugPath, fmt.Sprintf("%s/%s", serviceDir, tarFileName), i.Logger) ftpClient.Close() if err != nil { logrus.Errorf("Failed to download slug file for group %s: %v", i.SourceDir, err) return err } - logrus.Debug("Successful download slug file: ", shareSlugPath) return nil } diff --git a/builder/exector/import_app.go b/builder/exector/import_app.go index 1880565ba..5a7c8d94c 100644 --- a/builder/exector/import_app.go +++ b/builder/exector/import_app.go @@ -498,13 +498,9 @@ func (i *ImportApp) loadApps() error { } } else { os.MkdirAll(filepath.Base(shareSlugPath), 0755) - cmd := exec.Command("cp", fileName, shareSlugPath) - var out bytes.Buffer - cmd.Stdout = &out - cmd.Stderr = &out - err = cmd.Run() + err := util.CopyFile(fileName, shareSlugPath) if err != nil { - logrus.Error("Failed to copy slug file to local directory: ", out.String()) + logrus.Error("Failed to copy slug file to local directory: ", shareSlugPath) return err } } diff --git a/util/comman.go b/util/comman.go index e5a62796a..f94eb2ba7 100644 --- a/util/comman.go +++ b/util/comman.go @@ -166,7 +166,7 @@ func CmdRunWithTimeout(cmd *exec.Cmd, timeout time.Duration) (bool, error) { go func() { <-done // allow goroutine to exit }() - logrus.Info("process:%s killed", cmd.Path) + logrus.Infof("process:%s killed", cmd.Path) return true, err case err = <-done: return false, err @@ -564,6 +564,37 @@ func Unzip(archive, target string) error { return nil } +// CopyFile copy source file to target +// direct io read and write file +// Keep the permissions user and group +func CopyFile(source, target string) error { + sfi, err := os.Stat(source) + if err != nil { + return err + } + elem := reflect.ValueOf(sfi.Sys()).Elem() + uid := elem.FieldByName("Uid").Uint() + gid := elem.FieldByName("Gid").Uint() + sf, err := directio.OpenFile(source, os.O_RDONLY, 0) + if err != nil { + return err + } + defer sf.Close() + tf, err := directio.OpenFile(target, os.O_RDONLY|os.O_CREATE|os.O_WRONLY, sfi.Mode()) + if err != nil { + return err + } + defer tf.Close() + _, err = io.Copy(tf, sf) + if err != nil { + return err + } + if err := os.Chown(target, int(uid), int(gid)); err != nil { + return err + } + return nil +} + //GetParentDirectory GetParentDirectory func GetParentDirectory(dirctory string) string { return substr(dirctory, 0, strings.LastIndex(dirctory, "/")) diff --git a/util/comman_test.go b/util/comman_test.go index de69adab7..255d857e2 100644 --- a/util/comman_test.go +++ b/util/comman_test.go @@ -99,3 +99,9 @@ func TestDiskUsage(t *testing.T) { func TestGetCurrentDir(t *testing.T) { t.Log(GetCurrentDir()) } + +func TestCopyFile(t *testing.T) { + if err := CopyFile("/tmp/test2.zip", "/tmp/test4.zip"); err != nil { + t.Fatal(err) + } +}