auser-poolparty 0.2.68 → 0.2.69
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/Manifest.txt +3 -0
- data/PostInstall.txt +1 -1
- data/README.txt +3 -0
- data/Rakefile +3 -3
- data/bin/cloud-configure +4 -2
- data/bin/cloud-start +4 -3
- data/lib/poolparty.rb +5 -3
- data/lib/poolparty/helpers/binary.rb +3 -1
- data/lib/poolparty/helpers/optioner.rb +27 -18
- data/lib/poolparty/helpers/provisioner_base.rb +13 -4
- data/lib/poolparty/helpers/provisioners/master.rb +2 -2
- data/lib/poolparty/modules/cloud_resourcer.rb +1 -1
- data/lib/poolparty/modules/file_writer.rb +2 -2
- data/lib/poolparty/monitors/base_monitor.rb +29 -1
- data/lib/poolparty/net/messenger.rb +5 -2
- data/lib/poolparty/net/remote_bases/ec2.rb +17 -7
- data/lib/poolparty/net/remoter.rb +7 -3
- data/lib/poolparty/net/remoter_base.rb +18 -0
- data/lib/poolparty/plugins/deploydirectory.rb +7 -1
- data/lib/poolparty/plugins/git.rb +47 -0
- data/lib/poolparty/pool/base.rb +1 -0
- data/lib/poolparty/pool/cloud.rb +1 -1
- data/lib/poolparty/pool/pool.rb +1 -2
- data/lib/poolparty/pool/resource.rb +7 -3
- data/lib/poolparty/pool/resources/directory.rb +4 -1
- data/lib/poolparty/pool/resources/exec.rb +2 -5
- data/lib/poolparty/pool/resources/file.rb +1 -1
- data/lib/poolparty/pool/resources/package.rb +1 -1
- data/lib/poolparty/version.rb +1 -1
- data/lib/poolpartyspec.rb +0 -0
- data/poolparty.gemspec +4 -4
- data/spec/poolparty/helpers/optioner_spec.rb +3 -4
- data/spec/poolparty/modules/configurable_spec.rb +2 -2
- data/spec/poolparty/net/remote_bases/ec2_spec.rb +4 -2
- data/spec/poolparty/net/remoter_spec.rb +1 -0
- data/spec/poolparty/plugins/git_spec.rb +45 -0
- data/spec/poolparty/pool/plugin_spec.rb +1 -1
- data/spec/poolparty/pool/resource_spec.rb +2 -2
- data/spec/poolparty/spec_helper.rb +1 -1
- data/tasks/deployment.rake +3 -5
- data/website/index.html +1 -1
- metadata +337 -3
data/Manifest.txt
CHANGED
@@ -273,6 +273,7 @@ lib/poolparty/net/remote_instance.rb
|
|
273
273
|
lib/poolparty/net/remoter.rb
|
274
274
|
lib/poolparty/net/remoter_base.rb
|
275
275
|
lib/poolparty/plugins/deploydirectory.rb
|
276
|
+
lib/poolparty/plugins/git.rb
|
276
277
|
lib/poolparty/plugins/line.rb
|
277
278
|
lib/poolparty/plugins/rsyncmirror.rb
|
278
279
|
lib/poolparty/plugins/runit.rb
|
@@ -323,6 +324,7 @@ lib/poolparty/templates/puppetrunner
|
|
323
324
|
lib/poolparty/templates/yaws.conf
|
324
325
|
lib/poolparty/version.rb
|
325
326
|
lib/poolpartycl.rb
|
327
|
+
lib/poolpartyspec.rb
|
326
328
|
log/pool.logs
|
327
329
|
poolparty.gemspec
|
328
330
|
script/destroy
|
@@ -363,6 +365,7 @@ spec/poolparty/net/remote_spec.rb
|
|
363
365
|
spec/poolparty/net/remoter_base_spec.rb
|
364
366
|
spec/poolparty/net/remoter_spec.rb
|
365
367
|
spec/poolparty/plugins/deploydirectory_spec.rb
|
368
|
+
spec/poolparty/plugins/git_spec.rb
|
366
369
|
spec/poolparty/plugins/line_spec.rb
|
367
370
|
spec/poolparty/plugins/svn_spec.rb
|
368
371
|
spec/poolparty/pool/base_spec.rb
|
data/PostInstall.txt
CHANGED
data/README.txt
CHANGED
@@ -40,6 +40,9 @@ sudo gem install auser-poolparty
|
|
40
40
|
|
41
41
|
== TODO:
|
42
42
|
* Rewrite the disallowed_options to whitelist allowed_options on resources
|
43
|
+
* Add pingback for nodes to master when failure occurs
|
44
|
+
* Add become master for the nodes
|
45
|
+
* Add soft-stop to haproxy while reconfiguring
|
43
46
|
* Replace services with Runit
|
44
47
|
* Refactor provisioning to use erlang
|
45
48
|
* Add queuing of tasks on the messenger
|
data/Rakefile
CHANGED
@@ -23,12 +23,12 @@ task :build_local_gem => [:clean_tmp, :spec, :clean_pkg, :"manifest:refresh", :p
|
|
23
23
|
desc "Packge with timestamp"
|
24
24
|
task :update_timestamp do
|
25
25
|
data = open("PostInstall.txt").read
|
26
|
-
str = "Updated at #{Time.now.strftime("%D")}"
|
26
|
+
str = "Updated at #{Time.now.strftime("%H:%M %D")}"
|
27
27
|
|
28
28
|
if data.scan(/Updated at/).empty?
|
29
|
-
data = data
|
29
|
+
data = data ^ {:updated_at => str}
|
30
30
|
else
|
31
|
-
data = data
|
31
|
+
data = data.gsub(/just installed PoolParty\!(.*)$/, "just installed PoolParty! (#{str})")
|
32
32
|
end
|
33
33
|
::File.open("PostInstall.txt", "w+") {|f| f << data }
|
34
34
|
end
|
data/bin/cloud-configure
CHANGED
@@ -4,7 +4,8 @@ require "poolparty"
|
|
4
4
|
require "poolpartycl"
|
5
5
|
|
6
6
|
o = PoolParty::Optioner.new(ARGV) do |opts, optioner|
|
7
|
-
|
7
|
+
optioner.cloudnames
|
8
|
+
# optioner.daemonizeable
|
8
9
|
end
|
9
10
|
|
10
11
|
o.loaded_clouds.each do |cloud|
|
@@ -13,7 +14,8 @@ o.loaded_clouds.each do |cloud|
|
|
13
14
|
|
14
15
|
# hide_output do
|
15
16
|
# if provision_class == "master" || provision_class == "all"
|
16
|
-
|
17
|
+
@cl = self
|
18
|
+
daemon ? daemonize {Provisioner.configure_master(@cl, testing)} : Provisioner.configure_master(self, testing)
|
17
19
|
# end
|
18
20
|
# if provision_class == "slave" || provision_class == "all"
|
19
21
|
# Provisioner.configure_slaves(self, testing)
|
data/bin/cloud-start
CHANGED
@@ -4,8 +4,8 @@ require "poolparty"
|
|
4
4
|
require "poolpartycl"
|
5
5
|
|
6
6
|
o = PoolParty::Optioner.new(ARGV) do |opts, optioner|
|
7
|
-
|
8
|
-
|
7
|
+
optioner.cloudnames
|
8
|
+
optioner.daemonizeable
|
9
9
|
end
|
10
10
|
|
11
11
|
o.loaded_clouds.each do |cloud|
|
@@ -18,7 +18,8 @@ o.loaded_clouds.each do |cloud|
|
|
18
18
|
# puts("\tNot launching while in testing mode")
|
19
19
|
# else
|
20
20
|
vputs "Launching and configuring the master"
|
21
|
-
|
21
|
+
@cl = self
|
22
|
+
daemon ? daemonize {@cl.launch_and_configure_master!} : launch_and_configure_master!
|
22
23
|
# end
|
23
24
|
# end
|
24
25
|
when_no_pending_instances do
|
data/lib/poolparty.rb
CHANGED
@@ -81,8 +81,10 @@ class Class
|
|
81
81
|
end
|
82
82
|
|
83
83
|
## Load PoolParty Plugins and package
|
84
|
-
|
85
|
-
|
86
|
-
|
84
|
+
module PoolParty
|
85
|
+
%w(plugins base_packages).each do |dir|
|
86
|
+
Dir[::File.dirname(__FILE__) + "/poolparty/#{dir}/*.rb"].each do |file|
|
87
|
+
require file
|
88
|
+
end
|
87
89
|
end
|
88
90
|
end
|
@@ -47,7 +47,7 @@ module PoolParty
|
|
47
47
|
def daemonize(&block)
|
48
48
|
vputs "Daemonizing..."
|
49
49
|
trap("CHLD") {Process.wait(-1, Process::WNOHANG)}
|
50
|
-
fork do
|
50
|
+
pid = fork do
|
51
51
|
Signal.trap('HUP', 'IGNORE') # Don't die upon logout
|
52
52
|
File.open("/dev/null", "r+") do |devnull|
|
53
53
|
$stdout.reopen(devnull)
|
@@ -56,6 +56,8 @@ module PoolParty
|
|
56
56
|
end
|
57
57
|
block.call if block
|
58
58
|
end
|
59
|
+
Process.detach(pid)
|
60
|
+
pid
|
59
61
|
end
|
60
62
|
|
61
63
|
end
|
@@ -11,17 +11,25 @@ module PoolParty
|
|
11
11
|
include MethodMissingSugar
|
12
12
|
|
13
13
|
def initialize(args=[], opts={}, &block)
|
14
|
-
@arguments = parse_args(args)
|
15
|
-
@parse_options = opts[:parse_options] ? opts[:parse_options] : true
|
14
|
+
@arguments = parse_args(args)
|
16
15
|
@extra_help = opts.has_key?(:extra_help) ? opts[:extra_help] : ""
|
17
|
-
@abstract = opts
|
18
|
-
@
|
16
|
+
@abstract = opts.has_key?(:abstract) ? opts[:abstract] : false
|
17
|
+
@load_pools = opts.has_key?(:load_pools) ? opts[:load_pools] : !@abstract
|
18
|
+
@parse_options = opts.has_key?(:parse_options) ? opts[:parse_options] : true
|
19
|
+
@command = opts.has_key?(:command) ? opts[:command] : false
|
19
20
|
|
20
21
|
parse_options(&block) if @parse_options
|
21
22
|
set_default_options
|
22
23
|
self
|
23
24
|
end
|
24
25
|
|
26
|
+
def daemonizeable
|
27
|
+
@opts.on('-d', '--daemonize', 'Daemonize starting the cloud') { self.daemon true }
|
28
|
+
end
|
29
|
+
def cloudnames
|
30
|
+
@opts.on('-n cloudname', '--name name', 'Start cloud by this name') { |c| self.cloudname c }
|
31
|
+
end
|
32
|
+
|
25
33
|
def parse_args(argv, safe=[])
|
26
34
|
argv
|
27
35
|
end
|
@@ -37,33 +45,34 @@ module PoolParty
|
|
37
45
|
|
38
46
|
def parse_options(&blk)
|
39
47
|
progname = $0.include?("-") ? "#{::File.basename($0[/(\w+)-/, 1])} #{::File.basename($0[/-(.*)/, 1])}" : ::File.basename($0)
|
40
|
-
opts = OptionParser.new
|
41
|
-
opts.banner = "Usage: #{progname} #{@abstract ? "[command] " : ""}[options]"
|
48
|
+
@opts = OptionParser.new
|
49
|
+
@opts.banner = "Usage: #{progname} #{@abstract ? "[command] " : ""}[options]"
|
42
50
|
|
43
|
-
opts.separator ""
|
51
|
+
@opts.separator ""
|
44
52
|
|
45
53
|
unless @abstract
|
46
|
-
opts.separator "Options:"
|
54
|
+
@opts.separator "Options:"
|
47
55
|
|
48
|
-
opts.on('-v', '--verbose', 'Be verbose') { self.verbose true }
|
49
|
-
opts.on('-s [file]', '--spec-file [file]', 'Set the spec file') { |file| self.spec file.chomp }
|
50
|
-
opts.on('-t', '--test', 'Testing mode') { self.testing true }
|
51
|
-
|
52
|
-
blk.call(opts, self) if blk
|
56
|
+
@opts.on('-v', '--verbose', 'Be verbose') { self.verbose true }
|
57
|
+
@opts.on('-s [file]', '--spec-file [file]', 'Set the spec file') { |file| self.spec file.chomp }
|
58
|
+
@opts.on('-t', '--test', 'Testing mode') { self.testing true }
|
59
|
+
|
60
|
+
blk.call(@opts, self) if blk
|
53
61
|
end
|
54
62
|
|
55
|
-
opts.on('-V', '--version', 'Display the version') { puts @version ; exit 0 }
|
56
|
-
opts.on_tail("-h", "--help", "Show this message") do
|
57
|
-
puts opts
|
63
|
+
@opts.on('-V', '--version', 'Display the version') { puts @version ; exit 0 }
|
64
|
+
@opts.on_tail("-h", "--help", "Show this message") do
|
65
|
+
puts @opts
|
58
66
|
puts @extra_help
|
59
67
|
exit
|
60
68
|
end
|
61
69
|
|
62
|
-
opts.parse(@arguments.dup)
|
70
|
+
@opts.parse(@arguments.dup)
|
63
71
|
|
64
72
|
process_options
|
65
73
|
output_options if verbose
|
66
|
-
|
74
|
+
|
75
|
+
if @load_pools
|
67
76
|
self.loaded_pool load_pool(self.spec || Binary.get_existing_spec_location)
|
68
77
|
|
69
78
|
self.loaded_clouds extract_cloud_from_options(self)
|
@@ -211,9 +211,10 @@ module PoolParty
|
|
211
211
|
[
|
212
212
|
"#!/usr/bin/env sh",
|
213
213
|
upgrade_system,
|
214
|
-
|
214
|
+
install_rubygems,
|
215
215
|
make_logger_directory,
|
216
216
|
install_puppet,
|
217
|
+
fix_rubygems,
|
217
218
|
custom_install_tasks
|
218
219
|
] << install_tasks
|
219
220
|
end
|
@@ -281,11 +282,19 @@ module PoolParty
|
|
281
282
|
File.join(File.dirname(__FILE__), "..", "templates")
|
282
283
|
end
|
283
284
|
|
284
|
-
def
|
285
|
+
def install_rubygems
|
286
|
+
<<-EOE
|
287
|
+
#{installer_for("ruby rubygems")}
|
288
|
+
EOE
|
289
|
+
end
|
290
|
+
|
291
|
+
def fix_rubygems
|
285
292
|
<<-EOE
|
286
|
-
#{installer_for("ruby rubygems")}
|
287
|
-
gem update --system # Force rubygems update
|
288
293
|
echo '#{open(::File.join(template_directory, "gem")).read}' > /usr/bin/gem
|
294
|
+
echo 'Updating rubygems'
|
295
|
+
PAT=`/usr/bin/gem env gemdir`
|
296
|
+
/usr/bin/gem update --system #{unix_hide_string}
|
297
|
+
/usr/bin/gem update --system #{unix_hide_string}
|
289
298
|
EOE
|
290
299
|
end
|
291
300
|
|
@@ -122,7 +122,7 @@ wget http://github.com/auser/poolparty/tree/master%2Fpkg%2Fpoolparty.gem?raw=tru
|
|
122
122
|
#{
|
123
123
|
%w(rake lockfile rubyforge hoe ZenTest sexp_processor flexmock logging activesupport
|
124
124
|
RubyInline ParseTree ruby2ruby xml-simple poolparty).map do |dep|
|
125
|
-
"gem install --ignore-dependencies -y --no-ri --no-rdoc #{dep}.gem #{unix_hide_string}"
|
125
|
+
"/usr/bin/gem install --ignore-dependencies -y --no-ri --no-rdoc #{dep}.gem #{unix_hide_string}"
|
126
126
|
end.join("\n")
|
127
127
|
}
|
128
128
|
EOE
|
@@ -186,7 +186,7 @@ cp #{Base.remote_storage_path}/poolparty.pp /etc/puppet/manifests/classes/poolpa
|
|
186
186
|
s << "puppetca --clean master.compute-1.internal 2>&1 > /dev/null"
|
187
187
|
s << "puppetca --clean master.ec2.internal 2>&1 > /dev/null"
|
188
188
|
end.join(";")
|
189
|
-
"if [ -f '/usr/bin/
|
189
|
+
"if [ -f '/usr/bin/puppetrerun' ]; then /usr/bin/puppetrerun; else #{str}; fi"
|
190
190
|
end
|
191
191
|
|
192
192
|
def restart_puppetd
|
@@ -6,7 +6,7 @@ module PoolParty
|
|
6
6
|
FileUtils.cp file, path unless file == path || ::File.exists?(path)
|
7
7
|
end
|
8
8
|
def cleanup_storage_directory
|
9
|
-
Dir["#{Base.storage_directory}
|
9
|
+
Dir["#{Base.storage_directory}/**/*"].each do |f|
|
10
10
|
::FileUtils.rm f if ::File.file?(f)
|
11
11
|
end
|
12
12
|
end
|
@@ -79,7 +79,7 @@ module PoolParty
|
|
79
79
|
path
|
80
80
|
end
|
81
81
|
def clear_base_directory
|
82
|
-
Dir["#{Base.storage_directory}
|
82
|
+
Dir["#{Base.storage_directory}/**/*"].each do |f|
|
83
83
|
::FileUtils.rm f if ::File.file?(f)
|
84
84
|
end
|
85
85
|
end
|
@@ -1,7 +1,33 @@
|
|
1
1
|
=begin rdoc
|
2
2
|
Monitor class
|
3
3
|
|
4
|
-
|
4
|
+
Monitors are the basis for PoolParty scaling. Your cloud will expand and
|
5
|
+
contract against these monitors. You can set your cloud to be monitored by these
|
6
|
+
monitors simply by using them in the contract_when and the expand_when macros
|
7
|
+
on your cloud like so:
|
8
|
+
|
9
|
+
expand_when "cpu > 1.2", "memory > 0.94"
|
10
|
+
contract_when "cpu < 0.4", "memory < 0.3"
|
11
|
+
|
12
|
+
You can also add your own monitors simply by creating a directory in the same
|
13
|
+
directory as the pool spec (the same directory as the plugin directory exists) and
|
14
|
+
placing your monitor file (format: [monitorname]_monitor.rb) there.
|
15
|
+
|
16
|
+
Monitors are simply classes of the name of the monitor. They subclass the BaseMonitor
|
17
|
+
class from PoolParty. A sample monitor would look similar to:
|
18
|
+
|
19
|
+
class SampleMonitor < PoolParty::Monitors::BaseMonitor
|
20
|
+
def run
|
21
|
+
end
|
22
|
+
end
|
23
|
+
register_monitor :sample
|
24
|
+
|
25
|
+
The monitor class must have an instance level method called run. This method is called when
|
26
|
+
the cloud is checking the monitor. The output of this method should be the output of
|
27
|
+
the monitor.
|
28
|
+
|
29
|
+
Notice that at the end, you must call register_monitor :monitorname. This will tell your cloud
|
30
|
+
that it can monitor it with this monitor.
|
5
31
|
=end
|
6
32
|
require "#{::File.dirname(__FILE__)}/../pool/base"
|
7
33
|
|
@@ -49,7 +75,9 @@ module PoolParty
|
|
49
75
|
end
|
50
76
|
end
|
51
77
|
|
78
|
+
# Require included monitors
|
52
79
|
Dir["#{File.dirname(__FILE__)}/monitors/*.rb"].each {|f| require f}
|
80
|
+
# Require custom monitors
|
53
81
|
Dir["#{PoolParty::Base.custom_monitor_directories}/*.rb"].each {|f| require f}
|
54
82
|
|
55
83
|
module PoolParty
|
@@ -1,12 +1,15 @@
|
|
1
1
|
=begin rdoc
|
2
|
-
The connection to the messenger from poolparty, the client
|
2
|
+
The connection to the messenger from poolparty, the client.
|
3
|
+
|
4
|
+
This class will setup a socket connection to the master's client
|
5
|
+
at the messenger_client_port
|
3
6
|
=end
|
4
7
|
module PoolParty
|
5
8
|
module Messenger
|
6
9
|
def with_socket(testing=false, &block)
|
7
10
|
host = testing ? "localhost" : (master.ip)
|
8
11
|
vputs "Pinging #{host} with the messenger"
|
9
|
-
socket = TCPSocket.open(host,
|
12
|
+
socket = TCPSocket.open(host, Base.messenger_client_port)
|
10
13
|
out = yield(socket)
|
11
14
|
socket.close
|
12
15
|
out
|
@@ -1,3 +1,9 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
EC2 Remoter Base
|
3
|
+
|
4
|
+
This serves as the basis for running PoolParty on Amazon's ec2 cloud
|
5
|
+
cluster.
|
6
|
+
=end
|
1
7
|
require "date"
|
2
8
|
require "#{::File.dirname(__FILE__)}/ec2/ec2_response_object"
|
3
9
|
|
@@ -65,18 +71,21 @@ begin
|
|
65
71
|
EC2ResponseObject.get_descriptions(ec2.describe_instances)
|
66
72
|
end
|
67
73
|
|
68
|
-
def after_launch_master(
|
74
|
+
def after_launch_master(inst=nil)
|
75
|
+
instance = master
|
76
|
+
vputs "Running tasks after launching the master"
|
69
77
|
begin
|
70
|
-
when_no_pending_instances do
|
78
|
+
# when_no_pending_instances do
|
71
79
|
if instance
|
72
|
-
ec2.associate_address(:instance_id => instance.
|
73
|
-
ec2.attach_volume(:volume_id => ebs_volume_id, :instance_id => instance.
|
80
|
+
ec2.associate_address(:instance_id => instance.instance_id, :public_ip => set_master_ip_to) if set_master_ip_to
|
81
|
+
ec2.attach_volume(:volume_id => ebs_volume_id, :instance_id => instance.instance_id, :device => ebs_volume_device) if ebs_volume_id && ebs_volume_mount_point
|
74
82
|
end
|
75
|
-
end
|
83
|
+
# end
|
76
84
|
rescue Exception => e
|
85
|
+
vputs "Error in after_launch_master: #{e}"
|
77
86
|
end
|
78
87
|
reset_remoter_base!
|
79
|
-
when_all_assigned_ips {wait "
|
88
|
+
when_all_assigned_ips {wait "5.seconds"}
|
80
89
|
end
|
81
90
|
|
82
91
|
# Help create a keypair for the cloud
|
@@ -112,7 +121,8 @@ begin
|
|
112
121
|
"if [ -z \"$(grep -v '#' /etc/hosts | grep '#{o.name}')\" ]; then echo '127.0.0.1 #{o.name}' >> /etc/hosts; fi",
|
113
122
|
"hostname #{o.name}",
|
114
123
|
"echo #{o.name} > /etc/hostname",
|
115
|
-
"cd /var/poolparty && wget http://rubyforge.org/frs/download.php/43666/amazon-ec2-0.3.1.gem -O amazon-ec2.gem 2>&1
|
124
|
+
"cd /var/poolparty && wget http://rubyforge.org/frs/download.php/43666/amazon-ec2-0.3.1.gem -O amazon-ec2.gem 2>&1",
|
125
|
+
"/usr/bin/gem install -y --no-ri --no-rdoc amazon-ec2.gem 2>&1"
|
116
126
|
]
|
117
127
|
end
|
118
128
|
|
@@ -82,11 +82,15 @@ module PoolParty
|
|
82
82
|
out
|
83
83
|
end
|
84
84
|
def request_launch_master_instance
|
85
|
-
inst = launch_new_instance!
|
85
|
+
@inst = launch_new_instance!
|
86
86
|
wait "5.seconds"
|
87
|
-
when_no_pending_instances
|
87
|
+
when_no_pending_instances do
|
88
|
+
vputs "Master has launched"
|
89
|
+
reset!
|
90
|
+
after_launch_master(@inst)
|
91
|
+
end
|
88
92
|
end
|
89
|
-
def after_launch_master(
|
93
|
+
def after_launch_master(inst=nil)
|
90
94
|
vputs "After launch master in remoter"
|
91
95
|
end
|
92
96
|
# Let's terminate an instance that is not the master instance
|
@@ -1,3 +1,21 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
The base for Remote Bases
|
3
|
+
|
4
|
+
By extending this class, you can easily add remoters to
|
5
|
+
PoolParty. There are 4 methods that the remote base needs to implement
|
6
|
+
in order to be compatible.
|
7
|
+
|
8
|
+
The four methods are:
|
9
|
+
launch_new_instance!
|
10
|
+
terminate_instance(id)
|
11
|
+
describe_instance(id)
|
12
|
+
describe_instances
|
13
|
+
|
14
|
+
After your remote base is written, make sure to register the base outside the context
|
15
|
+
of the remote base, like so:
|
16
|
+
register_remote_base :remote_base_name
|
17
|
+
|
18
|
+
=end
|
1
19
|
module PoolParty
|
2
20
|
|
3
21
|
def register_remote_base(*args)
|