From 23008283a28cdfd6738efbadcaab05fc62e59c30 Mon Sep 17 00:00:00 2001 From: Chad Woolley Date: Fri, 13 Dec 2024 21:52:52 +0530 Subject: [PATCH 1/6] Extract devfile event processing to DevfilePoststartEventsProcessor - See https://gitlab.com/gitlab-org/gitlab/-/issues/520867 - See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/182354 --- ee/lib/remote_development/files.rb | 12 +- .../create/main_component_updater.rb | 59 +- .../main_component_updater_container_args.sh | 9 +- .../main_component_updater_init_tools.sh | 5 + ...pdater_sleep_until_workspace_is_running.sh | 11 + .../main_component_updater_start_sshd.sh | 11 + ...loner_component_inserter_container_args.sh | 37 +- .../create/workspace_creator.rb | 2 +- .../create/workspace_variables_builder.rb | 10 + ...orkspace_variables_git_credential_store.sh | 2 +- .../output/desired_config_generator.rb | 65 ++ .../kubernetes_poststart_hook_command.sh | 3 + .../kubernetes_poststart_hook_inserter.rb | 59 ++ .../output/scripts_configmap_appender.rb | 108 +++ .../output/scripts_volume_inserter.rb | 45 ++ .../reconcile/reconcile_constants.rb | 4 + .../workspace_operations_constants.rb | 1 + ...le.main-container-updated-devfile.yaml.erb | 20 +- ...ated-marketplace-disabled-devfile.yaml.erb | 20 +- .../example.processed-devfile.yaml.erb | 28 +- ...e.project-cloner-inserted-devfile.yaml.erb | 28 +- .../create/main_component_updater_spec.rb | 2 +- .../workspace_variables_builder_spec.rb | 6 + .../workspace_variables_creator_spec.rb | 6 +- ...red_config_generator_golden_master_spec.rb | 639 +++++++++++++++++- .../output/desired_config_generator_spec.rb | 20 +- .../reconcile/output/devfile_parser_spec.rb | 1 + ...kubernetes_poststart_hook_inserter_spec.rb | 85 +++ .../output/scripts_configmap_appender_spec.rb | 70 ++ .../output/scripts_volume_inserter_spec.rb | 82 +++ .../remote_development/integration_spec.rb | 1 + .../remote_development_shared_contexts.rb | 183 ++++- 32 files changed, 1546 insertions(+), 88 deletions(-) create mode 100644 ee/lib/remote_development/workspace_operations/create/main_component_updater_init_tools.sh create mode 100644 ee/lib/remote_development/workspace_operations/create/main_component_updater_sleep_until_workspace_is_running.sh create mode 100644 ee/lib/remote_development/workspace_operations/create/main_component_updater_start_sshd.sh create mode 100644 ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_command.sh create mode 100644 ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_inserter.rb create mode 100644 ee/lib/remote_development/workspace_operations/reconcile/output/scripts_configmap_appender.rb create mode 100644 ee/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter.rb create mode 100644 ee/spec/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_inserter_spec.rb create mode 100644 ee/spec/lib/remote_development/workspace_operations/reconcile/output/scripts_configmap_appender_spec.rb create mode 100644 ee/spec/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter_spec.rb diff --git a/ee/lib/remote_development/files.rb b/ee/lib/remote_development/files.rb index ba3a32d5d28204..f535d6bcbdfd0c 100644 --- a/ee/lib/remote_development/files.rb +++ b/ee/lib/remote_development/files.rb @@ -30,10 +30,18 @@ def self.read_file(path) DEFAULT_DEVFILE_YAML = read_file("settings/default_devfile.yaml") GIT_CREDENTIAL_STORE_SCRIPT = read_file("workspace_operations/create/workspace_variables_git_credential_store.sh") - PROJECTS_CLONER_COMPONENT_INSERTER_CONTAINER_ARGS = - read_file("workspace_operations/create/project_cloner_component_inserter_container_args.sh") + KUBERNETES_POSTSTART_HOOK_COMMAND = + read_file("workspace_operations/reconcile/output/kubernetes_poststart_hook_command.sh") MAIN_COMPONENT_UPDATER_CONTAINER_ARGS = read_file("workspace_operations/create/main_component_updater_container_args.sh") + MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT = + read_file("workspace_operations/create/main_component_updater_init_tools.sh") + MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT = + read_file("workspace_operations/create/main_component_updater_sleep_until_workspace_is_running.sh") + MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT = + read_file("workspace_operations/create/main_component_updater_start_sshd.sh") + PROJECTS_CLONER_COMPONENT_INSERTER_CONTAINER_ARGS = + read_file("workspace_operations/create/project_cloner_component_inserter_container_args.sh") private_class_method :read_file end diff --git a/ee/lib/remote_development/workspace_operations/create/main_component_updater.rb b/ee/lib/remote_development/workspace_operations/create/main_component_updater.rb index 282bc511802a87..887d7643d55024 100644 --- a/ee/lib/remote_development/workspace_operations/create/main_component_updater.rb +++ b/ee/lib/remote_development/workspace_operations/create/main_component_updater.rb @@ -30,6 +30,14 @@ def self.update(context) main_component_container = main_component.fetch(:container) + # TODO: When user-defined postStart commands are supported, add validation in previous devfile validation + # steps of the ".../workspace_operations/create" ROP chain. + # See: https://gitlab.com/gitlab-org/gitlab/-/issues/505988 + add_poststart_commands( + processed_devfile: processed_devfile, + main_component: main_component + ) + update_env_vars( main_component_container: main_component_container, tools_dir: tools_dir, @@ -110,6 +118,55 @@ def self.update_endpoints(main_component_container:, editor_port:, ssh_port:) nil end + # @param [Hash] processed_devfile + # @param [Hash] main_component + # @return [void] + def self.add_poststart_commands(processed_devfile:, main_component:) + processed_devfile => { + commands: Array => commands, + events: { + postStart: Array => poststart_events + } + } + + main_component => { name: String => main_component_name } + + # Add the start_sshd event + start_sshd_command_id = "gl-start-sshd-command" + commands << { + id: start_sshd_command_id, + exec: { + commandLine: MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, + component: main_component_name + } + } + poststart_events << start_sshd_command_id + + # Add the init_tools event + sleep_until_container_is_running_command_id = "gl-init-tools-command" + commands << { + id: sleep_until_container_is_running_command_id, + exec: { + commandLine: MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT, + component: main_component_name + } + } + poststart_events << sleep_until_container_is_running_command_id + + # Add the sleep_until_container_is_running event + sleep_until_container_is_running_command_id = "gl-sleep-until-container-is-running-command" + commands << { + id: sleep_until_container_is_running_command_id, + exec: { + commandLine: MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, + component: main_component_name + } + } + poststart_events << sleep_until_container_is_running_command_id + + nil + end + # @param [Hash] main_component_container # @return [void] def self.override_command_and_args(main_component_container:) @@ -123,7 +180,7 @@ def self.override_command_and_args(main_component_container:) nil end - private_class_method :update_env_vars, :update_endpoints, :override_command_and_args + private_class_method :update_env_vars, :update_endpoints, :add_poststart_commands, :override_command_and_args end end end diff --git a/ee/lib/remote_development/workspace_operations/create/main_component_updater_container_args.sh b/ee/lib/remote_development/workspace_operations/create/main_component_updater_container_args.sh index 0b00f476a16a97..cc66f385651346 100644 --- a/ee/lib/remote_development/workspace_operations/create/main_component_updater_container_args.sh +++ b/ee/lib/remote_development/workspace_operations/create/main_component_updater_container_args.sh @@ -1,8 +1 @@ -sshd_path=$(which sshd) -if [ -x "$sshd_path" ]; then - echo "Starting sshd on port ${GL_SSH_PORT}" - $sshd_path -D -p "${GL_SSH_PORT}" & -else - echo "'sshd' not found in path. Not starting SSH server." -fi -"${GL_TOOLS_DIR}/init_tools.sh" +tail -f /dev/null diff --git a/ee/lib/remote_development/workspace_operations/create/main_component_updater_init_tools.sh b/ee/lib/remote_development/workspace_operations/create/main_component_updater_init_tools.sh new file mode 100644 index 00000000000000..acf8892ead0d21 --- /dev/null +++ b/ee/lib/remote_development/workspace_operations/create/main_component_updater_init_tools.sh @@ -0,0 +1,5 @@ +#!/bin/sh +echo "$(date -Iseconds): ----------------------------------------" +echo "$(date -Iseconds): Running ${GL_TOOLS_DIR}/init_tools.sh with output written to ${GL_WORKSPACE_LOGS_DIR}/init-tools.log..." +"${GL_TOOLS_DIR}/init_tools.sh" >> "${GL_WORKSPACE_LOGS_DIR}/init-tools.log" 2>&1 & +echo "$(date -Iseconds): Finished running ${GL_TOOLS_DIR}/init_tools.sh." diff --git a/ee/lib/remote_development/workspace_operations/create/main_component_updater_sleep_until_workspace_is_running.sh b/ee/lib/remote_development/workspace_operations/create/main_component_updater_sleep_until_workspace_is_running.sh new file mode 100644 index 00000000000000..4f9cd1c4b16a2d --- /dev/null +++ b/ee/lib/remote_development/workspace_operations/create/main_component_updater_sleep_until_workspace_is_running.sh @@ -0,0 +1,11 @@ +#!/bin/sh +echo "$(date -Iseconds): ----------------------------------------" +echo "$(date -Iseconds): Sleeping until workspace is running..." +time_to_sleep=5 +status_file="/.workspace-data/variables/file/gl_workspace_reconciled_actual_state.txt" +while [ "$(cat ${status_file})" != "Running" ]; do + echo "$(date -Iseconds): Workspace state is '$(cat ${status_file})' from status file '${status_file}'. Blocking remaining postStart events execution for ${time_to_sleep} seconds until state is 'Running'..." + sleep ${time_to_sleep} +done +echo "$(date -Iseconds): Workspace state is now 'Running', continuing postStart hook execution." +echo "$(date -Iseconds): Finished sleeping until workspace is running." diff --git a/ee/lib/remote_development/workspace_operations/create/main_component_updater_start_sshd.sh b/ee/lib/remote_development/workspace_operations/create/main_component_updater_start_sshd.sh new file mode 100644 index 00000000000000..cc4adb32df67df --- /dev/null +++ b/ee/lib/remote_development/workspace_operations/create/main_component_updater_start_sshd.sh @@ -0,0 +1,11 @@ +#!/bin/sh +echo "$(date -Iseconds): ----------------------------------------" +echo "$(date -Iseconds): Starting sshd if it is found..." +sshd_path=$(which sshd) +if [ -x "${sshd_path}" ]; then + echo "$(date -Iseconds): Starting ${sshd_path} on port ${GL_SSH_PORT} with output written to ${GL_WORKSPACE_LOGS_DIR}/start-sshd.log" + "${sshd_path}" -D -p "${GL_SSH_PORT}" >> "${GL_WORKSPACE_LOGS_DIR}/start-sshd.log" 2>&1 & +else + echo "$(date -Iseconds): 'sshd' not found in path. Not starting SSH server." >&2 +fi +echo "$(date -Iseconds): Finished starting sshd if it is found." diff --git a/ee/lib/remote_development/workspace_operations/create/project_cloner_component_inserter_container_args.sh b/ee/lib/remote_development/workspace_operations/create/project_cloner_component_inserter_container_args.sh index f7251ea89121c4..8f11fe70e9057e 100644 --- a/ee/lib/remote_development/workspace_operations/create/project_cloner_component_inserter_container_args.sh +++ b/ee/lib/remote_development/workspace_operations/create/project_cloner_component_inserter_container_args.sh @@ -1,23 +1,30 @@ -if [ -f "%s" ]; +echo "$(date -Iseconds): ----------------------------------------" +echo "$(date -Iseconds): Cloning project if necessary..." + +if [ -f "%s" ] then - echo "Project cloning was already successful"; - exit 0; + echo "$(date -Iseconds): Project cloning was already successful" + exit 0 fi -if [ -d "%s" ]; + +if [ -d "%s" ] then - echo "Removing unsuccessfully cloned project directory"; - rm -rf "%s"; + echo "$(date -Iseconds): Removing unsuccessfully cloned project directory" + rm -rf "%s" fi -echo "Cloning project"; -git clone --branch "%s" "%s" "%s"; + +echo "$(date -Iseconds): Cloning project" +git clone --branch "%s" "%s" "%s" exit_code=$? -if [ "${exit_code}" -eq 0 ]; + +if [ "${exit_code}" -eq 0 ] then - echo "Project cloning successful"; - touch "%s"; - echo "Updated file to indicate successful project cloning"; - exit 0; + echo "$(date -Iseconds): Project cloning successful" + touch "%s" + echo "$(date -Iseconds): Updated file to indicate successful project cloning" else - echo "Project cloning failed with exit code: ${exit_code}"; - exit "${exit_code}"; + echo "$(date -Iseconds): Project cloning failed with exit code: ${exit_code}" >&2 fi + +echo "$(date -Iseconds): Finished cloning project if necessary." +exit "${exit_code}" diff --git a/ee/lib/remote_development/workspace_operations/create/workspace_creator.rb b/ee/lib/remote_development/workspace_operations/create/workspace_creator.rb index 17beea2a8de5e0..0e61b166a9ee40 100644 --- a/ee/lib/remote_development/workspace_operations/create/workspace_creator.rb +++ b/ee/lib/remote_development/workspace_operations/create/workspace_creator.rb @@ -32,7 +32,7 @@ def self.create(context) user: User => user, project: Project => project, } - project_dir = "#{workspace_data_volume_path}/#{project.path}" + project_dir = "#{WORKSPACE_DATA_VOLUME_PATH}/#{project.path}" workspace = RemoteDevelopment::Workspace.new workspace.name = workspace_name diff --git a/ee/lib/remote_development/workspace_operations/create/workspace_variables_builder.rb b/ee/lib/remote_development/workspace_operations/create/workspace_variables_builder.rb index cfc51fb53e915a..cf8b54ea5dd7bf 100644 --- a/ee/lib/remote_development/workspace_operations/create/workspace_variables_builder.rb +++ b/ee/lib/remote_development/workspace_operations/create/workspace_variables_builder.rb @@ -30,6 +30,15 @@ def self.build( internal_variables = [ + #------------------------------------------------------------------- + # The directory to which logs related to the creation and management of the workspace are written. + # For example, logs from the poststart events. + { + key: "GL_WORKSPACE_LOGS_DIR", + value: WORKSPACE_LOGS_DIR, + variable_type: ENVIRONMENT_TYPE, + workspace_id: workspace_id + }, #------------------------------------------------------------------- # The user's workspace-specific personal access token which is injected into the workspace, and used for # authentication. For example, in the credential.helper script below. @@ -50,6 +59,7 @@ def self.build( #------------------------------------------------------------------- # Standard git ENV vars which configure git on the workspace. See https://git-scm.com/docs/git-config { + # TODO: We should be able to move this entry to the scripts volume. # This script is set as the value of `credential.helper` below in `GIT_CONFIG_VALUE_0` key: GIT_CREDENTIAL_STORE_SCRIPT_FILE_NAME, value: GIT_CREDENTIAL_STORE_SCRIPT, diff --git a/ee/lib/remote_development/workspace_operations/create/workspace_variables_git_credential_store.sh b/ee/lib/remote_development/workspace_operations/create/workspace_variables_git_credential_store.sh index 704a9be35d0942..517eeb6cee4ca1 100644 --- a/ee/lib/remote_development/workspace_operations/create/workspace_variables_git_credential_store.sh +++ b/ee/lib/remote_development/workspace_operations/create/workspace_variables_git_credential_store.sh @@ -7,7 +7,7 @@ fi if [ -z "${GL_TOKEN_FILE_PATH}" ]; then - echo "We could not find the GL_TOKEN_FILE_PATH variable" + echo "$(date -Iseconds): We could not find the GL_TOKEN_FILE_PATH variable" >&2 exit 1 fi password=$(cat "${GL_TOKEN_FILE_PATH}") diff --git a/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator.rb b/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator.rb index b97564e39c6b06..6fca809460e629 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator.rb @@ -108,6 +108,14 @@ def self.generate_desired_config(workspace:, include_all_resources:, logger:) annotations: workspace_inventory_annotations ) + append_scripts_resources( + desired_config: desired_config, + processed_devfile_yaml: processed_devfile_yaml, + namespace: workspace.namespace, + labels: labels, + annotations: workspace_inventory_annotations + ) + return desired_config unless include_all_resources append_inventory_config_map( @@ -337,6 +345,63 @@ def self.append_network_policy( nil end + # @param [Array] desired_config + # @param [String] processed_devfile_yaml + # @param [String] namespace + # @param [Hash] labels + # @param [Hash] annotations + # @return [void] + def self.append_scripts_resources(desired_config:, processed_devfile_yaml:, namespace:, labels:, annotations:) + desired_config => [ + *_, + { + kind: "Deployment", + spec: { + template: { + spec: { + containers: Array => containers, + volumes: Array => volumes + } + } + } + }, + *_ + ] + + processed_devfile = YAML.safe_load(processed_devfile_yaml).deep_symbolize_keys.to_h + + devfile_commands = processed_devfile.fetch(:commands) + devfile_events = processed_devfile.fetch(:events) + + # NOTE: This guard clause ensures we still support older running workspaces which were started before we + # added support for devfile postStart events. In that case, we don't want to add any resources + # related to the postStart script handling, because that would cause those existing workspaces + # to restart because the deployment would be updated. + return unless devfile_events[:postStart] + + ScriptsConfigmapAppender.append( + desired_config: desired_config, + namespace: namespace, + labels: labels, + annotations: annotations, + devfile_commands: devfile_commands, + devfile_events: devfile_events + ) + + ScriptsVolumeInserter.insert( + containers: containers, + volumes: volumes + ) + + KubernetesPoststartHookInserter.insert( + containers: containers, + devfile_commands: devfile_commands, + devfile_events: devfile_events + ) + + nil + end + # @param [Array] desired_config # @param [String] name # @param [String] namespace 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 new file mode 100644 index 00000000000000..0bc34317453022 --- /dev/null +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_command.sh @@ -0,0 +1,3 @@ +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_inserter.rb b/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_inserter.rb new file mode 100644 index 00000000000000..5f421b26e77a98 --- /dev/null +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_inserter.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +module RemoteDevelopment + module WorkspaceOperations + module Reconcile + module Output + # NOTE: This class has "Kubernetes" prepended to "Poststart" in the name to make it explicit that it + # deals with Kubernetes postStart hooks in the Kuberneted Deployment resource, and that + # it is NOT dealing with the postStart events which are found in devfiles. + class KubernetesPoststartHookInserter + include Files + include ReconcileConstants + + # @param [Array] containers + # @param [Array] devfile_commands + # @param [Hash] devfile_events + # @return [void] + def self.insert(containers:, devfile_commands:, devfile_events:) + devfile_events => { postStart: Array => poststart_command_ids } + + containers_with_devfile_poststart_commands = + poststart_command_ids.each_with_object([]) do |poststart_command_id, accumulator| + command = devfile_commands.find { |command| command.fetch(:id) == poststart_command_id } + command => { + exec: { + component: String => container_name + } + } + accumulator << container_name + end.uniq + + containers.each do |container| + container_name = container.fetch(:name) + + 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}" + ) + + container[:lifecycle] = { + postStart: { + exec: { + command: ["/bin/sh", "-c", kubernetes_poststart_hook_script] + } + } + } + end + + nil + end + end + end + end + end +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 new file mode 100644 index 00000000000000..9e33bd83de1ea4 --- /dev/null +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_configmap_appender.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true + +module RemoteDevelopment + module WorkspaceOperations + module Reconcile + module Output + class ScriptsConfigmapAppender + include ReconcileConstants + + # @param [Array] desired_config + # @param [String] namespace + # @param [Hash] labels + # @param [Hash] annotations + # @param [Array] devfile_commands + # @param [Hash] devfile_events + # @return [void] + def self.append(desired_config:, namespace:, labels:, annotations:, devfile_commands:, devfile_events:) + configmap_data = {} + + configmap = + { + kind: "ConfigMap", + apiVersion: "v1", + metadata: { + name: WORKSPACE_SCRIPTS_CONFIGMAP_NAME, + namespace: namespace, + labels: labels, + annotations: annotations + }, + data: configmap_data + } + + add_devfile_command_scripts_to_configmap_data( + configmap_data: configmap_data, + devfile_commands: devfile_commands, + devfile_events: devfile_events + ) + + add_run_poststart_commands_script_to_configmap_data( + configmap_data: configmap_data, + devfile_events: devfile_events + ) + + # noinspection RubyMismatchedArgumentType - RubyMine is misinterpreting types for Hash values + configmap[:data] = Gitlab::Utils.deep_sort_hashes(configmap_data).to_h + + desired_config.append(configmap) + + nil + end + + # @param [Hash] configmap_data + # @param [Array] devfile_commands + # @param [Hash] devfile_events + # @return [void] + def self.add_devfile_command_scripts_to_configmap_data(configmap_data:, devfile_commands:, devfile_events:) + devfile_events => { postStart: Array => poststart_command_ids } + + poststart_command_ids.each do |poststart_command_id| + command = devfile_commands.find { |command| command.fetch(:id) == poststart_command_id } + command => { + exec: { + commandLine: String => command_line + } + } + + configmap_data[poststart_command_id.to_sym] = command_line + end + + nil + end + + # @param [Hash] configmap_data + # @param [Array] devfile_commands + # @param [Hash] devfile_events + # @return [void] + def self.add_run_poststart_commands_script_to_configmap_data(configmap_data:, 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] = + <<~SH.chomp + #!/bin/sh + #{script_command_lines} + SH + + nil + end + + private_class_method :add_devfile_command_scripts_to_configmap_data, + :add_run_poststart_commands_script_to_configmap_data + end + end + end + end +end diff --git a/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter.rb b/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter.rb new file mode 100644 index 00000000000000..c64b898e7d78de --- /dev/null +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module RemoteDevelopment + module WorkspaceOperations + module Reconcile + module Output + class ScriptsVolumeInserter + include ReconcileConstants + + # @param [Array] containers + # @param [Array] volumes + # @return [void] + def self.insert(containers:, volumes:) + volume = + { + name: WORKSPACE_SCRIPTS_VOLUME_NAME, + projected: { + defaultMode: 0o774, + sources: [ + { + configMap: { + name: WORKSPACE_SCRIPTS_CONFIGMAP_NAME + } + } + ] + } + } + volume_mount = + { + name: WORKSPACE_SCRIPTS_VOLUME_NAME, + mountPath: WORKSPACE_SCRIPTS_VOLUME_PATH + } + + volumes << volume + containers.each do |container| + container.fetch(:volumeMounts) << volume_mount + end + + nil + end + end + end + 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 d6e2393b792bf0..f2a1430d8d9656 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/reconcile_constants.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/reconcile_constants.rb @@ -14,9 +14,13 @@ module ReconcileConstants # Please keep alphabetized RUN_AS_USER = 5001 + RUN_POSTSTART_COMMANDS_SCRIPT_NAME = "gl-run-poststart-commands.sh" WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME = "gl_workspace_reconciled_actual_state.txt" WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH = "#{VARIABLES_VOLUME_PATH}/#{WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}".freeze + WORKSPACE_SCRIPTS_CONFIGMAP_NAME = "scripts-configmap" + WORKSPACE_SCRIPTS_VOLUME_NAME = "gl-workspace-scripts" + WORKSPACE_SCRIPTS_VOLUME_PATH = "/workspace-scripts" end end 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 9795c7266d391e..cbde68f388fb1a 100644 --- a/ee/lib/remote_development/workspace_operations/workspace_operations_constants.rb +++ b/ee/lib/remote_development/workspace_operations/workspace_operations_constants.rb @@ -20,6 +20,7 @@ module WorkspaceOperationsConstants VARIABLES_VOLUME_NAME = "gl-workspace-variables" VARIABLES_VOLUME_PATH = "/.workspace-data/variables/file" WORKSPACE_DATA_VOLUME_PATH = "/projects" + WORKSPACE_LOGS_DIR = "#{WORKSPACE_DATA_VOLUME_PATH}/workspace-logs".freeze WORKSPACE_TOOLS_IMAGE = "registry.gitlab.com/gitlab-org/workspaces/gitlab-workspaces-tools:12.0.0" end end 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 d11ae389409b7b..1bb706ef9e638a 100644 --- a/ee/spec/fixtures/remote_development/example.main-container-updated-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.main-container-updated-devfile.yaml.erb @@ -58,8 +58,26 @@ commands: - id: gl-tools-injector-command apply: component: gl-tools-injector + - id: gl-start-sshd-command + exec: + commandLine: | + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, 8) %> + component: tooling-container + - id: gl-init-tools-command + exec: + commandLine: | + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT, 8) %> + component: tooling-container + - id: gl-sleep-until-container-is-running-command + exec: + commandLine: | + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, 8) %> + component: tooling-container events: preStart: - gl-tools-injector-command - postStart: [] + postStart: + - 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.main-container-updated-marketplace-disabled-devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.main-container-updated-marketplace-disabled-devfile.yaml.erb index d11ae389409b7b..1bb706ef9e638a 100644 --- a/ee/spec/fixtures/remote_development/example.main-container-updated-marketplace-disabled-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.main-container-updated-marketplace-disabled-devfile.yaml.erb @@ -58,8 +58,26 @@ commands: - id: gl-tools-injector-command apply: component: gl-tools-injector + - id: gl-start-sshd-command + exec: + commandLine: | + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, 8) %> + component: tooling-container + - id: gl-init-tools-command + exec: + commandLine: | + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT, 8) %> + component: tooling-container + - id: gl-sleep-until-container-is-running-command + exec: + commandLine: | + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, 8) %> + component: tooling-container events: preStart: - gl-tools-injector-command - postStart: [] + postStart: + - 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 5678b7927f07ee..1254c6359c3849 100644 --- a/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb @@ -82,16 +82,34 @@ components: - name: gl-workspace-data volume: size: 50Gi -events: - preStart: - - gl-tools-injector-command - - gl-project-cloner-command - postStart: [] commands: - id: gl-tools-injector-command apply: component: gl-tools-injector + - id: gl-start-sshd-command + exec: + commandLine: | + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, 8) %> + component: tooling-container + - id: gl-init-tools-command + exec: + commandLine: | + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT, 8) %> + component: tooling-container + - id: gl-sleep-until-container-is-running-command + exec: + commandLine: | + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, 8) %> + component: tooling-container - id: gl-project-cloner-command apply: component: gl-project-cloner +events: + preStart: + - gl-tools-injector-command + - gl-project-cloner-command + postStart: + - gl-start-sshd-command + - gl-init-tools-command + - gl-sleep-until-container-is-running-command variables: {} diff --git a/ee/spec/fixtures/remote_development/example.project-cloner-inserted-devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.project-cloner-inserted-devfile.yaml.erb index 2afdda81f39d5f..45e9fa12410adf 100644 --- a/ee/spec/fixtures/remote_development/example.project-cloner-inserted-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.project-cloner-inserted-devfile.yaml.erb @@ -67,16 +67,34 @@ components: memoryRequest: 500Mi cpuLimit: 500m cpuRequest: 100m -events: - preStart: - - gl-tools-injector-command - - gl-project-cloner-command - postStart: [] commands: - id: gl-tools-injector-command apply: component: gl-tools-injector + - id: gl-start-sshd-command + exec: + commandLine: | + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, 8) %> + component: tooling-container + - id: gl-init-tools-command + exec: + commandLine: | + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT, 8) %> + component: tooling-container + - id: gl-sleep-until-container-is-running-command + exec: + commandLine: | + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, 8) %> + component: tooling-container - id: gl-project-cloner-command apply: component: gl-project-cloner +events: + preStart: + - gl-tools-injector-command + - gl-project-cloner-command + postStart: + - gl-start-sshd-command + - gl-init-tools-command + - gl-sleep-until-container-is-running-command variables: {} diff --git a/ee/spec/lib/remote_development/workspace_operations/create/main_component_updater_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/main_component_updater_spec.rb index 8f57157318a45b..0c955d53f5dba2 100644 --- a/ee/spec/lib/remote_development/workspace_operations/create/main_component_updater_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/create/main_component_updater_spec.rb @@ -9,7 +9,7 @@ read_devfile("example.tools-injector-inserted-devfile.yaml.erb") end - let(:expected_processed_devfile_name) { 'example.main-container-updated-devfile.yaml.erb' } + let(:expected_processed_devfile_name) { "example.main-container-updated-devfile.yaml.erb" } let(:expected_processed_devfile) { read_devfile(expected_processed_devfile_name) } let(:vscode_extension_marketplace_metadata_enabled) { false } diff --git a/ee/spec/lib/remote_development/workspace_operations/create/workspace_variables_builder_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/workspace_variables_builder_spec.rb index 316368a8833aff..9e164169170498 100644 --- a/ee/spec/lib/remote_development/workspace_operations/create/workspace_variables_builder_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/create/workspace_variables_builder_spec.rb @@ -17,6 +17,12 @@ let(:git_credential_store_script) { RemoteDevelopment::Files::GIT_CREDENTIAL_STORE_SCRIPT } let(:expected_variables) do [ + { + key: "GL_WORKSPACE_LOGS_DIR", + value: RemoteDevelopment::WorkspaceOperations::WorkspaceOperationsConstants::WORKSPACE_LOGS_DIR, + variable_type: RemoteDevelopment::Enums::WorkspaceVariable::ENVIRONMENT_TYPE, + workspace_id: workspace_id + }, { key: create_constants_module::TOKEN_FILE_NAME, value: "example-pat-value", diff --git a/ee/spec/lib/remote_development/workspace_operations/create/workspace_variables_creator_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/workspace_variables_creator_spec.rb index 2bfddb68f2b91f..0035a98dc14cfa 100644 --- a/ee/spec/lib/remote_development/workspace_operations/create/workspace_variables_creator_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/create/workspace_variables_creator_spec.rb @@ -48,7 +48,7 @@ context "when workspace variables create is successful" do let(:valid_variable_type) { RemoteDevelopment::Enums::WorkspaceVariable::ENVIRONMENT_TYPE } let(:variable_type) { valid_variable_type } - let(:expected_number_of_records_saved) { 18 } + let(:expected_number_of_records_saved) { 19 } it "creates the workspace variable records and returns ok result containing original context" do expect { result }.to change { workspace.workspace_variables.count }.by(expected_number_of_records_saved) @@ -63,10 +63,10 @@ context "when workspace create fails" do let(:invalid_variable_type) { 9999999 } let(:variable_type) { invalid_variable_type } - let(:expected_number_of_records_saved) { 16 } + let(:expected_number_of_records_saved) { 17 } it "does not create the invalid workspace variable records and returns an error result with model errors" do - # NOTE: Any valid records will be saved if they are first in the array before the invalid record, but that"s OK, + # NOTE: Any valid records will be saved if they are first in the array before the invalid record, but that's OK, # because if we return an err_result, the entire transaction will be rolled back at a higher level. expect { result }.to change { workspace.workspace_variables.count }.by(expected_number_of_records_saved) 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 00ef6b2eb51af5..c60d4c98f4e5f1 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 @@ -279,8 +279,8 @@ def input_processed_devfile_yaml_without_poststart_event command: - "/bin/sh" - "-c" - memoryLimit: 512Mi - memoryRequest: 256Mi + memoryLimit: 1000Mi + memoryRequest: 500Mi cpuLimit: 500m cpuRequest: 100m - name: gl-workspace-data @@ -489,8 +489,23 @@ def golden_master_desired_config_with_include_all_resources_true { mountPath: "/.workspace-data/variables/file", name: "gl-workspace-variables" + }, + { + name: "gl-workspace-scripts", + mountPath: "/workspace-scripts" } - ] + ], + lifecycle: { + postStart: { + exec: { + 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" + ] + } + } + } } ], initContainers: [ @@ -577,6 +592,19 @@ def golden_master_desired_config_with_include_all_resources_true } ] } + }, + { + name: "gl-workspace-scripts", + projected: { + defaultMode: 508, + sources: [ + { + configMap: { + name: "scripts-configmap" + } + } + ] + } } ] } @@ -766,6 +794,31 @@ def golden_master_desired_config_with_include_all_resources_true ] } }, + { + 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: "scripts-configmap", + namespace: "gl-rd-ns-991-990-fedcba" + }, + data: { + "gl-run-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): Running /workspace-scripts/gl-example-tooling-container-internal-command...\"\n/workspace-scripts/gl-example-tooling-container-internal-command || true\n", + "gl-example-tooling-container-internal-command": "echo 'example tooling container internal command'" + } + }, { apiVersion: "v1", kind: "ConfigMap", @@ -1010,8 +1063,23 @@ def golden_master_desired_config_with_include_all_resources_false { mountPath: "/.workspace-data/variables/file", name: "gl-workspace-variables" + }, + { + name: "gl-workspace-scripts", + mountPath: "/workspace-scripts" } - ] + ], + lifecycle: { + postStart: { + exec: { + 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" + ] + } + } + } } ], initContainers: [ @@ -1098,6 +1166,19 @@ def golden_master_desired_config_with_include_all_resources_false } ] } + }, + { + name: "gl-workspace-scripts", + projected: { + defaultMode: 508, + sources: [ + { + configMap: { + name: "scripts-configmap" + } + } + ] + } } ] } @@ -1286,6 +1367,31 @@ def golden_master_desired_config_with_include_all_resources_false "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: "scripts-configmap", + namespace: "gl-rd-ns-991-990-fedcba" + }, + data: { + "gl-run-poststart-commands.sh": "#!/bin/sh\necho \"$(date -Iseconds): Running /workspace-scripts/gl-example-tooling-container-internal-command...\"\n/workspace-scripts/gl-example-tooling-container-internal-command || true\n", + "gl-example-tooling-container-internal-command": "echo 'example tooling container internal command'" + } } ] end @@ -1468,11 +1574,532 @@ def golden_master_desired_config_from_legacy_devfile_with_no_poststart_and_with_ resources: { limits: { cpu: "500m", - memory: "512Mi" + memory: "1000Mi" }, requests: { cpu: "100m", - memory: "256Mi" + 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: 508, + sources: [ + { + secret: { + name: "workspace-991-990-fedcba-file" + } + } + ] + } + } + ] + } + } + }, + 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", + "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" + } + } + ] + end + + # @return [Array] + def golden_master_desired_config_from_legacy_devfile_with_no_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" + } + ] + } + ], + initContainers: [ + { + args: [ + "echo 'project cloner container args'" + ], + command: [ + "/bin/sh", + "-c" + ], + env: [ + { + name: "PROJECTS_ROOT", + value: "/projects" + }, + { + name: "PROJECT_SOURCE", + value: "/projects" + } + ], + envFrom: [ + { + secretRef: { + name: "workspace-991-990-fedcba-env-var" + } + } + ], + image: "alpine/git:2.45.2", + imagePullPolicy: "Always", + name: "gl-project-cloner-gl-project-cloner-command-1", + resources: { + limits: { + cpu: "500m", + memory: "1000Mi" + }, + requests: { + cpu: "100m", + memory: "500Mi" } }, securityContext: { 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 1b3c1d0cb7c453..bb1b19ddc8c96c 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 @@ -15,12 +15,15 @@ let(:started) { true } let(:desired_state_is_terminated) { false } let(:include_all_resources) { false } + let(:include_scripts_resources) { true } + let(:legacy_scripts_in_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' } let(:max_resources_per_workspace) { {} } let(:default_resources_per_workspace_container) { {} } let(:image_pull_secrets) { [] } + let(:processed_devfile_yaml) { example_processed_devfile_yaml } let(:workspaces_agent_config) do config = create( :workspaces_agent_config, @@ -41,7 +44,8 @@ agent: agent, user: user, desired_state: desired_state, - actual_state: actual_state + actual_state: actual_state, + processed_devfile: processed_devfile_yaml ) end @@ -52,6 +56,8 @@ desired_state_is_terminated: desired_state_is_terminated, 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, 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, @@ -201,6 +207,18 @@ expect(resource_quota).not_to be_nil 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(:processed_devfile_yaml) do + read_devfile_yaml("example.legacy-scripts-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 end context 'when DevfileParser returns empty array' do diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/devfile_parser_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/devfile_parser_spec.rb index 11f37197bf5aaa..adceb0e4a00c36 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/devfile_parser_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/devfile_parser_spec.rb @@ -113,6 +113,7 @@ agent_labels: agent_labels, agent_annotations: agent_annotations, image_pull_secrets: image_pull_secrets, + include_scripts_resources: false, core_resources_only: true ) end 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 new file mode 100644 index 00000000000000..c562a5a17c82d1 --- /dev/null +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/kubernetes_poststart_hook_inserter_spec.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +require "fast_spec_helper" + +RSpec.describe RemoteDevelopment::WorkspaceOperations::Reconcile::Output::KubernetesPoststartHookInserter, feature_category: :workspaces do + include_context 'with remote development shared fixtures' + + let(:processed_devfile) { example_processed_devfile } + let(:devfile_commands) { processed_devfile.fetch(:commands) } + let(:devfile_events) { processed_devfile.fetch(:events) } + let(:input_containers) do + deployment = create_deployment(include_scripts_resources: false) + deployment => { + spec: { + template: { + spec: { + containers: Array => containers + } + } + } + } + containers + end + + let(:expected_containers) do + deployment = create_deployment(include_scripts_resources: true) + deployment => { + spec: { + template: { + spec: { + containers: Array => containers + } + } + } + } + containers + end + + subject(:invoke_insert) do + described_class.insert( + # pass input containers without resources for scripts added, then assert they get added by the described_class + containers: input_containers, + devfile_commands: devfile_commands, + devfile_events: devfile_events + ) + 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 + }, + *_ + ] + + input_containers => [ + *_, + { + lifecycle: Hash => first_container_updated_lifecycle_hooks + }, + *_ + ] + + expect(first_container_updated_lifecycle_hooks).to eq(first_container_expected_lifecycle_hooks) + end + + private + + # @param [Boolean] include_scripts_resources + # @return [Hash] + def create_deployment(include_scripts_resources:) + workspace_deployment( + workspace_name: "name", + workspace_namespace: "namespace", + include_scripts_resources: include_scripts_resources + ) + 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 new file mode 100644 index 00000000000000..a5ce42d750fc8f --- /dev/null +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/scripts_configmap_appender_spec.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +require "fast_spec_helper" + +RSpec.describe RemoteDevelopment::WorkspaceOperations::Reconcile::Output::ScriptsConfigmapAppender, feature_category: :workspaces do + include_context 'with remote development shared fixtures' + + let(:files) { RemoteDevelopment::Files } + let(:annotations) { { a: "1" } } + let(:labels) { { b: "2" } } + let(:namespace) { "namespace" } + let(:processed_devfile) { example_processed_devfile } + let(:devfile_commands) { processed_devfile.fetch(:commands) } + let(:devfile_events) { processed_devfile.fetch(:events) } + let(:expected_postart_commands_script) do + <<~SCRIPT + #!/bin/sh + echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-start-sshd-command..." + #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-start-sshd-command || true + echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-init-tools-command..." + #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-init-tools-command || true + echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command..." + #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command || true + SCRIPT + end + + subject(:updated_desired_config) do + # Make a fake desired config with one existing fake element, to prove we are appending + desired_config = [ + {} + ] + + described_class.append( + desired_config: desired_config, + namespace: namespace, + labels: labels, + annotations: annotations, + devfile_commands: devfile_commands, + devfile_events: devfile_events + ) + + desired_config + 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: name + }, + data: data + }, + ] + + expect(api_version).to eq("v1") + expect(name).to eq(reconcile_constants_module::WORKSPACE_SCRIPTS_CONFIGMAP_NAME) + expect(data).to eq( + "gl-init-tools-command": files::MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT, + reconcile_constants_module::RUN_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => + expected_postart_commands_script, + "gl-sleep-until-container-is-running-command": + files::MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, + "gl-start-sshd-command": files::MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT + ) + end +end diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter_spec.rb new file mode 100644 index 00000000000000..106c60b95d2274 --- /dev/null +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter_spec.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +require "fast_spec_helper" + +RSpec.describe RemoteDevelopment::WorkspaceOperations::Reconcile::Output::ScriptsVolumeInserter, feature_category: :workspaces do + include_context 'with remote development shared fixtures' + + let(:processed_devfile) { example_processed_devfile } + let(:input_containers) do + [ + { volumeMounts: [{}] }, + { volumeMounts: [{}] } + ] + end + + let(:input_volumes) { [{}] } + + subject(:invoke_insert) do + described_class.insert( + containers: input_containers, + volumes: input_volumes + ) + end + + it "inserts volume" do + invoke_insert + + expect(input_volumes.length).to eq(2) + + input_volumes => [ + {}, # existing fake element + { + name: volume_name, + projected: { + defaultMode: mode, + sources: [ + { + configMap: { + name: configmap_name + } + } + ] + } + } + ] + + expect(volume_name) + .to eq(reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_NAME) + expect(mode).to eq(0o774) + expect(configmap_name) + .to eq(reconcile_constants_module::WORKSPACE_SCRIPTS_CONFIGMAP_NAME) + end + + it "inserts volumeMounts" do + invoke_insert + + expect(input_containers.all? { |c| c[:volumeMounts].length == 2 }).to be true + + input_containers => [ + { + volumeMounts: [ + {}, # existing fake element + inserted_mount_1 + ] + }, + { + volumeMounts: [ + {}, # existing fake element + inserted_mount_2 + ] + } + ] + + expected_mount = { + name: reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_NAME, + mountPath: reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH + } + + expect(inserted_mount_1).to eq(expected_mount) + expect(inserted_mount_2).to eq(expected_mount) + end +end diff --git a/ee/spec/requests/remote_development/integration_spec.rb b/ee/spec/requests/remote_development/integration_spec.rb index eede75954da165..b3d7b2f85597ba 100644 --- a/ee/spec/requests/remote_development/integration_spec.rb +++ b/ee/spec/requests/remote_development/integration_spec.rb @@ -129,6 +129,7 @@ def expected_internal_variables(random_string:) # rubocop:disable Layout/LineLength -- keep them on one line for easier readability and editability [ + { key: "GL_WORKSPACE_LOGS_DIR", type: :environment, value: workspace_operations_constants_module::WORKSPACE_LOGS_DIR }, { key: create_constants_module::TOKEN_FILE_NAME, type: :file, value: /glpat-.+/ }, { key: "GL_TOKEN_FILE_PATH", type: :environment, value: token_file_path }, { key: git_credential_store_script_file_name, type: :file, value: git_credential_store_script }, 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 f5173e21a5967e..5a382c3a0d8ffa 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 @@ -330,7 +330,7 @@ def create_config_to_apply(workspace:, **args) # rubocop:enable GitlabSecurity/PublicSend end - # rubocop:disable Metrics/ParameterLists, Metrics/AbcSize -- Cleanup as part of https://gitlab.com/gitlab-org/gitlab/-/issues/421687 + # rubocop:disable Metrics/ParameterLists, Metrics/AbcSize, Metrics/PerceivedComplexity -- Cleanup as part of https://gitlab.com/gitlab-org/gitlab/-/issues/421687 # @param [RemoteDevelopment::Workspace] workspace # @param [Boolean] started @@ -353,6 +353,8 @@ def create_config_to_apply(workspace:, **args) # @param [String] project_name # @param [String] namespace_path # @param [Array] image_pull_secrets + # @param [Boolean] include_scripts_resources + # @param [Boolean] legacy_scripts_in_container_command # @param [Boolean] core_resources_only # @return [Array] def create_config_to_apply_v3( @@ -380,6 +382,8 @@ def create_config_to_apply_v3( project_name: "test-project", namespace_path: "test-group", image_pull_secrets: [], + include_scripts_resources: true, + legacy_scripts_in_container_command: false, core_resources_only: false ) spec_replicas = started ? 1 : 0 @@ -427,7 +431,9 @@ def create_config_to_apply_v3( default_resources_per_workspace_container: default_resources_per_workspace_container, allow_privilege_escalation: allow_privilege_escalation, use_kubernetes_user_namespaces: use_kubernetes_user_namespaces, - default_runtime_class: default_runtime_class + default_runtime_class: default_runtime_class, + include_scripts_resources: include_scripts_resources, + legacy_scripts_in_container_command: legacy_scripts_in_container_command ) workspace_service = workspace_service( @@ -460,6 +466,12 @@ def create_config_to_apply_v3( egress_ip_rules: egress_ip_rules ) + scripts_configmap = scripts_configmap( + workspace_namespace: workspace.namespace, + labels: labels, + annotations: workspace_inventory_annotations + ) + secrets_inventory_config_map = secrets_inventory_config_map( workspace_name: workspace.name, workspace_namespace: workspace.namespace, @@ -513,6 +525,7 @@ def create_config_to_apply_v3( unless core_resources_only resources << workspace_service_account resources << workspace_network_policy if include_network_policy + resources << scripts_configmap if include_scripts_resources if include_all_resources resources << secrets_inventory_config_map if include_inventory @@ -525,7 +538,7 @@ def create_config_to_apply_v3( normalize_resources(namespace_path, project_name, resources) end - # rubocop:enable Metrics/ParameterLists, Metrics/CyclomaticComplexity, Metrics/AbcSize + # rubocop:enable Metrics/ParameterLists, Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/PerceivedComplexity # @param [String] workspace_name # @param [String] workspace_namespace @@ -555,24 +568,28 @@ def workspace_inventory_config_map(workspace_name:, workspace_namespace:, labels # @param [String] workspace_name # @param [String] workspace_namespace - # @param [Hash] labels + # @param [Boolean] allow_privilege_escalation # @param [Hash] annotations - # @param [Integer] spec_replicas # @param [Hash] default_resources_per_workspace_container - # @param [Boolean] allow_privilege_escalation - # @param [Boolean] use_kubernetes_user_namespaces # @param [String] default_runtime_class + # @param [Boolean] include_scripts_resources + # @param [Boolean] legacy_scripts_in_container_command + # @param [Hash] labels + # @param [Integer] spec_replicas + # @param [Boolean] use_kubernetes_user_namespaces # @return [Hash] def workspace_deployment( workspace_name:, workspace_namespace:, - labels:, - annotations:, - spec_replicas:, - default_resources_per_workspace_container:, - allow_privilege_escalation:, - use_kubernetes_user_namespaces:, - default_runtime_class: + allow_privilege_escalation: false, + annotations: {}, + default_resources_per_workspace_container: {}, + default_runtime_class: "", + include_scripts_resources: true, + legacy_scripts_in_container_command: false, + labels: {}, + spec_replicas: 1, + use_kubernetes_user_namespaces: false ) container_security_context = { 'allowPrivilegeEscalation' => allow_privilege_escalation, @@ -672,6 +689,10 @@ def workspace_deployment( { mountPath: workspace_operations_constants_module::VARIABLES_VOLUME_PATH, name: workspace_operations_constants_module::VARIABLES_VOLUME_NAME + }, + { + mountPath: reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH, + name: reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_NAME } ], securityContext: container_security_context, @@ -681,7 +702,23 @@ def workspace_deployment( name: "#{workspace_name}-env-var" } } - ] + ], + lifecycle: { + postStart: { + exec: { + command: [ + "/bin/sh", + "-c", + format( + files_module::KUBERNETES_POSTSTART_HOOK_COMMAND, + run_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 + ) + ] + } + } + } }, { env: [ @@ -710,6 +747,10 @@ def workspace_deployment( { mountPath: workspace_operations_constants_module::VARIABLES_VOLUME_PATH, name: workspace_operations_constants_module::VARIABLES_VOLUME_NAME + }, + { + mountPath: reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH, + name: reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_NAME } ], securityContext: container_security_context, @@ -837,6 +878,19 @@ def workspace_deployment( } ] } + }, + { + name: reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_NAME, + projected: { + defaultMode: 508, + sources: [ + { + configMap: { + name: reconcile_constants_module::WORKSPACE_SCRIPTS_CONFIGMAP_NAME + } + } + ] + } } ], securityContext: { @@ -851,6 +905,26 @@ def workspace_deployment( status: {} } + unless include_scripts_resources + deployment[:spec][:template][:spec][:containers].each do |container| + container[:volumeMounts].delete_if do |volume_mount| + volume_mount[:name] == reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_NAME + end + end + deployment[:spec][:template][:spec][:volumes].delete_if do |volume| + volume[:name] == reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_NAME + end + deployment[:spec][:template][:spec][:containers][0].delete(:lifecycle) + end + + if legacy_scripts_in_container_command + deployment[:spec][:template][:spec][:containers][0][:args][0] = + <<~YAML.chomp + #{files_module::MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT} + #{files_module::MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT} + YAML + end + deployment[:spec][:template][:spec].delete(:runtimeClassName) if default_runtime_class.empty? deployment[:spec][:template][:spec].delete(:hostUsers) unless use_kubernetes_user_namespaces @@ -919,7 +993,7 @@ def pvc( annotations: annotations, creationTimestamp: nil, labels: labels, - name: "#{workspace_name}-gl-workspace-data", + name: "#{workspace_name}-#{create_constants_module::WORKSPACE_DATA_VOLUME_NAME}", namespace: workspace_namespace }, spec: { @@ -1032,6 +1106,62 @@ def workspace_network_policy( } end + # @param [String] workspace_namespace + # @param [Hash] labels + # @param [Hash] annotations + # @return [Hash] + def scripts_configmap(workspace_namespace:, labels:, annotations:) + postart_commands_script = + <<~SCRIPT + #!/bin/sh + echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-start-sshd-command..." + #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-start-sshd-command || true + echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-init-tools-command..." + #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-init-tools-command || true + echo "$(date -Iseconds): Running #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command..." + #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command || true + SCRIPT + + { + apiVersion: "v1", + kind: "ConfigMap", + metadata: { + annotations: annotations, + labels: labels, + name: reconcile_constants_module::WORKSPACE_SCRIPTS_CONFIGMAP_NAME, + namespace: workspace_namespace + }, + data: { + "gl-init-tools-command": files_module::MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT, + reconcile_constants_module::RUN_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => postart_commands_script, + "gl-sleep-until-container-is-running-command": + files_module::MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, + "gl-start-sshd-command": files_module::MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT + } + } + end + + # @param [String] workspace_name + # @param [String] workspace_namespace + # @param [Hash] labels + # @param [Hash] annotations + # @return [Hash] + def secrets_inventory_config_map(workspace_name:, workspace_namespace:, labels:, annotations:) + { + apiVersion: "v1", + kind: "ConfigMap", + metadata: { + annotations: annotations, + labels: + Gitlab::Utils.deep_sort_hashes( + labels.merge({ "cli-utils.sigs.k8s.io/inventory-id": "#{workspace_name}-secrets-inventory" }) + ), + name: "#{workspace_name}-secrets-inventory", + namespace: workspace_namespace + } + } + end + # @param [String] workspace_name # @param [String] workspace_namespace # @param [Hash] labels @@ -1076,27 +1206,6 @@ def workspace_resource_quota( } end - # @param [String] workspace_name - # @param [String] workspace_namespace - # @param [Hash] labels - # @param [Hash] annotations - # @return [Hash] - def secrets_inventory_config_map(workspace_name:, workspace_namespace:, labels:, annotations:) - { - apiVersion: "v1", - kind: "ConfigMap", - metadata: { - annotations: annotations, - labels: - Gitlab::Utils.deep_sort_hashes( - labels.merge({ "cli-utils.sigs.k8s.io/inventory-id": "#{workspace_name}-secrets-inventory" }) - ), - name: "#{workspace_name}-secrets-inventory", - namespace: workspace_namespace - } - } - end - # @param [String] workspace_name # @param [String] workspace_namespace # @param [Hash] labels -- GitLab From 1a3e2b19e884e51b02f0c4dfe61a1cc85455d40c Mon Sep 17 00:00:00 2001 From: Chad Woolley Date: Thu, 1 May 2025 20:56:04 -0700 Subject: [PATCH 2/6] Fix specs and cleanup after rebase --- .../workspace_operations/create/workspace_creator.rb | 2 +- .../reconcile/output/desired_config_generator.rb | 2 +- ...scripts-in-container-command-processed-devfile.yaml.erb | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ee/lib/remote_development/workspace_operations/create/workspace_creator.rb b/ee/lib/remote_development/workspace_operations/create/workspace_creator.rb index 0e61b166a9ee40..17beea2a8de5e0 100644 --- a/ee/lib/remote_development/workspace_operations/create/workspace_creator.rb +++ b/ee/lib/remote_development/workspace_operations/create/workspace_creator.rb @@ -32,7 +32,7 @@ def self.create(context) user: User => user, project: Project => project, } - project_dir = "#{WORKSPACE_DATA_VOLUME_PATH}/#{project.path}" + project_dir = "#{workspace_data_volume_path}/#{project.path}" workspace = RemoteDevelopment::Workspace.new workspace.name = workspace_name diff --git a/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator.rb b/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator.rb index 6fca809460e629..aa041a5ce26e7c 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator.rb @@ -377,7 +377,7 @@ def self.append_scripts_resources(desired_config:, processed_devfile_yaml:, name # added support for devfile postStart events. In that case, we don't want to add any resources # related to the postStart script handling, because that would cause those existing workspaces # to restart because the deployment would be updated. - return unless devfile_events[:postStart] + return unless devfile_events[:postStart].present? ScriptsConfigmapAppender.append( desired_config: desired_config, diff --git a/ee/spec/fixtures/remote_development/example.legacy-scripts-in-container-command-processed-devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.legacy-scripts-in-container-command-processed-devfile.yaml.erb index f2a98e5bb58c65..c0e3a8f5929404 100644 --- a/ee/spec/fixtures/remote_development/example.legacy-scripts-in-container-command-processed-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.legacy-scripts-in-container-command-processed-devfile.yaml.erb @@ -9,7 +9,8 @@ components: image: quay.io/mloriedo/universal-developer-image:ubi8-dw-demo args: - | - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_CONTAINER_ARGS, 10) %> + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT, 10) %> + <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT, 10) %> command: - "/bin/sh" - "-c" @@ -75,8 +76,8 @@ components: command: - "/bin/sh" - "-c" - memoryLimit: 512Mi - memoryRequest: 256Mi + memoryLimit: 1000Mi + memoryRequest: 500Mi cpuLimit: 500m cpuRequest: 100m - name: gl-workspace-data -- GitLab From a946723e5ce6010e983364eb58dfc784579ca10f Mon Sep 17 00:00:00 2001 From: Chad Woolley Date: Thu, 1 May 2025 21:23:28 -0700 Subject: [PATCH 3/6] Review feedback: Introduce defaultMode constants --- .../reconcile/output/devfile_parser.rb | 2 +- .../reconcile/output/scripts_volume_inserter.rb | 2 +- .../reconcile/reconcile_constants.rb | 1 + .../workspace_operations_constants.rb | 1 + .../desired_config_generator_golden_master_spec.rb | 12 ++++++------ .../reconcile/output/scripts_volume_inserter_spec.rb | 2 +- .../remote_development_shared_contexts.rb | 4 ++-- 7 files changed, 13 insertions(+), 11 deletions(-) diff --git a/ee/lib/remote_development/workspace_operations/reconcile/output/devfile_parser.rb b/ee/lib/remote_development/workspace_operations/reconcile/output/devfile_parser.rb index ba7ce58657c7e3..e61dcc265829b3 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/output/devfile_parser.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/devfile_parser.rb @@ -216,7 +216,7 @@ def self.inject_secrets(workspace_resources:, env_secret_names:, file_secret_nam volume = { name: VARIABLES_VOLUME_NAME, projected: { - defaultMode: 0o774, + defaultMode: VARIABLES_VOLUME_DEFAULT_MODE, sources: file_secret_names.map { |name| { secret: { name: name } } } } } diff --git a/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter.rb b/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter.rb index c64b898e7d78de..cc4b84b281711b 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter.rb @@ -15,7 +15,7 @@ def self.insert(containers:, volumes:) { name: WORKSPACE_SCRIPTS_VOLUME_NAME, projected: { - defaultMode: 0o774, + defaultMode: WORKSPACE_SCRIPTS_VOLUME_DEFAULT_MODE, sources: [ { configMap: { 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 f2a1430d8d9656..ed55f7d0d2b098 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/reconcile_constants.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/reconcile_constants.rb @@ -19,6 +19,7 @@ module ReconcileConstants WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH = "#{VARIABLES_VOLUME_PATH}/#{WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}".freeze WORKSPACE_SCRIPTS_CONFIGMAP_NAME = "scripts-configmap" + WORKSPACE_SCRIPTS_VOLUME_DEFAULT_MODE = 0o774 WORKSPACE_SCRIPTS_VOLUME_NAME = "gl-workspace-scripts" WORKSPACE_SCRIPTS_VOLUME_PATH = "/workspace-scripts" 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 cbde68f388fb1a..75ed622382e6ab 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,7 @@ module WorkspaceOperations # See documentation at ../README.md#constant-declarations for more information. module WorkspaceOperationsConstants # Please keep alphabetized + VARIABLES_VOLUME_DEFAULT_MODE = 0o774 VARIABLES_VOLUME_NAME = "gl-workspace-variables" VARIABLES_VOLUME_PATH = "/.workspace-data/variables/file" WORKSPACE_DATA_VOLUME_PATH = "/projects" 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 c60d4c98f4e5f1..136b8e29370909 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 @@ -583,7 +583,7 @@ def golden_master_desired_config_with_include_all_resources_true { name: "gl-workspace-variables", projected: { - defaultMode: 508, + defaultMode: 0o774, sources: [ { secret: { @@ -596,7 +596,7 @@ def golden_master_desired_config_with_include_all_resources_true { name: "gl-workspace-scripts", projected: { - defaultMode: 508, + defaultMode: 0o774, sources: [ { configMap: { @@ -1157,7 +1157,7 @@ def golden_master_desired_config_with_include_all_resources_false { name: "gl-workspace-variables", projected: { - defaultMode: 508, + defaultMode: 0o774, sources: [ { secret: { @@ -1170,7 +1170,7 @@ def golden_master_desired_config_with_include_all_resources_false { name: "gl-workspace-scripts", projected: { - defaultMode: 508, + defaultMode: 0o774, sources: [ { configMap: { @@ -1617,7 +1617,7 @@ def golden_master_desired_config_from_legacy_devfile_with_no_poststart_and_with_ { name: "gl-workspace-variables", projected: { - defaultMode: 508, + defaultMode: 0o774, sources: [ { secret: { @@ -2138,7 +2138,7 @@ def golden_master_desired_config_from_legacy_devfile_with_no_poststart_and_with_ { name: "gl-workspace-variables", projected: { - defaultMode: 508, + defaultMode: 0o774, sources: [ { secret: { diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter_spec.rb index 106c60b95d2274..f43f4cb3298a3b 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter_spec.rb @@ -46,7 +46,7 @@ expect(volume_name) .to eq(reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_NAME) - expect(mode).to eq(0o774) + expect(mode).to eq(reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_DEFAULT_MODE) expect(configmap_name) .to eq(reconcile_constants_module::WORKSPACE_SCRIPTS_CONFIGMAP_NAME) 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 5a382c3a0d8ffa..042884cb9463ba 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 @@ -869,7 +869,7 @@ def workspace_deployment( { name: workspace_operations_constants_module::VARIABLES_VOLUME_NAME, projected: { - defaultMode: 508, + defaultMode: workspace_operations_constants_module::VARIABLES_VOLUME_DEFAULT_MODE, sources: [ { secret: { @@ -882,7 +882,7 @@ def workspace_deployment( { name: reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_NAME, projected: { - defaultMode: 508, + defaultMode: reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_DEFAULT_MODE, sources: [ { configMap: { -- GitLab From a01b85800e9d2444f3312c35dd4c67e005fae5c4 Mon Sep 17 00:00:00 2001 From: Chad Woolley Date: Thu, 1 May 2025 21:43:49 -0700 Subject: [PATCH 4/6] Fix RubyMine warnings, including duplicated method --- .../open_in_workspace_spec.rb | 1 + ...red_config_generator_golden_master_spec.rb | 521 ------------------ .../remote_development/integration_spec.rb | 1 + 3 files changed, 2 insertions(+), 521 deletions(-) diff --git a/ee/spec/features/remote_development/open_in_workspace_spec.rb b/ee/spec/features/remote_development/open_in_workspace_spec.rb index 37deed1921a046..c9500c859c4d63 100644 --- a/ee/spec/features/remote_development/open_in_workspace_spec.rb +++ b/ee/spec/features/remote_development/open_in_workspace_spec.rb @@ -18,6 +18,7 @@ end it 'they should be able to click on Open in Workspace' do + # noinspection RubyArgCount -- Rubymine is incorrectly thinking this is an invalid block argument within '.merge-request' do click_button 'Code' end 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 136b8e29370909..c65c14ad800271 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 @@ -1917,526 +1917,5 @@ def golden_master_desired_config_from_legacy_devfile_with_no_poststart_and_with_ ] end - # @return [Array] - def golden_master_desired_config_from_legacy_devfile_with_no_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" - } - ] - } - ], - initContainers: [ - { - args: [ - "echo 'project cloner container args'" - ], - command: [ - "/bin/sh", - "-c" - ], - env: [ - { - name: "PROJECTS_ROOT", - value: "/projects" - }, - { - name: "PROJECT_SOURCE", - value: "/projects" - } - ], - envFrom: [ - { - secretRef: { - name: "workspace-991-990-fedcba-env-var" - } - } - ], - image: "alpine/git:2.45.2", - imagePullPolicy: "Always", - name: "gl-project-cloner-gl-project-cloner-command-1", - resources: { - limits: { - cpu: "500m", - memory: "1000Mi" - }, - requests: { - cpu: "100m", - memory: "500Mi" - } - }, - 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" - } - } - ] - } - } - ] - } - } - }, - 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", - "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" - } - } - ] - end - # rubocop:enable Layout/LineLength, Style/WordArray end diff --git a/ee/spec/requests/remote_development/integration_spec.rb b/ee/spec/requests/remote_development/integration_spec.rb index b3d7b2f85597ba..562e6d5ba4fc57 100644 --- a/ee/spec/requests/remote_development/integration_spec.rb +++ b/ee/spec/requests/remote_development/integration_spec.rb @@ -238,6 +238,7 @@ def do_create_org_mapping organization_id: common_organization.to_global_id.to_s, cluster_agent_id: agent.to_global_id.to_s } + # noinspection RubyMismatchedArgumentType -- RubyMine is not detecting that FactoryBot returns a User type do_graphql_mutation_post( name: :organization_create_cluster_agent_mapping, input: organization_create_cluster_agent_mapping_create_mutation_args, -- GitLab From 77caadb71a82329697218b2729de6be68bc7a0f6 Mon Sep 17 00:00:00 2001 From: Chad Woolley Date: Fri, 2 May 2025 16:43:34 -0700 Subject: [PATCH 5/6] Review feedback: Use constant in script --- .../create/main_component_updater.rb | 14 +++++++--- ...pdater_sleep_until_workspace_is_running.sh | 2 +- .../create/workspace_variables_builder.rb | 2 +- .../kubernetes_poststart_hook_inserter.rb | 2 +- .../reconcile/reconcile_constants.rb | 3 --- .../workspace_operations_constants.rb | 3 +++ ...le.main-container-updated-devfile.yaml.erb | 8 +++++- ...ated-marketplace-disabled-devfile.yaml.erb | 8 +++++- .../example.processed-devfile.yaml.erb | 8 +++++- ...e.project-cloner-inserted-devfile.yaml.erb | 8 +++++- .../output/scripts_configmap_appender_spec.rb | 10 ++++++- .../integration_spec_helpers.rb | 26 +++++++++---------- .../remote_development_shared_contexts.rb | 15 ++++++++--- 13 files changed, 78 insertions(+), 31 deletions(-) diff --git a/ee/lib/remote_development/workspace_operations/create/main_component_updater.rb b/ee/lib/remote_development/workspace_operations/create/main_component_updater.rb index 887d7643d55024..7832d2d0fa3960 100644 --- a/ee/lib/remote_development/workspace_operations/create/main_component_updater.rb +++ b/ee/lib/remote_development/workspace_operations/create/main_component_updater.rb @@ -143,22 +143,28 @@ def self.add_poststart_commands(processed_devfile:, main_component:) poststart_events << start_sshd_command_id # Add the init_tools event - sleep_until_container_is_running_command_id = "gl-init-tools-command" + init_tools_command_id = "gl-init-tools-command" commands << { - id: sleep_until_container_is_running_command_id, + id: init_tools_command_id, exec: { commandLine: MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT, component: main_component_name } } - poststart_events << sleep_until_container_is_running_command_id + poststart_events << init_tools_command_id # Add the sleep_until_container_is_running event sleep_until_container_is_running_command_id = "gl-sleep-until-container-is-running-command" + sleep_until_container_is_running_script = + format( + MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, + workspace_reconciled_actual_state_file_path: WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH + ) + commands << { id: sleep_until_container_is_running_command_id, exec: { - commandLine: MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, + commandLine: sleep_until_container_is_running_script, component: main_component_name } } diff --git a/ee/lib/remote_development/workspace_operations/create/main_component_updater_sleep_until_workspace_is_running.sh b/ee/lib/remote_development/workspace_operations/create/main_component_updater_sleep_until_workspace_is_running.sh index 4f9cd1c4b16a2d..a4dc9035c950ac 100644 --- a/ee/lib/remote_development/workspace_operations/create/main_component_updater_sleep_until_workspace_is_running.sh +++ b/ee/lib/remote_development/workspace_operations/create/main_component_updater_sleep_until_workspace_is_running.sh @@ -2,7 +2,7 @@ echo "$(date -Iseconds): ----------------------------------------" echo "$(date -Iseconds): Sleeping until workspace is running..." time_to_sleep=5 -status_file="/.workspace-data/variables/file/gl_workspace_reconciled_actual_state.txt" +status_file="%s" while [ "$(cat ${status_file})" != "Running" ]; do echo "$(date -Iseconds): Workspace state is '$(cat ${status_file})' from status file '${status_file}'. Blocking remaining postStart events execution for ${time_to_sleep} seconds until state is 'Running'..." sleep ${time_to_sleep} diff --git a/ee/lib/remote_development/workspace_operations/create/workspace_variables_builder.rb b/ee/lib/remote_development/workspace_operations/create/workspace_variables_builder.rb index cf8b54ea5dd7bf..f156ba03be159f 100644 --- a/ee/lib/remote_development/workspace_operations/create/workspace_variables_builder.rb +++ b/ee/lib/remote_development/workspace_operations/create/workspace_variables_builder.rb @@ -59,7 +59,7 @@ def self.build( #------------------------------------------------------------------- # Standard git ENV vars which configure git on the workspace. See https://git-scm.com/docs/git-config { - # TODO: We should be able to move this entry to the scripts volume. + # TODO: Move this entry to the scripts volume: https://gitlab.com/gitlab-org/gitlab/-/issues/539045 # This script is set as the value of `credential.helper` below in `GIT_CONFIG_VALUE_0` key: GIT_CREDENTIAL_STORE_SCRIPT_FILE_NAME, value: GIT_CREDENTIAL_STORE_SCRIPT, 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 5f421b26e77a98..408f5fd59484db 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 @@ -5,7 +5,7 @@ module WorkspaceOperations module Reconcile module Output # NOTE: This class has "Kubernetes" prepended to "Poststart" in the name to make it explicit that it - # deals with Kubernetes postStart hooks in the Kuberneted Deployment resource, and that + # deals with Kubernetes postStart hooks in the Kubernetes Deployment resource, and that # it is NOT dealing with the postStart events which are found in devfiles. class KubernetesPoststartHookInserter include Files 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 ed55f7d0d2b098..b9061e3aa01b12 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/reconcile_constants.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/reconcile_constants.rb @@ -15,9 +15,6 @@ module ReconcileConstants # Please keep alphabetized RUN_AS_USER = 5001 RUN_POSTSTART_COMMANDS_SCRIPT_NAME = "gl-run-poststart-commands.sh" - WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME = "gl_workspace_reconciled_actual_state.txt" - WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH = - "#{VARIABLES_VOLUME_PATH}/#{WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}".freeze WORKSPACE_SCRIPTS_CONFIGMAP_NAME = "scripts-configmap" WORKSPACE_SCRIPTS_VOLUME_DEFAULT_MODE = 0o774 WORKSPACE_SCRIPTS_VOLUME_NAME = "gl-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 75ed622382e6ab..e7ffb5eea5a5f7 100644 --- a/ee/lib/remote_development/workspace_operations/workspace_operations_constants.rb +++ b/ee/lib/remote_development/workspace_operations/workspace_operations_constants.rb @@ -22,6 +22,9 @@ module WorkspaceOperationsConstants VARIABLES_VOLUME_PATH = "/.workspace-data/variables/file" WORKSPACE_DATA_VOLUME_PATH = "/projects" WORKSPACE_LOGS_DIR = "#{WORKSPACE_DATA_VOLUME_PATH}/workspace-logs".freeze + WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME = "gl_workspace_reconciled_actual_state.txt" + WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH = + "#{VARIABLES_VOLUME_PATH}/#{WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}".freeze WORKSPACE_TOOLS_IMAGE = "registry.gitlab.com/gitlab-org/workspaces/gitlab-workspaces-tools:12.0.0" end end 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 1bb706ef9e638a..1aae1f0a36e433 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 @@ -71,7 +71,13 @@ commands: - id: gl-sleep-until-container-is-running-command exec: commandLine: | - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, 8) %> + <%= + script = format( + MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, + workspace_reconciled_actual_state_file_path: WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH + ) + indent_yaml_literal(script, 8) + %> component: tooling-container events: preStart: 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 1bb706ef9e638a..1aae1f0a36e433 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 @@ -71,7 +71,13 @@ commands: - id: gl-sleep-until-container-is-running-command exec: commandLine: | - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, 8) %> + <%= + script = format( + MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, + workspace_reconciled_actual_state_file_path: WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH + ) + indent_yaml_literal(script, 8) + %> component: tooling-container events: preStart: 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 1254c6359c3849..eb9a0482cb358f 100644 --- a/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.processed-devfile.yaml.erb @@ -99,7 +99,13 @@ commands: - id: gl-sleep-until-container-is-running-command exec: commandLine: | - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, 8) %> + <%= + script = format( + MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, + workspace_reconciled_actual_state_file_path: WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH + ) + indent_yaml_literal(script, 8) + %> component: tooling-container - id: gl-project-cloner-command apply: diff --git a/ee/spec/fixtures/remote_development/example.project-cloner-inserted-devfile.yaml.erb b/ee/spec/fixtures/remote_development/example.project-cloner-inserted-devfile.yaml.erb index 45e9fa12410adf..3bbfc3d01c7926 100644 --- a/ee/spec/fixtures/remote_development/example.project-cloner-inserted-devfile.yaml.erb +++ b/ee/spec/fixtures/remote_development/example.project-cloner-inserted-devfile.yaml.erb @@ -84,7 +84,13 @@ commands: - id: gl-sleep-until-container-is-running-command exec: commandLine: | - <%= indent_yaml_literal(MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, 8) %> + <%= + script = format( + MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, + workspace_reconciled_actual_state_file_path: WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH + ) + indent_yaml_literal(script, 8) + %> component: tooling-container - id: gl-project-cloner-command apply: 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 a5ce42d750fc8f..8b51e969ebc281 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 @@ -24,6 +24,14 @@ SCRIPT end + let(:main_component_updater_sleep_until_container_is_running_script) do + format( + files::MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, + workspace_reconciled_actual_state_file_path: + workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH + ) + end + subject(:updated_desired_config) do # Make a fake desired config with one existing fake element, to prove we are appending desired_config = [ @@ -63,7 +71,7 @@ reconcile_constants_module::RUN_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => expected_postart_commands_script, "gl-sleep-until-container-is-running-command": - files::MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, + main_component_updater_sleep_until_container_is_running_script, "gl-start-sshd-command": files::MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT ) end diff --git a/ee/spec/support/helpers/remote_development/integration_spec_helpers.rb b/ee/spec/support/helpers/remote_development/integration_spec_helpers.rb index 1d1a92fa166c13..2552049afb335c 100644 --- a/ee/spec/support/helpers/remote_development/integration_spec_helpers.rb +++ b/ee/spec/support/helpers/remote_development/integration_spec_helpers.rb @@ -163,7 +163,7 @@ def simulate_first_poll( workspace: workspace, include_all_resources: true, workspace_variables_additional_data: { - "#{reconcile_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state + "#{workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state }, **additional_args_for_create_config_to_apply_yaml_stream ) @@ -205,7 +205,7 @@ def simulate_second_poll( started: true, include_all_resources: true, workspace_variables_additional_data: { - "#{reconcile_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state + "#{workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state }, **additional_args_for_create_config_to_apply_yaml_stream ) @@ -250,7 +250,7 @@ def simulate_third_poll( workspace: workspace, started: false, workspace_variables_additional_data: { - "#{reconcile_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state + "#{workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state }, **additional_args_for_create_config_to_apply_yaml_stream ) @@ -296,7 +296,7 @@ def simulate_fourth_poll( started: false, include_all_resources: true, workspace_variables_additional_data: { - "#{reconcile_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state + "#{workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state }, **additional_args_for_create_config_to_apply_yaml_stream ) @@ -342,7 +342,7 @@ def simulate_fifth_poll( started: false, include_all_resources: true, workspace_variables_additional_data: { - "#{reconcile_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state + "#{workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state }, **additional_args_for_create_config_to_apply_yaml_stream ) @@ -409,7 +409,7 @@ def simulate_seventh_poll( started: false, include_all_resources: true, workspace_variables_additional_data: { - "#{reconcile_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state + "#{workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state }, **additional_args_for_create_config_to_apply_yaml_stream ) @@ -454,7 +454,7 @@ def simulate_eighth_poll( workspace: workspace, started: true, workspace_variables_additional_data: { - "#{reconcile_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state + "#{workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state }, **additional_args_for_create_config_to_apply_yaml_stream ) @@ -505,7 +505,7 @@ def simulate_ninth_poll( started: true, include_all_resources: true, workspace_variables_additional_data: { - "#{reconcile_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state + "#{workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state }, **additional_args_for_create_config_to_apply_yaml_stream ) @@ -551,7 +551,7 @@ def simulate_tenth_poll( workspace: workspace, started: false, workspace_variables_additional_data: { - "#{reconcile_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state + "#{workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state }, **additional_args_for_create_config_to_apply_yaml_stream ) @@ -597,7 +597,7 @@ def simulate_eleventh_poll( started: false, include_all_resources: true, workspace_variables_additional_data: { - "#{reconcile_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state + "#{workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state }, **additional_args_for_create_config_to_apply_yaml_stream ) @@ -645,7 +645,7 @@ def simulate_twelfth_poll( started: false, include_all_resources: true, workspace_variables_additional_data: { - "#{reconcile_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state + "#{workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state }, **additional_args_for_create_config_to_apply_yaml_stream ) @@ -692,7 +692,7 @@ def simulate_thirteenth_poll( started: false, desired_state_is_terminated: true, workspace_variables_additional_data: { - "#{reconcile_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state + "#{workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state }, **additional_args_for_create_config_to_apply_yaml_stream ) @@ -738,7 +738,7 @@ def simulate_fourteenth_poll( desired_state_is_terminated: true, include_all_resources: true, workspace_variables_additional_data: { - "#{reconcile_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state + "#{workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": actual_state }, **additional_args_for_create_config_to_apply_yaml_stream ) 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 042884cb9463ba..bfbd2749390a6e 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 @@ -497,7 +497,10 @@ def create_config_to_apply_v3( workspace_variables_file: workspace_variables_file || get_workspace_variables_file(workspace_variables: workspace.workspace_variables), additional_data: workspace_variables_additional_data || - { "#{reconcile_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": workspace.actual_state } + { + "#{workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_NAME}": + workspace.actual_state + } ) if max_resources_per_workspace.present? @@ -1122,6 +1125,13 @@ def scripts_configmap(workspace_namespace:, labels:, annotations:) #{reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_PATH}/gl-sleep-until-container-is-running-command || true SCRIPT + sleep_until_container_is_running_script = + format( + RemoteDevelopment::Files::MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, + workspace_reconciled_actual_state_file_path: + workspace_operations_constants_module::WORKSPACE_RECONCILED_ACTUAL_STATE_FILE_PATH + ) + { apiVersion: "v1", kind: "ConfigMap", @@ -1134,8 +1144,7 @@ def scripts_configmap(workspace_namespace:, labels:, annotations:) data: { "gl-init-tools-command": files_module::MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT, reconcile_constants_module::RUN_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => postart_commands_script, - "gl-sleep-until-container-is-running-command": - files_module::MAIN_COMPONENT_UPDATER_SLEEP_UNTIL_CONTAINER_IS_RUNNING_SCRIPT, + "gl-sleep-until-container-is-running-command": sleep_until_container_is_running_script, "gl-start-sshd-command": files_module::MAIN_COMPONENT_UPDATER_START_SSHD_SCRIPT } } -- GitLab From f478dd331f7acd2867296a5ae5b75160e92da0ca Mon Sep 17 00:00:00 2001 From: Chad Woolley Date: Mon, 5 May 2025 13:20:16 -0700 Subject: [PATCH 6/6] Review feedback: add workspace name to scripts configmap --- .../reconcile/output/config_values_extractor.rb | 2 ++ .../reconcile/output/desired_config_generator.rb | 14 +++++++++++++- .../reconcile/output/scripts_configmap_appender.rb | 5 +++-- .../reconcile/output/scripts_volume_inserter.rb | 5 +++-- .../reconcile/reconcile_constants.rb | 1 - .../output/config_values_extractor_spec.rb | 3 +++ .../desired_config_generator_golden_master_spec.rb | 8 ++++---- .../output/desired_config_generator_spec.rb | 8 ++++++++ .../output/scripts_configmap_appender_spec.rb | 6 ++++-- .../output/scripts_volume_inserter_spec.rb | 5 +++-- .../remote_development_shared_contexts.rb | 8 +++++--- 11 files changed, 48 insertions(+), 17 deletions(-) diff --git a/ee/lib/remote_development/workspace_operations/reconcile/output/config_values_extractor.rb b/ee/lib/remote_development/workspace_operations/reconcile/output/config_values_extractor.rb index 9b9b4312bc86c1..39735a3ee777e2 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/output/config_values_extractor.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/config_values_extractor.rb @@ -44,6 +44,7 @@ def self.extract(workspace:) workspace_inventory_name = "#{workspace_name}-workspace-inventory" secrets_inventory_name = "#{workspace_name}-secrets-inventory" + scripts_configmap_name = "#{workspace_name}-scripts-configmap" { # Please keep alphabetized @@ -69,6 +70,7 @@ def self.extract(workspace:) network_policy_egress: deep_sort_and_symbolize_hashes(workspaces_agent_config.network_policy_egress), processed_devfile_yaml: workspace.processed_devfile, replicas: workspace.desired_state_running? ? 1 : 0, + scripts_configmap_name: scripts_configmap_name, secrets_inventory_annotations: deep_sort_and_symbolize_hashes( common_annotations.merge("config.k8s.io/owning-inventory": secrets_inventory_name) diff --git a/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator.rb b/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator.rb index aa041a5ce26e7c..c0193527feab9e 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator.rb @@ -29,6 +29,7 @@ def self.generate_desired_config(workspace:, include_all_resources:, logger:) network_policy_egress: Array => network_policy_egress, processed_devfile_yaml: String => processed_devfile_yaml, replicas: Integer => replicas, + scripts_configmap_name: scripts_configmap_name, secrets_inventory_annotations: Hash => secrets_inventory_annotations, secrets_inventory_name: String => secrets_inventory_name, use_kubernetes_user_namespaces: TrueClass | FalseClass => use_kubernetes_user_namespaces, @@ -111,6 +112,7 @@ def self.generate_desired_config(workspace:, include_all_resources:, logger:) append_scripts_resources( desired_config: desired_config, processed_devfile_yaml: processed_devfile_yaml, + name: scripts_configmap_name, namespace: workspace.namespace, labels: labels, annotations: workspace_inventory_annotations @@ -347,11 +349,19 @@ def self.append_network_policy( # @param [Array] desired_config # @param [String] processed_devfile_yaml + # @param [String] name # @param [String] namespace # @param [Hash] labels # @param [Hash] annotations # @return [void] - def self.append_scripts_resources(desired_config:, processed_devfile_yaml:, namespace:, labels:, annotations:) + def self.append_scripts_resources( + desired_config:, + processed_devfile_yaml:, + name:, + namespace:, + labels:, + annotations: + ) desired_config => [ *_, { @@ -381,6 +391,7 @@ def self.append_scripts_resources(desired_config:, processed_devfile_yaml:, name ScriptsConfigmapAppender.append( desired_config: desired_config, + name: name, namespace: namespace, labels: labels, annotations: annotations, @@ -389,6 +400,7 @@ def self.append_scripts_resources(desired_config:, processed_devfile_yaml:, name ) ScriptsVolumeInserter.insert( + configmap_name: name, containers: containers, volumes: volumes ) 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 9e33bd83de1ea4..717b60d1b71129 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 @@ -8,13 +8,14 @@ class ScriptsConfigmapAppender include ReconcileConstants # @param [Array] desired_config + # @param [String] name # @param [String] namespace # @param [Hash] labels # @param [Hash] annotations # @param [Array] devfile_commands # @param [Hash] devfile_events # @return [void] - def self.append(desired_config:, namespace:, labels:, annotations:, devfile_commands:, devfile_events:) + def self.append(desired_config:, name:, namespace:, labels:, annotations:, devfile_commands:, devfile_events:) configmap_data = {} configmap = @@ -22,7 +23,7 @@ def self.append(desired_config:, namespace:, labels:, annotations:, devfile_comm kind: "ConfigMap", apiVersion: "v1", metadata: { - name: WORKSPACE_SCRIPTS_CONFIGMAP_NAME, + name: name, namespace: namespace, labels: labels, annotations: annotations diff --git a/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter.rb b/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter.rb index cc4b84b281711b..9bd2ca40a9a5cd 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter.rb @@ -7,10 +7,11 @@ module Output class ScriptsVolumeInserter include ReconcileConstants + # @param [String] configmap_name # @param [Array] containers # @param [Array] volumes # @return [void] - def self.insert(containers:, volumes:) + def self.insert(configmap_name:, containers:, volumes:) volume = { name: WORKSPACE_SCRIPTS_VOLUME_NAME, @@ -19,7 +20,7 @@ def self.insert(containers:, volumes:) sources: [ { configMap: { - name: WORKSPACE_SCRIPTS_CONFIGMAP_NAME + name: configmap_name } } ] 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 b9061e3aa01b12..bd31907166842b 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/reconcile_constants.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/reconcile_constants.rb @@ -15,7 +15,6 @@ module ReconcileConstants # Please keep alphabetized RUN_AS_USER = 5001 RUN_POSTSTART_COMMANDS_SCRIPT_NAME = "gl-run-poststart-commands.sh" - WORKSPACE_SCRIPTS_CONFIGMAP_NAME = "scripts-configmap" WORKSPACE_SCRIPTS_VOLUME_DEFAULT_MODE = 0o774 WORKSPACE_SCRIPTS_VOLUME_NAME = "gl-workspace-scripts" WORKSPACE_SCRIPTS_VOLUME_PATH = "/workspace-scripts" diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/config_values_extractor_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/config_values_extractor_spec.rb index a820517ba736b3..db35f2f478f0da 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/config_values_extractor_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/config_values_extractor_spec.rb @@ -114,6 +114,7 @@ network_policy_egress processed_devfile_yaml replicas + scripts_configmap_name secrets_inventory_annotations secrets_inventory_name use_kubernetes_user_namespaces @@ -163,6 +164,8 @@ expect(extracted_values[:processed_devfile_yaml]).to eq(workspace.processed_devfile) + expect(extracted_values[:scripts_configmap_name]).to eq("#{workspace.name}-scripts-configmap") + expect(extracted_values[:secrets_inventory_annotations]).to eq( { "config.k8s.io/owning-inventory": "#{workspace.name}-secrets-inventory", 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 c65c14ad800271..880ea53cf7e3ae 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 @@ -600,7 +600,7 @@ def golden_master_desired_config_with_include_all_resources_true sources: [ { configMap: { - name: "scripts-configmap" + name: "workspace-991-990-fedcba-scripts-configmap" } } ] @@ -811,7 +811,7 @@ def golden_master_desired_config_with_include_all_resources_true tier: "development", "agent.gitlab.com/id": "991" }, - name: "scripts-configmap", + name: "workspace-991-990-fedcba-scripts-configmap", namespace: "gl-rd-ns-991-990-fedcba" }, data: { @@ -1174,7 +1174,7 @@ def golden_master_desired_config_with_include_all_resources_false sources: [ { configMap: { - name: "scripts-configmap" + name: "workspace-991-990-fedcba-scripts-configmap" } } ] @@ -1385,7 +1385,7 @@ def golden_master_desired_config_with_include_all_resources_false tier: "development", "agent.gitlab.com/id": "991" }, - name: "scripts-configmap", + name: "workspace-991-990-fedcba-scripts-configmap", namespace: "gl-rd-ns-991-990-fedcba" }, data: { 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 bb1b19ddc8c96c..6268f8b8b4e024 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 @@ -83,6 +83,14 @@ expect(workspace_resources).to eq(expected_config) end + it "includes the workspace name in all resource names" do + resources_without_workspace_name_in_name = workspace_resources.reject do |resource| + resource[:metadata][:name].include?(workspace.name) + end + + expect(resources_without_workspace_name_in_name).to be_empty + end + context 'when desired_state terminated' do let(:desired_state_is_terminated) { true } let(:desired_state) { states_module::TERMINATED } 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 8b51e969ebc281..0a41e31a76402f 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 @@ -8,6 +8,7 @@ let(:files) { RemoteDevelopment::Files } let(:annotations) { { a: "1" } } let(:labels) { { b: "2" } } + let(:name) { "workspacename-scripts-configmap" } let(:namespace) { "namespace" } let(:processed_devfile) { example_processed_devfile } let(:devfile_commands) { processed_devfile.fetch(:commands) } @@ -40,6 +41,7 @@ described_class.append( desired_config: desired_config, + name: name, namespace: namespace, labels: labels, annotations: annotations, @@ -58,14 +60,14 @@ { apiVersion: api_version, metadata: { - name: name + name: configmap_name }, data: data }, ] expect(api_version).to eq("v1") - expect(name).to eq(reconcile_constants_module::WORKSPACE_SCRIPTS_CONFIGMAP_NAME) + expect(configmap_name).to eq(name) expect(data).to eq( "gl-init-tools-command": files::MAIN_COMPONENT_UPDATER_INIT_TOOLS_SCRIPT, reconcile_constants_module::RUN_POSTSTART_COMMANDS_SCRIPT_NAME.to_sym => diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter_spec.rb index f43f4cb3298a3b..0ffb71392f0cdd 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/scripts_volume_inserter_spec.rb @@ -5,6 +5,7 @@ RSpec.describe RemoteDevelopment::WorkspaceOperations::Reconcile::Output::ScriptsVolumeInserter, feature_category: :workspaces do include_context 'with remote development shared fixtures' + let(:name) { "workspacename-scripts-configmap" } let(:processed_devfile) { example_processed_devfile } let(:input_containers) do [ @@ -17,6 +18,7 @@ subject(:invoke_insert) do described_class.insert( + configmap_name: name, containers: input_containers, volumes: input_volumes ) @@ -47,8 +49,7 @@ expect(volume_name) .to eq(reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_NAME) expect(mode).to eq(reconcile_constants_module::WORKSPACE_SCRIPTS_VOLUME_DEFAULT_MODE) - expect(configmap_name) - .to eq(reconcile_constants_module::WORKSPACE_SCRIPTS_CONFIGMAP_NAME) + expect(configmap_name).to eq(name) end it "inserts volumeMounts" do 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 bfbd2749390a6e..8295e28be85fa4 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 @@ -467,6 +467,7 @@ def create_config_to_apply_v3( ) scripts_configmap = scripts_configmap( + workspace_name: workspace.name, workspace_namespace: workspace.namespace, labels: labels, annotations: workspace_inventory_annotations @@ -889,7 +890,7 @@ def workspace_deployment( sources: [ { configMap: { - name: reconcile_constants_module::WORKSPACE_SCRIPTS_CONFIGMAP_NAME + name: "#{workspace_name}-scripts-configmap" } } ] @@ -1109,11 +1110,12 @@ def workspace_network_policy( } end + # @param [String] workspace_name # @param [String] workspace_namespace # @param [Hash] labels # @param [Hash] annotations # @return [Hash] - def scripts_configmap(workspace_namespace:, labels:, annotations:) + def scripts_configmap(workspace_name:, workspace_namespace:, labels:, annotations:) postart_commands_script = <<~SCRIPT #!/bin/sh @@ -1138,7 +1140,7 @@ def scripts_configmap(workspace_namespace:, labels:, annotations:) metadata: { annotations: annotations, labels: labels, - name: reconcile_constants_module::WORKSPACE_SCRIPTS_CONFIGMAP_NAME, + name: "#{workspace_name}-scripts-configmap", namespace: workspace_namespace }, data: { -- GitLab