defog 0.1.1 → 0.2.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/README.rdoc +68 -24
- data/lib/defog/error.rb +3 -0
- data/lib/defog/file.rb +27 -22
- data/lib/defog/handle.rb +2 -2
- data/lib/defog/proxy.rb +77 -7
- data/lib/defog/version.rb +1 -1
- data/spec/proxy_spec.rb +118 -19
- metadata +15 -15
data/README.rdoc
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
= defog
|
2
2
|
|
3
|
-
Defog wraps the [
|
4
|
-
|
3
|
+
Defog wraps the fog[https://rubygems.org/gems/fog] gem (specifically,
|
4
|
+
{Fog::Storage}[http://fog.io/1.3.1/storage/]), providing access to files
|
5
5
|
stored in the cloud via proxy files on the local file system.
|
6
6
|
A proxy file can be
|
7
7
|
* Read-only: A local cached copy of a cloud file.
|
@@ -10,7 +10,7 @@ A proxy file can be
|
|
10
10
|
|
11
11
|
Defog thus lets you use ordinary programmatic tools to access and
|
12
12
|
manipulate your cloud data. Thanks to the magic of
|
13
|
-
[
|
13
|
+
fog[https://rubygems.org/gems/fog] it works across cloud providers, and
|
14
14
|
it also works with the local file system as a "provider" so that you can,
|
15
15
|
e.g. use the local file system for development and the cloud for
|
16
16
|
production.
|
@@ -100,38 +100,83 @@ In addition, the handle allows you to look up the path where the local proxy fil
|
|
100
100
|
|
101
101
|
=== Persistence
|
102
102
|
|
103
|
-
By default, the local proxy
|
104
|
-
possible to
|
105
|
-
|
106
|
-
|
107
|
-
|
103
|
+
By default, Defog will delete the local proxy when closing a file.
|
104
|
+
However, it is possible to keep the local proxy file so that it if the
|
105
|
+
remote is accessed again the data will not need to be transferred again.
|
106
|
+
(This is true even between executions of the program: a Defog::Proxy
|
107
|
+
instance can start with proxy files already in place, and it will use them.)
|
108
|
+
|
109
|
+
Persistence can be enabled by default for the Defog::Proxy instance via:
|
110
|
+
|
111
|
+
defog = Defog::Proxy.new(:provider => ..., :persist => true)
|
112
|
+
|
113
|
+
And/or persistence can be overridden on a per-file basis at proxy open time:
|
108
114
|
|
109
115
|
file = defog.file("key/of/file", mode, :persist => true)
|
110
116
|
|
111
|
-
or
|
117
|
+
or at proxy close time:
|
112
118
|
|
113
119
|
file.close(:persist => true)
|
114
120
|
|
115
121
|
When opening a file whose local proxy has been persisted, Defog checks to see if
|
116
|
-
the local proxy is out of date and if so replaces it.
|
122
|
+
the local proxy is out of date and if so replaces it (via MD5 digests).
|
123
|
+
|
124
|
+
== Local proxy file cache
|
125
|
+
|
126
|
+
For basic usage, you don't need to worry about the cache, the default
|
127
|
+
settings work fine. But if you will be persisting proxy files you may want to
|
128
|
+
manage the cache more carefully.
|
129
|
+
|
130
|
+
=== Cache location
|
131
|
+
|
132
|
+
The cache for a given Defog::Proxy is rooted at a directory on the local
|
133
|
+
file system. You can set and query the root via
|
134
|
+
|
135
|
+
defog = Defog::Proxy.new(:provider => ..., :proxy_root => "/my/chosen/root")
|
136
|
+
defog.proxy_root # => returns a Pathname
|
117
137
|
|
118
|
-
|
119
|
-
locally persisted file (other than opening and closing it again without
|
120
|
-
:persist => true). But it's fair game to delete it outside of Defog, such
|
121
|
-
as via a cron job that cleans out old files.
|
138
|
+
If you don't specify a root, Defog uses one of two defaults:
|
122
139
|
|
123
|
-
|
140
|
+
{Rails.root}/tmp/defog/{provider}-{location} # if Rails is defined
|
141
|
+
{Dir.tmpdir}/defog/{provider}-{location} # if Rails is not defined
|
124
142
|
|
125
|
-
|
143
|
+
In these, <code>location</code> disambiguates between Defog::Proxy instances.
|
144
|
+
For :AWS it's the bucket name and for :local it's the
|
145
|
+
<code>local_root</code> directory path with slashes replaced with dashes.
|
126
146
|
|
127
|
-
|
147
|
+
[Why cache local files, you ask? Why not bypass this whole cache thing if
|
148
|
+
using :local? Well, the motivation for supporting :local is to use it in
|
149
|
+
development and use :AWS in production. So, to more faithfully mimic
|
150
|
+
production behavior, :local mode goes through the same code path and same
|
151
|
+
caching mechanism.]
|
128
152
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
<code>local_root</code> directory path with slashes replaced with underscores.
|
153
|
+
Within the cache, indvidiual proxy files are located by treating the key as
|
154
|
+
a path relative to the proxy root (with slashes in the key indicating
|
155
|
+
subdirectories in the path).
|
133
156
|
|
134
|
-
|
157
|
+
=== Cache size management
|
158
|
+
|
159
|
+
Defog can perform simple size management of the local proxy file cache. This is
|
160
|
+
of course useful mostly when persisting files.
|
161
|
+
|
162
|
+
You can specify a maximum cache size via:
|
163
|
+
|
164
|
+
defog = Defog::Proxy.new(:provider => ..., :max_cache_size => size-in-bytes)
|
165
|
+
|
166
|
+
If a maximum size is set, then before downloading data to create a proxy,
|
167
|
+
Defog will check the space available and delete persisted proxy files as needed
|
168
|
+
in LRU order. Does not delete files for proxies that are currently open.
|
169
|
+
If this would not free up enough space (because of open proxies or just
|
170
|
+
because the remote is larger than the cache), raises
|
171
|
+
Defog::Error::CacheFull and doesn't actually delete anything.
|
172
|
+
|
173
|
+
You can also manually delete an individual persisted file, such as via:
|
174
|
+
|
175
|
+
defog.file("key").proxy_path.unlink
|
176
|
+
|
177
|
+
And it's fair game to delete proxy files outside of Defog, such as via a
|
178
|
+
cron job. Of course in these cases it's up to you to make sure not to
|
179
|
+
unintentionally delete a proxy file that's currently open.
|
135
180
|
|
136
181
|
== Installation
|
137
182
|
|
@@ -141,9 +186,8 @@ Gemfile:
|
|
141
186
|
== Compatibility
|
142
187
|
|
143
188
|
Defog has (so far) been tested on MRI 1.9.3 using
|
144
|
-
[
|
189
|
+
fog[https://rubygems.org/gems/fog] storage providers :local and :AWS
|
145
190
|
|
146
191
|
== Copyright
|
147
192
|
|
148
193
|
Released under the MIT License. See LICENSE for details.
|
149
|
-
|
data/lib/defog/error.rb
CHANGED
data/lib/defog/file.rb
CHANGED
@@ -31,35 +31,40 @@ module Defog
|
|
31
31
|
# Upon closing the proxy file, in normal use the cloud storage gets synchronized and
|
32
32
|
# the proxy deleted. See File#close for more details.
|
33
33
|
class File < ::File
|
34
|
-
def self.get(opts={}, &block) #:nodoc:
|
35
|
-
opts = opts.keyword_args(:handle => :required, :mode => :required, :persist => :optional)
|
36
34
|
|
37
|
-
|
38
|
-
|
39
|
-
|
35
|
+
def initialize(opts={}, &block) #:nodoc:
|
36
|
+
opts = opts.keyword_args(:handle => :required, :mode => :required, :persist => :optional)
|
37
|
+
@handle = opts.handle
|
38
|
+
@persist = opts.persist
|
40
39
|
|
40
|
+
key = @handle.key
|
41
|
+
proxy_path = @handle.proxy_path
|
41
42
|
proxy_path.dirname.mkpath
|
42
|
-
|
43
43
|
case opts.mode
|
44
|
-
when "r"
|
45
|
-
|
46
|
-
when "w", "w+"
|
47
|
-
|
48
|
-
when "r+", "a", "a+"
|
49
|
-
|
50
|
-
|
44
|
+
when "r"
|
45
|
+
create_proxy
|
46
|
+
when "w", "w+"
|
47
|
+
@upload = true
|
48
|
+
when "r+", "a", "a+"
|
49
|
+
create_proxy
|
50
|
+
@upload = true
|
51
51
|
else
|
52
52
|
raise ArgumentError, "Invalid mode #{opts.mode.inspect}"
|
53
53
|
end
|
54
54
|
|
55
|
-
|
55
|
+
super(proxy_path, opts.mode, &block)
|
56
56
|
end
|
57
57
|
|
58
|
-
def
|
59
|
-
@
|
60
|
-
|
58
|
+
def create_proxy
|
59
|
+
@handle.proxy.open_proxy_file(@handle)
|
60
|
+
@handle.proxy.fog_wrapper.get_file(@handle.key, @handle.proxy_path)
|
61
|
+
end
|
62
|
+
|
63
|
+
def upload_proxy
|
64
|
+
@handle.proxy.fog_wrapper.put_file(@handle.key, @handle.proxy_path)
|
61
65
|
end
|
62
66
|
|
67
|
+
|
63
68
|
# Closes the proxy file and synchronizes the cloud storage (if it was
|
64
69
|
# opened as writeable) then deletes the proxy file.
|
65
70
|
#
|
@@ -75,13 +80,13 @@ module Defog
|
|
75
80
|
# (This will override the setting of <code>:persist</code> passed to Proxy#file)
|
76
81
|
#
|
77
82
|
def close(opts={})
|
78
|
-
opts = opts.keyword_args(:persist => @
|
83
|
+
opts = opts.keyword_args(:persist => @persist, :synchronize => true)
|
79
84
|
super()
|
80
|
-
|
81
|
-
|
82
|
-
handle.
|
83
|
-
handle.proxy_path.unlink unless opts.persist
|
85
|
+
if @handle.proxy_path.exist?
|
86
|
+
upload_proxy if @upload and opts.synchronize
|
87
|
+
@handle.proxy_path.unlink unless opts.persist
|
84
88
|
end
|
89
|
+
@handle.proxy.close_proxy_file(@handle)
|
85
90
|
end
|
86
91
|
end
|
87
92
|
end
|
data/lib/defog/handle.rb
CHANGED
@@ -93,8 +93,8 @@ module Defog
|
|
93
93
|
# to suppress deleting the file and so maintain the file after closing. See File#close for more
|
94
94
|
# details.
|
95
95
|
def open(mode, opts={}, &block)
|
96
|
-
opts = opts.keyword_args(:persist)
|
97
|
-
File.
|
96
|
+
opts = opts.keyword_args(:persist => @proxy.persist)
|
97
|
+
File.open(opts.merge(:handle => self, :mode => mode), &block)
|
98
98
|
end
|
99
99
|
|
100
100
|
end
|
data/lib/defog/proxy.rb
CHANGED
@@ -1,17 +1,20 @@
|
|
1
1
|
require "hash_keyword_args"
|
2
|
-
require "tmpdir"
|
3
2
|
require "pathname"
|
3
|
+
require "set"
|
4
|
+
require "tmpdir"
|
4
5
|
|
5
6
|
module Defog
|
6
7
|
class Proxy
|
7
8
|
|
8
|
-
attr_reader :proxy_root
|
9
|
+
attr_reader :proxy_root
|
10
|
+
attr_reader :persist
|
11
|
+
attr_reader :max_cache_size
|
9
12
|
attr_reader :fog_wrapper # :nodoc:
|
10
13
|
|
11
14
|
# Opens a <code>Fog</code> cloud storage connection to map to a corresponding proxy
|
12
15
|
# directory. Use via, e.g.,
|
13
16
|
#
|
14
|
-
# Defog::Proxy.new(:provider => :AWS, :aws_access_key_id => access_key, ...)
|
17
|
+
# defog = Defog::Proxy.new(:provider => :AWS, :aws_access_key_id => access_key, ...)
|
15
18
|
#
|
16
19
|
# The <code>:provider</code> and its corresponding options must be
|
17
20
|
# specified as per <code>Fog::Storage.new</code>. Currently, only
|
@@ -31,10 +34,27 @@ module Defog
|
|
31
34
|
# to worry about it. But if you do care, you can specify the option:
|
32
35
|
# :proxy_root => "/root/for/this/proxy/files"
|
33
36
|
#
|
37
|
+
# You can turn on persistence of local proxy files by specifying
|
38
|
+
# :persist => true
|
39
|
+
# The persistence behavior can be overriden on a per-file basis when
|
40
|
+
# opening a proxy (see Defog::Handle#open)
|
41
|
+
#
|
42
|
+
# You can enable cache management by specifying a max cache size in
|
43
|
+
# bytes, e.g.
|
44
|
+
# :max_cache_size => 3.gigabytes
|
45
|
+
# See the README for discussion. [Number#gigabytes is defined in
|
46
|
+
# Rails' ActiveSupport core extensions]
|
34
47
|
def initialize(opts={})
|
35
|
-
opts = opts.keyword_args(:provider => :required,
|
48
|
+
opts = opts.keyword_args(:provider => :required,
|
49
|
+
:proxy_root => :optional,
|
50
|
+
:persist => :optional,
|
51
|
+
:max_cache_size => :optional,
|
52
|
+
:OTHERS => :optional)
|
36
53
|
|
37
54
|
@proxy_root = Pathname.new(opts.delete(:proxy_root)) if opts.proxy_root
|
55
|
+
@persist = opts.delete(:persist)
|
56
|
+
@max_cache_size = opts.delete(:max_cache_size)
|
57
|
+
@open_proxy_paths = Set.new
|
38
58
|
|
39
59
|
@fog_wrapper = FogWrapper.connect(opts)
|
40
60
|
|
@@ -69,12 +89,13 @@ module Defog
|
|
69
89
|
@fog_wrapper.fog_directory
|
70
90
|
end
|
71
91
|
|
72
|
-
# Proxy a remote cloud file. Returns a Defog::Handle object that
|
92
|
+
# Proxy a remote cloud file. Returns or yields a Defog::Handle object that
|
73
93
|
# represents the file.
|
74
94
|
#
|
75
|
-
# If a <code>mode</code> is
|
95
|
+
# If a <code>mode</code> is given, opens a proxy file via
|
76
96
|
# Defog::Handle#open (passing it the mode and other options and
|
77
|
-
# optional block), returning instead the Defog::File object.
|
97
|
+
# optional block), returning or yielding instead the Defog::File object.
|
98
|
+
#
|
78
99
|
#
|
79
100
|
# Thus
|
80
101
|
# proxy.file("key", mode, options, &block)
|
@@ -90,5 +111,54 @@ module Defog
|
|
90
111
|
end
|
91
112
|
end
|
92
113
|
|
114
|
+
def open_proxy_file(handle) #:nodoc:
|
115
|
+
manage_cache(handle) if max_cache_size
|
116
|
+
@open_proxy_paths << handle.proxy_path
|
117
|
+
end
|
118
|
+
|
119
|
+
def close_proxy_file(handle) #:nodoc:
|
120
|
+
@open_proxy_paths.delete handle.proxy_path
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
def manage_cache(handle)
|
126
|
+
remote_size = handle.size
|
127
|
+
proxy_path = handle.proxy_path
|
128
|
+
|
129
|
+
# find available space (not counting current proxy)
|
130
|
+
available = max_cache_size
|
131
|
+
proxy_root.find { |path| available -= path.size if path.file? and path != proxy_path}
|
132
|
+
return if available >= remote_size
|
133
|
+
|
134
|
+
space_needed = remote_size - available
|
135
|
+
|
136
|
+
# find all paths in the cache that aren't currently open (not
|
137
|
+
# counting current proxy)
|
138
|
+
candidates = []
|
139
|
+
proxy_root.find { |path| candidates << path if path.file? and not @open_proxy_paths.include?(path) and path != proxy_path}
|
140
|
+
|
141
|
+
# take candidates in LRU order until that would be enough space
|
142
|
+
would_free = 0
|
143
|
+
candidates = Set.new(candidates.sort_by(&:atime).take_while{|path| (would_free < space_needed).tap{|condition| would_free += path.size}})
|
144
|
+
|
145
|
+
# still not enough...?
|
146
|
+
raise Error::CacheFull, "No room in cache for #{handle.key.inspect}: size=#{remote_size} available=#{available} can_free=#{would_free}, max_cache_size=#{max_cache_size}" if would_free < space_needed
|
147
|
+
|
148
|
+
# LRU order may have taken more than needed, if last file was a big
|
149
|
+
# chunk. So take another pass, eliminating files that aren't needed.
|
150
|
+
# Do this in reverse size order, since we want to keep big files in
|
151
|
+
# the cache if possible since they're most expensive to replace.
|
152
|
+
candidates.sort_by(&:size).reverse.each do |path|
|
153
|
+
if (would_free - path.size) > space_needed
|
154
|
+
candidates.delete path
|
155
|
+
would_free -= path.size
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# free the remaining candidates
|
160
|
+
candidates.each(&:unlink)
|
161
|
+
end
|
162
|
+
|
93
163
|
end
|
94
164
|
end
|
data/lib/defog/version.rb
CHANGED
data/spec/proxy_spec.rb
CHANGED
@@ -2,25 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
shared_examples "a proxy" do |args|
|
4
4
|
|
5
|
-
|
6
|
-
proxy = Defog::Proxy.new(args)
|
7
|
-
proxy.proxy_root.should == Pathname.new(Dir.tmpdir) + "defog" + proxy.provider.to_s + proxy.location
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should default proxy root to Rails.root" do
|
11
|
-
with_rails_defined do
|
12
|
-
proxy = Defog::Proxy.new(args)
|
13
|
-
proxy.proxy_root.should == Rails.root + "tmp/defog" + proxy.provider.to_s + proxy.location
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should accept proxy root parameter" do
|
18
|
-
path = Pathname.new("/a/random/path")
|
19
|
-
proxy = Defog::Proxy.new(args.merge(:proxy_root => path))
|
20
|
-
proxy.proxy_root.should == path
|
21
|
-
end
|
22
|
-
|
23
|
-
context do
|
5
|
+
context "basic features" do
|
24
6
|
before(:each) do
|
25
7
|
@proxy = Defog::Proxy.new(args)
|
26
8
|
end
|
@@ -57,6 +39,123 @@ shared_examples "a proxy" do |args|
|
|
57
39
|
end
|
58
40
|
end
|
59
41
|
|
42
|
+
context "proxy root location" do
|
43
|
+
it "should default proxy root to tmpdir/defog" do
|
44
|
+
proxy = Defog::Proxy.new(args)
|
45
|
+
proxy.proxy_root.should == Pathname.new(Dir.tmpdir) + "defog" + proxy.provider.to_s + proxy.location
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should default proxy root to Rails.root" do
|
49
|
+
with_rails_defined do
|
50
|
+
proxy = Defog::Proxy.new(args)
|
51
|
+
proxy.proxy_root.should == Rails.root + "tmp/defog" + proxy.provider.to_s + proxy.location
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should accept proxy root parameter" do
|
56
|
+
path = Pathname.new("/a/random/path")
|
57
|
+
proxy = Defog::Proxy.new(args.merge(:proxy_root => path))
|
58
|
+
proxy.proxy_root.should == path
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "cache management" do
|
63
|
+
before(:each) do
|
64
|
+
@proxy = Defog::Proxy.new(args.merge(:max_cache_size => 100, :persist => true))
|
65
|
+
@proxy.proxy_root.rmtree
|
66
|
+
@proxy.proxy_root.mkpath
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should raise an error trying to proxy a file larger than the cache" do
|
70
|
+
create_remote("x" * 101)
|
71
|
+
expect { @proxy.file(key, "r") }.should raise_error(Defog::Error::CacheFull)
|
72
|
+
proxy_path.should_not be_exist
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should not count existing proxy in total" do
|
76
|
+
create_proxy("y" * 70)
|
77
|
+
create_remote("x" * 70)
|
78
|
+
expect { @proxy.file(key, "r") do end }.should_not raise_error(Defog::Error::CacheFull)
|
79
|
+
proxy_path.should be_exist
|
80
|
+
proxy_path.read.should == remote_body
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should delete proxies to make room" do
|
84
|
+
create_other_proxy("a", 10)
|
85
|
+
create_other_proxy("b", 30)
|
86
|
+
create_other_proxy("c", 40)
|
87
|
+
create_remote("x" * 80)
|
88
|
+
expect { @proxy.file(key, "r") do end }.should_not raise_error(Defog::Error::CacheFull)
|
89
|
+
proxy_path.should be_exist
|
90
|
+
other_proxy_path("a").should be_exist
|
91
|
+
other_proxy_path("b").should_not be_exist
|
92
|
+
other_proxy_path("c").should_not be_exist
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should not delete proxies that are open" do
|
96
|
+
create_other_proxy("a", 20)
|
97
|
+
create_other_proxy("b", 20)
|
98
|
+
create_other_remote("R", 30)
|
99
|
+
create_other_remote("S", 30)
|
100
|
+
create_remote("x" * 30)
|
101
|
+
@proxy.file("R", "r") do
|
102
|
+
@proxy.file("S", "r") do
|
103
|
+
expect { @proxy.file(key, "r") do end }.should_not raise_error(Defog::Error::CacheFull)
|
104
|
+
proxy_path.should be_exist
|
105
|
+
other_proxy_path("a").should_not be_exist
|
106
|
+
other_proxy_path("b").should_not be_exist
|
107
|
+
other_proxy_path("R").should be_exist
|
108
|
+
other_proxy_path("S").should be_exist
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should delete proxies that are no longer open" do
|
114
|
+
create_other_remote("R", 60)
|
115
|
+
create_remote("z" * 60)
|
116
|
+
@proxy.file("R", "r") do end
|
117
|
+
other_proxy_path("R").should be_exist
|
118
|
+
expect { @proxy.file(key, "r") do end }.should_not raise_error(Defog::Error::CacheFull)
|
119
|
+
proxy_path.should be_exist
|
120
|
+
other_proxy_path("R").should_not be_exist
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should not delete proxies if there wouldn't be enough space" do
|
124
|
+
create_other_proxy("a", 20)
|
125
|
+
create_other_proxy("b", 20)
|
126
|
+
create_other_remote("r", 30)
|
127
|
+
create_other_remote("s", 30)
|
128
|
+
create_remote("z" * 50)
|
129
|
+
@proxy.file("r", "r") do
|
130
|
+
@proxy.file("s", "r") do
|
131
|
+
expect { @proxy.file(key, "r") do end }.should raise_error(Defog::Error::CacheFull)
|
132
|
+
proxy_path.should_not be_exist
|
133
|
+
other_proxy_path("a").should be_exist
|
134
|
+
other_proxy_path("b").should be_exist
|
135
|
+
other_proxy_path("r").should be_exist
|
136
|
+
other_proxy_path("s").should be_exist
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
def create_other_proxy(otherkey, size)
|
144
|
+
other_proxy_path(otherkey).open("w") do |f|
|
145
|
+
f.write("x" * size)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def other_proxy_path(otherkey)
|
150
|
+
@proxy.file(otherkey).proxy_path
|
151
|
+
end
|
152
|
+
|
153
|
+
def create_other_remote(otherkey, size)
|
154
|
+
@proxy.fog_directory.files.create(:key => otherkey, :body => "x" * size)
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
|
60
159
|
end
|
61
160
|
|
62
161
|
describe Defog::Proxy do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: defog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-04-27 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fog
|
16
|
-
requirement: &
|
16
|
+
requirement: &70234406646360 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70234406646360
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: hash_keyword_args
|
27
|
-
requirement: &
|
27
|
+
requirement: &70234406645920 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70234406645920
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: fastandand
|
38
|
-
requirement: &
|
38
|
+
requirement: &70234406645400 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70234406645400
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rake
|
49
|
-
requirement: &
|
49
|
+
requirement: &70234406644900 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70234406644900
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rspec
|
60
|
-
requirement: &
|
60
|
+
requirement: &70234406644280 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70234406644280
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: simplecov
|
71
|
-
requirement: &
|
71
|
+
requirement: &70234406643420 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70234406643420
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: simplecov-gem-adapter
|
82
|
-
requirement: &
|
82
|
+
requirement: &70234406643000 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70234406643000
|
91
91
|
description: Wrapper to fog gem, proxying access to cloud files as local files.
|
92
92
|
email:
|
93
93
|
- ronen@barzel.org
|