HBASE-22152 Create a jenkins file for yetus to processing GitHub PR
[hbase.git] / bin / hirb.rb
blobfcbec7809c9da41270cac6f55b39f31a04c13fba
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.
19 # File passed to org.jruby.Main by bin/hbase.  Pollutes jirb with hbase imports
20 # and hbase  commands and then loads jirb.  Outputs a banner that tells user
21 # where to find help, shell version, and loads up a custom hirb.
23 # In noninteractive mode, runs commands from stdin until completion or an error.
24 # On success will exit with status 0, on any problem will exit non-zero. Callers
25 # should only rely on "not equal to 0", because the current error exit code of 1
26 # will likely be updated to diffentiate e.g. invalid commands, incorrect args,
27 # permissions, etc.
29 # TODO: Interrupt a table creation or a connection to a bad master.  Currently
30 # has to time out.  Below we've set down the retries for rpc and hbase but
31 # still can be annoying (And there seem to be times when we'll retry for
32 # ever regardless)
33 # TODO: Add support for listing and manipulating catalog tables, etc.
34 # TODO: Encoding; need to know how to go from ruby String to UTF-8 bytes
36 # Run the java magic include and import basic HBase types that will help ease
37 # hbase hacking.
38 include Java
40 # Some goodies for hirb. Should these be left up to the user's discretion?
41 require 'irb/completion'
42 require 'pathname'
44 # Add the directory names in hbase.jruby.sources commandline option
45 # to the ruby load path so I can load up my HBase ruby modules
46 sources = java.lang.System.getProperty('hbase.ruby.sources')
47 $LOAD_PATH.unshift Pathname.new(sources)
50 # FIXME: Switch args processing to getopt
52 # See if there are args for this shell. If any, read and then strip from ARGV
53 # so they don't go through to irb.  Output shell 'usage' if user types '--help'
54 cmdline_help = <<HERE # HERE document output as shell usage
55 Usage: shell [OPTIONS] [SCRIPTFILE [ARGUMENTS]]
57  -d | --debug            Set DEBUG log levels.
58  -h | --help             This help.
59  -n | --noninteractive   Do not run within an IRB session and exit with non-zero
60                          status on first error.
61  -Dkey=value             Pass hbase-*.xml Configuration overrides. For example, to
62                          use an alternate zookeeper ensemble, pass:
63                            -Dhbase.zookeeper.quorum=zookeeper.example.org
64                          For faster fail, pass the below and vary the values:
65                            -Dhbase.client.retries.number=7
66                            -Dhbase.ipc.client.connect.max.retries=3
67 HERE
69 # Takes configuration and an arg that is expected to be key=value format.
70 # If c is empty, creates one and returns it
71 def add_to_configuration(c, arg)
72   kv = arg.split('=')
73   kv.length == 2 || (raise "Expected parameter #{kv} in key=value format")
74   c = org.apache.hadoop.hbase.HBaseConfiguration.create if c.nil?
75   c.set(kv[0], kv[1])
76   c
77 end
79 found = []
80 script2run = nil
81 log_level = org.apache.log4j.Level::ERROR
82 @shell_debug = false
83 interactive = true
84 _configuration = nil
85 D_ARG = '-D'.freeze
86 while (arg = ARGV.shift)
87   if arg == '-h' || arg == '--help'
88     puts cmdline_help
89     exit
90   elsif arg == D_ARG
91     argValue = ARGV.shift || (raise "#{D_ARG} takes a 'key=value' parameter")
92     _configuration = add_to_configuration(_configuration, argValue)
93     found.push(arg)
94     found.push(argValue)
95   elsif arg.start_with? D_ARG
96     _configuration = add_to_configuration(_configuration, arg[2..-1])
97     found.push(arg)
98   elsif arg == '-d' || arg == '--debug'
99     log_level = org.apache.log4j.Level::DEBUG
100     $fullBackTrace = true
101     @shell_debug = true
102     found.push(arg)
103     puts 'Setting DEBUG log level...'
104   elsif arg == '-n' || arg == '--noninteractive'
105     interactive = false
106     found.push(arg)
107   elsif arg == '-r' || arg == '--return-values'
108     warn '[INFO] the -r | --return-values option is ignored. we always behave '\
109          'as though it was given.'
110     found.push(arg)
111   else
112     # Presume it a script. Save it off for running later below
113     # after we've set up some environment.
114     script2run = arg
115     found.push(arg)
116     # Presume that any other args are meant for the script.
117     break
118   end
121 # Delete all processed args
122 found.each { |arg| ARGV.delete(arg) }
123 # Make sure debug flag gets back to IRB
124 ARGV.unshift('-d') if @shell_debug
126 # Set logging level to avoid verboseness
127 org.apache.log4j.Logger.getLogger('org.apache.zookeeper').setLevel(log_level)
128 org.apache.log4j.Logger.getLogger('org.apache.hadoop.hbase').setLevel(log_level)
130 # Require HBase now after setting log levels
131 require 'hbase_constants'
133 # Load hbase shell
134 require 'shell'
136 # Require formatter
137 require 'shell/formatter'
139 # Setup the HBase module.  Create a configuration.
140 @hbase = _configuration.nil? ? Hbase::Hbase.new : Hbase::Hbase.new(_configuration)
142 # Setup console
143 @shell = Shell::Shell.new(@hbase, interactive)
144 @shell.debug = @shell_debug
146 # Add commands to this namespace
147 # TODO avoid polluting main namespace by using a binding
148 @shell.export_commands(self)
150 # Add help command
151 def help(command = nil)
152   @shell.help(command)
155 # Backwards compatibility method
156 def tools
157   @shell.help_group('tools')
160 # Debugging method
161 def debug
162   if @shell_debug
163     @shell_debug = false
164     conf.back_trace_limit = 0
165     log_level = org.apache.log4j.Level::ERROR
166   else
167     @shell_debug = true
168     conf.back_trace_limit = 100
169     log_level = org.apache.log4j.Level::DEBUG
170   end
171   org.apache.log4j.Logger.getLogger('org.apache.zookeeper').setLevel(log_level)
172   org.apache.log4j.Logger.getLogger('org.apache.hadoop.hbase').setLevel(log_level)
173   debug?
176 def debug?
177   puts "Debug mode is #{@shell_debug ? 'ON' : 'OFF'}\n\n"
178   nil
181 # Include hbase constants
182 include HBaseConstants
184 # If script2run, try running it.  If we're in interactive mode, will go on to run the shell unless
185 # script calls 'exit' or 'exit 0' or 'exit errcode'.
186 load(script2run) if script2run
188 if interactive
189   # Output a banner message that tells users where to go for help
190   @shell.print_banner
192   require 'irb'
193   require 'irb/hirb'
195   module IRB
196     def self.start(ap_path = nil)
197       $0 = File.basename(ap_path, '.rb') if ap_path
199       IRB.setup(ap_path)
200       @CONF[:IRB_NAME] = 'hbase'
201       @CONF[:AP_NAME] = 'hbase'
202       @CONF[:BACK_TRACE_LIMIT] = 0 unless $fullBackTrace
204       hirb = if @CONF[:SCRIPT]
205                HIRB.new(nil, @CONF[:SCRIPT])
206              else
207                HIRB.new
208              end
210       @CONF[:IRB_RC].call(hirb.context) if @CONF[:IRB_RC]
211       @CONF[:MAIN_CONTEXT] = hirb.context
213       catch(:IRB_EXIT) do
214         hirb.eval_input
215       end
216     end
217   end
219   IRB.start
220 else
221   begin
222     # Noninteractive mode: if there is input on stdin, do a simple REPL.
223     # XXX Note that this purposefully uses STDIN and not Kernel.gets
224     #     in order to maintain compatibility with previous behavior where
225     #     a user could pass in script2run and then still pipe commands on
226     #     stdin.
227     require 'irb/ruby-lex'
228     require 'irb/workspace'
229     workspace = IRB::WorkSpace.new(binding)
230     scanner = RubyLex.new
232     # RubyLex claims to take an IO but really wants an InputMethod
233     module IOExtensions
234       def encoding
235         external_encoding
236       end
237     end
238     IO.include IOExtensions
240     scanner.set_input(STDIN)
241     scanner.each_top_level_statement do |statement, linenum|
242       puts(workspace.evaluate(nil, statement, 'stdin', linenum))
243     end
244   # XXX We're catching Exception on purpose, because we want to include
245   #     unwrapped java exceptions, syntax errors, eval failures, etc.
246   rescue Exception => exception
247     message = exception.to_s
248     # exception unwrapping in shell means we'll have to handle Java exceptions
249     # as a special case in order to format them properly.
250     if exception.is_a? java.lang.Exception
251       warn 'java exception'
252       message = exception.get_message
253     end
254     # Include the 'ERROR' string to try to make transition easier for scripts that
255     # may have already been relying on grepping output.
256     puts "ERROR #{exception.class}: #{message}"
257     if $fullBacktrace
258       # re-raising the will include a backtrace and exit.
259       raise exception
260     else
261       exit 1
262     end
263   end