private async STT.Task <Data.TaskStatus> ProcessTaskAsync(TaskEntity taskToExecute, List <ResultEntity> resultEntityList, SteamfitterContext steamfitterContext, CancellationToken ct)
        {
            var overallStatus = Data.TaskStatus.succeeded;
            var tasks         = new List <STT.Task <string> >();
            var xref          = new Dictionary <int, ResultEntity>();

            foreach (var resultEntity in resultEntityList)
            {
                resultEntity.InputString = resultEntity.InputString.Replace("{moid}", resultEntity.VmId.ToString());
                resultEntity.InputString = resultEntity.InputString.Replace("{VmName}", resultEntity.VmName);
                if (resultEntity.VmId != null && resultEntity.VmName == "")
                {
                    resultEntity.VmName = _stackStormService.GetVmName((Guid)resultEntity.VmId);
                }
                resultEntity.Status     = TaskStatus.pending;
                resultEntity.StatusDate = DateTime.UtcNow;
                // if no expiration is set, us the maximum allowed by the TaskProcessMaxWaitSeconds setting
                resultEntity.ExpirationSeconds = resultEntity.ExpirationSeconds <= 0 ? _vmTaskProcessingOptions.CurrentValue.TaskProcessMaxWaitSeconds : resultEntity.ExpirationSeconds;
                var task = await RunTask(taskToExecute, resultEntity, ct);

                tasks.Add(task);
                xref[task.Id] = resultEntity;
                await steamfitterContext.SaveChangesAsync();

                _engineHub.Clients.Group(EngineGroups.SystemGroup).SendAsync(EngineMethods.ResultUpdated, _mapper.Map <ViewModels.Result>(resultEntity));
            }
            foreach (var bucket in AsCompletedBuckets(tasks))
            {
                try
                {
                    var task         = await bucket;
                    var resultEntity = xref[task.Id];
                    resultEntity.ActualOutput = task.Result == null ? "" : task.Result.ToString();
                    resultEntity.Status       = ProcessResult(resultEntity, ct);
                    resultEntity.StatusDate   = DateTime.UtcNow;
                    if (resultEntity.Status != Data.TaskStatus.succeeded)
                    {
                        if (overallStatus != Data.TaskStatus.failed)
                        {
                            overallStatus = resultEntity.Status;
                        }
                    }
                    await steamfitterContext.SaveChangesAsync();

                    _engineHub.Clients.Group(EngineGroups.SystemGroup).SendAsync(EngineMethods.ResultUpdated, _mapper.Map <ViewModels.Result>(resultEntity));
                }
                catch (OperationCanceledException)
                {
                    _logger.LogInformation("the executing task was cancelled");
                }
                catch (Exception ex)
                {
                    _logger.LogInformation(ex, "the executing task caused an exception");
                }
            }
            return(overallStatus);
        }
Esempio n. 2
0
        private async Task <Data.TaskStatus> ExecuteStackstormTaskAsync(DispatchTaskEntity dispatchTaskToExecute, List <DispatchTaskResultEntity> resultEntityList, CancellationToken ct)
        {
            var overallStatus = Data.TaskStatus.succeeded;

            foreach (var resultEntity in resultEntityList)
            {
                Task <string> task = null;
                resultEntity.InputString = resultEntity.InputString.Replace("VmGuid", "Moid").Replace("{moid}", resultEntity.VmId.ToString());
                resultEntity.VmName      = _stackStormService.GetVmName((Guid)resultEntity.VmId);
                switch (dispatchTaskToExecute.Action)
                {
                case TaskAction.guest_file_read:
                {
                    task = Task.Run(() => _stackStormService.GuestReadFile(resultEntity.InputString));
                    break;
                }

                case TaskAction.guest_process_run:
                {
                    task = Task.Run(() => _stackStormService.GuestCommand(resultEntity.InputString));
                    break;
                }

                case TaskAction.vm_hw_power_on:
                {
                    task = Task.Run(() => _stackStormService.VmPowerOn(resultEntity.InputString));
                    break;
                }

                case TaskAction.vm_hw_power_off:
                {
                    task = Task.Run(() => _stackStormService.VmPowerOff(resultEntity.InputString));
                    break;
                }

                case TaskAction.vm_create_from_template:
                {
                    task = Task.Run(() => _stackStormService.CreateVmFromTemplate(resultEntity.InputString));
                    break;
                }

                case TaskAction.vm_hw_remove:
                {
                    task = Task.Run(() => _stackStormService.VmRemove(resultEntity.InputString));
                    break;
                }

                default:
                {
                    var message = $"Task Action {dispatchTaskToExecute.Action} has not been implemented.";
                    _logger.LogError(message);
                    resultEntity.Status     = Data.TaskStatus.failed;
                    resultEntity.StatusDate = DateTime.UtcNow;
                    break;
                }
                }

                if (task.Wait(TimeSpan.FromSeconds(resultEntity.ExpirationSeconds)))
                {
                    resultEntity.ActualOutput = task.Result.ToString();
                    resultEntity.Status       = ProcessDispatchTaskResult(resultEntity, ct);
                }
                else
                {
                    resultEntity.ActualOutput = task.Result.ToString();
                    resultEntity.Status       = Data.TaskStatus.expired;
                }
                resultEntity.StatusDate = DateTime.UtcNow;
                if (resultEntity.Status != Data.TaskStatus.succeeded)
                {
                    if (overallStatus != Data.TaskStatus.failed)
                    {
                        overallStatus = resultEntity.Status;
                    }
                }
            }
            await _context.SaveChangesAsync();

            return(overallStatus);
        }