k8s.io/kubernetes@v1.29.3/pkg/kubelet/container/runtime.go (about) 1 /* 2 Copyright 2015 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 //go:generate mockgen -source=runtime.go -destination=testing/runtime_mock.go -package=testing Runtime 18 package container 19 20 import ( 21 "context" 22 "fmt" 23 "io" 24 "net/url" 25 "reflect" 26 "strings" 27 "time" 28 29 v1 "k8s.io/api/core/v1" 30 "k8s.io/apimachinery/pkg/api/resource" 31 "k8s.io/apimachinery/pkg/types" 32 "k8s.io/client-go/tools/remotecommand" 33 "k8s.io/client-go/util/flowcontrol" 34 runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" 35 "k8s.io/klog/v2" 36 "k8s.io/kubernetes/pkg/volume" 37 ) 38 39 // Version interface allow to consume the runtime versions - compare and format to string. 40 type Version interface { 41 // Compare compares two versions of the runtime. On success it returns -1 42 // if the version is less than the other, 1 if it is greater than the other, 43 // or 0 if they are equal. 44 Compare(other string) (int, error) 45 // String returns a string that represents the version. 46 String() string 47 } 48 49 // ImageSpec is an internal representation of an image. Currently, it wraps the 50 // value of a Container's Image field, but in the future it will include more detailed 51 // information about the different image types. 52 type ImageSpec struct { 53 // ID of the image. 54 Image string 55 // Runtime handler used to pull this image 56 RuntimeHandler string 57 // The annotations for the image. 58 // This should be passed to CRI during image pulls and returned when images are listed. 59 Annotations []Annotation 60 } 61 62 // ImageStats contains statistics about all the images currently available. 63 type ImageStats struct { 64 // Total amount of storage consumed by existing images. 65 TotalStorageBytes uint64 66 } 67 68 // Runtime interface defines the interfaces that should be implemented 69 // by a container runtime. 70 // Thread safety is required from implementations of this interface. 71 type Runtime interface { 72 // Type returns the type of the container runtime. 73 Type() string 74 75 // Version returns the version information of the container runtime. 76 Version(ctx context.Context) (Version, error) 77 78 // APIVersion returns the cached API version information of the container 79 // runtime. Implementation is expected to update this cache periodically. 80 // This may be different from the runtime engine's version. 81 // TODO(random-liu): We should fold this into Version() 82 APIVersion() (Version, error) 83 // Status returns the status of the runtime. An error is returned if the Status 84 // function itself fails, nil otherwise. 85 Status(ctx context.Context) (*RuntimeStatus, error) 86 // GetPods returns a list of containers grouped by pods. The boolean parameter 87 // specifies whether the runtime returns all containers including those already 88 // exited and dead containers (used for garbage collection). 89 GetPods(ctx context.Context, all bool) ([]*Pod, error) 90 // GarbageCollect removes dead containers using the specified container gc policy 91 // If allSourcesReady is not true, it means that kubelet doesn't have the 92 // complete list of pods from all available sources (e.g., apiserver, http, 93 // file). In this case, garbage collector should refrain itself from aggressive 94 // behavior such as removing all containers of unrecognized pods (yet). 95 // If evictNonDeletedPods is set to true, containers and sandboxes belonging to pods 96 // that are terminated, but not deleted will be evicted. Otherwise, only deleted pods 97 // will be GC'd. 98 // TODO: Revisit this method and make it cleaner. 99 GarbageCollect(ctx context.Context, gcPolicy GCPolicy, allSourcesReady bool, evictNonDeletedPods bool) error 100 // SyncPod syncs the running pod into the desired pod. 101 SyncPod(ctx context.Context, pod *v1.Pod, podStatus *PodStatus, pullSecrets []v1.Secret, backOff *flowcontrol.Backoff) PodSyncResult 102 // KillPod kills all the containers of a pod. Pod may be nil, running pod must not be. 103 // TODO(random-liu): Return PodSyncResult in KillPod. 104 // gracePeriodOverride if specified allows the caller to override the pod default grace period. 105 // only hard kill paths are allowed to specify a gracePeriodOverride in the kubelet in order to not corrupt user data. 106 // it is useful when doing SIGKILL for hard eviction scenarios, or max grace period during soft eviction scenarios. 107 KillPod(ctx context.Context, pod *v1.Pod, runningPod Pod, gracePeriodOverride *int64) error 108 // GetPodStatus retrieves the status of the pod, including the 109 // information of all containers in the pod that are visible in Runtime. 110 GetPodStatus(ctx context.Context, uid types.UID, name, namespace string) (*PodStatus, error) 111 // TODO(vmarmol): Unify pod and containerID args. 112 // GetContainerLogs returns logs of a specific container. By 113 // default, it returns a snapshot of the container log. Set 'follow' to true to 114 // stream the log. Set 'follow' to false and specify the number of lines (e.g. 115 // "100" or "all") to tail the log. 116 GetContainerLogs(ctx context.Context, pod *v1.Pod, containerID ContainerID, logOptions *v1.PodLogOptions, stdout, stderr io.Writer) (err error) 117 // DeleteContainer deletes a container. If the container is still running, an error is returned. 118 DeleteContainer(ctx context.Context, containerID ContainerID) error 119 // ImageService provides methods to image-related methods. 120 ImageService 121 // UpdatePodCIDR sends a new podCIDR to the runtime. 122 // This method just proxies a new runtimeConfig with the updated 123 // CIDR value down to the runtime shim. 124 UpdatePodCIDR(ctx context.Context, podCIDR string) error 125 // CheckpointContainer tells the runtime to checkpoint a container 126 // and store the resulting archive to the checkpoint directory. 127 CheckpointContainer(ctx context.Context, options *runtimeapi.CheckpointContainerRequest) error 128 // Generate pod status from the CRI event 129 GeneratePodStatus(event *runtimeapi.ContainerEventResponse) (*PodStatus, error) 130 // ListMetricDescriptors gets the descriptors for the metrics that will be returned in ListPodSandboxMetrics. 131 // This list should be static at startup: either the client and server restart together when 132 // adding or removing metrics descriptors, or they should not change. 133 // Put differently, if ListPodSandboxMetrics references a name that is not described in the initial 134 // ListMetricDescriptors call, then the metric will not be broadcasted. 135 ListMetricDescriptors(ctx context.Context) ([]*runtimeapi.MetricDescriptor, error) 136 // ListPodSandboxMetrics retrieves the metrics for all pod sandboxes. 137 ListPodSandboxMetrics(ctx context.Context) ([]*runtimeapi.PodSandboxMetrics, error) 138 } 139 140 // StreamingRuntime is the interface implemented by runtimes that handle the serving of the 141 // streaming calls (exec/attach/port-forward) themselves. In this case, Kubelet should redirect to 142 // the runtime server. 143 type StreamingRuntime interface { 144 GetExec(ctx context.Context, id ContainerID, cmd []string, stdin, stdout, stderr, tty bool) (*url.URL, error) 145 GetAttach(ctx context.Context, id ContainerID, stdin, stdout, stderr, tty bool) (*url.URL, error) 146 GetPortForward(ctx context.Context, podName, podNamespace string, podUID types.UID, ports []int32) (*url.URL, error) 147 } 148 149 // ImageService interfaces allows to work with image service. 150 type ImageService interface { 151 // PullImage pulls an image from the network to local storage using the supplied 152 // secrets if necessary. It returns a reference (digest or ID) to the pulled image. 153 PullImage(ctx context.Context, image ImageSpec, pullSecrets []v1.Secret, podSandboxConfig *runtimeapi.PodSandboxConfig) (string, error) 154 // GetImageRef gets the reference (digest or ID) of the image which has already been in 155 // the local storage. It returns ("", nil) if the image isn't in the local storage. 156 GetImageRef(ctx context.Context, image ImageSpec) (string, error) 157 // ListImages gets all images currently on the machine. 158 ListImages(ctx context.Context) ([]Image, error) 159 // RemoveImage removes the specified image. 160 RemoveImage(ctx context.Context, image ImageSpec) error 161 // ImageStats returns Image statistics. 162 ImageStats(ctx context.Context) (*ImageStats, error) 163 // ImageFsInfo returns a list of file systems for containers/images 164 ImageFsInfo(ctx context.Context) (*runtimeapi.ImageFsInfoResponse, error) 165 } 166 167 // Attacher interface allows to attach a container. 168 type Attacher interface { 169 AttachContainer(ctx context.Context, id ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) (err error) 170 } 171 172 // CommandRunner interface allows to run command in a container. 173 type CommandRunner interface { 174 // RunInContainer synchronously executes the command in the container, and returns the output. 175 // If the command completes with a non-0 exit code, a k8s.io/utils/exec.ExitError will be returned. 176 RunInContainer(ctx context.Context, id ContainerID, cmd []string, timeout time.Duration) ([]byte, error) 177 } 178 179 // Pod is a group of containers. 180 type Pod struct { 181 // The ID of the pod, which can be used to retrieve a particular pod 182 // from the pod list returned by GetPods(). 183 ID types.UID 184 // The name and namespace of the pod, which is readable by human. 185 Name string 186 Namespace string 187 // Creation timestamps of the Pod in nanoseconds. 188 CreatedAt uint64 189 // List of containers that belongs to this pod. It may contain only 190 // running containers, or mixed with dead ones (when GetPods(true)). 191 Containers []*Container 192 // List of sandboxes associated with this pod. The sandboxes are converted 193 // to Container temporarily to avoid substantial changes to other 194 // components. This is only populated by kuberuntime. 195 // TODO: use the runtimeApi.PodSandbox type directly. 196 Sandboxes []*Container 197 } 198 199 // PodPair contains both runtime#Pod and api#Pod 200 type PodPair struct { 201 // APIPod is the v1.Pod 202 APIPod *v1.Pod 203 // RunningPod is the pod defined in pkg/kubelet/container/runtime#Pod 204 RunningPod *Pod 205 } 206 207 // ContainerID is a type that identifies a container. 208 type ContainerID struct { 209 // The type of the container runtime. e.g. 'docker'. 210 Type string 211 // The identification of the container, this is comsumable by 212 // the underlying container runtime. (Note that the container 213 // runtime interface still takes the whole struct as input). 214 ID string 215 } 216 217 // BuildContainerID returns the ContainerID given type and id. 218 func BuildContainerID(typ, ID string) ContainerID { 219 return ContainerID{Type: typ, ID: ID} 220 } 221 222 // ParseContainerID is a convenience method for creating a ContainerID from an ID string. 223 func ParseContainerID(containerID string) ContainerID { 224 var id ContainerID 225 if err := id.ParseString(containerID); err != nil { 226 klog.ErrorS(err, "Parsing containerID failed") 227 } 228 return id 229 } 230 231 // ParseString converts given string into ContainerID 232 func (c *ContainerID) ParseString(data string) error { 233 // Trim the quotes and split the type and ID. 234 parts := strings.Split(strings.Trim(data, "\""), "://") 235 if len(parts) != 2 { 236 return fmt.Errorf("invalid container ID: %q", data) 237 } 238 c.Type, c.ID = parts[0], parts[1] 239 return nil 240 } 241 242 func (c *ContainerID) String() string { 243 return fmt.Sprintf("%s://%s", c.Type, c.ID) 244 } 245 246 // IsEmpty returns whether given ContainerID is empty. 247 func (c *ContainerID) IsEmpty() bool { 248 return *c == ContainerID{} 249 } 250 251 // MarshalJSON formats a given ContainerID into a byte array. 252 func (c *ContainerID) MarshalJSON() ([]byte, error) { 253 return []byte(fmt.Sprintf("%q", c.String())), nil 254 } 255 256 // UnmarshalJSON parses ContainerID from a given array of bytes. 257 func (c *ContainerID) UnmarshalJSON(data []byte) error { 258 return c.ParseString(string(data)) 259 } 260 261 // State represents the state of a container 262 type State string 263 264 const ( 265 // ContainerStateCreated indicates a container that has been created (e.g. with docker create) but not started. 266 ContainerStateCreated State = "created" 267 // ContainerStateRunning indicates a currently running container. 268 ContainerStateRunning State = "running" 269 // ContainerStateExited indicates a container that ran and completed ("stopped" in other contexts, although a created container is technically also "stopped"). 270 ContainerStateExited State = "exited" 271 // ContainerStateUnknown encompasses all the states that we currently don't care about (like restarting, paused, dead). 272 ContainerStateUnknown State = "unknown" 273 ) 274 275 // Container provides the runtime information for a container, such as ID, hash, 276 // state of the container. 277 type Container struct { 278 // The ID of the container, used by the container runtime to identify 279 // a container. 280 ID ContainerID 281 // The name of the container, which should be the same as specified by 282 // v1.Container. 283 Name string 284 // The image name of the container, this also includes the tag of the image, 285 // the expected form is "NAME:TAG". 286 Image string 287 // The id of the image used by the container. 288 ImageID string 289 // Runtime handler used to pull the image if any. 290 ImageRuntimeHandler string 291 // Hash of the container, used for comparison. Optional for containers 292 // not managed by kubelet. 293 Hash uint64 294 // Hash of the container over fields with Resources field zero'd out. 295 // NOTE: This is needed during alpha and beta so that containers using Resources are 296 // not unexpectedly restarted when InPlacePodVerticalScaling feature-gate is toggled. 297 //TODO(vinaykul,InPlacePodVerticalScaling): Remove this in GA+1 and make HashWithoutResources to become Hash. 298 HashWithoutResources uint64 299 // State is the state of the container. 300 State State 301 } 302 303 // PodStatus represents the status of the pod and its containers. 304 // v1.PodStatus can be derived from examining PodStatus and v1.Pod. 305 type PodStatus struct { 306 // ID of the pod. 307 ID types.UID 308 // Name of the pod. 309 Name string 310 // Namespace of the pod. 311 Namespace string 312 // All IPs assigned to this pod 313 IPs []string 314 // Status of containers in the pod. 315 ContainerStatuses []*Status 316 // Status of the pod sandbox. 317 // Only for kuberuntime now, other runtime may keep it nil. 318 SandboxStatuses []*runtimeapi.PodSandboxStatus 319 // Timestamp at which container and pod statuses were recorded 320 TimeStamp time.Time 321 } 322 323 // ContainerResources represents the Resources allocated to the running container. 324 type ContainerResources struct { 325 // CPU capacity reserved for the container 326 CPURequest *resource.Quantity 327 // CPU limit enforced on the container 328 CPULimit *resource.Quantity 329 // Memory capaacity reserved for the container 330 MemoryRequest *resource.Quantity 331 // Memory limit enforced on the container 332 MemoryLimit *resource.Quantity 333 } 334 335 // Status represents the status of a container. 336 type Status struct { 337 // ID of the container. 338 ID ContainerID 339 // Name of the container. 340 Name string 341 // Status of the container. 342 State State 343 // Creation time of the container. 344 CreatedAt time.Time 345 // Start time of the container. 346 StartedAt time.Time 347 // Finish time of the container. 348 FinishedAt time.Time 349 // Exit code of the container. 350 ExitCode int 351 // Name of the image, this also includes the tag of the image, 352 // the expected form is "NAME:TAG". 353 Image string 354 // ID of the image. 355 ImageID string 356 // Runtime handler used to pull the image if any. 357 ImageRuntimeHandler string 358 // Hash of the container, used for comparison. 359 Hash uint64 360 // Hash of the container over fields with Resources field zero'd out. 361 HashWithoutResources uint64 362 // Number of times that the container has been restarted. 363 RestartCount int 364 // A string explains why container is in such a status. 365 Reason string 366 // Message written by the container before exiting (stored in 367 // TerminationMessagePath). 368 Message string 369 // CPU and memory resources for this container 370 Resources *ContainerResources 371 } 372 373 // FindContainerStatusByName returns container status in the pod status with the given name. 374 // When there are multiple containers' statuses with the same name, the first match will be returned. 375 func (podStatus *PodStatus) FindContainerStatusByName(containerName string) *Status { 376 for _, containerStatus := range podStatus.ContainerStatuses { 377 if containerStatus.Name == containerName { 378 return containerStatus 379 } 380 } 381 return nil 382 } 383 384 // GetRunningContainerStatuses returns container status of all the running containers in a pod 385 func (podStatus *PodStatus) GetRunningContainerStatuses() []*Status { 386 runningContainerStatuses := []*Status{} 387 for _, containerStatus := range podStatus.ContainerStatuses { 388 if containerStatus.State == ContainerStateRunning { 389 runningContainerStatuses = append(runningContainerStatuses, containerStatus) 390 } 391 } 392 return runningContainerStatuses 393 } 394 395 // Image contains basic information about a container image. 396 type Image struct { 397 // ID of the image. 398 ID string 399 // Other names by which this image is known. 400 RepoTags []string 401 // Digests by which this image is known. 402 RepoDigests []string 403 // The size of the image in bytes. 404 Size int64 405 // ImageSpec for the image which include annotations. 406 Spec ImageSpec 407 // Pin for preventing garbage collection 408 Pinned bool 409 } 410 411 // EnvVar represents the environment variable. 412 type EnvVar struct { 413 Name string 414 Value string 415 } 416 417 // Annotation represents an annotation. 418 type Annotation struct { 419 Name string 420 Value string 421 } 422 423 // Mount represents a volume mount. 424 type Mount struct { 425 // Name of the volume mount. 426 // TODO(yifan): Remove this field, as this is not representing the unique name of the mount, 427 // but the volume name only. 428 Name string 429 // Path of the mount within the container. 430 ContainerPath string 431 // Path of the mount on the host. 432 HostPath string 433 // Whether the mount is read-only. 434 ReadOnly bool 435 // Whether the mount needs SELinux relabeling 436 SELinuxRelabel bool 437 // Requested propagation mode 438 Propagation runtimeapi.MountPropagation 439 } 440 441 // PortMapping contains information about the port mapping. 442 type PortMapping struct { 443 // Protocol of the port mapping. 444 Protocol v1.Protocol 445 // The port number within the container. 446 ContainerPort int 447 // The port number on the host. 448 HostPort int 449 // The host IP. 450 HostIP string 451 } 452 453 // DeviceInfo contains information about the device. 454 type DeviceInfo struct { 455 // Path on host for mapping 456 PathOnHost string 457 // Path in Container to map 458 PathInContainer string 459 // Cgroup permissions 460 Permissions string 461 } 462 463 // CDIDevice contains information about CDI device 464 type CDIDevice struct { 465 // Name is a fully qualified device name 466 Name string 467 } 468 469 // RunContainerOptions specify the options which are necessary for running containers 470 type RunContainerOptions struct { 471 // The environment variables list. 472 Envs []EnvVar 473 // The mounts for the containers. 474 Mounts []Mount 475 // The host devices mapped into the containers. 476 Devices []DeviceInfo 477 // The CDI devices for the container 478 CDIDevices []CDIDevice 479 // The annotations for the container 480 // These annotations are generated by other components (i.e., 481 // not users). Currently, only device plugins populate the annotations. 482 Annotations []Annotation 483 // If the container has specified the TerminationMessagePath, then 484 // this directory will be used to create and mount the log file to 485 // container.TerminationMessagePath 486 PodContainerDir string 487 // The type of container rootfs 488 ReadOnly bool 489 // hostname for pod containers 490 Hostname string 491 } 492 493 // VolumeInfo contains information about the volume. 494 type VolumeInfo struct { 495 // Mounter is the volume's mounter 496 Mounter volume.Mounter 497 // BlockVolumeMapper is the Block volume's mapper 498 BlockVolumeMapper volume.BlockVolumeMapper 499 // SELinuxLabeled indicates whether this volume has had the 500 // pod's SELinux label applied to it or not 501 SELinuxLabeled bool 502 // Whether the volume permission is set to read-only or not 503 // This value is passed from volume.spec 504 ReadOnly bool 505 // Inner volume spec name, which is the PV name if used, otherwise 506 // it is the same as the outer volume spec name. 507 InnerVolumeSpecName string 508 } 509 510 // VolumeMap represents the map of volumes. 511 type VolumeMap map[string]VolumeInfo 512 513 // RuntimeConditionType is the types of required runtime conditions. 514 type RuntimeConditionType string 515 516 const ( 517 // RuntimeReady means the runtime is up and ready to accept basic containers. 518 RuntimeReady RuntimeConditionType = "RuntimeReady" 519 // NetworkReady means the runtime network is up and ready to accept containers which require network. 520 NetworkReady RuntimeConditionType = "NetworkReady" 521 ) 522 523 // RuntimeStatus contains the status of the runtime. 524 type RuntimeStatus struct { 525 // Conditions is an array of current observed runtime conditions. 526 Conditions []RuntimeCondition 527 } 528 529 // GetRuntimeCondition gets a specified runtime condition from the runtime status. 530 func (r *RuntimeStatus) GetRuntimeCondition(t RuntimeConditionType) *RuntimeCondition { 531 for i := range r.Conditions { 532 c := &r.Conditions[i] 533 if c.Type == t { 534 return c 535 } 536 } 537 return nil 538 } 539 540 // String formats the runtime status into human readable string. 541 func (r *RuntimeStatus) String() string { 542 var ss []string 543 for _, c := range r.Conditions { 544 ss = append(ss, c.String()) 545 } 546 return fmt.Sprintf("Runtime Conditions: %s", strings.Join(ss, ", ")) 547 } 548 549 // RuntimeCondition contains condition information for the runtime. 550 type RuntimeCondition struct { 551 // Type of runtime condition. 552 Type RuntimeConditionType 553 // Status of the condition, one of true/false. 554 Status bool 555 // Reason is brief reason for the condition's last transition. 556 Reason string 557 // Message is human readable message indicating details about last transition. 558 Message string 559 } 560 561 // String formats the runtime condition into human readable string. 562 func (c *RuntimeCondition) String() string { 563 return fmt.Sprintf("%s=%t reason:%s message:%s", c.Type, c.Status, c.Reason, c.Message) 564 } 565 566 // Pods represents the list of pods 567 type Pods []*Pod 568 569 // FindPodByID finds and returns a pod in the pod list by UID. It will return an empty pod 570 // if not found. 571 func (p Pods) FindPodByID(podUID types.UID) Pod { 572 for i := range p { 573 if p[i].ID == podUID { 574 return *p[i] 575 } 576 } 577 return Pod{} 578 } 579 580 // FindPodByFullName finds and returns a pod in the pod list by the full name. 581 // It will return an empty pod if not found. 582 func (p Pods) FindPodByFullName(podFullName string) Pod { 583 for i := range p { 584 if BuildPodFullName(p[i].Name, p[i].Namespace) == podFullName { 585 return *p[i] 586 } 587 } 588 return Pod{} 589 } 590 591 // FindPod combines FindPodByID and FindPodByFullName, it finds and returns a pod in the 592 // pod list either by the full name or the pod ID. It will return an empty pod 593 // if not found. 594 func (p Pods) FindPod(podFullName string, podUID types.UID) Pod { 595 if len(podFullName) > 0 { 596 return p.FindPodByFullName(podFullName) 597 } 598 return p.FindPodByID(podUID) 599 } 600 601 // FindContainerByName returns a container in the pod with the given name. 602 // When there are multiple containers with the same name, the first match will 603 // be returned. 604 func (p *Pod) FindContainerByName(containerName string) *Container { 605 for _, c := range p.Containers { 606 if c.Name == containerName { 607 return c 608 } 609 } 610 return nil 611 } 612 613 // FindContainerByID returns a container in the pod with the given ContainerID. 614 func (p *Pod) FindContainerByID(id ContainerID) *Container { 615 for _, c := range p.Containers { 616 if c.ID == id { 617 return c 618 } 619 } 620 return nil 621 } 622 623 // FindSandboxByID returns a sandbox in the pod with the given ContainerID. 624 func (p *Pod) FindSandboxByID(id ContainerID) *Container { 625 for _, c := range p.Sandboxes { 626 if c.ID == id { 627 return c 628 } 629 } 630 return nil 631 } 632 633 // ToAPIPod converts Pod to v1.Pod. Note that if a field in v1.Pod has no 634 // corresponding field in Pod, the field would not be populated. 635 func (p *Pod) ToAPIPod() *v1.Pod { 636 var pod v1.Pod 637 pod.UID = p.ID 638 pod.Name = p.Name 639 pod.Namespace = p.Namespace 640 641 for _, c := range p.Containers { 642 var container v1.Container 643 container.Name = c.Name 644 container.Image = c.Image 645 pod.Spec.Containers = append(pod.Spec.Containers, container) 646 } 647 return &pod 648 } 649 650 // IsEmpty returns true if the pod is empty. 651 func (p *Pod) IsEmpty() bool { 652 return reflect.DeepEqual(p, &Pod{}) 653 } 654 655 // GetPodFullName returns a name that uniquely identifies a pod. 656 func GetPodFullName(pod *v1.Pod) string { 657 // Use underscore as the delimiter because it is not allowed in pod name 658 // (DNS subdomain format), while allowed in the container name format. 659 return pod.Name + "_" + pod.Namespace 660 } 661 662 // BuildPodFullName builds the pod full name from pod name and namespace. 663 func BuildPodFullName(name, namespace string) string { 664 return name + "_" + namespace 665 } 666 667 // ParsePodFullName parsed the pod full name. 668 func ParsePodFullName(podFullName string) (string, string, error) { 669 parts := strings.Split(podFullName, "_") 670 if len(parts) != 2 || parts[0] == "" || parts[1] == "" { 671 return "", "", fmt.Errorf("failed to parse the pod full name %q", podFullName) 672 } 673 return parts[0], parts[1], nil 674 } 675 676 // Option is a functional option type for Runtime, useful for 677 // completely optional settings. 678 type Option func(Runtime) 679 680 // SortContainerStatusesByCreationTime sorts the container statuses by creation time. 681 type SortContainerStatusesByCreationTime []*Status 682 683 func (s SortContainerStatusesByCreationTime) Len() int { return len(s) } 684 func (s SortContainerStatusesByCreationTime) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 685 func (s SortContainerStatusesByCreationTime) Less(i, j int) bool { 686 return s[i].CreatedAt.Before(s[j].CreatedAt) 687 } 688 689 const ( 690 // MaxPodTerminationMessageLogLength is the maximum bytes any one pod may have written 691 // as termination message output across all containers. Containers will be evenly truncated 692 // until output is below this limit. 693 MaxPodTerminationMessageLogLength = 1024 * 12 694 // MaxContainerTerminationMessageLength is the upper bound any one container may write to 695 // its termination message path. Contents above this length will be truncated. 696 MaxContainerTerminationMessageLength = 1024 * 4 697 // MaxContainerTerminationMessageLogLength is the maximum bytes any one container will 698 // have written to its termination message when the message is read from the logs. 699 MaxContainerTerminationMessageLogLength = 1024 * 2 700 // MaxContainerTerminationMessageLogLines is the maximum number of previous lines of 701 // log output that the termination message can contain. 702 MaxContainerTerminationMessageLogLines = 80 703 )