From 81804fc4641d279fec8f9bf48b21b22fc90cb891 Mon Sep 17 00:00:00 2001
From: Peter Hunt <pehunt@redhat.com>
Date: Fri, 15 Feb 2019 16:39:24 -0500
Subject: pod infra container is started before a container in a pod is run,
 started, or attached.

Prior, a pod would have to be started immediately when created, leading to confusion about what a pod state should be immediately after creation. The problem was podman run --pod ... would error out if the infra container wasn't started (as it is a dependency). Fix this by allowing for recursive start, where each of the container's dependencies are started prior to the new container. This is only applied to the case where a new container is attached to a pod.

Also rework container_api Start, StartAndAttach, and Init functions, as there was some duplicated code, which made addressing the problem easier to fix.

Signed-off-by: Peter Hunt <pehunt@redhat.com>
---
 cmd/podman/attach.go    | 3 ++-
 cmd/podman/play_kube.go | 2 +-
 cmd/podman/run.go       | 7 ++++---
 cmd/podman/start.go     | 6 ++++--
 cmd/podman/utils.go     | 4 ++--
 5 files changed, 13 insertions(+), 9 deletions(-)

(limited to 'cmd')

diff --git a/cmd/podman/attach.go b/cmd/podman/attach.go
index ed175bdf4..f6492240d 100644
--- a/cmd/podman/attach.go
+++ b/cmd/podman/attach.go
@@ -74,7 +74,8 @@ func attachCmd(c *cliconfig.AttachValues) error {
 		inputStream = nil
 	}
 
-	if err := startAttachCtr(ctr, os.Stdout, os.Stderr, inputStream, c.DetachKeys, c.SigProxy, false); err != nil && errors.Cause(err) != libpod.ErrDetach {
+	// If the container is in a pod, also set to recursively start dependencies
+	if err := startAttachCtr(ctr, os.Stdout, os.Stderr, inputStream, c.DetachKeys, c.SigProxy, false, ctr.PodID() != ""); err != nil && errors.Cause(err) != libpod.ErrDetach {
 		return errors.Wrapf(err, "error attaching to container %s", ctr.ID())
 	}
 
diff --git a/cmd/podman/play_kube.go b/cmd/podman/play_kube.go
index 4ecd30cd4..97ab7afd4 100644
--- a/cmd/podman/play_kube.go
+++ b/cmd/podman/play_kube.go
@@ -154,7 +154,7 @@ func playKubeYAMLCmd(c *cliconfig.KubePlayValues) error {
 
 	// start the containers
 	for _, ctr := range containers {
-		if err := ctr.Start(ctx); err != nil {
+		if err := ctr.Start(ctx, false); err != nil {
 			// Making this a hard failure here to avoid a mess
 			// the other containers are in created status
 			return err
diff --git a/cmd/podman/run.go b/cmd/podman/run.go
index 64f8b6856..45fc8df76 100644
--- a/cmd/podman/run.go
+++ b/cmd/podman/run.go
@@ -72,7 +72,8 @@ func runCmd(c *cliconfig.RunValues) error {
 	ctx := getContext()
 	// Handle detached start
 	if createConfig.Detach {
-		if err := ctr.Start(ctx); err != nil {
+		// if the container was created as part of a pod, also start its dependencies, if any.
+		if err := ctr.Start(ctx, c.IsSet("pod")); err != nil {
 			// This means the command did not exist
 			exitCode = 127
 			if strings.Index(err.Error(), "permission denied") > -1 {
@@ -117,7 +118,8 @@ func runCmd(c *cliconfig.RunValues) error {
 			}
 		}
 	}
-	if err := startAttachCtr(ctr, outputStream, errorStream, inputStream, c.String("detach-keys"), c.Bool("sig-proxy"), true); err != nil {
+	// if the container was created as part of a pod, also start its dependencies, if any.
+	if err := startAttachCtr(ctr, outputStream, errorStream, inputStream, c.String("detach-keys"), c.Bool("sig-proxy"), true, c.IsSet("pod")); err != nil {
 		// We've manually detached from the container
 		// Do not perform cleanup, or wait for container exit code
 		// Just exit immediately
@@ -125,7 +127,6 @@ func runCmd(c *cliconfig.RunValues) error {
 			exitCode = 0
 			return nil
 		}
-
 		// This means the command did not exist
 		exitCode = 127
 		if strings.Index(err.Error(), "permission denied") > -1 {
diff --git a/cmd/podman/start.go b/cmd/podman/start.go
index 1f671aefd..bbb4e87d2 100644
--- a/cmd/podman/start.go
+++ b/cmd/podman/start.go
@@ -105,7 +105,8 @@ func startCmd(c *cliconfig.StartValues) error {
 			}
 
 			// attach to the container and also start it not already running
-			err = startAttachCtr(ctr, os.Stdout, os.Stderr, inputStream, c.DetachKeys, sigProxy, !ctrRunning)
+			// If the container is in a pod, also set to recursively start dependencies
+			err = startAttachCtr(ctr, os.Stdout, os.Stderr, inputStream, c.DetachKeys, sigProxy, !ctrRunning, ctr.PodID() != "")
 			if errors.Cause(err) == libpod.ErrDetach {
 				// User manually detached
 				// Exit cleanly immediately
@@ -144,7 +145,8 @@ func startCmd(c *cliconfig.StartValues) error {
 			continue
 		}
 		// Handle non-attach start
-		if err := ctr.Start(ctx); err != nil {
+		// If the container is in a pod, also set to recursively start dependencies
+		if err := ctr.Start(ctx, ctr.PodID() != ""); err != nil {
 			if lastError != nil {
 				fmt.Fprintln(os.Stderr, lastError)
 			}
diff --git a/cmd/podman/utils.go b/cmd/podman/utils.go
index 744d010d5..c76e7f2a4 100644
--- a/cmd/podman/utils.go
+++ b/cmd/podman/utils.go
@@ -20,7 +20,7 @@ type RawTtyFormatter struct {
 }
 
 // Start (if required) and attach to a container
-func startAttachCtr(ctr *libpod.Container, stdout, stderr, stdin *os.File, detachKeys string, sigProxy bool, startContainer bool) error {
+func startAttachCtr(ctr *libpod.Container, stdout, stderr, stdin *os.File, detachKeys string, sigProxy bool, startContainer bool, recursive bool) error {
 	ctx := context.Background()
 	resize := make(chan remotecommand.TerminalSize)
 
@@ -76,7 +76,7 @@ func startAttachCtr(ctr *libpod.Container, stdout, stderr, stdin *os.File, detac
 		return ctr.Attach(streams, detachKeys, resize)
 	}
 
-	attachChan, err := ctr.StartAndAttach(getContext(), streams, detachKeys, resize)
+	attachChan, err := ctr.StartAndAttach(getContext(), streams, detachKeys, resize, recursive)
 	if err != nil {
 		return err
 	}
-- 
cgit v1.2.3-54-g00ecf