From 9d0979888b37d57e3e1dfa6d892ea0570dda9e06 Mon Sep 17 00:00:00 2001 From: Marten Lohstroh Date: Wed, 6 Mar 2024 22:54:25 -0800 Subject: [PATCH] Add `pre-build-cmd` to `docker` target property --- .../generator/docker/CDockerGenerator.java | 24 +++++--------- .../generator/docker/DockerGenerator.java | 33 +++++++++++++++++++ .../generator/docker/TSDockerGenerator.java | 6 ++++ .../target/property/DockerProperty.java | 32 +++++++++++++----- .../DistributedCountContainerized.lf | 3 +- 5 files changed, 74 insertions(+), 24 deletions(-) diff --git a/core/src/main/java/org/lflang/generator/docker/CDockerGenerator.java b/core/src/main/java/org/lflang/generator/docker/CDockerGenerator.java index 4a29cc998f..d3e4c64eeb 100644 --- a/core/src/main/java/org/lflang/generator/docker/CDockerGenerator.java +++ b/core/src/main/java/org/lflang/generator/docker/CDockerGenerator.java @@ -1,10 +1,8 @@ package org.lflang.generator.docker; -import org.eclipse.xtext.xbase.lib.IterableExtensions; +import java.util.List; import org.lflang.generator.LFGeneratorContext; import org.lflang.target.Target; -import org.lflang.target.property.BuildCommandsProperty; -import org.lflang.util.StringUtil; /** * Generate the docker file related code for the C and CCpp target. @@ -34,10 +32,7 @@ public String defaultImage() { protected String generateDockerFileContent() { var lfModuleName = context.getFileConfig().name; var config = context.getTargetConfig(); - var compileCommand = - IterableExtensions.isNullOrEmpty(config.get(BuildCommandsProperty.INSTANCE)) - ? generateCompileCommand() - : StringUtil.joinObjects(config.get(BuildCommandsProperty.INSTANCE), " "); + var compileCommand = generateCompileCommand(); var compiler = config.target == Target.CCPP ? "g++" : "gcc"; var baseImage = baseImage(); return String.join( @@ -83,14 +78,13 @@ protected String generateRunForBuildDependencies() { } } - /** Return the default compile command for the C docker container. */ - protected String generateCompileCommand() { - return String.join( - "\n", - "RUN set -ex && \\", - "mkdir bin && \\", - "cmake -DCMAKE_INSTALL_BINDIR=./bin -S src-gen -B bin && \\", - "cd bin && \\", + @Override + protected List defaultBuildCommands() { + return List.of( + "set -ex", + "mkdir -p bin", + "cmake -DCMAKE_INSTALL_BINDIR=./bin -S src-gen -B bin", + "cd bin", "make all"); } } diff --git a/core/src/main/java/org/lflang/generator/docker/DockerGenerator.java b/core/src/main/java/org/lflang/generator/docker/DockerGenerator.java index 203c5f94d7..b529342c26 100644 --- a/core/src/main/java/org/lflang/generator/docker/DockerGenerator.java +++ b/core/src/main/java/org/lflang/generator/docker/DockerGenerator.java @@ -1,8 +1,11 @@ package org.lflang.generator.docker; import java.nio.file.Path; +import java.util.List; import org.lflang.generator.LFGeneratorContext; +import org.lflang.target.property.BuildCommandsProperty; import org.lflang.target.property.DockerProperty; +import org.lflang.util.StringUtil; /** * A class for generating docker files. @@ -30,6 +33,28 @@ public DockerGenerator(LFGeneratorContext context) { /** Return a RUN command for installing/checking build dependencies. */ protected abstract String generateRunForBuildDependencies(); + /** Return the default compile commands for the C docker container. */ + protected abstract List defaultBuildCommands(); + + protected List getBuildCommands() { + var customBuildCommands = context.getTargetConfig().get(BuildCommandsProperty.INSTANCE); + if (customBuildCommands != null && !customBuildCommands.isEmpty()) { + return customBuildCommands; + } + return defaultBuildCommands(); + } + + /** Return the default compile command for the C docker container. */ + protected String generateCompileCommand() { + var preBuildCmd = preBuildCmd(); + var run = "RUN "; + var del = " && "; + if (!preBuildCmd.isEmpty()) { + run = run + preBuildCmd + del; + } + return run + StringUtil.joinObjects(getBuildCommands(), del); + } + /** Return the default base image. */ public abstract String defaultImage(); @@ -42,6 +67,14 @@ public String baseImage() { return defaultImage(); } + public String preBuildCmd() { + var preBuildCmd = context.getTargetConfig().get(DockerProperty.INSTANCE).preBuildCmd(); + if (preBuildCmd != null) { + return preBuildCmd; + } + return ""; + } + /** * Produce a DockerData object, which bundles all information needed to output a Dockerfile. * diff --git a/core/src/main/java/org/lflang/generator/docker/TSDockerGenerator.java b/core/src/main/java/org/lflang/generator/docker/TSDockerGenerator.java index cdb6ddcf4b..6f943bbb30 100644 --- a/core/src/main/java/org/lflang/generator/docker/TSDockerGenerator.java +++ b/core/src/main/java/org/lflang/generator/docker/TSDockerGenerator.java @@ -1,5 +1,6 @@ package org.lflang.generator.docker; +import java.util.List; import org.lflang.generator.LFGeneratorContext; /** @@ -31,6 +32,11 @@ protected String generateRunForBuildDependencies() { return "RUN which node && node --version"; } + @Override + protected List defaultBuildCommands() { + return List.of("pnpm install"); // FIXME: actually build using docker, not natively. + } + @Override public String defaultImage() { return "node:alpine"; diff --git a/core/src/main/java/org/lflang/target/property/DockerProperty.java b/core/src/main/java/org/lflang/target/property/DockerProperty.java index 1dc47724fe..c7eadcb1a3 100644 --- a/core/src/main/java/org/lflang/target/property/DockerProperty.java +++ b/core/src/main/java/org/lflang/target/property/DockerProperty.java @@ -36,6 +36,7 @@ public DockerOptions fromAst(Element node, MessageReporter reporter) { var enabled = false; var from = ""; var rti = DockerOptions.DOCKERHUB_RTI_IMAGE; + var preBuildCmd = ""; if (node.getLiteral() != null) { if (ASTUtils.toBoolean(node)) { @@ -45,15 +46,23 @@ public DockerOptions fromAst(Element node, MessageReporter reporter) { enabled = true; for (KeyValuePair entry : node.getKeyvalue().getPairs()) { DockerOption option = (DockerOption) DictionaryType.DOCKER_DICT.forName(entry.getName()); - if (option != null && option.equals(DockerOption.FROM)) { - from = ASTUtils.elementToSingleString(entry.getValue()); + if (option == null) { + continue; } - if (option != null && option.equals(DockerOption.RTI_IMAGE)) { - rti = ASTUtils.elementToSingleString(entry.getValue()); + switch (option) { + case FROM: + from = ASTUtils.elementToSingleString(entry.getValue()); + break; + case RTI_IMAGE: + rti = ASTUtils.elementToSingleString(entry.getValue()); + break; + case PRE_BUILD_CMD: + preBuildCmd = ASTUtils.elementToSingleString(entry.getValue()); + break; } } } - return new DockerOptions(enabled, from, rti); + return new DockerOptions(enabled, from, rti, preBuildCmd); } @Override @@ -86,6 +95,12 @@ public Element toAstElement(DockerOptions value) { } pair.setValue(ASTUtils.toElement(value.rti)); } + if (opt == DockerOption.PRE_BUILD_CMD) { + if (!value.preBuildCmd.isEmpty()) { + continue; + } + pair.setValue(ASTUtils.toElement(value.preBuildCmd)); + } kvp.getPairs().add(pair); } e.setKeyvalue(kvp); @@ -102,7 +117,7 @@ public String name() { } /** Settings related to Docker options. */ - public record DockerOptions(boolean enabled, String from, String rti) { + public record DockerOptions(boolean enabled, String from, String rti, String preBuildCmd) { /** Default location to pull the rti from. */ public static final String DOCKERHUB_RTI_IMAGE = "lflang/rti:rti"; @@ -111,7 +126,7 @@ public record DockerOptions(boolean enabled, String from, String rti) { public static final String LOCAL_RTI_IMAGE = "rti:local"; public DockerOptions(boolean enabled) { - this(enabled, "", DOCKERHUB_RTI_IMAGE); + this(enabled, "", DOCKERHUB_RTI_IMAGE, ""); } } @@ -122,7 +137,8 @@ public DockerOptions(boolean enabled) { */ public enum DockerOption implements DictionaryElement { FROM("FROM", PrimitiveType.STRING), - RTI_IMAGE("rti-image", PrimitiveType.STRING); + RTI_IMAGE("rti-image", PrimitiveType.STRING), + PRE_BUILD_CMD("pre-build-cmd", PrimitiveType.STRING); public final PrimitiveType type; diff --git a/test/C/src/docker/federated/DistributedCountContainerized.lf b/test/C/src/docker/federated/DistributedCountContainerized.lf index dfcf9472cf..0429d84d7d 100644 --- a/test/C/src/docker/federated/DistributedCountContainerized.lf +++ b/test/C/src/docker/federated/DistributedCountContainerized.lf @@ -9,7 +9,8 @@ target C { logging: DEBUG, coordination: centralized, docker: { - rti-image: "rti:local" + rti-image: "rti:local", + pre-build-cmd: "ls" } }