morpheus-cli 2.10.1 → 2.10.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/morpheus +60 -21
- data/lib/morpheus/api/api_client.rb +2 -0
- data/lib/morpheus/api/instances_interface.rb +8 -0
- data/lib/morpheus/cli.rb +19 -10
- data/lib/morpheus/cli/accounts.rb +32 -9
- data/lib/morpheus/cli/alias_command.rb +68 -22
- data/lib/morpheus/cli/app_templates.rb +22 -7
- data/lib/morpheus/cli/apps.rb +32 -26
- data/lib/morpheus/cli/cli_command.rb +135 -27
- data/lib/morpheus/cli/clouds.rb +8 -3
- data/lib/morpheus/cli/coloring_command.rb +39 -0
- data/lib/morpheus/cli/dot_file.rb +207 -0
- data/lib/morpheus/cli/echo_command.rb +32 -0
- data/lib/morpheus/cli/error_handler.rb +3 -1
- data/lib/morpheus/cli/groups.rb +18 -20
- data/lib/morpheus/cli/hosts.rb +96 -22
- data/lib/morpheus/cli/instances.rb +76 -8
- data/lib/morpheus/cli/log_level_command.rb +51 -0
- data/lib/morpheus/cli/option_parser.rb +13 -7
- data/lib/morpheus/cli/option_types.rb +337 -317
- data/lib/morpheus/cli/remote.rb +37 -6
- data/lib/morpheus/cli/roles.rb +3 -1
- data/lib/morpheus/cli/shell.rb +299 -245
- data/lib/morpheus/cli/source_command.rb +39 -0
- data/lib/morpheus/cli/ssl_verification_command.rb +49 -0
- data/lib/morpheus/cli/tasks.rb +2 -2
- data/lib/morpheus/cli/users.rb +7 -11
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/virtual_images.rb +3 -4
- data/lib/morpheus/cli/whoami.rb +6 -5
- data/morpheus-cli.gemspec +1 -1
- data/scripts/generate_morpheus_commands_help.morpheus +1253 -0
- metadata +10 -3
- data/lib/morpheus/cli/config_file.rb +0 -126
data/lib/morpheus/cli/remote.rb
CHANGED
@@ -65,7 +65,6 @@ class Morpheus::Cli::Remote
|
|
65
65
|
use_it = false
|
66
66
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
67
67
|
opts.banner = subcommand_usage("[name] [url]")
|
68
|
-
build_common_options(opts, options, [])
|
69
68
|
opts.on( '--use', '--use', "Make this the current remote appliance" ) do
|
70
69
|
use_it = true
|
71
70
|
end
|
@@ -80,6 +79,7 @@ class Morpheus::Cli::Remote
|
|
80
79
|
# puts good_opts
|
81
80
|
# exit
|
82
81
|
# end
|
82
|
+
build_common_options(opts, options, [:quiet])
|
83
83
|
opts.footer = "This will add a new appliance to your list.\n" +
|
84
84
|
"If it's first one, it will be made the current active appliance."
|
85
85
|
end
|
@@ -103,6 +103,7 @@ class Morpheus::Cli::Remote
|
|
103
103
|
end
|
104
104
|
if @appliances[new_appliance_name] != nil
|
105
105
|
print red, "Remote appliance already configured with the name '#{args[0]}'", reset, "\n"
|
106
|
+
return false
|
106
107
|
else
|
107
108
|
@appliances[new_appliance_name] = {
|
108
109
|
host: url,
|
@@ -110,11 +111,38 @@ class Morpheus::Cli::Remote
|
|
110
111
|
}
|
111
112
|
::Morpheus::Cli::Remote.save_appliances(@appliances)
|
112
113
|
if use_it
|
113
|
-
|
114
|
+
Morpheus::Cli::Remote.set_active_appliance(new_appliance_name)
|
114
115
|
@appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
115
116
|
end
|
116
117
|
end
|
117
|
-
|
118
|
+
|
119
|
+
if options[:quiet] || options[:no_prompt]
|
120
|
+
return true
|
121
|
+
end
|
122
|
+
|
123
|
+
# check to see if this is a fresh appliance.
|
124
|
+
# GET /api/setup only returns 200 if it can still be initialized, else 400
|
125
|
+
@setup_interface = Morpheus::SetupInterface.new(@appliance_url)
|
126
|
+
appliance_status_json = nil
|
127
|
+
begin
|
128
|
+
appliance_status_json = @setup_interface.get()
|
129
|
+
if appliance_status_json['success'] == true
|
130
|
+
return setup([new_appliance_name])
|
131
|
+
end
|
132
|
+
# should not get here
|
133
|
+
rescue RestClient::Exception => e
|
134
|
+
#print_rest_exception(e, options)
|
135
|
+
# laff, treating any non - 200 as meaning it is good ...is bad.. could be at the wrong site.. sending credentials..
|
136
|
+
print cyan,"Appliance is ready.\n", reset
|
137
|
+
end
|
138
|
+
|
139
|
+
if use_it
|
140
|
+
if ::Morpheus::Cli::OptionTypes::confirm("Would you like to login now?", options.merge({default: true}))
|
141
|
+
return ::Morpheus::Cli::Login.new.handle([new_appliance_name])
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
return true
|
118
146
|
end
|
119
147
|
|
120
148
|
def remove(args)
|
@@ -156,7 +184,9 @@ class Morpheus::Cli::Remote
|
|
156
184
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
157
185
|
opts.banner = subcommand_usage("[name]")
|
158
186
|
build_common_options(opts, options, [])
|
159
|
-
opts.footer = "This
|
187
|
+
opts.footer = "This sets the current active appliance.\n" +
|
188
|
+
"This allows you to switch between your different appliances.\n" +
|
189
|
+
"You may override this with the --remote option in your commands."
|
160
190
|
end
|
161
191
|
optparse.parse!(args)
|
162
192
|
if args.count < 1
|
@@ -185,8 +215,8 @@ class Morpheus::Cli::Remote
|
|
185
215
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
186
216
|
opts.banner = subcommand_usage()
|
187
217
|
opts.footer = "" +
|
188
|
-
"This
|
189
|
-
"You will need to use an appliance
|
218
|
+
"This clears the current active appliance.\n" +
|
219
|
+
"You will need to use an appliance, or pass the --remote option to your commands."
|
190
220
|
build_common_options(opts, options, [])
|
191
221
|
end
|
192
222
|
optparse.parse!(args)
|
@@ -206,6 +236,7 @@ class Morpheus::Cli::Remote
|
|
206
236
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
207
237
|
opts.banner = subcommand_usage()
|
208
238
|
build_common_options(opts, options, [:json])
|
239
|
+
opts.footer = "Prints the name of the current remote appliance"
|
209
240
|
end
|
210
241
|
optparse.parse!(args)
|
211
242
|
|
data/lib/morpheus/cli/roles.rb
CHANGED
@@ -223,7 +223,8 @@ class Morpheus::Cli::Roles
|
|
223
223
|
usage = "Usage: morpheus roles add [options]"
|
224
224
|
options = {}
|
225
225
|
optparse = OptionParser.new do|opts|
|
226
|
-
opts.banner = subcommand_usage("[
|
226
|
+
opts.banner = subcommand_usage("[options]")
|
227
|
+
build_option_type_options(opts, options, add_role_option_types)
|
227
228
|
build_common_options(opts, options, [:options, :json, :dry_run])
|
228
229
|
end
|
229
230
|
optparse.parse!(args)
|
@@ -316,6 +317,7 @@ class Morpheus::Cli::Roles
|
|
316
317
|
options = {}
|
317
318
|
optparse = OptionParser.new do|opts|
|
318
319
|
opts.banner = subcommand_usage("[name] [options]")
|
320
|
+
build_option_type_options(opts, options, update_role_option_types)
|
319
321
|
build_common_options(opts, options, [:options, :json, :dry_run])
|
320
322
|
end
|
321
323
|
optparse.parse!(args)
|
data/lib/morpheus/cli/shell.rb
CHANGED
@@ -13,8 +13,10 @@ require 'morpheus/cli/error_handler'
|
|
13
13
|
class Morpheus::Cli::Shell
|
14
14
|
include Morpheus::Cli::CliCommand
|
15
15
|
|
16
|
+
@@instance = nil
|
17
|
+
|
16
18
|
def self.instance
|
17
|
-
@@instance
|
19
|
+
@@instance ||= self.new
|
18
20
|
end
|
19
21
|
|
20
22
|
def initialize()
|
@@ -58,12 +60,19 @@ class Morpheus::Cli::Shell
|
|
58
60
|
@command_options = {} # this is a way to curry options to all commands.. but meh
|
59
61
|
optparse = OptionParser.new do|opts|
|
60
62
|
opts.banner = usage
|
61
|
-
opts.on('
|
63
|
+
opts.on('--norc','--norc', "Do not read and execute the personal initialization script .morpheusrc") do
|
64
|
+
@norc = true
|
65
|
+
end
|
66
|
+
opts.on('-I','--insecure', "Allow for insecure HTTPS communication i.e. bad SSL certificate") do |val|
|
67
|
+
Morpheus::RestClient.enable_ssl_verification = false
|
68
|
+
end
|
69
|
+
opts.on('-C','--nocolor', "Disable ANSI coloring") do
|
62
70
|
@command_options[:nocolor] = true
|
63
71
|
Term::ANSIColor::coloring = false
|
64
72
|
end
|
65
73
|
opts.on('-V','--debug', "Print extra output for debugging. ") do |json|
|
66
74
|
Morpheus::Logging.set_log_level(Morpheus::Logging::Logger::DEBUG)
|
75
|
+
::RestClient.log = Morpheus::Logging.debug? ? STDOUT : nil
|
67
76
|
@command_options[:debug] = true
|
68
77
|
end
|
69
78
|
opts.on( '-h', '--help', "Prints this help" ) do
|
@@ -77,281 +86,326 @@ class Morpheus::Cli::Shell
|
|
77
86
|
@history_logger.info "shell started" if @history_logger
|
78
87
|
load_history_from_log_file()
|
79
88
|
|
80
|
-
exit = false
|
81
|
-
while !exit do
|
82
|
-
Readline.completion_append_character = " "
|
83
|
-
Readline.completion_proc = @auto_complete
|
84
|
-
Readline.basic_word_break_characters = ""
|
85
|
-
#Readline.basic_word_break_characters = "\t\n\"\‘`@$><=;|&{( "
|
86
|
-
input = Readline.readline("#{cyan}morpheus> #{reset}", true).to_s
|
87
|
-
input = input.strip
|
88
89
|
|
89
|
-
|
90
|
+
# execute startup script
|
91
|
+
if !@norc
|
92
|
+
if File.exists?(Morpheus::Cli::DotFile.morpheusrc_filename)
|
93
|
+
@history_logger.info("load source #{Morpheus::Cli::DotFile.morpheusrc_filename}") if @history_logger
|
94
|
+
Morpheus::Cli::DotFile.new(Morpheus::Cli::DotFile.morpheusrc_filename).execute()
|
90
95
|
end
|
91
96
|
end
|
92
97
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
#
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
unless input.strip.empty? || (["exit"].include?(input.strip)) || input.strip[0].to_s.chr == "!"
|
104
|
-
log_history_command(input.strip)
|
105
|
-
end
|
98
|
+
exit = false
|
99
|
+
while !exit do
|
100
|
+
Readline.completion_append_character = " "
|
101
|
+
Readline.completion_proc = @auto_complete
|
102
|
+
Readline.basic_word_break_characters = ""
|
103
|
+
#Readline.basic_word_break_characters = "\t\n\"\‘`@$><=;|&{( "
|
104
|
+
input = Readline.readline("#{cyan}morpheus> #{reset}", true).to_s
|
105
|
+
input = input.strip
|
106
|
+
|
107
|
+
execute_commands(input)
|
106
108
|
end
|
109
|
+
|
110
|
+
end
|
107
111
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
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
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
112
|
+
def execute_commands(input)
|
113
|
+
# split the command on unquoted semicolons.
|
114
|
+
# so you can run multiple commands at once! eg hosts list; instances list
|
115
|
+
# all_commands = input.gsub(/(\;)(?=(?:[^"]|"[^"]*")*$)/, '__CMDDELIM__').split('__CMDDELIM__').collect {|it| it.to_s.strip }.select {|it| !it.empty? }.compact
|
116
|
+
all_commands = input.gsub(/(\;)(?=(?:[^"']|"[^'"]*")*$)/, '__CMDDELIM__').split('__CMDDELIM__').collect {|it| it.to_s.strip }.select {|it| !it.empty? }.compact
|
117
|
+
#puts "executing #{all_commands.size} commands: #{all_commands}"
|
118
|
+
all_commands.each do |cmd|
|
119
|
+
execute_command(cmd)
|
120
|
+
end
|
121
|
+
# skip logging of exit and !cmd
|
122
|
+
unless input.strip.empty? || (["exit"].include?(input.strip)) || input.strip[0].to_s.chr == "!"
|
123
|
+
log_history_command(input.strip)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def execute_command(input)
|
128
|
+
#puts "shell execute_command(#{input})"
|
129
|
+
@command_options = {}
|
130
|
+
|
131
|
+
input = input.to_s.strip
|
132
|
+
|
133
|
+
# print cyan,"morpheus > ",reset
|
134
|
+
# input = $stdin.gets.chomp!
|
135
|
+
if !input.empty?
|
136
|
+
|
137
|
+
if input == 'exit'
|
138
|
+
#print cyan,"Goodbye\n",reset
|
139
|
+
@history_logger.info "exit" if @history_logger
|
140
|
+
exit 0
|
141
|
+
elsif input == 'help'
|
142
|
+
|
143
|
+
puts "You are in a morpheus client shell."
|
144
|
+
puts "See the available commands below."
|
145
|
+
|
146
|
+
|
147
|
+
puts "\nCommands:"
|
148
|
+
# commands = @morpheus_commands + @shell_commands
|
149
|
+
@morpheus_commands.sort.each {|cmd|
|
150
|
+
puts "\t#{cmd.to_s}"
|
151
|
+
}
|
152
|
+
puts "\n"
|
153
|
+
puts "\nShell Commands:"
|
154
|
+
@shell_commands.each {|cmd|
|
155
|
+
puts "\t#{cmd.to_s}"
|
156
|
+
}
|
157
|
+
puts "\n"
|
158
|
+
puts "For more information."
|
159
|
+
puts "See https://github.com/gomorpheus/morpheus-cli/wiki"
|
160
|
+
print "\n"
|
161
|
+
return 0
|
162
|
+
elsif input =~ /^history/
|
163
|
+
n_commands = input.sub(/^history\s?/, '').sub(/\-n\s?/, '')
|
164
|
+
n_commands = n_commands.empty? ? 25 : n_commands.to_i
|
165
|
+
cmd_numbers = @history.keys.last(n_commands)
|
166
|
+
puts "Last #{cmd_numbers.size} commands"
|
167
|
+
cmd_numbers.each do |cmd_number|
|
168
|
+
cmd = @history[cmd_number]
|
169
|
+
puts "#{cmd_number.to_s.rjust(3, ' ')} #{cmd}"
|
170
|
+
end
|
171
|
+
return 0
|
172
|
+
elsif input == 'clear'
|
173
|
+
print "\e[H\e[2J"
|
174
|
+
return 0
|
175
|
+
elsif input == 'flush-history' || input == 'flush_history'
|
176
|
+
file_path = history_file_path
|
177
|
+
if File.exists?(file_path)
|
178
|
+
File.truncate(file_path, 0)
|
179
|
+
end
|
180
|
+
@history = {}
|
181
|
+
@last_command_number = 0
|
182
|
+
@history_logger = load_history_logger
|
183
|
+
puts "history cleared!"
|
184
|
+
return 0
|
185
|
+
elsif input == 'reload' || input == 'reload!'
|
186
|
+
#log_history_command(input)
|
187
|
+
# could just fork instead?
|
188
|
+
Morpheus::Cli.load!
|
189
|
+
# initialize()
|
190
|
+
# gotta reload appliance, groups, credentials
|
191
|
+
@appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
192
|
+
recalculate_auto_complete_commands()
|
193
|
+
# execute startup script
|
194
|
+
# if File.exists?(Morpheus::Cli::DotFile.morpheusrc_filename)
|
195
|
+
# Morpheus::Cli::DotFile.new(Morpheus::Cli::DotFile.morpheusrc_filename).execute()
|
196
|
+
# end
|
197
|
+
begin
|
198
|
+
load __FILE__
|
199
|
+
rescue => err
|
200
|
+
print "failed to reload #{__FILE__}. oh well"
|
201
|
+
# print err
|
202
|
+
end
|
203
|
+
print dark," #=> shell has been reloaded",reset,"\n" if Morpheus::Logging.debug?
|
204
|
+
return 0
|
205
|
+
elsif input == '!!'
|
206
|
+
cmd_number = @history.keys[-1]
|
207
|
+
input = @history[cmd_number]
|
208
|
+
if !input
|
209
|
+
puts "There is no previous command"
|
210
|
+
return 1
|
211
|
+
end
|
212
|
+
execute_commands(input)
|
213
|
+
elsif input =~ /^\!.+/
|
214
|
+
cmd_number = input.sub("!", "").to_i
|
215
|
+
if cmd_number != 0
|
185
216
|
input = @history[cmd_number]
|
186
217
|
if !input
|
187
|
-
puts "
|
188
|
-
return 1
|
189
|
-
end
|
190
|
-
execute_commands(input)
|
191
|
-
elsif input =~ /^\!.+/
|
192
|
-
cmd_number = input.sub("!", "").to_i
|
193
|
-
if cmd_number != 0
|
194
|
-
input = @history[cmd_number]
|
195
|
-
if !input
|
196
|
-
puts "Command not found by number #{cmd_number}"
|
197
|
-
return 0
|
198
|
-
end
|
199
|
-
#puts "executing history command: (#{cmd_number}) #{input}"
|
200
|
-
execute_commands(input)
|
218
|
+
puts "Command not found by number #{cmd_number}"
|
201
219
|
return 0
|
202
220
|
end
|
203
|
-
|
204
|
-
|
205
|
-
if log_level == ""
|
206
|
-
puts "#{Morpheus::Logging.log_level}"
|
207
|
-
elsif log_level == "debug"
|
208
|
-
#log_history_command(input)
|
209
|
-
@command_options[:debug] = true
|
210
|
-
Morpheus::Logging.set_log_level(Morpheus::Logging::Logger::DEBUG)
|
211
|
-
elsif log_level == "info"
|
212
|
-
#log_history_command(input)
|
213
|
-
@command_options.delete(:debug)
|
214
|
-
Morpheus::Logging.set_log_level(Morpheus::Logging::Logger::INFO)
|
215
|
-
elsif log_level.to_s == "0" || (log_level.to_i > 0 && log_level.to_i < 7)
|
216
|
-
# other log levels are pointless right now..
|
217
|
-
@command_options.delete(:debug)
|
218
|
-
Morpheus::Logging.set_log_level(log_level.to_i)
|
219
|
-
else
|
220
|
-
print_red_alert "unknown log level: #{log_level}"
|
221
|
-
end
|
222
|
-
return 0
|
223
|
-
# lots of hidden commands
|
224
|
-
elsif input == "debug"
|
225
|
-
@command_options[:debug] = true
|
226
|
-
Morpheus::Logging.set_log_level(Morpheus::Logging::Logger::DEBUG)
|
227
|
-
return 0
|
228
|
-
elsif ["hello","hi","hey","hola"].include?(input.strip.downcase)
|
229
|
-
print "#{input.capitalize}, how may I #{cyan}help#{reset} you?\n"
|
230
|
-
return
|
231
|
-
elsif input == "colorize"
|
232
|
-
Term::ANSIColor::coloring = true
|
233
|
-
@command_options[:nocolor] = false
|
234
|
-
return 0
|
235
|
-
elsif input == "uncolorize"
|
236
|
-
Term::ANSIColor::coloring = false
|
237
|
-
@command_options[:nocolor] = true
|
221
|
+
#puts "executing history command: (#{cmd_number}) #{input}"
|
222
|
+
execute_commands(input)
|
238
223
|
return 0
|
239
|
-
elsif input == "shell"
|
240
|
-
print "#{cyan}You are already in a shell.#{reset}\n"
|
241
|
-
return false
|
242
224
|
end
|
243
225
|
|
244
|
-
|
245
|
-
|
226
|
+
elsif input == "insecure"
|
227
|
+
Morpheus::RestClient.enable_ssl_verification = false
|
228
|
+
return 0
|
229
|
+
# use log-level [debug|info]
|
230
|
+
# elsif input =~ /^log_level/ # hidden for now
|
231
|
+
# log_level = input.sub(/^log_level\s*/, '').strip
|
232
|
+
# if log_level == ""
|
233
|
+
# puts "#{Morpheus::Logging.log_level}"
|
234
|
+
# elsif log_level == "debug"
|
235
|
+
# #log_history_command(input)
|
236
|
+
# @command_options[:debug] = true
|
237
|
+
# Morpheus::Logging.set_log_level(Morpheus::Logging::Logger::DEBUG)
|
238
|
+
# ::RestClient.log = Morpheus::Logging.debug? ? STDOUT : nil
|
239
|
+
# elsif log_level == "info"
|
240
|
+
# #log_history_command(input)
|
241
|
+
# @command_options.delete(:debug)
|
242
|
+
# Morpheus::Logging.set_log_level(Morpheus::Logging::Logger::INFO)
|
243
|
+
# ::RestClient.log = Morpheus::Logging.debug? ? STDOUT : nil
|
244
|
+
# elsif log_level.to_s == "0" || (log_level.to_i > 0 && log_level.to_i < 7)
|
245
|
+
# # other log levels are pointless right now..
|
246
|
+
# @command_options.delete(:debug)
|
247
|
+
# Morpheus::Logging.set_log_level(log_level.to_i)
|
248
|
+
# ::RestClient.log = Morpheus::Logging.debug? ? STDOUT : nil
|
249
|
+
# else
|
250
|
+
# print_red_alert "unknown log level: #{log_level}"
|
251
|
+
# end
|
252
|
+
# return 0
|
253
|
+
# # lots of hidden commands
|
254
|
+
# elsif input == "debug"
|
255
|
+
# @command_options[:debug] = true
|
256
|
+
# Morpheus::Logging.set_log_level(Morpheus::Logging::Logger::DEBUG)
|
257
|
+
# ::RestClient.log = Morpheus::Logging.debug? ? STDOUT : nil
|
258
|
+
# return 0
|
259
|
+
elsif ["hello","hi","hey","hola"].include?(input.strip.downcase)
|
260
|
+
print "#{input.capitalize}, how may I #{cyan}help#{reset} you?\n"
|
261
|
+
return
|
262
|
+
# use morpheus coloring [on|off]
|
263
|
+
# elsif input == "colorize"
|
264
|
+
# Term::ANSIColor::coloring = true
|
265
|
+
# @command_options[:nocolor] = false
|
266
|
+
# return 0
|
267
|
+
# elsif input == "uncolorize"
|
268
|
+
# Term::ANSIColor::coloring = false
|
269
|
+
# @command_options[:nocolor] = true
|
270
|
+
# return 0
|
271
|
+
elsif input == "shell"
|
272
|
+
print "#{cyan}You are already in a shell.#{reset}\n"
|
273
|
+
return false
|
274
|
+
# there is actually a Cli::SourceCommand !
|
275
|
+
# elsif input =~ /^source\s*/i
|
276
|
+
# source_file = input.sub(/^source\s*/i, '')
|
277
|
+
# # execute a source script
|
278
|
+
# if File.exists?(source_file)
|
279
|
+
# cmd_results = Morpheus::Cli::DotFile.new(source_file).execute()
|
280
|
+
# # return !cmd_results.include?(false)
|
281
|
+
# return true
|
282
|
+
# else
|
283
|
+
# print_red_alert "file not found: '#{source_file}'"
|
284
|
+
# return false
|
285
|
+
# end
|
286
|
+
# there is actually a Cli::EchoCommand !
|
287
|
+
# elsif input =~ /^echo\s*/i
|
288
|
+
# your_words = input.sub(/^echo\s*/i, '')
|
289
|
+
# print your_words.to_s + "\n"
|
290
|
+
# return true
|
291
|
+
end
|
246
292
|
|
293
|
+
begin
|
294
|
+
argv = Shellwords.shellsplit(input)
|
247
295
|
|
248
|
-
if Morpheus::Cli::CliRegistry.has_command?(argv[0]) || Morpheus::Cli::CliRegistry.has_alias?(argv[0])
|
249
|
-
#log_history_command(input)
|
250
|
-
Morpheus::Cli::CliRegistry.exec(argv[0], argv[1..-1])
|
251
|
-
else
|
252
|
-
print_yellow_warning "Unrecognized Command '#{argv[0]}'. Try 'help' to see a list of available commands."
|
253
|
-
@history_logger.warn "Unrecognized Command #{argv[0]}" if @history_logger
|
254
|
-
#puts optparse
|
255
|
-
end
|
256
|
-
# rescue ArgumentError
|
257
|
-
# puts "Argument Syntax Error..."
|
258
|
-
rescue Interrupt
|
259
|
-
# nothing to do
|
260
|
-
@history_logger.warn "shell interrupt" if @history_logger
|
261
|
-
print "\nInterrupt. aborting command '#{input}'\n"
|
262
|
-
rescue SystemExit
|
263
|
-
# nothing to do
|
264
|
-
# print "\n"
|
265
|
-
rescue => e
|
266
|
-
@history_logger.error "#{e.message}" if @history_logger
|
267
|
-
Morpheus::Cli::ErrorHandler.new.handle_error(e, @command_options)
|
268
|
-
# exit 1
|
269
|
-
end
|
270
296
|
|
271
|
-
if
|
272
|
-
|
273
|
-
|
297
|
+
if Morpheus::Cli::CliRegistry.has_command?(argv[0]) || Morpheus::Cli::CliRegistry.has_alias?(argv[0])
|
298
|
+
#log_history_command(input)
|
299
|
+
Morpheus::Cli::CliRegistry.exec(argv[0], argv[1..-1])
|
300
|
+
else
|
301
|
+
print_yellow_warning "Unrecognized Command '#{argv[0]}'. Try 'help' to see a list of available commands."
|
302
|
+
@history_logger.warn "Unrecognized Command #{argv[0]}" if @history_logger
|
303
|
+
#puts optparse
|
274
304
|
end
|
305
|
+
# rescue ArgumentError
|
306
|
+
# puts "Argument Syntax Error..."
|
307
|
+
rescue Interrupt
|
308
|
+
# nothing to do
|
309
|
+
@history_logger.warn "shell interrupt" if @history_logger
|
310
|
+
print "\nInterrupt. aborting command '#{input}'\n"
|
311
|
+
rescue SystemExit
|
312
|
+
# nothing to do
|
313
|
+
# print "\n"
|
314
|
+
rescue => e
|
315
|
+
@history_logger.error "#{e.message}" if @history_logger
|
316
|
+
Morpheus::Cli::ErrorHandler.new.handle_error(e, @command_options)
|
317
|
+
# exit 1
|
318
|
+
end
|
275
319
|
|
320
|
+
if @return_to_log_level
|
321
|
+
Morpheus::Logging.set_log_level(@return_to_log_level)
|
322
|
+
::RestClient.log = Morpheus::Logging.debug? ? STDOUT : nil
|
323
|
+
@return_to_log_level = nil
|
276
324
|
end
|
277
325
|
|
278
326
|
end
|
279
327
|
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
input << char
|
328
|
+
end
|
329
|
+
|
330
|
+
def get_prompt
|
331
|
+
input = ''
|
332
|
+
while char=$stdin.getch do
|
333
|
+
if char == '\n'
|
334
|
+
print "\r\n"
|
335
|
+
puts "executing..."
|
336
|
+
break
|
290
337
|
end
|
291
|
-
|
338
|
+
print char
|
339
|
+
input << char
|
292
340
|
end
|
341
|
+
return input
|
342
|
+
end
|
293
343
|
|
294
|
-
|
295
|
-
|
296
|
-
|
344
|
+
def history_file_path
|
345
|
+
File.join(Morpheus::Cli.home_directory, "shell_history")
|
346
|
+
end
|
297
347
|
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
# end
|
307
|
-
return logger
|
348
|
+
def load_history_logger
|
349
|
+
file_path = history_file_path
|
350
|
+
if !Dir.exists?(File.dirname(file_path))
|
351
|
+
FileUtils.mkdir_p(File.dirname(file_path))
|
352
|
+
end
|
353
|
+
if !File.exists?(file_path)
|
354
|
+
FileUtils.touch(file_path)
|
355
|
+
FileUtils.chmod(0600, file_path)
|
308
356
|
end
|
357
|
+
logger = Logger.new(file_path)
|
358
|
+
# logger.formatter = proc do |severity, datetime, progname, msg|
|
359
|
+
# "#{msg}\n"
|
360
|
+
# end
|
361
|
+
return logger
|
362
|
+
end
|
309
363
|
|
310
|
-
|
311
|
-
|
312
|
-
|
364
|
+
def load_history_from_log_file(n_commands=1000)
|
365
|
+
@history ||= {}
|
366
|
+
@last_command_number ||= 0
|
313
367
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
end
|
368
|
+
begin
|
369
|
+
if Gem.win_platform?
|
370
|
+
return @history
|
371
|
+
end
|
372
|
+
file_path = history_file_path
|
373
|
+
FileUtils.mkdir_p(File.dirname(file_path))
|
374
|
+
# grab extra lines because not all log entries are commands
|
375
|
+
n_lines = n_commands + 500
|
376
|
+
history_lines = `tail -n #{n_lines} #{file_path}`.split(/\n/)
|
377
|
+
command_lines = history_lines.select do |line|
|
378
|
+
line.match(/\(cmd (\d+)\) (.+)/)
|
379
|
+
end
|
380
|
+
command_lines = command_lines.last(n_commands)
|
381
|
+
command_lines.each do |line|
|
382
|
+
matches = line.match(/\(cmd (\d+)\) (.+)/)
|
383
|
+
if matches && matches.size == 3
|
384
|
+
cmd_number = matches[1].to_i
|
385
|
+
cmd = matches[2]
|
386
|
+
|
387
|
+
@last_command_number = cmd_number
|
388
|
+
@history[@last_command_number] = cmd
|
389
|
+
|
390
|
+
# for Ctrl+R history searching
|
391
|
+
Readline::HISTORY << cmd
|
339
392
|
end
|
340
|
-
rescue => e
|
341
|
-
# raise e
|
342
|
-
# puts "failed to load history from log"
|
343
|
-
@history = {}
|
344
393
|
end
|
345
|
-
|
394
|
+
rescue => e
|
395
|
+
# raise e
|
396
|
+
# puts "failed to load history from log"
|
397
|
+
@history = {}
|
346
398
|
end
|
399
|
+
return @history
|
400
|
+
end
|
347
401
|
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
end
|
402
|
+
def log_history_command(cmd)
|
403
|
+
@history ||= {}
|
404
|
+
@last_command_number ||= 0
|
405
|
+
@last_command_number += 1
|
406
|
+
@history[@last_command_number] = cmd
|
407
|
+
if @history_logger
|
408
|
+
@history_logger.info "(cmd #{@last_command_number}) #{cmd}"
|
356
409
|
end
|
357
410
|
end
|
411
|
+
end
|