diff --git a/ee/config/feature_flags/beta/allow_extensions_marketplace_in_workspace.yml b/ee/config/feature_flags/beta/allow_extensions_marketplace_in_workspace.yml new file mode 100644 index 0000000000000000000000000000000000000000..65df964c1dc32d7edd190b7d9e8fac30d91e1959 --- /dev/null +++ b/ee/config/feature_flags/beta/allow_extensions_marketplace_in_workspace.yml @@ -0,0 +1,9 @@ +--- +name: allow_extensions_marketplace_in_workspace +feature_issue_url: https://gitlab.com/groups/gitlab-org/-/epics/12443 +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/142001 +rollout_issue_url: https://gitlab.com/gitlab-com/gl-infra/production/-/issues/17418 +milestone: '16.9' +group: group::ide +type: beta +default_enabled: false diff --git a/ee/lib/remote_development/workspaces/create/editor_component_injector.rb b/ee/lib/remote_development/workspaces/create/editor_component_injector.rb index bd2517266e29f41d76490c26127471a9cdbba06e..937bc743644ca54bd04357bd9b83d3ce5732d243 100644 --- a/ee/lib/remote_development/workspaces/create/editor_component_injector.rb +++ b/ee/lib/remote_development/workspaces/create/editor_component_injector.rb @@ -12,7 +12,7 @@ def self.inject(value) value => { processed_devfile: Hash => processed_devfile, volume_mounts: Hash => volume_mounts, - # params: Hash => params # NOTE: Params is currently unused until we use the editor entry + params: Hash => params } volume_mounts => { data_volume: Hash => data_volume } data_volume => { @@ -20,15 +20,31 @@ def self.inject(value) path: String => volume_path, } - # NOTE: Editor is currently unused - # editor = params[:editor] + params => { + agent: Clusters::Agent => agent + } editor_port = 60001 ssh_port = 60022 + enable_marketplace = Feature.enabled?( + :allow_extensions_marketplace_in_workspace, + agent.project.root_namespace, + type: :beta + ) - editor_component = processed_devfile['components'].find { |c| c.dig('attributes', 'gl/inject-editor') } - override_main_container(editor_component, volume_name, volume_path, editor_port, ssh_port) if editor_component inject_editor_component(processed_devfile, volume_name, volume_path) + editor_component = processed_devfile['components'].find { |c| c.dig('attributes', 'gl/inject-editor') } + + if editor_component + override_main_container( + editor_component, + volume_name, + volume_path, + editor_port, + ssh_port, + enable_marketplace + ) + end value end @@ -38,8 +54,9 @@ def self.inject(value) # @param [String] volume_path # @param [Integer] editor_port # @param [Integer] ssh_port + # @param [Boolean] enable_marketplace # @return [Hash] - def self.override_main_container(component, volume_name, volume_path, editor_port, ssh_port) + def self.override_main_container(component, volume_name, volume_path, editor_port, ssh_port, enable_marketplace) # This overrides the main container's command # Open issue to support both starting the editor and running the default command: # https://gitlab.com/gitlab-org/gitlab/-/issues/392853 @@ -78,6 +95,10 @@ def self.override_main_container(component, volume_name, volume_path, editor_por { 'name' => 'GL_SSH_PORT', 'value' => ssh_port.to_s + }, + { + 'name' => 'GL_EDITOR_ENABLE_MARKETPLACE', + 'value' => enable_marketplace.to_s } ] @@ -127,7 +148,7 @@ def self.inject_editor_component(processed_devfile, volume_name, volume_path) def self.editor_components(volume_name, volume_path) # TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/409775 - choose image based on which editor is passed. image_name = 'registry.gitlab.com/gitlab-org/gitlab-web-ide-vscode-fork/web-ide-injector' - image_tag = '5' + image_tag = '6' [ { diff --git a/ee/spec/fixtures/remote_development/example.processed-devfile-v2.yaml b/ee/spec/fixtures/remote_development/example.processed-devfile-v2.yaml index 7c9d5684eac056013bccd7433fd08208a512d59e..34ae035025a7b4d1f6420f14fc1352103d39e82e 100644 --- a/ee/spec/fixtures/remote_development/example.processed-devfile-v2.yaml +++ b/ee/spec/fixtures/remote_development/example.processed-devfile-v2.yaml @@ -32,6 +32,8 @@ components: value: "60001" - name: GL_SSH_PORT value: "60022" + - name: GL_EDITOR_ENABLE_MARKETPLACE + value: "true" endpoints: - name: editor-server targetPort: 60001 @@ -49,7 +51,7 @@ components: size: 15Gi - name: gl-editor-injector container: - image: registry.gitlab.com/gitlab-org/gitlab-web-ide-vscode-fork/web-ide-injector:5 + image: registry.gitlab.com/gitlab-org/gitlab-web-ide-vscode-fork/web-ide-injector:6 volumeMounts: - name: gl-workspace-data path: /projects diff --git a/ee/spec/fixtures/remote_development/example.processed-devfile.yaml b/ee/spec/fixtures/remote_development/example.processed-devfile.yaml index 7c9d5684eac056013bccd7433fd08208a512d59e..34ae035025a7b4d1f6420f14fc1352103d39e82e 100644 --- a/ee/spec/fixtures/remote_development/example.processed-devfile.yaml +++ b/ee/spec/fixtures/remote_development/example.processed-devfile.yaml @@ -32,6 +32,8 @@ components: value: "60001" - name: GL_SSH_PORT value: "60022" + - name: GL_EDITOR_ENABLE_MARKETPLACE + value: "true" endpoints: - name: editor-server targetPort: 60001 @@ -49,7 +51,7 @@ components: size: 15Gi - name: gl-editor-injector container: - image: registry.gitlab.com/gitlab-org/gitlab-web-ide-vscode-fork/web-ide-injector:5 + image: registry.gitlab.com/gitlab-org/gitlab-web-ide-vscode-fork/web-ide-injector:6 volumeMounts: - name: gl-workspace-data path: /projects diff --git a/ee/spec/fixtures/remote_development/example.processed-marketplace-disabled-devfile.yaml b/ee/spec/fixtures/remote_development/example.processed-marketplace-disabled-devfile.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0797452bfb5ac6ced23940a0073b0d50a4fd883e --- /dev/null +++ b/ee/spec/fixtures/remote_development/example.processed-marketplace-disabled-devfile.yaml @@ -0,0 +1,94 @@ +--- +schemaVersion: 2.2.0 +metadata: {} +components: + - name: tooling-container + attributes: + gl/inject-editor: true + container: + image: quay.io/mloriedo/universal-developer-image:ubi8-dw-demo + args: + - |- + sshd_path=$(which sshd) + if [ -x "$sshd_path" ]; then + echo "Starting sshd on port ${GL_SSH_PORT}" + $sshd_path -D -p $GL_SSH_PORT & + else + echo "'sshd' not found in path. Not starting SSH server." + fi + /projects/.gl-editor/start_server.sh + command: + - "/bin/sh" + - "-c" + volumeMounts: + - name: gl-workspace-data + path: /projects + env: + - name: GL_EDITOR_VOLUME_DIR + value: "/projects/.gl-editor" + - name: GL_EDITOR_LOG_LEVEL + value: "info" + - name: GL_EDITOR_PORT + value: "60001" + - name: GL_SSH_PORT + value: "60022" + - name: GL_EDITOR_ENABLE_MARKETPLACE + value: "false" + endpoints: + - name: editor-server + targetPort: 60001 + exposure: public + secure: true + protocol: https + - name: ssh-server + targetPort: 60022 + exposure: internal + secure: true + dedicatedPod: false + mountSources: true + - name: gl-workspace-data + volume: + size: 15Gi + - name: gl-editor-injector + container: + image: registry.gitlab.com/gitlab-org/gitlab-web-ide-vscode-fork/web-ide-injector:6 + volumeMounts: + - name: gl-workspace-data + path: /projects + env: + - name: GL_EDITOR_VOLUME_DIR + value: "/projects/.gl-editor" + memoryLimit: 256Mi + memoryRequest: 128Mi + cpuLimit: 500m + cpuRequest: 100m + - name: gl-cloner-injector + container: + image: alpine/git:2.36.3 + volumeMounts: + - name: gl-workspace-data + path: "/projects" + args: + - |- + if [ ! -d '/projects/test-project' ]; + then + git clone --branch master http://localhost/test-group/test-project.git /projects/test-project; + fi + command: + - "/bin/sh" + - "-c" + memoryLimit: 256Mi + memoryRequest: 128Mi + cpuLimit: 500m + cpuRequest: 100m +events: + preStart: + - gl-editor-injector-command + - gl-cloner-injector-command +commands: + - id: gl-editor-injector-command + apply: + component: gl-editor-injector + - id: gl-cloner-injector-command + apply: + component: gl-cloner-injector diff --git a/ee/spec/lib/remote_development/workspaces/create/editor_component_injector_spec.rb b/ee/spec/lib/remote_development/workspaces/create/editor_component_injector_spec.rb index 4789696632fc61034b8b286fe7160ed80f6ba725..230dda453b32dd9e4e4e21fdd5ac823c62e27c62 100644 --- a/ee/spec/lib/remote_development/workspaces/create/editor_component_injector_spec.rb +++ b/ee/spec/lib/remote_development/workspaces/create/editor_component_injector_spec.rb @@ -5,17 +5,18 @@ RSpec.describe RemoteDevelopment::Workspaces::Create::EditorComponentInjector, feature_category: :remote_development do include_context 'with remote development shared fixtures' + let(:agent) { create(:ee_cluster_agent, :with_remote_development_agent_config) } let(:flattened_devfile_name) { 'example.flattened-devfile.yaml' } - let(:processed_devfile) { YAML.safe_load(read_devfile(flattened_devfile_name)).to_h } - let(:expected_processed_devfile) { YAML.safe_load(example_processed_devfile) } - let(:component_name) { "gl-editor-injector" } - let(:volume_name) { "gl-workspace-data" } + let(:input_processed_devfile) { YAML.safe_load(read_devfile(flattened_devfile_name)).to_h } + let(:processed_devfile_name) { 'example.processed-devfile.yaml' } + let(:expected_processed_devfile) { YAML.safe_load(read_devfile(processed_devfile_name)).to_h } + let(:volume_name) { 'gl-workspace-data' } let(:value) do { params: { - editor: "editor" # NOTE: Currently unused + agent: agent }, - processed_devfile: processed_devfile, + processed_devfile: input_processed_devfile, volume_mounts: { data_volume: { name: volume_name, @@ -29,13 +30,30 @@ described_class.inject(value) end - it "injects the editor injector component" do - components = returned_value.dig(:processed_devfile, "components") - editor_injector_component = components.find { |component| component.fetch("name") == component_name } - processed_devfile_components = expected_processed_devfile.fetch("components") - expected_volume_component = processed_devfile_components.find do |component| - component.fetch("name") == component_name + shared_examples 'successful injection of editor components' do + it 'injects the editor injector component' do + components = returned_value.dig(:processed_devfile, 'components') + editor_component = components.find { |c| c.dig('attributes', 'gl/inject-editor') } + editor_injector_component = components.find { |c| c.fetch('name') == 'gl-editor-injector' } + relevant_components = [editor_component, editor_injector_component] + relevant_components_name = relevant_components.map { |c| c.fetch('name') } + processed_devfile_components = expected_processed_devfile.fetch('components') + expected_relevant_components = processed_devfile_components.select do |component| + relevant_components_name.include? component.fetch('name') + end + expect(relevant_components).to eq(expected_relevant_components) end - expect(editor_injector_component).to eq(expected_volume_component) + end + + it_behaves_like 'successful injection of editor components' + + context "when allow_extensions_marketplace_in_workspace is disabled" do + let(:processed_devfile_name) { 'example.processed-marketplace-disabled-devfile.yaml' } + + before do + stub_feature_flags(allow_extensions_marketplace_in_workspace: false) + end + + it_behaves_like 'successful injection of editor components' end end diff --git a/ee/spec/support/shared_contexts/remote_development/remote_development_shared_contexts.rb b/ee/spec/support/shared_contexts/remote_development/remote_development_shared_contexts.rb index 6b52e536a9880cf9f15e654da297a98107af4716..1c20489e5f04b47ca6a40fc76023aeeaec15d5af 100644 --- a/ee/spec/support/shared_contexts/remote_development/remote_development_shared_contexts.rb +++ b/ee/spec/support/shared_contexts/remote_development/remote_development_shared_contexts.rb @@ -618,6 +618,10 @@ def workspace_deployment( name: "GL_SSH_PORT", value: "60022" }, + { + name: "GL_EDITOR_ENABLE_MARKETPLACE", + value: "true" + }, { name: "PROJECTS_ROOT", value: "/projects" @@ -741,7 +745,7 @@ def workspace_deployment( value: "/projects" } ], - image: "registry.gitlab.com/gitlab-org/gitlab-web-ide-vscode-fork/web-ide-injector:5", + image: "registry.gitlab.com/gitlab-org/gitlab-web-ide-vscode-fork/web-ide-injector:6", imagePullPolicy: "Always", name: "gl-editor-injector-gl-editor-injector-command-2", resources: {