vos 0.0.4 → 0.1.0
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/Rakefile +2 -2
- data/lib/vos/box/marks.rb +31 -0
- data/lib/vos/box/shell.rb +87 -0
- data/lib/vos/box/vfs.rb +43 -0
- data/lib/vos/box.rb +45 -0
- data/lib/{rsh → vos}/drivers/abstract.rb +1 -5
- data/lib/vos/drivers/local.rb +38 -0
- data/lib/vos/drivers/specification.rb +15 -0
- data/lib/vos/drivers/ssh.rb +256 -0
- data/lib/vos/gems.rb +6 -0
- data/lib/vos/helpers/ubuntu.rb +40 -0
- data/lib/{rsh → vos}/support.rb +3 -1
- data/lib/{rsh.rb → vos.rb} +7 -5
- data/readme.md +115 -14
- data/spec/box_spec.rb +37 -90
- data/spec/drivers/local_spec.rb +10 -0
- data/spec/drivers/spec_helper.rb +5 -0
- data/spec/drivers/ssh_spec.rb +15 -0
- data/spec/spec_helper.rb +2 -1
- metadata +33 -21
- data/lib/rsh/box/marks.rb +0 -29
- data/lib/rsh/box.rb +0 -182
- data/lib/rsh/drivers/local.rb +0 -48
- data/lib/rsh/drivers/ssh.rb +0 -147
- data/lib/rsh/gems.rb +0 -2
- data/spec/abstract_driver/dir/dir2/file +0 -0
- data/spec/abstract_driver/local_file +0 -1
- data/spec/abstract_driver.rb +0 -82
- data/spec/box_spec/dir/dir2/file +0 -0
- data/spec/box_spec/local_file +0 -1
- data/spec/local_driver_spec.rb +0 -9
- data/spec/ssh_driver_spec.rb +0 -15
data/Rakefile
CHANGED
@@ -2,8 +2,8 @@ require 'rake_ext'
|
|
2
2
|
|
3
3
|
project(
|
4
4
|
name: "vos",
|
5
|
-
version: "0.0
|
6
|
-
summary: "
|
5
|
+
version: "0.1.0",
|
6
|
+
summary: "Virtual Operating System",
|
7
7
|
|
8
8
|
author: "Alexey Petrushin",
|
9
9
|
homepage: "http://github.com/alexeypetrushin/vos"
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Vos
|
2
|
+
class Box
|
3
|
+
module Marks
|
4
|
+
def mark key
|
5
|
+
ensure_mark_requrements!
|
6
|
+
file("#{marks_dir}/#{key}").create!
|
7
|
+
end
|
8
|
+
|
9
|
+
def has_mark? key
|
10
|
+
ensure_mark_requrements!
|
11
|
+
entry["#{marks_dir}/#{key}"].exist?
|
12
|
+
end
|
13
|
+
|
14
|
+
def clear_marks
|
15
|
+
bash "rm -r #{marks_dir}"
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
def marks_dir
|
20
|
+
home "/.marks"
|
21
|
+
end
|
22
|
+
|
23
|
+
def ensure_mark_requrements!
|
24
|
+
unless @ensure_mark_requrements
|
25
|
+
self.dir(marks_dir).create
|
26
|
+
@ensure_mark_requrements = true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Vos
|
2
|
+
class Box
|
3
|
+
module Shell
|
4
|
+
def bash cmd, *args
|
5
|
+
self['/'].bash cmd, *args
|
6
|
+
end
|
7
|
+
|
8
|
+
def bash_without_path cmd, *args
|
9
|
+
check = args.shift if args.first.is_a?(Regexp)
|
10
|
+
options = args.last || {}
|
11
|
+
|
12
|
+
cmd = env cmd
|
13
|
+
code, stdout_and_stderr = open{driver.bash cmd}
|
14
|
+
|
15
|
+
unless code == 0
|
16
|
+
puts stdout_and_stderr
|
17
|
+
raise "can't execute '#{cmd}'!"
|
18
|
+
end
|
19
|
+
|
20
|
+
if check and (stdout_and_stderr !~ check)
|
21
|
+
puts stdout_and_stderr
|
22
|
+
raise "output not match with #{check.inspect}!"
|
23
|
+
end
|
24
|
+
|
25
|
+
stdout_and_stderr
|
26
|
+
end
|
27
|
+
|
28
|
+
def exec cmd
|
29
|
+
open{driver.exec(env(cmd))}
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_writer :env
|
33
|
+
def env command_or_env_variables = nil, &block
|
34
|
+
@env ||= default_env
|
35
|
+
|
36
|
+
if block
|
37
|
+
before = env.clone
|
38
|
+
begin
|
39
|
+
if variables = command_or_env_variables
|
40
|
+
raise 'invalid arguments' unless variables.is_a? Hash
|
41
|
+
@env.merge! variables
|
42
|
+
end
|
43
|
+
block.call
|
44
|
+
ensure
|
45
|
+
@env = before
|
46
|
+
end
|
47
|
+
else
|
48
|
+
if command_or_env_variables == nil
|
49
|
+
@env
|
50
|
+
elsif command_or_env_variables.is_a? String
|
51
|
+
cmd = command_or_env_variables
|
52
|
+
env_str = env.to_a.collect{|k, v| "#{k}=#{v}"}.join(' ')
|
53
|
+
wrap_cmd env_str, cmd
|
54
|
+
elsif command_or_env_variables.is_a? Hash
|
55
|
+
variables = command_or_env_variables
|
56
|
+
@env.merge! variables
|
57
|
+
else
|
58
|
+
raise 'invalid arguments'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
def default_env
|
63
|
+
{}
|
64
|
+
end
|
65
|
+
def wrap_cmd env_str, cmd
|
66
|
+
%(#{env_str}#{' && ' unless env_str.empty?}#{cmd})
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
def home path = nil
|
71
|
+
open{@home = bash('cd ~; pwd').gsub("\n", '')} unless @home
|
72
|
+
path ? self[@home][path] : self[@home]
|
73
|
+
end
|
74
|
+
|
75
|
+
# def generate_tmp_dir_name
|
76
|
+
# open do
|
77
|
+
# driver.generate_tmp_dir_name
|
78
|
+
# end
|
79
|
+
# end
|
80
|
+
|
81
|
+
# def inspect
|
82
|
+
# "<Box: #{options[:host]}>"
|
83
|
+
# end
|
84
|
+
# alias_method :to_s, :inspect
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/vos/box/vfs.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
module Vos
|
2
|
+
class Box
|
3
|
+
module Vfs
|
4
|
+
def open_fs &block
|
5
|
+
open &block
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_entry
|
9
|
+
'/'.to_entry_on(self)
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_file
|
13
|
+
to_entry.file
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_dir
|
17
|
+
to_entry
|
18
|
+
end
|
19
|
+
|
20
|
+
# def [] path
|
21
|
+
# to_entry[path]
|
22
|
+
# end
|
23
|
+
# alias_method :/, :[]
|
24
|
+
|
25
|
+
%w(dir file entry entries [] / tmp).each do |m|
|
26
|
+
script = <<-RUBY
|
27
|
+
def #{m} *a, &b
|
28
|
+
to_entry.#{m} *a, &b
|
29
|
+
end
|
30
|
+
RUBY
|
31
|
+
eval script, binding, __FILE__, __LINE__
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module Vfs
|
38
|
+
class Dir
|
39
|
+
def bash cmd, *args
|
40
|
+
storage.bash_without_path "cd #{path} && #{cmd}", *args
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/vos/box.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
module Vos
|
2
|
+
class Box
|
3
|
+
include Shell, Marks, Vfs
|
4
|
+
|
5
|
+
attr_accessor :options
|
6
|
+
|
7
|
+
def initialize options = {}
|
8
|
+
@options = options
|
9
|
+
options[:host] ||= 'localhost'
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
#
|
14
|
+
# driver
|
15
|
+
#
|
16
|
+
def driver
|
17
|
+
unless @driver
|
18
|
+
klass = options[:host] == 'localhost' ? Drivers::Local : Drivers::Ssh
|
19
|
+
@driver = klass.new options
|
20
|
+
end
|
21
|
+
@driver
|
22
|
+
end
|
23
|
+
|
24
|
+
def open &block
|
25
|
+
driver.open &block
|
26
|
+
end
|
27
|
+
def close
|
28
|
+
driver.close
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
#
|
33
|
+
# Micelaneous
|
34
|
+
#
|
35
|
+
def inspect
|
36
|
+
host = options[:host]
|
37
|
+
if host == 'localhost'
|
38
|
+
''
|
39
|
+
else
|
40
|
+
host
|
41
|
+
end
|
42
|
+
end
|
43
|
+
alias_method :to_s, :inspect
|
44
|
+
end
|
45
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module Vos
|
2
2
|
module Drivers
|
3
3
|
class Abstract
|
4
4
|
attr_reader :options
|
@@ -6,10 +6,6 @@ module Rsh
|
|
6
6
|
def initialize options = {}
|
7
7
|
@options = options
|
8
8
|
end
|
9
|
-
|
10
|
-
def generate_tmp_dir_name
|
11
|
-
"/tmp/ssh_tmp_dir_#{rand(10**6)}"
|
12
|
-
end
|
13
9
|
end
|
14
10
|
end
|
15
11
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'vfs/storages/local'
|
2
|
+
|
3
|
+
module Vos
|
4
|
+
module Drivers
|
5
|
+
class Local < Abstract
|
6
|
+
#
|
7
|
+
# Vfs
|
8
|
+
#
|
9
|
+
include Vfs::Storages::Local::LocalVfsHelper
|
10
|
+
def open &block
|
11
|
+
block.call self if block
|
12
|
+
end
|
13
|
+
alias_method :open_fs, :open
|
14
|
+
def close; end
|
15
|
+
|
16
|
+
|
17
|
+
#
|
18
|
+
# Shell
|
19
|
+
#
|
20
|
+
def exec command
|
21
|
+
code, stdout, stderr = Open3.popen3 command do |stdin, stdout, stderr, waitth|
|
22
|
+
[waitth.value.to_i, stdout.read, stderr.read]
|
23
|
+
end
|
24
|
+
|
25
|
+
return code, stdout, stderr
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def bash command
|
30
|
+
code, stdout_and_stderr = Open3.popen2e command do |stdin, stdout_and_stderr, wait_thread|
|
31
|
+
[wait_thread.value.to_i, stdout_and_stderr.read]
|
32
|
+
end
|
33
|
+
|
34
|
+
return code, stdout_and_stderr
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
shared_examples_for 'vos driver' do
|
2
|
+
describe "shell" do
|
3
|
+
it 'exec' do
|
4
|
+
@driver.open do |d|
|
5
|
+
d.exec("echo 'ok'").should == [0, "ok\n", ""]
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'bash' do
|
10
|
+
@driver.open do |d|
|
11
|
+
d.bash("echo 'ok'").should == [0, "ok\n"]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,256 @@
|
|
1
|
+
require 'net/ssh'
|
2
|
+
require 'net/sftp'
|
3
|
+
|
4
|
+
module Vos
|
5
|
+
module Drivers
|
6
|
+
class Ssh < Abstract
|
7
|
+
module VfsStorage
|
8
|
+
#
|
9
|
+
# Attributes
|
10
|
+
#
|
11
|
+
def attributes path
|
12
|
+
|
13
|
+
stat = sftp.stat! fix_path(path)
|
14
|
+
attrs = {}
|
15
|
+
attrs[:file] = stat.file?
|
16
|
+
attrs[:dir] = stat.directory?
|
17
|
+
# stat.symlink?
|
18
|
+
attrs
|
19
|
+
rescue Net::SFTP::StatusException
|
20
|
+
{}
|
21
|
+
end
|
22
|
+
|
23
|
+
def set_attributes path, attrs
|
24
|
+
raise 'not supported'
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# File
|
29
|
+
#
|
30
|
+
def read_file path, &block
|
31
|
+
sftp.file.open fix_path(path), 'r' do |is|
|
32
|
+
while buff = is.gets
|
33
|
+
block.call buff
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def write_file path, append, &block
|
39
|
+
# there's no support for :append in Net::SFTP, so we just mimic it
|
40
|
+
if append
|
41
|
+
attrs = attributes(path)
|
42
|
+
data = if attrs
|
43
|
+
if attrs[:file]
|
44
|
+
os = ""
|
45
|
+
read_file(path){|buff| os << buff}
|
46
|
+
delete_file path
|
47
|
+
os
|
48
|
+
else
|
49
|
+
raise "can't append to dir!"
|
50
|
+
end
|
51
|
+
else
|
52
|
+
''
|
53
|
+
end
|
54
|
+
write_file path, false do |writer|
|
55
|
+
writer.call data
|
56
|
+
block.call writer
|
57
|
+
end
|
58
|
+
else
|
59
|
+
sftp.file.open fix_path(path), 'w' do |os|
|
60
|
+
writer = -> buff {os.write buff}
|
61
|
+
block.call writer
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def delete_file remote_file_path
|
67
|
+
sftp.remove! fix_path(remote_file_path)
|
68
|
+
end
|
69
|
+
|
70
|
+
# def move_file path
|
71
|
+
# raise 'not supported'
|
72
|
+
# end
|
73
|
+
|
74
|
+
|
75
|
+
#
|
76
|
+
# Dir
|
77
|
+
#
|
78
|
+
def create_dir path
|
79
|
+
sftp.mkdir! path
|
80
|
+
end
|
81
|
+
|
82
|
+
def delete_dir path
|
83
|
+
exec "rm -r #{path}"
|
84
|
+
end
|
85
|
+
|
86
|
+
def each path, &block
|
87
|
+
sftp.dir.foreach path do |stat|
|
88
|
+
next if stat.name == '.' or stat.name == '..'
|
89
|
+
if stat.directory?
|
90
|
+
block.call stat.name, :dir
|
91
|
+
else
|
92
|
+
block.call stat.name, :file
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def efficient_dir_copy from, to
|
98
|
+
from.storage.open_fs do |from_fs|
|
99
|
+
to.storage.open_fs do |to_fs|
|
100
|
+
if from_fs.local?
|
101
|
+
sftp.upload! from.path, fix_path(to.path)
|
102
|
+
true
|
103
|
+
elsif to_fs.local?
|
104
|
+
sftp.download! fix_path(to.path), from.path, :recursive => true
|
105
|
+
true
|
106
|
+
else
|
107
|
+
false
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# def move_dir path
|
114
|
+
# raise 'not supported'
|
115
|
+
# end
|
116
|
+
|
117
|
+
|
118
|
+
#
|
119
|
+
# Special
|
120
|
+
#
|
121
|
+
def tmp &block
|
122
|
+
tmp_dir = "/tmp/vfs_#{rand(10**3)}"
|
123
|
+
if block
|
124
|
+
begin
|
125
|
+
create_dir tmp_dir
|
126
|
+
block.call tmp_dir
|
127
|
+
ensure
|
128
|
+
delete_dir tmp_dir
|
129
|
+
end
|
130
|
+
else
|
131
|
+
create_dir tmp_dir
|
132
|
+
tmp_dir
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def local?; false end
|
137
|
+
end
|
138
|
+
|
139
|
+
def initialize options = {}
|
140
|
+
super
|
141
|
+
raise "ssh options not provided!" unless options[:ssh]
|
142
|
+
raise "invalid ssh options!" unless options[:ssh].is_a?(Hash)
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
#
|
147
|
+
# Establishing SSH channel
|
148
|
+
#
|
149
|
+
def open &block
|
150
|
+
if block
|
151
|
+
if @ssh
|
152
|
+
block.call self
|
153
|
+
else
|
154
|
+
begin
|
155
|
+
open
|
156
|
+
block.call self
|
157
|
+
ensure
|
158
|
+
close
|
159
|
+
end
|
160
|
+
end
|
161
|
+
else
|
162
|
+
unless @ssh
|
163
|
+
ssh_options = self.options[:ssh].clone
|
164
|
+
host = options[:host] || raise('host not provided!')
|
165
|
+
user = ssh_options.delete(:user) || raise('user not provied!')
|
166
|
+
@ssh = Net::SSH.start(host, user, ssh_options)
|
167
|
+
@sftp = @ssh.sftp.connect
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def close
|
173
|
+
if @ssh
|
174
|
+
@ssh.close
|
175
|
+
# @sftp.close not needed
|
176
|
+
@ssh, @sftp = nil
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def to_s; options[:host] end
|
181
|
+
|
182
|
+
|
183
|
+
#
|
184
|
+
# Vfs
|
185
|
+
#
|
186
|
+
include VfsStorage
|
187
|
+
alias_method :open_fs, :open
|
188
|
+
|
189
|
+
|
190
|
+
#
|
191
|
+
# Shell
|
192
|
+
#
|
193
|
+
def exec command
|
194
|
+
# somehow net-ssh doesn't executes ~/.profile, so we need to execute it manually
|
195
|
+
# command = ". ~/.profile && #{command}"
|
196
|
+
|
197
|
+
stdout, stderr, code, signal = hacked_exec! ssh, command
|
198
|
+
|
199
|
+
return code, stdout, stderr
|
200
|
+
end
|
201
|
+
|
202
|
+
def bash command
|
203
|
+
# somehow net-ssh doesn't executes ~/.profile, so we need to execute it manually
|
204
|
+
# command = ". ~/.profile && #{command}"
|
205
|
+
|
206
|
+
stdout_and_stderr, stderr, code, signal = hacked_exec! ssh, command, true
|
207
|
+
|
208
|
+
return code, stdout_and_stderr
|
209
|
+
end
|
210
|
+
|
211
|
+
|
212
|
+
protected
|
213
|
+
attr_accessor :ssh, :sftp
|
214
|
+
|
215
|
+
def fix_path path
|
216
|
+
path.sub(/^\~/, home)
|
217
|
+
end
|
218
|
+
|
219
|
+
def home
|
220
|
+
unless @home
|
221
|
+
command = 'cd ~; pwd'
|
222
|
+
code, stdout, stderr = exec command
|
223
|
+
raise "can't execute '#{command}'!" unless code == 0
|
224
|
+
@home = stdout.gsub("\n", '')
|
225
|
+
end
|
226
|
+
@home
|
227
|
+
end
|
228
|
+
|
229
|
+
# taken from here http://stackoverflow.com/questions/3386233/how-to-get-exit-status-with-rubys-netssh-library/3386375#3386375
|
230
|
+
def hacked_exec!(ssh, command, merge_stdout_and_stderr = false, &block)
|
231
|
+
stdout_data = ""
|
232
|
+
stderr_data = ""
|
233
|
+
exit_code = nil
|
234
|
+
exit_signal = nil
|
235
|
+
|
236
|
+
channel = ssh.open_channel do |channel|
|
237
|
+
channel.exec(command) do |ch, success|
|
238
|
+
raise "could not execute command: #{command.inspect}" unless success
|
239
|
+
|
240
|
+
channel.on_data{|ch2, data| stdout_data << data}
|
241
|
+
channel.on_extended_data do |ch2, type, data|
|
242
|
+
stdout_data << data if merge_stdout_and_stderr
|
243
|
+
stderr_data << data
|
244
|
+
end
|
245
|
+
channel.on_request("exit-status"){|ch,data| exit_code = data.read_long}
|
246
|
+
channel.on_request("exit-signal"){|ch, data| exit_signal = data.read_long}
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
channel.wait
|
251
|
+
|
252
|
+
[stdout_data, stderr_data, exit_code, exit_signal]
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
data/lib/vos/gems.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
module Vos
|
2
|
+
module Helpers
|
3
|
+
module Ubuntu
|
4
|
+
def default_env
|
5
|
+
{:DEBIAN_FRONTEND => 'noninteractive'}
|
6
|
+
end
|
7
|
+
def wrap_cmd env_str, cmd
|
8
|
+
%(. #{env_file.path} && #{env_str}#{' && ' unless env_str.empty?}#{cmd})
|
9
|
+
end
|
10
|
+
|
11
|
+
def env_file
|
12
|
+
file '/etc/profile' ## file '/etc/environment'
|
13
|
+
end
|
14
|
+
|
15
|
+
def append_to_environment file, reload = true
|
16
|
+
raise "#{file} must be an Entry" unless file.is_a? Vfs::Entry
|
17
|
+
|
18
|
+
env_ext = dir '/etc/profile_ext'
|
19
|
+
|
20
|
+
remote_file = env_ext[file.name]
|
21
|
+
file.copy_to! remote_file
|
22
|
+
|
23
|
+
require_clause = "source #{remote_file.path}"
|
24
|
+
env_file.append "\n#{require_clause}\n" unless env_file.content.include? require_clause
|
25
|
+
|
26
|
+
reload_env if reload
|
27
|
+
end
|
28
|
+
|
29
|
+
def reload_env
|
30
|
+
bash ". #{env_file.path}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
module Vfs
|
37
|
+
class File
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
data/lib/{rsh → vos}/support.rb
RENAMED
@@ -2,6 +2,8 @@ require 'fileutils'
|
|
2
2
|
require 'net/ssh'
|
3
3
|
require 'net/sftp'
|
4
4
|
|
5
|
+
require 'vfs'
|
6
|
+
|
5
7
|
# class File
|
6
8
|
# class << self
|
7
9
|
# def ensure_dir_exist directory, options = {}
|
@@ -23,7 +25,7 @@ require 'net/sftp'
|
|
23
25
|
# FileUtils.cp_r from, to
|
24
26
|
# end
|
25
27
|
#
|
26
|
-
# def
|
28
|
+
# def delete_dir dir
|
27
29
|
# FileUtils.rm_r dir
|
28
30
|
# end
|
29
31
|
# end
|
data/lib/{rsh.rb → vos.rb}
RENAMED
@@ -1,11 +1,9 @@
|
|
1
1
|
raise 'ruby 1.9.2 or higher required!' if RUBY_VERSION < '1.9.2'
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'vos/gems'
|
4
4
|
|
5
5
|
require 'open3'
|
6
6
|
|
7
|
-
require 'net/ssh'
|
8
|
-
require 'net/sftp'
|
9
7
|
|
10
8
|
%w(
|
11
9
|
support
|
@@ -14,6 +12,10 @@ require 'net/sftp'
|
|
14
12
|
drivers/local
|
15
13
|
drivers/ssh
|
16
14
|
|
17
|
-
box/
|
15
|
+
box/shell
|
16
|
+
box/marks
|
17
|
+
box/vfs
|
18
18
|
box
|
19
|
-
|
19
|
+
|
20
|
+
helpers/ubuntu
|
21
|
+
).each{|f| require "vos/#{f}"}
|