rhc 0.84.15 → 0.85.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|