Class: Chef::Expander::Control

Inherits:
Object
  • Object
show all
Defined in:
lib/chef/expander/control.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(argv) ⇒ Control

Returns a new instance of Control.



77
78
79
# File 'lib/chef/expander/control.rb', line 77

def initialize(argv)
  @argv = argv.dup
end

Class Method Details

.arg(*args) ⇒ Object



50
51
52
# File 'lib/chef/expander/control.rb', line 50

def self.arg(*args)
  #TODO
end

.compileObject

– TODO: this is confusing and unneeded. Just whitelist the methods that map to commands and use send



68
69
70
71
72
73
74
75
# File 'lib/chef/expander/control.rb', line 68

def self.compile
  run_method = "def run; case @argv.first;"
  descriptions.each do |method_name, command_name, desc|
    run_method << "when '#{command_name}';#{method_name};"
  end
  run_method << "else; help; end; end;"
  class_eval(run_method, __FILE__, __LINE__)
end

.desc(description) ⇒ Object



42
43
44
# File 'lib/chef/expander/control.rb', line 42

def self.desc(description)
  @desc = description
end

.descriptionsObject



54
55
56
# File 'lib/chef/expander/control.rb', line 54

def self.descriptions
  @descriptions ||= []
end

.method_added(method_name) ⇒ Object



58
59
60
61
62
63
# File 'lib/chef/expander/control.rb', line 58

def self.method_added(method_name)
  if @desc
    descriptions << [method_name, method_name.to_s.gsub('_', '-'), @desc]
    @desc = nil
  end
end

.option(*args) ⇒ Object



46
47
48
# File 'lib/chef/expander/control.rb', line 46

def self.option(*args)
  #TODO
end

.run(argv) ⇒ Object



37
38
39
40
# File 'lib/chef/expander/control.rb', line 37

def self.run(argv)
  remaining_args_after_opts = Expander.init_config(ARGV)
  new(remaining_args_after_opts).run
end

Instance Method Details

#helpObject



82
83
84
85
86
87
88
89
90
# File 'lib/chef/expander/control.rb', line 82

def help
  puts "Chef Expander #{Expander.version}"
  puts "Usage: chef-expanderctl COMMAND"
  puts
  puts "Commands:"
  self.class.descriptions.each do |method_name, command_name, desc|
    puts "  #{command_name}".ljust(15) + desc
  end
end

#log_levelObject



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/chef/expander/control.rb', line 174

def log_level
  @argv.shift
  level = @argv.first
  acceptable_levels = %w{debug info warn error fatal}
  unless acceptable_levels.include?(level)
    puts "Log level must be one of #{acceptable_levels.join(', ')}"
    exit 1
  end

  h = HighLine.new
  response_mutex = Mutex.new
  
  responses = [h.color("Host", :bold), h.color("PID", :bold), h.color("GUID", :bold), h.color("Log Level", :bold)]
  AMQP.start(Expander.config.amqp_config) do
    node = Expander::Node.local_node
    node.exclusive_control_queue.subscribe do |header, message|
      reply = Yajl::Parser.parse(message)
      n = reply['node']
      response_mutex.synchronize do
        responses << n["hostname_f"] << n["pid"].to_s << n["guid"] << reply["level"]
      end
    end
    node.broadcast_message(Yajl::Encoder.encode({:action => :set_log_level, :level => level, :rsvp => node.exclusive_control_queue_name}))
    EM.add_timer(2) { AMQP.stop; EM.stop }
  end
  puts h.list(responses, :columns_across, 4)
end

#node_statusObject



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/chef/expander/control.rb', line 143

def node_status
  status_mutex = Mutex.new
  h = ::HighLine.new
  node_status = [h.color("Host", :bold), h.color("PID", :bold), h.color("GUID", :bold), h.color("Vnodes", :bold)]

  print("Collecting status info from the cluster...")

  AMQP.start(Expander.config.amqp_config) do
    node = Expander::Node.local_node
    node.exclusive_control_queue.subscribe do |header, message|
      status = Yajl::Parser.parse(message)
      status_mutex.synchronize do
        node_status << status["hostname_f"]
        node_status << status["pid"].to_s
        node_status << status["guid"]
        # BIG ASSUMPTION HERE that nodes only have contiguous vnode ranges
        # will not be true once vnode recovery is implemented
        node_status << "#{status["vnodes"].min}-#{status["vnodes"].max}"
      end
    end
    node.broadcast_message(Yajl::Encoder.encode(:action => :status, :rsvp => node.exclusive_control_queue_name))
    EM.add_timer(2) { AMQP.stop;EM.stop }
  end

  puts "done"
  puts
  puts h.list(node_status, :columns_across, 4)
  puts
end

#queue_depthObject



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/chef/expander/control.rb', line 93

def queue_depth
  h = HighLine.new
  message_counts = []

  amqp_client = Bunny.new(Expander.config.amqp_config)
  amqp_client.start

  0.upto(VNODES - 1) do |vnode|
    q = amqp_client.queue("vnode-#{vnode}", :durable => true)
    message_counts << q.status[:message_count]
  end
  total_messages = message_counts.inject(0) { |sum, count| sum + count }
  max = message_counts.max
  min = message_counts.min

  avg = total_messages.to_f / message_counts.size.to_f

  puts "  total messages:       #{total_messages}"
  puts "  average queue depth:  #{avg}"
  puts "  max queue depth:      #{max}"
  puts "  min queue depth:      #{min}" 
ensure
  amqp_client.stop if defined?(amqp_client) && amqp_client
end

#queue_statusObject



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/chef/expander/control.rb', line 119

def queue_status
  h = HighLine.new
  queue_status = [h.color("VNode", :bold), h.color("Messages", :bold), h.color("Consumers", :bold)]

  total_messages = 0

  amqp_client = Bunny.new(Expander.config.amqp_config)
  amqp_client.start

  0.upto(VNODES - 1) do |vnode|
    q = amqp_client.queue("vnode-#{vnode}", :durable => true)
    status = q.status
    # returns {:message_count => method.message_count, :consumer_count => method.consumer_count}
    queue_status << vnode.to_s << status[:message_count].to_s << status[:consumer_count].to_s
    total_messages += status[:message_count]
  end
  puts "  total messages: #{total_messages}"
  puts
  puts h.list(queue_status, :columns_across, 3)
ensure
  amqp_client.stop if defined?(amqp_client) && amqp_client
end