七天用 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开源,点击这里查看

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 3年前 自动加精
讨论数量: 4

大哥,建个群,我来学习

3年前 评论

大佬能更新下群二维码么 :blush:

3年前 评论

@loda 已更新,后面再失效的话,可以加我微信号(备注go),我拉你们进群

file

file

3年前 评论
loda 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!