bosh_aws_cpi 1.2652.0 → 1.2657.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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