Implement wait command
This commit is contained in:
		
							parent
							
								
									ce72d5409c
								
							
						
					
					
						commit
						43ae69a06d
					
				|  | @ -24,13 +24,13 @@ defmodule ClearPermissionsCommand do | |||
|   def validate([], _) do | ||||
|     {:validation_failure, :not_enough_args} | ||||
|   end | ||||
|   def switches(), do: [] | ||||
| 
 | ||||
|   def validate([_|_] = args, _) when length(args) > 1 do | ||||
|     {:validation_failure, :too_many_args} | ||||
|   end | ||||
|   def validate([_], _), do: :ok | ||||
| 
 | ||||
|   def switches(), do: [] | ||||
| 
 | ||||
|   def run([username], %{node: node_name, vhost: vhost}) do | ||||
|     node_name | ||||
|     |> Helpers.parse_node | ||||
|  |  | |||
|  | @ -31,7 +31,7 @@ defmodule Parser do | |||
|   defp build_switches(default) do | ||||
|     Enum.reduce(Helpers.commands, | ||||
|                 default, | ||||
|                 fn({_, command}, {:error, _} = err) -> err; | ||||
|                 fn({_, _}, {:error, _} = err) -> err; | ||||
|                   ({_, command}, switches) -> | ||||
|                     command_switches = command.switches() | ||||
|                     case Enum.filter(command_switches, | ||||
|  |  | |||
|  | @ -130,6 +130,21 @@ defmodule RabbitMQCtl do | |||
|     result | ||||
|   end | ||||
| 
 | ||||
|   defp print_standard_messages({:error, :process_not_running} = result, _) do | ||||
|     IO.puts "Error: process is not running." | ||||
|     result | ||||
|   end | ||||
| 
 | ||||
|   defp print_standard_messages({:error, {:garbage_in_pid_file, _}} = result, _) do | ||||
|     IO.puts "Error: garbage in pid file." | ||||
|     result | ||||
|   end | ||||
| 
 | ||||
|   defp print_standard_messages({:error, {:could_not_read_pid, err}} = result, _) do | ||||
|     IO.puts "Error: could not read pid. Detail: #{err}" | ||||
|     result | ||||
|   end | ||||
| 
 | ||||
|   defp print_standard_messages({:healthcheck_failed, message} = result, _) do | ||||
|     IO.puts "Error: healthcheck failed. Message: #{message}" | ||||
|     result | ||||
|  |  | |||
|  | @ -0,0 +1,84 @@ | |||
| ## The contents of this file are subject to the Mozilla Public License | ||||
| ## Version 1.1 (the "License"); you may not use this file except in | ||||
| ## compliance with the License. You may obtain a copy of the License | ||||
| ## at http://www.mozilla.org/MPL/ | ||||
| ## | ||||
| ## Software distributed under the License is distributed on an "AS IS" | ||||
| ## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See | ||||
| ## the License for the specific language governing rights and | ||||
| ## limitations under the License. | ||||
| ## | ||||
| ## The Original Code is RabbitMQ. | ||||
| ## | ||||
| ## The Initial Developer of the Original Code is GoPivotal, Inc. | ||||
| ## Copyright (c) 2007-2016 Pivotal Software, Inc.  All rights reserved. | ||||
| 
 | ||||
| 
 | ||||
| defmodule WaitCommand do | ||||
|   @behaviour CommandBehaviour | ||||
|   @flags [] | ||||
| 
 | ||||
|   def merge_defaults(args, opts), do: {args, opts} | ||||
| 
 | ||||
|   def validate([_|_] = args, _) when length(args) > 1, do: {:validation_failure, :too_many_args}   | ||||
|   def validate([], _), do: {:validation_failure, :not_enough_args}   | ||||
|   def validate([_], _), do: :ok | ||||
| 
 | ||||
|   def switches(), do: [] | ||||
| 
 | ||||
|   def run([pid_file], %{node: node_name}) do | ||||
|     node_name | ||||
|     |> Helpers.parse_node | ||||
|     |> wait_for_application(pid_file, :rabbit_and_plugins); | ||||
|   end | ||||
| 
 | ||||
|   def usage, do: "wait <pid_file>" | ||||
| 
 | ||||
|   def flags, do: @flags | ||||
| 
 | ||||
|   def banner(_, %{node: node_name}), do: "Waiting for node #{node_name} ..." | ||||
| 
 | ||||
|   defp wait_for_application(node, pid_file, :rabbit_and_plugins) do | ||||
|       case read_pid_file(pid_file, true) do | ||||
|         {:error, _} = err -> err | ||||
|         pid -> | ||||
|           IO.puts "pid is #{pid}" | ||||
|           wait_for_startup(node, pid) | ||||
|       end | ||||
|   end | ||||
| 
 | ||||
|   defp wait_for_startup(node, pid) do  | ||||
|     while_process_is_alive( | ||||
|       node, pid, fn() -> :rpc.call(node, :rabbit, :await_startup, []) == :ok end) | ||||
|   end | ||||
| 
 | ||||
|   defp while_process_is_alive(node, pid, activity) do  | ||||
|     case :rabbit_misc.is_os_process_alive(pid) do | ||||
|       true  ->  | ||||
|         case activity.() do | ||||
|           true  -> :ok | ||||
|           false ->  | ||||
|             :timer.sleep(1000) | ||||
|             while_process_is_alive(node, pid, activity) | ||||
|         end | ||||
|       false -> {:error, :process_not_running} | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   defp read_pid_file(pid_file, wait) do | ||||
|     case {:file.read_file(pid_file), wait} do  | ||||
|       {{:ok, bin}, _} -> | ||||
|         case Integer.parse(bin) do | ||||
|           :error -> | ||||
|             {:error, {:garbage_in_pid_file, pid_file}} | ||||
|           {int, _} -> Integer.to_char_list int | ||||
|         end | ||||
|       {{:error, :enoent}, true} -> | ||||
|         :timer.sleep(1000) | ||||
|         read_pid_file(pid_file, wait) | ||||
|       {{:error, err}, _} ->  | ||||
|         {:error, {:could_not_read_pid, err}} | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
| end | ||||
|  | @ -0,0 +1,47 @@ | |||
| ## The contents of this file are subject to the Mozilla Public License | ||||
| ## Version 1.1 (the "License"); you may not use this file except in | ||||
| ## compliance with the License. You may obtain a copy of the License | ||||
| ## at http://www.mozilla.org/MPL/ | ||||
| ## | ||||
| ## Software distributed under the License is distributed on an "AS IS" | ||||
| ## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See | ||||
| ## the License for the specific language governing rights and | ||||
| ## limitations under the License. | ||||
| ## | ||||
| ## The Original Code is RabbitMQ. | ||||
| ## | ||||
| ## The Initial Developer of the Original Code is GoPivotal, Inc. | ||||
| ## Copyright (c) 2007-2016 Pivotal Software, Inc.  All rights reserved. | ||||
| 
 | ||||
| 
 | ||||
| defmodule WaitCommandTest do | ||||
|   use ExUnit.Case, async: false | ||||
|   import TestHelper | ||||
| 
 | ||||
|   @command WaitCommand | ||||
| 
 | ||||
|   setup_all do | ||||
|     :net_kernel.start([:rabbitmqctl, :shortnames]) | ||||
|     :net_kernel.connect_node(get_rabbit_hostname) | ||||
| 
 | ||||
|     on_exit([], fn -> | ||||
|       :erlang.disconnect_node(get_rabbit_hostname) | ||||
|       :net_kernel.stop() | ||||
|     end) | ||||
| 
 | ||||
|     :ok | ||||
|   end | ||||
| 
 | ||||
|   setup do | ||||
|     {:ok, opts: %{node: get_rabbit_hostname}} | ||||
|   end | ||||
| 
 | ||||
|   test "validate: with extra arguments returns an arg count error", context do | ||||
|     assert @command.validate(["pid_file", "extra"], context[:opts]) == {:validation_failure, :too_many_args} | ||||
|     assert @command.validate([], context[:opts]) == {:validation_failure, :not_enough_args} | ||||
|   end | ||||
| 
 | ||||
|   test "banner", context do | ||||
|     assert @command.banner([], context[:opts]) =~ ~r/Waiting for node #{get_rabbit_hostname}/ | ||||
|   end | ||||
| end | ||||
		Loading…
	
		Reference in New Issue