diff --git a/build/tools/SharedCodeGenerator/SharedCodeGenerator.csproj b/build/tools/SharedCodeGenerator/SharedCodeGenerator.csproj index 99e274c24c..cf68b0941d 100644 --- a/build/tools/SharedCodeGenerator/SharedCodeGenerator.csproj +++ b/build/tools/SharedCodeGenerator/SharedCodeGenerator.csproj @@ -10,7 +10,7 @@ - + diff --git a/images/build/Dockerfiles/oryxTools.Dockerfile b/images/build/Dockerfiles/oryxTools.Dockerfile new file mode 100644 index 0000000000..d7c7a7acca --- /dev/null +++ b/images/build/Dockerfiles/oryxTools.Dockerfile @@ -0,0 +1,30 @@ +# Oryx Tools - Volume Mount Image +# Packages Oryx build system binaries into a minimal filesystem-only image. +# The image is mounted at /opt/oryx inside Kudu containers at runtime. + +ARG BASE_IMAGE + +FROM ${BASE_IMAGE} AS source + +ARG GIT_COMMIT=unspecified +ARG BUILD_NUMBER=unspecified +ARG RELEASE_TAG_NAME=unspecified + +# Signed oryx binaries produced by the pipeline build step +COPY binaries /opt/oryx/ + +# Helper scripts renamed into place +COPY images/build/benv.sh /opt/oryx/benv +COPY images/build/logger.sh /opt/oryx/logger + +# Rename main binary, set permissions, write image markers +RUN mv /opt/oryx/GenerateBuildScript /opt/oryx/oryx \ + && chmod a+x /opt/oryx/oryx \ + && chmod a+x /opt/oryx/Microsoft.Oryx.BuildServer \ + && chmod +x /opt/oryx/benv \ + && chmod +x /opt/oryx/logger \ + && echo "volume-mount" > /opt/oryx/.imagetype + +FROM scratch + +COPY --from=source /opt/oryx/ / diff --git a/src/BuildScriptGenerator/BaseBashBuildScript.sh.tpl b/src/BuildScriptGenerator/BaseBashBuildScript.sh.tpl index 25b723fcb4..a5862fd970 100644 --- a/src/BuildScriptGenerator/BaseBashBuildScript.sh.tpl +++ b/src/BuildScriptGenerator/BaseBashBuildScript.sh.tpl @@ -330,13 +330,20 @@ echo "Manifest file created." {{ end }} {{ end }} -OS_TYPE_SOURCE_DIR="/opt/oryx/.ostype" -if [ -f "$OS_TYPE_SOURCE_DIR" ] +if [ -n "$DEBIAN_FLAVOR" ] then - echo "Copying .ostype to manifest output directory." - cp "$OS_TYPE_SOURCE_DIR" "$MANIFEST_DIR/.ostype" + echo "Generating .ostype from DEBIAN_FLAVOR environment variable." + echo "DEBIAN|$DEBIAN_FLAVOR" | tr '[a-z]' '[A-Z]' > "$MANIFEST_DIR/.ostype" +elif [ -n "$OS_FLAVOR" ] +then + echo "Generating .ostype from OS_FLAVOR environment variable." + echo "DEBIAN|$OS_FLAVOR" | tr '[a-z]' '[A-Z]' > "$MANIFEST_DIR/.ostype" +elif [ -f "/opt/oryx/.ostype" ] +then + echo "Copying .ostype from /opt/oryx/.ostype to manifest output directory." + cp "/opt/oryx/.ostype" "$MANIFEST_DIR/.ostype" else - echo "File $OS_TYPE_SOURCE_DIR does not exist. Cannot copy to manifest directory." 1>&2 + echo "No OS flavor environment variable set and /opt/oryx/.ostype does not exist. Cannot generate .ostype." 1>&2 exit 1 fi diff --git a/src/BuildScriptGenerator/BuildScriptGenerator.csproj b/src/BuildScriptGenerator/BuildScriptGenerator.csproj index 9151e7a866..bfe4f8d1c3 100644 --- a/src/BuildScriptGenerator/BuildScriptGenerator.csproj +++ b/src/BuildScriptGenerator/BuildScriptGenerator.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/BuildScriptGenerator/PlatformInstallerBase.cs b/src/BuildScriptGenerator/PlatformInstallerBase.cs index 1603475663..369ec6fdb5 100644 --- a/src/BuildScriptGenerator/PlatformInstallerBase.cs +++ b/src/BuildScriptGenerator/PlatformInstallerBase.cs @@ -224,7 +224,6 @@ protected string GetInstallerScriptSnippet( snippet .AppendLine("echo") .AppendLine("oryxImageDetectorFile=\"/opt/oryx/.imagetype\"") - .AppendLine("oryxOsDetectorFile=\"/opt/oryx/.ostype\"") .AppendLine($"if [ -f \"$oryxImageDetectorFile\" ] && [ \"$platformName\" = \"dotnet\" ] && grep -q \"jamstack\" \"$oryxImageDetectorFile\"; then") .AppendLine("echo \"image detector file exists, platform is dotnet..\"") .AppendLine($"PATH=/opt/dotnet/{version}/dotnet:$PATH") @@ -260,9 +259,9 @@ protected string GetInstallerScriptSnippet( .AppendLine($"mkdir -p /home/codespace/.ruby") .AppendLine($"ln -sfn /opt/ruby/{version} /home/codespace/.ruby/current") .AppendLine("fi") - .AppendLine($"if [ -f \"$oryxImageDetectorFile\" ] && [ -f \"$oryxOsDetectorFile\" ] && [ \"$platformName\" = \"python\" ] && grep -q \"githubactions\" \"$oryxImageDetectorFile\" && grep -q \"BULLSEYE\" \"$oryxOsDetectorFile\"; then") + .AppendLine($"if [ -f \"$oryxImageDetectorFile\" ] && [ \"$platformName\" = \"python\" ] && (grep -q \"githubactions\" \"$oryxImageDetectorFile\" || grep -q \"volume-mount\" \"$oryxImageDetectorFile\") && [ \"$DEBIAN_FLAVOR\" = \"bullseye\" ]; then") .AppendLine($" echo \"image detector file exists, platform is python..\"") - .AppendLine($" echo \"OS detector file exists, OS is bullseye..\"") + .AppendLine($" echo \"OS is bullseye, checking Python version for libffi6 compat..\"") .AppendLine($" if [ '{version}' == 3.7* ] || [ '{version}' == 3.8* ]; then") .AppendLine($" curl -LO http://ftp.de.debian.org/debian/pool/main/libf/libffi/libffi6_3.2.1-9_amd64.deb") .AppendLine($" dpkg -i libffi6_3.2.1-9_amd64.deb") diff --git a/tests/BuildScriptGeneratorCli.Tests/BuildCommandTest.cs b/tests/BuildScriptGeneratorCli.Tests/BuildCommandTest.cs index aad39d7c8d..c79198a394 100644 --- a/tests/BuildScriptGeneratorCli.Tests/BuildCommandTest.cs +++ b/tests/BuildScriptGeneratorCli.Tests/BuildCommandTest.cs @@ -39,6 +39,11 @@ public BuildCommandTest(TestTempDirTestFixture testFixture) { _testDir = testFixture; _testDirPath = testFixture.RootDirPath; + + if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("DEBIAN_FLAVOR"))) + { + Environment.SetEnvironmentVariable("DEBIAN_FLAVOR", "bookworm"); + } } [Fact] @@ -296,31 +301,74 @@ public void OnSuccess_Execute_WritesOnlyBuildOutput_ToStandardOutput() } [EnableOnPlatform("LINUX")] - public void BuildScriptFails_WhenOstypeFile_NotPresent() + public void BuildScriptSucceeds_WhenOstypeFile_NotPresent_ButDebianFlavorEnvVarSet() { // Arrange var stringToPrint = "Hello World"; var script = $"#!/bin/bash\necho {stringToPrint}\n"; - var serviceProvider = CreateServiceProvider( - new TestProgrammingPlatform( - platformName: "test", - platformVersions: new[] { "1.0.0" }, - canGenerateScript: true, - scriptContent: script, - detector: new TestPlatformDetectorUsingPlatformName( - detectedPlatformName: "test", - detectedPlatformVersion: "1.0.0")), - scriptOnly: false, - createOsTypeFile: false); - var buildCommand = new BuildCommand(); - var testConsole = new TestConsole(newLineCharacter: string.Empty); - - // Act - var exitCode = buildCommand.Execute(serviceProvider, testConsole); + Environment.SetEnvironmentVariable("DEBIAN_FLAVOR", "bookworm"); + try + { + var serviceProvider = CreateServiceProvider( + new TestProgrammingPlatform( + platformName: "test", + platformVersions: new[] { "1.0.0" }, + canGenerateScript: true, + scriptContent: script, + detector: new TestPlatformDetectorUsingPlatformName( + detectedPlatformName: "test", + detectedPlatformVersion: "1.0.0")), + scriptOnly: false, + createOsTypeFile: false); + var buildCommand = new BuildCommand(); + var testConsole = new TestConsole(newLineCharacter: string.Empty); + + // Act + var exitCode = buildCommand.Execute(serviceProvider, testConsole); + + // Assert + Assert.Equal(0, exitCode); + } + finally + { + Environment.SetEnvironmentVariable("DEBIAN_FLAVOR", null); + } + } - // Assert failed with exit code 1 - Assert.Equal(1, exitCode); - Assert.Contains($"File {OS_TYPE_FILE_PATH} does not exist. Cannot copy to manifest directory.", testConsole.StdError); + [EnableOnPlatform("LINUX")] + public void BuildScriptFails_WhenOstypeFile_NotPresent_AndNoEnvVarSet() + { + // Arrange + var stringToPrint = "Hello World"; + var script = $"#!/bin/bash\necho {stringToPrint}\n"; + var originalDebianFlavor = Environment.GetEnvironmentVariable("DEBIAN_FLAVOR"); + Environment.SetEnvironmentVariable("DEBIAN_FLAVOR", null); + try + { + var serviceProvider = CreateServiceProvider( + new TestProgrammingPlatform( + platformName: "test", + platformVersions: new[] { "1.0.0" }, + canGenerateScript: true, + scriptContent: script, + detector: new TestPlatformDetectorUsingPlatformName( + detectedPlatformName: "test", + detectedPlatformVersion: "1.0.0")), + scriptOnly: false, + createOsTypeFile: false); + var buildCommand = new BuildCommand(); + var testConsole = new TestConsole(newLineCharacter: string.Empty); + + // Act + var exitCode = buildCommand.Execute(serviceProvider, testConsole); + + // Assert + Assert.Equal(1, exitCode); + } + finally + { + Environment.SetEnvironmentVariable("DEBIAN_FLAVOR", originalDebianFlavor); + } } [Fact]