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(Constants.CHEF_NODE_PIPE_NAME, transport);

                        try
                        {
                            pipeClient.Connect(Constants.CHEF_NODE_CONNECT_TIMEOUT_MSECS);

                            SetNodeValueRequestBase request = CreateRequest();

                            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 CreateException(message);
                                }
                            }
                            if (ChefNodeCmdletExceptionBase.HasError(responseHash))
                            {
                                throw CreateException(responseHash);
                            }

                            // done.
                            break;
                        }
                        catch (TimeoutException e)
                        {
                            ThrowTerminatingError(new ErrorRecord(e, "Connection timed out", ErrorCategory.OperationTimeout, pipeClient));
                        }
                        catch (ChefNodeCmdletExceptionBase e)
                        {
                            ThrowTerminatingError(new ErrorRecord(e, "ChefNodeCmdlet exception", ErrorCategory.InvalidResult, pipeClient));
                        }
                        catch (Exception e)
                        {
                            ThrowTerminatingError(new ErrorRecord(e, "Unexpected exception", ErrorCategory.NotSpecified, pipeClient));
                        }
                        finally
                        {
                            pipeClient.Close();
                            pipeClient = null;
                        }
                    }
                }
Example #2
0
        static void Main(string[] args)
        {
            // resolve persistent node path.
            string nodeFilePath = null;

            if (2 == args.Length && args[0] == "-nf")
            {
                nodeFilePath = args[1];
            }
            else
            {
                Console.WriteLine("Usage: TestChefNodeCmdlet -nf <nodefile>");
                Console.WriteLine();
                Console.WriteLine("The nodefile is a JSON text file containing initial values and which receives any modified node values.");
                return;
            }

            // load initial node values, if any.
            string nodeFileText = ReadTextFile(nodeFilePath);

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

            if (nodeFileText.Length > 0)
            {
                nodeHash = (IDictionary)transport.NormalizeDeserializedObject(transport.ConvertStringToObject <object>(nodeFileText));
            }

            // current and new resource hashes.
            IDictionary currentResourceHash = new Hashtable();

            currentResourceHash.Add("name", "test name");

            IDictionary newResourceHash = new Hashtable(currentResourceHash);

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

            Console.WriteLine("Hit Ctrl+C to stop the server.");
            for (; ;)
            {
                try
                {
                    Console.WriteLine("Waiting for client to connect...");
                    pipeServer.WaitForConnection();
                    for (; ;)
                    {
                        // use duck typing to determine type of request.
                        IDictionary requestHash = (IDictionary)transport.NormalizeDeserializedObject(pipeServer.Receive <object>());

                        if (null == requestHash)
                        {
                            break;
                        }

                        bool validRequest = false;

                        if (requestHash.Contains(Constants.JSON_COMMAND_KEY))
                        {
                            if (requestHash.Contains(Constants.JSON_PATH_KEY) && requestHash.Contains(Constants.JSON_NODE_VALUE_KEY))
                            {
                                if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "SetChefNodeRequest")
                                {
                                    SetChefNodeRequest request = new SetChefNodeRequest((ICollection)requestHash[Constants.JSON_PATH_KEY],
                                                                                        requestHash[Constants.JSON_NODE_VALUE_KEY]);
                                    Console.WriteLine(String.Format("Received: {0}", request.ToString()));

                                    InsertNodeHash(nodeHash, request.Path, transport.NormalizeDeserializedObject(request.NodeValue));

                                    SetChefNodeResponse response = new SetChefNodeResponse(request.Path);
                                    Console.WriteLine(String.Format("Responding: {0}", response.ToString()));
                                    pipeServer.Send(response);

                                    // save change to node file.
                                    WriteTextFile(nodeFilePath, transport.ConvertObjectToString(nodeHash, true));
                                    validRequest = true;
                                }
                                else if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "SetCurrentResourceRequest")
                                {
                                    SetCurrentResourceRequest request = new SetCurrentResourceRequest((ICollection)requestHash[Constants.JSON_PATH_KEY],
                                                                                                      requestHash[Constants.JSON_NODE_VALUE_KEY]);
                                    Console.WriteLine(String.Format("Received: {0}", request.ToString()));

                                    InsertNodeHash(currentResourceHash, request.Path, transport.NormalizeDeserializedObject(request.NodeValue));

                                    SetCurrentResourceResponse response = new SetCurrentResourceResponse();
                                    Console.WriteLine(String.Format("Responding: {0}", response.ToString()));
                                    pipeServer.Send(response);
                                    validRequest = true;
                                }
                                else if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "SetNewResourceRequest")
                                {
                                    SetNewResourceRequest request = new SetNewResourceRequest((ICollection)requestHash[Constants.JSON_PATH_KEY],
                                                                                              requestHash[Constants.JSON_NODE_VALUE_KEY]);
                                    Console.WriteLine(String.Format("Received: {0}", request.ToString()));

                                    InsertNodeHash(newResourceHash, request.Path, transport.NormalizeDeserializedObject(request.NodeValue));

                                    SetNewResourceResponse response = new SetNewResourceResponse();
                                    Console.WriteLine(String.Format("Responding: {0}", response.ToString()));
                                    pipeServer.Send(response);
                                    validRequest = true;
                                }
                            }
                            else if (requestHash.Contains(Constants.JSON_PATH_KEY))
                            {
                                if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "GetChefNodeRequest")
                                {
                                    GetChefNodeRequest request = new GetChefNodeRequest((ICollection)requestHash[Constants.JSON_PATH_KEY]);
                                    Console.WriteLine(String.Format("Received: {0}", request.ToString()));

                                    object nodeValue             = QueryNodeHash(nodeHash, request.Path);
                                    GetChefNodeResponse response = new GetChefNodeResponse(request.Path, nodeValue);

                                    Console.WriteLine(String.Format("Responding: {0}", response.ToString()));
                                    pipeServer.Send(response);
                                    validRequest = true;
                                }
                                else if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "GetCurrentResourceRequest")
                                {
                                    GetCurrentResourceRequest request = new GetCurrentResourceRequest((ICollection)requestHash[Constants.JSON_PATH_KEY]);
                                    Console.WriteLine(String.Format("Received: {0}", request.ToString()));

                                    object nodeValue = QueryNodeHash(currentResourceHash, request.Path);
                                    GetCurrentResourceResponse response = new GetCurrentResourceResponse(request.Path, nodeValue);

                                    Console.WriteLine(String.Format("Responding: {0}", response.ToString()));
                                    pipeServer.Send(response);
                                    validRequest = true;
                                }
                                else if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "GetNewResourceRequest")
                                {
                                    GetNewResourceRequest request = new GetNewResourceRequest((ICollection)requestHash[Constants.JSON_PATH_KEY]);
                                    Console.WriteLine(String.Format("Received: {0}", request.ToString()));

                                    object nodeValue = QueryNodeHash(newResourceHash, request.Path);
                                    GetNewResourceResponse response = new GetNewResourceResponse(request.Path, nodeValue);

                                    Console.WriteLine(String.Format("Responding: {0}", response.ToString()));
                                    pipeServer.Send(response);
                                    validRequest = true;
                                }
                            }
                        }
                        if (false == validRequest)
                        {
                            // unknown request type; hang up and try again.
                            break;
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
                finally
                {
                    pipeServer.Close();
                }
            }
        }
Example #3
0
        static void Main(string[] args)
        {
            // resolve persistent node path.
            string nodeFilePath = null;

            if (2 == args.Length && args[0] == "-nf")
            {
                nodeFilePath = args[1];
            }
            else
            {
                Console.WriteLine("Usage: TestChefNodeCmdlet -nf <nodefile>");
                Console.WriteLine();
                Console.WriteLine("The nodefile is a JSON text file containing initial values and which receives any modified node values.");
                return;
            }

            // load initial node values, if any.
            string nodeFileText = ReadTextFile(nodeFilePath);

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

            if (nodeFileText.Length > 0)
            {
                nodeHash = (IDictionary)transport.NormalizeDeserializedObject(transport.ConvertStringToObject<object>(nodeFileText));
            }

            // current and new resource hashes.
            IDictionary currentResourceHash = new Hashtable();
            currentResourceHash.Add("name", "test name");

            IDictionary newResourceHash = new Hashtable(currentResourceHash);

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

            Console.WriteLine("Hit Ctrl+C to stop the server.");
            for (; ; )
            {
                try
                {
                    Console.WriteLine("Waiting for client to connect...");
                    pipeServer.WaitForConnection();
                    for (; ; )
                    {
                        // use duck typing to determine type of request.
                        IDictionary requestHash = (IDictionary)transport.NormalizeDeserializedObject(pipeServer.Receive<object>());

                        if (null == requestHash)
                        {
                            break;
                        }

                        bool validRequest = false;

                        if (requestHash.Contains(Constants.JSON_COMMAND_KEY))
                        {
                            if (requestHash.Contains(Constants.JSON_PATH_KEY) && requestHash.Contains(Constants.JSON_NODE_VALUE_KEY))
                            {
                                if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "SetChefNodeRequest")
                                {
                                    SetChefNodeRequest request = new SetChefNodeRequest((ICollection)requestHash[Constants.JSON_PATH_KEY],
                                                                                        requestHash[Constants.JSON_NODE_VALUE_KEY]);
                                    Console.WriteLine(String.Format("Received: {0}", request.ToString()));

                                    InsertNodeHash(nodeHash, request.Path, transport.NormalizeDeserializedObject(request.NodeValue));

                                    SetChefNodeResponse response = new SetChefNodeResponse(request.Path);
                                    Console.WriteLine(String.Format("Responding: {0}", response.ToString()));
                                    pipeServer.Send(response);

                                    // save change to node file.
                                    WriteTextFile(nodeFilePath, transport.ConvertObjectToString(nodeHash, true));
                                    validRequest = true;
                                }
                                else if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "SetCurrentResourceRequest")
                                {
                                    SetCurrentResourceRequest request = new SetCurrentResourceRequest((ICollection)requestHash[Constants.JSON_PATH_KEY],
                                                                                                      requestHash[Constants.JSON_NODE_VALUE_KEY]);
                                    Console.WriteLine(String.Format("Received: {0}", request.ToString()));

                                    InsertNodeHash(currentResourceHash, request.Path, transport.NormalizeDeserializedObject(request.NodeValue));

                                    SetCurrentResourceResponse response = new SetCurrentResourceResponse();
                                    Console.WriteLine(String.Format("Responding: {0}", response.ToString()));
                                    pipeServer.Send(response);
                                    validRequest = true;
                                }
                                else if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "SetNewResourceRequest")
                                {
                                    SetNewResourceRequest request = new SetNewResourceRequest((ICollection)requestHash[Constants.JSON_PATH_KEY],
                                                                                              requestHash[Constants.JSON_NODE_VALUE_KEY]);
                                    Console.WriteLine(String.Format("Received: {0}", request.ToString()));

                                    InsertNodeHash(newResourceHash, request.Path, transport.NormalizeDeserializedObject(request.NodeValue));

                                    SetNewResourceResponse response = new SetNewResourceResponse();
                                    Console.WriteLine(String.Format("Responding: {0}", response.ToString()));
                                    pipeServer.Send(response);
                                    validRequest = true;
                                }
                            }
                            else if (requestHash.Contains(Constants.JSON_PATH_KEY))
                            {
                                if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "GetChefNodeRequest")
                                {
                                    GetChefNodeRequest request = new GetChefNodeRequest((ICollection)requestHash[Constants.JSON_PATH_KEY]);
                                    Console.WriteLine(String.Format("Received: {0}", request.ToString()));

                                    object nodeValue = QueryNodeHash(nodeHash, request.Path);
                                    GetChefNodeResponse response = new GetChefNodeResponse(request.Path, nodeValue);

                                    Console.WriteLine(String.Format("Responding: {0}", response.ToString()));
                                    pipeServer.Send(response);
                                    validRequest = true;
                                }
                                else if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "GetCurrentResourceRequest")
                                {
                                    GetCurrentResourceRequest request = new GetCurrentResourceRequest((ICollection)requestHash[Constants.JSON_PATH_KEY]);
                                    Console.WriteLine(String.Format("Received: {0}", request.ToString()));

                                    object nodeValue = QueryNodeHash(currentResourceHash, request.Path);
                                    GetCurrentResourceResponse response = new GetCurrentResourceResponse(request.Path, nodeValue);

                                    Console.WriteLine(String.Format("Responding: {0}", response.ToString()));
                                    pipeServer.Send(response);
                                    validRequest = true;
                                }
                                else if (requestHash[Constants.JSON_COMMAND_KEY].ToString() == "GetNewResourceRequest")
                                {
                                    GetNewResourceRequest request = new GetNewResourceRequest((ICollection)requestHash[Constants.JSON_PATH_KEY]);
                                    Console.WriteLine(String.Format("Received: {0}", request.ToString()));

                                    object nodeValue = QueryNodeHash(newResourceHash, request.Path);
                                    GetNewResourceResponse response = new GetNewResourceResponse(request.Path, nodeValue);

                                    Console.WriteLine(String.Format("Responding: {0}", response.ToString()));
                                    pipeServer.Send(response);
                                    validRequest = true;
                                }
                            }
                        }
                        if (false == validRequest)
                        {
                            // unknown request type; hang up and try again.
                            break;
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
                finally
                {
                    pipeServer.Close();
                }
            }
        }
                // Summary:
                //  implements required cmdlet processing method.
                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(Constants.CHEF_NODE_PIPE_NAME, transport);

                        try
                        {
                            GetNodeValueRequestBase request = CreateRequest();

                            pipeClient.Connect(Constants.CHEF_NODE_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 CreateException(message);
                                }
                            }
                            if (ChefNodeCmdletExceptionBase.HasError(responseHash))
                            {
                                throw CreateException(responseHash);
                            }

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

                            if (null != nodeValue)
                            {
                                WriteObject(nodeValue, nodeValue is ICollection);
                            }

                            // done.
                            break;
                        }
                        catch (TimeoutException e)
                        {
                            ThrowTerminatingError(new ErrorRecord(e, "Connection timed out", ErrorCategory.OperationTimeout, pipeClient));
                        }
                        catch (ChefNodeCmdletExceptionBase e)
                        {
                            ThrowTerminatingError(new ErrorRecord(e, "ChefNodeCmdlet exception", ErrorCategory.InvalidResult, pipeClient));
                        }
                        catch (Exception e)
                        {
                            ThrowTerminatingError(new ErrorRecord(e, "Unexpected exception", ErrorCategory.NotSpecified, pipeClient));
                        }
                        finally
                        {
                            pipeClient.Close();
                            pipeClient = null;
                        }
                    }
                }
Example #5
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;
                }
            }
        }
                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;
                        }
                    }
                }
                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;
                        }
                    }
                }
Example #8
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;
                }
            }
        }