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
data/vmc-ng/Rakefile
CHANGED
@@ -6,43 +6,34 @@ require "vmc/version"
|
|
6
6
|
task :default => :spec
|
7
7
|
|
8
8
|
desc "Run specs"
|
9
|
-
task :spec =>
|
10
|
-
|
11
|
-
desc "Run integration tests"
|
12
|
-
task :test => ["bundler:install", "test:integration"]
|
13
|
-
|
14
|
-
task :build do
|
15
|
-
sh "gem build vmc.gemspec"
|
16
|
-
end
|
17
|
-
|
18
|
-
task :install => :build do
|
19
|
-
sh "gem install --local vmc-#{VMC::VERSION}"
|
20
|
-
sh "rm vmc-#{VMC::VERSION}.gem"
|
21
|
-
end
|
22
|
-
|
23
|
-
task :uninstall do
|
24
|
-
sh "gem uninstall vmc"
|
9
|
+
task :spec => "bundler:install" do
|
10
|
+
sh("rspec")
|
25
11
|
end
|
26
12
|
|
27
|
-
|
28
|
-
|
29
|
-
task :release => :build do
|
30
|
-
sh "gem push vmc-#{VMC::VERSION}.gem"
|
31
|
-
end
|
32
|
-
|
33
|
-
namespace "bundler" do
|
34
|
-
desc "Install gems"
|
13
|
+
namespace :bundler do
|
14
|
+
desc "Install bundler and gems"
|
35
15
|
task "install" do
|
36
|
-
sh("bundle install")
|
16
|
+
sh("(gem list --local bundler | grep bundler || gem install bundler) && (bundle check || bundle install)")
|
37
17
|
end
|
38
18
|
end
|
39
19
|
|
40
|
-
namespace
|
41
|
-
|
42
|
-
|
20
|
+
namespace :gem do
|
21
|
+
desc "Build Gem"
|
22
|
+
task :build do
|
23
|
+
sh "gem build vmc.gemspec"
|
43
24
|
end
|
44
25
|
|
45
|
-
|
46
|
-
|
26
|
+
desc "Install Gem"
|
27
|
+
task :install => :build do
|
28
|
+
sh "gem install --local vmc-#{VMC::VERSION}"
|
29
|
+
sh "rm vmc-#{VMC::VERSION}.gem"
|
47
30
|
end
|
31
|
+
|
32
|
+
desc "Uninstall Gem"
|
33
|
+
task :uninstall do
|
34
|
+
sh "gem uninstall vmc"
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "Reinstall Gem"
|
38
|
+
task :reinstall => [:uninstall, :install]
|
48
39
|
end
|
data/vmc-ng/lib/vmc.rb
CHANGED
@@ -2,10 +2,11 @@ require "vmc/version"
|
|
2
2
|
|
3
3
|
require "vmc/cli"
|
4
4
|
require "vmc/cli/start"
|
5
|
-
require "vmc/cli/app"
|
6
5
|
require "vmc/cli/service"
|
7
6
|
require "vmc/cli/user"
|
8
7
|
require "vmc/cli/space"
|
9
8
|
require "vmc/cli/organization"
|
10
|
-
|
11
|
-
|
9
|
+
|
10
|
+
Dir[File.expand_path("../vmc/cli/{app,route,domain}/*.rb", __FILE__)].each do |file|
|
11
|
+
require file unless File.basename(file) == 'base.rb'
|
12
|
+
end
|
data/vmc-ng/lib/vmc/cli.rb
CHANGED
@@ -2,10 +2,9 @@ require "yaml"
|
|
2
2
|
require "socket"
|
3
3
|
require "net/http"
|
4
4
|
require "multi_json"
|
5
|
+
require "fileutils"
|
5
6
|
|
6
7
|
require "mothership"
|
7
|
-
require "mothership/pretty"
|
8
|
-
require "mothership/progress"
|
9
8
|
|
10
9
|
require "cfoundry"
|
11
10
|
|
@@ -23,8 +22,6 @@ module VMC
|
|
23
22
|
class CLI < Mothership
|
24
23
|
include VMC::Interactive
|
25
24
|
include VMC::Spacing
|
26
|
-
include Mothership::Pretty
|
27
|
-
include Mothership::Progress
|
28
25
|
|
29
26
|
option :help, :alias => "-h", :type => :boolean,
|
30
27
|
:desc => "Show command usage & instructions"
|
@@ -148,7 +145,11 @@ module VMC
|
|
148
145
|
msg = e.class.name
|
149
146
|
msg << ": #{e}" unless e.to_s.empty?
|
150
147
|
|
151
|
-
File.
|
148
|
+
crash_file = File.expand_path(VMC::CRASH_FILE)
|
149
|
+
|
150
|
+
FileUtils.mkdir_p(File.dirname(crash_file))
|
151
|
+
|
152
|
+
File.open(crash_file, "w") do |f|
|
152
153
|
f.puts "Time of crash:"
|
153
154
|
f.puts " #{Time.now}"
|
154
155
|
f.puts ""
|
@@ -260,7 +261,7 @@ module VMC
|
|
260
261
|
return exp if File.exist? exp
|
261
262
|
end
|
262
263
|
|
263
|
-
paths.first
|
264
|
+
File.expand_path(paths.first)
|
264
265
|
end
|
265
266
|
|
266
267
|
def client_target
|
@@ -396,21 +397,21 @@ module VMC
|
|
396
397
|
def find_by_name(what)
|
397
398
|
proc { |name, choices, *_|
|
398
399
|
choices.find { |c| c.name == name } ||
|
399
|
-
fail("Unknown #{what} '#{name}'")
|
400
|
+
fail("Unknown #{what} '#{name}'.")
|
400
401
|
}
|
401
402
|
end
|
402
403
|
|
403
404
|
def by_name(what, obj = what)
|
404
405
|
proc { |name, *_|
|
405
406
|
client.send(:"#{obj}_by_name", name) ||
|
406
|
-
fail("Unknown #{what} '#{name}'")
|
407
|
+
fail("Unknown #{what} '#{name}'.")
|
407
408
|
}
|
408
409
|
end
|
409
410
|
|
410
411
|
def find_by_name_insensitive(what)
|
411
412
|
proc { |name, choices|
|
412
413
|
choices.find { |c| c.name.upcase == name.upcase } ||
|
413
|
-
fail("Unknown #{what} '#{name}'")
|
414
|
+
fail("Unknown #{what} '#{name}'.")
|
414
415
|
}
|
415
416
|
end
|
416
417
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "vmc/cli/app/base"
|
2
|
+
|
3
|
+
module VMC::App
|
4
|
+
class Apps < Base
|
5
|
+
IS_UTF8 = !!(ENV["LC_ALL"] || ENV["LC_CTYPE"] || ENV["LANG"] || "")["UTF-8"].freeze
|
6
|
+
|
7
|
+
desc "Show app information"
|
8
|
+
group :apps
|
9
|
+
input :app, :argument => :required, :from_given => by_name("app"),
|
10
|
+
:desc => "App to show"
|
11
|
+
def app
|
12
|
+
app = input[:app]
|
13
|
+
|
14
|
+
if quiet?
|
15
|
+
line app.name
|
16
|
+
else
|
17
|
+
display_app(app)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def display_app(a)
|
22
|
+
status = app_status(a)
|
23
|
+
|
24
|
+
line "#{c(a.name, :name)}: #{status}"
|
25
|
+
|
26
|
+
indented do
|
27
|
+
line "platform: #{b(a.framework.name)} on #{b(a.runtime.name)}"
|
28
|
+
|
29
|
+
start_line "usage: #{b(human_mb(a.memory))}"
|
30
|
+
print " #{d(IS_UTF8 ? "\xc3\x97" : "x")} #{b(a.total_instances)}"
|
31
|
+
print " instance#{a.total_instances == 1 ? "" : "s"}"
|
32
|
+
|
33
|
+
line
|
34
|
+
|
35
|
+
unless a.urls.empty?
|
36
|
+
line "urls: #{a.urls.collect { |u| b(u) }.join(", ")}"
|
37
|
+
end
|
38
|
+
|
39
|
+
unless a.services.empty?
|
40
|
+
line "services: #{a.services.collect { |s| b(s.name) }.join(", ")}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require "vmc/cli/app/base"
|
2
|
+
|
3
|
+
module VMC::App
|
4
|
+
class Apps < Base
|
5
|
+
desc "List your applications"
|
6
|
+
group :apps
|
7
|
+
input :space, :from_given => by_name("space"),
|
8
|
+
:default => proc { client.current_space },
|
9
|
+
:desc => "Show apps in given space"
|
10
|
+
input :name, :desc => "Filter by name regexp"
|
11
|
+
input :runtime, :desc => "Filter by runtime regexp"
|
12
|
+
input :framework, :desc => "Filter by framework regexp"
|
13
|
+
input :url, :desc => "Filter by url regexp"
|
14
|
+
input :full, :type => :boolean, :default => false,
|
15
|
+
:desc => "Verbose output format"
|
16
|
+
def apps
|
17
|
+
if space = input[:space]
|
18
|
+
space.summarize! rescue CFoundry::APIError
|
19
|
+
|
20
|
+
apps =
|
21
|
+
with_progress("Getting applications in #{c(space.name, :name)}") do
|
22
|
+
space.apps
|
23
|
+
end
|
24
|
+
else
|
25
|
+
apps =
|
26
|
+
with_progress("Getting applications") do
|
27
|
+
client.apps(:depth => 2)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
line unless quiet?
|
32
|
+
|
33
|
+
if apps.empty? and !quiet?
|
34
|
+
line "No applications."
|
35
|
+
return
|
36
|
+
end
|
37
|
+
|
38
|
+
apps.reject! do |a|
|
39
|
+
!app_matches?(a, input)
|
40
|
+
end
|
41
|
+
|
42
|
+
apps = apps.sort_by(&:name)
|
43
|
+
|
44
|
+
if input[:full]
|
45
|
+
spaced(apps) do |a|
|
46
|
+
invoke :app, :app => a
|
47
|
+
end
|
48
|
+
elsif quiet?
|
49
|
+
apps.each do |a|
|
50
|
+
line a.name
|
51
|
+
end
|
52
|
+
else
|
53
|
+
display_apps_table(apps)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def display_apps_table(apps)
|
58
|
+
table(
|
59
|
+
["name", "status", "usage", v2? && "plan", "runtime", "url"],
|
60
|
+
apps.collect { |a|
|
61
|
+
[ c(a.name, :name),
|
62
|
+
app_status(a),
|
63
|
+
"#{a.total_instances} x #{human_mb(a.memory)}",
|
64
|
+
v2? && (a.production ? "prod" : "dev"),
|
65
|
+
a.runtime.name,
|
66
|
+
if a.urls.empty?
|
67
|
+
d("none")
|
68
|
+
elsif a.urls.size == 1
|
69
|
+
a.url
|
70
|
+
else
|
71
|
+
"#{a.url}, ..."
|
72
|
+
end
|
73
|
+
]
|
74
|
+
})
|
75
|
+
end
|
76
|
+
|
77
|
+
def app_matches?(a, options)
|
78
|
+
if name = options[:name]
|
79
|
+
return false if a.name !~ /#{name}/
|
80
|
+
end
|
81
|
+
|
82
|
+
if runtime = options[:runtime]
|
83
|
+
return false if a.runtime.name !~ /#{runtime}/
|
84
|
+
end
|
85
|
+
|
86
|
+
if framework = options[:framework]
|
87
|
+
return false if a.framework.name !~ /#{framework}/
|
88
|
+
end
|
89
|
+
|
90
|
+
if url = options[:url]
|
91
|
+
return false if a.urls.none? { |u| u =~ /#{url}/ }
|
92
|
+
end
|
93
|
+
|
94
|
+
true
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require "vmc/cli"
|
2
|
+
|
3
|
+
module VMC
|
4
|
+
module App
|
5
|
+
class Base < CLI
|
6
|
+
# choose the right color for app/instance state
|
7
|
+
def state_color(s)
|
8
|
+
case s
|
9
|
+
when "STARTING"
|
10
|
+
:neutral
|
11
|
+
when "STARTED", "RUNNING"
|
12
|
+
:good
|
13
|
+
when "DOWN"
|
14
|
+
:bad
|
15
|
+
when "FLAPPING"
|
16
|
+
:error
|
17
|
+
when "N/A"
|
18
|
+
:unknown
|
19
|
+
else
|
20
|
+
:warning
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def app_status(a)
|
25
|
+
health = a.health
|
26
|
+
|
27
|
+
if a.debug_mode == "suspend" && health == "0%"
|
28
|
+
c("suspended", :neutral)
|
29
|
+
else
|
30
|
+
c(health.downcase, state_color(health))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def memory_choices(exclude = 0)
|
35
|
+
info = client.info
|
36
|
+
used = info[:usage][:memory]
|
37
|
+
limit = info[:limits][:memory]
|
38
|
+
available = limit - used + exclude
|
39
|
+
|
40
|
+
mem = 64
|
41
|
+
choices = []
|
42
|
+
until mem > available
|
43
|
+
choices << human_mb(mem)
|
44
|
+
mem *= 2
|
45
|
+
end
|
46
|
+
|
47
|
+
choices
|
48
|
+
end
|
49
|
+
|
50
|
+
def human_mb(num)
|
51
|
+
human_size(num * 1024 * 1024, 0)
|
52
|
+
end
|
53
|
+
|
54
|
+
def human_size(num, precision = 1)
|
55
|
+
sizes = ["G", "M", "K"]
|
56
|
+
sizes.each.with_index do |suf, i|
|
57
|
+
pow = sizes.size - i
|
58
|
+
unit = 1024 ** pow
|
59
|
+
if num >= unit
|
60
|
+
return format("%.#{precision}f%s", num / unit, suf)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
format("%.#{precision}fB", num)
|
65
|
+
end
|
66
|
+
|
67
|
+
def megabytes(str)
|
68
|
+
if str =~ /T$/i
|
69
|
+
str.to_i * 1024 * 1024
|
70
|
+
elsif str =~ /G$/i
|
71
|
+
str.to_i * 1024
|
72
|
+
elsif str =~ /M$/i
|
73
|
+
str.to_i
|
74
|
+
elsif str =~ /K$/i
|
75
|
+
str.to_i / 1024
|
76
|
+
else # assume megabytes
|
77
|
+
str.to_i
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "vmc/cli/app/base"
|
2
|
+
|
3
|
+
module VMC::App
|
4
|
+
class Crashes < Base
|
5
|
+
desc "List an app's crashed instances"
|
6
|
+
group :apps, :info, :hidden => true
|
7
|
+
input :apps, :argument => :splat, :singular => :app,
|
8
|
+
:desc => "Applications whose crashed instances to list",
|
9
|
+
:from_given => by_name("app")
|
10
|
+
def crashes
|
11
|
+
apps = input[:apps]
|
12
|
+
fail "No applications given." if apps.empty?
|
13
|
+
|
14
|
+
spaced(apps) do |app|
|
15
|
+
instances =
|
16
|
+
with_progress("Getting crashed instances for #{c(app.name, :name)}") do
|
17
|
+
app.crashes
|
18
|
+
end
|
19
|
+
|
20
|
+
spaced(instances) do |i|
|
21
|
+
if quiet?
|
22
|
+
line i.id
|
23
|
+
else
|
24
|
+
display_crashed_instance(i)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def display_crashed_instance(i)
|
31
|
+
start_line "instance #{c("\##{i.id}", :instance)}: "
|
32
|
+
puts "#{b(c("crashed", :error))} "
|
33
|
+
|
34
|
+
indented do
|
35
|
+
if s = i.since
|
36
|
+
line "since: #{c(s.strftime("%F %r"), :neutral)}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require "set"
|
2
|
+
|
3
|
+
require "vmc/cli/app/base"
|
4
|
+
|
5
|
+
module VMC::App
|
6
|
+
class Delete < Base
|
7
|
+
desc "Delete an application"
|
8
|
+
group :apps, :manage
|
9
|
+
input(:apps, :argument => :splat, :singular => :app,
|
10
|
+
:desc => "Applications to delete",
|
11
|
+
:from_given => by_name("app")) {
|
12
|
+
apps = client.apps
|
13
|
+
fail "No applications." if apps.empty?
|
14
|
+
|
15
|
+
[ask("Delete which application?", :choices => apps.sort_by(&:name),
|
16
|
+
:display => proc(&:name))]
|
17
|
+
}
|
18
|
+
input(:really, :type => :boolean, :forget => true,
|
19
|
+
:default => proc { force? || interact }) { |name, color|
|
20
|
+
ask("Really delete #{c(name, color)}?", :default => false)
|
21
|
+
}
|
22
|
+
input :routes, :type => :boolean, :default => false,
|
23
|
+
:desc => "Delete associated routes"
|
24
|
+
input :orphaned, :aliases => "-o", :type => :boolean,
|
25
|
+
:desc => "Delete orphaned instances"
|
26
|
+
input :all, :type => :boolean, :default => false,
|
27
|
+
:desc => "Delete all applications"
|
28
|
+
def delete
|
29
|
+
apps = client.apps
|
30
|
+
|
31
|
+
if input[:all]
|
32
|
+
return unless input[:really, "ALL APPS", :bad]
|
33
|
+
|
34
|
+
to_delete = apps
|
35
|
+
others = []
|
36
|
+
else
|
37
|
+
to_delete = input[:apps]
|
38
|
+
others = apps - to_delete
|
39
|
+
end
|
40
|
+
|
41
|
+
orphaned = find_orphaned_services(to_delete, others)
|
42
|
+
|
43
|
+
deleted = []
|
44
|
+
spaced(to_delete) do |app|
|
45
|
+
really = input[:all] || input[:really, app.name, :name]
|
46
|
+
next unless really
|
47
|
+
|
48
|
+
deleted << app
|
49
|
+
|
50
|
+
with_progress("Deleting #{c(app.name, :name)}") do
|
51
|
+
app.routes.collect(&:delete!) if input[:routes]
|
52
|
+
app.delete!
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
delete_orphaned_services(orphaned, input[:orphaned])
|
57
|
+
|
58
|
+
to_delete
|
59
|
+
end
|
60
|
+
|
61
|
+
def find_orphaned_services(apps, others = [])
|
62
|
+
orphaned = Set.new
|
63
|
+
|
64
|
+
apps.each do |a|
|
65
|
+
a.services.each do |i|
|
66
|
+
if others.none? { |x| x.binds?(i) }
|
67
|
+
orphaned << i
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
orphaned.each(&:invalidate!)
|
73
|
+
end
|
74
|
+
|
75
|
+
def delete_orphaned_services(instances, orphaned)
|
76
|
+
return if instances.empty?
|
77
|
+
|
78
|
+
line unless quiet? || force?
|
79
|
+
|
80
|
+
instances.select { |i|
|
81
|
+
orphaned ||
|
82
|
+
ask("Delete orphaned service instance #{c(i.name, :name)}?",
|
83
|
+
:default => false)
|
84
|
+
}.each do |instance|
|
85
|
+
# TODO: splat
|
86
|
+
invoke :delete_service, :instance => instance, :really => true
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|