1 Star 0 Fork 0

MJreams/docker

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
run.go 3.81 KB
一键复制 编辑 原始数据 按行查看 历史
MJreams 提交于 2024-01-08 12:37 . 构建容器
/**
* @Author MJreams
* @Time 2024/1/8 10:17:00
*
**/
package main
import (
"encoding/json"
"fmt"
"math/rand"
"os"
"strconv"
"strings"
"time"
log "github.com/Sirupsen/logrus"
"github.com/mydocker/cgroups"
"github.com/mydocker/cgroups/subsystems"
"github.com/mydocker/container"
"github.com/mydocker/network"
)
func Run(tty bool, comArray []string, res *subsystems.ResourceConfig, containerName, volume, imageName string,
envSlice []string, nw string, portmapping []string) {
containerID := randStringBytes(10)
if containerName == "" {
containerName = containerID
}
// Run 执行具体 command
/*
这里的Start方法是真正开始前面创建好的command的调用,它首先会clone出来一个namespace隔离的
进程,然后在子进程中,调用/proc/self/exe,也就是调用自己,发送init参数,调用我们写的init方法,
去初始化容器的一些资源。
*/
parent, writePipe := container.NewParentProcess(tty, containerName, volume, imageName, envSlice)
if parent == nil {
log.Errorf("New parent process error")
return
}
if err := parent.Start(); err != nil {
log.Error(err)
}
//record container info
containerName, err := recordContainerInfo(parent.Process.Pid, comArray, containerName, containerID, volume)
if err != nil {
log.Errorf("Record container info error %v", err)
return
}
// use containerID as cgroup name
cgroupManager := cgroups.NewCgroupManager(containerID)
defer cgroupManager.Destroy()
cgroupManager.Set(res)
cgroupManager.Apply(parent.Process.Pid)
if nw != "" {
// config container network
network.Init()
containerInfo := &container.ContainerInfo{
Id: containerID,
Pid: strconv.Itoa(parent.Process.Pid),
Name: containerName,
PortMapping: portmapping,
}
if err := network.Connect(nw, containerInfo); err != nil {
log.Errorf("Error Connect Network %v", err)
return
}
}
sendInitCommand(comArray, writePipe)
if tty {
parent.Wait()
deleteContainerInfo(containerName)
container.DeleteWorkSpace(volume, containerName)
}
}
func sendInitCommand(comArray []string, writePipe *os.File) {
command := strings.Join(comArray, " ")
log.Infof("command all is %s", command)
writePipe.WriteString(command)
writePipe.Close()
}
func recordContainerInfo(containerPID int, commandArray []string, containerName, id, volume string) (string, error) {
createTime := time.Now().Format("2006-01-02 15:04:05")
command := strings.Join(commandArray, "")
containerInfo := &container.ContainerInfo{
Id: id,
Pid: strconv.Itoa(containerPID),
Command: command,
CreatedTime: createTime,
Status: container.RUNNING,
Name: containerName,
Volume: volume,
}
jsonBytes, err := json.Marshal(containerInfo)
if err != nil {
log.Errorf("Record container info error %v", err)
return "", err
}
jsonStr := string(jsonBytes)
dirUrl := fmt.Sprintf(container.DefaultInfoLocation, containerName)
if err := os.MkdirAll(dirUrl, 0622); err != nil {
log.Errorf("Mkdir error %s error %v", dirUrl, err)
return "", err
}
fileName := dirUrl + "/" + container.ConfigName
file, err := os.Create(fileName)
defer file.Close()
if err != nil {
log.Errorf("Create file %s error %v", fileName, err)
return "", err
}
if _, err := file.WriteString(jsonStr); err != nil {
log.Errorf("File write string error %v", err)
return "", err
}
return containerName, nil
}
func deleteContainerInfo(containerId string) {
dirURL := fmt.Sprintf(container.DefaultInfoLocation, containerId)
if err := os.RemoveAll(dirURL); err != nil {
log.Errorf("Remove dir %s error %v", dirURL, err)
}
}
func randStringBytes(n int) string {
letterBytes := "1234567890"
rand.Seed(time.Now().UnixNano())
b := make([]byte, n)
for i := range b {
b[i] = letterBytes[rand.Intn(len(letterBytes))]
}
return string(b)
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/mjreams/docker.git
git@gitee.com:mjreams/docker.git
mjreams
docker
docker
master

搜索帮助

D67c1975 1850385 1daf7b77 1850385