Ejemplo n.º 1
0
                protected override void ProcessRecord()
                {
                    // iterate attempting to connect, send and receive to Chef node server.
                    for (int tryIndex = 0; tryIndex < Constants.MAX_CLIENT_RETRIES; ++tryIndex)
                    {
                        ITransport transport = new JsonTransport();
                        PipeClient pipeClient = new PipeClient(PipeName, transport);

                        try
                        {
                            // FIX: query the current value of $LastExitCode from powershell host.
                            int lastExitCode = 0;
                            GetNextActionRequest request = new GetNextActionRequest(lastExitCode);

                            pipeClient.Connect(Constants.NEXT_ACTION_CONNECT_TIMEOUT_MSECS);

                            IDictionary responseHash = (IDictionary)transport.NormalizeDeserializedObject(pipeClient.SendReceive<object>(request));

                            if (null == responseHash)
                            {
                                if (tryIndex + 1 < Constants.MAX_CLIENT_RETRIES)
                                {
                                    // delay retry a few ticks to yield time in case server is busy.
                                    Thread.Sleep(Constants.SLEEP_BETWEEN_CLIENT_RETRIES_MSECS);
                                    continue;
                                }
                                else
                                {
                                    string message = String.Format("Failed to get expected response after {0} retries.", Constants.MAX_CLIENT_RETRIES);
                                    throw new GetNextActionException(message);
                                }
                            }
                            if (ChefNodeCmdletExceptionBase.HasError(responseHash))
                            {
                                throw new GetNextActionException(responseHash);
                            }

                            // can't write a null object to pipeline, so write nothing in the null case.
                            string nextAction = responseHash.Contains(Constants.JSON_NEXT_ACTION_KEY) ? responseHash[Constants.JSON_NEXT_ACTION_KEY].ToString() : null;

                            if (null == nextAction)
                            {
                                throw new GetNextActionException("Received null for next action; expecting an exit command when finished.");
                            }

                            // automagically convert next action into an invocable script block.
                            //
                            // example of use:
                            //
                            //  while ($TRUE)
                            //  {
                            //      $Error.clear()
                            //      $nextAction = $NULL
                            //      $nextAction = get-NextAction
                            //      if ($Error.Count -eq 0)
                            //      {
                            //          write-output $nextAction
                            //          Invoke-Command -scriptblock $nextAction
                            //          sleep 1
                            //      }
                            //      else
                            //      {
                            //          break
                            //      }
                            //  }
                            ScriptBlock scriptBlock = ScriptBlock.Create(nextAction);

                            WriteObject(scriptBlock);

                            // done.
                            break;
                        }
                        catch (TimeoutException e)
                        {
                            ThrowTerminatingError(new ErrorRecord(e, "Connection timed out", ErrorCategory.OperationTimeout, pipeClient));
                        }
                        catch (GetNextActionException e)
                        {
                            ThrowTerminatingError(new ErrorRecord(e, "get-NextAction exception", ErrorCategory.InvalidResult, pipeClient));
                        }
                        catch (Exception e)
                        {
                            ThrowTerminatingError(new ErrorRecord(e, "Unexpected exception", ErrorCategory.NotSpecified, pipeClient));
                        }
                        finally
                        {
                            pipeClient.Close();
                            pipeClient = null;
                        }
                    }
                }
Ejemplo n.º 2
0
                protected override void ProcessRecord()
                {
                    // iterate attempting to connect, send and receive to Chef node server.
                    for (int tryIndex = 0; tryIndex < Constants.MAX_CLIENT_RETRIES; ++tryIndex)
                    {
                        ITransport transport  = new JsonTransport();
                        PipeClient pipeClient = new PipeClient(PipeName, transport);

                        try
                        {
                            GetNextActionRequest request = new GetNextActionRequest(LastActionExitCode, LastActionErrorMessage);

                            pipeClient.Connect(Constants.NEXT_ACTION_CONNECT_TIMEOUT_MSECS);

                            IDictionary responseHash = (IDictionary)transport.NormalizeDeserializedObject(pipeClient.SendReceive <object>(request));

                            if (null == responseHash)
                            {
                                if (tryIndex + 1 < Constants.MAX_CLIENT_RETRIES)
                                {
                                    // delay retry a few ticks to yield time in case server is busy.
                                    Thread.Sleep(Constants.SLEEP_BETWEEN_CLIENT_RETRIES_MSECS);
                                    continue;
                                }
                                else
                                {
                                    string message = String.Format("Failed to get expected response after {0} retries.", Constants.MAX_CLIENT_RETRIES);
                                    throw new GetNextActionException(message);
                                }
                            }
                            if (ChefNodeCmdletExceptionBase.HasError(responseHash))
                            {
                                throw new GetNextActionException(responseHash);
                            }

                            // next action cannot be null.
                            string nextAction = responseHash.Contains(Constants.JSON_NEXT_ACTION_KEY) ? responseHash[Constants.JSON_NEXT_ACTION_KEY].ToString() : null;

                            if (null == nextAction)
                            {
                                throw new GetNextActionException("Received null for next action; expecting an exit command when finished.");
                            }

                            // enhance next action with try-catch logic to set the $global:RS_LastErrorRecord variable
                            // in case of an exception thrown by a script. the try-catch block loses details of script
                            // execution if caught by an outer block instead of the inner block which threw it.
                            nextAction = NEXT_ACTION_PREFIX + nextAction + NEXT_ACTION_POSTFIX;

                            // automagically convert next action into an invocable script block.
                            //
                            // example of use:
                            //
                            //  while ($TRUE)
                            //  {
                            //      $Error.clear()
                            //      $nextAction = $NULL
                            //      $nextAction = get-NextAction $pipeName
                            //      if ($Error.Count -eq 0)
                            //      {
                            //          write-output $nextAction
                            //          Invoke-Command -scriptblock $nextAction
                            //          sleep 1
                            //      }
                            //      else
                            //      {
                            //          break
                            //      }
                            //  }
                            ScriptBlock scriptBlock = ScriptBlock.Create(nextAction);

                            WriteObject(scriptBlock);

                            // done.
                            break;
                        }
                        catch (TimeoutException e)
                        {
                            ThrowTerminatingError(new ErrorRecord(e, "Connection timed out", ErrorCategory.OperationTimeout, pipeClient));
                        }
                        catch (GetNextActionException e)
                        {
                            ThrowTerminatingError(new ErrorRecord(e, "get-NextAction exception", ErrorCategory.InvalidResult, pipeClient));
                        }
                        catch (Exception e)
                        {
                            ThrowTerminatingError(new ErrorRecord(e, "Unexpected exception", ErrorCategory.NotSpecified, pipeClient));
                        }
                        finally
                        {
                            pipeClient.Close();
                            pipeClient = null;
                        }
                    }
                }
Ejemplo n.º 3
0
        static void Main(string[] args)
        {
            // resolve persistent node path.
            string pipeName       = null;
            string nextActionPath = null;

            if (4 == args.Length && args[0] == "-pn" && args[2] == "-na")
            {
                pipeName       = args[1];
                nextActionPath = args[3];
            }
            else
            {
                Console.WriteLine("Usage: -pn <pipe name> -na <next action file path>");
                Console.WriteLine();
                Console.WriteLine("The <pipe name> is any legal file name which uniquely distinguishes the pipe server.");
                Console.WriteLine("The <next action file path> is a text file containing a list of actions to execute in PowerShell.");
                return;
            }

            FileStream   fileStream   = null;
            StreamReader streamReader = null;

            try
            {
                // read next action file linewise.
                fileStream   = new FileStream(nextActionPath, FileMode.OpenOrCreate, FileAccess.Read);
                streamReader = new StreamReader(fileStream);

                // use JSON transport to unmarshal initial nodes.
                ITransport transport = new JsonTransport();

                // create pipe server using JSON as transport.
                PipeServer pipeServer = new PipeServer(pipeName, transport);

                Console.WriteLine("Hit Ctrl+C to stop the server.");

                bool moreCommands = true;

                while (moreCommands)
                {
                    try
                    {
                        Console.WriteLine("Waiting for client to connect...");
                        pipeServer.WaitForConnection();

                        GetNextActionRequest request = pipeServer.Receive <GetNextActionRequest>();

                        if (null == request)
                        {
                            break;
                        }
                        Console.WriteLine(String.Format("Received: {0}", request.ToString()));

                        for (;;)
                        {
                            string nextLine = streamReader.ReadLine();

                            if (null == nextLine)
                            {
                                moreCommands = false;
                                nextLine     = "exit";
                            }
                            if (nextLine.Trim().Length > 0)
                            {
                                GetNextActionResponse response = new GetNextActionResponse(nextLine);

                                Console.WriteLine(String.Format("Responding: {0}", response.ToString()));
                                pipeServer.Send(response);
                                break;
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                    finally
                    {
                        pipeServer.Close();
                    }
                }
            }
            catch (IOException e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                if (null != streamReader)
                {
                    streamReader.Close();
                    streamReader = null;
                }
                if (null != fileStream)
                {
                    fileStream.Close();
                    fileStream = null;
                }
            }
        }