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/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
|