rhc 0.84.15 → 0.85.12

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -11,6 +11,7 @@ rescue LoadError
11
11
  rake_gempackage = true
12
12
  end
13
13
 
14
+ task(:default).clear
14
15
  task :default => [:package]
15
16
 
16
17
  # Create the gem specification for packaging
@@ -22,9 +23,9 @@ spec = Gem::Specification.new do |s|
22
23
  s.summary = %q{OpenShift Express Client Tools}
23
24
  s.homepage = %q{https://openshift.redhat.com/app/express}
24
25
  s.description = %q{The client tools for the OpenShift Express platform that allow for application management.}
25
- s.files = FileList['lib/**/*.rb', 'bin/*', 'conf/*'].to_a
26
+ s.files = FileList['lib/**/*.rb', 'lib/rhc', 'bin/*', 'conf/*'].to_a
26
27
  s.files += %w(LICENSE README Rakefile)
27
- s.executables = ['rhc-chk', 'rhc-create-app', 'rhc-create-domain', 'rhc-ctl-domain', 'rhc-ctl-app', 'rhc-snapshot', 'rhc-domain-info', 'rhc-user-info', 'rhc-tail-files']
28
+ s.executables = ['rhc', 'rhc-domain', 'rhc-app', 'rhc-sshkey', 'rhc-chk', 'rhc-create-app', 'rhc-create-domain', 'rhc-ctl-domain', 'rhc-ctl-app', 'rhc-snapshot', 'rhc-domain-info', 'rhc-user-info', 'rhc-tail-files', 'rhc-port-forward']
28
29
  begin
29
30
  # Use Ruby version to target F13, RHEL5, Windows and OSX (assume no Xcode)
30
31
  if ENV['JSON_PURE'] or (RUBY_VERSION == "1.8.6" or RUBY_PLATFORM =~ /mswin/ or RUBY_PLATFORM =~ /darwin/)
@@ -51,4 +52,4 @@ else
51
52
  end
52
53
 
53
54
  # Add the 'pkg' directory to the clean task
54
- CLEAN.include("pkg")
55
+ CLEAN.include("pkg")
data/bin/rhc ADDED
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person
5
+ # obtaining a copy of this software and associated documentation files
6
+ # (the "Software"), to deal in the Software without restriction,
7
+ # including without limitation the rights to use, copy, modify, merge,
8
+ # publish, distribute, sublicense, and/or sell copies of the Software,
9
+ # and to permit persons to whom the Software is furnished to do so,
10
+ # subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19
+ # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20
+ # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # SOFTWARE.
23
+
24
+
25
+ #
26
+ # print help
27
+ #
28
+ def p_usage
29
+ puts <<USAGE
30
+
31
+ Usage: rhc (<resource> | --help) [<command>] [<args>]
32
+ Command line tool for performing operations related to your rhcloud account.
33
+
34
+ List of resources
35
+ domain Manage the namespace for the registered rhcloud user.
36
+ app Manage applications within the rhcloud account.
37
+ sshkey Manage multiple keys for the registered rhcloud user.
38
+
39
+ See 'rhc <resource> --help' for more applicable commands and argumments on a specific resource.
40
+
41
+ USAGE
42
+ exit 255
43
+ end
44
+
45
+
46
+ def get_args
47
+ ARGV.shift
48
+ args = ""
49
+ ARGV.each do|a|
50
+ if ( a.to_s.strip.length == 0 || a.to_s.strip.match(/\s/) ); a = "'#{a}'" end
51
+ args += " #{a}"
52
+ end
53
+ args
54
+ end
55
+
56
+ case ARGV[0]
57
+ when "domain"
58
+ system("rhc-domain #{get_args} 2>&1")
59
+ when "app"
60
+ system("rhc-app #{get_args} 2>&1")
61
+ when "sshkey"
62
+ system("rhc-sshkey #{get_args} 2>&1")
63
+ when "-h", "--help", "help", nil
64
+ p_usage
65
+ else
66
+ puts "Invalid rhc command: #{ARGV[0]}"
67
+ p_usage
68
+ end
69
+
70
+ exit 0
@@ -0,0 +1,602 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person
5
+ # obtaining a copy of this software and associated documentation files
6
+ # (the "Software"), to deal in the Software without restriction,
7
+ # including without limitation the rights to use, copy, modify, merge,
8
+ # publish, distribute, sublicense, and/or sell copies of the Software,
9
+ # and to permit persons to whom the Software is furnished to do so,
10
+ # subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19
+ # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20
+ # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # SOFTWARE.
23
+
24
+
25
+ require 'rhc-common'
26
+ require 'base64'
27
+
28
+ $embed_mapper = { 'add' => 'configure', 'remove' => 'deconfigure' }
29
+
30
+ #
31
+ # print help
32
+ #
33
+ def p_usage
34
+ libra_server = get_var('libra_server')
35
+ rhlogin = get_var('default_rhlogin') ? "Default: #{get_var('default_rhlogin')}" : "required"
36
+ type_keys = RHC::get_cartridge_listing(nil, ', ', libra_server, @http, 'standalone', false)
37
+ puts <<USAGE
38
+
39
+ Usage: rhc app (<command> | cartridge <cartridge-action> | --help) [<args>]
40
+ Create and manage an OpenShift Express application.
41
+
42
+ List of commands
43
+ create Bind a registered rhcloud user to a domain in rhcloud.
44
+ show Display information about a user
45
+ start Starts the application (includes embedded)
46
+ stop Stops the application (includes embedded)
47
+ force-stop Stops all application processes
48
+ restart Restart the application
49
+ reload Reloads application configuration
50
+ status Returns application status
51
+ destroy Destroys the application
52
+ tidy Garbage collects the git repo and empties log/tmp dirs
53
+ add-alias Add a custom domain name for the application
54
+ remove-alias Remove a custom domain name for the application
55
+ threaddump Trigger a thread dump for jbossas applications
56
+ tail Tail the logs of an application
57
+ snapshot [save|restore] Saves/Restores an application snapshot to/from a tarball at the location specified using --filepath (default: ./$APPNAME.tar.gz)
58
+ cartridge <action> Manage an embedded cartridge
59
+
60
+ List of cartridge actions
61
+ list List of supported embedded cartridges
62
+ add Add an embedded application
63
+ remove Remove an embedded application
64
+ stop Stop the embedded application
65
+ start Start the embedded application
66
+ restart Restart the embedded application
67
+ status Returns embedded application status
68
+ reload Reloads embedded application configuration
69
+
70
+ List of arguments
71
+ -l|--rhlogin rhlogin Red Hat login (RHN or OpenShift login with OpenShift Express access) (#{rhlogin})
72
+ -p|--password password RHLogin password (optional, will prompt)
73
+ -a|--app application Application name (alphanumeric - max #{RHC::APP_NAME_MAX_LENGTH} chars) (required)
74
+ -t|--type type Type of app to create (#{type_keys}) (required for creating an application)
75
+ -c|--cartridge cartridge The embedded cartrige to manage (required for the cartridge command)
76
+ -r|--repo path Git Repo path (defaults to ./$app_name)
77
+ -n|--nogit Only create remote space, don't pull it locally
78
+ --no-dns Skip DNS check. Must be used in combination with --nogit
79
+ -d|--debug Print Debug info
80
+ -h|--help Show Usage info
81
+ -b|--bypass Bypass warnings (applicable to application destroying only)
82
+ -f|--filepath filepath Applicable in case of snapshot and log command
83
+ -o|--opts options Options to pass to the server-side (linux based) tail command (applicable to tail command only) (-f is implicit. See the linux tail man page full list of options.) (Ex: --opts '-n 100')
84
+ --alias alias Specify server alias (when using add/remove-alias)
85
+ --config path Path of alternate config file
86
+ --timeout # Timeout, in seconds, for connection
87
+ --enable-jenkins [name] Indicates to create a Jenkins application (if not already available)
88
+ and embed the Jenkins client into this application. The default
89
+ name will be 'jenkins' if not specified. Note that --no-dns is ignored
90
+ for the creation of the Jenkins application.
91
+ USAGE
92
+ exit 255
93
+ end
94
+
95
+
96
+ def validate_args(val_type=true, val_cartridge=false, val_timeout=true)
97
+ # If provided a config path, check it
98
+ check_cpath($opt)
99
+
100
+ # Pull in configs from files
101
+ $libra_server = get_var('libra_server')
102
+ debug = get_var('debug') == 'false' ? nil : get_var('debug')
103
+
104
+ $opt['rhlogin'] = get_var('default_rhlogin') unless $opt['rhlogin']
105
+ p_usage if !RHC::check_rhlogin($opt['rhlogin'])
106
+
107
+ p_usage if !RHC::check_app($opt['app'])
108
+
109
+ if val_type && !$opt['type']
110
+ puts "Application Type is required"
111
+ p_usage
112
+ end
113
+
114
+ if val_cartridge && !$opt['cartridge']
115
+ puts "Cartridge name is required"
116
+ p_usage
117
+ end
118
+
119
+ debug = $opt["debug"] ? true : false
120
+ RHC::debug(debug)
121
+
122
+ RHC::timeout($opt["timeout"] ? $opt["timeout"] : get_var('timeout')) if val_timeout
123
+
124
+ $password = $opt['password'] ? $opt['password'] : RHC::get_password
125
+ end
126
+
127
+ def create_app
128
+ validate_args
129
+
130
+ user_info = RHC::get_user_info($libra_server, $opt['rhlogin'], $password, @http, false)
131
+ app_info = user_info['app_info']
132
+
133
+ if app_info[$opt['app']]
134
+ puts "An application named '#{$opt['app']}' in namespace '#{user_info['user_info']['namespace']}' already exists"
135
+ exit 255
136
+ end
137
+
138
+ jenkins_app_name = nil
139
+ has_jenkins = false
140
+ if $opt['enable-jenkins']
141
+ app_info.each do |app_name, app|
142
+ if app['framework'] == 'jenkins-1.4'
143
+ jenkins_app_name = app_name
144
+ has_jenkins = true
145
+ puts "
146
+ Found existing Jenkins application: #{jenkins_app_name}
147
+ "
148
+ if !$opt['enable-jenkins'].empty?
149
+ puts "Ignoring specified Jenkins app name: #{$opt['enable-jenkins']}"
150
+ end
151
+ end
152
+ end
153
+ if !has_jenkins
154
+ if $opt['type'] =~ /^jenkins-/
155
+ has_jenkins = true
156
+ if $opt['no-dns']
157
+ puts "
158
+ The --no-dns option can't be used in conjunction with --enable-jenkins
159
+ when creating a #{$opt['type']} application. Either remove the --no-dns
160
+ option or first install your #{$opt['type']} application with --no-dns
161
+ and then use 'rhc app cartridge add' to embed the Jenkins client.
162
+ "
163
+ exit 255
164
+ end
165
+ jenkins_app_name = $opt['app']
166
+ puts "
167
+ The Jenkins client will be embedded into the Jenkins application
168
+ currently being created: '#{$opt['app']}'
169
+ "
170
+ end
171
+ end
172
+ if !has_jenkins
173
+ if !$opt['enable-jenkins'].empty?
174
+ jenkins_app_name = $opt['enable-jenkins']
175
+ else
176
+ jenkins_app_name = 'jenkins'
177
+ end
178
+
179
+ if !RHC::check_app(jenkins_app_name)
180
+ p_usage
181
+ end
182
+
183
+ if jenkins_app_name == $opt['app']
184
+ puts "You must specify a different name for your application and Jenkins ('#{$opt['app']}')."
185
+ exit 100
186
+ end
187
+
188
+ if app_info.has_key?(jenkins_app_name)
189
+ puts "You already have an application named '#{jenkins_app_name}'."
190
+ puts "In order to continue you'll need to specify a different name"
191
+ puts "with --enable-jenkins or destroy the existing application."
192
+ exit 100
193
+ end
194
+ end
195
+ end
196
+
197
+ $opt['repo'] = $opt['app'] unless $opt['repo']
198
+
199
+ if @mydebug
200
+ puts "
201
+ Found a bug? Post to the forum and we'll get right on it.
202
+ IRC: #openshift on freenode
203
+ Forums: https://www.redhat.com/openshift/forums
204
+
205
+ "
206
+ end
207
+
208
+ #
209
+ # Confirm local git repo exists
210
+ #
211
+ unless $opt['nogit']
212
+ if File.exists?($opt['repo'])
213
+ puts "We will not overwrite an existing git repo. Please remove:"
214
+ puts " #{File.expand_path($opt['repo'])}"
215
+ puts "Then try again."
216
+ puts
217
+ exit 210
218
+ else
219
+ begin
220
+ # Create the parent directory for the git repo
221
+ @git_parent = File.expand_path($opt['repo'] + "/../")
222
+ FileUtils.mkdir_p(@git_parent)
223
+ rescue Exception => e
224
+ puts "Could not write to #{@git_parent}"
225
+ puts "Reason: #{e.message}"
226
+ puts
227
+ puts "Please re-run from a directory you have write access to or specify -r with a"
228
+ puts "path you have write access to"
229
+ puts
230
+ exit 211
231
+ end
232
+ end
233
+ end
234
+
235
+ if jenkins_app_name && !has_jenkins
236
+ jenkins_app = RHC::create_app($libra_server, @http, user_info, jenkins_app_name, 'jenkins-1.4', $opt['rhlogin'], $password, nil, false, true, true)
237
+ available = RHC::check_app_available(@http, jenkins_app[:app_name], jenkins_app[:fqdn], jenkins_app[:health_check_path], jenkins_app[:result], jenkins_app[:git_url], nil, true)
238
+ if !available
239
+ puts "Unable to access your new Jenkins application."
240
+ exit 1
241
+ end
242
+ end
243
+
244
+ #
245
+ # Create remote application space
246
+ #
247
+ main_app = RHC::create_app($libra_server, @http, user_info, $opt['app'], $opt['type'], $opt['rhlogin'], $password, $opt['repo'], $opt['no-dns'], $opt['nogit'], false)
248
+ if jenkins_app_name
249
+ puts "Now embedding the jenkins client into '#{$opt['app']}'..."
250
+ RHC::ctl_app($libra_server, @http, $opt['app'], $opt['rhlogin'], $password, 'configure', true, 'jenkins-client-1.4', nil, false)
251
+ end
252
+
253
+ unless $opt['no-dns']
254
+ available = RHC::check_app_available(@http, main_app[:app_name], main_app[:fqdn], main_app[:health_check_path], main_app[:result], main_app[:git_url], $opt['repo'], $opt['nogit'])
255
+ if !available
256
+ puts "Unable to access your new application."
257
+ exit 1
258
+ end
259
+ end
260
+
261
+ end
262
+
263
+ def show_app
264
+ validate_args(false)
265
+ user_info = RHC::get_user_info($libra_server, $opt['rhlogin'], $password, @http, true)
266
+
267
+ app_found = false
268
+ unless user_info['app_info'].empty?
269
+ user_info['app_info'].each do |key, val|
270
+ if key == $opt['app']
271
+ app_found = true
272
+ puts ""
273
+ puts "Application Info"
274
+ puts "================"
275
+ puts key
276
+ puts " Framework: #{val['framework']}"
277
+ puts " Creation: #{val['creation_time']}"
278
+ puts " UUID: #{val['uuid']}"
279
+ puts " Git URL: ssh://#{val['uuid']}@#{key}-#{user_info['user_info']['namespace']}.#{user_info['user_info']['rhc_domain']}/~/git/#{key}.git/"
280
+ puts " Public URL: http://#{key}-#{user_info['user_info']['namespace']}.#{user_info['user_info']['rhc_domain']}/"
281
+ if val['aliases'] && !val['aliases'].empty?
282
+ puts " Aliases: #{val['aliases'].join(', ')}"
283
+ end
284
+ puts ""
285
+ puts " Embedded: "
286
+ if val['embedded'] && !val['embedded'].empty?
287
+ val['embedded'].each do |embed_key, embed_val|
288
+ if embed_val.has_key?('info') && !embed_val['info'].empty?
289
+ puts " #{embed_key} - #{embed_val['info']}"
290
+ else
291
+ puts " #{embed_key}"
292
+ end
293
+ end
294
+ else
295
+ puts " None"
296
+ end
297
+ puts ""
298
+
299
+ # there should be a single application with the given app name
300
+ break
301
+
302
+ end
303
+ end
304
+ end
305
+
306
+ if !app_found
307
+ puts
308
+ puts "Could not find app '#{$opt['app']}'. Please run 'rhc domain show' to get a list"
309
+ puts "of your current running applications"
310
+ puts
311
+ end
312
+
313
+ end
314
+
315
+ def control_app(command)
316
+ validate_args(false)
317
+
318
+ if ($opt['alias'] and !(command =~ /-alias$/)) || (command =~ /-alias$/ and ! $opt['alias'])
319
+ puts "When specifying alias make sure to use add-alias or remove-alias command"
320
+ p_usage
321
+ end
322
+
323
+ command = "deconfigure" if command == "destroy"
324
+
325
+ if !$opt["bypass"] and command == "deconfigure"
326
+ # deconfigure is the actual hook called on 'destroy'
327
+ # destroy is used for clarity
328
+ puts <<WARNING
329
+ !!!! WARNING !!!! WARNING !!!! WARNING !!!!
330
+ You are about to destroy the #{$opt['app']} application.
331
+
332
+ This is NOT reversible, all remote data for this application will be removed.
333
+ WARNING
334
+
335
+ print "Do you want to destroy this application (y/n): "
336
+ begin
337
+ agree = gets.chomp
338
+ if agree != 'y'
339
+ puts "\n"
340
+ exit 217
341
+ end
342
+ rescue Interrupt
343
+ puts "\n"
344
+ exit 217
345
+ end
346
+ end
347
+
348
+ RHC::ctl_app($libra_server, @http, $opt['app'], $opt['rhlogin'], $password, command, false, nil, $opt['alias'])
349
+ end
350
+
351
+ def control_cartridge(command)
352
+ validate_args(false, true)
353
+
354
+ # override command if it's in the mapper
355
+ command = $embed_mapper[command] if $embed_mapper[command]
356
+ framework = $opt['cartridge']
357
+
358
+ RHC::ctl_app($libra_server, @http, $opt['app'], $opt['rhlogin'], $password, command, true, framework, $opt['alias'])
359
+ end
360
+
361
+ def show_embedded_list
362
+ libra_server = get_var('libra_server')
363
+ puts ""
364
+ puts "List of supported embedded cartridges:"
365
+ puts ""
366
+ type_keys = RHC::get_cartridge_listing(nil, ', ', libra_server, @http, 'embedded', false)
367
+ puts type_keys
368
+ puts ""
369
+ exit 255
370
+ end
371
+
372
+ def save_or_restore_snapshot(command)
373
+ validate_args(false, false, true)
374
+
375
+ user_info = RHC::get_user_info($libra_server, $opt['rhlogin'], $password, @http, @mydebug, false)
376
+
377
+ app = $opt['app']
378
+ $opt['filepath'] = "#{$opt['app']}.tar.gz" if command == 'save' and not $opt['filepath']
379
+
380
+ unless user_info['app_info'][app]
381
+ puts
382
+ puts "Could not find app '#{app}'. Please run 'rhc domain show' to get a list"
383
+ puts "of your current running applications"
384
+ puts
385
+ exit 101
386
+ end
387
+
388
+ app_uuid = user_info['app_info'][app]['uuid']
389
+ namespace = user_info['user_info']['namespace']
390
+ rhc_domain = user_info['user_info']['rhc_domain']
391
+ if command == 'save'
392
+ ssh_cmd = "ssh #{app_uuid}@#{app}-#{namespace}.#{rhc_domain} 'snapshot' > #{$opt['filepath']}"
393
+ puts "Pulling down a snapshot to #{$opt['filepath']}"
394
+ else
395
+ if File.exists? $opt['filepath']
396
+ `tar -tf #{$opt['filepath']} './*/#{app}'`
397
+ if $?.exitstatus != 0
398
+ puts "Archive at #{$opt['filepath']} does not contain the target application: ./*/#{app}"
399
+ puts "If you created this archive rather than exported with 'rhc app snapshot', be sure"
400
+ puts "the directory structure inside the archive starts with ./<app_uuid>/"
401
+ puts "i.e.: tar -czvf <app_name>.tar.gz ./<app_uuid>/"
402
+ exit 255
403
+ else
404
+ `tar -tf #{$opt['filepath']} './*/git'`
405
+ include_git = $?.exitstatus == 0
406
+ ssh_cmd = "cat #{$opt['filepath']} | ssh #{app_uuid}@#{app}-#{namespace}.#{rhc_domain} 'restore#{include_git ? ' INCLUDE_GIT' : ''}'"
407
+ puts "Restoring from snapshot #{$opt['filepath']}"
408
+ end
409
+ else
410
+ puts "Archive not found: #{$opt['filepath']}"
411
+ exit 255
412
+ end
413
+ end
414
+
415
+ puts
416
+ puts ssh_cmd if @mydebug
417
+ output = `#{ssh_cmd}`
418
+ puts
419
+ if $?.exitstatus != 0
420
+ puts output
421
+ puts
422
+ if command == 'save'
423
+ puts "Error in trying to save snapshot. You can try to save manually by running:"
424
+ else
425
+ puts "Error in trying to restore application from snapshot. You can try to restore manually by running:"
426
+ end
427
+ puts
428
+ puts ssh_cmd
429
+ puts
430
+ exit 1
431
+ end
432
+ puts output if command == 'restore' && @mydebug
433
+ end
434
+
435
+ def show_logs
436
+ validate_args(false, false, true)
437
+
438
+ user_info = RHC::get_user_info($libra_server, $opt['rhlogin'], $password, @http, false)
439
+ app = $opt['app']
440
+
441
+ unless user_info['app_info'][app]
442
+ puts
443
+ puts "Could not find app '#{$opt['app']}'. Please run 'rhc domain show' to get a list"
444
+ puts "of your current running applications"
445
+ puts
446
+ exit 101
447
+ end
448
+
449
+ $opt['filepath'] = "#{$opt['app']}/logs/*" unless $opt['filepath']
450
+ file_glob = "#{$opt['filepath']}"
451
+ app_uuid = user_info['app_info'][app]['uuid']
452
+ namespace = user_info['user_info']['namespace']
453
+ rhc_domain = user_info['user_info']['rhc_domain']
454
+
455
+ # -t to force PTY and avoid daemons
456
+ # Red Hat Openshift: https://bugzilla.redhat.com/show_bug.cgi?id=726646
457
+ # OpenSSH https://bugzilla.mindrot.org/show_bug.cgi?id=396
458
+ ssh_cmd = "ssh -t #{app_uuid}@#{app}-#{namespace}.#{rhc_domain} 'tail#{$opt['opts'] ? ' --opts ' + Base64::encode64($opt['opts']).chomp : ''} #{file_glob}'"
459
+
460
+ puts "Attempting to tail files: #{file_glob}"
461
+ puts "Use ctl + c to stop"
462
+ puts
463
+ puts ssh_cmd if @mydebug
464
+ begin
465
+ exec ssh_cmd
466
+ rescue SystemCallError
467
+ puts
468
+ puts "Error in trying to tail files. You can tail manually by running:"
469
+ puts
470
+ puts ssh_cmd
471
+ puts
472
+ exit 1
473
+ end
474
+ # this should never happen
475
+ exit 1
476
+ end
477
+
478
+
479
+ begin
480
+ argv_c = ARGV.clone
481
+
482
+ if ARGV[0] =~ /^create$/
483
+ ARGV.shift
484
+ opts = GetoptLong.new(
485
+ ["--debug", "-d", GetoptLong::NO_ARGUMENT],
486
+ ["--help", "-h", GetoptLong::NO_ARGUMENT],
487
+ ["--rhlogin", "-l", GetoptLong::REQUIRED_ARGUMENT],
488
+ ["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
489
+ ["--no-dns", GetoptLong::NO_ARGUMENT],
490
+ ["--nogit", "-n", GetoptLong::NO_ARGUMENT],
491
+ ["--app", "-a", GetoptLong::REQUIRED_ARGUMENT],
492
+ ["--repo", "-r", GetoptLong::REQUIRED_ARGUMENT],
493
+ ["--type", "-t", GetoptLong::REQUIRED_ARGUMENT],
494
+ ["--enable-jenkins", GetoptLong::OPTIONAL_ARGUMENT],
495
+ ["--config", GetoptLong::REQUIRED_ARGUMENT],
496
+ ["--timeout", GetoptLong::REQUIRED_ARGUMENT]
497
+ )
498
+ elsif ARGV[0] =~ /^(show|start|stop|force-stop|restart|reload|status|destroy|tidy|add-alias|remove-alias|threaddump|destroy)$/
499
+ ARGV.shift
500
+ opts = GetoptLong.new(
501
+ ["--debug", "-d", GetoptLong::NO_ARGUMENT],
502
+ ["--help", "-h", GetoptLong::NO_ARGUMENT],
503
+ ["--rhlogin", "-l", GetoptLong::REQUIRED_ARGUMENT],
504
+ ["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
505
+ ["--app", "-a", GetoptLong::REQUIRED_ARGUMENT],
506
+ ["--alias", GetoptLong::REQUIRED_ARGUMENT],
507
+ ["--bypass", "-b", GetoptLong::NO_ARGUMENT],
508
+ ["--config", GetoptLong::REQUIRED_ARGUMENT],
509
+ ["--timeout", GetoptLong::REQUIRED_ARGUMENT]
510
+ )
511
+ elsif ARGV[0] =~ /^cartridge$/
512
+ ARGV.shift
513
+ ARGV.shift if ARGV[0] =~ /^(add|remove|stop|start|restart|status|reload|list)$/
514
+ opts = GetoptLong.new(
515
+ ["--debug", "-d", GetoptLong::NO_ARGUMENT],
516
+ ["--help", "-h", GetoptLong::NO_ARGUMENT],
517
+ ["--rhlogin", "-l", GetoptLong::REQUIRED_ARGUMENT],
518
+ ["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
519
+ ["--app", "-a", GetoptLong::REQUIRED_ARGUMENT],
520
+ ["--cartridge", "-c", GetoptLong::REQUIRED_ARGUMENT],
521
+ ["--config", GetoptLong::REQUIRED_ARGUMENT],
522
+ ["--timeout", GetoptLong::REQUIRED_ARGUMENT]
523
+ )
524
+ elsif ARGV[0] =~ /^tail$/
525
+ ARGV.shift
526
+ opts = GetoptLong.new(
527
+ ["--debug", "-d", GetoptLong::NO_ARGUMENT],
528
+ ["--help", "-h", GetoptLong::NO_ARGUMENT],
529
+ ["--rhlogin", "-l", GetoptLong::REQUIRED_ARGUMENT],
530
+ ["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
531
+ ["--app", "-a", GetoptLong::REQUIRED_ARGUMENT],
532
+ ["--opts", "-o", GetoptLong::REQUIRED_ARGUMENT],
533
+ ["--filepath", "-f", GetoptLong::REQUIRED_ARGUMENT],
534
+ ["--config", GetoptLong::REQUIRED_ARGUMENT],
535
+ ["--timeout", GetoptLong::REQUIRED_ARGUMENT]
536
+ )
537
+ elsif ARGV[0] =~ /^snapshot$/
538
+ ARGV.shift
539
+ ARGV.shift if ARGV[0] =~ /^(save|restore)$/
540
+ opts = GetoptLong.new(
541
+ ["--debug", "-d", GetoptLong::NO_ARGUMENT],
542
+ ["--help", "-h", GetoptLong::NO_ARGUMENT],
543
+ ["--rhlogin", "-l", GetoptLong::REQUIRED_ARGUMENT],
544
+ ["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
545
+ ["--app", "-a", GetoptLong::REQUIRED_ARGUMENT],
546
+ ["--filepath", "-f", GetoptLong::REQUIRED_ARGUMENT],
547
+ ["--config", GetoptLong::REQUIRED_ARGUMENT],
548
+ ["--timeout", GetoptLong::REQUIRED_ARGUMENT]
549
+ )
550
+ else
551
+ puts "Missing or invalid command!" unless ARGV[0] =~ /^(help|-h|--help)$/
552
+ # just exit at this point
553
+ # printing the usage description will be handled in the rescue
554
+ exit 255
555
+ end
556
+
557
+ $opt = {}
558
+ opts.each do |o, a|
559
+ $opt[o[2..-1]] = a.to_s
560
+ end
561
+
562
+ rescue Exception => e
563
+ p_usage
564
+ end
565
+
566
+ p_usage if $opt["help"]
567
+
568
+ case argv_c[0]
569
+ when "create"
570
+ create_app
571
+ when "show"
572
+ show_app
573
+ when "start", "stop", "force-stop", "restart", "reload", "status", "tidy", "add-alias", "remove-alias", "threaddump", "destroy"
574
+ control_app(argv_c[0])
575
+ when "tail"
576
+ show_logs
577
+ when "snapshot"
578
+ case argv_c[1]
579
+ when "save", "restore"
580
+ save_or_restore_snapshot(argv_c[1])
581
+ else
582
+ puts "Missing or invalid snapshot action!"
583
+ p_usage
584
+ end
585
+ when "cartridge"
586
+ case argv_c[1]
587
+ when "add", "remove", "start", "stop", "restart", "status", "reload"
588
+ control_cartridge(argv_c[1])
589
+ when "list", nil
590
+ show_embedded_list
591
+ else
592
+ puts "Missing or invalid cartridge action!"
593
+ p_usage
594
+ end
595
+ when "-h", "--help", "help", nil
596
+ p_usage
597
+ else
598
+ puts "Invalid command!"
599
+ p_usage
600
+ end
601
+
602
+ exit 0