diff --git a/ee/lib/remote_development/files.rb b/ee/lib/remote_development/files.rb index f14c530e590b7d583fb182f5cbeffe4d33a190da..2c14889848f08884328e5148b4903ab894df5bb7 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_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") - 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/project_cloner_component_inserter_container_args.sh b/ee/lib/remote_development/workspace_operations/create/internal_poststart_command_clone_project.sh similarity index 61% 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/internal_poststart_command_clone_project.sh index 8f11fe70e9057e3dc828af96f90e5d21f124156f..fe61c361fd28c59148f3bf17be0ce13e7c4502eb 100644 --- a/ee/lib/remote_development/workspace_operations/create/project_cloner_component_inserter_container_args.sh +++ b/ee/lib/remote_development/workspace_operations/create/internal_poststart_command_clone_project.sh @@ -1,12 +1,19 @@ +#!/bin/sh 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" @@ -17,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 0000000000000000000000000000000000000000..a71a35cee7c578a467c51327c24a09c352bf9e32 --- /dev/null +++ b/ee/lib/remote_development/workspace_operations/create/internal_poststart_commands_inserter.rb @@ -0,0 +1,112 @@ +# 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: { + 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 } + }, + } + + project_cloning_successful_file = "#{volume_path}/#{PROJECT_CLONING_SUCCESSFUL_FILE_NAME}" + clone_dir = "#{volume_path}/#{project.path}" + project_url = project.http_url_to_repo + + # 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) + ) + + # 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: { + 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 2710ee4d29759f719735b4fa455ea6f2da804468..46c8b6e984ff94ca3348a968b9d01d804ee6a7f9 100644 --- a/ee/lib/remote_development/workspace_operations/create/main.rb +++ b/ee/lib/remote_development/workspace_operations/create/main.rb @@ -25,7 +25,7 @@ def self.main(context) .map(VolumeDefiner.method(:define)) .map(ToolsInjectorComponentInserter.method(:insert)) .map(MainComponentUpdater.method(:update)) - .map(ProjectClonerComponentInserter.method(:insert)) + .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 9b33e093f1db94f45c9ac8f151682e8e35f5c60e..20867ee3b6fa8ff00a35507ce4341971c65aa144 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| @@ -30,14 +28,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 - ) - update_env_vars( main_component_container: main_component_container, tools_dir: tools_dir, @@ -118,61 +108,6 @@ def self.update_endpoints(main_component_container:, editor_port:, ssh_port:) nil end - # @param [Hash] processed_devfile - # @param [Hash] main_component - # @return [void] - def self.add_poststart_commands(processed_devfile:, main_component:) - processed_devfile => { - commands: Array => commands, - events: { - postStart: Array => poststart_events - } - } - - main_component => { name: String => main_component_name } - - # 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:) @@ -186,7 +121,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/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 a5c555c520df2e2d0d98e7c05339e7b5110462cb..0000000000000000000000000000000000000000 --- 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.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 0000000000000000000000000000000000000000..4f6cd4db6b108e7b7fc62de5d37db764f247f0f6 --- /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 111bdc0ee470a561ca4859ecd6141b88cd14215f..e88d474cc571031c8613bff8c0f58a47dd37f2d8 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" @@ -72,7 +72,11 @@ components: path: "/projects" args: - | - <%= indent_yaml_literal(PROJECTS_CLONER_COMPONENT_INSERTER_CONTAINER_ARGS, 10) %> + <%= + script = INTERNAL_POSTSTART_COMMAND_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 d43b052e3f7d546778af0817b410f2edd5cbe6ee..2740b5f509fa6d2b8c5185f7b4f94a276ed198f5 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,32 +58,8 @@ 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 events: preStart: - gl-tools-injector-command - postStart: - - 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 d43b052e3f7d546778af0817b410f2edd5cbe6ee..2740b5f509fa6d2b8c5185f7b4f94a276ed198f5 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,32 +58,8 @@ 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 events: preStart: - gl-tools-injector-command - postStart: - - 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 15407e58f23df388878507a96dda6d8a3a0de1e7..ea73a5c21fcf5c7222b5b6f66107de9c8e5ec06e 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,35 +70,40 @@ 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(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) %> 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 21cc1e4365ed70b3479a266656eab3a457624305..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 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/project_cloner_component_inserter_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/internal_poststart_commands_inserter_spec.rb similarity index 67% rename from ee/spec/lib/remote_development/workspace_operations/create/project_cloner_component_inserter_spec.rb rename to ee/spec/lib/remote_development/workspace_operations/create/internal_poststart_commands_inserter_spec.rb index 947e5f1be67878547492c80f9473a03705888b65..2d60c336a9d8fee1f7eb1d9443093d28537c42ec 100644 --- a/ee/spec/lib/remote_development/workspace_operations/create/project_cloner_component_inserter_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/create/internal_poststart_commands_inserter_spec.rb @@ -2,21 +2,20 @@ require "fast_spec_helper" -RSpec.describe RemoteDevelopment::WorkspaceOperations::Create::ProjectClonerComponentInserter, feature_category: :workspaces do +RSpec.describe RemoteDevelopment::WorkspaceOperations::Create::InternalPoststartCommandsInserter, 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") + 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 @@ -26,13 +25,12 @@ 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 } - }, - settings: { - project_cloner_image: 'alpine/git:2.45.2' } } end @@ -41,7 +39,7 @@ described_class.insert(context) end - it "injects the project cloner component" do + 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 0c955d53f5dba279ad26bca3c82e3a3141440804..d454ee7ed587de6273d835fd0e9616833af54d57 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 @@ -38,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 d073cb9389cf8d90898881142e435a32f916e468..411fd14f7af5c0fffffb6efac24a43a0159f2aa4 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 8155c33ba55474901ee46c2bb4c116055f872a8b..664520733f950b5b323ea7c6574af310b34483fa 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,7 @@ [RemoteDevelopment::WorkspaceOperations::Create::VolumeDefiner, :map], [RemoteDevelopment::WorkspaceOperations::Create::ToolsInjectorComponentInserter, :map], [RemoteDevelopment::WorkspaceOperations::Create::MainComponentUpdater, :map], - [RemoteDevelopment::WorkspaceOperations::Create::ProjectClonerComponentInserter, :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 ce082214ba9251ae0b2983318d2ca7b68cc50ea1..8015413d36d0149bed9f50f01ec0f225760ab133 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.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/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 395bb577d52f72cbfef06a749b317d093cee2a4c..cfbcabeeed261d1369c1f773b438d0154c3e433f 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: sidecar-container container: - image: alpine/git:2.45.2 + image: "sidecar-container:latest" volumeMounts: - name: gl-workspace-data path: "/projects" + env: + - name: GL_ENV2_NAME + value: "gl-env2-value" args: - - "echo 'project cloner container args'" + - "echo 'sidecar container args'" command: - "/bin/sh" - "-c" @@ -254,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-project-cloner-command + - id: example-prestart-apply-command apply: - component: gl-project-cloner + component: sidecar-container events: preStart: - - gl-project-cloner-command + - example-prestart-apply-command postStart: - - gl-example-tooling-container-internal-command + - example-poststart-exec-command variables: {} YAML end @@ -544,13 +547,17 @@ def golden_master_desired_config_with_include_all_resources_true initContainers: [ { args: [ - "echo 'project cloner container args'" + "echo 'sidecar container args'" ], command: [ "/bin/sh", "-c" ], env: [ + { + name: "GL_ENV2_NAME", + value: "gl-env2-value" + }, { 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: "sidecar-container:latest", imagePullPolicy: "Always", - name: "gl-project-cloner-gl-project-cloner-command-1", + name: "sidecar-container-example-prestart-apply-command-1", resources: { limits: { cpu: "500m", @@ -848,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'" } }, { @@ -1118,13 +1125,17 @@ def golden_master_desired_config_with_include_all_resources_false initContainers: [ { args: [ - "echo 'project cloner container args'" + "echo 'sidecar container args'" ], command: [ "/bin/sh", "-c" ], env: [ + { + name: "GL_ENV2_NAME", + value: "gl-env2-value" + }, { 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: "sidecar-container:latest", imagePullPolicy: "Always", - name: "gl-project-cloner-gl-project-cloner-command-1", + name: "sidecar-container-example-prestart-apply-command-1", resources: { limits: { cpu: "500m", @@ -1422,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'" } } ] @@ -2168,13 +2179,17 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources initContainers: [ { args: [ - "echo 'project cloner container args'" + "echo 'sidecar container args'" ], command: [ "/bin/sh", "-c" ], env: [ + { + name: "GL_ENV2_NAME", + value: "gl-env2-value" + }, { 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: "sidecar-container:latest", imagePullPolicy: "Always", - name: "gl-project-cloner-gl-project-cloner-command-1", + name: "sidecar-container-example-prestart-apply-command-1", resources: { limits: { cpu: "500m", @@ -2482,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'" } }, { @@ -2730,13 +2745,17 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources initContainers: [ { args: [ - "echo 'project cloner container args'" + "echo 'sidecar container args'" ], command: [ "/bin/sh", "-c" ], env: [ + { + name: "GL_ENV2_NAME", + value: "gl-env2-value" + }, { 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: "sidecar-container:latest", imagePullPolicy: "Always", - name: "gl-project-cloner-gl-project-cloner-command-1", + name: "sidecar-container-example-prestart-apply-command-1", resources: { limits: { cpu: "500m", @@ -3044,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'" } } ] 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 00dae4adadb0371cefcfb2124c577930b9a8c5da..f9e81477315d17aefdec09fdc6630b8abac26e2f 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,25 +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-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_sleep_until_container_is_running_script) do - format( - files::MAIN_COMPONENT_UPDATER_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 @@ -69,12 +50,13 @@ expect(api_version).to eq("v1") expect(configmap_name).to eq(name) expect(data).to eq( - "gl-init-tools-command": files::MAIN_COMPONENT_UPDATER_START_VSCODE_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, - "gl-start-sshd-command": files::MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT + sleep_until_container_is_running_script, + "gl-start-sshd-command": files::INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT ) end end 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 7dc205ac427bcedd8820f9c0d5d90e139e4c7a61..e27999c2a1fbf93a73fb056cfc50e03422c530b7 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 af4030d802aa0387570e88a7d677fc897aae8858..8f96456bef6160288021e3066f00ca66ee6dc2e0 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} + #{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::INTERNAL_POSTSTART_COMMAND_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? @@ -1123,30 +1129,52 @@ def workspace_network_policy( } end + # @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 = "#{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 + + # @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:) - postart_commands_script = - <<~SCRIPT - #!/bin/sh - echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-start-sshd-command..." - #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-start-sshd-command || true - echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-init-tools-command..." - #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-init-tools-command || true - echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command..." - #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command || true - SCRIPT - - sleep_until_container_is_running_script = - format( - RemoteDevelopment::Files::MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, - workspace_reconciled_actual_state_file_path: - workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH - ) - { apiVersion: "v1", kind: "ConfigMap", @@ -1157,10 +1185,11 @@ def scripts_configmap(workspace_name:, workspace_namespace:, labels:, annotation namespace: workspace_namespace }, data: { - "gl-init-tools-command": files_module::MAIN_COMPONENT_UPDATER_START_VSCODE_SCRIPT, + "gl-clone-project-command": clone_project_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