hcnerrors.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. //go:build windows
  2. package hcn
  3. import (
  4. "errors"
  5. "fmt"
  6. "github.com/Microsoft/hcsshim/internal/hcs"
  7. "github.com/Microsoft/hcsshim/internal/hcserror"
  8. "github.com/Microsoft/hcsshim/internal/interop"
  9. "github.com/sirupsen/logrus"
  10. "golang.org/x/sys/windows"
  11. )
  12. var (
  13. errInvalidNetworkID = errors.New("invalid network ID")
  14. errInvalidEndpointID = errors.New("invalid endpoint ID")
  15. errInvalidNamespaceID = errors.New("invalid namespace ID")
  16. errInvalidLoadBalancerID = errors.New("invalid load balancer ID")
  17. errInvalidRouteID = errors.New("invalid route ID")
  18. )
  19. func checkForErrors(methodName string, hr error, resultBuffer *uint16) error {
  20. errorFound := false
  21. if hr != nil {
  22. errorFound = true
  23. }
  24. result := ""
  25. if resultBuffer != nil {
  26. result = interop.ConvertAndFreeCoTaskMemString(resultBuffer)
  27. if result != "" {
  28. errorFound = true
  29. }
  30. }
  31. if errorFound {
  32. returnError := new(hr, methodName, result)
  33. logrus.Debugf(returnError.Error()) // HCN errors logged for debugging.
  34. return returnError
  35. }
  36. return nil
  37. }
  38. type ErrorCode uint32
  39. // For common errors, define the error as it is in windows, so we can quickly determine it later
  40. const (
  41. ERROR_NOT_FOUND = ErrorCode(windows.ERROR_NOT_FOUND)
  42. HCN_E_PORT_ALREADY_EXISTS ErrorCode = ErrorCode(windows.HCN_E_PORT_ALREADY_EXISTS)
  43. )
  44. type HcnError struct {
  45. *hcserror.HcsError
  46. code ErrorCode
  47. }
  48. func (e *HcnError) Error() string {
  49. return e.HcsError.Error()
  50. }
  51. func CheckErrorWithCode(err error, code ErrorCode) bool {
  52. hcnError, ok := err.(*HcnError)
  53. if ok {
  54. return hcnError.code == code
  55. }
  56. return false
  57. }
  58. func IsElementNotFoundError(err error) bool {
  59. return CheckErrorWithCode(err, ERROR_NOT_FOUND)
  60. }
  61. func IsPortAlreadyExistsError(err error) bool {
  62. return CheckErrorWithCode(err, HCN_E_PORT_ALREADY_EXISTS)
  63. }
  64. func new(hr error, title string, rest string) error {
  65. err := &HcnError{}
  66. hcsError := hcserror.New(hr, title, rest)
  67. err.HcsError = hcsError.(*hcserror.HcsError)
  68. err.code = ErrorCode(hcserror.Win32FromError(hr))
  69. return err
  70. }
  71. //
  72. // Note that the below errors are not errors returned by hcn itself
  73. // we wish to separate them as they are shim usage error
  74. //
  75. // NetworkNotFoundError results from a failed search for a network by Id or Name
  76. type NetworkNotFoundError struct {
  77. NetworkName string
  78. NetworkID string
  79. }
  80. func (e NetworkNotFoundError) Error() string {
  81. if e.NetworkName != "" {
  82. return fmt.Sprintf("Network name %q not found", e.NetworkName)
  83. }
  84. return fmt.Sprintf("Network ID %q not found", e.NetworkID)
  85. }
  86. // EndpointNotFoundError results from a failed search for an endpoint by Id or Name
  87. type EndpointNotFoundError struct {
  88. EndpointName string
  89. EndpointID string
  90. }
  91. func (e EndpointNotFoundError) Error() string {
  92. if e.EndpointName != "" {
  93. return fmt.Sprintf("Endpoint name %q not found", e.EndpointName)
  94. }
  95. return fmt.Sprintf("Endpoint ID %q not found", e.EndpointID)
  96. }
  97. // NamespaceNotFoundError results from a failed search for a namsepace by Id
  98. type NamespaceNotFoundError struct {
  99. NamespaceID string
  100. }
  101. func (e NamespaceNotFoundError) Error() string {
  102. return fmt.Sprintf("Namespace ID %q not found", e.NamespaceID)
  103. }
  104. // LoadBalancerNotFoundError results from a failed search for a loadbalancer by Id
  105. type LoadBalancerNotFoundError struct {
  106. LoadBalancerId string
  107. }
  108. func (e LoadBalancerNotFoundError) Error() string {
  109. return fmt.Sprintf("LoadBalancer %q not found", e.LoadBalancerId)
  110. }
  111. // RouteNotFoundError results from a failed search for a route by Id
  112. type RouteNotFoundError struct {
  113. RouteId string
  114. }
  115. func (e RouteNotFoundError) Error() string {
  116. return fmt.Sprintf("SDN Route %q not found", e.RouteId)
  117. }
  118. // IsNotFoundError returns a boolean indicating whether the error was caused by
  119. // a resource not being found.
  120. func IsNotFoundError(err error) bool {
  121. switch pe := err.(type) {
  122. case NetworkNotFoundError:
  123. return true
  124. case EndpointNotFoundError:
  125. return true
  126. case NamespaceNotFoundError:
  127. return true
  128. case LoadBalancerNotFoundError:
  129. return true
  130. case RouteNotFoundError:
  131. return true
  132. case *hcserror.HcsError:
  133. return pe.Err == hcs.ErrElementNotFound
  134. }
  135. return false
  136. }