sprinkle 0.3.1 → 0.3.2

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.
@@ -0,0 +1,18 @@
1
+ module Sprinkle
2
+ module Installers
3
+ class Runner < Installer
4
+ attr_accessor :cmd #:nodoc:
5
+
6
+ def initialize(parent, cmd) #:nodoc:
7
+ super parent
8
+ @cmd = cmd
9
+ end
10
+
11
+ protected
12
+
13
+ def install_commands #:nodoc:
14
+ @cmd
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,29 @@
1
+ module Sprinkle
2
+ module Installers
3
+ class Smart < Installer
4
+ attr_accessor :packages #:nodoc:
5
+
6
+ def initialize(parent, packages, &block) #:nodoc:
7
+ super parent, &block
8
+ packages = [packages] unless packages.is_a? Array
9
+ @packages = packages
10
+ end
11
+
12
+ protected
13
+
14
+ def install_commands #:nodoc:
15
+ "smart install #{@packages.join(' ')} -y 2>&1 | tee -a /var/log/smart-sprinkle"
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ module Sprinkle
22
+ module Package
23
+ class Package
24
+ def smart(*names, &block)
25
+ @installer = Sprinkle::Installers::Smart.new(self, *names, &block)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -3,8 +3,8 @@ module Sprinkle
3
3
  # = Source Package Installer
4
4
  #
5
5
  # The source package installer installs software from source.
6
- # It handles downloading, extracting, configuring, building,
7
- # and installing software.
6
+ # It handles downloading, extracting, configuring, building,
7
+ # and installing software.
8
8
  #
9
9
  # == Configuration Options
10
10
  #
@@ -22,7 +22,7 @@ module Sprinkle
22
22
  # * <b>configure</b> - Configure is the stage which the ./configure script is run.
23
23
  # * <b>build</b> - Build is the stage in which `make` is called.
24
24
  # * <b>install</b> - Install is the stage which `make install` is called.
25
- #
25
+ #
26
26
  # == Example Usage
27
27
  #
28
28
  # First, a simple package, no configuration:
@@ -63,7 +63,7 @@ module Sprinkle
63
63
  # end
64
64
  #
65
65
  # As you can see, setting options is as simple as creating a
66
- # block and calling the option as a method with the value as
66
+ # block and calling the option as a method with the value as
67
67
  # its parameter.
68
68
 
69
69
  class Source < Installer
@@ -97,7 +97,11 @@ module Sprinkle
97
97
  end
98
98
 
99
99
  def download_commands #:nodoc:
100
- [ "wget -cq --directory-prefix='#{@options[:archives]}' #{@source}" ]
100
+ if File.exist? @source
101
+ [ "cp #{@source} #{@options[:archives]}/#{archive_name}" ]
102
+ else
103
+ [ "wget -cq --directory-prefix='#{@options[:archives]}' #{@source}" ]
104
+ end
101
105
  end
102
106
 
103
107
  def extract_commands #:nodoc:
@@ -162,7 +166,7 @@ module Sprinkle
162
166
  when /tar$/
163
167
  'tar xf'
164
168
  when /zip$/
165
- 'unzip'
169
+ 'unzip -o'
166
170
  else
167
171
  raise "Unknown source archive format: #{archive_name}"
168
172
  end
@@ -72,7 +72,8 @@ module Sprinkle
72
72
  #
73
73
  # If you pass the option :render => true, this tells transfer that the source file
74
74
  # is an ERB template to be rendered locally before being transferred (you can declare
75
- # variables in the package scope). When render is true, recursive is turned off.
75
+ # variables in the package scope). When render is true, recursive is turned off. Note
76
+ # you can also explicitly pass locals in to render with the :locals option.
76
77
  #
77
78
  # package :nginx_conf do
78
79
  # nginx_port = 8080
@@ -118,7 +119,7 @@ module Sprinkle
118
119
 
119
120
  def render_template_file(path, context, prefix)
120
121
  template = File.read(path)
121
- tempfile = render_template(template, binding(), @package.name)
122
+ tempfile = render_template(template, context, @package.name)
122
123
  tempfile
123
124
  end
124
125
 
@@ -139,8 +140,21 @@ module Sprinkle
139
140
 
140
141
  recursive = @options[:recursive]
141
142
 
142
- if options[:render]
143
- tempfile = render_template_file(@source, binding(), @package.name)
143
+ if options[:render]
144
+ if options[:locals]
145
+ context = {}
146
+ options[:locals].each_pair do |k,v|
147
+ if v.respond_to?(:call)
148
+ context[k] = v.call
149
+ else
150
+ context[k] = v
151
+ end
152
+ end
153
+ else
154
+ context = binding()
155
+ end
156
+
157
+ tempfile = render_template_file(@source, context, @package.name)
144
158
  sourcepath = tempfile.path
145
159
  logger.info "Rendering template #{@source} to temporary file #{sourcepath}"
146
160
  recursive = false
@@ -0,0 +1,15 @@
1
+ module Sprinkle
2
+ module Installers
3
+ class User < Installer
4
+ def initialize(package, username, options, &block)
5
+ super package, &block
6
+ @username=username
7
+ @options =options
8
+ end
9
+ protected
10
+ def install_commands
11
+ "adduser #{@options[:flags]} #{@username}"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,43 @@
1
+ module Sprinkle
2
+ module Installers
3
+ # = Zypper Installer
4
+ #
5
+ # Zypper is a command-line interface to ZYpp system management library.
6
+ # It mostly be used on Suse or OpenSuse.
7
+ #
8
+ # == Example Usage
9
+ #
10
+ # Installing the magic_beans package via Zypper. Its all the craze these days.
11
+ #
12
+ # package :magic_beans do
13
+ # zypper 'magic_beans'
14
+ # end
15
+ #
16
+ # You may also specify multiple packages as an array:
17
+ #
18
+ # package :magic_beans do
19
+ # zypper %w(magic_beans magic_sauce)
20
+ # end
21
+ #
22
+ # or an argument list:
23
+ #
24
+ # package :magic_beans do
25
+ # zypper "magic_beans", "magic_sauce"
26
+ # end
27
+ class Zypper < Installer
28
+ attr_accessor :packages #:nodoc:
29
+
30
+ def initialize(parent, *packages, &block) #:nodoc:
31
+ packages.flatten!
32
+ super parent, &block
33
+ @packages = packages
34
+ end
35
+
36
+ protected
37
+
38
+ def install_commands #:nodoc:
39
+ "zypper -n install -l -R #{@packages.join(' ')}"
40
+ end
41
+ end
42
+ end
43
+ end
@@ -121,6 +121,9 @@ module Sprinkle
121
121
  @installers = []
122
122
  self.instance_eval &block
123
123
  end
124
+ def add_user(username, options={}, &block)
125
+ @installers<<Sprinkle::Installers::User.new(self, username, options, &block)
126
+ end
124
127
 
125
128
  def freebsd_pkg(*names, &block)
126
129
  @installers << Sprinkle::Installers::FreebsdPkg.new(self, *names, &block)
@@ -162,6 +165,10 @@ module Sprinkle
162
165
  @installers << Sprinkle::Installers::Yum.new(self, *names, &block)
163
166
  end
164
167
 
168
+ def zypper(*names, &block)
169
+ @installers << Sprinkle::Installers::Zypper.new(self, *names, &block)
170
+ end
171
+
165
172
  def gem(name, options = {}, &block)
166
173
  @recommends << :rubygems
167
174
  @installers << Sprinkle::Installers::Gem.new(self, name, options, &block)
@@ -188,10 +195,18 @@ module Sprinkle
188
195
  @installers << Sprinkle::Installers::PushText.new(self, text, path, options, &block)
189
196
  end
190
197
 
198
+ def replace_text(regex, text, path, options={}, &block)
199
+ @installers << Sprinkle::Installers::ReplaceText.new(self, regex, text, path, options, &block)
200
+ end
201
+
191
202
  def transfer(source, destination, options = {}, &block)
192
203
  @installers << Sprinkle::Installers::Transfer.new(self, source, destination, options, &block)
193
204
  end
194
205
 
206
+ def runner(cmd)
207
+ @installers << Sprinkle::Installers::Runner.new(self, cmd)
208
+ end
209
+
195
210
  def verify(description = '', &block)
196
211
  @verifications << Sprinkle::Verify.new(self, description, &block)
197
212
  end
@@ -0,0 +1,21 @@
1
+ module Sprinkle
2
+ module Verifiers
3
+ # = Apt package Verifier
4
+ #
5
+ # Contains a verifier to check the existance of an Apt package.
6
+ #
7
+ # == Example Usage
8
+ #
9
+ # verify { has_apt 'ntp' }
10
+ #
11
+ module Apt
12
+ Sprinkle::Verify.register(Sprinkle::Verifiers::Apt)
13
+
14
+ # Checks to make sure the apt <tt>package</tt> exists on the remote server.
15
+ def has_apt(package)
16
+ @commands << "dpkg --status #{package} | grep \"ok installed\""
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -21,6 +21,14 @@ module Sprinkle
21
21
  def file_contains(path, text)
22
22
  @commands << "grep '#{text}' #{path}"
23
23
  end
24
+ def user_present(username)
25
+ @commands << %Q{grep -q -e \'^#{username}:x\' /etc/passwd && test -d ~#{username}}
26
+ end
27
+ def matches_local(localfile, remotefile, mode=nil)
28
+ raise "Couldn't find local file #{localfile}" unless ::File.exists?(localfile)
29
+ local = `md5 #{localfile}`.split.last
30
+ @commands << %{[ "X$(md5sum #{remotefile}|cut -d\\ -f 1)" = "X#{local}" ]}
31
+ end
24
32
  end
25
33
  end
26
- end
34
+ end
@@ -0,0 +1,26 @@
1
+ module Sprinkle
2
+ module Verifiers
3
+ module Package
4
+ Sprinkle::Verify.register(Sprinkle::Verifiers::Package)
5
+
6
+ def has_package(*packages)
7
+ if packages.is_a?(Array) && packages.first.is_a?(Array)
8
+ packages = packages.first
9
+ else
10
+ packages = [packages] unless packages.is_a? Array
11
+ end
12
+
13
+ packages.each do |pak|
14
+ case Sprinkle::Installers::InstallPackage.installer
15
+ when :yum
16
+ @commands << "[ -n \"`yum list installed #{pak} 2> /dev/null | egrep -e \\\"#{pak}\\\"`\" ]"
17
+ else
18
+ raise "Unknown InstallPackage.installer"
19
+ end
20
+ end
21
+ end
22
+
23
+ alias_method :has_packages, :has_package
24
+ end
25
+ end
26
+ end
@@ -14,8 +14,8 @@ module Sprinkle
14
14
  # Checks to make sure <tt>process</tt> is a process running
15
15
  # on the remote server.
16
16
  def has_process(process)
17
- @commands << "ps aux | grep '#{process}' | grep -v grep"
17
+ @commands << "ps -C #{process}"
18
18
  end
19
19
  end
20
20
  end
21
- end
21
+ end
@@ -17,8 +17,8 @@ module Sprinkle
17
17
 
18
18
  # Checks if a gem exists by calling "sudo gem list" and grepping against it.
19
19
  def has_gem(name, version=nil)
20
- version = version.nil? ? '' : version.gsub('.', '\.')
21
- @commands << "sudo gem list | grep -e '^#{name} (.*#{version}.*)$'"
20
+ version = version.nil? ? '' : "--version '#{version}'"
21
+ @commands << "sudo gem list '#{name}' --installed #{version} > /dev/null"
22
22
  end
23
23
  end
24
24
  end
@@ -6,7 +6,7 @@ module Sprinkle
6
6
  # block fails, Sprinkle will stop the script gracefully, raising the error.
7
7
  #
8
8
  # In addition to checking post install if it was successfully, verification
9
- # blocks are also ran before an install to see if a package is <em>already</em>
9
+ # blocks are also run before an install to see if a package is <em>already</em>
10
10
  # installed. If this is the case, the package is skipped and Sprinkle continues
11
11
  # with the next package. This behavior can be overriden by setting the -f flag on
12
12
  # the sprinkle script or setting Sprinkle::OPTIONS[:force] to true if you're
@@ -111,4 +111,4 @@ module Sprinkle
111
111
  @description = description
112
112
  end
113
113
  end
114
- end
114
+ end
@@ -32,11 +32,11 @@ describe Sprinkle::Installers::PushText do
32
32
  end
33
33
 
34
34
  it 'should invoke the push text installer for all specified packages' do
35
- @install_commands.should == %q[echo -e 'another-hair-brained-idea' |tee -a /dev/mind/late-night]
35
+ @install_commands.should == %q[/bin/echo -e 'another-hair-brained-idea' |tee -a /dev/mind/late-night]
36
36
  end
37
37
 
38
38
  it 'should automatically insert pre/post commands for the specified package' do
39
- @installer.send(:install_sequence).should == [ 'op1', "echo -e 'another-hair-brained-idea' |tee -a /dev/mind/late-night", 'op2' ]
39
+ @installer.send(:install_sequence).should == [ 'op1', "/bin/echo -e 'another-hair-brained-idea' |tee -a /dev/mind/late-night", 'op2' ]
40
40
  end
41
41
 
42
42
  end
@@ -48,7 +48,7 @@ describe Sprinkle::Installers::PushText do
48
48
  end
49
49
 
50
50
  it "should invoke the push installer with sudo" do
51
- @install_commands.should == %q[echo -e 'a special user' |sudo tee -a /dev/mind/the-day-after]
51
+ @install_commands.should == %q[/bin/echo -e 'a special user' |sudo tee -a /dev/mind/the-day-after]
52
52
  end
53
53
  end
54
54
 
@@ -59,7 +59,7 @@ describe Sprinkle::Installers::PushText do
59
59
  end
60
60
 
61
61
  it "should correctly encode the single quote character" do
62
- @install_commands.should == %q[echo -e 'I'\''m a string with a single quote' |tee -a /dev/mind/the-day-after]
62
+ @install_commands.should == %q[/bin/echo -e 'I'\''m a string with a single quote' |tee -a /dev/mind/the-day-after]
63
63
  end
64
64
  end
65
65
 
@@ -0,0 +1,45 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Sprinkle::Installers::ReplaceText do
4
+
5
+ before do
6
+ @package = mock(Sprinkle::Package, :name => 'package')
7
+ @options = {:sudo => true}
8
+ end
9
+
10
+ def create_replacement_text(regex, text, path, options={}, &block)
11
+ Sprinkle::Installers::ReplaceText.new(@package, regex, text, path, options, &block)
12
+ end
13
+
14
+ describe 'when created' do
15
+
16
+ it 'should accept text to replace, replacement, and path' do
17
+ @installer = create_replacement_text 'text_to_replace', 'new_text', '/etc/example/foo.conf'
18
+ @installer.regex.should == 'text_to_replace'
19
+ @installer.text.should == 'new_text'
20
+ @installer.path.should == '/etc/example/foo.conf'
21
+ end
22
+
23
+ end
24
+
25
+ describe 'during installation' do
26
+
27
+ before do
28
+ @installer = create_replacement_text 'bad option', 'super option', '/etc/brand/new.conf' do
29
+ pre :install, 'op1'
30
+ post :install, 'op2'
31
+ end
32
+ @install_commands = @installer.send :install_commands
33
+ end
34
+
35
+ it 'should invoke the replace text installer for all specified packages' do
36
+ @install_commands.should == %q[sed -i 's/bad option/super option/g' /etc/brand/new.conf]
37
+ end
38
+
39
+ it 'should automatically insert pre/post commands for the specified package' do
40
+ @installer.send(:install_sequence).should == [ 'op1', "sed -i 's/bad option/super option/g' /etc/brand/new.conf", 'op2' ]
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,31 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Sprinkle::Installers::Runner do
4
+
5
+ before do
6
+ @package = mock(Sprinkle::Package, :name => 'package')
7
+ end
8
+
9
+ def create_runner(cmd)
10
+ Sprinkle::Installers::Runner.new(@package, cmd)
11
+ end
12
+
13
+ describe 'when created' do
14
+ it 'should accept a single cmd to run' do
15
+ @installer = create_runner 'teste'
16
+ @installer.cmd.should == 'teste'
17
+ end
18
+ end
19
+
20
+ describe 'during execution' do
21
+
22
+ before do
23
+ @installer = create_runner 'teste'
24
+ @install_commands = @installer.send :install_commands
25
+ end
26
+
27
+ it 'should run the given command for all specified packages' do
28
+ @install_commands.should == 'teste'
29
+ end
30
+ end
31
+ end