...

Source file src/github.com/redhat-developer/odo/pkg/component/handler.go

Documentation: github.com/redhat-developer/odo/pkg/component

     1  package component
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
     7  	devfilev1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
     8  	"github.com/devfile/library/v2/pkg/devfile/parser"
     9  	"k8s.io/klog"
    10  
    11  	envcontext "github.com/redhat-developer/odo/pkg/config/context"
    12  	"github.com/redhat-developer/odo/pkg/configAutomount"
    13  	"github.com/redhat-developer/odo/pkg/devfile/image"
    14  	"github.com/redhat-developer/odo/pkg/exec"
    15  	"github.com/redhat-developer/odo/pkg/kclient"
    16  	odolabels "github.com/redhat-developer/odo/pkg/labels"
    17  	"github.com/redhat-developer/odo/pkg/libdevfile"
    18  	"github.com/redhat-developer/odo/pkg/log"
    19  	odocontext "github.com/redhat-developer/odo/pkg/odo/context"
    20  	"github.com/redhat-developer/odo/pkg/platform"
    21  	"github.com/redhat-developer/odo/pkg/remotecmd"
    22  	"github.com/redhat-developer/odo/pkg/testingutil/filesystem"
    23  )
    24  
    25  type runHandler struct {
    26  	ctx                   context.Context
    27  	platformClient        platform.Client
    28  	execClient            exec.Client
    29  	configAutomountClient configAutomount.Client
    30  	podName               string
    31  	ComponentExists       bool
    32  	containersRunning     []string
    33  	msg                   string
    34  	directRun             bool
    35  
    36  	fs           filesystem.Filesystem
    37  	imageBackend image.Backend
    38  
    39  	devfile parser.DevfileObj
    40  	path    string
    41  }
    42  
    43  var _ libdevfile.Handler = (*runHandler)(nil)
    44  
    45  type HandlerOptions struct {
    46  	PodName           string
    47  	ComponentExists   bool
    48  	ContainersRunning []string
    49  	Msg               string
    50  	DirectRun         bool
    51  
    52  	// For apply Kubernetes / Openshift
    53  	Devfile parser.DevfileObj
    54  	Path    string
    55  }
    56  
    57  func NewRunHandler(
    58  	ctx context.Context,
    59  	platformClient platform.Client,
    60  	execClient exec.Client,
    61  	configAutomountClient configAutomount.Client,
    62  
    63  	// For building images
    64  	fs filesystem.Filesystem,
    65  	imageBackend image.Backend,
    66  
    67  	options HandlerOptions,
    68  
    69  ) *runHandler {
    70  	return &runHandler{
    71  		ctx:                   ctx,
    72  		platformClient:        platformClient,
    73  		execClient:            execClient,
    74  		configAutomountClient: configAutomountClient,
    75  		podName:               options.PodName,
    76  		ComponentExists:       options.ComponentExists,
    77  		containersRunning:     options.ContainersRunning,
    78  		msg:                   options.Msg,
    79  		directRun:             options.DirectRun,
    80  
    81  		fs:           fs,
    82  		imageBackend: imageBackend,
    83  
    84  		devfile: options.Devfile,
    85  		path:    options.Path,
    86  	}
    87  }
    88  
    89  func (a *runHandler) ApplyImage(img devfilev1.Component) error {
    90  	return image.BuildPushSpecificImage(a.ctx, a.imageBackend, a.fs, img, envcontext.GetEnvConfig(a.ctx).PushImages)
    91  }
    92  
    93  func (a *runHandler) ApplyKubernetes(kubernetes devfilev1.Component, kind v1alpha2.CommandGroupKind) error {
    94  	var (
    95  		componentName = odocontext.GetComponentName(a.ctx)
    96  		appName       = odocontext.GetApplication(a.ctx)
    97  	)
    98  	mode := odolabels.ComponentDevMode
    99  	if kind == v1alpha2.DeployCommandGroupKind {
   100  		mode = odolabels.ComponentDeployMode
   101  	}
   102  	switch platform := a.platformClient.(type) {
   103  	case kclient.ClientInterface:
   104  		return ApplyKubernetes(mode, appName, componentName, a.devfile, kubernetes, platform, a.path)
   105  	default:
   106  		klog.V(4).Info("apply kubernetes/Openshift commands are not implemented on podman")
   107  		log.Warningf("Apply Kubernetes/Openshift components are not supported on Podman. Skipping: %v.", kubernetes.Name)
   108  		return nil
   109  	}
   110  }
   111  
   112  func (a *runHandler) ApplyOpenShift(openshift devfilev1.Component, kind v1alpha2.CommandGroupKind) error {
   113  	return a.ApplyKubernetes(openshift, kind)
   114  }
   115  
   116  func (a *runHandler) ExecuteNonTerminatingCommand(ctx context.Context, command devfilev1.Command) error {
   117  	var (
   118  		componentName = odocontext.GetComponentName(a.ctx)
   119  		appName       = odocontext.GetApplication(a.ctx)
   120  	)
   121  	if isContainerRunning(command.Exec.Component, a.containersRunning) {
   122  		return ExecuteRunCommand(ctx, a.execClient, a.platformClient, command, a.ComponentExists, a.podName, appName, componentName)
   123  	}
   124  	switch platform := a.platformClient.(type) {
   125  	case kclient.ClientInterface:
   126  		return ExecuteInNewContainer(ctx, platform, a.configAutomountClient, a.devfile, componentName, appName, command)
   127  	default:
   128  		klog.V(4).Info("executing a command in a new container is not implemented on podman")
   129  		log.Warningf("executing a command in a new container is not implemented on podman. Skipping: %v.", command.Id)
   130  		return nil
   131  	}
   132  }
   133  
   134  func (a *runHandler) ExecuteTerminatingCommand(ctx context.Context, command devfilev1.Command) error {
   135  	var (
   136  		componentName = odocontext.GetComponentName(a.ctx)
   137  		appName       = odocontext.GetApplication(a.ctx)
   138  	)
   139  	if isContainerRunning(command.Exec.Component, a.containersRunning) {
   140  		return ExecuteTerminatingCommand(ctx, a.execClient, a.platformClient, command, a.ComponentExists, a.podName, appName, componentName, a.msg, a.directRun)
   141  	}
   142  	switch platform := a.platformClient.(type) {
   143  	case kclient.ClientInterface:
   144  		return ExecuteInNewContainer(ctx, platform, a.configAutomountClient, a.devfile, componentName, appName, command)
   145  	default:
   146  		klog.V(4).Info("executing a command in a new container is not implemented on podman")
   147  		log.Warningf("executing a command in a new container is not implemented on podman. Skipping: %v.", command.Id)
   148  		return nil
   149  	}
   150  }
   151  
   152  // IsRemoteProcessForCommandRunning returns true if the command is running
   153  func (a *runHandler) IsRemoteProcessForCommandRunning(ctx context.Context, command devfilev1.Command, podName string) (bool, error) {
   154  	remoteProcess, err := remotecmd.NewKubeExecProcessHandler(a.execClient).GetProcessInfoForCommand(ctx, remotecmd.CommandDefinition{Id: command.Id}, podName, command.Exec.Component)
   155  	if err != nil {
   156  		return false, err
   157  	}
   158  
   159  	return remoteProcess.Status == remotecmd.Running, nil
   160  }
   161  
   162  func isContainerRunning(container string, containers []string) bool {
   163  	for _, cnt := range containers {
   164  		if container == cnt {
   165  			return true
   166  		}
   167  	}
   168  	return false
   169  }
   170  

View as plain text