diff --git a/.dockerignore b/.dockerignore index 46e140101cf..48ae73ade65 100644 --- a/.dockerignore +++ b/.dockerignore @@ -10,6 +10,8 @@ !az.completion # Make an exception for the license file !LICENSE.txt +# Make an exception for Azure CLI RPMs +!docker-temp/* # Exclude build droppings, as mentioned in .gitignore src/build* # Exclude tests diff --git a/Dockerfile b/alpine.dockerfile similarity index 94% rename from Dockerfile rename to alpine.dockerfile index f723c87baca..003c3a0834f 100644 --- a/Dockerfile +++ b/alpine.dockerfile @@ -18,7 +18,7 @@ LABEL maintainer="Microsoft" \ org.label-schema.name="Azure CLI" \ org.label-schema.version=$CLI_VERSION \ org.label-schema.license="MIT" \ - org.label-schema.description="The Azure CLI is used for all Resource Manager deployments in Azure." \ + org.label-schema.description="A great cloud needs great tools; we're excited to introduce Azure CLI, our next generation multi-platform command line experience for Azure." \ org.label-schema.url="https://docs.microsoft.com/cli/azure/overview" \ org.label-schema.usage="https://docs.microsoft.com/cli/azure/install-az-cli2#docker" \ org.label-schema.build-date=$BUILD_DATE \ diff --git a/azure-linux.dockerfile b/azure-linux.dockerfile new file mode 100644 index 00000000000..856c53547bd --- /dev/null +++ b/azure-linux.dockerfile @@ -0,0 +1,31 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- + +FROM mcr.microsoft.com/cbl-mariner/base/core:2.0 + +ARG CLI_VERSION + +# Metadata as defined at http://label-schema.org +ARG BUILD_DATE + +LABEL maintainer="Microsoft" \ + org.label-schema.schema-version="1.0" \ + org.label-schema.vendor="Microsoft" \ + org.label-schema.name="Azure CLI" \ + org.label-schema.version=$CLI_VERSION \ + org.label-schema.license="MIT" \ + org.label-schema.description="A great cloud needs great tools; we're excited to introduce Azure CLI, our next generation multi-platform command line experience for Azure." \ + org.label-schema.url="https://docs.microsoft.com/cli/azure/overview" \ + org.label-schema.usage="https://learn.microsoft.com/en-us/cli/azure/run-azure-cli-docker" \ + org.label-schema.build-date=$BUILD_DATE \ + org.label-schema.vcs-url="https://github.com/Azure/azure-cli.git" \ + org.label-schema.docker.cmd="docker run -v \${HOME}/.azure:/root/.azure -it mcr.microsoft.com/azure-cli:$CLI_VERSION-azure" + + +# Azure Linux base image does not contain Mozilla CA certificates, install ca-certificates package to prevent CERTIFICATE_VERIFY_FAILED errors, see https://github.com/Azure/azure-cli/issues/26026 +RUN --mount=type=bind,target=/azure-cli.rpm,source=./docker-temp/azure-cli.rpm tdnf install ca-certificates /azure-cli.rpm -y && tdnf clean all && rm -rf /var/cache/tdnf + +ENV AZ_INSTALLER=DOCKER +CMD bash diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 9c2a04b90d6..025c163a5a4 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -259,19 +259,15 @@ jobs: inputs: filePath: build_scripts\windows\scripts\test_msi_installation.ps1 -- job: BuildDockerImage - displayName: Build Docker Image - - dependsOn: ExtractMetadata - condition: succeeded() +- job: BuildDockerImageAlpine + displayName: Build Docker Image Alpine strategy: matrix: - AMD64: - pool: ${{ variables.ubuntu_pool }} - artifactName: docker-amd64 - ARM64: - pool: ${{ variables.ubuntu_arm64_pool }} - artifactName: docker-arm64 + ${{ each arch in parameters.architectures }}: + Alpine ${{ arch.name }}: + pool: ${{ arch.pool }} + artifactName: docker-${{ arch.value }} + dockerfile: alpine.dockerfile pool: name: $(pool) steps: @@ -295,19 +291,18 @@ jobs: TargetPath: $(Build.ArtifactStagingDirectory) ArtifactName: $(artifactName) -- job: TestDockerImage - displayName: Test Docker Image - - dependsOn: BuildDockerImage +- job: TestDockerImageAlpine + displayName: Test Docker Image Alpine + dependsOn: + - BuildDockerImageAlpine + - ExtractMetadata condition: succeeded() strategy: matrix: - AMD64: - pool: ${{ variables.ubuntu_pool }} - artifactName: docker-amd64 - ARM64: - pool: ${{ variables.ubuntu_arm64_pool }} - artifactName: docker-arm64 + ${{ each arch in parameters.architectures }}: + Alpine ${{ arch.name }}: + pool: ${{ arch.pool }} + artifactName: docker-${{ arch.name }} pool: name: $(pool) steps: @@ -317,7 +312,6 @@ jobs: TargetPath: '$(Build.ArtifactStagingDirectory)/metadata' artifactName: metadata - - task: DownloadPipelineArtifact@1 displayName: 'Download Docker Image' inputs: @@ -340,6 +334,88 @@ jobs: docker run $IMAGE_NAME /bin/bash -c "time az self-test && time az --version && sleep 5" displayName: 'Bash Script' +- job: BuildDockerImageAzureLinux + displayName: Build Docker Image Azure Linux + dependsOn: BuildRpmPackageMariner + strategy: + matrix: + ${{ each arch in parameters.architectures }}: + Mariner 2.0 ${{ arch.name }}: + pool: ${{ arch.pool }} + artifactName: docker-mariner2.0-${{ arch.value }} + dockerfile: azure-linux.dockerfile + packageArtifactName: rpm-mariner2.0-${{ arch.value }} + pool: + name: $(pool) + steps: + - bash: ./scripts/ci/install_docker.sh + displayName: Install Docker + - task: DownloadPipelineArtifact@1 + displayName: 'Download Build Artifacts' + inputs: + TargetPath: '$(Build.ArtifactStagingDirectory)/docker' + artifactName: $(packageArtifactName) + - bash: | + set -ex + mkdir docker-temp + mv $(Build.ArtifactStagingDirectory)/docker/*.rpm ./docker-temp/azure-cli.rpm + + bash scripts/release/docker/pipeline.sh + displayName: 'Build Docker' + + - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 + displayName: 'SBOM' + inputs: + BuildDropPath: $(Build.ArtifactStagingDirectory) + DockerImagesToScan: 'clibuild$BUILD_BUILDNUMBER:latest' + + - task: PublishPipelineArtifact@0 + inputs: + TargetPath: $(Build.ArtifactStagingDirectory) + ArtifactName: $(artifactName) + +- job: TestDockerImageAzureLinux + displayName: Test Docker Image Azure Linux + dependsOn: + - BuildDockerImageAzureLinux + - ExtractMetadata + strategy: + matrix: + ${{ each arch in parameters.architectures }}: + Mariner 2.0 ${{ arch.name }}: + pool: ${{ arch.pool }} + artifactName: docker-mariner2.0-${{ arch.value }} + pool: + name: $(pool) + steps: + - task: DownloadPipelineArtifact@1 + displayName: 'Download Metadata' + inputs: + TargetPath: '$(Build.ArtifactStagingDirectory)/metadata' + artifactName: metadata + + - task: DownloadPipelineArtifact@1 + displayName: 'Download Docker Image' + inputs: + TargetPath: '$(Build.ArtifactStagingDirectory)/docker' + artifactName: $(artifactName) + + - bash: ./scripts/ci/install_docker.sh + displayName: Install Docker + + - bash: | + set -exv + + CLI_VERSION=`cat $SYSTEM_ARTIFACTSDIRECTORY/metadata/version` + IMAGE_NAME=clibuild$BUILD_BUILDNUMBER:latest + TAR_FILE=$SYSTEM_ARTIFACTSDIRECTORY/docker/docker-azure-cli-$CLI_VERSION.tar + + echo "== Test docker image ==" + + docker load < $TAR_FILE + docker run $IMAGE_NAME /bin/bash -c "time az self-test && time az --version && sleep 5" + displayName: 'Bash Script' + - job: BuildPythonWheel displayName: Build Python Wheels @@ -1098,8 +1174,10 @@ jobs: - VerifyVersions - BuildWindowsMSI - TestMsiInstallation - - BuildDockerImage - - TestDockerImage + - BuildDockerImageAlpine + - TestDockerImageAlpine + - BuildDockerImageAzureLinux + - TestDockerImageAzureLinux - BuildPythonWheel - TestPythonWheel - TestCore diff --git a/scripts/release/docker/pipeline.sh b/scripts/release/docker/pipeline.sh index 2050814e7d1..5a6dad3c443 100755 --- a/scripts/release/docker/pipeline.sh +++ b/scripts/release/docker/pipeline.sh @@ -13,6 +13,7 @@ docker build --no-cache \ --build-arg BUILD_DATE="`date -u +"%Y-%m-%dT%H:%M:%SZ"`" \ --build-arg CLI_VERSION=$CLI_VERSION \ --tag $IMAGE_NAME:latest \ + --file $DOCKERFILE \ $BUILD_SOURCESDIRECTORY docker save -o "$BUILD_STAGINGDIRECTORY/docker-azure-cli-${CLI_VERSION}.tar" $IMAGE_NAME:latest