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