aboutsummaryrefslogtreecommitdiff
path: root/cmd/podman
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2019-02-26 20:54:57 -0600
committerbaude <bbaude@redhat.com>2019-03-05 14:03:55 -0600
commit598bde52d02eb82634c6b1fa357253f03120a4a0 (patch)
tree08c935792c9e1d57ee00f8db98b3f1a74987f4b6 /cmd/podman
parent645426fe797f90fc75712388e0373158f13bab0a (diff)
downloadpodman-598bde52d02eb82634c6b1fa357253f03120a4a0.tar.gz
podman-598bde52d02eb82634c6b1fa357253f03120a4a0.tar.bz2
podman-598bde52d02eb82634c6b1fa357253f03120a4a0.zip
podman healthcheck run (phase 1)
Add the ability to manually run a container's healthcheck command. This is only the first phase of implementing the healthcheck. Subsequent pull requests will deal with the exposing the results and history of healthchecks as well as the scheduling. Signed-off-by: baude <bbaude@redhat.com>
Diffstat (limited to 'cmd/podman')
-rw-r--r--cmd/podman/cliconfig/config.go4
-rw-r--r--cmd/podman/commands.go7
-rw-r--r--cmd/podman/commands_remoteclient.go5
-rw-r--r--cmd/podman/create.go25
-rw-r--r--cmd/podman/healthcheck.go25
-rw-r--r--cmd/podman/healthcheck_run.go53
6 files changed, 119 insertions, 0 deletions
diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go
index ea99aafc2..7945cb6cb 100644
--- a/cmd/podman/cliconfig/config.go
+++ b/cmd/podman/cliconfig/config.go
@@ -217,6 +217,10 @@ type PauseValues struct {
All bool
}
+type HealthCheckValues struct {
+ PodmanCommand
+}
+
type KubePlayValues struct {
PodmanCommand
Authfile string
diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go
index c261e54e2..150413970 100644
--- a/cmd/podman/commands.go
+++ b/cmd/podman/commands.go
@@ -121,3 +121,10 @@ func getSystemSubCommands() []*cobra.Command {
_renumberCommand,
}
}
+
+// Commands that the local client implements
+func getHealtcheckSubCommands() []*cobra.Command {
+ return []*cobra.Command{
+ _healthcheckrunCommand,
+ }
+}
diff --git a/cmd/podman/commands_remoteclient.go b/cmd/podman/commands_remoteclient.go
index 081043b25..f0f815d78 100644
--- a/cmd/podman/commands_remoteclient.go
+++ b/cmd/podman/commands_remoteclient.go
@@ -52,3 +52,8 @@ func getTrustSubCommands() []*cobra.Command {
func getSystemSubCommands() []*cobra.Command {
return []*cobra.Command{}
}
+
+// Commands that the remoteclient implements
+func getHealtcheckSubCommands() []*cobra.Command {
+ return []*cobra.Command{}
+}
diff --git a/cmd/podman/create.go b/cmd/podman/create.go
index 129c886b2..a7b9bbf31 100644
--- a/cmd/podman/create.go
+++ b/cmd/podman/create.go
@@ -12,6 +12,7 @@ import (
"strings"
"syscall"
+ "github.com/containers/image/manifest"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/cmd/podman/shared"
@@ -117,6 +118,10 @@ func createInit(c *cliconfig.PodmanCommand) error {
}
func createContainer(c *cliconfig.PodmanCommand, runtime *libpod.Runtime) (*libpod.Container, *cc.CreateConfig, error) {
+ var (
+ hasHealthCheck bool
+ healthCheck *manifest.Schema2HealthConfig
+ )
if c.Bool("trace") {
span, _ := opentracing.StartSpanFromContext(Ctx, "createContainer")
defer span.Finish()
@@ -163,12 +168,32 @@ func createContainer(c *cliconfig.PodmanCommand, runtime *libpod.Runtime) (*libp
} else {
imageName = newImage.ID()
}
+
+ // add healthcheck if it exists AND is correct mediatype
+ _, mediaType, err := newImage.Manifest(ctx)
+ if err != nil {
+ return nil, nil, errors.Wrapf(err, "unable to determine mediatype of image %s", newImage.ID())
+ }
+ if mediaType == manifest.DockerV2Schema2MediaType {
+ healthCheck, err = newImage.GetHealthCheck(ctx)
+ if err != nil {
+ return nil, nil, errors.Wrapf(err, "unable to get healthcheck for %s", c.InputArgs[0])
+ }
+ if healthCheck != nil {
+ hasHealthCheck = true
+ }
+ }
}
createConfig, err := parseCreateOpts(ctx, c, runtime, imageName, data)
if err != nil {
return nil, nil, err
}
+ // Because parseCreateOpts does derive anything from the image, we add health check
+ // at this point. The rest is done by WithOptions.
+ createConfig.HasHealthCheck = hasHealthCheck
+ createConfig.HealthCheck = healthCheck
+
ctr, err := createContainerFromCreateConfig(runtime, createConfig, ctx, nil)
if err != nil {
return nil, nil, err
diff --git a/cmd/podman/healthcheck.go b/cmd/podman/healthcheck.go
new file mode 100644
index 000000000..e7cc125cc
--- /dev/null
+++ b/cmd/podman/healthcheck.go
@@ -0,0 +1,25 @@
+package main
+
+import (
+ "github.com/containers/libpod/cmd/podman/cliconfig"
+ "github.com/spf13/cobra"
+)
+
+var healthcheckDescription = "Manage health checks on containers"
+var healthcheckCommand = cliconfig.PodmanCommand{
+ Command: &cobra.Command{
+ Use: "healthcheck",
+ Short: "Manage Healthcheck",
+ Long: healthcheckDescription,
+ },
+}
+
+// Commands that are universally implemented
+var healthcheckCommands []*cobra.Command
+
+func init() {
+ healthcheckCommand.AddCommand(healthcheckCommands...)
+ healthcheckCommand.AddCommand(getHealtcheckSubCommands()...)
+ healthcheckCommand.SetUsageTemplate(UsageTemplate())
+ rootCmd.AddCommand(healthcheckCommand.Command)
+}
diff --git a/cmd/podman/healthcheck_run.go b/cmd/podman/healthcheck_run.go
new file mode 100644
index 000000000..a91f87146
--- /dev/null
+++ b/cmd/podman/healthcheck_run.go
@@ -0,0 +1,53 @@
+package main
+
+import (
+ "fmt"
+ "github.com/containers/libpod/cmd/podman/cliconfig"
+ "github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/pkg/adapter"
+ "github.com/pkg/errors"
+ "github.com/spf13/cobra"
+)
+
+var (
+ healthcheckRunCommand cliconfig.HealthCheckValues
+ healthcheckRunDescription = "run the health check of a container"
+ _healthcheckrunCommand = &cobra.Command{
+ Use: "run CONTAINER",
+ Short: "run the health check of a container",
+ Long: healthcheckRunDescription,
+ Example: `podman healthcheck run mywebapp`,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ healthcheckRunCommand.InputArgs = args
+ healthcheckRunCommand.GlobalFlags = MainGlobalOpts
+ return healthCheckCmd(&healthcheckRunCommand)
+ },
+ Args: func(cmd *cobra.Command, args []string) error {
+ if len(args) < 1 || len(args) > 1 {
+ return errors.New("must provide the name or ID of one container")
+ }
+ return nil
+ },
+ }
+)
+
+func init() {
+ healthcheckRunCommand.Command = _healthcheckrunCommand
+ healthcheckRunCommand.SetUsageTemplate(UsageTemplate())
+}
+
+func healthCheckCmd(c *cliconfig.HealthCheckValues) error {
+ runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ if err != nil {
+ return errors.Wrap(err, "could not get runtime")
+ }
+ status, err := runtime.HealthCheck(c)
+ if err != nil {
+ if status == libpod.HealthCheckFailure {
+ fmt.Println("\nunhealthy")
+ }
+ return err
+ }
+ fmt.Println("\nhealthy")
+ return nil
+}