Skip to content

Commit

Permalink
Fix: Workload socket issue for concurrent module create (#5876) (#5885)…
Browse files Browse the repository at this point in the history
… (#5907)

Cherry pick of: 5712dcc



## Azure IoT Edge PR checklist:
  • Loading branch information
huguesBouvier authored Dec 10, 2021
1 parent f41d1b5 commit 26bbf71
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public static class Constants

public const string EdgeModuleHubServerCertificateFileKey = "EdgeModuleHubServerCertificateFile";

public const string CheckImagePullBeforeModuleCreate = "CheckImagePullBeforeModuleCreate";

public const string Unknown = "Unknown";

public const string UpstreamProtocolKey = "UpstreamProtocol";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ public class EdgeletCommandFactory<T> : ICommandFactory
readonly ICombinedConfigProvider<T> combinedConfigProvider;
readonly string edgeDeviceHostname;
readonly Option<string> parentEdgeHostname;
readonly bool checkImagePullBeforeModuleCreate;

public EdgeletCommandFactory(
IModuleManager moduleManager,
IConfigSource configSource,
ICombinedConfigProvider<T> combinedConfigProvider)
ICombinedConfigProvider<T> combinedConfigProvider,
bool checkImagePullBeforeModuleCreate)
{
this.moduleManager = Preconditions.CheckNotNull(moduleManager, nameof(moduleManager));
this.configSource = Preconditions.CheckNotNull(configSource, nameof(configSource));
Expand All @@ -32,19 +34,41 @@ public EdgeletCommandFactory(
}

this.parentEdgeHostname = Option.Maybe(this.configSource.Configuration.GetValue<string>(Constants.GatewayHostnameVariableName));
this.checkImagePullBeforeModuleCreate = checkImagePullBeforeModuleCreate;
}

public Task<ICommand> CreateAsync(IModuleWithIdentity module, IRuntimeInfo runtimeInfo) =>
Task.FromResult(
CreateOrUpdateCommand.BuildCreate(
this.moduleManager,
module.Module,
module.ModuleIdentity,
this.configSource,
this.combinedConfigProvider.GetCombinedConfig(module.Module, runtimeInfo),
this.edgeDeviceHostname,
this.parentEdgeHostname)
as ICommand);
public Task<ICommand> CreateAsync(IModuleWithIdentity module, IRuntimeInfo runtimeInfo)
{
if (this.checkImagePullBeforeModuleCreate)
{
T config = this.combinedConfigProvider.GetCombinedConfig(module.Module, runtimeInfo);
return Task.FromResult(
new GroupCommand(
new PrepareUpdateCommand(this.moduleManager, module.Module, config),
CreateOrUpdateCommand.BuildCreate(
this.moduleManager,
module.Module,
module.ModuleIdentity,
this.configSource,
config,
this.edgeDeviceHostname,
this.parentEdgeHostname)
as ICommand) as ICommand);
}
else
{
return Task.FromResult(
CreateOrUpdateCommand.BuildCreate(
this.moduleManager,
module.Module,
module.ModuleIdentity,
this.configSource,
this.combinedConfigProvider.GetCombinedConfig(module.Module, runtimeInfo),
this.edgeDeviceHostname,
this.parentEdgeHostname)
as ICommand);
}
}

public Task<ICommand> UpdateAsync(IModule current, IModuleWithIdentity next, IRuntimeInfo runtimeInfo) =>
this.UpdateAsync(Option.Some(current), next, runtimeInfo, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public PrepareUpdateCommand(IModuleManager moduleManager, IModule module, object

public string Id => $"PrepareUpdateCommand({this.module.Name})";

public string Show() => $"Prepare update module {this.module.Name}";
public string Show() => $"Prepare module {this.module.Name}";

public Task ExecuteAsync(CancellationToken token)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,14 +178,15 @@ public static async Task<int> MainAsync(IConfiguration configuration)
case Constants.IotedgedMode:
string managementUri = configuration.GetValue<string>(Constants.EdgeletManagementUriVariableName);
string workloadUri = configuration.GetValue<string>(Constants.EdgeletWorkloadUriVariableName);
bool checkImagePullBeforeModuleCreate = configuration.GetValue<bool>(Constants.CheckImagePullBeforeModuleCreate, true);
iothubHostname = configuration.GetValue<string>(Constants.IotHubHostnameVariableName);
deviceId = configuration.GetValue<string>(Constants.DeviceIdVariableName);
string moduleId = configuration.GetValue(Constants.ModuleIdVariableName, Constants.EdgeAgentModuleIdentityName);
string moduleGenerationId = configuration.GetValue<string>(Constants.EdgeletModuleGenerationIdVariableName);
apiVersion = configuration.GetValue<string>(Constants.EdgeletApiVersionVariableName);
TimeSpan performanceMetricsUpdateFrequency = configuration.GetTimeSpan("PerformanceMetricsUpdateFrequency", TimeSpan.FromMinutes(5));
builder.RegisterModule(new AgentModule(maxRestartCount, intensiveCareTime, coolOffTimeUnitInSeconds, usePersistentStorage, storagePath, Option.Some(new Uri(workloadUri)), Option.Some(apiVersion), moduleId, Option.Some(moduleGenerationId), enableNonPersistentStorageBackup, storageBackupPath, storageTotalMaxWalSize, storageMaxManifestFileSize, storageMaxOpenFiles, storageLogLevel));
builder.RegisterModule(new EdgeletModule(iothubHostname, deviceId, new Uri(managementUri), new Uri(workloadUri), apiVersion, dockerAuthConfig, upstreamProtocol, proxy, productInfo, closeOnIdleTimeout, idleTimeout, performanceMetricsUpdateFrequency, useServerHeartbeat, backupConfigFilePath));
builder.RegisterModule(new EdgeletModule(iothubHostname, deviceId, new Uri(managementUri), new Uri(workloadUri), apiVersion, dockerAuthConfig, upstreamProtocol, proxy, productInfo, closeOnIdleTimeout, idleTimeout, performanceMetricsUpdateFrequency, useServerHeartbeat, backupConfigFilePath, checkImagePullBeforeModuleCreate));
IEnumerable<X509Certificate2> trustBundle =
await CertificateHelper.GetTrustBundleFromEdgelet(new Uri(workloadUri), apiVersion, Constants.WorkloadApiVersion, moduleId, moduleGenerationId);
CertificateHelper.InstallCertificates(trustBundle, logger);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class EdgeletModule : Module
readonly TimeSpan performanceMetricsUpdateFrequency;
readonly bool useServerHeartbeat;
readonly string backupConfigFilePath;
readonly bool checkImagePullBeforeModuleCreate;

public EdgeletModule(
string iotHubHostname,
Expand All @@ -59,7 +60,8 @@ public EdgeletModule(
TimeSpan idleTimeout,
TimeSpan performanceMetricsUpdateFrequency,
bool useServerHeartbeat,
string backupConfigFilePath)
string backupConfigFilePath,
bool checkImagePullBeforeModuleCreate)
{
this.iotHubHostName = Preconditions.CheckNonWhiteSpace(iotHubHostname, nameof(iotHubHostname));
this.deviceId = Preconditions.CheckNonWhiteSpace(deviceId, nameof(deviceId));
Expand All @@ -75,6 +77,7 @@ public EdgeletModule(
this.performanceMetricsUpdateFrequency = performanceMetricsUpdateFrequency;
this.useServerHeartbeat = useServerHeartbeat;
this.backupConfigFilePath = Preconditions.CheckNonWhiteSpace(backupConfigFilePath, nameof(backupConfigFilePath));
this.checkImagePullBeforeModuleCreate = checkImagePullBeforeModuleCreate;
}

protected override void Load(ContainerBuilder builder)
Expand Down Expand Up @@ -129,7 +132,8 @@ protected override void Load(ContainerBuilder builder)
ICommandFactory factory = new EdgeletCommandFactory<CombinedDockerConfig>(
moduleManager,
configSource,
combinedDockerConfigProvider);
combinedDockerConfigProvider,
this.checkImagePullBeforeModuleCreate);
factory = new MetricsCommandFactory(factory, metricsProvider);
return new LoggingCommandFactory(factory, loggerFactory) as ICommandFactory;
})
Expand Down

0 comments on commit 26bbf71

Please sign in to comment.