Skip to content

Commit

Permalink
add code 5.2
Browse files Browse the repository at this point in the history
  • Loading branch information
xianlubird authored and Xianlu committed Jan 11, 2017
1 parent 6ea35e4 commit 6fac480
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 14 deletions.
17 changes: 17 additions & 0 deletions container/container_process.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@ import (
"syscall"
)

var (
RUNNING string = "running"
STOP string = "stopped"
Exit string = "exited"
DefaultInfoLocation string = "/var/run/mydocker/%s/"
ConfigName string = "config.json"
)

type ContainerInfo struct {
Pid string `json:"pid"` //容器的init进程在宿主机上的 PID
Id string `json:"id"` //容器Id
Name string `json:"name"` //容器名
Command string `json:"command"` //容器内init运行命令
CreatedTime string `json:"createTime"` //创建时间
Status string `json:"status"` //容器的状态
}

func NewParentProcess(tty bool) (*exec.Cmd, *os.File) {
readPipe, writePipe, err := NewPipe()
if err != nil {
Expand Down
65 changes: 65 additions & 0 deletions list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package main

import (
"encoding/json"
"fmt"
log "github.com/Sirupsen/logrus"
"github.com/xianlubird/mydocker/container"
"io/ioutil"
"os"
"text/tabwriter"
)

func ListContainers() {
dirURL := fmt.Sprintf(container.DefaultInfoLocation, "")
dirURL = dirURL[:len(dirURL)-1]
files, err := ioutil.ReadDir(dirURL)
if err != nil {
log.Errorf("Read dir %s error %v", dirURL, err)
return
}

var containers []*container.ContainerInfo
for _, file := range files {
tmpContainer, err := getContainerInfo(file)
if err != nil {
log.Errorf("Get container info error %v", err)
continue
}
containers = append(containers, tmpContainer)
}

w := tabwriter.NewWriter(os.Stdout, 12, 1, 3, ' ', 0)
fmt.Fprint(w, "ID\tNAME\tPID\tSTATUS\tCOMMAND\tCREATED\n")
for _, item := range containers {
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n",
item.Id,
item.Name,
item.Pid,
item.Status,
item.Command,
item.CreatedTime)
}
if err := w.Flush(); err != nil {
log.Errorf("Flush error %v", err)
return
}
}

func getContainerInfo(file os.FileInfo) (*container.ContainerInfo, error) {
containerName := file.Name()
configFileDir := fmt.Sprintf(container.DefaultInfoLocation, containerName)
configFileDir = configFileDir + container.ConfigName
content, err := ioutil.ReadFile(configFileDir)
if err != nil {
log.Errorf("Read file %s error %v", configFileDir, err)
return nil, err
}
var containerInfo container.ContainerInfo
if err := json.Unmarshal(content, &containerInfo); err != nil {
log.Errorf("Json unmarshal error %v", err)
return nil, err
}

return &containerInfo, nil
}
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func main() {
app.Commands = []cli.Command{
initCommand,
runCommand,
listCommand,
}

app.Before = func(context *cli.Context) error {
Expand Down
31 changes: 22 additions & 9 deletions main_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ import (
"fmt"
log "github.com/Sirupsen/logrus"
"github.com/urfave/cli"
"github.com/xianlubird/mydocker/container"
"github.com/xianlubird/mydocker/cgroups/subsystems"
"github.com/xianlubird/mydocker/container"
)

var runCommand = cli.Command{
Name: "run",
Usage: `Create a container with namespace and cgroups limit
mydocker run -ti [command]`,
Usage: `Create a container with namespace and cgroups limit ie: mydocker run -ti [command]`,
Flags: []cli.Flag{
cli.BoolFlag{
Name: "ti",
Expand All @@ -22,17 +21,21 @@ var runCommand = cli.Command{
Usage: "detach container",
},
cli.StringFlag{
Name: "m",
Name: "m",
Usage: "memory limit",
},
cli.StringFlag{
Name: "cpushare",
Name: "cpushare",
Usage: "cpushare limit",
},
cli.StringFlag{
Name: "cpuset",
Name: "cpuset",
Usage: "cpuset limit",
},
cli.StringFlag{
Name: "name",
Usage: "container name",
},
},
Action: func(context *cli.Context) error {
if len(context.Args()) < 1 {
Expand All @@ -50,11 +53,12 @@ var runCommand = cli.Command{
}
resConf := &subsystems.ResourceConfig{
MemoryLimit: context.String("m"),
CpuSet: context.String("cpuset"),
CpuShare:context.String("cpushare"),
CpuSet: context.String("cpuset"),
CpuShare: context.String("cpushare"),
}
log.Infof("createTty %v", createTty)
Run(createTty, cmdArray, resConf)
containerName := context.String("name")
Run(createTty, cmdArray, resConf, containerName)
return nil
},
}
Expand All @@ -68,3 +72,12 @@ var initCommand = cli.Command{
return err
},
}

var listCommand = cli.Command{
Name: "ps",
Usage: "list all the containers",
Action: func(context *cli.Context) error {
ListContainers()
return nil
},
}
83 changes: 78 additions & 5 deletions run.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package main

import (
"github.com/xianlubird/mydocker/container"
"github.com/xianlubird/mydocker/cgroups/subsystems"
"github.com/xianlubird/mydocker/cgroups"
"encoding/json"
"fmt"
log "github.com/Sirupsen/logrus"
"github.com/xianlubird/mydocker/cgroups"
"github.com/xianlubird/mydocker/cgroups/subsystems"
"github.com/xianlubird/mydocker/container"
"math/rand"
"os"
"strconv"
"strings"
"time"
)


func Run(tty bool, comArray []string, res *subsystems.ResourceConfig) {
func Run(tty bool, comArray []string, res *subsystems.ResourceConfig, containerName string) {
parent, writePipe := container.NewParentProcess(tty)
if parent == nil {
log.Errorf("New parent process error")
Expand All @@ -19,6 +23,14 @@ func Run(tty bool, comArray []string, res *subsystems.ResourceConfig) {
if err := parent.Start(); err != nil {
log.Error(err)
}

//record container info
containerName, err := recordContainerInfo(parent.Process.Pid, comArray, containerName)
if err != nil {
log.Errorf("Record container info error %v", err)
return
}

// use mydocker-cgroup as cgroup name
cgroupManager := cgroups.NewCgroupManager("mydocker-cgroup")
defer cgroupManager.Destroy()
Expand All @@ -28,6 +40,7 @@ func Run(tty bool, comArray []string, res *subsystems.ResourceConfig) {
sendInitCommand(comArray, writePipe)
if tty {
parent.Wait()
deleteContainerInfo(containerName)
}
}

Expand All @@ -37,3 +50,63 @@ func sendInitCommand(comArray []string, writePipe *os.File) {
writePipe.WriteString(command)
writePipe.Close()
}

func recordContainerInfo(containerPID int, commandArray []string, containerName string) (string, error) {
id := randStringBytes(10)
createTime := time.Now().Format("2006-01-02 15:04:05")
command := strings.Join(commandArray, "")
if containerName == "" {
containerName = id
}
containerInfo := &container.ContainerInfo{
Id: id,
Pid: strconv.Itoa(containerPID),
Command: command,
CreatedTime: createTime,
Status: container.RUNNING,
Name: containerName,
}

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)
}

0 comments on commit 6fac480

Please sign in to comment.