/// <summary>UpdateInstallationStatus /// Restart System if after installation restart is required. /// </summary> public void HandleRestart() { TimeSpan utilityTaskTimeOut = TimeSpan.FromMinutes(this._serviceSettings.OperationTimeOutInMinutes); NodeAgentSfUtilityExitCodes wuOperationState = this._nodeAgentSfUtility.GetWuOperationState(utilityTaskTimeOut); _eventSource.InfoMessage("Handling restart. Current WU Operation State : {0}.", wuOperationState); switch (wuOperationState) { case NodeAgentSfUtilityExitCodes.InstallationCompleted: this._nodeAgentSfUtility.UpdateInstallationStatus(NodeAgentSfUtilityExitCodes.RestartRequested, null, utilityTaskTimeOut); this.RestartSystem(); break; case NodeAgentSfUtilityExitCodes.RestartRequested: this.RestartSystem(); break; case NodeAgentSfUtilityExitCodes.OperationCompleted: break; default: _eventSource.ErrorMessage("Invalid state : {0}", wuOperationState); break; } }
/// <summary> /// Changes the state machine state to Completed. /// </summary> public void CompleteWUOperations() { TimeSpan utilityTaskTimeOut = TimeSpan.FromMinutes(this._serviceSettings.OperationTimeOutInMinutes); NodeAgentSfUtilityExitCodes wuOperationState = this._nodeAgentSfUtility.GetWuOperationState(utilityTaskTimeOut); _eventSource.InfoMessage("Completing Wu Operation. Current state: {0}", wuOperationState); switch (wuOperationState) { case NodeAgentSfUtilityExitCodes.InstallationCompleted: case NodeAgentSfUtilityExitCodes.RestartNotNeeded: case NodeAgentSfUtilityExitCodes.RestartCompleted: this._nodeAgentSfUtility.UpdateInstallationStatus( NodeAgentSfUtilityExitCodes.OperationCompleted, null, utilityTaskTimeOut); break; case NodeAgentSfUtilityExitCodes.OperationCompleted: break; default: _eventSource.WarningMessage("Invalid WU state : " + wuOperationState); break; } }
/// <summary>UpdateInstallationStatus /// Restart System if after installation restart is required. /// </summary> public void HandleRestart() { TimeSpan utilityTaskTimeOut = TimeSpan.FromMinutes(this._serviceSettings.OperationTimeOutInMinutes); NodeAgentSfUtilityExitCodes wuOperationState = this._nodeAgentSfUtility.GetWuOperationState(utilityTaskTimeOut); _eventSource.InfoMessage("Handling restart. Current WU Operation State : {0}.", wuOperationState); string systemRestartDescription = "Installation attempted, now trying to restart the node."; switch (wuOperationState) { case NodeAgentSfUtilityExitCodes.InstallationCompleted: this._nodeAgentSfUtility.UpdateInstallationStatus(NodeAgentSfUtilityExitCodes.RestartRequested, null, utilityTaskTimeOut); this._nodeAgentSfUtility.ReportHealth(WUOperationStatus, systemRestartDescription, HealthState.Ok, -1, TimeSpan.FromMinutes(this._serviceSettings.OperationTimeOutInMinutes)); this.RestartSystem(); break; case NodeAgentSfUtilityExitCodes.RestartRequested: this._nodeAgentSfUtility.ReportHealth(WUOperationStatus, systemRestartDescription, HealthState.Ok, -1, TimeSpan.FromMinutes(this._serviceSettings.OperationTimeOutInMinutes)); this.RestartSystem(); break; case NodeAgentSfUtilityExitCodes.OperationCompleted: break; default: _eventSource.ErrorMessage("Invalid state : {0}", wuOperationState); break; } }
/// <summary> /// Resets the state machine. /// </summary> /// <returns></returns> public bool ResetStateMachine() { _eventSource.InfoMessage("Resetting State Machine."); TimeSpan utilityTaskTimeOut = TimeSpan.FromMinutes(this._serviceSettings.OperationTimeOutInMinutes); try { NodeAgentSfUtilityExitCodes wuOperationState = this._nodeAgentSfUtility.GetWuOperationState(utilityTaskTimeOut); switch (wuOperationState) { case NodeAgentSfUtilityExitCodes.None: break; case NodeAgentSfUtilityExitCodes.DownloadCompleted: this._nodeAgentSfUtility.UpdateSearchAndDownloadStatus(NodeAgentSfUtilityExitCodes.OperationAborted, null, utilityTaskTimeOut); break; default: this._nodeAgentSfUtility.UpdateInstallationStatus(NodeAgentSfUtilityExitCodes.OperationCompleted, null, utilityTaskTimeOut); break; } return(true); } catch (Exception e) { _eventSource.ErrorMessage("Not able to reset state machine. exception : {0}", e); return(false); } }
/// <summary> /// Utility to Report health for the NodeAgentService. Typical usecases are as below /// If windows update operation is not successful after exhausting all reties, user can post warning level health report /// If windows update operation is successfull, user can post Ok level health report. /// </summary> /// <param name="applicationName">Application name for constructing the servicename</param> /// <param name="healthProperty">Title for health report. Once the health report is set, any future updates should be done using same healthProperty.</param> /// <param name="healthDescription">Description of the health. In case of failure a good description is very helpful for quick mitigation.</param> /// <param name="healthState"><see cref="HealthState"/>Indicating the severity of the health report</param> /// <param name="timeToLiveInMinutes">Time to live for health report in the health manager in minutes. Default value is -1 indicating infinite time to live, any positive value indicates </param> /// <param name="timeout">Timeout for the async operation</param> /// <param name="cancellationToken">Cancellation token to cancel this async operation</param> /// <returns>Operation result in <see cref="NodeAgentSfUtilityExitCodes"/></returns> public NodeAgentSfUtilityExitCodes ReportHealth(Uri applicationName, String healthProperty, String healthDescription, HealthState healthState, long timeToLiveInMinutes, TimeSpan timeout, CancellationToken cancellationToken) { NodeAgentSfUtilityExitCodes result = HealthManagerHelper.PostServiceHealthReport(this.fabricClient, applicationName, ServiceNameSuffix, healthProperty, healthDescription, (System.Fabric.Health.HealthState)healthState, timeout, timeToLiveInMinutes); ServiceEventSource.Current.InfoMessage("CommandProcessor.ReportHealth returned {0}", result); return(result); }
public ExecutorDataForNtService GetExecutorDataForNtService() { string executorDataForNtServiceFilePath = Path.Combine(this._settingsManager.WorkFolder, ExecutorDataForNtServiceFileName); _eventSource.InfoMessage("Retrieving Executor data from {0}", executorDataForNtServiceFilePath); NodeAgentSfUtilityExitCodes exitCode = GetWuOperationState(TimeSpan.FromMinutes(this._serviceSettings.OperationTimeOutInMinutes)); return(SerializationUtility.DeserializeFromFile <ExecutorDataForNtService>(executorDataForNtServiceFilePath)); }
/// <summary> /// Gets the application status of a deployed application /// </summary> /// <param name="applicationName">Uri of the application to be queried.</param> /// <param name="timeout">Timeout for the async operation</param> /// <param name="cancellationToken">The cancellation token to cancel the async operation</param> /// <returns>A Task representing the asnyc operation, result of the task would be /// <see cref="NodeAgentSfUtilityExitCodes.Success"/> in case applicaiton exists, /// <see cref="NodeAgentSfUtilityExitCodes.ApplicationNotFound"/> in case applicaiton doesn't exists /// </returns> public async Task <NodeAgentSfUtilityExitCodes> GetApplicationDeployedStatusAsync(Uri applicationName, TimeSpan timeout, CancellationToken cancellationToken) { NodeAgentSfUtilityExitCodes result = await CoordinatorServiceHelper.GetApplicationDeployedStatusAsync(this.fabricClient, applicationName, timeout, cancellationToken); ServiceEventSource.Current.InfoMessage("CommandProcessor.GetApplicationDeployedStatusAsync returned {0}", result); return(result); }
/// <summary> /// Update the status of Search and Download operation /// </summary> /// <param name="nodeName">name of service fabric node</param> /// <param name="updateState">State of Wu operation, possible values are InstallationInProgress, InstallationCompleted, RestartRequested, RestartNotNeeded, OperationCompleted</param> /// <param name="operationResult">result of the install operation, can be null in case no results are there to be updated</param> /// <returns>true if operation is success else false.</returns> public bool UpdateSearchAndDownloadStatus(NodeAgentSfUtilityExitCodes updateState, WindowsUpdateOperationResult operationResult = null, TimeSpan timeout = default(TimeSpan)) { _eventSource.InfoMessage("Updating search and download status : updateState : {0}, operationResult : {1}, timeout : {2}", updateState, operationResult, timeout); this.ReportCurrentNodeStatus(operationResult); string filePath = Path.Combine(this._settingsManager.TempFolder, OperationResultFileName); string[] arguments; if (operationResult != null) { operationResult.Serialize(filePath); arguments = new string[] { "UpdateSearchAndDownloadStatus", this._nodeName, this._applicationUri.ToString(), updateState.ToString(), this._serviceSettings.WUOperationTimeOutInMinutes.ToString(), timeout.TotalSeconds.ToString(), filePath }; } else { arguments = new string[] { "UpdateSearchAndDownloadStatus", this._nodeName, this._applicationUri.ToString(), updateState.ToString(), this._serviceSettings.WUOperationTimeOutInMinutes.ToString(), timeout.TotalSeconds.ToString() }; } ProcessExecutor processExecutor = new ProcessExecutor(SfUtilityFileName, CreateProcessArgument(arguments)); long retries = 0; while (!this._cancellationToken.IsCancellationRequested) { if (processExecutor.Execute() == 0) { return(true); } if (retries >= this._serviceSettings.WUOperationRetryCount || this._cancellationToken.IsCancellationRequested) { break; } TimeSpan retryDelayTime = TimeSpan.FromMinutes(this._serviceSettings.WUDelayBetweenRetriesInMinutes); this._helper.WaitOnTask(Task.Delay(retryDelayTime), this._cancellationToken); retries++; } throw new Exception("Not able to update Search/download status."); }
private NodeAgentSfUtilityExitCodes WaitForInstallationApproval(CancellationToken cancellationToken) { _eventSource.InfoMessage("Waiting for Installation approval."); while (!cancellationToken.IsCancellationRequested) { NodeAgentSfUtilityExitCodes wuOperationState = this._nodeAgentSfUtility.GetWuOperationState(TimeSpan.FromMinutes(this._serviceSettings.OperationTimeOutInMinutes)); if (wuOperationState.Equals(NodeAgentSfUtilityExitCodes.InstallationApproved)) { _eventSource.InfoMessage("Installation Approved."); return(wuOperationState); } else if (wuOperationState.Equals(NodeAgentSfUtilityExitCodes.OperationCompleted) || wuOperationState.Equals(NodeAgentSfUtilityExitCodes.None)) { _eventSource.InfoMessage("Installation Approval failed."); return(NodeAgentSfUtilityExitCodes.Failure); } this._helper.WaitOnTask(Task.Delay(TimeSpan.FromMinutes(this._serviceSettings.WUDelayBetweenRetriesInMinutes)), cancellationToken); } _eventSource.InfoMessage("Installation Approval failed."); return(NodeAgentSfUtilityExitCodes.Failure); }
/// <summary> /// Updates the status of search and download operation in CoordinatorService's repliable store /// And updates the RepairTask with appropriate state as per the updateState provided /// </summary> /// <param name="nodeName">Name of current service fabric node</param> /// <param name="applicationName">Uri of the Patch Orchestration Application.</param> /// <param name="updateState">State of Wu operation, possible values are DownloadAvailable, DownloadCompleted, OperationCompleted</param> /// <param name="operationResult">result of the search and download operation, cannot be null</param> /// <param name="installationTimeout">Amount of time a node can undergo installation, during installation node would be in disabled state</param> /// <param name="timeout">Timeout for the async operation</param> /// <param name="cancellationToken">The cancellation token to cancel the async operation</param> /// <returns>Task containing result of operation, true for success, false for failure</returns> /// <returns> /// A Task representing the asnyc operation, result of the task would be <see cref="NodeAgentSfUtilityExitCodes.Success"/> in case of success /// Any other <see cref="NodeAgentSfUtilityExitCodes"/> in case of failure /// </returns> public async Task <NodeAgentSfUtilityExitCodes> UpdateSearchAndDownloadStatusAsync(String nodeName, Uri applicationName, NodeAgentSfUtilityExitCodes updateState, WindowsUpdateOperationResult operationResult, int installationTimeout, TimeSpan timeout, CancellationToken cancellationToken) { String taskDescription = null; String resultDetails = null; NodeAgentSfUtilityExitCodes result; ExecutorDataForRmTask executorData = new ExecutorDataForRmTask() { ExecutorSubState = updateState, ExecutorTimeoutInMinutes = installationTimeout }; if (null != operationResult) { int succeededOperations; int abortedOperations; int totalOperations; this.GetWuOperationResultCount(operationResult, out totalOperations, out abortedOperations, out succeededOperations); result = await CoordinatorServiceHelper.UpdateWuOperationResult( this.fabricClient, applicationName, operationResult, timeout, cancellationToken); if (result != NodeAgentSfUtilityExitCodes.Success) { return(result); } taskDescription = String.Format( "{0} updates successfully downloaded on {1}. Creating this repair task to install the downloaded updates", succeededOperations, operationResult.OperationTime); resultDetails = String.Format("{0} updates searched. {1} downloaded successfully, {2} downloads were aborted", operationResult.UpdateDetails.Count, succeededOperations, abortedOperations); } switch (updateState) { case NodeAgentSfUtilityExitCodes.DownloadCompleted: { result = await RepairManagerHelper.CreateRepairTaskForNode( this.fabricClient, nodeName, taskDescription, resultDetails, executorData, timeout, cancellationToken); break; } case NodeAgentSfUtilityExitCodes.OperationCompleted: { result = NodeAgentSfUtilityExitCodes.Success; break; } case NodeAgentSfUtilityExitCodes.OperationAborted: { ServiceEventSource.Current.InfoMessage(String.Format("Operation aborted for a claimed task")); result = await RepairManagerHelper.UpdateRepairTask(this.fabricClient, nodeName, RepairTaskState.Completed, RepairTaskResult.Failed, "Aborting the operation", updateState, timeout, cancellationToken); break; } default: { ServiceEventSource.Current.ErrorMessage( String.Format("UpdateSearchAndDownloadStatusAsync called with invalid state {0}", updateState)); result = NodeAgentSfUtilityExitCodes.InvalidArgument; break; } } ServiceEventSource.Current.InfoMessage("UpdateSearchAndDownloadStatusAsync result = {0}", result); return(result); }
/// <summary> /// Updates the repair task for current node /// </summary> /// <param name="fc">Fabric client object used for carrying out service fabric client requests</param> /// <param name="nodeName">Nodename against which repair task needs to be updated</param> /// <param name="taskState">State of the repair task <see cref="RepairTaskState"/></param> /// <param name="taskResultStatus">Result status for last completed operation by RE</param> /// <param name="resultDetails">Result details for last completed operation by RE</param> /// <param name="executorState">Substate of repair executor</param> /// <param name="timeout">Timeout for the async operation</param> /// <param name="cancellationToken">The cancellation token to cancel the async operation</param> /// <param name="restartRequesteDateTime">Timestamp at which restart was requested</param> /// <returns>A Task representing the asnyc operation</returns> internal static async Task <NodeAgentSfUtilityExitCodes> UpdateRepairTask(FabricClient fc, string nodeName, RepairTaskState taskState, RepairTaskResult taskResultStatus, string resultDetails, NodeAgentSfUtilityExitCodes executorState, TimeSpan timeout, CancellationToken cancellationToken, DateTime?restartRequesteDateTime) { try { var repairTask = await GetRepairTaskForNode(fc, nodeName, timeout, cancellationToken); if (null != repairTask) { await UpdateRepairTask(fc, repairTask, taskState, taskResultStatus, resultDetails, executorState, timeout, cancellationToken, restartRequesteDateTime); return(NodeAgentSfUtilityExitCodes.Success); } else { // If repair task does not exist we're in a unknown state. ServiceEventSource.Current.ErrorMessage( String.Format("RepairManagerHelper.UpdateRepairTask failed. No repair task found for this node")); return(NodeAgentSfUtilityExitCodes.RepairTaskInvalidState); } } catch (Exception e) { ServiceEventSource.Current.ErrorMessage( String.Format("RepairManagerHelper.UpdateRepairTask failed. Exception details {0}", e)); if (e is FabricTransientException) { return(NodeAgentSfUtilityExitCodes.RetryableException); } else { return(NodeAgentSfUtilityExitCodes.Failure); } } }
/// <summary> /// Updates the repair task for current node /// </summary> /// <param name="fc">Fabric client object used for carrying out service fabric client requests</param> /// <param name="nodeName">Nodename against which repair task needs to be updated</param> /// <param name="taskState">State of the repair task <see cref="RepairTaskState"/></param> /// <param name="taskResultStatus">Result status for last completed operation by RE</param> /// <param name="resultDetails">Result details for last completed operation by RE</param> /// <param name="executorState">Substate of repair executor</param> /// <param name="timeout">Timeout for the async operation</param> /// <param name="cancellationToken">The cancellation token to cancel the async operation</param> /// <returns>A Task representing the asnyc operation</returns> internal static async Task <NodeAgentSfUtilityExitCodes> UpdateRepairTask(FabricClient fc, string nodeName, RepairTaskState taskState, RepairTaskResult taskResultStatus, string resultDetails, NodeAgentSfUtilityExitCodes executorState, TimeSpan timeout, CancellationToken cancellationToken) { return(await UpdateRepairTask(fc, nodeName, taskState, taskResultStatus, resultDetails, executorState, timeout, cancellationToken, null)); }
/// <summary> /// Updates the repair task for current node /// </summary> /// <param name="fc">Fabric client object used for carrying out service fabric client requests</param> /// <param name="task">Repair task which needs to be updated</param> /// <param name="taskState">State of the repair task <see cref="RepairTaskState"/></param> /// <param name="taskResultStatus">Result status for last completed operation by RE</param> /// <param name="resultDetails">Result details for last completed operation by RE</param> /// <param name="executorState">Substate of repair executor</param> /// <param name="timeout">Timeout for the async operation</param> /// <param name="cancellationToken">The cancellation token to cancel the async operation</param> /// <returns>A Task representing the asnyc operation</returns> private static async Task UpdateRepairTask(FabricClient fc, RepairTask task, RepairTaskState taskState, RepairTaskResult taskResultStatus, string resultDetails, NodeAgentSfUtilityExitCodes executorState, TimeSpan timeout, CancellationToken cancellationToken, DateTime?restartRequesteDateTime) { // Do the actual work before mark the task as Executing. task.State = taskState; task.ResultStatus = taskResultStatus; task.ResultDetails = resultDetails; ExecutorDataForRmTask executorData = SerializationUtility.Deserialize <ExecutorDataForRmTask>(task.ExecutorData); executorData.ExecutorSubState = executorState; if (restartRequesteDateTime.HasValue) { executorData.RestartRequestedTime = restartRequesteDateTime.Value; } task.ExecutorData = SerializationUtility.Serialize(executorData); await fc.RepairManager.UpdateRepairExecutionStateAsync(task, timeout, cancellationToken); }
/// <summary> /// Update the status of installation operation in Coordinator Service's Relaible store /// Also update the status of repair task as per the updateState provided /// </summary> /// <param name="nodeName">Name of the service fabric node</param> /// <param name="applicationName">Uri of the Patch Orchestration Application.</param> /// <param name="updateState">State of Wu operation, possible values are InstallationInProgress, InstallationCompleted, RestartRequested, RestartNotNeeded, OperationCompleted</param> /// <param name="operationResult">result of the install operation, can be null in case no results are there to be updated</param> /// <param name="timeout">Timeout for the async operation</param> /// <param name="cancellationToken">The cancellation token to cancel the async operation</param> /// <returns> /// A Task representing the asnyc operation, result of the task would be <see cref="NodeAgentSfUtilityExitCodes.Success"/> in case of success /// Any other <see cref="NodeAgentSfUtilityExitCodes"/> in case of failure /// </returns> public async Task <NodeAgentSfUtilityExitCodes> UpdateInstallationStatusAsync(String nodeName, Uri applicationName, NodeAgentSfUtilityExitCodes updateState, WindowsUpdateOperationResult operationResult, TimeSpan timeout, CancellationToken cancellationToken) { NodeAgentSfUtilityExitCodes result; String resultDetails = null; if (operationResult != null) { int succeededOperations; int abortedOperations; int totalOperations; this.GetWuOperationResultCount(operationResult, out totalOperations, out abortedOperations, out succeededOperations); result = await CoordinatorServiceHelper.UpdateWuOperationResult( this.fabricClient, applicationName, operationResult, timeout, cancellationToken); if (result != NodeAgentSfUtilityExitCodes.Success) { return(result); } resultDetails = String.Format( "{0} out of {1} updates were installed successfully, {2} were aborted", succeededOperations, operationResult.UpdateDetails.Count, abortedOperations); } switch (updateState) { case NodeAgentSfUtilityExitCodes.InstallationCompleted: { result = await RepairManagerHelper.UpdateRepairTask( this.fabricClient, nodeName, RepairTaskState.Executing, RepairTaskResult.Pending, resultDetails, NodeAgentSfUtilityExitCodes.InstallationCompleted, timeout, cancellationToken); break; } case NodeAgentSfUtilityExitCodes.InstallationInProgress: { result = await RepairManagerHelper.UpdateRepairTask(this.fabricClient, nodeName, RepairTaskState.Executing, RepairTaskResult.Pending, resultDetails, NodeAgentSfUtilityExitCodes.InstallationInProgress, timeout, cancellationToken); break; } case NodeAgentSfUtilityExitCodes.RestartRequested: { resultDetails = "Installation of the updates completed, Restart pending"; result = await RepairManagerHelper.UpdateRepairTask(this.fabricClient, nodeName, RepairTaskState.Executing, RepairTaskResult.Pending, resultDetails, NodeAgentSfUtilityExitCodes.RestartRequested, timeout, cancellationToken, DateTime.UtcNow); break; } case NodeAgentSfUtilityExitCodes.RestartNotNeeded: { resultDetails = "Installation of the updates completed, Restart not needed"; result = await RepairManagerHelper.UpdateRepairTask(this.fabricClient, nodeName, RepairTaskState.Executing, RepairTaskResult.Pending, resultDetails, NodeAgentSfUtilityExitCodes.RestartNotNeeded, timeout, cancellationToken); break; } case NodeAgentSfUtilityExitCodes.RestartCompleted: { resultDetails = "Installation of the updates completed, Restart post installation completed successfully"; result = await RepairManagerHelper.UpdateRepairTask(this.fabricClient, nodeName, RepairTaskState.Executing, RepairTaskResult.Pending, resultDetails, NodeAgentSfUtilityExitCodes.RestartCompleted, timeout, cancellationToken); break; } case NodeAgentSfUtilityExitCodes.OperationCompleted: { ServiceEventSource.Current.InfoMessage(String.Format("Mark the operation as completed")); result = await RepairManagerHelper.UpdateRepairTask(this.fabricClient, nodeName, RepairTaskState.Restoring, RepairTaskResult.Succeeded, resultDetails, NodeAgentSfUtilityExitCodes.OperationCompleted, timeout, cancellationToken); break; } default: { ServiceEventSource.Current.ErrorMessage(String.Format("UpdateInstallationStatusAsync called with invalid state {0}", updateState)); result = NodeAgentSfUtilityExitCodes.InvalidArgument; break; } } ServiceEventSource.Current.InfoMessage("UpdateInstallationStatusAsync result = {0}", result); return(result); }
private bool HandleWUOperationStates(CancellationToken cancellationToken) { TimeSpan utilityTaskTimeOut = TimeSpan.FromMinutes(this._serviceSettings.OperationTimeOutInMinutes); NodeAgentSfUtilityExitCodes wuOperationState = this._nodeAgentSfUtility.GetWuOperationState(utilityTaskTimeOut); _eventSource.InfoMessage("Current WU Operation State : {0}", wuOperationState); bool reschedule = false; switch (wuOperationState) { case NodeAgentSfUtilityExitCodes.None: case NodeAgentSfUtilityExitCodes.OperationCompleted: { OperationResultCode searchResult = SearchUpdates(cancellationToken); reschedule = (searchResult != OperationResultCode.orcSucceeded ? true : reschedule); if (this._wuCollectionWrapper != null) { if (this._wuCollectionWrapper.Collection.Count == 0) { _eventSource.InfoMessage("No Windows Update available. Completing the operation."); //Complete operation. this._nodeAgentSfUtility.UpdateSearchAndDownloadStatus( NodeAgentSfUtilityExitCodes.OperationCompleted, this._operationResultFormatter.CreateSearchAndDownloadDummyResult(), utilityTaskTimeOut ); break; } OperationResultCode downloadResult = DownloadUpdates(cancellationToken); reschedule = (downloadResult != OperationResultCode.orcSucceeded ? true : reschedule); WindowsUpdateOperationResult searchAndDownloadResult = this._operationResultFormatter.FormatSearchAndDownloadResult(downloadResult, this._wuCollectionWrapper); _eventSource.InfoMessage("Search and download result: {0}", searchAndDownloadResult); this._nodeAgentSfUtility.UpdateSearchAndDownloadStatus(NodeAgentSfUtilityExitCodes.DownloadCompleted, searchAndDownloadResult, utilityTaskTimeOut); NodeAgentSfUtilityExitCodes exitCodes = this.WaitForInstallationApproval(cancellationToken); if (exitCodes.Equals(NodeAgentSfUtilityExitCodes.Failure)) { _eventSource.ErrorMessage("Not able to move from DownloadCompleted state to InstallationApproved state."); reschedule = true; break; } this._nodeAgentSfUtility.UpdateInstallationStatus(NodeAgentSfUtilityExitCodes.InstallationInProgress, null, utilityTaskTimeOut); OperationResultCode installResult = InstallUpdates(cancellationToken); reschedule = (installResult != OperationResultCode.orcSucceeded ? true : reschedule); WindowsUpdateOperationResult installationResult = this._operationResultFormatter.FormatInstallationResult(installResult, this._wuCollectionWrapper); _eventSource.InfoMessage("Installation result: {0}", installationResult); this._nodeAgentSfUtility.UpdateInstallationStatus(NodeAgentSfUtilityExitCodes.InstallationCompleted, installationResult, utilityTaskTimeOut); } break; } case NodeAgentSfUtilityExitCodes.DownloadCompleted: case NodeAgentSfUtilityExitCodes.InstallationApproved: { NodeAgentSfUtilityExitCodes exitCodes = this.WaitForInstallationApproval(cancellationToken); if (exitCodes.Equals(NodeAgentSfUtilityExitCodes.Failure)) { _eventSource.ErrorMessage("Not able to move from DownloadCompleted state to InstallationApproved state."); reschedule = true; break; } OperationResultCode searchResult = SearchUpdates(cancellationToken); reschedule = (searchResult != OperationResultCode.orcSucceeded ? true : reschedule); if (this._wuCollectionWrapper != null) { if (this._wuCollectionWrapper.Collection.Count == 0) { string msg = "Current Operation state : InstallationApproved but no updates found to install. Completing the operation."; this._nodeAgentSfUtility.ReportHealth("WindowsUpdateOperationResult", msg, HealthState.Warning, -1, TimeSpan.FromMinutes(this._serviceSettings.OperationTimeOutInMinutes)); _eventSource.WarningMessage(msg); //Complete operation. this._nodeAgentSfUtility.UpdateInstallationStatus( NodeAgentSfUtilityExitCodes.OperationCompleted, this._operationResultFormatter.CreateInstallationDummyResult(), utilityTaskTimeOut ); break; } this._nodeAgentSfUtility.UpdateInstallationStatus(NodeAgentSfUtilityExitCodes.InstallationInProgress, null, utilityTaskTimeOut); OperationResultCode installResult = InstallUpdates(cancellationToken); reschedule = (installResult != OperationResultCode.orcSucceeded ? true : reschedule); WindowsUpdateOperationResult installationResult = this._operationResultFormatter.FormatInstallationResult(installResult, this._wuCollectionWrapper); _eventSource.InfoMessage("Installation result: {0}", installationResult); this._nodeAgentSfUtility.UpdateInstallationStatus(NodeAgentSfUtilityExitCodes.InstallationCompleted, installationResult, utilityTaskTimeOut); } break; } case NodeAgentSfUtilityExitCodes.InstallationInProgress: { OperationResultCode searchResult = SearchUpdates(cancellationToken); reschedule = (searchResult != OperationResultCode.orcSucceeded ? true : reschedule); if (this._wuCollectionWrapper != null) { if (this._wuCollectionWrapper.Collection.Count == 0) { //this is possible when installation is completed but NT service is killed before updating "InstallationCompleted" status. break; } OperationResultCode installResult = InstallUpdates(cancellationToken); reschedule = (installResult != OperationResultCode.orcSucceeded ? true : reschedule); WindowsUpdateOperationResult installationResult = this._operationResultFormatter.FormatInstallationResult(installResult, this._wuCollectionWrapper); _eventSource.InfoMessage("Installation result: {0}", installationResult); this._nodeAgentSfUtility.UpdateInstallationStatus(NodeAgentSfUtilityExitCodes.InstallationCompleted, installationResult, utilityTaskTimeOut); } break; } default: break; } return(reschedule); }
// polls every 5 minutes, execute the callback if the date-time is according to frequency mentioned in Settings.xml. private void ScheduleTimer() { try { if (!this.CheckApplicationExists()) { _eventSource.InfoMessage("Application deleted. Removing NT service..."); this._windowsUpdateManager.ResetStateMachine(); this.RemoveSelf(); return; } // If cancellation token is canceled or application is not found if (this._cancellationToken.IsCancellationRequested) { _eventSource.InfoMessage("Canceled timer."); return; } NodeAgentSfUtilityExitCodes exitCode = this._nodeAgentSfUtility.GetWuOperationState( TimeSpan.FromMinutes(this._serviceSettings.OperationTimeOutInMinutes)); _eventSource.InfoMessage("Current Wu state: {0}", exitCode); if (exitCode == NodeAgentSfUtilityExitCodes.RestartRequested) { _eventSource.ErrorMessage("Not able to restart system."); //wait for sometime before retrying. This delay is recommended if posting health reports. if (this._helper.WaitOnTask(Task.Delay(TimeSpan.FromMinutes(WaitTimeInMinutes)), this._cancellationToken)) { this.ScheduleWindowsUpdates(); this.ScheduleTimer(); } return; } else if (exitCode == NodeAgentSfUtilityExitCodes.RestartCompleted) { this.ScheduleWindowsUpdates(); this.CreateNewCheckpointFile(); this.ScheduleTimer(); return; } CheckpointFileData fileData = this.ReadCheckpointFile(); if (fileData.rescheduleNeeded) { // If total retries are exhausted, schedule the call back for next interval mentioned in Settings.xml. if (this.IncrementRetryCount() == false) { if (this._windowsUpdateManager.ResetStateMachine()) { this.UpdateSettingsAndCreateCheckpoint(); this.CreateNewCheckpointFile(); } else { if (this._helper.WaitOnTask(Task.Delay(TimeSpan.FromMinutes(WaitTimeInMinutes)), this._cancellationToken)) { this.ScheduleTimer(); } return; } } } else { // Do not update the lastAttemptedTime. this.UpdateSettingsAndCreateCheckpoint(false); } // read checkpoint file after modifications. fileData = this.ReadCheckpointFile(); // Execute call back if (this.ScheduleWindowsUpdatesFlag(fileData)) { bool retryNeeded = this.ScheduleWindowsUpdates(); if (retryNeeded) { fileData.rescheduleNeeded = true; this.WriteCheckpointFile(fileData); } else { this.CreateNewCheckpointFile(); } this.ScheduleTimer(); return; } } catch (Exception e) { _eventSource.ErrorMessage("ScheduleTimer ended with exception : {0}", e); } TimeSpan operationTimeSpan = TimeSpan.FromMinutes(WaitTimeInMinutes); if (this._helper.WaitOnTask(Task.Delay(operationTimeSpan), this._cancellationToken)) { this.ScheduleTimer(); } }
public Task <NodeAgentSfUtilityExitCodes> UpdateInstallationStatusAsync(string nodeName, Uri applicationName, NodeAgentSfUtilityExitCodes updateState, WindowsUpdateOperationResult operationResult, TimeSpan timeout, CancellationToken cancellationToken) { throw new NotImplementedException(); }