...

Source file src/github.com/Microsoft/hcsshim/errors.go

Documentation: github.com/Microsoft/hcsshim

     1  //go:build windows
     2  
     3  package hcsshim
     4  
     5  import (
     6  	"fmt"
     7  	"syscall"
     8  
     9  	"github.com/Microsoft/hcsshim/internal/hns"
    10  
    11  	"github.com/Microsoft/hcsshim/internal/hcs"
    12  	"github.com/Microsoft/hcsshim/internal/hcserror"
    13  )
    14  
    15  var (
    16  	// ErrComputeSystemDoesNotExist is an error encountered when the container being operated on no longer exists = hcs.exist
    17  	ErrComputeSystemDoesNotExist = hcs.ErrComputeSystemDoesNotExist
    18  
    19  	// ErrElementNotFound is an error encountered when the object being referenced does not exist
    20  	ErrElementNotFound = hcs.ErrElementNotFound
    21  
    22  	// ErrElementNotFound is an error encountered when the object being referenced does not exist
    23  	ErrNotSupported = hcs.ErrNotSupported
    24  
    25  	// ErrInvalidData is an error encountered when the request being sent to hcs is invalid/unsupported
    26  	// decimal -2147024883 / hex 0x8007000d
    27  	ErrInvalidData = hcs.ErrInvalidData
    28  
    29  	// ErrHandleClose is an error encountered when the handle generating the notification being waited on has been closed
    30  	ErrHandleClose = hcs.ErrHandleClose
    31  
    32  	// ErrAlreadyClosed is an error encountered when using a handle that has been closed by the Close method
    33  	ErrAlreadyClosed = hcs.ErrAlreadyClosed
    34  
    35  	// ErrInvalidNotificationType is an error encountered when an invalid notification type is used
    36  	ErrInvalidNotificationType = hcs.ErrInvalidNotificationType
    37  
    38  	// ErrInvalidProcessState is an error encountered when the process is not in a valid state for the requested operation
    39  	ErrInvalidProcessState = hcs.ErrInvalidProcessState
    40  
    41  	// ErrTimeout is an error encountered when waiting on a notification times out
    42  	ErrTimeout = hcs.ErrTimeout
    43  
    44  	// ErrUnexpectedContainerExit is the error encountered when a container exits while waiting for
    45  	// a different expected notification
    46  	ErrUnexpectedContainerExit = hcs.ErrUnexpectedContainerExit
    47  
    48  	// ErrUnexpectedProcessAbort is the error encountered when communication with the compute service
    49  	// is lost while waiting for a notification
    50  	ErrUnexpectedProcessAbort = hcs.ErrUnexpectedProcessAbort
    51  
    52  	// ErrUnexpectedValue is an error encountered when hcs returns an invalid value
    53  	ErrUnexpectedValue = hcs.ErrUnexpectedValue
    54  
    55  	// ErrOperationDenied is an error when hcs attempts an operation that is explicitly denied
    56  	ErrOperationDenied = hcs.ErrOperationDenied
    57  
    58  	// ErrVmcomputeAlreadyStopped is an error encountered when a shutdown or terminate request is made on a stopped container
    59  	ErrVmcomputeAlreadyStopped = hcs.ErrVmcomputeAlreadyStopped
    60  
    61  	// ErrVmcomputeOperationPending is an error encountered when the operation is being completed asynchronously
    62  	ErrVmcomputeOperationPending = hcs.ErrVmcomputeOperationPending
    63  
    64  	// ErrVmcomputeOperationInvalidState is an error encountered when the compute system is not in a valid state for the requested operation
    65  	ErrVmcomputeOperationInvalidState = hcs.ErrVmcomputeOperationInvalidState
    66  
    67  	// ErrProcNotFound is an error encountered when a procedure look up fails.
    68  	ErrProcNotFound = hcs.ErrProcNotFound
    69  
    70  	// ErrVmcomputeOperationAccessIsDenied is an error which can be encountered when enumerating compute systems in RS1/RS2
    71  	// builds when the underlying silo might be in the process of terminating. HCS was fixed in RS3.
    72  	ErrVmcomputeOperationAccessIsDenied = hcs.ErrVmcomputeOperationAccessIsDenied
    73  
    74  	// ErrVmcomputeInvalidJSON is an error encountered when the compute system does not support/understand the messages sent by management
    75  	ErrVmcomputeInvalidJSON = hcs.ErrVmcomputeInvalidJSON
    76  
    77  	// ErrVmcomputeUnknownMessage is an error encountered guest compute system doesn't support the message
    78  	ErrVmcomputeUnknownMessage = hcs.ErrVmcomputeUnknownMessage
    79  
    80  	// ErrNotSupported is an error encountered when hcs doesn't support the request
    81  	ErrPlatformNotSupported = hcs.ErrPlatformNotSupported
    82  )
    83  
    84  type EndpointNotFoundError = hns.EndpointNotFoundError
    85  type NetworkNotFoundError = hns.NetworkNotFoundError
    86  
    87  // ProcessError is an error encountered in HCS during an operation on a Process object
    88  type ProcessError struct {
    89  	Process   *process
    90  	Operation string
    91  	Err       error
    92  	Events    []hcs.ErrorEvent
    93  }
    94  
    95  // ContainerError is an error encountered in HCS during an operation on a Container object
    96  type ContainerError struct {
    97  	Container *container
    98  	Operation string
    99  	Err       error
   100  	Events    []hcs.ErrorEvent
   101  }
   102  
   103  func (e *ContainerError) Error() string {
   104  	if e == nil {
   105  		return "<nil>"
   106  	}
   107  
   108  	if e.Container == nil {
   109  		return "unexpected nil container for error: " + e.Err.Error()
   110  	}
   111  
   112  	s := "container " + e.Container.system.ID()
   113  
   114  	if e.Operation != "" {
   115  		s += " encountered an error during " + e.Operation
   116  	}
   117  
   118  	switch e.Err.(type) {
   119  	case nil:
   120  		break
   121  	case syscall.Errno:
   122  		s += fmt.Sprintf(": failure in a Windows system call: %s (0x%x)", e.Err, hcserror.Win32FromError(e.Err))
   123  	default:
   124  		s += fmt.Sprintf(": %s", e.Err.Error())
   125  	}
   126  
   127  	for _, ev := range e.Events {
   128  		s += "\n" + ev.String()
   129  	}
   130  
   131  	return s
   132  }
   133  
   134  func (e *ProcessError) Error() string {
   135  	if e == nil {
   136  		return "<nil>"
   137  	}
   138  
   139  	if e.Process == nil {
   140  		return "Unexpected nil process for error: " + e.Err.Error()
   141  	}
   142  
   143  	s := fmt.Sprintf("process %d in container %s", e.Process.p.Pid(), e.Process.p.SystemID())
   144  	if e.Operation != "" {
   145  		s += " encountered an error during " + e.Operation
   146  	}
   147  
   148  	switch e.Err.(type) {
   149  	case nil:
   150  		break
   151  	case syscall.Errno:
   152  		s += fmt.Sprintf(": failure in a Windows system call: %s (0x%x)", e.Err, hcserror.Win32FromError(e.Err))
   153  	default:
   154  		s += fmt.Sprintf(": %s", e.Err.Error())
   155  	}
   156  
   157  	for _, ev := range e.Events {
   158  		s += "\n" + ev.String()
   159  	}
   160  
   161  	return s
   162  }
   163  
   164  // IsNotExist checks if an error is caused by the Container or Process not existing.
   165  // Note: Currently, ErrElementNotFound can mean that a Process has either
   166  // already exited, or does not exist. Both IsAlreadyStopped and IsNotExist
   167  // will currently return true when the error is ErrElementNotFound.
   168  func IsNotExist(err error) bool {
   169  	if _, ok := err.(EndpointNotFoundError); ok {
   170  		return true
   171  	}
   172  	if _, ok := err.(NetworkNotFoundError); ok {
   173  		return true
   174  	}
   175  	return hcs.IsNotExist(getInnerError(err))
   176  }
   177  
   178  // IsAlreadyClosed checks if an error is caused by the Container or Process having been
   179  // already closed by a call to the Close() method.
   180  func IsAlreadyClosed(err error) bool {
   181  	return hcs.IsAlreadyClosed(getInnerError(err))
   182  }
   183  
   184  // IsPending returns a boolean indicating whether the error is that
   185  // the requested operation is being completed in the background.
   186  func IsPending(err error) bool {
   187  	return hcs.IsPending(getInnerError(err))
   188  }
   189  
   190  // IsTimeout returns a boolean indicating whether the error is caused by
   191  // a timeout waiting for the operation to complete.
   192  func IsTimeout(err error) bool {
   193  	return hcs.IsTimeout(getInnerError(err))
   194  }
   195  
   196  // IsAlreadyStopped returns a boolean indicating whether the error is caused by
   197  // a Container or Process being already stopped.
   198  // Note: Currently, ErrElementNotFound can mean that a Process has either
   199  // already exited, or does not exist. Both IsAlreadyStopped and IsNotExist
   200  // will currently return true when the error is ErrElementNotFound.
   201  func IsAlreadyStopped(err error) bool {
   202  	return hcs.IsAlreadyStopped(getInnerError(err))
   203  }
   204  
   205  // IsNotSupported returns a boolean indicating whether the error is caused by
   206  // unsupported platform requests
   207  // Note: Currently Unsupported platform requests can be mean either
   208  // ErrVmcomputeInvalidJSON, ErrInvalidData, ErrNotSupported or ErrVmcomputeUnknownMessage
   209  // is thrown from the Platform
   210  func IsNotSupported(err error) bool {
   211  	return hcs.IsNotSupported(getInnerError(err))
   212  }
   213  
   214  // IsOperationInvalidState returns true when err is caused by
   215  // `ErrVmcomputeOperationInvalidState`.
   216  func IsOperationInvalidState(err error) bool {
   217  	return hcs.IsOperationInvalidState(getInnerError(err))
   218  }
   219  
   220  // IsAccessIsDenied returns true when err is caused by
   221  // `ErrVmcomputeOperationAccessIsDenied`.
   222  func IsAccessIsDenied(err error) bool {
   223  	return hcs.IsAccessIsDenied(getInnerError(err))
   224  }
   225  
   226  func getInnerError(err error) error {
   227  	switch pe := err.(type) {
   228  	case nil:
   229  		return nil
   230  	case *ContainerError:
   231  		err = pe.Err
   232  	case *ProcessError:
   233  		err = pe.Err
   234  	}
   235  	return err
   236  }
   237  
   238  func convertSystemError(err error, c *container) error {
   239  	if serr, ok := err.(*hcs.SystemError); ok {
   240  		return &ContainerError{Container: c, Operation: serr.Op, Err: serr.Err, Events: serr.Events}
   241  	}
   242  	return err
   243  }
   244  
   245  func convertProcessError(err error, p *process) error {
   246  	if perr, ok := err.(*hcs.ProcessError); ok {
   247  		return &ProcessError{Process: p, Operation: perr.Op, Err: perr.Err, Events: perr.Events}
   248  	}
   249  	return err
   250  }
   251  

View as plain text