Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,6 @@ linters:
- staticcheck
path: internal/winapi/
text: "ST1003:"
- linters:
- staticcheck
path: internal/vmcompute/
text: "ST1003:"
- linters:
- staticcheck
path: internal/regstate/
Expand Down
8 changes: 6 additions & 2 deletions internal/gcs/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,10 @@ func (p *Process) ExitCode() (_ int, err error) {
return -1, errors.New("process not exited")
}
if err := p.waitCall.Err(); err != nil {
return -1, err
var rerr *rpcError
if !errors.As(err, &rerr) || uint32(rerr.result) != hrNotFound {
return -1, err
}
}
return int(p.waitResp.ExitCode), nil
}
Expand Down Expand Up @@ -274,7 +277,8 @@ func (p *Process) Stdio() (stdin io.Writer, stdout, stderr io.Reader) {
// Wait waits for the process (or guest connection) to terminate.
func (p *Process) Wait() error {
p.waitCall.Wait()
return p.waitCall.Err()
_, err := p.ExitCode()
return err
}

func (p *Process) waitBackground() {
Expand Down
163 changes: 0 additions & 163 deletions internal/hcs/callback.go

This file was deleted.

63 changes: 48 additions & 15 deletions internal/hcs/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,36 @@ type ErrorEvent struct {
EventID uint16 `json:"EventId,omitempty"`
Flags uint32 `json:"Flags,omitempty"`
Source string `json:"Source,omitempty"`
//Data []EventData `json:"Data,omitempty"` // Omit this as HCS doesn't encode this well. It's more confusing to include. It is however logged in debug mode (see processHcsResult function)
//Data []EventData `json:"Data,omitempty"` // Omit this as HCS doesn't encode this well. It's more confusing to include.
}

// hcsResult mirrors the HCS [ResultError] document and implements [error]
// so callers can recover it via [errors.As]. The unexported cause keeps
// [errors.Is] working against the underlying syscall errno.
//
// [ResultError]: https://learn.microsoft.com/en-us/virtualization/api/hcs/schemareference#ResultError
type hcsResult struct {
Error int32
ErrorMessage string
// ErrorCode mirrors the "Error" JSON field; renamed to avoid colliding
// with the [hcsResult.Error] method.
ErrorCode int32 `json:"Error,omitempty"`
ErrorMessage string `json:"ErrorMessage,omitempty"`
ErrorEvents []ErrorEvent `json:"ErrorEvents,omitempty"`

cause error
}

func (r *hcsResult) Error() string {
if r.cause != nil {
return r.cause.Error()
}
if r.ErrorMessage != "" {
return r.ErrorMessage
}
return fmt.Sprintf("hcs result: 0x%08x", uint32(r.ErrorCode))
}

func (r *hcsResult) Unwrap() error { return r.cause }

func (ev *ErrorEvent) String() string {
evs := "[Event Detail: " + ev.Message
if ev.StackTrace != "" {
Expand All @@ -129,14 +150,26 @@ func (ev *ErrorEvent) String() string {
return evs
}

func processHcsResult(ctx context.Context, resultJSON string) []ErrorEvent {
if resultJSON != "" {
result := &hcsResult{}
if err := json.Unmarshal([]byte(resultJSON), result); err != nil {
log.G(ctx).WithError(err).Warning("Could not unmarshal HCS result")
return nil
}
return result.ErrorEvents
// wrapHcsResult attaches the parsed HCS ResultError document to err so
// callers can recover it via `errors.As(err, new(*hcsResult))`. Returns
// err unchanged when the document is empty or unparseable.
func wrapHcsResult(ctx context.Context, err error, resultJSON string) error {
if err == nil || resultJSON == "" {
return err
}
r := &hcsResult{cause: err}
if jerr := json.Unmarshal([]byte(resultJSON), r); jerr != nil {
log.G(ctx).WithError(jerr).Warning("Could not unmarshal HCS result")
return err
}
return r
}

// eventsFromError returns the ErrorEvents from any wrapped HCS result in err.
func eventsFromError(err error) []ErrorEvent {
var r *hcsResult
if errors.As(err, &r) {
return r.ErrorEvents
}
return nil
}
Expand Down Expand Up @@ -201,7 +234,7 @@ func (e *SystemError) Error() string {
return s
}

func makeSystemError(system *System, op string, err error, events []ErrorEvent) error {
func makeSystemError(system *System, op string, err error) error {
// Don't double wrap errors
var e *SystemError
if errors.As(err, &e) {
Expand All @@ -213,7 +246,7 @@ func makeSystemError(system *System, op string, err error, events []ErrorEvent)
HcsError: HcsError{
Op: op,
Err: err,
Events: events,
Events: eventsFromError(err),
},
}
}
Expand All @@ -235,7 +268,7 @@ func (e *ProcessError) Error() string {
return s
}

func makeProcessError(process *Process, op string, err error, events []ErrorEvent) error {
func makeProcessError(process *Process, op string, err error) error {
// Don't double wrap errors
var e *ProcessError
if errors.As(err, &e) {
Expand All @@ -247,7 +280,7 @@ func makeProcessError(process *Process, op string, err error, events []ErrorEven
HcsError: HcsError{
Op: op,
Err: err,
Events: events,
Events: eventsFromError(err),
},
}
}
Expand Down
Loading
Loading