From 6fd32c0c7c34fc30c2dc5293d97b75f9b42a6a02 Mon Sep 17 00:00:00 2001 From: Vishal Tak Date: Tue, 3 Jun 2025 12:55:36 +0530 Subject: [PATCH 1/3] Update post start behaviour for workspace Cloning the project is no longer backgrounded. This prevents the workspace from being marked ready prematurely. Internal post start commands what start sshd andstart vs code continue to be backgrounded. This is because they are long-running processes. Before executing any user-provided post start commands, we will wait for the workspace to be marked ready. This will be backgrounded to not block the workspace from being marked ready. Co-authored-by: Daniyal Arshad --- ee/lib/remote_development/files.rb | 2 + ...internal_poststart_command_start_vscode.sh | 4 +- .../internal_poststart_commands_inserter.rb | 13 +- ...ubernetes_legacy_poststart_hook_command.sh | 5 + .../kubernetes_poststart_hook_command.sh | 15 +- .../kubernetes_poststart_hook_inserter.rb | 27 +- .../output/scripts_configmap_appender.rb | 71 +- .../reconcile/reconcile_constants.rb | 4 +- .../workspace_operations_constants.rb | 2 + .../example.desired_config.json | 2 +- ...ststart-commands-inserted-devfile.yaml.erb | 4 + ...tainer-command-processed-devfile.yaml.erb} | 0 ...ntainer-command-processed-devfile.yaml.erb | 110 +++ .../example.processed-devfile.yaml.erb | 4 + ...red_config_generator_golden_master_spec.rb | 706 +++++++++++++++++- .../output/desired_config_generator_spec.rb | 21 +- ...kubernetes_poststart_hook_inserter_spec.rb | 68 +- .../output/scripts_configmap_appender_spec.rb | 41 +- .../remote_development_shared_contexts.rb | 103 ++- 19 files changed, 1108 insertions(+), 94 deletions(-) create mode 100644 ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_legacy_poststart_hook_command.sh rename ee/spec/fixtures/remote_development/{example.legacy-scripts-in-container-command-processed-devfile.yaml.erb => example.legacy-no-poststart-in-container-command-processed-devfile.yaml.erb} (100%) create mode 100644 ee/spec/fixtures/remote_development/example.legacy-poststart-in-container-command-processed-devfile.yaml.erb diff --git a/ee/lib/remote_development/files.rb b/ee/lib/remote_development/files.rb index 2c14889848f088..c4d98d251e00bb 100644 --- a/ee/lib/remote_development/files.rb +++ b/ee/lib/remote_development/files.rb @@ -38,6 +38,8 @@ def self.read_file(path) 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_LEGACY_POSTSTART_HOOK_COMMAND = + read_file("workspace_operations/reconcile/output/kubernetes_legacy_poststart_hook_command.sh") KUBERNETES_POSTSTART_HOOK_COMMAND = read_file("workspace_operations/reconcile/output/kubernetes_poststart_hook_command.sh") MAIN_COMPONENT_UPDATER_CONTAINER_ARGS = diff --git a/ee/lib/remote_development/workspace_operations/create/internal_poststart_command_start_vscode.sh b/ee/lib/remote_development/workspace_operations/create/internal_poststart_command_start_vscode.sh index 1f11d7e5c90f7e..d585b4d5dc25aa 100644 --- a/ee/lib/remote_development/workspace_operations/create/internal_poststart_command_start_vscode.sh +++ b/ee/lib/remote_development/workspace_operations/create/internal_poststart_command_start_vscode.sh @@ -96,6 +96,4 @@ echo "$(date -Iseconds): - Workspace trust disabled: yes" --port "${GL_VSCODE_PORT}" \ --log "${GL_VSCODE_LOG_LEVEL}" \ --without-connection-token \ - --disable-workspace-trust - -echo "$(date -Iseconds): VS Code: Remote Extension Host process exited with code $?" + --disable-workspace-trust & 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 be6a89412ac726..6f7d584c19d27c 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 @@ -5,6 +5,7 @@ module WorkspaceOperations module Create class InternalPoststartCommandsInserter include CreateConstants + include WorkspaceOperationsConstants include Files include RemoteDevelopmentConstants @@ -61,7 +62,8 @@ def self.insert(context) id: clone_project_command_id, exec: { commandLine: clone_project_script, - component: main_component_name + component: main_component_name, + label: INTERNAL_BLOCKING_COMMAND_LABEL } } poststart_events << clone_project_command_id @@ -72,7 +74,8 @@ def self.insert(context) id: start_sshd_command_id, exec: { commandLine: INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT, - component: main_component_name + component: main_component_name, + label: INTERNAL_BLOCKING_COMMAND_LABEL } } poststart_events << start_sshd_command_id @@ -83,7 +86,8 @@ def self.insert(context) id: start_vscode_command_id, exec: { commandLine: INTERNAL_POSTSTART_COMMAND_START_VSCODE_SCRIPT, - component: main_component_name + component: main_component_name, + label: INTERNAL_BLOCKING_COMMAND_LABEL } } poststart_events << start_vscode_command_id @@ -100,7 +104,8 @@ def self.insert(context) id: sleep_until_container_is_running_command_id, exec: { commandLine: sleep_until_container_is_running_script, - component: main_component_name + component: main_component_name, + label: INTERNAL_COMMAND_LABEL } } poststart_events << sleep_until_container_is_running_command_id diff --git a/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_legacy_poststart_hook_command.sh b/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_legacy_poststart_hook_command.sh new file mode 100644 index 00000000000000..c0963bf88df7ee --- /dev/null +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_legacy_poststart_hook_command.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +mkdir -p "${GL_WORKSPACE_LOGS_DIR}" +ln -sf "${GL_WORKSPACE_LOGS_DIR}" /tmp +"%s" 1>>"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" 2>>"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log" diff --git a/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_command.sh b/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_command.sh index 0bc34317453022..a9364680289926 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_command.sh +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_command.sh @@ -1,3 +1,16 @@ +#!/bin/sh + mkdir -p "${GL_WORKSPACE_LOGS_DIR}" ln -sf "${GL_WORKSPACE_LOGS_DIR}" /tmp -"%s" 1>>"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" 2>>"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log" & + +# shellcheck disable=SC2129 # Better readability +echo "$(date -Iseconds): ----------------------------------------" >> "${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" +echo "$(date -Iseconds): Running poststart commands for workspace..." >> "${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" + +echo "$(date -Iseconds): ----------------------------------------" >> "${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" +echo "$(date -Iseconds): Running internal blocking poststart commands script..." >> "${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" +"%s" 1>>"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" 2>>"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log" + +echo "$(date -Iseconds): ----------------------------------------" >> "${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" +echo "$(date -Iseconds): Running non-blocking poststart commands script..." >> "${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" +"%s" 1>>"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" 2>>"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log" & diff --git a/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_inserter.rb b/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_inserter.rb index 408f5fd59484db..5b2bbdd0291888 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_inserter.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_inserter.rb @@ -16,6 +16,10 @@ class KubernetesPoststartHookInserter # @param [Hash] devfile_events # @return [void] def self.insert(containers:, devfile_commands:, devfile_events:) + internal_blocking_command_label_present = devfile_commands.find do |command| + command.dig(:exec, :label) == INTERNAL_BLOCKING_COMMAND_LABEL + end + devfile_events => { postStart: Array => poststart_command_ids } containers_with_devfile_poststart_commands = @@ -34,12 +38,23 @@ def self.insert(containers:, devfile_commands:, devfile_events:) next unless containers_with_devfile_poststart_commands.include?(container_name) - kubernetes_poststart_hook_script = - format( - KUBERNETES_POSTSTART_HOOK_COMMAND, - run_poststart_commands_script_file_path: - "#{WORKSPACE_SCRIPTS_VOLUME_PATH}/#{RUN_POSTSTART_COMMANDS_SCRIPT_NAME}" - ) + if internal_blocking_command_label_present + kubernetes_poststart_hook_script = + format( + KUBERNETES_POSTSTART_HOOK_COMMAND, + run_internal_blocking_poststart_commands_script_file_path: + "#{WORKSPACE_SCRIPTS_VOLUME_PATH}/#{RUN_INTERNAL_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME}", + run_non_blocking_poststart_commands_script_file_path: + "#{WORKSPACE_SCRIPTS_VOLUME_PATH}/#{RUN_NON_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME}" + ) + else + kubernetes_poststart_hook_script = + format( + KUBERNETES_LEGACY_POSTSTART_HOOK_COMMAND, + run_internal_blocking_poststart_commands_script_file_path: + "#{WORKSPACE_SCRIPTS_VOLUME_PATH}/#{LEGACY_RUN_POSTSTART_COMMANDS_SCRIPT_NAME}" + ) + end container[:lifecycle] = { postStart: { diff --git a/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_configmap_appender.rb b/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_configmap_appender.rb index 717b60d1b71129..75671bb4df3957 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_configmap_appender.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_configmap_appender.rb @@ -6,6 +6,7 @@ module Reconcile module Output class ScriptsConfigmapAppender include ReconcileConstants + include WorkspaceOperationsConstants # @param [Array] desired_config # @param [String] name @@ -39,6 +40,7 @@ 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 ) @@ -75,33 +77,68 @@ def self.add_devfile_command_scripts_to_configmap_data(configmap_data:, devfile_ # @param [Array] devfile_commands # @param [Hash] devfile_events # @return [void] - def self.add_run_poststart_commands_script_to_configmap_data(configmap_data:, devfile_events:) + def self.add_run_poststart_commands_script_to_configmap_data( + configmap_data:, + devfile_commands:, + devfile_events: + ) devfile_events => { postStart: Array => poststart_command_ids } - script_command_lines = - 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 - # container from exitin. Then users can view logs to debug failures. - # See https://github.com/eclipse-che/che/issues/23404#issuecomment-2787779571 - # for more context. - <<~CMD - echo "$(date -Iseconds): Running #{WORKSPACE_SCRIPTS_VOLUME_PATH}/#{poststart_command_id}..." - #{WORKSPACE_SCRIPTS_VOLUME_PATH}/#{poststart_command_id} || true - CMD - end.join - - configmap_data[RUN_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym] = + internal_blocking_command_label_present = devfile_commands.find do |command| + command.dig(:exec, :label) == INTERNAL_BLOCKING_COMMAND_LABEL + end + + unless internal_blocking_command_label_present + 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)} + SH + return + end + + # Segregate internal commands and user provided commands. + # Before any non-blocking post start command is executed, we wait for the workspace to be marked ready. + # TODO: User provided commands should be added to the non-blocking poststart script with https://gitlab.com/gitlab-org/gitlab/-/issues/505988 + internal_blocking_poststart_command_ids, non_blocking_poststart_command_ids = + poststart_command_ids.partition do |id| + command = devfile_commands.find { |cmd| cmd[:id] == id } + command && command.dig(:exec, :label) == INTERNAL_BLOCKING_COMMAND_LABEL + end + + configmap_data[RUN_INTERNAL_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym] = <<~SH.chomp #!/bin/sh - #{script_command_lines} + #{get_poststart_command_script_content(poststart_command_ids: internal_blocking_poststart_command_ids)} + SH + + 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)} SH nil end + # @param [Array] poststart_command_ids + # @return [String] + def self.get_poststart_command_script_content(poststart_command_ids:) + 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 + # container from exiting. Then users can view logs to debug failures. + # See https://github.com/eclipse-che/che/issues/23404#issuecomment-2787779571 + # for more context. + <<~CMD + echo "$(date -Iseconds): Running #{WORKSPACE_SCRIPTS_VOLUME_PATH}/#{poststart_command_id}..." + #{WORKSPACE_SCRIPTS_VOLUME_PATH}/#{poststart_command_id} || true + CMD + end.join + end + private_class_method :add_devfile_command_scripts_to_configmap_data, - :add_run_poststart_commands_script_to_configmap_data + :add_run_poststart_commands_script_to_configmap_data, :get_poststart_command_script_content end end end diff --git a/ee/lib/remote_development/workspace_operations/reconcile/reconcile_constants.rb b/ee/lib/remote_development/workspace_operations/reconcile/reconcile_constants.rb index 7e8c9925b137ee..af9a4ece11b5c5 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/reconcile_constants.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/reconcile_constants.rb @@ -13,8 +13,10 @@ module ReconcileConstants include WorkspaceOperationsConstants # Please keep alphabetized + LEGACY_RUN_POSTSTART_COMMANDS_SCRIPT_NAME = "gl-run-poststart-commands.sh" RUN_AS_USER = 5001 - RUN_POSTSTART_COMMANDS_SCRIPT_NAME = "gl-run-poststart-commands.sh" + RUN_INTERNAL_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME = "gl-run-internal-blocking-poststart-commands.sh" + RUN_NON_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME = "gl-run-non-blocking-poststart-commands.sh" WORKSPACE_SCRIPTS_VOLUME_DEFAULT_MODE = 0o555 WORKSPACE_SCRIPTS_VOLUME_NAME = "gl-workspace-scripts" WORKSPACE_SCRIPTS_VOLUME_PATH = "/workspace-scripts" diff --git a/ee/lib/remote_development/workspace_operations/workspace_operations_constants.rb b/ee/lib/remote_development/workspace_operations/workspace_operations_constants.rb index 0968ac4b118d11..3db8d85e1dd868 100644 --- a/ee/lib/remote_development/workspace_operations/workspace_operations_constants.rb +++ b/ee/lib/remote_development/workspace_operations/workspace_operations_constants.rb @@ -17,6 +17,8 @@ module WorkspaceOperations # See documentation at ../README.md#constant-declarations for more information. module WorkspaceOperationsConstants # Please keep alphabetized + INTERNAL_BLOCKING_COMMAND_LABEL = "gl-internal-blocking" + INTERNAL_COMMAND_LABEL = "gl-internal" VARIABLES_VOLUME_DEFAULT_MODE = 0o774 VARIABLES_VOLUME_NAME = "gl-workspace-variables" VARIABLES_VOLUME_PATH = "/.workspace-data/variables/file" diff --git a/ee/spec/fixtures/remote_development/example.desired_config.json b/ee/spec/fixtures/remote_development/example.desired_config.json index 8d9b5d32e0ae1a..b70c00f250ddb0 100644 --- a/ee/spec/fixtures/remote_development/example.desired_config.json +++ b/ee/spec/fixtures/remote_development/example.desired_config.json @@ -149,7 +149,7 @@ "command": [ "/bin/sh", "-c", - "mkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\"/workspace-scripts/gl-run-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" + "#!/bin/sh\n\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running poststart commands for workspace...\"\n\nmkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running internal blocking poststart commands script...\"\n\"/workspace-scripts/gl-run-internal-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\"\n\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running non-blocking poststart commands script...\"\n\"/workspace-scripts/gl-run-non-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" ] } } 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 4f6cd4db6b108e..b72337b3ac8817 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 @@ -66,16 +66,19 @@ commands: indent_yaml_literal(script, 8) %> component: tooling-container + label: <%= INTERNAL_BLOCKING_COMMAND_LABEL %> - 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 %> - 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 %> - id: gl-sleep-until-container-is-running-command exec: commandLine: | @@ -87,6 +90,7 @@ commands: indent_yaml_literal(script, 8) %> component: tooling-container + label: <%= INTERNAL_COMMAND_LABEL %> events: preStart: - gl-tools-injector-command 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-no-poststart-in-container-command-processed-devfile.yaml.erb similarity index 100% rename from ee/spec/fixtures/remote_development/example.legacy-scripts-in-container-command-processed-devfile.yaml.erb rename to ee/spec/fixtures/remote_development/example.legacy-no-poststart-in-container-command-processed-devfile.yaml.erb diff --git a/ee/spec/fixtures/remote_development/example.legacy-poststart-in-container-command-processed-devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.legacy-poststart-in-container-command-processed-devfile.yaml.erb new file mode 100644 index 00000000000000..ea73a5c21fcf5c --- /dev/null +++ b/ee/spec/fixtures/remote_development/example.legacy-poststart-in-container-command-processed-devfile.yaml.erb @@ -0,0 +1,110 @@ +--- +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" + volumeMounts: + - name: gl-workspace-data + path: /projects + 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 + volumeMounts: + - name: gl-workspace-data + path: /projects + env: + - name: MYSQL_ROOT_PASSWORD + value: "my-secret-pw" + dedicatedPod: false + mountSources: true + - name: gl-tools-injector + container: + image: <%= WORKSPACE_TOOLS_IMAGE %> + volumeMounts: + - name: gl-workspace-data + path: /projects + env: + - name: GL_TOOLS_DIR + value: "/projects/.gl-tools" + memoryLimit: 512Mi + memoryRequest: 256Mi + cpuLimit: 500m + cpuRequest: 100m + - name: gl-workspace-data + volume: + size: 50Gi +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.processed-devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb index ea73a5c21fcf5c..00be4f60fa32bd 100644 --- a/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb @@ -78,16 +78,19 @@ commands: indent_yaml_literal(script, 8) %> component: tooling-container + label: <%= INTERNAL_BLOCKING_COMMAND_LABEL %> - 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 %> - 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 %> - id: gl-sleep-until-container-is-running-command exec: commandLine: | @@ -99,6 +102,7 @@ commands: indent_yaml_literal(script, 8) %> component: tooling-container + label: <%= INTERNAL_COMMAND_LABEL %> events: preStart: - gl-tools-injector-command 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 cfbcabeeed261d..b013ccaca40deb 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 @@ -165,6 +165,15 @@ it_behaves_like "generated desired_config golden master checks" + context "with legacy devfile that includes postStart event" do + let(:input_processed_devfile_yaml) { input_processed_devfile_yaml_with_legacy_poststart_event } + let(:golden_master_desired_config) do + golden_master_desired_config_from_legacy_devfile_with_poststart_and_with_include_all_resources_true + end + + it_behaves_like "generated desired_config golden master checks" + end + context "with legacy devfile that does not include postStart event" do let(:input_processed_devfile_yaml) { input_processed_devfile_yaml_without_poststart_event } let(:golden_master_desired_config) do @@ -257,9 +266,88 @@ def input_processed_devfile_yaml_with_poststart_event volume: size: 50Gi commands: - - id: example-poststart-exec-command + - id: gl-internal-example-command-1 + exec: + commandLine: "echo 'gl-internal-example-command-1'" + component: tooling-container + label: gl-internal-blocking + - id: gl-internal-example-command-2 + exec: + commandLine: "echo 'gl-internal-example-command-2'" + component: tooling-container + - id: example-prestart-apply-command + apply: + component: sidecar-container + events: + preStart: + - example-prestart-apply-command + postStart: + - gl-internal-example-command-1 + - gl-internal-example-command-2 + variables: {} + YAML + end + + # @return [String] + def input_processed_devfile_yaml_with_legacy_poststart_event + <<~YAML + --- + 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: + - "echo 'tooling container args'" + command: + - "/bin/sh" + - "-c" + volumeMounts: + - name: gl-workspace-data + path: /projects + env: + - name: GL_ENV_NAME + value: "gl-env-value" + endpoints: + - name: server + targetPort: 60001 + exposure: public + secure: true + protocol: https + dedicatedPod: false + mountSources: true + - name: sidecar-container + container: + image: "sidecar-container:latest" + volumeMounts: + - name: gl-workspace-data + path: "/projects" + env: + - name: GL_ENV2_NAME + value: "gl-env2-value" + args: + - "echo 'sidecar container args'" + command: + - "/bin/sh" + - "-c" + memoryLimit: 1000Mi + memoryRequest: 500Mi + cpuLimit: 500m + cpuRequest: 100m + - name: gl-workspace-data + volume: + size: 50Gi + commands: + - id: gl-internal-example-command-1 + exec: + commandLine: "echo 'gl-internal-example-command-1'" + component: tooling-container + - id: gl-internal-example-command-2 exec: - commandLine: "echo 'example poststart exec command'" + commandLine: "echo 'gl-internal-example-command-2'" component: tooling-container - id: example-prestart-apply-command apply: @@ -268,7 +356,8 @@ def input_processed_devfile_yaml_with_poststart_event preStart: - example-prestart-apply-command postStart: - - example-poststart-exec-command + - gl-internal-example-command-1 + - gl-internal-example-command-2 variables: {} YAML end @@ -537,7 +626,7 @@ def golden_master_desired_config_with_include_all_resources_true command: [ "/bin/sh", "-c", - "mkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\"/workspace-scripts/gl-run-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" + "#!/bin/sh\n\nmkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\n# shellcheck disable=SC2129 # Better readability\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running poststart commands for workspace...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running internal blocking poststart commands script...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\"/workspace-scripts/gl-run-internal-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\"\n\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running non-blocking poststart commands script...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\"/workspace-scripts/gl-run-non-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" ] } } @@ -855,8 +944,10 @@ 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/example-poststart-exec-command...\"\n/workspace-scripts/example-poststart-exec-command || true\n", - "example-poststart-exec-command": "echo 'example poststart exec command'" + "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n/workspace-scripts/gl-internal-example-command-1 || true\n", + "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n/workspace-scripts/gl-internal-example-command-2 || true\n", + "gl-internal-example-command-1": "echo 'gl-internal-example-command-1'", + "gl-internal-example-command-2": "echo 'gl-internal-example-command-2'" } }, { @@ -1115,7 +1206,7 @@ def golden_master_desired_config_with_include_all_resources_false command: [ "/bin/sh", "-c", - "mkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\"/workspace-scripts/gl-run-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" + "#!/bin/sh\n\nmkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\n# shellcheck disable=SC2129 # Better readability\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running poststart commands for workspace...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running internal blocking poststart commands script...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\"/workspace-scripts/gl-run-internal-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\"\n\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running non-blocking poststart commands script...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\"/workspace-scripts/gl-run-non-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" ] } } @@ -1433,8 +1524,589 @@ 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/example-poststart-exec-command...\"\n/workspace-scripts/example-poststart-exec-command || true\n", - "example-poststart-exec-command": "echo 'example poststart exec command'" + "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n/workspace-scripts/gl-internal-example-command-1 || true\n", + "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n/workspace-scripts/gl-internal-example-command-2 || true\n", + "gl-internal-example-command-1": "echo 'gl-internal-example-command-1'", + "gl-internal-example-command-2": "echo 'gl-internal-example-command-2'" + } + } + ] + end + + # @return [Array] + def golden_master_desired_config_from_legacy_devfile_with_poststart_and_with_include_all_resources_true + [ + { + apiVersion: "v1", + kind: "ConfigMap", + metadata: { + annotations: { + environment: "production", + team: "engineering", + "workspaces.gitlab.com/host-template": "{{.port}}-workspace-991-990-fedcba.workspaces.localdev.me", + "workspaces.gitlab.com/id": "993", + "workspaces.gitlab.com/max-resources-per-workspace-sha256": "24aefc317e11db538ede450d1773e273966b9801b988d49e1219f2a9bf8e7f66" + }, + labels: { + app: "workspace", + tier: "development", + "agent.gitlab.com/id": "991", + "cli-utils.sigs.k8s.io/inventory-id": "workspace-991-990-fedcba-workspace-inventory" + }, + name: "workspace-991-990-fedcba-workspace-inventory", + namespace: "gl-rd-ns-991-990-fedcba" + } + }, + { + apiVersion: "apps/v1", + kind: "Deployment", + metadata: { + annotations: { + environment: "production", + team: "engineering", + "config.k8s.io/owning-inventory": "workspace-991-990-fedcba-workspace-inventory", + "workspaces.gitlab.com/host-template": "{{.port}}-workspace-991-990-fedcba.workspaces.localdev.me", + "workspaces.gitlab.com/id": "993", + "workspaces.gitlab.com/max-resources-per-workspace-sha256": "24aefc317e11db538ede450d1773e273966b9801b988d49e1219f2a9bf8e7f66" + }, + creationTimestamp: nil, + labels: { + app: "workspace", + tier: "development", + "agent.gitlab.com/id": "991" + }, + name: "workspace-991-990-fedcba", + namespace: "gl-rd-ns-991-990-fedcba" + }, + spec: { + replicas: 1, + selector: { + matchLabels: { + app: "workspace", + tier: "development", + "agent.gitlab.com/id": "991" + } + }, + strategy: { + type: "Recreate" + }, + template: { + metadata: { + annotations: { + environment: "production", + team: "engineering", + "config.k8s.io/owning-inventory": "workspace-991-990-fedcba-workspace-inventory", + "workspaces.gitlab.com/host-template": "{{.port}}-workspace-991-990-fedcba.workspaces.localdev.me", + "workspaces.gitlab.com/id": "993", + "workspaces.gitlab.com/max-resources-per-workspace-sha256": "24aefc317e11db538ede450d1773e273966b9801b988d49e1219f2a9bf8e7f66" + }, + creationTimestamp: nil, + labels: { + app: "workspace", + tier: "development", + "agent.gitlab.com/id": "991" + }, + name: "workspace-991-990-fedcba", + namespace: "gl-rd-ns-991-990-fedcba" + }, + spec: + { + containers: [ + { + args: [ + "echo 'tooling container args'" + ], + command: [ + "/bin/sh", + "-c" + ], + env: [ + { + name: "GL_ENV_NAME", + value: "gl-env-value" + }, + { + name: "PROJECTS_ROOT", + value: "/projects" + }, + { + name: "PROJECT_SOURCE", + value: "/projects" + } + ], + envFrom: [ + { + secretRef: { + name: "workspace-991-990-fedcba-env-var" + } + } + ], + image: "quay.io/mloriedo/universal-developer-image:ubi8-dw-demo", + imagePullPolicy: "Always", + name: "tooling-container", + ports: [ + { + containerPort: 60001, + name: "server", + protocol: "TCP" + } + ], + resources: { + limits: { + cpu: "1", + memory: "1Gi" + }, + requests: { + cpu: "0.5", + memory: "512Mi" + } + }, + securityContext: { + allowPrivilegeEscalation: false, + privileged: false, + runAsNonRoot: true, + runAsUser: 5001 + }, + volumeMounts: [ + { + mountPath: "/projects", + name: "gl-workspace-data" + }, + { + mountPath: "/.workspace-data/variables/file", + name: "gl-workspace-variables" + }, + { + name: "gl-workspace-scripts", + mountPath: "/workspace-scripts" + } + ], + lifecycle: { + postStart: { + exec: { + command: [ + "/bin/sh", + "-c", + "#!/bin/sh\n\nmkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\"/workspace-scripts/gl-run-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\"\n" + ] + } + } + } + } + ], + initContainers: [ + { + args: [ + "echo 'sidecar container args'" + ], + command: [ + "/bin/sh", + "-c" + ], + env: [ + { + name: "GL_ENV2_NAME", + value: "gl-env2-value" + }, + { + name: "PROJECTS_ROOT", + value: "/projects" + }, + { + name: "PROJECT_SOURCE", + value: "/projects" + } + ], + envFrom: [ + { + secretRef: { + name: "workspace-991-990-fedcba-env-var" + } + } + ], + image: "sidecar-container:latest", + imagePullPolicy: "Always", + name: "sidecar-container-example-prestart-apply-command-1", + resources: { + limits: { + cpu: "500m", + memory: "1000Mi" + }, + requests: { + cpu: "100m", + memory: "500Mi" + } + }, + securityContext: { + allowPrivilegeEscalation: false, + privileged: false, + runAsNonRoot: true, + runAsUser: 5001 + }, + volumeMounts: [ + { + mountPath: "/projects", + name: "gl-workspace-data" + }, + { + mountPath: "/.workspace-data/variables/file", + name: "gl-workspace-variables" + } + ] + } + ], + runtimeClassName: "standard", + securityContext: { + fsGroup: 0, + fsGroupChangePolicy: "OnRootMismatch", + runAsNonRoot: true, + runAsUser: 5001 + }, + serviceAccountName: "workspace-991-990-fedcba", + volumes: [ + { + name: "gl-workspace-data", + persistentVolumeClaim: { + claimName: "workspace-991-990-fedcba-gl-workspace-data" + } + }, + { + name: "gl-workspace-variables", + projected: { + defaultMode: 0o774, + sources: [ + { + secret: { + name: "workspace-991-990-fedcba-file" + } + } + ] + } + }, + { + name: "gl-workspace-scripts", + projected: { + defaultMode: 0o555, + sources: [ + { + configMap: { + name: "workspace-991-990-fedcba-scripts-configmap" + } + } + ] + } + } + ] + } + } + }, + status: {} + }, + { + apiVersion: "v1", + kind: "Service", + metadata: { + annotations: { + environment: "production", + team: "engineering", + "config.k8s.io/owning-inventory": "workspace-991-990-fedcba-workspace-inventory", + "workspaces.gitlab.com/host-template": "{{.port}}-workspace-991-990-fedcba.workspaces.localdev.me", + "workspaces.gitlab.com/id": "993", + "workspaces.gitlab.com/max-resources-per-workspace-sha256": "24aefc317e11db538ede450d1773e273966b9801b988d49e1219f2a9bf8e7f66" + }, + creationTimestamp: nil, + labels: { + app: "workspace", + tier: "development", + "agent.gitlab.com/id": "991" + }, + name: "workspace-991-990-fedcba", + namespace: "gl-rd-ns-991-990-fedcba" + }, + spec: { + ports: [ + { + name: "server", + port: 60001, + targetPort: 60001 + } + ], + selector: { + app: "workspace", + tier: "development", + "agent.gitlab.com/id": "991" + } + }, + status: { + loadBalancer: {} + } + }, + { + apiVersion: "v1", + kind: "PersistentVolumeClaim", + metadata: { + annotations: { + environment: "production", + team: "engineering", + "config.k8s.io/owning-inventory": "workspace-991-990-fedcba-workspace-inventory", + "workspaces.gitlab.com/host-template": "{{.port}}-workspace-991-990-fedcba.workspaces.localdev.me", + "workspaces.gitlab.com/id": "993", + "workspaces.gitlab.com/max-resources-per-workspace-sha256": "24aefc317e11db538ede450d1773e273966b9801b988d49e1219f2a9bf8e7f66" + }, + creationTimestamp: nil, + labels: { + app: "workspace", + tier: "development", + "agent.gitlab.com/id": "991" + }, + name: "workspace-991-990-fedcba-gl-workspace-data", + namespace: "gl-rd-ns-991-990-fedcba" + }, + spec: { + accessModes: [ + "ReadWriteOnce" + ], + resources: { + requests: { + storage: "50Gi" + } + } + }, + status: {} + }, + { + apiVersion: "v1", + automountServiceAccountToken: false, + imagePullSecrets: [ + { + name: "registry-secret" + } + ], + kind: "ServiceAccount", + metadata: { + annotations: { + environment: "production", + team: "engineering", + "config.k8s.io/owning-inventory": "workspace-991-990-fedcba-workspace-inventory", + "workspaces.gitlab.com/host-template": "{{.port}}-workspace-991-990-fedcba.workspaces.localdev.me", + "workspaces.gitlab.com/id": "993", + "workspaces.gitlab.com/max-resources-per-workspace-sha256": "24aefc317e11db538ede450d1773e273966b9801b988d49e1219f2a9bf8e7f66" + }, + labels: { + app: "workspace", + tier: "development", + "agent.gitlab.com/id": "991" + }, + name: "workspace-991-990-fedcba", + namespace: "gl-rd-ns-991-990-fedcba" + } + }, + { + apiVersion: "networking.k8s.io/v1", + kind: "NetworkPolicy", + metadata: { + annotations: { + environment: "production", + team: "engineering", + "config.k8s.io/owning-inventory": "workspace-991-990-fedcba-workspace-inventory", + "workspaces.gitlab.com/host-template": "{{.port}}-workspace-991-990-fedcba.workspaces.localdev.me", + "workspaces.gitlab.com/id": "993", + "workspaces.gitlab.com/max-resources-per-workspace-sha256": "24aefc317e11db538ede450d1773e273966b9801b988d49e1219f2a9bf8e7f66" + }, + labels: { + app: "workspace", + tier: "development", + "agent.gitlab.com/id": "991" + }, + name: "workspace-991-990-fedcba", + namespace: "gl-rd-ns-991-990-fedcba" + }, + spec: { + egress: [ + { + ports: [ + { + port: 53, + protocol: "TCP" + }, + { + port: 53, + protocol: "UDP" + } + ], + to: [ + { + namespaceSelector: { + matchLabels: { + "kubernetes.io/metadata.name": "kube-system" + } + } + } + ] + }, + { + to: [ + { + ipBlock: { + cidr: "0.0.0.0/0", + except: [ + "10.0.0.0/8", + "172.16.0.0/12", + "192.168.0.0/16" + ] + } + } + ] + } + ], + ingress: [ + { + from: [ + { + namespaceSelector: { + matchLabels: { + "kubernetes.io/metadata.name": "gitlab-workspaces" + } + }, + podSelector: { + matchLabels: { + "app.kubernetes.io/name": "gitlab-workspaces-proxy" + } + } + } + ] + } + ], + podSelector: {}, + policyTypes: [ + "Ingress", + "Egress" + ] + } + }, + { + apiVersion: "v1", + kind: "ConfigMap", + metadata: { + annotations: { + environment: "production", + team: "engineering", + "config.k8s.io/owning-inventory": "workspace-991-990-fedcba-workspace-inventory", + "workspaces.gitlab.com/host-template": "{{.port}}-workspace-991-990-fedcba.workspaces.localdev.me", + "workspaces.gitlab.com/id": "993", + "workspaces.gitlab.com/max-resources-per-workspace-sha256": "24aefc317e11db538ede450d1773e273966b9801b988d49e1219f2a9bf8e7f66" + }, + labels: { + app: "workspace", + tier: "development", + "agent.gitlab.com/id": "991" + }, + name: "workspace-991-990-fedcba-scripts-configmap", + namespace: "gl-rd-ns-991-990-fedcba" + }, + data: { + "gl-run-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n/workspace-scripts/gl-internal-example-command-1 || true\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n/workspace-scripts/gl-internal-example-command-2 || true\n", + "gl-internal-example-command-1": "echo 'gl-internal-example-command-1'", + "gl-internal-example-command-2": "echo 'gl-internal-example-command-2'" + } + }, + { + apiVersion: "v1", + kind: "ConfigMap", + metadata: { + annotations: { + environment: "production", + team: "engineering", + "workspaces.gitlab.com/host-template": "{{.port}}-workspace-991-990-fedcba.workspaces.localdev.me", + "workspaces.gitlab.com/id": "993", + "workspaces.gitlab.com/max-resources-per-workspace-sha256": "24aefc317e11db538ede450d1773e273966b9801b988d49e1219f2a9bf8e7f66" + }, + labels: { + app: "workspace", + tier: "development", + "agent.gitlab.com/id": "991", + "cli-utils.sigs.k8s.io/inventory-id": "workspace-991-990-fedcba-secrets-inventory" + }, + name: "workspace-991-990-fedcba-secrets-inventory", + namespace: "gl-rd-ns-991-990-fedcba" + } + }, + { + apiVersion: "v1", + kind: "ResourceQuota", + metadata: { + annotations: { + environment: "production", + team: "engineering", + "config.k8s.io/owning-inventory": "workspace-991-990-fedcba-workspace-inventory", + "workspaces.gitlab.com/host-template": "{{.port}}-workspace-991-990-fedcba.workspaces.localdev.me", + "workspaces.gitlab.com/id": "993", + "workspaces.gitlab.com/max-resources-per-workspace-sha256": "24aefc317e11db538ede450d1773e273966b9801b988d49e1219f2a9bf8e7f66" + }, + labels: { + app: "workspace", + tier: "development", + "agent.gitlab.com/id": "991" + }, + name: "workspace-991-990-fedcba", + namespace: "gl-rd-ns-991-990-fedcba" + }, + spec: { + hard: { + "limits.cpu": "2", + "limits.memory": "4Gi", + "requests.cpu": "1", + "requests.memory": "1Gi" + } + } + }, + { + apiVersion: "v1", + data: { + ENV_VAR1: "ZW52LXZhci12YWx1ZTE=" + }, + kind: "Secret", + metadata: { + annotations: { + environment: "production", + team: "engineering", + "config.k8s.io/owning-inventory": "workspace-991-990-fedcba-secrets-inventory", + "workspaces.gitlab.com/host-template": "{{.port}}-workspace-991-990-fedcba.workspaces.localdev.me", + "workspaces.gitlab.com/id": "993", + "workspaces.gitlab.com/max-resources-per-workspace-sha256": "24aefc317e11db538ede450d1773e273966b9801b988d49e1219f2a9bf8e7f66" + }, + labels: { + app: "workspace", + tier: "development", + "agent.gitlab.com/id": "991" + }, + name: "workspace-991-990-fedcba-env-var", + namespace: "gl-rd-ns-991-990-fedcba" + } + }, + { + apiVersion: "v1", + data: { + FILE_VAR1: "ZmlsZS12YXItdmFsdWUx", + "gl_workspace_reconciled_actual_state.txt": "UnVubmluZw==" + }, + kind: "Secret", + metadata: { + annotations: { + environment: "production", + team: "engineering", + "config.k8s.io/owning-inventory": "workspace-991-990-fedcba-secrets-inventory", + "workspaces.gitlab.com/host-template": "{{.port}}-workspace-991-990-fedcba.workspaces.localdev.me", + "workspaces.gitlab.com/id": "993", + "workspaces.gitlab.com/max-resources-per-workspace-sha256": "24aefc317e11db538ede450d1773e273966b9801b988d49e1219f2a9bf8e7f66" + }, + labels: { + app: "workspace", + tier: "development", + "agent.gitlab.com/id": "991" + }, + name: "workspace-991-990-fedcba-file", + namespace: "gl-rd-ns-991-990-fedcba" } } ] @@ -2169,7 +2841,7 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources command: [ "/bin/sh", "-c", - "mkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\"/workspace-scripts/gl-run-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" + "#!/bin/sh\n\nmkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\n# shellcheck disable=SC2129 # Better readability\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running poststart commands for workspace...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running internal blocking poststart commands script...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\"/workspace-scripts/gl-run-internal-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\"\n\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running non-blocking poststart commands script...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\"/workspace-scripts/gl-run-non-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" ] } } @@ -2497,8 +3169,10 @@ 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/example-poststart-exec-command...\"\n/workspace-scripts/example-poststart-exec-command || true\n", - "example-poststart-exec-command": "echo 'example poststart exec command'" + "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n/workspace-scripts/gl-internal-example-command-1 || true\n", + "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n/workspace-scripts/gl-internal-example-command-2 || true\n", + "gl-internal-example-command-1": "echo 'gl-internal-example-command-1'", + "gl-internal-example-command-2": "echo 'gl-internal-example-command-2'" } }, { @@ -2735,7 +3409,7 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources command: [ "/bin/sh", "-c", - "mkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\"/workspace-scripts/gl-run-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" + "#!/bin/sh\n\nmkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\n# shellcheck disable=SC2129 # Better readability\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running poststart commands for workspace...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running internal blocking poststart commands script...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\"/workspace-scripts/gl-run-internal-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\"\n\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running non-blocking poststart commands script...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\"/workspace-scripts/gl-run-non-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" ] } } @@ -3063,8 +3737,10 @@ 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/example-poststart-exec-command...\"\n/workspace-scripts/example-poststart-exec-command || true\n", - "example-poststart-exec-command": "echo 'example poststart exec command'" + "gl-run-internal-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-1...\"\n/workspace-scripts/gl-internal-example-command-1 || true\n", + "gl-run-non-blocking-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): Running /workspace-scripts/gl-internal-example-command-2...\"\n/workspace-scripts/gl-internal-example-command-2 || true\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/desired_config_generator_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_spec.rb index ee6e6b582a72c2..871c71e3474a21 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_spec.rb @@ -16,7 +16,8 @@ let(:desired_state_is_terminated) { false } let(:include_all_resources) { false } let(:include_scripts_resources) { true } - let(:legacy_scripts_in_container_command) { false } + let(:legacy_no_poststart_container_command) { false } + let(:legacy_poststart_container_command) { false } let(:deployment_resource_version_from_agent) { workspace.deployment_resource_version } let(:network_policy_enabled) { true } let(:gitlab_workspaces_proxy_namespace) { 'gitlab-workspaces' } @@ -59,7 +60,8 @@ include_network_policy: workspace.workspaces_agent_config.network_policy_enabled, include_all_resources: include_all_resources, include_scripts_resources: include_scripts_resources, - legacy_scripts_in_container_command: legacy_scripts_in_container_command, + legacy_no_poststart_container_command: legacy_no_poststart_container_command, + legacy_poststart_container_command: legacy_poststart_container_command, egress_ip_rules: workspace.workspaces_agent_config.network_policy_egress.map(&:deep_symbolize_keys), max_resources_per_workspace: max_resources_per_workspace, default_resources_per_workspace_container: default_resources_per_workspace_container, @@ -245,11 +247,22 @@ end end + context "when legacy postStart events are present in devfile" do + let(:legacy_poststart_container_command) { true } + let(:processed_devfile_yaml) do + read_devfile_yaml("example.legacy-poststart-in-container-command-processed-devfile.yaml.erb") + end + + it 'returns expected config without script resources' do + expect(workspace_resources).to eq(expected_config) + end + end + context "when postStart events are not present in devfile" do let(:include_scripts_resources) { false } - let(:legacy_scripts_in_container_command) { true } + let(:legacy_no_poststart_container_command) { true } let(:processed_devfile_yaml) do - read_devfile_yaml("example.legacy-scripts-in-container-command-processed-devfile.yaml.erb") + read_devfile_yaml("example.legacy-no-poststart-in-container-command-processed-devfile.yaml.erb") end it 'returns expected config without script resources' do diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_inserter_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_inserter_spec.rb index c562a5a17c82d1..de667b3c3fde19 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_inserter_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_inserter_spec.rb @@ -8,8 +8,12 @@ let(:processed_devfile) { example_processed_devfile } let(:devfile_commands) { processed_devfile.fetch(:commands) } let(:devfile_events) { processed_devfile.fetch(:events) } + let(:legacy_poststart_container_command) { false } let(:input_containers) do - deployment = create_deployment(include_scripts_resources: false) + deployment = create_deployment( + include_scripts_resources: false, + legacy_poststart_container_command: legacy_poststart_container_command + ) deployment => { spec: { template: { @@ -23,7 +27,10 @@ end let(:expected_containers) do - deployment = create_deployment(include_scripts_resources: true) + deployment = create_deployment( + include_scripts_resources: true, + legacy_poststart_container_command: legacy_poststart_container_command + ) deployment => { spec: { template: { @@ -45,41 +52,58 @@ ) end + shared_examples "successful insertion of postStart lifecycle hooks" do + it "inserts postStart lifecycle hooks", :unlimited_max_formatted_output_length do + invoke_insert + + expected_containers => [ + *_, + { + lifecycle: Hash => first_container_expected_lifecycle_hooks + }, + *_ + ] + + input_containers => [ + *_, + { + lifecycle: Hash => first_container_updated_lifecycle_hooks + }, + *_ + ] + + expect(first_container_updated_lifecycle_hooks).to eq(first_container_expected_lifecycle_hooks) + end + end + it "has valid fixtures with no lifecycle in any input_containers" do expect(input_containers.any? { |c| c[:lifecycle] }).to be false end - it "inserts postStart lifecycle hooks", :unlimited_max_formatted_output_length do - invoke_insert - - expected_containers => [ - *_, - { - lifecycle: Hash => first_container_expected_lifecycle_hooks - }, - *_ - ] + it_behaves_like "successful insertion of postStart lifecycle hooks" - input_containers => [ - *_, - { - lifecycle: Hash => first_container_updated_lifecycle_hooks - }, - *_ - ] + context "when legacy poststart scripts are used" do + let(:legacy_poststart_container_command) { true } + let(:processed_devfile) do + yaml_safe_load_symbolized( + read_devfile_yaml("example.legacy-poststart-in-container-command-processed-devfile.yaml.erb") + ) + end - expect(first_container_updated_lifecycle_hooks).to eq(first_container_expected_lifecycle_hooks) + it_behaves_like "successful insertion of postStart lifecycle hooks" end private # @param [Boolean] include_scripts_resources + # # @param [Boolean] legacy_poststart_container_command # @return [Hash] - def create_deployment(include_scripts_resources:) + def create_deployment(include_scripts_resources:, legacy_poststart_container_command:) workspace_deployment( workspace_name: "name", workspace_namespace: "namespace", - include_scripts_resources: include_scripts_resources + include_scripts_resources: include_scripts_resources, + legacy_poststart_container_command: legacy_poststart_container_command ) end end 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 f9e81477315d17..23c9eca6be6a3c 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 @@ -52,11 +52,48 @@ expect(data).to eq( "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 => - postart_commands_script, + reconcile_constants_module::RUN_INTERNAL_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => + internal_blocking_poststart_commands_script, + reconcile_constants_module::RUN_NON_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => + non_blocking_poststart_commands_script, "gl-sleep-until-container-is-running-command": sleep_until_container_is_running_script, "gl-start-sshd-command": files::INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT ) end + + context "when legacy poststart scripts are used" do + let(:processed_devfile) do + yaml_safe_load_symbolized( + read_devfile_yaml("example.legacy-poststart-in-container-command-processed-devfile.yaml.erb") + ) + end + + it "appends ConfigMap to desired_config" do + expect(updated_desired_config.length).to eq(2) + + updated_desired_config => [ + {}, # existing fake element + { + apiVersion: api_version, + metadata: { + name: configmap_name + }, + data: data + }, + ] + + expect(api_version).to eq("v1") + expect(configmap_name).to eq(name) + expect(data).to eq( + "gl-clone-project-command": clone_project_script, + "gl-init-tools-command": files::INTERNAL_POSTSTART_COMMAND_START_VSCODE_SCRIPT, + reconcile_constants_module::LEGACY_RUN_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => + legacy_poststart_commands_script, + "gl-sleep-until-container-is-running-command": + sleep_until_container_is_running_script, + "gl-start-sshd-command": files::INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT + ) + end + end end diff --git a/ee/spec/support/shared_contexts/remote_development/remote_development_shared_contexts.rb b/ee/spec/support/shared_contexts/remote_development/remote_development_shared_contexts.rb index 8f96456bef6160..95232f6bc5ec62 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 @@ -354,7 +354,7 @@ def create_config_to_apply(workspace:, **args) # @param [String] namespace_path # @param [Array] image_pull_secrets # @param [Boolean] include_scripts_resources - # @param [Boolean] legacy_scripts_in_container_command + # @param [Boolean] legacy_no_poststart_container_command # @param [String] shared_namespace # @param [Boolean] core_resources_only # @return [Array] @@ -384,7 +384,8 @@ def create_config_to_apply_v3( namespace_path: "test-group", image_pull_secrets: [], include_scripts_resources: true, - legacy_scripts_in_container_command: false, + legacy_no_poststart_container_command: false, + legacy_poststart_container_command: false, shared_namespace: "", core_resources_only: false ) @@ -436,7 +437,8 @@ def create_config_to_apply_v3( use_kubernetes_user_namespaces: use_kubernetes_user_namespaces, default_runtime_class: default_runtime_class, include_scripts_resources: include_scripts_resources, - legacy_scripts_in_container_command: legacy_scripts_in_container_command + legacy_no_poststart_container_command: legacy_no_poststart_container_command, + legacy_poststart_container_command: legacy_poststart_container_command ) workspace_service = workspace_service( @@ -473,7 +475,8 @@ def create_config_to_apply_v3( workspace_name: workspace.name, workspace_namespace: workspace.namespace, labels: labels, - annotations: workspace_inventory_annotations + annotations: workspace_inventory_annotations, + legacy_poststart_container_command: legacy_poststart_container_command ) secrets_inventory_config_map = secrets_inventory_config_map( @@ -580,7 +583,8 @@ def workspace_inventory_config_map(workspace_name:, workspace_namespace:, labels # @param [Hash] default_resources_per_workspace_container # @param [String] default_runtime_class # @param [Boolean] include_scripts_resources - # @param [Boolean] legacy_scripts_in_container_command + # @param [Boolean] legacy_no_poststart_container_command + # @param [Boolean] legacy_poststart_container_command # @param [Hash] labels # @param [Integer] spec_replicas # @param [Boolean] use_kubernetes_user_namespaces @@ -593,7 +597,8 @@ def workspace_deployment( default_resources_per_workspace_container: {}, default_runtime_class: "", include_scripts_resources: true, - legacy_scripts_in_container_command: false, + legacy_no_poststart_container_command: false, + legacy_poststart_container_command: false, labels: {}, spec_replicas: 1, use_kubernetes_user_namespaces: false @@ -715,9 +720,12 @@ def workspace_deployment( "-c", format( files_module::KUBERNETES_POSTSTART_HOOK_COMMAND, - run_poststart_commands_script_file_path: + run_internal_blocking_poststart_commands_script_file_path: + "#{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/" \ + "#{reconcile_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: "#{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/" \ - "#{reconcile_constants_module::RUN_POSTSTART_COMMANDS_SCRIPT_NAME}" # rubocop:disable Layout/LineEndStringConcatenationIndentation -- Match default RubyMien formatting + "#{reconcile_constants_module::RUN_NON_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME}" # rubocop:disable Layout/LineEndStringConcatenationIndentation -- Match default RubyMine formatting ) ] } @@ -876,7 +884,26 @@ def workspace_deployment( deployment[:spec][:template][:spec][:containers][0].delete(:lifecycle) end - if legacy_scripts_in_container_command + if legacy_poststart_container_command + deployment[:spec][:template][:spec][:containers][0][:lifecycle] = { + postStart: { + exec: { + command: [ + "/bin/sh", + "-c", + format( + files_module::KUBERNETES_LEGACY_POSTSTART_HOOK_COMMAND, + run_internal_blocking_poststart_commands_script_file_path: + "#{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/" \ + "#{reconcile_constants_module::LEGACY_RUN_POSTSTART_COMMANDS_SCRIPT_NAME}" # rubocop:disable Layout/LineEndStringConcatenationIndentation -- Match default RubyMine formatting + ) + ] + } + } + } + end + + if legacy_no_poststart_container_command # Add the container args for the container where tools are injected deployment[:spec][:template][:spec][:containers][0][:args][0] = <<~YAML.chomp @@ -1130,7 +1157,28 @@ def workspace_network_policy( end # @return [String] - def postart_commands_script + def internal_blocking_poststart_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 + SCRIPT + end + + # @return [String] + def non_blocking_poststart_commands_script + <<~SCRIPT + #!/bin/sh + 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 + + def legacy_poststart_commands_script <<~SCRIPT #!/bin/sh echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-clone-project-command..." @@ -1173,8 +1221,33 @@ def sleep_until_container_is_running_script # @param [String] workspace_namespace # @param [Hash] labels # @param [Hash] annotations + # @param [Boolean] legacy_poststart_container_command # @return [Hash] - def scripts_configmap(workspace_name:, workspace_namespace:, labels:, annotations:) + def scripts_configmap( + workspace_name:, + workspace_namespace:, + labels:, + annotations:, + legacy_poststart_container_command: + ) + data = { + "gl-clone-project-command": clone_project_script, + "gl-init-tools-command": files_module::INTERNAL_POSTSTART_COMMAND_START_VSCODE_SCRIPT, + reconcile_constants_module::RUN_INTERNAL_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => + internal_blocking_poststart_commands_script, + reconcile_constants_module::RUN_NON_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => + non_blocking_poststart_commands_script, + "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 + } + + if legacy_poststart_container_command + data.delete(reconcile_constants_module::RUN_INTERNAL_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym) + data.delete(reconcile_constants_module::RUN_NON_BLOCKING_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym) + data[reconcile_constants_module::LEGACY_RUN_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym] = + legacy_poststart_commands_script + end + { apiVersion: "v1", kind: "ConfigMap", @@ -1184,13 +1257,7 @@ def scripts_configmap(workspace_name:, workspace_namespace:, labels:, annotation name: "#{workspace_name}-scripts-configmap", namespace: workspace_namespace }, - data: { - "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::INTERNAL_POSTSTART_COMMAND_START_SSHD_SCRIPT - } + data: data } end -- GitLab From cc7a7b06d422d028cf0d408ff8262d974db2e050 Mon Sep 17 00:00:00 2001 From: Vishal Tak Date: Wed, 4 Jun 2025 14:08:52 +0530 Subject: [PATCH 2/3] Add restrictions to enforce command label prefix in devfile --- .../restrictions_enforcer.rb | 20 ++++++++++++++++--- ...refix-command-apply-label-devfile.yaml.erb | 15 ++++++++++++++ ...prefix-command-exec-label-devfile.yaml.erb | 17 ++++++++++++++++ .../restrictions_enforcer_spec.rb | 2 ++ locale/gitlab.pot | 3 +++ 5 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 ee/spec/fixtures/remote_development/example.invalid-restricted-prefix-command-apply-label-devfile.yaml.erb create mode 100644 ee/spec/fixtures/remote_development/example.invalid-restricted-prefix-command-exec-label-devfile.yaml.erb diff --git a/ee/lib/remote_development/devfile_operations/restrictions_enforcer.rb b/ee/lib/remote_development/devfile_operations/restrictions_enforcer.rb index fc21a31e186ba2..37773594239543 100644 --- a/ee/lib/remote_development/devfile_operations/restrictions_enforcer.rb +++ b/ee/lib/remote_development/devfile_operations/restrictions_enforcer.rb @@ -262,12 +262,26 @@ def self.validate_commands(context) next unless command_type component_name = command_type.fetch(:component) - next unless component_name.downcase.start_with?(RESTRICTED_PREFIX) + + if component_name.downcase.start_with?(RESTRICTED_PREFIX) + return err( + format( + _("Component name '%{component}' for command id '%{command}' must not start with '%{prefix}'"), + component: component_name, + command: command_id, + prefix: RESTRICTED_PREFIX + ), + context + ) + end + + command_label = command_type.fetch(:label, "") + next unless command_label.downcase.start_with?(RESTRICTED_PREFIX) return err( format( - _("Component name '%{component}' for command id '%{command}' must not start with '%{prefix}'"), - component: component_name, + _("Label '%{command_label}' for command id '%{command}' must not start with '%{prefix}'"), + command_label: command_label, command: command_id, prefix: RESTRICTED_PREFIX ), diff --git a/ee/spec/fixtures/remote_development/example.invalid-restricted-prefix-command-apply-label-devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.invalid-restricted-prefix-command-apply-label-devfile.yaml.erb new file mode 100644 index 00000000000000..ec80d211c10789 --- /dev/null +++ b/ee/spec/fixtures/remote_development/example.invalid-restricted-prefix-command-apply-label-devfile.yaml.erb @@ -0,0 +1,15 @@ +--- +schemaVersion: 2.2.0 +components: + - name: example + attributes: + gl/inject-editor: true + container: + image: quay.io/mloriedo/universal-developer-image:ubi8-dw-demo +commands: + - id: example + apply: + component: example + label: gl-example +events: {} +variables: {} diff --git a/ee/spec/fixtures/remote_development/example.invalid-restricted-prefix-command-exec-label-devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.invalid-restricted-prefix-command-exec-label-devfile.yaml.erb new file mode 100644 index 00000000000000..599d5ed62eb43c --- /dev/null +++ b/ee/spec/fixtures/remote_development/example.invalid-restricted-prefix-command-exec-label-devfile.yaml.erb @@ -0,0 +1,17 @@ +--- +schemaVersion: 2.2.0 +components: + - name: example + attributes: + gl/inject-editor: true + container: + image: quay.io/mloriedo/universal-developer-image:ubi8-dw-demo +commands: + - id: example + exec: + component: example + commandLine: mvn clean + workingDir: /projects/spring-petclinic + label: gl-example +events: {} +variables: {} 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 aa449daae6f331..20bc9be47c8849 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 @@ -82,6 +82,8 @@ "example.invalid-restricted-prefix-component-name-devfile.yaml.erb" | "Component name 'gl-example' must not start with 'gl-'" "example.invalid-restricted-prefix-event-type-prestart-name-devfile.yaml.erb" | "Event 'gl-example' of type 'preStart' must not start with 'gl-'" "example.invalid-restricted-prefix-variable-name-devfile.yaml.erb" | "Variable name 'gl-example' must not start with 'gl-'" + "example.invalid-restricted-prefix-command-apply-label-devfile.yaml.erb" | "Label 'gl-example' for command id 'example' must not start with 'gl-'" + "example.invalid-restricted-prefix-command-exec-label-devfile.yaml.erb" | "Label 'gl-example' for command id 'example' must not start with 'gl-'" "example.invalid-restricted-prefix-variable-name-with-underscore-devfile.yaml.erb" | "Variable name 'gl_example' must not start with 'gl_'" "example.invalid-root-attributes-pod-overrides-devfile.yaml.erb" | "Attribute 'pod-overrides' is not yet supported" "example.invalid-unsupported-component-container-dedicated-pod-devfile.yaml.erb" | "Property 'dedicatedPod' of component 'example' is not yet supported" diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 4c99d733850ec0..a7e347d09f4706 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -35791,6 +35791,9 @@ msgstr[1] "" msgid "Label %{labelName} was not found" msgstr "" +msgid "Label '%{command_label}' for command id '%{command}' must not start with '%{prefix}'" +msgstr "" + msgid "Label actions dropdown" msgstr "" -- GitLab From b42ba5600f408f595e62afe94cf1cace673a946e Mon Sep 17 00:00:00 2001 From: Daniyal Arshad Date: Wed, 4 Jun 2025 13:34:48 -0400 Subject: [PATCH 3/3] Address review suggestions --- .../kubernetes_poststart_hook_command.sh | 19 ++++++++++++------- .../kubernetes_poststart_hook_inserter.rb | 2 +- .../output/scripts_configmap_appender.rb | 10 +++++----- .../workspace_operations_constants.rb | 2 +- .../example.desired_config.json | 2 +- ...red_config_generator_golden_master_spec.rb | 8 ++++---- 6 files changed, 24 insertions(+), 19 deletions(-) diff --git a/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_command.sh b/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_command.sh index a9364680289926..792e1cad5d3a53 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_command.sh +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_command.sh @@ -3,14 +3,19 @@ mkdir -p "${GL_WORKSPACE_LOGS_DIR}" ln -sf "${GL_WORKSPACE_LOGS_DIR}" /tmp -# shellcheck disable=SC2129 # Better readability -echo "$(date -Iseconds): ----------------------------------------" >> "${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" -echo "$(date -Iseconds): Running poststart commands for workspace..." >> "${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" +{ + echo "$(date -Iseconds): ----------------------------------------" + echo "$(date -Iseconds): Running poststart commands for workspace..." + + echo "$(date -Iseconds): ----------------------------------------" + echo "$(date -Iseconds): Running internal blocking poststart commands script..." +} >> "${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" -echo "$(date -Iseconds): ----------------------------------------" >> "${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" -echo "$(date -Iseconds): Running internal blocking poststart commands script..." >> "${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" "%s" 1>>"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" 2>>"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log" -echo "$(date -Iseconds): ----------------------------------------" >> "${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" -echo "$(date -Iseconds): Running non-blocking poststart commands script..." >> "${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" +{ + echo "$(date -Iseconds): ----------------------------------------" + echo "$(date -Iseconds): Running non-blocking poststart commands script..." +} >> "${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" + "%s" 1>>"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log" 2>>"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log" & diff --git a/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_inserter.rb b/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_inserter.rb index 5b2bbdd0291888..134a75aeb574ee 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_inserter.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_inserter.rb @@ -16,7 +16,7 @@ class KubernetesPoststartHookInserter # @param [Hash] devfile_events # @return [void] def self.insert(containers:, devfile_commands:, devfile_events:) - internal_blocking_command_label_present = devfile_commands.find do |command| + internal_blocking_command_label_present = devfile_commands.any? do |command| command.dig(:exec, :label) == INTERNAL_BLOCKING_COMMAND_LABEL end diff --git a/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_configmap_appender.rb b/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_configmap_appender.rb index 75671bb4df3957..95c0f49594e5d8 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_configmap_appender.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_configmap_appender.rb @@ -91,9 +91,9 @@ def self.add_run_poststart_commands_script_to_configmap_data( unless internal_blocking_command_label_present 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)} - SH + #!/bin/sh + #{get_poststart_command_script_content(poststart_command_ids: poststart_command_ids)} + SH return end @@ -130,10 +130,10 @@ def self.get_poststart_command_script_content(poststart_command_ids:) # container from exiting. Then users can view logs to debug failures. # See https://github.com/eclipse-che/che/issues/23404#issuecomment-2787779571 # for more context. - <<~CMD + <<~SH echo "$(date -Iseconds): Running #{WORKSPACE_SCRIPTS_VOLUME_PATH}/#{poststart_command_id}..." #{WORKSPACE_SCRIPTS_VOLUME_PATH}/#{poststart_command_id} || true - CMD + SH end.join end diff --git a/ee/lib/remote_development/workspace_operations/workspace_operations_constants.rb b/ee/lib/remote_development/workspace_operations/workspace_operations_constants.rb index 3db8d85e1dd868..5232532367c4b2 100644 --- a/ee/lib/remote_development/workspace_operations/workspace_operations_constants.rb +++ b/ee/lib/remote_development/workspace_operations/workspace_operations_constants.rb @@ -17,8 +17,8 @@ module WorkspaceOperations # See documentation at ../README.md#constant-declarations for more information. module WorkspaceOperationsConstants # Please keep alphabetized - INTERNAL_BLOCKING_COMMAND_LABEL = "gl-internal-blocking" INTERNAL_COMMAND_LABEL = "gl-internal" + INTERNAL_BLOCKING_COMMAND_LABEL = "#{INTERNAL_COMMAND_LABEL}-blocking".freeze VARIABLES_VOLUME_DEFAULT_MODE = 0o774 VARIABLES_VOLUME_NAME = "gl-workspace-variables" VARIABLES_VOLUME_PATH = "/.workspace-data/variables/file" diff --git a/ee/spec/fixtures/remote_development/example.desired_config.json b/ee/spec/fixtures/remote_development/example.desired_config.json index b70c00f250ddb0..05273df55d3d8c 100644 --- a/ee/spec/fixtures/remote_development/example.desired_config.json +++ b/ee/spec/fixtures/remote_development/example.desired_config.json @@ -149,7 +149,7 @@ "command": [ "/bin/sh", "-c", - "#!/bin/sh\n\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running poststart commands for workspace...\"\n\nmkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running internal blocking poststart commands script...\"\n\"/workspace-scripts/gl-run-internal-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\"\n\necho \"$(date -Iseconds): ----------------------------------------\"\necho \"$(date -Iseconds): Running non-blocking poststart commands script...\"\n\"/workspace-scripts/gl-run-non-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" + "#!/bin/sh\n\nmkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\n{\n echo \"$(date -Iseconds): ----------------------------------------\"\n echo \"$(date -Iseconds): Running poststart commands for workspace...\"\n\n echo \"$(date -Iseconds): ----------------------------------------\"\n echo \"$(date -Iseconds): Running internal blocking poststart commands script...\"\n} >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\n\"/workspace-scripts/gl-run-internal-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\"\n\n{\n echo \"$(date -Iseconds): ----------------------------------------\"\n echo \"$(date -Iseconds): Running non-blocking poststart commands script...\"\n} >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\n\"/workspace-scripts/gl-run-non-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" ] } } 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 b013ccaca40deb..e163a714fbacb8 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 @@ -626,7 +626,7 @@ def golden_master_desired_config_with_include_all_resources_true command: [ "/bin/sh", "-c", - "#!/bin/sh\n\nmkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\n# shellcheck disable=SC2129 # Better readability\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running poststart commands for workspace...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running internal blocking poststart commands script...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\"/workspace-scripts/gl-run-internal-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\"\n\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running non-blocking poststart commands script...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\"/workspace-scripts/gl-run-non-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" + "#!/bin/sh\n\nmkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\n{\n echo \"$(date -Iseconds): ----------------------------------------\"\n echo \"$(date -Iseconds): Running poststart commands for workspace...\"\n\n echo \"$(date -Iseconds): ----------------------------------------\"\n echo \"$(date -Iseconds): Running internal blocking poststart commands script...\"\n} >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\n\"/workspace-scripts/gl-run-internal-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\"\n\n{\n echo \"$(date -Iseconds): ----------------------------------------\"\n echo \"$(date -Iseconds): Running non-blocking poststart commands script...\"\n} >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\n\"/workspace-scripts/gl-run-non-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" ] } } @@ -1206,7 +1206,7 @@ def golden_master_desired_config_with_include_all_resources_false command: [ "/bin/sh", "-c", - "#!/bin/sh\n\nmkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\n# shellcheck disable=SC2129 # Better readability\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running poststart commands for workspace...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running internal blocking poststart commands script...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\"/workspace-scripts/gl-run-internal-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\"\n\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running non-blocking poststart commands script...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\"/workspace-scripts/gl-run-non-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" + "#!/bin/sh\n\nmkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\n{\n echo \"$(date -Iseconds): ----------------------------------------\"\n echo \"$(date -Iseconds): Running poststart commands for workspace...\"\n\n echo \"$(date -Iseconds): ----------------------------------------\"\n echo \"$(date -Iseconds): Running internal blocking poststart commands script...\"\n} >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\n\"/workspace-scripts/gl-run-internal-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\"\n\n{\n echo \"$(date -Iseconds): ----------------------------------------\"\n echo \"$(date -Iseconds): Running non-blocking poststart commands script...\"\n} >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\n\"/workspace-scripts/gl-run-non-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" ] } } @@ -2841,7 +2841,7 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources command: [ "/bin/sh", "-c", - "#!/bin/sh\n\nmkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\n# shellcheck disable=SC2129 # Better readability\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running poststart commands for workspace...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running internal blocking poststart commands script...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\"/workspace-scripts/gl-run-internal-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\"\n\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running non-blocking poststart commands script...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\"/workspace-scripts/gl-run-non-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" + "#!/bin/sh\n\nmkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\n{\n echo \"$(date -Iseconds): ----------------------------------------\"\n echo \"$(date -Iseconds): Running poststart commands for workspace...\"\n\n echo \"$(date -Iseconds): ----------------------------------------\"\n echo \"$(date -Iseconds): Running internal blocking poststart commands script...\"\n} >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\n\"/workspace-scripts/gl-run-internal-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\"\n\n{\n echo \"$(date -Iseconds): ----------------------------------------\"\n echo \"$(date -Iseconds): Running non-blocking poststart commands script...\"\n} >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\n\"/workspace-scripts/gl-run-non-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" ] } } @@ -3409,7 +3409,7 @@ def golden_master_desired_config_for_shared_namespace_with_include_all_resources command: [ "/bin/sh", "-c", - "#!/bin/sh\n\nmkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\n# shellcheck disable=SC2129 # Better readability\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running poststart commands for workspace...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running internal blocking poststart commands script...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\"/workspace-scripts/gl-run-internal-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\"\n\necho \"$(date -Iseconds): ----------------------------------------\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\necho \"$(date -Iseconds): Running non-blocking poststart commands script...\" >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\"/workspace-scripts/gl-run-non-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" + "#!/bin/sh\n\nmkdir -p \"${GL_WORKSPACE_LOGS_DIR}\"\nln -sf \"${GL_WORKSPACE_LOGS_DIR}\" /tmp\n\n{\n echo \"$(date -Iseconds): ----------------------------------------\"\n echo \"$(date -Iseconds): Running poststart commands for workspace...\"\n\n echo \"$(date -Iseconds): ----------------------------------------\"\n echo \"$(date -Iseconds): Running internal blocking poststart commands script...\"\n} >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\n\"/workspace-scripts/gl-run-internal-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\"\n\n{\n echo \"$(date -Iseconds): ----------------------------------------\"\n echo \"$(date -Iseconds): Running non-blocking poststart commands script...\"\n} >> \"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\"\n\n\"/workspace-scripts/gl-run-non-blocking-poststart-commands.sh\" 1>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stdout.log\" 2>>\"${GL_WORKSPACE_LOGS_DIR}/poststart-stderr.log\" &\n" ] } } -- GitLab