summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pkg/api/handlers/libpod/healthcheck.go24
-rw-r--r--pkg/api/server/register_healthcheck.go25
-rw-r--r--pkg/api/server/swagger.go9
-rw-r--r--pkg/bindings/containers/healthcheck.go6
-rw-r--r--pkg/bindings/test/containers_test.go45
5 files changed, 104 insertions, 5 deletions
diff --git a/pkg/api/handlers/libpod/healthcheck.go b/pkg/api/handlers/libpod/healthcheck.go
index 6c74500b9..6eb2ab0e3 100644
--- a/pkg/api/handlers/libpod/healthcheck.go
+++ b/pkg/api/handlers/libpod/healthcheck.go
@@ -14,8 +14,30 @@ func RunHealthCheck(w http.ResponseWriter, r *http.Request) {
if err != nil {
if status == libpod.HealthCheckContainerNotFound {
utils.ContainerNotFound(w, name, err)
+ return
}
+ if status == libpod.HealthCheckNotDefined {
+ utils.Error(w, "no healthcheck defined", http.StatusConflict, err)
+ return
+ }
+ if status == libpod.HealthCheckContainerStopped {
+ utils.Error(w, "container not running", http.StatusConflict, err)
+ return
+ }
+ utils.InternalServerError(w, err)
+ return
+ }
+ ctr, err := runtime.LookupContainer(name)
+ if err != nil {
utils.InternalServerError(w, err)
+ return
}
- utils.WriteResponse(w, http.StatusOK, status)
+
+ hcLog, err := ctr.GetHealthCheckLog()
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
+
+ utils.WriteResponse(w, http.StatusOK, hcLog)
}
diff --git a/pkg/api/server/register_healthcheck.go b/pkg/api/server/register_healthcheck.go
index 5466e2905..69aa5bbfb 100644
--- a/pkg/api/server/register_healthcheck.go
+++ b/pkg/api/server/register_healthcheck.go
@@ -8,6 +8,29 @@ import (
)
func (s *APIServer) registerHealthCheckHandlers(r *mux.Router) error {
- r.Handle(VersionedPath("/libpod/containers/{name}/runhealthcheck"), s.APIHandler(libpod.RunHealthCheck)).Methods(http.MethodGet)
+ // swagger:operation GET /libpod/containers/{name:.*}/healthcheck libpod libpodRunHealthCheck
+ // ---
+ // tags:
+ // - containers
+ // summary: Run a container's healthcheck
+ // description: Execute the defined healthcheck and return information about the results
+ // parameters:
+ // - in: path
+ // name: name:.*
+ // type: string
+ // required: true
+ // description: the name or ID of the container
+ // produces:
+ // - application/json
+ // responses:
+ // 200:
+ // $ref: "#/responses/HealthcheckRun"
+ // 404:
+ // $ref: "#/responses/NoSuchContainer"
+ // 409:
+ // description: container has no healthcheck or is not running
+ // 500:
+ // $ref: '#/responses/InternalError'
+ r.Handle(VersionedPath("/libpod/containers/{name:.*}/healthcheck"), s.APIHandler(libpod.RunHealthCheck)).Methods(http.MethodGet)
return nil
}
diff --git a/pkg/api/server/swagger.go b/pkg/api/server/swagger.go
index 011196e5a..e3c991d6d 100644
--- a/pkg/api/server/swagger.go
+++ b/pkg/api/server/swagger.go
@@ -156,3 +156,12 @@ type swagVolumeListResponse struct {
// in:body
Body []libpod.Volume
}
+
+// Healthcheck
+// swagger:response HealthcheckRun
+type swagHealthCheckRunResponse struct {
+ // in:body
+ Body struct {
+ libpod.HealthCheckResults
+ }
+}
diff --git a/pkg/bindings/containers/healthcheck.go b/pkg/bindings/containers/healthcheck.go
index 3f94fad01..85cc2814c 100644
--- a/pkg/bindings/containers/healthcheck.go
+++ b/pkg/bindings/containers/healthcheck.go
@@ -10,15 +10,15 @@ import (
// RunHealthCheck executes the container's healthcheck and returns the health status of the
// container.
-func RunHealthCheck(ctx context.Context, nameOrID string) (*libpod.HealthCheckStatus, error) {
+func RunHealthCheck(ctx context.Context, nameOrID string) (*libpod.HealthCheckResults, error) {
conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
}
var (
- status libpod.HealthCheckStatus
+ status libpod.HealthCheckResults
)
- response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/runhealthcheck", nil, nameOrID)
+ response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/healthcheck", nil, nameOrID)
if err != nil {
return nil, err
}
diff --git a/pkg/bindings/test/containers_test.go b/pkg/bindings/test/containers_test.go
index e7ef620d4..34a9c3136 100644
--- a/pkg/bindings/test/containers_test.go
+++ b/pkg/bindings/test/containers_test.go
@@ -312,4 +312,49 @@ var _ = Describe("Podman containers ", func() {
Expect(exitCode).To(BeNumerically("==", -1))
})
+ It("run healthcheck", func() {
+ bt.runPodman([]string{"run", "-d", "--name", "hc", "--health-interval", "disable", "--health-retries", "2", "--health-cmd", "ls / || exit 1", alpine.name, "top"})
+
+ // bogus name should result in 404
+ _, err := containers.RunHealthCheck(bt.conn, "foobar")
+ Expect(err).ToNot(BeNil())
+ code, _ := bindings.CheckResponseCode(err)
+ Expect(code).To(BeNumerically("==", http.StatusNotFound))
+
+ // a container that has no healthcheck should be a 409
+ var name = "top"
+ bt.RunTopContainer(&name, &falseFlag, nil)
+ _, err = containers.RunHealthCheck(bt.conn, name)
+ Expect(err).ToNot(BeNil())
+ code, _ = bindings.CheckResponseCode(err)
+ Expect(code).To(BeNumerically("==", http.StatusConflict))
+
+ // TODO for the life of me, i cannot get this to work. maybe another set
+ // of eyes will
+ // successful healthcheck
+ //status := "healthy"
+ //for i:=0; i < 10; i++ {
+ // result, err := containers.RunHealthCheck(connText, "hc")
+ // Expect(err).To(BeNil())
+ // if result.Status != "healthy" {
+ // fmt.Println("Healthcheck container still starting, retrying in 1 second")
+ // time.Sleep(1 * time.Second)
+ // continue
+ // }
+ // status = result.Status
+ // break
+ //}
+ //Expect(status).To(Equal("healthy"))
+
+ // TODO enable this when wait is working
+ // healthcheck on a stopped container should be a 409
+ //err = containers.Stop(connText, "hc", nil)
+ //Expect(err).To(BeNil())
+ //_, err = containers.Wait(connText, "hc")
+ //Expect(err).To(BeNil())
+ //_, err = containers.RunHealthCheck(connText, "hc")
+ //code, _ = bindings.CheckResponseCode(err)
+ //Expect(code).To(BeNumerically("==", http.StatusConflict))
+ })
+
})