container.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. package hcsshim
  2. import (
  3. "fmt"
  4. "os"
  5. "time"
  6. "github.com/Microsoft/hcsshim/internal/hcs"
  7. "github.com/Microsoft/hcsshim/internal/mergemaps"
  8. "github.com/Microsoft/hcsshim/internal/schema1"
  9. )
  10. // ContainerProperties holds the properties for a container and the processes running in that container
  11. type ContainerProperties = schema1.ContainerProperties
  12. // MemoryStats holds the memory statistics for a container
  13. type MemoryStats = schema1.MemoryStats
  14. // ProcessorStats holds the processor statistics for a container
  15. type ProcessorStats = schema1.ProcessorStats
  16. // StorageStats holds the storage statistics for a container
  17. type StorageStats = schema1.StorageStats
  18. // NetworkStats holds the network statistics for a container
  19. type NetworkStats = schema1.NetworkStats
  20. // Statistics is the structure returned by a statistics call on a container
  21. type Statistics = schema1.Statistics
  22. // ProcessList is the structure of an item returned by a ProcessList call on a container
  23. type ProcessListItem = schema1.ProcessListItem
  24. // MappedVirtualDiskController is the structure of an item returned by a MappedVirtualDiskList call on a container
  25. type MappedVirtualDiskController = schema1.MappedVirtualDiskController
  26. // Type of Request Support in ModifySystem
  27. type RequestType = schema1.RequestType
  28. // Type of Resource Support in ModifySystem
  29. type ResourceType = schema1.ResourceType
  30. // RequestType const
  31. const (
  32. Add = schema1.Add
  33. Remove = schema1.Remove
  34. Network = schema1.Network
  35. )
  36. // ResourceModificationRequestResponse is the structure used to send request to the container to modify the system
  37. // Supported resource types are Network and Request Types are Add/Remove
  38. type ResourceModificationRequestResponse = schema1.ResourceModificationRequestResponse
  39. type container struct {
  40. system *hcs.System
  41. }
  42. // createComputeSystemAdditionalJSON is read from the environment at initialisation
  43. // time. It allows an environment variable to define additional JSON which
  44. // is merged in the CreateComputeSystem call to HCS.
  45. var createContainerAdditionalJSON []byte
  46. func init() {
  47. createContainerAdditionalJSON = ([]byte)(os.Getenv("HCSSHIM_CREATECONTAINER_ADDITIONALJSON"))
  48. }
  49. // CreateContainer creates a new container with the given configuration but does not start it.
  50. func CreateContainer(id string, c *ContainerConfig) (Container, error) {
  51. fullConfig, err := mergemaps.MergeJSON(c, createContainerAdditionalJSON)
  52. if err != nil {
  53. return nil, fmt.Errorf("failed to merge additional JSON '%s': %s", createContainerAdditionalJSON, err)
  54. }
  55. system, err := hcs.CreateComputeSystem(id, fullConfig)
  56. if err != nil {
  57. return nil, err
  58. }
  59. return &container{system}, err
  60. }
  61. // OpenContainer opens an existing container by ID.
  62. func OpenContainer(id string) (Container, error) {
  63. system, err := hcs.OpenComputeSystem(id)
  64. if err != nil {
  65. return nil, err
  66. }
  67. return &container{system}, err
  68. }
  69. // GetContainers gets a list of the containers on the system that match the query
  70. func GetContainers(q ComputeSystemQuery) ([]ContainerProperties, error) {
  71. return hcs.GetComputeSystems(q)
  72. }
  73. // Start synchronously starts the container.
  74. func (container *container) Start() error {
  75. return convertSystemError(container.system.Start(), container)
  76. }
  77. // Shutdown requests a container shutdown, but it may not actually be shutdown until Wait() succeeds.
  78. func (container *container) Shutdown() error {
  79. return convertSystemError(container.system.Shutdown(), container)
  80. }
  81. // Terminate requests a container terminate, but it may not actually be terminated until Wait() succeeds.
  82. func (container *container) Terminate() error {
  83. return convertSystemError(container.system.Terminate(), container)
  84. }
  85. // Waits synchronously waits for the container to shutdown or terminate.
  86. func (container *container) Wait() error {
  87. return convertSystemError(container.system.Wait(), container)
  88. }
  89. // WaitTimeout synchronously waits for the container to terminate or the duration to elapse. It
  90. // returns false if timeout occurs.
  91. func (container *container) WaitTimeout(t time.Duration) error {
  92. return convertSystemError(container.system.WaitTimeout(t), container)
  93. }
  94. // Pause pauses the execution of a container.
  95. func (container *container) Pause() error {
  96. return convertSystemError(container.system.Pause(), container)
  97. }
  98. // Resume resumes the execution of a container.
  99. func (container *container) Resume() error {
  100. return convertSystemError(container.system.Resume(), container)
  101. }
  102. // HasPendingUpdates returns true if the container has updates pending to install
  103. func (container *container) HasPendingUpdates() (bool, error) {
  104. return false, nil
  105. }
  106. // Statistics returns statistics for the container. This is a legacy v1 call
  107. func (container *container) Statistics() (Statistics, error) {
  108. properties, err := container.system.Properties(schema1.PropertyTypeStatistics)
  109. if err != nil {
  110. return Statistics{}, convertSystemError(err, container)
  111. }
  112. return properties.Statistics, nil
  113. }
  114. // ProcessList returns an array of ProcessListItems for the container. This is a legacy v1 call
  115. func (container *container) ProcessList() ([]ProcessListItem, error) {
  116. properties, err := container.system.Properties(schema1.PropertyTypeProcessList)
  117. if err != nil {
  118. return nil, convertSystemError(err, container)
  119. }
  120. return properties.ProcessList, nil
  121. }
  122. // This is a legacy v1 call
  123. func (container *container) MappedVirtualDisks() (map[int]MappedVirtualDiskController, error) {
  124. properties, err := container.system.Properties(schema1.PropertyTypeMappedVirtualDisk)
  125. if err != nil {
  126. return nil, convertSystemError(err, container)
  127. }
  128. return properties.MappedVirtualDiskControllers, nil
  129. }
  130. // CreateProcess launches a new process within the container.
  131. func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
  132. p, err := container.system.CreateProcess(c)
  133. if err != nil {
  134. return nil, convertSystemError(err, container)
  135. }
  136. return &process{p}, nil
  137. }
  138. // OpenProcess gets an interface to an existing process within the container.
  139. func (container *container) OpenProcess(pid int) (Process, error) {
  140. p, err := container.system.OpenProcess(pid)
  141. if err != nil {
  142. return nil, convertSystemError(err, container)
  143. }
  144. return &process{p}, nil
  145. }
  146. // Close cleans up any state associated with the container but does not terminate or wait for it.
  147. func (container *container) Close() error {
  148. return convertSystemError(container.system.Close(), container)
  149. }
  150. // Modify the System
  151. func (container *container) Modify(config *ResourceModificationRequestResponse) error {
  152. return convertSystemError(container.system.Modify(config), container)
  153. }