diff --git a/pkg/kubelet/dockershim/docker_container.go b/pkg/kubelet/dockershim/docker_container.go index 33a05556dfd..522649845c2 100644 --- a/pkg/kubelet/dockershim/docker_container.go +++ b/pkg/kubelet/dockershim/docker_container.go @@ -27,13 +27,15 @@ import ( dockerfilters "github.com/docker/docker/api/types/filters" dockerstrslice "github.com/docker/docker/api/types/strslice" "github.com/golang/glog" + "golang.org/x/net/context" runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" "k8s.io/kubernetes/pkg/kubelet/dockershim/libdocker" ) // ListContainers lists all containers matching the filter. -func (ds *dockerService) ListContainers(filter *runtimeapi.ContainerFilter) ([]*runtimeapi.Container, error) { +func (ds *dockerService) ListContainers(_ context.Context, r *runtimeapi.ListContainersRequest) (*runtimeapi.ListContainersResponse, error) { + filter := r.GetFilter() opts := dockertypes.ContainerListOptions{All: true} opts.Filters = dockerfilters.NewArgs() @@ -75,19 +77,24 @@ func (ds *dockerService) ListContainers(filter *runtimeapi.ContainerFilter) ([]* result = append(result, converted) } - return result, nil + + return &runtimeapi.ListContainersResponse{Containers: result}, nil } // CreateContainer creates a new container in the given PodSandbox // Docker cannot store the log to an arbitrary location (yet), so we create an // symlink at LogPath, linking to the actual path of the log. // TODO: check if the default values returned by the runtime API are ok. -func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeapi.ContainerConfig, sandboxConfig *runtimeapi.PodSandboxConfig) (string, error) { +func (ds *dockerService) CreateContainer(_ context.Context, r *runtimeapi.CreateContainerRequest) (*runtimeapi.CreateContainerResponse, error) { + podSandboxID := r.PodSandboxId + config := r.GetConfig() + sandboxConfig := r.GetSandboxConfig() + if config == nil { - return "", fmt.Errorf("container config is nil") + return nil, fmt.Errorf("container config is nil") } if sandboxConfig == nil { - return "", fmt.Errorf("sandbox config is nil for container %q", config.Metadata.Name) + return nil, fmt.Errorf("sandbox config is nil for container %q", config.Metadata.Name) } labels := makeLabels(config.GetLabels(), config.GetAnnotations()) @@ -100,7 +107,7 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeapi apiVersion, err := ds.getDockerAPIVersion() if err != nil { - return "", fmt.Errorf("unable to get the docker API version: %v", err) + return nil, fmt.Errorf("unable to get the docker API version: %v", err) } image := "" @@ -147,7 +154,7 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeapi securityOpts, err := ds.getSecurityOpts(config.GetLinux().GetSecurityContext().GetSeccompProfilePath(), securityOptSeparator) if err != nil { - return "", fmt.Errorf("failed to generate security options for container %q: %v", config.Metadata.Name, err) + return nil, fmt.Errorf("failed to generate security options for container %q: %v", config.Metadata.Name, err) } hc.SecurityOpt = append(hc.SecurityOpt, securityOpts...) @@ -158,9 +165,9 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeapi } if createResp != nil { - return createResp.ID, err + return &runtimeapi.CreateContainerResponse{ContainerId: createResp.ID}, nil } - return "", err + return nil, err } // getContainerLogPath returns the container log path specified by kubelet and the real @@ -229,45 +236,49 @@ func (ds *dockerService) removeContainerLogSymlink(containerID string) error { } // StartContainer starts the container. -func (ds *dockerService) StartContainer(containerID string) error { - err := ds.client.StartContainer(containerID) +func (ds *dockerService) StartContainer(_ context.Context, r *runtimeapi.StartContainerRequest) (*runtimeapi.StartContainerResponse, error) { + err := ds.client.StartContainer(r.ContainerId) // Create container log symlink for all containers (including failed ones). - if linkError := ds.createContainerLogSymlink(containerID); linkError != nil { + if linkError := ds.createContainerLogSymlink(r.ContainerId); linkError != nil { // Do not stop the container if we failed to create symlink because: // 1. This is not a critical failure. // 2. We don't have enough information to properly stop container here. // Kubelet will surface this error to user via an event. - return linkError + return nil, linkError } if err != nil { err = transformStartContainerError(err) - return fmt.Errorf("failed to start container %q: %v", containerID, err) + return nil, fmt.Errorf("failed to start container %q: %v", r.ContainerId, err) } - return nil + return &runtimeapi.StartContainerResponse{}, nil } // StopContainer stops a running container with a grace period (i.e., timeout). -func (ds *dockerService) StopContainer(containerID string, timeout int64) error { - return ds.client.StopContainer(containerID, time.Duration(timeout)*time.Second) +func (ds *dockerService) StopContainer(_ context.Context, r *runtimeapi.StopContainerRequest) (*runtimeapi.StopContainerResponse, error) { + err := ds.client.StopContainer(r.ContainerId, time.Duration(r.Timeout)*time.Second) + if err != nil { + return nil, err + } + return &runtimeapi.StopContainerResponse{}, nil } // RemoveContainer removes the container. -func (ds *dockerService) RemoveContainer(containerID string) error { +func (ds *dockerService) RemoveContainer(_ context.Context, r *runtimeapi.RemoveContainerRequest) (*runtimeapi.RemoveContainerResponse, error) { // Ideally, log lifecycle should be independent of container lifecycle. // However, docker will remove container log after container is removed, // we can't prevent that now, so we also clean up the symlink here. - err := ds.removeContainerLogSymlink(containerID) + err := ds.removeContainerLogSymlink(r.ContainerId) if err != nil { - return err + return nil, err } - err = ds.client.RemoveContainer(containerID, dockertypes.ContainerRemoveOptions{RemoveVolumes: true, Force: true}) + err = ds.client.RemoveContainer(r.ContainerId, dockertypes.ContainerRemoveOptions{RemoveVolumes: true, Force: true}) if err != nil { - return fmt.Errorf("failed to remove container %q: %v", containerID, err) + return nil, fmt.Errorf("failed to remove container %q: %v", r.ContainerId, err) } - return nil + return &runtimeapi.RemoveContainerResponse{}, nil } func getContainerTimestamps(r *dockertypes.ContainerJSON) (time.Time, time.Time, time.Time, error) { @@ -290,7 +301,8 @@ func getContainerTimestamps(r *dockertypes.ContainerJSON) (time.Time, time.Time, } // ContainerStatus inspects the docker container and returns the status. -func (ds *dockerService) ContainerStatus(containerID string) (*runtimeapi.ContainerStatus, error) { +func (ds *dockerService) ContainerStatus(_ context.Context, req *runtimeapi.ContainerStatusRequest) (*runtimeapi.ContainerStatusResponse, error) { + containerID := req.ContainerId r, err := ds.client.InspectContainer(containerID) if err != nil { return nil, err @@ -373,7 +385,7 @@ func (ds *dockerService) ContainerStatus(containerID string) (*runtimeapi.Contai if len(ir.RepoTags) > 0 { imageName = ir.RepoTags[0] } - return &runtimeapi.ContainerStatus{ + status := &runtimeapi.ContainerStatus{ Id: r.ID, Metadata: metadata, Image: &runtimeapi.ImageSpec{Image: imageName}, @@ -389,10 +401,12 @@ func (ds *dockerService) ContainerStatus(containerID string) (*runtimeapi.Contai Labels: labels, Annotations: annotations, LogPath: r.Config.Labels[containerLogPathLabelKey], - }, nil + } + return &runtimeapi.ContainerStatusResponse{Status: status}, nil } -func (ds *dockerService) UpdateContainerResources(containerID string, resources *runtimeapi.LinuxContainerResources) error { +func (ds *dockerService) UpdateContainerResources(_ context.Context, r *runtimeapi.UpdateContainerResourcesRequest) (*runtimeapi.UpdateContainerResourcesResponse, error) { + resources := r.Linux updateConfig := dockercontainer.UpdateConfig{ Resources: dockercontainer.Resources{ CPUPeriod: resources.CpuPeriod, @@ -404,9 +418,9 @@ func (ds *dockerService) UpdateContainerResources(containerID string, resources }, } - err := ds.client.UpdateContainerResources(containerID, updateConfig) + err := ds.client.UpdateContainerResources(r.ContainerId, updateConfig) if err != nil { - return fmt.Errorf("failed to update container %q: %v", containerID, err) + return nil, fmt.Errorf("failed to update container %q: %v", r.ContainerId, err) } - return nil + return &runtimeapi.UpdateContainerResourcesResponse{}, nil } diff --git a/pkg/kubelet/dockershim/docker_image.go b/pkg/kubelet/dockershim/docker_image.go index 1b39522f862..622945a8ec8 100644 --- a/pkg/kubelet/dockershim/docker_image.go +++ b/pkg/kubelet/dockershim/docker_image.go @@ -23,6 +23,7 @@ import ( dockertypes "github.com/docker/docker/api/types" dockerfilters "github.com/docker/docker/api/types/filters" "github.com/docker/docker/pkg/jsonmessage" + "golang.org/x/net/context" runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" "k8s.io/kubernetes/pkg/kubelet/dockershim/libdocker" @@ -31,7 +32,8 @@ import ( // This file implements methods in ImageManagerService. // ListImages lists existing images. -func (ds *dockerService) ListImages(filter *runtimeapi.ImageFilter) ([]*runtimeapi.Image, error) { +func (ds *dockerService) ListImages(_ context.Context, r *runtimeapi.ListImagesRequest) (*runtimeapi.ListImagesResponse, error) { + filter := r.GetFilter() opts := dockertypes.ImageListOptions{} if filter != nil { if filter.GetImage().GetImage() != "" { @@ -54,24 +56,35 @@ func (ds *dockerService) ListImages(filter *runtimeapi.ImageFilter) ([]*runtimea } result = append(result, apiImage) } - return result, nil + return &runtimeapi.ListImagesResponse{Images: result}, nil } // ImageStatus returns the status of the image, returns nil if the image doesn't present. -func (ds *dockerService) ImageStatus(image *runtimeapi.ImageSpec) (*runtimeapi.Image, error) { +func (ds *dockerService) ImageStatus(_ context.Context, r *runtimeapi.ImageStatusRequest) (*runtimeapi.ImageStatusResponse, error) { + image := r.GetImage() + imageInspect, err := ds.client.InspectImageByRef(image.Image) if err != nil { if libdocker.IsImageNotFoundError(err) { - return nil, nil + return &runtimeapi.ImageStatusResponse{}, nil } return nil, err } - return imageInspectToRuntimeAPIImage(imageInspect) + + imageStatus, err := imageInspectToRuntimeAPIImage(imageInspect) + if err != nil { + return nil, err + } + + return &runtimeapi.ImageStatusResponse{Image: imageStatus}, nil } // PullImage pulls an image with authentication config. -func (ds *dockerService) PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig) (string, error) { +func (ds *dockerService) PullImage(_ context.Context, r *runtimeapi.PullImageRequest) (*runtimeapi.PullImageResponse, error) { + image := r.GetImage() + auth := r.GetAuth() authConfig := dockertypes.AuthConfig{} + if auth != nil { authConfig.Username = auth.Username authConfig.Password = auth.Password @@ -84,14 +97,20 @@ func (ds *dockerService) PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi dockertypes.ImagePullOptions{}, ) if err != nil { - return "", filterHTTPError(err, image.Image) + return nil, filterHTTPError(err, image.Image) } - return getImageRef(ds.client, image.Image) + imageRef, err := getImageRef(ds.client, image.Image) + if err != nil { + return nil, err + } + + return &runtimeapi.PullImageResponse{ImageRef: imageRef}, nil } // RemoveImage removes the image. -func (ds *dockerService) RemoveImage(image *runtimeapi.ImageSpec) error { +func (ds *dockerService) RemoveImage(_ context.Context, r *runtimeapi.RemoveImageRequest) (*runtimeapi.RemoveImageResponse, error) { + image := r.GetImage() // If the image has multiple tags, we need to remove all the tags // TODO: We assume image.Image is image ID here, which is true in the current implementation // of kubelet, but we should still clarify this in CRI. @@ -99,22 +118,22 @@ func (ds *dockerService) RemoveImage(image *runtimeapi.ImageSpec) error { if err == nil && imageInspect != nil && len(imageInspect.RepoTags) > 1 { for _, tag := range imageInspect.RepoTags { if _, err := ds.client.RemoveImage(tag, dockertypes.ImageRemoveOptions{PruneChildren: true}); err != nil && !libdocker.IsImageNotFoundError(err) { - return err + return nil, err } } - return nil + return &runtimeapi.RemoveImageResponse{}, nil } // dockerclient.InspectImageByID doesn't work with digest and repoTags, // it is safe to continue removing it since there is another check below. if err != nil && !libdocker.IsImageNotFoundError(err) { - return err + return nil, err } _, err = ds.client.RemoveImage(image.Image, dockertypes.ImageRemoveOptions{PruneChildren: true}) if err != nil && !libdocker.IsImageNotFoundError(err) { - return err + return nil, err } - return nil + return &runtimeapi.RemoveImageResponse{}, nil } // getImageRef returns the image digest if exists, or else returns the image ID. diff --git a/pkg/kubelet/dockershim/docker_image_linux.go b/pkg/kubelet/dockershim/docker_image_linux.go index 1af785972cc..3ecc6599e92 100644 --- a/pkg/kubelet/dockershim/docker_image_linux.go +++ b/pkg/kubelet/dockershim/docker_image_linux.go @@ -21,10 +21,12 @@ package dockershim import ( "fmt" + "golang.org/x/net/context" + runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" ) // ImageFsInfo returns information of the filesystem that is used to store images. -func (ds *dockerService) ImageFsInfo() ([]*runtimeapi.FilesystemUsage, error) { +func (ds *dockerService) ImageFsInfo(_ context.Context, r *runtimeapi.ImageFsInfoRequest) (*runtimeapi.ImageFsInfoResponse, error) { return nil, fmt.Errorf("not implemented") } diff --git a/pkg/kubelet/dockershim/docker_image_unsupported.go b/pkg/kubelet/dockershim/docker_image_unsupported.go index 17519e0385f..b4fb70b3a4c 100644 --- a/pkg/kubelet/dockershim/docker_image_unsupported.go +++ b/pkg/kubelet/dockershim/docker_image_unsupported.go @@ -21,10 +21,12 @@ package dockershim import ( "fmt" + "golang.org/x/net/context" + runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" ) // ImageFsInfo returns information of the filesystem that is used to store images. -func (ds *dockerService) ImageFsInfo() ([]*runtimeapi.FilesystemUsage, error) { +func (ds *dockerService) ImageFsInfo(_ context.Context, r *runtimeapi.ImageFsInfoRequest) (*runtimeapi.ImageFsInfoResponse, error) { return nil, fmt.Errorf("not implemented") } diff --git a/pkg/kubelet/dockershim/docker_image_windows.go b/pkg/kubelet/dockershim/docker_image_windows.go index b147659f2b6..385b0545878 100644 --- a/pkg/kubelet/dockershim/docker_image_windows.go +++ b/pkg/kubelet/dockershim/docker_image_windows.go @@ -21,11 +21,13 @@ package dockershim import ( "time" + "golang.org/x/net/context" + runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" ) // ImageFsInfo returns information of the filesystem that is used to store images. -func (ds *dockerService) ImageFsInfo() ([]*runtimeapi.FilesystemUsage, error) { +func (ds *dockerService) ImageFsInfo(_ context.Context, _ *runtimeapi.ImageFsInfoRequest) (*runtimeapi.ImageFsInfoResponse, error) { // For Windows Stats to work correctly, a file system must be provided. For now, provide a fake filesystem. filesystems := []*runtimeapi.FilesystemUsage{ { @@ -35,5 +37,5 @@ func (ds *dockerService) ImageFsInfo() ([]*runtimeapi.FilesystemUsage, error) { }, } - return filesystems, nil + return &runtimeapi.ImageFsInfoResponse{ImageFilesystems: filesystems}, nil } diff --git a/pkg/kubelet/dockershim/docker_sandbox.go b/pkg/kubelet/dockershim/docker_sandbox.go index 88057311ac9..24d7879eeea 100644 --- a/pkg/kubelet/dockershim/docker_sandbox.go +++ b/pkg/kubelet/dockershim/docker_sandbox.go @@ -26,6 +26,7 @@ import ( dockercontainer "github.com/docker/docker/api/types/container" dockerfilters "github.com/docker/docker/api/types/filters" "github.com/golang/glog" + "golang.org/x/net/context" utilerrors "k8s.io/apimachinery/pkg/util/errors" runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" @@ -75,7 +76,9 @@ func (ds *dockerService) clearNetworkReady(podSandboxID string) { // For docker, PodSandbox is implemented by a container holding the network // namespace for the pod. // Note: docker doesn't use LogDirectory (yet). -func (ds *dockerService) RunPodSandbox(config *runtimeapi.PodSandboxConfig) (id string, err error) { +func (ds *dockerService) RunPodSandbox(ctx context.Context, r *runtimeapi.RunPodSandboxRequest) (*runtimeapi.RunPodSandboxResponse, error) { + config := r.GetConfig() + // Step 1: Pull the image for the sandbox. image := defaultSandboxImage podSandboxImage := ds.podSandboxImage @@ -87,13 +90,13 @@ func (ds *dockerService) RunPodSandbox(config *runtimeapi.PodSandboxConfig) (id // see: http://kubernetes.io/docs/user-guide/images/#configuring-nodes-to-authenticate-to-a-private-repository // Only pull sandbox image when it's not present - v1.PullIfNotPresent. if err := ensureSandboxImageExists(ds.client, image); err != nil { - return "", err + return nil, err } // Step 2: Create the sandbox container. createConfig, err := ds.makeSandboxDockerConfig(config, image) if err != nil { - return "", fmt.Errorf("failed to make sandbox docker config for pod %q: %v", config.Metadata.Name, err) + return nil, fmt.Errorf("failed to make sandbox docker config for pod %q: %v", config.Metadata.Name, err) } createResp, err := ds.client.CreateContainer(*createConfig) if err != nil { @@ -101,8 +104,9 @@ func (ds *dockerService) RunPodSandbox(config *runtimeapi.PodSandboxConfig) (id } if err != nil || createResp == nil { - return "", fmt.Errorf("failed to create a sandbox for pod %q: %v", config.Metadata.Name, err) + return nil, fmt.Errorf("failed to create a sandbox for pod %q: %v", config.Metadata.Name, err) } + resp := &runtimeapi.RunPodSandboxResponse{PodSandboxId: createResp.ID} ds.setNetworkReady(createResp.ID, false) defer func(e *error) { @@ -115,7 +119,7 @@ func (ds *dockerService) RunPodSandbox(config *runtimeapi.PodSandboxConfig) (id // Step 3: Create Sandbox Checkpoint. if err = ds.checkpointHandler.CreateCheckpoint(createResp.ID, constructPodSandboxCheckpoint(config)); err != nil { - return createResp.ID, err + return nil, err } // Step 4: Start the sandbox container. @@ -123,7 +127,7 @@ func (ds *dockerService) RunPodSandbox(config *runtimeapi.PodSandboxConfig) (id // startContainer failed. err = ds.client.StartContainer(createResp.ID) if err != nil { - return createResp.ID, fmt.Errorf("failed to start sandbox container for pod %q: %v", config.Metadata.Name, err) + return nil, fmt.Errorf("failed to start sandbox container for pod %q: %v", config.Metadata.Name, err) } // Rewrite resolv.conf file generated by docker. @@ -135,17 +139,17 @@ func (ds *dockerService) RunPodSandbox(config *runtimeapi.PodSandboxConfig) (id if dnsConfig := config.GetDnsConfig(); dnsConfig != nil { containerInfo, err := ds.client.InspectContainer(createResp.ID) if err != nil { - return createResp.ID, fmt.Errorf("failed to inspect sandbox container for pod %q: %v", config.Metadata.Name, err) + return nil, fmt.Errorf("failed to inspect sandbox container for pod %q: %v", config.Metadata.Name, err) } if err := rewriteResolvFile(containerInfo.ResolvConfPath, dnsConfig.Servers, dnsConfig.Searches, dnsConfig.Options); err != nil { - return createResp.ID, fmt.Errorf("rewrite resolv.conf failed for pod %q: %v", config.Metadata.Name, err) + return nil, fmt.Errorf("rewrite resolv.conf failed for pod %q: %v", config.Metadata.Name, err) } } // Do not invoke network plugins if in hostNetwork mode. if nsOptions := config.GetLinux().GetSecurityContext().GetNamespaceOptions(); nsOptions != nil && nsOptions.HostNetwork { - return createResp.ID, nil + return resp, nil } // Step 5: Setup networking for the sandbox. @@ -163,7 +167,7 @@ func (ds *dockerService) RunPodSandbox(config *runtimeapi.PodSandboxConfig) (id glog.Warningf("Failed to stop sandbox container %q for pod %q: %v", createResp.ID, config.Metadata.Name, err) } } - return createResp.ID, err + return resp, err } // StopPodSandbox stops the sandbox. If there are any running containers in the @@ -171,13 +175,17 @@ func (ds *dockerService) RunPodSandbox(config *runtimeapi.PodSandboxConfig) (id // TODO: This function blocks sandbox teardown on networking teardown. Is it // better to cut our losses assuming an out of band GC routine will cleanup // after us? -func (ds *dockerService) StopPodSandbox(podSandboxID string) error { +func (ds *dockerService) StopPodSandbox(ctx context.Context, r *runtimeapi.StopPodSandboxRequest) (*runtimeapi.StopPodSandboxResponse, error) { var namespace, name string var hostNetwork bool var checkpointErr, statusErr error + podSandboxID := r.PodSandboxId + resp := &runtimeapi.StopPodSandboxResponse{} + // Try to retrieve sandbox information from docker daemon or sandbox checkpoint - status, statusErr := ds.PodSandboxStatus(podSandboxID) + statusResp, statusErr := ds.PodSandboxStatus(ctx, &runtimeapi.PodSandboxStatusRequest{PodSandboxId: podSandboxID}) + status := statusResp.GetStatus() if statusErr == nil { nsOpts := status.GetLinux().GetNamespaces().GetOptions() hostNetwork = nsOpts != nil && nsOpts.HostNetwork @@ -196,7 +204,7 @@ func (ds *dockerService) StopPodSandbox(podSandboxID string) error { glog.Warningf("Both sandbox container and checkpoint for id %q could not be found. "+ "Proceed without further sandbox information.", podSandboxID) } else { - return utilerrors.NewAggregate([]error{ + return nil, utilerrors.NewAggregate([]error{ fmt.Errorf("failed to get checkpoint for sandbox %q: %v", podSandboxID, checkpointErr), fmt.Errorf("failed to get sandbox status: %v", statusErr)}) } @@ -237,14 +245,21 @@ func (ds *dockerService) StopPodSandbox(podSandboxID string) error { ds.checkpointHandler.RemoveCheckpoint(podSandboxID) } } - return utilerrors.NewAggregate(errList) + + if len(errList) == 0 { + return resp, nil + } + // TODO: Stop all running containers in the sandbox. + return nil, utilerrors.NewAggregate(errList) } // RemovePodSandbox removes the sandbox. If there are running containers in the // sandbox, they should be forcibly removed. -func (ds *dockerService) RemovePodSandbox(podSandboxID string) error { +func (ds *dockerService) RemovePodSandbox(ctx context.Context, r *runtimeapi.RemovePodSandboxRequest) (*runtimeapi.RemovePodSandboxResponse, error) { + podSandboxID := r.PodSandboxId var errs []error + opts := dockertypes.ContainerListOptions{All: true} opts.Filters = dockerfilters.NewArgs() @@ -258,7 +273,7 @@ func (ds *dockerService) RemovePodSandbox(podSandboxID string) error { // Remove all containers in the sandbox. for i := range containers { - if err := ds.RemoveContainer(containers[i].ID); err != nil && !libdocker.IsContainerNotFoundError(err) { + if _, err := ds.RemoveContainer(ctx, &runtimeapi.RemoveContainerRequest{ContainerId: containers[i].ID}); err != nil && !libdocker.IsContainerNotFoundError(err) { errs = append(errs, err) } } @@ -277,7 +292,10 @@ func (ds *dockerService) RemovePodSandbox(podSandboxID string) error { if err := ds.checkpointHandler.RemoveCheckpoint(podSandboxID); err != nil { errs = append(errs, err) } - return utilerrors.NewAggregate(errs) + if len(errs) == 0 { + return &runtimeapi.RemovePodSandboxResponse{}, nil + } + return nil, utilerrors.NewAggregate(errs) } // getIPFromPlugin interrogates the network plugin for an IP. @@ -342,7 +360,9 @@ func (ds *dockerService) getIP(podSandboxID string, sandbox *dockertypes.Contain } // PodSandboxStatus returns the status of the PodSandbox. -func (ds *dockerService) PodSandboxStatus(podSandboxID string) (*runtimeapi.PodSandboxStatus, error) { +func (ds *dockerService) PodSandboxStatus(ctx context.Context, req *runtimeapi.PodSandboxStatusRequest) (*runtimeapi.PodSandboxStatusResponse, error) { + podSandboxID := req.PodSandboxId + // Inspect the container. r, err := ds.client.InspectContainer(podSandboxID) if err != nil { @@ -375,7 +395,7 @@ func (ds *dockerService) PodSandboxStatus(podSandboxID string) (*runtimeapi.PodS return nil, err } labels, annotations := extractLabels(r.Config.Labels) - return &runtimeapi.PodSandboxStatus{ + status := &runtimeapi.PodSandboxStatus{ Id: r.ID, State: state, CreatedAt: ct, @@ -394,11 +414,14 @@ func (ds *dockerService) PodSandboxStatus(podSandboxID string) (*runtimeapi.PodS }, }, }, - }, nil + } + return &runtimeapi.PodSandboxStatusResponse{Status: status}, nil } // ListPodSandbox returns a list of Sandbox. -func (ds *dockerService) ListPodSandbox(filter *runtimeapi.PodSandboxFilter) ([]*runtimeapi.PodSandbox, error) { +func (ds *dockerService) ListPodSandbox(_ context.Context, r *runtimeapi.ListPodSandboxRequest) (*runtimeapi.ListPodSandboxResponse, error) { + filter := r.GetFilter() + // By default, list all containers whether they are running or not. opts := dockertypes.ContainerListOptions{All: true} filterOutReadySandboxes := false @@ -482,7 +505,7 @@ func (ds *dockerService) ListPodSandbox(filter *runtimeapi.PodSandboxFilter) ([] result = append(result, checkpointToRuntimeAPISandbox(id, checkpoint)) } - return result, nil + return &runtimeapi.ListPodSandboxResponse{Items: result}, nil } // applySandboxLinuxOptions applies LinuxPodSandboxConfig to dockercontainer.HostConfig and dockercontainer.ContainerCreateConfig. diff --git a/pkg/kubelet/dockershim/docker_service.go b/pkg/kubelet/dockershim/docker_service.go index 6fa1106f4fd..31662ae3c72 100644 --- a/pkg/kubelet/dockershim/docker_service.go +++ b/pkg/kubelet/dockershim/docker_service.go @@ -28,11 +28,11 @@ import ( "github.com/blang/semver" dockertypes "github.com/docker/docker/api/types" "github.com/golang/glog" + "golang.org/x/net/context" "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kubetypes "k8s.io/apimachinery/pkg/types" - internalapi "k8s.io/kubernetes/pkg/kubelet/apis/cri" runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig" kubecm "k8s.io/kubernetes/pkg/kubelet/cm" @@ -262,11 +262,17 @@ func NewDockerService(config *ClientConfig, podSandboxImage string, streamingCon return ds, nil } +// CRIService is the interface implement CRI remote service server. +type CRIService interface { + runtimeapi.RuntimeServiceServer + runtimeapi.ImageServiceServer +} + // DockerService is an interface that embeds the new RuntimeService and // ImageService interfaces. type DockerService interface { - internalapi.RuntimeService - internalapi.ImageManagerService + CRIService + Start() error // For serving streaming calls. http.Handler @@ -309,8 +315,10 @@ type dockerService struct { disableSharedPID bool } +// TODO: handle context. + // Version returns the runtime name, runtime version and runtime API version -func (ds *dockerService) Version(_ string) (*runtimeapi.VersionResponse, error) { +func (ds *dockerService) Version(_ context.Context, r *runtimeapi.VersionRequest) (*runtimeapi.VersionResponse, error) { v, err := ds.getDockerVersion() if err != nil { return nil, err @@ -336,17 +344,20 @@ func (ds *dockerService) getDockerVersion() (*dockertypes.Version, error) { } // UpdateRuntimeConfig updates the runtime config. Currently only handles podCIDR updates. -func (ds *dockerService) UpdateRuntimeConfig(runtimeConfig *runtimeapi.RuntimeConfig) (err error) { +func (ds *dockerService) UpdateRuntimeConfig(_ context.Context, r *runtimeapi.UpdateRuntimeConfigRequest) (*runtimeapi.UpdateRuntimeConfigResponse, error) { + runtimeConfig := r.GetRuntimeConfig() if runtimeConfig == nil { - return + return &runtimeapi.UpdateRuntimeConfigResponse{}, nil } + glog.Infof("docker cri received runtime config %+v", runtimeConfig) if ds.network != nil && runtimeConfig.NetworkConfig.PodCidr != "" { event := make(map[string]interface{}) event[network.NET_PLUGIN_EVENT_POD_CIDR_CHANGE_DETAIL_CIDR] = runtimeConfig.NetworkConfig.PodCidr ds.network.Event(network.NET_PLUGIN_EVENT_POD_CIDR_CHANGE, event) } - return + + return &runtimeapi.UpdateRuntimeConfigResponse{}, nil } // GetNetNS returns the network namespace of the given containerID. The ID @@ -392,7 +403,7 @@ func (ds *dockerService) Start() error { // Status returns the status of the runtime. // TODO(random-liu): Set network condition accordingly here. -func (ds *dockerService) Status() (*runtimeapi.RuntimeStatus, error) { +func (ds *dockerService) Status(_ context.Context, r *runtimeapi.StatusRequest) (*runtimeapi.StatusResponse, error) { runtimeReady := &runtimeapi.RuntimeCondition{ Type: runtimeapi.RuntimeReady, Status: true, @@ -412,7 +423,8 @@ func (ds *dockerService) Status() (*runtimeapi.RuntimeStatus, error) { networkReady.Reason = "NetworkPluginNotReady" networkReady.Message = fmt.Sprintf("docker: network plugin is not ready: %v", err) } - return &runtimeapi.RuntimeStatus{Conditions: conditions}, nil + status := &runtimeapi.RuntimeStatus{Conditions: conditions} + return &runtimeapi.StatusResponse{Status: status}, nil } func (ds *dockerService) ServeHTTP(w http.ResponseWriter, r *http.Request) { diff --git a/pkg/kubelet/dockershim/docker_stats_linux.go b/pkg/kubelet/dockershim/docker_stats_linux.go index 48622185f1b..e6bc458e217 100644 --- a/pkg/kubelet/dockershim/docker_stats_linux.go +++ b/pkg/kubelet/dockershim/docker_stats_linux.go @@ -20,15 +20,17 @@ package dockershim import ( "fmt" + + "golang.org/x/net/context" runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" ) // ContainerStats returns stats for a container stats request based on container id. -func (ds *dockerService) ContainerStats(string) (*runtimeapi.ContainerStats, error) { +func (ds *dockerService) ContainerStats(_ context.Context, r *runtimeapi.ContainerStatsRequest) (*runtimeapi.ContainerStatsResponse, error) { return nil, fmt.Errorf("not implemented") } // ListContainerStats returns stats for a list container stats request based on a filter. -func (ds *dockerService) ListContainerStats(*runtimeapi.ContainerStatsFilter) ([]*runtimeapi.ContainerStats, error) { +func (ds *dockerService) ListContainerStats(_ context.Context, r *runtimeapi.ListContainerStatsRequest) (*runtimeapi.ListContainerStatsResponse, error) { return nil, fmt.Errorf("not implemented") } diff --git a/pkg/kubelet/dockershim/docker_stats_unsupported.go b/pkg/kubelet/dockershim/docker_stats_unsupported.go index d9f7beef5c7..009362bb51a 100644 --- a/pkg/kubelet/dockershim/docker_stats_unsupported.go +++ b/pkg/kubelet/dockershim/docker_stats_unsupported.go @@ -21,15 +21,17 @@ package dockershim import ( "fmt" + "golang.org/x/net/context" + runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" ) // ContainerStats returns stats for a container stats request based on container id. -func (ds *dockerService) ContainerStats(string) (*runtimeapi.ContainerStats, error) { +func (ds *dockerService) ContainerStats(_ context.Context, r *runtimeapi.ContainerStatsRequest) (*runtimeapi.ContainerStatsResponse, error) { return nil, fmt.Errorf("not implemented") } // ListContainerStats returns stats for a list container stats request based on a filter. -func (ds *dockerService) ListContainerStats(*runtimeapi.ContainerStatsFilter) ([]*runtimeapi.ContainerStats, error) { +func (ds *dockerService) ListContainerStats(_ context.Context, r *runtimeapi.ListContainerStatsRequest) (*runtimeapi.ListContainerStatsResponse, error) { return nil, fmt.Errorf("not implemented") } diff --git a/pkg/kubelet/dockershim/docker_stats_windows.go b/pkg/kubelet/dockershim/docker_stats_windows.go index 6f51239502e..49bd2b66716 100644 --- a/pkg/kubelet/dockershim/docker_stats_windows.go +++ b/pkg/kubelet/dockershim/docker_stats_windows.go @@ -21,20 +21,23 @@ package dockershim import ( "time" + "golang.org/x/net/context" + runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" ) // ContainerStats returns stats for a container stats request based on container id. -func (ds *dockerService) ContainerStats(containerID string) (*runtimeapi.ContainerStats, error) { - containerStats, err := ds.getContainerStats(containerID) +func (ds *dockerService) ContainerStats(_ context.Context, r *runtimeapi.ContainerStatsRequest) (*runtimeapi.ContainerStatsResponse, error) { + stats, err := ds.getContainerStats(r.ContainerId) if err != nil { return nil, err } - return containerStats, nil + return &runtimeapi.ContainerStatsResponse{Stats: stats}, nil } // ListContainerStats returns stats for a list container stats request based on a filter. -func (ds *dockerService) ListContainerStats(containerStatsFilter *runtimeapi.ContainerStatsFilter) ([]*runtimeapi.ContainerStats, error) { +func (ds *dockerService) ListContainerStats(ctx context.Context, r *runtimeapi.ListContainerStatsRequest) (*runtimeapi.ListContainerStatsResponse, error) { + containerStatsFilter := r.GetFilter() filter := &runtimeapi.ContainerFilter{} if containerStatsFilter != nil { @@ -43,13 +46,13 @@ func (ds *dockerService) ListContainerStats(containerStatsFilter *runtimeapi.Con filter.LabelSelector = containerStatsFilter.LabelSelector } - containers, err := ds.ListContainers(filter) + listResp, err := ds.ListContainers(ctx, &runtimeapi.ListContainersRequest{Filter: filter}) if err != nil { return nil, err } var stats []*runtimeapi.ContainerStats - for _, container := range containers { + for _, container := range listResp.Containers { containerStats, err := ds.getContainerStats(container.Id) if err != nil { return nil, err @@ -58,7 +61,7 @@ func (ds *dockerService) ListContainerStats(containerStatsFilter *runtimeapi.Con stats = append(stats, containerStats) } - return stats, nil + return &runtimeapi.ListContainerStatsResponse{Stats: stats}, nil } func (ds *dockerService) getContainerStats(containerID string) (*runtimeapi.ContainerStats, error) { @@ -72,10 +75,11 @@ func (ds *dockerService) getContainerStats(containerID string) (*runtimeapi.Cont return nil, err } - status, err := ds.ContainerStatus(containerID) + statusResp, err := ds.ContainerStatus(context.Background(), &runtimeapi.ContainerStatusRequest{ContainerId: containerID}) if err != nil { return nil, err } + status := statusResp.GetStatus() dockerStats := statsJSON.Stats timestamp := time.Now().UnixNano() diff --git a/pkg/kubelet/dockershim/docker_streaming.go b/pkg/kubelet/dockershim/docker_streaming.go index 4c4b74185ab..c55e0829cd0 100644 --- a/pkg/kubelet/dockershim/docker_streaming.go +++ b/pkg/kubelet/dockershim/docker_streaming.go @@ -26,14 +26,15 @@ import ( "time" dockertypes "github.com/docker/docker/api/types" - "github.com/golang/glog" + "golang.org/x/net/context" "k8s.io/client-go/tools/remotecommand" runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/server/streaming" "k8s.io/kubernetes/pkg/kubelet/util/ioutils" + utilexec "k8s.io/utils/exec" "k8s.io/kubernetes/pkg/kubelet/dockershim/libdocker" ) @@ -76,20 +77,35 @@ func (r *streamingRuntime) PortForward(podSandboxID string, port int32, stream i // ExecSync executes a command in the container, and returns the stdout output. // If command exits with a non-zero exit code, an error is returned. -func (ds *dockerService) ExecSync(containerID string, cmd []string, timeout time.Duration) (stdout []byte, stderr []byte, err error) { +func (ds *dockerService) ExecSync(_ context.Context, req *runtimeapi.ExecSyncRequest) (*runtimeapi.ExecSyncResponse, error) { + timeout := time.Duration(req.Timeout) * time.Second var stdoutBuffer, stderrBuffer bytes.Buffer - err = ds.streamingRuntime.exec(containerID, cmd, + err := ds.streamingRuntime.exec(req.ContainerId, req.Cmd, nil, // in ioutils.WriteCloserWrapper(&stdoutBuffer), ioutils.WriteCloserWrapper(&stderrBuffer), false, // tty nil, // resize timeout) - return stdoutBuffer.Bytes(), stderrBuffer.Bytes(), err + + var exitCode int32 + if err != nil { + exitError, ok := err.(utilexec.ExitError) + if !ok { + return nil, err + } + + exitCode = int32(exitError.ExitStatus()) + } + return &runtimeapi.ExecSyncResponse{ + Stdout: stdoutBuffer.Bytes(), + Stderr: stderrBuffer.Bytes(), + ExitCode: exitCode, + }, nil } // Exec prepares a streaming endpoint to execute a command in the container, and returns the address. -func (ds *dockerService) Exec(req *runtimeapi.ExecRequest) (*runtimeapi.ExecResponse, error) { +func (ds *dockerService) Exec(_ context.Context, req *runtimeapi.ExecRequest) (*runtimeapi.ExecResponse, error) { if ds.streamingServer == nil { return nil, streaming.ErrorStreamingDisabled("exec") } @@ -101,7 +117,7 @@ func (ds *dockerService) Exec(req *runtimeapi.ExecRequest) (*runtimeapi.ExecResp } // Attach prepares a streaming endpoint to attach to a running container, and returns the address. -func (ds *dockerService) Attach(req *runtimeapi.AttachRequest) (*runtimeapi.AttachResponse, error) { +func (ds *dockerService) Attach(_ context.Context, req *runtimeapi.AttachRequest) (*runtimeapi.AttachResponse, error) { if ds.streamingServer == nil { return nil, streaming.ErrorStreamingDisabled("attach") } @@ -113,7 +129,7 @@ func (ds *dockerService) Attach(req *runtimeapi.AttachRequest) (*runtimeapi.Atta } // PortForward prepares a streaming endpoint to forward ports from a PodSandbox, and returns the address. -func (ds *dockerService) PortForward(req *runtimeapi.PortForwardRequest) (*runtimeapi.PortForwardResponse, error) { +func (ds *dockerService) PortForward(_ context.Context, req *runtimeapi.PortForwardRequest) (*runtimeapi.PortForwardResponse, error) { if ds.streamingServer == nil { return nil, streaming.ErrorStreamingDisabled("port forward") } diff --git a/pkg/kubelet/dockershim/remote/docker_server.go b/pkg/kubelet/dockershim/remote/docker_server.go index 21865e3e2c1..bd2af0705d3 100644 --- a/pkg/kubelet/dockershim/remote/docker_server.go +++ b/pkg/kubelet/dockershim/remote/docker_server.go @@ -33,16 +33,16 @@ type DockerServer struct { // endpoint is the endpoint to serve on. endpoint string // service is the docker service which implements runtime and image services. - service DockerService + service dockershim.CRIService // server is the grpc server. server *grpc.Server } // NewDockerServer creates the dockershim grpc server. -func NewDockerServer(endpoint string, s dockershim.DockerService) *DockerServer { +func NewDockerServer(endpoint string, s dockershim.CRIService) *DockerServer { return &DockerServer{ endpoint: endpoint, - service: NewDockerService(s), + service: s, } } diff --git a/pkg/kubelet/dockershim/remote/docker_service.go b/pkg/kubelet/dockershim/remote/docker_service.go deleted file mode 100644 index 2d85f179000..00000000000 --- a/pkg/kubelet/dockershim/remote/docker_service.go +++ /dev/null @@ -1,249 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package remote - -import ( - "time" - - "golang.org/x/net/context" - - internalapi "k8s.io/kubernetes/pkg/kubelet/apis/cri" - runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" - "k8s.io/kubernetes/pkg/kubelet/dockershim" - utilexec "k8s.io/utils/exec" -) - -// DockerService is the interface implement CRI remote service server. -type DockerService interface { - runtimeapi.RuntimeServiceServer - runtimeapi.ImageServiceServer -} - -// dockerService uses dockershim service to implement DockerService. -// Notice that the contexts in the functions are not used now. -// TODO(random-liu): Change the dockershim service to support context, and implement -// internal services and remote services with the dockershim service. -type dockerService struct { - runtimeService internalapi.RuntimeService - imageService internalapi.ImageManagerService -} - -func NewDockerService(s dockershim.DockerService) DockerService { - return &dockerService{runtimeService: s, imageService: s} -} - -func (d *dockerService) Version(ctx context.Context, r *runtimeapi.VersionRequest) (*runtimeapi.VersionResponse, error) { - return d.runtimeService.Version(r.Version) -} - -func (d *dockerService) Status(ctx context.Context, r *runtimeapi.StatusRequest) (*runtimeapi.StatusResponse, error) { - status, err := d.runtimeService.Status() - if err != nil { - return nil, err - } - return &runtimeapi.StatusResponse{Status: status}, nil -} - -func (d *dockerService) RunPodSandbox(ctx context.Context, r *runtimeapi.RunPodSandboxRequest) (*runtimeapi.RunPodSandboxResponse, error) { - podSandboxId, err := d.runtimeService.RunPodSandbox(r.GetConfig()) - if err != nil { - return nil, err - } - return &runtimeapi.RunPodSandboxResponse{PodSandboxId: podSandboxId}, nil -} - -func (d *dockerService) StopPodSandbox(ctx context.Context, r *runtimeapi.StopPodSandboxRequest) (*runtimeapi.StopPodSandboxResponse, error) { - err := d.runtimeService.StopPodSandbox(r.PodSandboxId) - if err != nil { - return nil, err - } - return &runtimeapi.StopPodSandboxResponse{}, nil -} - -func (d *dockerService) RemovePodSandbox(ctx context.Context, r *runtimeapi.RemovePodSandboxRequest) (*runtimeapi.RemovePodSandboxResponse, error) { - err := d.runtimeService.RemovePodSandbox(r.PodSandboxId) - if err != nil { - return nil, err - } - return &runtimeapi.RemovePodSandboxResponse{}, nil -} - -func (d *dockerService) PodSandboxStatus(ctx context.Context, r *runtimeapi.PodSandboxStatusRequest) (*runtimeapi.PodSandboxStatusResponse, error) { - podSandboxStatus, err := d.runtimeService.PodSandboxStatus(r.PodSandboxId) - if err != nil { - return nil, err - } - return &runtimeapi.PodSandboxStatusResponse{Status: podSandboxStatus}, nil -} - -func (d *dockerService) ListPodSandbox(ctx context.Context, r *runtimeapi.ListPodSandboxRequest) (*runtimeapi.ListPodSandboxResponse, error) { - items, err := d.runtimeService.ListPodSandbox(r.GetFilter()) - if err != nil { - return nil, err - } - return &runtimeapi.ListPodSandboxResponse{Items: items}, nil -} - -func (d *dockerService) CreateContainer(ctx context.Context, r *runtimeapi.CreateContainerRequest) (*runtimeapi.CreateContainerResponse, error) { - containerId, err := d.runtimeService.CreateContainer(r.PodSandboxId, r.GetConfig(), r.GetSandboxConfig()) - if err != nil { - return nil, err - } - return &runtimeapi.CreateContainerResponse{ContainerId: containerId}, nil -} - -func (d *dockerService) StartContainer(ctx context.Context, r *runtimeapi.StartContainerRequest) (*runtimeapi.StartContainerResponse, error) { - err := d.runtimeService.StartContainer(r.ContainerId) - if err != nil { - return nil, err - } - return &runtimeapi.StartContainerResponse{}, nil -} - -func (d *dockerService) StopContainer(ctx context.Context, r *runtimeapi.StopContainerRequest) (*runtimeapi.StopContainerResponse, error) { - err := d.runtimeService.StopContainer(r.ContainerId, r.Timeout) - if err != nil { - return nil, err - } - return &runtimeapi.StopContainerResponse{}, nil -} - -func (d *dockerService) RemoveContainer(ctx context.Context, r *runtimeapi.RemoveContainerRequest) (*runtimeapi.RemoveContainerResponse, error) { - err := d.runtimeService.RemoveContainer(r.ContainerId) - if err != nil { - return nil, err - } - return &runtimeapi.RemoveContainerResponse{}, nil -} - -func (d *dockerService) ListContainers(ctx context.Context, r *runtimeapi.ListContainersRequest) (*runtimeapi.ListContainersResponse, error) { - containers, err := d.runtimeService.ListContainers(r.GetFilter()) - if err != nil { - return nil, err - } - return &runtimeapi.ListContainersResponse{Containers: containers}, nil -} - -func (d *dockerService) ContainerStatus(ctx context.Context, r *runtimeapi.ContainerStatusRequest) (*runtimeapi.ContainerStatusResponse, error) { - status, err := d.runtimeService.ContainerStatus(r.ContainerId) - if err != nil { - return nil, err - } - return &runtimeapi.ContainerStatusResponse{Status: status}, nil -} - -func (d *dockerService) UpdateContainerResources(ctx context.Context, r *runtimeapi.UpdateContainerResourcesRequest) (*runtimeapi.UpdateContainerResourcesResponse, error) { - err := d.runtimeService.UpdateContainerResources(r.ContainerId, r.Linux) - if err != nil { - return nil, err - } - return &runtimeapi.UpdateContainerResourcesResponse{}, nil -} - -func (d *dockerService) ExecSync(ctx context.Context, r *runtimeapi.ExecSyncRequest) (*runtimeapi.ExecSyncResponse, error) { - stdout, stderr, err := d.runtimeService.ExecSync(r.ContainerId, r.Cmd, time.Duration(r.Timeout)*time.Second) - var exitCode int32 - if err != nil { - exitError, ok := err.(utilexec.ExitError) - if !ok { - return nil, err - } - exitCode = int32(exitError.ExitStatus()) - } - return &runtimeapi.ExecSyncResponse{ - Stdout: stdout, - Stderr: stderr, - ExitCode: exitCode, - }, nil -} - -func (d *dockerService) Exec(ctx context.Context, r *runtimeapi.ExecRequest) (*runtimeapi.ExecResponse, error) { - return d.runtimeService.Exec(r) -} - -func (d *dockerService) Attach(ctx context.Context, r *runtimeapi.AttachRequest) (*runtimeapi.AttachResponse, error) { - return d.runtimeService.Attach(r) -} - -func (d *dockerService) PortForward(ctx context.Context, r *runtimeapi.PortForwardRequest) (*runtimeapi.PortForwardResponse, error) { - return d.runtimeService.PortForward(r) -} - -func (d *dockerService) UpdateRuntimeConfig(ctx context.Context, r *runtimeapi.UpdateRuntimeConfigRequest) (*runtimeapi.UpdateRuntimeConfigResponse, error) { - err := d.runtimeService.UpdateRuntimeConfig(r.GetRuntimeConfig()) - if err != nil { - return nil, err - } - return &runtimeapi.UpdateRuntimeConfigResponse{}, nil -} - -func (d *dockerService) ListImages(ctx context.Context, r *runtimeapi.ListImagesRequest) (*runtimeapi.ListImagesResponse, error) { - images, err := d.imageService.ListImages(r.GetFilter()) - if err != nil { - return nil, err - } - return &runtimeapi.ListImagesResponse{Images: images}, nil -} - -func (d *dockerService) ImageStatus(ctx context.Context, r *runtimeapi.ImageStatusRequest) (*runtimeapi.ImageStatusResponse, error) { - image, err := d.imageService.ImageStatus(r.GetImage()) - if err != nil { - return nil, err - } - return &runtimeapi.ImageStatusResponse{Image: image}, nil -} - -func (d *dockerService) PullImage(ctx context.Context, r *runtimeapi.PullImageRequest) (*runtimeapi.PullImageResponse, error) { - image, err := d.imageService.PullImage(r.GetImage(), r.GetAuth()) - if err != nil { - return nil, err - } - return &runtimeapi.PullImageResponse{ImageRef: image}, nil -} - -func (d *dockerService) RemoveImage(ctx context.Context, r *runtimeapi.RemoveImageRequest) (*runtimeapi.RemoveImageResponse, error) { - err := d.imageService.RemoveImage(r.GetImage()) - if err != nil { - return nil, err - } - return &runtimeapi.RemoveImageResponse{}, nil -} - -// ImageFsInfo returns information of the filesystem that is used to store images. -func (d *dockerService) ImageFsInfo(ctx context.Context, r *runtimeapi.ImageFsInfoRequest) (*runtimeapi.ImageFsInfoResponse, error) { - filesystems, err := d.imageService.ImageFsInfo() - if err != nil { - return nil, err - } - return &runtimeapi.ImageFsInfoResponse{ImageFilesystems: filesystems}, nil -} - -func (d *dockerService) ContainerStats(ctx context.Context, r *runtimeapi.ContainerStatsRequest) (*runtimeapi.ContainerStatsResponse, error) { - stats, err := d.runtimeService.ContainerStats(r.ContainerId) - if err != nil { - return nil, err - } - return &runtimeapi.ContainerStatsResponse{Stats: stats}, nil -} - -func (d *dockerService) ListContainerStats(ctx context.Context, r *runtimeapi.ListContainerStatsRequest) (*runtimeapi.ListContainerStatsResponse, error) { - stats, err := d.runtimeService.ListContainerStats(r.GetFilter()) - if err != nil { - return nil, err - } - return &runtimeapi.ListContainerStatsResponse{Stats: stats}, nil -}