diff --git a/doc/user/workspace/_index.md b/doc/user/workspace/_index.md index 6220604ba55547642dedb268268a30eccea0c96f..78dfd7396582084a209526a3be2fd0833431cb70 100644 --- a/doc/user/workspace/_index.md +++ b/doc/user/workspace/_index.md @@ -293,6 +293,29 @@ Use this type of event to: For an example that shows how to configure `postStart` events, see the [example configurations](#example-configurations). +#### Working directory for `postStart` commands + +By default, `postStart` commands run in different working directories depending on the component: + +- Main component with attribute `gl/inject-editor: true`: Commands run in the project directory (`/projects/`). +- Other components: Commands run in the container's default working directory. + +You can override the default behavior by specifying a `workingDir` in your command definition: + +```yaml +commands: + - id: install-dependencies + exec: + component: tooling-container + commandLine: "npm install" + workingDir: "/custom/path" + - id: setup-project + exec: + component: tooling-container + commandLine: "echo 'Setting up in project directory'" + # Runs in project directory by default +``` + #### Monitor `postStart` event progress When your workspace runs `postStart` events, you can monitor their progress and check the workspace logs. @@ -333,19 +356,45 @@ components: endpoints: - name: http-3000 targetPort: 3000 + - name: database-container + container: + image: mysql + env: + - name: MYSQL_ROOT_PASSWORD + value: "my-secret-pw" commands: + # Command 1: Container 1, no working directory (uses project directory) - id: install-dependencies exec: component: tooling-container commandLine: "npm install" + + # Command 2: Container 1, with working directory - id: setup-environment exec: component: tooling-container commandLine: "echo 'Setting up development environment'" + workingDir: "/home/gitlab-workspaces" + + # Command 3: Container 2, no working directory (uses container default) + - id: init-database + exec: + component: database-container + commandLine: "echo 'Database initialized' > db-init.log" + + # Command 4: Container 2, with working directory + - id: setup-database + exec: + component: database-container + commandLine: "mkdir -p /var/lib/mysql/logs && echo 'DB setup complete' > setup.log" + workingDir: "/var/lib/mysql" + events: postStart: - install-dependencies - setup-environment + - init-database + - setup-database ``` {{< alert type="note" >}} diff --git a/ee/lib/remote_development/devfile_operations/restrictions_enforcer.rb b/ee/lib/remote_development/devfile_operations/restrictions_enforcer.rb index 5d8c044780697d616ef9e18a972cb72bd2791c0b..f0055387595711d98ac20f095bc10e451137af09 100644 --- a/ee/lib/remote_development/devfile_operations/restrictions_enforcer.rb +++ b/ee/lib/remote_development/devfile_operations/restrictions_enforcer.rb @@ -22,7 +22,7 @@ class RestrictionsEnforcer SUPPORTED_EVENTS = %i[preStart postStart].freeze # Currently, we only support the following options for exec commands - SUPPORTED_EXEC_COMMAND_OPTIONS = %i[commandLine component label hotReloadCapable].freeze + SUPPORTED_EXEC_COMMAND_OPTIONS = %i[commandLine component label hotReloadCapable workingDir].freeze # Currently, we only support the default value `false` for the `hotReloadCapable` option SUPPORTED_HOT_RELOAD_VALUE = false diff --git a/ee/lib/remote_development/workspace_operations/create/desired_config/devfile_resource_appender.rb b/ee/lib/remote_development/workspace_operations/create/desired_config/devfile_resource_appender.rb index 6e4aa1e09b2008c316fecdd6d7ffaaecf065709d..6178f42f69a738498fc79f0dc61d21eb72d20c50 100644 --- a/ee/lib/remote_development/workspace_operations/create/desired_config/devfile_resource_appender.rb +++ b/ee/lib/remote_development/workspace_operations/create/desired_config/devfile_resource_appender.rb @@ -32,7 +32,8 @@ def self.append(context) workspace_inventory_annotations_for_partial_reconciliation, workspace_inventory_name: workspace_inventory_name, workspace_name: workspace_name, - workspace_namespace: workspace_namespace + workspace_namespace: workspace_namespace, + project_path: project_path } append_inventory_configmap( @@ -69,6 +70,7 @@ def self.append(context) processed_devfile_yaml: processed_devfile_yaml, name: scripts_configmap_name, namespace: workspace_namespace, + project_path: project_path, labels: labels, annotations: workspace_inventory_annotations_for_partial_reconciliation ) @@ -261,6 +263,7 @@ def self.append_network_policy( # @param [String] processed_devfile_yaml # @param [String] name # @param [String] namespace + # @param [String] project_path # @param [Hash] labels # @param [Hash] annotations # @return [void] @@ -269,6 +272,7 @@ def self.append_scripts_resources( processed_devfile_yaml:, name:, namespace:, + project_path:, labels:, annotations: ) @@ -303,10 +307,12 @@ def self.append_scripts_resources( desired_config_array: desired_config_array, name: name, namespace: namespace, + project_path: project_path, labels: labels, annotations: annotations, devfile_commands: devfile_commands, - devfile_events: devfile_events + devfile_events: devfile_events, + processed_devfile: processed_devfile ) ScriptsVolumeInserter.insert( diff --git a/ee/lib/remote_development/workspace_operations/create/desired_config/main.rb b/ee/lib/remote_development/workspace_operations/create/desired_config/main.rb index f7ffac7d6ad5b6508650b57a9f125ce016f5bca4..0787786486ba9c1bf29e9b35ce44795b9f916254 100644 --- a/ee/lib/remote_development/workspace_operations/create/desired_config/main.rb +++ b/ee/lib/remote_development/workspace_operations/create/desired_config/main.rb @@ -23,7 +23,8 @@ def self.main(parent_context) workspaces_agent_config: workspace.workspaces_agent_config, processed_devfile_yaml: workspace.processed_devfile, logger: logger, - desired_config_array: [] + desired_config_array: [], + project_path: workspace.project.path } initial_result = Gitlab::Fp::Result.ok(context) diff --git a/ee/lib/remote_development/workspace_operations/create/desired_config/poststart_commands_helper.rb b/ee/lib/remote_development/workspace_operations/create/desired_config/poststart_commands_helper.rb new file mode 100644 index 0000000000000000000000000000000000000000..bc7dae0a6f3cc62e9f4e69ee0913ea3aa4cba283 --- /dev/null +++ b/ee/lib/remote_development/workspace_operations/create/desired_config/poststart_commands_helper.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module RemoteDevelopment + module WorkspaceOperations + module Create + module DesiredConfig + module PoststartCommandsHelper + include RemoteDevelopmentConstants + + # @param [Hash] processed_devfile + # @return [String] + def extract_main_component_name(processed_devfile:) + components = processed_devfile.fetch(:components) + + main_component = components.find do |component| + component.dig(:attributes, MAIN_COMPONENT_INDICATOR_ATTRIBUTE.to_sym) + end + + main_component.fetch(:name) + end + end + end + end + end +end diff --git a/ee/lib/remote_development/workspace_operations/create/desired_config/scripts_configmap_appender.rb b/ee/lib/remote_development/workspace_operations/create/desired_config/scripts_configmap_appender.rb index 393bcc4d008ea4e2ae2259a2551516a1bcd99cd7..22d1d6c64daae4631de71b64d2fc92fadf557407 100644 --- a/ee/lib/remote_development/workspace_operations/create/desired_config/scripts_configmap_appender.rb +++ b/ee/lib/remote_development/workspace_operations/create/desired_config/scripts_configmap_appender.rb @@ -7,23 +7,29 @@ module DesiredConfig class ScriptsConfigmapAppender include CreateConstants include WorkspaceOperationsConstants + extend PoststartCommandsHelper - # @param [Array] desired_config_array + # rubocop:disable Metrics/ParameterLists -- all arguments needed + # @param [Array] desired_config # @param [String] name # @param [String] namespace + # @param [String] project_path # @param [Hash] labels # @param [Hash] annotations # @param [Array] devfile_commands # @param [Hash] devfile_events + # @param [Hash] processed_devfile # @return [void] def self.append( desired_config_array:, name:, namespace:, + project_path:, labels:, annotations:, devfile_commands:, - devfile_events: + devfile_events:, + processed_devfile: ) configmap_data = {} @@ -49,7 +55,9 @@ def self.append( add_run_poststart_commands_script_to_configmap_data( configmap_data: configmap_data, devfile_commands: devfile_commands, - devfile_events: devfile_events + devfile_events: devfile_events, + project_path: project_path, + processed_devfile: processed_devfile ) # noinspection RubyMismatchedArgumentType - RubyMine is misinterpreting types for Hash values @@ -59,6 +67,7 @@ def self.append( nil end + # rubocop:enable Metrics/ParameterLists # @param [Hash] configmap_data # @param [Array] devfile_commands @@ -82,13 +91,17 @@ def self.add_devfile_command_scripts_to_configmap_data(configmap_data:, devfile_ end # @param [Hash] configmap_data + # @param [Hash] processed_devfile # @param [Array] devfile_commands # @param [Hash] devfile_events + # @param [String] project_path # @return [void] def self.add_run_poststart_commands_script_to_configmap_data( configmap_data:, + processed_devfile:, devfile_commands:, - devfile_events: + devfile_events:, + project_path: ) devfile_events => { postStart: Array => poststart_command_ids } @@ -96,6 +109,10 @@ def self.add_run_poststart_commands_script_to_configmap_data( command.dig(:exec, :label) == INTERNAL_BLOCKING_COMMAND_LABEL end + main_component_name = extract_main_component_name( + processed_devfile: processed_devfile + ) + unless internal_blocking_command_label_present # SAST IGNORE: String interpolation in shell context is safe here # The interpolated method call returns validated script content @@ -104,7 +121,7 @@ def self.add_run_poststart_commands_script_to_configmap_data( configmap_data[LEGACY_RUN_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym] = <<~SH.chomp #!/bin/sh - #{get_poststart_command_script_content(poststart_command_ids: poststart_command_ids)} + #{get_poststart_command_script_content(poststart_command_ids: poststart_command_ids, devfile_commands: devfile_commands, project_path: project_path, main_component_name: main_component_name, is_legacy_poststart_command: true)} SH return end @@ -124,7 +141,7 @@ def self.add_run_poststart_commands_script_to_configmap_data( configmap_data[RUN_INTERNAL_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym] = <<~SH.chomp #!/bin/sh - #{get_poststart_command_script_content(poststart_command_ids: internal_blocking_poststart_command_ids)} + #{get_poststart_command_script_content(poststart_command_ids: internal_blocking_poststart_command_ids, devfile_commands: devfile_commands, project_path: project_path, main_component_name: main_component_name)} SH # SAST IGNORE: String interpolation in shell context is safe here @@ -134,15 +151,25 @@ def self.add_run_poststart_commands_script_to_configmap_data( configmap_data[RUN_NON_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym] = <<~SH.chomp #!/bin/sh - #{get_poststart_command_script_content(poststart_command_ids: non_blocking_poststart_command_ids)} + #{get_poststart_command_script_content(poststart_command_ids: non_blocking_poststart_command_ids, devfile_commands: devfile_commands, project_path: project_path, main_component_name: main_component_name)} SH nil end # @param [Array] poststart_command_ids + # @param [Array] devfile_commands + # @param [String] project_path + # @param [String] main_component_name + # @param [Boolean] is_legacy_poststart_command # @return [String] - def self.get_poststart_command_script_content(poststart_command_ids:) + def self.get_poststart_command_script_content( + poststart_command_ids:, + devfile_commands:, + project_path:, + main_component_name:, + is_legacy_poststart_command: false + ) poststart_command_ids.map do |poststart_command_id| # NOTE: We force all the poststart scripts to exit successfully with `|| true`, to # prevent the Kubernetes poststart hook from failing, and thus prevent the @@ -155,10 +182,30 @@ def self.get_poststart_command_script_content(poststart_command_ids:) # Additional validation in ee/lib/remote_development/devfile_operations/restrictions_enforcer.rb # Future SAST alerts on this heredoc can be safely ignored. # Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/547719 + + script_execution = "#{WORKSPACE_SCRIPTS_VOLUME_PATH}/#{poststart_command_id}" + command = devfile_commands.find { |cmd| cmd[:id] == poststart_command_id } + + unless is_legacy_poststart_command + working_dir = command.dig(:exec, :workingDir) + component_name = command.dig(:exec, :component) + + effective_working_dir = if working_dir.present? + Shellwords.shellescape(working_dir) + elsif component_name == main_component_name + # Default to PROJECT_SOURCE for main component if workingDir is not specified + "${PROJECT_SOURCE}/#{Shellwords.shellescape(project_path)}" + end + + if effective_working_dir.present? + script_execution = "(cd #{effective_working_dir} && #{script_execution})" + end + end + <<~SH echo "$(date -Iseconds): ----------------------------------------" echo "$(date -Iseconds): Running #{WORKSPACE_SCRIPTS_VOLUME_PATH}/#{poststart_command_id}..." - #{WORKSPACE_SCRIPTS_VOLUME_PATH}/#{poststart_command_id} || true + #{script_execution} || true echo "$(date -Iseconds): Finished running #{WORKSPACE_SCRIPTS_VOLUME_PATH}/#{poststart_command_id}." SH end.join 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 c6dfc08a2a441c0f980e124ce8097ef8c5701cfa..a14752fa4f89aa89bf4a2bf35bf02e62a0d20812 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 @@ -71,7 +71,8 @@ def self.insert(context) exec: { commandLine: clone_project_script, component: main_component_name, - label: INTERNAL_BLOCKING_COMMAND_LABEL + label: INTERNAL_BLOCKING_COMMAND_LABEL, + workingDir: WORKSPACE_DATA_VOLUME_PATH } } @@ -93,7 +94,8 @@ def self.insert(context) exec: { commandLine: clone_unshallow_script, component: main_component_name, - label: INTERNAL_BLOCKING_COMMAND_LABEL + label: INTERNAL_BLOCKING_COMMAND_LABEL, + workingDir: WORKSPACE_DATA_VOLUME_PATH } } end @@ -105,7 +107,8 @@ def self.insert(context) exec: { commandLine: INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT, component: main_component_name, - label: INTERNAL_BLOCKING_COMMAND_LABEL + label: INTERNAL_BLOCKING_COMMAND_LABEL, + workingDir: WORKSPACE_DATA_VOLUME_PATH } } @@ -116,7 +119,8 @@ def self.insert(context) exec: { commandLine: INTERNAL_POSTSTART_COMMAND_START_VSCODE_SCRIPT, component: main_component_name, - label: INTERNAL_BLOCKING_COMMAND_LABEL + label: INTERNAL_BLOCKING_COMMAND_LABEL, + workingDir: WORKSPACE_DATA_VOLUME_PATH } } @@ -136,7 +140,8 @@ def self.insert(context) exec: { commandLine: sleep_until_container_is_running_script, component: main_component_name, - label: INTERNAL_COMMAND_LABEL + label: INTERNAL_COMMAND_LABEL, + workingDir: WORKSPACE_DATA_VOLUME_PATH } } diff --git a/ee/lib/remote_development/workspace_operations/reconcile/output/old_desired_config_generator.rb b/ee/lib/remote_development/workspace_operations/reconcile/output/old_desired_config_generator.rb index 80ccb4761278c2cd56055b493df35d95c219f21f..b18c2e181fb36b9fd52ab3c6864f7217f57a192f 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/output/old_desired_config_generator.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/old_desired_config_generator.rb @@ -116,6 +116,7 @@ def self.generate_desired_config(workspace:, include_all_resources:, logger:) processed_devfile_yaml: processed_devfile_yaml, name: scripts_configmap_name, namespace: workspace.namespace, + project_path: workspace.project.path, labels: labels, annotations: workspace_inventory_annotations ) @@ -364,6 +365,7 @@ def self.append_network_policy( # @param [String] processed_devfile_yaml # @param [String] name # @param [String] namespace + # @param [String] project_path # @param [Hash] labels # @param [Hash] annotations # @return [void] @@ -372,6 +374,7 @@ def self.append_scripts_resources( processed_devfile_yaml:, name:, namespace:, + project_path:, labels:, annotations: ) @@ -406,10 +409,12 @@ def self.append_scripts_resources( desired_config: desired_config, name: name, namespace: namespace, + project_path: project_path, labels: labels, annotations: annotations, devfile_commands: devfile_commands, - devfile_events: devfile_events + devfile_events: devfile_events, + processed_devfile: processed_devfile ) Create::DesiredConfig::ScriptsVolumeInserter.insert( diff --git a/ee/lib/remote_development/workspace_operations/reconcile/output/old_scripts_configmap_appender.rb b/ee/lib/remote_development/workspace_operations/reconcile/output/old_scripts_configmap_appender.rb index 9e4de02790400e1b169827dc58813df0f20b4fcd..ba06a0c04313e553abe941a341c9b4c4721d5c5b 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/output/old_scripts_configmap_appender.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/old_scripts_configmap_appender.rb @@ -7,16 +7,30 @@ module Output class OldScriptsConfigmapAppender include Create::CreateConstants include WorkspaceOperationsConstants + extend Create::DesiredConfig::PoststartCommandsHelper + # rubocop:disable Metrics/ParameterLists -- all arguments needed # @param [Array] desired_config # @param [String] name # @param [String] namespace + # @param [String] project_path # @param [Hash] labels # @param [Hash] annotations # @param [Array] devfile_commands # @param [Hash] devfile_events + # @param [Hash] processed_devfile # @return [void] - def self.append(desired_config:, name:, namespace:, labels:, annotations:, devfile_commands:, devfile_events:) + def self.append( + desired_config:, + name:, + namespace:, + project_path:, + labels:, + annotations:, + devfile_commands:, + devfile_events:, + processed_devfile: + ) configmap_data = {} configmap = @@ -41,7 +55,9 @@ def self.append(desired_config:, name:, namespace:, labels:, annotations:, devfi add_run_poststart_commands_script_to_configmap_data( configmap_data: configmap_data, devfile_commands: devfile_commands, - devfile_events: devfile_events + devfile_events: devfile_events, + project_path: project_path, + processed_devfile: processed_devfile ) # noinspection RubyMismatchedArgumentType - RubyMine is misinterpreting types for Hash values @@ -51,6 +67,7 @@ def self.append(desired_config:, name:, namespace:, labels:, annotations:, devfi nil end + # rubocop:enable Metrics/ParameterLists # @param [Hash] configmap_data # @param [Array] devfile_commands @@ -74,13 +91,17 @@ def self.add_devfile_command_scripts_to_configmap_data(configmap_data:, devfile_ end # @param [Hash] configmap_data + # @param [Hash] processed_devfile # @param [Array] devfile_commands # @param [Hash] devfile_events + # @param [String] project_path # @return [void] def self.add_run_poststart_commands_script_to_configmap_data( configmap_data:, + processed_devfile:, devfile_commands:, - devfile_events: + devfile_events:, + project_path: ) devfile_events => { postStart: Array => poststart_command_ids } @@ -88,6 +109,10 @@ def self.add_run_poststart_commands_script_to_configmap_data( command.dig(:exec, :label) == INTERNAL_BLOCKING_COMMAND_LABEL end + main_component_name = extract_main_component_name( + processed_devfile: processed_devfile + ) + unless internal_blocking_command_label_present # SAST IGNORE: String interpolation in shell context is safe here # The interpolated method call returns validated script content @@ -96,7 +121,7 @@ def self.add_run_poststart_commands_script_to_configmap_data( configmap_data[LEGACY_RUN_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym] = <<~SH.chomp #!/bin/sh - #{get_poststart_command_script_content(poststart_command_ids: poststart_command_ids)} + #{get_poststart_command_script_content(poststart_command_ids: poststart_command_ids, devfile_commands: devfile_commands, project_path: project_path, main_component_name: main_component_name, is_legacy_poststart_command: true)} SH return end @@ -116,7 +141,7 @@ def self.add_run_poststart_commands_script_to_configmap_data( configmap_data[RUN_INTERNAL_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym] = <<~SH.chomp #!/bin/sh - #{get_poststart_command_script_content(poststart_command_ids: internal_blocking_poststart_command_ids)} + #{get_poststart_command_script_content(poststart_command_ids: internal_blocking_poststart_command_ids, devfile_commands: devfile_commands, project_path: project_path, main_component_name: main_component_name)} SH # SAST IGNORE: String interpolation in shell context is safe here @@ -126,15 +151,25 @@ def self.add_run_poststart_commands_script_to_configmap_data( configmap_data[RUN_NON_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym] = <<~SH.chomp #!/bin/sh - #{get_poststart_command_script_content(poststart_command_ids: non_blocking_poststart_command_ids)} + #{get_poststart_command_script_content(poststart_command_ids: non_blocking_poststart_command_ids, devfile_commands: devfile_commands, project_path: project_path, main_component_name: main_component_name)} SH nil end # @param [Array] poststart_command_ids + # @param [Array] devfile_commands + # @param [String] project_path + # @param [String] main_component_name + # @param [Boolean] is_legacy_poststart_command # @return [String] - def self.get_poststart_command_script_content(poststart_command_ids:) + def self.get_poststart_command_script_content( + poststart_command_ids:, + devfile_commands:, + project_path:, + main_component_name:, + is_legacy_poststart_command: false + ) poststart_command_ids.map do |poststart_command_id| # NOTE: We force all the poststart scripts to exit successfully with `|| true`, to # prevent the Kubernetes poststart hook from failing, and thus prevent the @@ -147,10 +182,30 @@ def self.get_poststart_command_script_content(poststart_command_ids:) # Additional validation in ee/lib/remote_development/devfile_operations/restrictions_enforcer.rb # Future SAST alerts on this heredoc can be safely ignored. # Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/547719 + + script_execution = "#{WORKSPACE_SCRIPTS_VOLUME_PATH}/#{poststart_command_id}" + command = devfile_commands.find { |cmd| cmd[:id] == poststart_command_id } + + unless is_legacy_poststart_command + working_dir = command.dig(:exec, :workingDir) + component_name = command.dig(:exec, :component) + + effective_working_dir = if working_dir.present? + Shellwords.shellescape(working_dir) + elsif component_name == main_component_name + # Default to PROJECT_SOURCE for main component if workingDir is not specified + "${PROJECT_SOURCE}/#{Shellwords.shellescape(project_path)}" + end + + if effective_working_dir.present? + script_execution = "(cd #{effective_working_dir} && #{script_execution})" + end + end + <<~SH echo "$(date -Iseconds): ----------------------------------------" echo "$(date -Iseconds): Running #{WORKSPACE_SCRIPTS_VOLUME_PATH}/#{poststart_command_id}..." - #{WORKSPACE_SCRIPTS_VOLUME_PATH}/#{poststart_command_id} || true + #{script_execution} || true echo "$(date -Iseconds): Finished running #{WORKSPACE_SCRIPTS_VOLUME_PATH}/#{poststart_command_id}." SH end.join diff --git a/ee/spec/features/remote_development/workspaces_spec.rb b/ee/spec/features/remote_development/workspaces_spec.rb index 84ae7ff39568c1d8ff4f4a68cac7cad5e04d53c2..d38c2099dd0bd8145e620acbc51fa6701e06a10e 100644 --- a/ee/spec/features/remote_development/workspaces_spec.rb +++ b/ee/spec/features/remote_development/workspaces_spec.rb @@ -37,11 +37,37 @@ let(:user_defined_commands) do [ + { + id: "db-component-command-with-working-dir", + exec: { + component: "database-container", + commandLine: "echo 'executes postStart command in the specified workingDir'", + workingDir: "test-dir", + hotReloadCapable: false + } + }, + { + id: "db-component-command-without-working-dir", + exec: { + component: "database-container", + commandLine: "echo 'executes postStart command in the the container's default WORKDIR'", + hotReloadCapable: false + } + }, + { + id: "main-component-command-without-working-dir", + exec: { + component: "tooling-container", + commandLine: "echo 'executes postStart command in the projects/project_path directory'", + hotReloadCapable: false + } + }, { id: "user-defined-command", exec: { component: "tooling-container", - commandLine: "echo 'user-defined postStart command'", + commandLine: "echo 'executes postStart command in the specified workingDir'", + workingDir: "test-dir", hotReloadCapable: false } } diff --git a/ee/spec/fixtures/remote_development/example.container-commands-updated-devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.container-commands-updated-devfile.yaml.erb index 1538644cea6f434b3842b5d0a707b04a468f27e0..4b6e1f4393f4b11426676f20c982869716882431 100644 --- a/ee/spec/fixtures/remote_development/example.container-commands-updated-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.container-commands-updated-devfile.yaml.erb @@ -72,12 +72,32 @@ events: preStart: - gl-tools-injector-command postStart: + - db-component-command-with-working-dir + - db-component-command-without-working-dir + - main-component-command-without-working-dir - user-defined-command commands: - id: user-defined-command exec: component: tooling-container - commandLine: echo 'user-defined postStart command' + commandLine: echo 'executes postStart command in the specified workingDir' + workingDir: test-dir + hotReloadCapable: false + - id: main-component-command-without-working-dir + exec: + component: tooling-container + commandLine: echo 'executes postStart command in the projects/project_path directory' + hotReloadCapable: false + - id: db-component-command-with-working-dir + exec: + component: database-container + commandLine: echo 'executes postStart command in the specified workingDir' + workingDir: test-dir + hotReloadCapable: false + - id: db-component-command-without-working-dir + exec: + component: database-container + commandLine: echo 'executes postStart command in the the container's default WORKDIR' hotReloadCapable: false - id: gl-tools-injector-command apply: diff --git a/ee/spec/fixtures/remote_development/example.devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.devfile.yaml.erb index 89469bb636852591f77f6339c4a772d5e7d51b36..cfc42a201d5bdf8513949373c2a9cbe18f29240a 100644 --- a/ee/spec/fixtures/remote_development/example.devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.devfile.yaml.erb @@ -23,9 +23,29 @@ commands: - id: user-defined-command exec: component: tooling-container - commandLine: echo 'user-defined postStart command' + commandLine: echo 'executes postStart command in the specified workingDir' + workingDir: test-dir + hotReloadCapable: false + - id: main-component-command-without-working-dir + exec: + component: tooling-container + commandLine: echo 'executes postStart command in the projects/project_path directory' + hotReloadCapable: false + - id: db-component-command-with-working-dir + exec: + component: database-container + commandLine: echo 'executes postStart command in the specified workingDir' + workingDir: test-dir + hotReloadCapable: false + - id: db-component-command-without-working-dir + exec: + component: database-container + commandLine: echo 'executes postStart command in the the container's default WORKDIR' hotReloadCapable: false events: preStart: [] postStart: + - db-component-command-with-working-dir + - db-component-command-without-working-dir + - main-component-command-without-working-dir - user-defined-command diff --git a/ee/spec/fixtures/remote_development/example.flattened-devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.flattened-devfile.yaml.erb index 1d9010790ed5449295b3c32c3fed92cb7ee17fd0..25940936d870b06fd38839acd030b31f0d8cbb7f 100644 --- a/ee/spec/fixtures/remote_development/example.flattened-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.flattened-devfile.yaml.erb @@ -30,10 +30,30 @@ commands: - id: user-defined-command exec: component: tooling-container - commandLine: echo 'user-defined postStart command' + commandLine: echo 'executes postStart command in the specified workingDir' + workingDir: test-dir + hotReloadCapable: false + - id: main-component-command-without-working-dir + exec: + component: tooling-container + commandLine: echo 'executes postStart command in the projects/project_path directory' + hotReloadCapable: false + - id: db-component-command-with-working-dir + exec: + component: database-container + commandLine: echo 'executes postStart command in the specified workingDir' + workingDir: test-dir + hotReloadCapable: false + - id: db-component-command-without-working-dir + exec: + component: database-container + commandLine: echo 'executes postStart command in the the container's default WORKDIR' hotReloadCapable: false events: postStart: + - db-component-command-with-working-dir + - db-component-command-without-working-dir + - main-component-command-without-working-dir - user-defined-command preStart: [] variables: {} 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 index b168db6c869e44e9791708958e6b65ab6e766bbf..a1ebb898ddd458125f0b3041c000acfb0ef16f05 100644 --- 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 @@ -72,7 +72,24 @@ commands: - id: user-defined-command exec: component: tooling-container - commandLine: echo 'user-defined postStart command' + commandLine: echo 'executes postStart command in the specified workingDir' + workingDir: test-dir + hotReloadCapable: false + - id: main-component-command-without-working-dir + exec: + component: tooling-container + commandLine: echo 'executes postStart command in the projects/project_path directory' + hotReloadCapable: false + - id: db-component-command-with-working-dir + exec: + component: database-container + commandLine: echo 'executes postStart command in the specified workingDir' + workingDir: test-dir + hotReloadCapable: false + - id: db-component-command-without-working-dir + exec: + component: database-container + commandLine: echo 'executes postStart command in the the container's default WORKDIR' hotReloadCapable: false - id: gl-tools-injector-command apply: @@ -86,6 +103,7 @@ commands: %> component: tooling-container label: <%= INTERNAL_BLOCKING_COMMAND_LABEL %> + workingDir: /projects - id: gl-clone-unshallow-command exec: commandLine: | @@ -95,18 +113,21 @@ commands: %> component: tooling-container label: <%= INTERNAL_BLOCKING_COMMAND_LABEL %> + workingDir: /projects - id: gl-start-sshd-command exec: commandLine: | <%= indent_yaml_literal(INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT, 8) %> component: tooling-container label: <%= INTERNAL_BLOCKING_COMMAND_LABEL %> + workingDir: /projects - id: gl-init-tools-command exec: commandLine: | <%= indent_yaml_literal(INTERNAL_POSTSTART_COMMAND_START_VSCODE_SCRIPT, 8) %> component: tooling-container label: <%= INTERNAL_BLOCKING_COMMAND_LABEL %> + workingDir: /projects - id: gl-sleep-until-container-is-running-command exec: commandLine: | @@ -119,6 +140,7 @@ commands: %> component: tooling-container label: <%= INTERNAL_COMMAND_LABEL %> + workingDir: /projects events: preStart: - gl-tools-injector-command @@ -128,5 +150,8 @@ events: - gl-start-sshd-command - gl-init-tools-command - gl-sleep-until-container-is-running-command + - db-component-command-with-working-dir + - db-component-command-without-working-dir + - main-component-command-without-working-dir - user-defined-command variables: {} 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 dee97fca4a270f7b9b4e30efc09666d9c277cf27..073df2c875bccdd6f8f1c04e9ab06dd7d253bcd1 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 @@ -61,7 +61,24 @@ commands: - id: user-defined-command exec: component: tooling-container - commandLine: echo 'user-defined postStart command' + commandLine: echo 'executes postStart command in the specified workingDir' + workingDir: test-dir + hotReloadCapable: false + - id: main-component-command-without-working-dir + exec: + component: tooling-container + commandLine: echo 'executes postStart command in the projects/project_path directory' + hotReloadCapable: false + - id: db-component-command-with-working-dir + exec: + component: database-container + commandLine: echo 'executes postStart command in the specified workingDir' + workingDir: test-dir + hotReloadCapable: false + - id: db-component-command-without-working-dir + exec: + component: database-container + commandLine: echo 'executes postStart command in the the container's default WORKDIR' hotReloadCapable: false - id: gl-tools-injector-command apply: @@ -70,5 +87,8 @@ events: preStart: - gl-tools-injector-command postStart: + - db-component-command-with-working-dir + - db-component-command-without-working-dir + - main-component-command-without-working-dir - user-defined-command variables: {} diff --git a/ee/spec/fixtures/remote_development/example.main-container-updated-marketplace-disabled-devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.main-container-updated-marketplace-disabled-devfile.yaml.erb index dee97fca4a270f7b9b4e30efc09666d9c277cf27..073df2c875bccdd6f8f1c04e9ab06dd7d253bcd1 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 @@ -61,7 +61,24 @@ commands: - id: user-defined-command exec: component: tooling-container - commandLine: echo 'user-defined postStart command' + commandLine: echo 'executes postStart command in the specified workingDir' + workingDir: test-dir + hotReloadCapable: false + - id: main-component-command-without-working-dir + exec: + component: tooling-container + commandLine: echo 'executes postStart command in the projects/project_path directory' + hotReloadCapable: false + - id: db-component-command-with-working-dir + exec: + component: database-container + commandLine: echo 'executes postStart command in the specified workingDir' + workingDir: test-dir + hotReloadCapable: false + - id: db-component-command-without-working-dir + exec: + component: database-container + commandLine: echo 'executes postStart command in the the container's default WORKDIR' hotReloadCapable: false - id: gl-tools-injector-command apply: @@ -70,5 +87,8 @@ events: preStart: - gl-tools-injector-command postStart: + - db-component-command-with-working-dir + - db-component-command-without-working-dir + - main-component-command-without-working-dir - user-defined-command variables: {} diff --git a/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb index 3bca9e092e783263b5d416dfa16050b0a3148a61..daab101bfee9f5aaf2ea032903e65afb59758eb1 100644 --- a/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb @@ -87,7 +87,24 @@ commands: - id: user-defined-command exec: component: tooling-container - commandLine: echo 'user-defined postStart command' + commandLine: echo 'executes postStart command in the specified workingDir' + workingDir: test-dir + hotReloadCapable: false + - id: main-component-command-without-working-dir + exec: + component: tooling-container + commandLine: echo 'executes postStart command in the projects/project_path directory' + hotReloadCapable: false + - id: db-component-command-with-working-dir + exec: + component: database-container + commandLine: echo 'executes postStart command in the specified workingDir' + workingDir: test-dir + hotReloadCapable: false + - id: db-component-command-without-working-dir + exec: + component: database-container + commandLine: echo 'executes postStart command in the the container's default WORKDIR' hotReloadCapable: false - id: gl-tools-injector-command apply: @@ -101,6 +118,7 @@ commands: %> component: tooling-container label: <%= INTERNAL_BLOCKING_COMMAND_LABEL %> + workingDir: /projects - id: gl-clone-unshallow-command exec: commandLine: | @@ -110,18 +128,21 @@ commands: %> component: tooling-container label: <%= INTERNAL_BLOCKING_COMMAND_LABEL %> + workingDir: /projects - id: gl-start-sshd-command exec: commandLine: | <%= indent_yaml_literal(INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT, 8) %> component: tooling-container label: <%= INTERNAL_BLOCKING_COMMAND_LABEL %> + workingDir: /projects - id: gl-init-tools-command exec: commandLine: | <%= indent_yaml_literal(INTERNAL_POSTSTART_COMMAND_START_VSCODE_SCRIPT, 8) %> component: tooling-container label: <%= INTERNAL_BLOCKING_COMMAND_LABEL %> + workingDir: /projects - id: gl-sleep-until-container-is-running-command exec: commandLine: | @@ -134,6 +155,7 @@ commands: %> component: tooling-container label: <%= INTERNAL_COMMAND_LABEL %> + workingDir: /projects events: preStart: - gl-tools-injector-command @@ -143,5 +165,8 @@ events: - gl-start-sshd-command - gl-init-tools-command - gl-sleep-until-container-is-running-command + - db-component-command-with-working-dir + - db-component-command-without-working-dir + - main-component-command-without-working-dir - user-defined-command variables: {} diff --git a/ee/spec/fixtures/remote_development/example.tools-injector-inserted-devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.tools-injector-inserted-devfile.yaml.erb index d43e844f9768ec9b5e607f6c364aa6b56860df8a..8395a20fa30d04e659d6630845df3983358ac727 100644 --- a/ee/spec/fixtures/remote_development/example.tools-injector-inserted-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.tools-injector-inserted-devfile.yaml.erb @@ -40,12 +40,32 @@ events: preStart: - gl-tools-injector-command postStart: + - db-component-command-with-working-dir + - db-component-command-without-working-dir + - main-component-command-without-working-dir - user-defined-command commands: - id: user-defined-command exec: component: tooling-container - commandLine: echo 'user-defined postStart command' + commandLine: echo 'executes postStart command in the specified workingDir' + workingDir: test-dir + hotReloadCapable: false + - id: main-component-command-without-working-dir + exec: + component: tooling-container + commandLine: echo 'executes postStart command in the projects/project_path directory' + hotReloadCapable: false + - id: db-component-command-with-working-dir + exec: + component: database-container + commandLine: echo 'executes postStart command in the specified workingDir' + workingDir: test-dir + hotReloadCapable: false + - id: db-component-command-without-working-dir + exec: + component: database-container + commandLine: echo 'executes postStart command in the the container's default WORKDIR' hotReloadCapable: false - id: gl-tools-injector-command apply: diff --git a/ee/spec/lib/remote_development/devfile_operations/restrictions_enforcer_spec.rb b/ee/spec/lib/remote_development/devfile_operations/restrictions_enforcer_spec.rb index e5508406497a6be9d00d34724a31fc95a943123e..b196054a6d2785a2f502d4c1bc231db72d4d496f 100644 --- a/ee/spec/lib/remote_development/devfile_operations/restrictions_enforcer_spec.rb +++ b/ee/spec/lib/remote_development/devfile_operations/restrictions_enforcer_spec.rb @@ -112,7 +112,7 @@ "example.invalid-restricted-prefix-variable-name-with-underscore-devfile.yaml.erb" | "Variable name 'gl_example' must not start with 'gl_'" | :processed_devfile "example.invalid-root-attributes-pod-overrides-devfile.yaml.erb" | "Attribute 'pod-overrides' is not yet supported" | :processed_devfile "example.invalid-unsupported-command-exec-hot-reload-capable-option-devfile.yaml.erb" | "Property 'hotReloadCapable' for exec command 'unsupported-hot-reload-option' must be false when specified" | :processed_devfile - "example.invalid-unsupported-command-exec-options-devfile.yaml.erb" | "Unsupported options 'unsupportedOption' for exec command 'unsupported-options'. Only 'commandLine, component, label, hotReloadCapable' are supported." | :processed_devfile + "example.invalid-unsupported-command-exec-options-devfile.yaml.erb" | "Unsupported options 'unsupportedOption' for exec command 'unsupported-options'. Only 'commandLine, component, label, hotReloadCapable, workingDir' are supported." | :processed_devfile "example.invalid-unsupported-command-type-devfile.yaml.erb" | "Command 'composite-command' must have one of the supported command types: exec, apply" | :processed_devfile "example.invalid-unsupported-command-type-poststart-event-devfile.yaml.erb" | "PostStart event references command 'apply-command' which is not an exec command. Only exec commands are supported in postStart events" | :processed_devfile "example.invalid-poststart-event-nonexistent-command-devfile.yaml.erb" | "PostStart event references command 'nonexistent-command' which has no command definition." | :processed_devfile diff --git a/ee/spec/lib/remote_development/workspace_operations/create/desired_config/devfile_resource_appender_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/desired_config/devfile_resource_appender_spec.rb index 2edd7793103217f5a100c21d0dc42a23b2cb3cf8..a0f87d86aa6c9a79725e400d7066e5f7c0b4e8ad 100644 --- a/ee/spec/lib/remote_development/workspace_operations/create/desired_config/devfile_resource_appender_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/create/desired_config/devfile_resource_appender_spec.rb @@ -121,7 +121,8 @@ max_resources_per_workspace: max_resources_per_workspace, shared_namespace: shared_namespace, env_secret_name: env_secret_name, - file_secret_name: file_secret_name + file_secret_name: file_secret_name, + project_path: "test-project" } end diff --git a/ee/spec/lib/remote_development/workspace_operations/create/desired_config/main_integeration_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/desired_config/main_integeration_spec.rb index d307230addded3ff608509a69b8b988d16b3b828..a1a7c214c46ab9ad0de045ab28401eab42e1077a 100644 --- a/ee/spec/lib/remote_development/workspace_operations/create/desired_config/main_integeration_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/create/desired_config/main_integeration_spec.rb @@ -76,6 +76,8 @@ ) end + let(:project) { instance_double("Project", path: "test-project") } + let(:input_processed_devfile_yaml) { input_processed_devfile_yaml_with_poststart_event } let(:workspace) do @@ -89,6 +91,7 @@ desired_state_running?: desired_state_running, actual_state: states_module::RUNNING, workspace_variables: workspace_variables, + project: project, processed_devfile: input_processed_devfile_yaml ) end @@ -262,10 +265,13 @@ def input_processed_devfile_yaml_with_poststart_event commandLine: "echo 'gl-internal-example-command-1'" component: tooling-container label: gl-internal-blocking + workingDir: /projects - id: gl-internal-example-command-2 exec: commandLine: "echo 'gl-internal-example-command-2'" component: tooling-container + label: gl-internal + workingDir: /projects - id: example-prestart-apply-command apply: component: sidecar-container @@ -895,8 +901,8 @@ def expected_desired_config_array_with_desired_state_running namespace: "gl-rd-ns-991-990-fedcba" }, data: { - "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n/workspace-scripts/gl-internal-example-command-1 || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-1.\"\n", - "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n/workspace-scripts/gl-internal-example-command-2 || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-2.\"\n", + "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n(cd /projects && /workspace-scripts/gl-internal-example-command-1) || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-1.\"\n", + "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n(cd /projects && /workspace-scripts/gl-internal-example-command-2) || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-2.\"\n", "gl-internal-example-command-1": "echo 'gl-internal-example-command-1'", "gl-internal-example-command-2": "echo 'gl-internal-example-command-2'" } @@ -1480,8 +1486,8 @@ def expected_desired_config_array_with_desired_state_running_with_use_kubernetes namespace: "gl-rd-ns-991-990-fedcba" }, data: { - "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n/workspace-scripts/gl-internal-example-command-1 || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-1.\"\n", - "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n/workspace-scripts/gl-internal-example-command-2 || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-2.\"\n", + "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n(cd /projects && /workspace-scripts/gl-internal-example-command-1) || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-1.\"\n", + "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n(cd /projects && /workspace-scripts/gl-internal-example-command-2) || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-2.\"\n", "gl-internal-example-command-1": "echo 'gl-internal-example-command-1'", "gl-internal-example-command-2": "echo 'gl-internal-example-command-2'" } @@ -2063,8 +2069,8 @@ def expected_desired_config_array_with_desired_state_stopped namespace: "gl-rd-ns-991-990-fedcba" }, data: { - "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n/workspace-scripts/gl-internal-example-command-1 || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-1.\"\n", - "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n/workspace-scripts/gl-internal-example-command-2 || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-2.\"\n", + "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n(cd /projects && /workspace-scripts/gl-internal-example-command-1) || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-1.\"\n", + "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n(cd /projects && /workspace-scripts/gl-internal-example-command-2) || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-2.\"\n", "gl-internal-example-command-1": "echo 'gl-internal-example-command-1'", "gl-internal-example-command-2": "echo 'gl-internal-example-command-2'" } @@ -3765,8 +3771,8 @@ def expected_desired_config_array_for_shared_namespace_with_desired_state_runnin namespace: "default" }, data: { - "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n/workspace-scripts/gl-internal-example-command-1 || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-1.\"\n", - "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n/workspace-scripts/gl-internal-example-command-2 || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-2.\"\n", + "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n(cd /projects && /workspace-scripts/gl-internal-example-command-1) || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-1.\"\n", + "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n(cd /projects && /workspace-scripts/gl-internal-example-command-2) || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-2.\"\n", "gl-internal-example-command-1": "echo 'gl-internal-example-command-1'", "gl-internal-example-command-2": "echo 'gl-internal-example-command-2'" } @@ -4336,8 +4342,8 @@ def expected_desired_config_array_for_shared_namespace_with_desired_state_stoppe namespace: "default" }, data: { - "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n/workspace-scripts/gl-internal-example-command-1 || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-1.\"\n", - "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n/workspace-scripts/gl-internal-example-command-2 || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-2.\"\n", + "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n(cd /projects && /workspace-scripts/gl-internal-example-command-1) || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-1.\"\n", + "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n(cd /projects && /workspace-scripts/gl-internal-example-command-2) || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-2.\"\n", "gl-internal-example-command-1": "echo 'gl-internal-example-command-1'", "gl-internal-example-command-2": "echo 'gl-internal-example-command-2'" } diff --git a/ee/spec/lib/remote_development/workspace_operations/create/desired_config/main_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/desired_config/main_spec.rb index e73f7321de5438180e0cc062715c98045663db60..cad42f9c9b657dbfca8ddbfd8b58f3e0af527432 100644 --- a/ee/spec/lib/remote_development/workspace_operations/create/desired_config/main_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/create/desired_config/main_spec.rb @@ -16,6 +16,7 @@ let(:workspace_agent) { instance_double("Clusters::Agent", id: 1) } # rubocop:disable RSpec/VerifiedDoubleReference -- We're using the quoted version so we can use fast_spec_helper let(:workspaces_agent_config) { instance_double("RemoteDevelopment::WorkspacesAgentConfig") } # rubocop:disable RSpec/VerifiedDoubleReference -- We're using the quoted version so we can use fast_spec_helper + let(:project) { instance_double("Project", path: "test-project") } # rubocop:disable RSpec/VerifiedDoubleReference -- We're using the quoted version so we can use fast_spec_helper let(:workspace) do instance_double( "RemoteDevelopment::Workspace", # rubocop:disable RSpec/VerifiedDoubleReference -- We're using the quoted version so we can use fast_spec_helper @@ -24,6 +25,7 @@ namespace: "workspace-namespace", workspaces_agent_config: workspaces_agent_config, desired_state_running?: true, + project: project, processed_devfile: "---") end @@ -48,6 +50,7 @@ workspaces_agent_id: 1, workspaces_agent_config: workspaces_agent_config, processed_devfile_yaml: parent_context[:workspace].processed_devfile, + project_path: parent_context[:workspace].project.path, logger: logger, desired_config_array: [] } diff --git a/ee/spec/lib/remote_development/workspace_operations/create/desired_config/scripts_configmap_appender_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/desired_config/scripts_configmap_appender_spec.rb index de00abd60df229bf4ba5cad7b069a04784bf590d..6cf935985518634550c748b2dfe31a259cac5e73 100644 --- a/ee/spec/lib/remote_development/workspace_operations/create/desired_config/scripts_configmap_appender_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/create/desired_config/scripts_configmap_appender_spec.rb @@ -24,10 +24,12 @@ desired_config_array: desired_config_array, name: name, namespace: namespace, + project_path: "test-project", labels: labels, annotations: annotations, devfile_commands: devfile_commands, - devfile_events: devfile_events + devfile_events: devfile_events, + processed_devfile: processed_devfile ) desired_config_array @@ -56,12 +58,37 @@ create_constants_module::RUN_INTERNAL_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => internal_blocking_poststart_commands_script, create_constants_module::RUN_NON_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => - non_blocking_poststart_commands_script(user_command_ids: ["user-defined-command"]), + non_blocking_poststart_commands_script( + user_command_ids: %w[ + db-component-command-with-working-dir + db-component-command-without-working-dir + main-component-command-without-working-dir + user-defined-command + ], + devfile_commands: devfile_commands + ), "gl-sleep-until-container-is-running-command": sleep_until_container_is_running_script, "gl-start-sshd-command": files::INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT, - "user-defined-command": "echo 'user-defined postStart command'" + "db-component-command-with-working-dir": "echo 'executes postStart command in the specified workingDir'", + "db-component-command-without-working-dir": + "echo 'executes postStart command in the the container's default WORKDIR'", + "main-component-command-without-working-dir": + "echo 'executes postStart command in the projects/project_path directory'", + "user-defined-command": "echo 'executes postStart command in the specified workingDir'" ) + + non_blocking_script = data[create_constants_module::RUN_NON_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym] + expect(non_blocking_script).to include( + '(cd test-dir && /workspace-scripts/db-component-command-with-working-dir) || true' + ) + expect(non_blocking_script).to include( + '/workspace-scripts/db-component-command-without-working-dir || true' + ) + expect(non_blocking_script).to include( + '(cd ${PROJECT_SOURCE}/test-project && /workspace-scripts/main-component-command-without-working-dir) || true' + ) + expect(non_blocking_script).to include('(cd test-dir && /workspace-scripts/user-defined-command) || true') end context "when legacy poststart scripts are used" do diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/main_integration_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/main_integration_spec.rb index 30b17f17339b2c4fa9c293a004ad1e4ca13cb8e0..efadbca16eaa7f498d0c4c1e2614ead67aba1251 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/main_integration_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/main_integration_spec.rb @@ -16,6 +16,8 @@ agent.reload end + let_it_be(:project) { create(:project, path: "test-project") } + let(:desired_state) { states_module::STOPPED } let(:actual_state) { states_module::STOPPED } let(:force_include_all_resources) { false } @@ -23,6 +25,7 @@ { user: user, agent: agent, + project: project, desired_state: desired_state, actual_state: actual_state, force_include_all_resources: force_include_all_resources @@ -73,11 +76,37 @@ let(:user_defined_commands) do [ + { + id: "db-component-command-with-working-dir", + exec: { + component: "database-container", + commandLine: "echo 'executes postStart command in the specified workingDir'", + workingDir: "test-dir", + hotReloadCapable: false + } + }, + { + id: "db-component-command-without-working-dir", + exec: { + component: "database-container", + commandLine: "echo 'executes postStart command in the the container's default WORKDIR'", + hotReloadCapable: false + } + }, + { + id: "main-component-command-without-working-dir", + exec: { + component: "tooling-container", + commandLine: "echo 'executes postStart command in the projects/project_path directory'", + hotReloadCapable: false + } + }, { id: "user-defined-command", exec: { component: "tooling-container", - commandLine: "echo 'user-defined postStart command'", + commandLine: "echo 'executes postStart command in the specified workingDir'", + workingDir: "test-dir", hotReloadCapable: false } } diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/old_desired_config_generator_golden_master_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/old_desired_config_generator_golden_master_spec.rb index 310580cedd628e86fdf34fb1b6e2b653e2b7b2a7..2f078712cc027e79751d8608d216eeb905a8d535 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/old_desired_config_generator_golden_master_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/old_desired_config_generator_golden_master_spec.rb @@ -82,6 +82,8 @@ let(:input_processed_devfile_yaml) { input_processed_devfile_yaml_with_poststart_event } + let(:project) { instance_double("Project", path: "test-project") } + let(:workspace) do instance_double( "RemoteDevelopment::Workspace", @@ -94,6 +96,7 @@ desired_state_terminated?: desired_state_terminated, actual_state: 'Running', workspace_variables: workspace_variables, + project: project, processed_devfile: input_processed_devfile_yaml ) end @@ -275,10 +278,13 @@ def input_processed_devfile_yaml_with_poststart_event commandLine: "echo 'gl-internal-example-command-1'" component: tooling-container label: gl-internal-blocking + workingDir: /projects - id: gl-internal-example-command-2 exec: commandLine: "echo 'gl-internal-example-command-2'" component: tooling-container + label: gl-internal + workingDir: /projects - id: example-prestart-apply-command apply: component: sidecar-container @@ -948,8 +954,8 @@ def golden_master_desired_config_with_include_all_resources_true namespace: "gl-rd-ns-991-990-fedcba" }, data: { - "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n/workspace-scripts/gl-internal-example-command-1 || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-1.\"\n", - "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n/workspace-scripts/gl-internal-example-command-2 || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-2.\"\n", + "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n(cd /projects && /workspace-scripts/gl-internal-example-command-1) || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-1.\"\n", + "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n(cd /projects && /workspace-scripts/gl-internal-example-command-2) || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-2.\"\n", "gl-internal-example-command-1": "echo 'gl-internal-example-command-1'", "gl-internal-example-command-2": "echo 'gl-internal-example-command-2'" } @@ -1528,8 +1534,8 @@ def golden_master_desired_config_with_include_all_resources_false namespace: "gl-rd-ns-991-990-fedcba" }, data: { - "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n/workspace-scripts/gl-internal-example-command-1 || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-1.\"\n", - "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n/workspace-scripts/gl-internal-example-command-2 || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-2.\"\n", + "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n(cd /projects && /workspace-scripts/gl-internal-example-command-1) || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-1.\"\n", + "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n(cd /projects && /workspace-scripts/gl-internal-example-command-2) || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-2.\"\n", "gl-internal-example-command-1": "echo 'gl-internal-example-command-1'", "gl-internal-example-command-2": "echo 'gl-internal-example-command-2'" } @@ -3173,8 +3179,8 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources namespace: "default" }, data: { - "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n/workspace-scripts/gl-internal-example-command-1 || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-1.\"\n", - "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n/workspace-scripts/gl-internal-example-command-2 || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-2.\"\n", + "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n(cd /projects && /workspace-scripts/gl-internal-example-command-1) || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-1.\"\n", + "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n(cd /projects && /workspace-scripts/gl-internal-example-command-2) || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-2.\"\n", "gl-internal-example-command-1": "echo 'gl-internal-example-command-1'", "gl-internal-example-command-2": "echo 'gl-internal-example-command-2'" } @@ -3741,8 +3747,8 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources namespace: "default" }, data: { - "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n/workspace-scripts/gl-internal-example-command-1 || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-1.\"\n", - "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n/workspace-scripts/gl-internal-example-command-2 || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-2.\"\n", + "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n(cd /projects && /workspace-scripts/gl-internal-example-command-1) || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-1.\"\n", + "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n(cd /projects && /workspace-scripts/gl-internal-example-command-2) || true\necho \"$(date -Iseconds): Finished running /workspace-scripts/gl-internal-example-command-2.\"\n", "gl-internal-example-command-1": "echo 'gl-internal-example-command-1'", "gl-internal-example-command-2": "echo 'gl-internal-example-command-2'" } diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/old_desired_config_generator_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/old_desired_config_generator_spec.rb index 369898ac72400e278e0955bc090e41818c58b293..7ba1b61d887c0a076cc4f34d699fcfb9a67192a2 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/old_desired_config_generator_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/old_desired_config_generator_spec.rb @@ -36,6 +36,7 @@ describe "#generate_desired_config" do let(:logger) { instance_double(Logger) } let(:user) { create(:user) } + let_it_be(:project) { create(:project, path: "test-project") } let_it_be(:agent, reload: true) { create(:ee_cluster_agent) } let(:desired_state) { states_module::RUNNING } let(:actual_state) { states_module::STOPPED } @@ -75,17 +76,44 @@ user: user, desired_state: desired_state, actual_state: actual_state, - processed_devfile: processed_devfile_yaml + processed_devfile: processed_devfile_yaml, + project: project ) end let(:user_defined_commands) do [ + { + id: "db-component-command-with-working-dir", + exec: { + component: "database-container", + commandLine: "echo 'executes postStart command in the specified workingDir'", + workingDir: "test-dir", + hotReloadCapable: false + } + }, + { + id: "db-component-command-without-working-dir", + exec: { + component: "database-container", + commandLine: "echo 'executes postStart command in the the container's default WORKDIR'", + hotReloadCapable: false + } + }, + { + id: "main-component-command-without-working-dir", + exec: { + component: "tooling-container", + commandLine: "echo 'executes postStart command in the projects/project_path directory'", + hotReloadCapable: false + } + }, { id: "user-defined-command", exec: { component: "tooling-container", - commandLine: "echo 'user-defined postStart command'", + commandLine: "echo 'executes postStart command in the specified workingDir'", + workingDir: "test-dir", hotReloadCapable: false } } diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/old_scripts_configmap_appender_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/old_scripts_configmap_appender_spec.rb index 775331d34f8d2bb97bc80dc6ac449ece2be53dc0..63b3e1ce3aff8e627d96f5e04a8907256d93984c 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/old_scripts_configmap_appender_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/old_scripts_configmap_appender_spec.rb @@ -24,10 +24,12 @@ desired_config: desired_config, name: name, namespace: namespace, + project_path: "test-project", labels: labels, annotations: annotations, devfile_commands: devfile_commands, - devfile_events: devfile_events + devfile_events: devfile_events, + processed_devfile: processed_devfile ) desired_config @@ -56,12 +58,37 @@ create_constants_module::RUN_INTERNAL_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => internal_blocking_poststart_commands_script, create_constants_module::RUN_NON_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => - non_blocking_poststart_commands_script(user_command_ids: ["user-defined-command"]), + non_blocking_poststart_commands_script( + user_command_ids: %w[ + db-component-command-with-working-dir + db-component-command-without-working-dir + main-component-command-without-working-dir + user-defined-command + ], + devfile_commands: devfile_commands + ), "gl-sleep-until-container-is-running-command": sleep_until_container_is_running_script, "gl-start-sshd-command": files::INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT, - "user-defined-command": "echo 'user-defined postStart command'" + "db-component-command-with-working-dir": "echo 'executes postStart command in the specified workingDir'", + "db-component-command-without-working-dir": + "echo 'executes postStart command in the the container's default WORKDIR'", + "main-component-command-without-working-dir": + "echo 'executes postStart command in the projects/project_path directory'", + "user-defined-command": "echo 'executes postStart command in the specified workingDir'" ) + + non_blocking_script = data[create_constants_module::RUN_NON_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym] + expect(non_blocking_script).to include( + '(cd test-dir && /workspace-scripts/db-component-command-with-working-dir) || true' + ) + expect(non_blocking_script).to include( + '/workspace-scripts/db-component-command-without-working-dir || true' + ) + expect(non_blocking_script).to include( + '(cd ${PROJECT_SOURCE}/test-project && /workspace-scripts/main-component-command-without-working-dir) || true' + ) + expect(non_blocking_script).to include('(cd test-dir && /workspace-scripts/user-defined-command) || true') end context "when legacy poststart scripts are used" do diff --git a/ee/spec/requests/remote_development/integration_spec.rb b/ee/spec/requests/remote_development/integration_spec.rb index 21816cffd439119bd897d860426bca5c6af1432a..9add5c8b1aefdeab00ec893676f0492d6d46a94b 100644 --- a/ee/spec/requests/remote_development/integration_spec.rb +++ b/ee/spec/requests/remote_development/integration_spec.rb @@ -76,11 +76,37 @@ let(:user_defined_commands) do [ + { + id: "db-component-command-with-working-dir", + exec: { + component: "database-container", + commandLine: "echo 'executes postStart command in the specified workingDir'", + workingDir: "test-dir", + hotReloadCapable: false + } + }, + { + id: "db-component-command-without-working-dir", + exec: { + component: "database-container", + commandLine: "echo 'executes postStart command in the the container's default WORKDIR'", + hotReloadCapable: false + } + }, + { + id: "main-component-command-without-working-dir", + exec: { + component: "tooling-container", + commandLine: "echo 'executes postStart command in the projects/project_path directory'", + hotReloadCapable: false + } + }, { id: "user-defined-command", exec: { component: "tooling-container", - commandLine: "echo 'user-defined postStart command'", + commandLine: "echo 'executes postStart command in the specified workingDir'", + workingDir: "test-dir", hotReloadCapable: false } } 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 f1cf2b5bc73a66fba2de3169420085705720989e..0335dce3809d55d3f0cf3e12f9aec0763d8a3604 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 @@ -781,7 +781,26 @@ def workspace_deployment( name: "#{workspace_name}-env-var" } } - ] + ], + lifecycle: { + postStart: { + exec: { + command: [ + "/bin/sh", + "-c", + format( + files_module::KUBERNETES_POSTSTART_HOOK_COMMAND, + run_internal_blocking_poststart_commands_script_file_path: + "#{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/" \ + "#{create_constants_module::RUN_INTERNAL_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME}", # rubocop:disable Layout/LineEndStringConcatenationIndentation -- Match default RubyMine formatting + run_non_blocking_poststart_commands_script_file_path: + "#{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/" \ + "#{create_constants_module::RUN_NON_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME}" # rubocop:disable Layout/LineEndStringConcatenationIndentation -- Match default RubyMine formatting + ) + ] + } + } + } }, { image: "quay.io/mloriedo/universal-developer-image:ubi8-dw-demo", @@ -921,6 +940,8 @@ def workspace_deployment( status: {} } + database_container = deployment[:spec][:template][:spec][:containers].find { |c| c[:name] == "database-container" } + unless include_scripts_resources deployment[:spec][:template][:spec][:containers].each do |container| container[:volumeMounts].delete_if do |volume_mount| @@ -931,9 +952,11 @@ def workspace_deployment( volume[:name] == create_constants_module::WORKSPACE_SCRIPTS_VOLUME_NAME end deployment[:spec][:template][:spec][:containers][0].delete(:lifecycle) + database_container&.delete(:lifecycle) end if legacy_poststart_container_command + database_container&.delete(:lifecycle) deployment[:spec][:template][:spec][:containers][0][:lifecycle] = { postStart: { exec: { @@ -950,6 +973,7 @@ def workspace_deployment( } } } + deployment[:spec][:template][:spec][:containers][1][:lifecycle] end if legacy_no_poststart_container_command @@ -1207,44 +1231,68 @@ def workspace_network_policy( # @return [String] def internal_blocking_poststart_commands_script + data_volume_path = workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH <<~SCRIPT #!/bin/sh echo "$(date -Iseconds): ----------------------------------------" echo "$(date -Iseconds): Running #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-clone-project-command..." - #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-clone-project-command || true + (cd #{data_volume_path} && #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-clone-project-command) || true echo "$(date -Iseconds): Finished running #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-clone-project-command." echo "$(date -Iseconds): ----------------------------------------" echo "$(date -Iseconds): Running #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-clone-unshallow-command..." - #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-clone-unshallow-command || true + (cd #{data_volume_path} && #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-clone-unshallow-command) || true echo "$(date -Iseconds): Finished running #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-clone-unshallow-command." echo "$(date -Iseconds): ----------------------------------------" echo "$(date -Iseconds): Running #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-start-sshd-command..." - #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-start-sshd-command || true + (cd #{data_volume_path} && #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-start-sshd-command) || true echo "$(date -Iseconds): Finished running #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-start-sshd-command." echo "$(date -Iseconds): ----------------------------------------" echo "$(date -Iseconds): Running #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-init-tools-command..." - #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-init-tools-command || true + (cd #{data_volume_path} && #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-init-tools-command) || true echo "$(date -Iseconds): Finished running #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-init-tools-command." SCRIPT end # @param [Array] user_command_ids + # @param [Array] devfile_commands + # @param [String] project_path + # @param [String] main_component_name # @return [String] - def non_blocking_poststart_commands_script(user_command_ids: []) + def non_blocking_poststart_commands_script( + user_command_ids:, + devfile_commands:, + project_path: "test-project", + main_component_name: "tooling-container" + ) + data_volume_path = workspace_operations_constants_module::WORKSPACE_DATA_VOLUME_PATH script = <<~SCRIPT #!/bin/sh echo "$(date -Iseconds): ----------------------------------------" echo "$(date -Iseconds): Running #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command..." - #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command || true + (cd #{data_volume_path} && #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command) || true echo "$(date -Iseconds): Finished running #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command." SCRIPT # Add user-defined commands if any user_command_ids.each do |command_id| + command = devfile_commands.find { |cmd| cmd[:id] == command_id } + script_execution = "#{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/#{command_id}" + + working_dir = command.dig(:exec, :workingDir) + component_name = command.dig(:exec, :component) + + effective_working_dir = if working_dir.present? + working_dir + elsif component_name == main_component_name + "${PROJECT_SOURCE}/#{Shellwords.shellescape(project_path)}" + end + + script_execution = "(cd #{effective_working_dir} && #{script_execution})" if effective_working_dir.present? + script += <<~SCRIPT echo "$(date -Iseconds): ----------------------------------------" echo "$(date -Iseconds): Running #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/#{command_id}..." - #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/#{command_id} || true + #{script_execution} || true echo "$(date -Iseconds): Finished running #{create_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/#{command_id}." SCRIPT end @@ -1337,7 +1385,10 @@ def scripts_configmap( create_constants_module::RUN_INTERNAL_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => internal_blocking_poststart_commands_script, create_constants_module::RUN_NON_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => - non_blocking_poststart_commands_script(user_command_ids: user_command_ids), + non_blocking_poststart_commands_script( + user_command_ids: user_command_ids, + devfile_commands: user_defined_commands + ), "gl-sleep-until-container-is-running-command": sleep_until_container_is_running_script, "gl-start-sshd-command": files_module::INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT }