Browse code

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

Guillaume J. Charmes authored on 2013/04/20 04:08:43
Showing 2 changed files
... ...
@@ -530,16 +530,42 @@ func (container *Container) releaseNetwork() {
530 530
 	container.NetworkSettings = &NetworkSettings{}
531 531
 }
532 532
 
533
+// FIXME: replace this with a control socket within docker-init
534
+func (container *Container) waitLxc() error {
535
+	for {
536
+		if output, err := exec.Command("lxc-info", "-n", container.Id).CombinedOutput(); err != nil {
537
+			return err
538
+		} else {
539
+			if !strings.Contains(string(output), "RUNNING") {
540
+				return nil
541
+			}
542
+		}
543
+		time.Sleep(500 * time.Millisecond)
544
+	}
545
+	return nil
546
+}
547
+
533 548
 func (container *Container) monitor() {
534 549
 	// Wait for the program to exit
535 550
 	Debugf("Waiting for process")
536
-	if err := container.cmd.Wait(); err != nil {
537
-		// Discard the error as any signals or non 0 returns will generate an error
538
-		Debugf("%s: Process: %s", container.Id, err)
551
+
552
+	// If the command does not exists, try to wait via lxc
553
+	if container.cmd == nil {
554
+		if err := container.waitLxc(); err != nil {
555
+			Debugf("%s: Process: %s", container.Id, err)
556
+		}
557
+	} else {
558
+		if err := container.cmd.Wait(); err != nil {
559
+			// Discard the error as any signals or non 0 returns will generate an error
560
+			Debugf("%s: Process: %s", container.Id, err)
561
+		}
539 562
 	}
540 563
 	Debugf("Process finished")
541 564
 
542
-	exitCode := container.cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
565
+	var exitCode int = -1
566
+	if container.cmd != nil {
567
+		exitCode = container.cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
568
+	}
543 569
 
544 570
 	// Cleanup
545 571
 	container.releaseNetwork()
... ...
@@ -184,12 +184,6 @@ func (runtime *Runtime) Register(container *Container) error {
184 184
 		}
185 185
 	}
186 186
 
187
-	// If the container is not running or just has been flagged not running
188
-	// then close the wait lock chan (will be reset upon start)
189
-	if !container.State.Running {
190
-		close(container.waitLock)
191
-	}
192
-
193 187
 	// Even if not running, we init the lock (prevents races in start/stop/kill)
194 188
 	container.State.initLock()
195 189
 
... ...
@@ -207,6 +201,15 @@ func (runtime *Runtime) Register(container *Container) error {
207 207
 	// done
208 208
 	runtime.containers.PushBack(container)
209 209
 	runtime.idIndex.Add(container.Id)
210
+
211
+	// If the container is not running or just has been flagged not running
212
+	// then close the wait lock chan (will be reset upon start)
213
+	if !container.State.Running {
214
+		close(container.waitLock)
215
+	} else {
216
+		container.allocateNetwork()
217
+		go container.monitor()
218
+	}
210 219
 	return nil
211 220
 }
212 221