vos 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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/readme.md
CHANGED
@@ -1,21 +1,122 @@
|
|
1
|
-
#
|
1
|
+
# Vfs - Virtual File System
|
2
2
|
|
3
|
-
|
3
|
+
Handy and simple abstraction over any storage that can represent concept of File and Directory (or at least part of it).
|
4
|
+
The Vfs for File System Storages is the same as ActiveRecord is for Relational Databases.
|
4
5
|
|
5
|
-
|
6
|
+
Currently, there are following implementations available:
|
7
|
+
|
8
|
+
- local file system
|
9
|
+
- remote file system (over ssh)
|
10
|
+
|
11
|
+
## Goals
|
12
|
+
|
13
|
+
- **handy, simple and clean** API.
|
14
|
+
- **high performance** - the same as by using low-level storage API, there should be no extra calls **.
|
15
|
+
- same API for different storages (Local FS, SSH, Hadoop, or any other , ...).
|
16
|
+
- should work **simultaneously with different storages**.
|
17
|
+
- small codebase, easy to extend by others.
|
18
|
+
- simple storage-driver implementation, easy add new storage types (Hadoop DFS, LDAP, Document Oriented DB, In-Memory, ...).
|
19
|
+
|
20
|
+
** all methods should have the same performance as native system calls, except for :move and :rename. Right now they are implemented
|
21
|
+
ASAP by using copy+destroy approach, will be fixed as soon as I'll have free time to do it.
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
$ gem install vfs
|
26
|
+
$ gem install vos
|
27
|
+
|
28
|
+
## Code samples:
|
29
|
+
gem 'vfs' # Virtual File System
|
30
|
+
require 'vfs'
|
31
|
+
|
32
|
+
gem 'vos' # Virtual Operating System
|
33
|
+
require 'vos'
|
34
|
+
|
35
|
+
|
36
|
+
# Connections, let's deploy our 'cool_app' project from our local box to remote server
|
37
|
+
server = Vfs::Box.new(host: 'cool_app.com', ssh: {user: 'me', password: 'secret'})
|
38
|
+
me = '~'.to_dir
|
39
|
+
|
40
|
+
cool_app = server['apps/cool_app']
|
41
|
+
projects = me['projects']
|
42
|
+
|
43
|
+
|
44
|
+
# Working with dirs, copying dir from any source to any destination (local/remote/custom_storage_type)
|
45
|
+
projects['cool_app'].copy_to cool_app
|
46
|
+
|
47
|
+
|
48
|
+
# Working with files
|
49
|
+
dbc = cool_app.file('config/database.yml') # <= the 'config' dir not exist yet
|
50
|
+
dbc.write("user: root\npassword: secret") # <= now the 'database.yml' and parent 'config' has been created
|
51
|
+
dbc.content =~ /database/ # => false, we forgot to add the database
|
52
|
+
dbc.append("\ndatabase: mysql") # let's do it
|
53
|
+
|
54
|
+
dbc.update do |content| # and add host info
|
55
|
+
content + "\nhost: cool_app.com "
|
56
|
+
end
|
57
|
+
|
58
|
+
projects['cool_app/config/database.yml']. # or just overwrite it with our local dev version
|
59
|
+
copy_to! dbc
|
60
|
+
|
61
|
+
# there are also streaming support (read/write/append), please go to specs for docs
|
6
62
|
|
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
63
|
|
64
|
+
# Checks
|
65
|
+
cool_app['config'].exist? # => true
|
66
|
+
cool_app.dir('config').exist? # => true
|
67
|
+
cool_app.file('config').exist? # => false
|
68
|
+
|
69
|
+
cool_app['config'].dir? # => true
|
70
|
+
cool_app['config'].file? # => false
|
71
|
+
|
72
|
+
|
73
|
+
# Navigation
|
74
|
+
config = cool_app['config']
|
75
|
+
config.parent # => </apps/cool_app>
|
76
|
+
config['../..'] # => </>
|
77
|
+
config['../..'].dir? # => true
|
78
|
+
|
79
|
+
cool_app.entries # => list of dirs and files, also support &block
|
80
|
+
cool_app.files # => list of files, also support &block
|
81
|
+
cool_app.dirs # => list of dirs, also support &block
|
82
|
+
|
83
|
+
|
84
|
+
# For more please go to specs (create/update/move/copy/destroy/...)
|
85
|
+
|
86
|
+
## Integration with [Vos][vos] (Virtual Operating System)
|
87
|
+
|
88
|
+
server['apps/cool_app'].bash 'rails production'
|
89
|
+
|
90
|
+
For more details please go to [Vos][vos] project page.
|
91
|
+
|
92
|
+
# Why?
|
93
|
+
|
94
|
+
To easy my work: with local FS, remote FS (cluster management, deployment automation), and some specific systems like Hadoop DFS.
|
95
|
+
|
96
|
+
Because the API of standard File/Dir/FileUtils classes are just terrible. And there's the reason for it - the goal of thouse tools
|
97
|
+
is to provide 1-to-1 clone of underlying OS API, instead of provididing handy tool.
|
98
|
+
|
99
|
+
And if you want to use remote FS - things are getting even worse and more complicated (Net::SSH & Net::SFTP use a little
|
100
|
+
different API than local FS, and you has to remember all thouse little quirks).
|
101
|
+
|
14
102
|
## TODO
|
15
103
|
|
16
|
-
|
17
|
-
|
18
|
-
-
|
19
|
-
-
|
104
|
+
### v 0.1 (all done)
|
105
|
+
|
106
|
+
- bash & basic support for
|
107
|
+
- File.append
|
108
|
+
- list of entries/files/dirs
|
109
|
+
- support for efficient copy for Local and SSH storages
|
110
|
+
|
111
|
+
### v 0.2 (not started)
|
112
|
+
|
113
|
+
- efficient (not copy/destroy) versions of move_to, rename
|
114
|
+
- glob search for directories: Dir['**/*.yml']
|
115
|
+
- access via attributes and helpers for unix chmod
|
116
|
+
- add storages: remote FS over HTTP.
|
117
|
+
|
118
|
+
### future
|
119
|
+
|
120
|
+
- add storages: Hadoop DFS, MongoDB, Amazon S3
|
20
121
|
|
21
|
-
[
|
122
|
+
[vfs]: http://github.com/alexeypetrushin/vfs
|
data/spec/box_spec.rb
CHANGED
@@ -1,109 +1,56 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
4
|
-
with_tmp_spec_dir before: :each
|
5
|
-
|
3
|
+
describe Vos::Box do
|
6
4
|
before :each do
|
7
|
-
@box =
|
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
|
5
|
+
@box = Vos::Box.new
|
6
|
+
@box.stub :puts
|
18
7
|
end
|
19
8
|
|
20
|
-
describe
|
21
|
-
|
22
|
-
|
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
|
9
|
+
describe 'vfs integration' do
|
10
|
+
it 'smoke test' do
|
11
|
+
@box['/'].exist?.should be_true
|
59
12
|
end
|
60
13
|
|
61
|
-
|
62
|
-
|
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
|
14
|
+
it 'vfs integration' do
|
15
|
+
@box['/'].bash("echo 'ok'").should == "ok\n"
|
97
16
|
end
|
98
17
|
end
|
99
18
|
|
100
19
|
describe "shell" do
|
101
20
|
it 'bash' do
|
102
21
|
@box.bash("echo 'ok'").should == "ok\n"
|
103
|
-
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'bash working dir should be /' do
|
25
|
+
@box.bash('pwd').should == "/\n"
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'check with regex' do
|
29
|
+
@box.bash "echo 'ok'", /ok/
|
30
|
+
-> {@box.bash "echo 'ok'", /no/}.should raise_error(/not match/)
|
31
|
+
end
|
104
32
|
|
105
33
|
it "exec" do
|
106
34
|
@box.exec("echo 'ok'").should == [0, "ok\n", ""]
|
107
35
|
end
|
36
|
+
|
37
|
+
it 'home' do
|
38
|
+
@box.home.should_not be_nil
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'env' do
|
42
|
+
@box.env.should == {}
|
43
|
+
@box.env = {a: 'b'}
|
44
|
+
|
45
|
+
@box.env c: 'd' do
|
46
|
+
@box.env.should == {a: 'b', c: 'd'}
|
47
|
+
end
|
48
|
+
@box.env.should == {a: 'b'}
|
49
|
+
|
50
|
+
@box.env(c: 'd')
|
51
|
+
@box.env.should == {a: 'b', c: 'd'}
|
52
|
+
|
53
|
+
@box.env('ls').should == "a=b c=d && ls"
|
54
|
+
end
|
108
55
|
end
|
109
56
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'drivers/spec_helper'
|
2
|
+
|
3
|
+
describe Vos::Drivers::Ssh do
|
4
|
+
it_should_behave_like "vos driver"
|
5
|
+
it_should_behave_like "vfs storage"
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
@storage = @driver = Vos::Drivers::Ssh.new(config[:remote_driver])
|
9
|
+
@driver.open
|
10
|
+
end
|
11
|
+
|
12
|
+
after :all do
|
13
|
+
@driver.close
|
14
|
+
end
|
15
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
+
- 1
|
7
8
|
- 0
|
8
|
-
|
9
|
-
version: 0.0.4
|
9
|
+
version: 0.1.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Alexey Petrushin
|
@@ -14,10 +14,22 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-02-
|
17
|
+
date: 2011-02-08 00:00:00 +03:00
|
18
18
|
default_executable:
|
19
|
-
dependencies:
|
20
|
-
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: vfs
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
21
33
|
description:
|
22
34
|
email:
|
23
35
|
executables: []
|
@@ -30,25 +42,25 @@ files:
|
|
30
42
|
- Rakefile
|
31
43
|
- readme.md
|
32
44
|
- lib/old/ssh.rb
|
33
|
-
- lib/
|
34
|
-
- lib/
|
35
|
-
- lib/
|
36
|
-
- lib/
|
37
|
-
- lib/
|
38
|
-
- lib/
|
39
|
-
- lib/
|
40
|
-
- lib/
|
41
|
-
-
|
42
|
-
-
|
43
|
-
-
|
44
|
-
-
|
45
|
-
- spec/box_spec/local_file
|
45
|
+
- lib/vos/box/marks.rb
|
46
|
+
- lib/vos/box/shell.rb
|
47
|
+
- lib/vos/box/vfs.rb
|
48
|
+
- lib/vos/box.rb
|
49
|
+
- lib/vos/drivers/abstract.rb
|
50
|
+
- lib/vos/drivers/local.rb
|
51
|
+
- lib/vos/drivers/specification.rb
|
52
|
+
- lib/vos/drivers/ssh.rb
|
53
|
+
- lib/vos/gems.rb
|
54
|
+
- lib/vos/helpers/ubuntu.rb
|
55
|
+
- lib/vos/support.rb
|
56
|
+
- lib/vos.rb
|
46
57
|
- spec/box_spec.rb
|
47
58
|
- spec/config.example.yml
|
48
59
|
- spec/config.yml
|
49
|
-
- spec/
|
60
|
+
- spec/drivers/local_spec.rb
|
61
|
+
- spec/drivers/spec_helper.rb
|
62
|
+
- spec/drivers/ssh_spec.rb
|
50
63
|
- spec/spec_helper.rb
|
51
|
-
- spec/ssh_driver_spec.rb
|
52
64
|
has_rdoc: true
|
53
65
|
homepage: http://github.com/alexeypetrushin/vos
|
54
66
|
licenses: []
|
@@ -80,6 +92,6 @@ rubyforge_project:
|
|
80
92
|
rubygems_version: 1.3.7
|
81
93
|
signing_key:
|
82
94
|
specification_version: 3
|
83
|
-
summary:
|
95
|
+
summary: Virtual Operating System
|
84
96
|
test_files: []
|
85
97
|
|
data/lib/rsh/box/marks.rb
DELETED
@@ -1,29 +0,0 @@
|
|
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
DELETED
@@ -1,182 +0,0 @@
|
|
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
|
data/lib/rsh/drivers/local.rb
DELETED
@@ -1,48 +0,0 @@
|
|
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
|