在上篇中我們實現了通過exec命令,重新進入了后臺運行中的容器,本篇將實現stop命令,將運行中的容器停止
同時放到了Gitee和Github上,都可進行獲取
本章節對應的版本標簽是:5.5,防止后面代碼過多,不好查看,可切換到標簽版本進行查看
實現該功能的主要思路如下:
docker停止所有容器、1 首先根據容器名稱,定位到其配置文件
2 讀取配置文件,得到容器的PID,發送kill信號,停止進程,這樣容器運行也停止了
3 將相關的停止信息更新寫入配置文件中進行保存
在main函數中新增stop命令:
func main() {app.Commands = []cli.Command{command.InitCommand,command.RunCommand,command.CommitCommand,command.ListCommand,command.LogCommand,command.ExecCommand,command.StopCommand,}
}
main_command.go新增相關的命令:
var StopCommand = cli.Command{Name: "stop",Usage: "stop container",Action: func(context *cli.Context) {if len(context.Args()) < 1 {log.Errorf("missing container name")return}containerName := context.Args().Get(0)if err := run.StopContainer(containerName); err != nil {log.Errorf("stop container err: %v", err)}},
}
docker容器自動停止原因,我們根據容器名稱,找到容器的配置文件的存放位置
讀取配置文件后,我們能得到容器在宿主機上的PID
更加PID,我們就能發送kill命令,去停止容器
停止容器后,將配置文件中的容器狀態改為停止,然后更新存儲配置文件
具體的代碼實現如下:
func StopContainer(containerName string) error {// 根據容器名稱,得到PIDpid, err := getContainerPidByName(containerName)if err != nil {return err}pidInt, err := strconv.Atoi(pid)if err != nil {return fmt.Errorf("convert pid %s to int err: %v", pid, err)}// 發送kill名稱,停止容器進程if err := syscall.Kill(pidInt, syscall.SIGTERM); err != nil {return fmt.Errorf("send sigterm %d, err: %v", pid, err)}// 更新存儲容器信息containerInfo, err := getContainerInfoByName(containerName)if err != nil {return fmt.Errorf("get container info err: %v", err)}containerInfo.Status = container.STOPcontainerInfo.Pid = ""newContainerInfo, err := json.Marshal(containerInfo)if err != nil {return fmt.Errorf("json marshal %v,err: %v", containerInfo, err)}dirUrl := fmt.Sprintf(container.DefaultInfoLocation, containerName)configPath := dirUrl + container.ConfigNameif err := ioutil.WriteFile(configPath, newContainerInfo, 0622); err != nil {return fmt.Errorf("write file %s err: %v", configPath, err)}return nil
}
docker暫停容器、上面的代碼中用到了兩個函數,一個是根據容器名稱得到容器的PID,一個是根據容器名稱得到容器的配置(根據這兩個好像可以優化下,拿到了容器的配置,里面就有容器的PID了,讀者感興趣的話可以試試)
func getContainerPidByName(containerName string) (string, error) {dirUrl := fmt.Sprintf(container.DefaultInfoLocation, containerName)configFilePath := dirUrl + container.ConfigNamecontentBytes, err := ioutil.ReadFile(configFilePath)if err != nil {return "", fmt.Errorf("read file %s err: %v", configFilePath, err)}var containerInfo container.ContainerInfoif err := json.Unmarshal(contentBytes, &containerInfo); err != nil {return "", fmt.Errorf("json ummarshal err: %v", err)}return containerInfo.Pid, nil
}func getContainerInfoByName(containerName string) (*container.ContainerInfo, error) {dirUrl := fmt.Sprintf(container.DefaultInfoLocation, containerName)configFilePath := dirUrl + container.ConfigNamecontentBytes, err := ioutil.ReadFile(configFilePath)if err != nil {return nil, fmt.Errorf("read file %s err: %v", configFilePath, err)}var containerInfo container.ContainerInfoif err := json.Unmarshal(contentBytes, &containerInfo); err != nil {return nil, fmt.Errorf("json ummarshal err: %v", err)}return &containerInfo, nil
}
我們測試如下:
root@lw-Code-01-Series-PF5NU1G ~/code/go/dockerDemo main ● ./main run --name bird -d top ? ? 417 07:28:53
{"level":"info","msg":"memory cgroup path: /sys/fs/cgroup/memory/mydocker-cgroup","time":"2022-04-09T07:29:00+08:00"}
{"level":"info","msg":"memory cgroup path: /sys/fs/cgroup/memory/mydocker-cgroup","time":"2022-04-09T07:29:00+08:00"}
{"level":"info","msg":"all command is : top","time":"2022-04-09T07:29:00+08:00"}
{"level":"info","msg":"parent process run","time":"2022-04-09T07:29:00+08:00"}root@lw-Code-01-Series-PF5NU1G ~/code/go/dockerDemo main ● ./main ps SIG(127) ? ? 418 07:29:00
ID NAME PID STATUS COMMAND CREATED
1808352378 bird 126298 running top 9000-04-04 00:00:00root@lw-Code-01-Series-PF5NU1G ~/code/go/dockerDemo main ● ps -ef|grep top ? ? 419 07:29:05
root 2751 1776 0 4月07 ? 00:00:01 /usr/libexec/xdg-desktop-portal
root 2778 1776 0 4月07 ? 00:00:00 /usr/libexec/xdg-desktop-portal-gtk
root 126298 1 0 07:28 pts/2 00:00:00 top
root 126537 22616 0 07:29 pts/2 00:00:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox toproot@lw-Code-01-Series-PF5NU1G ~/code/go/dockerDemo main ● ./main stop bird ? ? 420 07:29:09root@lw-Code-01-Series-PF5NU1G ~/code/go/dockerDemo main ● ./main ps ? ? 421 07:29:20
ID NAME PID STATUS COMMAND CREATED
1808352378 bird stop top 9000-04-04 00:00:00root@lw-Code-01-Series-PF5NU1G ~/code/go/dockerDemo main ● ps -ef|grep top ? ? 422 07:29:24
root 2751 1776 0 4月07 ? 00:00:01 /usr/libexec/xdg-desktop-portal
root 2778 1776 0 4月07 ? 00:00:00 /usr/libexec/xdg-desktop-portal-gtk
root 126883 22616 0 07:29 pts/2 00:00:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox top
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态