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.
- data/vmc-ng/Rakefile +21 -30
- data/vmc-ng/lib/vmc.rb +4 -3
- data/vmc-ng/lib/vmc/cli.rb +10 -9
- data/vmc-ng/lib/vmc/cli/app/app.rb +45 -0
- data/vmc-ng/lib/vmc/cli/app/apps.rb +97 -0
- data/vmc-ng/lib/vmc/cli/app/base.rb +82 -0
- data/vmc-ng/lib/vmc/cli/app/crashes.rb +41 -0
- data/vmc-ng/lib/vmc/cli/app/delete.rb +90 -0
- data/vmc-ng/lib/vmc/cli/app/deprecated.rb +11 -0
- data/vmc-ng/lib/vmc/cli/app/env.rb +86 -0
- data/vmc-ng/lib/vmc/cli/app/files.rb +85 -0
- data/vmc-ng/lib/vmc/cli/app/health.rb +27 -0
- data/vmc-ng/lib/vmc/cli/app/instances.rb +49 -0
- data/vmc-ng/lib/vmc/cli/app/logs.rb +80 -0
- data/vmc-ng/lib/vmc/cli/app/push.rb +336 -0
- data/vmc-ng/lib/vmc/cli/app/rename.rb +31 -0
- data/vmc-ng/lib/vmc/cli/app/restart.rb +23 -0
- data/vmc-ng/lib/vmc/cli/app/routes.rb +97 -0
- data/vmc-ng/lib/vmc/cli/app/scale.rb +67 -0
- data/vmc-ng/lib/vmc/cli/app/start.rb +96 -0
- data/vmc-ng/lib/vmc/cli/app/stats.rb +68 -0
- data/vmc-ng/lib/vmc/cli/app/stop.rb +29 -0
- data/vmc-ng/lib/vmc/cli/domain/add_domain.rb +27 -0
- data/vmc-ng/lib/vmc/cli/domain/base.rb +12 -0
- data/vmc-ng/lib/vmc/cli/domain/create_domain.rb +31 -0
- data/vmc-ng/lib/vmc/cli/domain/delete_domain.rb +51 -0
- data/vmc-ng/lib/vmc/cli/domain/domains.rb +43 -0
- data/vmc-ng/lib/vmc/cli/domain/remove_domain.rb +26 -0
- data/vmc-ng/lib/vmc/cli/help.rb +0 -1
- data/vmc-ng/lib/vmc/cli/interactive.rb +4 -0
- data/vmc-ng/lib/vmc/cli/route/base.rb +12 -0
- data/vmc-ng/lib/vmc/cli/route/create_route.rb +42 -0
- data/vmc-ng/lib/vmc/cli/route/delete_route.rb +42 -0
- data/vmc-ng/lib/vmc/cli/route/routes.rb +26 -0
- data/vmc-ng/lib/vmc/detect.rb +2 -2
- data/vmc-ng/lib/vmc/spec_helper.rb +1 -0
- data/vmc-ng/lib/vmc/version.rb +1 -1
- data/vmc-ng/spec/cli/app/push_spec.rb +34 -0
- data/vmc-ng/spec/cli/app/rename_spec.rb +108 -0
- data/vmc-ng/spec/cli/route/delete_route_spec.rb +160 -0
- data/vmc-ng/spec/detect_spec.rb +54 -0
- data/vmc-ng/spec/factories/app_factory.rb +9 -0
- data/vmc-ng/spec/factories/client_factory.rb +16 -0
- data/vmc-ng/spec/factories/domain_factory.rb +9 -0
- data/vmc-ng/spec/factories/factory.rb +3 -0
- data/vmc-ng/spec/factories/framework_factory.rb +9 -0
- data/vmc-ng/spec/factories/route_factory.rb +10 -0
- data/vmc-ng/spec/spec_helper.rb +17 -0
- data/vmc-ng/spec/support/interact_helpers.rb +23 -0
- metadata +135 -62
- data/vmc-ng/lib/vmc/cli/app.rb +0 -1333
- data/vmc-ng/lib/vmc/cli/domain.rb +0 -164
- data/vmc-ng/lib/vmc/cli/route.rb +0 -106
- data/vmc-ng/lib/vmc/spec_helpers.rb +0 -431
- data/vmc-ng/lib/vmc/spec_helpers/eventlog.rb +0 -277
- data/vmc-ng/lib/vmc/spec_helpers/patches.rb +0 -94
- data/vmc-ng/spec/Rakefile +0 -13
- data/vmc-ng/spec/app/app_spec.rb +0 -19
- data/vmc-ng/spec/app/apps_spec.rb +0 -79
- data/vmc-ng/spec/app/push_spec.rb +0 -74
- data/vmc-ng/spec/assets/hello-sinatra/Gemfile +0 -2
- data/vmc-ng/spec/assets/hello-sinatra/main.rb +0 -5
- data/vmc-ng/spec/assets/hello-sinatra/manifest.yml +0 -9
- data/vmc-ng/spec/helpers.rb +0 -7
- 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
|