rhc 0.68.5
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/LICENSE +21 -0
- data/README +41 -0
- data/Rakefile +32 -0
- data/bin/rhc-create-app +389 -0
- data/bin/rhc-create-domain +177 -0
- data/bin/rhc-ctl-app +157 -0
- data/bin/rhc-snapshot +119 -0
- data/bin/rhc-user-info +151 -0
- data/conf/express.conf +8 -0
- data/lib/rhc-common.rb +318 -0
- metadata +107 -0
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Copyright 2011 Red Hat, Inc.
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person
|
4
|
+
# obtaining a copy of this software and associated documentation files
|
5
|
+
# (the "Software"), to deal in the Software without restriction,
|
6
|
+
# including without limitation the rights to use, copy, modify, merge,
|
7
|
+
# publish, distribute, sublicense, and/or sell copies of the Software,
|
8
|
+
# and to permit persons to whom the Software is furnished to do so,
|
9
|
+
# subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
18
|
+
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
19
|
+
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
# SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
Openshift Express (RHC)
|
2
|
+
========
|
3
|
+
|
4
|
+
Please stop by #openshift on irc.freenode.net if you have any questions or
|
5
|
+
comments. Another good resource are the blogs and forums at
|
6
|
+
http://openshift.redhat.com
|
7
|
+
|
8
|
+
|
9
|
+
Quickstart
|
10
|
+
========
|
11
|
+
|
12
|
+
DEPENDENCIES: git
|
13
|
+
openssh-clients
|
14
|
+
ruby (1.8.7 or later)
|
15
|
+
rubygems
|
16
|
+
json gem
|
17
|
+
parseconfig gem
|
18
|
+
|
19
|
+
Step 1: Create an rhc domain:
|
20
|
+
|
21
|
+
$ ./rhc-create-domain -n desirednamespace -l rhlogin
|
22
|
+
|
23
|
+
Step 2: Create an rhc application:
|
24
|
+
|
25
|
+
$ ./rhc-create-app -l rhlogin -a appname -r /path/to/new/git/repo -t <framework Ex: php-5.3.2>
|
26
|
+
|
27
|
+
Once that's complete, follow the directions printed at the end of running
|
28
|
+
rhc-create-app
|
29
|
+
|
30
|
+
|
31
|
+
Updating your site
|
32
|
+
========
|
33
|
+
|
34
|
+
Once your site is created, updating it is as simple as making changes to your
|
35
|
+
git repo. Commit them, then push. For example:
|
36
|
+
|
37
|
+
$ edit index.php
|
38
|
+
$ git commit -a -m "what I did"
|
39
|
+
$ git push
|
40
|
+
|
41
|
+
Then just reload your web page to see the changes
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rake'
|
5
|
+
require 'rake/clean'
|
6
|
+
require 'rake/gempackagetask'
|
7
|
+
|
8
|
+
task :default => [:package]
|
9
|
+
|
10
|
+
# Create the gem specification for packaging
|
11
|
+
spec = Gem::Specification.new do |s|
|
12
|
+
s.name = %q{rhc}
|
13
|
+
s.version = /(Version: )(.*)/.match(File.read("../build/specs/rhc.spec"))[2]
|
14
|
+
s.author = "Red Hat"
|
15
|
+
s.email = %q{openshift@redhat.com}
|
16
|
+
s.summary = %q{OpenShift Express Client Tools}
|
17
|
+
s.homepage = %q{https://openshift.redhat.com/app/express}
|
18
|
+
s.description = %q{OpenShift Express Client Tools}
|
19
|
+
s.files = FileList['lib/**/*.rb', 'bin/*', 'conf/*'].to_a
|
20
|
+
s.files += %w(LICENSE README Rakefile)
|
21
|
+
s.executables = ['rhc-create-app', 'rhc-create-domain', 'rhc-ctl-app', 'rhc-snapshot', 'rhc-user-info']
|
22
|
+
s.add_dependency('json')
|
23
|
+
s.add_dependency('parseconfig')
|
24
|
+
end
|
25
|
+
|
26
|
+
# Define a :package task that bundles the gem
|
27
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
28
|
+
pkg.need_tar = false
|
29
|
+
end
|
30
|
+
|
31
|
+
# Add the 'pkg' directory to the clean task
|
32
|
+
CLEAN.include("pkg")
|
data/bin/rhc-create-app
ADDED
@@ -0,0 +1,389 @@
|
|
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
|
+
require 'rhc-common'
|
25
|
+
|
26
|
+
def p_usage
|
27
|
+
rhlogin = get_var('default_rhlogin') ? "Default: #{get_var('default_rhlogin')}" : "(required)"
|
28
|
+
type_keys = RHC::get_cartridge_types(', ')
|
29
|
+
puts <<USAGE
|
30
|
+
|
31
|
+
Usage: #{$0}
|
32
|
+
Create a new app Openshift Express project.
|
33
|
+
|
34
|
+
-a|--app application Application name (alphanumeric - max #{RHC::Maxdlen} chars) (required)
|
35
|
+
-t|--type type Type of app to create (#{type_keys}) (required)
|
36
|
+
-l|--rhlogin rhlogin RHCloud rhlogin (#{rhlogin})
|
37
|
+
-p|--password password RHLogin password (optional, will prompt)
|
38
|
+
-r|--repo path Git Repo path (defaults to ./$app_name)
|
39
|
+
-n|--nogit Only create remote space, don't pull it locally
|
40
|
+
-d|--debug Print Debug info
|
41
|
+
-h|--help Show Usage info
|
42
|
+
|
43
|
+
USAGE
|
44
|
+
exit 255
|
45
|
+
end
|
46
|
+
|
47
|
+
begin
|
48
|
+
opts = GetoptLong.new(
|
49
|
+
["--debug", "-d", GetoptLong::NO_ARGUMENT],
|
50
|
+
["--help", "-h", GetoptLong::NO_ARGUMENT],
|
51
|
+
["--nogit", "-n", GetoptLong::NO_ARGUMENT],
|
52
|
+
["--rhlogin", "-l", GetoptLong::OPTIONAL_ARGUMENT],
|
53
|
+
["--password", "-p", GetoptLong::OPTIONAL_ARGUMENT],
|
54
|
+
["--app", "-a", GetoptLong::REQUIRED_ARGUMENT],
|
55
|
+
["--repo", "-r", GetoptLong::OPTIONAL_ARGUMENT],
|
56
|
+
["--type", "-t", GetoptLong::REQUIRED_ARGUMENT]
|
57
|
+
)
|
58
|
+
opt = {}
|
59
|
+
opts.each do |o, a|
|
60
|
+
opt[o[2..-1]] = a.to_s
|
61
|
+
end
|
62
|
+
rescue Exception => e
|
63
|
+
#puts e.message
|
64
|
+
p_usage
|
65
|
+
end
|
66
|
+
|
67
|
+
# Pull in configs from files
|
68
|
+
libra_domain = get_var('libra_domain')
|
69
|
+
libra_server = get_var('libra_server')
|
70
|
+
debug = get_var('debug') == 'false' ? nil : get_var('debug')
|
71
|
+
|
72
|
+
ssh_config = "#{ENV['HOME']}/.ssh/config"
|
73
|
+
ssh_config_d = "#{ENV['HOME']}/.ssh/"
|
74
|
+
|
75
|
+
if opt["help"]
|
76
|
+
p_usage
|
77
|
+
end
|
78
|
+
|
79
|
+
if opt["debug"]
|
80
|
+
debug = true
|
81
|
+
end
|
82
|
+
|
83
|
+
opt["rhlogin"] = get_var('default_rhlogin') unless opt["rhlogin"]
|
84
|
+
|
85
|
+
if !RHC::check_rhlogin(opt['rhlogin'])
|
86
|
+
p_usage
|
87
|
+
end
|
88
|
+
|
89
|
+
if !RHC::check_app(opt['app'])
|
90
|
+
p_usage
|
91
|
+
end
|
92
|
+
|
93
|
+
type = RHC::get_cartridge(opt['type'])
|
94
|
+
if !type
|
95
|
+
p_usage
|
96
|
+
end
|
97
|
+
|
98
|
+
if !opt["rhlogin"] || !opt["app"] || !opt["type"]
|
99
|
+
p_usage
|
100
|
+
end
|
101
|
+
|
102
|
+
password = opt['password']
|
103
|
+
if !password
|
104
|
+
password = RHC::get_password
|
105
|
+
end
|
106
|
+
|
107
|
+
#
|
108
|
+
# Get UUID from file
|
109
|
+
#
|
110
|
+
|
111
|
+
uuid = get_var(opt["rhlogin"])
|
112
|
+
unless uuid
|
113
|
+
puts "Could not find UUID for #{opt["rhlogin"]}"
|
114
|
+
exit 99
|
115
|
+
end
|
116
|
+
|
117
|
+
opt["repo"] = opt["app"] unless opt["repo"]
|
118
|
+
|
119
|
+
puts ""
|
120
|
+
puts "Please support the developer preview - let #openshift on freenode know of any"
|
121
|
+
puts "bugs you find"
|
122
|
+
puts ""
|
123
|
+
|
124
|
+
#
|
125
|
+
# Confirm local git repo exists
|
126
|
+
#
|
127
|
+
unless opt['nogit']
|
128
|
+
if File.exists?(opt['repo'])
|
129
|
+
puts "We will not overwrite an existing git repo. Please remove:"
|
130
|
+
puts " #{File.expand_path(opt['repo'])}"
|
131
|
+
puts "Then try again."
|
132
|
+
puts
|
133
|
+
exit 210
|
134
|
+
else
|
135
|
+
begin
|
136
|
+
# Create the parent directory for the git repo
|
137
|
+
@git_parent = File.expand_path(opt['repo'] + "/../")
|
138
|
+
FileUtils.mkdir_p(@git_parent)
|
139
|
+
rescue Errno::EACCES
|
140
|
+
puts "Could not write to #{@git_parent}"
|
141
|
+
puts "Reason: " + $!
|
142
|
+
puts
|
143
|
+
puts "Please re-run from a directory you have write access to or specify -r with a"
|
144
|
+
puts "path you have write access to"
|
145
|
+
puts
|
146
|
+
exit 211
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
#
|
152
|
+
# Confirm libra_id_rsa exists
|
153
|
+
#
|
154
|
+
unless File.exists?("#{ssh_config_d}/libra_id_rsa")
|
155
|
+
puts
|
156
|
+
puts "Could not find #{ssh_config_d}/libra_id_rsa, cannot continue"
|
157
|
+
puts "This file was created by rhc-create-domain. If it does not exist you may need to create"
|
158
|
+
puts "a new one."
|
159
|
+
puts
|
160
|
+
exit 212
|
161
|
+
end
|
162
|
+
|
163
|
+
#
|
164
|
+
# Create remote application space
|
165
|
+
#
|
166
|
+
|
167
|
+
puts "Creating remote application space: " + opt['app']
|
168
|
+
|
169
|
+
data = {:cartridge => opt['type'],
|
170
|
+
:action => 'configure',
|
171
|
+
:app_name => opt['app'],
|
172
|
+
:rhlogin => opt['rhlogin']
|
173
|
+
}
|
174
|
+
if debug
|
175
|
+
data['debug'] = "true"
|
176
|
+
end
|
177
|
+
json_data = JSON.generate(data)
|
178
|
+
|
179
|
+
puts "Contacting https://#{libra_server}"
|
180
|
+
|
181
|
+
url = URI.parse("https://#{libra_server}/app/broker/cartridge")
|
182
|
+
response = RHC::http_post(@http, url, json_data, password)
|
183
|
+
|
184
|
+
if response.code == '200'
|
185
|
+
RHC::print_response_success(response, debug, true)
|
186
|
+
else
|
187
|
+
RHC::print_response_err(response, debug)
|
188
|
+
end
|
189
|
+
|
190
|
+
#
|
191
|
+
# At this point, we need to register a handler to guarantee app
|
192
|
+
# cleanup on any exceptions or calls to exit
|
193
|
+
#
|
194
|
+
at_exit do
|
195
|
+
unless $!.nil? || $!.is_a?(SystemExit) && $!.success?
|
196
|
+
json_data = JSON.generate(
|
197
|
+
{:cartridge => opt['type'],
|
198
|
+
:action => 'deconfigure',
|
199
|
+
:app_name => opt['app'],
|
200
|
+
:rhlogin => opt['rhlogin'],
|
201
|
+
:password => password
|
202
|
+
})
|
203
|
+
puts "Cleaning up application"
|
204
|
+
url = URI.parse("https://#{libra_server}/app/broker/cartridge")
|
205
|
+
RHC::http_post(@http, url, json_data, password)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
#
|
210
|
+
# Check / add new host to ~/.ssh/config
|
211
|
+
#
|
212
|
+
|
213
|
+
puts "Checking ~/.ssh/config"
|
214
|
+
|
215
|
+
user_info = RHC::get_user_info(libra_server, opt['rhlogin'], password, @http, debug, false)
|
216
|
+
|
217
|
+
my_url = "#{opt['app']}-#{user_info['user_info']['namespace']}.#{libra_domain}"
|
218
|
+
|
219
|
+
found = false
|
220
|
+
|
221
|
+
begin
|
222
|
+
File.open(ssh_config, "r") do |sline|
|
223
|
+
while(line = sline.gets)
|
224
|
+
if line.to_s.start_with? "Host *.#{libra_domain}"
|
225
|
+
found = true
|
226
|
+
break
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
rescue Errno::EACCES
|
231
|
+
puts "Could not read from #{ssh_config}"
|
232
|
+
puts "Reason: " + $!
|
233
|
+
puts
|
234
|
+
puts "Please correct this first. Then run rerun."
|
235
|
+
puts
|
236
|
+
exit 213
|
237
|
+
rescue Errno::ENOENT
|
238
|
+
puts "Could not find #{ssh_config}. This is ok, continuing"
|
239
|
+
end
|
240
|
+
if found
|
241
|
+
puts "Found #{libra_domain} in ~/.ssh/config... No need to adjust"
|
242
|
+
else
|
243
|
+
puts " Adding #{libra_domain} to ~/.ssh/config"
|
244
|
+
begin
|
245
|
+
f = File.open(ssh_config, "a")
|
246
|
+
f.puts <<SSH
|
247
|
+
|
248
|
+
# Added by rhc-create-app app on #{`date`}
|
249
|
+
Host *.#{libra_domain}
|
250
|
+
IdentityFile ~/.ssh/libra_id_rsa
|
251
|
+
VerifyHostKeyDNS yes
|
252
|
+
StrictHostKeyChecking no
|
253
|
+
PasswordAuthentication no
|
254
|
+
UserKnownHostsFile ~/.ssh/libra_known_hosts
|
255
|
+
|
256
|
+
SSH
|
257
|
+
f.close
|
258
|
+
rescue Errno::EACCES
|
259
|
+
puts "Could not write to #{ssh_config}"
|
260
|
+
puts "Reason: " + $!
|
261
|
+
puts
|
262
|
+
puts "Please correct this first. Then run rerun."
|
263
|
+
puts
|
264
|
+
exit 214
|
265
|
+
rescue Errno::ENOENT
|
266
|
+
# Make directory and config if they do not exist
|
267
|
+
puts "Could not find directory: " + $!
|
268
|
+
puts "creating"
|
269
|
+
FileUtils.mkdir_p ssh_config_d
|
270
|
+
file = File.open(ssh_config, 'w')
|
271
|
+
file.close
|
272
|
+
retry
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
File.chmod(0700, ssh_config_d)
|
277
|
+
File.chmod(0600, ssh_config)
|
278
|
+
|
279
|
+
#
|
280
|
+
# Confirm that the host exists in DNS
|
281
|
+
#
|
282
|
+
puts "Now your new domain name is being populated worldwide (this might take a minute)..."
|
283
|
+
|
284
|
+
# Allow DNS to propogate
|
285
|
+
sleep 15
|
286
|
+
|
287
|
+
# Now start checking for DNS
|
288
|
+
loop = 0
|
289
|
+
sleep_time = 2
|
290
|
+
while loop < RHC::Maxretries && !RHC::hostexist?(my_url)
|
291
|
+
sleep sleep_time
|
292
|
+
loop+=1
|
293
|
+
puts " retry # #{loop} - Waiting for DNS: #{my_url}"
|
294
|
+
sleep_time = RHC::delay(sleep_time)
|
295
|
+
end
|
296
|
+
|
297
|
+
if loop >= RHC::Maxretries
|
298
|
+
puts "Host could not be created and/or found..."
|
299
|
+
exit 215
|
300
|
+
end
|
301
|
+
|
302
|
+
sleep_time = 2
|
303
|
+
attempt = 0
|
304
|
+
#
|
305
|
+
# Pull new repo locally
|
306
|
+
#
|
307
|
+
|
308
|
+
git_url = "ssh://#{uuid}@#{opt['app']}-#{user_info['user_info']['namespace']}.#{libra_domain}/~/git/#{opt['app']}.git/"
|
309
|
+
|
310
|
+
unless opt['nogit']
|
311
|
+
puts "Pulling new repo down"
|
312
|
+
|
313
|
+
puts "git clone #{git_url} #{opt['repo']}" if debug
|
314
|
+
git_pull = `git clone #{git_url} #{opt['repo']}`
|
315
|
+
if $?.exitstatus != 0
|
316
|
+
puts "Error in git pull"
|
317
|
+
puts git_pull
|
318
|
+
exit 216
|
319
|
+
end
|
320
|
+
else
|
321
|
+
puts <<IMPORTANT
|
322
|
+
|
323
|
+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
324
|
+
IMPORTANT: Since the -n flag was specified, no local repo has been created.
|
325
|
+
This means you can't make changes to your published application until after
|
326
|
+
you clone the repo yourself. See the git url below for more information.
|
327
|
+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
328
|
+
|
329
|
+
IMPORTANT
|
330
|
+
end
|
331
|
+
|
332
|
+
#
|
333
|
+
# At this point, we need to register a handler to guarantee git
|
334
|
+
# repo cleanup on any exceptions or calls to exit
|
335
|
+
#
|
336
|
+
at_exit do
|
337
|
+
unless $!.nil? || $!.is_a?(SystemExit) && $!.success?
|
338
|
+
puts "Cleaning up git repo"
|
339
|
+
FileUtils.rm_rf opt['repo']
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
#
|
344
|
+
# Test several times, doubling sleep time between attempts.
|
345
|
+
#
|
346
|
+
sleep_time = 2
|
347
|
+
attempt = 0
|
348
|
+
puts "Confirming application #{opt['app']} is available"
|
349
|
+
while attempt < RHC::Maxretries
|
350
|
+
attempt+=1
|
351
|
+
puts " Attempt # #{attempt}"
|
352
|
+
page = 'health'
|
353
|
+
if (type == :php)
|
354
|
+
page = 'health_check.php'
|
355
|
+
end
|
356
|
+
url = URI.parse("http://#{my_url}/#{page}")
|
357
|
+
begin
|
358
|
+
response = @http.get_response(url)
|
359
|
+
rescue Exception => e
|
360
|
+
response = nil
|
361
|
+
end
|
362
|
+
if !response.nil? && response.code == "200" && response.body[0,1] == "1"
|
363
|
+
puts <<LOOKSGOOD
|
364
|
+
|
365
|
+
Success! Your application is now published here:
|
366
|
+
|
367
|
+
http://#{my_url}/
|
368
|
+
|
369
|
+
The remote repository is located here:
|
370
|
+
|
371
|
+
#{git_url}
|
372
|
+
|
373
|
+
To make changes to your application, commit to #{opt['repo']}/.
|
374
|
+
Then run 'git push' to update your Openshift Express space
|
375
|
+
|
376
|
+
LOOKSGOOD
|
377
|
+
exit 0
|
378
|
+
end
|
379
|
+
if !response.nil? && debug
|
380
|
+
puts "Server responded with #{response.code}"
|
381
|
+
puts response.body unless response.code == '503'
|
382
|
+
end
|
383
|
+
puts
|
384
|
+
puts " sleeping #{sleep_time} seconds"
|
385
|
+
sleep sleep_time
|
386
|
+
sleep_time = RHC::delay(sleep_time)
|
387
|
+
end
|
388
|
+
puts "Unable to find or access the site... problems"
|
389
|
+
exit 254
|