72 lines
1.4 KiB
Go
72 lines
1.4 KiB
Go
// +build windows
|
|
|
|
package hcs
|
|
|
|
import (
|
|
"syscall"
|
|
"time"
|
|
|
|
"github.com/Microsoft/hcsshim"
|
|
"github.com/containerd/containerd/plugin"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
type Process struct {
|
|
hcsshim.Process
|
|
|
|
pid uint32
|
|
io *IO
|
|
ec uint32
|
|
exitedAt time.Time
|
|
ecErr error
|
|
ecSync chan struct{}
|
|
}
|
|
|
|
func (p *Process) Pid() uint32 {
|
|
return p.pid
|
|
}
|
|
|
|
func (p *Process) ExitCode() (uint32, error) {
|
|
<-p.ecSync
|
|
return p.ec, p.ecErr
|
|
}
|
|
|
|
func (p *Process) ExitedAt() time.Time {
|
|
return p.exitedAt
|
|
}
|
|
|
|
func (p *Process) Status() plugin.Status {
|
|
select {
|
|
case <-p.ecSync:
|
|
return plugin.StoppedStatus
|
|
default:
|
|
}
|
|
|
|
return plugin.RunningStatus
|
|
}
|
|
|
|
func (p *Process) Delete() error {
|
|
p.io.Close()
|
|
return p.Close()
|
|
}
|
|
|
|
func processExitCode(containerID string, p *Process) (uint32, error) {
|
|
if err := p.Wait(); err != nil {
|
|
if herr, ok := err.(*hcsshim.ProcessError); ok && herr.Err != syscall.ERROR_BROKEN_PIPE {
|
|
return 255, errors.Wrapf(err, "failed to wait for container '%s' process %u", containerID, p.pid)
|
|
}
|
|
// process is probably dead, let's try to get its exit code
|
|
}
|
|
|
|
ec, err := p.Process.ExitCode()
|
|
if err != nil {
|
|
if herr, ok := err.(*hcsshim.ProcessError); ok && herr.Err != syscall.ERROR_BROKEN_PIPE {
|
|
return 255, errors.Wrapf(err, "failed to get container '%s' process %d exit code", containerID, p.pid)
|
|
}
|
|
// Well, unknown exit code it is
|
|
ec = 255
|
|
}
|
|
p.exitedAt = time.Now()
|
|
return uint32(ec), err
|
|
}
|