From 7a3fdf6ab56952532a6753564e00933a9eb937b8 Mon Sep 17 00:00:00 2001 From: Daniyal Arshad Date: Tue, 13 May 2025 20:22:12 -0400 Subject: [PATCH 1/3] Move init_tools.sh into rails repo - Adds init_tools.sh as a workspace_operations create script - Rename main_component_updater_init_tools - Rename workspace_variables having _EDITOR_EXTENSIONS_GALLERY_ - Add new constant for start_vscode_command - Update erb fixtures with the new constant - Add unit test EE: true --- ee/lib/remote_development/files.rb | 4 +- .../create/create_constants.rb | 1 + .../create/main_component_updater.rb | 10 +- .../main_component_updater_init_tools.sh | 5 - .../main_component_updater_start_vscode.sh | 101 +++++++++++ .../create/workspace_variables_builder.rb | 11 +- ...ntainer-command-processed-devfile.yaml.erb | 2 +- ...le.main-container-updated-devfile.yaml.erb | 6 +- ...ated-marketplace-disabled-devfile.yaml.erb | 6 +- .../example.processed-devfile.yaml.erb | 6 +- ...e.project-cloner-inserted-devfile.yaml.erb | 6 +- ...ponent_updater_start_vscode_script_spec.rb | 160 ++++++++++++++++++ .../workspace_variables_builder_spec.rb | 6 +- .../output/scripts_configmap_appender_spec.rb | 6 +- .../remote_development/integration_spec.rb | 6 +- .../remote_development_shared_contexts.rb | 8 +- 16 files changed, 300 insertions(+), 44 deletions(-) delete mode 100644 ee/lib/remote_development/workspace_operations/create/main_component_updater_init_tools.sh create mode 100644 ee/lib/remote_development/workspace_operations/create/main_component_updater_start_vscode.sh create mode 100644 ee/spec/lib/remote_development/workspace_operations/create/main_component_updater_start_vscode_script_spec.rb diff --git a/ee/lib/remote_development/files.rb b/ee/lib/remote_development/files.rb index f535d6bcbdfd0c..f14c530e590b7d 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/create_constants.rb b/ee/lib/remote_development/workspace_operations/create/create_constants.rb index 45796e0958cc65..775e88523c6617 100644 --- a/ee/lib/remote_development/workspace_operations/create/create_constants.rb +++ b/ee/lib/remote_development/workspace_operations/create/create_constants.rb @@ -19,6 +19,7 @@ module CreateConstants MAIN_COMPONENT_INDICATOR_ATTRIBUTE = "gl/inject-editor" NAMESPACE_PREFIX = "gl-rd-ns" PROJECT_CLONING_SUCCESSFUL_FILE_NAME = ".gl_project_cloning_successful" + START_VSCODE_COMMAND = "gl-start-vscode-command" TOKEN_FILE_NAME = "gl_token" TOKEN_FILE_PATH = "#{VARIABLES_VOLUME_PATH}/#{TOKEN_FILE_NAME}".freeze TOOLS_DIR_NAME = ".gl-tools" 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 7832d2d0fa3960..9223aa8e8eed48 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 @@ -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 = START_VSCODE_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 acf8892ead0d21..00000000000000 --- 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 00000000000000..ac76798327e016 --- /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): Vscode 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_EDITOR_LOG_LEVEL - log level for the server. defaults to "info". +# # $GL_EDITOR_PORT - port on which the server is exposed. defaults to "60001". +# # $GL_EDITOR_IGNORE_VERSION_MISMATCH - if set to true, the server works even when server and WebIDE versions do not match. +# # $GL_EDITOR_ENABLE_MARKETPLACE - if set to true, set configuration to enable marketplace. +# # $GL_VSCODE_EXTENSION_MARKETPLACE_SERVICE_URL - service url for the extensions gallery. +# # $GL_VSCODE_EXTENSION_MARKETPLACE_ITEM_URL - item url for the extensions gallery. +# # $GL_VSCODE_EXTENSION_MARKETPLACE_RESOURCE_URL_TEMPLATE - resource url template for the extensions gallery. +# # $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_EDITOR_LOG_LEVEL}" ]; then + GL_EDITOR_LOG_LEVEL="info" + echo "$(date -Iseconds): Setting default GL_EDITOR_LOG_LEVEL=${GL_EDITOR_LOG_LEVEL}" +fi + +if [ -z "${GL_EDITOR_PORT}" ]; then + GL_EDITOR_PORT="60001" + echo "$(date -Iseconds): Setting default GL_EDITOR_PORT=${GL_EDITOR_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_EDITOR_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_EDITOR_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_EDITOR_HOST="0.0.0.0" + +echo "$(date -Iseconds): Starting server for the editor with:" +echo "$(date -Iseconds): - Host: ${GL_EDITOR_HOST}" +echo "$(date -Iseconds): - Port: ${GL_EDITOR_PORT}" +echo "$(date -Iseconds): - Log level: ${GL_EDITOR_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_EDITOR_HOST}" \ + --port "${GL_EDITOR_PORT}" \ + --log "${GL_EDITOR_LOG_LEVEL}" \ + --without-connection-token \ + --disable-workspace-trust + +echo "$(date -Iseconds): Vscode: 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 f156ba03be159f..335759ae3a4e15 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,23 @@ 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 + # All *_EDITOR_EXTENSIONS_GALLERY_* variables were renamed to *_VSCODE_EXTENSION_MARKETPLACE_* in 18.1 { - 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 15eba94a88692f..26522a4a51188b 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" 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 4c69a6f7e436cc..0376170aecf8f9 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 @@ -63,10 +63,10 @@ commands: commandLine: | <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, 8) %> component: tooling-container - - id: gl-init-tools-command + - id: <%= START_VSCODE_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: @@ -84,6 +84,6 @@ events: - gl-tools-injector-command postStart: - gl-start-sshd-command - - gl-init-tools-command + - <%= START_VSCODE_COMMAND %> - gl-sleep-until-container-is-running-command variables: {} 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 4c69a6f7e436cc..0376170aecf8f9 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 @@ -63,10 +63,10 @@ commands: commandLine: | <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, 8) %> component: tooling-container - - id: gl-init-tools-command + - id: <%= START_VSCODE_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: @@ -84,6 +84,6 @@ events: - gl-tools-injector-command postStart: - gl-start-sshd-command - - gl-init-tools-command + - <%= START_VSCODE_COMMAND %> - gl-sleep-until-container-is-running-command variables: {} 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 09be3f2219c1b0..5870c0a6e5b7b7 100644 --- a/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb @@ -91,10 +91,10 @@ commands: commandLine: | <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, 8) %> component: tooling-container - - id: gl-init-tools-command + - id: <%= START_VSCODE_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: @@ -116,6 +116,6 @@ events: - gl-project-cloner-command postStart: - gl-start-sshd-command - - gl-init-tools-command + - <%= START_VSCODE_COMMAND %> - gl-sleep-until-container-is-running-command variables: {} 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 45b69dae9643ef..35d22e8bfd9a8e 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 @@ -76,10 +76,10 @@ commands: commandLine: | <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, 8) %> component: tooling-container - - id: gl-init-tools-command + - id: <%= START_VSCODE_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: @@ -101,6 +101,6 @@ events: - gl-project-cloner-command postStart: - gl-start-sshd-command - - gl-init-tools-command + - <%= START_VSCODE_COMMAND %> - gl-sleep-until-container-is-running-command variables: {} 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 00000000000000..b3507f27ab542d --- /dev/null +++ b/ee/spec/lib/remote_development/workspace_operations/create/main_component_updater_start_vscode_script_spec.rb @@ -0,0 +1,160 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'tempfile' +require 'fileutils' + +RSpec.describe 'Remote Development VSCode Startup Script', feature_category: :workspaces do + let(:script_content) { RemoteDevelopment::Files::MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT } + let(:script_file) { Tempfile.new(["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) { "60001" } + 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 + def run_script(custom_env = nil) + env_vars = custom_env || env + 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? + + # Read the log file if it exists + log_content = File.exist?(log_file_path) ? File.read(log_file_path) : nil + + [result, status, 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) + + # Modify the script to exit before server execution + # Script exits before running the actual server 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"}, + "exit 0 #" + ) + + script_file.write(modified_script) + script_file.close + FileUtils.chmod(0o755, script_file.path) + 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_EDITOR_IGNORE_VERSION_MISMATCH" => "true", + "GL_EDITOR_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[0] } + let(:status) { script_result[1] } + let(:log_content) { script_result[2] } + + it "executes successfully and creates the log file" do + expect(status).to be true + expect(output).to include("Vscode 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_EDITOR_LOG_LEVEL=#{editor_log_level}") + expect(log_content).to include("Setting default GL_EDITOR_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_EDITOR_LOG_LEVEL" => custom_editor_log_level, + "GL_EDITOR_PORT" => custom_editor_port + }) + end + + let!(:script_result) { run_script } + let(:status) { script_result[1] } + let(:log_content) { script_result[2] } + + 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_EDITOR_LOG_LEVEL") + expect(log_content).not_to include("Setting default GL_EDITOR_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[1] } + let(:log_content) { script_result[2] } + + 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 9e164169170498..3b5575422f3a58 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 0a41e31a76402f..c296be2b02045f 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 @@ -18,8 +18,8 @@ #!/bin/sh echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-start-sshd-command..." #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-start-sshd-command || true - echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-init-tools-command..." - #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-init-tools-command || true + echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/#{create_constants_module::START_VSCODE_COMMAND}..." + #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/#{create_constants_module::START_VSCODE_COMMAND} || true echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command..." #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command || true SCRIPT @@ -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, + "#{create_constants_module::START_VSCODE_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 562e6d5ba4fc57..d66c55f237ea9f 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 0292c267881d81..fca1fcfeb62184 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 @@ -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 @@ -1134,8 +1134,8 @@ def scripts_configmap(workspace_name:, workspace_namespace:, labels:, annotation #!/bin/sh echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-start-sshd-command..." #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-start-sshd-command || true - echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-init-tools-command..." - #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-init-tools-command || true + echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/#{create_constants_module::START_VSCODE_COMMAND}..." + #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/#{create_constants_module::START_VSCODE_COMMAND} || true echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command..." #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command || true SCRIPT @@ -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, + "#{create_constants_module::START_VSCODE_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 -- GitLab From 7e983ac7797d799d6303ab5f43f9a688a9e4082c Mon Sep 17 00:00:00 2001 From: Daniyal Arshad Date: Tue, 20 May 2025 16:42:53 -0400 Subject: [PATCH 2/3] Address review suggestions --- .../create/create_constants.rb | 1 - .../create/main_component_updater.rb | 8 +- .../main_component_updater_start_vscode.sh | 48 +++++------ .../create/workspace_variables_builder.rb | 1 - ...ntainer-command-processed-devfile.yaml.erb | 6 +- ...le.main-container-updated-devfile.yaml.erb | 10 +-- ...ated-marketplace-disabled-devfile.yaml.erb | 10 +-- .../example.processed-devfile.yaml.erb | 10 +-- ...e.project-cloner-inserted-devfile.yaml.erb | 10 +-- ...ponent_updater_start_vscode_script_spec.rb | 79 +++++++++++-------- .../output/scripts_configmap_appender_spec.rb | 6 +- .../remote_development_shared_contexts.rb | 12 +-- 12 files changed, 107 insertions(+), 94 deletions(-) diff --git a/ee/lib/remote_development/workspace_operations/create/create_constants.rb b/ee/lib/remote_development/workspace_operations/create/create_constants.rb index 775e88523c6617..45796e0958cc65 100644 --- a/ee/lib/remote_development/workspace_operations/create/create_constants.rb +++ b/ee/lib/remote_development/workspace_operations/create/create_constants.rb @@ -19,7 +19,6 @@ module CreateConstants MAIN_COMPONENT_INDICATOR_ATTRIBUTE = "gl/inject-editor" NAMESPACE_PREFIX = "gl-rd-ns" PROJECT_CLONING_SUCCESSFUL_FILE_NAME = ".gl_project_cloning_successful" - START_VSCODE_COMMAND = "gl-start-vscode-command" TOKEN_FILE_NAME = "gl_token" TOKEN_FILE_PATH = "#{VARIABLES_VOLUME_PATH}/#{TOKEN_FILE_NAME}".freeze TOOLS_DIR_NAME = ".gl-tools" 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 9223aa8e8eed48..9b33e093f1db94 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 } ) @@ -143,7 +143,7 @@ def self.add_poststart_commands(processed_devfile:, main_component:) poststart_events << start_sshd_command_id # Add the start_vscode event - start_vscode_command_id = START_VSCODE_COMMAND + start_vscode_command_id = "gl-init-tools-command" commands << { id: start_vscode_command_id, exec: { 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 index ac76798327e016..1f11d7e5c90f7e 100644 --- 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 @@ -8,7 +8,7 @@ LOG_FILE="${GL_WORKSPACE_LOGS_DIR}/start_vscode.log" mkdir -p "$(dirname "${LOG_FILE}")" -echo "$(date -Iseconds): Vscode initialization started" +echo "$(date -Iseconds): VS Code initialization started" # Start logging exec 1>>"${LOG_FILE}" 2>&1 @@ -17,13 +17,13 @@ exec 1>>"${LOG_FILE}" 2>&1 # # # # It uses the following environment variables # # $GL_TOOLS_DIR - directory where the tools are copied. -# # $GL_EDITOR_LOG_LEVEL - log level for the server. defaults to "info". -# # $GL_EDITOR_PORT - port on which the server is exposed. defaults to "60001". -# # $GL_EDITOR_IGNORE_VERSION_MISMATCH - if set to true, the server works even when server and WebIDE versions do not match. -# # $GL_EDITOR_ENABLE_MARKETPLACE - if set to true, set configuration to enable marketplace. -# # $GL_VSCODE_EXTENSION_MARKETPLACE_SERVICE_URL - service url for the extensions gallery. -# # $GL_VSCODE_EXTENSION_MARKETPLACE_ITEM_URL - item url for the extensions gallery. -# # $GL_VSCODE_EXTENSION_MARKETPLACE_RESOURCE_URL_TEMPLATE - resource url template for the extensions gallery. +# # $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. @@ -32,14 +32,14 @@ if [ -z "${GL_TOOLS_DIR}" ]; then exit 1 fi -if [ -z "${GL_EDITOR_LOG_LEVEL}" ]; then - GL_EDITOR_LOG_LEVEL="info" - echo "$(date -Iseconds): Setting default GL_EDITOR_LOG_LEVEL=${GL_EDITOR_LOG_LEVEL}" +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_EDITOR_PORT}" ]; then - GL_EDITOR_PORT="60001" - echo "$(date -Iseconds): Setting default GL_EDITOR_PORT=${GL_EDITOR_PORT}" +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 @@ -59,7 +59,7 @@ fi PRODUCT_JSON_FILE="${GL_TOOLS_DIR}/vscode-reh-web/product.json" -if [ "$GL_EDITOR_IGNORE_VERSION_MISMATCH" = true ]; then +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 @@ -69,7 +69,7 @@ if [ "$GL_EDITOR_IGNORE_VERSION_MISMATCH" = true ]; then echo "$(date -Iseconds): Removed 'commit' key from ${PRODUCT_JSON_FILE}" fi -if [ "$GL_EDITOR_ENABLE_MARKETPLACE" = true ]; then +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" @@ -80,22 +80,22 @@ echo "$(date -Iseconds): Contents of ${PRODUCT_JSON_FILE} are: " cat "${PRODUCT_JSON_FILE}" echo -GL_EDITOR_HOST="0.0.0.0" +GL_VSCODE_HOST="0.0.0.0" echo "$(date -Iseconds): Starting server for the editor with:" -echo "$(date -Iseconds): - Host: ${GL_EDITOR_HOST}" -echo "$(date -Iseconds): - Port: ${GL_EDITOR_PORT}" -echo "$(date -Iseconds): - Log level: ${GL_EDITOR_LOG_LEVEL}" +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_EDITOR_HOST}" \ - --port "${GL_EDITOR_PORT}" \ - --log "${GL_EDITOR_LOG_LEVEL}" \ + --host "${GL_VSCODE_HOST}" \ + --port "${GL_VSCODE_PORT}" \ + --log "${GL_VSCODE_LOG_LEVEL}" \ --without-connection-token \ --disable-workspace-trust -echo "$(date -Iseconds): Vscode: Remote Extension Host process exited with code $?" +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 335759ae3a4e15..e028488b3199de 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 @@ -124,7 +124,6 @@ def self.build( #------------------------------------------------------------------- # Variables with prefix `GL_VSCODE_EXTENSION_MARKETPLACE` are used for configuring the # GitLab fork of VS Code which is injected into the workspace. - # All *_EDITOR_EXTENSIONS_GALLERY_* variables were renamed to *_VSCODE_EXTENSION_MARKETPLACE_* in 18.1 { key: "GL_VSCODE_EXTENSION_MARKETPLACE_SERVICE_URL", value: vscode_extension_marketplace_service_url, 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 26522a4a51188b..111bdc0ee470a5 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 @@ -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 0376170aecf8f9..d43b052e3f7d54 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 @@ -63,7 +63,7 @@ commands: commandLine: | <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, 8) %> component: tooling-container - - id: <%= START_VSCODE_COMMAND %> + - id: gl-init-tools-command exec: commandLine: | <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, 8) %> @@ -84,6 +84,6 @@ events: - gl-tools-injector-command postStart: - gl-start-sshd-command - - <%= START_VSCODE_COMMAND %> + - gl-init-tools-command - gl-sleep-until-container-is-running-command variables: {} 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 0376170aecf8f9..d43b052e3f7d54 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 @@ -63,7 +63,7 @@ commands: commandLine: | <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, 8) %> component: tooling-container - - id: <%= START_VSCODE_COMMAND %> + - id: gl-init-tools-command exec: commandLine: | <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, 8) %> @@ -84,6 +84,6 @@ events: - gl-tools-injector-command postStart: - gl-start-sshd-command - - <%= START_VSCODE_COMMAND %> + - gl-init-tools-command - gl-sleep-until-container-is-running-command variables: {} 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 5870c0a6e5b7b7..15407e58f23df3 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 @@ -91,7 +91,7 @@ commands: commandLine: | <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, 8) %> component: tooling-container - - id: <%= START_VSCODE_COMMAND %> + - id: gl-init-tools-command exec: commandLine: | <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, 8) %> @@ -116,6 +116,6 @@ events: - gl-project-cloner-command postStart: - gl-start-sshd-command - - <%= START_VSCODE_COMMAND %> + - gl-init-tools-command - gl-sleep-until-container-is-running-command variables: {} 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 35d22e8bfd9a8e..21cc1e4365ed70 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 @@ -76,7 +76,7 @@ commands: commandLine: | <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, 8) %> component: tooling-container - - id: <%= START_VSCODE_COMMAND %> + - id: gl-init-tools-command exec: commandLine: | <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, 8) %> @@ -101,6 +101,6 @@ events: - gl-project-cloner-command postStart: - gl-start-sshd-command - - <%= START_VSCODE_COMMAND %> + - gl-init-tools-command - gl-sleep-until-container-is-running-command variables: {} 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 index b3507f27ab542d..86089c0068cb3b 100644 --- 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 @@ -1,12 +1,14 @@ # frozen_string_literal: true -require 'spec_helper' -require 'tempfile' -require 'fileutils' +require "fast_spec_helper" +require "tempfile" +require "fileutils" + +RSpec.describe "Remote Development VSCode Startup Script", feature_category: :workspaces do + include_context "with constant modules" -RSpec.describe 'Remote Development VSCode Startup Script', feature_category: :workspaces do let(:script_content) { RemoteDevelopment::Files::MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT } - let(:script_file) { Tempfile.new(["start_vscode", ".sh"]) } + 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") } @@ -15,29 +17,36 @@ 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) { "60001" } + 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 + 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? + status = $?&.success? || false # Read the log file if it exists log_content = File.exist?(log_file_path) ? File.read(log_file_path) : nil - [result, status, log_content] + { + output: result, + success: status, + logs: log_content + } end before do @@ -48,16 +57,22 @@ def run_script(custom_env = nil) 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 exit before server execution # Script exits before running the actual server 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"}, - "exit 0 #" + mock_vscode_server_command ) script_file.write(modified_script) script_file.close - FileUtils.chmod(0o755, script_file.path) + FileUtils.chmod(0o755, script_file.path.to_s) end after do @@ -69,28 +84,28 @@ def run_script(custom_env = nil) describe "happy path script execution with default settings" do let(:env) do base_env.merge({ - "GL_EDITOR_IGNORE_VERSION_MISMATCH" => "true", - "GL_EDITOR_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 + 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[0] } - let(:status) { script_result[1] } - let(:log_content) { script_result[2] } + 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("Vscode initialization started") + 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_EDITOR_LOG_LEVEL=#{editor_log_level}") - expect(log_content).to include("Setting default GL_EDITOR_PORT=#{editor_port}") + 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 @@ -124,21 +139,21 @@ def run_script(custom_env = nil) let(:custom_editor_port) { "8080" } let(:env) do base_env.merge({ - "GL_EDITOR_LOG_LEVEL" => custom_editor_log_level, - "GL_EDITOR_PORT" => custom_editor_port + GL_VSCODE_LOG_LEVEL: custom_editor_log_level, + GL_VSCODE_PORT: custom_editor_port }) end let!(:script_result) { run_script } - let(:status) { script_result[1] } - let(:log_content) { script_result[2] } + 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_EDITOR_LOG_LEVEL") - expect(log_content).not_to include("Setting default GL_EDITOR_PORT") + 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}") @@ -147,10 +162,10 @@ def run_script(custom_env = nil) end describe "script execution without required variables" do - let(:env_without_tools) { { "GL_WORKSPACE_LOGS_DIR" => log_dir } } + let(:env_without_tools) { { GL_WORKSPACE_LOGS_DIR: log_dir } } let!(:script_result) { run_script(env_without_tools) } - let(:status) { script_result[1] } - let(:log_content) { script_result[2] } + 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 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 c296be2b02045f..00dae4adadb037 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 @@ -18,8 +18,8 @@ #!/bin/sh echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-start-sshd-command..." #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-start-sshd-command || true - echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/#{create_constants_module::START_VSCODE_COMMAND}..." - #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/#{create_constants_module::START_VSCODE_COMMAND} || true + echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-init-tools-command..." + #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-init-tools-command || true echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command..." #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command || true SCRIPT @@ -69,7 +69,7 @@ expect(api_version).to eq("v1") expect(configmap_name).to eq(name) expect(data).to eq( - "#{create_constants_module::START_VSCODE_COMMAND}": files::MAIN_COMPONENT_UPDATER_START_VSCODE_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/support/shared_contexts/remote_development/remote_development_shared_contexts.rb b/ee/spec/support/shared_contexts/remote_development/remote_development_shared_contexts.rb index fca1fcfeb62184..af4030d802aa03 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" }, { @@ -1134,8 +1134,8 @@ def scripts_configmap(workspace_name:, workspace_namespace:, labels:, annotation #!/bin/sh echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-start-sshd-command..." #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-start-sshd-command || true - echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/#{create_constants_module::START_VSCODE_COMMAND}..." - #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/#{create_constants_module::START_VSCODE_COMMAND} || true + echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-init-tools-command..." + #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-init-tools-command || true echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command..." #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command || true SCRIPT @@ -1157,7 +1157,7 @@ def scripts_configmap(workspace_name:, workspace_namespace:, labels:, annotation namespace: workspace_namespace }, data: { - "#{create_constants_module::START_VSCODE_COMMAND}": files_module::MAIN_COMPONENT_UPDATER_START_VSCODE_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 -- GitLab From 8c9a5c4b26e041bb984d47e0f5e5cb504fe13946 Mon Sep 17 00:00:00 2001 From: Daniyal Arshad Date: Fri, 23 May 2025 12:42:40 -0400 Subject: [PATCH 3/3] Update comment in script spec --- .../create/main_component_updater_start_vscode_script_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 index 86089c0068cb3b..d073cb9389cf8d 100644 --- 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 @@ -63,8 +63,8 @@ def run_script(custom_env = nil) raise "Expected VSCode server execution pattern not found in script. The script may have changed." end - # Modify the script to exit before server execution - # Script exits before running the actual server because we don't have the vscode-reh-web executables setup + # 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 -- GitLab