mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-10-31 16:13:45 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			258 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			258 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package hcsshim
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"syscall"
 | |
| 
 | |
| 	"github.com/Microsoft/hcsshim/internal/hns"
 | |
| 
 | |
| 	"github.com/Microsoft/hcsshim/internal/hcs"
 | |
| 	"github.com/Microsoft/hcsshim/internal/hcserror"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	// ErrComputeSystemDoesNotExist is an error encountered when the container being operated on no longer exists = hcs.exist
 | |
| 	ErrComputeSystemDoesNotExist = hcs.ErrComputeSystemDoesNotExist
 | |
| 
 | |
| 	// ErrElementNotFound is an error encountered when the object being referenced does not exist
 | |
| 	ErrElementNotFound = hcs.ErrElementNotFound
 | |
| 
 | |
| 	// ErrElementNotFound is an error encountered when the object being referenced does not exist
 | |
| 	ErrNotSupported = hcs.ErrNotSupported
 | |
| 
 | |
| 	// ErrInvalidData is an error encountered when the request being sent to hcs is invalid/unsupported
 | |
| 	// decimal -2147024883 / hex 0x8007000d
 | |
| 	ErrInvalidData = hcs.ErrInvalidData
 | |
| 
 | |
| 	// ErrHandleClose is an error encountered when the handle generating the notification being waited on has been closed
 | |
| 	ErrHandleClose = hcs.ErrHandleClose
 | |
| 
 | |
| 	// ErrAlreadyClosed is an error encountered when using a handle that has been closed by the Close method
 | |
| 	ErrAlreadyClosed = hcs.ErrAlreadyClosed
 | |
| 
 | |
| 	// ErrInvalidNotificationType is an error encountered when an invalid notification type is used
 | |
| 	ErrInvalidNotificationType = hcs.ErrInvalidNotificationType
 | |
| 
 | |
| 	// ErrInvalidProcessState is an error encountered when the process is not in a valid state for the requested operation
 | |
| 	ErrInvalidProcessState = hcs.ErrInvalidProcessState
 | |
| 
 | |
| 	// ErrTimeout is an error encountered when waiting on a notification times out
 | |
| 	ErrTimeout = hcs.ErrTimeout
 | |
| 
 | |
| 	// ErrUnexpectedContainerExit is the error encountered when a container exits while waiting for
 | |
| 	// a different expected notification
 | |
| 	ErrUnexpectedContainerExit = hcs.ErrUnexpectedContainerExit
 | |
| 
 | |
| 	// ErrUnexpectedProcessAbort is the error encountered when communication with the compute service
 | |
| 	// is lost while waiting for a notification
 | |
| 	ErrUnexpectedProcessAbort = hcs.ErrUnexpectedProcessAbort
 | |
| 
 | |
| 	// ErrUnexpectedValue is an error encountered when hcs returns an invalid value
 | |
| 	ErrUnexpectedValue = hcs.ErrUnexpectedValue
 | |
| 
 | |
| 	// ErrVmcomputeAlreadyStopped is an error encountered when a shutdown or terminate request is made on a stopped container
 | |
| 	ErrVmcomputeAlreadyStopped = hcs.ErrVmcomputeAlreadyStopped
 | |
| 
 | |
| 	// ErrVmcomputeOperationPending is an error encountered when the operation is being completed asynchronously
 | |
| 	ErrVmcomputeOperationPending = hcs.ErrVmcomputeOperationPending
 | |
| 
 | |
| 	// ErrVmcomputeOperationInvalidState is an error encountered when the compute system is not in a valid state for the requested operation
 | |
| 	ErrVmcomputeOperationInvalidState = hcs.ErrVmcomputeOperationInvalidState
 | |
| 
 | |
| 	// ErrProcNotFound is an error encountered when the the process cannot be found
 | |
| 	ErrProcNotFound = hcs.ErrProcNotFound
 | |
| 
 | |
| 	// ErrVmcomputeOperationAccessIsDenied is an error which can be encountered when enumerating compute systems in RS1/RS2
 | |
| 	// builds when the underlying silo might be in the process of terminating. HCS was fixed in RS3.
 | |
| 	ErrVmcomputeOperationAccessIsDenied = hcs.ErrVmcomputeOperationAccessIsDenied
 | |
| 
 | |
| 	// ErrVmcomputeInvalidJSON is an error encountered when the compute system does not support/understand the messages sent by management
 | |
| 	ErrVmcomputeInvalidJSON = hcs.ErrVmcomputeInvalidJSON
 | |
| 
 | |
| 	// ErrVmcomputeUnknownMessage is an error encountered guest compute system doesn't support the message
 | |
| 	ErrVmcomputeUnknownMessage = hcs.ErrVmcomputeUnknownMessage
 | |
| 
 | |
| 	// ErrNotSupported is an error encountered when hcs doesn't support the request
 | |
| 	ErrPlatformNotSupported = hcs.ErrPlatformNotSupported
 | |
| )
 | |
| 
 | |
| type EndpointNotFoundError = hns.EndpointNotFoundError
 | |
| type NetworkNotFoundError = hns.NetworkNotFoundError
 | |
| 
 | |
| // ProcessError is an error encountered in HCS during an operation on a Process object
 | |
| type ProcessError struct {
 | |
| 	Process   *process
 | |
| 	Operation string
 | |
| 	ExtraInfo string
 | |
| 	Err       error
 | |
| 	Events    []hcs.ErrorEvent
 | |
| }
 | |
| 
 | |
| // ContainerError is an error encountered in HCS during an operation on a Container object
 | |
| type ContainerError struct {
 | |
| 	Container *container
 | |
| 	Operation string
 | |
| 	ExtraInfo string
 | |
| 	Err       error
 | |
| 	Events    []hcs.ErrorEvent
 | |
| }
 | |
| 
 | |
| func (e *ContainerError) Error() string {
 | |
| 	if e == nil {
 | |
| 		return "<nil>"
 | |
| 	}
 | |
| 
 | |
| 	if e.Container == nil {
 | |
| 		return "unexpected nil container for error: " + e.Err.Error()
 | |
| 	}
 | |
| 
 | |
| 	s := "container " + e.Container.system.ID()
 | |
| 
 | |
| 	if e.Operation != "" {
 | |
| 		s += " encountered an error during " + e.Operation
 | |
| 	}
 | |
| 
 | |
| 	switch e.Err.(type) {
 | |
| 	case nil:
 | |
| 		break
 | |
| 	case syscall.Errno:
 | |
| 		s += fmt.Sprintf(": failure in a Windows system call: %s (0x%x)", e.Err, hcserror.Win32FromError(e.Err))
 | |
| 	default:
 | |
| 		s += fmt.Sprintf(": %s", e.Err.Error())
 | |
| 	}
 | |
| 
 | |
| 	for _, ev := range e.Events {
 | |
| 		s += "\n" + ev.String()
 | |
| 	}
 | |
| 
 | |
| 	if e.ExtraInfo != "" {
 | |
| 		s += " extra info: " + e.ExtraInfo
 | |
| 	}
 | |
| 
 | |
| 	return s
 | |
| }
 | |
| 
 | |
| func makeContainerError(container *container, operation string, extraInfo string, err error) error {
 | |
| 	// Don't double wrap errors
 | |
| 	if _, ok := err.(*ContainerError); ok {
 | |
| 		return err
 | |
| 	}
 | |
| 	containerError := &ContainerError{Container: container, Operation: operation, ExtraInfo: extraInfo, Err: err}
 | |
| 	return containerError
 | |
| }
 | |
| 
 | |
| func (e *ProcessError) Error() string {
 | |
| 	if e == nil {
 | |
| 		return "<nil>"
 | |
| 	}
 | |
| 
 | |
| 	if e.Process == nil {
 | |
| 		return "Unexpected nil process for error: " + e.Err.Error()
 | |
| 	}
 | |
| 
 | |
| 	s := fmt.Sprintf("process %d in container %s", e.Process.p.Pid(), e.Process.p.SystemID())
 | |
| 	if e.Operation != "" {
 | |
| 		s += " encountered an error during " + e.Operation
 | |
| 	}
 | |
| 
 | |
| 	switch e.Err.(type) {
 | |
| 	case nil:
 | |
| 		break
 | |
| 	case syscall.Errno:
 | |
| 		s += fmt.Sprintf(": failure in a Windows system call: %s (0x%x)", e.Err, hcserror.Win32FromError(e.Err))
 | |
| 	default:
 | |
| 		s += fmt.Sprintf(": %s", e.Err.Error())
 | |
| 	}
 | |
| 
 | |
| 	for _, ev := range e.Events {
 | |
| 		s += "\n" + ev.String()
 | |
| 	}
 | |
| 
 | |
| 	return s
 | |
| }
 | |
| 
 | |
| func makeProcessError(process *process, operation string, extraInfo string, err error) error {
 | |
| 	// Don't double wrap errors
 | |
| 	if _, ok := err.(*ProcessError); ok {
 | |
| 		return err
 | |
| 	}
 | |
| 	processError := &ProcessError{Process: process, Operation: operation, ExtraInfo: extraInfo, Err: err}
 | |
| 	return processError
 | |
| }
 | |
| 
 | |
| // IsNotExist checks if an error is caused by the Container or Process not existing.
 | |
| // Note: Currently, ErrElementNotFound can mean that a Process has either
 | |
| // already exited, or does not exist. Both IsAlreadyStopped and IsNotExist
 | |
| // will currently return true when the error is ErrElementNotFound or ErrProcNotFound.
 | |
| func IsNotExist(err error) bool {
 | |
| 	if _, ok := err.(EndpointNotFoundError); ok {
 | |
| 		return true
 | |
| 	}
 | |
| 	if _, ok := err.(NetworkNotFoundError); ok {
 | |
| 		return true
 | |
| 	}
 | |
| 	return hcs.IsNotExist(getInnerError(err))
 | |
| }
 | |
| 
 | |
| // IsAlreadyClosed checks if an error is caused by the Container or Process having been
 | |
| // already closed by a call to the Close() method.
 | |
| func IsAlreadyClosed(err error) bool {
 | |
| 	return hcs.IsAlreadyClosed(getInnerError(err))
 | |
| }
 | |
| 
 | |
| // IsPending returns a boolean indicating whether the error is that
 | |
| // the requested operation is being completed in the background.
 | |
| func IsPending(err error) bool {
 | |
| 	return hcs.IsPending(getInnerError(err))
 | |
| }
 | |
| 
 | |
| // IsTimeout returns a boolean indicating whether the error is caused by
 | |
| // a timeout waiting for the operation to complete.
 | |
| func IsTimeout(err error) bool {
 | |
| 	return hcs.IsTimeout(getInnerError(err))
 | |
| }
 | |
| 
 | |
| // IsAlreadyStopped returns a boolean indicating whether the error is caused by
 | |
| // a Container or Process being already stopped.
 | |
| // Note: Currently, ErrElementNotFound can mean that a Process has either
 | |
| // already exited, or does not exist. Both IsAlreadyStopped and IsNotExist
 | |
| // will currently return true when the error is ErrElementNotFound or ErrProcNotFound.
 | |
| func IsAlreadyStopped(err error) bool {
 | |
| 	return hcs.IsAlreadyStopped(getInnerError(err))
 | |
| }
 | |
| 
 | |
| // IsNotSupported returns a boolean indicating whether the error is caused by
 | |
| // unsupported platform requests
 | |
| // Note: Currently Unsupported platform requests can be mean either
 | |
| // ErrVmcomputeInvalidJSON, ErrInvalidData, ErrNotSupported or ErrVmcomputeUnknownMessage
 | |
| // is thrown from the Platform
 | |
| func IsNotSupported(err error) bool {
 | |
| 	return hcs.IsNotSupported(getInnerError(err))
 | |
| }
 | |
| 
 | |
| func getInnerError(err error) error {
 | |
| 	switch pe := err.(type) {
 | |
| 	case nil:
 | |
| 		return nil
 | |
| 	case *ContainerError:
 | |
| 		err = pe.Err
 | |
| 	case *ProcessError:
 | |
| 		err = pe.Err
 | |
| 	}
 | |
| 	return err
 | |
| }
 | |
| 
 | |
| func convertSystemError(err error, c *container) error {
 | |
| 	if serr, ok := err.(*hcs.SystemError); ok {
 | |
| 		return &ContainerError{Container: c, Operation: serr.Op, ExtraInfo: serr.Extra, Err: serr.Err, Events: serr.Events}
 | |
| 	}
 | |
| 	return err
 | |
| }
 | |
| 
 | |
| func convertProcessError(err error, p *process) error {
 | |
| 	if perr, ok := err.(*hcs.ProcessError); ok {
 | |
| 		return &ProcessError{Process: p, Operation: perr.Op, Err: perr.Err, Events: perr.Events}
 | |
| 	}
 | |
| 	return err
 | |
| }
 | 
