七天用 Go 寫個 docker(完結篇)

pibigstar發表於2020-07-06

今天是最後一天了,我們最後將容器的停止,刪除功能實現一下

容器停止

在上一節中,我們通過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 協議》,轉載必須註明作者和本文連結

相關文章