Browse code

Add support for healthcheck in composefile v3

`docker stack deploy` now supports a composefile v3 format that have a
healthcheck.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>

Vincent Demeester authored on 2016/11/18 23:09:13
Showing 2 changed files
... ...
@@ -6,6 +6,7 @@ import (
6 6
 	"os"
7 7
 	"sort"
8 8
 	"strings"
9
+	"time"
9 10
 
10 11
 	"github.com/spf13/cobra"
11 12
 	"golang.org/x/net/context"
... ...
@@ -13,6 +14,7 @@ import (
13 13
 	"github.com/aanand/compose-file/loader"
14 14
 	composetypes "github.com/aanand/compose-file/types"
15 15
 	"github.com/docker/docker/api/types"
16
+	"github.com/docker/docker/api/types/container"
16 17
 	"github.com/docker/docker/api/types/mount"
17 18
 	networktypes "github.com/docker/docker/api/types/network"
18 19
 	"github.com/docker/docker/api/types/swarm"
... ...
@@ -487,6 +489,11 @@ func convertService(
487 487
 		return swarm.ServiceSpec{}, err
488 488
 	}
489 489
 
490
+	healthcheck, err := convertHealthcheck(service.HealthCheck)
491
+	if err != nil {
492
+		return swarm.ServiceSpec{}, err
493
+	}
494
+
490 495
 	serviceSpec := swarm.ServiceSpec{
491 496
 		Annotations: swarm.Annotations{
492 497
 			Name:   name,
... ...
@@ -499,6 +506,7 @@ func convertService(
499 499
 				Args:            service.Command,
500 500
 				Hostname:        service.Hostname,
501 501
 				Hosts:           convertExtraHosts(service.ExtraHosts),
502
+				Healthcheck:     healthcheck,
502 503
 				Env:             convertEnvironment(service.Environment),
503 504
 				Labels:          getStackLabels(namespace.name, service.Labels),
504 505
 				Dir:             service.WorkingDir,
... ...
@@ -531,6 +539,47 @@ func convertExtraHosts(extraHosts map[string]string) []string {
531 531
 	return hosts
532 532
 }
533 533
 
534
+func convertHealthcheck(healthcheck *composetypes.HealthCheckConfig) (*container.HealthConfig, error) {
535
+	if healthcheck == nil {
536
+		return nil, nil
537
+	}
538
+	var (
539
+		err               error
540
+		timeout, interval time.Duration
541
+		retries           int
542
+	)
543
+	if healthcheck.Disable {
544
+		if len(healthcheck.Test) != 0 {
545
+			return nil, fmt.Errorf("command and disable key can't be set at the same time")
546
+		}
547
+		return &container.HealthConfig{
548
+			Test: []string{"NONE"},
549
+		}, nil
550
+
551
+	}
552
+	if healthcheck.Timeout != "" {
553
+		timeout, err = time.ParseDuration(healthcheck.Timeout)
554
+		if err != nil {
555
+			return nil, err
556
+		}
557
+	}
558
+	if healthcheck.Interval != "" {
559
+		interval, err = time.ParseDuration(healthcheck.Interval)
560
+		if err != nil {
561
+			return nil, err
562
+		}
563
+	}
564
+	if healthcheck.Retries != nil {
565
+		retries = int(*healthcheck.Retries)
566
+	}
567
+	return &container.HealthConfig{
568
+		Test:     healthcheck.Test,
569
+		Timeout:  timeout,
570
+		Interval: interval,
571
+		Retries:  retries,
572
+	}, nil
573
+}
574
+
534 575
 func convertRestartPolicy(restart string, source *composetypes.RestartPolicy) (*swarm.RestartPolicy, error) {
535 576
 	// TODO: log if restart is being ignored
536 577
 	if source == nil {
... ...
@@ -128,6 +128,7 @@ type HealthCheckConfig struct {
128 128
 	Timeout  string
129 129
 	Interval string
130 130
 	Retries  *uint64
131
+	Disable  bool
131 132
 }
132 133
 
133 134
 type UpdateConfig struct {