コード例 #1
0
        //note: this doesn't implement SaveExitDataAs( action );
        private ExecuteResult SpawnExternal(ActionItem a, Dictionary <string, string> dynamicData, object parentExitData, bool dryRun)
        {
            ExecuteResult result = new ExecuteResult();
            List <string> args   = new List <string>();

            Plan container = new Plan();

            a.InstanceId   = ActionInstanceIdCounter++;
            container.Name = $"{Name}:{a.Name}";
            container.Actions.Add(a.Clone());
            container.StartInfo = StartInfo;

            string planYaml = CryptoHelpers.Encode(container.ToYaml());

            args.Add($"/plan:{planYaml}");
            args.Add($"/dryRun:{dryRun}");
            args.Add($"/taskModel:single");
            foreach (string key in dynamicData.Keys)
            {
                args.Add($"/{key}:{dynamicData[key]}");
            }
            args.Add($"/data:{parentExitData}");
            string arguments = string.Join(" ", args);

            Process p = new Process();

            p.StartInfo.Arguments              = arguments;
            p.StartInfo.FileName               = "synapse.cli.exe";
            p.StartInfo.RedirectStandardInput  = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError  = true;
            p.StartInfo.UseShellExecute        = false;
            p.StartInfo.CreateNoWindow         = true;
            p.StartInfo.WindowStyle            = ProcessWindowStyle.Hidden;
            p.EnableRaisingEvents              = true;
            //if( a.HasRunAs )
            //{
            //    p.StartInfo.Domain = a.RunAs.Domain;
            //    p.StartInfo.UserName = a.RunAs.UserName;
            //    SecureString pw = new SecureString();
            //    foreach( char c in a.RunAs.Password )
            //        pw.AppendChar( c );
            //    p.StartInfo.Password = pw;
            //}

            p.OutputDataReceived += p_OutputDataReceived;

            p.Start();

            result.PId = p.Id;
#if sqlite
            a.UpdateInstanceStatus(StatusType.None, "SpawnExternal", 0, p.Id);
#endif
            #region read this
            // best practice information on accessing stdout/stderr from mdsn article:
            //  https://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput%28v=vs.110%29.aspx
            // Do not wait for the child process to exit before reading to the end of its redirected stream.
            // Do not perform a synchronous read to the end of both redirected streams.
            // string output = p.StandardOutput.ReadToEnd();
            // string error = p.StandardError.ReadToEnd();
            // p.WaitForExit();
            // Use asynchronous read operations on at least one of the streams.
            #endregion
            p.BeginOutputReadLine();
            p.BeginErrorReadLine();


            p.WaitForExit();

            result.BranchStatus = result.Status = (StatusType)p.ExitCode;
            return(result);
        }
コード例 #2
0
        void ProcessRecursive(IActionContainer parentContext, SecurityContext parentSecurityContext,
                              ActionItem actionGroup, List <ActionItem> actions, ExecuteResult parentResult,
                              Dictionary <string, string> dynamicData, bool dryRun,
                              Func <SecurityContext, ActionItem, Dictionary <string, string>, object, bool, ExecuteResult> executeHandlerMethod)
        {
            if (WantsStopOrPause())
            {
                return;
            }


            parentContext.EnsureInitialized();

            //queryStatus provides the inbound value to ExecuteCase evaluation; it's the ExecuteCase comparison value.
            //queryStatus is carried downward through successive subtree executions.
            StatusType queryStatus = parentResult.Status;

            #region actionGroup
            if (actionGroup != null &&
                (((actionGroup.ExecuteCase & parentResult.Status) == actionGroup.ExecuteCase) || (actionGroup.ExecuteCase == StatusType.Any)))
            {
                actionGroup.EnsureInitialized();

                #region actionGroup-forEach
                if ((actionGroup.HasParameters && actionGroup.Parameters.HasForEach) ||
                    (actionGroup.Handler.HasConfig && actionGroup.Handler.Config.HasForEach))
                {
                    List <ActionItem> resolvedParmsActionGroup = new List <ActionItem>();
                    ResolveConfigAndParameters(actionGroup, dynamicData, ref resolvedParmsActionGroup, parentResult.ExitData);

                    foreach (ActionItem ai in resolvedParmsActionGroup)
                    {
                        ai.Parameters.ForEach = null;
                    }

                    actionGroup.InstanceId = ActionInstanceIdCounter++;
                    ActionItem agclone = actionGroup.Clone();
                    agclone.Result            = new ExecuteResult();
                    parentContext.ActionGroup = agclone;

                    Parallel.ForEach(resolvedParmsActionGroup, a =>    // foreach( ActionItem a in resolvedParmsActionGroup )
                    {
#if sqlite
                        a.CreateInstance(parentContext, InstanceId);
#endif
                        a.InstanceId     = ActionInstanceIdCounter++;
                        ActionItem clone = a.Clone();
                        agclone.Actions.Add(clone);

                        ExecuteResult r = executeHandlerMethod(parentSecurityContext, a, dynamicData, parentResult.ExitData, dryRun);
                        parentContext.ActionGroup.Result.SetBranchStatusChecked(r);
                        parentContext.Result.SetBranchStatusChecked(r);
                        clone.Handler.Type      = actionGroup.Handler.Type;
                        clone.Handler.StartInfo = actionGroup.Handler.StartInfo;
                        clone.Result            = r;

                        if (r.Status > queryStatus)
                        {
                            queryStatus = r.Status;
                        }

                        if (a.HasActions)
                        {
                            ProcessRecursive(clone, a.RunAs, a.ActionGroup, a.Actions, r, dynamicData, dryRun, executeHandlerMethod);
                            parentContext.ActionGroup.Result.SetBranchStatusChecked(clone.Result);
                            parentContext.Result.SetBranchStatusChecked(clone.Result);

                            if (clone.Result.Status > queryStatus)
                            {
                                queryStatus = clone.Result.Status;
                            }
                        }
                    });
                }
                #endregion
                #region actionGroup-single
                else
                {
#if sqlite
                    actionGroup.CreateInstance(parentContext, InstanceId);
#endif
                    ResolveConfigAndParameters(actionGroup, dynamicData, parentResult.ExitData);

                    actionGroup.InstanceId = ActionInstanceIdCounter++;
                    ActionItem clone = actionGroup.Clone();
                    parentContext.ActionGroup = clone;

                    ExecuteResult r = executeHandlerMethod(parentSecurityContext, actionGroup, dynamicData, parentResult.ExitData, dryRun);
                    parentContext.Result.SetBranchStatusChecked(r);
                    clone.Handler.Type      = actionGroup.Handler.Type;
                    clone.Handler.StartInfo = actionGroup.Handler.StartInfo;
                    clone.Result            = r;

                    if (r.Status > queryStatus)
                    {
                        queryStatus = r.Status;
                    }

                    if (actionGroup.HasActions)
                    {
                        ProcessRecursive(clone, actionGroup.RunAs, null, actionGroup.Actions, r, dynamicData, dryRun, executeHandlerMethod);
                        parentContext.Result.SetBranchStatusChecked(clone.Result);

                        if (clone.Result.Status > queryStatus)
                        {
                            queryStatus = clone.Result.Status;
                        }
                    }
                }
                #endregion
            }
            #endregion


            #region actions
            IEnumerable <ActionItem> actionList =
                actions.Where(a => (((a.ExecuteCase & queryStatus) == a.ExecuteCase) || (a.ExecuteCase == StatusType.Any)));

            List <ActionItem> resolvedParmsActions = new List <ActionItem>();
            Parallel.ForEach(actionList, a =>    // foreach( ActionItem a in actionList )
                             ResolveConfigAndParameters(a, dynamicData, ref resolvedParmsActions, parentResult.ExitData)
                             );

            Parallel.ForEach(resolvedParmsActions, a =>    // foreach( ActionItem a in resolvedParmsActions )
            {
#if sqlite
                a.CreateInstance(parentContext, InstanceId);
#endif
                a.InstanceId     = ActionInstanceIdCounter++;
                ActionItem clone = a.Clone();
                parentContext.Actions.Add(clone);

                ExecuteResult r = a.Result;
                if (r?.Status != StatusType.Failed)
                {
                    r = executeHandlerMethod(parentSecurityContext, a, dynamicData, parentResult.ExitData, dryRun);
                }

                parentContext.Result.SetBranchStatusChecked(r);
                clone.Handler.Type      = a.Handler.Type;
                clone.Handler.StartInfo = a.Handler.StartInfo;
                clone.Result            = r;

                if (a.HasActions)
                {
                    ProcessRecursive(clone, a.RunAs, a.ActionGroup, a.Actions, r, dynamicData, dryRun, executeHandlerMethod);
                    parentContext.Result.SetBranchStatusChecked(clone.Result);
                }
            });
            #endregion
        }