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

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 (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