vos 0.3.13 → 0.3.14

Sign up to get free protection for your applications and to get access to all the features.
data/lib/vos/box/vfs.rb CHANGED
@@ -1,10 +1,6 @@
1
1
  module Vos
2
2
  class Box
3
3
  module Vfs
4
- def open_fs &block
5
- open &block
6
- end
7
-
8
4
  def to_entry
9
5
  '/'.to_entry_on(self)
10
6
  end
@@ -2,7 +2,11 @@ require 'vfs/storages/local'
2
2
 
3
3
  module Vos
4
4
  module Drivers
5
- class Local < Abstract
5
+ class Local
6
+ def initialize root = ''
7
+ @root = root
8
+ end
9
+
6
10
  #
7
11
  # Vfs
8
12
  #
@@ -10,7 +14,6 @@ module Vos
10
14
  def open &block
11
15
  block.call self if block
12
16
  end
13
- alias_method :open_fs, :open
14
17
  def close; end
15
18
 
16
19
 
@@ -0,0 +1,66 @@
1
+ require 'aws'
2
+ require 'vos/drivers/s3_vfs_storage'
3
+
4
+ module Vos
5
+ module Drivers
6
+ class S3
7
+ attr_reader :connection, :bucket
8
+
9
+ DEFAULT_OPTIONS = {
10
+ # public: true
11
+ }
12
+
13
+ def initialize initialization_options, options = {}
14
+ @initialization_options, @options = initialization_options, DEFAULT_OPTIONS.merge(options)
15
+ end
16
+
17
+
18
+ #
19
+ # Establishing SSH channel
20
+ #
21
+ def open &block
22
+ if block
23
+ if connection
24
+ block.call self
25
+ else
26
+ begin
27
+ open
28
+ block.call self
29
+ ensure
30
+ close
31
+ end
32
+ end
33
+ else
34
+ unless connection
35
+ @connection = ::AWS::S3.new self.initialization_options.clone
36
+ unless bucket = options[:bucket]
37
+ raise("S3 bucket not provided (use Vos::Drivers::S3.new({initialization options ...}, {bucket: '<bucket_name>'}))!")
38
+ end
39
+ @bucket = @connection.buckets[bucket]
40
+ end
41
+ end
42
+ end
43
+
44
+ def close; end
45
+
46
+ #
47
+ # Vfs
48
+ #
49
+ include S3VfsStorage
50
+
51
+
52
+ #
53
+ # Miscellaneous
54
+ #
55
+ def inspect; "<#{self.class.name} #{initialization_options.inspect}, #{options.inspect}>" end
56
+ alias_method :to_s, :inspect
57
+
58
+ def _clear
59
+ bucket.objects.each{|o| o.delete}
60
+ end
61
+
62
+ protected
63
+ attr_reader :initialization_options, :options
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,156 @@
1
+ module Vos
2
+ module Drivers
3
+ module S3VfsStorage
4
+ class Error < StandardError
5
+ end
6
+
7
+ class Writer
8
+ attr_reader :data
9
+ def initialize
10
+ @data = ""
11
+ end
12
+
13
+ def write data
14
+ @data << data
15
+ end
16
+ end
17
+
18
+ #
19
+ # Attributes
20
+ #
21
+ def attributes path
22
+ path = normalize_path(path)
23
+ return {dir: true, file: false} if path.empty?
24
+
25
+ file = bucket.objects[path]
26
+
27
+ attrs = {}
28
+ file_exists = file.exists?
29
+ attrs[:file] = file_exists
30
+ if file_exists
31
+ attrs[:dir] = false
32
+ elsif dir_exists? path
33
+ attrs[:dir] = true
34
+ else
35
+ return nil
36
+ end
37
+
38
+ if file_exists
39
+ attrs[:size] = file.content_length
40
+ attrs[:updated_at] = file.last_modified
41
+ end
42
+
43
+ attrs
44
+ end
45
+
46
+ def set_attributes path, attrs
47
+ raise 'not supported'
48
+ end
49
+
50
+ #
51
+ # File
52
+ #
53
+ def read_file path, &block
54
+ path = normalize_path path
55
+ file = bucket.objects[path]
56
+ block.call file.read
57
+ end
58
+
59
+ def write_file original_path, append, &block
60
+ path = normalize_path original_path
61
+ # TODO2 Performance lost, extra call to check file existence
62
+ file = bucket.objects[path]
63
+ file_exist = file.exists?
64
+ raise "can't write, file #{original_path} already exist!" if !append and file_exist
65
+
66
+ if append
67
+ # there's no support for :append in Fog, so we just mimic it
68
+ writer = Writer.new
69
+ writer.write file.read if file_exist
70
+ block.call writer
71
+ file.write writer.data
72
+ else
73
+ writer = Writer.new
74
+ block.call writer
75
+ file.write writer.data
76
+ end
77
+ end
78
+
79
+ def delete_file path
80
+ path = normalize_path path
81
+ file = bucket.objects[path]
82
+ file.delete
83
+ end
84
+
85
+
86
+ #
87
+ # Dir
88
+ #
89
+ def create_dir path
90
+ raise Error, ":create_dir not supported!"
91
+ end
92
+
93
+ def delete_dir path
94
+ path = normalize_path path
95
+
96
+ bucket.as_tree(prefix: path).children.each do |obj|
97
+ if obj.branch?
98
+ delete_dir "/#{obj.prefix}"
99
+ elsif obj.leaf?
100
+ bucket.objects[obj.key].delete
101
+ else
102
+ raise "unknow node type!"
103
+ end
104
+ end
105
+ end
106
+
107
+ def each_entry path, query, &block
108
+ path = normalize_path path
109
+ raise "S3 not support :each_entry with query!" if query
110
+
111
+ bucket.as_tree(prefix: path).children.each do |obj|
112
+ if obj.branch?
113
+ block.call obj.prefix.sub("#{path}/", '').sub(/\/$/, ''), :dir
114
+ elsif obj.leaf?
115
+ block.call obj.key.sub("#{path}/", ''), :file
116
+ else
117
+ raise "unknow node type!"
118
+ end
119
+ end
120
+ end
121
+
122
+ #
123
+ # Special
124
+ #
125
+ def tmp &block
126
+ tmp_dir = "/tmp/#{rand(10**6)}"
127
+ if block
128
+ begin
129
+ block.call tmp_dir
130
+ ensure
131
+ delete_dir tmp_dir
132
+ end
133
+ else
134
+ tmp_dir
135
+ end
136
+ end
137
+
138
+ def local?; false end
139
+
140
+ protected
141
+ def dir_exists? path
142
+ path = normalize_path path
143
+ catch :break do
144
+ bucket.as_tree(prefix: path).children.each do
145
+ throw :break, true
146
+ end
147
+ false
148
+ end
149
+ end
150
+
151
+ def normalize_path path
152
+ path.sub(/^\//, '')
153
+ end
154
+ end
155
+ end
156
+ end
@@ -5,15 +5,11 @@ shared_examples_for 'vos driver' do
5
5
 
6
6
  describe "shell" do
7
7
  it 'exec' do
8
- @driver.open do |d|
9
- d.exec("echo 'ok'").should == [0, "ok\n", ""]
10
- end
8
+ @driver.exec("echo 'ok'").should == [0, "ok\n", ""]
11
9
  end
12
10
 
13
11
  it 'bash' do
14
- @driver.open do |d|
15
- d.bash("echo 'ok'").should == [0, "ok\n"]
16
- end
12
+ @driver.bash("echo 'ok'").should == [0, "ok\n"]
17
13
  end
18
14
  end
19
15
  end
@@ -3,14 +3,14 @@ require 'net/sftp'
3
3
 
4
4
  module Vos
5
5
  module Drivers
6
- class Ssh < Abstract
6
+ class Ssh
7
7
  DEFAULT_OPTIONS = {
8
8
  config: true
9
9
  }
10
10
 
11
- def initialize options = {}
12
- super
11
+ def initialize options = {}, root = ''
13
12
  raise ":host not provided!" unless options[:host]
13
+ @root = root
14
14
  @options = DEFAULT_OPTIONS.merge options
15
15
 
16
16
  # config_options = Net::SSH.configuration_for(options[:host])
@@ -59,7 +59,6 @@ module Vos
59
59
  # Vfs
60
60
  #
61
61
  include SshVfsStorage
62
- alias_method :open_fs, :open
63
62
 
64
63
 
65
64
  #
@@ -90,7 +89,7 @@ module Vos
90
89
  def host; options[:host] end
91
90
 
92
91
  protected
93
- attr_accessor :ssh, :sftp
92
+ attr_accessor :ssh, :sftp, :options
94
93
 
95
94
  def fix_path path
96
95
  path.sub(/^\~/, home)
@@ -15,22 +15,29 @@ module Vos
15
15
  # Attributes
16
16
  #
17
17
  def attributes path
18
+ path = with_root path
19
+ path = fix_path path
18
20
 
19
- stat = sftp.stat! fix_path(path)
21
+ stat = sftp.stat! path
20
22
  attrs = {}
21
23
  attrs[:file] = stat.file?
22
24
  attrs[:dir] = stat.directory?
23
25
  # stat.symlink?
24
26
 
25
27
  # attributes special for file system
26
- attrs[:updated_at] = stat.mtime
28
+ time = stat.mtime
29
+ attrs[:updated_at] = time && Time.at(time)
30
+ attrs[:size] = stat.size if attrs[:file]
27
31
 
28
32
  attrs
29
33
  rescue Net::SFTP::StatusException
30
- {}
34
+ nil
31
35
  end
32
36
 
33
37
  def set_attributes path, attrs
38
+ path = with_root path
39
+ path = fix_path path
40
+
34
41
  raise 'not supported'
35
42
  end
36
43
 
@@ -38,7 +45,10 @@ module Vos
38
45
  # File
39
46
  #
40
47
  def read_file path, &block
41
- sftp.file.open fix_path(path), 'r' do |is|
48
+ path = with_root path
49
+ path = fix_path path
50
+
51
+ sftp.file.open path, 'r' do |is|
42
52
  while buff = is.gets
43
53
  block.call buff
44
54
  end
@@ -49,15 +59,13 @@ module Vos
49
59
  # there's no support for :append in Net::SFTP, so we just mimic it
50
60
  if append
51
61
  attrs = attributes(path)
52
- data = if attrs
53
- if attrs[:file]
62
+ data = if attrs[:file]
54
63
  os = ""
55
64
  read_file(path){|buff| os << buff}
56
65
  delete_file path
57
66
  os
58
- else
59
- raise "can't append to dir!"
60
- end
67
+ elsif attrs[:dir]
68
+ raise "can't append to dir!"
61
69
  else
62
70
  ''
63
71
  end
@@ -66,14 +74,18 @@ module Vos
66
74
  block.call writer
67
75
  end
68
76
  else
69
- sftp.file.open fix_path(path), 'w' do |out|
77
+ path = with_root path
78
+ path = fix_path path
79
+ sftp.file.open path, 'w' do |out|
70
80
  block.call Writer.new(out)
71
81
  end
72
82
  end
73
83
  end
74
84
 
75
- def delete_file remote_file_path
76
- sftp.remove! fix_path(remote_file_path)
85
+ def delete_file path
86
+ path = with_root path
87
+ path = fix_path path
88
+ sftp.remove! path
77
89
  end
78
90
 
79
91
  # def move_file path
@@ -85,14 +97,21 @@ module Vos
85
97
  # Dir
86
98
  #
87
99
  def create_dir path
100
+ path = with_root path
101
+ path = fix_path path
88
102
  sftp.mkdir! path
89
103
  end
90
104
 
91
105
  def delete_dir path
106
+ path = with_root path
107
+ path = fix_path path
92
108
  exec "rm -r #{path}"
93
109
  end
94
110
 
95
111
  def each_entry path, query, &block
112
+ path = with_root path
113
+ path = fix_path path
114
+
96
115
  raise "SshVfsStorage not support :each_entry with query!" if query
97
116
 
98
117
  sftp.dir.foreach path do |stat|
@@ -127,7 +146,7 @@ module Vos
127
146
  # Special
128
147
  #
129
148
  def tmp &block
130
- tmp_dir = "/tmp/vfs_#{rand(10**3)}"
149
+ tmp_dir = "/tmp_#{rand(10**6)}"
131
150
  if block
132
151
  begin
133
152
  create_dir tmp_dir
@@ -142,6 +161,25 @@ module Vos
142
161
  end
143
162
 
144
163
  def local?; false end
164
+
165
+ def _delete_root_dir
166
+ raise 'refuse to delete / directory!' if root == '/'
167
+ exec "rm -r #{@root}" unless root.empty?
168
+ end
169
+
170
+ def _create_root_dir
171
+ raise 'refuse to create / directory!' if root == '/'
172
+ sftp.mkdir! root unless root.empty?
173
+ end
174
+
175
+ protected
176
+ def root
177
+ @root || raise('root not defined!')
178
+ end
179
+
180
+ def with_root path
181
+ path == '/' ? root : root + path
182
+ end
145
183
  end
146
184
  end
147
185
  end
data/lib/vos.rb CHANGED
@@ -7,7 +7,6 @@ require 'open3'
7
7
  %w(
8
8
  support
9
9
 
10
- drivers/abstract
11
10
  drivers/local
12
11
  drivers/ssh_vfs_storage
13
12
  drivers/ssh
data/readme.md CHANGED
@@ -30,7 +30,7 @@ For more details look also to [Virtual File System][vfs] project.
30
30
  Or checkout configuration I use to control my production servers [My Cluster][my_cluster] in conjunction with small
31
31
  configuration tool [Cluster Management][cluster_management].
32
32
 
33
- ## Please let me know about bugs and Your proposals, there's the 'Issues' tab at the top, feel free to submit.
33
+ ## License
34
34
 
35
35
  Copyright (c) Alexey Petrushin http://petrush.in, released under the MIT license.
36
36
 
File without changes
data/spec/box_spec.rb CHANGED
@@ -1,8 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Vos::Box do
4
+ with_tmp_spec_dir
5
+
4
6
  before do
5
- @box = Vos::Box.new
7
+ storage = Vos::Drivers::Local.new spec_dir
8
+ @box = Vos::Box.new storage
6
9
  @box.stub :puts
7
10
  end
8
11
 
@@ -1,6 +1,13 @@
1
- :ssh:
2
- :host: some_host.com
1
+ :ssh_driver:
2
+ :host: xxx.com
3
3
 
4
4
  # optional, you can omit and use id_rsa key instead
5
5
  # :user: some_user
6
- # :password: some_password
6
+ # :password: some_password
7
+
8
+ :s3:
9
+ :driver:
10
+ :access_key_id: 'xxx'
11
+ :secret_access_key: 'xxx'
12
+
13
+ :bucket: :xxx
data/spec/config.yml CHANGED
@@ -1,2 +1,9 @@
1
1
  :ssh_driver:
2
- :host: universal.4ire.net
2
+ :host: universal.4ire.net
3
+
4
+ :s3:
5
+ :driver:
6
+ :access_key_id: 'AKIAJRX4FEUREBQ6IYTQ'
7
+ :secret_access_key: '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'
8
+
9
+ :bucket: :vostest
File without changes
@@ -1,10 +1,20 @@
1
1
  require 'drivers/spec_helper'
2
2
 
3
3
  describe Vos::Drivers::Local do
4
- it_should_behave_like "vos driver"
5
- it_should_behave_like "vfs storage"
4
+ with_tmp_spec_dir
6
5
 
7
6
  before do
8
- @storage = @driver = Vos::Drivers::Local.new
7
+ @storage = @driver = Vos::Drivers::Local.new(spec_dir)
9
8
  end
9
+
10
+ it_should_behave_like "vos driver"
11
+
12
+ it_should_behave_like 'vfs storage basic'
13
+ it_should_behave_like 'vfs storage attributes basic'
14
+ it_should_behave_like 'vfs storage files'
15
+ it_should_behave_like 'vfs storage full attributes for files'
16
+ it_should_behave_like 'vfs storage dirs'
17
+ it_should_behave_like 'vfs storage full attributes for dirs'
18
+ it_should_behave_like 'vfs storage query'
19
+ it_should_behave_like 'vfs storage tmp dir'
10
20
  end
@@ -0,0 +1,89 @@
1
+ require 'drivers/spec_helper'
2
+
3
+ require 'aws' rescue LoadError
4
+
5
+ if defined? AWS
6
+ require 'vos/drivers/s3'
7
+
8
+ describe 'S3' do
9
+ before :all do
10
+ @storage = Vos::Drivers::S3.new(config[:s3][:driver], bucket: config[:s3][:bucket])
11
+ @storage.open
12
+ end
13
+ after(:all){@storage.close}
14
+
15
+ before{@storage._clear}
16
+ after{@storage._clear}
17
+
18
+ it_should_behave_like 'vfs storage basic'
19
+ it_should_behave_like 'vfs storage attributes basic'
20
+ it_should_behave_like 'vfs storage files'
21
+
22
+ describe 'limited attributes' do
23
+ it "attributes for files" do
24
+ @storage.write_file('/file', false){|w| w.write 'something'}
25
+ attrs = @storage.attributes('/file')
26
+ attrs[:file].should be_true
27
+ attrs[:dir].should be_false
28
+ # attrs[:created_at].class.should == Time
29
+ attrs[:updated_at].class.should == Time
30
+ attrs[:size].should == 9
31
+ end
32
+ end
33
+
34
+ describe 'limited tmp' do
35
+ it "tmp dir" do
36
+ @storage.tmp.should_not be_nil
37
+
38
+ file_path = nil
39
+ @storage.tmp do |tmp_dir|
40
+ file_path = "#{tmp_dir}/file"
41
+ @storage.write_file(file_path, false){|w| w.write 'something'}
42
+ end
43
+ file_path.should_not be_nil
44
+ @storage.attributes(file_path).should be_nil
45
+ end
46
+ end
47
+
48
+ describe 'limited dirs' do
49
+ def create_s3_fake_dir dir
50
+ @storage.write_file("#{dir}/file.txt", false){|w| w.write 'something'}
51
+ end
52
+
53
+ it "directory crud" do
54
+ @storage.attributes('/dir').should be_nil
55
+
56
+ create_s3_fake_dir('/dir')
57
+ attrs = @storage.attributes('/dir')
58
+ attrs[:file].should be_false
59
+ attrs[:dir].should be_true
60
+
61
+ @storage.delete_dir('/dir')
62
+ @storage.attributes('/dir').should be_nil
63
+ end
64
+
65
+ it 'should delete not-empty directories' do
66
+ create_s3_fake_dir('/dir')
67
+ create_s3_fake_dir('/dir/dir2')
68
+ @storage.write_file('/dir/dir2/file', false){|w| w.write 'something'}
69
+ @storage.attributes('/dir').should_not be_nil
70
+
71
+ @storage.delete_dir('/dir')
72
+ @storage.attributes('/dir').should be_nil
73
+ end
74
+
75
+ it 'each' do
76
+ # -> {@storage.each_entry('/not_existing_dir', nil){|path, type| list[path] = type}}.should raise_error
77
+
78
+ create_s3_fake_dir('/dir/dir2')
79
+ @storage.write_file('/dir/file', false){|w| w.write 'something'}
80
+
81
+ list = {}
82
+ @storage.each_entry('/dir', nil){|path, type| list[path] = type}
83
+ list.should == {'dir2' => :dir, 'file' => :file}
84
+ end
85
+ end
86
+ end
87
+ else
88
+ warn 'no aws library, specs will be skipped'
89
+ end
@@ -1,15 +1,48 @@
1
1
  require 'drivers/spec_helper'
2
2
 
3
3
  describe Vos::Drivers::Ssh do
4
- it_should_behave_like "vos driver"
5
- it_should_behave_like "vfs storage"
6
-
7
4
  before :all do
8
- @storage = @driver = Vos::Drivers::Ssh.new(config[:ssh_driver])
5
+ @storage = @driver = Vos::Drivers::Ssh.new(config[:ssh_driver], '/vos_test')
9
6
  @driver.open
10
7
  end
11
8
 
12
9
  after :all do
13
10
  @driver.close
14
11
  end
12
+
13
+ before do
14
+ @driver._delete_root_dir
15
+ @driver._create_root_dir
16
+ end
17
+ after{@driver._delete_root_dir}
18
+
19
+ it_should_behave_like "vos driver"
20
+
21
+ it_should_behave_like 'vfs storage basic'
22
+ it_should_behave_like 'vfs storage attributes basic'
23
+ it_should_behave_like 'vfs storage files'
24
+ it_should_behave_like 'vfs storage dirs'
25
+ it_should_behave_like 'vfs storage tmp dir'
26
+
27
+ describe 'limited ssh attributes' do
28
+ it "attributes for dirs" do
29
+ @storage.create_dir('/dir')
30
+ attrs = @storage.attributes('/dir')
31
+ attrs[:file].should be_false
32
+ attrs[:dir].should be_true
33
+ # attrs[:created_at].class.should == Time
34
+ attrs[:updated_at].class.should == Time
35
+ attrs.should_not include(:size)
36
+ end
37
+
38
+ it "attributes for files" do
39
+ @storage.write_file('/file', false){|w| w.write 'something'}
40
+ attrs = @storage.attributes('/file')
41
+ attrs[:file].should be_true
42
+ attrs[:dir].should be_false
43
+ # attrs[:created_at].class.should == Time
44
+ attrs[:updated_at].class.should == Time
45
+ attrs[:size].should == 9
46
+ end
47
+ end
15
48
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vos
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.13
4
+ version: 0.3.14
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-08-10 00:00:00.000000000Z
12
+ date: 2011-08-25 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: net-ssh
16
- requirement: &363240 !ruby/object:Gem::Requirement
16
+ requirement: &2785270 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *363240
24
+ version_requirements: *2785270
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: net-sftp
27
- requirement: &640270 !ruby/object:Gem::Requirement
27
+ requirement: &2784970 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *640270
35
+ version_requirements: *2784970
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: vfs
38
- requirement: &738060 !ruby/object:Gem::Requirement
38
+ requirement: &2784680 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *738060
46
+ version_requirements: *2784680
47
47
  description:
48
48
  email:
49
49
  executables: []
@@ -57,8 +57,9 @@ files:
57
57
  - lib/vos/box/shell.rb
58
58
  - lib/vos/box/vfs.rb
59
59
  - lib/vos/box.rb
60
- - lib/vos/drivers/abstract.rb
61
60
  - lib/vos/drivers/local.rb
61
+ - lib/vos/drivers/s3.rb
62
+ - lib/vos/drivers/s3_vfs_storage.rb
62
63
  - lib/vos/drivers/specification.rb
63
64
  - lib/vos/drivers/ssh.rb
64
65
  - lib/vos/drivers/ssh_vfs_storage.rb
@@ -66,10 +67,13 @@ files:
66
67
  - lib/vos/helpers/ubuntu.rb
67
68
  - lib/vos/support.rb
68
69
  - lib/vos.rb
70
+ - spec/box_spec/emptygit
69
71
  - spec/box_spec.rb
70
72
  - spec/config.example.yml
71
73
  - spec/config.yml
74
+ - spec/drivers/local_spec/emptygit
72
75
  - spec/drivers/local_spec.rb
76
+ - spec/drivers/s3_spec.rb
73
77
  - spec/drivers/spec_helper.rb
74
78
  - spec/drivers/ssh_spec.rb
75
79
  - spec/spec_helper.rb
@@ -1,11 +0,0 @@
1
- module Vos
2
- module Drivers
3
- class Abstract
4
- attr_reader :options
5
-
6
- def initialize options = {}
7
- @options = options
8
- end
9
- end
10
- end
11
- end