Add builder code and release pipelines (#1934)

* Fix .net 7 test

* added builder code into the oryx repo

* add cli builder into the pipelines, and added tests for it

* add missing line to build images script

* make grep use regex exact match

* add some basic build scripts for the builder image

* added missing ruby dep

* finished up scripts to build the builder images

* add cli builder in cli image building

* added pipelines to release base and capps builder images

* add builder jobs to validation

* depend on the builder job

* typo

* actually push the builder images to the prod acr

* add to ci and nightly

* removed extra unused script

* fix indentation

* retag and push the stack images to prod as well

* also use mcr for cli-builder image

* fix telemetry key and make ostype generic

* added link to CNB docs

* copy artifacts over to the expected artifacts dir

* removed condition for builder scripts running

* attempt to fix pipeline

* add gitignore

* remove gitignored files

* pr feedback remove files and fix pipelines

* updated base builder documentation

* added template build, and updating instrumentation key to connection string

* add to the rest of the pipelines and pull the cli builder before retagging it

* pr feedback: added exo pipefail to shell scripts and test on newer dotnet versions

* update builder base os to bullseye

* cleanup remaining buster ref, and remove libuuid

* allow php and ruby deps be installed on bullseye

* actually saving file :(

* removed the re-tagging to mcr logic
This commit is contained in:
Paul Dorsch 2023-03-23 17:36:24 -04:00 коммит произвёл GitHub
Родитель 6c04ec7568
Коммит a0f4a740a0
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
39 изменённых файлов: 1134 добавлений и 3 удалений

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

@ -30,6 +30,7 @@ declare -r ORYXTESTS_GITHUB_ACTIONS_ASBASE_BUILDIMAGE_DOCKERFILE="$REPO_DIR/test
declare -r ORYXTESTS_GITHUB_ACTIONS_ASBASE_WITHENV_BUILDIMAGE_DOCKERFILE="$REPO_DIR/tests/images/build/gitHubActions.AsBaseWithEnv.Dockerfile"
declare -r RUNTIME_IMAGES_SRC_DIR="$REPO_DIR/images/runtime"
declare -r BUILD_IMAGES_CLI_DOCKERFILE="$REPO_DIR/images/build/Dockerfiles/cli.Dockerfile"
declare -r BUILD_IMAGES_CLI_BUILDER_DOCKERFILE="$REPO_DIR/images/build/Dockerfiles/cliBuilder.Dockerfile"
declare -r BUILD_IMAGES_FULL_DOCKERFILE="$REPO_DIR/images/build/Dockerfiles/full.Dockerfile"
declare -r BUILD_IMAGES_AZ_FUNCS_JAMSTACK_DOCKERFILE="$REPO_DIR/images/build/Dockerfiles/azureFunctions.JamStack.Dockerfile"
declare -r BUILD_IMAGES_GITHUB_ACTIONS_DOCKERFILE="$REPO_DIR/images/build/Dockerfiles/gitHubActions.Dockerfile"
@ -54,6 +55,8 @@ declare -r BASE_IMAGES_ARTIFACTS_FILE_PREFIX="$ARTIFACTS_DIR/images"
declare -r RUNTIME_IMAGES_ARTIFACTS_FILE="$ARTIFACTS_DIR/images/runtime-images"
declare -r ACR_BUILD_IMAGES_ARTIFACTS_FILE="$ARTIFACTS_DIR/images/build-images-acr.txt"
declare -r ACR_RUNTIME_IMAGES_ARTIFACTS_FILE="$ARTIFACTS_DIR/images/runtime-images-acr"
declare -r ACR_BUILDER_IMAGES_ARTIFACTS_FILE="$ARTIFACTS_DIR/images/builder-images-acr.txt"
declare -r ACR_CAPPS_BUILDER_IMAGES_ARTIFACTS_FILE="$ARTIFACTS_DIR/images/capps-builder-images-acr.txt"
declare -r PACK_IMAGE_NAME='pack'
declare -r PACK_STACK_BASE_IMAGE_NAME="pack-stack-base"

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

@ -438,6 +438,41 @@ function buildCliImage() {
docker tag $builtImageName "$devImageRepo:$devImageTag"
}
function buildCliBuilderImage() {
buildBuildScriptGeneratorImage
local osType=$1
local osFlavor=$2
local builtImageRepo="$ACR_CLI_BUILD_IMAGE_REPO"
local devImageRepo="$DEVBOX_CLI_BUILD_IMAGE_REPO"
if [ -z "$osType" && -z "$osFlavor" ]; then
osType="debian"
osFlavor="bullseye"
fi
imageTag="builder-$osType-$osFlavor"
devImageName="$devImageRepo:$imageTag"
builtImageName="$builtImageRepo:$imageTag"
echo
echo "-------------Creating CLI Builder image-------------------"
docker build -t $builtImageName \
--build-arg AI_CONNECTION_STRING=$APPLICATION_INSIGHTS_CONNECTION_STRING \
--build-arg SDK_STORAGE_BASE_URL_VALUE=$sdkStorageAccountUrl \
--build-arg DEBIAN_FLAVOR=$osFlavor \
--label com.microsoft.oryx="$labelContent" \
-f "$BUILD_IMAGES_CLI_BUILDER_DOCKERFILE" \
.
createImageNameWithReleaseTag $builtImageName
echo
echo "$builtImageName image history"
docker history $builtImageName
echo "Tagging '$builtImageName' with dev name '$devImageName'"
docker tag $builtImageName $devImageName
}
function buildFullImage() {
buildBuildScriptGeneratorImage
@ -498,6 +533,7 @@ if [ -z "$imageTypeToBuild" ]; then
buildCliImage "buster"
buildCliImage "bullseye"
buildCliImage
buildCliBuilderImage "debian" "bullseye"
buildBuildPackImage
buildFullImage "buster"
buildFullImage "bullseye"
@ -539,17 +575,20 @@ elif [ "$imageTypeToBuild" == "cli" ]; then
buildCliImage
buildCliImage "buster"
buildCliImage "bullseye"
buildCliBuilderImage "debian" "bullseye"
elif [ "$imageTypeToBuild" == "cli-stretch" ]; then
buildCliImage
elif [ "$imageTypeToBuild" == "cli-buster" ]; then
buildCliImage "buster"
elif [ "$imageTypeToBuild" == "cli-bullseye" ]; then
buildCliImage "bullseye"
elif [ "$imageTypeToBuild" == "cli-builder-bullseye" ]; then
buildCliBuilderImage "debian" "bullseye"
elif [ "$imageTypeToBuild" == "buildpack" ]; then
buildBuildPackImage
else
echo "Error: Invalid value for '--type' switch. Valid values are: \
githubactions, jamstack, ltsversions, latest, full, vso-focal, cli, buildpack"
githubactions, jamstack, ltsversions, latest, full, vso-focal, cli, cli-builder-bullseye, buildpack"
exit 1
fi

11
builders/README.md Normal file
Просмотреть файл

@ -0,0 +1,11 @@
# Builders
This repo contains the definitions of the builder images that are used to build application source code into
runnable images.
These builders use the buildpack ecosystem defined by the [Cloud Native Buildpacks](https://buildpacks.io/) project.
They build the application code using the Oryx project, and can use the Oryx runtime images for the final images.
The `/base` directory contains the builder image itself, and is where the buildpack was authored. The
`/container-apps-wrapper` directory contains the code for an image that was built on top of the builder image and
has some additional logic, such as detecting the runtime version before running the build.

3
builders/base/.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,3 @@
builder/builder.toml
buildpack/buildpack.toml
buildpack/bin/build

96
builders/base/README.md Normal file
Просмотреть файл

@ -0,0 +1,96 @@
## Oryx Builder
### Official release
The Oryx-CI pipeline will release a version of the base builder image as `mcr.microsoft.com/oryx/builder:{TAG}`.
### Local testing and release to personal ACR
Use the `./build/buildBuildImages.sh` script to build a local version of the cli-builder image.
Use the `./buildBaseBuilder.sh` script, passing in the cli-builder image you just built, to build a local version
of the basebuilder image.
### Manual release
The following steps detail releasing a new base builder image manually.
#### Prerequisites
You must have access to the `oryxprodmcr` ACR instance in the Oryx production subscription account and have logged in
locally to `docker` with this ACR instance's credentials.
#### Build CLI image
_Note_: The CLI Builder image used has its OS packages pre-baked, since
[the builder **CAN NOT** run as a root user](https://buildpacks.io/docs/operator-guide/create-a-stack/#specification)
to dynamically install components via `apt-get` at run-time.
```
./oryx/build/buildBuildImages.sh -t cli-builder-bullseye
docker tag oryx/cli:builder-debian-bullseye oryxprodmcr.azurecr.io/public/oryx/cli:builder-debian-bullseye-{BUILD_ID}
```
#### Push CLI image
```
docker push oryxprodmcr.azurecr.io/public/oryx/cli:builder-debian-bullseye-{BUILD_ID}
```
#### Update the stack Dockerfile with the new CLI tag
Open `oryx-builder/stack/Dockerfile` and update the CLI image used as a base with the new tag for the CLI image previously pushed.
_Note_: this should continue to point to MCR as the CLI image pushed to oryxprodmcr will be propagated to MCR shortly after.
#### Create stack images
```
cd .\oryx-builder\stack
docker build . -t oryxprodmcr.azurecr.io/public/oryx/builder:stack-base-{BUILD_ID} --target base
docker build . -t oryxprodmcr.azurecr.io/public/oryx/builder:stack-run-{BUILD_ID} --target run
docker build . -t oryxprodmcr.azurecr.io/public/oryx/builder:stack-build-{BUILD_ID} --target build
```
#### Push stack images
```
docker push oryxprodmcr.azurecr.io/public/oryx/builder:stack-base-{BUILD_ID}
docker push oryxprodmcr.azurecr.io/public/oryx/builder:stack-run-{BUILD_ID}
docker push oryxprodmcr.azurecr.io/public/oryx/builder:stack-build-{BUILD_ID}
```
#### Create buildpack image
```
cd .\oryx-builder\packaged-buildpack
pack buildpack package oryxprodmcr.azurecr.io/public/oryx/builder:buildpack-{BUILD_ID} --config .\package.toml
```
#### Push buildpack image
```
docker push oryxprodmcr.azurecr.io/public/oryx/builder:buildpack-{BUILD_ID}
```
#### Update the builder.toml with the new buildpack and stack tags
Open `oryx-builder/builder/builder.toml` and update the the buildpack and stack images used with the new tag previously pushed.
_Note_: these images should continue to point to MCR as the images pushed to oryxprodmcr will be propagated to MCR shortly after.
#### Create builder image
```
cd .\oryx-builder\builder
pack builder create oryxprodmcr.azurecr.io/public/oryx/builder:{BUILD_ID} --config .\builder.toml
```
#### Test builder image
```
pack build {YOUR_TEST_ACR}.azurecr.io/container-app:1234 --path .\oryx\tests\SampleApps\DotNetCore\NetCore6PreviewMvcApp --builder oryxprodmcr.azurecr.io/public/oryx/builder:{BUILD_ID} --run-image mcr.microsoft.com/oryx/dotnetcore:6.0 --env "CALLER_ID=test"
```
#### Push builder image
```
docker push oryxprodmcr.azurecr.io/public/oryx/builder:{BUILD_ID}
```

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

@ -0,0 +1,145 @@
#!/bin/bash
set -exo pipefail
declare -r SCRIPT_DIR=$( cd $( dirname "$0" ) && pwd )
declare -r REPO_DIR=$( cd $( dirname "$0" ) && cd .. && cd .. && pwd )
source $REPO_DIR/build/__variables.sh
source $REPO_DIR/build/__sdkStorageConstants.sh
# constants
declare -r ORYX_AI_CONNECTION_STRING_PLACEHOLDER="%ORYX_AI_CONNECTION_STRING%"
declare -r ORYX_SDK_STORAGE_BASE_URL_PLACEHOLDER="%ORYX_SDK_STORAGE_BASE_URL%"
declare -r ORYX_BUILDPACK_IMAGE_PLACEHOLDER="%ORYX_BUILDPACK_IMAGE%"
declare -r ORYX_BUILDPACK_VERSION_PLACEHOLDER="%ORYX_BUILDPACK_VERSION%"
declare -r ORYX_RUN_STACK_IMAGE_PLACEHOLDER="%ORYX_RUN_STACK_IMAGE%"
declare -r ORYX_BUILD_STACK_IMAGE_PLACEHOLDER="%ORYX_BUILD_STACK_IMAGE%"
# parameter defaults
builderImageVersion="20230208.1"
destinationFqdn="oryxprodmcr.azurecr.io"
destinationRepo="public/oryx/builder"
buildpackVersion="0.0.4"
storageAccountUrl="$PROD_SDK_CDN_STORAGE_BASE_URL"
PARAMS=""
while (( "$#" )); do
case "$1" in
-c|--cli-builder-image)
cliBuilderImage=$2
shift 2
;;
-v|--builder-image-version)
builderImageVersion=$2
shift 2
;;
-f|--destination-registry-fqdn)
destinationFqdn=$2
shift 2
;;
-r|--destination-registry-repo)
destinationRepo=$2
shift 2
;;
--buildpack-version)
buildpackVersion=$2
shift 2
;;
-s|--storage-account-url)
storageAccountUrl=$2
shift 2
;;
--) # end argument parsing
shift
break
;;
-*|--*=) # unsupported flags
echo "Error: Unsupported flag $1" >&2
exit 1
;;
*) # preserve positional arguments
PARAMS="$PARAMS $1"
shift
;;
esac
done
if [ -z $cliBuilderImage ]; then
cliBuilderImage="$destinationFqdn/public/oryx/cli:builder-debian-bullseye-$builderImageVersion"
docker pull $cliBuilderImage
fi
# Create artifact dir & files
echo "Initializing artifacts file: $ACR_BUILDER_IMAGES_ARTIFACTS_FILE"
mkdir -p "$ARTIFACTS_DIR/images"
touch $ACR_BUILDER_IMAGES_ARTIFACTS_FILE
> $ACR_BUILDER_IMAGES_ARTIFACTS_FILE
# Building stack
echo "Tagging all images with the tag: $builderImageVersion"
echo "-------------------------------------------------"
echo
echo "Building stack..."
echo
baseImage="$destinationFqdn/$destinationRepo:stack-base-$builderImageVersion"
buildStackImage="$destinationFqdn/$destinationRepo:stack-build-$builderImageVersion"
runStackImage="$destinationFqdn/$destinationRepo:stack-run-$builderImageVersion"
docker build $SCRIPT_DIR/stack/ \
--build-arg CLI_BUILDER_IMAGE="$cliBuilderImage" \
-t $baseImage \
--target base
docker build $SCRIPT_DIR/stack/ \
--build-arg CLI_BUILDER_IMAGE="$cliBuilderImage" \
-t $runStackImage \
--target run
docker build $SCRIPT_DIR/stack/ \
--build-arg CLI_BUILDER_IMAGE="$cliBuilderImage" \
-t $buildStackImage \
--target build
echo "$baseImage" >> $ACR_BUILDER_IMAGES_ARTIFACTS_FILE
echo "$runStackImage" >> $ACR_BUILDER_IMAGES_ARTIFACTS_FILE
echo "$buildStackImage" >> $ACR_BUILDER_IMAGES_ARTIFACTS_FILE
echo "-------------------------------------------------"
# Copy buildpack/bin/template.build over to buildpack/bin/build and replace placeholders
buildFileTemplate="$SCRIPT_DIR/buildpack/bin/template.build"
targetBuildFile="$SCRIPT_DIR/buildpack/bin/build"
cp "$buildFileTemplate" "$targetBuildFile"
sed -i "s|$ORYX_AI_CONNECTION_STRING_PLACEHOLDER|$APPLICATION_INSIGHTS_CONNECTION_STRING|g" "$targetBuildFile"
sed -i "s|$ORYX_SDK_STORAGE_BASE_URL_PLACEHOLDER|$storageAccountUrl|g" "$targetBuildFile"
# Copy template.buildpack.toml over to buildpack.toml and replace placeholders
buildpackTomlTemplate="$SCRIPT_DIR/buildpack/template.buildpack.toml"
targetBuildpackToml="$SCRIPT_DIR/buildpack/buildpack.toml"
cp "$buildpackTomlTemplate" "$targetBuildpackToml"
sed -i "s|$ORYX_BUILDPACK_VERSION_PLACEHOLDER|$buildpackVersion|g" "$targetBuildpackToml"
# Packaging buildpack
buildPackImage="$destinationFqdn/$destinationRepo:buildpack-$builderImageVersion"
echo
echo "Packaging buildpack image: $buildPackImage"
echo
pack buildpack package $buildPackImage --config $SCRIPT_DIR/packaged-buildpack/package.toml
echo "$buildPackImage" >> $ACR_BUILDER_IMAGES_ARTIFACTS_FILE
echo "-------------------------------------------------"
# Copy template.builder.toml over to builder.toml and replace placeholders
builderTomlTemplate="$SCRIPT_DIR/builder/template.builder.toml"
targetBuilderToml="$SCRIPT_DIR/builder/builder.toml"
cp "$builderTomlTemplate" "$targetBuilderToml"
sed -i "s|$ORYX_BUILDPACK_IMAGE_PLACEHOLDER|$buildPackImage|g" "$targetBuilderToml"
sed -i "s|$ORYX_BUILDPACK_VERSION_PLACEHOLDER|$buildpackVersion|g" "$targetBuilderToml"
sed -i "s|$ORYX_RUN_STACK_IMAGE_PLACEHOLDER|$runStackImage|g" "$targetBuilderToml"
sed -i "s|$ORYX_BUILD_STACK_IMAGE_PLACEHOLDER|$buildStackImage|g" "$targetBuilderToml"
# Creating builder image
builderImage="$destinationFqdn/$destinationRepo:$builderImageVersion"
echo
echo "Creating builder image: $builderImage"
echo
pack builder create $builderImage --config $SCRIPT_DIR/builder/builder.toml
echo "$builderImage" >> $ACR_BUILDER_IMAGES_ARTIFACTS_FILE
echo "-------------------------------------------------"

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

@ -0,0 +1,25 @@
Reference: [_Create a builder_](https://buildpacks.io/docs/operator-guide/create-a-builder/)
## Create builder
The following must have been built first:
- [Stack](../stack)
- [Buildpack](../buildpack)
```
cd .\oryx-builder\builder
pack builder create oryx-builder:bionic --config .\builder.toml
```
## Use builder
```
pack build my-app my-builder:bionic --path .\oryx\tests\SampleApps\<path_to_app>
```
## Running the app
```
docker run --rm --entrypoint sys-info -it my-app
```

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

@ -0,0 +1,16 @@
[[buildpacks]]
image = "%ORYX_BUILDPACK_IMAGE%"
# Order used for detection
[[order]]
[[order.group]]
id = "oryx/buildpack"
version = "%ORYX_BUILDPACK_VERSION%"
# Stack that will be used by the builder
[stack]
id = "oryx.stacks.skeleton"
# This image is used at runtime
run-image = "%ORYX_RUN_STACK_IMAGE%"
# This image is used at build-time
build-image = "%ORYX_BUILD_STACK_IMAGE%"

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

@ -0,0 +1,23 @@
Reference: [_Building blocks of a Cloud Native Buildpack_](https://buildpacks.io/docs/buildpack-author-guide/create-buildpack/building-blocks-cnb/)
## Package buildpack
Reference the [`packaged-buildpack`](../packaged-buildpack) folder for more information on how to package the buildpack.
## Set default builder
```
pack config default-builder cnbs/sample-builder:bionic
```
## Trust default builder
```
pack config trusted-builders add cnbs/sample-builder:bionic
```
## Build the buildpack
```
pack build test-ruby-app --path ./ruby-sample-app --buildpack ./buildpack
```

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

@ -0,0 +1,10 @@
#!/usr/bin/env bash
set -eo pipefail
oryx detect $1 2> /dev/null
if [[ $? -eq 0 ]]; then
echo "Successfully detected compatible application platform."
else
echo "Unable to detect compatible application platform."
fi

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

@ -0,0 +1,30 @@
#!/usr/bin/env bash
set -exo pipefail
echo "---> Oryx Buildpack"
# 1. Get arguments
layersdir=$1
# 2. Create the Oryx layer directory for the buildpack
oryxlayer="$layersdir"/oryx
mkdir -p "$oryxlayer"
# 3. Make the Oryx layer available during launch
echo -e '[types]\nlaunch = true' > "$layersdir/oryx.toml"
# 4. Set Oryx-specific environment variables
export ENABLE_DYNAMIC_INSTALL="true"
export ORYX_AI_CONNECTION_STRING="%ORYX_AI_CONNECTION_STRING%"
export ORYX_SDK_STORAGE_BASE_URL="%ORYX_SDK_STORAGE_BASE_URL%"
# 5. Use the Oryx CLI to build the application
oryx build . --output ./oryx-output
# 6. Set the default start command
cat > "$layersdir/launch.toml" << EOL
[[processes]]
type = "run"
command = "oryx create-script -appPath ./oryx-output; ./run.sh"
default = true
EOL

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

@ -0,0 +1,11 @@
# Buildpack API version
api = "0.7"
# Buildpack ID and metadata
[buildpack]
id = "oryx/buildpack"
version = "%ORYX_BUILDPACK_VERSION%"
# Stacks that the buildpack will work with
[[stacks]]
id = "oryx.stacks.skeleton"

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

@ -0,0 +1,12 @@
Reference: [_Package a buildpack_](https://buildpacks.io/docs/buildpack-author-guide/package-a-buildpack/)
## Package the buildpack as an image
The following must have been built first:
- [Stack](../stack)
```
cd .\oryx-builder\packaged-buildpack
pack buildpack package oryx-buildpack --config .\package.toml
```

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

@ -0,0 +1,2 @@
[buildpack]
uri = "../buildpack/"

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

@ -0,0 +1,44 @@
# 1. Set a common base
ARG CLI_BUILDER_IMAGE="mcr.microsoft.com/oryx/cli:builder-debian-buster-20230208.1"
FROM ${CLI_BUILDER_IMAGE} as base
# 2. Set required CNB information
ENV CNB_USER_ID=1000
ENV CNB_GROUP_ID=1000
ENV CNB_STACK_ID="oryx.stacks.skeleton"
LABEL io.buildpacks.stack.id="oryx.stacks.skeleton"
# 3. Create the user
RUN groupadd cnb --gid ${CNB_GROUP_ID} && \
useradd --uid ${CNB_USER_ID} --gid ${CNB_GROUP_ID} -m -s /bin/bash cnb
# 4. Install common packages
RUN apt-get update && \
apt-get install -y xz-utils ca-certificates && \
rm -rf /var/lib/apt/lists/*
# 5. Start a new run stage
FROM base as run
# 6. Set user and group (as declared in base image)
USER ${CNB_USER_ID}:${CNB_GROUP_ID}
# 7. Start a new build stage
FROM base as build
ENV ORYX_SDK_STORAGE_BASE_URL="https://oryx-cdn.microsoft.io"
ENV ENABLE_DYNAMIC_INSTALL="true"
# 8. Install packages that we want to make available at build time
RUN apt-get update && \
apt-get install -y git wget jq && \
rm -rf /var/lib/apt/lists/* && \
wget https://github.com/sclevine/yj/releases/download/v5.0.0/yj-linux -O /usr/local/bin/yj && \
chmod +x /usr/local/bin/yj
USER root
RUN chown ${CNB_USER_ID}:${CNB_GROUP_ID} /opt
# 9. Set user and group (as declared in base image)
USER ${CNB_USER_ID}:${CNB_GROUP_ID}

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

@ -0,0 +1,31 @@
Reference: [_Create a stack_](https://buildpacks.io/docs/operator-guide/create-a-stack/)
## Create the base image
```
cd .\oryx-builder\stack
docker build . -t oryx/sample-stack-base:skeleton --target base
```
## Create the run image
```
cd .\oryx-builder\stack
docker build . -t oryx/sample-stack-run:skeleton --target run
```
## Create the build image
```
cd .\oryx-builder\stack
docker build . -t oryx/sample-stack-build:skeleton --target build
```
## Create all three stack images
```
cd .\oryx-builder\stack
docker build . -t oryx/sample-stack-base:skeleton --target base
docker build . -t oryx/sample-stack-run:skeleton --target run
docker build . -t oryx/sample-stack-build:skeleton --target build
```

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

@ -0,0 +1,41 @@
ARG BASE_BUILDER_IMAGE="mcr.microsoft.com/oryx/builder:20230208.1"
FROM ${BASE_BUILDER_IMAGE}
# these environment variables are generally going to be overwritten:
# APP_IMAGE: name that the builder will push the final image as, e.g. testacr.azurecr.io/app/capps-runnable-app
# ACR_RESOURCE_NAME: resource name of the ACR instance, e.g. testacr.azurecr.io
# TENANT_ID: tenant id in which the ACR resides
# ACR_SCOPE: scope that the image will need to push to the ACR, e.g. repository:app/capps-runnable-app:pull,push
# MI_PRINCIPAL_ID: principal id of the managed identity that will allow the image to push to the specified ACR
ENV APP_IMAGE="" \
ACR_RESOURCE_NAME="" \
TENANT_ID="" \
ACR_SCOPE="" \
MI_PRINCIPAL_ID=""
# these environment variables are not usually overwritten
ENV COMPRESSED_APP_LOCATION="/app-source/app.tar.gz" \
CNB_APP_DIR="/workspace/" \
CNB_PLATFORM_API="0.9" \
ORYX_SDK_STORAGE_BASE_URL="https://oryx-cdn.microsoft.io" \
ENABLE_DYNAMIC_INSTALL="true" \
ORYX_AI_CONNECTION_STRING="InstrumentationKey=4aadba6b-30c8-42db-9b93-024d5c62b887" \
MANAGEMENT_RESOURCE_URI="https://management.core.windows.net/"
USER root
# download and install file package
RUN set -eux; \
apt-get update; \
apt-get install -y --no-install-recommends \
file \
; \
rm -rf /var/lib/apt/lists/*
ADD startup-script.sh /startup-script.sh
RUN chmod +x /startup-script.sh
USER ${CNB_USER_ID}:${CNB_GROUP_ID}
ENTRYPOINT [ "/startup-script.sh" ]

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

@ -0,0 +1,7 @@
# Container Apps Wrapper
This directory contains an image that uses the Oryx builder image as a base, but has
some additional logic added on top of it, specifically for the builds that happen within
the container apps platform.
This extra logic is located within the [start script](./startup-script.sh), and is the container's
entrypoint.

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

@ -0,0 +1,68 @@
#!/bin/bash
set -exo pipefail
# This script that builds the builder image using the dockerfile in this directory,
# and pushes it to a specified azure container registry. Users must specify an
# ACR name to push the image to, and have the option to override the image repo and tag for the image.
declare -r SCRIPT_DIR=$( cd $( dirname "$0" ) && pwd )
declare -r REPO_DIR=$( cd $( dirname "$0" ) && cd .. && cd .. && pwd )
source $REPO_DIR/build/__variables.sh
# default values for non-required parameters
destinationFqdn="oryxprodmcr.azurecr.io"
destinationRepo="public/oryx/builder"
destinationTag="capps-20230208.1"
baseBuilderImage="mcr.microsoft.com/oryx/builder:20230208.1"
PARAMS=""
while (( "$#" )); do
case "$1" in
-f|--destination-fqdn)
destinationFqdn=$2
shift 2
;;
-r|--destination-repo)
destinationRepo=$2
shift 2
;;
-t|--destination-tag)
destinationTag=$2
shift 2
;;
-b|--base-builder-tag)
baseBuilderImage=$2
shift 2
;;
--) # end argument parsing
shift
break
;;
-*|--*=) # unsupported flags
echo "Error: Unsupported flag $1" >&2
exit 1
;;
*) # preserve positional arguments
PARAMS="$PARAMS $1"
shift
;;
esac
done
# set positional arguments in their proper place
eval set -- "$PARAMS"
echo "Initializing artifacts file: $ACR_CAPPS_BUILDER_IMAGES_ARTIFACTS_FILE"
mkdir -p "$ARTIFACTS_DIR/images"
touch $ACR_CAPPS_BUILDER_IMAGES_ARTIFACTS_FILE
> $ACR_CAPPS_BUILDER_IMAGES_ARTIFACTS_FILE
BUILD_IMAGE="$destinationFqdn/$destinationRepo:$destinationTag"
echo "Building '$BUILD_IMAGE'..."
echo
cd $SCRIPT_DIR
docker build \
--build-arg BASE_BUILDER_IMAGE=$baseBuilderImage \
-t $BUILD_IMAGE \
-f Dockerfile \
.
echo
echo "$BUILD_IMAGE" >> $ACR_CAPPS_BUILDER_IMAGES_ARTIFACTS_FILE

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

@ -0,0 +1,45 @@
#!/bin/bash
set -e
# Wait for tarball to be placed in COMPRESSED_APP_LOCATION, and the type to be compressed data.
# Waiting for the type to be compressed data also helps ensure that the file is fully uploaded before
# proceeding.
while [[ ! -f $COMPRESSED_APP_LOCATION || ! "$(file $COMPRESSED_APP_LOCATION)" =~ "compressed data" ]]
do
echo "Waiting for app source to be uploaded to '$COMPRESSED_APP_LOCATION'..."
sleep 5
done
# Extract app code to CNB_APP_DIR directory.
echo "Found app source at '$COMPRESSED_APP_LOCATION'. Extracting to $CNB_APP_DIR"
mkdir -p $CNB_APP_DIR
cd $CNB_APP_DIR
tar -xzf "$COMPRESSED_APP_LOCATION"
# Detecting runtime stack and setting correct oryx runtime image.
runtime_stack=$(oryx dockerfile . | head -n 1 | sed 's/ARG RUNTIME=//')
export CNB_RUN_IMAGE="mcr.microsoft.com/oryx/$runtime_stack"
# Retrieving the acr access token for Bearer authentication per:
# https://github.com/Azure/acr/blob/main/docs/Token-BasicAuth.md#calling-an-azure-container-registry-api
# https://github.com/Azure/acr/blob/main/docs/AAD-OAuth.md#getting-credentials-programmatically
aad_access_token=$(curl -H "X-IDENTITY-HEADER: $IDENTITY_HEADER" \
"$IDENTITY_ENDPOINT?resource=$MANAGEMENT_RESOURCE_URI&principal_id=$MI_PRINCIPAL_ID&api-version=2019-08-01" \
| jq -r '.access_token')
acr_refresh_token=$(curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d \
"grant_type=access_token&service=$ACR_RESOURCE_NAME&tenant=$TENANT_ID&access_token=$aad_access_token" \
https://$ACR_RESOURCE_NAME/oauth2/exchange \
| jq -r '.refresh_token')
acr_access_token=$(curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d \
"grant_type=refresh_token&service=$ACR_RESOURCE_NAME&scope=$ACR_SCOPE&refresh_token=$acr_refresh_token" \
https://$ACR_RESOURCE_NAME/oauth2/token \
| jq -r '.access_token')
export CNB_REGISTRY_AUTH='{"'$ACR_RESOURCE_NAME'":"Bearer '$acr_access_token'"}'
# Execute the buildpack build using the /cnb/lifecycle/creator command.
# https://github.com/buildpacks/spec/blob/main/platform.md#creator
exec /lifecycle/creator --log-level=debug $APP_IMAGE

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

@ -0,0 +1,154 @@
ARG DEBIAN_FLAVOR
# 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
ARG SDK_STORAGE_BASE_URL_VALUE="https://oryx-cdn.microsoft.io"
ARG AI_CONNECTION_STRING
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=${SDK_STORAGE_BASE_URL_VALUE} \
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" \
LANGUAGE="C.UTF-8" \
LC_ALL="C.UTF-8" \
ORYX_AI_CONNECTION_STRING="${AI_CONNECTION_STRING}" \
DOTNET_SKIP_FIRST_TIME_EXPERIENCE="1"
# Install an assortment of traditional tooling (unicode, SSL, HTTP, etc.)
RUN if [ "${DEBIAN_FLAVOR}" = "buster" ]; then \
apt-get update \
&& apt-get install -y --no-install-recommends \
libicu63 \
libcurl4 \
libssl1.1 \
&& rm -rf /var/lib/apt/lists/* ; \
elif [ "${DEBIAN_FLAVOR}" = "bullseye" ]; then \
apt-get update \
&& apt-get install -y --no-install-recommends \
libicu67 \
libcurl4 \
libssl1.1 \
libyaml-dev \
libxml2 \
&& rm -rf /var/lib/apt/lists/* ; \
else \
apt-get update \
&& apt-get install -y --no-install-recommends \
libcurl3 \
libicu57 \
liblttng-ust0 \
libssl1.0.2 \
&& rm -rf /var/lib/apt/lists/* ; \
fi
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
# .NET Core dependencies for running Oryx
libc6 \
libgcc1 \
libgssapi-krb5-2 \
libstdc++6 \
zlib1g \
libunwind8 \
rsync \
libgdiplus \
# Required for mysqlclient
default-libmysqlclient-dev \
# PHP pre-reqs
ca-certificates \
libargon2-0 \
libcurl4-openssl-dev \
libedit-dev \
libonig-dev \
libncurses6 \
libsodium-dev \
libsqlite3-dev \
libxml2-dev \
xz-utils \
# ruby pre-req
libyaml-dev \
&& 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-builder" > /opt/oryx/.imagetype \
&& echo "DEBIAN|${DEBIAN_FLAVOR}" | tr '[a-z]' '[A-Z]' > /opt/oryx/.ostype
# Install Hugo and Yarn for node applications
ARG BUILD_DIR="/opt/tmp/build"
ARG IMAGES_DIR="/opt/tmp/images"
RUN ${IMAGES_DIR}/build/installHugo.sh
RUN set -ex \
&& yarnCacheFolder="/usr/local/share/yarn-cache" \
&& mkdir -p $yarnCacheFolder \
&& chmod 777 $yarnCacheFolder \
&& . ${BUILD_DIR}/__nodeVersions.sh \
&& ${IMAGES_DIR}/receiveGpgKeys.sh 6A010C5166006599AA17F08146C2130DFD2497F5 \
&& ${IMAGES_DIR}/retry.sh "curl -fsSLO --compressed https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \
&& ${IMAGES_DIR}/retry.sh "curl -fsSLO --compressed https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz.asc" \
&& gpg --batch --verify yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz \
&& mkdir -p /opt/yarn \
&& tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/yarn \
&& mv /opt/yarn/yarn-v$YARN_VERSION /opt/yarn/$YARN_VERSION \
&& rm yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz
RUN set -ex \
&& . ${BUILD_DIR}/__nodeVersions.sh \
&& ln -s $YARN_VERSION /opt/yarn/stable \
&& ln -s $YARN_VERSION /opt/yarn/latest \
&& ln -s $YARN_VERSION /opt/yarn/$YARN_MINOR_VERSION \
&& ln -s $YARN_MINOR_VERSION /opt/yarn/$YARN_MAJOR_VERSION
RUN set -ex \
&& mkdir -p /links \
&& cp -s /opt/yarn/stable/bin/yarn /opt/yarn/stable/bin/yarnpkg /links
# Install Python tooling for some .NET (e.g., Blazor) and node applications
RUN set -ex \
# Upgrade system python
&& PYTHONIOENCODING="UTF-8" \
&& apt-get update \
&& apt-get upgrade -y \
&& apt-get install -y --no-install-recommends \
git \
make \
unzip \
build-essential \
libpq-dev \
moreutils \
python3-pip \
rsync \
swig \
tk-dev \
unixodbc-dev \
uuid-dev \
&& rm -rf /var/lib/apt/lists/*
# Install Python 3.8 to use in some .NET and node applications
RUN tmpDir="/opt/tmp" \
&& imagesDir="$tmpDir/images" \
&& buildDir="$tmpDir/build" \
&& cp -f $tmpDir/images/build/benv.sh /opt/oryx/benv \
&& cp -f $tmpDir/images/build/logger.sh /opt/oryx/logger \
&& chmod +x /opt/oryx/benv \
&& chmod +x /opt/oryx/logger \
&& mkdir -p /usr/local/share/pip-cache/lib \
&& chmod -R 777 /usr/local/share/pip-cache \
&& pip3 install pip --upgrade \
&& pip install --upgrade cython \
&& pip3 install --upgrade cython \
&& . $buildDir/__pythonVersions.sh \
&& $imagesDir/installPlatform.sh python $PYTHON38_VERSION \
&& [ -d "/opt/python/$PYTHON38_VERSION" ] && echo /opt/python/$PYTHON38_VERSION/lib >> /etc/ld.so.conf.d/python.conf \
&& ldconfig \
&& cd /opt/python \
&& ln -s $PYTHON38_VERSION 3.8 \
&& ln -s $PYTHON38_VERSION latest \
&& ln -s $PYTHON38_VERSION stable
ENTRYPOINT [ "benv" ]

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

@ -127,7 +127,7 @@ namespace Microsoft.Oryx.BuildScriptGenerator
var snippet = new StringBuilder();
snippet
.AppendLine()
.AppendLine($"if grep -q -e cli \"/opt/oryx/.imagetype\" -e jamstack \"/opt/oryx/.imagetype\"; then")
.AppendLine($"if grep -q -e '^cli$' \"/opt/oryx/.imagetype\" -e '^jamstack$' \"/opt/oryx/.imagetype\"; then")
.AppendCommonSkeletonDepenendenciesInstallation()
.AppendPlatformSpecificSkeletonDepenendenciesInstallation(this)
.AppendLine("fi")

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

@ -92,6 +92,17 @@ namespace Microsoft.Oryx.BuildImage.Tests
appName, runtimeVersion, _imageHelper.GetCliImage(ImageTestHelperConstants.CliBullseyeTag));
}
[Theory, Trait("category", "cli-builder-bullseye")]
[InlineData(NetCore6PreviewWebApp, "6.0")]
[InlineData(NetCoreApp70WebApp, "7.0")]
public void BuildsApplication_ByDynamicallyInstallingSDKs_CliBuilderBullseye(
string appName,
string runtimeVersion)
{
BuildsApplication_ByDynamicallyInstallingSDKs(
appName, runtimeVersion, _imageHelper.GetCliBuilderImage(ImageTestHelperConstants.CliBuilderBullseyeTag));
}
private void BuildsApplication_ByDynamicallyInstallingSDKs(
string appName,
string runtimeVersion,

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

@ -57,6 +57,13 @@ namespace Microsoft.Oryx.BuildImage.Tests
InstallsHugoVersionDynamically_UsingEnvironmentVariable_AndBuildsApp(imageTestHelper.GetCliImage(ImageTestHelperConstants.CliBullseyeTag));
}
[Fact, Trait("category", "cli-builder-bullseye")]
public void PipelineTestInvocationCliBuilderBullseye()
{
var imageTestHelper = new ImageTestHelper();
InstallsHugoVersionDynamically_UsingEnvironmentVariable_AndBuildsApp(imageTestHelper.GetCliBuilderImage(ImageTestHelperConstants.CliBuilderBullseyeTag));
}
private void InstallsHugoVersionDynamically_UsingEnvironmentVariable_AndBuildsApp(string imageName)
{
// Please note:

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

@ -64,6 +64,13 @@ namespace Microsoft.Oryx.BuildImage.Tests
BuildsMavenArcheTypeSampleWithDynamicInstallation(version, _imageHelper.GetCliImage(ImageTestHelperConstants.CliBullseyeTag));
}
[Theory, Trait("category", "cli-builder-bullseye")]
[MemberData(nameof(VersionsData))]
public void BuildsMavenArcheTypeSampleWithDynamicInstallationCliBuilderBullseye(string version)
{
BuildsMavenArcheTypeSampleWithDynamicInstallation(version, _imageHelper.GetCliBuilderImage(ImageTestHelperConstants.CliBuilderBullseyeTag));
}
private void BuildsMavenArcheTypeSampleWithDynamicInstallation(string version, string imageName)
{
// Arrange

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

@ -74,6 +74,19 @@ namespace Microsoft.Oryx.BuildImage.Tests
}
}
public static TheoryData<string, string> ImageNameDataCliBuilderBullseye
{
get
{
var data = new TheoryData<string, string>();
var imageTestHelper = new ImageTestHelper();
data.Add("12.22.11", imageTestHelper.GetCliBuilderImage(ImageTestHelperConstants.CliBuilderBullseyeTag));
data.Add("14.19.1", imageTestHelper.GetCliBuilderImage(ImageTestHelperConstants.CliBuilderBullseyeTag));
data.Add("16.14.2", imageTestHelper.GetCliBuilderImage(ImageTestHelperConstants.CliBuilderBullseyeTag));
return data;
}
}
[Theory, Trait("category", "githubactions")]
[Trait("build-image", "github-actions-debian-stretch")]
@ -107,6 +120,13 @@ namespace Microsoft.Oryx.BuildImage.Tests
GeneratesScript_AndBuildNodeAppsWithDynamicInstallation(version, buildImageName);
}
[Theory, Trait("category", "cli-builder-bullseye")]
[MemberData(nameof(ImageNameDataCliBuilderBullseye))]
public void GeneratesScript_AndBuildNodeAppsWithDynamicInstallationCliBuilderBullseye(string version, string buildImageName)
{
GeneratesScript_AndBuildNodeAppsWithDynamicInstallation(version, buildImageName);
}
private void GeneratesScript_AndBuildNodeAppsWithDynamicInstallation(string version, string buildImageName)
{
// Arrange

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

@ -108,6 +108,26 @@ namespace Microsoft.Oryx.BuildImage.Tests
return data;
}
}
public static TheoryData<string, string, string> VersionAndImageNameDataCliBuilderBullseye
{
get
{
var data = new TheoryData<string, string, string>();
var imageHelper = new ImageTestHelper();
data.Add(PhpVersions.Php74Version, imageHelper.GetCliBuilderImage(ImageTestHelperConstants.CliBuilderBullseyeTag), PhpVersions.ComposerVersion);
data.Add(PhpVersions.Php80Version, imageHelper.GetCliBuilderImage(ImageTestHelperConstants.CliBuilderBullseyeTag), PhpVersions.ComposerVersion);
data.Add(PhpVersions.Php81Version, imageHelper.GetCliBuilderImage(ImageTestHelperConstants.CliBuilderBullseyeTag), PhpVersions.ComposerVersion);
data.Add(PhpVersions.Php82Version, imageHelper.GetCliBuilderImage(ImageTestHelperConstants.CliBuilderBullseyeTag), PhpVersions.ComposerVersion);
// test latest php-composer version
data.Add(PhpVersions.Php74Version, imageHelper.GetCliBuilderImage(ImageTestHelperConstants.CliBuilderBullseyeTag), PhpVersions.Composer23Version);
data.Add(PhpVersions.Php80Version, imageHelper.GetCliBuilderImage(ImageTestHelperConstants.CliBuilderBullseyeTag), PhpVersions.Composer23Version);
data.Add(PhpVersions.Php81Version, imageHelper.GetCliBuilderImage(ImageTestHelperConstants.CliBuilderBullseyeTag), PhpVersions.Composer23Version);
data.Add(PhpVersions.Php82Version, imageHelper.GetCliBuilderImage(ImageTestHelperConstants.CliBuilderBullseyeTag), PhpVersions.Composer23Version);
return data;
}
}
[Theory, Trait("category", "githubactions")]
@ -138,6 +158,13 @@ namespace Microsoft.Oryx.BuildImage.Tests
BuildsAppByInstallingSdkDynamically(phpVersion, imageName, phpComposerVersion, "/opt/php");
}
[Theory, Trait("category", "cli-builder-bullseye")]
[MemberData(nameof(VersionAndImageNameDataCliBuilderBullseye))]
public void BuildsAppByInstallingSdkDynamicallyCliBuilderBullseye(string phpVersion, string imageName, string phpComposerVersion)
{
BuildsAppByInstallingSdkDynamically(phpVersion, imageName, phpComposerVersion, "/opt/php");
}
private void BuildsAppByInstallingSdkDynamically(
string phpVersion,
string imageName,

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

@ -74,6 +74,16 @@ namespace Microsoft.Oryx.BuildImage.Tests
GeneratesScript_AndBuildsPython_FlaskApp(imageTestHelper.GetCliImage(ImageTestHelperConstants.CliBullseyeTag), "3.9.0", "/opt");
}
[Fact, Trait("category", "cli-builder-bullseye")]
public void PipelineTestInvocationCliBuilderBullseye()
{
var imageTestHelper = new ImageTestHelper();
GeneratesScript_AndBuildsPython_FlaskApp(
imageTestHelper.GetCliBuilderImage(ImageTestHelperConstants.CliBuilderBullseyeTag), PythonVersions.Python39Version, "/opt");
GeneratesScript_AndBuildsPython_FlaskApp(
imageTestHelper.GetCliBuilderImage(ImageTestHelperConstants.CliBuilderBullseyeTag), PythonVersions.Python310Version, "/opt");
}
private void GeneratesScript_AndBuildsPython_FlaskApp(
string imageName,
string version,

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

@ -74,6 +74,17 @@ namespace Microsoft.Oryx.BuildImage.Tests
RubyVersions.Ruby31Version, imageTestHelper.GetCliImage(imageTag));
}
[Theory, Trait("category", "cli-builder-bullseye")]
[InlineData(ImageTestHelperConstants.CliBuilderBullseyeTag)]
public void PipelineTestInvocationCliBuilderBullseye(string imageTag)
{
var imageTestHelper = new ImageTestHelper();
GeneratesScript_AndBuildSinatraAppWithDynamicInstall(
RubyVersions.Ruby30Version, imageTestHelper.GetCliBuilderImage(imageTag));
GeneratesScript_AndBuildSinatraAppWithDynamicInstall(
RubyVersions.Ruby31Version, imageTestHelper.GetCliBuilderImage(imageTag));
}
private void GeneratesScript_AndBuildSinatraAppWithDynamicInstall(string version, string buildImageName)
{
// Please note:

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

@ -50,6 +50,7 @@ namespace Microsoft.Oryx.Tests.Common
private const string _cliStretchTag = ImageTestHelperConstants.CliStretchTag;
private const string _cliBusterTag = ImageTestHelperConstants.CliBusterTag;
private const string _cliBullseyeTag = ImageTestHelperConstants.CliBullseyeTag;
private const string _cliBuilderBullseyeTag = ImageTestHelperConstants.CliBuilderBullseyeTag;
private const string _latestTag = ImageTestHelperConstants.LatestStretchTag;
private const string _ltsVersionsStretch = ImageTestHelperConstants.LtsVersionsStretch;
private const string _ltsVersionsBuster = ImageTestHelperConstants.LtsVersionsBuster;
@ -254,6 +255,10 @@ namespace Microsoft.Oryx.Tests.Common
{
return GetCliImage(_cliBullseyeTag);
}
else if(string.Equals(tag, _cliBuilderBullseyeTag))
{
return GetCliBuilderImage(_cliBuilderBullseyeTag);
}
else if (string.Equals(tag, _fullStretch))
{
return GetFullBuildImage(_fullStretch);
@ -405,6 +410,23 @@ namespace Microsoft.Oryx.Tests.Common
return $"{_repoPrefix}/{_cliRepository}:{_cliStretchTag}{_tagSuffix}";
}
/// <summary>
/// Constructs a 'cli' image using either the default image base (oryxdevmcr.azurecr.io/public/oryx), or the
/// base set by the ORYX_TEST_IMAGE_BASE environment variable. If a tag suffix was set with the environment
/// variable ORYX_TEST_TAG_SUFFIX, it will be used as the tag, otherwise, the 'latest' tag will be used.
/// </summary>
/// <returns>A 'cli builder' image that can be pulled for testing.</returns>
public string GetCliBuilderImage(string imageTagPrefix = null)
{
if (!string.IsNullOrEmpty(imageTagPrefix)
&& string.Equals(imageTagPrefix.ToLower(), _cliBuilderBullseyeTag))
{
return $"{_repoPrefix}/{_cliRepository}:{_cliBuilderBullseyeTag}{_tagSuffix}";
}
throw new ArgumentException($"Could not find cli builder image with image tag prefix '{imageTagPrefix}'.");
}
private string GetTestTag()
{
if (string.IsNullOrEmpty(_tagSuffix))
@ -492,6 +514,7 @@ namespace Microsoft.Oryx.Tests.Common
public const string CliStretchTag = "debian-stretch";
public const string CliBusterTag = "debian-buster";
public const string CliBullseyeTag = "debian-bullseye";
public const string CliBuilderBullseyeTag = "builder-debian-bullseye";
public const string LatestStretchTag = "debian-stretch";
public const string LtsVersionsStretch = "lts-versions-debian-stretch";
public const string LtsVersionsBuster = "lts-versions-debian-buster";

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

@ -38,6 +38,9 @@ parameters:
-
key: CliBullseye
value: cli-bullseye
-
key: CliBuilderBullseye
value: cli-builder-bullseye
-
key: Buildpack
value: buildpack
@ -147,6 +150,9 @@ stages:
echo "##vso[task.setvariable variable=PushRuntimeImages;]false"
echo "##vso[task.setvariable variable=EmbedBuildContextInImages;]true"
echo "##vso[task.setvariable variable=storageAccountUrl;]${{ parameters.storageAccountUrl }}"
if [[ "${{ buildImage.value }}" =~ "cli-builder" ]]; then
echo "##vso[task.setvariable variable=PushBuilderImages;]true"
fi
displayName: 'Set variables'
- template: templates/_setReleaseTag.yml
@ -155,6 +161,17 @@ stages:
parameters:
imageType: ${{ buildImage.value }}
- job: Job_BuilderImages
displayName: Build Builder Images
pool:
name: AzurePipelines-EO
demands:
- ImageOverride -equals AzurePipelinesUbuntu20.04compliant
timeoutInMinutes: 480
steps:
- template: templates/_builderTemplate.yml
dependsOn: Job_BuildImage_CliBuilderBullseye
- job: Job_RuntimeImages
displayName: Build and Test Runtime Images
dependsOn: Job_SignBinaries

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

@ -36,6 +36,9 @@ parameters:
-
key: CliBullseye
value: cli-bullseye
-
key: CliBuilderBullseye
value: cli-builder-bullseye
-
key: Buildpack
value: buildpack
@ -107,11 +110,25 @@ stages:
echo "##vso[task.setvariable variable=EmbedBuildContextInImages;]true"
echo "##vso[task.setvariable variable=RELEASE_TAG_NAME;]$(Build.BuildNumber)"
echo "##vso[task.setvariable variable=storageAccountUrl;]${{ parameters.storageAccountUrl }}"
if [[ "${{ buildImage.value }}" =~ "cli-builder" ]]; then
echo "##vso[task.setvariable variable=PushBuilderImages;]true"
fi
displayName: 'Set variables'
- template: templates/_buildTemplate.yml
parameters:
imageType: ${{ buildImage.value }}
- job: Job_BuilderImages
displayName: Build Builder Images
pool:
name: AzurePipelines-EO
demands:
- ImageOverride -equals AzurePipelinesUbuntu20.04compliant
timeoutInMinutes: 480
steps:
- template: templates/_builderTemplate.yml
dependsOn: Job_BuildImage_CliBuilderBullseye
- job: Job_RuntimeImages
displayName: Build and Test Runtime Images
condition: succeeded()

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

@ -221,7 +221,7 @@ steps:
imageNamesPath: '$(Build.ArtifactStagingDirectory)/images/build-images-acr.txt'
includeLatestTag: false
enforceDockerNamingConvention: false
condition: and(succeeded(), eq(variables['PushBuildImages'], 'true'), eq(variables['BuildBuildImages'], 'true'))
condition: and(succeeded(), or(eq(variables['PushBuildImages'], 'true'), eq(variables['PushBuilderImages'], 'true')), eq(variables['BuildBuildImages'], 'true'))
- task: Docker@1
displayName: 'Push runtime images to ACR'

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

@ -0,0 +1,58 @@
parameters:
ascName: oryx-automation-service-principal
acrName: oryxdevmcr.azurecr.io
steps:
- script: |
curl -sSL "https://github.com/buildpacks/pack/releases/download/v0.28.0/pack-v0.28.0-linux.tgz" | tar -C /usr/local/bin/ --no-same-owner -xzv pack
displayName: 'Install Pack CLI'
condition: true
- task: Docker@1
displayName: Container registry login
inputs:
command: login
azureSubscriptionEndpoint: ${{ parameters.ascName }}
azureContainerRegistry: ${{ parameters.acrName }}
- task: ShellScript@2
displayName: 'Build base builder images'
inputs:
scriptPath: ./builders/base/buildBaseBuilder.sh
args: -f ${{ parameters.acrName }} -r "public/oryx/builder" -v $(Build.DefinitionName).$(Build.BuildNumber)
- task: ShellScript@2
displayName: 'Build container apps builder images'
inputs:
scriptPath: ./builders/container-apps/buildCappsBuilder.sh
args: -f ${{ parameters.acrName }} -r "public/oryx/builder" -t "capps-$(Build.DefinitionName).$(Build.BuildNumber)" -b "${{ parameters.acrName }}/public/oryx/builder:$(Build.DefinitionName).$(Build.BuildNumber)"
- task: CopyFiles@2
displayName: 'Copy artifacts from source repo to agent artifacts folder'
inputs:
sourceFolder: '$(Build.SourcesDirectory)/artifacts'
contents: '**/*.*'
targetFolder: $(Build.ArtifactStagingDirectory)
overWrite: true
- task: Docker@1
displayName: 'Push base build images to ACR'
inputs:
azureSubscriptionEndpoint: ${{ parameters.ascName }}
azureContainerRegistry: ${{ parameters.acrName }}
command: 'Push an image'
pushMultipleImages: true
imageNamesPath: '$(Build.ArtifactStagingDirectory)/images/builder-images-acr.txt'
includeLatestTag: false
enforceDockerNamingConvention: false
- task: Docker@1
displayName: 'Push container apps builder images to ACR'
inputs:
azureSubscriptionEndpoint: ${{ parameters.ascName }}
azureContainerRegistry: ${{ parameters.acrName }}
command: 'Push an image'
pushMultipleImages: true
imageNamesPath: '$(Build.ArtifactStagingDirectory)/images/capps-builder-images-acr.txt'
includeLatestTag: false
enforceDockerNamingConvention: false

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

@ -107,6 +107,13 @@ steps:
scriptPath: ./vsts/scripts/tagCliImagesForRelease.sh
condition: and(succeeded(), eq(variables['ReleaseBuildImages'], 'true'))
- task: ms-devlabs.utilitytasks.task-Shellpp.Shell++@0
displayName: 'Pull and create release tags for Builder images'
inputs:
type: FilePath
scriptPath: ./vsts/scripts/tagBuilderImagesForRelease.sh
condition: and(succeeded(), eq(variables['ReleaseBuildImages'], 'true'))
- task: UseDotNet@2
displayName: 'Use .NET Core sdk 3.1.x'
inputs:
@ -156,6 +163,14 @@ steps:
args: '$(Build.ArtifactStagingDirectory)/drop/images/${{ parameters.acrPmeProdName }}-cli-images-mcr.txt'
condition: and(succeeded(), eq(variables['ReleaseBuildImages'], 'true'))
- task: ms-devlabs.utilitytasks.task-Shellpp.Shell++@0
displayName: 'Push builder images to PME staging ACR'
inputs:
type: FilePath
scriptPath: ./vsts/scripts/pushImagesToRegistry.sh
args: '$(Build.ArtifactStagingDirectory)/drop/images/${{ parameters.acrPmeProdName }}-builder-images-mcr.txt'
condition: and(succeeded(), eq(variables['ReleaseBuildImages'], 'true'))
- task: ms-devlabs.utilitytasks.task-Shellpp.Shell++@0
displayName: 'Push runtime images to PME staging ACR'
inputs:

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

@ -36,6 +36,9 @@ parameters:
-
key: CliBullseye
value: cli-bullseye
-
key: CliBuilderBullseye
value: cli-builder-bullseye
-
key: Buildpack
value: buildpack
@ -74,11 +77,25 @@ jobs:
echo "##vso[task.setvariable variable=EmbedBuildContextInImages;]true"
echo "##vso[task.setvariable variable=RELEASE_TAG_NAME;]$(Build.BuildNumber)"
echo "##vso[task.setvariable variable=storageAccountUrl;]${{ parameters.storageAccountUrl }}"
if [[ "${{ buildImage.value }}" =~ "cli-builder" ]]; then
echo "##vso[task.setvariable variable=PushBuilderImages;]true"
fi
displayName: 'Set variables'
- template: templates/_buildTemplate.yml
parameters:
imageType: ${{ buildImage.value }}
- job: Job_BuilderImages
displayName: Build Builder Images
pool:
name: AzurePipelines-EO
demands:
- ImageOverride -equals AzurePipelinesUbuntu20.04compliant
timeoutInMinutes: 480
steps:
- template: templates/_builderTemplate.yml
dependsOn: Job_BuildImage_CliBuilderBullseye
- job: Job_RuntimeImages
displayName: Build and Test Runtime Images
pool:

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

@ -85,6 +85,9 @@ if [ -n "$TESTINTEGRATIONCASEFILTER" ];then
elif [[ "$strippedVal" == "cli-debian-bullseye" ]];then
buildImageFilter="cli"
buildImageTagFilter="debian-bullseye"
elif [[ "$strippedVal" == "cli-builder-debian-bullseye" ]];then
buildImageFilter="cli"
buildImageTagFilter="builder-debian-bullseye"
fi
fi
done
@ -108,6 +111,7 @@ tagBuildImageForIntegrationTest "$imagefilter/build" "full-debian-bullseye" "$bu
tagBuildImageForIntegrationTest "$imagefilter/cli" "debian-stretch" "$buildImageFilter" "$buildImageTagFilter"
tagBuildImageForIntegrationTest "$imagefilter/cli" "debian-buster" "$buildImageFilter" "$buildImageTagFilter"
tagBuildImageForIntegrationTest "$imagefilter/cli" "debian-bullseye" "$buildImageFilter" "$buildImageTagFilter"
tagBuildImageForIntegrationTest "$imagefilter/cli" "builder-debian-bullseye" "$buildImageFilter" "$buildImageTagFilter"
tagBuildImageForIntegrationTest "$imagefilter/pack" "" "$buildImageFilter" "$buildImageTagFilter"

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

@ -0,0 +1,55 @@
#!/bin/bash
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT license.
# --------------------------------------------------------------------------------------------
set -exo pipefail
declare -r REPO_DIR=$( cd $( dirname "$0" ) && cd .. && cd .. && pwd )
source $REPO_DIR/build/__variables.sh
outPmeFileMCR="$BUILD_ARTIFACTSTAGINGDIRECTORY/drop/images/oryxprodmcr-builder-images-mcr.txt"
if [ -f "$outPmeFileMCR" ]; then
rm $outPmeFileMCR
fi
function tagBuilderImage() {
local devRegistryImageName="$1"
local prodRegistryLatestTagName="$2"
local prodRegistrySpecificTagName="$3"
local prodPmeRegistryRepoName="oryxprodmcr.azurecr.io/public/oryx/builder"
sourceBranchName=$BUILD_SOURCEBRANCHNAME
echo "Pulling the source image $devRegistryImageName..."
docker pull "$devRegistryImageName" | sed 's/^/ /'
echo
echo "Tagging the source image for $prodPmeRegistryRepoName with tag $prodRegistrySpecificTagName..."
prodPmeRegistryImageName="$prodPmeRegistryRepoName:$prodRegistrySpecificTagName"
docker tag "$devRegistryImageName" "$prodPmeRegistryImageName"
echo "$prodPmeRegistryImageName">>"$outPmeFileMCR"
if [ "$sourceBranchName" == "main" ]; then
echo "Tagging the source image for $prodPmeRegistryRepoName with tag $prodRegistryLatestTagName..."
prodPmeRegistryImageName="$prodPmeRegistryRepoName:$prodRegistryLatestTagName"
docker tag "$devRegistryImageName" "$prodPmeRegistryRepoName:$prodRegistryLatestTagName"
echo "$prodPmeRegistryImageName">>"$outPmeFileMCR"
else
echo "Not creating 'latest' tag as source branch is not 'main'. Current branch is $sourceBranchName"
fi
echo -------------------------------------------------------------------------------
}
tagBuilderImage "$ACR_PUBLIC_PREFIX/builder:$BUILD_DEFINITIONNAME.$RELEASE_TAG_NAME" "latest" "$RELEASE_TAG_NAME"
tagBuilderImage "$ACR_PUBLIC_PREFIX/builder:capps-$BUILD_DEFINITIONNAME.$RELEASE_TAG_NAME" "capps" "capps-$RELEASE_TAG_NAME"
tagBuilderImage "$ACR_PUBLIC_PREFIX/builder:stack-base-$BUILD_DEFINITIONNAME.$RELEASE_TAG_NAME" "stack-base" "stack-base-$RELEASE_TAG_NAME"
tagBuilderImage "$ACR_PUBLIC_PREFIX/builder:stack-build-$BUILD_DEFINITIONNAME.$RELEASE_TAG_NAME" "stack-build" "stack-build-$RELEASE_TAG_NAME"
tagBuilderImage "$ACR_PUBLIC_PREFIX/builder:stack-run-$BUILD_DEFINITIONNAME.$RELEASE_TAG_NAME" "stack-run" "stack-run-$RELEASE_TAG_NAME"
echo "printing pme tags from $outPmeFileMCR"
cat $outPmeFileMCR
echo -------------------------------------------------------------------------------

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

@ -19,6 +19,7 @@ if [ -f "$outPmeFile" ]; then
rm $outPmeFile
fi
# CLI Images
cliImage="$sourceImageRepo/cli:debian-stretch-$BUILD_DEFINITIONNAME.$RELEASE_TAG_NAME"
cliBusterImage="$sourceImageRepo/cli:debian-buster-$BUILD_DEFINITIONNAME.$RELEASE_TAG_NAME"
cliBullseyeImage="$sourceImageRepo/cli:debian-bullseye-$BUILD_DEFINITIONNAME.$RELEASE_TAG_NAME"
@ -43,6 +44,18 @@ echo "Retagging CLI bullseye image for $prodPmeImageRepo with 'debian-bullseye-$
echo "$prodPmeImageRepo/cli:debian-bullseye-$RELEASE_TAG_NAME">>"$outPmeFile"
docker tag "$cliBullseyeImage" "$prodPmeImageRepo/cli:debian-bullseye-$RELEASE_TAG_NAME"
# CLI Builder images
devCliBuilderBullseyeImage="$sourceImageRepo/cli:builder-debian-bullseye-$BUILD_DEFINITIONNAME.$RELEASE_TAG_NAME"
builderProdTag="builder-debian-bullseye-$RELEASE_TAG_NAME"
builderProdStableTag="builder-debian-bullseye-stable"
prodCliBuilderBullseyeImage="$prodPmeImageRepo/cli:$builderProdTag"
echo "Pulling CLI builder bullseye image '$devCliBuilderBullseyeImage'..."
docker pull "$devCliBuilderBullseyeImage"
echo "Retagging CLI builder bullseye image for '$prodPmeImageRepo/cli' with '$builderProdTag'..."
echo "$prodCliBuilderBullseyeImage">>"$outPmeFile"
docker tag "$devCliBuilderBullseyeImage" "$prodCliBuilderBullseyeImage"
if [ "$sourceBranchName" == "main" ]; then
echo "Retagging CLI image with '{os type}-stable'..."
@ -54,6 +67,9 @@ if [ "$sourceBranchName" == "main" ]; then
docker tag "$cliBullseyeImage" "$prodPmeImageRepo/cli:debian-bullseye-stable"
echo "$prodPmeImageRepo/cli:debian-bullseye-stable">>"$outPmeFile"
docker tag "$devCliBuilderBullseyeImage" "$prodPmeImageRepo/cli:$builderProdStableTag"
echo "$prodPmeImageRepo/cli:$builderProdStableTag">>"$outPmeFile"
else
echo "Not creating 'stable' or 'latest' tags as source branch is not 'main'. Current branch is $sourceBranchName"
fi