rhc 0.98.16 → 1.0.4

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.
Files changed (94) hide show
  1. data/bin/rhc +7 -49
  2. data/bin/rhc-app +14 -3
  3. data/bin/rhc-chk +16 -16
  4. data/bin/rhc-create-app +2 -0
  5. data/bin/rhc-create-domain +1 -2
  6. data/bin/rhc-ctl-app +12 -3
  7. data/bin/rhc-ctl-domain +1 -2
  8. data/bin/rhc-domain +1 -2
  9. data/bin/rhc-domain-info +1 -2
  10. data/bin/rhc-port-forward +1 -2
  11. data/bin/rhc-snapshot +3 -0
  12. data/bin/rhc-sshkey +1 -2
  13. data/bin/rhc-tail-files +1 -1
  14. data/bin/rhc-user-info +1 -3
  15. data/features/application.feature +4 -1
  16. data/features/domain.feature +0 -4
  17. data/features/geared_application.feature +11 -0
  18. data/features/lib/rhc_helper/app.rb +16 -5
  19. data/features/lib/rhc_helper/cartridge.rb +25 -9
  20. data/features/lib/rhc_helper/commandify.rb +34 -7
  21. data/features/lib/rhc_helper/domain.rb +2 -2
  22. data/features/lib/rhc_helper/httpify.rb +24 -14
  23. data/features/lib/rhc_helper/persistable.rb +1 -1
  24. data/features/lib/rhc_helper/sshkey.rb +11 -7
  25. data/features/lib/rhc_helper.rb +5 -3
  26. data/features/multiple_cartridge.feature +1 -1
  27. data/features/scaled_application.feature +48 -0
  28. data/features/sshkey.feature +37 -31
  29. data/features/step_definitions/application_steps.rb +18 -7
  30. data/features/step_definitions/cartridge_steps.rb +29 -3
  31. data/features/step_definitions/domain_steps.rb +2 -2
  32. data/features/step_definitions/sshkey_steps.rb +34 -34
  33. data/features/support/assumptions.rb +21 -9
  34. data/features/support/before_hooks.rb +24 -6
  35. data/features/support/env.rb +45 -19
  36. data/lib/rhc/cartridge_helper.rb +27 -0
  37. data/lib/rhc/cli.rb +1 -1
  38. data/lib/rhc/command_runner.rb +31 -3
  39. data/lib/rhc/commands/alias.rb +38 -0
  40. data/lib/rhc/commands/app.rb +478 -0
  41. data/lib/rhc/commands/base.rb +42 -12
  42. data/lib/rhc/commands/cartridge.rb +189 -0
  43. data/lib/rhc/commands/domain.rb +11 -49
  44. data/lib/rhc/commands/port-forward.rb +0 -1
  45. data/lib/rhc/commands/setup.rb +2 -1
  46. data/lib/rhc/commands/snapshot.rb +118 -0
  47. data/lib/rhc/commands/sshkey.rb +24 -38
  48. data/lib/rhc/commands/tail.rb +24 -0
  49. data/lib/rhc/commands/threaddump.rb +16 -0
  50. data/lib/rhc/commands.rb +33 -7
  51. data/lib/rhc/config.rb +28 -12
  52. data/lib/rhc/context_helper.rb +19 -5
  53. data/lib/rhc/core_ext.rb +86 -0
  54. data/lib/rhc/exceptions.rb +44 -0
  55. data/lib/rhc/git_helper.rb +59 -0
  56. data/lib/rhc/helpers.rb +86 -5
  57. data/lib/rhc/output_helpers.rb +213 -0
  58. data/lib/rhc/rest/application.rb +134 -67
  59. data/lib/rhc/rest/base.rb +48 -0
  60. data/lib/rhc/rest/cartridge.rb +40 -44
  61. data/lib/rhc/rest/client.rb +127 -59
  62. data/lib/rhc/rest/domain.rb +29 -39
  63. data/lib/rhc/rest/gear_group.rb +10 -0
  64. data/lib/rhc/rest/key.rb +8 -23
  65. data/lib/rhc/rest/user.rb +8 -24
  66. data/lib/rhc/rest.rb +22 -11
  67. data/lib/rhc/ssh_key_helpers.rb +47 -0
  68. data/lib/rhc/usage_templates/help.erb +0 -1
  69. data/lib/rhc/version.rb +3 -3
  70. data/lib/rhc/wizard.rb +123 -225
  71. data/lib/rhc-common.rb +43 -62
  72. data/spec/rest_spec_helper.rb +159 -36
  73. data/spec/rhc/cli_spec.rb +29 -1
  74. data/spec/rhc/command_spec.rb +32 -35
  75. data/spec/rhc/commands/alias_spec.rb +123 -0
  76. data/spec/rhc/commands/app_spec.rb +414 -0
  77. data/spec/rhc/commands/cartridge_spec.rb +342 -0
  78. data/spec/rhc/commands/domain_spec.rb +8 -8
  79. data/spec/rhc/commands/setup_spec.rb +17 -6
  80. data/spec/rhc/commands/snapshot_spec.rb +140 -0
  81. data/spec/rhc/commands/sshkey_spec.rb +26 -4
  82. data/spec/rhc/commands/tail_spec.rb +34 -0
  83. data/spec/rhc/commands/threaddump_spec.rb +83 -0
  84. data/spec/rhc/config_spec.rb +39 -13
  85. data/spec/rhc/context_spec.rb +51 -0
  86. data/spec/rhc/helpers_spec.rb +52 -12
  87. data/spec/rhc/rest_application_spec.rb +16 -3
  88. data/spec/rhc/rest_client_spec.rb +144 -36
  89. data/spec/rhc/rest_spec.rb +1 -1
  90. data/spec/rhc/wizard_spec.rb +133 -232
  91. data/spec/spec_helper.rb +4 -3
  92. metadata +56 -31
  93. data/features/support/ssh.sh +0 -2
  94. data/spec/rhc/common_spec.rb +0 -49
@@ -0,0 +1,414 @@
1
+ require 'spec_helper'
2
+ require 'rest_spec_helper'
3
+ require 'rhc/commands/app'
4
+ require 'rhc/config'
5
+
6
+ describe RHC::Commands::App do
7
+ before(:each) do
8
+ FakeFS.activate!
9
+ FakeFS::FileSystem.clear
10
+ RHC::Config.set_defaults
11
+ RHC::Helpers::MAX_RETRIES = 3
12
+ @instance = RHC::Commands::App.new
13
+ RHC::Commands::App.stub(:new) do
14
+ @instance.stub(:git_config_get) { "" }
15
+ @instance.stub(:git_config_set) { "" }
16
+ Kernel.stub(:sleep) { }
17
+ @instance.stub(:git_clone_repo) do |git_url, repo_dir|
18
+ raise RHC::GitException, "Error in git clone" if repo_dir == "giterrorapp"
19
+ Dir::mkdir(repo_dir)
20
+ end
21
+ @instance.stub(:host_exist?) do |host|
22
+ host.match("dnserror") ? false : true
23
+ end
24
+ @instance
25
+ end
26
+ end
27
+
28
+ after(:each) do
29
+ FakeFS.deactivate!
30
+ end
31
+
32
+ describe 'app default' do
33
+ before(:each) do
34
+ FakeFS.deactivate!
35
+ @rc = MockRestClient.new
36
+ end
37
+
38
+ context 'app' do
39
+ let(:arguments) { ['app', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
40
+ it { run_output.should match('Usage:') }
41
+ end
42
+ end
43
+
44
+ describe 'app create' do
45
+ let(:arguments) { ['app', 'create', 'app1', 'mock_standalone_cart-1', '--noprompt', '--timeout', '10', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
46
+
47
+ context 'when run' do
48
+ before(:each) do
49
+ @rc = MockRestClient.new
50
+ domain = @rc.add_domain("mockdomain")
51
+ end
52
+ it { expect { run }.should exit_with_code(0) }
53
+ it { run_output.should match("Success") }
54
+ end
55
+ end
56
+
57
+ describe 'app create no cart found error' do
58
+ let(:arguments) { ['app', 'create', 'app1', 'nomatch_cart', '--trace', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
59
+
60
+ context 'when run' do
61
+ before(:each) do
62
+ @rc = MockRestClient.new
63
+ domain = @rc.add_domain("mockdomain")
64
+ @rc.stub(:cartridges) { [] }
65
+ end
66
+ it { expect { run }.should raise_error(RHC::CartridgeNotFoundException) }
67
+ end
68
+ end
69
+
70
+ describe 'app create too many carts found error' do
71
+ let(:arguments) { ['app', 'create', 'app1', 'mock_standalone_cart', '--trace', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
72
+
73
+ context 'when run' do
74
+ before(:each) do
75
+ @rc = MockRestClient.new
76
+ domain = @rc.add_domain("mockdomain")
77
+ end
78
+ it { expect { run }.should raise_error(RHC::MultipleCartridgesException) }
79
+ end
80
+ end
81
+
82
+ describe 'app create enable-jenkins' do
83
+ let(:arguments) { ['app', 'create', 'app1', '--trace', 'mock_unique_standalone_cart', '--enable-jenkins', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
84
+
85
+ context 'when run' do
86
+ before(:each) do
87
+ @rc = MockRestClient.new
88
+ @domain = @rc.add_domain("mockdomain")
89
+ end
90
+ it "should create a jenkins app and a regular app with an embedded jenkins client" do
91
+ expect { run }.should exit_with_code(0)
92
+ jenkins_app = @domain.find_application("jenkins")
93
+ jenkins_app.cartridges[0].name.should == "jenkins-1.4"
94
+ app = @domain.find_application("app1")
95
+ app.find_cartridge("jenkins-client-1.4")
96
+ end
97
+ end
98
+ end
99
+
100
+ describe 'app create enable-jenkins with --no-dns' do
101
+ let(:arguments) { ['app', 'create', 'app1', 'mock_unique_standalone_cart', '--trace', '--enable-jenkins', '--no-dns', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
102
+
103
+ context 'when run' do
104
+ before(:each) do
105
+ @rc = MockRestClient.new
106
+ domain = @rc.add_domain("mockdomain")
107
+ end
108
+ it { expect { run }.should raise_error(ArgumentError, /The --no-dns option can't be used in conjunction with --enable-jenkins/) }
109
+ end
110
+ end
111
+
112
+ describe 'app create enable-jenkins with same name as app' do
113
+ let(:arguments) { ['app', 'create', 'app1', 'mock_unique_standalone_cart', '--trace', '--enable-jenkins', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
114
+
115
+ context 'when run' do
116
+ before(:each) do
117
+ @rc = MockRestClient.new
118
+ domain = @rc.add_domain("mockdomain")
119
+ end
120
+ it { expect { run }.should raise_error(ArgumentError, /You have named both your main application and your Jenkins application/) }
121
+ end
122
+ end
123
+
124
+ describe 'app create enable-jenkins with existing jenkins' do
125
+ let(:arguments) { ['app', 'create', 'app1', 'mock_unique_standalone_cart', '--trace', '--enable-jenkins', 'jenkins2', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
126
+
127
+ context 'when run' do
128
+ before(:each) do
129
+ @rc = MockRestClient.new
130
+ @domain = @rc.add_domain("mockdomain")
131
+ @domain.add_application("jenkins", "jenkins-1.4")
132
+ end
133
+ it "should use existing jenkins" do
134
+ expect { run }.should exit_with_code(0)
135
+ expect { @domain.find_application("jenkins") }.should_not raise_error
136
+ expect { @domain.find_application("jenkins2") }.should raise_error(RHC::ApplicationNotFoundException)
137
+ end
138
+ end
139
+ end
140
+
141
+ describe 'app create enable-jenkins named after existing app' do
142
+ let(:arguments) { ['app', 'create', 'app1', 'mock_unique_standalone_cart', '--trace', '--enable-jenkins', 'app2', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
143
+
144
+ context 'when run' do
145
+ before(:each) do
146
+ @rc = MockRestClient.new
147
+ domain = @rc.add_domain("mockdomain")
148
+ domain.add_application("app2", "mock_unique_standalone_cart")
149
+ end
150
+ it { expect { run }.should raise_error(ArgumentError, /You have named your Jenkins application the same as an existing application/) }
151
+ end
152
+ end
153
+
154
+ describe 'app create jenkins fails to install warnings' do
155
+ let(:arguments) { ['app', 'create', 'app1', 'mock_unique_standalone_cart', '--enable-jenkins', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
156
+
157
+ before(:each) do
158
+ @rc = MockRestClient.new
159
+ @domain = @rc.add_domain("mockdomain")
160
+ end
161
+
162
+ context 'when run with error in jenkins setup' do
163
+ before(:each) do
164
+ @instance.stub(:setup_jenkins_app) { raise Exception }
165
+ end
166
+ it "should print out jenkins warning" do
167
+ run_output.should match("Jenkins failed to install")
168
+ end
169
+ end
170
+
171
+ context 'when run with error in jenkins-client setup' do
172
+ before(:each) do
173
+ @instance.stub(:setup_jenkins_client) { raise Exception }
174
+ end
175
+ it "should print out jenkins warning" do
176
+ run_output.should match("Jenkins client failed to install")
177
+ end
178
+ end
179
+ end
180
+
181
+ describe 'app create jenkins install with retries' do
182
+ let(:arguments) { ['app', 'create', 'app1', 'mock_unique_standalone_cart', '--enable-jenkins', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
183
+
184
+ context 'when run with server error in jenkins-client setup' do
185
+ before(:each) do
186
+ @rc = MockRestClient.new
187
+ @domain = @rc.add_domain("mockdomain")
188
+ @instance.stub(:setup_jenkins_client) { raise RHC::Rest::ServerErrorException.new("Server error", 157) }
189
+ end
190
+ it "should fail embedding jenkins cartridge" do
191
+ run_output.should match("Jenkins client failed to install")
192
+ end
193
+ end
194
+
195
+ end
196
+
197
+ describe 'dns app create warnings' do
198
+ let(:arguments) { ['app', 'create', 'app1', 'mock_unique_standalone_cart', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
199
+
200
+ context 'when run' do
201
+ before(:each) do
202
+ @rc = MockRestClient.new
203
+ @domain = @rc.add_domain("dnserror")
204
+ end
205
+ it { run_output.should match("unable to lookup your hostname") }
206
+ end
207
+ end
208
+
209
+ describe 'app create git warnings' do
210
+ let(:arguments) { ['app', 'create', 'app1', 'mock_unique_standalone_cart', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
211
+
212
+ before(:each) do
213
+ @rc = MockRestClient.new
214
+ @domain = @rc.add_domain("mockdomain")
215
+ @instance.stub(:run_git_clone) { raise RHC::GitException }
216
+ end
217
+
218
+ context 'when run with error in git clone' do
219
+ it "should print out git warning" do
220
+ run_output.should match("We were unable to clone your application's git repo")
221
+ end
222
+ end
223
+
224
+ context 'when run with windows and no nslookup bug' do
225
+ before(:each) do
226
+ RHC::Helpers.stub(:windows?) { true }
227
+ @instance.stub(:run_nslookup) { true }
228
+ @instance.stub(:run_ping) { true }
229
+ end
230
+ it "should print out git warning" do
231
+ run_output.should match(" We were unable to clone your application's git repo")
232
+ end
233
+ end
234
+
235
+ context 'when run with windows nslookup bug' do
236
+ before(:each) do
237
+ RHC::Helpers.stub(:windows?) { true }
238
+ @instance.stub(:run_nslookup) { true }
239
+ @instance.stub(:run_ping) { false }
240
+ end
241
+ it "should print out windows warning" do
242
+ run_output.should match("This may also be related to an issue with Winsock on Windows")
243
+ end
244
+ end
245
+ end
246
+
247
+ describe 'app create --nogit deprecated' do
248
+ let(:arguments) { ['app', 'create', 'app1', 'mock_unique_standalone_cart', '--noprompt', '--nogit', '--config', '/tmp/test.conf', '-l', 'test@test.foo', '-p', 'password'] }
249
+
250
+ before (:each) do
251
+ @rc = MockRestClient.new
252
+ @domain = @rc.add_domain("mockdomain")
253
+ end
254
+
255
+ context 'when run' do
256
+ it { run_output.should match("The option '--nogit' is deprecated. Please use '--\\[no-\\]git' instead") }
257
+ end
258
+ end
259
+
260
+ describe 'app create prompt for sshkeys' do
261
+ let(:arguments) { ['app', 'create', 'app1', 'mock_unique_standalone_cart', '--config', '/tmp/test.conf', '-l', 'test@test.foo', '-p', 'password'] }
262
+
263
+ before (:each) do
264
+ @rc = MockRestClient.new
265
+ @domain = @rc.add_domain("mockdomain")
266
+ # fakefs is activated
267
+ Dir.mkdir('/tmp/')
268
+ File.open('/tmp/test.conf', 'w') do |f|
269
+ f.write("rhlogin=test@test.foo")
270
+ end
271
+
272
+ # don't run wizard here because we test this elsewhere
273
+ wizard_instance = RHC::SSHWizard.new(@rc)
274
+ wizard_instance.stub(:ssh_key_uploaded?) { true }
275
+ RHC::SSHWizard.stub(:new) { wizard_instance }
276
+ RHC::Config.stub(:should_run_ssh_wizard?) { false }
277
+ end
278
+
279
+ context 'when run' do
280
+ it { expect { run }.should exit_with_code(0) }
281
+ end
282
+ end
283
+
284
+ describe 'app git-clone' do
285
+ let(:arguments) { ['app', 'git-clone', '--trace', '-a', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
286
+
287
+ context 'when run' do
288
+ before(:each) do
289
+ @rc = MockRestClient.new
290
+ @domain = @rc.add_domain("mockdomain")
291
+ @app = @domain.add_application("app1", "mock_unique_standalone_cart")
292
+ end
293
+ it { expect { run }.should exit_with_code(0) }
294
+ end
295
+ end
296
+
297
+ describe 'app delete' do
298
+ let(:arguments) { ['app', 'delete', '--trace', '-a', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
299
+
300
+ context 'when run' do
301
+ before(:each) do
302
+ @rc = MockRestClient.new
303
+ @domain = @rc.add_domain("mockdomain")
304
+ end
305
+ it "should not remove app when no is sent as input" do
306
+ @app = @domain.add_application("app1", "mock_type")
307
+ expect { run(["no"]) }.should exit_with_code(0)
308
+ @domain.applications.length.should == 1
309
+ @domain.applications[0] == @app
310
+ end
311
+
312
+ it "should remove app when yes is sent as input" do
313
+ @app = @domain.add_application("app1", "mock_type")
314
+ expect { run(["yes"]) }.should exit_with_code(0)
315
+ @domain.applications.length.should == 0
316
+ end
317
+ it "should raise cartridge not found exception when no apps exist" do
318
+ expect { run }.should raise_error RHC::ApplicationNotFoundException
319
+ end
320
+ end
321
+ end
322
+
323
+ describe 'app show' do
324
+ let(:arguments) { ['app', 'show', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
325
+
326
+ context 'when run' do
327
+ before(:each) do
328
+ @rc = MockRestClient.new
329
+ @domain = @rc.add_domain("mockdomain")
330
+ @domain.add_application("app1", "mock_type")
331
+ end
332
+ it { run_output.should match("app1 @ https://app1-mockdomain.fake.foo/") }
333
+ end
334
+
335
+ context 'when run with scaled app' do
336
+ before(:each) do
337
+ @rc = MockRestClient.new
338
+ @domain = @rc.add_domain("mockdomain")
339
+ @domain.add_application("app1", "mock_type",true)
340
+ end
341
+ it { run_output.should match("app1 @ https://app1-mockdomain.fake.foo/") }
342
+ it { run_output.should match("Scaled x2") }
343
+ end
344
+ end
345
+
346
+ describe 'app show --state' do
347
+ let(:arguments) { ['app', 'show', 'app1', '--state', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
348
+
349
+ context 'when run' do
350
+ before(:each) do
351
+ @rc = MockRestClient.new
352
+ @domain = @rc.add_domain("mockdomain")
353
+ @domain.add_application("app1", "mock_type")
354
+ end
355
+ it { run_output.should match("started") }
356
+ end
357
+ end
358
+
359
+ describe 'app status' do
360
+ let(:arguments) { ['app', 'status', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
361
+
362
+ context 'when run' do
363
+ before(:each) do
364
+ @rc = MockRestClient.new
365
+ @domain = @rc.add_domain("mockdomain")
366
+ @domain.add_application("app1", "mock_type")
367
+ end
368
+ it { run_output.should match("started") }
369
+ it { run_output.should match("deprecated") }
370
+ end
371
+ end
372
+
373
+ describe 'app actions' do
374
+
375
+ before(:each) do
376
+ @rc = MockRestClient.new
377
+ domain = @rc.add_domain("mockdomain")
378
+ app = domain.add_application("app1", "mock_type")
379
+ app.add_cartridge('mock_cart-1')
380
+ end
381
+
382
+ context 'app start' do
383
+ let(:arguments) { ['app', 'start', '-a', 'app1','--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
384
+ it { run_output.should match('start') }
385
+ end
386
+
387
+ context 'app stop' do
388
+ let(:arguments) { ['app', 'stop', 'app1','--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
389
+
390
+ it { run_output.should match('stop') }
391
+ end
392
+
393
+ context 'app force stop' do
394
+ let(:arguments) { ['app', 'force-stop', 'app1','--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
395
+
396
+ it { run_output.should match('force') }
397
+ end
398
+
399
+ context 'app restart' do
400
+ let(:arguments) { ['app', 'restart', 'app1','--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
401
+ it { run_output.should match('restart') }
402
+ end
403
+
404
+ context 'app reload' do
405
+ let(:arguments) { ['app', 'reload', 'app1','--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
406
+ it { run_output.should match('reload') }
407
+ end
408
+
409
+ context 'app tidy' do
410
+ let(:arguments) { ['app', 'tidy', 'app1','--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
411
+ it { run_output.should match('cleaned') }
412
+ end
413
+ end
414
+ end