automateit 0.71006 → 0.71012
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.tar.gz.sig +0 -0
- data/CHANGES.txt +12 -0
- data/Rakefile +6 -1
- data/TODO.txt +10 -2
- data/lib/automateit/account_manager/linux.rb +4 -2
- data/lib/automateit/address_manager.rb +2 -82
- data/lib/automateit/address_manager/base.rb +148 -0
- data/lib/automateit/address_manager/linux.rb +8 -46
- data/lib/automateit/address_manager/sunos.rb +46 -0
- data/lib/automateit/interpreter.rb +4 -0
- data/lib/automateit/platform_manager.rb +1 -0
- data/lib/automateit/platform_manager/darwin.rb +2 -2
- data/lib/automateit/platform_manager/freebsd.rb +4 -0
- data/lib/automateit/platform_manager/sunos.rb +39 -0
- data/lib/automateit/plugin/driver.rb +21 -4
- data/lib/automateit/plugin/manager.rb +2 -1
- data/lib/automateit/root.rb +1 -1
- data/lib/automateit/service_manager/sysv.rb +2 -1
- data/lib/automateit/shell_manager.rb +3 -0
- data/lib/automateit/shell_manager/portable.rb +22 -14
- data/lib/automateit/template_manager.rb +4 -3
- data/lib/automateit/template_manager/base.rb +13 -7
- data/spec/breaker.rb +8 -0
- data/spec/integration/{address_manager_linux_spec.rb → address_manager_spec.rb} +65 -25
- data/spec/integration/package_manager_spec.rb +4 -0
- data/spec/integration/service_manager_sysv_spec.rb +92 -34
- data/spec/integration/template_manager_erb_spec.rb +22 -5
- data/spec/unit/plugins_spec.rb +5 -0
- data/spec/unit/template_manager_erb_spec.rb +4 -0
- metadata +9 -4
- metadata.gz.sig +0 -0
@@ -2,10 +2,10 @@
|
|
2
2
|
#
|
3
3
|
# A PlatformManager driver for Apple's Darwin.
|
4
4
|
class AutomateIt::PlatformManager::Darwin < AutomateIt::PlatformManager::Struct
|
5
|
-
depends_on :files => ["/usr/sbin/scutil"], :programs => ["which"]
|
5
|
+
depends_on :files => ["/usr/sbin/scutil"], :programs => ["which", "uname"]
|
6
6
|
|
7
7
|
def suitability(method, *args) # :nodoc:
|
8
|
-
# Must be higher than PlatformManager::
|
8
|
+
# Must be higher than PlatformManager::Uname
|
9
9
|
return available? ? 3 : 0
|
10
10
|
end
|
11
11
|
|
@@ -2,6 +2,10 @@
|
|
2
2
|
#
|
3
3
|
# A PlatformManager driver for FreeBSD.
|
4
4
|
class AutomateIt::PlatformManager::FreeBSD < AutomateIt::PlatformManager::Uname
|
5
|
+
def self.token
|
6
|
+
:freebsd
|
7
|
+
end
|
8
|
+
|
5
9
|
depends_on :files => %w(/etc/portsnap.conf /etc/rc.conf)
|
6
10
|
|
7
11
|
def suitability(method, *args) # :nodoc:
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# == PlatformManager::SunOS
|
2
|
+
#
|
3
|
+
# A PlatformManager driver for SunOS.
|
4
|
+
class AutomateIt::PlatformManager::SunOS < AutomateIt::PlatformManager::Uname
|
5
|
+
def self.token
|
6
|
+
:sunos
|
7
|
+
end
|
8
|
+
|
9
|
+
depends_on \
|
10
|
+
:programs => %w(uname),
|
11
|
+
:callbacks => [lambda {
|
12
|
+
begin
|
13
|
+
not `uname -s`.match(/SunOS/i).nil?
|
14
|
+
rescue
|
15
|
+
false
|
16
|
+
end
|
17
|
+
}]
|
18
|
+
|
19
|
+
def suitability(method, *args) # :nodoc:
|
20
|
+
# Must be higher than PlatformManager::Struct and Uname
|
21
|
+
return available? ? 3 : 0
|
22
|
+
end
|
23
|
+
|
24
|
+
def _prepare
|
25
|
+
return if @struct[:release]
|
26
|
+
@struct[:distro] = "sun"
|
27
|
+
@struct[:release] = `uname -r`.strip.downcase
|
28
|
+
@struct
|
29
|
+
end
|
30
|
+
|
31
|
+
def query(search)
|
32
|
+
_prepare
|
33
|
+
super(search)
|
34
|
+
end
|
35
|
+
|
36
|
+
def single_vendor?
|
37
|
+
return true
|
38
|
+
end
|
39
|
+
end
|
@@ -45,6 +45,18 @@ module AutomateIt
|
|
45
45
|
cattr_accessor :classes
|
46
46
|
self.classes = {}
|
47
47
|
|
48
|
+
# Returns the Plugin::Manager instance for this Driver.
|
49
|
+
attr_accessor :manager
|
50
|
+
|
51
|
+
# Setup a Driver.
|
52
|
+
#
|
53
|
+
# Options:
|
54
|
+
# * :manager -- The Plugin::Manager instance controlling this driver.
|
55
|
+
def setup(opts={})
|
56
|
+
self.manager = opts[:manager] if opts[:manager]
|
57
|
+
super(opts)
|
58
|
+
end
|
59
|
+
|
48
60
|
# Retrieve the manager token for this driver
|
49
61
|
def self.manager_token
|
50
62
|
fragments = base_driver.to_s.split(/::/)
|
@@ -70,10 +82,14 @@ module AutomateIt
|
|
70
82
|
if subclass.base_driver?
|
71
83
|
# Ignore, base drivers should never be registered
|
72
84
|
elsif base_driver
|
73
|
-
|
74
|
-
classes[
|
75
|
-
|
76
|
-
|
85
|
+
manager_token = subclass.manager_token
|
86
|
+
classes[manager_token] ||= []
|
87
|
+
|
88
|
+
unless classes[manager_token].include?(subclass)
|
89
|
+
classes[manager_token] << subclass
|
90
|
+
end
|
91
|
+
|
92
|
+
### puts "manager_token %s / driver %s" % [manager_token, subclass]
|
77
93
|
else
|
78
94
|
# XXX Should this really raise an exception?
|
79
95
|
raise TypeError.new("Can't determine manager for driver: #{subclass}")
|
@@ -197,6 +213,7 @@ module AutomateIt
|
|
197
213
|
raise NotImplementedError.new("Missing dependencies -- %s" % msg)
|
198
214
|
end
|
199
215
|
end
|
216
|
+
protected :_raise_unless_available
|
200
217
|
|
201
218
|
# What is this driver's suitability for automatic detection? The Manager
|
202
219
|
# queries its drivers when there isn't a driver specified with a
|
@@ -80,7 +80,8 @@ module AutomateIt
|
|
80
80
|
end
|
81
81
|
self.class.driver_classes.each do |driver_class|
|
82
82
|
driver_token = driver_class.token
|
83
|
-
@drivers[driver_token].setup(
|
83
|
+
@drivers[driver_token].setup(
|
84
|
+
:interpreter => @interpreter, :manager => self)
|
84
85
|
end
|
85
86
|
end
|
86
87
|
|
data/lib/automateit/root.rb
CHANGED
@@ -60,7 +60,7 @@ class AutomateIt::ServiceManager::SYSV < AutomateIt::ServiceManager::BaseDriver
|
|
60
60
|
end
|
61
61
|
|
62
62
|
result = tell(service, :status, :check => true)
|
63
|
-
|
63
|
+
nitpick("_sash top: k=%s r=%s e=%s" % [kind, result, expected])
|
64
64
|
return result if expected == result
|
65
65
|
if opts[:wait]
|
66
66
|
timeout = Time.now + opts[:wait]
|
@@ -69,6 +69,7 @@ class AutomateIt::ServiceManager::SYSV < AutomateIt::ServiceManager::BaseDriver
|
|
69
69
|
[kind, service, timeout - Time.now])
|
70
70
|
sleep 0.5
|
71
71
|
result = tell(service, :status, :check => true)
|
72
|
+
nitpick("_sash rep: k=%s r=%s e=%s" % [kind, result, expected])
|
72
73
|
break if expected == result
|
73
74
|
end
|
74
75
|
log.info(PNOTE+" ServiceManager#%s finished waiting for '%s', got: %s" %
|
@@ -28,6 +28,9 @@ class AutomateIt::ShellManager < AutomateIt::Plugin::Manager
|
|
28
28
|
|
29
29
|
# Backup +sources+ if they exist. Returns the names of the backups created.
|
30
30
|
#
|
31
|
+
# Options:
|
32
|
+
# * :quiet -- Don't display output? Default is false.
|
33
|
+
#
|
31
34
|
# These backups are copies of the original sources saved into the same
|
32
35
|
# directories as the originals. The pathnames of these copies are timestamped
|
33
36
|
# and guaranteed to be unique, so you can have multiple backups of the same
|
@@ -30,6 +30,8 @@ class AutomateIt::ShellManager::Portable < AutomateIt::ShellManager::BaseDriver
|
|
30
30
|
|
31
31
|
# See ShellManager#backup
|
32
32
|
def backup(*sources)
|
33
|
+
sources, opts = args_and_opts(*sources)
|
34
|
+
|
33
35
|
targets = []
|
34
36
|
for source in sources
|
35
37
|
is_dir = File.directory?(source)
|
@@ -46,17 +48,19 @@ class AutomateIt::ShellManager::Portable < AutomateIt::ShellManager::BaseDriver
|
|
46
48
|
|
47
49
|
target = ::Tempster.tempster(tempster_opts)
|
48
50
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
51
|
+
log.silence(opts[:quiet] ? Logger::WARN : log.level) do
|
52
|
+
if is_dir
|
53
|
+
cp_opts = {}
|
54
|
+
cp_opts[:recursive] = true if is_dir
|
55
|
+
cp_opts[:preserve] = :try
|
53
56
|
|
54
|
-
|
55
|
-
|
57
|
+
source_children = _directory_contents(source)
|
58
|
+
#puts "sc: %s" % source_children.inspect
|
56
59
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
+
interpreter.cp_r(source_children, target, cp_opts)
|
61
|
+
else
|
62
|
+
interpreter.cp(source, target)
|
63
|
+
end
|
60
64
|
end
|
61
65
|
|
62
66
|
targets << target
|
@@ -393,6 +397,8 @@ class AutomateIt::ShellManager::Portable < AutomateIt::ShellManager::BaseDriver
|
|
393
397
|
end
|
394
398
|
|
395
399
|
modified_entries = []
|
400
|
+
modified_ownership = false
|
401
|
+
modified_permission = false
|
396
402
|
Find.find(*targets) do |path|
|
397
403
|
modified = false
|
398
404
|
stat = writing? || File.exists?(path) ? File.stat(path) : nil
|
@@ -401,15 +407,18 @@ class AutomateIt::ShellManager::Portable < AutomateIt::ShellManager::BaseDriver
|
|
401
407
|
mode = opts[:mode] | (stat.directory? ? DIRECTORY_MASK : FILE_MASK) if stat
|
402
408
|
unless stat and (mode ^ stat.mode).zero?
|
403
409
|
modified = true
|
410
|
+
modified_permission = true
|
404
411
|
File.chmod(mode, path) if writing?
|
405
412
|
end
|
406
413
|
end
|
407
414
|
if user and (not stat or user != stat.uid)
|
408
415
|
modified = true
|
416
|
+
modified_ownership = true
|
409
417
|
File.chown(user, nil, path) if writing?
|
410
418
|
end
|
411
419
|
if group and (not stat or group != stat.gid)
|
412
420
|
modified = true
|
421
|
+
modified_ownership = true
|
413
422
|
File.chown(nil, group, path) if writing?
|
414
423
|
end
|
415
424
|
modified_entries << path if modified
|
@@ -421,19 +430,18 @@ class AutomateIt::ShellManager::Portable < AutomateIt::ShellManager::BaseDriver
|
|
421
430
|
display_entries = opts[:details] ? modified_entries : targets
|
422
431
|
display_entries = [display_entries].flatten
|
423
432
|
|
424
|
-
if
|
433
|
+
if modified_permission
|
425
434
|
msg = "chmod"
|
426
435
|
msg << " -R" if opts[:recursive]
|
427
436
|
msg << " 0%o" % opts[:mode] if opts[:mode]
|
428
437
|
msg << " " << display_entries.join(' ')
|
429
438
|
log.info(PEXEC+msg)
|
430
439
|
end
|
431
|
-
if
|
440
|
+
if modified_ownership
|
432
441
|
msg = "chown"
|
433
442
|
msg << " -R" if opts[:recursive]
|
434
443
|
msg << " %s" % opts[:user] if opts[:user]
|
435
444
|
msg << ":" if opts[:user] and opts[:group]
|
436
|
-
msg << " " unless opts[:user] and opts[:group]
|
437
445
|
msg << "%s" % opts[:group] if opts[:group]
|
438
446
|
msg << " " << display_entries.join(' ')
|
439
447
|
log.info(PEXEC+msg)
|
@@ -484,11 +492,11 @@ class AutomateIt::ShellManager::Portable < AutomateIt::ShellManager::BaseDriver
|
|
484
492
|
end
|
485
493
|
|
486
494
|
unless quiet
|
487
|
-
msg =
|
495
|
+
msg = "touch"
|
488
496
|
msg << " --reference %s" % like if like
|
489
497
|
msg << " --stamp %s" % stamp if stamp
|
490
498
|
msg << " " << [targets].flatten.join(" ")
|
491
|
-
log.info(msg)
|
499
|
+
log.info(PEXEC+msg)
|
492
500
|
end
|
493
501
|
|
494
502
|
results = []
|
@@ -17,9 +17,10 @@ class AutomateIt::TemplateManager < AutomateIt::Plugin::Manager
|
|
17
17
|
# * :text -- Read the template from this string.
|
18
18
|
# * :to -- Render to a file, otherwise returns the rendered string.
|
19
19
|
# * :locals -- Hash of variables passed to template as local variables.
|
20
|
-
# * :dependencies --
|
21
|
-
#
|
22
|
-
# * :
|
20
|
+
# * :dependencies -- Array of filenames to check timestamps on, only used
|
21
|
+
# when :check is :timestamp.
|
22
|
+
# * :backup -- Make a backup? Default is true.
|
23
|
+
# * :force -- Render without making a check. Default is false.
|
23
24
|
# * :check -- Determines when to render, otherwise uses value of
|
24
25
|
# +default_check+, possible values:
|
25
26
|
# * :compare -- Only render if rendered template is different than the
|
@@ -16,6 +16,10 @@ class AutomateIt::TemplateManager::BaseDriver < AutomateIt::Plugin::Driver
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
#.......................................................................
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
19
23
|
# Return Array of +dependencies+ newer than +filename+. Will be empty if
|
20
24
|
# +filename+ is newer than all of the +dependencies+.
|
21
25
|
def _newer(filename, *dependencies)
|
@@ -26,13 +30,11 @@ class AutomateIt::TemplateManager::BaseDriver < AutomateIt::Plugin::Driver
|
|
26
30
|
end
|
27
31
|
return updated
|
28
32
|
end
|
29
|
-
protected :_newer
|
30
33
|
|
31
34
|
# Does +filename+ exist?
|
32
35
|
def _exists?(filename)
|
33
36
|
return File.exists?(filename)
|
34
37
|
end
|
35
|
-
protected :_exists?
|
36
38
|
|
37
39
|
# Return the contents of +filename+.
|
38
40
|
def _read(filename)
|
@@ -47,20 +49,22 @@ class AutomateIt::TemplateManager::BaseDriver < AutomateIt::Plugin::Driver
|
|
47
49
|
end
|
48
50
|
end
|
49
51
|
end
|
50
|
-
protected :_read
|
51
52
|
|
52
53
|
# Write +contents+ to +filename+.
|
53
54
|
def _write(filename, contents)
|
54
55
|
File.open(filename, "w+"){|writer| writer.write(contents)} if writing?
|
55
56
|
return true
|
56
57
|
end
|
57
|
-
|
58
|
+
|
59
|
+
# Backup +filename+.
|
60
|
+
def _backup(filename)
|
61
|
+
interpreter.backup(filename)
|
62
|
+
end
|
58
63
|
|
59
64
|
# Return the modification date for +filename+.
|
60
65
|
def _mtime(filename)
|
61
66
|
return _exists? ? File.mtime(filename) : nil
|
62
67
|
end
|
63
|
-
protected :_mtime
|
64
68
|
|
65
69
|
# Render a template specified in the block. It takes the same arguments and
|
66
70
|
# returns the same results as the #render call.
|
@@ -84,6 +88,7 @@ class AutomateIt::TemplateManager::BaseDriver < AutomateIt::Plugin::Driver
|
|
84
88
|
source_filename = args[0] || opts[:file]
|
85
89
|
target_filename = args[1] || opts[:to]
|
86
90
|
source_text = opts[:text]
|
91
|
+
opts[:backup] = true if opts[:backup].nil?
|
87
92
|
|
88
93
|
raise ArgumentError.new("No source specified with :file or :text") if not source_filename and not source_text
|
89
94
|
raise Errno::ENOENT.new(source_filename) if writing? and source_filename and not _exists?(source_filename)
|
@@ -155,11 +160,13 @@ class AutomateIt::TemplateManager::BaseDriver < AutomateIt::Plugin::Driver
|
|
155
160
|
log.debug(PNOTE+"Rendering for '#{target_filename}' skipped because contents are the same")
|
156
161
|
return false
|
157
162
|
else
|
158
|
-
log.info(PNOTE+"Rendering '#{target_filename} because its contents changed")
|
163
|
+
log.info(PNOTE+"Rendering '#{target_filename}' because its contents changed")
|
159
164
|
end
|
160
165
|
when :timestamp
|
161
166
|
log.info(PNOTE+"Rendering '#{target_filename}' because of updated: #{updates.join(' ')}")
|
162
167
|
end
|
168
|
+
|
169
|
+
_backup(target_filename) if target_exists and opts[:backup]
|
163
170
|
result = _write(target_filename, output)
|
164
171
|
return result
|
165
172
|
ensure
|
@@ -168,5 +175,4 @@ class AutomateIt::TemplateManager::BaseDriver < AutomateIt::Plugin::Driver
|
|
168
175
|
end
|
169
176
|
end
|
170
177
|
end
|
171
|
-
protected :_render_helper
|
172
178
|
end
|
data/spec/breaker.rb
ADDED
@@ -4,34 +4,26 @@ if not INTERPRETER.euid?
|
|
4
4
|
puts "NOTE: Can't check 'euid' on this platform, #{__FILE__}"
|
5
5
|
elsif not INTERPRETER.superuser?
|
6
6
|
puts "NOTE: Must be root to check #{__FILE__}"
|
7
|
-
elsif not INTERPRETER.address_manager[:linux].available?
|
8
|
-
puts "NOTE: Can't check AddressManager::Linux on this platform, #{__FILE__}"
|
9
7
|
else
|
10
|
-
describe
|
8
|
+
describe AutomateIt::AddressManager, :shared => true do
|
11
9
|
before(:all) do
|
10
|
+
# Should examples be independent? True is correct and lets you run a
|
11
|
+
# single example. False is evil and requires you to run the entire suite,
|
12
|
+
# but it's much faster. On Linux false yields a 5x speed-up.
|
13
|
+
@independent = false
|
14
|
+
|
12
15
|
@a = AutomateIt.new(:verbosity => Logger::WARN)
|
13
16
|
@m = @a.address_manager
|
14
|
-
|
15
|
-
@properties = {
|
16
|
-
:device => "eth0",
|
17
|
-
:label => "xxxx",
|
18
|
-
:address => "10.0.0.249",
|
19
|
-
:mask => "24",
|
20
|
-
:announcements => 1,
|
21
|
-
}
|
22
|
-
|
23
|
-
@device_and_label = @properties[:device]+":"+@properties[:label]
|
24
|
-
|
25
|
-
if @m.interfaces.include?(@device_and_label) \
|
26
|
-
or @m.addresses.include?(@properties[:address])
|
27
|
-
raise "ERROR: This computer already has the device/address used for testing! Either disable #{@device_and_label} and #{@properties[:address]}, or change the spec to test using different properties."
|
28
|
-
end
|
29
17
|
end
|
30
18
|
|
31
19
|
after(:all) do
|
32
20
|
@m.remove(@properties)
|
33
21
|
end
|
34
22
|
|
23
|
+
after(:each) do
|
24
|
+
@m.remove(@properties) if @independent
|
25
|
+
end
|
26
|
+
|
35
27
|
it "should find interfaces for top-level device" do
|
36
28
|
@m.interfaces.should include(@properties[:device])
|
37
29
|
end
|
@@ -50,36 +42,41 @@ else
|
|
50
42
|
|
51
43
|
it "should add an address" do
|
52
44
|
@m.add(@properties).should be_true
|
53
|
-
# Leaves active interface behind for other tests
|
54
45
|
end
|
55
46
|
|
56
47
|
it "should find added interface" do
|
57
|
-
|
48
|
+
@m.add(@properties).should be_true if @independent
|
49
|
+
|
58
50
|
@m.interfaces.should include(@device_and_label)
|
59
51
|
end
|
60
52
|
|
61
53
|
it "should find added IP address" do
|
62
|
-
|
54
|
+
@m.add(@properties).should be_true if @independent
|
55
|
+
|
63
56
|
@m.addresses.should include(@properties[:address])
|
64
57
|
end
|
65
58
|
|
66
59
|
it "should find added address using a properties bundle" do
|
67
|
-
|
60
|
+
@m.add(@properties).should be_true if @independent
|
61
|
+
|
68
62
|
@m.has?(@properties).should be_true
|
69
63
|
end
|
70
64
|
|
71
65
|
it "should find added address using the IP address" do
|
72
|
-
|
66
|
+
@m.add(@properties).should be_true if @independent
|
67
|
+
|
73
68
|
@m.has?(:address => @properties[:address]).should be_true
|
74
69
|
end
|
75
70
|
|
76
71
|
it "should find added address using device and label" do
|
77
|
-
|
72
|
+
@m.add(@properties).should be_true if @independent
|
73
|
+
|
78
74
|
@m.has?(:device => @properties[:device], :label => @properties[:label]).should be_true
|
79
75
|
end
|
80
76
|
|
81
77
|
it "should remove an address" do
|
82
|
-
|
78
|
+
@m.add(@properties).should be_true if @independent
|
79
|
+
|
83
80
|
@m.remove(@properties).should be_true
|
84
81
|
end
|
85
82
|
|
@@ -116,4 +113,47 @@ else
|
|
116
113
|
@m.hostnames_for("kagami").should == ["kagami"]
|
117
114
|
end
|
118
115
|
end
|
116
|
+
|
117
|
+
#---[ Targets ]---------------------------------------------------------
|
118
|
+
|
119
|
+
%w(linux sunos).each do |driver_name|
|
120
|
+
driver_token = driver_name.to_sym
|
121
|
+
driver = INTERPRETER.address_manager[driver_token]
|
122
|
+
if driver.available?
|
123
|
+
describe driver.class.to_s do
|
124
|
+
it_should_behave_like "AutomateIt::AddressManager"
|
125
|
+
|
126
|
+
before(:all) do
|
127
|
+
|
128
|
+
@properties = {
|
129
|
+
:device => @m.interfaces.reject{|t| t =~ /^lo\d+$/}.first,
|
130
|
+
:label => "1",
|
131
|
+
:address => "10.0.0.249",
|
132
|
+
:mask => "24",
|
133
|
+
}
|
134
|
+
|
135
|
+
case driver_token
|
136
|
+
when :sunos
|
137
|
+
# Accept defaults
|
138
|
+
when :linux
|
139
|
+
@properties[:label] = "atst"
|
140
|
+
@properties[:announcements] = 1
|
141
|
+
else
|
142
|
+
raise ArgumentError.new("Unknown AddressManager driver: #{driver_token}")
|
143
|
+
end
|
144
|
+
|
145
|
+
@device_and_label = @properties[:device]+":"+@properties[:label]
|
146
|
+
|
147
|
+
if @m.interfaces.include?(@device_and_label) \
|
148
|
+
or @m.addresses.include?(@properties[:address])
|
149
|
+
raise "ERROR: This computer already has the device/address used for testing! Either disable #{@device_and_label} and #{@properties[:address]}, or change the spec to test using different properties."
|
150
|
+
end
|
151
|
+
|
152
|
+
@d = @m[driver_token]
|
153
|
+
end
|
154
|
+
end
|
155
|
+
else
|
156
|
+
puts %{NOTE: Can't check %s on this platform, #{__FILE__}} % driver.class
|
157
|
+
end
|
158
|
+
end
|
119
159
|
end
|