gin框架使用websocket实现进入容器内部执行命令

文章目录

  • 1. 先决条件
  • 2. gin框架实现
  • 3. 测试用html文件
  • 4. 需要完善

1. 先决条件

docker开放远程API端口

2. gin框架实现

type GetCommandResultRequire struct {
	IpAddr        string `json:"ip_addr"` //传入要控制容器的ip地址
	ContainerUuid string `json:"container_uuid"` //容器id
}

func GetCommendResult(c *gin.Context) {

	var sendCommandRequire GetCommandResultRequire
	sendCommandRequire.IpAddr = c.Query("ip_addr")
	sendCommandRequire.ContainerUuid = c.Query("container_uuid")

	//升级接口
	ws, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		fmt.Print("升级websocket连接错误:", err)
		return
	}
	defer ws.Close()

    execHr := new(types.HijackedResponse)
	dockerCli, err := ConnectDocker(sendCommandRequire.IpAddr)
	if err != nil {
		tools.SetErr(c, 500, err, err.Error())//此处是自己实现的gin返回
		return
	}

	//启动携程,持续接收信息、传入命令、异常关闭docker链接
	go func() {
		for {
			_, message, err := ws.ReadMessage()
			if err != nil {
				logger.Error("接口断开:", err)
				execHr.Close()
				ws.Close()
				return
			}
			logger.Info(string(message))
			//发送命令
			err = SendCommend(string(message), execHr)
			if err != nil {
				logger.Error("命令发送错误")
			}
		}
	}()

	err = ExecContainer(dockerCli, execHr, ws, sendCommandRequire.ContainerUuid)
	if err != nil {
		tools.SetErr(c, 500, err, err.Error())
		return
	}
	logger.Info("链接关闭")
}

//定义一个函数,链接容器,并持续输出。
func ExecContainer(dockerCli *client.Client, execHr *types.HijackedResponse, conn *websocket.Conn, containerId string) error {

	ctx := context.Background()
	// 在指定容器中执行/bin/bash命令
	ir, err := dockerCli.ContainerExecCreate(ctx, containerId, types.ExecConfig{
		AttachStdin:  true,
		AttachStdout: true,
		AttachStderr: true,
		Cmd:          []string{"/bin/sh"},
		Tty:          true,
	})
	if err != nil {
		return err
	}

	// 保持链接
	*execHr, err = dockerCli.ContainerExecAttach(ctx, ir.ID, types.ExecStartCheck{Detach: false, Tty: true})
	if err != nil {
		return err
	}

	//关闭I/O
	defer execHr.Close()

	// 输入一个测试命令(非必要)
	_, err = execHr.Conn.Write([]byte("ls\r"))
	if err != nil {
		return err
	}

	// 输出
	scanner := bufio.NewScanner(execHr.Conn)
	for scanner.Scan() {
		fmt.Println(scanner.Text())
		text := scanner.Text()
		b, _ := json.Marshal(text)
		err = conn.WriteMessage(websocket.TextMessage, b)
		if err != nil {
			log.Println("写入错误", err)
			//return err
			continue
		}
	}
	logger.Info("容器输出结束")
	return nil
}

//写一个函数,向容器中发送命令。
func SendCommend(cmdString string, execHr *types.HijackedResponse) (err error) {

	_, err = execHr.Conn.Write([]byte(cmdString + "\r"))
	if err != nil {
		return
	}
	return nil
}

3. 测试用html文件

仅是一个测试文件,很丑,但是后端测试够了。

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>TestWebsocket</title>
 
    <script type="text/javascript">
        var Server_Com;
        function LinkServer() {
            // 声明连接
            
            if ("WebSocket" in window) {
                Server_Com = new WebSocket("ws://127.0.0.1:18000/v1/m6e/docker/container/exec?ip_addr=10.10.239.32&container_uuid=48bcf6811212");
                console.log("新建连接到->127.0.0.1:18000");
            }
 
            // 建立连接后发送
            Server_Com.onopen = function() {
 
                Server_Com.send("Hello Server!"); // Web Socket 已连接上,使用 send() 方法发送数据
                console.log("已连接上服务器");
            }
 
            // 接收服务器消息
            Server_Com.onmessage = function(event) {
                var recv_msg = event.data;
 
                if (recv_msg == "Hello Client!") {
                    console.log("接收到服务器的问候: " + recv_msg); // 用于提示收到信息
                } else {
                    document.getElementById("Time").textContent = document.getElementById("Time").textContent + "\r\n" + recv_msg; // 实时更新显示服务器发回的时间
                    console.log("接收到服务器数据: " + recv_msg);
                }
            }
        }

        function SendMessage(){
            var inputMessage = document.getElementById("sendcmd").value;
            Server_Com.send(inputMessage);
        }
    </script>
</head>
 
<body>
    <p>接收到的信息:</p>
    <p id="Time">crow-exec测试</p>
    <button onclick="SendMessage()">发送消息</button>
    <input id="sendcmd" name="sendcmd"></input>
    <button onclick="LinkServer()">连接</button>
 
</body>
</html>

4. 需要完善

vi 编辑器无法实现,需要进一步完善。


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/2549.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

对堆题的总体思路

浅说一下pwn堆并用一个简单的例子具体说明给刚入坑堆的小朋友说的一些思路说一下堆是什么堆你可以看成一个结构体数组&#xff0c;然后数组里每个元素都会开辟一块内存来存储数据那么这块用来存储数据的内存就是堆。结构体数组在BSS段上&#xff0c;其内容就是堆的地址&#xf…

动态SQL必知必会

动态SQL必知必会1、什么是动态SQL2、为什么使用动态SQL3、动态SQL的标签4、if 标签-单标签判断5、choose标签-多条件分支判断6、set 标签-修改语句7、foreach标签7.1 批量查询7.2 批量删除7.3 批量添加8、模糊分页查询1、什么是动态SQL 动态 SQL 是 MyBatis 的强大特性之一。如…

阿里巴巴2017实习生笔试题(二)——总结

具体题目来自阿里巴巴2017实习生笔试题&#xff0c;本文仅为整理与汇总。 本题应该往C的多态性进行理解&#xff0c;多态中的动态链接在执行时进行&#xff0c;静态链接在编译时进行。其中A、C、D 都是动态链接的优点&#xff0c;B 时静态链接的优点。 减少页面交换可从如下角…

nginx-动静分离-防盗链-location-4

动静分离 为了加快网站的解析速度&#xff0c;可以把动态页面和静态页面有不同的服务器来解析&#xff0c;加快机械速度。降低原来单个服务器的压力。在动静分离的tomcat时候比较明显&#xff0c;因为tomcat解析静态很慢&#xff0c;其实这些原理的话很好理解&#xff0c;简单…

Baumer工业相机堡盟万兆网相机如何使用千兆网网卡环境保持帧率不变(C++)

项目场景 Baumer工业相机堡盟相机是一种高性能、高质量的工业相机&#xff0c;可用于各种应用场景&#xff0c;如物体检测、计数和识别、运动分析和图像处理。 Baumer的万兆网相机拥有出色的图像处理性能&#xff0c;可以实时传输高分辨率图像。此外&#xff0c;该相机还具…

IP、MAC和端口

IP&#xff0c;MAC和端口的概念MAC地址也叫物理地址、硬件地址&#xff0c;由网络设备厂家直接烧录在网卡上的&#xff0c;理论上Mac地址是唯一-的。 但因为Mac地址可以通过程序修改&#xff0c;所以也有可能会重复。IP地址是互联网上的每台设备都规定了-一个唯一的地址, 这个地…

网络安全之认识勒索病毒

一、什么是勒索病毒 勒索病毒&#xff0c;是一种新型电脑病毒&#xff0c;伴随数字货币兴起&#xff0c;主要以邮件、程序木马、网页挂马、服务器入侵、捆绑软件等多种形式进行传播&#xff0c;一旦感染将给用户带来无法估量的损失。如果遭受勒索病毒攻击&#xff0c;将会使绝…

如何用C语言实现渣男通讯录

注意&#xff1a;纯属玩笑&#xff0c;博大家一乐&#xff0c;切勿当真&#x1f4d6;首先我们要知道一个渣男通讯录有哪些信息要包含哪些功能1.你的通讯录要装多少个女朋友你得规定吧&#xff1b;2.每个女朋友的姓名&#xff0c;年龄&#xff0c;电话&#xff0c;爱好这些要有吧…

第29次CCFCSP认证经验总结

鄙人有幸参加了由中国计算机学会举办的第29次计算机软件能力认证考试&#xff0c;在此进行一些考试细节和经验的总结。 如果没有仔细了解过的小白去网上搜索CCFCSP&#xff0c;可能出现的是CSP-J/S&#xff0c;但是详细了解会发现&#xff0c;首先CSP-J/S分初试和复试&#xff…

.NET/C#/GC与内存管理(含深度解析)

详情请看参考文章&#xff1a;.NET面试题解析(06)-GC与内存管理 - 不灬赖 - 博客园 (cnblogs.com)一、对象创建及生命周期一个对象的生命周期简单概括就是&#xff1a;创建>使用>释放&#xff0c;在.NET中一个对象的生命周期&#xff1a;new创建对象并分配内存对象初始化…

【Linux】浅谈shell命令以及运行原理

前言&#xff1a;上篇博文把linux下的基本指令讲解完了。本期我们聊聊Linux下【shell】命令及其运行原理。 目录 Shell的基本概念与作用 原理图展示 shell命令执行原理 Shell的基本概念与作用 Linux严格意义上说的是一个操作系统&#xff0c;我们称之为“核心&#xff08;ker…

文心一言 VS ChatGPT,国产大模型和国外的差距有多大?

3月16号&#xff0c;百度正式发布了『文心一言』&#xff0c;这是国内公司第一次发布类ChatGPT的产品。大家一定非常好奇文心一言和chatgpt之间的差距有多大&#xff1f;国产大模型还有多少路可走&#xff1f;本文就全面测评这两款产品&#xff01; 目录 体验网址 1、旅游攻…

【vue2】vue2中的性能优化(持续更新中)

⭐ v-for 遍历避免同时使用 v-if ⭐ v-for 中的key绑定唯一的值 ⭐ v-show与v-if对性能的影响 ⭐ 妙用计算属性 ⭐ 使用防抖与节流控制发送频率 ⭐ 路由守卫处理请求避免重复发送请求 ⭐ 使用第三方UI库的引入方式 【前言】 该系列是博主在使用vue2开发项目中常用上的一…

这些IT行业趋势,将改变2023

上一周&#xff0c;你被"AI"刷屏了吗&#xff1f; 打开任何一家科技媒体&#xff0c;人工智能都是不变的热门话题。周初大家还在用ChatGPT写论文、查资料、写代码&#xff0c;到周末的时候大家已经开始用GPT-4图像识别来做饭、Microsoft 365 Copilot 来写PPT了。 GP…

【Linux】Linux基本指令(下)

前言&#xff1a; 紧接上期【Linux】基本指令&#xff08;上&#xff09;的学习&#xff0c;今天我们继续学习基本指令操作&#xff0c;深入探讨指令的基本知识。 目录 &#xff08;一&#xff09;常用指令 &#x1f449;more指令 &#x1f449;less指令&#xff08;重要&…

【动手学深度学习】(task1)注意力机制剖析

note 将注意力汇聚的输出计算可以作为值的加权平均&#xff0c;选择不同的注意力评分函数会带来不同的注意力汇聚操作。当查询和键是不同长度的矢量时&#xff0c;可以使用可加性注意力评分函数。当它们的长度相同时&#xff0c;使用缩放的“点&#xff0d;积”注意力评分函数…

【问题系列】vue当编辑框被触发就出现保存按钮

目录 问题描述&#xff1a; 解决方案&#xff1a; 1.方案一 2.方案二 3.方案三 问题描述&#xff1a; 一个表单用vue的事件实现当点击编辑按钮(或图标)出现保存按钮&#xff0c;当要编辑的时候只出现编辑按钮&#xff0c;此时保存按钮隐藏 解决方案&#xff1a; 1.方案一…

C++演讲比赛流程管理系统_黑马

任务 学校演讲比赛&#xff0c;12人&#xff0c;两轮&#xff0c;第一轮淘汰赛&#xff0c;第二轮决赛 选手编号 [ 10001 - 10012 ] 分组比赛 每组6人 10个评委 去除最高分 最低分&#xff0c;求平均分 为该轮成绩 每组淘汰后三名&#xff0c;前三名晋级决赛 决赛 前三名胜出 …

KDGX-A光缆故障断点检测仪

一、产品概述 KDGX-A光纤寻障仪是武汉凯迪正大为光纤网络领域施工、测试、维护所设计的一款测试仪表。可实现对光纤链路状态和故障的快速分析&#xff0c;适用于室外维护作业&#xff0c;是现场光纤网络测试与维护中替代OTDR的经济型解决方案。 二、主要特点 1)一键式光纤链路…

基于文心一言的底层视觉理解,百度网盘把「猫」换成了「黄色的猫」

随着移动互联网的一路狂飙&#xff0c;手机已经成为人们的新器官。出门不带钥匙可以&#xff0c;不带手机却是万万不可以的。而手机上&#xff0c;小小的摄像头也越来越成为各位「vlogger」的口袋魔方。每天有超过数亿的照片和视频被上传到百度网盘中&#xff0c;这些照片和视频…
最新文章