From 2907567484a18cb80b33f8b08e6ccdacef0ce22d Mon Sep 17 00:00:00 2001 From: Bryce Lampe Date: Mon, 9 Dec 2024 15:41:58 -0800 Subject: [PATCH] Don't attempt to parse custom syntax (#346) The provider currently attempts to parse your Dockerfile in case there are any obviously broken syntax errors. However, Dockerfiles can use custom syntaxes which are implemented as their own images. Buildkit detects `# syntax=` directives, pulls the image, and uses it to parse. It doesn't make sense for us to attempt to replicate that behavior, so when we detect a custom syntax we will simply disable this validation. If there are syntax errors the user will discover them after the build is attempted. Fixes https://github.com/pulumi/pulumi-docker-build/issues/300 --- CHANGELOG.md | 3 +++ provider/internal/dockerfile.go | 18 ++++++++++++++++-- provider/internal/dockerfile_test.go | 19 +++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62fd6c6..c8c35e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ - Upgraded buildx from 0.16.0 to 0.18.0. +### Fixed +- Custom `# syntax=` directives no longer cause validation errors. (https://github.com/pulumi/pulumi-docker-build/issues/300) + ## 0.0.7 (2024-10-16) ### Fixed diff --git a/provider/internal/dockerfile.go b/provider/internal/dockerfile.go index 1757dbf..4d17a6c 100644 --- a/provider/internal/dockerfile.go +++ b/provider/internal/dockerfile.go @@ -15,6 +15,7 @@ package internal import ( + "bytes" "errors" "io" "os" @@ -96,13 +97,26 @@ func (d *Dockerfile) validate(preview bool, c *Context) error { } func parseDockerfile(r io.Reader) error { - parsed, err := parser.Parse(r) + df, _ := io.ReadAll(r) + syntax, _, _, _ := parser.DetectSyntax(df) + if syntax == "" { + syntax = os.Getenv("BUILDKIT_SYNTAX") + } + + // Disable validation if this uses a custom syntax. + if syntax != "" && syntax != "docker/dockerfile:1" { + return nil + } + + parsed, err := parser.Parse(bytes.NewReader(df)) if err != nil { return newCheckFailure(err, "dockerfile") } + _, _, err = instructions.Parse(parsed.AST, nil) if err != nil { - return err + return newCheckFailure(err, "dockerfile") } + return nil } diff --git a/provider/internal/dockerfile_test.go b/provider/internal/dockerfile_test.go index bd9fc74..2572d59 100644 --- a/provider/internal/dockerfile_test.go +++ b/provider/internal/dockerfile_test.go @@ -57,12 +57,31 @@ func TestValidateDockerfile(t *testing.T) { }, wantErr: "unknown instruction: RUNN", }, + { + name: "invalid syntax inline with default syntax directive", + d: Dockerfile{ + Inline: `# syntax=docker/dockerfile:1 + RUNN it`, + }, + wantErr: "unknown instruction: RUNN", + }, { name: "valid syntax inline", d: Dockerfile{ Inline: "FROM scratch", }, }, + { + name: "valid custom syntax inline", + d: Dockerfile{ + Inline: `# syntax=docker.io/docker/dockerfile:1.7-labs +FROM public.ecr.aws/docker/library/node:22-alpine AS base + +WORKDIR /app +COPY --parents ./package.json ./package-lock.json ./apps/*/package.json ./packages/*/package.json ./ +`, + }, + }, { name: "unset", d: Dockerfile{},