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 +4 -3
- data/bin/rhc +70 -0
- data/bin/rhc-app +602 -0
- data/bin/rhc-chk +5 -5
- data/bin/rhc-create-app +1 -1
- data/bin/rhc-create-domain +6 -6
- data/bin/rhc-ctl-app +1 -1
- data/bin/rhc-ctl-domain +4 -4
- data/bin/rhc-domain +348 -0
- data/bin/rhc-domain-info +4 -4
- data/bin/rhc-port-forward +146 -0
- data/bin/rhc-snapshot +2 -2
- data/bin/rhc-sshkey +258 -0
- data/bin/rhc-tail-files +2 -2
- data/bin/rhc-user-info +4 -0
- data/lib/rhc +135 -0
- data/lib/rhc-common.rb +96 -9
- metadata +22 -11
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
|
data/bin/rhc-app
ADDED
@@ -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
|