1.实现容器的后台运行, -d Flag
①在runCommand中加入-d Flag
cli.BoolFlag{
Name: "d",
Usage: "detach container",
}
②-d和-ti不能同时存在
createTty := context.Bool("ti")
detach := context.Bool("d")
if createTty && detach {
return fmt.Errorf("ti and d paramter can not both provided")
}
③在run.go中,使parent进程自动退出,这样就直接进入到了后台运行状态.
//if tty表示detach是true
if tty {
parent.Wait()
}
2.实现查看运行容器, ps
在容器运行时要记录容器的运行信息
在run.go中的recordContainerInfo中
①利用随机数生成一个容器id
②创建一个containerInfo的接口,里面存放ID,pid,command等信息
③将containerinfo转换为json格式
④将containerinfo存入一以下这个文件中
DefaultInfoLocation string = "/var/run/mydocker/%s/" //%s为containername
ConfigName string = "config.json"
在ps时查看容器信息
①调用listCommand中listContainers
其核心是在于遍历DefaultInfoLocation 中所有的containername
然后读取里面的config.json中的内容.
3.实现查看容器日志 logs
在容器运行时要记录容器的运行信息
①创建日志文件,其创建位置以及创建的策略与ps中一致。
②将容器运行的输出方式从标准输出改为日志文件。
cmd.Stdout = stdLogFile
在logs时读取日志信息
就是打开上面的文件,然后再读取的方式进行的。
4.实现进入容器Namespace
进入namespace的意义。就是类似于从后台容器的角度,运行某些指令,使得
后台容器与运行在前台一样。
Cgo
是一种在Go语言中使用C语言的方法。这也是为什么有些GO语言中有C语言的代码。
EnterNamespace函数
①判断环境变量,mydocker_pid与mydocker_cmd是否存在。
②打开namespace所在的文件。
③使用setns系统调用,来进入到namespace中。
④使用system(mydocker_cmd)来调用余下的命令.
ExecContainer函数
①根据containername获得pid
②重新创建一个exec的指令
cmd := exec.Command("/proc/self/exe", "exec")
③设置环境变量,只有设置了环境变量以后,调用EnterNamespace才会有效。
④重新执行新的exec函数.