Skip to content
Open
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
5 changes: 4 additions & 1 deletion devcontainer/devcontainer.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/moby/buildkit/frontend/dockerfile/instructions"
"github.com/moby/buildkit/frontend/dockerfile/linter"
"github.com/moby/buildkit/frontend/dockerfile/parser"
"github.com/moby/buildkit/frontend/dockerfile/shell"
"github.com/tailscale/hujson"
Expand Down Expand Up @@ -355,7 +356,9 @@ func UserFromDockerfile(dockerfileContent string, buildArgs map[string]string) (
currentStage *instructions.Stage
)
for _, child := range res.AST.Children {
inst, err := instructions.ParseInstruction(child)
// ParseInstruction uses a nil linter, which panics when buildkit applies
// a "# check=" comment to it.
inst, err := instructions.ParseInstructionWithLinter(child, linter.New(&linter.Config{}))
if err != nil {
return "", fmt.Errorf("parse instruction: %w", err)
}
Expand Down
23 changes: 23 additions & 0 deletions devcontainer/devcontainer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,29 @@ func TestUserFromDockerfile_BuildArgs(t *testing.T) {
require.NoError(t, err)
require.Equal(t, "testuser", user)
})

t.Run("LintCheckComment", func(t *testing.T) {
t.Parallel()
registry := registrytest.New(t)
image, err := partial.UncompressedToImage(emptyImage{configFile: &v1.ConfigFile{
Config: v1.Config{
User: "testuser",
},
}})
require.NoError(t, err)
ref := strings.TrimPrefix(registry, "http://") + "/coder/test:latest"
parsed, err := name.ParseReference(ref)
require.NoError(t, err)
err = remote.Write(parsed, image)
require.NoError(t, err)

// buildkit applies "# check=" comments to the linter of the next
// instruction, which panics without an initialized linter.
content := fmt.Sprintf("# syntax note\n# check=skip=JSONArgsRecommended\nFROM %s\n# check=error=true\nRUN echo hi\n", ref)
user, err := devcontainer.UserFromDockerfile(content, nil)
require.NoError(t, err)
require.Equal(t, "testuser", user)
})
}

func TestUserFrom(t *testing.T) {
Expand Down
4 changes: 3 additions & 1 deletion devcontainer/features/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func extractFromImage(fs billy.Filesystem, directory, reference string) error {
}

var tarLayer *tar.Reader
var layerReader io.ReadCloser
for _, manifestLayer := range manifest.Layers {
if manifestLayer.MediaType != TarLayerMediaType {
continue
Expand All @@ -44,7 +45,7 @@ func extractFromImage(fs billy.Filesystem, directory, reference string) error {
if err != nil {
return fmt.Errorf("fetch feature layer %s: %w", reference, err)
}
layerReader, err := layer.Uncompressed()
layerReader, err = layer.Uncompressed()
if err != nil {
return fmt.Errorf("uncompress feature layer %s: %w", reference, err)
}
Expand All @@ -54,6 +55,7 @@ func extractFromImage(fs billy.Filesystem, directory, reference string) error {
if tarLayer == nil {
return fmt.Errorf("no tar layer found with media type %q: are you sure this is a devcontainer feature?", TarLayerMediaType)
}
defer layerReader.Close()

for {
header, err := tarLayer.Next()
Expand Down
Loading