capricorn 0.2.00
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/app_generators/engine/engine_generator.rb +39 -0
- data/app_generators/engine/templates/Gmfile +20 -0
- data/app_generators/engine/templates/MIT-LICENSE.txt +20 -0
- data/app_generators/engine/templates/README.rdoc +7 -0
- data/app_generators/engine/templates/config/routes.rb +2 -0
- data/app_generators/engine/templates/gitignore +3 -0
- data/app_generators/engine/templates/init.rb +1 -0
- data/app_generators/engine/templates/lib/engine.rb +1 -0
- data/app_generators/engine/templates/rails/init.rb +1 -0
- data/app_generators/engine/templates/tasks/engine_tasks.rake +4 -0
- data/bin/capricorn +20 -0
- data/lib/capricorn.rb +100 -0
- data/lib/capricorn/actor.rb +23 -0
- data/lib/capricorn/actor/actions.rb +76 -0
- data/lib/capricorn/actors/apache_actor.rb +56 -0
- data/lib/capricorn/actors/base_actor.rb +276 -0
- data/lib/capricorn/actors/mysql_actor.rb +20 -0
- data/lib/capricorn/actors/passenger_actor.rb +19 -0
- data/lib/capricorn/actors/plesk_actor.rb +210 -0
- data/lib/capricorn/actors/sqlite3_actor.rb +44 -0
- data/lib/capricorn/app_runner.rb +119 -0
- data/lib/capricorn/apps/dev.rb +15 -0
- data/lib/capricorn/apps/engines.rb +33 -0
- data/lib/capricorn/apps/jobs.rb +35 -0
- data/lib/capricorn/apps/satellite.rb +32 -0
- data/lib/capricorn/apps/server.rb +67 -0
- data/lib/capricorn/client.rb +48 -0
- data/lib/capricorn/client/auth_token.rb +98 -0
- data/lib/capricorn/daemon.rb +71 -0
- data/lib/capricorn/exception_handler.rb +79 -0
- data/lib/capricorn/extentions/rubygems_plugin.rb +27 -0
- data/lib/capricorn/extentions/thor_extentions.rb +32 -0
- data/lib/capricorn/job_queue.rb +199 -0
- data/lib/capricorn/satellite.rb +50 -0
- data/lib/capricorn/satellite/actions.rb +35 -0
- data/lib/capricorn/satellite/dependency_loader.rb +78 -0
- data/lib/capricorn/satellite/persistence.rb +50 -0
- data/lib/capricorn/server.rb +122 -0
- data/lib/capricorn/server/daemon.rb +88 -0
- data/lib/capricorn/server/proxy.rb +25 -0
- data/lib/capricorn/server/security.rb +113 -0
- data/lib/capricorn/system.rb +184 -0
- data/lib/capricorn/system/config.rb +49 -0
- data/lib/capricorn/system/helper.rb +21 -0
- data/lib/capricorn/system/options.rb +79 -0
- data/lib/capricorn/system/process_user.rb +73 -0
- data/lib/capricorn/system/satellites.rb +44 -0
- data/lib/capricorn/system/shell.rb +80 -0
- data/lib/rubygems_plugin.rb +1 -0
- data/spec/actor/actions_spec.rb +13 -0
- data/spec/spec_helper.rb +1 -0
- metadata +108 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
module Capricorn
|
3
|
+
module Actors # :nodoc:
|
4
|
+
class MysqlActor < Capricorn::Actor
|
5
|
+
|
6
|
+
on_install_satellite :create_database
|
7
|
+
before_uninstall_satellite :backup_database
|
8
|
+
on_uninstall_satellite :drop_database
|
9
|
+
|
10
|
+
def create_database
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
def drop_database
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
module Capricorn
|
3
|
+
module Actors # :nodoc:
|
4
|
+
class PassengerActor < Capricorn::Actor
|
5
|
+
|
6
|
+
after_install_satellite :restart
|
7
|
+
after_link_satellite :restart
|
8
|
+
|
9
|
+
# restart the current satellite.
|
10
|
+
def restart
|
11
|
+
system.as_user(system.web_user, system.web_group) do
|
12
|
+
tmp_restart = File.join(system.satellite_root, 'tmp', 'restart.txt')
|
13
|
+
FileUtils.touch tmp_restart, :verbose => true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,210 @@
|
|
1
|
+
|
2
|
+
module Capricorn
|
3
|
+
module Actors # :nodoc:
|
4
|
+
class PleskActor < Capricorn::Actor
|
5
|
+
|
6
|
+
before_install_satellite :create_client
|
7
|
+
before_install_satellite :create_domain
|
8
|
+
after_install_satellite :link_htdocs
|
9
|
+
after_install_satellite :reload_subdomains
|
10
|
+
after_install_satellite :restart_apache
|
11
|
+
on_install_satellite :create_database
|
12
|
+
on_uninstall_satellite :drop_databases
|
13
|
+
|
14
|
+
def create_client
|
15
|
+
# only do this if this is needed
|
16
|
+
if false
|
17
|
+
unless system.client?(system.plesk_client)
|
18
|
+
system.create_client(system.plesk_client, system.plesk_client, 'mypwd')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_domain
|
24
|
+
unless system.domain?(satellite.basedomain)
|
25
|
+
system.create_domain(system.plesk_client, satellite.basedomain,
|
26
|
+
system.web_user[0,20], (rand(1_000_000_000) + 10_000).to_s)
|
27
|
+
else
|
28
|
+
httpdocs_path = "/var/www/vhosts/#{satellite.basedomain}/httpdocs"
|
29
|
+
system.set_satellite_option(:web_user,
|
30
|
+
system.get_user_name(File.stat(httpdocs_path).uid))
|
31
|
+
end
|
32
|
+
|
33
|
+
if satellite.subdomain? and !system.subdomain?(satellite.basedomain, satellite.subdomain)
|
34
|
+
system.create_subdomain(satellite.basedomain, satellite.subdomain)
|
35
|
+
end
|
36
|
+
|
37
|
+
FileUtils.mkdir_p(system.satellite_root)
|
38
|
+
FileUtils.mkdir_p(system.shared_root)
|
39
|
+
FileUtils.chown_R(system.web_user, system.web_group, system.satellite_root)
|
40
|
+
FileUtils.chown_R(system.web_user, system.web_group, system.shared_root)
|
41
|
+
end
|
42
|
+
|
43
|
+
def link_htdocs
|
44
|
+
httpdocs_path = File.join(File.dirname(system.satellite_root), 'httpdocs')
|
45
|
+
FileUtils.rm_rf(httpdocs_path)
|
46
|
+
FileUtils.ln_s(system.satellite_root, httpdocs_path)
|
47
|
+
FileUtils.chown_R(system.web_user, system.web_group, httpdocs_path)
|
48
|
+
|
49
|
+
File.open(File.join(system.satellite_root, '../conf/vhost.conf'), 'w+') do |f|
|
50
|
+
f.puts "DocumentRoot #{httpdocs_path}/public"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def reload_subdomains
|
55
|
+
system.run("#{system.plesk_websrvmng_bin} --reconfigure-vhost --vhost-name=#{satellite.basedomain}")
|
56
|
+
end
|
57
|
+
|
58
|
+
def restart_apache
|
59
|
+
system.run("#{system.plesk_httpd_bin} restart")
|
60
|
+
end
|
61
|
+
|
62
|
+
def create_database
|
63
|
+
db_name = satellite.domain.downcase.gsub(/[^a-z]+/, '_')[0,63]
|
64
|
+
db_user = db_name[0,13]
|
65
|
+
db_pswd = (rand(1_000_000_000) + 10_000).to_s
|
66
|
+
|
67
|
+
system.create_database(satellite.basedomain, "#{db_name}_d", "#{db_user}_ud", db_pswd)
|
68
|
+
system.create_database(satellite.basedomain, "#{db_name}_t", "#{db_user}_ut", db_pswd)
|
69
|
+
system.create_database(satellite.basedomain, "#{db_name}_p", "#{db_user}_up", db_pswd)
|
70
|
+
|
71
|
+
|
72
|
+
system.as_user(system.web_user, system.web_group) do
|
73
|
+
config = %{
|
74
|
+
development:
|
75
|
+
adapter: mysql
|
76
|
+
database: #{db_name}_d
|
77
|
+
username: #{db_user}_ud
|
78
|
+
password: #{db_pswd}
|
79
|
+
host: localhost
|
80
|
+
encoding: utf8
|
81
|
+
socket: /var/lib/mysql/mysql.sock
|
82
|
+
|
83
|
+
test:
|
84
|
+
adapter: mysql
|
85
|
+
database: #{db_name}_t
|
86
|
+
username: #{db_user}_ut
|
87
|
+
password: #{db_pswd}
|
88
|
+
host: localhost
|
89
|
+
encoding: utf8
|
90
|
+
socket: /var/lib/mysql/mysql.sock
|
91
|
+
|
92
|
+
production:
|
93
|
+
adapter: mysql
|
94
|
+
database: #{db_name}_p
|
95
|
+
username: #{db_user}_up
|
96
|
+
password: #{db_pswd}
|
97
|
+
host: localhost
|
98
|
+
encoding: utf8
|
99
|
+
socket: /var/lib/mysql/mysql.sock
|
100
|
+
}
|
101
|
+
|
102
|
+
db_file = File.join(system.satellite_root, 'config', 'database.yml')
|
103
|
+
File.open(db_file, 'w+') { |f| f.write config }
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def drop_databases
|
108
|
+
db_name = satellite.domain.downcase.gsub(/[^a-z]+/, '_')[0,63]
|
109
|
+
|
110
|
+
system.drop_database("#{db_name}_d")
|
111
|
+
system.drop_database("#{db_name}_t")
|
112
|
+
system.drop_database("#{db_name}_p")
|
113
|
+
end
|
114
|
+
|
115
|
+
module Helper
|
116
|
+
|
117
|
+
def create_client(name, login, pwd)
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
# check is the client exists
|
122
|
+
def client?(login)
|
123
|
+
!(run("#{plesk_client_bin} -i #{login}") =~ /Object not found: Client/)
|
124
|
+
end
|
125
|
+
|
126
|
+
# create a domain through plesk
|
127
|
+
def create_domain(client, domain, user, passwd)
|
128
|
+
run("#{plesk_domain_bin} -c #{domain} -clogin #{client} -status enabled -hosting true -hst_type phys -dns true -www true -login #{user} -passwd #{passwd} -shell /bin/bash")
|
129
|
+
end
|
130
|
+
|
131
|
+
# check if a domain exists with plesk
|
132
|
+
def domain?(domain)
|
133
|
+
!(run("#{plesk_domain_bin} -i #{domain}") =~ /Object not found: Domain/)
|
134
|
+
end
|
135
|
+
|
136
|
+
# create a subdomain through plesk
|
137
|
+
def create_subdomain(basedomain, subdomain)
|
138
|
+
run("#{plesk_subdomain_bin} -c #{subdomain} -d #{basedomain}")
|
139
|
+
end
|
140
|
+
|
141
|
+
# check if a subdomain exists with plesk
|
142
|
+
def subdomain?(basedomain, subdomain)
|
143
|
+
run("#{plesk_subdomain_bin} -i -s #{subdomain} -d #{basedomain}") =~ /SUCCESS: Gathering/
|
144
|
+
end
|
145
|
+
|
146
|
+
# create a database through plesk
|
147
|
+
def create_database(basedomain, db_name, db_user, pwd)
|
148
|
+
o = run("#{plesk_database_bin} -c #{db_name} -domain #{basedomain} -server #{plesk_database_server} -add_user #{db_user} -passwd #{pwd}")
|
149
|
+
if o =~ /Database with requested name already exists/
|
150
|
+
o = run("#{plesk_database_bin} -u #{db_name} -add_user #{db_user} -passwd #{pwd}")
|
151
|
+
if o =~ /Unable to create database user: User/
|
152
|
+
o = run("#{plesk_database_bin} -u #{db_name} -update_user #{db_user} -passwd #{pwd}")
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# drop a database through plesk
|
158
|
+
def drop_database(db_name)
|
159
|
+
run("#{plesk_database_bin} -r #{db_name}")
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
module Config
|
165
|
+
|
166
|
+
# set the plesk client to be used for this satellite.
|
167
|
+
def plesk_client(&block)
|
168
|
+
satellite_option(:plesk_client, block)
|
169
|
+
end
|
170
|
+
|
171
|
+
# path to the client tool.
|
172
|
+
def plesk_client_bin(&block)
|
173
|
+
option(:plesk_client_bin, block) { |v| v or '/usr/local/psa/bin/client' }
|
174
|
+
end
|
175
|
+
|
176
|
+
# path to the domain tool.
|
177
|
+
def plesk_domain_bin(&block)
|
178
|
+
option(:plesk_domain_bin, block) { |v| v or '/usr/local/psa/bin/domain' }
|
179
|
+
end
|
180
|
+
|
181
|
+
# path to the subdomain tool.
|
182
|
+
def plesk_subdomain_bin(&block)
|
183
|
+
option(:plesk_subdomain_bin, block) { |v| v or '/usr/local/psa/bin/subdomain' }
|
184
|
+
end
|
185
|
+
|
186
|
+
# path to the database tool.
|
187
|
+
def plesk_database_bin(&block)
|
188
|
+
option(:plesk_database_bin, block) { |v| v or '/usr/local/psa/bin/database' }
|
189
|
+
end
|
190
|
+
|
191
|
+
# path to the websrvmng tool.
|
192
|
+
def plesk_websrvmng_bin(&block)
|
193
|
+
option(:plesk_websrvmng_bin, block) { |v| v or '/usr/local/psa/admin/sbin/websrvmng' }
|
194
|
+
end
|
195
|
+
|
196
|
+
# path to the httpd tool.
|
197
|
+
def plesk_httpd_bin(&block)
|
198
|
+
option(:plesk_httpd_bin, block) { |v| v or '/etc/init.d/httpd' }
|
199
|
+
end
|
200
|
+
|
201
|
+
# host and port of database server.
|
202
|
+
def plesk_database_server(&block)
|
203
|
+
option(:plesk_database_server, block)
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
module Capricorn
|
3
|
+
module Actors # :nodoc:
|
4
|
+
class Sqlite3Actor < Capricorn::Actor
|
5
|
+
|
6
|
+
after_install_satellite :write_config_file
|
7
|
+
|
8
|
+
# write the +database.yml+ config file.
|
9
|
+
def write_config_file
|
10
|
+
system.as_user(system.web_user, system.web_group) do
|
11
|
+
|
12
|
+
config = %{# SQLite version 3.x
|
13
|
+
# gem install sqlite3-ruby (not necessary on OS X Leopard)
|
14
|
+
development:
|
15
|
+
adapter: sqlite3
|
16
|
+
database: db/system/development.sqlite3
|
17
|
+
pool: 5
|
18
|
+
timeout: 5000
|
19
|
+
|
20
|
+
# Warning: The database defined as "test" will be erased and
|
21
|
+
# re-generated from your development database when you run "rake".
|
22
|
+
# Do not set this db to the same as development or production.
|
23
|
+
test:
|
24
|
+
adapter: sqlite3
|
25
|
+
database: db/system/test.sqlite3
|
26
|
+
pool: 5
|
27
|
+
timeout: 5000
|
28
|
+
|
29
|
+
production:
|
30
|
+
adapter: sqlite3
|
31
|
+
database: db/system/production.sqlite3
|
32
|
+
pool: 5
|
33
|
+
timeout: 5000
|
34
|
+
}
|
35
|
+
|
36
|
+
db_file = File.join(system.satellite_root, 'config', 'database.yml')
|
37
|
+
File.open(db_file, 'w+') { |f| f.write config }
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
Capricorn.runtime_gem('thor', Capricorn::THOR_VERSION)
|
2
|
+
|
3
|
+
require File.dirname(__FILE__)+'/extentions/thor_extentions'
|
4
|
+
|
5
|
+
module Capricorn
|
6
|
+
|
7
|
+
# AppRunner allows us to have multiple apps in different namespaces
|
8
|
+
class AppRunner < Thor
|
9
|
+
|
10
|
+
# register a subapplication with the app runner.
|
11
|
+
def self.use(app)
|
12
|
+
Capricorn::Apps.const_get(app)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Override Thor#help so we can give info about not-yet-loaded tasks
|
16
|
+
def help(task = nil)
|
17
|
+
super
|
18
|
+
|
19
|
+
unless task
|
20
|
+
search = ".*#{search}" if options["substring"]
|
21
|
+
search = /^#{search}.*/i
|
22
|
+
group = options[:group] || "standard"
|
23
|
+
|
24
|
+
classes = Thor.subclasses.select do |k|
|
25
|
+
(options[:all] || k.group_name == group) &&
|
26
|
+
Thor::Util.constant_to_thor_path(k.name) =~ search
|
27
|
+
end
|
28
|
+
display_klasses(false, classes)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# forward actions to the sub apps
|
33
|
+
def method_missing(meth, *args)
|
34
|
+
meth = meth.to_s
|
35
|
+
super(meth.to_sym, *args) unless meth.include?(?:)
|
36
|
+
|
37
|
+
begin
|
38
|
+
task = Thor[meth]
|
39
|
+
task.parse(task.klass.new, ARGV[1..-1])
|
40
|
+
rescue => e
|
41
|
+
puts e.message
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def display_klasses(with_modules = false, klasses = Thor.subclasses)
|
48
|
+
klasses -= [Thor, Capricorn::AppRunner] unless with_modules
|
49
|
+
raise Error, "No Thor tasks available" if klasses.empty?
|
50
|
+
|
51
|
+
if with_modules && !thor_yaml.empty?
|
52
|
+
max_name = thor_yaml.max { |(xk, xv), (yk, yv)| xk.to_s.size <=> yk.to_s.size }.first.size
|
53
|
+
modules_label = "Modules"
|
54
|
+
namespaces_label = "Namespaces"
|
55
|
+
column_width = [max_name + 4, modules_label.size + 1].max
|
56
|
+
|
57
|
+
print "%-#{column_width}s" % modules_label
|
58
|
+
puts namespaces_label
|
59
|
+
print "%-#{column_width}s" % ("-" * modules_label.size)
|
60
|
+
puts "-" * namespaces_label.size
|
61
|
+
|
62
|
+
thor_yaml.each do |name, info|
|
63
|
+
print "%-#{column_width}s" % name
|
64
|
+
puts info[:constants].map { |c| Thor::Util.constant_to_thor_path(c) }.join(", ")
|
65
|
+
end
|
66
|
+
|
67
|
+
puts
|
68
|
+
end
|
69
|
+
|
70
|
+
# Calculate the largest base class name
|
71
|
+
max_base = klasses.max do |x,y|
|
72
|
+
Thor::Util.constant_to_thor_path(x.name).size <=> Thor::Util.constant_to_thor_path(y.name).size
|
73
|
+
end.name.size
|
74
|
+
|
75
|
+
# Calculate the size of the largest option description
|
76
|
+
max_left_item = klasses.max do |x,y|
|
77
|
+
(x.maxima.usage + x.maxima.opt).to_i <=> (y.maxima.usage + y.maxima.opt).to_i
|
78
|
+
end
|
79
|
+
|
80
|
+
max_left = max_left_item.maxima.usage + max_left_item.maxima.opt
|
81
|
+
|
82
|
+
unless klasses.empty?
|
83
|
+
puts # add some spacing
|
84
|
+
klasses.each { |k| display_tasks(k, max_base, max_left); }
|
85
|
+
else
|
86
|
+
puts "\033[1;34mNo Thor tasks available\033[0m"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def display_tasks(klass, max_base, max_left)
|
91
|
+
if klass.tasks.values.length > 1
|
92
|
+
|
93
|
+
base = Thor::Util.constant_to_thor_path(klass.name)
|
94
|
+
|
95
|
+
if base.to_a.empty?
|
96
|
+
base = 'default'
|
97
|
+
puts "\033[1;35m#{base}\033[0m"
|
98
|
+
else
|
99
|
+
puts "\033[1;34m#{base}\033[0m"
|
100
|
+
end
|
101
|
+
|
102
|
+
puts "-" * base.length
|
103
|
+
|
104
|
+
klass.tasks.each true do |name, task|
|
105
|
+
format_string = "%-#{max_left + max_base + 5}s"
|
106
|
+
print format_string % task.formatted_usage(true)
|
107
|
+
puts task.description
|
108
|
+
end
|
109
|
+
|
110
|
+
unless klass.opts.empty?
|
111
|
+
puts "\nglobal options: #{Options.new(klass.opts)}"
|
112
|
+
end
|
113
|
+
|
114
|
+
puts # add some spacing
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Capricorn.runtime_gem('thor', Capricorn::THOR_VERSION)
|
2
|
+
|
3
|
+
module Capricorn
|
4
|
+
module Apps # :nodoc:
|
5
|
+
|
6
|
+
class Dev < Thor
|
7
|
+
desc "activate DOMAIN", "turn an existing satelite into a development satelite"
|
8
|
+
def activate(domain)
|
9
|
+
Capricorn.runtime_gem('rubigen', Capricorn::RUBIGEN_VERSION)
|
10
|
+
Capricorn.client.make_development_satellite(domain)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
Capricorn.runtime_gem('thor', Capricorn::THOR_VERSION)
|
2
|
+
|
3
|
+
module Capricorn
|
4
|
+
module Apps # :nodoc:
|
5
|
+
|
6
|
+
class Engines < Thor
|
7
|
+
desc 'install DOMAIN NAME', 'install an engine'
|
8
|
+
method_options :version => :required, :lib => :optional, :source => :optional, :token => :optional
|
9
|
+
def install(domain, name)
|
10
|
+
desc = { :version => options[:version] }
|
11
|
+
desc[:lib] = options[:lib] if options[:lib]
|
12
|
+
desc[:source] = options[:source] if options[:source]
|
13
|
+
Capricorn.client(options[:token]).install_engine(domain, name, desc)
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'update DOMAIN NAME', 'update an engine'
|
17
|
+
method_options :version => :required, :lib => :optional, :source => :optional, :token => :optional
|
18
|
+
def update(domain, name)
|
19
|
+
desc = { :version => options[:version] }
|
20
|
+
desc[:lib] = options[:lib] if options[:lib]
|
21
|
+
desc[:source] = options[:source] if options[:source]
|
22
|
+
Capricorn.client(options[:token]).update_engine(domain, name, desc)
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'uninstall DOMAIN NAME', 'uninstall an engine'
|
26
|
+
method_options :token => :optional
|
27
|
+
def uninstall(domain, name)
|
28
|
+
Capricorn.client(options[:token]).uninstall_engine(domain, name)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|