Merge pull request #12614 from baude/bz2028408

fix healthcheck timeouts and ut8 coercion
This commit is contained in:
OpenShift Merge Robot
2022-01-06 23:36:09 +01:00
committed by GitHub
7 changed files with 75 additions and 22 deletions

View File

@ -257,7 +257,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
healthIntervalFlagName := "health-interval" healthIntervalFlagName := "health-interval"
createFlags.StringVar( createFlags.StringVar(
&cf.HealthInterval, &cf.HealthInterval,
healthIntervalFlagName, DefaultHealthCheckInterval, healthIntervalFlagName, define.DefaultHealthCheckInterval,
"set an interval for the healthchecks (a value of disable results in no automatic timer setup)", "set an interval for the healthchecks (a value of disable results in no automatic timer setup)",
) )
_ = cmd.RegisterFlagCompletionFunc(healthIntervalFlagName, completion.AutocompleteNone) _ = cmd.RegisterFlagCompletionFunc(healthIntervalFlagName, completion.AutocompleteNone)
@ -265,7 +265,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
healthRetriesFlagName := "health-retries" healthRetriesFlagName := "health-retries"
createFlags.UintVar( createFlags.UintVar(
&cf.HealthRetries, &cf.HealthRetries,
healthRetriesFlagName, DefaultHealthCheckRetries, healthRetriesFlagName, define.DefaultHealthCheckRetries,
"the number of retries allowed before a healthcheck is considered to be unhealthy", "the number of retries allowed before a healthcheck is considered to be unhealthy",
) )
_ = cmd.RegisterFlagCompletionFunc(healthRetriesFlagName, completion.AutocompleteNone) _ = cmd.RegisterFlagCompletionFunc(healthRetriesFlagName, completion.AutocompleteNone)
@ -273,7 +273,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
healthStartPeriodFlagName := "health-start-period" healthStartPeriodFlagName := "health-start-period"
createFlags.StringVar( createFlags.StringVar(
&cf.HealthStartPeriod, &cf.HealthStartPeriod,
healthStartPeriodFlagName, DefaultHealthCheckStartPeriod, healthStartPeriodFlagName, define.DefaultHealthCheckStartPeriod,
"the initialization time needed for a container to bootstrap", "the initialization time needed for a container to bootstrap",
) )
_ = cmd.RegisterFlagCompletionFunc(healthStartPeriodFlagName, completion.AutocompleteNone) _ = cmd.RegisterFlagCompletionFunc(healthStartPeriodFlagName, completion.AutocompleteNone)
@ -281,7 +281,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
healthTimeoutFlagName := "health-timeout" healthTimeoutFlagName := "health-timeout"
createFlags.StringVar( createFlags.StringVar(
&cf.HealthTimeout, &cf.HealthTimeout,
healthTimeoutFlagName, DefaultHealthCheckTimeout, healthTimeoutFlagName, define.DefaultHealthCheckTimeout,
"the maximum time allowed to complete the healthcheck before an interval is considered failed", "the maximum time allowed to complete the healthcheck before an interval is considered failed",
) )
_ = cmd.RegisterFlagCompletionFunc(healthTimeoutFlagName, completion.AutocompleteNone) _ = cmd.RegisterFlagCompletionFunc(healthTimeoutFlagName, completion.AutocompleteNone)

View File

@ -11,6 +11,7 @@ import (
"github.com/containers/common/pkg/cgroups" "github.com/containers/common/pkg/cgroups"
"github.com/containers/common/pkg/config" "github.com/containers/common/pkg/config"
"github.com/containers/podman/v3/cmd/podman/registry" "github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/podman/v3/pkg/api/handlers" "github.com/containers/podman/v3/pkg/api/handlers"
"github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/domain/entities"
@ -304,10 +305,10 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *c
VolumesFrom: cc.HostConfig.VolumesFrom, VolumesFrom: cc.HostConfig.VolumesFrom,
Workdir: cc.Config.WorkingDir, Workdir: cc.Config.WorkingDir,
Net: &netInfo, Net: &netInfo,
HealthInterval: DefaultHealthCheckInterval, HealthInterval: define.DefaultHealthCheckInterval,
HealthRetries: DefaultHealthCheckRetries, HealthRetries: define.DefaultHealthCheckRetries,
HealthTimeout: DefaultHealthCheckTimeout, HealthTimeout: define.DefaultHealthCheckTimeout,
HealthStartPeriod: DefaultHealthCheckStartPeriod, HealthStartPeriod: define.DefaultHealthCheckStartPeriod,
} }
if !rootless.IsRootless() { if !rootless.IsRootless() {
var ulimits []string var ulimits []string

View File

@ -5,14 +5,7 @@ import (
) )
var ( var (
// DefaultHealthCheckInterval default value
DefaultHealthCheckInterval = "30s"
// DefaultHealthCheckRetries default value
DefaultHealthCheckRetries uint = 3
// DefaultHealthCheckStartPeriod default value
DefaultHealthCheckStartPeriod = "0s"
// DefaultHealthCheckTimeout default value
DefaultHealthCheckTimeout = "30s"
// DefaultImageVolume default value // DefaultImageVolume default value
DefaultImageVolume = "bind" DefaultImageVolume = "bind"
// Pull in configured json library // Pull in configured json library

View File

@ -237,12 +237,12 @@ func (i *inspector) inspect(namesOrIDs []string) error {
} }
func printJSON(data []interface{}) error { func printJSON(data []interface{}) error {
buf, err := json.MarshalIndent(data, "", " ") enc := json.NewEncoder(os.Stdout)
if err != nil { // by default, json marshallers will force utf=8 from
return err // a string. this breaks healthchecks that use <,>, &&.
} enc.SetEscapeHTML(false)
_, err = fmt.Println(string(buf)) enc.SetIndent("", " ")
return err return enc.Encode(data)
} }
func printTmpl(typ, row string, data []interface{}) error { func printTmpl(typ, row string, data []interface{}) error {

View File

@ -34,3 +34,16 @@ const (
// HealthCheckDefined means the healthcheck was found on the container // HealthCheckDefined means the healthcheck was found on the container
HealthCheckDefined HealthCheckStatus = iota HealthCheckDefined HealthCheckStatus = iota
) )
// Healthcheck defaults. These are used both in the cli as well in
// libpod and were moved from cmd/podman/common
const (
// DefaultHealthCheckInterval default value
DefaultHealthCheckInterval = "30s"
// DefaultHealthCheckRetries default value
DefaultHealthCheckRetries uint = 3
// DefaultHealthCheckStartPeriod default value
DefaultHealthCheckStartPeriod = "0s"
// DefaultHealthCheckTimeout default value
DefaultHealthCheckTimeout = "30s"
)

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"os" "os"
"strings" "strings"
"time"
"github.com/containers/common/libimage" "github.com/containers/common/libimage"
"github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/libpod"
@ -64,6 +65,13 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
// NOTE: the health check is only set for Docker images // NOTE: the health check is only set for Docker images
// but inspect will take care of it. // but inspect will take care of it.
s.HealthConfig = inspectData.HealthCheck s.HealthConfig = inspectData.HealthCheck
if s.HealthConfig != nil && s.HealthConfig.Timeout == 0 {
hct, err := time.ParseDuration(define.DefaultHealthCheckTimeout)
if err != nil {
return nil, err
}
s.HealthConfig.Timeout = hct
}
} }
// Image stop signal // Image stop signal

View File

@ -2,7 +2,9 @@ package integration
import ( import (
"fmt" "fmt"
"io/ioutil"
"os" "os"
"path/filepath"
"time" "time"
define "github.com/containers/podman/v3/libpod/define" define "github.com/containers/podman/v3/libpod/define"
@ -258,4 +260,40 @@ var _ = Describe("Podman healthcheck run", func() {
Expect(startAgain.OutputToString()).To(Equal("hc")) Expect(startAgain.OutputToString()).To(Equal("hc"))
Expect(startAgain.ErrorToString()).To(Equal("")) Expect(startAgain.ErrorToString()).To(Equal(""))
}) })
It("Verify default time is used and no utf-8 escapes", func() {
cwd, err := os.Getwd()
Expect(err).To(BeNil())
podmanTest.AddImageToRWStore(ALPINE)
// Write target and fake files
targetPath, err := CreateTempDirInTempDir()
Expect(err).To(BeNil())
containerfile := fmt.Sprintf(`FROM %s
HEALTHCHECK CMD ls -l / 2>&1`, ALPINE)
containerfilePath := filepath.Join(targetPath, "Containerfile")
err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644)
Expect(err).To(BeNil())
defer func() {
Expect(os.Chdir(cwd)).To(BeNil())
Expect(os.RemoveAll(targetPath)).To(BeNil())
}()
// make cwd as context root path
Expect(os.Chdir(targetPath)).To(BeNil())
session := podmanTest.Podman([]string{"build", "--format", "docker", "-t", "test", "."})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
run := podmanTest.Podman([]string{"run", "-dt", "--name", "hctest", "test", "ls"})
run.WaitWithDefaultTimeout()
Expect(run).Should(Exit(0))
inspect := podmanTest.InspectContainer("hctest")
// Check to make sure a default time value was added
Expect(inspect[0].Config.Healthcheck.Timeout).To(BeNumerically("==", 30000000000))
// Check to make sure characters were not coerced to utf8
Expect(inspect[0].Config.Healthcheck.Test).To(Equal([]string{"CMD-SHELL", "ls -l / 2>&1"}))
})
}) })