Merge pull request #845 from docker/add-aci-healthcheck

Add Healthchecks to ACI
This commit is contained in:
Guillaume Tardif 2020-11-06 13:47:33 +01:00 committed by GitHub
commit af1dae52eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 720 additions and 313 deletions

View File

@ -40,6 +40,7 @@ func ContainerToComposeProject(r containers.ContainerConfig) (types.Project, err
return types.Project{}, err
}
retries := uint64(r.Healthcheck.Retries)
project := types.Project{
Name: r.ID,
Services: []types.ServiceConfig{
@ -52,6 +53,14 @@ func ContainerToComposeProject(r containers.ContainerConfig) (types.Project, err
Volumes: serviceConfigVolumes,
DomainName: r.DomainName,
Environment: toComposeEnvs(r.Environment),
HealthCheck: &types.HealthCheckConfig{
Test: r.Healthcheck.Test,
Timeout: &r.Healthcheck.Timeout,
Interval: &r.Healthcheck.Interval,
Retries: &retries,
StartPeriod: &r.Healthcheck.StartPeriod,
Disable: r.Healthcheck.Disable,
},
Deploy: &types.DeployConfig{
Resources: types.Resources{
Reservations: &types.Resource{

View File

@ -23,6 +23,7 @@ import (
"os"
"strconv"
"strings"
"time"
"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance"
"github.com/Azure/go-autorest/autorest/to"
@ -68,7 +69,7 @@ func ToContainerGroup(ctx context.Context, aciContext store.AciContext, p types.
return containerinstance.ContainerGroup{}, err
}
var containers []containerinstance.Container
var ctnrs []containerinstance.Container
restartPolicy, err := project.getRestartPolicy()
if err != nil {
return containerinstance.ContainerGroup{}, err
@ -78,7 +79,7 @@ func ToContainerGroup(ctx context.Context, aciContext store.AciContext, p types.
Location: &aciContext.Location,
ContainerGroupProperties: &containerinstance.ContainerGroupProperties{
OsType: containerinstance.Linux,
Containers: &containers,
Containers: &ctnrs,
Volumes: volumes,
ImageRegistryCredentials: &registryCreds,
RestartPolicy: restartPolicy,
@ -110,7 +111,7 @@ func ToContainerGroup(ctx context.Context, aciContext store.AciContext, p types.
dnsLabelName = serviceDomainName
}
containers = append(containers, containerDefinition)
ctnrs = append(ctnrs, containerDefinition)
}
if len(groupPorts) > 0 {
groupDefinition.ContainerGroupProperties.IPAddress = &containerinstance.IPAddress{
@ -119,15 +120,23 @@ func ToContainerGroup(ctx context.Context, aciContext store.AciContext, p types.
DNSNameLabel: dnsLabelName,
}
}
if len(containers) > 1 {
dnsSideCar := getDNSSidecar(containers)
containers = append(containers, dnsSideCar)
if len(ctnrs) > 1 {
dnsSideCar := getDNSSidecar(ctnrs)
ctnrs = append(ctnrs, dnsSideCar)
}
groupDefinition.ContainerGroupProperties.Containers = &containers
groupDefinition.ContainerGroupProperties.Containers = &ctnrs
return groupDefinition, nil
}
func durationToSeconds(d *types.Duration) *int32 {
if d == nil || *d == 0 {
return nil
}
v := int32(time.Duration(*d).Seconds())
return &v
}
func getDNSSidecar(containers []containerinstance.Container) containerinstance.Container {
names := []string{"/hosts"}
for _, container := range containers {
@ -181,6 +190,7 @@ func (s serviceConfigAciHelper) getAciContainer(volumesCache map[string]bool) (c
EnvironmentVariables: getEnvVariables(s.Environment),
Resources: resource,
VolumeMounts: volumes,
LivenessProbe: s.getLivenessProbe(),
},
}, nil
}
@ -237,6 +247,38 @@ func (s serviceConfigAciHelper) getResourceRequestsLimits() (*containerinstance.
return &resources, nil
}
func (s serviceConfigAciHelper) getLivenessProbe() *containerinstance.ContainerProbe {
if s.HealthCheck != nil && !s.HealthCheck.Disable && len(s.HealthCheck.Test) > 0 {
testArray := s.HealthCheck.Test
switch s.HealthCheck.Test[0] {
case "NONE", "CMD", "CMD-SHELL":
testArray = s.HealthCheck.Test[1:]
}
if len(testArray) == 0 {
return nil
}
var retries *int32
if s.HealthCheck.Retries != nil {
retries = to.Int32Ptr(int32(*s.HealthCheck.Retries))
}
probe := containerinstance.ContainerProbe{
Exec: &containerinstance.ContainerExec{
Command: to.StringSlicePtr(testArray),
},
InitialDelaySeconds: durationToSeconds(s.HealthCheck.StartPeriod),
PeriodSeconds: durationToSeconds(s.HealthCheck.Interval),
TimeoutSeconds: durationToSeconds(s.HealthCheck.Timeout),
}
if retries != nil && *retries > 0 {
probe.FailureThreshold = retries
probe.SuccessThreshold = retries
}
return &probe
}
return nil
}
func getEnvVariables(composeEnv types.MappingWithEquals) *[]containerinstance.EnvironmentVariable {
result := []containerinstance.EnvironmentVariable{}
for key, value := range composeEnv {
@ -310,6 +352,31 @@ func ContainerGroupToContainer(containerID string, cg containerinstance.Containe
FQDN: fqdn(cg, region),
Env: envVars,
}
var healthcheck = containers.Healthcheck{
Disable: true,
}
if cc.LivenessProbe != nil &&
cc.LivenessProbe.Exec != nil &&
cc.LivenessProbe.Exec.Command != nil {
if len(*cc.LivenessProbe.Exec.Command) > 0 {
healthcheck.Disable = false
healthcheck.Test = *cc.LivenessProbe.Exec.Command
if cc.LivenessProbe.PeriodSeconds != nil {
healthcheck.Interval = types.Duration(int64(*cc.LivenessProbe.PeriodSeconds) * int64(time.Second))
}
if cc.LivenessProbe.SuccessThreshold != nil {
healthcheck.Retries = int(*cc.LivenessProbe.SuccessThreshold)
}
if cc.LivenessProbe.TimeoutSeconds != nil {
healthcheck.Timeout = types.Duration(int64(*cc.LivenessProbe.TimeoutSeconds) * int64(time.Second))
}
if cc.LivenessProbe.InitialDelaySeconds != nil {
healthcheck.StartPeriod = types.Duration(int64(*cc.LivenessProbe.InitialDelaySeconds) * int64(time.Second))
}
}
}
c := containers.Container{
ID: containerID,
Status: status,
@ -323,6 +390,7 @@ func ContainerGroupToContainer(containerID string, cg containerinstance.Containe
Platform: platform,
Config: config,
HostConfig: hostConfig,
Healthcheck: healthcheck,
}
return c

View File

@ -20,6 +20,7 @@ import (
"context"
"os"
"testing"
"time"
"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance"
"github.com/Azure/go-autorest/autorest/to"
@ -88,6 +89,19 @@ func TestContainerGroupToContainer(t *testing.T) {
MemoryInGB: to.Float64Ptr(0.1),
},
},
LivenessProbe: &containerinstance.ContainerProbe{
Exec: &containerinstance.ContainerExec{
Command: to.StringSlicePtr([]string{
"my",
"command",
"--option",
}),
},
PeriodSeconds: to.Int32Ptr(10),
SuccessThreshold: to.Int32Ptr(3),
InitialDelaySeconds: to.Int32Ptr(2),
TimeoutSeconds: to.Int32Ptr(1),
},
},
}
@ -113,12 +127,111 @@ func TestContainerGroupToContainer(t *testing.T) {
MemoryReservation: gbToBytes(0.1),
RestartPolicy: "any",
},
Healthcheck: containers.Healthcheck{
Disable: false,
Test: []string{
"my",
"command",
"--option",
},
Interval: types.Duration(10 * time.Second),
Retries: 3,
StartPeriod: types.Duration(2 * time.Second),
Timeout: types.Duration(time.Second),
},
}
container := ContainerGroupToContainer("myContainerID", myContainerGroup, myContainer, "eastus")
assert.DeepEqual(t, container, expectedContainer)
}
func TestHealthcheckTranslation(t *testing.T) {
test := []string{
"my",
"command",
"--option",
}
interval := types.Duration(10 * time.Second)
retries := uint64(42)
startPeriod := types.Duration(2 * time.Second)
timeout := types.Duration(3 * time.Second)
project := types.Project{
Services: []types.ServiceConfig{
{
Name: "service1",
Image: "image1",
HealthCheck: &types.HealthCheckConfig{
Test: test,
Timeout: &timeout,
Interval: &interval,
Retries: &retries,
StartPeriod: &startPeriod,
Disable: false,
},
},
},
}
testHealthcheckTestPrefixRemoval := func(test []string, shellPreffix ...string) {
project.Services[0].HealthCheck.Test = append(shellPreffix, test...)
group, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
assert.NilError(t, err)
assert.DeepEqual(t, (*group.Containers)[0].LivenessProbe.Exec.Command, to.StringSlicePtr(test))
assert.Equal(t, *(*group.Containers)[0].LivenessProbe.PeriodSeconds, int32(10))
assert.Equal(t, *(*group.Containers)[0].LivenessProbe.SuccessThreshold, int32(42))
assert.Equal(t, *(*group.Containers)[0].LivenessProbe.FailureThreshold, int32(42))
assert.Equal(t, *(*group.Containers)[0].LivenessProbe.InitialDelaySeconds, int32(2))
assert.Equal(t, *(*group.Containers)[0].LivenessProbe.TimeoutSeconds, int32(3))
}
testHealthcheckTestPrefixRemoval(test)
testHealthcheckTestPrefixRemoval(test, "NONE")
testHealthcheckTestPrefixRemoval(test, "CMD")
testHealthcheckTestPrefixRemoval(test, "CMD-SHELL")
project.Services[0].HealthCheck.Disable = true
group, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
assert.NilError(t, err)
assert.Assert(t, (*group.Containers)[0].LivenessProbe == nil)
}
func TestHealthcheckTranslationZeroValues(t *testing.T) {
test := []string{
"my",
"command",
"--option",
}
interval := types.Duration(0)
retries := uint64(0)
startPeriod := types.Duration(0)
timeout := types.Duration(0)
project := types.Project{
Services: []types.ServiceConfig{
{
Name: "service1",
Image: "image1",
HealthCheck: &types.HealthCheckConfig{
Test: test,
Timeout: &timeout,
Interval: &interval,
Retries: &retries,
StartPeriod: &startPeriod,
Disable: false,
},
},
},
}
group, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
assert.NilError(t, err)
assert.DeepEqual(t, (*group.Containers)[0].LivenessProbe.Exec.Command, to.StringSlicePtr(test))
assert.Assert(t, (*group.Containers)[0].LivenessProbe.PeriodSeconds == nil)
assert.Assert(t, (*group.Containers)[0].LivenessProbe.SuccessThreshold == nil)
assert.Assert(t, (*group.Containers)[0].LivenessProbe.FailureThreshold == nil)
assert.Assert(t, (*group.Containers)[0].LivenessProbe.InitialDelaySeconds == nil)
assert.Assert(t, (*group.Containers)[0].LivenessProbe.TimeoutSeconds == nil)
}
func TestContainerGroupToServiceStatus(t *testing.T) {
myContainerGroup := containerinstance.ContainerGroup{
ContainerGroupProperties: &containerinstance.ContainerGroupProperties{

View File

@ -20,6 +20,8 @@ import (
"context"
"io"
"github.com/compose-spec/compose-go/types"
"github.com/docker/compose-cli/formatter"
)
@ -54,6 +56,7 @@ type Container struct {
HostConfig *HostConfig `json:",omitempty"`
Ports []Port `json:",omitempty"`
Platform string
Healthcheck Healthcheck
}
// RuntimeConfig config of a created container
@ -112,6 +115,24 @@ type ContainerConfig struct {
DomainName string
// AutoRemove sets the container to be removed automatically when stopped
AutoRemove bool
// Healthcheck contains the command and interval of the checks
Healthcheck Healthcheck
}
// Healthcheck defines the configuration of a healthcheck
type Healthcheck struct {
// Disable disables the check
Disable bool
// Test is the command to be run to check the health of the container
Test []string
// Interval is the period in between the checks
Interval types.Duration
// Retries is the number of attempts before declaring the container as healthy or unhealthy
Retries int
// StartPeriod is the start delay before starting the checks
StartPeriod types.Duration
// Timeout is the timeout in between checks
Timeout types.Duration
}
// ExecRequest contaiens configuration about an exec request

View File

@ -21,6 +21,7 @@ import (
"fmt"
"io"
"os"
"time"
"github.com/containerd/console"
"github.com/spf13/cobra"
@ -59,6 +60,12 @@ func Command(contextType string) *cobra.Command {
cmd.Flags().StringArrayVar(&opts.EnvironmentFiles, "env-file", []string{}, "Path to environment files to be translated as environment variables")
cmd.Flags().StringVarP(&opts.RestartPolicyCondition, "restart", "", containers.RestartPolicyRunNo, "Restart policy to apply when a container exits (no|always|on-failure)")
cmd.Flags().BoolVar(&opts.Rm, "rm", false, "Automatically remove the container when it exits")
cmd.Flags().StringVar(&opts.HealthCmd, "health-cmd", "", "Command to run to check health")
cmd.Flags().DurationVar(&opts.HealthInterval, "health-interval", time.Duration(0), "Time between running the check (ms|s|m|h) (default 0s)")
cmd.Flags().IntVar(&opts.HealthRetries, "health-retries", 10, "Consecutive failures needed to report unhealthy")
cmd.Flags().DurationVar(&opts.HealthStartPeriod, "health-start-period", time.Duration(0), "Start period for the container to initialize before starting "+
"health-retries countdown (ms|s|m|h) (default 0s)")
cmd.Flags().DurationVar(&opts.HealthTimeout, "health-timeout", time.Duration(0), "Maximum time to allow one check to run (ms|s|m|h) (default 0s)")
if contextType == store.AciContextType {
cmd.Flags().StringVar(&opts.DomainName, "domainname", "", "Container NIS domain name")

View File

@ -4,14 +4,19 @@ Usage:
run [flags]
Flags:
--cpus float Number of CPUs (default 1)
-d, --detach Run container in background and print container ID
--domainname string Container NIS domain name
-e, --env stringArray Set environment variables
--env-file stringArray Path to environment files to be translated as environment variables
-l, --label stringArray Set meta data on a container
-m, --memory bytes Memory limit
--name string Assign a name to the container
-p, --publish stringArray Publish a container's port(s). [HOST_PORT:]CONTAINER_PORT
--restart string Restart policy to apply when a container exits (no|always|on-failure) (default "no")
-v, --volume stringArray Volume. Ex: storageaccount/my_share[:/absolute/path/to/target][:ro]
--cpus float Number of CPUs (default 1)
-d, --detach Run container in background and print container ID
--domainname string Container NIS domain name
-e, --env stringArray Set environment variables
--env-file stringArray Path to environment files to be translated as environment variables
--health-cmd string Command to run to check health
--health-interval duration Time between running the check (ms|s|m|h) (default 0s)
--health-retries int Consecutive failures needed to report unhealthy (default 10)
--health-start-period duration Start period for the container to initialize before starting health-retries countdown (ms|s|m|h) (default 0s)
--health-timeout duration Maximum time to allow one check to run (ms|s|m|h) (default 0s)
-l, --label stringArray Set meta data on a container
-m, --memory bytes Memory limit
--name string Assign a name to the container
-p, --publish stringArray Publish a container's port(s). [HOST_PORT:]CONTAINER_PORT
--restart string Restart policy to apply when a container exits (no|always|on-failure) (default "no")
-v, --volume stringArray Volume. Ex: storageaccount/my_share[:/absolute/path/to/target][:ro]

View File

@ -15,5 +15,13 @@
"MemoryLimit": 0,
"AutoRemove": false
},
"Platform": "Linux"
"Platform": "Linux",
"Healthcheck": {
"Disable": false,
"Test": null,
"Interval": "0s",
"Retries": 0,
"StartPeriod": "0s",
"Timeout": "0s"
}
}

View File

@ -20,7 +20,9 @@ import (
"fmt"
"strconv"
"strings"
"time"
"github.com/compose-spec/compose-go/types"
"github.com/docker/cli/opts"
"github.com/docker/docker/pkg/namesgenerator"
"github.com/docker/go-connections/nat"
@ -44,6 +46,11 @@ type Opts struct {
RestartPolicyCondition string
DomainName string
Rm bool
HealthCmd string
HealthInterval time.Duration
HealthRetries int
HealthStartPeriod time.Duration
HealthTimeout time.Duration
}
// ToContainerConfig convert run options to a container configuration
@ -76,6 +83,13 @@ func (r *Opts) ToContainerConfig(image string) (containers.ContainerConfig, erro
envVars = append(envVars, vars...)
}
var healthCmd []string
var healthInterval types.Duration
if len(r.HealthCmd) > 0 {
healthCmd = strings.Split(r.HealthCmd, " ")
healthInterval = types.Duration(r.HealthInterval)
}
return containers.ContainerConfig{
ID: r.Name,
Image: image,
@ -89,6 +103,11 @@ func (r *Opts) ToContainerConfig(image string) (containers.ContainerConfig, erro
RestartPolicyCondition: restartPolicy,
DomainName: r.DomainName,
AutoRemove: r.Rm,
Healthcheck: containers.Healthcheck{
Disable: len(healthCmd) == 0,
Test: healthCmd,
Interval: healthInterval,
},
}, nil
}

View File

@ -47,7 +47,7 @@ __Legend:__
| service.external_links | x |
| service.extra_hosts | x |
| service.group_add | x |
| service.healthcheck | n |
| service.healthcheck | ✓ |
| service.hostname | x |
| service.image | ✓ | Private images will be accessible if the user is logged into the corresponding registry at deploy time. Users will be automatically logged in to Azure Container Registry using their Azure login if possible.
| service.isolation | x |
@ -209,3 +209,21 @@ services:
In this example, the db container will be allocated 2 CPUs and 2G of memory. It will be allowed to use up to 3 CPUs and 3G of memory, using some of the resources allocated to the web container.
The web container will have its limits set to the same values as reservations, by default.
## Healthchecks
Healthchecks can be described in the `healthcheck` section in the service. It translates to `LivenessProbe` in ACI. By that, the container is restarted if it becomes unhealthy.
```yaml
services:
web:
image: nginx
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
```
**Note:** that the `test` command can be a `string` or an array starting or not by `NONE`, `CMD`, `CMD-SHELL`. In the ACI implementation, these prefixes are ignored.

2
go.mod
View File

@ -22,7 +22,7 @@ require (
github.com/aws/aws-sdk-go v1.35.15
github.com/awslabs/goformation/v4 v4.15.3
github.com/buger/goterm v0.0.0-20200322175922-2f3e71b85129
github.com/compose-spec/compose-go v0.0.0-20201005072614-3b6106793209
github.com/compose-spec/compose-go v0.0.0-20201104130931-5afecaa4cb35
github.com/containerd/console v1.0.1
github.com/containerd/containerd v1.3.5 // indirect
github.com/docker/cli v0.0.0-20200528204125-dd360c7c0de8

5
go.sum
View File

@ -122,8 +122,8 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/compose-spec/compose-go v0.0.0-20201005072614-3b6106793209 h1:PLZiS7hjkiAqZYBRAEq3tbGlhCh6/R14dO1ahwbEIBg=
github.com/compose-spec/compose-go v0.0.0-20201005072614-3b6106793209/go.mod h1:rNXXqhdClEljsNb6QDIOqTQaRfigwTgGZZM6Zpr3LeY=
github.com/compose-spec/compose-go v0.0.0-20201104130931-5afecaa4cb35 h1:HLxSiPmzCkBi3mGgxHQGBi3vxUuzT72Q9xjG49hkvSA=
github.com/compose-spec/compose-go v0.0.0-20201104130931-5afecaa4cb35/go.mod h1:cBdHyUvAothdUpqXANCfTHU7cEqsXRvSiLxjhOTuwvc=
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s=
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
@ -516,6 +516,7 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMc
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v0.0.0-20181112162635-ac52e6811b56 h1:yhqBHs09SmmUoNOHc9jgK4a60T3XFRtPAkYxVnqgY50=
github.com/xeipuuv/gojsonschema v0.0.0-20181112162635-ac52e6811b56/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=

File diff suppressed because it is too large Load Diff

View File

@ -51,6 +51,7 @@ message Container {
repeated Port ports = 11;
string platform = 13;
HostConfig host_config = 15;
Healthcheck healthcheck = 16;
}
message HostConfig {
@ -62,6 +63,12 @@ message HostConfig {
bool auto_remove = 6;
}
message Healthcheck {
bool disable = 1;
repeated string test = 2;
int64 interval = 3;
}
message InspectRequest {
string id = 1;
}
@ -113,6 +120,7 @@ message RunRequest {
repeated string command = 9;
repeated string environment = 10;
bool auto_remove = 11;
Healthcheck healthcheck = 12;
}
message RunResponse {

View File

@ -20,6 +20,8 @@ import (
"context"
"errors"
"github.com/compose-spec/compose-go/types"
"github.com/docker/compose-cli/api/containers"
"github.com/docker/compose-cli/formatter"
containersv1 "github.com/docker/compose-cli/protos/containers/v1"
@ -141,6 +143,11 @@ func toGrpcContainer(c containers.Container) *containersv1.Container {
RestartPolicy: c.HostConfig.RestartPolicy,
AutoRemove: c.HostConfig.AutoRemove,
},
Healthcheck: &containersv1.Healthcheck{
Disable: c.Healthcheck.Disable,
Test: c.Healthcheck.Test,
Interval: int64(c.Healthcheck.Interval),
},
}
}
@ -167,5 +174,10 @@ func grpcContainerToContainerConfig(request *containersv1.RunRequest) containers
RestartPolicyCondition: request.RestartPolicyCondition,
Environment: request.Environment,
AutoRemove: request.AutoRemove,
Healthcheck: containers.Healthcheck{
Disable: request.GetHealthcheck().GetDisable(),
Test: request.GetHealthcheck().GetTest(),
Interval: types.Duration(request.GetHealthcheck().GetInterval()),
},
}
}

View File

@ -15,5 +15,13 @@
"MemoryLimit": 0,
"AutoRemove": false
},
"Platform": "Linux"
"Platform": "Linux",
"Healthcheck": {
"Disable": false,
"Test": null,
"Interval": "0s",
"Retries": 0,
"StartPeriod": "0s",
"Timeout": "0s"
}
}