elzar 0.1.2 → 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.
Files changed (42) hide show
  1. data/.gitignore +3 -0
  2. data/CHANGELOG.md +6 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +46 -83
  5. data/README.md +19 -17
  6. data/USAGE.md +257 -0
  7. data/bin/elzar +94 -0
  8. data/chef/site-cookbooks/ruby/metadata.rb +3 -1
  9. data/chef/site-cookbooks/ruby/recipes/default.rb +1 -0
  10. data/chef/site-cookbooks/ruby/recipes/path.rb +17 -0
  11. data/elzar.gemspec +4 -0
  12. data/lib/elzar.rb +5 -1
  13. data/lib/elzar/assistant.rb +82 -70
  14. data/lib/elzar/aws_config.rb +46 -0
  15. data/lib/elzar/cli.rb +143 -0
  16. data/lib/elzar/compute.rb +52 -0
  17. data/lib/elzar/core_ext/hash.rb +18 -0
  18. data/lib/elzar/fog.rb +53 -0
  19. data/lib/elzar/ssh_key_locator.rb +37 -0
  20. data/lib/elzar/templates/Gemfile +4 -4
  21. data/lib/elzar/templates/Vagrantfile.erb +1 -1
  22. data/lib/elzar/templates/aws_config.private.yml +13 -0
  23. data/lib/elzar/templates/aws_config.yml +6 -0
  24. data/lib/elzar/templates/data_bags/deploy/authorized_keys.json +4 -5
  25. data/lib/elzar/templates/dna/rails.json +15 -0
  26. data/lib/elzar/templates/gitignore +1 -0
  27. data/lib/elzar/version.rb +1 -1
  28. data/script/ci_nightly +14 -0
  29. data/spec/fixtures/rails_integration_template/add_root_user.rb +9 -0
  30. data/spec/fixtures/rails_integration_template/database.yml +7 -0
  31. data/spec/fixtures/rails_integration_template/deploy.rb +11 -0
  32. data/spec/fixtures/rails_integration_template/template.rb +22 -0
  33. data/spec/integration/rails_spec.rb +190 -0
  34. data/spec/lib/elzar/assistant_spec.rb +30 -0
  35. data/spec/lib/elzar/aws_config_spec.rb +84 -0
  36. data/spec/lib/elzar/ssh_key_locator_spec.rb +51 -0
  37. data/spec/spec_helper.rb +11 -0
  38. data/spec/support/shell_interaction_helpers.rb +33 -0
  39. metadata +107 -7
  40. data/lib/elzar/chef_dna.rb +0 -48
  41. data/lib/elzar/templates/dna.json +0 -25
  42. data/spec/chef_dna_spec.rb +0 -58
data/.gitignore CHANGED
@@ -1 +1,4 @@
1
1
  /.vagrant
2
+ .idea
3
+ pkg
4
+ provision
@@ -1,3 +1,9 @@
1
+ ## 0.2.0
2
+ * Drop support for relevance_rails
3
+ * Update DNA to be opinionated, to support Ruby 1.9.3
4
+ (as opposed to REE) and Postgres (as opposed to MySQL)
5
+ * Update CLI commands and options. (See USAGE.md.)
6
+
1
7
  ## 0.1.0
2
8
  * Initial working version for relevance_rails
3
9
 
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in elzar.gemspec
4
+ gemspec
@@ -1,96 +1,59 @@
1
- GIT
2
- remote: git://github.com/sumbach/knife-github-cookbooks.git
3
- revision: 13d5d7444b468cab24e6fa2d4b07da6ea45ac088
1
+ PATH
2
+ remote: .
4
3
  specs:
5
- knife-github-cookbooks (0.1.5)
6
- chef (~> 0.10.0)
7
- launchy (~> 0.4.0)
4
+ elzar (0.2.0)
5
+ fog (~> 1.5.0)
6
+ gli (~> 2.0.0)
7
+ multi_json (~> 1.3.0)
8
+ slushy (~> 0.1.3)
8
9
 
9
10
  GEM
10
11
  remote: http://rubygems.org/
11
12
  specs:
12
- archive-tar-minitar (0.5.2)
13
- bunny (0.7.9)
14
- chef (0.10.8)
15
- bunny (>= 0.6.0)
16
- erubis
17
- highline
18
- json (>= 1.4.4, <= 1.6.1)
19
- mixlib-authentication (>= 1.1.0)
20
- mixlib-cli (>= 1.1.0)
21
- mixlib-config (>= 1.1.2)
22
- mixlib-log (>= 1.3.0)
23
- moneta
24
- net-ssh (~> 2.1.3)
25
- net-ssh-multi (~> 1.1.0)
26
- ohai (>= 0.6.0)
27
- rest-client (>= 1.0.4, < 1.7.0)
28
- treetop (~> 1.4.9)
29
- uuidtools
30
- configuration (1.3.1)
31
- erubis (2.7.0)
32
- ffi (1.0.11)
33
- highline (1.6.11)
34
- i18n (0.6.0)
35
- ipaddress (0.8.0)
36
- json (1.5.2)
37
- knife-solo (0.0.4)
38
- chef (~> 0.10.0)
39
- net-ssh (~> 2.1.3)
40
- launchy (0.4.0)
41
- configuration (>= 0.0.5)
42
- rake (>= 0.8.1)
43
- mime-types (1.18)
44
- mixlib-authentication (1.1.4)
45
- mixlib-log
46
- mixlib-cli (1.2.2)
47
- mixlib-config (1.1.2)
48
- mixlib-log (1.3.0)
49
- moneta (0.6.0)
13
+ bahia (0.7.2)
14
+ open4 (~> 1.3.0)
15
+ builder (3.1.3)
16
+ diff-lcs (1.1.3)
17
+ excon (0.16.2)
18
+ fog (1.5.0)
19
+ builder
20
+ excon (~> 0.14)
21
+ formatador (~> 0.2.0)
22
+ mime-types
23
+ multi_json (~> 1.0)
24
+ net-scp (~> 1.0.4)
25
+ net-ssh (>= 2.1.3)
26
+ nokogiri (~> 1.5.0)
27
+ ruby-hmac
28
+ formatador (0.2.3)
29
+ gli (2.0.0)
30
+ jruby-pageant (1.1.1)
31
+ mime-types (1.19)
32
+ multi_json (1.3.6)
50
33
  net-scp (1.0.4)
51
34
  net-ssh (>= 1.99.1)
52
- net-ssh (2.1.4)
53
- net-ssh-gateway (1.1.0)
54
- net-ssh (>= 1.99.1)
55
- net-ssh-multi (1.1)
56
- net-ssh (>= 2.1.4)
57
- net-ssh-gateway (>= 0.99.0)
58
- ohai (0.6.12)
59
- ipaddress
60
- mixlib-cli
61
- mixlib-config
62
- mixlib-log
63
- systemu
64
- yajl-ruby
65
- polyglot (0.3.3)
35
+ net-ssh (2.6.0)
36
+ jruby-pageant (>= 1.1.1)
37
+ nokogiri (1.5.5)
38
+ open4 (1.3.0)
66
39
  rake (0.9.2.2)
67
- rest-client (1.6.7)
68
- mime-types (>= 1.16)
69
- systemu (2.5.0)
70
- thor (0.14.6)
71
- treetop (1.4.10)
72
- polyglot
73
- polyglot (>= 0.3.1)
74
- uuidtools (2.1.2)
75
- vagrant (0.8.7)
76
- archive-tar-minitar (= 0.5.2)
77
- erubis (~> 2.7.0)
78
- i18n (~> 0.6.0)
79
- json (~> 1.5.1)
80
- net-scp (~> 1.0.4)
81
- net-ssh (~> 2.1.4)
82
- thor (~> 0.14.6)
83
- virtualbox (~> 0.9.1)
84
- virtualbox (0.9.2)
85
- ffi (~> 1.0.9)
86
- yajl-ruby (1.1.0)
40
+ rspec (2.11.0)
41
+ rspec-core (~> 2.11.0)
42
+ rspec-expectations (~> 2.11.0)
43
+ rspec-mocks (~> 2.11.0)
44
+ rspec-core (2.11.1)
45
+ rspec-expectations (2.11.3)
46
+ diff-lcs (~> 1.1.3)
47
+ rspec-mocks (2.11.2)
48
+ ruby-hmac (0.4.0)
49
+ slushy (0.1.3)
87
50
 
88
51
  PLATFORMS
89
52
  ruby
90
53
 
91
54
  DEPENDENCIES
92
- chef (= 0.10.8)
93
- json (= 1.5.2)
94
- knife-github-cookbooks!
95
- knife-solo (= 0.0.4)
96
- vagrant (= 0.8.7)
55
+ bahia
56
+ bundler
57
+ elzar!
58
+ rake (~> 0.9.2.2)
59
+ rspec
data/README.md CHANGED
@@ -1,22 +1,11 @@
1
1
  ## Description
2
+
2
3
  This gem enables a Rails app to define custom Chef recipes while still using an awesome default set
3
- of Chef recipes. Best used in conjunction with relevance\_rails and slushy. Includes recipes for
4
- ruby 1.9, ree, mysql, postgresql and nginx/passenger.
4
+ of Chef recipes. Includes recipes for Ruby 1.9, postgresql, and nginx/passenger.
5
5
 
6
6
  ## Usage
7
7
 
8
- To use Elzar with your Rails app, just use (relevance_rails)[https://github.com/relevance/relevance_rails].
9
-
10
- But if you'd like to manually do it:
11
-
12
- ```ruby
13
- # Creates a provision/ directory to define app-specific cookbooks
14
- Elzar.create_provision_directory 'provision'
15
-
16
- # To combine Elzar's cookbooks with your app's cookbooks
17
- dir = Elzar.merge_and_create_temp_directory 'provision'
18
- # You now have a directory you can put on a chef node
19
- ```
8
+ To use Elzar with your Rails app, see [USAGE.md](https://github.com/relevance/elzar/blob/master/USAGE.md).
20
9
 
21
10
  ## Local Development
22
11
 
@@ -26,9 +15,12 @@ If you'd like to try these Chef cookbooks with Vagrant:
26
15
  $ git clone git@github.com:relevance/elzar.git
27
16
  $ cd elzar
28
17
  $ gem install bundler
29
- # creates provision/ for local vagrant use
18
+
19
+ # creates a `provision` directory for local vagrant use
30
20
  $ rake bam
21
+
31
22
  $ cd provision
23
+ $ vim dna.json # edit DNA file to give a name to your Rails app with no whitespace (e.g., "my_sample_app")
32
24
  $ bundle install
33
25
 
34
26
  ## Using Vagrant
@@ -40,7 +32,7 @@ your bundle and grab the Ubuntu Lucid VM image.
40
32
  vagrant box add lucid64 http://files.vagrantup.com/lucid64.box
41
33
 
42
34
  ```sh
43
- ## Spin up a new VM
35
+ ## Spin up a new VM and run the Chef recipes on it
44
36
  $ vagrant up
45
37
 
46
38
  ## SSH into the VM
@@ -57,6 +49,16 @@ $ vagrant suspend
57
49
  $ vagrant resume
58
50
  ```
59
51
 
52
+ ### CLI Development
53
+
54
+ The CLI tool (bin/elzar) is built on top of [GLI](https://github.com/davetron5000/gli)
55
+ which is a command line parser modelled after Git. Normally any
56
+ exception that occurs while running a command results in only the error
57
+ message being displayed, not the backtrace. If you would like to view
58
+ the backtrace you must set the env variable `GLI_DEBUG=true`.
59
+
60
+ GLI_DEBUG=true bundle exec bin/elzar foo
61
+
60
62
  ## Issues
61
63
 
62
- Please file issues [on github](https://github.com/relevance/elzar/issues).
64
+ Please file issues [on GitHub](https://github.com/relevance/elzar/issues).
@@ -0,0 +1,257 @@
1
+ Elzar Usage
2
+ ===========
3
+
4
+ ## Rails Tutorial
5
+
6
+ This example assumes that you have a working Rails application that is
7
+ compatible with the default [Rails DNA](/relevance/elzar/tree/master/lib/elzar/templates/dna/rails.json)
8
+ included in Elzar.
9
+
10
+ All commands assume your `RAILS_ROOT` is your current working directory.
11
+
12
+ ### Step 0: Install Elzar
13
+
14
+ ```sh
15
+ gem install elzar
16
+ ```
17
+
18
+
19
+ ### Step 1: Initialize Elzar's Provision Directory
20
+
21
+ This creates a `provision/` directory inside of your project. This
22
+ folder will be used to hold configuration data, custom Chef recipes,
23
+ and the `dna.json` file which specifies how configuration data to
24
+ the Chef recipes themselves.
25
+
26
+ ```sh
27
+ elzar init --dna=rails
28
+ ```
29
+
30
+
31
+ ### Step 2: Configure dna.json
32
+
33
+ The previous command created a `dna.json` template at
34
+ `provision/dna.json`. It will look roughly like so:
35
+
36
+ ```javascript
37
+ {
38
+ "run_list":["role[plumbing]", "role[postgres_database]", "ruby", "passenger", "rails_app"],
39
+ "passenger": {
40
+ "version": "3.0.11",
41
+ "root_path": "/opt/relevance-ruby/lib/ruby/gems/1.9.1/gems/passenger-3.0.11",
42
+ "module_path": "/opt/relevance-ruby/lib/ruby/gems/1.9.1/gems/passenger-3.0.11/ext/apache2/mod_passenger.so"
43
+ },
44
+ "ruby": {
45
+ "version": "1.9.3-p194",
46
+ "url": "http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p194.tar.gz"
47
+ },
48
+ "rails_app": {
49
+ "name": "TODO: Replace with the name of your Rails app"
50
+ }
51
+ }
52
+ ```
53
+
54
+ This file specifies which recipes Chef will run and how they will be
55
+ ran. For example, you can edit the `run_list` to run a custom
56
+ recipe that you have created or swap out one of the default recipes for
57
+ another (e.g. mysql for postgresql).
58
+
59
+ At the very least you will need to specify `rails_app[name]`. For
60
+ example:
61
+
62
+ ```javascript
63
+ "rails_app": {
64
+ "name": "elzar_rails_example"
65
+ }
66
+ ```
67
+
68
+ The `rails_app[name]` in `dna.json` has several implicit effects:
69
+
70
+ * It determines where your app lives on the file system (e.g.,
71
+ `/var/www/apps/elzar_rails_example/`)
72
+ * It determines the name of your database (e.g.,
73
+ `elzar_rails_example_production`)
74
+ * It determines the path of your nginx configuration file (e.g.,
75
+ `/etc/nginx/sites-enabled/elzar_rails_example`)
76
+
77
+ You'll want to consider how your choice of `rails_app` name will operate
78
+ in these contexts (e.g., whether your database engine allows
79
+ dashes in its database names).
80
+
81
+
82
+ ### Step 3: Configure AWS Settings
83
+
84
+ The `init` command also created 2 separate AWS configuration files:
85
+
86
+ * `provision/aws_config.yml` - holds non-sensitive settings, which
87
+ you're comfortable checking into Git
88
+ * `provision/aws_config.private.yml` - holds (wait for it) private
89
+ settings, which you should **not** check into Git
90
+
91
+ These files look like so:
92
+
93
+ ```yaml
94
+ # aws_config.yml
95
+ server:
96
+ creation_config:
97
+ flavor_id: <instance type, e.g. 'm1.large'>
98
+ image_id: <AMI to bootstrap with; must be some Ubuntu server image; e.g., "ami-fd589594" for Ubuntu 11.04>
99
+ groups: <security group to place the new deployment in, e.g. "default">
100
+ key_name: <name of the public/private keypair to start instance with>
101
+ ```
102
+
103
+ ```yaml
104
+ # aws_config.private.yml
105
+ aws_credentials:
106
+ aws_access_key_id: <your aws access key id>
107
+ aws_secret_access_key: <your aws secret access key>
108
+
109
+ server:
110
+ private_key: |
111
+ -----BEGIN RSA PRIVATE KEY-----
112
+ Include the RSA private key here. This should correspond to the keypair indicated
113
+ by server[:creation_config][:key_name] in aws_config.yml.
114
+ -----END RSA PRIVATE KEY-----
115
+ ```
116
+
117
+ Elzar will load both of these files and perform a deep merge on them.
118
+ Any settings in `aws_config.private.yml` will override settings found in
119
+ `aws_config.yml`.
120
+
121
+ Edit these files as appropriate for your project.
122
+
123
+
124
+ ### Step 4: Preheat Your Server
125
+
126
+ This step will provision a new server from AWS using your specified
127
+ credentials and will bootstrap Chef Solo on the box.
128
+
129
+ Note: **A *new* EC2 instance is provisioned each time this script is
130
+ executed**; you'll probably want to clean up those instances if you need
131
+ to re-start for any reason.
132
+
133
+ ```sh
134
+ elzar preheat "ElzarRailsExample Staging"
135
+ ```
136
+
137
+ In this case, Elzar will provision a new instance and tag it with a name
138
+ of "ElzarRailsExample Staging". This is the name that you will see when browsing
139
+ instances in the AWS console. Name your instance accordingly.
140
+
141
+ If this step completes successfully, it will display the ID of the
142
+ instance, which you'll use in the next step, as well as its public IP address. For example:
143
+
144
+ ```
145
+ Finished Provisioning Server
146
+ Instance ID: i-abcdef01
147
+ Instance IP: 42.42.000.42
148
+ ````
149
+
150
+
151
+ ### Step 5: Cook the Recipes
152
+
153
+ This step is responsible for combining your custom recipes (if any) and
154
+ configuration with the default recipes that ship with Elzar. The
155
+ combined payload will be uploaded to the server and placed in
156
+ `/tmp/chef-solo` where they will run.
157
+
158
+
159
+ ```sh
160
+ elzar cook [YOUR-INSTANCE-ID]
161
+ ```
162
+
163
+
164
+ ### Step 6: Configure Capistrano
165
+
166
+ At this point in time, we have a server that is ready to run our app.
167
+ Now, we just need to get our app up there.
168
+
169
+ First off, we need to add Capistrano and [capistrano-relevance](https://github.com/relevance/capistrano-relevance) to our Rails app.
170
+ To do so, add these lines to the `Gemfile` in the Rails application:
171
+
172
+ ```ruby
173
+ group :deployment do
174
+ gem 'capistrano', :git => 'git://github.com/capistrano/capistrano', :ref => 'b31e2f5'
175
+ gem 'capistrano-relevance'
176
+ end
177
+ ```
178
+
179
+ And then execute:
180
+
181
+ ```sh
182
+ bundle
183
+ bundle exec capify .
184
+ ```
185
+
186
+ Next, we need to customize `config/deploy.rb` for our app.
187
+ (For the purposes of this tutorial, we'll assume that we want the default capistrano-relevance configuration. For alternative setups, and for more information on capistrano-relevance, check out its [README](https://github.com/relevance/capistrano-relevance/blob/master/README.md).)
188
+
189
+ *Replace* the existing contents of `config/deploy.rb` with a structure like so:
190
+
191
+ ```ruby
192
+ require 'bundler/capistrano'
193
+ require 'capistrano/relevance/all'
194
+
195
+ set :application, "elzar_rails_example" # TODO Replace with *your* app name
196
+ set :repository, "git://github.com/you/elzar_rails_example" # TODO Replace with *your* repo
197
+
198
+ role :web, "42.42.000.42" # TODO Replace with the IP address for *your* EC2 instance
199
+ role :app, "42.42.000.42" # TODO Replace with the IP address for *your* EC2 instance
200
+ role :db, "42.42.000.42", :primary => true # TODO Replace with the IP address for *your* EC2 instance
201
+ ```
202
+
203
+
204
+ ### Step 7: Prepare to Serve
205
+
206
+ Now that we have a working Capistrano configuration we just need to make a couple of other small tweaks to make the box deployable.
207
+ Specifically, we need to create the directory structure that Capistrano expects and place our database configuration on the box.
208
+
209
+ Best practices (TM) discourage us from checking in any database credentials into our Git repo.
210
+ Instead, we can create a `database.yml` file on the server.
211
+
212
+ ```sh
213
+ bundle exec cap deploy:setup
214
+
215
+ ssh deploy@42.42.000.42
216
+
217
+ # Create the the directory where you will store your shared configuration.
218
+ mkdir /var/www/apps/[YOUR-APP-NAME]/shared/config
219
+
220
+ # Add production settings for the database
221
+ vim /var/www/apps/[YOUR-APP-NAME]/shared/config/database.yml
222
+
223
+ # We're done messing around on the server; let's get outta here
224
+ exit
225
+ ```
226
+
227
+ Your `database.yml` file should look similar to this one, obviously edited to meet your application's needs.
228
+
229
+ ```yaml
230
+ production:
231
+ adapter: postgresql
232
+ encoding: unicode
233
+ database: [YOUR-APP-NAME]_production
234
+ pool: 5
235
+ username: deploy
236
+ password: d3pl0y-p0stgr3s
237
+ ```
238
+
239
+
240
+ ### Step 8: Serve It Up
241
+
242
+ Here comes the exciting part.
243
+ It's time to deploy our Rails app to the box.
244
+ Since this is the first time we've ever deployed to the box we'll need to run a special Capistrano command that does slightly more work than a bare deploy.
245
+
246
+ ```sh
247
+ # execute from RAILS_ROOT on your localhost
248
+ bundle exec cap deploy:cold
249
+ ```
250
+
251
+ Congratulations! You should be able to visit the IP address using your favorite browser and see the application up and running.
252
+
253
+ For subsequent deploys, you can simply run:
254
+
255
+ ```sh
256
+ bundle exec cap deploy
257
+ ```