From 385b8686a19b7cd82bddd979deec2adb006b226f Mon Sep 17 00:00:00 2001 From: Vishal Tak Date: Fri, 23 May 2025 13:17:03 +0530 Subject: [PATCH 1/4] Move workspace project cloning to post start --- ee/lib/remote_development/files.rb | 4 +- .../workspace_operations/create/main.rb | 1 - .../create/main_component_updater.rb | 59 ++++++++- ...> main_component_updater_clone_project.sh} | 1 + .../project_cloner_component_inserter.rb | 90 ------------- ...ntainer-command-processed-devfile.yaml.erb | 6 +- ...le.main-container-updated-devfile.yaml.erb | 9 ++ ...ated-marketplace-disabled-devfile.yaml.erb | 9 ++ .../example.processed-devfile.yaml.erb | 29 ++--- ...e.project-cloner-inserted-devfile.yaml.erb | 106 --------------- .../create/main_component_updater_spec.rb | 17 ++- .../workspace_operations/create/main_spec.rb | 1 - .../project_cloner_component_inserter_spec.rb | 47 ------- .../create/volume_component_inserter_spec.rb | 2 +- ...red_config_generator_golden_master_spec.rb | 55 +++++--- .../output/scripts_configmap_appender_spec.rb | 19 +++ .../fixture_file_helpers.rb | 12 +- .../remote_development_shared_contexts.rb | 121 +++++++++++------- 18 files changed, 243 insertions(+), 345 deletions(-) rename ee/lib/remote_development/workspace_operations/create/{project_cloner_component_inserter_container_args.sh => main_component_updater_clone_project.sh} (98%) delete mode 100644 ee/lib/remote_development/workspace_operations/create/project_cloner_component_inserter.rb delete mode 100644 ee/spec/lib/remote_development/workspace_operations/create/project_cloner_component_inserter_spec.rb diff --git a/ee/lib/remote_development/files.rb b/ee/lib/remote_development/files.rb index f14c530e590b7d..9b02bf618cea67 100644 --- a/ee/lib/remote_development/files.rb +++ b/ee/lib/remote_development/files.rb @@ -32,6 +32,8 @@ def self.read_file(path) read_file("workspace_operations/create/workspace_variables_git_credential_store.sh") KUBERNETES_POSTSTART_HOOK_COMMAND = read_file("workspace_operations/reconcile/output/kubernetes_poststart_hook_command.sh") + MAIN_COMPONENT_UPDATER_CLONE_PROJECT_SCRIPT = + read_file("workspace_operations/create/main_component_updater_clone_project.sh") MAIN_COMPONENT_UPDATER_CONTAINER_ARGS = read_file("workspace_operations/create/main_component_updater_container_args.sh") MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT = @@ -40,8 +42,6 @@ def self.read_file(path) read_file("workspace_operations/create/main_component_updater_sleep_until_workspace_is_running.sh") MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT = read_file("workspace_operations/create/main_component_updater_start_sshd.sh") - PROJECTS_CLONER_COMPONENT_INSERTER_CONTAINER_ARGS = - read_file("workspace_operations/create/project_cloner_component_inserter_container_args.sh") private_class_method :read_file end diff --git a/ee/lib/remote_development/workspace_operations/create/main.rb b/ee/lib/remote_development/workspace_operations/create/main.rb index 2710ee4d29759f..aaf4d8c72762e9 100644 --- a/ee/lib/remote_development/workspace_operations/create/main.rb +++ b/ee/lib/remote_development/workspace_operations/create/main.rb @@ -25,7 +25,6 @@ def self.main(context) .map(VolumeDefiner.method(:define)) .map(ToolsInjectorComponentInserter.method(:insert)) .map(MainComponentUpdater.method(:update)) - .map(ProjectClonerComponentInserter.method(:insert)) .map(VolumeComponentInserter.method(:insert)) .and_then(Creator.method(:create)) .inspect_ok(WorkspaceObserver.method(:observe)) 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 9b33e093f1db94..bfbafcd7859e91 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 @@ -12,10 +12,21 @@ class MainComponentUpdater def self.update(context) context => { processed_devfile: Hash => processed_devfile, + params: Hash => params, tools_dir: String => tools_dir, + volume_mounts: Hash => volume_mounts, vscode_extension_marketplace_metadata: Hash => vscode_extension_marketplace_metadata } + volume_mounts => { data_volume: Hash => data_volume } + data_volume => { path: String => volume_path } + params => { + project: project, + project_ref: String => project_ref, + } + project_cloning_successful_file = "#{volume_path}/#{PROJECT_CLONING_SUCCESSFUL_FILE_NAME}" + clone_dir = "#{volume_path}/#{project.path}" + project_url = project.http_url_to_repo processed_devfile => { components: Array => components } @@ -35,7 +46,11 @@ def self.update(context) # See: https://gitlab.com/gitlab-org/gitlab/-/issues/505988 add_poststart_commands( processed_devfile: processed_devfile, - main_component: main_component + main_component: main_component, + project_cloning_successful_file: project_cloning_successful_file, + clone_dir: clone_dir, + project_ref: project_ref, + project_url: project_url ) update_env_vars( @@ -120,8 +135,19 @@ def self.update_endpoints(main_component_container:, editor_port:, ssh_port:) # @param [Hash] processed_devfile # @param [Hash] main_component + # @param [String] project_cloning_successful_file + # @param [String] clone_dir + # @param [String] project_ref + # @param [String] project_url # @return [void] - def self.add_poststart_commands(processed_devfile:, main_component:) + def self.add_poststart_commands( + processed_devfile:, + main_component:, + project_cloning_successful_file:, + clone_dir:, + project_ref:, + project_url: + ) processed_devfile => { commands: Array => commands, events: { @@ -131,6 +157,35 @@ def self.add_poststart_commands(processed_devfile:, main_component:) main_component => { name: String => main_component_name } + # Add the clone_project event + # + # The project should be cloned only if one is not cloned successfully already. + # This is required to avoid resetting user's modifications to the files. + # This is achieved by checking for the existence of a file before cloning. + # If the file does not exist, clone the project. + # To accommodate for scenarios where the project cloning failed midway in the previous attempt, + # remove the directory before cloning. + # Once cloning is successful, create the file which is used in the check above. + # This will ensure the project is not cloned again on restarts. + clone_project_command_id = "gl-clone-project-command" + clone_project_script = + format( + MAIN_COMPONENT_UPDATER_CLONE_PROJECT_SCRIPT, + project_cloning_successful_file: Shellwords.shellescape(project_cloning_successful_file), + clone_dir: Shellwords.shellescape(clone_dir), + project_ref: Shellwords.shellescape(project_ref), + project_url: Shellwords.shellescape(project_url) + ) + + commands << { + id: clone_project_command_id, + exec: { + commandLine: clone_project_script, + component: main_component_name + } + } + poststart_events << clone_project_command_id + # Add the start_sshd event start_sshd_command_id = "gl-start-sshd-command" commands << { diff --git a/ee/lib/remote_development/workspace_operations/create/project_cloner_component_inserter_container_args.sh b/ee/lib/remote_development/workspace_operations/create/main_component_updater_clone_project.sh similarity index 98% rename from ee/lib/remote_development/workspace_operations/create/project_cloner_component_inserter_container_args.sh rename to ee/lib/remote_development/workspace_operations/create/main_component_updater_clone_project.sh index 8f11fe70e9057e..fdfcf65c7ed703 100644 --- a/ee/lib/remote_development/workspace_operations/create/project_cloner_component_inserter_container_args.sh +++ b/ee/lib/remote_development/workspace_operations/create/main_component_updater_clone_project.sh @@ -1,3 +1,4 @@ +#!/bin/sh echo "$(date -Iseconds): ----------------------------------------" echo "$(date -Iseconds): Cloning project if necessary..." diff --git a/ee/lib/remote_development/workspace_operations/create/project_cloner_component_inserter.rb b/ee/lib/remote_development/workspace_operations/create/project_cloner_component_inserter.rb deleted file mode 100644 index a5c555c520df2e..00000000000000 --- a/ee/lib/remote_development/workspace_operations/create/project_cloner_component_inserter.rb +++ /dev/null @@ -1,90 +0,0 @@ -# frozen_string_literal: true - -module RemoteDevelopment - module WorkspaceOperations - module Create - class ProjectClonerComponentInserter - include CreateConstants - include Files - - PROJECT_CLONER_COMPONENT_NAME = "gl-project-cloner" - - # @param [Hash] context - # @return [Hash] - def self.insert(context) - context => { - processed_devfile: Hash => processed_devfile, - volume_mounts: Hash => volume_mounts, - params: Hash => params, - settings: Hash => settings - } - volume_mounts => { data_volume: Hash => data_volume } - data_volume => { path: String => volume_path } - params => { - project: project, - project_ref: String => project_ref, - } - settings => { - project_cloner_image: String => image, - } - project_cloning_successful_file = "#{volume_path}/#{PROJECT_CLONING_SUCCESSFUL_FILE_NAME}" - - # TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/408448 - # replace the alpine/git docker image with one that is published by gitlab for security / reliability - # reasons - clone_dir = "#{volume_path}/#{project.path}" - project_url = project.http_url_to_repo - - # The project should be cloned only if one is not cloned successfully already. - # This is required to avoid resetting user's modifications to the files. - # This is achieved by checking for the existence of a file before cloning. - # If the file does not exist, clone the project. - # To accommodate for scenarios where the project cloning failed midway in the previous attempt, - # remove the directory before cloning. - # Once cloning is successful, create the file which is used in the check above. - # This will ensure the project is not cloned again on restarts. - container_args = format(PROJECTS_CLONER_COMPONENT_INSERTER_CONTAINER_ARGS, - project_cloning_successful_file: Shellwords.shellescape(project_cloning_successful_file), - clone_dir: Shellwords.shellescape(clone_dir), - project_ref: Shellwords.shellescape(project_ref), - project_url: Shellwords.shellescape(project_url) - ) - - # TODO: https://gitlab.com/groups/gitlab-org/-/epics/10461 - # implement better error handling to allow cloner to be able to deal with different categories of errors - # issue: https://gitlab.com/gitlab-org/gitlab/-/issues/408451 - cloner_component = { - name: PROJECT_CLONER_COMPONENT_NAME, - container: { - image: image, - args: [container_args], - # command has been overridden here as the default command in the alpine/git - # container invokes git directly - command: %w[/bin/sh -c], - memoryLimit: "1000Mi", - memoryRequest: "500Mi", - cpuLimit: "500m", - cpuRequest: "100m" - } - } - - processed_devfile.fetch(:components) << cloner_component - - # create a command that will invoke the cloner - cloner_command = { - id: "#{PROJECT_CLONER_COMPONENT_NAME}-command", - apply: { - component: cloner_component[:name] - } - } - processed_devfile.fetch(:commands) << cloner_command - - # configure the workspace to run the cloner command upon workspace start - processed_devfile.fetch(:events)[:preStart] << cloner_command[:id] - - context - end - end - end - end -end 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 111bdc0ee470a5..1607dd90539035 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 @@ -72,7 +72,11 @@ components: path: "/projects" args: - | - <%= indent_yaml_literal(PROJECTS_CLONER_COMPONENT_INSERTER_CONTAINER_ARGS, 10) %> + <%= + script = MAIN_COMPONENT_UPDATER_CLONE_PROJECT_SCRIPT.dup + script.gsub!("#!/bin/sh\n", "") + indent_yaml_literal(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 d43b052e3f7d54..ff14c1e54c39e5 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 @@ -58,6 +58,14 @@ commands: - id: gl-tools-injector-command apply: component: gl-tools-injector + - id: gl-clone-project-command + exec: + commandLine: | + <%= + script = MAIN_COMPONENT_UPDATER_CLONE_PROJECT_SCRIPT + indent_yaml_literal(script, 8) + %> + component: tooling-container - id: gl-start-sshd-command exec: commandLine: | @@ -83,6 +91,7 @@ events: preStart: - gl-tools-injector-command postStart: + - gl-clone-project-command - gl-start-sshd-command - gl-init-tools-command - gl-sleep-until-container-is-running-command 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 d43b052e3f7d54..ff14c1e54c39e5 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 @@ -58,6 +58,14 @@ commands: - id: gl-tools-injector-command apply: component: gl-tools-injector + - id: gl-clone-project-command + exec: + commandLine: | + <%= + script = MAIN_COMPONENT_UPDATER_CLONE_PROJECT_SCRIPT + indent_yaml_literal(script, 8) + %> + component: tooling-container - id: gl-start-sshd-command exec: commandLine: | @@ -83,6 +91,7 @@ events: preStart: - gl-tools-injector-command postStart: + - gl-clone-project-command - gl-start-sshd-command - gl-init-tools-command - gl-sleep-until-container-is-running-command 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 15407e58f23df3..9a9e8c526ef9fd 100644 --- a/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb @@ -63,22 +63,6 @@ components: memoryRequest: 256Mi cpuLimit: 500m cpuRequest: 100m - - name: gl-project-cloner - container: - image: alpine/git:2.45.2 - volumeMounts: - - name: gl-workspace-data - path: "/projects" - args: - - | - <%= indent_yaml_literal(PROJECTS_CLONER_COMPONENT_INSERTER_CONTAINER_ARGS, 10) %> - command: - - "/bin/sh" - - "-c" - memoryLimit: 1000Mi - memoryRequest: 500Mi - cpuLimit: 500m - cpuRequest: 100m - name: gl-workspace-data volume: size: 50Gi @@ -86,6 +70,14 @@ commands: - id: gl-tools-injector-command apply: component: gl-tools-injector + - id: gl-clone-project-command + exec: + commandLine: | + <%= + script = MAIN_COMPONENT_UPDATER_CLONE_PROJECT_SCRIPT + indent_yaml_literal(script, 8) + %> + component: tooling-container - id: gl-start-sshd-command exec: commandLine: | @@ -107,14 +99,11 @@ commands: indent_yaml_literal(script, 8) %> component: tooling-container - - id: gl-project-cloner-command - apply: - component: gl-project-cloner events: preStart: - gl-tools-injector-command - - gl-project-cloner-command postStart: + - gl-clone-project-command - gl-start-sshd-command - gl-init-tools-command - gl-sleep-until-container-is-running-command 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 21cc1e4365ed70..e69de29bb2d1d6 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 @@ -1,106 +0,0 @@ ---- -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: - - | - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_CONTAINER_ARGS, 10) %> - command: - - "/bin/sh" - - "-c" - env: - - name: GL_TOOLS_DIR - value: "/projects/.gl-tools" - - name: GL_VSCODE_LOG_LEVEL - value: "info" - - name: GL_VSCODE_PORT - value: "<%= WORKSPACE_EDITOR_PORT %>" - - name: GL_SSH_PORT - value: "<%= WORKSPACE_SSH_PORT %>" - - name: GL_VSCODE_ENABLE_MARKETPLACE - value: "false" - endpoints: - - name: editor-server - targetPort: <%= WORKSPACE_EDITOR_PORT %> - exposure: public - secure: true - protocol: https - - name: ssh-server - targetPort: <%= WORKSPACE_SSH_PORT %> - exposure: internal - secure: true - dedicatedPod: false - mountSources: true - - name: database-container - container: - image: mysql - env: - - name: MYSQL_ROOT_PASSWORD - value: "my-secret-pw" - dedicatedPod: false - mountSources: true - - name: gl-tools-injector - container: - image: <%= WORKSPACE_TOOLS_IMAGE %> - env: - - name: GL_TOOLS_DIR - value: "/projects/.gl-tools" - memoryLimit: 512Mi - memoryRequest: 256Mi - cpuLimit: 500m - cpuRequest: 100m - - name: gl-project-cloner - container: - image: alpine/git:2.45.2 - args: - - | - <%= indent_yaml_literal(PROJECTS_CLONER_COMPONENT_INSERTER_CONTAINER_ARGS, 10) %> - command: - - "/bin/sh" - - "-c" - memoryLimit: 1000Mi - memoryRequest: 500Mi - cpuLimit: 500m - cpuRequest: 100m -commands: - - id: gl-tools-injector-command - apply: - component: gl-tools-injector - - id: gl-start-sshd-command - exec: - commandLine: | - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, 8) %> - component: tooling-container - - id: gl-init-tools-command - exec: - commandLine: | - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, 8) %> - component: tooling-container - - id: gl-sleep-until-container-is-running-command - exec: - commandLine: | - <%= - script = format( - MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, - workspace_reconciled_actual_state_file_path: WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH - ) - indent_yaml_literal(script, 8) - %> - component: tooling-container - - id: gl-project-cloner-command - apply: - component: gl-project-cloner -events: - preStart: - - gl-tools-injector-command - - gl-project-cloner-command - postStart: - - gl-start-sshd-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_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/main_component_updater_spec.rb index 0c955d53f5dba2..7848dc3c6861e0 100644 --- a/ee/spec/lib/remote_development/workspace_operations/create/main_component_updater_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/create/main_component_updater_spec.rb @@ -14,12 +14,27 @@ let(:vscode_extension_marketplace_metadata_enabled) { false } + let(:project_path) { "test-project" } + let(:project) do + http_url_to_repo = "#{root_url}test-group/#{project_path}.git" + instance_double("Project", path: project_path, http_url_to_repo: http_url_to_repo) # rubocop:disable RSpec/VerifiedDoubleReference -- We're using the quoted version so we can use fast_spec_helper + end + let(:context) do { + params: { + project: project, + project_ref: "master" + }, processed_devfile: input_processed_devfile, tools_dir: "#{workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH}/" \ "#{create_constants_module::TOOLS_DIR_NAME}", - vscode_extension_marketplace_metadata: { enabled: vscode_extension_marketplace_metadata_enabled } + vscode_extension_marketplace_metadata: { enabled: vscode_extension_marketplace_metadata_enabled }, + volume_mounts: { + data_volume: { + path: workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH + } + } } end diff --git a/ee/spec/lib/remote_development/workspace_operations/create/main_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/main_spec.rb index 8155c33ba55474..39e63740715254 100644 --- a/ee/spec/lib/remote_development/workspace_operations/create/main_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/create/main_spec.rb @@ -14,7 +14,6 @@ [RemoteDevelopment::WorkspaceOperations::Create::VolumeDefiner, :map], [RemoteDevelopment::WorkspaceOperations::Create::ToolsInjectorComponentInserter, :map], [RemoteDevelopment::WorkspaceOperations::Create::MainComponentUpdater, :map], - [RemoteDevelopment::WorkspaceOperations::Create::ProjectClonerComponentInserter, :map], [RemoteDevelopment::WorkspaceOperations::Create::VolumeComponentInserter, :map], [RemoteDevelopment::WorkspaceOperations::Create::Creator, :and_then], [observer_class, observer_method], diff --git a/ee/spec/lib/remote_development/workspace_operations/create/project_cloner_component_inserter_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/project_cloner_component_inserter_spec.rb deleted file mode 100644 index 947e5f1be67878..00000000000000 --- a/ee/spec/lib/remote_development/workspace_operations/create/project_cloner_component_inserter_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -require "fast_spec_helper" - -RSpec.describe RemoteDevelopment::WorkspaceOperations::Create::ProjectClonerComponentInserter, feature_category: :workspaces do - include_context 'with remote development shared fixtures' - - let(:project_path) { "test-project" } - let(:project) do - http_url_to_repo = "#{root_url}test-group/#{project_path}.git" - instance_double("Project", path: project_path, http_url_to_repo: http_url_to_repo) # rubocop:disable RSpec/VerifiedDoubleReference -- We're using the quoted version so we can use fast_spec_helper - end - - let(:input_processed_devfile) do - read_devfile("example.main-container-updated-devfile.yaml.erb") - end - - let(:expected_processed_devfile) do - read_devfile("example.project-cloner-inserted-devfile.yaml.erb") - end - - let(:context) do - { - params: { - project: project, - project_ref: "master" - }, - processed_devfile: input_processed_devfile, - volume_mounts: { - data_volume: { - path: workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH - } - }, - settings: { - project_cloner_image: 'alpine/git:2.45.2' - } - } - end - - subject(:returned_value) do - described_class.insert(context) - end - - it "injects the project cloner component" do - expect(returned_value[:processed_devfile]).to eq(expected_processed_devfile) - end -end diff --git a/ee/spec/lib/remote_development/workspace_operations/create/volume_component_inserter_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/volume_component_inserter_spec.rb index ce082214ba9251..a8c6b6f077f9ba 100644 --- a/ee/spec/lib/remote_development/workspace_operations/create/volume_component_inserter_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/create/volume_component_inserter_spec.rb @@ -6,7 +6,7 @@ include_context 'with remote development shared fixtures' let(:input_processed_devfile) do - read_devfile("example.project-cloner-inserted-devfile.yaml.erb") + read_devfile("example.main-container-updated-devfile.yaml.erb") end let(:expected_processed_devfile) do diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_golden_master_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_golden_master_spec.rb index 395bb577d52f72..4ccb3616282e0e 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_golden_master_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_golden_master_spec.rb @@ -235,14 +235,17 @@ def input_processed_devfile_yaml_with_poststart_event protocol: https dedicatedPod: false mountSources: true - - name: gl-project-cloner + - name: gl-tools-injector container: - image: alpine/git:2.45.2 + image: "gl-tools-injector:latest" volumeMounts: - name: gl-workspace-data path: "/projects" + env: + - name: GL_TOOLS_DIR + value: "/projects/.gl-tools" args: - - "echo 'project cloner container args'" + - "echo 'tools injector container args'" command: - "/bin/sh" - "-c" @@ -258,12 +261,12 @@ def input_processed_devfile_yaml_with_poststart_event exec: commandLine: "echo 'example tooling container internal command'" component: tooling-container - - id: gl-project-cloner-command + - id: gl-tools-injector-command apply: - component: gl-project-cloner + component: gl-tools-injector events: preStart: - - gl-project-cloner-command + - gl-tools-injector-command postStart: - gl-example-tooling-container-internal-command variables: {} @@ -544,13 +547,17 @@ def golden_master_desired_config_with_include_all_resources_true initContainers: [ { args: [ - "echo 'project cloner container args'" + "echo 'tools injector container args'" ], command: [ "/bin/sh", "-c" ], env: [ + { + name: "GL_TOOLS_DIR", + value: "/projects/.gl-tools" + }, { name: "PROJECTS_ROOT", value: "/projects" @@ -567,9 +574,9 @@ def golden_master_desired_config_with_include_all_resources_true } } ], - image: "alpine/git:2.45.2", + image: "gl-tools-injector:latest", imagePullPolicy: "Always", - name: "gl-project-cloner-gl-project-cloner-command-1", + name: "gl-tools-injector-gl-tools-injector-command-1", resources: { limits: { cpu: "500m", @@ -1118,13 +1125,17 @@ def golden_master_desired_config_with_include_all_resources_false initContainers: [ { args: [ - "echo 'project cloner container args'" + "echo 'tools injector container args'" ], command: [ "/bin/sh", "-c" ], env: [ + { + name: "GL_TOOLS_DIR", + value: "/projects/.gl-tools" + }, { name: "PROJECTS_ROOT", value: "/projects" @@ -1141,9 +1152,9 @@ def golden_master_desired_config_with_include_all_resources_false } } ], - image: "alpine/git:2.45.2", + image: "gl-tools-injector:latest", imagePullPolicy: "Always", - name: "gl-project-cloner-gl-project-cloner-command-1", + name: "gl-tools-injector-gl-tools-injector-command-1", resources: { limits: { cpu: "500m", @@ -2168,13 +2179,17 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources initContainers: [ { args: [ - "echo 'project cloner container args'" + "echo 'tools injector container args'" ], command: [ "/bin/sh", "-c" ], env: [ + { + name: "GL_TOOLS_DIR", + value: "/projects/.gl-tools" + }, { name: "PROJECTS_ROOT", value: "/projects" @@ -2191,9 +2206,9 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources } } ], - image: "alpine/git:2.45.2", + image: "gl-tools-injector:latest", imagePullPolicy: "Always", - name: "gl-project-cloner-gl-project-cloner-command-1", + name: "gl-tools-injector-gl-tools-injector-command-1", resources: { limits: { cpu: "500m", @@ -2730,13 +2745,17 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources initContainers: [ { args: [ - "echo 'project cloner container args'" + "echo 'tools injector container args'" ], command: [ "/bin/sh", "-c" ], env: [ + { + name: "GL_TOOLS_DIR", + value: "/projects/.gl-tools" + }, { name: "PROJECTS_ROOT", value: "/projects" @@ -2753,9 +2772,9 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources } } ], - image: "alpine/git:2.45.2", + image: "gl-tools-injector:latest", imagePullPolicy: "Always", - name: "gl-project-cloner-gl-project-cloner-command-1", + name: "gl-tools-injector-gl-tools-injector-command-1", resources: { limits: { cpu: "500m", 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 00dae4adadb037..6bd08aeafc88fa 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 @@ -16,6 +16,8 @@ let(:expected_postart_commands_script) do <<~SCRIPT #!/bin/sh + echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-clone-project-command..." + #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-clone-project-command || true 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..." @@ -25,6 +27,22 @@ SCRIPT end + let(:main_component_updater_clone_project_script) do + volume_path = workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH + project_cloning_successful_file = "#{volume_path}/#{create_constants_module::PROJECT_CLONING_SUCCESSFUL_FILE_NAME}" + clone_dir = "#{volume_path}/test-project" + project_ref = "master" + project_url = "#{root_url}test-group/test-project.git" + + format( + files::MAIN_COMPONENT_UPDATER_CLONE_PROJECT_SCRIPT, + project_cloning_successful_file: Shellwords.shellescape(project_cloning_successful_file), + clone_dir: Shellwords.shellescape(clone_dir), + project_ref: Shellwords.shellescape(project_ref), + project_url: Shellwords.shellescape(project_url) + ) + end + let(:main_component_updater_sleep_until_container_is_running_script) do format( files::MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, @@ -69,6 +87,7 @@ expect(api_version).to eq("v1") expect(configmap_name).to eq(name) expect(data).to eq( + "gl-clone-project-command": main_component_updater_clone_project_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, diff --git a/ee/spec/support/helpers/remote_development/fixture_file_helpers.rb b/ee/spec/support/helpers/remote_development/fixture_file_helpers.rb index 7dc205ac427bce..e27999c2a1fbf9 100644 --- a/ee/spec/support/helpers/remote_development/fixture_file_helpers.rb +++ b/ee/spec/support/helpers/remote_development/fixture_file_helpers.rb @@ -21,7 +21,7 @@ def read_devfile_yaml(filename, project_name: "test-project", namespace_path: "t devfile_contents.gsub!('test-project', project_name) devfile_contents.gsub!('test-group', namespace_path) - format_project_cloner_script!(devfile_contents, project_name: project_name, namespace_path: namespace_path) + format_clone_project_script!(devfile_contents, project_name: project_name, namespace_path: namespace_path) devfile_contents end @@ -43,7 +43,7 @@ def root_url # @param [String] project_name # @param [String] namespace_path # @return [void] - def format_project_cloner_script!( + def format_clone_project_script!( content, project_name: "test-project", namespace_path: "test-group" @@ -51,13 +51,13 @@ def format_project_cloner_script!( # NOTE: These replacements correspond to the `format` command in `project_cloner_component_inserter.rb` content.gsub!( "%s", - "#{WORKSPACE_DATA_VOLUME_PATH}/#{PROJECT_CLONING_SUCCESSFUL_FILE_NAME}" + Shellwords.shellescape("#{WORKSPACE_DATA_VOLUME_PATH}/#{PROJECT_CLONING_SUCCESSFUL_FILE_NAME}") ) - content.gsub!("%s", "master") - content.gsub!("%s", "#{root_url}#{namespace_path}/#{project_name}.git") + content.gsub!("%s", Shellwords.shellescape("master")) + content.gsub!("%s", Shellwords.shellescape("#{root_url}#{namespace_path}/#{project_name}.git")) content.gsub!( "%s", - "#{WORKSPACE_DATA_VOLUME_PATH}/#{project_name}" + Shellwords.shellescape("#{WORKSPACE_DATA_VOLUME_PATH}/#{project_name}") ) nil 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 af4030d802aa03..9837c87d992f80 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 @@ -605,9 +605,6 @@ def workspace_deployment( 'runAsUser' => reconcile_constants_module::RUN_AS_USER } - project_cloner_script_content = files_module::PROJECTS_CLONER_COMPONENT_INSERTER_CONTAINER_ARGS.dup - format_project_cloner_script!(project_cloner_script_content) - deployment = { apiVersion: "apps/v1", kind: "Deployment", @@ -771,51 +768,6 @@ def workspace_deployment( } ], initContainers: [ - { - args: [project_cloner_script_content], - command: %w[/bin/sh -c], - env: [ - { - name: "PROJECTS_ROOT", - value: workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH - }, - { - name: "PROJECT_SOURCE", - value: workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH - } - ], - image: "alpine/git:2.45.2", - imagePullPolicy: "Always", - name: "gl-project-cloner-gl-project-cloner-command-1", - resources: { - limits: { - cpu: "500m", - memory: "1000Mi" - }, - requests: { - cpu: "100m", - memory: "500Mi" - } - }, - volumeMounts: [ - { - mountPath: workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH, - name: create_constants_module::WORKSPACE_DATA_VOLUME_NAME - }, - { - mountPath: workspace_operations_constants_module::VARIABLES_VOLUME_PATH, - name: workspace_operations_constants_module::VARIABLES_VOLUME_NAME - } - ], - securityContext: container_security_context, - envFrom: [ - { - secretRef: { - name: "#{workspace_name}-env-var" - } - } - ] - }, { env: [ { @@ -834,7 +786,7 @@ def workspace_deployment( ], image: workspace_operations_constants_module::WORKSPACE_TOOLS_IMAGE, imagePullPolicy: "Always", - name: "gl-tools-injector-gl-tools-injector-command-2", + name: "gl-tools-injector-gl-tools-injector-command-1", resources: { limits: { cpu: "500m", @@ -925,11 +877,65 @@ def workspace_deployment( end if legacy_scripts_in_container_command + # Add the container args for the container where tools are injected deployment[:spec][:template][:spec][:containers][0][:args][0] = <<~YAML.chomp #{files_module::MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT} #{files_module::MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT} YAML + + # Insert the project cloning as the first init container + project_cloner_script_content = files_module::MAIN_COMPONENT_UPDATER_CLONE_PROJECT_SCRIPT.dup + project_cloner_script_content.gsub!("#!/bin/sh\n", "") + format_clone_project_script!(project_cloner_script_content) + + project_cloning_init_container = { + args: [project_cloner_script_content], + command: %w[/bin/sh -c], + env: [ + { + name: "PROJECTS_ROOT", + value: workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH + }, + { + name: "PROJECT_SOURCE", + value: workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH + } + ], + image: "alpine/git:2.45.2", + imagePullPolicy: "Always", + name: "gl-project-cloner-gl-project-cloner-command-1", + resources: { + limits: { + cpu: "500m", + memory: "1000Mi" + }, + requests: { + cpu: "100m", + memory: "500Mi" + } + }, + volumeMounts: [ + { + mountPath: workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH, + name: create_constants_module::WORKSPACE_DATA_VOLUME_NAME + }, + { + mountPath: workspace_operations_constants_module::VARIABLES_VOLUME_PATH, + name: workspace_operations_constants_module::VARIABLES_VOLUME_NAME + } + ], + securityContext: container_security_context, + envFrom: [ + { + secretRef: { + name: "#{workspace_name}-env-var" + } + } + ] + } + deployment[:spec][:template][:spec][:initContainers].prepend(project_cloning_init_container) + deployment[:spec][:template][:spec][:initContainers][1][:name] = "gl-tools-injector-gl-tools-injector-command-2" end deployment[:spec][:template][:spec].delete(:runtimeClassName) if default_runtime_class.empty? @@ -1132,6 +1138,8 @@ def scripts_configmap(workspace_name:, workspace_namespace:, labels:, annotation postart_commands_script = <<~SCRIPT #!/bin/sh + echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-clone-project-command..." + #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-clone-project-command || true 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..." @@ -1140,6 +1148,20 @@ def scripts_configmap(workspace_name:, workspace_namespace:, labels:, annotation #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command || true SCRIPT + volume_path = workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH + project_cloning_successful_file = "#{volume_path}/#{create_constants_module::PROJECT_CLONING_SUCCESSFUL_FILE_NAME}" + clone_dir = "#{workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH}/test-project" + project_ref = "master" + project_url = "http://localhost/test-group/test-project.git" + clone_project_script = + format( + RemoteDevelopment::Files::MAIN_COMPONENT_UPDATER_CLONE_PROJECT_SCRIPT, + project_cloning_successful_file: Shellwords.shellescape(project_cloning_successful_file), + clone_dir: Shellwords.shellescape(clone_dir), + project_ref: Shellwords.shellescape(project_ref), + project_url: Shellwords.shellescape(project_url) + ) + sleep_until_container_is_running_script = format( RemoteDevelopment::Files::MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, @@ -1157,6 +1179,7 @@ def scripts_configmap(workspace_name:, workspace_namespace:, labels:, annotation namespace: workspace_namespace }, data: { + "gl-clone-project-command": clone_project_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, -- GitLab From cd850da3b8864b6c545ece9d343935b5080bff8e Mon Sep 17 00:00:00 2001 From: Vishal Tak Date: Wed, 28 May 2025 09:34:40 +0530 Subject: [PATCH 2/4] Add step in ROP chain to insert poststart commands --- ee/lib/remote_development/files.rb | 16 +-- ...ternal_poststart_command_clone_project.sh} | 8 ++ ...mmand_sleep_until_workspace_is_running.sh} | 0 ... internal_poststart_command_start_sshd.sh} | 0 ...nternal_poststart_command_start_vscode.sh} | 0 .../internal_poststart_commands_inserter.rb | 117 +++++++++++++++++ .../workspace_operations/create/main.rb | 1 + .../create/main_component_updater.rb | 120 +----------------- ...ststart-commands-inserted-devfile.yaml.erb | 98 ++++++++++++++ ...ntainer-command-processed-devfile.yaml.erb | 6 +- ...le.main-container-updated-devfile.yaml.erb | 35 +---- ...ated-marketplace-disabled-devfile.yaml.erb | 35 +---- .../example.processed-devfile.yaml.erb | 8 +- ...ternal_poststart_commands_inserter_spec.rb | 45 +++++++ .../create/main_component_updater_spec.rb | 19 +-- ...ponent_updater_start_vscode_script_spec.rb | 2 +- .../workspace_operations/create/main_spec.rb | 1 + .../create/volume_component_inserter_spec.rb | 2 +- .../output/scripts_configmap_appender_spec.rb | 8 +- .../remote_development_shared_contexts.rb | 14 +- 20 files changed, 303 insertions(+), 232 deletions(-) rename ee/lib/remote_development/workspace_operations/create/{main_component_updater_clone_project.sh => internal_poststart_command_clone_project.sh} (62%) rename ee/lib/remote_development/workspace_operations/create/{main_component_updater_sleep_until_workspace_is_running.sh => internal_poststart_command_sleep_until_workspace_is_running.sh} (100%) rename ee/lib/remote_development/workspace_operations/create/{main_component_updater_start_sshd.sh => internal_poststart_command_start_sshd.sh} (100%) rename ee/lib/remote_development/workspace_operations/create/{main_component_updater_start_vscode.sh => internal_poststart_command_start_vscode.sh} (100%) create mode 100644 ee/lib/remote_development/workspace_operations/create/internal_poststart_commands_inserter.rb create mode 100644 ee/spec/fixtures/remote_development/example.internal-poststart-commands-inserted-devfile.yaml.erb create mode 100644 ee/spec/lib/remote_development/workspace_operations/create/internal_poststart_commands_inserter_spec.rb diff --git a/ee/lib/remote_development/files.rb b/ee/lib/remote_development/files.rb index 9b02bf618cea67..2c14889848f088 100644 --- a/ee/lib/remote_development/files.rb +++ b/ee/lib/remote_development/files.rb @@ -30,18 +30,18 @@ def self.read_file(path) DEFAULT_DEVFILE_YAML = read_file("settings/default_devfile.yaml") GIT_CREDENTIAL_STORE_SCRIPT = read_file("workspace_operations/create/workspace_variables_git_credential_store.sh") + INTERNAL_POSTSTART_COMMAND_CLONE_PROJECT_SCRIPT = + read_file("workspace_operations/create/internal_poststart_command_clone_project.sh") + INTERNAL_POSTSTART_COMMAND_START_VSCODE_SCRIPT = + read_file("workspace_operations/create/internal_poststart_command_start_vscode.sh") + INTERNAL_POSTSTART_COMMAND_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT = + read_file("workspace_operations/create/internal_poststart_command_sleep_until_workspace_is_running.sh") + INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT = + read_file("workspace_operations/create/internal_poststart_command_start_sshd.sh") KUBERNETES_POSTSTART_HOOK_COMMAND = read_file("workspace_operations/reconcile/output/kubernetes_poststart_hook_command.sh") - MAIN_COMPONENT_UPDATER_CLONE_PROJECT_SCRIPT = - read_file("workspace_operations/create/main_component_updater_clone_project.sh") MAIN_COMPONENT_UPDATER_CONTAINER_ARGS = read_file("workspace_operations/create/main_component_updater_container_args.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 = - read_file("workspace_operations/create/main_component_updater_start_sshd.sh") private_class_method :read_file end diff --git a/ee/lib/remote_development/workspace_operations/create/main_component_updater_clone_project.sh b/ee/lib/remote_development/workspace_operations/create/internal_poststart_command_clone_project.sh similarity index 62% rename from ee/lib/remote_development/workspace_operations/create/main_component_updater_clone_project.sh rename to ee/lib/remote_development/workspace_operations/create/internal_poststart_command_clone_project.sh index fdfcf65c7ed703..fe61c361fd28c5 100644 --- a/ee/lib/remote_development/workspace_operations/create/main_component_updater_clone_project.sh +++ b/ee/lib/remote_development/workspace_operations/create/internal_poststart_command_clone_project.sh @@ -2,12 +2,18 @@ echo "$(date -Iseconds): ----------------------------------------" echo "$(date -Iseconds): Cloning project if necessary..." +# The project should be cloned only if one is not cloned successfully already. +# This is required to avoid resetting user's modifications to the files. +# This is achieved by checking for the existence of a file before cloning. +# If the file does not exist, clone the project. if [ -f "%s" ] then echo "$(date -Iseconds): Project cloning was already successful" exit 0 fi +# To accommodate for scenarios where the project cloning failed midway in the previous attempt, +# remove the directory before cloning. if [ -d "%s" ] then echo "$(date -Iseconds): Removing unsuccessfully cloned project directory" @@ -18,6 +24,8 @@ echo "$(date -Iseconds): Cloning project" git clone --branch "%s" "%s" "%s" exit_code=$? +# Once cloning is successful, create the file which is used in the check above. +# This will ensure the project is not cloned again on restarts. if [ "${exit_code}" -eq 0 ] then echo "$(date -Iseconds): Project cloning successful" diff --git a/ee/lib/remote_development/workspace_operations/create/main_component_updater_sleep_until_workspace_is_running.sh b/ee/lib/remote_development/workspace_operations/create/internal_poststart_command_sleep_until_workspace_is_running.sh similarity index 100% rename from ee/lib/remote_development/workspace_operations/create/main_component_updater_sleep_until_workspace_is_running.sh rename to ee/lib/remote_development/workspace_operations/create/internal_poststart_command_sleep_until_workspace_is_running.sh diff --git a/ee/lib/remote_development/workspace_operations/create/main_component_updater_start_sshd.sh b/ee/lib/remote_development/workspace_operations/create/internal_poststart_command_start_sshd.sh similarity index 100% rename from ee/lib/remote_development/workspace_operations/create/main_component_updater_start_sshd.sh rename to ee/lib/remote_development/workspace_operations/create/internal_poststart_command_start_sshd.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/internal_poststart_command_start_vscode.sh similarity index 100% rename from ee/lib/remote_development/workspace_operations/create/main_component_updater_start_vscode.sh rename to ee/lib/remote_development/workspace_operations/create/internal_poststart_command_start_vscode.sh diff --git a/ee/lib/remote_development/workspace_operations/create/internal_poststart_commands_inserter.rb b/ee/lib/remote_development/workspace_operations/create/internal_poststart_commands_inserter.rb new file mode 100644 index 00000000000000..cfdd085b931d1b --- /dev/null +++ b/ee/lib/remote_development/workspace_operations/create/internal_poststart_commands_inserter.rb @@ -0,0 +1,117 @@ +# frozen_string_literal: true + +module RemoteDevelopment + module WorkspaceOperations + module Create + class InternalPoststartCommandsInserter + include CreateConstants + include Files + + # @param [Hash] context + # @return [Hash] + def self.insert(context) + # TODO: When user-defined postStart commands are supported, add validation in previous devfile validation + # steps of the ".../workspace_operations/create" ROP chain. + # See: https://gitlab.com/gitlab-org/gitlab/-/issues/505988 + + context => { + processed_devfile: Hash => processed_devfile, + params: Hash => params, + volume_mounts: Hash => volume_mounts, + } + + volume_mounts => { data_volume: Hash => data_volume } + data_volume => { path: String => volume_path } + params => { + project: project, + project_ref: String => project_ref, + } + project_cloning_successful_file = "#{volume_path}/#{PROJECT_CLONING_SUCCESSFUL_FILE_NAME}" + clone_dir = "#{volume_path}/#{project.path}" + project_url = project.http_url_to_repo + processed_devfile => { + components: Array => components + } + + # NOTE: We will always have exactly one main_component found, because we have already + # validated this in devfile_validator.rb + main_component = components.find do |component| + # NOTE: We can't use pattern matching here, because constants can't be used in pattern matching. + # Otherwise, we could do this all in a single pattern match. + component.dig(:attributes, MAIN_COMPONENT_INDICATOR_ATTRIBUTE.to_sym) + end + + processed_devfile => { + commands: Array => commands, + events: { + postStart: Array => poststart_events + } + } + + main_component => { name: String => main_component_name } + + # Add the clone_project event + clone_project_command_id = "gl-clone-project-command" + clone_project_script = + format( + INTERNAL_POSTSTART_COMMAND_CLONE_PROJECT_SCRIPT, + project_cloning_successful_file: Shellwords.shellescape(project_cloning_successful_file), + clone_dir: Shellwords.shellescape(clone_dir), + project_ref: Shellwords.shellescape(project_ref), + project_url: Shellwords.shellescape(project_url) + ) + + commands << { + id: clone_project_command_id, + exec: { + commandLine: clone_project_script, + component: main_component_name + } + } + poststart_events << clone_project_command_id + + # Add the start_sshd event + start_sshd_command_id = "gl-start-sshd-command" + commands << { + id: start_sshd_command_id, + exec: { + commandLine: INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT, + component: main_component_name + } + } + poststart_events << start_sshd_command_id + + # Add the start_vscode event + start_vscode_command_id = "gl-init-tools-command" + commands << { + id: start_vscode_command_id, + exec: { + commandLine: INTERNAL_POSTSTART_COMMAND_START_VSCODE_SCRIPT, + component: main_component_name + } + } + 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" + sleep_until_container_is_running_script = + format( + INTERNAL_POSTSTART_COMMAND_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, + workspace_reconciled_actual_state_file_path: WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH + ) + + commands << { + id: sleep_until_container_is_running_command_id, + exec: { + commandLine: sleep_until_container_is_running_script, + component: main_component_name + } + } + poststart_events << sleep_until_container_is_running_command_id + + context + end + end + end + end +end diff --git a/ee/lib/remote_development/workspace_operations/create/main.rb b/ee/lib/remote_development/workspace_operations/create/main.rb index aaf4d8c72762e9..46c8b6e984ff94 100644 --- a/ee/lib/remote_development/workspace_operations/create/main.rb +++ b/ee/lib/remote_development/workspace_operations/create/main.rb @@ -25,6 +25,7 @@ def self.main(context) .map(VolumeDefiner.method(:define)) .map(ToolsInjectorComponentInserter.method(:insert)) .map(MainComponentUpdater.method(:update)) + .map(InternalPoststartCommandsInserter.method(:insert)) .map(VolumeComponentInserter.method(:insert)) .and_then(Creator.method(:create)) .inspect_ok(WorkspaceObserver.method(:observe)) 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 bfbafcd7859e91..746ede00b78ee2 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 @@ -12,21 +12,10 @@ class MainComponentUpdater def self.update(context) context => { processed_devfile: Hash => processed_devfile, - params: Hash => params, tools_dir: String => tools_dir, - volume_mounts: Hash => volume_mounts, vscode_extension_marketplace_metadata: Hash => vscode_extension_marketplace_metadata } - volume_mounts => { data_volume: Hash => data_volume } - data_volume => { path: String => volume_path } - params => { - project: project, - project_ref: String => project_ref, - } - project_cloning_successful_file = "#{volume_path}/#{PROJECT_CLONING_SUCCESSFUL_FILE_NAME}" - clone_dir = "#{volume_path}/#{project.path}" - project_url = project.http_url_to_repo processed_devfile => { components: Array => components } @@ -41,18 +30,6 @@ def self.update(context) main_component_container = main_component.fetch(:container) - # TODO: When user-defined postStart commands are supported, add validation in previous devfile validation - # steps of the ".../workspace_operations/create" ROP chain. - # See: https://gitlab.com/gitlab-org/gitlab/-/issues/505988 - add_poststart_commands( - processed_devfile: processed_devfile, - main_component: main_component, - project_cloning_successful_file: project_cloning_successful_file, - clone_dir: clone_dir, - project_ref: project_ref, - project_url: project_url - ) - update_env_vars( main_component_container: main_component_container, tools_dir: tools_dir, @@ -133,101 +110,6 @@ def self.update_endpoints(main_component_container:, editor_port:, ssh_port:) nil end - # @param [Hash] processed_devfile - # @param [Hash] main_component - # @param [String] project_cloning_successful_file - # @param [String] clone_dir - # @param [String] project_ref - # @param [String] project_url - # @return [void] - def self.add_poststart_commands( - processed_devfile:, - main_component:, - project_cloning_successful_file:, - clone_dir:, - project_ref:, - project_url: - ) - processed_devfile => { - commands: Array => commands, - events: { - postStart: Array => poststart_events - } - } - - main_component => { name: String => main_component_name } - - # Add the clone_project event - # - # The project should be cloned only if one is not cloned successfully already. - # This is required to avoid resetting user's modifications to the files. - # This is achieved by checking for the existence of a file before cloning. - # If the file does not exist, clone the project. - # To accommodate for scenarios where the project cloning failed midway in the previous attempt, - # remove the directory before cloning. - # Once cloning is successful, create the file which is used in the check above. - # This will ensure the project is not cloned again on restarts. - clone_project_command_id = "gl-clone-project-command" - clone_project_script = - format( - MAIN_COMPONENT_UPDATER_CLONE_PROJECT_SCRIPT, - project_cloning_successful_file: Shellwords.shellescape(project_cloning_successful_file), - clone_dir: Shellwords.shellescape(clone_dir), - project_ref: Shellwords.shellescape(project_ref), - project_url: Shellwords.shellescape(project_url) - ) - - commands << { - id: clone_project_command_id, - exec: { - commandLine: clone_project_script, - component: main_component_name - } - } - poststart_events << clone_project_command_id - - # Add the start_sshd event - start_sshd_command_id = "gl-start-sshd-command" - commands << { - id: start_sshd_command_id, - exec: { - commandLine: MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, - component: main_component_name - } - } - poststart_events << start_sshd_command_id - - # Add the start_vscode event - start_vscode_command_id = "gl-init-tools-command" - commands << { - id: start_vscode_command_id, - exec: { - commandLine: MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, - component: main_component_name - } - } - 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" - sleep_until_container_is_running_script = - format( - MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, - workspace_reconciled_actual_state_file_path: WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH - ) - - commands << { - id: sleep_until_container_is_running_command_id, - exec: { - commandLine: sleep_until_container_is_running_script, - component: main_component_name - } - } - poststart_events << sleep_until_container_is_running_command_id - - nil - end - # @param [Hash] main_component_container # @return [void] def self.override_command_and_args(main_component_container:) @@ -241,7 +123,7 @@ def self.override_command_and_args(main_component_container:) nil end - private_class_method :update_env_vars, :update_endpoints, :add_poststart_commands, :override_command_and_args + private_class_method :update_env_vars, :update_endpoints, :override_command_and_args end end end diff --git a/ee/spec/fixtures/remote_development/example.internal-poststart-commands-inserted-devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.internal-poststart-commands-inserted-devfile.yaml.erb new file mode 100644 index 00000000000000..4f6cd4db6b108e --- /dev/null +++ b/ee/spec/fixtures/remote_development/example.internal-poststart-commands-inserted-devfile.yaml.erb @@ -0,0 +1,98 @@ +--- +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: + - | + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_CONTAINER_ARGS, 10) %> + command: + - "/bin/sh" + - "-c" + env: + - name: GL_TOOLS_DIR + value: "/projects/.gl-tools" + - name: GL_VSCODE_LOG_LEVEL + value: "info" + - name: GL_VSCODE_PORT + value: "<%= WORKSPACE_EDITOR_PORT %>" + - name: GL_SSH_PORT + value: "<%= WORKSPACE_SSH_PORT %>" + - name: GL_VSCODE_ENABLE_MARKETPLACE + value: "false" + endpoints: + - name: editor-server + targetPort: <%= WORKSPACE_EDITOR_PORT %> + exposure: public + secure: true + protocol: https + - name: ssh-server + targetPort: <%= WORKSPACE_SSH_PORT %> + exposure: internal + secure: true + dedicatedPod: false + mountSources: true + - name: database-container + container: + image: mysql + env: + - name: MYSQL_ROOT_PASSWORD + value: "my-secret-pw" + dedicatedPod: false + mountSources: true + - name: gl-tools-injector + container: + image: <%= WORKSPACE_TOOLS_IMAGE %> + env: + - name: GL_TOOLS_DIR + value: "/projects/.gl-tools" + memoryLimit: 512Mi + memoryRequest: 256Mi + cpuLimit: 500m + cpuRequest: 100m +commands: + - id: gl-tools-injector-command + apply: + component: gl-tools-injector + - id: gl-clone-project-command + exec: + commandLine: | + <%= + script = INTERNAL_POSTSTART_COMMAND_CLONE_PROJECT_SCRIPT + indent_yaml_literal(script, 8) + %> + component: tooling-container + - id: gl-start-sshd-command + exec: + commandLine: | + <%= indent_yaml_literal(INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT, 8) %> + component: tooling-container + - id: gl-init-tools-command + exec: + commandLine: | + <%= indent_yaml_literal(INTERNAL_POSTSTART_COMMAND_START_VSCODE_SCRIPT, 8) %> + component: tooling-container + - id: gl-sleep-until-container-is-running-command + exec: + commandLine: | + <%= + script = format( + INTERNAL_POSTSTART_COMMAND_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, + workspace_reconciled_actual_state_file_path: WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH + ) + indent_yaml_literal(script, 8) + %> + component: tooling-container +events: + preStart: + - gl-tools-injector-command + postStart: + - gl-clone-project-command + - gl-start-sshd-command + - gl-init-tools-command + - gl-sleep-until-container-is-running-command +variables: {} 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 1607dd90539035..e88d474cc57103 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 @@ -9,8 +9,8 @@ components: image: quay.io/mloriedo/universal-developer-image:ubi8-dw-demo args: - | - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, 10) %> - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, 10) %> + <%= indent_yaml_literal(INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT, 10) %> + <%= indent_yaml_literal(INTERNAL_POSTSTART_COMMAND_START_VSCODE_SCRIPT, 10) %> command: - "/bin/sh" - "-c" @@ -73,7 +73,7 @@ components: args: - | <%= - script = MAIN_COMPONENT_UPDATER_CLONE_PROJECT_SCRIPT.dup + script = INTERNAL_POSTSTART_COMMAND_CLONE_PROJECT_SCRIPT.dup script.gsub!("#!/bin/sh\n", "") indent_yaml_literal(script, 10) %> 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 ff14c1e54c39e5..2740b5f509fa6d 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 @@ -58,41 +58,8 @@ commands: - id: gl-tools-injector-command apply: component: gl-tools-injector - - id: gl-clone-project-command - exec: - commandLine: | - <%= - script = MAIN_COMPONENT_UPDATER_CLONE_PROJECT_SCRIPT - indent_yaml_literal(script, 8) - %> - component: tooling-container - - id: gl-start-sshd-command - exec: - commandLine: | - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, 8) %> - component: tooling-container - - id: gl-init-tools-command - exec: - commandLine: | - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, 8) %> - component: tooling-container - - id: gl-sleep-until-container-is-running-command - exec: - commandLine: | - <%= - script = format( - MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, - workspace_reconciled_actual_state_file_path: WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH - ) - indent_yaml_literal(script, 8) - %> - component: tooling-container events: preStart: - gl-tools-injector-command - postStart: - - gl-clone-project-command - - gl-start-sshd-command - - gl-init-tools-command - - gl-sleep-until-container-is-running-command + postStart: [] 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 ff14c1e54c39e5..2740b5f509fa6d 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 @@ -58,41 +58,8 @@ commands: - id: gl-tools-injector-command apply: component: gl-tools-injector - - id: gl-clone-project-command - exec: - commandLine: | - <%= - script = MAIN_COMPONENT_UPDATER_CLONE_PROJECT_SCRIPT - indent_yaml_literal(script, 8) - %> - component: tooling-container - - id: gl-start-sshd-command - exec: - commandLine: | - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, 8) %> - component: tooling-container - - id: gl-init-tools-command - exec: - commandLine: | - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, 8) %> - component: tooling-container - - id: gl-sleep-until-container-is-running-command - exec: - commandLine: | - <%= - script = format( - MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, - workspace_reconciled_actual_state_file_path: WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH - ) - indent_yaml_literal(script, 8) - %> - component: tooling-container events: preStart: - gl-tools-injector-command - postStart: - - gl-clone-project-command - - gl-start-sshd-command - - gl-init-tools-command - - gl-sleep-until-container-is-running-command + postStart: [] 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 9a9e8c526ef9fd..ea73a5c21fcf5c 100644 --- a/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb @@ -74,26 +74,26 @@ commands: exec: commandLine: | <%= - script = MAIN_COMPONENT_UPDATER_CLONE_PROJECT_SCRIPT + script = INTERNAL_POSTSTART_COMMAND_CLONE_PROJECT_SCRIPT indent_yaml_literal(script, 8) %> component: tooling-container - id: gl-start-sshd-command exec: commandLine: | - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, 8) %> + <%= indent_yaml_literal(INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT, 8) %> component: tooling-container - id: gl-init-tools-command exec: commandLine: | - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, 8) %> + <%= indent_yaml_literal(INTERNAL_POSTSTART_COMMAND_START_VSCODE_SCRIPT, 8) %> component: tooling-container - id: gl-sleep-until-container-is-running-command exec: commandLine: | <%= script = format( - MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, + INTERNAL_POSTSTART_COMMAND_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, workspace_reconciled_actual_state_file_path: WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH ) indent_yaml_literal(script, 8) diff --git a/ee/spec/lib/remote_development/workspace_operations/create/internal_poststart_commands_inserter_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/internal_poststart_commands_inserter_spec.rb new file mode 100644 index 00000000000000..2d60c336a9d8fe --- /dev/null +++ b/ee/spec/lib/remote_development/workspace_operations/create/internal_poststart_commands_inserter_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require "fast_spec_helper" + +RSpec.describe RemoteDevelopment::WorkspaceOperations::Create::InternalPoststartCommandsInserter, feature_category: :workspaces do + include_context 'with remote development shared fixtures' + + let(:input_processed_devfile) do + read_devfile("example.main-container-updated-devfile.yaml.erb") + end + + let(:expected_processed_devfile_name) { "example.internal-poststart-commands-inserted-devfile.yaml.erb" } + let(:expected_processed_devfile) { read_devfile(expected_processed_devfile_name) } + + let(:project_path) { "test-project" } + let(:project) do + http_url_to_repo = "#{root_url}test-group/#{project_path}.git" + instance_double("Project", path: project_path, http_url_to_repo: http_url_to_repo) # rubocop:disable RSpec/VerifiedDoubleReference -- We're using the quoted version so we can use fast_spec_helper + end + + let(:context) do + { + params: { + project: project, + project_ref: "master" + }, + processed_devfile: input_processed_devfile, + tools_dir: "#{workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH}/" \ + "#{create_constants_module::TOOLS_DIR_NAME}", + volume_mounts: { + data_volume: { + path: workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH + } + } + } + end + + subject(:returned_value) do + described_class.insert(context) + end + + it 'updates the devfile' do + expect(returned_value[:processed_devfile]).to eq(expected_processed_devfile) + end +end diff --git a/ee/spec/lib/remote_development/workspace_operations/create/main_component_updater_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/main_component_updater_spec.rb index 7848dc3c6861e0..d454ee7ed587de 100644 --- a/ee/spec/lib/remote_development/workspace_operations/create/main_component_updater_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/create/main_component_updater_spec.rb @@ -14,27 +14,12 @@ let(:vscode_extension_marketplace_metadata_enabled) { false } - let(:project_path) { "test-project" } - let(:project) do - http_url_to_repo = "#{root_url}test-group/#{project_path}.git" - instance_double("Project", path: project_path, http_url_to_repo: http_url_to_repo) # rubocop:disable RSpec/VerifiedDoubleReference -- We're using the quoted version so we can use fast_spec_helper - end - let(:context) do { - params: { - project: project, - project_ref: "master" - }, processed_devfile: input_processed_devfile, tools_dir: "#{workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH}/" \ "#{create_constants_module::TOOLS_DIR_NAME}", - vscode_extension_marketplace_metadata: { enabled: vscode_extension_marketplace_metadata_enabled }, - volume_mounts: { - data_volume: { - path: workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH - } - } + vscode_extension_marketplace_metadata: { enabled: vscode_extension_marketplace_metadata_enabled } } end @@ -53,7 +38,7 @@ end context "when vscode_extension_marketplace_metadata Web IDE setting is disabled" do - let(:expected_processed_devfile_name) { 'example.main-container-updated-marketplace-disabled-devfile.yaml.erb' } + let(:expected_processed_devfile_name) { "example.main-container-updated-marketplace-disabled-devfile.yaml.erb" } let(:vscode_extension_marketplace_metadata_enabled) { false } it 'injects the tools injector component' do 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 d073cb9389cf8d..411fd14f7af5c0 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 @@ -7,7 +7,7 @@ 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_content) { RemoteDevelopment::Files::INTERNAL_POSTSTART_COMMAND_START_VSCODE_SCRIPT } let(:script_file) { Tempfile.new(%w[start_vscode .sh]) } let(:log_dir) { Dir.mktmpdir } let(:tools_dir) { Dir.mktmpdir } diff --git a/ee/spec/lib/remote_development/workspace_operations/create/main_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/main_spec.rb index 39e63740715254..664520733f950b 100644 --- a/ee/spec/lib/remote_development/workspace_operations/create/main_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/create/main_spec.rb @@ -14,6 +14,7 @@ [RemoteDevelopment::WorkspaceOperations::Create::VolumeDefiner, :map], [RemoteDevelopment::WorkspaceOperations::Create::ToolsInjectorComponentInserter, :map], [RemoteDevelopment::WorkspaceOperations::Create::MainComponentUpdater, :map], + [RemoteDevelopment::WorkspaceOperations::Create::InternalPoststartCommandsInserter, :map], [RemoteDevelopment::WorkspaceOperations::Create::VolumeComponentInserter, :map], [RemoteDevelopment::WorkspaceOperations::Create::Creator, :and_then], [observer_class, observer_method], diff --git a/ee/spec/lib/remote_development/workspace_operations/create/volume_component_inserter_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/volume_component_inserter_spec.rb index a8c6b6f077f9ba..8015413d36d014 100644 --- a/ee/spec/lib/remote_development/workspace_operations/create/volume_component_inserter_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/create/volume_component_inserter_spec.rb @@ -6,7 +6,7 @@ include_context 'with remote development shared fixtures' let(:input_processed_devfile) do - read_devfile("example.main-container-updated-devfile.yaml.erb") + read_devfile("example.internal-poststart-commands-inserted-devfile.yaml.erb") end let(:expected_processed_devfile) do 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 6bd08aeafc88fa..837dabaf562671 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 @@ -35,7 +35,7 @@ project_url = "#{root_url}test-group/test-project.git" format( - files::MAIN_COMPONENT_UPDATER_CLONE_PROJECT_SCRIPT, + files::INTERNAL_POSTSTART_COMMAND_CLONE_PROJECT_SCRIPT, project_cloning_successful_file: Shellwords.shellescape(project_cloning_successful_file), clone_dir: Shellwords.shellescape(clone_dir), project_ref: Shellwords.shellescape(project_ref), @@ -45,7 +45,7 @@ let(:main_component_updater_sleep_until_container_is_running_script) do format( - files::MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, + files::INTERNAL_POSTSTART_COMMAND_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, workspace_reconciled_actual_state_file_path: workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH ) @@ -88,12 +88,12 @@ expect(configmap_name).to eq(name) expect(data).to eq( "gl-clone-project-command": main_component_updater_clone_project_script, - "gl-init-tools-command": files::MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, + "gl-init-tools-command": files::INTERNAL_POSTSTART_COMMAND_START_VSCODE_SCRIPT, reconcile_constants_module::RUN_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => expected_postart_commands_script, "gl-sleep-until-container-is-running-command": main_component_updater_sleep_until_container_is_running_script, - "gl-start-sshd-command": files::MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT + "gl-start-sshd-command": files::INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT ) end end diff --git a/ee/spec/support/shared_contexts/remote_development/remote_development_shared_contexts.rb b/ee/spec/support/shared_contexts/remote_development/remote_development_shared_contexts.rb index 9837c87d992f80..1e478ee8858551 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 @@ -880,12 +880,12 @@ def workspace_deployment( # Add the container args for the container where tools are injected deployment[:spec][:template][:spec][:containers][0][:args][0] = <<~YAML.chomp - #{files_module::MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT} - #{files_module::MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT} + #{files_module::INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT} + #{files_module::INTERNAL_POSTSTART_COMMAND_START_VSCODE_SCRIPT} YAML # Insert the project cloning as the first init container - project_cloner_script_content = files_module::MAIN_COMPONENT_UPDATER_CLONE_PROJECT_SCRIPT.dup + project_cloner_script_content = files_module::INTERNAL_POSTSTART_COMMAND_CLONE_PROJECT_SCRIPT.dup project_cloner_script_content.gsub!("#!/bin/sh\n", "") format_clone_project_script!(project_cloner_script_content) @@ -1155,7 +1155,7 @@ def scripts_configmap(workspace_name:, workspace_namespace:, labels:, annotation project_url = "http://localhost/test-group/test-project.git" clone_project_script = format( - RemoteDevelopment::Files::MAIN_COMPONENT_UPDATER_CLONE_PROJECT_SCRIPT, + RemoteDevelopment::Files::INTERNAL_POSTSTART_COMMAND_CLONE_PROJECT_SCRIPT, project_cloning_successful_file: Shellwords.shellescape(project_cloning_successful_file), clone_dir: Shellwords.shellescape(clone_dir), project_ref: Shellwords.shellescape(project_ref), @@ -1164,7 +1164,7 @@ def scripts_configmap(workspace_name:, workspace_namespace:, labels:, annotation sleep_until_container_is_running_script = format( - RemoteDevelopment::Files::MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, + RemoteDevelopment::Files::INTERNAL_POSTSTART_COMMAND_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, workspace_reconciled_actual_state_file_path: workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH ) @@ -1180,10 +1180,10 @@ def scripts_configmap(workspace_name:, workspace_namespace:, labels:, annotation }, data: { "gl-clone-project-command": clone_project_script, - "gl-init-tools-command": files_module::MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, + "gl-init-tools-command": files_module::INTERNAL_POSTSTART_COMMAND_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 + "gl-start-sshd-command": files_module::INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT } } end -- GitLab From 8e1a88ba4addb2266d7514eaae4abc4f78a4866c Mon Sep 17 00:00:00 2001 From: Vishal Tak Date: Wed, 28 May 2025 09:45:31 +0530 Subject: [PATCH 3/4] Update golden master spec to be generic --- ...red_config_generator_golden_master_spec.rb | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_golden_master_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_golden_master_spec.rb index 4ccb3616282e0e..cfbcabeeed261d 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_golden_master_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_golden_master_spec.rb @@ -235,17 +235,17 @@ def input_processed_devfile_yaml_with_poststart_event protocol: https dedicatedPod: false mountSources: true - - name: gl-tools-injector + - name: sidecar-container container: - image: "gl-tools-injector:latest" + image: "sidecar-container:latest" volumeMounts: - name: gl-workspace-data path: "/projects" env: - - name: GL_TOOLS_DIR - value: "/projects/.gl-tools" + - name: GL_ENV2_NAME + value: "gl-env2-value" args: - - "echo 'tools injector container args'" + - "echo 'sidecar container args'" command: - "/bin/sh" - "-c" @@ -257,18 +257,18 @@ def input_processed_devfile_yaml_with_poststart_event volume: size: 50Gi commands: - - id: gl-example-tooling-container-internal-command + - id: example-poststart-exec-command exec: - commandLine: "echo 'example tooling container internal command'" + commandLine: "echo 'example poststart exec command'" component: tooling-container - - id: gl-tools-injector-command + - id: example-prestart-apply-command apply: - component: gl-tools-injector + component: sidecar-container events: preStart: - - gl-tools-injector-command + - example-prestart-apply-command postStart: - - gl-example-tooling-container-internal-command + - example-poststart-exec-command variables: {} YAML end @@ -547,7 +547,7 @@ def golden_master_desired_config_with_include_all_resources_true initContainers: [ { args: [ - "echo 'tools injector container args'" + "echo 'sidecar container args'" ], command: [ "/bin/sh", @@ -555,8 +555,8 @@ def golden_master_desired_config_with_include_all_resources_true ], env: [ { - name: "GL_TOOLS_DIR", - value: "/projects/.gl-tools" + name: "GL_ENV2_NAME", + value: "gl-env2-value" }, { name: "PROJECTS_ROOT", @@ -574,9 +574,9 @@ def golden_master_desired_config_with_include_all_resources_true } } ], - image: "gl-tools-injector:latest", + image: "sidecar-container:latest", imagePullPolicy: "Always", - name: "gl-tools-injector-gl-tools-injector-command-1", + name: "sidecar-container-example-prestart-apply-command-1", resources: { limits: { cpu: "500m", @@ -855,8 +855,8 @@ def golden_master_desired_config_with_include_all_resources_true namespace: "gl-rd-ns-991-990-fedcba" }, data: { - "gl-run-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): Running /workspace-scripts/gl-example-tooling-container-internal-command...\"\n/workspace-scripts/gl-example-tooling-container-internal-command || true\n", - "gl-example-tooling-container-internal-command": "echo 'example tooling container internal command'" + "gl-run-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): Running /workspace-scripts/example-poststart-exec-command...\"\n/workspace-scripts/example-poststart-exec-command || true\n", + "example-poststart-exec-command": "echo 'example poststart exec command'" } }, { @@ -1125,7 +1125,7 @@ def golden_master_desired_config_with_include_all_resources_false initContainers: [ { args: [ - "echo 'tools injector container args'" + "echo 'sidecar container args'" ], command: [ "/bin/sh", @@ -1133,8 +1133,8 @@ def golden_master_desired_config_with_include_all_resources_false ], env: [ { - name: "GL_TOOLS_DIR", - value: "/projects/.gl-tools" + name: "GL_ENV2_NAME", + value: "gl-env2-value" }, { name: "PROJECTS_ROOT", @@ -1152,9 +1152,9 @@ def golden_master_desired_config_with_include_all_resources_false } } ], - image: "gl-tools-injector:latest", + image: "sidecar-container:latest", imagePullPolicy: "Always", - name: "gl-tools-injector-gl-tools-injector-command-1", + name: "sidecar-container-example-prestart-apply-command-1", resources: { limits: { cpu: "500m", @@ -1433,8 +1433,8 @@ def golden_master_desired_config_with_include_all_resources_false namespace: "gl-rd-ns-991-990-fedcba" }, data: { - "gl-run-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): Running /workspace-scripts/gl-example-tooling-container-internal-command...\"\n/workspace-scripts/gl-example-tooling-container-internal-command || true\n", - "gl-example-tooling-container-internal-command": "echo 'example tooling container internal command'" + "gl-run-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): Running /workspace-scripts/example-poststart-exec-command...\"\n/workspace-scripts/example-poststart-exec-command || true\n", + "example-poststart-exec-command": "echo 'example poststart exec command'" } } ] @@ -2179,7 +2179,7 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources initContainers: [ { args: [ - "echo 'tools injector container args'" + "echo 'sidecar container args'" ], command: [ "/bin/sh", @@ -2187,8 +2187,8 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources ], env: [ { - name: "GL_TOOLS_DIR", - value: "/projects/.gl-tools" + name: "GL_ENV2_NAME", + value: "gl-env2-value" }, { name: "PROJECTS_ROOT", @@ -2206,9 +2206,9 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources } } ], - image: "gl-tools-injector:latest", + image: "sidecar-container:latest", imagePullPolicy: "Always", - name: "gl-tools-injector-gl-tools-injector-command-1", + name: "sidecar-container-example-prestart-apply-command-1", resources: { limits: { cpu: "500m", @@ -2497,8 +2497,8 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources namespace: "default" }, data: { - "gl-run-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): Running /workspace-scripts/gl-example-tooling-container-internal-command...\"\n/workspace-scripts/gl-example-tooling-container-internal-command || true\n", - "gl-example-tooling-container-internal-command": "echo 'example tooling container internal command'" + "gl-run-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): Running /workspace-scripts/example-poststart-exec-command...\"\n/workspace-scripts/example-poststart-exec-command || true\n", + "example-poststart-exec-command": "echo 'example poststart exec command'" } }, { @@ -2745,7 +2745,7 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources initContainers: [ { args: [ - "echo 'tools injector container args'" + "echo 'sidecar container args'" ], command: [ "/bin/sh", @@ -2753,8 +2753,8 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources ], env: [ { - name: "GL_TOOLS_DIR", - value: "/projects/.gl-tools" + name: "GL_ENV2_NAME", + value: "gl-env2-value" }, { name: "PROJECTS_ROOT", @@ -2772,9 +2772,9 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources } } ], - image: "gl-tools-injector:latest", + image: "sidecar-container:latest", imagePullPolicy: "Always", - name: "gl-tools-injector-gl-tools-injector-command-1", + name: "sidecar-container-example-prestart-apply-command-1", resources: { limits: { cpu: "500m", @@ -3063,8 +3063,8 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources namespace: "default" }, data: { - "gl-run-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): Running /workspace-scripts/gl-example-tooling-container-internal-command...\"\n/workspace-scripts/gl-example-tooling-container-internal-command || true\n", - "gl-example-tooling-container-internal-command": "echo 'example tooling container internal command'" + "gl-run-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): Running /workspace-scripts/example-poststart-exec-command...\"\n/workspace-scripts/example-poststart-exec-command || true\n", + "example-poststart-exec-command": "echo 'example poststart exec command'" } } ] -- GitLab From f684c801de27d0de2589ecc88b64ec7c51747142 Mon Sep 17 00:00:00 2001 From: Vishal Tak Date: Thu, 29 May 2025 08:41:42 +0530 Subject: [PATCH 4/4] Reuse shared fixtures --- .../internal_poststart_commands_inserter.rb | 53 +++++++------- .../create/main_component_updater.rb | 8 +-- .../output/scripts_configmap_appender_spec.rb | 43 +---------- .../remote_development_shared_contexts.rb | 72 ++++++++++--------- 4 files changed, 69 insertions(+), 107 deletions(-) diff --git a/ee/lib/remote_development/workspace_operations/create/internal_poststart_commands_inserter.rb b/ee/lib/remote_development/workspace_operations/create/internal_poststart_commands_inserter.rb index cfdd085b931d1b..a71a35cee7c578 100644 --- a/ee/lib/remote_development/workspace_operations/create/internal_poststart_commands_inserter.rb +++ b/ee/lib/remote_development/workspace_operations/create/internal_poststart_commands_inserter.rb @@ -15,40 +15,25 @@ def self.insert(context) # See: https://gitlab.com/gitlab-org/gitlab/-/issues/505988 context => { - processed_devfile: Hash => processed_devfile, - params: Hash => params, - volume_mounts: Hash => volume_mounts, + processed_devfile: { + components: Array => components, + commands: Array => commands, + events: { + postStart: Array => poststart_events + } + }, + params: { + project: project, + project_ref: String => project_ref, + }, + volume_mounts: { + data_volume: { path: String => volume_path } + }, } - volume_mounts => { data_volume: Hash => data_volume } - data_volume => { path: String => volume_path } - params => { - project: project, - project_ref: String => project_ref, - } project_cloning_successful_file = "#{volume_path}/#{PROJECT_CLONING_SUCCESSFUL_FILE_NAME}" clone_dir = "#{volume_path}/#{project.path}" project_url = project.http_url_to_repo - processed_devfile => { - components: Array => components - } - - # NOTE: We will always have exactly one main_component found, because we have already - # validated this in devfile_validator.rb - main_component = components.find do |component| - # NOTE: We can't use pattern matching here, because constants can't be used in pattern matching. - # Otherwise, we could do this all in a single pattern match. - component.dig(:attributes, MAIN_COMPONENT_INDICATOR_ATTRIBUTE.to_sym) - end - - processed_devfile => { - commands: Array => commands, - events: { - postStart: Array => poststart_events - } - } - - main_component => { name: String => main_component_name } # Add the clone_project event clone_project_command_id = "gl-clone-project-command" @@ -61,6 +46,16 @@ def self.insert(context) project_url: Shellwords.shellescape(project_url) ) + # NOTE: We will always have exactly one main_component found, because we have already + # validated this in devfile_validator.rb + main_component = components.find do |component| + # NOTE: We can't use pattern matching here, because constants can't be used in pattern matching. + # Otherwise, we could do this all in a single pattern match. + component.dig(:attributes, MAIN_COMPONENT_INDICATOR_ATTRIBUTE.to_sym) + end + + main_component => { name: String => main_component_name } + commands << { id: clone_project_command_id, exec: { 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 746ede00b78ee2..20867ee3b6fa8f 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 @@ -11,15 +11,13 @@ class MainComponentUpdater # @return [Hash] def self.update(context) context => { - processed_devfile: Hash => processed_devfile, + processed_devfile: { + components: Array => components + }, tools_dir: String => tools_dir, vscode_extension_marketplace_metadata: Hash => vscode_extension_marketplace_metadata } - processed_devfile => { - components: Array => components - } - # NOTE: We will always have exactly one main_component found, because we have already # validated this in devfile_validator.rb main_component = components.find do |component| 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 837dabaf562671..f9e81477315d17 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 @@ -13,43 +13,6 @@ let(:processed_devfile) { example_processed_devfile } let(:devfile_commands) { processed_devfile.fetch(:commands) } let(:devfile_events) { processed_devfile.fetch(:events) } - let(:expected_postart_commands_script) do - <<~SCRIPT - #!/bin/sh - echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-clone-project-command..." - #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-clone-project-command || true - 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}/gl-sleep-until-container-is-running-command..." - #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command || true - SCRIPT - end - - let(:main_component_updater_clone_project_script) do - volume_path = workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH - project_cloning_successful_file = "#{volume_path}/#{create_constants_module::PROJECT_CLONING_SUCCESSFUL_FILE_NAME}" - clone_dir = "#{volume_path}/test-project" - project_ref = "master" - project_url = "#{root_url}test-group/test-project.git" - - format( - files::INTERNAL_POSTSTART_COMMAND_CLONE_PROJECT_SCRIPT, - project_cloning_successful_file: Shellwords.shellescape(project_cloning_successful_file), - clone_dir: Shellwords.shellescape(clone_dir), - project_ref: Shellwords.shellescape(project_ref), - project_url: Shellwords.shellescape(project_url) - ) - end - - let(:main_component_updater_sleep_until_container_is_running_script) do - format( - files::INTERNAL_POSTSTART_COMMAND_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, - workspace_reconciled_actual_state_file_path: - workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH - ) - end subject(:updated_desired_config) do # Make a fake desired config with one existing fake element, to prove we are appending @@ -87,12 +50,12 @@ expect(api_version).to eq("v1") expect(configmap_name).to eq(name) expect(data).to eq( - "gl-clone-project-command": main_component_updater_clone_project_script, + "gl-clone-project-command": clone_project_script, "gl-init-tools-command": files::INTERNAL_POSTSTART_COMMAND_START_VSCODE_SCRIPT, reconcile_constants_module::RUN_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => - expected_postart_commands_script, + postart_commands_script, "gl-sleep-until-container-is-running-command": - main_component_updater_sleep_until_container_is_running_script, + sleep_until_container_is_running_script, "gl-start-sshd-command": files::INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT ) end diff --git a/ee/spec/support/shared_contexts/remote_development/remote_development_shared_contexts.rb b/ee/spec/support/shared_contexts/remote_development/remote_development_shared_contexts.rb index 1e478ee8858551..8f96456bef6160 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 @@ -1129,46 +1129,52 @@ def workspace_network_policy( } end - # @param [String] workspace_name - # @param [String] workspace_namespace - # @param [Hash] labels - # @param [Hash] annotations - # @return [Hash] - def scripts_configmap(workspace_name:, workspace_namespace:, labels:, annotations:) - postart_commands_script = - <<~SCRIPT - #!/bin/sh - echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-clone-project-command..." - #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-clone-project-command || true - 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}/gl-sleep-until-container-is-running-command..." - #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command || true - SCRIPT + # @return [String] + def postart_commands_script + <<~SCRIPT + #!/bin/sh + echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-clone-project-command..." + #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-clone-project-command || true + 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}/gl-sleep-until-container-is-running-command..." + #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command || true + SCRIPT + end + # @return [String] + def clone_project_script volume_path = workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH project_cloning_successful_file = "#{volume_path}/#{create_constants_module::PROJECT_CLONING_SUCCESSFUL_FILE_NAME}" clone_dir = "#{workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH}/test-project" project_ref = "master" - project_url = "http://localhost/test-group/test-project.git" - clone_project_script = - format( - RemoteDevelopment::Files::INTERNAL_POSTSTART_COMMAND_CLONE_PROJECT_SCRIPT, - project_cloning_successful_file: Shellwords.shellescape(project_cloning_successful_file), - clone_dir: Shellwords.shellescape(clone_dir), - project_ref: Shellwords.shellescape(project_ref), - project_url: Shellwords.shellescape(project_url) - ) + project_url = "#{root_url}test-group/test-project.git" + format( + RemoteDevelopment::Files::INTERNAL_POSTSTART_COMMAND_CLONE_PROJECT_SCRIPT, + project_cloning_successful_file: Shellwords.shellescape(project_cloning_successful_file), + clone_dir: Shellwords.shellescape(clone_dir), + project_ref: Shellwords.shellescape(project_ref), + project_url: Shellwords.shellescape(project_url) + ) + end - sleep_until_container_is_running_script = - format( - RemoteDevelopment::Files::INTERNAL_POSTSTART_COMMAND_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, - workspace_reconciled_actual_state_file_path: - workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH - ) + # @return [String] + def sleep_until_container_is_running_script + format( + RemoteDevelopment::Files::INTERNAL_POSTSTART_COMMAND_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, + workspace_reconciled_actual_state_file_path: + workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH + ) + end + # @param [String] workspace_name + # @param [String] workspace_namespace + # @param [Hash] labels + # @param [Hash] annotations + # @return [Hash] + def scripts_configmap(workspace_name:, workspace_namespace:, labels:, annotations:) { apiVersion: "v1", kind: "ConfigMap", -- GitLab