mirror of
https://github.com/containers/podman.git
synced 2025-07-04 18:27:33 +08:00
Improve ps handling of container start/stop time
Previously all calculations were done based off the container's start time. Retrieve end time and use it to calculate time stopped for containers. Also, convert ps JSON output to report timestamps for create, start, and stop times. Signed-off-by: Matthew Heon <matthew.heon@gmail.com> Closes: #1228 Approved by: rhatdan
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -15,4 +15,5 @@
|
|||||||
.ropeproject
|
.ropeproject
|
||||||
__pycache__
|
__pycache__
|
||||||
/cmd/podman/varlink/ioprojectatomicpodman.go
|
/cmd/podman/varlink/ioprojectatomicpodman.go
|
||||||
|
/cmd/podman/varlink/iopodman.go
|
||||||
.gopathok
|
.gopathok
|
||||||
|
@ -42,6 +42,7 @@ type BatchContainerStruct struct {
|
|||||||
Exited bool
|
Exited bool
|
||||||
Pid int
|
Pid int
|
||||||
StartedTime time.Time
|
StartedTime time.Time
|
||||||
|
ExitedTime time.Time
|
||||||
Size *ContainerSize
|
Size *ContainerSize
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,6 +77,7 @@ func BatchContainerOp(ctr *libpod.Container, opts PsOptions) (BatchContainerStru
|
|||||||
pid int
|
pid int
|
||||||
size *ContainerSize
|
size *ContainerSize
|
||||||
startedTime time.Time
|
startedTime time.Time
|
||||||
|
exitedTime time.Time
|
||||||
)
|
)
|
||||||
|
|
||||||
batchErr := ctr.Batch(func(c *libpod.Container) error {
|
batchErr := ctr.Batch(func(c *libpod.Container) error {
|
||||||
@ -93,6 +95,10 @@ func BatchContainerOp(ctr *libpod.Container, opts PsOptions) (BatchContainerStru
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("error getting started time for %q: %v", c.ID(), err)
|
logrus.Errorf("error getting started time for %q: %v", c.ID(), err)
|
||||||
}
|
}
|
||||||
|
exitedTime, err = c.FinishedTime()
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("error getting exited time for %q: %v", c.ID(), err)
|
||||||
|
}
|
||||||
|
|
||||||
if !opts.Size && !opts.Namespace {
|
if !opts.Size && !opts.Namespace {
|
||||||
return nil
|
return nil
|
||||||
@ -132,6 +138,7 @@ func BatchContainerOp(ctr *libpod.Container, opts PsOptions) (BatchContainerStru
|
|||||||
Exited: exited,
|
Exited: exited,
|
||||||
Pid: pid,
|
Pid: pid,
|
||||||
StartedTime: startedTime,
|
StartedTime: startedTime,
|
||||||
|
ExitedTime: exitedTime,
|
||||||
Size: size,
|
Size: size,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ type psTemplateParams struct {
|
|||||||
Command string
|
Command string
|
||||||
CreatedAtTime time.Time
|
CreatedAtTime time.Time
|
||||||
Created string
|
Created string
|
||||||
RunningFor string
|
|
||||||
Status string
|
Status string
|
||||||
Ports string
|
Ports string
|
||||||
Size string
|
Size string
|
||||||
@ -57,10 +56,11 @@ type psJSONParams struct {
|
|||||||
Image string `json:"image"`
|
Image string `json:"image"`
|
||||||
ImageID string `json:"image_id"`
|
ImageID string `json:"image_id"`
|
||||||
Command []string `json:"command"`
|
Command []string `json:"command"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
|
||||||
ExitCode int32 `json:"exitCode"`
|
ExitCode int32 `json:"exitCode"`
|
||||||
Exited bool `json:"exited"`
|
Exited bool `json:"exited"`
|
||||||
RunningFor time.Duration `json:"runningFor"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
StartedAt time.Time `json:"startedAt"`
|
||||||
|
ExitedAt time.Time `json:"exitedAt"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
PID int `json:"PID"`
|
PID int `json:"PID"`
|
||||||
Ports []ocicni.PortMapping `json:"ports"`
|
Ports []ocicni.PortMapping `json:"ports"`
|
||||||
@ -110,7 +110,7 @@ func (a psSortedPod) Less(i, j int) bool { return a.psSorted[i].Pod < a.psSorted
|
|||||||
type psSortedRunningFor struct{ psSorted }
|
type psSortedRunningFor struct{ psSorted }
|
||||||
|
|
||||||
func (a psSortedRunningFor) Less(i, j int) bool {
|
func (a psSortedRunningFor) Less(i, j int) bool {
|
||||||
return a.psSorted[i].RunningFor < a.psSorted[j].RunningFor
|
return a.psSorted[j].StartedAt.After(a.psSorted[i].StartedAt)
|
||||||
}
|
}
|
||||||
|
|
||||||
type psSortedStatus struct{ psSorted }
|
type psSortedStatus struct{ psSorted }
|
||||||
@ -529,7 +529,6 @@ func getTemplateOutput(psParams []psJSONParams, opts batchcontainer.PsOptions) (
|
|||||||
if opts.Pod {
|
if opts.Pod {
|
||||||
pod = psParam.Pod
|
pod = psParam.Pod
|
||||||
}
|
}
|
||||||
runningFor := units.HumanDuration(psParam.RunningFor)
|
|
||||||
|
|
||||||
command := strings.Join(psParam.Command, " ")
|
command := strings.Join(psParam.Command, " ")
|
||||||
if !opts.NoTrunc {
|
if !opts.NoTrunc {
|
||||||
@ -542,9 +541,10 @@ func getTemplateOutput(psParams []psJSONParams, opts batchcontainer.PsOptions) (
|
|||||||
|
|
||||||
switch psParam.Status {
|
switch psParam.Status {
|
||||||
case libpod.ContainerStateStopped.String():
|
case libpod.ContainerStateStopped.String():
|
||||||
status = fmt.Sprintf("Exited (%d) %s ago", psParam.ExitCode, runningFor)
|
exitedSince := units.HumanDuration(time.Since(psParam.ExitedAt))
|
||||||
|
status = fmt.Sprintf("Exited (%d) %s ago", psParam.ExitCode, exitedSince)
|
||||||
case libpod.ContainerStateRunning.String():
|
case libpod.ContainerStateRunning.String():
|
||||||
status = "Up " + runningFor + " ago"
|
status = "Up " + units.HumanDuration(time.Since(psParam.StartedAt)) + " ago"
|
||||||
case libpod.ContainerStatePaused.String():
|
case libpod.ContainerStatePaused.String():
|
||||||
status = "Paused"
|
status = "Paused"
|
||||||
case libpod.ContainerStateCreated.String(), libpod.ContainerStateConfigured.String():
|
case libpod.ContainerStateCreated.String(), libpod.ContainerStateConfigured.String():
|
||||||
@ -563,7 +563,6 @@ func getTemplateOutput(psParams []psJSONParams, opts batchcontainer.PsOptions) (
|
|||||||
Command: command,
|
Command: command,
|
||||||
CreatedAtTime: psParam.CreatedAt,
|
CreatedAtTime: psParam.CreatedAt,
|
||||||
Created: units.HumanDuration(time.Since(psParam.CreatedAt)) + " ago",
|
Created: units.HumanDuration(time.Since(psParam.CreatedAt)) + " ago",
|
||||||
RunningFor: runningFor,
|
|
||||||
Status: status,
|
Status: status,
|
||||||
Ports: ports,
|
Ports: ports,
|
||||||
Size: size,
|
Size: size,
|
||||||
@ -613,9 +612,11 @@ func getAndSortJSONParams(containers []*libpod.Container, opts batchcontainer.Ps
|
|||||||
Image: batchInfo.ConConfig.RootfsImageName,
|
Image: batchInfo.ConConfig.RootfsImageName,
|
||||||
ImageID: batchInfo.ConConfig.RootfsImageID,
|
ImageID: batchInfo.ConConfig.RootfsImageID,
|
||||||
Command: batchInfo.ConConfig.Spec.Process.Args,
|
Command: batchInfo.ConConfig.Spec.Process.Args,
|
||||||
CreatedAt: batchInfo.ConConfig.CreatedTime,
|
|
||||||
ExitCode: batchInfo.ExitCode,
|
ExitCode: batchInfo.ExitCode,
|
||||||
Exited: batchInfo.Exited,
|
Exited: batchInfo.Exited,
|
||||||
|
CreatedAt: batchInfo.ConConfig.CreatedTime,
|
||||||
|
StartedAt: batchInfo.StartedTime,
|
||||||
|
ExitedAt: batchInfo.ExitedTime,
|
||||||
Status: batchInfo.ConState.String(),
|
Status: batchInfo.ConState.String(),
|
||||||
PID: batchInfo.Pid,
|
PID: batchInfo.Pid,
|
||||||
Ports: batchInfo.ConConfig.PortMappings,
|
Ports: batchInfo.ConConfig.PortMappings,
|
||||||
@ -628,10 +629,6 @@ func getAndSortJSONParams(containers []*libpod.Container, opts batchcontainer.Ps
|
|||||||
Pod: ctr.PodID(),
|
Pod: ctr.PodID(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if !batchInfo.StartedTime.IsZero() && batchInfo.ConState == libpod.ContainerStateRunning {
|
|
||||||
params.RunningFor = time.Since(batchInfo.StartedTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
psOutput = append(psOutput, params)
|
psOutput = append(psOutput, params)
|
||||||
}
|
}
|
||||||
return sortPsOutput(opts.Sort, psOutput)
|
return sortPsOutput(opts.Sort, psOutput)
|
||||||
|
Reference in New Issue
Block a user