vmc 0.4.0.beta.93 → 0.4.0.beta.94

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/vmc-ng/Rakefile +21 -30
  2. data/vmc-ng/lib/vmc.rb +4 -3
  3. data/vmc-ng/lib/vmc/cli.rb +10 -9
  4. data/vmc-ng/lib/vmc/cli/app/app.rb +45 -0
  5. data/vmc-ng/lib/vmc/cli/app/apps.rb +97 -0
  6. data/vmc-ng/lib/vmc/cli/app/base.rb +82 -0
  7. data/vmc-ng/lib/vmc/cli/app/crashes.rb +41 -0
  8. data/vmc-ng/lib/vmc/cli/app/delete.rb +90 -0
  9. data/vmc-ng/lib/vmc/cli/app/deprecated.rb +11 -0
  10. data/vmc-ng/lib/vmc/cli/app/env.rb +86 -0
  11. data/vmc-ng/lib/vmc/cli/app/files.rb +85 -0
  12. data/vmc-ng/lib/vmc/cli/app/health.rb +27 -0
  13. data/vmc-ng/lib/vmc/cli/app/instances.rb +49 -0
  14. data/vmc-ng/lib/vmc/cli/app/logs.rb +80 -0
  15. data/vmc-ng/lib/vmc/cli/app/push.rb +336 -0
  16. data/vmc-ng/lib/vmc/cli/app/rename.rb +31 -0
  17. data/vmc-ng/lib/vmc/cli/app/restart.rb +23 -0
  18. data/vmc-ng/lib/vmc/cli/app/routes.rb +97 -0
  19. data/vmc-ng/lib/vmc/cli/app/scale.rb +67 -0
  20. data/vmc-ng/lib/vmc/cli/app/start.rb +96 -0
  21. data/vmc-ng/lib/vmc/cli/app/stats.rb +68 -0
  22. data/vmc-ng/lib/vmc/cli/app/stop.rb +29 -0
  23. data/vmc-ng/lib/vmc/cli/domain/add_domain.rb +27 -0
  24. data/vmc-ng/lib/vmc/cli/domain/base.rb +12 -0
  25. data/vmc-ng/lib/vmc/cli/domain/create_domain.rb +31 -0
  26. data/vmc-ng/lib/vmc/cli/domain/delete_domain.rb +51 -0
  27. data/vmc-ng/lib/vmc/cli/domain/domains.rb +43 -0
  28. data/vmc-ng/lib/vmc/cli/domain/remove_domain.rb +26 -0
  29. data/vmc-ng/lib/vmc/cli/help.rb +0 -1
  30. data/vmc-ng/lib/vmc/cli/interactive.rb +4 -0
  31. data/vmc-ng/lib/vmc/cli/route/base.rb +12 -0
  32. data/vmc-ng/lib/vmc/cli/route/create_route.rb +42 -0
  33. data/vmc-ng/lib/vmc/cli/route/delete_route.rb +42 -0
  34. data/vmc-ng/lib/vmc/cli/route/routes.rb +26 -0
  35. data/vmc-ng/lib/vmc/detect.rb +2 -2
  36. data/vmc-ng/lib/vmc/spec_helper.rb +1 -0
  37. data/vmc-ng/lib/vmc/version.rb +1 -1
  38. data/vmc-ng/spec/cli/app/push_spec.rb +34 -0
  39. data/vmc-ng/spec/cli/app/rename_spec.rb +108 -0
  40. data/vmc-ng/spec/cli/route/delete_route_spec.rb +160 -0
  41. data/vmc-ng/spec/detect_spec.rb +54 -0
  42. data/vmc-ng/spec/factories/app_factory.rb +9 -0
  43. data/vmc-ng/spec/factories/client_factory.rb +16 -0
  44. data/vmc-ng/spec/factories/domain_factory.rb +9 -0
  45. data/vmc-ng/spec/factories/factory.rb +3 -0
  46. data/vmc-ng/spec/factories/framework_factory.rb +9 -0
  47. data/vmc-ng/spec/factories/route_factory.rb +10 -0
  48. data/vmc-ng/spec/spec_helper.rb +17 -0
  49. data/vmc-ng/spec/support/interact_helpers.rb +23 -0
  50. metadata +135 -62
  51. data/vmc-ng/lib/vmc/cli/app.rb +0 -1333
  52. data/vmc-ng/lib/vmc/cli/domain.rb +0 -164
  53. data/vmc-ng/lib/vmc/cli/route.rb +0 -106
  54. data/vmc-ng/lib/vmc/spec_helpers.rb +0 -431
  55. data/vmc-ng/lib/vmc/spec_helpers/eventlog.rb +0 -277
  56. data/vmc-ng/lib/vmc/spec_helpers/patches.rb +0 -94
  57. data/vmc-ng/spec/Rakefile +0 -13
  58. data/vmc-ng/spec/app/app_spec.rb +0 -19
  59. data/vmc-ng/spec/app/apps_spec.rb +0 -79
  60. data/vmc-ng/spec/app/push_spec.rb +0 -74
  61. data/vmc-ng/spec/assets/hello-sinatra/Gemfile +0 -2
  62. data/vmc-ng/spec/assets/hello-sinatra/main.rb +0 -5
  63. data/vmc-ng/spec/assets/hello-sinatra/manifest.yml +0 -9
  64. data/vmc-ng/spec/helpers.rb +0 -7
  65. data/vmc-ng/spec/start/target_spec.rb +0 -60
@@ -0,0 +1,31 @@
1
+ require "vmc/detect"
2
+
3
+ require "vmc/cli/app/base"
4
+
5
+ module VMC::App
6
+ class Rename < Base
7
+ desc "Rename an application"
8
+ group :apps, :manage
9
+ input(:app, :argument => :optional, :desc => "Application to rename",
10
+ :from_given => by_name("app")) {
11
+ apps = client.apps
12
+ fail "No applications." if apps.empty?
13
+
14
+ ask("Rename which application?", :choices => apps.sort_by(&:name),
15
+ :display => proc(&:name))
16
+ }
17
+ input(:name, :argument => :optional, :desc => "New application name") {
18
+ ask("New name")
19
+ }
20
+ def rename
21
+ app = input[:app]
22
+ name = input[:name]
23
+
24
+ app.name = name
25
+
26
+ with_progress("Renaming to #{c(name, :name)}") do
27
+ app.update!
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
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, :argument => :splat, :singular => :app,
8
+ :desc => "Applications to start",
9
+ :from_given => by_name("app")
10
+ input :debug_mode, :aliases => "-d",
11
+ :desc => "Debug mode to start in"
12
+ input :all, :type => :boolean, :default => false,
13
+ :desc => "Restart all applications"
14
+ def restart
15
+ invoke :stop, :all => input[:all], :apps => input[:apps]
16
+
17
+ line unless quiet?
18
+
19
+ invoke :start, :all => input[:all], :apps => input[:apps],
20
+ :debug_mode => input[:debug_mode]
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,97 @@
1
+ require "vmc/cli/app/base"
2
+
3
+ module VMC::App
4
+ class Routes < Base
5
+ desc "Add a URL mapping for an app"
6
+ group :apps, :info, :hidden => true
7
+ input :app, :argument => true,
8
+ :desc => "Application to add the URL to",
9
+ :from_given => by_name("app")
10
+ input :url, :argument => true,
11
+ :desc => "URL to map to the application"
12
+ def map
13
+ app = input[:app]
14
+
15
+ simple = input[:url].sub(/^https?:\/\/(.*)\/?/i, '\1')
16
+
17
+ if v2?
18
+ host, domain_name = simple.split(".", 2)
19
+
20
+ domain =
21
+ client.current_space.domain_by_name(domain_name, :depth => 0)
22
+
23
+ fail "Invalid domain '#{domain_name}'" unless domain
24
+
25
+ route = client.routes_by_host(host, :depth => 0).find do |r|
26
+ r.domain == domain
27
+ end
28
+
29
+ unless route
30
+ route = client.route
31
+
32
+ with_progress("Creating route #{c(simple, :name)}") do
33
+ route.host = host
34
+ route.domain = domain
35
+ route.space = app.space
36
+ route.create!
37
+ end
38
+ end
39
+
40
+ with_progress("Binding #{c(simple, :name)} to #{c(app.name, :name)}") do
41
+ app.add_route(route)
42
+ end
43
+ else
44
+ with_progress("Updating #{c(app.name, :name)}") do
45
+ app.urls << simple
46
+ app.update!
47
+ end
48
+ end
49
+ end
50
+
51
+
52
+ desc "Remove a URL mapping from an app"
53
+ group :apps, :info, :hidden => true
54
+ input :app, :argument => true,
55
+ :desc => "Application to remove the URL from",
56
+ :from_given => by_name("app")
57
+ input(:url, :argument => true, :desc => "URL to unmap") { |choices|
58
+ ask("Which URL?", :choices => choices)
59
+ }
60
+ def unmap
61
+ app = input[:app]
62
+ url = input[:url, app.urls]
63
+
64
+ simple = url.sub(/^https?:\/\/(.*)\/?/i, '\1')
65
+
66
+ if v2?
67
+ host, domain_name = simple.split(".", 2)
68
+
69
+ domain =
70
+ client.current_space.domain_by_name(domain_name, :depth => 0)
71
+
72
+ fail "Invalid domain '#{domain_name}'" unless domain
73
+
74
+ route = app.routes_by_host(host, :depth => 0).find do |r|
75
+ r.domain == domain
76
+ end
77
+
78
+ fail "Invalid route '#{simple}'" unless route
79
+
80
+ with_progress("Removing route #{c(simple, :name)}") do
81
+ app.remove_route(route)
82
+ end
83
+ else
84
+ with_progress("Updating #{c(app.name, :name)}") do |s|
85
+ unless app.urls.delete(simple)
86
+ s.fail do
87
+ err "URL #{url} is not mapped to this application."
88
+ return
89
+ end
90
+ end
91
+
92
+ app.update!
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,67 @@
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, :hidden => true
7
+ input :app, :argument => true, :desc => "Application to update",
8
+ :from_given => by_name("app")
9
+ input(:instances, :type => :numeric,
10
+ :desc => "Number of instances to run") { |default|
11
+ ask("Instances", :default => default)
12
+ }
13
+ input(:memory, :desc => "Memory limit") { |default|
14
+ ask("Memory Limit", :choices => memory_choices(default),
15
+ :allow_other => true,
16
+ :default => human_mb(default))
17
+ }
18
+ input :plan, :default => "D100",
19
+ :desc => "Application plan (e.g. D100, P200)"
20
+ input :restart, :type => :boolean, :default => true,
21
+ :desc => "Restart app after updating?"
22
+ def scale
23
+ app = input[:app]
24
+
25
+ if input.given?(:instances)
26
+ instances = input[:instances, app.total_instances]
27
+ end
28
+
29
+ if input.given?(:memory)
30
+ memory = input[:memory, app.memory]
31
+ end
32
+
33
+ if input.given?(:plan)
34
+ fail "Plans not supported on target cloud." unless v2?
35
+
36
+ plan_name = input[:plan]
37
+ production = !!(plan_name =~ /^p/i)
38
+ end
39
+
40
+ unless instances || memory || plan_name
41
+ instances = input[:instances, app.total_instances]
42
+ memory = input[:memory, app.memory]
43
+ end
44
+
45
+ memory = megabytes(memory) if memory
46
+
47
+ instances_changed = instances && instances != app.total_instances
48
+ memory_changed = memory && memory != app.memory
49
+ plan_changed = plan_name && production != app.production
50
+
51
+ unless memory_changed || instances_changed || plan_changed
52
+ fail "No changes!"
53
+ end
54
+
55
+ with_progress("Scaling #{c(app.name, :name)}") do
56
+ app.total_instances = instances if instances_changed
57
+ app.memory = memory if memory_changed
58
+ app.production = production if plan_changed
59
+ app.update!
60
+ end
61
+
62
+ if memory_changed && app.started? && input[:restart]
63
+ invoke :restart, :app => app
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,96 @@
1
+ require "vmc/cli/app/base"
2
+
3
+ module VMC::App
4
+ class Start < Base
5
+ APP_CHECK_LIMIT = 60
6
+
7
+ desc "Start an application"
8
+ group :apps, :manage
9
+ input :apps, :argument => :splat, :singular => :app,
10
+ :desc => "Applications to start",
11
+ :from_given => by_name("app")
12
+ input :debug_mode, :aliases => "-d",
13
+ :desc => "Debug mode to start in"
14
+ input :all, :type => :boolean, :default => false,
15
+ :desc => "Start all applications"
16
+ def start
17
+ apps = input[:all] ? client.apps : input[:apps]
18
+ fail "No applications given." if apps.empty?
19
+
20
+ spaced(apps) do |app|
21
+ app = filter(:start_app, app)
22
+
23
+ switch_mode(app, input[:debug_mode])
24
+
25
+ with_progress("Starting #{c(app.name, :name)}") do |s|
26
+ if app.started?
27
+ s.skip do
28
+ err "Already started."
29
+ end
30
+ end
31
+
32
+ app.start!
33
+ end
34
+
35
+ check_application(app)
36
+
37
+ if app.debug_mode && !quiet?
38
+ line
39
+ invoke :instances, :app => app
40
+ end
41
+ end
42
+ end
43
+
44
+ # set app debug mode, ensuring it's valid, and shutting it down
45
+ def switch_mode(app, mode)
46
+ mode = nil if mode == "none"
47
+ mode = "run" if mode == "debug_mode" # no value given
48
+
49
+ return false if app.debug_mode == mode
50
+
51
+ if mode.nil?
52
+ with_progress("Removing debug mode") do
53
+ app.debug_mode = nil
54
+ app.stop! if app.started?
55
+ end
56
+
57
+ return true
58
+ end
59
+
60
+ with_progress("Switching mode to #{c(mode, :name)}") do |s|
61
+ runtime = client.runtimes.find { |r| r.name == app.runtime.name }
62
+ modes = runtime.debug_modes
63
+
64
+ if modes.include?(mode)
65
+ app.debug_mode = mode
66
+ app.stop! if app.started?
67
+ else
68
+ fail "Unknown mode '#{mode}'; available: #{modes.join ", "}"
69
+ end
70
+ end
71
+ end
72
+
73
+ def check_application(app)
74
+ with_progress("Checking #{c(app.name, :name)}") do |s|
75
+ if app.debug_mode == "suspend"
76
+ s.skip do
77
+ line "Application is in suspended debugging mode."
78
+ line "It will wait for you to attach to it before starting."
79
+ end
80
+ end
81
+
82
+ seconds = 0
83
+ until app.healthy?
84
+ sleep 1
85
+ seconds += 1
86
+ if seconds == APP_CHECK_LIMIT
87
+ s.give_up do
88
+ err "Application failed to start."
89
+ # TODO: print logs
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,68 @@
1
+ require "vmc/cli/app/base"
2
+
3
+ module VMC::App
4
+ class Stats < Base
5
+ desc "Display application instance status"
6
+ group :apps, :info, :hidden => true
7
+ input :app, :argument => true,
8
+ :desc => "Application to get the stats for",
9
+ :from_given => by_name("app")
10
+ def stats
11
+ app = input[:app]
12
+
13
+ stats =
14
+ with_progress("Getting stats for #{c(app.name, :name)}") do |s|
15
+ begin
16
+ app.stats
17
+ rescue CFoundry::StatsError
18
+ s.fail do
19
+ err "Application #{b(app.name)} is not running."
20
+ return
21
+ end
22
+ end
23
+ end
24
+
25
+ line unless quiet?
26
+
27
+ table(
28
+ %w{instance cpu memory disk},
29
+ stats.sort_by { |idx, _| idx.to_i }.collect { |idx, info|
30
+ idx = c("\##{idx}", :instance)
31
+
32
+ if info[:state] == "DOWN"
33
+ [idx, c("down", :bad)]
34
+ else
35
+ stats = info[:stats]
36
+ usage = stats[:usage]
37
+
38
+ if usage
39
+ [ idx,
40
+ "#{percentage(usage[:cpu])} of #{b(stats[:cores])} cores",
41
+ "#{usage(usage[:mem] * 1024, stats[:mem_quota])}",
42
+ "#{usage(usage[:disk], stats[:disk_quota])}"
43
+ ]
44
+ else
45
+ [idx, c("n/a", :neutral)]
46
+ end
47
+ end
48
+ })
49
+ end
50
+
51
+ def percentage(num, low = 50, mid = 70)
52
+ color =
53
+ if num <= low
54
+ :good
55
+ elsif num <= mid
56
+ :warning
57
+ else
58
+ :bad
59
+ end
60
+
61
+ c(format("%.1f\%", num), color)
62
+ end
63
+
64
+ def usage(used, limit)
65
+ "#{b(human_size(used))} of #{b(human_size(limit, 0))}"
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,29 @@
1
+ require "vmc/cli/app/base"
2
+
3
+ module VMC::App
4
+ class Stop < Base
5
+ desc "Stop an application"
6
+ group :apps, :manage
7
+ input :apps, :argument => :splat, :singular => :app,
8
+ :desc => "Applications to start",
9
+ :from_given => by_name("app")
10
+ input :all, :type => :boolean, :default => false,
11
+ :desc => "Stop all applications"
12
+ def stop
13
+ apps = input[:all] ? client.apps : input[:apps]
14
+ fail "No applications given." if apps.empty?
15
+
16
+ apps.each do |app|
17
+ with_progress("Stopping #{c(app.name, :name)}") do |s|
18
+ if app.stopped?
19
+ s.skip do
20
+ err "Application is not running."
21
+ end
22
+ end
23
+
24
+ app.stop!
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ require "vmc/cli/domain/base"
2
+
3
+ module VMC::Domain
4
+ class AddDomain < Base
5
+ desc "Add a domain to a space"
6
+ group :domains
7
+ input :name, :argument => :required,
8
+ :desc => "Domain to add"
9
+ input :space, :from_given => by_name("space"),
10
+ :default => proc { client.current_space },
11
+ :desc => "Space to add the domain to"
12
+
13
+ def add_domain
14
+ space = input[:space]
15
+ name = input[:name].sub(/^\*\./, "")
16
+
17
+ org = space.organization
18
+
19
+ domain = org.domains.find { |d| d.name == name } ||
20
+ invoke(:create_domain, :org => org, :name => name)
21
+
22
+ with_progress("Adding #{c(domain.name, :name)} to #{c(space.name, :name)}") do
23
+ space.add_domain(domain)
24
+ end
25
+ end
26
+ end
27
+ end