Class: Riak::Node
- Inherits:
-
Object
- Object
- Riak::Node
- Includes:
- Util::Translation
- Defined in:
- lib/riak/node.rb,
lib/riak/node/log.rb,
lib/riak/node/console.rb,
lib/riak/node/control.rb,
lib/riak/node/version.rb,
lib/riak/node/defaults.rb,
lib/riak/node/generation.rb,
lib/riak/node/configuration.rb
Overview
A Node encapsulates the generation and management of standalone Riak nodes. It is used by the TestServer to start and manage an in-memory node for supporting integration test suites.
Direct Known Subclasses
Defined Under Namespace
Constant Summary
- LAGER_LEVELS =
[ :debug, :info, :notice, :warning, :error, :critical, :alert, :emergency ]
- STATS_REGEXP =
Regexp for parsing riak-admin status output. Takes into account the minor bug fixed by https://github.com/basho/riak_kv/pull/134 and multiline output used when lists of things grow long.
/^([^:\n]+)\s:\s((?:.*)(?:\n\s+[^\n]+)*)/- ENV_DEFAULTS =
Settings based on Riak master/1.0.
{ :riak_core => { :ring_creation_size => 64 }, :riak_kv => { :storage_backend => :riak_kv_bitcask_backend, :map_js_vm_count => 8, :reduce_js_vm_count => 6, :hook_js_vm_count => 2, :mapper_batch_size => 5, :js_max_vm_mem => 8, :js_thread_stack => 16, :riak_kv_stat => true, :legacy_stats => false, :vnode_vclocks => true, :http_url_encoding => :on, :legacy_keylisting => false, :mapred_system => :pipe, :add_paths => [] }, :riak_search => { :enabled => true }, :luwak => { :enabled => true }, :merge_index => { :buffer_rollover_size => 1048576, :max_compact_segments => 20 }, :eleveldb => {}, :bitcask => {}, :lager => { :crash_log_size => 65536, :error_logger_redirect => true }, :riak_sysmon => { :process_limit => 30, :port_limit => 30, :gc_ms_limit => 50, :heap_word_limit => 10485760 }, :sasl => { :sasl_error_logger => false } }.freeze
- VM_DEFAULTS =
Based on Riak master/1.0.
{ "+K" => true, "+A" => 64, "-smp" => "enable", "+W" => "w", "-env ERL_MAX_PORTS" => 4096, "-env ERL_FULLSWEEP_AFTER" => 0 }.freeze
- NODE_DIRECTORIES =
The directories (and accessor methods) that will be created under the generated node.
[:bin, :etc, :log, :data, :ring, :pipe]
Instance Attribute Summary (collapse)
-
- (Hash) configuration
readonly
The configuration that was passed to the Node when initialized.
-
- (Hash) env
readonly
The contents of the Erlang environment, which will be created into the app.config file.
-
- (Pathname) root
readonly
The root directory of the Node, where all files are placed after generation.
-
- (Pathname) source
readonly
The source of the Riak installation from where the Node will be generated.
-
- (Hash) vm
readonly
The command-line switches for the Erlang virtual machine, which will be created into the vm.args file.
Class Method Summary (collapse)
-
+ (Object) create(configuration = {})
Creates a new Riak node.
Instance Method Summary (collapse)
-
- (Pathname) admin_script
The script for controlling non-lifecycle features of Riak like joining, leaving, status, ringready, etc.
-
- (Riak::Node::Console) attach
Attach to the node's console via the pipe.
- - (Object) base_dir
- - (Object) configure_base_dir
- - (Object) configure_version
-
- (Pathname) control_script
The script for starting, stopping and pinging the Node.
-
- (String) control_script_name
The name of the 'riak' or 'riaksearch' control script.
-
- (String) cookie
The cookie/shared secret used for connecting a cluster.
-
- (Object) create
Generates the node.
-
- (Object) destroy
Removes the node from disk and freezes the object.
-
- (Object) drop
Clears data from known data directories.
-
- (Array<Pathname>) erlang_sources
Where user Erlang code will be loaded from.
-
- (Boolean) exist?
Does the node exist on disk?.
- - (Object) expand_log_level(level)
-
- (Fixnum) handoff_port
The port used for handing off data to other nodes.
-
- (String) http_ip
The interface to which the HTTP API is connected.
-
- (Fixnum) http_port
The port to which the HTTP API is connected.
-
- (Node) initialize(configuration = {})
constructor
Creates the template for a Riak node.
-
- (Pathname) javascript_source
Where user Javascript code will be loaded from.
-
- (String) join(node)
Joins the node to another node to create a cluster.
-
- (Object) js_reload
Forces the node to restart/reload its JavaScript VMs, effectively reloading any user-provided code.
-
- (Symbol) kv_backend
The storage backend for Riak KV.
-
- (String) leave
Removes this node from its current cluster, handing off all data.
-
- (Pathname) manifest
The "manifest" file where the node configuration will be written.
-
- (Hash) member_status
Provides the status of members of the ring.
-
- (String) name
The name of the Riak node as seen by distributed Erlang communication.
-
- (String) pb_ip
The interface to which the Protocol Buffers API is connected.
-
- (Fixnum) pb_port
The port to which the Protocol Buffers API is connected.
-
- (Array<String>) peers
A list of node names that are also members of this node's cluster, and empty list if the #member_status fails or no other nodes are present.
-
- (String) ping
Pings the node.
- - (Object) read_console_log(*levels)
-
- (Object) recreate
Deletes the node and regenerates it.
-
- (String) remove(node)
Forcibly removes a node from the current cluster without invoking handoff.
-
- (String) restart
Reboots the node.
-
- (Fixnum) ring_size
The size of the ring, i.e.
-
- (true, false) ringready?
Detects whether the node's cluster has converged on the ring.
-
- (Symbol) search_backend
The storage backend for Riak Search.
-
- (Array<String>) services
Lists riak_core applications that have registered as available, e.g.
-
- (String) start
Starts the node.
-
- (true, false) started?
Is the node running?.
-
- (Hash) status
Captures the status of the node.
-
- (String) stop
Stops the node.
-
- (true, false) stopped?
Is the node stopped? (opposite of #started?).
- - (Object) version
-
- (Object) with_console {|console| ... }
Execute the block against the Riak node's console.
Methods included from Util::Translation
Constructor Details
Instance Attribute Details
- (Hash) configuration (readonly)
The configuration that was passed to the Node when initialized
30 31 32 |
# File 'lib/riak/node/configuration.rb', line 30 def configuration @configuration end |
- (Hash) env (readonly)
The contents of the Erlang environment, which will be created into the app.config file.
22 23 24 |
# File 'lib/riak/node/configuration.rb', line 22 def env @env end |
- (Pathname) root (readonly)
The root directory of the Riak::Node, where all files are placed after generation.
104 105 106 |
# File 'lib/riak/node/configuration.rb', line 104 def root @root end |
- (Pathname) source (readonly)
The source of the Riak installation from where the Riak::Node will be generated. This should point to the directory that contains the 'riak' and 'riak-admin' scripts.
99 100 101 |
# File 'lib/riak/node/configuration.rb', line 99 def source @source end |
- (Hash) vm (readonly)
The command-line switches for the Erlang virtual machine, which will be created into the vm.args file
26 27 28 |
# File 'lib/riak/node/configuration.rb', line 26 def vm @vm end |
Class Method Details
+ (Object) create(configuration = {})
Creates a new Riak node. Unlike #new, this will also generate the node if it does not exist on disk. Equivalent to new followed by #create.
20 21 22 23 24 |
# File 'lib/riak/node.rb', line 20 def self.create(configuration={}) new(configuration).tap do |node| node.create end end |
Instance Method Details
- (Pathname) admin_script
The script for controlling non-lifecycle features of Riak like joining, leaving, status, ringready, etc.
121 122 123 |
# File 'lib/riak/node/configuration.rb', line 121 def admin_script @admin_script ||= root + 'bin' + "#{control_script_name}-admin" end |
- (Riak::Node::Console) attach
Attach to the node's console via the pipe.
70 71 72 |
# File 'lib/riak/node/control.rb', line 70 def attach Console.open self end |
- (Object) base_dir
16 17 18 |
# File 'lib/riak/node/version.rb', line 16 def base_dir @base_dir ||= configure_base_dir end |
- (Object) configure_base_dir
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/riak/node/version.rb', line 20 def configure_base_dir pattern = /^RUNNER_BASE_DIR=(.*)/ lines = control_script.readlines.grep(pattern) if lines.empty? nil else line = lines.first case line when /^RUNNER_BASE_DIR=$\{RUNNER_SCRIPT_DIR%\/*\}/ source.parent else path = pattern.match(line)[1] Pathname.new(path). if File.directory?(path) end end end |
- (Object) configure_version
9 10 11 12 13 14 |
# File 'lib/riak/node/version.rb', line 9 def configure_version if base_dir versions = (base_dir + 'releases' + 'start_erl.data').read versions.split(" ")[1] end end |
- (Pathname) control_script
The script for starting, stopping and pinging the Node.
108 109 110 |
# File 'lib/riak/node/configuration.rb', line 108 def control_script @control_script ||= root + 'bin' + control_script_name end |
- (String) control_script_name
The name of the 'riak' or 'riaksearch' control script.
114 115 116 |
# File 'lib/riak/node/configuration.rb', line 114 def control_script_name @control_script_name ||= (source + 'riaksearch').exist? ? 'riaksearch' : 'riak' end |
- (String) cookie
The cookie/shared secret used for connecting a cluster
91 92 93 |
# File 'lib/riak/node/configuration.rb', line 91 def vm['-setcookie'] end |
- (Object) create
Generates the node.
17 18 19 20 21 22 23 24 25 |
# File 'lib/riak/node/generation.rb', line 17 def create unless exist? create_directories write_scripts write_vm_args write_app_config write_manifest end end |
- (Object) destroy
Removes the node from disk and freezes the object.
43 44 45 46 |
# File 'lib/riak/node/generation.rb', line 43 def destroy delete freeze end |
- (Object) drop
Clears data from known data directories. Stops the node if it is running.
29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/riak/node/generation.rb', line 29 def drop was_started = started? stop if was_started data.children.each do |item| if item.directory? item.children.each {|c| c.rmtree } else item.delete end end start if was_started end |
- (Array<Pathname>) erlang_sources
Where user Erlang code will be loaded from
33 34 35 |
# File 'lib/riak/node/configuration.rb', line 33 def erlang_sources env[:riak_kv][:add_paths].map {|p| Pathname.new(p) } end |
- (Boolean) exist?
Does the node exist on disk?
6 7 8 |
# File 'lib/riak/node/generation.rb', line 6 def exist? manifest.exist? end |
- (Object) expand_log_level(level)
23 24 25 26 27 28 29 30 31 32 |
# File 'lib/riak/node/log.rb', line 23 def (level) case level when Range first = LAGER_LEVELS.index(level.begin.to_sym) || 0 last = LAGER_LEVELS.index(level.end.to_sym) || -1 LAGER_LEVELS[first..last] when Symbol level end end |
- (Fixnum) handoff_port
The port used for handing off data to other nodes.
48 49 50 |
# File 'lib/riak/node/configuration.rb', line 48 def handoff_port env[:riak_core][:handoff_port] end |
- (String) http_ip
The interface to which the HTTP API is connected
64 65 66 |
# File 'lib/riak/node/configuration.rb', line 64 def http_ip env[:riak_core][:http][0][0] end |
- (Fixnum) http_port
The port to which the HTTP API is connected.
53 54 55 56 |
# File 'lib/riak/node/configuration.rb', line 53 def http_port # We'll only support 0.14 and later, which uses http rather than web_ip/web_port env[:riak_core][:http][0][1] end |
- (Pathname) javascript_source
Where user Javascript code will be loaded from
38 39 40 |
# File 'lib/riak/node/configuration.rb', line 38 def javascript_source Pathname.new(env[:riak_kv][:js_source_dir]) end |
- (String) join(node)
Joins the node to another node to create a cluster.
89 90 91 92 |
# File 'lib/riak/node/control.rb', line 89 def join(node) node = node.name if Node === node riak_admin 'join', node end |
- (Object) js_reload
Forces the node to restart/reload its JavaScript VMs, effectively reloading any user-provided code.
140 141 142 |
# File 'lib/riak/node/control.rb', line 140 def js_reload riak_admin 'js_reload' end |
- (Symbol) kv_backend
The storage backend for Riak KV.
79 80 81 |
# File 'lib/riak/node/configuration.rb', line 79 def kv_backend env[:riak_kv][:storage_backend] end |
- (String) leave
Removes this node from its current cluster, handing off all data.
96 97 98 |
# File 'lib/riak/node/control.rb', line 96 def leave riak_admin 'leave' end |
- (Pathname) manifest
The "manifest" file where the node configuration will be written.
128 129 130 |
# File 'lib/riak/node/configuration.rb', line 128 def manifest root + '.node.yml' end |
- (Hash) member_status
Provides the status of members of the ring.
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 172 |
# File 'lib/riak/node/control.rb', line 146 def member_status output = riak_admin 'member_status' result = {} if $?.success? output.each_line do |line| next if line =~ /^(?:[=-]|Status)+/ # Skip the pretty headers if line =~ %r{^Valid:(\d+) / Leaving:(\d+) / Exiting:(\d+) / Joining:(\d+) / Down:(\d+)} result.merge!(:valid => $1.to_i, :leaving => $2.to_i, :exiting => $3.to_i, :joining => $4.to_i, :down => $5.to_i) else result[:members] ||= {} status, ring, pending, node = line.split(/\s+/) node = $1 if node =~ /^'(.*)'$/ ring = $1.to_f if ring =~ /(\d+\.\d+)%/ result[:members][node] = { :status => status, :ring => ring, :pending => (pending == '--') ? 0 : pending.to_i } end end end result end |
- (String) name
The name of the Riak node as seen by distributed Erlang communication. AKA "-name" in vm.args.
85 86 87 |
# File 'lib/riak/node/configuration.rb', line 85 def name vm['-name'] end |
- (String) pb_ip
The interface to which the Protocol Buffers API is connected
69 70 71 |
# File 'lib/riak/node/configuration.rb', line 69 def pb_ip env[:riak_kv][:pb_ip] end |
- (Fixnum) pb_port
The port to which the Protocol Buffers API is connected.
59 60 61 |
# File 'lib/riak/node/configuration.rb', line 59 def pb_port env[:riak_kv][:pb_port] end |
- (Array<String>) peers
A list of node names that are also members of this node's cluster, and empty list if the #member_status fails or no other nodes are present
177 178 179 180 |
# File 'lib/riak/node/control.rb', line 177 def peers all_nodes = member_status[:members] && member_status[:members].keys.reject {|n| n == name } all_nodes || [] end |
- (String) ping
Pings the node
55 56 57 58 59 60 61 62 63 64 |
# File 'lib/riak/node/control.rb', line 55 def ping begin riak 'ping' rescue SystemCallError # If the control script doesn't exist or has the wrong # permissions, we should still return something sane so we can # do the right thing. "Node '#{name}' not responding to pings." end end |
- (Object) read_console_log(*levels)
14 15 16 17 18 19 20 21 |
# File 'lib/riak/node/log.rb', line 14 def read_console_log(*levels) console_log = log + 'console.log' if console_log.exist? levels = levels.map { |level| (level) }.compact.flatten pattern = /(#{levels.map { |level| "\\[#{level}\\]" }.join("|")})/ console_log.readlines.grep(pattern) end end |
- (Object) recreate
Deletes the node and regenerates it.
11 12 13 14 |
# File 'lib/riak/node/generation.rb', line 11 def recreate delete create end |
- (String) remove(node)
Forcibly removes a node from the current cluster without invoking handoff.
104 105 106 107 |
# File 'lib/riak/node/control.rb', line 104 def remove(node) node = node.name if Node === node riak_admin 'remove', node end |
- (String) restart
Reboots the node
43 44 45 |
# File 'lib/riak/node/control.rb', line 43 def restart riak 'reboot' end |
- (Fixnum) ring_size
The size of the ring, i.e. number of partitions
43 44 45 |
# File 'lib/riak/node/configuration.rb', line 43 def ring_size env[:riak_core][:ring_creation_size] end |
- (true, false) ringready?
Detects whether the node's cluster has converged on the ring.
121 122 123 124 |
# File 'lib/riak/node/control.rb', line 121 def ringready? output = riak_admin 'ringready' output =~ /^TRUE/ || $?.success? end |
- (Symbol) search_backend
The storage backend for Riak Search.
74 75 76 |
# File 'lib/riak/node/configuration.rb', line 74 def search_backend env[:riak_search][:search_backend] end |
- (Array<String>) services
Lists riak_core applications that have registered as available, e.g. ["riak_kv", "riak_search", "riak_pipe"]
129 130 131 132 133 134 135 136 |
# File 'lib/riak/node/control.rb', line 129 def services output = riak_admin 'services' if $?.success? output.strip.match(/^\[(.*)\]$/)[1].split(/,/) else [] end end |
- (String) start
Starts the node.
27 28 29 30 31 |
# File 'lib/riak/node/control.rb', line 27 def start res = riak 'start' wait_for_startup res end |
- (true, false) started?
Is the node running?
13 14 15 16 |
# File 'lib/riak/node/control.rb', line 13 def started? pinged = ping pinged.strip =~ /pong/ || pinged.strip !~ /Node '[^']+' not responding to pings/ end |
- (Hash) status
Captures the status of the node.
111 112 113 114 115 116 117 |
# File 'lib/riak/node/control.rb', line 111 def status output = riak_admin 'status' if $?.success? result = {} Hash[output.scan(STATS_REGEXP)] end end |
- (String) stop
Stops the node
35 36 37 38 39 |
# File 'lib/riak/node/control.rb', line 35 def stop res = riak 'stop' wait_for_shutdown res end |
- (true, false) stopped?
Is the node stopped? (opposite of #started?).
21 22 23 |
# File 'lib/riak/node/control.rb', line 21 def stopped? !started? end |
- (Object) version
5 6 7 |
# File 'lib/riak/node/version.rb', line 5 def version @version ||= configure_version end |
- (Object) with_console {|console| ... }
Execute the block against the Riak node's console.
78 79 80 81 82 83 84 85 |
# File 'lib/riak/node/control.rb', line 78 def with_console begin console = attach yield console ensure console.close if console end end |