s3cp 1.1.12 → 1.1.13

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,12 @@
1
+ === 1.1.13 (2013-01-27)
2
+
3
+ * Added: s3stat --acl option to display associated access-control list XML document.
4
+
5
+ * Added: s3mod now accepts multiple (wildcard) paths and supports setting both
6
+ --headers and --acl. (Denis Arh).
7
+
8
+ * Fixed: Beter metadata display in s3stat.
9
+
1
10
  === 1.1.12 (2013-01-22)
2
11
 
3
12
  * Added: Support for 'Content-Disposition' header (Denis Arh).
@@ -17,17 +17,51 @@
17
17
 
18
18
  require 's3cp/utils'
19
19
 
20
+ # Default options
21
+ options = {
22
+ :verbose => false,
23
+ :acl => nil,
24
+ :headers => []
25
+ }
26
+
27
+ # Setup cli params
20
28
  op = OptionParser.new do |opts|
21
- opts.banner = "s3mod [path] [permission]"
29
+ opts.banner = "s3mod [path(s)]"
30
+
31
+ opts.banner = <<-BANNER
32
+ s3mod [path(s)] ([permission])
33
+
34
+ Multiple paths with multiple wildcards are supported:
35
+ s3://bucket/path/*foo/*/bar*.jpg
36
+
37
+ LEGACY SUPPORT
38
+
39
+ This tool still supports old paramater format:
40
+ % s3mod [path] [permission]
41
+ You are encouraged to use --acl instead of passing permission as last parameter.
42
+
43
+ WARNINGS:
44
+
45
+ 1) Due to limitations in AWS's S3 API, when you use --headers all ACL
46
+ properties are removed from the S3 object.
47
+
48
+ 2) Due to limitations in AWS's S3 API, this command fails on S3 objects
49
+ larger then 5Gb.
50
+
51
+ BANNER
52
+ opts.separator ''
53
+
54
+ opts.on("--verbose", "Verbose mode") do
55
+ options[:verbose] = true
56
+ end
22
57
 
23
- opts.separator ""
24
- opts.separator "where [permission] is one of:"
25
- opts.separator ""
26
- opts.separator " * private"
27
- opts.separator " * authenticated-read"
28
- opts.separator " * public-read"
29
- opts.separator " * public-read-write"
30
- opts.separator ""
58
+ opts.on('--headers \'Header1: Header1Value\',\'Header2: Header2Value\'', Array, "Headers to set on the item in S3." ) do |h|
59
+ options[:headers] = h
60
+ end
61
+
62
+ opts.on("--acl PERMISSION", "One of 'private', 'authenticated-read', 'public-read', 'public-read-write'") do |permission|
63
+ options[:acl] = S3CP.validate_acl(permission)
64
+ end
31
65
 
32
66
  opts.on_tail("-h", "--help", "Show this message") do
33
67
  puts op
@@ -36,22 +70,36 @@ op = OptionParser.new do |opts|
36
70
  end
37
71
 
38
72
  op.parse!(ARGV)
73
+ paths = ARGV
39
74
 
40
- if ARGV.size < 2
75
+ if ARGV.size < 1 || !options[:headers]
41
76
  puts op
42
77
  exit
43
78
  end
44
79
 
45
- def update_permissions(s3, bucket, key, permission)
46
- puts "Setting #{permission} on s3://#{bucket}/#{key}"
47
- s3.buckets[bucket].objects[key].acl = permission
80
+ # Legacy (support for s3mod [path] [acl] )
81
+ # See if last param starts with "s3://", validate & remove it from list of paths
82
+ if !options[:acl] && paths.size > 1 && S3CP::LEGAL_MODS.include?(paths.last)
83
+ options[:acl] = S3CP.validate_acl(paths.pop);
48
84
  end
49
85
 
50
- source = ARGV[0]
51
- permission = S3CP.validate_acl(ARGV.last)
52
-
53
86
  S3CP.load_config()
54
-
55
87
  @s3 = S3CP.connect()
56
- bucket,key = S3CP.bucket_and_key(source)
57
- update_permissions(@s3, bucket, key, permission)
88
+
89
+ paths.each do |path|
90
+ bucket,key = S3CP.bucket_and_key(path)
91
+ fail "Invalid bucket/key: #{path}" unless key
92
+
93
+ S3CP.objects_by_wildcard(@s3.buckets[bucket], key) { | obj |
94
+ puts "s3://#{bucket}/#{obj.key}"
95
+
96
+ if options[:headers].size > 0
97
+ current_medata = obj.metadata
98
+ object_metadata = S3CP.set_header_options(current_medata, S3CP.headers_array_to_hash(options[:headers]))
99
+ end
100
+
101
+ if options[:acl]
102
+ obj.acl = options[:acl]
103
+ end
104
+ }
105
+ end
@@ -17,9 +17,15 @@
17
17
 
18
18
  require 's3cp/utils'
19
19
 
20
+ @options = {}
21
+
20
22
  op = OptionParser.new do |opts|
21
23
  opts.banner = "s3stat [path]"
22
24
 
25
+ opts.on("--acl", "Display Access Control List XML document") do
26
+ @options[:acl] = true
27
+ end
28
+
23
29
  opts.on_tail("-h", "--help", "Show this message") do
24
30
  puts op
25
31
  exit
@@ -43,8 +49,15 @@ S3CP.load_config()
43
49
 
44
50
  @s3 = S3CP.connect().buckets[@bucket]
45
51
 
46
- metadata = @s3.objects[@key].head
52
+ obj = @s3.objects[@key]
53
+
54
+ metadata = obj.head
47
55
  metadata.keys.sort { |k1, k2| k1.to_s <=> k2.to_s}.each do |k|
48
- puts "#{"%30s" % k} #{metadata[k]}"
56
+ puts "#{"%30s" % k} #{metadata[k].is_a?(Hash) ? metadata[k].inspect : metadata[k].to_s}"
49
57
  end
50
58
 
59
+ if @options[:acl]
60
+ puts
61
+ xml = Nokogiri::XML(obj.acl.to_s)
62
+ puts xml.to_s
63
+ end
@@ -175,8 +175,9 @@ module S3CP
175
175
  end
176
176
  end
177
177
 
178
-
179
- options[:metadata] = remaining unless remaining.empty?
178
+ remaining.each do |k,v|
179
+ options[k] = v
180
+ end
180
181
 
181
182
  options
182
183
  end
@@ -187,6 +188,31 @@ module S3CP
187
188
  end
188
189
  permission
189
190
  end
191
+
192
+ # Yield to block for all objects matching key_regex
193
+ def objects_by_wildcard(bucket, key_regex, &block)
194
+ # First, trim multiple wildcards & wildcards on the end
195
+ key = key_regex.gsub(/\*+/, '*')
196
+
197
+ if 0 < key.count('*')
198
+ key_split = key.split('*', 2);
199
+ kpfix = key_split.shift(); # ignore first part as AWS API takes it as a prefix
200
+ regex = []
201
+
202
+ key_split.each do |kpart|
203
+ regex.push Regexp.quote(kpart)
204
+ end
205
+
206
+ regex = regex.empty? ? nil : Regexp.new(regex.join('.*') + '$');
207
+
208
+ bucket.objects.with_prefix(kpfix).each do |obj|
209
+ yield obj if regex == nil || regex.match(obj.key[kpfix.size..-1])
210
+ end
211
+ else
212
+ # no wildcards, simple:
213
+ yield bucket.objects[key]
214
+ end
215
+ end
190
216
  end
191
217
 
192
218
  # Monkey-patch S3 object for download streaming
@@ -16,5 +16,5 @@
16
16
  # the License.
17
17
 
18
18
  module S3CP
19
- VERSION = "1.1.12"
19
+ VERSION = "1.1.13"
20
20
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: s3cp
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
4
+ hash: 9
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 1
9
- - 12
10
- version: 1.1.12
9
+ - 13
10
+ version: 1.1.13
11
11
  platform: ruby
12
12
  authors:
13
13
  - Alex Boisvert
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2013-01-22 00:00:00 Z
18
+ date: 2013-01-27 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  version_requirements: &id001 !ruby/object:Gem::Requirement