cloud66 0.0.26

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of cloud66 might be problematic. Click here for more details.

@@ -0,0 +1,64 @@
1
+ require 'httparty'
2
+ require 'json'
3
+
4
+ class CloudQuartz
5
+ include HTTParty
6
+ @api_key = ""
7
+ @agent_id = ""
8
+
9
+ def initialize(options = {})
10
+ @api_key = options[:api_key]
11
+ @agent_id = options[:agent_id]
12
+ @secret_key = options[:secret_key]
13
+ self.class.base_uri options[:url] || 'https://api.cloud66.com'
14
+ end
15
+
16
+ def get_job
17
+ process(self.class.get("/queue/#{@agent_id}.json", { :headers => ClientAuth.build_headers(@api_key, @secret_key) } ))
18
+ end
19
+
20
+ def register(agent)
21
+ process(self.class.post('/agent.json', { :headers => ClientAuth.build_headers(@api_key, @secret_key).merge({'Content-Type' => 'application/json'}), :body => agent.to_json }))
22
+ end
23
+
24
+ def unregister(agent)
25
+ process(self.class.delete("/agent/#{@agent_id}.json", :headers => ClientAuth.build_headers(@api_key, @secret_key)))
26
+ end
27
+
28
+ def post_results(job_id, data)
29
+ process(self.class.post("/job/#{job_id}/complete.json", { :headers => ClientAuth.build_headers(@api_key, @secret_key).merge({'Content-Type' => 'application/json'}), :body => data.to_json } ))
30
+ end
31
+
32
+ def pulse_without_ip_address
33
+ process(self.class.get("/agent/#{@agent_id}/pulse.json", { :headers => ClientAuth.build_headers(@api_key, @secret_key) } ))
34
+ end
35
+
36
+ def pulse_with_ip_address(data)
37
+ process(self.class.post("/agent/#{@agent_id}/pulse.json", { :headers => ClientAuth.build_headers(@api_key, @secret_key).merge({'Content-Type' => 'application/json'}), :body => data.to_json } ))
38
+ end
39
+
40
+ def status(stat)
41
+ data = { :status => stat }
42
+ process(self.class.post("/agent/#{@agent_id}/status.json", { :headers => ClientAuth.build_headers(@api_key, @secret_key).merge({'Content-Type' => 'application/json'}), :body => data.to_json }))
43
+ end
44
+
45
+ def init(data)
46
+ process(self.class.post("/agent/#{@agent_id}/initialize.json", { :headers => ClientAuth.build_headers(@api_key, @secret_key).merge({'Content-Type' => 'application/json'}), :body => data.to_json }))
47
+ end
48
+
49
+ def send_vital_signs(data)
50
+ process(self.class.post("/agent/#{@agent_id}/vitalsigns.json", { :headers => ClientAuth.build_headers(@api_key, @secret_key).merge({'Content-Type' => 'application/json'}), :body => data.to_json } ))
51
+ end
52
+
53
+ private
54
+
55
+ def process(response)
56
+ if response.code != 200
57
+ raise response.body
58
+ else
59
+ response.parsed_response
60
+ end
61
+ end
62
+ end
63
+
64
+
@@ -0,0 +1,74 @@
1
+ require File.join(File.dirname(__FILE__), 'quartz_plugin')
2
+ require 'tempfile'
3
+ require 'fileutils'
4
+
5
+ class Backup < QuartzPlugin
6
+
7
+ @@version_major = 0
8
+ @@version_minor = 0
9
+ @@version_revision = 1
10
+
11
+ def info
12
+ { :uid => "64cec894b98b43ce9e6047a9284a4b7d", :name => "Backup", :version => get_version }
13
+ end
14
+
15
+ def run(message)
16
+
17
+ pl = payload(message)
18
+
19
+ job_name = pl['job_name']
20
+ backup_script = "#Script generated by Cloud66 job '#{job_name}'\n\n" + pl['script']
21
+ script_name = pl['script_name']
22
+
23
+ random_file = Tempfile.new('cloud66').path + '.rb'
24
+ File.open(random_file, 'w') do |f|
25
+ f.puts backup_script
26
+ end
27
+
28
+ backup_root_directory = File.expand_path('~/.cloud66/backup')
29
+ FileUtils.mkdir_p(backup_root_directory)
30
+
31
+ command = "backup perform --trigger #{script_name} --root-path #{backup_root_directory} --config_file #{random_file} 2>&1"
32
+ @log.info "Shell command '#{command}'"
33
+
34
+ begin
35
+ result = run_shell("#{command}")
36
+ data = result[:message]
37
+
38
+ #regex to identify all the "error" lines
39
+ errorRegex = Regexp.new('(?<line>\[\d{4}\/\d{2}\/\d{2}\s\d{2}\:\d{2}\:\d{2}\]\[\\e\[31merror\\e\[0m\].*?)(\\n|$)')
40
+ errors = data.scan(errorRegex)
41
+
42
+ if errors.size > 0
43
+
44
+ #log all the errors
45
+ @log.info errors
46
+
47
+ #get rid of the backtrace
48
+ removeRegex = Regexp.new('(Backtrace\:|\d{2}\:\d{2}\]\[\\e\[31merror\\e\[0m\]\s*\/)')
49
+
50
+ #subregex to get rid of nasty timestamp and [\e[31merror\e[0m]
51
+ replaceRegex = Regexp.new('^.*\[\\e\[31merror\\e\[0m\]')
52
+
53
+ errorResult = []
54
+ errors.each do |errorArr|
55
+ error = errorArr[0]
56
+ errorResult << error.gsub(replaceRegex,'').chomp unless error =~ removeRegex
57
+ end
58
+
59
+ run_result(false, errorResult.join("\n"))
60
+ else
61
+ if (result[:ok])
62
+ run_result(true, "Backup completed successfully!")
63
+ else
64
+ run_result(true, "An error occurred!")
65
+ end
66
+ end
67
+
68
+ rescue => ex
69
+ run_result(false, "Failed to execute backup due to #{ex}")
70
+ ensure
71
+ File.delete random_file if File.exists? random_file
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,19 @@
1
+ require File.join(File.dirname(__FILE__), 'quartz_plugin')
2
+
3
+ class Broken < QuartzPlugin
4
+
5
+ @@version_major = 0
6
+ @@version_minor = 0
7
+ @@version_revision = 1
8
+
9
+ def info
10
+ { :uid => "04165a45fde840a9a17b41f019b3dca3", :name => "Broken", :version => get_version }
11
+ end
12
+
13
+ def run(message)
14
+ @log.info "Running with #{message}"
15
+ @log.info "This is a failure"
16
+
17
+ run_result(false, "Boo! It's broken")
18
+ end
19
+ end
@@ -0,0 +1,66 @@
1
+ require File.join(File.dirname(__FILE__), 'quartz_plugin')
2
+ require 'fileutils'
3
+
4
+ class FileRotate < QuartzPlugin
5
+
6
+ @@version_major = 0
7
+ @@version_minor = 0
8
+ @@version_revision = 1
9
+
10
+ def info
11
+ { :uid => "02f7d8237bcc438e8f0659babfef2911", :name => "File Rotater", :version => get_version }
12
+ end
13
+
14
+ def run(message)
15
+ pl = payload(message)
16
+
17
+ source_pattern = pl['source_pattern']
18
+ dest_folder = pl['location']
19
+ keep = pl['keep'].nil? ? 5 : pl['keep'].to_i
20
+ post_rotate = pl['post_rotate']
21
+
22
+ archive = File.join(dest_folder, '/archive')
23
+
24
+ ext = Time.now.utc.strftime('%Y%m%d%H%M%S')
25
+
26
+ FileUtils.mkdir_p(archive)
27
+ rotated = false
28
+ Dir.glob(source_pattern).each do |f|
29
+ rotated = true
30
+ fname = File.basename(f)
31
+ dest_filename = "#{fname}.#{ext}"
32
+ dest_path = File.join(archive, dest_filename)
33
+ @log.debug "Moving #{f} to #{dest_path}"
34
+
35
+ move_shell = run_shell("mv #{f} #{dest_path}")
36
+ return run_result(false, move_shell[:message]) unless move_shell[:ok]
37
+
38
+ return run_result(true, "Files moved successfully with no rotation") if keep == 0
39
+
40
+ # find all the files from this one's rotations
41
+ rotated_pattern = "#{File.join(archive, fname)}.*"
42
+ @log.debug "Looking for rotated files #{rotated_pattern}"
43
+ all_rotated = Dir.glob(rotated_pattern)
44
+ if all_rotated.count > keep
45
+ remove_count = all_rotated.count - keep
46
+ to_remote = all_rotated.sort! { |a,b| File.mtime(a) <=> File.mtime(b) }[0...remove_count]
47
+ @log.debug "Removing extra files"
48
+ to_remote.each do |tr|
49
+ @log.debug "Removing #{tr}"
50
+ remove_shell = run_shell("rm #{tr}")
51
+ return run_result(false, remove_shell[:message]) unless remove_shell[:ok]
52
+ end
53
+ end
54
+ end
55
+
56
+ if !post_rotate.empty? && rotated
57
+ @log.debug "Running post rotate step #{post_rotate}"
58
+ post_shell = run_shell(post_rotate)
59
+ return run_result(false, post_shell[:message]) unless post_shell[:ok]
60
+ end
61
+
62
+ result = rotated ? "Files rotated successfully" : "No files to rotate"
63
+
64
+ run_result(true, result)
65
+ end
66
+ end
@@ -0,0 +1,65 @@
1
+ require File.join(File.dirname(__FILE__), 'quartz_plugin')
2
+ require 'fileutils'
3
+
4
+ class LogRotate < QuartzPlugin
5
+
6
+ @@version_major = 0
7
+ @@version_minor = 0
8
+ @@version_revision = 1
9
+
10
+ def info
11
+ { :uid => "8f4286bfd946c8b08b234833673b8860", :name => "Log Rotate", :version => get_version }
12
+ end
13
+
14
+ def run(message)
15
+ pl = payload(message)
16
+
17
+ @source_pattern = pl['source_pattern']
18
+ @dest_folder = pl['destination']
19
+ @keep = pl['keep'].empty? ? 0 : pl['keep'].to_i
20
+ @post_run_step = pl['post_rotate']
21
+
22
+ ext = Time.now.utc.strftime('%Y%m%d%H%M%S')
23
+
24
+ FileUtils.mkdir_p(@dest_folder)
25
+
26
+ Dir.glob(@source_pattern).each do |f|
27
+ dest_file = File.join(@dest_folder, File.basename(f))
28
+ next if File.directory?(f)
29
+ fname = "#{dest_file}.gz"
30
+ dump_cmd = "cat #{f} | gzip > '#{fname}.#{ext}'"
31
+ @log.debug "Running #{dump_cmd}"
32
+ copy_result = run_shell(dump_cmd)
33
+
34
+ return run_result(false, copy_result[:message]) unless copy_result[:ok]
35
+
36
+ @log.debug "Removing source log files"
37
+ remove_result = run_shell("rm #{f}")
38
+
39
+ return run_result(false, remove_result[:message]) unless remove_result[:ok]
40
+
41
+ # find all the files from this one's rotations
42
+ rotated_pattern = "#{fname}.*"
43
+ @log.debug "Looking for rotated files #{rotated_pattern}"
44
+ all_rotated = Dir.glob(rotated_pattern)
45
+ if all_rotated.count > @keep
46
+ remove_count = all_rotated.count - @keep
47
+ to_remote = all_rotated.sort! { |a,b| File.mtime(a) <=> File.mtime(b) }[0...remove_count]
48
+ @log.debug "Removing extra #{remove_count} files"
49
+ to_remote.each do |tr|
50
+ @log.debug "Removing #{tr}"
51
+ remove_shell = run_shell("rm #{tr}")
52
+ return run_result(false, remove_shell[:message]) unless remove_shell[:ok]
53
+ end
54
+ end
55
+ end
56
+
57
+ if !@post_run_step.nil? && !@post_run_step.empty?
58
+ @log.debug "Running post rotate step #{@post_run_step}"
59
+ post_shell = run_shell(@post_run_step)
60
+ return run_result(false, post_shell[:message]) unless post_shell[:ok]
61
+ end
62
+
63
+ return run_result(true, "Log files rotated succesfully")
64
+ end
65
+ end
@@ -0,0 +1,92 @@
1
+ require File.join(File.dirname(__FILE__), 'quartz_plugin')
2
+ require 'fileutils'
3
+
4
+ class MysqlBackup < QuartzPlugin
5
+
6
+ @@version_major = 0
7
+ @@version_minor = 0
8
+ @@version_revision = 1
9
+
10
+ def info
11
+ { :uid => "67deb35a555344c8a7651c656e6c8e2e", :name => "MySQL Backup", :version => get_version }
12
+ end
13
+
14
+ def run(message)
15
+ pl = payload(message)
16
+ pl = pl.select { |k,v| !v.nil? && !v.empty? }
17
+
18
+ @log.debug "Pruned payload #{pl}"
19
+
20
+ @job_name = pl['job_name'].gsub(/[^\w\s_-]+/, '').gsub(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2').gsub(/\s/, '_')
21
+ @mysqldump_utility = pl['dump_utility'] || '/usr/bin/mysqldump'
22
+ @name = pl['db_name'] || :all
23
+ @username = pl['username']
24
+ @password = pl['password']
25
+ @socket = pl['socket']
26
+ @host = pl['host']
27
+ @port = pl['port']
28
+ @skip_tables = pl['skip_tables']
29
+ @only_tables = pl['only_tables']
30
+ @additional_options = pl['additional_options'] || ['--single-transaction', '--quick']
31
+ @path = pl['backup_folder']
32
+
33
+ @only_tables = @only_tables.split(',') unless @only_tables.nil?
34
+ @skip_tables = @skip_tables.split(',') unless @skip_tables.nil?
35
+
36
+ dump_cmd = "#{mysqldump} | gzip > '#{ File.join(@path, @job_name.downcase) }.sql.gz'"
37
+ @log.debug "Running #{dump_cmd}"
38
+
39
+ FileUtils.mkdir_p(@path)
40
+
41
+ result = run_shell dump_cmd
42
+ if result[:ok]
43
+ run_result(true, "MySQL Backup finished successfully")
44
+ else
45
+ run_result(false, result[:message])
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ # copied from backup gem with little mods
52
+ def mysqldump
53
+ "#{ @mysqldump_utility } #{ credential_options } #{ connectivity_options } " +
54
+ "#{ user_options } #{ @name } #{ tables_to_dump } #{ tables_to_skip }"
55
+ end
56
+
57
+ def credential_options
58
+ %w[username password].map do |option|
59
+ value = instance_variable_get("@#{option}")
60
+ next if value.to_s.empty?
61
+ "--#{option}='#{value}'".gsub('--username', '--user')
62
+ end.compact.join(' ')
63
+ end
64
+
65
+ def connectivity_options
66
+ %w[host port socket].map do |option|
67
+ value = instance_variable_get("@#{option}")
68
+ next if value.to_s.empty?
69
+ "--#{option}='#{value}'"
70
+ end.compact.join(' ')
71
+ end
72
+
73
+ def user_options
74
+ @additional_options.join(' ') unless @additional_options.nil?
75
+ end
76
+
77
+ def tables_to_dump
78
+ @only_tables.join(' ') unless @only_tables.nil? || dump_all?
79
+ end
80
+
81
+ def tables_to_skip
82
+ return '' if @skip_tables.nil?
83
+ @skip_tables.map do |table|
84
+ "--ignore-table='#{@name}.#{table}'"
85
+ end.join(' ') unless dump_all?
86
+ end
87
+
88
+ def dump_all?
89
+ @name == :all
90
+ end
91
+
92
+ end
@@ -0,0 +1,44 @@
1
+ require 'open4'
2
+ require 'json'
3
+
4
+ class QuartzPlugin
5
+
6
+ def initialize(log, options)
7
+ @log = log
8
+ @options = options
9
+ end
10
+
11
+ def run_result(success, message)
12
+ result = { :ok => success, :message => message }
13
+ @log.debug "Job finished with result #{result}"
14
+
15
+ result
16
+ end
17
+
18
+ def payload(message)
19
+ v = message['payload']
20
+ @log.debug "Payload received: #{v}"
21
+ v = v.merge({'job_name' => message['job_name']})
22
+ @log.debug "Payload used: #{v}"
23
+ v
24
+ end
25
+
26
+ def run_shell(command)
27
+ pid, stdin, stdout, stderr = Open4::popen4("#{command}")
28
+ ignored, status = Process::waitpid2 pid
29
+
30
+ if status.exitstatus == 0
31
+ { :ok => true, :message => stdout.read.strip }
32
+ else
33
+ { :ok => false, :message => stderr.read.strip}
34
+ end
35
+ end
36
+
37
+ @@version_major = 0
38
+ @@version_minor = 0
39
+ @@version_revision = 1
40
+
41
+ def get_version
42
+ "#{@@version_major}.#{@@version_minor}.#{@@version_revision}"
43
+ end
44
+ end
@@ -0,0 +1,207 @@
1
+ require File.join(File.dirname(__FILE__), 'quartz_plugin')
2
+ require 'fileutils'
3
+ require 'fog'
4
+ require 'set'
5
+
6
+ class RackspaceBackup < QuartzPlugin
7
+
8
+ @@version_major = 0
9
+ @@version_minor = 0
10
+ @@version_revision = 1
11
+
12
+ def info
13
+ { :uid => "86a34908c51311e1a0a923db6188709b", :name => "Rackspace Backup", :version => get_version }
14
+ end
15
+
16
+ def run(message)
17
+
18
+ pl = payload(message)
19
+ @log.debug "Pruned payload #{pl}"
20
+
21
+ @username = pl['username']
22
+ @api_key = pl['api_key']
23
+ @container = pl['container']
24
+ @remote_path = pl['remote_path']
25
+ @region = pl['region']
26
+ @keep = pl['keep'].empty? ? 0 : pl['keep'].to_i
27
+ @local_pattern = pl['local_pattern']
28
+ @testing = pl['testing']
29
+
30
+ return transfer
31
+ end
32
+
33
+ private
34
+
35
+ def get_connection
36
+ #Fog.mock! unless @testing.nil? || @testing == false
37
+ if @region == 'europe'
38
+ connection = Fog::Storage.new(
39
+ :provider => 'Rackspace',
40
+ :rackspace_username => @username,
41
+ :rackspace_api_key => @api_key,
42
+ :rackspace_auth_url => "lon.auth.api.rackspacecloud.com"
43
+ )
44
+ else
45
+ connection = Fog::Storage.new(
46
+ :provider => 'Rackspace',
47
+ :rackspace_username => @username,
48
+ :rackspace_api_key => @api_key,
49
+ )
50
+ end
51
+ connection
52
+
53
+ end
54
+
55
+ def transfer
56
+ begin
57
+ #set up the rackspace connection
58
+ @connection = get_connection
59
+ if @keep <= 0
60
+ sync_files_without_version_history
61
+ else
62
+ sync_files_with_version_history
63
+ end
64
+
65
+ rescue Excon::Errors::SocketError => exc
66
+ @log.error exc.message
67
+ return run_result(false, exc.message)
68
+ rescue Excon::Errors::Error => exc
69
+ @log.error exc.message
70
+ result = exc.response.body
71
+ message = result.match(/\<Message\>(.*)\<\/Message\>/)
72
+ if !message.nil?
73
+ message = message[1]
74
+ return run_result(false, message)
75
+ elsif exc.response.status == 404
76
+ return run_result(false, "Remote rackspace serivce or container not found (404)")
77
+ elsif exc.response.status != 0
78
+ return run_result(false, "Remote rackspace serivce returned error #{exc.response.status} without any more details")
79
+ else
80
+ return run_result(false, exc.message)
81
+ end
82
+ end
83
+ end
84
+
85
+ def remove_initial_slash(filename)
86
+ filename.sub(/^\//, '')
87
+ end
88
+
89
+ def ensure_trailing_slash(filename)
90
+ return "" if filename.empty?
91
+ filename.sub(/\/$/, '') + '/'
92
+ end
93
+
94
+ def sync_files_without_version_history
95
+
96
+ #prepare the remote directory variable
97
+ @remote_path = remove_initial_slash(ensure_trailing_slash(@remote_path))
98
+ count = 0
99
+
100
+ #for each local file match
101
+ Dir.glob(File.expand_path(@local_pattern)).each do |f|
102
+
103
+ #skip to next match if current is a directory
104
+ next if File.directory?(f)
105
+
106
+ #assign the remote filename
107
+ new_remote_filename = remove_initial_slash(File.join(@remote_path, f))
108
+ @log.debug "Copying #{f} to #{new_remote_filename}"
109
+ count += 1
110
+
111
+ #push file to rackspace
112
+ File.open(f, 'r') do |file|
113
+ @connection.put_object(@container, new_remote_filename, file)
114
+ end
115
+ end
116
+
117
+ return run_result(true, "Successully pushed #{count} file(s) to Rackspace Cloud Files container (without version history)")
118
+
119
+ end
120
+
121
+ def sync_files_with_version_history
122
+
123
+ #prepare the remote directory variable
124
+ @remote_path = remove_initial_slash(ensure_trailing_slash(@remote_path))
125
+ count = 0
126
+
127
+ #get remote directory
128
+ directory = @connection.directories.get(@container)
129
+
130
+ #cache the rackspace remote directory identifing all appropriate files
131
+ remote_path_match = Regexp.new("^#{@remote_path}", "i")
132
+ rackspace_directory = directory.files.map {|f| f.key }
133
+
134
+ all_remote_files = rackspace_directory.select {|m| m =~ remote_path_match}.map {|m| remove_initial_slash(m.gsub(remote_path_match, ''))}
135
+ archive_regex = /(?<folder>^Archive_Cloud66 \(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\)\/)/
136
+ non_archive_files = all_remote_files.reject { |m| m =~ archive_regex }
137
+ archived_files = all_remote_files.select { |m| m =~ archive_regex }
138
+
139
+ new_archive_folder = "Archive_Cloud66 (#{Time.now.strftime("%Y-%m-%d %H:%M:%S")})/"
140
+
141
+ #copy all non-archive files to new backup folder
142
+ non_archive_files.each do |relative_file|
143
+
144
+ puts "name is #{relative_file}"
145
+
146
+ #move file to archive
147
+ existing_remote_filename = remove_initial_slash(File.join(@remote_path, relative_file))
148
+ new_remote_relative_filename = File.join(new_archive_folder, "#{relative_file}")
149
+ new_remote_filename = remove_initial_slash(File.join(@remote_path, new_remote_relative_filename))
150
+
151
+ @log.debug "Copying #{existing_remote_filename} to #{new_remote_filename}"
152
+ @connection.copy_object @container, existing_remote_filename, @container, new_remote_filename
153
+
154
+ @log.debug "Removing #{existing_remote_filename}"
155
+ @connection.delete_object @container, existing_remote_filename
156
+
157
+ #add newly archived file to list of archived files
158
+ archived_files << new_remote_relative_filename
159
+ end
160
+
161
+ #copy up all new files from source
162
+ all_local_files = Dir.glob(File.expand_path(@local_pattern))
163
+ return run_result(true, "No file(s) identified to push to Rackspace Cloud Files container (with version history)") if all_local_files.size == 0
164
+
165
+ #determine a local root to create relative files (TODO?)
166
+ #local_root = ""
167
+ #local_root_regex = Regexp.new local_root
168
+
169
+ #copy all local matches up to rackspace
170
+ all_local_files.each do |f|
171
+
172
+ #skip to next match if current is a directory
173
+ next if File.directory?(f)
174
+
175
+ #assign the remote filename
176
+ new_remote_filename = remove_initial_slash(File.join(@remote_path, f))
177
+ @log.debug "Copying #{f} to #{new_remote_filename}"
178
+ count += 1
179
+
180
+ #push file to rackspace
181
+ File.open(f, 'r') do |file|
182
+ @connection.put_object @container, new_remote_filename, file
183
+ end
184
+
185
+ end
186
+
187
+ #get list of archive folders
188
+ archive_folders = archived_files.map {|m| archive_regex.match(m)['folder']}.uniq.sort.reverse
189
+
190
+ #if we have too many archive folders
191
+ while archive_folders.size > @keep do
192
+ archive_folder = archive_folders.delete_at(archive_folders.size-1)
193
+ archive_regex = Regexp.new "^#{Regexp.escape(archive_folder)}", "i"
194
+
195
+ #remove old archived files
196
+ archived_files.select { |m| m =~ archive_regex }.each do |file|
197
+ remote_file_to_remove = remove_initial_slash(File.join(@remote_path, file))
198
+ @log.debug "Removing old archive file #{remote_file_to_remove}"
199
+ @connection.delete_object @container, remote_file_to_remove
200
+ end
201
+ end
202
+
203
+ return run_result(true, "Successully pushed #{count} file(s) to Rackspace Cloud Files container (with version history)")
204
+
205
+ end
206
+
207
+ end
@@ -0,0 +1,29 @@
1
+ require File.join(File.dirname(__FILE__), 'quartz_plugin')
2
+
3
+ class Rake < QuartzPlugin
4
+
5
+ @@version_major = 0
6
+ @@version_minor = 0
7
+ @@version_revision = 1
8
+
9
+ def info
10
+ { :uid => "62e3583abfc24f209916c4ff97661fa0", :name => "Rake", :version => get_version }
11
+ end
12
+
13
+ def run(message)
14
+ @log.debug "Running with #{message}"
15
+ payload = payload(message)
16
+ task = payload['task']
17
+ location = payload['location']
18
+ params = payload['parameters']
19
+ @log.info "Rake #{task} in #{location} with params:#{params}"
20
+
21
+ begin
22
+ command = "cd #{location} && bundle exec rake #{task} #{params}"
23
+ result = run_shell(command)
24
+ run_result(result[:ok], result[:message])
25
+ rescue => ex
26
+ run_result(false, "Failed to run rake due to #{ex}")
27
+ end
28
+ end
29
+ end