engineyard 2.3.3 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,7 +10,7 @@ module EY
10
10
  attr_reader :token
11
11
 
12
12
  def initialize(endpoint, ui, token = nil)
13
- @client = EY::CloudClient.new(:endpoint => endpoint, :output => ui.out, :user_agent => USER_AGENT)
13
+ @client = EY::CloudClient.new(endpoint: endpoint, output: ui.out, user_agent: USER_AGENT)
14
14
  @ui = ui
15
15
  @eyrc = EY::EYRC.load
16
16
  token_from('--api-token') { token } ||
@@ -13,12 +13,12 @@ module EY
13
13
  you run '#{banner_base} recipes apply'.
14
14
  DESC
15
15
 
16
- method_option :environment, :type => :string, :aliases => %w(-e),
17
- :required => true, :default => '',
18
- :desc => "Environment in which to apply recipes"
19
- method_option :account, :type => :string, :aliases => %w(-c),
20
- :required => true, :default => '',
21
- :desc => "Name of the account in which the environment can be found"
16
+ method_option :environment, type: :string, aliases: %w(-e),
17
+ required: true, default: '',
18
+ desc: "Environment in which to apply recipes"
19
+ method_option :account, type: :string, aliases: %w(-c),
20
+ required: true, default: '',
21
+ desc: "Name of the account in which the environment can be found"
22
22
  def apply
23
23
  environment = fetch_environment(options[:environment], options[:account])
24
24
  apply_recipes(environment)
@@ -38,17 +38,17 @@ module EY
38
38
  and also automatically each time you update/rebuild your instances.
39
39
  DESC
40
40
 
41
- method_option :environment, :type => :string, :aliases => %w(-e),
42
- :required => true, :default => '',
43
- :desc => "Environment that will receive the recipes"
44
- method_option :account, :type => :string, :aliases => %w(-c),
45
- :required => true, :default => '',
46
- :desc => "Name of the account in which the environment can be found"
47
- method_option :apply, :type => :boolean,
48
- :desc => "Apply the recipes immediately after they are uploaded"
49
- method_option :file, :type => :string, :aliases => %w(-f),
50
- :required => true, :default => '',
51
- :desc => "Specify a gzipped tar file (.tgz) for upload instead of cookbooks/ directory"
41
+ method_option :environment, type: :string, aliases: %w(-e),
42
+ required: true, default: '',
43
+ desc: "Environment that will receive the recipes"
44
+ method_option :account, type: :string, aliases: %w(-c),
45
+ required: true, default: '',
46
+ desc: "Name of the account in which the environment can be found"
47
+ method_option :apply, type: :boolean,
48
+ desc: "Apply the recipes immediately after they are uploaded"
49
+ method_option :file, type: :string, aliases: %w(-f),
50
+ required: true, default: '',
51
+ desc: "Specify a gzipped tar file (.tgz) for upload instead of cookbooks/ directory"
52
52
  def upload
53
53
  environment = fetch_environment(options[:environment], options[:account])
54
54
  upload_recipes(environment, options[:file])
@@ -80,7 +80,11 @@ module EY
80
80
  end
81
81
 
82
82
  recipes_file = Tempfile.new("recipes")
83
+
83
84
  cmd = "tar czf '#{recipes_file.path}' cookbooks/"
85
+ if FileTest.exist?("data_bags")
86
+ cmd = cmd + " data_bags/"
87
+ end
84
88
 
85
89
  unless system(cmd)
86
90
  raise EY::Error, "Could not archive recipes.\nCommand `#{cmd}` exited with an error."
@@ -97,12 +101,12 @@ module EY
97
101
 
98
102
  If the cookbooks directory already exists, an error will be raised.
99
103
  DESC
100
- method_option :environment, :type => :string, :aliases => %w(-e),
101
- :required => true, :default => '',
102
- :desc => "Environment for which to download the recipes"
103
- method_option :account, :type => :string, :aliases => %w(-c),
104
- :required => true, :default => '',
105
- :desc => "Name of the account in which the environment can be found"
104
+ method_option :environment, type: :string, aliases: %w(-e),
105
+ required: true, default: '',
106
+ desc: "Environment for which to download the recipes"
107
+ method_option :account, type: :string, aliases: %w(-c),
108
+ required: true, default: '',
109
+ desc: "Name of the account in which the environment can be found"
106
110
  def download
107
111
  if File.exist?('cookbooks')
108
112
  raise EY::Error, "Cannot download recipes, cookbooks directory already exists."
@@ -255,7 +255,7 @@ module EY
255
255
  end
256
256
 
257
257
  def print_help(table)
258
- print_table(table, :ident => 2, :truncate => true, :colwidth => 20)
258
+ print_table(table, ident: 2, truncate: true, colwidth: 20)
259
259
  end
260
260
 
261
261
  def set_color(string, color, bold=false)
@@ -3,17 +3,17 @@ module EY
3
3
  class Web < EY::Thor
4
4
  desc "enable [--environment/-e ENVIRONMENT]",
5
5
  "Remove the maintenance page for this application in the given environment."
6
- method_option :environment, :type => :string, :aliases => %w(-e),
7
- :required => true, :default => '',
8
- :desc => "Environment on which to take down the maintenance page"
9
- method_option :app, :type => :string, :aliases => %w(-a),
10
- :required => true, :default => '',
11
- :desc => "Name of the application whose maintenance page will be removed"
12
- method_option :account, :type => :string, :aliases => %w(-c),
13
- :required => true, :default => '',
14
- :desc => "Name of the account in which the environment can be found"
15
- method_option :verbose, :type => :boolean, :aliases => %w(-v),
16
- :desc => "Be verbose"
6
+ method_option :environment, type: :string, aliases: %w(-e),
7
+ required: true, default: '',
8
+ desc: "Environment on which to take down the maintenance page"
9
+ method_option :app, type: :string, aliases: %w(-a),
10
+ required: true, default: '',
11
+ desc: "Name of the application whose maintenance page will be removed"
12
+ method_option :account, type: :string, aliases: %w(-c),
13
+ required: true, default: '',
14
+ desc: "Name of the account in which the environment can be found"
15
+ method_option :verbose, type: :boolean, aliases: %w(-v),
16
+ desc: "Be verbose"
17
17
  def enable
18
18
  app_env = fetch_app_environment(options[:app], options[:environment], options[:account])
19
19
  ui.info "Taking down maintenance page for '#{app_env.app.name}' in '#{app_env.environment.name}'"
@@ -33,17 +33,17 @@ module EY
33
33
  * public/maintenance.html
34
34
  * public/system/maintenance.html.default
35
35
  DESC
36
- method_option :environment, :type => :string, :aliases => %w(-e),
37
- :required => true, :default => '',
38
- :desc => "Environment on which to put up the maintenance page"
39
- method_option :app, :type => :string, :aliases => %w(-a),
40
- :required => true, :default => '',
41
- :desc => "Name of the application whose maintenance page will be put up"
42
- method_option :account, :type => :string, :aliases => %w(-c),
43
- :required => true, :default => '',
44
- :desc => "Name of the account in which the environment can be found"
45
- method_option :verbose, :type => :boolean, :aliases => %w(-v),
46
- :desc => "Be verbose"
36
+ method_option :environment, type: :string, aliases: %w(-e),
37
+ required: true, default: '',
38
+ desc: "Environment on which to put up the maintenance page"
39
+ method_option :app, type: :string, aliases: %w(-a),
40
+ required: true, default: '',
41
+ desc: "Name of the application whose maintenance page will be put up"
42
+ method_option :account, type: :string, aliases: %w(-c),
43
+ required: true, default: '',
44
+ desc: "Name of the account in which the environment can be found"
45
+ method_option :verbose, type: :boolean, aliases: %w(-v),
46
+ desc: "Be verbose"
47
47
  def disable
48
48
  app_env = fetch_app_environment(options[:app], options[:environment], options[:account])
49
49
  ui.info "Putting up maintenance page for '#{app_env.app.name}' in '#{app_env.environment.name}'"
@@ -59,17 +59,17 @@ module EY
59
59
 
60
60
  Note: Uses the version of the ey.yml currently checked out on the servers.
61
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"
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
73
  def restart
74
74
  app_env = fetch_app_environment(options[:app], options[:environment], options[:account])
75
75
  ui.info "Restarting servers on #{app_env.hierarchy_name}"
@@ -71,9 +71,9 @@ module EY
71
71
  def instances_data(instances, bridge)
72
72
  instances.map do |i|
73
73
  {
74
- :hostname => i.hostname == bridge ? 'localhost' : i.hostname,
75
- :roles => [i.role],
76
- :name => i.name,
74
+ hostname: i.hostname == bridge ? 'localhost' : i.hostname,
75
+ roles: [i.role],
76
+ name: i.name,
77
77
  }
78
78
  end
79
79
  end
@@ -115,7 +115,8 @@ Authentication Failed. Things to fix:
115
115
  level = debug.downcase.to_sym
116
116
  end
117
117
  end
118
- {:paranoid => false, :verbose => level, :keepalive => true, :keepalive_interval => 60}
118
+
119
+ {paranoid: false, verbose: level, keepalive: true, keepalive_interval: 60}
119
120
  end
120
121
 
121
122
  def ssh(cmd, hostname, username, out, err)
@@ -143,6 +144,9 @@ Authentication Failed. Things to fix:
143
144
  channel.on_request("exit-signal") do |_, data|
144
145
  exit_code = 255
145
146
  end
147
+
148
+ # sending eof declares no more data coming from this end (close stdin)
149
+ channel.eof!
146
150
  end
147
151
  end
148
152
 
@@ -38,7 +38,10 @@ defaults:
38
38
  #
39
39
  # By default, assets are detected using app/assets and config/application.rb.
40
40
  #
41
- # If you use rails assets, set this to true.
41
+ # If you use rails assets and you want Engine Yard to compile your assets
42
+ # during deploy, set this to true. If you want to compile assets locally
43
+ # before deploy, set this to false. Make sure you add `public/assets` to
44
+ # `.gitignore` if you want Engine Yard to precompile your assets.
42
45
  #
43
46
  # For more control over assets, set precompile_assets: false and
44
47
  # run your precompile task in the deploy/before_compile_assets.rb deploy hook.
@@ -31,11 +31,11 @@ module EY
31
31
 
32
32
  def serverside_runner(app_env, verbose, serverside_version = serverside_version, ignore_bad_bridge = false)
33
33
  ServersideRunner.new({
34
- :bridge => app_env.environment.bridge!(ignore_bad_bridge).hostname,
35
- :app => app_env.app,
36
- :environment => app_env.environment,
37
- :verbose => verbose,
38
- :serverside_version => serverside_version
34
+ bridge: app_env.environment.bridge!(ignore_bad_bridge).hostname,
35
+ app: app_env.app,
36
+ environment: app_env.environment,
37
+ verbose: verbose,
38
+ serverside_version: serverside_version
39
39
  })
40
40
  end
41
41
 
@@ -52,9 +52,9 @@ module EY
52
52
  environment_name ||= use_default_environment
53
53
  remotes = repo.remotes if in_repo?
54
54
  constraints = {
55
- :environment_name => environment_name,
56
- :account_name => account_name,
57
- :remotes => remotes,
55
+ environment_name: environment_name,
56
+ account_name: account_name,
57
+ remotes: remotes,
58
58
  }
59
59
 
60
60
  resolver = api.resolve_environments(constraints)
@@ -84,10 +84,10 @@ module EY
84
84
  environment_name ||= use_default_environment
85
85
  remotes = repo.remotes if in_repo?
86
86
  constraints = {
87
- :app_name => app_name,
88
- :environment_name => environment_name,
89
- :account_name => account_name,
90
- :remotes => remotes,
87
+ app_name: app_name,
88
+ environment_name: environment_name,
89
+ account_name: account_name,
90
+ remotes: remotes,
91
91
  }
92
92
 
93
93
  if constraints.all? { |k,v| v.nil? || v.empty? || v.to_s.empty? }
@@ -1,4 +1,4 @@
1
1
  module EY
2
- VERSION = '2.3.3'
3
- ENGINEYARD_SERVERSIDE_VERSION = ENV['ENGINEYARD_SERVERSIDE_VERSION'] || '2.3.9'
2
+ VERSION = '3.0.0'
3
+ ENGINEYARD_SERVERSIDE_VERSION = ENV['ENGINEYARD_SERVERSIDE_VERSION'] || '2.4.2'
4
4
  end
@@ -0,0 +1,176 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for "running ey scp" do
4
+ given "integration"
5
+
6
+ def extra_ey_options
7
+ {:prepend_to_path => {'scp' => "#!/bin/sh\necho scp $*"}}
8
+ end
9
+ end
10
+
11
+ shared_examples_for "running ey scp for select role" do
12
+ given "integration"
13
+
14
+ def extra_ey_options
15
+ {:prepend_to_path => {'scp' => "#!/bin/sh\necho scp $*"}}
16
+ end
17
+
18
+ def command_to_run(opts)
19
+ cmd = ["scp", opts[:from], opts[:to]].compact + (@scp_flag || [])
20
+ cmd << "--environment" << opts[:environment] if opts[:environment]
21
+ cmd << "--quiet" if opts[:quiet]
22
+ cmd
23
+ end
24
+
25
+ it "runs the command on the right servers" do
26
+ login_scenario "one app, one environment"
27
+ ey command_to_run(from: "from", to: "to", environment: 'giblets', verbose: true)
28
+ @hosts.each do |host_prefix|
29
+ @raw_ssh_commands.grep(/^scp from turkey@#{host_prefix}.+:to$/).should_not be_empty
30
+ end
31
+ @raw_ssh_commands.grep(/^scp from turkey@.+:to$/).count.should == @hosts.count
32
+ end
33
+
34
+ it "is quiet" do
35
+ login_scenario "one app, one environment"
36
+ ey command_to_run(from: "from", to: "to", environment: 'giblets', quiet: true)
37
+ @out.should =~ /scp.*from.*to/
38
+ @out.should_not =~ /Loading application data/
39
+ end
40
+
41
+ it "raises an error when there are no matching hosts" do
42
+ login_scenario "one app, one environment, no instances"
43
+ ey command_to_run({from: "from", to: "to", environment: 'giblets', verbose: true}), expect_failure: true
44
+ end
45
+
46
+ it "errors correctly when no file paths are specified" do
47
+ login_scenario "one app, one environment"
48
+ ey command_to_run({environment: 'giblets', verbose: true}), expect_failure: true
49
+ ey command_to_run({from: "from", environment: 'giblets', verbose: true}), expect_failure: true
50
+ end
51
+ end
52
+
53
+ describe "ey scp" do
54
+ include_examples "running ey scp"
55
+
56
+ before(:all) do
57
+ login_scenario "one app, many environments"
58
+ end
59
+
60
+ it "complains if it has no app master" do
61
+ ey %w[scp from to -e bakon], :expect_failure => true
62
+ @err.should =~ /'bakon' does not have any matching instances/
63
+ end
64
+
65
+ end
66
+
67
+ describe "ey scp with an ambiguous git repo" do
68
+ include_examples "running ey scp"
69
+ def command_to_run(_) %w[scp from to] end
70
+ include_examples "it requires an unambiguous git repo"
71
+ end
72
+
73
+ describe "ey scp" do
74
+ include_examples "running ey scp"
75
+
76
+ def command_to_run(opts)
77
+ cmd = %w[scp HOST:from to]
78
+ cmd << "--environment" << opts[:environment] if opts[:environment]
79
+ cmd << "--account" << opts[:account] if opts[:account]
80
+ cmd
81
+ end
82
+
83
+ def verify_ran(scenario)
84
+ scp_target = scenario[:ssh_username] + '@' + scenario[:master_hostname]
85
+ @raw_ssh_commands.should == ["scp #{scp_target}:from to"]
86
+ end
87
+
88
+ include_examples "it takes an environment name and an account name"
89
+ end
90
+
91
+ describe "ey scp --all" do
92
+ before do
93
+ @scp_flag = %w[--all]
94
+ @hosts = %w(app_hostname
95
+ app_master_hostname
96
+ util_fluffy_hostname
97
+ util_rocky_hostname
98
+ db_master_hostname
99
+ db_slave_1_hostname
100
+ db_slave_2_hostname)
101
+ end
102
+
103
+ include_examples "running ey scp"
104
+ include_examples "running ey scp for select role"
105
+ end
106
+
107
+ describe "ey scp --app-servers" do
108
+ before do
109
+ @scp_flag = %w[--app-servers]
110
+ @hosts = %w(app_hostname app_master_hostname)
111
+ end
112
+
113
+ include_examples "running ey scp"
114
+ include_examples "running ey scp for select role"
115
+ end
116
+
117
+ describe "ey scp --db-master" do
118
+ before do
119
+ @scp_flag = %w[--db-master]
120
+ @hosts = %w(db_master_hostname)
121
+ end
122
+
123
+ include_examples "running ey scp"
124
+ include_examples "running ey scp for select role"
125
+ end
126
+
127
+ describe "ey scp --db-slaves" do
128
+ before do
129
+ @scp_flag = %w[--db-slaves]
130
+ @hosts = %w(db_slave_1_hostname db_slave_2_hostname)
131
+ end
132
+
133
+ include_examples "running ey scp"
134
+ include_examples "running ey scp for select role"
135
+ end
136
+
137
+ describe "ey scp --db-servers" do
138
+ before do
139
+ @scp_flag = %w[--db-servers]
140
+ @hosts = %w(db_master_hostname db_slave_1_hostname db_slave_2_hostname)
141
+ end
142
+
143
+ include_examples "running ey scp"
144
+ include_examples "running ey scp for select role"
145
+ end
146
+
147
+ describe "ey scp --utilities" do
148
+ before do
149
+ @scp_flag = %w[--utilities]
150
+ @hosts = %w(util_fluffy_hostname util_rocky_hostname)
151
+ end
152
+
153
+ include_examples "running ey scp"
154
+ include_examples "running ey scp for select role"
155
+ end
156
+
157
+ describe "ey scp --utilities fluffy" do
158
+ before do
159
+ @scp_flag = %w[--utilities fluffy]
160
+ @hosts = %w(util_fluffy_hostname)
161
+ end
162
+
163
+ include_examples "running ey scp"
164
+ include_examples "running ey scp for select role"
165
+ end
166
+
167
+ describe "ey scp --utilities fluffy rocky" do
168
+ before do
169
+ @scp_flag = %w[--utilities fluffy rocky]
170
+ @hosts = %w(util_fluffy_hostname util_rocky_hostname)
171
+ end
172
+
173
+ include_examples "running ey scp"
174
+ include_examples "running ey scp for select role"
175
+ end
176
+