bosh-director 1.3202.0 → 1.3213.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/db/migrations/director/20151223172000_rename_requires_json.rb +7 -0
  3. data/db/migrations/director/20160106162749_runtime_configs.rb +19 -0
  4. data/db/migrations/director/20160106163433_add_runtime_configs_to_deployments.rb +7 -0
  5. data/db/migrations/director/20160202162216_add_post_start_completed_to_instance.rb +7 -0
  6. data/db/migrations/director/20160210201838_denormalize_compiled_package_stemcell_id_to_stemcell_name_and_version.rb +57 -0
  7. data/db/migrations/director/20160219175840_add_column_teams_to_deployments.rb +8 -0
  8. data/db/migrations/director/20160224222508_add_deployment_name_to_task.rb +7 -0
  9. data/db/migrations/director/20160225182206_rename_post_start_completed.rb +8 -0
  10. data/lib/bosh/director.rb +9 -0
  11. data/lib/bosh/director/api.rb +1 -1
  12. data/lib/bosh/director/api/api_helper.rb +27 -0
  13. data/lib/bosh/director/api/controllers/base_controller.rb +28 -5
  14. data/lib/bosh/director/api/controllers/cloud_configs_controller.rb +4 -3
  15. data/lib/bosh/director/api/controllers/deployments_controller.rb +165 -81
  16. data/lib/bosh/director/api/controllers/locks_controller.rb +1 -1
  17. data/lib/bosh/director/api/controllers/packages_controller.rb +4 -35
  18. data/lib/bosh/director/api/controllers/releases_controller.rb +6 -4
  19. data/lib/bosh/director/api/controllers/runtime_configs_controller.rb +41 -0
  20. data/lib/bosh/director/api/controllers/stemcells_controller.rb +1 -1
  21. data/lib/bosh/director/api/controllers/tasks_controller.rb +72 -5
  22. data/lib/bosh/director/api/deployment_manager.rb +10 -42
  23. data/lib/bosh/director/api/extensions/scoping.rb +11 -24
  24. data/lib/bosh/director/api/instance_lookup.rb +10 -22
  25. data/lib/bosh/director/api/instance_manager.rb +27 -15
  26. data/lib/bosh/director/api/local_identity_provider.rb +0 -8
  27. data/lib/bosh/director/api/problem_manager.rb +7 -19
  28. data/lib/bosh/director/api/property_manager.rb +12 -21
  29. data/lib/bosh/director/api/resurrector_manager.rb +4 -4
  30. data/lib/bosh/director/api/route_configuration.rb +1 -0
  31. data/lib/bosh/director/api/runtime_config_manager.rb +35 -0
  32. data/lib/bosh/director/api/snapshot_manager.rb +2 -2
  33. data/lib/bosh/director/api/task_helper.rb +2 -1
  34. data/lib/bosh/director/api/task_manager.rb +2 -8
  35. data/lib/bosh/director/api/uaa_identity_provider.rb +0 -16
  36. data/lib/bosh/director/blob_util.rb +3 -2
  37. data/lib/bosh/director/cloudcheck_helper.rb +17 -3
  38. data/lib/bosh/director/compile_task.rb +53 -24
  39. data/lib/bosh/director/compile_task_generator.rb +6 -6
  40. data/lib/bosh/director/compiled_package_group.rb +4 -3
  41. data/lib/bosh/director/compiled_release.rb +6 -0
  42. data/lib/bosh/director/compiled_release/manifest.rb +30 -0
  43. data/lib/bosh/director/compiled_release_manifest.rb +3 -3
  44. data/lib/bosh/director/config.rb +11 -1
  45. data/lib/bosh/director/deployment_plan.rb +1 -0
  46. data/lib/bosh/director/deployment_plan/assembler.rb +6 -2
  47. data/lib/bosh/director/deployment_plan/cloud_manifest_parser.rb +26 -10
  48. data/lib/bosh/director/deployment_plan/compilation_config.rb +43 -7
  49. data/lib/bosh/director/deployment_plan/compilation_instance_pool.rb +10 -3
  50. data/lib/bosh/director/deployment_plan/deployment_repo.rb +4 -10
  51. data/lib/bosh/director/deployment_plan/dynamic_network.rb +1 -1
  52. data/lib/bosh/director/deployment_plan/instance.rb +36 -17
  53. data/lib/bosh/director/deployment_plan/instance_plan.rb +13 -2
  54. data/lib/bosh/director/deployment_plan/instance_spec.rb +12 -4
  55. data/lib/bosh/director/deployment_plan/job.rb +73 -39
  56. data/lib/bosh/director/deployment_plan/job_availability_zone_parser.rb +4 -4
  57. data/lib/bosh/director/deployment_plan/job_migrator.rb +7 -7
  58. data/lib/bosh/director/deployment_plan/job_network_parser.rb +6 -6
  59. data/lib/bosh/director/deployment_plan/job_spec_parser.rb +91 -33
  60. data/lib/bosh/director/deployment_plan/links/link.rb +9 -4
  61. data/lib/bosh/director/deployment_plan/links/link_lookup.rb +23 -15
  62. data/lib/bosh/director/deployment_plan/links/link_path.rb +168 -15
  63. data/lib/bosh/director/deployment_plan/links/links_resolver.rb +34 -32
  64. data/lib/bosh/director/deployment_plan/links/template_link.rb +28 -8
  65. data/lib/bosh/director/deployment_plan/manifest_validator.rb +1 -1
  66. data/lib/bosh/director/deployment_plan/network_settings.rb +27 -13
  67. data/lib/bosh/director/deployment_plan/package_validator.rb +9 -5
  68. data/lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb +4 -4
  69. data/lib/bosh/director/deployment_plan/planner.rb +31 -7
  70. data/lib/bosh/director/deployment_plan/planner_factory.rb +147 -6
  71. data/lib/bosh/director/deployment_plan/runtime_manifest_parser.rb +142 -0
  72. data/lib/bosh/director/deployment_plan/stemcell.rb +2 -2
  73. data/lib/bosh/director/deployment_plan/steps/package_compile_step.rb +3 -2
  74. data/lib/bosh/director/deployment_plan/template.rb +93 -8
  75. data/lib/bosh/director/deployment_plan/update_config.rb +10 -0
  76. data/lib/bosh/director/deployment_plan/vm_extension.rb +27 -0
  77. data/lib/bosh/director/errand/runner.rb +1 -1
  78. data/lib/bosh/director/errors.rb +11 -1
  79. data/lib/bosh/director/instance_updater.rb +46 -57
  80. data/lib/bosh/director/instance_updater/instance_state.rb +9 -0
  81. data/lib/bosh/director/instance_updater/state_applier.rb +18 -5
  82. data/lib/bosh/director/job_queue.rb +2 -2
  83. data/lib/bosh/director/job_renderer.rb +2 -2
  84. data/lib/bosh/director/job_updater.rb +7 -1
  85. data/lib/bosh/director/jobs/attach_disk.rb +2 -2
  86. data/lib/bosh/director/jobs/cloud_check/apply_resolutions.rb +6 -1
  87. data/lib/bosh/director/jobs/cloud_check/scan_and_fix.rb +14 -3
  88. data/lib/bosh/director/jobs/export_release.rb +1 -1
  89. data/lib/bosh/director/jobs/fetch_logs.rb +1 -4
  90. data/lib/bosh/director/jobs/helpers/compiled_package_deleter.rb +1 -2
  91. data/lib/bosh/director/jobs/helpers/stemcell_deleter.rb +0 -16
  92. data/lib/bosh/director/jobs/release/release_job.rb +7 -7
  93. data/lib/bosh/director/jobs/run_errand.rb +5 -5
  94. data/lib/bosh/director/jobs/ssh.rb +3 -3
  95. data/lib/bosh/director/jobs/update_deployment.rb +41 -5
  96. data/lib/bosh/director/jobs/update_release.rb +78 -82
  97. data/lib/bosh/director/jobs/update_stemcell.rb +1 -1
  98. data/lib/bosh/director/jobs/vm_state.rb +34 -21
  99. data/lib/bosh/director/key_generator.rb +54 -0
  100. data/lib/bosh/director/lock.rb +2 -2
  101. data/lib/bosh/director/log_bundles_cleaner.rb +1 -0
  102. data/lib/bosh/director/manifest/changeset.rb +39 -22
  103. data/lib/bosh/director/manifest/diff_lines.rb +1 -27
  104. data/lib/bosh/director/manifest/manifest.rb +22 -7
  105. data/lib/bosh/director/manifest/redactor.rb +44 -0
  106. data/lib/bosh/director/models.rb +1 -0
  107. data/lib/bosh/director/models/compiled_package.rb +21 -15
  108. data/lib/bosh/director/models/deployment.rb +10 -0
  109. data/lib/bosh/director/models/instance.rb +2 -1
  110. data/lib/bosh/director/models/release_version.rb +0 -16
  111. data/lib/bosh/director/models/runtime_config.rb +19 -0
  112. data/lib/bosh/director/models/template.rb +4 -4
  113. data/lib/bosh/director/package_dependencies_manager.rb +22 -0
  114. data/lib/bosh/director/password_helper.rb +18 -0
  115. data/lib/bosh/director/permission_authorizer.rb +50 -30
  116. data/lib/bosh/director/post_deployment_script_runner.rb +40 -0
  117. data/lib/bosh/director/problem_handlers/missing_disk.rb +2 -2
  118. data/lib/bosh/director/problem_resolver.rb +8 -2
  119. data/lib/bosh/director/problem_scanner/scanner.rb +1 -1
  120. data/lib/bosh/director/problem_scanner/vm_scan_stage.rb +1 -1
  121. data/lib/bosh/director/validation_helper.rb +5 -5
  122. data/lib/bosh/director/version.rb +1 -1
  123. data/lib/bosh/director/vm_creator.rb +8 -0
  124. data/lib/cloud/dummy.rb +1 -0
  125. metadata +51 -19
  126. data/lib/bosh/director/api/vm_state_manager.rb +0 -9
  127. data/lib/bosh/director/compiled_package/blob_sha_mismatch_error.rb +0 -5
  128. data/lib/bosh/director/compiled_package/compiled_package.rb +0 -30
@@ -1,26 +1,31 @@
1
1
  module Bosh::Director::Models
2
2
  class CompiledPackage < Sequel::Model(Bosh::Director::Config.db)
3
3
  many_to_one :package
4
- many_to_one :stemcell
5
-
6
- # Creates a dependency_key from a list of dependencies
7
- # Input MUST include immediate & transitive dependencies
8
- def self.create_dependency_key(transitive_dependencies)
9
- key = transitive_dependencies.to_a.sort_by(&:name).map { |p| [p.name, p.version]}
10
- Yajl::Encoder.encode(key)
11
- end
12
4
 
13
5
  # Creates a 'unique' key to use in the global package cache
14
- def self.create_cache_key(package, transitive_dependencies, stemcell)
6
+ def self.create_cache_key(package, transitive_dependencies, stemcell_sha1)
15
7
  dependency_fingerprints = transitive_dependencies.to_a.sort_by(&:name).map {|p| p.fingerprint }
16
- hash_input = ([package.fingerprint, stemcell.sha1]+dependency_fingerprints).join('')
8
+ hash_input = ([package.fingerprint, stemcell_sha1]+dependency_fingerprints).join('')
17
9
  Digest::SHA1.hexdigest(hash_input)
18
10
  end
19
11
 
12
+ # Marks job template model as being used by release version
13
+ # @param string stemcell os & version, e.g. 'ubuntu_trusty/3146.1'
14
+ # @return hash, e.g. { stemcell_os: 'ubuntu_trusty', stemcell_version: '3146.1' }
15
+ def self.split_stemcell_os_and_version(name)
16
+ values = name.split('/', 2)
17
+
18
+ unless 2 == values.length
19
+ raise "Expected value to be in the format of \"{os_name}/{stemcell_version}\", but given \"#{name}\""
20
+ end
21
+
22
+ return { os: values[0], version: values[1] }
23
+ end
24
+
20
25
  def validate
21
- validates_presence [:package_id, :stemcell_id, :sha1, :blobstore_id, :dependency_key]
22
- validates_unique [:package_id, :stemcell_id, :dependency_key]
23
- validates_unique [:package_id, :stemcell_id, :build]
26
+ validates_presence [:package_id, :stemcell_os, :stemcell_version, :sha1, :blobstore_id, :dependency_key]
27
+ validates_unique [:package_id, :stemcell_os, :stemcell_version, :dependency_key]
28
+ validates_unique [:package_id, :stemcell_os, :stemcell_version, :build]
24
29
  end
25
30
 
26
31
  def before_save
@@ -37,10 +42,11 @@ module Bosh::Director::Models
37
42
  package.version
38
43
  end
39
44
 
40
- def self.generate_build_number(package_model, stemcell_model)
45
+ def self.generate_build_number(package_model, stemcell_os, stemcell_version)
41
46
  attrs = {
42
47
  :package_id => package_model.id,
43
- :stemcell_id => stemcell_model.id
48
+ :stemcell_os => stemcell_os,
49
+ :stemcell_version => stemcell_version,
44
50
  }
45
51
 
46
52
  filter(attrs).max(:build).to_i + 1
@@ -7,6 +7,7 @@ module Bosh::Director::Models
7
7
  one_to_many :properties, :class => "Bosh::Director::Models::DeploymentProperty"
8
8
  one_to_many :problems, :class => "Bosh::Director::Models::DeploymentProblem"
9
9
  many_to_one :cloud_config
10
+ many_to_one :runtime_config
10
11
 
11
12
  def validate
12
13
  validates_presence :name
@@ -22,6 +23,15 @@ module Bosh::Director::Models
22
23
  def link_spec=(data)
23
24
  self.link_spec_json = Yajl::Encoder.encode(data)
24
25
  end
26
+
27
+ def self.transform_admin_team_scope_to_teams(token_scopes)
28
+ return [] if token_scopes.nil?
29
+ team_scopes = token_scopes.map do |scope|
30
+ match = scope.match(/\Abosh\.teams\.([^\.]*)\.admin\z/)
31
+ match[1] unless match.nil?
32
+ end
33
+ team_scopes.compact
34
+ end
25
35
  end
26
36
 
27
37
  Deployment.plugin :association_dependencies
@@ -41,7 +41,8 @@ module Bosh::Director::Models
41
41
 
42
42
  def cloud_properties_hash
43
43
  if cloud_properties.nil?
44
- spec['vm_type']['cloud_properties']
44
+ return {} if spec.nil? || spec['vm_type'].nil?
45
+ spec['vm_type']['cloud_properties'] || {}
45
46
  else
46
47
  JSON.parse(cloud_properties)
47
48
  end
@@ -11,22 +11,6 @@ module Bosh::Director::Models
11
11
  validates_unique [:release_id, :version]
12
12
  end
13
13
 
14
- # immediate dependency models
15
- def dependencies(package)
16
- package.dependency_set.map { |package_name| package_by_name(package_name) }.to_set
17
- end
18
-
19
- # all dependency models, including transitives
20
- # assumes there are no cycles (checked during upload)
21
- def transitive_dependencies(package)
22
- dependency_set = Set.new
23
- dependencies(package).each do |dependency|
24
- dependency_set << dependency
25
- dependency_set.merge(transitive_dependencies(dependency))
26
- end
27
- dependency_set
28
- end
29
-
30
14
  def package_by_name(package_name)
31
15
  packages_by_name.fetch(package_name)
32
16
  end
@@ -0,0 +1,19 @@
1
+ module Bosh
2
+ module Director
3
+ module Models
4
+ class RuntimeConfig < Sequel::Model(Bosh::Director::Config.db)
5
+ def before_create
6
+ self.created_at ||= Time.now
7
+ end
8
+
9
+ def manifest=(runtime_config_hash)
10
+ self.properties = Psych.dump(runtime_config_hash)
11
+ end
12
+
13
+ def manifest
14
+ Psych.load properties
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -36,12 +36,12 @@ module Bosh::Director::Models
36
36
  object_or_nil(self.properties_json)
37
37
  end
38
38
 
39
- def requires=(requires_spec)
40
- self.requires_json = json_encode(requires_spec)
39
+ def consumes=(consumes_spec)
40
+ self.consumes_json = json_encode(consumes_spec)
41
41
  end
42
42
 
43
- def requires
44
- object_or_nil(self.requires_json)
43
+ def consumes
44
+ object_or_nil(self.consumes_json)
45
45
  end
46
46
 
47
47
  def provides=(provides_spec)
@@ -0,0 +1,22 @@
1
+ module Bosh
2
+ module Director
3
+ class PackageDependenciesManager
4
+ def initialize(release_version)
5
+ @release_version = release_version
6
+ end
7
+
8
+ def transitive_dependencies(package)
9
+ dependency_set = Set.new
10
+ dependencies(package).each do |dependency|
11
+ dependency_set << dependency
12
+ dependency_set.merge(transitive_dependencies(dependency))
13
+ end
14
+ dependency_set
15
+ end
16
+
17
+ def dependencies(package)
18
+ package.dependency_set.map { |package_name| @release_version.package_by_name(package_name) }.to_set
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,18 @@
1
+ require 'securerandom'
2
+ require 'unix_crypt'
3
+
4
+ module Bosh::Director
5
+ module PasswordHelper
6
+ # SHA512 tolerates salt lengths from 8 to 16 bytes
7
+ # we found this by using the mkpasswd (from the whois package) on ubuntu linux
8
+ SALT_MAX_LENGTH_IN_BYTES = 16
9
+
10
+ PASSWORD_LENGTH = 30
11
+
12
+ def sha512_hashed_password
13
+ salt = SecureRandom.hex(SALT_MAX_LENGTH_IN_BYTES / 2)
14
+ password = SecureRandom.hex(PASSWORD_LENGTH)
15
+ UnixCrypt::SHA512.build(password, salt)
16
+ end
17
+ end
18
+ end
@@ -1,52 +1,72 @@
1
1
  module Bosh::Director
2
2
  class PermissionAuthorizer
3
- def initialize
4
- @director_uuid ||= Bosh::Director::Models::DirectorAttribute.uuid
3
+ def initialize(uuid_provider)
4
+ @uuid_provider = uuid_provider
5
5
  end
6
6
 
7
- def has_admin_scope?(token_scopes)
8
- !(intersect(permissions[:write], token_scopes).empty?)
7
+ def granted_or_raise(subject, permission, user_scopes)
8
+ if !is_granted?(subject, permission, user_scopes)
9
+ raise UnauthorizedToAccessDeployment, "Require one of the scopes: #{list_expected_scope(subject, permission, user_scopes).join(', ')}"
10
+ end
9
11
  end
10
12
 
11
- def has_admin_or_director_read_scope?(token_scopes)
12
- !(intersect(permissions[:read], token_scopes).empty?)
13
+ def is_granted?(subject, permission, user_scopes)
14
+ !intersect(user_scopes, list_expected_scope(subject, permission, user_scopes)).empty?
13
15
  end
14
16
 
15
- def has_team_admin_scope?(token_scopes)
16
- token_scopes.any? do |e|
17
- /bosh.teams.[^\.]+.admin/ =~ e
17
+ def list_expected_scope(subject, permission, user_scopes)
18
+ expected_scope = director_permissions[:admin]
19
+
20
+ if subject.instance_of? Models::Deployment
21
+ expected_scope << deployment_team_scopes(subject, 'admin')
22
+
23
+ if :admin == permission
24
+ # already allowed with initial expected_scope
25
+ elsif :read == permission
26
+ expected_scope << director_permissions[:read]
27
+ else
28
+ raise ArgumentError, "Unexpected permission for deployment: #{permission}"
29
+ end
30
+ elsif :director == subject
31
+ if :admin == permission
32
+ # already allowed with initial expected_scope
33
+ elsif :create_deployment == permission
34
+ expected_scope << add_bosh_admin_scopes(user_scopes)
35
+ elsif [:read_releases, :list_deployments, :read_stemcells, :list_tasks].include?(permission)
36
+ expected_scope << director_permissions[:read]
37
+ expected_scope << add_bosh_admin_scopes(user_scopes)
38
+ elsif :read == permission
39
+ expected_scope << director_permissions[:read]
40
+ else
41
+ raise ArgumentError, "Unexpected permission for director: #{permission}"
42
+ end
43
+ else
44
+ raise ArgumentError, "Unexpected subject: #{subject}"
18
45
  end
46
+
47
+ expected_scope.flatten.uniq
19
48
  end
20
49
 
21
- def contains_requested_scope?(valid_scopes, token_scopes)
22
- return false unless valid_scopes
23
- !(intersect(valid_scopes, token_scopes).empty?)
50
+ private
51
+
52
+ def add_bosh_admin_scopes(user_scopes)
53
+ user_scopes.select do |scope|
54
+ scope.match(/\Abosh\.teams\.([^\.]*)\.admin\z/)
55
+ end
24
56
  end
25
57
 
26
- def permissions
58
+ def director_permissions
27
59
  {
28
- :read => ['bosh.admin', "bosh.#{@director_uuid}.admin", 'bosh.read', "bosh.#{@director_uuid}.read"],
29
- :write => ['bosh.admin', "bosh.#{@director_uuid}.admin"]
60
+ read: ['bosh.read', "bosh.#{@uuid_provider.uuid}.read"],
61
+ admin: ['bosh.admin', "bosh.#{@uuid_provider.uuid}.admin"],
30
62
  }
31
63
  end
32
64
 
33
- def is_authorized?(provided_scopes, token_scopes)
34
- return true if has_admin_or_director_read_scope?(token_scopes)
35
-
36
- return contains_requested_scope?(provided_scopes, token_scopes)
65
+ def deployment_team_scopes(deployment, permission)
66
+ permissions = deployment.teams.nil? ? [] : deployment.teams.split(',')
67
+ permissions.map{ |team_name| "bosh.teams.#{team_name}.#{permission}" }
37
68
  end
38
69
 
39
- def raise_error_if_unauthorized(provided_scopes, deployment_scopes)
40
- return if has_admin_scope?(provided_scopes)
41
-
42
- if (deployment_scopes & provided_scopes).empty?
43
- raise Bosh::Director::UnauthorizedToAccessDeployment,
44
- 'You are unauthorized to view this deployment. Please contact the BOSH admin.'
45
- end
46
- end
47
-
48
- private
49
-
50
70
  def intersect(valid_scopes, token_scopes)
51
71
  valid_scopes & token_scopes
52
72
  end
@@ -0,0 +1,40 @@
1
+ module Bosh::Director
2
+ class PostDeploymentScriptRunner
3
+
4
+ def self.run_post_deploys_after_resurrection(deployment)
5
+ return unless Config.enable_post_deploy
6
+ instances = Models::Instance.filter(deployment: deployment).exclude(vm_cid: nil).all
7
+ agent_options = {
8
+ timeout: 10,
9
+ retry_methods: {get_state: 0}
10
+ }
11
+
12
+ ThreadPool.new(:max_threads => Config.max_threads).wrap do |pool|
13
+ instances.each do |instance|
14
+ pool.process do
15
+ agent = AgentClient.with_vm_credentials_and_agent_id(instance.credentials, instance.agent_id, agent_options)
16
+ begin
17
+ agent.run_script('post-deploy', {})
18
+ rescue Bosh::Director::RpcTimeout
19
+ # Ignoring timeout errors
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ def self.run_post_deploys_after_deployment(deployment_plan)
27
+ return unless Config.enable_post_deploy
28
+ ThreadPool.new(:max_threads => Config.max_threads).wrap do |pool|
29
+ deployment_plan.jobs.each do |job|
30
+ job.instances.select{|instance| instance.model[:vm_cid] != nil && instance.model.state != "stopped"}.each do |instance|
31
+ pool.process do
32
+ instance.agent_client.run_script('post-deploy', {})
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ end
40
+ end
@@ -23,8 +23,8 @@ module Bosh::Director
23
23
 
24
24
  def description
25
25
  job = @instance.job || "unknown job"
26
- index = @instance.index || "unknown index"
27
- disk_label = "`#{@disk.disk_cid}' (#{job}/#{index}, #{@disk.size.to_i}M)"
26
+ uuid = @instance.uuid || "unknown id"
27
+ disk_label = "`#{@disk.disk_cid}' (#{job}/#{uuid}, #{@disk.size.to_i}M)"
28
28
  "Disk #{disk_label} is missing"
29
29
  end
30
30
 
@@ -6,6 +6,7 @@ module Bosh::Director
6
6
  def initialize(deployment)
7
7
  @deployment = deployment
8
8
  @resolved_count = 0
9
+ @resolution_error_logs = StringIO.new
9
10
 
10
11
  #temp
11
12
  @event_log = Config.event_log
@@ -42,7 +43,10 @@ module Bosh::Director
42
43
  apply_resolution(problem)
43
44
  end
44
45
  end
45
- @resolved_count
46
+
47
+ error_message = @resolution_error_logs.string.empty? ? nil : @resolution_error_logs.string.chomp
48
+
49
+ [@resolved_count, error_message]
46
50
  end
47
51
 
48
52
  private
@@ -75,8 +79,10 @@ module Bosh::Director
75
79
  private
76
80
 
77
81
  def log_resolution_error(problem, error)
78
- logger.error("Error resolving problem `#{problem.id}': #{error}")
82
+ error_message = "Error resolving problem `#{problem.id}': #{error}"
83
+ logger.error(error_message)
79
84
  logger.error(error.backtrace.join("\n"))
85
+ @resolution_error_logs.puts(error_message)
80
86
  end
81
87
  end
82
88
  end
@@ -20,7 +20,7 @@ module Bosh::Director
20
20
  def reset(vms=nil)
21
21
  if vms
22
22
  vms.each do |job, index|
23
- instance = @instance_manager.find_by_name(@deployment.name, job, index)
23
+ instance = @instance_manager.find_by_name(@deployment, job, index)
24
24
 
25
25
  Models::DeploymentProblem.where(
26
26
  deployment: @deployment,
@@ -18,7 +18,7 @@ module Bosh::Director
18
18
  def scan(vms=nil)
19
19
  if vms
20
20
  instances = vms.map do |job, index|
21
- @instance_manager.find_by_name(@deployment.name, job, index)
21
+ @instance_manager.find_by_name(@deployment, job, index)
22
22
  end
23
23
  else
24
24
  instances = Models::Instance.filter(deployment: @deployment).exclude(vm_cid: nil).all
@@ -5,7 +5,7 @@ module Bosh::Director
5
5
 
6
6
  if hash && !hash.kind_of?(Hash)
7
7
  raise Bosh::Director::ValidationInvalidType,
8
- "Object (#{hash.inspect}) did not match the required type `Hash'"
8
+ "Object (#{hash.inspect}) did not match the required type 'Hash'"
9
9
 
10
10
  elsif hash && hash.has_key?(property)
11
11
  result = hash[property]
@@ -27,12 +27,12 @@ module Bosh::Director
27
27
 
28
28
  if options[:min] && result < options[:min]
29
29
  raise ValidationViolatedMin,
30
- "`#{property}' value (#{result.inspect}) should be greater than #{options[:min].inspect}"
30
+ "'#{property}' value (#{result.inspect}) should be greater than #{options[:min].inspect}"
31
31
  end
32
32
 
33
33
  if options[:max] && result > options[:max]
34
34
  raise ValidationViolatedMax,
35
- "`#{property}' value (#{result.inspect}) should be less than #{options[:max].inspect}"
35
+ "'#{property}' value (#{result.inspect}) should be less than #{options[:max].inspect}"
36
36
  end
37
37
 
38
38
  elsif options[:default]
@@ -40,7 +40,7 @@ module Bosh::Director
40
40
 
41
41
  elsif !options[:optional]
42
42
  raise ValidationMissingField,
43
- "Required property `#{property}' was not specified in object (#{hash.inspect})"
43
+ "Required property '#{property}' was not specified in object (#{hash.inspect})"
44
44
  end
45
45
 
46
46
  result
@@ -48,7 +48,7 @@ module Bosh::Director
48
48
 
49
49
  def invalid_type(property, klass, value)
50
50
  raise ValidationInvalidType,
51
- "Property `#{property}' (value #{value.inspect}) did not match the required type `#{klass}'"
51
+ "Property '#{property}' (value #{value.inspect}) did not match the required type '#{klass}'"
52
52
  end
53
53
  end
54
54
  end