Skip to content

Let containers inherit a workspace #13054

@shykes

Description

@shykes

Let container commands inherit a workspace

Problem

When a command runs inside a Dagger container and opens its own Dagger connection, the inner client detects its workspace from the container filesystem.

That is often the wrong workspace.

For example, consider a Go test suite for a Helm chart. The tests use the Dagger SDK to read chart files from the current workspace:

chart := dag.CurrentWorkspace().
    Directory(".", dagger.WorkspaceDirectoryOpts{Include: []string{chartPath}}).
    Directory(chartPath)

If an outer Dagger call runs that suite with:

testCtr.WithExec([]string{"go", "test", "./e2e/helm"})

then go test runs inside testCtr. When the test calls dagger.Connect(), it creates a nested Dagger client from inside that container.

Today, that client sees only the files available in testCtr. It does not see the caller's workspace.

Proposed Solution

Add an optional inheritWorkspace argument to container command surfaces that can open nested Dagger clients:

extend type Container {
  withExec(
    # ...
    """
    Default workspace for nested Dagger clients.
    """
    inheritWorkspace: WorkspaceID
  ): Container!

  asService(
    # ...
    """
    Default workspace for nested Dagger clients.
    """
    inheritWorkspace: WorkspaceID
  ): Service!

  terminal(
    # ...
    """
    Default workspace for nested Dagger clients.
    """
    inheritWorkspace: WorkspaceID
  ): Container!
}

Go usage:

testCtr.WithExec(
    []string{"go", "test", "./e2e/helm"},
    dagger.ContainerWithExecOpts{
        InheritWorkspace: dag.CurrentWorkspace(),
    },
)

inheritWorkspace is a command-scoped default. It is stronger than filesystem detection, but weaker than explicit workspace selection by the inner client.

New binding order:

inner client's declared workspace string
> command-provided inheritWorkspace
> inner client's own filesystem detection
> ordinary parent inheritance

If the inner client uses -W, --workspace, or SDK WithWorkspace, that wins.

Passing inheritWorkspace should enable the same nested Dagger access as experimentalPrivilegedNesting; passing both remains valid but redundant.

Expected behavior:

- withExec, asService, and terminal accept an optional inherited workspace.
- Inner clients use explicit -W/--workspace/WithWorkspace over inheritWorkspace.
- Inner clients use inheritWorkspace over container filesystem detection.
- Behavior is unchanged when inheritWorkspace is unset.
- Go tests running inside withExec can call dag.CurrentWorkspace() and resolve the caller workspace.
- Workspace module loading uses the inherited workspace when requested.

This intentionally grants the nested client access to the caller-selected workspace object. The capability should be scoped to the command/service/terminal execution metadata, not ambient engine state.

Implementation Notes

Nested exec clients already have parent links. The current issue is priority: non-module clients set pendingWorkspaceLoad = true, so they detect from their own filesystem before ordinary parent inheritance.

Implement this by threading an encoded inherited workspace ID through exec metadata and nested client initialization, then checking it in workspace binding after declared client metadata and before host detection.

For asService and terminal, carry the workspace through the existing metadata path used for nested-client setup. Preserve it across withExec(...).asService() and terminal exec-error paths.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions