From 61f2486ffeb98801efcd2b4fe9b6c091586dcf66 Mon Sep 17 00:00:00 2001 From: Allen Sun Date: Wed, 19 Sep 2018 18:16:48 +0800 Subject: [PATCH] fix: make container state in inpsect API correct Signed-off-by: Allen Sun --- apis/swagger.yml | 10 ++- apis/types/container_state.go | 143 ++++++++++++++++++++++++++++--- apis/types/exec_create_config.go | 2 +- test/cli_inspect_test.go | 39 ++++++++- 4 files changed, 175 insertions(+), 19 deletions(-) diff --git a/apis/swagger.yml b/apis/swagger.yml index e286bbb7c..63acebd6d 100644 --- a/apis/swagger.yml +++ b/apis/swagger.yml @@ -3379,7 +3379,7 @@ definitions: ContainerState: type: "object" - required: [StartedAt, FinishedAt] + required: [StartedAt, FinishedAt, Pid, ExitCode, Error, OOMKilled, Dead, Paused, Restarting, Running, Status] properties: Status: $ref: "#/definitions/Status" @@ -3396,27 +3396,35 @@ definitions: Use the `Status` field instead to determine if a container's state is "running". type: "boolean" + x-nullable: false Paused: description: "Whether this container is paused." type: "boolean" + x-nullable: false Restarting: description: "Whether this container is restarting." type: "boolean" + x-nullable: false OOMKilled: description: "Whether this container has been killed because it ran out of memory." type: "boolean" + x-nullable: false Dead: description: "Whether this container is dead." type: "boolean" + x-nullable: false Pid: + x-nullable: false description: "The process ID of this container" type: "integer" ExitCode: + x-nullable: false description: "The last exit code of this container" type: "integer" Error: description: "The error message of this container" type: "string" + x-nullable: false StartedAt: description: "The time when this container was last started." type: "string" diff --git a/apis/types/container_state.go b/apis/types/container_state.go index f33579d8b..fc54f22ca 100644 --- a/apis/types/container_state.go +++ b/apis/types/container_state.go @@ -19,29 +19,36 @@ import ( type ContainerState struct { // Whether this container is dead. - Dead bool `json:"Dead,omitempty"` + // Required: true + Dead bool `json:"Dead"` // The error message of this container - Error string `json:"Error,omitempty"` + // Required: true + Error string `json:"Error"` // The last exit code of this container - ExitCode int64 `json:"ExitCode,omitempty"` + // Required: true + ExitCode int64 `json:"ExitCode"` // The time when this container last exited. // Required: true FinishedAt string `json:"FinishedAt"` // Whether this container has been killed because it ran out of memory. - OOMKilled bool `json:"OOMKilled,omitempty"` + // Required: true + OOMKilled bool `json:"OOMKilled"` // Whether this container is paused. - Paused bool `json:"Paused,omitempty"` + // Required: true + Paused bool `json:"Paused"` // The process ID of this container - Pid int64 `json:"Pid,omitempty"` + // Required: true + Pid int64 `json:"Pid"` // Whether this container is restarting. - Restarting bool `json:"Restarting,omitempty"` + // Required: true + Restarting bool `json:"Restarting"` // Whether this container is running. // @@ -54,14 +61,16 @@ type ContainerState struct { // // Use the `Status` field instead to determine if a container's state is "running". // - Running bool `json:"Running,omitempty"` + // Required: true + Running bool `json:"Running"` // The time when this container was last started. // Required: true StartedAt string `json:"StartedAt"` // status - Status Status `json:"Status,omitempty"` + // Required: true + Status Status `json:"Status"` } /* polymorph ContainerState Dead false */ @@ -90,11 +99,51 @@ type ContainerState struct { func (m *ContainerState) Validate(formats strfmt.Registry) error { var res []error + if err := m.validateDead(formats); err != nil { + // prop + res = append(res, err) + } + + if err := m.validateError(formats); err != nil { + // prop + res = append(res, err) + } + + if err := m.validateExitCode(formats); err != nil { + // prop + res = append(res, err) + } + if err := m.validateFinishedAt(formats); err != nil { // prop res = append(res, err) } + if err := m.validateOOMKilled(formats); err != nil { + // prop + res = append(res, err) + } + + if err := m.validatePaused(formats); err != nil { + // prop + res = append(res, err) + } + + if err := m.validatePid(formats); err != nil { + // prop + res = append(res, err) + } + + if err := m.validateRestarting(formats); err != nil { + // prop + res = append(res, err) + } + + if err := m.validateRunning(formats); err != nil { + // prop + res = append(res, err) + } + if err := m.validateStartedAt(formats); err != nil { // prop res = append(res, err) @@ -111,6 +160,33 @@ func (m *ContainerState) Validate(formats strfmt.Registry) error { return nil } +func (m *ContainerState) validateDead(formats strfmt.Registry) error { + + if err := validate.Required("Dead", "body", bool(m.Dead)); err != nil { + return err + } + + return nil +} + +func (m *ContainerState) validateError(formats strfmt.Registry) error { + + if err := validate.RequiredString("Error", "body", string(m.Error)); err != nil { + return err + } + + return nil +} + +func (m *ContainerState) validateExitCode(formats strfmt.Registry) error { + + if err := validate.Required("ExitCode", "body", int64(m.ExitCode)); err != nil { + return err + } + + return nil +} + func (m *ContainerState) validateFinishedAt(formats strfmt.Registry) error { if err := validate.RequiredString("FinishedAt", "body", string(m.FinishedAt)); err != nil { @@ -120,6 +196,51 @@ func (m *ContainerState) validateFinishedAt(formats strfmt.Registry) error { return nil } +func (m *ContainerState) validateOOMKilled(formats strfmt.Registry) error { + + if err := validate.Required("OOMKilled", "body", bool(m.OOMKilled)); err != nil { + return err + } + + return nil +} + +func (m *ContainerState) validatePaused(formats strfmt.Registry) error { + + if err := validate.Required("Paused", "body", bool(m.Paused)); err != nil { + return err + } + + return nil +} + +func (m *ContainerState) validatePid(formats strfmt.Registry) error { + + if err := validate.Required("Pid", "body", int64(m.Pid)); err != nil { + return err + } + + return nil +} + +func (m *ContainerState) validateRestarting(formats strfmt.Registry) error { + + if err := validate.Required("Restarting", "body", bool(m.Restarting)); err != nil { + return err + } + + return nil +} + +func (m *ContainerState) validateRunning(formats strfmt.Registry) error { + + if err := validate.Required("Running", "body", bool(m.Running)); err != nil { + return err + } + + return nil +} + func (m *ContainerState) validateStartedAt(formats strfmt.Registry) error { if err := validate.RequiredString("StartedAt", "body", string(m.StartedAt)); err != nil { @@ -131,10 +252,6 @@ func (m *ContainerState) validateStartedAt(formats strfmt.Registry) error { func (m *ContainerState) validateStatus(formats strfmt.Registry) error { - if swag.IsZero(m.Status) { // not required - return nil - } - if err := m.Status.Validate(formats); err != nil { if ve, ok := err.(*errors.Validation); ok { return ve.ValidateName("Status") diff --git a/apis/types/exec_create_config.go b/apis/types/exec_create_config.go index 45b00292e..ce371c64d 100644 --- a/apis/types/exec_create_config.go +++ b/apis/types/exec_create_config.go @@ -37,7 +37,7 @@ type ExecCreateConfig struct { // Escape keys for detach DetachKeys string `json:"DetachKeys,omitempty"` - // Env for commands + // envs for exec command in container Env []string `json:"Env"` // Is the container in privileged mode diff --git a/test/cli_inspect_test.go b/test/cli_inspect_test.go index abc413242..044c19e49 100644 --- a/test/cli_inspect_test.go +++ b/test/cli_inspect_test.go @@ -37,7 +37,7 @@ func (suite *PouchInspectSuite) TearDownTest(c *check.C) { func (suite *PouchInspectSuite) TestInspectFormat(c *check.C) { name := "inspect-format-print" - res := command.PouchRun("create", "-m", "30M", "--name", name, busyboxImage) + res := command.PouchRun("create", "-m", "30M", "--name", name, busyboxImage, "top") defer DelContainerForceMultyTime(c, name) res.Assert(c, icmd.Success) @@ -61,7 +61,7 @@ func (suite *PouchInspectSuite) TestInspectFormat(c *check.C) { func (suite *PouchInspectSuite) TestInspectWrongFormat(c *check.C) { name := "inspect-wrong-format-print" - res := command.PouchRun("create", "-m", "30M", "--name", name, busyboxImage) + res := command.PouchRun("create", "-m", "30M", "--name", name, busyboxImage, "top") defer DelContainerForceMultyTime(c, name) res.Assert(c, icmd.Success) @@ -82,7 +82,7 @@ func (suite *PouchInspectSuite) TestMultiInspect(c *check.C) { } setUp := func() { for _, name := range names { - command.PouchRun("create", "-m", "30M", "--name", name, busyboxImage).Assert(c, icmd.Success) + command.PouchRun("create", "-m", "30M", "--name", name, busyboxImage, "top").Assert(c, icmd.Success) } } cleanUp := func() { @@ -100,7 +100,6 @@ func (suite *PouchInspectSuite) TestMultiInspect(c *check.C) { // TestMultiInspect is to verify inspect command with multiple args. func (suite *PouchInspectSuite) TestMultiInspectErrors(c *check.C) { - errorCases := []struct { containers []string args []string @@ -140,3 +139,35 @@ func (suite *PouchInspectSuite) TestMultiInspectErrors(c *check.C) { c.Assert(output, check.Equals, errCase.expectedOutput) } } + +// +func (suite *PouchInspectSuite) TestContainerInspectState(c *check.C) { + // 1. /bin/sh will exit immediately + name := "TestContainerInspectStateAutoExit" + res := command.PouchRun("run", "--name", name, busyboxImage, "/bin/sh") + defer DelContainerForceMultyTime(c, name) + res.Assert(c, icmd.Success) + + output := command.PouchRun("inspect", "-f", "{{.State.Pid}}", name).Stdout() + c.Assert(strings.TrimSpace(output), check.Equals, "0") + output = command.PouchRun("inspect", "-f", "{{.State.ExitCode}}", name).Stdout() + c.Assert(strings.TrimSpace(output), check.Equals, "0") + output = command.PouchRun("inspect", "-f", "{{.State.Status}}", name).Stdout() + c.Assert(strings.TrimSpace(output), check.Equals, "exited") + + // 2. stop a container and check the exit code and + name = "TestContainerInspectStateManullyStop" + res = command.PouchRun("run", "-d", "--name", name, busyboxImage, "top") + defer DelContainerForceMultyTime(c, name) + res.Assert(c, icmd.Success) + // stop container + res = command.PouchRun("stop", "-t", "0", name) + res.Assert(c, icmd.Success) + + output = command.PouchRun("inspect", "-f", "{{.State.Pid}}", name).Stdout() + c.Assert(strings.TrimSpace(output), check.Equals, "0") + output = command.PouchRun("inspect", "-f", "{{.State.ExitCode}}", name).Stdout() + c.Assert(strings.TrimSpace(output), check.Not(check.Equals), "0") + output = command.PouchRun("inspect", "-f", "{{.State.Status}}", name).Stdout() + c.Assert(strings.TrimSpace(output), check.Equals, "stopped") +}