baptize 0.0.1

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