折腾了一周多,终于搞定了在docker的python API下,当执行exec_run时,如何连接container的PTY。
当弄明白之后,才发现原来是那么简单。之前几乎搜遍了google和百度,都没有找到相关的文章
前言
这两年,docker的发展如火如荼,作为网络测试,我们也在尝试着将docker引入测试中,来更多的模拟真实用户,并实现自动化。
Pexpect是一个非常强大且好用的工具,当需要与设备和PC连接时,基本上都会用到。而之前都直接使用spawn一个命令行来进行连接
本篇博文将介绍一种使用pexpect的fdspawn,通过socket方式连接到container的方法,以便与远程的container进行交互
自动化思路
- client通过python API连接到docker
- 创建一个container并保持运行
- 使用exec_run()新建一个连接,运行
/bin/bash
,并开启socket方式
- 使用pexpect的fdspawn连接exec_run()返回的socket
环境准备
参见之前博文
安装必要的包
1 2
| $ pip install docker $ pip install pexpect
|
开始使用
1 2 3
| >>> import docker >>> client=docker.DockerClient(base_url='tcp://10.0.0.10:1234') >>> c1 = client.containers.run("ubuntu", detach=True, tty=True)
|
1 2 3 4 5 6
| >>> res = c1.exec_run("/bin/bash", socket=True, stdin=True, tty=True) >>> res ExecResult(exit_code=None, output=<socket object, fd=15, family=1, type=1, protocol=0>) >>> sock = res.output >>> sock <socket object, fd=15, family=1, type=1, protocol=0>
|
1 2 3 4 5 6 7 8 9 10 11
| >>> import pexpect.fdpexpect >>> session=pexpect.fdpexpect.fdspawn(sock.fileno(),timeout=10) >>> >>> session.send("ls\n") 3 >>> session.expect("#") 0 >>> session.before ' ls\r\n\x1b[0m\x1b[01;34mbin\x1b[0m \x1b[01;34mdev\x1b[0m \x1b[01;34mhome\x1b[0m \x1b[01;34mlib64\x1b[0m \x1b[01;34mmnt\x1b[0m \x1b[01;34mproc\x1b[0m \x1b[01;34mrun\x1b[0m \x1b[01;34msrv\x1b[0m \x1b[30;42mtmp\x1b[0m \x1b[01;34mvar\x1b[0m\r\n\x1b[01;34mboot\x1b[0m \x1b[01;34metc\x1b[0m \x1b[01;34mlib\x1b[0m \x1b[01;34mmedia\x1b[0m \x1b[01;34mopt\x1b[0m \x1b[01;34mroot\x1b[0m \x1b[01;34msbin\x1b[0m \x1b[01;34msys\x1b[0m \x1b[01;34musr\x1b[0m\r\n\x1b]0;root@6a097ddbe55d: /\x07root@6a097ddbe55d:/' >>> session.after '#' >>>
|
注意事项
- 在使用exec_run()执行开启命令时,需要指定
stdin=True
,否则,pexpect的send()将无法将命令发送至container
- 同样,在使用exec_run()时,需要指定
tty=True
,否则,将没有命令行提示符,无法进行匹配