Do not use env.yaml file anymore (#6057)

* Remove GetApplication from LocalConfigProvider interface and all related stuff

* Remove GetName from LocalConfigProvider interface and all related stuff

* Remove GetContainers from LocalConfigProvider interface

* Remove Exists method from LocalConfigProvider interface and stop odo dev writing env.yaml file

* Remove GetDebugort method from LocalConfigProvider interface + fix #6056

* Remove unnecessary fields from EnvInfo structure

* Remove all references to env.yaml file

* Review

* Test for #6056
This commit is contained in:
Philippe Martin
2022-08-29 15:25:09 +02:00
committed by GitHub
parent bda53f15f3
commit 0a83f1d899
43 changed files with 1259 additions and 2893 deletions

View File

@@ -414,12 +414,3 @@ This state file contains the forwarded ports:
]
}
```
## Env File
When `odo dev` is executed, a `.odo/env/env.yaml` file is created if it does not exist. It stores the namespace/project that will be used by the component during the dev session. The value is removed from the file at the end of the session.
```yaml
ComponentSettings:
Project: myproject
```

View File

@@ -70,22 +70,6 @@ func GatherName(devObj parser.DevfileObj, devfilePath string) (string, error) {
return filepath.Base(filepath.Dir(sourcePath)), nil
}
// Exists checks whether a component with the given name exists in the current application or not
// componentName is the component name to perform check for
// The first returned parameter is a bool indicating if a component with the given name already exists or not
// The second returned parameter is the error that might occurs while execution
func Exists(client kclient.ClientInterface, componentName, applicationName string) (bool, error) {
deploymentName, err := dfutil.NamespaceOpenShiftObject(componentName, applicationName)
if err != nil {
return false, fmt.Errorf("unable to create namespaced name: %w", err)
}
deployment, _ := client.GetDeploymentByName(deploymentName)
if deployment != nil {
return true, nil
}
return false, nil
}
// GetOnePod gets a pod using the component and app name
func GetOnePod(client kclient.ClientInterface, componentName string, appName string) (*corev1.Pod, error) {
return client.GetRunningPodFromSelector(odolabels.GetSelector(componentName, appName, odolabels.ComponentDevMode, false))

View File

@@ -76,7 +76,6 @@ func (o *DevClient) Start(
pushParameters := adapters.PushParameters{
EnvSpecificInfo: *envSpecificInfo,
DebugPort: envSpecificInfo.GetDebugPort(),
Path: path,
IgnoredFiles: ignorePaths,
Debug: debug,
@@ -130,7 +129,6 @@ func (o *DevClient) Watch(
Debug: debug,
DevfileBuildCmd: buildCommand,
DevfileRunCmd: runCommand,
DebugPort: envSpecificInfo.GetDebugPort(),
Variables: variables,
RandomPorts: randomPorts,
WatchFiles: watchFiles,

View File

@@ -6,39 +6,40 @@ package dev
import (
context "context"
io "io"
reflect "reflect"
parser "github.com/devfile/library/pkg/devfile/parser"
gomock "github.com/golang/mock/gomock"
adapters "github.com/redhat-developer/odo/pkg/devfile/adapters"
filesystem "github.com/redhat-developer/odo/pkg/testingutil/filesystem"
watch "github.com/redhat-developer/odo/pkg/watch"
io "io"
reflect "reflect"
)
// MockClient is a mock of Client interface
// MockClient is a mock of Client interface.
type MockClient struct {
ctrl *gomock.Controller
recorder *MockClientMockRecorder
}
// MockClientMockRecorder is the mock recorder for MockClient
// MockClientMockRecorder is the mock recorder for MockClient.
type MockClientMockRecorder struct {
mock *MockClient
}
// NewMockClient creates a new mock instance
// NewMockClient creates a new mock instance.
func NewMockClient(ctrl *gomock.Controller) *MockClient {
mock := &MockClient{ctrl: ctrl}
mock.recorder = &MockClientMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockClient) EXPECT() *MockClientMockRecorder {
return m.recorder
}
// Start mocks base method
// Start mocks base method.
func (m *MockClient) Start(devfileObj parser.DevfileObj, namespace string, ignorePaths []string, path string, debug bool, buildCommand, runCommand string, randomPorts bool, errOut io.Writer, fs filesystem.Filesystem) (watch.ComponentStatus, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Start", devfileObj, namespace, ignorePaths, path, debug, buildCommand, runCommand, randomPorts, errOut, fs)
@@ -47,13 +48,13 @@ func (m *MockClient) Start(devfileObj parser.DevfileObj, namespace string, ignor
return ret0, ret1
}
// Start indicates an expected call of Start
// Start indicates an expected call of Start.
func (mr *MockClientMockRecorder) Start(devfileObj, namespace, ignorePaths, path, debug, buildCommand, runCommand, randomPorts, errOut, fs interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Start", reflect.TypeOf((*MockClient)(nil).Start), devfileObj, namespace, ignorePaths, path, debug, buildCommand, runCommand, randomPorts, errOut, fs)
}
// Watch mocks base method
// Watch mocks base method.
func (m *MockClient) Watch(devfilePath string, devfileObj parser.DevfileObj, path string, ignorePaths []string, out io.Writer, h Handler, ctx context.Context, debug bool, buildCommand, runCommand string, variables map[string]string, randomPorts, watchFiles bool, errOut io.Writer, componentStatus watch.ComponentStatus) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Watch", devfilePath, devfileObj, path, ignorePaths, out, h, ctx, debug, buildCommand, runCommand, variables, randomPorts, watchFiles, errOut, componentStatus)
@@ -61,36 +62,36 @@ func (m *MockClient) Watch(devfilePath string, devfileObj parser.DevfileObj, pat
return ret0
}
// Watch indicates an expected call of Watch
// Watch indicates an expected call of Watch.
func (mr *MockClientMockRecorder) Watch(devfilePath, devfileObj, path, ignorePaths, out, h, ctx, debug, buildCommand, runCommand, variables, randomPorts, watchFiles, errOut, componentStatus interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Watch", reflect.TypeOf((*MockClient)(nil).Watch), devfilePath, devfileObj, path, ignorePaths, out, h, ctx, debug, buildCommand, runCommand, variables, randomPorts, watchFiles, errOut, componentStatus)
}
// MockHandler is a mock of Handler interface
// MockHandler is a mock of Handler interface.
type MockHandler struct {
ctrl *gomock.Controller
recorder *MockHandlerMockRecorder
}
// MockHandlerMockRecorder is the mock recorder for MockHandler
// MockHandlerMockRecorder is the mock recorder for MockHandler.
type MockHandlerMockRecorder struct {
mock *MockHandler
}
// NewMockHandler creates a new mock instance
// NewMockHandler creates a new mock instance.
func NewMockHandler(ctrl *gomock.Controller) *MockHandler {
mock := &MockHandler{ctrl: ctrl}
mock.recorder = &MockHandlerMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockHandler) EXPECT() *MockHandlerMockRecorder {
return m.recorder
}
// RegenerateAdapterAndPush mocks base method
// RegenerateAdapterAndPush mocks base method.
func (m *MockHandler) RegenerateAdapterAndPush(arg0 adapters.PushParameters, arg1 watch.WatchParameters, arg2 *watch.ComponentStatus) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "RegenerateAdapterAndPush", arg0, arg1, arg2)
@@ -98,7 +99,7 @@ func (m *MockHandler) RegenerateAdapterAndPush(arg0 adapters.PushParameters, arg
return ret0
}
// RegenerateAdapterAndPush indicates an expected call of RegenerateAdapterAndPush
// RegenerateAdapterAndPush indicates an expected call of RegenerateAdapterAndPush.
func (mr *MockHandlerMockRecorder) RegenerateAdapterAndPush(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegenerateAdapterAndPush", reflect.TypeOf((*MockHandler)(nil).RegenerateAdapterAndPush), arg0, arg1, arg2)

View File

@@ -121,7 +121,7 @@ func (a Adapter) Push(parameters adapters.PushParameters, componentStatus *watch
BuildCmd: parameters.DevfileBuildCmd,
RunCmd: parameters.DevfileRunCmd,
DebugCmd: parameters.DevfileDebugCmd,
}, parameters.DebugPort, deployment)
}, deployment)
if err != nil {
return fmt.Errorf("unable to create or update component: %w", err)
}
@@ -319,7 +319,6 @@ func (a *Adapter) createOrUpdateComponent(
componentExists bool,
ei envinfo.EnvSpecificInfo,
commands libdevfile.DevfileCommands,
devfileDebugPort int,
deployment *appsv1.Deployment,
) (*appsv1.Deployment, bool, error) {
@@ -364,11 +363,6 @@ func (a *Adapter) createOrUpdateComponent(
utils.AddOdoProjectVolume(&containers)
utils.AddOdoMandatoryVolume(&containers)
containers, err = utils.UpdateContainerEnvVars(a.Devfile, containers, commands.DebugCmd, devfileDebugPort)
if err != nil {
return nil, false, err
}
containers, err = utils.UpdateContainersEntrypointsIfNeeded(a.Devfile, containers, commands.BuildCmd, commands.RunCmd, commands.DebugCmd)
if err != nil {
return nil, false, err

View File

@@ -125,15 +125,12 @@ func TestCreateOrUpdateComponent(t *testing.T) {
return true, &deployment, nil
})
}
tt.envInfo.EnvInfo = *envinfo.GetFakeEnvInfo(envinfo.ComponentSettings{
Name: testComponentName,
AppName: testAppName,
})
tt.envInfo.EnvInfo = envinfo.EnvInfo{}
ctrl := gomock.NewController(t)
fakePrefClient := preference.NewMockClient(ctrl)
fakePrefClient.EXPECT().GetEphemeralSourceVolume()
componentAdapter := NewKubernetesAdapter(fkclient, fakePrefClient, nil, nil, adapterCtx, "")
_, _, err := componentAdapter.createOrUpdateComponent(tt.running, tt.envInfo, libdevfile.DevfileCommands{}, 0, nil)
_, _, err := componentAdapter.createOrUpdateComponent(tt.running, tt.envInfo, libdevfile.DevfileCommands{}, nil)
// Checks for unexpected error cases
if !tt.wantErr == (err != nil) {

View File

@@ -1,8 +1,6 @@
package utils
import (
"strconv"
"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
devfileParser "github.com/devfile/library/pkg/devfile/parser"
@@ -16,9 +14,6 @@ import (
const (
// _envProjectsRoot is the env defined for project mount in a component container when component's mountSources=true
_envProjectsRoot = "PROJECTS_ROOT"
// _envDebugPort is the env defined in the runtime component container which holds the debug port for remote debugging
_envDebugPort = "DEBUG_PORT"
)
// GetOdoContainerVolumes returns the mandatory Kube volumes for an Odo component
@@ -51,19 +46,6 @@ func GetOdoContainerVolumes(sourcePVCName string) []corev1.Volume {
}
}
// isEnvPresent checks if the env variable is present in an array of env variables
func isEnvPresent(EnvVars []corev1.EnvVar, envVarName string) bool {
isPresent := false
for _, envVar := range EnvVars {
if envVar.Name == envVarName {
isPresent = true
}
}
return isPresent
}
// AddOdoProjectVolume adds the odo project volume to the containers
func AddOdoProjectVolume(containers *[]corev1.Container) {
if containers == nil {
@@ -153,47 +135,6 @@ func UpdateContainersEntrypointsIfNeeded(
}
// UpdateContainerEnvVars updates the container environment variables
func UpdateContainerEnvVars(
devfileObj devfileParser.DevfileObj,
containers []corev1.Container,
devfileDebugCmd string,
devfileDebugPort int,
) ([]corev1.Container, error) {
debugCommand, hasDebugCmd, err := libdevfile.GetCommand(devfileObj, devfileDebugCmd, v1alpha2.DebugCommandGroupKind)
if err != nil {
return nil, err
}
if !hasDebugCmd {
return containers, nil
}
debugContainers, err := libdevfile.GetContainerComponentsForCommand(devfileObj, debugCommand)
if err != nil {
return nil, err
}
for i := range containers {
container := &containers[i]
// Check if the container belongs to a debug command component
for _, c := range debugContainers {
if container.Name == c && !isEnvPresent(container.Env, _envDebugPort) {
klog.V(2).Infof("Updating container %v env with debug command's debugPort", container.Name)
container.Env = append(container.Env,
corev1.EnvVar{
Name: _envDebugPort,
Value: strconv.Itoa(devfileDebugPort),
})
break
}
}
}
return containers, nil
}
// overrideContainerCommandAndArgsIfNeeded overrides the container's entrypoint
// if the corresponding component does not have any command and/or args in the Devfile.
// This is a workaround until the default Devfile registry exposes stacks with non-terminating containers.

View File

@@ -4,7 +4,6 @@ import (
"reflect"
"testing"
devfilepkg "github.com/devfile/api/v2/pkg/devfile"
"github.com/devfile/library/pkg/devfile/parser/data"
"github.com/redhat-developer/odo/pkg/storage"
@@ -203,599 +202,6 @@ func TestAddOdoMandatoryVolume(t *testing.T) {
}
}
func TestUpdateContainerEnvVars(t *testing.T) {
cmd := "ls -la"
cmp := "alias1"
debugCommand := "nodemon --inspect={DEBUG_PORT}"
debugComponent := "alias2"
image := "image1"
workDir := "/root"
defaultCommand := []string{"tail"}
execRunGroup := devfilev1.CommandGroup{
IsDefault: util.GetBoolPtr(true),
Kind: devfilev1.RunCommandGroupKind,
}
execDebugGroup := devfilev1.CommandGroup{
IsDefault: util.GetBoolPtr(true),
Kind: devfilev1.DebugCommandGroupKind,
}
defaultArgs := []string{"-f", "/dev/null"}
devfileData, _ := data.NewDevfileData(string(data.APISchemaVersion220))
devfileData.SetMetadata(devfilepkg.DevfileMetadata{Name: "my-app"})
_ = devfileData.AddCommands([]devfilev1.Command{
{
Id: "debug-cmd",
CommandUnion: devfilev1.CommandUnion{
Exec: &devfilev1.ExecCommand{
Component: cmp,
LabeledCommand: devfilev1.LabeledCommand{
BaseCommand: devfilev1.BaseCommand{Group: &execDebugGroup},
},
},
},
},
})
_ = devfileData.AddComponents([]devfilev1.Component{
{
Name: cmp,
ComponentUnion: devfilev1.ComponentUnion{
Container: &devfilev1.ContainerComponent{
Container: devfilev1.Container{
Image: "my-image",
},
},
},
},
})
devfileObj := devfileParser.DevfileObj{
Data: devfileData,
}
tests := []struct {
name string
debugCommand string
debugPort int
containers []corev1.Container
execCommands []devfilev1.Command
wantErr bool
}{
{
name: "Case: Container With Command and Args",
containers: []corev1.Container{
{
Name: cmp,
Image: image,
ImagePullPolicy: corev1.PullAlways,
Command: defaultCommand,
Args: defaultArgs,
Env: []corev1.EnvVar{},
},
},
execCommands: []devfilev1.Command{
{
CommandUnion: devfilev1.CommandUnion{
Exec: &devfilev1.ExecCommand{
LabeledCommand: devfilev1.LabeledCommand{
BaseCommand: devfilev1.BaseCommand{
Group: &execRunGroup,
},
},
CommandLine: cmd,
Component: cmp,
WorkingDir: workDir,
},
},
},
},
wantErr: false,
},
{
name: "Case: Container With Command and Args but Missing Work Dir",
containers: []corev1.Container{
{
Name: cmp,
Image: image,
ImagePullPolicy: corev1.PullAlways,
Command: defaultCommand,
Args: defaultArgs,
Env: []corev1.EnvVar{},
},
},
execCommands: []devfilev1.Command{
{
CommandUnion: devfilev1.CommandUnion{
Exec: &devfilev1.ExecCommand{
LabeledCommand: devfilev1.LabeledCommand{
BaseCommand: devfilev1.BaseCommand{
Group: &execRunGroup,
},
},
CommandLine: cmd,
Component: cmp,
},
},
},
},
wantErr: false,
},
{
name: "Case: Container With No Command and Args ",
containers: []corev1.Container{
{
Name: cmp,
Image: image,
ImagePullPolicy: corev1.PullAlways,
Env: []corev1.EnvVar{},
},
},
execCommands: []devfilev1.Command{
{
CommandUnion: devfilev1.CommandUnion{
Exec: &devfilev1.ExecCommand{
LabeledCommand: devfilev1.LabeledCommand{
BaseCommand: devfilev1.BaseCommand{
Group: &execRunGroup,
},
},
CommandLine: cmd,
Component: cmp,
WorkingDir: workDir,
},
},
},
},
wantErr: false,
},
{
name: "Case: Custom Command Container With No Command and Args ",
containers: []corev1.Container{
{
Name: cmp,
Image: image,
ImagePullPolicy: corev1.PullAlways,
Env: []corev1.EnvVar{},
},
},
execCommands: []devfilev1.Command{
{
Id: "customcommand",
CommandUnion: devfilev1.CommandUnion{
Exec: &devfilev1.ExecCommand{
LabeledCommand: devfilev1.LabeledCommand{
BaseCommand: devfilev1.BaseCommand{
Group: &execRunGroup,
},
},
CommandLine: cmd,
Component: cmp,
WorkingDir: workDir,
},
},
},
},
wantErr: false,
},
{
name: "Case: empty debug command",
debugPort: 5858,
containers: []corev1.Container{
{
Name: cmp,
Image: image,
ImagePullPolicy: corev1.PullAlways,
Env: []corev1.EnvVar{},
},
{
Name: debugComponent,
Image: image,
ImagePullPolicy: corev1.PullAlways,
Env: []corev1.EnvVar{},
},
},
execCommands: []devfilev1.Command{
{
Id: "customruncommand",
CommandUnion: devfilev1.CommandUnion{
Exec: &devfilev1.ExecCommand{
LabeledCommand: devfilev1.LabeledCommand{
BaseCommand: devfilev1.BaseCommand{
Group: &execRunGroup,
},
},
CommandLine: cmd,
Component: cmp,
WorkingDir: workDir,
},
},
},
{
CommandUnion: devfilev1.CommandUnion{
Exec: &devfilev1.ExecCommand{
LabeledCommand: devfilev1.LabeledCommand{
BaseCommand: devfilev1.BaseCommand{
Group: &execDebugGroup,
},
},
CommandLine: debugCommand,
Component: debugComponent,
WorkingDir: workDir,
},
},
},
},
wantErr: false,
},
{
name: "Case: custom debug command",
debugCommand: "customdebugcommand",
debugPort: 3000,
containers: []corev1.Container{
{
Name: cmp,
Image: image,
ImagePullPolicy: corev1.PullAlways,
Env: []corev1.EnvVar{},
},
},
execCommands: []devfilev1.Command{
{
CommandUnion: devfilev1.CommandUnion{
Exec: &devfilev1.ExecCommand{
LabeledCommand: devfilev1.LabeledCommand{
BaseCommand: devfilev1.BaseCommand{
Group: &execRunGroup,
},
},
CommandLine: cmd,
Component: cmp,
WorkingDir: workDir,
},
},
},
{
Id: "customdebugcommand",
CommandUnion: devfilev1.CommandUnion{
Exec: &devfilev1.ExecCommand{
LabeledCommand: devfilev1.LabeledCommand{
BaseCommand: devfilev1.BaseCommand{
Group: &execDebugGroup,
},
},
CommandLine: debugCommand,
Component: cmp,
WorkingDir: workDir,
},
},
},
},
wantErr: false,
},
{
name: "Case: custom debug command with DEBUG_PORT env already set",
debugCommand: "customdebugcommand",
debugPort: 3000,
containers: []corev1.Container{
{
Name: cmp,
Image: image,
ImagePullPolicy: corev1.PullAlways,
Env: []corev1.EnvVar{
{
Name: "DEBUG_PORT",
Value: "5858",
},
},
},
},
execCommands: []devfilev1.Command{
{
CommandUnion: devfilev1.CommandUnion{
Exec: &devfilev1.ExecCommand{
LabeledCommand: devfilev1.LabeledCommand{
BaseCommand: devfilev1.BaseCommand{
Group: &execRunGroup,
},
},
CommandLine: cmd,
Component: cmp,
WorkingDir: workDir,
},
},
},
{
Id: "customdebugcommand",
CommandUnion: devfilev1.CommandUnion{
Exec: &devfilev1.ExecCommand{
LabeledCommand: devfilev1.LabeledCommand{
BaseCommand: devfilev1.BaseCommand{
Group: &execDebugGroup,
},
},
CommandLine: debugCommand,
Component: cmp,
WorkingDir: workDir,
Env: []devfilev1.EnvVar{},
},
},
},
},
wantErr: false,
},
{
name: "Case: wrong custom debug command",
debugCommand: "customdebugcommand123",
debugPort: 9090,
containers: []corev1.Container{
{
Name: cmp,
Image: image,
ImagePullPolicy: corev1.PullAlways,
Env: []corev1.EnvVar{},
},
{
Name: debugComponent,
Image: image,
ImagePullPolicy: corev1.PullAlways,
Env: []corev1.EnvVar{},
},
},
execCommands: []devfilev1.Command{
{
Id: "run",
CommandUnion: devfilev1.CommandUnion{
Exec: &devfilev1.ExecCommand{
LabeledCommand: devfilev1.LabeledCommand{
BaseCommand: devfilev1.BaseCommand{
Group: &execRunGroup,
},
},
CommandLine: cmd,
Component: cmp,
WorkingDir: workDir,
},
},
},
{
Id: "debug",
CommandUnion: devfilev1.CommandUnion{
Exec: &devfilev1.ExecCommand{
LabeledCommand: devfilev1.LabeledCommand{
BaseCommand: devfilev1.BaseCommand{
Group: &devfilev1.CommandGroup{
IsDefault: util.GetBoolPtr(true),
Kind: devfilev1.BuildCommandGroupKind,
},
},
},
CommandLine: debugCommand,
Component: debugComponent,
WorkingDir: workDir,
},
},
},
},
wantErr: false,
},
{
name: "Case: custom run command with single environment variable",
containers: []corev1.Container{
{
Name: cmp,
Image: image,
ImagePullPolicy: corev1.PullAlways,
Env: []corev1.EnvVar{},
},
},
execCommands: []devfilev1.Command{
{
Id: "customruncommand",
CommandUnion: devfilev1.CommandUnion{
Exec: &devfilev1.ExecCommand{
LabeledCommand: devfilev1.LabeledCommand{
BaseCommand: devfilev1.BaseCommand{
Group: &execRunGroup,
},
},
CommandLine: cmd,
Component: cmp,
WorkingDir: workDir,
Env: []devfilev1.EnvVar{
{
Name: "env1",
Value: "value1",
},
},
},
},
},
},
wantErr: false,
},
{
name: "Case: custom run command with multiple environment variable",
containers: []corev1.Container{
{
Name: cmp,
Image: image,
ImagePullPolicy: corev1.PullAlways,
Env: []corev1.EnvVar{},
},
},
execCommands: []devfilev1.Command{
{
Id: "customruncommand",
CommandUnion: devfilev1.CommandUnion{
Exec: &devfilev1.ExecCommand{
LabeledCommand: devfilev1.LabeledCommand{
BaseCommand: devfilev1.BaseCommand{
Group: &execRunGroup,
},
},
CommandLine: cmd,
Component: cmp,
WorkingDir: workDir,
Env: []devfilev1.EnvVar{
{
Name: "env1",
Value: "value1",
},
{
Name: "env2",
Value: "value2 with space",
},
},
},
},
},
},
wantErr: false,
},
{
name: "Case: custom debug command with single environment variable",
debugCommand: "customdebugcommand",
debugPort: 3000,
containers: []corev1.Container{
{
Name: cmp,
Image: image,
ImagePullPolicy: corev1.PullAlways,
Env: []corev1.EnvVar{},
},
},
execCommands: []devfilev1.Command{
{
CommandUnion: devfilev1.CommandUnion{
Exec: &devfilev1.ExecCommand{
LabeledCommand: devfilev1.LabeledCommand{
BaseCommand: devfilev1.BaseCommand{
Group: &execRunGroup,
},
},
CommandLine: cmd,
Component: cmp,
WorkingDir: workDir,
},
},
},
{
Id: "customdebugcommand",
CommandUnion: devfilev1.CommandUnion{
Exec: &devfilev1.ExecCommand{
LabeledCommand: devfilev1.LabeledCommand{
BaseCommand: devfilev1.BaseCommand{
Group: &execDebugGroup,
},
},
CommandLine: debugCommand,
Component: cmp,
WorkingDir: workDir,
Env: []devfilev1.EnvVar{
{
Name: "env1",
Value: "value1",
},
},
},
},
},
},
wantErr: false,
},
{
name: "Case: custom debug command with multiple environment variables",
debugCommand: "customdebugcommand",
debugPort: 3000,
containers: []corev1.Container{
{
Name: cmp,
Image: image,
ImagePullPolicy: corev1.PullAlways,
Env: []corev1.EnvVar{},
},
},
execCommands: []devfilev1.Command{
{
CommandUnion: devfilev1.CommandUnion{
Exec: &devfilev1.ExecCommand{
LabeledCommand: devfilev1.LabeledCommand{
BaseCommand: devfilev1.BaseCommand{
Group: &execRunGroup,
},
},
CommandLine: cmd,
Component: cmp,
WorkingDir: workDir,
},
},
},
{
Id: "customdebugcommand",
CommandUnion: devfilev1.CommandUnion{
Exec: &devfilev1.ExecCommand{
LabeledCommand: devfilev1.LabeledCommand{
BaseCommand: devfilev1.BaseCommand{
Group: &execDebugGroup,
},
},
CommandLine: debugCommand,
Component: cmp,
WorkingDir: workDir,
Env: []devfilev1.EnvVar{
{
Name: "env1",
Value: "value1",
},
{
Name: "env2",
Value: "value2 with space",
},
},
},
},
},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
containers, err := UpdateContainerEnvVars(devfileObj, tt.containers, "debug-cmd", tt.debugPort)
envDebugPortMatched := false
for _, container := range containers {
for _, testContainer := range tt.containers {
if container.Name == testContainer.Name {
for _, envVar := range container.Env {
// if the debug command is also present
if len(tt.execCommands) >= 2 {
if envVar.Name == _envDebugPort {
// check if the debug command's debugPort env was set properly
envDebugPortMatched = true
}
}
}
}
}
}
if tt.wantErr != (err != nil) {
t.Errorf("unexpected error, wantErr: %v, err: %v", tt.wantErr, err)
}
if len(tt.execCommands) >= 2 && !envDebugPortMatched {
t.Errorf("TestUpdateContainerEnvVars error: missing env var %s in container %q",
_envDebugPort, cmp)
}
})
}
}
func TestUpdateContainersEntrypointsIfNeeded(t *testing.T) {
const (
buildCommand = "my-build"

View File

@@ -18,9 +18,8 @@ type PushParameters struct {
DevfileRunCmd string // DevfileRunCmd takes the run command through the command line and overwrites devfile run command
DevfileDebugCmd string // DevfileDebugCmd takes the debug command through the command line and overwrites the devfile debug command
DevfileScanIndexForWatch bool // DevfileScanIndexForWatch is true if watch's push should regenerate the index file during SyncFiles, false otherwise. See 'pkg/sync/adapter.go' for details
EnvSpecificInfo envinfo.EnvSpecificInfo // EnvSpecificInfo contains information of env.yaml file
EnvSpecificInfo envinfo.EnvSpecificInfo // EnvSpecificInfo contains information of devfile
Debug bool // Runs the component in debug mode
DebugPort int // Port used for remote debugging
RandomPorts bool // True to forward containers ports on local random ports
ErrOut io.Writer // Writer to output forwarded port information
}

View File

@@ -2,63 +2,22 @@
package envinfo
import (
"fmt"
"io"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/devfile/library/pkg/devfile/parser"
"github.com/devfile/library/pkg/devfile/parser/data/v2/common"
dfutil "github.com/devfile/library/pkg/util"
"github.com/redhat-developer/odo/pkg/devfile/location"
"github.com/redhat-developer/odo/pkg/localConfigProvider"
"github.com/redhat-developer/odo/pkg/testingutil/filesystem"
"github.com/redhat-developer/odo/pkg/util"
"k8s.io/klog"
)
type RUNMode string
const (
Run RUNMode = "run"
Debug RUNMode = "debug"
)
const (
envInfoEnvName = "ENVINFO"
envInfoFileName = "env.yaml"
// DefaultDebugPort is the default port used for debugging on remote pod
DefaultDebugPort = 5858
// DefaultRunMode is the default run mode of the component
DefaultRunMode = Run
)
// EnvInfo holds all the env specific information relevant to a specific Component.
type EnvInfo struct {
devfileObj parser.DevfileObj
componentSettings ComponentSettings `yaml:"ComponentSettings,omitempty"`
}
// proxyEnvInfo holds all the parameter that envinfo does but exposes all
// of it, used for serialization.
type proxyEnvInfo struct {
ComponentSettings ComponentSettings `yaml:"ComponentSettings,omitempty"`
devfileObj parser.DevfileObj
}
// EnvSpecificInfo wraps the envinfo and provides helpers to
// serialize it.
type EnvSpecificInfo struct {
devfilePath string
Filename string `yaml:"FileName,omitempty"`
fs filesystem.Filesystem
EnvInfo `yaml:",omitempty"`
envinfoFileExists bool
devfilePath string
EnvInfo `yaml:",omitempty"`
}
var _ localConfigProvider.LocalConfigProvider = (*EnvSpecificInfo)(nil)
@@ -67,251 +26,20 @@ func (esi EnvSpecificInfo) GetDevfilePath() string {
return esi.devfilePath
}
// getEnvInfoFile first checks for the ENVINFO variable
// then we check for directory and eventually the file (which we return as a string)
func getEnvInfoFile(envDir string) (string, string, error) {
if env, ok := os.LookupEnv(envInfoEnvName); ok {
return env, filepath.Join(env, "..", "..", "..", "devfile.yaml"), nil
}
if envDir == "" {
var err error
envDir, err = os.Getwd()
if err != nil {
return "", "", err
}
}
return filepath.Join(envDir, ".odo", "env", envInfoFileName), location.DevfileLocation(envDir), nil
}
// NewEnvSpecificInfo retrieves the environment file. If it does not exist, it returns *blank*
// NewEnvSpecificInfo retrieves the information about devfile path
func NewEnvSpecificInfo(envDir string) (*EnvSpecificInfo, error) {
return newEnvSpecificInfo(envDir, filesystem.Get())
}
// newEnvSpecificInfo retrieves the env.yaml file, if it does not exist, we return a *BLANK* environment file.
func newEnvSpecificInfo(envDir string, fs filesystem.Filesystem) (*EnvSpecificInfo, error) {
// Get the path of the environment file
envInfoFile, devfilePath, err := getEnvInfoFile(envDir)
if err != nil {
return nil, fmt.Errorf("failed to get the path of the environment file: %w", err)
}
devfilePath := location.DevfileLocation(envDir)
// Organize that information into a struct
e := EnvSpecificInfo{
EnvInfo: NewEnvInfo(),
devfilePath: devfilePath,
Filename: envInfoFile,
envinfoFileExists: true,
fs: fs,
}
// If the env.yaml file does not exist then we simply return and set e.envinfoFileExists as false
if _, err = e.fs.Stat(envInfoFile); os.IsNotExist(err) {
e.envinfoFileExists = false
return &e, nil
}
// Retrieve the environment file
err = getFromFile(&e.EnvInfo, e.Filename)
if err != nil {
return nil, err
EnvInfo: EnvInfo{},
devfilePath: devfilePath,
}
return &e, nil
}
func getFromFile(envinfo *EnvInfo, filename string) error {
proxyei := newProxyEnvInfo()
err := util.GetFromFile(&proxyei, filename)
if err != nil {
return err
}
envinfo.componentSettings = proxyei.ComponentSettings
return nil
}
// NewEnvInfo creates an empty EnvSpecificInfo struct with typeMeta populated
func NewEnvInfo() EnvInfo {
return EnvInfo{}
}
// newProxyEnvInfo creates an empty ProxyEnvInfo struct with typeMeta populated
func newProxyEnvInfo() proxyEnvInfo {
return proxyEnvInfo{}
}
// SetConfiguration sets the environment specific info such as the Cluster Host, Name, etc.
// we then **write** this data to the environment yaml file (see envInfoFileName const)
func (esi *EnvSpecificInfo) SetConfiguration(parameter string, value interface{}) (err error) {
if p, ok := asLocallySupportedParameter(parameter); ok {
switch p {
case "name":
val := value.(string)
esi.componentSettings.Name = val
case "project":
val := value.(string)
esi.componentSettings.Project = val
case "debugport":
val, err := strconv.Atoi(value.(string))
if err != nil {
return fmt.Errorf("failed to set debug port: %w", err)
}
esi.componentSettings.DebugPort = &val
}
return esi.writeToFile()
}
return fmt.Errorf("unknown parameter: %q is not a parameter in the odo environment file, please refer `odo env set --help` to see valid parameters", parameter)
}
// DeleteEnvDirIfEmpty Deletes the env directory if its empty
func (esi *EnvSpecificInfo) DeleteEnvDirIfEmpty() error {
envDir := filepath.Dir(esi.Filename)
_, err := esi.fs.Stat(envDir)
if os.IsNotExist(err) {
// If the Env dir doesn't exist then we dont mind
return nil
} else if err != nil {
// Possible to not have permission to the dir
return err
}
f, err := esi.fs.Open(envDir)
if err != nil {
return err
}
defer f.Close()
_, err = f.Readdir(1)
// If directory is empty we can remove it
if err == io.EOF {
klog.V(4).Info("Deleting the env directory as well because its empty")
return esi.fs.Remove(envDir)
}
return err
}
// DeleteEnvInfoFile deletes the envinfo.yaml file if it exists
func (esi *EnvSpecificInfo) DeleteEnvInfoFile() error {
return dfutil.DeletePath(esi.Filename)
}
// IsSet uses reflection to get the parameter from the envinfo struct, currently
// it only searches the componentSettings
func (esi *EnvSpecificInfo) IsSet(parameter string) bool {
return util.IsSet(esi.componentSettings, parameter)
}
// Exists returns whether the envinfo file exists or not
func (esi *EnvSpecificInfo) Exists() bool {
return esi.envinfoFileExists
}
var (
// Mandatory parameters in the environment file (env.yaml)
manParams = []string{
"name",
"project",
}
)
// DeleteConfiguration is used to delete environment specific info from local odo envinfo
func (esi *EnvSpecificInfo) DeleteConfiguration(parameter string) error {
for _, manParam := range manParams {
if parameter == manParam {
return fmt.Errorf("failed to unset %q: %q is mandatory parameter", parameter, parameter)
}
}
if p, ok := asLocallySupportedParameter(parameter); ok {
if err := util.DeleteConfiguration(&esi.componentSettings, p); err != nil {
return err
}
return esi.writeToFile()
}
return fmt.Errorf("unknown parameter: %q is not a parameter in the odo environment file, please refer `odo env unset --help` to unset a valid parameter", parameter)
}
// GetComponentSettings returns the componentSettings from envinfo
func (esi *EnvSpecificInfo) GetComponentSettings() ComponentSettings {
return esi.componentSettings
}
// SetComponentSettings sets the componentSettings from to the envinfo and writes to the file
func (esi *EnvSpecificInfo) SetComponentSettings(cs ComponentSettings) error {
esi.componentSettings = cs
return esi.writeToFile()
}
func (esi *EnvSpecificInfo) writeToFile() error {
proxyei := newProxyEnvInfo()
proxyei.ComponentSettings = esi.componentSettings
return util.WriteToYAMLFile(&proxyei, esi.Filename)
}
// GetName returns the component name
func (ei *EnvInfo) GetName() string {
return ei.componentSettings.Name
}
// GetDebugPort returns the DebugPort, returns default if nil
func (ei *EnvInfo) GetDebugPort() int {
if ei.componentSettings.DebugPort == nil {
return DefaultDebugPort
}
return *ei.componentSettings.DebugPort
}
// GetContainers returns the Container components from the devfile
// returns empty list if nil
func (ei *EnvInfo) GetContainers() ([]localConfigProvider.LocalContainer, error) {
var localContainers []localConfigProvider.LocalContainer
devfileComponents, err := ei.devfileObj.Data.GetComponents(common.DevfileOptions{})
if err != nil {
return localContainers, err
}
for _, component := range devfileComponents {
if component.Container == nil {
continue
}
localContainers = append(localContainers, localConfigProvider.LocalContainer{
Name: component.Name,
})
}
return localContainers, nil
}
// IsUserCreatedDevfile returns the UserCreatedDevfile
func (ei *EnvInfo) IsUserCreatedDevfile() bool {
return ei.componentSettings.UserCreatedDevfile
}
// GetRunMode returns the RunMode, returns default if nil
func (ei *EnvInfo) GetRunMode() RUNMode {
if ei.componentSettings.RunMode == nil {
return DefaultRunMode
}
return *ei.componentSettings.RunMode
}
// SetRunMode sets the RunMode in the env file
func (esi *EnvSpecificInfo) SetRunMode(runMode RUNMode) error {
esi.componentSettings.RunMode = &runMode
return esi.writeToFile()
}
// GetApplication returns the application name
func (ei *EnvInfo) GetApplication() string {
return ei.componentSettings.AppName
}
// SetDevfileObj sets the devfileObj for the envinfo
func (ei *EnvInfo) SetDevfileObj(devfileObj parser.DevfileObj) {
ei.devfileObj = devfileObj
@@ -321,43 +49,3 @@ func (ei *EnvInfo) SetDevfileObj(devfileObj parser.DevfileObj) {
func (ei *EnvInfo) GetDevfileObj() parser.DevfileObj {
return ei.devfileObj
}
const (
// Name is the name of the setting controlling the component name
Name = "Name"
// NameDescription is the human-readable description for name setting
NameDescription = "Set this value to user-defined component name to specify the component name"
// Project is the name of the setting controlling the component project
Project = "Project"
// ProjectDescription is the human-readable description for project setting
ProjectDescription = "Set this value to user-defined project to let the component create under the project"
// DebugPort is the name of the setting controlling the component debug port
DebugPort = "DebugPort"
// DebugPortDescription s the human-readable description for debug port setting
DebugPortDescription = "Set this value to user-defined debug port to assign the debug port to the component"
// Push parameter
Push = "PUSH"
// PushDescription is the description of push parameter
PushDescription = "Push parameter is the action to write devfile commands to env.yaml"
)
var (
supportedLocalParameterDescriptions = map[string]string{
Name: NameDescription,
Project: ProjectDescription,
DebugPort: DebugPortDescription,
Push: PushDescription,
}
lowerCaseLocalParameters = util.GetLowerCaseParameters(GetLocallySupportedParameters())
)
func asLocallySupportedParameter(param string) (string, bool) {
lower := strings.ToLower(param)
return lower, lowerCaseLocalParameters[lower]
}
// GetLocallySupportedParameters returns the name of the supported global parameters
func GetLocallySupportedParameters() []string {
return dfutil.GetSortedKeys(supportedLocalParameterDescriptions)
}

View File

@@ -1,262 +0,0 @@
package envinfo
import (
"fmt"
"os"
"path/filepath"
"strconv"
"testing"
"github.com/redhat-developer/odo/pkg/testingutil/filesystem"
)
func TestSetEnvInfo(t *testing.T) {
fs := filesystem.NewFakeFs()
tempEnvFile, err := fs.TempFile("", "odoenvinfo")
if err != nil {
t.Fatal(err)
}
defer tempEnvFile.Close()
t.Setenv(envInfoEnvName, tempEnvFile.Name())
testDebugPort := 5005
invalidParam := "invalidParameter"
tests := []struct {
name string
parameter string
value interface{}
existingEnvInfo EnvInfo
checkConfigSetting []string
expectError bool
}{
{
name: fmt.Sprintf("Case 1: %s to test", DebugPort),
parameter: DebugPort,
value: strconv.Itoa(testDebugPort),
existingEnvInfo: EnvInfo{
componentSettings: ComponentSettings{},
},
checkConfigSetting: []string{"debugport"},
expectError: false,
},
{
name: fmt.Sprintf("Case 2: %s to test", invalidParam),
parameter: invalidParam,
value: strconv.Itoa(testDebugPort),
existingEnvInfo: EnvInfo{
componentSettings: ComponentSettings{},
},
checkConfigSetting: []string{"debugport"},
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
esi, err := NewEnvSpecificInfo("")
if err != nil {
t.Error(err)
}
esi.EnvInfo = tt.existingEnvInfo
err = esi.SetConfiguration(tt.parameter, tt.value)
if !tt.expectError && err != nil {
t.Errorf("unexpected error for SetConfiguration with %s: %v", tt.parameter, err)
} else if !tt.expectError && err == nil {
isSet := false
for _, configSetting := range tt.checkConfigSetting {
isSet = esi.IsSet(configSetting)
if !isSet {
t.Errorf("the setting '%s' is not set", configSetting)
}
}
}
})
}
}
func TestUnsetEnvInfo(t *testing.T) {
fs := filesystem.NewFakeFs()
tempEnvFile, err := fs.TempFile("", "odoenvinfo")
if err != nil {
t.Fatal(err)
}
if err != nil {
t.Fatal(err)
}
defer tempEnvFile.Close()
t.Setenv(envInfoEnvName, tempEnvFile.Name())
testDebugPort := 15005
invalidParam := "invalidParameter"
tests := []struct {
name string
parameter string
existingEnvInfo EnvInfo
expectError bool
}{
{
name: fmt.Sprintf("Case 1: unset %s", DebugPort),
parameter: DebugPort,
existingEnvInfo: EnvInfo{
componentSettings: ComponentSettings{
DebugPort: &testDebugPort,
},
},
expectError: false,
},
{
name: fmt.Sprintf("Case 2: unset %s", invalidParam),
parameter: invalidParam,
existingEnvInfo: EnvInfo{
componentSettings: ComponentSettings{
DebugPort: &testDebugPort,
},
},
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
esi, err := NewEnvSpecificInfo("")
if err != nil {
t.Error(err)
}
esi.EnvInfo = tt.existingEnvInfo
err = esi.DeleteConfiguration(tt.parameter)
if err == nil && tt.expectError {
t.Errorf("expected error for DeleteConfiguration with %s", tt.parameter)
} else if !tt.expectError {
if err != nil {
t.Error(err)
}
isSet := esi.IsSet(tt.parameter)
if isSet {
t.Errorf("the '%v' is not set to nil", tt.parameter)
}
}
})
}
}
func TestEnvSpecificInfonitDoesntCreateLocalOdoFolder(t *testing.T) {
// cleaning up old odo files if any
filename, _, err := getEnvInfoFile("")
if err != nil {
t.Error(err)
}
os.RemoveAll(filename)
conf, err := NewEnvSpecificInfo("")
if err != nil {
t.Errorf("error while creating envinfo %v", err)
}
if _, err = os.Stat(conf.Filename); !os.IsNotExist(err) {
t.Errorf("local env.yaml shouldn't exist yet")
}
}
func TestDeleteEnvDirIfEmpty(t *testing.T) {
// create a fake fs in memory
fs := filesystem.NewFakeFs()
// create a odo config directory on fake fs
configDir, err := fs.TempDir(os.TempDir(), "odo")
if err != nil {
t.Error(err)
}
// create a mock env info from above fake fs & dir
esi, err := mockEnvSpecificInfo(configDir, fs)
if err != nil {
t.Error(err)
}
envDir := filepath.Join(configDir, ".odo", "env")
if _, err = fs.Stat(envDir); os.IsNotExist(err) {
t.Error("config directory doesn't exist")
}
tests := []struct {
name string
// create indicates if a file is supposed to be created in the odo config dir
create bool
setupEnv func(create bool, fs filesystem.Filesystem, envDir string) error
wantOdoDir bool
wantErr bool
}{
{
name: "Case 1: Empty config dir",
create: false,
setupEnv: createDirectoryAndFile,
wantOdoDir: false,
},
{
name: "Case 2: Config dir with test file",
create: true,
setupEnv: createDirectoryAndFile,
wantOdoDir: true,
},
}
for _, tt := range tests {
err := tt.setupEnv(tt.create, fs, envDir)
if err != nil {
t.Error(err)
}
err = esi.DeleteEnvDirIfEmpty()
if err != nil {
t.Error(err)
}
file, err := fs.Stat(envDir)
if !tt.wantOdoDir && !os.IsNotExist(err) {
// we don't want odo dir but odo dir exists
fmt.Println(file.Size())
t.Error("odo env directory exists even after deleting it")
t.Errorf("Error in test %q", tt.name)
} else if tt.wantOdoDir && os.IsNotExist(err) {
// we want odo dir to exist after odo delete --all but it does not exist
t.Error("wanted odo directory to exist after odo delete --all")
t.Errorf("Error in test %q", tt.name)
}
}
}
func createDirectoryAndFile(create bool, fs filesystem.Filesystem, odoDir string) error {
if !create {
return nil
}
file, err := fs.Create(filepath.Join(odoDir, "testfile"))
if err != nil {
return err
}
_, err = file.Write([]byte("hello world"))
if err != nil {
return err
}
file.Close()
if err != nil {
return err
}
return nil
}
func mockEnvSpecificInfo(configDir string, fs filesystem.Filesystem) (*EnvSpecificInfo, error) {
esi := &EnvSpecificInfo{
Filename: filepath.Join(configDir, ".odo", "env", "env.yaml"),
fs: fs,
}
err := fs.MkdirAll(filepath.Join(configDir, ".odo", "env"), os.ModePerm)
if err != nil {
return nil, err
}
return esi, nil
}

View File

@@ -1,8 +0,0 @@
package envinfo
// GetFakeEnvInfo gets a fake envInfo using the given componentSettings
func GetFakeEnvInfo(settings ComponentSettings) *EnvInfo {
return &EnvInfo{
componentSettings: settings,
}
}

View File

@@ -1,20 +0,0 @@
package envinfo
// ComponentSettings holds all component related information
type ComponentSettings struct {
Name string `yaml:"Name,omitempty" json:"name,omitempty"`
Project string `yaml:"Project,omitempty" json:"project,omitempty"`
UserCreatedDevfile bool `yaml:"UserCreatedDevfile,omitempty" json:"UserCreatedDevfile,omitempty"`
// AppName is the application name. Application is a virtual concept present in odo used
// for grouping of components. A namespace can contain multiple applications
AppName string `yaml:"AppName,omitempty" json:"appName,omitempty"`
// DebugPort controls the port used by the pod to run the debugging agent on
DebugPort *int `yaml:"DebugPort,omitempty" json:"debugPort,omitempty"`
// RunMode indicates the mode of run used for a successful push
RunMode *RUNMode `yaml:"RunMode,omitempty" json:"runMode,omitempty"`
}

File diff suppressed because it is too large Load Diff

View File

@@ -14,20 +14,8 @@ type LocalStorage struct {
Container string `yaml:"-" json:"-"`
}
// LocalContainer holds the container related information
type LocalContainer struct {
Name string `yaml:"Name" json:"Name"`
}
// LocalConfigProvider is an interface which all local config providers need to implement
// currently implemented by EnvInfo
type LocalConfigProvider interface {
GetApplication() string
GetName() string
GetDebugPort() int
GetContainers() ([]LocalContainer, error)
ListStorage() ([]LocalStorage, error)
Exists() bool
}

View File

@@ -33,91 +33,6 @@ func (m *MockLocalConfigProvider) EXPECT() *MockLocalConfigProviderMockRecorder
return m.recorder
}
// Exists mocks base method.
func (m *MockLocalConfigProvider) Exists() bool {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Exists")
ret0, _ := ret[0].(bool)
return ret0
}
// Exists indicates an expected call of Exists.
func (mr *MockLocalConfigProviderMockRecorder) Exists() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Exists", reflect.TypeOf((*MockLocalConfigProvider)(nil).Exists))
}
// GetApplication mocks base method.
func (m *MockLocalConfigProvider) GetApplication() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetApplication")
ret0, _ := ret[0].(string)
return ret0
}
// GetApplication indicates an expected call of GetApplication.
func (mr *MockLocalConfigProviderMockRecorder) GetApplication() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetApplication", reflect.TypeOf((*MockLocalConfigProvider)(nil).GetApplication))
}
// GetContainers mocks base method.
func (m *MockLocalConfigProvider) GetContainers() ([]LocalContainer, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetContainers")
ret0, _ := ret[0].([]LocalContainer)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetContainers indicates an expected call of GetContainers.
func (mr *MockLocalConfigProviderMockRecorder) GetContainers() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetContainers", reflect.TypeOf((*MockLocalConfigProvider)(nil).GetContainers))
}
// GetDebugPort mocks base method.
func (m *MockLocalConfigProvider) GetDebugPort() int {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetDebugPort")
ret0, _ := ret[0].(int)
return ret0
}
// GetDebugPort indicates an expected call of GetDebugPort.
func (mr *MockLocalConfigProviderMockRecorder) GetDebugPort() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDebugPort", reflect.TypeOf((*MockLocalConfigProvider)(nil).GetDebugPort))
}
// GetName mocks base method.
func (m *MockLocalConfigProvider) GetName() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetName")
ret0, _ := ret[0].(string)
return ret0
}
// GetName indicates an expected call of GetName.
func (mr *MockLocalConfigProviderMockRecorder) GetName() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetName", reflect.TypeOf((*MockLocalConfigProvider)(nil).GetName))
}
// GetNamespace mocks base method.
func (m *MockLocalConfigProvider) GetNamespace() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetNamespace")
ret0, _ := ret[0].(string)
return ret0
}
// GetNamespace indicates an expected call of GetNamespace.
func (mr *MockLocalConfigProviderMockRecorder) GetNamespace() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNamespace", reflect.TypeOf((*MockLocalConfigProvider)(nil).GetNamespace))
}
// ListStorage mocks base method.
func (m *MockLocalConfigProvider) ListStorage() ([]LocalStorage, error) {
m.ctrl.T.Helper()

View File

@@ -71,7 +71,7 @@ func (o *AddBindingOptions) Complete(cmdline cmdline.Cmdline, args []string) (er
return err
}
// this ensures that the namespace as set in env.yaml is used
// this ensures that the current namespace is used
o.clientset.KubernetesClient.SetNamespace(o.GetProject())
o.flags = o.clientset.BindingClient.GetFlags(cmdline.GetFlags())

View File

@@ -199,7 +199,7 @@ func TestComponentOptions_deleteDevfileComponent(t *testing.T) {
os.RemoveAll(prefixDir)
// the second one to cleanup after execution
defer os.RemoveAll(prefixDir)
info := populateWorkingDir(filesystem.DefaultFs{}, workingDir, compName, projectName, appName)
info := populateWorkingDir(filesystem.DefaultFs{}, workingDir, compName, projectName)
ctrl := gomock.NewController(t)
kubeClient := prepareKubeClient(ctrl, projectName)
deleteClient := tt.deleteClient(ctrl)
@@ -220,18 +220,12 @@ func TestComponentOptions_deleteDevfileComponent(t *testing.T) {
}
// populateWorkingDir populates the working directory with .odo and devfile.yaml, and returns envinfo
func populateWorkingDir(fs filesystem.Filesystem, workingDir, compName, projectName, appName string) *envinfo.EnvSpecificInfo {
_ = fs.MkdirAll(filepath.Join(workingDir, ".odo", "env"), 0755)
_ = fs.WriteFile(filepath.Join(workingDir, ".odo", "env", "env.yaml"), []byte{}, 0644)
func populateWorkingDir(fs filesystem.Filesystem, workingDir, compName, projectName string) *envinfo.EnvSpecificInfo {
_ = fs.MkdirAll(filepath.Join(workingDir), 0755)
env, err := envinfo.NewEnvSpecificInfo(workingDir)
if err != nil {
return env
}
_ = env.SetComponentSettings(envinfo.ComponentSettings{
Name: compName,
Project: projectName,
AppName: appName,
})
devfileObj := testingutil.GetTestDevfileObjFromFile("devfile-deploy.yaml")
devfileYAML, err := yaml.Marshal(devfileObj.Data)
if err != nil {
@@ -260,7 +254,6 @@ func prepareKubeClient(ctrl *gomock.Controller, projectName string) kclient.Clie
func prepareContext(ctrl *gomock.Controller, kubeClient kclient.ClientInterface, info *envinfo.EnvSpecificInfo, workingDir string) *genericclioptions.Context {
cmdline := cmdline.NewMockCmdline(ctrl)
cmdline.EXPECT().GetWorkingDirectory().Return(workingDir, nil).AnyTimes()
cmdline.EXPECT().CheckIfConfigurationNeeded().Return(true, nil).AnyTimes()
cmdline.EXPECT().FlagValueIfSet("project").Return("").AnyTimes()
cmdline.EXPECT().FlagValueIfSet("app").Return("").AnyTimes()
cmdline.EXPECT().FlagValueIfSet("component").Return("").AnyTimes()

View File

@@ -66,7 +66,7 @@ func (o *BindingOptions) Complete(cmdline cmdline.Cmdline, args []string) (err e
if err != nil {
return err
}
// this ensures that the namespace set in env.yaml is used
// this ensures that the current namespace is used
o.clientset.KubernetesClient.SetNamespace(o.GetProject())
return nil
}

View File

@@ -71,7 +71,7 @@ func (o *ComponentOptions) Complete(cmdline cmdline.Cmdline, args []string) (err
if err != nil {
return err
}
// this ensures that the namespace set in env.yaml is used
// this ensures that the current namespace is used
o.clientset.KubernetesClient.SetNamespace(o.GetProject())
return nil
}

View File

@@ -10,7 +10,6 @@ import (
"github.com/spf13/cobra"
"github.com/devfile/library/pkg/devfile/parser"
"k8s.io/klog"
ktemplates "k8s.io/kubectl/pkg/util/templates"
"github.com/redhat-developer/odo/pkg/component"
@@ -19,7 +18,6 @@ import (
"github.com/redhat-developer/odo/pkg/devfile/adapters"
kcomponent "github.com/redhat-developer/odo/pkg/devfile/adapters/kubernetes/component"
"github.com/redhat-developer/odo/pkg/devfile/location"
"github.com/redhat-developer/odo/pkg/envinfo"
"github.com/redhat-developer/odo/pkg/libdevfile"
"github.com/redhat-developer/odo/pkg/log"
clierrors "github.com/redhat-developer/odo/pkg/odo/cli/errors"
@@ -151,33 +149,6 @@ func (o *DevOptions) Complete(cmdline cmdline.Cmdline, args []string) error {
o.initialDevfileObj = o.Context.EnvSpecificInfo.GetDevfileObj()
// ENV.YAML
//
// Set the appropriate variables in the env.yaml file
//
// TODO: Eventually refactor with code in deploy/deploy.go
envfileinfo, err := envinfo.NewEnvSpecificInfo("")
if err != nil {
return fmt.Errorf("unable to retrieve configuration information: %v", err)
}
// If the env.yaml does not exist, we will save the project name
if !envfileinfo.Exists() {
err = envfileinfo.SetComponentSettings(envinfo.ComponentSettings{Project: o.GetProject()})
if err != nil {
return fmt.Errorf("failed to write new env.yaml file: %w", err)
}
} else if envfileinfo.Exists() && envfileinfo.GetComponentSettings().Project != o.GetProject() {
// If the env.yaml exists and the project is set incorrectly, we'll override it.
klog.V(4).Info("Overriding project name in env.yaml as it's set incorrectly, new project name: ", o.GetProject())
err = envfileinfo.SetConfiguration("project", o.GetProject())
if err != nil {
return fmt.Errorf("failed to update project in env.yaml file: %w", err)
}
}
// END ENV.YAML
o.clientset.KubernetesClient.SetNamespace(o.GetProject())
return nil
@@ -212,14 +183,8 @@ func (o *DevOptions) Run(ctx context.Context) (err error) {
return err
}
// add odo-file-index.json path to .gitignore
err = util.AddOdoFileIndex(gitIgnoreFile)
if err != nil {
return err
}
// add devstate.json path to .gitignore
err = util.AddOdoDevState(gitIgnoreFile)
// add .odo dir to .gitignore
err = util.AddOdoDirectory(gitIgnoreFile)
if err != nil {
return err
}
@@ -315,32 +280,12 @@ func (o *DevOptions) HandleSignal() error {
}
func (o *DevOptions) Cleanup(commandError error) {
err := unsetProjectInEnvfile()
if err != nil {
klog.V(4).Infof("Error unsetting project into env.yaml file")
}
if commandError != nil {
devFileObj := o.Context.EnvSpecificInfo.GetDevfileObj()
_ = o.clientset.WatchClient.CleanupDevResources(devFileObj, log.GetStdout())
}
}
func unsetProjectInEnvfile() error {
envfileinfo, err := envinfo.NewEnvSpecificInfo("")
if err != nil {
return err
}
if envfileinfo.Exists() {
err = envfileinfo.SetConfiguration("project", "")
if err != nil {
return err
}
}
return nil
}
// NewCmdDev implements the odo dev command
func NewCmdDev(name, fullName string) *cobra.Command {
o := NewDevOptions()

View File

@@ -69,7 +69,7 @@ func (o *BindingListOptions) Complete(cmdline cmdline.Cmdline, args []string) (e
return err
}
// this ensures that the namespace set in env.yaml is used
// this ensures that the current namespace is used
o.clientset.KubernetesClient.SetNamespace(o.GetProject())
return nil
}

View File

@@ -51,7 +51,7 @@ func (o *RemoveBindingOptions) Complete(cmdline cmdline.Cmdline, args []string)
return err
}
// this ensures that the namespace as set in env.yaml is used
// this ensures that the current namespace is used
o.clientset.KubernetesClient.SetNamespace(o.GetProject())
o.flags = o.clientset.BindingClient.GetFlags(cmdline.GetFlags())

View File

@@ -35,21 +35,6 @@ func (m *MockCmdline) EXPECT() *MockCmdlineMockRecorder {
return m.recorder
}
// CheckIfConfigurationNeeded mocks base method.
func (m *MockCmdline) CheckIfConfigurationNeeded() (bool, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CheckIfConfigurationNeeded")
ret0, _ := ret[0].(bool)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// CheckIfConfigurationNeeded indicates an expected call of CheckIfConfigurationNeeded.
func (mr *MockCmdlineMockRecorder) CheckIfConfigurationNeeded() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckIfConfigurationNeeded", reflect.TypeOf((*MockCmdline)(nil).CheckIfConfigurationNeeded))
}
// Context mocks base method.
func (m *MockCmdline) Context() context.Context {
m.ctrl.T.Helper()

View File

@@ -1,7 +1,6 @@
package genericclioptions
import (
"errors"
"fmt"
"github.com/redhat-developer/odo/pkg/devfile"
@@ -39,8 +38,6 @@ type internalCxt struct {
project string
// application used for the command, either passed with the `--app` flag, or the current one by default
application string
// component used for the command, either passed with the `--component` flag, or the current one by default
component string
// componentContext is the value passed with the `--context` flag
componentContext string
// outputFlag is the value passed with the `-o` flag
@@ -101,11 +98,9 @@ func New(parameters CreateParameters) (*Context, error) {
}
ctx.LocalConfigProvider = ctx.EnvSpecificInfo
ctx.project = resolveProject(parameters.cmdline)
ctx.project = parameters.cmdline.FlagValueIfSet(util.ProjectFlagName)
ctx.application = resolveApp(parameters.cmdline, ctx.EnvSpecificInfo, parameters.appIfNeeded)
ctx.component = resolveComponent(parameters.cmdline, ctx.EnvSpecificInfo)
ctx.application = defaultAppName
ctx.componentContext = parameters.componentContext
@@ -120,11 +115,6 @@ func New(parameters CreateParameters) (*Context, error) {
return nil, e
}
if parameters.cmdline.FlagValueIfSet(util.ComponentFlagName) != "" {
if err = ctx.checkComponentExistsOrFail(); err != nil {
return nil, err
}
}
}
if parameters.devfile {
@@ -165,33 +155,6 @@ func NewContextCompletion(command *cobra.Command) *Context {
return ctx
}
// Component retrieves the optionally specified component or the current one if it is set. If no component is set, returns
// an error
func (o *Context) Component(optionalComponent ...string) (string, error) {
return o.ComponentAllowingEmpty(false, optionalComponent...)
}
// ComponentAllowingEmpty retrieves the optionally specified component or the current one if it is set, allowing empty
// components (instead of exiting with an error) if so specified
func (o *Context) ComponentAllowingEmpty(allowEmpty bool, optionalComponent ...string) (string, error) {
switch len(optionalComponent) {
case 0:
// if we're not specifying a component to resolve, get the current one (resolved in NewContext as cmp)
// so nothing to do here unless the calling context doesn't allow no component to be set in which case we return an error
if !allowEmpty && len(o.component) == 0 {
return "", errors.New("no component is set")
}
case 1:
cmp := optionalComponent[0]
o.component = cmp
default:
// safeguard: fail if more than one optional string is passed because it would be a programming error
return "", fmt.Errorf("ComponentAllowingEmpty function only accepts one optional argument, was given: %v", optionalComponent)
}
return o.component, nil
}
func (o *Context) GetProject() string {
return o.project
}

View File

@@ -8,12 +8,10 @@ import (
"github.com/golang/mock/gomock"
"github.com/redhat-developer/odo/pkg/envinfo"
"github.com/redhat-developer/odo/pkg/kclient"
"github.com/redhat-developer/odo/pkg/odo/cmdline"
"github.com/redhat-developer/odo/pkg/testingutil/filesystem"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@@ -99,12 +97,8 @@ func TestNew(t *testing.T) {
workingDir string
populateWorkingDir func(fs filesystem.Filesystem)
// current namespace
currentNamespace string
// flags
projectFlag string
appFlag string
componentFlag string
outputFlag string
allFlagSet bool
@@ -127,29 +121,17 @@ func TestNew(t *testing.T) {
isOffline: true,
workingDir: filepath.Join(prefixDir, "myapp"),
projectFlag: "myproject",
appFlag: "myapp",
componentFlag: "mycomponent",
outputFlag: "",
allFlagSet: false,
populateWorkingDir: func(fs filesystem.Filesystem) {
_ = fs.MkdirAll(filepath.Join(prefixDir, "myapp", ".odo", "env"), 0755)
env, err := envinfo.NewEnvSpecificInfo(filepath.Join(prefixDir, "myapp"))
if err != nil {
return
}
_ = env.SetComponentSettings(envinfo.ComponentSettings{
Name: "a-name",
Project: "a-project",
AppName: "an-app-name",
})
},
},
expectedErr: "",
expected: &Context{
internalCxt: internalCxt{
project: "myproject",
application: "myapp",
component: "mycomponent",
application: "app",
// empty when no devfile
componentContext: "",
outputFlag: "",
@@ -166,24 +148,13 @@ func TestNew(t *testing.T) {
outputFlag: "",
allFlagSet: false,
populateWorkingDir: func(fs filesystem.Filesystem) {
_ = fs.MkdirAll(filepath.Join(prefixDir, "myapp", ".odo", "env"), 0755)
env, err := envinfo.NewEnvSpecificInfo(filepath.Join(prefixDir, "myapp"))
if err != nil {
return
}
_ = env.SetComponentSettings(envinfo.ComponentSettings{
Name: "a-name",
Project: "a-project",
AppName: "an-app-name",
})
},
},
expectedErr: "",
expected: &Context{
internalCxt: internalCxt{
project: "",
application: "an-app-name",
component: "a-name",
application: "app",
// empty when no devfile
componentContext: "",
outputFlag: "",
@@ -202,23 +173,13 @@ func TestNew(t *testing.T) {
parentCommandName: "url",
commandName: "create",
populateWorkingDir: func(fs filesystem.Filesystem) {
_ = fs.MkdirAll(filepath.Join(prefixDir, "myapp", ".odo", "env"), 0755)
env, err := envinfo.NewEnvSpecificInfo(filepath.Join(prefixDir, "myapp"))
if err != nil {
return
}
_ = env.SetComponentSettings(envinfo.ComponentSettings{
Name: "a-name",
AppName: "an-app-name",
})
},
},
expectedErr: "",
expected: &Context{
internalCxt: internalCxt{
project: "",
application: "an-app-name",
component: "a-name",
application: "app",
componentContext: "",
outputFlag: "",
devfilePath: "",
@@ -232,21 +193,17 @@ func TestNew(t *testing.T) {
isOffline: true,
workingDir: filepath.Join(prefixDir, "myapp"),
projectFlag: "myproject",
appFlag: "myapp",
componentFlag: "mycomponent",
outputFlag: "",
allFlagSet: false,
populateWorkingDir: func(fs filesystem.Filesystem) {
_ = fs.MkdirAll(filepath.Join(prefixDir, "myapp", ".odo", "env"), 0755)
_ = fs.WriteFile(filepath.Join(prefixDir, "myapp", ".odo", "env", "env.yaml"), []byte{}, 0644)
},
},
expectedErr: "The current directory does not represent an odo component",
expected: &Context{
internalCxt: internalCxt{
project: "myproject",
application: "myapp",
component: "mycomponent",
application: "app",
componentContext: filepath.Join(prefixDir, "myapp"),
outputFlag: "",
devfilePath: "",
@@ -260,13 +217,11 @@ func TestNew(t *testing.T) {
isOffline: true,
workingDir: filepath.Join(prefixDir, "myapp"),
projectFlag: "myproject",
appFlag: "myapp",
componentFlag: "mycomponent",
outputFlag: "",
allFlagSet: false,
populateWorkingDir: func(fs filesystem.Filesystem) {
_ = fs.MkdirAll(filepath.Join(prefixDir, "myapp", ".odo", "env"), 0755)
_ = fs.WriteFile(filepath.Join(prefixDir, "myapp", ".odo", "env", "env.yaml"), []byte{}, 0644)
_ = fs.MkdirAll(filepath.Join(prefixDir, "myapp"), 0755)
_ = fs.WriteFile(filepath.Join(prefixDir, "myapp", ".devfile.yaml"), []byte(devfileYAML), 0644)
},
},
@@ -274,8 +229,7 @@ func TestNew(t *testing.T) {
expected: &Context{
internalCxt: internalCxt{
project: "myproject",
application: "myapp",
component: "mycomponent",
application: "app",
componentContext: filepath.Join(prefixDir, "myapp"),
outputFlag: "",
devfilePath: filepath.Join(prefixDir, "myapp", ".devfile.yaml"),
@@ -289,13 +243,11 @@ func TestNew(t *testing.T) {
isOffline: true,
workingDir: filepath.Join(prefixDir, "myapp"),
projectFlag: "myproject",
appFlag: "myapp",
componentFlag: "mycomponent",
outputFlag: "",
allFlagSet: false,
populateWorkingDir: func(fs filesystem.Filesystem) {
_ = fs.MkdirAll(filepath.Join(prefixDir, "myapp", ".odo", "env"), 0755)
_ = fs.WriteFile(filepath.Join(prefixDir, "myapp", ".odo", "env", "env.yaml"), []byte{}, 0644)
_ = fs.MkdirAll(filepath.Join(prefixDir, "myapp"), 0755)
_ = fs.WriteFile(filepath.Join(prefixDir, "myapp", "devfile.yaml"), []byte(devfileYAML), 0644)
},
},
@@ -303,8 +255,7 @@ func TestNew(t *testing.T) {
expected: &Context{
internalCxt: internalCxt{
project: "myproject",
application: "myapp",
component: "mycomponent",
application: "app",
componentContext: filepath.Join(prefixDir, "myapp"),
outputFlag: "",
devfilePath: filepath.Join(prefixDir, "myapp", "devfile.yaml"),
@@ -327,9 +278,7 @@ func TestNew(t *testing.T) {
// Fake Cobra
cmdline := cmdline.NewMockCmdline(ctrl)
cmdline.EXPECT().GetWorkingDirectory().Return(tt.input.workingDir, nil).AnyTimes()
cmdline.EXPECT().CheckIfConfigurationNeeded().Return(true, nil).AnyTimes()
cmdline.EXPECT().FlagValueIfSet("project").Return(tt.input.projectFlag).AnyTimes()
cmdline.EXPECT().FlagValueIfSet("app").Return(tt.input.appFlag).AnyTimes()
cmdline.EXPECT().FlagValueIfSet("component").Return(tt.input.componentFlag).AnyTimes()
cmdline.EXPECT().FlagValueIfSet("o").Return(tt.input.outputFlag).AnyTimes()
cmdline.EXPECT().IsFlagSet("all").Return(tt.input.allFlagSet).AnyTimes()
@@ -355,18 +304,6 @@ func TestNew(t *testing.T) {
}
kclient.EXPECT().GetNamespaceNormal(gomock.Any()).Return(ns, nil).AnyTimes()
if tt.expected != nil {
depName := tt.expected.component + "-" + tt.expected.application
dep := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: depName,
},
}
kclient.EXPECT().GetDeploymentByName(gomock.Any()).Return(dep, nil).AnyTimes()
kclient.EXPECT().GetCurrentNamespace().Return(tt.input.currentNamespace).AnyTimes()
cmdline.EXPECT().GetKubeClient().Return(kclient, nil).AnyTimes()
}
// Call the tested function
params := NewCreateParameters(cmdline)
if tt.input.needDevfile {
@@ -406,9 +343,6 @@ func TestNew(t *testing.T) {
if result.application != tt.expected.application {
t.Errorf("Expected application %s, got %s", tt.expected.application, result.application)
}
if result.component != tt.expected.component {
t.Errorf("Expected component %s, got %s", tt.expected.component, result.component)
}
if result.componentContext != tt.expected.componentContext {
t.Errorf("Expected component context %s, got %s", tt.expected.componentContext, result.componentContext)
}

View File

@@ -5,8 +5,6 @@ import (
kerrors "k8s.io/apimachinery/pkg/api/errors"
"github.com/redhat-developer/odo/pkg/component"
"github.com/redhat-developer/odo/pkg/localConfigProvider"
"github.com/redhat-developer/odo/pkg/odo/cmdline"
"github.com/redhat-developer/odo/pkg/odo/util"
)
@@ -53,49 +51,3 @@ func (o *internalCxt) resolveProjectAndNamespace(cmdline cmdline.Cmdline) error
o.project = namespace
return nil
}
// resolveApp resolves the app
// If `--app` flag is used, return its value
// Or If app is set in envfile, return its value
// Or if createAppIfNeeded, returns the default app name
func resolveApp(cmdline cmdline.Cmdline, localConfiguration localConfigProvider.LocalConfigProvider, createAppIfNeeded bool) string {
appFlag := cmdline.FlagValueIfSet(util.ApplicationFlagName)
if len(appFlag) > 0 {
return appFlag
}
app := localConfiguration.GetApplication()
if app == "" && createAppIfNeeded {
app = defaultAppName
}
return app
}
// resolveComponent resolves component
// If `--component` flag is used, return its value
// Or Return the value in envfile
func resolveComponent(cmdline cmdline.Cmdline, localConfiguration localConfigProvider.LocalConfigProvider) string {
cmpFlag := cmdline.FlagValueIfSet(util.ComponentFlagName)
if len(cmpFlag) > 0 {
return cmpFlag
}
return localConfiguration.GetName()
}
func resolveProject(cmdline cmdline.Cmdline) string {
return cmdline.FlagValueIfSet(util.ProjectFlagName)
}
// checkComponentExistsOrFail checks if the specified component exists with the given context and returns error if not.
// KClient, component and application should have been set before to call this method
func (o *internalCxt) checkComponentExistsOrFail() error {
exists, err := component.Exists(o.KClient, o.component, o.application)
if err != nil {
return err
}
if !exists {
return fmt.Errorf("component %v does not exist in application %s", o.component, o.application)
}
return nil
}

View File

@@ -7,10 +7,6 @@ import (
const (
// ProjectFlagName is the name of the flag allowing a user to specify which project to operate on
ProjectFlagName = "project"
// ApplicationFlagName is the name of the flag allowing a user to specify which application to operate on
ApplicationFlagName = "app"
// ComponentFlagName is the name of the flag allowing a user to specify which component to operate on
ComponentFlagName = "component"
// OutputFlagName is the name of the flag allowing user to specify output format
OutputFlagName = "o"
// ContextFlagName is the name of the flag allowing a user to specify the location of the component settings

View File

@@ -330,8 +330,6 @@ func Test_kubernetesClient_List(t *testing.T) {
defer ctrl.Finish()
mockLocalConfig := localConfigProvider.NewMockLocalConfigProvider(ctrl)
mockLocalConfig.EXPECT().GetName().Return(tt.fields.generic.componentName).AnyTimes()
mockLocalConfig.EXPECT().GetApplication().Return(tt.fields.generic.appName).AnyTimes()
tt.fields.generic.localConfigProvider = mockLocalConfig

View File

@@ -104,7 +104,7 @@ func Push(client Client, configProvider localConfigProvider.LocalConfigProvider)
if err != nil {
return nil, err
}
log.Successf("Deleted storage %v from %v", storage.Name, configProvider.GetName())
log.Successf("Deleted storage %v from component", storage.Name)
continue
} else if storage.Name == val.Name {
if val.Spec.Size != storage.Spec.Size {
@@ -122,7 +122,7 @@ func Push(client Client, configProvider localConfigProvider.LocalConfigProvider)
if e := client.Create(storage); e != nil {
return nil, e
}
log.Successf("Added storage %v to %v", storage.Name, configProvider.GetName())
log.Successf("Added storage %v to component", storage.Name)
}
return ephemeralConfigNames, nil

View File

@@ -18,8 +18,6 @@ func getStorageLabels(storageName, componentName, applicationName string) map[st
}
func TestPush(t *testing.T) {
componentName := "nodejs"
localStorage0 := localConfigProvider.LocalStorage{
Name: "storage-0",
Size: "1Gi",
@@ -243,8 +241,6 @@ func TestPush(t *testing.T) {
fakeStorageClient := NewMockClient(ctrl)
fakeLocalConfig := localConfigProvider.NewMockLocalConfigProvider(ctrl)
fakeLocalConfig.EXPECT().GetName().Return(componentName).AnyTimes()
fakeStorageClient.EXPECT().List().Return(tt.returnedFromCluster, nil).AnyTimes()
fakeLocalConfig.EXPECT().ListStorage().Return(tt.returnedFromLocal, nil).AnyTimes()

View File

@@ -20,7 +20,6 @@ import (
const DotOdoDirectory = ".odo"
const fileIndexName = "odo-file-index.json"
const fileDevState = "devstate.json"
// FileIndex holds the file index used for storing local file state change
type FileIndex struct {
@@ -98,21 +97,12 @@ func GetIndexFileRelativeToContext() string {
}
// AddOdoFileIndex adds odo-file-index.json to .gitignore
func AddOdoFileIndex(gitIgnoreFile string) error {
return addOdoFileIndex(gitIgnoreFile, filesystem.DefaultFs{})
func AddOdoDirectory(gitIgnoreFile string) error {
return addOdoDirectory(gitIgnoreFile, filesystem.DefaultFs{})
}
func addOdoFileIndex(gitIgnoreFile string, fs filesystem.Filesystem) error {
return addFileToIgnoreFile(gitIgnoreFile, filepath.Join(DotOdoDirectory, fileIndexName), fs)
}
// AddOdoDevState adds devstate.json to .gitignore
func AddOdoDevState(gitIgnoreFile string) error {
return addOdoDevState(gitIgnoreFile, filesystem.DefaultFs{})
}
func addOdoDevState(gitIgnoreFile string, fs filesystem.Filesystem) error {
return addFileToIgnoreFile(gitIgnoreFile, filepath.Join(DotOdoDirectory, fileDevState), fs)
func addOdoDirectory(gitIgnoreFile string, fs filesystem.Filesystem) error {
return addFileToIgnoreFile(gitIgnoreFile, DotOdoDirectory, fs)
}
// TouchGitIgnoreFile checks .gitignore file exists or not, if not then create it

View File

@@ -74,7 +74,7 @@ func TestCheckGitIgnoreFile(t *testing.T) {
}
func TestAddOdoFileIndex(t *testing.T) {
func TestAddOdoDirectory(t *testing.T) {
// create a fake fs in memory
fs := filesystem.NewFakeFs()
@@ -94,7 +94,7 @@ func TestAddOdoFileIndex(t *testing.T) {
wantErr bool
}{
{
testName: "Test when odo-file-index.json added to .gitignore",
testName: "Test when .odo added to .gitignore",
create: false,
gitIgnoreCreate: mockDirectoryInfo,
directory: gitignorePath,
@@ -111,7 +111,7 @@ func TestAddOdoFileIndex(t *testing.T) {
t.Run(tt.testName, func(t *testing.T) {
err := addOdoFileIndex(tt.directory, fs)
err := addOdoDirectory(tt.directory, fs)
if !tt.wantErr == (err != nil) {
t.Errorf("addOdoFileIndex unexpected error %v, wantErr %v", err, tt.wantErr)

View File

@@ -75,7 +75,7 @@ type WatchParameters struct {
DevfileWatchHandler func(adapters.PushParameters, WatchParameters, *ComponentStatus) error
// Parameter whether or not to show build logs
Show bool
// EnvSpecificInfo contains information of env.yaml file
// EnvSpecificInfo contains information about devfile
EnvSpecificInfo *envinfo.EnvSpecificInfo
// DevfileBuildCmd takes the build command through the command line and overwrites devfile build command
DevfileBuildCmd string
@@ -541,7 +541,6 @@ func processEvents(
DevfileScanIndexForWatch: !hasFirstSuccessfulPushOccurred,
EnvSpecificInfo: *parameters.EnvSpecificInfo,
Debug: parameters.Debug,
DebugPort: parameters.DebugPort,
RandomPorts: parameters.RandomPorts,
ErrOut: parameters.ErrOut,
}

View File

@@ -11,6 +11,9 @@ components:
targetPort: 3000
- name: tcp-5858
targetPort: 5858
env:
- name: DEBUG_PORT_PROJECT
value: "5858"
image: registry.access.redhat.com/ubi8/nodejs-14:latest
name: runtime

View File

@@ -16,6 +16,9 @@ components:
targetPort: 3000
- name: "5858-tcp"
targetPort: 5858
env:
- name: DEBUG_PORT_PROJECT
value: "5858"
mountSources: true
commands:
- id: devbuild

View File

@@ -41,6 +41,9 @@ components:
targetPort: 3000
- name: tcp-5858
targetPort: 5858
env:
- name: DEBUG_PORT_PROJECT
value: "5858"
volumeMounts:
- name: artifacts
path: /artifacts

View File

@@ -18,6 +18,9 @@ components:
targetPort: 3000
- name: tcp-5858
targetPort: 5858
env:
- name: DEBUG_PORT_PROJECT
value: "5858"
commands:
- id: install
exec:

View File

@@ -5,7 +5,7 @@
"license": "EPL-2.0",
"scripts": {
"start": "node server.js",
"debug": "node --inspect-brk=${DEBUG_PORT} server.js",
"debug": "node --inspect-brk=${DEBUG_PORT_PROJECT} server.js",
"test": "node test/test.js"
},
"dependencies": {

View File

@@ -29,7 +29,7 @@ var _ = Describe("odo delete command tests", func() {
helper.CommonAfterEach(commonVar)
})
When("running odo delete from a directory that does not contain a .odo/env/env.yaml file", func() {
When("running odo delete from a non-component directory", func() {
var files []string
BeforeEach(func() {
files = helper.ListFilesInDir(commonVar.Context)

View File

@@ -53,6 +53,13 @@ var _ = Describe("odo dev debug command tests", func() {
// We are just using this to validate if nodejs agent is listening on the other side
helper.HttpWaitForWithStatus("http://"+ports["5858"], "WebSockets request was expected", 12, 5, 400)
})
// #6056
It("should not add a DEBUG_PORT variable to the container", func() {
podName := commonVar.CliRunner.GetRunningPodNameByComponent(cmpName, commonVar.Project)
stdout := commonVar.CliRunner.Exec(podName, commonVar.Project, "--", "sh", "-c", "echo -n ${DEBUG_PORT}")
Expect(stdout).To(BeEmpty())
})
})
})

View File

@@ -235,8 +235,8 @@ ComponentSettings:
devSession.WaitEnd()
})
It("should have modified env.yaml indicating current namespace and use current namespace", func() {
helper.FileShouldContainSubstring(".odo/env/env.yaml", "Project: "+commonVar.Project)
It("should not have modified env.yaml, and use current namespace", func() {
helper.FileShouldContainSubstring(".odo/env/env.yaml", "Project: another-project")
deploymentName := fmt.Sprintf("%s-%s", cmpName, "app")
out := commonVar.CliRunner.Run("get", "deployments", deploymentName, "-n", commonVar.Project).Out.Contents()
@@ -253,9 +253,6 @@ ComponentSettings:
var err error
devSession, _, _, _, err = helper.StartDevMode(nil)
Expect(err).ToNot(HaveOccurred())
// An ENV file should have been created indicating current namespace
Expect(helper.VerifyFileExists(".odo/env/env.yaml")).To(BeTrue())
helper.FileShouldContainSubstring(".odo/env/env.yaml", "Project: "+commonVar.Project)
})
AfterEach(func() {
@@ -274,11 +271,6 @@ ComponentSettings:
errout := commonVar.CliRunner.Run("get", "deployment", "-n", commonVar.Project).Err.Contents()
Expect(string(errout)).ToNot(ContainSubstring(deploymentName))
})
It("should unset project from env.yaml file", func() {
Expect(helper.VerifyFileExists(".odo/env/env.yaml")).To(BeTrue())
helper.FileShouldNotContainSubstring(".odo/env/env.yaml", "Project")
})
})
})
@@ -290,10 +282,6 @@ ComponentSettings:
var err error
devSession, _, _, _, err = helper.StartDevMode(nil)
Expect(err).ToNot(HaveOccurred())
// An ENV file should have been created indicating current namespace
Expect(helper.VerifyFileExists(".odo/env/env.yaml")).To(BeTrue())
helper.FileShouldContainSubstring(".odo/env/env.yaml", "Project: "+commonVar.Project)
helper.FileShouldNotContainSubstring(".odo/env/env.yaml", "Name: "+cmpName)
})
AfterEach(func() {
@@ -386,9 +374,6 @@ ComponentSettings:
var err error
devSession, _, _, _, err = helper.StartDevMode(nil, "--no-watch")
Expect(err).ToNot(HaveOccurred())
// An ENV file should have been created indicating current namespace
Expect(helper.VerifyFileExists(".odo/env/env.yaml")).To(BeTrue())
helper.FileShouldContainSubstring(".odo/env/env.yaml", "Project: "+commonVar.Project)
})
AfterEach(func() {

View File

@@ -147,9 +147,7 @@ var _ = Describe("odo create/delete/list/set namespace/project tests", func() {
helper.MakeDir(odoDir)
err := helper.CreateFileWithContent(filepath.Join(odoDir, "env.yaml"), fmt.Sprintf(`
ComponentSettings:
Name: my-component
Project: %s
AppName: app
`, commonVar.Project))
Expect(err).ShouldNot(HaveOccurred())
})