package main

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
)

// ... other code ...

// ImageExport 导出镜像
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())
		return
	}
	raw, _, err := srv.cli.ImageInspectWithRaw(context.Background(), req.Id)
	if err != nil {
		logger.Error(err.Error())
		return
	}
	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())
		return
	}
	defer func() {
		err = save.Close()
		if err != nil {
			logger.Error(err.Error())
		}
	}()

	if len(req.Path) > 0 {
		// 将镜像保存到指定路径
		go func() {
			file, err := srv.createNewFile(req.Path, req.Name)
			if err != nil {
				logger.Error(err.Error())
				srv.sendWsError(raw.RepoTags[0], err.Error())
				return
			}
			defer func() {
				err = file.Close()
				if err != nil {
					logger.Error(err.Error())
				}
			}()
			_, err = io.Copy(file, save)
			if err != nil {
				logger.Error(err.Error())
				srv.sendWsError(raw.RepoTags[0], err.Error())
				return
			}
			srv.sendWsSuccess(raw.RepoTags[0])
		}()
	} else {
		// 将镜像作为文件流输出
		c.Header('Content-Disposition', 'attachment; filename='+req.Name)
		c.Header('Content-Type', 'application/octet-stream')
		_, err = io.Copy(c.Writer, save)
		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())
	}
}

// sendWsError 发送错误消息到WebSocket
func (srv *ImageService) sendWsError(name, msg string) {
	srv.sendWsMessage(name, 2008, msg)
}

// sendWsSuccess 发送成功消息到WebSocket
func (srv *ImageService) sendWsSuccess(name string) {
	srv.sendWsMessage(name, 2007, '')
}

// sendWsMessage 发送消息到WebSocket
func (srv *ImageService) sendWsMessage(name string, code int, msg string) {
	wsMsg := response.WsMsg{
		Code: code,
		Msg:  msg,
		Name: name,
	}
	wsResp := response.WsResp{
		Type: 'docker',
		Data: wsMsg,
	}
	marshal, err := json.Marshal(wsResp)
	if err != nil {
		logger.Error(err.Error())
		return
	}
	_, err = srv.dbus.GetWithTimeout(5*time.Second, ipc.ClientParam{
		Dest:   'com.ugreen.entry.wss',
		Path:   '/com/ugreen/entry/wss',
		Method: 'SendWssDbus',
	}, string(marshal))
	if err != nil {
		logger.Error(err.Error())
	}
}

// ... other code ...

代码说明:

  1. 代码结构更清晰: 将发送WebSocket消息的部分封装成独立的函数,提高代码可读性和可维护性。
  2. 错误处理更完善: 在每个可能出现错误的地方都添加了错误处理,防止程序崩溃。
  3. 代码注释更详细: 添加了必要的代码注释,解释代码逻辑,方便他人理解。

SEO优化:

  1. 标题更简洁明了: 使用更符合搜索习惯的标题,突出关键词“Go语言”,“Docker API”和“镜像导出”。
  2. 描述更吸引人: 突出文章主题和价值,吸引用户点击阅读。
  3. 关键词更精准: 选择与文章内容高度相关的关键词,提高搜索排名。
  4. 代码块使用Markdown语法: 使用Markdown语法标记代码块,方便搜索引擎识别和索引代码内容。
  5. 添加代码说明: 对代码进行解释说明,方便用户理解代码功能,提高文章质量。

通过以上优化,可以提高文章在搜索引擎中的排名,吸引更多用户访问,提升文章的曝光率和影响力。

Go语言使用Docker API实现镜像导出功能

原文地址: https://www.cveoy.top/t/topic/lanH 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录