mirror of
https://github.com/containers/podman.git
synced 2025-10-24 15:03:45 +08:00
Merge pull request #13909 from mheon/startup_probe
Add support for startup healthchecks
This commit is contained in:
@ -12,7 +12,7 @@ import (
|
||||
func RunHealthCheck(w http.ResponseWriter, r *http.Request) {
|
||||
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
|
||||
name := utils.GetName(r)
|
||||
status, err := runtime.HealthCheck(name)
|
||||
status, err := runtime.HealthCheck(r.Context(), name)
|
||||
if err != nil {
|
||||
if status == define.HealthCheckContainerNotFound {
|
||||
utils.ContainerNotFound(w, name, err)
|
||||
@ -32,6 +32,8 @@ func RunHealthCheck(w http.ResponseWriter, r *http.Request) {
|
||||
hcStatus := define.HealthCheckUnhealthy
|
||||
if status == define.HealthCheckSuccess {
|
||||
hcStatus = define.HealthCheckHealthy
|
||||
} else if status == define.HealthCheckStartup {
|
||||
hcStatus = define.HealthCheckStarting
|
||||
}
|
||||
report := define.HealthCheckResults{
|
||||
Status: hcStatus,
|
||||
|
||||
@ -174,125 +174,129 @@ const (
|
||||
)
|
||||
|
||||
type ContainerCreateOptions struct {
|
||||
Annotation []string
|
||||
Attach []string
|
||||
Authfile string
|
||||
BlkIOWeight string
|
||||
BlkIOWeightDevice []string
|
||||
CapAdd []string
|
||||
CapDrop []string
|
||||
CgroupNS string
|
||||
CgroupsMode string
|
||||
CgroupParent string `json:"cgroup_parent,omitempty"`
|
||||
CIDFile string
|
||||
ConmonPIDFile string `json:"container_conmon_pidfile,omitempty"`
|
||||
CPUPeriod uint64
|
||||
CPUQuota int64
|
||||
CPURTPeriod uint64
|
||||
CPURTRuntime int64
|
||||
CPUShares uint64
|
||||
CPUS float64 `json:"cpus,omitempty"`
|
||||
CPUSetCPUs string `json:"cpuset_cpus,omitempty"`
|
||||
CPUSetMems string
|
||||
Devices []string `json:"devices,omitempty"`
|
||||
DeviceCgroupRule []string
|
||||
DeviceReadBPs []string `json:"device_read_bps,omitempty"`
|
||||
DeviceReadIOPs []string
|
||||
DeviceWriteBPs []string
|
||||
DeviceWriteIOPs []string
|
||||
Entrypoint *string `json:"container_command,omitempty"`
|
||||
Env []string
|
||||
EnvHost bool
|
||||
EnvFile []string
|
||||
Expose []string
|
||||
GIDMap []string
|
||||
GroupAdd []string
|
||||
HealthCmd string
|
||||
HealthInterval string
|
||||
HealthRetries uint
|
||||
HealthStartPeriod string
|
||||
HealthTimeout string
|
||||
HealthOnFailure string
|
||||
Hostname string `json:"hostname,omitempty"`
|
||||
HTTPProxy bool
|
||||
HostUsers []string
|
||||
ImageVolume string
|
||||
Init bool
|
||||
InitContainerType string
|
||||
InitPath string
|
||||
Interactive bool
|
||||
IPC string
|
||||
Label []string
|
||||
LabelFile []string
|
||||
LogDriver string
|
||||
LogOptions []string
|
||||
Memory string
|
||||
MemoryReservation string
|
||||
MemorySwap string
|
||||
MemorySwappiness int64
|
||||
Name string `json:"container_name"`
|
||||
NoHealthCheck bool
|
||||
OOMKillDisable bool
|
||||
OOMScoreAdj *int
|
||||
Arch string
|
||||
OS string
|
||||
Variant string
|
||||
PID string `json:"pid,omitempty"`
|
||||
PIDsLimit *int64
|
||||
Platform string
|
||||
Pod string
|
||||
PodIDFile string
|
||||
Personality string
|
||||
PreserveFDs uint
|
||||
Privileged bool
|
||||
PublishAll bool
|
||||
Pull string
|
||||
Quiet bool
|
||||
ReadOnly bool
|
||||
ReadOnlyTmpFS bool
|
||||
Restart string
|
||||
Replace bool
|
||||
Requires []string
|
||||
Rm bool
|
||||
RootFS bool
|
||||
Secrets []string
|
||||
SecurityOpt []string `json:"security_opt,omitempty"`
|
||||
SdNotifyMode string
|
||||
ShmSize string
|
||||
SignaturePolicy string
|
||||
StopSignal string
|
||||
StopTimeout uint
|
||||
StorageOpts []string
|
||||
SubUIDName string
|
||||
SubGIDName string
|
||||
Sysctl []string `json:"sysctl,omitempty"`
|
||||
Systemd string
|
||||
Timeout uint
|
||||
TLSVerify commonFlag.OptionalBool
|
||||
TmpFS []string
|
||||
TTY bool
|
||||
Timezone string
|
||||
Umask string
|
||||
EnvMerge []string
|
||||
UnsetEnv []string
|
||||
UnsetEnvAll bool
|
||||
UIDMap []string
|
||||
Ulimit []string
|
||||
User string
|
||||
UserNS string `json:"-"`
|
||||
UTS string
|
||||
Mount []string
|
||||
Volume []string `json:"volume,omitempty"`
|
||||
VolumesFrom []string `json:"volumes_from,omitempty"`
|
||||
Workdir string
|
||||
SeccompPolicy string
|
||||
PidFile string
|
||||
ChrootDirs []string
|
||||
IsInfra bool
|
||||
IsClone bool
|
||||
DecryptionKeys []string
|
||||
|
||||
Net *NetOptions `json:"net,omitempty"`
|
||||
Annotation []string
|
||||
Attach []string
|
||||
Authfile string
|
||||
BlkIOWeight string
|
||||
BlkIOWeightDevice []string
|
||||
CapAdd []string
|
||||
CapDrop []string
|
||||
CgroupNS string
|
||||
CgroupsMode string
|
||||
CgroupParent string `json:"cgroup_parent,omitempty"`
|
||||
CIDFile string
|
||||
ConmonPIDFile string `json:"container_conmon_pidfile,omitempty"`
|
||||
CPUPeriod uint64
|
||||
CPUQuota int64
|
||||
CPURTPeriod uint64
|
||||
CPURTRuntime int64
|
||||
CPUShares uint64
|
||||
CPUS float64 `json:"cpus,omitempty"`
|
||||
CPUSetCPUs string `json:"cpuset_cpus,omitempty"`
|
||||
CPUSetMems string
|
||||
Devices []string `json:"devices,omitempty"`
|
||||
DeviceCgroupRule []string
|
||||
DeviceReadBPs []string `json:"device_read_bps,omitempty"`
|
||||
DeviceReadIOPs []string
|
||||
DeviceWriteBPs []string
|
||||
DeviceWriteIOPs []string
|
||||
Entrypoint *string `json:"container_command,omitempty"`
|
||||
Env []string
|
||||
EnvHost bool
|
||||
EnvFile []string
|
||||
Expose []string
|
||||
GIDMap []string
|
||||
GroupAdd []string
|
||||
HealthCmd string
|
||||
HealthInterval string
|
||||
HealthRetries uint
|
||||
HealthStartPeriod string
|
||||
HealthTimeout string
|
||||
HealthOnFailure string
|
||||
Hostname string `json:"hostname,omitempty"`
|
||||
HTTPProxy bool
|
||||
HostUsers []string
|
||||
ImageVolume string
|
||||
Init bool
|
||||
InitContainerType string
|
||||
InitPath string
|
||||
Interactive bool
|
||||
IPC string
|
||||
Label []string
|
||||
LabelFile []string
|
||||
LogDriver string
|
||||
LogOptions []string
|
||||
Memory string
|
||||
MemoryReservation string
|
||||
MemorySwap string
|
||||
MemorySwappiness int64
|
||||
Name string `json:"container_name"`
|
||||
NoHealthCheck bool
|
||||
OOMKillDisable bool
|
||||
OOMScoreAdj *int
|
||||
Arch string
|
||||
OS string
|
||||
Variant string
|
||||
PID string `json:"pid,omitempty"`
|
||||
PIDsLimit *int64
|
||||
Platform string
|
||||
Pod string
|
||||
PodIDFile string
|
||||
Personality string
|
||||
PreserveFDs uint
|
||||
Privileged bool
|
||||
PublishAll bool
|
||||
Pull string
|
||||
Quiet bool
|
||||
ReadOnly bool
|
||||
ReadOnlyTmpFS bool
|
||||
Restart string
|
||||
Replace bool
|
||||
Requires []string
|
||||
Rm bool
|
||||
RootFS bool
|
||||
Secrets []string
|
||||
SecurityOpt []string `json:"security_opt,omitempty"`
|
||||
SdNotifyMode string
|
||||
ShmSize string
|
||||
SignaturePolicy string
|
||||
StartupHCCmd string
|
||||
StartupHCInterval string
|
||||
StartupHCRetries uint
|
||||
StartupHCSuccesses uint
|
||||
StartupHCTimeout string
|
||||
StopSignal string
|
||||
StopTimeout uint
|
||||
StorageOpts []string
|
||||
SubUIDName string
|
||||
SubGIDName string
|
||||
Sysctl []string `json:"sysctl,omitempty"`
|
||||
Systemd string
|
||||
Timeout uint
|
||||
TLSVerify commonFlag.OptionalBool
|
||||
TmpFS []string
|
||||
TTY bool
|
||||
Timezone string
|
||||
Umask string
|
||||
EnvMerge []string
|
||||
UnsetEnv []string
|
||||
UnsetEnvAll bool
|
||||
UIDMap []string
|
||||
Ulimit []string
|
||||
User string
|
||||
UserNS string `json:"-"`
|
||||
UTS string
|
||||
Mount []string
|
||||
Volume []string `json:"volume,omitempty"`
|
||||
VolumesFrom []string `json:"volumes_from,omitempty"`
|
||||
Workdir string
|
||||
SeccompPolicy string
|
||||
PidFile string
|
||||
ChrootDirs []string
|
||||
IsInfra bool
|
||||
IsClone bool
|
||||
DecryptionKeys []string
|
||||
Net *NetOptions `json:"net,omitempty"`
|
||||
|
||||
CgroupConf []string
|
||||
|
||||
|
||||
@ -8,13 +8,15 @@ import (
|
||||
)
|
||||
|
||||
func (ic *ContainerEngine) HealthCheckRun(ctx context.Context, nameOrID string, options entities.HealthCheckOptions) (*define.HealthCheckResults, error) {
|
||||
status, err := ic.Libpod.HealthCheck(nameOrID)
|
||||
status, err := ic.Libpod.HealthCheck(ctx, nameOrID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hcStatus := define.HealthCheckUnhealthy
|
||||
if status == define.HealthCheckSuccess {
|
||||
hcStatus = define.HealthCheckHealthy
|
||||
} else if status == define.HealthCheckStartup {
|
||||
hcStatus = define.HealthCheckStarting
|
||||
}
|
||||
report := define.HealthCheckResults{
|
||||
Status: hcStatus,
|
||||
|
||||
@ -527,6 +527,9 @@ func createContainerOptions(rt *libpod.Runtime, s *specgen.SpecGenerator, pod *l
|
||||
options = append(options, libpod.WithHealthCheck(s.ContainerHealthCheckConfig.HealthConfig))
|
||||
logrus.Debugf("New container has a health check")
|
||||
}
|
||||
if s.ContainerHealthCheckConfig.StartupHealthConfig != nil {
|
||||
options = append(options, libpod.WithStartupHealthcheck(s.ContainerHealthCheckConfig.StartupHealthConfig))
|
||||
}
|
||||
|
||||
if s.ContainerHealthCheckConfig.HealthCheckOnFailureAction != define.HealthCheckOnFailureActionNone {
|
||||
options = append(options, libpod.WithHealthCheckOnFailureAction(s.ContainerHealthCheckConfig.HealthCheckOnFailureAction))
|
||||
|
||||
@ -536,6 +536,10 @@ type ContainerResourceConfig struct {
|
||||
type ContainerHealthCheckConfig struct {
|
||||
HealthConfig *manifest.Schema2HealthConfig `json:"healthconfig,omitempty"`
|
||||
HealthCheckOnFailureAction define.HealthCheckOnFailureAction `json:"health_check_on_failure_action,omitempty"`
|
||||
// Startup healthcheck for a container.
|
||||
// Requires that HealthConfig be set.
|
||||
// Optional.
|
||||
StartupHealthConfig *define.StartupHealthCheck `json:"startupHealthConfig,omitempty"`
|
||||
}
|
||||
|
||||
// SpecGenerator creates an OCI spec and Libpod configuration options to create
|
||||
|
||||
@ -256,7 +256,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
|
||||
if c.NoHealthCheck {
|
||||
return errors.New("cannot specify both --no-healthcheck and --health-cmd")
|
||||
}
|
||||
s.HealthConfig, err = makeHealthCheckFromCli(c.HealthCmd, c.HealthInterval, c.HealthRetries, c.HealthTimeout, c.HealthStartPeriod)
|
||||
s.HealthConfig, err = makeHealthCheckFromCli(c.HealthCmd, c.HealthInterval, c.HealthRetries, c.HealthTimeout, c.HealthStartPeriod, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -272,6 +272,25 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
|
||||
}
|
||||
s.HealthCheckOnFailureAction = onFailureAction
|
||||
|
||||
if c.StartupHCCmd != "" {
|
||||
if c.NoHealthCheck {
|
||||
return errors.New("cannot specify both --no-healthcheck and --health-startup-cmd")
|
||||
}
|
||||
// The hardcoded "1s" will be discarded, as the startup
|
||||
// healthcheck does not have a period. So just hardcode
|
||||
// something that parses correctly.
|
||||
tmpHcConfig, err := makeHealthCheckFromCli(c.StartupHCCmd, c.StartupHCInterval, c.StartupHCRetries, c.StartupHCTimeout, "1s", true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.StartupHealthConfig = new(define.StartupHealthCheck)
|
||||
s.StartupHealthConfig.Test = tmpHcConfig.Test
|
||||
s.StartupHealthConfig.Interval = tmpHcConfig.Interval
|
||||
s.StartupHealthConfig.Timeout = tmpHcConfig.Timeout
|
||||
s.StartupHealthConfig.Retries = tmpHcConfig.Retries
|
||||
s.StartupHealthConfig.Successes = int(c.StartupHCSuccesses)
|
||||
}
|
||||
|
||||
if err := setNamespaces(s, c); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -838,7 +857,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeHealthCheckFromCli(inCmd, interval string, retries uint, timeout, startPeriod string) (*manifest.Schema2HealthConfig, error) {
|
||||
func makeHealthCheckFromCli(inCmd, interval string, retries uint, timeout, startPeriod string, isStartup bool) (*manifest.Schema2HealthConfig, error) {
|
||||
cmdArr := []string{}
|
||||
isArr := true
|
||||
err := json.Unmarshal([]byte(inCmd), &cmdArr) // array unmarshalling
|
||||
@ -886,7 +905,7 @@ func makeHealthCheckFromCli(inCmd, interval string, retries uint, timeout, start
|
||||
|
||||
hc.Interval = intervalDuration
|
||||
|
||||
if retries < 1 {
|
||||
if retries < 1 && !isStartup {
|
||||
return nil, errors.New("healthcheck-retries must be greater than 0")
|
||||
}
|
||||
hc.Retries = int(retries)
|
||||
|
||||
Reference in New Issue
Block a user