Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions pkg/devcontainer/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ func (r *runner) buildImage(
parsedConfig := params.parsedConfig
options := params.options

targetArch, err := r.Driver.TargetArchitecture(ctx, r.ID)
targetArch, err := r.driver.TargetArchitecture(ctx, r.id)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -471,7 +471,7 @@ func (r *runner) executeBuild(
ExtendedBuildInfo: params.extendedBuildInfo,
DockerfilePath: params.dockerfilePath,
DockerfileContent: params.dockerfileContent,
LocalWorkspaceFolder: r.LocalWorkspaceFolder,
LocalWorkspaceFolder: r.localWorkspaceFolder,
Options: options,
TargetArch: targetArch,
})
Expand All @@ -484,16 +484,16 @@ func (r *runner) executeBuild(

// check if we should fallback to dockerless.
// This should only be OSS kubernetes as of March 06, 2025.
dockerDriver, ok := r.Driver.(driver.DockerDriver)
dockerDriver, ok := r.driver.(driver.DockerDriver)
if options.ForceDockerless || !ok {
if r.WorkspaceConfig.Agent.Dockerless.Disabled == pkgconfig.BoolTrue {
if r.workspaceConfig.Agent.Dockerless.Disabled == pkgconfig.BoolTrue {
return nil, fmt.Errorf(
"cannot build devcontainer because driver is non-docker and dockerless fallback is disabled",
)
}

return dockerlessFallback(&dockerlessFallbackParams{
localWorkspaceFolder: r.LocalWorkspaceFolder,
localWorkspaceFolder: r.localWorkspaceFolder,
containerWorkspaceFolder: params.substitutionContext.ContainerWorkspaceFolder,
parsedConfig: params.parsedConfig,
buildInfo: params.buildInfo,
Expand All @@ -509,7 +509,7 @@ func (r *runner) executeBuild(
ExtendedBuildInfo: params.extendedBuildInfo,
DockerfilePath: params.dockerfilePath,
DockerfileContent: params.dockerfileContent,
LocalWorkspaceFolder: r.LocalWorkspaceFolder,
LocalWorkspaceFolder: r.localWorkspaceFolder,
Options: options,
})
}
Expand Down
20 changes: 10 additions & 10 deletions pkg/devcontainer/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ type composeUpParams struct {
}

func (r *runner) composeHelper() (*compose.ComposeHelper, error) {
dockerDriver, ok := r.Driver.(driver.DockerDriver)
dockerDriver, ok := r.driver.(driver.DockerDriver)
if !ok {
return nil, fmt.Errorf(
"docker compose is not supported by this provider, choose a different one",
Expand All @@ -112,7 +112,7 @@ func (r *runner) stopDockerCompose(ctx context.Context, projectName string) erro
return fmt.Errorf("find docker compose: %w", err)
}

parsedConfig, _, err := r.getSubstitutedConfig(r.WorkspaceConfig.CLIOptions)
parsedConfig, _, err := r.getSubstitutedConfig(r.workspaceConfig.CLIOptions)
if err != nil {
return fmt.Errorf("get parsed config: %w", err)
}
Expand Down Expand Up @@ -140,7 +140,7 @@ func (r *runner) deleteDockerCompose(
return fmt.Errorf("find docker compose: %w", err)
}

parsedConfig, _, err := r.getSubstitutedConfig(r.WorkspaceConfig.CLIOptions)
parsedConfig, _, err := r.getSubstitutedConfig(r.workspaceConfig.CLIOptions)
if err != nil {
return fmt.Errorf("get parsed config: %w", err)
}
Expand Down Expand Up @@ -235,7 +235,7 @@ func (r *runner) loadComposeProject(
if err != nil {
return nil, fmt.Errorf("load docker compose project: %w", err)
}
project.Name = composeHelper.GetProjectName(r.ID)
project.Name = composeHelper.GetProjectName(r.id)
log.Debugf("Loaded project %s", project.Name)

if err := validateRunServices(parsedConfig.Config.RunServices, project); err != nil {
Expand Down Expand Up @@ -375,15 +375,15 @@ func (r *runner) updateContainerUserUID(
ctx context.Context,
parsedConfig *config.DevContainerConfig,
) error {
dockerDriver, ok := r.Driver.(driver.DockerDriver)
dockerDriver, ok := r.driver.(driver.DockerDriver)
if !ok {
return nil
}
writer := log.Writer(log.LevelInfo)
defer func() { _ = writer.Close() }()
if err := dockerDriver.UpdateContainerUserUID(
ctx,
r.ID,
r.id,
parsedConfig,
writer,
); err != nil {
Expand Down Expand Up @@ -604,7 +604,7 @@ func composeFileFromEnv(envFiles []string) (string, error) {

func (r *runner) getEnvFiles() []string {
var envFiles []string
envFile := path.Join(r.LocalWorkspaceFolder, ".env")
envFile := path.Join(r.localWorkspaceFolder, ".env")
envFileStat, err := os.Stat(envFile)
if err == nil && envFileStat.Mode().IsRegular() {
envFiles = append(envFiles, envFile)
Expand Down Expand Up @@ -873,11 +873,11 @@ func (r *runner) recreateDevContainer(
) error {
log.Debugf("Deleting dev container %s due to --recreate", container.ID)

if err := r.Driver.StopDevContainer(ctx, r.ID); err != nil {
if err := r.driver.StopDevContainer(ctx, r.id); err != nil {
return fmt.Errorf("stop dev container: %w", err)
}

if err := r.Driver.DeleteDevContainer(ctx, r.ID); err != nil {
if err := r.driver.DeleteDevContainer(ctx, r.id); err != nil {
return fmt.Errorf("delete dev container: %w", err)
}
return nil
Expand Down Expand Up @@ -954,7 +954,7 @@ func getDockerComposeFolder(workspaceOriginFolder string) string {
// docker-compose folder using a collision-safe unique name that retains the
// given prefix (so checkForPersistedFile can still match it by prefix).
func (r *runner) writeComposeOverrideFile(prefix string, data []byte) (string, error) {
dockerComposeFolder := getDockerComposeFolder(r.WorkspaceConfig.Origin)
dockerComposeFolder := getDockerComposeFolder(r.workspaceConfig.Origin)
if err := os.MkdirAll(dockerComposeFolder, 0o750); err != nil {
return "", err
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/devcontainer/compose_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ func TestEscapeComposeLabelValueRoundTrip(t *testing.T) {
func TestBuildServiceLabels(t *testing.T) {
t.Run("uses default ID label when no ID labels", func(t *testing.T) {
r := &runner{}
r.ID = "workspace-id"
r.id = "workspace-id"

labels := r.buildServiceLabels(nil)

Expand All @@ -567,7 +567,7 @@ func TestBuildServiceLabels(t *testing.T) {

t.Run("escapes dollars but preserves other characters", func(t *testing.T) {
r := &runner{}
r.IDLabels = []string{"id.label=$value"}
r.idLabels = []string{"id.label=$value"}

labels := r.buildServiceLabels(map[string]string{"extra": "it's $here"})

Expand All @@ -582,7 +582,7 @@ func TestBuildServiceLabels(t *testing.T) {

t.Run("splits ID label only on first equals sign", func(t *testing.T) {
r := &runner{}
r.IDLabels = []string{"id.label=a=b=c"}
r.idLabels = []string{"id.label=a=b=c"}

labels := r.buildServiceLabels(nil)

Expand All @@ -593,7 +593,7 @@ func TestBuildServiceLabels(t *testing.T) {

t.Run("additional labels merge alongside ID labels", func(t *testing.T) {
r := &runner{}
r.IDLabels = []string{"id.label=v"}
r.idLabels = []string{"id.label=v"}

labels := r.buildServiceLabels(map[string]string{"k": "plain"})

Expand Down
8 changes: 4 additions & 4 deletions pkg/devcontainer/compose_up.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,13 @@ exec "$$@"
// are merged in. All values are escaped to prevent compose variable expansion.
func (r *runner) buildServiceLabels(additionalLabels map[string]string) composetypes.Labels {
labels := composetypes.Labels{}
if len(r.IDLabels) > 0 {
for _, l := range r.IDLabels {
if len(r.idLabels) > 0 {
for _, l := range r.idLabels {
k, v, _ := strings.Cut(l, "=")
labels[k] = escapeComposeLabelValue(v)
}
} else {
labels[pkgconfig.DevcontainerIDLabel] = r.ID
labels[pkgconfig.DevcontainerIDLabel] = r.id
}
for k, v := range additionalLabels {
labels.Add(k, escapeComposeLabelValue(v))
Expand Down Expand Up @@ -189,7 +189,7 @@ func namedVolumesFromMounts(mounts []*config.Mount) map[string]composetypes.Volu
}

func (r *runner) resolveComposeGPUAvailability(composeHelper *compose.ComposeHelper) bool {
switch r.WorkspaceConfig.CLIOptions.GPUAvailability {
switch r.workspaceConfig.CLIOptions.GPUAvailability {
case stringTrue:
return true
case stringFalse:
Expand Down
34 changes: 17 additions & 17 deletions pkg/devcontainer/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@ func (r *runner) getRawConfig(options provider.CLIOptions) (*config.DevContainer
// rawConfigFromWorkspace returns the config embedded in the workspace metadata,
// or nil when none is present.
func (r *runner) rawConfigFromWorkspace() *config.DevContainerConfig {
if r.WorkspaceConfig.Workspace.DevContainerConfig == nil {
if r.workspaceConfig.Workspace.DevContainerConfig == nil {
return nil
}

rawConfig := config.CloneDevContainerConfig(r.WorkspaceConfig.Workspace.DevContainerConfig)
if devContainerPath := r.WorkspaceConfig.Workspace.DevContainerPath; devContainerPath != "" {
rawConfig.Origin = path.Join(filepath.ToSlash(r.LocalWorkspaceFolder), devContainerPath)
rawConfig := config.CloneDevContainerConfig(r.workspaceConfig.Workspace.DevContainerConfig)
if devContainerPath := r.workspaceConfig.Workspace.DevContainerPath; devContainerPath != "" {
rawConfig.Origin = path.Join(filepath.ToSlash(r.localWorkspaceFolder), devContainerPath)
} else {
rawConfig.Origin = path.Join(
filepath.ToSlash(r.LocalWorkspaceFolder),
filepath.ToSlash(r.localWorkspaceFolder),
".devcontainer."+pkgconfig.BinaryName+".json",
)
}
Expand All @@ -56,7 +56,7 @@ func (r *runner) rawConfigFromWorkspace() *config.DevContainerConfig {
// rawConfigFromContainer returns a synthetic config for a running-container
// source, or nil when the source is not a container.
func (r *runner) rawConfigFromContainer() *config.DevContainerConfig {
containerID := r.WorkspaceConfig.Workspace.Source.Container
containerID := r.workspaceConfig.Workspace.Source.Container
if containerID == "" {
return nil
}
Expand All @@ -75,14 +75,14 @@ func (r *runner) rawConfigFromContainer() *config.DevContainerConfig {
func (r *runner) rawConfigFromCrane(
options provider.CLIOptions,
) (*config.DevContainerConfig, error) {
localWorkspaceFolder, err := crane.PullConfigFromSource(r.WorkspaceConfig, &options)
localWorkspaceFolder, err := crane.PullConfigFromSource(r.workspaceConfig, &options)
if err != nil {
return nil, err
}
return config.ParseDevContainerJSON(
context.Background(),
localWorkspaceFolder,
r.WorkspaceConfig.Workspace.DevContainerPath,
r.workspaceConfig.Workspace.DevContainerPath,
)
}

Expand All @@ -91,8 +91,8 @@ func (r *runner) rawConfigFromCrane(
func (r *runner) rawConfigFromFilesystem(
options provider.CLIOptions,
) (*config.DevContainerConfig, error) {
localWorkspaceFolder := r.LocalWorkspaceFolder
if subPath := r.WorkspaceConfig.Workspace.Source.GitSubPath; subPath != "" {
localWorkspaceFolder := r.localWorkspaceFolder
if subPath := r.workspaceConfig.Workspace.Source.GitSubPath; subPath != "" {
localWorkspaceFolder = filepath.Join(localWorkspaceFolder, subPath)
}

Expand All @@ -109,7 +109,7 @@ func (r *runner) rawConfigFromFilesystem(
rawConfig, err := config.ParseDevContainerJSONWithOptions(
context.Background(),
localWorkspaceFolder,
r.WorkspaceConfig.Workspace.DevContainerPath,
r.workspaceConfig.Workspace.DevContainerPath,
opts,
)
// A missing devcontainer.json is not an error: fall back to auto-detection.
Expand Down Expand Up @@ -160,10 +160,10 @@ func (r *runner) getDefaultConfig(
defaultConfig.ImageContainer = config.ImageContainer{Image: options.FallbackImage}
} else {
log.Infof("Try detecting project programming language")
defaultConfig = language.DefaultConfig(r.LocalWorkspaceFolder)
defaultConfig = language.DefaultConfig(r.localWorkspaceFolder)
}

defaultConfig.Origin = path.Join(filepath.ToSlash(r.LocalWorkspaceFolder), ".devcontainer.json")
defaultConfig.Origin = path.Join(filepath.ToSlash(r.localWorkspaceFolder), ".devcontainer.json")
if err := config.SaveDevContainerJSON(defaultConfig); err != nil {
return nil, fmt.Errorf("write default devcontainer.json: %w", err)
}
Expand Down Expand Up @@ -214,8 +214,8 @@ func (r *runner) buildSubstitutionContext(
) *config.SubstitutionContext {
configFile := rawParsedConfig.Origin
workspaceMount, containerWorkspaceFolder := getWorkspace(
r.LocalWorkspaceFolder,
r.WorkspaceConfig.Workspace.ID,
r.localWorkspaceFolder,
r.workspaceConfig.Workspace.ID,
rawParsedConfig,
)

Expand All @@ -225,8 +225,8 @@ func (r *runner) buildSubstitutionContext(
}

return &config.SubstitutionContext{
DevContainerID: config.DeriveDevContainerID(r.LocalWorkspaceFolder, configFile),
LocalWorkspaceFolder: r.LocalWorkspaceFolder,
DevContainerID: config.DeriveDevContainerID(r.localWorkspaceFolder, configFile),
LocalWorkspaceFolder: r.localWorkspaceFolder,
ContainerWorkspaceFolder: containerWorkspaceFolder,
Env: env,
WorkspaceMount: workspaceMount,
Expand Down
14 changes: 8 additions & 6 deletions pkg/devcontainer/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"github.com/stretchr/testify/suite"
)

const testWorkspaceFolder = "/workspace"

type SubstituteTestSuite struct {
suite.Suite
runner *runner
Expand All @@ -20,9 +22,9 @@ func TestSubstituteTestSuite(t *testing.T) {

func (s *SubstituteTestSuite) SetupTest() {
s.runner = &runner{
ID: "test-id",
LocalWorkspaceFolder: "/workspace",
WorkspaceConfig: &provider2.AgentWorkspaceInfo{
id: "test-id",
localWorkspaceFolder: testWorkspaceFolder,
workspaceConfig: &provider2.AgentWorkspaceInfo{
Workspace: &provider2.Workspace{
ID: "test-workspace",
},
Expand Down Expand Up @@ -377,7 +379,7 @@ func TestWorkspaceMountFolderWarning(t *testing.T) {
name: "both set",
conf: &config.DevContainerConfig{
DevContainerConfigBase: config.DevContainerConfigBase{
WorkspaceFolder: "/workspace",
WorkspaceFolder: testWorkspaceFolder,
},
NonComposeBase: config.NonComposeBase{WorkspaceMount: new("source=v")},
},
Expand All @@ -394,7 +396,7 @@ func TestWorkspaceMountFolderWarning(t *testing.T) {
name: "folder without mount",
conf: &config.DevContainerConfig{
DevContainerConfigBase: config.DevContainerConfigBase{
WorkspaceFolder: "/workspace",
WorkspaceFolder: testWorkspaceFolder,
},
},
wantMsg: true,
Expand All @@ -403,7 +405,7 @@ func TestWorkspaceMountFolderWarning(t *testing.T) {
name: "empty-string mount satisfies the pairing",
conf: &config.DevContainerConfig{
DevContainerConfigBase: config.DevContainerConfigBase{
WorkspaceFolder: "/workspace",
WorkspaceFolder: testWorkspaceFolder,
},
NonComposeBase: config.NonComposeBase{WorkspaceMount: new("")},
},
Expand Down
Loading
Loading