Pauld/1568462 cut down skeleton/cli image (#1492)

* Initial work to transition CLI image to Skeleton image

* added most of oryx cli baked in dependencies to the build script generator

* added extension to string builder to install aptget packages, and added missing installations needed for php composer

* cleaned up sample app

* cleanup, and move php prereq installation to only apply to stretch

* fixed test to comply with new version resolver behavior

* add tests for cli dynamic installation and sample apps

* added correct installation root

* fix some java github-action tests

* added package installation to ruby, and updated tests

Co-authored-by: Cormac McCarthy <corm@microsoft.com>
This commit is contained in:
Paul Dorsch 2022-08-09 15:45:49 -04:00 коммит произвёл GitHub
Родитель 21056ad4cf
Коммит d5631d5acb
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
31 изменённых файлов: 675 добавлений и 54 удалений

Просмотреть файл

@ -0,0 +1,51 @@
#!/bin/bash
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT license.
# --------------------------------------------------------------------------------------------
# This script calculates container sizes after building a sample app with a given image.
#
# Input: docker image that should be used to base the containers off of
# Output: A file that contains the names of the sample apps used, and the size of the container
# after the sample app was built.
set -e
declare -r REPO_DIR=$( cd $( dirname "$0" ) && cd .. && pwd )
dockerImage=$1
function buildSampleAppAndCalculateSize() {
platform=$1
sampleApp=$2
name="sample-app-$sampleApp"
echo
echo "Creating container for $platform/$sampleApp with name $name..."
docker run --name $name -v "/$REPO_DIR/tests/SampleApps/$platform/$sampleApp://app" $dockerImage oryx build //app >/dev/null 2>&1
docker ps --size -as -f "name=$name" --format "$platform/$sampleApp size: {{.Size}}" >> $resultFileName
echo "Finished. Removing container $name..."
docker rm $name >/dev/null 2>&1
}
resultFileName="/tmp/sample-app-container-sizes.txt"
echo "Container sizes being written to output file: $resultFileName"
echo "Sample app container sizes for $dockerImage" > $resultFileName
echo "-------------------------------------------" >> $resultFileName
buildSampleAppAndCalculateSize "DotNetCore" "NetCoreApp31.MvcApp"
buildSampleAppAndCalculateSize "golang" "hello-world"
buildSampleAppAndCalculateSize "hugo" "hugo-sample"
buildSampleAppAndCalculateSize "java" "MavenSimpleJavaApp"
buildSampleAppAndCalculateSize "nodejs" "helloworld-nuxtjs"
buildSampleAppAndCalculateSize "php" "greetings"
buildSampleAppAndCalculateSize "python" "flask-app"
buildSampleAppAndCalculateSize "ruby" "Jekyll-app"
echo
echo "Finished all sample apps. Printing contents of output file $resultFileName..."
echo
echo
cat $resultFileName

Просмотреть файл

@ -1,11 +1,23 @@
ARG DEBIAN_FLAVOR
FROM buildpack-deps:${DEBIAN_FLAVOR}-curl
# Use the curl flavor of buildpack-deps as the base image, which is lighter than the standard flavor; more information here: https://hub.docker.com/_/buildpack-deps
FROM buildpack-deps:${DEBIAN_FLAVOR}-curl as main
ARG DEBIAN_FLAVOR
ENV DEBIAN_FLAVOR=$DEBIAN_FLAVOR
COPY --from=oryxdevmcr.azurecr.io/private/oryx/buildscriptgenerator /opt/buildscriptgen/ /opt/buildscriptgen/
COPY --from=oryxdevmcr.azurecr.io/private/oryx/support-files-image-for-build /tmp/oryx/ /opt/tmp
ENV ORYX_SDK_STORAGE_BASE_URL="https://oryx-cdn.microsoft.io" \
ENABLE_DYNAMIC_INSTALL="true" \
PATH="/usr/local/go/bin:/opt/python/latest/bin:/opt/oryx:/opt/yarn/stable/bin:/opt/hugo/lts:$PATH" \
DYNAMIC_INSTALL_ROOT_DIR="/opt" \
PYTHONIOENCODING="UTF-8" \
LANG="C.UTF-8" \
DOTNET_SKIP_FIRST_TIME_EXPERIENCE="1"
# Install an assortment of traditional tooling (unicode, SSL, HTTP, etc.)
# Also install some PHP requirements (unsure why it's gated by buster flavor, maybe due to some libraries being released per debian flavor, but we should try to install these pre-reqs no matter what)
RUN if [ "${DEBIAN_FLAVOR}" = "buster" ]; then \
apt-get update \
&& apt-get install -y --no-install-recommends \
@ -25,26 +37,25 @@ RUN if [ "${DEBIAN_FLAVOR}" = "buster" ]; then \
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
# .NET Core dependencies
# .NET Core dependencies for running Oryx
libc6 \
libgcc1 \
libgssapi-krb5-2 \
libstdc++6 \
zlib1g \
rsync \
libgdiplus \
&& rm -rf /var/lib/apt/lists/* \
&& chmod a+x /opt/buildscriptgen/GenerateBuildScript \
&& mkdir -p /opt/oryx \
&& ln -s /opt/buildscriptgen/GenerateBuildScript /opt/oryx/oryx \
&& echo "cli" > /opt/oryx/.imagetype \
&& echo "DEBIAN|${DEBIAN_FLAVOR}" | tr '[a-z]' '[A-Z]' > /opt/oryx/.ostype
RUN tmpDir="/opt/tmp" \
&& cp -f $tmpDir/images/build/benv.sh /opt/oryx/benv \
&& chmod +x /opt/oryx/benv
ENV ORYX_SDK_STORAGE_BASE_URL="https://oryx-cdn.microsoft.io"
ENV ENABLE_DYNAMIC_INSTALL="true"
ENV PATH="$PATH:/opt/oryx"
ENV DYNAMIC_INSTALL_ROOT_DIR="/opt"
&& cp -f $tmpDir/images/build/logger.sh /opt/oryx/logger \
&& chmod +x /opt/oryx/benv \
&& chmod +x /opt/oryx/logger
ENTRYPOINT [ "benv" ]

Просмотреть файл

@ -42,7 +42,7 @@ RUN if [ "${DEBIAN_FLAVOR}" = "bullseye" ]; then \
apt-get update \
&& apt-get install -y --no-install-recommends \
libicu67 \
libcurl4 \
libcurl4 \
libssl1.1 \
&& rm -rf /var/lib/apt/lists/* \
&& curl -LO http://security.debian.org/debian-security/pool/updates/main/libx/libxml2/libxml2_2.9.10+dfsg-6.7+deb11u2_amd64.deb \
@ -52,7 +52,7 @@ RUN if [ "${DEBIAN_FLAVOR}" = "bullseye" ]; then \
apt-get update \
&& apt-get install -y --no-install-recommends \
libicu63 \
libcurl4 \
libcurl4 \
libssl1.1 \
&& rm -rf /var/lib/apt/lists/* ; \
else \
@ -105,7 +105,7 @@ COPY --from=intermediate /opt /opt
# as per solution 2 https://stackoverflow.com/questions/65921037/nuget-restore-stopped-working-inside-docker-container
RUN ${IMAGES_DIR}/retry.sh "curl -o /usr/local/share/ca-certificates/verisign.crt -SsL https://crt.sh/?d=1039083 && update-ca-certificates" \
&& echo "value of DEBIAN_FLAVOR is ${DEBIAN_FLAVOR}"
# Install PHP pre-reqs # Install PHP pre-reqs
RUN if [ "${DEBIAN_FLAVOR}" = "buster" ] || [ "${DEBIAN_FLAVOR}" = "bullseye" ]; then \
apt-get update \

Просмотреть файл

@ -49,7 +49,7 @@ RUN LANG="C.UTF-8" \
FROM main AS intermediate
COPY --from=oryxdevmcr.azurecr.io/private/oryx/support-files-image-for-build /tmp/oryx/ /opt/tmp
COPY --from=oryxdevmcr.azurecr.io/private/oryx/buildscriptgenerator /opt/buildscriptgen/ /opt/buildscriptgen/
FROM main AS final
ARG AI_KEY
ARG SDK_STORAGE_BASE_URL_VALUE

Просмотреть файл

@ -0,0 +1,3 @@
# Build PHP 8.1
FROM oryxdevmcr.azurecr.io/private/oryx/php-build-prereqs AS php81-build
RUN set -eux && . /php/__phpVersions.sh && PHP_VERSION=$PHP81_VERSION GPG_KEYS=$PHP81_KEYS PHP_SHA256=$PHP81_TAR_SHA256 /php/build.sh

Просмотреть файл

@ -47,8 +47,8 @@ namespace Microsoft.Oryx.BuildScriptGenerator
public string GenerateDockerfile(DockerfileContext ctx)
{
var dockerfileBuildImageName = "build";
var dockerfileBuildImageTag = "azfunc-jamstack";
var dockerfileBuildImageName = "cli";
var dockerfileBuildImageTag = "stable";
var dockerfileRuntimeImage = !string.IsNullOrEmpty(this.commonOptions.RuntimePlatformName) ?
ConvertToRuntimeName(this.commonOptions.RuntimePlatformName) : string.Empty;
@ -135,6 +135,37 @@ namespace Microsoft.Oryx.BuildScriptGenerator
return platformName;
}
/// <summary>
/// When looking for a satifying runtime version, format it so that tags '8' and '8.1' are treated as
/// '8.99999.99999' and '8.1.99999', respectively. This allows the tags to be treated as the "maximum
/// version within the provided major or minor version that Oryx supports" during version comparison.
/// </summary>
/// <param name="runtimeVersions">The list of runtime versions supported for a platform.</param>
/// <returns>A list of tuples containing the original runtime version and its formatted version.</returns>
private static IEnumerable<(string OriginalRuntimeVersion, string FormattedRuntimeVersion)> FormatRuntimeVersions(IEnumerable<string> runtimeVersions)
{
return runtimeVersions.Select(v => FormatRuntimeVersion(v));
}
/// <summary>
/// When looking for a satifying runtime version, format it so that tags '8' and '8.1' are treated as
/// '8.99999.99999' and '8.1.99999', respectively. This allows the tags to be treated as the "maximum
/// version within the provided major or minor version that Oryx supports" during version comparison.
/// </summary>
/// <param name="runtimeVersion">The runtime version supported for a platform.</param>
/// <returns>A tuple containing the original runtime version and its formatted version.</returns>
private static (string OriginalRuntimeVersion, string FormattedRuntimeVersion) FormatRuntimeVersion(string runtimeVersion)
{
var formattedVersion = runtimeVersion;
var segments = runtimeVersion.Split('.');
for (int i = 0; i < 3 - segments.Length; i++)
{
formattedVersion += ".99999";
}
return (runtimeVersion, formattedVersion);
}
/// <summary>
/// Determines the version of the runtime image to use in the Dockerfile using the following logic:
/// (1) If both the platform name and version are provided, attempt to find the maximum satisfying version
@ -166,7 +197,17 @@ namespace Microsoft.Oryx.BuildScriptGenerator
platformVersion = $"~{platformVersion}";
}
return SemanticVersionResolver.GetMaxSatisfyingVersion(platformVersion, runtimeVersions) ?? runtimeVersions.LastOrDefault();
var formattedRuntimeVersions = FormatRuntimeVersions(runtimeVersions);
var satisfyingVersion = SemanticVersionResolver.GetMaxSatisfyingVersion(platformVersion, formattedRuntimeVersions.Select(v => v.FormattedRuntimeVersion));
if (satisfyingVersion == null)
{
return runtimeVersions.LastOrDefault();
}
return formattedRuntimeVersions
.Where(v => string.Equals(v.FormattedRuntimeVersion, satisfyingVersion))
.Select(v => v.OriginalRuntimeVersion)
.FirstOrDefault();
}
return runtimeVersions.LastOrDefault();

Просмотреть файл

@ -4,8 +4,10 @@
// --------------------------------------------------------------------------------------------
using System.IO;
using System.Text;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Oryx.BuildScriptGenerator.Php;
namespace Microsoft.Oryx.BuildScriptGenerator.DotNetCore
{
@ -31,5 +33,22 @@ namespace Microsoft.Oryx.BuildScriptGenerator.DotNetCore
dynamicInstallDir: Path.Combine(
this.CommonOptions.DynamicInstallRootDir, DotNetCoreConstants.PlatformName));
}
public override void InstallPlatformSpecificSkeletonDependencies(StringBuilder stringBuilder)
{
stringBuilder.AppendLine($"echo 'Installing {DotNetCoreConstants.PlatformName} specific dependencies...'");
// .NET Core dependencies (this is universal for all versions of .NET Core)
stringBuilder.AppendAptGetInstallPackages(
"libc6",
"libgcc1",
"libgssapi-krb5-2",
"libstdc++6",
"zlib1g",
"libuuid1",
"libunwind8");
InstallPythonToolingAndLanguage(stringBuilder);
}
}
}

Просмотреть файл

@ -4,8 +4,10 @@
// --------------------------------------------------------------------------------------------
using System.IO;
using System.Text;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Oryx.BuildScriptGenerator.DotNetCore;
namespace Microsoft.Oryx.BuildScriptGenerator.Node
{
@ -30,5 +32,37 @@ namespace Microsoft.Oryx.BuildScriptGenerator.Node
builtInDir: NodeConstants.InstalledNodeVersionsDir,
dynamicInstallDir: Path.Combine(this.CommonOptions.DynamicInstallRootDir, NodeConstants.PlatformName));
}
public override void InstallPlatformSpecificSkeletonDependencies(StringBuilder stringBuilder)
{
stringBuilder.AppendLine($"echo 'Installing {NodeConstants.PlatformName} specific dependencies...'");
// Install Hugo and Yarn for node applications
stringBuilder.AppendLine("BUILD_DIR=\"/opt/tmp/build\"");
stringBuilder.AppendLine("IMAGES_DIR=\"/opt/tmp/images\"");
stringBuilder.AppendLine("${IMAGES_DIR}/build/installHugo.sh");
stringBuilder.AppendLine("set -ex");
stringBuilder.AppendLine("yarnCacheFolder=\"/usr/local/share/yarn-cache\"");
stringBuilder.AppendLine("mkdir -p $yarnCacheFolder");
stringBuilder.AppendLine("chmod 777 $yarnCacheFolder");
stringBuilder.AppendLine(". ${BUILD_DIR}/__nodeVersions.sh");
stringBuilder.AppendLine("${IMAGES_DIR}/receiveGpgKeys.sh 6A010C5166006599AA17F08146C2130DFD2497F5");
stringBuilder.AppendLine("${IMAGES_DIR}/retry.sh \"curl -fsSLO --compressed https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz\"");
stringBuilder.AppendLine("${IMAGES_DIR}/retry.sh \"curl -fsSLO --compressed https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz.asc\"");
stringBuilder.AppendLine("gpg --batch --verify yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz");
stringBuilder.AppendLine("mkdir -p /opt/yarn");
stringBuilder.AppendLine("tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/yarn");
stringBuilder.AppendLine("mv /opt/yarn/yarn-v$YARN_VERSION /opt/yarn/$YARN_VERSION");
stringBuilder.AppendLine("rm yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz");
stringBuilder.AppendLine(". ${BUILD_DIR}/__nodeVersions.sh");
stringBuilder.AppendLine("ln -s $YARN_VERSION /opt/yarn/stable");
stringBuilder.AppendLine("ln -s $YARN_VERSION /opt/yarn/latest");
stringBuilder.AppendLine("ln -s $YARN_VERSION /opt/yarn/$YARN_MINOR_VERSION");
stringBuilder.AppendLine("ln -s $YARN_MINOR_VERSION /opt/yarn/$YARN_MAJOR_VERSION");
stringBuilder.AppendLine("mkdir -p /links");
stringBuilder.AppendLine("cp -s /opt/yarn/stable/bin/yarn /opt/yarn/stable/bin/yarnpkg /links");
InstallPythonToolingAndLanguage(stringBuilder);
}
}
}

Просмотреть файл

@ -4,6 +4,7 @@
// --------------------------------------------------------------------------------------------
using System.IO;
using System.Text;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@ -33,5 +34,39 @@ namespace Microsoft.Oryx.BuildScriptGenerator.Php
builtInDir: PhpConstants.InstalledPhpComposerVersionDir,
dynamicInstallDir: Path.Combine(this.CommonOptions.DynamicInstallRootDir, "php-composer"));
}
public override void InstallPlatformSpecificSkeletonDependencies(StringBuilder stringBuilder)
{
stringBuilder.AppendLine($"echo 'Installing php-composer specific dependencies...'");
// Install an assortment of traditional tooling (unicode, SSL, HTTP, etc.)
stringBuilder.AppendLine("if [ \"${DEBIAN_FLAVOR}\" = \"buster\" ]; then");
stringBuilder.AppendAptGetInstallPackages(
"ca-certificates",
"libargon2-0",
"libcurl4-openssl-dev",
"libedit-dev",
"libonig-dev",
"libncurses6",
"libsodium-dev",
"libsqlite3-dev",
"libxml2-dev",
"xz-utils");
stringBuilder.AppendLine("else");
stringBuilder.AppendLine("tmpDir=\"/opt/tmp\"");
stringBuilder.AppendLine("imagesDir=\"$tmpDir/images\"");
stringBuilder.AppendLine("$imagesDir/build/php/prereqs/installPrereqs.sh");
stringBuilder.AppendAptGetInstallPackages(
"libcurl3",
"libicu57",
"liblttng-ust0",
"libssl1.0.2",
"libargon2-0",
"libonig-dev",
"libncurses5-dev",
"libxml2-dev",
"libedit-dev");
stringBuilder.AppendLine("fi");
}
}
}

Просмотреть файл

@ -4,6 +4,7 @@
// --------------------------------------------------------------------------------------------
using System.IO;
using System.Text;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@ -33,5 +34,39 @@ namespace Microsoft.Oryx.BuildScriptGenerator.Php
builtInDir: PhpConstants.InstalledPhpVersionsDir,
dynamicInstallDir: Path.Combine(this.CommonOptions.DynamicInstallRootDir, PhpConstants.PlatformName));
}
public override void InstallPlatformSpecificSkeletonDependencies(StringBuilder stringBuilder)
{
stringBuilder.AppendLine($"echo 'Installing {PhpConstants.PlatformName} specific dependencies...'");
// Install an assortment of traditional tooling (unicode, SSL, HTTP, etc.)
stringBuilder.AppendLine("if [ \"${DEBIAN_FLAVOR}\" = \"buster\" ]; then");
stringBuilder.AppendAptGetInstallPackages(
"ca-certificates",
"libargon2-0",
"libcurl4-openssl-dev",
"libedit-dev",
"libonig-dev",
"libncurses6",
"libsodium-dev",
"libsqlite3-dev",
"libxml2-dev",
"xz-utils");
stringBuilder.AppendLine("else");
stringBuilder.AppendLine("tmpDir=\"/opt/tmp\"");
stringBuilder.AppendLine("imagesDir=\"$tmpDir/images\"");
stringBuilder.AppendLine("$imagesDir/build/php/prereqs/installPrereqs.sh");
stringBuilder.AppendAptGetInstallPackages(
"libcurl3",
"libicu57",
"liblttng-ust0",
"libssl1.0.2",
"libargon2-0",
"libonig-dev",
"libncurses5-dev",
"libxml2-dev",
"libedit-dev");
stringBuilder.AppendLine("fi");
}
}
}

Просмотреть файл

@ -28,6 +28,57 @@ namespace Microsoft.Oryx.BuildScriptGenerator
protected ILogger Logger { get; }
/// <summary>
/// Install tooling that is common to all platforms.
/// </summary>
public static void InstallCommonSkeletonDependencies(StringBuilder stringBuilder)
{
stringBuilder.AppendLine("echo 'Installing common platform dependencies...'");
stringBuilder.AppendAptGetInstallPackages("git");
}
public static void InstallPythonToolingAndLanguage(StringBuilder stringBuilder)
{
stringBuilder.AppendLine("echo 'Installing python tooling and language...'");
// Install Python tooling
stringBuilder.AppendLine("PYTHONIOENCODING=\"UTF-8\"");
stringBuilder.AppendAptGetInstallPackages(
"make",
"unzip",
"build-essential",
"libpq-dev",
"moreutils",
"python3-pip",
"swig",
"tk-dev",
"unixodbc-dev",
"uuid-dev");
// Install Python 3.8
stringBuilder.AppendLine("tmpDir=\"/opt/tmp\"");
stringBuilder.AppendLine("imagesDir=\"$tmpDir/images\"");
stringBuilder.AppendLine("buildDir=\"$tmpDir/build\"");
stringBuilder.AppendLine("mkdir -p /usr/local/share/pip-cache/lib");
stringBuilder.AppendLine("chmod -R 777 /usr/local/share/pip-cache");
stringBuilder.AppendLine("pip3 install pip --upgrade");
stringBuilder.AppendLine("python3 -m pip install --upgrade cython");
stringBuilder.AppendLine("pip3 install --upgrade cython");
stringBuilder.AppendLine(". $buildDir/__pythonVersions.sh");
stringBuilder.AppendLine("$imagesDir/installPlatform.sh python $PYTHON38_VERSION");
stringBuilder.AppendLine("[ -d \"/opt/python/$PYTHON38_VERSION\" ] && echo /opt/python/$PYTHON38_VERSION/lib >> /etc/ld.so.conf.d/python.conf");
stringBuilder.AppendLine("ldconfig");
stringBuilder.AppendLine("cd /opt/python");
stringBuilder.AppendLine("ln -s $PYTHON38_VERSION 3.8");
stringBuilder.AppendLine("ln -s $PYTHON38_VERSION latest");
stringBuilder.AppendLine("ln -s $PYTHON38_VERSION stable");
}
public virtual void InstallPlatformSpecificSkeletonDependencies(StringBuilder stringBuilder)
{
stringBuilder.AppendLine("echo 'No platform specific dependencies to install.'");
}
protected string GetInstallerScriptSnippet(
string platformName,
string version,
@ -45,6 +96,10 @@ namespace Microsoft.Oryx.BuildScriptGenerator
var snippet = new StringBuilder();
snippet
.AppendLine()
.AppendLine($"if grep -q cli \"/opt/oryx/.imagetype\"; then")
.AppendCommonSkeletonDepenendenciesInstallation()
.AppendPlatformSpecificSkeletonDepenendenciesInstallation(this)
.AppendLine("fi")
.AppendLine("PLATFORM_SETUP_START=$SECONDS")
.AppendLine("SDK_DEBIAN_TYPE=$DEBIAN_FLAVOR")
.AppendLine("echo")

Просмотреть файл

@ -4,6 +4,7 @@
// --------------------------------------------------------------------------------------------
using System.IO;
using System.Text;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@ -30,5 +31,12 @@ namespace Microsoft.Oryx.BuildScriptGenerator.Python
builtInDir: PythonConstants.InstalledPythonVersionsDir,
dynamicInstallDir: Path.Combine(this.CommonOptions.DynamicInstallRootDir, PythonConstants.PlatformName));
}
public override void InstallPlatformSpecificSkeletonDependencies(StringBuilder stringBuilder)
{
stringBuilder.AppendLine($"echo 'Installing {PythonConstants.PlatformName} specific dependencies...'");
InstallPythonToolingAndLanguage(stringBuilder);
}
}
}

Просмотреть файл

@ -4,6 +4,7 @@
// --------------------------------------------------------------------------------------------
using System.IO;
using System.Text;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@ -30,5 +31,50 @@ namespace Microsoft.Oryx.BuildScriptGenerator.Ruby
builtInDir: RubyConstants.InstalledRubyVersionsDir,
dynamicInstallDir: Path.Combine(this.CommonOptions.DynamicInstallRootDir, RubyConstants.PlatformName));
}
public override void InstallPlatformSpecificSkeletonDependencies(StringBuilder stringBuilder)
{
stringBuilder.AppendLine($"echo 'Installing {RubyConstants.PlatformName} specific dependencies...'");
stringBuilder.AppendAptGetInstallPackages(
"libreadline-dev",
"bzip2",
"build-essential",
"libssl-dev",
"zlib1g-dev",
"libpq-dev",
"libsqlite3-dev",
"patch",
"gawk",
"g++",
"gcc",
"make",
"libc6-dev",
"patch",
"libreadline6-dev",
"libyaml-dev",
"sqlite3",
"autoconf",
"libgdbm-dev",
"libncurses5-dev",
"automake",
"libtool",
"bison",
"pkg-config",
"libffi-dev",
"bison",
"libxslt-dev",
"libxml2-dev",
"wget",
"git",
"net-tools",
"dnsutils",
"curl",
"tcpdump",
"iproute2",
"unixodbc-dev",
"vim",
"tcptraceroute");
}
}
}

Просмотреть файл

@ -42,6 +42,31 @@ namespace Microsoft.Oryx.BuildScriptGenerator
return stringBuilder;
}
public static StringBuilder AppendPlatformSpecificSkeletonDepenendenciesInstallation(this StringBuilder stringBuilder, PlatformInstallerBase platformInstaller)
{
platformInstaller.InstallPlatformSpecificSkeletonDependencies(stringBuilder);
return stringBuilder;
}
public static StringBuilder AppendCommonSkeletonDepenendenciesInstallation(this StringBuilder stringBuilder)
{
PlatformInstallerBase.InstallCommonSkeletonDependencies(stringBuilder);
return stringBuilder;
}
public static StringBuilder AppendAptGetInstallPackages(this StringBuilder stringBuilder, params string[] packagesToInstall)
{
stringBuilder.AppendLine("apt-get update");
stringBuilder.AppendLine("apt-get upgrade -y");
stringBuilder.AppendLine("apt-get install -y --no-install-recommends \\");
stringBuilder.AppendLine($" {string.Join(" ", packagesToInstall)}");
stringBuilder.AppendLine("rm -rf /var/lib/apt/lists/*");
return stringBuilder;
}
public static StringBuilder AppendFormatWithLine(
this StringBuilder stringBuilder,
string format,

Просмотреть файл

@ -19,8 +19,8 @@ namespace Microsoft.Oryx.BuildScriptGenerator.Tests
private const string _buildImageFormat = "mcr.microsoft.com/oryx/{0}:{1}";
private const string _argRuntimeFormat = "ARG RUNTIME={0}:{1}";
private const string _buildImageName = "build";
private const string _buildImageTag = "azfunc-jamstack";
private const string _buildImageName = "cli";
private const string _buildImageTag = "stable";
private readonly string _tempDirRoot;
@ -119,7 +119,7 @@ namespace Microsoft.Oryx.BuildScriptGenerator.Tests
[InlineData("nodejs", "10", "10")]
[InlineData("nodejs", "12", "12")]
[InlineData("nodejs", "~12", "12")] // Test semver spec
[InlineData("nodejs", "~8", "8.12")] // Test semver spec
[InlineData("nodejs", "~8", "8")] // Test semver spec
[InlineData("nodejs", "<13", "12")] // Test semver
[InlineData("php", "5.6", "5.6")]
[InlineData("php", "7.3", "7.3")]
@ -169,7 +169,7 @@ namespace Microsoft.Oryx.BuildScriptGenerator.Tests
/// <param name="detectedPlatformVersion">The platform version that is "detected".</param>
/// <param name="expectedRuntimeImageTag">The expected runtime tag of the Dockerfile produced.</param>
[Theory]
[InlineData("dotnet", "2.0", "2.0")]
[InlineData("dotnet", "5.0.17", "5.0")]
[InlineData("dotnet", "2.1", "2.1")]
[InlineData("dotnet", "3.0", "3.0")]
[InlineData("nodejs", "6", "6")]
@ -177,13 +177,13 @@ namespace Microsoft.Oryx.BuildScriptGenerator.Tests
[InlineData("nodejs", "10", "10")]
[InlineData("nodejs", "12", "12")]
[InlineData("nodejs", "~12", "12")] // Test semver spec
[InlineData("nodejs", "~8", "8.12")] // Test semver spec
[InlineData("nodejs", "~8", "8")] // Test semver spec
[InlineData("nodejs", "<13", "12")] // Test semver
[InlineData("php", "5.6", "5.6")]
[InlineData("php", "7.3", "7.3")]
[InlineData("python", "2.7", "2.7")]
[InlineData("python", "3.7", "3.10")] // 3.7.x not currently a runtime, use latest
[InlineData("python", "3.8", "3.8")]
[InlineData("python", "3.8.1", "3.8")]
public void GenerateDockerfile_GeneratesBuildTagAndRuntime_ForNoProvidedPlatform(
string platformName,
string detectedPlatformVersion,

Просмотреть файл

@ -42,9 +42,33 @@ namespace Microsoft.Oryx.BuildImage.Tests
[InlineData(NetCoreApp31MvcApp, "3.1")]
[InlineData(NetCoreApp50MvcApp, "5.0")]
[InlineData(NetCore7PreviewMvcApp, "7.0.0-preview.6.22324.4")]
public void BuildsApplication_ByDynamicallyInstallingSDKs(
public void BuildsApplication_ByDynamicallyInstallingSDKs_GithubActions(
string appName,
string runtimeVersion)
{
BuildsApplication_ByDynamicallyInstallingSDKs(
appName, runtimeVersion, _restrictedPermissionsImageHelper.GetGitHubActionsBuildImage());
}
[Theory, Trait("category", "cli")]
[InlineData(NetCoreApp21WebApp, "2.1")]
[InlineData(NetCoreApp31MvcApp, "3.1")]
[InlineData(NetCoreApp50MvcApp, "5.0")]
[InlineData(NetCore7PreviewMvcApp, "7.0.0-preview.6.22324.4")]
public void BuildsApplication_ByDynamicallyInstallingSDKs_Cli(
string appName,
string runtimeVersion)
{
BuildsApplication_ByDynamicallyInstallingSDKs(
appName, runtimeVersion, _imageHelper.GetCliImage());
BuildsApplication_ByDynamicallyInstallingSDKs(
appName, runtimeVersion, _imageHelper.GetCliImage("cli-buster"));
}
private void BuildsApplication_ByDynamicallyInstallingSDKs(
string appName,
string runtimeVersion,
string imageName)
{
// Arrange
var volume = CreateSampleAppVolume(appName);
@ -68,7 +92,7 @@ namespace Microsoft.Oryx.BuildImage.Tests
// Act
var result = _dockerCli.Run(new DockerRunArguments
{
ImageId = _restrictedPermissionsImageHelper.GetGitHubActionsBuildImage(),
ImageId = imageName,
EnvironmentVariables = new List<EnvironmentVariable> { CreateAppNameEnvVar(appName) },
Volumes = new List<DockerVolume> { volume },
CommandToExecuteOnRun = "/bin/bash",

Просмотреть файл

@ -55,6 +55,15 @@ namespace Microsoft.Oryx.BuildImage.Tests
GDIPlusLibrary_IsPresentInTheImage("github-actions-buster");
}
[Fact, Trait("category", "cli")]
public void PipelineTestInvocationCli()
{
GDIPlusLibrary_IsPresentInTheImage("cli");
GDIPlusLibrary_IsPresentInTheImage("cli-buster");
Builds_NetCore31App_UsingNetCore31_DotNetSdkVersion(_imageHelper.GetCliImage());
Builds_NetCore31App_UsingNetCore31_DotNetSdkVersion(_imageHelper.GetCliImage("cli-buster"));
}
private readonly string SdkVersionMessageFormat = "Using .NET Core SDK Version: {0}";
[Fact (Skip="NetCore11 is no longer officially supported"), Trait("category", "latest")]
@ -274,8 +283,9 @@ namespace Microsoft.Oryx.BuildImage.Tests
result.GetDebugInfo());
}
[Fact, Trait("category", "latest")]
public void Builds_NetCore31App_UsingNetCore31_DotNetSdkVersion()
[Theory, Trait("category", "latest")]
[InlineData(Settings.BuildImageName)]
public void Builds_NetCore31App_UsingNetCore31_DotNetSdkVersion(string imageName)
{
// Arrange
var appName = "NetCoreApp31.MvcApp";
@ -293,7 +303,7 @@ namespace Microsoft.Oryx.BuildImage.Tests
// Act
var result = _dockerCli.Run(new DockerRunArguments
{
ImageId = Settings.BuildImageName,
ImageId = imageName,
EnvironmentVariables = new List<EnvironmentVariable> { CreateAppNameEnvVar(appName) },
Volumes = new List<DockerVolume> { volume },
CommandToExecuteOnRun = "/bin/bash",

Просмотреть файл

@ -36,6 +36,15 @@ namespace Microsoft.Oryx.BuildImage.Tests
InstallsHugoVersionDynamically_UsingEnvironmentVariable_AndBuildsApp(imageTestHelper.GetGitHubActionsBuildImage());
}
[Theory, Trait("category", "cli")]
[InlineData("cli")]
[InlineData("cli-buster")]
public void PipelineTestInvocationCli(string imageTag)
{
var imageTestHelper = new ImageTestHelper();
InstallsHugoVersionDynamically_UsingEnvironmentVariable_AndBuildsApp(imageTestHelper.GetCliImage(imageTag));
}
private void InstallsHugoVersionDynamically_UsingEnvironmentVariable_AndBuildsApp(string imageName)
{
// Please note:

Просмотреть файл

@ -43,6 +43,15 @@ namespace Microsoft.Oryx.BuildImage.Tests
GeneratesScript_AndBuilds(imageTestHelper.GetAzureFunctionsJamStackBuildImage());
}
[Theory, Trait("category", "cli")]
[InlineData("cli")]
[InlineData("cli-buster")]
public void PipelineTestInvocationCli(string imageTag)
{
var imageTestHelper = new ImageTestHelper();
GeneratesScript_AndBuilds(imageTestHelper.GetCliImage(imageTag));
}
private void GeneratesScript_AndBuilds(string buildImageName)
{
// Please note:

Просмотреть файл

@ -37,7 +37,20 @@ namespace Microsoft.Oryx.BuildImage.Tests
[Theory, Trait("category", "githubactions")]
[MemberData(nameof(VersionsData))]
public void BuildsMavenArcheTypeSampleWithDynamicInstallation(string version)
public void BuildsMavenArcheTypeSampleWithDynamicInstallationGithubActions(string version)
{
BuildsMavenArcheTypeSampleWithDynamicInstallation(version, _imageHelper.GetGitHubActionsBuildImage());
}
[Theory, Trait("category", "cli")]
[MemberData(nameof(VersionsData))]
public void BuildsMavenArcheTypeSampleWithDynamicInstallationCli(string version)
{
BuildsMavenArcheTypeSampleWithDynamicInstallation(version, _imageHelper.GetCliImage());
BuildsMavenArcheTypeSampleWithDynamicInstallation(version, _imageHelper.GetCliImage("cli-buster"));
}
private void BuildsMavenArcheTypeSampleWithDynamicInstallation(string version, string imageName)
{
// Arrange
var appName = "MavenArcheType";
@ -53,7 +66,7 @@ namespace Microsoft.Oryx.BuildImage.Tests
// Act
var result = _dockerCli.Run(new DockerRunArguments
{
ImageId = _imageHelper.GetGitHubActionsBuildImage(),
ImageId = imageName,
EnvironmentVariables = new List<EnvironmentVariable> { CreateAppNameEnvVar(appName) },
Volumes = new List<DockerVolume> { volume },
CommandToExecuteOnRun = "/bin/bash",

Просмотреть файл

@ -23,7 +23,28 @@ namespace Microsoft.Oryx.BuildImage.Tests
DockerVolume.CreateMirror(Path.Combine(_hostSamplesDir, "java", sampleAppName));
[Fact, Trait("category", "githubactions")]
public void BuildsMavenArcheTypeSample()
public void JavaSampleAppsTestsGithubActions()
{
var imageTag = "github-actions";
BuildsMavenArcheTypeSample(imageTag);
BuildsMavenJ2EESample(imageTag);
BuildsMavenSimpleJavaApp(imageTag);
BuildsSpringBootSampleApp(imageTag);
}
[Theory, Trait("category", "cli")]
[InlineData("cli")]
[InlineData("cli-buster")]
public void JavaSampleAppsTestsCli(string imageTag)
{
BuildsMavenArcheTypeSample(imageTag);
BuildsMavenJ2EESample(imageTag);
BuildsMavenSimpleJavaApp(imageTag);
BuildsSpringBootSampleApp(imageTag);
}
private void BuildsMavenArcheTypeSample(string imageTag)
{
// Arrange
var appName = "MavenArcheType";
@ -39,7 +60,7 @@ namespace Microsoft.Oryx.BuildImage.Tests
// Act
var result = _dockerCli.Run(new DockerRunArguments
{
ImageId = _imageHelper.GetGitHubActionsBuildImage(),
ImageId = _imageHelper.GetBuildImage(imageTag),
EnvironmentVariables = new List<EnvironmentVariable> { CreateAppNameEnvVar(appName) },
Volumes = new List<DockerVolume> { volume },
CommandToExecuteOnRun = "/bin/bash",
@ -55,8 +76,7 @@ namespace Microsoft.Oryx.BuildImage.Tests
result.GetDebugInfo());
}
[Fact, Trait("category", "githubactions")]
public void BuildsMavenJ2EESample()
private void BuildsMavenJ2EESample(string imageTag)
{
// Arrange
var appName = "MavenJ2EESample";
@ -72,7 +92,7 @@ namespace Microsoft.Oryx.BuildImage.Tests
// Act
var result = _dockerCli.Run(new DockerRunArguments
{
ImageId = _imageHelper.GetGitHubActionsBuildImage(),
ImageId = _imageHelper.GetBuildImage(imageTag),
EnvironmentVariables = new List<EnvironmentVariable> { CreateAppNameEnvVar(appName) },
Volumes = new List<DockerVolume> { volume },
CommandToExecuteOnRun = "/bin/bash",
@ -88,8 +108,7 @@ namespace Microsoft.Oryx.BuildImage.Tests
result.GetDebugInfo());
}
[Fact, Trait("category", "githubactions")]
public void BuildsMavenSimpleJavaApp()
private void BuildsMavenSimpleJavaApp(string imageTag)
{
// Arrange
var appName = "MavenSimpleJavaApp";
@ -105,7 +124,7 @@ namespace Microsoft.Oryx.BuildImage.Tests
// Act
var result = _dockerCli.Run(new DockerRunArguments
{
ImageId = _imageHelper.GetGitHubActionsBuildImage(),
ImageId = _imageHelper.GetBuildImage(imageTag),
EnvironmentVariables = new List<EnvironmentVariable> { CreateAppNameEnvVar(appName) },
Volumes = new List<DockerVolume> { volume },
CommandToExecuteOnRun = "/bin/bash",
@ -121,8 +140,7 @@ namespace Microsoft.Oryx.BuildImage.Tests
result.GetDebugInfo());
}
[Fact, Trait("category", "githubactions")]
public void BuildsSpringBootSampleApp()
private void BuildsSpringBootSampleApp(string imageTag)
{
// Arrange
var appName = "SprintBootSample";
@ -138,7 +156,7 @@ namespace Microsoft.Oryx.BuildImage.Tests
// Act
var result = _dockerCli.Run(new DockerRunArguments
{
ImageId = _imageHelper.GetGitHubActionsBuildImage(),
ImageId = _imageHelper.GetBuildImage(imageTag),
EnvironmentVariables = new List<EnvironmentVariable> { CreateAppNameEnvVar(appName) },
Volumes = new List<DockerVolume> { volume },
CommandToExecuteOnRun = "/bin/bash",

Просмотреть файл

@ -34,9 +34,38 @@ namespace Microsoft.Oryx.BuildImage.Tests
}
}
public static TheoryData<string, string> ImageNameDataCli
{
get
{
var data = new TheoryData<string, string>();
var imageTestHelper = new ImageTestHelper();
data.Add("12.22.11", imageTestHelper.GetCliImage());
data.Add("14.19.1", imageTestHelper.GetCliImage());
data.Add("16.14.2", imageTestHelper.GetCliImage());
data.Add("12.22.11", imageTestHelper.GetCliImage("cli-buster"));
data.Add("14.19.1", imageTestHelper.GetCliImage("cli-buster"));
data.Add("16.14.2", imageTestHelper.GetCliImage("cli-buster"));
return data;
}
}
[Theory, Trait("category", "githubactions")]
[MemberData(nameof(ImageNameData))]
public void GeneratesScript_AndBuildNodeAppsWithDynamicInstallation(string version, string buildImageName)
public void GeneratesScript_AndBuildNodeAppsWithDynamicInstallationGithubActions(string version, string buildImageName)
{
GeneratesScript_AndBuildNodeAppsWithDynamicInstallation(version, buildImageName);
}
[Theory, Trait("category", "cli")]
[MemberData(nameof(ImageNameDataCli))]
public void GeneratesScript_AndBuildNodeAppsWithDynamicInstallationCli(string version, string buildImageName)
{
GeneratesScript_AndBuildNodeAppsWithDynamicInstallation(version, buildImageName);
}
private void GeneratesScript_AndBuildNodeAppsWithDynamicInstallation(string version, string buildImageName)
{
// Arrange
var devPackageName = "nodemon";

Просмотреть файл

@ -49,6 +49,15 @@ namespace Microsoft.Oryx.BuildImage.Tests
GeneratesScript_AndBuilds(imageTestHelper.GetAzureFunctionsJamStackBuildImage());
}
[Theory, Trait("category", "cli")]
[InlineData("cli")]
[InlineData("cli-buster")]
public void PipelineTestInvocationCli(string imageTag)
{
var imageTestHelper = new ImageTestHelper();
GeneratesScript_AndBuilds(imageTestHelper.GetCliImage(imageTag));
}
private void GeneratesScript_AndBuilds(string buildImageName)
{
// Please note:

Просмотреть файл

@ -50,9 +50,47 @@ namespace Microsoft.Oryx.BuildImage.Tests
}
}
public static TheoryData<string, string, string> VersionAndImageNameDataCli
{
get
{
var data = new TheoryData<string, string, string>();
var imageHelper = new ImageTestHelper();
data.Add(PhpVersions.Php73Version, imageHelper.GetCliImage(),PhpVersions.ComposerVersion);
data.Add(PhpVersions.Php74Version, imageHelper.GetCliImage(), PhpVersions.ComposerVersion);
data.Add(PhpVersions.Php74Version, imageHelper.GetCliImage("cli-buster"), PhpVersions.ComposerVersion);
data.Add(PhpVersions.Php80Version, imageHelper.GetCliImage("cli-buster"), PhpVersions.ComposerVersion);
data.Add(PhpVersions.Php81Version, imageHelper.GetCliImage("cli-buster"), PhpVersions.ComposerVersion);
// test latest php-composer version
data.Add(PhpVersions.Php73Version, imageHelper.GetCliImage(), PhpVersions.Composer23Version);
data.Add(PhpVersions.Php74Version, imageHelper.GetCliImage(), PhpVersions.Composer23Version);
data.Add(PhpVersions.Php74Version, imageHelper.GetCliImage("cli-buster"), PhpVersions.Composer23Version);
data.Add(PhpVersions.Php80Version, imageHelper.GetCliImage("cli-buster"), PhpVersions.Composer23Version);
data.Add(PhpVersions.Php81Version, imageHelper.GetCliImage("cli-buster"), PhpVersions.Composer23Version);
return data;
}
}
[Theory, Trait("category", "githubactions")]
[MemberData(nameof(VersionAndImageNameData))]
public void BuildsAppByInstallingSdkDynamically(string phpVersion, string imageName, string phpComposerVersion)
public void BuildsAppByInstallingSdkDynamicallyGithubActions(string phpVersion, string imageName, string phpComposerVersion)
{
BuildsAppByInstallingSdkDynamically(phpVersion, imageName, phpComposerVersion);
}
[Theory, Trait("category", "cli")]
[MemberData(nameof(VersionAndImageNameDataCli))]
public void BuildsAppByInstallingSdkDynamicallyCli(string phpVersion, string imageName, string phpComposerVersion)
{
BuildsAppByInstallingSdkDynamically(phpVersion, imageName, phpComposerVersion, "/opt/php");
}
private void BuildsAppByInstallingSdkDynamically(
string phpVersion,
string imageName,
string phpComposerVersion,
string installationRoot = BuildScriptGenerator.Constants.TemporaryInstallationDirectoryRoot)
{
// Arrange
var appName = "twig-example";
@ -81,8 +119,7 @@ namespace Microsoft.Oryx.BuildImage.Tests
{
Assert.True(result.IsSuccess);
Assert.Contains(
$"PHP executable: " +
BuildScriptGenerator.Constants.TemporaryInstallationDirectoryRoot, result.StdOut);
$"PHP executable: " + installationRoot, result.StdOut);
Assert.Contains("Installing twig/twig", result.StdErr); // Composer prints its messages to STDERR
Assert.Contains($"\'php-composer\' version \'{phpComposerVersion}\'", result.StdOut);
},

Просмотреть файл

@ -96,6 +96,42 @@ namespace Microsoft.Oryx.BuildImage.Tests
result.GetDebugInfo());
}
[Theory, Trait("category", "cli")]
[InlineData(PhpVersions.Php74Version, "cli")]
[InlineData(PhpVersions.Php73Version, "cli")]
[InlineData(PhpVersions.Php80Version, "cli-buster")]
public void GeneratesScript_AndBuilds_TwigExample_WithDynamicInstallation(string phpVersion, string imageTag)
{
// Arrange
var appName = "twig-example";
var volume = CreateSampleAppVolume(appName);
var appDir = volume.ContainerDir;
var appOutputDir = "/tmp/app-output";
var script = new ShellScriptBuilder()
.AddDefaultTestEnvironmentVariables()
.AddBuildCommand($"{appDir} -o {appOutputDir} --platform {PhpConstants.PlatformName} --platform-version {phpVersion}")
.ToString();
// Act
var result = _dockerCli.Run(new DockerRunArguments
{
ImageId = _imageHelper.GetBuildImage(imageTag),
EnvironmentVariables = new List<EnvironmentVariable> { CreateAppNameEnvVar(appName) },
Volumes = new List<DockerVolume> { volume },
CommandToExecuteOnRun = "/bin/bash",
CommandArguments = new[] { "-c", script }
});
// Assert
RunAsserts(() =>
{
Assert.True(result.IsSuccess);
Assert.Contains($"PHP executable: /opt/php/{phpVersion}/bin/php", result.StdOut);
Assert.Contains($"Installing twig/twig", result.StdErr); // Composer prints its messages to STDERR
},
result.GetDebugInfo());
}
[Theory, Trait("category", "ltsversions")]
[InlineData(PhpVersions.Php74Version)]
[InlineData(PhpVersions.Php73Version)]

Просмотреть файл

@ -39,14 +39,25 @@ namespace Microsoft.Oryx.BuildImage.Tests
GeneratesScript_AndBuildsPython(imageTestHelper.GetGitHubActionsBuildImage("github-actions-bullseye"), "3.10.4");
}
private void GeneratesScript_AndBuildsPython(string imageName, string version)
[Fact, Trait("category", "cli")]
public void PipelineTestInvocationCli()
{
var imageTestHelper = new ImageTestHelper();
GeneratesScript_AndBuildsPython(imageTestHelper.GetCliImage(), "3.8.1", "/opt");
GeneratesScript_AndBuildsPython(imageTestHelper.GetCliImage(), "3.8.3", "/opt");
GeneratesScript_AndBuildsPython(imageTestHelper.GetCliImage("cli-buster"), "3.9.0", "/opt");
}
private void GeneratesScript_AndBuildsPython(
string imageName,
string version,
string installationRoot = BuildScriptGenerator.Constants.TemporaryInstallationDirectoryRoot)
{
// Please note:
// This test method has at least 1 wrapper function that pases the imageName parameter.
// Arrange
var installationDir = $"{BuildScriptGenerator.Constants.TemporaryInstallationDirectoryRoot}/" +
$"python/{version}";
var installationDir = $"{installationRoot}/python/{version}";
var appName = "flask-app";
var volume = CreateSampleAppVolume(appName);
var appDir = volume.ContainerDir;

Просмотреть файл

@ -32,7 +32,6 @@ namespace Microsoft.Oryx.BuildImage.Tests
{
GeneratesScript_AndBuilds(Settings.BuildImageName);
JamSpell_CanBe_Installed_In_The_BuildImage("latest");
JamSpell_CanBe_Installed_In_The_BuildImage("latest");
DoesNotGenerateCondaBuildScript_IfImageDoesNotHaveCondaInstalledInIt("latest");
}
@ -57,6 +56,16 @@ namespace Microsoft.Oryx.BuildImage.Tests
DoesNotGenerateCondaBuildScript_IfImageDoesNotHaveCondaInstalledInIt("github-actions-buster");
}
[Theory, Trait("category", "cli")]
[InlineData("cli")]
[InlineData("cli-buster")]
public void PipelineTestInvocationCli(string imageTag)
{
GeneratesScript_AndBuilds(_imageHelper.GetCliImage(imageTag));
JamSpell_CanBe_Installed_In_The_BuildImage(imageTag);
DoesNotGenerateCondaBuildScript_IfImageDoesNotHaveCondaInstalledInIt(imageTag);
}
[Theory]
[InlineData(Settings.BuildImageName)]
[InlineData(Settings.LtsVersionsBuildImageName)]

Просмотреть файл

@ -41,6 +41,18 @@ namespace Microsoft.Oryx.BuildImage.Tests
RubyVersions.Ruby31Version, imageTestHelper.GetGitHubActionsBuildImage());
}
[Theory, Trait("category", "cli")]
[InlineData("cli")]
[InlineData("cli-buster")]
public void PipelineTestInvocationCli(string imageTag)
{
var imageTestHelper = new ImageTestHelper();
GeneratesScript_AndBuildSinatraAppWithDynamicInstall(
RubyVersions.Ruby30Version, imageTestHelper.GetCliImage(imageTag));
GeneratesScript_AndBuildSinatraAppWithDynamicInstall(
RubyVersions.Ruby31Version, imageTestHelper.GetCliImage(imageTag));
}
private void GeneratesScript_AndBuildSinatraAppWithDynamicInstall(string version, string buildImageName)
{
// Please note:

Просмотреть файл

@ -29,6 +29,7 @@ namespace Microsoft.Oryx.BuildImage.Tests
var imageTestHelper = new ImageTestHelper();
Builds_JekyllStaticWebApp_UsingCustomBuildCommand(
imageTestHelper.GetVsoBuildImage("vso-focal"));
GeneratesScript_AndBuildRailsApp(imageTestHelper.GetVsoBuildImage("vso-focal"));
}
[Fact, Trait("category", "jamstack")]
@ -39,6 +40,17 @@ namespace Microsoft.Oryx.BuildImage.Tests
imageTestHelper.GetAzureFunctionsJamStackBuildImage());
}
[Theory, Trait("category", "cli")]
[InlineData("cli")]
[InlineData("cli-buster")]
public void PipelineTestInvocationCli(string imageTag)
{
var imageTestHelper = new ImageTestHelper();
Builds_JekyllStaticWebApp_UsingCustomBuildCommand(
imageTestHelper.GetCliImage(imageTag));
GeneratesScript_AndBuildRailsApp(imageTestHelper.GetCliImage(imageTag));
}
[Fact, Trait("category", "vso-focal")]
public void GeneratesScript_AndBuildSinatraApp()
{
@ -72,8 +84,7 @@ namespace Microsoft.Oryx.BuildImage.Tests
result.GetDebugInfo());
}
[Fact, Trait("category", "vso-focal")]
public void GeneratesScript_AndBuildRailsApp()
private void GeneratesScript_AndBuildRailsApp(string imageName)
{
// Arrange
var appName = "ruby-on-rails-app";
@ -82,14 +93,14 @@ namespace Microsoft.Oryx.BuildImage.Tests
var appOutputDir = "/tmp/app-output";
var script = new ShellScriptBuilder()
.AddDefaultTestEnvironmentVariables()
.AddCommand($"cd {appDir} && bundle update")
.AddCommand($"cd {appDir}")
.AddBuildCommand($"{appDir} -o {appOutputDir}")
.ToString();
// Act
var result = _dockerCli.Run(new DockerRunArguments
{
ImageId = _imageHelper.GetVsoBuildImage("vso-focal"),
ImageId = imageName,
EnvironmentVariables = new List<EnvironmentVariable> { CreateAppNameEnvVar(appName) },
Volumes = new List<DockerVolume> { volume },
CommandToExecuteOnRun = "/bin/bash",

Просмотреть файл

@ -37,7 +37,20 @@ namespace Microsoft.Oryx.BuildImage.Tests
}
[Fact, Trait("category", "ltsversions")]
public void GeneratesScript_AndBuildGolangAppWithDynamicInstall()
public void GeneratesScript_AndBuildGolangAppWithDynamicInstall_Lts()
{
GeneratesScript_AndBuildGolangAppWithDynamicInstall(_imageHelper.GetLtsVersionsBuildImage());
}
[Theory, Trait("category", "cli")]
[InlineData("cli")]
[InlineData("cli-buster")]
public void GeneratesScript_AndBuildGolangAppWithDynamicInstall_Cli(string imageTag)
{
GeneratesScript_AndBuildGolangAppWithDynamicInstall(_imageHelper.GetCliImage(imageTag));
}
private void GeneratesScript_AndBuildGolangAppWithDynamicInstall(string imageName)
{
var imageTestHelper = new ImageTestHelper();
@ -54,7 +67,7 @@ namespace Microsoft.Oryx.BuildImage.Tests
// Act
var result = _dockerCli.Run(new DockerRunArguments
{
ImageId = imageTestHelper.GetLtsVersionsBuildImage(),
ImageId = imageName,
EnvironmentVariables = new List<EnvironmentVariable> { CreateAppNameEnvVar(appName) },
Volumes = new List<DockerVolume> { volume },
CommandToExecuteOnRun = "/bin/bash",

Просмотреть файл

@ -197,6 +197,14 @@ namespace Microsoft.Oryx.Tests.Common
{
return GetAzureFunctionsJamStackBuildImage(_azureFunctionsJamStackBullseye);
}
else if (string.Equals(tag, _cliRepository))
{
return GetCliImage(_cliRepository);
}
else if (string.Equals(tag, _cliBusterRepository))
{
return GetCliImage(_cliBusterRepository);
}
throw new NotSupportedException($"A build image cannot be created with the given tag '{tag}'.");
}