Adds containerd-shim-runhcs verbose logging support
Revendors to Microsoft/hcsshim v0.7.5 that added support for logging all runhcs.exe commands via Windows named pipes. This now launches all runhcs.exe commands and forwards debug logging to the containerd-shim-runhcs log when with --debug. Signed-off-by: Justin Terry (VM) <juterry@microsoft.com>
This commit is contained in:
parent
772644e978
commit
81eb40fabf
@ -22,15 +22,19 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
winio "github.com/Microsoft/go-winio"
|
||||||
"github.com/Microsoft/hcsshim/cmd/go-runhcs"
|
"github.com/Microsoft/hcsshim/cmd/go-runhcs"
|
||||||
containerd_types "github.com/containerd/containerd/api/types"
|
containerd_types "github.com/containerd/containerd/api/types"
|
||||||
"github.com/containerd/containerd/api/types/task"
|
"github.com/containerd/containerd/api/types/task"
|
||||||
@ -50,24 +54,87 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
runhcsShimVersion = "0.0.1"
|
runhcsShimVersion = "0.0.1"
|
||||||
|
safePipePrefix = `\\.\pipe\ProtectedPrefix\Administrators\`
|
||||||
|
|
||||||
|
errorConnectionAborted syscall.Errno = 1236
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
empty = &ptypes.Empty{}
|
empty = &ptypes.Empty{}
|
||||||
)
|
)
|
||||||
|
|
||||||
func newRunhcs(bundle string) *runhcs.Runhcs {
|
func newRunhcs(debugLog string) *runhcs.Runhcs {
|
||||||
rhs := &runhcs.Runhcs{
|
rhs := &runhcs.Runhcs{
|
||||||
Debug: logrus.GetLevel() == logrus.DebugLevel,
|
Debug: debugLog != "",
|
||||||
LogFormat: runhcs.JSON,
|
LogFormat: runhcs.JSON,
|
||||||
Owner: "containerd-runhcs-shim-v1",
|
Owner: "containerd-runhcs-shim-v1",
|
||||||
}
|
}
|
||||||
if rhs.Debug {
|
if rhs.Debug {
|
||||||
rhs.Log = filepath.Join(bundle, "runhcs-debug.log")
|
rhs.Log = debugLog
|
||||||
}
|
}
|
||||||
return rhs
|
return rhs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// forwardRunhcsLogs copies logs from c and writes them to the ctx logger
|
||||||
|
// upstream.
|
||||||
|
func forwardRunhcsLogs(ctx context.Context, c net.Conn, fields logrus.Fields) {
|
||||||
|
defer c.Close()
|
||||||
|
j := json.NewDecoder(c)
|
||||||
|
|
||||||
|
for {
|
||||||
|
e := logrus.Entry{}
|
||||||
|
err := j.Decode(&e.Data)
|
||||||
|
if err == io.EOF || err == errorConnectionAborted {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
// Likely the last message wasn't complete at closure. Just read all
|
||||||
|
// data and forward as error.
|
||||||
|
data, _ := ioutil.ReadAll(io.MultiReader(j.Buffered(), c))
|
||||||
|
if len(data) != 0 {
|
||||||
|
log.G(ctx).WithFields(fields).Error(string(data))
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := e.Data[logrus.FieldKeyMsg]
|
||||||
|
delete(e.Data, logrus.FieldKeyMsg)
|
||||||
|
|
||||||
|
level, err := logrus.ParseLevel(e.Data[logrus.FieldKeyLevel].(string))
|
||||||
|
if err != nil {
|
||||||
|
log.G(ctx).WithFields(fields).WithError(err).Debug("invalid log level")
|
||||||
|
level = logrus.DebugLevel
|
||||||
|
}
|
||||||
|
delete(e.Data, logrus.FieldKeyLevel)
|
||||||
|
|
||||||
|
// TODO: JTERRY75 maybe we need to make this configurable so we know
|
||||||
|
// that runhcs is using the same one we are deserializing.
|
||||||
|
ti, err := time.Parse(logrus.DefaultTimestampFormat, e.Data[logrus.FieldKeyTime].(string))
|
||||||
|
if err != nil {
|
||||||
|
log.G(ctx).WithFields(fields).WithError(err).Debug("invalid time stamp format")
|
||||||
|
ti = time.Time{}
|
||||||
|
}
|
||||||
|
delete(e.Data, logrus.FieldKeyTime)
|
||||||
|
|
||||||
|
etr := log.G(ctx).WithFields(fields).WithFields(e.Data)
|
||||||
|
etr.Time = ti
|
||||||
|
switch level {
|
||||||
|
case logrus.PanicLevel:
|
||||||
|
etr.Panic(msg)
|
||||||
|
case logrus.FatalLevel:
|
||||||
|
etr.Fatal(msg)
|
||||||
|
case logrus.ErrorLevel:
|
||||||
|
etr.Error(msg)
|
||||||
|
case logrus.WarnLevel:
|
||||||
|
etr.Warn(msg)
|
||||||
|
case logrus.InfoLevel:
|
||||||
|
etr.Info(msg)
|
||||||
|
case logrus.DebugLevel:
|
||||||
|
etr.Debug(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// New returns a new runhcs shim service that can be used via GRPC
|
// New returns a new runhcs shim service that can be used via GRPC
|
||||||
func New(ctx context.Context, id string, publisher events.Publisher) (shim.Shim, error) {
|
func New(ctx context.Context, id string, publisher events.Publisher) (shim.Shim, error) {
|
||||||
return &service{
|
return &service{
|
||||||
@ -87,6 +154,10 @@ type service struct {
|
|||||||
|
|
||||||
context context.Context
|
context context.Context
|
||||||
|
|
||||||
|
// debugLog if not "" indicates the log pipe path for runhcs.exe to write its logs to.
|
||||||
|
debugLog string
|
||||||
|
debugListener net.Listener
|
||||||
|
|
||||||
id string
|
id string
|
||||||
processes map[string]*process
|
processes map[string]*process
|
||||||
|
|
||||||
@ -195,6 +266,8 @@ func (s *service) StartShim(ctx context.Context, id, containerdBinary, container
|
|||||||
|
|
||||||
// State returns runtime state information for a process
|
// State returns runtime state information for a process
|
||||||
func (s *service) State(ctx context.Context, r *taskAPI.StateRequest) (*taskAPI.StateResponse, error) {
|
func (s *service) State(ctx context.Context, r *taskAPI.StateRequest) (*taskAPI.StateResponse, error) {
|
||||||
|
log.G(ctx).Debugf("State: %s: %s", r.ID, r.ExecID)
|
||||||
|
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
@ -208,7 +281,7 @@ func (s *service) State(ctx context.Context, r *taskAPI.StateRequest) (*taskAPI.
|
|||||||
|
|
||||||
// This is a container
|
// This is a container
|
||||||
if p.cid == p.id {
|
if p.cid == p.id {
|
||||||
rhcs := newRunhcs(p.bundle)
|
rhcs := newRunhcs(s.debugLog)
|
||||||
cs, err := rhcs.State(ctx, p.id)
|
cs, err := rhcs.State(ctx, p.id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -318,7 +391,7 @@ func writeMountsToConfig(bundle string, mounts []*containerd_types.Mount) error
|
|||||||
|
|
||||||
// Create a new initial process and container with runhcs
|
// Create a new initial process and container with runhcs
|
||||||
func (s *service) Create(ctx context.Context, r *taskAPI.CreateTaskRequest) (*taskAPI.CreateTaskResponse, error) {
|
func (s *service) Create(ctx context.Context, r *taskAPI.CreateTaskRequest) (*taskAPI.CreateTaskResponse, error) {
|
||||||
log.G(ctx).Infof("Create: %s", r.ID)
|
log.G(ctx).Debugf("Create: %s", r.ID)
|
||||||
|
|
||||||
// Hold the lock for the entire duration to avoid duplicate process creation.
|
// Hold the lock for the entire duration to avoid duplicate process creation.
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
@ -363,16 +436,84 @@ func (s *service) Create(ctx context.Context, r *taskAPI.CreateTaskRequest) (*ta
|
|||||||
pr.close()
|
pr.close()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
// TODO: Parse the real RunHcs Opts r.Options
|
||||||
|
opts, ok := ctx.Value(shim.OptsKey{}).(shim.Opts)
|
||||||
|
if ok && opts.Debug {
|
||||||
|
if s.debugLog == "" {
|
||||||
|
logPath := safePipePrefix + fmt.Sprintf("runhcs-log-%s", r.ID)
|
||||||
|
l, err := winio.ListenPipe(logPath, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
s.debugLog = logPath
|
||||||
|
s.debugListener = l
|
||||||
|
|
||||||
|
// Accept connections and forward all logs for each runhcs.exe
|
||||||
|
// invocation
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
c, err := s.debugListener.Accept()
|
||||||
|
if err != nil {
|
||||||
|
if err == errorConnectionAborted {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
log.G(ctx).WithError(err).Debug("log accept failure")
|
||||||
|
// Logrus error locally?
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fields := map[string]interface{}{
|
||||||
|
"log-source": "runhcs",
|
||||||
|
"task-id": r.ID,
|
||||||
|
}
|
||||||
|
go forwardRunhcsLogs(ctx, c, fields)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pidfilePath := path.Join(r.Bundle, "runhcs-pidfile.pid")
|
pidfilePath := path.Join(r.Bundle, "runhcs-pidfile.pid")
|
||||||
copts := &runhcs.CreateOpts{
|
copts := &runhcs.CreateOpts{
|
||||||
IO: io,
|
IO: io,
|
||||||
PidFile: pidfilePath,
|
PidFile: pidfilePath,
|
||||||
ShimLog: path.Join(r.Bundle, "runhcs-shim.log"),
|
}
|
||||||
VMLog: path.Join(r.Bundle, "runhcs-vm-shim.log"),
|
rhcs := newRunhcs(s.debugLog)
|
||||||
|
if rhcs.Debug {
|
||||||
|
doForwardLogs := func(source, logPipeFmt string, opt *string) error {
|
||||||
|
pipeName := fmt.Sprintf(logPipeFmt, r.ID)
|
||||||
|
*opt = safePipePrefix + pipeName
|
||||||
|
l, err := winio.ListenPipe(*opt, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
defer l.Close()
|
||||||
|
c, err := l.Accept()
|
||||||
|
if err != nil {
|
||||||
|
log.G(ctx).
|
||||||
|
WithField("task-id", r.ID).
|
||||||
|
WithError(err).
|
||||||
|
Errorf("failed to accept %s", pipeName)
|
||||||
|
} else {
|
||||||
|
fields := map[string]interface{}{
|
||||||
|
"log-source": source,
|
||||||
|
"task-id": r.ID,
|
||||||
|
}
|
||||||
|
go forwardRunhcsLogs(ctx, c, fields)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
rhcs := newRunhcs(r.Bundle)
|
err = doForwardLogs("runhcs-shim", "runhcs-shim-log-%s", &copts.ShimLog)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = doForwardLogs("runhcs--vm-shim", "runhcs-vm-shim-log-%s", &copts.VMLog)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
err = rhcs.Create(ctx, r.ID, r.Bundle, copts)
|
err = rhcs.Create(ctx, r.ID, r.Bundle, copts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -408,7 +549,7 @@ func (s *service) Create(ctx context.Context, r *taskAPI.CreateTaskRequest) (*ta
|
|||||||
|
|
||||||
// Start a process
|
// Start a process
|
||||||
func (s *service) Start(ctx context.Context, r *taskAPI.StartRequest) (*taskAPI.StartResponse, error) {
|
func (s *service) Start(ctx context.Context, r *taskAPI.StartRequest) (*taskAPI.StartResponse, error) {
|
||||||
log.G(ctx).Infof("Start: %s: %s", r.ID, r.ExecID)
|
log.G(ctx).Debugf("Start: %s: %s", r.ID, r.ExecID)
|
||||||
var p *process
|
var p *process
|
||||||
var err error
|
var err error
|
||||||
if p, err = s.getProcess(r.ID, r.ExecID); err != nil {
|
if p, err = s.getProcess(r.ID, r.ExecID); err != nil {
|
||||||
@ -421,7 +562,7 @@ func (s *service) Start(ctx context.Context, r *taskAPI.StartRequest) (*taskAPI.
|
|||||||
return nil, errors.New("cannot start already started container or process")
|
return nil, errors.New("cannot start already started container or process")
|
||||||
}
|
}
|
||||||
|
|
||||||
rhcs := newRunhcs(p.bundle)
|
rhcs := newRunhcs(s.debugLog)
|
||||||
|
|
||||||
// This is a start/exec
|
// This is a start/exec
|
||||||
if r.ExecID != "" {
|
if r.ExecID != "" {
|
||||||
@ -431,10 +572,43 @@ func (s *service) Start(ctx context.Context, r *taskAPI.StartRequest) (*taskAPI.
|
|||||||
eopts := &runhcs.ExecOpts{
|
eopts := &runhcs.ExecOpts{
|
||||||
IO: p.relay.io,
|
IO: p.relay.io,
|
||||||
PidFile: pidfilePath,
|
PidFile: pidfilePath,
|
||||||
ShimLog: path.Join(p.bundle, fmt.Sprintf("runhcs-%s-shim.log", execFmt)),
|
|
||||||
Detach: true,
|
Detach: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if rhcs.Debug {
|
||||||
|
doForwardLogs := func(source, pipeName string, opt *string) error {
|
||||||
|
*opt = safePipePrefix + pipeName
|
||||||
|
l, err := winio.ListenPipe(*opt, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
defer l.Close()
|
||||||
|
c, err := l.Accept()
|
||||||
|
if err != nil {
|
||||||
|
log.G(ctx).
|
||||||
|
WithField("task-id", r.ID).
|
||||||
|
WithField("exec-id", r.ExecID).
|
||||||
|
WithError(err).
|
||||||
|
Errorf("failed to accept %s", pipeName)
|
||||||
|
} else {
|
||||||
|
fields := map[string]interface{}{
|
||||||
|
"log-source": source,
|
||||||
|
"task-id": r.ID,
|
||||||
|
"exec-id": r.ExecID,
|
||||||
|
}
|
||||||
|
go forwardRunhcsLogs(ctx, c, fields)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err = doForwardLogs("runhcs-shim-exec", "runhcs-shim-log-"+execFmt, &eopts.ShimLog)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ID here is the containerID to exec the process in.
|
// ID here is the containerID to exec the process in.
|
||||||
err = rhcs.Exec(ctx, r.ID, procConfig, eopts)
|
err = rhcs.Exec(ctx, r.ID, procConfig, eopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -490,7 +664,7 @@ func (s *service) Start(ctx context.Context, r *taskAPI.StartRequest) (*taskAPI.
|
|||||||
|
|
||||||
// Delete the initial process and container
|
// Delete the initial process and container
|
||||||
func (s *service) Delete(ctx context.Context, r *taskAPI.DeleteRequest) (*taskAPI.DeleteResponse, error) {
|
func (s *service) Delete(ctx context.Context, r *taskAPI.DeleteRequest) (*taskAPI.DeleteResponse, error) {
|
||||||
log.G(ctx).Infof("Delete: %s: %s", r.ID, r.ExecID)
|
log.G(ctx).Debugf("Delete: %s: %s", r.ID, r.ExecID)
|
||||||
|
|
||||||
var p *process
|
var p *process
|
||||||
var err error
|
var err error
|
||||||
@ -500,7 +674,7 @@ func (s *service) Delete(ctx context.Context, r *taskAPI.DeleteRequest) (*taskAP
|
|||||||
|
|
||||||
// This is a container
|
// This is a container
|
||||||
if p.cid == p.id {
|
if p.cid == p.id {
|
||||||
rhs := newRunhcs(p.bundle)
|
rhs := newRunhcs(s.debugLog)
|
||||||
dopts := &runhcs.DeleteOpts{
|
dopts := &runhcs.DeleteOpts{
|
||||||
Force: true,
|
Force: true,
|
||||||
}
|
}
|
||||||
@ -530,11 +704,15 @@ func (s *service) Delete(ctx context.Context, r *taskAPI.DeleteRequest) (*taskAP
|
|||||||
|
|
||||||
// Pids returns all pids inside the container
|
// Pids returns all pids inside the container
|
||||||
func (s *service) Pids(ctx context.Context, r *taskAPI.PidsRequest) (*taskAPI.PidsResponse, error) {
|
func (s *service) Pids(ctx context.Context, r *taskAPI.PidsRequest) (*taskAPI.PidsResponse, error) {
|
||||||
|
log.G(ctx).Debugf("Pids: %s", r.ID)
|
||||||
|
|
||||||
return nil, errdefs.ErrNotImplemented
|
return nil, errdefs.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pause the container
|
// Pause the container
|
||||||
func (s *service) Pause(ctx context.Context, r *taskAPI.PauseRequest) (*ptypes.Empty, error) {
|
func (s *service) Pause(ctx context.Context, r *taskAPI.PauseRequest) (*ptypes.Empty, error) {
|
||||||
|
log.G(ctx).Debugf("Pause: %s", r.ID)
|
||||||
|
|
||||||
// TODO: Validate that 'id' is actually a valid parent container ID
|
// TODO: Validate that 'id' is actually a valid parent container ID
|
||||||
var p *process
|
var p *process
|
||||||
var err error
|
var err error
|
||||||
@ -542,7 +720,7 @@ func (s *service) Pause(ctx context.Context, r *taskAPI.PauseRequest) (*ptypes.E
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rhcs := newRunhcs(p.bundle)
|
rhcs := newRunhcs(s.debugLog)
|
||||||
if err = rhcs.Pause(ctx, p.id); err != nil {
|
if err = rhcs.Pause(ctx, p.id); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -552,6 +730,8 @@ func (s *service) Pause(ctx context.Context, r *taskAPI.PauseRequest) (*ptypes.E
|
|||||||
|
|
||||||
// Resume the container
|
// Resume the container
|
||||||
func (s *service) Resume(ctx context.Context, r *taskAPI.ResumeRequest) (*ptypes.Empty, error) {
|
func (s *service) Resume(ctx context.Context, r *taskAPI.ResumeRequest) (*ptypes.Empty, error) {
|
||||||
|
log.G(ctx).Debugf("Resume: %s", r.ID)
|
||||||
|
|
||||||
// TODO: Validate that 'id' is actually a valid parent container ID
|
// TODO: Validate that 'id' is actually a valid parent container ID
|
||||||
var p *process
|
var p *process
|
||||||
var err error
|
var err error
|
||||||
@ -559,7 +739,7 @@ func (s *service) Resume(ctx context.Context, r *taskAPI.ResumeRequest) (*ptypes
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rhcs := newRunhcs(p.bundle)
|
rhcs := newRunhcs(s.debugLog)
|
||||||
if err = rhcs.Resume(ctx, p.id); err != nil {
|
if err = rhcs.Resume(ctx, p.id); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -569,12 +749,14 @@ func (s *service) Resume(ctx context.Context, r *taskAPI.ResumeRequest) (*ptypes
|
|||||||
|
|
||||||
// Checkpoint the container
|
// Checkpoint the container
|
||||||
func (s *service) Checkpoint(ctx context.Context, r *taskAPI.CheckpointTaskRequest) (*ptypes.Empty, error) {
|
func (s *service) Checkpoint(ctx context.Context, r *taskAPI.CheckpointTaskRequest) (*ptypes.Empty, error) {
|
||||||
|
log.G(ctx).Debugf("Checkpoint: %s", r.ID)
|
||||||
|
|
||||||
return nil, errdefs.ErrNotImplemented
|
return nil, errdefs.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kill a process with the provided signal
|
// Kill a process with the provided signal
|
||||||
func (s *service) Kill(ctx context.Context, r *taskAPI.KillRequest) (*ptypes.Empty, error) {
|
func (s *service) Kill(ctx context.Context, r *taskAPI.KillRequest) (*ptypes.Empty, error) {
|
||||||
log.G(ctx).Infof("Kill: %s: %s", r.ID, r.ExecID)
|
log.G(ctx).Debugf("Kill: %s: %s", r.ID, r.ExecID)
|
||||||
|
|
||||||
var p *process
|
var p *process
|
||||||
var err error
|
var err error
|
||||||
@ -584,7 +766,7 @@ func (s *service) Kill(ctx context.Context, r *taskAPI.KillRequest) (*ptypes.Emp
|
|||||||
|
|
||||||
// TODO: JTERRY75 runhcs needs r.Signal in string form
|
// TODO: JTERRY75 runhcs needs r.Signal in string form
|
||||||
// TODO: JTERRY75 runhcs support for r.All?
|
// TODO: JTERRY75 runhcs support for r.All?
|
||||||
rhcs := newRunhcs(p.bundle)
|
rhcs := newRunhcs(s.debugLog)
|
||||||
if err = rhcs.Kill(ctx, p.id, strconv.FormatUint(uint64(r.Signal), 10)); err != nil {
|
if err = rhcs.Kill(ctx, p.id, strconv.FormatUint(uint64(r.Signal), 10)); err != nil {
|
||||||
if !strings.Contains(err.Error(), "container is stopped") {
|
if !strings.Contains(err.Error(), "container is stopped") {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -596,7 +778,7 @@ func (s *service) Kill(ctx context.Context, r *taskAPI.KillRequest) (*ptypes.Emp
|
|||||||
|
|
||||||
// Exec an additional process inside the container
|
// Exec an additional process inside the container
|
||||||
func (s *service) Exec(ctx context.Context, r *taskAPI.ExecProcessRequest) (*ptypes.Empty, error) {
|
func (s *service) Exec(ctx context.Context, r *taskAPI.ExecProcessRequest) (*ptypes.Empty, error) {
|
||||||
log.G(ctx).Infof("Exec: %s: %s", r.ID, r.ExecID)
|
log.G(ctx).Debugf("Exec: %s: %s", r.ID, r.ExecID)
|
||||||
|
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
defer s.mu.Unlock()
|
||||||
@ -679,6 +861,8 @@ func (s *service) Exec(ctx context.Context, r *taskAPI.ExecProcessRequest) (*pty
|
|||||||
|
|
||||||
// ResizePty of a process
|
// ResizePty of a process
|
||||||
func (s *service) ResizePty(ctx context.Context, r *taskAPI.ResizePtyRequest) (*ptypes.Empty, error) {
|
func (s *service) ResizePty(ctx context.Context, r *taskAPI.ResizePtyRequest) (*ptypes.Empty, error) {
|
||||||
|
log.G(ctx).Debugf("ResizePty: %s: %s", r.ID, r.ExecID)
|
||||||
|
|
||||||
var p *process
|
var p *process
|
||||||
var err error
|
var err error
|
||||||
if p, err = s.getProcess(r.ID, r.ExecID); err != nil {
|
if p, err = s.getProcess(r.ID, r.ExecID); err != nil {
|
||||||
@ -689,7 +873,7 @@ func (s *service) ResizePty(ctx context.Context, r *taskAPI.ResizePtyRequest) (*
|
|||||||
opts := runhcs.ResizeTTYOpts{
|
opts := runhcs.ResizeTTYOpts{
|
||||||
Pid: &pid,
|
Pid: &pid,
|
||||||
}
|
}
|
||||||
rhcs := newRunhcs(p.bundle)
|
rhcs := newRunhcs(s.debugLog)
|
||||||
if err = rhcs.ResizeTTY(ctx, p.cid, uint16(r.Width), uint16(r.Height), &opts); err != nil {
|
if err = rhcs.ResizeTTY(ctx, p.cid, uint16(r.Width), uint16(r.Height), &opts); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -699,6 +883,8 @@ func (s *service) ResizePty(ctx context.Context, r *taskAPI.ResizePtyRequest) (*
|
|||||||
|
|
||||||
// CloseIO of a process
|
// CloseIO of a process
|
||||||
func (s *service) CloseIO(ctx context.Context, r *taskAPI.CloseIORequest) (*ptypes.Empty, error) {
|
func (s *service) CloseIO(ctx context.Context, r *taskAPI.CloseIORequest) (*ptypes.Empty, error) {
|
||||||
|
log.G(ctx).Debugf("CloseIO: %s: %s", r.ID, r.ExecID)
|
||||||
|
|
||||||
var p *process
|
var p *process
|
||||||
var err error
|
var err error
|
||||||
if p, err = s.getProcess(r.ID, r.ExecID); err != nil {
|
if p, err = s.getProcess(r.ID, r.ExecID); err != nil {
|
||||||
@ -710,11 +896,15 @@ func (s *service) CloseIO(ctx context.Context, r *taskAPI.CloseIORequest) (*ptyp
|
|||||||
|
|
||||||
// Update a running container
|
// Update a running container
|
||||||
func (s *service) Update(ctx context.Context, r *taskAPI.UpdateTaskRequest) (*ptypes.Empty, error) {
|
func (s *service) Update(ctx context.Context, r *taskAPI.UpdateTaskRequest) (*ptypes.Empty, error) {
|
||||||
|
log.G(ctx).Debugf("Update: %s", r.ID)
|
||||||
|
|
||||||
return nil, errdefs.ErrNotImplemented
|
return nil, errdefs.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for a process to exit
|
// Wait for a process to exit
|
||||||
func (s *service) Wait(ctx context.Context, r *taskAPI.WaitRequest) (*taskAPI.WaitResponse, error) {
|
func (s *service) Wait(ctx context.Context, r *taskAPI.WaitRequest) (*taskAPI.WaitResponse, error) {
|
||||||
|
log.G(ctx).Debugf("Wait: %s: %s", r.ID, r.ExecID)
|
||||||
|
|
||||||
var p *process
|
var p *process
|
||||||
var err error
|
var err error
|
||||||
if p, err = s.getProcess(r.ID, r.ExecID); err != nil {
|
if p, err = s.getProcess(r.ID, r.ExecID); err != nil {
|
||||||
@ -729,11 +919,15 @@ func (s *service) Wait(ctx context.Context, r *taskAPI.WaitRequest) (*taskAPI.Wa
|
|||||||
|
|
||||||
// Stats returns statistics about the running container
|
// Stats returns statistics about the running container
|
||||||
func (s *service) Stats(ctx context.Context, r *taskAPI.StatsRequest) (*taskAPI.StatsResponse, error) {
|
func (s *service) Stats(ctx context.Context, r *taskAPI.StatsRequest) (*taskAPI.StatsResponse, error) {
|
||||||
|
log.G(ctx).Debugf("Stats: %s", r.ID)
|
||||||
|
|
||||||
return nil, errdefs.ErrNotImplemented
|
return nil, errdefs.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect returns the runhcs shim information
|
// Connect returns the runhcs shim information
|
||||||
func (s *service) Connect(ctx context.Context, r *taskAPI.ConnectRequest) (*taskAPI.ConnectResponse, error) {
|
func (s *service) Connect(ctx context.Context, r *taskAPI.ConnectRequest) (*taskAPI.ConnectResponse, error) {
|
||||||
|
log.G(ctx).Debugf("Connect: %s", r.ID)
|
||||||
|
|
||||||
return &taskAPI.ConnectResponse{
|
return &taskAPI.ConnectResponse{
|
||||||
ShimPid: uint32(os.Getpid()),
|
ShimPid: uint32(os.Getpid()),
|
||||||
TaskPid: s.processes[s.id].pid,
|
TaskPid: s.processes[s.id].pid,
|
||||||
@ -743,7 +937,11 @@ func (s *service) Connect(ctx context.Context, r *taskAPI.ConnectRequest) (*task
|
|||||||
|
|
||||||
// Shutdown stops this instance of the runhcs shim
|
// Shutdown stops this instance of the runhcs shim
|
||||||
func (s *service) Shutdown(ctx context.Context, r *taskAPI.ShutdownRequest) (*ptypes.Empty, error) {
|
func (s *service) Shutdown(ctx context.Context, r *taskAPI.ShutdownRequest) (*ptypes.Empty, error) {
|
||||||
log.G(ctx).Infof("Shutdown: %s", r.ID)
|
log.G(ctx).Debugf("Shutdown: %s", r.ID)
|
||||||
|
|
||||||
|
if s.debugListener != nil {
|
||||||
|
s.debugListener.Close()
|
||||||
|
}
|
||||||
|
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
return empty, nil
|
return empty, nil
|
||||||
|
@ -33,7 +33,7 @@ golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c
|
|||||||
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
|
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
|
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
|
||||||
github.com/Microsoft/go-winio v0.4.10
|
github.com/Microsoft/go-winio v0.4.10
|
||||||
github.com/Microsoft/hcsshim v0.7.4
|
github.com/Microsoft/hcsshim v0.7.6
|
||||||
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
||||||
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
||||||
github.com/containerd/ttrpc 2a805f71863501300ae1976d29f0454ae003e85a
|
github.com/containerd/ttrpc 2a805f71863501300ae1976d29f0454ae003e85a
|
||||||
|
13
vendor/github.com/Microsoft/hcsshim/cmd/go-runhcs/runhcs.go
generated
vendored
13
vendor/github.com/Microsoft/hcsshim/cmd/go-runhcs/runhcs.go
generated
vendored
@ -6,6 +6,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/containerd/go-runc"
|
"github.com/containerd/go-runc"
|
||||||
@ -22,6 +24,7 @@ const (
|
|||||||
JSON Format = "json"
|
JSON Format = "json"
|
||||||
|
|
||||||
command = "runhcs"
|
command = "runhcs"
|
||||||
|
safePipePrefix = `\\.\pipe\ProtectedPrefix\Administrators\`
|
||||||
)
|
)
|
||||||
|
|
||||||
var bytesBufferPool = sync.Pool{
|
var bytesBufferPool = sync.Pool{
|
||||||
@ -43,7 +46,7 @@ func putBuf(b *bytes.Buffer) {
|
|||||||
type Runhcs struct {
|
type Runhcs struct {
|
||||||
// Debug enables debug output for logging.
|
// Debug enables debug output for logging.
|
||||||
Debug bool
|
Debug bool
|
||||||
// Log sets the log file path where internal debug information is written.
|
// Log sets the log file path or named pipe (e.g. \\.\pipe\ProtectedPrefix\Administrators\runhcs-log) where internal debug information is written.
|
||||||
Log string
|
Log string
|
||||||
// LogFormat sets the format used by logs.
|
// LogFormat sets the format used by logs.
|
||||||
LogFormat Format
|
LogFormat Format
|
||||||
@ -59,8 +62,14 @@ func (r *Runhcs) args() []string {
|
|||||||
out = append(out, "--debug")
|
out = append(out, "--debug")
|
||||||
}
|
}
|
||||||
if r.Log != "" {
|
if r.Log != "" {
|
||||||
// TODO: JTERRY75 - Should we do abs here?
|
if strings.HasPrefix(r.Log, safePipePrefix) {
|
||||||
out = append(out, "--log", r.Log)
|
out = append(out, "--log", r.Log)
|
||||||
|
} else {
|
||||||
|
abs, err := filepath.Abs(r.Log)
|
||||||
|
if err == nil {
|
||||||
|
out = append(out, "--log", abs)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if r.LogFormat != none {
|
if r.LogFormat != none {
|
||||||
out = append(out, "--log-format", string(r.LogFormat))
|
out = append(out, "--log-format", string(r.LogFormat))
|
||||||
|
13
vendor/github.com/Microsoft/hcsshim/cmd/go-runhcs/runhcs_create.go
generated
vendored
13
vendor/github.com/Microsoft/hcsshim/cmd/go-runhcs/runhcs_create.go
generated
vendored
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
runc "github.com/containerd/go-runc"
|
runc "github.com/containerd/go-runc"
|
||||||
)
|
)
|
||||||
@ -13,9 +14,9 @@ type CreateOpts struct {
|
|||||||
runc.IO
|
runc.IO
|
||||||
// PidFile is the path to the file to write the process id to.
|
// PidFile is the path to the file to write the process id to.
|
||||||
PidFile string
|
PidFile string
|
||||||
// ShimLog is the path to the log file for the launched shim process.
|
// ShimLog is the path to the log file or named pipe (e.g. \\.\pipe\ProtectedPrefix\Administrators\runhcs-<container-id>-shim-log) for the launched shim process.
|
||||||
ShimLog string
|
ShimLog string
|
||||||
// VMLog is the path to the log file for the launched VM shim process.
|
// VMLog is the path to the log file or named pipe (e.g. \\.\pipe\ProtectedPrefix\Administrators\runhcs-<container-id>-vm-log) for the launched VM shim process.
|
||||||
VMLog string
|
VMLog string
|
||||||
// VMConsole is the path to the pipe for the VM's console (e.g. \\.\pipe\debugpipe)
|
// VMConsole is the path to the pipe for the VM's console (e.g. \\.\pipe\debugpipe)
|
||||||
VMConsole string
|
VMConsole string
|
||||||
@ -31,19 +32,27 @@ func (opt *CreateOpts) args() ([]string, error) {
|
|||||||
out = append(out, "--pid-file", abs)
|
out = append(out, "--pid-file", abs)
|
||||||
}
|
}
|
||||||
if opt.ShimLog != "" {
|
if opt.ShimLog != "" {
|
||||||
|
if strings.HasPrefix(opt.ShimLog, safePipePrefix) {
|
||||||
|
out = append(out, "--shim-log", opt.ShimLog)
|
||||||
|
} else {
|
||||||
abs, err := filepath.Abs(opt.ShimLog)
|
abs, err := filepath.Abs(opt.ShimLog)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
out = append(out, "--shim-log", abs)
|
out = append(out, "--shim-log", abs)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if opt.VMLog != "" {
|
if opt.VMLog != "" {
|
||||||
|
if strings.HasPrefix(opt.VMLog, safePipePrefix) {
|
||||||
|
out = append(out, "--vm-log", opt.VMLog)
|
||||||
|
} else {
|
||||||
abs, err := filepath.Abs(opt.VMLog)
|
abs, err := filepath.Abs(opt.VMLog)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
out = append(out, "--vm-log", abs)
|
out = append(out, "--vm-log", abs)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if opt.VMConsole != "" {
|
if opt.VMConsole != "" {
|
||||||
out = append(out, "--vm-console", opt.VMConsole)
|
out = append(out, "--vm-console", opt.VMConsole)
|
||||||
}
|
}
|
||||||
|
7
vendor/github.com/Microsoft/hcsshim/cmd/go-runhcs/runhcs_exec.go
generated
vendored
7
vendor/github.com/Microsoft/hcsshim/cmd/go-runhcs/runhcs_exec.go
generated
vendored
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/containerd/go-runc"
|
"github.com/containerd/go-runc"
|
||||||
)
|
)
|
||||||
@ -15,7 +16,7 @@ type ExecOpts struct {
|
|||||||
Detach bool
|
Detach bool
|
||||||
// PidFile is the path to the file to write the process id to.
|
// PidFile is the path to the file to write the process id to.
|
||||||
PidFile string
|
PidFile string
|
||||||
// ShimLog is the path to the log file for the launched shim process.
|
// ShimLog is the path to the log file or named pipe (e.g. \\.\pipe\ProtectedPrefix\Administrators\runhcs-<container-id>-<exec-id>-log) for the launched shim process.
|
||||||
ShimLog string
|
ShimLog string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,12 +33,16 @@ func (opt *ExecOpts) args() ([]string, error) {
|
|||||||
out = append(out, "--pid-file", abs)
|
out = append(out, "--pid-file", abs)
|
||||||
}
|
}
|
||||||
if opt.ShimLog != "" {
|
if opt.ShimLog != "" {
|
||||||
|
if strings.HasPrefix(opt.ShimLog, safePipePrefix) {
|
||||||
|
out = append(out, "--shim-log", opt.ShimLog)
|
||||||
|
} else {
|
||||||
abs, err := filepath.Abs(opt.ShimLog)
|
abs, err := filepath.Abs(opt.ShimLog)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
out = append(out, "--shim-log", abs)
|
out = append(out, "--shim-log", abs)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
vendor/github.com/Microsoft/hcsshim/hnsendpoint.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/hnsendpoint.go
generated
vendored
@ -6,6 +6,8 @@ import (
|
|||||||
|
|
||||||
// HNSEndpoint represents a network endpoint in HNS
|
// HNSEndpoint represents a network endpoint in HNS
|
||||||
type HNSEndpoint = hns.HNSEndpoint
|
type HNSEndpoint = hns.HNSEndpoint
|
||||||
|
// Namespace represents a Compartment.
|
||||||
|
type Namespace = hns.Namespace
|
||||||
|
|
||||||
//SystemType represents the type of the system on which actions are done
|
//SystemType represents the type of the system on which actions are done
|
||||||
type SystemType string
|
type SystemType string
|
||||||
|
Loading…
Reference in New Issue
Block a user