cloulu 0.0.0 → 0.1.1

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 (152) hide show
  1. data/bin/{cloulu → cl} +0 -0
  2. data/lib/cc_api_stub/applications.rb +53 -0
  3. data/lib/cc_api_stub/domains.rb +16 -0
  4. data/lib/cc_api_stub/frameworks.rb +22 -0
  5. data/lib/cc_api_stub/helper.rb +131 -0
  6. data/lib/cc_api_stub/login.rb +21 -0
  7. data/lib/cc_api_stub/organization_users.rb +21 -0
  8. data/lib/cc_api_stub/organizations.rb +70 -0
  9. data/lib/cc_api_stub/routes.rb +26 -0
  10. data/lib/cc_api_stub/runtimes.rb +22 -0
  11. data/lib/cc_api_stub/service_bindings.rb +22 -0
  12. data/lib/cc_api_stub/service_instances.rb +22 -0
  13. data/lib/cc_api_stub/services.rb +25 -0
  14. data/lib/cc_api_stub/spaces.rb +49 -0
  15. data/lib/cc_api_stub/users.rb +84 -0
  16. data/lib/cc_api_stub.rb +17 -0
  17. data/lib/cfoundry/auth_token.rb +63 -0
  18. data/lib/cfoundry/baseclient.rb +201 -0
  19. data/lib/cfoundry/chatty_hash.rb +46 -0
  20. data/lib/cfoundry/client.rb +46 -0
  21. data/lib/cfoundry/concerns/login_helpers.rb +13 -0
  22. data/lib/cfoundry/errors.rb +160 -0
  23. data/lib/cfoundry/rest_client.rb +299 -0
  24. data/lib/cfoundry/test_support.rb +3 -0
  25. data/lib/cfoundry/trace_helpers.rb +40 -0
  26. data/lib/cfoundry/uaaclient.rb +112 -0
  27. data/lib/cfoundry/upload_helpers.rb +187 -0
  28. data/lib/cfoundry/v1/app.rb +363 -0
  29. data/lib/cfoundry/v1/base.rb +72 -0
  30. data/lib/cfoundry/v1/client.rb +193 -0
  31. data/lib/cfoundry/v1/framework.rb +21 -0
  32. data/lib/cfoundry/v1/model.rb +178 -0
  33. data/lib/cfoundry/v1/model_magic.rb +129 -0
  34. data/lib/cfoundry/v1/runtime.rb +24 -0
  35. data/lib/cfoundry/v1/service.rb +39 -0
  36. data/lib/cfoundry/v1/service_instance.rb +32 -0
  37. data/lib/cfoundry/v1/service_plan.rb +19 -0
  38. data/lib/cfoundry/v1/user.rb +22 -0
  39. data/lib/cfoundry/v2/app.rb +392 -0
  40. data/lib/cfoundry/v2/base.rb +83 -0
  41. data/lib/cfoundry/v2/client.rb +138 -0
  42. data/lib/cfoundry/v2/domain.rb +11 -0
  43. data/lib/cfoundry/v2/framework.rb +14 -0
  44. data/lib/cfoundry/v2/model.rb +148 -0
  45. data/lib/cfoundry/v2/model_magic.rb +449 -0
  46. data/lib/cfoundry/v2/organization.rb +16 -0
  47. data/lib/cfoundry/v2/route.rb +15 -0
  48. data/lib/cfoundry/v2/runtime.rb +12 -0
  49. data/lib/cfoundry/v2/service.rb +19 -0
  50. data/lib/cfoundry/v2/service_auth_token.rb +9 -0
  51. data/lib/cfoundry/v2/service_binding.rb +10 -0
  52. data/lib/cfoundry/v2/service_instance.rb +14 -0
  53. data/lib/cfoundry/v2/service_plan.rb +12 -0
  54. data/lib/cfoundry/v2/space.rb +18 -0
  55. data/lib/cfoundry/v2/user.rb +64 -0
  56. data/lib/cfoundry/validator.rb +39 -0
  57. data/lib/cfoundry/version.rb +4 -0
  58. data/lib/cfoundry/zip.rb +56 -0
  59. data/lib/cfoundry.rb +2 -0
  60. data/lib/manifests-vmc-plugin/errors.rb +21 -0
  61. data/lib/manifests-vmc-plugin/loader/builder.rb +34 -0
  62. data/lib/manifests-vmc-plugin/loader/normalizer.rb +149 -0
  63. data/lib/manifests-vmc-plugin/loader/resolver.rb +79 -0
  64. data/lib/manifests-vmc-plugin/loader.rb +31 -0
  65. data/lib/manifests-vmc-plugin/plugin.rb +145 -0
  66. data/lib/manifests-vmc-plugin/version.rb +3 -0
  67. data/lib/manifests-vmc-plugin.rb +313 -0
  68. data/lib/mothership/base.rb +99 -0
  69. data/lib/mothership/callbacks.rb +85 -0
  70. data/lib/mothership/command.rb +146 -0
  71. data/lib/mothership/errors.rb +38 -0
  72. data/lib/mothership/help/commands.rb +53 -0
  73. data/lib/mothership/help/printer.rb +170 -0
  74. data/lib/mothership/help.rb +64 -0
  75. data/lib/mothership/inputs.rb +189 -0
  76. data/lib/mothership/parser.rb +182 -0
  77. data/lib/mothership/version.rb +3 -0
  78. data/lib/mothership.rb +64 -0
  79. data/lib/tunnel-vmc-plugin/plugin.rb +178 -0
  80. data/lib/tunnel-vmc-plugin/tunnel.rb +308 -0
  81. data/lib/tunnel-vmc-plugin/version.rb +3 -0
  82. data/lib/uaa/http.rb +168 -0
  83. data/lib/uaa/misc.rb +121 -0
  84. data/lib/uaa/scim.rb +292 -0
  85. data/lib/uaa/token_coder.rb +196 -0
  86. data/lib/uaa/token_issuer.rb +255 -0
  87. data/lib/uaa/util.rb +235 -0
  88. data/lib/uaa/version.rb +19 -0
  89. data/lib/uaa.rb +18 -0
  90. data/lib/vmc/cli/app/app.rb +45 -0
  91. data/lib/vmc/cli/app/apps.rb +99 -0
  92. data/lib/vmc/cli/app/base.rb +90 -0
  93. data/lib/vmc/cli/app/crashes.rb +42 -0
  94. data/lib/vmc/cli/app/delete.rb +95 -0
  95. data/lib/vmc/cli/app/deprecated.rb +11 -0
  96. data/lib/vmc/cli/app/env.rb +78 -0
  97. data/lib/vmc/cli/app/files.rb +137 -0
  98. data/lib/vmc/cli/app/health.rb +26 -0
  99. data/lib/vmc/cli/app/instances.rb +53 -0
  100. data/lib/vmc/cli/app/logs.rb +76 -0
  101. data/lib/vmc/cli/app/push/create.rb +165 -0
  102. data/lib/vmc/cli/app/push/interactions.rb +94 -0
  103. data/lib/vmc/cli/app/push/sync.rb +64 -0
  104. data/lib/vmc/cli/app/push.rb +109 -0
  105. data/lib/vmc/cli/app/rename.rb +35 -0
  106. data/lib/vmc/cli/app/restart.rb +20 -0
  107. data/lib/vmc/cli/app/scale.rb +71 -0
  108. data/lib/vmc/cli/app/start.rb +143 -0
  109. data/lib/vmc/cli/app/stats.rb +67 -0
  110. data/lib/vmc/cli/app/stop.rb +27 -0
  111. data/lib/vmc/cli/help.rb +11 -0
  112. data/lib/vmc/cli/interactive.rb +105 -0
  113. data/lib/vmc/cli/route/base.rb +12 -0
  114. data/lib/vmc/cli/route/map.rb +82 -0
  115. data/lib/vmc/cli/route/routes.rb +25 -0
  116. data/lib/vmc/cli/route/unmap.rb +94 -0
  117. data/lib/vmc/cli/service/base.rb +8 -0
  118. data/lib/vmc/cli/service/bind.rb +44 -0
  119. data/lib/vmc/cli/service/create.rb +126 -0
  120. data/lib/vmc/cli/service/delete.rb +86 -0
  121. data/lib/vmc/cli/service/rename.rb +35 -0
  122. data/lib/vmc/cli/service/service.rb +42 -0
  123. data/lib/vmc/cli/service/services.rb +114 -0
  124. data/lib/vmc/cli/service/unbind.rb +38 -0
  125. data/lib/vmc/cli/start/base.rb +94 -0
  126. data/lib/vmc/cli/start/colors.rb +13 -0
  127. data/lib/vmc/cli/start/info.rb +126 -0
  128. data/lib/vmc/cli/start/login.rb +97 -0
  129. data/lib/vmc/cli/start/logout.rb +17 -0
  130. data/lib/vmc/cli/start/target.rb +60 -0
  131. data/lib/vmc/cli/start/target_interactions.rb +37 -0
  132. data/lib/vmc/cli/start/targets.rb +16 -0
  133. data/lib/vmc/cli/user/base.rb +29 -0
  134. data/lib/vmc/cli/user/create.rb +39 -0
  135. data/lib/vmc/cli/user/delete.rb +27 -0
  136. data/lib/vmc/cli/user/passwd.rb +50 -0
  137. data/lib/vmc/cli/user/register.rb +42 -0
  138. data/lib/vmc/cli/user/users.rb +32 -0
  139. data/lib/vmc/cli/v2_check_cli.rb +16 -0
  140. data/lib/vmc/cli.rb +474 -0
  141. data/lib/vmc/constants.rb +13 -0
  142. data/lib/vmc/detect.rb +129 -0
  143. data/lib/vmc/errors.rb +19 -0
  144. data/lib/vmc/plugin.rb +56 -0
  145. data/lib/vmc/spacing.rb +89 -0
  146. data/lib/vmc/spec_helper.rb +1 -0
  147. data/lib/vmc/test_support.rb +6 -0
  148. data/lib/vmc/version.rb +3 -0
  149. data/lib/vmc.rb +8 -0
  150. data/vendor/errors/v1.yml +189 -0
  151. data/vendor/errors/v2.yml +360 -0
  152. metadata +303 -190
@@ -0,0 +1,53 @@
1
+ require "vmc/cli/app/base"
2
+
3
+ module VMC::App
4
+ class Instances < Base
5
+ desc "List an app's instances"
6
+ group :apps, :info
7
+ input :apps, :desc => "Applications whose instances to list",
8
+ :argument => :splat, :singular => :app,
9
+ :from_given => by_name(:app)
10
+ def instances
11
+ apps = input[:apps]
12
+ fail "No applications given." if apps.empty?
13
+
14
+ spaced(apps) do |app|
15
+ instances =
16
+ with_progress("Getting instances for #{c(app.name, :name)}") do
17
+ app.instances
18
+ end
19
+
20
+ line unless quiet?
21
+
22
+ spaced(instances.sort { |a, b| a.id.to_i <=> b.id.to_i }) do |i|
23
+ if quiet?
24
+ line i.id
25
+ else
26
+ display_instance(i)
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def display_instance(i)
35
+ start_line "instance #{c("\##{i.id}", :instance)}: "
36
+ puts "#{b(c(i.state.downcase, state_color(i.state)))}"
37
+
38
+ indented do
39
+ if s = i.since
40
+ line "started: #{c(s.strftime("%F %r"), :neutral)}"
41
+ end
42
+
43
+ if d = i.debugger
44
+ line "debugger: port #{b(d[:port])} at #{b(d[:ip])}"
45
+ end
46
+
47
+ if c = i.console
48
+ line "console: port #{b(c[:port])} at #{b(c[:ip])}"
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,76 @@
1
+ require "vmc/cli/app/base"
2
+
3
+ module VMC::App
4
+ class Logs < Base
5
+ desc "Print out an app's logs"
6
+ group :apps, :info
7
+ input :app, :desc => "Application to get the logs of", :argument => true,
8
+ :from_given => by_name(:app)
9
+ input :instance, :desc => "Instance of application to get the logs of",
10
+ :default => "0"
11
+ input :all, :desc => "Get logs for every instance", :default => false
12
+ def logs
13
+ app = input[:app]
14
+
15
+ instances =
16
+ if input[:all] || input[:instance] == "all"
17
+ app.instances
18
+ else
19
+ app.instances.select { |i| i.id == input[:instance] }
20
+ end
21
+
22
+ if instances.empty?
23
+ if input[:all]
24
+ fail "No instances found."
25
+ else
26
+ fail "Instance #{app.name} \##{input[:instance]} not found."
27
+ end
28
+ end
29
+
30
+ spaced(instances) do |i|
31
+ show_instance_logs(app, i)
32
+ end
33
+ end
34
+
35
+ desc "Print out the logs for an app's crashed instances"
36
+ group :apps, :info, :hidden => true
37
+ input :app, :desc => "Application to get the logs of", :argument => true,
38
+ :from_given => by_name(:app)
39
+ def crashlogs
40
+ app = input[:app]
41
+
42
+ crashes = app.crashes
43
+
44
+ fail "No crashed instances found." if crashes.empty?
45
+
46
+ most_recent = crashes.sort_by(&:since).last
47
+ show_instance_logs(app, most_recent)
48
+ end
49
+
50
+ def show_instance_logs(app, i)
51
+ return unless i.id
52
+
53
+ logs =
54
+ with_progress(
55
+ "Getting logs for #{c(app.name, :name)} " +
56
+ c("\##{i.id}", :instance)) do
57
+ i.files("logs")
58
+ end
59
+
60
+ line unless quiet?
61
+
62
+ spaced(logs) do |log|
63
+ begin
64
+ body =
65
+ with_progress("Reading " + b(log.join("/"))) do |s|
66
+ i.file(*log)
67
+ end
68
+
69
+ lines body
70
+ line unless body.empty?
71
+ rescue CFoundry::NotFound
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,165 @@
1
+ require "vmc/detect"
2
+
3
+ module VMC::App
4
+ module Create
5
+ attr_accessor :input
6
+ attr_writer :path
7
+
8
+ def get_inputs
9
+ inputs = {}
10
+ inputs[:name] = input[:name]
11
+ inputs[:total_instances] = input[:instances]
12
+ inputs[:space] = client.current_space if client.current_space
13
+
14
+ if v2?
15
+ inputs[:production] = !!(input[:plan] =~ /^p/i)
16
+ inputs[:command] = input[:command] if input.has?(:command) || !has_procfile?
17
+ else
18
+ framework = inputs[:framework] = determine_framework
19
+ inputs[:runtime] = determine_runtime(framework)
20
+ inputs[:command] = input[:command] if can_have_custom_start_command?(framework)
21
+ end
22
+
23
+ inputs[:buildpack] = input[:buildpack] if v2?
24
+
25
+ if v2?
26
+ detected = detector.detected
27
+ human_mb = human_mb((detected && detected.memory_suggestion) || 64)
28
+ else
29
+ human_mb = human_mb(detector.suggested_memory(framework) || 64)
30
+ end
31
+
32
+ inputs[:memory] = megabytes(input[:memory, human_mb])
33
+
34
+ inputs[:stack] = input[:stack] if v2?
35
+
36
+ inputs
37
+ end
38
+
39
+ def determine_framework
40
+ return input[:framework] if input.has?(:framework)
41
+
42
+ if (detected_framework = detector.detect_framework)
43
+ input[:framework, [detected_framework], detected_framework, :other]
44
+ else
45
+ input[:framework, detector.all_frameworks, nil, nil]
46
+ end
47
+ end
48
+
49
+ def determine_runtime(framework)
50
+ return input[:runtime] if input.has?(:runtime)
51
+
52
+ detected_runtimes =
53
+ if framework.name == "standalone"
54
+ detector.detect_runtimes
55
+ else
56
+ detector.runtimes(framework)
57
+ end
58
+
59
+ default_runtime = detected_runtimes.size == 1 ? detected_runtimes.first : nil
60
+
61
+ if detected_runtimes.empty?
62
+ input[:runtime, detector.all_runtimes, nil, nil]
63
+ else
64
+ input[:runtime, detected_runtimes, default_runtime, :other]
65
+ end
66
+ end
67
+
68
+ def create_app(inputs)
69
+ fail "appname should be at least five characters in length." if inputs[:name].length < 5
70
+
71
+ app = client.app
72
+
73
+ inputs.each { |key, value| app.send(:"#{key}=", value) }
74
+
75
+ app = filter(:create_app, app)
76
+
77
+ with_progress("Creating #{c(app.name, :name)}") do
78
+ wrap_message_format_errors do
79
+ begin
80
+ app.create!
81
+ rescue CFoundry::NotAuthorized
82
+ fail "You need the Project Developer role in #{b(client.current_space.name)} to push."
83
+ end
84
+ end
85
+ end
86
+
87
+ app
88
+ end
89
+
90
+ def map_route(app)
91
+ line unless quiet?
92
+
93
+ host = input[:host, app.name] if v2?
94
+ domain = input[:domain, app]
95
+
96
+ mapped_url = false
97
+ until domain == "none" || !domain || mapped_url
98
+ begin
99
+ host = "" if host == "none"
100
+ invoke :map, :app => app, :host => host, :domain => domain
101
+ mapped_url = true
102
+ rescue CFoundry::RouteHostTaken, CFoundry::UriAlreadyTaken => e
103
+ raise if force?
104
+
105
+ line c(e.description, :bad)
106
+ line
107
+
108
+ input.forget(:host) if v2?
109
+ input.forget(:domain)
110
+
111
+ host = input[:host, app.name] if v2?
112
+ domain = input[:domain, app]
113
+
114
+ # version bumps on v1 even though mapping fails
115
+ app.invalidate! unless v2?
116
+ end
117
+ end
118
+ end
119
+
120
+ def create_services(app)
121
+ return unless input[:create_services]
122
+
123
+ while true
124
+ invoke :create_service, { :app => app }, :plan => :interact
125
+ break unless ask("Create another service?", :default => false)
126
+ end
127
+ end
128
+
129
+ def bind_services(app)
130
+ return unless input[:bind_services]
131
+
132
+ while true
133
+ invoke :bind_service, :app => app
134
+ break if (all_instances - app.services).empty?
135
+ break unless ask("Bind another service?", :default => false)
136
+ end
137
+ end
138
+
139
+ def start_app(app)
140
+ invoke :start, :app => app if input[:start]
141
+ end
142
+
143
+ private
144
+
145
+ def has_procfile?
146
+ File.exists?("#@path/Procfile")
147
+ end
148
+
149
+ def can_have_custom_start_command?(framework)
150
+ framework.name == "standalone"
151
+ end
152
+
153
+ def all_instances
154
+ @all_instances ||= client.service_instances
155
+ end
156
+
157
+ def detector
158
+ @detector ||= VMC::Detector.new(client, @path)
159
+ end
160
+
161
+ def target_base
162
+ client.target.sub(/^https?:\/\/([^\.]+\.)?(.+)\/?/, '\2')
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,94 @@
1
+ module VMC::App
2
+ module PushInteractions
3
+ def ask_name
4
+ ask("Name")
5
+ end
6
+
7
+ def ask_host(name)
8
+ ask "Subdomain", :choices => [name, "none"],
9
+ :default => name,
10
+ :allow_other => true
11
+ end
12
+
13
+ def ask_domain(app)
14
+ choices = v2? ? app.space.domains : ["#{app.name}.#{target_base}"]
15
+
16
+ options = {
17
+ :choices => choices + ["none"],
18
+ :display => proc { |d| d.is_a?(String) ? d : d.name },
19
+ :allow_other => true
20
+ }
21
+
22
+ options[:default] = choices.first if choices.size == 1
23
+
24
+ ask "Domain", options
25
+ end
26
+
27
+ def ask_memory(default)
28
+ ask("Memory Limit",
29
+ :choices => memory_choices,
30
+ :allow_other => true,
31
+ :default => default || "64M")
32
+ end
33
+
34
+ def ask_instances
35
+ ask("Instances", :default => 1)
36
+ end
37
+
38
+ def ask_framework(choices, default, other)
39
+ ask_with_other("Framework", client.frameworks, choices, default, other)
40
+ end
41
+
42
+ def ask_runtime(choices, default, other)
43
+ ask_with_other("Runtime", client.runtimes, choices, default, other)
44
+ end
45
+
46
+ def ask_command
47
+ command = ask("Custom startup command", :default => "none")
48
+
49
+ if command != "none"
50
+ command
51
+ end
52
+ end
53
+
54
+ def ask_create_services
55
+ line unless quiet?
56
+ ask "Create services for application?", :default => false
57
+ end
58
+
59
+ def ask_bind_services
60
+ return if all_instances.empty?
61
+
62
+ ask "Bind other services to application?", :default => false
63
+ end
64
+
65
+ private
66
+
67
+ def ask_with_other(message, all, choices, default, other)
68
+ choices = choices.sort_by(&:name)
69
+ choices << other if other
70
+
71
+ opts = {
72
+ :choices => choices,
73
+ :display => proc { |x|
74
+ if other && x == other
75
+ "other"
76
+ else
77
+ x.name
78
+ end
79
+ }
80
+ }
81
+
82
+ opts[:default] = default if default
83
+
84
+ res = ask(message, opts)
85
+
86
+ if other && res == other
87
+ opts[:choices] = all
88
+ res = ask(message, opts)
89
+ end
90
+
91
+ res
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,64 @@
1
+ module VMC::App
2
+ module Sync
3
+ def apply_changes(app)
4
+ app.memory = megabytes(input[:memory]) if input.has?(:memory)
5
+ app.total_instances = input[:instances] if input.has?(:instances)
6
+ app.command = input[:command] if input.has?(:command)
7
+ app.production = input[:plan].upcase.start_with?("P") if input.has?(:plan)
8
+ app.framework = input[:framework] if input.has?(:framework)
9
+ app.runtime = input[:runtime] if input.has?(:runtime)
10
+ app.buildpack = input[:buildpack] if input.has?(:buildpack)
11
+ end
12
+
13
+ def display_changes(app)
14
+ return unless app.changed?
15
+
16
+ line "Changes:"
17
+
18
+ indented do
19
+ app.changes.each do |attr, (old, new)|
20
+ line "#{c(attr, :name)}: #{diff_str(attr, old)} -> #{diff_str(attr, new)}"
21
+ end
22
+ end
23
+ end
24
+
25
+ def commit_changes(app)
26
+ if app.changed?
27
+ with_progress("Updating #{c(app.name, :name)}") do
28
+ wrap_message_format_errors do
29
+ app.update!
30
+ end
31
+ end
32
+ end
33
+
34
+ if input[:restart] && app.started?
35
+ invoke :restart, :app => app
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def diff_str(attr, val)
42
+ case attr
43
+ when :memory
44
+ human_mb(val)
45
+ when :framework, :runtime
46
+ val.name
47
+ when :command, :buildpack
48
+ "'#{val}'"
49
+ when :production
50
+ bool(val)
51
+ else
52
+ val
53
+ end
54
+ end
55
+
56
+ def bool(b)
57
+ if b
58
+ c("true", :yes)
59
+ else
60
+ c("false", :no)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,109 @@
1
+ require "vmc/cli/app/base"
2
+ require "vmc/cli/app/push/sync"
3
+ require "vmc/cli/app/push/create"
4
+ require "vmc/cli/app/push/interactions"
5
+
6
+ module VMC::App
7
+ class Push < Base
8
+ include Sync
9
+ include Create
10
+
11
+ desc "Push an application, syncing changes if it exists"
12
+ group :apps, :manage
13
+ input :name, :desc => "Application name", :argument => :optional
14
+ input :path, :desc => "Path containing the bits", :default => "."
15
+ input :host, :desc => "Subdomain for the app's URL"
16
+ input :domain, :desc => "Domain for the app",
17
+ :from_given => proc { |given, app|
18
+ if !v2? || given == "none"
19
+ given
20
+ else
21
+ app.space.domain_by_name(given) ||
22
+ fail_unknown("domain", given)
23
+ end
24
+ }
25
+ input :memory, :desc => "Memory limit"
26
+ input :instances, :desc => "Number of instances to run", :type => :integer
27
+ input :framework, :desc => "Framework to use",
28
+ :from_given => by_name(:framework)
29
+ input :runtime, :desc => "Runtime to use",
30
+ :from_given => by_name(:runtime)
31
+ input :command, :desc => "Startup command"
32
+ input :plan, :desc => "Application plan", :default => "D100"
33
+ input :start, :desc => "Start app after pushing?", :default => true
34
+ input :restart, :desc => "Restart app after updating?", :default => true
35
+ input :buildpack, :desc => "Custom buildpack URL", :default => nil
36
+ input :stack, :desc => "Stack to use", :default => nil,
37
+ :from_given => by_name(:stack)
38
+ input :create_services, :desc => "Interactively create services?",
39
+ :type => :boolean, :default => proc { force? ? false : interact }
40
+ input :bind_services, :desc => "Interactively bind services?",
41
+ :type => :boolean, :default => proc { force? ? false : interact }
42
+ interactions PushInteractions
43
+
44
+ def push
45
+ name = input[:name]
46
+ path = File.expand_path(input[:path])
47
+ app = client.app_by_name(name)
48
+
49
+ if app
50
+ sync_app(app, path)
51
+ else
52
+ setup_new_app(path)
53
+ end
54
+ end
55
+
56
+ def sync_app(app, path)
57
+ upload_app(app, path)
58
+ apply_changes(app)
59
+ display_changes(app)
60
+ commit_changes(app)
61
+ end
62
+
63
+ def setup_new_app(path)
64
+ self.path = path
65
+ app = create_app(get_inputs)
66
+ map_route(app)
67
+ create_services(app)
68
+ bind_services(app)
69
+ upload_app(app, path)
70
+ start_app(app)
71
+ end
72
+
73
+ private
74
+
75
+ def url_choices(name)
76
+ if v2?
77
+ client.current_space.domains.sort_by(&:name).collect do |d|
78
+ # TODO: check availability
79
+ "#{name}.#{d.name}"
80
+ end
81
+ else
82
+ %W(#{name}.#{target_base})
83
+ end
84
+ end
85
+
86
+ def upload_app(app, path)
87
+ app = filter(:push_app, app)
88
+
89
+ with_progress("Uploading #{c(app.name, :name)}") do
90
+ app.upload(path)
91
+ end
92
+ rescue
93
+ err "Upload failed. Try again with 'vmc push'."
94
+ raise
95
+ end
96
+
97
+ def wrap_message_format_errors
98
+ yield
99
+ rescue CFoundry::MessageParseError => e
100
+ md = e.description.match /Field: ([^,]+)/
101
+ field = md[1]
102
+
103
+ case field
104
+ when "buildpack"
105
+ fail "Buildpack must be a public git repository URI."
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,35 @@
1
+ require "vmc/cli/app/base"
2
+
3
+ module VMC::App
4
+ class Rename < Base
5
+ desc "Rename an application"
6
+ group :apps, :manage, :hidden => true
7
+ input :app, :desc => "Application to rename", :argument => :optional,
8
+ :from_given => by_name(:app)
9
+ input :name, :desc => "New application name", :argument => :optional
10
+ def rename
11
+ app = input[:app]
12
+ name = input[:name]
13
+
14
+ app.name = name
15
+
16
+ with_progress("Renaming to #{c(name, :name)}") do
17
+ app.update!
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def ask_app
24
+ apps = client.apps
25
+ fail "No applications." if apps.empty?
26
+
27
+ ask("Rename which application?", :choices => apps.sort_by(&:name),
28
+ :display => proc(&:name))
29
+ end
30
+
31
+ def ask_name
32
+ ask("New name")
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,20 @@
1
+ require "vmc/cli/app/base"
2
+
3
+ module VMC::App
4
+ class Restart < Base
5
+ desc "Stop and start an application"
6
+ group :apps, :manage
7
+ input :apps, :desc => "Applications to start", :argument => :splat,
8
+ :singular => :app, :from_given => by_name(:app)
9
+ input :debug_mode, :desc => "Debug mode to start in", :aliases => "-d"
10
+ input :all, :desc => "Restart all applications", :default => false
11
+ def restart
12
+ invoke :stop, :all => input[:all], :apps => input[:apps]
13
+
14
+ line unless quiet?
15
+
16
+ invoke :start, :all => input[:all], :apps => input[:apps],
17
+ :debug_mode => input[:debug_mode]
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,71 @@
1
+ require "vmc/cli/app/base"
2
+
3
+ module VMC::App
4
+ class Scale < Base
5
+ desc "Update the instances/memory limit for an application"
6
+ group :apps, :info
7
+ input :app, :desc => "Application to update", :argument => true,
8
+ :from_given => by_name(:app)
9
+ input :instances, :desc => "Number of instances to run",
10
+ :type => :numeric
11
+ input :memory, :desc => "Memory limit"
12
+ input :disk, :desc => "Disk quota"
13
+ input :plan, :desc => "Application plan", :default => "D100"
14
+ input :restart, :desc => "Restart app after updating?", :default => true
15
+ def scale
16
+ app = input[:app]
17
+
18
+ if input.has?(:instances)
19
+ instances = input[:instances, app.total_instances]
20
+ end
21
+
22
+ if input.has?(:memory)
23
+ memory = input[:memory, app.memory]
24
+ end
25
+
26
+ if input.has?(:disk)
27
+ disk = input[:disk, human_mb(app.disk_quota)]
28
+ end
29
+
30
+ if input.has?(:plan)
31
+ fail "Plans not supported on target cloud." unless v2?
32
+
33
+ plan_name = input[:plan]
34
+ production = !!(plan_name =~ /^p/i)
35
+ end
36
+
37
+ unless instances || memory || disk || plan_name
38
+ instances = input[:instances, app.total_instances]
39
+ memory = input[:memory, app.memory]
40
+ end
41
+
42
+ app.total_instances = instances if input.has?(:instances)
43
+ app.memory = megabytes(memory) if input.has?(:memory)
44
+ app.disk_quota = megabytes(disk) if input.has?(:disk)
45
+ app.production = production if input.has?(:plan)
46
+
47
+ fail "No changes!" unless app.changed?
48
+
49
+ with_progress("Scaling #{c(app.name, :name)}") do
50
+ app.update!
51
+ end
52
+
53
+ needs_restart = app.changes.key?(:memory) || app.changes.key?(:disk_quota)
54
+
55
+ if needs_restart && app.started? && input[:restart]
56
+ invoke :restart, :app => app
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def ask_instances(default)
63
+ ask("Instances", :default => default)
64
+ end
65
+
66
+ def ask_memory(default)
67
+ ask("Memory Limit", :choices => memory_choices(default),
68
+ :default => human_mb(default), :allow_other => true)
69
+ end
70
+ end
71
+ end