From fbc50e5285e960e6533e64a768dd4fb5615c8f7e Mon Sep 17 00:00:00 2001
From: Ashley Cui <acui@redhat.com>
Date: Mon, 15 Feb 2021 15:36:33 -0500
Subject: [PATCH 1/5] fix journald logs --tail 0

Signed-off-by: Ashley Cui <acui@redhat.com>
---
 libpod/container_log_linux.go | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go
index d895171cf5..c9620100e3 100644
--- a/libpod/container_log_linux.go
+++ b/libpod/container_log_linux.go
@@ -34,6 +34,8 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
 	var config journal.JournalReaderConfig
 	if options.Tail < 0 {
 		config.NumFromTail = 0
+	} else if options.Tail == 0 {
+		config.NumFromTail = math.MaxUint64
 	} else {
 		config.NumFromTail = uint64(options.Tail)
 	}

From f2d057c943957dce99b49d291c2e1b96af31a9e5 Mon Sep 17 00:00:00 2001
From: Ashley Cui <acui@redhat.com>
Date: Mon, 15 Feb 2021 15:37:45 -0500
Subject: [PATCH 2/5] Fix journald logs --since

Signed-off-by: Ashley Cui <acui@redhat.com>
---
 libpod/container_log_linux.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go
index c9620100e3..af46191d01 100644
--- a/libpod/container_log_linux.go
+++ b/libpod/container_log_linux.go
@@ -47,7 +47,7 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
 		if time.Now().Before(options.Since) {
 			return nil
 		}
-		config.Since = time.Since(options.Since)
+		config.Since = -time.Since(options.Since)
 	}
 	config.Matches = append(config.Matches, journal.Match{
 		Field: "CONTAINER_ID_FULL",

From 9016387bba45bd681d64e6b01f9c94f7bbb0448a Mon Sep 17 00:00:00 2001
From: Ashley Cui <acui@redhat.com>
Date: Wed, 17 Feb 2021 15:02:22 -0500
Subject: [PATCH 3/5] Fix journald logs --follow

Previously, --follow with a podman logs using journald would not exit

Signed-off-by: Ashley Cui <acui@redhat.com>
---
 libpod/container_log_linux.go | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go
index af46191d01..713db9c1eb 100644
--- a/libpod/container_log_linux.go
+++ b/libpod/container_log_linux.go
@@ -11,8 +11,10 @@ import (
 	"strings"
 	"time"
 
+	"github.com/containers/podman/v2/libpod/define"
 	"github.com/containers/podman/v2/libpod/logs"
 	journal "github.com/coreos/go-systemd/v22/sdjournal"
+	"github.com/hpcloud/tail/watch"
 	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
 )
@@ -65,8 +67,12 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
 	if options.Tail == math.MaxInt64 {
 		r.Rewind()
 	}
+	state, err := c.State()
+	if err != nil {
+		return err
+	}
 
-	if options.Follow {
+	if options.Follow && state == define.ContainerStateRunning {
 		go func() {
 			done := make(chan bool)
 			until := make(chan time.Time)
@@ -78,6 +84,21 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
 					// nothing to do anymore
 				}
 			}()
+			go func() {
+				for {
+					state, err := c.State()
+					if err != nil {
+						until <- time.Time{}
+						logrus.Error(err)
+						break
+					}
+					time.Sleep(watch.POLL_DURATION)
+					if state != define.ContainerStateRunning && state != define.ContainerStatePaused {
+						until <- time.Time{}
+						break
+					}
+				}
+			}()
 			follower := FollowBuffer{logChannel}
 			err := r.Follow(until, follower)
 			if err != nil {

From 612ba6aa828d3c19b43f8420d99e0f1416f15cbf Mon Sep 17 00:00:00 2001
From: Ashley Cui <acui@redhat.com>
Date: Wed, 17 Feb 2021 15:35:04 -0500
Subject: [PATCH 4/5] Fix journald logs with more than 1 container

A podman logs on multiple containers will correctly display the
container ID next to the log line

Signed-off-by: Ashley Cui <acui@redhat.com>
---
 libpod/container_log_linux.go | 52 ++++++++++++++++++++++++++++++++---
 1 file changed, 48 insertions(+), 4 deletions(-)

diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go
index 713db9c1eb..91ca216ea8 100644
--- a/libpod/container_log_linux.go
+++ b/libpod/container_log_linux.go
@@ -8,7 +8,6 @@ import (
 	"fmt"
 	"io"
 	"math"
-	"strings"
 	"time"
 
 	"github.com/containers/podman/v2/libpod/define"
@@ -41,7 +40,11 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
 	} else {
 		config.NumFromTail = uint64(options.Tail)
 	}
-	config.Formatter = journalFormatter
+	if options.Multi {
+		config.Formatter = journalFormatterWithID
+	} else {
+		config.Formatter = journalFormatter
+	}
 	defaultTime := time.Time{}
 	if options.Since != defaultTime {
 		// coreos/go-systemd/sdjournal doesn't correctly handle requests for data in the future
@@ -137,7 +140,45 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
 	return nil
 }
 
+func journalFormatterWithID(entry *journal.JournalEntry) (string, error) {
+	// get
+	output, err := formatterPrefix(entry)
+	if err != nil {
+		return "", err
+	}
+
+	id, ok := entry.Fields["CONTAINER_ID_FULL"]
+	if !ok {
+		return "", fmt.Errorf("no CONTAINER_ID_FULL field present in journal entry")
+	}
+	if len(id) > 12 {
+		id = id[:12]
+	}
+	output += fmt.Sprintf("%s ", id)
+	// Append message
+	msg, err := formatterMessage(entry)
+	if err != nil {
+		return "", err
+	}
+	output += msg
+	return output, nil
+}
+
 func journalFormatter(entry *journal.JournalEntry) (string, error) {
+	output, err := formatterPrefix(entry)
+	if err != nil {
+		return "", err
+	}
+	// Append message
+	msg, err := formatterMessage(entry)
+	if err != nil {
+		return "", err
+	}
+	output += msg
+	return output, nil
+}
+
+func formatterPrefix(entry *journal.JournalEntry) (string, error) {
 	usec := entry.RealtimeTimestamp
 	tsString := time.Unix(0, int64(usec)*int64(time.Microsecond)).Format(logs.LogTimeFormat)
 	output := fmt.Sprintf("%s ", tsString)
@@ -160,13 +201,16 @@ func journalFormatter(entry *journal.JournalEntry) (string, error) {
 		output += fmt.Sprintf("%s ", logs.FullLogType)
 	}
 
+	return output, nil
+}
+
+func formatterMessage(entry *journal.JournalEntry) (string, error) {
 	// Finally, append the message
 	msg, ok := entry.Fields["MESSAGE"]
 	if !ok {
 		return "", fmt.Errorf("no MESSAGE field present in journal entry")
 	}
-	output += strings.TrimSpace(msg)
-	return output, nil
+	return msg, nil
 }
 
 type FollowBuffer struct {

From 05eb06f5686be1a14f33cdc0c23785d6da0feccb Mon Sep 17 00:00:00 2001
From: Daniel J Walsh <dwalsh@redhat.com>
Date: Wed, 17 Feb 2021 23:06:43 -0500
Subject: [PATCH 5/5] Turn on journald and k8s file logging tests

Signed-off-by: Ashley Cui <acui@redhat.com>
---
 libpod/container_log_linux.go |   1 -
 test/e2e/logs_test.go         | 598 +++++++++++++++++-----------------
 test/utils/utils.go           |  10 +
 3 files changed, 307 insertions(+), 302 deletions(-)

diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go
index 91ca216ea8..b1f601a4c9 100644
--- a/libpod/container_log_linux.go
+++ b/libpod/container_log_linux.go
@@ -141,7 +141,6 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
 }
 
 func journalFormatterWithID(entry *journal.JournalEntry) (string, error) {
-	// get
 	output, err := formatterPrefix(entry)
 	if err != nil {
 		return "", err
diff --git a/test/e2e/logs_test.go b/test/e2e/logs_test.go
index b370aeec16..1b9d26c495 100644
--- a/test/e2e/logs_test.go
+++ b/test/e2e/logs_test.go
@@ -36,345 +36,341 @@ var _ = Describe("Podman logs", func() {
 
 	})
 
-	It("all lines", func() {
-		logc := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
+	for _, log := range []string{"k8s-file", "journald", "json-file"} {
+		It("all lines: "+log, func() {
+			logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+			logc.WaitWithDefaultTimeout()
+			Expect(logc).To(Exit(0))
 
-		cid := logc.OutputToString()
-		results := podmanTest.Podman([]string{"logs", cid})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(Exit(0))
-		Expect(len(results.OutputToStringArray())).To(Equal(3))
-	})
+			cid := logc.OutputToString()
+			results := podmanTest.Podman([]string{"logs", cid})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(Exit(0))
+			Expect(len(results.OutputToStringArray())).To(Equal(3))
+		})
 
-	It("tail two lines", func() {
-		logc := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
-		cid := logc.OutputToString()
+		It("tail two lines: "+log, func() {
+			logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+			logc.WaitWithDefaultTimeout()
+			Expect(logc).To(Exit(0))
+			cid := logc.OutputToString()
 
-		results := podmanTest.Podman([]string{"logs", "--tail", "2", cid})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(Exit(0))
-		Expect(len(results.OutputToStringArray())).To(Equal(2))
-	})
+			results := podmanTest.Podman([]string{"logs", "--tail", "2", cid})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(Exit(0))
+			Expect(len(results.OutputToStringArray())).To(Equal(2))
+		})
 
-	It("tail zero lines", func() {
-		logc := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
-		cid := logc.OutputToString()
+		It("tail zero lines: "+log, func() {
+			logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+			logc.WaitWithDefaultTimeout()
+			Expect(logc).To(Exit(0))
+			cid := logc.OutputToString()
 
-		results := podmanTest.Podman([]string{"logs", "--tail", "0", cid})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(Exit(0))
-		Expect(len(results.OutputToStringArray())).To(Equal(0))
-	})
+			results := podmanTest.Podman([]string{"logs", "--tail", "0", cid})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(Exit(0))
+			Expect(len(results.OutputToStringArray())).To(Equal(0))
+		})
 
-	It("tail 800 lines", func() {
-		logc := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "i=1; while [ \"$i\" -ne 1000 ]; do echo \"line $i\"; i=$((i + 1)); done"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
-		cid := logc.OutputToString()
+		It("tail 800 lines: "+log, func() {
+			logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "i=1; while [ \"$i\" -ne 1000 ]; do echo \"line $i\"; i=$((i + 1)); done"})
+			logc.WaitWithDefaultTimeout()
+			Expect(logc).To(Exit(0))
+			cid := logc.OutputToString()
 
-		results := podmanTest.Podman([]string{"logs", "--tail", "800", cid})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(Exit(0))
-		Expect(len(results.OutputToStringArray())).To(Equal(800))
-	})
+			results := podmanTest.Podman([]string{"logs", "--tail", "800", cid})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(Exit(0))
+			Expect(len(results.OutputToStringArray())).To(Equal(800))
+		})
 
-	It("tail 2 lines with timestamps", func() {
-		logc := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
-		cid := logc.OutputToString()
+		It("tail 2 lines with timestamps: "+log, func() {
+			logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+			logc.WaitWithDefaultTimeout()
+			Expect(logc).To(Exit(0))
+			cid := logc.OutputToString()
 
-		results := podmanTest.Podman([]string{"logs", "--tail", "2", "-t", cid})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(Exit(0))
-		Expect(len(results.OutputToStringArray())).To(Equal(2))
-	})
+			results := podmanTest.Podman([]string{"logs", "--tail", "2", "-t", cid})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(Exit(0))
+			Expect(len(results.OutputToStringArray())).To(Equal(2))
+		})
 
-	It("since time 2017-08-07", func() {
-		logc := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
-		cid := logc.OutputToString()
+		It("since time 2017-08-07: "+log, func() {
+			logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+			logc.WaitWithDefaultTimeout()
+			Expect(logc).To(Exit(0))
+			cid := logc.OutputToString()
 
-		results := podmanTest.Podman([]string{"logs", "--since", "2017-08-07T10:10:09.056611202-04:00", cid})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(Exit(0))
-		Expect(len(results.OutputToStringArray())).To(Equal(3))
-	})
+			results := podmanTest.Podman([]string{"logs", "--since", "2017-08-07T10:10:09.056611202-04:00", cid})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(Exit(0))
+			Expect(len(results.OutputToStringArray())).To(Equal(3))
+		})
 
-	It("since duration 10m", func() {
-		logc := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
-		cid := logc.OutputToString()
+		It("since duration 10m: "+log, func() {
+			logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+			logc.WaitWithDefaultTimeout()
+			Expect(logc).To(Exit(0))
+			cid := logc.OutputToString()
 
-		results := podmanTest.Podman([]string{"logs", "--since", "10m", cid})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(Exit(0))
-		Expect(len(results.OutputToStringArray())).To(Equal(3))
-	})
+			results := podmanTest.Podman([]string{"logs", "--since", "10m", cid})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(Exit(0))
+			Expect(len(results.OutputToStringArray())).To(Equal(3))
+		})
 
-	It("latest and container name should fail", func() {
-		results := podmanTest.Podman([]string{"logs", "-l", "foobar"})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(ExitWithError())
-	})
+		It("latest and container name should fail: "+log, func() {
+			results := podmanTest.Podman([]string{"logs", "-l", "foobar"})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(ExitWithError())
+		})
 
-	It("two containers showing short container IDs", func() {
-		SkipIfRemote("FIXME: podman-remote logs does not support showing two containers at the same time")
-		log1 := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
-		log1.WaitWithDefaultTimeout()
-		Expect(log1.ExitCode()).To(Equal(0))
-		cid1 := log1.OutputToString()
+		It("two containers showing short container IDs: "+log, func() {
+			SkipIfRemote("FIXME: podman-remote logs does not support showing two containers at the same time")
+			log1 := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+			log1.WaitWithDefaultTimeout()
+			Expect(log1.ExitCode()).To(Equal(0))
+			cid1 := log1.OutputToString()
 
-		log2 := podmanTest.Podman([]string{"run", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
-		log2.WaitWithDefaultTimeout()
-		Expect(log2.ExitCode()).To(Equal(0))
-		cid2 := log2.OutputToString()
+			log2 := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+			log2.WaitWithDefaultTimeout()
+			Expect(log2.ExitCode()).To(Equal(0))
+			cid2 := log2.OutputToString()
 
-		results := podmanTest.Podman([]string{"logs", cid1, cid2})
-		results.WaitWithDefaultTimeout()
-		Expect(results).Should(Exit(0))
+			results := podmanTest.Podman([]string{"logs", cid1, cid2})
+			results.WaitWithDefaultTimeout()
+			Expect(results).Should(Exit(0))
 
-		output := results.OutputToStringArray()
-		Expect(len(output)).To(Equal(6))
-		Expect(strings.Contains(output[0], cid1[:12]) || strings.Contains(output[0], cid2[:12])).To(BeTrue())
-	})
+			output := results.OutputToStringArray()
+			Expect(len(output)).To(Equal(6))
+			Expect(strings.Contains(output[0], cid1[:12]) || strings.Contains(output[0], cid2[:12])).To(BeTrue())
+		})
 
-	It("podman logs on a created container should result in 0 exit code", func() {
-		session := podmanTest.Podman([]string{"create", "-t", "--name", "log", ALPINE})
-		session.WaitWithDefaultTimeout()
-		Expect(session).To(Exit(0))
+		It("podman logs on a created container should result in 0 exit code: "+log, func() {
+			session := podmanTest.Podman([]string{"create", "-t", "--name", "log", ALPINE})
+			session.WaitWithDefaultTimeout()
+			Expect(session).To(Exit(0))
 
-		results := podmanTest.Podman([]string{"logs", "log"})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(Exit(0))
-	})
+			results := podmanTest.Podman([]string{"logs", "log"})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(Exit(0))
+		})
+
+		It("for container: "+log, func() {
+			logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+			logc.WaitWithDefaultTimeout()
+			Expect(logc).To(Exit(0))
+			cid := logc.OutputToString()
+
+			results := podmanTest.Podman([]string{"logs", cid})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(Exit(0))
+			Expect(len(results.OutputToStringArray())).To(Equal(3))
+			Expect(results.OutputToString()).To(Equal("podman podman podman"))
+		})
+
+		It("tail two lines: "+log, func() {
+			logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+			logc.WaitWithDefaultTimeout()
+			Expect(logc).To(Exit(0))
+			cid := logc.OutputToString()
+			results := podmanTest.Podman([]string{"logs", "--tail", "2", cid})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(Exit(0))
+			Expect(len(results.OutputToStringArray())).To(Equal(2))
+		})
+
+		It("tail 99 lines: "+log, func() {
+			logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+			logc.WaitWithDefaultTimeout()
+			Expect(logc).To(Exit(0))
+			cid := logc.OutputToString()
+
+			results := podmanTest.Podman([]string{"logs", "--tail", "99", cid})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(Exit(0))
+			Expect(len(results.OutputToStringArray())).To(Equal(3))
+		})
+
+		It("tail 2 lines with timestamps: "+log, func() {
+			logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+			logc.WaitWithDefaultTimeout()
+			Expect(logc).To(Exit(0))
+			cid := logc.OutputToString()
+
+			results := podmanTest.Podman([]string{"logs", "--tail", "2", "-t", cid})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(Exit(0))
+			Expect(len(results.OutputToStringArray())).To(Equal(2))
+		})
+
+		It("since time 2017-08-07: "+log, func() {
+			logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+			logc.WaitWithDefaultTimeout()
+			Expect(logc).To(Exit(0))
+			cid := logc.OutputToString()
+
+			results := podmanTest.Podman([]string{"logs", "--since", "2017-08-07T10:10:09.056611202-04:00", cid})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(Exit(0))
+			Expect(len(results.OutputToStringArray())).To(Equal(3))
+		})
+
+		It("with duration 10m: "+log, func() {
+			logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
+			logc.WaitWithDefaultTimeout()
+			Expect(logc).To(Exit(0))
+			cid := logc.OutputToString()
+
+			results := podmanTest.Podman([]string{"logs", "--since", "10m", cid})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(Exit(0))
+			Expect(len(results.OutputToStringArray())).To(Equal(3))
+		})
+
+		It("streaming output: "+log, func() {
+			containerName := "logs-f-rm"
+
+			logc := podmanTest.Podman([]string{"run", "--log-driver", log, "--rm", "--name", containerName, "-dt", ALPINE, "sh", "-c", "echo podman; sleep 1; echo podman"})
+			logc.WaitWithDefaultTimeout()
+			Expect(logc).To(Exit(0))
+
+			results := podmanTest.Podman([]string{"logs", "-f", containerName})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(Exit(0))
+
+			// TODO: we should actually check for two podman lines,
+			// but as of 2020-06-17 there's a race condition in which
+			// 'logs -f' may not catch all output from a container
+			Expect(results.OutputToString()).To(ContainSubstring("podman"))
+
+			// Container should now be terminatING or terminatED, but we
+			// have no guarantee of which: 'logs -f' does not necessarily
+			// wait for cleanup. Run 'inspect' and accept either state.
+			inspect := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.State.Status}}", containerName})
+			inspect.WaitWithDefaultTimeout()
+			if inspect.ExitCode() == 0 {
+				Expect(inspect.OutputToString()).To(Equal("exited"))
+				// TODO: add 2-second wait loop to confirm cleanup
+			} else {
+				Expect(inspect.ErrorToString()).To(ContainSubstring("no such container"))
+			}
+		})
+
+		It("podman logs with log-driver=none errors: "+log, func() {
+			ctrName := "logsctr"
+			logc := podmanTest.Podman([]string{"run", "--log-driver", log, "--name", ctrName, "-d", "--log-driver", "none", ALPINE, "top"})
+			logc.WaitWithDefaultTimeout()
+			Expect(logc).To(Exit(0))
+
+			logs := podmanTest.Podman([]string{"logs", "-f", ctrName})
+			logs.WaitWithDefaultTimeout()
+			Expect(logs).To(Not(Exit(0)))
+		})
+
+		It("follow output stopped container: "+log, func() {
+			containerName := "logs-f"
+
+			logc := podmanTest.Podman([]string{"run", "--log-driver", log, "--name", containerName, "-d", ALPINE, "true"})
+			logc.WaitWithDefaultTimeout()
+			Expect(logc).To(Exit(0))
+
+			results := podmanTest.Podman([]string{"logs", "-f", containerName})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(Exit(0))
+		})
+
+		It("using container with container log-size: "+log, func() {
+			logc := podmanTest.Podman([]string{"run", "--log-driver", log, "--log-opt=max-size=10k", "-d", ALPINE, "sh", "-c", "echo podman podman podman"})
+			logc.WaitWithDefaultTimeout()
+			Expect(logc).To(Exit(0))
+			cid := logc.OutputToString()
+
+			wait := podmanTest.Podman([]string{"wait", cid})
+			wait.WaitWithDefaultTimeout()
+			Expect(wait).To(Exit(0))
+
+			inspect := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.HostConfig.LogConfig.Size}}", cid})
+			inspect.WaitWithDefaultTimeout()
+			Expect(inspect).To(Exit(0))
+			Expect(inspect.OutputToString()).To(Equal("10kB"))
+
+			results := podmanTest.Podman([]string{"logs", cid})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(Exit(0))
+			Expect(results.OutputToString()).To(Equal("podman podman podman"))
+		})
+
+		It("Make sure logs match expected length: "+log, func() {
+			logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-t", "--name", "test", ALPINE, "sh", "-c", "echo 1; echo 2"})
+			logc.WaitWithDefaultTimeout()
+			Expect(logc).To(Exit(0))
+
+			wait := podmanTest.Podman([]string{"wait", "test"})
+			wait.WaitWithDefaultTimeout()
+			Expect(wait).To(Exit(0))
+
+			results := podmanTest.Podman([]string{"logs", "test"})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(Exit(0))
+			outlines := results.OutputToStringArray()
+			Expect(len(outlines)).To(Equal(2))
+			Expect(outlines[0]).To(Equal("1\r"))
+			Expect(outlines[1]).To(Equal("2\r"))
+		})
+
+		It("podman logs test stdout and stderr: "+log, func() {
+			cname := "log-test"
+			logc := podmanTest.Podman([]string{"run", "--log-driver", log, "--name", cname, ALPINE, "sh", "-c", "echo stdout; echo stderr >&2"})
+			logc.WaitWithDefaultTimeout()
+			Expect(logc).To(Exit(0))
+
+			wait := podmanTest.Podman([]string{"wait", cname})
+			wait.WaitWithDefaultTimeout()
+			Expect(wait).To(Exit(0))
+
+			results := podmanTest.Podman([]string{"logs", cname})
+			results.WaitWithDefaultTimeout()
+			Expect(results).To(Exit(0))
+			Expect(results.OutputToString()).To(Equal("stdout"))
+			Expect(results.ErrorToString()).To(Equal("stderr"))
+		})
+	}
 
 	It("using journald for container with container tag", func() {
-		Skip("need to verify images have correct packages for journald")
+		SkipIfInContainer("journalctl inside a container doesn't work correctly")
 		logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "--log-opt=tag={{.ImageName}}", "-d", ALPINE, "sh", "-c", "echo podman; sleep 0.1; echo podman; sleep 0.1; echo podman"})
 		logc.WaitWithDefaultTimeout()
 		Expect(logc).To(Exit(0))
 		cid := logc.OutputToString()
 
-		wait := podmanTest.Podman([]string{"wait", "-l"})
-		wait.WaitWithDefaultTimeout()
-		Expect(wait).To(Exit(0))
-
-		cmd := exec.Command("journalctl", "--no-pager", "-o", "json", "--output-fields=CONTAINER_TAG", "-u", fmt.Sprintf("libpod-conmon-%s.scope", cid))
-		out, err := cmd.CombinedOutput()
-		Expect(err).To(BeNil())
-		Expect(string(out)).To(ContainSubstring("alpine"))
-	})
-
-	It("using journald for container name", func() {
-		Skip("need to verify images have correct packages for journald")
-		containerName := "inside-journal"
-		logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-d", "--name", containerName, ALPINE, "sh", "-c", "echo podman; sleep 0.1; echo podman; sleep 0.1; echo podman"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
-		cid := logc.OutputToString()
-
-		wait := podmanTest.Podman([]string{"wait", "-l"})
-		wait.WaitWithDefaultTimeout()
-		Expect(wait).To(Exit(0))
-
-		cmd := exec.Command("journalctl", "--no-pager", "-o", "json", "--output-fields=CONTAINER_NAME", "-u", fmt.Sprintf("libpod-conmon-%s.scope", cid))
-		out, err := cmd.CombinedOutput()
-		Expect(err).To(BeNil())
-		Expect(string(out)).To(ContainSubstring(containerName))
-	})
-
-	It("using journald for container", func() {
-		Skip("need to verify images have correct packages for journald")
-		logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
-		cid := logc.OutputToString()
-
-		results := podmanTest.Podman([]string{"logs", cid})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(Exit(0))
-		Expect(len(results.OutputToStringArray())).To(Equal(3))
-		Expect(results.OutputToString()).To(Equal("podman podman podman"))
-	})
-
-	It("using journald tail two lines", func() {
-		Skip("need to verify images have correct packages for journald")
-		logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
-		cid := logc.OutputToString()
-		results := podmanTest.Podman([]string{"logs", "--tail", "2", cid})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(Exit(0))
-		Expect(len(results.OutputToStringArray())).To(Equal(2))
-	})
-
-	It("using journald tail 99 lines", func() {
-		Skip("need to verify images have correct packages for journald")
-		logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
-		cid := logc.OutputToString()
-
-		results := podmanTest.Podman([]string{"logs", "--tail", "99", cid})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(Exit(0))
-		Expect(len(results.OutputToStringArray())).To(Equal(3))
-	})
-
-	It("using journald tail 2 lines with timestamps", func() {
-		Skip("need to verify images have correct packages for journald")
-		logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
-		cid := logc.OutputToString()
-
-		results := podmanTest.Podman([]string{"logs", "--tail", "2", "-t", cid})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(Exit(0))
-		Expect(len(results.OutputToStringArray())).To(Equal(2))
-	})
-
-	It("using journald since time 2017-08-07", func() {
-		Skip("need to verify images have correct packages for journald")
-		logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
-		cid := logc.OutputToString()
-
-		results := podmanTest.Podman([]string{"logs", "--since", "2017-08-07T10:10:09.056611202-04:00", cid})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(Exit(0))
-		Expect(len(results.OutputToStringArray())).To(Equal(3))
-	})
-
-	It("using journald with duration 10m", func() {
-		Skip("need to verify images have correct packages for journald")
-		logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
-		cid := logc.OutputToString()
-
-		results := podmanTest.Podman([]string{"logs", "--since", "10m", cid})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(Exit(0))
-		Expect(len(results.OutputToStringArray())).To(Equal(3))
-	})
-
-	It("streaming output", func() {
-		containerName := "logs-f-rm"
-
-		logc := podmanTest.Podman([]string{"run", "--rm", "--name", containerName, "-dt", ALPINE, "sh", "-c", "echo podman; sleep 1; echo podman"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
-
-		results := podmanTest.Podman([]string{"logs", "-f", containerName})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(Exit(0))
-
-		// TODO: we should actually check for two podman lines,
-		// but as of 2020-06-17 there's a race condition in which
-		// 'logs -f' may not catch all output from a container
-		Expect(results.OutputToString()).To(ContainSubstring("podman"))
-
-		// Container should now be terminatING or terminatED, but we
-		// have no guarantee of which: 'logs -f' does not necessarily
-		// wait for cleanup. Run 'inspect' and accept either state.
-		inspect := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.State.Status}}", containerName})
-		inspect.WaitWithDefaultTimeout()
-		if inspect.ExitCode() == 0 {
-			Expect(inspect.OutputToString()).To(Equal("exited"))
-			// TODO: add 2-second wait loop to confirm cleanup
-		} else {
-			Expect(inspect.ErrorToString()).To(ContainSubstring("no such container"))
-		}
-	})
-
-	It("podman logs with log-driver=none errors", func() {
-		ctrName := "logsctr"
-		logc := podmanTest.Podman([]string{"run", "--name", ctrName, "-d", "--log-driver", "none", ALPINE, "top"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
-
-		logs := podmanTest.Podman([]string{"logs", "-f", ctrName})
-		logs.WaitWithDefaultTimeout()
-		Expect(logs).To(Not(Exit(0)))
-	})
-
-	It("follow output stopped container", func() {
-		containerName := "logs-f"
-
-		logc := podmanTest.Podman([]string{"run", "--name", containerName, "-d", ALPINE, "true"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
-
-		results := podmanTest.Podman([]string{"logs", "-f", containerName})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(Exit(0))
-	})
-
-	It("using container with container log-size", func() {
-		logc := podmanTest.Podman([]string{"run", "--log-opt=max-size=10k", "-d", ALPINE, "sh", "-c", "echo podman podman podman"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
-		cid := logc.OutputToString()
-
 		wait := podmanTest.Podman([]string{"wait", cid})
 		wait.WaitWithDefaultTimeout()
 		Expect(wait).To(Exit(0))
 
-		inspect := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.HostConfig.LogConfig.Size}}", cid})
-		inspect.WaitWithDefaultTimeout()
-		Expect(inspect).To(Exit(0))
-		Expect(inspect.OutputToString()).To(Equal("10kB"))
-
-		results := podmanTest.Podman([]string{"logs", cid})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(Exit(0))
-		Expect(results.OutputToString()).To(Equal("podman podman podman"))
+		cmd := exec.Command("journalctl", "--no-pager", "-o", "json", "--output-fields=CONTAINER_TAG", fmt.Sprintf("CONTAINER_ID_FULL=%s", cid))
+		out, err := cmd.CombinedOutput()
+		Expect(err).To(BeNil())
+		Expect(string(out)).To(ContainSubstring("alpine"))
 	})
 
-	It("Make sure logs match expected length", func() {
-		logc := podmanTest.Podman([]string{"run", "-t", "--name", "test", ALPINE, "sh", "-c", "echo 1; echo 2"})
+	It("using journald container name", func() {
+		SkipIfInContainer("journalctl inside a container doesn't work correctly")
+		containerName := "inside-journal"
+		logc := podmanTest.Podman([]string{"run", "--log-driver", "journald", "-d", "--name", containerName, ALPINE, "sh", "-c", "echo podman; sleep 0.1; echo podman; sleep 0.1; echo podman"})
 		logc.WaitWithDefaultTimeout()
 		Expect(logc).To(Exit(0))
+		cid := logc.OutputToString()
 
-		wait := podmanTest.Podman([]string{"wait", "test"})
+		wait := podmanTest.Podman([]string{"wait", cid})
 		wait.WaitWithDefaultTimeout()
 		Expect(wait).To(Exit(0))
 
-		results := podmanTest.Podman([]string{"logs", "test"})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(Exit(0))
-		outlines := results.OutputToStringArray()
-		Expect(len(outlines)).To(Equal(2))
-		Expect(outlines[0]).To(Equal("1\r"))
-		Expect(outlines[1]).To(Equal("2\r"))
-	})
-
-	It("podman logs test stdout and stderr", func() {
-		cname := "log-test"
-		logc := podmanTest.Podman([]string{"run", "--name", cname, ALPINE, "sh", "-c", "echo stdout; echo stderr >&2"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
-
-		wait := podmanTest.Podman([]string{"wait", cname})
-		wait.WaitWithDefaultTimeout()
-		Expect(wait).To(Exit(0))
-
-		results := podmanTest.Podman([]string{"logs", cname})
-		results.WaitWithDefaultTimeout()
-		Expect(results).To(Exit(0))
-		Expect(results.OutputToString()).To(Equal("stdout"))
-		Expect(results.ErrorToString()).To(Equal("stderr"))
+		cmd := exec.Command("journalctl", "--no-pager", "-o", "json", "--output-fields=CONTAINER_NAME", fmt.Sprintf("CONTAINER_ID_FULL=%s", cid))
+		out, err := cmd.CombinedOutput()
+		Expect(err).To(BeNil())
+		Expect(string(out)).To(ContainSubstring(containerName))
 	})
 })
diff --git a/test/utils/utils.go b/test/utils/utils.go
index 6790f31cdd..80af7fb7c2 100644
--- a/test/utils/utils.go
+++ b/test/utils/utils.go
@@ -482,3 +482,13 @@ func RandomString(n int) string {
 	}
 	return string(b)
 }
+
+//SkipIfInContainer skips a test if the test is run inside a container
+func SkipIfInContainer(reason string) {
+	if len(reason) < 5 {
+		panic("SkipIfInContainer must specify a reason to skip")
+	}
+	if os.Getenv("TEST_ENVIRON") == "container" {
+		Skip("[container]: " + reason)
+	}
+}