dew 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -63,6 +63,28 @@ And perform a basic self-test:
63
63
 
64
64
  ## Creating a Simple Environment
65
65
 
66
+ Assuming that you've created (or downloaded) your `~/.dew` directory, you should be ready to create a simple environment.
67
+
68
+ First, take a look at `~/.dew/profiles/test-light.yaml`. `test-light` is the profile we'll be using to create our environment. You'll see that it contains:
69
+
70
+ * AMIs for each region
71
+ * two instances, using the 'default' keypair and the 'default' security group
72
+ * an elastic load balancer (elb) with a listener on port 80
73
+
74
+ If your keypair isn't called 'default', you'll need to edit this file and change it.
75
+
76
+ Now, run:
77
+
78
+ dew -v environments create test-light my-first-environment
79
+
80
+ You'll be shown a summary of the environment that you're about to create. Type 'y' to confirm its creation and watch as it's created.
81
+
82
+ Once complete you can run the following commands to interact with your environment:
83
+
84
+ dew environments ssh my-first-environment
85
+ dew environments show my-first-environment
86
+ dew environments destroy my-first-environment
87
+
66
88
  ## Creating an AMI for a new Environment
67
89
 
68
90
  ## Deploying to an Environment
@@ -7,7 +7,7 @@ instances:
7
7
  size: c1.medium
8
8
  count: 2
9
9
  security-group: default
10
- keypair: devops
10
+ keypair: default
11
11
  elb:
12
12
  listener_ports:
13
13
  - 80
@@ -25,7 +25,7 @@ instances:
25
25
  #security-groups:
26
26
  # - default
27
27
 
28
- keypair: devops
28
+ keypair: default
29
29
 
30
30
  elb:
31
31
  listener_ports:
@@ -84,18 +84,18 @@ end
84
84
  Then /^PUGE database environment variables should be set on each server to match the created RDS$/ do
85
85
  environment.servers.each do |server|
86
86
  ssh = server.ssh
87
- %w{PUGE_DB_NAME PUGE_DB_USERNAME PUGE_DB_PASSWORD}.each do |var|
87
+ %w{DB_NAME DB_USERNAME DB_PASSWORD}.each do |var|
88
88
  ssh.run("echo $#{var}").chomp.length.should_not == 0
89
89
  end
90
- ssh.run("echo $PUGE_DB_HOST").chomp.should == environment.database.public_address
90
+ ssh.run("echo $DB_HOST").chomp.should == environment.database.public_address
91
91
  end
92
92
  end
93
93
 
94
94
  Then /^I should be able to connect to the RDS$/ do
95
95
  environment.servers.each do |server|
96
96
  ssh = server.ssh
97
- #host.run("nc -w 1 $PUGE_DB_HOST 3306 > /dev/null 2>&1 ; echo $?").chomp.should == "0"
97
+ #host.run("nc -w 1 $DB_HOST 3306 > /dev/null 2>&1 ; echo $?").chomp.should == "0"
98
98
  ssh.run("sudo apt-get install -y mysql-client", :quiet_stderr => true)
99
- ssh.run("echo show databases | mysql -u$PUGE_DB_USERNAME -p$PUGE_DB_PASSWORD -h$PUGE_DB_HOST").chomp.length.should_not == 0
99
+ ssh.run("echo show databases | mysql -u$DB_USERNAME -p$DB_PASSWORD -h$DB_HOST").chomp.length.should_not == 0
100
100
  end
101
101
  end
@@ -16,14 +16,41 @@ class DeployCommand < Clamp::Command
16
16
  parameter "ENVIRONMENT_NAME", "Environment to deploy into"
17
17
 
18
18
  option ['--rails-env'], 'ENVIRONMENT', "Rails environment to use", :default => 'production'
19
+ option ['--server-name'], 'SERVER_NAME', "Server name for Name-Based Virtual Host"
20
+ option ['--ssl-certificate'], 'FILE', "SSL Certificate file"
21
+ option ['--ssl-private-key'], 'FILE', "SSL Private Key file"
22
+ option ['--[no-]passenger'], :flag, "Use passenger (just server public/* if unset)", :default => true, :attribute_name => :use_passenger
23
+
24
+ def check_and_remove_rvmrc
25
+ if ssh.exist? "#{application_name}/.rvmrc"
26
+ Inform.debug(".rvmrc discovered - removing to avoid Passenger conflicts")
27
+ # XXX We need a company-wide standard or a better way of supporting .rvmrc stuffs
28
+ ssh.run "rm -f #{application_name}/.rvmrc"
29
+ end
30
+ end
19
31
 
32
+ def use_ssl?
33
+ ssl_certificate || ssl_private_key
34
+ end
35
+
20
36
  def execute
37
+ if use_ssl?
38
+ raise "--server-name required if SSL credentials supplied" unless server_name
39
+ raise "--ssl-private-key required if SSL certificate supplied" unless ssl_private_key
40
+ raise "--ssl-private-key file #{ssl_private_key} does not exist" unless File.exist?(ssl_private_key)
41
+ raise "--ssl-certificate required if SSL private key supplied" unless ssl_certificate
42
+ raise "--ssl-certificate file #{ssl_certificate} does not exist" unless File.exist?(ssl_certificate)
43
+ end
44
+
21
45
  env = Environment.get(environment_name)
46
+
47
+ db_managed = false
48
+
22
49
  env.servers.each do |server|
23
50
  Inform.info("Working with server %{id} of %{l} servers", :id => server.id, :l => env.servers.length)
24
51
  env.remove_server_from_elb(server) if env.has_elb?
25
52
 
26
- ssh = server.ssh
53
+ @ssh = server.ssh
27
54
  initial = !ssh.exist?(application_name)
28
55
 
29
56
  Inform.info("%{app} doesn't exist - initial install", :app => application_name) if initial
@@ -34,17 +61,22 @@ class DeployCommand < Clamp::Command
34
61
 
35
62
  Inform.info("Obtaining version %{v} of %{app}", :v => revision, :app => application_name) do
36
63
  if initial
37
- Inform.debug("Writing out ~/.ssh/known_hosts file to allow github clone")
38
- ssh.upload template('known_hosts'), ".ssh/known_hosts"
64
+ unless ssh.exist?('.ssh/known_hosts') && ssh.read('.ssh/known_hosts').include?(File.read(template('known_hosts')))
65
+ Inform.debug("Writing out ~/.ssh/known_hosts file to allow github clone")
66
+ ssh.upload template('known_hosts'), ".ssh/known_hosts"
67
+ end
39
68
  Inform.debug("Cloning %{app} in to ~/%{app}", :app => application_name)
40
69
  ssh.run "git clone git@github.com:playup/#{application_name}.git #{application_name}"
41
70
  else
42
71
  Inform.debug("Updating %{app} repository", :app => application_name)
72
+ check_and_remove_rvmrc
43
73
  ssh.run "cd #{application_name}; git fetch -q"
44
74
  end
45
-
75
+
76
+ check_and_remove_rvmrc
46
77
  Inform.debug("Checking out version %{version}", :version => revision)
47
78
  ssh.run "cd #{application_name} && git checkout -q -f origin/#{revision}"
79
+ check_and_remove_rvmrc
48
80
  end
49
81
 
50
82
  cd_and_rvm = "cd #{application_name} && . /usr/local/rvm/scripts/rvm && rvm use ruby-1.9.2 && RAILS_ENV=#{rails_env} "
@@ -54,23 +86,48 @@ class DeployCommand < Clamp::Command
54
86
  end
55
87
 
56
88
  if ssh.exist?("#{application_name}/config/database.yml")
57
- Inform.info("config/database.yml exists, creating and/or updating database") do
58
- Inform.debug("Creating database") if initial
59
- ssh.run cd_and_rvm + "rake db:create" if initial
60
- Inform.debug("Updating database")
61
- ssh.run cd_and_rvm + "rake db:migrate"
89
+ if !db_managed
90
+ Inform.info("config/database.yml exists, creating and/or updating database") do
91
+ if initial
92
+ Inform.debug("Creating database")
93
+ ssh.run cd_and_rvm + "bundle exec rake db:create"
94
+ end
95
+ Inform.debug("Updating database")
96
+ ssh.run cd_and_rvm + "bundle exec rake db:migrate"
97
+ db_managed = true # don't do database steps more than once
98
+ end
62
99
  end
63
100
  else
64
101
  Inform.info("No config/database.yml, skipping database step")
65
102
  end
66
-
67
- Inform.info("Starting application with passenger") do
103
+
104
+ build_script = 'script/build'
105
+ if ssh.exist? application_name + '/' + build_script
106
+ Inform.info("Build script discovered at %{build_script}, running", :build_script => build_script) do
107
+ ssh.run cd_and_rvm + "bundle exec #{build_script}"
108
+ end
109
+ end
110
+
111
+ if use_ssl?
112
+ Inform.info "Uploading SSL Certificate & Private Key" do
113
+ ssh.run "sudo mkdir -p /etc/apache2/certs" unless ssh.exist?("/etc/apache2/certs")
114
+ ssh.upload ssl_certificate, "/tmp/sslcert"
115
+ ssh.run "sudo mv -f /tmp/sslcert /etc/apache2/certs/#{application_name}.crt"
116
+ ssh.upload ssl_private_key, "/tmp/sslkey"
117
+ ssh.run "sudo mv -f /tmp/sslkey /etc/apache2/certs/#{application_name}.key"
118
+ end
119
+ end
120
+
121
+ Inform.info("Starting application") do
68
122
  if ssh.exist?('/etc/apache2/sites-enabled/000-default')
69
123
  Inform.debug("Disabling default apache site")
70
124
  ssh.run "sudo a2dissite default"
71
125
  end
72
126
  Inform.debug("Uploading passenger config")
73
127
  passenger_config = ERB.new(File.read template('apache.conf.erb')).result(OpenStruct.new(
128
+ :use_passenger? => use_passenger?,
129
+ :use_ssl? => use_ssl?,
130
+ :server_name => server_name,
74
131
  :rails_env => rails_env,
75
132
  :application_name => application_name,
76
133
  :working_directory => "/home/ubuntu/#{application_name}"
@@ -79,23 +136,33 @@ class DeployCommand < Clamp::Command
79
136
  ssh.run "sudo cp /tmp/apache.conf /etc/apache2/sites-available/#{application_name}"
80
137
  ssh.run "sudo chmod 0644 /etc/apache2/sites-available/#{application_name}" # yeah, I don't know why it gets written as 0600
81
138
  unless ssh.exist?('/etc/apache2/sites-enabled/#{application_name}')
82
- Inform.debug("Enabling passenger site in apache")
139
+ Inform.debug("Enabling site in apache")
83
140
  ssh.run "sudo a2ensite #{application_name}"
84
141
  end
85
142
  Inform.debug("Restarting apache")
86
143
  ssh.run "sudo apache2ctl restart"
87
144
  end
88
145
 
89
- status_url = "http://#{server.public_ip_address}/status"
90
- Inform.info("Checking status URL at %{u}", :u => status_url) do
91
- response = JSON.parse(open(status_url).read)
92
- unless response.include?('status') && response['status'] == 'OK'
93
- raise "Did not receive an OK status response."
146
+ unless server_name || !use_passenger?
147
+ status_url = "http://#{server.public_ip_address}/status"
148
+ Inform.info("Checking status URL at %{u}", :u => status_url) do
149
+ response = JSON.parse(open(status_url).read)
150
+ unless response.include?('status') && response['status'] == 'OK'
151
+ raise "Did not receive an OK status response."
152
+ end
94
153
  end
154
+ else
155
+ Inform.warning "Skipping health check as we don't yet support forcing server_name on HTTP"
95
156
  end
96
157
  env.add_server_to_elb(server) if env.has_elb?
97
158
  end
98
159
  end
160
+
161
+ private
162
+
163
+ def ssh
164
+ @ssh
165
+ end
99
166
 
100
167
  end
101
168
 
@@ -1,12 +1,65 @@
1
1
  <VirtualHost *:80>
2
2
  ServerAdmin admin@playup.com
3
3
 
4
- PassEnv PUGE_DB_HOST PUGE_DB_NAME PUGE_DB_USERNAME PUGE_DB_PASSWORD
4
+ <% if server_name %>
5
+ ServerName <%= server_name %>
6
+ <% end %>
5
7
 
6
- PassengerFriendlyErrorPages off
7
- PassengerMaxRequests 50
8
+ <% if use_passenger? %>
9
+ PassEnv DB_HOST DB_NAME DB_USERNAME DB_PASSWORD
8
10
 
9
- RailsEnv <%= rails_env %>
11
+ PassengerFriendlyErrorPages off
12
+ PassengerMaxRequests 50
13
+
14
+ RailsEnv <%= rails_env %>
15
+ <% if server_name %>
16
+ PassengerPreStart http://<%= server_name %>/status
17
+ <% else %>
18
+ PassengerPreStart http://localhost/status
19
+ <% end %>
20
+ <% end %>
21
+
22
+ DocumentRoot <%= working_directory %>/public
23
+ <Directory <%= working_directory %>/public>
24
+ allow from all
25
+ Options -MultiViews
26
+ AllowOverride None
27
+ Order allow,deny
28
+ </Directory>
29
+
30
+ ErrorLog /var/log/apache2/<%= application_name %>-error.log
31
+
32
+ # Possible values include: debug, info, notice, warn, error, crit,
33
+ # alert, emerg.
34
+ LogLevel warn
35
+
36
+ CustomLog /var/log/apache2/<%= application_name %>-access.log combined
37
+ </VirtualHost>
38
+ <% if use_ssl? %>
39
+ <VirtualHost *:443>
40
+ ServerAdmin admin@playup.com
41
+
42
+ <% if server_name %>
43
+ ServerName <%= server_name %>
44
+ <% end %>
45
+
46
+ <% if use_passenger? %>
47
+ PassEnv DB_HOST DB_NAME DB_USERNAME DB_PASSWORD
48
+
49
+ PassengerFriendlyErrorPages off
50
+ PassengerMaxRequests 50
51
+
52
+ RailsEnv <%= rails_env %>
53
+ <% if server_name %>
54
+ PassengerPreStart http://<%= server_name %>/status
55
+ <% else %>
56
+ PassengerPreStart http://localhost/status
57
+ <% end %>
58
+ <% end %>
59
+
60
+ SSLEngine On
61
+ SSLCertificateFile /etc/apache2/certs/<%= application_name %>.crt
62
+ SSLCertificateKeyFile /etc/apache2/certs/<%= application_name %>.key
10
63
 
11
64
  DocumentRoot <%= working_directory %>/public
12
65
  <Directory <%= working_directory %>/public>
@@ -24,5 +77,6 @@
24
77
 
25
78
  CustomLog /var/log/apache2/<%= application_name %>-access.log combined
26
79
 
27
- PassengerPreStart http://localhost/status
28
80
  </VirtualHost>
81
+ <% end %>
82
+
@@ -22,10 +22,10 @@ class Database < FogModel
22
22
 
23
23
  def db_environment_file password
24
24
  <<-EOF
25
- PUGE_DB_HOST=#{fog_object.endpoint['Address']}
26
- PUGE_DB_NAME=#{id}
27
- PUGE_DB_USERNAME=#{master_username}
28
- PUGE_DB_PASSWORD=#{password}
25
+ DB_HOST=#{fog_object.endpoint['Address']}
26
+ DB_NAME=#{id}
27
+ DB_USERNAME=#{master_username}
28
+ DB_PASSWORD=#{password}
29
29
  EOF
30
30
  end
31
31
 
data/lib/dew/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Dew
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
@@ -44,10 +44,10 @@ describe Database do
44
44
  describe "db_environment_file" do
45
45
  it "should return the contents of a file to use as /etc/environment that can be used to connct to this database" do
46
46
  data = @database.db_environment_file('password')
47
- data.should =~ /PUGE_DB_NAME=#{id}/
48
- data.should =~ /PUGE_DB_USERNAME=root/
49
- data.should =~ /PUGE_DB_PASSWORD=password/
50
- data.should =~ /PUGE_DB_HOST=127.0.0.1/
47
+ data.should =~ /DB_NAME=#{id}/
48
+ data.should =~ /DB_USERNAME=root/
49
+ data.should =~ /DB_PASSWORD=password/
50
+ data.should =~ /DB_HOST=127.0.0.1/
51
51
  end
52
52
  end
53
53
  describe :public_address do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dew
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 29
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 2
10
- version: 0.1.2
9
+ - 3
10
+ version: 0.1.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - PlayUp Devops
@@ -15,12 +15,12 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-06-29 00:00:00 Z
18
+ date: 2011-07-05 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: inform
22
22
  prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
23
+ version_requirements: &id001 !ruby/object:Gem::Requirement
24
24
  none: false
25
25
  requirements:
26
26
  - - ~>
@@ -32,11 +32,11 @@ dependencies:
32
32
  - 4
33
33
  version: 0.0.4
34
34
  type: :runtime
35
- version_requirements: *id001
35
+ requirement: *id001
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: clamp
38
38
  prerelease: false
39
- requirement: &id002 !ruby/object:Gem::Requirement
39
+ version_requirements: &id002 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ~>
@@ -48,11 +48,11 @@ dependencies:
48
48
  - 0
49
49
  version: 0.2.0
50
50
  type: :runtime
51
- version_requirements: *id002
51
+ requirement: *id002
52
52
  - !ruby/object:Gem::Dependency
53
53
  name: fog
54
54
  prerelease: false
55
- requirement: &id003 !ruby/object:Gem::Requirement
55
+ version_requirements: &id003 !ruby/object:Gem::Requirement
56
56
  none: false
57
57
  requirements:
58
58
  - - ~>
@@ -64,11 +64,11 @@ dependencies:
64
64
  - 2
65
65
  version: 0.8.2
66
66
  type: :runtime
67
- version_requirements: *id003
67
+ requirement: *id003
68
68
  - !ruby/object:Gem::Dependency
69
69
  name: gofer
70
70
  prerelease: false
71
- requirement: &id004 !ruby/object:Gem::Requirement
71
+ version_requirements: &id004 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -80,11 +80,11 @@ dependencies:
80
80
  - 5
81
81
  version: 0.2.5
82
82
  type: :runtime
83
- version_requirements: *id004
83
+ requirement: *id004
84
84
  - !ruby/object:Gem::Dependency
85
85
  name: highline
86
86
  prerelease: false
87
- requirement: &id005 !ruby/object:Gem::Requirement
87
+ version_requirements: &id005 !ruby/object:Gem::Requirement
88
88
  none: false
89
89
  requirements:
90
90
  - - ~>
@@ -96,11 +96,11 @@ dependencies:
96
96
  - 2
97
97
  version: 1.6.2
98
98
  type: :runtime
99
- version_requirements: *id005
99
+ requirement: *id005
100
100
  - !ruby/object:Gem::Dependency
101
101
  name: terminal-table
102
102
  prerelease: false
103
- requirement: &id006 !ruby/object:Gem::Requirement
103
+ version_requirements: &id006 !ruby/object:Gem::Requirement
104
104
  none: false
105
105
  requirements:
106
106
  - - ~>
@@ -112,11 +112,11 @@ dependencies:
112
112
  - 2
113
113
  version: 1.4.2
114
114
  type: :runtime
115
- version_requirements: *id006
115
+ requirement: *id006
116
116
  - !ruby/object:Gem::Dependency
117
117
  name: nokogiri
118
118
  prerelease: false
119
- requirement: &id007 !ruby/object:Gem::Requirement
119
+ version_requirements: &id007 !ruby/object:Gem::Requirement
120
120
  none: false
121
121
  requirements:
122
122
  - - ">="
@@ -126,11 +126,11 @@ dependencies:
126
126
  - 0
127
127
  version: "0"
128
128
  type: :runtime
129
- version_requirements: *id007
129
+ requirement: *id007
130
130
  - !ruby/object:Gem::Dependency
131
131
  name: rake
132
132
  prerelease: false
133
- requirement: &id008 !ruby/object:Gem::Requirement
133
+ version_requirements: &id008 !ruby/object:Gem::Requirement
134
134
  none: false
135
135
  requirements:
136
136
  - - ~>
@@ -142,11 +142,11 @@ dependencies:
142
142
  - 7
143
143
  version: 0.8.7
144
144
  type: :development
145
- version_requirements: *id008
145
+ requirement: *id008
146
146
  - !ruby/object:Gem::Dependency
147
147
  name: rspec
148
148
  prerelease: false
149
- requirement: &id009 !ruby/object:Gem::Requirement
149
+ version_requirements: &id009 !ruby/object:Gem::Requirement
150
150
  none: false
151
151
  requirements:
152
152
  - - ~>
@@ -158,11 +158,11 @@ dependencies:
158
158
  - 0
159
159
  version: 2.6.0
160
160
  type: :development
161
- version_requirements: *id009
161
+ requirement: *id009
162
162
  - !ruby/object:Gem::Dependency
163
163
  name: cucumber
164
164
  prerelease: false
165
- requirement: &id010 !ruby/object:Gem::Requirement
165
+ version_requirements: &id010 !ruby/object:Gem::Requirement
166
166
  none: false
167
167
  requirements:
168
168
  - - ~>
@@ -174,11 +174,11 @@ dependencies:
174
174
  - 3
175
175
  version: 0.10.3
176
176
  type: :development
177
- version_requirements: *id010
177
+ requirement: *id010
178
178
  - !ruby/object:Gem::Dependency
179
179
  name: simplecov
180
180
  prerelease: false
181
- requirement: &id011 !ruby/object:Gem::Requirement
181
+ version_requirements: &id011 !ruby/object:Gem::Requirement
182
182
  none: false
183
183
  requirements:
184
184
  - - ~>
@@ -190,11 +190,11 @@ dependencies:
190
190
  - 0
191
191
  version: 0.4.0
192
192
  type: :development
193
- version_requirements: *id011
193
+ requirement: *id011
194
194
  - !ruby/object:Gem::Dependency
195
195
  name: flay
196
196
  prerelease: false
197
- requirement: &id012 !ruby/object:Gem::Requirement
197
+ version_requirements: &id012 !ruby/object:Gem::Requirement
198
198
  none: false
199
199
  requirements:
200
200
  - - ~>
@@ -206,11 +206,11 @@ dependencies:
206
206
  - 2
207
207
  version: 1.4.2
208
208
  type: :development
209
- version_requirements: *id012
209
+ requirement: *id012
210
210
  - !ruby/object:Gem::Dependency
211
211
  name: geminabox
212
212
  prerelease: false
213
- requirement: &id013 !ruby/object:Gem::Requirement
213
+ version_requirements: &id013 !ruby/object:Gem::Requirement
214
214
  none: false
215
215
  requirements:
216
216
  - - ">="
@@ -220,7 +220,7 @@ dependencies:
220
220
  - 0
221
221
  version: "0"
222
222
  type: :development
223
- version_requirements: *id013
223
+ requirement: *id013
224
224
  description: |
225
225
  Dew is a layer between fog and the ground
226
226