relevance_rails 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.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ *v0.2.0*
2
+
3
+ * Depend on slushy for provisioning
4
+ * Depend on elzar as a gem
5
+ ** elzar's chef recipes stay in elzar
6
+ ** relevance_rails has no knowledge of elzar's recipe internals
7
+ * Search for local ssh public keys before querying ssh-agent
8
+ * Improved UX around retrying failed commands
9
+ * Fix fixtures generator
10
+ * Generated Rails app depends on haml <= 3.1.4 due to haml 3.1.5 bug
11
+
1
12
  *v0.1.2*
2
13
 
3
14
  * add streaming output from chef convergence using a fog monkeypatch
data/Guardfile ADDED
@@ -0,0 +1,7 @@
1
+ guard 'rspec', :version => 2 do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
+
5
+ watch('spec/spec_helper.rb') { "spec" }
6
+ watch(%r{^spec/support/.+\.rb$}) { "spec" }
7
+ end
data/Rakefile CHANGED
@@ -9,3 +9,11 @@ task :acceptance do
9
9
  ENV["ACCEPTANCE"] = "true"
10
10
  Rake::Task[:spec].invoke
11
11
  end
12
+
13
+ # Do not run using bundle exec!
14
+ # FakeFS causes issues when bundler injects it into the require chain.
15
+ desc 'Run the elzar nightly specs'
16
+ RSpec::Core::RakeTask.new :elzar_nightly do |t|
17
+ t.pattern = 'spec/elzar_recipes_spec.rb'
18
+ t.rspec_opts = '-t ci'
19
+ end
data/USAGE.md CHANGED
@@ -13,10 +13,11 @@ $ rails g provision_config postgresql
13
13
  Configuring bundled ssh keys
14
14
  ----------------------------
15
15
 
16
- By default, relevance_rails bundles all your keys from `ssh-add -L` with your instance. For bundling
17
- additional keys, you can create a ~/.relevance_rails/keys_git_url file and point it to a git repo that
18
- has additional keys. Keys in that git repo should exist as top level *.pub files. You *MUST* have at
19
- least one key to provision.
16
+ By default, relevance_rails bundles one of your local keys (~/.ssh/id_rsa.pub, ~/.ssh/id_dsa.pub, or
17
+ ~/.ssh/id_ecdsa.pub) with your instance. If none are found it bundles all your keys from `ssh-add
18
+ -L`. For bundling additional keys, you can create a ~/.relevance_rails/keys_git_url file and point it
19
+ to a git repo that has additional keys. Keys in that git repo should exist as top level *.pub files.
20
+ You *MUST* have at least one key to provision.
20
21
 
21
22
  Provisioning on EC2
22
23
  -------------------
@@ -11,8 +11,7 @@ STR
11
11
  %h1 WELCOME HOME
12
12
  STR
13
13
  create_file "app/views/relevance_rails/db.html.haml", <<-STR
14
- = conn = ActiveRecord::Base.connection
15
- = results = conn.execute("select 4200+42 as advanced_math")
14
+ - results = ActiveRecord::Base.connection.select_all("select 4200+42 as advanced_math")
16
15
  %h1.advanced_math= results.first["advanced_math"]
17
16
  STR
18
17
  end
@@ -1,5 +1,7 @@
1
1
  require 'relevance_rails'
2
+ require 'tempfile'
2
3
  require 'rails/generators'
4
+ require 'elzar'
3
5
 
4
6
  class ProvisionConfigGenerator < Rails::Generators::Base
5
7
  include RelevanceRails::GeneratorOverrides
@@ -27,7 +29,14 @@ class ProvisionConfigGenerator < Rails::Generators::Base
27
29
 
28
30
  def check_authorized_keys
29
31
  if (@authorized_keys = fetch_keys).empty?
30
- abort "No ssh keys were found! Check ssh-add -L and your keys_git_url config."
32
+ abort <<-EOF
33
+ No SSH public keys were found!
34
+
35
+ To ensure you have remote access to your servers, an SSH public key must be available from at least one of these sources:
36
+ - local file (~/.ssh/id_rsa.pub, ~/.ssh/id_dsa.pub, or ~/.ssh/id_ecdsa.pub)
37
+ - ssh-agent (by running `ssh-add -L`)
38
+ - public keys git repo (URL to repo specified in ~/.relevance_rails/key_git_url)
39
+ EOF
31
40
  end
32
41
  end
33
42
 
@@ -39,42 +48,23 @@ class ProvisionConfigGenerator < Rails::Generators::Base
39
48
  git :commit => '-m "Add Capistrano files"'
40
49
  end
41
50
 
42
- def fetch_elzar
43
- git :remote => 'add -f elzar git://github.com/relevance/elzar.git'
44
- git :merge => '-s ours --no-commit elzar/master'
45
- git :"read-tree" => '--prefix=provision/ -u elzar/master'
46
- gsub_file 'provision/Vagrantfile', /config\.vm\.host_name(\s+)= .*$/,
47
- "config.vm.host_name\\1= '#{name.gsub('_','-')}.local'"
48
- end
49
-
50
- def create_authorized_key_data_bag
51
- @authorized_keys.map! {|key| "\"#{key}\""}
52
- template('authorized_keys.json.erb', 'provision/data_bags/deploy/authorized_keys.json', {:force => true})
53
- end
54
-
55
- def create_dna_json
56
- path = File.expand_path('provision/dna.json', destination_root)
57
- json = JSON.parse File.binread(path)
58
- json['rails_app']['name'] = name
59
- RelevanceRails::ChefDNA.gene_splice(json,database)
60
- create_file('provision/dna.json', JSON.generate(json), {:force => true})
51
+ def create_provision_directory
52
+ Elzar.create_provision_directory Rails.root.join('provision'),
53
+ :ruby_version => RelevanceRails.ruby_version, :database => database,
54
+ :authorized_keys => @authorized_keys, :app_name => name
61
55
  end
62
56
 
63
57
  def create_rvmrc
64
58
  if File.exists?(rvmrc = Rails.root.join('.rvmrc'))
65
- create_file('provision/.rvmrc', File.read(rvmrc), :force => true)
66
- git :add => 'provision/.rvmrc'
59
+ copy_file(rvmrc, 'provision/.rvmrc', :force => true)
67
60
  else
68
61
  remove_file 'provision/.rvmrc'
69
- git :rm => 'provision/.rvmrc'
70
62
  end
71
63
  end
72
64
 
73
65
  def commit_changes
74
- git :add => 'provision/data_bags/deploy/authorized_keys.json'
75
- git :add => 'provision/Vagrantfile'
76
- git :add => 'provision/dna.json'
77
- git :commit => '-m "Merge Elzar as our provision subdirectory"'
66
+ git :add => 'provision/'
67
+ git :commit => "-m 'Provision directory auto-created by elzar #{Elzar::VERSION}'"
78
68
  end
79
69
 
80
70
  private
@@ -104,10 +94,28 @@ class ProvisionConfigGenerator < Rails::Generators::Base
104
94
  git :add => destination
105
95
  end
106
96
 
107
-
108
97
  def fetch_keys
109
- local_keys = `ssh-add -L`.split("\n")
110
- local_keys = [] unless $?.success?
111
- (local_keys + RelevanceRails::PublicKeyFetcher.public_keys).uniq
98
+ keys = local_keys
99
+ keys = ssh_agent_keys if keys.empty?
100
+ keys += RelevanceRails::PublicKeyFetcher.public_keys
101
+ keys.uniq
102
+ end
103
+
104
+ def local_keys
105
+ key_files = [
106
+ File.expand_path("~/.ssh/id_dsa.pub"),
107
+ File.expand_path("~/.ssh/id_ecdsa.pub"),
108
+ File.expand_path("~/.ssh/id_rsa.pub"),
109
+ ]
110
+ key_files.select { |p| File.exist?(p) }.take(1).map { |p| split_keys(File.read(p)) }.flatten(1)
111
+ end
112
+
113
+ def ssh_agent_keys
114
+ keys = split_keys(`ssh-add -L`)
115
+ $?.success? ? keys : []
116
+ end
117
+
118
+ def split_keys(s)
119
+ s.split("\n").reject { |k| k.blank? }
112
120
  end
113
121
  end
@@ -1,7 +1,10 @@
1
1
  source :rubygems
2
2
 
3
3
  gem 'rails', '~> 3.2.2'
4
- gem 'haml', '~> 3.1.4'
4
+ # Avoiding 3.1.5 which has a bug with aliasing
5
+ # AbstractController::Rendering#render_to_body
6
+ # https://github.com/haml/haml/issues/519
7
+ gem 'haml', '>= 3.1.0', '<= 3.1.4'
5
8
  gem 'configatron', '~> 2.8.3'
6
9
  gem 'airbrake', '~> 3.0.4'
7
10
  gem 'factory_girl_rails', '~> 1.2.0'
@@ -29,7 +32,7 @@ end
29
32
  group "development", "test" do
30
33
  gem 'capybara', '~> 1.1.1'
31
34
  gem 'selenium-webdriver', '~> 2.5.0'
32
- gem 'rspec-rails', '~> 2.6.0'
35
+ gem 'rspec-rails', '~> 2.9.0'
33
36
  gem 'mocha', '~> 0.9.12'
34
37
  gem 'guard-rspec', '~> 0.5.0', :require => false
35
38
  gem 'growl', '~> 1.0.3', :require => false
@@ -1,49 +1,59 @@
1
1
  require 'fog'
2
2
  require 'thor'
3
- require 'timeout'
4
3
  require 'relevance_rails/fog_ext/ssh'
4
+ require 'slushy'
5
+ require 'elzar'
5
6
 
6
7
  module RelevanceRails
7
8
  module Provision
8
- class AptInstallError < StandardError
9
- end
9
+ CONFIG_FILE = 'config/ec2_instance.txt'
10
10
 
11
11
  def self.create_ec2(name = nil)
12
12
  abort "Please provide a $NAME" unless name
13
- server = provision_ec2_instances(name)
14
- wait_for_ssh server
15
- run_commands server
13
+ slushy = provision_ec2_instances(name)
14
+ slushy.bootstrap
15
+ tmpdir = Elzar.merge_and_create_temp_directory Rails.root.join('provision')
16
+ slushy.converge tmpdir
17
+ server = slushy.server
18
+ puts "Server Instance: #{server.id}"
19
+ puts "Server IP: #{server.public_ip_address}"
20
+ server
16
21
  end
17
22
 
18
23
  def self.stop_ec2
19
- return unless ENV["FORCE"] == "true" || Thor::Shell::Basic.new.yes?("Are you sure you want to shut down EC2 instance #{instance_id}?")
24
+ return unless (ENV["FORCE"] == "true") || Thor::Shell::Basic.new.yes?("Are you sure you want to shut down EC2 instance #{instance_id}?")
20
25
  puts "Shutting down EC2 instance #{instance_id}..."
21
- server = fog_connection.servers.get(instance_id)
22
- server.stop
23
- server.wait_for { state == "stopped" }
26
+ slushy = Slushy::Instance.new(fog_connection, instance_id)
27
+ slushy.stop
24
28
  puts "Done!"
25
29
  end
26
30
 
27
31
  def self.destroy_ec2
28
- return unless ENV["FORCE"] == "true" || Thor::Shell::Basic.new.yes?("Are you sure you want to destroy EC2 instance #{instance_id}?")
32
+ return unless (ENV["FORCE"] == "true") || Thor::Shell::Basic.new.yes?("Are you sure you want to destroy EC2 instance #{instance_id}?")
29
33
  puts "Destroying EC2 instance #{instance_id}..."
30
- server = fog_connection.servers.get(instance_id)
31
- server.destroy
32
- server.wait_for { state == "terminated" }
33
- puts "Removing config/ec2_instance.txt..."
34
- File.delete('config/ec2_instance.txt')
34
+ slushy = Slushy::Instance.new(fog_connection, instance_id)
35
+ slushy.terminate
36
+ puts "Removing #{CONFIG_FILE}..."
37
+ File.delete(CONFIG_FILE)
35
38
  puts "Done!"
36
39
  end
37
40
 
38
41
  def self.current_dns
39
- server = fog_connection.servers.get(instance_id)
40
- puts server.reload.dns_name
42
+ puts current_server.reload.dns_name
43
+ end
44
+
45
+ def self.current_server
46
+ fog_connection.servers.get(instance_id)
47
+ end
48
+
49
+ def self.private_key
50
+ config['server']['private_key']
41
51
  end
42
52
 
43
53
  private
44
54
 
45
55
  def self.instance_id
46
- @instance_id ||= File.read('config/ec2_instance.txt').chomp
56
+ @instance_id ||= File.read(CONFIG_FILE).chomp
47
57
  end
48
58
 
49
59
  def self.config
@@ -56,97 +66,14 @@ module RelevanceRails
56
66
 
57
67
  def self.provision_ec2_instances(name)
58
68
  puts "Provisioning an instance..."
59
- server = fog_connection.servers.create(config['server']['creation_config'])
60
- fog_connection.tags.create(:key => 'Name',
61
- :value => "#{name}",
62
- :resource_id => server.id)
63
- server.private_key = config['server']['private_key']
64
-
65
- File.open("config/ec2_instance.txt", "w") do |f|
66
- f.puts(server.id)
67
- end
69
+ conf = config['server']['creation_config']
70
+ conf['tags'] = {'Name' => name}
68
71
 
72
+ slushy = Slushy::Instance.launch(fog_connection, conf)
73
+ slushy.server.private_key = private_key
74
+ File.open(CONFIG_FILE, "w") { |f| f.puts(slushy.server.id) }
69
75
  puts "Provisioned!"
70
- server
76
+ slushy
71
77
  end
72
-
73
- def self.run_commands(server)
74
- apt_installs(server)
75
- puts "Installing chef..."
76
- run_command(server, 'sudo gem install chef --no-ri --no-rdoc --version 0.10.8')
77
- puts "Copying chef resources from provision directory..."
78
- server.scp("#{Rails.root.join('provision')}/", '/tmp/chef-solo', :recursive => true)
79
- puts "Converging server, this may take a while (10-20 minutes)"
80
- run_command(server, 'cd /tmp/chef-solo && sudo /var/lib/gems/1.8/bin/chef-solo -c solo.rb -j dna.json')
81
-
82
- puts "Server Instance: #{server.id}"
83
- puts "Server IP: #{server.public_ip_address}"
84
- server
85
- end
86
-
87
- def self.retry_block(times, errors, failure)
88
- succeeded = false
89
- attempts = 0
90
- last_error = nil
91
- until succeeded || attempts > times-1
92
- begin
93
- retval = yield
94
- succeeded = true
95
- rescue *errors => e
96
- puts failure
97
- attempts +=1
98
- last_error = e
99
- end
100
- end
101
- if succeeded
102
- return retval
103
- else
104
- exit 1
105
- end
106
- end
107
-
108
- def self.apt_installs(server)
109
- retry_block(3, [AptInstallError], "Apt-cache came from corrupt mirror, retrying update...") do
110
- puts "Updating apt cache..."
111
- run_apt_command(server, 'sudo apt-get update')
112
- puts "Installing ruby..."
113
- run_apt_command(server, 'sudo apt-get -y install ruby')
114
- puts "Installing rubygems..."
115
- run_apt_command(server, 'sudo apt-get -y install rubygems1.8')
116
- end
117
- end
118
-
119
- def self.run_apt_command(server, command)
120
- jobs = server.ssh(command)
121
- raise AptInstallError unless jobs_succeeded?(jobs)
122
- end
123
-
124
- def self.run_command(server, command)
125
- jobs = server.ssh(command)
126
- exit 1 unless jobs_succeeded?(jobs)
127
- end
128
-
129
- def self.wait_for_ssh(server)
130
- puts "Waiting for ssh connectivity..."
131
- server.wait_for { ready? }
132
- retry_block(5, [Errno::ECONNREFUSED, Timeout::Error], "Connecting to Amazon refused. Retrying...") do
133
- sleep 10
134
- Timeout.timeout(60) { server.ssh('ls') }
135
- end
136
- puts "Server up and listening for SSH!"
137
- end
138
-
139
- def self.jobs_succeeded?(jobs)
140
- return true if jobs.all? { |job| job.status == 0 }
141
- jobs.each do |job|
142
- puts "----------------------"
143
- puts "Command '#{job.command}'"
144
- puts "STDOUT: #{job.stdout}"
145
- puts "STDERR: #{job.stderr}"
146
- puts "----------------------"
147
- end
148
- false
149
- end
150
-
151
78
  end
152
79
  end
@@ -3,8 +3,8 @@ require 'tmpdir'
3
3
  module RelevanceRails::PublicKeyFetcher
4
4
  def self.public_keys
5
5
  pubkeys = []
6
- return pubkeys unless File.exist? user_git_url
7
- git_url = File.read user_git_url
6
+ return pubkeys unless File.exist?(user_git_url)
7
+ git_url = File.read(user_git_url)
8
8
  return pubkeys unless git_url =~ /\/(.*)\.git/
9
9
  repo_name = $1
10
10
  Dir.mktmpdir('public_keys') { |dir|
@@ -3,17 +3,17 @@ require 'relevance_rails'
3
3
  module RelevanceRails
4
4
  class Runner
5
5
  def self.start(argv=ARGV)
6
- if argv.empty? || argv[0] == '--help' || argv[0] == '-h'
6
+ if argv.empty? || (argv[0] == '--help') || (argv[0] == '-h')
7
7
  print_help
8
- elsif argv.delete '--version'
8
+ elsif argv.delete('--version')
9
9
  puts "RelevanceRails #{RelevanceRails::VERSION}"
10
10
  elsif argv[0] == 'new'
11
11
  add_default_options! argv
12
- if ENV['rvm_path'].nil?
12
+ if ENV['rvm_path'].nil? || ENV['NO_RVM']
13
13
  exec 'rails', *argv
14
14
  else
15
15
  app_name = argv[1]
16
- env = setup_rvm app_name
16
+ env = setup_rvm(app_name)
17
17
 
18
18
  new_rvm_string = "#{env.environment_name.split('@')[0]}@#{app_name}"
19
19
  install_relevance_rails argv, new_rvm_string, env.environment_name
@@ -54,9 +54,7 @@ STR
54
54
  # in 1.12.0, so you don't use this trick anymore.
55
55
  $LOAD_PATH.unshift "#{ENV['rvm_path']}/lib"
56
56
  end
57
-
58
57
  require 'rvm'
59
-
60
58
  env = RVM::Environment.current
61
59
  env.gemset_create(app_name)
62
60
  env
@@ -66,13 +64,19 @@ STR
66
64
  child_env = RVM::Environment.new(new_rvm_string)
67
65
  puts "Installing relevance_rails into the app's gemset..."
68
66
 
69
- result = if argv.delete '--relevance-dev'
70
- rubygem = "#{ENV['rvm_path']}/gems/#{current_gemset}/cache/relevance_rails-#{RelevanceRails::VERSION}.gem"
71
- child_env.run('gem', 'install', rubygem)
67
+ result = if argv.delete('--relevance-dev')
68
+ gem_dir = "#{ENV['rvm_path']}/gems/#{current_gemset}/cache"
69
+ require 'elzar'
70
+ child_env.run('gem', 'install', "#{gem_dir}/elzar-#{Elzar::VERSION}.gem")
71
+ child_env.run('gem', 'install', "#{gem_dir}/relevance_rails-#{RelevanceRails::VERSION}.gem")
72
72
  else
73
73
  child_env.run('gem', 'install', 'relevance_rails', '-v', RelevanceRails::VERSION)
74
74
  end
75
- abort "Unable to install relevance_rails into the new gemset" if result.exit_status != 0
75
+ if result.exit_status != 0
76
+ abort "Unable to install relevance_rails into the new gemset. " +
77
+ "\nExit code: #{result.exit_status}" +
78
+ "\nFailed with:\n#{result.stderr}"
79
+ end
76
80
  end
77
81
 
78
82
  def self.add_default_options!(argv)
@@ -1,3 +1,3 @@
1
1
  module RelevanceRails
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -1,7 +1,6 @@
1
1
  require "relevance_rails/version"
2
2
  require "relevance_rails/public_key_fetcher"
3
- require "relevance_rails/chef_dna"
4
- require 'relevance_rails/railtie' if defined? Rails
3
+ require 'relevance_rails/railtie' if defined?(Rails)
5
4
  require 'relevance_rails/generator_overrides'
6
5
 
7
6
  module RelevanceRails
@@ -8,31 +8,28 @@ Gem::Specification.new do |s|
8
8
  s.homepage = "http://github.com/relevance/relevance_rails"
9
9
  s.authors = ["Alex Redington"]
10
10
  s.email = ["alex.redington@thinkrelevance.com"]
11
- s.homepage = ""
12
11
  s.summary = %q{Rails 3 Relevance style, with all infrastructure bits automated away.}
13
12
  s.description = %q{A Rails 3 wrapper which forces template use and includes a plethora of generators for standard Relevance bits.}
14
13
 
15
- s.rubyforge_project = "relevance_rails"
16
-
17
14
  s.files = `git ls-files`.split("\n")
18
15
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
16
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
- s.require_paths = ["lib"]
21
17
 
22
- s.bindir = 'bin'
23
18
  s.executables = ['relevance_rails']
24
19
 
25
- # specify any dependencies here; for example:
26
- s.add_runtime_dependency 'rails', '~> 3.2'
27
-
28
20
  # be aware that we're monkey-patching fog in fog_ext/ssh.rb;
29
21
  # if we update fog, that monkey-patch might need to be
30
22
  # revisited
31
23
  s.add_runtime_dependency 'fog', '1.3.1'
32
-
24
+ s.add_runtime_dependency 'rails', '~> 3.2'
25
+ s.add_runtime_dependency 'slushy', '~> 0.1.1'
33
26
  s.add_runtime_dependency 'thor', '~> 0.14.6'
34
- s.add_development_dependency 'pry'
27
+ s.add_runtime_dependency 'elzar', '~> 0.1.0'
28
+
35
29
  s.add_development_dependency 'capybara'
36
- s.add_development_dependency 'rspec'
30
+ s.add_development_dependency 'fakefs'
31
+ s.add_development_dependency 'guard-rspec'
32
+ s.add_development_dependency 'pry'
37
33
  s.add_development_dependency 'rake', '~> 0.9.2.2'
34
+ s.add_development_dependency 'rspec'
38
35
  end
data/script/ci CHANGED
@@ -25,9 +25,13 @@ function files_must_NOT_exist {
25
25
  RAILS_APP="app_for_ci"
26
26
  TARGET_HOST="placeholder.example.com"
27
27
 
28
+ # Set overrideable defaults
29
+ : ${CI_DATABASE:="postgresql"}
30
+ : ${CI_RUBY_VERSION:="ruby-1.9.2"}
31
+
28
32
  # Setup RVM
29
33
  source "$HOME/.rvm/scripts/rvm"
30
- rvm use "ruby-1.9.2@relevance_rails"
34
+ rvm use "$CI_RUBY_VERSION@relevance_rails"
31
35
  echo "RVM is now using:` rvm current`"
32
36
 
33
37
  # exit if any statement fails;
@@ -50,7 +54,7 @@ rvm --force gemset delete $RAILS_APP
50
54
  set -e
51
55
  echo "Done"
52
56
 
53
- relevance_rails new $RAILS_APP --database=postgresql --relevance-dev
57
+ relevance_rails new $RAILS_APP --database=$CI_DATABASE --relevance-dev
54
58
 
55
59
  # NOTE: this does NOT change the RVM gemset; we set it manually below
56
60
  builtin cd $RAILS_APP
data/script/ci_nightly CHANGED
@@ -13,36 +13,53 @@ function stop_server_and_exit {
13
13
  echo "Stopping newly-created server..."
14
14
  bundle exec rake provision:stop FORCE=true --trace
15
15
  echo "Done."
16
+ else
17
+ echo "No server to stop (i.e. can't find config/ec2_instance.txt)."
16
18
  fi
17
19
 
18
20
  echo "BUILD FAILED"
19
21
  exit 1
20
22
  }
21
23
 
24
+ function cd_rails_app {
25
+ builtin cd $RAILS_APP
26
+ rvm gemset use $RAILS_APP
27
+ }
28
+
22
29
  echo "RVM is now using:` rvm current`"
23
30
 
31
+ if [ -z $CI_RUBY_VERSION ]; then
32
+ echo 'You must specify $CI_RUBY_VERSION!'
33
+ exit 1
34
+ fi
35
+
36
+ if [ -z $CI_DATABASE ]; then
37
+ echo 'You must specify $CI_DATABASE!'
38
+ exit 1
39
+ fi
40
+
24
41
  set -e
25
42
  ./script/ci
26
43
  set +e
27
44
 
28
45
  source "$HOME/.rvm/scripts/rvm"
29
- rvm use "ruby-1.9.2@$RAILS_APP"
46
+ rvm use "$CI_RUBY_VERSION@$RAILS_APP"
30
47
  echo "RVM is now using:` rvm current`"
31
48
 
32
49
  builtin cd $RAILS_APP
33
-
50
+
34
51
  echo "Provisioning an EC2 instance..."
35
52
  rm -f $EC2_MEMENTO_FILE
36
53
  server_name="Nightly Build Testing - `date "+%Y-%m-%d %H:%M:%S"` "
37
54
  bundle exec rake --trace provision:ec2 NAME="$server_name"
38
55
  [ $? -ne 0 ] && stop_server_and_exit
39
56
  echo "Done!"
40
-
57
+
41
58
  echo "Determine the EC2 instance's DNS name..."
42
59
  TARGET_HOST=`bundle exec rake provision:current_dns`
43
60
  [ $? -ne 0 ] && stop_server_and_exit
44
61
  echo "Done."
45
-
62
+
46
63
  echo "Generating relevance_rails deployment scripts..."
47
64
  ./script/rails generate deployment staging $TARGET_HOST --force
48
65
  [ $? -ne 0 ] && stop_server_and_exit
@@ -67,11 +84,10 @@ echo "RVM is now using:` rvm current`"
67
84
 
68
85
  echo "Running the acceptance tests against our newly-created server..."
69
86
  ACCEPTANCE_HOST=$TARGET_HOST rake acceptance --trace
70
- [ $? -ne 0 ] && stop_server_and_exit
87
+ [ $? -ne 0 ] && cd_rails_app && stop_server_and_exit
71
88
  echo "Done."
72
89
 
73
- builtin cd $RAILS_APP
74
- rvm gemset use $RAILS_APP
90
+ cd_rails_app
75
91
 
76
92
  echo "Terminating our newly-created server..."
77
93
  bundle exec rake provision:destroy FORCE=true --trace
@@ -0,0 +1,33 @@
1
+ #!/bin/bash
2
+
3
+ RAILS_APP="elzar_nightly_app"
4
+ EC2_MEMENTO_FILE="config/ec2_instance.txt"
5
+
6
+ function stop_server_and_exit {
7
+ if [ -f $EC2_MEMENTO_FILE ]; then
8
+ echo "Stopping newly-created server..."
9
+ bundle exec rake provision:stop FORCE=true --trace
10
+ else
11
+ echo "No server to stop (i.e. can't find config/ec2_instance.txt)."
12
+ fi
13
+
14
+ echo "BUILD FAILED"
15
+ exit 1
16
+ }
17
+
18
+ source "$HOME/.rvm/scripts/rvm"
19
+ export CI_GEMSET=elzar_nightly
20
+ # Tests and app are all running in CI_GEMSET
21
+ export NO_RVM=true
22
+
23
+ rvm use "$CI_RUBY_VERSION@$CI_GEMSET"
24
+ gem install bundler
25
+ bundle install
26
+
27
+ # DO NOT bundle exec rake - fakefs activation borks everything
28
+ rake elzar_nightly
29
+
30
+ [ $? -ne 0 ] && builtin cd $RAILS_APP && stop_server_and_exit
31
+
32
+ builtin cd $RAILS_APP
33
+ bundle exec rake provision:destroy FORCE=true --trace
@@ -0,0 +1,88 @@
1
+ require 'spec_helper'
2
+ require 'fileutils'
3
+ require 'relevance_rails/provision'
4
+
5
+ describe "Elzar recipes", :ci => true do
6
+ let(:rails_app) { ENV['RAILS_APP'] || 'elzar_nightly_app' }
7
+ let(:server_name) { "Elzar Nightly (#{database} / #{ruby_version}) - #{Time.now.strftime("%Y-%m-%d %H:%M:%S")}" }
8
+ let(:database) { ENV['CI_DATABASE'] || 'mysql' }
9
+ let(:database_cmd) { { 'mysql' => 'mysql', 'postgresql' => 'psql'}[database] }
10
+ let(:ruby_version) { ENV['CI_RUBY_VERSION'] || 'ruby-1.9.3-p125' }
11
+ let(:ruby_bin_path) {
12
+ ruby_version.start_with?('ree-') ? '/opt/ruby-enterprise/bin' : '/opt/relevance-ruby/bin'
13
+ }
14
+ let(:gemset) { ENV['CI_GEMSET'] || 'elzar_nightly' }
15
+
16
+ # wrapper around system
17
+ def shell(cmd)
18
+ puts "Executing #{cmd}..."
19
+ system(cmd)
20
+ abort "Command '#{cmd}' failed" unless $?.success?
21
+ end
22
+
23
+ def sh(cmd)
24
+ shell "#{ruby_version}@#{gemset} -S #{cmd}"
25
+ end
26
+
27
+ def rake(cmd)
28
+ sh "bundle exec rake #{cmd}"
29
+ end
30
+
31
+ # New app is created in current gemset
32
+ def create_new_app
33
+ rake 'install --trace'
34
+ FileUtils.rm_rf(rails_app)
35
+ sh "relevance_rails new #{rails_app} --database=#{database} --relevance-dev"
36
+ end
37
+
38
+ def ssh(cmd)
39
+ server = RelevanceRails::Provision.current_server
40
+ server.username = 'relevance'
41
+ server.private_key = RelevanceRails::Provision.private_key
42
+ job = nil
43
+ capture_stdout { job = server.ssh(cmd).first }
44
+ job
45
+ end
46
+
47
+ def command_succeeds(cmd)
48
+ ssh(cmd).status.should == 0
49
+ end
50
+
51
+ before(:all) do
52
+ create_new_app
53
+ Dir.chdir rails_app
54
+ rake %[provision:ec2 NAME="#{server_name}" --trace]
55
+ end
56
+
57
+ it "installs the right ruby" do
58
+ job = ssh "#{ruby_bin_path}/ruby -v"
59
+ if ruby_version.start_with?('ree-')
60
+ job.stdout.include?("Ruby Enterprise Edition").should be_true
61
+ else
62
+ version_number = ruby_version.sub(/^ruby/, '').tr('-', '')
63
+ job.stdout.start_with?("ruby #{version_number}").should be_true
64
+ end
65
+ end
66
+
67
+ it "installs the correct database" do
68
+ command_succeeds("#{database_cmd} --version")
69
+ end
70
+
71
+ it "creates a deploy user" do
72
+ command_succeeds("ls /home/deploy")
73
+ end
74
+
75
+ it "creates nginx and configures it" do
76
+ # TODO: get nginx version from elzar
77
+ command_succeeds "/opt/nginx-1.0.10/sbin/nginx -h"
78
+ command_succeeds "ls /etc/nginx/nginx.conf"
79
+ command_succeeds "ls /etc/init.d/nginx"
80
+ command_succeeds "ls /etc/nginx/sites-enabled/#{rails_app}"
81
+ end
82
+
83
+ it "installs passenger gem and configures it" do
84
+ command_succeeds "#{ruby_bin_path}/gem list passenger$ |grep passenger -q"
85
+ command_succeeds "ls /etc/nginx/conf.d/passenger.conf"
86
+ command_succeeds %[grep -q "passenger_ruby #{ruby_bin_path}/ruby;" /etc/nginx/conf.d/passenger.conf]
87
+ end
88
+ end
@@ -0,0 +1,116 @@
1
+ require 'spec_helper'
2
+ require 'fileutils'
3
+ require 'fakefs/spec_helpers'
4
+ require 'generators/provision_config/provision_config_generator'
5
+
6
+ describe ProvisionConfigGenerator do
7
+ subject { ProvisionConfigGenerator.new(["name"]) }
8
+
9
+ describe "#local_keys" do
10
+ include FakeFS::SpecHelpers
11
+
12
+ def write_fixture(path, contents)
13
+ FileUtils.mkdir_p(File.dirname(path))
14
+ File.open(path, "w") { |f| f.write(contents) }
15
+ end
16
+
17
+ it "returns the contents of id_rsa.pub when it exists" do
18
+ write_fixture(File.expand_path("~/.ssh/id_rsa.pub"), "RSA-public-key")
19
+ subject.send(:local_keys).should == ["RSA-public-key"]
20
+ end
21
+
22
+ it "returns the contents of id_dsa.pub when it exists" do
23
+ write_fixture(File.expand_path("~/.ssh/id_dsa.pub"), "DSA-public-key")
24
+ subject.send(:local_keys).should == ["DSA-public-key"]
25
+ end
26
+
27
+ it "returns the contents of id_ecdsa.pub when it exists" do
28
+ write_fixture(File.expand_path("~/.ssh/id_ecdsa.pub"), "ECDSA-public-key")
29
+ subject.send(:local_keys).should == ["ECDSA-public-key"]
30
+ end
31
+
32
+ it "returns the contents of id_dsa.pub when both id_dsa.pub and id_rsa.pub exist" do
33
+ write_fixture(File.expand_path("~/.ssh/id_dsa.pub"), "DSA-public-key")
34
+ write_fixture(File.expand_path("~/.ssh/id_rsa.pub"), "RSA-public-key")
35
+ subject.send(:local_keys).should == ["DSA-public-key"]
36
+ end
37
+
38
+ it "ignores trailing newlines" do
39
+ write_fixture(File.expand_path("~/.ssh/id_rsa.pub"), "RSA-public-key\n\n")
40
+ subject.send(:local_keys).should == ["RSA-public-key"]
41
+ end
42
+
43
+ it "ignores blank lines" do
44
+ write_fixture(File.expand_path("~/.ssh/id_rsa.pub"), "\n\nRSA-public-key\n\n\n")
45
+ subject.send(:local_keys).should == ["RSA-public-key"]
46
+ end
47
+ end
48
+
49
+ describe "#ssh_agent_keys" do
50
+ it "retrieves keys from ssh agent" do
51
+ subject.should_receive("`").with("ssh-add -L") do
52
+ system("true")
53
+ "my-public-key\nanother-public-key"
54
+ end
55
+ subject.send(:ssh_agent_keys).should == ["my-public-key", "another-public-key"]
56
+ end
57
+
58
+ it "ignores output from ssh-add when execution fails" do
59
+ subject.stub("`") do
60
+ system("false")
61
+ # Actual message that comes back from failed call
62
+ "The agent has no entities"
63
+ end
64
+ subject.send(:ssh_agent_keys).should == []
65
+ end
66
+ end
67
+
68
+ describe "#fetch_keys" do
69
+ it "returns local keys when they exist" do
70
+ subject.stub(:local_keys).and_return(["key-from-local-file"])
71
+ subject.stub(:ssh_agent_keys).and_return(["key-from-ssh-agent"])
72
+ RelevanceRails::PublicKeyFetcher.stub(:public_keys).and_return([])
73
+ subject.send(:fetch_keys).should == ["key-from-local-file"]
74
+ end
75
+
76
+ it "returns keys from ssh agent when local keys do NOT exist" do
77
+ subject.stub(:local_keys).and_return([])
78
+ subject.stub(:ssh_agent_keys).and_return(["key-from-ssh-agent"])
79
+ RelevanceRails::PublicKeyFetcher.stub(:public_keys).and_return([])
80
+ subject.send(:fetch_keys).should == ["key-from-ssh-agent"]
81
+ end
82
+
83
+ it "combines local keys with those from PublicKeyFetcher" do
84
+ subject.stub(:local_keys).and_return(["key-from-local-file"])
85
+ RelevanceRails::PublicKeyFetcher.stub(:public_keys).and_return(["key-from-git-repo"])
86
+ subject.send(:fetch_keys).should == ["key-from-local-file", "key-from-git-repo"]
87
+ end
88
+
89
+ it "combines ssh agent keys with those from PublicKeyFetcher" do
90
+ subject.stub(:local_keys).and_return([])
91
+ subject.stub(:ssh_agent_keys).and_return(["key-from-ssh-agent"])
92
+ RelevanceRails::PublicKeyFetcher.stub(:public_keys).and_return(["key-from-git-repo"])
93
+ subject.send(:fetch_keys).should == ["key-from-ssh-agent", "key-from-git-repo"]
94
+ end
95
+
96
+ it "excludes duplicate keys" do
97
+ subject.stub(:local_keys).and_return(["key-1", "key-2", "key-1"])
98
+ RelevanceRails::PublicKeyFetcher.stub(:public_keys).and_return(["key-3", "key-2", "key-3"])
99
+ subject.send(:fetch_keys).should == ["key-1", "key-2", "key-3"]
100
+ end
101
+ end
102
+
103
+ describe "#check_authorized_keys" do
104
+ it "aborts if no ssh-keys are found" do
105
+ subject.stub(:fetch_keys).and_return([])
106
+ should_abort_with(/^No SSH public keys were found!/) do
107
+ subject.check_authorized_keys
108
+ end
109
+ end
110
+
111
+ it "doesn't abort if ssh-keys are found" do
112
+ subject.should_receive(:fetch_keys).and_return(['ssh-rsa ZZZZ'])
113
+ expect { subject.check_authorized_keys }.to_not raise_error
114
+ end
115
+ end
116
+ end
@@ -15,10 +15,9 @@ describe RelevanceRails::Runner do
15
15
  it "new calls exec" do
16
16
  RelevanceRails::Runner.should_receive(:exec).with(anything,
17
17
  '-S', 'rails', 'new', 'the_app', '-m',
18
- File.expand_path(File.dirname(__FILE__) +
19
- "/../../lib/relevance_rails/relevance_rails_template.rb"))
18
+ File.expand_path("../../../lib/relevance_rails/relevance_rails_template.rb", File.dirname(__FILE__)))
20
19
  RelevanceRails::Runner.should_receive(:install_relevance_rails)
21
- env = mock :environment_name => '1.9.3@default'
20
+ env = mock(:environment_name => '1.9.3@default')
22
21
  RelevanceRails::Runner.should_receive(:setup_rvm).and_return(env)
23
22
  start('new', 'the_app')
24
23
  end
data/spec/spec_helper.rb CHANGED
@@ -44,6 +44,7 @@ RSpec.configure do |config|
44
44
  config.include TestHelpers
45
45
  config.filter_run :focused => true
46
46
  config.filter_run_excluding :acceptance => true
47
+ config.filter_run_excluding :ci => true
47
48
  config.filter_run_excluding :disabled => true
48
49
  config.run_all_when_everything_filtered = true
49
50
  end
data/techdebt.md CHANGED
@@ -1,20 +1,18 @@
1
1
  * TECHDEBT BY COMPONENT *
2
2
 
3
3
  * GENERAL
4
- ** remove heredocs, replace by erb templates
5
4
  ** move all general configuration to a ~/.relevance_rails.yml file (AWS stuff, keys git repo stuff)
6
- ** cleaner rvm version detection - intermittenly picks up no version
7
5
  ** intermittent mysql::server failures (mysql server not up yet) on `vagrant up`. Attempt fix in site_cookbooks
8
- ** intermittent setup failure - apt-get update fails with 404s or ruby not found
9
6
  ** when generating an app with --database=postgresql, provision_config
10
7
  generator intermittently fails at the beginning with different gem not found
11
8
  errors. Generating the app more than once or inspecting the problem solves it
12
9
  ** provision_config generator intermittently can't detect current working directory which breaks
13
10
  git commands. Current solution of sprinkling Dir.chdir is a bandaid at best.
14
-
15
- * Provisioning an instance
16
- ** Don't hardcode path to chef binstub, caused by ubuntu installing weirdness
17
11
  ** Make the deployment generator idempotent
18
- ** Better error handling when the aws.yml is not present
19
- ** On an uncaught exception, destroy the ec2 instances (?)
20
- ** RelevanceRails::Provision.wait_for_ssh intermittently hangs
12
+ ** Have pg and mysql recipes depend on a unified gem install method. This method would call
13
+ gem_package for mri and ree_gem for ree. When this is done, we can add --dont-install-useful-gems
14
+ back to the ree installer.
15
+ ** Upgrade to haml > 3.1.5 once AbstractController::Rendering#render_to_body bug is resolved
16
+ ** bundle exec rake elzar_nightly breaks due to fakefs being activated early in require chain.
17
+ Calling the rake task works fine locally and on CI. Attempting to not require fakefs in the
18
+ Gemfile didn't work.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: relevance_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-19 00:00:00.000000000 Z
12
+ date: 2012-05-09 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: fog
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - '='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.3.1
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - '='
28
+ - !ruby/object:Gem::Version
29
+ version: 1.3.1
14
30
  - !ruby/object:Gem::Dependency
15
31
  name: rails
16
32
  requirement: !ruby/object:Gem::Requirement
@@ -28,21 +44,21 @@ dependencies:
28
44
  - !ruby/object:Gem::Version
29
45
  version: '3.2'
30
46
  - !ruby/object:Gem::Dependency
31
- name: fog
47
+ name: slushy
32
48
  requirement: !ruby/object:Gem::Requirement
33
49
  none: false
34
50
  requirements:
35
- - - '='
51
+ - - ~>
36
52
  - !ruby/object:Gem::Version
37
- version: 1.3.1
53
+ version: 0.1.1
38
54
  type: :runtime
39
55
  prerelease: false
40
56
  version_requirements: !ruby/object:Gem::Requirement
41
57
  none: false
42
58
  requirements:
43
- - - '='
59
+ - - ~>
44
60
  - !ruby/object:Gem::Version
45
- version: 1.3.1
61
+ version: 0.1.1
46
62
  - !ruby/object:Gem::Dependency
47
63
  name: thor
48
64
  requirement: !ruby/object:Gem::Requirement
@@ -60,7 +76,23 @@ dependencies:
60
76
  - !ruby/object:Gem::Version
61
77
  version: 0.14.6
62
78
  - !ruby/object:Gem::Dependency
63
- name: pry
79
+ name: elzar
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 0.1.0
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 0.1.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: capybara
64
96
  requirement: !ruby/object:Gem::Requirement
65
97
  none: false
66
98
  requirements:
@@ -76,7 +108,7 @@ dependencies:
76
108
  - !ruby/object:Gem::Version
77
109
  version: '0'
78
110
  - !ruby/object:Gem::Dependency
79
- name: capybara
111
+ name: fakefs
80
112
  requirement: !ruby/object:Gem::Requirement
81
113
  none: false
82
114
  requirements:
@@ -92,7 +124,23 @@ dependencies:
92
124
  - !ruby/object:Gem::Version
93
125
  version: '0'
94
126
  - !ruby/object:Gem::Dependency
95
- name: rspec
127
+ name: guard-rspec
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: pry
96
144
  requirement: !ruby/object:Gem::Requirement
97
145
  none: false
98
146
  requirements:
@@ -123,6 +171,22 @@ dependencies:
123
171
  - - ~>
124
172
  - !ruby/object:Gem::Version
125
173
  version: 0.9.2.2
174
+ - !ruby/object:Gem::Dependency
175
+ name: rspec
176
+ requirement: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ! '>='
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ type: :development
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ none: false
186
+ requirements:
187
+ - - ! '>='
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
126
190
  description: A Rails 3 wrapper which forces template use and includes a plethora of
127
191
  generators for standard Relevance bits.
128
192
  email:
@@ -137,6 +201,7 @@ files:
137
201
  - .travis.yml
138
202
  - CHANGELOG.md
139
203
  - Gemfile
204
+ - Guardfile
140
205
  - README.md
141
206
  - Rakefile
142
207
  - USAGE.md
@@ -146,7 +211,6 @@ files:
146
211
  - lib/generators/fixtures/fixtures_generator.rb
147
212
  - lib/generators/provision_config/provision_config_generator.rb
148
213
  - lib/generators/provision_config/templates/Capfile
149
- - lib/generators/provision_config/templates/authorized_keys.json.erb
150
214
  - lib/generators/provision_config/templates/deploy.rb.erb
151
215
  - lib/generators/provision_config/templates/recipes_deploy.rb
152
216
  - lib/generators/provision_config/templates/vagrant.rb
@@ -158,7 +222,6 @@ files:
158
222
  - lib/generators/relevance_file/templates/database.example.yml.postgresql.erb
159
223
  - lib/generators/relevance_file/templates/spec_helper.rb
160
224
  - lib/relevance_rails.rb
161
- - lib/relevance_rails/chef_dna.rb
162
225
  - lib/relevance_rails/fog_ext/ssh.rb
163
226
  - lib/relevance_rails/generator_overrides.rb
164
227
  - lib/relevance_rails/provision.rb
@@ -171,13 +234,14 @@ files:
171
234
  - relevance_rails.gemspec
172
235
  - script/ci
173
236
  - script/ci_nightly
237
+ - script/elzar_nightly
174
238
  - spec/acceptance_spec.rb
175
- - spec/lib/provision_config_generator_spec.rb
176
- - spec/lib/provision_spec.rb
177
- - spec/lib/runner_spec.rb
239
+ - spec/elzar_recipes_spec.rb
240
+ - spec/lib/generators/provision_config/provision_config_generator_spec.rb
241
+ - spec/lib/relevance_rails/runner_spec.rb
178
242
  - spec/spec_helper.rb
179
243
  - techdebt.md
180
- homepage: ''
244
+ homepage: http://github.com/relevance/relevance_rails
181
245
  licenses: []
182
246
  post_install_message:
183
247
  rdoc_options: []
@@ -189,16 +253,27 @@ required_ruby_version: !ruby/object:Gem::Requirement
189
253
  - - ! '>='
190
254
  - !ruby/object:Gem::Version
191
255
  version: '0'
256
+ segments:
257
+ - 0
258
+ hash: 3573380774667230504
192
259
  required_rubygems_version: !ruby/object:Gem::Requirement
193
260
  none: false
194
261
  requirements:
195
262
  - - ! '>='
196
263
  - !ruby/object:Gem::Version
197
264
  version: '0'
265
+ segments:
266
+ - 0
267
+ hash: 3573380774667230504
198
268
  requirements: []
199
- rubyforge_project: relevance_rails
200
- rubygems_version: 1.8.21
269
+ rubyforge_project:
270
+ rubygems_version: 1.8.24
201
271
  signing_key:
202
272
  specification_version: 3
203
273
  summary: Rails 3 Relevance style, with all infrastructure bits automated away.
204
- test_files: []
274
+ test_files:
275
+ - spec/acceptance_spec.rb
276
+ - spec/elzar_recipes_spec.rb
277
+ - spec/lib/generators/provision_config/provision_config_generator_spec.rb
278
+ - spec/lib/relevance_rails/runner_spec.rb
279
+ - spec/spec_helper.rb
@@ -1,6 +0,0 @@
1
- {
2
- "id":"authorized_keys",
3
- "keys": [
4
- <%= authorized_keys.join(",\n") %>
5
- ]
6
- }
@@ -1,34 +0,0 @@
1
- module RelevanceRails::ChefDNA
2
- def self.gene_splice(json, database)
3
- set_ruby(json)
4
- set_database(json, database)
5
- end
6
-
7
- def self.set_database(json, database)
8
- if database == 'postgresql'
9
- db_index = json['run_list'].find_index { |e| e == 'mysql::server' || e == 'role[postgres_database]'}
10
- json['run_list'][db_index] = 'role[postgres_database]'
11
- elsif database.nil? || database == 'mysql'
12
- db_index = json['run_list'].find_index { |e| e == 'mysql::server' || e == 'role[postgres_database]'}
13
- json['run_list'][db_index] = 'mysql::server'
14
- end
15
- end
16
-
17
- def self.set_ruby(json)
18
- if RelevanceRails.ruby_version =~ /^ree-(.*)/i
19
- json['ruby_enterprise']['version'] = $1
20
- json['ruby_enterprise']['url'] = "http://rubyenterpriseedition.googlecode.com/files/ruby-enterprise-#{$1}"
21
- appstack_index = json['run_list'].find_index {|e| e[/^role\[.*_appstack\]$/] }
22
- json['run_list'][appstack_index] = 'role[enterprise_appstack]'
23
- elsif RelevanceRails.ruby_version =~ /^ruby-(.*)/i
24
- full_version = $1
25
- json['ruby']['version'] = full_version
26
- major_version = full_version[/(\d\.\d).*/, 1]
27
- json['ruby']['url'] = "http://ftp.ruby-lang.org/pub/ruby/#{major_version}/ruby-#{full_version}.tar.gz"
28
- appstack_index = json['run_list'].find_index {|e| e[/^role\[.*_appstack\]$/] }
29
- json['run_list'][appstack_index] = 'role[ruby_appstack]'
30
- else
31
- raise "Your ruby is NOT SUPPORTED. Please use ree or ruby."
32
- end
33
- end
34
- end
@@ -1,26 +0,0 @@
1
- require 'spec_helper'
2
- require 'generators/provision_config/provision_config_generator'
3
-
4
- describe ProvisionConfigGenerator do
5
- context '#check_authorized_keys' do
6
- subject { ProvisionConfigGenerator.new(['name']) }
7
-
8
- it "aborts if no ssh-keys are found" do
9
- subject.should_receive(:`).and_return do
10
- system('exit 1')
11
- # Actual message that comes back from failed call
12
- 'The agent has no entities'
13
- end
14
- RelevanceRails::PublicKeyFetcher.should_receive(:public_keys).and_return([])
15
-
16
- should_abort_with(/^No ssh keys were found!/) do
17
- subject.check_authorized_keys
18
- end
19
- end
20
-
21
- it "doesn't abort if ssh-keys are found" do
22
- subject.should_receive(:fetch_keys).and_return(['ssh-rsa ZZZZ'])
23
- expect { subject.check_authorized_keys }.to_not raise_error
24
- end
25
- end
26
- end
@@ -1,68 +0,0 @@
1
- require 'spec_helper'
2
- require 'relevance_rails/provision'
3
-
4
- describe RelevanceRails::Provision do
5
- def job(options={})
6
- options = {:stdout => '', :stderr => '', :status => 0}.update options
7
- mock(options)
8
- end
9
-
10
- describe '.run_commands' do
11
- it "fails fast if a command fails" do
12
- server = mock(:ssh => [job(:status => 1, :command => 'exit 1', :stderr => 'FAIL WHALE')])
13
- capture_stdout do
14
- expect do
15
- RelevanceRails::Provision.run_commands server
16
- end.to raise_error SystemExit
17
- end.should =~ /STDERR: FAIL WHALE/
18
- end
19
- end
20
-
21
- describe '.wait_for_ssh' do
22
-
23
- let(:server) { mock("server") }
24
-
25
- before do
26
- server.should_receive(:wait_for).ordered.and_return(true)
27
- end
28
-
29
- it 'retries if the first attempt fails' do
30
- server.should_receive(:ssh).ordered.and_raise(Errno::ECONNREFUSED)
31
- server.should_receive(:ssh).ordered.and_return([job(:command => 'echo')])
32
- RelevanceRails::Provision.should_receive(:sleep).twice.with(10).and_return(10)
33
- expect do
34
- capture_stdout { RelevanceRails::Provision.wait_for_ssh(server) }
35
- end.to_not raise_error
36
- end
37
-
38
- it 'retries up to five times, then fails' do
39
- server.should_receive(:ssh).ordered.exactly(5).times.and_raise(Errno::ECONNREFUSED)
40
- RelevanceRails::Provision.should_receive(:sleep).exactly(5).times.with(10).and_return(10)
41
- expect do
42
- capture_stdout { RelevanceRails::Provision.wait_for_ssh(server) }
43
- end.to raise_error SystemExit
44
- end
45
- end
46
-
47
- describe '.apt_installs' do
48
- it 'retries if the first attempt fails' do
49
- server = mock("server")
50
- server.should_receive(:ssh).ordered.with('sudo apt-get update').and_return([job(:command => 'sudo apt-get update')])
51
- server.should_receive(:ssh).ordered.with('sudo apt-get -y install ruby').and_return([job(:status => 1, :command => 'sudo apt-get -y install ruby')])
52
- server.should_receive(:ssh).ordered.with('sudo apt-get update').and_return([job(:command => 'sudo apt-get update')])
53
- server.should_receive(:ssh).ordered.with('sudo apt-get -y install ruby').and_return([job(:command => 'sudo apt-get -y install ruby')])
54
- server.should_receive(:ssh).ordered.with('sudo apt-get -y install rubygems1.8').and_return([job(:command => 'sudo apt-get -y install rubygems1.8')])
55
- expect do
56
- capture_stdout { RelevanceRails::Provision.apt_installs(server) }
57
- end.to_not raise_error
58
- end
59
-
60
- it 'tries twice, then fails' do
61
- server = mock("server")
62
- server.should_receive(:ssh).exactly(3).with('sudo apt-get update').and_return([job(:status => 1, :command => 'sudo apt-get update')])
63
- expect do
64
- capture_stdout { RelevanceRails::Provision.apt_installs(server) }
65
- end.to raise_error SystemExit
66
- end
67
- end
68
- end