diff --git a/ee/lib/remote_development/files.rb b/ee/lib/remote_development/files.rb index f535d6bcbdfd0c3ffe717ff98c0af383400cd6c3..f14c530e590b7d583fb182f5cbeffe4d33a190da 100644 --- a/ee/lib/remote_development/files.rb +++ b/ee/lib/remote_development/files.rb @@ -34,8 +34,8 @@ def self.read_file(path) read_file("workspace_operations/reconcile/output/kubernetes_poststart_hook_command.sh") MAIN_COMPONENT_UPDATER_CONTAINER_ARGS = read_file("workspace_operations/create/main_component_updater_container_args.sh") - MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT = - read_file("workspace_operations/create/main_component_updater_init_tools.sh") + MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT = + read_file("workspace_operations/create/main_component_updater_start_vscode.sh") MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT = read_file("workspace_operations/create/main_component_updater_sleep_until_workspace_is_running.sh") MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT = diff --git a/ee/lib/remote_development/workspace_operations/create/main_component_updater.rb b/ee/lib/remote_development/workspace_operations/create/main_component_updater.rb index 7832d2d0fa396037a47f0491849c524ff511fe49..9b33e093f1db94f45c9ac8f151682e8e35f5c60e 100644 --- a/ee/lib/remote_development/workspace_operations/create/main_component_updater.rb +++ b/ee/lib/remote_development/workspace_operations/create/main_component_updater.rb @@ -74,11 +74,11 @@ def self.update_env_vars(main_component_container:, tools_dir:, editor_port:, ss value: tools_dir }, { - name: "GL_EDITOR_LOG_LEVEL", + name: "GL_VSCODE_LOG_LEVEL", value: "info" }, { - name: "GL_EDITOR_PORT", + name: "GL_VSCODE_PORT", value: editor_port.to_s }, { @@ -86,7 +86,7 @@ def self.update_env_vars(main_component_container:, tools_dir:, editor_port:, ss value: ssh_port.to_s }, { - name: "GL_EDITOR_ENABLE_MARKETPLACE", + name: "GL_VSCODE_ENABLE_MARKETPLACE", value: enable_marketplace.to_s } ) @@ -142,16 +142,16 @@ def self.add_poststart_commands(processed_devfile:, main_component:) } poststart_events << start_sshd_command_id - # Add the init_tools event - init_tools_command_id = "gl-init-tools-command" + # Add the start_vscode event + start_vscode_command_id = "gl-init-tools-command" commands << { - id: init_tools_command_id, + id: start_vscode_command_id, exec: { - commandLine: MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT, + commandLine: MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, component: main_component_name } } - poststart_events << init_tools_command_id + poststart_events << start_vscode_command_id # Add the sleep_until_container_is_running event sleep_until_container_is_running_command_id = "gl-sleep-until-container-is-running-command" diff --git a/ee/lib/remote_development/workspace_operations/create/main_component_updater_init_tools.sh b/ee/lib/remote_development/workspace_operations/create/main_component_updater_init_tools.sh deleted file mode 100644 index acf8892ead0d21452819bf014bde44723946cc4c..0000000000000000000000000000000000000000 --- a/ee/lib/remote_development/workspace_operations/create/main_component_updater_init_tools.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -echo "$(date -Iseconds): ----------------------------------------" -echo "$(date -Iseconds): Running ${GL_TOOLS_DIR}/init_tools.sh with output written to ${GL_WORKSPACE_LOGS_DIR}/init-tools.log..." -"${GL_TOOLS_DIR}/init_tools.sh" >> "${GL_WORKSPACE_LOGS_DIR}/init-tools.log" 2>&1 & -echo "$(date -Iseconds): Finished running ${GL_TOOLS_DIR}/init_tools.sh." diff --git a/ee/lib/remote_development/workspace_operations/create/main_component_updater_start_vscode.sh b/ee/lib/remote_development/workspace_operations/create/main_component_updater_start_vscode.sh new file mode 100644 index 0000000000000000000000000000000000000000..1f11d7e5c90f7ee2e82e536112dfa0f8a1661b03 --- /dev/null +++ b/ee/lib/remote_development/workspace_operations/create/main_component_updater_start_vscode.sh @@ -0,0 +1,101 @@ +#!/bin/sh + +echo "$(date -Iseconds): ----------------------------------------" +echo "$(date -Iseconds): Running main_component_updater_start_vscode.sh with output written to ${GL_WORKSPACE_LOGS_DIR}/start_vscode.log..." + +# Define log file path +LOG_FILE="${GL_WORKSPACE_LOGS_DIR}/start_vscode.log" + +mkdir -p "$(dirname "${LOG_FILE}")" + +echo "$(date -Iseconds): VS Code initialization started" + +# Start logging +exec 1>>"${LOG_FILE}" 2>&1 + +# # This script initilizes the tools injected into the workspace on startup. +# # +# # It uses the following environment variables +# # $GL_TOOLS_DIR - directory where the tools are copied. +# # $GL_VSCODE_LOG_LEVEL - log level for the server. defaults to "info". +# # $GL_VSCODE_PORT - port on which the server is exposed. defaults to "60001". +# # $GL_VSCODE_IGNORE_VERSION_MISMATCH - if set to true, the server works even when server and WebIDE versions do not match. +# # $GL_VSCODE_ENABLE_MARKETPLACE - if set to true, set configuration to enable marketplace. +# # $GL_VSCODE_EXTENSION_MARKETPLACE_SERVICE_URL - service url for the extensions marketplace. +# # $GL_VSCODE_EXTENSION_MARKETPLACE_ITEM_URL - item url for the extensions marketplace. +# # $GL_VSCODE_EXTENSION_MARKETPLACE_RESOURCE_URL_TEMPLATE - resource url template for the extensions marketplace. +# # $GITLAB_WORKFLOW_TOKEN - a giltab personal access token to configure the gitlab vscode extension. +# # $GITLAB_WORKFLOW_TOKEN_FILE - the contents of this file populate GITLAB_WORKFLOW_TOKEN if it is not set. + +if [ -z "${GL_TOOLS_DIR}" ]; then + echo "$(date -Iseconds): \$GL_TOOLS_DIR is not set" + exit 1 +fi + +if [ -z "${GL_VSCODE_LOG_LEVEL}" ]; then + GL_VSCODE_LOG_LEVEL="info" + echo "$(date -Iseconds): Setting default GL_VSCODE_LOG_LEVEL=${GL_VSCODE_LOG_LEVEL}" +fi + +if [ -z "${GL_VSCODE_PORT}" ]; then + GL_VSCODE_PORT="60001" + echo "$(date -Iseconds): Setting default GL_VSCODE_PORT=${GL_VSCODE_PORT}" +fi + +if [ -z "${GL_VSCODE_EXTENSION_MARKETPLACE_SERVICE_URL}" ]; then + GL_VSCODE_EXTENSION_MARKETPLACE_SERVICE_URL="https://open-vsx.org/vscode/gallery" + echo "$(date -Iseconds): Setting default GL_VSCODE_EXTENSION_MARKETPLACE_SERVICE_URL=${GL_VSCODE_EXTENSION_MARKETPLACE_SERVICE_URL}" +fi + +if [ -z "${GL_VSCODE_EXTENSION_MARKETPLACE_ITEM_URL}" ]; then + GL_VSCODE_EXTENSION_MARKETPLACE_ITEM_URL="https://open-vsx.org/vscode/item" + echo "$(date -Iseconds): Setting default GL_VSCODE_EXTENSION_MARKETPLACE_ITEM_URL=${GL_VSCODE_EXTENSION_MARKETPLACE_ITEM_URL}" +fi + +if [ -z "${GL_VSCODE_EXTENSION_MARKETPLACE_RESOURCE_URL_TEMPLATE}" ]; then + GL_VSCODE_EXTENSION_MARKETPLACE_RESOURCE_URL_TEMPLATE="https://open-vsx.org/api/{publisher}/{name}/{version}/file/{path}" + echo "$(date -Iseconds): Setting default GL_VSCODE_EXTENSION_MARKETPLACE_RESOURCE_URL_TEMPLATE=${GL_VSCODE_EXTENSION_MARKETPLACE_RESOURCE_URL_TEMPLATE}" +fi + +PRODUCT_JSON_FILE="${GL_TOOLS_DIR}/vscode-reh-web/product.json" + +if [ "$GL_VSCODE_IGNORE_VERSION_MISMATCH" = true ]; then + # TODO: remove this section once issue is fixed - https://gitlab.com/gitlab-org/gitlab/-/issues/373669 + # remove "commit" key from product.json to avoid client-server mismatch + # TODO: remove this once we are not worried about version mismatch + # https://gitlab.com/gitlab-org/gitlab/-/issues/373669 + echo "$(date -Iseconds): Ignoring VS Code client-server version mismatch" + sed -i.bak '/"commit"/d' "${PRODUCT_JSON_FILE}" && rm "${PRODUCT_JSON_FILE}.bak" + echo "$(date -Iseconds): Removed 'commit' key from ${PRODUCT_JSON_FILE}" +fi + +if [ "$GL_VSCODE_ENABLE_MARKETPLACE" = true ]; then + EXTENSIONS_GALLERY_KEY="{\\n\\t\"extensionsGallery\": {\\n\\t\\t\"serviceUrl\": \"${GL_VSCODE_EXTENSION_MARKETPLACE_SERVICE_URL}\",\\n\\t\\t\"itemUrl\": \"${GL_VSCODE_EXTENSION_MARKETPLACE_ITEM_URL}\",\\n\\t\\t\"resourceUrlTemplate\": \"${GL_VSCODE_EXTENSION_MARKETPLACE_RESOURCE_URL_TEMPLATE}\"\\n\\t}," + echo "$(date -Iseconds): '${EXTENSIONS_GALLERY_KEY}' in '${PRODUCT_JSON_FILE}' at the beginning of the file" + sed -i.bak "1s|.*|$EXTENSIONS_GALLERY_KEY|" "${PRODUCT_JSON_FILE}" && rm "${PRODUCT_JSON_FILE}.bak" + echo "$(date -Iseconds): Extensions gallery configuration added" +fi + +echo "$(date -Iseconds): Contents of ${PRODUCT_JSON_FILE} are: " +cat "${PRODUCT_JSON_FILE}" +echo + +GL_VSCODE_HOST="0.0.0.0" + +echo "$(date -Iseconds): Starting server for the editor with:" +echo "$(date -Iseconds): - Host: ${GL_VSCODE_HOST}" +echo "$(date -Iseconds): - Port: ${GL_VSCODE_PORT}" +echo "$(date -Iseconds): - Log level: ${GL_VSCODE_LOG_LEVEL}" +echo "$(date -Iseconds): - Without connection token: yes" +echo "$(date -Iseconds): - Workspace trust disabled: yes" + +# For the actual server execution, we need to make sure it doesn't get backgrounded +# and its output continues going to the log file +"${GL_TOOLS_DIR}/vscode-reh-web/bin/gitlab-webide-server" \ + --host "${GL_VSCODE_HOST}" \ + --port "${GL_VSCODE_PORT}" \ + --log "${GL_VSCODE_LOG_LEVEL}" \ + --without-connection-token \ + --disable-workspace-trust + +echo "$(date -Iseconds): VS Code: Remote Extension Host process exited with code $?" diff --git a/ee/lib/remote_development/workspace_operations/create/workspace_variables_builder.rb b/ee/lib/remote_development/workspace_operations/create/workspace_variables_builder.rb index f156ba03be159ffcb7caff9e3398e162db551076..e028488b3199def9752db079e5e3471efc14f3ac 100644 --- a/ee/lib/remote_development/workspace_operations/create/workspace_variables_builder.rb +++ b/ee/lib/remote_development/workspace_operations/create/workspace_variables_builder.rb @@ -122,24 +122,22 @@ def self.build( #------------------------------------------------------------------- #------------------------------------------------------------------- - # Variables with prefix `GL_EDITOR_EXTENSIONS_GALLERY` are used for configuring the + # Variables with prefix `GL_VSCODE_EXTENSION_MARKETPLACE` are used for configuring the # GitLab fork of VS Code which is injected into the workspace. - # TODO: Rename these to be `GL_VSCODE_EXTENSION_MARKETPLACE_*` to be consistent with the new naming standard - # See https://gitlab.com/gitlab-org/gitlab/-/issues/520884 { - key: "GL_EDITOR_EXTENSIONS_GALLERY_SERVICE_URL", + key: "GL_VSCODE_EXTENSION_MARKETPLACE_SERVICE_URL", value: vscode_extension_marketplace_service_url, variable_type: ENVIRONMENT_TYPE, workspace_id: workspace_id }, { - key: "GL_EDITOR_EXTENSIONS_GALLERY_ITEM_URL", + key: "GL_VSCODE_EXTENSION_MARKETPLACE_ITEM_URL", value: vscode_extension_marketplace_item_url, variable_type: ENVIRONMENT_TYPE, workspace_id: workspace_id }, { - key: "GL_EDITOR_EXTENSIONS_GALLERY_RESOURCE_URL_TEMPLATE", + key: "GL_VSCODE_EXTENSION_MARKETPLACE_RESOURCE_URL_TEMPLATE", value: vscode_extension_marketplace_resource_url_template, variable_type: ENVIRONMENT_TYPE, workspace_id: workspace_id diff --git a/ee/spec/fixtures/remote_development/example.legacy-scripts-in-container-command-processed-devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.legacy-scripts-in-container-command-processed-devfile.yaml.erb index 15eba94a88692fe84dab17750c7efd14ee901ff9..111bdc0ee470a561ca4859ecd6141b88cd14215f 100644 --- a/ee/spec/fixtures/remote_development/example.legacy-scripts-in-container-command-processed-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.legacy-scripts-in-container-command-processed-devfile.yaml.erb @@ -10,7 +10,7 @@ components: args: - | <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, 10) %> - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT, 10) %> + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, 10) %> command: - "/bin/sh" - "-c" @@ -20,13 +20,13 @@ components: env: - name: GL_TOOLS_DIR value: "/projects/.gl-tools" - - name: GL_EDITOR_LOG_LEVEL + - name: GL_VSCODE_LOG_LEVEL value: "info" - - name: GL_EDITOR_PORT + - name: GL_VSCODE_PORT value: "<%= WORKSPACE_EDITOR_PORT %>" - name: GL_SSH_PORT value: "<%= WORKSPACE_SSH_PORT %>" - - name: GL_EDITOR_ENABLE_MARKETPLACE + - name: GL_VSCODE_ENABLE_MARKETPLACE value: "false" endpoints: - name: editor-server diff --git a/ee/spec/fixtures/remote_development/example.main-container-updated-devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.main-container-updated-devfile.yaml.erb index 4c69a6f7e436cc6f137fed86410f95862c5d3bde..d43b052e3f7d546778af0817b410f2edd5cbe6ee 100644 --- a/ee/spec/fixtures/remote_development/example.main-container-updated-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.main-container-updated-devfile.yaml.erb @@ -16,13 +16,13 @@ components: env: - name: GL_TOOLS_DIR value: "/projects/.gl-tools" - - name: GL_EDITOR_LOG_LEVEL + - name: GL_VSCODE_LOG_LEVEL value: "info" - - name: GL_EDITOR_PORT + - name: GL_VSCODE_PORT value: "<%= WORKSPACE_EDITOR_PORT %>" - name: GL_SSH_PORT value: "<%= WORKSPACE_SSH_PORT %>" - - name: GL_EDITOR_ENABLE_MARKETPLACE + - name: GL_VSCODE_ENABLE_MARKETPLACE value: "false" endpoints: - name: editor-server @@ -66,7 +66,7 @@ commands: - id: gl-init-tools-command exec: commandLine: | - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT, 8) %> + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, 8) %> component: tooling-container - id: gl-sleep-until-container-is-running-command exec: diff --git a/ee/spec/fixtures/remote_development/example.main-container-updated-marketplace-disabled-devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.main-container-updated-marketplace-disabled-devfile.yaml.erb index 4c69a6f7e436cc6f137fed86410f95862c5d3bde..d43b052e3f7d546778af0817b410f2edd5cbe6ee 100644 --- a/ee/spec/fixtures/remote_development/example.main-container-updated-marketplace-disabled-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.main-container-updated-marketplace-disabled-devfile.yaml.erb @@ -16,13 +16,13 @@ components: env: - name: GL_TOOLS_DIR value: "/projects/.gl-tools" - - name: GL_EDITOR_LOG_LEVEL + - name: GL_VSCODE_LOG_LEVEL value: "info" - - name: GL_EDITOR_PORT + - name: GL_VSCODE_PORT value: "<%= WORKSPACE_EDITOR_PORT %>" - name: GL_SSH_PORT value: "<%= WORKSPACE_SSH_PORT %>" - - name: GL_EDITOR_ENABLE_MARKETPLACE + - name: GL_VSCODE_ENABLE_MARKETPLACE value: "false" endpoints: - name: editor-server @@ -66,7 +66,7 @@ commands: - id: gl-init-tools-command exec: commandLine: | - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT, 8) %> + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, 8) %> component: tooling-container - id: gl-sleep-until-container-is-running-command exec: diff --git a/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb index 09be3f2219c1b0a6bdd1fb0d48305ab12d45891d..15407e58f23df388878507a96dda6d8a3a0de1e7 100644 --- a/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb @@ -19,13 +19,13 @@ components: env: - name: GL_TOOLS_DIR value: "/projects/.gl-tools" - - name: GL_EDITOR_LOG_LEVEL + - name: GL_VSCODE_LOG_LEVEL value: "info" - - name: GL_EDITOR_PORT + - name: GL_VSCODE_PORT value: "<%= WORKSPACE_EDITOR_PORT %>" - name: GL_SSH_PORT value: "<%= WORKSPACE_SSH_PORT %>" - - name: GL_EDITOR_ENABLE_MARKETPLACE + - name: GL_VSCODE_ENABLE_MARKETPLACE value: "false" endpoints: - name: editor-server @@ -94,7 +94,7 @@ commands: - id: gl-init-tools-command exec: commandLine: | - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT, 8) %> + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, 8) %> component: tooling-container - id: gl-sleep-until-container-is-running-command exec: diff --git a/ee/spec/fixtures/remote_development/example.project-cloner-inserted-devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.project-cloner-inserted-devfile.yaml.erb index 45b69dae9643ef7952f659467b8076af50db743f..21cc1e4365ed70b3479a266656eab3a457624305 100644 --- a/ee/spec/fixtures/remote_development/example.project-cloner-inserted-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.project-cloner-inserted-devfile.yaml.erb @@ -16,13 +16,13 @@ components: env: - name: GL_TOOLS_DIR value: "/projects/.gl-tools" - - name: GL_EDITOR_LOG_LEVEL + - name: GL_VSCODE_LOG_LEVEL value: "info" - - name: GL_EDITOR_PORT + - name: GL_VSCODE_PORT value: "<%= WORKSPACE_EDITOR_PORT %>" - name: GL_SSH_PORT value: "<%= WORKSPACE_SSH_PORT %>" - - name: GL_EDITOR_ENABLE_MARKETPLACE + - name: GL_VSCODE_ENABLE_MARKETPLACE value: "false" endpoints: - name: editor-server @@ -79,7 +79,7 @@ commands: - id: gl-init-tools-command exec: commandLine: | - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT, 8) %> + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, 8) %> component: tooling-container - id: gl-sleep-until-container-is-running-command exec: diff --git a/ee/spec/lib/remote_development/workspace_operations/create/main_component_updater_start_vscode_script_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/main_component_updater_start_vscode_script_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..d073cb9389cf8d90898881142e435a32f916e468 --- /dev/null +++ b/ee/spec/lib/remote_development/workspace_operations/create/main_component_updater_start_vscode_script_spec.rb @@ -0,0 +1,175 @@ +# frozen_string_literal: true + +require "fast_spec_helper" +require "tempfile" +require "fileutils" + +RSpec.describe "Remote Development VSCode Startup Script", feature_category: :workspaces do + include_context "with constant modules" + + let(:script_content) { RemoteDevelopment::Files::MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT } + let(:script_file) { Tempfile.new(%w[start_vscode .sh]) } + let(:log_dir) { Dir.mktmpdir } + let(:tools_dir) { Dir.mktmpdir } + let(:product_json_path) { File.join(tools_dir, "vscode-reh-web/product.json") } + let(:log_file_path) { File.join(log_dir, "start_vscode.log") } + let(:extension_marketplace_service_url) { "https://marketplace.example.com" } + let(:extension_marketplace_item_url) { "https://item.example.com" } + let(:extension_marketplace_resource_url_template) { "https://resource.example.com/{path}" } + let(:editor_log_level) { "info" } + let(:editor_port) { create_constants_module::WORKSPACE_EDITOR_PORT } + let(:editor_host) { "0.0.0.0" } + let(:initial_product_json) { '{"commit": "test-commit", "otherKey": "value"}' } + let(:base_env) do + { + GL_TOOLS_DIR: tools_dir, + GL_WORKSPACE_LOGS_DIR: log_dir + } + end + + # Helper method to run the script with given environment variables + # @param [Hash, nil] custom_env + # @return [Hash] + def run_script(custom_env = nil) + env_vars = custom_env || env + # Convert symbol keys to strings for the environment variables + env_string = env_vars.map { |k, v| "#{k}=#{v}" }.join(" ") + + # Execute the script + result = `env -i #{env_string} #{script_file.path} 2>&1` + status = $?&.success? || false + + # Read the log file if it exists + log_content = File.exist?(log_file_path) ? File.read(log_file_path) : nil + + { + output: result, + success: status, + logs: log_content + } + end + + before do + # Create the directory structure + FileUtils.mkdir_p(File.join(tools_dir, "vscode-reh-web")) + + # Create a mock product.json file + FileUtils.mkdir_p(File.dirname(product_json_path)) + File.write(product_json_path, initial_product_json) + + mock_vscode_server_command = "echo 'Mock VSCode server execution - skipping actual server start'" + + unless script_content.match?(%r{"\${GL_TOOLS_DIR}/vscode-reh-web/bin/gitlab-webide-server"}) + raise "Expected VSCode server execution pattern not found in script. The script may have changed." + end + + # Modify the script to replace the server execution command + # Script mocks the server execution because we don't have the vscode-reh-web executables setup + modified_script = script_content.gsub( + %r{"\${GL_TOOLS_DIR}/vscode-reh-web/bin/gitlab-webide-server"}, + mock_vscode_server_command + ) + + script_file.write(modified_script) + script_file.close + FileUtils.chmod(0o755, script_file.path.to_s) + end + + after do + script_file.unlink + FileUtils.remove_entry(log_dir) + FileUtils.remove_entry(tools_dir) + end + + describe "happy path script execution with default settings" do + let(:env) do + base_env.merge({ + GL_VSCODE_IGNORE_VERSION_MISMATCH: "true", + GL_VSCODE_ENABLE_MARKETPLACE: "true", + GL_VSCODE_EXTENSION_MARKETPLACE_SERVICE_URL: extension_marketplace_service_url, + GL_VSCODE_EXTENSION_MARKETPLACE_ITEM_URL: extension_marketplace_item_url, + GL_VSCODE_EXTENSION_MARKETPLACE_RESOURCE_URL_TEMPLATE: extension_marketplace_resource_url_template + }) + end + + let!(:script_result) { run_script } + let(:output) { script_result.fetch(:output) } + let(:status) { script_result.fetch(:success) } + let(:log_content) { script_result.fetch(:logs) } + + it "executes successfully and creates the log file" do + expect(status).to be true + expect(output).to include("VS Code initialization started") + expect(File).to exist(log_file_path) + end + + it "sets default environment variables for unspecified values" do + expect(log_content).to include("Setting default GL_VSCODE_LOG_LEVEL=#{editor_log_level}") + expect(log_content).to include("Setting default GL_VSCODE_PORT=#{editor_port}") + end + + it "logs the correct server startup information" do + expect(log_content).to include("Starting server for the editor with:") + expect(log_content).to include("- Host: #{editor_host}") + expect(log_content).to include("- Port: #{editor_port}") + expect(log_content).to include("- Log level: #{editor_log_level}") + expect(log_content).to include("- Without connection token: yes") + expect(log_content).to include("- Workspace trust disabled: yes") + end + + it "removes the commit key from product.json for version mismatch handling" do + expect(log_content).to include("Ignoring VS Code client-server version mismatch") + expect(log_content).to include("Removed 'commit' key from #{product_json_path}") + end + + it "adds the extensions gallery configuration to product.json for marketplace" do + expect(log_content).to include("Extensions gallery configuration added") + + # Check if the log shows the modified content + expect(log_content).to include("Contents of #{product_json_path} are:") + expect(log_content).to include("extensionsGallery") + expect(log_content).to include("\"serviceUrl\": \"#{extension_marketplace_service_url}\"") + expect(log_content).to include("\"itemUrl\": \"#{extension_marketplace_item_url}\"") + expect(log_content).to include("\"resourceUrlTemplate\": \"#{extension_marketplace_resource_url_template}\"") + end + end + + describe "script execution with custom settings" do + let(:custom_editor_log_level) { "debug" } + let(:custom_editor_port) { "8080" } + let(:env) do + base_env.merge({ + GL_VSCODE_LOG_LEVEL: custom_editor_log_level, + GL_VSCODE_PORT: custom_editor_port + }) + end + + let!(:script_result) { run_script } + let(:status) { script_result.fetch(:success) } + let(:log_content) { script_result.fetch(:logs) } + + it "uses the provided environment variables instead of defaults" do + expect(status).to be true + + # Verify custom values were used (not default values) + expect(log_content).not_to include("Setting default GL_VSCODE_LOG_LEVEL") + expect(log_content).not_to include("Setting default GL_VSCODE_PORT") + + # Verify custom server configuration in logs + expect(log_content).to include("- Port: #{custom_editor_port}") + expect(log_content).to include("- Log level: #{custom_editor_log_level}") + end + end + + describe "script execution without required variables" do + let(:env_without_tools) { { GL_WORKSPACE_LOGS_DIR: log_dir } } + let!(:script_result) { run_script(env_without_tools) } + let(:status) { script_result.fetch(:success) } + let(:log_content) { script_result.fetch(:logs) } + + it "fails when GL_TOOLS_DIR is not set" do + expect(status).to be false + expect(log_content).to include("GL_TOOLS_DIR is not set") + end + end +end diff --git a/ee/spec/lib/remote_development/workspace_operations/create/workspace_variables_builder_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/workspace_variables_builder_spec.rb index 9e164169170498491336a4bd3990721b1193bf0b..3b5575422f3a5819f17bbc908e539da65556500d 100644 --- a/ee/spec/lib/remote_development/workspace_operations/create/workspace_variables_builder_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/create/workspace_variables_builder_spec.rb @@ -90,19 +90,19 @@ workspace_id: workspace_id }, { - key: "GL_EDITOR_EXTENSIONS_GALLERY_SERVICE_URL", + key: "GL_VSCODE_EXTENSION_MARKETPLACE_SERVICE_URL", value: vscode_extensions_gallery_service_url, variable_type: RemoteDevelopment::Enums::WorkspaceVariable::ENVIRONMENT_TYPE, workspace_id: workspace_id }, { - key: "GL_EDITOR_EXTENSIONS_GALLERY_ITEM_URL", + key: "GL_VSCODE_EXTENSION_MARKETPLACE_ITEM_URL", value: vscode_extensions_gallery_item_url, variable_type: RemoteDevelopment::Enums::WorkspaceVariable::ENVIRONMENT_TYPE, workspace_id: workspace_id }, { - key: "GL_EDITOR_EXTENSIONS_GALLERY_RESOURCE_URL_TEMPLATE", + key: "GL_VSCODE_EXTENSION_MARKETPLACE_RESOURCE_URL_TEMPLATE", value: vscode_extensions_gallery_resource_url_template, variable_type: RemoteDevelopment::Enums::WorkspaceVariable::ENVIRONMENT_TYPE, workspace_id: workspace_id diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/scripts_configmap_appender_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/scripts_configmap_appender_spec.rb index 0a41e31a76402f096e79efec35c0cdfb23a715f8..00dae4adadb0371cefcfb2124c577930b9a8c5da 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/scripts_configmap_appender_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/scripts_configmap_appender_spec.rb @@ -69,7 +69,7 @@ expect(api_version).to eq("v1") expect(configmap_name).to eq(name) expect(data).to eq( - "gl-init-tools-command": files::MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT, + "gl-init-tools-command": files::MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, reconcile_constants_module::RUN_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => expected_postart_commands_script, "gl-sleep-until-container-is-running-command": diff --git a/ee/spec/requests/remote_development/integration_spec.rb b/ee/spec/requests/remote_development/integration_spec.rb index 562e6d5ba4fc579a95d67d57a281922863ea211d..d66c55f237ea9f0e1f78d91dd7844c0deb44c6bc 100644 --- a/ee/spec/requests/remote_development/integration_spec.rb +++ b/ee/spec/requests/remote_development/integration_spec.rb @@ -140,9 +140,9 @@ def expected_internal_variables(random_string:) { key: "GIT_CONFIG_VALUE_0", type: :environment, value: git_credential_store_script_file_path }, { key: "GIT_CONFIG_VALUE_1", type: :environment, value: "Workspaces User" }, { key: "GIT_CONFIG_VALUE_2", type: :environment, value: "workspaces-user@example.org" }, - { key: "GL_EDITOR_EXTENSIONS_GALLERY_ITEM_URL", type: :environment, value: "https://open-vsx.org/vscode/item" }, - { key: "GL_EDITOR_EXTENSIONS_GALLERY_RESOURCE_URL_TEMPLATE", type: :environment, value: "https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{versionRaw}/{path}" }, - { key: "GL_EDITOR_EXTENSIONS_GALLERY_SERVICE_URL", type: :environment, value: "https://open-vsx.org/vscode/gallery" }, + { key: "GL_VSCODE_EXTENSION_MARKETPLACE_ITEM_URL", type: :environment, value: "https://open-vsx.org/vscode/item" }, + { key: "GL_VSCODE_EXTENSION_MARKETPLACE_RESOURCE_URL_TEMPLATE", type: :environment, value: "https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{versionRaw}/{path}" }, + { key: "GL_VSCODE_EXTENSION_MARKETPLACE_SERVICE_URL", type: :environment, value: "https://open-vsx.org/vscode/gallery" }, { key: "GL_WORKSPACE_DOMAIN_TEMPLATE", type: :environment, value: "${PORT}-workspace-#{agent.id}-#{user.id}-#{random_string}.#{dns_zone}" }, { key: "GITLAB_WORKFLOW_INSTANCE_URL", type: :environment, value: Gitlab::Routing.url_helpers.root_url }, { key: "GITLAB_WORKFLOW_TOKEN_FILE", type: :environment, value: token_file_path } 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 0292c267881d8198bd9d9b659563c807aedb511f..af4030d802aa0387570e88a7d677fc897aae8858 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 @@ -648,11 +648,11 @@ def workspace_deployment( "#{create_constants_module::TOOLS_DIR_NAME}" }, { - name: "GL_EDITOR_LOG_LEVEL", + name: "GL_VSCODE_LOG_LEVEL", value: "info" }, { - name: "GL_EDITOR_PORT", + name: "GL_VSCODE_PORT", value: create_constants_module::WORKSPACE_EDITOR_PORT.to_s }, { @@ -660,7 +660,7 @@ def workspace_deployment( value: create_constants_module::WORKSPACE_SSH_PORT.to_s }, { - name: "GL_EDITOR_ENABLE_MARKETPLACE", + name: "GL_VSCODE_ENABLE_MARKETPLACE", value: "false" }, { @@ -928,7 +928,7 @@ def workspace_deployment( deployment[:spec][:template][:spec][:containers][0][:args][0] = <<~YAML.chomp #{files_module::MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT} - #{files_module::MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT} + #{files_module::MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT} YAML end @@ -1157,7 +1157,7 @@ def scripts_configmap(workspace_name:, workspace_namespace:, labels:, annotation namespace: workspace_namespace }, data: { - "gl-init-tools-command": files_module::MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT, + "gl-init-tools-command": files_module::MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, reconcile_constants_module::RUN_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => postart_commands_script, "gl-sleep-until-container-is-running-command": sleep_until_container_is_running_script, "gl-start-sshd-command": files_module::MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT