fake_runtime.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /*
  2. Copyright 2017 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package fake
  14. import (
  15. "context"
  16. "fmt"
  17. "time"
  18. "google.golang.org/grpc"
  19. kubeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
  20. apitest "k8s.io/cri-api/pkg/apis/testing"
  21. "k8s.io/kubernetes/pkg/kubelet/util"
  22. utilexec "k8s.io/utils/exec"
  23. )
  24. // RemoteRuntime represents a fake remote container runtime.
  25. type RemoteRuntime struct {
  26. server *grpc.Server
  27. // Fake runtime service.
  28. RuntimeService *apitest.FakeRuntimeService
  29. // Fake image service.
  30. ImageService *apitest.FakeImageService
  31. }
  32. // NewFakeRemoteRuntime creates a new RemoteRuntime.
  33. func NewFakeRemoteRuntime() *RemoteRuntime {
  34. fakeRuntimeService := apitest.NewFakeRuntimeService()
  35. fakeImageService := apitest.NewFakeImageService()
  36. f := &RemoteRuntime{
  37. server: grpc.NewServer(),
  38. RuntimeService: fakeRuntimeService,
  39. ImageService: fakeImageService,
  40. }
  41. kubeapi.RegisterRuntimeServiceServer(f.server, f)
  42. kubeapi.RegisterImageServiceServer(f.server, f)
  43. return f
  44. }
  45. // Start starts the fake remote runtime.
  46. func (f *RemoteRuntime) Start(endpoint string) error {
  47. l, err := util.CreateListener(endpoint)
  48. if err != nil {
  49. return fmt.Errorf("failed to listen on %q: %v", endpoint, err)
  50. }
  51. go f.server.Serve(l)
  52. // Set runtime and network conditions ready.
  53. f.RuntimeService.FakeStatus = &kubeapi.RuntimeStatus{
  54. Conditions: []*kubeapi.RuntimeCondition{
  55. {Type: kubeapi.RuntimeReady, Status: true},
  56. {Type: kubeapi.NetworkReady, Status: true},
  57. },
  58. }
  59. return nil
  60. }
  61. // Stop stops the fake remote runtime.
  62. func (f *RemoteRuntime) Stop() {
  63. f.server.Stop()
  64. }
  65. // Version returns the runtime name, runtime version, and runtime API version.
  66. func (f *RemoteRuntime) Version(ctx context.Context, req *kubeapi.VersionRequest) (*kubeapi.VersionResponse, error) {
  67. return f.RuntimeService.Version(req.Version)
  68. }
  69. // RunPodSandbox creates and starts a pod-level sandbox. Runtimes must ensure
  70. // the sandbox is in the ready state on success.
  71. func (f *RemoteRuntime) RunPodSandbox(ctx context.Context, req *kubeapi.RunPodSandboxRequest) (*kubeapi.RunPodSandboxResponse, error) {
  72. sandboxID, err := f.RuntimeService.RunPodSandbox(req.Config, req.RuntimeHandler)
  73. if err != nil {
  74. return nil, err
  75. }
  76. return &kubeapi.RunPodSandboxResponse{PodSandboxId: sandboxID}, nil
  77. }
  78. // StopPodSandbox stops any running process that is part of the sandbox and
  79. // reclaims network resources (e.g., IP addresses) allocated to the sandbox.
  80. // If there are any running containers in the sandbox, they must be forcibly
  81. // terminated.
  82. func (f *RemoteRuntime) StopPodSandbox(ctx context.Context, req *kubeapi.StopPodSandboxRequest) (*kubeapi.StopPodSandboxResponse, error) {
  83. err := f.RuntimeService.StopPodSandbox(req.PodSandboxId)
  84. if err != nil {
  85. return nil, err
  86. }
  87. return &kubeapi.StopPodSandboxResponse{}, nil
  88. }
  89. // RemovePodSandbox removes the sandbox. If there are any running containers
  90. // in the sandbox, they must be forcibly terminated and removed.
  91. // This call is idempotent, and must not return an error if the sandbox has
  92. // already been removed.
  93. func (f *RemoteRuntime) RemovePodSandbox(ctx context.Context, req *kubeapi.RemovePodSandboxRequest) (*kubeapi.RemovePodSandboxResponse, error) {
  94. err := f.RuntimeService.StopPodSandbox(req.PodSandboxId)
  95. if err != nil {
  96. return nil, err
  97. }
  98. return &kubeapi.RemovePodSandboxResponse{}, nil
  99. }
  100. // PodSandboxStatus returns the status of the PodSandbox. If the PodSandbox is not
  101. // present, returns an error.
  102. func (f *RemoteRuntime) PodSandboxStatus(ctx context.Context, req *kubeapi.PodSandboxStatusRequest) (*kubeapi.PodSandboxStatusResponse, error) {
  103. podStatus, err := f.RuntimeService.PodSandboxStatus(req.PodSandboxId)
  104. if err != nil {
  105. return nil, err
  106. }
  107. return &kubeapi.PodSandboxStatusResponse{Status: podStatus}, nil
  108. }
  109. // ListPodSandbox returns a list of PodSandboxes.
  110. func (f *RemoteRuntime) ListPodSandbox(ctx context.Context, req *kubeapi.ListPodSandboxRequest) (*kubeapi.ListPodSandboxResponse, error) {
  111. items, err := f.RuntimeService.ListPodSandbox(req.Filter)
  112. if err != nil {
  113. return nil, err
  114. }
  115. return &kubeapi.ListPodSandboxResponse{Items: items}, nil
  116. }
  117. // CreateContainer creates a new container in specified PodSandbox
  118. func (f *RemoteRuntime) CreateContainer(ctx context.Context, req *kubeapi.CreateContainerRequest) (*kubeapi.CreateContainerResponse, error) {
  119. containerID, err := f.RuntimeService.CreateContainer(req.PodSandboxId, req.Config, req.SandboxConfig)
  120. if err != nil {
  121. return nil, err
  122. }
  123. return &kubeapi.CreateContainerResponse{ContainerId: containerID}, nil
  124. }
  125. // StartContainer starts the container.
  126. func (f *RemoteRuntime) StartContainer(ctx context.Context, req *kubeapi.StartContainerRequest) (*kubeapi.StartContainerResponse, error) {
  127. err := f.RuntimeService.StartContainer(req.ContainerId)
  128. if err != nil {
  129. return nil, err
  130. }
  131. return &kubeapi.StartContainerResponse{}, nil
  132. }
  133. // StopContainer stops a running container with a grace period (i.e., timeout).
  134. // This call is idempotent, and must not return an error if the container has
  135. // already been stopped.
  136. func (f *RemoteRuntime) StopContainer(ctx context.Context, req *kubeapi.StopContainerRequest) (*kubeapi.StopContainerResponse, error) {
  137. err := f.RuntimeService.StopContainer(req.ContainerId, req.Timeout)
  138. if err != nil {
  139. return nil, err
  140. }
  141. return &kubeapi.StopContainerResponse{}, nil
  142. }
  143. // RemoveContainer removes the container. If the container is running, the
  144. // container must be forcibly removed.
  145. // This call is idempotent, and must not return an error if the container has
  146. // already been removed.
  147. func (f *RemoteRuntime) RemoveContainer(ctx context.Context, req *kubeapi.RemoveContainerRequest) (*kubeapi.RemoveContainerResponse, error) {
  148. err := f.RuntimeService.RemoveContainer(req.ContainerId)
  149. if err != nil {
  150. return nil, err
  151. }
  152. return &kubeapi.RemoveContainerResponse{}, nil
  153. }
  154. // ListContainers lists all containers by filters.
  155. func (f *RemoteRuntime) ListContainers(ctx context.Context, req *kubeapi.ListContainersRequest) (*kubeapi.ListContainersResponse, error) {
  156. items, err := f.RuntimeService.ListContainers(req.Filter)
  157. if err != nil {
  158. return nil, err
  159. }
  160. return &kubeapi.ListContainersResponse{Containers: items}, nil
  161. }
  162. // ContainerStatus returns status of the container. If the container is not
  163. // present, returns an error.
  164. func (f *RemoteRuntime) ContainerStatus(ctx context.Context, req *kubeapi.ContainerStatusRequest) (*kubeapi.ContainerStatusResponse, error) {
  165. status, err := f.RuntimeService.ContainerStatus(req.ContainerId)
  166. if err != nil {
  167. return nil, err
  168. }
  169. return &kubeapi.ContainerStatusResponse{Status: status}, nil
  170. }
  171. // ExecSync runs a command in a container synchronously.
  172. func (f *RemoteRuntime) ExecSync(ctx context.Context, req *kubeapi.ExecSyncRequest) (*kubeapi.ExecSyncResponse, error) {
  173. var exitCode int32
  174. stdout, stderr, err := f.RuntimeService.ExecSync(req.ContainerId, req.Cmd, time.Duration(req.Timeout)*time.Second)
  175. if err != nil {
  176. exitError, ok := err.(utilexec.ExitError)
  177. if !ok {
  178. return nil, err
  179. }
  180. exitCode = int32(exitError.ExitStatus())
  181. }
  182. return &kubeapi.ExecSyncResponse{
  183. Stdout: stdout,
  184. Stderr: stderr,
  185. ExitCode: exitCode,
  186. }, nil
  187. }
  188. // Exec prepares a streaming endpoint to execute a command in the container.
  189. func (f *RemoteRuntime) Exec(ctx context.Context, req *kubeapi.ExecRequest) (*kubeapi.ExecResponse, error) {
  190. return f.RuntimeService.Exec(req)
  191. }
  192. // Attach prepares a streaming endpoint to attach to a running container.
  193. func (f *RemoteRuntime) Attach(ctx context.Context, req *kubeapi.AttachRequest) (*kubeapi.AttachResponse, error) {
  194. return f.RuntimeService.Attach(req)
  195. }
  196. // PortForward prepares a streaming endpoint to forward ports from a PodSandbox.
  197. func (f *RemoteRuntime) PortForward(ctx context.Context, req *kubeapi.PortForwardRequest) (*kubeapi.PortForwardResponse, error) {
  198. return f.RuntimeService.PortForward(req)
  199. }
  200. // ContainerStats returns stats of the container. If the container does not
  201. // exist, the call returns an error.
  202. func (f *RemoteRuntime) ContainerStats(ctx context.Context, req *kubeapi.ContainerStatsRequest) (*kubeapi.ContainerStatsResponse, error) {
  203. stats, err := f.RuntimeService.ContainerStats(req.ContainerId)
  204. if err != nil {
  205. return nil, err
  206. }
  207. return &kubeapi.ContainerStatsResponse{Stats: stats}, nil
  208. }
  209. // ListContainerStats returns stats of all running containers.
  210. func (f *RemoteRuntime) ListContainerStats(ctx context.Context, req *kubeapi.ListContainerStatsRequest) (*kubeapi.ListContainerStatsResponse, error) {
  211. stats, err := f.RuntimeService.ListContainerStats(req.Filter)
  212. if err != nil {
  213. return nil, err
  214. }
  215. return &kubeapi.ListContainerStatsResponse{Stats: stats}, nil
  216. }
  217. // UpdateRuntimeConfig updates the runtime configuration based on the given request.
  218. func (f *RemoteRuntime) UpdateRuntimeConfig(ctx context.Context, req *kubeapi.UpdateRuntimeConfigRequest) (*kubeapi.UpdateRuntimeConfigResponse, error) {
  219. err := f.RuntimeService.UpdateRuntimeConfig(req.RuntimeConfig)
  220. if err != nil {
  221. return nil, err
  222. }
  223. return &kubeapi.UpdateRuntimeConfigResponse{}, nil
  224. }
  225. // Status returns the status of the runtime.
  226. func (f *RemoteRuntime) Status(ctx context.Context, req *kubeapi.StatusRequest) (*kubeapi.StatusResponse, error) {
  227. status, err := f.RuntimeService.Status()
  228. if err != nil {
  229. return nil, err
  230. }
  231. return &kubeapi.StatusResponse{Status: status}, nil
  232. }
  233. // UpdateContainerResources updates ContainerConfig of the container.
  234. func (f *RemoteRuntime) UpdateContainerResources(ctx context.Context, req *kubeapi.UpdateContainerResourcesRequest) (*kubeapi.UpdateContainerResourcesResponse, error) {
  235. err := f.RuntimeService.UpdateContainerResources(req.ContainerId, req.Linux)
  236. if err != nil {
  237. return nil, err
  238. }
  239. return &kubeapi.UpdateContainerResourcesResponse{}, nil
  240. }
  241. // ReopenContainerLog reopens the container log file.
  242. func (f *RemoteRuntime) ReopenContainerLog(ctx context.Context, req *kubeapi.ReopenContainerLogRequest) (*kubeapi.ReopenContainerLogResponse, error) {
  243. err := f.RuntimeService.ReopenContainerLog(req.ContainerId)
  244. if err != nil {
  245. return nil, err
  246. }
  247. return &kubeapi.ReopenContainerLogResponse{}, nil
  248. }