From f0a68b39299f3580c6a15de64352e487c35e6274 Mon Sep 17 00:00:00 2001 From: Kim Christensen <2461567+kichristensen@users.noreply.github.com> Date: Sat, 23 Mar 2024 13:43:34 +0100 Subject: [PATCH] Handle custom invocation images without #PORTER_INIT (#2998) * Handle custom Dockerfile without PORTER_INIT The documentation says that if the PORTER_INIT section is missing on the custom dockerfile, it will be placed right after the FROM section. This was not the case, instead it was place at the end of the file, resulting in a dockerfile not working with Porter Signed-off-by: Kim Christensen --------- Signed-off-by: Kim Christensen --- pkg/build/dockerfile-generator.go | 4 +-- pkg/build/dockerfile-generator_test.go | 29 +++++++++++++++++++ ...le-without-init-expected-output.Dockerfile | 19 ++++++++++++ .../missing-args-expected-output.Dockerfile | 4 +-- ...ng-mixins-token-expected-output.Dockerfile | 4 +-- 5 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 pkg/build/testdata/custom-dockerfile-without-init-expected-output.Dockerfile diff --git a/pkg/build/dockerfile-generator.go b/pkg/build/dockerfile-generator.go index e30b0639a..688c2a3f3 100644 --- a/pkg/build/dockerfile-generator.go +++ b/pkg/build/dockerfile-generator.go @@ -254,7 +254,7 @@ func (g *DockerfileGenerator) copyMixin(mixin string) error { func (g *DockerfileGenerator) getIndexOfToken(lines []string, token string) int { for lineNumber, lineContent := range lines { - if token == strings.TrimSpace(lineContent) { + if strings.HasPrefix(strings.TrimSpace(lineContent), token) { return lineNumber } } @@ -269,7 +269,7 @@ func (g *DockerfileGenerator) replaceTokens(ctx context.Context, lines []string) return nil, fmt.Errorf("error generating Dockerfile content for mixins: %w", err) } - fromToken := g.getIndexOfToken(lines, "FROM") + fromToken := g.getIndexOfToken(lines, "FROM") + 1 substitutions := []struct { token string diff --git a/pkg/build/dockerfile-generator_test.go b/pkg/build/dockerfile-generator_test.go index 19030547b..54cdbcf26 100644 --- a/pkg/build/dockerfile-generator_test.go +++ b/pkg/build/dockerfile-generator_test.go @@ -103,6 +103,35 @@ COPY mybin /cnab/app/ require.NoError(t, err) test.CompareGoldenFile(t, "testdata/custom-dockerfile-expected-output.Dockerfile", strings.Join(gotlines, "\n")) }) + + t.Run("build from custom docker without PORTER_INIT supplied", func(t *testing.T) { + t.Parallel() + + c := config.NewTestConfig(t) + tmpl := templates.NewTemplates(c.Config) + configTpl, err := tmpl.GetManifest() + require.Nil(t, err) + c.TestContext.AddTestFileContents(configTpl, config.Name) + + m, err := manifest.LoadManifestFrom(context.Background(), c.Config, config.Name) + require.NoError(t, err, "could not load manifest") + + // Use a custom dockerfile template + m.Dockerfile = "Dockerfile.template" + customFrom := `FROM ubuntu:latest +# stuff +COPY mybin /cnab/app/ + +` + c.TestContext.AddTestFileContents([]byte(customFrom), "Dockerfile.template") + + mp := mixin.NewTestMixinProvider() + g := NewDockerfileGenerator(c.Config, m, tmpl, mp) + gotlines, err := g.buildDockerfile(context.Background()) + + require.NoError(t, err) + test.CompareGoldenFile(t, "testdata/custom-dockerfile-without-init-expected-output.Dockerfile", strings.Join(gotlines, "\n")) + }) } func TestPorter_generateDockerfile(t *testing.T) { diff --git a/pkg/build/testdata/custom-dockerfile-without-init-expected-output.Dockerfile b/pkg/build/testdata/custom-dockerfile-without-init-expected-output.Dockerfile new file mode 100644 index 000000000..2adc49f81 --- /dev/null +++ b/pkg/build/testdata/custom-dockerfile-without-init-expected-output.Dockerfile @@ -0,0 +1,19 @@ +# syntax=docker/dockerfile-upstream:1.4.0 +FROM ubuntu:latest +ARG BUNDLE_DIR +ARG BUNDLE_UID=65532 +ARG BUNDLE_USER=nonroot +ARG BUNDLE_GID=0 +RUN useradd ${BUNDLE_USER} -m -u ${BUNDLE_UID} -g ${BUNDLE_GID} -o +# stuff +COPY mybin /cnab/app/ + +# exec mixin has no buildtime dependencies + +RUN rm ${BUNDLE_DIR}/porter.yaml +RUN rm -fr ${BUNDLE_DIR}/.cnab +COPY --link .cnab /cnab +RUN chgrp -R ${BUNDLE_GID} /cnab && chmod -R g=u /cnab +USER ${BUNDLE_UID} +WORKDIR ${BUNDLE_DIR} +CMD ["/cnab/app/run"] \ No newline at end of file diff --git a/pkg/build/testdata/missing-args-expected-output.Dockerfile b/pkg/build/testdata/missing-args-expected-output.Dockerfile index 3d88f9dd1..cdc093fac 100644 --- a/pkg/build/testdata/missing-args-expected-output.Dockerfile +++ b/pkg/build/testdata/missing-args-expected-output.Dockerfile @@ -1,12 +1,12 @@ # syntax=docker/dockerfile-upstream:1.4.0 FROM ubuntu:latest -COPY mybin /cnab/app/ - ARG BUNDLE_DIR ARG BUNDLE_UID=65532 ARG BUNDLE_USER=nonroot ARG BUNDLE_GID=0 RUN useradd ${BUNDLE_USER} -m -u ${BUNDLE_UID} -g ${BUNDLE_GID} -o +COPY mybin /cnab/app/ + # exec mixin has no buildtime dependencies RUN rm ${BUNDLE_DIR}/porter.yaml diff --git a/pkg/build/testdata/missing-mixins-token-expected-output.Dockerfile b/pkg/build/testdata/missing-mixins-token-expected-output.Dockerfile index 8c1e39626..dd8e803a7 100644 --- a/pkg/build/testdata/missing-mixins-token-expected-output.Dockerfile +++ b/pkg/build/testdata/missing-mixins-token-expected-output.Dockerfile @@ -1,12 +1,12 @@ # syntax=docker/dockerfile-upstream:1.4.0 FROM ubuntu:light ARG BUNDLE_DIR -COPY mybin /cnab/app/ -ARG BUNDLE_DIR ARG BUNDLE_UID=65532 ARG BUNDLE_USER=nonroot ARG BUNDLE_GID=0 RUN useradd ${BUNDLE_USER} -m -u ${BUNDLE_UID} -g ${BUNDLE_GID} -o +ARG BUNDLE_DIR +COPY mybin /cnab/app/ # exec mixin has no buildtime dependencies RUN rm ${BUNDLE_DIR}/porter.yaml