src/WebJobs.Script.WebHost/ContainerManagement/LinuxContainerInitializationHostedService.cs (66 lines of code) (raw):
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Script.WebHost.Management;
using Microsoft.Azure.WebJobs.Script.WebHost.Models;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace Microsoft.Azure.WebJobs.Script.WebHost.ContainerManagement
{
public abstract class LinuxContainerInitializationHostedService : IHostedService
{
private readonly IEnvironment _environment;
private readonly IInstanceManager _instanceManager;
private readonly ILogger _logger;
private readonly StartupContextProvider _startupContextProvider;
private CancellationToken _cancellationToken;
public LinuxContainerInitializationHostedService(IEnvironment environment, IInstanceManager instanceManager, ILogger logger, StartupContextProvider startupContextProvider)
{
_environment = environment;
_instanceManager = instanceManager;
_logger = logger;
_startupContextProvider = startupContextProvider;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogDebug("Starting container initialization service.");
_cancellationToken = cancellationToken;
// The service should be registered in Linux Consumption only, but do additional check here.
if (_environment.IsAnyLinuxConsumption())
{
await ApplyStartContextIfPresent(cancellationToken);
}
}
private async Task ApplyStartContextIfPresent(CancellationToken cancellationToken)
{
(bool hasStartContext, string startContext) = await TryGetStartContextOrNullAsync(cancellationToken);
if (hasStartContext && !string.IsNullOrEmpty(startContext))
{
_logger.LogDebug("Applying host context");
var encryptedAssignmentContext = JsonConvert.DeserializeObject<EncryptedHostAssignmentContext>(startContext);
var assignmentContext = _startupContextProvider.SetContext(encryptedAssignmentContext);
await SpecializeMSISideCar(assignmentContext);
try
{
bool success = await _instanceManager.AssignInstanceAsync(assignmentContext);
_logger.LogDebug("AssignInstanceAsync was invoked (Success={success})", success);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to assign instance.");
}
}
else
{
_logger.LogDebug("No host context specified. Waiting for host assignment");
}
}
protected abstract Task<(bool HasStartContext, string StartContext)> TryGetStartContextOrNullAsync(CancellationToken cancellationToken);
protected abstract Task SpecializeMSISideCar(HostAssignmentContext assignmentContext);
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
}