Adds healthcheck

This PR adds support for HealthCheck, being able to supply, for example:

```yaml
version: "3"

services:
  redis:
    image: redis
    healthcheck:
      test: echo "hello world"
      interval: 10s
      timeout: 1s
      retries: 5
```

Which is then converted to:

```yaml
spec:
  containers:
  - image: redis
    livenessProbe:
      exec:
        command:
        - echo "hello world"
      failureThreshold: 5
      periodSeconds: 10
      timeoutSeconds: 1
    name: redis
    resources: {}
  restartPolicy: Always
```

At the moment, this only supports livenessProbe, with support for readinessProbe in the future.
This commit is contained in:
Charlie Drage
2017-08-25 10:02:51 -04:00
parent 2ff2d38ed1
commit 2e99b8fd3a
11 changed files with 391 additions and 3 deletions
+29
View File
@@ -32,6 +32,34 @@ import (
"github.com/pkg/errors"
)
func TestParseHealthCheck(t *testing.T) {
helperValue := uint64(2)
check := types.HealthCheckConfig{
Test: []string{"CMD-SHELL", "echo", "foobar"},
Timeout: "1s",
Interval: "2s",
Retries: &helperValue,
StartPeriod: "3s",
}
// CMD-SHELL or SHELL is included Test within docker/cli, thus we remove the first value in Test
expected := kobject.HealthCheck{
Test: []string{"echo", "foobar"},
Timeout: 1,
Interval: 2,
Retries: 2,
StartPeriod: 3,
}
output, err := parseHealthCheck(check)
if err != nil {
t.Errorf("Unable to convert HealthCheckConfig: %s", err)
}
if !reflect.DeepEqual(output, expected) {
t.Errorf("Structs are not equal, expected: %s, output: %s", expected, output)
}
}
func TestLoadV3Volumes(t *testing.T) {
vol := types.ServiceVolumeConfig{
Type: "volume",
@@ -66,6 +94,7 @@ func TestLoadV3Ports(t *testing.T) {
if output[0] != expected {
t.Errorf("Expected %v, got %v", expected, output[0])
}
}
// Test if service types are parsed properly on user input
+57
View File
@@ -20,6 +20,7 @@ import (
"io/ioutil"
"strconv"
"strings"
"time"
libcomposeyaml "github.com/docker/libcompose/yaml"
@@ -162,6 +163,52 @@ func loadV3Ports(ports []types.ServicePortConfig) []kobject.Ports {
return komposePorts
}
/* Convert the HealthCheckConfig as designed by Docker to
a Kubernetes-compatible format.
*/
func parseHealthCheck(composeHealthCheck types.HealthCheckConfig) (kobject.HealthCheck, error) {
var timeout, interval, retries, startPeriod int32
// Here we convert the timeout from 1h30s (example) to 36030 seconds.
if composeHealthCheck.Timeout != "" {
parse, err := time.ParseDuration(composeHealthCheck.Timeout)
if err != nil {
return kobject.HealthCheck{}, errors.Wrap(err, "unable to parse health check timeout variable")
}
timeout = int32(parse.Seconds())
}
if composeHealthCheck.Interval != "" {
parse, err := time.ParseDuration(composeHealthCheck.Interval)
if err != nil {
return kobject.HealthCheck{}, errors.Wrap(err, "unable to parse health check interval variable")
}
interval = int32(parse.Seconds())
}
if *composeHealthCheck.Retries != 0 {
retries = int32(*composeHealthCheck.Retries)
}
if composeHealthCheck.StartPeriod != "" {
parse, err := time.ParseDuration(composeHealthCheck.StartPeriod)
if err != nil {
return kobject.HealthCheck{}, errors.Wrap(err, "unable to parse health check startPeriod variable")
}
startPeriod = int32(parse.Seconds())
}
// Due to docker/cli adding "CMD-SHELL" to the struct, we remove the first element of composeHealthCheck.Test
return kobject.HealthCheck{
Test: composeHealthCheck.Test[1:],
Timeout: timeout,
Interval: interval,
Retries: retries,
StartPeriod: startPeriod,
}, nil
}
func dockerComposeToKomposeMapping(composeObject *types.Config) (kobject.KomposeObject, error) {
// Step 1. Initialize what's going to be returned
@@ -198,8 +245,18 @@ func dockerComposeToKomposeMapping(composeObject *types.Config) (kobject.Kompose
// Deploy keys
//
// mode:
serviceConfig.DeployMode = composeServiceConfig.Deploy.Mode
// HealthCheck
if composeServiceConfig.HealthCheck != nil && !composeServiceConfig.HealthCheck.Disable {
var err error
serviceConfig.HealthChecks, err = parseHealthCheck(*composeServiceConfig.HealthCheck)
if err != nil {
return kobject.KomposeObject{}, errors.Wrap(err, "Unable to parse health check")
}
}
if (composeServiceConfig.Deploy.Resources != types.Resources{}) {
// memory: