bosh_aws_cpi 1.2652.0 → 1.2657.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 16fa136873ef1c5afd91bd2a6afed01422320639
4
- data.tar.gz: ad15b66bf0ae287aea2a64d7a8bcb221dd9408cb
3
+ metadata.gz: de2813b880f8bd8f982bc621d778f0107b8e0059
4
+ data.tar.gz: 740352254379a1afd8566fa9ce725316e12c4464
5
5
  SHA512:
6
- metadata.gz: 0e53dc52949f467b740f8d7dbd51a7de87fc99cc5bb28399f8fbd672caaf8e3b07a929acb882e3fdb70849f9e06ee8c924fd558d4bdbd8adf453776fd9122011
7
- data.tar.gz: 868b9a3e5c677b7e4dc95ad5d6daa87dcb664b65b2cda73e49bb0425888d841425d2e01250de0623e8d416f3d3f56e1b0b91f1d5bbf963b9d415e83f417d949e
6
+ metadata.gz: ac882c156c0793a3083cb00b81e849bb10725cfbbf614500de7dd0b41a47a847c1d5dceac7cb436f37b465673111e576fe6db0e73a660d435a344c29d36d258b
7
+ data.tar.gz: 3920789f8cc8f2110afcd514f0d32a367c556f68bac8e3a1b4d83bd084433f93e879db324faab50141c41bf77ae39a3fa3e85553ba0961b6a08a2381e9c7d081
@@ -31,6 +31,10 @@ module Bosh::AwsCloud
31
31
  initialize_aws
32
32
  initialize_registry
33
33
 
34
+ elb = AWS::ELB.new
35
+
36
+ @instance_manager = InstanceManager.new(region, registry, elb, az_selector, @logger)
37
+
34
38
  @metadata_lock = Mutex.new
35
39
  end
36
40
 
@@ -84,26 +88,32 @@ module Bosh::AwsCloud
84
88
  stemcell = StemcellFinder.find_by_region_and_id(region, stemcell_id)
85
89
 
86
90
  begin
87
- instance_manager = InstanceManager.new(region, registry, az_selector)
88
- instance = instance_manager.
89
- create(agent_id, stemcell.image_id, resource_pool, network_spec, (disk_locality || []), environment, options)
91
+ instance = @instance_manager.create(
92
+ agent_id,
93
+ stemcell.image_id,
94
+ resource_pool,
95
+ network_spec,
96
+ (disk_locality || []),
97
+ environment,
98
+ options,
99
+ )
90
100
 
91
101
  logger.info("Creating new instance '#{instance.id}'")
92
102
 
93
103
  NetworkConfigurator.new(network_spec).configure(region, instance)
94
104
 
95
105
  registry_settings = initial_agent_settings(
96
- agent_id,
97
- network_spec,
98
- environment,
99
- stemcell.root_device_name,
106
+ agent_id,
107
+ network_spec,
108
+ environment,
109
+ stemcell.root_device_name,
100
110
  )
101
111
  registry.update_settings(instance.id, registry_settings)
102
112
 
103
113
  instance.id
104
114
  rescue => e # is this rescuing too much?
105
115
  logger.error(%Q[Failed to create instance: #{e.message}\n#{e.backtrace.join("\n")}])
106
- instance_manager.terminate(instance.id, fast_path_delete?) if instance
116
+ instance.terminate(fast_path_delete?) if instance
107
117
  raise e
108
118
  end
109
119
  end
@@ -124,7 +134,7 @@ module Bosh::AwsCloud
124
134
  def delete_vm(instance_id)
125
135
  with_thread_name("delete_vm(#{instance_id})") do
126
136
  logger.info("Deleting instance '#{instance_id}'")
127
- InstanceManager.new(region, registry).terminate(instance_id, fast_path_delete?)
137
+ @instance_manager.find(instance_id).terminate(fast_path_delete?)
128
138
  end
129
139
  end
130
140
 
@@ -133,7 +143,7 @@ module Bosh::AwsCloud
133
143
  # @param [String] instance_id EC2 instance id
134
144
  def reboot_vm(instance_id)
135
145
  with_thread_name("reboot_vm(#{instance_id})") do
136
- InstanceManager.new(region, registry).reboot(instance_id)
146
+ @instance_manager.find(instance_id).reboot
137
147
  end
138
148
  end
139
149
 
@@ -142,7 +152,7 @@ module Bosh::AwsCloud
142
152
  # @param [String] instance_id EC2 instance id
143
153
  def has_vm?(instance_id)
144
154
  with_thread_name("has_vm?(#{instance_id})") do
145
- InstanceManager.new(region, registry).has_instance?(instance_id)
155
+ @instance_manager.find(instance_id).exists?
146
156
  end
147
157
  end
148
158
 
@@ -0,0 +1,102 @@
1
+ module Bosh::AwsCloud
2
+ class Instance
3
+ def initialize(aws_instance, registry, elb, logger)
4
+ @aws_instance = aws_instance
5
+ @registry = registry
6
+ @elb = elb
7
+ @logger = logger
8
+ end
9
+
10
+ def id
11
+ @aws_instance.id
12
+ end
13
+
14
+ def elastic_ip
15
+ @aws_instance.elastic_ip
16
+ end
17
+
18
+ def associate_elastic_ip(elastic_ip)
19
+ @aws_instance.associate_elastic_ip(elastic_ip)
20
+ end
21
+
22
+ def disassociate_elastic_ip
23
+ @aws_instance.disassociate_elastic_ip
24
+ end
25
+
26
+ def wait_for_running
27
+ # If we time out, it is because the instance never gets from state running to started,
28
+ # so we signal the director that it is ok to retry the operation. At the moment this
29
+ # forever (until the operation is cancelled by the user).
30
+ begin
31
+ @logger.info("Waiting for instance to be ready...")
32
+ ResourceWait.for_instance(instance: @aws_instance, state: :running)
33
+ rescue Bosh::Common::RetryCountExceeded
34
+ @logger.warn("Timed out waiting for instance '#{aws_instance.id}' to be running")
35
+ raise Bosh::Clouds::VMCreationFailed.new(true)
36
+ end
37
+ end
38
+
39
+ # Soft reboots EC2 instance
40
+ def reboot
41
+ # There is no trackable status change for the instance being
42
+ # rebooted, so it's up to CPI client to keep track of agent
43
+ # being ready after reboot.
44
+ # Due to this, we can't deregister the instance from any load
45
+ # balancers it might be attached to, and reattach once the
46
+ # reboot is complete, so we just have to let the load balancers
47
+ # take the instance out of rotation, and put it back in once it
48
+ # is back up again.
49
+ @aws_instance.reboot
50
+ end
51
+
52
+ def terminate(fast=false)
53
+ remove_from_load_balancers
54
+
55
+ begin
56
+ @aws_instance.terminate
57
+ rescue AWS::EC2::Errors::InvalidInstanceID::NotFound => e
58
+ @logger.warn("Failed to terminate instance '#{@aws_instance.id}' because it was not found: #{e.inspect}")
59
+ raise Bosh::Clouds::VMNotFound, "VM `#{@aws_instance.id}' not found"
60
+ ensure
61
+ @logger.info("Deleting instance settings for '#{@aws_instance.id}'")
62
+ @registry.delete_settings(@aws_instance.id)
63
+ end
64
+
65
+ if fast
66
+ TagManager.tag(@aws_instance, "Name", "to be deleted")
67
+ @logger.info("Instance #{@aws_instance.id} marked to deletion")
68
+ return
69
+ end
70
+
71
+ begin
72
+ @logger.info("Deleting instance '#{@aws_instance.id}'")
73
+ ResourceWait.for_instance(instance: @aws_instance, state: :terminated)
74
+ rescue AWS::EC2::Errors::InvalidInstanceID::NotFound => e
75
+ @logger.debug("Failed to find terminated instance '#{@aws_instance.id}' after deletion: #{e.inspect}")
76
+ # It's OK, just means that instance has already been deleted
77
+ end
78
+ end
79
+
80
+ # Determines if the instance exists.
81
+ def exists?
82
+ @aws_instance.exists? && @aws_instance.status != :terminated
83
+ end
84
+
85
+ def attach_to_load_balancers(load_balancer_ids)
86
+ load_balancer_ids.each do |load_balancer_id|
87
+ lb = @elb.load_balancers[load_balancer_id]
88
+ lb.instances.register(@aws_instance)
89
+ end
90
+ end
91
+
92
+ def remove_from_load_balancers
93
+ @elb.load_balancers.each do |load_balancer|
94
+ begin
95
+ load_balancer.instances.deregister(@aws_instance)
96
+ rescue AWS::ELB::Errors::InvalidInstance
97
+ # ignore this, as it just means it wasn't registered
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -5,37 +5,38 @@ module Bosh::AwsCloud
5
5
  class InstanceManager
6
6
  include Helpers
7
7
 
8
- attr_reader :instance
9
- attr_reader :instance_params
10
- attr_reader :elbs
11
-
12
- def initialize(region, registry, az_selector=nil)
8
+ def initialize(region, registry, elb, az_selector, logger)
13
9
  @region = region
14
10
  @registry = registry
15
- @logger = Bosh::Clouds::Config.logger
11
+ @elb = elb
16
12
  @az_selector = az_selector
17
- @instance_params = {count: 1}
13
+ @logger = logger
18
14
  end
19
15
 
20
16
  def create(agent_id, stemcell_id, resource_pool, networks_spec, disk_locality, environment, options)
21
- @instance_params[:image_id] = stemcell_id
22
- @instance_params[:instance_type] = resource_pool["instance_type"]
23
- set_user_data_parameter(networks_spec)
24
- set_key_name_parameter(resource_pool["key_name"], options["aws"]["default_key_name"])
25
- set_security_groups_parameter(networks_spec, options["aws"]["default_security_groups"])
26
- set_vpc_parameters(networks_spec)
17
+ instance_params = {count: 1}
18
+ instance_params[:image_id] = stemcell_id
19
+ instance_params[:instance_type] = resource_pool["instance_type"]
20
+
21
+ set_user_data_parameter(instance_params, networks_spec)
22
+ set_key_name_parameter(instance_params, resource_pool["key_name"], options["aws"]["default_key_name"])
23
+ set_security_groups_parameter(instance_params, networks_spec, options["aws"]["default_security_groups"])
24
+ set_vpc_parameters(instance_params, networks_spec)
25
+
27
26
  set_availability_zone_parameter(
28
- (disk_locality || []).map { |volume_id| @region.volumes[volume_id].availability_zone.to_s },
29
- resource_pool["availability_zone"],
30
- (@instance_params[:subnet].availability_zone_name if @instance_params[:subnet])
27
+ instance_params,
28
+ (disk_locality || []).map { |volume_id| @region.volumes[volume_id].availability_zone.to_s },
29
+ resource_pool["availability_zone"],
30
+ (instance_params[:subnet].availability_zone_name if instance_params[:subnet])
31
31
  )
32
-
32
+
33
33
  @logger.info("Creating new instance with: #{instance_params.inspect}")
34
-
34
+
35
+ aws_instance = nil
35
36
  if resource_pool["spot_bid_price"]
36
37
  @logger.info("Launching spot instance...")
37
38
  spot_manager = Bosh::AwsCloud::SpotManager.new(@region)
38
- @instance = spot_manager.create(instance_params, resource_pool["spot_bid_price"])
39
+ aws_instance = spot_manager.create(instance_params, resource_pool["spot_bid_price"])
39
40
  else
40
41
  # Retry the create instance operation a couple of times if we are told that the IP
41
42
  # address is in use - it can happen when the director recreates a VM and AWS
@@ -43,111 +44,43 @@ module Bosh::AwsCloud
43
44
  # realocate it again.
44
45
  errors = [AWS::EC2::Errors::InvalidIPAddress::InUse]
45
46
  Bosh::Common.retryable(sleep: instance_create_wait_time, tries: 10, on: errors) do |tries, error|
46
- @logger.info("Launching on demand instance...")
47
+ @logger.info("Launching on demand instance...")
47
48
  @logger.warn("IP address was in use: #{error}") if tries > 0
48
- @instance = @region.instances.create(instance_params)
49
+ aws_instance = @region.instances.create(instance_params)
49
50
  end
50
- end
51
-
52
- # We need to wait here for the instance to be running, as if we are going to
53
- # attach to a load balancer, the instance must be running.
54
- # If we time out, it is because the instance never gets from state running to started,
55
- # so we signal the director that it is ok to retry the operation. At the moment this
56
- # forever (until the operation is cancelled by the user).
57
- begin
58
- @logger.info("Waiting for instance to be ready...")
59
- ResourceWait.for_instance(instance: instance, state: :running)
60
- rescue Bosh::Common::RetryCountExceeded => e
61
- @logger.warn("timed out waiting for #{instance.id} to be running")
62
- raise Bosh::Clouds::VMCreationFailed.new(true)
63
- end
64
-
65
- @elbs = resource_pool['elbs']
66
- attach_to_load_balancers if elbs
67
-
68
- instance
69
- end
70
-
71
- def terminate(instance_id, fast=false)
72
- @instance = @region.instances[instance_id]
73
-
74
- remove_from_load_balancers
75
-
76
- begin
77
- instance.terminate
78
- rescue AWS::EC2::Errors::InvalidInstanceID::NotFound => e
79
- @logger.info("Failed to terminate instance because it was not found: #{e.inspect}")
80
- raise Bosh::Clouds::VMNotFound, "VM `#{instance_id}' not found"
81
- ensure
82
- @logger.info("Deleting instance settings for '#{instance_id}'")
83
- @registry.delete_settings(instance_id)
84
51
  end
85
52
 
86
- if fast
87
- TagManager.tag(instance, "Name", "to be deleted")
88
- @logger.info("Instance #{instance_id} marked to deletion")
89
- return
90
- end
53
+ instance = Instance.new(aws_instance, @registry, @elb, @logger)
91
54
 
92
55
  begin
93
- @logger.info("Deleting instance '#{instance.id}'")
94
- ResourceWait.for_instance(instance: instance, state: :terminated)
95
- rescue AWS::EC2::Errors::InvalidInstanceID::NotFound
96
- # It's OK, just means that instance has already been deleted
56
+ # We need to wait here for the instance to be running, as if we are going to
57
+ # attach to a load balancer, the instance must be running.
58
+ instance.wait_for_running
59
+ instance.attach_to_load_balancers(resource_pool['elbs'] || [])
60
+ rescue => e
61
+ @logger.warn("Failed to configure instance '#{instance.id}': #{e.inspect}")
62
+ begin
63
+ instance.terminate
64
+ rescue => e
65
+ @logger.error("Failed to terminate mis-configured instance '#{instance.id}': #{e.inspect}")
66
+ end
67
+ raise
97
68
  end
98
- end
99
-
100
- # Soft reboots EC2 instance
101
- # @param [String] instance_id EC2 instance id
102
- def reboot(instance_id)
103
- instance = @region.instances[instance_id]
104
-
105
- # There is no trackable status change for the instance being
106
- # rebooted, so it's up to CPI client to keep track of agent
107
- # being ready after reboot.
108
- # Due to this, we can't deregister the instance from any load
109
- # balancers it might be attached to, and reattach once the
110
- # reboot is complete, so we just have to let the load balancers
111
- # take the instance out of rotation, and put it back in once it
112
- # is back up again.
113
- instance.reboot
114
- end
115
69
 
116
- def attach_to_load_balancers
117
- elb = AWS::ELB.new
118
-
119
- elbs.each do |load_balancer|
120
- lb = elb.load_balancers[load_balancer]
121
- lb.instances.register(instance)
122
- end
70
+ instance
123
71
  end
124
72
 
125
- # Determines if the instance exists.
126
73
  # @param [String] instance_id EC2 instance id
127
- def has_instance?(instance_id)
128
- instance = @region.instances[instance_id]
129
-
130
- instance.exists? && instance.status != :terminated
74
+ def find(instance_id)
75
+ Instance.new(@region.instances[instance_id], @registry, @elb, @logger)
131
76
  end
132
77
 
133
- def remove_from_load_balancers
134
- elb = AWS::ELB.new
135
-
136
- elb.load_balancers.each do |load_balancer|
137
- begin
138
- load_balancer.instances.deregister(instance)
139
- rescue AWS::ELB::Errors::InvalidInstance
140
- # ignore this, as it just means it wasn't registered
141
- end
142
- end
143
- end
144
-
145
- def set_key_name_parameter(resource_pool_key_name, default_aws_key_name)
78
+ def set_key_name_parameter(instance_params, resource_pool_key_name, default_aws_key_name)
146
79
  key_name = resource_pool_key_name || default_aws_key_name
147
80
  instance_params[:key_name] = key_name unless key_name.nil?
148
81
  end
149
82
 
150
- def set_security_groups_parameter(networks_spec, default_security_groups)
83
+ def set_security_groups_parameter(instance_params, networks_spec, default_security_groups)
151
84
  security_group_names = extract_security_group_names(networks_spec)
152
85
  if security_group_names.empty?
153
86
  instance_params[:security_groups] = default_security_groups
@@ -156,33 +89,33 @@ module Bosh::AwsCloud
156
89
  end
157
90
  end
158
91
 
159
- def set_vpc_parameters(network_spec)
92
+ def set_vpc_parameters(instance_params, network_spec)
160
93
  manual_network_spec = network_spec.values.select { |spec| ["manual", nil].include? spec["type"] }.first
161
94
  if manual_network_spec
162
95
  instance_params[:private_ip_address] = manual_network_spec["ip"]
163
96
  end
164
-
165
- subnet_network_spec = network_spec.values.select { |spec|
166
- ["manual", nil, "dynamic"].include?(spec["type"]) &&
97
+
98
+ subnet_network_spec = network_spec.values.select { |spec|
99
+ ["manual", nil, "dynamic"].include?(spec["type"]) &&
167
100
  spec.fetch("cloud_properties", {}).has_key?("subnet")
168
101
  }.first
169
102
  if subnet_network_spec
170
103
  instance_params[:subnet] = @region.subnets[subnet_network_spec["cloud_properties"]["subnet"]]
171
- end
104
+ end
172
105
  end
173
106
 
174
- def set_availability_zone_parameter(volume_zones, resource_pool_zone, subnet_zone)
107
+ def set_availability_zone_parameter(instance_params, volume_zones, resource_pool_zone, subnet_zone)
175
108
  availability_zone = @az_selector.common_availability_zone(volume_zones, resource_pool_zone, subnet_zone)
176
109
  instance_params[:availability_zone] = availability_zone if availability_zone
177
110
  end
178
111
 
179
- def set_user_data_parameter(networks_spec)
112
+ def set_user_data_parameter(instance_params, networks_spec)
180
113
  user_data = {registry: {endpoint: @registry.endpoint}}
181
114
 
182
115
  spec_with_dns = networks_spec.values.select { |spec| spec.has_key? "dns" }.first
183
116
  user_data[:dns] = {nameserver: spec_with_dns["dns"]} if spec_with_dns
184
117
 
185
- @instance_params[:user_data] = Yajl::Encoder.encode(user_data)
118
+ instance_params[:user_data] = Yajl::Encoder.encode(user_data)
186
119
  end
187
120
 
188
121
  private
@@ -1,5 +1,5 @@
1
1
  module Bosh
2
2
  module AwsCloud
3
- VERSION = '1.2652.0'
3
+ VERSION = '1.2657.0'
4
4
  end
5
5
  end
data/lib/cloud/aws.rb CHANGED
@@ -32,6 +32,7 @@ require "cloud/aws/dynamic_network"
32
32
  require "cloud/aws/manual_network"
33
33
  require "cloud/aws/vip_network"
34
34
  require "cloud/aws/instance_manager"
35
+ require "cloud/aws/instance"
35
36
  require "cloud/aws/spot_manager"
36
37
  require "cloud/aws/tag_manager"
37
38
  require "cloud/aws/availability_zone_selector"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bosh_aws_cpi
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2652.0
4
+ version: 1.2657.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - VMware
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-19 00:00:00.000000000 Z
11
+ date: 2014-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk
@@ -30,42 +30,42 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.2652.0
33
+ version: 1.2657.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 1.2652.0
40
+ version: 1.2657.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bosh_cpi
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 1.2652.0
47
+ version: 1.2657.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 1.2652.0
54
+ version: 1.2657.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bosh-registry
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 1.2652.0
61
+ version: 1.2657.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 1.2652.0
68
+ version: 1.2657.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: httpclient
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -96,7 +96,7 @@ dependencies:
96
96
  version: 0.8.2
97
97
  description: |-
98
98
  BOSH AWS CPI
99
- 43d2e8
99
+ a6c527
100
100
  email: support@cloudfoundry.com
101
101
  executables:
102
102
  - bosh_aws_console
@@ -112,6 +112,7 @@ files:
112
112
  - lib/cloud/aws/cloud.rb
113
113
  - lib/cloud/aws/dynamic_network.rb
114
114
  - lib/cloud/aws/helpers.rb
115
+ - lib/cloud/aws/instance.rb
115
116
  - lib/cloud/aws/instance_manager.rb
116
117
  - lib/cloud/aws/light_stemcell.rb
117
118
  - lib/cloud/aws/manual_network.rb