Skip to content

Commit

Permalink
Exec without devfile/adapters
Browse files Browse the repository at this point in the history
  • Loading branch information
feloy committed Feb 15, 2022
1 parent 5b1f99b commit 1517d4f
Show file tree
Hide file tree
Showing 17 changed files with 263 additions and 769 deletions.
4 changes: 4 additions & 0 deletions pkg/deploy/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,7 @@ func (o *deployHandler) ApplyKubernetes(kubernetes v1alpha2.Component) error {
}
return nil
}

func (o *deployHandler) Execute(command v1alpha2.Command) error {
return errors.New("Exec command is not implemented for Deploy")
}
5 changes: 0 additions & 5 deletions pkg/devfile/adapters/common/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,6 @@ func GetTestCommand(data data.DevfileData, devfileTestCmd string) (runCommand de
return getCommand(data, devfileTestCmd, devfilev1.TestCommandGroupKind)
}

// GetDeployCommand iterates through the components in the devfile and returns the deploy command
func GetDeployCommand(data data.DevfileData, devfileDeployCmd string) (deployCommand devfilev1.Command, err error) {
return getCommand(data, devfileDeployCmd, devfilev1.DeployCommandGroupKind)
}

// ValidateAndGetPushDevfileCommands validates the build and the run command,
// if provided through odo push or else checks the devfile for devBuild and devRun.
// It returns the build and run commands if its validated successfully, error otherwise.
Expand Down
18 changes: 0 additions & 18 deletions pkg/devfile/adapters/common/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,6 @@ import (
"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
)

// NoDefaultForGroup indicates a error when no default command was found for the given Group
type NoDefaultForGroup struct {
Group v1alpha2.CommandGroupKind
}

func (n NoDefaultForGroup) Error() string {
return fmt.Sprintf("there should be exactly one default command for command group %v, currently there is no default command", n.Group)
}

// MoreDefaultForGroup indicates a error when more than one default command was found for the given Group
type MoreDefaultForGroup struct {
Group v1alpha2.CommandGroupKind
}

func (m MoreDefaultForGroup) Error() string {
return fmt.Sprintf("there should be exactly one default command for command group %v, currently there is more than one default command", m.Group)
}

// NoCommandForGroup indicates a error when no command was found for the given Group
type NoCommandForGroup struct {
Group v1alpha2.CommandGroupKind
Expand Down
44 changes: 0 additions & 44 deletions pkg/devfile/adapters/common/generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ package common

import (
"io"
"strings"

devfilev1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
"github.com/devfile/library/pkg/devfile/parser/data/v2/common"
"github.com/pkg/errors"
"github.com/redhat-developer/odo/pkg/log"
"github.com/redhat-developer/odo/pkg/machineoutput"
"github.com/redhat-developer/odo/pkg/util"
"k8s.io/klog"
Expand Down Expand Up @@ -51,10 +49,6 @@ func (a GenericAdapter) Logger() machineoutput.MachineEventLoggingClient {
return a.logger
}

func (a *GenericAdapter) SetLogger(loggingClient machineoutput.MachineEventLoggingClient) {
a.logger = loggingClient
}

func (a GenericAdapter) ComponentInfo(command devfilev1.Command) (ComponentInfo, error) {
return a.componentInfo(command)
}
Expand All @@ -63,11 +57,6 @@ func (a GenericAdapter) SupervisorComponentInfo(command devfilev1.Command) (Comp
return a.supervisordComponentInfo(command)
}

// ExecuteCommand simply calls exec.ExecuteCommand using the GenericAdapter's client
func (a GenericAdapter) ExecuteCommand(compInfo ComponentInfo, command []string, show bool, consoleOutputStdout *io.PipeWriter, consoleOutputStderr *io.PipeWriter) (err error) {
return ExecuteCommand(a.client, compInfo, command, show, consoleOutputStdout, consoleOutputStderr)
}

// closeWriterAndWaitForAck closes the PipeWriter and then waits for a channel response from the ContainerOutputWriter (indicating that the reader had closed).
// This ensures that we always get the full stderr/stdout output from the container process BEFORE we output the devfileCommandExecution event.
func closeWriterAndWaitForAck(stdoutWriter *io.PipeWriter, stdoutChannel chan interface{}, stderrWriter *io.PipeWriter, stderrChannel chan interface{}) {
Expand Down Expand Up @@ -178,39 +167,6 @@ func (a GenericAdapter) addToComposite(commandsMap PushCommandsMap, groupType de
return commands, nil
}

// ExecDevfileEvent receives a Devfile Event (PostStart, PreStop etc.) and loops through them
// Each Devfile Command associated with the given event is retrieved, and executed in the container specified
// in the command
func (a GenericAdapter) ExecDevfileEvent(events []string, eventType DevfileEventType, show bool) error {
if len(events) > 0 {
log.Infof("\nExecuting %s event commands for component %s", string(eventType), a.ComponentName)
commands, err := a.Devfile.Data.GetCommands(common.DevfileOptions{})
if err != nil {
return err
}

commandMap := GetCommandsMap(commands)
for _, commandName := range events {
// Convert commandName to lower because GetCommands converts Command.Exec.Id's to lower
command, ok := commandMap[strings.ToLower(commandName)]
if !ok {
return errors.New("unable to find devfile command " + commandName)
}

c, err := New(command, commandMap, a)
if err != nil {
return err
}
// Execute command in container
err = c.Execute(show)
if err != nil {
return errors.Wrapf(err, "unable to execute devfile command %s", commandName)
}
}
}
return nil
}

func (a GenericAdapter) ApplyComponent(component string) error {
return nil
}
Expand Down
35 changes: 0 additions & 35 deletions pkg/devfile/adapters/common/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@ type PredefinedDevfileCommands string
type DevfileEventType string

const (
// DefaultDevfileInitCommand is a predefined devfile command for init
DefaultDevfileInitCommand PredefinedDevfileCommands = "devinit"

// DefaultDevfileBuildCommand is a predefined devfile command for build
DefaultDevfileBuildCommand PredefinedDevfileCommands = "devbuild"

// DefaultDevfileRunCommand is a predefined devfile command for run
DefaultDevfileRunCommand PredefinedDevfileCommands = "devrun"
Expand All @@ -40,9 +35,6 @@ const (
// use GetBootstrapperImage() function instead of this variable
defaultBootstrapperImage = "registry.access.redhat.com/ocp-tools-4/odo-init-container-rhel8:1.1.11"

// SupervisordControlCommand sub command which stands for control
SupervisordControlCommand = "ctl"

// SupervisordVolumeName Create a custom name and (hope) that users don't use the *exact* same name in their deployment (occlient.go)
SupervisordVolumeName = "odo-supervisord-shared-data"

Expand All @@ -61,18 +53,9 @@ const (
// ENV variable to overwrite image used to bootstrap SupervisorD in S2I and Devfile builder Image
bootstrapperImageEnvName = "ODO_BOOTSTRAPPER_IMAGE"

// BinBash The path to sh executable
BinBash = "/bin/sh"

// DefaultVolumeSize Default volume size for volumes defined in a devfile
DefaultVolumeSize = "1Gi"

// EnvProjectsRoot is the env defined for project mount in a component container when component's mountSources=true
EnvProjectsRoot = "PROJECTS_ROOT"

// EnvProjectsSrc is the env defined for path to the project source in a component container
EnvProjectsSrc = "PROJECT_SOURCE"

// EnvOdoCommandRunWorkingDir is the env defined in the runtime component container which holds the work dir for the run command
EnvOdoCommandRunWorkingDir = "ODO_COMMAND_RUN_WORKING_DIR"

Expand All @@ -93,26 +76,8 @@ const (

// SupervisordCtlSubCommand is the supervisord sub command ctl
SupervisordCtlSubCommand = "ctl"

// PreStart is a devfile event
PreStart DevfileEventType = "preStart"

// PostStart is a devfile event
PostStart DevfileEventType = "postStart"

// PreStop is a devfile event
PreStop DevfileEventType = "preStop"

// PostStop is a devfile event
PostStop DevfileEventType = "postStop"
)

// CommandNames is a struct to store the default and adapter names for devfile commands
type CommandNames struct {
DefaultName string
AdapterName string
}

// GetBootstrapperImage returns the odo-init bootstrapper image
func GetBootstrapperImage() string {
if env, ok := os.LookupEnv(bootstrapperImageEnvName); ok {
Expand Down
50 changes: 7 additions & 43 deletions pkg/devfile/adapters/kubernetes/component/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/redhat-developer/odo/pkg/devfile/adapters/kubernetes/utils"
"github.com/redhat-developer/odo/pkg/envinfo"
"github.com/redhat-developer/odo/pkg/kclient"
"github.com/redhat-developer/odo/pkg/libdevfile"
"github.com/redhat-developer/odo/pkg/log"
"github.com/redhat-developer/odo/pkg/preference"
"github.com/redhat-developer/odo/pkg/service"
Expand Down Expand Up @@ -312,12 +313,11 @@ func (a Adapter) Push(parameters common.PushParameters) (err error) {

// PostStart events from the devfile will only be executed when the component
// didn't previously exist
postStartEvents := a.Devfile.Data.GetEvents().PostStart
if !componentExists && len(postStartEvents) > 0 {
err = a.ExecDevfileEvent(postStartEvents, common.PostStart, parameters.Show)
if !componentExists && libdevfile.HasPostStartEvents(a.Devfile) {
log.Infof("\nExecuting %s event commands for component %s", string(libdevfile.PostStart), a.ComponentName)
err = libdevfile.ExecPostStartEvents(a.Devfile, a.ComponentName, newExecHandler(a.Client, a.pod.Name, parameters.Show))
if err != nil {
return err

}
}

Expand Down Expand Up @@ -673,13 +673,12 @@ func (a Adapter) Delete(labels map[string]string, show bool, wait bool) error {
podSpinner.End(true)

// if there are preStop events, execute them before deleting the deployment
preStopEvents := a.Devfile.Data.GetEvents().PreStop
if len(preStopEvents) > 0 {
if libdevfile.HasPreStopEvents(a.Devfile) {
if pod.Status.Phase != corev1.PodRunning {
return fmt.Errorf("unable to execute preStop events, pod for component %s is not running", a.ComponentName)
}

err = a.ExecDevfileEvent(preStopEvents, common.PreStop, show)
log.Infof("\nExecuting %s event commands for component %s", libdevfile.PreStop, a.ComponentName)
err = libdevfile.ExecPreStopEvents(a.Devfile, a.ComponentName, newExecHandler(a.Client, pod.Name, show))
if err != nil {
return err
}
Expand All @@ -699,41 +698,6 @@ func (a Adapter) Delete(labels map[string]string, show bool, wait bool) error {
return nil
}

// Exec executes a command in the component
func (a Adapter) Exec(command []string) error {
exists, err := component.ComponentExists(a.Client, a.ComponentName, a.AppName)
if err != nil {
return err
}

if !exists {
return errors.Errorf("the component %s doesn't exist on the cluster", a.ComponentName)
}

runCommand, err := common.GetRunCommand(a.Devfile.Data, "")
if err != nil {
return err
}
containerName := runCommand.Exec.Component

// get the pod
pod, err := component.GetOnePod(a.Client, a.ComponentName, a.AppName)
if err != nil {
return errors.Wrapf(err, "unable to get pod for component %s", a.ComponentName)
}

if pod.Status.Phase != corev1.PodRunning {
return fmt.Errorf("unable to exec as the component is not running. Current status=%v", pod.Status.Phase)
}

componentInfo := common.ComponentInfo{
PodName: pod.Name,
ContainerName: containerName,
}

return a.ExecuteCommand(componentInfo, command, true, nil, nil)
}

func (a Adapter) ExecCMDInContainer(componentInfo common.ComponentInfo, cmd []string, stdout io.Writer, stderr io.Writer, stdin io.Reader, tty bool) error {
return a.Client.ExecCMDInContainer(componentInfo.ContainerName, componentInfo.PodName, cmd, stdout, stderr, stdin, tty)
}
Expand Down
13 changes: 0 additions & 13 deletions pkg/devfile/adapters/kubernetes/component/errors.go

This file was deleted.

Loading

0 comments on commit 1517d4f

Please sign in to comment.