aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libpod/healthcheck.go36
-rw-r--r--pkg/api/handlers/compat/images_build.go2
-rw-r--r--test/apiv2/10-images.at5
-rw-r--r--test/e2e/healthcheck_run_test.go22
-rw-r--r--test/system/220-healthcheck.bats17
5 files changed, 52 insertions, 30 deletions
diff --git a/libpod/healthcheck.go b/libpod/healthcheck.go
index 53bad47b4..40af9aec3 100644
--- a/libpod/healthcheck.go
+++ b/libpod/healthcheck.go
@@ -2,7 +2,6 @@ package libpod
import (
"bufio"
- "bytes"
"io/ioutil"
"os"
"path/filepath"
@@ -22,16 +21,6 @@ const (
MaxHealthCheckLogLength = 500
)
-// hcWriteCloser allows us to use bufio as a WriteCloser
-type hcWriteCloser struct {
- *bufio.Writer
-}
-
-// Used to add a closer to bufio
-func (hcwc hcWriteCloser) Close() error {
- return nil
-}
-
// HealthCheck verifies the state and validity of the healthcheck configuration
// on the container and then executes the healthcheck
func (r *Runtime) HealthCheck(name string) (define.HealthCheckStatus, error) {
@@ -51,7 +40,6 @@ func (c *Container) runHealthCheck() (define.HealthCheckStatus, error) {
var (
newCommand []string
returnCode int
- capture bytes.Buffer
inStartPeriod bool
)
hcCommand := c.HealthCheckConfig().Test
@@ -73,20 +61,30 @@ func (c *Container) runHealthCheck() (define.HealthCheckStatus, error) {
if len(newCommand) < 1 || newCommand[0] == "" {
return define.HealthCheckNotDefined, errors.Errorf("container %s has no defined healthcheck", c.ID())
}
- captureBuffer := bufio.NewWriter(&capture)
- hcw := hcWriteCloser{
- captureBuffer,
+ rPipe, wPipe, err := os.Pipe()
+ if err != nil {
+ return define.HealthCheckInternalError, errors.Wrapf(err, "unable to create pipe for healthcheck session")
}
+ defer wPipe.Close()
+ defer rPipe.Close()
+
streams := new(define.AttachStreams)
- streams.OutputStream = hcw
- streams.ErrorStream = hcw
streams.InputStream = bufio.NewReader(os.Stdin)
-
+ streams.OutputStream = wPipe
+ streams.ErrorStream = wPipe
streams.AttachOutput = true
streams.AttachError = true
streams.AttachInput = true
+ stdout := []string{}
+ go func() {
+ scanner := bufio.NewScanner(rPipe)
+ for scanner.Scan() {
+ stdout = append(stdout, scanner.Text())
+ }
+ }()
+
logrus.Debugf("executing health check command %s for %s", strings.Join(newCommand, " "), c.ID())
timeStart := time.Now()
hcResult := define.HealthCheckSuccess
@@ -119,7 +117,7 @@ func (c *Container) runHealthCheck() (define.HealthCheckStatus, error) {
}
}
- eventLog := capture.String()
+ eventLog := strings.Join(stdout, "\n")
if len(eventLog) > MaxHealthCheckLogLength {
eventLog = eventLog[:MaxHealthCheckLogLength]
}
diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go
index cc9667202..0ebf74f98 100644
--- a/pkg/api/handlers/compat/images_build.go
+++ b/pkg/api/handlers/compat/images_build.go
@@ -605,8 +605,8 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
}
// Send headers and prime client for stream to come
- w.WriteHeader(http.StatusOK)
w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
flush()
body := w.(io.Writer)
diff --git a/test/apiv2/10-images.at b/test/apiv2/10-images.at
index 673858a3c..9526183e3 100644
--- a/test/apiv2/10-images.at
+++ b/test/apiv2/10-images.at
@@ -190,6 +190,11 @@ t POST "libpod/build?dockerfile=containerfile" $CONTAINERFILE_TAR application/js
t POST "build?dockerfile=containerfile" $CONTAINERFILE_TAR application/json 200 \
.stream~"STEP 1/1: FROM $IMAGE"
+# Build api response header must contain Content-type: application/json
+t POST "build?dockerfile=containerfile" $CONTAINERFILE_TAR application/json 200
+response_headers=$(cat "$WORKDIR/curl.headers.out")
+like "$response_headers" ".*application/json.*" "header does not contains application/json"
+
# PR #12091: output from compat API must now include {"aux":{"ID":"sha..."}}
t POST "build?dockerfile=containerfile" $CONTAINERFILE_TAR 200 \
'.aux|select(has("ID")).ID~^sha256:[0-9a-f]\{64\}$'
diff --git a/test/e2e/healthcheck_run_test.go b/test/e2e/healthcheck_run_test.go
index c84488145..866edbf0e 100644
--- a/test/e2e/healthcheck_run_test.go
+++ b/test/e2e/healthcheck_run_test.go
@@ -54,6 +54,28 @@ var _ = Describe("Podman healthcheck run", func() {
Expect(hc).Should(Exit(125))
})
+ It("podman run healthcheck and logs should contain healthcheck output", func() {
+ session := podmanTest.Podman([]string{"run", "--name", "test-logs", "-dt", "--health-interval", "1s", "--health-cmd", "echo working", "busybox", "sleep", "3600"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ // Buy a little time to get container running
+ for i := 0; i < 5; i++ {
+ hc := podmanTest.Podman([]string{"healthcheck", "run", "test-logs"})
+ hc.WaitWithDefaultTimeout()
+ exitCode := hc.ExitCode()
+ if exitCode == 0 || i == 4 {
+ break
+ }
+ time.Sleep(1 * time.Second)
+ }
+
+ hc := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.State.Healthcheck.Log}}", "test-logs"})
+ hc.WaitWithDefaultTimeout()
+ Expect(hc).Should(Exit(0))
+ Expect(hc.OutputToString()).To(ContainSubstring("working"))
+ })
+
It("podman healthcheck from image's config (not container config)", func() {
// Regression test for #12226: a health check may be defined in
// the container or the container-config of an image.
diff --git a/test/system/220-healthcheck.bats b/test/system/220-healthcheck.bats
index 1d4a2ea7e..c502ad669 100644
--- a/test/system/220-healthcheck.bats
+++ b/test/system/220-healthcheck.bats
@@ -15,10 +15,7 @@ function _check_health {
run_podman inspect --format "{{json .State.Healthcheck}}" healthcheck_c
parse_table "$tests" | while read field expect;do
- # (kludge to deal with parse_table and empty strings)
- if [ "$expect" = "''" ]; then expect=""; fi
-
- actual=$(jq -r ".$field" <<<"$output")
+ actual=$(jq ".$field" <<<"$output")
is "$actual" "$expect" "$testname - .State.Healthcheck.$field"
done
}
@@ -77,10 +74,10 @@ EOF
is "$output" "" "output from 'podman healthcheck run'"
_check_health "All healthy" "
-Status | healthy
+Status | \"healthy\"
FailingStreak | 0
Log[-1].ExitCode | 0
-Log[-1].Output |
+Log[-1].Output | \"Life is Good on stdout\\\nLife is Good on stderr\"
"
# Force a failure
@@ -88,19 +85,19 @@ Log[-1].Output |
sleep 2
_check_health "First failure" "
-Status | healthy
+Status | \"healthy\"
FailingStreak | [123]
Log[-1].ExitCode | 1
-Log[-1].Output |
+Log[-1].Output | \"Uh-oh on stdout!\\\nUh-oh on stderr!\"
"
# After three successive failures, container should no longer be healthy
sleep 5
_check_health "Three or more failures" "
-Status | unhealthy
+Status | \"unhealthy\"
FailingStreak | [3456]
Log[-1].ExitCode | 1
-Log[-1].Output |
+Log[-1].Output | \"Uh-oh on stdout!\\\nUh-oh on stderr!\"
"
# healthcheck should now fail, with exit status 1 and 'unhealthy' output