vfs 0.0.4
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 +10 -0
- data/lib/old/ssh.rb +11 -0
- data/lib/rsh/box/marks.rb +29 -0
- data/lib/rsh/box.rb +182 -0
- data/lib/rsh/drivers/abstract.rb +15 -0
- data/lib/rsh/drivers/local.rb +48 -0
- data/lib/rsh/drivers/ssh.rb +147 -0
- data/lib/rsh/gems.rb +2 -0
- data/lib/rsh/support.rb +30 -0
- data/lib/rsh.rb +19 -0
- data/readme.md +21 -0
- data/spec/abstract_driver/dir/dir2/file +0 -0
- data/spec/abstract_driver/local_file +1 -0
- data/spec/abstract_driver.rb +82 -0
- data/spec/box_spec/dir/dir2/file +0 -0
- data/spec/box_spec/local_file +1 -0
- data/spec/box_spec.rb +109 -0
- data/spec/config.example.yml +4 -0
- data/spec/config.yml +5 -0
- data/spec/local_driver_spec.rb +9 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/ssh_driver_spec.rb +15 -0
- metadata +85 -0
data/Rakefile
ADDED
data/lib/old/ssh.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module Rsh
|
2
|
+
module Marks
|
3
|
+
def mark key
|
4
|
+
ensure_mark_requrements!
|
5
|
+
bash "touch #{marks_dir}/#{key}"
|
6
|
+
end
|
7
|
+
|
8
|
+
def has_mark? key
|
9
|
+
ensure_mark_requrements!
|
10
|
+
file_exist? "#{marks_dir}/#{key}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def clear_marks
|
14
|
+
bash "rm -r #{marks_dir}"
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
def marks_dir
|
19
|
+
home "/.marks"
|
20
|
+
end
|
21
|
+
|
22
|
+
def ensure_mark_requrements!
|
23
|
+
unless @ensure_mark_requrements
|
24
|
+
create_directory marks_dir unless directory_exist? marks_dir
|
25
|
+
@ensure_mark_requrements = true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/rsh/box.rb
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
module Rsh
|
2
|
+
class Box
|
3
|
+
include Marks
|
4
|
+
|
5
|
+
attr_accessor :options
|
6
|
+
|
7
|
+
def initialize options = {}
|
8
|
+
@options = options
|
9
|
+
options[:host] ||= 'localhost'
|
10
|
+
end
|
11
|
+
|
12
|
+
def driver
|
13
|
+
unless @driver
|
14
|
+
klass = options[:host] == 'localhost' ? Drivers::Local : Drivers::Ssh
|
15
|
+
@driver = klass.new options
|
16
|
+
end
|
17
|
+
@driver
|
18
|
+
end
|
19
|
+
|
20
|
+
def local_driver
|
21
|
+
@local_driver ||= Drivers::Local.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def bulk &b
|
25
|
+
driver.bulk &b
|
26
|
+
end
|
27
|
+
|
28
|
+
def upload_file from_local_path, to_remote_path, options = {}
|
29
|
+
bulk do
|
30
|
+
raise "file '#{from_local_path}' not exists!" unless local_driver.file_exist? from_local_path
|
31
|
+
if driver.file_exist?(to_remote_path)
|
32
|
+
if options[:override]
|
33
|
+
driver.remove_file to_remote_path
|
34
|
+
else
|
35
|
+
raise "file '#{to_remote_path}' already exists!"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
driver.upload_file from_local_path, to_remote_path
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def download_file from_remote_path, to_local_path, options = {}
|
43
|
+
bulk do
|
44
|
+
raise "file #{from_remote_path} not exists!" unless driver.file_exist?(from_remote_path)
|
45
|
+
if local_driver.file_exist? to_local_path
|
46
|
+
if options[:override]
|
47
|
+
local_driver.remove_file to_local_path
|
48
|
+
else
|
49
|
+
raise "file #{to_local_path} already exists!"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
driver.download_file from_remote_path, to_local_path
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def remove_file remote_file_path, options = {}
|
57
|
+
bulk do
|
58
|
+
if driver.file_exist? remote_file_path
|
59
|
+
driver.remove_file remote_file_path
|
60
|
+
else
|
61
|
+
raise "file #{remote_file_path} not exists!" unless options[:silent]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def exist? remote_path
|
67
|
+
driver.exist? remote_path
|
68
|
+
end
|
69
|
+
|
70
|
+
def file_exist? remote_file_path
|
71
|
+
driver.file_exist? remote_file_path
|
72
|
+
end
|
73
|
+
|
74
|
+
def remove_directory remote_directory_path, options = {}
|
75
|
+
bulk do
|
76
|
+
if driver.directory_exist? remote_directory_path
|
77
|
+
driver.remove_directory remote_directory_path
|
78
|
+
else
|
79
|
+
raise "directory #{remote_directory_path} not exists!" unless options[:silent]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def create_directory remote_path, options = {}
|
85
|
+
bulk do
|
86
|
+
if driver.directory_exist?(remote_path)
|
87
|
+
if options[:override]
|
88
|
+
driver.remove_directory remote_path
|
89
|
+
driver.create_directory remote_path
|
90
|
+
elsif options[:silent]
|
91
|
+
# do nothing
|
92
|
+
else
|
93
|
+
raise "directory '#{remote_path}' already exists!"
|
94
|
+
end
|
95
|
+
else
|
96
|
+
driver.create_directory remote_path
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def directory_exist? remote_path
|
102
|
+
driver.directory_exist? remote_path
|
103
|
+
end
|
104
|
+
|
105
|
+
def upload_directory from_local_path, to_remote_path, options = {}
|
106
|
+
bulk do
|
107
|
+
raise "directory '#{from_local_path}' not exists!" unless local_driver.directory_exist? from_local_path
|
108
|
+
if driver.directory_exist?(to_remote_path)
|
109
|
+
if options[:override]
|
110
|
+
driver.remove_directory to_remote_path
|
111
|
+
else
|
112
|
+
raise "directory '#{to_remote_path}' already exists!"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
driver.upload_directory from_local_path, to_remote_path
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def download_directory from_remote_path, to_local_path, options = {}
|
120
|
+
bulk do
|
121
|
+
raise "directory #{from_remote_path} not exists!" unless driver.directory_exist?(from_remote_path)
|
122
|
+
if local_driver.directory_exist? to_local_path
|
123
|
+
if options[:override]
|
124
|
+
local_driver.remove_directory to_local_path
|
125
|
+
else
|
126
|
+
raise "directory #{to_local_path} already exists!"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
driver.download_directory from_remote_path, to_local_path
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def with_tmp_dir &block
|
134
|
+
bulk do
|
135
|
+
tmp_dir = driver.generate_tmp_dir_name
|
136
|
+
begin
|
137
|
+
remove_directory tmp_dir if directory_exist? tmp_dir
|
138
|
+
create_directory tmp_dir
|
139
|
+
block.call
|
140
|
+
ensure
|
141
|
+
remove_directory tmp_dir if directory_exist? tmp_dir
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def bash cmd, options = {}
|
147
|
+
ignore_stderr = options.delete :ignore_stderr
|
148
|
+
raise "invalid options :#{options.keys.join(', :')}" unless options.empty?
|
149
|
+
|
150
|
+
code, stdout, stderr = exec cmd
|
151
|
+
unless code == 0
|
152
|
+
puts stdout
|
153
|
+
puts stderr
|
154
|
+
raise "can't execute '#{cmd}'!"
|
155
|
+
end
|
156
|
+
unless stderr.empty? or ignore_stderr
|
157
|
+
puts stderr
|
158
|
+
raise "stderr not empty for '#{cmd}'!"
|
159
|
+
end
|
160
|
+
stdout + stderr
|
161
|
+
end
|
162
|
+
|
163
|
+
def exec cmd
|
164
|
+
driver.exec cmd
|
165
|
+
end
|
166
|
+
|
167
|
+
def home path = nil
|
168
|
+
@home ||= bash('cd ~; pwd').gsub("\n", '')
|
169
|
+
"#{@home}#{path}"
|
170
|
+
end
|
171
|
+
|
172
|
+
def inspect
|
173
|
+
"<Box: #{options[:host]}>"
|
174
|
+
end
|
175
|
+
alias_method :to_s, :inspect
|
176
|
+
|
177
|
+
protected
|
178
|
+
def method_missing m, *a, &b
|
179
|
+
driver.send m, *a, &b
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Rsh
|
2
|
+
module Drivers
|
3
|
+
class Local < Abstract
|
4
|
+
def upload_file from_local_path, to_remote_path
|
5
|
+
FileUtils.copy from_local_path, to_remote_path
|
6
|
+
end
|
7
|
+
|
8
|
+
def download_file from_remote_path, to_local_path
|
9
|
+
FileUtils.copy from_remote_path, to_local_path
|
10
|
+
end
|
11
|
+
|
12
|
+
def exist? remote_file_path
|
13
|
+
File.exist? remote_file_path
|
14
|
+
end
|
15
|
+
|
16
|
+
alias_method :directory_exist?, :exist?
|
17
|
+
alias_method :file_exist?, :exist?
|
18
|
+
|
19
|
+
def remove_file remote_file_path
|
20
|
+
File.delete remote_file_path
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_directory path
|
24
|
+
Dir.mkdir path
|
25
|
+
end
|
26
|
+
|
27
|
+
def remove_directory path
|
28
|
+
FileUtils.rm_r path
|
29
|
+
end
|
30
|
+
|
31
|
+
def upload_directory from_local_path, to_remote_path
|
32
|
+
FileUtils.cp_r from_local_path, to_remote_path
|
33
|
+
end
|
34
|
+
|
35
|
+
def download_directory from_remote_path, to_local_path
|
36
|
+
FileUtils.cp_r from_remote_path, to_local_path
|
37
|
+
end
|
38
|
+
|
39
|
+
def exec command
|
40
|
+
code, stdout, stderr = Open3.popen3 command do |stdin, stdout, stderr, waitth|
|
41
|
+
[waitth.value.to_i, stdout.read, stderr.read]
|
42
|
+
end
|
43
|
+
|
44
|
+
return code, stdout, stderr
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
module Rsh
|
2
|
+
module Drivers
|
3
|
+
class Ssh < Abstract
|
4
|
+
def initialize options = {}
|
5
|
+
super
|
6
|
+
raise "ssh options not provided!" unless options[:ssh]
|
7
|
+
raise "invalid ssh options!" unless options[:ssh].is_a?(Hash)
|
8
|
+
end
|
9
|
+
|
10
|
+
def upload_file from_local_path, to_remote_path
|
11
|
+
sftp.upload! from_local_path, fix_path(to_remote_path)
|
12
|
+
end
|
13
|
+
|
14
|
+
def download_file from_remote_path, to_local_path
|
15
|
+
File.open to_local_path, "w" do |out|
|
16
|
+
sftp.download! fix_path(from_remote_path), out #, :recursive => true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def exist? remote_file_path
|
21
|
+
begin
|
22
|
+
fattrs = sftp.stat! fix_path(remote_file_path)
|
23
|
+
fattrs.directory? or fattrs.file? or fattrs.symlink?
|
24
|
+
rescue Net::SFTP::StatusException
|
25
|
+
false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
alias_method :directory_exist?, :exist?
|
29
|
+
alias_method :file_exist?, :exist?
|
30
|
+
|
31
|
+
def remove_file remote_file_path
|
32
|
+
sftp.remove! fix_path(remote_file_path)
|
33
|
+
end
|
34
|
+
|
35
|
+
def exec command
|
36
|
+
remote do |ssh, sftp|
|
37
|
+
# somehow net-ssh doesn't executes ~/.profile, so we need to execute it manually
|
38
|
+
# command = ". ~/.profile && #{command}"
|
39
|
+
|
40
|
+
stdout, stderr, code, signal = hacked_exec! ssh, command
|
41
|
+
|
42
|
+
return code, stdout, stderr
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def open
|
47
|
+
ssh_options = self.options[:ssh].clone
|
48
|
+
host = options[:host] || raise('host not provided!')
|
49
|
+
user = ssh_options.delete(:user) || raise('user not provied!')
|
50
|
+
@ssh = Net::SSH.start(host, user, ssh_options)
|
51
|
+
@sftp = @ssh.sftp.connect
|
52
|
+
end
|
53
|
+
|
54
|
+
def close
|
55
|
+
@ssh.close
|
56
|
+
# @sftp.close not needed
|
57
|
+
@ssh, @sftp = nil
|
58
|
+
end
|
59
|
+
|
60
|
+
def create_directory path
|
61
|
+
remote do |ssh, sftp|
|
62
|
+
sftp.mkdir! path
|
63
|
+
# exec "mkdir #{path}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def remove_directory path
|
68
|
+
exec "rm -r #{path}"
|
69
|
+
end
|
70
|
+
|
71
|
+
def upload_directory from_local_path, to_remote_path
|
72
|
+
remote do |ssh, sftp|
|
73
|
+
sftp.upload! from_local_path, fix_path(to_remote_path)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def download_directory from_remote_path, to_local_path
|
78
|
+
remote do |ssh, sftp|
|
79
|
+
sftp.download! fix_path(from_remote_path), to_local_path, :recursive => true
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
protected
|
84
|
+
def fix_path path
|
85
|
+
path.sub(/^\~/, home)
|
86
|
+
end
|
87
|
+
|
88
|
+
def home
|
89
|
+
unless @home
|
90
|
+
command = 'cd ~; pwd'
|
91
|
+
code, stdout, stderr = exec command
|
92
|
+
raise "can't execute '#{command}'!" unless code == 0
|
93
|
+
@home = stdout.gsub("\n", '')
|
94
|
+
end
|
95
|
+
@home
|
96
|
+
end
|
97
|
+
|
98
|
+
# taken from here http://stackoverflow.com/questions/3386233/how-to-get-exit-status-with-rubys-netssh-library/3386375#3386375
|
99
|
+
def hacked_exec!(ssh, command, &block)
|
100
|
+
stdout_data = ""
|
101
|
+
stderr_data = ""
|
102
|
+
exit_code = nil
|
103
|
+
exit_signal = nil
|
104
|
+
|
105
|
+
channel = ssh.open_channel do |channel|
|
106
|
+
channel.exec(command) do |ch, success|
|
107
|
+
raise "could not execute command: #{command.inspect}" unless success
|
108
|
+
|
109
|
+
channel.on_data{|ch2, data| stdout_data << data}
|
110
|
+
channel.on_extended_data{|ch2, type, data| stderr_data << data}
|
111
|
+
channel.on_request("exit-status"){|ch,data| exit_code = data.read_long}
|
112
|
+
channel.on_request("exit-signal"){|ch, data| exit_signal = data.read_long}
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
channel.wait
|
117
|
+
|
118
|
+
[stdout_data, stderr_data, exit_code, exit_signal]
|
119
|
+
end
|
120
|
+
|
121
|
+
def remote(&block)
|
122
|
+
if @ssh
|
123
|
+
block.call @ssh, @sftp
|
124
|
+
else
|
125
|
+
# Rails.logger.info "Connecting to remote Hadoop #{options[:user]}@#{options[:host]}"
|
126
|
+
begin
|
127
|
+
open
|
128
|
+
block.call @ssh, @sftp
|
129
|
+
ensure
|
130
|
+
close
|
131
|
+
end
|
132
|
+
|
133
|
+
# Net::SSH.start options[:host], options[:user], :config => true do |ssh|
|
134
|
+
# ssh.sftp.connect do |sftp|
|
135
|
+
# begin
|
136
|
+
# @ssh, @sftp = ssh, sftp
|
137
|
+
# block.call @ssh, @sftp
|
138
|
+
# ensure
|
139
|
+
# @ssh, @sftp = nil
|
140
|
+
# end
|
141
|
+
# end
|
142
|
+
# end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
data/lib/rsh/gems.rb
ADDED
data/lib/rsh/support.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'net/ssh'
|
3
|
+
require 'net/sftp'
|
4
|
+
|
5
|
+
# class File
|
6
|
+
# class << self
|
7
|
+
# def ensure_dir_exist directory, options = {}
|
8
|
+
# options = options.symbolize_keys
|
9
|
+
# clean = options.delete :clean
|
10
|
+
# raise "unsupported options #{options.keys}!" unless options.empty?
|
11
|
+
#
|
12
|
+
# FileUtils.rm_r directory, :force => true if clean and File.exist?(directory)
|
13
|
+
# FileUtils.mkdir_p directory
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# def copy_dir_content from, to
|
17
|
+
# Dir.glob "#{from}/*" do |item|
|
18
|
+
# FileUtils.cp_r item, to
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# def copy_dir from, to
|
23
|
+
# FileUtils.cp_r from, to
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# def remove_dir dir
|
27
|
+
# FileUtils.rm_r dir
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
# end
|
data/lib/rsh.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
raise 'ruby 1.9.2 or higher required!' if RUBY_VERSION < '1.9.2'
|
2
|
+
|
3
|
+
require 'rsh/gems'
|
4
|
+
|
5
|
+
require 'open3'
|
6
|
+
|
7
|
+
require 'net/ssh'
|
8
|
+
require 'net/sftp'
|
9
|
+
|
10
|
+
%w(
|
11
|
+
support
|
12
|
+
|
13
|
+
drivers/abstract
|
14
|
+
drivers/local
|
15
|
+
drivers/ssh
|
16
|
+
|
17
|
+
box/marks
|
18
|
+
box
|
19
|
+
).each{|f| require "rsh/#{f}"}
|
data/readme.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Rsh - Tiny wrapper over Net::SSH/SFTP
|
2
|
+
|
3
|
+
Because they are too hard to use and have terrible API design.
|
4
|
+
|
5
|
+
box = Rsh::Box.new host: 'webapp.com', ssh: {user: 'root', password: 'secret'}
|
6
|
+
|
7
|
+
box.upload_directory '/my_project', '/apps/my_project'
|
8
|
+
box.bash 'nohup /apps/my_project/server_start'
|
9
|
+
|
10
|
+
Honestly my wrapper also not very good. I would like to make API looks like the ['rush'][rush] gem (made by Adam Wiggins)
|
11
|
+
but it requires a lots of time, maybe I'll do it later.
|
12
|
+
So, for now it's just a small wrapper to do ssh/io operations not so painfull.
|
13
|
+
|
14
|
+
## TODO
|
15
|
+
|
16
|
+
- remove ssh.remote and use only open/close
|
17
|
+
- introduce Entity/Dir/File (the same as in Rush)
|
18
|
+
- allow to move files between any Boxes, not only between local and remote.
|
19
|
+
- add support for moving dirs.
|
20
|
+
|
21
|
+
[rush]: http://github.com/adamwiggins/rush
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
some content
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples_for 'abstract driver' do
|
4
|
+
dir = "#{File.dirname __FILE__}/abstract_driver"
|
5
|
+
with_tmp_spec_dir dir, before: :each
|
6
|
+
|
7
|
+
describe "io" do
|
8
|
+
before :each do
|
9
|
+
@local_dir = spec_dir
|
10
|
+
@remote_dir = @driver.generate_tmp_dir_name
|
11
|
+
|
12
|
+
@driver.remove_directory @remote_dir if @driver.directory_exist? @remote_dir
|
13
|
+
@driver.create_directory @remote_dir
|
14
|
+
end
|
15
|
+
|
16
|
+
after :each do
|
17
|
+
@driver.remove_directory @remote_dir if @driver.directory_exist? @remote_dir
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "files" do
|
21
|
+
before :each do
|
22
|
+
@local_file = "#{@local_dir}/local_file"
|
23
|
+
@check_file = "#{@local_dir}/check_file"
|
24
|
+
@remote_file = "#{@remote_dir}/remote_file"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "file_exist?" do
|
28
|
+
@driver.file_exist?(@remote_file).should be_false
|
29
|
+
@driver.upload_file(@local_file, @remote_file)
|
30
|
+
@driver.file_exist?(@remote_file).should be_true
|
31
|
+
end
|
32
|
+
|
33
|
+
it "upload & download file" do
|
34
|
+
@driver.upload_file(@local_file, @remote_file)
|
35
|
+
@driver.file_exist?(@remote_file).should be_true
|
36
|
+
|
37
|
+
@driver.download_file(@remote_file, @check_file)
|
38
|
+
File.read(@local_file).should == File.read(@check_file)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "remove_file" do
|
42
|
+
@driver.upload_file(@local_file, @remote_file)
|
43
|
+
@driver.file_exist?(@remote_file).should be_true
|
44
|
+
@driver.remove_file(@remote_file)
|
45
|
+
@driver.file_exist?(@remote_file).should be_false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'directories' do
|
50
|
+
before :each do
|
51
|
+
@from_local, @remote_path, @to_local = "#{@local_dir}/dir", "#{@remote_dir}/upload", "#{@local_dir}/download"
|
52
|
+
end
|
53
|
+
|
54
|
+
it "directory_exist?, create_directory, remove_directory" do
|
55
|
+
dir = "#{@remote_dir}/some_dir"
|
56
|
+
@driver.directory_exist?(dir).should be_false
|
57
|
+
@driver.create_directory(dir)
|
58
|
+
@driver.directory_exist?(dir).should be_true
|
59
|
+
@driver.remove_directory(dir)
|
60
|
+
@driver.directory_exist?(dir).should be_false
|
61
|
+
end
|
62
|
+
|
63
|
+
it "upload_directory & download_directory" do
|
64
|
+
upload_path_check = "#{@remote_path}/dir2/file"
|
65
|
+
@driver.file_exist?(upload_path_check).should be_false
|
66
|
+
@driver.upload_directory(@from_local, @remote_path)
|
67
|
+
@driver.file_exist?(upload_path_check).should be_true
|
68
|
+
|
69
|
+
download_path_check = "#{@to_local}/dir2/file"
|
70
|
+
File.exist?(download_path_check).should be_false
|
71
|
+
@driver.download_directory(@remote_path, @to_local)
|
72
|
+
File.exist?(download_path_check).should be_true
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "shell" do
|
78
|
+
it 'exec' do
|
79
|
+
@driver.exec("echo 'ok'").should == [0, "ok\n", ""]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
some content
|
data/spec/box_spec.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rsh::Box do
|
4
|
+
with_tmp_spec_dir before: :each
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
@box = Rsh::Box.new
|
8
|
+
|
9
|
+
@local_dir = spec_dir
|
10
|
+
@remote_dir = @box.generate_tmp_dir_name
|
11
|
+
|
12
|
+
@box.remove_directory @remote_dir if @box.directory_exist? @remote_dir
|
13
|
+
@box.create_directory @remote_dir
|
14
|
+
end
|
15
|
+
|
16
|
+
after :each do
|
17
|
+
@box.remove_directory @remote_dir if @box.directory_exist? @remote_dir
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "io" do
|
21
|
+
describe "files" do
|
22
|
+
before :each do
|
23
|
+
@local_file = "#{@local_dir}/local_file"
|
24
|
+
@check_file = "#{@local_dir}/check_file"
|
25
|
+
@remote_file = "#{@remote_dir}/remote_file"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "file_exist?" do
|
29
|
+
@box.file_exist?(@remote_file).should be_false
|
30
|
+
@box.upload_file(@local_file, @remote_file)
|
31
|
+
@box.file_exist?(@remote_file).should be_true
|
32
|
+
end
|
33
|
+
|
34
|
+
it "upload_file" do
|
35
|
+
@box.upload_file(@local_file, @remote_file)
|
36
|
+
@box.file_exist?(@remote_file).should be_true
|
37
|
+
|
38
|
+
lambda{@box.upload_file(@local_file, @remote_file)}.should raise_error(/exists/)
|
39
|
+
|
40
|
+
# upload with override
|
41
|
+
@box.upload_file(@local_file, @remote_file, override: true)
|
42
|
+
@box.file_exist?(@remote_file).should be_true
|
43
|
+
end
|
44
|
+
|
45
|
+
it "download_file" do
|
46
|
+
lambda{@box.download_file(@remote_file, @check_file)}.should raise_error(/not exists/)
|
47
|
+
@box.upload_file(@local_file, @remote_file)
|
48
|
+
@box.download_file(@remote_file, @check_file)
|
49
|
+
File.read(@local_file).should == File.read(@check_file)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "remove_file" do
|
53
|
+
lambda{@box.remove_file(@remote_file)}.should raise_error(/not exists/)
|
54
|
+
@box.upload_file(@local_file, @remote_file)
|
55
|
+
@box.file_exist?(@remote_file).should be_true
|
56
|
+
@box.remove_file(@remote_file)
|
57
|
+
@box.file_exist?(@remote_file).should be_false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe 'directories' do
|
62
|
+
before :each do
|
63
|
+
@from_local, @remote_path, @to_local = "#{@local_dir}/dir", "#{@remote_dir}/upload", "#{@local_dir}/download"
|
64
|
+
end
|
65
|
+
|
66
|
+
it "directory_exist?" do
|
67
|
+
@box.file_exist?(@remote_path).should be_false
|
68
|
+
@box.upload_directory(@from_local, @remote_path)
|
69
|
+
@box.file_exist?(@remote_path).should be_true
|
70
|
+
end
|
71
|
+
|
72
|
+
it "upload_directory" do
|
73
|
+
@box.upload_directory(@from_local, @remote_path)
|
74
|
+
@box.directory_exist?(@remote_path).should be_true
|
75
|
+
|
76
|
+
lambda{@box.upload_directory(@from_local, @remote_path)}.should raise_error(/exists/)
|
77
|
+
|
78
|
+
# upload with override
|
79
|
+
@box.upload_directory(@from_local, @remote_path, override: true)
|
80
|
+
@box.directory_exist?(@remote_path).should be_true
|
81
|
+
end
|
82
|
+
|
83
|
+
it "download_directory" do
|
84
|
+
lambda{@box.download_directory(@remote_path, @to_local)}.should raise_error(/not exists/)
|
85
|
+
@box.upload_directory(@from_local, @remote_path)
|
86
|
+
@box.download_directory(@remote_path, @to_local)
|
87
|
+
File.exist?("#{@to_local}/dir2/file").should be_true
|
88
|
+
end
|
89
|
+
|
90
|
+
it "remove_directory" do
|
91
|
+
lambda{@box.remove_directory(@remote_path)}.should raise_error(/not exists/)
|
92
|
+
@box.upload_directory(@from_local, @remote_path)
|
93
|
+
@box.directory_exist?(@remote_path).should be_true
|
94
|
+
@box.remove_directory(@remote_path)
|
95
|
+
@box.directory_exist?(@remote_path).should be_false
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "shell" do
|
101
|
+
it 'bash' do
|
102
|
+
@box.bash("echo 'ok'").should == "ok\n"
|
103
|
+
end
|
104
|
+
|
105
|
+
it "exec" do
|
106
|
+
@box.exec("echo 'ok'").should == [0, "ok\n", ""]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
data/spec/config.yml
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rspec_ext'
|
2
|
+
require 'rsh'
|
3
|
+
|
4
|
+
rspec do
|
5
|
+
def config
|
6
|
+
dir = File.dirname __FILE__
|
7
|
+
config_file_path = "#{dir}/config.yml"
|
8
|
+
raise "no config '#{config_file_path}'!" unless File.exist? config_file_path
|
9
|
+
@config ||= YAML.load_file config_file_path
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'abstract_driver'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
describe Rsh::Drivers::Ssh do
|
5
|
+
it_should_behave_like "abstract driver"
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
@driver = Rsh::Drivers::Ssh.new config[:remote_driver]
|
9
|
+
@driver.open
|
10
|
+
end
|
11
|
+
|
12
|
+
after :each do
|
13
|
+
@driver.close
|
14
|
+
end
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vfs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 4
|
9
|
+
version: 0.0.4
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Alexey Petrushin
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-02-02 00:00:00 +03:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description:
|
22
|
+
email:
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files: []
|
28
|
+
|
29
|
+
files:
|
30
|
+
- Rakefile
|
31
|
+
- readme.md
|
32
|
+
- lib/old/ssh.rb
|
33
|
+
- lib/rsh/box/marks.rb
|
34
|
+
- lib/rsh/box.rb
|
35
|
+
- lib/rsh/drivers/abstract.rb
|
36
|
+
- lib/rsh/drivers/local.rb
|
37
|
+
- lib/rsh/drivers/ssh.rb
|
38
|
+
- lib/rsh/gems.rb
|
39
|
+
- lib/rsh/support.rb
|
40
|
+
- lib/rsh.rb
|
41
|
+
- spec/abstract_driver/dir/dir2/file
|
42
|
+
- spec/abstract_driver/local_file
|
43
|
+
- spec/abstract_driver.rb
|
44
|
+
- spec/box_spec/dir/dir2/file
|
45
|
+
- spec/box_spec/local_file
|
46
|
+
- spec/box_spec.rb
|
47
|
+
- spec/config.example.yml
|
48
|
+
- spec/config.yml
|
49
|
+
- spec/local_driver_spec.rb
|
50
|
+
- spec/spec_helper.rb
|
51
|
+
- spec/ssh_driver_spec.rb
|
52
|
+
has_rdoc: true
|
53
|
+
homepage: http://github.com/alexeypetrushin/vfs
|
54
|
+
licenses: []
|
55
|
+
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options: []
|
58
|
+
|
59
|
+
require_paths:
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
segments:
|
67
|
+
- 0
|
68
|
+
version: "0"
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
version: "0"
|
77
|
+
requirements: []
|
78
|
+
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 1.3.7
|
81
|
+
signing_key:
|
82
|
+
specification_version: 3
|
83
|
+
summary: Tiny wrapper over Net::SSH/SFTP + small rake addon for cluster configuration management
|
84
|
+
test_files: []
|
85
|
+
|