baptize 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZGRmM2Y4ZGE4YWM1NTNjNWFjYWY1Y2Q3YjBiZGQ5ZDczOTIxMGZlOA==
5
+ data.tar.gz: !binary |-
6
+ NWZhZGI1NDQ1YjdmZjg5NDY3N2M4OGE5ODY0M2NmYmRjYmY5M2EzNg==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ MzRhMTc5NzI1ODA5MWJkOGFmZmE4YjJhZTQzMWUzODM1OTdiYmE3OTk1ZTFh
10
+ MTRmYjE0OTRmOTY2Mjc2YjBjZDhkMmYyODcxNzMzYjE5ZTdjZGM1MzdkZmQ0
11
+ NWIwNzViNGIwM2E3MTZhOGEyMDBlN2I5Yjc2NWE3OGEzYTQ5ZmM=
12
+ data.tar.gz: !binary |-
13
+ MDU4NTc0ZmE3NDhjODY4YTk0ODU1MGZkYzIwZTQ4Yjc5OTM2Y2U4ZWE2ZWZh
14
+ MTNmODVjYjNiMzA1ZDIxNWM5YWE2ZWRlZDI1NDdjZTg3YzZiYzVlZTQ5ZWJl
15
+ NTQ4MTFhYzE1YTU1MzNmOWE4YzFiOTExNjNlYmM0Y2E1YmU3MWY=
data/README.markdown ADDED
@@ -0,0 +1,26 @@
1
+ Baptize
2
+ ---
3
+
4
+ Entirely undocumented for the time being.
5
+
6
+ To install, run:
7
+
8
+ rake install
9
+
10
+ A sample `Capfile` to get you started:
11
+
12
+ require 'bundler'
13
+ require 'capistrano'
14
+ require 'baptize'
15
+ set :capistrano_path, "#{root_path}/capistrano"
16
+ set :assets_path, "#{capistrano_path}/assets"
17
+ load_configuration :roles
18
+
19
+ Dir.glob("#{capistrano_path}/packages/**/*.rb").each do |package|
20
+ load(package)
21
+ end
22
+
23
+ Dir.glob("#{capistrano_path}/recipes/**/*.rb").each do |recipe|
24
+ load(recipe)
25
+ end
26
+
@@ -0,0 +1,189 @@
1
+ module Capistrano
2
+ module Baptize
3
+
4
+ # Raised by verifiers, if conditions aren't met
5
+ class VerificationFailure < RuntimeError
6
+ end
7
+
8
+ class PolicyDefinition
9
+ attr_reader :role, :dependencies
10
+
11
+ def initialize(role, parent)
12
+ @role = role
13
+ @dependencies = []
14
+ @parent = parent
15
+ end
16
+
17
+ def respond_to?(sym, include_priv = false)
18
+ super || @parent.respond_to?(sym, include_priv)
19
+ end
20
+
21
+ def method_missing(sym, *args, &block)
22
+ if @parent.respond_to?(sym)
23
+ @parent.send(sym, *args, &block)
24
+ else
25
+ super
26
+ end
27
+ end
28
+
29
+ def full_name
30
+ "baptize:policies:#{role}"
31
+ end
32
+
33
+ def requires(*tasks)
34
+ Array(tasks).flatten.each do |name|
35
+ @dependencies << (name.kind_of?(Symbol) ? "baptize:packages:#{name}" : name.to_s)
36
+ end
37
+ end
38
+ end
39
+
40
+ class PackageDefinition
41
+ attr_reader :name, :description, :dependencies, :install_block, :verify_block, :before_block, :after_block
42
+
43
+ def initialize(name, parent)
44
+ @name = name
45
+ @parent = parent
46
+ @dependencies = []
47
+ @install_block = nil
48
+ @verify_block = nil
49
+ @before_block = nil
50
+ @after_block = nil
51
+ end
52
+
53
+ def respond_to?(sym, include_priv = false)
54
+ super || @parent.respond_to?(sym, include_priv)
55
+ end
56
+
57
+ def method_missing(sym, *args, &block)
58
+ if @parent.respond_to?(sym)
59
+ @parent.send(sym, *args, &block)
60
+ else
61
+ super
62
+ end
63
+ end
64
+
65
+ def full_name
66
+ "baptize:packages:#{name}"
67
+ end
68
+
69
+ def description(desc = nil)
70
+ @description = desc unless desc.nil?
71
+ @description
72
+ end
73
+ alias_method :desc, :description
74
+
75
+ def requires(*tasks)
76
+ Array(tasks).flatten.each do |name|
77
+ @dependencies << "baptize:packages:#{name}"
78
+ end
79
+ end
80
+
81
+ def before(&block)
82
+ @before_block = block
83
+ end
84
+
85
+ def after(&block)
86
+ @after_block = block
87
+ end
88
+
89
+ def install(&block)
90
+ @install_block = block
91
+ end
92
+
93
+ def verify(&block)
94
+ @verify_block = block
95
+ end
96
+ end
97
+
98
+ module DSL
99
+
100
+ def self.packages_installed
101
+ @packages_installed ||= []
102
+ end
103
+
104
+ def self.packages_installed=(value)
105
+ @packages_installed = value
106
+ end
107
+
108
+ def self.policies
109
+ @policies ||= {}
110
+ end
111
+
112
+ def policy(role_names, &block)
113
+ Array(role_names).flatten.each do |role_name|
114
+ if Capistrano::Baptize::DSL.policies[role_name]
115
+ policy = Capistrano::Baptize::DSL.policies[role_name]
116
+ policy.instance_eval &block
117
+ else
118
+ Capistrano::Baptize::DSL.policies[role_name] = PolicyDefinition.new(role_name, self)
119
+ policy = Capistrano::Baptize::DSL.policies[role_name]
120
+ policy.instance_eval &block
121
+ namespace :baptize do
122
+ namespace :policies do
123
+ task policy.role do
124
+ logger.info "Applying policy #{policy.role}"
125
+ old_env_roles = ENV['ROLES']
126
+ # TODO: This is maybe not ideal, as multiple roles would be applied in sequence, not parallel.
127
+ # Also, I'm not sure if they would be skipped for later roles, if already run for an earlier one
128
+ Capistrano::Baptize::DSL.packages_installed = []
129
+ ENV['ROLES'] = policy.role.to_s
130
+ policy.dependencies.each do |task_name|
131
+ find_and_execute_task(task_name)
132
+ end
133
+ ENV['ROLES'] = old_env_roles
134
+ end
135
+ end
136
+ end
137
+ after "baptize:install", policy.full_name
138
+ end
139
+ end
140
+ end
141
+
142
+ def package(package_name, &block)
143
+ package = PackageDefinition.new(package_name, self)
144
+ package.instance_eval &block
145
+ namespace :baptize do
146
+ namespace :packages do
147
+ desc "[package] #{package.description}" if package.description
148
+ task package.name do
149
+ # Cap doesn't track if a task has already been applied - we need to do this
150
+ unless Capistrano::Baptize::DSL.packages_installed.include? package.name
151
+ Capistrano::Baptize::DSL.packages_installed << package.name
152
+ instance_eval(&package.before_block) if package.before_block
153
+ if package.verify_block
154
+ logger.debug "Verifying package #{package.name}"
155
+ already_installed = begin
156
+ instance_eval(&package.verify_block)
157
+ true
158
+ rescue VerificationFailure => err
159
+ false
160
+ end
161
+ if already_installed
162
+ logger.info "Skipping previously installed package #{package.name}"
163
+ else
164
+ logger.info "Installing package #{package.name}"
165
+ instance_eval(&package.install_block)
166
+ instance_eval(&package.verify_block)
167
+ end
168
+ elsif package.install_block
169
+ # logger.important "WARNING: `verify` block not implemented for package #{package.name}."
170
+ logger.info "Installing package #{package.name}"
171
+ instance_eval(&package.install_block)
172
+ else
173
+ # logger.important "WARNING: `install` block not implemented for package #{package.name}."
174
+ logger.info "Nothing to do for package #{package.name}"
175
+ end
176
+ instance_eval(&package.after_block) if package.after_block
177
+ end
178
+ end
179
+ end
180
+ end
181
+ package.dependencies.each do |task_name|
182
+ before package.full_name, task_name
183
+ end
184
+ end
185
+ end
186
+
187
+ end
188
+ end
189
+
@@ -0,0 +1,78 @@
1
+ module Capistrano
2
+ module Baptize
3
+
4
+ module Helpers
5
+ def asset_path(asset)
6
+ File.join(fetch(:assets_path), asset)
7
+ end
8
+
9
+ def remote_assert(command)
10
+ results = []
11
+ pipeline = Array(command).flatten.map {|c| "#{c} > /dev/null 2> /dev/null ; if [ $? -eq 0 ] ; then echo -n 'true' ; else echo -n 'false' ; fi" }.join(" ; ")
12
+ invoke_command(pipeline) do |ch, stream, out|
13
+ results << (out == 'true')
14
+ end
15
+ results.all?
16
+ end
17
+
18
+ # logs the command then executes it locally.
19
+ # returns the command output as a string
20
+ def run_locally(cmd)
21
+ if dry_run
22
+ return logger.debug "executing locally: #{cmd.inspect}"
23
+ end
24
+ logger.trace "executing locally: #{cmd.inspect}" if logger
25
+ output_on_stdout = nil
26
+ elapsed = Benchmark.realtime do
27
+ output_on_stdout = `#{cmd}`
28
+ end
29
+ if $?.to_i > 0 # $? is command exit code (posix style)
30
+ raise Capistrano::LocalArgumentError, "Command #{cmd} returned status code #{$?}"
31
+ end
32
+ logger.trace "command finished in #{(elapsed * 1000).round}ms" if logger
33
+ output_on_stdout
34
+ end
35
+
36
+ def current_role
37
+ ENV['ROLES'].to_sym
38
+ end
39
+
40
+ def load_configuration(environment)
41
+ top.instance_eval do
42
+ if environment == :all
43
+ Dir.glob("#{capistrano_path}/config/**/*.rb").each do |conf|
44
+ load(conf)
45
+ end
46
+ else
47
+ Dir.glob("#{capistrano_path}/config/#{environment}.rb").each do |conf|
48
+ load(conf)
49
+ end
50
+ Dir.glob("#{capistrano_path}/config/#{environment}/**/*.rb").each do |conf|
51
+ load(conf)
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ def md5_of_file(path, md5)
58
+ remote_assert "test $(md5sum #{path.shellescape} | cut -f1 -d' ') = #{md5.shellescape}"
59
+ end
60
+
61
+ def escape_sed_arg(s)
62
+ s.gsub("'", "'\\\\''").gsub("\n", '\n').gsub("/", "\\\\/").gsub('&', '\\\&')
63
+ end
64
+
65
+ def replace_text(pattern, replacement, path)
66
+ run "sed -i 's/#{escape_sed_arg(pattern)}/#{escape_sed_arg(replacement)}/g' #{path.shellescape}"
67
+ end
68
+
69
+ def render(path, locals = {})
70
+ require 'erb'
71
+ require 'ostruct'
72
+ ERB.new(File.read(path)).result(OpenStruct.new(locals).instance_eval { binding })
73
+ end
74
+
75
+ end
76
+
77
+ end
78
+ end
@@ -0,0 +1,61 @@
1
+ module Capistrano
2
+ module Baptize
3
+
4
+ # Defines all baptize top-level tasks
5
+ def self.install(scope)
6
+ scope.instance_eval do
7
+ set :root_path, File.expand_path(Dir.pwd)
8
+ set :capistrano_path, "#{root_path}/capistrano"
9
+ # Can't run this here, since Capfile might want to redefine
10
+ # load_configuration :roles
11
+
12
+ namespace :baptize do
13
+
14
+ desc "Loads baptize configuration files"
15
+ task :load_configuration do
16
+ top.instance_eval do
17
+ top.load_configuration :baptize
18
+ default_run_options[:shell] = 'sudo bash' if fetch(:use_sudo, true)
19
+ end
20
+ end
21
+
22
+ task :default do
23
+ load_configuration
24
+ install
25
+ end
26
+
27
+ desc "Configures all available roles"
28
+ task :install do ; end
29
+
30
+ desc "List configured roles"
31
+ task :roles do
32
+ load_configuration
33
+ result = []
34
+ logger.info "Configured roles:"
35
+ top.roles.each do |name,r|
36
+ logger.info "#{name} [" + r.servers.join(", ") + "]"
37
+ end
38
+ end
39
+
40
+ namespace :policies do
41
+ desc "List configured policies"
42
+ task :default do
43
+ load_configuration
44
+ logger.info "Configured policies:"
45
+ tasks.flatten.each do |x|
46
+ if x.kind_of?(Capistrano::TaskDefinition) && x.fully_qualified_name != "baptize:policies"
47
+ name = x.fully_qualified_name.gsub(/^baptize:policies:/, "")
48
+ policy = Capistrano::Baptize::DSL.policies[name.to_sym]
49
+ logger.info "#{name} [" + policy.dependencies.join(", ") + "]"
50
+ end
51
+ end
52
+ # logger.info "Policies have been defined for roles: " + policies.join(", ")
53
+ end
54
+ end
55
+
56
+ end
57
+ end
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,22 @@
1
+ module Capistrano
2
+ module Baptize
3
+ module Plugins
4
+ module Apt
5
+
6
+ def apt(packages, options = {})
7
+ command = options[:dependencies_only] ? 'build-dep' : 'install'
8
+ noninteractive = "env DEBCONF_TERSE='yes' DEBIAN_PRIORITY='critical' DEBIAN_FRONTEND=noninteractive"
9
+ packages = Array(packages).flatten.map{|p| p.to_s.shellescape }.join(" ")
10
+ invoke_command "#{noninteractive} apt-get --assume-yes --force-yes --show-upgraded --quiet #{command} #{packages}"
11
+ end
12
+
13
+ def has_apt(packages)
14
+ Array(packages).flatten.each do |p|
15
+ raise VerificationFailure, "apt package #{p} not installed" unless remote_assert("dpkg --status #{p.to_s.shellescape} | grep 'ok installed'")
16
+ end
17
+ end
18
+
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,43 @@
1
+ module Capistrano
2
+ module Baptize
3
+ module Plugins
4
+ module Base
5
+
6
+ def has_file(path)
7
+ raise VerificationFailure, "Remote file #{path} does not exist" unless remote_assert("test -e #{path.shellescape}")
8
+ end
9
+
10
+ def has_directory(path)
11
+ raise VerificationFailure, "Remote directory #{path} does not exist" unless remote_assert("test -d #{path.shellescape}")
12
+ end
13
+
14
+ def matches_local(local_path, remote_path)
15
+ raise VerificationFailure, "Couldn't find local file #{local_path}" unless ::File.exists?(local_path)
16
+ require 'digest/md5'
17
+ local_md5 = Digest::MD5.hexdigest(::File.read(local_path))
18
+ raise VerificationFailure, "Remote file #{remote_path} doesn't match local file #{local_path}" unless md5_of_file(remote_path, local_md5)
19
+ end
20
+
21
+ def file_contains(path, text, options = {})
22
+ options = {:mode => :text}.merge(options)
23
+ if options[:mode] == :text
24
+ command = Array(text.strip.split("\n")).flatten.map {|line| "grep --fixed-strings #{line.shellescape} #{path.shellescape}" }.join(" && ")
25
+ elsif options[:mode] == :perl
26
+ command = "grep --perl-regexp #{text.shellescape} #{path.shellescape}"
27
+ else
28
+ command = "grep --basic-regexp #{text.shellescape} #{path.shellescape}"
29
+ end
30
+ remote_assert command
31
+ end
32
+
33
+ def has_executable(path)
34
+ raise VerificationFailure, "No executable #{path} found" unless remote_assert "which #{path.shellescape}"
35
+ end
36
+
37
+ def has_user(name)
38
+ raise VerificationFailure, "No user #{name}" unless remote_assert "id -u #{name.to_s.shellescape}"
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,43 @@
1
+ module Capistrano
2
+ module Baptize
3
+ module Plugins
4
+ module Pecl
5
+
6
+ def pecl(package_name, options = {})
7
+ package_version = options[:version]
8
+ if package_version
9
+ run "TERM= pecl install --alldeps #{package_name.shellescape}-#{package_version.shellescape}"
10
+ else
11
+ run "TERM= pecl install --alldeps #{package_name.shellescape}"
12
+ end
13
+ ini_file = ! options[:ini_file].nil?
14
+ if ini_file
15
+ if ini_file.is_a?(String)
16
+ text = ini_file
17
+ elsif ini_file.is_a?(Hash) && ini_file[:content]
18
+ text = ini_file[:content]
19
+ else
20
+ text = "extension=#{package_name}.so"
21
+ end
22
+ if ini_file.is_a?(Hash) && ini_file[:path]
23
+ path = ini_file[:path]
24
+ else
25
+ path = "/etc/php5/conf.d/#{package_name}.ini"
26
+ end
27
+ put(text, path)
28
+ end
29
+ end
30
+
31
+ def has_pecl(package_name, options = {})
32
+ package_version = options[:version]
33
+ if package_version
34
+ raise VerificationFailure, "PECL package #{package_name}-#{package_version} not installed" unless remote_assert "TERM= pecl list | grep \"^#{package_name.shellescape}\\\\s*#{package_version.shellescape}\""
35
+ else
36
+ raise VerificationFailure, "PECL package #{package_name} not installed" unless remote_assert "TERM= pecl list | grep \"^#{package_name.shellescape}\\\\s\""
37
+ end
38
+ end
39
+
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,52 @@
1
+ require 'tempfile'
2
+
3
+ module Capistrano
4
+ module Baptize
5
+ module Plugins
6
+ module Transfer
7
+ def self.included(base)
8
+ base.send :alias_method, :original_upload, :upload
9
+ base.send :alias_method, :upload, :patched_upload
10
+ end
11
+
12
+ # Performs a two-step upload
13
+ # File is first uploaded to /tmp/, then moved into place
14
+ # Can optionally roll everything into a tarball
15
+ # and may chmod the destination afterwards
16
+ def patched_upload(from, to, options={}, &block)
17
+ use_tarball = options.delete :tarball
18
+ set_owner = options.delete :owner
19
+ if use_tarball
20
+ raise "Can't tarball streaming upload" if from.kind_of?(IO)
21
+ exclude = use_tarball[:exclude] if (use_tarball.kind_of?(Hash) && use_tarball[:exclude])
22
+ tar_options = exclude.map {|glob| "--exclude \"#{glob}\" " }.join('')
23
+ tempfile = Dir::Tmpname.make_tmpname(['/tmp/baptize-', '.tar.gz'], nil)
24
+ local_command = "cd #{from.shellescape} ; #{local_tar_bin} -zcf #{tempfile.shellescape} #{tar_options}."
25
+ raise "Unable to tar #{from}" unless run_locally(local_command)
26
+ destination = "/tmp/#{File.basename(tempfile)}"
27
+ else
28
+ destination = "/tmp/#{File.basename(Dir::Tmpname.make_tmpname('/tmp/baptize-', nil))}"
29
+ end
30
+ original_upload(tempfile || from, destination, options, &block)
31
+ if use_tarball
32
+ run "tar -zxf #{destination.shellescape} -C #{to.shellescape}"
33
+ run "rm #{destination.shellescape}"
34
+ else
35
+ run "mv #{destination.shellescape} #{to.shellescape}"
36
+ end
37
+ if set_owner
38
+ run "chown -R #{set_owner}:#{set_owner} #{to.shellescape}"
39
+ end
40
+ if tempfile
41
+ File.delete tempfile
42
+ end
43
+ end
44
+
45
+ protected
46
+ def local_tar_bin
47
+ (`uname` =~ /Darwin/ ? "COPYFILE_DISABLE=true /usr/bin/gnutar" : "tar")
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
data/lib/baptize.rb ADDED
@@ -0,0 +1,21 @@
1
+ require 'baptize/dsl'
2
+ require 'baptize/install'
3
+ require 'baptize/helpers'
4
+ Dir.glob(File.join(File.dirname(__FILE__), "baptize/plugins/**/*.rb")).each do |f|
5
+ require f
6
+ end
7
+
8
+ Capistrano::Configuration.instance(:must_exist).load do
9
+ class << self
10
+ include Capistrano::Baptize::DSL
11
+ include Capistrano::Baptize::Helpers
12
+ Capistrano::Baptize::Plugins.constants.collect do |const_name|
13
+ Capistrano::Baptize::Plugins.const_get(const_name)
14
+ end.select do |const|
15
+ const.class == Module
16
+ end.each do |m|
17
+ include m
18
+ end
19
+ end
20
+ Capistrano::Baptize.install(self)
21
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: baptize
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Troels Knak-Nielsen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-09-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capistrano
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Baptize is an extension for Capistrano, that allows for server provisioning
28
+ email:
29
+ - troels@knak-nielsen.dk
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files:
33
+ - README.markdown
34
+ files:
35
+ - lib/baptize.rb
36
+ - lib/baptize/dsl.rb
37
+ - lib/baptize/helpers.rb
38
+ - lib/baptize/install.rb
39
+ - lib/baptize/plugins/apt.rb
40
+ - lib/baptize/plugins/base.rb
41
+ - lib/baptize/plugins/pecl.rb
42
+ - lib/baptize/plugins/transfer.rb
43
+ - README.markdown
44
+ homepage: http://github.com/troelskn/baptize
45
+ licenses: []
46
+ metadata: {}
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project:
63
+ rubygems_version: 2.0.3
64
+ signing_key:
65
+ specification_version: 4
66
+ summary: Baptize is an extension for Capistrano, that allows for server provisioning
67
+ test_files: []