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
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
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
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