/// <summary> /// Returns a task which will complete when underlying upgrade completes. /// </summary> /// <param name="timeout"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task <FabricUpgradeProgress> GetCurrentRunningUpgradeTaskAsync( TimeSpan timeout, CancellationToken cancellationToken) { FabricUpgradeProgress fabricUpgradeProgress = null; var timeoutHelper = new TimeoutHelper(timeout, Constants.MaxOperationTimeout); while (true) { fabricUpgradeProgress = await this.fabricClient.ClusterManager.GetFabricUpgradeProgressAsync( timeoutHelper.GetOperationTimeout(), cancellationToken); Trace.WriteInfo(TraceType, "Current status: {0}", fabricUpgradeProgress.UpgradeState); if (IsUpgradeCompleted(fabricUpgradeProgress.UpgradeState)) { break; } if (IsUpgradeInUnSupportedState(fabricUpgradeProgress.UpgradeState)) { throw new NotSupportedException(string.Format("Cluster Fabric upgrade is in state {0}", fabricUpgradeProgress.UpgradeState)); } var delayTime = timeoutHelper.GetRemainingTime(); if (delayTime.CompareTo(TimeSpan.FromSeconds(DelayTimeoutInSeconds)) > 0) { delayTime = TimeSpan.FromSeconds(DelayTimeoutInSeconds); } await Task.Delay(delayTime, cancellationToken); } return(fabricUpgradeProgress); }
/// <summary> /// Provisions the Service Fabric by using the specified timeout and cancellation token. /// </summary> /// <param name="codePathInImageStore"></param> /// <param name="configPathInImageStore"></param> /// <param name="timeout"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task ProvisionFabricAsync(string codePathInImageStore, string configPathInImageStore, TimeSpan timeout, CancellationToken cancellationToken) { var timeoutHelper = new TimeoutHelper(timeout, timeout); await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync(() => this.fabricClient.ClusterManager.ProvisionFabricAsync( codePathInImageStore, configPathInImageStore, timeoutHelper.GetOperationTimeout(), cancellationToken), FabricClientRetryErrors.ProvisionFabricErrors.Value, timeoutHelper.GetRemainingTime(), cancellationToken).ConfigureAwait(false); }
/// <summary> /// Deletes the cluster manifest file and/or Service Fabric code package from the image store. /// </summary> /// <param name="imageStoreConnectionString"></param> /// <param name="clusterManifestPath"></param> /// <param name="clusterManifestPathInImageStore"></param> /// <param name="codePackagePath"></param> /// <param name="codePackagePathInImageStore"></param> /// <param name="timeout"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task RemoveClusterPackageAsync( string imageStoreConnectionString, string clusterManifestPathInImageStore, string codePackagePathInImageStore, TimeSpan timeout, CancellationToken cancellationToken) { var timeoutHelper = new TimeoutHelper(timeout, timeout); await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync(() => Task.Run(() => this.fabricClient.ClusterManager.RemoveClusterPackage( imageStoreConnectionString, clusterManifestPathInImageStore, codePackagePathInImageStore) ), timeoutHelper.GetRemainingTime(), cancellationToken).ConfigureAwait(false); }
/// <summary> /// Copy and provision upgrade package. /// </summary> /// <param name="commandParameter"></param> /// <param name="targetCodeVersion"></param> /// <param name="targetConfigVersion"></param> /// <param name="timeoutHelper"></param> /// <param name="cancellationToken"></param> /// <returns></returns> internal async Task CopyAndProvisionUpgradePackageAsync( ClusterUpgradeCommandParameter commandParameter, string targetCodeVersion, string targetConfigVersion, TimeoutHelper timeoutHelper, CancellationToken cancellationToken) { var imageStorePath = string.IsNullOrWhiteSpace(targetCodeVersion) ? string.Empty : targetCodeVersion; imageStorePath += string.IsNullOrWhiteSpace(targetConfigVersion) ? string.Empty : "_" + targetConfigVersion; imageStorePath = imageStorePath.Trim('_'); Trace.WriteInfo(TraceType, "CopyAndProvision"); var configFileName = string.Empty; var codeFileName = string.Empty; var configPathInImageStore = string.Empty; var codePathInImageStore = string.Empty; if (!string.IsNullOrWhiteSpace(commandParameter.ConfigFilePath)) { configFileName = Path.GetFileName(commandParameter.ConfigFilePath); configPathInImageStore = Path.Combine(imageStorePath, configFileName); } if (!string.IsNullOrWhiteSpace(commandParameter.CodeFilePath)) { codeFileName = Path.GetFileName(commandParameter.CodeFilePath); codePathInImageStore = Path.Combine(imageStorePath, codeFileName); } if (string.IsNullOrWhiteSpace(configFileName) && string.IsNullOrWhiteSpace(codeFileName)) { return; } var configFilePath = commandParameter.ConfigFilePath; var codeFilePath = commandParameter.CodeFilePath; if (!string.IsNullOrWhiteSpace(targetCodeVersion)) { var provisionedCodeList = await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync(() => this.fabricClient.QueryManager.GetProvisionedFabricCodeVersionListAsync(targetCodeVersion), timeoutHelper.GetOperationTimeout(), cancellationToken).ConfigureAwait(false); if (provisionedCodeList.Count != 0) { Trace.WriteInfo(TraceType, "Code Already provisioned: {0}", targetCodeVersion); codePathInImageStore = null; codeFilePath = null; } } if (!string.IsNullOrWhiteSpace(targetConfigVersion)) { var provisionedConfigList = await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync(() => this.fabricClient.QueryManager.GetProvisionedFabricConfigVersionListAsync(targetConfigVersion), timeoutHelper.GetOperationTimeout(), cancellationToken).ConfigureAwait(false); if (provisionedConfigList.Count != 0) { Trace.WriteInfo(TraceType, "Config Already provisioned: {0}", targetConfigVersion); configPathInImageStore = null; configFilePath = null; } } // Get current cluster manifest file if (string.IsNullOrWhiteSpace(this.imageStoreConnectionString)) { var clusterManifest = await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync(() => this.fabricClient.ClusterManager.GetClusterManifestAsync( timeoutHelper.GetOperationTimeout(), cancellationToken), timeoutHelper.GetOperationTimeout(), cancellationToken).ConfigureAwait(false); // Get image store connection string if it not yet done. this.imageStoreConnectionString = GetImageStoreConnectionString(clusterManifest); } if (!string.IsNullOrWhiteSpace(configPathInImageStore) || !string.IsNullOrWhiteSpace(codePathInImageStore)) { // CopyClusterPackage is not an async API, so ideally we should create a sync version of ExecuteFabricActionWithRetry and don't spawn a new task thread here. // However, the copy and provision call doesn't happen all the time so there's no perf consideration here to have an extra thread. // Also, I don't see why CopyClusterPackage shouldn't expose an async version in the future. // So, don't bother to create a sync version of ExecuteFabricActionWithRetryAsync. await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync(() => Task.Run( delegate { Trace.WriteInfo(TraceType, "Copy to ImageStorePath: {0}", imageStorePath); this.fabricClient.ClusterManager.CopyClusterPackage( this.imageStoreConnectionString, configFilePath, configPathInImageStore, codeFilePath, codePathInImageStore, timeoutHelper.GetOperationTimeout()); }), timeoutHelper.GetRemainingTime(), cancellationToken).ConfigureAwait(false); Trace.WriteInfo(TraceType, "Completed Copy to ImageStorePath: {0}", imageStorePath); // Provision the code and config Trace.WriteInfo( TraceType, "Provision codePath:{0} configPath:{1}", codePathInImageStore, configPathInImageStore); await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync(() => this.fabricClient.ClusterManager.ProvisionFabricAsync( codePathInImageStore, configPathInImageStore, timeoutHelper.GetOperationTimeout(), cancellationToken), FabricClientRetryErrors.ProvisionFabricErrors.Value, timeoutHelper.GetRemainingTime(), cancellationToken).ConfigureAwait(false); Trace.WriteInfo( TraceType, "Completed Provision codePath:{0} configPath:{1}", codePathInImageStore, configPathInImageStore); } }