Nathan Gieseker 9a429d8d25 Windows: Updates Windows Vendoring
Updates windows dependent libraries for vendoing.
2019-01-23 18:43:18 -08:00

99 lines
2.0 KiB
Go

package uvm
import (
"context"
"encoding/json"
"io"
"io/ioutil"
"net"
"syscall"
"github.com/sirupsen/logrus"
)
const _ERROR_CONNECTION_ABORTED syscall.Errno = 1236
var _ = (OutputHandler)(parseLogrus)
func parseLogrus(r io.Reader) {
j := json.NewDecoder(r)
logger := logrus.StandardLogger()
for {
e := logrus.Entry{Logger: logger}
err := j.Decode(&e.Data)
if err == io.EOF || err == _ERROR_CONNECTION_ABORTED {
break
}
if err != nil {
// Something went wrong. Read the rest of the data as a single
// string and log it at once -- it's probably a GCS panic stack.
logrus.Error("gcs log read: ", err)
rest, _ := ioutil.ReadAll(io.MultiReader(j.Buffered(), r))
if len(rest) != 0 {
logrus.Error("gcs stderr: ", string(rest))
}
break
}
msg := e.Data["msg"]
delete(e.Data, "msg")
lvl := e.Data["level"]
delete(e.Data, "level")
e.Data["vm.time"] = e.Data["time"]
delete(e.Data, "time")
switch lvl {
case "debug":
e.Debug(msg)
case "info":
e.Info(msg)
case "warning":
e.Warning(msg)
case "error", "fatal":
e.Error(msg)
default:
e.Info(msg)
}
}
}
type acceptResult struct {
c net.Conn
err error
}
func processOutput(ctx context.Context, l net.Listener, doneChan chan struct{}, handler OutputHandler) {
defer close(doneChan)
ch := make(chan acceptResult)
go func() {
c, err := l.Accept()
ch <- acceptResult{c, err}
}()
select {
case <-ctx.Done():
l.Close()
return
case ar := <-ch:
c, err := ar.c, ar.err
l.Close()
if err != nil {
logrus.Error("accepting log socket: ", err)
return
}
defer c.Close()
handler(c)
}
}
// Start synchronously starts the utility VM.
func (uvm *UtilityVM) Start() error {
if uvm.outputListener != nil {
ctx, cancel := context.WithCancel(context.Background())
go processOutput(ctx, uvm.outputListener, uvm.outputProcessingDone, uvm.outputHandler)
uvm.outputProcessingCancel = cancel
uvm.outputListener = nil
}
return uvm.hcsSystem.Start()
}