From 3f4459ffd4e6c09d3dc75f4796b3dbb30494fe5c Mon Sep 17 00:00:00 2001 From: Chris Yan Date: Thu, 21 Oct 2021 16:28:34 -0700 Subject: [PATCH 1/3] Update Linux Docker container builds Signed-off-by: Chris Yan --- .../build_linux_docker_images.Jenkinsfile | 113 +++++++++++------- .../docker/dockerfiles/linux/Dockerfile | 11 +- 2 files changed, 74 insertions(+), 50 deletions(-) diff --git a/.jenkins/infrastructure/docker/build_linux_docker_images.Jenkinsfile b/.jenkins/infrastructure/docker/build_linux_docker_images.Jenkinsfile index 2c44d5798a..3584311d96 100644 --- a/.jenkins/infrastructure/docker/build_linux_docker_images.Jenkinsfile +++ b/.jenkins/infrastructure/docker/build_linux_docker_images.Jenkinsfile @@ -1,55 +1,90 @@ // Copyright (c) Open Enclave SDK contributors. // Licensed under the MIT License. -OECI_LIB_VERSION = env.OECI_LIB_VERSION ?: "master" -oe = library("OpenEnclaveCommon@${OECI_LIB_VERSION}").jenkins.common.Openenclave.new() +library "OpenEnclaveJenkinsLibrary@${params.OECI_LIB_VERSION}" -AGENTS_LABEL = params.AGENTS_LABEL -TIMEOUT_MINUTES = params.TIMEOUT_MINUTES ?: 240 - -INTERNAL_REPO = params.INTERNAL_REPO ?: "https://oejenkinscidockerregistry.azurecr.io" -INTERNAL_REPO_CREDS = params.INTERNAL_REPO_CREDS ?: "oejenkinscidockerregistry" -DOCKERHUB_REPO_CREDS = params.DOCKERHUB_REPO_CREDS ?: "oeciteamdockerhub" -LINUX_DOCKERFILE = ".jenkins/infrastructure/docker/dockerfiles/linux/Dockerfile" - -def buildLinuxDockerContainers() { - node(AGENTS_LABEL) { - timeout(TIMEOUT_MINUTES) { - stage("Checkout") { +pipeline { + agent { + label globalvars.AGENTS_LABELS["ubuntu-nonsgx"] + } + options { + timeout(time: 240, unit: 'MINUTES') + } + parameters { + string(name: "REPOSITORY_NAME", defaultValue: "openenclave/openenclave", description: "GitHub repository to checkout") + string(name: "BRANCH_NAME", defaultValue: "master", description: "The branch used to checkout the repository") + string(name: "DOCKER_TAG", defaultValue: "standalone-linux-build", description: "The tag for the new Docker images") + string(name: "INTERNAL_REPO", defaultValue: "https://oejenkinscidockerregistry.azurecr.io", description: "Url for internal Docker repository") + string(name: "OECI_LIB_VERSION", defaultValue: 'master', description: 'Version of OE Libraries to use') + booleanParam(name: "PUBLISH_DOCKER_HUB", defaultValue: false, description: "Publish container to OECITeam Docker Hub?") + booleanParam(name: "TAG_LATEST", defaultValue: false, description: "Update the latest tag to the currently built DOCKER_TAG") + } + environment { + INTERNAL_REPO_CREDS = 'oejenkinscidockerregistry' + DOCKERHUB_REPO_CREDS = 'oeciteamdockerhub' + LINUX_DOCKERFILE = ".jenkins/infrastructure/docker/dockerfiles/linux/Dockerfile" + } + stages { + stage("Checkout") { + steps { cleanWs() - checkout scm + checkout([$class: 'GitSCM', + branches: [[name: BRANCH_NAME]], + extensions: [], + userRemoteConfigs: [[url: "https://github.com/${params.REPOSITORY_NAME}"]]]) } - String buildArgs = oe.dockerBuildArgs("UID=\$(id -u)", "UNAME=\$(id -un)", - "GID=\$(id -g)", "GNAME=\$(id -gn)") - parallel "Build Ubuntu 18.04 Docker Image": { + } + stage("Build") { + parallel { stage("Build Ubuntu 18.04 Docker Image") { - oe1804 = oe.dockerImage("oetools-18.04:${DOCKER_TAG}", LINUX_DOCKERFILE, "${buildArgs} --build-arg ubuntu_version=18.04 --build-arg devkits_uri=${DEVKITS_URI}") - puboe1804 = oe.dockerImage("oeciteam/oetools-18.04:${DOCKER_TAG}", LINUX_DOCKERFILE, "${buildArgs} --build-arg ubuntu_version=18.04 --build-arg devkits_uri=${DEVKITS_URI}") + steps { + script { + docker.withRegistry(params.INTERNAL_REPO, env.INTERNAL_REPO_CREDS) { + buildArgs = common.dockerBuildArgs("UID=\$(id -u)", "UNAME=\$(id -un)", + "GID=\$(id -g)", "GNAME=\$(id -gn)") + oe1804 = common.dockerImage("oetools-18.04:${params.DOCKER_TAG}", env.LINUX_DOCKERFILE, "${buildArgs} --build-arg ubuntu_version=18.04") + puboe1804 = common.dockerImage("oeciteam/oetools-18.04:${params.DOCKER_TAG}", env.LINUX_DOCKERFILE, "${buildArgs} --build-arg ubuntu_version=18.04") + } + } + } } - }, "Build Ubuntu 20.04 Docker Image": { stage("Build Ubuntu 20.04 Docker Image") { - oe2004 = oe.dockerImage("oetools-20.04:${DOCKER_TAG}",LINUX_DOCKERFILE, "${buildArgs} --build-arg ubuntu_version=20.04 --build-arg devkits_uri=${DEVKITS_URI}") - puboe2004 = oe.dockerImage("oeciteam/oetools-20.04:${DOCKER_TAG}", LINUX_DOCKERFILE, "${buildArgs} --build-arg ubuntu_version=20.04 --build-arg devkits_uri=${DEVKITS_URI}") + steps { + script { + buildArgs = common.dockerBuildArgs("UID=\$(id -u)", "UNAME=\$(id -un)", + "GID=\$(id -g)", "GNAME=\$(id -gn)") + oe2004 = common.dockerImage("oetools-20.04:${params.DOCKER_TAG}", env.LINUX_DOCKERFILE, "${buildArgs} --build-arg ubuntu_version=20.04") + puboe2004 = common.dockerImage("oeciteam/oetools-20.04:${params.DOCKER_TAG}", env.LINUX_DOCKERFILE, "${buildArgs} --build-arg ubuntu_version=20.04") + } + } } } - stage("Push to OE Docker Registry") { - docker.withRegistry(INTERNAL_REPO, INTERNAL_REPO_CREDS) { - oe.exec_with_retry { oe1804.push() } - oe.exec_with_retry { oe2004.push() } - if(TAG_LATEST == "true") { - oe.exec_with_retry { oe1804.push('latest') } - oe.exec_with_retry { oe2004.push('latest') } + } + stage("Push to OE Docker Registry") { + steps { + script { + docker.withRegistry(params.INTERNAL_REPO, env.INTERNAL_REPO_CREDS) { + common.exec_with_retry { oe1804.push() } + common.exec_with_retry { oe2004.push() } + if(params.TAG_LATEST == "true") { + common.exec_with_retry { oe1804.push('latest') } + common.exec_with_retry { oe2004.push('latest') } + } } } } - stage("Push to OE Docker Hub Registry") { - docker.withRegistry('', DOCKERHUB_REPO_CREDS) { - if(PUBLISH_DOCKER_HUB == "true") { - oe.exec_with_retry { puboe1804.push() } - oe.exec_with_retry { puboe2004.push() } - if(TAG_LATEST == "true") { - oe.exec_with_retry { puboe1804.push('latest') } - oe.exec_with_retry { puboe2004.push('latest') } + } + stage("Push to OE Docker Hub Registry") { + steps { + script { + docker.withRegistry('', env.DOCKERHUB_REPO_CREDS) { + if(params.PUBLISH_DOCKER_HUB == "true") { + common.exec_with_retry { puboe1804.push() } + common.exec_with_retry { puboe2004.push() } + if(params.TAG_LATEST == "true") { + common.exec_with_retry { puboe1804.push('latest') } + common.exec_with_retry { puboe2004.push('latest') } + } } } } @@ -57,5 +92,3 @@ def buildLinuxDockerContainers() { } } } - -buildLinuxDockerContainers() diff --git a/.jenkins/infrastructure/docker/dockerfiles/linux/Dockerfile b/.jenkins/infrastructure/docker/dockerfiles/linux/Dockerfile index 71a15e6836..71cd731a55 100644 --- a/.jenkins/infrastructure/docker/dockerfiles/linux/Dockerfile +++ b/.jenkins/infrastructure/docker/dockerfiles/linux/Dockerfile @@ -11,13 +11,12 @@ # # Once installed, build a docker image from .jenkins folder and # it will use this Dockerfile by default: -# openenclave$ sudo docker build --no-cache=true --build-arg ubuntu_version= --build-arg devkits_uri= -t oetools-: -f .jenkins/Dockerfile.full . +# openenclave$ sudo docker build --no-cache=true --build-arg ubuntu_version= -t oetools-: -f .jenkins/Dockerfile.full . # # For example, for version 1.x with Ubuntu 18.04 : # openenclave$ sudo docker build \ # --no-cache=true \ # --build-arg ubuntu_version=18.04 \ -# --build-arg devkits_uri=https://tcpsbuild.blob.core.windows.net/tcsp-build/OE-CI-devkits-dd4c992d.tar.gz \ # -t oetools-18.04:1.x \ # -f .jenkins/infrastructure/docker/dockerfiles/linux/Dockerfile \ # . @@ -58,10 +57,6 @@ ARG GNAME=jenkins ARG UID=1000 ARG GID=1000 -ARG devkits_uri -# Check to make sure devkits_uri is defined as build arg -RUN test ! -z ${devkits_uri+x} - # Install essential packages RUN apt-get update && \ apt-get -y --no-install-recommends upgrade && \ @@ -105,9 +100,5 @@ RUN groupadd --gid ${GID} ${GNAME} RUN useradd --create-home --uid ${UID} --gid ${GID} --shell /bin/bash ${UNAME} RUN echo "${UNAME} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers -# Setup devkit -RUN curl ${devkits_uri} | tar xvz --no-same-permissions --no-same-owner -RUN echo ${devkits_uri##*/} > /devkits/TARBALL - # Set up out-of-proc attestation ENV SGX_AESM_ADDR=1 From 1f5ba850421eeabefca3683600055066913e6ac8 Mon Sep 17 00:00:00 2001 From: Chris Yan Date: Thu, 21 Oct 2021 16:49:06 -0700 Subject: [PATCH 2/3] Workaround Ansible install via pip and py36 Signed-off-by: Chris Yan --- .jenkins/infrastructure/docker/dockerfiles/linux/Dockerfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.jenkins/infrastructure/docker/dockerfiles/linux/Dockerfile b/.jenkins/infrastructure/docker/dockerfiles/linux/Dockerfile index 71cd731a55..3b1bddadcf 100644 --- a/.jenkins/infrastructure/docker/dockerfiles/linux/Dockerfile +++ b/.jenkins/infrastructure/docker/dockerfiles/linux/Dockerfile @@ -57,6 +57,10 @@ ARG GNAME=jenkins ARG UID=1000 ARG GID=1000 +# Workaround for https://githubmemory.com/repo/pypa/pip/issues/10219 +ENV LANG=C.UTF-8 +ENV LC_ALL=C.UTF-8 + # Install essential packages RUN apt-get update && \ apt-get -y --no-install-recommends upgrade && \ From 97256fdb775e912446f7b75b9940a63638a84ad5 Mon Sep 17 00:00:00 2001 From: Chris Yan Date: Mon, 25 Oct 2021 15:32:30 -0700 Subject: [PATCH 3/3] Build and test base image - Use make if cmake not installed Signed-off-by: Chris Yan --- .../build_linux_docker_images.Jenkinsfile | 84 +++++++++++++++---- .jenkins/library/vars/helpers.groovy | 38 +++++++-- 2 files changed, 99 insertions(+), 23 deletions(-) diff --git a/.jenkins/infrastructure/docker/build_linux_docker_images.Jenkinsfile b/.jenkins/infrastructure/docker/build_linux_docker_images.Jenkinsfile index 3584311d96..e38815d36a 100644 --- a/.jenkins/infrastructure/docker/build_linux_docker_images.Jenkinsfile +++ b/.jenkins/infrastructure/docker/build_linux_docker_images.Jenkinsfile @@ -5,12 +5,13 @@ library "OpenEnclaveJenkinsLibrary@${params.OECI_LIB_VERSION}" pipeline { agent { - label globalvars.AGENTS_LABELS["ubuntu-nonsgx"] + label globalvars.AGENTS_LABELS["acc-ubuntu-18.04"] } options { timeout(time: 240, unit: 'MINUTES') } parameters { + string(name: "SGX_VERSION", description: "Intel SGX version to install (Ex: 2.15.100). For versions see: https://download.01.org/intel-sgx/sgx_repo/ubuntu/apt_preference_files/") string(name: "REPOSITORY_NAME", defaultValue: "openenclave/openenclave", description: "GitHub repository to checkout") string(name: "BRANCH_NAME", defaultValue: "master", description: "The branch used to checkout the repository") string(name: "DOCKER_TAG", defaultValue: "standalone-linux-build", description: "The tag for the new Docker images") @@ -22,6 +23,7 @@ pipeline { environment { INTERNAL_REPO_CREDS = 'oejenkinscidockerregistry' DOCKERHUB_REPO_CREDS = 'oeciteamdockerhub' + BASE_DOCKERFILE_DIR = ".jenkins/infrastructure/docker/dockerfiles/linux/base/" LINUX_DOCKERFILE = ".jenkins/infrastructure/docker/dockerfiles/linux/Dockerfile" } stages { @@ -34,27 +36,70 @@ pipeline { userRemoteConfigs: [[url: "https://github.com/${params.REPOSITORY_NAME}"]]]) } } - stage("Build") { + stage("Base Image") { + stages { + stage('Build Base') { + steps { + dir(env.BASE_DOCKERFILE_DIR) { + sh """ + chmod +x ./build.sh + mkdir build + cd build + ../build.sh -v "${params.SGX_VERSION}" -u "18.04" -t "${params.DOCKER_TAG}" + ../build.sh -v "${params.SGX_VERSION}" -u "20.04" -t "${params.DOCKER_TAG}" + """ + } + } + } + stage('Test Base') { + parallel { + stage("Test Base - 18.04") { + steps { + script { + def image = docker.image("openenclave-bionic:${params.DOCKER_TAG}") + image.inside("--user root:root --cap-add=SYS_PTRACE --device /dev/sgx:/dev/sgx --volume /var/run/aesmd/aesm.socket:/var/run/aesmd/aesm.socket") { + sh """ + apt update + apt install -y build-essential open-enclave libssl-dev + """ + helpers.TestSamplesCommand(false, "open-enclave") + } + } + } + } + stage("Test Base - 20.04") { + steps { + script { + def image = docker.image("openenclave-focal:${params.DOCKER_TAG}") + image.inside("--user root:root --cap-add=SYS_PTRACE --device /dev/sgx:/dev/sgx --volume /var/run/aesmd/aesm.socket:/var/run/aesmd/aesm.socket") { + sh """ + apt update + apt install -y build-essential open-enclave libssl-dev + """ + helpers.TestSamplesCommand(false, "open-enclave") + } + } + } + } + } + } + } + } + stage("Full CI/CD Image") { parallel { stage("Build Ubuntu 18.04 Docker Image") { steps { script { - docker.withRegistry(params.INTERNAL_REPO, env.INTERNAL_REPO_CREDS) { - buildArgs = common.dockerBuildArgs("UID=\$(id -u)", "UNAME=\$(id -un)", - "GID=\$(id -g)", "GNAME=\$(id -gn)") - oe1804 = common.dockerImage("oetools-18.04:${params.DOCKER_TAG}", env.LINUX_DOCKERFILE, "${buildArgs} --build-arg ubuntu_version=18.04") - puboe1804 = common.dockerImage("oeciteam/oetools-18.04:${params.DOCKER_TAG}", env.LINUX_DOCKERFILE, "${buildArgs} --build-arg ubuntu_version=18.04") - } + oe1804 = common.dockerImage("oetools-18.04:${DOCKER_TAG}", LINUX_DOCKERFILE, "--build-arg ubuntu_version=18.04") + puboe1804 = common.dockerImage("oeciteam/oetools-18.04:${DOCKER_TAG}", LINUX_DOCKERFILE, "--build-arg ubuntu_version=18.04") } } } stage("Build Ubuntu 20.04 Docker Image") { steps { script { - buildArgs = common.dockerBuildArgs("UID=\$(id -u)", "UNAME=\$(id -un)", - "GID=\$(id -g)", "GNAME=\$(id -gn)") - oe2004 = common.dockerImage("oetools-20.04:${params.DOCKER_TAG}", env.LINUX_DOCKERFILE, "${buildArgs} --build-arg ubuntu_version=20.04") - puboe2004 = common.dockerImage("oeciteam/oetools-20.04:${params.DOCKER_TAG}", env.LINUX_DOCKERFILE, "${buildArgs} --build-arg ubuntu_version=20.04") + oe2004 = common.dockerImage("oetools-20.04:${DOCKER_TAG}",LINUX_DOCKERFILE, "--build-arg ubuntu_version=20.04") + puboe2004 = common.dockerImage("oeciteam/oetools-20.04:${DOCKER_TAG}", LINUX_DOCKERFILE, "--build-arg ubuntu_version=20.04") } } } @@ -77,11 +122,11 @@ pipeline { stage("Push to OE Docker Hub Registry") { steps { script { - docker.withRegistry('', env.DOCKERHUB_REPO_CREDS) { - if(params.PUBLISH_DOCKER_HUB == "true") { + docker.withRegistry('', DOCKERHUB_REPO_CREDS) { + if(PUBLISH_DOCKER_HUB == "true") { common.exec_with_retry { puboe1804.push() } common.exec_with_retry { puboe2004.push() } - if(params.TAG_LATEST == "true") { + if(TAG_LATEST == "true") { common.exec_with_retry { puboe1804.push('latest') } common.exec_with_retry { puboe2004.push('latest') } } @@ -91,4 +136,13 @@ pipeline { } } } + post { + always { + emailext( + subject: "Jenkins: ${env.JOB_NAME} [#${env.BUILD_NUMBER}] status is ${currentBuild.currentResult}", + body: "See build log for details: ${env.BUILD_URL}", + recipientProviders: [[$class: 'DevelopersRecipientProvider'], [$class: 'RequesterRecipientProvider']] + ) + } + } } diff --git a/.jenkins/library/vars/helpers.groovy b/.jenkins/library/vars/helpers.groovy index 81603abd6b..a24356629b 100644 --- a/.jenkins/library/vars/helpers.groovy +++ b/.jenkins/library/vars/helpers.groovy @@ -105,15 +105,37 @@ def testSamplesLinux(boolean lvi_mitigation, String oe_package) { cp -r /opt/openenclave/share/openenclave/samples ~/ cd ~/samples . /opt/openenclave/share/openenclave/openenclaverc + if hash cmake 2> /dev/null; then + echo "INFO: Using cmake to build" + export BUILD_SYSTEM=CMAKE + elif hash make 2> /dev/null; then + echo "INFO: Using make to build" + export BUILD_SYSTEM=MAKE + fi + if [[ -z \${BUILD_SYSTEM+x} ]]; then + echo "Error: cmake and make not found. Please install either one to proceed" + exit 1 + fi for i in *; do - if [[ -d \${i} ]] && [[ -f \${i}/CMakeLists.txt ]]; then - cd \${i} - mkdir build - cd build - cmake .. ${lvi_args} - make - make run - cd ~/samples + if [[ \${BUILD_SYSTEM} == "CMAKE" ]]; then + if [[ -d \${i} ]] && [[ -f \${i}/CMakeLists.txt ]]; then + cd \${i} + mkdir build + cd build + cmake .. ${lvi_args} + make + make run + cd ~/samples + fi + elif [[ \${BUILD_SYSTEM} == "MAKE" ]]; then + if [[ -d \${i} ]] && [[ -f \${i}/Makefile ]]; then + cd \${i} + make build + make run + fi + else + echo "Error: unrecognized build system. Either cmake or make must be installed." + exit 1 fi done cd ~