elesai 0.9.3 → 0.10.5

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/lib/elesai/lsi.rb CHANGED
@@ -1,6 +1,8 @@
1
+ require 'elesai/megacli'
2
+
1
3
  module Elesai
2
4
 
3
- class LSIArray
5
+ class LSI
4
6
 
5
7
  attr_reader :adapters, :virtualdrives, :physicaldrives, :bbus, :enclosures
6
8
 
@@ -13,54 +15,58 @@ module Elesai
13
15
  @bbus = []
14
16
 
15
17
  case opts[:hint]
16
- when :pd,:physicaldrive
17
- PDlist_aAll.new.parse!(self,opts)
18
- when :vd,:virtualdrive
19
- LDPDinfo_aAll.new.parse!(self,opts)
18
+ when :physicaldrive
19
+ Megacli::PDlist_aAll.new.parse!(self,opts)
20
+ when :virtualdrive
21
+ Megacli::LDPDinfo_aAll.new.parse!(self,opts)
22
+ when :adapter
23
+ Megacli::AdpAllInfo_aAll.new.parse!(self,opts)
20
24
  when :bbu
21
- AdpBbuCmd_aAll.new.parse!(self,opts)
25
+ Megacli::AdpBbuCmd_aAll.new.parse!(self,opts)
22
26
  else
23
- PDlist_aAll.new.parse!(self,opts)
24
- LDPDinfo_aAll.new.parse!(self,opts)
25
- AdpBbuCmd_aAll.new.parse!(self,opts)
27
+ Megacli::AdpAllInfo_aAll.new.parse!(self,opts)
28
+ Megacli::PDlist_aAll.new.parse!(self,opts)
29
+ Megacli::LDPDinfo_aAll.new.parse!(self,opts)
30
+ Megacli::AdpBbuCmd_aAll.new.parse!(self,opts)
26
31
  end
27
32
  end
28
33
 
29
- def add_adapter(a)
30
- @adapters[a[:id]] = a if @adapters[a[:id]].nil?
34
+ def add(component)
35
+ case component
36
+ when Adapter
37
+ @adapters[component[:id]] = component if @adapters[component[:id]].nil?
38
+ when VirtualDrive
39
+ @virtualdrives.push(component)
40
+ when PhysicalDrive
41
+ @physicaldrives[component._id] = component if @physicaldrives[component._id].nil?
42
+ return @physicaldrives[component._id]
43
+ when BBU
44
+ @bbus.push(component)
45
+ else
46
+ raise StandardError, "invalid component #{component.class}"
47
+ end
31
48
  end
32
49
 
33
- def add_virtualdrive(vd)
34
- @virtualdrives.push(vd)
35
- end
36
50
 
37
- def add_physicaldrive(pd)
38
- @physicaldrives[pd._id] = pd if @physicaldrives[pd._id].nil?
39
- @physicaldrives[pd._id]
40
- end
41
51
 
42
- def add_bbu(bbu)
43
- @bbus.push(bbu)
44
- end
45
52
 
46
- def to_s
47
- lsiarrayout = "LSI Array\n"
48
- @adapters.each do |adapter|
49
- lsiarrayout += " adapter #{adapter.id}\n"
50
- adapter.virtualdrives.each do |virtualdrive|
51
- lsiarrayout += " +--+ #{virtualdrive.to_str}\n"
52
- virtualdrive.physicaldrives.each do |id,physicaldrive|
53
- lsiarrayout += " | |-- pd #{physicaldrive.to_str}\n"
54
- end
55
- end
56
- end
57
- lsiarrayout
58
- end
59
53
 
60
- ### Adapter
54
+
55
+
56
+
61
57
 
62
58
  class Adapter < Hash
63
59
 
60
+ class Section < Hash
61
+ attr_reader :section
62
+ def initialize(section)
63
+ @section = section
64
+ end
65
+ def inspect
66
+ "#{self.class}:#@section:#{self.__id__}"
67
+ end
68
+ end
69
+
64
70
  def initialize
65
71
  self[:virtualdrives] = []
66
72
  self[:physicaldrives] = {}
@@ -71,14 +77,6 @@ module Elesai
71
77
  "#{self[:id]}"
72
78
  end
73
79
 
74
- def type
75
- :adapter
76
- end
77
-
78
- def type_of?(type)
79
- self.type == type
80
- end
81
-
82
80
  def inspect
83
81
  "#{self.class}:#{self.__id__}"
84
82
  end
@@ -87,9 +85,15 @@ module Elesai
87
85
  self[:physicaldrives][pd._id] = pd unless self[:physicaldrives][pd._id].nil?
88
86
  end
89
87
 
90
- end
88
+ def add_section(section)
89
+ self[section.section] = section
90
+ end
91
+
92
+ def to_s
93
+ "[ADAPTER] %2s %s %s %s %s" % [ self._id,self[:versions][:productname].gsub(/\s+/,'_'),self[:versions][:fwpackagebuild],self[:imageversions][:fwversion],self[:hwconfiguration][:sasaddress] ]
94
+ end
91
95
 
92
- ### Virtual Drive
96
+ end
93
97
 
94
98
  class VirtualDrive < Hash
95
99
 
@@ -116,14 +120,6 @@ module Elesai
116
120
  self[:targetid]
117
121
  end
118
122
 
119
- def type
120
- :virtualdrive
121
- end
122
-
123
- def type_of?(type)
124
- self.type == type
125
- end
126
-
127
123
  def inspect
128
124
  "#{self.class}:#{self.__id__}"
129
125
  end
@@ -138,8 +134,6 @@ module Elesai
138
134
 
139
135
  end
140
136
 
141
- ### Physical Drive
142
-
143
137
  class PhysicalDrive < Hash
144
138
 
145
139
  STATES = {
@@ -175,14 +169,6 @@ module Elesai
175
169
  "e#{self[:enclosuredeviceid].to_s}s#{self[:slotnumber].to_s}".to_sym
176
170
  end
177
171
 
178
- def type
179
- :physicaldrive
180
- end
181
-
182
- def type_of?(type)
183
- self.type == type
184
- end
185
-
186
172
  def to_s
187
173
  keys = [:deviceid, :firmwarestate, :coercedsize, :mediatype, :pdtype, :mediaerrorcount, :predictivefailurecount,:inquirydata]
188
174
  #"[PD] %8s %4s %19s %8.2f%s %5s %5s %3d %3d %s" % [ self.id, @deviceid, "#{@state}:#{@spin}", @_size.number, @_size.unit, @mediatype, @pdtype, @mediaerrors, @predictivefailure, @inquirydata ]
@@ -214,49 +200,41 @@ module Elesai
214
200
  end
215
201
  end
216
202
 
217
- ### BBU
218
-
219
203
  class BBU < Hash
220
204
 
221
205
  class NumberUnit < Struct.new(:number, :unit)
222
206
  def to_s ; "%d%s" % [self.number,self.unit] end
223
207
  end
224
208
 
225
- class Stub < Hash
209
+ class Section < Hash
210
+ attr_reader :section
211
+ def initialize(section)
212
+ @section = section
213
+ end
226
214
  def inspect
227
- "#{self.class}:#{self.__id__}"
215
+ "#{self.class}:#{@section.capitalize}:#{self.__id__}"
228
216
  end
229
217
  end
230
- class Status < Stub; end
231
- class FirmwareStatus < Stub; end
232
- class DesignInfo < Stub; end
233
- class Properties < Stub; end
234
- class CapacityInfo < Stub; end
235
- class GasGaugeStatus < Stub; end
236
218
 
237
219
  def initialize
238
- self[:status] = Status.new
239
- self[:firmwarestatus] = FirmwareStatus.new
240
- self[:designinfo] = DesignInfo.new
241
- self[:properties] = Properties.new
242
- self[:capacityinfo] = CapacityInfo.new
243
- self[:gasgaugestatus] = GasGaugeStatus.new
244
- self[:capacityinfo][:absolutestateofcharge] = '-'
245
220
  end
246
221
 
247
222
  def _id
248
223
  self[:id]
249
224
  end
250
225
 
226
+ def add_section(section)
227
+ self[section.section] = section
228
+ end
229
+
251
230
  def inspect
252
231
  "#{self.class}:#{self.__id__}"
253
232
  end
254
233
 
255
234
  def to_s
256
- self[:capacityinfo][:absolutestateofcharge] = '-' unless self[:batterytype] == "iBBU"
257
- self[:capacityinfo][:remainingcapacity] = '-' unless self[:batterytype] == "iBBU"
258
- "[BBU] %s %-5s %-4s %-11s %3s:%-8s %s:%s %s:%s %7s:%-4s %s" % [self[:id],self[:batterytype],self[:designinfo][:devicechemistry],self[:firmwarestatus][:chargingstatus],self[:firmwarestatus][:learncycleactive],self[:firmwarestatus][:learncyclestatus],self[:voltage].gsub(/\s/,''),self[:firmwarestatus][:voltage],self[:temperature].gsub(/\s/,''),self[:firmwarestatus][:temperature],self[:capacityinfo][:remainingcapacity],self[:capacityinfo][:absolutestateofcharge],self[:properties][:nextlearntime]]
259
- #puts self[:firmwarestatus].keys
235
+ capacityinfo_absolutestateofcharge = self[:batterytype] == 'iBBU' ? self[:capacityinfo][:absolutestateofcharge] : '-'
236
+ capacityinfo_remainingcapacity = self[:batterytype] == 'iBBU' ? self[:capacityinfo][:remainingcapacity] : '-'
237
+ "[BBU] %s %-5s %-4s %-11s %3s:%-8s %s:%s %s:%s %7s:%-4s %s" % [self[:id],self[:batterytype],self[:designinfo][:devicechemistry],self[:firmwarestatus][:chargingstatus],self[:firmwarestatus][:learncycleactive],self[:firmwarestatus][:learncyclestatus],self[:voltage].gsub(/\s/,''),self[:firmwarestatus][:voltage],self[:temperature].gsub(/\s/,''),self[:firmwarestatus][:temperature],capacityinfo_remainingcapacity,capacityinfo_absolutestateofcharge,self[:properties][:nextlearntime]]
260
238
  end
261
239
  end
262
240
  end
@@ -0,0 +1,102 @@
1
+ module Elesai; module Megacli
2
+
3
+ class AdpAllInfo_aAll < Megacli
4
+
5
+ def initialize
6
+ @megacli = { :adapter => { :re => /^Adapter\s+#*(?<value>\d+)/, :method => self.method(:adapter_match) },
7
+ :versions => { :re => /^Versions/, :method => self.method(:section_match) },
8
+ :mfgdata => { :re => /^Mfg\.\s+Data/, :method => self.method(:section_match) },
9
+ :imageversions => { :re => /^Image Versions in Flash/, :method => self.method(:section_match) },
10
+ :pendingvensions => { :re => /^Pending Images in Flash/, :method => self.method(:section_match) },
11
+ :pciinfo => { :re => /^PCI Info/, :method => self.method(:section_match) },
12
+ :hwconfiguration => { :re => /^HW Configuration/, :method => self.method(:section_match) },
13
+ :setttings => { :re => /^Settings/, :method => self.method(:section_match) },
14
+ :capabilities => { :re => /^Capabilities/, :method => self.method(:section_match) },
15
+ :status => { :re => /^Status/, :method => self.method(:section_match) },
16
+ :limitations => { :re => /^Limitations/, :method => self.method(:section_match) },
17
+ :devicepresent => { :re => /^Device Present/, :method => self.method(:section_match) },
18
+ :supportedadapteroperations => { :re => /^Supported Adapter Operations/, :method => self.method(:section_match) },
19
+ :supportedvdoperations => { :re => /^Supported VD Operations/, :method => self.method(:section_match) },
20
+ :supportedddoperations => { :re => /^Supported PD Operations/, :method => self.method(:section_match) },
21
+ :errorcounters => { :re => /^Error Counters/, :method => self.method(:section_match) },
22
+ :clusterinformation => { :re => /^ClusterInformation/, :method => self.method(:section_match) },
23
+ :defaultsettings => { :re => /^Default Settings/, :method => self.method(:section_match) },
24
+ :exit => { :re => /^Exit Code: /, :method => self.method(:exit_match) },
25
+ :attribute => { :re => /^(?<key>[A-Za-z0-9()\s#'-.&]+)([:|=](?<value>.*))?/, :method => self.method(:attribute_match) }
26
+ }.freeze
27
+ @command_arguments = "-adpallinfo -aall".freeze
28
+ @command_output_file = "adpallinfo_aall".freeze
29
+ end
30
+
31
+ def parse!(lsi,opts)
32
+ fake = opts[:fake].nil? ? @command_arguments : File.join(opts[:fake],@command_output_file)
33
+ super lsi, :fake => fake, :megacli => opts[:megacli]
34
+ end
35
+
36
+ # State Machine
37
+
38
+ workflow do
39
+
40
+ state :start do
41
+ event :adapter_line, :transitions_to => :adapter
42
+ event :exit_line, :transitions_to => :exit
43
+ end
44
+
45
+ state :adapter do
46
+ event :adapter_line, :transitions_to => :adapter # empty adapter
47
+ event :section_line, :transitions_to => :section
48
+ event :exit_line, :transitions_to => :exit
49
+ end
50
+
51
+ state :section do
52
+ event :exit_line, :transitions_to => :exit
53
+ event :adapter_line, :transitions_to => :adapter
54
+ event :attribute_line, :transitions_to => :attribute
55
+ end
56
+
57
+ state :attribute do
58
+ event :attribute_line, :transitions_to => :attribute
59
+ event :section_line, :transitions_to => :section
60
+ event :adapter_line, :transitions_to => :adapter
61
+ event :exit_line, :transitions_to => :exit
62
+ end
63
+
64
+ state :exit
65
+
66
+ on_transition do |from, to, triggering_event, *event_args|
67
+ #puts self.spec.states[to].class
68
+ # puts " transition: #{from} >> #{triggering_event}! >> #{to}: #{event_args.join(' ')}"
69
+ #puts " #{current_state.meta}"
70
+ end
71
+ end
72
+
73
+ ### Match Handlers
74
+
75
+ def section_match(k,match)
76
+ @log.debug "ADPINFO_SECTION! #{k} -> #{match.string}"
77
+ section_line!(LSI::Adapter::Section.new(k))
78
+ end
79
+
80
+ ### Line Handlers
81
+
82
+ def section_line(section)
83
+ @log.debug " [#{current_state}] event: section_line: new #{section.inspect}"
84
+ end
85
+
86
+ def on_section_entry(old_state, event, *args)
87
+ @log.debug " [#{current_state}] on_entry: leaving #{old_state}; args: #{args}"
88
+ unless @context.current.nil?
89
+ @context.close if Elesai::LSI::Adapter::Section === @context.current
90
+ end
91
+ @context.current.add_section(args[0])
92
+ @context.open(args[0])
93
+ end
94
+
95
+ def on_section_exit(new_state, event, *args)
96
+ @log.debug " [#{current_state}] on_exit: entering #{new_state}; args: #{args}"
97
+ @context.flash!(new_state)
98
+ end
99
+
100
+ end
101
+
102
+ end end
@@ -0,0 +1,107 @@
1
+ module Elesai; module Megacli
2
+
3
+ class AdpBbuCmd_aAll < Megacli
4
+
5
+ def initialize
6
+ @megacli = { :bbu => { :re => /^BBU status for Adapter:\s+(?<value>\d+)/, :method => self.method(:bbu_match) },
7
+ :firmwarestatus => { :re => /^BBU Firmware Status:/, :method => self.method(:section_match) },
8
+ :designinfo => { :re => /^BBU Design Info for Adapter:\s+(?<value>\d+)/, :method => self.method(:section_match) },
9
+ :properties => { :re => /^BBU Properties for Adapter:\s+(?<value>\d+)/, :method => self.method(:section_match) },
10
+ :gasgaugestatus => { :re => /^GasGuageStatus:/, :method => self.method(:section_match) },
11
+ :capacityinfo => { :re => /^BBU Capacity Info for Adapter:\s+(?<value>\d+)/, :method => self.method(:section_match) },
12
+ :exit => { :re => /^Exit Code: /, :method => self.method(:exit_match) },
13
+ :attribute => { :re => /^(?<key>[A-Za-z0-9()\s#'-.&]+)[:|=](?<value>.*)/, :method => self.method(:attribute_match) }
14
+ }.freeze
15
+ @command_arguments = "-adpbbucmd -aall".freeze
16
+ @command_output_file = "adpbbucmd_aall".freeze
17
+ end
18
+
19
+ def parse!(lsi,opts)
20
+ fake = opts[:fake].nil? ? @command_arguments : File.join(opts[:fake],@command_output_file)
21
+ super lsi, :fake => fake, :megacli => opts[:megacli]
22
+ end
23
+
24
+ # State Machine
25
+
26
+ workflow do
27
+
28
+ state :start do
29
+ event :bbu_line, :transitions_to => :bbu
30
+ event :exit_line, :transitions_to => :exit
31
+ end
32
+
33
+ state :bbu do
34
+ event :attribute_line, :transitions_to => :attribute
35
+ event :section_line, :transitions_to => :section
36
+ end
37
+
38
+ state :section do
39
+ event :exit_line, :transitions_to => :exit
40
+ event :attribute_line, :transitions_to => :attribute
41
+ end
42
+
43
+ state :attribute do
44
+ event :attribute_line, :transitions_to => :attribute
45
+ event :section_line, :transitions_to => :section
46
+ event :exit_line, :transitions_to => :exit
47
+ end
48
+
49
+ state :exit
50
+
51
+ end
52
+
53
+ # Regular Expression Match Handlers
54
+
55
+ def bbu_match(k,match)
56
+ @log.debug "BBU! #{match.string}"
57
+ key = 'id'
58
+ value = match[:value]
59
+ adapter_line(LSI::Adapter.new,key,value)
60
+ bbu_line!(LSI::BBU.new,key,value)
61
+ end
62
+
63
+ def section_match(k,match)
64
+ @log.debug "ADPINFO_SECTION! #{k} -> #{match.string}"
65
+ section_line!(LSI::BBU::Section.new(k))
66
+ end
67
+
68
+ ### Line Handlers
69
+
70
+ def bbu_line(bbu,key,value)
71
+ @log.debug " [#{current_state}] event: bbu_line: new #{bbu.inspect}"
72
+ bbu[key.to_sym] = value.to_i
73
+ end
74
+
75
+ def on_bbu_entry(old_state, event, *args)
76
+ @log.debug " [#{current_state}] on_entry: leaving #{old_state}; args: #{args}"
77
+ @context.open args[0]
78
+ end
79
+
80
+ def on_bbu_exit(new_state, event, *args)
81
+ @log.debug " [#{current_state}] on_exit: entering #{new_state}; args: #{args}"
82
+ @context.flash!(new_state)
83
+ end
84
+
85
+ def section_line(section)
86
+ @log.debug " [#{current_state}] event: section_line: new #{section.inspect}"
87
+ end
88
+
89
+ def on_section_entry(old_state, event, *args)
90
+ @log.debug " [#{current_state}] on_entry: leaving #{old_state}; args: #{args}"
91
+ unless @context.current.nil?
92
+ @context.close if Elesai::LSI::BBU::Section === @context.current
93
+ end
94
+ @context.current.add_section(args[0])
95
+ @context.open(args[0])
96
+ end
97
+
98
+ def on_section_exit(new_state, event, *args)
99
+ @log.debug " [#{current_state}] on_exit: entering #{new_state}; args: #{args}"
100
+ @context.flash!(new_state)
101
+ end
102
+
103
+ end
104
+
105
+ end end
106
+
107
+
@@ -0,0 +1,140 @@
1
+ module Elesai; module Megacli
2
+
3
+ class LDPDinfo_aAll < Megacli
4
+
5
+ def initialize
6
+ @megacli = { :adapter => { :re => /^Adapter\s+#*(?<value>\d+)/, :method => self.method(:adapter_match) },
7
+ :virtualdrive => { :re => /^Virtual\s+Drive:\s+\d+\s+\((?<key>Target\s+Id):\s+(?<value>\d+)\)/, :method => self.method(:virtualdrive_match) },
8
+ :physicaldrive => { :re => /^(?<key>Enclosure\s+Device\s+ID):\s+(?<value>\d+)/, :method => self.method(:physicaldrive_match) },
9
+ :exit => { :re => /^Exit Code: /, :method => self.method(:exit_match) },
10
+ :attribute => { :re => /^(?<key>[A-Za-z0-9()\s#'-.&]+)[:|=](?<value>.*)/, :method => self.method(:attribute_match) }
11
+ }.freeze
12
+ @command_arguments = "-ldpdinfo -aall".freeze
13
+ @command_output_file = "ldpdinfo_aall".freeze
14
+ end
15
+
16
+ def parse!(lsi,opts)
17
+ fake = opts[:fake].nil? ? @command_arguments : File.join(opts[:fake],@command_output_file)
18
+ super lsi, :fake => fake, :megacli => opts[:megacli]
19
+ end
20
+
21
+ # Regular Expression Match Handlers
22
+
23
+ def virtualdrive_match(k,match)
24
+ @log.debug "VIRTUALDRIVE! #{match.string}"
25
+ key = match[:key].gsub(/\s+/,"").downcase
26
+ value = match[:value]
27
+ virtualdrive_line!(LSI::VirtualDrive.new,key,value)
28
+ end
29
+
30
+ def physicaldrive_match(k,match)
31
+ @log.debug "PHYSICALDRIVE! #{match.string}"
32
+ key = match[:key].gsub(/\s+/,"").downcase
33
+ value = match[:value]
34
+ physicaldrive_line!(LSI::PhysicalDrive.new,key,value)
35
+ end
36
+
37
+ # Line Handlers
38
+
39
+ def adapter_line(adapter,key,value)
40
+ @log.debug " [#{current_state}] event adapter_line: new #{adapter.inspect}"
41
+ adapter[key.to_sym] = value.to_i
42
+ end
43
+
44
+ def on_adapter_entry(old_state, event, *args)
45
+ @log.debug " [#{current_state}] on_entry: leaving #{old_state}; args: #{args}"
46
+
47
+ @context.close unless @context.current.nil? or Elesai::LSI::Adapter === @context.current
48
+ @context.open args[0]
49
+ end
50
+
51
+ def on_adapter_exit(new_state, event, *args)
52
+ @log.debug " [#{current_state}] on_exit: entering #{new_state}; args: #{args}"
53
+ @context.flash!(new_state)
54
+ end
55
+
56
+ def virtualdrive_line(virtualdrive,key,value)
57
+ @log.debug " [#{current_state}] event: virtualdrive_line: new #{virtualdrive.inspect}"
58
+ virtualdrive[key.to_sym] = value.to_i
59
+ end
60
+
61
+ def on_virtualdrive_entry(old_state, event, *args)
62
+ @log.debug " [#{current_state}] on_entry: leaving #{old_state}; args: #{args}"
63
+
64
+ unless @context.current.nil?
65
+ if Elesai::LSI::VirtualDrive === @context.current
66
+ @context.close
67
+ end
68
+ end
69
+ virtualdrive = args[0]
70
+ @context.open virtualdrive
71
+ end
72
+
73
+ def on_virtualdrive_exit(new_state, event, *args)
74
+ @log.debug " [#{current_state}] on_exit: entering #{new_state}; args: #{args}"
75
+ @context.flash!(new_state)
76
+ end
77
+
78
+ # Physical Drive
79
+
80
+ def physicaldrive_line(physicaldrive,key,value)
81
+ @log.debug " [#{current_state}] event: physicaldrive_line: new #{physicaldrive.inspect}"
82
+ physicaldrive[key.to_sym] = value.to_i
83
+ end
84
+
85
+ def on_physicaldrive_entry(old_state, event, *args)
86
+ @log.debug " [#{current_state}] on_entry: leaving #{old_state}; args: #{args}"
87
+ @context.open args[0]
88
+ end
89
+
90
+ def on_physicaldrive_exit(new_state, event, *args)
91
+ @log.debug " [#{current_state}] on_exit: entering #{new_state}; args: #{args}"
92
+ @context.flash!(new_state)
93
+ end
94
+
95
+ workflow do
96
+
97
+ state :start do
98
+ event :adapter_line, :transitions_to => :adapter
99
+ event :exit_line, :transitions_to => :exit
100
+ end
101
+
102
+ state :adapter do
103
+ event :adapter_line, :transitions_to => :adapter
104
+ event :attribute_line, :transitions_to => :attribute
105
+ event :virtualdrive_line, :transitions_to => :virtualdrive
106
+ event :exit_line, :transitions_to => :exit
107
+ end
108
+
109
+ state :physicaldrive do
110
+ event :attribute_line, :transitions_to => :physicaldrive
111
+ event :exit_line, :transitions_to => :exit
112
+ event :adapter_line, :transitions_to => :adapter
113
+ event :physicaldrive_line, :transitions_to => :physicaldrive
114
+ event :attribute_line, :transitions_to => :attribute
115
+ end
116
+
117
+ state :virtualdrive do
118
+ event :physicaldrive_line, :transitions_to => :physicaldrive
119
+ event :attribute_line, :transitions_to => :attribute
120
+ end
121
+
122
+ state :attribute do
123
+ event :attribute_line, :transitions_to => :attribute
124
+ event :virtualdrive_line, :transitions_to => :virtualdrive
125
+ event :physicaldrive_line, :transitions_to => :physicaldrive
126
+ event :adapter_line, :transitions_to => :adapter
127
+ event :exit_line, :transitions_to => :exit
128
+ end
129
+
130
+ state :exit
131
+
132
+ on_transition do |from, to, triggering_event, *event_args|
133
+ #puts self.spec.states[to].class
134
+ # puts " transition: #{from} >> #{triggering_event}! >> #{to}: #{event_args.join(' ')}"
135
+ #puts " #{current_state.meta}"
136
+ end
137
+ end
138
+
139
+ end
140
+ end; end