2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/ * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								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  kubelet 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"bytes" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"fmt" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"io" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"io/ioutil" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"net/http" 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 08:42:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"net/url" 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									"os" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"path" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"path/filepath" 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-24 22:49:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"runtime" 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									"sort" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"strings" 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-24 01:44:26 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"time" 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"github.com/golang/glog" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/api" 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/api/v1" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									utilpod  "k8s.io/kubernetes/pkg/api/v1/pod" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/api/v1/validation" 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-04 03:06:03 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									metav1  "k8s.io/kubernetes/pkg/apis/meta/v1" 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/fieldpath" 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-18 01:23:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/kubelet/cm" 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									kubecontainer  "k8s.io/kubernetes/pkg/kubelet/container" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/kubelet/envvars" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/kubelet/images" 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 08:42:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/kubelet/server/remotecommand" 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/kubelet/status" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									kubetypes  "k8s.io/kubernetes/pkg/kubelet/types" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/kubelet/util/format" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/labels" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/types" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/util/sets" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/util/term" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									utilvalidation  "k8s.io/kubernetes/pkg/util/validation" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/util/validation/field" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/volume" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/volume/util/volumehelper" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/third_party/forked/golang/expansion" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Get a list of pods that have data directories.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  listPodsFromDisk ( )  ( [ ] types . UID ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									podInfos ,  err  :=  ioutil . ReadDir ( kl . getPodsDir ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pods  :=  [ ] types . UID { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  i  :=  range  podInfos  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  podInfos [ i ] . IsDir ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											pods  =  append ( pods ,  types . UID ( podInfos [ i ] . Name ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  pods ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// getActivePods returns non-terminal pods
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  getActivePods ( )  [ ] * v1 . Pod  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									allPods  :=  kl . podManager . GetPods ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									activePods  :=  kl . filterOutTerminatedPods ( allPods ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  activePods 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-31 16:05:02 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// makeDevices determines the devices for the given container.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Experimental. For now, we hardcode /dev/nvidia0 no matter what the user asks for
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// (we only support one device per node).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// TODO: add support for more than 1 GPU after #28216.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  makeDevices ( container  * v1 . Container )  [ ] kubecontainer . DeviceInfo  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-31 16:05:02 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									nvidiaGPULimit  :=  container . Resources . Limits . NvidiaGPU ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  nvidiaGPULimit . Value ( )  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  [ ] kubecontainer . DeviceInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											{ PathOnHost :  "/dev/nvidia0" ,  PathInContainer :  "/dev/nvidia0" ,  Permissions :  "mrw" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											{ PathOnHost :  "/dev/nvidiactl" ,  PathInContainer :  "/dev/nvidiactl" ,  Permissions :  "mrw" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											{ PathOnHost :  "/dev/nvidia-uvm" ,  PathInContainer :  "/dev/nvidia-uvm" ,  Permissions :  "mrw" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// makeMounts determines the mount points for the given container.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  makeMounts ( pod  * v1 . Pod ,  podDir  string ,  container  * v1 . Container ,  hostName ,  hostDomain ,  podIP  string ,  podVolumes  kubecontainer . VolumeMap )  ( [ ] kubecontainer . Mount ,  error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									// Kubernetes only mounts on /etc/hosts if :
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// - container does not use hostNetwork and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// - container is not an infrastructure(pause) container
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// - container is not already mounting on /etc/hosts
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// When the pause container is being created, its IP is still unknown. Hence, PodIP will not have been set.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-01 22:10:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// OS is not Windows
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									mountEtcHostsFile  :=  ( pod . Spec . SecurityContext  ==  nil  ||  ! pod . Spec . HostNetwork )  &&  len ( podIP )  >  0  &&  runtime . GOOS  !=  "windows" 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									glog . V ( 3 ) . Infof ( "container: %v/%v/%v podIP: %q creating hosts mount: %v" ,  pod . Namespace ,  pod . Name ,  container . Name ,  podIP ,  mountEtcHostsFile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									mounts  :=  [ ] kubecontainer . Mount { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  mount  :=  range  container . VolumeMounts  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										mountEtcHostsFile  =  mountEtcHostsFile  &&  ( mount . MountPath  !=  etcHostsPath ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										vol ,  ok  :=  podVolumes [ mount . Name ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											glog . Warningf ( "Mount cannot be satisfied for container %q, because the volume is missing: %q" ,  container . Name ,  mount ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										relabelVolume  :=  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// If the volume supports SELinux and it has not been
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// relabeled already and it is not a read-only volume,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// relabel it and mark it as labeled
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  vol . Mounter . GetAttributes ( ) . Managed  &&  vol . Mounter . GetAttributes ( ) . SupportsSELinux  &&  ! vol . SELinuxLabeled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											vol . SELinuxLabeled  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											relabelVolume  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										hostPath ,  err  :=  volume . GetPath ( vol . Mounter ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  mount . SubPath  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											hostPath  =  filepath . Join ( hostPath ,  mount . SubPath ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-01 22:10:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Docker Volume Mounts fail on Windows if it is not of the form C:/
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										containerPath  :=  mount . MountPath 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  runtime . GOOS  ==  "windows"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  strings . HasPrefix ( hostPath ,  "/" )  &&  ! strings . Contains ( hostPath ,  ":" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												hostPath  =  "c:"  +  hostPath 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  strings . HasPrefix ( containerPath ,  "/" )  &&  ! strings . Contains ( containerPath ,  ":" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												containerPath  =  "c:"  +  containerPath 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										mounts  =  append ( mounts ,  kubecontainer . Mount { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											Name :            mount . Name , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-01 22:10:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ContainerPath :   containerPath , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											HostPath :        hostPath , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ReadOnly :        mount . ReadOnly , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											SELinuxRelabel :  relabelVolume , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  mountEtcHostsFile  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										hostsMount ,  err  :=  makeHostsMount ( podDir ,  podIP ,  hostName ,  hostDomain ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										mounts  =  append ( mounts ,  * hostsMount ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  mounts ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// makeHostsMount makes the mountpoint for the hosts file that the containers
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// in a pod are injected with.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  makeHostsMount ( podDir ,  podIP ,  hostName ,  hostDomainName  string )  ( * kubecontainer . Mount ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									hostsFilePath  :=  path . Join ( podDir ,  "etc-hosts" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  :=  ensureHostsFile ( hostsFilePath ,  podIP ,  hostName ,  hostDomainName ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  & kubecontainer . Mount { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-25 06:42:19 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										Name :            "k8s-managed-etc-hosts" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ContainerPath :   etcHostsPath , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										HostPath :        hostsFilePath , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ReadOnly :        false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										SELinuxRelabel :  true , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// ensureHostsFile ensures that the given host file has an up-to-date ip, host
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// name, and domain name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ensureHostsFile ( fileName ,  hostIP ,  hostName ,  hostDomainName  string )  error  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  _ ,  err  :=  os . Stat ( fileName ) ;  os . IsExist ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										glog . V ( 4 ) . Infof ( "kubernetes-managed etc-hosts file exits. Will not be recreated: %q" ,  fileName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  buffer  bytes . Buffer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									buffer . WriteString ( "# Kubernetes-managed hosts file.\n" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									buffer . WriteString ( "127.0.0.1\tlocalhost\n" )                       // ipv4 localhost
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									buffer . WriteString ( "::1\tlocalhost ip6-localhost ip6-loopback\n" )  // ipv6 localhost
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									buffer . WriteString ( "fe00::0\tip6-localnet\n" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									buffer . WriteString ( "fe00::0\tip6-mcastprefix\n" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									buffer . WriteString ( "fe00::1\tip6-allnodes\n" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									buffer . WriteString ( "fe00::2\tip6-allrouters\n" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  len ( hostDomainName )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										buffer . WriteString ( fmt . Sprintf ( "%s\t%s.%s\t%s\n" ,  hostIP ,  hostName ,  hostDomainName ,  hostName ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										buffer . WriteString ( fmt . Sprintf ( "%s\t%s\n" ,  hostIP ,  hostName ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  ioutil . WriteFile ( fileName ,  buffer . Bytes ( ) ,  0644 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  makePortMappings ( container  * v1 . Container )  ( ports  [ ] kubecontainer . PortMapping )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									names  :=  make ( map [ string ] struct { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  p  :=  range  container . Ports  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pm  :=  kubecontainer . PortMapping { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											HostPort :       int ( p . HostPort ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ContainerPort :  int ( p . ContainerPort ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											Protocol :       p . Protocol , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											HostIP :         p . HostIP , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// We need to create some default port name if it's not specified, since
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// this is necessary for rkt.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// http://issue.k8s.io/7710
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  p . Name  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											pm . Name  =  fmt . Sprintf ( "%s-%s:%d" ,  container . Name ,  p . Protocol ,  p . ContainerPort ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											pm . Name  =  fmt . Sprintf ( "%s-%s" ,  container . Name ,  p . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Protect against exposing the same protocol-port more than once in a container.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  _ ,  ok  :=  names [ pm . Name ] ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											glog . Warningf ( "Port name conflicted, %q is defined more than once" ,  pm . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ports  =  append ( ports ,  pm ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										names [ pm . Name ]  =  struct { } { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-17 09:42:39 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// truncatePodHostnameIfNeeded truncates the pod hostname if it's longer than 63 chars.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  truncatePodHostnameIfNeeded ( podName ,  hostname  string )  ( string ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Cap hostname at 63 chars (specification is 64bytes which is 63 chars and the null terminating char).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  hostnameMaxLen  =  63 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  len ( hostname )  <=  hostnameMaxLen  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  hostname ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									truncated  :=  hostname [ : hostnameMaxLen ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									glog . Errorf ( "hostname for pod:%q was longer than %d. Truncated hostname to :%q" ,  podName ,  hostnameMaxLen ,  truncated ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// hostname should not end with '-' or '.'
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									truncated  =  strings . TrimRight ( truncated ,  "-." ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  len ( truncated )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// This should never happen.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  "" ,  fmt . Errorf ( "hostname for pod %q was invalid: %q" ,  podName ,  hostname ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  truncated ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// GeneratePodHostNameAndDomain creates a hostname and domain name for a pod,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// given that pod's spec and annotations or returns an error.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  GeneratePodHostNameAndDomain ( pod  * v1 . Pod )  ( string ,  string ,  error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									// TODO(vmarmol): Handle better.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clusterDomain  :=  kl . clusterDomain 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									podAnnotations  :=  pod . Annotations 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  podAnnotations  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										podAnnotations  =  make ( map [ string ] string ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									hostname  :=  pod . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  len ( pod . Spec . Hostname )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  msgs  :=  utilvalidation . IsDNS1123Label ( pod . Spec . Hostname ) ;  len ( msgs )  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  "" ,  "" ,  fmt . Errorf ( "Pod Hostname %q is not a valid DNS label: %s" ,  pod . Spec . Hostname ,  strings . Join ( msgs ,  ";" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										hostname  =  pod . Spec . Hostname 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										hostnameCandidate  :=  podAnnotations [ utilpod . PodHostnameAnnotation ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  len ( utilvalidation . IsDNS1123Label ( hostnameCandidate ) )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// use hostname annotation, if specified.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											hostname  =  hostnameCandidate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-17 09:42:39 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									hostname ,  err  :=  truncatePodHostnameIfNeeded ( pod . Name ,  hostname ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  "" ,  "" ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									hostDomain  :=  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  len ( pod . Spec . Subdomain )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  msgs  :=  utilvalidation . IsDNS1123Label ( pod . Spec . Subdomain ) ;  len ( msgs )  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  "" ,  "" ,  fmt . Errorf ( "Pod Subdomain %q is not a valid DNS label: %s" ,  pod . Spec . Subdomain ,  strings . Join ( msgs ,  ";" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										hostDomain  =  fmt . Sprintf ( "%s.%s.svc.%s" ,  pod . Spec . Subdomain ,  pod . Namespace ,  clusterDomain ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										subdomainCandidate  :=  pod . Annotations [ utilpod . PodSubdomainAnnotation ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  len ( utilvalidation . IsDNS1123Label ( subdomainCandidate ) )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											hostDomain  =  fmt . Sprintf ( "%s.%s.svc.%s" ,  subdomainCandidate ,  pod . Namespace ,  clusterDomain ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  hostname ,  hostDomain ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// GenerateRunContainerOptions generates the RunContainerOptions, which can be used by
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// the container runtime to set parameters for launching a container.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  GenerateRunContainerOptions ( pod  * v1 . Pod ,  container  * v1 . Container ,  podIP  string )  ( * kubecontainer . RunContainerOptions ,  error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									var  err  error 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-18 01:23:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									pcm  :=  kl . containerManager . NewPodContainerManager ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									_ ,  podContainerName  :=  pcm . GetPodContainerName ( pod ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									opts  :=  & kubecontainer . RunContainerOptions { CgroupParent :  podContainerName } 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									hostname ,  hostDomainName ,  err  :=  kl . GeneratePodHostNameAndDomain ( pod ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									opts . Hostname  =  hostname 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									podName  :=  volumehelper . GetUniquePodName ( pod ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									volumes  :=  kl . volumeManager . GetMountedVolumesForPod ( podName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									opts . PortMappings  =  makePortMappings ( container ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-31 16:05:02 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									opts . Devices  =  makeDevices ( container ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									opts . Mounts ,  err  =  makeMounts ( pod ,  kl . getPodDir ( pod . UID ) ,  container ,  hostname ,  hostDomainName ,  podIP ,  volumes ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									opts . Envs ,  err  =  kl . makeEnvironmentVariables ( pod ,  container ,  podIP ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-01 22:10:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// Disabling adding TerminationMessagePath on Windows as these files would be mounted as docker volume and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Docker for Windows has a bug where only directories can be mounted
 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-24 22:49:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  len ( container . TerminationMessagePath )  !=  0  &&  runtime . GOOS  !=  "windows"  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										p  :=  kl . getPodContainerDir ( pod . UID ,  container . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  :=  os . MkdirAll ( p ,  0750 ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											glog . Errorf ( "Error on creating %q: %v" ,  p ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											opts . PodContainerDir  =  p 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									opts . DNS ,  opts . DNSSearch ,  err  =  kl . GetClusterDNS ( pod ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 04:45:38 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// only do this check if the experimental behavior is enabled, otherwise allow it to default to false
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  kl . experimentalHostUserNamespaceDefaulting  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										opts . EnableHostUserNamespace  =  kl . enableHostUserNamespace ( pod ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									return  opts ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								var  masterServices  =  sets . NewString ( "kubernetes" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// getServiceEnvVarMap makes a map[string]string of env vars for services a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// pod in namespace ns should see.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  getServiceEnvVarMap ( ns  string )  ( map [ string ] string ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  ( 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										serviceMap  =  make ( map [ string ] * v1 . Service ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										m           =  make ( map [ string ] string ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Get all service resources from the master (via a cache),
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// and populate them into service environment variables.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  kl . serviceLister  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Kubelets without masters (e.g. plain GCE ContainerVM) don't set env vars.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  m ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									services ,  err  :=  kl . serviceLister . List ( labels . Everything ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  m ,  fmt . Errorf ( "failed to list services when setting up env vars." ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// project the services in namespace ns onto the master services
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  i  :=  range  services  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										service  :=  services [ i ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// ignore services where ClusterIP is "None" or empty
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ! v1 . IsServiceIPSet ( service )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										serviceName  :=  service . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										switch  service . Namespace  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// for the case whether the master service namespace is the namespace the pod
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// is in, the pod should receive all the services in the namespace.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// ordering of the case clauses below enforces this
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  ns : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											serviceMap [ serviceName ]  =  service 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  kl . masterServiceNamespace : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  masterServices . Has ( serviceName )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  _ ,  exists  :=  serviceMap [ serviceName ] ;  ! exists  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													serviceMap [ serviceName ]  =  service 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									mappedServices  :=  [ ] * v1 . Service { } 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									for  key  :=  range  serviceMap  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										mappedServices  =  append ( mappedServices ,  serviceMap [ key ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  e  :=  range  envvars . FromServices ( mappedServices )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										m [ e . Name ]  =  e . Value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  m ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Make the environment variables for a pod in the given namespace.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  makeEnvironmentVariables ( pod  * v1 . Pod ,  container  * v1 . Container ,  podIP  string )  ( [ ] kubecontainer . EnvVar ,  error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									var  result  [ ] kubecontainer . EnvVar 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Note:  These are added to the docker Config, but are not included in the checksum computed
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// by dockertools.BuildDockerName(...).  That way, we can still determine whether an
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// v1.Container is already running by its hash. (We don't want to restart a container just
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									// because some service changed.)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Note that there is a race between Kubelet seeing the pod and kubelet seeing the service.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// To avoid this users can: (1) wait between starting a service and starting; or (2) detect
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// missing service env var and exit and be restarted; or (3) use DNS instead of env vars
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// and keep trying to resolve the DNS name of the service (recommended).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									serviceEnv ,  err  :=  kl . getServiceEnvVarMap ( pod . Namespace ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  result ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Determine the final values of variables:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// 1.  Determine the final value of each variable:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									//     a.  If the variable's Value is set, expand the `$(var)` references to other
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									//         variables in the .Value field; the sources of variables are the declared
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									//         variables of the container and the service environment variables
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									//     b.  If a source is defined for an environment variable, resolve the source
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// 2.  Create the container's environment in the order variables are declared
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// 3.  Add remaining service environment vars
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tmpEnv       =  make ( map [ string ] string ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										configMaps   =  make ( map [ string ] * v1 . ConfigMap ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										secrets      =  make ( map [ string ] * v1 . Secret ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										mappingFunc  =  expansion . MappingFuncFor ( tmpEnv ,  serviceEnv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  envVar  :=  range  container . Env  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Accesses apiserver+Pods.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// So, the master may set service env vars, or kubelet may.  In case both are doing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// it, we delete the key from the kubelet-generated ones so we don't have duplicate
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// env vars.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// TODO: remove this net line once all platforms use apiserver+Pods.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										delete ( serviceEnv ,  envVar . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										runtimeVal  :=  envVar . Value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  runtimeVal  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// Step 1a: expand variable references
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											runtimeVal  =  expansion . Expand ( runtimeVal ,  mappingFunc ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  if  envVar . ValueFrom  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// Step 1b: resolve alternate env var sources
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  envVar . ValueFrom . FieldRef  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												runtimeVal ,  err  =  kl . podFieldSelectorRuntimeValue ( envVar . ValueFrom . FieldRef ,  pod ,  podIP ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													return  result ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  envVar . ValueFrom . ResourceFieldRef  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												defaultedPod ,  defaultedContainer ,  err  :=  kl . defaultPodLimitsForDownwardApi ( pod ,  container ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													return  result ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												runtimeVal ,  err  =  containerResourceRuntimeValue ( envVar . ValueFrom . ResourceFieldRef ,  defaultedPod ,  defaultedContainer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													return  result ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  envVar . ValueFrom . ConfigMapKeyRef  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												name  :=  envVar . ValueFrom . ConfigMapKeyRef . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												key  :=  envVar . ValueFrom . ConfigMapKeyRef . Key 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												configMap ,  ok  :=  configMaps [ name ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  kl . kubeClient  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														return  result ,  fmt . Errorf ( "Couldn't get configMap %v/%v, no kubeClient defined" ,  pod . Namespace ,  name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													configMap ,  err  =  kl . kubeClient . Core ( ) . ConfigMaps ( pod . Namespace ) . Get ( name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														return  result ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													configMaps [ name ]  =  configMap 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												runtimeVal ,  ok  =  configMap . Data [ key ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													return  result ,  fmt . Errorf ( "Couldn't find key %v in ConfigMap %v/%v" ,  key ,  pod . Namespace ,  name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  envVar . ValueFrom . SecretKeyRef  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												name  :=  envVar . ValueFrom . SecretKeyRef . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												key  :=  envVar . ValueFrom . SecretKeyRef . Key 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												secret ,  ok  :=  secrets [ name ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  kl . kubeClient  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														return  result ,  fmt . Errorf ( "Couldn't get secret %v/%v, no kubeClient defined" ,  pod . Namespace ,  name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													secret ,  err  =  kl . kubeClient . Core ( ) . Secrets ( pod . Namespace ) . Get ( name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														return  result ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													secrets [ name ]  =  secret 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												runtimeValBytes ,  ok  :=  secret . Data [ key ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													return  result ,  fmt . Errorf ( "Couldn't find key %v in Secret %v/%v" ,  key ,  pod . Namespace ,  name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												runtimeVal  =  string ( runtimeValBytes ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tmpEnv [ envVar . Name ]  =  runtimeVal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										result  =  append ( result ,  kubecontainer . EnvVar { Name :  envVar . Name ,  Value :  tmpEnv [ envVar . Name ] } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Append remaining service env vars.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  k ,  v  :=  range  serviceEnv  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										result  =  append ( result ,  kubecontainer . EnvVar { Name :  k ,  Value :  v } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  result ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// podFieldSelectorRuntimeValue returns the runtime value of the given
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// selector for a pod.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  podFieldSelectorRuntimeValue ( fs  * v1 . ObjectFieldSelector ,  pod  * v1 . Pod ,  podIP  string )  ( string ,  error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									internalFieldPath ,  _ ,  err  :=  api . Scheme . ConvertFieldLabel ( fs . APIVersion ,  "Pod" ,  fs . FieldPath ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  "" ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  internalFieldPath  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  "spec.nodeName" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  pod . Spec . NodeName ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  "spec.serviceAccountName" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  pod . Spec . ServiceAccountName ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  "status.podIP" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  podIP ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  fieldpath . ExtractFieldPathAsString ( pod ,  internalFieldPath ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// containerResourceRuntimeValue returns the value of the provided container resource
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  containerResourceRuntimeValue ( fs  * v1 . ResourceFieldSelector ,  pod  * v1 . Pod ,  container  * v1 . Container )  ( string ,  error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									containerName  :=  fs . ContainerName 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  len ( containerName )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  fieldpath . ExtractContainerResourceValue ( fs ,  container ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  fieldpath . ExtractResourceValueByContainerName ( fs ,  pod ,  containerName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// One of the following arguments must be non-nil: runningPod, status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// TODO: Modify containerRuntime.KillPod() to accept the right arguments.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  killPod ( pod  * v1 . Pod ,  runningPod  * kubecontainer . Pod ,  status  * kubecontainer . PodStatus ,  gracePeriodOverride  * int64 )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									var  p  kubecontainer . Pod 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  runningPod  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										p  =  * runningPod 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  if  status  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										p  =  kubecontainer . ConvertPodStatusToRunningPod ( kl . GetRuntime ( ) . Type ( ) ,  status ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-18 01:23:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// cache the pod cgroup Name for reducing the cpu resource limits of the pod cgroup once the pod is killed
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pcm  :=  kl . containerManager . NewPodContainerManager ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  podCgroup  cm . CgroupName 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									reduceCpuLimts  :=  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  pod  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										podCgroup ,  _  =  pcm . GetPodContainerName ( pod ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// If the pod is nil then cgroup limit must have already
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// been decreased earlier
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										reduceCpuLimts  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Call the container runtime KillPod method which stops all running containers of the pod
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  :=  kl . containerRuntime . KillPod ( pod ,  p ,  gracePeriodOverride ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// At this point the pod might not completely free up cpu and memory resources.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// In such a case deleting the pod's cgroup might cause the pod's charges to be transferred
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// to the parent cgroup. There might be various kinds of pod charges at this point.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// For example, any volume used by the pod that was backed by memory will have its
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// pages charged to the pod cgroup until those volumes are removed by the kubelet.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Hence we only reduce the cpu resource limits of the pod's cgroup
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// and defer the responsibilty of destroying the pod's cgroup to the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// cleanup method and the housekeeping loop.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  reduceCpuLimts  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pcm . ReduceCPULimits ( podCgroup ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// makePodDataDirs creates the dirs for the pod datas.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  makePodDataDirs ( pod  * v1 . Pod )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									uid  :=  pod . UID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  :=  os . MkdirAll ( kl . getPodDir ( uid ) ,  0750 ) ;  err  !=  nil  &&  ! os . IsExist ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  :=  os . MkdirAll ( kl . getPodVolumesDir ( uid ) ,  0750 ) ;  err  !=  nil  &&  ! os . IsExist ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  :=  os . MkdirAll ( kl . getPodPluginsDir ( uid ) ,  0750 ) ;  err  !=  nil  &&  ! os . IsExist ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// returns whether the pod uses the host network namespace.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  podUsesHostNetwork ( pod  * v1 . Pod )  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  pod . Spec . HostNetwork 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// getPullSecretsForPod inspects the Pod and retrieves the referenced pull
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// secrets.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// TODO: duplicate secrets are being retrieved multiple times and there
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// is no cache.  Creating and using a secret manager interface will make this
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// easier to address.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  getPullSecretsForPod ( pod  * v1 . Pod )  ( [ ] v1 . Secret ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pullSecrets  :=  [ ] v1 . Secret { } 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  secretRef  :=  range  pod . Spec . ImagePullSecrets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										secret ,  err  :=  kl . kubeClient . Core ( ) . Secrets ( pod . Namespace ) . Get ( secretRef . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											glog . Warningf ( "Unable to retrieve pull secret %s/%s for %s/%s due to %v.  The image pull may not succeed." ,  pod . Namespace ,  secretRef . Name ,  pod . Namespace ,  pod . Name ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pullSecrets  =  append ( pullSecrets ,  * secret ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  pullSecrets ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Returns true if pod is in the terminated state ("Failed" or "Succeeded").
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  podIsTerminated ( pod  * v1 . Pod )  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  status  v1 . PodStatus 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									// Check the cached pod status which was set after the last sync.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									status ,  ok  :=  kl . statusManager . GetPodStatus ( pod . UID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// If there is no cached status, use the status from the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// apiserver. This is useful if kubelet has recently been
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// restarted.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										status  =  pod . Status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  status . Phase  ==  v1 . PodFailed  ||  status . Phase  ==  v1 . PodSucceeded  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// filterOutTerminatedPods returns the given pods which the status manager
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// does not consider failed or succeeded.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  filterOutTerminatedPods ( pods  [ ] * v1 . Pod )  [ ] * v1 . Pod  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  filteredPods  [ ] * v1 . Pod 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  p  :=  range  pods  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  kl . podIsTerminated ( p )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										filteredPods  =  append ( filteredPods ,  p ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  filteredPods 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// removeOrphanedPodStatuses removes obsolete entries in podStatus where
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// the pod is no longer considered bound to this node.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  removeOrphanedPodStatuses ( pods  [ ] * v1 . Pod ,  mirrorPods  [ ] * v1 . Pod )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									podUIDs  :=  make ( map [ types . UID ] bool ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  pod  :=  range  pods  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										podUIDs [ pod . UID ]  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  pod  :=  range  mirrorPods  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										podUIDs [ pod . UID ]  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									kl . statusManager . RemoveOrphanedStatuses ( podUIDs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// HandlePodCleanups performs a series of cleanup work, including terminating
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// pod workers, killing unwanted pods, and removing orphaned volumes/pod
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// directories.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// NOTE: This function is executed by the main sync loop, so it
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// should not contain any blocking calls.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  HandlePodCleanups ( )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-18 01:23:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// The kubelet lacks checkpointing, so we need to introspect the set of pods
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// in the cgroup tree prior to inspecting the set of pods in our pod manager.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// this ensures our view of the cgroup tree does not mistakenly observe pods
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// that are added after the fact...
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										cgroupPods  map [ types . UID ] cm . CgroupName 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										err         error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  kl . cgroupsPerQOS  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pcm  :=  kl . containerManager . NewPodContainerManager ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										cgroupPods ,  err  =  pcm . GetAllPodsFromCgroups ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  fmt . Errorf ( "failed to get list of pods that still exist on cgroup mounts: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									allPods ,  mirrorPods  :=  kl . podManager . GetPodsAndMirrorPods ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Pod phase progresses monotonically. Once a pod has reached a final state,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// it should never leave regardless of the restart policy. The statuses
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// of such pods should not be changed, and there is no need to sync them.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// TODO: the logic here does not handle two cases:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									//   1. If the containers were removed immediately after they died, kubelet
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									//      may fail to generate correct statuses, let alone filtering correctly.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									//   2. If kubelet restarted before writing the terminated status for a pod
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									//      to the apiserver, it could still restart the terminated pod (even
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									//      though the pod was not considered terminated by the apiserver).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// These two conditions could be alleviated by checkpointing kubelet.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									activePods  :=  kl . filterOutTerminatedPods ( allPods ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									desiredPods  :=  make ( map [ types . UID ] empty ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  pod  :=  range  activePods  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										desiredPods [ pod . UID ]  =  empty { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Stop the workers for no-longer existing pods.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// TODO: is here the best place to forget pod workers?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									kl . podWorkers . ForgetNonExistingPodWorkers ( desiredPods ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									kl . probeManager . CleanupPods ( activePods ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									runningPods ,  err  :=  kl . runtimeCache . GetPods ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										glog . Errorf ( "Error listing containers: %#v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  pod  :=  range  runningPods  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  _ ,  found  :=  desiredPods [ pod . ID ] ;  ! found  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											kl . podKillingCh  <-  & kubecontainer . PodPair { APIPod :  nil ,  RunningPod :  pod } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									kl . removeOrphanedPodStatuses ( allPods ,  mirrorPods ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Note that we just killed the unwanted pods. This may not have reflected
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// in the cache. We need to bypass the cache to get the latest set of
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// running pods to clean up the volumes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// TODO: Evaluate the performance impact of bypassing the runtime cache.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									runningPods ,  err  =  kl . containerRuntime . GetPods ( false ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										glog . Errorf ( "Error listing containers: %#v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Remove any orphaned volumes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Note that we pass all pods (including terminated pods) to the function,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// so that we don't remove volumes associated with terminated but not yet
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// deleted pods.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									err  =  kl . cleanupOrphanedPodDirs ( allPods ,  runningPods ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// We want all cleanup tasks to be run even if one of them failed. So
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// we just log an error here and continue other cleanup tasks.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// This also applies to the other clean up tasks.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										glog . Errorf ( "Failed cleaning up orphaned pod directories: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Remove any orphaned mirror pods.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									kl . podManager . DeleteOrphanedMirrorPods ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Clear out any old bandwidth rules
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									err  =  kl . cleanupBandwidthLimits ( allPods ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										glog . Errorf ( "Failed cleaning up bandwidth limits: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-18 01:23:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// Remove any cgroups in the hierarchy for pods that should no longer exist
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  kl . cgroupsPerQOS  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										kl . cleanupOrphanedPodCgroups ( cgroupPods ,  allPods ,  runningPods ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									kl . backOff . GC ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// podKiller launches a goroutine to kill a pod received from the channel if
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// another goroutine isn't already in action.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  podKiller ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									killing  :=  sets . NewString ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									resultCh  :=  make ( chan  types . UID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									defer  close ( resultCh ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  podPair ,  ok  :=  <- kl . podKillingCh : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											runningPod  :=  podPair . RunningPod 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											apiPod  :=  podPair . APIPod 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  killing . Has ( string ( runningPod . ID ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												// The pod is already being killed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											killing . Insert ( string ( runningPod . ID ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											go  func ( apiPod  * v1 . Pod ,  runningPod  * kubecontainer . Pod ,  ch  chan  types . UID )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												defer  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ch  <-  runningPod . ID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												glog . V ( 2 ) . Infof ( "Killing unwanted pod %q" ,  runningPod . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												err  :=  kl . killPod ( apiPod ,  runningPod ,  nil ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													glog . Errorf ( "Failed killing the pod %q: %v" ,  runningPod . Name ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} ( apiPod ,  runningPod ,  resultCh ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  podID  :=  <- resultCh : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											killing . Delete ( string ( podID ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// checkHostPortConflicts detects pods with conflicted host ports.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  hasHostPortConflicts ( pods  [ ] * v1 . Pod )  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									ports  :=  sets . String { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  pod  :=  range  pods  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  errs  :=  validation . AccumulateUniqueHostPorts ( pod . Spec . Containers ,  & ports ,  field . NewPath ( "spec" ,  "containers" ) ) ;  len ( errs )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											glog . Errorf ( "Pod %q: HostPort is already allocated, ignoring: %v" ,  format . Pod ( pod ) ,  errs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  errs  :=  validation . AccumulateUniqueHostPorts ( pod . Spec . InitContainers ,  & ports ,  field . NewPath ( "spec" ,  "initContainers" ) ) ;  len ( errs )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											glog . Errorf ( "Pod %q: HostPort is already allocated, ignoring: %v" ,  format . Pod ( pod ) ,  errs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// validateContainerLogStatus returns the container ID for the desired container to retrieve logs for, based on the state
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// of the container. The previous flag will only return the logs for the last terminated container, otherwise, the current
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// running container is preferred over a previous termination. If info about the container is not available then a specific
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// error is returned to the end user.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  validateContainerLogStatus ( podName  string ,  podStatus  * v1 . PodStatus ,  containerName  string ,  previous  bool )  ( containerID  kubecontainer . ContainerID ,  err  error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									var  cID  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									cStatus ,  found  :=  v1 . GetContainerStatus ( podStatus . ContainerStatuses ,  containerName ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									// if not found, check the init containers
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ! found  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										cStatus ,  found  =  v1 . GetContainerStatus ( podStatus . InitContainerStatuses ,  containerName ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ! found  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  kubecontainer . ContainerID { } ,  fmt . Errorf ( "container %q in pod %q is not available" ,  containerName ,  podName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									lastState  :=  cStatus . LastTerminationState 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									waiting ,  running ,  terminated  :=  cStatus . State . Waiting ,  cStatus . State . Running ,  cStatus . State . Terminated 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  previous : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  lastState . Terminated  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  kubecontainer . ContainerID { } ,  fmt . Errorf ( "previous terminated container %q in pod %q not found" ,  containerName ,  podName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										cID  =  lastState . Terminated . ContainerID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  running  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										cID  =  cStatus . ContainerID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  terminated  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										cID  =  terminated . ContainerID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  lastState . Terminated  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										cID  =  lastState . Terminated . ContainerID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  waiting  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// output some info for the most common pending failures
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										switch  reason  :=  waiting . Reason ;  reason  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  images . ErrImagePull . Error ( ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  kubecontainer . ContainerID { } ,  fmt . Errorf ( "container %q in pod %q is waiting to start: image can't be pulled" ,  containerName ,  podName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  images . ErrImagePullBackOff . Error ( ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  kubecontainer . ContainerID { } ,  fmt . Errorf ( "container %q in pod %q is waiting to start: trying and failing to pull image" ,  containerName ,  podName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  kubecontainer . ContainerID { } ,  fmt . Errorf ( "container %q in pod %q is waiting to start: %v" ,  containerName ,  podName ,  reason ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// unrecognized state
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  kubecontainer . ContainerID { } ,  fmt . Errorf ( "container %q in pod %q is waiting to start - no logs yet" ,  containerName ,  podName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  kubecontainer . ParseContainerID ( cID ) ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// GetKubeletContainerLogs returns logs from the container
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// TODO: this method is returning logs of random container attempts, when it should be returning the most recent attempt
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// or all of them.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  GetKubeletContainerLogs ( podFullName ,  containerName  string ,  logOptions  * v1 . PodLogOptions ,  stdout ,  stderr  io . Writer )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									// Pod workers periodically write status to statusManager. If status is not
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// cached there, something is wrong (or kubelet just restarted and hasn't
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// caught up yet). Just assume the pod is not ready yet.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									name ,  namespace ,  err  :=  kubecontainer . ParsePodFullName ( podFullName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  fmt . Errorf ( "unable to parse pod full name %q: %v" ,  podFullName ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pod ,  ok  :=  kl . GetPodByName ( namespace ,  name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  fmt . Errorf ( "pod %q cannot be found - no logs available" ,  name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									podUID  :=  pod . UID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  mirrorPod ,  ok  :=  kl . podManager . GetMirrorPodByPod ( pod ) ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										podUID  =  mirrorPod . UID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									podStatus ,  found  :=  kl . statusManager . GetPodStatus ( podUID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ! found  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// If there is no cached status, use the status from the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// apiserver. This is useful if kubelet has recently been
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// restarted.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										podStatus  =  pod . Status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-21 06:35:34 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// TODO: Consolidate the logic here with kuberuntime.GetContainerLogs, here we convert container name to containerID,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// but inside kuberuntime we convert container id back to container name and restart count.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// TODO: After separate container log lifecycle management, we should get log based on the existing log files
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// instead of container status.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									containerID ,  err  :=  kl . validateContainerLogStatus ( pod . Name ,  & podStatus ,  containerName ,  logOptions . Previous ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Do a zero-byte write to stdout before handing off to the container runtime.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// This ensures at least one Write call is made to the writer when copying starts,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// even if we then block waiting for log output from the container.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  _ ,  err  :=  stdout . Write ( [ ] byte { } ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  kl . containerRuntime . GetContainerLogs ( pod ,  containerID ,  logOptions ,  stdout ,  stderr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// GetPhase returns the phase of a pod given its container info.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// This func is exported to simplify integration with 3rd party kubelet
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// integrations like kubernetes-mesos.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  GetPhase ( spec  * v1 . PodSpec ,  info  [ ] v1 . ContainerStatus )  v1 . PodPhase  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									initialized  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pendingInitialization  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									failedInitialization  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  container  :=  range  spec . InitContainers  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										containerStatus ,  ok  :=  v1 . GetContainerStatus ( info ,  container . Name ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											pendingInitialization ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  containerStatus . State . Running  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											pendingInitialization ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  containerStatus . State . Terminated  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  containerStatus . State . Terminated . ExitCode  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												initialized ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												failedInitialization ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  containerStatus . State . Waiting  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  containerStatus . LastTerminationState . Terminated  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  containerStatus . LastTerminationState . Terminated . ExitCode  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													initialized ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													failedInitialization ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												pendingInitialization ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											pendingInitialization ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unknown  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									running  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									waiting  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									stopped  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									failed  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									succeeded  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  container  :=  range  spec . Containers  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										containerStatus ,  ok  :=  v1 . GetContainerStatus ( info ,  container . Name ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											unknown ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  containerStatus . State . Running  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											running ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  containerStatus . State . Terminated  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											stopped ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  containerStatus . State . Terminated . ExitCode  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												succeeded ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												failed ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  containerStatus . State . Waiting  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  containerStatus . LastTerminationState . Terminated  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												stopped ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												waiting ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											unknown ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  failedInitialization  >  0  &&  spec . RestartPolicy  ==  v1 . RestartPolicyNever  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  v1 . PodFailed 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  pendingInitialization  >  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										fallthrough 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  waiting  >  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										glog . V ( 5 ) . Infof ( "pod waiting > 0, pending" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// One or more containers has not been started
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  v1 . PodPending 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									case  running  >  0  &&  unknown  ==  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// All containers have been started, and at least
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// one container is running
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  v1 . PodRunning 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									case  running  ==  0  &&  stopped  >  0  &&  unknown  ==  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// All containers are terminated
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  spec . RestartPolicy  ==  v1 . RestartPolicyAlways  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											// All containers are in the process of restarting
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  v1 . PodRunning 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  stopped  ==  succeeded  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// RestartPolicy is not Always, and all
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// containers are terminated in success
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  v1 . PodSucceeded 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  spec . RestartPolicy  ==  v1 . RestartPolicyNever  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											// RestartPolicy is Never, and all containers are
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// terminated with at least one in failure
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  v1 . PodFailed 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// RestartPolicy is OnFailure, and at least one in failure
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// and in the process of restarting
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  v1 . PodRunning 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										glog . V ( 5 ) . Infof ( "pod default case, pending" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  v1 . PodPending 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// generateAPIPodStatus creates the final API pod status for a pod, given the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// internal pod status.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  generateAPIPodStatus ( pod  * v1 . Pod ,  podStatus  * kubecontainer . PodStatus )  v1 . PodStatus  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									glog . V ( 3 ) . Infof ( "Generating status for %q" ,  format . Pod ( pod ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// check if an internal module has requested the pod is evicted.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  podSyncHandler  :=  range  kl . PodSyncHandlers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  result  :=  podSyncHandler . ShouldEvict ( pod ) ;  result . Evict  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  v1 . PodStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												Phase :    v1 . PodFailed , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												Reason :   result . Reason , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												Message :  result . Message , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									s  :=  kl . convertStatusToAPIStatus ( pod ,  podStatus ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Assume info is ready to process
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									spec  :=  & pod . Spec 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									allStatus  :=  append ( append ( [ ] v1 . ContainerStatus { } ,  s . ContainerStatuses ... ) ,  s . InitContainerStatuses ... ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									s . Phase  =  GetPhase ( spec ,  allStatus ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									kl . probeManager . UpdatePodStatus ( pod . UID ,  s ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									s . Conditions  =  append ( s . Conditions ,  status . GeneratePodInitializedCondition ( spec ,  s . InitContainerStatuses ,  s . Phase ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									s . Conditions  =  append ( s . Conditions ,  status . GeneratePodReadyCondition ( spec ,  s . ContainerStatuses ,  s . Phase ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// s (the PodStatus we are creating) will not have a PodScheduled condition yet, because converStatusToAPIStatus()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// does not create one. If the existing PodStatus has a PodScheduled condition, then copy it into s and make sure
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// it is set to true. If the existing PodStatus does not have a PodScheduled condition, then create one that is set to true.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  _ ,  oldPodScheduled  :=  v1 . GetPodCondition ( & pod . Status ,  v1 . PodScheduled ) ;  oldPodScheduled  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										s . Conditions  =  append ( s . Conditions ,  * oldPodScheduled ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									v1 . UpdatePodCondition ( & pod . Status ,  & v1 . PodCondition { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										Type :    v1 . PodScheduled , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										Status :  v1 . ConditionTrue , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ! kl . standaloneMode  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										hostIP ,  err  :=  kl . getHostIPAnyWay ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											glog . V ( 4 ) . Infof ( "Cannot get host IP: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											s . HostIP  =  hostIP . String ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  podUsesHostNetwork ( pod )  &&  s . PodIP  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												s . PodIP  =  hostIP . String ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  * s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// convertStatusToAPIStatus creates an api PodStatus for the given pod from
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// the given internal pod status.  It is purely transformative and does not
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// alter the kubelet state at all.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  convertStatusToAPIStatus ( pod  * v1 . Pod ,  podStatus  * kubecontainer . PodStatus )  * v1 . PodStatus  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  apiPodStatus  v1 . PodStatus 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									apiPodStatus . PodIP  =  podStatus . IP 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									apiPodStatus . ContainerStatuses  =  kl . convertToAPIContainerStatuses ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pod ,  podStatus , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pod . Status . ContainerStatuses , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pod . Spec . Containers , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										len ( pod . Spec . InitContainers )  >  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									apiPodStatus . InitContainerStatuses  =  kl . convertToAPIContainerStatuses ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pod ,  podStatus , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pod . Status . InitContainerStatuses , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pod . Spec . InitContainers , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										len ( pod . Spec . InitContainers )  >  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  & apiPodStatus 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// convertToAPIContainerStatuses converts the given internal container
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// statuses into API container statuses.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  convertToAPIContainerStatuses ( pod  * v1 . Pod ,  podStatus  * kubecontainer . PodStatus ,  previousStatus  [ ] v1 . ContainerStatus ,  containers  [ ] v1 . Container ,  hasInitContainers ,  isInitContainer  bool )  [ ] v1 . ContainerStatus  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									convertContainerStatus  :=  func ( cs  * kubecontainer . ContainerStatus )  * v1 . ContainerStatus  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										cid  :=  cs . ID . String ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										status  :=  & v1 . ContainerStatus { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											Name :          cs . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											RestartCount :  int32 ( cs . RestartCount ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											Image :         cs . Image , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ImageID :       cs . ImageID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ContainerID :   cid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										switch  cs . State  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  kubecontainer . ContainerStateRunning : 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-04 02:57:26 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											status . State . Running  =  & v1 . ContainerStateRunning { StartedAt :  metav1 . NewTime ( cs . StartedAt ) } 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										case  kubecontainer . ContainerStateExited : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											status . State . Terminated  =  & v1 . ContainerStateTerminated { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												ExitCode :     int32 ( cs . ExitCode ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												Reason :       cs . Reason , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												Message :      cs . Message , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-04 02:57:26 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												StartedAt :    metav1 . NewTime ( cs . StartedAt ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												FinishedAt :   metav1 . NewTime ( cs . FinishedAt ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												ContainerID :  cid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											status . State . Waiting  =  & v1 . ContainerStateWaiting { } 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Fetch old containers statuses from old pod status.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									oldStatuses  :=  make ( map [ string ] v1 . ContainerStatus ,  len ( containers ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  status  :=  range  previousStatus  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										oldStatuses [ status . Name ]  =  status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Set all container statuses to default waiting state
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									statuses  :=  make ( map [ string ] * v1 . ContainerStatus ,  len ( containers ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									defaultWaitingState  :=  v1 . ContainerState { Waiting :  & v1 . ContainerStateWaiting { Reason :  "ContainerCreating" } } 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  hasInitContainers  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										defaultWaitingState  =  v1 . ContainerState { Waiting :  & v1 . ContainerStateWaiting { Reason :  "PodInitializing" } } 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  container  :=  range  containers  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										status  :=  & v1 . ContainerStatus { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											Name :   container . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											Image :  container . Image , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											State :  defaultWaitingState , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Apply some values from the old statuses as the default values.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  oldStatus ,  found  :=  oldStatuses [ container . Name ] ;  found  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											status . RestartCount  =  oldStatus . RestartCount 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											status . LastTerminationState  =  oldStatus . LastTerminationState 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										statuses [ container . Name ]  =  status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Make the latest container status comes first.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sort . Sort ( sort . Reverse ( kubecontainer . SortContainerStatusesByCreationTime ( podStatus . ContainerStatuses ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Set container statuses according to the statuses seen in pod status
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									containerSeen  :=  map [ string ] int { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  cStatus  :=  range  podStatus . ContainerStatuses  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										cName  :=  cStatus . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  _ ,  ok  :=  statuses [ cName ] ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// This would also ignore the infra container.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  containerSeen [ cName ]  >=  2  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										status  :=  convertContainerStatus ( cStatus ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  containerSeen [ cName ]  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											statuses [ cName ]  =  status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											statuses [ cName ] . LastTerminationState  =  status . State 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										containerSeen [ cName ]  =  containerSeen [ cName ]  +  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Handle the containers failed to be started, which should be in Waiting state.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  container  :=  range  containers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  isInitContainer  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// If the init container is terminated with exit code 0, it won't be restarted.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// TODO(random-liu): Handle this in a cleaner way.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											s  :=  podStatus . FindContainerStatusByName ( container . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  s  !=  nil  &&  s . State  ==  kubecontainer . ContainerStateExited  &&  s . ExitCode  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// If a container should be restarted in next syncpod, it is *Waiting*.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ! kubecontainer . ShouldContainerBeRestarted ( & container ,  pod ,  podStatus )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										status  :=  statuses [ container . Name ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										reason ,  message ,  ok  :=  kl . reasonCache . Get ( pod . UID ,  container . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// In fact, we could also apply Waiting state here, but it is less informative,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// and the container will be restarted soon, so we prefer the original state here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// Note that with the current implementation of ShouldContainerBeRestarted the original state here
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// could be:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											//   * Waiting: There is no associated historical container and start failure reason record.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											//   * Terminated: The container is terminated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  status . State . Terminated  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											status . LastTerminationState  =  status . State 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										status . State  =  v1 . ContainerState { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											Waiting :  & v1 . ContainerStateWaiting { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												Reason :   reason . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												Message :  message , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										statuses [ container . Name ]  =  status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									var  containerStatuses  [ ] v1 . ContainerStatus 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  status  :=  range  statuses  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										containerStatuses  =  append ( containerStatuses ,  * status ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Sort the container statuses since clients of this interface expect the list
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// of containers in a pod has a deterministic order.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  isInitContainer  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										kubetypes . SortInitContainerStatuses ( pod ,  containerStatuses ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										sort . Sort ( kubetypes . SortedContainerStatuses ( containerStatuses ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  containerStatuses 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Returns logs of current machine.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  ServeLogs ( w  http . ResponseWriter ,  req  * http . Request )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// TODO: whitelist logs we are willing to serve
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									kl . logServer . ServeHTTP ( w ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// findContainer finds and returns the container with the given pod ID, full name, and container name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// It returns nil if not found.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  findContainer ( podFullName  string ,  podUID  types . UID ,  containerName  string )  ( * kubecontainer . Container ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pods ,  err  :=  kl . containerRuntime . GetPods ( false ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 08:42:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									podUID  =  kl . podManager . TranslatePodUID ( podUID ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									pod  :=  kubecontainer . Pods ( pods ) . FindPod ( podFullName ,  podUID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  pod . FindContainerByName ( containerName ) ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Run a command in a container, returns the combined stdout, stderr as an array of bytes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  RunInContainer ( podFullName  string ,  podUID  types . UID ,  containerName  string ,  cmd  [ ] string )  ( [ ] byte ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									container ,  err  :=  kl . findContainer ( podFullName ,  podUID ,  containerName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  container  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil ,  fmt . Errorf ( "container not found (%q)" ,  containerName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-24 01:44:26 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// TODO(timstclair): Pass a proper timeout value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  kl . runner . RunInContainer ( container . ID ,  cmd ,  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// ExecInContainer executes a command in a container, connecting the supplied
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// stdin/stdout/stderr to the command's IO streams.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-24 01:44:26 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  ExecInContainer ( podFullName  string ,  podUID  types . UID ,  containerName  string ,  cmd  [ ] string ,  stdin  io . Reader ,  stdout ,  stderr  io . WriteCloser ,  tty  bool ,  resize  <- chan  term . Size ,  timeout  time . Duration )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 08:42:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									streamingRuntime ,  ok  :=  kl . containerRuntime . ( kubecontainer . DirectStreamingRuntime ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  fmt . Errorf ( "streaming methods not supported by runtime" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									container ,  err  :=  kl . findContainer ( podFullName ,  podUID ,  containerName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  container  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  fmt . Errorf ( "container not found (%q)" ,  containerName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-24 01:44:26 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  streamingRuntime . ExecInContainer ( container . ID ,  cmd ,  stdin ,  stdout ,  stderr ,  tty ,  resize ,  timeout ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// AttachContainer uses the container runtime to attach the given streams to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// the given container.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  AttachContainer ( podFullName  string ,  podUID  types . UID ,  containerName  string ,  stdin  io . Reader ,  stdout ,  stderr  io . WriteCloser ,  tty  bool ,  resize  <- chan  term . Size )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 08:42:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									streamingRuntime ,  ok  :=  kl . containerRuntime . ( kubecontainer . DirectStreamingRuntime ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  fmt . Errorf ( "streaming methods not supported by runtime" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									container ,  err  :=  kl . findContainer ( podFullName ,  podUID ,  containerName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  container  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  fmt . Errorf ( "container not found (%q)" ,  containerName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 08:42:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  streamingRuntime . AttachContainer ( container . ID ,  stdin ,  stdout ,  stderr ,  tty ,  resize ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// PortForward connects to the pod's port and copies data between the port
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// and the stream.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  PortForward ( podFullName  string ,  podUID  types . UID ,  port  uint16 ,  stream  io . ReadWriteCloser )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 08:42:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									streamingRuntime ,  ok  :=  kl . containerRuntime . ( kubecontainer . DirectStreamingRuntime ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  fmt . Errorf ( "streaming methods not supported by runtime" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pods ,  err  :=  kl . containerRuntime . GetPods ( false ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 08:42:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									podUID  =  kl . podManager . TranslatePodUID ( podUID ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									pod  :=  kubecontainer . Pods ( pods ) . FindPod ( podFullName ,  podUID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  pod . IsEmpty ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  fmt . Errorf ( "pod not found (%q)" ,  podFullName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 08:42:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  streamingRuntime . PortForward ( & pod ,  port ,  stream ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// GetExec gets the URL the exec will be served from, or nil if the Kubelet will serve it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  GetExec ( podFullName  string ,  podUID  types . UID ,  containerName  string ,  cmd  [ ] string ,  streamOpts  remotecommand . Options )  ( * url . URL ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  streamingRuntime  :=  kl . containerRuntime . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  kubecontainer . DirectStreamingRuntime : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Kubelet will serve the exec directly.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  kubecontainer . IndirectStreamingRuntime : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										container ,  err  :=  kl . findContainer ( podFullName ,  podUID ,  containerName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  container  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  nil ,  fmt . Errorf ( "container not found (%q)" ,  containerName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  streamingRuntime . GetExec ( container . ID ,  cmd ,  streamOpts . Stdin ,  streamOpts . Stdout ,  streamOpts . Stderr ,  streamOpts . TTY ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil ,  fmt . Errorf ( "container runtime does not support exec" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// GetAttach gets the URL the attach will be served from, or nil if the Kubelet will serve it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  GetAttach ( podFullName  string ,  podUID  types . UID ,  containerName  string ,  streamOpts  remotecommand . Options )  ( * url . URL ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  streamingRuntime  :=  kl . containerRuntime . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  kubecontainer . DirectStreamingRuntime : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Kubelet will serve the attach directly.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  kubecontainer . IndirectStreamingRuntime : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										container ,  err  :=  kl . findContainer ( podFullName ,  podUID ,  containerName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  container  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:36:11 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  nil ,  fmt . Errorf ( "container %s not found in pod %s" ,  containerName ,  podFullName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// The TTY setting for attach must match the TTY setting in the initial container configuration,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// since whether the process is running in a TTY cannot be changed after it has started.  We
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// need the api.Pod to get the TTY status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pod ,  found  :=  kl . GetPodByFullName ( podFullName ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-06 19:49:55 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ! found  ||  ( string ( podUID )  !=  ""  &&  pod . UID  !=  podUID )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:36:11 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  nil ,  fmt . Errorf ( "pod %s not found" ,  podFullName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										containerSpec  :=  kubecontainer . GetContainerSpec ( pod ,  containerName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  containerSpec  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  nil ,  fmt . Errorf ( "container %s not found in pod %s" ,  containerName ,  podFullName ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 08:42:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:36:11 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										tty  :=  containerSpec . TTY 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 08:42:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:36:11 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  streamingRuntime . GetAttach ( container . ID ,  streamOpts . Stdin ,  streamOpts . Stdout ,  streamOpts . Stderr ,  tty ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 08:42:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil ,  fmt . Errorf ( "container runtime does not support attach" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// GetPortForward gets the URL the port-forward will be served from, or nil if the Kubelet will serve it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  GetPortForward ( podName ,  podNamespace  string ,  podUID  types . UID )  ( * url . URL ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  streamingRuntime  :=  kl . containerRuntime . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  kubecontainer . DirectStreamingRuntime : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Kubelet will serve the attach directly.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  kubecontainer . IndirectStreamingRuntime : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pods ,  err  :=  kl . containerRuntime . GetPods ( false ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										podUID  =  kl . podManager . TranslatePodUID ( podUID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										podFullName  :=  kubecontainer . BuildPodFullName ( podName ,  podNamespace ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pod  :=  kubecontainer . Pods ( pods ) . FindPod ( podFullName ,  podUID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  pod . IsEmpty ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  nil ,  fmt . Errorf ( "pod not found (%q)" ,  podFullName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  streamingRuntime . GetPortForward ( podName ,  podNamespace ,  podUID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil ,  fmt . Errorf ( "container runtime does not support port-forward" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 23:58:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-18 01:23:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// cleanupOrphanedPodCgroups removes the Cgroups of pods that should not be
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// running and whose volumes have been cleaned up.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  cleanupOrphanedPodCgroups ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									cgroupPods  map [ types . UID ] cm . CgroupName , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									pods  [ ] * v1 . Pod ,  runningPods  [ ] * kubecontainer . Pod )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-18 01:23:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// Add all running and existing terminated pods to a set allPods
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									allPods  :=  sets . NewString ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  pod  :=  range  pods  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										allPods . Insert ( string ( pod . UID ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  pod  :=  range  runningPods  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										allPods . Insert ( string ( pod . ID ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pcm  :=  kl . containerManager . NewPodContainerManager ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Iterate over all the found pods to verify if they should be running
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  uid ,  val  :=  range  cgroupPods  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  allPods . Has ( string ( uid ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// If volumes have not been unmounted/detached, do not delete the cgroup in case so the charge does not go to the parent.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  podVolumesExist  :=  kl . podVolumesExist ( uid ) ;  podVolumesExist  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											glog . V ( 3 ) . Infof ( "Orphaned pod %q found, but volumes are not cleaned up, Skipping cgroups deletion: %v" ,  uid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										glog . V ( 3 ) . Infof ( "Orphaned pod %q found, removing pod cgroups" ,  uid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Destroy all cgroups of pod that should not be running,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// by first killing all the attached processes to these cgroups.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// We ignore errors thrown by the method, as the housekeeping loop would
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// again try to delete these unwanted pod cgroups
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										go  pcm . Destroy ( val ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 04:45:38 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// enableHostUserNamespace determines if the host user namespace should be used by the container runtime.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Returns true if the pod is using a host pid, pic, or network namespace, the pod is using a non-namespaced
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// capability, the pod contains a privileged container, or the pod has a host path volume.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// NOTE: when if a container shares any namespace with another container it must also share the user namespace
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// or it will not have the correct capabilities in the namespace.  This means that host user namespace
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// is enabled per pod, not per container.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  enableHostUserNamespace ( pod  * v1 . Pod )  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 04:45:38 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  hasPrivilegedContainer ( pod )  ||  hasHostNamespace ( pod )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										hasHostVolume ( pod )  ||  hasNonNamespacedCapability ( pod )  ||  kl . hasHostMountPVC ( pod )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// hasPrivilegedContainer returns true if any of the containers in the pod are privileged.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  hasPrivilegedContainer ( pod  * v1 . Pod )  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 04:45:38 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  _ ,  c  :=  range  pod . Spec . Containers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  c . SecurityContext  !=  nil  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											c . SecurityContext . Privileged  !=  nil  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											* c . SecurityContext . Privileged  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// hasNonNamespacedCapability returns true if MKNOD, SYS_TIME, or SYS_MODULE is requested for any container.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  hasNonNamespacedCapability ( pod  * v1 . Pod )  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 04:45:38 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  _ ,  c  :=  range  pod . Spec . Containers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  c . SecurityContext  !=  nil  &&  c . SecurityContext . Capabilities  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											for  _ ,  cap  :=  range  c . SecurityContext . Capabilities . Add  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  cap  ==  "MKNOD"  ||  cap  ==  "SYS_TIME"  ||  cap  ==  "SYS_MODULE"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// hasHostVolume returns true if the pod spec has a HostPath volume.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  hasHostVolume ( pod  * v1 . Pod )  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 04:45:38 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  _ ,  v  :=  range  pod . Spec . Volumes  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  v . HostPath  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// hasHostNamespace returns true if hostIPC, hostNetwork, or hostPID are set to true.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  hasHostNamespace ( pod  * v1 . Pod )  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 04:45:38 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  pod . Spec . SecurityContext  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  pod . Spec . HostIPC  ||  pod . Spec . HostNetwork  ||  pod . Spec . HostPID 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 04:45:38 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// hasHostMountPVC returns true if a PVC is referencing a HostPath volume.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-19 04:50:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( kl  * Kubelet )  hasHostMountPVC ( pod  * v1 . Pod )  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 04:45:38 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  _ ,  volume  :=  range  pod . Spec . Volumes  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  volume . PersistentVolumeClaim  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											pvc ,  err  :=  kl . kubeClient . Core ( ) . PersistentVolumeClaims ( pod . Namespace ) . Get ( volume . PersistentVolumeClaim . ClaimName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												glog . Warningf ( "unable to retrieve pvc %s:%s - %v" ,  pod . Namespace ,  volume . PersistentVolumeClaim . ClaimName ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  pvc  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												referencedVolume ,  err  :=  kl . kubeClient . Core ( ) . PersistentVolumes ( ) . Get ( pvc . Spec . VolumeName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													glog . Warningf ( "unable to retrieve pvc %s - %v" ,  pvc . Spec . VolumeName ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  referencedVolume  !=  nil  &&  referencedVolume . Spec . HostPath  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}