func srv ImageService ImageExportc ginContext user string loggerInfoimage export start var req requestImageSaveReq if err = cBindJSON&req; err != nil loggerErrorerrError raw _ err = srvcliImageIns
这个方法中存在两种导出方式:
-
当
req.Path不为空时,使用go func()开启一个新的goroutine处理导出操作。在该goroutine中,通过srv.cli.ImageSave()方法将镜像保存为tar文件,并通过srv.createNewFile()方法创建一个新的文件,然后将tar文件内容写入该文件。在写入过程中,如果发生错误,则通过WebSocket通知前端导出失败。最后,通过WebSocket通知前端导出成功。 -
当
req.Path为空时,直接将镜像保存为tar文件,并通过io.Pipe()创建一个管道,将tar文件内容写入管道。然后将管道的内容通过HTTP响应直接输出给前端。
根据你的需求,如果要将导出的save变成文件流输出给前端,可以修改第二种导出方式。具体修改如下:
func (srv *ImageService) ImageExport(c *gin.Context, user string) {
logger.Info("image export start...")
var req request.ImageSaveReq
if err := c.BindJSON(&req); err != nil {
logger.Error(err.Error())
}
raw, _, err := srv.cli.ImageInspectWithRaw(context.Background(), req.Id)
if err != nil {
logger.Error(err.Error())
}
split := strings.Split(raw.RepoTags[0], ":")
name := split[0] + "(" + split[1] + ")"
save, err := srv.cli.ImageSave(context.Background(), raw.RepoTags)
if err != nil {
logger.Error(err.Error())
}
defer func() {
err = save.Close()
if err != nil {
logger.Error(err.Error())
}
}()
reader, writer := io.Pipe()
go func() {
defer func() {
err = writer.Close()
if err != nil {
logger.Error(err.Error())
}
}()
if err = json.NewEncoder(writer).Encode(save); err != nil {
logger.Error(err.Error())
}
}()
c.Header("Content-Disposition", "attachment; filename="+req.Name)
c.Header("Content-Type", "application/octet-stream")
_, err = io.Copy(c.Writer, reader)
if err != nil {
logger.Error(err.Error())
c.String(http.StatusInternalServerError, "Failed to write response stream")
return
}
c.Status(http.StatusOK)
log := model.DockerLog{
CreateTime: time.Now().Unix(),
Level: 1,
Operator: user,
Content: fmt.Sprintf("Export image file with image name:%s", name),
}
tx := srv.db.Create(&log)
if tx.Error != nil {
logger.Error(tx.Error.Error())
}
}
这样修改后,将会直接将镜像保存为tar文件,并通过HTTP响应将文件内容输出给前端。
原文地址: https://www.cveoy.top/t/topic/inC2 著作权归作者所有。请勿转载和采集!