vfs-momolog 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.gitignore +8 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/Rakefile +2 -0
  5. data/docs/basics.rb +116 -0
  6. data/docs/s3_backup.rb +29 -0
  7. data/docs/s3_backup/app/files/bos.png +0 -0
  8. data/docs/s3_basics.rb +19 -0
  9. data/docs/s3_sandbox.rb +24 -0
  10. data/docs/site/404.html +8 -0
  11. data/docs/site/basics.html +305 -0
  12. data/docs/site/index.html +8 -0
  13. data/docs/site/s3_backup.html +111 -0
  14. data/docs/site/s3_basics.html +84 -0
  15. data/docs/site/s3_sandbox.html +99 -0
  16. data/docs/site/ssh_basics.html +84 -0
  17. data/docs/site/ssh_deployment.html +125 -0
  18. data/docs/site/ssh_sandbox.html +103 -0
  19. data/docs/ssh_basics.rb +19 -0
  20. data/docs/ssh_deployment.rb +35 -0
  21. data/docs/ssh_deployment/app/app.rb +0 -0
  22. data/docs/ssh_sandbox.rb +28 -0
  23. data/lib/vfs.rb +18 -0
  24. data/lib/vfs/drivers/local.rb +180 -0
  25. data/lib/vfs/drivers/specification.rb +169 -0
  26. data/lib/vfs/entries/dir.rb +256 -0
  27. data/lib/vfs/entries/entry.rb +152 -0
  28. data/lib/vfs/entries/file.rb +155 -0
  29. data/lib/vfs/entries/universal_entry.rb +24 -0
  30. data/lib/vfs/entry_proxy.rb +42 -0
  31. data/lib/vfs/error.rb +4 -0
  32. data/lib/vfs/integration.rb +30 -0
  33. data/lib/vfs/path.rb +123 -0
  34. data/lib/vfs/version.rb +3 -0
  35. data/lib/vfs/vfs.rb +38 -0
  36. data/old/hash_fs.rb +216 -0
  37. data/old/hash_fs_spec.rb +10 -0
  38. data/readme.md +143 -0
  39. data/spec/container_spec.rb +31 -0
  40. data/spec/dir_spec.rb +253 -0
  41. data/spec/entry_spec.rb +42 -0
  42. data/spec/file_spec.rb +215 -0
  43. data/spec/misc_spec.rb +19 -0
  44. data/spec/path_spec.rb +127 -0
  45. data/spec/spec_helper.rb +50 -0
  46. data/spec/storages/local_spec.rb +24 -0
  47. data/spec/storages/local_spec/emptygit +0 -0
  48. data/spec/universal_entry_spec.rb +69 -0
  49. data/todo.md +19 -0
  50. data/vfs.gemspec +17 -0
  51. metadata +105 -0
@@ -0,0 +1,103 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="content-type" content="text/html;charset=utf-8">
5
+ <title>ssh_sandbox.rb</title>
6
+ <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
7
+ </head>
8
+ <body>
9
+ <div id='container'>
10
+ <div id="background"></div>
11
+ <div id="jump_to">
12
+ Jump To &hellip;
13
+ <div id="jump_wrapper">
14
+ <div id="jump_page">
15
+ <a class="source" href="basics.html">basics.rb</a>
16
+ <a class="source" href="s3_backup.html">s3_backup.rb</a>
17
+ <a class="source" href="s3_basics.html">s3_basics.rb</a>
18
+ <a class="source" href="s3_sandbox.html">s3_sandbox.rb</a>
19
+ <a class="source" href="ssh_basics.html">ssh_basics.rb</a>
20
+ <a class="source" href="ssh_deployment.html">ssh_deployment.rb</a>
21
+ <a class="source" href="ssh_sandbox.html">ssh_sandbox.rb</a>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ <table cellspacing=0 cellpadding=0>
26
+ <thead>
27
+ <tr>
28
+ <th class=docs><h1>ssh_sandbox.rb</h1></th>
29
+ <th class=code></th>
30
+ </tr>
31
+ </thead>
32
+ <tbody>
33
+ <tr id='section-1'>
34
+ <td class=docs>
35
+ <div class="pilwrap">
36
+ <a class="pilcrow" href="#section-1">&#182;</a>
37
+ </div>
38
+ <p>Example of using SFTP as a storage for <a href="index.html">Virtual File System</a></p>
39
+ </td>
40
+ <td class=code>
41
+ <div class='highlight'><pre></pre></div>
42
+ </td>
43
+ </tr>
44
+ <tr id='section-2'>
45
+ <td class=docs>
46
+ <div class="pilwrap">
47
+ <a class="pilcrow" href="#section-2">&#182;</a>
48
+ </div>
49
+ <p>To use SSH/SFTP we need the SSH driver, You need &lsquo;vos&rsquo;, &lsquo;net-ssh&rsquo; and &lsquo;net-sftp&rsquo; gems installed.</p>
50
+
51
+ <pre><code>gem install vos net-ssh net-sftp
52
+ </code></pre>
53
+ </td>
54
+ <td class=code>
55
+ <div class='highlight'><pre><span class="nb">require</span> <span class="s1">&#39;vfs&#39;</span>
56
+ <span class="nb">require</span> <span class="s1">&#39;vos&#39;</span>
57
+ <span class="nb">require</span> <span class="s1">&#39;vos/drivers/ssh&#39;</span></pre></div>
58
+ </td>
59
+ </tr>
60
+ <tr id='section-3'>
61
+ <td class=docs>
62
+ <div class="pilwrap">
63
+ <a class="pilcrow" href="#section-3">&#182;</a>
64
+ </div>
65
+ <p>Initializing SSH driver, if You can connect to server using identity file provide host only.</p>
66
+
67
+ <p>If the connection requires login and password You need to provide it:</p>
68
+
69
+ <pre><code>driver = Vos::Drivers::Ssh.new \
70
+ host: &lsquo;xxx.com&rsquo;,
71
+ user: &lsquo;xxx&rsquo;,
72
+ password: &lsquo;xxx&rsquo;
73
+ </code></pre>
74
+ </td>
75
+ <td class=code>
76
+ <div class='highlight'><pre><span class="n">driver</span> <span class="o">=</span> <span class="no">Vos</span><span class="o">::</span><span class="no">Drivers</span><span class="o">::</span><span class="no">Ssh</span><span class="o">.</span><span class="n">new</span> <span class="n">host</span><span class="p">:</span> <span class="s1">&#39;xxx.com&#39;</span></pre></div>
77
+ </td>
78
+ </tr>
79
+ <tr id='section-4'>
80
+ <td class=docs>
81
+ <div class="pilwrap">
82
+ <a class="pilcrow" href="#section-4">&#182;</a>
83
+ </div>
84
+ <p>After creating driver we can create storage.</p>
85
+ </td>
86
+ <td class=code>
87
+ <div class='highlight'><pre><span class="n">box</span> <span class="o">=</span> <span class="no">Vos</span><span class="o">::</span><span class="no">Box</span><span class="o">.</span><span class="n">new</span> <span class="n">driver</span></pre></div>
88
+ </td>
89
+ </tr>
90
+ <tr id='section-5'>
91
+ <td class=docs>
92
+ <div class="pilwrap">
93
+ <a class="pilcrow" href="#section-5">&#182;</a>
94
+ </div>
95
+ <p>Preparing temporary dir for sample and cleaning it before starting.</p>
96
+ </td>
97
+ <td class=code>
98
+ <div class='highlight'><pre><span class="vg">$sandbox</span> <span class="o">=</span> <span class="n">box</span><span class="o">[</span><span class="s1">&#39;/tmp/vfs_sandbox&#39;</span><span class="o">].</span><span class="n">to_dir</span><span class="o">.</span><span class="n">destroy</span></pre></div>
99
+ </td>
100
+ </tr>
101
+ </table>
102
+ </div>
103
+ </body>
@@ -0,0 +1,19 @@
1
+ # Example of [Virtual File System][vfs] working with SFTP.
2
+ #
3
+ # This is exactly the same [basic example][basics] but this time
4
+ # we using SFTP as storage instead of local file system.
5
+
6
+ # Adding examples folder to load paths.
7
+ $LOAD_PATH << File.expand_path("#{__FILE__}/../..")
8
+
9
+ # Connecting to SFTP and preparing sandbox. You may take a look at
10
+ # the [docs/ssh_sandbox.rb][ssh_sandbox] to see the actual code.
11
+ require 'docs/ssh_sandbox'
12
+
13
+ # Now we just executig [basic example][basics]
14
+ # but with the `$storage` set to SFTP.
15
+ require 'docs/basics'
16
+
17
+ # [vfs]: index.html
18
+ # [basics]: basics.html
19
+ # [ssh_sandbox]: ssh_sandbox.html
@@ -0,0 +1,35 @@
1
+ # Example of Application Deployment using [Virtual File System][vfs].
2
+ #
3
+ # In this example we uploading sample app files to remote server,
4
+ # write database configuration file and restart the server on remote machine.
5
+
6
+ # Adding examples folder to load paths.
7
+ $LOAD_PATH << File.expand_path("#{__FILE__}/../..")
8
+
9
+ # Connecting to SFTP and preparing sandbox. You may take a look at
10
+ # the [docs/ssh_sandbox.rb][ssh_sandbox] to see the actual code.
11
+ require 'docs/ssh_sandbox'
12
+ sandbox = $sandbox
13
+
14
+ # Preparing sample files located in our local folder in
15
+ # current directory.
16
+ current_dir = __FILE__.to_entry.parent
17
+ sample_app = current_dir['ssh_deployment/app']
18
+
19
+ # Copying application files to remote machine.
20
+ app = sandbox['apps/app']
21
+ sample_app.copy_to app
22
+ p app['app.rb'].exist? # => true
23
+
24
+ # Writing database configuration file.
25
+ config = app['config.yml']
26
+ config.write "database: mysql"
27
+ config.append "name: app_production"
28
+ p app['config.yml'].exist? # => true
29
+
30
+ # Updating gems and restarting the server.
31
+ p app.bash("echo 'bundle install'") # => bundle install
32
+ p app.bash("echo 'server start'") # => server start
33
+
34
+ # [vfs]: index.html
35
+ # [ssh_sandbox]: ssh_sandbox.html
File without changes
@@ -0,0 +1,28 @@
1
+ # Example of using SFTP as a storage for [Virtual File System][vfs]
2
+
3
+ # To use SSH/SFTP we need the SSH driver, You need 'vos', 'net-ssh' and 'net-sftp' gems installed.
4
+ #
5
+ # gem install vos net-ssh net-sftp
6
+ #
7
+ require 'vfs'
8
+ require 'vos'
9
+ require 'vos/drivers/ssh'
10
+
11
+ # Initializing SSH driver, if You can connect to server using identity file provide host only.
12
+ #
13
+ # If the connection requires login and password You need to provide it:
14
+ #
15
+ # driver = Vos::Drivers::Ssh.new \
16
+ # host: 'xxx.com',
17
+ # user: 'xxx',
18
+ # password: 'xxx'
19
+ #
20
+ driver = Vos::Drivers::Ssh.new host: 'xxx.com'
21
+
22
+ # After creating driver we can create storage.
23
+ box = Vos::Box.new driver
24
+
25
+ # Preparing temporary dir for sample and cleaning it before starting.
26
+ $sandbox = box['/tmp/vfs_sandbox'].to_dir.destroy
27
+
28
+ # [vfs]: index.html
data/lib/vfs.rb ADDED
@@ -0,0 +1,18 @@
1
+ module Vfs
2
+ autoload :Path, 'vfs/path'
3
+ autoload :Error, 'vfs/error'
4
+
5
+ autoload :Entry, 'vfs/entries/entry'
6
+ autoload :File, 'vfs/entries/file'
7
+ autoload :Dir, 'vfs/entries/dir'
8
+ autoload :UniversalEntry, 'vfs/entries/universal_entry'
9
+
10
+ autoload :EntryProxy, 'vfs/entry_proxy'
11
+
12
+ module Drivers
13
+ autoload :Local, 'vfs/drivers/local'
14
+ end
15
+ end
16
+
17
+ require 'vfs/vfs'
18
+ require 'vfs/integration'
@@ -0,0 +1,180 @@
1
+ require 'fileutils'
2
+ require 'tempfile'
3
+
4
+ module Vfs
5
+ module Drivers
6
+ class Local
7
+ class Writer
8
+ def initialize out; @out = out end
9
+
10
+ def write data
11
+ @out.write data
12
+ end
13
+ end
14
+
15
+ DEFAULT_BUFFER = 1000 * 1024
16
+
17
+ def initialize options = {}
18
+ options = options.clone
19
+ @root = options.delete(:root) || ''
20
+ raise "invalid options #{options}" unless options.empty?
21
+ end
22
+
23
+ def open &block
24
+ block.call self if block
25
+ end
26
+ def close; end
27
+
28
+ attr_writer :buffer
29
+ def buffer
30
+ @buffer || DEFAULT_BUFFER
31
+ end
32
+
33
+ #
34
+ # Attributes
35
+ #
36
+ def attributes path
37
+ path = with_root path
38
+
39
+ stat = ::File.stat path
40
+ attrs = {}
41
+ attrs[:file] = !!stat.file?
42
+ attrs[:dir] = !!stat.directory?
43
+
44
+ # attributes special for file system
45
+ attrs[:created_at] = stat.ctime
46
+ attrs[:updated_at] = stat.mtime
47
+ attrs[:size] = stat.size if attrs[:file]
48
+ attrs
49
+ rescue Errno::ENOTDIR
50
+ nil
51
+ rescue Errno::ENOENT
52
+ nil
53
+ end
54
+
55
+ def set_attributes path, attrs
56
+ # TODO2 set attributes
57
+ not_implemented
58
+ end
59
+
60
+
61
+ #
62
+ # File
63
+ #
64
+ def read_file path, &block
65
+ path = with_root path
66
+ ::File.open path, 'r' do |is|
67
+ while buff = is.gets(self.buffer || DEFAULT_BUFFER)
68
+ block.call buff
69
+ end
70
+ end
71
+ end
72
+
73
+ def write_file original_path, append, &block
74
+ path = with_root original_path
75
+
76
+ option = append ? 'a' : 'w'
77
+ ::File.open path, "#{option}b" do |out|
78
+ block.call Writer.new(out)
79
+ end
80
+ end
81
+
82
+ def delete_file path
83
+ path = with_root path
84
+ ::File.delete path
85
+ end
86
+
87
+ # def move_file from, to
88
+ # FileUtils.mv from, to
89
+ # end
90
+
91
+
92
+ #
93
+ # Dir
94
+ #
95
+ def create_dir path
96
+ path = with_root path
97
+ ::Dir.mkdir path
98
+ end
99
+
100
+ def delete_dir original_path
101
+ path = with_root original_path
102
+ ::FileUtils.rm_r path
103
+ end
104
+
105
+ def each_entry path, query, &block
106
+ path = with_root path
107
+
108
+ if query
109
+ path_with_trailing_slash = path == '/' ? path : "#{path}/"
110
+ ::Dir["#{path_with_trailing_slash}#{query}"].each do |absolute_path|
111
+ name = absolute_path.sub path_with_trailing_slash, ''
112
+ block.call name, ->{::File.directory?(absolute_path) ? :dir : :file}
113
+ # if ::File.directory? absolute_path
114
+ # block.call relative_path, :dir
115
+ # else
116
+ # block.call relative_path, :file
117
+ # end
118
+ end
119
+ else
120
+ ::Dir.foreach path do |name|
121
+ next if name == '.' or name == '..'
122
+ block.call name, ->{::File.directory?("#{path}/#{name}") ? :dir : :file}
123
+ # if ::File.directory? "#{path}/#{relative_name}"
124
+ # block.call relative_name, :dir
125
+ # else
126
+ # block.call relative_name, :file
127
+ # end
128
+ end
129
+ end
130
+ end
131
+
132
+ # def efficient_dir_copy from, to, override
133
+ # return false if override # FileUtils.cp_r doesn't support this behaviour
134
+ #
135
+ # from.driver.open_fs do |from_fs|
136
+ # to.driver.open_fs do |to_fs|
137
+ # if from_fs.local? and to_fs.local?
138
+ # FileUtils.cp_r from.path, to.path
139
+ # true
140
+ # else
141
+ # false
142
+ # end
143
+ # end
144
+ # end
145
+ # end
146
+
147
+ #
148
+ # Other
149
+ #
150
+ def local?; true end
151
+
152
+ def tmp &block
153
+ path = "/tmp/#{rand(10**6)}"
154
+ # tmp_dir = "#{::Dir.tmpdir}/#{rand(10**6)}"
155
+ if block
156
+ begin
157
+ ::FileUtils.mkdir_p with_root(path)
158
+ block.call path
159
+ ensure
160
+ ::FileUtils.rm_r with_root(path) if ::File.exist? with_root(path)
161
+ end
162
+ else
163
+ ::FileUtils.mkdir_p with_root(path)
164
+ path
165
+ end
166
+ end
167
+
168
+ def to_s; '' end
169
+
170
+ protected
171
+ def root
172
+ @root || raise('root not defined!')
173
+ end
174
+
175
+ def with_root path
176
+ path == '/' ? root : root + path
177
+ end
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,169 @@
1
+ require 'rspec_ext'
2
+ require 'ruby_ext'
3
+
4
+ shared_examples_for 'vfs driver basic' do
5
+ it 'should respond to :local?' do
6
+ @driver.should respond_to(:local?)
7
+ end
8
+
9
+ it "should provide open method" do
10
+ @driver.open
11
+ @driver.open{'result'}.should == 'result'
12
+ end
13
+ end
14
+
15
+ shared_examples_for 'vfs driver attributes basic' do
16
+ it 'should have root dir' do
17
+ attrs = @driver.attributes('/')
18
+ attrs[:dir].should be_true
19
+ attrs[:file].should be_false
20
+ end
21
+
22
+ it "attributes should return nil if there's no entry" do
23
+ @driver.attributes('/non_existing_entry').should be_nil
24
+ end
25
+ end
26
+
27
+ shared_examples_for 'vfs driver files' do
28
+ it "file attributes" do
29
+ @driver.attributes('/file').should be_nil
30
+
31
+ @driver.write_file('/file', false){|w| w.write 'something'}
32
+ attrs = @driver.attributes('/file')
33
+ attrs[:file].should be_true
34
+ attrs[:dir].should be_false
35
+ end
36
+
37
+ it "read, write, append" do
38
+ # write
39
+ @driver.write_file('/file', false){|w| w.write 'something'}
40
+ @driver.attributes('/file')[:file].should == true
41
+
42
+ # read
43
+ data = ""
44
+ @driver.read_file('/file'){|buff| data << buff}
45
+ data.should == 'something'
46
+
47
+ # append
48
+ @driver.write_file('/file', true){|w| w.write ' another'}
49
+ data = ""
50
+ @driver.read_file('/file'){|buff| data << buff}
51
+ data.should == 'something another'
52
+ end
53
+
54
+ it "delete_file" do
55
+ @driver.write_file('/file', false){|w| w.write 'something'}
56
+ @driver.attributes('/file')[:file].should be_true
57
+ @driver.delete_file('/file')
58
+ @driver.attributes('/file').should be_nil
59
+ end
60
+ end
61
+
62
+ shared_examples_for 'vfs driver full attributes for files' do
63
+ it "attributes for files" do
64
+ @driver.write_file('/file', false){|w| w.write 'something'}
65
+ attrs = @driver.attributes('/file')
66
+ attrs[:file].should be_true
67
+ attrs[:dir].should be_false
68
+ attrs[:created_at].class.should == Time
69
+ attrs[:updated_at].class.should == Time
70
+ attrs[:size].should == 9
71
+ end
72
+ end
73
+
74
+ shared_examples_for 'vfs driver dirs' do
75
+ it "directory crud" do
76
+ @driver.attributes('/dir').should be_nil
77
+
78
+ @driver.create_dir('/dir')
79
+ attrs = @driver.attributes('/dir')
80
+ attrs[:file].should be_false
81
+ attrs[:dir].should be_true
82
+
83
+ @driver.delete_dir('/dir')
84
+ @driver.attributes('/dir').should be_nil
85
+ end
86
+
87
+ it 'should delete not-empty directories' do
88
+ @driver.create_dir('/dir')
89
+ @driver.create_dir('/dir/dir2')
90
+ @driver.write_file('/dir/dir2/file', false){|w| w.write 'something'}
91
+ @driver.attributes('/dir').should_not be_nil
92
+
93
+ @driver.delete_dir('/dir')
94
+ @driver.attributes('/dir').should be_nil
95
+ end
96
+
97
+ it 'each' do
98
+ -> {@driver.each_entry('/not_existing_dir', nil){|path, type| list[path] = type}}.should raise_error
99
+
100
+ @driver.create_dir '/dir'
101
+ @driver.create_dir('/dir/dir2')
102
+ @driver.write_file('/dir/file', false){|w| w.write 'something'}
103
+
104
+ list = {}
105
+ @driver.each_entry '/dir', nil do |path, type|
106
+ type = type.call if type.is_a? Proc
107
+ list[path] = type
108
+ end
109
+
110
+ list.should == {'dir2' => :dir, 'file' => :file}
111
+ end
112
+
113
+ # it "upload_directory & download_directory" do
114
+ # upload_path_check = "#{@remote_path}/dir2/file"
115
+ # check_attributes upload_path_check, nil
116
+ # @driver.upload_directory(@from_local, @remote_path)
117
+ # check_attributes upload_path_check, file: true, dir: false
118
+ #
119
+ # download_path_check = "#{@to_local}/dir2/file"
120
+ # File.exist?(download_path_check).should be_false
121
+ # @driver.download_directory(@remote_path, @to_local)
122
+ # File.exist?(download_path_check).should be_true
123
+ # end
124
+ end
125
+
126
+ shared_examples_for 'vfs driver query' do
127
+ it 'each with query' do
128
+ @driver.create_dir '/dir'
129
+ @driver.create_dir('/dir/dir_a')
130
+ @driver.create_dir('/dir/dir_b')
131
+ @driver.write_file('/dir/file_a', false){|w| w.write 'something'}
132
+
133
+ list = {}
134
+ @driver.each_entry '/dir', '*_a' do |path, type|
135
+ type = type.call if type.is_a? Proc
136
+ list[path] = type
137
+ end
138
+
139
+ list.should == {'dir_a' => :dir, 'file_a' => :file}
140
+ end
141
+ end
142
+
143
+ shared_examples_for 'vfs driver full attributes for dirs' do
144
+ it "attributes for dirs" do
145
+ @driver.create_dir('/dir')
146
+ attrs = @driver.attributes('/dir')
147
+ attrs[:file].should be_false
148
+ attrs[:dir].should be_true
149
+ attrs[:created_at].class.should == Time
150
+ attrs[:updated_at].class.should == Time
151
+ attrs.should_not include(:size)
152
+ end
153
+ end
154
+
155
+ shared_examples_for 'vfs driver tmp dir' do
156
+ it "tmp dir" do
157
+ dir = @driver.tmp
158
+ @driver.attributes(dir).should_not be_nil
159
+ @driver.delete_dir dir
160
+ @driver.attributes(dir).should be_nil
161
+
162
+ dir = nil
163
+ @driver.tmp do |tmp_dir|
164
+ dir = tmp_dir
165
+ @driver.attributes(dir).should_not be_nil
166
+ end
167
+ @driver.attributes(dir).should be_nil
168
+ end
169
+ end