From 14d86bb468576124c2994ba086f5f10b8690fe87 Mon Sep 17 00:00:00 2001 From: Vishal Tak Date: Wed, 17 Jan 2024 09:19:28 +0530 Subject: [PATCH 1/2] Add config for enabling marketplace in workspace Use allow_extensions_marketplace_in_workspace feature flag at the root namespace of the agent project of the workspace to enable extensions inside the workspace. --- ...ow_extensions_marketplace_in_workspace.yml | 9 ++ .../create/editor_component_injector.rb | 35 +++++-- .../remote_development/workspaces_spec.rb | 1 + .../example.processed-devfile-v2.yaml | 4 +- .../example.processed-devfile.yaml | 4 +- ...processed-marketplace-enabled-devfile.yaml | 94 +++++++++++++++++++ .../create/editor_component_injector_spec.rb | 48 +++++++--- .../create/main_integration_spec.rb | 4 + .../remote_development_shared_contexts.rb | 6 +- 9 files changed, 182 insertions(+), 23 deletions(-) create mode 100644 ee/config/feature_flags/beta/allow_extensions_marketplace_in_workspace.yml create mode 100644 ee/spec/fixtures/remote_development/example.processed-marketplace-enabled-devfile.yaml 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 00000000000000..65df964c1dc32d --- /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 bd2517266e29f4..937bc743644ca5 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/features/remote_development/workspaces_spec.rb b/ee/spec/features/remote_development/workspaces_spec.rb index 7548665b8ff5db..fe18af04ba6f34 100644 --- a/ee/spec/features/remote_development/workspaces_spec.rb +++ b/ee/spec/features/remote_development/workspaces_spec.rb @@ -26,6 +26,7 @@ before do stub_licensed_features(remote_development: true) + stub_feature_flags(allow_extensions_marketplace_in_workspace: false) allow(Gitlab::Kas).to receive(:verify_api_request).and_return(true) 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 7c9d5684eac056..0797452bfb5ac6 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: "false" 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 7c9d5684eac056..0797452bfb5ac6 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: "false" 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-enabled-devfile.yaml b/ee/spec/fixtures/remote_development/example.processed-marketplace-enabled-devfile.yaml new file mode 100644 index 00000000000000..34ae035025a7b4 --- /dev/null +++ b/ee/spec/fixtures/remote_development/example.processed-marketplace-enabled-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: "true" + 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 4789696632fc61..0404f9d7597fa6 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,34 @@ 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 |allow_extensions_marketplace_in_workspace:| + before do + if allow_extensions_marketplace_in_workspace + stub_feature_flags(allow_extensions_marketplace_in_workspace: agent.project.root_namespace) + else + stub_feature_flags(allow_extensions_marketplace_in_workspace: false) + end end - expect(editor_injector_component).to eq(expected_volume_component) + + 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 + end + + it_behaves_like 'successful injection of editor components', allow_extensions_marketplace_in_workspace: false + + context "when allow_extensions_marketplace_in_workspace is enabled for agent.project.root_namespace" do + let(:processed_devfile_name) { 'example.processed-marketplace-enabled-devfile.yaml' } + + it_behaves_like 'successful injection of editor components', allow_extensions_marketplace_in_workspace: true end end diff --git a/ee/spec/lib/remote_development/workspaces/create/main_integration_spec.rb b/ee/spec/lib/remote_development/workspaces/create/main_integration_spec.rb index f7034bd092bcdc..ca3a12400ac3fa 100644 --- a/ee/spec/lib/remote_development/workspaces/create/main_integration_spec.rb +++ b/ee/spec/lib/remote_development/workspaces/create/main_integration_spec.rb @@ -49,6 +49,10 @@ described_class.main(value) end + before do + stub_feature_flags(allow_extensions_marketplace_in_workspace: false) + end + context 'when params are valid' do context 'when devfile is valid' do before do 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 6b52e536a9880c..2d4d6e68c5ae06 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: "false" + }, { 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: { -- GitLab From ed02769db99277f1a05374a2f191732457c82143 Mon Sep 17 00:00:00 2001 From: Vishal Tak Date: Mon, 22 Jan 2024 09:21:46 +0530 Subject: [PATCH 2/2] Change spec to assume default true --- .../remote_development/workspaces_spec.rb | 1 - .../example.processed-devfile-v2.yaml | 2 +- .../example.processed-devfile.yaml | 2 +- ...ocessed-marketplace-disabled-devfile.yaml} | 2 +- .../create/editor_component_injector_spec.rb | 22 ++++++++----------- .../create/main_integration_spec.rb | 4 ---- .../remote_development_shared_contexts.rb | 2 +- 7 files changed, 13 insertions(+), 22 deletions(-) rename ee/spec/fixtures/remote_development/{example.processed-marketplace-enabled-devfile.yaml => example.processed-marketplace-disabled-devfile.yaml} (99%) diff --git a/ee/spec/features/remote_development/workspaces_spec.rb b/ee/spec/features/remote_development/workspaces_spec.rb index fe18af04ba6f34..7548665b8ff5db 100644 --- a/ee/spec/features/remote_development/workspaces_spec.rb +++ b/ee/spec/features/remote_development/workspaces_spec.rb @@ -26,7 +26,6 @@ before do stub_licensed_features(remote_development: true) - stub_feature_flags(allow_extensions_marketplace_in_workspace: false) allow(Gitlab::Kas).to receive(:verify_api_request).and_return(true) 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 0797452bfb5ac6..34ae035025a7b4 100644 --- a/ee/spec/fixtures/remote_development/example.processed-devfile-v2.yaml +++ b/ee/spec/fixtures/remote_development/example.processed-devfile-v2.yaml @@ -33,7 +33,7 @@ components: - name: GL_SSH_PORT value: "60022" - name: GL_EDITOR_ENABLE_MARKETPLACE - value: "false" + value: "true" endpoints: - name: editor-server targetPort: 60001 diff --git a/ee/spec/fixtures/remote_development/example.processed-devfile.yaml b/ee/spec/fixtures/remote_development/example.processed-devfile.yaml index 0797452bfb5ac6..34ae035025a7b4 100644 --- a/ee/spec/fixtures/remote_development/example.processed-devfile.yaml +++ b/ee/spec/fixtures/remote_development/example.processed-devfile.yaml @@ -33,7 +33,7 @@ components: - name: GL_SSH_PORT value: "60022" - name: GL_EDITOR_ENABLE_MARKETPLACE - value: "false" + value: "true" endpoints: - name: editor-server targetPort: 60001 diff --git a/ee/spec/fixtures/remote_development/example.processed-marketplace-enabled-devfile.yaml b/ee/spec/fixtures/remote_development/example.processed-marketplace-disabled-devfile.yaml similarity index 99% rename from ee/spec/fixtures/remote_development/example.processed-marketplace-enabled-devfile.yaml rename to ee/spec/fixtures/remote_development/example.processed-marketplace-disabled-devfile.yaml index 34ae035025a7b4..0797452bfb5ac6 100644 --- a/ee/spec/fixtures/remote_development/example.processed-marketplace-enabled-devfile.yaml +++ b/ee/spec/fixtures/remote_development/example.processed-marketplace-disabled-devfile.yaml @@ -33,7 +33,7 @@ components: - name: GL_SSH_PORT value: "60022" - name: GL_EDITOR_ENABLE_MARKETPLACE - value: "true" + value: "false" endpoints: - name: editor-server targetPort: 60001 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 0404f9d7597fa6..230dda453b32dd 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 @@ -30,15 +30,7 @@ described_class.inject(value) end - shared_examples 'successful injection of editor components' do |allow_extensions_marketplace_in_workspace:| - before do - if allow_extensions_marketplace_in_workspace - stub_feature_flags(allow_extensions_marketplace_in_workspace: agent.project.root_namespace) - else - stub_feature_flags(allow_extensions_marketplace_in_workspace: false) - end - end - + 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') } @@ -53,11 +45,15 @@ end end - it_behaves_like 'successful injection of editor components', allow_extensions_marketplace_in_workspace: false + it_behaves_like 'successful injection of editor components' - context "when allow_extensions_marketplace_in_workspace is enabled for agent.project.root_namespace" do - let(:processed_devfile_name) { 'example.processed-marketplace-enabled-devfile.yaml' } + 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', allow_extensions_marketplace_in_workspace: true + it_behaves_like 'successful injection of editor components' end end diff --git a/ee/spec/lib/remote_development/workspaces/create/main_integration_spec.rb b/ee/spec/lib/remote_development/workspaces/create/main_integration_spec.rb index ca3a12400ac3fa..f7034bd092bcdc 100644 --- a/ee/spec/lib/remote_development/workspaces/create/main_integration_spec.rb +++ b/ee/spec/lib/remote_development/workspaces/create/main_integration_spec.rb @@ -49,10 +49,6 @@ described_class.main(value) end - before do - stub_feature_flags(allow_extensions_marketplace_in_workspace: false) - end - context 'when params are valid' do context 'when devfile is valid' do before do 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 2d4d6e68c5ae06..1c20489e5f04b4 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 @@ -620,7 +620,7 @@ def workspace_deployment( }, { name: "GL_EDITOR_ENABLE_MARKETPLACE", - value: "false" + value: "true" }, { name: "PROJECTS_ROOT", -- GitLab