瀏覽代碼

Merge pull request #3724 from creack/extract-lxc-phase-2

Refactor process to command
Victor Vieux 11 年之前
父節點
當前提交
0dd856ee7f
共有 7 個文件被更改,包括 107 次插入100 次删除
  1. 64 61
      container.go
  2. 3 3
      execdriver/chroot/driver.go
  3. 10 10
      execdriver/driver.go
  4. 12 10
      execdriver/lxc/driver.go
  5. 4 4
      execdriver/lxc/lxc_template_unit_test.go
  6. 4 4
      runtime.go
  7. 10 8
      sysinit/sysinit.go

+ 64 - 61
container.go

@@ -54,7 +54,7 @@ type Container struct {
 	Name           string
 	Name           string
 	Driver         string
 	Driver         string
 
 
-	process   *execdriver.Process
+	command   *execdriver.Command
 	stdout    *utils.WriteBroadcaster
 	stdout    *utils.WriteBroadcaster
 	stderr    *utils.WriteBroadcaster
 	stderr    *utils.WriteBroadcaster
 	stdin     io.ReadCloser
 	stdin     io.ReadCloser
@@ -307,8 +307,8 @@ func (container *Container) setupPty() error {
 		return err
 		return err
 	}
 	}
 	container.ptyMaster = ptyMaster
 	container.ptyMaster = ptyMaster
-	container.process.Stdout = ptySlave
-	container.process.Stderr = ptySlave
+	container.command.Stdout = ptySlave
+	container.command.Stderr = ptySlave
 
 
 	// Copy the PTYs to our broadcasters
 	// Copy the PTYs to our broadcasters
 	go func() {
 	go func() {
@@ -320,8 +320,8 @@ func (container *Container) setupPty() error {
 
 
 	// stdin
 	// stdin
 	if container.Config.OpenStdin {
 	if container.Config.OpenStdin {
-		container.process.Stdin = ptySlave
-		container.process.SysProcAttr.Setctty = true
+		container.command.Stdin = ptySlave
+		container.command.SysProcAttr.Setctty = true
 		go func() {
 		go func() {
 			defer container.stdin.Close()
 			defer container.stdin.Close()
 			utils.Debugf("startPty: begin of stdin pipe")
 			utils.Debugf("startPty: begin of stdin pipe")
@@ -333,10 +333,10 @@ func (container *Container) setupPty() error {
 }
 }
 
 
 func (container *Container) setupStd() error {
 func (container *Container) setupStd() error {
-	container.process.Stdout = container.stdout
-	container.process.Stderr = container.stderr
+	container.command.Stdout = container.stdout
+	container.command.Stderr = container.stderr
 	if container.Config.OpenStdin {
 	if container.Config.OpenStdin {
-		stdin, err := container.process.StdinPipe()
+		stdin, err := container.command.StdinPipe()
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
@@ -494,6 +494,49 @@ func (container *Container) Attach(stdin io.ReadCloser, stdinCloser io.Closer, s
 	})
 	})
 }
 }
 
 
+func populateCommand(c *Container) {
+	var (
+		en           *execdriver.Network
+		driverConfig []string
+	)
+	if !c.Config.NetworkDisabled {
+		network := c.NetworkSettings
+		en = &execdriver.Network{
+			Gateway:     network.Gateway,
+			Bridge:      network.Bridge,
+			IPAddress:   network.IPAddress,
+			IPPrefixLen: network.IPPrefixLen,
+			Mtu:         c.runtime.config.Mtu,
+		}
+	}
+
+	if lxcConf := c.hostConfig.LxcConf; lxcConf != nil {
+		for _, pair := range lxcConf {
+			driverConfig = append(driverConfig, fmt.Sprintf("%s = %s", pair.Key, pair.Value))
+		}
+	}
+	resources := &execdriver.Resources{
+		Memory:     c.Config.Memory,
+		MemorySwap: c.Config.MemorySwap,
+		CpuShares:  c.Config.CpuShares,
+	}
+	c.command = &execdriver.Command{
+		ID:         c.ID,
+		Privileged: c.hostConfig.Privileged,
+		Rootfs:     c.RootfsPath(),
+		InitPath:   "/.dockerinit",
+		Entrypoint: c.Path,
+		Arguments:  c.Args,
+		WorkingDir: c.Config.WorkingDir,
+		Network:    en,
+		Tty:        c.Config.Tty,
+		User:       c.Config.User,
+		Config:     driverConfig,
+		Resources:  resources,
+	}
+	c.command.SysProcAttr = &syscall.SysProcAttr{Setsid: true}
+}
+
 func (container *Container) Start() (err error) {
 func (container *Container) Start() (err error) {
 	container.Lock()
 	container.Lock()
 	defer container.Unlock()
 	defer container.Unlock()
@@ -605,15 +648,15 @@ func (container *Container) Start() (err error) {
 		return err
 		return err
 	}
 	}
 
 
-	var workingDir string
+	root := container.RootfsPath()
+
 	if container.Config.WorkingDir != "" {
 	if container.Config.WorkingDir != "" {
-		workingDir = path.Clean(container.Config.WorkingDir)
-		if err := os.MkdirAll(path.Join(container.RootfsPath(), workingDir), 0755); err != nil {
+		container.Config.WorkingDir = path.Clean(container.Config.WorkingDir)
+		if err := os.MkdirAll(path.Join(root, container.Config.WorkingDir), 0755); err != nil {
 			return nil
 			return nil
 		}
 		}
 	}
 	}
 
 
-	root := container.RootfsPath()
 	envPath, err := container.EnvConfigPath()
 	envPath, err := container.EnvConfigPath()
 	if err != nil {
 	if err != nil {
 		return err
 		return err
@@ -658,48 +701,7 @@ func (container *Container) Start() (err error) {
 		}
 		}
 	}
 	}
 
 
-	var (
-		en           *execdriver.Network
-		driverConfig []string
-	)
-
-	if !container.Config.NetworkDisabled {
-		network := container.NetworkSettings
-		en = &execdriver.Network{
-			Gateway:     network.Gateway,
-			Bridge:      network.Bridge,
-			IPAddress:   network.IPAddress,
-			IPPrefixLen: network.IPPrefixLen,
-			Mtu:         container.runtime.config.Mtu,
-		}
-	}
-
-	if lxcConf := container.hostConfig.LxcConf; lxcConf != nil {
-		for _, pair := range lxcConf {
-			driverConfig = append(driverConfig, fmt.Sprintf("%s = %s", pair.Key, pair.Value))
-		}
-	}
-	resources := &execdriver.Resources{
-		Memory:     container.Config.Memory,
-		MemorySwap: container.Config.MemorySwap,
-		CpuShares:  container.Config.CpuShares,
-	}
-
-	container.process = &execdriver.Process{
-		ID:         container.ID,
-		Privileged: container.hostConfig.Privileged,
-		Rootfs:     root,
-		InitPath:   "/.dockerinit",
-		Entrypoint: container.Path,
-		Arguments:  container.Args,
-		WorkingDir: workingDir,
-		Network:    en,
-		Tty:        container.Config.Tty,
-		User:       container.Config.User,
-		Config:     driverConfig,
-		Resources:  resources,
-	}
-	container.process.SysProcAttr = &syscall.SysProcAttr{Setsid: true}
+	populateCommand(container)
 
 
 	// Setup logging of stdout and stderr to disk
 	// Setup logging of stdout and stderr to disk
 	if err := container.runtime.LogToDisk(container.stdout, container.logPath("json"), "stdout"); err != nil {
 	if err := container.runtime.LogToDisk(container.stdout, container.logPath("json"), "stdout"); err != nil {
@@ -722,13 +724,13 @@ func (container *Container) Start() (err error) {
 	}
 	}
 
 
 	callbackLock := make(chan struct{})
 	callbackLock := make(chan struct{})
-	callback := func(process *execdriver.Process) {
-		container.State.SetRunning(process.Pid())
-		if process.Tty {
+	callback := func(command *execdriver.Command) {
+		container.State.SetRunning(command.Pid())
+		if command.Tty {
 			// The callback is called after the process Start()
 			// The callback is called after the process Start()
 			// so we are in the parent process. In TTY mode, stdin/out/err is the PtySlace
 			// so we are in the parent process. In TTY mode, stdin/out/err is the PtySlace
 			// which we close here.
 			// which we close here.
-			if c, ok := process.Stdout.(io.Closer); ok {
+			if c, ok := command.Stdout.(io.Closer); ok {
 				c.Close()
 				c.Close()
 			}
 			}
 		}
 		}
@@ -1134,9 +1136,10 @@ func (container *Container) monitor(callback execdriver.StartCallback) error {
 		exitCode int
 		exitCode int
 	)
 	)
 
 
-	if container.process == nil {
+	if container.command == nil {
 		// This happends when you have a GHOST container with lxc
 		// This happends when you have a GHOST container with lxc
-		err = container.runtime.WaitGhost(container)
+		populateCommand(container)
+		err = container.runtime.RestoreCommand(container)
 	} else {
 	} else {
 		exitCode, err = container.runtime.Run(container, callback)
 		exitCode, err = container.runtime.Run(container, callback)
 	}
 	}
@@ -1228,7 +1231,7 @@ func (container *Container) Kill() error {
 
 
 	// 2. Wait for the process to die, in last resort, try to kill the process directly
 	// 2. Wait for the process to die, in last resort, try to kill the process directly
 	if err := container.WaitTimeout(10 * time.Second); err != nil {
 	if err := container.WaitTimeout(10 * time.Second); err != nil {
-		if container.process == nil {
+		if container.command == nil {
 			return fmt.Errorf("lxc-kill failed, impossible to kill the container %s", utils.TruncateID(container.ID))
 			return fmt.Errorf("lxc-kill failed, impossible to kill the container %s", utils.TruncateID(container.ID))
 		}
 		}
 		log.Printf("Container %s failed to exit within 10 seconds of lxc-kill %s - trying direct SIGKILL", "SIGKILL", utils.TruncateID(container.ID))
 		log.Printf("Container %s failed to exit within 10 seconds of lxc-kill %s - trying direct SIGKILL", "SIGKILL", utils.TruncateID(container.ID))

+ 3 - 3
execdriver/chroot/driver.go

@@ -36,7 +36,7 @@ func NewDriver() (*driver, error) {
 	return &driver{}, nil
 	return &driver{}, nil
 }
 }
 
 
-func (d *driver) Run(c *execdriver.Process, startCallback execdriver.StartCallback) (int, error) {
+func (d *driver) Run(c *execdriver.Command, startCallback execdriver.StartCallback) (int, error) {
 	params := []string{
 	params := []string{
 		"chroot",
 		"chroot",
 		c.Rootfs,
 		c.Rootfs,
@@ -70,11 +70,11 @@ func (d *driver) Run(c *execdriver.Process, startCallback execdriver.StartCallba
 	return c.GetExitCode(), err
 	return c.GetExitCode(), err
 }
 }
 
 
-func (d *driver) Kill(p *execdriver.Process, sig int) error {
+func (d *driver) Kill(p *execdriver.Command, sig int) error {
 	return p.Process.Kill()
 	return p.Process.Kill()
 }
 }
 
 
-func (d *driver) Wait(id string) error {
+func (d *driver) Restore(c *execdriver.Command) error {
 	panic("Not Implemented")
 	panic("Not Implemented")
 }
 }
 
 

+ 10 - 10
execdriver/driver.go

@@ -16,7 +16,7 @@ var (
 var dockerInitFcts map[string]InitFunc
 var dockerInitFcts map[string]InitFunc
 
 
 type (
 type (
-	StartCallback func(*Process)
+	StartCallback func(*Command)
 	InitFunc      func(i *InitArgs) error
 	InitFunc      func(i *InitArgs) error
 )
 )
 
 
@@ -59,11 +59,11 @@ type Info interface {
 }
 }
 
 
 type Driver interface {
 type Driver interface {
-	Run(c *Process, startCallback StartCallback) (int, error) // Run executes the process and blocks until the process exits and returns the exit code
-	Kill(c *Process, sig int) error
-	Wait(id string) error // Wait on an out of process...process - lxc ghosts TODO: Rename to reattach, reconnect
-	Name() string         // Driver name
-	Info(id string) Info  // "temporary" hack (until we move state from core to plugins)
+	Run(c *Command, startCallback StartCallback) (int, error) // Run executes the process and blocks until the process exits and returns the exit code
+	Kill(c *Command, sig int) error
+	Restore(c *Command) error // Wait and try to re-attach on an out of process command
+	Name() string             // Driver name
+	Info(id string) Info      // "temporary" hack (until we move state from core to plugins)
 }
 }
 
 
 // Network settings of the container
 // Network settings of the container
@@ -83,8 +83,8 @@ type Resources struct {
 
 
 // Process wrapps an os/exec.Cmd to add more metadata
 // Process wrapps an os/exec.Cmd to add more metadata
 // TODO: Rename to Command
 // TODO: Rename to Command
-type Process struct {
-	exec.Cmd
+type Command struct {
+	exec.Cmd `json:"-"`
 
 
 	ID         string     `json:"id"`
 	ID         string     `json:"id"`
 	Privileged bool       `json:"privileged"`
 	Privileged bool       `json:"privileged"`
@@ -103,7 +103,7 @@ type Process struct {
 
 
 // Return the pid of the process
 // Return the pid of the process
 // If the process is nil -1 will be returned
 // If the process is nil -1 will be returned
-func (c *Process) Pid() int {
+func (c *Command) Pid() int {
 	if c.Process == nil {
 	if c.Process == nil {
 		return -1
 		return -1
 	}
 	}
@@ -112,7 +112,7 @@ func (c *Process) Pid() int {
 
 
 // Return the exit code of the process
 // Return the exit code of the process
 // if the process has not exited -1 will be returned
 // if the process has not exited -1 will be returned
-func (c *Process) GetExitCode() int {
+func (c *Command) GetExitCode() int {
 	if c.ProcessState == nil {
 	if c.ProcessState == nil {
 		return -1
 		return -1
 	}
 	}

+ 12 - 10
execdriver/lxc/driver.go

@@ -30,6 +30,7 @@ func init() {
 		if err := setupCapabilities(args); err != nil {
 		if err := setupCapabilities(args); err != nil {
 			return err
 			return err
 		}
 		}
+
 		if err := setupWorkingDirectory(args); err != nil {
 		if err := setupWorkingDirectory(args); err != nil {
 			return err
 			return err
 		}
 		}
@@ -37,6 +38,7 @@ func init() {
 		if err := changeUser(args); err != nil {
 		if err := changeUser(args); err != nil {
 			return err
 			return err
 		}
 		}
+
 		path, err := exec.LookPath(args.Args[0])
 		path, err := exec.LookPath(args.Args[0])
 		if err != nil {
 		if err != nil {
 			log.Printf("Unable to locate %v", args.Args[0])
 			log.Printf("Unable to locate %v", args.Args[0])
@@ -72,7 +74,7 @@ func (d *driver) Name() string {
 	return fmt.Sprintf("%s-%s", DriverName, version)
 	return fmt.Sprintf("%s-%s", DriverName, version)
 }
 }
 
 
-func (d *driver) Run(c *execdriver.Process, startCallback execdriver.StartCallback) (int, error) {
+func (d *driver) Run(c *execdriver.Command, startCallback execdriver.StartCallback) (int, error) {
 	configPath, err := d.generateLXCConfig(c)
 	configPath, err := d.generateLXCConfig(c)
 	if err != nil {
 	if err != nil {
 		return -1, err
 		return -1, err
@@ -170,13 +172,13 @@ func (d *driver) Run(c *execdriver.Process, startCallback execdriver.StartCallba
 	return c.GetExitCode(), waitErr
 	return c.GetExitCode(), waitErr
 }
 }
 
 
-func (d *driver) Kill(c *execdriver.Process, sig int) error {
+func (d *driver) Kill(c *execdriver.Command, sig int) error {
 	return d.kill(c, sig)
 	return d.kill(c, sig)
 }
 }
 
 
-func (d *driver) Wait(id string) error {
+func (d *driver) Restore(c *execdriver.Command) error {
 	for {
 	for {
-		output, err := exec.Command("lxc-info", "-n", id).CombinedOutput()
+		output, err := exec.Command("lxc-info", "-n", c.ID).CombinedOutput()
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
@@ -198,7 +200,7 @@ func (d *driver) version() string {
 	return version
 	return version
 }
 }
 
 
-func (d *driver) kill(c *execdriver.Process, sig int) error {
+func (d *driver) kill(c *execdriver.Command, sig int) error {
 	output, err := exec.Command("lxc-kill", "-n", c.ID, strconv.Itoa(sig)).CombinedOutput()
 	output, err := exec.Command("lxc-kill", "-n", c.ID, strconv.Itoa(sig)).CombinedOutput()
 	if err != nil {
 	if err != nil {
 		return fmt.Errorf("Err: %s Output: %s", err, output)
 		return fmt.Errorf("Err: %s Output: %s", err, output)
@@ -206,7 +208,7 @@ func (d *driver) kill(c *execdriver.Process, sig int) error {
 	return nil
 	return nil
 }
 }
 
 
-func (d *driver) waitForStart(c *execdriver.Process, waitLock chan struct{}) error {
+func (d *driver) waitForStart(c *execdriver.Command, waitLock chan struct{}) error {
 	var (
 	var (
 		err    error
 		err    error
 		output []byte
 		output []byte
@@ -302,8 +304,8 @@ func rootIsShared() bool {
 	return true
 	return true
 }
 }
 
 
-func (d *driver) generateLXCConfig(p *execdriver.Process) (string, error) {
-	root := path.Join(d.root, "containers", p.ID, "config.lxc")
+func (d *driver) generateLXCConfig(c *execdriver.Command) (string, error) {
+	root := path.Join(d.root, "containers", c.ID, "config.lxc")
 	fo, err := os.Create(root)
 	fo, err := os.Create(root)
 	if err != nil {
 	if err != nil {
 		return "", err
 		return "", err
@@ -311,10 +313,10 @@ func (d *driver) generateLXCConfig(p *execdriver.Process) (string, error) {
 	defer fo.Close()
 	defer fo.Close()
 
 
 	if err := LxcTemplateCompiled.Execute(fo, struct {
 	if err := LxcTemplateCompiled.Execute(fo, struct {
-		*execdriver.Process
+		*execdriver.Command
 		AppArmor bool
 		AppArmor bool
 	}{
 	}{
-		Process:  p,
+		Command:  c,
 		AppArmor: d.apparmor,
 		AppArmor: d.apparmor,
 	}); err != nil {
 	}); err != nil {
 		return "", err
 		return "", err

+ 4 - 4
execdriver/lxc/lxc_template_unit_test.go

@@ -37,14 +37,14 @@ func TestLXCConfig(t *testing.T) {
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-	process := &execdriver.Process{
+	command := &execdriver.Command{
 		ID: "1",
 		ID: "1",
 		Resources: &execdriver.Resources{
 		Resources: &execdriver.Resources{
 			Memory:    int64(mem),
 			Memory:    int64(mem),
 			CpuShares: int64(cpu),
 			CpuShares: int64(cpu),
 		},
 		},
 	}
 	}
-	p, err := driver.generateLXCConfig(process)
+	p, err := driver.generateLXCConfig(command)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
@@ -68,7 +68,7 @@ func TestCustomLxcConfig(t *testing.T) {
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-	process := &execdriver.Process{
+	command := &execdriver.Command{
 		ID:         "1",
 		ID:         "1",
 		Privileged: false,
 		Privileged: false,
 		Config: []string{
 		Config: []string{
@@ -77,7 +77,7 @@ func TestCustomLxcConfig(t *testing.T) {
 		},
 		},
 	}
 	}
 
 
-	p, err := driver.generateLXCConfig(process)
+	p, err := driver.generateLXCConfig(command)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}

+ 4 - 4
runtime.go

@@ -817,15 +817,15 @@ func (runtime *Runtime) Diff(container *Container) (archive.Archive, error) {
 }
 }
 
 
 func (runtime *Runtime) Run(c *Container, startCallback execdriver.StartCallback) (int, error) {
 func (runtime *Runtime) Run(c *Container, startCallback execdriver.StartCallback) (int, error) {
-	return runtime.execDriver.Run(c.process, startCallback)
+	return runtime.execDriver.Run(c.command, startCallback)
 }
 }
 
 
 func (runtime *Runtime) Kill(c *Container, sig int) error {
 func (runtime *Runtime) Kill(c *Container, sig int) error {
-	return runtime.execDriver.Kill(c.process, sig)
+	return runtime.execDriver.Kill(c.command, sig)
 }
 }
 
 
-func (runtime *Runtime) WaitGhost(c *Container) error {
-	return runtime.execDriver.Wait(c.ID)
+func (runtime *Runtime) RestoreCommand(c *Container) error {
+	return runtime.execDriver.Restore(c.command)
 }
 }
 
 
 // Nuke kills all containers then removes all content
 // Nuke kills all containers then removes all content

+ 10 - 8
sysinit/sysinit.go

@@ -50,14 +50,16 @@ func SysInit() {
 		os.Exit(1)
 		os.Exit(1)
 	}
 	}
 
 
-	// Get cmdline arguments
-	user := flag.String("u", "", "username or uid")
-	gateway := flag.String("g", "", "gateway address")
-	ip := flag.String("i", "", "ip address")
-	workDir := flag.String("w", "", "workdir")
-	privileged := flag.Bool("privileged", false, "privileged mode")
-	mtu := flag.Int("mtu", 1500, "interface mtu")
-	driver := flag.String("driver", "", "exec driver")
+	var (
+		// Get cmdline arguments
+		user       = flag.String("u", "", "username or uid")
+		gateway    = flag.String("g", "", "gateway address")
+		ip         = flag.String("i", "", "ip address")
+		workDir    = flag.String("w", "", "workdir")
+		privileged = flag.Bool("privileged", false, "privileged mode")
+		mtu        = flag.Int("mtu", 1500, "interface mtu")
+		driver     = flag.String("driver", "", "exec driver")
+	)
 	flag.Parse()
 	flag.Parse()
 
 
 	// Get env
 	// Get env