HBASE-22518 yetus personality is treating branch-1.4 like earlier branches for hadoop...
[hbase.git] / hbase-shell / src / main / ruby / shell.rb
bloba8e58ed6560bf0f00387d430d54ec3c1d29a9b43
3 # Licensed to the Apache Software Foundation (ASF) under one
4 # or more contributor license agreements.  See the NOTICE file
5 # distributed with this work for additional information
6 # regarding copyright ownership.  The ASF licenses this file
7 # to you under the Apache License, Version 2.0 (the
8 # "License"); you may not use this file except in compliance
9 # with the License.  You may obtain a copy of the License at
11 #     http://www.apache.org/licenses/LICENSE-2.0
13 # Unless required by applicable law or agreed to in writing, software
14 # distributed under the License is distributed on an "AS IS" BASIS,
15 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 # See the License for the specific language governing permissions and
17 # limitations under the License.
20 # Shell commands module
21 module Shell
22   @@commands = {}
23   def self.commands
24     @@commands
25   end
27   @@command_groups = {}
28   def self.command_groups
29     @@command_groups
30   end
32   def self.load_command(name, group, aliases = [])
33     return if commands[name]
35     # Register command in the group
36     raise ArgumentError, "Unknown group: #{group}" unless command_groups[group]
37     command_groups[group][:commands] << name
39     # Load command
40     begin
41       require "shell/commands/#{name}"
42       klass_name = name.to_s.gsub(/(?:^|_)(.)/) { Regexp.last_match(1).upcase } # camelize
43       commands[name] = eval("Commands::#{klass_name}")
44       aliases.each do |an_alias|
45         commands[an_alias] = commands[name]
46       end
47     rescue => e
48       raise "Can't load hbase shell command: #{name}. Error: #{e}\n#{e.backtrace.join("\n")}"
49     end
50   end
52   def self.load_command_group(group, opts)
53     raise ArgumentError, "No :commands for group #{group}" unless opts[:commands]
55     command_groups[group] = {
56       commands: [],
57       command_names: opts[:commands],
58       full_name: opts[:full_name] || group,
59       comment: opts[:comment]
60     }
62     all_aliases = opts[:aliases] || {}
64     opts[:commands].each do |command|
65       aliases = all_aliases[command] || []
66       load_command(command, group, aliases)
67     end
68   end
70   #----------------------------------------------------------------------
71   # rubocop:disable Metrics/ClassLength
72   class Shell
73     attr_accessor :hbase
74     attr_accessor :interactive
75     alias interactive? interactive
77     @debug = false
78     attr_accessor :debug
80     def initialize(hbase, interactive = true)
81       self.hbase = hbase
82       self.interactive = interactive
83     end
85     # Returns Admin class from admin.rb
86     def admin
87       @admin ||= hbase.admin
88     end
90     def hbase_taskmonitor
91       @hbase_taskmonitor ||= hbase.taskmonitor
92     end
94     def hbase_table(name)
95       hbase.table(name, self)
96     end
98     def hbase_replication_admin
99       @hbase_replication_admin ||= hbase.replication_admin
100     end
102     def hbase_security_admin
103       @hbase_security_admin ||= hbase.security_admin
104     end
106     def hbase_visibility_labels_admin
107       @hbase_visibility_labels_admin ||= hbase.visibility_labels_admin
108     end
110     def hbase_quotas_admin
111       @hbase_quotas_admin ||= hbase.quotas_admin
112     end
114     def hbase_rsgroup_admin
115       @rsgroup_admin ||= hbase.rsgroup_admin
116     end
118     def export_commands(where)
119       ::Shell.commands.keys.each do |cmd|
120         # here where is the IRB namespace
121         # this method just adds the call to the specified command
122         # which just references back to 'this' shell object
123         # a decently extensible way to add commands
124         where.send :instance_eval, <<-EOF
125           def #{cmd}(*args)
126             ret = @shell.command('#{cmd}', *args)
127             puts
128             return ret
129           end
130         EOF
131       end
132     end
134     def command_instance(command)
135       ::Shell.commands[command.to_s].new(self)
136     end
138     # call the method 'command' on the specified command
139     def command(command, *args)
140       internal_command(command, :command, *args)
141     end
143     # call a specific internal method in the command instance
144     # command  - name of the command to call
145     # method_name - name of the method on the command to call. Defaults to just 'command'
146     # args - to be passed to the named method
147     def internal_command(command, method_name = :command, *args)
148       command_instance(command).command_safe(debug, method_name, *args)
149     end
151     def print_banner
152       puts 'HBase Shell'
153       puts 'Use "help" to get list of supported commands.'
154       puts 'Use "exit" to quit this interactive shell.'
155       puts 'For Reference, please visit: http://hbase.apache.org/book.html#shell'
156       print 'Version '
157       command('version')
158       puts
159     end
161     def help_multi_command(command)
162       puts "Command: #{command}"
163       puts command_instance(command).help
164       puts
165       nil
166     end
168     def help_command(command)
169       puts command_instance(command).help
170       nil
171     end
173     def help_group(group_name)
174       group = ::Shell.command_groups[group_name.to_s]
175       group[:commands].sort.each { |cmd| help_multi_command(cmd) }
176       if group[:comment]
177         puts '-' * 80
178         puts
179         puts group[:comment]
180         puts
181       end
182       nil
183     end
185     def help(command = nil)
186       if command
187         return help_command(command) if ::Shell.commands[command.to_s]
188         return help_group(command) if ::Shell.command_groups[command.to_s]
189         puts "ERROR: Invalid command or command group name: #{command}"
190         puts
191       end
193       puts help_header
194       puts
195       puts 'COMMAND GROUPS:'
196       ::Shell.command_groups.each do |name, group|
197         puts '  Group name: ' + name
198         puts '  Commands: ' + group[:command_names].sort.join(', ')
199         puts
200       end
201       unless command
202         puts 'SHELL USAGE:'
203         help_footer
204       end
205       nil
206     end
208     def help_header
209       "HBase Shell, version #{org.apache.hadoop.hbase.util.VersionInfo.getVersion}, " \
210              "r#{org.apache.hadoop.hbase.util.VersionInfo.getRevision}, " \
211              "#{org.apache.hadoop.hbase.util.VersionInfo.getDate}" + "\n" \
212              "Type 'help \"COMMAND\"', (e.g. 'help \"get\"' -- the quotes are necessary) for help on a specific command.\n" \
213              "Commands are grouped. Type 'help \"COMMAND_GROUP\"', (e.g. 'help \"general\"') for help on a command group."
214     end
216     def help_footer
217       puts <<-HERE
218 Quote all names in HBase Shell such as table and column names.  Commas delimit
219 command parameters.  Type <RETURN> after entering a command to run it.
220 Dictionaries of configuration used in the creation and alteration of tables are
221 Ruby Hashes. They look like this:
223   {'key1' => 'value1', 'key2' => 'value2', ...}
225 and are opened and closed with curley-braces.  Key/values are delimited by the
226 '=>' character combination.  Usually keys are predefined constants such as
227 NAME, VERSIONS, COMPRESSION, etc.  Constants do not need to be quoted.  Type
228 'Object.constants' to see a (messy) list of all constants in the environment.
230 If you are using binary keys or values and need to enter them in the shell, use
231 double-quote'd hexadecimal representation. For example:
233   hbase> get 't1', "key\\x03\\x3f\\xcd"
234   hbase> get 't1', "key\\003\\023\\011"
235   hbase> put 't1', "test\\xef\\xff", 'f1:', "\\x01\\x33\\x40"
237 The HBase shell is the (J)Ruby IRB with the above HBase-specific commands added.
238 For more on the HBase Shell, see http://hbase.apache.org/book.html
239       HERE
240     end
241   end
242   # rubocop:enable Metrics/ClassLength
245 # Load commands base class
246 require 'shell/commands'
248 # Load all commands
249 Shell.load_command_group(
250   'general',
251   full_name: 'GENERAL HBASE SHELL COMMANDS',
252   commands: %w[
253     status
254     version
255     table_help
256     whoami
257     processlist
258   ]
261 Shell.load_command_group(
262   'ddl',
263   full_name: 'TABLES MANAGEMENT COMMANDS',
264   commands: %w[
265     alter
266     create
267     describe
268     disable
269     disable_all
270     is_disabled
271     drop
272     drop_all
273     enable
274     enable_all
275     is_enabled
276     exists
277     list
278     show_filters
279     alter_status
280     alter_async
281     get_table
282     locate_region
283     list_regions
284     clone_table_schema
285   ],
286   aliases: {
287     'describe' => ['desc']
288   }
291 Shell.load_command_group(
292   'namespace',
293   full_name: 'NAMESPACE MANAGEMENT COMMANDS',
294   commands: %w[
295     create_namespace
296     drop_namespace
297     alter_namespace
298     describe_namespace
299     list_namespace
300     list_namespace_tables
301   ]
304 Shell.load_command_group(
305   'dml',
306   full_name: 'DATA MANIPULATION COMMANDS',
307   commands: %w[
308     count
309     delete
310     deleteall
311     get
312     get_counter
313     incr
314     put
315     scan
316     truncate
317     truncate_preserve
318     append
319     get_splits
320   ]
323 Shell.load_command_group(
324   'tools',
325   full_name: 'HBASE SURGERY TOOLS',
326   comment: "WARNING: Above commands are for 'experts'-only as misuse can damage an install",
327   commands: %w[
328     assign
329     balancer
330     balance_switch
331     balancer_enabled
332     normalize
333     normalizer_switch
334     normalizer_enabled
335     is_in_maintenance_mode
336     close_region
337     compact
338     compaction_switch
339     flush
340     major_compact
341     move
342     split
343     merge_region
344     unassign
345     zk_dump
346     wal_roll
347     catalogjanitor_run
348     catalogjanitor_switch
349     catalogjanitor_enabled
350     cleaner_chore_run
351     cleaner_chore_switch
352     cleaner_chore_enabled
353     compact_rs
354     compaction_state
355     trace
356     splitormerge_switch
357     splitormerge_enabled
358     clear_compaction_queues
359     list_deadservers
360     clear_deadservers
361     clear_block_cache
362     stop_master
363     stop_regionserver
364     rit
365     list_decommissioned_regionservers
366     decommission_regionservers
367     recommission_regionserver
368   ],
369   # TODO: remove older hlog_roll command
370   aliases: {
371     'wal_roll' => ['hlog_roll']
372   }
375 Shell.load_command_group(
376   'replication',
377   full_name: 'CLUSTER REPLICATION TOOLS',
378   commands: %w[
379     add_peer
380     remove_peer
381     list_peers
382     enable_peer
383     disable_peer
384     set_peer_replicate_all
385     set_peer_serial
386     set_peer_namespaces
387     append_peer_namespaces
388     remove_peer_namespaces
389     set_peer_exclude_namespaces
390     append_peer_exclude_namespaces
391     remove_peer_exclude_namespaces
392     show_peer_tableCFs
393     set_peer_tableCFs
394     set_peer_exclude_tableCFs
395     append_peer_exclude_tableCFs
396     remove_peer_exclude_tableCFs
397     set_peer_bandwidth
398     list_replicated_tables
399     append_peer_tableCFs
400     remove_peer_tableCFs
401     enable_table_replication
402     disable_table_replication
403     get_peer_config
404     list_peer_configs
405     update_peer_config
406     transit_peer_sync_replication_state
407   ]
410 Shell.load_command_group(
411   'snapshots',
412   full_name: 'CLUSTER SNAPSHOT TOOLS',
413   commands: %w[
414     snapshot
415     clone_snapshot
416     restore_snapshot
417     delete_snapshot
418     delete_all_snapshot
419     delete_table_snapshots
420     list_snapshots
421     list_table_snapshots
422   ]
425 Shell.load_command_group(
426   'configuration',
427   full_name: 'ONLINE CONFIGURATION TOOLS',
428   commands: %w[
429     update_config
430     update_all_config
431   ]
434 Shell.load_command_group(
435   'quotas',
436   full_name: 'CLUSTER QUOTAS TOOLS',
437   commands: %w[
438     set_quota
439     list_quotas
440     list_quota_table_sizes
441     list_quota_snapshots
442     list_snapshot_sizes
443     enable_rpc_throttle
444     disable_rpc_throttle
445     enable_exceed_throttle_quota
446     disable_exceed_throttle_quota
447   ]
450 Shell.load_command_group(
451   'security',
452   full_name: 'SECURITY TOOLS',
453   comment: 'NOTE: Above commands are only applicable if running with the AccessController coprocessor',
454   commands: %w[
455     list_security_capabilities
456     grant
457     revoke
458     user_permission
459   ]
462 Shell.load_command_group(
463   'procedures',
464   full_name: 'PROCEDURES & LOCKS MANAGEMENT',
465   commands: %w[
466     list_procedures
467     list_locks
468   ]
471 Shell.load_command_group(
472   'visibility labels',
473   full_name: 'VISIBILITY LABEL TOOLS',
474   comment: 'NOTE: Above commands are only applicable if running with the VisibilityController coprocessor',
475   commands: %w[
476     add_labels
477     list_labels
478     set_auths
479     get_auths
480     clear_auths
481     set_visibility
482   ]
485 Shell.load_command_group(
486   'rsgroup',
487   full_name: 'RSGroups',
488   comment: "NOTE: The rsgroup Coprocessor Endpoint must be enabled on the Master else commands fail with:
489   UnknownProtocolException: No registered Master Coprocessor Endpoint found for RSGroupAdminService",
490   commands: %w[
491     list_rsgroups
492     get_rsgroup
493     add_rsgroup
494     remove_rsgroup
495     balance_rsgroup
496     move_servers_rsgroup
497     move_tables_rsgroup
498     move_namespaces_rsgroup
499     move_servers_tables_rsgroup
500     move_servers_namespaces_rsgroup
501     get_server_rsgroup
502     get_table_rsgroup
503     remove_servers_rsgroup
504   ]