engineyard 1.7.0.pre2 → 2.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/engineyard/cli.rb +15 -12
- data/lib/engineyard/cli/recipes.rb +31 -3
- data/lib/engineyard/cli/ui.rb +24 -22
- data/lib/engineyard/config.rb +43 -3
- data/lib/engineyard/deploy_config/migrate.rb +2 -2
- data/lib/engineyard/version.rb +1 -1
- data/spec/ey/deploy_spec.rb +23 -9
- data/spec/ey/list_environments_spec.rb +0 -1
- data/spec/ey/status_spec.rb +5 -2
- metadata +11 -12
- data/lib/engineyard/cli/#recipes.rb# +0 -32
data/lib/engineyard/cli.rb
CHANGED
@@ -3,6 +3,7 @@ require 'engineyard/error'
|
|
3
3
|
require 'engineyard/thor'
|
4
4
|
require 'engineyard/deploy_config'
|
5
5
|
require 'engineyard/serverside_runner'
|
6
|
+
require 'launchy'
|
6
7
|
|
7
8
|
module EY
|
8
9
|
class CLI < EY::Thor
|
@@ -146,7 +147,7 @@ module EY
|
|
146
147
|
app_env = fetch_app_environment(options[:app], options[:environment], options[:account])
|
147
148
|
deployment = app_env.last_deployment
|
148
149
|
if deployment
|
149
|
-
ui.say "# Status of last deployment of #{app_env.
|
150
|
+
ui.say "# Status of last deployment of #{app_env.hierarchy_name}:"
|
150
151
|
ui.say "#"
|
151
152
|
ui.show_deployment(deployment)
|
152
153
|
ui.say "#"
|
@@ -177,10 +178,9 @@ module EY
|
|
177
178
|
:desc => "Show environments matching environment name"
|
178
179
|
def environments
|
179
180
|
if options[:all] && options[:simple]
|
180
|
-
|
181
|
-
puts api.environments.map {|env| env.name}
|
181
|
+
ui.print_simple_envs api.environments
|
182
182
|
elsif options[:all]
|
183
|
-
ui.print_envs(api.apps
|
183
|
+
ui.print_envs(api.apps)
|
184
184
|
else
|
185
185
|
remotes = nil
|
186
186
|
if options[:app] == ''
|
@@ -203,14 +203,17 @@ module EY
|
|
203
203
|
|
204
204
|
apps = resolver.matches.map { |app_env| app_env.app }.uniq
|
205
205
|
|
206
|
-
if
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
206
|
+
if options[:simple]
|
207
|
+
if apps.size > 1
|
208
|
+
message = "# This app matches multiple Applications in EY Cloud:\n"
|
209
|
+
apps.each { |app| message << "#\t#{app.name}\n" }
|
210
|
+
message << "# The following environments contain those applications:\n\n"
|
211
|
+
ui.warn(message)
|
212
|
+
end
|
213
|
+
ui.print_simple_envs(apps.map{ |app| app.environments }.flatten)
|
214
|
+
else
|
215
|
+
ui.print_envs(apps, config.default_environment)
|
211
216
|
end
|
212
|
-
|
213
|
-
ui.print_envs(apps, config.default_environment, options[:simple], config.endpoint)
|
214
217
|
end
|
215
218
|
end
|
216
219
|
map "envs" => :environments
|
@@ -263,7 +266,7 @@ module EY
|
|
263
266
|
env_config = config.environment_config(app_env.environment_name)
|
264
267
|
deploy_config = EY::DeployConfig.new(options, env_config, repo, ui)
|
265
268
|
|
266
|
-
ui.info("Rolling back #{app_env.
|
269
|
+
ui.info("Rolling back #{app_env.hierarchy_name}")
|
267
270
|
|
268
271
|
runner = serverside_runner(app_env, deploy_config.verbose)
|
269
272
|
runner.rollback do |args|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
1
3
|
module EY
|
2
4
|
class CLI
|
3
5
|
class Recipes < EY::Thor
|
@@ -66,10 +68,25 @@ module EY
|
|
66
68
|
environment.upload_recipes_at_path(filename)
|
67
69
|
ui.say "Recipes file #{filename} uploaded successfully for #{environment.name}"
|
68
70
|
else
|
69
|
-
|
71
|
+
path = cookbooks_dir_archive_path
|
72
|
+
environment.upload_recipes_at_path(path)
|
70
73
|
ui.say "Recipes in cookbooks/ uploaded successfully for #{environment.name}"
|
71
74
|
end
|
72
75
|
end
|
76
|
+
|
77
|
+
def cookbooks_dir_archive_path
|
78
|
+
unless FileTest.exist?("cookbooks")
|
79
|
+
raise EY::Error, "Could not find chef recipes. Please run from the root of your recipes repo."
|
80
|
+
end
|
81
|
+
|
82
|
+
recipes_file = Tempfile.new("recipes")
|
83
|
+
cmd = "tar czf '#{recipes_file.path}' cookbooks/"
|
84
|
+
|
85
|
+
unless system(cmd)
|
86
|
+
raise EY::Error, "Could not archive recipes.\nCommand `#{cmd}` exited with an error."
|
87
|
+
end
|
88
|
+
recipes_file.path
|
89
|
+
end
|
73
90
|
end
|
74
91
|
|
75
92
|
desc "download [--environment ENVIRONMENT]",
|
@@ -87,9 +104,20 @@ module EY
|
|
87
104
|
:required => true, :default => '',
|
88
105
|
:desc => "Name of the account in which the environment can be found"
|
89
106
|
def download
|
107
|
+
if File.exist?('cookbooks')
|
108
|
+
raise EY::Error, "Cannot download recipes, cookbooks directory already exists."
|
109
|
+
end
|
110
|
+
|
90
111
|
environment = fetch_environment(options[:environment], options[:account])
|
91
|
-
|
92
|
-
|
112
|
+
|
113
|
+
recipes = environment.download_recipes
|
114
|
+
cmd = "tar xzf '#{recipes.path}' cookbooks"
|
115
|
+
|
116
|
+
if system(cmd)
|
117
|
+
ui.say "Recipes downloaded successfully for #{environment.name}"
|
118
|
+
else
|
119
|
+
raise EY::Error, "Could not unarchive recipes.\nCommand `#{cmd}` exited with an error."
|
120
|
+
end
|
93
121
|
end
|
94
122
|
|
95
123
|
end
|
data/lib/engineyard/cli/ui.rb
CHANGED
@@ -127,30 +127,32 @@ module EY
|
|
127
127
|
return ''
|
128
128
|
end
|
129
129
|
|
130
|
-
def
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
puts "
|
130
|
+
def print_simple_envs(envs)
|
131
|
+
puts envs.map{|env| env.name }.uniq.sort
|
132
|
+
end
|
133
|
+
|
134
|
+
def print_envs(apps, default_env_name = nil)
|
135
|
+
apps.sort_by {|app| "#{app.account.name}/#{app.name}" }.each do |app|
|
136
|
+
puts "#{app.account.name}/#{app.name}"
|
137
|
+
if app.environments.any?
|
138
|
+
app.environments.sort_by {|env| env.name }.each do |env|
|
139
|
+
icount = env.instances_count
|
140
|
+
iname = case icount
|
141
|
+
when 0 then "(stopped)"
|
142
|
+
when 1 then "1 instance"
|
143
|
+
else "#{icount} instances"
|
144
|
+
end
|
145
|
+
|
146
|
+
name = env.name == default_env_name ? "#{env.name} (default)" : env.name
|
147
|
+
framework_env = env.framework_env && "[#{env.framework_env.center(12)}]"
|
148
|
+
|
149
|
+
puts " #{name.ljust(30)} #{framework_env} #{iname}"
|
150
150
|
end
|
151
|
-
|
152
|
-
puts ""
|
151
|
+
else
|
152
|
+
puts " (No environments)"
|
153
153
|
end
|
154
|
+
|
155
|
+
puts ""
|
154
156
|
end
|
155
157
|
end
|
156
158
|
|
data/lib/engineyard/config.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'uri'
|
2
2
|
require 'yaml'
|
3
|
+
require 'pathname'
|
3
4
|
require 'engineyard/error'
|
4
5
|
|
5
6
|
module EY
|
@@ -60,8 +61,44 @@ module EY
|
|
60
61
|
environments[environment_name] ||= {}
|
61
62
|
environments[environment_name][key] = value
|
62
63
|
ensure_path
|
64
|
+
comments = ey_yml_comments
|
63
65
|
@path.open('w') do |f|
|
64
|
-
|
66
|
+
f.puts comments
|
67
|
+
f.puts YAML.dump(@config)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
EY_YML_HINTS = <<-HINTS
|
72
|
+
# ey.yml supports many deploy configuration options when committed in an
|
73
|
+
# application's repository.
|
74
|
+
#
|
75
|
+
# Valid locations: REPO_ROOT/ey.yml or REPO_ROOT/config/ey.yml.
|
76
|
+
#
|
77
|
+
# Examples options:
|
78
|
+
#
|
79
|
+
# environments:
|
80
|
+
# YOUR_ENVIRONMENT_NAME: # All options pertain only to the named environment
|
81
|
+
# migrate: true # Default --migrate choice for ey deploy
|
82
|
+
# migration_command: 'rake migrate' # Default migrate command to run when migrations are enabled
|
83
|
+
# branch: default_deploy_branch # Branch/ref to be deployed by default during ey deploy
|
84
|
+
# bundle_without: development test # The string to pass to bundle install --without ''
|
85
|
+
# maintenance_on_migrate: true # Enable maintenance page during migrate action (use with caution) (default: true)
|
86
|
+
# maintenance_on_restart: false # Enable maintanence page during every deploy (default: false for unicorn & passenger)
|
87
|
+
# ignore_database_adapter_warning: false # Hide the warning shown when the Gemfile does not contain a recognized database adapter (mongodb for example)
|
88
|
+
# your_own_custom_key: 'any attribute you put in ey.yml is available in deploy hooks'
|
89
|
+
#
|
90
|
+
# Further information available here:
|
91
|
+
# https://support.cloud.engineyard.com/entries/20996661-customize-your-deployment-on-engine-yard-cloud
|
92
|
+
#
|
93
|
+
# NOTE: Please commit this file into your git repository.
|
94
|
+
#
|
95
|
+
HINTS
|
96
|
+
|
97
|
+
def ey_yml_comments
|
98
|
+
if @path.exist?
|
99
|
+
existing = @path.readlines.grep(/^#/).join("\n")
|
100
|
+
else
|
101
|
+
EY_YML_HINTS
|
65
102
|
end
|
66
103
|
end
|
67
104
|
|
@@ -70,8 +107,11 @@ module EY
|
|
70
107
|
unless EY::Repo.exist?
|
71
108
|
raise "Not in application directory. Unable to save configuration."
|
72
109
|
end
|
73
|
-
|
74
|
-
|
110
|
+
if Pathname.new('config').exist?
|
111
|
+
@path = Pathname.new('config/ey.yml')
|
112
|
+
else
|
113
|
+
@path = Pathname.new('ey.yml')
|
114
|
+
end
|
75
115
|
@path
|
76
116
|
end
|
77
117
|
|
@@ -101,12 +101,12 @@ module EY
|
|
101
101
|
command_from_interaction
|
102
102
|
end
|
103
103
|
ui.say "#{env_config.path}: migrate settings saved for #{env_config.name}."
|
104
|
-
ui.
|
104
|
+
ui.info "It's a good idea to git commit #{env_config.path} with these new changes."
|
105
105
|
true
|
106
106
|
rescue Timeout::Error
|
107
107
|
@perform = nil
|
108
108
|
@command = nil
|
109
|
-
ui.error "Timeout when waiting for input.
|
109
|
+
ui.error "Timeout when waiting for input. Maybe this is not a terminal?"
|
110
110
|
ui.error "ey deploy no longer migrates when no default is set in ey.yml."
|
111
111
|
ui.error "Run interactively for step-by-step ey.yml migration setup."
|
112
112
|
return false
|
data/lib/engineyard/version.rb
CHANGED
data/spec/ey/deploy_spec.rb
CHANGED
@@ -107,43 +107,57 @@ describe "ey deploy" do
|
|
107
107
|
@ssh_commands.last.should =~ %r{/usr/local/ey_resin/ruby/bin/engineyard-serverside}
|
108
108
|
end
|
109
109
|
|
110
|
-
context "without migrate sepecified interactively reads migration command" do
|
111
|
-
|
110
|
+
context "without migrate sepecified, interactively reads migration command" do
|
111
|
+
def clean_ey_yml
|
112
|
+
File.unlink 'ey.yml' if File.exist?('ey.yml')
|
113
|
+
FileUtils.rm_r 'config' if FileTest.exist?('config')
|
114
|
+
end
|
115
|
+
|
116
|
+
before { clean_ey_yml }
|
117
|
+
after { clean_ey_yml }
|
112
118
|
|
113
|
-
it "defaults to yes, and then rake db:migrate" do
|
114
|
-
|
119
|
+
it "defaults to yes, and then rake db:migrate (and installs to config/ey.yml if config/ exists already)" do
|
120
|
+
ey_yml = Pathname.new('config/ey.yml')
|
121
|
+
File.exist?('ey.yml').should be_false
|
122
|
+
ey_yml.dirname.mkpath
|
123
|
+
ey_yml.should_not be_exist
|
115
124
|
ey(%w[deploy]) do |input|
|
116
125
|
input.puts('')
|
117
126
|
input.puts('')
|
118
127
|
end
|
119
128
|
@ssh_commands.last.should =~ /engineyard-serverside.*deploy/
|
120
129
|
@ssh_commands.last.should =~ /--migrate 'rake db:migrate'/
|
121
|
-
|
130
|
+
File.exist?('ey.yml').should be_false
|
131
|
+
ey_yml.should be_exist
|
132
|
+
env_conf = read_yaml(ey_yml.to_s)['environments']['giblets']
|
122
133
|
env_conf['migrate'].should == true
|
123
134
|
env_conf['migration_command'].should == 'rake db:migrate'
|
124
135
|
end
|
125
136
|
|
126
137
|
it "accepts new commands" do
|
127
|
-
File.exist?('
|
138
|
+
File.exist?('ey.yml').should be_false
|
139
|
+
FileTest.exist?('config').should be_false
|
128
140
|
ey(%w[deploy], :hide_err => true) do |input|
|
129
141
|
input.puts("y")
|
130
142
|
input.puts("ruby migrate")
|
131
143
|
end
|
132
144
|
@ssh_commands.last.should =~ /engineyard-serverside.*deploy/
|
133
145
|
@ssh_commands.last.should =~ /--migrate 'ruby migrate'/
|
134
|
-
|
146
|
+
File.exist?('ey.yml').should be_true
|
147
|
+
env_conf = read_yaml('ey.yml')['environments']['giblets']
|
135
148
|
env_conf['migrate'].should == true
|
136
149
|
env_conf['migration_command'].should == 'ruby migrate'
|
137
150
|
end
|
138
151
|
|
139
152
|
it "doesn't ask for the command if you say no" do
|
140
|
-
File.exist?('
|
153
|
+
File.exist?('ey.yml').should be_false
|
141
154
|
ey(%w[deploy], :hide_err => true) do |input|
|
142
155
|
input.puts("no")
|
143
156
|
end
|
144
157
|
@ssh_commands.last.should =~ /engineyard-serverside.*deploy/
|
145
158
|
@ssh_commands.last.should_not =~ /--migrate/
|
146
|
-
|
159
|
+
File.exist?('ey.yml').should be_true
|
160
|
+
read_yaml('ey.yml')['environments']['giblets']['migrate'].should == false
|
147
161
|
end
|
148
162
|
end
|
149
163
|
|
@@ -114,7 +114,6 @@ describe "ey environments with an ambiguous git repo" do
|
|
114
114
|
|
115
115
|
it "lists environments from all apps using the git repo" do
|
116
116
|
fast_ey %w[environments]
|
117
|
-
@out.should =~ /git repo matches multiple/i
|
118
117
|
@out.should include("giblets")
|
119
118
|
@out.should include("keycollector_production")
|
120
119
|
end
|
data/spec/ey/status_spec.rb
CHANGED
@@ -9,12 +9,15 @@ describe "ey environments" do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
it "outputs the status of the deployment" do
|
12
|
+
ey %w[deploy -e giblets --ref HEAD --no-migrate]
|
12
13
|
ey %w[status -e giblets]
|
13
14
|
@out.should =~ /Application:\s+rails232app/
|
14
15
|
@out.should =~ /Environment:\s+giblets/
|
15
16
|
@out.should =~ /Ref:\s+HEAD/
|
16
|
-
@out.should =~ /Resolved Ref:\s+HEAD/
|
17
|
-
@out.should =~ /
|
17
|
+
@out.should =~ /Resolved Ref:\s+resolved-HEAD/
|
18
|
+
@out.should =~ /Commit:\s+[a-f0-9]{40}/
|
19
|
+
@out.should =~ /Migrate:\s+false/
|
20
|
+
@out.should =~ /Deployed by:\s+One App Many Envs/
|
18
21
|
@out.should =~ /Started at:/
|
19
22
|
@out.should =~ /Finished at:/
|
20
23
|
@out.should =~ /This deployment was successful/
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: engineyard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.pre1
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-
|
12
|
+
date: 2012-05-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rest-client
|
@@ -82,7 +82,7 @@ dependencies:
|
|
82
82
|
requirements:
|
83
83
|
- - '='
|
84
84
|
- !ruby/object:Gem::Version
|
85
|
-
version:
|
85
|
+
version: 2.0.0.pre1
|
86
86
|
type: :runtime
|
87
87
|
prerelease: false
|
88
88
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -90,7 +90,7 @@ dependencies:
|
|
90
90
|
requirements:
|
91
91
|
- - '='
|
92
92
|
- !ruby/object:Gem::Version
|
93
|
-
version:
|
93
|
+
version: 2.0.0.pre1
|
94
94
|
- !ruby/object:Gem::Dependency
|
95
95
|
name: engineyard-cloud-client
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,7 +98,7 @@ dependencies:
|
|
98
98
|
requirements:
|
99
99
|
- - ~>
|
100
100
|
- !ruby/object:Gem::Version
|
101
|
-
version: 0.1
|
101
|
+
version: 1.0.1
|
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: 0.1
|
109
|
+
version: 1.0.1
|
110
110
|
- !ruby/object:Gem::Dependency
|
111
111
|
name: net-ssh
|
112
112
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,17 +128,17 @@ dependencies:
|
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
129
129
|
none: false
|
130
130
|
requirements:
|
131
|
-
- -
|
131
|
+
- - ~>
|
132
132
|
- !ruby/object:Gem::Version
|
133
|
-
version: 2.
|
133
|
+
version: '2.1'
|
134
134
|
type: :runtime
|
135
135
|
prerelease: false
|
136
136
|
version_requirements: !ruby/object:Gem::Requirement
|
137
137
|
none: false
|
138
138
|
requirements:
|
139
|
-
- -
|
139
|
+
- - ~>
|
140
140
|
- !ruby/object:Gem::Version
|
141
|
-
version: 2.
|
141
|
+
version: '2.1'
|
142
142
|
- !ruby/object:Gem::Dependency
|
143
143
|
name: rspec
|
144
144
|
requirement: !ruby/object:Gem::Requirement
|
@@ -308,7 +308,6 @@ extensions: []
|
|
308
308
|
extra_rdoc_files: []
|
309
309
|
files:
|
310
310
|
- bin/ey
|
311
|
-
- lib/engineyard/cli/#recipes.rb#
|
312
311
|
- lib/engineyard/cli/api.rb
|
313
312
|
- lib/engineyard/cli/recipes.rb
|
314
313
|
- lib/engineyard/cli/ui.rb
|
@@ -413,7 +412,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
413
412
|
version: 1.3.1
|
414
413
|
requirements: []
|
415
414
|
rubyforge_project:
|
416
|
-
rubygems_version: 1.8.
|
415
|
+
rubygems_version: 1.8.24
|
417
416
|
signing_key:
|
418
417
|
specification_version: 3
|
419
418
|
summary: Command-line deployment for the Engine Yard cloud
|
@@ -1,32 +0,0 @@
|
|
1
|
-
module EY
|
2
|
-
class CLI
|
3
|
-
class Recipes < EY::Thor
|
4
|
-
X1gx1GGG desc "recipes apply [ENVIRONMENT]", <<-DESC
|
5
|
-
Run uploaded chef recipes on specified environment.
|
6
|
-
|
7
|
-
This is similar to '#{banner_base} rebuild' except Engine Yard's main
|
8
|
-
configuration step is skipped.
|
9
|
-
DESC
|
10
|
-
|
11
|
-
def apply(name = nil)
|
12
|
-
environment = fetch_environment(name)
|
13
|
-
environment.run_custom_recipes
|
14
|
-
EY.ui.say "Uploaded recipes started for #{environment.name}"
|
15
|
-
end
|
16
|
-
|
17
|
-
desc "recipes upload [ENVIRONMENT]", <<-DESC
|
18
|
-
Upload custom chef recipes to specified environment.
|
19
|
-
|
20
|
-
The current directory should contain a subdirectory named "cookbooks" to be
|
21
|
-
uploaded.
|
22
|
-
DESC
|
23
|
-
|
24
|
-
def upload(name = nil)
|
25
|
-
environment = fetch_environment(name)
|
26
|
-
environment.upload_recipes
|
27
|
-
EY.ui.say "Recipes uploaded successfully for #{environment.name}"
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|