elasticsearch-manager 0.1.1 → 0.1.2.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- N2FlYzM2ZDk2Njg4M2I5NTJkOGQ4M2ZjMGM3ZjA2MjFiMjk3MmY3ZQ==
5
- data.tar.gz: !binary |-
6
- OGVjMGNiNjUxZjhjZGNmNThmYWZlZDZiOWVkMzYyY2M1MzI3YWZiOQ==
2
+ SHA1:
3
+ metadata.gz: 4e33a67d294a013df625637e54a74b3768103eff
4
+ data.tar.gz: bacfd5645a75323de255fcdb4e7eed862d611ef5
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- Yzk1YTMwYjBmYmRkZTVmYjU0ZmYwNjg1NzhhMTRiNDk3NjczMDdjMjVkNDNm
10
- Mjk2NGYyOTM5YmNjOGZjMmNhNTkwNmQ0M2NlMzBhMjRjMzk0MGUxODUwZmVj
11
- NDViNjU2N2ZjNDZlNGRlNzFmYTgzODNhYWUzNjY1MDE4MTg2MWI=
12
- data.tar.gz: !binary |-
13
- Y2Y1YTg4Mjg0NjhjN2ZhZjZiYzZiMmU2Zjk3MjhiNmNhM2VkZWIwOWE3NmUw
14
- ODhiNDA0ZjI2NWEyZDhkNGFmZTAzODJiYTY0YzZjZWE2NzJlNjE3MGVkZjVj
15
- Mjg0ZmRhODI5ZmU1NjU4N2NhMzFjZmVlNDk3MjNjYzA2YzYwNTA=
6
+ metadata.gz: f481ee93f5117ad7ca76d2986061bb93fb8a8c4767246e2b80814d806a7a44b519d52103cafa6fbc5957c07ca8289832a8a44d1b27809b60a6f71c75b9366702
7
+ data.tar.gz: 7cdca00339dd4c242afbbb4c1ec78d9782c86649a0dcdee31630d70deda76be98b9ad791cbd355f84cef71f25d90c7bd364007d8ea7d8abb3f4eb2bef0e155cc
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- elasticsearch-manager (0.1.1)
4
+ elasticsearch-manager (0.1.2)
5
5
  colorize (~> 0.7)
6
6
  highline (~> 1.7)
7
7
  json (~> 1.8)
@@ -19,8 +19,12 @@ opt_parser = OptionParser.new do |opts|
19
19
  elasticsearch-manager [options] <command>
20
20
 
21
21
  Available commands:
22
- rolling-restart -- Restart elasticsearch across the entire cluster, one node at a time.
22
+ rolling-restart -- Restart elasticsearch across the entire cluster, one node at a time
23
+ list-nodes -- List IPs of nodes in the cluster
24
+ shard-state -- Print current shard states
23
25
  status -- Check the current state of the cluster (green/yellow/red)
26
+ diable-routing -- Disable shard routing allocation
27
+ enable-routing -- Enable shard routing allocation
24
28
 
25
29
  EOC
26
30
 
@@ -51,8 +55,16 @@ cmd = ARGV[0]
51
55
  case cmd
52
56
  when 'rolling-restart'
53
57
  ec = CMD.rolling_restart(options)
58
+ when 'list-nodes'
59
+ ec = CMD.list_nodes(options)
60
+ when 'shard-state'
61
+ ec = CMD.shard_states(options)
54
62
  when 'status'
55
63
  ec = CMD.status(options)
64
+ when 'disable-routing'
65
+ ec = CMD.disable_routing(options)
66
+ when 'enable-routing'
67
+ ec = CMD.enable_routing(options)
56
68
  else
57
69
  puts "Unknown command: #{cmd}\n"
58
70
  puts opt_parser
@@ -29,6 +29,16 @@ module Elasticsearch
29
29
  get('/_cluster/settings')
30
30
  end
31
31
 
32
+ def node_concurrent_recoveries(num_recoveries = 2)
33
+ data = {
34
+ 'transient' => {
35
+ 'cluster.routing.allocation.node_concurrent_recoveries' => num_recoveries
36
+ }
37
+ }.to_json
38
+
39
+ put('/_cluster/settings', data)
40
+ end
41
+
32
42
  def routing(disable = true)
33
43
  data = {
34
44
  'transient' => {
@@ -1,8 +1,7 @@
1
1
  require 'colorize'
2
2
  require 'net/ssh'
3
3
 
4
- require 'elasticsearch/manager/manager'
5
- require 'elasticsearch/manager/rollingrestart'
4
+ require 'elasticsearch/manager'
6
5
 
7
6
 
8
7
  module Elasticsearch
@@ -17,8 +16,9 @@ module Elasticsearch
17
16
  print_cluster_status(manager, 'The cluster is currently unstable! Not proceeding with rolling-restart')
18
17
  return 2
19
18
  end
20
- puts "Discovering cluster members...\n"
19
+ print "Discovering cluster members..." if opts[:verbose]
21
20
  manager.cluster_members!
21
+ print "\rDiscovering cluster members... Done!\n" if opts[:verbose]
22
22
  timeout = opts[:timeout] || 600
23
23
  sleep_interval = opts[:sleep_interval] || 30
24
24
  begin
@@ -31,6 +31,51 @@ module Elasticsearch
31
31
  return 0
32
32
  end
33
33
 
34
+ def self.list_nodes(opts)
35
+ manager = _manager(opts)
36
+ print "Discovering cluster members..." if opts[:verbose]
37
+ manager.cluster_members!
38
+ print "\rDiscovering cluster members... Done!\n" if opts[:verbose]
39
+ manager.list_node_ips
40
+ return 0
41
+ end
42
+
43
+ def self.disable_routing(opts)
44
+ manager = _manager(opts)
45
+ print "Disabling shard routing allocation..."
46
+ msg = if manager.disable_routing
47
+ "disabled!".colorize(:green)
48
+ else
49
+ "error, unable to disable shard routing allocation!".colorize(:red)
50
+ end
51
+ print "\rDisabling shard routing allocation... #{msg}\n"
52
+ return 0
53
+ end
54
+
55
+ def self.enable_routing(opts)
56
+ manager = _manager(opts)
57
+ print "Enabling shard routing allocation..."
58
+ msg = if manager.enable_routing
59
+ "enabled!".colorize(:green)
60
+ else
61
+ "error, unable to enable shard routing allocation!".colorize(:red)
62
+ end
63
+ print "\rEnabling shard routing allocation... #{msg}\n"
64
+ return 0
65
+ end
66
+
67
+ def self.shard_states(opts)
68
+ manager = _manager(opts)
69
+ print "Discovering cluster members..." if opts[:verbose]
70
+ manager.cluster_members!
71
+ print "\rDiscovering cluster members... Done!\n" if opts[:verbose]
72
+ puts "UNASSIGNED: #{manager.state.count_unassigned_shards}"
73
+ manager.nodes.each do |node|
74
+ puts "#{node.ip}:\tSTARTED: #{node.count_started_shards}\t|\tINITIALIZING: #{node.count_initializing_shards}\t|\tRELOCATING: #{node.count_relocating_shards}"
75
+ end
76
+ return 0
77
+ end
78
+
34
79
  def self.status(opts)
35
80
  manager = _manager(opts)
36
81
  status = manager.cluster_status
@@ -6,10 +6,11 @@ module Elasticsearch
6
6
  class ESManager
7
7
  include Elasticsearch::Model
8
8
 
9
- attr_accessor :leader, :members, :nodes
9
+ attr_accessor :leader, :members, :nodes, :state
10
10
 
11
11
  def initialize(cluster_host = 'localhost', port = 9200)
12
12
  @client = Elasticsearch::Client::ESClient.new(cluster_host, port)
13
+ @state = nil
13
14
  @leader = nil
14
15
  @nodes = nil
15
16
  @members = nil
@@ -30,8 +31,9 @@ module Elasticsearch
30
31
  end
31
32
 
32
33
  def cluster_members!
33
- state = cluster_state
34
+ @state = cluster_state
34
35
  @nodes = state.nodes
36
+ @nodes.sort! { |a,b| a.id <=> b.id }
35
37
  @leader = @nodes.select { |n| n.master }[0].ip
36
38
  @members = @nodes.map { |n| n.ip }
37
39
  end
@@ -55,6 +57,12 @@ module Elasticsearch
55
57
  ret = @client.routing(false)
56
58
  ret['transient']['cluster']['routing']['allocation']['enable'] == 'all'
57
59
  end
60
+
61
+ def set_concurrent_recoveries(num_recoveries)
62
+ ret = @client.node_concurrent_recoveries(num_recoveries)
63
+ # Elasticache seems to return integer settings as strings when setting them...
64
+ ret['transient']['cluster']['routing']['allocation']['node_concurrent_recoveries'] == num_recoveries.to_s
65
+ end
58
66
  end
59
67
  end
60
68
  end
@@ -0,0 +1,15 @@
1
+ module Elasticsearch
2
+ module Manager
3
+
4
+ class ESManager
5
+ def list_node_ips
6
+ puts "#{@leader} -- master"
7
+ @members.each do |m|
8
+ unless m == @leader
9
+ puts m
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -29,8 +29,10 @@ module Elasticsearch
29
29
 
30
30
  def restart_node(node_ip, timeout, sleep_interval)
31
31
  puts "\nRestarting Elasticsearch on node: #{node_ip}"
32
+ # Pull the current node's state
33
+ n = @state.nodes.select { |n| n.ip == node_ip }[0]
34
+
32
35
  raise "Could not disable shard routing prior to restarting node: #{node_ip}".colorize(:red) unless disable_routing
33
-
34
36
  Net::SSH.start(node_ip, ENV['USER']) do |ssh|
35
37
  ssh.exec 'sudo service elasticsearch restart'
36
38
  end
@@ -43,6 +45,10 @@ module Elasticsearch
43
45
  raise NodeAvailableTimeout, "Node did not become available after waiting #{timeout} seconds...".colorize(:red)
44
46
  end
45
47
 
48
+ # Make sure the cluster is willing to concurrently recover as many
49
+ # shards per node as this node happens to have.
50
+ raise "Could not update node_concurrent_recoveries prior to restarting node: #{node_ip}".colorize(:red) unless set_concurrent_recoveries(n.count_started_shards + 1)
51
+
46
52
  raise "Could not re-enable shard routing following restart of node: #{node_ip}".colorize(:red) unless enable_routing
47
53
 
48
54
  begin
@@ -1,5 +1,5 @@
1
1
  module Elasticsearch
2
2
  module Manager
3
- VERSION = "0.1.1"
3
+ VERSION = "0.1.2.pre"
4
4
  end
5
5
  end
@@ -1,4 +1,5 @@
1
1
  require_relative 'manager/manager'
2
+ require_relative 'manager/nodes'
2
3
  require_relative 'manager/rollingrestart'
3
4
  require_relative 'manager/version'
4
5
 
@@ -34,6 +34,19 @@ module Elasticsearch
34
34
  end
35
35
  end
36
36
  end
37
+
38
+ def count_initializing_shards
39
+ shards.select { |s| s.state.upcase == 'INITIALIZING' }.length
40
+ end
41
+
42
+ def count_relocating_shards
43
+ shards.select { |s| s.state.upcase == 'RELOCATING' }.length
44
+ end
45
+
46
+ def count_started_shards
47
+ shards.select { |s| s.state.upcase == 'STARTED' }.length
48
+ end
49
+
37
50
  extend Representer
38
51
  end
39
52
  end
@@ -13,11 +13,11 @@ module Elasticsearch
13
13
  property :master_node
14
14
  nested :routing_nodes do
15
15
  property :unassigned, setter: (lambda do |v,args|
16
- self.unassigned = v.map {|s| Elasticsearch::Manager::Model::Shard.new.extend(Elastiman::Model::Shard::Representer).from_hash(s) }
16
+ self.unassigned = v.map {|s| Elasticsearch::Model::Shard.new.extend(Elastiman::Model::Shard::Representer).from_hash(s) }
17
17
  end)
18
18
  property :nodes, setter: (lambda do |v,args|
19
19
  self.nodes = v.map do |id, shards|
20
- shards.each { |shard| Elasticsearch::Manager::Model::Shard.new.extend(Elastiman::Model::Shard::Representer).from_hash(shard) }
20
+ shards.each { |shard| Elasticsearch::Model::Shard.new.extend(Elastiman::Model::Shard::Representer).from_hash(shard) }
21
21
  end.flatten
22
22
  end)
23
23
  end
@@ -2,22 +2,45 @@ require 'ostruct'
2
2
  require 'representable/json'
3
3
 
4
4
  module Elasticsearch
5
- class ClusterState < OpenStruct
6
- module Representer
7
- include Representable::JSON
8
- include Representable::Hash
9
- include Representable::Hash::AllowSymbols
10
-
11
- property :cluster_name
12
- property :master_node
13
- property :nodes, setter: (lambda do |v,args|
14
- self.nodes = v.map do |id,node|
15
- n = Elasticsearch::Model::Node.new.extend(Elasticsearch::Model::Node::Representer).from_hash(node)
16
- n.id, n.master, n.ip = id, id == self.master_node, n.transport_address[/\d+\.\d+\.\d+\.\d+/]
17
- n
18
- end
19
- end)
5
+ module Model
6
+ class ClusterState < OpenStruct
7
+ module Representer
8
+ include Representable::JSON
9
+ include Representable::Hash
10
+ include Representable::Hash::AllowSymbols
11
+
12
+ property :cluster_name
13
+ property :master_node
14
+ property :nodes, setter: (lambda do |v,args|
15
+ self.nodes = v.map do |id,node|
16
+ n = Elasticsearch::Model::Node.new.extend(Elasticsearch::Model::Node::Representer).from_hash(node)
17
+ n.id, n.master, n.ip = id, id == self.master_node, n.transport_address[/\d+\.\d+\.\d+\.\d+/]
18
+ n
19
+ end
20
+ end)
21
+ property :routing_nodes, setter: (lambda do |v,args|
22
+ v.each do |status,routes|
23
+ if status == 'nodes'
24
+ routes.each do |id,shards|
25
+ n = self.nodes.select { |n| n.id == id }[0]
26
+ s = shards.map do |shard|
27
+ Elasticsearch::Model::Shard.new.extend(Elasticsearch::Model::Shard::Representer).from_hash(shard)
28
+ end
29
+ n.shards = s
30
+ end
31
+ elsif status == 'unassigned'
32
+ self.unassigned_shards = routes.map do |shard|
33
+ Elasticsearch::Model::Shard.new.extend(Elasticsearch::Model::Shard::Representer).from_hash(shard)
34
+ end
35
+ end
36
+ end
37
+ end)
38
+ end
39
+
40
+ def count_unassigned_shards
41
+ unassigned_shards.length
42
+ end
43
+ extend Representer
20
44
  end
21
- extend Representer
22
45
  end
23
46
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elasticsearch-manager
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Oldfield
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-08 00:00:00.000000000 Z
11
+ date: 2015-05-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -203,6 +203,7 @@ files:
203
203
  - lib/elasticsearch/manager/cmd.rb
204
204
  - lib/elasticsearch/manager/errors.rb
205
205
  - lib/elasticsearch/manager/manager.rb
206
+ - lib/elasticsearch/manager/nodes.rb
206
207
  - lib/elasticsearch/manager/rollingrestart.rb
207
208
  - lib/elasticsearch/manager/version.rb
208
209
  - lib/elasticsearch/model.rb
@@ -235,14 +236,14 @@ require_paths:
235
236
  - lib
236
237
  required_ruby_version: !ruby/object:Gem::Requirement
237
238
  requirements:
238
- - - ! '>='
239
+ - - '>='
239
240
  - !ruby/object:Gem::Version
240
241
  version: '0'
241
242
  required_rubygems_version: !ruby/object:Gem::Requirement
242
243
  requirements:
243
- - - ! '>='
244
+ - - '>'
244
245
  - !ruby/object:Gem::Version
245
- version: '0'
246
+ version: 1.3.1
246
247
  requirements: []
247
248
  rubyforge_project:
248
249
  rubygems_version: 2.4.6