public WindowsUpdateServiceCoordinator(IConfigStore configStore, string configSection, KeyValueStoreReplica kvsReplica, IStatefulServicePartition partition, IExceptionHandlingPolicy exceptionPolicy) { configStore.ThrowIfNull("configStore"); configSection.ThrowIfNullOrWhiteSpace("configSectionName"); kvsReplica.ThrowIfNull("kvsReplica"); partition.ThrowIfNull("partition"); exceptionPolicy.ThrowIfNull("exceptionPolicy"); this.commandProcessor = new FabricClientWrapper(); this.store = kvsReplica; this.partition = partition; this.packageRetriever = new UpdatePackageRetriever(); this.serviceName = new Uri(Constants.SystemServicePrefix + configSection); this.configStore = configStore; this.configSectionName = configSection; this.exceptionPolicy = exceptionPolicy; // Read all the configuration values string coordinatorType = configStore.ReadUnencryptedString(configSection, Constants.ConfigurationSection.CoordinatorType); this.testMode = false; this.testSrcDir = string.Empty; if (coordinatorType.Equals(Constants.ConfigurationSection.WUTestCoordinator)) { this.testSrcDir = configStore.ReadUnencryptedString(configSection, Constants.WUSCoordinator.TestCabFolderParam); this.testMode = true; } this.waitTimeBeforePolling = TimeSpan.FromMinutes(Constants.WUSCoordinator.PollingIntervalInMinutesDefault); this.windowsUpdateApiTimeout = TimeSpan.FromMinutes(Constants.WUSCoordinator.WuApiTimeoutInMinutesDefault); }
private void Initialize( IConfigStore configStore, string configSectionName, KeyValueStoreReplica kvsStore, IStatefulServicePartition partition) { var baseUrlStr = configStore.ReadUnencryptedString(configSectionName, Constants.ConfigurationSection.BaseUrl); var clusterId = configStore.ReadUnencryptedString(Constants.ConfigurationSection.PaasSectionName, Constants.ConfigurationSection.ClusterId); var primaryNodeTypes = GetPrimaryNodeTypes(configStore, configSectionName); // Error checking baseUrlStr.ThrowIfNullOrWhiteSpace("baseUrlStr"); clusterId.ThrowIfNullOrWhiteSpace("clusterId"); Uri baseUrl; if (!Uri.TryCreate(baseUrlStr, UriKind.Absolute, out baseUrl)) { throw new ArgumentException("BaseUrl in clusterManifest is not of Uri type"); } Trace.WriteNoise(TraceType, "BaseUrl: {0}", baseUrl); var wrpStreamChannelUrlStr = Path.Combine(baseUrlStr, clusterId); Uri wrpStreamChannelUri; if (!Uri.TryCreate(wrpStreamChannelUrlStr, UriKind.Absolute, out wrpStreamChannelUri)) { throw new ArgumentException($"StreamChannel URL is not of Uri type: {wrpStreamChannelUrlStr}"); } Trace.WriteInfo(TraceType, "StreamChannel URL: {0}", wrpStreamChannelUrlStr); var wrpPollUrlStr = $"{wrpStreamChannelUrlStr}?api-version={ApiVersion}"; Uri wrpPollUri; if (!Uri.TryCreate(wrpPollUrlStr, UriKind.Absolute, out wrpPollUri)) { throw new ArgumentException($"Poll URL is not of Uri type: {wrpPollUrlStr}"); } Trace.WriteInfo(TraceType, "Poll URL: {0}", wrpPollUrlStr); var fabricClientWrapper = new FabricClientWrapper(); var resourceCommandProcessors = new Dictionary <ResourceType, IResourceCommandProcessor>() { { ResourceType.Cluster, new ClusterCommandProcessor( configStore, configSectionName, fabricClientWrapper, new CommandParameterGenerator(fabricClientWrapper), new NodeStatusManager(kvsStore, configStore, configSectionName), JsonSerializer.Create(WrpGatewayClient.SerializerSettings), primaryNodeTypes) }, { ResourceType.ApplicationType, new ApplicationTypeCommandProcessor( new ApplicationTypeClient(fabricClientWrapper.FabricClient, configStore, configSectionName)) }, { ResourceType.Application, new ApplicationCommandProcessor( new ApplicationClient(fabricClientWrapper.FabricClient)) }, { ResourceType.Service, new ServiceCommandProcessor( new ServiceClient(fabricClientWrapper.FabricClient)) } }; this.coordinators = new List <IUpgradeCoordinator> { new ResourceCoordinator( kvsStore, configStore, configSectionName, resourceCommandProcessors, new WrpPackageRetriever(wrpPollUri, clusterId, configStore, configSectionName), new ExceptionHandlingPolicy(Constants.PaasCoordinator.SFRPPollHealthProperty, ResourceCoordinator.TaskName, configStore, configSectionName, partition)), new StreamChannelCoordinator( new WrpStreamChannel(wrpStreamChannelUri, clusterId, configStore, configSectionName), new ExceptionHandlingPolicy(Constants.PaasCoordinator.SFRPStreamChannelHealthProperty, StreamChannelCoordinator.TaskName, configStore, configSectionName, partition)) }; }
private async Task UpgradeClusterAsync(ClusterUpgradeCommandParameter upgradeCommandParameter, CancellationToken token) { if (upgradeCommandParameter == null) { Trace.WriteInfo(TraceType, "upgradeCommandParameter is null. No op."); return; } if (string.IsNullOrWhiteSpace(upgradeCommandParameter.ConfigFilePath) && string.IsNullOrWhiteSpace(upgradeCommandParameter.CodeFilePath)) { Trace.WriteInfo(TraceType, "upgradeCommandParameter .ConfigFilePath=null and .CodeFilePath=null. No op."); return; } Trace.WriteInfo(TraceType, "Upgrade command parameters: CodePath: {0}, CodeVersion: {1}, ConfigPath: {2}, ConfigVersion: {3}", upgradeCommandParameter.CodeFilePath, upgradeCommandParameter.CodeVersion, upgradeCommandParameter.ConfigFilePath, upgradeCommandParameter.ConfigVersion); // Determine targetCodeVersion & targetConfigVersion var targetCodeVersion = upgradeCommandParameter.CodeVersion; var targetConfigVersion = upgradeCommandParameter.ConfigVersion; if (!string.IsNullOrWhiteSpace(upgradeCommandParameter.ConfigFilePath) && string.IsNullOrWhiteSpace(targetConfigVersion)) { // If config version is not mentioned then read it from given manifest file targetConfigVersion = FabricClientWrapper.GetConfigVersion(upgradeCommandParameter.ConfigFilePath); } // Get root image store path var imageStorePath = GetImageStorePath(targetCodeVersion, targetConfigVersion); // Build cluster package file paths in image store var configFileName = string.Empty; var codeFileName = string.Empty; var configPathInImageStore = string.Empty; var codePathInImageStore = string.Empty; if (!string.IsNullOrWhiteSpace(upgradeCommandParameter.ConfigFilePath)) { configFileName = Path.GetFileName(upgradeCommandParameter.ConfigFilePath); configPathInImageStore = Path.Combine(imageStorePath, configFileName); } if (!string.IsNullOrWhiteSpace(upgradeCommandParameter.CodeFilePath)) { codeFileName = Path.GetFileName(upgradeCommandParameter.CodeFilePath); codePathInImageStore = Path.Combine(imageStorePath, codeFileName); } // Determine cluster package content that needs to be published. var configFilePath = upgradeCommandParameter.ConfigFilePath; var codeFilePath = upgradeCommandParameter.CodeFilePath; if (!string.IsNullOrWhiteSpace(targetCodeVersion)) { var provisionedCodeList = await this.fabricClientWrapper.GetProvisionedFabricCodeVersionListAsync(targetCodeVersion, Constants.MaxOperationTimeout, token); if (provisionedCodeList.Count != 0) { Trace.WriteInfo(TraceType, "Code Already provisioned: {0}", targetCodeVersion); codePathInImageStore = null; codeFilePath = null; } } if (!string.IsNullOrWhiteSpace(targetConfigVersion)) { var provisionedConfigList = await this.fabricClientWrapper.GetProvisionedFabricConfigVersionListAsync(targetConfigVersion, Constants.MaxOperationTimeout, token); if (provisionedConfigList.Count != 0) { Trace.WriteInfo(TraceType, "Config Already provisioned: {0}", targetConfigVersion); configPathInImageStore = null; configFilePath = null; } } if (string.IsNullOrWhiteSpace(configPathInImageStore) && string.IsNullOrWhiteSpace(codePathInImageStore)) { Trace.WriteInfo(TraceType, "Both code={0} and config={1} are already provisioned. No op.", targetCodeVersion, targetConfigVersion); } else { Trace.WriteInfo( TraceType, "UpgradeClusterAsync: CodePath {0}, CodeVersion {1}, ConfigPath {2}, ConfigVersion {3}", codeFilePath ?? "null", targetCodeVersion ?? "null", configFilePath ?? "null", targetConfigVersion ?? "null"); var imageStoreConnectionString = this.configStore.ReadUnencryptedString(Constants.ManagementSection.ManagementSectionName, Constants.ManagementSection.ImageStoreConnectionString); var copyTimeout = this.configStore.ReadTimeSpan(this.configSectionName, Constants.ConfigurationSection.CopyClusterPackageTimeoutInSeconds, TimeSpan.FromSeconds(180)); Trace.WriteInfo( TraceType, "UpgradeClusterAsync: CopyClusterPackageAsync: Config:{0}->{1} Code:{2}->{3} Timeout:{4}", configFilePath ?? "null", configPathInImageStore ?? "null", codeFilePath ?? "null", codePathInImageStore ?? "null", copyTimeout); await this.fabricClientWrapper.CopyClusterPackageAsync( imageStoreConnectionString, configFilePath, configPathInImageStore, codeFilePath, codePathInImageStore, copyTimeout, token); Trace.WriteInfo( TraceType, "UpgradeClusterAsync: CopyClusterPackageAsync - Completed"); var provisionTimeout = this.configStore.ReadTimeSpan(this.configSectionName, Constants.ConfigurationSection.ProvisionClusterPackageTimeoutInSeconds, TimeSpan.FromSeconds(300)); Trace.WriteInfo( TraceType, "UpgradeClusterAsync: ProvisionFabricAsync: Config:{0} Code:{1} Timeout:{2}", configPathInImageStore ?? "null", codePathInImageStore ?? "null", provisionTimeout); try { await this.fabricClientWrapper.ProvisionFabricAsync( codePathInImageStore, configPathInImageStore, provisionTimeout, token); Trace.WriteInfo( TraceType, "UpgradeClusterAsync: ProvisionFabricAsync - Completed"); } finally { try { Trace.WriteInfo( TraceType, "UpgradeClusterAsync: RemoveClusterPackageAsync: Config:{0} Code:{1} Timeout:{2}", configPathInImageStore ?? "null", codePathInImageStore ?? "null", copyTimeout); await this.fabricClientWrapper.RemoveClusterPackageAsync( imageStoreConnectionString, codePathInImageStore, configPathInImageStore, copyTimeout, token); Trace.WriteInfo( TraceType, "UpgradeClusterAsync: RemoveClusterPackageAsync: Config:{0} Code:{1} - Completed", configPathInImageStore ?? "null", codePathInImageStore ?? "null"); } catch (Exception ex) { Trace.WriteWarning( TraceType, "UpgradeClusterAsync: RemoveClusterPackageAsync: Config:{0} Code:{1}. Failed with exception: {2}", configPathInImageStore ?? "null", codePathInImageStore ?? "null", ex); } } } var startUpgradeTimeout = this.configStore.ReadTimeSpan(this.configSectionName, Constants.ConfigurationSection.StartClusterUpgradeTimeoutInSeconds, TimeSpan.FromSeconds(180)); Trace.WriteInfo( TraceType, "UpgradeClusterAsync: CodeVersion:{0} ConfigVersion:{1} Timeout:{2}", targetCodeVersion ?? "null", targetConfigVersion ?? "null", startUpgradeTimeout); await this.fabricClientWrapper.UpgradeFabricAsync(upgradeCommandParameter.UpgradeDescription, targetCodeVersion, targetConfigVersion, startUpgradeTimeout, token); Trace.WriteInfo( TraceType, "UpgradeClusterAsync: CodeVersion:{0} ConfigVersion:{1} - Started", targetCodeVersion ?? "null", targetConfigVersion ?? "null"); }