Skip to content

Commit bf934f6

Browse files
Merge pull request #9706 from klihub/devel/main/nri-input/container-extra-status
server,nri: pass extended container status to NRI.
2 parents 256fed5 + 4eabb00 commit bf934f6

File tree

4 files changed

+92
-17
lines changed

4 files changed

+92
-17
lines changed

internal/nri/container.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,26 @@ import (
55
specs "github.com/opencontainers/runtime-spec/specs-go"
66
)
77

8+
// ContainerStatus represents the status of a container.
9+
type ContainerStatus struct {
10+
State nri.ContainerState
11+
Reason string
12+
Message string
13+
Pid uint32
14+
CreatedAt int64
15+
StartedAt int64
16+
FinishedAt int64
17+
ExitCode int32
18+
}
19+
820
// Container interface for interacting with NRI.
921
type Container interface {
1022
GetDomain() string
1123

1224
GetPodSandboxID() string
1325
GetID() string
1426
GetName() string
15-
GetState() nri.ContainerState
27+
GetStatus() *ContainerStatus
1628
GetLabels() map[string]string
1729
GetAnnotations() map[string]string
1830
GetArgs() []string
@@ -39,11 +51,13 @@ type LinuxContainer interface {
3951
}
4052

4153
func containerToNRI(ctr Container) *nri.Container {
54+
status := ctr.GetStatus()
55+
4256
return &nri.Container{
4357
Id: ctr.GetID(),
4458
PodSandboxId: ctr.GetPodSandboxID(),
4559
Name: ctr.GetName(),
46-
State: ctr.GetState(),
60+
State: status.State,
4761
Labels: ctr.GetLabels(),
4862
Annotations: ctr.GetAnnotations(),
4963
Args: ctr.GetArgs(),
@@ -53,6 +67,11 @@ func containerToNRI(ctr Container) *nri.Container {
5367
Linux: linuxContainerToNRI(ctr),
5468
User: ctr.GetUser(),
5569
Rlimits: ctr.GetRlimits(),
70+
Pid: status.Pid,
71+
CreatedAt: status.CreatedAt,
72+
StartedAt: status.StartedAt,
73+
FinishedAt: status.FinishedAt,
74+
ExitCode: status.ExitCode,
5675
}
5776
}
5877

server/container_start.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func (s *Server) StartContainer(ctx context.Context, req *types.StartContainerRe
8989
}
9090
}
9191

92-
if err := s.nri.stopContainer(ctx, sandbox, c); err != nil {
92+
if err := s.nri.stopContainer(ctx, sandbox, c, false); err != nil {
9393
log.Warnf(ctx, "NRI stop failed for container %q: %v", c.ID(), err)
9494
}
9595

server/container_stop.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,10 @@ func (s *Server) postStopCleanup(ctx context.Context, ctr *oci.Container, sb *sa
7979
}
8080
}
8181

82-
if err := s.nri.stopContainer(ctx, sb, ctr); err != nil {
82+
if err := s.nri.stopContainer(ctx, sb, ctr, true); err != nil {
8383
log.Warnf(ctx, "NRI stop container request of %s failed: %v", ctr.ID(), err)
8484
}
85+
8586
// persist container state at the end, so there's no window where CRI-O reports the container
8687
// as stopped, but hasn't run post stop hooks.
8788
if err := s.ContainerStateToDisk(ctx, ctr); err != nil {

server/nri-api.go

Lines changed: 68 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -293,11 +293,17 @@ func (a *nriAPI) postUpdateContainer(ctx context.Context, criCtr *oci.Container)
293293
return a.nri.PostUpdateContainer(ctx, pod, ctr)
294294
}
295295

296-
func (a *nriAPI) stopContainer(ctx context.Context, criPod *sandbox.Sandbox, criCtr *oci.Container) error {
296+
func (a *nriAPI) stopContainer(ctx context.Context, criPod *sandbox.Sandbox, criCtr *oci.Container, updateState bool) error {
297297
if !a.isEnabled() {
298298
return nil
299299
}
300300

301+
if updateState {
302+
if err := a.cri.Runtime().UpdateContainerStatus(ctx, criCtr); err != nil {
303+
log.Warnf(ctx, "Error updating the container status %q: %v", criCtr.ID(), err)
304+
}
305+
}
306+
301307
ctr := &criContainer{
302308
api: a,
303309
ctr: criCtr,
@@ -669,21 +675,70 @@ func (c *criContainer) GetName() string {
669675
return c.GetSpec().Annotations["io.kubernetes.container.name"]
670676
}
671677

672-
func (c *criContainer) GetState() api.ContainerState {
673-
if c.ctr != nil {
674-
switch c.ctr.State().Status {
675-
case oci.ContainerStateCreated:
676-
return api.ContainerState_CONTAINER_CREATED
677-
case oci.ContainerStatePaused:
678-
return api.ContainerState_CONTAINER_PAUSED
679-
case oci.ContainerStateRunning:
680-
return api.ContainerState_CONTAINER_RUNNING
681-
case oci.ContainerStateStopped:
682-
return api.ContainerState_CONTAINER_STOPPED
678+
func (c *criContainer) GetStatus() *nri.ContainerStatus {
679+
const (
680+
// unknownReason is the exit reason when a container's exit code is not known
681+
unknownReason = "Unknown"
682+
// completedExitReason is the exit reason when container exits with 0.
683+
completedExitReason = "Completed"
684+
// errorExitReason is the exit reason when container exits with non-zero.
685+
errorExitReason = "Error"
686+
// oomKilledReason is the exit reason when container is killed by OOM killer.
687+
oomKilledReason = "OOMKilled"
688+
// seccompKilledReason is the exit reason when container is killed by seccomp.
689+
seccompKilledReason = "seccomp killed"
690+
)
691+
692+
status := &nri.ContainerStatus{
693+
State: api.ContainerState_CONTAINER_UNKNOWN,
694+
Reason: unknownReason,
695+
}
696+
697+
if c.ctr == nil {
698+
return status
699+
}
700+
701+
cState := c.ctr.State()
702+
703+
switch cState.Status {
704+
case oci.ContainerStateCreated:
705+
status.State = api.ContainerState_CONTAINER_CREATED
706+
status.CreatedAt = c.ctr.CreatedAt().UnixNano()
707+
case oci.ContainerStateRunning, oci.ContainerStatePaused:
708+
status.State = api.ContainerState_CONTAINER_RUNNING
709+
status.CreatedAt = c.ctr.CreatedAt().UnixNano()
710+
status.StartedAt = cState.Started.UnixNano()
711+
case oci.ContainerStateStopped:
712+
status.State = api.ContainerState_CONTAINER_STOPPED
713+
status.CreatedAt = c.ctr.CreatedAt().UnixNano()
714+
status.StartedAt = cState.Started.UnixNano()
715+
status.FinishedAt = cState.Finished.UnixNano()
716+
717+
if cState.ExitCode != nil {
718+
status.ExitCode = *cState.ExitCode
683719
}
720+
721+
switch {
722+
case cState.OOMKilled:
723+
status.Reason = oomKilledReason
724+
case cState.SeccompKilled:
725+
status.Reason = seccompKilledReason
726+
status.Message = cState.Error
727+
case cState.ExitCode != nil:
728+
if status.ExitCode == 0 {
729+
status.Reason = completedExitReason
730+
} else {
731+
status.Reason = errorExitReason
732+
status.Message = cState.Error
733+
}
734+
}
735+
}
736+
737+
if cState.InitPid > 0 {
738+
status.Pid = uint32(cState.InitPid)
684739
}
685740

686-
return api.ContainerState_CONTAINER_UNKNOWN
741+
return status
687742
}
688743

689744
func (c *criContainer) GetLabels() map[string]string {

0 commit comments

Comments
 (0)