engineyard 2.0.0.rc1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +160 -154
- data/lib/engineyard/cli.rb +19 -7
- data/lib/engineyard/cli/api.rb +67 -44
- data/lib/engineyard/cli/recipes.rb +1 -1
- data/lib/engineyard/cli/web.rb +31 -0
- data/lib/engineyard/commands/deploy.rb +4 -4
- data/lib/engineyard/config.rb +1 -1
- data/lib/engineyard/deploy_config/migrate.rb +4 -7
- data/lib/engineyard/eyrc.rb +2 -6
- data/lib/engineyard/serverside_runner.rb +24 -4
- data/lib/engineyard/thor.rb +2 -2
- data/lib/engineyard/version.rb +1 -1
- data/spec/engineyard/config_spec.rb +1 -1
- data/spec/engineyard/eyrc_spec.rb +1 -1
- data/spec/ey/web/restart_spec.rb +21 -0
- data/spec/spec_helper.rb +0 -4
- data/spec/support/helpers.rb +1 -1
- metadata +42 -19
data/README.rdoc
CHANGED
@@ -10,7 +10,7 @@ Note: Don't add engineyard to your application's Gemfile. The engineyard gem is
|
|
10
10
|
|
11
11
|
== Login
|
12
12
|
|
13
|
-
The first command you run will notice that you are not logged in and will ask you for your
|
13
|
+
The first command you run will notice that you are not logged in and will ask you for your Engine Yard email and password.
|
14
14
|
|
15
15
|
== Configuration
|
16
16
|
|
@@ -27,7 +27,6 @@ The ey.yml file allows options to be saved for each environment to which an appl
|
|
27
27
|
bundle_without: test development mygroup # exclude groups on bundle install
|
28
28
|
copy_exclude: # don't rsync the following dirs
|
29
29
|
- .git
|
30
|
-
verbose: true # always run verbose deploy (unless overriden on command line)
|
31
30
|
maintenance_on_restart: false # show maintenance page during app restart (default: false except for glassfish and mongrel)
|
32
31
|
maintenance_on_migrate: false # show maintenance page during migrations (default: true)
|
33
32
|
precompile_assets: true # enables rails assets precompilation (default: inferred using app/assets and config/application.rb)
|
@@ -37,193 +36,199 @@ Many of the options in ey.yml will only work if the file is committed to your ap
|
|
37
36
|
|
38
37
|
== Commands
|
39
38
|
|
40
|
-
|
41
|
-
ey deploy
|
39
|
+
=== ey deploy
|
42
40
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
-m, [--migrate=MIGRATE] # Run migrations via [MIGRATE], defaults to 'rake db:migrate'; use --no-migrate to avoid running migrations
|
49
|
-
-v, [--verbose] # Be verbose
|
50
|
-
[--ignore-default-branch] # Force a deploy of the specified branch even if a default is set
|
51
|
-
[--ignore-bad-master] # Force a deploy even if the master is in a bad state
|
52
|
-
[--extra-deploy-hook-options key:val] # Additional options to be made available in deploy hooks (in the 'config' hash)
|
53
|
-
# Add more keys as follows: --extra-deploy-hook-options key1:val1 key2:val2
|
41
|
+
This command must be run within the current directory containing the app to be
|
42
|
+
deployed. If ey.yml specifies a default branch then the ref parameter can be
|
43
|
+
omitted. Furthermore, if a default branch is specified but a different
|
44
|
+
command is supplied the deploy will fail unless --ignore-default-branch
|
45
|
+
is used.
|
54
46
|
|
47
|
+
If ey.yml does not specify a default migrate choice, you will be prompted to
|
48
|
+
specify a migration choice. A different command can later be specified via
|
49
|
+
--migrate "ruby do_migrations.rb". Migrations can also be skipped entirely
|
50
|
+
by using --no-migrate.
|
55
51
|
|
56
|
-
|
57
|
-
This command must be run within the current directory containing the app to be
|
58
|
-
deployed. If ey.yml specifies a default branch then the ref parameter can be
|
59
|
-
omitted. Furthermore, if a default branch is specified but a different
|
60
|
-
command is supplied the deploy will fail unless --ignore-default-branch
|
61
|
-
is used.
|
52
|
+
Options:
|
62
53
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
54
|
+
-r, [--ref=REF] [--branch=] [--tag=] # Git ref to deploy. May be a branch, a tag, or a SHA.
|
55
|
+
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
56
|
+
-a, [--app=APP] # Name of the application to deploy
|
57
|
+
-e, [--environment=ENVIRONMENT] # Environment in which to deploy this application
|
58
|
+
-m, [--migrate=MIGRATE] # Run migrations via [MIGRATE], defaults to 'rake db:migrate'; use --no-migrate to avoid running migrations
|
59
|
+
-v, [--verbose] # Be verbose
|
60
|
+
[--ignore-default-branch] # Force a deploy of the specified branch even if a default is set
|
61
|
+
[--ignore-bad-master] # Force a deploy even if the master is in a bad state
|
62
|
+
[--extra-deploy-hook-options key:val] # Additional options to be made available in deploy hooks (in the 'config' hash)
|
63
|
+
# Add more keys as follows: --extra-deploy-hook-options key1:val1 key2:val2
|
67
64
|
|
68
|
-
Command:
|
69
|
-
ey environments
|
70
65
|
|
71
|
-
|
72
|
-
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
73
|
-
-a, [--app=APP] # Name of the application containing the environments
|
74
|
-
-e, [--environment=ENVIRONMENT] # Show only environments matching named environment
|
75
|
-
-s, [--simple] # Print each environment name on its own on a new line
|
76
|
-
-a, [--all] # Show all environments, not just ones associated with this application.
|
66
|
+
=== ey status
|
77
67
|
|
78
|
-
|
79
|
-
By default, environments for this app are displayed. The --all option will display all environments, including those for this app.
|
68
|
+
Show the status of most recent deployment of the specified application and environment. This action only informational and will not change your application.
|
80
69
|
|
81
|
-
|
82
|
-
ey logs
|
70
|
+
Options:
|
83
71
|
|
84
|
-
|
85
|
-
|
86
|
-
|
72
|
+
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
73
|
+
-a, [--app=APP] # Name of the application containing the environment
|
74
|
+
-e, [--environment=ENVIRONMENT] # Name of the environment with the desired deployment
|
87
75
|
|
88
|
-
|
89
|
-
Displays Engine Yard configuration logs for all servers in the environment. If recipes were uploaded to the environment & run, their logs will also be displayed beneath the
|
90
|
-
main configuration logs.
|
76
|
+
=== ey environments
|
91
77
|
|
92
|
-
|
93
|
-
ey rebuild
|
94
|
-
|
95
|
-
Options:
|
96
|
-
-e, [--environment=ENVIRONMENT] # Environment to rebuild
|
97
|
-
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
78
|
+
By default, environments for this app are displayed. The --all option will display all environments, including those for this app.
|
98
79
|
|
99
|
-
|
100
|
-
Engine Yard's main configuration run occurs on all servers. Mainly used to fix failed configuration of new or existing servers, or to update servers to latest Engine Yard stack
|
101
|
-
(e.g. to apply an Engine Yard supplied security patch).
|
80
|
+
Options:
|
102
81
|
|
103
|
-
|
82
|
+
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
83
|
+
-a, [--app=APP] # Name of the application containing the environments
|
84
|
+
-e, [--environment=ENVIRONMENT] # Show only environments matching named environment
|
85
|
+
-s, [--simple] # Print each environment name on its own on a new line
|
86
|
+
-a, [--all] # Show all environments, not just ones associated with this application.
|
104
87
|
|
105
|
-
Command:
|
106
|
-
ey rollback
|
107
88
|
|
108
|
-
|
109
|
-
-v, [--verbose] # Be verbose
|
110
|
-
-a, [--app=APP] # Name of the application to roll back
|
111
|
-
-e, [--environment=ENVIRONMENT] # Environment in which to roll back the application
|
112
|
-
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
89
|
+
=== ey logs
|
113
90
|
|
114
|
-
|
115
|
-
Uses code from previous deploy in the "/data/APP_NAME/releases" directory on remote server(s) to restart application servers.
|
91
|
+
Displays Engine Yard configuration logs for all servers in the environment. If recipes were uploaded to the environment & run, their logs will also be displayed beneath the main configuration logs.
|
116
92
|
|
117
|
-
|
118
|
-
ey recipes apply
|
93
|
+
Options:
|
119
94
|
|
120
|
-
|
121
|
-
|
122
|
-
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
95
|
+
-e, [--environment=ENVIRONMENT] # Environment with the interesting logs
|
96
|
+
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
123
97
|
|
124
|
-
|
125
|
-
This is similar to 'ey rebuild' except Engine Yard's main configuration step is skipped.
|
98
|
+
=== ey rebuild
|
126
99
|
|
127
|
-
|
128
|
-
|
100
|
+
Engine Yard's main configuration run occurs on all servers. Mainly used to fix failed configuration of new or existing servers, or to update servers to latest Engine Yard stack
|
101
|
+
(e.g. to apply an Engine Yard supplied security patch).
|
129
102
|
|
130
|
-
|
131
|
-
-e, [--environment=ENVIRONMENT] # Environment that will receive the recipes
|
132
|
-
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
103
|
+
Note that uploaded recipes are also run after the main configuration run has successfully completed.
|
133
104
|
|
134
|
-
|
135
|
-
The current directory should contain a subdirectory named "cookbooks" to be uploaded.
|
105
|
+
Options:
|
136
106
|
|
137
|
-
|
138
|
-
|
107
|
+
-e, [--environment=ENVIRONMENT] # Environment to rebuild
|
108
|
+
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
139
109
|
|
140
|
-
|
141
|
-
-e, [--environment=ENVIRONMENT] # Environment for which to download the recipes
|
142
|
-
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
110
|
+
=== ey rollback
|
143
111
|
|
144
|
-
|
145
|
-
The recipes will be unpacked into a directory called "cookbooks" in the current directory.
|
112
|
+
Uses code from previous deploy in the "/data/APP_NAME/releases" directory on remote server(s) to restart application servers.
|
146
113
|
|
147
|
-
|
114
|
+
Options:
|
148
115
|
|
149
|
-
|
150
|
-
|
116
|
+
-v, [--verbose] # Be verbose
|
117
|
+
-a, [--app=APP] # Name of the application to roll back
|
118
|
+
-e, [--environment=ENVIRONMENT] # Environment in which to roll back the application
|
119
|
+
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
151
120
|
|
152
|
-
|
153
|
-
-v, [--verbose] # Be verbose
|
154
|
-
-a, [--app=APP] # Name of the application whose maintenance page will be removed
|
155
|
-
-e, [--environment=ENVIRONMENT] # Environment on which to take down the maintenance page
|
156
|
-
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
121
|
+
=== ey recipes apply
|
157
122
|
|
158
|
-
|
123
|
+
This is similar to 'ey rebuild' except Engine Yard's main configuration step is skipped.
|
159
124
|
|
160
|
-
|
161
|
-
ey web disable
|
125
|
+
Options:
|
162
126
|
|
163
|
-
|
164
|
-
|
165
|
-
-a, [--app=APP] # Name of the application whose maintenance page will be put up
|
166
|
-
-e, [--environment=ENVIRONMENT] # Environment on which to put up the maintenance page
|
167
|
-
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
127
|
+
-e, [--environment=ENVIRONMENT] # Environment in which to apply recipes
|
128
|
+
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
168
129
|
|
169
|
-
|
170
|
-
The maintenance page is taken from the app currently being deployed. This means that you can customize maintenance pages to tell users the reason for downtime on every
|
171
|
-
particular deploy.
|
130
|
+
=== ey recipes upload
|
172
131
|
|
173
|
-
|
174
|
-
* public/maintenance.html.custom
|
175
|
-
* public/maintenance.html.tmp
|
176
|
-
* public/maintenance.html
|
177
|
-
* public/system/maintenance.html.default
|
132
|
+
The current directory should contain a subdirectory named "cookbooks" to be uploaded.
|
178
133
|
|
179
|
-
|
180
|
-
ey ssh
|
134
|
+
Options:
|
181
135
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
[--db-master] # Run command on the master database server
|
187
|
-
-a, [--all] # Run command on all servers
|
188
|
-
[--db-slaves] # Run command on the slave database servers
|
189
|
-
-e, [--environment=ENVIRONMENT] # Environment to ssh into
|
190
|
-
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
136
|
+
-e, [--environment=ENVIRONMENT] # Environment that will receive the recipes
|
137
|
+
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
138
|
+
[--apply] # Apply the recipes (same as above) immediately after uploading
|
139
|
+
-f, [--file=FILE] # Specify a gzipped tar file (.tgz) for upload instead of cookbooks/ directory
|
191
140
|
|
192
|
-
|
193
|
-
If a command is supplied, it will be run, otherwise a session will be opened. The application master is used for environments with clusters. Option --all requires a command to
|
194
|
-
be supplied and runs it on all servers.
|
141
|
+
=== ey recipes download
|
195
142
|
|
196
|
-
|
143
|
+
The recipes will be unpacked into a directory called "cookbooks" in the current directory.
|
197
144
|
|
198
|
-
|
145
|
+
If the cookbooks directory already exists, an error will be raised.
|
199
146
|
|
200
|
-
|
201
|
-
ey launch
|
147
|
+
Options:
|
202
148
|
|
203
|
-
|
204
|
-
|
205
|
-
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
149
|
+
-e, [--environment=ENVIRONMENT] # Environment for which to download the recipes
|
150
|
+
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
206
151
|
|
207
|
-
|
208
|
-
Open the application in a browser.
|
152
|
+
=== ey web enable
|
209
153
|
|
210
|
-
|
211
|
-
ey whoami
|
154
|
+
Remove the maintenance page for this application in the given environment.
|
212
155
|
|
213
|
-
|
214
|
-
Who am I logged in as?
|
156
|
+
Options:
|
215
157
|
|
216
|
-
|
217
|
-
|
158
|
+
-v, [--verbose] # Be verbose
|
159
|
+
-a, [--app=APP] # Name of the application whose maintenance page will be removed
|
160
|
+
-e, [--environment=ENVIRONMENT] # Environment on which to take down the maintenance page
|
161
|
+
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
218
162
|
|
219
|
-
|
220
|
-
Log in and verify access to EY Cloud. Use logout first if you need to switch user accounts.
|
163
|
+
=== ey web disable
|
221
164
|
|
222
|
-
|
223
|
-
ey logout
|
165
|
+
The maintenance page is taken from the app currently being deployed. This means that you can customize maintenance pages to tell users the reason for downtime on every particular deploy.
|
224
166
|
|
225
|
-
|
226
|
-
|
167
|
+
Maintenance pages searched for in order of decreasing priority:
|
168
|
+
* public/maintenance.html.custom
|
169
|
+
* public/maintenance.html.tmp
|
170
|
+
* public/maintenance.html
|
171
|
+
* public/system/maintenance.html.default
|
172
|
+
|
173
|
+
Options:
|
174
|
+
|
175
|
+
-v, [--verbose] # Be verbose
|
176
|
+
-a, [--app=APP] # Name of the application whose maintenance page will be put up
|
177
|
+
-e, [--environment=ENVIRONMENT] # Environment on which to put up the maintenance page
|
178
|
+
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
179
|
+
|
180
|
+
|
181
|
+
=== ey web restart
|
182
|
+
|
183
|
+
Restarts the application servers for the given application. Enables maintenance pages if it would be enabled during a normal deploy. Respects the maintenance_on_restart ey.yml configuration.
|
184
|
+
|
185
|
+
Options:
|
186
|
+
|
187
|
+
-v, [--verbose] # Be verbose
|
188
|
+
-a, [--app=APP] # Name of the application to restart
|
189
|
+
-e, [--environment=ENVIRONMENT] # Name of the environment to restart
|
190
|
+
-c, [--account=ACCOUNT] # Name of the account in which the app and environment can be found
|
191
|
+
|
192
|
+
=== ey ssh
|
193
|
+
|
194
|
+
If a command is supplied, it will be run, otherwise a session will be opened. The application master is used for environments with clusters. Option --all requires a command to be supplied and runs it on all servers.
|
195
|
+
|
196
|
+
Note: this command is a bit picky about its ordering. To run a command with arguments on all servers, like "rm -f /some/file", you need to order it like so:
|
197
|
+
|
198
|
+
$ ey ssh "rm -f /some/file" -e my-environment --all
|
199
|
+
|
200
|
+
Options:
|
201
|
+
|
202
|
+
[--utilities=one two three] # Run command on the utility servers with the given names. If no names are given, run on all utility servers.
|
203
|
+
[--app-servers] # Run command on all application servers
|
204
|
+
[--db-servers] # Run command on the database servers
|
205
|
+
[--db-master] # Run command on the master database server
|
206
|
+
-A, [--all] # Run command on all servers
|
207
|
+
[--db-slaves] # Run command on the slave database servers
|
208
|
+
-e, [--environment=ENVIRONMENT] # Name of the environment to ssh into
|
209
|
+
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
210
|
+
|
211
|
+
=== ey launch
|
212
|
+
|
213
|
+
Open the application in a browser.
|
214
|
+
|
215
|
+
Options:
|
216
|
+
|
217
|
+
-c, [--account=ACCOUNT] # Name of the account in which the environment can be found
|
218
|
+
-a, [--app=APP] # Name of the application to launch
|
219
|
+
-e, [--environment=ENVIRONMENT] # Name of the environment for the application
|
220
|
+
|
221
|
+
=== ey whoami
|
222
|
+
|
223
|
+
Who am I logged in as? Prints the name and email of the current logged in user.
|
224
|
+
|
225
|
+
=== ey login
|
226
|
+
|
227
|
+
Log in and verify access to EY Cloud. Use logout first if you need to switch user accounts.
|
228
|
+
|
229
|
+
=== ey logout
|
230
|
+
|
231
|
+
Remove the current API key from ~/.eyrc or env variable $EYRC
|
227
232
|
|
228
233
|
|
229
234
|
== API Client
|
@@ -234,15 +239,16 @@ See https://github.com/engineyard/engineyard-cloud-client for the API client lib
|
|
234
239
|
|
235
240
|
The API commands will print internal information if $DEBUG is set:
|
236
241
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
242
|
+
$ DEBUG=1 ey environments --all
|
243
|
+
GET https://cloud.engineyard.com/api/v2/apps
|
244
|
+
Params {"no_instances"=>"true"}
|
245
|
+
Headers {"User-Agent"=>"EngineYard/2.0.0 EngineYardCloudClient/1.0.5",
|
246
|
+
"Accept"=>"application/json",
|
247
|
+
"X-EY-Cloud-Token"=>"YOURTOKEN"}
|
248
|
+
Response {"apps"=>
|
249
|
+
[{"environments"=>[],
|
250
|
+
"name"=>"myapp",
|
251
|
+
"repository_uri"=>"git@github.com:myaccount/myapp.git",
|
252
|
+
"app_type_id"=>"rails3",
|
253
|
+
"account"=>{"name"=>"myaccount", "id"=>1234},
|
254
|
+
"id"=>12345}]}
|
data/lib/engineyard/cli.rb
CHANGED
@@ -107,8 +107,8 @@ module EY
|
|
107
107
|
deployment.successful = runner.call(out, err)
|
108
108
|
rescue Interrupt
|
109
109
|
err << "Interrupted. Deployment halted.\n"
|
110
|
-
ui.warn "Recording canceled deployment in
|
111
|
-
ui.warn "WARNING: Interrupting again may result in a never-finished deployment in the deployment history on
|
110
|
+
ui.warn "Recording canceled deployment in Engine Yard Cloud..."
|
111
|
+
ui.warn "WARNING: Interrupting again may result in a never-finished deployment in the deployment history on Engine Yard Cloud."
|
112
112
|
raise
|
113
113
|
rescue StandardError => e
|
114
114
|
deployment.err << "Error encountered during deploy.\n#{e.class} #{e}\n"
|
@@ -118,11 +118,11 @@ module EY
|
|
118
118
|
deployment.finished
|
119
119
|
|
120
120
|
if deployment.successful?
|
121
|
-
ui.info "Successful deployment recorded on
|
121
|
+
ui.info "Successful deployment recorded on Engine Yard Cloud"
|
122
122
|
ui.info "Deploy complete"
|
123
123
|
ui.info "Now you can run `ey launch' to open the application in a browser."
|
124
124
|
else
|
125
|
-
ui.info "Failed deployment recorded on
|
125
|
+
ui.info "Failed deployment recorded on Engine Yard Cloud"
|
126
126
|
raise EY::Error, "Deploy failed"
|
127
127
|
end
|
128
128
|
end
|
@@ -204,7 +204,7 @@ module EY
|
|
204
204
|
|
205
205
|
if options[:simple]
|
206
206
|
if apps.size > 1
|
207
|
-
message = "# This app matches multiple Applications in
|
207
|
+
message = "# This app matches multiple Applications in Engine Yard Cloud:\n"
|
208
208
|
apps.each { |app| message << "#\t#{app.name}\n" }
|
209
209
|
message << "# The following environments contain those applications:\n\n"
|
210
210
|
ui.warn(message)
|
@@ -296,7 +296,7 @@ module EY
|
|
296
296
|
method_option :account, :type => :string, :aliases => %w(-c),
|
297
297
|
:required => true, :default => '',
|
298
298
|
:desc => "Name of the account in which the environment can be found"
|
299
|
-
method_option :all, :type => :boolean, :aliases => %(-
|
299
|
+
method_option :all, :type => :boolean, :aliases => %(-A),
|
300
300
|
:desc => "Run command on all servers"
|
301
301
|
method_option :app_servers, :type => :boolean,
|
302
302
|
:desc => "Run command on all application servers"
|
@@ -457,7 +457,19 @@ module EY
|
|
457
457
|
ui.say "#{current_user.name} (#{current_user.email})"
|
458
458
|
end
|
459
459
|
|
460
|
-
desc "login", "Log in and verify access to
|
460
|
+
desc "login", "Log in and verify access to Engine Yard Cloud."
|
461
|
+
long_desc <<-DESC
|
462
|
+
You may run this command to log in to EY Cloud without performing
|
463
|
+
any other action.
|
464
|
+
|
465
|
+
Once you are logged in, a file will be stored at ~/.eyrc with your
|
466
|
+
API token. You may override the location of this file using the
|
467
|
+
$EYRC environment variable.
|
468
|
+
|
469
|
+
Instead of logging in, you may specify a token on the command line
|
470
|
+
with --api-token or using the $ENGINEYARD_API_TOKEN environment
|
471
|
+
variable.
|
472
|
+
DESC
|
461
473
|
def login
|
462
474
|
whoami
|
463
475
|
end
|
data/lib/engineyard/cli/api.rb
CHANGED
@@ -5,71 +5,94 @@ require 'engineyard/eyrc'
|
|
5
5
|
module EY
|
6
6
|
class CLI
|
7
7
|
class API
|
8
|
-
|
9
|
-
ui.info("We need to fetch your API token; please log in.")
|
10
|
-
begin
|
11
|
-
email = ui.ask("Email: ")
|
12
|
-
password = ui.ask("Password: ", true)
|
13
|
-
token = EY::CloudClient.authenticate(email, password, ui)
|
14
|
-
EY::EYRC.load.api_token = token
|
15
|
-
token
|
16
|
-
rescue EY::CloudClient::InvalidCredentials
|
17
|
-
ui.warn "Invalid username or password; please try again."
|
18
|
-
retry
|
19
|
-
end
|
20
|
-
end
|
8
|
+
USER_AGENT = "EngineYard/#{EY::VERSION}"
|
21
9
|
|
22
10
|
attr_reader :token
|
23
11
|
|
24
12
|
def initialize(endpoint, ui, token = nil)
|
13
|
+
@client = EY::CloudClient.new(:endpoint => endpoint, :output => ui.out, :user_agent => USER_AGENT)
|
25
14
|
@ui = ui
|
26
|
-
EY::
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
@source = 'token from --api-token'
|
33
|
-
elsif @token = ENV['ENGINEYARD_API_TOKEN']
|
34
|
-
@specified = true
|
35
|
-
@source = 'token from $ENGINEYARD_API_TOKEN'
|
36
|
-
elsif @token = EY::EYRC.load.api_token
|
37
|
-
@specified = false
|
38
|
-
@source = "api_token in #{EY::EYRC.load.path}"
|
39
|
-
elsif @token = self.class.authenticate(ui)
|
40
|
-
@specified = false
|
41
|
-
@source = 'credentials'
|
42
|
-
else
|
43
|
-
raise EY::Error, "Sorry, we couldn't get your API token."
|
44
|
-
end
|
45
|
-
|
46
|
-
@api = EY::CloudClient.new(@token, @ui)
|
15
|
+
@eyrc = EY::EYRC.load
|
16
|
+
token_from('--api-token') { token } ||
|
17
|
+
token_from('$ENGINEYARD_API_TOKEN') { ENV['ENGINEYARD_API_TOKEN'] } ||
|
18
|
+
token_from(@eyrc.path, false) { @eyrc.api_token } ||
|
19
|
+
authenticate ||
|
20
|
+
token_not_loaded
|
47
21
|
end
|
48
22
|
|
49
23
|
def respond_to?(*a)
|
50
|
-
super or @
|
24
|
+
super or @client.respond_to?(*a)
|
51
25
|
end
|
52
26
|
|
53
27
|
protected
|
54
28
|
|
55
29
|
def method_missing(meth, *args, &block)
|
56
|
-
if @
|
57
|
-
@
|
30
|
+
if @client.respond_to?(meth)
|
31
|
+
with_reauthentication { @client.send(meth, *args, &block) }
|
58
32
|
else
|
59
33
|
super
|
60
34
|
end
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
35
|
+
end
|
36
|
+
|
37
|
+
def with_reauthentication
|
38
|
+
begin
|
39
|
+
yield
|
40
|
+
rescue EY::CloudClient::InvalidCredentials
|
41
|
+
if @specified || !@ui.interactive?
|
42
|
+
# If the token is specified, we raise immediately if it is rejected.
|
43
|
+
raise EY::Error, "Authentication failed: Invalid #{@source}."
|
44
|
+
else
|
45
|
+
@ui.warn "Authentication failed: Invalid #{@source}."
|
46
|
+
authenticate
|
47
|
+
retry
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Get the token from the provided block, saving it if it works.
|
53
|
+
# Specified will help us know what to do if loading the token fails.
|
54
|
+
# Returns true if it gets a token.
|
55
|
+
# Returns false if there is no token.
|
56
|
+
def token_from(source, specified = true)
|
57
|
+
token = yield
|
58
|
+
if token
|
59
|
+
@client.token = token
|
60
|
+
@specified = specified
|
61
|
+
@source = "token from #{source}"
|
62
|
+
@token = token
|
63
|
+
true
|
65
64
|
else
|
66
|
-
|
67
|
-
|
68
|
-
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Load the token from EY Cloud if interactive and
|
70
|
+
# token wasn't explicitly specified previously.
|
71
|
+
def authenticate
|
72
|
+
if @specified
|
73
|
+
return false
|
74
|
+
end
|
75
|
+
|
76
|
+
@source = "credentials"
|
77
|
+
@specified = false
|
78
|
+
|
79
|
+
@ui.info("We need to fetch your API token; please log in.")
|
80
|
+
begin
|
81
|
+
email = @ui.ask("Email: ")
|
82
|
+
passwd = @ui.ask("Password: ", true)
|
83
|
+
@token = @client.authenticate!(email, passwd)
|
84
|
+
@eyrc.api_token = @token
|
85
|
+
true
|
86
|
+
rescue EY::CloudClient::InvalidCredentials
|
87
|
+
@ui.warn "Authentication failed. Please try again."
|
69
88
|
retry
|
70
89
|
end
|
71
90
|
end
|
72
91
|
|
92
|
+
# Occurs when all avenues for getting the token are exhausted.
|
93
|
+
def token_not_loaded
|
94
|
+
raise EY::Error, "Sorry, we couldn't get your API token."
|
95
|
+
end
|
73
96
|
end
|
74
97
|
end
|
75
98
|
end
|
@@ -28,7 +28,7 @@ module EY
|
|
28
28
|
"Upload custom chef recipes to specified environment so they can be applied."
|
29
29
|
long_desc <<-DESC
|
30
30
|
Make an archive of the "cookbooks/" subdirectory in your current working
|
31
|
-
directory and upload it to
|
31
|
+
directory and upload it to Engine Yard Cloud's recipe storage.
|
32
32
|
|
33
33
|
Alternatively, specify a .tgz of a cookbooks/ directory yourself as follows:
|
34
34
|
|
data/lib/engineyard/cli/web.rb
CHANGED
@@ -49,6 +49,37 @@ module EY
|
|
49
49
|
ui.info "Putting up maintenance page for '#{app_env.app.name}' in '#{app_env.environment.name}'"
|
50
50
|
serverside_runner(app_env, options[:verbose]).put_up_maintenance_page.call(ui.out, ui.err)
|
51
51
|
end
|
52
|
+
|
53
|
+
desc "restart [--environment ENVIRONMENT]",
|
54
|
+
"Restart the application servers without deploying."
|
55
|
+
long_desc <<-DESC
|
56
|
+
Restarts the application servers (e.g. Passenger, Unicorn, etc).
|
57
|
+
|
58
|
+
Respects the maintenance_on_restart settings in the application's ey.yml.
|
59
|
+
|
60
|
+
Note: Uses the version of the ey.yml currently checked out on the servers.
|
61
|
+
DESC
|
62
|
+
method_option :environment, :type => :string, :aliases => %w(-e),
|
63
|
+
:required => true, :default => false,
|
64
|
+
:desc => "Environment in which to deploy this application"
|
65
|
+
method_option :app, :type => :string, :aliases => %w(-a),
|
66
|
+
:required => true, :default => '',
|
67
|
+
:desc => "Name of the application to deploy"
|
68
|
+
method_option :account, :type => :string, :aliases => %w(-c),
|
69
|
+
:required => true, :default => '',
|
70
|
+
:desc => "Name of the account in which the environment can be found"
|
71
|
+
method_option :verbose, :type => :boolean, :aliases => %w(-v),
|
72
|
+
:desc => "Be verbose"
|
73
|
+
def restart
|
74
|
+
app_env = fetch_app_environment(options[:app], options[:environment], options[:account])
|
75
|
+
ui.info "Restarting servers on #{app_env.hierarchy_name}"
|
76
|
+
if serverside_runner(app_env, options[:verbose]).restart.call(ui.out, ui.err)
|
77
|
+
ui.info "Restart complete"
|
78
|
+
else
|
79
|
+
raise EY::Error, "Restart failed"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
52
83
|
end
|
53
84
|
end
|
54
85
|
end
|
@@ -36,8 +36,8 @@ class EY
|
|
36
36
|
deployment.successful = runner.call(out, err)
|
37
37
|
rescue Interrupt
|
38
38
|
err << "Interrupted. Deployment halted.\n"
|
39
|
-
ui.warn "Recording canceled deployment in
|
40
|
-
ui.warn "WARNING: Interrupting again may result in a never-finished deployment in the deployment history on
|
39
|
+
ui.warn "Recording canceled deployment in Engine Yard Cloud..."
|
40
|
+
ui.warn "WARNING: Interrupting again may result in a never-finished deployment in the deployment history on Engine Yard Cloud."
|
41
41
|
raise
|
42
42
|
rescue StandardError => e
|
43
43
|
deployment.err << "Error encountered during deploy.\n#{e.class} #{e}\n"
|
@@ -47,11 +47,11 @@ class EY
|
|
47
47
|
deployment.finished
|
48
48
|
|
49
49
|
if deployment.successful?
|
50
|
-
ui.info "Successful deployment recorded on
|
50
|
+
ui.info "Successful deployment recorded on Engine Yard Cloud"
|
51
51
|
ui.info "Deploy complete"
|
52
52
|
ui.info "Now you can run `ey launch' to open the application in a browser."
|
53
53
|
else
|
54
|
-
ui.info "Failed deployment recorded on
|
54
|
+
ui.info "Failed deployment recorded on Engine Yard Cloud"
|
55
55
|
raise EY::Error, "Deploy failed"
|
56
56
|
end
|
57
57
|
end
|
data/lib/engineyard/config.rb
CHANGED
@@ -90,18 +90,15 @@ module EY
|
|
90
90
|
end
|
91
91
|
|
92
92
|
def perform_from_interaction
|
93
|
-
ui.warn "
|
94
|
-
ui.
|
95
|
-
ui.warn "Migrate can be toggled per-deploy using --migrate or --no-migrate."
|
96
|
-
ui.warn "Let's set a default migration choice."
|
97
|
-
ui.warn "**********************************************************************"
|
98
|
-
@perform = ui.agree('Migrate every deploy by default? ', true)
|
93
|
+
ui.warn "Please choose a default migration behavior for this environment."
|
94
|
+
@perform = ui.agree("Run migrations by default on #{env_config.name}? ", true)
|
99
95
|
env_config.migrate = @perform
|
100
96
|
if @perform
|
101
97
|
command_from_interaction
|
102
98
|
end
|
103
99
|
ui.say "#{env_config.path}: migrate settings saved for #{env_config.name}."
|
104
|
-
ui.
|
100
|
+
ui.say "You can override this default with --migrate or --no-migrate."
|
101
|
+
ui.info "Please git commit #{env_config.path} with these new changes."
|
105
102
|
true
|
106
103
|
rescue Timeout::Error
|
107
104
|
@perform = nil
|
data/lib/engineyard/eyrc.rb
CHANGED
@@ -2,14 +2,14 @@ module EY
|
|
2
2
|
class EYRC
|
3
3
|
attr_reader :path
|
4
4
|
|
5
|
-
DEFAULT_PATH = "
|
5
|
+
DEFAULT_PATH = "#{ENV['HOME']}/.eyrc"
|
6
6
|
|
7
7
|
def self.load
|
8
8
|
new(ENV['EYRC'] || DEFAULT_PATH)
|
9
9
|
end
|
10
10
|
|
11
11
|
def initialize(path)
|
12
|
-
|
12
|
+
@path = Pathname.new(path).expand_path
|
13
13
|
end
|
14
14
|
|
15
15
|
def exist?
|
@@ -30,10 +30,6 @@ module EY
|
|
30
30
|
|
31
31
|
private
|
32
32
|
|
33
|
-
def path=(p)
|
34
|
-
@path = Pathname.new(p).expand_path
|
35
|
-
end
|
36
|
-
|
37
33
|
def [](key)
|
38
34
|
read_data[key.to_s]
|
39
35
|
end
|
@@ -10,6 +10,7 @@ module EY
|
|
10
10
|
@username = environment.username
|
11
11
|
@hostname = bridge
|
12
12
|
@command = nil
|
13
|
+
@acc_env_name = "#{app.account.name}/#{environment.name}"
|
13
14
|
end
|
14
15
|
|
15
16
|
def deploy(&block)
|
@@ -22,6 +23,11 @@ module EY
|
|
22
23
|
self
|
23
24
|
end
|
24
25
|
|
26
|
+
def restart(&block)
|
27
|
+
@command = @adapter.restart(&block)
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
25
31
|
def put_up_maintenance_page(&block)
|
26
32
|
@command = @adapter.enable_maintenance(&block)
|
27
33
|
self
|
@@ -89,16 +95,30 @@ module EY
|
|
89
95
|
begin
|
90
96
|
ssh(cmd, @hostname, @username, out, err)
|
91
97
|
rescue Net::SSH::AuthenticationFailed
|
92
|
-
raise EY::Error,
|
98
|
+
raise EY::Error, <<-ERROR
|
99
|
+
Authentication Failed. Things to fix:
|
100
|
+
1. Add your SSH key to your local SSH agent with `ssh-add path/to/key`.
|
101
|
+
2. Add your SSH key to #{@acc_env_name} on Engine Yard Cloud and apply the changes.
|
102
|
+
(https://support.cloud.engineyard.com/entries/20996846-set-up-ssh-keys)
|
103
|
+
ERROR
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def net_ssh_options
|
109
|
+
level = :fatal # default in Net::SSH
|
110
|
+
if debug = ENV["DEBUG"]
|
111
|
+
level = :info
|
112
|
+
if %w[debug info warn error fatal].include?(debug.downcase)
|
113
|
+
level = debug.downcase.to_sym
|
93
114
|
end
|
94
115
|
end
|
116
|
+
{:paranoid => false, :verbose => level}
|
95
117
|
end
|
96
118
|
|
97
119
|
def ssh(cmd, hostname, username, out, err)
|
98
120
|
exit_code = 1
|
99
|
-
|
100
|
-
options_for_ssh[:verbose] = ENV["DEBUG"].downcase.to_sym if ENV["DEBUG"]
|
101
|
-
Net::SSH.start(hostname, username, options_for_ssh) do |net_ssh|
|
121
|
+
Net::SSH.start(hostname, username, net_ssh_options) do |net_ssh|
|
102
122
|
net_ssh.open_channel do |channel|
|
103
123
|
channel.exec cmd do |_, success|
|
104
124
|
unless success
|
data/lib/engineyard/thor.rb
CHANGED
@@ -40,7 +40,7 @@ module EY
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def fetch_environment(environment_name, account_name)
|
43
|
-
ui.info "Loading application data from
|
43
|
+
ui.info "Loading application data from Engine Yard Cloud..."
|
44
44
|
|
45
45
|
environment_name ||= use_default_environment
|
46
46
|
remotes = repo.remotes if in_repo?
|
@@ -72,7 +72,7 @@ module EY
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def fetch_app_environment(app_name, environment_name, account_name)
|
75
|
-
ui.info "Loading application data from
|
75
|
+
ui.info "Loading application data from Engine Yard Cloud..."
|
76
76
|
|
77
77
|
environment_name ||= use_default_environment
|
78
78
|
remotes = repo.remotes if in_repo?
|
data/lib/engineyard/version.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "ey web restart" do
|
4
|
+
given "integration"
|
5
|
+
|
6
|
+
def command_to_run(opts)
|
7
|
+
cmd = %w[web restart]
|
8
|
+
cmd << "-e" << opts[:environment] if opts[:environment]
|
9
|
+
cmd << "-a" << opts[:app] if opts[:app]
|
10
|
+
cmd << "-c" << opts[:account] if opts[:account]
|
11
|
+
cmd << "--verbose" if opts[:verbose]
|
12
|
+
cmd
|
13
|
+
end
|
14
|
+
|
15
|
+
def verify_ran(scenario)
|
16
|
+
@ssh_commands.should have_command_like(/engineyard-serverside.*restart.*--app #{scenario[:application]}/)
|
17
|
+
end
|
18
|
+
|
19
|
+
include_examples "it takes an environment name and an app name and an account name"
|
20
|
+
include_examples "it invokes engineyard-serverside"
|
21
|
+
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/support/helpers.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: engineyard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0
|
5
|
-
prerelease:
|
4
|
+
version: 2.0.0
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
|
-
-
|
8
|
+
- Engine Yard Cloud Team
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-08-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rest-client
|
@@ -98,7 +98,7 @@ dependencies:
|
|
98
98
|
requirements:
|
99
99
|
- - '='
|
100
100
|
- !ruby/object:Gem::Version
|
101
|
-
version: 2.0.0
|
101
|
+
version: 2.0.0
|
102
102
|
type: :runtime
|
103
103
|
prerelease: false
|
104
104
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -106,7 +106,7 @@ dependencies:
|
|
106
106
|
requirements:
|
107
107
|
- - '='
|
108
108
|
- !ruby/object:Gem::Version
|
109
|
-
version: 2.0.0
|
109
|
+
version: 2.0.0
|
110
110
|
- !ruby/object:Gem::Dependency
|
111
111
|
name: engineyard-cloud-client
|
112
112
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,7 +114,7 @@ dependencies:
|
|
114
114
|
requirements:
|
115
115
|
- - ~>
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: 1.0.
|
117
|
+
version: 1.0.5
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -122,7 +122,7 @@ dependencies:
|
|
122
122
|
requirements:
|
123
123
|
- - ~>
|
124
124
|
- !ruby/object:Gem::Version
|
125
|
-
version: 1.0.
|
125
|
+
version: 1.0.5
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
127
|
name: net-ssh
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
@@ -144,17 +144,17 @@ dependencies:
|
|
144
144
|
requirement: !ruby/object:Gem::Requirement
|
145
145
|
none: false
|
146
146
|
requirements:
|
147
|
-
- -
|
147
|
+
- - '='
|
148
148
|
- !ruby/object:Gem::Version
|
149
|
-
version:
|
149
|
+
version: 2.1.0
|
150
150
|
type: :runtime
|
151
151
|
prerelease: false
|
152
152
|
version_requirements: !ruby/object:Gem::Requirement
|
153
153
|
none: false
|
154
154
|
requirements:
|
155
|
-
- -
|
155
|
+
- - '='
|
156
156
|
- !ruby/object:Gem::Version
|
157
|
-
version:
|
157
|
+
version: 2.1.0
|
158
158
|
- !ruby/object:Gem::Dependency
|
159
159
|
name: rspec
|
160
160
|
requirement: !ruby/object:Gem::Requirement
|
@@ -366,6 +366,7 @@ files:
|
|
366
366
|
- spec/ey/status_spec.rb
|
367
367
|
- spec/ey/web/disable_spec.rb
|
368
368
|
- spec/ey/web/enable_spec.rb
|
369
|
+
- spec/ey/web/restart_spec.rb
|
369
370
|
- spec/ey/whoami_spec.rb
|
370
371
|
- spec/spec_helper.rb
|
371
372
|
- spec/support/bundled_ey
|
@@ -377,11 +378,26 @@ files:
|
|
377
378
|
- spec/support/shared_behavior.rb
|
378
379
|
homepage: http://github.com/engineyard/engineyard
|
379
380
|
licenses: []
|
380
|
-
post_install_message: ! "
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
381
|
+
post_install_message: ! "Thank you for downloading engineyard gem version 2!\n\n############
|
382
|
+
NOTICE when upgrading from 1.x to 2.x ############\n\nFirst, if you have any trouble,
|
383
|
+
you can uninstall this version to downgrade.\nThis version of the CLI does not affect
|
384
|
+
the web deploy system.\nPlease file a support ticket if you have any issues at:
|
385
|
+
support.cloud.engineyard.com\n\n* IMPORTANT: eydeploy.rb modifications MUST be verified
|
386
|
+
in staging!\n Many internals have changed that could break eydeploy.rb!\n* The
|
387
|
+
order of compile_assets has *changed*. It now runs before\n the maintenance page
|
388
|
+
is enabled, to reduce downtime.\n* ey.yml files should be checked in to your repository.\n*
|
389
|
+
Default bundler version is now 1.1.5.\n\nA few other nice changes:\n\n* All CLI
|
390
|
+
commands are significantly faster. Woo!\n* Deploy hooks now have access to `account_name`
|
391
|
+
and `environment_name`.\n* Deploy hooks can now use run! and sudo! to abort on failure.\n*
|
392
|
+
Supports new ey.yml options when ey.yml is committed:\n * maintenance_on_restart:
|
393
|
+
true/false (default: false except for glassfish and mongrel)\n * maintenance_on_migrate:
|
394
|
+
true/false (default: true)\n * precompile_assets: true/false (default: inferred
|
395
|
+
using app/assets and config/application.rb)\n * ignore_database_adapter_warning:
|
396
|
+
true (hides adapter warning)\n* Don't remove maintenance pages that weren't put
|
397
|
+
up during this deploy if maintenance options (above) are set to false.\n* ey web
|
398
|
+
restart - restarts web servers without deploying.\n\nDeploying for the first time?
|
399
|
+
The Engine Yard Pandas want to help you!\nEmail pandas@engineyard.com with your
|
400
|
+
questions.\n"
|
385
401
|
rdoc_options: []
|
386
402
|
require_paths:
|
387
403
|
- lib
|
@@ -391,12 +407,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
391
407
|
- - ! '>='
|
392
408
|
- !ruby/object:Gem::Version
|
393
409
|
version: '0'
|
410
|
+
segments:
|
411
|
+
- 0
|
412
|
+
hash: -4522439113898007272
|
394
413
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
395
414
|
none: false
|
396
415
|
requirements:
|
397
|
-
- - ! '
|
416
|
+
- - ! '>='
|
398
417
|
- !ruby/object:Gem::Version
|
399
|
-
version:
|
418
|
+
version: '0'
|
419
|
+
segments:
|
420
|
+
- 0
|
421
|
+
hash: -4522439113898007272
|
400
422
|
requirements: []
|
401
423
|
rubyforge_project:
|
402
424
|
rubygems_version: 1.8.24
|
@@ -426,6 +448,7 @@ test_files:
|
|
426
448
|
- spec/ey/status_spec.rb
|
427
449
|
- spec/ey/web/disable_spec.rb
|
428
450
|
- spec/ey/web/enable_spec.rb
|
451
|
+
- spec/ey/web/restart_spec.rb
|
429
452
|
- spec/ey/whoami_spec.rb
|
430
453
|
- spec/spec_helper.rb
|
431
454
|
- spec/support/bundled_ey
|