浏览代码

Allow to wait on container even after docker server restarts using lxc-info

Guillaume J. Charmes 12 年之前
父节点
当前提交
82848d4158
共有 2 个文件被更改,包括 39 次插入10 次删除
  1. 30 4
      container.go
  2. 9 6
      runtime.go

+ 30 - 4
container.go

@@ -530,16 +530,42 @@ func (container *Container) releaseNetwork() {
 	container.NetworkSettings = &NetworkSettings{}
 }
 
+// FIXME: replace this with a control socket within docker-init
+func (container *Container) waitLxc() error {
+	for {
+		if output, err := exec.Command("lxc-info", "-n", container.Id).CombinedOutput(); err != nil {
+			return err
+		} else {
+			if !strings.Contains(string(output), "RUNNING") {
+				return nil
+			}
+		}
+		time.Sleep(500 * time.Millisecond)
+	}
+	return nil
+}
+
 func (container *Container) monitor() {
 	// Wait for the program to exit
 	Debugf("Waiting for process")
-	if err := container.cmd.Wait(); err != nil {
-		// Discard the error as any signals or non 0 returns will generate an error
-		Debugf("%s: Process: %s", container.Id, err)
+
+	// If the command does not exists, try to wait via lxc
+	if container.cmd == nil {
+		if err := container.waitLxc(); err != nil {
+			Debugf("%s: Process: %s", container.Id, err)
+		}
+	} else {
+		if err := container.cmd.Wait(); err != nil {
+			// Discard the error as any signals or non 0 returns will generate an error
+			Debugf("%s: Process: %s", container.Id, err)
+		}
 	}
 	Debugf("Process finished")
 
-	exitCode := container.cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
+	var exitCode int = -1
+	if container.cmd != nil {
+		exitCode = container.cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
+	}
 
 	// Cleanup
 	container.releaseNetwork()

+ 9 - 6
runtime.go

@@ -184,12 +184,6 @@ func (runtime *Runtime) Register(container *Container) error {
 		}
 	}
 
-	// If the container is not running or just has been flagged not running
-	// then close the wait lock chan (will be reset upon start)
-	if !container.State.Running {
-		close(container.waitLock)
-	}
-
 	// Even if not running, we init the lock (prevents races in start/stop/kill)
 	container.State.initLock()
 
@@ -207,6 +201,15 @@ func (runtime *Runtime) Register(container *Container) error {
 	// done
 	runtime.containers.PushBack(container)
 	runtime.idIndex.Add(container.Id)
+
+	// If the container is not running or just has been flagged not running
+	// then close the wait lock chan (will be reset upon start)
+	if !container.State.Running {
+		close(container.waitLock)
+	} else {
+		container.allocateNetwork()
+		go container.monitor()
+	}
 	return nil
 }