rhc 1.3.8 → 1.4.7
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/features/lib/rhc_helper/domain.rb +9 -18
- data/features/scaled_application.feature +1 -1
- data/features/step_definitions/cartridge_steps.rb +1 -1
- data/lib/rhc.rb +3 -0
- data/lib/rhc/cartridge_helpers.rb +85 -27
- data/lib/rhc/command_runner.rb +1 -1
- data/lib/rhc/commands/app.rb +64 -52
- data/lib/rhc/commands/cartridge.rb +19 -32
- data/lib/rhc/commands/port_forward.rb +4 -2
- data/lib/rhc/coverage_helper.rb +2 -4
- data/lib/rhc/exceptions.rb +0 -3
- data/lib/rhc/git_helpers.rb +1 -1
- data/lib/rhc/helpers.rb +25 -11
- data/lib/rhc/output_helpers.rb +1 -7
- data/lib/rhc/rest/cartridge.rb +1 -1
- data/lib/rhc/rest/client.rb +3 -3
- data/lib/rhc/rest/mock.rb +8 -2
- data/lib/rhc/wizard.rb +29 -22
- data/spec/coverage_helper.rb +5 -8
- data/spec/rhc/commands/app_spec.rb +95 -8
- data/spec/rhc/commands/cartridge_spec.rb +2 -4
- data/spec/rhc/commands/port_forward_spec.rb +16 -7
- data/spec/rhc/helpers_spec.rb +52 -16
- data/spec/rhc/wizard_spec.rb +1 -6
- data/spec/spec_helper.rb +0 -1
- metadata +2 -61
- data/bin/rhc-app +0 -549
- data/bin/rhc-chk +0 -595
- data/bin/rhc-create-app +0 -249
- data/bin/rhc-create-domain +0 -190
- data/bin/rhc-ctl-app +0 -180
- data/bin/rhc-ctl-domain +0 -191
- data/bin/rhc-domain +0 -347
- data/bin/rhc-domain-info +0 -156
- data/bin/rhc-port-forward +0 -234
- data/bin/rhc-snapshot +0 -109
- data/bin/rhc-sshkey +0 -177
- data/bin/rhc-tail-files +0 -133
- data/bin/rhc-user-info +0 -12
- data/lib/rhc-common.rb +0 -1205
data/bin/rhc-sshkey
DELETED
@@ -1,177 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'rhc/coverage_helper'
|
4
|
-
|
5
|
-
require 'rhc-common'
|
6
|
-
|
7
|
-
RHC::Helpers.deprecated_command('rhc sshkey',true)
|
8
|
-
|
9
|
-
#
|
10
|
-
# print help
|
11
|
-
#
|
12
|
-
def p_usage(exit_code = 255)
|
13
|
-
rhlogin = get_var('default_rhlogin') ? "Default: #{get_var('default_rhlogin')}" : "required"
|
14
|
-
puts <<USAGE
|
15
|
-
|
16
|
-
Usage: rhc sshkey (<command> | --help) [<args>]
|
17
|
-
Manage multiple keys for the registered rhcloud user.
|
18
|
-
|
19
|
-
List of commands
|
20
|
-
list Display all the SSH keys for the user account
|
21
|
-
add Add SSH key to the user account
|
22
|
-
update Update SSH key for the user account
|
23
|
-
remove Remove SSH key from the user account
|
24
|
-
|
25
|
-
List of arguments
|
26
|
-
-l|--rhlogin rhlogin OpenShift login (#{rhlogin})
|
27
|
-
-p|--password password Password (optional, will prompt)
|
28
|
-
-i|--identifier key-name User-specified identifier for the key
|
29
|
-
-k|--ssh key-filepath SSH public key filepath
|
30
|
-
-d|--debug Print Debug info
|
31
|
-
-h|--help Show Usage info
|
32
|
-
--config path Path of alternate config file
|
33
|
-
--timeout # Timeout, in seconds, for the session
|
34
|
-
|
35
|
-
USAGE
|
36
|
-
exit exit_code
|
37
|
-
end
|
38
|
-
|
39
|
-
|
40
|
-
def validate_args(val_id=true)
|
41
|
-
# If provided a config path, check it
|
42
|
-
RHC::Config.check_cpath($opt)
|
43
|
-
|
44
|
-
# Pull in configs from files
|
45
|
-
$libra_server = get_var('libra_server')
|
46
|
-
debug = get_var('debug') == 'false' ? nil : get_var('debug')
|
47
|
-
|
48
|
-
$opt['rhlogin'] = get_var('default_rhlogin') unless $opt['rhlogin']
|
49
|
-
p_usage if !RHC::check_rhlogin($opt['rhlogin'])
|
50
|
-
|
51
|
-
debug = $opt["debug"] ? true : false
|
52
|
-
RHC::debug(debug)
|
53
|
-
|
54
|
-
p_usage if val_id && !RHC::check_key($opt['identifier'])
|
55
|
-
|
56
|
-
RHC::timeout($opt["timeout"], get_var('timeout'))
|
57
|
-
RHC::connect_timeout($opt["timeout"], get_var('timeout'))
|
58
|
-
$password = $opt['password'] ? $opt['password'] : RHC::get_password
|
59
|
-
end
|
60
|
-
|
61
|
-
def remove_key
|
62
|
-
validate_args(true)
|
63
|
-
|
64
|
-
data = {}
|
65
|
-
data[:rhlogin] = $opt['rhlogin']
|
66
|
-
data[:key_name] = $opt['identifier']
|
67
|
-
data[:action] = 'remove-key'
|
68
|
-
|
69
|
-
url = URI.parse("https://#{$libra_server}/broker/ssh_keys")
|
70
|
-
handle_key_mgmt_response(url, data, $password)
|
71
|
-
end
|
72
|
-
|
73
|
-
def show_key_list
|
74
|
-
validate_args(false)
|
75
|
-
|
76
|
-
ssh_keys = RHC::get_ssh_keys($libra_server, $opt['rhlogin'], $password, RHC::Config.default_proxy)
|
77
|
-
additional_ssh_keys = ssh_keys['keys']
|
78
|
-
|
79
|
-
puts ""
|
80
|
-
puts "SSH keys"
|
81
|
-
puts "========"
|
82
|
-
|
83
|
-
# first list the primary key
|
84
|
-
puts " Name: default"
|
85
|
-
puts " Type: #{ssh_keys['ssh_type']}"
|
86
|
-
puts "Fingerprint: #{ssh_keys['fingerprint']}"
|
87
|
-
#puts " Key: #{ssh_keys['ssh_key']}"
|
88
|
-
puts ""
|
89
|
-
|
90
|
-
# now list the additional keys
|
91
|
-
if additional_ssh_keys && additional_ssh_keys.kind_of?(Hash)
|
92
|
-
additional_ssh_keys.each do |name, keyval|
|
93
|
-
puts " Name: #{name}"
|
94
|
-
puts " Type: #{keyval['type']}"
|
95
|
-
puts "Fingerprint: #{keyval['fingerprint']}"
|
96
|
-
#puts " Key: #{keyval['key']}"
|
97
|
-
puts ""
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
begin
|
103
|
-
argv_c = ARGV.clone
|
104
|
-
|
105
|
-
if ARGV[0] =~ /^(add|update)$/
|
106
|
-
ARGV.shift
|
107
|
-
opts = GetoptLong.new(
|
108
|
-
["--debug", "-d", GetoptLong::NO_ARGUMENT],
|
109
|
-
["--help", "-h", GetoptLong::NO_ARGUMENT],
|
110
|
-
["--rhlogin", "-l", GetoptLong::REQUIRED_ARGUMENT],
|
111
|
-
["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
|
112
|
-
["--identifier", "-i", GetoptLong::REQUIRED_ARGUMENT],
|
113
|
-
["--ssh", "-k", GetoptLong::REQUIRED_ARGUMENT],
|
114
|
-
["--config", GetoptLong::REQUIRED_ARGUMENT],
|
115
|
-
["--timeout", GetoptLong::REQUIRED_ARGUMENT]
|
116
|
-
)
|
117
|
-
elsif ARGV[0] =~ /^remove$/
|
118
|
-
ARGV.shift
|
119
|
-
opts = GetoptLong.new(
|
120
|
-
["--debug", "-d", GetoptLong::NO_ARGUMENT],
|
121
|
-
["--help", "-h", GetoptLong::NO_ARGUMENT],
|
122
|
-
["--rhlogin", "-l", GetoptLong::REQUIRED_ARGUMENT],
|
123
|
-
["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
|
124
|
-
["--identifier", "-i", GetoptLong::REQUIRED_ARGUMENT],
|
125
|
-
["--config", GetoptLong::REQUIRED_ARGUMENT],
|
126
|
-
["--timeout", GetoptLong::REQUIRED_ARGUMENT]
|
127
|
-
)
|
128
|
-
elsif ARGV[0] =~ /^list$/
|
129
|
-
ARGV.shift
|
130
|
-
opts = GetoptLong.new(
|
131
|
-
["--debug", "-d", GetoptLong::NO_ARGUMENT],
|
132
|
-
["--help", "-h", GetoptLong::NO_ARGUMENT],
|
133
|
-
["--rhlogin", "-l", GetoptLong::REQUIRED_ARGUMENT],
|
134
|
-
["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
|
135
|
-
["--config", GetoptLong::REQUIRED_ARGUMENT],
|
136
|
-
["--timeout", GetoptLong::REQUIRED_ARGUMENT]
|
137
|
-
)
|
138
|
-
else
|
139
|
-
opts = GetoptLong.new(
|
140
|
-
["--help", "-h", GetoptLong::NO_ARGUMENT]
|
141
|
-
)
|
142
|
-
unless ARGV[0] =~ /^(help|-h|--help)$/
|
143
|
-
puts "Missing or invalid command!"
|
144
|
-
# just exit at this point
|
145
|
-
# printing the usage description will be handled in the rescue
|
146
|
-
exit 255
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
$opt = {}
|
151
|
-
opts.each do |o, a|
|
152
|
-
$opt[o[2..-1]] = a.to_s
|
153
|
-
end
|
154
|
-
|
155
|
-
rescue Exception => e
|
156
|
-
p_usage
|
157
|
-
end
|
158
|
-
|
159
|
-
p_usage 0 if $opt["help"]
|
160
|
-
|
161
|
-
case argv_c[0]
|
162
|
-
when "add", "update"
|
163
|
-
validate_args(true)
|
164
|
-
add_or_update_key(argv_c[0], $opt['identifier'], $opt['ssh'],
|
165
|
-
$opt['rhlogin'], $password)
|
166
|
-
when "remove"
|
167
|
-
remove_key
|
168
|
-
when "list", nil
|
169
|
-
show_key_list
|
170
|
-
when "-h", "--help", "help", nil
|
171
|
-
p_usage 0
|
172
|
-
else
|
173
|
-
puts "Invalid command!"
|
174
|
-
p_usage
|
175
|
-
end
|
176
|
-
|
177
|
-
exit 0
|
data/bin/rhc-tail-files
DELETED
@@ -1,133 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'rhc/coverage_helper'
|
4
|
-
|
5
|
-
require 'rhc-common'
|
6
|
-
require 'base64'
|
7
|
-
|
8
|
-
#
|
9
|
-
# print help
|
10
|
-
#
|
11
|
-
def p_usage(exit_code = 255)
|
12
|
-
rhlogin = get_var('default_rhlogin') ? "Default: #{get_var('default_rhlogin')}" : "required"
|
13
|
-
puts <<USAGE
|
14
|
-
|
15
|
-
Usage: #{$0}
|
16
|
-
Tail the logs of an application
|
17
|
-
|
18
|
-
-l|--rhlogin rhlogin OpenShift login (#{rhlogin})
|
19
|
-
-a|--app Target application (required)
|
20
|
-
-f|--files File glob relative to app (default <application_name>/logs/*) (optional)
|
21
|
-
-o|--opts Options to pass to the server-side (linux based) tail command (-f is implicit. See the linux tail man page full list of options.) (Ex: --opts '-n 100')
|
22
|
-
-p|--password password Password (optional, will prompt)
|
23
|
-
-d|--debug Print Debug info
|
24
|
-
-h|--help Show Usage info
|
25
|
-
--config path Path of alternate config file
|
26
|
-
--timeout # Timeout, in seconds, for the session
|
27
|
-
|
28
|
-
USAGE
|
29
|
-
exit exit_code
|
30
|
-
end
|
31
|
-
|
32
|
-
begin
|
33
|
-
opts = GetoptLong.new(
|
34
|
-
["--debug", "-d", GetoptLong::NO_ARGUMENT],
|
35
|
-
["--help", "-h", GetoptLong::NO_ARGUMENT],
|
36
|
-
["--app", "-a", GetoptLong::REQUIRED_ARGUMENT],
|
37
|
-
["--opts", "-o", GetoptLong::REQUIRED_ARGUMENT],
|
38
|
-
["--files", "-f", GetoptLong::REQUIRED_ARGUMENT],
|
39
|
-
["--rhlogin", "-l", GetoptLong::REQUIRED_ARGUMENT],
|
40
|
-
["--config", GetoptLong::REQUIRED_ARGUMENT],
|
41
|
-
["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
|
42
|
-
["--timeout", GetoptLong::REQUIRED_ARGUMENT]
|
43
|
-
)
|
44
|
-
opt = {}
|
45
|
-
opts.each do |o, a|
|
46
|
-
opt[o[2..-1]] = a.to_s
|
47
|
-
end
|
48
|
-
rescue Exception => e
|
49
|
-
#puts e.message
|
50
|
-
p_usage
|
51
|
-
end
|
52
|
-
|
53
|
-
# If provided a config path, check it
|
54
|
-
RHC::Config.check_cpath(opt)
|
55
|
-
|
56
|
-
# Pull in configs from files
|
57
|
-
libra_server = get_var('libra_server')
|
58
|
-
debug = get_var('debug') == 'false' ? nil : get_var('debug')
|
59
|
-
|
60
|
-
p_usage 0 if opt['help']
|
61
|
-
|
62
|
-
p_usage if !opt['app'] || 0 != ARGV.length
|
63
|
-
|
64
|
-
debug = true if opt['debug']
|
65
|
-
|
66
|
-
RHC::debug(debug)
|
67
|
-
|
68
|
-
RHC::timeout(opt["timeout"], get_var('timeout'))
|
69
|
-
RHC::connect_timeout(opt["timeout"], get_var('timeout'))
|
70
|
-
|
71
|
-
opt['rhlogin'] = get_var('default_rhlogin') unless opt['rhlogin']
|
72
|
-
|
73
|
-
if !RHC::check_rhlogin(opt['rhlogin'])
|
74
|
-
p_usage
|
75
|
-
end
|
76
|
-
|
77
|
-
password = opt['password']
|
78
|
-
if !password
|
79
|
-
password = RHC::get_password
|
80
|
-
end
|
81
|
-
|
82
|
-
user_info = RHC::get_user_info(libra_server, opt['rhlogin'], password, RHC::Config.default_proxy, false)
|
83
|
-
|
84
|
-
app = opt['app']
|
85
|
-
|
86
|
-
unless user_info['app_info'][app]
|
87
|
-
puts
|
88
|
-
puts "Could not find app '#{opt['app']}'. Please run rhc-domain-info to get a list"
|
89
|
-
puts "of your current running applications"
|
90
|
-
puts
|
91
|
-
exit 101
|
92
|
-
end
|
93
|
-
|
94
|
-
opt['files'] = "*/log*/*" unless opt['files']
|
95
|
-
file_glob = "#{opt['files']}"
|
96
|
-
app_uuid = user_info['app_info'][app]['uuid']
|
97
|
-
namespace = user_info['user_info']['domains'][0]['namespace']
|
98
|
-
rhc_domain = user_info['user_info']['rhc_domain']
|
99
|
-
|
100
|
-
# -t to force PTY and avoid daemons
|
101
|
-
# Red Hat OpenShift: https://bugzilla.redhat.com/show_bug.cgi?id=726646
|
102
|
-
# OpenSSH https://bugzilla.mindrot.org/show_bug.cgi?id=396
|
103
|
-
|
104
|
-
remote_cmd = "tail#{opt['opts'] ? ' --opts ' + Base64::encode64(opt['opts']).chomp : ''} #{file_glob}"
|
105
|
-
ssh_cmd = "ssh -t #{app_uuid}@#{app}-#{namespace}.#{rhc_domain} '#{remote_cmd}'"
|
106
|
-
|
107
|
-
puts "Attempting to tail files: #{file_glob}"
|
108
|
-
puts "Use ctl + c to stop"
|
109
|
-
puts ssh_cmd if debug
|
110
|
-
begin
|
111
|
-
if opt['files'] == 'system-messages'
|
112
|
-
RHC::ctl_app(libra_server, RHC::Config.default_proxy, opt['app'], opt['rhlogin'], password,
|
113
|
-
'system-messages', false, nil, nil)
|
114
|
-
else
|
115
|
-
ssh_ruby("#{app}-#{namespace}.#{rhc_domain}", app_uuid, remote_cmd)
|
116
|
-
end
|
117
|
-
rescue Interrupt
|
118
|
-
puts
|
119
|
-
puts "Terminating..."
|
120
|
-
exit 0
|
121
|
-
rescue SocketError => e
|
122
|
-
puts
|
123
|
-
puts "Could not connect: #{e.message}"
|
124
|
-
puts
|
125
|
-
puts "DEBUG: #{e.debug}" if debug
|
126
|
-
puts "You can try to run this manually if you have ssh installed: "
|
127
|
-
puts
|
128
|
-
puts ssh_cmd
|
129
|
-
puts
|
130
|
-
exit 1
|
131
|
-
end
|
132
|
-
# this should never happen
|
133
|
-
exit 1
|
data/bin/rhc-user-info
DELETED
data/lib/rhc-common.rb
DELETED
@@ -1,1205 +0,0 @@
|
|
1
|
-
require 'rubygems' # Will eventually be removed when this file is deprecated
|
2
|
-
require 'fileutils'
|
3
|
-
require 'getoptlong'
|
4
|
-
require 'net/http'
|
5
|
-
require 'net/https'
|
6
|
-
require 'net/ssh'
|
7
|
-
require 'rhc/vendor/sshkey'
|
8
|
-
require 'resolv'
|
9
|
-
require 'uri'
|
10
|
-
require 'highline/import'
|
11
|
-
require 'rhc'
|
12
|
-
require 'rhc/rest'
|
13
|
-
require 'rhc/helpers'
|
14
|
-
require 'rhc/config'
|
15
|
-
require 'rhc/wizard'
|
16
|
-
require 'rhc/tar_gz'
|
17
|
-
require 'rhc/json'
|
18
|
-
|
19
|
-
module RHC
|
20
|
-
|
21
|
-
DEFAULT_MAX_LENGTH = 16
|
22
|
-
APP_NAME_MAX_LENGTH = 32
|
23
|
-
MAX_RETRIES = 7
|
24
|
-
DEFAULT_DELAY = 2.0
|
25
|
-
API = "1.1.3"
|
26
|
-
PATTERN_VERSION=/\A\d+\.\d+\.\d+\z/
|
27
|
-
@read_timeout = 120
|
28
|
-
@connect_timeout = 20
|
29
|
-
@mydebug = false
|
30
|
-
@@api_version = "?.?.?"
|
31
|
-
|
32
|
-
# reset lines
|
33
|
-
# \r moves the cursor to the beginning of line
|
34
|
-
# ANSI escape code to clear line from cursor to end of line
|
35
|
-
# "\e" is an alternative to "\033"
|
36
|
-
# cf. http://en.wikipedia.org/wiki/ANSI_escape_code
|
37
|
-
CLEAR_LINE = "\r" + "\e[0K"
|
38
|
-
|
39
|
-
DEBUG_INGORE_KEYS = {
|
40
|
-
'result' => nil,
|
41
|
-
'debug' => nil,
|
42
|
-
'exit_code' => nil,
|
43
|
-
'messages' => nil,
|
44
|
-
'data' => nil,
|
45
|
-
'api' => nil
|
46
|
-
}
|
47
|
-
|
48
|
-
def self.timeout(*vals)
|
49
|
-
vals.each do |val|
|
50
|
-
if val
|
51
|
-
unless val.to_i > 0
|
52
|
-
puts 'Timeout must be specified as a number greater than 0'
|
53
|
-
exit 1
|
54
|
-
end
|
55
|
-
@read_timeout = [val.to_i, @read_timeout].max
|
56
|
-
return @read_timeout
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def self.connect_timeout(*vals)
|
62
|
-
vals.each do |val|
|
63
|
-
if val
|
64
|
-
unless val.to_i > 0
|
65
|
-
puts 'Timeout must be specified as a number greater than 0'
|
66
|
-
exit 1
|
67
|
-
end
|
68
|
-
@connect_timeout = [val.to_i, @connect_timeout].max
|
69
|
-
return @connect_timeout
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def self.debug(bool)
|
75
|
-
@mydebug = bool
|
76
|
-
end
|
77
|
-
|
78
|
-
def self.update_server_api_v(dict)
|
79
|
-
if !dict['api'].nil? && (dict['api'] =~ PATTERN_VERSION)
|
80
|
-
@@api_version = dict['api']
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def self.check_version
|
85
|
-
if @@api_version =~ PATTERN_VERSION
|
86
|
-
if API != @@api_version
|
87
|
-
puts "\nNOTICE: Client API version (#{API}) does not match the server (#{@@api_version}).\nThough requests may succeed, you should consider updating your client tools.\n\n"
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def self.delay(time, adj=DEFAULT_DELAY)
|
93
|
-
(time*=adj).to_int
|
94
|
-
end
|
95
|
-
|
96
|
-
def self.json_encode(data)
|
97
|
-
RHC::Json.encode(data)
|
98
|
-
end
|
99
|
-
|
100
|
-
def self.json_decode(json)
|
101
|
-
RHC::Json.decode(json)
|
102
|
-
end
|
103
|
-
|
104
|
-
def self.generate_json(data)
|
105
|
-
data['api'] = API
|
106
|
-
json = json_encode(data)
|
107
|
-
json
|
108
|
-
end
|
109
|
-
|
110
|
-
def self.get_cartridges_list(libra_server, net_http, cart_type="standalone", print_result=nil)
|
111
|
-
puts "Obtaining list of cartridges (please excuse the delay)..."
|
112
|
-
data = {'cart_type' => cart_type}
|
113
|
-
if @mydebug
|
114
|
-
data[:debug] = true
|
115
|
-
end
|
116
|
-
print_post_data(data)
|
117
|
-
json_data = generate_json(data)
|
118
|
-
|
119
|
-
url = URI.parse("https://#{libra_server}/broker/cartlist")
|
120
|
-
response = http_post(net_http, url, json_data, "none")
|
121
|
-
|
122
|
-
unless response.code == '200'
|
123
|
-
print_response_err(response)
|
124
|
-
return []
|
125
|
-
end
|
126
|
-
begin
|
127
|
-
json_resp = json_decode(response.body)
|
128
|
-
rescue RHC::JsonError
|
129
|
-
exit 1
|
130
|
-
end
|
131
|
-
update_server_api_v(json_resp)
|
132
|
-
if print_result
|
133
|
-
print_response_success(json_resp)
|
134
|
-
end
|
135
|
-
begin
|
136
|
-
carts = (json_decode(json_resp['data']))['carts']
|
137
|
-
rescue RHC::JsonError
|
138
|
-
exit 1
|
139
|
-
end
|
140
|
-
carts
|
141
|
-
end
|
142
|
-
|
143
|
-
def self.get_cartridge_listing(carts, sep, libra_server, net_http, cart_type="standalone", print_result=nil)
|
144
|
-
carts = get_cartridges_list(libra_server, net_http, cart_type, print_result) if carts.nil?
|
145
|
-
carts.join(sep)
|
146
|
-
end
|
147
|
-
|
148
|
-
|
149
|
-
# Invalid chars (") ($) (^) (<) (>) (|) (%) (/) (;) (:) (,) (\) (*) (=) (~)
|
150
|
-
def self.check_rhlogin(rhlogin)
|
151
|
-
if rhlogin
|
152
|
-
if rhlogin =~ /["\$\^<>\|%\/;:,\\\*=~]/
|
153
|
-
puts 'OpenShift login may not contain any of these characters: (\") ($) (^) (<) (>) (|) (%) (/) (;) (:) (,) (\) (*) (=) (~)'
|
154
|
-
return false
|
155
|
-
end
|
156
|
-
else
|
157
|
-
puts "OpenShift login is required"
|
158
|
-
return false
|
159
|
-
end
|
160
|
-
true
|
161
|
-
end
|
162
|
-
|
163
|
-
def self.check_app(app)
|
164
|
-
check_field(app, 'application', APP_NAME_MAX_LENGTH)
|
165
|
-
end
|
166
|
-
|
167
|
-
def self.check_namespace(namespace)
|
168
|
-
check_field(namespace, 'namespace', DEFAULT_MAX_LENGTH)
|
169
|
-
end
|
170
|
-
|
171
|
-
def self.check_key(keyname)
|
172
|
-
check_field(keyname, 'key name', DEFAULT_MAX_LENGTH, /[^0-9a-zA-Z]/,
|
173
|
-
'contains invalid characters! Only alpha-numeric characters allowed.')
|
174
|
-
end
|
175
|
-
|
176
|
-
def self.check_field(field, type, max=0, val_regex=/[^0-9a-zA-Z]/,
|
177
|
-
regex_failed_error='contains non-alphanumeric characters!')
|
178
|
-
if field
|
179
|
-
if field =~ val_regex
|
180
|
-
say "#{type} " + regex_failed_error
|
181
|
-
return false
|
182
|
-
end
|
183
|
-
if max != 0 && field.length > max
|
184
|
-
say "maximum #{type} size is #{max} characters"
|
185
|
-
return false
|
186
|
-
end
|
187
|
-
else
|
188
|
-
say "#{type} is required"
|
189
|
-
return false
|
190
|
-
end
|
191
|
-
field
|
192
|
-
end
|
193
|
-
|
194
|
-
def self.print_post_data(h)
|
195
|
-
if (@mydebug)
|
196
|
-
puts 'Submitting form:'
|
197
|
-
h.each do |k,v|
|
198
|
-
if k.to_s != 'password'
|
199
|
-
puts "#{k.to_s}: #{v.to_s}"
|
200
|
-
else
|
201
|
-
print 'password: '
|
202
|
-
for i in (1..v.length)
|
203
|
-
print 'X'
|
204
|
-
end
|
205
|
-
puts ''
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
def self.get_user_info(libra_server, rhlogin, password, net_http, print_result, not_found_message=nil)
|
212
|
-
data = {'rhlogin' => rhlogin}
|
213
|
-
if @mydebug
|
214
|
-
data[:debug] = true
|
215
|
-
end
|
216
|
-
print_post_data(data)
|
217
|
-
json_data = generate_json(data)
|
218
|
-
|
219
|
-
url = URI.parse("https://#{libra_server}/broker/userinfo")
|
220
|
-
response = http_post(net_http, url, json_data, password)
|
221
|
-
|
222
|
-
unless response.code == '200'
|
223
|
-
if response.code == '404'
|
224
|
-
if not_found_message
|
225
|
-
puts not_found_message
|
226
|
-
else
|
227
|
-
puts "A user with rhlogin '#{rhlogin}' does not have a registered domain. Be sure to run 'rhc domain create' before using the other rhc tools."
|
228
|
-
end
|
229
|
-
exit 99
|
230
|
-
elsif response.code == '401'
|
231
|
-
puts "Invalid user credentials"
|
232
|
-
exit 97
|
233
|
-
else
|
234
|
-
print_response_err(response)
|
235
|
-
end
|
236
|
-
exit 1
|
237
|
-
end
|
238
|
-
begin
|
239
|
-
json_resp = json_decode(response.body)
|
240
|
-
rescue RHC::JsonError
|
241
|
-
exit 1
|
242
|
-
end
|
243
|
-
update_server_api_v(json_resp)
|
244
|
-
if print_result
|
245
|
-
print_response_success(json_resp)
|
246
|
-
end
|
247
|
-
begin
|
248
|
-
user_info = json_decode(json_resp['data'].to_s)
|
249
|
-
rescue RHC::JsonError
|
250
|
-
exit 1
|
251
|
-
end
|
252
|
-
user_info
|
253
|
-
end
|
254
|
-
|
255
|
-
# Public: Get a list of ssh keys
|
256
|
-
#
|
257
|
-
# type - The String type RSA or DSS.
|
258
|
-
# libra_server - The String DNS for the broker
|
259
|
-
# rhlogin - The String login name
|
260
|
-
# password - The String password for login
|
261
|
-
# net_http - The NET::HTTP Object to use
|
262
|
-
#
|
263
|
-
# Examples
|
264
|
-
#
|
265
|
-
# RHC::get_ssh_keys('openshift.redhat.com',
|
266
|
-
# 'mylogin@example.com',
|
267
|
-
# 'mypassword',
|
268
|
-
# RHC::Config.default_proxy)
|
269
|
-
# # => { "ssh_type" => "ssh-rsa",
|
270
|
-
# "ssh_key" => "AAAAB3NzaC1yc2EAAAADAQAB....",
|
271
|
-
# "fingerprint" => "ea:08:e3:c7:e3:c3:8e:6a:66:34:65:e4:56:f4:3e:ff"}
|
272
|
-
#
|
273
|
-
# FIXME! Exits on failure! Should return something instead
|
274
|
-
#
|
275
|
-
# Returns Hash on success or exits on failure
|
276
|
-
def self.get_ssh_keys(libra_server, rhlogin, password, net_http)
|
277
|
-
data = {'rhlogin' => rhlogin, 'action' => 'list-keys'}
|
278
|
-
if @mydebug
|
279
|
-
data[:debug] = true
|
280
|
-
end
|
281
|
-
print_post_data(data)
|
282
|
-
json_data = generate_json(data)
|
283
|
-
|
284
|
-
url = URI.parse("https://#{libra_server}/broker/ssh_keys")
|
285
|
-
response = http_post(net_http, url, json_data, password)
|
286
|
-
|
287
|
-
unless response.code == '200'
|
288
|
-
if response.code == '401'
|
289
|
-
puts "Invalid user credentials"
|
290
|
-
exit 97
|
291
|
-
else
|
292
|
-
print_response_err(response)
|
293
|
-
end
|
294
|
-
exit 1
|
295
|
-
end
|
296
|
-
begin
|
297
|
-
json_resp = json_decode(response.body)
|
298
|
-
rescue RHC::JsonError
|
299
|
-
exit 1
|
300
|
-
end
|
301
|
-
update_server_api_v(json_resp)
|
302
|
-
begin
|
303
|
-
ssh_keys = (json_decode(json_resp['data'].to_s))
|
304
|
-
rescue RHC::JsonError
|
305
|
-
exit 1
|
306
|
-
end
|
307
|
-
|
308
|
-
# Inject public fingerprint into key.
|
309
|
-
begin
|
310
|
-
if ssh_keys['ssh_type'].nil? or ssh_keys['ssh_type'].empty?
|
311
|
-
ssh_keys['fingerprint'] = nil
|
312
|
-
else
|
313
|
-
ssh_keys['fingerprint'] = \
|
314
|
-
Net::SSH::KeyFactory.load_data_public_key(
|
315
|
-
"#{ssh_keys['ssh_type']} #{ssh_keys['ssh_key']}").fingerprint
|
316
|
-
end
|
317
|
-
rescue NoMethodError
|
318
|
-
#older net/ssh (mac for example)
|
319
|
-
tempfile = `mktemp /tmp/openshift.XXXXXXXX`
|
320
|
-
`echo "#{ssh_keys['ssh_type']} #{ssh_keys['ssh_key']}" > #{tempfile}`
|
321
|
-
ssh_keys['fingerprint'] = `ssh-keygen -lf #{tempfile}`.split(' ')[1]
|
322
|
-
rescue Net::SSH::Exception, NotImplementedError, OpenSSL::PKey::PKeyError
|
323
|
-
# Could be a new unsupported key type or invalid data on the server
|
324
|
-
ssh_keys['fingerprint'] = 'Key type is not recognized. Please check this key is valid.'
|
325
|
-
end
|
326
|
-
|
327
|
-
if ssh_keys['keys'] && ssh_keys['keys'].kind_of?(Hash)
|
328
|
-
ssh_keys['keys'].each do |name, keyval|
|
329
|
-
type = keyval['type']
|
330
|
-
key = keyval['key']
|
331
|
-
begin
|
332
|
-
ssh_keys['keys'][name]['fingerprint'] = \
|
333
|
-
Net::SSH::KeyFactory.load_data_public_key(
|
334
|
-
"#{type} #{key}").fingerprint
|
335
|
-
rescue NoMethodError
|
336
|
-
#older net/ssh (mac for example)
|
337
|
-
tempfile = `mktemp /tmp/openshift.XXXXXXXX`
|
338
|
-
`echo "#{type} #{key}" > #{tempfile}`
|
339
|
-
ssh_keys['keys'][name]['fingerprint'] = `ssh-keygen -lf #{tempfile}`.split(' ')[1]
|
340
|
-
rescue NotImplementedError, Net::SSH::Exception, OpenSSL::PKey::PKeyError
|
341
|
-
# Could be a new unsupported key type or invalid data on the server
|
342
|
-
ssh_keys['keys'][name]['fingerprint'] = 'Key type is not recognized. Please check this key is valid.'
|
343
|
-
end
|
344
|
-
end
|
345
|
-
end
|
346
|
-
ssh_keys
|
347
|
-
end
|
348
|
-
|
349
|
-
def self.get_password
|
350
|
-
password = nil
|
351
|
-
begin
|
352
|
-
password = ask_password
|
353
|
-
rescue Interrupt
|
354
|
-
puts "\n"
|
355
|
-
exit 1
|
356
|
-
end
|
357
|
-
puts "\n"
|
358
|
-
password
|
359
|
-
end
|
360
|
-
|
361
|
-
def self.http_post(http, url, json_data, password)
|
362
|
-
req = http::Post.new(url.path)
|
363
|
-
|
364
|
-
puts "Contacting #{url.scheme}://#{url.host}" if @mydebug
|
365
|
-
req.set_form_data({'json_data' => json_data, 'password' => password})
|
366
|
-
req['User-Agent'] = RHC::Helpers.user_agent
|
367
|
-
|
368
|
-
http = http.new(url.host, url.port)
|
369
|
-
http.open_timeout = @connect_timeout
|
370
|
-
http.read_timeout = @read_timeout
|
371
|
-
if url.scheme == "https"
|
372
|
-
http.use_ssl = true
|
373
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
374
|
-
end
|
375
|
-
begin
|
376
|
-
response = http.start {|http| http.request(req)}
|
377
|
-
if response.code == '404' && response.content_type == 'text/html'
|
378
|
-
# TODO probably want to remove this at some point
|
379
|
-
puts "!!!! WARNING !!!! WARNING !!!! WARNING !!!!"
|
380
|
-
puts "RHCloud server not found. You might want to try updating your rhc client tools."
|
381
|
-
exit 218
|
382
|
-
end
|
383
|
-
response
|
384
|
-
rescue Exception => e
|
385
|
-
puts "There was a problem communicating with the server. Response message: #{e.message}"
|
386
|
-
puts "If you were disconnected it is possible the operation finished without being able to report success."
|
387
|
-
puts "You can use 'rhc domain show' and 'rhc app show --state' to learn about the status of your user and application(s)."
|
388
|
-
exit 219
|
389
|
-
end
|
390
|
-
end
|
391
|
-
|
392
|
-
def self.print_response_err(response)
|
393
|
-
puts "Problem reported from server. Response code was #{response.code}."
|
394
|
-
if (!@mydebug)
|
395
|
-
puts "Re-run with -d for more information."
|
396
|
-
end
|
397
|
-
exit_code = 1
|
398
|
-
if response.class.inspect == "Struct::FakeResponse"
|
399
|
-
print_response_message(response.body)
|
400
|
-
elsif response.content_type == 'application/json'
|
401
|
-
begin
|
402
|
-
json_resp = json_decode(response.body)
|
403
|
-
exit_code = print_json_body(json_resp)
|
404
|
-
rescue RHC::JsonError
|
405
|
-
exit_code = 1
|
406
|
-
end
|
407
|
-
elsif @mydebug
|
408
|
-
puts "HTTP response from server is #{response.body}"
|
409
|
-
end
|
410
|
-
exit exit_code.nil? ? 666 : exit_code
|
411
|
-
end
|
412
|
-
|
413
|
-
def self.print_response_messages(json_resp)
|
414
|
-
messages = json_resp['messages']
|
415
|
-
print_response_message(messages)
|
416
|
-
end
|
417
|
-
|
418
|
-
def self.print_response_message(message)
|
419
|
-
if (message && !message.empty?)
|
420
|
-
puts ''
|
421
|
-
puts 'MESSAGES:'
|
422
|
-
puts message
|
423
|
-
puts ''
|
424
|
-
end
|
425
|
-
end
|
426
|
-
|
427
|
-
def self.print_response_success(json_resp, print_result=false)
|
428
|
-
if @mydebug
|
429
|
-
print "Response from server:"
|
430
|
-
$stdout.flush
|
431
|
-
print_json_body(json_resp, print_result)
|
432
|
-
elsif print_result
|
433
|
-
print_json_body(json_resp)
|
434
|
-
else
|
435
|
-
print_response_messages(json_resp)
|
436
|
-
end
|
437
|
-
end
|
438
|
-
|
439
|
-
def self.print_json_body(json_resp, print_result=true)
|
440
|
-
print_response_messages(json_resp)
|
441
|
-
exit_code = json_resp['exit_code']
|
442
|
-
if @mydebug
|
443
|
-
if json_resp['debug']
|
444
|
-
puts ''
|
445
|
-
puts 'DEBUG:'
|
446
|
-
puts json_resp['debug']
|
447
|
-
puts ''
|
448
|
-
puts "Exit Code: #{exit_code}"
|
449
|
-
if (json_resp.length > 3)
|
450
|
-
json_resp.each do |k,v|
|
451
|
-
if !DEBUG_INGORE_KEYS.has_key?(k)
|
452
|
-
puts "#{k.to_s}: #{v.to_s}"
|
453
|
-
end
|
454
|
-
end
|
455
|
-
end
|
456
|
-
end
|
457
|
-
if json_resp['api']
|
458
|
-
puts "API version: #{json_resp['api']}"
|
459
|
-
end
|
460
|
-
end
|
461
|
-
if print_result && json_resp['result']
|
462
|
-
puts ''
|
463
|
-
puts 'RESULT:'
|
464
|
-
puts json_resp['result']
|
465
|
-
puts ''
|
466
|
-
end
|
467
|
-
exit_code
|
468
|
-
end
|
469
|
-
|
470
|
-
#
|
471
|
-
# Check if host exists
|
472
|
-
#
|
473
|
-
def self.hostexist?(host)
|
474
|
-
RHC::Helpers.host_exists?(host)
|
475
|
-
end
|
476
|
-
|
477
|
-
def self.create_app(libra_server, net_http, user_info, app_name, app_type, rhlogin, password, repo_dir=nil, no_dns=false, no_git=false, is_embedded_jenkins=false, gear_size='small',scale=false)
|
478
|
-
|
479
|
-
# Need to have a fake HTTPResponse object for passing to print_reponse_err
|
480
|
-
# May already be initialized if called from another piece of code
|
481
|
-
# FIXME: remove this requirement when refactoring rhc
|
482
|
-
begin
|
483
|
-
Struct::FakeResponse
|
484
|
-
rescue NameError
|
485
|
-
Struct.new('FakeResponse',:body,:code,:content_type)
|
486
|
-
end
|
487
|
-
|
488
|
-
domains = user_info['user_info']['domains']
|
489
|
-
if domains.empty?
|
490
|
-
emessage = "Please create a domain with 'rhc domain create -n <namespace>' before creating applications."
|
491
|
-
print_response_err(Struct::FakeResponse.new(emessage,403))
|
492
|
-
end
|
493
|
-
namespace = domains[0]['namespace']
|
494
|
-
puts "Creating application: #{app_name} in #{namespace}"
|
495
|
-
data = {:cartridge => app_type,
|
496
|
-
:action => 'configure',
|
497
|
-
:node_profile => gear_size,
|
498
|
-
:app_name => app_name,
|
499
|
-
:rhlogin => rhlogin
|
500
|
-
}
|
501
|
-
if @mydebug
|
502
|
-
data[:debug] = true
|
503
|
-
end
|
504
|
-
|
505
|
-
# Need to use the new REST API for scaling apps
|
506
|
-
# We'll need to then get the new application using the existing
|
507
|
-
# API in order to access the rest of the logic in this function
|
508
|
-
if scale
|
509
|
-
end_point = "https://#{libra_server}/broker/rest/api"
|
510
|
-
client = RHC::Rest::Client.new(end_point, rhlogin, password)
|
511
|
-
|
512
|
-
domain = client.find_domain(user_info['user_info']['domains'][0]['namespace'])
|
513
|
-
|
514
|
-
namespace = domain.id
|
515
|
-
# Catch errors
|
516
|
-
begin
|
517
|
-
application = domain.add_application(app_name,{:cartridge => app_type, :scale => true, :gear_profile => gear_size})
|
518
|
-
|
519
|
-
# Variables that are needed for the rest of the function
|
520
|
-
app_uuid = application.uuid
|
521
|
-
result = "Successfully created application: #{app_name}"
|
522
|
-
|
523
|
-
# health check path now returned by the API
|
524
|
-
health_check_path = application.health_check_path
|
525
|
-
|
526
|
-
puts "DEBUG: '#{app_name}' creation returned success." if @mydebug
|
527
|
-
rescue RHC::Rest::ConnectionException, RHC::Rest::ResourceAccessException => e
|
528
|
-
print_response_err(Struct::FakeResponse.new(e.message,e.code))
|
529
|
-
rescue RHC::Rest::ValidationException => e
|
530
|
-
validation_error_code = (e.code.nil?) ? 406 : e.code
|
531
|
-
print_response_err(Struct::FakeResponse.new(e.message, validation_error_code))
|
532
|
-
rescue RHC::Rest::ServerErrorException => e
|
533
|
-
error_code = (e.code.nil?) ? 500 : e.code
|
534
|
-
print_response_err(Struct::FakeResponse.new(e.message, error_code))
|
535
|
-
end
|
536
|
-
else
|
537
|
-
json_data = generate_json(data)
|
538
|
-
|
539
|
-
url = URI.parse("https://#{libra_server}/broker/cartridge")
|
540
|
-
response = http_post(net_http, url, json_data, password)
|
541
|
-
|
542
|
-
if response.code == '200'
|
543
|
-
json_resp = json_decode(response.body)
|
544
|
-
print_response_success(json_resp)
|
545
|
-
json_data = json_decode(json_resp['data'])
|
546
|
-
health_check_path = json_data['health_check_path']
|
547
|
-
app_uuid = json_data['uuid']
|
548
|
-
result = json_resp['result']
|
549
|
-
puts "DEBUG: '#{app_name}' creation returned success." if @mydebug
|
550
|
-
else
|
551
|
-
print_response_err(response)
|
552
|
-
end
|
553
|
-
end
|
554
|
-
|
555
|
-
#
|
556
|
-
# At this point, we need to register a handler to guarantee app
|
557
|
-
# cleanup on any exceptions or calls to exit
|
558
|
-
#
|
559
|
-
at_exit do
|
560
|
-
unless $!.nil? || $!.is_a?(SystemExit) && $!.success?
|
561
|
-
puts "Cleaning up application"
|
562
|
-
destroy_app(libra_server, net_http, app_name, rhlogin, password)
|
563
|
-
end
|
564
|
-
end
|
565
|
-
|
566
|
-
rhc_domain = user_info['user_info']['rhc_domain']
|
567
|
-
|
568
|
-
fqdn = "#{app_name}-#{namespace}.#{rhc_domain}"
|
569
|
-
|
570
|
-
loop = 0
|
571
|
-
#
|
572
|
-
# Confirm that the host exists in DNS
|
573
|
-
#
|
574
|
-
unless no_dns
|
575
|
-
puts "Now your new domain name is being propagated worldwide (this might take a minute)..."
|
576
|
-
|
577
|
-
# Allow DNS to propogate
|
578
|
-
sleep 15
|
579
|
-
|
580
|
-
# Now start checking for DNS
|
581
|
-
sleep_time = 2
|
582
|
-
while loop < MAX_RETRIES && !hostexist?(fqdn)
|
583
|
-
sleep sleep_time
|
584
|
-
loop+=1
|
585
|
-
print CLEAR_LINE + " retry # #{loop} - Waiting for DNS: #{fqdn}"
|
586
|
-
$stdout.flush
|
587
|
-
sleep_time = delay(sleep_time)
|
588
|
-
end
|
589
|
-
end
|
590
|
-
|
591
|
-
# if we have executed print statements, then move to the next line
|
592
|
-
if loop > 0
|
593
|
-
puts
|
594
|
-
end
|
595
|
-
|
596
|
-
# construct the Git URL
|
597
|
-
git_url = "ssh://#{app_uuid}@#{app_name}-#{namespace}.#{rhc_domain}/~/git/#{app_name}.git/"
|
598
|
-
|
599
|
-
# If the hostname couldn't be resolved, print out the git URL
|
600
|
-
# and exit cleanly. This will help solve issues where DNS times
|
601
|
-
# out in APAC, etc on resolution.
|
602
|
-
if loop >= MAX_RETRIES
|
603
|
-
puts <<WARNING
|
604
|
-
|
605
|
-
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
606
|
-
WARNING: We were unable to lookup your hostname (#{fqdn})
|
607
|
-
in a reasonable amount of time. This can happen periodically and will just
|
608
|
-
take an extra minute or two to propagate depending on where you are in the
|
609
|
-
world. Once you are able to access your application in a browser, you can then
|
610
|
-
clone your git repository.
|
611
|
-
|
612
|
-
Application URL: http://#{fqdn}
|
613
|
-
|
614
|
-
Git Repository URL: #{git_url}
|
615
|
-
|
616
|
-
Git Clone command:
|
617
|
-
git clone #{git_url} #{repo_dir}
|
618
|
-
|
619
|
-
If you can't get your application '#{app_name}' running in the browser, you can
|
620
|
-
also try destroying and recreating the application as well using:
|
621
|
-
|
622
|
-
rhc app destroy -a #{app_name} -l #{rhlogin}
|
623
|
-
|
624
|
-
If this doesn't work for you, let us know in the forums or in IRC and we'll
|
625
|
-
make sure to get you up and running.
|
626
|
-
|
627
|
-
Forums: https://openshift.redhat.com/community/forums/openshift
|
628
|
-
|
629
|
-
IRC: #openshift (on Freenode)
|
630
|
-
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
631
|
-
|
632
|
-
WARNING
|
633
|
-
exit 0
|
634
|
-
end
|
635
|
-
|
636
|
-
#
|
637
|
-
# Pull new repo locally
|
638
|
-
#
|
639
|
-
|
640
|
-
unless no_git
|
641
|
-
puts "Pulling new repo down" if @mydebug
|
642
|
-
|
643
|
-
quiet = (@mydebug ? ' ' : '--quiet ')
|
644
|
-
puts "git clone #{quiet}#{git_url} #{repo_dir}" if @mydebug
|
645
|
-
git_clone = %x[git clone #{quiet} #{git_url} #{repo_dir} 2>&1]
|
646
|
-
if $?.exitstatus != 0
|
647
|
-
|
648
|
-
if RHC::Helpers.windows?
|
649
|
-
|
650
|
-
`nslookup #{app_name}-#{namespace}.#{rhc_domain}`
|
651
|
-
windows_nslookup = $?.exitstatus == 0
|
652
|
-
`ping #{app_name}-#{namespace}.#{rhc_domain} -n 2`
|
653
|
-
windows_ping = $?.exitstatus == 0
|
654
|
-
|
655
|
-
if windows_nslookup and !windows_ping # this is related to BZ #826769
|
656
|
-
puts <<WINSOCKISSUE
|
657
|
-
|
658
|
-
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
659
|
-
WARNING: We were unable to lookup your hostname (#{fqdn})
|
660
|
-
in a reasonable amount of time. This can happen periodically and will just
|
661
|
-
take up to 10 extra minutes to propagate depending on where you are in the
|
662
|
-
world. This may also be related to an issue with Winsock on Windows [1][2].
|
663
|
-
We recommend you wait a few minutes then clone your git repository manually.
|
664
|
-
|
665
|
-
Git Clone command:
|
666
|
-
git clone #{git_url} #{repo_dir}
|
667
|
-
|
668
|
-
[1] http://support.microsoft.com/kb/299357
|
669
|
-
[2] http://support.microsoft.com/kb/811259
|
670
|
-
|
671
|
-
If this doesn't work for you, let us know in the forums or in IRC and we'll
|
672
|
-
make sure to get you up and running.
|
673
|
-
|
674
|
-
Forums: https://openshift.redhat.com/community/forums/openshift
|
675
|
-
|
676
|
-
IRC: #openshift (on Freenode)
|
677
|
-
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
678
|
-
|
679
|
-
WINSOCKISSUE
|
680
|
-
exit 0
|
681
|
-
end
|
682
|
-
end
|
683
|
-
puts "Error in git clone"
|
684
|
-
puts git_clone
|
685
|
-
exit 216
|
686
|
-
end
|
687
|
-
else
|
688
|
-
if is_embedded_jenkins
|
689
|
-
# if this is a jenkins client application to be embedded,
|
690
|
-
# then print this message only in debug mode
|
691
|
-
if @mydebug
|
692
|
-
puts "
|
693
|
-
Note: There is a git repo for your Jenkins application '#{app_name}'
|
694
|
-
but it isn't being downloaded as part of this process. In most cases
|
695
|
-
it isn't needed but you can always clone it later.
|
696
|
-
|
697
|
-
"
|
698
|
-
end
|
699
|
-
else
|
700
|
-
puts <<IMPORTANT
|
701
|
-
|
702
|
-
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
703
|
-
IMPORTANT: Since the -n flag was specified, no local repo has been created.
|
704
|
-
This means you can't make changes to your published application until after
|
705
|
-
you clone the repo yourself. See the git url below for more information.
|
706
|
-
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
707
|
-
|
708
|
-
IMPORTANT
|
709
|
-
end
|
710
|
-
end
|
711
|
-
|
712
|
-
#
|
713
|
-
# At this point, we need to register a handler to guarantee git
|
714
|
-
# repo cleanup on any exceptions or calls to exit
|
715
|
-
#
|
716
|
-
unless no_git
|
717
|
-
at_exit do
|
718
|
-
unless $!.nil? || $!.is_a?(SystemExit) && $!.success?
|
719
|
-
puts "Cleaning up git repo"
|
720
|
-
FileUtils.rm_rf repo_dir
|
721
|
-
end
|
722
|
-
end
|
723
|
-
end
|
724
|
-
return {:app_name => app_name,
|
725
|
-
:fqdn => fqdn,
|
726
|
-
:health_check_path => health_check_path,
|
727
|
-
:git_url => git_url,
|
728
|
-
:repo_dir => repo_dir,
|
729
|
-
:result => result
|
730
|
-
}
|
731
|
-
end
|
732
|
-
|
733
|
-
#
|
734
|
-
# An application is considered available if the health check URL unambiguously returns a 1 or 0.
|
735
|
-
# Otherwise, if the root URL for the app successfully returns content it is also considered
|
736
|
-
# successful. In the future, applications that do not expose a public web interface will need
|
737
|
-
# a more advanced check mechanism, or the check should not prevent creation.
|
738
|
-
#
|
739
|
-
def self.check_app_available(net_http, app_name, fqdn, health_check_path, result, git_url, repo_dir, no_git)
|
740
|
-
|
741
|
-
available = MAX_RETRIES.times.any? do |i|
|
742
|
-
sleep i * DEFAULT_DELAY
|
743
|
-
|
744
|
-
puts "Checking if the application is available ##{i+1}"
|
745
|
-
if health_check_path and !health_check_path.empty?
|
746
|
-
value = open("http://#{fqdn}/#{health_check_path}").read[0,1] rescue nil
|
747
|
-
# TODO: I should be typed exception ApplicationHealthFailure
|
748
|
-
raise "ERROR: The application was unable to start. Please report this issue via the forums or IRC or file a bug through our public bug tracker." if value == '0'
|
749
|
-
next true if value == '1'
|
750
|
-
end
|
751
|
-
open("http://#{fqdn}") rescue nil
|
752
|
-
end
|
753
|
-
|
754
|
-
if available
|
755
|
-
puts "Application #{app_name} is available at: http://#{fqdn}/"
|
756
|
-
puts " Git URL: #{git_url}"
|
757
|
-
|
758
|
-
if @mydebug
|
759
|
-
unless no_git
|
760
|
-
puts "To make changes to '#{app_name}', commit to #{repo_dir}/."
|
761
|
-
else
|
762
|
-
puts <<LOOKSGOOD
|
763
|
-
To make changes to '#{app_name}', you must first clone it with:
|
764
|
-
git clone #{git_url}
|
765
|
-
|
766
|
-
LOOKSGOOD
|
767
|
-
puts "Then run 'git push' to update your OpenShift space."
|
768
|
-
end
|
769
|
-
end
|
770
|
-
if result && !result.empty?
|
771
|
-
puts "#{result}"
|
772
|
-
end
|
773
|
-
true
|
774
|
-
else
|
775
|
-
puts "Application is not available"
|
776
|
-
false
|
777
|
-
end
|
778
|
-
rescue StandardError => e
|
779
|
-
puts e
|
780
|
-
false
|
781
|
-
end
|
782
|
-
|
783
|
-
def self.destroy_app(libra_server, net_http, app_name, rhlogin, password)
|
784
|
-
json_data = generate_json(
|
785
|
-
{:action => 'deconfigure',
|
786
|
-
:app_name => app_name,
|
787
|
-
:rhlogin => rhlogin
|
788
|
-
})
|
789
|
-
url = URI.parse("https://#{libra_server}/broker/cartridge")
|
790
|
-
http_post(net_http, url, json_data, password)
|
791
|
-
end
|
792
|
-
|
793
|
-
def self.ctl_app(libra_server, net_http, app_name, rhlogin, password, action, embedded=false, framework=nil, server_alias=nil, print_result=true)
|
794
|
-
data = {:action => action,
|
795
|
-
:app_name => app_name,
|
796
|
-
:rhlogin => rhlogin
|
797
|
-
}
|
798
|
-
|
799
|
-
data[:server_alias] = server_alias if server_alias
|
800
|
-
if framework
|
801
|
-
data[:cartridge] = framework
|
802
|
-
end
|
803
|
-
|
804
|
-
if @mydebug
|
805
|
-
data[:debug] = true
|
806
|
-
end
|
807
|
-
|
808
|
-
json_data = generate_json(data)
|
809
|
-
|
810
|
-
url = nil
|
811
|
-
if embedded
|
812
|
-
url = URI.parse("https://#{libra_server}/broker/embed_cartridge")
|
813
|
-
else
|
814
|
-
url = URI.parse("https://#{libra_server}/broker/cartridge")
|
815
|
-
end
|
816
|
-
response = http_post(net_http, url, json_data, password)
|
817
|
-
|
818
|
-
if response.code == '200'
|
819
|
-
json_resp = json_decode(response.body)
|
820
|
-
print_response_success(json_resp, print_result || @mydebug)
|
821
|
-
else
|
822
|
-
print_response_err(response)
|
823
|
-
end
|
824
|
-
json_decode(response.body)
|
825
|
-
end
|
826
|
-
|
827
|
-
def self.snapshot_create(rhc_domain, namespace, app_name, app_uuid, filename, debug=false)
|
828
|
-
|
829
|
-
ssh_cmd = "ssh #{app_uuid}@#{app_name}-#{namespace}.#{rhc_domain} 'snapshot' > #{filename}"
|
830
|
-
puts "Pulling down a snapshot to #{filename}..."
|
831
|
-
puts ssh_cmd if debug
|
832
|
-
puts
|
833
|
-
|
834
|
-
begin
|
835
|
-
|
836
|
-
if ! RHC::Helpers.windows?
|
837
|
-
output = `#{ssh_cmd}`
|
838
|
-
if $?.exitstatus != 0
|
839
|
-
puts output
|
840
|
-
puts "Error in trying to save snapshot. You can try to save manually by running:"
|
841
|
-
puts
|
842
|
-
puts ssh_cmd
|
843
|
-
puts
|
844
|
-
return 1
|
845
|
-
end
|
846
|
-
else
|
847
|
-
Net::SSH.start("#{app_name}-#{namespace}.#{rhc_domain}", app_uuid) do |ssh|
|
848
|
-
File.open(filename, 'wb') do |file|
|
849
|
-
ssh.exec! "snapshot" do |channel, stream, data|
|
850
|
-
if stream == :stdout
|
851
|
-
file.write(data)
|
852
|
-
else
|
853
|
-
puts data if debug
|
854
|
-
end
|
855
|
-
end
|
856
|
-
end
|
857
|
-
end
|
858
|
-
end
|
859
|
-
rescue Exception => e
|
860
|
-
puts e.backtrace if debug
|
861
|
-
puts "Error in trying to save snapshot. You can try to save manually by running:"
|
862
|
-
puts
|
863
|
-
puts ssh_cmd
|
864
|
-
puts
|
865
|
-
return 1
|
866
|
-
end
|
867
|
-
true
|
868
|
-
end
|
869
|
-
|
870
|
-
def self.snapshot_restore(rhc_domain, namespace, app_name, app_uuid, filename, debug=false)
|
871
|
-
if File.exists? filename
|
872
|
-
|
873
|
-
include_git = RHC::Helpers.windows? ? false : RHC::TarGz.contains(filename, './*/git')
|
874
|
-
|
875
|
-
ssh_cmd = "cat #{filename} | ssh #{app_uuid}@#{app_name}-#{namespace}.#{rhc_domain} 'restore#{include_git ? ' INCLUDE_GIT' : ''}'"
|
876
|
-
puts "Restoring from snapshot #{filename}..."
|
877
|
-
puts ssh_cmd if debug
|
878
|
-
puts
|
879
|
-
|
880
|
-
begin
|
881
|
-
if ! RHC::Helpers.windows?
|
882
|
-
output = `#{ssh_cmd}`
|
883
|
-
if $?.exitstatus != 0
|
884
|
-
puts output
|
885
|
-
puts "Error in trying to restore snapshot. You can try to restore manually by running:"
|
886
|
-
puts
|
887
|
-
puts ssh_cmd
|
888
|
-
puts
|
889
|
-
return 1
|
890
|
-
end
|
891
|
-
else
|
892
|
-
ssh = Net::SSH.start("#{app_name}-#{namespace}.#{rhc_domain}", app_uuid)
|
893
|
-
ssh.open_channel do |channel|
|
894
|
-
channel.exec("restore#{include_git ? ' INCLUDE_GIT' : ''}") do |ch, success|
|
895
|
-
channel.on_data do |ch, data|
|
896
|
-
puts data
|
897
|
-
end
|
898
|
-
channel.on_extended_data do |ch, type, data|
|
899
|
-
puts data
|
900
|
-
end
|
901
|
-
channel.on_close do |ch|
|
902
|
-
puts "Terminating..."
|
903
|
-
end
|
904
|
-
File.open(filename, 'rb') do |file|
|
905
|
-
file.chunk(1024) do |chunk|
|
906
|
-
channel.send_data chunk
|
907
|
-
end
|
908
|
-
end
|
909
|
-
channel.eof!
|
910
|
-
end
|
911
|
-
end
|
912
|
-
ssh.loop
|
913
|
-
end
|
914
|
-
rescue Exception => e
|
915
|
-
puts e.backtrace
|
916
|
-
puts "Error in trying to restore snapshot. You can try to restore manually by running:"
|
917
|
-
puts
|
918
|
-
puts ssh_cmd
|
919
|
-
puts
|
920
|
-
return 1
|
921
|
-
end
|
922
|
-
|
923
|
-
else
|
924
|
-
puts "Archive not found: #{filename}"
|
925
|
-
return 255
|
926
|
-
end
|
927
|
-
true
|
928
|
-
end
|
929
|
-
|
930
|
-
end
|
931
|
-
|
932
|
-
# provide a hook for performing actions before rhc-* commands exit
|
933
|
-
at_exit {
|
934
|
-
# ensure client tools are up to date
|
935
|
-
RHC::check_version
|
936
|
-
}
|
937
|
-
|
938
|
-
#
|
939
|
-
# Config paths... /etc/openshift/express.conf or $GEM/conf/express.conf -> ~/.openshift/express.conf
|
940
|
-
#
|
941
|
-
# semi-private: Just in case we rename again :)
|
942
|
-
@opts_config_path = nil
|
943
|
-
@conf_name = 'express.conf'
|
944
|
-
_linux_cfg = '/etc/openshift/' + @conf_name
|
945
|
-
_gem_cfg = File.join(File.expand_path(File.dirname(__FILE__) + "/../conf"), @conf_name)
|
946
|
-
@home_conf = File.expand_path('~/.openshift')
|
947
|
-
@local_config_path = File.join(@home_conf, @conf_name)
|
948
|
-
@config_path = File.exists?(_linux_cfg) ? _linux_cfg : _gem_cfg
|
949
|
-
@home_dir=File.expand_path("~")
|
950
|
-
|
951
|
-
local_config_path = File.expand_path(@local_config_path)
|
952
|
-
|
953
|
-
#
|
954
|
-
# Check for proxy environment
|
955
|
-
#
|
956
|
-
|
957
|
-
@http = RHC::Config.default_proxy
|
958
|
-
|
959
|
-
def config_path
|
960
|
-
return @opts_config_path ? @opts_config_path : @local_config_path
|
961
|
-
end
|
962
|
-
|
963
|
-
def config
|
964
|
-
return @opts_config ? @opts_config : @local_config
|
965
|
-
end
|
966
|
-
|
967
|
-
def ask_password
|
968
|
-
return ask("Password: ") { |q|
|
969
|
-
q.echo = '*'
|
970
|
-
q.whitespace = :chomp
|
971
|
-
}
|
972
|
-
end
|
973
|
-
|
974
|
-
def kfile_not_found
|
975
|
-
puts <<KFILE_NOT_FOUND
|
976
|
-
Your SSH keys are created either by running ssh-keygen (password optional)
|
977
|
-
or by having the 'rhc domain create' command do it for you. If you created
|
978
|
-
them on your own (or want to use an existing keypair), be sure to paste
|
979
|
-
your public key into the express console at http://www.openshift.com.
|
980
|
-
The client tools use the value of 'ssh_key_file' in express.conf to find
|
981
|
-
your key followed by the defaults of id_rsa[.pub] and then
|
982
|
-
id_rsa[.pub].
|
983
|
-
KFILE_NOT_FOUND
|
984
|
-
|
985
|
-
#exit 212
|
986
|
-
end
|
987
|
-
|
988
|
-
def get_kfile(check_exists=true)
|
989
|
-
ssh_key_file = get_var('ssh_key_file')
|
990
|
-
if ssh_key_file
|
991
|
-
if (File.basename(ssh_key_file) == ssh_key_file)
|
992
|
-
kfile = "#{ENV['HOME']}/.ssh/#{ssh_key_file}"
|
993
|
-
else
|
994
|
-
kfile = File.expand_path(ssh_key_file)
|
995
|
-
end
|
996
|
-
else
|
997
|
-
kfile = "#{ENV['HOME']}/.ssh/id_rsa"
|
998
|
-
end
|
999
|
-
if check_exists && !File.exists?(kfile)
|
1000
|
-
if ssh_key_file
|
1001
|
-
puts "WARNING: Unable to find '#{kfile}' referenced in express.conf."
|
1002
|
-
kfile_not_found
|
1003
|
-
else
|
1004
|
-
kfile = "#{ENV['HOME']}/.ssh/id_rsa"
|
1005
|
-
if !File.exists?(kfile)
|
1006
|
-
puts "WARNING: Unable to find ssh key file."
|
1007
|
-
kfile_not_found
|
1008
|
-
end
|
1009
|
-
end
|
1010
|
-
end
|
1011
|
-
return kfile
|
1012
|
-
end
|
1013
|
-
|
1014
|
-
def get_kpfile(kfile, check_exists=true)
|
1015
|
-
kpfile = kfile + '.pub'
|
1016
|
-
if check_exists && !File.exists?(kpfile)
|
1017
|
-
puts "WARNING: Unable to find '#{kpfile}'"
|
1018
|
-
kfile_not_found
|
1019
|
-
end
|
1020
|
-
return kpfile
|
1021
|
-
end
|
1022
|
-
|
1023
|
-
# Add a new namespace to configs
|
1024
|
-
def self.add_rhlogin_config(rhlogin, uuid)
|
1025
|
-
config_path = RHC::Config.local_config_path
|
1026
|
-
f = open(File.expand_path(config_path), 'a')
|
1027
|
-
unless RHC::Config['default_rhlogin']
|
1028
|
-
f.puts("# Default rhlogin to use if none is specified")
|
1029
|
-
f.puts("default_rhlogin=#{rhlogin}")
|
1030
|
-
f.puts("")
|
1031
|
-
end
|
1032
|
-
f.close
|
1033
|
-
end
|
1034
|
-
|
1035
|
-
# Public: Handle response message when updating keys
|
1036
|
-
#
|
1037
|
-
# url - The Object URI::HTTPS
|
1038
|
-
# data - The Hash representation of the data response
|
1039
|
-
# password - The String password for the user
|
1040
|
-
#
|
1041
|
-
# Examples
|
1042
|
-
#
|
1043
|
-
# handle_key_mgmt_response(
|
1044
|
-
# URI.parse('https://openshift.redhat.com/broker/ssh_keys'),
|
1045
|
-
# {
|
1046
|
-
# :rhlogin=>"rhnlogin@example.com",
|
1047
|
-
# :key_name=>"default",
|
1048
|
-
# :action=>"update-key",
|
1049
|
-
# :ssh=>"AAAAB3NzaC1yc2EAAAADAQABAAAAgQCrXG5c.....",
|
1050
|
-
# :key_type=>"ssh-rsa"},
|
1051
|
-
# 'mypass')
|
1052
|
-
# # => nil
|
1053
|
-
#
|
1054
|
-
# Returns nil on Success and RHC::http object on failure
|
1055
|
-
def handle_key_mgmt_response(url, data, password)
|
1056
|
-
RHC::print_post_data(data)
|
1057
|
-
json_data = RHC::generate_json(data)
|
1058
|
-
|
1059
|
-
response = RHC::http_post(RHC::Config.default_proxy, url, json_data, password)
|
1060
|
-
|
1061
|
-
if response.code == '200'
|
1062
|
-
begin
|
1063
|
-
json_resp = RHC::json_decode(response.body)
|
1064
|
-
RHC::update_server_api_v(json_resp)
|
1065
|
-
RHC::print_response_success(json_resp)
|
1066
|
-
puts "Success"
|
1067
|
-
return
|
1068
|
-
rescue RHC::JsonError
|
1069
|
-
RHC::print_response_err(response)
|
1070
|
-
end
|
1071
|
-
else
|
1072
|
-
RHC::print_response_err(response)
|
1073
|
-
end
|
1074
|
-
puts "Failure"
|
1075
|
-
return response
|
1076
|
-
end
|
1077
|
-
|
1078
|
-
# Public: Add or upload an ssh key
|
1079
|
-
#
|
1080
|
-
# type - The String type RSA or DSS.
|
1081
|
-
# command - The String value 'add' or 'update'
|
1082
|
-
# identifier - The String value to identify the key
|
1083
|
-
# pub_key_file_path - The String file path of the public key
|
1084
|
-
# rhlogin - The String login to the broker
|
1085
|
-
# password- The String password for the user
|
1086
|
-
#
|
1087
|
-
# Examples
|
1088
|
-
#
|
1089
|
-
# generate_ssh_key_ruby('add', 'newkeyname', '~/.ssh/id_rsa',
|
1090
|
-
# 'mylogin', 'mypass')
|
1091
|
-
# # => /home/user/.ssh/id_rsa.pub
|
1092
|
-
#
|
1093
|
-
# Returns nil on success or HTTP object on failure
|
1094
|
-
def add_or_update_key(command, identifier, pub_key_file_path, rhlogin, password)
|
1095
|
-
|
1096
|
-
# Read user public ssh key
|
1097
|
-
if pub_key_file_path
|
1098
|
-
if File.readable?(pub_key_file_path)
|
1099
|
-
begin
|
1100
|
-
ssh_keyfile_contents = File.open(pub_key_file_path).gets.chomp.split(' ')
|
1101
|
-
ssh_key = ssh_keyfile_contents[1]
|
1102
|
-
ssh_key_type = ssh_keyfile_contents[0]
|
1103
|
-
rescue Exception => e
|
1104
|
-
puts "Invalid public keyfile format! Please specify a valid user public keyfile."
|
1105
|
-
exit 1
|
1106
|
-
end
|
1107
|
-
else
|
1108
|
-
puts "Unable to read user public keyfile #{pub_key_file_path}"
|
1109
|
-
exit 1
|
1110
|
-
end
|
1111
|
-
else # create key
|
1112
|
-
key_name = identifier
|
1113
|
-
puts "Generating ssh key pair for user '#{key_name}' in the dir '#{Dir.pwd}/'"
|
1114
|
-
# REMOVED in favor of generate_ssh_key_ruby: system("ssh-keygen -t rsa -f '#{key_name}'")
|
1115
|
-
ssh_pub_key_file = generate_ssh_key_ruby()
|
1116
|
-
ssh_keyfile_contents = File.open(ssh_pub_key_file).gets.chomp.split(' ')
|
1117
|
-
ssh_key = ssh_keyfile_contents[1]
|
1118
|
-
ssh_key_type = ssh_keyfile_contents[0]
|
1119
|
-
end
|
1120
|
-
|
1121
|
-
data = {}
|
1122
|
-
data[:rhlogin] = rhlogin
|
1123
|
-
data[:key_name] = identifier
|
1124
|
-
data[:ssh] = ssh_key
|
1125
|
-
data[:action] = 'add-key'
|
1126
|
-
data[:key_type] = ssh_key_type
|
1127
|
-
|
1128
|
-
if command == 'add'
|
1129
|
-
data[:action] = 'add-key'
|
1130
|
-
elsif command == 'update'
|
1131
|
-
data[:action] = 'update-key'
|
1132
|
-
end
|
1133
|
-
|
1134
|
-
url = URI.parse("https://#{RHC::Config['libra_server']}/broker/ssh_keys")
|
1135
|
-
handle_key_mgmt_response(url, data, password)
|
1136
|
-
end
|
1137
|
-
|
1138
|
-
|
1139
|
-
# Public: Generate an SSH key and store it in ~/.ssh/id_rsa
|
1140
|
-
#
|
1141
|
-
# type - The String type RSA or DSS.
|
1142
|
-
# bits - The Integer value for number of bits.
|
1143
|
-
# comment - The String comment for the key
|
1144
|
-
#
|
1145
|
-
# Examples
|
1146
|
-
#
|
1147
|
-
# generate_ssh_key_ruby()
|
1148
|
-
# # => /home/user/.ssh/id_rsa.pub
|
1149
|
-
#
|
1150
|
-
# Returns nil on failure or public key location as a String on success
|
1151
|
-
def generate_ssh_key_ruby(type="RSA", bits = 1024, comment = "OpenShift-Key")
|
1152
|
-
key = RHC::Vendor::SSHKey.generate(:type => type,
|
1153
|
-
:bits => bits,
|
1154
|
-
:comment => comment)
|
1155
|
-
ssh_dir = "#{RHC::Config.home_dir}/.ssh"
|
1156
|
-
if File.exists?("#{ssh_dir}/id_rsa")
|
1157
|
-
puts "SSH key already exists: #{ssh_dir}/id_rsa. Reusing..."
|
1158
|
-
return nil
|
1159
|
-
else
|
1160
|
-
unless File.exists?(ssh_dir)
|
1161
|
-
FileUtils.mkdir_p(ssh_dir)
|
1162
|
-
File.chmod(0700, ssh_dir)
|
1163
|
-
end
|
1164
|
-
File.open("#{ssh_dir}/id_rsa", 'w') {|f| f.write(key.private_key)}
|
1165
|
-
File.chmod(0600, "#{ssh_dir}/id_rsa")
|
1166
|
-
File.open("#{ssh_dir}/id_rsa.pub", 'w') {|f| f.write(key.ssh_public_key)}
|
1167
|
-
end
|
1168
|
-
"#{ssh_dir}/id_rsa.pub"
|
1169
|
-
end
|
1170
|
-
|
1171
|
-
# Public: Run ssh command on remote host
|
1172
|
-
#
|
1173
|
-
# host - The String of the remote hostname to ssh to.
|
1174
|
-
# username - The String username of the remote user to ssh as.
|
1175
|
-
# command - The String command to run on the remote host.
|
1176
|
-
#
|
1177
|
-
# Examples
|
1178
|
-
#
|
1179
|
-
# ssh_ruby('myapp-t.rhcloud.com',
|
1180
|
-
# '109745632b514e9590aa802ec015b074',
|
1181
|
-
# 'rhcsh tail -f $OPENSHIFT_LOG_DIR/*"')
|
1182
|
-
# # => true
|
1183
|
-
#
|
1184
|
-
# Returns true on success
|
1185
|
-
def ssh_ruby(host, username, command)
|
1186
|
-
Net::SSH.start(host, username) do |session|
|
1187
|
-
session.open_channel do |channel|
|
1188
|
-
channel.request_pty do |ch, success|
|
1189
|
-
puts "pty could not be obtained" unless success
|
1190
|
-
end
|
1191
|
-
|
1192
|
-
channel.on_data do |ch, data|
|
1193
|
-
#puts "[#{file}] -> #{data}"
|
1194
|
-
puts data
|
1195
|
-
end
|
1196
|
-
channel.exec command
|
1197
|
-
end
|
1198
|
-
session.loop
|
1199
|
-
end
|
1200
|
-
end
|
1201
|
-
|
1202
|
-
# Public: legacy convinience function for getting config keys
|
1203
|
-
def get_var(key)
|
1204
|
-
RHC::Config[key]
|
1205
|
-
end
|