@@ -193,7 +193,7 @@ func parseTimeString(str string) (time.Time, error) {
193193 return t , nil
194194}
195195
196- func (r * runtime ) getContainerStatus (container ContainerStatus , image , imageID , startTime string ) * kubecontainer.ContainerStatus {
196+ func (r * runtime ) getContainerStatus (container ContainerStatus , image , imageID , startTime string , podLabels map [ string ] string ) * kubecontainer.ContainerStatus {
197197 status := & kubecontainer.ContainerStatus {}
198198
199199 _ , _ , _ , containerName , restartCount , _ , err := r .parseHyperContainerFullName (container .Name )
@@ -246,10 +246,17 @@ func (r *runtime) getContainerStatus(container ContainerStatus, image, imageID,
246246 status .FinishedAt = terminatedFinishedAt
247247 }
248248
249+ var message string
250+ path := podLabels [containerName ]
251+ if data , err := ioutil .ReadFile (path ); err != nil {
252+ message = fmt .Sprintf ("Error on reading termination-log %s: %v" , path , err )
253+ } else {
254+ message = string (data )
255+ }
256+
257+ status .Message = message
249258 status .State = kubecontainer .ContainerStateExited
250259 status .Reason = container .Terminated .Reason
251-
252- status .Message = container .Terminated .Message
253260 status .ExitCode = container .Terminated .ExitCode
254261 default :
255262 if startTime == "" {
@@ -470,6 +477,7 @@ func (r *runtime) buildHyperPod(pod *api.Pod, restartCount int, pullSecrets []ap
470477 var containers []map [string ]interface {}
471478 var k8sHostNeeded = true
472479 dnsServers := make (map [string ]string )
480+ terminationMsgLabels := make (map [string ]string )
473481 for _ , container := range pod .Spec .Containers {
474482 c := make (map [string ]interface {})
475483 c [KEY_NAME ] = r .buildHyperContainerFullName (
@@ -527,6 +535,38 @@ func (r *runtime) buildHyperPod(pod *api.Pod, restartCount int, pullSecrets []ap
527535 }
528536 c [KEY_PORTS ] = ports
529537
538+ // NOTE: PodContainerDir is from TerminationMessagePath, TerminationMessagePath is default to /dev/termination-log
539+ if opts .PodContainerDir != "" && container .TerminationMessagePath != "" {
540+ // In docker runtime, the container log path contains the container ID.
541+ // However, for hyper runtime, we cannot get the container ID before the
542+ // the container is launched, so here we generate a random uuid to enable
543+ // us to map a container's termination message path to an unique log file
544+ // on the disk.
545+ randomUID := util .NewUUID ()
546+ containerLogPath := path .Join (opts .PodContainerDir , string (randomUID ))
547+ fs , err := os .Create (containerLogPath )
548+ if err != nil {
549+ return nil , err
550+ }
551+
552+ if err := fs .Close (); err != nil {
553+ return nil , err
554+ }
555+ mnt := & kubecontainer.Mount {
556+ // Use a random name for the termination message mount, so that
557+ // when a container restarts, it will not overwrite the old termination
558+ // message.
559+ Name : fmt .Sprintf ("termination-message-%s" , randomUID ),
560+ ContainerPath : container .TerminationMessagePath ,
561+ HostPath : containerLogPath ,
562+ ReadOnly : false ,
563+ }
564+ opts .Mounts = append (opts .Mounts , * mnt )
565+
566+ // set termination msg labels with host path
567+ terminationMsgLabels [container .Name ] = mnt .HostPath
568+ }
569+
530570 // volumes
531571 if len (opts .Mounts ) > 0 {
532572 var containerVolumes []map [string ]interface {}
@@ -537,14 +577,27 @@ func (r *runtime) buildHyperPod(pod *api.Pod, restartCount int, pullSecrets []ap
537577 v [KEY_READONLY ] = volume .ReadOnly
538578 containerVolumes = append (containerVolumes , v )
539579
540- // Setup global hosts volume
541- if volume .Name == "k8s-managed-etc-hosts" && k8sHostNeeded {
542- k8sHostNeeded = false
543- volumes = append (volumes , map [string ]interface {}{
544- KEY_NAME : volume .Name ,
545- KEY_VOLUME_DRIVE : VOLUME_TYPE_VFS ,
546- KEY_VOLUME_SOURCE : volume .HostPath ,
547- })
580+ if k8sHostNeeded {
581+ // Setup global hosts volume
582+ if volume .Name == "k8s-managed-etc-hosts" {
583+ k8sHostNeeded = false
584+ volumes = append (volumes , map [string ]interface {}{
585+ KEY_NAME : volume .Name ,
586+ KEY_VOLUME_DRIVE : VOLUME_TYPE_VFS ,
587+ KEY_VOLUME_SOURCE : volume .HostPath ,
588+ })
589+ }
590+
591+ // Setup global termination msg volume
592+ if strings .HasPrefix (volume .Name , "termination-message" ) {
593+ k8sHostNeeded = false
594+
595+ volumes = append (volumes , map [string ]interface {}{
596+ KEY_NAME : volume .Name ,
597+ KEY_VOLUME_DRIVE : VOLUME_TYPE_VFS ,
598+ KEY_VOLUME_SOURCE : volume .HostPath ,
599+ })
600+ }
548601 }
549602 }
550603 c [KEY_VOLUMES ] = containerVolumes
@@ -609,6 +662,11 @@ func (r *runtime) buildHyperPod(pod *api.Pod, restartCount int, pullSecrets []ap
609662 podLabels [k ] = v
610663 }
611664
665+ // append termination message label
666+ for k , v := range terminationMsgLabels {
667+ podLabels [k ] = v
668+ }
669+
612670 specMap [KEY_LABELS ] = podLabels
613671
614672 // other params required
@@ -1060,10 +1118,11 @@ func (r *runtime) GetPodStatus(uid types.UID, name, namespace string) (*kubecont
10601118 for _ , containerInfo := range podInfo .PodInfo .Status .Status {
10611119 for _ , container := range podInfo .PodInfo .Spec .Containers {
10621120 if container .ContainerID == containerInfo .ContainerID {
1121+ c := r .getContainerStatus (containerInfo , container .Image , container .ImageID ,
1122+ podInfo .PodInfo .Status .StartTime , podInfo .PodInfo .Spec .Labels )
10631123 status .ContainerStatuses = append (
10641124 status .ContainerStatuses ,
1065- r .getContainerStatus (containerInfo , container .Image , container .ImageID ,
1066- podInfo .PodInfo .Status .StartTime ))
1125+ c )
10671126 }
10681127 }
10691128 }
0 commit comments