Skip to content

Commit

Permalink
Introduced config task that allows for uploading of config files
Browse files Browse the repository at this point in the history
  • Loading branch information
Tobias Lütke committed Dec 5, 2008
1 parent fbf76da commit 81d1ec6
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 14 deletions.
2 changes: 2 additions & 0 deletions Manifest.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ lib/sprinkle/installers/rake.rb
lib/sprinkle/installers/rpm.rb
lib/sprinkle/installers/source.rb
lib/sprinkle/installers/yum.rb
lib/sprinkle/installers/config.rb
lib/sprinkle/installers/noop.rb
lib/sprinkle/package.rb
lib/sprinkle/policy.rb
lib/sprinkle/script.rb
Expand Down
2 changes: 1 addition & 1 deletion lib/sprinkle.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# Configure active support to log auto-loading of dependencies
#ActiveSupport::Dependencies::RAILS_DEFAULT_LOGGER = Logger.new($stdout)
#ActiveSupport::Dependencies.log_activity = true

# Load up extensions to existing classes
Dir[File.dirname(__FILE__) + '/sprinkle/extensions/*.rb'].each { |e| require e }
# Load up the verifiers so they can register themselves
Expand Down
45 changes: 36 additions & 9 deletions lib/sprinkle/actors/capistrano.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ def initialize(&block) #:nodoc:
@config = ::Capistrano::Configuration.new
@config.logger.level = Sprinkle::OPTIONS[:verbose] ? ::Capistrano::Logger::INFO : ::Capistrano::Logger::IMPORTANT
@config.set(:password) { ::Capistrano::CLI.password_prompt }
@name_counters = Hash.new { |h, v| h[v] = 0 }

if block
self.instance_eval &block
self.instance_eval(&block)
else
@config.load 'deploy' # normally in the config directory for rails
end
Expand All @@ -50,38 +52,63 @@ def recipes(script)
@loaded_recipes << script
end

def process(name, commands, roles, suppress_and_return_failures = false) #:nodoc:
define_task(name, roles) do
def process(name, commands, roles, suppress_and_return_failures = false) #:nodoc:
task = task_sym(name)

define_task(task, roles) do
via = fetch(:run_method, :sudo)
commands.each do |command|
invoke_command command, :via => via
end
end


begin
run(name)
run(task)

return true
rescue ::Capistrano::CommandError => e
return false if suppress_and_return_failures

# Reraise error if we're not suppressing it
raise
end
end

def put(name, uploads, roles, suppress_and_return_failures = false) #:nodoc:
task = task_sym(name)

define_task(task, roles) do
uploads.each do |file, content|
put file, content
end
end

begin
run(task)

return true
rescue ::Capistrano::CommandError => e
return false if suppress_and_return_failures

# Reraise error if we're not suppressing it
raise
end
end

private

# REVISIT: can we set the description somehow?
def define_task(name, roles, &block)
@config.task task_sym(name), :roles => roles, &block
@config.task name, :roles => roles, &block
end

def run(task)
@config.send task_sym(task)
def run(name)
@config.send name
end

def task_sym(name)
"install_#{name.to_task_name}".to_sym
"install_#{name.to_task_name}_#{@name_counters[name] += 1}".to_sym
end
end
end
Expand Down
17 changes: 17 additions & 0 deletions lib/sprinkle/actors/local.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,23 @@ def process(name, commands, roles, suppress_and_return_failures = false) #:nodoc
system command
return false if $?.to_i != 0
end
return true
end

def put(name, uploads, roles, suppress_and_return_failures = false)
uploads.each do |file, content|
retried = false
begin
File.open(file, "w+") { |fp| fp << content }
rescue Errno::ENOENT
FileUtils.mkdir_p(File.dirname(file))
if retried == false
retried = true
retry
end
end
end

return true
end

Expand Down
54 changes: 54 additions & 0 deletions lib/sprinkle/installers/config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
require 'open-uri'

module Sprinkle
module Installers
# = Config Installer
#
# Allows you to upload config files to the server
#
# == Example Usage
#
# config do
# put '/etc/apache2/ports.conf', 'Listen 8080'
# end
#
class Config
include Sprinkle::Configurable

attr_accessor :package, :delivery, :pending_uploads #:nodoc:

def initialize(package, &block) #:nodoc:
@package = package
@pending_uploads = {}
self.instance_eval(&block) if block
end

def put(file, content)
@pending_uploads[file] = content
end

def put_file(file, source)
@pending_uploads[file] = open(source).read
end

def process(roles) #:nodoc:
assert_delivery

if logger.debug?
pending = @pending_uploads.keys.join(", ");
logger.debug "#{@package.name} uploading: #{pending} for roles: #{roles}\n"
end

unless Sprinkle::OPTIONS[:testing]
pending = @pending_uploads.keys.join(", ");
logger.info "--> #{@package.name} uploading for roles: #{roles}"
logger.info " #{pending}"
@delivery.put(@package.name, @pending_uploads, roles)
end

end


end
end
end
9 changes: 7 additions & 2 deletions lib/sprinkle/package.rb
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,17 @@ def rake(name, options = {}, &block)
end

def noop(&block)
@operations << Sprinkle::Installers::Noop.new(self, name, options, &block)
@operations << Sprinkle::Installers::Noop.new(self, &block)
end

def config(&block)
@operations << Sprinkle::Installers::Config.new(self, &block)
end

def verify(description = '', &block)
@verifications << Sprinkle::Verify.new(self, description, &block)
end
end


def process(deployment, roles)
return if meta_package?
Expand Down
28 changes: 26 additions & 2 deletions spec/sprinkle/actors/capistrano_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def create_cap(&block)
end

it 'should invoke capistrano task after creation' do
@cap.should_receive(:run).with(@name).and_return
@cap.should_receive(:run).with(:install_name_1).and_return
end

it 'should raise capistrano errors when suppressing parameter is not set' do
Expand Down Expand Up @@ -158,13 +158,37 @@ def create_cap(&block)

it 'should be applicable for the supplied roles' do
@cap.stub!(:run).and_return
@cap.config.should_receive(:task).with(:install_name, :roles => @roles).and_return
@cap.config.should_receive(:task).with(:install_name_1, :roles => @roles).and_return
end

after do
@cap.process @name, @commands, @roles
end
end

describe 'generated upload task' do

before do
@uploads = {'hello.txt' => 'world'}
@roles = %w( app )
@name = 'name'

@cap = create_cap do; config { put 'hello.txt', 'world'}; end
@cap.config.stub!(:put).and_return
end

it 'should recieve a put command for the pending upload' do
@cap.config.should_receive(:put).with('hello.txt', 'world').and_return(true)
end

it 'should be applicable for the supplied roles' do
@cap.stub!(:run).and_return
@cap.config.should_receive(:task).with(:install_name_1, :roles => @roles).and_return
end

after do
@cap.put @name, @uploads, @roles
end
end

end
27 changes: 27 additions & 0 deletions spec/sprinkle/installers/config_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require File.dirname(__FILE__) + '/../../spec_helper'

describe Sprinkle::Installers::Config do

before do
@package = mock(Sprinkle::Package, :name => 'package')
end

def create_config(&block)
Sprinkle::Installers::Config.new(@package, &block)
end

describe 'during initialization' do

before do
@installer = create_config do
put "hello.txt", 'world'
end
end

it 'should store content in a pending hash' do
@installer.pending_uploads.has_key?('hello.txt').should == true
@installer.pending_uploads['hello.txt'].should == 'world'
end

end
end

0 comments on commit 81d1ec6

Please sign in to comment.