2015-03-11 21:53:36 +00:00
|
|
|
/*
|
2015-05-01 16:19:44 +00:00
|
|
|
Copyright 2015 The Kubernetes Authors All rights reserved.
|
2015-03-11 21:53:36 +00:00
|
|
|
|
|
|
|
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 container
|
|
|
|
|
|
|
|
import (
|
2015-03-23 17:14:30 +00:00
|
|
|
"fmt"
|
2015-04-23 01:09:24 +00:00
|
|
|
"io"
|
2015-06-05 21:10:45 +00:00
|
|
|
"reflect"
|
2015-03-23 17:14:30 +00:00
|
|
|
"strings"
|
2015-11-10 22:18:47 +00:00
|
|
|
"time"
|
2015-03-23 17:14:30 +00:00
|
|
|
|
2015-10-07 17:58:05 +00:00
|
|
|
"github.com/golang/glog"
|
2015-08-05 22:03:47 +00:00
|
|
|
"k8s.io/kubernetes/pkg/api"
|
|
|
|
"k8s.io/kubernetes/pkg/types"
|
2016-03-09 02:58:24 +00:00
|
|
|
"k8s.io/kubernetes/pkg/util/flowcontrol"
|
2015-08-05 22:03:47 +00:00
|
|
|
"k8s.io/kubernetes/pkg/volume"
|
2015-03-11 21:53:36 +00:00
|
|
|
)
|
|
|
|
|
2015-04-21 20:02:50 +00:00
|
|
|
type Version interface {
|
|
|
|
// Compare compares two versions of the runtime. On success it returns -1
|
|
|
|
// if the version is less than the other, 1 if it is greater than the other,
|
|
|
|
// or 0 if they are equal.
|
|
|
|
Compare(other string) (int, error)
|
|
|
|
// String returns a string that represents the version.
|
|
|
|
String() string
|
|
|
|
}
|
|
|
|
|
2015-05-06 21:42:03 +00:00
|
|
|
// ImageSpec is an internal representation of an image. Currently, it wraps the
|
|
|
|
// value of a Container's Image field, but in the future it will include more detailed
|
|
|
|
// information about the different image types.
|
|
|
|
type ImageSpec struct {
|
|
|
|
Image string
|
|
|
|
}
|
|
|
|
|
2016-03-29 00:05:02 +00:00
|
|
|
// ImageStats contains statistics about all the images currently available.
|
|
|
|
type ImageStats struct {
|
|
|
|
// Total amount of storage consumed by existing images.
|
|
|
|
TotalStorageBytes uint64
|
|
|
|
}
|
|
|
|
|
2015-03-11 21:53:36 +00:00
|
|
|
// Runtime interface defines the interfaces that should be implemented
|
|
|
|
// by a container runtime.
|
2015-10-20 00:35:33 +00:00
|
|
|
// Thread safety is required from implementations of this interface.
|
2015-03-11 21:53:36 +00:00
|
|
|
type Runtime interface {
|
2015-10-21 20:04:10 +00:00
|
|
|
// Type returns the type of the container runtime.
|
|
|
|
Type() string
|
|
|
|
|
2015-04-21 20:02:50 +00:00
|
|
|
// Version returns the version information of the container runtime.
|
|
|
|
Version() (Version, error)
|
2016-02-26 09:06:26 +00:00
|
|
|
|
|
|
|
// APIVersion returns the cached API version information of the container
|
|
|
|
// runtime. Implementation is expected to update this cache periodically.
|
|
|
|
// This may be different from the runtime engine's version.
|
2016-03-03 10:01:15 +00:00
|
|
|
// TODO(random-liu): We should fold this into Version()
|
2016-01-14 23:16:07 +00:00
|
|
|
APIVersion() (Version, error)
|
2016-03-03 10:01:15 +00:00
|
|
|
// Status returns error if the runtime is unhealthy; nil otherwise.
|
|
|
|
Status() error
|
2015-03-11 21:53:36 +00:00
|
|
|
// GetPods returns a list containers group by pods. The boolean parameter
|
|
|
|
// specifies whether the runtime returns all containers including those already
|
|
|
|
// exited and dead containers (used for garbage collection).
|
|
|
|
GetPods(all bool) ([]*Pod, error)
|
2015-10-05 22:35:32 +00:00
|
|
|
// GarbageCollect removes dead containers using the specified container gc policy
|
|
|
|
GarbageCollect(gcPolicy ContainerGCPolicy) error
|
2015-04-30 23:48:15 +00:00
|
|
|
// Syncs the running pod into the desired pod.
|
2016-03-09 02:58:24 +00:00
|
|
|
SyncPod(pod *api.Pod, apiPodStatus api.PodStatus, podStatus *PodStatus, pullSecrets []api.Secret, backOff *flowcontrol.Backoff) PodSyncResult
|
2015-08-20 01:57:58 +00:00
|
|
|
// KillPod kills all the containers of a pod. Pod may be nil, running pod must not be.
|
2016-01-12 10:19:13 +00:00
|
|
|
// TODO(random-liu): Return PodSyncResult in KillPod.
|
2016-04-27 03:30:59 +00:00
|
|
|
// gracePeriodOverride if specified allows the caller to override the pod default grace period.
|
|
|
|
// only hard kill paths are allowed to specify a gracePeriodOverride in the kubelet in order to not corrupt user data.
|
|
|
|
// it is useful when doing SIGKILL for hard eviction scenarios, or max grace period during soft eviction scenarios.
|
|
|
|
KillPod(pod *api.Pod, runningPod Pod, gracePeriodOverride *int64) error
|
2015-12-05 00:06:25 +00:00
|
|
|
// GetPodStatus retrieves the status of the pod, including the
|
2015-11-10 22:18:47 +00:00
|
|
|
// information of all containers in the pod that are visble in Runtime.
|
2015-12-05 00:06:25 +00:00
|
|
|
GetPodStatus(uid types.UID, name, namespace string) (*PodStatus, error)
|
2015-05-06 21:42:03 +00:00
|
|
|
// PullImage pulls an image from the network to local storage using the supplied
|
|
|
|
// secrets if necessary.
|
2015-05-08 17:53:00 +00:00
|
|
|
PullImage(image ImageSpec, pullSecrets []api.Secret) error
|
2015-04-23 17:35:14 +00:00
|
|
|
// IsImagePresent checks whether the container image is already in the local storage.
|
2015-05-06 21:42:03 +00:00
|
|
|
IsImagePresent(image ImageSpec) (bool, error)
|
2015-04-29 23:00:36 +00:00
|
|
|
// Gets all images currently on the machine.
|
|
|
|
ListImages() ([]Image, error)
|
|
|
|
// Removes the specified image.
|
2015-05-06 21:42:03 +00:00
|
|
|
RemoveImage(image ImageSpec) error
|
2016-03-29 00:05:02 +00:00
|
|
|
// Returns Image statistics.
|
|
|
|
ImageStats() (*ImageStats, error)
|
2015-05-01 23:07:05 +00:00
|
|
|
// TODO(vmarmol): Unify pod and containerID args.
|
2015-04-29 03:25:25 +00:00
|
|
|
// GetContainerLogs returns logs of a specific container. By
|
|
|
|
// default, it returns a snapshot of the container log. Set 'follow' to true to
|
|
|
|
// stream the log. Set 'follow' to false and specify the number of lines (e.g.
|
|
|
|
// "100" or "all") to tail the log.
|
2015-10-07 17:58:05 +00:00
|
|
|
GetContainerLogs(pod *api.Pod, containerID ContainerID, logOptions *api.PodLogOptions, stdout, stderr io.Writer) (err error)
|
2015-05-11 22:32:51 +00:00
|
|
|
// ContainerCommandRunner encapsulates the command runner interfaces for testability.
|
|
|
|
ContainerCommandRunner
|
2015-07-28 04:48:55 +00:00
|
|
|
// ContainerAttach encapsulates the attaching to containers for testability
|
|
|
|
ContainerAttacher
|
|
|
|
}
|
|
|
|
|
|
|
|
type ContainerAttacher interface {
|
2015-10-07 17:58:05 +00:00
|
|
|
AttachContainer(id ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) (err error)
|
2015-05-11 22:32:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// CommandRunner encapsulates the command runner interfaces for testability.
|
|
|
|
type ContainerCommandRunner interface {
|
|
|
|
// Runs the command in the container of the specified pod using nsenter.
|
|
|
|
// Attaches the processes stdin, stdout, and stderr. Optionally uses a
|
|
|
|
// tty.
|
2015-10-07 17:58:05 +00:00
|
|
|
ExecInContainer(containerID ContainerID, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error
|
2015-05-11 22:32:51 +00:00
|
|
|
// Forward the specified port from the specified pod to the stream.
|
|
|
|
PortForward(pod *Pod, port uint16, stream io.ReadWriteCloser) error
|
2015-03-11 21:53:36 +00:00
|
|
|
}
|
|
|
|
|
2015-08-10 17:28:39 +00:00
|
|
|
// ImagePuller wraps Runtime.PullImage() to pull a container image.
|
|
|
|
// It will check the presence of the image, and report the 'image pulling',
|
|
|
|
// 'image pulled' events correspondingly.
|
|
|
|
type ImagePuller interface {
|
2015-10-02 13:45:46 +00:00
|
|
|
PullImage(pod *api.Pod, container *api.Container, pullSecrets []api.Secret) (error, string)
|
2015-04-29 20:35:37 +00:00
|
|
|
}
|
|
|
|
|
2015-11-10 22:18:47 +00:00
|
|
|
// Pod is a group of containers.
|
2015-03-11 21:53:36 +00:00
|
|
|
type Pod struct {
|
|
|
|
// The ID of the pod, which can be used to retrieve a particular pod
|
|
|
|
// from the pod list returned by GetPods().
|
|
|
|
ID types.UID
|
|
|
|
// The name and namespace of the pod, which is readable by human.
|
|
|
|
Name string
|
|
|
|
Namespace string
|
|
|
|
// List of containers that belongs to this pod. It may contain only
|
|
|
|
// running containers, or mixed with dead ones (when GetPods(true)).
|
|
|
|
Containers []*Container
|
|
|
|
}
|
|
|
|
|
2016-01-31 23:56:55 +00:00
|
|
|
// PodPair contains both runtime#Pod and api#Pod
|
|
|
|
type PodPair struct {
|
|
|
|
// APIPod is the api.Pod
|
|
|
|
APIPod *api.Pod
|
|
|
|
// RunningPod is the pod defined defined in pkg/kubelet/container/runtime#Pod
|
|
|
|
RunningPod *Pod
|
|
|
|
}
|
|
|
|
|
2015-04-22 23:19:05 +00:00
|
|
|
// ContainerID is a type that identifies a container.
|
|
|
|
type ContainerID struct {
|
|
|
|
// The type of the container runtime. e.g. 'docker', 'rkt'.
|
|
|
|
Type string
|
|
|
|
// The identification of the container, this is comsumable by
|
|
|
|
// the underlying container runtime. (Note that the container
|
|
|
|
// runtime interface still takes the whole struct as input).
|
|
|
|
ID string
|
|
|
|
}
|
|
|
|
|
|
|
|
func BuildContainerID(typ, ID string) ContainerID {
|
|
|
|
return ContainerID{Type: typ, ID: ID}
|
|
|
|
}
|
|
|
|
|
2015-10-07 17:58:05 +00:00
|
|
|
// Convenience method for creating a ContainerID from an ID string.
|
|
|
|
func ParseContainerID(containerID string) ContainerID {
|
|
|
|
var id ContainerID
|
|
|
|
if err := id.ParseString(containerID); err != nil {
|
|
|
|
glog.Error(err)
|
|
|
|
}
|
|
|
|
return id
|
|
|
|
}
|
|
|
|
|
2015-04-22 23:19:05 +00:00
|
|
|
func (c *ContainerID) ParseString(data string) error {
|
|
|
|
// Trim the quotes and split the type and ID.
|
|
|
|
parts := strings.Split(strings.Trim(data, "\""), "://")
|
|
|
|
if len(parts) != 2 {
|
|
|
|
return fmt.Errorf("invalid container ID: %q", data)
|
|
|
|
}
|
|
|
|
c.Type, c.ID = parts[0], parts[1]
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ContainerID) String() string {
|
|
|
|
return fmt.Sprintf("%s://%s", c.Type, c.ID)
|
|
|
|
}
|
|
|
|
|
2015-10-07 17:58:05 +00:00
|
|
|
func (c *ContainerID) IsEmpty() bool {
|
|
|
|
return *c == ContainerID{}
|
|
|
|
}
|
|
|
|
|
2015-04-22 23:19:05 +00:00
|
|
|
func (c *ContainerID) MarshalJSON() ([]byte, error) {
|
|
|
|
return []byte(fmt.Sprintf("%q", c.String())), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ContainerID) UnmarshalJSON(data []byte) error {
|
|
|
|
return c.ParseString(string(data))
|
|
|
|
}
|
|
|
|
|
2015-12-24 23:46:56 +00:00
|
|
|
// DockerID is an ID of docker container. It is a type to make it clear when we're working with docker container Ids
|
|
|
|
type DockerID string
|
|
|
|
|
|
|
|
func (id DockerID) ContainerID() ContainerID {
|
|
|
|
return ContainerID{
|
|
|
|
Type: "docker",
|
|
|
|
ID: string(id),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-05 00:06:25 +00:00
|
|
|
type ContainerState string
|
2015-11-06 02:19:45 +00:00
|
|
|
|
|
|
|
const (
|
2015-12-05 00:06:25 +00:00
|
|
|
ContainerStateRunning ContainerState = "running"
|
|
|
|
ContainerStateExited ContainerState = "exited"
|
|
|
|
// This unknown encompasses all the states that we currently don't care.
|
|
|
|
ContainerStateUnknown ContainerState = "unknown"
|
2015-11-06 02:19:45 +00:00
|
|
|
)
|
|
|
|
|
2015-03-11 21:53:36 +00:00
|
|
|
// Container provides the runtime information for a container, such as ID, hash,
|
2015-12-05 00:06:25 +00:00
|
|
|
// state of the container.
|
2015-03-11 21:53:36 +00:00
|
|
|
type Container struct {
|
|
|
|
// The ID of the container, used by the container runtime to identify
|
|
|
|
// a container.
|
2015-10-07 17:58:05 +00:00
|
|
|
ID ContainerID
|
2015-03-11 21:53:36 +00:00
|
|
|
// The name of the container, which should be the same as specified by
|
|
|
|
// api.Container.
|
|
|
|
Name string
|
2016-03-18 18:43:20 +00:00
|
|
|
// The image name of the container, this also includes the tag of the image,
|
|
|
|
// the expected form is "NAME:TAG".
|
2015-03-11 21:53:36 +00:00
|
|
|
Image string
|
|
|
|
// Hash of the container, used for comparison. Optional for containers
|
|
|
|
// not managed by kubelet.
|
|
|
|
Hash uint64
|
2015-12-05 00:06:25 +00:00
|
|
|
// State is the state of the container.
|
|
|
|
State ContainerState
|
2015-03-20 21:16:55 +00:00
|
|
|
}
|
|
|
|
|
2015-12-05 00:06:25 +00:00
|
|
|
// PodStatus represents the status of the pod and its containers.
|
|
|
|
// api.PodStatus can be derived from examining PodStatus and api.Pod.
|
|
|
|
type PodStatus struct {
|
2015-11-10 22:18:47 +00:00
|
|
|
// ID of the pod.
|
|
|
|
ID types.UID
|
|
|
|
// Name of the pod.
|
|
|
|
Name string
|
|
|
|
// Namspace of the pod.
|
|
|
|
Namespace string
|
|
|
|
// IP of the pod.
|
|
|
|
IP string
|
|
|
|
// Status of containers in the pod.
|
2015-12-05 00:06:25 +00:00
|
|
|
ContainerStatuses []*ContainerStatus
|
2015-11-10 22:18:47 +00:00
|
|
|
}
|
|
|
|
|
2015-12-05 00:06:25 +00:00
|
|
|
// ContainerStatus represents the status of a container.
|
|
|
|
type ContainerStatus struct {
|
2015-11-10 22:18:47 +00:00
|
|
|
// ID of the container.
|
|
|
|
ID ContainerID
|
|
|
|
// Name of the container.
|
|
|
|
Name string
|
|
|
|
// Status of the container.
|
2015-12-05 00:06:25 +00:00
|
|
|
State ContainerState
|
2015-11-10 22:18:47 +00:00
|
|
|
// Creation time of the container.
|
|
|
|
CreatedAt time.Time
|
|
|
|
// Start time of the container.
|
|
|
|
StartedAt time.Time
|
|
|
|
// Finish time of the container.
|
|
|
|
FinishedAt time.Time
|
|
|
|
// Exit code of the container.
|
|
|
|
ExitCode int
|
2016-03-18 18:43:20 +00:00
|
|
|
// Name of the image, this also includes the tag of the image,
|
|
|
|
// the expected form is "NAME:TAG".
|
2015-11-10 22:18:47 +00:00
|
|
|
Image string
|
|
|
|
// ID of the image.
|
|
|
|
ImageID string
|
|
|
|
// Hash of the container, used for comparison.
|
2015-12-05 00:06:25 +00:00
|
|
|
Hash uint64
|
2015-11-10 22:18:47 +00:00
|
|
|
// Number of times that the container has been restarted.
|
|
|
|
RestartCount int
|
|
|
|
// A string explains why container is in such a status.
|
|
|
|
Reason string
|
|
|
|
// Message written by the container before exiting (stored in
|
|
|
|
// TerminationMessagePath).
|
|
|
|
Message string
|
|
|
|
}
|
|
|
|
|
2015-12-05 00:06:25 +00:00
|
|
|
// FindContainerStatusByName returns container status in the pod status with the given name.
|
|
|
|
// When there are multiple containers' statuses with the same name, the first match will be returned.
|
|
|
|
func (podStatus *PodStatus) FindContainerStatusByName(containerName string) *ContainerStatus {
|
|
|
|
for _, containerStatus := range podStatus.ContainerStatuses {
|
|
|
|
if containerStatus.Name == containerName {
|
|
|
|
return containerStatus
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get container status of all the running containers in a pod
|
|
|
|
func (podStatus *PodStatus) GetRunningContainerStatuses() []*ContainerStatus {
|
|
|
|
runnningContainerStatues := []*ContainerStatus{}
|
|
|
|
for _, containerStatus := range podStatus.ContainerStatuses {
|
|
|
|
if containerStatus.State == ContainerStateRunning {
|
|
|
|
runnningContainerStatues = append(runnningContainerStatues, containerStatus)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return runnningContainerStatues
|
|
|
|
}
|
|
|
|
|
2015-04-29 23:00:36 +00:00
|
|
|
// Basic information about a container image.
|
|
|
|
type Image struct {
|
|
|
|
// ID of the image.
|
|
|
|
ID string
|
|
|
|
// Other names by which this image is known.
|
2015-12-02 08:53:56 +00:00
|
|
|
RepoTags []string
|
2016-05-03 17:22:39 +00:00
|
|
|
// Digests by which this image is known.
|
|
|
|
RepoDigests []string
|
2015-04-29 23:00:36 +00:00
|
|
|
// The size of the image in bytes.
|
|
|
|
Size int64
|
|
|
|
}
|
|
|
|
|
2015-05-12 21:49:35 +00:00
|
|
|
type EnvVar struct {
|
|
|
|
Name string
|
|
|
|
Value string
|
|
|
|
}
|
|
|
|
|
|
|
|
type Mount struct {
|
|
|
|
// Name of the volume mount.
|
|
|
|
Name string
|
|
|
|
// Path of the mount within the container.
|
|
|
|
ContainerPath string
|
|
|
|
// Path of the mount on the host.
|
|
|
|
HostPath string
|
|
|
|
// Whether the mount is read-only.
|
|
|
|
ReadOnly bool
|
2015-10-07 19:19:06 +00:00
|
|
|
// Whether the mount needs SELinux relabeling
|
|
|
|
SELinuxRelabel bool
|
2015-05-12 21:49:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type PortMapping struct {
|
|
|
|
// Name of the port mapping
|
|
|
|
Name string
|
|
|
|
// Protocol of the port mapping.
|
|
|
|
Protocol api.Protocol
|
|
|
|
// The port number within the container.
|
|
|
|
ContainerPort int
|
|
|
|
// The port number on the host.
|
|
|
|
HostPort int
|
|
|
|
// The host IP.
|
|
|
|
HostIP string
|
|
|
|
}
|
|
|
|
|
2015-03-26 18:59:41 +00:00
|
|
|
// RunContainerOptions specify the options which are necessary for running containers
|
|
|
|
type RunContainerOptions struct {
|
2015-05-12 21:49:35 +00:00
|
|
|
// The environment variables list.
|
|
|
|
Envs []EnvVar
|
|
|
|
// The mounts for the containers.
|
|
|
|
Mounts []Mount
|
2016-04-27 00:54:19 +00:00
|
|
|
// The host devices mapped into the containers.
|
|
|
|
Devices []string
|
2015-05-12 21:49:35 +00:00
|
|
|
// The port mappings for the containers.
|
|
|
|
PortMappings []PortMapping
|
2015-03-26 18:59:41 +00:00
|
|
|
// If the container has specified the TerminationMessagePath, then
|
|
|
|
// this directory will be used to create and mount the log file to
|
|
|
|
// container.TerminationMessagePath
|
|
|
|
PodContainerDir string
|
|
|
|
// The list of DNS servers for the container to use.
|
|
|
|
DNS []string
|
|
|
|
// The list of DNS search domains.
|
|
|
|
DNSSearch []string
|
2015-04-24 00:07:52 +00:00
|
|
|
// The parent cgroup to pass to Docker
|
|
|
|
CgroupParent string
|
2016-02-11 22:31:26 +00:00
|
|
|
// The type of container rootfs
|
|
|
|
ReadOnly bool
|
2016-02-02 18:59:54 +00:00
|
|
|
// hostname for pod containers
|
|
|
|
Hostname string
|
2015-03-26 18:59:41 +00:00
|
|
|
}
|
|
|
|
|
2015-10-07 19:19:06 +00:00
|
|
|
// VolumeInfo contains information about the volume.
|
|
|
|
type VolumeInfo struct {
|
2016-03-23 05:12:21 +00:00
|
|
|
// Mounter is the volume's mounter
|
|
|
|
Mounter volume.Mounter
|
2015-10-07 19:19:06 +00:00
|
|
|
// SELinuxLabeled indicates whether this volume has had the
|
|
|
|
// pod's SELinux label applied to it or not
|
|
|
|
SELinuxLabeled bool
|
|
|
|
}
|
|
|
|
|
|
|
|
type VolumeMap map[string]VolumeInfo
|
2015-05-06 23:50:57 +00:00
|
|
|
|
2015-03-20 21:16:55 +00:00
|
|
|
type Pods []*Pod
|
|
|
|
|
2015-04-06 23:58:34 +00:00
|
|
|
// FindPodByID finds and returns a pod in the pod list by UID. It will return an empty pod
|
2015-03-20 21:16:55 +00:00
|
|
|
// if not found.
|
|
|
|
func (p Pods) FindPodByID(podUID types.UID) Pod {
|
|
|
|
for i := range p {
|
|
|
|
if p[i].ID == podUID {
|
|
|
|
return *p[i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Pod{}
|
|
|
|
}
|
|
|
|
|
2015-04-06 23:58:34 +00:00
|
|
|
// FindPodByFullName finds and returns a pod in the pod list by the full name.
|
|
|
|
// It will return an empty pod if not found.
|
|
|
|
func (p Pods) FindPodByFullName(podFullName string) Pod {
|
|
|
|
for i := range p {
|
|
|
|
if BuildPodFullName(p[i].Name, p[i].Namespace) == podFullName {
|
|
|
|
return *p[i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Pod{}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FindPod combines FindPodByID and FindPodByFullName, it finds and returns a pod in the
|
|
|
|
// pod list either by the full name or the pod ID. It will return an empty pod
|
|
|
|
// if not found.
|
|
|
|
func (p Pods) FindPod(podFullName string, podUID types.UID) Pod {
|
|
|
|
if len(podFullName) > 0 {
|
|
|
|
return p.FindPodByFullName(podFullName)
|
|
|
|
}
|
|
|
|
return p.FindPodByID(podUID)
|
|
|
|
}
|
|
|
|
|
2015-03-20 21:16:55 +00:00
|
|
|
// FindContainerByName returns a container in the pod with the given name.
|
|
|
|
// When there are multiple containers with the same name, the first match will
|
|
|
|
// be returned.
|
|
|
|
func (p *Pod) FindContainerByName(containerName string) *Container {
|
|
|
|
for _, c := range p.Containers {
|
|
|
|
if c.Name == containerName {
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
2015-03-11 21:53:36 +00:00
|
|
|
}
|
2015-03-23 17:14:30 +00:00
|
|
|
|
2016-01-07 18:34:47 +00:00
|
|
|
func (p *Pod) FindContainerByID(id ContainerID) *Container {
|
|
|
|
for _, c := range p.Containers {
|
|
|
|
if c.ID == id {
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2015-06-23 23:01:12 +00:00
|
|
|
// ToAPIPod converts Pod to api.Pod. Note that if a field in api.Pod has no
|
|
|
|
// corresponding field in Pod, the field would not be populated.
|
|
|
|
func (p *Pod) ToAPIPod() *api.Pod {
|
|
|
|
var pod api.Pod
|
|
|
|
pod.UID = p.ID
|
|
|
|
pod.Name = p.Name
|
|
|
|
pod.Namespace = p.Namespace
|
|
|
|
|
|
|
|
for _, c := range p.Containers {
|
|
|
|
var container api.Container
|
|
|
|
container.Name = c.Name
|
|
|
|
container.Image = c.Image
|
|
|
|
pod.Spec.Containers = append(pod.Spec.Containers, container)
|
|
|
|
}
|
|
|
|
return &pod
|
|
|
|
}
|
|
|
|
|
2015-06-05 21:10:45 +00:00
|
|
|
// IsEmpty returns true if the pod is empty.
|
|
|
|
func (p *Pod) IsEmpty() bool {
|
|
|
|
return reflect.DeepEqual(p, &Pod{})
|
|
|
|
}
|
|
|
|
|
2015-03-23 17:14:30 +00:00
|
|
|
// GetPodFullName returns a name that uniquely identifies a pod.
|
|
|
|
func GetPodFullName(pod *api.Pod) string {
|
|
|
|
// Use underscore as the delimiter because it is not allowed in pod name
|
|
|
|
// (DNS subdomain format), while allowed in the container name format.
|
2015-10-29 08:22:33 +00:00
|
|
|
return pod.Name + "_" + pod.Namespace
|
2015-03-23 17:14:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Build the pod full name from pod name and namespace.
|
|
|
|
func BuildPodFullName(name, namespace string) string {
|
|
|
|
return name + "_" + namespace
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse the pod full name.
|
|
|
|
func ParsePodFullName(podFullName string) (string, string, error) {
|
|
|
|
parts := strings.Split(podFullName, "_")
|
|
|
|
if len(parts) != 2 {
|
|
|
|
return "", "", fmt.Errorf("failed to parse the pod full name %q", podFullName)
|
|
|
|
}
|
|
|
|
return parts[0], parts[1], nil
|
|
|
|
}
|
2016-02-05 15:47:06 +00:00
|
|
|
|
|
|
|
// Option is a functional option type for Runtime, useful for
|
|
|
|
// completely optional settings.
|
|
|
|
type Option func(Runtime)
|
2016-02-26 00:18:34 +00:00
|
|
|
|
|
|
|
// Sort the container statuses by creation time.
|
|
|
|
type SortContainerStatusesByCreationTime []*ContainerStatus
|
|
|
|
|
|
|
|
func (s SortContainerStatusesByCreationTime) Len() int { return len(s) }
|
|
|
|
func (s SortContainerStatusesByCreationTime) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
|
|
|
func (s SortContainerStatusesByCreationTime) Less(i, j int) bool {
|
|
|
|
return s[i].CreatedAt.Before(s[j].CreatedAt)
|
|
|
|
}
|