sprinkle 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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