七天用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開源,點擊這裏查看

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