matross 0.1.0 → 0.2.0
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.
- data/README.md +22 -2
- data/lib/matross/base.rb +21 -0
- data/lib/matross/delayed_job.rb +15 -0
- data/lib/matross/errors.rb +4 -0
- data/lib/matross/foreman.rb +47 -5
- data/lib/matross/mysql.rb +43 -0
- data/lib/matross/templates/base/logrotate.erb +9 -0
- data/lib/matross/templates/mysql/database.yml.erb +9 -0
- data/lib/matross/templates/unicorn/unicorn.rb.erb +0 -2
- data/lib/matross/unicorn.rb +3 -1
- data/lib/matross/version.rb +1 -1
- data/matross.gemspec +3 -2
- metadata +35 -8
- checksums.yaml +0 -15
- data/VERSION +0 -1
data/README.md
CHANGED
@@ -6,7 +6,7 @@ Put matross in the `:development` group of your `Gemfile`:
|
|
6
6
|
|
7
7
|
```ruby
|
8
8
|
group :development do
|
9
|
-
|
9
|
+
gem 'matross', :git => 'git://github.com/innvent/matross.git'
|
10
10
|
end
|
11
11
|
```
|
12
12
|
|
@@ -23,5 +23,25 @@ We made a bunch of additions and customizations. Below we list the most relevant
|
|
23
23
|
|
24
24
|
* **Foreman by default**:
|
25
25
|
* **Custom foreman upstart template**: we use a custom upstart template, that enables `console log`, allowing `logrotate` to work properly.
|
26
|
-
* **User template overwrite**:
|
27
26
|
|
27
|
+
## Overriding default templates
|
28
|
+
We have our opinions, but don't know everything. What works for us, may not fit your needs since each app is a unique snowflake. To take care of that `matross` allows you to define your own templates to use instead of the built in ones. Look at the included ones in `lib/matross/templates` to see how we think things should go.
|
29
|
+
|
30
|
+
For example to override the default `lib/matross/templates/unicorn.rb.erb` simply put your template in your applications `config/matross/unicorn/unicorn.rb.erb`. The general idea is `config/matross/#{recipe_name}/#{erb_template}`
|
31
|
+
|
32
|
+
## Managing application daemons with Foreman
|
33
|
+
|
34
|
+
Foreman has freed us of the tedious task of writing `init` and `upstart` scripts. Some of our `matross` recipes automatically add processes - such as the `unicorn` server - to the Procfile.
|
35
|
+
|
36
|
+
If you have an application Procfile with custom daemons defined, such as `delayed_job`, they will be concantenated with all the processes defined in `matross`, resulting in one final Procfile-matross file that will be used to start your app and export init scrips.
|
37
|
+
|
38
|
+
You can specify the number of each instance defined in Procfile-matross using the `foreman_procs` capistrano variable.
|
39
|
+
Supose you have a process called `dj` and want to export 3 instances of it:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
set :foreman_procs, {
|
43
|
+
dj: 3
|
44
|
+
}
|
45
|
+
```
|
46
|
+
|
47
|
+
We also modified the default upstart template to log through upstart instead of just piping stdout and stderr into files. Goodbye nocturnal logexplosion. (Like all templates you can override it)
|
data/lib/matross/base.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'matross/errors'
|
3
|
+
|
1
4
|
def template(from, to)
|
2
5
|
override_template = File.join(Dir.pwd, 'config/matross', from)
|
3
6
|
if File.exist?(override_template)
|
@@ -7,3 +10,21 @@ def template(from, to)
|
|
7
10
|
end
|
8
11
|
put ERB.new(erb).result(binding), to
|
9
12
|
end
|
13
|
+
|
14
|
+
def dep_included?(dependency)
|
15
|
+
lockfile = Bundler::LockfileParser.new(Bundler.read_file(Bundler.default_lockfile))
|
16
|
+
if not lockfile.specs.any? { |gem| gem.name == dependency} then
|
17
|
+
raise Matross::MissingDepError, "recipe requires the #{dependency} gem"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
namespace :base do
|
22
|
+
|
23
|
+
task :logrotate, :roles => :app do
|
24
|
+
run "mkdir -p #{shared_path}/config"
|
25
|
+
template "base/logrotate.erb", "#{shared_path}/config/logrotate"
|
26
|
+
run "#{sudo} ln -nfs #{shared_path}/config/logrotate /etc/logrotate.d/#{application}"
|
27
|
+
end
|
28
|
+
after "deploy:setup", "base:logrotate"
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
dep_included? 'delayed_job'
|
2
|
+
|
3
|
+
namespace :delayed_job do
|
4
|
+
|
5
|
+
desc "Writes the delayed job part of the Procfile"
|
6
|
+
task :procfile, :roles => :dj do
|
7
|
+
procfile_template = <<-EOF.gsub(/^\s+/, '')
|
8
|
+
dj: bundle exec rake jobs:work
|
9
|
+
EOF
|
10
|
+
procfile = ERB.new(procfile_template, nil, '-')
|
11
|
+
put procfile.result(binding), "#{shared_path}/Procfile.dj"
|
12
|
+
end
|
13
|
+
after "foreman:pre_setup", "delayed_job:procfile"
|
14
|
+
|
15
|
+
end
|
data/lib/matross/foreman.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
dep_included? 'foreman'
|
2
|
+
|
1
3
|
_cset(:foreman_user) { user }
|
2
4
|
_cset :foreman_bin, "bundle exec foreman"
|
5
|
+
_cset :foreman_procs, {}
|
3
6
|
|
4
7
|
namespace :foreman do
|
5
8
|
|
@@ -9,10 +12,18 @@ namespace :foreman do
|
|
9
12
|
end
|
10
13
|
before "foreman:setup", "foreman:pre_setup"
|
11
14
|
|
12
|
-
desc "Merges all partial Procfiles"
|
15
|
+
desc "Merges all partial Procfiles and defines a specific dotenv"
|
13
16
|
task :setup do
|
14
|
-
run "cat #{shared_path}/Procfile.* > #{shared_path}/Procfile"
|
17
|
+
run "cat $(test -f #{current_path}/Procfile && echo -n \"#{current_path}/Procfile\") #{shared_path}/Procfile.* > #{shared_path}/Procfile-matross"
|
15
18
|
run "rm #{shared_path}/Procfile.*"
|
19
|
+
|
20
|
+
dotenv_template = <<-EOF.gsub(/^\s+/, '')
|
21
|
+
RAILS_ENV=#{rails_env.to_s.shellescape}
|
22
|
+
EOF
|
23
|
+
dotenv = ERB.new(dotenv_template, nil, '-')
|
24
|
+
put dotenv.result(binding), "#{shared_path}/.env-matross-partial"
|
25
|
+
run "cat $(test -f #{current_path}/.env && echo \"$_\") #{shared_path}/.env-matross-partial > #{shared_path}/.env-matross"
|
26
|
+
run "rm #{shared_path}/.env-matross-partial"
|
16
27
|
end
|
17
28
|
before "foreman:export", "foreman:setup"
|
18
29
|
|
@@ -23,22 +34,53 @@ namespace :foreman do
|
|
23
34
|
upload File.expand_path("../templates/foreman", __FILE__), matross_path,
|
24
35
|
:via => :scp, :recursive => true
|
25
36
|
|
37
|
+
# By default spawn one instance of every process
|
38
|
+
procs = {}
|
39
|
+
capture("cat #{current_path}/Procfile-matross").split("\n").each { |line|
|
40
|
+
process = line[/^([A-Za-z0-9_]+):\s*(.+)$/, 1]
|
41
|
+
procs[process] = 1
|
42
|
+
}
|
43
|
+
procs.merge!(foreman_procs)
|
44
|
+
|
45
|
+
proc_list = ""
|
46
|
+
procs.each { |process, num|
|
47
|
+
proc_list << ',' unless proc_list.empty?
|
48
|
+
proc_list << "#{process}=#{num}"
|
49
|
+
}
|
50
|
+
proc_list = " -c #{proc_list}" unless proc_list.empty?
|
51
|
+
|
26
52
|
run "cd #{current_path} && #{foreman_bin} export upstart #{shared_path}/upstart "\
|
27
|
-
"-f #{current_path}/Procfile "\
|
53
|
+
"-f #{current_path}/Procfile-matross "\
|
28
54
|
"-a #{application} "\
|
29
55
|
"-u #{foreman_user} "\
|
30
56
|
"-l #{shared_path}/log "\
|
31
|
-
"-t #{matross_path}/foreman"
|
57
|
+
"-t #{matross_path}/foreman "\
|
58
|
+
"-e #{shared_path}/.env-matross"\
|
59
|
+
<< proc_list
|
32
60
|
run "cd #{shared_path}/upstart && #{sudo} cp * /etc/init/"
|
33
61
|
end
|
34
62
|
before "deploy:restart", "foreman:export"
|
35
63
|
|
36
64
|
desc "Symlink configuration scripts"
|
37
65
|
task :symlink, :roles => [:app, :dj], :except => { :no_release => true } do
|
38
|
-
run "ln -nfs #{shared_path}/Procfile #{
|
66
|
+
run "ln -nfs #{shared_path}/Procfile-matross #{current_path}/Procfile-matross"
|
67
|
+
run "ln -nfs #{shared_path}/.env-matross #{current_path}/.env-matross"
|
39
68
|
end
|
40
69
|
after "foreman:setup", "foreman:symlink"
|
41
70
|
|
71
|
+
desc "Symlink upstart logs to application shared/log"
|
72
|
+
task :log, :roles => [:app, :dj] do
|
73
|
+
capture("ls #{shared_path}/upstart -1").split(/\r?\n/).each { |line|
|
74
|
+
log = File.basename(line.sub(/\.conf\Z/, ".log"))
|
75
|
+
run <<-EOF.gsub(/^\s+/, '')
|
76
|
+
#{sudo} touch /var/log/upstart/#{log} &&
|
77
|
+
#{sudo} chmod o+r /var/log/upstart/#{log} &&
|
78
|
+
ln -nfs /var/log/upstart/#{log} #{shared_path}/log/#{log}
|
79
|
+
EOF
|
80
|
+
}
|
81
|
+
end
|
82
|
+
after "foreman:export", "foreman:log"
|
83
|
+
|
42
84
|
desc "Restart services"
|
43
85
|
task :restart, :roles => [:app, :dj] do
|
44
86
|
run "#{sudo} start #{application} || #{sudo} restart #{application}"
|
@@ -0,0 +1,43 @@
|
|
1
|
+
dep_included? 'mysql2'
|
2
|
+
|
3
|
+
_cset(:database_config) { "#{shared_path}/config/database.yml" }
|
4
|
+
|
5
|
+
namespace :db do
|
6
|
+
|
7
|
+
desc "Creates the database.yml file in shared path"
|
8
|
+
task :setup, :roles => [:app, :dj] do
|
9
|
+
run "mkdir -p #{shared_path}/config"
|
10
|
+
template "mysql/database.yml.erb", database_config
|
11
|
+
end
|
12
|
+
after "deploy:setup", "db:setup"
|
13
|
+
|
14
|
+
desc "Updates the symlink for database.yml for the just deployed release"
|
15
|
+
task :symlink, :roles => [:app, :dj] do
|
16
|
+
run "ln -nfs #{database_config} #{current_path}/config/database.yml"
|
17
|
+
end
|
18
|
+
before "deploy:restart", "db:symlink"
|
19
|
+
|
20
|
+
desc "Creates the application database"
|
21
|
+
task :create, :roles => [:db] do
|
22
|
+
sql = <<-EOF.gsub(/^\s+/, '')
|
23
|
+
CREATE DATABASE IF NOT EXISTS #{mysql_database};
|
24
|
+
EOF
|
25
|
+
run "mysql --user=#{mysql_user} --password=#{mysql_passwd} --host=#{mysql_host} --execute=\"#{sql}\""
|
26
|
+
end
|
27
|
+
after "db:setup", "db:create"
|
28
|
+
|
29
|
+
desc "Loads the application schema into the database"
|
30
|
+
task :schema_load, :roles => [:db] do
|
31
|
+
sql = <<-EOF.gsub(/^\s+/, '')
|
32
|
+
SELECT count(*) FROM information_schema.TABLES WHERE (TABLE_SCHEMA = '#{mysql_database}');
|
33
|
+
EOF
|
34
|
+
table_count = capture("mysql --batch --skip-column-names "\
|
35
|
+
"--user=#{mysql_user} "\
|
36
|
+
"--password=#{mysql_passwd} "\
|
37
|
+
"--host=#{mysql_host} "\
|
38
|
+
"--execute=\"#{sql}\"").to_i
|
39
|
+
run "cd #{current_path} &&"\
|
40
|
+
"RAILS_ENV=#{rails_env.to_s.shellescape} bundle exec rake db:schema:load" if table_count == 0
|
41
|
+
end
|
42
|
+
after "db:symlink", "db:schema_load"
|
43
|
+
end
|
@@ -2,8 +2,6 @@ app_path = "<%= current_path %>"
|
|
2
2
|
|
3
3
|
working_directory "#{app_path}"
|
4
4
|
pid "#{app_path}/tmp/pids/unicorn.pid"
|
5
|
-
stderr_path "#{app_path}/log/unicorn.log"
|
6
|
-
stdout_path "#{app_path}/log/unicorn.log"
|
7
5
|
|
8
6
|
listen "/tmp/unicorn.sock"
|
9
7
|
worker_processes <%= unicorn_workers %>
|
data/lib/matross/unicorn.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
dep_included? 'unicorn'
|
2
|
+
|
1
3
|
_cset(:unicorn_config) { "#{shared_path}/config/unicorn.rb" }
|
2
4
|
_cset(:unicorn_log) { "#{shared_path}/log/unicorn.log" }
|
3
5
|
_cset :unicorn_workers, 1
|
@@ -17,7 +19,7 @@ namespace :unicorn do
|
|
17
19
|
web: bundle exec unicorn -c <%= unicorn_config %> -E <%= rails_env %>
|
18
20
|
EOF
|
19
21
|
procfile = ERB.new(procfile_template, nil, '-')
|
20
|
-
put procfile.result(binding), "#{shared_path}/Procfile.
|
22
|
+
put procfile.result(binding), "#{shared_path}/Procfile.web"
|
21
23
|
end
|
22
24
|
after "foreman:pre_setup", "unicorn:procfile"
|
23
25
|
|
data/lib/matross/version.rb
CHANGED
data/matross.gemspec
CHANGED
@@ -6,7 +6,7 @@ require "matross/version"
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "matross"
|
8
8
|
spec.version = Matross::VERSION
|
9
|
-
spec.authors = ["Artur Rodrigues"
|
9
|
+
spec.authors = ["Artur Rodrigues", "Joao Sa"]
|
10
10
|
spec.email = ["arturhoo@gmail.com", "me@joaomsa.com"]
|
11
11
|
spec.description = %q{Our collection of opnionated Capistrano recipes}
|
12
12
|
spec.summary = %q{Our collection of opnionated Capistrano recipes}
|
@@ -19,8 +19,9 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "pry"
|
22
23
|
|
23
|
-
spec.add_dependency "capistrano", "~> 2.15.
|
24
|
+
spec.add_dependency "capistrano", "~> 2.15.0"
|
24
25
|
end
|
25
26
|
|
26
27
|
|
metadata
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: matross
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Artur Rodrigues
|
@@ -9,11 +10,12 @@ authors:
|
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date: 2013-
|
13
|
+
date: 2013-10-04 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: bundler
|
16
17
|
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
17
19
|
requirements:
|
18
20
|
- - ~>
|
19
21
|
- !ruby/object:Gem::Version
|
@@ -21,24 +23,43 @@ dependencies:
|
|
21
23
|
type: :development
|
22
24
|
prerelease: false
|
23
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
24
27
|
requirements:
|
25
28
|
- - ~>
|
26
29
|
- !ruby/object:Gem::Version
|
27
30
|
version: '1.3'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: pry
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
type: :development
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
28
47
|
- !ruby/object:Gem::Dependency
|
29
48
|
name: capistrano
|
30
49
|
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
31
51
|
requirements:
|
32
52
|
- - ~>
|
33
53
|
- !ruby/object:Gem::Version
|
34
|
-
version: 2.15.
|
54
|
+
version: 2.15.0
|
35
55
|
type: :runtime
|
36
56
|
prerelease: false
|
37
57
|
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
38
59
|
requirements:
|
39
60
|
- - ~>
|
40
61
|
- !ruby/object:Gem::Version
|
41
|
-
version: 2.15.
|
62
|
+
version: 2.15.0
|
42
63
|
description: Our collection of opnionated Capistrano recipes
|
43
64
|
email:
|
44
65
|
- arturhoo@gmail.com
|
@@ -53,13 +74,17 @@ files:
|
|
53
74
|
- LICENSE.txt
|
54
75
|
- README.md
|
55
76
|
- Rakefile
|
56
|
-
- VERSION
|
57
77
|
- lib/matross.rb
|
58
78
|
- lib/matross/base.rb
|
79
|
+
- lib/matross/delayed_job.rb
|
80
|
+
- lib/matross/errors.rb
|
59
81
|
- lib/matross/foreman.rb
|
60
82
|
- lib/matross/local_assets.rb
|
83
|
+
- lib/matross/mysql.rb
|
61
84
|
- lib/matross/nginx.rb
|
85
|
+
- lib/matross/templates/base/logrotate.erb
|
62
86
|
- lib/matross/templates/foreman/process.conf.erb
|
87
|
+
- lib/matross/templates/mysql/database.yml.erb
|
63
88
|
- lib/matross/templates/nginx/nginx_virtual_host_conf.erb
|
64
89
|
- lib/matross/templates/unicorn/unicorn.rb.erb
|
65
90
|
- lib/matross/unicorn.rb
|
@@ -68,25 +93,27 @@ files:
|
|
68
93
|
homepage: https://github.com/innvent/matross
|
69
94
|
licenses:
|
70
95
|
- MIT
|
71
|
-
metadata: {}
|
72
96
|
post_install_message:
|
73
97
|
rdoc_options: []
|
74
98
|
require_paths:
|
75
99
|
- lib
|
76
100
|
required_ruby_version: !ruby/object:Gem::Requirement
|
101
|
+
none: false
|
77
102
|
requirements:
|
78
103
|
- - ! '>='
|
79
104
|
- !ruby/object:Gem::Version
|
80
105
|
version: '0'
|
81
106
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
82
108
|
requirements:
|
83
109
|
- - ! '>='
|
84
110
|
- !ruby/object:Gem::Version
|
85
111
|
version: '0'
|
86
112
|
requirements: []
|
87
113
|
rubyforge_project:
|
88
|
-
rubygems_version:
|
114
|
+
rubygems_version: 1.8.23
|
89
115
|
signing_key:
|
90
|
-
specification_version:
|
116
|
+
specification_version: 3
|
91
117
|
summary: Our collection of opnionated Capistrano recipes
|
92
118
|
test_files: []
|
119
|
+
has_rdoc:
|
checksums.yaml
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
---
|
2
|
-
!binary "U0hBMQ==":
|
3
|
-
metadata.gz: !binary |-
|
4
|
-
Mjc1ZTA0NDY3NTgzOTE4ODFlNmU2NDM2ODkxYjBmOGIwMmYxYTg4NA==
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ZjFkM2Q0OGMwNTZiMmJkMGRiNzliMjYwYTcwNTZiZjcyOGNhZDA1Nw==
|
7
|
-
!binary "U0hBNTEy":
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
MjA2MjczMGRjMDNjZDM5M2ZiOGIwMDRjMmNlYTY3NjM1NmE5MWJhODgxYmQ0
|
10
|
-
ZDM3MGZkMDhkMWM4YWY5ZjA5MzI0MzEzYjIxM2VkM2E1YWM2OTU2NWMzZWEy
|
11
|
-
MDBjODgxYmIyZWNmOTM0MmUxNzVhYmNhMjVlNGJjYWMzNzg1MmU=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
MjZmMzllNzlkMjMxMjE1MGRmMjdjZjMxYjdkMmZiZTA5YmQ4MWE2YjdlYWVh
|
14
|
-
MjA3YTgyNTc5YjI4NzA3MzdhYWEzNmM3YjAyYjUyMmY5MjcyZmJlYWI4MGY2
|
15
|
-
ZWZjNzc5ZjhlNTVhZThiNmZlZTFmODg2ZWJmOTU5MDBjMjQ0Zjk=
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.0.0
|