deltacloud-client 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +11 -7
- data/bin/deltacloudc +9 -6
- data/lib/deltacloud.rb +412 -322
- data/lib/documentation.rb +97 -0
- data/lib/plain_formatter.rb +86 -0
- data/specs/instances_spec.rb +14 -14
- data/specs/realms_spec.rb +0 -2
- data/specs/spec_helper.rb +2 -5
- data/specs/storage_volume_spec.rb +2 -2
- metadata +20 -18
- data/credentials.yml +0 -2
- data/lib/dcloud/base_model.rb +0 -80
- data/lib/dcloud/hardware_profile.rb +0 -124
- data/lib/dcloud/image.rb +0 -56
- data/lib/dcloud/instance.rb +0 -142
- data/lib/dcloud/realm.rb +0 -57
- data/lib/dcloud/state.rb +0 -30
- data/lib/dcloud/storage_snapshot.rb +0 -59
- data/lib/dcloud/storage_volume.rb +0 -63
- data/lib/dcloud/transition.rb +0 -35
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'lib/deltacloud'
|
2
|
+
|
3
|
+
skip_methods = [ "id=", "uri=" ]
|
4
|
+
|
5
|
+
begin
|
6
|
+
@dc=DeltaCloud.new('mockuser', 'mockpassword', 'http://localhost:3001/api')
|
7
|
+
rescue
|
8
|
+
puts "Please make sure that Deltacloud API is running with Mock driver"
|
9
|
+
exit(1)
|
10
|
+
end
|
11
|
+
|
12
|
+
@dc.entry_points.keys.each do |ep|
|
13
|
+
@dc.send(ep)
|
14
|
+
end
|
15
|
+
class_list = @dc.classes
|
16
|
+
|
17
|
+
def read_method_description(c, method)
|
18
|
+
if method =~ /es$/
|
19
|
+
" # Read #{c.downcase} collection from Deltacloud API"
|
20
|
+
else
|
21
|
+
case method
|
22
|
+
when "uri"
|
23
|
+
" # Return URI to API for this object"
|
24
|
+
when "action_urls"
|
25
|
+
" # Return available actions API URL"
|
26
|
+
when "client"
|
27
|
+
" # Return instance of API client"
|
28
|
+
else
|
29
|
+
" # Get #{method} attribute value from #{c.downcase}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def read_parameters(c, method)
|
35
|
+
out = []
|
36
|
+
if method =~ /es$/
|
37
|
+
out << " # @param [String, #id] Filter by ID"
|
38
|
+
end
|
39
|
+
out.join("\n")
|
40
|
+
end
|
41
|
+
|
42
|
+
def read_return_value(c, method)
|
43
|
+
if method =~ /es$/
|
44
|
+
rt = "Array"
|
45
|
+
else
|
46
|
+
rt = "String"
|
47
|
+
end
|
48
|
+
" # @return [String] Value of #{method}"
|
49
|
+
end
|
50
|
+
|
51
|
+
out = []
|
52
|
+
|
53
|
+
class_list.each do |c|
|
54
|
+
class_name = "#{c}".gsub(/^DeltaCloud::/, '')
|
55
|
+
out << "module DeltaCloud"
|
56
|
+
out << " class API"
|
57
|
+
@dc.entry_points.keys.each do |ep|
|
58
|
+
out << "# Return #{ep.to_s.classify} object with given id\n"
|
59
|
+
out << "# "
|
60
|
+
out << "# *#{@dc.documentation(ep.to_s).description}*"
|
61
|
+
out << "# @return [#{ep.to_s.classify}]"
|
62
|
+
out << "def #{ep.to_s.gsub(/s$/, '')}"
|
63
|
+
out << "end"
|
64
|
+
out << "# Return collection of #{ep.to_s.classify} objects"
|
65
|
+
out << "# "
|
66
|
+
out << "# *#{@dc.documentation(ep.to_s).description}*"
|
67
|
+
@dc.documentation(ep.to_s, 'index').params.each do |p|
|
68
|
+
out << p.to_comment
|
69
|
+
end
|
70
|
+
out << "# @return [Array] [#{ep.to_s.classify}]"
|
71
|
+
out << "def #{ep}(opts={})"
|
72
|
+
out << "end"
|
73
|
+
end
|
74
|
+
out << " end"
|
75
|
+
out << " class #{class_name}"
|
76
|
+
c.instance_methods(false).each do |method|
|
77
|
+
next if skip_methods.include?(method)
|
78
|
+
params = read_parameters(class_name, method)
|
79
|
+
retval = read_return_value(class_name, method)
|
80
|
+
out << read_method_description(class_name, method)
|
81
|
+
out << params if params
|
82
|
+
out << retval if retval
|
83
|
+
out << " def #{method}"
|
84
|
+
out << " # This method was generated dynamically from API"
|
85
|
+
out << " end\n"
|
86
|
+
end
|
87
|
+
out << " end"
|
88
|
+
out << "end"
|
89
|
+
end
|
90
|
+
|
91
|
+
FileUtils.rm_r('doc') rescue nil
|
92
|
+
FileUtils.mkdir_p('doc')
|
93
|
+
File.open('doc/deltacloud.rb', 'w') do |f|
|
94
|
+
f.puts(out.join("\n"))
|
95
|
+
end
|
96
|
+
system("yardoc -m markdown --readme README --title 'Deltacloud Client Library' 'lib/*.rb' 'doc/deltacloud.rb' --verbose")
|
97
|
+
FileUtils.rm('doc/deltacloud.rb')
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module DeltaCloud
|
2
|
+
module PlainFormatter
|
3
|
+
module FormatObject
|
4
|
+
|
5
|
+
class Base
|
6
|
+
def initialize(obj)
|
7
|
+
@obj = obj
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Image < Base
|
12
|
+
def format
|
13
|
+
sprintf("%-10s | %-20s | %-6s | %-20s | %15s",
|
14
|
+
@obj.id[0,10],
|
15
|
+
@obj.name ? @obj.name[0, 20]: 'unknown',
|
16
|
+
@obj.architecture[0,6],
|
17
|
+
@obj.description[0,20],
|
18
|
+
@obj.owner_id[0,15]
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class Realm < Base
|
24
|
+
def format
|
25
|
+
sprintf("%-10s | %-15s | %-5s | %10s GB",
|
26
|
+
@obj.id[0, 10],
|
27
|
+
@obj.name[0, 15],
|
28
|
+
@obj.state[0,5],
|
29
|
+
@obj.limit.to_s[0,10]
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class HardwareProfile < Base
|
35
|
+
def format
|
36
|
+
sprintf("%-15s | %-6s | %10s | %10s ", @obj.id[0, 15],
|
37
|
+
@obj.architecture.value[0,6], @obj.memory.value.to_s[0,10], @obj.storage.value.to_s[0,10])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class Instance < Base
|
42
|
+
def format
|
43
|
+
sprintf("%-15s | %-15s | %-15s | %10s | %32s | %32s",
|
44
|
+
@obj.id ? @obj.id[0,15] : '-',
|
45
|
+
@obj.name ? @obj.name[0,15] : 'unknown',
|
46
|
+
@obj.image.name ? @obj.image.name[0,15] : 'unknown',
|
47
|
+
@obj.state ? @obj.state.to_s[0,10] : 'unknown',
|
48
|
+
@obj.public_addresses.join(',')[0,32],
|
49
|
+
@obj.private_addresses.join(',')[0,32]
|
50
|
+
)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class StorageVolume < Base
|
55
|
+
def format
|
56
|
+
sprintf("%-10s | %15s GB | %-10s | %-10s | %-15s",
|
57
|
+
@obj.id[0,10],
|
58
|
+
@obj.capacity ? @obj.capacity.to_s[0,15] : 'unknown',
|
59
|
+
@obj.device ? @obj.device[0,10] : 'unknown',
|
60
|
+
@obj.respond_to?('state') ? @obj.state[0,10] : 'unknown',
|
61
|
+
@obj.instance ? @obj.instance.name[0,15] : 'unknown'
|
62
|
+
)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class StorageSnapshot < Base
|
67
|
+
def format
|
68
|
+
sprintf("%-10s | %-15s | %-6s | %15s",
|
69
|
+
@obj.id[0,10],
|
70
|
+
@obj.storage_volume.respond_to?('name') ? @obj.storage_volume.name[0, 15] : 'unknown',
|
71
|
+
@obj.state ? @obj.state[0,10] : 'unknown',
|
72
|
+
@obj.created ? @obj.created[0,19] : 'unknown'
|
73
|
+
)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
def format(obj)
|
80
|
+
object_name = obj.class.name.classify.gsub(/^DeltaCloud::/, '')
|
81
|
+
format_class = DeltaCloud::PlainFormatter::FormatObject.const_get(object_name)
|
82
|
+
format_class.new(obj).format
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
data/specs/instances_spec.rb
CHANGED
@@ -32,9 +32,9 @@ describe "instances" do
|
|
32
32
|
instance.owner_id.should_not be_nil
|
33
33
|
instance.owner_id.should be_a( String )
|
34
34
|
instance.image.should_not be_nil
|
35
|
-
instance.image.should be_a(
|
36
|
-
instance.
|
37
|
-
instance.
|
35
|
+
instance.image.should be_a( DeltaCloud::Image )
|
36
|
+
instance.hardware_profile.should_not be_nil
|
37
|
+
instance.hardware_profile.should be_a( DeltaCloud::HardwareProfile )
|
38
38
|
instance.state.should_not be_nil
|
39
39
|
instance.state.should be_a( String )
|
40
40
|
instance.public_addresses.should_not be_nil
|
@@ -70,11 +70,11 @@ describe "instances" do
|
|
70
70
|
instance.public_addresses.first.should eql( "img1.inst0.public.com" )
|
71
71
|
instance.image.should_not be_nil
|
72
72
|
instance.image.uri.should eql( API_URL + "/images/img1" )
|
73
|
-
instance.
|
74
|
-
instance.
|
75
|
-
instance.
|
76
|
-
instance.
|
77
|
-
instance.
|
73
|
+
instance.hardware_profile.should_not be_nil
|
74
|
+
instance.hardware_profile.should_not be_nil
|
75
|
+
instance.hardware_profile.uri.should eql( API_URL + "/hardware_profiles/m1-large" )
|
76
|
+
instance.hardware_profile.memory.value.should eql(10240.0)
|
77
|
+
instance.hardware_profile.storage.value.should eql(850.0)
|
78
78
|
instance.state.should eql( "RUNNING" )
|
79
79
|
instance.actions.should_not be_nil
|
80
80
|
end
|
@@ -88,7 +88,7 @@ describe "instances" do
|
|
88
88
|
instance.id.should match( /inst[0-9]+/ )
|
89
89
|
instance.name.should eql( 'TestInstance' )
|
90
90
|
instance.image.id.should eql( 'img1' )
|
91
|
-
instance.
|
91
|
+
instance.hardware_profile.id.should eql( 'm1-large' )
|
92
92
|
instance.realm.id.should eql( 'us' )
|
93
93
|
end
|
94
94
|
end
|
@@ -100,7 +100,7 @@ describe "instances" do
|
|
100
100
|
instance.uri.should match( %r{#{API_URL}/instances/inst[0-9]+} )
|
101
101
|
instance.id.should match( /inst[0-9]+/ )
|
102
102
|
instance.image.id.should eql( 'img1' )
|
103
|
-
instance.
|
103
|
+
instance.hardware_profile.id.should eql( 'm1-large' )
|
104
104
|
instance.realm.id.should eql( 'eu' )
|
105
105
|
end
|
106
106
|
end
|
@@ -113,7 +113,7 @@ describe "instances" do
|
|
113
113
|
instance.uri.should match( %r{#{API_URL}/instances/inst[0-9]+} )
|
114
114
|
instance.id.should match( /inst[0-9]+/ )
|
115
115
|
instance.image.id.should eql( 'img1' )
|
116
|
-
instance.
|
116
|
+
instance.hardware_profile.id.should eql( 'm1-xlarge' )
|
117
117
|
instance.realm.id.should eql( 'us' )
|
118
118
|
end
|
119
119
|
end
|
@@ -126,8 +126,8 @@ describe "instances" do
|
|
126
126
|
instance.uri.should match( %r{#{API_URL}/instances/inst[0-9]+} )
|
127
127
|
instance.id.should match( /inst[0-9]+/ )
|
128
128
|
instance.image.id.should eql( 'img1' )
|
129
|
-
instance.
|
130
|
-
instance.
|
129
|
+
instance.hardware_profile.id.should eql( 'm1-xlarge' )
|
130
|
+
instance.hardware_profile.memory.value.should eql(12288.0)
|
131
131
|
instance.realm.id.should eql( 'us' )
|
132
132
|
end
|
133
133
|
end
|
@@ -140,7 +140,7 @@ describe "instances" do
|
|
140
140
|
instance.uri.should match( %r{#{API_URL}/instances/inst[0-9]+} )
|
141
141
|
instance.id.should match( /inst[0-9]+/ )
|
142
142
|
instance.image.id.should eql( 'img1' )
|
143
|
-
instance.
|
143
|
+
instance.hardware_profile.id.should eql( 'm1-xlarge' )
|
144
144
|
instance.realm.id.should eql( 'eu' )
|
145
145
|
end
|
146
146
|
end
|
data/specs/realms_spec.rb
CHANGED
@@ -44,13 +44,11 @@ describe "realms" do
|
|
44
44
|
realm.id.should eql( 'us' )
|
45
45
|
realm.name.should eql( 'United States' )
|
46
46
|
realm.state.should eql( 'AVAILABLE' )
|
47
|
-
realm.limit.should eql( :unlimited )
|
48
47
|
realm = client.realm( 'eu' )
|
49
48
|
realm.should_not be_nil
|
50
49
|
realm.id.should eql( 'eu' )
|
51
50
|
realm.name.should eql( 'Europe' )
|
52
51
|
realm.state.should eql( 'AVAILABLE' )
|
53
|
-
realm.limit.should eql( :unlimited )
|
54
52
|
end
|
55
53
|
end
|
56
54
|
|
data/specs/spec_helper.rb
CHANGED
@@ -32,11 +32,8 @@ API_PORT = api_port
|
|
32
32
|
API_PATH = '/api'
|
33
33
|
|
34
34
|
API_URL = "http://#{API_HOST}:#{API_PORT}#{API_PATH}"
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
API_NAME = credentials['name']
|
39
|
-
API_PASSWORD = credentials['password']
|
35
|
+
API_NAME = 'mockuser'
|
36
|
+
API_PASSWORD = 'mockpassword'
|
40
37
|
|
41
38
|
$: << File.dirname( __FILE__ ) + '/../lib'
|
42
39
|
require 'deltacloud'
|
@@ -46,7 +46,7 @@ describe "storage volumes" do
|
|
46
46
|
storage_volume.device.should eql( '/dev/sda1' )
|
47
47
|
storage_volume.instance.should_not be_nil
|
48
48
|
storage_volume.instance.id.should eql( 'inst1' )
|
49
|
-
ip = storage_volume.instance
|
49
|
+
ip = storage_volume.instance
|
50
50
|
ip.hardware_profile.architecture.value.should eql( 'i386' )
|
51
51
|
end
|
52
52
|
end
|
@@ -63,7 +63,7 @@ describe "storage volumes" do
|
|
63
63
|
storage_volume.device.should eql( '/dev/sda1' )
|
64
64
|
storage_volume.instance.should_not be_nil
|
65
65
|
storage_volume.instance.id.should eql( 'inst1' )
|
66
|
-
ip = storage_volume.instance
|
66
|
+
ip = storage_volume.instance
|
67
67
|
ip.hardware_profile.architecture.value.should eql( 'i386' )
|
68
68
|
end
|
69
69
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deltacloud-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Red Hat, Inc.
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-06-
|
12
|
+
date: 2010-06-29 00:00:00 +02:00
|
13
13
|
default_executable: deltacloudc
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,12 +20,22 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 1.
|
23
|
+
version: 1.4.2
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
|
-
name:
|
26
|
+
name: nokogiri
|
27
27
|
type: :runtime
|
28
28
|
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.4.1
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rspec
|
37
|
+
type: :development
|
38
|
+
version_requirement:
|
29
39
|
version_requirements: !ruby/object:Gem::Requirement
|
30
40
|
requirements:
|
31
41
|
- - ">="
|
@@ -42,17 +52,9 @@ extra_rdoc_files:
|
|
42
52
|
- COPYING
|
43
53
|
files:
|
44
54
|
- Rakefile
|
45
|
-
- credentials.yml
|
46
55
|
- lib/deltacloud.rb
|
47
|
-
- lib/
|
48
|
-
- lib/
|
49
|
-
- lib/dcloud/image.rb
|
50
|
-
- lib/dcloud/instance.rb
|
51
|
-
- lib/dcloud/realm.rb
|
52
|
-
- lib/dcloud/state.rb
|
53
|
-
- lib/dcloud/storage_snapshot.rb
|
54
|
-
- lib/dcloud/storage_volume.rb
|
55
|
-
- lib/dcloud/transition.rb
|
56
|
+
- lib/documentation.rb
|
57
|
+
- lib/plain_formatter.rb
|
56
58
|
- init.rb
|
57
59
|
- bin/deltacloudc
|
58
60
|
- COPYING
|
@@ -88,31 +90,31 @@ test_files:
|
|
88
90
|
- specs/fixtures/images/img1.yml
|
89
91
|
- specs/fixtures/images/img2.yml
|
90
92
|
- specs/fixtures/images/img3.yml
|
93
|
+
- specs/fixtures/instances/inst0.yml
|
91
94
|
- specs/fixtures/instances/inst1.yml
|
92
95
|
- specs/fixtures/instances/inst2.yml
|
93
|
-
- specs/fixtures/instances/inst0.yml
|
94
96
|
- specs/fixtures/storage_snapshots/snap1.yml
|
95
97
|
- specs/fixtures/storage_snapshots/snap2.yml
|
96
98
|
- specs/fixtures/storage_snapshots/snap3.yml
|
97
99
|
- specs/fixtures/storage_volumes/vol1.yml
|
98
100
|
- specs/fixtures/storage_volumes/vol2.yml
|
99
101
|
- specs/fixtures/storage_volumes/vol3.yml
|
100
|
-
- specs/
|
102
|
+
- specs/hardware_profiles_spec.rb
|
101
103
|
- specs/images_spec.rb
|
102
104
|
- specs/initialization_spec.rb
|
103
105
|
- specs/instance_states_spec.rb
|
104
106
|
- specs/instances_spec.rb
|
105
107
|
- specs/realms_spec.rb
|
106
108
|
- specs/shared/resources.rb
|
109
|
+
- specs/spec_helper.rb
|
107
110
|
- specs/storage_snapshot_spec.rb
|
108
111
|
- specs/storage_volume_spec.rb
|
109
|
-
- specs/hardware_profiles_spec.rb
|
110
112
|
- specs/data/images/img1.yml
|
111
113
|
- specs/data/images/img2.yml
|
112
114
|
- specs/data/images/img3.yml
|
115
|
+
- specs/data/instances/inst0.yml
|
113
116
|
- specs/data/instances/inst1.yml
|
114
117
|
- specs/data/instances/inst2.yml
|
115
|
-
- specs/data/instances/inst0.yml
|
116
118
|
- specs/data/storage_snapshots/snap1.yml
|
117
119
|
- specs/data/storage_snapshots/snap2.yml
|
118
120
|
- specs/data/storage_snapshots/snap3.yml
|
data/credentials.yml
DELETED
data/lib/dcloud/base_model.rb
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright (C) 2009 Red Hat, Inc.
|
3
|
-
#
|
4
|
-
# This library is free software; you can redistribute it and/or
|
5
|
-
# modify it under the terms of the GNU Lesser General Public
|
6
|
-
# License as published by the Free Software Foundation; either
|
7
|
-
# version 2.1 of the License, or (at your option) any later version.
|
8
|
-
#
|
9
|
-
# This library is distributed in the hope that it will be useful,
|
10
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
12
|
-
# Lesser General Public License for more details.
|
13
|
-
#
|
14
|
-
# You should have received a copy of the GNU Lesser General Public
|
15
|
-
# License along with this library; if not, write to the Free Software
|
16
|
-
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
17
|
-
|
18
|
-
|
19
|
-
module DCloud
|
20
|
-
class BaseModel
|
21
|
-
|
22
|
-
def self.xml_tag_name(name=nil)
|
23
|
-
unless ( name.nil? )
|
24
|
-
@xml_tag_name = name
|
25
|
-
end
|
26
|
-
@xml_tag_name || self.class.name.downcase.to_sym
|
27
|
-
end
|
28
|
-
|
29
|
-
|
30
|
-
def self.attribute(attr)
|
31
|
-
build_reader attr
|
32
|
-
end
|
33
|
-
|
34
|
-
def self.build_reader(attr)
|
35
|
-
eval "
|
36
|
-
def #{attr}
|
37
|
-
check_load_payload
|
38
|
-
@#{attr}
|
39
|
-
end
|
40
|
-
"
|
41
|
-
end
|
42
|
-
|
43
|
-
attr_reader :uri
|
44
|
-
|
45
|
-
def initialize(client, uri=nil, xml=nil)
|
46
|
-
@client = client
|
47
|
-
@uri = uri
|
48
|
-
@loaded = false
|
49
|
-
load_payload( xml )
|
50
|
-
end
|
51
|
-
|
52
|
-
def id()
|
53
|
-
check_load_payload
|
54
|
-
@id
|
55
|
-
end
|
56
|
-
|
57
|
-
|
58
|
-
protected
|
59
|
-
|
60
|
-
attr_reader :client
|
61
|
-
|
62
|
-
def check_load_payload()
|
63
|
-
return if @loaded
|
64
|
-
xml = @client.fetch_resource( self.class.xml_tag_name.to_sym, @uri )
|
65
|
-
load_payload(xml)
|
66
|
-
end
|
67
|
-
|
68
|
-
def load_payload(xml=nil)
|
69
|
-
unless ( xml.nil? )
|
70
|
-
@loaded = true
|
71
|
-
@id = xml.text( 'id' )
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def unload
|
76
|
-
@loaded = false
|
77
|
-
end
|
78
|
-
|
79
|
-
end
|
80
|
-
end
|