cf 0.1.5 → 0.6.0.rc1
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/LICENSE +1277 -30
- data/Rakefile +12 -1
- data/bin/cf +0 -3
- data/lib/cf.rb +6 -0
- data/lib/cf/cli.rb +389 -190
- data/lib/cf/cli/app/app.rb +45 -0
- data/lib/cf/cli/app/apps.rb +99 -0
- data/lib/cf/cli/app/base.rb +90 -0
- data/lib/cf/cli/app/crashes.rb +42 -0
- data/lib/cf/cli/app/delete.rb +95 -0
- data/lib/cf/cli/app/deprecated.rb +11 -0
- data/lib/cf/cli/app/env.rb +78 -0
- data/lib/cf/cli/app/files.rb +137 -0
- data/lib/cf/cli/app/health.rb +26 -0
- data/lib/cf/cli/app/instances.rb +53 -0
- data/lib/cf/cli/app/logs.rb +76 -0
- data/lib/cf/cli/app/push.rb +105 -0
- data/lib/cf/cli/app/push/create.rb +149 -0
- data/lib/cf/cli/app/push/interactions.rb +94 -0
- data/lib/cf/cli/app/push/sync.rb +64 -0
- data/lib/cf/cli/app/rename.rb +35 -0
- data/lib/cf/cli/app/restart.rb +20 -0
- data/lib/cf/cli/app/scale.rb +69 -0
- data/lib/cf/cli/app/start.rb +143 -0
- data/lib/cf/cli/app/stats.rb +67 -0
- data/lib/cf/cli/app/stop.rb +27 -0
- data/lib/cf/cli/domain/base.rb +8 -0
- data/lib/cf/cli/domain/domains.rb +40 -0
- data/lib/cf/cli/domain/map.rb +55 -0
- data/lib/cf/cli/domain/unmap.rb +56 -0
- data/lib/cf/cli/help.rb +15 -0
- data/lib/cf/cli/interactive.rb +105 -0
- data/lib/cf/cli/organization/base.rb +12 -0
- data/lib/cf/cli/organization/create.rb +32 -0
- data/lib/cf/cli/organization/delete.rb +73 -0
- data/lib/cf/cli/organization/org.rb +45 -0
- data/lib/cf/cli/organization/orgs.rb +35 -0
- data/lib/cf/cli/organization/rename.rb +36 -0
- data/lib/cf/cli/route/base.rb +8 -0
- data/lib/cf/cli/route/map.rb +70 -0
- data/lib/cf/cli/route/routes.rb +26 -0
- data/lib/cf/cli/route/unmap.rb +62 -0
- data/lib/cf/cli/service/base.rb +8 -0
- data/lib/cf/cli/service/bind.rb +44 -0
- data/lib/cf/cli/service/create.rb +107 -0
- data/lib/cf/cli/service/delete.rb +82 -0
- data/lib/cf/cli/service/rename.rb +35 -0
- data/lib/cf/cli/service/service.rb +40 -0
- data/lib/cf/cli/service/services.rb +99 -0
- data/lib/cf/cli/service/unbind.rb +38 -0
- data/lib/cf/cli/space/base.rb +19 -0
- data/lib/cf/cli/space/create.rb +63 -0
- data/lib/cf/cli/space/delete.rb +95 -0
- data/lib/cf/cli/space/rename.rb +39 -0
- data/lib/cf/cli/space/space.rb +64 -0
- data/lib/cf/cli/space/spaces.rb +55 -0
- data/lib/cf/cli/space/switch.rb +16 -0
- data/lib/cf/cli/start/base.rb +93 -0
- data/lib/cf/cli/start/colors.rb +13 -0
- data/lib/cf/cli/start/info.rb +124 -0
- data/lib/cf/cli/start/login.rb +94 -0
- data/lib/cf/cli/start/logout.rb +17 -0
- data/lib/cf/cli/start/target.rb +69 -0
- data/lib/cf/cli/start/target_interactions.rb +37 -0
- data/lib/cf/cli/start/targets.rb +16 -0
- data/lib/cf/cli/user/base.rb +29 -0
- data/lib/cf/cli/user/create.rb +39 -0
- data/lib/cf/cli/user/passwd.rb +43 -0
- data/lib/cf/cli/user/register.rb +42 -0
- data/lib/cf/cli/user/users.rb +32 -0
- data/lib/cf/constants.rb +10 -7
- data/lib/cf/detect.rb +113 -48
- data/lib/cf/errors.rb +17 -0
- data/lib/cf/plugin.rb +28 -12
- data/lib/cf/spacing.rb +89 -0
- data/lib/cf/spec_helper.rb +1 -0
- data/lib/cf/test_support.rb +6 -0
- data/lib/cf/version.rb +1 -1
- data/spec/assets/hello-sinatra/Gemfile +3 -0
- data/spec/assets/hello-sinatra/Gemfile.lock +17 -0
- data/spec/assets/hello-sinatra/config.ru +3 -0
- data/spec/assets/hello-sinatra/fat-cat-makes-app-larger.png +0 -0
- data/spec/assets/hello-sinatra/main.rb +6 -0
- data/spec/assets/specker_runner/specker_runner_input.rb +6 -0
- data/spec/assets/specker_runner/specker_runner_pause.rb +5 -0
- data/spec/cf/cli/app/base_spec.rb +17 -0
- data/spec/cf/cli/app/delete_spec.rb +188 -0
- data/spec/cf/cli/app/instances_spec.rb +65 -0
- data/spec/cf/cli/app/push/create_spec.rb +661 -0
- data/spec/cf/cli/app/push_spec.rb +369 -0
- data/spec/cf/cli/app/rename_spec.rb +104 -0
- data/spec/cf/cli/app/scale_spec.rb +75 -0
- data/spec/cf/cli/app/start_spec.rb +208 -0
- data/spec/cf/cli/app/stats_spec.rb +68 -0
- data/spec/cf/cli/domain/map_spec.rb +130 -0
- data/spec/cf/cli/domain/unmap_spec.rb +69 -0
- data/spec/cf/cli/organization/orgs_spec.rb +108 -0
- data/spec/cf/cli/organization/rename_spec.rb +113 -0
- data/spec/cf/cli/route/map_spec.rb +121 -0
- data/spec/cf/cli/route/unmap_spec.rb +155 -0
- data/spec/cf/cli/service/bind_spec.rb +25 -0
- data/spec/cf/cli/service/delete_spec.rb +22 -0
- data/spec/cf/cli/service/rename_spec.rb +105 -0
- data/spec/cf/cli/service/service_spec.rb +23 -0
- data/spec/cf/cli/service/unbind_spec.rb +25 -0
- data/spec/cf/cli/space/create_spec.rb +93 -0
- data/spec/cf/cli/space/rename_spec.rb +102 -0
- data/spec/cf/cli/space/spaces_spec.rb +104 -0
- data/spec/cf/cli/space/switch_space_spec.rb +55 -0
- data/spec/cf/cli/start/info_spec.rb +160 -0
- data/spec/cf/cli/start/login_spec.rb +142 -0
- data/spec/cf/cli/start/logout_spec.rb +50 -0
- data/spec/cf/cli/start/target_spec.rb +123 -0
- data/spec/cf/cli/user/create_spec.rb +54 -0
- data/spec/cf/cli/user/passwd_spec.rb +102 -0
- data/spec/cf/cli/user/register_spec.rb +140 -0
- data/spec/cf/cli_spec.rb +442 -0
- data/spec/cf/detect_spec.rb +54 -0
- data/spec/console_app_specker/console_app_specker_matchers_spec.rb +173 -0
- data/spec/console_app_specker/specker_runner_spec.rb +167 -0
- data/spec/features/account_lifecycle_spec.rb +85 -0
- data/spec/features/login_spec.rb +66 -0
- data/spec/features/push_flow_spec.rb +125 -0
- data/spec/features/switching_targets_spec.rb +32 -0
- data/spec/spec_helper.rb +72 -0
- data/spec/support/command_helper.rb +81 -0
- data/spec/support/config_helper.rb +15 -0
- data/spec/support/console_app_specker_matchers.rb +86 -0
- data/spec/support/fake_home_dir.rb +55 -0
- data/spec/support/interact_helper.rb +29 -0
- data/spec/support/shared_examples/errors.rb +40 -0
- data/spec/support/shared_examples/input.rb +14 -0
- data/spec/support/specker_runner.rb +80 -0
- data/spec/support/tracking_expector.rb +71 -0
- metadata +427 -66
- data/lib/cf/cli/app.rb +0 -595
- data/lib/cf/cli/command.rb +0 -444
- data/lib/cf/cli/dots.rb +0 -133
- data/lib/cf/cli/service.rb +0 -112
- data/lib/cf/cli/user.rb +0 -71
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
module CF::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 = app.space.domains
|
|
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 CF::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,35 @@
|
|
|
1
|
+
require "cf/cli/app/base"
|
|
2
|
+
|
|
3
|
+
module CF::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 "cf/cli/app/base"
|
|
2
|
+
|
|
3
|
+
module CF::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,69 @@
|
|
|
1
|
+
require "cf/cli/app/base"
|
|
2
|
+
|
|
3
|
+
module CF::App
|
|
4
|
+
class Scale < Base
|
|
5
|
+
desc "Update the instances/memory limit for an application"
|
|
6
|
+
group :apps, :info, :hidden => true
|
|
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
|
+
plan_name = input[:plan]
|
|
32
|
+
production = !!(plan_name =~ /^p/i)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
unless instances || memory || disk || plan_name
|
|
36
|
+
instances = input[:instances, app.total_instances]
|
|
37
|
+
memory = input[:memory, app.memory]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
app.total_instances = instances if input.has?(:instances)
|
|
41
|
+
app.memory = megabytes(memory) if input.has?(:memory)
|
|
42
|
+
app.disk_quota = megabytes(disk) if input.has?(:disk)
|
|
43
|
+
app.production = production if input.has?(:plan)
|
|
44
|
+
|
|
45
|
+
fail "No changes!" unless app.changed?
|
|
46
|
+
|
|
47
|
+
with_progress("Scaling #{c(app.name, :name)}") do
|
|
48
|
+
app.update!
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
needs_restart = app.changes.key?(:memory) || app.changes.key?(:disk_quota)
|
|
52
|
+
|
|
53
|
+
if needs_restart && app.started? && input[:restart]
|
|
54
|
+
invoke :restart, :app => app
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def ask_instances(default)
|
|
61
|
+
ask("Instances", :default => default)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def ask_memory(default)
|
|
65
|
+
ask("Memory Limit", :choices => memory_choices(default),
|
|
66
|
+
:default => human_mb(default), :allow_other => true)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
require "cf/cli/app/base"
|
|
2
|
+
|
|
3
|
+
module CF::App
|
|
4
|
+
class Start < Base
|
|
5
|
+
APP_CHECK_LIMIT = 60
|
|
6
|
+
|
|
7
|
+
desc "Start an application"
|
|
8
|
+
group :apps, :manage
|
|
9
|
+
input :apps, :desc => "Applications to start", :argument => :splat,
|
|
10
|
+
:singular => :app, :from_given => by_name(:app)
|
|
11
|
+
input :debug_mode, :desc => "Debug mode to start in", :aliases => "-d"
|
|
12
|
+
input :all, :desc => "Start all applications", :default => false
|
|
13
|
+
def start
|
|
14
|
+
apps = input[:all] ? client.apps : input[:apps]
|
|
15
|
+
fail "No applications given." if apps.empty?
|
|
16
|
+
|
|
17
|
+
spaced(apps) do |app|
|
|
18
|
+
app = filter(:start_app, app)
|
|
19
|
+
|
|
20
|
+
switch_mode(app, input[:debug_mode])
|
|
21
|
+
|
|
22
|
+
if app.started?
|
|
23
|
+
err "Application #{b(app.name)} is already started."
|
|
24
|
+
next
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
log = start_app(app)
|
|
28
|
+
stream_start_log(log) if log
|
|
29
|
+
check_application(app)
|
|
30
|
+
|
|
31
|
+
if app.debug_mode && !quiet?
|
|
32
|
+
line
|
|
33
|
+
invoke :instances, :app => app
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def start_app(app)
|
|
41
|
+
log = nil
|
|
42
|
+
with_progress("Starting #{c(app.name, :name)}") do
|
|
43
|
+
app.start!(true) do |url|
|
|
44
|
+
log = url
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
log
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def stream_start_log(log)
|
|
51
|
+
offset = 0
|
|
52
|
+
|
|
53
|
+
while true
|
|
54
|
+
begin
|
|
55
|
+
client.stream_url(log + "&tail&tail_offset=#{offset}") do |out|
|
|
56
|
+
offset += out.size
|
|
57
|
+
print out
|
|
58
|
+
end
|
|
59
|
+
rescue Timeout::Error
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
rescue CFoundry::APIError
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# set app debug mode, ensuring it's valid, and shutting it down
|
|
66
|
+
def switch_mode(app, mode)
|
|
67
|
+
mode = nil if mode == "none"
|
|
68
|
+
mode = "run" if mode == "" # no value given
|
|
69
|
+
|
|
70
|
+
return false if app.debug == mode
|
|
71
|
+
|
|
72
|
+
if mode.nil?
|
|
73
|
+
with_progress("Removing debug mode") do
|
|
74
|
+
app.debug = nil
|
|
75
|
+
app.stop! if app.started?
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
return true
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
with_progress("Switching mode to #{c(mode, :name)}") do |s|
|
|
82
|
+
app.debug = mode
|
|
83
|
+
app.stop! if app.started?
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def check_application(app)
|
|
88
|
+
if app.debug == "suspend"
|
|
89
|
+
line "Application is in suspended debugging mode."
|
|
90
|
+
line "It will wait for you to attach to it before starting."
|
|
91
|
+
return
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
line "Checking #{c(app.name, :name)}..."
|
|
95
|
+
|
|
96
|
+
seconds = 0
|
|
97
|
+
while instances = app.instances
|
|
98
|
+
indented { print_instances_summary(instances) }
|
|
99
|
+
|
|
100
|
+
if all_instances_running?(instances)
|
|
101
|
+
line "#{c("OK", :good)}"
|
|
102
|
+
return
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
if any_instance_flapping?(instances) || seconds == APP_CHECK_LIMIT
|
|
106
|
+
err "Application failed to start."
|
|
107
|
+
return
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
sleep 1
|
|
111
|
+
seconds += 1
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def all_instances_running?(instances)
|
|
116
|
+
instances.all? { |i| i.state == "RUNNING" }
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def any_instance_flapping?(instances)
|
|
120
|
+
instances.any? { |i| i.state == "FLAPPING" }
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def print_instances_summary(instances)
|
|
124
|
+
counts = Hash.new { 0 }
|
|
125
|
+
instances.each do |i|
|
|
126
|
+
counts[i.state] += 1
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
states = []
|
|
130
|
+
%w{RUNNING STARTING DOWN FLAPPING}.each do |state|
|
|
131
|
+
if (num = counts[state]) > 0
|
|
132
|
+
states << "#{b(num)} #{c(state.downcase, state_color(state))}"
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
total = instances.count
|
|
137
|
+
running = counts["RUNNING"].to_s.rjust(total.to_s.size)
|
|
138
|
+
|
|
139
|
+
ratio = "#{running}#{d("/")}#{total} instances:"
|
|
140
|
+
line "#{ratio} #{states.join(", ")}"
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require "cf/cli/app/base"
|
|
2
|
+
|
|
3
|
+
module CF::App
|
|
4
|
+
class Stats < Base
|
|
5
|
+
desc "Display application instance status"
|
|
6
|
+
group :apps, :info, :hidden => true
|
|
7
|
+
input :app, :desc => "Application to get the stats for",
|
|
8
|
+
:argument => true, :from_given => by_name(:app)
|
|
9
|
+
def stats
|
|
10
|
+
app = input[:app]
|
|
11
|
+
|
|
12
|
+
stats =
|
|
13
|
+
with_progress("Getting stats for #{c(app.name, :name)}") do |s|
|
|
14
|
+
begin
|
|
15
|
+
app.stats
|
|
16
|
+
rescue CFoundry::StatsError
|
|
17
|
+
s.fail do
|
|
18
|
+
err "Application #{b(app.name)} is not running."
|
|
19
|
+
return
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
line unless quiet?
|
|
25
|
+
|
|
26
|
+
table(
|
|
27
|
+
%w{instance cpu memory disk},
|
|
28
|
+
stats.sort_by { |idx, _| idx.to_i }.collect { |idx, info|
|
|
29
|
+
idx = c("\##{idx}", :instance)
|
|
30
|
+
|
|
31
|
+
if info[:state] == "DOWN"
|
|
32
|
+
[idx, c("down", :bad)]
|
|
33
|
+
else
|
|
34
|
+
stats = info[:stats]
|
|
35
|
+
usage = stats[:usage]
|
|
36
|
+
|
|
37
|
+
if usage
|
|
38
|
+
[ idx,
|
|
39
|
+
"#{percentage(usage[:cpu])}",
|
|
40
|
+
"#{usage(usage[:mem], stats[:mem_quota])}",
|
|
41
|
+
"#{usage(usage[:disk], stats[:disk_quota])}"
|
|
42
|
+
]
|
|
43
|
+
else
|
|
44
|
+
[idx, c("n/a", :neutral)]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
})
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def percentage(num, low = 50, mid = 70)
|
|
51
|
+
color =
|
|
52
|
+
if num <= low
|
|
53
|
+
:good
|
|
54
|
+
elsif num <= mid
|
|
55
|
+
:warning
|
|
56
|
+
else
|
|
57
|
+
:bad
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
c(format("%.1f\%", num), color)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def usage(used, limit)
|
|
64
|
+
"#{b(human_size(used))} of #{b(human_size(limit, 0))}"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|