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
@@ -0,0 +1,52 @@
1
+ require 'elzar/fog'
2
+ require 'slushy'
3
+ require 'yaml'
4
+
5
+ module Elzar
6
+ module Compute
7
+ def self.provision_and_bootstrap!(instance_name, aws_config)
8
+ instance_id, instance_ip = provision(instance_name, aws_config)
9
+ bootstrap(instance_id, aws_config)
10
+
11
+ [instance_id, instance_ip]
12
+ end
13
+
14
+ def self.provision(name, aws_config)
15
+ config = aws_config['server']['creation_config']
16
+ config['tags'] = {'Name' => name}
17
+
18
+ slushy_instance = Slushy::Instance.launch(fog_connection(aws_config), config)
19
+ [slushy_instance.instance_id, slushy_instance.server.public_ip_address]
20
+ end
21
+
22
+ def self.bootstrap(instance_id, aws_config)
23
+ slushy_instance = slushy_instance_for(instance_id, aws_config)
24
+ slushy_instance.bootstrap
25
+ end
26
+
27
+ def self.converge!(instance_id, aws_config)
28
+ tmpdir = Elzar.merge_and_create_temp_directory File.expand_path('provision/')
29
+ slushy_instance = slushy_instance_for(instance_id, aws_config)
30
+ slushy_instance.converge tmpdir
31
+
32
+ [slushy_instance.instance_id, slushy_instance.server.public_ip_address]
33
+ end
34
+
35
+ def self.destroy!(instance_id, aws_config)
36
+ slushy_instance = slushy_instance_for(instance_id, aws_config)
37
+ slushy_instance.terminate
38
+ end
39
+
40
+ private
41
+
42
+ def self.fog_connection(aws_config)
43
+ @fog_connection ||= Fog::Compute.new(aws_config['aws_credentials'].merge(:provider => 'AWS'))
44
+ end
45
+
46
+ def self.slushy_instance_for(instance_id, aws_config)
47
+ Slushy::Instance.new(fog_connection(aws_config), instance_id).tap do |s|
48
+ s.server.private_key = aws_config['server']['private_key']
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,18 @@
1
+ module HashDeepMergeExt
2
+
3
+ # Implementation pulled from ActiveSupport
4
+ def deep_merge(other_hash)
5
+ dup.deep_merge!(other_hash)
6
+ end
7
+
8
+ def deep_merge!(other_hash)
9
+ other_hash.each_pair do |k,v|
10
+ tv = self[k]
11
+ self[k] = tv.is_a?(Hash) && v.is_a?(Hash) ? tv.deep_merge(v) : v
12
+ end
13
+ self
14
+ end
15
+
16
+ end
17
+
18
+ Hash.send(:include, HashDeepMergeExt) unless Hash.new.respond_to?(:deep_merge)
@@ -0,0 +1,53 @@
1
+ require 'fog'
2
+ require 'fog/core/ssh'
3
+
4
+ # Monkey-patch Fog 1.3.1 to stream SSH output
5
+ # (in real time) to stdout.
6
+ class Fog::SSH::Real
7
+ def run(commands)
8
+ commands = [*commands]
9
+ results = []
10
+ begin
11
+ Net::SSH.start(@address, @username, @options) do |ssh|
12
+ commands.each do |command|
13
+ result = Fog::SSH::Result.new(command)
14
+ ssh.open_channel do |ssh_channel|
15
+ ssh_channel.request_pty
16
+ ssh_channel.exec(command) do |channel, success|
17
+ unless success
18
+ raise "Could not execute command: #{command.inspect}"
19
+ end
20
+
21
+ channel.on_data do |ch, data|
22
+ result.stdout << data
23
+ puts data
24
+ end
25
+
26
+ channel.on_extended_data do |ch, type, data|
27
+ next unless type == 1
28
+ result.stderr << data
29
+ puts data
30
+ end
31
+
32
+ channel.on_request('exit-status') do |ch, data|
33
+ result.status = data.read_long
34
+ end
35
+
36
+ channel.on_request('exit-signal') do |ch, data|
37
+ result.status = 255
38
+ end
39
+ end
40
+ end
41
+ ssh.loop
42
+ results << result
43
+ end
44
+ end
45
+ rescue Net::SSH::HostKeyMismatch => exception
46
+ exception.remember_host!
47
+ sleep 0.2
48
+ retry
49
+ end
50
+ results
51
+ end
52
+ end
53
+
@@ -0,0 +1,37 @@
1
+ module Elzar
2
+ module SshKeyLocator
3
+
4
+ class << self
5
+ def default_key_file_paths
6
+ %w[id_dsa.pub id_ecdsa.pub id_rsa.pub].map do |base_filename|
7
+ File.expand_path("~/.ssh/#{base_filename}")
8
+ end
9
+ end
10
+
11
+ def find_keys(candidate_key_file_paths = default_key_file_paths)
12
+ local_keys = find_local_keys(candidate_key_file_paths)
13
+ local_keys.empty? ? find_agent_keys : local_keys
14
+ end
15
+
16
+ def find_local_keys(candidate_key_file_paths = default_key_file_paths)
17
+ first_existing_file = candidate_key_file_paths.find { |p| File.exist?(p) }
18
+ return [] unless first_existing_file
19
+
20
+ file_content = File.read(first_existing_file)
21
+ split_keys(file_content)
22
+ end
23
+
24
+ def find_agent_keys
25
+ keys = split_keys(`ssh-add -L`)
26
+ $?.success? ? keys : []
27
+ end
28
+
29
+ private
30
+
31
+ def split_keys(s)
32
+ s.split("\n").reject { |k| k.strip.empty? }
33
+ end
34
+ end
35
+
36
+ end
37
+ end
@@ -5,8 +5,8 @@ group "development" do
5
5
  gem "json", "1.5.2"
6
6
 
7
7
  gem "elzar"
8
- gem "vagrant", "0.8.7"
9
- gem "chef", "0.10.8"
10
- gem "knife-solo", "0.0.4"
11
- gem "knife-github-cookbooks", :git => "git://github.com/sumbach/knife-github-cookbooks.git"
8
+ gem "vagrant", "1.0.5"
9
+ gem "chef", "10.14.4"
10
+ gem "knife-solo", "0.0.14"
11
+ gem "knife-github-cookbooks", "~> 0.1.7"
12
12
  end
@@ -5,7 +5,7 @@ Vagrant::Config.run do |config|
5
5
  config.vm.box = "lucid64"
6
6
  config.vm.box_url = "http://files.vagrantup.com/lucid64.box"
7
7
  config.vm.host_name = <%= @vm_host_name.inspect %>
8
- config.vm.network "172.25.5.5"
8
+ config.vm.network :hostonly, "172.25.5.5"
9
9
  config.vm.provision :shell, :path => "upgrade-chef.sh"
10
10
  config.vm.provision :chef_solo do |chef|
11
11
  chef.cookbooks_path = <%= @cookbooks_path.inspect %>
@@ -0,0 +1,13 @@
1
+ # !!! DO NOT add this file to source control !!!
2
+ #
3
+ # Settings in this file override settings in aws_config.yml
4
+ aws_credentials:
5
+ aws_access_key_id: <your aws access key id>
6
+ aws_secret_access_key: <your aws secret access key>
7
+
8
+ server:
9
+ private_key: |
10
+ -----BEGIN RSA PRIVATE KEY-----
11
+ Include the RSA private key here. This should correspond to the keypair indicated
12
+ by server[:creation_config][:key_name] in aws_config.yml.
13
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,6 @@
1
+ server:
2
+ creation_config:
3
+ flavor_id: <instance type, e.g. 'm1.large'>
4
+ image_id: <AMI to bootstrap with; must be some Ubuntu server image; e.g., "ami-fd589594" for Ubuntu 11.04>
5
+ groups: <security group to place the new deployment in, e.g. "default">
6
+ key_name: <name of the public/private keypair to start instance with>
@@ -1,9 +1,8 @@
1
1
  {
2
2
  "id":"authorized_keys",
3
3
  "keys": [
4
- "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzqe0G9iGh9QoCdBVYmaTIxZU0cZP15uiXtLUsOf+BAjniNy2tX6fM+9+Mwmz76sqPlpL/ai/eVKg/WlmjtZErInTUdEu5IGoNqORLtwxGtu4u0tl/bByIEeYInHqlFlQnyEFeSEcWwW9JKWC7jL3Wh4M8FZrrGIQ7yd+XF4Q3vUpL+MZThs3/+VSoGvqcPbRGHoLtlgjwsjobXI6ckj839SkT0zVPuIoUl7zxlD4FRH95Hv60fjVIFU3D2aeOJrLkqHFogGjrXG47AIjgw5Xb1cwTUA0zQQ1Lq5TF038smXEyvySPOAuPPTnBC11TuzADdEuI0zFmjSu2RYi4/TfZw== alex.redington@thinkrelevance.com",
5
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC/aJwkhY3lpj6f62mpsy+fZ1lS90jF2cSTkX/bmjXrBO4yyFQsPFzsZhe6kdKkJGsVocppS8TZujzwL2vnhH4zfIIDIEwl9F9bqBznTwuwP0BcPIEJTEc7YVds2ocjR73A9YHHZxV7IfzYnYVunEmPtvPCSdQn+xq3V1bzY9tJJzXu/9DI0qxjTQAWB5nPfqyGwNnn2pcfNeZQquXMRHQnEyncpGq936vrYemwr25MlGNGzvhq0vQM8Qo5PSqh7XwSHR31aTsyL6RDF9nMOqHvqRsF+MKrsZSCYhjZ9ebuSRjdiDeWGNeYA8+zJJiirjJYwN6qxIGQ1AAkNrqZfKzV russolsen@thinkrelevance.com",
6
- "ssh-dss AAAAB3NzaC1kc3MAAACBAJCaIm17djv5DOGA0amRQTibubORv0mVCDnhkT/rYOIEAXr9S+s3JqrWqC9Q9++wFxVvuTr7rJArktoPQJXuAZfk9yH1Yyd2dhzMM/jHnw/TYKOnYj6mn4ygwARm9oZkuBI9AV81ICBtZPdBwPAH4vpOoY8FtKCCaiKrJdOCJfSPAAAAFQDlOSP4ehJY3w65d5GDEMftZ2va/wAAAIAUwmNmhG4W8LNv+ONsvJ/+GY2OumSJt72uzjcFRx9OLFzMgTG5YqQNuCbosA5SXvRS4w1F2+gPW/Tsdh9D3CElqOq3slMY+1JuDWznDK3byDe5sHQz8OOpjBtxFdn+bZJHTXercVpfIqjxR+903/zjYUT2tgv8kyZu44thn8+wRAAAAIBCoJqTsZwwErIH+RnX+LIETPYkKMt664CYb9mnNDj5a6hV/JX+ThiFdDd4YBUTVQkyNTQasJgOfZyauDT0BQJiEIiag1guvRtLhYH3PEId3vMsMGfv5349v2UqVr9g01CnbOL+yGc/Akxcw58/5QZe45S3A7hDbgUGsEBTNEuGaQ== sam@thinkrelevance.com",
7
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC/kJu5qUgbtVqYdxxN0LvZMJ5//JRno7bgnQ8ZB6dAouyE13GaiJ3jl61xCdKIOe6FL9/x2C379fcj2MUXiq/iIH4bllgn9owux7TucE4bKmMm2DxwDH/A2kvES3V+7LznvSSyhUJTSIVII2gQdeSaeE1DrJDNJJv/riXvmP6BI1AaLJnfE82Ym7XuYeLqvz1f6pCwxCZipuxjqr8HNBL3MfVN4Dw2xxya5AwAiR5Za93fVmszXBoyGo+BaUTTjdGzb4ghGOHjgp7rdLWbRoVcyXWntXq0jQ/Jkdg0dUVvFgLA88/IjyKvstmI1SrKK6SlwCWLSjAESpX3xRG2FNhp gabriel.horner@gmail.com"
8
- ]
4
+ "TODO: Add your public SSH keys for the provisioned server here",
5
+ "TODO: Add your public SSH keys for the provisioned server here",
6
+ "TODO: Add your public SSH keys for the provisioned server here"
7
+ ]
9
8
  }
@@ -0,0 +1,15 @@
1
+ {
2
+ "run_list":["role[plumbing]", "role[postgres_database]", "ruby", "passenger", "rails_app", "ruby::path"],
3
+ "passenger": {
4
+ "version": "3.0.11",
5
+ "root_path": "/opt/relevance-ruby/lib/ruby/gems/1.9.1/gems/passenger-3.0.11",
6
+ "module_path": "/opt/relevance-ruby/lib/ruby/gems/1.9.1/gems/passenger-3.0.11/ext/apache2/mod_passenger.so"
7
+ },
8
+ "ruby": {
9
+ "version": "1.9.3-p194",
10
+ "url": "http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p194.tar.gz"
11
+ },
12
+ "rails_app": {
13
+ "name": "TODO: Replace with the name of your Rails app"
14
+ }
15
+ }
@@ -0,0 +1 @@
1
+ aws_config.private.yml
@@ -1,3 +1,3 @@
1
1
  module Elzar
2
- VERSION = '0.1.2'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -0,0 +1,14 @@
1
+ #!/bin/bash
2
+
3
+ source "$HOME/.rvm/scripts/rvm"
4
+ export CI_RUBY_VERSION="ruby-1.9.3-p194"
5
+ export CI_GEMSET=elzar_nightly
6
+
7
+ # Tests and app are all running in CI_GEMSET
8
+ export NO_RVM=true
9
+
10
+ rvm use "$CI_RUBY_VERSION@$CI_GEMSET"
11
+ gem install bundler
12
+ bundle install
13
+
14
+ bundle exec rspec --tag ci
@@ -0,0 +1,9 @@
1
+ class AddRootUser < ActiveRecord::Migration
2
+ def up
3
+ User.find_or_create_by_username! 'root'
4
+ end
5
+
6
+ def down
7
+ raise ActiveRecord::IrreversibleMigration
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ production:
2
+ adapter: postgresql
3
+ encoding: unicode
4
+ database: elzar_nightly_app_production
5
+ pool: 5
6
+ username: deploy
7
+ password: d3pl0y-p0stgr3s
@@ -0,0 +1,11 @@
1
+ require 'bundler/capistrano'
2
+ require 'capistrano/relevance/all'
3
+
4
+ set :application, "elzar_nightly_app"
5
+ set :repository, "/tmp/elzar_nightly_app" # TODO Find a way not to duplicate this path here and inside the spec. Pass as env arg?
6
+
7
+ set(:server_ip) { ENV['SERVER_IP'] || raise("You must supply SERVER_IP") }
8
+
9
+ role :web, server_ip
10
+ role :app, server_ip
11
+ role :db, server_ip, :primary => true
@@ -0,0 +1,22 @@
1
+ TemplateRoot = File.expand_path '..', __FILE__
2
+
3
+ gem 'capistrano', :group => 'deployment', :git => 'git://github.com/capistrano/capistrano', :ref => 'b31e2f5'
4
+ gem 'capistrano-relevance', :group => 'deployment'
5
+
6
+ gem 'therubyracer', :group => 'assets', :platforms => :ruby
7
+
8
+ run 'bundle install'
9
+ run 'bundle exec capify .'
10
+
11
+ remove_file File.join('config', 'deploy.rb')
12
+ copy_file File.join(TemplateRoot, 'deploy.rb'), File.join('config', 'deploy.rb')
13
+
14
+ run 'rails generate scaffold user username:string'
15
+
16
+ next_migration_timestamp = (Time.now + 1)
17
+ migration_filename = next_migration_timestamp.utc.strftime("%Y%m%d%H%M%S") + '_add_root_user.rb'
18
+ copy_file File.join(TemplateRoot, 'add_root_user.rb'), File.join('db', 'migrate', migration_filename)
19
+
20
+ git :init
21
+ git :add => "."
22
+ git :commit => "-a -m 'Initial commit'"
@@ -0,0 +1,190 @@
1
+ require 'spec_helper'
2
+ require 'fileutils'
3
+ require 'json'
4
+
5
+ describe "Rails integration", :ci => true do
6
+ let(:rails_app) { 'elzar_nightly_app' }
7
+ let(:path_to_rails_app) { File.join '/tmp', rails_app }
8
+ let(:server_name) { "Elzar Nightly (rails) - #{Time.now.strftime("%Y-%m-%d %H:%M:%S")}" }
9
+ let(:aws_config_dir) { ENV['AWS_CONFIG_DIR'] || raise('You must set AWS_CONFIG_DIR to run the integration tests') }
10
+ let(:instance_info) { { :id => nil, :ip => nil } }
11
+
12
+ ######################################################################
13
+ # Command line helpers
14
+ ######################################################################
15
+
16
+ # wrapper around system
17
+ def shell(cmd)
18
+ puts "Executing #{cmd}..."
19
+ Bundler.clean_system(cmd)
20
+ abort "Command '#{cmd}' failed" unless $?.success?
21
+ end
22
+
23
+ def elzar(args)
24
+ puts "Running `elzar #{args}`"
25
+
26
+ super
27
+
28
+ raise "Error running `elzar #{args}`. Failed with: #{stderr}" unless process.exitstatus == 0
29
+ end
30
+
31
+ def rake(cmd)
32
+ sh "bundle exec rake #{cmd}"
33
+ end
34
+
35
+ def in_rails_app(&block)
36
+ pwd = FileUtils.pwd
37
+ FileUtils.cd path_to_rails_app
38
+ yield
39
+ ensure
40
+ FileUtils.cd pwd
41
+ end
42
+
43
+ ######################################################################
44
+ # Rails app helpers
45
+ ######################################################################
46
+
47
+ def create_new_rails_app
48
+ shell "gem install rails"
49
+ FileUtils.rm_rf(path_to_rails_app)
50
+ rails_template = File.expand_path('../../fixtures/rails_integration_template/template.rb', __FILE__)
51
+ shell %Q{rails new "#{path_to_rails_app}" -d postgresql -m "#{rails_template}"}
52
+ end
53
+
54
+ def configure_elzar
55
+ in_rails_app do
56
+ rewrite_json('provision/dna.json') do |dna|
57
+ dna['rails_app']['name'] = rails_app
58
+ end
59
+ end
60
+ end
61
+
62
+ def rewrite_json(path_to_json, &block)
63
+ json = JSON.parse File.read(path_to_json)
64
+ yield json
65
+ File.open(path_to_json, 'w') { |f| f << JSON.generate(json) }
66
+ end
67
+
68
+ ######################################################################
69
+ # AWS helpers
70
+ ######################################################################
71
+
72
+ def aws_config
73
+ @aws_config ||= Elzar::AwsConfig.load_configs(aws_config_dir)
74
+ end
75
+
76
+ def fog
77
+ @fog ||= Fog::Compute.new(aws_config['aws_credentials'].merge(:provider => 'AWS'))
78
+ end
79
+
80
+ def server(instance_id)
81
+ fog.servers.get(instance_id).tap do |s|
82
+ s.private_key = aws_config['server']['private_key']
83
+ end
84
+ end
85
+
86
+ def ssh(server, cmd)
87
+ job = nil
88
+ capture_stdout { job = server.ssh(cmd).first }
89
+ job
90
+ end
91
+
92
+ def put_database_config_on_server(server)
93
+ shared_path = "/var/www/apps/#{rails_app}/shared/config"
94
+ path_to_db_config = File.expand_path('../../fixtures/rails_integration_template/database.yml', __FILE__)
95
+ server.scp path_to_db_config, "/home/ubuntu/database.yml"
96
+
97
+ ssh server, "sudo mkdir -p #{shared_path}"
98
+ ssh server, "sudo mv ~/database.yml #{shared_path}/database.yml"
99
+ ssh server, "sudo chown -R deploy:deploy #{shared_path}"
100
+ end
101
+
102
+ def destroy_instance(instance_id)
103
+ in_rails_app do
104
+ elzar "destroy \"#{instance_id}\" --aws_config_dir=#{aws_config_dir}"
105
+ end
106
+ end
107
+
108
+ def capture_instance_details(output)
109
+ id = output.match(/Instance ID: (.+)$/i)[1]
110
+ ip = output.match(/Instance IP: (.+)$/i)[1]
111
+ [id, ip]
112
+ end
113
+
114
+ ######################################################################
115
+ # Assertion helpers
116
+ ######################################################################
117
+
118
+ # Returns true if the command gives zero exit status, false for non zero exit status.
119
+ def execute_local_command(cmd)
120
+ Bundler.clean_system(cmd)
121
+ end
122
+
123
+ # Returns true if the command gives zero exit status, false for non zero exit status.
124
+ def execute_remote_command(server, cmd)
125
+ ssh(server, cmd).status == 0
126
+ end
127
+
128
+ def assert_state_after_init
129
+ in_rails_app do
130
+ execute_local_command('ls provision > /dev/null').should == true
131
+ execute_local_command('grep -q rails provision/dna.json').should == true
132
+ end
133
+ end
134
+
135
+ def assert_state_after_preheat(server)
136
+ execute_remote_command(server, 'gem list | grep chef').should == true
137
+ end
138
+
139
+ def assert_state_after_cook(server)
140
+ execute_remote_command(server, '/opt/relevance-ruby/bin/ruby -v | grep 1\.9\.3').should == true
141
+ execute_remote_command(server, 'sudo service postgresql status').should == true
142
+ execute_remote_command(server, 'sudo service nginx status').should == true
143
+ execute_remote_command(server, 'ls /home/deploy').should == true
144
+ end
145
+
146
+ def assert_state_after_deploy(server_ip)
147
+ execute_local_command(%Q{curl -sL -w '%{http_code}' #{server_ip} -o /dev/null | grep 200}).should == true
148
+ execute_local_command(%Q{curl -s #{server_ip}/users.json | grep '"username":"root"'}).should == true
149
+ end
150
+
151
+ it 'works' do
152
+ create_new_rails_app
153
+
154
+ in_rails_app do
155
+ elzar "init --dna=rails"
156
+ end
157
+
158
+ assert_state_after_init
159
+
160
+ in_rails_app do
161
+ configure_elzar
162
+ elzar %Q{preheat "#{server_name}" --aws_config_dir=#{aws_config_dir}}
163
+ instance_info[:id], instance_info[:ip] = capture_instance_details(stdout)
164
+ end
165
+
166
+ instance_info[:id].should_not == nil
167
+ instance_info[:ip].should_not == nil
168
+ server = server(instance_info[:id])
169
+
170
+ assert_state_after_preheat(server)
171
+
172
+ in_rails_app do
173
+ elzar "cook \"#{instance_info[:id]}\" --aws_config_dir=#{aws_config_dir}"
174
+ end
175
+
176
+ assert_state_after_cook(server)
177
+
178
+ in_rails_app do
179
+ shell %Q{SERVER_IP="#{instance_info[:ip]}" cap deploy:setup}
180
+ put_database_config_on_server(server)
181
+ shell %Q{SERVER_IP="#{instance_info[:ip]}" cap deploy}
182
+ end
183
+
184
+ assert_state_after_deploy(instance_info[:ip])
185
+ end
186
+
187
+ after(:each) do
188
+ destroy_instance(instance_info[:id]) if instance_info[:id]
189
+ end
190
+ end