diff --git a/pkg/dev/dev.go b/pkg/dev/dev.go index 6f2934b8211..7c95694c9fd 100644 --- a/pkg/dev/dev.go +++ b/pkg/dev/dev.go @@ -13,8 +13,7 @@ import ( "k8s.io/klog/v2" "github.com/redhat-developer/odo/pkg/devfile/adapters" - "github.com/redhat-developer/odo/pkg/devfile/adapters/common" - "github.com/redhat-developer/odo/pkg/devfile/adapters/kubernetes" + "github.com/redhat-developer/odo/pkg/devfile/adapters/kubernetes/component" "github.com/redhat-developer/odo/pkg/watch" ) @@ -43,7 +42,7 @@ func NewDevClient( func (o *DevClient) Start( devfileObj parser.DevfileObj, - platformContext kubernetes.KubernetesContext, + namespace string, ignorePaths []string, path string, debug bool, @@ -53,19 +52,22 @@ func (o *DevClient) Start( errOut io.Writer, ) error { klog.V(4).Infoln("Creating new adapter") - adapter, err := adapters.NewComponentAdapter( + adapter := component.NewKubernetesAdapter( o.kubernetesClient, o.prefClient, o.portForwardClient, - devfileObj.GetMetadataName(), path, "app", devfileObj, platformContext, randomPorts, errOut) - if err != nil { - return err - } + component.AdapterContext{ + ComponentName: devfileObj.GetMetadataName(), + Context: path, + AppName: "app", + Devfile: devfileObj, + }, + namespace, randomPorts, errOut) envSpecificInfo, err := envinfo.NewEnvSpecificInfo(path) if err != nil { return err } - pushParameters := common.PushParameters{ + pushParameters := adapters.PushParameters{ EnvSpecificInfo: *envSpecificInfo, DebugPort: envSpecificInfo.GetDebugPort(), Path: path, diff --git a/pkg/dev/interface.go b/pkg/dev/interface.go index 3aa85082d3f..0459719383d 100644 --- a/pkg/dev/interface.go +++ b/pkg/dev/interface.go @@ -4,22 +4,20 @@ import ( "context" "io" - "github.com/redhat-developer/odo/pkg/devfile/adapters/common" - "github.com/devfile/library/pkg/devfile/parser" - "github.com/redhat-developer/odo/pkg/devfile/adapters/kubernetes" + "github.com/redhat-developer/odo/pkg/devfile/adapters" "github.com/redhat-developer/odo/pkg/watch" ) type Client interface { - // Start the resources in devfileObj on the platformContext. It then pushes the files in path to the container. + // Start the resources in devfileObj on the namespace. It then pushes the files in path to the container. // If debug is true, executes the debug command, or the run command by default. // If buildCommand is set, this will look up the specified build command in the Devfile. Otherwise, it uses the default one. // If runCommand is set, this will look up the specified run command in the Devfile and execute it. Otherwise, it uses the default one. Start( devfileObj parser.DevfileObj, - platformContext kubernetes.KubernetesContext, + namespace string, ignorePaths []string, path string, debug bool, @@ -50,5 +48,5 @@ type Client interface { } type Handler interface { - RegenerateAdapterAndPush(common.PushParameters, watch.WatchParameters) error + RegenerateAdapterAndPush(adapters.PushParameters, watch.WatchParameters) error } diff --git a/pkg/dev/mock.go b/pkg/dev/mock.go index a9d2ff0edd0..59dfa030174 100644 --- a/pkg/dev/mock.go +++ b/pkg/dev/mock.go @@ -11,8 +11,7 @@ import ( parser "github.com/devfile/library/pkg/devfile/parser" gomock "github.com/golang/mock/gomock" - common "github.com/redhat-developer/odo/pkg/devfile/adapters/common" - kubernetes "github.com/redhat-developer/odo/pkg/devfile/adapters/kubernetes" + adapters "github.com/redhat-developer/odo/pkg/devfile/adapters" watch "github.com/redhat-developer/odo/pkg/watch" ) @@ -40,31 +39,31 @@ func (m *MockClient) EXPECT() *MockClientMockRecorder { } // Start mocks base method. -func (m *MockClient) Start(devfileObj parser.DevfileObj, platformContext kubernetes.KubernetesContext, ignorePaths []string, path string, debug, randomPorts bool, errOut io.Writer) error { +func (m *MockClient) Start(devfileObj parser.DevfileObj, namespace string, ignorePaths []string, path string, debug bool, buildCommand, runCommand string, randomPorts bool, errOut io.Writer) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Start", devfileObj, platformContext, ignorePaths, path, debug, randomPorts, errOut) + ret := m.ctrl.Call(m, "Start", devfileObj, namespace, ignorePaths, path, debug, buildCommand, runCommand, randomPorts, errOut) ret0, _ := ret[0].(error) return ret0 } // Start indicates an expected call of Start. -func (mr *MockClientMockRecorder) Start(devfileObj, platformContext, ignorePaths, path, debug, randomPorts, errOut interface{}) *gomock.Call { +func (mr *MockClientMockRecorder) Start(devfileObj, namespace, ignorePaths, path, debug, buildCommand, runCommand, randomPorts, errOut interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Start", reflect.TypeOf((*MockClient)(nil).Start), devfileObj, platformContext, ignorePaths, path, debug, randomPorts, errOut) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Start", reflect.TypeOf((*MockClient)(nil).Start), devfileObj, namespace, ignorePaths, path, debug, buildCommand, runCommand, randomPorts, errOut) } // Watch mocks base method. -func (m *MockClient) Watch(devfileObj parser.DevfileObj, path string, ignorePaths []string, out io.Writer, h Handler, ctx context.Context, debug bool, variables map[string]string) error { +func (m *MockClient) Watch(devfileObj parser.DevfileObj, path string, ignorePaths []string, out io.Writer, h Handler, ctx context.Context, debug bool, buildCommand, runCommand string, variables map[string]string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Watch", devfileObj, path, ignorePaths, out, h, ctx, debug, variables) + ret := m.ctrl.Call(m, "Watch", devfileObj, path, ignorePaths, out, h, ctx, debug, buildCommand, runCommand, variables) ret0, _ := ret[0].(error) return ret0 } // Watch indicates an expected call of Watch. -func (mr *MockClientMockRecorder) Watch(devfileObj, path, ignorePaths, out, h, ctx, debug, variables interface{}) *gomock.Call { +func (mr *MockClientMockRecorder) Watch(devfileObj, path, ignorePaths, out, h, ctx, debug, buildCommand, runCommand, variables interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Watch", reflect.TypeOf((*MockClient)(nil).Watch), devfileObj, path, ignorePaths, out, h, ctx, debug, variables) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Watch", reflect.TypeOf((*MockClient)(nil).Watch), devfileObj, path, ignorePaths, out, h, ctx, debug, buildCommand, runCommand, variables) } // MockHandler is a mock of Handler interface. @@ -91,7 +90,7 @@ func (m *MockHandler) EXPECT() *MockHandlerMockRecorder { } // RegenerateAdapterAndPush mocks base method. -func (m *MockHandler) RegenerateAdapterAndPush(arg0 common.PushParameters, arg1 watch.WatchParameters) error { +func (m *MockHandler) RegenerateAdapterAndPush(arg0 adapters.PushParameters, arg1 watch.WatchParameters) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "RegenerateAdapterAndPush", arg0, arg1) ret0, _ := ret[0].(error) diff --git a/pkg/devfile/adapters/common/interface.go b/pkg/devfile/adapters/common/interface.go deleted file mode 100644 index 00f7e836a38..00000000000 --- a/pkg/devfile/adapters/common/interface.go +++ /dev/null @@ -1,6 +0,0 @@ -package common - -// ComponentAdapter defines the functions that platform-specific adapters must implement -type ComponentAdapter interface { - Push(parameters PushParameters) error -} diff --git a/pkg/devfile/adapters/common/utils.go b/pkg/devfile/adapters/common/utils.go deleted file mode 100644 index edae73f589d..00000000000 --- a/pkg/devfile/adapters/common/utils.go +++ /dev/null @@ -1,41 +0,0 @@ -package common - -import ( - "path/filepath" - "strings" - - devfilev1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" -) - -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" -) - -// GetCommandsMap returns a map of the command Id to the command -func GetCommandsMap(commands []devfilev1.Command) map[string]devfilev1.Command { - commandMap := make(map[string]devfilev1.Command, len(commands)) - for _, command := range commands { - command.Id = strings.ToLower(command.Id) - commandMap[command.Id] = command - } - return commandMap -} - -// GetSyncFilesFromAttributes gets the target files and folders along with their respective remote destination from the devfile -// it uses the "dev.odo.push.path" attribute in the run command -func GetSyncFilesFromAttributes(commandsMap PushCommandsMap) map[string]string { - syncMap := make(map[string]string) - if value, ok := commandsMap[devfilev1.RunCommandGroupKind]; ok { - for key, value := range value.Attributes.Strings(nil) { - if strings.HasPrefix(key, "dev.odo.push.path:") { - localValue := strings.ReplaceAll(key, "dev.odo.push.path:", "") - syncMap[filepath.Clean(localValue)] = filepath.ToSlash(filepath.Clean(value)) - } - } - } - return syncMap -} diff --git a/pkg/devfile/adapters/helper.go b/pkg/devfile/adapters/helper.go deleted file mode 100644 index 12ba53b5f19..00000000000 --- a/pkg/devfile/adapters/helper.go +++ /dev/null @@ -1,71 +0,0 @@ -package adapters - -import ( - "errors" - "io" - - devfileParser "github.com/devfile/library/pkg/devfile/parser" - "github.com/redhat-developer/odo/pkg/devfile/adapters/common" - "github.com/redhat-developer/odo/pkg/devfile/adapters/kubernetes" - "github.com/redhat-developer/odo/pkg/kclient" - "github.com/redhat-developer/odo/pkg/portForward" - "github.com/redhat-developer/odo/pkg/preference" -) - -// NewComponentAdapter returns a Devfile adapter for the targeted platform -func NewComponentAdapter( - kubernetesClient kclient.ClientInterface, - prefClient preference.Client, - portForwardClient portForward.Client, - componentName string, - context string, - appName string, - devObj devfileParser.DevfileObj, - platformContext interface{}, - randomPorts bool, - errOut io.Writer, -) (common.ComponentAdapter, error) { - - adapterContext := common.AdapterContext{ - ComponentName: componentName, - Context: context, - AppName: appName, - Devfile: devObj, - } - - kc, ok := platformContext.(kubernetes.KubernetesContext) - if !ok { - return nil, errors.New("error retrieving context for Kubernetes") - } - return createKubernetesAdapter(adapterContext, kubernetesClient, prefClient, portForwardClient, kc.Namespace, randomPorts, errOut) - -} - -func createKubernetesAdapter( - adapterContext common.AdapterContext, - kubernetesClient kclient.ClientInterface, - prefClient preference.Client, - portForwardClient portForward.Client, - namespace string, - randomPorts bool, - errOut io.Writer, -) (common.ComponentAdapter, error) { - if namespace != "" { - kubernetesClient.SetNamespace(namespace) - } - return newKubernetesAdapter(adapterContext, kubernetesClient, prefClient, portForwardClient, randomPorts, errOut) -} - -func newKubernetesAdapter( - adapterContext common.AdapterContext, - client kclient.ClientInterface, - prefClient preference.Client, - portForwardClient portForward.Client, - randomPorts bool, - errOut io.Writer, -) (common.ComponentAdapter, error) { - // Feed the common metadata to the platform-specific adapter - kubernetesAdapter := kubernetes.New(adapterContext, client, prefClient, portForwardClient, randomPorts, errOut) - - return kubernetesAdapter, nil -} diff --git a/pkg/devfile/adapters/helper_test.go b/pkg/devfile/adapters/helper_test.go deleted file mode 100644 index dec95803a7e..00000000000 --- a/pkg/devfile/adapters/helper_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package adapters - -import ( - "os" - "reflect" - "testing" - - "github.com/devfile/library/pkg/devfile/parser/data" - - devfilev1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" - devfileParser "github.com/devfile/library/pkg/devfile/parser" - adaptersCommon "github.com/redhat-developer/odo/pkg/devfile/adapters/common" - "github.com/redhat-developer/odo/pkg/kclient" -) - -func TestNewPlatformAdapter(t *testing.T) { - tests := []struct { - adapterType string - name string - componentName string - componentType devfilev1.ComponentType - wantErr bool - }{ - { - adapterType: "kubernetes.Adapter", - name: "get platform adapter", - componentName: "test", - componentType: devfilev1.ContainerComponentType, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run("get platform adapter", func(t *testing.T) { - devObj := devfileParser.DevfileObj{ - Data: func() data.DevfileData { - devfileData, err := data.NewDevfileData(string(data.APISchemaVersion200)) - if err != nil { - t.Error(err) - } - err = devfileData.AddComponents([]devfilev1.Component{}) - if err != nil { - t.Error(err) - } - return devfileData - }(), - } - - adapterContext := adaptersCommon.AdapterContext{ - ComponentName: tt.componentName, - Devfile: devObj, - } - fkclient, _ := kclient.FakeNew() - adapter, err := newKubernetesAdapter(adapterContext, fkclient, nil, nil, false, os.Stdout) - if err != nil { - t.Errorf("unexpected error: '%v'", err) - } - - // test that the returned adapter is of the right type - if !tt.wantErr == (reflect.TypeOf(adapter).String() != tt.adapterType) { - t.Errorf("incorrect adapter type: '%v'", err) - } - }) - } -} diff --git a/pkg/devfile/adapters/kubernetes/adapter.go b/pkg/devfile/adapters/kubernetes/adapter.go deleted file mode 100644 index 1540fc5a9ef..00000000000 --- a/pkg/devfile/adapters/kubernetes/adapter.go +++ /dev/null @@ -1,52 +0,0 @@ -package kubernetes - -import ( - "fmt" - "io" - - "github.com/redhat-developer/odo/pkg/kclient" - "github.com/redhat-developer/odo/pkg/portForward" - "github.com/redhat-developer/odo/pkg/preference" - - "github.com/redhat-developer/odo/pkg/devfile/adapters/common" - "github.com/redhat-developer/odo/pkg/devfile/adapters/kubernetes/component" -) - -// Adapter maps Devfiles to Kubernetes resources and actions -type Adapter struct { - componentAdapter common.ComponentAdapter -} - -var _ common.ComponentAdapter = (*Adapter)(nil) - -type KubernetesContext struct { - Namespace string -} - -// New instantiates a kubernetes adapter -func New( - adapterContext common.AdapterContext, - client kclient.ClientInterface, - prefClient preference.Client, - portForwardClient portForward.Client, - randomPorts bool, - errOut io.Writer, -) Adapter { - - compAdapter := component.New(adapterContext, client, prefClient, portForwardClient, randomPorts, errOut) - - return Adapter{ - componentAdapter: &compAdapter, - } -} - -// Push creates Kubernetes resources that correspond to the devfile if they don't already exist -func (k Adapter) Push(parameters common.PushParameters) error { - - err := k.componentAdapter.Push(parameters) - if err != nil { - return fmt.Errorf("failed to create the component: %w", err) - } - - return nil -} diff --git a/pkg/devfile/adapters/kubernetes/component/adapter.go b/pkg/devfile/adapters/kubernetes/component/adapter.go index 6b105a44558..d06fc741c7d 100644 --- a/pkg/devfile/adapters/kubernetes/component/adapter.go +++ b/pkg/devfile/adapters/kubernetes/component/adapter.go @@ -3,15 +3,14 @@ package component import ( "fmt" "io" + "path/filepath" + "strings" "k8s.io/utils/pointer" - "github.com/devfile/library/pkg/devfile/generator" - devfileCommon "github.com/devfile/library/pkg/devfile/parser/data/v2/common" - "github.com/redhat-developer/odo/pkg/component" "github.com/redhat-developer/odo/pkg/devfile" - "github.com/redhat-developer/odo/pkg/devfile/adapters/common" + "github.com/redhat-developer/odo/pkg/devfile/adapters" "github.com/redhat-developer/odo/pkg/devfile/adapters/kubernetes/storage" "github.com/redhat-developer/odo/pkg/devfile/adapters/kubernetes/utils" "github.com/redhat-developer/odo/pkg/envinfo" @@ -28,6 +27,8 @@ import ( "github.com/redhat-developer/odo/pkg/util" devfilev1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" + "github.com/devfile/library/pkg/devfile/generator" + "github.com/devfile/library/pkg/devfile/parser" parsercommon "github.com/devfile/library/pkg/devfile/parser/data/v2/common" dfutil "github.com/devfile/library/pkg/util" @@ -37,20 +38,57 @@ import ( "k8s.io/klog" ) -// New instantiates a component adapter -func New( - adapterContext common.AdapterContext, - kubeClient kclient.ClientInterface, +// Adapter is a component adapter implementation for Kubernetes +type Adapter struct { + kubeClient kclient.ClientInterface + prefClient preference.Client + portForwardClient portForward.Client + + AdapterContext + logger machineoutput.MachineEventLoggingClient + + devfileBuildCmd string + devfileRunCmd string + devfileDebugCmd string + devfileDebugPort int + pod *corev1.Pod + deployment *appsv1.Deployment + + randomPorts bool + errOut io.Writer +} + +// AdapterContext is a construct that is common to all adapters +type AdapterContext struct { + ComponentName string // ComponentName is the odo component name, it is NOT related to any devfile components + Context string // Context is the given directory containing the source code and configs + AppName string // the application name associated to a component + Devfile parser.DevfileObj // Devfile is the object returned by the Devfile parser +} + +var _ sync.SyncClient = (*Adapter)(nil) +var _ ComponentAdapter = (*Adapter)(nil) + +// NewKubernetesAdapter returns a Devfile adapter for the targeted platform +func NewKubernetesAdapter( + kubernetesClient kclient.ClientInterface, prefClient preference.Client, portForwardClient portForward.Client, + context AdapterContext, + namespace string, randomPorts bool, errOut io.Writer, ) Adapter { + + if namespace != "" { + kubernetesClient.SetNamespace(namespace) + } + return Adapter{ - kubeClient: kubeClient, + kubeClient: kubernetesClient, prefClient: prefClient, portForwardClient: portForwardClient, - AdapterContext: adapterContext, + AdapterContext: context, logger: machineoutput.NewMachineEventLoggingClient(), randomPorts: randomPorts, errOut: errOut, @@ -73,43 +111,20 @@ func (a *Adapter) getPod(refresh bool) (*corev1.Pod, error) { return a.pod, nil } -func (a *Adapter) ComponentInfo(command devfilev1.Command) (common.ComponentInfo, error) { +func (a *Adapter) ComponentInfo(command devfilev1.Command) (adapters.ComponentInfo, error) { pod, err := a.getPod(false) if err != nil { - return common.ComponentInfo{}, err + return adapters.ComponentInfo{}, err } - return common.ComponentInfo{ + return adapters.ComponentInfo{ PodName: pod.Name, ContainerName: command.Exec.Component, }, nil } -// Adapter is a component adapter implementation for Kubernetes -type Adapter struct { - kubeClient kclient.ClientInterface - prefClient preference.Client - portForwardClient portForward.Client - - common.AdapterContext - logger machineoutput.MachineEventLoggingClient - - devfileBuildCmd string - devfileRunCmd string - devfileDebugCmd string - devfileDebugPort int - pod *corev1.Pod - deployment *appsv1.Deployment - - randomPorts bool - errOut io.Writer -} - -var _ sync.SyncClient = (*Adapter)(nil) -var _ common.ComponentAdapter = (*Adapter)(nil) - // Push updates the component if a matching component exists or creates one if it doesn't exist // Once the component has started, it will sync the source code to it. -func (a Adapter) Push(parameters common.PushParameters) (err error) { +func (a Adapter) Push(parameters adapters.PushParameters) (err error) { // Get the Dev deployment: // Since `odo deploy` can theoretically deploy a deployment as well with the same instance name @@ -293,18 +308,18 @@ func (a Adapter) Push(parameters common.PushParameters) (err error) { s = log.Spinner("Syncing files into the container") defer s.End(false) // Get a sync adapter. Check if project files have changed and sync accordingly - syncAdapter := sync.New(a.AdapterContext, &a, a.kubeClient) - compInfo := common.ComponentInfo{ + syncAdapter := sync.New(&a, a.kubeClient, a.ComponentName) + compInfo := adapters.ComponentInfo{ ContainerName: containerName, PodName: pod.GetName(), SyncFolder: syncFolder, } - syncParams := common.SyncParameters{ + syncParams := adapters.SyncParameters{ PushParams: parameters, CompInfo: compInfo, ComponentExists: componentExists, PodChanged: podChanged, - Files: common.GetSyncFilesFromAttributes(pushDevfileCommands), + Files: getSyncFilesFromAttributes(pushDevfileCommands), } execRequired, err := syncAdapter.SyncFiles(syncParams) @@ -335,7 +350,7 @@ func (a Adapter) Push(parameters common.PushParameters) (err error) { return err } - commandType, err := devfileCommon.GetCommandType(cmd) + commandType, err := parsercommon.GetCommandType(cmd) if err != nil { return err } @@ -656,6 +671,24 @@ func getFirstContainerWithSourceVolume(containers []corev1.Container) (string, s } // ExtractProjectToComponent extracts the project archive(tar) to the target path from the reader stdin -func (a Adapter) ExtractProjectToComponent(componentInfo common.ComponentInfo, targetPath string, stdin io.Reader) error { +func (a Adapter) ExtractProjectToComponent(componentInfo adapters.ComponentInfo, targetPath string, stdin io.Reader) error { return a.kubeClient.ExtractProjectToComponent(componentInfo.ContainerName, componentInfo.PodName, targetPath, stdin) } + +// PushCommandsMap stores the commands to be executed as per their types. +type PushCommandsMap map[devfilev1.CommandGroupKind]devfilev1.Command + +// getSyncFilesFromAttributes gets the target files and folders along with their respective remote destination from the devfile +// it uses the "dev.odo.push.path" attribute in the run command +func getSyncFilesFromAttributes(commandsMap PushCommandsMap) map[string]string { + syncMap := make(map[string]string) + if value, ok := commandsMap[devfilev1.RunCommandGroupKind]; ok { + for key, value := range value.Attributes.Strings(nil) { + if strings.HasPrefix(key, "dev.odo.push.path:") { + localValue := strings.ReplaceAll(key, "dev.odo.push.path:", "") + syncMap[filepath.Clean(localValue)] = filepath.ToSlash(filepath.Clean(value)) + } + } + } + return syncMap +} diff --git a/pkg/devfile/adapters/kubernetes/component/adapter_test.go b/pkg/devfile/adapters/kubernetes/component/adapter_test.go index f093d0303c0..da92eb0038e 100644 --- a/pkg/devfile/adapters/kubernetes/component/adapter_test.go +++ b/pkg/devfile/adapters/kubernetes/component/adapter_test.go @@ -22,7 +22,6 @@ import ( devfileParser "github.com/devfile/library/pkg/devfile/parser" "github.com/devfile/library/pkg/testingutil" - adaptersCommon "github.com/redhat-developer/odo/pkg/devfile/adapters/common" "github.com/redhat-developer/odo/pkg/kclient" odolabels "github.com/redhat-developer/odo/pkg/labels" odoTestingUtil "github.com/redhat-developer/odo/pkg/testingutil" @@ -114,7 +113,7 @@ func TestCreateOrUpdateComponent(t *testing.T) { }(), } - adapterCtx := adaptersCommon.AdapterContext{ + adapterCtx := AdapterContext{ ComponentName: testComponentName, AppName: testAppName, Devfile: devObj, @@ -135,7 +134,7 @@ func TestCreateOrUpdateComponent(t *testing.T) { Name: testComponentName, AppName: testAppName, }) - componentAdapter := New(adapterCtx, fkclient, nil, nil, false, os.Stdout) + componentAdapter := NewKubernetesAdapter(fkclient, nil, nil, adapterCtx, "", false, os.Stdout) err := componentAdapter.createOrUpdateComponent(tt.running, tt.envInfo, false) // Checks for unexpected error cases @@ -310,7 +309,7 @@ func TestDoesComponentExist(t *testing.T) { }(), } - adapterCtx := adaptersCommon.AdapterContext{ + adapterCtx := AdapterContext{ ComponentName: tt.componentName, AppName: tt.appName, Devfile: devObj, @@ -348,7 +347,7 @@ func TestDoesComponentExist(t *testing.T) { }) // DoesComponentExist requires an already started component, so start it. - componentAdapter := New(adapterCtx, fkclient, nil, nil, false, os.Stdout) + componentAdapter := NewKubernetesAdapter(fkclient, nil, nil, adapterCtx, "", false, os.Stdout) err := componentAdapter.createOrUpdateComponent(false, tt.envInfo, false) // Checks for unexpected error cases @@ -424,7 +423,7 @@ func TestWaitAndGetComponentPod(t *testing.T) { }(), } - adapterCtx := adaptersCommon.AdapterContext{ + adapterCtx := AdapterContext{ ComponentName: testComponentName, Devfile: devObj, } @@ -444,7 +443,7 @@ func TestWaitAndGetComponentPod(t *testing.T) { ctrl := gomock.NewController(t) prefClient := preference.NewMockClient(ctrl) prefClient.EXPECT().GetPushTimeout().Return(100 * time.Second) - componentAdapter := New(adapterCtx, fkclient, prefClient, nil, false, os.Stdout) + componentAdapter := NewKubernetesAdapter(fkclient, prefClient, nil, adapterCtx, "", false, os.Stdout) _, err := componentAdapter.getPod(false) // Checks for unexpected error cases @@ -552,7 +551,7 @@ func TestAdapter_generateDeploymentObjectMeta(t *testing.T) { a := Adapter{ kubeClient: fakeClient, - AdapterContext: adaptersCommon.AdapterContext{ + AdapterContext: AdapterContext{ ComponentName: tt.fields.componentName, AppName: tt.fields.appName, }, diff --git a/pkg/devfile/adapters/kubernetes/component/commandhandler.go b/pkg/devfile/adapters/kubernetes/component/commandhandler.go index 63faaf6199a..39dc5dfbf7e 100644 --- a/pkg/devfile/adapters/kubernetes/component/commandhandler.go +++ b/pkg/devfile/adapters/kubernetes/component/commandhandler.go @@ -9,7 +9,7 @@ import ( "k8s.io/klog" "github.com/redhat-developer/odo/pkg/component" - "github.com/redhat-developer/odo/pkg/devfile/adapters/common" + "github.com/redhat-developer/odo/pkg/devfile/adapters" "github.com/redhat-developer/odo/pkg/libdevfile" "github.com/redhat-developer/odo/pkg/log" "github.com/redhat-developer/odo/pkg/remotecmd" @@ -22,12 +22,12 @@ const numberOfLinesToOutputLog = 100 type adapterHandler struct { Adapter - parameters common.PushParameters + parameters adapters.PushParameters componentExists bool } var _ libdevfile.Handler = (*adapterHandler)(nil) -var _ common.ComponentAdapter = (*adapterHandler)(nil) +var _ ComponentAdapter = (*adapterHandler)(nil) var _ sync.SyncClient = (*adapterHandler)(nil) func (a *adapterHandler) ApplyImage(_ devfilev1.Component) error { diff --git a/pkg/devfile/adapters/kubernetes/component/interface.go b/pkg/devfile/adapters/kubernetes/component/interface.go new file mode 100644 index 00000000000..c52044b12d4 --- /dev/null +++ b/pkg/devfile/adapters/kubernetes/component/interface.go @@ -0,0 +1,8 @@ +package component + +import "github.com/redhat-developer/odo/pkg/devfile/adapters" + +// ComponentAdapter defines the functions that platform-specific adapters must implement +type ComponentAdapter interface { + Push(parameters adapters.PushParameters) error +} diff --git a/pkg/devfile/adapters/kubernetes/utils/utils.go b/pkg/devfile/adapters/kubernetes/utils/utils.go index 56c1c872755..f05d93fd792 100644 --- a/pkg/devfile/adapters/kubernetes/utils/utils.go +++ b/pkg/devfile/adapters/kubernetes/utils/utils.go @@ -9,11 +9,18 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/klog" - adaptersCommon "github.com/redhat-developer/odo/pkg/devfile/adapters/common" "github.com/redhat-developer/odo/pkg/libdevfile" "github.com/redhat-developer/odo/pkg/storage" ) +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 func GetOdoContainerVolumes(sourcePVCName string) []corev1.Volume { var sourceVolume corev1.Volume @@ -64,7 +71,7 @@ func AddOdoProjectVolume(containers *[]corev1.Container) { } for i, container := range *containers { for _, env := range container.Env { - if env.Name == adaptersCommon.EnvProjectsRoot { + if env.Name == _envProjectsRoot { container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{ Name: storage.OdoSourceVolume, MountPath: env.Value, @@ -172,11 +179,11 @@ func UpdateContainerEnvVars( // Check if the container belongs to a debug command component for _, c := range debugContainers { - if container.Name == c && !isEnvPresent(container.Env, adaptersCommon.EnvDebugPort) { + 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: adaptersCommon.EnvDebugPort, + Name: _envDebugPort, Value: strconv.Itoa(devfileDebugPort), }) break diff --git a/pkg/devfile/adapters/kubernetes/utils/utils_test.go b/pkg/devfile/adapters/kubernetes/utils/utils_test.go index f0e5b2e574a..fc3119db8ea 100644 --- a/pkg/devfile/adapters/kubernetes/utils/utils_test.go +++ b/pkg/devfile/adapters/kubernetes/utils/utils_test.go @@ -16,7 +16,6 @@ import ( devfileParser "github.com/devfile/library/pkg/devfile/parser" appsv1 "k8s.io/api/apps/v1" - adaptersCommon "github.com/redhat-developer/odo/pkg/devfile/adapters/common" "github.com/redhat-developer/odo/pkg/kclient" odoTestingUtil "github.com/redhat-developer/odo/pkg/testingutil" @@ -120,7 +119,7 @@ func TestAddOdoProjectVolume(t *testing.T) { Name: "container1", Env: []corev1.EnvVar{ { - Name: adaptersCommon.EnvProjectsRoot, + Name: _envProjectsRoot, Value: "/path1", }, }, @@ -129,7 +128,7 @@ func TestAddOdoProjectVolume(t *testing.T) { Name: "container2", Env: []corev1.EnvVar{ { - Name: adaptersCommon.EnvProjectsRoot, + Name: _envProjectsRoot, Value: "/path2", }, }, @@ -860,7 +859,7 @@ func TestUpdateContainerEnvVars(t *testing.T) { for _, envVar := range container.Env { // if the debug command is also present if len(tt.execCommands) >= 2 { - if envVar.Name == adaptersCommon.EnvDebugPort { + if envVar.Name == _envDebugPort { // check if the debug command's debugPort env was set properly envDebugPortMatched = true } @@ -876,7 +875,7 @@ func TestUpdateContainerEnvVars(t *testing.T) { if len(tt.execCommands) >= 2 && !envDebugPortMatched { t.Errorf("TestUpdateContainerEnvVars error: missing env var %s in container %q", - adaptersCommon.EnvDebugPort, cmp) + _envDebugPort, cmp) } }) } diff --git a/pkg/devfile/adapters/common/types.go b/pkg/devfile/adapters/types.go similarity index 74% rename from pkg/devfile/adapters/common/types.go rename to pkg/devfile/adapters/types.go index d3bfb08a34b..c183a3412a9 100644 --- a/pkg/devfile/adapters/common/types.go +++ b/pkg/devfile/adapters/types.go @@ -1,20 +1,9 @@ -package common +package adapters import ( - devfilev1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" - devfileParser "github.com/devfile/library/pkg/devfile/parser" - "github.com/redhat-developer/odo/pkg/envinfo" ) -// AdapterContext is a construct that is common to all adapters -type AdapterContext struct { - ComponentName string // ComponentName is the odo component name, it is NOT related to any devfile components - Context string // Context is the given directory containing the source code and configs - AppName string // the application name associated to a component - Devfile devfileParser.DevfileObj // Devfile is the object returned by the Devfile parser -} - // PushParameters is a struct containing the parameters to be used when pushing to a devfile component type PushParameters struct { Path string // Path refers to the parent folder containing the source code to push up to a component @@ -52,11 +41,3 @@ type ComponentInfo struct { func (ci ComponentInfo) IsEmpty() bool { return len(ci.ContainerName) == 0 } - -// PushCommandsMap stores the commands to be executed as per their types. -type PushCommandsMap map[devfilev1.CommandGroupKind]devfilev1.Command - -// NewPushCommandMap returns the instance of PushCommandsMap -func NewPushCommandMap() PushCommandsMap { - return make(map[devfilev1.CommandGroupKind]devfilev1.Command) -} diff --git a/pkg/devfile/validate/validate.go b/pkg/devfile/validate/validate.go index 8c62034f514..df75170e54c 100644 --- a/pkg/devfile/validate/validate.go +++ b/pkg/devfile/validate/validate.go @@ -2,9 +2,9 @@ package validate import ( "fmt" + "strings" - "github.com/redhat-developer/odo/pkg/devfile/adapters/common" - + devfilev1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" v2 "github.com/devfile/library/pkg/devfile/parser/data/v2" parsercommon "github.com/devfile/library/pkg/devfile/parser/data/v2/common" "k8s.io/klog" @@ -25,7 +25,7 @@ func ValidateDevfileData(data interface{}) error { return err } - commandsMap := common.GetCommandsMap(commands) + commandsMap := getCommandsMap(commands) // Validate all the devfile components before validating commands if err := validateComponents(components); err != nil { @@ -46,3 +46,13 @@ func ValidateDevfileData(data interface{}) error { return nil } + +// getCommandsMap returns a map of the command Id to the command +func getCommandsMap(commands []devfilev1.Command) map[string]devfilev1.Command { + commandMap := make(map[string]devfilev1.Command, len(commands)) + for _, command := range commands { + command.Id = strings.ToLower(command.Id) + commandMap[command.Id] = command + } + return commandMap +} diff --git a/pkg/devfile/adapters/common/utils_test.go b/pkg/devfile/validate/validate_test.go similarity index 97% rename from pkg/devfile/adapters/common/utils_test.go rename to pkg/devfile/validate/validate_test.go index 0b37178f19c..35e3a1dbb3f 100644 --- a/pkg/devfile/adapters/common/utils_test.go +++ b/pkg/devfile/validate/validate_test.go @@ -1,4 +1,4 @@ -package common +package validate import ( "testing" @@ -13,7 +13,7 @@ import ( "github.com/redhat-developer/odo/pkg/util" ) -func TestGetCommands(t *testing.T) { +func Test_getCommands(t *testing.T) { component := []devfilev1.Component{ testingutil.GetFakeContainerComponent("alias1"), @@ -135,7 +135,7 @@ func TestGetCommands(t *testing.T) { t.Errorf("unexpected error: %v", err) } - commandsMap := GetCommandsMap(commands) + commandsMap := getCommandsMap(commands) if len(commandsMap) != len(tt.expectedCommands) { t.Errorf("TestGetCommands error: number of returned commands don't match: %v got: %v", len(tt.expectedCommands), len(commandsMap)) } diff --git a/pkg/odo/cli/dev/dev.go b/pkg/odo/cli/dev/dev.go index ad74a301282..f52d6f3743a 100644 --- a/pkg/odo/cli/dev/dev.go +++ b/pkg/odo/cli/dev/dev.go @@ -17,8 +17,7 @@ import ( "github.com/redhat-developer/odo/pkg/dev" ododevfile "github.com/redhat-developer/odo/pkg/devfile" "github.com/redhat-developer/odo/pkg/devfile/adapters" - "github.com/redhat-developer/odo/pkg/devfile/adapters/common" - "github.com/redhat-developer/odo/pkg/devfile/adapters/kubernetes" + 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" @@ -202,10 +201,7 @@ func (o *DevOptions) Validate() error { func (o *DevOptions) Run(ctx context.Context) (err error) { var ( - devFileObj = o.Context.EnvSpecificInfo.GetDevfileObj() - platformContext = kubernetes.KubernetesContext{ - Namespace: o.Context.GetProject(), - } + devFileObj = o.Context.EnvSpecificInfo.GetDevfileObj() path = filepath.Dir(o.Context.EnvSpecificInfo.GetDevfilePath()) devfileName = devFileObj.GetMetadataName() namespace = o.GetProject() @@ -223,7 +219,7 @@ func (o *DevOptions) Run(ctx context.Context) (err error) { "odo version: "+version.VERSION) log.Section("Deploying to the cluster in developer mode") - err = o.clientset.DevClient.Start(devFileObj, platformContext, o.ignorePaths, path, o.debugFlag, o.buildCommandFlag, o.runCommandFlag, o.randomPortsFlag, o.errOut) + err = o.clientset.DevClient.Start(devFileObj, namespace, o.ignorePaths, path, o.debugFlag, o.buildCommandFlag, o.runCommandFlag, o.randomPortsFlag, o.errOut) if err != nil { return err } @@ -251,8 +247,8 @@ func (o *DevOptions) Run(ctx context.Context) (err error) { } // RegenerateAdapterAndPush regenerates the adapter and pushes the files to remote pod -func (o *Handler) RegenerateAdapterAndPush(pushParams common.PushParameters, watchParams watch.WatchParameters) error { - var adapter common.ComponentAdapter +func (o *Handler) RegenerateAdapterAndPush(pushParams adapters.PushParameters, watchParams watch.WatchParameters) error { + var adapter kcomponent.ComponentAdapter adapter, err := o.regenerateComponentAdapterFromWatchParams(watchParams) if err != nil { @@ -267,28 +263,26 @@ func (o *Handler) RegenerateAdapterAndPush(pushParams common.PushParameters, wat return nil } -func (o *Handler) regenerateComponentAdapterFromWatchParams(parameters watch.WatchParameters) (common.ComponentAdapter, error) { +func (o *Handler) regenerateComponentAdapterFromWatchParams(parameters watch.WatchParameters) (kcomponent.ComponentAdapter, error) { devObj, err := ododevfile.ParseAndValidateFromFileWithVariables(location.DevfileLocation(""), parameters.Variables) if err != nil { return nil, err } - platformContext := kubernetes.KubernetesContext{ - Namespace: parameters.EnvSpecificInfo.GetNamespace(), - } - - return adapters.NewComponentAdapter( + return kcomponent.NewKubernetesAdapter( o.clientset.KubernetesClient, o.clientset.PreferenceClient, o.clientset.PortForwardClient, - parameters.ComponentName, - parameters.Path, - parameters.ApplicationName, - devObj, - platformContext, + kcomponent.AdapterContext{ + ComponentName: parameters.ComponentName, + Context: parameters.Path, + AppName: parameters.ApplicationName, + Devfile: devObj, + }, + parameters.EnvSpecificInfo.GetNamespace(), o.randomPorts, o.errOut, - ) + ), nil } func (o *DevOptions) HandleSignal() error { diff --git a/pkg/sync/adapter.go b/pkg/sync/adapter.go index 8f3e782e12d..32c756fe187 100644 --- a/pkg/sync/adapter.go +++ b/pkg/sync/adapter.go @@ -9,7 +9,7 @@ import ( "github.com/devfile/library/pkg/devfile/generator" dfutil "github.com/devfile/library/pkg/util" - "github.com/redhat-developer/odo/pkg/devfile/adapters/common" + "github.com/redhat-developer/odo/pkg/devfile/adapters" "github.com/redhat-developer/odo/pkg/kclient" "github.com/redhat-developer/odo/pkg/remotecmd" "github.com/redhat-developer/odo/pkg/util" @@ -18,19 +18,19 @@ import ( ) // New instantiates a component adapter -func New(adapterContext common.AdapterContext, syncClient SyncClient, kubeClient kclient.ClientInterface) Adapter { +func New(syncClient SyncClient, kubeClient kclient.ClientInterface, componentName string) Adapter { return Adapter{ - kubeClient: kubeClient, - SyncClient: syncClient, - AdapterContext: adapterContext, + kubeClient: kubeClient, + SyncClient: syncClient, + ComponentName: componentName, } } // Adapter is a component adapter implementation for sync type Adapter struct { - kubeClient kclient.ClientInterface - SyncClient SyncClient - common.AdapterContext + kubeClient kclient.ClientInterface + SyncClient SyncClient + ComponentName string } // SyncFiles does a couple of things: @@ -38,7 +38,7 @@ type Adapter struct { // otherwise, it checks which files have changed and syncs the delta // it returns a boolean execRequired and an error. execRequired tells us if files have // changed and devfile execution is required -func (a Adapter) SyncFiles(syncParameters common.SyncParameters) (bool, error) { +func (a Adapter) SyncFiles(syncParameters adapters.SyncParameters) (bool, error) { // Whether to write the indexer content to the index file path (resolvePath) forceWrite := false @@ -169,7 +169,7 @@ func (a Adapter) SyncFiles(syncParameters common.SyncParameters) (bool, error) { } // pushLocal syncs source code from the user's disk to the component -func (a Adapter) pushLocal(path string, files []string, delFiles []string, isForcePush bool, globExps []string, compInfo common.ComponentInfo, ret util.IndexerRet) error { +func (a Adapter) pushLocal(path string, files []string, delFiles []string, isForcePush bool, globExps []string, compInfo adapters.ComponentInfo, ret util.IndexerRet) error { klog.V(4).Infof("Push: componentName: %s, path: %s, files: %s, delFiles: %s, isForcePush: %+v", a.ComponentName, path, files, delFiles, isForcePush) // Edge case: check to see that the path is NOT empty. @@ -222,7 +222,7 @@ func (a Adapter) pushLocal(path string, files []string, delFiles []string, isFor // updateIndexWithWatchChanges uses the pushParameters.WatchDeletedFiles and pushParamters.WatchFiles to update // the existing index file; the index file is required to exist when this function is called. -func updateIndexWithWatchChanges(pushParameters common.PushParameters) error { +func updateIndexWithWatchChanges(pushParameters adapters.PushParameters) error { indexFilePath, err := util.ResolveIndexFilePath(pushParameters.Path) if err != nil { diff --git a/pkg/sync/adapter_test.go b/pkg/sync/adapter_test.go index 0492dc8514c..a1ad6f0be70 100644 --- a/pkg/sync/adapter_test.go +++ b/pkg/sync/adapter_test.go @@ -8,14 +8,10 @@ import ( "reflect" "testing" - "github.com/devfile/library/pkg/devfile/parser/data" - - devfilev1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" "github.com/devfile/library/pkg/devfile/generator" - "github.com/devfile/library/pkg/devfile/parser" "github.com/golang/mock/gomock" - "github.com/redhat-developer/odo/pkg/devfile/adapters/common" + "github.com/redhat-developer/odo/pkg/devfile/adapters" "github.com/redhat-developer/odo/pkg/kclient" "github.com/redhat-developer/odo/pkg/sync/mock" "github.com/redhat-developer/odo/pkg/util" @@ -115,22 +111,22 @@ func TestSyncFiles(t *testing.T) { tests := []struct { name string client SyncClient - syncParameters common.SyncParameters + syncParameters adapters.SyncParameters wantErr bool wantIsPushRequired bool }{ { name: "Case 1: Component does not exist", client: syncClient, - syncParameters: common.SyncParameters{ - PushParams: common.PushParameters{ + syncParameters: adapters.SyncParameters{ + PushParams: adapters.PushParameters{ Path: directory, WatchFiles: []string{}, WatchDeletedFiles: []string{}, IgnoredFiles: []string{}, ForceBuild: false, }, - CompInfo: common.ComponentInfo{ + CompInfo: adapters.ComponentInfo{ ContainerName: "abcd", }, ComponentExists: false, @@ -141,15 +137,15 @@ func TestSyncFiles(t *testing.T) { { name: "Case 2: Component does exist", client: syncClient, - syncParameters: common.SyncParameters{ - PushParams: common.PushParameters{ + syncParameters: adapters.SyncParameters{ + PushParams: adapters.PushParameters{ Path: directory, WatchFiles: []string{}, WatchDeletedFiles: []string{}, IgnoredFiles: []string{}, ForceBuild: false, }, - CompInfo: common.ComponentInfo{ + CompInfo: adapters.ComponentInfo{ ContainerName: "abcd", }, ComponentExists: true, @@ -160,15 +156,15 @@ func TestSyncFiles(t *testing.T) { { name: "Case 3: FakeErrorClient error", client: errorSyncClient, - syncParameters: common.SyncParameters{ - PushParams: common.PushParameters{ + syncParameters: adapters.SyncParameters{ + PushParams: adapters.PushParameters{ Path: directory, WatchFiles: []string{}, WatchDeletedFiles: []string{}, IgnoredFiles: []string{}, ForceBuild: true, }, - CompInfo: common.ComponentInfo{ + CompInfo: adapters.ComponentInfo{ ContainerName: "abcd", }, ComponentExists: true, @@ -179,15 +175,15 @@ func TestSyncFiles(t *testing.T) { { name: "Case 4: File change", client: syncClient, - syncParameters: common.SyncParameters{ - PushParams: common.PushParameters{ + syncParameters: adapters.SyncParameters{ + PushParams: adapters.PushParameters{ Path: directory, WatchFiles: []string{path.Join(directory, "test.log")}, WatchDeletedFiles: []string{}, IgnoredFiles: []string{}, ForceBuild: false, }, - CompInfo: common.ComponentInfo{ + CompInfo: adapters.ComponentInfo{ ContainerName: "abcd", }, ComponentExists: true, @@ -198,26 +194,7 @@ func TestSyncFiles(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - devObj := parser.DevfileObj{ - Data: func() data.DevfileData { - devfileData, err := data.NewDevfileData(string(data.APISchemaVersion200)) - if err != nil { - t.Error(err) - } - err = devfileData.AddComponents([]devfilev1.Component{}) - if err != nil { - t.Error(err) - } - return devfileData - }(), - } - - adapterCtx := common.AdapterContext{ - ComponentName: testComponentName, - Devfile: devObj, - } - - syncAdapter := New(adapterCtx, tt.client, kc) + syncAdapter := New(tt.client, kc, testComponentName) isPushRequired, err := syncAdapter.SyncFiles(tt.syncParameters) if !tt.wantErr && err != nil { t.Errorf("TestSyncFiles error: unexpected error when syncing files %v", err) @@ -274,7 +251,7 @@ func TestPushLocal(t *testing.T) { files []string delFiles []string isForcePush bool - compInfo common.ComponentInfo + compInfo adapters.ComponentInfo wantErr bool }{ { @@ -284,7 +261,7 @@ func TestPushLocal(t *testing.T) { files: []string{path.Join(directory, "test.log")}, delFiles: []string{}, isForcePush: false, - compInfo: common.ComponentInfo{ + compInfo: adapters.ComponentInfo{ ContainerName: "abcd", }, wantErr: false, @@ -296,7 +273,7 @@ func TestPushLocal(t *testing.T) { files: []string{path.Join(directory, "test.log")}, delFiles: []string{}, isForcePush: false, - compInfo: common.ComponentInfo{ + compInfo: adapters.ComponentInfo{ ContainerName: "abcd", }, wantErr: true, @@ -308,7 +285,7 @@ func TestPushLocal(t *testing.T) { files: []string{}, delFiles: []string{}, isForcePush: false, - compInfo: common.ComponentInfo{ + compInfo: adapters.ComponentInfo{ ContainerName: "abcd", }, wantErr: false, @@ -320,7 +297,7 @@ func TestPushLocal(t *testing.T) { files: []string{}, delFiles: []string{path.Join(directory, "test.log")}, isForcePush: false, - compInfo: common.ComponentInfo{ + compInfo: adapters.ComponentInfo{ ContainerName: "abcd", }, wantErr: false, @@ -332,7 +309,7 @@ func TestPushLocal(t *testing.T) { files: []string{}, delFiles: []string{}, isForcePush: true, - compInfo: common.ComponentInfo{ + compInfo: adapters.ComponentInfo{ ContainerName: "abcd", }, wantErr: false, @@ -344,7 +321,7 @@ func TestPushLocal(t *testing.T) { files: []string{}, delFiles: []string{}, isForcePush: false, - compInfo: common.ComponentInfo{ + compInfo: adapters.ComponentInfo{ ContainerName: "abcd", SyncFolder: "/some/path", }, @@ -353,26 +330,7 @@ func TestPushLocal(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - devObj := parser.DevfileObj{ - Data: func() data.DevfileData { - devfileData, err := data.NewDevfileData(string(data.APISchemaVersion200)) - if err != nil { - t.Error(err) - } - err = devfileData.AddComponents([]devfilev1.Component{}) - if err != nil { - t.Error(err) - } - return devfileData - }(), - } - - adapterCtx := common.AdapterContext{ - ComponentName: testComponentName, - Devfile: devObj, - } - - syncAdapter := New(adapterCtx, syncClient, kc) + syncAdapter := New(syncClient, kc, testComponentName) err := syncAdapter.pushLocal(tt.path, tt.files, tt.delFiles, tt.isForcePush, []string{}, tt.compInfo, util.IndexerRet{}) if !tt.wantErr && err != nil { t.Errorf("TestPushLocal error: error pushing files: %v", err) @@ -456,7 +414,7 @@ func TestUpdateIndexWithWatchChanges(t *testing.T) { t.Fatalf("TestUpdateIndexWithWatchChangesLocal error: unable to write index file: %v", err) } - pushParams := common.PushParameters{ + pushParams := adapters.PushParameters{ Path: directory, } diff --git a/pkg/sync/mock/sync.go b/pkg/sync/mock/sync.go index 61e4e0fc670..88a6b5f4c9a 100644 --- a/pkg/sync/mock/sync.go +++ b/pkg/sync/mock/sync.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: sync.go +// Source: pkg/sync/sync.go // Package mock is a generated GoMock package. package mock @@ -9,41 +9,41 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - common "github.com/redhat-developer/odo/pkg/devfile/adapters/common" + adapters "github.com/redhat-developer/odo/pkg/devfile/adapters" ) -// MockSyncClient is a mock of SyncClient interface +// MockSyncClient is a mock of SyncClient interface. type MockSyncClient struct { ctrl *gomock.Controller recorder *MockSyncClientMockRecorder } -// MockSyncClientMockRecorder is the mock recorder for MockSyncClient +// MockSyncClientMockRecorder is the mock recorder for MockSyncClient. type MockSyncClientMockRecorder struct { mock *MockSyncClient } -// NewMockSyncClient creates a new mock instance +// NewMockSyncClient creates a new mock instance. func NewMockSyncClient(ctrl *gomock.Controller) *MockSyncClient { mock := &MockSyncClient{ctrl: ctrl} mock.recorder = &MockSyncClientMockRecorder{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 *MockSyncClient) EXPECT() *MockSyncClientMockRecorder { return m.recorder } -// ExtractProjectToComponent mocks base method -func (m *MockSyncClient) ExtractProjectToComponent(arg0 common.ComponentInfo, arg1 string, arg2 io.Reader) error { +// ExtractProjectToComponent mocks base method. +func (m *MockSyncClient) ExtractProjectToComponent(arg0 adapters.ComponentInfo, arg1 string, arg2 io.Reader) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ExtractProjectToComponent", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } -// ExtractProjectToComponent indicates an expected call of ExtractProjectToComponent +// ExtractProjectToComponent indicates an expected call of ExtractProjectToComponent. func (mr *MockSyncClientMockRecorder) ExtractProjectToComponent(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExtractProjectToComponent", reflect.TypeOf((*MockSyncClient)(nil).ExtractProjectToComponent), arg0, arg1, arg2) diff --git a/pkg/sync/sync.go b/pkg/sync/sync.go index 86692842cf9..f60ebb2a8a8 100644 --- a/pkg/sync/sync.go +++ b/pkg/sync/sync.go @@ -7,7 +7,7 @@ import ( "os" "path/filepath" - "github.com/redhat-developer/odo/pkg/devfile/adapters/common" + "github.com/redhat-developer/odo/pkg/devfile/adapters" "github.com/redhat-developer/odo/pkg/log" "github.com/redhat-developer/odo/pkg/testingutil/filesystem" "github.com/redhat-developer/odo/pkg/util" @@ -19,7 +19,7 @@ import ( ) type SyncClient interface { - ExtractProjectToComponent(common.ComponentInfo, string, io.Reader) error + ExtractProjectToComponent(adapters.ComponentInfo, string, io.Reader) error } // CopyFile copies localPath directory or list of files in copyFiles list to the directory in running Pod. @@ -27,7 +27,7 @@ type SyncClient interface { // During copying binary components, localPath represent base directory path to binary and copyFiles contains path of binary // During copying local source components, localPath represent base directory path whereas copyFiles is empty // During `odo watch`, localPath represent base directory path whereas copyFiles contains list of changed Files -func CopyFile(client SyncClient, localPath string, compInfo common.ComponentInfo, targetPath string, copyFiles []string, globExps []string, ret util.IndexerRet) error { +func CopyFile(client SyncClient, localPath string, compInfo adapters.ComponentInfo, targetPath string, copyFiles []string, globExps []string, ret util.IndexerRet) error { // Destination is set to "ToSlash" as all containers being ran within OpenShift / S2I are all // Linux based and thus: "\opt\app-root\src" would not work correctly. diff --git a/pkg/watch/watch.go b/pkg/watch/watch.go index c8584f90e89..04726f7156a 100644 --- a/pkg/watch/watch.go +++ b/pkg/watch/watch.go @@ -10,13 +10,13 @@ import ( "github.com/devfile/library/pkg/devfile/parser" _delete "github.com/redhat-developer/odo/pkg/component/delete" + "github.com/redhat-developer/odo/pkg/devfile/adapters" "github.com/redhat-developer/odo/pkg/labels" "github.com/redhat-developer/odo/pkg/state" "github.com/fsnotify/fsnotify" gitignore "github.com/sabhiram/go-gitignore" - "github.com/redhat-developer/odo/pkg/devfile/adapters/common" "github.com/redhat-developer/odo/pkg/envinfo" "github.com/redhat-developer/odo/pkg/log" "github.com/redhat-developer/odo/pkg/util" @@ -59,7 +59,7 @@ type WatchParameters struct { // Custom function that can be used to push detected changes to remote pod. For more info about what each of the parameters to this function, please refer, pkg/component/component.go#PushLocal // WatchHandler func(kclient.ClientInterface, string, string, string, io.Writer, []string, []string, bool, []string, bool) error // Custom function that can be used to push detected changes to remote devfile pod. For more info about what each of the parameters to this function, please refer, pkg/devfile/adapters/interface.go#PlatformAdapter - DevfileWatchHandler func(common.PushParameters, WatchParameters) error + DevfileWatchHandler func(adapters.PushParameters, WatchParameters) error // Parameter whether or not to show build logs Show bool // EnvSpecificInfo contains information of env.yaml file @@ -338,7 +338,7 @@ func processEvents(changedFiles, deletedPaths []string, parameters WatchParamete fmt.Fprintf(out, "Pushing files...\n\n") klog.V(4).Infof("Copying files %s to pod", changedFiles) - pushParams := common.PushParameters{ + pushParams := adapters.PushParameters{ Path: parameters.Path, WatchFiles: changedFiles, WatchDeletedFiles: deletedPaths, diff --git a/scripts/mockgen.sh b/scripts/mockgen.sh index 8ac34d007c3..dec60898e4e 100755 --- a/scripts/mockgen.sh +++ b/scripts/mockgen.sh @@ -82,3 +82,8 @@ mockgen -source=pkg/binding/interface.go \ mockgen -source=pkg/binding/backend/interface.go \ -package backend \ -destination pkg/binding/backend/mock.go + + +mockgen -source=pkg/sync/sync.go \ + -package mock \ + -destination pkg/sync/mock/sync.go