From b25b06577e80f08a99c7217707e13a3fc1382ff2 Mon Sep 17 00:00:00 2001 From: Lantao Liu Date: Wed, 6 Dec 2017 06:00:26 +0000 Subject: [PATCH 1/2] Improve container and sandbox status. Signed-off-by: Lantao Liu --- pkg/server/container_status.go | 7 +-- pkg/server/sandbox_status.go | 91 +++++++++++++++++++--------------- 2 files changed, 54 insertions(+), 44 deletions(-) diff --git a/pkg/server/container_status.go b/pkg/server/container_status.go index 0cf5e182d..4533da2a4 100644 --- a/pkg/server/container_status.go +++ b/pkg/server/container_status.go @@ -100,6 +100,7 @@ func toCRIContainerStatus(container containerstore.Container, spec *runtime.Imag } type containerInfo struct { + // TODO(random-liu): Add sandboxID in CRI container status. SandboxID string `json:"sandboxID"` Pid uint32 `json:"pid"` Removing bool `json:"removing"` @@ -115,7 +116,6 @@ func toCRIContainerInfo(ctx context.Context, container containerstore.Container, return nil, nil } - info := make(map[string]string) meta := container.Metadata status := container.Status.Get() @@ -146,6 +146,7 @@ func toCRIContainerInfo(ctx context.Context, container containerstore.Container, if err != nil { return nil, fmt.Errorf("failed to marshal info %v: %v", ci, err) } - info["info"] = string(infoBytes) - return info, nil + return map[string]string{ + "info": string(infoBytes), + }, nil } diff --git a/pkg/server/sandbox_status.go b/pkg/server/sandbox_status.go index 9ac52e1e8..06e6b5fd0 100644 --- a/pkg/server/sandbox_status.go +++ b/pkg/server/sandbox_status.go @@ -44,6 +44,8 @@ func (c *criContainerdService) PodSandboxStatus(ctx context.Context, r *runtime. return nil, fmt.Errorf("failed to get sandbox container task: %v", err) } + var pid uint32 + var processStatus containerd.ProcessStatus // Set sandbox state to NOTREADY by default. state := runtime.PodSandboxState_SANDBOX_NOTREADY // If the sandbox container is running, treat it as READY. @@ -56,6 +58,8 @@ func (c *criContainerdService) PodSandboxStatus(ctx context.Context, r *runtime. if taskStatus.Status == containerd.Running { state = runtime.PodSandboxState_SANDBOX_READY } + pid = task.Pid() + processStatus = taskStatus.Status } ip, err := c.getIP(sandbox) @@ -69,7 +73,7 @@ func (c *criContainerdService) PodSandboxStatus(ctx context.Context, r *runtime. } createdAt := ctrInfo.CreatedAt status := toCRISandboxStatus(sandbox.Metadata, state, createdAt, ip) - info, err := toCRISandboxContainerInfo(ctx, sandbox.Container, r.GetVerbose()) + info, err := toCRISandboxInfo(ctx, sandbox, pid, processStatus, r.GetVerbose()) if err != nil { return nil, fmt.Errorf("failed to get verbose sandbox container info: %v", err) } @@ -82,62 +86,67 @@ func (c *criContainerdService) PodSandboxStatus(ctx context.Context, r *runtime. // TODO (mikebrow): discuss predefining constants structures for some or all of these field names in CRI type sandboxInfo struct { - Pid uint32 `json:"pid"` - State string `json:"state"` - SnapshotKey string `json:"snapshotKey"` - Snapshotter string `json:"snapshotter"` - RuntimeSpec *runtimespec.Spec `json:"runtimeSpec"` + Pid uint32 `json:"pid"` + Status string `json:"processStatus"` + NetNSClosed bool `json:"netNamespaceClosed"` + Image string `json:"image"` + SnapshotKey string `json:"snapshotKey"` + Snapshotter string `json:"snapshotter"` + Config *runtime.PodSandboxConfig `json:"config"` + RuntimeSpec *runtimespec.Spec `json:"runtimeSpec"` } -// toCRISandboxContainerInfo converts internal container object information to CRI sandbox container status response info map. -func toCRISandboxContainerInfo(ctx context.Context, container containerd.Container, verbose bool) (map[string]string, error) { +// toCRISandboxInfo converts internal container object information to CRI sandbox status response info map. +func toCRISandboxInfo(ctx context.Context, sandbox sandboxstore.Sandbox, + pid uint32, processStatus containerd.ProcessStatus, verbose bool) (map[string]string, error) { if !verbose { return nil, nil } - task, err := container.Task(ctx, nil) - if err != nil { - return nil, fmt.Errorf("failed to get sandbox container task: %v", err) - } - status, err := task.Status(ctx) - if err != nil { - return nil, fmt.Errorf("failed to get sandbox container task status: %v", err) + si := &sandboxInfo{ + Pid: pid, + Status: string(processStatus), + Config: sandbox.Config, } - info := make(map[string]string) - pid := task.Pid() - - oldSpec, err := container.Spec(ctx) - if err != nil { - glog.Errorf("Failed to get sandbox container runtime spec: %v", err) + if si.Status == "" { + // If processStatus is empty, it means that the task is deleted. Apply "deleted" + // status which does not exist in containerd. + si.Status = "deleted" + } + + if sandbox.NetNSPath != "" { + // Add network closed information if sandbox is not using host network. + si.NetNSClosed = (sandbox.NetNS == nil || sandbox.NetNS.Closed()) + } + + container := sandbox.Container + spec, err := container.Spec(ctx) + if err == nil { + si.RuntimeSpec = spec + } else { + glog.Errorf("Failed to get sandbox container %q runtime spec: %v", sandbox.ID, err) } - var snapshotkey, snapshotter string ctrInfo, err := container.Info(ctx) if err == nil { - snapshotkey = ctrInfo.SnapshotKey - snapshotter = ctrInfo.Snapshotter + // Do not use config.SandboxImage because the configuration might + // be changed during restart. It may not reflect the actual image + // used by the sandbox container. + si.Image = ctrInfo.Image + si.SnapshotKey = ctrInfo.SnapshotKey + si.Snapshotter = ctrInfo.Snapshotter } else { - glog.Errorf("Failed to get target shapshot info: %v", err) + glog.Errorf("Failed to get sandbox container %q info: %v", sandbox.ID, err) } - si := &sandboxInfo{ - Pid: pid, - State: string(status.Status), - SnapshotKey: snapshotkey, - Snapshotter: snapshotter, - RuntimeSpec: oldSpec, + infoBytes, err := json.Marshal(si) + if err != nil { + return nil, fmt.Errorf("failed to marshal info %v: %v", si, err) } - - m, err := json.Marshal(si) - if err == nil { - info["info"] = string(m) - } else { - glog.Errorf("failed to marshal info %v: %v", si, err) - info["info"] = err.Error() - } - - return info, nil + return map[string]string{ + "info": string(infoBytes), + }, nil } func (c *criContainerdService) getIP(sandbox sandboxstore.Sandbox) (string, error) { From dd017e6e6c339aea5622e42407fcc0795e35acce Mon Sep 17 00:00:00 2001 From: Lantao Liu Date: Wed, 6 Dec 2017 06:01:26 +0000 Subject: [PATCH 2/2] Move less important function to the end. Signed-off-by: Lantao Liu --- pkg/server/sandbox_status.go | 122 +++++++++++++++++------------------ 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/pkg/server/sandbox_status.go b/pkg/server/sandbox_status.go index 06e6b5fd0..a52d13904 100644 --- a/pkg/server/sandbox_status.go +++ b/pkg/server/sandbox_status.go @@ -84,6 +84,67 @@ func (c *criContainerdService) PodSandboxStatus(ctx context.Context, r *runtime. }, nil } +func (c *criContainerdService) getIP(sandbox sandboxstore.Sandbox) (string, error) { + config := sandbox.Config + + if config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetHostNetwork() { + // For sandboxes using the host network we are not + // responsible for reporting the IP. + return "", nil + } + + if err := c.netPlugin.Status(); err != nil { + // If the network is not ready then there is nothing to report. + glog.V(4).Infof("getIP: unable to get sandbox %q network status: network plugin not ready.", sandbox.ID) + return "", nil + } + + // The network namespace has been closed. + if sandbox.NetNS == nil || sandbox.NetNS.Closed() { + return "", nil + } + + podNetwork := ocicni.PodNetwork{ + Name: config.GetMetadata().GetName(), + Namespace: config.GetMetadata().GetNamespace(), + ID: sandbox.ID, + NetNS: sandbox.NetNSPath, + PortMappings: toCNIPortMappings(config.GetPortMappings()), + } + + ip, err := c.netPlugin.GetPodNetworkStatus(podNetwork) + if err == nil { + return ip, nil + } + + // Ignore the error on network status + glog.V(4).Infof("getIP: failed to read sandbox %q IP from plugin: %v", sandbox.ID, err) + return "", nil +} + +// toCRISandboxStatus converts sandbox metadata into CRI pod sandbox status. +func toCRISandboxStatus(meta sandboxstore.Metadata, state runtime.PodSandboxState, createdAt time.Time, ip string) *runtime.PodSandboxStatus { + nsOpts := meta.Config.GetLinux().GetSecurityContext().GetNamespaceOptions() + return &runtime.PodSandboxStatus{ + Id: meta.ID, + Metadata: meta.Config.GetMetadata(), + State: state, + CreatedAt: createdAt.UnixNano(), + Network: &runtime.PodSandboxNetworkStatus{Ip: ip}, + Linux: &runtime.LinuxPodSandboxStatus{ + Namespaces: &runtime.Namespace{ + Options: &runtime.NamespaceOption{ + HostNetwork: nsOpts.GetHostNetwork(), + HostPid: nsOpts.GetHostPid(), + HostIpc: nsOpts.GetHostIpc(), + }, + }, + }, + Labels: meta.Config.GetLabels(), + Annotations: meta.Config.GetAnnotations(), + } +} + // TODO (mikebrow): discuss predefining constants structures for some or all of these field names in CRI type sandboxInfo struct { Pid uint32 `json:"pid"` @@ -148,64 +209,3 @@ func toCRISandboxInfo(ctx context.Context, sandbox sandboxstore.Sandbox, "info": string(infoBytes), }, nil } - -func (c *criContainerdService) getIP(sandbox sandboxstore.Sandbox) (string, error) { - config := sandbox.Config - - if config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetHostNetwork() { - // For sandboxes using the host network we are not - // responsible for reporting the IP. - return "", nil - } - - if err := c.netPlugin.Status(); err != nil { - // If the network is not ready then there is nothing to report. - glog.V(4).Infof("getIP: unable to get sandbox %q network status: network plugin not ready.", sandbox.ID) - return "", nil - } - - // The network namespace has been closed. - if sandbox.NetNS == nil || sandbox.NetNS.Closed() { - return "", nil - } - - podNetwork := ocicni.PodNetwork{ - Name: config.GetMetadata().GetName(), - Namespace: config.GetMetadata().GetNamespace(), - ID: sandbox.ID, - NetNS: sandbox.NetNSPath, - PortMappings: toCNIPortMappings(config.GetPortMappings()), - } - - ip, err := c.netPlugin.GetPodNetworkStatus(podNetwork) - if err == nil { - return ip, nil - } - - // Ignore the error on network status - glog.V(4).Infof("getIP: failed to read sandbox %q IP from plugin: %v", sandbox.ID, err) - return "", nil -} - -// toCRISandboxStatus converts sandbox metadata into CRI pod sandbox status. -func toCRISandboxStatus(meta sandboxstore.Metadata, state runtime.PodSandboxState, createdAt time.Time, ip string) *runtime.PodSandboxStatus { - nsOpts := meta.Config.GetLinux().GetSecurityContext().GetNamespaceOptions() - return &runtime.PodSandboxStatus{ - Id: meta.ID, - Metadata: meta.Config.GetMetadata(), - State: state, - CreatedAt: createdAt.UnixNano(), - Network: &runtime.PodSandboxNetworkStatus{Ip: ip}, - Linux: &runtime.LinuxPodSandboxStatus{ - Namespaces: &runtime.Namespace{ - Options: &runtime.NamespaceOption{ - HostNetwork: nsOpts.GetHostNetwork(), - HostPid: nsOpts.GetHostPid(), - HostIpc: nsOpts.GetHostIpc(), - }, - }, - }, - Labels: meta.Config.GetLabels(), - Annotations: meta.Config.GetAnnotations(), - } -}