Class: Sprinkle::Installers::Installer

Inherits:
Object
  • Object
show all
Includes:
Attributes, Sudo
Defined in:
lib/sprinkle/installers/installer.rb

Overview

The base class which all installers must subclass, this class makes sure all installers share some general features, which are outlined below.

Pre/Post Installation Hooks

With all installation methods you have the ability to specify multiple pre/post installation hooks. This gives you the ability to specify commands to run before and after an installation takes place. There are three ways to specify a pre/post hook.

Note about sudo: When using the Capistrano actor all commands by default are run using sudo (unless your Capfile includes “set :use_sudo, false”). If you wish to use sudo periodically with “set :user_sudo, false” or with an actor other than Capistrano then you can just append it to your command. Some installers (transfer) also support a :sudo option, so check each installer for details.

First, a single command:

pre :install, 'echo "Hello, World!"'
post :install, 'rm -rf /'

Second, an array of commands:

commands = ['echo "First"', 'echo "Then Another"']
pre :install, commands
post :install, commands

Third, a block which returns either a single or multiple commands:

pre :install do
  amount = 7 * 3
  "echo 'Before we install, lets plant #{amount} magic beans...'"
end
post :install do
  ['echo "Now... let's hope they sprout!", 'echo "Indeed they have!"']
end

Other Pre/Post Hooks

Some installation methods actually grant you more fine grained control of when commands are run rather than a blanket pre :install or post :install. If this is the case, it will be documented on the installation method's corresponding documentation page.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Sudo

#sudo?, #sudo_cmd, #sudo_stack

Methods included from Attributes

#defaults, #set_defaults

Constructor Details

#initialize(package, options = {}, &block) ⇒ Installer

:nodoc:



61
62
63
64
65
66
67
# File 'lib/sprinkle/installers/installer.rb', line 61

def initialize(package, options = {}, &block) #:nodoc:
  @package = package
  @options = options || {}
  @pre = {}; @post = {}
  @delivery = nil
  self.instance_eval(&block) if block
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object



121
122
123
124
125
126
127
# File 'lib/sprinkle/installers/installer.rb', line 121

def method_missing(method, *args, &block)
  if package.class.installer_methods.include?(method)
    @package.send(method, *args, &block)
  else
    super(method, *args, &block)
  end
end

Instance Attribute Details

#deliveryObject

:nodoc:



59
60
61
# File 'lib/sprinkle/installers/installer.rb', line 59

def delivery
  @delivery
end

#optionsObject

:nodoc:



59
60
61
# File 'lib/sprinkle/installers/installer.rb', line 59

def options
  @options
end

#packageObject

:nodoc:



59
60
61
# File 'lib/sprinkle/installers/installer.rb', line 59

def package
  @package
end

#post(stage, *commands, &block) ⇒ Object

:nodoc:



59
60
61
# File 'lib/sprinkle/installers/installer.rb', line 59

def post
  @post
end

#pre(stage, *commands, &block) ⇒ Object

:nodoc:



59
60
61
# File 'lib/sprinkle/installers/installer.rb', line 59

def pre
  @pre
end

Class Method Details

.api(&block) ⇒ Object



76
77
78
# File 'lib/sprinkle/installers/installer.rb', line 76

def api(&block)
  Sprinkle::Package::Package.add_api(&block)
end

.inherited(base) ⇒ Object



84
85
86
# File 'lib/sprinkle/installers/installer.rb', line 84

def inherited(base)
  subclasses << base
end

.subclassesObject



72
73
74
# File 'lib/sprinkle/installers/installer.rb', line 72

def subclasses
  @subclasses ||= []
end

.verify_api(&block) ⇒ Object



80
81
82
# File 'lib/sprinkle/installers/installer.rb', line 80

def verify_api(&block)
  Sprinkle::Verify.class_eval(&block)
end

Instance Method Details

#announceObject

Called right before an installer is exected, can be used for logging and announcing what is about to happen



139
# File 'lib/sprinkle/installers/installer.rb', line 139

def announce; end

#commands_from_block(block) ⇒ Object



113
114
115
116
117
118
119
# File 'lib/sprinkle/installers/installer.rb', line 113

def commands_from_block(block)
  return [] unless block
  out = nil
  diff = @package.with_private_install_queue { out = block.call }
  diff.each {|x| x.delivery = self.delivery }
  diff.empty? ? out : diff.map {|x| x.install_sequence }
end

#defer(block) ⇒ Object

defer execution of command block until the package is being processed



109
110
111
# File 'lib/sprinkle/installers/installer.rb', line 109

def defer(block)
  p = Proc.new { self.commands_from_block(block) }
end

#escape_shell_arg(str) ⇒ Object



89
90
91
# File 'lib/sprinkle/installers/installer.rb', line 89

def escape_shell_arg(str)
  str.gsub("'", "'\\\\''").gsub("\n", '\n')
end

#install_sequenceObject

More complicated installers that have different stages, and require pre/post commands within stages can override install_sequence and take complete control of the install command sequence construction (eg. source based installer).



157
158
159
160
# File 'lib/sprinkle/installers/installer.rb', line 157

def install_sequence
  commands = pre_commands(:install) + [ install_commands ] + post_commands(:install)
  flatten commands
end

#per_host?Boolean

Returns:

  • (Boolean)


129
130
131
# File 'lib/sprinkle/installers/installer.rb', line 129

def per_host?
  return false
end

#post_processObject

Called right after processing, can be used for local cleanup such as removing any temporary files created on the local system, etc



135
# File 'lib/sprinkle/installers/installer.rb', line 135

def post_process; end

#process(roles) ⇒ Object

:nodoc:



141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/sprinkle/installers/installer.rb', line 141

def process(roles) #:nodoc:
  if logger.debug?
    sequence = install_sequence; sequence = sequence.join('; ') if sequence.is_a? Array
    logger.debug "#{@package.name} install sequence: #{sequence} for roles: #{roles}\n"
  end

  unless Sprinkle::OPTIONS[:testing]
    logger.debug "    --> Running #{self.class.name} for roles: #{roles}"
    @delivery.install(self, roles, :per_host => per_host?)
  end
  post_process
end