func (s RuntimeServer) Status(ctx context.Context, req *rtApi.StatusRequest) (*rtApi.StatusResponse, error) {
	response := &rtApi.StatusResponse{
		Status: &rtApi.RuntimeStatus{
			Conditions: []*rtApi.RuntimeCondition{
				{
					Type:   rtApi.RuntimeReady,
					Status: true,
				},
				{
					Type:   rtApi.NetworkReady,
					Status: true,
				},
			},
		},
	}
	return response, nil
}
Status returns the status of the runtime.
package cri  
import (
	"bytes"
	"errors"
	"io/ioutil"
	"path"
	"strconv"
	"strings"
	"github.com/automaticserver/lxe/cli/version"
	"github.com/automaticserver/lxe/lxf"
	"github.com/automaticserver/lxe/lxf/device"
	"github.com/automaticserver/lxe/network"
	"github.com/automaticserver/lxe/shared"
	"github.com/lxc/lxd/lxc/config"
	opencontainers "github.com/opencontainers/runtime-spec/specs-go"
	"github.com/sirupsen/logrus"
	"golang.org/x/net/context"
	utilNet "k8s.io/apimachinery/pkg/util/net"
	rtApi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
	"k8s.io/kubernetes/pkg/kubelet/util/ioutils"
)
const (
	criVersion = "0.1.0"
)
var (
	ErrNotImplemented       = errors.New("not implemented")
	ErrUnknownNetworkPlugin = errors.New("unknown network plugin")
)
type RuntimeServer struct {
	rtApi.RuntimeServiceServer
	lxf       lxf.Client
	stream    *streamService
	lxdConfig *config.Config
	criConfig *Config
	network   network.Plugin
}
func NewRuntimeServer(criConfig *Config, lxf lxf.Client, network network.Plugin) (*RuntimeServer, error) {
	var err error
	runtime := RuntimeServer{
		criConfig: criConfig,
		network:   network,
	}
	configPath, err := getLXDConfigPath(criConfig)
	if err != nil {
		return nil, err
	}
	runtime.lxdConfig, err = config.LoadConfig(configPath)
	if err != nil {
		return nil, err
	}
	runtime.lxf = lxf
	return &runtime, nil
}
func (s RuntimeServer) Version(ctx context.Context, req *rtApi.VersionRequest) (*rtApi.VersionResponse, error) {
	log := log.WithContext(ctx).WithField("version", req.GetVersion())
	info, err := s.lxf.GetRuntimeInfo()
	if err != nil {
		return nil, AnnErr(log, err, "unable to get server environment")
	}
	response := &rtApi.VersionResponse{
		Version:           criVersion,
		RuntimeName:       Domain,
		RuntimeVersion:    version.Version,
		RuntimeApiVersion: info.Version,
	}
	return response, nil
}
func (s RuntimeServer) RunPodSandbox(ctx context.Context, req *rtApi.RunPodSandboxRequest) (*rtApi.RunPodSandboxResponse, error) {  
	log := log.WithContext(ctx).WithFields(logrus.Fields{
		"podname":   req.GetConfig().GetMetadata().GetName(),
		"namespace": req.GetConfig().GetMetadata().GetNamespace(),
		"poduid":    req.GetConfig().GetMetadata().GetUid(),
	})
	log.Info("run pod")
	var err error
	sb := s.lxf.NewSandbox()
	sb.Hostname = req.GetConfig().GetHostname()
	sb.LogDirectory = req.GetConfig().GetLogDirectory()
	meta := req.GetConfig().GetMetadata()
	sb.Metadata = lxf.SandboxMetadata{
		Attempt:   meta.GetAttempt(),
		Name:      meta.GetName(),
		Namespace: meta.GetNamespace(),
		UID:       meta.GetUid(),
	}
	sb.Labels = req.GetConfig().GetLabels()
	sb.Annotations = req.GetConfig().GetAnnotations()
	if req.GetConfig().GetDnsConfig() != nil {
		sb.NetworkConfig.Nameservers = req.GetConfig().GetDnsConfig().GetServers()
		sb.NetworkConfig.Searches = req.GetConfig().GetDnsConfig().GetSearches()
	}
	if strings.ToLower(req.GetConfig().GetLinux().GetSecurityContext().GetNamespaceOptions().GetNetwork().String()) == string(lxf.NetworkHost) {
		sb.NetworkConfig.Mode = lxf.NetworkHost
		lxf.AppendIfSet(&sb.Config, "raw.lxc", "lxc.include = "+s.criConfig.LXEHostnetworkFile)
	} else {
		switch s.criConfig.LXENetworkPlugin {
		case NetworkPluginBridge:
			sb.NetworkConfig.Mode = lxf.NetworkBridged
		case NetworkPluginCNI:
			sb.NetworkConfig.Mode = lxf.NetworkCNI
		default:
			return nil, AnnErr(log, ErrUnknownNetworkPlugin, s.criConfig.LXENetworkPlugin)
		}
	}
	if sb.NetworkConfig.Mode != lxf.NetworkHost {
		for _, portMap := range req.Config.PortMappings {
			if portMap.GetHostPort() == 0 || portMap.GetContainerPort() == 0 {
				continue
			}
			hostPort := int(portMap.GetHostPort())
			containerPort := int(portMap.GetContainerPort())
			var protocol device.Protocol
			switch portMap.GetProtocol() {  
			case rtApi.Protocol_UDP:
				protocol = device.ProtocolUDP
			case rtApi.Protocol_TCP:
				fallthrough
			default:
				protocol = device.ProtocolTCP
			}
			hostIP := portMap.GetHostIp()
			if hostIP == "" {
				hostIP = "0.0.0.0"
			}
			containerIP := "127.0.0.1"
			sb.Devices.Upsert(&device.Proxy{
				Listen: &device.ProxyEndpoint{
					Protocol: protocol,
					Address:  hostIP,
					Port:     hostPort,
				},
				Destination: &device.ProxyEndpoint{
					Protocol: protocol,
					Address:  containerIP,
					Port:     containerPort,
				},
			})
		}
	}
	if req.Config.Linux != nil {  
		lxf.SetIfSet(&sb.Config, "user.linux.cgroup_parent", req.Config.Linux.CgroupParent)
		for key, value := range req.Config.Linux.Sysctls {
			sb.Config["user.linux.sysctls."+key] = value
		}
		if req.Config.Linux.SecurityContext != nil {
			privileged := req.Config.Linux.SecurityContext.Privileged
			sb.Config["user.linux.security_context.privileged"] = strconv.FormatBool(privileged)
			sb.Config["security.privileged"] = strconv.FormatBool(privileged)
			if req.Config.Linux.SecurityContext.NamespaceOptions != nil {
				nsi := "user.linux.security_context.namespace_options"
				nso := req.Config.Linux.SecurityContext.NamespaceOptions
				sb.Config[nsi+".ipc"] = nameSpaceOptionToString(nso.Ipc)
				sb.Config[nsi+".network"] = nameSpaceOptionToString(nso.Network)
				sb.Config[nsi+".pid"] = nameSpaceOptionToString(nso.Pid)
			}
			if req.Config.Linux.SecurityContext.ReadonlyRootfs {
				sb.Devices.Upsert(&device.Disk{
					Path:     "/",
					Readonly: true,
					Pool: "default",
				})
			}
			if req.Config.Linux.SecurityContext.RunAsUser != nil {
				sb.Config["user.linux.security_context.run_as_user"] =
					strconv.FormatInt(req.Config.Linux.SecurityContext.RunAsUser.Value, 10)
			}
			lxf.SetIfSet(&sb.Config, "user.linux.security_context.seccomp_profile_path",
				req.Config.Linux.SecurityContext.SeccompProfilePath)
			if req.Config.Linux.SecurityContext.SelinuxOptions != nil {
				sci := "user.linux.security_context.namespace_options"
				sco := req.Config.Linux.SecurityContext.SelinuxOptions
				lxf.SetIfSet(&sb.Config, sci+".role", sco.Role)
				lxf.SetIfSet(&sb.Config, sci+".level", sco.Level)
				lxf.SetIfSet(&sb.Config, sci+".user", sco.User)
				lxf.SetIfSet(&sb.Config, sci+".type", sco.Type)
			}
		}
	}
	err = sb.Apply()
	if err != nil {
		return nil, AnnErr(log, err, "failed to create pod")
	}
	log = log.WithField("podid", sb.ID)
	if sb.NetworkConfig.Mode != lxf.NetworkHost {  
		podNet, err := s.network.PodNetwork(sb.ID, sb.Annotations)
		if err != nil {
			return nil, AnnErr(log, err, "can't enter pod network context")
		}
		res, err := podNet.WhenCreated(ctx, &network.Properties{})
		if err != nil {
			return nil, AnnErr(log, err, "can't create pod network")
		}
		err = s.handleNetworkResult(sb, res)
		if err != nil {
			return nil, AnnErr(log, err, "unable to save pod network result")
		}
		res, err = podNet.WhenStarted(ctx, &network.PropertiesRunning{
			Properties: network.Properties{
				Data: sb.NetworkConfig.ModeData,
			},
			Pid: 0,  
		})
		if err != nil {
			return nil, AnnErr(log, err, "can't start pod network")
		}
		err = s.handleNetworkResult(sb, res)
		if err != nil {
			return nil, AnnErr(log, err, "unable to save start pod network result")
		}
	}
	log.Info("run pod successful")
	return &rtApi.RunPodSandboxResponse{PodSandboxId: sb.ID}, nil
}
func (s RuntimeServer) StopPodSandbox(ctx context.Context, req *rtApi.StopPodSandboxRequest) (*rtApi.StopPodSandboxResponse, error) {
	log := log.WithContext(ctx).WithField("podid", req.GetPodSandboxId())
	log.Info("stop pod")
	sb, err := s.lxf.GetSandbox(req.GetPodSandboxId())
	if err != nil {
		if shared.IsErrNotFound(err) {
			return &rtApi.StopPodSandboxResponse{}, nil
		}
		return nil, AnnErr(log, err, "unable to get pod")
	}
	err = s.stopContainers(sb)
	if err != nil {
		return nil, AnnErr(log, err, "unable to stop containers")
	}
	err = sb.Stop()
	if err != nil {
		return nil, AnnErr(log, err, "unable to stop pod")
	}
	if sb.NetworkConfig.Mode != lxf.NetworkHost {
		netw, err := s.network.PodNetwork(sb.ID, sb.Annotations)
		if err == nil {  
			_ = netw.WhenStopped(ctx, &network.Properties{Data: sb.NetworkConfig.ModeData})
		}
	}
	log.Info("stop pod successful")
	return &rtApi.StopPodSandboxResponse{}, nil
}
func (s RuntimeServer) RemovePodSandbox(ctx context.Context, req *rtApi.RemovePodSandboxRequest) (*rtApi.RemovePodSandboxResponse, error) {
	log := log.WithContext(ctx).WithField("podid", req.GetPodSandboxId())
	log.Info("remove pod")
	sb, err := s.lxf.GetSandbox(req.GetPodSandboxId())
	if err != nil {
		if shared.IsErrNotFound(err) {
			return &rtApi.RemovePodSandboxResponse{}, nil
		}
		return nil, AnnErr(log, err, "unable to get pod")
	}
	err = s.stopContainers(sb)
	if err != nil {
		return nil, AnnErr(log, err, "unable to stop containers")
	}
	err = s.deleteContainers(ctx, sb)
	if err != nil {
		return nil, AnnErr(log, err, "unable to delete containers")
	}
	err = sb.Delete()
	if err != nil {
		return nil, AnnErr(log, err, "unable to delete pod")
	}
	if sb.NetworkConfig.Mode != lxf.NetworkHost {
		netw, err := s.network.PodNetwork(sb.ID, sb.Annotations)
		if err != nil {
			log.WithError(err).Error("unable to delete networking: unable to enter pod network")
		} else {
			err := netw.WhenDeleted(ctx, &network.Properties{Data: sb.NetworkConfig.ModeData})
			if err == nil {
				log.WithError(err).Error("unable to delete networking: call to network plugin errored")
			}
		}
	}
	log.Info("remove pod successful")
	return &rtApi.RemovePodSandboxResponse{}, nil
}
func (s RuntimeServer) PodSandboxStatus(ctx context.Context, req *rtApi.PodSandboxStatusRequest) (*rtApi.PodSandboxStatusResponse, error) {
	log := log.WithContext(ctx).WithField("podid", req.GetPodSandboxId())
	sb, err := s.lxf.GetSandbox(req.GetPodSandboxId())
	if err != nil {
		return nil, AnnErr(log, err, "unable to get pod")
	}
	response := &rtApi.PodSandboxStatusResponse{
		Status: &rtApi.PodSandboxStatus{
			Id: sb.ID,
			Metadata: &rtApi.PodSandboxMetadata{
				Attempt:   sb.Metadata.Attempt,
				Name:      sb.Metadata.Name,
				Namespace: sb.Metadata.Namespace,
				Uid:       sb.Metadata.UID,
			},
			Linux:       &rtApi.LinuxPodSandboxStatus{},
			Labels:      sb.Labels,
			Annotations: sb.Annotations,
			CreatedAt:   sb.CreatedAt.UnixNano(),
			State:       stateSandboxAsCri(sb.State),
			Network: &rtApi.PodSandboxNetworkStatus{
				Ip: "",
			},
		},
	}
	for k, v := range sb.Config {
		if strings.HasPrefix(k, "user.linux.security_context.namespace_options.") {
			key := strings.TrimPrefix(k, "user.linux.security_context.namespace_options.")
			if response.Status.Linux.Namespaces == nil {
				response.Status.Linux.Namespaces = &rtApi.Namespace{Options: &rtApi.NamespaceOption{}}
			}
			switch key {
			case "ipc":
				response.Status.Linux.Namespaces.Options.Ipc = stringToNamespaceOption(v)
			case "pid":
				response.Status.Linux.Namespaces.Options.Pid = stringToNamespaceOption(v)
			case "network":
				response.Status.Linux.Namespaces.Options.Network = stringToNamespaceOption(v)
			}
		}
	}
	ip := s.getInetAddress(ctx, sb)
	if ip != "" {
		response.Status.Network.Ip = ip
	}
	return response, nil
}
func (s RuntimeServer) getInetAddress(ctx context.Context, sb *lxf.Sandbox) string {
	log := log.WithContext(ctx).WithField("podid", sb.ID)
	switch sb.NetworkConfig.Mode {
	case lxf.NetworkHost:
		ip, err := utilNet.ChooseHostInterface()
		if err != nil {
			log.WithError(err).Error("Couldn't choose host interface")
			return ""
		}
		return ip.String()
	case lxf.NetworkNone:
		return ""
	case lxf.NetworkBridged:
		fallthrough
	case lxf.NetworkCNI:
		podNet, err := s.network.PodNetwork(sb.ID, sb.Annotations)
		if err != nil {
			log.WithError(err).Error("Couldn't get cni pod network")
			return ""
		}
		status, err := podNet.Status(ctx, &network.PropertiesRunning{Properties: network.Properties{Data: sb.NetworkConfig.ModeData}, Pid: 0})
		if err != nil {
			log.WithError(err).Error("Couldn't get status of cni pod network")
			return ""
		}
		if len(status.IPs) > 0 {
			return status.IPs[0].String()
		}
	}
	cl, err := sb.Containers()
	if err != nil {
		log.WithError(err).Error("Couldn't list containers while trying to get inet address")
		return ""
	}
	for _, c := range cl {
		if c.StateName != lxf.ContainerStateRunning {
			continue
		}
		ip := c.GetInetAddress([]string{network.DefaultInterface})
		if ip != "" {
			return ip
		}
	}
	return ""
}
func (s RuntimeServer) ListPodSandbox(ctx context.Context, req *rtApi.ListPodSandboxRequest) (*rtApi.ListPodSandboxResponse, error) {
	log := log.WithContext(ctx).WithField("filter", req.GetFilter().String())
	sandboxes, err := s.lxf.ListSandboxes()
	if err != nil {
		return nil, AnnErr(log, err, "unable to list pods")
	}
	response := &rtApi.ListPodSandboxResponse{}
	for _, sb := range sandboxes {
		if req.GetFilter() != nil {
			filter := req.GetFilter()
			if filter.GetId() != "" && filter.GetId() != sb.ID {
				continue
			}
			if filter.GetState() != nil && filter.GetState().GetState() != stateSandboxAsCri(sb.State) {
				continue
			}
			if !CompareFilterMap(sb.Labels, filter.GetLabelSelector()) {
				continue
			}
		}
		pod := rtApi.PodSandbox{
			Id:        sb.ID,
			CreatedAt: sb.CreatedAt.UnixNano(),
			Metadata: &rtApi.PodSandboxMetadata{
				Attempt:   sb.Metadata.Attempt,
				Name:      sb.Metadata.Name,
				Namespace: sb.Metadata.Namespace,
				Uid:       sb.Metadata.UID,
			},
			State:       stateSandboxAsCri(sb.State),
			Labels:      sb.Labels,
			Annotations: sb.Annotations,
		}
		response.Items = append(response.Items, &pod)
	}
	return response, nil
}
func (s RuntimeServer) CreateContainer(ctx context.Context, req *rtApi.CreateContainerRequest) (*rtApi.CreateContainerResponse, error) {
	log := log.WithContext(ctx).WithFields(logrus.Fields{
		"containername": req.GetConfig().GetMetadata().GetName(),
		"attempt":       req.GetConfig().GetMetadata().GetAttempt(),
		"podid":         req.GetPodSandboxId(),
	})
	log.Info("create container")
	var err error
	c := s.lxf.NewContainer(req.GetPodSandboxId(), s.criConfig.LXDProfiles...)
	c.Labels = req.GetConfig().GetLabels()
	c.Annotations = req.GetConfig().GetAnnotations()
	meta := req.GetConfig().GetMetadata()
	c.Metadata = lxf.ContainerMetadata{
		Attempt: meta.GetAttempt(),
		Name:    meta.GetName(),
	}
	c.LogPath = req.GetConfig().GetLogPath()
	c.Image = req.GetConfig().GetImage().GetImage()
	for _, mnt := range req.GetConfig().GetMounts() {
		hostPath := mnt.GetHostPath()
		containerPath := mnt.GetContainerPath()
		if strings.HasPrefix(containerPath, "/var/run") {
			containerPath = path.Join("/run", strings.TrimPrefix(containerPath, "/var/run"))
		}
		if strings.HasPrefix(containerPath, "/run") {
			containerPath = path.Join("/mnt", strings.TrimPrefix(containerPath, "/run"))
		}
		c.Devices.Upsert(&device.Disk{
			Path:     containerPath,
			Source:   hostPath,
			Readonly: mnt.GetReadonly(),
			Optional: false,
		})
	}
	for _, dev := range req.GetConfig().GetDevices() {
		c.Devices.Upsert(&device.Block{
			Source: dev.GetHostPath(),
			Path:   dev.GetContainerPath(),
		})
	}
	c.Privileged = req.GetConfig().GetLinux().GetSecurityContext().GetPrivileged()
	for _, env := range req.GetConfig().GetEnvs() {
		switch {
		case env.GetKey() == "user-data":
			c.CloudInitUserData = env.GetValue()
		case env.GetKey() == "meta-data":
			c.CloudInitMetaData = env.GetValue()
		case env.GetKey() == "network-config":
			c.CloudInitNetworkConfig = env.GetValue()
		default:
			c.Environment[env.GetKey()] = env.GetValue()
		}
	}
	if c.CloudInitMetaData != "" && len(c.Environment) > 0 {
		c.CloudInitMetaData += "\n"
	}
	resrc := req.GetConfig().GetLinux().GetResources()
	if resrc != nil {
		c.Resources = &opencontainers.LinuxResources{}
		c.Resources.CPU = &opencontainers.LinuxCPU{}
		c.Resources.Memory = &opencontainers.LinuxMemory{}
		shares := uint64(resrc.CpuShares)
		c.Resources.CPU.Shares = &shares
		c.Resources.CPU.Quota = &resrc.CpuQuota
		period := uint64(resrc.CpuPeriod)
		c.Resources.CPU.Period = &period
		c.Resources.Memory.Limit = &resrc.MemoryLimitInBytes
	}
	err = c.Apply()
	if err != nil {
		return nil, AnnErr(log, err, "unable to create container")
	}
	sb, err := c.Sandbox()
	if err != nil {
		return nil, AnnErr(log, err, "unable to find sandbox")
	}
	if sb.NetworkConfig.Mode != lxf.NetworkHost {
		podNet, err := s.network.PodNetwork(sb.ID, sb.Annotations)
		if err != nil {
			return nil, AnnErr(log, err, "can't enter pod network context")
		}
		contNet, err := podNet.ContainerNetwork(c.ID, c.Annotations)
		if err != nil {
			return nil, AnnErr(log, err, "can't enter container network context")
		}
		res, err := contNet.WhenCreated(ctx, &network.Properties{})
		if err != nil {
			return nil, AnnErr(log, err, "can't create container network")
		}
		err = s.handleNetworkResult(sb, res)
		if err != nil {
			return nil, AnnErr(log, err, "unable to save create container network result")
		}
	}
	log.Info("create container successful")
	return &rtApi.CreateContainerResponse{ContainerId: c.ID}, nil
}
func (s RuntimeServer) StartContainer(ctx context.Context, req *rtApi.StartContainerRequest) (*rtApi.StartContainerResponse, error) {
	log := log.WithContext(ctx).WithField("containerid", req.GetContainerId())
	log.Info("start container")
	c, err := s.lxf.GetContainer(req.GetContainerId())
	if err != nil {
		return nil, AnnErr(log, err, "unable to get container")
	}
	err = c.Start()
	if err != nil {
		return nil, AnnErr(log, err, "unable to start container")
	}
	log.Info("start container successful")
	return &rtApi.StartContainerResponse{}, nil
}
func (s RuntimeServer) StopContainer(ctx context.Context, req *rtApi.StopContainerRequest) (*rtApi.StopContainerResponse, error) {
	log := log.WithContext(ctx).WithField("containerid", req.GetContainerId())
	log.Info("stop container")
	c, err := s.lxf.GetContainer(req.GetContainerId())
	if err != nil {
		if shared.IsErrNotFound(err) {
			return &rtApi.StopContainerResponse{}, nil
		}
		return nil, AnnErr(log, err, "unable to get container")
	}
	err = s.stopContainer(c, int(req.Timeout))
	if err != nil {
		return nil, AnnErr(log, err, "unable to stop container")
	}
	log.Info("stop container successful")
	return &rtApi.StopContainerResponse{}, nil
}
func (s RuntimeServer) RemoveContainer(ctx context.Context, req *rtApi.RemoveContainerRequest) (*rtApi.RemoveContainerResponse, error) {
	log := log.WithContext(ctx).WithField("containerid", req.GetContainerId())
	log.Info("remove container")
	c, err := s.lxf.GetContainer(req.GetContainerId())
	if err != nil {
		if shared.IsErrNotFound(err) {
			return &rtApi.RemoveContainerResponse{}, nil
		}
		return nil, AnnErr(log, err, "unable to get container")
	}
	err = s.deleteContainer(ctx, c)
	if err != nil {
		return nil, AnnErr(log, err, "unable to remove container")
	}
	log.Info("remove container successful")
	return &rtApi.RemoveContainerResponse{}, nil
}
func (s RuntimeServer) ListContainers(ctx context.Context, req *rtApi.ListContainersRequest) (*rtApi.ListContainersResponse, error) {
	log := log.WithContext(ctx).WithField("filter", req.GetFilter().String())
	response := &rtApi.ListContainersResponse{}
	cl, err := s.lxf.ListContainers()
	if err != nil {
		return nil, AnnErr(log, err, "unable to get container list")
	}
	for _, c := range cl {
		if req.GetFilter() != nil {
			filter := req.GetFilter()
			if filter.GetId() != "" && filter.GetId() != c.ID {
				continue
			}
			if filter.GetState() != nil && filter.GetState().GetState() != stateContainerAsCri(c.StateName) {
				continue
			}
			if filter.GetPodSandboxId() != "" && filter.GetPodSandboxId() != c.SandboxID() {
				continue
			}
			if !CompareFilterMap(c.Labels, filter.GetLabelSelector()) {
				continue
			}
		}
		response.Containers = append(response.Containers, toCriContainer(c))
	}
	return response, nil
}
func (s RuntimeServer) ContainerStatus(ctx context.Context, req *rtApi.ContainerStatusRequest) (*rtApi.ContainerStatusResponse, error) {
	log := log.WithContext(ctx).WithField("containerid", req.GetContainerId())
	ct, err := s.lxf.GetContainer(req.GetContainerId())
	if err != nil {
		return nil, AnnErr(log, err, "unable to get container")
	}
	response := toCriStatusResponse(ct)
	return response, nil
}
func (s RuntimeServer) UpdateContainerResources(ctx context.Context, req *rtApi.UpdateContainerResourcesRequest) (*rtApi.UpdateContainerResourcesResponse, error) {
	return nil, SilErr(log, ErrNotImplemented, "")
}
func (s RuntimeServer) ReopenContainerLog(ctx context.Context, req *rtApi.ReopenContainerLogRequest) (*rtApi.ReopenContainerLogResponse, error) {
	return nil, SilErr(log, ErrNotImplemented, "")
}
func (s RuntimeServer) ExecSync(ctx context.Context, req *rtApi.ExecSyncRequest) (*rtApi.ExecSyncResponse, error) {
	log := log.WithContext(ctx).WithFields(logrus.Fields{
		"containerid": req.GetContainerId(),
		"cmd":         req.GetCmd(),
	})
	stdin := bytes.NewReader(nil)
	stdinR := ioutil.NopCloser(stdin)
	stdout := bytes.NewBuffer(nil)
	stdoutW := ioutils.WriteCloserWrapper(stdout)
	stderr := bytes.NewBuffer(nil)
	stderrW := ioutils.WriteCloserWrapper(stderr)
	code, err := s.lxf.Exec(req.GetContainerId(), req.GetCmd(), stdinR, stdoutW, stderrW, false, false, req.GetTimeout(), nil)
	if err != nil {
		return nil, AnnErr(log, err, "unable to exec")
	}
	log = log.WithField("exit", code)
	log.Debug("exec finished")
	return &rtApi.ExecSyncResponse{
		Stdout:   stdout.Bytes(),
		Stderr:   stderr.Bytes(),
		ExitCode: code,
	}, err
}
func (s RuntimeServer) Exec(ctx context.Context, req *rtApi.ExecRequest) (*rtApi.ExecResponse, error) {
	log := log.WithContext(ctx).WithFields(logrus.Fields{
		"containerid": req.GetContainerId(),
		"cmd":         req.GetCmd(),
	})
	resp, err := s.stream.streamServer.GetExec(req)
	if err != nil {
		return nil, AnnErr(log, err, "unable to get exec stream")
	}
	return resp, nil
}
func (s RuntimeServer) Attach(ctx context.Context, req *rtApi.AttachRequest) (*rtApi.AttachResponse, error) {
	return nil, SilErr(log, ErrNotImplemented, "")
}
func (s RuntimeServer) PortForward(ctx context.Context, req *rtApi.PortForwardRequest) (resp *rtApi.PortForwardResponse, err error) {
	log := log.WithContext(ctx).WithFields(logrus.Fields{
		"podid": req.GetPodSandboxId(),
		"port":  req.GetPort(),
	})
	resp, err = s.stream.streamServer.GetPortForward(req)
	if err != nil {
		return nil, AnnErr(log, err, "unable to create port forward")
	}
	return resp, nil
}
func (s RuntimeServer) ContainerStats(ctx context.Context, req *rtApi.ContainerStatsRequest) (*rtApi.ContainerStatsResponse, error) {
	log := log.WithContext(ctx).WithField("containerid", req.GetContainerId())
	cntStat, err := s.lxf.GetContainer(req.GetContainerId())
	if err != nil {
		return nil, AnnErr(log, err, "unable to get container")
	}
	stats, err := toCriStats(cntStat)
	if err != nil {
		return nil, AnnErr(log, err, "unable to get stats")
	}
	return &rtApi.ContainerStatsResponse{Stats: stats}, nil
}
func (s RuntimeServer) ListContainerStats(ctx context.Context, req *rtApi.ListContainerStatsRequest) (*rtApi.ListContainerStatsResponse, error) {
	log := log.WithContext(ctx).WithField("filter", req.GetFilter())
	response := &rtApi.ListContainerStatsResponse{}
	if req.GetFilter() != nil && req.GetFilter().GetId() != "" {
		log = log.WithField("containerid", req.GetFilter().GetId())
		c, err := s.lxf.GetContainer(req.Filter.Id)
		if err != nil {
			return nil, AnnErr(log, err, "unable to get container")
		}
		st, err := toCriStats(c)
		if err != nil {
			return nil, AnnErr(log, err, "unable to get stats")
		}
		response.Stats = append(response.Stats, st)
		return response, nil
	}
	cts, err := s.lxf.ListContainers()
	if err != nil {
		return nil, AnnErr(log, err, "unable to list containers")
	}
	for _, c := range cts {
		log = log.WithField("containerid", c.ID)
		st, err := toCriStats(c)
		if err != nil {
			return nil, AnnErr(log, err, "unable to get stats")
		}
		response.Stats = append(response.Stats, st)
	}
	return response, nil
}
func (s RuntimeServer) UpdateRuntimeConfig(ctx context.Context, req *rtApi.UpdateRuntimeConfigRequest) (*rtApi.UpdateRuntimeConfigResponse, error) {
	log := log.WithContext(ctx).WithField("cidr", req.GetRuntimeConfig().GetNetworkConfig().GetPodCidr())
	err := s.network.UpdateRuntimeConfig(req.GetRuntimeConfig())
	if err != nil {
		return nil, AnnErr(log, err, "unable to update runtime config")
	}
	return &rtApi.UpdateRuntimeConfigResponse{}, nil
}