rfuse 1.0.2 → 1.0.3

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/lib/rfuse/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RFuse
2
- VERSION = "1.0.2"
2
+ VERSION = "1.0.3"
3
3
  end
data/lib/rfuse.rb CHANGED
@@ -19,6 +19,91 @@ module RFuse
19
19
  end
20
20
  end
21
21
 
22
+ # Parse mount arguments and options
23
+ #
24
+ # @param [Array<String>] argv
25
+ # normalised fuse options
26
+ #
27
+ # @param [Array<Symbol>] local_opts local options
28
+ # if these are found in the argv entry following "-o" they are removed
29
+ # from argv, ie so argv is a clean set of options that can be passed
30
+ # to {RFuse::Fuse} or {RFuse::FuseDelegator}
31
+ #
32
+ #
33
+ # @return [Hash{Symbol => String,Boolean}]
34
+ # the extracted options
35
+ #
36
+ # @since 1.0.3
37
+ #
38
+ # Fuse itself will normalise arguments
39
+ #
40
+ # mount -t fuse </path/to/fs>#<device> mountpoint [options...]
41
+ # mount.fuse </path/to/fs>#<device> mountpoint [options...]
42
+ #
43
+ # both result in a call to /path/to/fs with arguments...
44
+ #
45
+ # [device] mountpoint [-h] [-o [opt,optkey=value,...]]
46
+ #
47
+ # which this method will parse into a Hash with the following special keys
48
+ #
49
+ # :device - the optional mount device, removed from argv if present
50
+ # :mountpoint - required mountpoint
51
+ # :help - true if -h was supplied
52
+ #
53
+ # and any other supplied options.
54
+ #
55
+ # @example
56
+ # ARGV = [ "some/device", "/mnt/point", "-h", "-o", "debug,myfs=aValue" ]
57
+ # options = RFuse.parse_options(ARGV,:myfs)
58
+ #
59
+ # # options ==
60
+ # { :device => "some/device",
61
+ # :mountpoint => "/mnt/point",
62
+ # :help => true,
63
+ # :debug => true,
64
+ # :myfs => "aValue"
65
+ # }
66
+ # # and ARGV ==
67
+ # [ "/mnt/point","-h","-o","debug" ]
68
+ #
69
+ # fs = create_filesystem(options)
70
+ # fuse = RFuse::FuseDelegator.new(fs,*ARGV)
71
+ #
72
+ def self.parse_options(argv,*local_opts)
73
+ result = Hash.new(nil)
74
+
75
+ first_opt_index = (argv.find_index() { |opt| opt =~ /-.*/ } || argv.length )
76
+
77
+ result[:device] = argv.shift if first_opt_index > 1
78
+ result[:mountpoint] = argv[0] if argv.length > 0
79
+
80
+ if argv.include?("-h")
81
+ result[:help] = true
82
+ end
83
+
84
+ opt_index = ( argv.find_index("-o") || -1 ) + 1
85
+
86
+ if opt_index > 1 && opt_index < argv.length
87
+ options = argv[opt_index].split(",")
88
+
89
+ options.delete_if() do |opt|
90
+ opt.strip!
91
+
92
+ opt,value = opt.split("=",2)
93
+ value = true unless value
94
+ opt_sym = opt.to_sym
95
+ result[opt_sym] = value
96
+
97
+ #result of delete if
98
+ local_opts.include?(opt_sym)
99
+ end
100
+
101
+ argv[opt_index] = options.join(",")
102
+ end
103
+
104
+ result
105
+ end
106
+
22
107
  class Fuse
23
108
 
24
109
  # Main processing loop
@@ -40,7 +125,7 @@ module RFuse
40
125
  ready, ignore, errors = IO.select([@fuse_io,@pr],[],[@fuse_io])
41
126
 
42
127
  if ready.include?(@pr)
43
-
128
+
44
129
  @pr.getc
45
130
  @running = false
46
131
 
@@ -75,7 +160,7 @@ module RFuse
75
160
  # afer the filesystem has been mounted successfully
76
161
  def ruby_initialize
77
162
  @pr,@pw = IO.pipe()
78
-
163
+
79
164
  # The FD was created by FUSE so we don't want
80
165
  # ruby to do anything with it during GC
81
166
  @fuse_io = IO.for_fd(fd(),"r",:autoclose => false)
@@ -219,5 +304,4 @@ module RFuse
219
304
  end
220
305
  end
221
306
  end
222
-
223
307
  end #Module RFuse
data/spec/basic_spec.rb CHANGED
@@ -9,32 +9,6 @@ describe RFuse::Fuse do
9
9
  let!(:mockfs) { m = mock("fuse"); m.stub(:getattr).and_return(nil); m }
10
10
  let(:mountpoint) { tempmount() }
11
11
 
12
- context "mount options" do
13
- it "should handle -h" do
14
- fuse = RFuse::FuseDelegator.new(mockfs,mountpoint,"-h")
15
- fuse.mounted?.should be_false
16
- lambda { fuse.loop }.should raise_error(RFuse::Error)
17
- end
18
-
19
- it "should behave sensibly for bad mountpoint" do
20
- fuse = RFuse::FuseDelegator.new(mockfs,"bad/mount/point")
21
- fuse.mounted?.should be_false
22
- lambda { fuse.loop }.should raise_error(RFuse::Error)
23
- end
24
-
25
- it "should behave sensibly for bad options" do
26
- fuse = RFuse::FuseDelegator.new(mockfs,mountpoint,"-eviloption")
27
- fuse.mounted?.should be_false
28
- lambda { fuse.loop }.should raise_error(RFuse::Error)
29
- end
30
-
31
- it "should handle a Pathname as a mountpoint" do
32
- fuse = RFuse::FuseDelegator.new(mockfs,Pathname.new(mountpoint))
33
- fuse.mounted?.should be_true
34
- fuse.unmount()
35
- end
36
- end
37
-
38
12
  context "links" do
39
13
  it "should create and resolve symbolic links"
40
14
 
@@ -175,13 +149,13 @@ describe RFuse::Fuse do
175
149
  reads = 0
176
150
  mockfs.stub(:read) { |ctx,path,size,offset,ffi|
177
151
  reads += 2
178
- "hello world"[offset,reads]
152
+ "hello\000world"[offset,reads]
179
153
  }
180
154
 
181
155
  with_fuse(mountpoint,mockfs) do
182
156
  File.open("#{mountpoint}/test") do |f|
183
157
  val = f.gets
184
- val.should == "hello world"
158
+ val.should == "hello\000world"
185
159
  end
186
160
  end
187
161
  end
@@ -1,21 +1,51 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe RFuse::Fuse do
4
+
5
+ let(:dir_stat) { RFuse::Stat.directory(0444) }
6
+ let(:file_stat) { RFuse::Stat.file(0444) }
7
+ let!(:mockfs) { m = mock("fuse"); m.stub(:getattr).and_return(nil); m }
8
+ let(:mountpoint) { tempmount() }
9
+ let(:open_files) { Hash.new() }
10
+
11
+ it "should pass fileinfo to #release" do
12
+
13
+ file_handle = Object.new()
14
+ stored_ffi = nil
15
+ captured_ex = nil
16
+
17
+ mockfs.stub(:getattr).with(anything(),"/ffirelease").and_return(file_stat)
18
+
19
+ mockfs.should_receive(:open).with(anything(),"/ffirelease",anything()) { |ctx,path,ffi|
20
+ stored_ffi = ffi
21
+ ffi.fh = file_handle
22
+ }
23
+
24
+ mockfs.should_receive(:release).with(anything(),"/ffirelease",anything()) { |ctx,path,ffi|
25
+ # the return value of release is ignore, so exceptions here are lost
26
+ begin
27
+ ffi.fh.should == file_handle
28
+ ffi.should == stored_ffi
29
+ rescue Exception => ex
30
+ captured_ex = ex
31
+ end
32
+ }
33
+
34
+ with_fuse(mountpoint,mockfs) do
35
+ f1 = File.new("#{mountpoint}/ffirelease")
36
+ f1.close()
37
+ end
38
+
39
+ raise captured_ex if captured_ex
40
+ end
41
+
4
42
  context "file handles" do
5
43
  it "should retain file handles over GC" do
6
- mockfs = mock("fuse")
7
44
 
8
- file_stat = RFuse::Stat.file(0444,:size => 11)
45
+ file_stat.size = 11
9
46
 
10
- mockfs.stub(:getattr) { | ctx, path|
11
- case path
12
- when "/one","/two"
13
- file_stat
14
- else
15
- nil
16
- end
17
-
18
- }
47
+ mockfs.stub(:getattr).with(anything(),"/one").and_return(file_stat)
48
+ mockfs.stub(:getattr).with(anything(),"/two").and_return(file_stat)
19
49
 
20
50
  open_files = {}
21
51
  mockfs.stub(:open) { |ctx,path,ffi|
@@ -29,7 +59,6 @@ describe RFuse::Fuse do
29
59
  "hello world"
30
60
  }
31
61
 
32
- mountpoint = tempmount()
33
62
  with_fuse(mountpoint,mockfs) do
34
63
  f1 = File.new("#{mountpoint}/one")
35
64
  f2 = File.new("#{mountpoint}/two")
@@ -0,0 +1,112 @@
1
+ require 'spec_helper'
2
+ require 'pathname'
3
+ require 'tempfile'
4
+
5
+ describe RFuse do
6
+
7
+ let(:dir_stat) { RFuse::Stat.directory(0444) }
8
+ let(:file_stat) { RFuse::Stat.file(0444) }
9
+ let!(:mockfs) { m = mock("fuse"); m.stub(:getattr).and_return(nil); m }
10
+ let(:mountpoint) { tempmount() }
11
+
12
+ context "mount options" do
13
+ it "should handle -h" do
14
+ fuse = RFuse::FuseDelegator.new(mockfs,mountpoint,"-h")
15
+ fuse.mounted?.should be_false
16
+ lambda { fuse.loop }.should raise_error(RFuse::Error)
17
+ end
18
+
19
+ it "should behave sensibly for bad mountpoint" do
20
+ fuse = RFuse::FuseDelegator.new(mockfs,"bad/mount/point")
21
+ fuse.mounted?.should be_false
22
+ lambda { fuse.loop }.should raise_error(RFuse::Error)
23
+ end
24
+
25
+ it "should behave sensibly for bad options" do
26
+ fuse = RFuse::FuseDelegator.new(mockfs,mountpoint,"-eviloption")
27
+ fuse.mounted?.should be_false
28
+ lambda { fuse.loop }.should raise_error(RFuse::Error)
29
+ end
30
+
31
+ it "should handle a Pathname as a mountpoint" do
32
+ fuse = RFuse::FuseDelegator.new(mockfs,Pathname.new(mountpoint))
33
+ fuse.mounted?.should be_true
34
+ fuse.unmount()
35
+ end
36
+ end
37
+
38
+ context "#parse_options" do
39
+
40
+ it "should detect -h" do
41
+ argv = [ "/mountpoint","-h" ]
42
+ result = RFuse.parse_options(argv)
43
+
44
+ result[:help].should be_true
45
+ result[:mountpoint].should == "/mountpoint"
46
+ result[:debug].should be_false
47
+ end
48
+
49
+ it "should detect -h mixed with -o" do
50
+ argv = [ "/mountpoint","-h", "-o", "debug" ]
51
+ result = RFuse.parse_options(argv)
52
+
53
+ result[:help].should be_true
54
+ result[:mountpoint].should == "/mountpoint"
55
+ result[:debug].should be_true
56
+ end
57
+
58
+ it "should detect debug" do
59
+ argv = [ "/mountpoint","-o","debug" ]
60
+ result = RFuse.parse_options(argv)
61
+
62
+ result[:debug].should be_true
63
+ result[:help].should be_false
64
+
65
+ argv = [ "/mountpoint","-o","default_permissions,debug" ]
66
+ result = RFuse.parse_options(argv)
67
+ result[:debug].should be_true
68
+ end
69
+
70
+ it "should remove local options" do
71
+ argv = [ "/mountpoint","-o","debug,myoption" ]
72
+
73
+ result = RFuse.parse_options(argv,:myoption)
74
+
75
+ result[:debug].should be_true
76
+ result[:myoption].should be_true
77
+
78
+ argv[2].should == "debug"
79
+ end
80
+
81
+ it "should parse values from options" do
82
+ argv = [ "/mountpoint", "-o", "debug,someopt=somevalue" ]
83
+ result = RFuse.parse_options(argv)
84
+
85
+ result[:someopt].should == "somevalue"
86
+ end
87
+
88
+ it "should parse values and remove local options" do
89
+ argv = [ "/mountpoint", "-o", "debug,someopt=somevalue" ]
90
+ result = RFuse.parse_options(argv,:someopt)
91
+
92
+ result[:someopt].should == "somevalue"
93
+ argv[2].should == "debug"
94
+ end
95
+
96
+ it "should parse and remove optional device" do
97
+
98
+ argv = [ "a device", "/mountpoint" , "-o", "rw,debug,default_permissions" ]
99
+ result = RFuse.parse_options(argv)
100
+
101
+ result[:device].should == "a device"
102
+ result[:mountpoint].should == "/mountpoint"
103
+ result[:rw].should be_true
104
+ result[:debug].should be_true
105
+ result[:default_permissions].should be_true
106
+
107
+ argv.length.should == 3
108
+ argv.join(" ").should == "/mountpoint -o rw,debug,default_permissions"
109
+ end
110
+
111
+ end
112
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rfuse
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-09 00:00:00.000000000 Z
12
+ date: 2012-08-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -135,6 +135,7 @@ files:
135
135
  - sample/test-ruby.rb
136
136
  - spec/basic_spec.rb
137
137
  - spec/fuse_file_info_spec.rb
138
+ - spec/options_spec.rb
138
139
  - spec/ruby_loop_spec.rb
139
140
  - spec/spec_helper.rb
140
141
  - spec/xattr_spec.rb