Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Docker and Kubernetes adapter to use groups #3206

Merged
merged 2 commits into from
May 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 27 additions & 8 deletions pkg/devfile/adapters/common/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,23 @@ func getCommand(data data.DevfileData, commandName string, groupType common.Devf
if commandName != "" {

if command.Exec.Id == commandName {

if supportedCommand.Exec.Group.Kind == "" {
// Devfile V1 for commands passed from flags
// Group type is not updated during conversion
command.Exec.Group.Kind = groupType
}

// we have found the command with name, its groupType Should match to the flag
// e.g --build-command "mybuild"
// exec:
// id: mybuild
// group:
// kind: build
if command.Exec.Group.Kind != groupType {
return supportedCommand, fmt.Errorf("mismatched type, command %s is of type %v groupType in devfile", commandName, groupType)

}
supportedCommand = command
return supportedCommand, nil
}
Expand Down Expand Up @@ -65,7 +82,7 @@ func getCommand(data data.DevfileData, commandName string, groupType common.Devf
func validateCommand(data data.DevfileData, command common.DevfileCommand) (err error) {

// type must be exec
if command.Type != common.ExecCommandType {
if command.Exec == nil {
return fmt.Errorf("Command must be of type \"exec\"")
}

Expand All @@ -84,7 +101,7 @@ func validateCommand(data data.DevfileData, command common.DevfileCommand) (err

isActionValid := false
for _, component := range components {
if command.Exec.Component == component.Container.Name && isComponentSupported(component) {
if command.Exec.Component == component.Container.Name {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't we need the isComponentSupported check? It seems to be modified below

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a redundant check, we are already doing the same check in GetSupportedComponents

https://github.com/openshift/odo/blob/master/pkg/devfile/adapters/common/utils.go#L101

isActionValid = true
}
}
Expand Down Expand Up @@ -127,8 +144,10 @@ func GetRunCommand(data data.DevfileData, devfileRunCmd string) (runCommand comm
// 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.
func ValidateAndGetPushDevfileCommands(data data.DevfileData, devfileInitCmd, devfileBuildCmd, devfileRunCmd string) (pushDevfileCommands []common.DevfileCommand, err error) {
func ValidateAndGetPushDevfileCommands(data data.DevfileData, devfileInitCmd, devfileBuildCmd, devfileRunCmd string) (commandMap PushCommandsMap, err error) {
var emptyCommand common.DevfileCommand
commandMap = NewPushCommandMap()

isInitCommandValid, isBuildCommandValid, isRunCommandValid := false, false, false

initCommand, initCmdErr := GetInitCommand(data, devfileInitCmd)
Expand All @@ -140,7 +159,7 @@ func ValidateAndGetPushDevfileCommands(data data.DevfileData, devfileInitCmd, de
klog.V(3).Infof("No init command was provided")
} else if !isInitCmdEmpty && initCmdErr == nil {
isInitCommandValid = true
pushDevfileCommands = append(pushDevfileCommands, initCommand)
commandMap[common.InitCommandGroupType] = initCommand
klog.V(3).Infof("Init command: %v", initCommand.Exec.Id)
}

Expand All @@ -153,14 +172,14 @@ func ValidateAndGetPushDevfileCommands(data data.DevfileData, devfileInitCmd, de
klog.V(3).Infof("No build command was provided")
} else if !reflect.DeepEqual(emptyCommand, buildCommand) && buildCmdErr == nil {
isBuildCommandValid = true
pushDevfileCommands = append(pushDevfileCommands, buildCommand)
commandMap[common.BuildCommandGroupType] = buildCommand
klog.V(3).Infof("Build command: %v", buildCommand.Exec.Id)
}

runCommand, runCmdErr := GetRunCommand(data, devfileRunCmd)
if runCmdErr == nil && !reflect.DeepEqual(emptyCommand, runCommand) {
pushDevfileCommands = append(pushDevfileCommands, runCommand)
isRunCommandValid = true
commandMap[common.RunCommandGroupType] = runCommand
klog.V(3).Infof("Run command: %v", runCommand.Exec.Id)
}

Expand All @@ -176,8 +195,8 @@ func ValidateAndGetPushDevfileCommands(data data.DevfileData, devfileInitCmd, de
if runCmdErr != nil {
commandErrors += fmt.Sprintf(runCmdErr.Error(), "\n")
}
return []common.DevfileCommand{}, fmt.Errorf(commandErrors)
return commandMap, fmt.Errorf(commandErrors)
}

return pushDevfileCommands, nil
return commandMap, nil
}
9 changes: 9 additions & 0 deletions pkg/devfile/adapters/common/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package common

import (
devfileParser "github.com/openshift/odo/pkg/devfile/parser"
"github.com/openshift/odo/pkg/devfile/parser/data/common"
"github.com/openshift/odo/pkg/envinfo"
)

Expand Down Expand Up @@ -52,3 +53,11 @@ type ComponentInfo struct {
PodName string
ContainerName string
}

// PushCommandsMap stores the commands to be executed as per there types.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

their types

type PushCommandsMap map[common.DevfileCommandGroupType]common.DevfileCommand

// NewPushCommandMap returns the instance of PushCommandsMap
func NewPushCommandMap() PushCommandsMap {
return make(map[common.DevfileCommandGroupType]common.DevfileCommand)
}
7 changes: 5 additions & 2 deletions pkg/devfile/adapters/common/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,11 @@ type CommandNames struct {
}

func isComponentSupported(component common.DevfileComponent) bool {
// Currently odo only uses devfile components of type dockerimage, since most of the Che registry devfiles use it
return component.Type == common.ContainerComponentType
// Currently odo only uses devfile components of type container, since most of the Che registry devfiles use it
if component.Container != nil {
return true
}
return false
}

// GetBootstrapperImage returns the odo-init bootstrapper image
Expand Down
104 changes: 44 additions & 60 deletions pkg/devfile/adapters/docker/component/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,77 +344,61 @@ func getPortMap(context string, endpoints []*versionsCommon.Endpoint, show bool)

// Executes all the commands from the devfile in order: init and build - which are both optional, and a compulsary run.
// Init only runs once when the component is created.
func (a Adapter) execDevfile(pushDevfileCommands []versionsCommon.DevfileCommand, componentExists, show bool, containers []types.Container) (err error) {
func (a Adapter) execDevfile(commandsMap common.PushCommandsMap, componentExists, show bool, containers []types.Container) (err error) {
// If nothing has been passed, then the devfile is missing the required run command
if len(pushDevfileCommands) == 0 {
if len(commandsMap) == 0 {
return errors.New(fmt.Sprint("error executing devfile commands - there should be at least 1 command"))
}

commandOrder := []common.CommandNames{}

// Only add runinit to the expected commands if the component doesn't already exist
// This would be the case when first running the container
if !componentExists {
commandOrder = append(commandOrder, common.CommandNames{DefaultName: string(common.DefaultDevfileInitCommand), AdapterName: a.devfileInitCmd})
// Get Init Command
command, ok := commandsMap[versionsCommon.InitCommandGroupType]
if ok {

containerID := utils.GetContainerIDForAlias(containers, command.Exec.Component)
mik-dass marked this conversation as resolved.
Show resolved Hide resolved
compInfo := common.ComponentInfo{ContainerName: containerID}
err = exec.ExecuteDevfileBuildAction(&a.Client, *command.Exec, command.Exec.Id, compInfo, show)
if err != nil {
return err
}
}
}
commandOrder = append(
commandOrder,
common.CommandNames{DefaultName: string(common.DefaultDevfileBuildCommand), AdapterName: a.devfileBuildCmd},
common.CommandNames{DefaultName: string(common.DefaultDevfileRunCommand), AdapterName: a.devfileRunCmd},
)

// Loop through each of the expected commands in the devfile
for i, currentCommand := range commandOrder {
// Loop through each of the command given from the devfile
for _, command := range pushDevfileCommands {
// If the current command from the devfile is the currently expected command from the devfile
if command.Exec.Id == currentCommand.DefaultName || command.Exec.Id == currentCommand.AdapterName {
// If the current command is not the last command in the slice
// it is not expected to be the run command
if i < len(commandOrder)-1 {
// Any exec command such as "Init" and "Build"

containerID := utils.GetContainerIDForAlias(containers, command.Exec.Component)
compInfo := common.ComponentInfo{
ContainerName: containerID,
}

err = exec.ExecuteDevfileBuildAction(&a.Client, *command.Exec, command.Exec.Id, compInfo, show)
if err != nil {
return err
}

// If the current command is the last command in the slice
// it is expected to be the run command
} else {
// Last command is "Run"
klog.V(4).Infof("Executing devfile command %v", command.Exec.Id)

// Check if the devfile run component containers have supervisord as the entrypoint.
// Start the supervisord if the odo component does not exist
if !componentExists {
err = a.InitRunContainerSupervisord(command.Exec.Component, containers)
if err != nil {
return
}
}

containerID := utils.GetContainerIDForAlias(containers, command.Exec.Component)
compInfo := common.ComponentInfo{
ContainerName: containerID,
}

if componentExists && !common.IsRestartRequired(command) {
klog.V(4).Info("restart:false, Not restarting DevRun Command")
err = exec.ExecuteDevfileRunActionWithoutRestart(&a.Client, *command.Exec, command.Exec.Id, compInfo, show)
return
}

err = exec.ExecuteDevfileRunAction(&a.Client, *command.Exec, command.Exec.Id, compInfo, show)

}
// Get Build Command
command, ok := commandsMap[versionsCommon.BuildCommandGroupType]
if ok {
containerID := utils.GetContainerIDForAlias(containers, command.Exec.Component)
compInfo := common.ComponentInfo{ContainerName: containerID}
err = exec.ExecuteDevfileBuildAction(&a.Client, *command.Exec, command.Exec.Id, compInfo, show)
if err != nil {
return err
}
}

// Get Run command
command, ok = commandsMap[versionsCommon.RunCommandGroupType]
if ok {
klog.V(4).Infof("Executing devfile command %v", command.Exec.Id)

// Check if the devfile run component containers have supervisord as the entrypoint.
// Start the supervisord if the odo component does not exist
if !componentExists {
err = a.InitRunContainerSupervisord(command.Exec.Component, containers)
if err != nil {
return
}
}

containerID := utils.GetContainerIDForAlias(containers, command.Exec.Component)
compInfo := common.ComponentInfo{ContainerName: containerID}
if componentExists && !common.IsRestartRequired(command) {
klog.V(4).Info("restart:false, Not restarting DevRun Command")
err = exec.ExecuteDevfileRunActionWithoutRestart(&a.Client, *command.Exec, command.Exec.Id, compInfo, show)
return
}
err = exec.ExecuteDevfileRunAction(&a.Client, *command.Exec, command.Exec.Id, compInfo, show)
}

return
Expand Down
108 changes: 48 additions & 60 deletions pkg/devfile/adapters/kubernetes/component/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,76 +305,64 @@ func (a Adapter) waitAndGetComponentPod(hideSpinner bool) (*corev1.Pod, error) {

// Executes all the commands from the devfile in order: init and build - which are both optional, and a compulsary run.
// Init only runs once when the component is created.
func (a Adapter) execDevfile(pushDevfileCommands []versionsCommon.DevfileCommand, componentExists, show bool, podName string, containers []corev1.Container) (err error) {
func (a Adapter) execDevfile(commandsMap common.PushCommandsMap, componentExists, show bool, podName string, containers []corev1.Container) (err error) {
// If nothing has been passed, then the devfile is missing the required run command
if len(pushDevfileCommands) == 0 {
if len(commandsMap) == 0 {
return errors.New(fmt.Sprint("error executing devfile commands - there should be at least 1 command"))
}

commandOrder := []common.CommandNames{}
compInfo := common.ComponentInfo{
PodName: podName,
}

// Only add runinit to the expected commands if the component doesn't already exist
// This would be the case when first running the container
if !componentExists {
commandOrder = append(commandOrder, common.CommandNames{DefaultName: string(common.DefaultDevfileInitCommand), AdapterName: a.devfileInitCmd})
}
commandOrder = append(
commandOrder,
common.CommandNames{DefaultName: string(common.DefaultDevfileBuildCommand), AdapterName: a.devfileBuildCmd},
common.CommandNames{DefaultName: string(common.DefaultDevfileRunCommand), AdapterName: a.devfileRunCmd},
)

// Loop through each of the expected commands in the devfile
for i, currentCommand := range commandOrder {
// Loop through each of the command given from the devfile
for _, command := range pushDevfileCommands {
// If the current command from the devfile is the currently expected command from the devfile
if command.Exec.Id == currentCommand.DefaultName || command.Exec.Id == currentCommand.AdapterName {
// If the current command is not the last command in the slice
// it is not expected to be the run command
if i < len(commandOrder)-1 {
// Any exec command such as "Init" and "Build"

compInfo := common.ComponentInfo{
ContainerName: command.Exec.Component,
PodName: podName,
}

err = exec.ExecuteDevfileBuildAction(&a.Client, *command.Exec, command.Exec.Id, compInfo, show)
if err != nil {
return err
}

// If the current command is the last command in the slice
// it is expected to be the run command
} else {
// Last command is "Run"
klog.V(4).Infof("Executing devfile command %v", command.Exec.Id)

// Check if the devfile run component containers have supervisord as the entrypoint.
// Start the supervisord if the odo component does not exist
if !componentExists {
err = a.InitRunContainerSupervisord(command.Exec.Component, podName, containers)
if err != nil {
return
}
}

compInfo := common.ComponentInfo{
ContainerName: command.Exec.Component,
PodName: podName,
}

if componentExists && !common.IsRestartRequired(command) {
klog.V(4).Infof("restart:false, Not restarting DevRun Command")
err = exec.ExecuteDevfileRunActionWithoutRestart(&a.Client, *command.Exec, command.Exec.Id, compInfo, show)
return
}

err = exec.ExecuteDevfileRunAction(&a.Client, *command.Exec, command.Exec.Id, compInfo, show)
}
// Get Init Command
command, ok := commandsMap[versionsCommon.InitCommandGroupType]
if ok {
compInfo.ContainerName = command.Exec.Component
err = exec.ExecuteDevfileBuildAction(&a.Client, *command.Exec, command.Exec.Id, compInfo, show)
if err != nil {
return err
}

}

}

// Get Build Command
command, ok := commandsMap[versionsCommon.BuildCommandGroupType]
if ok {
compInfo.ContainerName = command.Exec.Component
err = exec.ExecuteDevfileBuildAction(&a.Client, *command.Exec, command.Exec.Id, compInfo, show)
if err != nil {
return err
}
}

// Get Run Command
command, ok = commandsMap[versionsCommon.RunCommandGroupType]
if ok {
klog.V(4).Infof("Executing devfile command %v", command.Exec.Id)
compInfo.ContainerName = command.Exec.Component

// Check if the devfile run component containers have supervisord as the entrypoint.
// Start the supervisord if the odo component does not exist
if !componentExists {
err = a.InitRunContainerSupervisord(command.Exec.Component, podName, containers)
if err != nil {
return
}
}

if componentExists && !common.IsRestartRequired(command) {
klog.V(4).Infof("restart:false, Not restarting DevRun Command")
err = exec.ExecuteDevfileRunActionWithoutRestart(&a.Client, *command.Exec, command.Exec.Id, compInfo, show)
return
}
err = exec.ExecuteDevfileRunAction(&a.Client, *command.Exec, command.Exec.Id, compInfo, show)

}

return
Expand Down