七天用Go写个docker(完结篇)

今天是最后一天了,我们最后将容器的停止,删除功能实现一下

容器停止

在上一节中,我们通过config.json 记录了容器的基本信息,其中就有一个status字段用来记录容器的状态,和一个PID字段记录容器的init进程在宿主机上的Pid,我们停止容器,也就是将该pid进程杀死,并更新status状态即可

// 停止容器,修改容器状态
func StopContainer(containerName string) {
	info, err := getContainerInfo(containerName)
	if err != nil {
		logrus.Errorf("get container info, err: %v", err)
		return
	}
	if info.Pid != "" {
		pid, _ := strconv.Atoi(info.Pid)
		// 杀死进程
		if err := syscall.Kill(pid, syscall.SIGTERM); err != nil {
			logrus.Errorf("stop container, pid: %d, err: %v", pid, err)
			return
		}
		// 修改容器状态
		info.Status = common.Stop
		info.Pid = ""
		bs, _ := json.Marshal(info)
		fileName := path.Join(common.DefaultContainerInfoPath, containerName, common.ContainerInfoFileName)
		err := ioutil.WriteFile(fileName, bs, 0622)
		if err != nil {
			logrus.Errorf("write container config.json, err: %v", err)
		}
	}
}

删除容器

首先这里需要明确,我们是不能删除正在运行的容器的,也就是statusRunning的容器,所以我们删除容器之前一定要先停止容器,然后我们将该容器生成的一系列文件夹删除即可

// 删除容器
func RemoveContainer(containerName string) {
	info, err := getContainerInfo(containerName)
	if err != nil {
		logrus.Errorf("get container info, err: %v", err)
		return
	}
	// 只能删除停止状态的容器
	if info.Status != common.Stop {
		logrus.Errorf("can't remove running container")
		return
	}
	dir := path.Join(common.DefaultContainerInfoPath, containerName)
	err = os.RemoveAll(dir)
	if err != nil {
		logrus.Errorf("remove container dir: %s, err: %v", dir, err)
		return
	}
}

到这里我们《七天用Go写个docker》系统文章就结束了,最后感谢大家的关注与支持!文章全部源码已在GitHub开源,点击这里查看

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章