windows process exit timestamp
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
efe177ed77
commit
5d3bc1a4a7
@ -52,5 +52,4 @@ message Event {
|
|||||||
uint32 pid = 3;
|
uint32 pid = 3;
|
||||||
uint32 exit_status = 4;
|
uint32 exit_status = 4;
|
||||||
google.protobuf.Timestamp exited_at = 5 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
|
google.protobuf.Timestamp exited_at = 5 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ package windows
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/containerd/containerd"
|
"github.com/containerd/containerd"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
@ -19,7 +20,7 @@ var (
|
|||||||
ErrLoadedContainer = errors.New("loaded container can only be terminated")
|
ErrLoadedContainer = errors.New("loaded container can only be terminated")
|
||||||
)
|
)
|
||||||
|
|
||||||
type eventCallback func(id string, evType containerd.EventType, pid, exitStatus uint32)
|
type eventCallback func(id string, evType containerd.EventType, pid, exitStatus uint32, exitedAt time.Time)
|
||||||
|
|
||||||
func loadContainers(ctx context.Context, h *hcs.HCS, sendEvent eventCallback) ([]*container, error) {
|
func loadContainers(ctx context.Context, h *hcs.HCS, sendEvent eventCallback) ([]*container, error) {
|
||||||
hCtr, err := h.LoadContainers(ctx)
|
hCtr, err := h.LoadContainers(ctx)
|
||||||
@ -49,7 +50,7 @@ func newContainer(ctx context.Context, h *hcs.HCS, id string, spec RuntimeSpec,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sendEvent(id, containerd.CreateEvent, hcsCtr.Pid(), 0)
|
sendEvent(id, containerd.CreateEvent, hcsCtr.Pid(), 0, time.Time{})
|
||||||
|
|
||||||
return &container{
|
return &container{
|
||||||
ctr: hcsCtr,
|
ctr: hcsCtr,
|
||||||
@ -85,7 +86,7 @@ func (c *container) Start(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.setStatus(containerd.RunningStatus)
|
c.setStatus(containerd.RunningStatus)
|
||||||
c.sendEvent(c.ctr.ID(), containerd.StartEvent, c.ctr.Pid(), 0)
|
c.sendEvent(c.ctr.ID(), containerd.StartEvent, c.ctr.Pid(), 0, time.Time{})
|
||||||
|
|
||||||
// Wait for our process to terminate
|
// Wait for our process to terminate
|
||||||
go func() {
|
go func() {
|
||||||
@ -94,7 +95,7 @@ func (c *container) Start(ctx context.Context) error {
|
|||||||
log.G(ctx).Debug(err)
|
log.G(ctx).Debug(err)
|
||||||
}
|
}
|
||||||
c.setStatus(containerd.StoppedStatus)
|
c.setStatus(containerd.StoppedStatus)
|
||||||
c.sendEvent(c.ctr.ID(), containerd.ExitEvent, c.ctr.Pid(), ec)
|
c.sendEvent(c.ctr.ID(), containerd.ExitEvent, c.ctr.Pid(), ec, c.ctr.Processes()[0].ExitedAt())
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -136,7 +137,7 @@ func (c *container) Exec(ctx context.Context, opts containerd.ExecOpts) (contain
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.G(ctx).Debug(err)
|
log.G(ctx).Debug(err)
|
||||||
}
|
}
|
||||||
c.sendEvent(c.ctr.ID(), containerd.ExitEvent, p.Pid(), ec)
|
c.sendEvent(c.ctr.ID(), containerd.ExitEvent, p.Pid(), ec, p.ExitedAt())
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return &process{p}, nil
|
return &process{p}, nil
|
||||||
|
@ -167,6 +167,10 @@ func (c *Container) Pid() uint32 {
|
|||||||
return c.pid
|
return c.pid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Container) Processes() []*Process {
|
||||||
|
return c.processes
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Container) Start(ctx context.Context) error {
|
func (c *Container) Start(ctx context.Context) error {
|
||||||
_, err := c.addProcess(ctx, c.spec.Process, c.io)
|
_, err := c.addProcess(ctx, c.spec.Process, c.io)
|
||||||
return err
|
return err
|
||||||
|
@ -4,6 +4,7 @@ package hcs
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/Microsoft/hcsshim"
|
"github.com/Microsoft/hcsshim"
|
||||||
"github.com/containerd/containerd"
|
"github.com/containerd/containerd"
|
||||||
@ -13,11 +14,12 @@ import (
|
|||||||
type Process struct {
|
type Process struct {
|
||||||
hcsshim.Process
|
hcsshim.Process
|
||||||
|
|
||||||
pid uint32
|
pid uint32
|
||||||
io *IO
|
io *IO
|
||||||
ec uint32
|
ec uint32
|
||||||
ecErr error
|
exitedAt time.Time
|
||||||
ecSync chan struct{}
|
ecErr error
|
||||||
|
ecSync chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Process) Pid() uint32 {
|
func (p *Process) Pid() uint32 {
|
||||||
@ -29,6 +31,10 @@ func (p *Process) ExitCode() (uint32, error) {
|
|||||||
return p.ec, p.ecErr
|
return p.ec, p.ecErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Process) ExitedAt() time.Time {
|
||||||
|
return p.exitedAt
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Process) Status() containerd.Status {
|
func (p *Process) Status() containerd.Status {
|
||||||
select {
|
select {
|
||||||
case <-p.ecSync:
|
case <-p.ecSync:
|
||||||
@ -60,6 +66,6 @@ func processExitCode(containerID string, p *Process) (uint32, error) {
|
|||||||
// Well, unknown exit code it is
|
// Well, unknown exit code it is
|
||||||
ec = 255
|
ec = 255
|
||||||
}
|
}
|
||||||
|
p.exitedAt = time.Now()
|
||||||
return uint32(ec), err
|
return uint32(ec), err
|
||||||
}
|
}
|
||||||
|
@ -53,20 +53,16 @@ func New(ic *plugin.InitContext) (interface{}, error) {
|
|||||||
hcs: hcs.New(owner, rootDir),
|
hcs: hcs.New(owner, rootDir),
|
||||||
}
|
}
|
||||||
|
|
||||||
sendEvent := func(id string, evType containerd.EventType, pid, exitStatus uint32) {
|
|
||||||
r.sendEvent(id, evType, pid, exitStatus)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Terminate all previous container that we may have started. We don't
|
// Terminate all previous container that we may have started. We don't
|
||||||
// support restoring containers
|
// support restoring containers
|
||||||
ctrs, err := loadContainers(ic.Context, r.hcs, sendEvent)
|
ctrs, err := loadContainers(ic.Context, r.hcs, r.sendEvent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range ctrs {
|
for _, c := range ctrs {
|
||||||
c.ctr.Delete(ic.Context)
|
c.ctr.Delete(ic.Context)
|
||||||
r.sendEvent(c.ctr.ID(), containerd.ExitEvent, c.ctr.Pid(), 255)
|
r.sendEvent(c.ctr.ID(), containerd.ExitEvent, c.ctr.Pid(), 255, time.Time{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to delete the old state dir and recreate it
|
// Try to delete the old state dir and recreate it
|
||||||
@ -112,11 +108,7 @@ func (r *Runtime) Create(ctx context.Context, id string, opts containerd.CreateO
|
|||||||
return nil, errors.Wrap(err, "failed to unmarshal oci spec")
|
return nil, errors.Wrap(err, "failed to unmarshal oci spec")
|
||||||
}
|
}
|
||||||
|
|
||||||
sendEvent := func(id string, evType containerd.EventType, pid, exitStatus uint32) {
|
ctr, err := newContainer(ctx, r.hcs, id, rtSpec, opts.IO, r.sendEvent)
|
||||||
r.sendEvent(id, evType, pid, exitStatus)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctr, err := newContainer(ctx, r.hcs, id, rtSpec, opts.IO, sendEvent)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -128,10 +120,10 @@ func (r *Runtime) Create(ctx context.Context, id string, opts containerd.CreateO
|
|||||||
return ctr, nil
|
return ctr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Runtime) Delete(ctx context.Context, c containerd.Container) (uint32, error) {
|
func (r *Runtime) Delete(ctx context.Context, c containerd.Container) (*containerd.Exit, error) {
|
||||||
wc, ok := c.(*container)
|
wc, ok := c.(*container)
|
||||||
if !ok {
|
if !ok {
|
||||||
return 0, fmt.Errorf("container cannot be cast as *windows.container")
|
return nil, fmt.Errorf("container cannot be cast as *windows.container")
|
||||||
}
|
}
|
||||||
ec, err := wc.ctr.ExitCode()
|
ec, err := wc.ctr.ExitCode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -144,7 +136,10 @@ func (r *Runtime) Delete(ctx context.Context, c containerd.Container) (uint32, e
|
|||||||
delete(r.containers, wc.ctr.ID())
|
delete(r.containers, wc.ctr.ID())
|
||||||
r.Unlock()
|
r.Unlock()
|
||||||
|
|
||||||
return ec, err
|
return &containerd.Exit{
|
||||||
|
Status: ec,
|
||||||
|
Timestamp: wc.ctr.Processes()[0].ExitedAt(),
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Runtime) Containers(ctx context.Context) ([]containerd.Container, error) {
|
func (r *Runtime) Containers(ctx context.Context) ([]containerd.Container, error) {
|
||||||
@ -167,7 +162,7 @@ func (r *Runtime) Events(ctx context.Context) <-chan *containerd.Event {
|
|||||||
return r.events
|
return r.events
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Runtime) sendEvent(id string, evType containerd.EventType, pid, exitStatus uint32) {
|
func (r *Runtime) sendEvent(id string, evType containerd.EventType, pid, exitStatus uint32, exitedAt time.Time) {
|
||||||
r.events <- &containerd.Event{
|
r.events <- &containerd.Event{
|
||||||
Timestamp: time.Now(),
|
Timestamp: time.Now(),
|
||||||
Runtime: runtimeName,
|
Runtime: runtimeName,
|
||||||
@ -175,5 +170,6 @@ func (r *Runtime) sendEvent(id string, evType containerd.EventType, pid, exitSta
|
|||||||
Pid: pid,
|
Pid: pid,
|
||||||
ID: id,
|
ID: id,
|
||||||
ExitStatus: exitStatus,
|
ExitStatus: exitStatus,
|
||||||
|
ExitedAt: exitedAt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user