...

Source file src/github.com/redhat-developer/odo/pkg/dev/kubedev/utils/utils.go

Documentation: github.com/redhat-developer/odo/pkg/dev/kubedev/utils

     1  package utils
     2  
     3  import (
     4  	"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
     5  	devfileParser "github.com/devfile/library/v2/pkg/devfile/parser"
     6  
     7  	corev1 "k8s.io/api/core/v1"
     8  	"k8s.io/klog"
     9  
    10  	"github.com/redhat-developer/odo/pkg/libdevfile"
    11  	"github.com/redhat-developer/odo/pkg/storage"
    12  )
    13  
    14  const (
    15  	// _envProjectsRoot is the env defined for project mount in a component container when component's mountSources=true
    16  	_envProjectsRoot = "PROJECTS_ROOT"
    17  )
    18  
    19  // GetOdoContainerVolumes returns the mandatory Kube volumes for an Odo component
    20  func GetOdoContainerVolumes(sourcePVCName string) []corev1.Volume {
    21  	var sourceVolume corev1.Volume
    22  
    23  	if sourcePVCName != "" {
    24  		// Define a Persistent volume using the found PVC volume source
    25  		sourceVolume = corev1.Volume{
    26  			Name: storage.OdoSourceVolume,
    27  			VolumeSource: corev1.VolumeSource{
    28  				PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: sourcePVCName},
    29  			},
    30  		}
    31  	} else {
    32  		// Define an Ephemeral volume using an EmptyDir volume source
    33  		sourceVolume = corev1.Volume{
    34  			Name: storage.OdoSourceVolume,
    35  			VolumeSource: corev1.VolumeSource{
    36  				EmptyDir: &corev1.EmptyDirVolumeSource{},
    37  			},
    38  		}
    39  	}
    40  
    41  	return []corev1.Volume{
    42  		sourceVolume,
    43  		{
    44  			// Create a volume that will be shared between InitContainer and the applicationContainer
    45  			// in order to pass over some files for odo
    46  			Name: storage.SharedDataVolumeName,
    47  			VolumeSource: corev1.VolumeSource{
    48  				EmptyDir: &corev1.EmptyDirVolumeSource{},
    49  			},
    50  		},
    51  	}
    52  }
    53  
    54  // AddOdoProjectVolume adds the odo project volume to the containers
    55  func AddOdoProjectVolume(containers []corev1.Container) {
    56  	if containers == nil {
    57  		return
    58  	}
    59  	for i := range containers {
    60  		for _, env := range containers[i].Env {
    61  			if env.Name == _envProjectsRoot {
    62  				containers[i].VolumeMounts = append(containers[i].VolumeMounts, corev1.VolumeMount{
    63  					Name:      storage.OdoSourceVolume,
    64  					MountPath: env.Value,
    65  				})
    66  			}
    67  		}
    68  	}
    69  }
    70  
    71  // AddOdoMandatoryVolume adds the odo mandatory volumes to the containers
    72  func AddOdoMandatoryVolume(containers []corev1.Container) {
    73  	if containers == nil {
    74  		return
    75  	}
    76  	for i := range containers {
    77  		klog.V(2).Infof("Updating container %v with mandatory volume mounts", containers[i].Name)
    78  		containers[i].VolumeMounts = append(containers[i].VolumeMounts, corev1.VolumeMount{
    79  			Name:      storage.SharedDataVolumeName,
    80  			MountPath: storage.SharedDataMountPath,
    81  		})
    82  	}
    83  }
    84  
    85  // UpdateContainersEntrypointsIfNeeded updates the run components entrypoint
    86  // if no entrypoint has been specified for the component in the devfile
    87  func UpdateContainersEntrypointsIfNeeded(
    88  	devfileObj devfileParser.DevfileObj,
    89  	containers []corev1.Container,
    90  	devfileBuildCmd string,
    91  	devfileRunCmd string,
    92  	devfileDebugCmd string,
    93  ) ([]corev1.Container, error) {
    94  	buildCommand, hasBuildCmd, err := libdevfile.GetCommand(devfileObj, devfileBuildCmd, v1alpha2.BuildCommandGroupKind)
    95  	if err != nil {
    96  		return nil, err
    97  	}
    98  	runCommand, hasRunCmd, err := libdevfile.GetCommand(devfileObj, devfileRunCmd, v1alpha2.RunCommandGroupKind)
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  	debugCommand, hasDebugCmd, err := libdevfile.GetCommand(devfileObj, devfileDebugCmd, v1alpha2.DebugCommandGroupKind)
   103  	if err != nil {
   104  		return nil, err
   105  	}
   106  
   107  	var cmdsToHandle []v1alpha2.Command
   108  	if hasBuildCmd {
   109  		cmdsToHandle = append(cmdsToHandle, buildCommand)
   110  	}
   111  	if hasRunCmd {
   112  		cmdsToHandle = append(cmdsToHandle, runCommand)
   113  	}
   114  	if hasDebugCmd {
   115  		cmdsToHandle = append(cmdsToHandle, debugCommand)
   116  	}
   117  
   118  	var components []string
   119  	var containerComps []string
   120  	for _, cmd := range cmdsToHandle {
   121  		containerComps, err = libdevfile.GetContainerComponentsForCommand(devfileObj, cmd)
   122  		if err != nil {
   123  			return nil, err
   124  		}
   125  		components = append(components, containerComps...)
   126  	}
   127  
   128  	for _, c := range components {
   129  		for i := range containers {
   130  			container := &containers[i]
   131  			if container.Name == c {
   132  				overrideContainerCommandAndArgsIfNeeded(container)
   133  			}
   134  		}
   135  	}
   136  
   137  	return containers, nil
   138  
   139  }
   140  
   141  // overrideContainerCommandAndArgsIfNeeded overrides the container's entrypoint
   142  // if the corresponding component does not have any command and/or args in the Devfile.
   143  // This is a workaround until the default Devfile registry exposes stacks with non-terminating containers.
   144  func overrideContainerCommandAndArgsIfNeeded(container *corev1.Container) {
   145  	if len(container.Command) != 0 || len(container.Args) != 0 {
   146  		return
   147  	}
   148  
   149  	klog.V(2).Infof("No entrypoint defined for the component, setting container %v entrypoint to 'tail -f /dev/null'. You can set a 'command' and/or 'args' for the component to override this default entrypoint.", container.Name)
   150  	// #5768: overriding command and args if the container had no Command or Args defined in it.
   151  	// This is a workaround for us to quickly switch to running without Supervisord,
   152  	// while waiting for the Devfile registry to expose stacks with non-terminating containers.
   153  	// TODO(rm3l): Remove this once https://github.com/devfile/registry/pull/102 is merged on the Devfile side
   154  	container.Command = []string{"tail"}
   155  	container.Args = []string{"-f", "/dev/null"}
   156  }
   157  

View as plain text