Skip to content

Remove signatures in-place from AppInsights agent jar before adding it to worker package #810

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 5, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 131 additions & 60 deletions package-pipeline.ps1
Original file line number Diff line number Diff line change
@@ -1,88 +1,159 @@
param (
[string]$buildNumber
[string]$buildNumber
)

# A function that checks exit codes and fails script if an error is found
# A helper function that stops the entire script if the last command failed.
function StopOnFailedExecution {
if ($LastExitCode)
{
exit $LastExitCode
}
if ($LastExitCode) {
exit $LastExitCode
}
}

Write-Host "Building azure-functions-java-worker with appinsights profile"
# --------------------------------------------------------------------
# Build the azure-functions-java-worker (using the "appinsights" profile)
# --------------------------------------------------------------------
Write-Host "=== Building azure-functions-java-worker with 'appinsights' profile ==="
mvn clean package --no-transfer-progress -B -P appinsights
StopOnFailedExecution

Write-Host "Creating nuget package Microsoft.Azure.Functions.JavaWorker"
Write-Host "buildNumber: " $buildNumber
Get-Command nuget
# --------------------------------------------------------------------
# Prepare the final "pkg" folder and copy core worker artifacts
# --------------------------------------------------------------------
Write-Host "`n=== Creating NuGet package: Microsoft.Azure.Functions.JavaWorker ==="
Write-Host "Using buildNumber: $buildNumber"

# Ensure 'nuget' command is available
Get-Command nuget | Out-Null
StopOnFailedExecution
remove-item pkg -Recurse -ErrorAction Ignore
mkdir pkg
Get-ChildItem -Path .\target\* -Include 'azure*' -Exclude '*shaded.jar','*tests.jar' | %{ Copy-Item $_.FullName .\pkg\azure-functions-java-worker.jar }

Write-Host "Removing old 'pkg' folder (if present)..."
Remove-Item -Recurse -Force -ErrorAction Ignore .\pkg

Write-Host "Creating new 'pkg' folder..."
New-Item -ItemType Directory -Path .\pkg | Out-Null

Write-Host "Copying azure-functions-java-worker.jar to 'pkg'..."
Get-ChildItem -Path .\target\* -Include 'azure*' -Exclude '*shaded.jar','*tests.jar' |
ForEach-Object { Copy-Item $_.FullName .\pkg\azure-functions-java-worker.jar }
StopOnFailedExecution
copy-item ./worker.config.json pkg
copy-item ./tools/AzureFunctionsJavaWorker.nuspec pkg/
copy-item ./annotationLib pkg/annotationLib -Recurse

# locate the agent jar produced by the `appinsights` Maven profile
$ApplicationInsightsAgentFile = [System.IO.Path]::Combine($PSScriptRoot, 'target', 'agent', 'applicationinsights-agent.jar')
Write-Host "Copying supporting files into 'pkg' folder..."
Copy-Item .\worker.config.json .\pkg\
Copy-Item .\tools\AzureFunctionsJavaWorker.nuspec .\pkg\
Copy-Item .\annotationLib .\pkg\annotationLib -Recurse

if (!(Test-Path -Path $ApplicationInsightsAgentFile)) {
Write-Host "Error: $ApplicationInsightsAgentFile not found."
Write-Host "Make sure you enabled the 'appinsights' Maven profile that copies the AI agent to target/agent/."
# --------------------------------------------------------------------
# Locate the Application Insights agent built by the Maven profile
# --------------------------------------------------------------------
$AgentSourcePath = Join-Path $PSScriptRoot 'target\agent\applicationinsights-agent.jar'
if (!(Test-Path -Path $AgentSourcePath)) {
Write-Host "`nERROR: Application Insights agent not found at '$AgentSourcePath'."
Write-Host "Make sure you enabled the 'appinsights' Maven profile."
exit 1
}

# local testing cleanup
$oldOutput = [System.IO.Path]::Combine($PSScriptRoot, "agent")
if (Test-Path -Path $oldOutput) {
Remove-Item -Path $oldOutput -Recurse
}
# --------------------------------------------------------------------
# Create a local 'agent' folder and copy the agent jar there
# --------------------------------------------------------------------
Write-Host "`n=== Setting up the agent folder ==="

# local testing cleanup
$oldExtract = [System.IO.Path]::Combine($PSScriptRoot, "extract")
if (Test-Path -Path $oldExtract) {
Remove-Item -Path $oldExtract -Recurse
}
$AgentFolder = Join-Path $PSScriptRoot 'agent'
$AgentFilename = 'applicationinsights-agent.jar'
$PackagedAgentFile = Join-Path $AgentFolder $AgentFilename

$extract = new-item -type directory -force $PSScriptRoot\extract
if (-not(Test-Path -Path $extract)) {
echo "Fail to create a new directory $extract"
exit 1
Write-Host "Removing old 'agent' folder (if present)..."
if (Test-Path -Path $AgentFolder) {
Remove-Item -Recurse -Force $AgentFolder
}

echo "Start extracting content from $ApplicationInsightsAgentFilename to extract folder"
cd -Path $extract -PassThru
jar xf $ApplicationInsightsAgentFile
cd $PSScriptRoot
echo "Done extracting"
Write-Host "Creating a new 'agent' folder..."
New-Item -ItemType Directory -Path $AgentFolder | Out-Null

echo "Unsign $ApplicationInsightsAgentFilename"
Remove-Item $extract\META-INF\MSFTSIG.*
$manifest = "$extract\META-INF\MANIFEST.MF"
$newContent = (Get-Content -Raw $manifest | Select-String -Pattern '(?sm)^(.*?\r?\n)\r?\n').Matches[0].Groups[1].Value
Set-Content -Path $manifest $newContent
Write-Host "Copying agent from '$AgentSourcePath' to '$PackagedAgentFile'..."
Copy-Item $AgentSourcePath -Destination $PackagedAgentFile
StopOnFailedExecution

$agent = new-item -type directory -force $PSScriptRoot\agent
$filename = "applicationinsights-agent.jar"
$result = [System.IO.Path]::Combine($agent, $filename)
echo "re-jar $filename"
# --------------------------------------------------------------------
# Remove signature files and adjust MANIFEST.MF in-place (no full extraction)
# --------------------------------------------------------------------
Write-Host "`n=== Removing signature files from '$PackagedAgentFile' ==="

cd -Path $extract -PassThru
jar cfm $result META-INF/MANIFEST.MF .
# Load .NET assemblies for ZipArchive on Windows
Add-Type -AssemblyName System.IO.Compression, System.IO.Compression.FileSystem

if (-not(Test-Path -Path $result)) {
echo "Fail to re-archive $filename"
exit 1
$fileStream = [System.IO.File]::Open($PackagedAgentFile, [System.IO.FileMode]::Open)
$zipArchive = New-Object System.IO.Compression.ZipArchive($fileStream, [System.IO.Compression.ZipArchiveMode]::Update)

try {
Write-Host "Deleting signature files from META-INF..."
$entriesToRemove = $zipArchive.Entries | Where-Object {
$_.FullName -like "META-INF/MSFTSIG.*" `
-or $_.FullName -like "META-INF/*.SF" `
-or $_.FullName -like "META-INF/*.RSA" `
-or $_.FullName -like "META-INF/*.DSA"
}

foreach ($entry in $entriesToRemove) {
Write-Host " Removing: $($entry.FullName)"
$entry.Delete()
}

Write-Host "Checking MANIFEST.MF for extra signature references..."
$manifestEntry = $zipArchive.Entries | Where-Object { $_.FullName -eq "META-INF/MANIFEST.MF" }
if ($manifestEntry) {
$reader = New-Object System.IO.StreamReader($manifestEntry.Open())
$manifestContent = $reader.ReadToEnd()
$reader.Close()

# Regex to remove blank line(s) after the main attributes
$pattern = '(?sm)^(.*?\r?\n)\r?\n'
$matches = [regex]::Matches($manifestContent, $pattern)

if ($matches.Count -gt 0) {
Write-Host " Removing signature-related lines after main attributes."
$cleanedManifest = $matches[0].Groups[1].Value

$manifestEntry.Delete()

$newManifestEntry = $zipArchive.CreateEntry("META-INF/MANIFEST.MF")
$writer = New-Object System.IO.StreamWriter($newManifestEntry.Open())
$writer.Write($cleanedManifest)
$writer.Flush()
$writer.Close()

Write-Host " MANIFEST.MF updated successfully."
}
else {
Write-Host " No extra blank lines found in MANIFEST.MF."
}
}
else {
Write-Host "No MANIFEST.MF found in the JAR (unexpected?)."
}
}
finally {
# Always dispose archive and file streams
$zipArchive.Dispose()
$fileStream.Dispose()
}
Write-Host "Creating the functions.codeless file"
New-Item -path $PSScriptRoot\agent -type file -name "functions.codeless"

cd $PSScriptRoot
Copy-Item $PSScriptRoot/agent $PSScriptRoot/pkg/agent -Recurse -Verbose
Write-Host "Done removing signature files from '$PackagedAgentFile'."

# --------------------------------------------------------------------
# Add 'functions.codeless' marker and copy agent folder to 'pkg'
# --------------------------------------------------------------------
Write-Host "`n=== Creating 'functions.codeless' marker file ==="
New-Item -Path $AgentFolder -Name "functions.codeless" -ItemType File | Out-Null

set-location pkg
Write-Host "Copying 'agent' folder into the 'pkg' folder..."
Copy-Item $AgentFolder (Join-Path $PSScriptRoot 'pkg\agent') -Recurse -Force -Verbose

# --------------------------------------------------------------------
# Package everything into the final NuGet package
# --------------------------------------------------------------------
Write-Host "`n=== Creating the NuGet package ==="
Push-Location pkg
nuget pack -Properties version=$buildNumber
set-location ..
Pop-Location

Write-Host "`n=== Script completed successfully. NuGet package created. ==="