Skip to content

Commit

Permalink
ARM Base Image Update Pipeline (#4160)
Browse files Browse the repository at this point in the history
First take on automating ARM Base Image update.

Use case scenario: 
1. tools/BaseImageUpdate/baseImage.ps1 is a helper script that a developer can use on his powershell to update the ARM base image version.  i.e. `Update-ARM-BaseImages -NewASPNetCoreVersion "2.1.23"`.
2. A developer send out a Pull request with base image changes.
3. A developer uses a pipeline `builds/misc/base-images-publish.yaml` to kick off the build & base image publication.
4. (Optional) As a good measure, once (3) is completed, a developer can run the build image pipeline to verify a successful publication.
  • Loading branch information
yophilav authored Jan 7, 2021
1 parent 4873dd9 commit 931778a
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 0 deletions.
45 changes: 45 additions & 0 deletions builds/misc/base-images-publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
trigger: none
pr: none

jobs:
################################################################################
- job: linux_arm32
################################################################################
displayName: Linux ARM32 Base Image Publication
pool:
name: $(pool.name)
demands:
- Agent.OS -equals Linux
- Agent.OSArchitecture -equals ARM
- agent-osbits -equals 32
- run-base-image-release -equals true

variables:
os: linux
arch: arm32v7

steps:
- template: templates/base-image-publish/base-image-clear-docker-cache.yaml
- template: templates/base-image-publish/base-image-docker-login.yaml
- template: templates/base-image-publish/base-image-build-and-publish.yaml

################################################################################
- job: linux_arm64
################################################################################
displayName: Linux ARM64 Base Image Publication
pool:
name: $(pool.name)
demands:
- Agent.OS -equals Linux
- Agent.OSArchitecture -equals ARM64
- agent-osbits -equals 64
- run-base-image-release -equals true

variables:
os: linux
arch: arm64v8

steps:
- template: templates/base-image-publish/base-image-clear-docker-cache.yaml
- template: templates/base-image-publish/base-image-docker-login.yaml
- template: templates/base-image-publish/base-image-build-and-publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
steps:
- pwsh: |
# Config the base image publication
$config = New-Object System.Collections.ArrayList
# Tuple format: (ModuleRepoPath, BaseImageName, ReturningVstsVar)
$config.AddRange((
[Tuple]::Create("edge-agent", "azureiotedge-agent-base", "edgeAgentTag"),
[Tuple]::Create("edge-hub", "azureiotedge-hub-base", "edgeHubTag"),
[Tuple]::Create("edge-modules/SimulatedTemperatureSensor","azureiotedge-module-base", "moduleTag"),
[Tuple]::Create("test/modules/TestAnalyzer", "azureiotedge-module-base-full", "fullModuleTag")
));
# Download librocksdb from blob storage
$artifactLocale = "$(Build.SourcesDirectory)/librocksdb.so"
Invoke-WebRequest -Uri $("https://edgebuild.blob.core.windows.net/librocksdb/librocksdb.so.$(arch)") -OutFile $artifactLocale
# Get all the tag for publication
Write-Output "`n`nBase Image Info"
foreach ($eachConfig in $config)
{
# Fetch tags & version from each module Dockerfiles {../$(arch)/base/Dockerfile, ../$(arch)/Dockerfile}
# Steps:
# 1. Go to a respective Dockerfile as defined in $config for an underlying base image
# 2. Read underlying base image tag using "ARG base_tag="
# 3. Go to a Dockerfile of the module to get tagging that refers to underly base image (2)
# 4. Set a variable with the tag obtained in (3). This variable has the same name as config by item3 of $config
# 5. Output the read values. Format: <BaseImageName>:<ReferringTag> 🠘 <UnderLyingBaseImageTag>
$pathPrefix = "$(Build.SourcesDirectory)/$($eachConfig.Item1)/docker/$(os)/$(arch)"
$unberlyingFilePath = $pathPrefix + '/base/Dockerfile' | Resolve-path
$underlyingTag = $($(Get-Content $unberlyingFilePath | Select-String "ARG base_tag=") -split "=")[1]
$imageFilePath = $pathPrefix + '/Dockerfile' | Resolve-path
Set-Variable -Name "$($eachConfig.Item3)" -Value "$($($(Get-Content $imageFilePath | Select-String "ARG base_tag=") -split "=")[1])"
Write-Output "$($eachConfig.Item2):$(Get-Variable -Name "$($eachConfig.Item3)" -ValueOnly) 🠘 $underlyingTag"
# Extract version number from the *-linux* base image
# Uses ($config.item3) + 'Version' to return the version string as an environment variable
#
# Note:
# The output {$(edgeAgentTagVersion), $(edgeHubTagVersion), $(moduleTagVersion), $(fullModuleTagVersion)} are used to publish artifacts
Set-Variable -Name "$($eachConfig.Item3)Version" -Value "$($(Get-Variable -Name "$($eachConfig.Item3)" -ValueOnly).split("-")[0])"
# Copy librocksdb.so to the same directory where base image is going to be built
$filePath = "$(Build.SourcesDirectory)/$($eachConfig.Item1)/docker/$(os)/$(arch)/base/librocksdb.so"
Copy-Item $artifactLocale -Destination "$filePath" -ErrorAction Stop
}
# Build base images & publish them
cd $(Build.SourcesDirectory)
$scriptPath = "$(Build.SourcesDirectory)/scripts/linux/createArmBase.sh"
Write-Output "`n`nBuild & Publish"
foreach ($eachConfig in $config)
{
$versionTag = $(Get-Variable -Name "$($eachConfig.Item3)Version" -ValueOnly)
$buildCommand = " ``sh -c ""$scriptPath -d $($eachConfig.Item1) -i $($eachConfig.Item2) -v $versionTag""`` "
echo "Command: $buildCommand"
Invoke-Expression -Command "$buildCommand"
# Clean up librocksdb.so that we copied here.
$filePath = "$(Build.SourcesDirectory)/$($eachConfig.Item1)/docker/$(os)/$(arch)/base/librocksdb.so"
Remove-Item $filePath
}
# Clean up librocksdb.so
Remove-Item $artifactLocale
displayName: Publish
name: publish
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
steps:
- pwsh: |
$isNoModuleRunning = [string]::IsNullOrEmpty($(docker ps -aq))
if (!$isNoModuleRunning)
{
docker stop $(docker ps -aq)
}
docker system prune --volumes -af
displayName: Clear cached docker images
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
steps:
- task: Docker@2
displayName: Docker Login
inputs:
command: login
containerRegistry: $(user.dockerConnection)
77 changes: 77 additions & 0 deletions tools/BaseImageUpdate/baseImage.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Run this on E2E test agent in PWSH
function Setup-BaseImage-Script
{
# Change current directory to ../iotedge
$rootDir = $env:BUILD_SOURCESDIRECTORY
if (-not $rootDir) {
$rootDir = [IO.Path]::Combine($PSScriptRoot, "..", "..")
}

cd $rootDir

$isDotNetInstalled = ((gp HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*).DisplayName -Match "Microsoft .NET Core Runtime").Length -gt 0;
if ($isDotNetInstalled)
{
# Cleaning build artifacts as it slow down the search
dotnet clean
dotnet clean -c release
}
}


function Get-Unique-BaseImages
{
Setup-BaseImage-Script

Get-ChildItem -Recurse -Filter "Dockerfile" | `
Select-String "ARG base_tag=" | `
ForEach-Object { $_.Line -replace 'ARG base_tag=', '' } | `
Sort-Object -Unique
}


function Update-ARM-BaseImages
{
[CmdletBinding()]
param (
<#
The new version of ASP .NET Core
Ex: The new ASP .NET Core tag is 2.1.23-bionic-arm32, the $NewASPNetCoreVersion = 2.1.23
#>
[Parameter(Mandatory)]
[string]
$NewASPNetCoreVersion
)

Setup-BaseImage-Script

# Get all the Dockerfile file location
$fileLocale = $(Get-ChildItem -Recurse -Filter "Dockerfile" )

# Replace the underlying ASP .Net Core to the new version
# Assuming the ARM64 & ARM32 both use the same *-bionic-arm* ASP .Net Core image tag
$baseAspNetLocale = $($($fileLocale | Convert-Path) -like "*\base\*" | Resolve-path)
foreach ($file in $baseAspNetLocale)
{
(Get-Content -Encoding utf8 $file.Path) |
Foreach-Object { $_ -replace "ARG base_tag=.*.-bionic-arm", "ARG base_tag=$NewASPNetCoreVersion-bionic-arm" } |
Set-Content -Encoding utf8 $file.Path
}

# Update the places where the base images are used
$baseImageLocale = $($fileLocale | Select-String "ARG base_tag=.*.-linux-arm" | Select-Object -Unique Path)
foreach ($file in $($baseImageLocale | Resolve-path))
{
# Increment the last digit by 1
$fileContent = (Get-Content $file.Path);
$curVersion = $($fileContent -like "ARG base_tag=*" ).split("=")[1].split("-")[0];
$splitVersion = $curVersion.split(".", 4);
$incrementedSegment = $([int]$splitVersion[3]) + 1;
$newBaseImageVersion = $($splitVersion[0,1,2] + $incrementedSegment -join ".");

# Replace the version
$fileContent |
Foreach-Object { $_ -replace "ARG base_tag=.*.-linux-arm", "ARG base_tag=$newBaseImageVersion-linux-arm" } |
Set-Content $file.Path
}
}

0 comments on commit 931778a

Please sign in to comment.