startapp 0.1.11 → 0.1.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/features/app_feature.rb +25 -0
  4. data/features/core_feature.rb +4 -2
  5. data/features/members_feature.rb +21 -1
  6. data/lib/rhc/commands/app.rb +64 -13
  7. data/lib/rhc/commands/apps.rb +7 -3
  8. data/lib/rhc/commands/create.rb +2 -1
  9. data/lib/rhc/commands/domain.rb +2 -1
  10. data/lib/rhc/commands/member.rb +348 -76
  11. data/lib/rhc/commands/scp.rb +15 -6
  12. data/lib/rhc/commands/snapshot.rb +5 -80
  13. data/lib/rhc/commands/team.rb +103 -0
  14. data/lib/rhc/context_helper.rb +57 -15
  15. data/lib/rhc/exceptions.rb +26 -2
  16. data/lib/rhc/git_helpers.rb +1 -1
  17. data/lib/rhc/helpers.rb +1 -1
  18. data/lib/rhc/output_helpers.rb +33 -8
  19. data/lib/rhc/rest/api.rb +1 -1
  20. data/lib/rhc/rest/cartridge.rb +6 -1
  21. data/lib/rhc/rest/client.rb +124 -5
  22. data/lib/rhc/rest/membership.rb +51 -6
  23. data/lib/rhc/rest/mock.rb +82 -8
  24. data/lib/rhc/rest/team.rb +34 -0
  25. data/lib/rhc/rest.rb +1 -0
  26. data/lib/rhc/ssh_helpers.rb +88 -0
  27. data/lib/rhc/usage_templates/command_help.erb +13 -3
  28. data/lib/rhc/usage_templates/command_syntax_help.erb +11 -0
  29. data/spec/direct_execution_helper.rb +1 -0
  30. data/spec/rhc/command_spec.rb +22 -3
  31. data/spec/rhc/commands/app_spec.rb +81 -3
  32. data/spec/rhc/commands/apps_spec.rb +41 -1
  33. data/spec/rhc/commands/domain_spec.rb +1 -1
  34. data/spec/rhc/commands/member_spec.rb +393 -22
  35. data/spec/rhc/commands/scp_spec.rb +14 -3
  36. data/spec/rhc/commands/snapshot_spec.rb +1 -2
  37. data/spec/rhc/commands/team_spec.rb +191 -0
  38. data/spec/rhc/helpers_spec.rb +2 -0
  39. data/spec/rhc/rest_client_spec.rb +23 -0
  40. data/spec/rhc/rest_spec.rb +5 -5
  41. data/spec/spec_helper.rb +36 -0
  42. metadata +8 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3273849d96283aa44ad1b0258b5adc134d84f505
4
- data.tar.gz: 8fa2feaa6770f0c9d2631551dc81ce5d71832cd3
3
+ metadata.gz: e13052412a98ea1d21434f471024f9f07a51aff3
4
+ data.tar.gz: c8d60adc7432be67b81528b3ef87a0eedd642c94
5
5
  SHA512:
6
- metadata.gz: c958c30189bff712117922940cc776a27081a35b9dd0f6e51066fc08e20492df4a064481d0de030f76641a8a68d17c188e5e7f6a34a81f631a1c067d21ea11c8
7
- data.tar.gz: baa4dad7bec30f1d91c28eb655beb16f8ec9a9b020f64787a207a8f9e9a8518152fa5b571bf57fb9f9df35a5badede7aa40790c1c86267ed8cd151c755c3d663
6
+ metadata.gz: 6b2e0ada6ed5bba114b7e5cadd47c6c5bf526e24b1747e91a64435285838d0adb2d92b1e997e3a778b71f82fd8f3091fdaed76d7be74313a94d0d3c75f83e79b
7
+ data.tar.gz: b5aac4e369506a156a9e55c5c6d893f818405c28a51b3bf956288a146bc9af8be74449a8db91fed0103b9f239eb37239922fa9569d0887eac1aaba2f7c5a7f3c
data/README.md CHANGED
@@ -7,8 +7,8 @@ info on installing the tool on each supported operating system.
7
7
 
8
8
  Please stop by #openshift on irc.freenode.net if you have any questions or
9
9
  comments. For more information about OpenShift, visit https://openshift.redhat.com
10
- or the OpenShift forum
11
- https://openshift.redhat.com/community/forums/openshift.
10
+ or the OpenShift support page
11
+ https://openshift.redhat.com/support.
12
12
 
13
13
 
14
14
  ## Using RHC to create an application
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+ require 'direct_execution_helper'
3
+
4
+ describe "rhc app scenarios" do
5
+ context "with an existing app" do
6
+ before(:all) do
7
+ standard_config
8
+ @app = has_an_application
9
+ end
10
+
11
+ let(:app){ @app }
12
+
13
+ it "should clone successfully" do
14
+ app_name = "clone#{random}"
15
+ r = rhc 'create-app', app_name, '--from-app', app.name
16
+ r.stdout.should match /Domain:\s+#{app.domain}/
17
+ r.stdout.should match /Cartridges:\s+#{app.cartridges.collect{|c| c.name}.join(', ')}/
18
+ r.stdout.should match /From app:\s+#{app.name}/
19
+ r.stdout.should match /Gear Size:\s+Copied from '#{app.name}'/
20
+ r.stdout.should match /Scaling:\s+#{app.scalable? ? 'yes' : 'no'}/
21
+ r.stdout.should match /Setting deployment configuration/
22
+ r.stdout.should match /Pulling down a snapshot of application '#{app.name}'/
23
+ end
24
+ end
25
+ end
@@ -50,6 +50,7 @@ describe "rhc core scenarios" do
50
50
  context "when creating an app" do
51
51
  when_running 'create-app', 'test1', a_web_cartridge
52
52
  before{ no_applications }
53
+ after { no_applications }
53
54
  it "returns the proper info and is in the rest api" do
54
55
  status.should == 0
55
56
  output.should match "Your application 'test1' is now available"
@@ -69,6 +70,7 @@ describe "rhc core scenarios" do
69
70
  standard_config
70
71
  @app = has_an_application
71
72
  end
73
+ after(:all){ @app.destroy }
72
74
 
73
75
  let(:app){ @app }
74
76
 
@@ -159,12 +161,12 @@ describe "rhc core scenarios" do
159
161
 
160
162
  context "when adding a cartridge" do
161
163
  context "with a scalable app" do
162
- before(:all) do
164
+ before(:each) do
163
165
  standard_config
164
166
  @app = has_a_scalable_application
165
167
  end
166
168
 
167
- after(:all) do
169
+ after(:each) do
168
170
  debug.puts "cleaning up scalable app" if debug?
169
171
  @app.destroy
170
172
  end
@@ -104,7 +104,7 @@ describe "rhc member scenarios" do
104
104
  members.any?{ |m| m.id == other_users[user1].id && m.editor? }.should be_true
105
105
  members.any?{ |m| m.id == other_users[user2].id && m.editor? }.should be_true
106
106
 
107
- r = rhc 'remove-member', domain.name, '--all'
107
+ r = rhc 'remove-member', '-n', domain.name, '--all'
108
108
  r.status.should == 0
109
109
  r.stdout.should match "Removing all members from domain.*done"
110
110
  members = client.find_domain(domain.name).members
@@ -161,6 +161,26 @@ describe "rhc member scenarios" do
161
161
  r.status.should == 0
162
162
  end
163
163
  end
164
+
165
+ it "should filter applications by owner" do
166
+ user = other_user.login
167
+ name = @domain.applications.first.name
168
+
169
+ r = rhc 'add-member', user, '--role', 'admin', '-n', domain.name
170
+ r.status.should == 0
171
+
172
+ with_environment(other_user) do
173
+ r = rhc 'apps', '--mine'
174
+ #r.status.should == 0
175
+ r.stdout.should match "No applications"
176
+
177
+ r = rhc 'apps'
178
+ r.status.should == 0
179
+ r.stdout.should match /You have access to \d+ applications?/
180
+ end
181
+ end
182
+
183
+ after { @domain.applications.first.destroy }
164
184
  end
165
185
  end
166
186
  end
@@ -51,9 +51,10 @@ module RHC::Commands
51
51
  syntax "<name> <cartridge> [... <cartridge>] [... VARIABLE=VALUE] [-n namespace]"
52
52
  option ["-n", "--namespace NAME"], "Namespace for the application"
53
53
  option ["-g", "--gear-size SIZE"], "Gear size controls how much memory and CPU your cartridges can use."
54
- option ["-s", "--scaling"], "Enable scaling for the web cartridge."
54
+ option ["-s", "--[no-]scaling"], "Enable scaling for the web cartridge."
55
55
  option ["-r", "--repo DIR"], "Path to the Git repository (defaults to ./$app_name)"
56
56
  option ["-e", "--env VARIABLE=VALUE"], "Environment variable(s) to be set on this app, or path to a file containing environment variables", :type => :list
57
+ option ["--from-app NAME"], "Create based on another application. All content and configurations will be copied from the original app."
57
58
  option ["--from-code URL"], "URL to a Git repository that will become the initial contents of the application"
58
59
  option ["--[no-]git"], "Skip creating the local Git repository."
59
60
  option ["--[no-]dns"], "Skip waiting for the application DNS name to resolve. Must be used in combination with --no-git"
@@ -68,6 +69,22 @@ module RHC::Commands
68
69
 
69
70
  arg_envs, cartridges = cartridges.partition{|item| item.match(env_var_regex_pattern)}
70
71
 
72
+ rest_domain = check_domain!
73
+ rest_app = nil
74
+ repo_dir = nil
75
+
76
+ if options.from_app
77
+ raise RHC::AppCloneNotSupportedException, "The server does not support creating apps based on others (rhc create-app --from-app)." if (!rest_domain.has_param?('ADD_APPLICATION', 'cartridges[][name]') || !rest_domain.has_param?('ADD_APPLICATION', 'cartridges[][url]'))
78
+ raise ArgumentError, "Option --from-code is incompatible with --from--app. When creating an app based on another resource you can either specify a Git repository URL with --from-code or an existing app name with --from-app." if options.from_code
79
+ raise ArgumentError, "Option --no-dns is incompatible with --from-app. We need to propagate the new app DNS to be able to configure it." if options.dns == false
80
+ raise ArgumentError, "Do not specify cartridges when creating an app based on another one. All cartridges will be copied from the original app." if !(cartridges || []).empty?
81
+
82
+ from_app = find_app(:app => options.from_app)
83
+
84
+ arg_envs = from_app.environment_variables.collect {|env| "#{env.name}=#{env.value} "} + arg_envs
85
+ cartridges = from_app.cartridges.reject{|c| c.tags.include?('web_proxy')}.collect{|c| c.custom? ? c.url : c.name}
86
+ end
87
+
71
88
  cartridges = check_cartridges(cartridges, &require_one_web_cart)
72
89
 
73
90
  options.default \
@@ -76,10 +93,6 @@ module RHC::Commands
76
93
 
77
94
  raise ArgumentError, "You have named both your main application and your Jenkins application '#{name}'. In order to continue you'll need to specify a different name with --enable-jenkins or choose a different application name." if jenkins_app_name == name && enable_jenkins?
78
95
 
79
- rest_domain = check_domain!
80
- rest_app = nil
81
- repo_dir = nil
82
-
83
96
  cart_names = cartridges.collect do |c|
84
97
  c.usage_rate? ? "#{c.short_name} (addtl. costs may apply)" : c.short_name
85
98
  end.join(', ')
@@ -90,13 +103,31 @@ module RHC::Commands
90
103
  warn "Server does not support environment variables."
91
104
  end
92
105
 
106
+ scaling = options.scaling
107
+
108
+ if from_app
109
+ scaling = from_app.scalable if scaling.nil?
110
+
111
+ cartridges = from_app.cartridges.reject{|c| c.tags.include?('web_proxy')}.collect do |cartridge|
112
+ {
113
+ :name => (cartridge.name if !cartridge.custom?),
114
+ :url => (cartridge.url if cartridge.custom?),
115
+ :gear_size => options.gear_size || cartridge.gear_profile,
116
+ :additional_gear_storage => (cartridge.additional_gear_storage if cartridge.additional_gear_storage > 0),
117
+ :scales_from => (cartridge.scales_from if cartridge.scalable?),
118
+ :scales_to => (cartridge.scales_to if cartridge.scalable?)
119
+ }.reject{|k,v| v.nil? }
120
+ end
121
+ end
122
+
93
123
  paragraph do
94
124
  header "Application Options"
95
125
  say table([["Domain:", options.namespace],
96
126
  ["Cartridges:", cart_names],
97
127
  (["Source Code:", options.from_code] if options.from_code),
98
- ["Gear Size:", options.gear_size || "default"],
99
- ["Scaling:", options.scaling ? "yes" : "no"],
128
+ (["From app:", from_app.name] if from_app),
129
+ ["Gear Size:", options.gear_size || (from_app ? "Copied from '#{from_app.name}'" : "default")],
130
+ ["Scaling:", (scaling ? "yes" : "no") + (from_app && options.scaling.nil? ? " (copied from '#{from_app.name}')" : '')],
100
131
  (["Environment Variables:", env.map{|item| "#{item.name}=#{item.value}"}.join(', ')] if env.present?),
101
132
  ].compact
102
133
  )
@@ -106,7 +137,7 @@ module RHC::Commands
106
137
  say "Creating application '#{name}' ... "
107
138
 
108
139
  # create the main app
109
- rest_app = create_app(name, cartridges, rest_domain, options.gear_size, options.scaling, options.from_code, env, options.auto_deploy, options.keep_deployments, options.deployment_branch)
140
+ rest_app = create_app(name, cartridges, rest_domain, options.gear_size, scaling, options.from_code, env, options.auto_deploy, options.keep_deployments, options.deployment_branch, options.deployment_type)
110
141
  success "done"
111
142
 
112
143
  paragraph{ indent{ success rest_app.messages.map(&:strip) } }
@@ -162,6 +193,19 @@ module RHC::Commands
162
193
  end
163
194
  end
164
195
 
196
+ if from_app
197
+ say "Setting deployment configuration ... "
198
+ rest_app.configure({:auto_deploy => from_app.auto_deploy, :keep_deployments => from_app.keep_deployments , :deployment_branch => from_app.deployment_branch, :deployment_type => from_app.deployment_type})
199
+ success 'done'
200
+
201
+ snapshot_filename = temporary_snapshot_filename(from_app.name)
202
+ save_snapshot(from_app, snapshot_filename)
203
+ restore_snapshot(rest_app, snapshot_filename)
204
+ File.delete(snapshot_filename) if File.exist?(snapshot_filename)
205
+
206
+ paragraph { warn "The application '#{from_app.name}' has aliases set which were not copied. Please configure the aliases of your new application manually." } unless from_app.aliases.empty?
207
+ end
208
+
165
209
  if options.git
166
210
  section(:now => true, :top => 1, :bottom => 1) do
167
211
  begin
@@ -334,6 +378,7 @@ module RHC::Commands
334
378
  option ["--state"], "Get the current state of the cartridges in this application"
335
379
  option ["--configuration"], "Get the current configuration values set in this application"
336
380
  option ["--gears [quota|ssh]"], "Show information about the cartridges on each gear in this application. Pass 'quota' to see per gear disk usage and limits. Pass 'ssh' to print only the SSH connection strings of each gear."
381
+ option ["-v", "--verbose"], "Display more details about the application's cartridges"
337
382
  def show(app_name)
338
383
 
339
384
  if options.state
@@ -377,7 +422,7 @@ module RHC::Commands
377
422
 
378
423
  else
379
424
  app = find_app(:include => :cartridges)
380
- display_app(app, app.cartridges)
425
+ display_app(app, app.cartridges, nil, options.verbose)
381
426
  end
382
427
 
383
428
  0
@@ -515,20 +560,21 @@ module RHC::Commands
515
560
  result
516
561
  end
517
562
 
518
- def create_app(name, cartridges, rest_domain, gear_size=nil, scale=nil, from_code=nil, environment_variables=nil, auto_deploy=nil, keep_deployments=nil, deployment_branch=nil)
563
+ def create_app(name, cartridges, rest_domain, gear_size=nil, scale=nil, from_code=nil, environment_variables=nil, auto_deploy=nil, keep_deployments=nil, deployment_branch=nil, deployment_type=nil)
519
564
  app_options = {:cartridges => Array(cartridges)}
520
565
  app_options[:gear_profile] = gear_size if gear_size
521
566
  app_options[:scale] = scale if scale
522
567
  app_options[:initial_git_url] = from_code if from_code
523
568
  app_options[:debug] = true if @debug
524
- app_options[:environment_variables] = environment_variables.map{ |item| item.to_hash } if environment_variables.present?
569
+ app_options[:environment_variables] = environment_variables.map{|i| i.to_hash}.group_by{|i| i[:name]}.values.map(&:last) if environment_variables.present?
525
570
  app_options[:auto_deploy] = auto_deploy if !auto_deploy.nil?
526
571
  app_options[:keep_deployments] = keep_deployments if keep_deployments
527
572
  app_options[:deployment_branch] = deployment_branch if deployment_branch
573
+ app_options[:deployment_type] = deployment_type if deployment_type
528
574
  debug "Creating application '#{name}' with these options - #{app_options.inspect}"
529
- rest_app = rest_domain.add_application(name, app_options)
530
575
 
531
- rest_app
576
+ rest_domain.add_application(name, app_options)
577
+
532
578
  rescue RHC::Rest::Exception => e
533
579
  if e.code == 109
534
580
  paragraph{ say "Valid cartridge types:" }
@@ -722,5 +768,10 @@ WARNING_OUTPUT
722
768
  def issues?
723
769
  not @issues.nil?
724
770
  end
771
+
772
+ def temporary_snapshot_filename(app_name)
773
+ "#{Dir.tmpdir}/#{app_name}_temp_clone.tar.gz"
774
+ end
775
+
725
776
  end
726
777
  end
@@ -4,16 +4,20 @@ module RHC::Commands
4
4
  class Apps < Base
5
5
  summary "List all your applications"
6
6
  description "Display the list of applications that you own. Includes information about each application."
7
+ option ['--mine'], "Display only applications you own"
8
+ option ["-v", "--verbose"], "Display additional details about the application's cartridges"
7
9
  def run
8
- applications = rest_client.applications(:include => :cartridges).sort
10
+ applications = (options.mine ?
11
+ rest_client.owned_applications(:include => :cartridges) :
12
+ rest_client.applications(:include => :cartridges)).sort
9
13
 
10
14
  info "In order to deploy applications, you must create a domain with 'app setup' or 'app create-domain'." and return 1 if applications.empty? && rest_client.domains.empty?
11
15
 
12
- applications.each{ |a| display_app(a, a.cartridges) }.blank? and
16
+ applications.each{ |a| display_app(a, a.cartridges, nil, options.verbose) }.blank? and
13
17
  info "No applications. Use 'app create-app'." and
14
18
  return 1
15
19
 
16
- success "You have #{applications.length} applications"
20
+ success "You have#{options.mine ? '' : ' access to'} #{pluralize(applications.length, 'application')}."
17
21
  0
18
22
  end
19
23
  end
@@ -39,9 +39,10 @@ module RHC::Commands
39
39
  syntax "<name> <cartridge> [... <cartridge>] [... VARIABLE=VALUE] [-n namespace]"
40
40
  option ["-n", "--namespace NAME"], "Namespace for the application"
41
41
  option ["-g", "--gear-size SIZE"], "Gear size controls how much memory and CPU your cartridges can use."
42
- option ["-s", "--scaling"], "Enable scaling for the web cartridge."
42
+ option ["-s", "--[no-]scaling"], "Enable scaling for the web cartridge."
43
43
  option ["-r", "--repo DIR"], "Path to the Git repository (defaults to ./$app_name)"
44
44
  option ["-e", "--env VARIABLE=VALUE"], "Environment variable(s) to be set on this app, or path to a file containing environment variables", :type => :list
45
+ option ["--from-app NAME"], "Create based on another application. All content and configurations will be copied from the original app."
45
46
  option ["--from-code URL"], "URL to a Git repository that will become the initial contents of the application"
46
47
  option ["--[no-]git"], "Skip creating the local Git repository."
47
48
  option ["--[no-]dns"], "Skip waiting for the application DNS name to resolve. Must be used in combination with --no-git"
@@ -149,8 +149,9 @@ module RHC::Commands
149
149
  domain = rest_client.find_domain(namespace)
150
150
 
151
151
  say "Leaving domain ... "
152
- domain.leave
152
+ result = domain.leave
153
153
  success "done"
154
+ result.messages.each{ |s| paragraph{ say s } }
154
155
 
155
156
  0
156
157
  end