ey-flex-test 0.3.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/LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +48 -0
- data/TODO +4 -0
- data/bin/ey-agent +17 -0
- data/bin/ey-monitor +10 -0
- data/bin/ey-recipes +133 -0
- data/bin/ey-slave +7 -0
- data/bin/ey-snapshots +52 -0
- data/bin/eybackup +70 -0
- data/lib/big-brother.rb +66 -0
- data/lib/bucket_minder.rb +110 -0
- data/lib/ey-api.rb +22 -0
- data/lib/ey.rb +305 -0
- data/lib/mysql_backup.rb +127 -0
- data/lib/mysql_slave.rb +22 -0
- data/lib/postgresql_backup.rb +31 -0
- data/lib/snapshot_minder.rb +157 -0
- data/lib/stonith.rb +194 -0
- data/spec/ey_api_spec.rb +74 -0
- metadata +75 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Engine Yard Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'rubygems/specification'
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
GEM = "ey-flex-test"
|
7
|
+
GEM_VERSION = "0.3.3"
|
8
|
+
AUTHOR = "Ezra Zygmuntowicz"
|
9
|
+
EMAIL = "awsmdev@engineyard.com"
|
10
|
+
HOMEPAGE = "http://engineyard.com/solo"
|
11
|
+
SUMMARY = "Command line interface to Engine Yard's cloud"
|
12
|
+
|
13
|
+
spec = Gem::Specification.new do |s|
|
14
|
+
s.name = GEM
|
15
|
+
s.version = GEM_VERSION
|
16
|
+
s.platform = Gem::Platform::RUBY
|
17
|
+
s.has_rdoc = true
|
18
|
+
s.extra_rdoc_files = ["README.rdoc", "LICENSE", 'TODO']
|
19
|
+
s.summary = SUMMARY
|
20
|
+
s.description = s.summary
|
21
|
+
s.author = AUTHOR
|
22
|
+
s.email = EMAIL
|
23
|
+
s.homepage = HOMEPAGE
|
24
|
+
s.bindir = "bin"
|
25
|
+
s.executables = %w( ey-slave ey-recipes eybackup ey-snapshots ey-monitor ey-agent)
|
26
|
+
# Uncomment this to add a dependency
|
27
|
+
# s.add_dependency "foo"
|
28
|
+
|
29
|
+
s.require_path = 'lib'
|
30
|
+
s.autorequire = GEM
|
31
|
+
s.files = %w(LICENSE README.rdoc Rakefile TODO) + Dir.glob("{lib,spec}/**/*")
|
32
|
+
end
|
33
|
+
|
34
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
35
|
+
pkg.gem_spec = spec
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "install the gem locally"
|
39
|
+
task :install => [:package] do
|
40
|
+
sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "create a gemspec file"
|
44
|
+
task :make_spec do
|
45
|
+
File.open("#{GEM}.gemspec", "w") do |file|
|
46
|
+
file.puts spec.to_ruby
|
47
|
+
end
|
48
|
+
end
|
data/TODO
ADDED
data/bin/ey-agent
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'json'
|
3
|
+
require 'big-brother'
|
4
|
+
|
5
|
+
json = JSON.parse(IO.read('/etc/chef/dna.json'))
|
6
|
+
|
7
|
+
|
8
|
+
# {'skip':[
|
9
|
+
# 'mysqld'
|
10
|
+
# ],
|
11
|
+
# 'check':[
|
12
|
+
# 'ttsrv'
|
13
|
+
# ]}
|
14
|
+
|
15
|
+
skips = JSON.parse(IO.read('/etc/ey-alerts.json')) rescue {}
|
16
|
+
|
17
|
+
puts EY::BigBrother.new(json.merge(skips)).check
|
data/bin/ey-monitor
ADDED
data/bin/ey-recipes
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'yaml'
|
4
|
+
require "optparse"
|
5
|
+
require "json"
|
6
|
+
require 'ey'
|
7
|
+
|
8
|
+
defaults = {:config => '~/.ey-cloud.yml',
|
9
|
+
:command => :get_envs,
|
10
|
+
:type => 'recipes',
|
11
|
+
:keep => 5}
|
12
|
+
options = {}
|
13
|
+
# Build a parser for the command line arguments
|
14
|
+
opts = OptionParser.new do |opts|
|
15
|
+
opts.version = "0.0.1"
|
16
|
+
|
17
|
+
opts.banner = "Usage: ey-recipes [-flag] [argument]"
|
18
|
+
opts.define_head "ey-recipes: managing your recipes..."
|
19
|
+
opts.separator '*'*80
|
20
|
+
|
21
|
+
opts.on("-l", "--list-recipes ENV", "List recipes for ENV") do |env|
|
22
|
+
options[:env] = env
|
23
|
+
options[:command] = :list
|
24
|
+
end
|
25
|
+
|
26
|
+
opts.on("-j", "--json ENV", "Get The DNA JSON for ENV") do |env|
|
27
|
+
options[:env] = env
|
28
|
+
options[:command] = :get_json
|
29
|
+
end
|
30
|
+
|
31
|
+
opts.on("-q", "--quick", "Run only the recipes required for a quick redeploy") do
|
32
|
+
options[:quick] = true
|
33
|
+
end
|
34
|
+
|
35
|
+
opts.on("-c", "--config CONFIG", "Use config file.") do |config|
|
36
|
+
options[:config] = config
|
37
|
+
end
|
38
|
+
|
39
|
+
opts.on("-r", "--rollback ENV", "Roll back to the previous recipe set for ENV and run them on your instances.") do |env|
|
40
|
+
options[:env] = env
|
41
|
+
options[:command] = :rollback
|
42
|
+
end
|
43
|
+
|
44
|
+
opts.on("-d", "--deploy ENV", "Upload a new recipe set and run them on your instances. Be sure to commit your changes to your git repo before deploying as we create a git archive of HEAD.") do |env|
|
45
|
+
options[:command] = :deploy
|
46
|
+
options[:identifier] = 'recipes'
|
47
|
+
options[:env] = env
|
48
|
+
end
|
49
|
+
|
50
|
+
opts.on("-u", "--upload ENV", "Upload a new recipe set so s3 but don't run it. Be sure to commit your changes to your git repo before deploying as we create a git archive of HEAD.") do |env|
|
51
|
+
options[:command] = :upload
|
52
|
+
options[:identifier] = 'recipes'
|
53
|
+
options[:env] = env
|
54
|
+
end
|
55
|
+
|
56
|
+
opts.on("--clear ENV", "Clear out any customer recipes attached to ENV") do |env|
|
57
|
+
options[:command] = :clear
|
58
|
+
options[:identifier] = 'recipes'
|
59
|
+
options[:env] = env
|
60
|
+
end
|
61
|
+
|
62
|
+
opts.on("--deploy-main ENV", "Redeploy the main EY recipe set and run it on your environment ENV") do |env|
|
63
|
+
options[:command] = :deploy_main
|
64
|
+
options[:env] = env
|
65
|
+
end
|
66
|
+
|
67
|
+
opts.on("-n", "--newest ENV", "download, install and run the current custom recipe set for ENV (THIS COMMAND CAN ONLY BE RUN ON YOUR EC2 INSTANCE)") do |env|
|
68
|
+
options[:command] = :converge
|
69
|
+
options[:identifier] = 'recipes'
|
70
|
+
options[:env] = env
|
71
|
+
end
|
72
|
+
|
73
|
+
opts.on("--view-log ENV", "view the last custom chef recipe run log file for ENV") do |env|
|
74
|
+
options[:command] = :view_logs
|
75
|
+
options[:env] = env
|
76
|
+
end
|
77
|
+
|
78
|
+
opts.on("--view-main-log ENV", "view the last main ey recipe run log file for ENV") do |env|
|
79
|
+
options[:command] = :view_logs
|
80
|
+
options[:env] = env
|
81
|
+
options[:main] = true
|
82
|
+
end
|
83
|
+
|
84
|
+
opts.on("--main ENV", "download, install and run the main ey recipe set for ENV (THIS COMMAND CAN ONLY BE RUN ON YOUR EC2 INSTANCE)") do |env|
|
85
|
+
options[:command] = :converge
|
86
|
+
options[:env] = env
|
87
|
+
options[:main] = true
|
88
|
+
options[:recipeloc] = "/etc/chef/recipes"
|
89
|
+
end
|
90
|
+
|
91
|
+
opts.on("--logs", "set the type to logs") do
|
92
|
+
options[:type] = 'logs'
|
93
|
+
options[:extension] = 'gz'
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
opts.parse!
|
99
|
+
|
100
|
+
ey = nil
|
101
|
+
if File.exist?(config = File.expand_path(options[:config] || defaults[:config]))
|
102
|
+
ey = EY::ChefRecipes.new(options = defaults.merge(YAML::load(IO.read(config))).merge(options))
|
103
|
+
elsif File.exist?(config = "/etc/.ey-cloud.yml")
|
104
|
+
ey = EY::ChefRecipes.new(options = defaults.merge(YAML::load(IO.read(config))).merge(options))
|
105
|
+
else
|
106
|
+
puts"You need to have an ~/.ey-cloud.yml file with your credentials in it to use this tool.\nOr point it at a yaml file with -c path/to/ey-cloud.yml"
|
107
|
+
exit 1
|
108
|
+
end
|
109
|
+
|
110
|
+
case options[:command]
|
111
|
+
when :list
|
112
|
+
ey.list true
|
113
|
+
when :rollback
|
114
|
+
ey.rollback
|
115
|
+
when :deploy
|
116
|
+
ey.deploy
|
117
|
+
when :get_json
|
118
|
+
jj ey.get_json
|
119
|
+
when :deploy_main
|
120
|
+
ey.deploy_main
|
121
|
+
when :view_logs
|
122
|
+
ey.view_logs
|
123
|
+
when :clear
|
124
|
+
ey.clear_bucket
|
125
|
+
when :upload
|
126
|
+
ey.upload_recipes
|
127
|
+
when :get_envs
|
128
|
+
envs = ey.get_envs
|
129
|
+
puts "Current Environments:"
|
130
|
+
envs.each {|k,v| puts "env: #{k} running instances: #{v['instances']}\n instance_ids: #{v['instance_ids'].inspect}" }
|
131
|
+
when :converge
|
132
|
+
ey.converge
|
133
|
+
end
|
data/bin/ey-slave
ADDED
data/bin/ey-snapshots
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'yaml'
|
4
|
+
require "optparse"
|
5
|
+
require "json"
|
6
|
+
require 'snapshot_minder'
|
7
|
+
|
8
|
+
defaults = {:config => '/etc/.mysql.backups.yml',
|
9
|
+
:command => :list_snapshots,
|
10
|
+
:keep => 5}
|
11
|
+
|
12
|
+
options = {}
|
13
|
+
# Build a parser for the command line arguments
|
14
|
+
opts = OptionParser.new do |opts|
|
15
|
+
opts.version = "0.0.1"
|
16
|
+
|
17
|
+
opts.banner = "Usage: ey-snapshots [-flag] [argument]"
|
18
|
+
opts.define_head "ey-snapshots: managing your snapshots..."
|
19
|
+
opts.separator '*'*80
|
20
|
+
|
21
|
+
opts.on("-l", "--list-snapshots", "list snapshots") do
|
22
|
+
options[:command] = :list_snapshots
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on("-c", "--config CONFIG", "Use config file.") do |config|
|
26
|
+
options[:config] = config
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on("-i", "--instance-id ID", "specify the instance id to work with(only needed if you are running this from ourside of ec2)") do |iid|
|
30
|
+
options[:instance_id] = iid
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
opts.on("--snapshot", "take snapshots of both of your volumes(only runs on your ec2 instance)") do
|
35
|
+
options[:command] = :snapshot_volumes
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
opts.parse!
|
42
|
+
|
43
|
+
ey = nil
|
44
|
+
if File.exist?(config = File.expand_path(defaults[:config]))
|
45
|
+
ey = EY::SnapshotMinder.new(options = defaults.merge(YAML::load(IO.read(config))).merge(options))
|
46
|
+
else
|
47
|
+
puts"You need to have an /etc/.mysql.backups.yml file with your credentials in it to use this tool.\nOr point it at a yaml file with -c .mysql.backups.yml"
|
48
|
+
exit 1
|
49
|
+
end
|
50
|
+
|
51
|
+
ey.send(options[:command])
|
52
|
+
ey.clean_snapshots(options[:keep])
|
data/bin/eybackup
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'yaml'
|
4
|
+
require "optparse"
|
5
|
+
require 'mysql_backup'
|
6
|
+
require 'postgresql_backup'
|
7
|
+
|
8
|
+
options = {:config => '/etc/.mysql.backups.yml',
|
9
|
+
:command => :new_backup}
|
10
|
+
|
11
|
+
# Build a parser for the command line arguments
|
12
|
+
opts = OptionParser.new do |opts|
|
13
|
+
opts.version = "0.0.1"
|
14
|
+
|
15
|
+
opts.banner = "Usage: eybackup [-flag] [argument]"
|
16
|
+
opts.define_head "eybackup: backing up your shit since way back when..."
|
17
|
+
opts.separator '*'*80
|
18
|
+
|
19
|
+
opts.on("-l", "--list-backup DATABASE", "List mysql backups for DATABASE") do |db|
|
20
|
+
options[:db] = (db || 'all')
|
21
|
+
options[:command] = :list
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on("-n", "--new-backup", "Create new mysql backup") do
|
25
|
+
options[:command] = :new_backup
|
26
|
+
end
|
27
|
+
|
28
|
+
opts.on("-c", "--config CONFIG", "Use config file.") do |config|
|
29
|
+
options[:config] = config
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.on("-d", "--download BACKUP_INDEX", "download the backup specified by index. Run eybackup -l to get the index.") do |index|
|
33
|
+
options[:command] = :download
|
34
|
+
options[:index] = index
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on("-e", "--engine DATABASE_ENGINE", "The database engine. ex: mysql, postgres.") do |engine|
|
38
|
+
options[:engine] = engine || 'mysql'
|
39
|
+
options[:config] ||= '/etc/.#{options[:engine]}.backups.yml'
|
40
|
+
end
|
41
|
+
|
42
|
+
opts.on("-r", "--restore BACKUP_INDEX", "Download and apply the backup specified by index WARNING! will overwrite the current db with the backup. Run eybackup -l to get the index.") do |index|
|
43
|
+
options[:command] = :restore
|
44
|
+
options[:index] = index
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
opts.parse!
|
50
|
+
|
51
|
+
eyb = nil
|
52
|
+
if File.exist?(options[:config])
|
53
|
+
eyb = case options[:engine]
|
54
|
+
when 'postgres' then EyBackup::PostgresqlBackup.new(YAML::load(IO.read(options[:config])))
|
55
|
+
when 'mysql', NilClass then EyBackup::MysqlBackup.new(YAML::load(IO.read(options[:config])))
|
56
|
+
else raise "Invalid engine: #{options[:engine]}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
case options[:command]
|
61
|
+
when :list
|
62
|
+
eyb.list options[:db], true
|
63
|
+
when :new_backup
|
64
|
+
eyb.new_backup
|
65
|
+
when :download
|
66
|
+
eyb.download(options[:index])
|
67
|
+
when :restore
|
68
|
+
eyb.restore(options[:index])
|
69
|
+
end
|
70
|
+
eyb.cleanup
|
data/lib/big-brother.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'dbi'
|
2
|
+
module EY
|
3
|
+
class BigBrother
|
4
|
+
def initialize(dna)
|
5
|
+
@dna = dna
|
6
|
+
@result = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def nginx_or_apache
|
10
|
+
server = ''
|
11
|
+
@dna['applications'].each do |name, app_data|
|
12
|
+
if app_data['recipes'].detect { |r| r == 'nginx' }
|
13
|
+
server = 'nginx'
|
14
|
+
end
|
15
|
+
|
16
|
+
if app_data['recipes'].detect { |r| r == 'passenger' }
|
17
|
+
server = 'apache2'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
server
|
21
|
+
end
|
22
|
+
|
23
|
+
def skip?(name)
|
24
|
+
(@dna['skip']||[]).include?(name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def check
|
28
|
+
case @dna['instance_role']
|
29
|
+
when 'solo'
|
30
|
+
check_process(nginx_or_apache) unless skip?(nginx_or_apache)
|
31
|
+
check_mysql unless skip?('mysqld')
|
32
|
+
when 'app', 'app_master'
|
33
|
+
check_process(nginx_or_apache) unless skip?(nginx_or_apache)
|
34
|
+
check_process('haproxy') unless skip?('haproxy')
|
35
|
+
when 'db_master', 'db_slave'
|
36
|
+
check_mysql unless skip?('mysqld')
|
37
|
+
when 'util'
|
38
|
+
end
|
39
|
+
(@dna['check']||[]).each do |check|
|
40
|
+
check_process(check)
|
41
|
+
end
|
42
|
+
@result.to_json
|
43
|
+
end
|
44
|
+
|
45
|
+
def check_mysql
|
46
|
+
check_process('mysqld')
|
47
|
+
DBI.connect("DBI:Mysql:mysql:#{@dna['db_host']}", 'root', @dna['users'].first['password'])
|
48
|
+
rescue DBI::DatabaseError => e
|
49
|
+
@result['mysqld'] = 'down'
|
50
|
+
end
|
51
|
+
|
52
|
+
def check_process(name)
|
53
|
+
return if name == ''
|
54
|
+
pids = `pgrep #{name}`.split("\n")
|
55
|
+
if pids.empty?
|
56
|
+
@result[name] = 'down'
|
57
|
+
else
|
58
|
+
if pids.detect {|p| `kill -0 #{p}; echo $?`.chomp.to_i != 0}
|
59
|
+
@result[name] = 'down'
|
60
|
+
else
|
61
|
+
@result[name] = 'up'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module AWS::S3
|
2
|
+
class S3Object
|
3
|
+
def <=>(other)
|
4
|
+
DateTime.parse(self.about['last-modified']) <=> DateTime.parse(other.about['last-modified'])
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'open-uri'
|
10
|
+
|
11
|
+
module EY
|
12
|
+
|
13
|
+
class BucketMinder
|
14
|
+
|
15
|
+
def initialize(opts={})
|
16
|
+
AWS::S3::Base.establish_connection!(
|
17
|
+
:access_key_id => opts[:aws_secret_id],
|
18
|
+
:secret_access_key => opts[:aws_secret_key]
|
19
|
+
)
|
20
|
+
@instance_id = opts[:instance_id]
|
21
|
+
@type = opts[:type]
|
22
|
+
@env = opts[:env]
|
23
|
+
@opts = opts
|
24
|
+
opts[:extension] ||= "tgz"
|
25
|
+
@keep = opts[:keep]
|
26
|
+
@name = "#{Time.now.strftime("%Y-%m-%dT%H:%M:%S").gsub(/:/, '-')}.#{@type}.#{opts[:extension]}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def bucket
|
30
|
+
@bucket ||= begin
|
31
|
+
buck = "#{@env}-#{@type}-#{instance_id}-#{Digest::SHA1.hexdigest(@opts[:aws_secret_id])[0..6]}"
|
32
|
+
begin
|
33
|
+
AWS::S3::Bucket.create buck
|
34
|
+
rescue AWS::S3::ResponseError
|
35
|
+
end
|
36
|
+
buck
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def instance_id
|
41
|
+
@instance_id ||= open("http://169.254.169.254/latest/meta-data/instance-id").read
|
42
|
+
end
|
43
|
+
|
44
|
+
def upload_object(file)
|
45
|
+
AWS::S3::S3Object.store(
|
46
|
+
@name,
|
47
|
+
open(file),
|
48
|
+
bucket,
|
49
|
+
:access => :private
|
50
|
+
)
|
51
|
+
FileUtils.rm file
|
52
|
+
puts "successful upload: #{@name}"
|
53
|
+
true
|
54
|
+
end
|
55
|
+
|
56
|
+
def download(index, printer = false)
|
57
|
+
obj = list[index.to_i]
|
58
|
+
puts "downloading: #{obj}" if printer
|
59
|
+
File.open(obj.key, 'wb') do |f|
|
60
|
+
print "." if printer
|
61
|
+
obj.value {|chunk| f.write chunk }
|
62
|
+
end
|
63
|
+
puts if printer
|
64
|
+
puts "finished" if printer
|
65
|
+
obj.key
|
66
|
+
end
|
67
|
+
|
68
|
+
def cleanup
|
69
|
+
list[0...-(@keep)].each{|o|
|
70
|
+
puts "deleting: #{o.key}"
|
71
|
+
o.delete
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_current
|
76
|
+
name = download(list.size - 1)
|
77
|
+
File.expand_path(name)
|
78
|
+
end
|
79
|
+
|
80
|
+
def clear_bucket
|
81
|
+
list.each do |o|
|
82
|
+
puts "deleting: #{o.key}"
|
83
|
+
o.delete
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def rollback
|
88
|
+
o = list.last
|
89
|
+
puts "rolling back: #{o.key}"
|
90
|
+
o.delete
|
91
|
+
end
|
92
|
+
|
93
|
+
def empty?
|
94
|
+
list.empty?
|
95
|
+
end
|
96
|
+
|
97
|
+
def list(printer = false)
|
98
|
+
objects = AWS::S3::Bucket.objects(bucket).sort
|
99
|
+
puts "listing bucket #{bucket}" if printer && !objects.empty?
|
100
|
+
if printer
|
101
|
+
objects.each_with_index do |b,i|
|
102
|
+
puts "#{i}:#{@env} #{b.key}"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
objects
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|