s3cp 1.1.17 → 1.1.18

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,27 @@
1
+ === 1.1.18 (2013-02-05)
2
+
3
+ * Fixed: Add new `s3lifecycle` command to manage object transtion rules.
4
+
5
+ A few examples:
6
+
7
+ # Show lifecycle rules for bucket
8
+ % s3lifecycle s3://bucket
9
+
10
+ # Add expiration rule (expire after 180 days)
11
+ % s3lifecycle --name "Optional name" --expire 180 s3://bucket/below/some/path/
12
+
13
+ # Transition objects to Glacier after 180 days
14
+ % s3lifecycle --glacier 180 s3://bucket/below/some/path/
15
+
16
+ # Transition objects to Glacier after 2013-03-29
17
+ % s3lifecycle --glacier 2013-03-29 s3://bucket/below/some/path/
18
+
19
+ # Enable rule by path (you can use --name to enable by name)
20
+ % s3lifecycle --enable s3://bucket/below/some/path/
21
+
22
+ # Disable rule by name
23
+ % s3lifecycle --disable --name "Some rule" s3://bucket
24
+
1
25
  === 1.1.17 (2013-02-05)
2
26
 
3
27
  * Fixed: Speed-up `s3du` (same dealio as s3ls -l from version 1.1.14)
data/bin/s3lifecycle ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 's3cp/s3lifecycle'
3
+
4
+
@@ -0,0 +1,168 @@
1
+ # Copyright (C) 2010-2012 Alex Boisvert and Bizo Inc. / All rights reserved.
2
+ #
3
+ # Licensed to the Apache Software Foundation (ASF) under one or more contributor
4
+ # license agreements. See the NOTICE file distributed with this work for
5
+ # additional information regarding copyright ownership. The ASF licenses this
6
+ # file to you under the Apache License, Version 2.0 (the "License"); you may not
7
+ # use this file except in compliance with the License. You may obtain a copy of
8
+ # the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
+ # License for the specific language governing permissions and limitations under
16
+ # the License.
17
+
18
+ require 's3cp/utils'
19
+
20
+ # Default options
21
+ options = { :verbose => false }
22
+
23
+ # Setup cli params
24
+ op = OptionParser.new do |opts|
25
+ opts.banner = <<-BANNER
26
+ s3lifecycle [COMMANDS] prefix
27
+ BANNER
28
+ opts.separator ''
29
+
30
+ opts.on("--verbose", "Verbose mode") do
31
+ options[:verbose] = true
32
+ end
33
+
34
+ opts.on("--name NAME", "Rule identifier optionally used in combination with --expire/glacier/enable/disable/remove") do |name|
35
+ options[:name] = name
36
+ end
37
+
38
+ opts.on("--expire DAYS_OR_DATE", "Expire object(s) after given number of days or specific date (YYYY-MM-DD)") do |time|
39
+ options[:expire] = S3CP.parse_days_or_date(time)
40
+ end
41
+
42
+ opts.on("--glacier DAYS_OR_DATE", "Transition objects to Glacier after given number of days or specific date (YYYY-MM-DD)") do |time|
43
+ options[:glacier] = S3CP.parse_days_or_date(time)
44
+ end
45
+
46
+ opts.on("--enable", "Enable rule(s) for expiration/glacier object transition") do
47
+ options[:enable] = true
48
+ end
49
+
50
+ opts.on("--disable", "Disable rule(s) for expiration/glacier object transition") do
51
+ options[:disable] = true
52
+ end
53
+
54
+ opts.on("--delete", "Delete rule(s) for expiration/glacier object transition") do
55
+ options[:delete] = true
56
+ end
57
+
58
+ opts.on_tail("-h", "--help", "Show this message") do
59
+ puts op
60
+ exit
61
+ end
62
+ end
63
+
64
+ p options.inspect if options[:verbose]
65
+
66
+ op.parse!(ARGV)
67
+ paths = ARGV
68
+
69
+ if ARGV.size == 0
70
+ puts op
71
+ exit
72
+ end
73
+
74
+ S3CP.load_config()
75
+ @s3 = S3CP.connect()
76
+
77
+ def time_or_date_str(msg, t)
78
+ if t.is_a?(Fixnum) || t.to_s =~ /^\d+$/
79
+ "%s after %d days" % [msg, t.to_i]
80
+ else
81
+ "%s on %s" % [msg, t]
82
+ end
83
+ end
84
+
85
+ def rule_to_str(r)
86
+ if r.expiration_time
87
+ [ r.prefix, r.id, r.status, time_or_date_str("Expire", r.expiration_time)]
88
+ elsif r.glacier_transition_time
89
+ [ r.prefix, r.id, r.status, time_or_date_str("Glacier", r.glacier_transition_time)]
90
+ else
91
+ [ r.prefix, r.id, r.status, "???"]
92
+ end
93
+ end
94
+
95
+ paths.each do |path|
96
+ bucket,key = S3CP.bucket_and_key(path)
97
+ fail "Invalid bucket/key: #{path}" unless key
98
+
99
+ case
100
+
101
+ when options[:expire]
102
+ @s3.buckets[bucket].lifecycle_configuration.update do
103
+ rule_options = {}
104
+ rule_options[:id] = options[:name] if options[:name]
105
+ rule_options[:expiration_time] = S3CP.parse_days_or_date(options[:expire])
106
+ add_rule(key, rule_options)
107
+ end
108
+
109
+ when options[:glacier]
110
+ @s3.buckets[bucket].lifecycle_configuration.update do
111
+ rule_options = {}
112
+ rule_options[:id] = options[:name] if options[:name]
113
+ rule_options[:glacier_transition_time] = S3CP.parse_days_or_date(options[:glacier])
114
+ add_rule(key, rule_options)
115
+ end
116
+
117
+ when options[:enable]
118
+ success = false
119
+ @s3.buckets[bucket].lifecycle_configuration.update do
120
+ self.rules.each do |r|
121
+ if (r.prefix == key) || (r.id == options[:name])
122
+ r.enable!
123
+ puts "Enabled rule: "
124
+ puts S3CP.tableify([rule_to_str(r)])
125
+ success = true
126
+ end
127
+ end
128
+ end
129
+ fail "Rule or prefix not found" unless success
130
+
131
+ when options[:disable]
132
+ success = false
133
+ @s3.buckets[bucket].lifecycle_configuration.update do
134
+ self.rules.each do |r|
135
+ if (r.prefix == key) || (r.id == options[:name])
136
+ r.disabled!
137
+ puts "Disabled rule: "
138
+ puts S3CP.tableify([rule_to_str(r)])
139
+ success = true
140
+ end
141
+ end
142
+ end
143
+ fail "Rule or prefix not found" unless success
144
+
145
+ when options[:delete]
146
+ success = false
147
+ @s3.buckets[bucket].lifecycle_configuration.update do
148
+ self.rules.each do |r|
149
+ if (r.prefix == key) || (r.id == options[:name])
150
+ remove_rule(r)
151
+ puts "Deleted rule: "
152
+ puts S3CP.tableify([rule_to_str(r)])
153
+ success = true
154
+ end
155
+ end
156
+ end
157
+ fail "Rule or prefix not found" unless success
158
+
159
+ else
160
+ puts "Lifecycle rules:"
161
+ rules = @s3.buckets[bucket].lifecycle_configuration.rules.to_a
162
+ if rules.empty?
163
+ puts "No lifecycle rules"
164
+ else
165
+ puts S3CP.tableify(rules.map { |r| rule_to_str(r) })
166
+ end
167
+ end
168
+ end
data/lib/s3cp/utils.rb CHANGED
@@ -91,6 +91,24 @@ module S3CP
91
91
  headers
92
92
  end
93
93
 
94
+ # Convert a series of rows [["one", "two", "three3"], ["foo", "bar", "baz"], ...]
95
+ # into a table-format.
96
+ def tableify(rows)
97
+ return "" if rows.nil? || rows.empty?
98
+ cols = rows[0].size
99
+ widths = (1..cols).map { |c| rows.map { |r| r[c-1].length }.max }
100
+ format = widths[0..-2].map { |w| "%-#{w}s" }.join(" ") + " %s"
101
+ rows.map { |r| format % r }.join("\n")
102
+ end
103
+
104
+ def parse_days_or_date(d)
105
+ if d.to_s =~ /^\d+$/
106
+ d.to_i
107
+ else
108
+ Date.parse(d)
109
+ end
110
+ end
111
+
94
112
  # Round a number at some `decimals` level of precision.
95
113
  def round(n, decimals = 0)
96
114
  (n * (10.0 ** decimals)).round * (10.0 ** (-decimals))
data/lib/s3cp/version.rb CHANGED
@@ -16,5 +16,5 @@
16
16
  # the License.
17
17
 
18
18
  module S3CP
19
- VERSION = "1.1.17"
19
+ VERSION = "1.1.18"
20
20
  end
data/lib/s3cp.rb ADDED
@@ -0,0 +1 @@
1
+ require 's3cp/utils'
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: 49
4
+ hash: 55
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 1
9
- - 17
10
- version: 1.1.17
9
+ - 18
10
+ version: 1.1.18
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-02-05 00:00:00 Z
18
+ date: 2013-02-06 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  version_requirements: &id001 !ruby/object:Gem::Requirement
@@ -54,12 +54,12 @@ dependencies:
54
54
  requirements:
55
55
  - - ~>
56
56
  - !ruby/object:Gem::Version
57
- hash: 9
57
+ hash: 53
58
58
  segments:
59
59
  - 1
60
- - 6
61
- - 3
62
- version: 1.6.3
60
+ - 8
61
+ - 1
62
+ version: 1.8.1
63
63
  requirement: *id003
64
64
  type: :runtime
65
65
  prerelease: false
@@ -123,6 +123,7 @@ executables:
123
123
  - s3dir
124
124
  - s3du
125
125
  - s3edit
126
+ - s3lifecycle
126
127
  - s3ls
127
128
  - s3mod
128
129
  - s3mv
@@ -136,6 +137,7 @@ extra_rdoc_files:
136
137
  - README.md
137
138
  - History.txt
138
139
  files:
140
+ - lib/s3cp.rb
139
141
  - lib/s3cp/s3cat.rb
140
142
  - lib/s3cp/s3tree.rb
141
143
  - lib/s3cp/#Untitled-5#
@@ -148,6 +150,7 @@ files:
148
150
  - lib/s3cp/s3cp.rb
149
151
  - lib/s3cp/s3stat.rb
150
152
  - lib/s3cp/utils.rb
153
+ - lib/s3cp/s3lifecycle.rb
151
154
  - lib/s3cp/s3rm.rb
152
155
  - lib/s3cp/s3up.rb
153
156
  - History.txt
@@ -165,6 +168,7 @@ files:
165
168
  - bin/s3cp_complete
166
169
  - bin/s3du
167
170
  - bin/s3cp
171
+ - bin/s3lifecycle
168
172
  - bin/s3rm
169
173
  - bin/s3stat
170
174
  homepage: