bosh-director 1.2941.0 → 1.2949.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,56 @@
1
+ module Bosh::Director
2
+ module DeploymentPlan
3
+ module Steps
4
+ class PrepareStep
5
+ def initialize(job, assembler)
6
+ @job = job
7
+ @assembler = assembler
8
+ end
9
+
10
+ def perform
11
+ job.begin_stage('Preparing deployment', 9)
12
+
13
+ job.track_and_log('Binding deployment') do
14
+ @assembler.bind_deployment
15
+ end
16
+
17
+ job.track_and_log('Binding releases') do
18
+ @assembler.bind_releases
19
+ end
20
+
21
+ job.track_and_log('Binding existing deployment') do
22
+ @assembler.bind_existing_deployment
23
+ end
24
+
25
+ job.track_and_log('Binding resource pools') do
26
+ @assembler.bind_resource_pools
27
+ end
28
+
29
+ job.track_and_log('Binding stemcells') do
30
+ @assembler.bind_stemcells
31
+ end
32
+
33
+ job.track_and_log('Binding templates') do
34
+ @assembler.bind_templates
35
+ end
36
+
37
+ job.track_and_log('Binding properties') do
38
+ @assembler.bind_properties
39
+ end
40
+
41
+ job.track_and_log('Binding unallocated VMs') do
42
+ @assembler.bind_unallocated_vms
43
+ end
44
+
45
+ job.track_and_log('Binding instance networks') do
46
+ @assembler.bind_instance_networks
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ attr_reader :job
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,70 @@
1
+ module Bosh::Director
2
+ module DeploymentPlan
3
+ module Steps
4
+ class UpdateStep
5
+ def initialize(base_job, event_log, resource_pools, assembler, deployment_plan, multi_job_updater)
6
+ @base_job = base_job
7
+ @logger = base_job.logger
8
+ @event_log = event_log
9
+ @resource_pools = resource_pools
10
+ @assembler = assembler
11
+ @deployment_plan = deployment_plan
12
+ @multi_job_updater = multi_job_updater
13
+ end
14
+
15
+
16
+ def perform
17
+ begin
18
+ @logger.info('Updating deployment')
19
+ assemble
20
+ update_jobs
21
+ @logger.info('Committing updates')
22
+ @deployment_plan.persist_updates!
23
+ @logger.info('Finished updating deployment')
24
+ ensure
25
+ @deployment_plan.update_stemcell_references!
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def assemble
32
+ @event_log.begin_stage('Preparing DNS', 1)
33
+ @base_job.track_and_log('Binding DNS') do
34
+ @assembler.bind_dns
35
+ end
36
+
37
+ @logger.info('Deleting no longer needed VMs')
38
+ @assembler.delete_unneeded_vms
39
+
40
+ @logger.info('Deleting no longer needed instances')
41
+ @assembler.delete_unneeded_instances
42
+
43
+ @logger.info('Updating resource pools')
44
+ @resource_pools.update
45
+ @base_job.task_checkpoint
46
+
47
+ @logger.info('Binding instance VMs')
48
+ @assembler.bind_instance_vms
49
+
50
+ @event_log.begin_stage('Preparing configuration', 1)
51
+ @base_job.track_and_log('Binding configuration') do
52
+ @assembler.bind_configuration
53
+ end
54
+ end
55
+
56
+ def update_jobs
57
+ @logger.info('Updating jobs')
58
+ @multi_job_updater.run(
59
+ @base_job,
60
+ @deployment_plan,
61
+ @deployment_plan.jobs_starting_on_deploy,
62
+ )
63
+
64
+ @logger.info('Refilling resource pools')
65
+ @resource_pools.refill
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -1,9 +1,6 @@
1
1
  module Bosh::Director
2
2
  class Errand::DeploymentPreparer
3
- # @param [Bosh::Director::DeploymentPlan::Planner] deployment
4
- # @param [Bosh::Director::DeploymentPlan::Job] job
5
- # @param [Bosh::Director::EventLog::Log] event_log
6
- # @param [Bosh::Blobstore::Jobs::BaseJob] base_job
3
+
7
4
  def initialize(deployment, job, event_log, base_job)
8
5
  @deployment = deployment
9
6
  @job = job
@@ -14,11 +11,11 @@ module Bosh::Director
14
11
  def prepare_deployment
15
12
  assembler = DeploymentPlan::Assembler.new(@deployment)
16
13
 
17
- preparer = DeploymentPlan::Preparer.new(@base_job, assembler)
18
- preparer.prepare
14
+ preparer = DeploymentPlan::Steps::PrepareStep.new(@base_job, assembler)
15
+ preparer.perform
19
16
 
20
- compiler = PackageCompiler.new(@deployment)
21
- compiler.compile
17
+ compiler = DeploymentPlan::Steps::PackageCompileStep.new(@deployment)
18
+ compiler.perform
22
19
  end
23
20
 
24
21
  def prepare_job
@@ -24,7 +24,7 @@ module Bosh::Director
24
24
  def perform
25
25
  deployment_model = @deployment_manager.find_by_name(@deployment_name)
26
26
  manifest = Psych.load(deployment_model.manifest)
27
- deployment = DeploymentPlan::Planner.parse(manifest, {}, event_log, logger)
27
+ deployment = DeploymentPlan::Planner.parse(manifest, deployment_model.cloud_config, {}, event_log, logger)
28
28
 
29
29
  job = deployment.job(@errand_name)
30
30
  if job.nil?
@@ -3,119 +3,95 @@ module Bosh::Director
3
3
  class UpdateDeployment < BaseJob
4
4
  include LockHelper
5
5
 
6
- attr_reader :notifier
7
-
8
6
  @queue = :normal
9
7
 
10
8
  def self.job_type
11
9
  :update_deployment
12
10
  end
13
11
 
14
- # @param [String] manifest_file Path to deployment manifest
15
- # @param [Hash] options Deployment options
16
- def initialize(manifest_file, cloud_config_id, options = {})
12
+ def initialize(manifest_file_path, cloud_config_id, options = {})
17
13
  @blobstore = App.instance.blobstores.blobstore
14
+ @manifest_file_path = manifest_file_path
15
+ @options = options
16
+ @cloud_config_id = cloud_config_id
17
+ end
18
18
 
19
- logger.info('Reading deployment manifest')
20
- @manifest_file = manifest_file
21
- @manifest = File.read(@manifest_file)
22
- logger.debug("Manifest:\n#{@manifest}")
19
+ def perform
20
+ with_deployment_lock(deployment_plan) do
21
+ logger.info('Updating deployment')
22
+ notifier.send_start_event
23
+ prepare_step.perform
24
+ compile_step.perform
25
+ update_step.perform
26
+ notifier.send_end_event
27
+ logger.info('Finished updating deployment')
23
28
 
24
- @cloud_config = Bosh::Director::Models::CloudConfig.find(id: cloud_config_id)
25
- logger.debug("Cloud Config:\n#{@cloud_config.inspect}")
29
+ "/deployments/#{deployment_plan.name}"
30
+ end
31
+ rescue Exception => e
32
+ notifier.send_error_event e
33
+ raise e
34
+ ensure
35
+ FileUtils.rm_rf(@manifest_file_path)
36
+ end
26
37
 
27
- logger.info('Creating deployment plan')
28
- logger.info("Deployment plan options: #{options.pretty_inspect}")
38
+ private
29
39
 
30
- plan_options = {
31
- 'recreate' => !!options['recreate'],
32
- 'job_states' => options['job_states'] || {},
33
- 'job_rename' => options['job_rename'] || {}
34
- }
40
+ # Job tasks
35
41
 
36
- manifest_as_hash = Psych.load(@manifest)
37
- @deployment_plan = DeploymentPlan::Planner.parse(manifest_as_hash, plan_options, event_log, logger)
38
- logger.info('Created deployment plan')
42
+ def prepare_step
43
+ DeploymentPlan::Steps::PrepareStep.new(self, assembler)
44
+ end
39
45
 
40
- nats_rpc = Config.nats_rpc
41
- @notifier = DeploymentPlan::Notifier.new(@deployment_plan, nats_rpc, logger)
46
+ def compile_step
47
+ DeploymentPlan::Steps::PackageCompileStep.new(deployment_plan)
48
+ end
42
49
 
43
- resource_pools = @deployment_plan.resource_pools
44
- @resource_pool_updaters = resource_pools.map do |resource_pool|
50
+ def update_step
51
+ resource_pool_updaters = deployment_plan.resource_pools.map do |resource_pool|
45
52
  ResourcePoolUpdater.new(resource_pool)
46
53
  end
54
+ resource_pools = DeploymentPlan::ResourcePools.new(event_log, resource_pool_updaters)
55
+ DeploymentPlan::Steps::UpdateStep.new(self, event_log, resource_pools, assembler, deployment_plan, multi_job_updater)
47
56
  end
48
57
 
49
- def prepare
50
- @assembler = DeploymentPlan::Assembler.new(@deployment_plan)
51
- preparer = DeploymentPlan::Preparer.new(self, @assembler)
52
- preparer.prepare
58
+ # Job dependencies
53
59
 
54
- logger.info('Compiling and binding packages')
55
- PackageCompiler.new(@deployment_plan).compile
60
+ def assembler
61
+ @assembler ||= DeploymentPlan::Assembler.new(deployment_plan)
56
62
  end
57
63
 
58
- def update
59
- resource_pools = DeploymentPlan::ResourcePools.new(event_log, @resource_pool_updaters)
60
- job_updater_factory = JobUpdaterFactory.new(@blobstore)
61
- multi_job_updater = DeploymentPlan::BatchMultiJobUpdater.new(job_updater_factory)
62
- updater = DeploymentPlan::Updater.new(self, event_log, resource_pools, @assembler, @deployment_plan, multi_job_updater)
63
- updater.update
64
+ def notifier
65
+ @notifier ||= DeploymentPlan::Notifier.new(deployment_plan, Config.nats_rpc, logger)
64
66
  end
65
67
 
66
- def update_stemcell_references
67
- current_stemcells = Set.new
68
- @deployment_plan.resource_pools.each do |resource_pool|
69
- current_stemcells << resource_pool.stemcell.model
70
- end
71
-
72
- deployment = @deployment_plan.model
73
- stemcells = deployment.stemcells
74
- stemcells.each do |stemcell|
75
- unless current_stemcells.include?(stemcell)
76
- stemcell.remove_deployment(deployment)
77
- end
68
+ def deployment_plan
69
+ @deployment_plan ||= begin
70
+ logger.info('Reading deployment manifest')
71
+ manifest_text = File.read(@manifest_file_path)
72
+ logger.debug("Manifest:\n#{manifest_text}")
73
+ deployment_manifest = Psych.load(manifest_text)
74
+
75
+ plan_options = {
76
+ 'recreate' => !!@options['recreate'],
77
+ 'job_states' => @options['job_states'] || {},
78
+ 'job_rename' => @options['job_rename'] || {}
79
+ }
80
+ logger.info('Creating deployment plan')
81
+ logger.info("Deployment plan options: #{plan_options.pretty_inspect}")
82
+
83
+ cloud_config = Bosh::Director::Models::CloudConfig[@cloud_config_id]
84
+
85
+ plan = DeploymentPlan::Planner.parse(deployment_manifest, cloud_config, plan_options, event_log, logger)
86
+ logger.info('Created deployment plan')
87
+ plan
78
88
  end
79
89
  end
80
90
 
81
- def perform
82
- with_deployment_lock(@deployment_plan) do
83
- logger.info('Preparing deployment')
84
- notifier.send_start_event
85
- prepare
86
- begin
87
- deployment = @deployment_plan.model
88
- logger.info('Finished preparing deployment')
89
- logger.info('Updating deployment')
90
- update
91
-
92
- with_release_locks(@deployment_plan) do
93
- deployment.db.transaction do
94
- deployment.remove_all_release_versions
95
- # Now we know that deployment has succeeded and can remove
96
- # previous partial deployments release version references
97
- # to be able to delete these release versions later.
98
- @deployment_plan.releases.each do |release|
99
- deployment.add_release_version(release.model)
100
- end
101
- end
102
- end
103
-
104
- deployment.manifest = @manifest
105
- deployment.cloud_config = @cloud_config
106
- deployment.save
107
- notifier.send_end_event
108
- logger.info('Finished updating deployment')
109
- "/deployments/#{deployment.name}"
110
- ensure
111
- update_stemcell_references
112
- end
91
+ def multi_job_updater
92
+ @multi_job_updater ||= begin
93
+ DeploymentPlan::BatchMultiJobUpdater.new(JobUpdaterFactory.new(@blobstore))
113
94
  end
114
- rescue Exception => e
115
- notifier.send_error_event e
116
- raise e
117
- ensure
118
- FileUtils.rm_rf(@manifest_file)
119
95
  end
120
96
  end
121
97
  end
@@ -1,13 +1,5 @@
1
1
  module Bosh::Director
2
- # Helper for managing BOSH locks.
3
2
  module LockHelper
4
-
5
- # Surround with deployment lock.
6
- #
7
- # @param [DeploymentPlan|String] deployment plan or name.
8
- # @option opts [Number] timeout how long to wait before giving up
9
- # @return [void]
10
- # @yield [void] block to surround
11
3
  def with_deployment_lock(deployment, opts = {})
12
4
  if deployment.respond_to?(:name)
13
5
  name = deployment.name
@@ -21,13 +13,6 @@ module Bosh::Director
21
13
  Lock.new("lock:deployment:#{name}", :timeout => timeout).lock { yield }
22
14
  end
23
15
 
24
- # Surround with stemcell lock.
25
- #
26
- # @param [String] name stemcell name.
27
- # @param [String] version stemcell version.
28
- # @option opts [Number] timeout how long to wait before giving up
29
- # @return [void]
30
- # @yield [void] block to surround
31
16
  def with_stemcell_lock(name, version, opts = {})
32
17
  timeout = opts[:timeout] || 10
33
18
  Config.logger.info("Acquiring stemcell lock on #{name}:#{version}")
@@ -35,31 +20,12 @@ module Bosh::Director
35
20
  lock { yield }
36
21
  end
37
22
 
38
- # Surround with release lock.
39
- #
40
- # @param [String] release name.
41
- # @option opts [Number] timeout how long to wait before giving up
42
- # @return [void]
43
- # @yield [void] block to surround
44
- def with_release_lock(release, opts = {})
45
- timeout = opts[:timeout] || 10
46
- Config.logger.info("Acquiring release lock on #{release}")
47
- Lock.new("lock:release:#{release}", :timeout => timeout).lock { yield }
23
+ def with_release_lock(release_name, opts = {})
24
+ with_release_locks([release_name], opts) { yield }
48
25
  end
49
26
 
50
- # Surround with deployment releases lock.
51
- #
52
- # @param [DeploymentPlan] deployment plan.
53
- # @option opts [Number] timeout how long to wait before giving up
54
- # @return [void]
55
- # @yield [void] block to surround
56
- def with_release_locks(deployment_plan, opts = {})
27
+ def with_release_locks(release_names, opts = {})
57
28
  timeout = opts[:timeout] || 10
58
- release_names = deployment_plan.releases.map do |release|
59
- release.name
60
- end
61
-
62
- # Sorting to enforce lock order to avoid deadlocks
63
29
  locks = release_names.sort.map do |release_name|
64
30
  Config.logger.info("Acquiring release lock: #{release_name}")
65
31
  Lock.new("lock:release:#{release_name}", :timeout => timeout)
@@ -73,13 +39,6 @@ module Bosh::Director
73
39
  end
74
40
  end
75
41
 
76
- # Surround with compile lock.
77
- #
78
- # @param [String|Number] package_id package id.
79
- # @param [String|Number] stemcell_id stemcell id.
80
- # @option opts [Number] timeout how long to wait before giving up
81
- # @return [void]
82
- # @yield [void] block to surround
83
42
  def with_compile_lock(package_id, stemcell_id, opts = {})
84
43
  timeout = opts[:timeout] || 15 * 60 # 15 minutes
85
44
 
@@ -5,6 +5,14 @@ module Bosh
5
5
  def before_create
6
6
  self.created_at ||= Time.now
7
7
  end
8
+
9
+ def manifest=(cloud_config_hash)
10
+ self.properties = Psych.dump(cloud_config_hash)
11
+ end
12
+
13
+ def manifest
14
+ Psych.load properties
15
+ end
8
16
  end
9
17
  end
10
18
  end
@@ -9,7 +9,7 @@ module Bosh::Director::Models
9
9
  one_to_many :vms
10
10
  one_to_many :properties, :class => "Bosh::Director::Models::DeploymentProperty"
11
11
  one_to_many :problems, :class => "Bosh::Director::Models::DeploymentProblem"
12
- many_to_one :cloud_config
12
+ many_to_one :cloud_config
13
13
 
14
14
  def validate
15
15
  validates_presence :name
@@ -1,5 +1,5 @@
1
1
  module Bosh
2
2
  module Director
3
- VERSION = '1.2941.0'
3
+ VERSION = '1.2949.0'
4
4
  end
5
5
  end