rhc 1.30.3 → 1.31.5
Sign up to get free protection for your applications and to get access to all the features.
- data/autocomplete/rhc_bash +28 -4
- data/lib/rhc/commands/app.rb +15 -0
- data/lib/rhc/commands/git_clone.rb +1 -1
- data/lib/rhc/commands/ssh.rb +1 -1
- data/lib/rhc/exceptions.rb +6 -0
- data/lib/rhc/git_helpers.rb +37 -14
- data/lib/rhc/helpers.rb +63 -1
- data/lib/rhc/rest/application.rb +5 -0
- data/lib/rhc/rest/client.rb +10 -0
- data/lib/rhc/rest/mock.rb +17 -5
- data/lib/rhc/ssh_helpers.rb +47 -20
- data/lib/rhc/wizard.rb +11 -14
- data/spec/rhc/commands/app_spec.rb +69 -2
- data/spec/rhc/commands/git_clone_spec.rb +35 -2
- data/spec/rhc/commands/scp_spec.rb +5 -0
- data/spec/rhc/commands/setup_spec.rb +2 -1
- data/spec/rhc/commands/snapshot_spec.rb +8 -2
- data/spec/rhc/commands/ssh_spec.rb +7 -2
- data/spec/rhc/wizard_spec.rb +82 -45
- data/spec/spec_helper.rb +4 -1
- metadata +13 -5
data/autocomplete/rhc_bash
CHANGED
@@ -10,9 +10,9 @@ _rhc()
|
|
10
10
|
if [[ "$cur" == -* ]]; then
|
11
11
|
opts="--always-prefix --clean --config --debug --header --insecure --limit --mock --noprompt --password --raw --rhlogin --server --ssl-ca-file --ssl-client-cert-file --ssl-client-key-file --ssl-version --timeout --token"
|
12
12
|
elif [ -z $cur ]; then
|
13
|
-
opts="account alias alias-add alias-delete-cert alias-list alias-remove alias-update-cert app app-configure app-create app-delete app-deploy app-force-stop app-reload app-restart app-scale-down app-scale-up app-show app-start app-stop app-tidy apps authorization authorization-add authorization-delete authorization-delete-all authorization-list cartridge cartridge-add cartridge-list cartridge-reload cartridge-remove cartridge-restart cartridge-scale cartridge-show cartridge-start cartridge-status cartridge-stop cartridge-storage deployment deployment-activate deployment-list deployment-show domain domain-configure domain-create domain-delete domain-leave domain-list domain-rename domain-show env env-list env-set env-show env-unset git-clone help logout member member-add member-list member-remove member-update port-forward region region-list scp server server-add server-configure server-list server-remove server-show server-status server-use setup snapshot snapshot-restore snapshot-save ssh sshkey sshkey-add sshkey-list sshkey-remove sshkey-show tail team team-create team-delete team-leave team-list team-show threaddump"
|
13
|
+
opts="account alias alias-add alias-delete-cert alias-list alias-remove alias-update-cert app app-configure app-create app-delete app-deploy app-enable-ha app-force-stop app-reload app-restart app-scale-down app-scale-up app-show app-start app-stop app-tidy apps authorization authorization-add authorization-delete authorization-delete-all authorization-list cartridge cartridge-add cartridge-list cartridge-reload cartridge-remove cartridge-restart cartridge-scale cartridge-show cartridge-start cartridge-status cartridge-stop cartridge-storage deployment deployment-activate deployment-list deployment-show domain domain-configure domain-create domain-delete domain-leave domain-list domain-rename domain-show env env-list env-set env-show env-unset git-clone help logout member member-add member-list member-remove member-update port-forward region region-list scp server server-add server-configure server-list server-remove server-show server-status server-use setup snapshot snapshot-restore snapshot-save ssh sshkey sshkey-add sshkey-list sshkey-remove sshkey-show tail team team-create team-delete team-leave team-list team-show threaddump"
|
14
14
|
else
|
15
|
-
opts="account account-logout activate-deployment add-alias add-authorization add-cartridge add-member add-server add-sshkey alias alias-add alias-delete-cert alias-list alias-remove alias-update-cert aliases app app-configure app-create app-delete app-deploy app-env app-force-stop app-reload app-restart app-scale-down app-scale-up app-scp app-show app-snapshot app-ssh app-start app-stop app-tidy apps authorization authorization-add authorization-delete authorization-delete-all authorization-list authorizations cartridge cartridge-add cartridge-list cartridge-reload cartridge-remove cartridge-restart cartridge-scale cartridge-show cartridge-start cartridge-status cartridge-stop cartridge-storage cartridges configure-app configure-domain configure-server create-app create-domain create-team delete-all-authorization delete-app delete-authorization delete-cert-alias delete-domain delete-team deploy deploy-app deployment deployment-activate deployment-list deployment-show deployments domain domain-configure domain-create domain-delete domain-leave domain-list domain-rename domain-show domains env env-add env-list env-remove env-set env-show env-unset envs force-stop-app git-clone help leave-domain leave-team list-alias list-authorization list-cartridge list-deployment list-domain list-env list-member list-region list-server list-sshkey list-team logout member member-add member-list member-remove member-update members port-forward region region-list regions reload-app reload-cartridge remove-alias remove-cartridge remove-member remove-server remove-sshkey rename-domain restart-app restart-cartridge restore-snapshot save-snapshot scale-cartridge scale-down-app scale-up-app scp server server-add server-configure server-list server-remove server-show server-status server-use servers set-env setup show-app show-cartridge show-deployment show-domain show-env show-server show-sshkey show-team snapshot snapshot-restore snapshot-save ssh sshkey sshkey-add sshkey-list sshkey-remove sshkey-show sshkeys start-app start-cartridge status-cartridge status-server stop-app stop-cartridge storage-cartridge tail team team-create team-delete team-leave team-list team-show teams threaddump tidy-app unset-env update-cert-alias update-member use-server"
|
15
|
+
opts="account account-logout activate-deployment add-alias add-authorization add-cartridge add-member add-server add-sshkey alias alias-add alias-delete-cert alias-list alias-remove alias-update-cert aliases app app-configure app-create app-delete app-deploy app-enable-ha app-env app-force-stop app-reload app-restart app-scale-down app-scale-up app-scp app-show app-snapshot app-ssh app-start app-stop app-tidy apps authorization authorization-add authorization-delete authorization-delete-all authorization-list authorizations cartridge cartridge-add cartridge-list cartridge-reload cartridge-remove cartridge-restart cartridge-scale cartridge-show cartridge-start cartridge-status cartridge-stop cartridge-storage cartridges configure-app configure-domain configure-server create-app create-domain create-team delete-all-authorization delete-app delete-authorization delete-cert-alias delete-domain delete-team deploy deploy-app deployment deployment-activate deployment-list deployment-show deployments domain domain-configure domain-create domain-delete domain-leave domain-list domain-rename domain-show domains enable-ha-app env env-add env-list env-remove env-set env-show env-unset envs force-stop-app git-clone help leave-domain leave-team list-alias list-authorization list-cartridge list-deployment list-domain list-env list-member list-region list-server list-sshkey list-team logout member member-add member-list member-remove member-update members port-forward region region-list regions reload-app reload-cartridge remove-alias remove-cartridge remove-member remove-server remove-sshkey rename-domain restart-app restart-cartridge restore-snapshot save-snapshot scale-cartridge scale-down-app scale-up-app scp server server-add server-configure server-list server-remove server-show server-status server-use servers set-env setup show-app show-cartridge show-deployment show-domain show-env show-server show-sshkey show-team snapshot snapshot-restore snapshot-save ssh sshkey sshkey-add sshkey-list sshkey-remove sshkey-show sshkeys start-app start-cartridge status-cartridge status-server stop-app stop-cartridge storage-cartridge tail team team-create team-delete team-leave team-list team-show teams threaddump tidy-app unset-env update-cert-alias update-member use-server"
|
16
16
|
fi
|
17
17
|
else
|
18
18
|
prev="${COMP_WORDS[@]:0:COMP_CWORD}"
|
@@ -200,7 +200,7 @@ _rhc()
|
|
200
200
|
if [[ "$cur" == -* ]]; then
|
201
201
|
opts=""
|
202
202
|
else
|
203
|
-
opts="configure create delete deploy env force-stop reload restart scale-down scale-up show snapshot start stop tidy"
|
203
|
+
opts="configure create delete deploy enable-ha env force-stop reload restart scale-down scale-up show snapshot start stop tidy"
|
204
204
|
fi
|
205
205
|
;;
|
206
206
|
|
@@ -236,6 +236,14 @@ _rhc()
|
|
236
236
|
fi
|
237
237
|
;;
|
238
238
|
|
239
|
+
"rhc app enable-ha")
|
240
|
+
if [[ "$cur" == -* ]]; then
|
241
|
+
opts="--app --application-id --namespace"
|
242
|
+
else
|
243
|
+
opts=""
|
244
|
+
fi
|
245
|
+
;;
|
246
|
+
|
239
247
|
"rhc app env")
|
240
248
|
if [[ "$cur" == -* ]]; then
|
241
249
|
opts="--app --application-id --confirm --env --namespace"
|
@@ -372,6 +380,14 @@ _rhc()
|
|
372
380
|
fi
|
373
381
|
;;
|
374
382
|
|
383
|
+
"rhc app-enable-ha")
|
384
|
+
if [[ "$cur" == -* ]]; then
|
385
|
+
opts="--app --application-id --namespace"
|
386
|
+
else
|
387
|
+
opts=""
|
388
|
+
fi
|
389
|
+
;;
|
390
|
+
|
375
391
|
"rhc app-env")
|
376
392
|
if [[ "$cur" == -* ]]; then
|
377
393
|
opts="--app --application-id --confirm --env --namespace"
|
@@ -1060,6 +1076,14 @@ _rhc()
|
|
1060
1076
|
fi
|
1061
1077
|
;;
|
1062
1078
|
|
1079
|
+
"rhc enable-ha-app")
|
1080
|
+
if [[ "$cur" == -* ]]; then
|
1081
|
+
opts="--app --application-id --namespace"
|
1082
|
+
else
|
1083
|
+
opts=""
|
1084
|
+
fi
|
1085
|
+
;;
|
1086
|
+
|
1063
1087
|
"rhc env")
|
1064
1088
|
if [[ "$cur" == -* ]]; then
|
1065
1089
|
opts=""
|
@@ -1192,7 +1216,7 @@ _rhc()
|
|
1192
1216
|
if [[ "$cur" == -* ]]; then
|
1193
1217
|
opts=""
|
1194
1218
|
else
|
1195
|
-
opts="account account-logout activate-deployment add-alias add-authorization add-cartridge add-member add-server add-sshkey alias alias-add alias-delete-cert alias-list alias-remove alias-update-cert aliases app app-configure app-create app-delete app-deploy app-env app-force-stop app-reload app-restart app-scale-down app-scale-up app-scp app-show app-snapshot app-ssh app-start app-stop app-tidy apps authorization authorization-add authorization-delete authorization-delete-all authorization-list authorizations cartridge cartridge-add cartridge-list cartridge-reload cartridge-remove cartridge-restart cartridge-scale cartridge-show cartridge-start cartridge-status cartridge-stop cartridge-storage cartridges configure-app configure-domain configure-server create-app create-domain create-team delete-all-authorization delete-app delete-authorization delete-cert-alias delete-domain delete-team deploy deploy-app deployment deployment-activate deployment-list deployment-show deployments domain domain-configure domain-create domain-delete domain-leave domain-list domain-rename domain-show domains env env-add env-list env-remove env-set env-show env-unset envs force-stop-app git-clone leave-domain leave-team list-alias list-authorization list-cartridge list-deployment list-domain list-env list-member list-region list-server list-sshkey list-team logout member member-add member-list member-remove member-update members port-forward region region-list regions reload-app reload-cartridge remove-alias remove-cartridge remove-member remove-server remove-sshkey rename-domain restart-app restart-cartridge restore-snapshot save-snapshot scale-cartridge scale-down-app scale-up-app scp server server-add server-configure server-list server-remove server-show server-status server-use servers set-env setup show-app show-cartridge show-deployment show-domain show-env show-server show-sshkey show-team snapshot snapshot-restore snapshot-save ssh sshkey sshkey-add sshkey-list sshkey-remove sshkey-show sshkeys start-app start-cartridge status-cartridge status-server stop-app stop-cartridge storage-cartridge tail team team-create team-delete team-leave team-list team-show teams threaddump tidy-app unset-env update-cert-alias update-member use-server"
|
1219
|
+
opts="account account-logout activate-deployment add-alias add-authorization add-cartridge add-member add-server add-sshkey alias alias-add alias-delete-cert alias-list alias-remove alias-update-cert aliases app app-configure app-create app-delete app-deploy app-enable-ha app-env app-force-stop app-reload app-restart app-scale-down app-scale-up app-scp app-show app-snapshot app-ssh app-start app-stop app-tidy apps authorization authorization-add authorization-delete authorization-delete-all authorization-list authorizations cartridge cartridge-add cartridge-list cartridge-reload cartridge-remove cartridge-restart cartridge-scale cartridge-show cartridge-start cartridge-status cartridge-stop cartridge-storage cartridges configure-app configure-domain configure-server create-app create-domain create-team delete-all-authorization delete-app delete-authorization delete-cert-alias delete-domain delete-team deploy deploy-app deployment deployment-activate deployment-list deployment-show deployments domain domain-configure domain-create domain-delete domain-leave domain-list domain-rename domain-show domains enable-ha-app env env-add env-list env-remove env-set env-show env-unset envs force-stop-app git-clone leave-domain leave-team list-alias list-authorization list-cartridge list-deployment list-domain list-env list-member list-region list-server list-sshkey list-team logout member member-add member-list member-remove member-update members port-forward region region-list regions reload-app reload-cartridge remove-alias remove-cartridge remove-member remove-server remove-sshkey rename-domain restart-app restart-cartridge restore-snapshot save-snapshot scale-cartridge scale-down-app scale-up-app scp server server-add server-configure server-list server-remove server-show server-status server-use servers set-env setup show-app show-cartridge show-deployment show-domain show-env show-server show-sshkey show-team snapshot snapshot-restore snapshot-save ssh sshkey sshkey-add sshkey-list sshkey-remove sshkey-show sshkeys start-app start-cartridge status-cartridge status-server stop-app stop-cartridge storage-cartridge tail team team-create team-delete team-leave team-list team-show teams threaddump tidy-app unset-env update-cert-alias update-member use-server"
|
1196
1220
|
fi
|
1197
1221
|
;;
|
1198
1222
|
|
data/lib/rhc/commands/app.rb
CHANGED
@@ -115,6 +115,11 @@ module RHC::Commands
|
|
115
115
|
scaling = from_app.scalable if scaling.nil?
|
116
116
|
region = from_app.region if region.nil?
|
117
117
|
|
118
|
+
if region.present? && !rest_client.allows_region_selection?
|
119
|
+
region = nil
|
120
|
+
warn 'Server does not allow selecting regions. Region is being ignored.'
|
121
|
+
end
|
122
|
+
|
118
123
|
cartridges = from_app.cartridges.reject{|c| c.tags.include?('web_proxy')}.collect do |cartridge|
|
119
124
|
{
|
120
125
|
:name => (cartridge.name if !cartridge.custom?),
|
@@ -356,6 +361,16 @@ module RHC::Commands
|
|
356
361
|
0
|
357
362
|
end
|
358
363
|
|
364
|
+
summary "Make the application highly available"
|
365
|
+
syntax "<app> [--namespace NAME]"
|
366
|
+
takes_application :argument => true
|
367
|
+
def enable_ha(app)
|
368
|
+
app_action :enable_ha
|
369
|
+
|
370
|
+
results { say "#{app} is now highly available" }
|
371
|
+
0
|
372
|
+
end
|
373
|
+
|
359
374
|
summary "Show information about an application"
|
360
375
|
description <<-DESC
|
361
376
|
Display the properties of an application, including its URL, the SSH
|
@@ -23,7 +23,7 @@ module RHC::Commands
|
|
23
23
|
|
24
24
|
0
|
25
25
|
else
|
26
|
-
error "You do not have git installed. In order to fully interact with OpenShift you will need to install and configure a git client."
|
26
|
+
error "You do not have git installed. In order to fully interact with OpenShift you will need to install and configure a git client.#{RHC::Helpers.windows? ? ' We recommend this free application: Git for Windows - a basic git command line and GUI client http://msysgit.github.io/.' : ''}"
|
27
27
|
2
|
28
28
|
end
|
29
29
|
end
|
data/lib/rhc/commands/ssh.rb
CHANGED
@@ -39,7 +39,7 @@ module RHC::Commands
|
|
39
39
|
|
40
40
|
debug "Using user specified SSH: #{options.ssh}" if options.ssh
|
41
41
|
|
42
|
-
command_line = [
|
42
|
+
command_line = [RHC::Helpers.split_path(ssh), ('-vvv' if debug?), rest_app.ssh_string.to_s, command].flatten.compact
|
43
43
|
|
44
44
|
debug "Invoking Kernel.exec with #{command_line.inspect}"
|
45
45
|
Kernel.send(:exec, *command_line)
|
data/lib/rhc/exceptions.rb
CHANGED
data/lib/rhc/git_helpers.rb
CHANGED
@@ -7,18 +7,41 @@ module RHC
|
|
7
7
|
"git"
|
8
8
|
end
|
9
9
|
|
10
|
-
def git_version
|
11
|
-
|
10
|
+
def git_version(cmd=discover_git_executable)
|
11
|
+
`"#{cmd}" --version 2>&1`.strip
|
12
12
|
end
|
13
13
|
|
14
14
|
def has_git?
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
discover_git_executable.present?
|
16
|
+
end
|
17
|
+
|
18
|
+
# try my best to discover a git executable
|
19
|
+
def discover_git_executable
|
20
|
+
@git_executable ||= begin
|
21
|
+
guessing_locations = [git_cmd]
|
22
|
+
|
23
|
+
#:nocov:
|
24
|
+
if RHC::Helpers.windows?
|
25
|
+
guessing_locations <<
|
26
|
+
discover_windows_executables do |base|
|
27
|
+
[
|
28
|
+
"git.exe",
|
29
|
+
"#{base}\\Git\\bin\\git.exe",
|
30
|
+
"#{base}\\git.exe",
|
31
|
+
]
|
32
|
+
end
|
21
33
|
end
|
34
|
+
|
35
|
+
# make sure commands can be executed and finally pick the first one
|
36
|
+
guessing_locations.flatten.uniq.select do |cmd|
|
37
|
+
((File.exist?(cmd) && File.executable?(cmd)) || exe?(cmd)) &&
|
38
|
+
(begin
|
39
|
+
git_version(cmd)
|
40
|
+
$?.success?
|
41
|
+
rescue ; false ; end)
|
42
|
+
end.collect{|cmd| cmd =~ / / ? '"' + cmd + '"' : cmd}.first
|
43
|
+
#:nocov:
|
44
|
+
end
|
22
45
|
end
|
23
46
|
|
24
47
|
def git_clone_deploy_hooks(repo_dir)
|
@@ -50,18 +73,18 @@ module RHC
|
|
50
73
|
dir
|
51
74
|
end
|
52
75
|
|
76
|
+
# :nocov: These all call external binaries so test them in cucumber
|
53
77
|
def git_remote_add(remote_name, remote_url)
|
54
|
-
cmd = "#{
|
78
|
+
cmd = "#{discover_git_executable} remote add upstream \"#{remote_url}\""
|
55
79
|
debug "Running #{cmd} 2>&1"
|
56
80
|
output = %x[#{cmd} 2>&1]
|
57
81
|
raise RHC::GitException, "Error while adding upstream remote - #{output}" unless output.empty?
|
58
82
|
end
|
59
83
|
|
60
|
-
# :nocov: These all call external binaries so test them in cucumber
|
61
84
|
def git_config_get(key)
|
62
85
|
return nil unless has_git?
|
63
86
|
|
64
|
-
config_get_cmd = "#{
|
87
|
+
config_get_cmd = "#{discover_git_executable} config --get #{key}"
|
65
88
|
value = %x[#{config_get_cmd}].strip
|
66
89
|
debug "Git config '#{config_get_cmd}' returned '#{value}'"
|
67
90
|
value = nil if $?.exitstatus != 0 or value.empty?
|
@@ -70,8 +93,8 @@ module RHC
|
|
70
93
|
end
|
71
94
|
|
72
95
|
def git_config_set(key, value)
|
73
|
-
unset_cmd = "#{
|
74
|
-
config_cmd = "#{
|
96
|
+
unset_cmd = "#{discover_git_executable} config --unset-all #{key}"
|
97
|
+
config_cmd = "#{discover_git_executable} config --add #{key} #{value}"
|
75
98
|
debug "Adding #{key} = #{value} to git config"
|
76
99
|
commands = [unset_cmd, config_cmd]
|
77
100
|
commands.each do |cmd|
|
@@ -85,7 +108,7 @@ module RHC
|
|
85
108
|
def git_clone_repo(git_url, repo_dir)
|
86
109
|
# quote the repo to avoid input injection risk
|
87
110
|
destination = (repo_dir ? " \"#{repo_dir}\"" : "")
|
88
|
-
cmd = "#{
|
111
|
+
cmd = "#{discover_git_executable} clone #{git_url}#{destination}"
|
89
112
|
debug "Running #{cmd}"
|
90
113
|
|
91
114
|
status, stdout, stderr = run_with_tee(cmd)
|
data/lib/rhc/helpers.rb
CHANGED
@@ -4,7 +4,7 @@ require 'rhc/config'
|
|
4
4
|
require 'rhc/output_helpers'
|
5
5
|
require 'rhc/server_helpers'
|
6
6
|
require 'rbconfig'
|
7
|
-
|
7
|
+
require 'csv'
|
8
8
|
require 'resolv'
|
9
9
|
|
10
10
|
OptionParser.accept(URI) {|s,| URI.parse(s) if s}
|
@@ -517,6 +517,68 @@ module RHC
|
|
517
517
|
s.is_a?(String) ? !!(s =~ /^(true|t|yes|y|1)$/i) : s
|
518
518
|
end
|
519
519
|
|
520
|
+
# split spaces but preserve sentences between quotes
|
521
|
+
def split_path(s, keep_quotes=false)
|
522
|
+
keep_quotes ? s.split(/\s(?=(?:[^"]|"[^"]*")*$)/) : CSV::parse_line(s, :col_sep => ' ')
|
523
|
+
end
|
524
|
+
|
525
|
+
def discover_windows_executables(&block)
|
526
|
+
#:nocov:
|
527
|
+
if RHC::Helpers.windows?
|
528
|
+
|
529
|
+
base_path = []
|
530
|
+
guessing_locations = []
|
531
|
+
|
532
|
+
# Look for the base path int the ProgramFiles env var...
|
533
|
+
if program_files = ENV['ProgramFiles']; program_files.present? && File.exists?(program_files)
|
534
|
+
base_path << program_files
|
535
|
+
end
|
536
|
+
|
537
|
+
# ... and in win32ole drives (drive root or Program Files)
|
538
|
+
begin
|
539
|
+
require 'win32ole'
|
540
|
+
WIN32OLE.new("Scripting.FileSystemObject").tap do |file_system|
|
541
|
+
file_system.Drives.each do |drive|
|
542
|
+
base_path << [
|
543
|
+
"#{drive.DriveLetter}:\\Program Files (x86)",
|
544
|
+
"#{drive.DriveLetter}:\\Program Files",
|
545
|
+
"#{drive.DriveLetter}:\\Progra~1",
|
546
|
+
"#{drive.DriveLetter}:"
|
547
|
+
]
|
548
|
+
end
|
549
|
+
end
|
550
|
+
rescue
|
551
|
+
end
|
552
|
+
|
553
|
+
# executables array from block
|
554
|
+
executable_groups = []
|
555
|
+
base_path.flatten.uniq.each do |base|
|
556
|
+
executable_groups << yield(base)
|
557
|
+
end
|
558
|
+
|
559
|
+
# give proper priorities
|
560
|
+
unless executable_groups.empty?
|
561
|
+
length = executable_groups.first.length
|
562
|
+
for i in 1..length do
|
563
|
+
executable_groups.each do |group|
|
564
|
+
guessing_locations << group[i - 1]
|
565
|
+
end
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
569
|
+
guessing_locations.flatten.uniq.select {|cmd| File.exist?(cmd) && File.executable?(cmd)}
|
570
|
+
else
|
571
|
+
[]
|
572
|
+
end
|
573
|
+
#:nocov:
|
574
|
+
end
|
575
|
+
|
576
|
+
def exe?(executable)
|
577
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).any? do |directory|
|
578
|
+
File.executable?(File.join(directory, executable.to_s))
|
579
|
+
end
|
580
|
+
end
|
581
|
+
|
520
582
|
BOUND_WARNING = self.method(:warn).to_proc
|
521
583
|
end
|
522
584
|
end
|
data/lib/rhc/rest/application.rb
CHANGED
@@ -110,6 +110,11 @@ module RHC
|
|
110
110
|
rest_method 'TIDY', :event => "tidy"
|
111
111
|
end
|
112
112
|
|
113
|
+
def enable_ha
|
114
|
+
raise RHC::HighAvailabilityNotSupportedException.new unless supports? "MAKE_HA"
|
115
|
+
rest_method 'MAKE_HA', :event => "make-ha"
|
116
|
+
end
|
117
|
+
|
113
118
|
def scale_up
|
114
119
|
rest_method 'SCALE_UP', :event => "scale-up"
|
115
120
|
end
|
data/lib/rhc/rest/client.rb
CHANGED
@@ -285,6 +285,16 @@ module RHC
|
|
285
285
|
api.supports? :LIST_REGIONS
|
286
286
|
end
|
287
287
|
|
288
|
+
#
|
289
|
+
# allows_region_selection? determines if the broker will allow a client
|
290
|
+
# to specify the region for an app
|
291
|
+
# @returns true if allowed; nil otherwise
|
292
|
+
#
|
293
|
+
def allows_region_selection?
|
294
|
+
supported_regions = regions rescue []
|
295
|
+
supported_regions.any? { |region| region.allow_selection == true }
|
296
|
+
end
|
297
|
+
|
288
298
|
def authorizations
|
289
299
|
raise AuthorizationsNotSupported unless supports_sessions?
|
290
300
|
api.rest_method 'LIST_AUTHORIZATIONS'
|
data/lib/rhc/rest/mock.rb
CHANGED
@@ -426,7 +426,8 @@ module RHC::Rest::Mock
|
|
426
426
|
['LIST_DEPLOYMENTS', "broker/rest/domain/#{domain_id}/application/#{app_id}/deployments", 'get' ],
|
427
427
|
['UPDATE_DEPLOYMENTS', "broker/rest/domain/#{domain_id}/application/#{app_id}/deployments", 'post' ],
|
428
428
|
['ACTIVATE', "broker/rest/domain/#{domain_id}/application/#{app_id}/events", 'post'],
|
429
|
-
['DEPLOY', "broker/rest/domain/#{domain_id}/application/#{app_id}/deployments", 'post']
|
429
|
+
['DEPLOY', "broker/rest/domain/#{domain_id}/application/#{app_id}/deployments", 'post'],
|
430
|
+
['MAKE_HA', "broker/rest/application/#{app_id}/events", 'make-ha']
|
430
431
|
].compact
|
431
432
|
end
|
432
433
|
|
@@ -764,15 +765,16 @@ module RHC::Rest::Mock
|
|
764
765
|
@applications = nil
|
765
766
|
end
|
766
767
|
|
767
|
-
def add_application(name, type=nil, scale=nil, gear_profile='default', git_url=nil)
|
768
|
+
def add_application(name, type=nil, scale=nil, gear_profile='default', git_url=nil, region=nil)
|
768
769
|
if type.is_a?(Hash)
|
769
770
|
scale = type[:scale]
|
770
771
|
gear_profile = type[:gear_profile]
|
771
772
|
git_url = type[:initial_git_url]
|
772
773
|
tags = type[:tags]
|
774
|
+
region = type[:region]
|
773
775
|
type = Array(type[:cartridges] || type[:cartridge])
|
774
776
|
end
|
775
|
-
a = MockRestApplication.new(client, name, type, self, scale, gear_profile, git_url)
|
777
|
+
a = MockRestApplication.new(client, name, type, self, scale, gear_profile, git_url, nil, region)
|
776
778
|
builder = @applications.find{ |app| app.cartridges.map(&:name).any?{ |s| s =~ /^jenkins-[\d\.]+$/ } }
|
777
779
|
a.building_app = builder.name if builder
|
778
780
|
@applications << a
|
@@ -847,11 +849,13 @@ module RHC::Rest::Mock
|
|
847
849
|
|
848
850
|
class MockRestApplication < RHC::Rest::Application
|
849
851
|
include Helpers
|
852
|
+
attr_writer :region
|
853
|
+
|
850
854
|
def fakeuuid
|
851
855
|
"fakeuuidfortests#{@name}"
|
852
856
|
end
|
853
857
|
|
854
|
-
def initialize(client, name, type, domain, scale=nil, gear_profile='default', initial_git_url=nil, environment_variables=nil)
|
858
|
+
def initialize(client, name, type, domain, scale=nil, gear_profile='default', initial_git_url=nil, environment_variables=nil, region=nil)
|
855
859
|
super({}, client)
|
856
860
|
@name = name
|
857
861
|
@domain = domain
|
@@ -870,7 +874,7 @@ module RHC::Rest::Mock
|
|
870
874
|
if scale
|
871
875
|
@scalable = true
|
872
876
|
end
|
873
|
-
@region =
|
877
|
+
@region = region
|
874
878
|
self.attributes = {:links => mock_response_links(mock_app_links('mock_domain_0', 'mock_app_0')), :messages => []}
|
875
879
|
self.gear_count = 5
|
876
880
|
types = Array(type)
|
@@ -954,6 +958,14 @@ module RHC::Rest::Mock
|
|
954
958
|
@app
|
955
959
|
end
|
956
960
|
|
961
|
+
def enable_ha
|
962
|
+
if supports? "MAKE_HA"
|
963
|
+
@app
|
964
|
+
else
|
965
|
+
raise RHC::HighAvailabilityNotSupportedException.new
|
966
|
+
end
|
967
|
+
end
|
968
|
+
|
957
969
|
def scale_up
|
958
970
|
@app
|
959
971
|
end
|
data/lib/rhc/ssh_helpers.rb
CHANGED
@@ -21,7 +21,6 @@ require 'httpclient'
|
|
21
21
|
|
22
22
|
module RHC
|
23
23
|
module SSHHelpers
|
24
|
-
|
25
24
|
class MultipleGearTask
|
26
25
|
def initialize(command, over, opts={})
|
27
26
|
requires_ssh_multi!
|
@@ -373,12 +372,6 @@ module RHC
|
|
373
372
|
pub_key
|
374
373
|
end
|
375
374
|
|
376
|
-
def exe?(executable)
|
377
|
-
ENV['PATH'].split(File::PATH_SEPARATOR).any? do |directory|
|
378
|
-
File.executable?(File.join(directory, executable.to_s))
|
379
|
-
end
|
380
|
-
end
|
381
|
-
|
382
375
|
# For Net::SSH versions (< 2.0.11) that does not have
|
383
376
|
# Net::SSH::KeyFactory.load_public_key, we drop to shell to get
|
384
377
|
# the key's fingerprint
|
@@ -426,18 +419,51 @@ module RHC
|
|
426
419
|
end
|
427
420
|
|
428
421
|
# check the version of SSH that is installed
|
429
|
-
def ssh_version
|
430
|
-
|
422
|
+
def ssh_version(cmd=discover_ssh_executable)
|
423
|
+
`"#{cmd}" -V 2>&1`.strip
|
431
424
|
end
|
432
425
|
|
433
426
|
# return whether or not SSH is installed
|
434
427
|
def has_ssh?
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
428
|
+
discover_ssh_executable.present?
|
429
|
+
end
|
430
|
+
|
431
|
+
# try my best to discover a ssh executable
|
432
|
+
def discover_ssh_executable
|
433
|
+
@ssh_executable ||= begin
|
434
|
+
guessing_locations = ['ssh']
|
435
|
+
|
436
|
+
#:nocov:
|
437
|
+
if RHC::Helpers.windows?
|
438
|
+
# looks for ssh.exe from msysgit or plink.exe from PuTTY, either on path or specific locations
|
439
|
+
guessing_locations <<
|
440
|
+
discover_windows_executables do |base|
|
441
|
+
[
|
442
|
+
'ssh.exe',
|
443
|
+
"#{base}\\Git\\bin\\ssh.exe",
|
444
|
+
"#{base}\\ssh.exe",
|
445
|
+
'plink.exe',
|
446
|
+
"#{base}\\PuTTY\\plink.exe",
|
447
|
+
"#{base}\\plink.exe",
|
448
|
+
'putty.exe',
|
449
|
+
"#{base}\\PuTTY\\putty.exe",
|
450
|
+
"#{base}\\putty.exe"
|
451
|
+
]
|
452
|
+
end
|
453
|
+
end
|
454
|
+
#:nocov:
|
455
|
+
|
456
|
+
# make sure commands can be executed and finally pick the first one
|
457
|
+
guessing_locations.flatten.uniq.select do |cmd|
|
458
|
+
(check_ssh_executable!(cmd).present? rescue false) &&
|
459
|
+
(begin
|
460
|
+
# putty -V exit as 1
|
461
|
+
cmd =~ /plink\.exe/i || cmd =~ /putty\.exe/i || (begin
|
462
|
+
ssh_version(cmd)
|
463
|
+
$?.success?
|
464
|
+
end)
|
465
|
+
rescue ; false ; end)
|
466
|
+
end.collect{|cmd| cmd =~ / / ? '"' + cmd + '"' : cmd}.first
|
441
467
|
end
|
442
468
|
end
|
443
469
|
|
@@ -445,13 +471,14 @@ module RHC
|
|
445
471
|
# if none was supplied, return installed ssh, if any.
|
446
472
|
def check_ssh_executable!(path)
|
447
473
|
if not path
|
448
|
-
|
449
|
-
|
474
|
+
discover_ssh_executable.tap do |ssh_cmd|
|
475
|
+
raise RHC::InvalidSSHExecutableException.new("No system SSH available. Please use the --ssh option to specify the path to your SSH executable, or install SSH.#{windows? ? ' We recommend this free application: Git for Windows - a basic git command line and GUI client http://msysgit.github.io/.' : ''}") unless ssh_cmd or has_ssh?
|
476
|
+
end
|
450
477
|
else
|
451
478
|
bin_path = path.split(' ').first
|
452
|
-
raise RHC::InvalidSSHExecutableException.new("SSH executable '#{bin_path}' does not exist.") unless File.exist?(bin_path) or exe?(bin_path)
|
453
|
-
raise RHC::InvalidSSHExecutableException.new("SSH executable '#{bin_path}' is not executable.") unless File.executable?(bin_path) or exe?(bin_path)
|
454
|
-
path
|
479
|
+
raise RHC::InvalidSSHExecutableException.new("SSH executable '#{bin_path}' does not exist.") unless File.exist?(bin_path) or File.exist?(path) or exe?(bin_path)
|
480
|
+
raise RHC::InvalidSSHExecutableException.new("SSH executable '#{bin_path}' is not executable.") unless File.executable?(path) or File.executable?(bin_path) or exe?(bin_path)
|
481
|
+
path =~ / / ? '"' + path + '"' : path
|
455
482
|
end
|
456
483
|
end
|
457
484
|
|
data/lib/rhc/wizard.rb
CHANGED
@@ -182,7 +182,7 @@ module RHC
|
|
182
182
|
end
|
183
183
|
|
184
184
|
def server_stage
|
185
|
-
paragraph do
|
185
|
+
paragraph do
|
186
186
|
unless options.__explicit__[:server]
|
187
187
|
say "If you have your own OpenShift server, you can specify it now. Just hit enter to use#{openshift_online_server? ? ' the server for OpenShift Online' : ''}: #{openshift_server}."
|
188
188
|
options.server = ask "Enter the server hostname: " do |q|
|
@@ -236,7 +236,7 @@ module RHC
|
|
236
236
|
elsif rest_client.supports_sessions? && !options.token
|
237
237
|
paragraph do
|
238
238
|
info "OpenShift can create and store a token on disk which allows to you to access the server without using your password. The key is stored in your home directory and should be kept secret. You can delete the key at any time by running 'rhc logout'."
|
239
|
-
if agree "Generate a token now? (yes|no) "
|
239
|
+
if options.create_token or agree "Generate a token now? (yes|no) "
|
240
240
|
say "Generating an authorization token for this client ... "
|
241
241
|
token = rest_client.new_session
|
242
242
|
options.token = token.token
|
@@ -287,8 +287,8 @@ module RHC
|
|
287
287
|
if write_servers_yml
|
288
288
|
say "Saving server configuration to #{system_path(servers.path)} ... "
|
289
289
|
servers.backup
|
290
|
-
servers.add_or_update(options.server,
|
291
|
-
:login => options.rhlogin,
|
290
|
+
servers.add_or_update(options.server,
|
291
|
+
:login => options.rhlogin,
|
292
292
|
:use_authorization_tokens => options.use_authorization_tokens,
|
293
293
|
:insecure => options.insecure,
|
294
294
|
:timeout => options.timeout,
|
@@ -605,7 +605,7 @@ module RHC
|
|
605
605
|
end
|
606
606
|
|
607
607
|
def generic_unix_install_check
|
608
|
-
paragraph do
|
608
|
+
paragraph do
|
609
609
|
say "Checking for git ... "
|
610
610
|
|
611
611
|
if has_git?
|
@@ -623,21 +623,18 @@ module RHC
|
|
623
623
|
end
|
624
624
|
|
625
625
|
def windows_install
|
626
|
-
|
627
|
-
|
628
|
-
# print out urls and some instructions
|
629
|
-
warn <<EOF
|
630
|
-
|
631
|
-
In order to fully interact with OpenShift you will need to install and configure a git client if you have not already done so.
|
626
|
+
unless discover_ssh_executable.present? && discover_git_executable.present?
|
627
|
+
warn <<EOF
|
632
628
|
|
633
|
-
Documentation for installing other tools you will need for OpenShift can be found at https://www.openshift.com/developers/install-the-client-tools
|
629
|
+
In order to fully interact with OpenShift you will need to install and configure a git client if you have not already done so. Documentation for installing other tools you will need for OpenShift can be found at https://www.openshift.com/developers/install-the-client-tools
|
634
630
|
|
635
631
|
We recommend these free applications:
|
636
632
|
|
637
|
-
* Git for Windows - a basic git command line and GUI client
|
633
|
+
* Git for Windows - a basic git command line and GUI client http://msysgit.github.io/
|
638
634
|
* TortoiseGit - git client that integrates into the file explorer http://code.google.com/p/tortoisegit/
|
639
|
-
|
635
|
+
|
640
636
|
EOF
|
637
|
+
end
|
641
638
|
end
|
642
639
|
end
|
643
640
|
|
@@ -163,6 +163,7 @@ describe RHC::Commands::App do
|
|
163
163
|
let!(:config){ base_config }
|
164
164
|
before{ RHC::Config.any_instance.stub(:has_local_config?).and_return(false) }
|
165
165
|
before{ described_class.any_instance.stub(:interactive?).and_return(true) }
|
166
|
+
before{ described_class.any_instance.stub(:discover_git_executable).and_return('git') }
|
166
167
|
before{ rest_client.domains.clear }
|
167
168
|
before{ rest_client.sshkeys.delete_if {|k| !k.is_ssh? } }
|
168
169
|
let(:arguments) { ['app', 'create', 'app1', 'mock_standalone_cart-1'] }
|
@@ -406,6 +407,7 @@ describe RHC::Commands::App do
|
|
406
407
|
@domain = rest_client.add_domain("mockdomain")
|
407
408
|
@instance.stub(:git_clone_application) { raise RHC::GitException }
|
408
409
|
@instance.stub(:check_sshkeys!)
|
410
|
+
@instance.stub(:discover_git_executable).and_return('git')
|
409
411
|
end
|
410
412
|
|
411
413
|
context 'when run with error in git clone' do
|
@@ -428,6 +430,7 @@ describe RHC::Commands::App do
|
|
428
430
|
RHC::Helpers.stub(:windows?) { true }
|
429
431
|
@instance.stub(:run_nslookup) { true }
|
430
432
|
@instance.stub(:run_ping) { true }
|
433
|
+
@instance.stub(:has_git?) { true }
|
431
434
|
end
|
432
435
|
it "should print out git warning" do
|
433
436
|
run_output.should match(" We were unable to clone your application's git repo")
|
@@ -439,6 +442,7 @@ describe RHC::Commands::App do
|
|
439
442
|
RHC::Helpers.stub(:windows?) { true }
|
440
443
|
@instance.stub(:run_nslookup) { true }
|
441
444
|
@instance.stub(:run_ping) { false }
|
445
|
+
@instance.stub(:has_git?) { true }
|
442
446
|
end
|
443
447
|
it "should print out windows warning" do
|
444
448
|
run_output.should match("This may also be related to an issue with Winsock on Windows")
|
@@ -473,26 +477,66 @@ describe RHC::Commands::App do
|
|
473
477
|
before(:each) do
|
474
478
|
FakeFS.deactivate!
|
475
479
|
@domain = rest_client.add_domain("mockdomain")
|
476
|
-
@app = @domain.add_application("app1", "mock_standalone_cart-1")
|
480
|
+
@app = @domain.add_application("app1", :cartridge=>"mock_standalone_cart-1")
|
477
481
|
@app.add_alias('myfoo.com')
|
478
482
|
@cart1 = @app.add_cartridge('mock_cart-1')
|
479
483
|
@cart2 = @app.add_cartridge('mock_cart-2')
|
480
484
|
@cart2.gear_profile = 'medium'
|
481
485
|
@instance.stub(:save_snapshot)
|
482
486
|
@instance.stub(:restore_snapshot)
|
487
|
+
@app.stub(:region){'aRegion'}
|
488
|
+
rest_client.api.stub(:supports?).with(:LIST_REGIONS){true}
|
483
489
|
end
|
484
490
|
|
485
|
-
context 'when run' do
|
491
|
+
context 'when run and the broker allows region selection' do
|
492
|
+
before do
|
493
|
+
rest_client.stub(:regions) do
|
494
|
+
region = double()
|
495
|
+
region.stub(:allow_selection){true}
|
496
|
+
[region]
|
497
|
+
end
|
498
|
+
end
|
499
|
+
|
486
500
|
let(:arguments) { ['app', 'create', 'clone', '--from-app', 'app1', '--no-git'] }
|
487
501
|
it { expect { run }.to exit_with_code(0) }
|
488
502
|
it "should clone successfully" do
|
489
503
|
run_output.should match(/Cartridges:\s+mock_standalone_cart-1, mock_cart-1, mock_cart-2/)
|
490
504
|
run_output.should match(/Gear Size:\s+Copied from 'app1'/)
|
491
505
|
run_output.should match(/Setting deployment configuration/)
|
506
|
+
run_output.should match(/Region:\s+aRegion\s+\(copied from 'app1'/)
|
492
507
|
run_output.should match(/done/)
|
493
508
|
end
|
494
509
|
end
|
495
510
|
|
511
|
+
context 'when source app has a region and the broker does not allow region selection' do
|
512
|
+
|
513
|
+
context 'and region flag is not specified' do
|
514
|
+
let(:arguments) { ['app', 'create', 'app2', '--from-app', 'app1', '--no-git'] }
|
515
|
+
it "should clone successfully" do
|
516
|
+
expect { run }.to exit_with_code(0)
|
517
|
+
run_output.should match(/Server does not allow selecting regions. Region is being ignored./)
|
518
|
+
run_output.should match(/Cartridges:\s+mock_standalone_cart-1, mock_cart-1, mock_cart-2/)
|
519
|
+
run_output.should match(/Gear Size:\s+Copied from 'app1'/)
|
520
|
+
run_output.should_not match(/Region:\s+aRegion\s+\(copied from 'app1'/)
|
521
|
+
run_output.should match(/Setting deployment configuration/)
|
522
|
+
run_output.should match(/done/)
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
context 'and region flag is specified' do
|
527
|
+
let(:arguments) { ['app', 'create', 'app2', '--from-app', 'app1', '--region','foo','--no-git'] }
|
528
|
+
it "should clone successfully" do
|
529
|
+
run_output.should match(/Server does not allow selecting regions. Region is being ignored./)
|
530
|
+
run_output.should match(/Cartridges:\s+mock_standalone_cart-1, mock_cart-1, mock_cart-2/)
|
531
|
+
run_output.should match(/Gear Size:\s+Copied from 'app1'/)
|
532
|
+
run_output.should_not match(/Region:\s+aRegion\s+\(copied from 'app1'/)
|
533
|
+
run_output.should match(/Setting deployment configuration/)
|
534
|
+
run_output.should match(/done/)
|
535
|
+
expect { run }.to exit_with_code(0)
|
536
|
+
end
|
537
|
+
end
|
538
|
+
end
|
539
|
+
|
496
540
|
context 'when cloning a scalable app as not scalable' do
|
497
541
|
before do
|
498
542
|
@scaled = @domain.add_application("scaled", "mock_standalone_cart-1", true)
|
@@ -848,6 +892,29 @@ describe RHC::Commands::App do
|
|
848
892
|
it { run_output.should match('cleaned') }
|
849
893
|
it { expect{ run }.to exit_with_code(0) }
|
850
894
|
end
|
895
|
+
|
896
|
+
context 'app enable-ha' do
|
897
|
+
let(:arguments) { ['app', 'enable-ha', 'app1'] }
|
898
|
+
it { run_output.should match('is now highly available') }
|
899
|
+
it { expect{ run }.to exit_with_code(0) }
|
900
|
+
end
|
901
|
+
|
902
|
+
end
|
903
|
+
|
904
|
+
describe 'app enable-ha' do
|
905
|
+
before do
|
906
|
+
@domain = rest_client.add_domain("mockdomain")
|
907
|
+
@app = @domain.add_application("app1", "mock_type")
|
908
|
+
@app.add_cartridge('mock_cart-1')
|
909
|
+
@app.links.delete 'MAKE_HA'
|
910
|
+
end
|
911
|
+
|
912
|
+
let(:arguments) { ['app', 'enable-ha', 'app1'] }
|
913
|
+
|
914
|
+
it "should raise ha not supported exception" do
|
915
|
+
run_output.should match(/The server does not support high availability/)
|
916
|
+
expect{ run }.to exit_with_code(135)
|
917
|
+
end
|
851
918
|
end
|
852
919
|
|
853
920
|
describe "#create_app" do
|
@@ -34,7 +34,7 @@ describe RHC::Commands::GitClone do
|
|
34
34
|
|
35
35
|
context 'when run without git installed' do
|
36
36
|
before do
|
37
|
-
@instance.stub(:
|
37
|
+
@instance.stub(:discover_git_executable){ nil }
|
38
38
|
end
|
39
39
|
it "should print out git warning" do
|
40
40
|
run_output.should match("You do not have git installed")
|
@@ -49,6 +49,7 @@ describe RHC::Commands::GitClone do
|
|
49
49
|
say "Cloned"
|
50
50
|
true
|
51
51
|
end
|
52
|
+
@instance.stub(:discover_git_executable){ 'git' }
|
52
53
|
end
|
53
54
|
|
54
55
|
it { expect { run }.to exit_with_code(0) }
|
@@ -65,7 +66,35 @@ describe RHC::Commands::GitClone do
|
|
65
66
|
let(:arguments) { ['git-clone', 'app2'] }
|
66
67
|
it { run_output.should match("Added remote upstream pointing to git://test") }
|
67
68
|
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "reports success successfully on windows" do
|
72
|
+
before do
|
73
|
+
RHC::Helpers.stub(:windows?) do ; true; end
|
74
|
+
RHC::Helpers.stub(:jruby?) do ; false ; end
|
75
|
+
RHC::Helpers.stub(:linux?) do ; false ; end
|
76
|
+
@instance.stub(:git_clone_repo) do |git_url, repo_dir|
|
77
|
+
Dir::mkdir(repo_dir)
|
78
|
+
say "Cloned"
|
79
|
+
true
|
80
|
+
end
|
81
|
+
@instance.stub(:discover_git_executable){ 'git.exe' }
|
82
|
+
end
|
83
|
+
|
84
|
+
it { expect { run }.to exit_with_code(0) }
|
85
|
+
it { run_output.should match("Cloned") }
|
68
86
|
|
87
|
+
context 'when app has an initial git url' do
|
88
|
+
before do
|
89
|
+
@app2 = @domain.add_application("app2", "mock_unique_standalone_cart", nil, "default", "git://test")
|
90
|
+
@instance.stub(:git_remote_add) do |remote_name, remote_url|
|
91
|
+
say "Added remote #{remote_name} pointing to #{remote_url}"
|
92
|
+
true
|
93
|
+
end
|
94
|
+
end
|
95
|
+
let(:arguments) { ['git-clone', 'app2'] }
|
96
|
+
it { run_output.should match("Added remote upstream pointing to git://test") }
|
97
|
+
end
|
69
98
|
end
|
70
99
|
|
71
100
|
context "testing git_clone_deploy_hooks" do
|
@@ -78,6 +107,7 @@ describe RHC::Commands::GitClone do
|
|
78
107
|
say "Copied" if File.exists?("#{repo_dir}/.git/hooks/pre_commit")
|
79
108
|
true
|
80
109
|
end
|
110
|
+
@instance.stub(:discover_git_executable){ 'git' }
|
81
111
|
|
82
112
|
# Get around the FakeFS bug (defunkt/fakefs#177) by
|
83
113
|
# stubbing the #cp call to inject a expected fs entry
|
@@ -92,7 +122,10 @@ describe RHC::Commands::GitClone do
|
|
92
122
|
end
|
93
123
|
|
94
124
|
context "reports failure" do
|
95
|
-
before
|
125
|
+
before do
|
126
|
+
@instance.stub(:git_clone_repo).and_raise(RHC::GitException)
|
127
|
+
@instance.stub(:discover_git_executable){ 'git' }
|
128
|
+
end
|
96
129
|
|
97
130
|
it { expect { run }.to exit_with_code(216) }
|
98
131
|
it { run_output.should match("Git returned an error") }
|
@@ -35,6 +35,7 @@ describe RHC::Commands::Scp do
|
|
35
35
|
@domain = rest_client.add_domain("mockdomain")
|
36
36
|
@domain.add_application("app1", "mock_type")
|
37
37
|
File.should_receive(:exist?).with("file.txt").once.and_return(false)
|
38
|
+
File.should_receive(:exist?).with("git").at_least(1).and_return(true)
|
38
39
|
end
|
39
40
|
it { run_output.should match("Local file, file_path, or directory could not be found.") }
|
40
41
|
end
|
@@ -48,6 +49,7 @@ describe RHC::Commands::Scp do
|
|
48
49
|
@domain = rest_client.add_domain("mockdomain")
|
49
50
|
@domain.add_application("app1", "mock_type")
|
50
51
|
File.should_receive(:exist?).with("file.txt").once.and_return(true)
|
52
|
+
File.should_receive(:exist?).with("git").at_least(1).and_return(true)
|
51
53
|
Net::SCP.should_receive("upload!".to_sym).with("127.0.0.1", "fakeuuidfortestsapp1","file.txt","app-root/data").and_raise(Errno::ECONNREFUSED)
|
52
54
|
end
|
53
55
|
it { run_output.should match("The server fakeuuidfortestsapp1 refused a connection with user 127.0.0.1. The application may be unavailable.") }
|
@@ -58,6 +60,7 @@ describe RHC::Commands::Scp do
|
|
58
60
|
@domain = rest_client.add_domain("mockdomain")
|
59
61
|
@domain.add_application("app1", "mock_type")
|
60
62
|
File.should_receive(:exist?).with("file.txt").once.and_return(true)
|
63
|
+
File.should_receive(:exist?).with("git").at_least(1).and_return(true)
|
61
64
|
Net::SCP.should_receive("upload!".to_sym).with("127.0.0.1", "fakeuuidfortestsapp1","file.txt","app-root/data").and_raise(SocketError)
|
62
65
|
end
|
63
66
|
it { run_output.should match("The connection to 127.0.0.1 failed: SocketError") }
|
@@ -69,6 +72,7 @@ describe RHC::Commands::Scp do
|
|
69
72
|
@domain = rest_client.add_domain("mockdomain")
|
70
73
|
@domain.add_application("app1", "mock_type")
|
71
74
|
File.should_receive(:exist?).with("file.txt").once.and_return(true)
|
75
|
+
File.should_receive(:exist?).with("git").at_least(1).and_return(true)
|
72
76
|
Net::SCP.should_receive("upload!".to_sym).with("127.0.0.1", "fakeuuidfortestsapp1","file.txt","app-root/data").and_raise(Net::SSH::AuthenticationFailed)
|
73
77
|
end
|
74
78
|
it { run_output.should match("Authentication to server 127.0.0.1 with user fakeuuidfortestsapp1 failed") }
|
@@ -79,6 +83,7 @@ describe RHC::Commands::Scp do
|
|
79
83
|
@domain = rest_client.add_domain("mockdomain")
|
80
84
|
@domain.add_application("app1", "mock_type")
|
81
85
|
File.should_receive(:exist?).with("file.txt").once.and_return(true)
|
86
|
+
File.should_receive(:exist?).with("git").at_least(1).and_return(true)
|
82
87
|
Net::SCP.should_receive("upload!".to_sym).with("127.0.0.1", "fakeuuidfortestsapp1","file.txt","app-root/data").and_raise(Net::SCP::Error.new("SCP error message"))
|
83
88
|
end
|
84
89
|
it { run_output.should match("An unknown error occurred: SCP error message") }
|
@@ -41,6 +41,7 @@ describe RHC::Commands::Setup do
|
|
41
41
|
it{ command_for('setup', '--clean').options.clean.should be_true }
|
42
42
|
|
43
43
|
it{ command_for('setup').options.server.should == 'openshift.redhat.com' }
|
44
|
+
it{ command_for('setup').options.create_token.should be_nil }
|
44
45
|
it{ command_for('setup', '--server', 'foo.com').options.server.should == 'foo.com' }
|
45
46
|
it{ command_for('setup', '--no-create-token').options.create_token.should == false }
|
46
47
|
it{ command_for('setup', '--create-token').options.create_token.should == true }
|
@@ -51,7 +52,7 @@ describe RHC::Commands::Setup do
|
|
51
52
|
end
|
52
53
|
context "when config has use_authorization_tokens=true" do
|
53
54
|
let!(:config){ base_config{ |c, d| d.add('use_authorization_tokens', 'true') } }
|
54
|
-
it{ command_for('setup').options.use_authorization_tokens.should
|
55
|
+
it{ command_for('setup').options.use_authorization_tokens.should be_true }
|
55
56
|
end
|
56
57
|
|
57
58
|
=begin context 'when libra_server is set' do
|
@@ -40,7 +40,6 @@ describe RHC::Commands::Snapshot do
|
|
40
40
|
|
41
41
|
context 'when failing to save a snapshot' do
|
42
42
|
before do
|
43
|
-
subject.class.any_instance.should_receive(:has_ssh?).and_return(true)
|
44
43
|
subject.class.any_instance.should_receive(:exec).with("ssh #{@ssh_uri.user}@#{@ssh_uri.host} 'snapshot' > #{@app.name}.tar.gz").and_return([1, 'some save failures'])
|
45
44
|
end
|
46
45
|
it { expect { run }.to exit_with_code(130) }
|
@@ -54,6 +53,8 @@ describe RHC::Commands::Snapshot do
|
|
54
53
|
RHC::Helpers.stub(:linux?) do ; false ; end
|
55
54
|
ssh = double(Net::SSH)
|
56
55
|
Net::SSH.should_receive(:start).with(@ssh_uri.host, @ssh_uri.user).and_yield(ssh)
|
56
|
+
subject.class.any_instance.stub(:discover_ssh_executable){ 'ssh' }
|
57
|
+
subject.class.any_instance.stub(:discover_git_executable){ 'git' }
|
57
58
|
ssh.should_receive(:exec!).with("snapshot").and_yield(nil, :stdout, 'foo').and_yield(nil, :stderr, 'foo')
|
58
59
|
end
|
59
60
|
it { expect { run }.to exit_with_code(0) }
|
@@ -67,6 +68,8 @@ describe RHC::Commands::Snapshot do
|
|
67
68
|
RHC::Helpers.stub(:linux?) do ; false ; end
|
68
69
|
ssh = double(Net::SSH)
|
69
70
|
Net::SSH.should_receive(:start).with(@ssh_uri.host, @ssh_uri.user).and_raise(Timeout::Error)
|
71
|
+
subject.class.any_instance.stub(:discover_ssh_executable){ 'ssh' }
|
72
|
+
subject.class.any_instance.stub(:discover_git_executable){ 'git' }
|
70
73
|
end
|
71
74
|
it { expect { run }.to exit_with_code(130) }
|
72
75
|
end
|
@@ -112,7 +115,6 @@ describe RHC::Commands::Snapshot do
|
|
112
115
|
before do
|
113
116
|
File.stub(:exists?).and_return(true)
|
114
117
|
RHC::TarGz.stub(:contains).and_return(true)
|
115
|
-
subject.class.any_instance.should_receive(:has_ssh?).and_return(true)
|
116
118
|
subject.class.any_instance.should_receive(:exec).with("cat '#{@app.name}.tar.gz' | ssh #{@ssh_uri.user}@#{@ssh_uri.host} 'restore INCLUDE_GIT'").and_return([1, 'some restore failures'])
|
117
119
|
end
|
118
120
|
it { expect { run }.to exit_with_code(130) }
|
@@ -134,6 +136,8 @@ describe RHC::Commands::Snapshot do
|
|
134
136
|
channel.should_receive(:on_extended_data).and_yield(nil, nil, 'foo')
|
135
137
|
channel.should_receive(:on_close).and_yield(nil)
|
136
138
|
lines = ''
|
139
|
+
subject.class.any_instance.stub(:discover_ssh_executable){ 'ssh' }
|
140
|
+
subject.class.any_instance.stub(:discover_git_executable){ 'git' }
|
137
141
|
File.open(File.expand_path('../../assets/targz_sample.tar.gz', __FILE__), 'rb') do |file|
|
138
142
|
file.chunk(1024) do |chunk|
|
139
143
|
lines << chunk
|
@@ -153,6 +157,8 @@ describe RHC::Commands::Snapshot do
|
|
153
157
|
RHC::Helpers.stub(:linux?) do ; false ; end
|
154
158
|
ssh = double(Net::SSH)
|
155
159
|
Net::SSH.should_receive(:start).with(@ssh_uri.host, @ssh_uri.user).and_raise(Timeout::Error)
|
160
|
+
subject.class.any_instance.stub(:discover_ssh_executable){ 'ssh' }
|
161
|
+
subject.class.any_instance.stub(:discover_git_executable){ 'git' }
|
156
162
|
end
|
157
163
|
it { expect { run }.to exit_with_code(130) }
|
158
164
|
end
|
@@ -120,7 +120,7 @@ describe RHC::Commands::Ssh do
|
|
120
120
|
before(:each) do
|
121
121
|
@domain = rest_client.add_domain("mockdomain")
|
122
122
|
@domain.add_application("app1", "mock_type")
|
123
|
-
|
123
|
+
subject.class.any_instance.stub(:discover_ssh_executable).and_return(nil)
|
124
124
|
end
|
125
125
|
it { run_output.should match("No system SSH available. Please use the --ssh option to specify the path to your SSH executable, or install SSH.") }
|
126
126
|
it { expect { run }.to exit_with_code(1) }
|
@@ -135,7 +135,9 @@ describe RHC::Commands::Ssh do
|
|
135
135
|
@domain = rest_client.add_domain("mockdomain")
|
136
136
|
@domain.add_application("app1", "mock_type")
|
137
137
|
RHC::Commands::Ssh.any_instance.should_not_receive(:has_ssh?)
|
138
|
-
File.should_receive(:exist?).with("path_to_ssh").
|
138
|
+
File.should_receive(:exist?).with("path_to_ssh").at_least(1).and_return(false)
|
139
|
+
File.should_receive(:executable?).with(/.*path_to_ssh/).at_least(1).and_return(false)
|
140
|
+
subject.class.any_instance.stub(:discover_git_executable).and_return('git')
|
139
141
|
end
|
140
142
|
it { run_output.should match("SSH executable 'path_to_ssh' does not exist.") }
|
141
143
|
it { expect { run }.to exit_with_code(1) }
|
@@ -148,6 +150,7 @@ describe RHC::Commands::Ssh do
|
|
148
150
|
RHC::Commands::Ssh.any_instance.should_not_receive(:has_ssh?)
|
149
151
|
File.should_receive(:exist?).with("path_to_ssh").once.and_return(true)
|
150
152
|
File.should_receive(:executable?).with(/.*path_to_ssh/).at_least(1).and_return(false)
|
153
|
+
subject.class.any_instance.stub(:discover_git_executable).and_return('git')
|
151
154
|
end
|
152
155
|
it { run_output.should match("SSH executable 'path_to_ssh' is not executable.") }
|
153
156
|
it { expect { run }.to exit_with_code(1) }
|
@@ -161,6 +164,7 @@ describe RHC::Commands::Ssh do
|
|
161
164
|
File.should_receive(:exist?).with("path_to_ssh").once.and_return(true)
|
162
165
|
File.should_receive(:executable?).with("path_to_ssh").once.and_return(true)
|
163
166
|
Kernel.should_receive(:exec).with("path_to_ssh", "fakeuuidfortestsapp1@127.0.0.1").once.times.and_return(0)
|
167
|
+
subject.class.any_instance.stub(:discover_git_executable).and_return('git')
|
164
168
|
end
|
165
169
|
it { run_output.should match("Connecting to fakeuuidfortestsapp") }
|
166
170
|
it { expect { run }.to exit_with_code(0) }
|
@@ -172,6 +176,7 @@ describe RHC::Commands::Ssh do
|
|
172
176
|
|
173
177
|
context 'has_ssh?' do
|
174
178
|
before{ RHC::Commands::Ssh.any_instance.stub(:ssh_version){ raise "Fake Exception" } }
|
179
|
+
before{ RHC::Commands::Ssh.any_instance.stub(:discover_ssh_executable){ nil } }
|
175
180
|
its(:has_ssh?) { should be_false }
|
176
181
|
end
|
177
182
|
end
|
data/spec/rhc/wizard_spec.rb
CHANGED
@@ -87,7 +87,7 @@ describe RHC::Wizard do
|
|
87
87
|
subject.should_receive(:applications).and_return([app])
|
88
88
|
Net::SSH.should_receive(:start).with("foo.com", "uuid", {:timeout => 60}).and_return(ssh)
|
89
89
|
subject.send(:test_ssh_connectivity).should be_true
|
90
|
-
end
|
90
|
+
end
|
91
91
|
it "should handle a failed connection" do
|
92
92
|
subject.should_receive(:ssh_key_uploaded?).and_return(true)
|
93
93
|
subject.should_receive(:applications).and_return([app])
|
@@ -100,7 +100,7 @@ describe RHC::Wizard do
|
|
100
100
|
subject.should_receive(:debug_error).with(interrupt)
|
101
101
|
Net::SSH.should_receive(:start).and_raise(interrupt)
|
102
102
|
expect{ subject.send(:test_ssh_connectivity) }.to raise_error(RuntimeError, /Connection attempt to foo.com was interrupted/)
|
103
|
-
end
|
103
|
+
end
|
104
104
|
end
|
105
105
|
|
106
106
|
describe "#core_auth" do
|
@@ -121,79 +121,79 @@ describe RHC::Wizard do
|
|
121
121
|
let(:auth){ subject.send(:auth) }
|
122
122
|
let(:user_obj){ double(:login => user) }
|
123
123
|
|
124
|
-
|
124
|
+
let(:wizard){RHC::Wizard.new(config, options) }
|
125
125
|
|
126
126
|
def expect_client_test(with_sessions=false)
|
127
|
-
|
127
|
+
wizard.should_receive(:new_client_for_options).ordered.and_return(rest_client)
|
128
128
|
rest_client.should_receive(:api).ordered
|
129
129
|
rest_client.should_receive(:user).ordered.and_return(user_obj)
|
130
130
|
rest_client.should_receive(:supports_sessions?).ordered.and_return(with_sessions)
|
131
131
|
end
|
132
132
|
def expect_raise_from_api(error)
|
133
|
-
|
133
|
+
wizard.should_receive(:new_client_for_options).ordered.and_return(rest_client)
|
134
134
|
rest_client.should_receive(:api).ordered.and_raise(error)
|
135
135
|
end
|
136
136
|
|
137
137
|
it "should prompt for user and password" do
|
138
138
|
expect_client_test
|
139
|
-
|
140
|
-
|
139
|
+
wizard.send(:login_stage).should be_true
|
140
|
+
wizard.send(:options).rhlogin.should == user
|
141
141
|
end
|
142
142
|
|
143
143
|
context "with token" do
|
144
144
|
let(:token){ 'a_test_value' }
|
145
145
|
let(:default_options){ {:token => token, :rhlogin => user} }
|
146
|
-
before{
|
146
|
+
before{ wizard.should_receive(:say).with(/Using an existing token for #{user} to login to /).ordered }
|
147
147
|
|
148
148
|
it "should continue without prompt" do
|
149
149
|
expect_client_test
|
150
|
-
|
150
|
+
wizard.send(:login_stage).should be_true
|
151
151
|
end
|
152
152
|
end
|
153
153
|
|
154
154
|
context "with credentials" do
|
155
155
|
let(:server){ mock_uri }
|
156
156
|
let(:default_options){ {:rhlogin => user, :password => password, :server => server} }
|
157
|
-
before{
|
157
|
+
before{ wizard.should_receive(:say).with(/Using #{user} to login to /).ordered }
|
158
158
|
|
159
159
|
it "should warn about a self signed cert error" do
|
160
160
|
expect_raise_from_api(RHC::Rest::SelfSignedCertificate.new('reason', 'message'))
|
161
|
-
|
162
|
-
|
163
|
-
|
161
|
+
wizard.should_receive(:warn).with(/server's certificate is self-signed/).ordered
|
162
|
+
wizard.should_receive(:openshift_online_server?).ordered.and_return(true)
|
163
|
+
wizard.should_receive(:warn).with(/server between you and OpenShift/).ordered
|
164
164
|
|
165
|
-
|
165
|
+
wizard.send(:login_stage).should be_nil
|
166
166
|
end
|
167
167
|
|
168
168
|
it "should warn about a cert error for Online" do
|
169
169
|
expect_raise_from_api(RHC::Rest::CertificateVerificationFailed.new('reason', 'message'))
|
170
|
-
|
171
|
-
|
172
|
-
|
170
|
+
wizard.should_receive(:warn).with(/server's certificate could not be verified/).ordered
|
171
|
+
wizard.should_receive(:openshift_online_server?).ordered.and_return(true)
|
172
|
+
wizard.should_receive(:warn).with(/server between you and OpenShift/).ordered
|
173
173
|
|
174
|
-
|
174
|
+
wizard.send(:login_stage).should be_nil
|
175
175
|
end
|
176
176
|
|
177
177
|
it "should warn about a cert error for custom server and continue" do
|
178
178
|
expect_raise_from_api(RHC::Rest::CertificateVerificationFailed.new('reason', 'message'))
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
179
|
+
wizard.should_receive(:warn).with(/server's certificate could not be verified/).ordered
|
180
|
+
wizard.should_receive(:openshift_online_server?).ordered.and_return(false)
|
181
|
+
wizard.should_receive(:warn).with(/bypass this check/).ordered
|
182
|
+
wizard.should_receive(:agree).with(/Connect without checking/).ordered.and_return(true)
|
183
183
|
expect_client_test
|
184
184
|
|
185
|
-
|
185
|
+
wizard.send(:login_stage).should be_true
|
186
186
|
options.insecure.should be_true
|
187
187
|
end
|
188
188
|
|
189
189
|
it "should warn about a cert error for custom server and be cancelled" do
|
190
190
|
expect_raise_from_api(RHC::Rest::CertificateVerificationFailed.new('reason', 'message'))
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
191
|
+
wizard.should_receive(:warn).with(/server's certificate could not be verified/).ordered
|
192
|
+
wizard.should_receive(:openshift_online_server?).ordered.and_return(false)
|
193
|
+
wizard.should_receive(:warn).with(/bypass this check/).ordered
|
194
|
+
wizard.should_receive(:agree).with(/Connect without checking/).ordered.and_return(false)
|
195
195
|
|
196
|
-
|
196
|
+
wizard.send(:login_stage).should be_nil
|
197
197
|
options.insecure.should be_false
|
198
198
|
end
|
199
199
|
|
@@ -206,10 +206,10 @@ describe RHC::Wizard do
|
|
206
206
|
it "should check for an existing token" do
|
207
207
|
store.should_receive(:get).and_return(nil)
|
208
208
|
|
209
|
-
|
210
|
-
|
209
|
+
wizard.should_receive(:info).with(/OpenShift can create and store a token on disk/).ordered
|
210
|
+
wizard.should_receive(:agree).with(/Generate a token now?/).ordered.and_return(false)
|
211
211
|
|
212
|
-
|
212
|
+
wizard.send(:login_stage).should be_true
|
213
213
|
options.token.should be_nil
|
214
214
|
end
|
215
215
|
end
|
@@ -223,42 +223,79 @@ describe RHC::Wizard do
|
|
223
223
|
|
224
224
|
it "should not generate a token if the user does not request it" do
|
225
225
|
store.should_not_receive(:get)
|
226
|
-
|
227
|
-
|
226
|
+
wizard.should_receive(:info).with(/OpenShift can create and store a token on disk/).ordered
|
227
|
+
wizard.should_receive(:agree).with(/Generate a token now?/).ordered.and_return(false)
|
228
228
|
|
229
|
-
|
229
|
+
wizard.send(:login_stage).should be_true
|
230
230
|
options.token.should be_nil
|
231
231
|
end
|
232
232
|
|
233
|
+
context "when the option to create tokens is passed" do
|
234
|
+
|
235
|
+
shared_examples "a wizard creating tokens without prompts" do
|
236
|
+
it "should create the token without prompting" do
|
237
|
+
store.should_not_receive(:get)
|
238
|
+
wizard.should_receive(:info).with(/OpenShift can create and store a token on disk/).ordered
|
239
|
+
wizard.should_receive(:agree).never
|
240
|
+
wizard.should_receive(:say).with(/Generating an authorization token for this client /).ordered
|
241
|
+
rest_client.should_receive(:new_session).ordered.and_return(auth_token)
|
242
|
+
store.should_receive(:put).with(user, server, token).ordered.and_return(true)
|
243
|
+
wizard.should_receive(:new_client_for_options).ordered.and_return(rest_client)
|
244
|
+
rest_client.should_receive(:user).ordered.and_return(true)
|
245
|
+
wizard.should_receive(:success).with(/lasts 1 minute/).ordered
|
246
|
+
|
247
|
+
wizard.send(:login_stage).should be_true
|
248
|
+
options.token.should == token
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
describe '--create-token' do
|
253
|
+
it_behaves_like 'a wizard creating tokens without prompts' do
|
254
|
+
let(:default_options){ {:rhlogin => user, :password => password, :server => server, :create_token => true} }
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
describe '--use-authorization-tokens' do
|
259
|
+
before { store.should_receive(:get) }
|
260
|
+
|
261
|
+
it_behaves_like 'a wizard creating tokens without prompts' do
|
262
|
+
#create token would normally be set in rhc/commands/server if not specified
|
263
|
+
#and running from the command line
|
264
|
+
let(:default_options){ {:rhlogin => user, :password => password, :server => server, :use_authorization_tokens => true, :create_token =>true} }
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
233
269
|
it "should generate a token if the user requests it" do
|
234
270
|
store.should_not_receive(:get)
|
235
|
-
|
236
|
-
|
237
|
-
|
271
|
+
wizard.should_receive(:info).with(/OpenShift can create and store a token on disk/).ordered
|
272
|
+
wizard.should_receive(:agree).with(/Generate a token now?/).ordered.and_return(true)
|
273
|
+
wizard.should_receive(:say).with(/Generating an authorization token for this client /).ordered
|
238
274
|
rest_client.should_receive(:new_session).ordered.and_return(auth_token)
|
239
275
|
store.should_receive(:put).with(user, server, token).ordered.and_return(true)
|
240
|
-
|
276
|
+
wizard.should_receive(:new_client_for_options).ordered.and_return(rest_client)
|
241
277
|
rest_client.should_receive(:user).ordered.and_return(true)
|
242
|
-
|
278
|
+
wizard.should_receive(:success).with(/lasts 1 minute/).ordered
|
243
279
|
|
244
|
-
|
280
|
+
wizard.send(:login_stage).should be_true
|
245
281
|
options.token.should == token
|
246
282
|
end
|
247
283
|
end
|
248
284
|
|
285
|
+
|
249
286
|
context "when the user doesn't want to use tokens" do
|
250
287
|
let(:default_options){ {:rhlogin => user, :password => password, :server => server, :use_authorization_tokens => false, :create_token => false} }
|
251
288
|
before do
|
252
|
-
|
289
|
+
wizard.should_receive(:new_client_for_options).ordered.and_return(rest_client)
|
253
290
|
rest_client.should_receive(:api).ordered
|
254
291
|
rest_client.should_receive(:user).ordered.and_return(user_obj)
|
255
292
|
end
|
256
293
|
|
257
294
|
it "should skip token generation" do
|
258
|
-
|
259
|
-
|
295
|
+
wizard.should_receive(:say).with(/Skipping token generation/)
|
296
|
+
wizard.should_receive(:agree).never
|
260
297
|
|
261
|
-
|
298
|
+
wizard.send(:login_stage).should be_true
|
262
299
|
options.token.should be_nil
|
263
300
|
end
|
264
301
|
end
|
@@ -407,7 +444,7 @@ describe RHC::Wizard do
|
|
407
444
|
|
408
445
|
context "when a multiple keys exist but is not the same" do
|
409
446
|
before{ setup_mock_ssh(true) }
|
410
|
-
before do
|
447
|
+
before do
|
411
448
|
stub_one_key('a_key')
|
412
449
|
stub_add_key_error('invalid```--', 'Invalid key name')
|
413
450
|
stub_add_key('another_key')
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rhc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 97
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 1.
|
8
|
+
- 31
|
9
|
+
- 5
|
10
|
+
version: 1.31.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Red Hat
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2014-
|
18
|
+
date: 2014-11-04 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: net-ssh
|
@@ -207,6 +207,14 @@ dependencies:
|
|
207
207
|
- 0
|
208
208
|
- 4
|
209
209
|
version: "0.4"
|
210
|
+
- - <
|
211
|
+
- !ruby/object:Gem::Version
|
212
|
+
hash: 7
|
213
|
+
segments:
|
214
|
+
- 0
|
215
|
+
- 6
|
216
|
+
- 0
|
217
|
+
version: 0.6.0
|
210
218
|
type: :development
|
211
219
|
version_requirements: *id012
|
212
220
|
- !ruby/object:Gem::Dependency
|