relevance_rails 0.0.3 → 0.1.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/.gitignore +2 -0
- data/.rvmrc +1 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +24 -0
- data/README.md +101 -4
- data/Rakefile +10 -0
- data/aws_config.example.yml +15 -0
- data/bin/relevance_rails +2 -19
- data/lib/generators/deployment/deployment_generator.rb +31 -0
- data/lib/generators/fixtures/fixtures_generator.rb +44 -0
- data/lib/generators/provision_config/provision_config_generator.rb +56 -0
- data/lib/generators/provision_config/templates/authorized_keys.json.erb +6 -0
- data/lib/generators/relevance_file/relevance_file_generator.rb +14 -76
- data/lib/generators/relevance_file/templates/{Gemfile → Gemfile.erb} +11 -5
- data/lib/generators/relevance_file/templates/README.markdown.erb +36 -0
- data/lib/generators/relevance_file/templates/application.html.haml.erb +9 -0
- data/lib/generators/relevance_file/templates/database.example.yml.mysql.erb +17 -0
- data/lib/generators/relevance_file/templates/database.example.yml.postgresql.erb +15 -0
- data/lib/generators/relevance_file/templates/deploy.rb.erb +22 -0
- data/lib/relevance_rails.rb +26 -1
- data/lib/relevance_rails/chef_dna.rb +32 -0
- data/lib/relevance_rails/provision.rb +69 -0
- data/lib/relevance_rails/railtie.rb +9 -0
- data/lib/relevance_rails/relevance_rails_template.rb +18 -26
- data/lib/relevance_rails/runner.rb +24 -0
- data/lib/relevance_rails/version.rb +1 -1
- data/lib/tasks/provision.rake +8 -0
- data/relevance_rails.gemspec +7 -2
- data/script/ci +57 -0
- data/spec/acceptance_spec.rb +25 -0
- data/spec/lib/provision_config_generator_spec.rb +27 -0
- data/spec/lib/relevance_rails_spec.rb +15 -0
- data/spec/lib/runner_spec.rb +22 -0
- data/spec/spec_helper.rb +59 -0
- data/techdebt.md +15 -0
- metadata +115 -12
- data/lib/relevance_rails/template_injector.rb +0 -5
data/.gitignore
CHANGED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm gemset use relevance_rails
|
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
*v0.1.0*
|
2
|
+
|
3
|
+
* Provisioning can be done on existing apps
|
4
|
+
* Support multiple rubies - 1.9 and ree
|
5
|
+
* Add unit tests
|
6
|
+
* Can run acceptance tests on generated apps - rails g fixtures
|
7
|
+
* From provision to deploy is a 2 step process - rake provision:ec2 and rails g deployment
|
8
|
+
* Add more error handling
|
9
|
+
* Tentative support for multiple databases - postgresql and mysql
|
10
|
+
|
11
|
+
*v0.0.4*
|
12
|
+
|
13
|
+
* Add support for generating EC2 deployment environments
|
14
|
+
* 'rails g deployment <environment>' to generate a new environment
|
15
|
+
* REQUIRES the presence of ~/.relevance_rails/aws_config.yml
|
16
|
+
* Template aws_config.yml included with this gem.
|
17
|
+
* Newly generates EC2 deployment environments will be wired up as new cap stages.
|
18
|
+
|
19
|
+
*v0.0.3*
|
20
|
+
|
21
|
+
* Add support for multiple public keys pushed to converged hosts.
|
22
|
+
* Public keys are fetched from a git repo.
|
23
|
+
* Git repo url is stored in ~/.relevance_rails/keys_git_url
|
24
|
+
* Only the top level keys from the repo will be pushed to new hosts.
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@ Relevance Rails
|
|
3
3
|
|
4
4
|
Yo dawg, I heard you like automation, so I automated your automation so you can autopilot while you autopilot!
|
5
5
|
|
6
|
-
Rails 3 projects with every fiddly bit convened rather than configured. Includes
|
6
|
+
Rails 3 projects with every fiddly bit convened rather than configured. Includes:
|
7
7
|
|
8
8
|
* HAML and SCSS
|
9
9
|
* RSpec 2 with Relevance config niceties
|
@@ -12,18 +12,115 @@ Rails 3 projects with every fiddly bit convened rather than configured. Includes
|
|
12
12
|
* Capistrano deploy recipes
|
13
13
|
* A VM deployment target under provision
|
14
14
|
|
15
|
+
[](http://travis-ci.org/relevance/relevance_rails)
|
16
|
+
|
15
17
|
Getting Started
|
16
18
|
---------------
|
17
19
|
|
20
|
+
For new projects:
|
21
|
+
|
18
22
|
````sh
|
19
|
-
|
20
|
-
|
23
|
+
$ gem install relevance_rails
|
24
|
+
$ relevance_rails new <your new project>
|
21
25
|
````
|
22
26
|
|
27
|
+
For existing projects, first add to your Gemfile:
|
28
|
+
|
29
|
+
group :development, :test do
|
30
|
+
gem 'relevance_rails'
|
31
|
+
end
|
32
|
+
|
33
|
+
After a `bundle install`, pull in our chef recipes into provision/:
|
34
|
+
|
35
|
+
```sh
|
36
|
+
# defaults to mysql
|
37
|
+
$ rails g provision_config app_name
|
38
|
+
# if using postgresql
|
39
|
+
$ rails g provision_config app_name postgresql
|
40
|
+
```
|
41
|
+
|
42
|
+
Provisioning on EC2
|
43
|
+
-------------------
|
44
|
+
|
45
|
+
First create an aws config in ~/.relevance\_rails/aws\_config.yml.
|
46
|
+
An example config looks like this:
|
47
|
+
|
48
|
+
```yaml
|
49
|
+
aws_credentials:
|
50
|
+
:aws_access_key_id: <your aws access key id>
|
51
|
+
:aws_secret_access_key: <your aws secret access key>
|
52
|
+
|
53
|
+
server:
|
54
|
+
creation_config:
|
55
|
+
:flavor_id: <instance type, e.g. 'm1.large'>
|
56
|
+
:image_id: <ami to bootstrap with. Must be some UBUNTU image. e.g. "ami-fd589594">
|
57
|
+
:groups: <security group to place the new deployment in, e.g. "default">
|
58
|
+
:key_name: <name of the public/private keypair to start instance with>
|
59
|
+
private_key: |
|
60
|
+
-----BEGIN RSA PRIVATE KEY-----
|
61
|
+
Include the RSA private key here. This should correspond to the keypair indicated
|
62
|
+
by :key_name above.
|
63
|
+
-----END RSA PRIVATE KEY-----
|
64
|
+
```
|
65
|
+
|
66
|
+
Now just provision your instance:
|
67
|
+
|
68
|
+
```sh
|
69
|
+
$ rake provision:ec2 NAME=qa
|
70
|
+
...
|
71
|
+
Server IP: 1.1.1.1
|
72
|
+
# Pass IP from previous command as second argument
|
73
|
+
$ rails g deployment qa 1.1.1.1
|
74
|
+
$ cap qa deploy:setup deploy
|
75
|
+
```
|
76
|
+
|
77
|
+
Provisioning with Vagrant
|
78
|
+
-------------------------
|
79
|
+
|
80
|
+
From your app's root directory:
|
81
|
+
|
82
|
+
```sh
|
83
|
+
$ cd provision
|
84
|
+
# pull in vagrant and chef
|
85
|
+
$ bundle install
|
86
|
+
$ vagrant up
|
87
|
+
```
|
88
|
+
|
89
|
+
Vagrant instance should be up at 172.25.5.5.
|
90
|
+
|
91
|
+
Supported Ruby Versions
|
92
|
+
-----------------------
|
93
|
+
|
94
|
+
Currently both Ruby 1.9.x and REE 1.8.7 are supported via RVM. relevance_rails
|
95
|
+
configures your Rails app (and Chef provisioning scripts) to require the version
|
96
|
+
of Ruby you used to invoke the relevance_rails executable.
|
97
|
+
|
98
|
+
Supported Databases
|
99
|
+
-------------------
|
100
|
+
|
101
|
+
Currently both MySQL and PostgreSQL are supported. By default relevance_rails configures
|
102
|
+
your Rails app (and Chef provisioning scripts) to use MySQL. However, if you use the
|
103
|
+
standard `--database=postgresql` Rails option, relevance_rails will use PostgreSQL.
|
104
|
+
|
105
|
+
Maintainer Notes
|
106
|
+
----------------
|
107
|
+
|
108
|
+
When QAing or doing local development of this gem, the gem must be built and installed locally.
|
109
|
+
|
110
|
+
In order to test deployment, use the example below to package the relevance_rails gem:
|
111
|
+
|
112
|
+
# Given a relevance_rails app "app" lives in "~/src/app"
|
113
|
+
# And the relevance_rails source lives in "~/src/relevance_rails"
|
114
|
+
~/src/relevance_rails $ gem build relevance_rails.gemspec
|
115
|
+
~/src/relevance_rails $ cd ~/src/app
|
116
|
+
~/src/app $ gem install ../relevance_rails/relevance_rails-0.0.7.gem
|
117
|
+
~/src/app $ bundle package
|
118
|
+
~/src/app $ git commit -m "Package gems" vendor/cache
|
119
|
+
|
23
120
|
Caveats
|
24
121
|
-------
|
25
122
|
|
26
|
-
|
123
|
+
Currently we only support Ruby 1.9.x, REE 1.8.7, Rails 3.2, MySQL, and PostgreSQL installed on Ubuntu.
|
27
124
|
|
28
125
|
Improvements
|
29
126
|
------------
|
data/Rakefile
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
aws_credentials:
|
2
|
+
:aws_access_key_id: <your aws access key id>
|
3
|
+
:aws_secret_access_key: <your aws secret access key>
|
4
|
+
|
5
|
+
server:
|
6
|
+
creation_config:
|
7
|
+
:flavor_id: <instance type, e.g. 'm1.large'>
|
8
|
+
:image_id: <ami to bootstrap with. Must be some UBUNTU image. e.g. "ami-fd589594">
|
9
|
+
:groups: <security group to place the new deployment in, e.g. "default">
|
10
|
+
:key_name: <name of the public/private keypair to start instance with>
|
11
|
+
private_key: |
|
12
|
+
-----BEGIN RSA PRIVATE KEY-----
|
13
|
+
Include the RSA private key here. This should correspond to the keypair indicated
|
14
|
+
by :key_name above.
|
15
|
+
-----END RSA PRIVATE KEY-----
|
data/bin/relevance_rails
CHANGED
@@ -1,21 +1,4 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
# This file was generated by RubyGems.
|
4
|
-
#
|
5
|
-
# The application 'railties' is installed as part of a gem, and
|
6
|
-
# this file is here to facilitate running it.
|
7
|
-
#
|
8
2
|
|
9
|
-
require '
|
10
|
-
|
11
|
-
version = ">= 0"
|
12
|
-
|
13
|
-
if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
|
14
|
-
version = $1
|
15
|
-
ARGV.shift
|
16
|
-
end
|
17
|
-
|
18
|
-
require 'relevance_rails/template_injector'
|
19
|
-
|
20
|
-
gem 'railties', version
|
21
|
-
load Gem.bin_path('railties', 'rails', version)
|
3
|
+
require 'relevance_rails/runner'
|
4
|
+
RelevanceRails::Runner.start
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class DeploymentGenerator < Rails::Generators::NamedBase
|
2
|
+
desc "Generates and updates capistrano config for a new deployment target"
|
3
|
+
argument :hostname, :type => :string
|
4
|
+
|
5
|
+
def write_stage_file
|
6
|
+
create_file "config/deploy/#{name}.rb", <<-DEPLOY_STAGE
|
7
|
+
set :user, 'deploy'
|
8
|
+
|
9
|
+
role :web, "#{hostname}"
|
10
|
+
role :app, "#{hostname}"
|
11
|
+
role :db, "#{hostname}", :primary => true
|
12
|
+
DEPLOY_STAGE
|
13
|
+
end
|
14
|
+
|
15
|
+
def inject_new_deployment_to_stages
|
16
|
+
new_contents = ""
|
17
|
+
File.new(Rails.root.join('config','deploy.rb')).readlines.each do |line|
|
18
|
+
unless line =~ /^set :stages, (.*)$/
|
19
|
+
new_contents << line
|
20
|
+
else
|
21
|
+
stages = eval($1)
|
22
|
+
stages << name
|
23
|
+
stage_array_contents = stages.map{|stage| "\"#{stage}\""}.join(', ')
|
24
|
+
new_contents << "set :stages, [#{stage_array_contents}]\n"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
File.open(Rails.root.join('config','deploy.rb'),'w') do |file|
|
28
|
+
file.write new_contents
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class FixturesGenerator < Rails::Generators::Base
|
2
|
+
def create_controller
|
3
|
+
create_file "app/controllers/relevance_rails_controller.rb", <<-STR
|
4
|
+
class RelevanceRailsController < ApplicationController
|
5
|
+
end
|
6
|
+
STR
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_views
|
10
|
+
create_file "app/views/relevance_rails/index.html.haml", <<-STR
|
11
|
+
%h1 WELCOME HOME
|
12
|
+
STR
|
13
|
+
create_file "app/views/relevance_rails/db.html.haml", <<-STR
|
14
|
+
%h1.database= ActiveRecord::Base.connection.current_database
|
15
|
+
STR
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_coffee
|
19
|
+
create_file "app/assets/javascripts/relevance_rails.js.coffee", <<-STR
|
20
|
+
console.log 'Hello from Relevance, Inc!'
|
21
|
+
STR
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_sass
|
25
|
+
create_file "app/assets/stylesheets/relevance_rails.css.scss", <<-STR
|
26
|
+
$background: blue;
|
27
|
+
|
28
|
+
h1.relevance {
|
29
|
+
background-color: $background;
|
30
|
+
}
|
31
|
+
STR
|
32
|
+
end
|
33
|
+
|
34
|
+
def modify_routes
|
35
|
+
insert_into_file "config/routes.rb", :after => "::Application.routes.draw do" do
|
36
|
+
<<-STR
|
37
|
+
|
38
|
+
# Required to test relevance_rails gem.
|
39
|
+
match '/relevance_rails' => 'relevance_rails#index'
|
40
|
+
match '/relevance_rails/db' => 'relevance_rails#db'
|
41
|
+
STR
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'relevance_rails'
|
2
|
+
require 'rails/generators'
|
3
|
+
|
4
|
+
class ProvisionConfigGenerator < Rails::Generators::NamedBase
|
5
|
+
|
6
|
+
desc "This generator configures the provision sub-directory with appropriate files."
|
7
|
+
|
8
|
+
source_root File.expand_path("../templates", __FILE__)
|
9
|
+
|
10
|
+
argument :database, :type => :string, :default => 'mysql'
|
11
|
+
|
12
|
+
attr_reader :authorized_keys
|
13
|
+
|
14
|
+
def fetch_elzar
|
15
|
+
git :remote => 'add -f elzar git://github.com/relevance/elzar.git'
|
16
|
+
git :merge => '-s ours --no-commit elzar/master'
|
17
|
+
git :"read-tree" => '--prefix=provision/ -u elzar/master'
|
18
|
+
gsub_file 'provision/Vagrantfile', /config\.vm\.host_name(\s+)= .*$/,
|
19
|
+
"config.vm.host_name\\1= '#{name.gsub('_','-')}.local'"
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_authorized_key_data_bag
|
23
|
+
if (@authorized_keys = fetch_keys).empty?
|
24
|
+
abort "No ssh keys were found! Check ssh-add -L and your keys_git_url config."
|
25
|
+
end
|
26
|
+
@authorized_keys.map! {|key| "\"#{key}\""}
|
27
|
+
template('authorized_keys.json.erb', 'provision/data_bags/deploy/authorized_keys.json', {:force => true})
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_dna_json
|
31
|
+
path = File.expand_path('provision/dna.json', destination_root)
|
32
|
+
json = JSON.parse File.binread(path)
|
33
|
+
json['rails_app']['name'] = name
|
34
|
+
# This generator may not receive a working directory;
|
35
|
+
# and we pull data by shelling out to RVM about the ruby
|
36
|
+
# version. This sets the directory explicitly beforehand.
|
37
|
+
Dir.chdir(destination_root)
|
38
|
+
RelevanceRails::ChefDNA.gene_splice(json,database)
|
39
|
+
create_file('provision/dna.json', JSON.generate(json), {:force => true})
|
40
|
+
end
|
41
|
+
|
42
|
+
def commit_changes
|
43
|
+
git :add => 'provision/data_bags/deploy/authorized_keys.json'
|
44
|
+
git :add => 'provision/Vagrantfile'
|
45
|
+
git :add => 'provision/dna.json'
|
46
|
+
git :commit => '-m "Merge Elzar as our provision subdirectory"'
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def fetch_keys
|
52
|
+
local_keys = `ssh-add -L`.split("\n")
|
53
|
+
local_keys = [] unless $?.success?
|
54
|
+
(local_keys + RelevanceRails::PublicKeyFetcher.public_keys).uniq
|
55
|
+
end
|
56
|
+
end
|
@@ -6,37 +6,22 @@ class RelevanceFileGenerator < Rails::Generators::NamedBase
|
|
6
6
|
|
7
7
|
source_root File.expand_path("../templates", __FILE__)
|
8
8
|
|
9
|
+
argument :database, :type => :string, :default => 'mysql'
|
10
|
+
|
9
11
|
def copy_gemfile
|
10
|
-
|
12
|
+
template "Gemfile.erb", "Gemfile"
|
11
13
|
end
|
12
14
|
|
13
15
|
def create_readme_markdown
|
14
|
-
|
15
|
-
# #{name}
|
16
|
-
|
17
|
-
## Getting Started
|
18
|
-
|
19
|
-
gem install bundler
|
20
|
-
# TODO other setup commands here
|
21
|
-
README
|
16
|
+
template "README.markdown.erb", "README.markdown"
|
22
17
|
end
|
23
18
|
|
24
19
|
def create_application_layout
|
25
|
-
|
26
|
-
!!!
|
27
|
-
%html
|
28
|
-
%head
|
29
|
-
%title #{name}
|
30
|
-
= stylesheet_link_tag :application
|
31
|
-
= javascript_include_tag :application
|
32
|
-
= csrf_meta_tag
|
33
|
-
%body
|
34
|
-
= yield
|
35
|
-
LAYOUT
|
20
|
+
template 'application.html.haml.erb', 'app/views/layouts/application.html.haml'
|
36
21
|
end
|
37
22
|
|
38
23
|
def create_rvmrc
|
39
|
-
create_file ".rvmrc", "rvm use
|
24
|
+
create_file ".rvmrc", "rvm use #{RelevanceRails.rvm_version}@#{name}"
|
40
25
|
end
|
41
26
|
|
42
27
|
def create_rspec
|
@@ -52,64 +37,17 @@ gem install bundler
|
|
52
37
|
end
|
53
38
|
|
54
39
|
def create_deploy
|
55
|
-
|
56
|
-
require 'bundler/capistrano'
|
57
|
-
|
58
|
-
set :application, "#{name}"
|
59
|
-
set :repository, "."
|
60
|
-
set :deploy_via, :copy
|
61
|
-
|
62
|
-
set :scm, :git
|
63
|
-
|
64
|
-
set :deploy_to, "/var/www/apps/\#{application}"
|
65
|
-
default_run_options[:pty] = true
|
66
|
-
set :ssh_options, { :paranoid => false, :forward_agent => true }
|
67
|
-
|
68
|
-
set :copy_exclude, '.git/*'
|
69
|
-
|
70
|
-
set :stages, %w(vagrant)
|
71
|
-
set :default_stage, 'vagrant'
|
72
|
-
|
73
|
-
after "deploy:setup", "deploy:copy_shared_db_config"
|
74
|
-
after "deploy:create_symlink", "deploy:symlink_shared_db_config"
|
75
|
-
|
76
|
-
Dir['config/deploy/recipes/*.rb'].sort.each { |f| eval(File.read(f)) }
|
77
|
-
CAP_CONFIG
|
40
|
+
template 'deploy.rb.erb', 'config/deploy.rb'
|
78
41
|
end
|
79
42
|
|
80
43
|
def create_database_example_yml
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
# re-generated from your development database when you run "rake".
|
89
|
-
# Do not set this db to the same as development or production.
|
90
|
-
test:
|
91
|
-
adapter: mysql2
|
92
|
-
encoding: utf8
|
93
|
-
database: #{name}_test
|
94
|
-
|
95
|
-
production:
|
96
|
-
adapter: mysql2
|
97
|
-
encoding: utf8
|
98
|
-
database: #{name}_production
|
99
|
-
DATABASE_CONFIG
|
100
|
-
end
|
101
|
-
|
102
|
-
def create_authorized_key_data_bag
|
103
|
-
authorized_keys = (`ssh-add -L`.split("\n") + RelevanceRails::PublicKeyFetcher.public_keys).uniq
|
104
|
-
authorized_keys.map! {|key| "\"#{key}\""}
|
105
|
-
create_file 'authorized_keys.json', <<-AUTHORIZED_KEYS
|
106
|
-
{
|
107
|
-
"id":"authorized_keys",
|
108
|
-
"keys": [
|
109
|
-
#{authorized_keys.join(",\n")}
|
110
|
-
]
|
111
|
-
}
|
112
|
-
AUTHORIZED_KEYS
|
44
|
+
if database == 'mysql'
|
45
|
+
template 'database.example.yml.mysql.erb', 'config/database.example.yml'
|
46
|
+
elsif database == 'postgresql'
|
47
|
+
template 'database.example.yml.postgresql.erb', 'config/database.example.yml'
|
48
|
+
else
|
49
|
+
create_file 'database.example.yml', "Don't know how to make a template for database: #{database}"
|
50
|
+
end
|
113
51
|
end
|
114
52
|
|
115
53
|
def copy_deploy_recipes
|