bosh-director 1.3196.0 → 1.3197.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: d7c6f7bf6221c4fa4f4b7caf35e9d55337756e64
4
- data.tar.gz: a828b6b9c5aea0d6b621f457b5574342e6bf1c99
3
+ metadata.gz: 20232eba24a87aea3baeb18ec4b1a6933b661478
4
+ data.tar.gz: 02fa2dec119dc01d11893d142579b5c185c4a8a2
5
5
  SHA512:
6
- metadata.gz: 5aab58e79857bfb1fad27ba5591c0e6521e76d969efe8237b5264d4a4ddade8bfa40345c08ab687d76872223fcb172a4b0d6261ba340b82268fa930d74626a0f
7
- data.tar.gz: 9c3cb7905dd55bfc74bac1e82c20b782694ec065af62d8bc4ddc4abcae80afd05cacda16cdace6f6adafaa9c7cf09f889e537b4982fa9423b80d3d04230280aa
6
+ metadata.gz: 9bbfa06bc2fbd42e883c3c22e54b297b6ac66e5bf31f690156b52f0830ff2918cc90ad84f4e1808aeb9499f18d2c14eb379083afc4e4bfa05a912cda5e1b2706
7
+ data.tar.gz: 31245c2728449b30782468433d65febcad7c2b1bf3373f486537a8eef7c14f3279cba64a90266c0632dad62cd6dfdc48fdd6ea5c33f059167c848bf872f2e421
@@ -87,7 +87,7 @@ module Bosh::Director
87
87
  def create_instance_plan(instance_model, vm_env)
88
88
  vm_type = DeploymentPlan::VmType.new(instance_model.spec['vm_type'])
89
89
  env = DeploymentPlan::Env.new(vm_env)
90
- stemcell = DeploymentPlan::Stemcell.new(instance_model.spec['stemcell'])
90
+ stemcell = DeploymentPlan::Stemcell.parse(instance_model.spec['stemcell'])
91
91
  stemcell.add_stemcell_model
92
92
  availability_zone = DeploymentPlan::AvailabilityZone.new(instance_model.availability_zone, instance_model.cloud_properties_hash)
93
93
 
@@ -128,13 +128,13 @@ module Bosh::Director
128
128
  "Stemcell not bound for resource pool `#{resource_pool.name}'"
129
129
  end
130
130
 
131
- stemcell.bind_model(@deployment_plan)
131
+ stemcell.bind_model(@deployment_plan.model)
132
132
  end
133
133
  return
134
134
  end
135
135
 
136
136
  @deployment_plan.stemcells.each do |_, stemcell|
137
- stemcell.bind_model(@deployment_plan)
137
+ stemcell.bind_model(@deployment_plan.model)
138
138
  end
139
139
  end
140
140
 
@@ -1,36 +1,27 @@
1
1
  module Bosh::Director
2
2
  module DeploymentPlan
3
3
  class CompilationInstancePool
4
- def initialize(instance_reuser, vm_creator, deployment_plan, logger, instance_deleter)
4
+ def initialize(instance_reuser, vm_creator, deployment_plan, logger, instance_deleter, max_instance_count)
5
5
  @instance_reuser = instance_reuser
6
- @vm_creator = vm_creator
7
- @deployment_plan = deployment_plan
8
6
  @logger = logger
9
7
  @instance_deleter = instance_deleter
8
+ @max_instance_count = max_instance_count
9
+ @instance_provider = InstanceProvider.new(deployment_plan, vm_creator, logger)
10
+ @mutex = Mutex.new
10
11
  end
11
12
 
12
13
  def with_reused_vm(stemcell)
13
14
  begin
14
- instance = @instance_reuser.get_instance(stemcell)
15
- if instance.nil?
16
- instance_plan, instance = create_instance_plan(stemcell)
17
- configure_instance_plan(instance_plan)
18
- @instance_reuser.add_in_use_instance(instance_plan.instance, stemcell)
19
- else
20
- @logger.info("Reusing compilation VM `#{instance.model.vm_cid}' for stemcell `#{stemcell.model.desc}'")
21
- end
22
-
23
- yield instance
24
-
25
- @instance_reuser.release_instance(instance)
15
+ instance_memo = obtain_instance_memo(stemcell)
16
+ yield instance_memo.instance
17
+ release_instance(instance_memo)
26
18
  rescue => e
27
- unless instance.nil? || instance_plan.nil?
28
- @instance_reuser.remove_instance(instance)
29
-
19
+ remove_instance(instance_memo)
20
+ unless instance_memo.instance_plan.nil?
30
21
  if Config.keep_unreachable_vms
31
22
  @logger.info('Keeping reused compilation VM for debugging')
32
23
  else
33
- delete_instance(instance_plan)
24
+ destroy_instance(instance_memo.instance_plan)
34
25
  end
35
26
  end
36
27
  raise e
@@ -40,32 +31,31 @@ module Bosh::Director
40
31
  def with_single_use_vm(stemcell)
41
32
  begin
42
33
  keep_failing_vm = false
43
- instance_plan, instance = create_instance_plan(stemcell)
44
- configure_instance_plan(instance_plan)
45
- yield instance
34
+ instance_memo = InstanceMemo.new(@instance_provider, stemcell)
35
+ yield instance_memo.instance
46
36
  rescue => e
47
37
  @logger.info('Keeping single-use compilation VM for debugging')
48
38
  keep_failing_vm = Config.keep_unreachable_vms
49
39
  raise e
50
40
  ensure
51
- unless instance.nil? || keep_failing_vm
52
- delete_instance(instance_plan)
41
+ unless instance_memo.instance.nil? || keep_failing_vm
42
+ destroy_instance(instance_memo.instance_plan)
53
43
  end
54
44
  end
55
45
  end
56
46
 
57
47
  def delete_instances(number_of_workers)
58
48
  ThreadPool.new(:max_threads => number_of_workers).wrap do |pool|
59
- @instance_reuser.each do |instance|
49
+ @instance_reuser.each do |instance_memo|
60
50
  pool.process do
61
- @instance_reuser.remove_instance(instance)
51
+ @instance_reuser.remove_instance(instance_memo)
62
52
  instance_plan = DeploymentPlan::InstancePlan.new(
63
- existing_instance: instance.model,
64
- instance: instance,
53
+ existing_instance: instance_memo.instance.model,
54
+ instance: instance_memo.instance,
65
55
  desired_instance: DeploymentPlan::DesiredInstance.new,
66
56
  network_plans: []
67
57
  )
68
- delete_instance(instance_plan)
58
+ destroy_instance(instance_plan)
69
59
  end
70
60
  end
71
61
  end
@@ -73,9 +63,50 @@ module Bosh::Director
73
63
 
74
64
  private
75
65
 
76
- def delete_instance(instance_plan)
66
+ def remove_instance(instance_memo)
67
+ @mutex.synchronize do
68
+ @instance_reuser.remove_instance(instance_memo)
69
+ end
70
+ end
71
+
72
+ def release_instance(instance_memo)
73
+ @mutex.synchronize do
74
+ @instance_reuser.release_instance(instance_memo)
75
+ end
76
+ end
77
+
78
+ def obtain_instance_memo(stemcell)
79
+ instance_memo = nil
80
+ @mutex.synchronize do
81
+ instance_memo = @instance_reuser.get_instance(stemcell)
82
+ if instance_memo.nil?
83
+ if @instance_reuser.total_instance_count >= @max_instance_count
84
+ instance_memo = @instance_reuser.remove_idle_instance_not_matching_stemcell(stemcell)
85
+ destroy_instance(instance_memo.instance_plan)
86
+ end
87
+ @logger.debug("Creating new compilation VM for stemcell '#{stemcell.model.desc}'")
88
+ instance_memo = InstanceMemo.new(@instance_provider, stemcell)
89
+ @instance_reuser.add_in_use_instance(instance_memo, stemcell)
90
+ else
91
+ @logger.info("Reusing compilation VM `#{instance_memo.instance.model.vm_cid}' for stemcell `#{stemcell.model.desc}'")
92
+ end
93
+ end
94
+ return instance_memo
95
+ end
96
+
97
+ def destroy_instance(instance_plan)
77
98
  @instance_deleter.delete_instance_plan(instance_plan, EventLog::NullStage.new)
78
99
  end
100
+ end
101
+
102
+ private
103
+
104
+ class InstanceProvider
105
+ def initialize(deployment_plan, vm_creator, logger)
106
+ @deployment_plan = deployment_plan
107
+ @vm_creator = vm_creator
108
+ @logger = logger
109
+ end
79
110
 
80
111
  def create_instance_plan(stemcell)
81
112
  if @deployment_plan.compilation.vm_type
@@ -86,14 +117,14 @@ module Bosh::Director
86
117
 
87
118
  env = Env.new(@deployment_plan.compilation.env)
88
119
 
89
- @compile_job = CompilationJob.new(vm_type, stemcell, env, @deployment_plan.compilation.network_name)
120
+ compile_job = CompilationJob.new(vm_type, stemcell, env, @deployment_plan.compilation.network_name)
90
121
  availability_zone = @deployment_plan.compilation.availability_zone
91
- instance = Instance.create_from_job(@compile_job, 0, 'started', @deployment_plan.model, {}, availability_zone, @logger)
122
+ instance = Instance.create_from_job(compile_job, 0, 'started', @deployment_plan.model, {}, availability_zone, @logger)
92
123
  instance.bind_new_instance_model
93
124
 
94
125
  compilation_network = @deployment_plan.network(@deployment_plan.compilation.network_name)
95
126
  reservation = DesiredNetworkReservation.new_dynamic(instance.model, compilation_network)
96
- desired_instance = DeploymentPlan::DesiredInstance.new(@compile_job, nil)
127
+ desired_instance = DeploymentPlan::DesiredInstance.new(compile_job, nil)
97
128
  instance_plan = DeploymentPlan::InstancePlan.new(
98
129
  existing_instance: instance.model,
99
130
  instance: instance,
@@ -101,18 +132,34 @@ module Bosh::Director
101
132
  network_plans: [DeploymentPlan::NetworkPlanner::Plan.new(reservation: reservation)]
102
133
  )
103
134
 
104
- @compile_job.add_instance_plans([instance_plan])
105
-
106
- return instance_plan, instance
135
+ compile_job.add_instance_plans([instance_plan])
136
+ instance_plan
107
137
  end
108
138
 
109
- def configure_instance_plan(instance_plan)
139
+ def create_instance(instance_plan)
110
140
  @deployment_plan.ip_provider.reserve(instance_plan.network_plans.first.reservation)
111
141
  @vm_creator.create_for_instance_plan(instance_plan, [])
142
+ instance_plan.instance
112
143
  end
113
144
  end
114
145
 
115
- private
146
+ class InstanceMemo
147
+ attr_reader :instance_plan
148
+
149
+ def initialize(instance_provider, stemcell)
150
+ @instance_provider = instance_provider
151
+ @stemcell = stemcell
152
+ end
153
+
154
+ def instance
155
+ return @instance if @called
156
+ @called = true
157
+ @instance_plan = @instance_provider.create_instance_plan(@stemcell)
158
+ @instance = @instance_plan.instance
159
+ @instance_provider.create_instance(@instance_plan)
160
+ @instance
161
+ end
162
+ end
116
163
 
117
164
  class CompilationVmType
118
165
  attr_reader :cloud_properties
@@ -33,7 +33,7 @@ module Bosh::Director
33
33
  if @deployment.stemcells.has_key?(alias_val)
34
34
  raise StemcellAliasAlreadyExists, "Duplicate stemcell alias '#{alias_val}'"
35
35
  end
36
- @deployment.add_stemcell(Stemcell.new(stemcell_hash))
36
+ @deployment.add_stemcell(Stemcell.parse(stemcell_hash))
37
37
  end
38
38
  end
39
39
  end
@@ -122,7 +122,13 @@ module Bosh::Director
122
122
  vm_creator = Bosh::Director::VmCreator.new(cloud, @logger, vm_deleter, disk_manager, job_renderer)
123
123
  dns_manager = DnsManagerProvider.create
124
124
  instance_deleter = Bosh::Director::InstanceDeleter.new(ip_provider, dns_manager, disk_manager)
125
- compilation_instance_pool = CompilationInstancePool.new(InstanceReuser.new, vm_creator, self, @logger, instance_deleter)
125
+ compilation_instance_pool = CompilationInstancePool.new(
126
+ InstanceReuser.new,
127
+ vm_creator,
128
+ self,
129
+ @logger,
130
+ instance_deleter,
131
+ compilation.workers)
126
132
  package_compile_step = DeploymentPlan::Steps::PackageCompileStep.new(
127
133
  jobs,
128
134
  compilation,
@@ -28,7 +28,7 @@ module Bosh::Director
28
28
  safe_property(spec, "cloud_properties", class: Hash, default: {})
29
29
 
30
30
  stemcell_spec = safe_property(spec, "stemcell", class: Hash)
31
- @stemcell = Stemcell.new(stemcell_spec)
31
+ @stemcell = Stemcell.parse(stemcell_spec)
32
32
 
33
33
  @env = safe_property(spec, "env", class: Hash, default: {})
34
34
  end
@@ -1,51 +1,44 @@
1
- # Copyright (c) 2009-2012 VMware, Inc.
2
-
3
1
  module Bosh::Director
4
2
  module DeploymentPlan
5
3
  class Stemcell
6
- include ValidationHelper
4
+ extend ValidationHelper
7
5
 
8
6
  attr_reader :alias
9
7
  attr_reader :os
10
-
11
- # @return [String] Stemcell name
12
8
  attr_reader :name
13
-
14
- # @return [String] Stemcell version
15
9
  attr_reader :version
16
-
17
- # @return [Models::Stemcell] Stemcell DB model
18
10
  attr_reader :model
19
11
 
20
- # @param [Hash] spec Raw stemcell spec according to deployment manifest
21
- def initialize(spec)
22
- @alias = safe_property(spec, "alias", :class => String, :optional => true)
23
-
24
- @name = safe_property(spec, "name", :class => String, :optional => true)
25
- @os = safe_property(spec, "os", :class => String, :optional => true)
12
+ def self.parse(spec)
13
+ name_alias = safe_property(spec, "alias", :class => String, :optional => true)
14
+ name = safe_property(spec, "name", :class => String, :optional => true)
15
+ os = safe_property(spec, "os", :class => String, :optional => true)
16
+ version = safe_property(spec, "version", :class => String)
26
17
 
27
- if @name.nil? && @os.nil?
18
+ if name.nil? && os.nil?
28
19
  raise ValidationMissingField, "Required property `os' or `name' was not specified in object (#{spec})"
29
20
  end
30
21
 
31
- if !@name.nil? && !@os.nil?
22
+ if !name.nil? && !os.nil?
32
23
  raise StemcellBothNameAndOS, "Properties `os' and `name' are both specified for stemcell, choose one. (#{spec})"
33
24
  end
34
25
 
35
- @version = safe_property(spec, "version", :class => String)
26
+ new(name_alias, name, os, version)
27
+ end
36
28
 
29
+ def initialize(name_alias, name, os, version)
30
+ @alias = name_alias
31
+ @name = name
32
+ @os = os
33
+ @version = version
37
34
  @manager = Api::StemcellManager.new
38
- @model = nil
39
35
  end
40
36
 
41
37
  def is_using_os?
42
38
  !@os.nil? && @name.nil?
43
39
  end
44
40
 
45
- # Looks up the stemcell matching provided spec
46
- # @return [void]
47
- def bind_model(deployment_plan)
48
- deployment_model = deployment_plan.model
41
+ def bind_model(deployment_model)
49
42
  if deployment_model.nil?
50
43
  raise DirectorError, "Deployment not bound in the deployment plan"
51
44
  end
@@ -109,7 +109,17 @@ module Bosh::Director
109
109
  end
110
110
  end
111
111
 
112
- private
112
+ def orphan_mounted_persistent_disk(instance, disk)
113
+ unmount(instance, disk)
114
+
115
+ disk_cid = disk.disk_cid
116
+ if disk_cid.nil?
117
+ @logger.info('Skipping disk detaching, instance does not have a disk')
118
+ return
119
+ end
120
+
121
+ detach_and_orphan_disk(disk, instance.model)
122
+ end
113
123
 
114
124
  def attach_disk(instance_model)
115
125
  disk_cid = instance_model.persistent_disk_cid
@@ -124,6 +134,8 @@ module Bosh::Director
124
134
  end
125
135
  end
126
136
 
137
+ private
138
+
127
139
  def delete_orphan_snapshot(orphan_snapshot)
128
140
  begin
129
141
  snapshot_cid = orphan_snapshot.snapshot_cid
@@ -149,18 +161,6 @@ module Bosh::Director
149
161
  end
150
162
  end
151
163
 
152
- def orphan_mounted_persistent_disk(instance, disk)
153
- unmount(instance, disk)
154
-
155
- disk_cid = disk.disk_cid
156
- if disk_cid.nil?
157
- @logger.info('Skipping disk detaching, instance does not have a disk')
158
- return
159
- end
160
-
161
- detach_and_orphan_disk(disk, instance.model)
162
- end
163
-
164
164
  def detach_and_orphan_disk(disk, instance_model)
165
165
  begin
166
166
  @logger.info("Detaching disk #{disk.disk_cid}")
@@ -1,7 +1,6 @@
1
1
  module Bosh::Director
2
2
  class NilInstanceError < ArgumentError; end
3
3
 
4
- # A class for maintaining Instance objects, making reusing Instances easier.
5
4
  class InstanceReuser
6
5
  def initialize
7
6
  @idle_instances_by_stemcell = {}
@@ -9,26 +8,23 @@ module Bosh::Director
9
8
  @mutex = Mutex.new
10
9
  end
11
10
 
12
- # Adds an instance's information to the pool of VMs that can be reused.
13
- # @param [DeploymentPlan::Instance] The instance for the new VM.
14
11
  def add_in_use_instance(instance, stemcell)
15
12
  raise NilInstanceError if instance.nil?
13
+ canonical_stemcell = canonical(stemcell)
16
14
  @mutex.synchronize do
17
- @in_use_instances_by_stemcell[stemcell] ||= []
18
- @in_use_instances_by_stemcell[stemcell] << instance
15
+ @in_use_instances_by_stemcell[canonical_stemcell] ||= []
16
+ @in_use_instances_by_stemcell[canonical_stemcell] << instance
19
17
  end
20
18
  end
21
19
 
22
- # Returns the instance of a VM that is not in use and can be reused.
23
- # @param [Models::Stemcell] stemcell The stemcell that the VM must be running.
24
- # @return [DeploymentPlan::Instance] The instance for an existing unused VM, if one exists. Otherwise, nil.
25
20
  def get_instance(stemcell)
21
+ canonical_stemcell = canonical(stemcell)
26
22
  @mutex.synchronize do
27
- return nil if @idle_instances_by_stemcell[stemcell].nil?
28
- instance = @idle_instances_by_stemcell[stemcell].pop
23
+ return nil if @idle_instances_by_stemcell[canonical_stemcell].nil?
24
+ instance = @idle_instances_by_stemcell[canonical_stemcell].pop
29
25
  return nil if instance.nil?
30
- @in_use_instances_by_stemcell[stemcell] ||= []
31
- @in_use_instances_by_stemcell[stemcell] << instance
26
+ @in_use_instances_by_stemcell[canonical_stemcell] ||= []
27
+ @in_use_instances_by_stemcell[canonical_stemcell] << instance
32
28
  return instance
33
29
  end
34
30
  end
@@ -44,46 +40,66 @@ module Bosh::Director
44
40
  raise NilInstanceError if instance.nil?
45
41
  @mutex.synchronize do
46
42
  release_without_lock(instance)
47
- @idle_instances_by_stemcell.each_value do |vms|
48
- vms.each do |v|
49
- vms.delete(v) if instance == v
43
+ @idle_instances_by_stemcell.each_value do |idle_instances|
44
+ idle_instances.each do |idle_instance|
45
+ idle_instances.delete(idle_instance) if instance == idle_instance
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ def remove_idle_instance_not_matching_stemcell(stemcell)
52
+ canonical_stemcell = canonical(stemcell)
53
+ @mutex.synchronize do
54
+ @idle_instances_by_stemcell.each do |stemcell, idle_instances|
55
+ if stemcell != canonical_stemcell && !idle_instances.empty?
56
+ return idle_instances.pop
50
57
  end
51
58
  end
52
59
  end
53
60
  end
54
61
 
55
- # Gets the total number of compilation instances created with a given stemcell.
56
- # @param [Models::Stemcell] stemcell The stemcell the VMs are running.
57
- # @return [Integer] The number of instances running a given stemcell.
58
62
  def get_num_instances(stemcell)
63
+ canonical_stemcell = canonical(stemcell)
59
64
  @mutex.synchronize do
60
- idle_count = @idle_instances_by_stemcell[stemcell].nil? ? 0 : @idle_instances_by_stemcell[stemcell].size
61
- in_use_count = @in_use_instances_by_stemcell[stemcell].nil? ? 0 : @in_use_instances_by_stemcell[stemcell].size
65
+ idle_count = @idle_instances_by_stemcell.fetch(canonical_stemcell, []).size
66
+ in_use_count = @in_use_instances_by_stemcell.fetch(canonical_stemcell, []).size
62
67
  idle_count + in_use_count
63
68
  end
64
69
  end
65
70
 
66
- # An iterator for all compilation VMs on all stemcells.
67
- # @yield [DeploymentPlan::Instance] yields each instance in InstanceReuser.
71
+ def total_instance_count
72
+ @mutex.synchronize do
73
+ sum = 0
74
+ @idle_instances_by_stemcell.values.each{|instances| sum += instances.to_a.count }
75
+ @in_use_instances_by_stemcell.values.each{|instances| sum += instances.to_a.count }
76
+ sum
77
+ end
78
+ end
79
+
68
80
  def each
69
- all_vms = (@idle_instances_by_stemcell.values + @in_use_instances_by_stemcell.values).flatten
70
- all_vms.each do |vm|
71
- yield vm
81
+ all_instances = (@idle_instances_by_stemcell.values + @in_use_instances_by_stemcell.values).flatten
82
+ all_instances.each do |instance|
83
+ yield instance
72
84
  end
73
85
  end
74
86
 
75
87
  private
76
88
 
77
89
  def release_without_lock(instance)
78
- @in_use_instances_by_stemcell.each do |stemcell, vms|
79
- vms.each do |v|
80
- if instance == v
81
- vms.delete(v)
82
- @idle_instances_by_stemcell[stemcell] ||= []
83
- @idle_instances_by_stemcell[stemcell] << instance
90
+ @in_use_instances_by_stemcell.each do |canonical_stemcell, in_use_instances|
91
+ in_use_instances.each do |in_use_instance|
92
+ if instance == in_use_instance
93
+ in_use_instances.delete(in_use_instance)
94
+ @idle_instances_by_stemcell[canonical_stemcell] ||= []
95
+ @idle_instances_by_stemcell[canonical_stemcell] << instance
84
96
  end
85
97
  end
86
98
  end
87
99
  end
100
+
101
+ def canonical(stemcell)
102
+ stemcell.desc
103
+ end
88
104
  end
89
105
  end
@@ -21,27 +21,103 @@ module Bosh::Director
21
21
  end
22
22
 
23
23
  def perform
24
- instance = Models::Instance.filter(job: @job_name, uuid: @instance_id).to_a.first
24
+ instance = query_instance_model
25
25
 
26
26
  if instance.nil? || instance.deployment.name != @deployment_name
27
27
  raise AttachDiskErrorUnknownInstance, "Instance '#{@job_name}/#{@instance_id}' in deployment '#{@deployment_name}' was not found"
28
28
  end
29
29
 
30
- if instance.persistent_disk.nil?
31
- raise AttachDiskNoPersistentDisk, "Job '#{@job_name}' is not configured with a persistent disk"
30
+ if instance.state != 'detached' && instance.state != 'stopped'
31
+ raise AttachDiskInvalidInstanceState, "Instance '#{@job_name}/#{@instance_id}' in deployment '#{@deployment_name}' must be in 'bosh stopped' state"
32
32
  end
33
33
 
34
- if instance.state != 'detached'
35
- raise AttachDiskInvalidInstanceState, "Instance '#{@job_name}/#{@instance_id}' in deployment '#{@deployment_name}' must be in 'bosh stopped --hard' state"
34
+ if instance.persistent_disk.nil?
35
+ raise AttachDiskNoPersistentDisk, "Job '#{@job_name}' is not configured with a persistent disk"
36
36
  end
37
37
 
38
+ previous_persistent_disk = instance.persistent_disk
38
39
  @transactor.retryable_transaction(instance.db) do
39
40
  instance.persistent_disk.update(active: false)
40
- Models::PersistentDisk.create(disk_cid: @disk_cid, instance_id: instance.id, active: true, size: 1, cloud_properties: {})
41
+
42
+ orphan_disk = Models::OrphanDisk[:disk_cid => @disk_cid]
43
+ if orphan_disk
44
+
45
+ current_disk = Models::PersistentDisk[instance_id: instance.id]
46
+ if current_disk
47
+ create_orphan_disk_from_current_disk(current_disk)
48
+ end
49
+
50
+ create_new_disk_from_orphan_disk(orphan_disk, instance)
51
+ else
52
+ Models::PersistentDisk.create(disk_cid: @disk_cid, instance_id: instance.id, active: true, size: 1, cloud_properties: {})
53
+ end
54
+ end
55
+
56
+ if instance.state == 'stopped'
57
+ instance = query_instance_model
58
+ deployment_plan_instance = deployment_plan_instance(instance)
59
+ if deployment_plan_instance.nil?
60
+ raise AttachDiskErrorUnknownInstance, "Deployment plan instance not found for instance model with id #{@instance_id}"
61
+ end
62
+
63
+ disk_manager = DiskManager.new(Config.cloud, logger)
64
+ disk_manager.orphan_mounted_persistent_disk(deployment_plan_instance, previous_persistent_disk)
65
+ disk_manager.attach_disk(instance)
41
66
  end
42
67
 
43
68
  "attached disk '#{@disk_cid}' to '#{@job_name}/#{@instance_id}' in deployment '#{@deployment_name}'"
44
69
  end
70
+
71
+ private
72
+
73
+ def create_orphan_disk_from_current_disk(current_disk)
74
+ new_orphan_disk = Models::OrphanDisk.create(disk_cid: current_disk.disk_cid,
75
+ size: current_disk.size,
76
+ availability_zone: current_disk.instance.availability_zone,
77
+ deployment_name: current_disk.instance.deployment.name,
78
+ instance_name: current_disk.instance.name,
79
+ cloud_properties: current_disk.cloud_properties)
80
+
81
+ current_disk.snapshots.each do |snapshot|
82
+ Models::OrphanSnapshot.create(orphan_disk: new_orphan_disk,
83
+ snapshot_cid: snapshot.snapshot_cid,
84
+ clean: snapshot.clean,
85
+ snapshot_created_at: snapshot.created_at)
86
+ snapshot.destroy
87
+ end
88
+
89
+ current_disk.destroy
90
+ end
91
+
92
+ def create_new_disk_from_orphan_disk(orphan_disk, instance)
93
+ new_disk = Models::PersistentDisk.create(disk_cid: orphan_disk.disk_cid,
94
+ instance_id: instance.id,
95
+ active: true,
96
+ size: orphan_disk.size,
97
+ cloud_properties: orphan_disk.cloud_properties)
98
+
99
+ orphan_disk.orphan_snapshots.each do |snapshot|
100
+ Models::Snapshot.create(persistent_disk: new_disk, snapshot_cid: snapshot.snapshot_cid, clean: snapshot.clean)
101
+ snapshot.destroy
102
+ end
103
+
104
+ orphan_disk.destroy
105
+ end
106
+
107
+ def query_instance_model
108
+ Models::Instance.filter(job: @job_name, uuid: @instance_id).to_a.first
109
+ end
110
+
111
+ def deployment_plan_instance(instance)
112
+ deployment_model = Api::DeploymentLookup.new.by_name(@deployment_name)
113
+ planner_factory = DeploymentPlan::PlannerFactory.create(logger)
114
+ deployment_plan = planner_factory.create_from_model(deployment_model)
115
+ job = deployment_plan.job(@job_name)
116
+
117
+ deployment_plan_instance = DeploymentPlan::Instance.create_from_job(job, 0, instance.state, deployment_model, instance.state, instance.availability_zone, logger)
118
+ deployment_plan_instance.bind_existing_instance_model(instance)
119
+ deployment_plan_instance
120
+ end
45
121
  end
46
122
  end
47
123
  end
@@ -27,7 +27,7 @@ module Bosh::Director
27
27
  def perform
28
28
  logger.info("Exporting release: #{@release_name}/#{@release_version} for #{@stemcell_os}/#{@stemcell_version}")
29
29
 
30
- deployment_plan_stemcell = Bosh::Director::DeploymentPlan::Stemcell.new({
30
+ deployment_plan_stemcell = Bosh::Director::DeploymentPlan::Stemcell.parse({
31
31
  "os" => @stemcell_os,
32
32
  "version" => @stemcell_version
33
33
  })
@@ -45,7 +45,7 @@ module Bosh::Director
45
45
 
46
46
  planner_factory = DeploymentPlan::PlannerFactory.create(logger)
47
47
  planner = planner_factory.create_from_model(targeted_deployment)
48
- deployment_plan_stemcell.bind_model(planner)
48
+ deployment_plan_stemcell.bind_model(planner.model)
49
49
 
50
50
  stemcell_model = deployment_plan_stemcell.model
51
51
  logger.info "Will compile with stemcell: #{stemcell_model.desc}"
@@ -61,6 +61,10 @@ module Bosh::Director::Models
61
61
  self.dns_records = JSON.dump(list)
62
62
  end
63
63
 
64
+ def name
65
+ "#{self.job}/#{self.uuid}"
66
+ end
67
+
64
68
  def to_s
65
69
  "#{self.job}/#{self.index} (#{self.uuid})"
66
70
  end
@@ -1,5 +1,5 @@
1
1
  module Bosh
2
2
  module Director
3
- VERSION = '1.3196.0'
3
+ VERSION = '1.3197.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bosh-director
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3196.0
4
+ version: 1.3197.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - VMware
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-17 00:00:00.000000000 Z
11
+ date: 2016-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bosh_common
@@ -16,98 +16,98 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.3196.0
19
+ version: 1.3197.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.3196.0
26
+ version: 1.3197.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bosh_cpi
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.3196.0
33
+ version: 1.3197.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.3196.0
40
+ version: 1.3197.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bosh-registry
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 1.3196.0
47
+ version: 1.3197.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.3196.0
54
+ version: 1.3197.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: blobstore_client
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 1.3196.0
61
+ version: 1.3197.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.3196.0
68
+ version: 1.3197.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: bosh-core
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 1.3196.0
75
+ version: 1.3197.0
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 1.3196.0
82
+ version: 1.3197.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: bosh-director-core
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 1.3196.0
89
+ version: 1.3197.0
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 1.3196.0
96
+ version: 1.3197.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: bosh-template
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 1.3196.0
103
+ version: 1.3197.0
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 1.3196.0
110
+ version: 1.3197.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: bosh_openstack_cpi
113
113
  requirement: !ruby/object:Gem::Requirement