Skip to content
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

Custom Host For Linux #4152

Merged
merged 30 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
a4ddd76
addressing comments and initial changes for generating artifacts
aishwaryabh Nov 7, 2024
4d2fe13
osx change
aishwaryabh Nov 7, 2024
335be05
deleting extra directory
aishwaryabh Nov 7, 2024
3754409
change order of extract directories
aishwaryabh Nov 7, 2024
4a6d9e7
logging artifact directory
aishwaryabh Nov 7, 2024
e5e2162
skipping flakey e2e test
aishwaryabh Nov 7, 2024
5676716
fixed version bug
aishwaryabh Nov 7, 2024
352eef7
addressing comments
aishwaryabh Nov 7, 2024
6c2bdb6
core tools host windows should still sign
aishwaryabh Nov 7, 2024
5885c82
adding exe to comment
aishwaryabh Nov 7, 2024
a34407d
removing self-contained arg
aishwaryabh Nov 7, 2024
60b0d5d
addding logging statement
aishwaryabh Nov 7, 2024
8a33b96
adding assembly path logging
aishwaryabh Nov 8, 2024
ad4f550
removing not needed nethost logging
aishwaryabh Nov 8, 2024
81449fc
more logging!
aishwaryabh Nov 8, 2024
0cf6a86
adding signing back
aishwaryabh Nov 20, 2024
edf988f
removing sign step
aishwaryabh Nov 20, 2024
54f3c76
adding path var
aishwaryabh Nov 20, 2024
bfc780f
adding variable to path
aishwaryabh Nov 20, 2024
22ad754
install net8
aishwaryabh Nov 21, 2024
6cce9b3
seperating net9 task to seperate job
aishwaryabh Nov 21, 2024
28d8d33
forgot quote
aishwaryabh Nov 21, 2024
5261a31
add core tools host
aishwaryabh Nov 21, 2024
a3522ea
adding mac signing
aishwaryabh Nov 21, 2024
e7c4b37
changing mac folder back
aishwaryabh Nov 21, 2024
ecb9206
changing signing path back
aishwaryabh Nov 21, 2024
eb31c00
trying 3rd party sign
aishwaryabh Nov 21, 2024
0c97b8e
trying to notarize
aishwaryabh Nov 21, 2024
a7f65ef
remove custom host mac
aishwaryabh Nov 25, 2024
96150e1
removing not needed logging
aishwaryabh Nov 25, 2024
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
119 changes: 114 additions & 5 deletions eng/ci/templates/official/jobs/build-core-tools-host.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ jobs:
Contents: |
func.exe
nethost.dll
TargetFolder: $(Build.ArtifactStagingDirectory)/_coreToolsHostPackagesWindows/win-x64
TargetFolder: $(Build.ArtifactStagingDirectory)/_coreToolsHostPackages/win-x64

- task: CopyFiles@2
displayName: Copy files (win-arm64)
Expand All @@ -113,11 +113,120 @@ jobs:
Contents: |
func.exe
nethost.dll
TargetFolder: $(Build.ArtifactStagingDirectory)/_coreToolsHostPackagesWindows/win-arm64

TargetFolder: $(Build.ArtifactStagingDirectory)/_coreToolsHostPackages/win-arm64

templateContext:
outputParentDirectory: $(Build.ArtifactStagingDirectory)
outputs:
- output: pipelineArtifact
path: $(Build.ArtifactStagingDirectory)/_coreToolsHostPackages
artifact: drop-coretools-host-windows

- job: BuildCoreToolsHostLinux
displayName: '[Linux] Build CoreToolsHost'
pool:
name: 1es-pool-azfunc
image: 1es-ubuntu-22.04
os: linux

steps:
- task: UseDotNet@2
inputs:
version: 9.x
includePreviewVersions: true
displayName: Install .NET 9
- task: UseDotNet@2
inputs:
version: 6.x
displayName: Install .NET 6

- task: DotnetCoreCLI@2
displayName: Dotnet Publish (linux-x64)
inputs:
command: publish
publishWebProjects: false
zipAfterPublish: false
arguments: -c Release -r linux-x64 -o $(Build.SourcesDirectory)/pkg_output/linux/linux-x64 --self-contained
workingDirectory: $(Build.SourcesDirectory)/host/src/CoreToolsHost

- task: CopyFiles@2
displayName: Copy files (linux-x64)
inputs:
SourceFolder: $(Build.SourcesDirectory)/pkg_output/linux/linux-x64
# Publish output will include many other files. We only need func & nethost.dll
Contents: |
func
libnethost.so
TargetFolder: $(Build.ArtifactStagingDirectory)/_coreToolsHostPackages/linux-x64

templateContext:
outputParentDirectory: $(Build.ArtifactStagingDirectory)
outputs:
- output: pipelineArtifact
path: $(Build.ArtifactStagingDirectory)/_coreToolsHostPackages
artifact: drop-coretools-host-linux

- job: BuildCoreToolsHostMac
displayName: '[Mac] Build CoreToolsHost'
pool:
name: Azure Pipelines
image: 'macOS-latest'
os: macOS

steps:
- task: UseDotNet@2
inputs:
version: 9.x
includePreviewVersions: true
displayName: Install .NET 9
- task: UseDotNet@2
inputs:
version: 6.x
displayName: Install .NET 6

- task: DotnetCoreCLI@2
displayName: Dotnet Publish (osx-x64)
inputs:
command: publish
publishWebProjects: false
zipAfterPublish: false
arguments: -c Release -r osx-x64 -o $(Build.SourcesDirectory)/pkg_output/osx/osx-x64 --self-contained
workingDirectory: $(Build.SourcesDirectory)/host/src/CoreToolsHost

- task: DotnetCoreCLI@2
displayName: Dotnet Publish (osx-arm64)
inputs:
command: publish
publishWebProjects: false
zipAfterPublish: false
arguments: -c Release -r osx-arm64 -o $(Build.SourcesDirectory)/pkg_output/osx/osx-arm64 --self-contained
workingDirectory: $(Build.SourcesDirectory)/host/src/CoreToolsHost

- task: CopyFiles@2
displayName: Copy files (osx-x64)
inputs:
SourceFolder: $(Build.SourcesDirectory)/pkg_output/osx/osx-x64
# Publish output will include many other files. We only need func & nethost.dll
Contents: |
func
libnethost.dylib
libnethost.a
TargetFolder: $(Build.ArtifactStagingDirectory)/_coreToolsHostPackages/osx-x64

- task: CopyFiles@2
displayName: Copy files (osx-arm64)
inputs:
SourceFolder: $(Build.SourcesDirectory)/pkg_output/osx/osx-arm64
# Publish output will include many other files. We only need func & nethost.dll
Contents: |
func
libnethost.dylib
libnethost.a
TargetFolder: $(Build.ArtifactStagingDirectory)/_coreToolsHostPackages/osx-arm64

templateContext:
outputParentDirectory: $(Build.ArtifactStagingDirectory)
outputs:
- output: pipelineArtifact
path: $(Build.ArtifactStagingDirectory)/_coreToolsHostPackagesWindows
artifact: drop-coretools-host-windows
path: $(Build.ArtifactStagingDirectory)/_coreToolsHostPackages
artifact: drop-coretools-host-osx
113 changes: 60 additions & 53 deletions src/Azure.Functions.ArtifactAssembler/ArtifactAssembler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ internal sealed class ArtifactAssembler
/// The artifacts for which we want to pack a custom host with it.
/// This dictionary contains the artifact name and the corresponding runtime identifier value.
/// </summary>
private readonly Dictionary<string, string> _customHostArtifacts = new()
private readonly Dictionary<string, string> _visualStudioArtifacts = new()
{
{ "Azure.Functions.Cli.min.win-x64", "win-x64" },
{ "Azure.Functions.Cli.min.win-arm64", "win-arm64" }
{ "Azure.Functions.Cli.min.win-arm64", "win-arm64" },
{ "Azure.Functions.Cli.linux-x64", "linux-x64" },
{ "Azure.Functions.Cli.osx-x64", "osx-x64" },
{ "Azure.Functions.Cli.osx-arm64", "osx-arm64" }
};

/// <summary>
Expand All @@ -38,7 +41,9 @@ internal sealed class ArtifactAssembler
private readonly string _outOfProcArtifactDirectoryName;
private readonly string _inProc6ArtifactName;
private readonly string _inProc8ArtifactName;
private readonly string _coreToolsHostArtifactName;
private readonly string _coreToolsHostWindowsArtifactName;
private readonly string _coreToolsHostLinuxArtifactName;
private readonly string _coreToolsHostMacArtifactName;
private readonly string _outOfProcArtifactName;
private readonly string _rootWorkingDirectory;
private readonly string _stagingDirectory;
Expand All @@ -56,7 +61,9 @@ internal ArtifactAssembler(string rootWorkingDirectory)

_inProc6ArtifactName = GetRequiredEnvironmentVariable(EnvironmentVariables.InProc6ArtifactName);
_inProc8ArtifactName = GetRequiredEnvironmentVariable(EnvironmentVariables.InProc8ArtifactName);
_coreToolsHostArtifactName = GetRequiredEnvironmentVariable(EnvironmentVariables.CoreToolsHostArtifactName);
_coreToolsHostWindowsArtifactName = GetRequiredEnvironmentVariable(EnvironmentVariables.CoreToolsHostWindowsArtifactName);
_coreToolsHostLinuxArtifactName = GetRequiredEnvironmentVariable(EnvironmentVariables.CoreToolsHostLinuxArtifactName);
_coreToolsHostMacArtifactName = GetRequiredEnvironmentVariable(EnvironmentVariables.CoreToolsHostOsxArtifactName);
_outOfProcArtifactName = GetRequiredEnvironmentVariable(EnvironmentVariables.OutOfProcArtifactName);

_rootWorkingDirectory = rootWorkingDirectory;
Expand All @@ -66,8 +73,8 @@ internal ArtifactAssembler(string rootWorkingDirectory)
internal async Task AssembleArtifactsAsync()
{
await ExtractDownloadedArtifactsAsync();
await CreateVisualStudioCoreToolsAsync();
await CreateCliCoreToolsAsync();
await CreateVisualStudioCoreToolsAsync();
}

private static string GetRequiredEnvironmentVariable(string variableName)
Expand All @@ -84,20 +91,27 @@ private async Task ExtractDownloadedArtifactsAsync()

var inProc6ArtifactDirPath = Path.Combine(inProcArtifactDownloadDir, _inProc6ArtifactName);
var inProc8ArtifactDirPath = Path.Combine(inProcArtifactDownloadDir, _inProc8ArtifactName);
var coreToolsHostArtifactDirPath = Path.Combine(coreToolsHostArtifactDownloadDir, _coreToolsHostArtifactName);
var outOfProcArtifactDirPath = Path.Combine(outOfProcArtifactDownloadDir, _outOfProcArtifactName);

var coreToolsHostWindowsArtifactDirPath = Path.Combine(coreToolsHostArtifactDownloadDir, _coreToolsHostWindowsArtifactName);
var coreToolsHostLinuxArtifactDirPath = Path.Combine(coreToolsHostArtifactDownloadDir, _coreToolsHostLinuxArtifactName);
var coreToolsHostMacArtifactDirPath = Path.Combine(coreToolsHostArtifactDownloadDir, _coreToolsHostMacArtifactName);

EnsureArtifactDirectoryExist(inProc6ArtifactDirPath);
EnsureArtifactDirectoryExist(inProc8ArtifactDirPath);
EnsureArtifactDirectoryExist(coreToolsHostArtifactDirPath);
EnsureArtifactDirectoryExist(outOfProcArtifactDirPath);
EnsureArtifactDirectoryExist(coreToolsHostWindowsArtifactDirPath);
EnsureArtifactDirectoryExist(coreToolsHostLinuxArtifactDirPath);
EnsureArtifactDirectoryExist(coreToolsHostMacArtifactDirPath);

_inProc6ExtractedRootDir = await MoveArtifactsToStagingDirectoryAndExtractIfNeeded(inProc6ArtifactDirPath, Path.Combine(_stagingDirectory, Constants.InProc6DirectoryName));
_inProc8ExtractedRootDir = await MoveArtifactsToStagingDirectoryAndExtractIfNeeded(inProc8ArtifactDirPath, Path.Combine(_stagingDirectory, Constants.InProc8DirectoryName));

Directory.Delete(inProcArtifactDownloadDir, true);

_coreToolsHostExtractedRootDir = await MoveArtifactsToStagingDirectoryAndExtractIfNeeded(coreToolsHostArtifactDirPath, Path.Combine(_stagingDirectory, Constants.CoreToolsHostDirectoryName));
_coreToolsHostExtractedRootDir = await MoveArtifactsToStagingDirectoryAndExtractIfNeeded(coreToolsHostWindowsArtifactDirPath, Path.Combine(_stagingDirectory, Constants.CoreToolsHostDirectoryName));
await MoveArtifactsToStagingDirectoryAndExtractIfNeeded(coreToolsHostLinuxArtifactDirPath, Path.Combine(_stagingDirectory, Constants.CoreToolsHostDirectoryName));
await MoveArtifactsToStagingDirectoryAndExtractIfNeeded(coreToolsHostMacArtifactDirPath, Path.Combine(_stagingDirectory, Constants.CoreToolsHostDirectoryName));
Directory.Delete(coreToolsHostArtifactDownloadDir, true);

_outOfProcExtractedRootDir = await MoveArtifactsToStagingDirectoryAndExtractIfNeeded(outOfProcArtifactDirPath, Path.Combine(_stagingDirectory, Constants.OutOfProcDirectoryName));
Expand Down Expand Up @@ -132,6 +146,13 @@ private static async Task<string> MoveArtifactsToStagingDirectoryAndExtractIfNee
{
await Task.Run(() => FileUtilities.CopyDirectory(artifactZipPath, destinationDirectory));
await ExtractZipFilesInDirectoryAsync(artifactZipPath, destinationDirectory);

// Delete additional files that are not needed
var filesToBeDeleted = Directory.EnumerateFiles(destinationDirectory);
foreach (var file in filesToBeDeleted)
{
File.Delete(file);
}
return destinationDirectory;
}

Expand All @@ -156,7 +177,7 @@ private async Task CreateVisualStudioCoreToolsAsync()
var customHostTargetArtifactDir = Path.Combine(_stagingDirectory, Constants.VisualStudioOutputArtifactDirectoryName);
Directory.CreateDirectory(customHostTargetArtifactDir);

var packTasks = _customHostArtifacts.Keys.Select(async artifactName =>
foreach (string artifactName in _visualStudioArtifacts.Keys)
aishwaryabh marked this conversation as resolved.
Show resolved Hide resolved
{
var inProc8ArtifactDirPath = Directory.EnumerateDirectories(_inProc8ExtractedRootDir)
.FirstOrDefault(dir => dir.Contains(artifactName));
Expand All @@ -171,31 +192,36 @@ private async Task CreateVisualStudioCoreToolsAsync()
var consolidatedArtifactDirPath = Path.Combine(customHostTargetArtifactDir, consolidatedArtifactDirName);
Directory.CreateDirectory(consolidatedArtifactDirPath);

// Copy in-proc8 files
var inProc8CopyTask = Task.Run(() => FileUtilities.CopyDirectory(inProc8ArtifactDirPath, Path.Combine(consolidatedArtifactDirPath, Constants.InProc8DirectoryName)));
// Copy in-proc8 files and delete directory after
await Task.Run(() => FileUtilities.CopyDirectory(inProc8ArtifactDirPath, Path.Combine(consolidatedArtifactDirPath, Constants.InProc8DirectoryName)));
Directory.Delete(inProc8ArtifactDirPath, true);

// Copy in-proc6 files
// Copy in-proc6 files and delete directory after
var inProc6ArtifactDirPath = Path.Combine(_inProc6ExtractedRootDir, artifactDirName);
EnsureArtifactDirectoryExist(inProc6ArtifactDirPath);
var inProc6CopyTask = Task.Run(() => FileUtilities.CopyDirectory(inProc6ArtifactDirPath, Path.Combine(consolidatedArtifactDirPath, Constants.InProc6DirectoryName)));
await Task.Run(() => FileUtilities.CopyDirectory(inProc6ArtifactDirPath, Path.Combine(consolidatedArtifactDirPath, Constants.InProc6DirectoryName)));
Directory.Delete(inProc6ArtifactDirPath, true);

// Copy core-tools-host files
var rid = GetRuntimeIdentifierForArtifactName(artifactName);
var coreToolsHostArtifactDirPath = Path.Combine(_coreToolsHostExtractedRootDir, rid);
EnsureArtifactDirectoryExist(coreToolsHostArtifactDirPath);
var coreToolsHostCopyTask = Task.Run(() => FileUtilities.CopyDirectory(coreToolsHostArtifactDirPath, consolidatedArtifactDirPath));

await Task.WhenAll(inProc8CopyTask, inProc6CopyTask, coreToolsHostCopyTask);
await Task.Run(() => FileUtilities.CopyDirectory(coreToolsHostArtifactDirPath, consolidatedArtifactDirPath));
Directory.Delete(coreToolsHostArtifactDirPath, true);

// consolidatedArtifactDirPath now contains custom core-tools host, in-proc6 and in-proc8 sub directories. Create a zip file.
var zipPath = Path.Combine(customHostTargetArtifactDir, $"{consolidatedArtifactDirName}.zip");
await Task.Run(() => FileUtilities.CreateZipFile(consolidatedArtifactDirPath, zipPath));
Console.WriteLine($"Successfully created target runtime zip at: {zipPath}");

Directory.Delete(consolidatedArtifactDirPath, true);
aishwaryabh marked this conversation as resolved.
Show resolved Hide resolved
});
}

// Delete directories
Directory.Delete(_inProc6ExtractedRootDir, true);
Directory.Delete(_inProc8ExtractedRootDir, true);
Directory.Delete(_coreToolsHostExtractedRootDir, true);

await Task.WhenAll(packTasks);
Console.WriteLine("Finished assembling Visual Studio Core Tools artifacts");
}

Expand Down Expand Up @@ -239,6 +265,8 @@ private async Task CreateCliCoreToolsAsync()
// If we are currently on the minified version of the artifacts, we do not want the inproc6/inproc8 subfolders
if (artifactName.Contains("min.win"))
{
Console.WriteLine($"Finished assembling {consolidatedArtifactDirPath}");
Console.WriteLine();
continue;
}

Expand All @@ -256,31 +284,30 @@ private async Task CreateCliCoreToolsAsync()
inProc8ArtifactDirPath = Path.Combine(_inProc8ExtractedRootDir, artifactNameWithVersion);
}

// Rename inproc8 directory to have the same version as the out-of-proc artifact before copying
string newInProc8ArtifactDirPath = RenameInProcDirectory(inProc8ArtifactDirPath, outOfProcVersion);

// Copy in-proc8 files and delete old directory
await Task.Run(() => FileUtilities.CopyDirectory(newInProc8ArtifactDirPath, Path.Combine(consolidatedArtifactDirPath, Constants.InProc8DirectoryName)));
Directory.Delete(newInProc8ArtifactDirPath, true);
// Copy in-proc8 files
var inProc8FinalDestination = Path.Combine(consolidatedArtifactDirPath, Constants.InProc8DirectoryName);
await Task.Run(() => FileUtilities.CopyDirectory(inProc8ArtifactDirPath, Path.Combine(consolidatedArtifactDirPath, Constants.InProc8DirectoryName)));
Console.WriteLine($"Copied files from {inProc8ArtifactDirPath} => {inProc8FinalDestination}");

// Rename inproc6 directory to have the same version as the out-of-proc artifact before copying
var inProcArtifactName = Path.GetFileName(inProc8ArtifactDirPath);
var inProc6ArtifactDirPath = Path.Combine(_inProc6ExtractedRootDir, inProcArtifactName);
EnsureArtifactDirectoryExist(inProc6ArtifactDirPath);
string newInProc6ArtifactDirPath = RenameInProcDirectory(inProc6ArtifactDirPath, outOfProcVersion);

// Copy in-proc6 files and delete old directory
await Task.Run(() => FileUtilities.CopyDirectory(newInProc6ArtifactDirPath, Path.Combine(consolidatedArtifactDirPath, Constants.InProc6DirectoryName)));
Directory.Delete(newInProc6ArtifactDirPath, true);
// Copy in-proc6 files
var inProc6FinalDestination = Path.Combine(consolidatedArtifactDirPath, Constants.InProc6DirectoryName);
await Task.Run(() => FileUtilities.CopyDirectory(inProc6ArtifactDirPath, Path.Combine(consolidatedArtifactDirPath, Constants.InProc6DirectoryName)));
Console.WriteLine($"Copied files from {inProc8ArtifactDirPath} => {inProc8FinalDestination}");

Console.WriteLine($"Finished assembling {consolidatedArtifactDirPath}");
Console.WriteLine();
}

// Delete the extracted directories
Directory.Delete(_inProc6ExtractedRootDir, true);
Directory.Delete(_inProc8ExtractedRootDir, true);
Directory.Delete(_coreToolsHostExtractedRootDir, true);
Directory.Delete(_outOfProcExtractedRootDir, true);

Console.WriteLine("Finished assembling CLI Core Tools artifacts");
Console.WriteLine();
}

private (string artifactDirectory, string version) GetArtifactDirectoryAndVersionNumber(string extractedRootDirectory, string artifactName)
Expand All @@ -296,28 +323,9 @@ private async Task CreateCliCoreToolsAsync()
return (artifactDirPath, version);
}

private string RenameInProcDirectory(string oldArtifactDirPath, string newVersion)
{
Match match = Regex.Match(oldArtifactDirPath, Constants.ArtifactNameRegexPattern);

if (!match.Success)
{
throw new InvalidOperationException($"Unable to extract content before version number from '{oldArtifactDirPath}'.");
}

var artifactName = match.Groups[1];
var newDirectoryName = $"{artifactName}{newVersion}";

// Rename (move) the directory
Directory.Move(oldArtifactDirPath, newDirectoryName);

return newDirectoryName;

}

private string GetRuntimeIdentifierForArtifactName(string artifactName)
{
if (_customHostArtifacts.TryGetValue(artifactName, out var rid))
if (_visualStudioArtifacts.TryGetValue(artifactName, out var rid))
{
return rid;
}
Expand Down Expand Up @@ -346,5 +354,4 @@ private static async Task ExtractZipFilesInDirectoryAsync(string zipSourceDir, s
}
}
}
}

}
Loading
Loading