Skip to content

feat: Mounting resources should not cause workspace restart#1533

Draft
tolusha wants to merge 3 commits intomainfrom
23533
Draft

feat: Mounting resources should not cause workspace restart#1533
tolusha wants to merge 3 commits intomainfrom
23533

Conversation

@tolusha
Copy link
Copy Markdown
Contributor

@tolusha tolusha commented Nov 3, 2025

What does this PR do?

This PR prevents automatic workspace restarts when mounting resources (ConfigMaps, Secrets, PVCs) by introducing a new controller.devfile.io/mount-on-start attribute.

What issues does this PR fix or reference?

eclipse-che/che#23553

Is it tested? How?

  1. Deploy Eclipse Che,
  2. Create a CM and secret, ensure workspace is not restarted
oc apply -f - <<EOF             
apiVersion: v1  
data:
  CM: data
kind: ConfigMap
metadata:
  annotations:
    controller.devfile.io/mount-as: env
    controller.devfile.io/mount-on-start: "true"
  labels:
    controller.devfile.io/mount-to-devworkspace: "true"
    controller.devfile.io/watch-configmap: "true"
  name: test
  namespace: admin-che
---
apiVersion: v1  
stringData:
  secret: data
kind: Secret
metadata:
  annotations:
    controller.devfile.io/mount-as: file
    controller.devfile.io/mount-on-start: "true"
    controller.devfile.io/mount-path: "/tmp/secret"
  labels:
    controller.devfile.io/mount-to-devworkspace: "true"
    controller.devfile.io/watch-secret: "true"
  name: test
  namespace: admin-che
---

EOF
  1. Restart a workspace, ensure that resources are mounted

PR Checklist

  • E2E tests pass (when PR is ready, comment /test v8-devworkspace-operator-e2e, v8-che-happy-path to trigger)
    • v8-devworkspace-operator-e2e: DevWorkspace e2e test
    • v8-che-happy-path: Happy path for verification integration with Che

Summary by CodeRabbit

  • New Features
    • Added support for controlling resource auto-mount timing in workspaces. Secrets, ConfigMaps, and Persistent Volume Claims can now be marked to mount only when the workspace starts, rather than being mounted to already-running workspaces. This enables better resource lifecycle management and provides finer control over when resources become available to your workspace.

@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented Nov 3, 2025

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: tolusha
Once this PR has been reviewed and has the lgtm label, please assign dkwon17 for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Comment thread pkg/provision/automount/gitconfig.go Outdated
@tolusha tolusha changed the title feat: Mouning resources should not cause workspace restart feat: Mounting resources should not cause workspace restart Nov 3, 2025
@tolusha tolusha marked this pull request as draft November 4, 2025 12:20
@tolusha
Copy link
Copy Markdown
Contributor Author

tolusha commented Nov 6, 2025

The main problem here is that even if we mount the resources (marked with special attributes) only when the workspace starts—and not while it’s running—we still need to decide how to handle changes to those resources while the workspace is active.
The crucial question is how we can prevent the workspace from restarting when those resources are modified, since the source object differs from the one in the cluster.

@dkwon17
Copy link
Copy Markdown
Collaborator

dkwon17 commented Nov 7, 2025

I haven't tried, but is it possible to ignore configmaps/secrets that have the controller.devfile.io/mount-on-start-only attribute in automountWatcher to avoid reconciling running workspaces?

Watches(&corev1.Secret{}, handler.EnqueueRequestsFromMapFunc(r.runningWorkspacesHandler), automountWatcher).

@tolusha
Copy link
Copy Markdown
Contributor Author

tolusha commented Nov 12, 2025

It slightly mitigates the problem, but it doesn’t address it completely.

For example:

  1. The object with the controller.devfile.io/mount-on-start-only attribute was changed, and we ignored it.
  2. When a DWOC object changes, it triggers a reconcile. Then we need to build the spec object and compare it with the one in the cluster. Since the objects differ, this causes the workspace to restart.

https://github.com/devfile/devworkspace-operator/blob/main/controllers/workspace/devworkspace_controller.go#L719-L742

@tolusha
Copy link
Copy Markdown
Contributor Author

tolusha commented Nov 12, 2025

There is a solution that I don’t really like, but it could work.
We would need to make copies of the objects marked with the controller.devfile.io/mount-on-start-only attribute that are mounted to the DW.
This way, we would be able to construct a spec object that matches the one in the cluster.

@openshift-merge-robot
Copy link
Copy Markdown

PR needs rebase.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

tolusha added 2 commits April 16, 2026 16:59
Signed-off-by: Anatolii Bazko <abazko@redhat.com>
…tart

Signed-off-by: Anatolii Bazko <abazko@redhat.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 21, 2026

📝 Walkthrough

Walkthrough

Updates workspace automount provisioning to conditionally gate resource mounting based on a new mount-on-start annotation and runtime context (whether workspace is running and current deployment state). The controller now fetches deployment information and threads workspace runtime context through automount resource handlers to filter which resources get mounted.

Changes

Cohort / File(s) Summary
Controller Entry Point
controllers/workspace/devworkspace_controller.go
Computes workspace running state and conditionally fetches cluster Deployment. Passes isWorkspaceRunning and workspaceDeployment to automount provisioning. Updated copyright year to 2019-2026.
Constants & Attributes
pkg/constants/attributes.go
Added new exported constant MountOnStartAttribute with value "controller.devfile.io/mount-on-start" to mark resources that should mount only when workspace starts. Updated copyright year.
Automount Provisioning Core
pkg/provision/automount/common.go
Updated ProvisionAutoMountResourcesInto signature to accept isWorkspaceRunning and workspaceDeployment. Introduced filtering logic via isAllowedToMount and presence-check helpers (isVolumeMountExistsInDeployment, isEnvFromSourceExistsInDeployment) to gate mount-on-start resources based on deployment state.
Automount Resource Handlers
pkg/provision/automount/{configmap,secret,pvcs}.go
Updated getDevWorkspaceConfigmaps, getDevWorkspaceSecrets, and getAutoMountPVCs to accept isWorkspaceRunning and workspaceDeployment parameters. Each handler now filters resources via isAllowedToMount before including them in results.
Git Configuration Provisioning
pkg/provision/automount/{gitconfig,templates}.go
Updated ProvisionGitConfiguration and related helper functions to accept workspace runtime context. Introduced shouldIncludeGitObject logic to conditionally include git credentials and TLS configmaps based on mount-on-start annotations and deployment state. Updated copyright year and imports.
Deployment Helper
pkg/provision/workspace/deployment.go
Added new exported function GetClusterDeployment to fetch the workspace Deployment from the cluster. Returns nil without error if Deployment not found. Updated copyright year to 2019-2026.
Automount Tests
pkg/provision/automount/{common,configmap,secret,pvcs,gitconfig}_test.go, pkg/provision/automount/common_persistenthome_test.go
Updated test calls to match new function signatures with isWorkspaceRunning and workspaceDeployment parameters. Added extensive coverage for mount-on-start behavior: verifying resources are skipped when workspace is running and resource not in deployment, included when not running, and allowed when already present in deployment. Added helper constructors for annotated Secrets/ConfigMaps and test Deployments.

Sequence Diagram

sequenceDiagram
    participant Controller
    participant Automount as Automount<br/>Provisioner
    participant DeploymentFetcher
    participant ResourceHandlers as ConfigMap/<br/>Secret/PVC<br/>Handlers
    participant FilterLogic as Filter &<br/>Presence Check

    Controller->>DeploymentFetcher: GetClusterDeployment(workspace)
    DeploymentFetcher-->>Controller: workspaceDeployment?

    Controller->>Automount: ProvisionAutoMountResourcesInto(...<br/>isWorkspaceRunning, workspaceDeployment)

    Automount->>ResourceHandlers: getDevWorkspaceConfigmaps<br/>(... isWorkspaceRunning, deployment)
    Automount->>ResourceHandlers: getDevWorkspaceSecrets<br/>(... isWorkspaceRunning, deployment)
    Automount->>ResourceHandlers: getAutoMountPVCs<br/>(... isWorkspaceRunning, deployment)

    loop For each resource
        ResourceHandlers->>FilterLogic: isAllowedToMount(resource<br/>isMountOnStart?, hasDeployment?, isRunning?)
        alt Mount-on-start & Running
            FilterLogic->>FilterLogic: Check if volume/env<br/>exists in deployment
            FilterLogic-->>ResourceHandlers: Include if<br/>present in deployment
        else Mount-on-start & Not Running
            FilterLogic-->>ResourceHandlers: Include (will be<br/>mounted on start)
        else Not Mount-on-start
            FilterLogic-->>ResourceHandlers: Always include
        end
        ResourceHandlers-->>Automount: Filtered Resources
    end

    Automount-->>Controller: Provisioned volumes &<br/>volumeMounts
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 Hops with glee through mount-on-start
Deployments checked with careful art,
Resources gated, wisely screened,
Only mounted when they're keen!
Runtime context flows just right,
Automounting, taking flight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.70% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main objective of the changeset: preventing workspace restarts when mounting resources via a new 'mount-on-start' mechanism.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 23533

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@tolusha
Copy link
Copy Markdown
Contributor Author

tolusha commented Apr 21, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 21, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/provision/automount/gitconfig.go (1)

53-76: ⚠️ Potential issue | 🟠 Major

Do not mount empty synthetic git resources after filtering all inputs.

When a first git credential/TLS resource is added with mount-on-start while the workspace is running, the helpers can filter out every input, but lines 63-74 still sync and return the merged Secret/ConfigMap mounts. That changes the Deployment with empty synthetic git config and can restart the workspace. Have the helpers report whether any eligible input was included, and skip returning these synthetic mounts unless they are already present in workspaceDeployment or contain eligible/base config.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/provision/automount/gitconfig.go` around lines 53 - 76, The code
currently always syncs and mounts synthetic git Secret/ConfigMap even when
helpers filtered out all inputs; update mergeGitCredentials and
constructGitConfig (or their callers) to return a boolean indicating whether any
eligible inputs or base config/tls were included, then in this block only call
sync.SyncObjectWithCluster and include the results from
getAutomountSecret/getAutomountConfigmap in flattenAutomountResources if that
boolean is true OR the corresponding resource already exists in
workspaceDeployment or contains non-empty/base config; otherwise skip syncing
and do not return the synthetic mounts. Ensure you reference
mergeGitCredentials, constructGitConfig, sync.SyncObjectWithCluster,
getAutomountSecret, getAutomountConfigmap and workspaceDeployment when
implementing the conditional logic.
🧹 Nitpick comments (3)
pkg/provision/automount/common.go (1)

412-422: Nit: loop variables are pluralized but represent single items.

automountVolumes/deploymentVolumes are singular elements produced by ranging over slices. Renaming improves readability.

Proposed rename
-func isVolumeMountExistsInDeployment(automountResource Resources, workspaceDeployment *appsv1.Deployment) bool {
-	for _, automountVolumes := range automountResource.Volumes {
-		for _, deploymentVolumes := range workspaceDeployment.Spec.Template.Spec.Volumes {
-			if automountVolumes.Name == deploymentVolumes.Name {
+func isVolumeMountExistsInDeployment(automountResource Resources, workspaceDeployment *appsv1.Deployment) bool {
+	for _, automountVolume := range automountResource.Volumes {
+		for _, deploymentVolume := range workspaceDeployment.Spec.Template.Spec.Volumes {
+			if automountVolume.Name == deploymentVolume.Name {
 				return true
 			}
 		}
 	}
 	return false
 }

Also, function names like isVolumeMountExistsInDeployment / isEnvFromSourceExistsInDeployment read awkwardly — consider volumeExistsInDeployment / envFromSourceExistsInDeployment.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/provision/automount/common.go` around lines 412 - 422, Rename the
pluralized loop variables to singulars and consider clearer function names: in
isVolumeMountExistsInDeployment change automountVolumes -> automountVolume and
deploymentVolumes -> deploymentVolume; similarly rename variables in
isEnvFromSourceExistsInDeployment if present. Also consider renaming the
functions to volumeExistsInDeployment and envFromSourceExistsInDeployment
(update all call sites) to improve readability while preserving behavior.
pkg/provision/automount/templates.go (1)

96-98: Vacuous-truth and nesting readability — small simplification possible.

!slices.ContainsFunc(xs, func(x) bool { return !p(x) }) reads as a double negation of "all satisfy p". It also returns true for an empty slice, which is fine here only because the loop below then doesn't iterate. Consider using a helper or an explicit all-loop for clarity, especially since the same pattern is repeated in mergeGitCredentials (Line 159-161):

Optional readability tweak
allConfigMapsMountOnStart := len(certificatesConfigMaps) > 0
for i := range certificatesConfigMaps {
    if !isMountOnStart(&certificatesConfigMaps[i]) {
        allConfigMapsMountOnStart = false
        break
    }
}

or, if you prefer keeping slices:

allConfigMapsMountOnStart := len(certificatesConfigMaps) > 0 &&
    !slices.ContainsFunc(certificatesConfigMaps, func(cm corev1.ConfigMap) bool {
        return !isMountOnStart(&cm)
    })

Not blocking — the behavior is correct today because empty slices short-circuit via the surrounding loop.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/provision/automount/templates.go` around lines 96 - 98, Replace the
double-negation slices.ContainsFunc pattern used to compute
allConfigMapsMountOnStart with a clearer "all" check: iterate
certificatesConfigMaps (or use len(certificatesConfigMaps) > 0 && ...) and set
allConfigMapsMountOnStart to false on the first element for which
isMountOnStart(&cm) is false; apply the same clearer pattern in the
mergeGitCredentials block where the identical slices.ContainsFunc(...) negation
is used so the logic and empty-slice semantics remain explicit and readable.
pkg/provision/automount/common_test.go (1)

413-710: Duplicate test coverage — three pairs assert the exact same scenario.

These pairs pass identical arguments (false, true, emptyDeployment()) against the same fake object and assert identical outcomes:

  • TestShouldNotMountSecretWithMountOnStarIfWorkspaceStarted (Line 413) ↔ TestShouldNotMountSecretWithMountOnStartWhenRunningAndNotInDeployment (Line 612)
  • TestShouldNotMountConfigMapWithMountOnStartIfWorkspaceStarted (Line 452) ↔ TestShouldNotMountConfigMapWithMountOnStartWhenRunningAndNotInDeployment (Line 530)
  • TestShouldNotMountPVCWithMountOnStartIfWorkspaceStarted (Line 491) ↔ TestShouldNotMountPVCWithMountOnStartWhenRunningAndNotInDeployment (Line 694)

Recommend collapsing each pair into a single test (or making one of them genuinely test a different state, e.g. isWorkspaceRunning=true with workspaceDeployment=nil, which currently has no coverage and is the ambiguous case discussed in common.go).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/provision/automount/common_test.go` around lines 413 - 710, Duplicate
tests cover the same inputs and assertions: collapse each pair into one test
(e.g., remove either TestShouldNotMountSecretWithMountOnStarIfWorkspaceStarted
or TestShouldNotMountSecretWithMountOnStartWhenRunningAndNotInDeployment, same
for the ConfigMap and PVC pairs) so you only call
ProvisionAutoMountResourcesInto once per scenario; alternatively change one test
of each pair to exercise the ambiguous case described in common.go by calling
ProvisionAutoMountResourcesInto(testPodAdditions, testAPI, testNamespace, false,
true, nil) (i.e., isWorkspaceStarted/isWorkspaceRunning=true with
workspaceDeployment=nil) and adjust assertions accordingly; update or remove
redundant test helper usage (mountOnStartSecretAsFile,
mountOnStartConfigMapAsFile, mountOnStartPVC) so each remaining test uniquely
covers either the "workspace started" or the "running and not in deployment"
scenario.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@controllers/workspace/devworkspace_controller.go`:
- Around line 459-467: The current branch around isWorkspaceRunning is inverted:
it only calls wsprovision.GetClusterDeployment when the workspace is NOT
running, leaving workspaceDeployment nil for running workspaces and causing
automount/isAllowedToMount to allow unsafe mounts. Change the condition to fetch
the existing deployment when isWorkspaceRunning is true by calling
wsprovision.GetClusterDeployment(workspace, clusterAPI) and assigning
workspaceDeployment (and returning errors as before) so
automount/isAllowedToMount receives the actual deployment for running
workspaces.

In `@pkg/constants/attributes.go`:
- Around line 175-179: The exported annotation constant MountOnStartAttribute
currently uses "controller.devfile.io/mount-on-start" but the PR and docs expect
"controller.devfile.io/mount-on-start-only"; update the value of
MountOnStartAttribute to "controller.devfile.io/mount-on-start-only" and then
search/replace all usages (tests, docs, and any code references) to use
MountOnStartAttribute so the public API key is consistent across code, tests,
and documentation.

In `@pkg/provision/automount/common_test.go`:
- Line 413: Rename the test function
TestShouldNotMountSecretWithMountOnStarIfWorkspaceStarted to correct the typo
(MountOnStart) so the function name reads
TestShouldNotMountSecretWithMountOnStartIfWorkspaceStarted; update any
references or subtests that call or document this function name to match the
corrected identifier (e.g., in package tests, test runners, or comments) to
ensure compilation and clarity.
- Around line 712-739: The test constructs a Deployment volume using the raw
string "test-pvc" but the production helper common.AutoMountPVCVolumeName(...)
is used to name volumes; update the test to call common.AutoMountPVCVolumeName
on the PVC name when creating the deployment volume and in the final assertion
so the test uses the same naming logic as ProvisionAutoMountResourcesInto and
getAutoMountPVCs; locate the volume creation in
TestMountOnStartPVCAllowedWhenVolumeExistsInDeployment and replace the literal
"test-pvc" with common.AutoMountPVCVolumeName("test-pvc") and also assert
equality against common.AutoMountPVCVolumeName("test-pvc") in the assert.Equal
call.

In `@pkg/provision/automount/common.go`:
- Around line 408-422: The current name-only check in
isVolumeMountExistsInDeployment can miss "shape changes" (e.g., ConfigMap
switched from file volume to envFrom) causing the new representation to be
ignored; update the reconciliation checks so that when a resource name matches
an existing deployment volume but the new automount Resources describe it as an
EnvFrom (or vice versa) we detect the mismatch and treat it as an
existing-but-changed resource that requires a restart/reconcile. Concretely,
augment the logic around isVolumeMountExistsInDeployment and
isEnvFromSourceExistsInDeployment (or the higher-level existsInDeployment /
isAllowedToMount flow) to: 1) detect same underlying resource name present in
deployment volumes but absent as a volume in automount.Resources (and check
container.EnvFrom entries for the same name), 2) return a sentinel
"shape-changed" result or treat it as exists so the controller triggers the
restart/reconcile, and 3) add a unit test covering the transition from
mount-as:file → mount-as:env (and vice versa) to ensure the change is not
silently ignored.
- Around line 378-401: The gating logic in isAllowedToMount is inverted: when
the workspace is running we must check the existing deployment, but the code
currently does the opposite; update the conditional so that the branch that
calls existsInDeployment(automountResource, workspaceDeployment) runs only when
isWorkspaceRunning is true (i.e., change the check around isWorkspaceRunning),
ensuring isMountOnStart is respected for running workspaces and
workspaceDeployment is used to gate mounts.

In `@pkg/provision/automount/configmap.go`:
- Around line 62-67: When a running workspace has an existing mount-on-start
ConfigMap, the current logic builds a new shape via getAutomountConfigmap(...)
and then drops it if isAllowedToMount(...) can't find an exact match, causing
the old mount to be removed and triggering a rollout; instead, detect that
workspaceDeployment already contains the mounted resource and preserve its
existing volume/mount/envFrom into the desired spec: if isAllowedToMount(...)
fails for a mount-on-start resource while isWorkspaceRunning is true, copy the
cluster-side resource (volume, volumeMount, and envFrom entries) from
workspaceDeployment into the automountCM entry added to allAutoMountResources
(or change getAutomountConfigmap to return the preserved cluster-side resource),
and apply the same preservation pattern for Secret and PVC automount paths so
in-place shape changes don’t drop existing mounts.

In `@pkg/provision/automount/gitconfig_test.go`:
- Around line 407-434: The test
TestMountGitCredentialWhenMixedMountOnStartSecrets asserts behavior that
contradicts the comment on shouldIncludeGitObject; either document the contract
or change logic—here, add a clarifying comment inside
TestMountGitCredentialWhenMixedMountOnStartSecrets stating that
ProvisionGitConfiguration will allow mount-on-start secrets through when any
sibling secret lacks the mount-on-start annotation (per shouldIncludeGitObject
in templates.go), and that this is an intentional tradeoff (only
fully-mount-on-start sets are gated), so the test expects 2 volumes/2 mounts for
the mixed case; reference shouldIncludeGitObject and ProvisionGitConfiguration
in the comment for future readers.
- Around line 224-251: The test initializes sync.ClusterAPI without setting
ClusterAPI.Ctx, leaving it nil and diverging from production; set ClusterAPI.Ctx
to a real context (e.g., context.Background() or context.TODO()) in the test
setup where ClusterAPI is constructed so getGitResources() and
sync.SyncObjectWithCluster() receive a non-nil context; update the ClusterAPI
construction in this test (and the other tests noted) so clusterAPI.Ctx is
assigned before calling ProvisionGitConfiguration or any API client operations.

In `@pkg/provision/automount/templates.go`:
- Around line 183-201: The current shouldIncludeGitObject logic short-circuits
on !allGitObjectsMountOnStart causing mount-on-start objects to be included
whenever any sibling is non-mount-on-start; fix by making that branch also
require the merged volume to already be present (i.e., require
workspaceDeployment != nil and/or isVolumeMountExistsInDeployment(...) to be
true) so a global "some sibling is non-mount-on-start" does not alone permit
inclusion, or alternatively update the comment to state the true behaviour;
change the condition involving allGitObjectsMountOnStart so it reads like
"!allGitObjectsMountOnStart && (workspaceDeployment != nil ||
isVolumeMountExistsInDeployment(automountMergedResource, workspaceDeployment))"
(or equivalent) and keep isMountOnStart, allGitObjectsMountOnStart,
workspaceDeployment, and isVolumeMountExistsInDeployment as the referenced
symbols.

---

Outside diff comments:
In `@pkg/provision/automount/gitconfig.go`:
- Around line 53-76: The code currently always syncs and mounts synthetic git
Secret/ConfigMap even when helpers filtered out all inputs; update
mergeGitCredentials and constructGitConfig (or their callers) to return a
boolean indicating whether any eligible inputs or base config/tls were included,
then in this block only call sync.SyncObjectWithCluster and include the results
from getAutomountSecret/getAutomountConfigmap in flattenAutomountResources if
that boolean is true OR the corresponding resource already exists in
workspaceDeployment or contains non-empty/base config; otherwise skip syncing
and do not return the synthetic mounts. Ensure you reference
mergeGitCredentials, constructGitConfig, sync.SyncObjectWithCluster,
getAutomountSecret, getAutomountConfigmap and workspaceDeployment when
implementing the conditional logic.

---

Nitpick comments:
In `@pkg/provision/automount/common_test.go`:
- Around line 413-710: Duplicate tests cover the same inputs and assertions:
collapse each pair into one test (e.g., remove either
TestShouldNotMountSecretWithMountOnStarIfWorkspaceStarted or
TestShouldNotMountSecretWithMountOnStartWhenRunningAndNotInDeployment, same for
the ConfigMap and PVC pairs) so you only call ProvisionAutoMountResourcesInto
once per scenario; alternatively change one test of each pair to exercise the
ambiguous case described in common.go by calling
ProvisionAutoMountResourcesInto(testPodAdditions, testAPI, testNamespace, false,
true, nil) (i.e., isWorkspaceStarted/isWorkspaceRunning=true with
workspaceDeployment=nil) and adjust assertions accordingly; update or remove
redundant test helper usage (mountOnStartSecretAsFile,
mountOnStartConfigMapAsFile, mountOnStartPVC) so each remaining test uniquely
covers either the "workspace started" or the "running and not in deployment"
scenario.

In `@pkg/provision/automount/common.go`:
- Around line 412-422: Rename the pluralized loop variables to singulars and
consider clearer function names: in isVolumeMountExistsInDeployment change
automountVolumes -> automountVolume and deploymentVolumes -> deploymentVolume;
similarly rename variables in isEnvFromSourceExistsInDeployment if present. Also
consider renaming the functions to volumeExistsInDeployment and
envFromSourceExistsInDeployment (update all call sites) to improve readability
while preserving behavior.

In `@pkg/provision/automount/templates.go`:
- Around line 96-98: Replace the double-negation slices.ContainsFunc pattern
used to compute allConfigMapsMountOnStart with a clearer "all" check: iterate
certificatesConfigMaps (or use len(certificatesConfigMaps) > 0 && ...) and set
allConfigMapsMountOnStart to false on the first element for which
isMountOnStart(&cm) is false; apply the same clearer pattern in the
mergeGitCredentials block where the identical slices.ContainsFunc(...) negation
is used so the logic and empty-slice semantics remain explicit and readable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bb85f151-8a4c-494e-833d-a35807facca0

📥 Commits

Reviewing files that changed from the base of the PR and between 943ae8e and fdc4426.

📒 Files selected for processing (12)
  • controllers/workspace/devworkspace_controller.go
  • pkg/constants/attributes.go
  • pkg/provision/automount/common.go
  • pkg/provision/automount/common_persistenthome_test.go
  • pkg/provision/automount/common_test.go
  • pkg/provision/automount/configmap.go
  • pkg/provision/automount/gitconfig.go
  • pkg/provision/automount/gitconfig_test.go
  • pkg/provision/automount/pvcs.go
  • pkg/provision/automount/secret.go
  • pkg/provision/automount/templates.go
  • pkg/provision/workspace/deployment.go

Comment thread controllers/workspace/devworkspace_controller.go
Comment thread pkg/constants/attributes.go
Comment thread pkg/provision/automount/common_test.go Outdated
Comment thread pkg/provision/automount/common_test.go
Comment thread pkg/provision/automount/common.go
Comment thread pkg/provision/automount/configmap.go
Comment thread pkg/provision/automount/gitconfig_test.go
Comment thread pkg/provision/automount/gitconfig_test.go
Comment thread pkg/provision/automount/templates.go
Comment thread pkg/provision/automount/templates.go
Signed-off-by: Anatolii Bazko <abazko@redhat.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 21, 2026

Codecov Report

❌ Patch coverage is 87.42138% with 20 lines in your changes missing coverage. Please review.
✅ Project coverage is 36.59%. Comparing base (b3e2af5) to head (05515fc).
⚠️ Report is 28 commits behind head on main.

Files with missing lines Patch % Lines
pkg/provision/workspace/deployment.go 0.00% 11 Missing ⚠️
pkg/provision/automount/common.go 87.23% 4 Missing and 2 partials ⚠️
controllers/workspace/devworkspace_controller.go 72.72% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1533      +/-   ##
==========================================
+ Coverage   35.48%   36.59%   +1.11%     
==========================================
  Files         168      168              
  Lines       14484    14671     +187     
==========================================
+ Hits         5139     5369     +230     
+ Misses       9006     8953      -53     
- Partials      339      349      +10     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants